Для этого квеста больше ничего не надо. Все необходимое для корректной работы квеста уже добавили. Вот полный текст квеста: $ Q& P# R+ \2 b 6 s K1 Z' y: b9 R4 M$ a, h
Теперь рассмотрим, как это работает.7 }; ?/ I1 b9 [3 E
Игрок подходит к начальному NCP (в данном случае 7056), нажимает на «Quest». Квест будет создан и состояние квеста перейдет к CREATED и игроку будет показана страничка Start.htm с описанием квеста. Тогда метод onEvent, поле открытия странички Start.htm переведет состояние квеста в STARTED и игроку будет показана страничка Started.htm, где будет опсание того, как найти keltirs и .т.д.1 F' k- i& p3 @' Q
3 W0 \0 f( J/ e$ Z, V1 A8 |4 M; P1 c9 t4 D3 Z
При состоянии STARTED будет зарегистрирован дроп «fangs» при убийстве keltirs. Игрок может вернуться к стартовому NCP и спросить о квесте – метод onEvent будет вызван снова. Если у игрока не хватает необходимого количества предметов, то метод check() не переведет квест в следующее состояние и Started.htm будет показана снова. Но если игрок собрал необходимее количество предметов (в данном случае 4 клыка), то метод check() вызовет метод completed() который переведет квест в новое состояние COMPLETED, заберет все клыки, даст карту мира, т.к. это награда за квест, покажет Completed.htm и завершит квест.4 s! V0 L. p' _
F7 o( l* @) S9 C/ |; \" l: a0 z
6 l; M# h( ]6 P0 F
Теперь давайте сделаем наш квест более похожим на то, что он должен из себя представлять., j+ b- X/ T! c4 z5 K7 b
Прежде всего у нас есть 3 метода для объявления их в Яве – onTalk, onKill и onEvent. Если методы onTalk и onKill не объявлены, то за них все будет делать метод onEvent, т.е. определять квестовых монстров и вызывать диалоги NCP. Есть примечание, методы onTalk и onKill будут вызывать только диалоги с NCP в зависимости от текущего состояния квеста. Метод onKill будет вызываться только тогда, когда мы убиваем квестового монстра. " _0 t$ P' j; L( b6 k1 J 6 P2 Q4 b$ E8 F8 | V7 ^6 y2 G' E& X! {- p: o
Давайте рассмотрим как вызывается метод onKill при убийстве keltir в состоянии квеста STARTED: + f% Z* P# M7 m4 L
STARTED.addKillId(KELTIR_NPC_ID)
Скопировать код
и метод onKill в классе Quest: / W z) Z" k- f1 j* T1 i. {0 n" {: |, r0 _. x, o
class Quest (JQuest):& G5 }8 e2 ?. n, u2 J+ a/ n) f
... 2 A- ~; o* R5 z
def onKill (self,npcId,st): ( ]3 D5 p* n" Q3 R, h
if npcId == KELTIR_NPC_ID: ) W' b8 v0 t# [! ?
n = getCount(st) & i* R8 p% t$ m' h/ ~7 a6 R
if n == 0: 4 @( W- A# M2 D1 _, s
return "Chat0.htm" , k5 g+ P6 k: Y% F% _4 O6 s
elif n == 1: @1 V& u6 J. i% X
return "Chat1.htm" + b l) `3 e$ m' T X: H" J% V y
elif n >= 4: 1 o# B7 k. w7 B; ]5 V7 N0 j
return "Chat4.htm" ) G$ m( \9 F2 g1 x6 F
return "Collected "+str(n)+" of 4 fangs"( l. b' J! o1 a" O) h
return
Скопировать код
Метод onKill (а так же метод onTalk) имеет следующие параметры: 4 G# E# T# G% Z7 b1 w 3 z7 L. a- a6 L. a8 Q" U! t' `9 {0 n# ^; ]6 j" X* J
• self – квест 7 m8 J4 V- e& L! G• npcId – ID NCP, которого мы должны убивать (если это метод onTalk, то ID того NCP, с которым мы должны поговорить).# ?) _) i( P6 T& k: W
• st – текущее состояние игрока.4 q @; h8 L/ i& ]" Z
8 S1 v" {) r4 M7 M) X; ? ' M# P. C" F6 M# V& {' lВ этом методе мы проверяем и отмечаем, является ли убитый NCP keltir’ом. В основном эта проверка не нужна, т.к. у нас только KELTIR_NPC_ID.* H g6 H7 Z4 W1 I
. n: z* ?, Z$ I5 K) r- w5 _. R" [% ^6 l4 y0 W
Затем проверяем количество предметов (в данном случае количество клыков), и если их вообще нет, то возвращаем строку "Chat0.htm", если только один предмет, то возвращаем строку "Chat1.htm", если же предметов 4 или больше, то "Chat4.htm". Если строка возвращена из методов onEvent, onKill или onTalk, то сервер покажет соответствующие htm. В Chat0.htm может иметь следующий текст: «Вы не имеете ни одного клыка, возвращайтесь позже, когда соберете 4 штуки и бла, бла, бла…», в Chat1.htm может быть следующий текст: «У Вас всего 1 клык, по этому соберите еще…». В Chat4.htm – «Вы собрали необходимое количество предметов, возвращайтесь к вашему тренеру, что бы завершить квест…» 7 \* ^8 S1 U3 q7 w1 e, r9 t6 I8 Y0 D) x; S
' k8 W; E+ U' @* B0 Q- L. h8 cПримечание: если в строка return начинается с "<html>", то будет показана страничка html с текстом, который стоит далее. Так вместо: " F( D [6 u7 e4 D9 T% l- k6 Nreturn "Chat4.htm"; d9 @1 u/ E& f: e5 t' R
% F% s/ Q6 n% ~3 W- ~( T) C / {& p) ^& k& J8 n& l t# t, U) cможно поставить:# H/ ~, L; \+ I( I- h
return "<html><body>Return to your trainer to complete the quest</body></html>"
Скопировать код
Так же если строка заканчивается без .htm или в начале нет <html>, то текст будет выведен, как системное сообщение в окне чата. В нашем случае мы сделаем так, что бы при каждом убийстве keltik выводилось системное сообщение: «Собрано N из 4-х клыков».# W& O7 `8 U/ e( _/ c! l
9 z% U6 [% C7 r, }" V
0 Z( Y7 s7 r4 g$ t6 b
Наш код для onKill имеет один недостаток. Он будет постоянно показывать Chat0.htm, Chat1.htm и Chat4.htm, нам же необходимо, что бы Chat0.htm и Chat1.htm показывались только один раз. Как нам это сделать? С помощью переменных.0 w1 X2 f0 _5 y( Q& ]' ]
# \9 `: S6 G" H
6 |7 G$ x$ u3 ^9 b5 e1 G, `: x! k5 f
В каждом квесте строки могут храниться с помощью переменных. Эти переменные сохраняются в Вашей БД. В каждом методе мы можем назначить, прочитать и удалить переменные. Давайте изменим метод onKill, так что бы каждый диалог вызывался только один раз.& d2 f4 ~0 U& z B- g
def onKill (self,npcId,st):) I2 A' C" I3 k4 x( E
if npcId == KELTIR_NPC_ID: 0 E8 K5 x6 y% h5 l+ G$ | v+ c
n = getCount(st) 4 F. @% N4 } M2 t6 T6 N" U
if n == 0: ( c. ?9 D2 a# B& S; C2 T- y
if st.get('chat0') == None : 0 b! O, Q: `; D) t) g3 L1 t
return "Chat1.htm"; f( O" c" L6 V) \$ e i) I2 V# l7 n
elif n >= 4:4 f1 {5 S3 E* G0 w( Z$ }/ C
return "Chat4.htm"+ `8 `& V, y& P, \- \2 N K2 Z
return "Collected "+str(n)+" of 4 fangs"% [% h* J C6 g$ H: E @5 D
return
Скопировать код
Если у игрока нет клыков (n=0), то мы получаем занчение переменной 'chat0'. Когда метод onKill вызван в первый раз, то пока ни каких переменных не имеется и python возвращает значение None. В этом случае объявляется переменная и показывается диалог Chat0.htm. Когда мы убиваем keltir, но не получаем с него клык, функция st.get('chat0') возвращает строку true, а не None. И во второй раз окно с Chat0.htm не появится, но в окне чата появится строчка «Collected 0 of 4 fangs». По тому же принципу сделано и с Chat1.htm.1 P9 d/ N9 j* v9 W, b6 a
, V- i' l0 ?. M8 a& b- V 8 v4 p1 H6 s; G' ^* e W3 I7 wВот конечный рабочий вариант квеста: 2 y- y2 I$ c5 }( G# b
import sys4 s; t7 F- {* h
from net.sf.l2j.gameserver.model.quest import State* N5 q8 z e( @2 {. V& \
from net.sf.l2j.gameserver.model.quest import QuestState$ f' c4 S5 X& R& o+ e0 j6 l/ H, }
from net.sf.l2j.gameserver.model.quest.jython import QuestJython as JQuest 7 U: s1 X5 W4 }" o' G0 I