Для этого квеста больше ничего не надо. Все необходимое для корректной работы квеста уже добавили. Вот полный текст квеста: # z0 @+ r5 R5 `- Z! Z + S6 D# U3 l+ x% N+ v. z
Теперь рассмотрим, как это работает.4 z* W0 I# U: v; T& h' ~& ~1 k; @
Игрок подходит к начальному NCP (в данном случае 7056), нажимает на «Quest». Квест будет создан и состояние квеста перейдет к CREATED и игроку будет показана страничка Start.htm с описанием квеста. Тогда метод onEvent, поле открытия странички Start.htm переведет состояние квеста в STARTED и игроку будет показана страничка Started.htm, где будет опсание того, как найти keltirs и .т.д.$ S, N2 g" ?, \- A5 d; t) B# P
; c& v$ S1 [5 d0 o) {7 e& x
. p( a. T% O6 V, A$ z: s4 \При состоянии STARTED будет зарегистрирован дроп «fangs» при убийстве keltirs. Игрок может вернуться к стартовому NCP и спросить о квесте – метод onEvent будет вызван снова. Если у игрока не хватает необходимого количества предметов, то метод check() не переведет квест в следующее состояние и Started.htm будет показана снова. Но если игрок собрал необходимее количество предметов (в данном случае 4 клыка), то метод check() вызовет метод completed() который переведет квест в новое состояние COMPLETED, заберет все клыки, даст карту мира, т.к. это награда за квест, покажет Completed.htm и завершит квест. + ^4 L. U) D% y5 g j4 |! v0 x1 ]) I- V! m7 {$ s( y t b& a) u7 F
Теперь давайте сделаем наш квест более похожим на то, что он должен из себя представлять.8 j! s6 u% M+ `4 K: ^/ `! o: C
Прежде всего у нас есть 3 метода для объявления их в Яве – onTalk, onKill и onEvent. Если методы onTalk и onKill не объявлены, то за них все будет делать метод onEvent, т.е. определять квестовых монстров и вызывать диалоги NCP. Есть примечание, методы onTalk и onKill будут вызывать только диалоги с NCP в зависимости от текущего состояния квеста. Метод onKill будет вызываться только тогда, когда мы убиваем квестового монстра. / B6 e# k( o1 a! }, H, ~; M" G : D& }5 D; S: C! U+ M0 C 8 u* V& { l# Q3 @Давайте рассмотрим как вызывается метод onKill при убийстве keltir в состоянии квеста STARTED:# p) T! p" b4 M, N2 V
STARTED.addKillId(KELTIR_NPC_ID)
Скопировать код
и метод onKill в классе Quest: " @" D2 T: [5 W6 z4 { * o- ?. t/ Y& M+ `
Метод onKill (а так же метод onTalk) имеет следующие параметры: P( h+ s( p8 W- V7 \ G9 ?7 Y! Q2 D0 V( E
) m8 G4 ?( C. z
• self – квест 8 H' ^: R; w* a! j u- ~4 D• npcId – ID NCP, которого мы должны убивать (если это метод onTalk, то ID того NCP, с которым мы должны поговорить). 8 O9 C3 i$ `& a3 m2 u• st – текущее состояние игрока. ! {8 k! |( G% F4 X% v/ ~6 }- X' ~5 e+ G* o8 B
* S9 C1 A f- `) X' M/ pВ этом методе мы проверяем и отмечаем, является ли убитый NCP keltir’ом. В основном эта проверка не нужна, т.к. у нас только KELTIR_NPC_ID. ! J b) a4 w5 F( K S4 D, y# [9 W" l4 \1 B0 {. Y9 K
2 d! V4 v5 f# l; lЗатем проверяем количество предметов (в данном случае количество клыков), и если их вообще нет, то возвращаем строку "Chat0.htm", если только один предмет, то возвращаем строку "Chat1.htm", если же предметов 4 или больше, то "Chat4.htm". Если строка возвращена из методов onEvent, onKill или onTalk, то сервер покажет соответствующие htm. В Chat0.htm может иметь следующий текст: «Вы не имеете ни одного клыка, возвращайтесь позже, когда соберете 4 штуки и бла, бла, бла…», в Chat1.htm может быть следующий текст: «У Вас всего 1 клык, по этому соберите еще…». В Chat4.htm – «Вы собрали необходимое количество предметов, возвращайтесь к вашему тренеру, что бы завершить квест…» 7 e/ }( V8 w/ K5 F$ s0 j 4 B0 g" T' \- I% ?8 L- ^ 3 G6 e' i! x; T- @/ ^4 z z) RПримечание: если в строка return начинается с "<html>", то будет показана страничка html с текстом, который стоит далее. Так вместо:0 z' U2 m( G+ h4 g
return "Chat4.htm": W5 M3 F4 T+ [! O
" e* [; W; j g' H6 j% \: Z0 n" i7 \
. u5 O5 Y' s- E1 O( j
можно поставить: / }* f0 [" ~0 n2 u2 R( C# d7 ?. Q
return "<html><body>Return to your trainer to complete the quest</body></html>"
Скопировать код
Так же если строка заканчивается без .htm или в начале нет <html>, то текст будет выведен, как системное сообщение в окне чата. В нашем случае мы сделаем так, что бы при каждом убийстве keltik выводилось системное сообщение: «Собрано N из 4-х клыков».$ ^6 y. p8 h; v' s b4 W4 Z# s
) \$ T6 E* M' S: W( |
, W' w3 K8 D" W' K( u
Наш код для onKill имеет один недостаток. Он будет постоянно показывать Chat0.htm, Chat1.htm и Chat4.htm, нам же необходимо, что бы Chat0.htm и Chat1.htm показывались только один раз. Как нам это сделать? С помощью переменных.: S. f3 F! b- t, A1 i
0 c- l3 ~# W% s) h( T8 q! z
$ `( k, @2 l8 u& JВ каждом квесте строки могут храниться с помощью переменных. Эти переменные сохраняются в Вашей БД. В каждом методе мы можем назначить, прочитать и удалить переменные. Давайте изменим метод onKill, так что бы каждый диалог вызывался только один раз.2 U9 r& n7 C$ i& ~
def onKill (self,npcId,st): : q6 T4 l& O3 a* W4 K @3 y# K
return "Chat4.htm" * ?; Z" e/ \( e5 b7 O. g9 F9 L$ J5 g
return "Collected "+str(n)+" of 4 fangs" 4 g; }- B- B, ^1 n# v
return
Скопировать код
Если у игрока нет клыков (n=0), то мы получаем занчение переменной 'chat0'. Когда метод onKill вызван в первый раз, то пока ни каких переменных не имеется и python возвращает значение None. В этом случае объявляется переменная и показывается диалог Chat0.htm. Когда мы убиваем keltir, но не получаем с него клык, функция st.get('chat0') возвращает строку true, а не None. И во второй раз окно с Chat0.htm не появится, но в окне чата появится строчка «Collected 0 of 4 fangs». По тому же принципу сделано и с Chat1.htm./ T8 C4 l3 k9 d, u* C
& r. d) e' v8 O
, }4 }% K8 r5 ]; ]Вот конечный рабочий вариант квеста: - `+ K8 o. \' j; g: u4 D
import sys 6 S: i x6 C, `6 i! c3 w
from net.sf.l2j.gameserver.model.quest import State # k3 G5 A- i- s" O( | ^( @
from net.sf.l2j.gameserver.model.quest import QuestState ' F1 N6 q+ F7 @7 w& e
from net.sf.l2j.gameserver.model.quest.jython import QuestJython as JQuest - T) I1 L* Y ?6 T" A' e: z