Зарегистрируйтесь сейчас чтобы найти еще больше друзей, и получить полноценный доступ ко всем функциям сайта!
Для просмотра Вам необходимо авторизоваться Если Вы еще не зарегистрированы, перейдите по ссылке:Зарегистрироваться  
 
x
 
Хроники        Interlude3 b: m+ @$ S9 l- J2 u 
Сборка        L2j6 f) r3 J) X( \ 
Обратите внимание: в файле htm стартового NCP обязательно должна быть ссылка на квест: 
( z  S, E$ O1 h4 D+ I7 @2 N* W% K. ~* S- STARTED.addQuestDrop(KELTIR_NPC_ID,FANGS_ITEM_ID,DROP_RATE)
 
  Скопировать код Для этого квеста больше ничего не надо. Все необходимое для корректной работы квеста уже добавили. Вот полный текст квеста:/ }. J, \1 }" N9 _8 D 
1 }  ~% @, \6 E3 K! q) S& E/ h 
- if getCount(st) >= 4 :. p/ {! d0 i' E4 A. K
 
 - completed(st)% L! C) @0 g& h2 Z" P( _, D
 
 -   return
 
- Y8 p: X5 T1 s, }. s$ s  
, f9 f# t+ i7 j: |- class Quest (JQuest):
 
- v" h) \% l0 R -   def __init__(self,id,name,descr): JQuest.__init__(self,id,name,descr)3 u% N0 O1 t8 M' Q0 ?% h
 
 -   def onEvent (self,event,st):
 
# S! X4 ^* q; X& y2 m! u - id = st.getState()
 
2 H' Q. S! f" p& }  z+ C - if   id == CREATED  : st.setState(STARTED)
 
; [; ^* \9 [: a$ D - elif id == COMPLETED: pass- _1 `5 c: A/ D; r* \
 
 - elif id == STARTED  : check(st)/ H: Y& [' O" C+ n8 _
 
 - return
 
% @% y3 h9 T  t: E9 M% U  
5 h% S5 o- |, D1 g+ v- QUEST     = Quest(201,"Tutorial", "Tutorial quest"), _2 o" u& ^3 a7 t7 ?# Q7 G
 
 - CREATED   = State('Start',     QUEST)
 
3 y" C. N/ N2 a* | - STARTED   = State('Started',   QUEST)
 
- G7 l5 b' b9 t - COMPLETED = State('Completed', QUEST), s# p3 n& A2 k, i  F: S
 
 - + X8 F5 ^% ~8 Z3 U9 I
 
 - QUEST.setInitialState(CREATED)  D. _" m8 K" a: [( s# A7 |
 
 - QUEST.addStartNpc(7056)
 
2 V- }/ ?" i; z$ J- ^  E# l6 W* { - STARTED.addQuestDrop(KELTIR_NPC_ID,FANGS_ITEM_ID,DROP_RATE)
 
  Скопировать код Теперь рассмотрим, как это работает.5 L* p" |* q9 Y 
Игрок подходит к начальному NCP (в данном случае 7056), нажимает на «Quest». Квест будет создан и состояние квеста перейдет к CREATED и игроку будет показана страничка Start.htm с описанием квеста. Тогда метод onEvent, поле открытия странички Start.htm переведет состояние квеста в STARTED и игроку будет показана страничка Started.htm, где будет опсание того, как найти keltirs и .т.д.  {, L0 j8 `4 {' E' D4 c 
 
# @9 [/ Y* K7 |: P: I8 ^# J& U, B: m0 n( I8 P" T8 S7 G1 [3 q 
При состоянии STARTED будет зарегистрирован дроп «fangs» при убийстве keltirs. Игрок может вернуться к стартовому NCP и спросить о квесте – метод onEvent будет вызван снова. Если у игрока не хватает необходимого количества предметов, то метод check() не переведет квест в следующее состояние и Started.htm будет показана снова. Но если игрок собрал необходимее количество предметов (в данном случае 4 клыка), то метод check() вызовет метод completed() который переведет квест в новое состояние COMPLETED, заберет все клыки, даст карту мира, т.к. это награда за квест, покажет Completed.htm и завершит квест. 
( F% L& Q: N- _& Z5 k 
8 A1 _! j( A6 F1 m0 p. g% v/ ~( o% _% D4 E 
Теперь давайте сделаем наш квест более похожим на то, что он должен из себя представлять. 
8 K: P" l# l( IПрежде всего у нас есть 3 метода для объявления их в Яве – onTalk, onKill и onEvent. Если методы onTalk и onKill не объявлены, то за них все будет делать метод onEvent, т.е. определять квестовых монстров и вызывать диалоги NCP. Есть примечание, методы onTalk и onKill будут вызывать только диалоги с NCP в зависимости от текущего состояния квеста. Метод onKill будет вызываться только тогда, когда мы убиваем квестового монстра.2 H& ~5 ~4 e% G$ O 
% I) [) F$ A1 ^ 
 
3 p, q* ^& a* @% x" R7 m6 TДавайте рассмотрим как вызывается метод onKill при убийстве keltir в состоянии квеста STARTED:# ~: ]- J; c9 H- ~9 l# @" c 
- STARTED.addKillId(KELTIR_NPC_ID)
 
  Скопировать код и метод onKill в классе Quest: 
9 {1 }4 H& q4 o 
5 T% V9 L3 Y. ^- class Quest (JQuest):
 
, T, b  u8 Y5 Y+ \0 |, @ -   .../ F- K% F, x: J3 @' g
 
 -   def onKill (self,npcId,st):" T/ `( {/ z3 g& M3 \1 _' ~' f; l; n
 
 - if npcId == KELTIR_NPC_ID:/ q  }0 A: U% N
 
 -    n = getCount(st)
 
7 R1 R2 Q: e6 S  A( S -    if   n == 0:
 
! F8 u& r- i- G -        return "Chat0.htm"
 
- O, W% ]$ w3 n! T+ A -    elif n == 1:
 
9 ?0 e, H6 ]7 A; F -        return "Chat1.htm": D4 c- u% [2 ~
 
 -    elif n >= 4:" U! f0 N3 ]5 B) r' G. Z- X
 
 -        return "Chat4.htm"
 
$ G1 f3 }- ?2 ~2 }- U/ n -    return "Collected "+str(n)+" of 4 fangs"6 P! F. G/ `1 T0 Y  Q
 
 - return
 
  Скопировать код Метод onKill (а так же метод onTalk) имеет следующие параметры: 
- y) ~) ]$ e# f! T. F! I$ j( X% n# [) s; N' u2 C7 L 
 
7 u& j7 ^, w9 E6 g' N• self – квест: g+ t! }/ a; |0 | 
• npcId – ID NCP, которого мы должны убивать (если это метод onTalk, то ID того NCP, с которым мы должны поговорить).5 e, s/ [$ D( m( t1 n  M 
• st – текущее состояние игрока. 
/ W0 U; z1 j; o8 Z$ Z 
( l8 i, U4 W, Z' y( y$ v. x' y  n6 |2 p% K& r- L- k 
В этом методе мы проверяем и отмечаем, является ли убитый NCP keltir’ом. В основном эта проверка не нужна, т.к. у нас только KELTIR_NPC_ID.. d% K  I( m" t) w3 q 
/ ^8 i) s: V! t& q  p" \ 
 
# s( {5 v# t' \9 I7 Y% HЗатем проверяем количество предметов (в данном случае количество клыков), и если их вообще нет, то возвращаем строку "Chat0.htm", если только один предмет, то возвращаем строку "Chat1.htm", если же предметов 4 или больше, то "Chat4.htm". Если строка возвращена из методов onEvent, onKill или onTalk, то сервер покажет соответствующие htm. В Chat0.htm может иметь следующий текст: «Вы не имеете ни одного клыка, возвращайтесь позже, когда соберете 4 штуки и бла, бла, бла…», в Chat1.htm может быть следующий текст: «У Вас всего 1 клык, по этому соберите еще…». В Chat4.htm – «Вы собрали необходимое количество предметов, возвращайтесь к вашему тренеру, что бы завершить квест…»9 L9 P# s" S8 J 
 
- `. Z6 J( y# Z+ Y% o% f. q& M* `5 W+ H. G6 j/ k; z 
Примечание: если в строка return начинается с "<html>", то будет показана страничка html с текстом, который стоит далее. Так вместо:% s3 W# r. K5 m1 x 
return "Chat4.htm". H" l- i  a- r9 Y3 u 
0 h' ?0 N9 ^1 F! g  _ 
 
3 M0 f$ U- \# V3 w$ _5 Wможно поставить:4 Q: Z8 K' C0 W. c6 b: d 
- return "<html><body>Return to your trainer to complete the quest</body></html>"
 
  Скопировать код Так же если строка заканчивается без .htm или в начале нет <html>, то текст будет выведен, как системное сообщение в окне чата. В нашем случае мы сделаем так, что бы при каждом убийстве keltik выводилось системное сообщение: «Собрано N из 4-х клыков».4 O  b: R/ c  y* c: C 
 
( Z3 y+ L0 Z& Q4 ~ 
# O! X- N; k1 i% s7 iНаш код для onKill имеет один недостаток. Он будет постоянно показывать Chat0.htm, Chat1.htm и Chat4.htm, нам же необходимо, что бы Chat0.htm и Chat1.htm показывались только один раз. Как нам это сделать? С помощью переменных.2 ]% i3 d; H; C% m) l$ y0 X 
& T7 T# ^- e" a9 K/ p) V 
1 O: j9 `) x3 [4 U+ t6 D) @& | 
В каждом квесте строки могут храниться с помощью переменных. Эти переменные сохраняются в Вашей БД. В каждом методе мы можем назначить, прочитать и удалить переменные. Давайте изменим метод onKill, так что бы каждый диалог вызывался только один раз. 
/ j: D& G+ \  @/ K# e! [' }- def onKill (self,npcId,st):
 
7 g# g! P7 j2 G! l' d - if npcId == KELTIR_NPC_ID:9 t, z/ d' @0 @: [% k
 
 - n = getCount(st)
 
7 o- ?+ e  }' V/ ^8 f - if n == 0:
 
- N) n% n9 @9 B - if st.get('chat0') == None :
 
9 S' H3 c" Y0 ~# k - st.set("chat0", "true")
 
' T9 g, o' t' R4 H - return "Chat0.htm"
 
: u6 x2 t* I  g" i - elif n == 1:
 
4 K: J' t6 s( R  w( N - if st.get('chat1') == None :* `: J9 \) F# y% F5 E" C
 
 - st.set("chat1", "true")( U. O' K6 t3 g4 t  ?' z; l
 
 - return "Chat1.htm"! S, `- y( s. ?! U3 P8 o
 
 - elif n >= 4:
 
/ d, h  w2 M# Y, w1 [% y% M - return "Chat4.htm", a9 W& q$ w6 N- V6 C, w
 
 - return "Collected "+str(n)+" of 4 fangs"
 
* a- W  k/ ]  S- c) @& I, ? - return
 
  Скопировать код Если у игрока нет клыков (n=0), то мы получаем занчение переменной 'chat0'. Когда метод onKill вызван в первый раз, то пока ни каких переменных не имеется и python возвращает значение None. В этом случае объявляется переменная и показывается диалог Chat0.htm. Когда мы убиваем keltir, но не получаем с него клык, функция st.get('chat0') возвращает строку true, а не None. И во второй раз окно с Chat0.htm не появится, но в окне чата появится строчка «Collected 0 of 4 fangs». По тому же принципу сделано и с Chat1.htm. 
2 N2 E5 ^9 z3 a/ J: z5 x5 g* b; D( M. f* v 
' @! L4 M( \" T+ L0 k- ?( g. m 
Вот конечный рабочий вариант квеста: 
: V* J0 t1 i" k& }$ w/ [# w7 W! E- import sys3 w  c3 t9 `9 }0 m! d2 t0 r  {
 
 - from net.sf.l2j.gameserver.model.quest import State7 H. r& n, @+ r/ J
 
 - from net.sf.l2j.gameserver.model.quest import QuestState
 
) P+ B1 _  l& Y - from net.sf.l2j.gameserver.model.quest.jython import QuestJython as JQuest7 F4 j7 u/ r7 s- D" ]( V0 `, z
 
  
1 N) k9 X5 N# r2 Q1 v- KELTIR_NPC_ID = 12082
 
! @- U" E3 v9 F: V' a) u1 B8 G! R - FANGS_ITEM_ID = 1859
 
5 |3 \/ |* a- Z' h - DROP_RATE    = 500000
 
$ y% A3 X" v" _ - 3 T# l  ]% t5 [# E4 ?
 
 - WORLD_MAP_ITEM_ID = 1665. C/ B) V6 T+ O
 
 - ; L% u% N4 h% Q9 N$ x/ q$ t/ O0 I
 
 - def getCount(st) :# f3 U/ \& d8 h; l. @) ]% Y2 ]" c1 T
 
 - return st.getQuestItemsCount(FANGS_ITEM_ID)
 
4 C9 L" e+ K% Z" L  C) B  
; x* `- q7 C7 q* x: |% s8 U- def completed(st) :
 
9 B0 S; |5 C. r( C* k! R - st.setState(COMPLETED), v% D  |+ t( ~0 U, K" a4 R; g2 _
 
 - st.clearQuestDrops()
 
- p! G' I7 p; ?% O) I - st.takeItems(FANGS_ITEM_ID,-1)4 ]7 H/ n, f; h; w; ]. w" b
 
 - st.giveItems(WORLD_MAP_ITEM_ID,1)+ |) i' r* P' V$ ]0 C; I& ]3 [
 
 - st.exitQuest(False)
 
. `/ \8 i3 ~; |! l4 | - return9 w- H. @0 s2 I6 J  r
 
 - , x- L- c4 z4 U$ t( P' Y7 f- m
 
 - def check(st) :
 
7 l1 a. Z$ q0 H. @9 h4 b1 S - if getCount(st) >= 4 :1 [% p- a& E$ x
 
 - completed(st)8 _. q5 m4 G/ ?7 `8 k( z" Z7 A  l4 v
 
 - return& w$ N( y$ D5 z
 
  
$ g1 q4 m; R, {0 h5 t8 L2 d3 q- class Quest (JQuest):
 
, {0 H' W! g& T7 U  
" ?+ V; h' u9 |- V# O- def __init__(self,id,name,descr): JQuest.__init__(self,id,name,descr)
 
5 D( x5 K# v$ } - & h' N9 h1 @9 c0 O6 T4 B4 o
 
 - def onEvent (self,event,st):
 
/ @& p3 R" P- d# \6 j# K# Y1 m - id = st.getState()
 
/ Z  v# y' w+ k  G( s4 u - if id == CREATED : st.setState(STARTED)  X( J% y. L% ?8 C3 G# z0 t0 N
 
 - elif id == COMPLETED: pass! t' g8 S) c1 x: _- y
 
 - elif id == STARTED : check(st)8 r1 P5 w( I" m8 q$ y& x
 
 - return0 b+ T# H( I! A5 J% e( }8 a% H  H
 
 - 8 g# M2 G: S/ A9 G9 f6 B& K/ K
 
 - def onKill (self,npcId,st):
 
6 a+ L! T  |# d$ H" A* V - if npcId == KELTIR_NPC_ID:2 \0 {- i3 z, f7 K9 F2 {$ _
 
 - n = getCount(st)
 
/ S% }$ P# j  M2 u* E - if n == 0:6 w0 z% G" E! b7 q: P4 v
 
 - if st.get('chat0') == None :5 |) _9 g% G8 i! Y# l
 
 - st.set("chat0", "true")
 
. ^3 H- `9 o. E" z" y  A - return "Chat0.htm"
 
# d& j1 V9 B- Z3 O  |' l5 {# \" Z. V - elif n == 1:
 
. k* Q3 m* N  a* B9 g& H( c - if st.get('chat1') == None :
 
4 H. C* n3 g' @; ~) _ - st.set("chat1", "true")
 
& E7 G5 p1 ^. L7 E* U - return "Chat1.htm"8 e: ?/ s/ |  k* }
 
 - elif n >= 4:
 
+ |6 j5 S& g; A8 Y) U - return "Chat4.htm"% V6 q" H4 \1 S5 Z5 }
 
 - return "Collect "+str(n)+" of 4 fangs"& ?" C+ R- L! u
 
 - return
 
; R9 `3 P& D& F. c# H  
% _( Q7 A$ ^! w3 B- J! i  Z# u- QUEST    = Quest(201, "Tutorial", "Tutorial quest")
 
- g* W6 x7 z9 Q7 Z" \& v# p2 O" u6 ] - CREATED = State('Start',    QUEST)6 b( G3 A/ Q# L  S" d  Q
 
 - STARTED = State('Started', QUEST)
 
- {$ W" T7 B4 A: i+ U# e% N, Q- q - COMPLETED = State('Completed', QUEST)
 
1 @" Q4 S% c* c0 N  
9 V! Z+ h- O- ^1 C& ]0 O/ S+ p- QUEST.setInitialState(CREATED)6 j/ t  u  z( u" }5 D7 @
 
 - QUEST.addStartNpc(7056)
 
3 w) [% w4 b- K  p  r - QUEST.addStartNpc(7012)2 ?& U$ u/ L& R/ k5 H
 
 - QUEST.addStartNpc(7009)
 
) I- S% y8 p0 _& p; C; K! U - QUEST.addStartNpc(7011)& D! B8 |/ Y3 }, h. O1 I" ~
 
 - 6 y6 m. L% ?, o* a- z
 
 - STARTED.addQuestDrop(KELTIR_NPC_ID,FANGS_ITEM_ID,DROP_RATE)
 
* _( N$ Z+ r  b- @' c9 M - STARTED.addKillId(KELTIR_NPC_ID): ?# |6 `; Y) G6 m: s9 Y7 y) {
 
 - STARTED.addTalkId(7056), {7 o3 b5 M' _* t
 
 - STARTED.addTalkI d(7012)
 
8 h% E5 i6 N' H3 s; R& O - STARTED.addTalkId(7009)5 ^9 ?& K# b) R& I& I1 O6 p7 v. q
 
 - STARTED.addTalkId(7011)
 
  Скопировать код 0 B2 M& ?5 O2 N2 X( G 
6 j3 @& R- ^1 U) {4 q 
 |