Рейтинг темы:
  • 1 Голос(ов) - 5 в среднем
  • 1
  • 2
  • 3
  • 4
  • 5
JythonQuest и с чем его едят
#1
Репост с форума -----. Так как там в нечитаемом виде, кидаю сюда заранее отформатировав.

Основа любого скрипта - класс унаследованный от JythonQuest. Что же это за класс и чем он так хорош?

Класс предназначен для создания квестов на языке Python. В принципе, он просто наследуется от класса Quest, и предназначен для "логического разделения". Что мол, квест написан на Python а не на Java.

Теперь расмотрим методв этого класса и их назначение. Небольшое отсупление: Часть методов является событийными (т.е. вызываются ядром при наступлении каких-либо условий). Эти методы в дальнейшем будут именоваться событиями. Так сделано, что бы отличить их от методов, которые вызывает пользователь.

Методы, связывающие квесты с npc/мобами

addAcquireSkillId(npcId) - вызовет событие onAcquireSkill когда вы будете учить скиллы у указанного НПЦ

addAggroRangeEnterId(npcId) - вызовет событие onAggroRangeEnter когда вы войдете в зону агрессии указанного НПЦ/Моба. Абсолютно неэффективно на мобах, у которых aggrorange = 0

addAttackId(npcId) - вызовет событие onAttack когда начнут атаковать моба/НПЦ. Событие будет вызвано всегда, и до нанесения урона.

addKillId(npcId) - вызовет событие onKill при убийстве указанного моба/NPC.

addSkillSeeId(npcId) - вызовет событие onSkillSee если на указаном npc применен скилл. Т.е. магатака, атака скиллом и лечение генерируют это событие.

addStartNpc(npcId) - при разговоре указанным npc автоматически будет начат квест для чара который говорит. Т.е. квест перейдет в состояние STARTED.

addTalkId(npcId) - при разговоре с указанным npc будет вызвано событие или onTalk если имя эвента не было передано или onAdvEvent/onEvent если было передано имя эвента.

addFirstTalk(npcId) - вызывает событие onFirstTalk сразу после старта квеста (т.е. после разговора с тем NPC, который был указан в addStartNpc).

addSpawnId(npcId) - метод onSpawn будет вызван при спавне указанного npc или при его респавне после смерти

Еще одно отступление: разговор с npc - что это?
Это обработка команды bypass -h %npcObjectId%_Quest [ИмяКвеста [эвент]] или bypass -h Quest [эвент]

Т.е. если вы хотите организовать вызов onTalk то пишите bypass -h %npcObjectId%_Quest Имя_вашего_квестаЕсли вы хотите что бы npc показал все квесты, в которых он участвует то bypass -h %npcObjectId%_QuestА если вы хотите вызвать метод onAdvTalk то bypass -h Quest Имя_квеста событие

Методы, влияющие на сам процесс

addSpawn(npcId, x,y, z, heading, randomOffset, despawnDelay, isSummonSpawn, instanceId) - спавнит моба. Я привел самую полную "версию" этого метода, есть и более короткие. randomOffset - логическое, говорит о том, должен ли моб спавнится в указанных координатах или рядом. Если выставить True - отлично подходит для спавна стада мобов.

startQuestTimer(name,time,npc,player,repeating) - запускает таймер, по прошествию времени (ВРЕМЯ В МИЛИСЕКУНДАХ) вызывается событие onAdvEvent с именем таймера в качестве имени эвента и передаными параметрами (npc,player). Если repeating False то таймер однократный

cancelQuestTimer(name,npc,player) - останавливает запущенный таймер.

Вот вроде краткое описание методов JythonQuest.

События.

Что это такое? Это такой же метод класса, но который вызывается ядром в определенном случае. При написании квеста основная задача состоит в перекрытии этих методов и реализации в них функционала.

Практически все методы возвращают строку. Если строка не пустая (не None или не "") то смотрится так: если строка начинается с <html> то это считается html-текстом, и он передается на клиент. Иначе, берется файл из той же папки где и сам скрипт с указаным именем (если есть) и передается клиенту.Основными параметрам являются npc и player. npc - объект класса L2NpcInstance а player - объект класса L2PcInstance.

Я рекомендую ознакомиться с javadoc по этим двум классам.

И так, основные события.

onTalk(npc,player) - вызывается при разговоре с npc или при событии таймера. Возвращает строку

onAdvEvent(npc,player,event) - вызвается при обработке события (bypass -h Quest имя событие), event - является строкой и содержит указаное имя. Возвращает строку.

onSpawn(npc) - вызывается при спавне npcOnKill(npc,killer,isPet) - событие при убийстве npc. killer - всегда L2NpcInstance. Если убил саммон то isPet == True и "настоящий убийца" killer.getPet()

onAttack(npc,killer,damage,isPet) - событие при атаке npc. Параметры сходны с пердыдущим, damage - нанесенный урон.

onAggroRangeEnter(npc,player,isPet) - событие при входе в аггро-зону моба. Параметры - смотри onKillonSkillSee(npc,caster,skill,targets,isPet) - если был каст. caster - L2PcInstance, кастующий; skill - объект класса L2Skill, прмененный скилл; targets массив из L2Object, цели скилла (у аурных скиллов например не одна цель); isPet - кастовал чар или его саммон.

onAcquireSkill(npc,player,skill) - Возникает, когда игрок выучил новый скилл.

Это основные события, их вполне хватает для написании достаточно слложных квестов и НПЦ.

Написание квеста.

И так, пора нам написать первый кастом-квест. Пусть это будет поднадоевший всем бафер Бафать он у нас будет 4 скилла, но потом мы доведем его до ума, и он у нас будет бафать их с анимацией и с сохранением "кто чего заказывал".

PHP код:
<?php 
import sys
from net
.sf.l2j.gameserver.model.quest import QuestJython as JQuest
from net
.sf.l2j.gameserver.datatables import SkillTable

BUFFER_ID
=70001
Buffs
= {1204:{1:5,2:10}, 1040:{2:10,3:15}, 1044:{1:5,2:10}, 1045: {1:5,2:10,3:15}}

Сначала некоторые определения. BUFFER_ID - ид нашего бафера. Как добавлять новых NPC в таблицу и спавнить их, вы конечно знаете. Можете заменить его на того, кто вам нравится. Buffs - хэш скиллов, ключ -ид скилла, значение пары левел-цена. Скиллы у нас будут WindWalk, Shield, Regeneration и Blessed Body.

Теперь собственно сам квест

PHP код:
<?php 
class MegaBuffer(JQuest):
def __init__(self):
JQuest.__init__(self, -1, "MegaBuffer", "Our First Mega Buffer")

self.addTalkId(BUFFER_ID)
self.addStartNpc(BUFFER_ID)

В конструкторе квеста мы вызываем конструктор суперкласса с идентификатором квеста -1, именем (без пробелов) и описанием. Почему -1? А потому что нам его на клиент не передавать... можете -2, можете 9999... главное что бы ID квеста был <0 или >1000 остальные квесты считаются игровыми и инфомация о них передеается на клиент (для окошечка Quests).

PHP код:
<?php 
def onAdvEvent
(self,npc,player,event):
if
event != "showskills":
buff = event.split("_")
price = Buffs[int(buff[0]][buff[1])
skill = SkillTable.getInstance().getInfo(buff[0],buff[1])

if
not skil :
return
"<html><body>Милейший, я не знаю таких баффов... да вы читер!</body></html>"

if player.getAdena() < price:
return
"<html><body>У вас не хватает денег, что бы оплатить мои услуги</body></html>"

skill.getEffects(npc,player)
return
"buffer-1.htm"

И так, что же у нас в методе onAdvEvent? Да очень просто. Мы будем передавать желаемый баф в формате скилл_левел. На клиенте мы будем парсить эту строку и соответсвенно кидать наши бафы. Ну и всегда возвращать список скиллов, который у нас в файлике buffer-1.htm. А вот и его содержимое.

<html><body>

Wind Walk<br>
<a action="bypass -h Quest MegaBuffer 1204_1">1 лвл - 5 аден</a><br1>
<a action="bypass -h Quest MegaBuffer 1204_2">2 лвл - 10 аден</a><br1>

Shield<br>
<a action="bypass -h Quest MegaBuffer 1040_2">2 лвл - 10 аден</a><br1>
<a action="bypass -h Quest MegaBuffer 1040_3">3 лвл - 15 аден</a><br1>
.......
</body></html>


Ну и событие onTalk что бы наш бафер нас поприветствовал.

PHP код:
<?php 
def onTalk
(self,npc,player):
return
"<html><body>Я - мегабафер!<br><a action='bypass -h Quest MegaBuffer showskills'>Мои скиллы!</a></body></html>"

Ну и собственно сама инициализация:

PHP код:
<?php 
buffer
= MegaBuffer()

Вот наш первый корявенький бафер Smile

Сегодня мы будем прикручивать анимацию к нашему баферу. Надеюсь, все обзавелись javaDoc по ядру?

Ничего сложного в этом нет, достаточно всего лишь изменить один вызов.

и так, было
PHP код:
<?php 
skill
.getEffects(npc,player)

Нам надо что бы гаш бафер провел полноценный каст. И так, что мы делаем?

Первым делом, берем нашего незадачливого плеера на таргет. Потом - кастуем наш скилл.
PHP код:
<?php 
npc
.setTarget(player)
npc.doCast(skill)

У описанного метода есть недостаток. У нашего npc очень быстро кончится мана - раз, второе - его могут "затюкать". Как нам это поправить?

PHP код:
<?php 
npc
.setBusy(True) # Отсаньте от меня, занят я!
npc.getStatus().setCurrentMp(npc.getMaxMp()) # восстанавливаем МП до полного
npc.doCast(skill)
npc.setBusy(False) # Все, я свободен

Однако, у данного метода есть недостаток. Это невысокая скорость каста. Вопрос, как можно ее ускорить? Подсказка - ответ лежит в области серверных пакетов.
Классический Interlude PvP сервер http://akamanah.ru/
Ответ
#2
SunnyX Написал:Модераторы, если можно, подправьте ошибки:
1) JytonQuest заменить на JythonQuest
2) addFirstTak на addFirstTalk
3) npconKill на npcOnKill
4)
PHP код:
<?php 
def onTalk
(self,npc,player):
return
"<html><body>Я - мегабафер!<br><a action="bypass -h Quest MegaBuffer showskills">Мои скиллы!</a></body></html>"
на
PHP код:
<?php 
def onTalk
(self,npc,player):
return
"<html><body>Я - мегабафер!<br><a action='bypass -h Quest MegaBuffer showskills'>Мои скиллы!</a></body></html>"

Спасибо.
эм, вы ж можете изменять свои сообщения....
Ну и вы не указали где поменять ибо текста много
Ответ
#3
Если бы мог изменить - изменил бы. Видимо время редактирования постов ограничено.
CTRL+F в помощь.
Классический Interlude PvP сервер http://akamanah.ru/
Ответ
#4
Спасибо, полезный мануал!!!
Ответ
#5
какой метод питона вносит данные в базу mysql
было бы чудно на примере с комментированием посмотреть.
Спасибо
Ответ


Перейти к форуму:


Пользователи, просматривающие эту тему: 1 Гость(ей)