Для этого квеста больше ничего не надо. Все необходимое для корректной работы квеста уже добавили. Вот полный текст квеста: ) G( t2 N) G) Q h& x0 Z: b5 U. X; S: ?6 A2 f
if getCount(st) >= 4 : - r) C/ a: u* U: B& n
completed(st) 2 g/ e. R: o/ I) {4 k* x8 j
return) [) R! f( W; M4 I6 p" d- E, s
( j( k. s$ \+ |* M9 F( j
class Quest (JQuest): ) V+ h# p: b: ]3 ^0 j% t& ]+ K
Теперь рассмотрим, как это работает.) N% H' k9 ?- l* {0 C
Игрок подходит к начальному NCP (в данном случае 7056), нажимает на «Quest». Квест будет создан и состояние квеста перейдет к CREATED и игроку будет показана страничка Start.htm с описанием квеста. Тогда метод onEvent, поле открытия странички Start.htm переведет состояние квеста в STARTED и игроку будет показана страничка Started.htm, где будет опсание того, как найти keltirs и .т.д. : V) P3 }# v3 K, G, o7 ]- ~0 p4 `0 G* Q" n- a7 z3 {5 w
8 w* E* G/ K# l" h$ n# I/ C
При состоянии STARTED будет зарегистрирован дроп «fangs» при убийстве keltirs. Игрок может вернуться к стартовому NCP и спросить о квесте – метод onEvent будет вызван снова. Если у игрока не хватает необходимого количества предметов, то метод check() не переведет квест в следующее состояние и Started.htm будет показана снова. Но если игрок собрал необходимее количество предметов (в данном случае 4 клыка), то метод check() вызовет метод completed() который переведет квест в новое состояние COMPLETED, заберет все клыки, даст карту мира, т.к. это награда за квест, покажет Completed.htm и завершит квест. 1 @0 g( }$ d8 c' i! d4 Y% Z' X6 c4 |) j% C% _
. o6 u9 U, n: l, A# |Теперь давайте сделаем наш квест более похожим на то, что он должен из себя представлять.% K" s! \+ m( l3 {5 J3 h, @
Прежде всего у нас есть 3 метода для объявления их в Яве – onTalk, onKill и onEvent. Если методы onTalk и onKill не объявлены, то за них все будет делать метод onEvent, т.е. определять квестовых монстров и вызывать диалоги NCP. Есть примечание, методы onTalk и onKill будут вызывать только диалоги с NCP в зависимости от текущего состояния квеста. Метод onKill будет вызываться только тогда, когда мы убиваем квестового монстра. # ] R8 q \) L 1 I5 r* {- c. K4 r/ S9 l1 |8 | ' e) u8 }1 {# b5 z. `' U @2 y7 uДавайте рассмотрим как вызывается метод onKill при убийстве keltir в состоянии квеста STARTED: 9 m; D6 f2 L) f+ ?1 ]0 U. y
STARTED.addKillId(KELTIR_NPC_ID)
Скопировать код
и метод onKill в классе Quest: / [9 h" c$ c6 v! F ; I) p6 N! Z+ a) a( E
class Quest (JQuest): % d/ U" @; t& E. k0 g6 q$ n1 A1 A3 B
return "Collected "+str(n)+" of 4 fangs" 3 H% m1 I5 p1 R {8 D- i. J
return
Скопировать код
Метод onKill (а так же метод onTalk) имеет следующие параметры:2 j5 ^" N2 D- o( D
+ h- i' j) b- g" _2 o l4 {$ p) R* W$ a. A9 v& \. e3 g6 g
• self – квест: v: V) i: N# K8 R
• npcId – ID NCP, которого мы должны убивать (если это метод onTalk, то ID того NCP, с которым мы должны поговорить).2 v& M5 S" i1 R9 Y3 @1 M% Z: C$ X
• st – текущее состояние игрока.7 }* Z6 `5 m# r, G! k
% e1 v' J' i$ U6 R
9 G4 r4 ?8 @+ j$ M) l. ~
В этом методе мы проверяем и отмечаем, является ли убитый NCP keltir’ом. В основном эта проверка не нужна, т.к. у нас только KELTIR_NPC_ID. 6 V2 A3 B! b. G a6 Q$ ~7 A * W8 v; B- R& I& L& P4 h! z" ?; D$ O6 |/ c3 }: s
Затем проверяем количество предметов (в данном случае количество клыков), и если их вообще нет, то возвращаем строку "Chat0.htm", если только один предмет, то возвращаем строку "Chat1.htm", если же предметов 4 или больше, то "Chat4.htm". Если строка возвращена из методов onEvent, onKill или onTalk, то сервер покажет соответствующие htm. В Chat0.htm может иметь следующий текст: «Вы не имеете ни одного клыка, возвращайтесь позже, когда соберете 4 штуки и бла, бла, бла…», в Chat1.htm может быть следующий текст: «У Вас всего 1 клык, по этому соберите еще…». В Chat4.htm – «Вы собрали необходимое количество предметов, возвращайтесь к вашему тренеру, что бы завершить квест…» $ C0 x; E! |% {$ L0 T3 u6 e # c( L7 b& x, X, X6 R: N # N$ v. n6 n. a8 S# Y+ k1 [" `$ C. x2 ]Примечание: если в строка return начинается с "<html>", то будет показана страничка html с текстом, который стоит далее. Так вместо:* G0 T6 P% j+ ?8 q0 K
return "Chat4.htm" 5 i* P, W4 x, O- Q2 w& \* @* N, V- q
return "<html><body>Return to your trainer to complete the quest</body></html>"
Скопировать код
Так же если строка заканчивается без .htm или в начале нет <html>, то текст будет выведен, как системное сообщение в окне чата. В нашем случае мы сделаем так, что бы при каждом убийстве keltik выводилось системное сообщение: «Собрано N из 4-х клыков». " H& j: M( ?7 x# g : A; c& Z# U: H0 c# m: J3 T* H; M5 Q/ }& Q
Наш код для onKill имеет один недостаток. Он будет постоянно показывать Chat0.htm, Chat1.htm и Chat4.htm, нам же необходимо, что бы Chat0.htm и Chat1.htm показывались только один раз. Как нам это сделать? С помощью переменных. 5 F: h/ L8 z: k0 C- ^1 s8 p - Y/ G: ]( [8 g& e& O ; `7 r- s0 X& Q) MВ каждом квесте строки могут храниться с помощью переменных. Эти переменные сохраняются в Вашей БД. В каждом методе мы можем назначить, прочитать и удалить переменные. Давайте изменим метод onKill, так что бы каждый диалог вызывался только один раз.' o+ t" n3 X t: z( T* E0 w
def onKill (self,npcId,st):4 {& b- ~! m3 G, f0 n& C. k
if npcId == KELTIR_NPC_ID:7 ^% s: E9 s$ z
n = getCount(st)/ a3 }5 C2 u9 F; W% X, s
if n == 0: ( _/ m8 A' I0 i% r9 e- `. c. c
if st.get('chat0') == None : ) c x4 t& S: V9 Y% W% i
st.set("chat0", "true") 6 z6 n1 x4 H" }$ S0 f O
return "Chat0.htm"% Q4 ^" ]& d, W5 }. i. k5 V
elif n == 1: ( x- G" ^1 M3 [
if st.get('chat1') == None : 1 U" b+ m: Q! h5 j( R3 J4 A
st.set("chat1", "true")6 X# U5 r7 p' d; x2 ~5 H
return "Chat1.htm" $ B% E+ K6 M; T- Z: f
elif n >= 4:( k3 g! Z8 V& k% y: i& p
return "Chat4.htm"- h+ p+ j! T7 i% ]2 i8 m- f
return "Collected "+str(n)+" of 4 fangs", l! i. |% `9 W. t
return
Скопировать код
Если у игрока нет клыков (n=0), то мы получаем занчение переменной 'chat0'. Когда метод onKill вызван в первый раз, то пока ни каких переменных не имеется и python возвращает значение None. В этом случае объявляется переменная и показывается диалог Chat0.htm. Когда мы убиваем keltir, но не получаем с него клык, функция st.get('chat0') возвращает строку true, а не None. И во второй раз окно с Chat0.htm не появится, но в окне чата появится строчка «Collected 0 of 4 fangs». По тому же принципу сделано и с Chat1.htm. 7 ^) }: i: \6 X; V0 Y* w% h $ S: ^7 z8 }( `2 O- T+ _$ k . N- u3 [2 d( k' `3 {: lВот конечный рабочий вариант квеста:* {5 O$ ~' y3 T* C% B, l; {4 [
import sys ( I. l8 M! R5 Y7 b2 t+ Q' r1 {0 g- E
from net.sf.l2j.gameserver.model.quest import State , e: Y5 l, c; d2 H
from net.sf.l2j.gameserver.model.quest import QuestState ! Q) g# ~; Z7 y' `5 s3 [: A
from net.sf.l2j.gameserver.model.quest.jython import QuestJython as JQuest ( ~( e1 x% V" M7 e