Для этого квеста больше ничего не надо. Все необходимое для корректной работы квеста уже добавили. Вот полный текст квеста:; i9 A& ]9 F9 i& g7 |3 |6 `1 L! R# J
Теперь рассмотрим, как это работает./ @; G( P& r% e' k# o* t
Игрок подходит к начальному NCP (в данном случае 7056), нажимает на «Quest». Квест будет создан и состояние квеста перейдет к CREATED и игроку будет показана страничка Start.htm с описанием квеста. Тогда метод onEvent, поле открытия странички Start.htm переведет состояние квеста в STARTED и игроку будет показана страничка Started.htm, где будет опсание того, как найти keltirs и .т.д. % \7 R. R$ t1 E! o {* p3 n " l1 t* G* a3 K6 k6 i! Y+ j( B0 v9 F) ^4 i L
При состоянии STARTED будет зарегистрирован дроп «fangs» при убийстве keltirs. Игрок может вернуться к стартовому NCP и спросить о квесте – метод onEvent будет вызван снова. Если у игрока не хватает необходимого количества предметов, то метод check() не переведет квест в следующее состояние и Started.htm будет показана снова. Но если игрок собрал необходимее количество предметов (в данном случае 4 клыка), то метод check() вызовет метод completed() который переведет квест в новое состояние COMPLETED, заберет все клыки, даст карту мира, т.к. это награда за квест, покажет Completed.htm и завершит квест. v8 D) `( ?/ Z, l* t. `
+ S7 C7 Q6 q% c. u4 y ( R5 Q/ Y* ^3 [) i. j; MТеперь давайте сделаем наш квест более похожим на то, что он должен из себя представлять. " ^1 k, P$ R: uПрежде всего у нас есть 3 метода для объявления их в Яве – onTalk, onKill и onEvent. Если методы onTalk и onKill не объявлены, то за них все будет делать метод onEvent, т.е. определять квестовых монстров и вызывать диалоги NCP. Есть примечание, методы onTalk и onKill будут вызывать только диалоги с NCP в зависимости от текущего состояния квеста. Метод onKill будет вызываться только тогда, когда мы убиваем квестового монстра. 4 c: P# w, V* R5 U9 H- U% ^$ I5 g# x; I. o, r: x, k7 f- C
7 T7 A4 g8 C) J9 S+ Y$ Y" [
Давайте рассмотрим как вызывается метод onKill при убийстве keltir в состоянии квеста STARTED:% [3 g. r. n2 m5 \
STARTED.addKillId(KELTIR_NPC_ID)
Скопировать код
и метод onKill в классе Quest: * c) Z0 }. e( Z0 B% v$ }5 A6 O6 X4 `) V3 V: K
class Quest (JQuest): m: [0 u) o& z' o, s! T6 \) \3 m$ t
... # ~% T3 P! ~/ Z3 R# Q( z. ]- o
def onKill (self,npcId,st):7 P: W) w6 p# M$ t. ^
if npcId == KELTIR_NPC_ID: ( }) w; q! B+ k( W( h9 j: p6 K; O
n = getCount(st)$ l# |$ K9 d; {+ h9 N
if n == 0:, G3 c7 b- V8 o1 j' U
return "Chat0.htm"7 V) W$ X: s( ~
elif n == 1:6 c; e" g; @* m. w* p
return "Chat1.htm" 7 M) O+ U$ U' {* h6 d9 O$ C
elif n >= 4: - F) g$ X/ O2 W- B A- k
return "Chat4.htm"8 j) \; e4 a! f6 B: e% ~5 f" c
return "Collected "+str(n)+" of 4 fangs"+ {/ Y" A4 E; W$ l1 {# l3 l' G
return
Скопировать код
Метод onKill (а так же метод onTalk) имеет следующие параметры:0 M0 O' h& U- L$ u. l
5 I& h0 k3 D% W5 R! W6 n6 K& _0 G" e/ d$ C3 n2 I
• self – квест% h9 S* ]/ \$ o% W: D8 K; A: Z2 q
• npcId – ID NCP, которого мы должны убивать (если это метод onTalk, то ID того NCP, с которым мы должны поговорить). & |0 y6 ~5 B% T• st – текущее состояние игрока.+ D/ {5 }; B+ w; ]
$ ^* B0 W$ N* C" }! i0 W
; S$ _ @4 c% W/ ]
В этом методе мы проверяем и отмечаем, является ли убитый NCP keltir’ом. В основном эта проверка не нужна, т.к. у нас только KELTIR_NPC_ID.) C& t3 ^) O* ]! U' M4 ]5 O7 L
" s5 {0 X% J1 i, Y! [. K
I! {3 w9 H: Y& h! j6 M& L8 p3 w1 E
Затем проверяем количество предметов (в данном случае количество клыков), и если их вообще нет, то возвращаем строку "Chat0.htm", если только один предмет, то возвращаем строку "Chat1.htm", если же предметов 4 или больше, то "Chat4.htm". Если строка возвращена из методов onEvent, onKill или onTalk, то сервер покажет соответствующие htm. В Chat0.htm может иметь следующий текст: «Вы не имеете ни одного клыка, возвращайтесь позже, когда соберете 4 штуки и бла, бла, бла…», в Chat1.htm может быть следующий текст: «У Вас всего 1 клык, по этому соберите еще…». В Chat4.htm – «Вы собрали необходимое количество предметов, возвращайтесь к вашему тренеру, что бы завершить квест…» ( E3 ~) m3 u- o' |2 i/ W% I- V# S, Q" o, O8 \/ l8 K
. C* j: B) {9 H6 X5 MПримечание: если в строка return начинается с "<html>", то будет показана страничка html с текстом, который стоит далее. Так вместо:2 T% c: j. E u7 @ S. Z) S
return "Chat4.htm"( i1 b- L7 S/ @$ {5 L$ {
/ U& Z0 F" B& Z2 W; }6 p) X% L4 H- G* ]) Z4 e
можно поставить: 9 h% x8 A) d {0 v8 v. Z
return "<html><body>Return to your trainer to complete the quest</body></html>"
Скопировать код
Так же если строка заканчивается без .htm или в начале нет <html>, то текст будет выведен, как системное сообщение в окне чата. В нашем случае мы сделаем так, что бы при каждом убийстве keltik выводилось системное сообщение: «Собрано N из 4-х клыков». ( X, y& o" M O% r2 l- }3 Q7 X, i7 K' i+ X! w) K+ I! O
# T& A( F+ C+ b5 I& i0 a8 rНаш код для onKill имеет один недостаток. Он будет постоянно показывать Chat0.htm, Chat1.htm и Chat4.htm, нам же необходимо, что бы Chat0.htm и Chat1.htm показывались только один раз. Как нам это сделать? С помощью переменных.( O) [5 o& i) \( d
6 t% D6 a" p h/ k
/ ^) j; @9 X4 `" h; B
В каждом квесте строки могут храниться с помощью переменных. Эти переменные сохраняются в Вашей БД. В каждом методе мы можем назначить, прочитать и удалить переменные. Давайте изменим метод onKill, так что бы каждый диалог вызывался только один раз. # ]- w/ C4 } E4 Q2 ~. L5 B; f
def onKill (self,npcId,st): ' e& U) @6 d) f4 g" g
if npcId == KELTIR_NPC_ID:. o# ^3 `: F! ^+ d
n = getCount(st): x/ k' p( s: B ~8 o; H
if n == 0: & }$ p, D& }, W# e% j- a
if st.get('chat0') == None : ( p# \2 \8 T. Y+ D
st.set("chat0", "true") . Y4 N6 n( g$ e! }* x! I
return "Chat0.htm" % F2 g! r6 n7 a6 o0 [
elif n == 1: `1 e8 r; w7 X6 \+ L" ?( b
if st.get('chat1') == None :9 t! i1 p8 y0 K6 ~/ `! m' Q+ b
Если у игрока нет клыков (n=0), то мы получаем занчение переменной 'chat0'. Когда метод onKill вызван в первый раз, то пока ни каких переменных не имеется и python возвращает значение None. В этом случае объявляется переменная и показывается диалог Chat0.htm. Когда мы убиваем keltir, но не получаем с него клык, функция st.get('chat0') возвращает строку true, а не None. И во второй раз окно с Chat0.htm не появится, но в окне чата появится строчка «Collected 0 of 4 fangs». По тому же принципу сделано и с Chat1.htm.% ^2 b, {- ]* m. l1 P6 R/ a
+ x9 f$ L; L, @0 |% U6 m5 J: A3 d6 T6 K( x, Y2 w# i( h) x
Вот конечный рабочий вариант квеста:/ u8 D+ x# z) a# o* i
import sys " j1 T: S0 N8 [& P. g* A
from net.sf.l2j.gameserver.model.quest import State : J9 ~& |$ |, u7 Q7 t; O
from net.sf.l2j.gameserver.model.quest import QuestState $ V8 e. n. e2 P7 r' V" @3 ]
from net.sf.l2j.gameserver.model.quest.jython import QuestJython as JQuest 3 v+ J, V& l" H* R( _% o$ i