• Страница 1 из 1
  • 1
[Мануал] Написание босса на С++
VIPSergeyДата: Вторник, 10.07.2012, 09:32 | Сообщение # 1
Скаут
Группа: Пользователи
Сообщений: 5
Награды: 0
Репутация: 5
Статус:
Всем привет. Решил поделится информацией, как же все таки заскриптовать босса, моба на С++.
Как мы знаем есть два способа скриптовки NPC. Это ScriptedAI и соответственно BossAI.
На данном случае я предлагаю использовать способ ScriptedAI.

Для начала давайте с Вами определимся, какие способности будет использовать наш пациент?
Для данного примера я выбрал 2 спелла:
http://ru.wowhead.com/spell=56090
http://ru.wowhead.com/spell=57369
Далее узнаем каким образом используются данные спеллы? Прочитали, поняли они кастуются на весь рейд, тоесть используем функцию SELECT_TARGET_RANDOM. Но об этом чуть позже.
Итак, приступим:

Для удобства в коде принято называть все своими именами:
Обозначим наши спеллы, перечислив их через 'перечислитель' Enum
Code

enum BossSpells
{
SPELL_IMPALE = 56090,
SPELL_UNHOLYSHADOW = 57369,
};

Дальше можно приступать к непосредственному оформлению самого босса: для начала создадим его шапочку (укажем имя скрипта)
Создаем отдельный класс для нашего моба/босса, присвоим классу имя нашего моба/босса. Присвоим АИ и зарегистрируем ее.
Code
class boss_wowgame_manual : public CreatureScript
{
public:
boss_wowjp_manual() : CreatureScript("boss_wowjp_manual") { }

CreatureAI* GetAI(Creature* creature) const
{
return new boss_wowgame_manualAI (creature);
}

struct boss_wowgame_manualAI : public ScriptedAI
{
boss_wowgame_manualAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
}

InstanceScript* instance;
Дальше мы с Вами разберем, как же ему использовать выбранные спеллы? Например через таймер.
Давайте введем переменные, таймеры для кастов и присвоим им значение
Code
uint32 ImpaleTimer;
uint32 UnholyshadowTimer;

void Reset()
{
ImpaleTimer = 30000;
UnholyshadowTimer = 65000;
}
Время, используещеся в программировании исчисляется в милисекундах, то есть 30000мс это есть 30 секунд (1000мс=1с)

Чтобы сделать нашего босса более разговорчивым, давайте заставим его болтать, при агро и при смерти. (стандартный набор)
Code
void EnterCombat(Unit* /*who*/)
{
me->MonsterYell("Your death will come now!", LANG_UNIVERSAL, NULL);
}

void JustDied(Unit* /*pKiller*/)
{
me->MonsterYell("You have deceived me! My time will come ...", LANG_UNIVERSAL, NULL);
}
Давайте разберемся что к чему:

void EnterCombat(Unit* /*who*/) - условие, агро моба.
me->MonsterYell("Your death will come now!", LANG_UNIVERSAL, NULL); - дествие при выполнении предыдущего условия

"Your death will come now!" - реплика которую должен выкрикнуть наш пациент при агро. Можно вместо слов в кавычках использовать текст из БД, например (-25, LANG_UNIVERSAL, NULL)
LANG_UNIVERSAL - это язык, на котором должен наш босс/моб болтать, из названия думаю ясно что этот способ универсальный, то есть понимают его все.

Вторую часть кода расписывать не стану, думаю понятно, тут тоже самое за исключением условия - наш босс/моб умер.
Хотелось бы остановить внимание на язках, которые сипользуются в ТС
LANG_UNIVERSAL
LANG_ORCISH
LANG_DARNASSIAN
LANG_TAURAHE
LANG_DWARVISH
LANG_COMMON
LANG_DEMONIC
LANG_TITAN
LANG_THALASSIAN
LANG_DRACONIC
LANG_KALIMAG
LANG_GNOMISH
LANG_TROLL
LANG_GUTTERSPEAK
LANG_DRAENEI
LANG_ZOMBIE
LANG_GNOMISH_BINARY
LANG_GOBLIN_BINARY
LANG_WORGEN
LANG_GOBLIN
Дальше нужно заскриптовать наши спеллы, обновление АИ.
Принцип действия данной части кода таков: Если таймер способности меньше или равен нулю, то кастуем спелл и обновляем. Если не выполено предыдушее условие - таймер ведет отстчет в обратную сторону.
Code
void UpdateAI(const uint32 diff)
{
if (ImpaleTimer <= diff)
{
if (Unit* target = SELECT_TARGET_RANDOM)
DoCast(target, SPELL_IMPALE);

ImpaleTimer = 30000;
} else ImpaleTimer -= diff;

if (UnholyshadowTimer <= diff)
{
if (Unit* target = SELECT_TARGET_RANDOM)
DoCast(target, SPELL_UNHOLYSHADOW);

UnholyshadowTimer = 65000;
} else UnholyshadowTimer -= diff;

DoMeleeAttackIfReady();
}
DoMeleeAttackIfReady(); - эта часть дает боссу/мобу бить обычными атаками, если данной части в коде не будет наш босс будет бегать за вами и бить только тогда, когда подойдет время каста.

Вот вприниципе и вся кодовая часть нашего босса/моба. Давайте теперь из этого всего соберем полный код:
Code
enum BossSpells
{
SPELL_IMPALE = 56090,
SPELL_UNHOLYSHADOW = 57369,
};

class boss_wowgame_manual : public CreatureScript
{
public:
boss_wowgame_manual() : CreatureScript("boss_wowgame_manual") { }

CreatureAI* GetAI(Creature* creature) const
{
return new boss_wowgame_manualAI (creature);
}

struct boss_wowgame_manualAI : public ScriptedAI
{
boss_wowgame_manualAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
}

InstanceScript* instance;

uint32 ImpaleTimer;
uint32 UnholyshadowTimer;

void Reset()
{
ImpaleTimer = 30000;
UnholyshadowTimer = 65000;
}

void EnterCombat(Unit* /*who*/)
{
me->MonsterYell("Your death will come now!", LANG_UNIVERSAL, NULL);
}

void JustDied(Unit* /*pKiller*/)
{
me->MonsterYell("You have deceived me! My time will come ...", LANG_UNIVERSAL, NULL);
}

void UpdateAI(const uint32 diff)
{
if (ImpaleTimer <= diff)
{
if (Unit* target = SELECT_TARGET_RANDOM)
DoCast(target, SPELL_IMPALE);

ImpaleTimer = 30000;
} else ImpaleTimer -= diff;

if (UnholyshadowTimer <= diff)
{
if (Unit* target = SELECT_TARGET_RANDOM)
DoCast(target, SPELL_UNHOLYSHADOW);

UnholyshadowTimer = 65000;
} else UnholyshadowTimer -= diff;

DoMeleeAttackIfReady();
}
};
};

void AddSC_boss_wowgame_manual()
{
new boss_wowgame_manual();
}
void AddSC_boss_wowgame_manual() - этим мы добавим загрузку скрипта в ядро.

Наш босс готов.

P.S. Если вдруг вы захотите его немного изменить, поменять спеллы то тогда это будет кстати:
Цель, которую выберет босс/моб для удара определяется следующим условием:
Code
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)
Также бывают и другие типы выбора цели:
SELECT_TARGET_RANDOM - цель выбирается случайно.
SELECT_TARGET_TOPAGGRO - выбирает юнита, который по аггрессии занимает позицию с начала.
SELECT_TARGET_BOTTOMAGGRO - выбирает юнита, который по аггрессии занимает позицию с конца.
SELECT_TARGET_NEAREST - выбирает юнита, который находится ближе всех.
SELECT_TARGET_FARTHEST - выбирает юнита, который находится дальше всех.

Прошу поднять тему думаю она поможет многим
Скачать уже сделанный патч можно ниже
http://letitbit.net/download/60366.668cae09682fa2d2a2095bd4b399/Boss_wowgame.rar.html


Сообщение отредактировал VIPSergey - Вторник, 10.07.2012, 09:42
 
hackДата: Среда, 22.08.2012, 15:27 | Сообщение # 2
Скаут
Группа: Пользователи
Сообщений: 13
Награды: 0
Репутация: 1
Статус:
Мне кажется или копипас?
 
dykerДата: Понедельник, 11.06.2018, 12:14 | Сообщение # 3
Скаут
Группа: Пользователи
Сообщений: 3
Награды: 0
Репутация: 0
Статус:
полезно
 
  • Страница 1 из 1
  • 1
Поиск: