↑ ↓

Теория написания квестов

Тема в разделе "Гайды и руководство по серверам AION", создана пользователем Alenheym, 11 июн 2016.

  1. TopicStarter Overlay
    Offline

    Alenheym Старший сержант Команда форума Модератор

    1.180
    385
    244
    Кредиты:
    $31.305,00
    Репутация:
    40
    Часть 1:

    Доброго времени суток! Написал вводный гайд по созданию квестов, хотелось бы услышать мнение форумчан по этому поводу А именно: что в гайде соответствует действительности, что нет; дополнения; замечания; благодарности.

    Так же может быть в этом топике, кто-нибудь сможет объяснить мне, как понять написан ли для того или иного квеста обработчик (имею ввиду gs/data/scripts/system/handlers/quest/*.java) или нет? А то сейчас редактируешь... редактируешь..., а эффекта нет...
    ————————————

    Файлы для редактирования/добавления квестов:

    ...\gameserver\data\static_data\quest_data\quest_data.xml - в этом файле находятся описания всех квестов, в него занесены подробные инструкции по выполнению квестов.
    Все инструкции по выполнению квестов уже занесены в данный файл командой Aion - Unique, поэтому вам он понадобится только если вы решите отредактировать какой-либо из квестов под свои нужды (например изменить кол-во опыта или денег выдаваемые за квест и т.д. и т.п.).

    Подробно останавливаться на рассмотрении данного файла не будем, рассмотрим лишь основные аттрибуты:

    "id" - уникальный идентификатор квеста в базе данных Aion. Формат: целое четырехзначное число, например "2001".
    "minlevel_permitted" - уровень необходимый для взятия квеста. Формат: целое одно/двухзначное число, например: "1"(1 уровень), "49"(49 уровень).
    "name" - имя квеста (на английском языке, например Food Bandits). Формат: строка.
    "race_permitted" тип расы для которой квест доступен, допустимые значения: "ELYOS","ASMODIANS".
    "start_npc_id" - уникальный идентификатор NPC у которого квест берётся. Формат: Целое шестизначное число, например: "203540".
    "end_npc_id" - уникальный идентификатор конечного NPC, которому необходимо сдать квест. Формат: Целое шестизначное число, например: "203540".
    "collect_item count" - кол-во предметов необходимых для прохождения квеста. Формат: целое число.
    "item_id" - уникальный идентификатор предмета необходимого для прохождения квеста. Формат: Целое девятизначное число, например "100200613".
    "exp" - количество опыта за квест. Формат: целое число.
    "gold" - количество денег за квест. Формат: целое число.
    "selectable_reward_item" - один из нескольких предметов на ваш выбор, даётся за прохождение предмета.

    Например, если в описании квеста указано:

    Код:
    <selectable_reward_item count="1" item_id="111111111"/>
    <selectable_reward_item count="1" item_id="222222222"/>
    
    то после прохождения квеста вы выбираете какой из предметов вам получить в качестве награды: "111111111" или "222222222".

    "count" - количество предметов выдаваемых за прохождение квеста. Формат: целое число.

    Дополнительные атрибуты вы можете найти открыв файл [quest_data.xml], там всё описано достаточно просто и в объяснениях не нуждается.

    ...\gameserver\data\static_data\quest_script_data\<название территории>.xml - в этом файле находятся правила получения и окончания квеста. Именно этот файл необходимо редактировать для добавления отсутствующих квестов.

    Есть три типа квестов:

    1. Квесты на убийство определенного количества мобов:

    Код:
    <!-- Food Bandits -->
     
    <monster_hunt start_npc_id="203540" id="2117">
     
    <monster_infos npc_id="210389" var_id="0" max_kill="9"/>
     
    </monster_hunt>
    Теперь давайте рассмотрим вышеприведенный код по строкам.

    Строка 1:

    Код:
    <monster_hunt start_npc_id="203540" id="2117">
    Данная строка определяет:
    monster_hunt - тип квеста: охота на монстров.
    start_npc_id - ID NPC -персонажа дающего данный квест.
    id - ID номер квеста в базе данных квестов. По нему можно посмотреть описание квеста в БД Aion.

    Строка 2:

    Код:
    <monster_infos npc_id="210389" var_id="0" max_kill="9"/>
    Данная строка определяет:
    monster_infos - тэг, открывающий описание каждого убиваемого моба.
    npc_id - ID монстра, которого необходимо убить по квесту.
    max_kill - количество необходимых для выполнения квеста монстров.

    Строка 3:

    Код:
    </monster_hunt>
    Тэг, закрывающий описание условия выполнения квеста типа "охота на монстров".

    После всего прочтенного можно составить описание квеста:
    Квест типа "охота на монстров", стартовый нпс "203540",убить мобов "210389" в количестве 9 штук, ID квеста в базе данных Aion=2117

    В вышеприведенном коде мы рассмотрели квест, в котором требуется убить мобов типа "210389", однако есть квесты для выполнения которых требуется убить мобов нескольких типов.

    Для реализации такого квеста достаточно просто добавить ещё одну строку <monster_infos> в правила получения и окончания квеста:

    Код:
    <!-- Food Bandits -->
     
    <monster_hunt start_npc_id="203540" id="2117">
     
    <monster_infos npc_id="210389" var_id="0" max_kill="9"/>
     
    <monster_infos npc_id="210390" var_id="0" max_kill="9"/> #добавляем строку с описание второго типа мобов.
     
    </monster_hunt>

    На этом описание квестов типа "охота на мобов" закончено.


    2. Квесты типа "Сбор предметов":

    Имеют формат записи:

    Код:
    <item_collecting id="2104" start_npc_id="203502" action_item_id="700124"/>
    Рассмотрим каждый параметр записи отдельно:
    item_collecting - тип квеста: сбор предметов
    id - ID номер квеста в базе данных квестов. По нему можно посмотреть описание квеста в БД Aion.
    start_npc_id - ID NPC персонажа дающего данный квест.
    action_item_id - контейнер, в котором содержится предмет необходимый для выполнения квеста (например в квесте 2104 который мы взяли в качестве примера это "Корзина с плодами"). Обратите внимание, что в базе данных Aion он числится не как предмет(item), а как нпс (npc).
    Об это свидетельствует и его id номер: "700124". ID контейнера шестизначный, тогда как id предметов (items) девятизначные. Поэтому для того чтобы найти необходимый контейнер в базе данных используйте поиск по npc. Для того чтобы лучше понять всё вышеописанное рекомендую посмотреть описание квеста.

    Однако не всегда требуемый для прохождения квеста предмет находится в контейнере. Есть квесты, в которых необходимые предметы выбиваются с монстров. Как написать условие такого квеста? Всё очень просто - достаточно лишь убрать аттрибут action_item_id из описания квеста, например:

    Код:
    <item_collecting id="2118" start_npc_id="203539"/>
    Общее для всех квестов данного типа: отсутствие атрибута <end_npc_id>. По крайней мере из всех виденных мною квестов он нигде не встречается. Возможно связано с тем что start_npc_id & end_npc_id во всех квестах данного типа совпадают.


    3. Квесты типа "Кто передаст? Я передаст?" .

    В квестах данного типа вам необходимо по поручению одного npc поговорить/передать предмет другому npc.

    Формат записи:

    Код:
    <report_to start_npc_id="203540" end_npc_id="203547" item_id="182203119" id="2121"/>
    Рассмотрим каждый параметр записи отдельно:
    report_to - тип квеста "Кто передаст?Я передаст?"
    start_npc_id - ID NPC-персонажа дающего данный квест.
    end_npc_id - ID NPC-персонажа завершающего квест.
    item_id - ID предмета, который необходимо передать
    id - ID самого квеста в базе данных квестов.

    Однако помимо квестов в которых необходимо передать какой либо предмет есть квесты, для выполнения которых вам нужно "передать слова" одного НПС другому. Как быть в этом случае?
    Всё очень просто: достаточно просто удалить аттрибут предмета item_id из описания квеста:

    Код:
    <report_to start_npc_id="203522" end_npc_id="203533" id="2110"/>
    Надеюсь данный гайд кому-либо будет полезен, всегда рад выслушать предложения по изменению/дополнению/исправлению материала.

    Автор: В©ViAl


    Часть 2:

    Итак, в первой части было упомянуто DoLoD следующий гайд, объясняющий, как запустить квест. Но кроме этого квест ещё прописывается и в скриптовой части.

    Разберём же его на примере квеста 2209 The Scribbler.
    Для этого переходим в папку по следующему пути. AL-Game\data\scripts\system\handlers\quest\altgard
    Находим документ _2209TheScribbler.java, который и описывает данный квест.

    Итак, начнём Разбор полётов.

    1. Первая не столь важная часть, это копирайтик.

    Он впринципе не нужен, но отдадим дань уважения aion emu, aion unique и aion lightning, и не поленимся прописать его.

    Код:
    /*
     
     * This file is part of aion-unique <aion-unique.org>.
     
     *
     
     *  aion-unique is free software: you can redistribute it and/or modify
     
     *  it under the terms of the GNU General Public License as published by
     
     *  the Free Software Foundation, either version 3 of the License, or
     
     *  (at your option) any later version.
     
     *
     
     *  aion-unique is distributed in the hope that it will be useful,
     
     *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     
     *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     
     *  GNU General Public License for more details.
     
     *
     
     *  You should have received a copy of the GNU General Public License
     
     *  along with aion-unique.  If not, see <http://www.gnu.org/licenses/>.
     
     */
    2. Укажем путь к нашему документику.

    Код:
    package quest.altgard;
    Разберём. package - это оператор, который указывает машине явы о существовании этого класа в данной папке. Путь к классу пишется через точку, а не через слешку, как мы привыкли делать. В конце любой операции всегда ставится точка с запятой.

    3. Далее зададим импорты, чтобы наш документ мог давать команды движку сервера.

    Код:
    import com.aionemu.gameserver.model.gameobjects.Npc;
     
    import com.aionemu.gameserver.model.gameobjects.player.Player;
     
    import com.aionemu.gameserver.network.aion.serverpackets.SM_DIALOG_WINDOW;
     
    import com.aionemu.gameserver.questEngine.handlers.QuestHandler;
     
    import com.aionemu.gameserver.questEngine.model.QuestEnv;
     
    import com.aionemu.gameserver.questEngine.model.QuestState;
     
    import com.aionemu.gameserver.questEngine.model.QuestStatus;
     
    import com.aionemu.gameserver.utils.PacketSendUtility;
     
    
    Импорты начинаются с оператора import. В разных случая их разное количество, но эти самые основные.

    Поясню:
    1) Указывает на взаимодействие с NPC.
    2) Указывает на взаимодействие с игроком, то - есть с вами.
    3) Указывает на То, что будут проходить диалоги между NPC и игроком.
    4-7) Указывает на основные команды квеста(его начало, продолжение и конец.)
    8) Оператор пакетов. Необходим для операций с пакетами.

    Все вышеперечисленные импорты обязательны и без них квест не будет работать.

    3-а. Если вы делаете свой квест, а ваше ЭГО просто хлещет из ушей, то можно написать следующий код.

    Код:
    /**
     
     * @author Mr. Poke
     
     *
     
     */

    Тут вместо ника создателя этого квеста вы разумеется указываете свой. Что это даёт. При проверке этого квеста явой, автор (@author) всплывает в опивании класса. Те, кто знаком с явой, поймут.

    4. Теперь мы начинаем скрипт. Объявляем о новом классе.

    Код:
    public class _2209TheScribbler extends QuestHandler
     
    {
     
    ...
     
    }

    Тут мы объявили о новом классе,с названием _2209TheScribbler доступном отовсюду, на что нам указывает оператор public, родителем которого является класс QuestHandler, на что нам указывает оператор extends (вспомните про импорты, теперь ясно зачем они нужны.) Всё, что находится внутри класса Закрывается в фигурные скобки. Как показанно в выше представленном примере.

    5. далее создаём переменную, со значением, равным ID нашего квеста.

    Код:
    private final static int	questId = 2209;
     
    	public _2209TheScribbler()
     
    	{
     
    		super(questId);
     
    	}
    Тут мы записали переменную questId недоступной, на что указывает оператор private.
    final указывает о законченности переменной, то есть приравнивать её к другим переменным или значениям мы не будем.
    static указывает на неизменимое значение
    int, или значение типа integer означает целочисленное значение размером в 1-2 байта. В нашем случае это ID квеста.

    Дальше мы публикуем новую переменную _2209TheScribbler(), чтобы получить доступ к закрытой переменной questId. Что и указанно в вышеприведённом коде.

    6. Далее мы расставим все фигурки на шахматной доске, то-есть дадим каждому NPC свою роль.

    Код:
     @Override
     
    	public void register()
     
    	{
     
    		qe.setNpcQuestData(203555).addOnQuestStart(questId);
     
    		qe.setNpcQuestData(203555).addOnTalkEvent(questId);
     
    		qe.setNpcQuestData(203562).addOnTalkEvent(questId);
     
    		qe.setNpcQuestData(203592).addOnTalkEvent(questId);
     
    	}
    Тут мы регистрируем всех NPC. Как начальный NPC у нас идёт 203555, далее идут ID NPC с которыми игрок должен взаимодействовать в течение всего квеста. Расстановка идёт тем методом, который указан выше. Первый NPC начальный, на что нам указывает addOnQuestStart (тут мы как раз и ссылаемся на переменную questId) После первого NPC идут все остальные, в том порядке, который задан в клиенте, ну или его порядок можно найти в базе данных. К примеру на _aiondatabase.ru.
    Переменная @Override является зарезервированной переменной нашим сервером. Она указывает на то, что данный список актёров будет взаимодействовать со следующим сценарием.

    7. Непосредственное сценарий, указывающий на действия, необходимые для прохождения квеста.

    Код:
    @Override
     
    	public boolean onDialogEvent(QuestEnv env)
     
    	{
     
    		final Player player = env.getPlayer();
     
    		int targetId = 0;
     
    		if(env.getVisibleObject() instanceof Npc)
     
    			targetId = ((Npc) env.getVisibleObject()).getNpcId();
     
    		QuestState qs = player.getQuestStateList().getQuestState(questId);
     
    		if(qs == null)
     
    		{
     
    			if(targetId == 203555)
     
    			{
     
    				if(env.getDialogId() == 25)
     
    					return sendQuestDialog(player, env.getVisibleObject().getObjectId(), 1011);
     
    				else
     
    					return defaultQuestStartDialog(env);
     
    			}
     
    		}
     
    		else if (qs.getStatus() == QuestStatus.START)
     
    		{
     
    			switch(targetId)
     
    			{
     
    				case 203562:
     
    				{
     
    					if (qs.getQuestVarById(0) == 0)
     
    					{
     
    						if(env.getDialogId() == 25)
     
    							return sendQuestDialog(player, env.getVisibleObject().getObjectId(), 1352);
     
    						else if(env.getDialogId() == 10000)
     
    						{
     
    							qs.setQuestVarById(0, qs.getQuestVarById(0) + 1);
     
    							updateQuestStatus(player, qs);
     
    							PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(env.getVisibleObject().getObjectId(), 10));
     
    							return true;
     
    						}
     
    					}
     
    				}
     
    				break;
     
    				case 203572:
     
    				{
     
    					if (qs.getQuestVarById(0) == 1)
     
    					{
     
    						if(env.getDialogId() == 25)
     
    							return sendQuestDialog(player, env.getVisibleObject().getObjectId(), 1693);
     
    						else if(env.getDialogId() == 10001)
     
    						{
     
    							qs.setQuestVarById(0, qs.getQuestVarById(0) + 1);
     
    							updateQuestStatus(player, qs);
     
    							PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(env.getVisibleObject().getObjectId(), 10));
     
    							return true;
     
    						}
     
    					}
     
    				}
     
    				break;
     
    				case 203592:
     
    				{
     
    					if (qs.getQuestVarById(0) == 2)
     
    					{
     
    						if(env.getDialogId() == 25)
     
    							return sendQuestDialog(player, env.getVisibleObject().getObjectId(), 2034);
     
    						else if(env.getDialogId() == 10002)
     
    						{
     
    							qs.setQuestVarById(0, qs.getQuestVarById(0) + 1);
     
    							updateQuestStatus(player, qs);
     
    							PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(env.getVisibleObject().getObjectId(), 10));
     
    							return true;
     
    						}
     
    					}
     
    				}
     
    				break;
     
    				case 203555:
     
    				{
     
    					if (qs.getQuestVarById(0) == 3)
     
    					{
     
    						if(env.getDialogId() == 25)
     
    							return sendQuestDialog(player, env.getVisibleObject().getObjectId(), 2375);
     
    						else if(env.getDialogId() == 1009)
     
    							{
     
    								qs.setStatus(QuestStatus.REWARD);
     
    								updateQuestStatus(player, qs);
     
    								return defaultQuestEndDialog(env);
     
    							}
     
    							else
     
    								return defaultQuestEndDialog(env);
     
    					}
     
    				}
     
    			}
     
    		}
     
    		else if (qs.getStatus() == QuestStatus.REWARD)
     
    		{
     
    			if(targetId == 203555)
     
    				return defaultQuestEndDialog(env);
     
    		}
     
    		return false;
     
    	}

    Как видите, код сценария очень велик. Хотя квест мы пройдём в два счёта.

    Разберём код по частям.

    7.0. КакСнова мы видем зарезервированную переменную @Override, которая указывает нам, что мы будем работать с выше представленным списком.

    7.1. Далее мы публикуем переменную сценария по типу boolean, что значит, что мы можем взять квест, а можем от него и отказаться.

    Переменную в данном случае мы взяли из одного из импортов.

    Код:
    public boolean onDialogEvent(QuestEnv env)
     
    	{
     
    ...
     
    }
    как и клас, весь сценарий закрывается в фигурные скобки.

    7.2.Тут мы объявляем о начале квеста.

    Код:
    final Player player = env.getPlayer();
     
    		int targetId = 0;
     
    		if(env.getVisibleObject() instanceof Npc)
     
    			targetId = ((Npc) env.getVisibleObject()).getNpcId();
     
    		QuestState qs = player.getQuestStateList().getQuestState(questId);

    Данный код указывает нам на то, что если мы возьмём в цель следующего NPC (первого в выше упомянутом сценарии), то появится диалоговое окно с предложением взять квест, так сказать помочь с появившейся проблемой. Данный код является статическим для всех квестов (я не считаю миссий), так что он актуален для любого квеста именно в таком виде. То-есть, хотите сделать квест, просто копипастим эту часть.

    7.3. Далее мы указываем диалог, который пройдёт с первым NPC.

    Данный диалог нужно только запустить, далее он продолжается сам.

    Код:
    if(qs == null)
     
    		{
     
    			if(targetId == 203555)
     
    			{
     
    				if(env.getDialogId() == 25)
     
    					return sendQuestDialog(player, env.getVisibleObject().getObjectId(), 1011);
     
    				else
     
    					return defaultQuestStartDialog(env);
     
    			}
     
    		}

    Тут мы можем как отказаться от квеста, так и получить его.
    Тут сценарий начинается с условного оператора if. После него в скобках мы пишем, что если данный квест не был ранее взят, то.... Далее происходит новое условие, где говорится, если NPC на которое мы нацелены является с ID 203555, то посылаем диалоговое окно под ID 1011. Далее else указывает, что в противном случае мы подставляем диалоговое окно по умолчанию (Да здраствует ариэль.) Переходим к следующей части.

    7.4.Тут мы начинаем описывать то, что произойдёт, если квест принят.

    Код:
    else if (qs.getStatus() == QuestStatus.START)
     
    switch(targetId)
     
    			{

    7.5. Тут мы начинаем описывать переключение на нового NPC c ID 203562.

    Код:
    case 203562:
     
    				{
     
    					if (qs.getQuestVarById(0) == 0)
     
    					{
     
    						if(env.getDialogId() == 25)
     
    							return sendQuestDialog(player, env.getVisibleObject().getObjectId(), 1352);
     
    						else if(env.getDialogId() == 10000)
     
    						{
     
    							qs.setQuestVarById(0, qs.getQuestVarById(0) + 1);
     
    							updateQuestStatus(player, qs);
     
    							PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(env.getVisibleObject().getObjectId(), 10));
     
    							return true;
     
    						}
     
    					}
     
    				}
     
    				break;

    В данном случае строчка if (qs.getQuestVarById(0) == 0) означает, что мы не взяли квест, и поэтому, он будет выдавать стандартное диалоговое окно, а не предложение продолжить квест. Код вообще означает что NPC с ID 203562 выдаст по умолчанию нам окно под ID 25 (стандартное диалоговое окно для квестов.) с в„– 10000.(ранее описанное стандарт). Между ними идёт посылка диалога с ID 1352, то есть диалог по умолчанию. Далее идёт стандартный процес передачи данных в пакет(кстати при помощи последнего импорта.) Если проще оценить всю эту часть, то единственное, что тут изменяется, это NPC ID. В остально в этой части сценария всё идёт по стандарту. Переходим к следующему диалогу.

    7.6. Тут мы описываем взаимодействие с невошедшим NPC в список, так как этот NPC является тем же самым NPC, что был описан выше.

    Код:
    case 203572:
     
    				{
     
    					if (qs.getQuestVarById(0) == 1)
     
    					{
     
    						if(env.getDialogId() == 25)
     
    							return sendQuestDialog(player, env.getVisibleObject().getObjectId(), 1693);
     
    						else if(env.getDialogId() == 10001)
     
    						{
     
    							qs.setQuestVarById(0, qs.getQuestVarById(0) + 1);
     
    							updateQuestStatus(player, qs);
     
    							PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(env.getVisibleObject().getObjectId(), 10));
     
    							return true;
     
    						}
     
    					}
     
    				}
     
    				break;
    Просто его ID меняется только для игрока, взявшего квест. Почему так? Всё проще чем кажется. Строчка if (qs.getQuestVarById(0) == 1) означает что мы взяли квест. А 1 NPC не может выдавать два сразу диалоговых окна, поэтому со стороны клиента происходит подмена NPC для решения этого конфликта. В данном окне по стандарту меняется в„– окна, и уже ставится уникальный ID диалога 1693. Это диалог для продолжения квеста. В остальном структура диалога во всех квестах та же. Так что переходим ко следующей фазе.

    7.7. Тут мы описываем дилог с последним NPC, который должен закончить квест.

    Код:
    case 203592:
     
    				{
     
    					if (qs.getQuestVarById(0) == 2)
     
    					{
     
    						if(env.getDialogId() == 25)
     
    							return sendQuestDialog(player, env.getVisibleObject().getObjectId(), 2034);
     
    						else if(env.getDialogId() == 10002)
     
    						{
     
    							qs.setQuestVarById(0, qs.getQuestVarById(0) + 1);
     
    							updateQuestStatus(player, qs);
     
    							PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(env.getVisibleObject().getObjectId(), 10));
     
    							return true;
     
    						}
     
    					}
     
    				}
     
    				break;
    Как и в придыдущем случае, меняется номер окна на единицу выше и ставится уникальный ID квестового диалога, в остальном стандартная процедура передачи информации в пакет.

    7.8.Тут мы описываем третий сценарий, если мы отказалисьот квеста.

    Что произойдёт с первым NPC, а он просто переключится на состояние по умолчанию. Он должен перестать предлагать выполнить этот квест.

    Код:
    {
     
    					if (qs.getQuestVarById(0) == 3)
     
    					{
     
    						if(env.getDialogId() == 25)
     
    							return sendQuestDialog(player, env.getVisibleObject().getObjectId(), 2375);
     
    						else if(env.getDialogId() == 1009)
     
    							{
     
    								qs.setStatus(QuestStatus.REWARD);
     
    								updateQuestStatus(player, qs);
     
    								return defaultQuestEndDialog(env);
     
    							}
     
    							else
     
    								return defaultQuestEndDialog(env);
     
    					}
     
    				}
    Выдаётся тоже уникальный ID диалога, где скорей вего NPC поменёт вас и весь ваш род до седьмого колена бранным словом. Номер окна по стандарту 1009, для отказа от квеста.

    7.9. Ну и мы конечно закрываем весь сценарий. Всё, квест готов.

    Но этот квест по структуре очень прост, существуют некоторые моменты, которые не оглашены выше. Так что во второй части мы разберём, как к примеру прописать в квесте взятие предета. А далее поговорим о миссиях.

    Если вам понравился гайд, тыкаем пасибку. Нет? ну что же, я вам не судья. Жду коментариев.

    Разберём новый импорт и новую возможную часть сценария. Видео вставки.
    Для того чтобы вставить из клиента видео, нажно Сделать новый импорт


    Код:
    import com.aionemu.gameserver.network.aion.serverpackets.SM_PLAY_MOVIE;
    Этот импорт позволяет нам вставить видео в квест. Видео вставки необходимы в некотрых квестах. Самое большое количество вставок в квесте обучения в бездне.

    Теперь вставим видео

    Код:
    if(var == 3)
     
    							{
     
    								PacketSendUtility.sendPacket(player, new SM_PLAY_MOVIE(0, 105));
     
    								player.getCommonData().setDp(0);
     
    								qs.setStatus(QuestStatus.REWARD);
     
    								updateQuestStatus(player, qs); 
     
    								return sendQuestDialog(player, env.getVisibleObject().getObjectId(), 5);
     
     
     
    }
    Данный способ передачи видео даёт возможность увмдеть мув после поражения или отказа от квеста. Как правило это миссии. Такого типа мувик к примеру в миссии в морхейме, пропавшие даевы. Из этого кода следует, если миссия не взята или провалена послать видео 105. после этого послать диалог номер 5. структура как видите стандартная.

    Код:
    case 204342:
     
    				{
     
    					switch(env.getDialogId())
     
    					{
     
    						case 25:
     
    							if(var == 0)
     
    								return sendQuestDialog(player, env.getVisibleObject().getObjectId(), 1011);
     
    							if(var == 4)
     
    								return sendQuestDialog(player, env.getVisibleObject().getObjectId(), 2375);
     
    						case 1012:
     
    							PacketSendUtility.sendPacket(player, new SM_PLAY_MOVIE(0, 82));
     
    							break;		 
     
    						case 10000:
     
    							if (var == 0)
     
    							{
     
    								qs.setQuestVarById(0, var + 1);
     
    								updateQuestStatus(player, qs);
     
    								PacketSendUtility.sendPacket(player, new SM_DIALOG_WINDOW(env.getVisibleObject().getObjectId(), 10));
     
    								return true;
     
    							}
    этот способ выдаёт мувик после определённого дилога (в нашем случае 1012). После чего переключается опять на диалог. Принцип диалога стандартный, единственное что мы вклинили пару лишних case - ов, дабы воспроизвести мувик. Вот так можно воспроизвести мув.

    Автор: хз
     
  2. Offline

    Дмитрий Ефрейтор

    337
    48
    61
    Кредиты:
    $15.270,06
    Репутация:
    5
    Это даже не гуглтранслятор.
    Аннотация @Override проверяет действительно ли метод помеченный данной аннотацией, переопределяет метод суперкласса. В противном случае во время компиляции генерируется сообщение об ошибке.
     
    Robin Hood нравится это.