Показать сообщение отдельно
Старый 26.02.2005, 10:57   #114
Vam

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

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

// *****************************************
// Обработчик состояния смерти НПС
// Примечание: НПС в это состояние переводит также и ядро системы, когда НПС добивают!
// -----------------------------------------
// self - мертвый НПС, other - убийца
// *****************************************

// Инициализация состояния смерти
func void ZS_Dead()
{ *
* *// сброс флага, что тело обыскивалось
* *self.aivar[AIV_RANSACKED] = FALSE;
* *// сброс флага, что НПС член партии
* *self.aivar[AIV_PARTYMEMBER] = FALSE;
* *// НПС перестает смотреть на кого-либо
* *B_StopLookAt(self);
* *// НПС прекращает на что-либо указывать
* *AI_StopPointAt(self);
* *// если (убийца ГГ или убийца член партии ГГ) и начисления экспы ГГ за убийство НПС не было
* *if(Npc_IsPlayer(other) ¦¦ (other.aivar[AIV_PARTYMEMBER] == TRUE)) && (self.aivar[AIV_VictoryXPGiven] == FALSE)
* *{
* * * *// начисление ГГ экспы (уровень НПС * 10)
* * * *B_GivePlayerXP (self.level * XP_PER_VICTORY);
* * * *// установить НПС флаг начисления экспы
* * * *self.aivar[AIV_VictoryXPGiven] = TRUE;
* *};
* *// если убит "Расчленитель" в каньоне
* *if(C_IAmCanyonRazor(self) == TRUE)
* *{
* * * *// счетчик убитых расчленителей ++
* * * *CanyonRazorBodyCount = CanyonRazorBodyCount + 1;
* * * *// если квест Грега об очистке каньона в стадии выполнения
* * * *if(MIS_Addon_Greg_ClearCanyon == LOG_RUNNING)
* * * *{
* * * * * *// выдача на экран информации об убитых расчленителях
* * * * * *B_CountCanyonRazor();
* * * *};
* *};
* *// если убита "Болотная вонючка"
* *if(self.aivar[AIV_MM_REAL_ID] == ID_SWAMPDRONE)
* *{
* * * *// если расстояние между НПС и убийцей < 3 метров
* * * *if(Npc_GetDistToNpc(self,other) < 300)
* * * *{
* * * * * *// жизнь убийцы уменьшается на 50 пунктов
* * * * * *other.attribute[ATR_HITPOINTS] -= 50;
* * * *};
* *};
* *// если Диего убит в Рудниковой долине
* *if(Hlp_GetInstanceID(self) == Hlp_GetInstanceID(DiegoOW))
* *{
* * * *// установить флаг "воскрешения" Диего в Хоринисе
* * * *Diego_IsDead = TRUE;
* *};
* *// если убийца ГГ
* *if(Npc_IsPlayer(other))
* *{
* * * *// установить флаг, что НПС убит ГГ
* * * *self.aivar[AIV_KilledByPlayer] = TRUE;
* * * *// если этого НПС не разрешалось убивать
* * * *if(C_DropUnconscious())
* * * *{
* * * * * *// счетчик невинно убитых ++
* * * * * *MadKillerCount = (MadKillerCount + 1);
* * * *}; * * *
* * * *// если убит "Полевой жук" и квест Фестера в стадии выполнения
* * * *if(self.guild == GIL_GIANT_BUG) && (MIS_Fester_KillBugs == LOG_RUNNING)
* * * *{
* * * * * *// увеличить счетчик убитых Полевых жуков
* * * * * *Festers_Giant_Bug_Killed = Festers_Giant_Bug_Killed + 1;
* * * *};
* * * *// если убита "Болотная крыса" и квест охоты с Аллигатором Джеком в стадии выполнения
* * * *if(Hlp_GetInstanceID(self) == Hlp_GetInstanceID(Swamprat)) && (MIS_KrokoJagd == LOG_Running)
* * * *{
* * * * * *// увеличить счетчик убитых Болотных крыс
* * * * * *AlligatorJack_KrokosKilled = AlligatorJack_KrokosKilled + 1;
* * * *};
* * * *// если убит "Рамон"
* * * *if(Hlp_GetInstanceID(self) == Hlp_GetInstanceID(Ramon))
* * * *{
* * * * * *// установка флага, что ГГ может разговаривать с бандитами
* * * * * *Player_HasTalkedToBanditCamp = TRUE;
* * * *};
* * * *// если убит "Франко"
* * * *if(Hlp_GetInstanceID(self) == Hlp_GetInstanceID(Franco))
* * * *{
* * * * * *// если квест "Охота на болотожоров с Логаном" в стадии выполнения
* * * * * *if(MIS_HlpLogan == LOG_RUNNING)
* * * * * *{
* * * * * * * *// квест завершается
* * * * * * * *MIS_HlpLogan = LOG_OBSOLETE;
* * * * * *};
* * * * * *// если квест "Найти Эдгора с каменной плиткой" в стадии выполнения
* * * * * *if(MIS_HlpEdgor == LOG_RUNNING)
* * * * * *{
* * * * * * * *// квест завершается
* * * * * * * *MIS_HlpEdgor = LOG_OBSOLETE;
* * * * * *};
* * * *};
* * * *// если убит "Фортуно"
* * * *if(Hlp_GetInstanceID(self) == Hlp_GetInstanceID(Fortuno))
* * * *{
* * * * * *// квест по "Поиску зеленого послушника" завершается
* * * * * *Log_SetTopicStatus(Topic_Addon_Fortuno,LOG_OBSOLE TE);
* * * *};
* *};
* *// если убит "Ползун" в пещере (где должен появиться Блудвин)
* *if(Hlp_GetInstanceID(self) == Hlp_GetInstanceID(Goldminecrawler))
* *{
* * * *// если убито более 8 ползунов и Блудвина нет
* * * *if(Minecrawler_Killed >= 9) && (Bloodwyn_Spawn == FALSE)
* * * *{ *
* * * * * *// Блудвин появляется в точке ADW_MINE_TO_MC_03
* * * * * *AI_Teleport(Bloodwyn,"ADW_MINE_TO_MC_03");
* * * * * *// установить Блудвину распорядок дня
* * * * * *B_StartOtherRoutine(Bloodwyn,"MINE");
* * * * * *// начислить ГГ 500 экспы
* * * * * *B_GivePlayerXP(XP_Addon_Bloodywyn);
* * * * * *// установить флаг появления Блудвина
* * * * * *Bloodwyn_Spawn = TRUE;
* * * *}
* * * *else // иначе
* * * *{
* * * * * *// счетчик убитых ползунов ++
* * * * * *Minecrawler_Killed = (Minecrawler_Killed + 1);
* * * *};
* *};
* *// удаление продаваемых предметов у торговцев
* *B_GiveTradeInv(self);
* *// создать в инвентаре монстров добываемые предметы (в зависимости от способностей ГГ)
* *B_GiveDeathInv(self);
* *// удаление рун у НПС
* *B_ClearRuneInv(self);
* *// оставить счетчики криминала ГГ по локациям в старом состоянии
* *B_DeletePetzCrime(self);
* *// сброс флага криминала у НПС
* *self.aivar[AIV_NpcSawPlayerCommit] = CRIME_NONE;
* *// убрать оружие
* *AI_UnequipWeapons(self);
* *// сброс флага показа видео
* *self.aivar[AIV_TAPOSITION] = FALSE;
};

// Цикл смерти (выхода из него нет)
func int ZS_Dead_loop()
{
* *// если показа видео не было
* *if(self.aivar[AIV_TAPOSITION] == FALSE)
* *{
* * * *// показать видео соответствующее смерти НПС
* * * *B_DragonKillCounter(self);
* * * *// установить флаг показа видео
* * * *self.aivar[AIV_TAPOSITION] = TRUE;
* *};
* *return LOOP_CONTINUE;
};



Добавление от 26 февраля 2005, 10:57
9. Функции состояний монстров.

Все обработчики основных состояний монстров находятся в директории ..\AI\Monster\ZS_Monster\
Имена файлов соответствуют именам обработчиков.

// **************************************
// Обработчик состояния атаки
// --------------------------------------
// self - НПС агрессор, other - НПС цель
// **************************************

// Функция обработки вспомогательного восприятия PERC_ASSESSSURPRISE
// Вызывается ядром системы когда ГГ превращается в человека из животного
func void B_MM_AssessSurprise()
{
* *// целью агрессора становится ГГ
* *Npc_SetTarget(self,other);
};

// Мнициализация состояния атаки
func void ZS_MM_Attack()
{
* *// установка времени реакции на восприятия 1 сек
* *Npc_SetPercTime(self,1);
* *// разрешить восприятие мертвого тела
* *Npc_PercEnable(self,PERC_ASSESSBODY,B_MM_AssessBo dy);
* *// разрешить восприятие магии
* *Npc_PercEnable(self,PERC_ASSESSMAGIC,B_AssessMagi c);
* *// разрешить восприятие повреждения
* *Npc_PercEnable(self,PERC_ASSESSDAMAGE,B_MM_Assess Damage);
* *// разрешить восприятие предупреждения
* *Npc_PercEnable(self,PERC_ASSESSWARN,B_MM_AssessWa rn);
* *// разрешить вспомогательное восприятие превращения
* *Npc_PercEnable(self,PERC_ASSESSSURPRISE,B_MM_Asse ssSurprise);
* *// инициализировать переменную other (последняя цель)
* *B_ValidateOther();
* *// если агрессор овца
* *if(self.guild == GIL_SHEEP)
* *{
* * * *// очистка очереди AI состояний НПС
* * * *Npc_ClearAIQueue(self);
* * * *// очистка восприятий
* * * *B_ClearPerceptions(self);
* * * *// установка цели
* * * *Npc_SetTarget(self,other);
* * * *// НПС убегает от цели
* * * *AI_StartState(self,ZS_MM_Flee,0,"");
* * * *return;
* *};
* *// НПС встает
* *AI_StandUp(self);
* *// включается режим передвижения - бег
* *AI_SetWalkmode(self,NPC_RUN);
* *// агрессору посылается предупреждение от цели
* *Npc_SendPassivePerc(self,PERC_ASSESSWARN,other,se lf);
* *// сброс флага окончания преследования
* *self.aivar[AIV_PursuitEnd] = FALSE;
* *// сброс счетчика времени нахождения в состоянии
* *self.aivar[AIV_StateTime] = 0;
* *// сброс флага первого удара
* *self.aivar[AIV_HitByOtherNpc] = 0;
* *// сброс выбранного заклинания
* *self.aivar[AIV_SelectSpell] = 0;
* *// сброс счетчика регенерации
* *self.aivar[AIV_TAPOSITION] = 0;
};

// Цикл состояния атаки
func int ZS_MM_Attack_Loop()
{
* *// повторно инициализировать other целью
* *Npc_GetTarget(self);
* *// если НПС дракон
* *if(self.guild == GIL_DRAGON)
* *{
* * * *// счетчик регенерации ++
* * * *self.aivar[AIV_TAPOSITION] += 1;
* * * *// если жизнь НПС < максимальной и счетчик регенерации >= 2 cек
* * * *if (self.attribute[ATR_HITPOINTS] < self.attribute[ATR_HITPOINTS_MAX]) && (self.aivar[AIV_TAPOSITION] >= 2)
* * * *{
* * * * * *// жизнь ++
* * * * * *self.attribute[ATR_HITPOINTS] += 1;
* * * * * *// сброс счетчика
* * * * * *self.aivar[AIV_TAPOSITION] = 0;
* * * *};
* *};
* *// если Равен убит и агрессор Каменный сторож
* *if(RavenIsDead == TRUE) && (self.guild == GIL_STONEGUARDIAN)
* *{ *
* * * *// агрессор умирает
* * * *B_KillNpc(self);
* *};
* *// если текущий уровень - Миненталь
* *if(CurrentLevel == OLDWORLD_ZEN)
* *{
* * * *// если расстояние от агрессора до точки OC_RAMP_07 <= 5 метров
* * * *if(Npc_GetDistToWP(self,"OC_RAMP_07") <= 500)
* * * *{
* * * * * *// очистка очереди AI состояний НПС
* * * * * *Npc_ClearAIQueue(self);
* * * * * *// НПС встает
* * * * * *AI_StandUp(self);
* * * * * *// проигрывается анимация T_WARN
* * * * * *AI_PlayAni(self,"T_WARN");
* * * * * *// установка флага окончания преследования
* * * * * *self.aivar[AIV_PursuitEnd] = TRUE;
* * * * * *return LOOP_END;
* * * *};
* *}; * * *
* *// если расстояние между НПС и целью > дистанции сражения
* *if(Npc_GetDistToNpc(self,other) > FIGHT_DIST_CANCEL)
* *{
* * * *// очистка очереди AI состояний НПС
* * * *Npc_ClearAIQueue(self);
* * * *// НПС встает
* * * *AI_StandUp(self);
* * * *// установка флага окончания преследования
* * * *self.aivar[AIV_PursuitEnd] = TRUE;
* * * *return LOOP_END;
* *};
* *// если время преследования превышает допустимое и НПС преследует цель
* *if(Npc_GetStateTime(self) > self.aivar[AIV_MM_FollowTime]) && (self.aivar[AIV_PursuitEnd] == FALSE)
* *{
* * * *Npc_ClearAIQueue(self);
* * * *AI_StandUp(self);
* * * *// НПС закончил преследование
* * * *self.aivar[AIV_PursuitEnd] = TRUE;
* * * *// получить дистанцию до цели
* * * *self.aivar[AIV_Dist] = Npc_GetDistToNpc(self,other);
* * * *// обновить время состояния НПС
* * * *self.aivar[AIV_StateTime] = Npc_GetStateTime(self);
* * * *// проиграть анимацию T_WARN
* * * *AI_PlayAni(self,"T_WARN");
* *};
* *// если НПС завершил преследование цели
* *if(self.aivar[AIV_PursuitEnd] == TRUE)
* *{
* * * *// если расстояние между НПС и целью > диапазона чувствительности НПС
* * * *if(Npc_GetDistToNpc(self,other) > self.senses_range)
* * * *{
* * * * * *return LOOP_END;
* * * *};
* * * *// если текущее время > предыдущего времени (прошла как минимум секунда)
* * * *if (Npc_GetStateTime (self) > self.aivar[AIV_StateTime])
* * * *{
* * * * * *// если расстояние между НПС и целью меньше дистанции, когда НПС прекратил преследование
* * * * * *if(Npc_GetDistToNpc(self,other) < self.aivar[AIV_Dist])
* * * * * *// или (цель не бежит и не прыгает)
* * * * * *¦¦ ((!C_BodyStateContains(other,BS_RUN)) && (!C_BodyStateContains(other,BS_JUMP)))
* * * * * *{
* * * * * * * *// сброс флага окончания преследования
* * * * * * * *self.aivar[AIV_PursuitEnd] = FALSE;
* * * * * * * *// сброс времени нахождения НПС в этом состоянии
* * * * * * * *Npc_SetStateTime(self,0);
* * * * * * * *// сброс счетчика времени нахождения в состоянии
* * * * * * * *self.aivar[AIV_StateTime] = 0;
* * * * * *}
* * * * * *else
* * * * * *{
* * * * * * * *// НПС поворачивается к цели
* * * * * * * *AI_TurnToNpc(self,other);
* * * * * * * *// получить дистанцию до цели
* * * * * * * *self.aivar[AIV_Dist] = Npc_GetDistToNpc(self,other);
* * * * * * * *// обновить время состояния НПС
* * * * * * * *self.aivar[AIV_StateTime] = Npc_GetStateTime(self);
* * * * * *};
* * * *};
* * * *return LOOP_CONTINUE;
* *};
* *// если (цель плывет или ныряет) и НПС не преследует цель в воде
* *if(C_BodyStateContains(other,BS_SWIM) ¦¦ C_BodyStateContains(other,BS_DIVE)) && (self.aivar[AIV_MM_FollowInWater] == FALSE)
* *{
* * * *// очистка очереди AI состояний НПС
* * * *Npc_ClearAIQueue(self);
* * * *// НПС встает
* * * *AI_StandUp(self);
* * * *return LOOP_END;
* *};
* *// если НПС выжидает перед атакой
* *if(self.aivar[AIV_WaitBeforeAttack] == 1)
* *{
* * * *// ожидание 0.8 сек
* * * *AI_Wait(self,0.8 );
* * * *// сброс флага задержки
* * * *self.aivar[AIV_WaitBeforeAttack] = 0;
* *};
* *// если уровень НПС == 0 (вызванный монстр)
* *if(self.level == 0)
* *{
* * * *// если текущее время > предыдущего времени (прошла как минимум секунда)
* * * *if(Npc_GetStateTime(self) > self.aivar[AIV_StateTime])
* * * *{
* * * * * *// время от начала вызова монстра ++
* * * * * *self.aivar[AIV_SummonTime] = (self.aivar[AIV_SummonTime] + 1);
* * * * * *// запомнить текущее время
* * * * * *self.aivar[AIV_StateTime] = Npc_GetStateTime(self);
* * * *};
* * * *// если время от начала вызова монстра >= времени жизни вызванных монстров
* * * *if(self.aivar[AIV_SummonTime] >= MONSTER_SUMMON_TIME)
* * * *{
* * * * * *// вызванный монстр умирает
* * * * * *Npc_ChangeAttribute(self,ATR_HITPOINTS,-self.attribute[ATR_HITPOINTS_MAX]);
* * * *};
* *};
* *// если цель не бежит и не прыгает и время в состоянии > 0
* *if((!C_BodyStateContains(other,BS_RUN)) && (!C_BodyStateContains(other,BS_JUMP))) && (Npc_GetStateTime(self) > 0)
* *{
* * * *// сброс времени текущего состояния
* * * *Npc_SetStateTime(self,0);
* * * *// сброс счетчика времени нахождения в состоянии
* * * *self.aivar[AIV_StateTime] = 0;
* *};
* *// если дистанция атаки > 0
* *if(self.aivar[AIV_MaxDistToWp] > 0)
* *{
* * * *// если расстояние между НПС и вайпоинтом НПС > дистанции атаки и расстояние между целью и вайпоинтом НПС > дистанции акаки
* * * *if(Npc_GetDistToWP(self,self.wp) > self.aivar[AIV_MaxDistToWp]) && (Npc_GetDistToWP(other,self.wp) > self.aivar[AIV_MaxDistToWp])
* * * *{
* * * * * *// установить НПС тактику защитников крепостных стен
* * * * * *self.fight_tactic = FAI_NAILED;
* * * *}
* * * *else // иначе (если НПС или цель близка к вайпоинту НПС)
* * * *{
* * * * * *// установить НПС родную тактику сражения
* * * * * *self.fight_tactic = self.aivar[AIV_OriginalFightTactic];
* * * *};
* *};
* *// если агрессор маг или
* *if(C_NpcIsMonsterMage(self))
* *¦¦ (self.guild == GIL_SKELETON) * * * * * * // скелет
* *¦¦ (self.guild == GIL_SUMMONED_SKELETON) * *// или вызванный скелет
* *¦¦ (self.guild > GIL_SEPERATOR_ORC) * * * * // или орк
* *{
* * * *// создать боеприпасы
* * * *B_CreateAmmo(self);
* * * *// установить полную ману
* * * *Npc_ChangeAttribute(self,ATR_MANA,ATR_MANA_MAX);
* * * *// выбрать оружие, сответствующее цели
* * * *B_SelectWeapon(self,other);
* *};
* *// если цель существует и не обездвижена
* *if(Hlp_IsValidNpc(other)) && (!C_NpcIsDown(other))
* *{
* * * *// если цель не в состоянии разговора
* * * *if(other.aivar[AIV_INVINCIBLE] == FALSE)
* * * *{
* * * * * *// НПС атакует цель (Примечание: функция AI_Attack работает только когда очередь AI состояний НПС пуста)
* * * * * *AI_Attack(self);
* * * *}
* * * *else
* * * *{
* * * * * *// очистка очереди AI состояний НПС
* * * * * *Npc_ClearAIQueue(self);
* * * *};
* * * *// запись НПС id последней цели
* * * *self.aivar[AIV_LASTTARGET] = Hlp_GetInstanceID(other);
* * * *return LOOP_CONTINUE;
* *}
* *else // иначе (если цель отсутствует или обездвижена)
* *{
* * * *// если приоритет агрессора на пожирание падали и агрессор может есть цель
* * * *if(self.aivar[AIV_MM_PRIORITY] == PRIO_EAT) && (C_WantToEat(self,other))
* * * *{
* * * * * *// очистка очереди AI состояний НПС
* * * * * *Npc_ClearAIQueue(self);
* * * * * *// НПС встает
* * * * * *AI_StandUp(self);
* * * * * *return LOOP_END;
* * * *};
* * * *// разрешение воспринимать все объекты в зоне действия восприятий
* * * *Npc_PerceiveAll(self);
* * * *// поиск новой цели
* * * *Npc_GetNextTarget(self);
* * * *// если цель найдена и она не обездвижена
* * * *if(Hlp_IsValidNpc(other)) && (!C_NpcIsDown(other))
* * * *// и (расстояние между НПС и целью < дистанции действия восприятий или цель ГГ)
* * * *&& ((Npc_GetDistToNpc(self,other) < PERC_DIST_INTERMEDIAT) ¦¦ (Npc_IsPlayer(other)))
* * * *// и цель не в состоянии разговора
* * * *&& (other.aivar[AIV_INVINCIBLE] == FALSE)
* * * *{
* * * * * *// запись НПС id последней цели
* * * * * *self.aivar[AIV_LASTTARGET] = Hlp_GetInstanceID(other);
* * * * * *return LOOP_CONTINUE;
* * * *}
* * * *else // иначе
* * * *{
* * * * * *// очистка очереди AI состояний НПС
* * * * * *Npc_ClearAIQueue(self);
* * * * * *// НПС встает
* * * * * *AI_StandUp(self);
* * * * * *return LOOP_END;
* * * *};
* *};
};

// Завершение состояния атаки
func void ZS_MM_Attack_End()
{
* *// установить other на последнюю цель
* *other = Hlp_GetNpc(self.aivar[AIV_LASTTARGET]);
* *// если агрессор маг или
* *if(C_NpcIsMonsterMage(self))
* *¦¦ (self.guild == GIL_SKELETON) * * * * * * // скелет
* *¦¦ (self.guild == GIL_SUMMONED_SKELETON) * *// или вызванный скелет
* *¦¦ (self.guild > GIL_SEPERATOR_ORC) * * * * // или орк
* *{
* * * *// НПС убирает оружие
* * * *AI_RemoveWeapon(self);
* *};
* *// если цель убита и агрессор может пожирать цель
* *if(Npc_IsDead(other)) && (C_WantToEat(self,other)) * * * * * * * * *
* *{
* * * *// очистка очереди AI состояний НПС
* * * *Npc_ClearAIQueue(self);
* * * *// переход в состояние пожирания добычи
* * * *AI_StartState(self,ZS_MM_EatBody,0,"");
* * * *return;
* *};
};

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