Название: Создаём собственные квесты (часть 2) [Версия для печати] Автор: admin Время: 2024-9-17 19:36 Название: Создаём собственные квесты (часть 2) Хроники Interlude 9 B$ e. L4 d& A, VСборка L2j 2 c0 }" e! y w; k. t! C- XОбратите внимание: в файле htm стартового NCP обязательно должна быть ссылка на квест: & q p) h% y1 z
Для этого квеста больше ничего не надо. Все необходимое для корректной работы квеста уже добавили. Вот полный текст квеста: ; W/ A' b- P- E6 `( u3 X& F) I / {- O% s9 D$ D- F9 ?# A
if getCount(st) >= 4 :* N1 K' \( e: `
completed(st) ' ~8 F, J/ c) Z# l
return( I( h1 j2 _# g2 c/ _
: I# f" M' R& _& x
class Quest (JQuest):% U2 N$ C; i+ \& ]) \& u$ x+ o
def __init__(self,id,name,descr): JQuest.__init__(self,id,name,descr)* _3 a9 A) u" o* K+ S
Теперь рассмотрим, как это работает." b$ L3 O4 B- R) [3 z3 \
Игрок подходит к начальному NCP (в данном случае 7056), нажимает на «Quest». Квест будет создан и состояние квеста перейдет к CREATED и игроку будет показана страничка Start.htm с описанием квеста. Тогда метод onEvent, поле открытия странички Start.htm переведет состояние квеста в STARTED и игроку будет показана страничка Started.htm, где будет опсание того, как найти keltirs и .т.д. 5 ~) u2 C; t! C9 S- T+ e" \& o$ U/ l, |! z4 ?8 x9 S2 ^7 f
6 q( |0 D7 Y* I1 o# H
При состоянии STARTED будет зарегистрирован дроп «fangs» при убийстве keltirs. Игрок может вернуться к стартовому NCP и спросить о квесте – метод onEvent будет вызван снова. Если у игрока не хватает необходимого количества предметов, то метод check() не переведет квест в следующее состояние и Started.htm будет показана снова. Но если игрок собрал необходимее количество предметов (в данном случае 4 клыка), то метод check() вызовет метод completed() который переведет квест в новое состояние COMPLETED, заберет все клыки, даст карту мира, т.к. это награда за квест, покажет Completed.htm и завершит квест. $ d2 R" r% K8 I. }: |1 m/ L* B ( D" B5 B+ t3 Q* g! Y: H/ e! Q7 |
Теперь давайте сделаем наш квест более похожим на то, что он должен из себя представлять.2 |) s: R/ |* j1 c- g/ B
Прежде всего у нас есть 3 метода для объявления их в Яве – onTalk, onKill и onEvent. Если методы onTalk и onKill не объявлены, то за них все будет делать метод onEvent, т.е. определять квестовых монстров и вызывать диалоги NCP. Есть примечание, методы onTalk и onKill будут вызывать только диалоги с NCP в зависимости от текущего состояния квеста. Метод onKill будет вызываться только тогда, когда мы убиваем квестового монстра.2 M" n* E4 I/ v3 g
) J$ t* O4 A/ e ) T3 G5 ]. M( Y; d; K% H+ LДавайте рассмотрим как вызывается метод onKill при убийстве keltir в состоянии квеста STARTED: 8 a' h% E& {! l) b- S# a9 f
STARTED.addKillId(KELTIR_NPC_ID)
Скопировать код
и метод onKill в классе Quest:) i- Y2 A+ \! V) ^
0 g* R" {# `* d5 U9 g/ L
return "Collected "+str(n)+" of 4 fangs" L) y+ \" D0 T( R$ l
return
Скопировать код
Метод onKill (а так же метод onTalk) имеет следующие параметры: / K2 R- q7 I% Q* o0 M" [& } G0 h
! a5 s. v( f0 W: T7 g+ ?
• self – квест ( i* s) }# x6 B! {/ g; `6 L1 f6 n• npcId – ID NCP, которого мы должны убивать (если это метод onTalk, то ID того NCP, с которым мы должны поговорить). - Q5 j/ E( o) a |4 w* y• st – текущее состояние игрока.9 k6 x) K+ ~6 }$ x& b" q
, ?7 J* m7 A* q( x4 e& k: g
5 l! m3 |6 H+ C4 f) K$ f& b3 _
В этом методе мы проверяем и отмечаем, является ли убитый NCP keltir’ом. В основном эта проверка не нужна, т.к. у нас только KELTIR_NPC_ID. & ~9 P4 h, w) o, v7 A' a. e: Q: k1 o& E- a
U' s* D9 w& B3 E% A$ `( |0 y. t
Затем проверяем количество предметов (в данном случае количество клыков), и если их вообще нет, то возвращаем строку "Chat0.htm", если только один предмет, то возвращаем строку "Chat1.htm", если же предметов 4 или больше, то "Chat4.htm". Если строка возвращена из методов onEvent, onKill или onTalk, то сервер покажет соответствующие htm. В Chat0.htm может иметь следующий текст: «Вы не имеете ни одного клыка, возвращайтесь позже, когда соберете 4 штуки и бла, бла, бла…», в Chat1.htm может быть следующий текст: «У Вас всего 1 клык, по этому соберите еще…». В Chat4.htm – «Вы собрали необходимое количество предметов, возвращайтесь к вашему тренеру, что бы завершить квест…»( r# T* e/ v; H/ n- O( R
4 F( \' k; i T3 ~* w
. O, G8 X: n: X; N/ V3 X* L
Примечание: если в строка return начинается с "<html>", то будет показана страничка html с текстом, который стоит далее. Так вместо:! [* L* p8 V4 a: H8 R) \0 d
return "Chat4.htm", t, s) B) P5 E: h
" {# ~# s0 ]. Y' g+ k+ u8 H, a: ^* h8 P' [5 P
можно поставить:$ v3 m* N$ Y( @8 N* {# V
return "<html><body>Return to your trainer to complete the quest</body></html>"
Скопировать код
Так же если строка заканчивается без .htm или в начале нет <html>, то текст будет выведен, как системное сообщение в окне чата. В нашем случае мы сделаем так, что бы при каждом убийстве keltik выводилось системное сообщение: «Собрано N из 4-х клыков». 4 z- a& N, L/ g; A; c0 L8 `' t8 M/ X, E/ \2 F! P* r( s6 M
: j o! w6 o# H0 ] ~3 R; L4 m& SНаш код для onKill имеет один недостаток. Он будет постоянно показывать Chat0.htm, Chat1.htm и Chat4.htm, нам же необходимо, что бы Chat0.htm и Chat1.htm показывались только один раз. Как нам это сделать? С помощью переменных. / g0 D' ~) p* M$ \, Y4 J) ?; h
- h6 K1 C! _0 P% \+ KВ каждом квесте строки могут храниться с помощью переменных. Эти переменные сохраняются в Вашей БД. В каждом методе мы можем назначить, прочитать и удалить переменные. Давайте изменим метод onKill, так что бы каждый диалог вызывался только один раз. : y. O/ a2 [+ O5 @% J
if st.get('chat1') == None : ( w- T. `/ p/ X, f! ?7 |# V
st.set("chat1", "true") ) P4 M, Y, B' L2 }% n# d
return "Chat1.htm": Q0 i3 Y6 K" ?, q9 K6 [
elif n >= 4: + A Y9 T" |( \! Z% v
return "Chat4.htm"* o1 L% J* O! V6 j& ]" `
return "Collected "+str(n)+" of 4 fangs"% E3 O/ s n. m" z3 H
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# c7 L% I: F/ E/ v6 f% ^: N& k, _
# \! B7 q( O; N8 N8 r9 `
Z, U- {0 G# dВот конечный рабочий вариант квеста:; d" K5 [) d$ [: `
import sys 5 G. P% o% [& c/ K/ s
from net.sf.l2j.gameserver.model.quest import State 0 N# \4 }- h5 y2 D* T9 F
from net.sf.l2j.gameserver.model.quest import QuestState 7 V' p) c$ ^8 K4 P) o
from net.sf.l2j.gameserver.model.quest.jython import QuestJython as JQuest+ j, W# l7 r8 T& q