Зарегистрируйтесь сейчас чтобы найти еще больше друзей, и получить полноценный доступ ко всем функциям сайта!
Для просмотра Вам необходимо авторизоваться Если Вы еще не зарегистрированы, перейдите по ссылке:Зарегистрироваться  
 
x
 
Хроники        Interlude 
* f& B5 \" t0 \8 H" }8 l. eСборка        L2j 
! i/ [) V; G7 k8 p+ ?: A' rОбратите внимание: в файле htm стартового NCP обязательно должна быть ссылка на квест: 
3 e# i) L+ |* C) w; ]8 W- STARTED.addQuestDrop(KELTIR_NPC_ID,FANGS_ITEM_ID,DROP_RATE)
 
  Скопировать код Для этого квеста больше ничего не надо. Все необходимое для корректной работы квеста уже добавили. Вот полный текст квеста:3 J/ K& k( M# B$ L* B& S, ~ 
 
' J0 o! M4 A! K4 s& c; e6 g- ~- if getCount(st) >= 4 :4 j& `9 V5 {+ n
 
 - completed(st)
 
! F% z! v/ g2 Q. @  [1 P -   return! D% }% Q4 @# M
 
  
3 I. F1 e) x) [8 _6 L$ H6 Z- class Quest (JQuest):
 
" M6 G0 D, n4 ^' H1 S6 H- W$ N -   def __init__(self,id,name,descr): JQuest.__init__(self,id,name,descr)
 
4 B" L6 ^0 \  } -   def onEvent (self,event,st):
 
6 A3 r/ e, p0 C# _3 h - id = st.getState()
 
7 D$ [9 D! l1 V- @ - if   id == CREATED  : st.setState(STARTED)
 
, y3 B3 q) u) q7 D4 _ - elif id == COMPLETED: pass
 
4 C# [% U: h- W! u3 V - elif id == STARTED  : check(st)/ [. j3 w8 U& t% o$ d
 
 - return  X6 z( r7 f5 ~  L7 I4 h
 
 - 7 N2 U' |/ \; g4 ~5 f0 T5 n
 
 - QUEST     = Quest(201,"Tutorial", "Tutorial quest")' L! d3 C* w( U* J  q
 
 - CREATED   = State('Start',     QUEST)
 
: V/ `. n" X! ?# r9 @ - STARTED   = State('Started',   QUEST)# K; n$ m. K+ L
 
 - COMPLETED = State('Completed', QUEST)
 
: O/ l$ f  ?$ {' F  
* Q! W. B# @1 U; G8 e- QUEST.setInitialState(CREATED)
 
! ?; u$ @+ W! x9 j6 R& n6 H( G - QUEST.addStartNpc(7056)
 
5 s  K1 s2 U  t) T - STARTED.addQuestDrop(KELTIR_NPC_ID,FANGS_ITEM_ID,DROP_RATE)
 
  Скопировать код Теперь рассмотрим, как это работает. 
; ?3 @. v  e$ IИгрок подходит к начальному NCP (в данном случае 7056), нажимает на «Quest». Квест будет создан и состояние квеста перейдет к CREATED и игроку будет показана страничка Start.htm с описанием квеста. Тогда метод onEvent, поле открытия странички Start.htm переведет состояние квеста в STARTED и игроку будет показана страничка Started.htm, где будет опсание того, как найти keltirs и .т.д.5 V# q1 P' u2 g4 R1 |) p 
 
0 M2 _6 d! [% Z9 U0 s3 c 
7 h4 o, M: Y4 L+ FПри состоянии STARTED будет зарегистрирован дроп «fangs» при убийстве keltirs. Игрок может вернуться к стартовому NCP и спросить о квесте – метод onEvent будет вызван снова. Если у игрока не хватает необходимого количества предметов, то метод check() не переведет квест в следующее состояние и Started.htm будет показана снова. Но если игрок собрал необходимее количество предметов (в данном случае 4 клыка), то метод check() вызовет метод completed() который переведет квест в новое состояние COMPLETED, заберет все клыки, даст карту мира, т.к. это награда за квест, покажет Completed.htm и завершит квест.; [3 M# C) \  ` 
 
9 r* |# W. V( U' n0 |$ f6 @6 X$ f: q- ^. Z6 s. U" I 
Теперь давайте сделаем наш квест более похожим на то, что он должен из себя представлять.8 w, k; S; r4 ~) ~, i: Q8 ? 
Прежде всего у нас есть 3 метода для объявления их в Яве – onTalk, onKill и onEvent. Если методы onTalk и onKill не объявлены, то за них все будет делать метод onEvent, т.е. определять квестовых монстров и вызывать диалоги NCP. Есть примечание, методы onTalk и onKill будут вызывать только диалоги с NCP в зависимости от текущего состояния квеста. Метод onKill будет вызываться только тогда, когда мы убиваем квестового монстра. 
$ G4 x# a8 b! \6 P 
! c( A* e9 ], d; z! K) w 
* F: u( E& c% K3 Q+ p7 fДавайте рассмотрим как вызывается метод onKill при убийстве keltir в состоянии квеста STARTED:3 W/ _. f; K5 R1 I4 g! j4 D/ z  W- M 
- STARTED.addKillId(KELTIR_NPC_ID)
 
  Скопировать код и метод onKill в классе Quest:+ v- Q3 }* |; D: h 
 
$ d: w2 A3 H0 C( b3 L4 I- O- class Quest (JQuest):
 
* a. G$ t# [/ v4 q -   ..." u+ H3 K6 m% N/ k3 f% D  V. ?$ [
 
 -   def onKill (self,npcId,st):
 
" ^% `) ?- n, r3 K# w$ W - if npcId == KELTIR_NPC_ID:
 
$ a0 ?2 V" {8 V7 D! ?) X -    n = getCount(st)
 
% }. T9 O; v& P0 i" a -    if   n == 0:
 
4 \2 T; Q3 i# _0 P* M. ] -        return "Chat0.htm"
 
+ ^% M* R8 l* X9 x -    elif n == 1:
 
% F: E$ K0 J6 K( O  s* N3 N" w -        return "Chat1.htm"$ D. n/ U; E6 v
 
 -    elif n >= 4:3 C, o; `6 T" a+ S& Y
 
 -        return "Chat4.htm"3 |  X& K( |2 L) j+ T% A: [' j
 
 -    return "Collected "+str(n)+" of 4 fangs"
 
" Y* O: S2 r* v - return
 
  Скопировать код Метод onKill (а так же метод onTalk) имеет следующие параметры: 
  X! `+ E# c" x. J! N! P  G  x5 v8 K& P5 A/ @( ~$ e5 f* q 
) ?4 v# x3 S' |% U' N 
• self – квест 
# }6 D: h. ~3 r1 {• npcId – ID NCP, которого мы должны убивать (если это метод onTalk, то ID того NCP, с которым мы должны поговорить). 
, |, c( L. m+ W. j0 h2 ?• st – текущее состояние игрока.! Y+ i7 G/ R2 W# b* [! a 
 
/ T# Z! Z' G! d4 R 
( d+ }* s) \& k) Z% n! }В этом методе мы проверяем и отмечаем, является ли убитый NCP keltir’ом. В основном эта проверка не нужна, т.к. у нас только KELTIR_NPC_ID.6 Y6 r3 u$ B8 \- f 
 
) ?% A% f+ O4 _" _$ g' L) l% r4 Q4 X4 ?# F# n7 I 
Затем проверяем количество предметов (в данном случае количество клыков), и если их вообще нет, то возвращаем строку "Chat0.htm", если только один предмет, то возвращаем строку "Chat1.htm", если же предметов 4 или больше, то "Chat4.htm". Если строка возвращена из методов onEvent, onKill или onTalk, то сервер покажет соответствующие htm. В Chat0.htm может иметь следующий текст: «Вы не имеете ни одного клыка, возвращайтесь позже, когда соберете 4 штуки и бла, бла, бла…», в Chat1.htm может быть следующий текст: «У Вас всего 1 клык, по этому соберите еще…». В Chat4.htm – «Вы собрали необходимое количество предметов, возвращайтесь к вашему тренеру, что бы завершить квест…» 
/ M* p  D+ q$ T- C 
1 ?! v+ M. C6 ?( \( m! d$ d) R. K( J" H' ?5 u5 s& A8 i! O# Q 
Примечание: если в строка return начинается с "<html>", то будет показана страничка html с текстом, который стоит далее. Так вместо: 
2 J# r7 |8 Y8 e% ]) rreturn "Chat4.htm"# C0 K; P$ W; Q0 e1 ~5 C+ h 
: m! P5 Q8 w5 \5 | 
 
" ]$ @5 I9 w$ j  w7 }. _* G9 ^можно поставить:3 ~9 a( {- q+ w, V- O4 j 
- return "<html><body>Return to your trainer to complete the quest</body></html>"
 
  Скопировать код Так же если строка заканчивается без .htm или в начале нет <html>, то текст будет выведен, как системное сообщение в окне чата. В нашем случае мы сделаем так, что бы при каждом убийстве keltik выводилось системное сообщение: «Собрано N из 4-х клыков». 
9 V% I. i7 c" @% ` 
  y- ~: p! X6 J9 Y6 `, S" e3 f. b4 Y 
/ E7 B. p5 l, C+ TНаш код для onKill имеет один недостаток. Он будет постоянно показывать Chat0.htm, Chat1.htm и Chat4.htm, нам же необходимо, что бы Chat0.htm и Chat1.htm показывались только один раз. Как нам это сделать? С помощью переменных. 
; m' c4 m  ]3 U6 z/ Q# ~ 
2 |& B" `% x4 I+ N, |: f. h* r 
6 n6 ~2 n& f3 q" q( ?, O3 [В каждом квесте строки могут храниться с помощью переменных. Эти переменные сохраняются в Вашей БД. В каждом методе мы можем назначить, прочитать и удалить переменные. Давайте изменим метод onKill, так что бы каждый диалог вызывался только один раз.; I: q; Y9 F& J0 j* E% u 
- def onKill (self,npcId,st):) o: N8 a/ o- P8 u- ^
 
 - if npcId == KELTIR_NPC_ID:
 
1 q2 e% ~- f  v: m" \" w' |, x, w - n = getCount(st)
 
4 J/ ^- L6 B% V+ x$ ^ - if n == 0:7 D8 C! i; [' R
 
 - if st.get('chat0') == None :
 
/ j8 w2 C4 M& H4 l. Y - st.set("chat0", "true")
 
9 P; K' g: c% v. ^; A, n' r - return "Chat0.htm"% u4 P" j' |# |& U. r
 
 - elif n == 1:
 
4 _1 n/ S5 P+ J8 a. d( h - if st.get('chat1') == None :( t6 l+ ]4 L6 v. A( d, H
 
 - st.set("chat1", "true")
 
4 e9 X) Q1 h1 I5 @ - return "Chat1.htm"
 
: b! y6 c; y9 X7 \! ? - elif n >= 4:' E& h1 w5 [) e1 \' g. L# V
 
 - return "Chat4.htm"
 
2 F8 N  f/ S" _2 @" T! u( E* } - return "Collected "+str(n)+" of 4 fangs"
 
; ]; A; ?# D6 K - return
 
  Скопировать код Если у игрока нет клыков (n=0), то мы получаем занчение переменной 'chat0'. Когда метод onKill вызван в первый раз, то пока ни каких переменных не имеется и python возвращает значение None. В этом случае объявляется переменная и показывается диалог Chat0.htm. Когда мы убиваем keltir, но не получаем с него клык, функция st.get('chat0') возвращает строку true, а не None. И во второй раз окно с Chat0.htm не появится, но в окне чата появится строчка «Collected 0 of 4 fangs». По тому же принципу сделано и с Chat1.htm." X+ d1 b% n) B6 C8 D 
 
) K' `6 V: k( a- R. d! ?0 P; B+ a# o# T! D! K* G& S& t$ w  P& d 
Вот конечный рабочий вариант квеста:- k+ c9 Z" r$ p+ h8 C 
- import sys
 
4 c4 b3 n$ M, G( l - from net.sf.l2j.gameserver.model.quest import State
 
  _: h- Q+ x4 V) j - from net.sf.l2j.gameserver.model.quest import QuestState" {* Q9 O. n( e! q( g8 {; ~$ y% P
 
 - from net.sf.l2j.gameserver.model.quest.jython import QuestJython as JQuest/ L0 u4 s4 v+ z) S+ y6 D
 
 - . k+ k9 q0 s# O4 c! a
 
 - KELTIR_NPC_ID = 120828 D! r4 S6 @& Z, L# D, P  C0 y
 
 - FANGS_ITEM_ID = 1859- V3 g4 V  i. K4 ~, Y2 e+ g& x
 
 - DROP_RATE    = 500000
 
: {  A: l, w. r2 l  
+ r* |% B  F1 S. q3 n2 q- WORLD_MAP_ITEM_ID = 16650 q( H/ k; @  p& C- `% x, ]& Q) w/ Y  H
 
 - ! d( d7 ?0 }7 m$ A
 
 - def getCount(st) :
 
  z. ?2 X  k/ \/ a/ V7 h - return st.getQuestItemsCount(FANGS_ITEM_ID)' _  h9 e& }1 |1 s& L' |" C
 
 - * f& |, O8 J* `( U& M: n) }
 
 - def completed(st) :
 
" O" A# k  e9 |, M( r5 @; v - st.setState(COMPLETED)7 {0 k, Q8 A& s0 S
 
 - st.clearQuestDrops()$ f1 H( f: L3 T4 s
 
 - st.takeItems(FANGS_ITEM_ID,-1)
 
3 m/ J+ m! e8 Y/ k0 w - st.giveItems(WORLD_MAP_ITEM_ID,1)$ M4 @. I! j6 X5 v4 ^3 L4 M* V
 
 - st.exitQuest(False)
 
7 y. t8 v% R4 W+ c3 h* g - return4 I# J5 ?' }' A% f" e. n
 
  
% C4 U3 b3 U! @% X" E9 E3 u' B- def check(st) :
 
# f/ L  Q  P$ B) x' v3 L! t - if getCount(st) >= 4 :
 
$ P; v; o, M. \! y+ O - completed(st)6 ]( B' S- o, _! D
 
 - return; D9 A2 t" f9 Y7 \& l& P! k) ~5 Z$ G, R
 
  
" p0 z7 A3 O9 W' p* [- class Quest (JQuest):" a- I& y( r5 j6 D( E, r
 
 - ( i7 S& L: X2 m( Z) E
 
 - def __init__(self,id,name,descr): JQuest.__init__(self,id,name,descr)3 W" a* G! o* T( A8 M
 
 - % T. y- a7 l8 ]3 N" B5 |; ]
 
 - def onEvent (self,event,st):3 N- P! v- `$ E0 ~/ Y' `
 
 - id = st.getState()
 
3 c& B& U8 n+ g# O1 b5 |1 O( R* a - if id == CREATED : st.setState(STARTED)
 
. g' `7 q2 U' q; D$ \9 R  W - elif id == COMPLETED: pass
 
: J+ ?/ N; }8 j$ t+ ]* L - elif id == STARTED : check(st)( D/ U& ]. T" p
 
 - return+ w- H* q, C! N2 x! M% |
 
  
: _' `( Z( U2 \4 [% J* ^" k- def onKill (self,npcId,st):
 
0 Q' J) f% y: X" I - if npcId == KELTIR_NPC_ID:9 n1 S1 j; ]3 T/ C; n  {' w2 n8 O
 
 - n = getCount(st). [2 |8 m8 X5 [/ b; K6 e+ F3 u
 
 - if n == 0:
 
- h1 f( W# c& w# D- t* V - if st.get('chat0') == None :8 {. d9 f+ d  a5 {6 R4 B
 
 - st.set("chat0", "true")
 
3 T; c0 c2 |% H7 A7 Z - return "Chat0.htm"
 
4 |, D9 }# ?/ F7 `' F& G- ~/ {) m - elif n == 1:% [3 E0 j) _8 z' K* ?! y; q, M: Y: N
 
 - if st.get('chat1') == None :
 
* V; X8 D. e( n: m/ Z+ h8 W# [# V - st.set("chat1", "true")
 
; F3 {: r  N4 _! z& x  R# E - return "Chat1.htm"9 j( f9 Y* \4 @- _
 
 - elif n >= 4:
 
# ?. [2 T( p  i, b3 f - return "Chat4.htm"
 
. a' n. R' u# P, W# m - return "Collect "+str(n)+" of 4 fangs"* g  W  Y5 O9 s; G( G. z- h" {
 
 - return
 
& R$ S2 @3 p, I7 A3 m2 Z5 F  
, k% `0 I3 {+ F/ u" r/ R# ?- QUEST    = Quest(201, "Tutorial", "Tutorial quest"): D: e( e2 f1 P# J4 {- R- y8 m  Y
 
 - CREATED = State('Start',    QUEST)& {' T: s7 t; s5 w8 j$ S( @- ^
 
 - STARTED = State('Started', QUEST)
 
5 \# I5 V: N3 m' w6 v# p - COMPLETED = State('Completed', QUEST)3 x, [( `6 U. s, P5 p
 
  
) N! i) {4 b* f( c) K- QUEST.setInitialState(CREATED)
 
# X- R9 e1 y6 |' E8 k' J! l9 ? - QUEST.addStartNpc(7056)
 
1 f4 g/ U' ^# e" g2 S6 A& x  @ - QUEST.addStartNpc(7012)
 
' @6 L2 O, Y% i, F' r - QUEST.addStartNpc(7009), w" b8 r4 D: R/ U  N
 
 - QUEST.addStartNpc(7011)3 \5 ]# C# ?) n7 K
 
 - * `. H% p. ^* k4 V3 \
 
 - STARTED.addQuestDrop(KELTIR_NPC_ID,FANGS_ITEM_ID,DROP_RATE)/ J5 \2 h% z. D, q
 
 - STARTED.addKillId(KELTIR_NPC_ID)
 
% J- I4 @0 n, F- g - STARTED.addTalkId(7056)) r- {6 X# b3 _! m0 C1 [4 B6 P
 
 - STARTED.addTalkI d(7012)
 
! F* K* ]9 Q8 h& ?& u3 c - STARTED.addTalkId(7009)! L: A( H+ }( U, H! g
 
 - STARTED.addTalkId(7011)
 
  Скопировать код 7 o" z' K# t/ ]/ N9 z9 L8 y 
1 J1 K9 j3 H& {3 p 
 |