Показать сообщение отдельно
Старый 07.04.2005, 12:02   #138
Vam

AGFC
Гость
 
Сообщений: n/a

По умолчанию Re: Уроки скриптологии

15. Магия.

Общие магические функции расположены в директории AI\Magic

// ************************************************** **
// Регистрация повреждения от магии и начисление экспы
// ************************************************** **

// ================================================== ==================
// Аргументы:
// --------------------------------------------------------------------
// slf - НПС кастующий заклинание
// oth - НПС цель
// damage - повреждение, нанесенное заклинанием
// ================================================== ==================

func void B_MagicHurtNpc(var C_NPC slf,var C_NPC oth,var int damage)
{
* *// уменьшить жизнь цели на величину повреждения
* *Npc_ChangeAttribute(oth,ATR_HITPOINTS,-damage);
* *// если цель мертва
* *if(Npc_IsDead(oth))
* *{
* * * *// (если кастующий ГГ или кастующий член партии ГГ) и экспа за цель не была начислена
* * * *if(Npc_IsPlayer(slf) ¦¦ (slf.aivar[AIV_PARTYMEMBER]==TRUE)) && (oth.aivar[AIV_VictoryXPGiven] == FALSE)
* * * *{
* * * * * *// начисление ГГ экспы (уровень цели * 10) (Примечание: Ошибка - вместо self.level должно быть oth.level)
* * * * * *B_GivePlayerXP(self.level * XP_PER_VICTORY);
* * * * * *// установить НПС флаг начисления экспы
* * * * * *oth.aivar[AIV_VictoryXPGiven] = TRUE;
* * * *};
* *};
};

... ещё файл

// **************************************
// Подготовка заклинания к использованию
// **************************************

// ================================================
// Аргументы:
// ------------------------------------------------
// slf - НПС кастующий заклинание
// spell - заклинание
// mana - требуемое кол-во маны
// ================================================

func void B_ReadySpell(var C_NPC slf,var int spell,var int mana)
{
* *// если макс. мана < требуемой
* *if(slf.attribute[ATR_MANA_MAX] < mana)
* *{
* * * *
* * * *// увеличить макс. ману на величину требуемой
* * * *Npc_ChangeAttribute(slf,ATR_MANA_MAX,mana);
* *};
* *// если мана < требуемой
* *if(slf.attribute[ATR_MANA] < mana)
* *{
* * * *// увеличить ману на величину требуемой
* * * *Npc_ChangeAttribute(slf,ATR_MANA,mana);
* *};
* *// если это заклинание уже применяется
* *if(Npc_IsDrawingSpell(slf) == spell)
* *{
* * * *return;
* *} *
* *// если это заклинание уже активно
* *if(Npc_GetActiveSpell(slf) == spell)
* *{
* * * *return; * *
* *}
* *// если активно другое заклинание
* *else if(Npc_GetActiveSpell(slf) != -1)
* *{
* * * *// убрать старое заклинание
* * * *AI_RemoveWeapon(slf);
* *};
* *// взять заклинание в руку
* *AI_ReadySpell(slf,spell,mana);
};

... ещё файл

// ************************************************** ***********
// Выбор заклинания кастующим НПС
// ************************************************** ***********

// ================================================== ===========
// Аргументы:
// -------------------------------------------------------------
// slf - НПС кастующий заклинание (агрессор)
// oth - НПС цель
// --------------------------------------------------------------------
// Возвращаемое значение:
// TRUE - заклинание готово, FALSE - нет.
// ================================================== ===========

func int B_SelectSpell(var C_NPC slf,var C_NPC oth)
{ *
* *// если агрессор друг ГГ и цель ГГ и цель человек
* *if(slf.npctype == NPCTYPE_FRIEND) && Npc_IsPlayer(oth) && (oth.guild < GIL_SEPERATOR_HUM)
* *{
* * * *// если агрессор Маг огня или агрессор всегда использует магию
* * * *if(slf.guild == GIL_KDF) ¦¦ (slf.aivar[AIV_MagicUser] == MAGIC_ALWAYS)
* * * *{
* * * * * *// если агрессор не имеет руны Сон
* * * * * *if(Npc_HasItems(slf,ItRu_Sleep) == 0)
* * * * * *{
* * * * * * * *// создать в инвентаре агрессора руну Сон
* * * * * * * *CreateInvItems(slf,ItRu_Sleep,1);
* * * * * *};
* * * * * *// подготовка заклинания Сон
* * * * * *B_ReadySpell(slf,SPL_Sleep,SPL_Cost_Sleep);
* * * * * *return TRUE;
* * * *}
* * * *else
* * * *{
* * * * * *return FALSE;
* * * *};
* *};
* *// если агрессор Черный маг и агрессор всегда использует магию
* *if(slf.guild == GIL_DMT) && (slf.aivar[AIV_MagicUser] == MAGIC_ALWAYS)
* *{
* * * * * *// создать в инвентаре агрессора следующие руны, если он их не имеет
* * * * * *if(Npc_HasItems(slf,ItRu_InstantFireball) == 0) {CreateInvItems(slf,ItRu_InstantFireball,1);}; *// "Огненный шар"
* * * * * *if(Npc_HasItems(slf,ItRu_Deathbolt) == 0) * * * {CreateInvItems(slf,ItRu_Deathbolt,1);}; * * * *// "Deathbolt" (Примечание: название не переведено)
* * * * * *if(Npc_HasItems(slf,ItRu_Deathball) == 0) * * * {CreateInvItems(slf,ItRu_Deathball,1);}; * * * *// "Deathball"
* * * * * *if(Npc_HasItems(slf,ItRu_Firerain) == 0) * * * *{CreateInvItems(slf,ItRu_Firerain,1);}; * * * * // "Огненный дождь"
* * * * * *if(Npc_HasItems(slf,ItRu_Thunderstorm) == 0) * *{CreateInvItems(slf,ItRu_Thunderstorm,1);}; * * // "Шторм"
* * * * * *if(Npc_HasItems(slf,ItRu_LightningFlash) == 0) *{CreateInvItems(slf,ItRu_LightningFlash,1);}; * // "Удар молнии"
* * * * * *if(Npc_HasItems(slf,ItRu_Firestorm) == 0) * * * {CreateInvItems(slf,ItRu_Firestorm,1);}; * * * *// "Малая огненная буря"
* * * * * *if(Npc_HasItems(slf,ItRu_Skull) == 0) * * * * * {CreateInvItems(slf,ItRu_Skull,1);}; * * * * * *// "Крик мертвых"
* * * *// если агрессор "Черный маг" (Примечание: Маг какой-то особенный, хотя в переводе не отражено)
* * * *if(Hlp_GetInstanceID(slf) == Hlp_GetInstanceID(DMT_1299_OberDementor_DI))
* * * *{
* * * * * *// подготовка заклинания "Крик мертвых"
* * * * * *B_ReadySpell(slf,SPL_Skull,SPL_Cost_Skull);
* * * * * *return TRUE;
* * * *}
* * * *else // обычные Черные маги
* * * *{
* * * * * *// если уже есть оружие готовое к бою
* * * * * *if(Npc_IsDrawingWeapon(slf))
* * * * * *{
* * * * * * * *return TRUE;
* * * * * *};
* * * * * *// если случайное число не задано
* * * * * *if(slf.aivar[AIV_SelectSpell] <= 0)
* * * * * *{
* * * * * * * *var int dK_rnd;
* * * * * * * *dK_rnd = Hlp_Random(10);
* * * * * * * *// получить случайное число
* * * * * * * *slf.aivar[AIV_SelectSpell] += dK_rnd;
* * * * * *};
* * * * * *// если случайное число < 10
* * * * * *if(slf.aivar[AIV_SelectSpell] < 10)
* * * * * *{
* * * * * * * *// если Глава <= 3, то подготовить заклинание "Огненный шар"
* * * * * * * *if(Kapitel <= 3) * * * *{B_ReadySpell(slf,SPL_InstantFireball,SPL_Cost_In stantFireball); return TRUE;}
* * * * * * * *// если Глава <= 4, то подготовить заклинание "Deathbolt"
* * * * * * * *else if (Kapitel <= 4) *{B_ReadySpell(slf,SPL_DeathBolt,SPL_Cost_DeathBol t); return TRUE;}
* * * * * * * *// иначе подготовить заклинание "Deathbаll"
* * * * * * * *else /*Kap 5+*/ * * * * {B_ReadySpell(slf,SPL_DeathBall,SPL_Cost_DeathBall ); return TRUE;};
* * * * * *}
* * * * * *// если случайное число == 10
* * * * * *else if(slf.aivar[AIV_SelectSpell] == 10)
* * * * * *{ *
* * * * * * * *// случайное число = 11
* * * * * * * *slf.aivar[AIV_SelectSpell] = 11;
* * * * * * * *var int dK_Mega;
* * * * * * * *dK_Mega = Hlp_Random(100);
* * * * * * * *// с вероятностью 0.02 подготовить заклинание "Огненный дождь"
* * * * * * * *if * * *(dK_Mega <= 2) *{B_ReadySpell(slf,SPL_Firerain,SPL_Cost_Firerain) ; * * * * * * *return TRUE;}
* * * * * * * *// с вероятностью 0.03 подготовить заклинание "Шторм"
* * * * * * * *else if (dK_Mega <= 5) *{B_ReadySpell(slf,SPL_Thunderstorm,SPL_Cost_Thund erstorm); * * *return TRUE;}
* * * * * * * *// с вероятностью 0.05 подготовить заклинание "Удар молнии"
* * * * * * * *else if (dK_Mega <= 10) {B_ReadySpell(slf,SPL_LightningFlash,SPL_Cost_Ligh tningFlash); *return TRUE;}
* * * * * * * *// с вероятностью 0.9 подготовить заклинание "Малая огненная буря"
* * * * * * * *else * * * * * * * * * *{B_ReadySpell(slf,SPL_Firestorm,SPL_Cost_Firestor m); * * * * * *return TRUE;};
* * * * * *}
* * * * * *// если случайное число == 12
* * * * * *else if (slf.aivar[AIV_SelectSpell] == 12)
* * * * * *{ *
* * * * * * * *// случайное число == 0
* * * * * * * *slf.aivar[AIV_SelectSpell] = 0;
* * * * * *};
* * * *};
* * * *return TRUE;
* *};
* *// если агрессор Маг огня или агрессор всегда использует магию
* *if(slf.guild == GIL_KDF) ¦¦ (slf.aivar[AIV_MagicUser] == MAGIC_ALWAYS)
* *{
* * * *// создать в инвентаре агрессора следующие руны, если он их не имеет
* * * *if(Npc_HasItems(slf,ItRu_Concussionbolt) == 0)
* * * *{
* * * * * *CreateInvItems(slf,ItRu_Concussionbolt,1); * * *// "Concussionbolt" (Название не переведено)
* * * *};
* * * *if(Npc_HasItems(slf,ItRu_InstantFireBall) == 0)
* * * *{
* * * * * *CreateInvItems(slf,ItRu_InstantFireBall,1); * * // "Огненный шар"
* * * *};
* * * *if(Npc_HasItems(slf,ItRu_Deathball) == 0)
* * * *{
* * * * * *CreateInvItems(slf,ItRu_Deathball,1); * * * * * // "Deathball" (Название не переведено)
* * * *};
* * * *if(Npc_HasItems(slf,ItRu_FullHeal) == 0)
* * * *{
* * * * * *CreateInvItems(slf,ItRu_FullHeal,1); * * * * * *// "Лечить сильное ранение"
* * * *};
* * * *// если текущая жизнь агрессора < 100 (Примечание: здесь и далее необходимо self заменить на slf)
* * * *if(self.attribute[ATR_HITPOINTS] < 100)
* * * *{
* * * * * *// подготовить заклинание "Лечить сильное ранение"
* * * * * *B_ReadySpell(slf,SPL_FullHeal,SPL_Cost_FullHeal);
* * * * * *return TRUE;
* * * *}
* * * *// если причина атаки агрессора убийство цели
* * * *else if(C_NpcHasAttackReasonToKill(self))
* * * *{
* * * * * *// если цель неуязвима или цель Равен (Примечание: Ошибка - необходимо self и other заменить на oth)
* * * * * *if(self.flags == NPC_FLAG_IMMORTAL) ¦¦ (Hlp_GetInstanceID(other) == Hlp_GetInstanceID(Raven))
* * * * * *{
* * * * * * * *// подготовить заклинание "Deathball"
* * * * * * * *B_ReadySpell(slf,SPL_Deathball,SPL_Cost_Deathball );
* * * * * *}
* * * * * *else
* * * * * *{
* * * * * * * *// подготовить заклинание "Огненный шар"
* * * * * * * *B_ReadySpell(slf,SPL_InstantFireball,SPL_Cost_Ins tantFireBall);
* * * * * *};
* * * * * *return TRUE;
* * * *}
* * * *else
* * * *{
* * * * * *// подготовить заклинание "Concussionbolt"
* * * * * *B_ReadySpell(slf,SPL_Concussionbolt,SPL_Cost_Conc ussionbolt);
* * * * * *return TRUE;
* * * *};
* *};
* *// если агрессор Паладин
* *if(slf.guild == GIL_PAL)
* *{
* * * *// если агрессор применяет тактику сражения охраны крепостных стен
* * * *if(slf.fight_tactic == FAI_NAILED)
* * * *{
* * * * * *return FALSE;
* * * *};
* * * *// если агрессор не имеет руны "Святая стрела"
* * * *if(Npc_HasItems(slf,ItRu_PalHolyBolt) == 0)
* * * *{
* * * * * *// создать в инвентаре агрессора руну "Святая стрела"
* * * * * *CreateInvItems(slf,ItRu_PalHolyBolt,1);
* * * *};
* * * *// если расстояние между агрессором и целью > дистанции атаки оружием ближнего радиуса действия и цель является источником зла
* * * *if(Npc_GetDistToNpc(slf,oth) > FIGHT_DIST_MELEE) && (C_NpcIsEvil(oth))
* * * *{
* * * * * *// подготовить заклинание "Святая стрела"
* * * * * *B_ReadySpell(slf,SPL_PalHolyBolt,SPL_Cost_PalHoly Bolt);
* * * * * *return TRUE;
* * * *}
* * * *else
* * * *{
* * * * * *return FALSE;
* * * *};
* *};
* *// если агрессор Маг скелетов
* *if(slf.guild == GIL_SKELETON_MAGE)
* *{
* * * *// создать в инвентаре агрессора следующие руны, если он их не имеет
* * * *if(Npc_HasItems(slf,ItRu_SumSkel) == 0)
* * * *{
* * * * * *CreateInvItems(slf,ItRu_SumSkel,1); * * // "Вызвать скелет"
* * * *};
* * * *if(Npc_HasItems(slf,ItRu_IceCube) == 0)
* * * *{
* * * * * *CreateInvItems(slf,ItRu_IceCube,1); * * // "Ледяная глыба"
* * * *};
* * * *if(Npc_HasItems(slf,ItRu_Icebolt) == 0)
* * * *{
* * * * * *CreateInvItems(slf,ItRu_Icebolt,1); * * // "Ледяная стрела"
* * * *};
* * * *// если случайное число >= 6
* * * *if(slf.aivar[AIV_SelectSpell] >= 6)
* * * *{
* * * * * *// случайное число = 1
* * * * * *slf.aivar[AIV_SelectSpell] = 1;
* * * *};
* * * *// если цель не заморожена и случайное число == 0
* * * *if(!Npc_IsInState(oth,ZS_MagicFreeze)) && (slf.aivar[AIV_SelectSpell] == 0)
* * * *{
* * * * * *// подготовить заклинание "Ледяная глыба"
* * * * * *B_ReadySpell(slf,SPL_IceCube,SPL_Cost_IceCube);
* * * * * *return TRUE;
* * * *}
* * * *// если случайное число == 1
* * * *else if (slf.aivar[AIV_SelectSpell] == 1)
* * * *{
* * * * * *// подготовить заклинание "Вызвать скелет"
* * * * * *B_ReadySpell(slf,SPL_SummonSkeleton,SPL_Cost_Summ onSkeleton);
* * * * * *return TRUE;
* * * *}
* * * *else
* * * *{
* * * * * *// подготовить заклинание "Ледяная стрела"
* * * * * *B_ReadySpell(slf,SPL_Icebolt,SPL_Cost_Icebolt);
* * * * * *return TRUE;
* * * *};
* *};
* *// если агрессор Ледяной голем
* *if(slf.guild == GIL_ICEGOLEM)
* *{
* * * *// если агрессор не имеет руны "Ледяная глыба"
* * * *if(Npc_HasItems(slf,ItRu_IceCube) == 0)
* * * *{
* * * * * *// создать в инвентаре агрессора руну "Ледяная глыба"
* * * * * *CreateInvItems(slf,ItRu_IceCube,1);
* * * *};
* * * *// если расстояние между агрессором и целью < дистанции атаки оружием ближнего радиуса действия или цель заморожена
* * * *if(Npc_GetDistToNpc(slf,oth) < FIGHT_DIST_MELEE) ¦¦ Npc_IsInState(oth,ZS_MagicFreeze) * * * * * * * * * * * * * * *
* * * *{
* * * * * *return FALSE;
* * * *}
* * * *else
* * * *{
* * * * * *// подготовить заклинание "Ледяная глыба"
* * * * * *B_ReadySpell(slf,SPL_IceCube,SPL_Cost_IceCube);
* * * * * *return TRUE;
* * * * * *
* * * *};
* *};
* *// если агрессор Огненный голем
* *if(slf.guild == GIL_FIREGOLEM)
* *{
* * * *// если агрессор не имеет руны "Огненный шар"
* * * *if(Npc_HasItems(slf,ItRu_InstantFireball) == 0)
* * * *{
* * * * * *// создать в инвентаре агрессора руну "Огненный шар"
* * * * * *CreateInvItems(slf,ItRu_InstantFireball,1);
* * * *};
* * * *// если расстояние между агрессором и целью > дистанции атаки оружием ближнего радиуса действия
* * * *if(Npc_GetDistToNpc(slf,oth) > FIGHT_DIST_MELEE)
* * * *{
* * * * * *// подготовить заклинание "Огненный шар"
* * * * * *B_ReadySpell(slf,SPL_InstantFireball,SPL_Cost_Ins tantFireball);
* * * * * *return TRUE;
* * * *}
* * * *else
* * * *{
* * * * * *return FALSE;
* * * *};
* *};
* *// если агрессор Болотный дракон
* *if(slf.aivar[AIV_MM_REAL_ID] == ID_DRAGON_SWAMP)
* *{
* * * *// если агрессор не имеет руны "Огненный шар"
* * * *if(Npc_HasItems(slf,ItRu_InstantFireball) == 0)
* * * *{
* * * * * *// создать в инвентаре агрессора руну "Огненный шар"
* * * * * *CreateInvItems(slf,ItRu_InstantFireball,1);
* * * *};
* * * *// если расстояние между агрессором и целью > дистанции применения драконами магии
* * * *if(Npc_GetDistToNpc(slf,oth) > FIGHT_DIST_DRAGON_MAGIC)
* * * *{
* * * * * *// подготовить заклинание "Огненный шар"
* * * * * *B_ReadySpell(slf,SPL_InstantFireball,SPL_Cost_Ins tantFireball);
* * * * * *return TRUE;
* * * *}
* * * *else
* * * *{
* * * * * *return FALSE;
* * * *};
* *};
* *// если агрессор Каменный дракон (всё идентично Болотному дракону)
* *if(slf.aivar[AIV_MM_REAL_ID] == ID_DRAGON_ROCK)
* *{
* * * *if (Npc_HasItems(slf,ItRu_InstantFireball) == 0)
* * * *{
* * * * * *CreateInvItems(slf,ItRu_InstantFireball,1);
* * * *};
* * * *if (Npc_GetDistToNpc(slf,oth) > FIGHT_DIST_DRAGON_MAGIC)
* * * *{
* * * * * *B_ReadySpell(slf,SPL_InstantFireball,SPL_Cost_Ins tantFireball);
* * * * * *return TRUE;
* * * *}
* * * *else
* * * *{
* * * * * *return FALSE;
* * * *};
* *};
* *// если агрессор Огненный дракон (всё идентично Болотному дракону)
* *if(slf.aivar[AIV_MM_REAL_ID] == ID_DRAGON_FIRE)
* *{
* * * *if(Npc_HasItems(slf,ItRu_InstantFireball) == 0)
* * * *{
* * * * * *CreateInvItems(slf,ItRu_InstantFireball,1);
* * * *};
* * * *if(Npc_GetDistToNpc(slf,oth) > FIGHT_DIST_DRAGON_MAGIC)
* * * *{
* * * * * *B_ReadySpell(slf,SPL_InstantFireball,SPL_Cost_Ins tantFireball);
* * * * * *return TRUE;
* * * *}
* * * *else
* * * *{
* * * * * *return FALSE;
* * * *};
* *};
* *// если агрессор Ледяной дракон (всё идентично Болотному дракону)
* *if(slf.aivar[AIV_MM_REAL_ID] == ID_DRAGON_ICE)
* *{
* * * *if(Npc_HasItems(slf,ItRu_InstantFireball) == 0)
* * * *{
* * * * * *CreateInvItems(slf,ItRu_InstantFireball,1);
* * * *};
* * * *if(Npc_GetDistToNpc(slf,oth) > FIGHT_DIST_DRAGON_MAGIC)
* * * *{
* * * * * *B_ReadySpell(slf,SPL_InstantFireball,SPL_Cost_Ins tantFireball);
* * * * * *return TRUE;
* * * *}
* * * *else
* * * *{
* * * * * *return FALSE;
* * * *};
* *};
* *// если агрессор Дракон нежить
* *if(slf.aivar[AIV_MM_REAL_ID] == ID_DRAGON_UNDEAD)
* *{
* * * *// очистить очередь AI состояний агрессора (Примечание: заменить self на slf)
* * * *Npc_ClearAIQueue(self);
* * * *// если агрессор не имеет руны "Deathball"
* * * *if(Npc_HasItems(slf,ItRu_Deathball) == 0)
* * * *{
* * * * * *// создать в инвентаре агрессора руну "Deathball"
* * * * * *CreateInvItems(slf,ItRu_Deathball,1);
* * * *};
* * * *// если расстояние между агрессором и целью > дистанции применения драконами магии
* * * *if(Npc_GetDistToNpc(slf,oth) > FIGHT_DIST_DRAGON_MAGIC)
* * * *{
* * * * * *// подготовить заклинание "Deathball"
* * * * * *B_ReadySpell(slf,SPL_Deathball,SPL_Cost_Deathball );
* * * * * *return TRUE;
* * * *}
* * * *else
* * * *{
* * * * * *return FALSE;
* * * *};
* *};
* *// если агрессор Шаман орков (всё идентично Огненному голему)
* *if(slf.aivar[AIV_MM_REAL_ID] == ID_ORCSHAMAN)
* *{
* * * *if(Npc_HasItems(slf,ItRu_InstantFireball) == 0)
* * * *{
* * * * * *CreateInvItems(slf,ItRu_InstantFireball,1);
* * * *};
* * * *if(Npc_GetDistToNpc(slf,oth) > FIGHT_DIST_MELEE)
* * * *{
* * * * * *B_ReadySpell(slf,SPL_InstantFireball,SPL_Cost_Ins tantFireball);
* * * * * *return TRUE;
* * * *}
* * * *else
* * * *{
* * * * * *return FALSE;
* * * *};
* *};
* *return FALSE;
}; *

Ответить с цитированием