Для этого квеста больше ничего не надо. Все необходимое для корректной работы квеста уже добавили. Вот полный текст квеста:5 o j4 B! @5 A( L, ? o6 d* l3 M
Теперь рассмотрим, как это работает.9 x1 l# F; o0 A
Игрок подходит к начальному NCP (в данном случае 7056), нажимает на «Quest». Квест будет создан и состояние квеста перейдет к CREATED и игроку будет показана страничка Start.htm с описанием квеста. Тогда метод onEvent, поле открытия странички Start.htm переведет состояние квеста в STARTED и игроку будет показана страничка Started.htm, где будет опсание того, как найти keltirs и .т.д. / X! L, M _; v/ A/ {* u, t: M* E; ]* C) ]2 v( D( V& O
& I: \7 g2 e/ e
При состоянии STARTED будет зарегистрирован дроп «fangs» при убийстве keltirs. Игрок может вернуться к стартовому NCP и спросить о квесте – метод onEvent будет вызван снова. Если у игрока не хватает необходимого количества предметов, то метод check() не переведет квест в следующее состояние и Started.htm будет показана снова. Но если игрок собрал необходимее количество предметов (в данном случае 4 клыка), то метод check() вызовет метод completed() который переведет квест в новое состояние COMPLETED, заберет все клыки, даст карту мира, т.к. это награда за квест, покажет Completed.htm и завершит квест. . w6 {: O% ?3 t# A. m. V. L& Y* q0 h
: A; p9 n5 @2 M K
Теперь давайте сделаем наш квест более похожим на то, что он должен из себя представлять. 8 r9 @4 e% {1 m- i7 Q- NПрежде всего у нас есть 3 метода для объявления их в Яве – onTalk, onKill и onEvent. Если методы onTalk и onKill не объявлены, то за них все будет делать метод onEvent, т.е. определять квестовых монстров и вызывать диалоги NCP. Есть примечание, методы onTalk и onKill будут вызывать только диалоги с NCP в зависимости от текущего состояния квеста. Метод onKill будет вызываться только тогда, когда мы убиваем квестового монстра. - B0 Z* p- p; {4 U4 H5 `5 D5 @4 ~: m+ y+ G* q5 q0 q' _+ X7 s
4 T8 l' K$ ~! SДавайте рассмотрим как вызывается метод onKill при убийстве keltir в состоянии квеста STARTED:: [3 e3 \$ |) f u/ R/ F) ~9 n/ `5 x
STARTED.addKillId(KELTIR_NPC_ID)
Скопировать код
и метод onKill в классе Quest:4 H$ x" D1 I! W d& C
4 F4 x8 k1 o- e; C- }" s- K7 Z
class Quest (JQuest):$ z7 o$ W9 I/ j' a4 x; N' h j
...3 X5 g1 H! V; c# G2 W% N4 N
def onKill (self,npcId,st): # B) @. n! G0 ~
if npcId == KELTIR_NPC_ID:) B V7 }! `" C4 C# |+ W
n = getCount(st) / M% l: d* m9 _; x& R/ [7 J
if n == 0:7 ~1 |8 W2 d" F* M& w
return "Chat0.htm"- [+ L/ V! v. M/ Q( J( g7 e
elif n == 1: " B, ~/ d0 c8 |% H$ }
return "Chat1.htm" 6 i* i2 e& E" `3 N ?; X
elif n >= 4:7 d# R5 b7 o$ D2 q3 t/ g" t' w2 v
return "Chat4.htm"* Z& T$ W- S3 D/ _% A+ T- e; b
return "Collected "+str(n)+" of 4 fangs" 3 X3 J7 A- h4 P0 S2 {( l( O% U
return
Скопировать код
Метод onKill (а так же метод onTalk) имеет следующие параметры: - V9 ^# R2 |1 H9 ^ 9 p! X, f. I6 ]2 a3 x1 j ; V I/ O6 C, D3 c4 y• self – квест * _9 U7 Y9 `; K- w! D• npcId – ID NCP, которого мы должны убивать (если это метод onTalk, то ID того NCP, с которым мы должны поговорить).! ~5 r6 R3 r0 G: \% J
• st – текущее состояние игрока.& ^$ ~. i( K5 x0 P9 W) y
6 f/ d. T l1 t' F& K K- J5 Y3 U ' Z9 Q! x- u: M: g. i4 b# RВ этом методе мы проверяем и отмечаем, является ли убитый NCP keltir’ом. В основном эта проверка не нужна, т.к. у нас только KELTIR_NPC_ID.# p( J" U6 Y: P5 x3 L" D
7 F$ i+ i% ~; I - l" B5 [; f: K. {' Y- m/ DЗатем проверяем количество предметов (в данном случае количество клыков), и если их вообще нет, то возвращаем строку "Chat0.htm", если только один предмет, то возвращаем строку "Chat1.htm", если же предметов 4 или больше, то "Chat4.htm". Если строка возвращена из методов onEvent, onKill или onTalk, то сервер покажет соответствующие htm. В Chat0.htm может иметь следующий текст: «Вы не имеете ни одного клыка, возвращайтесь позже, когда соберете 4 штуки и бла, бла, бла…», в Chat1.htm может быть следующий текст: «У Вас всего 1 клык, по этому соберите еще…». В Chat4.htm – «Вы собрали необходимое количество предметов, возвращайтесь к вашему тренеру, что бы завершить квест…»0 a; P# K K# v- S3 S+ j: L. T; w" s
; v$ L8 K9 d) n" z- W: g! x) E
2 N* c. T, H6 s( N; \* N
Примечание: если в строка return начинается с "<html>", то будет показана страничка html с текстом, который стоит далее. Так вместо: - h) b1 d- [% D/ T9 R! \2 {return "Chat4.htm"" R# Y8 h/ u7 w
return "<html><body>Return to your trainer to complete the quest</body></html>"
Скопировать код
Так же если строка заканчивается без .htm или в начале нет <html>, то текст будет выведен, как системное сообщение в окне чата. В нашем случае мы сделаем так, что бы при каждом убийстве keltik выводилось системное сообщение: «Собрано N из 4-х клыков».8 l8 q" |% l F. y; m2 ~( g! C$ i4 Q4 z
$ Y0 t) E# @- Q( u7 X8 O
9 q `% o { d/ A7 O: }8 n
Наш код для onKill имеет один недостаток. Он будет постоянно показывать Chat0.htm, Chat1.htm и Chat4.htm, нам же необходимо, что бы Chat0.htm и Chat1.htm показывались только один раз. Как нам это сделать? С помощью переменных. 5 M1 u8 d/ w: v9 i. _/ @) w* t
( j8 p1 q5 y6 t; A8 eВ каждом квесте строки могут храниться с помощью переменных. Эти переменные сохраняются в Вашей БД. В каждом методе мы можем назначить, прочитать и удалить переменные. Давайте изменим метод onKill, так что бы каждый диалог вызывался только один раз.3 |4 Q: U$ s X1 ^9 U& N
def onKill (self,npcId,st): # w8 P0 X9 M& s6 ?
if npcId == KELTIR_NPC_ID:; p& L! ^1 A. A8 f) I
n = getCount(st)! g- o- _; T, p0 ~9 {0 ^8 x9 a
if n == 0: ( ?, g6 @; i6 y7 b' C
if st.get('chat0') == None : , F6 ]4 n& U8 ?8 i C2 O) W
return "Collected "+str(n)+" of 4 fangs"! L& k8 s: _$ b# s2 p
return
Скопировать код
Если у игрока нет клыков (n=0), то мы получаем занчение переменной 'chat0'. Когда метод onKill вызван в первый раз, то пока ни каких переменных не имеется и python возвращает значение None. В этом случае объявляется переменная и показывается диалог Chat0.htm. Когда мы убиваем keltir, но не получаем с него клык, функция st.get('chat0') возвращает строку true, а не None. И во второй раз окно с Chat0.htm не появится, но в окне чата появится строчка «Collected 0 of 4 fangs». По тому же принципу сделано и с Chat1.htm. - z9 V% Y( T4 D" Z- U & m$ c& l6 E6 ^; O0 M( z' c . }% U( c/ \) A, mВот конечный рабочий вариант квеста: " D& ^0 d5 t0 J4 V3 n% D
import sys 1 f- Y1 A0 u. M: j
from net.sf.l2j.gameserver.model.quest import State 0 b0 g, e. a% n- l+ o6 ^
from net.sf.l2j.gameserver.model.quest import QuestState. E$ @$ i0 B* d: L" F! B
from net.sf.l2j.gameserver.model.quest.jython import QuestJython as JQuest * k* U1 c4 c) h( s% P9 U3 \