|
|
24.01.2005, 11:51
|
#81
|
|
Re: Уроки скриптологии
Продолжение...
// *************************** // AIVAR - Константы для монстров // ***************************
const int AIV_MM_ThreatenBeforeAttack * * * = 26; * //Монстр угрожает перед атакой const int AIV_MM_FollowTime * * * * * * * * = 27; * //Время преследования монстром в сек. const int * * * FOLLOWTIME_SHORT * * * *= 5; * * * *//Короткое преследование const int * * * FOLLOWTIME_MEDIUM * * * = 10; * * * //Среднее преследование const int * * * FOLLOWTIME_LONG * * * * = 20; * * * //Длительное преследование const int AIV_MM_FollowInWater * * * * * * *= 28; * //Полезет ли монстр за НПС в воду? (относится и к людям) // ---------------------------------------------- const int AIV_MM_PRIORITY * * * * * * * * * = 29; * //Приоритет поведения монстра const int * PRIO_EAT * * * * * * * * * *= 0; * * * *//Пожирание падали const int * PRIO_ATTACK * * * * * * * * = 1; * * * *//Нападение на жертву // ---------------------------------------------- const int AIV_MM_SleepStart * * * * * * * * = 30; * //Время отхода монстра ко сну (час) const int AIV_MM_SleepEnd * * * * * * * * * = 31; * //Время пробуждения const int AIV_MM_RestStart * * * * * * * * *= 32; * //Время начала отдыха const int AIV_MM_RestEnd * * * * * * * * * *= 33; * //Время окончания отдыха const int AIV_MM_RoamStart * * * * * * * * *= 34; * //Время начала брожения const int AIV_MM_RoamEnd * * * * * * * * * *= 35; * //Время окончания брожения const int AIV_MM_EatGroundStart * * * * * * = 36; * //Время начала кормежки const int AIV_MM_EatGroundEnd * * * * * * * = 37; * //Время окончания кормежки const int AIV_MM_WuselStart * * * * * * * * = 38; * //Время начала активности const int AIV_MM_WuselEnd * * * * * * * * * = 39; * //Время окончания активности const int AIV_MM_OrcSitStart * * * * * * * *= 40; * //Время, когда орк садится const int AIV_MM_OrcSitEnd * * * * * * * * *= 41; * //Время, когда орк встает const int * OnlyRoutine * * * * * * * * = -1; * * * //Время контролируется программой поведения монстра // ---------------------------------------------- const int AIV_MM_ShrinkState * * * * * * * *= 42; * //Состояние уменьшения монстра (коэффициент сжатия) // ---------------------------------------------- const int AIV_MM_REAL_ID * * * * * * * * * *= 43; * //Идентификатор монстра const int * ID_MEATBUG * * * * * * * * *= 1; * * * *//Мясной жук const int * ID_SHEEP * * * * * * * * * *= 2; * * * *//Овца const int * ID_GOBBO_GREEN * * * * * * *= 3; * * * *//Гоблин const int * ID_GOBBO_BLACK * * * * * * *= 4; * * * *//Черный гоблин const int * ID_GOBBO_SKELETON * * * * * = 5; * * * *//Скелет гоблина const int * ID_SUMMONED_GOBBO_SKELETON *= 6; * * * *//Вызванный Скелет гоблина const int * ID_SCAVENGER * * * * * * * *= 7; * * * *//Падальщик const int * ID_SCAVENGER_DEMON * * * * *= 8; * * * *//Зубастик const int * ID_GIANT_RAT * * * * * * * *= 8; * * * *//Крыса const int * ID_GIANT_BUG * * * * * * * *= 9; * * * *//Полевой жук const int * ID_BLOODFLY * * * * * * * * = 10; * * * //Кровяной шершень const int * ID_WARAN * * * * * * * * * *= 11; * * * //Ящерица const int * ID_FIREWARAN * * * * * * * *= 12; * * * //Огненная ящерица const int * ID_WOLF * * * * * * * * * * = 13; * * * //Волк const int * ID_WARG * * * * * * * * * * = 14; * * * //Варг const int * ID_SUMMONED_WOLF * * * * * *= 15; * * * //Вызванный Волк const int * ID_MINECRAWLER * * * * * * *= 16; * * * //Ползун const int * ID_MINECRAWLERWARRIOR * * * = 17; * * * //Воин ползунов const int * ID_LURKER * * * * * * * * * = 18; * * * //Шныг const int * ID_SKELETON * * * * * * * * = 19; * * * //Скелет const int * ID_SUMMONED_SKELETON * * * *= 20; * * * //Вызванный Скелет const int * ID_SKELETON_MAGE * * * * * *= 21; * * * //Маг скелетов const int * ID_ZOMBIE * * * * * * * * * = 22; * * * //Зомби const int * ID_SNAPPER * * * * * * * * *= 23; * * * //Глорх const int * ID_DRAGONSNAPPER * * * * * *= 24; * * * //Остер const int * ID_SHADOWBEAST * * * * * * *= 25; * * * //Мракорис const int * ID_SHADOWBEAST_SKELETON * * = 26; * * * //Скелет мракориса const int * ID_HARPY * * * * * * * * * *= 27; * * * //Гарпия const int * ID_STONEGOLEM * * * * * * * = 28; * * * //Каменный голем const int * ID_FIREGOLEM * * * * * * * *= 29; * * * //Огненный голем const int * ID_ICEGOLEM * * * * * * * * = 30; * * * //Ледяной голем const int * ID_SUMMONED_GOLEM * * * * * = 31; * * * //Вызванный Голем const int * ID_DEMON * * * * * * * * * *= 32; * * * //Демон const int * ID_SUMMONED_DEMON * * * * * = 33; * * * //Вызванный Демон const int * ID_DEMON_LORD * * * * * * * = 34; * * * //Лорд демонов const int * ID_TROLL * * * * * * * * * *= 35; * * * //Троль const int * ID_TROLL_BLACK * * * * * * *= 36; * * * //Черный троль const int * ID_SWAMPSHARK * * * * * * * = 37; * * * //Болотожор const int * ID_DRAGON_FIRE * * * * * * *= 38; * * * //Огненный дракон const int * ID_DRAGON_ICE * * * * * * * = 39; * * * //Ледяной дракон const int * ID_DRAGON_ROCK * * * * * * *= 40; * * * //Каменный дракон const int * ID_DRAGON_SWAMP * * * * * * = 41; * * * //Болотный дракон const int * ID_DRAGON_UNDEAD * * * * * *= 42; * * * //Дракон нежить const int * ID_MOLERAT * * * * * * * * *= 43; * * * //Кротокрыс const int * ID_ORCWARRIOR * * * * * * * = 44; * * * //Воин орков const int * ID_ORCSHAMAN * * * * * * * *= 45; * * * //Шаман орков const int * ID_ORCELITE * * * * * * * * = 46; * * * //Элитный воин орков const int * ID_UNDEADORCWARRIOR * * * * = 47; * * * //Орк нежить const int * ID_DRACONIAN * * * * * * * *= 48; * * * //Ящер const int * ID_WISP * * * * * * * * * * = 49; * * * //Огонек
//----- Addon ------
const int * ID_Alligator * * * * * * * *= 50; * * * //Аллигатор const int * ID_Swampgolem * * * * * * * = 51; * * * //Болотный голем const int * ID_Stoneguardian * * * * * *= 52; * * * //Каменный сторож const int * ID_Gargoyle * * * * * * * * = 53; * * * //Огненный дух мракориса const int * ID_Bloodhound * * * * * * * = 54; * * * //Кровяная собака const int * ID_Icewolf * * * * * * * * *= 55; * * * //Ледяной волк const int * ID_OrcBiter * * * * * * * * = 56; * * * //Зубастик const int * ID_Razor * * * * * * * * * *= 57; * * * //Расчленитель const int * ID_Swarm * * * * * * * * * *= 58; * * * //Рой const int * ID_Swamprat * * * * * * * * = 59; * * * //Болотная крыса const int * ID_BLATTCRAWLER * * * * * * = 60; * * * //Богомол const int * ID_SummonedGuardian * * * * = 61; * * * //Вызванный Каменный страж const int * ID_SummonedZombie * * * * * = 62; * * * //Вызванный Зомби const int * ID_Keiler * * * * * * * * * = 63; * * * //Кабан const int * ID_SWAMPDRONE * * * * * * * = 64; * * * //Болотная вонючка
// ---------------------------------------------- const int AIV_LASTBODY * * * * * * * * * * *= 44; * //Ссылка на последнего сожранного монстра
// ********************** // Дальнейшие человеческие AIVARы // **********************
// ------ Сражение с Альриком ------------------- const int AIV_ArenaFight * * * * * * * * * *= 45; * //Параметры сражения const int * AF_NONE * * * * * * * * * * = 0; * * * *//Сражения не было const int * AF_RUNNING * * * * * * * * *= 1; * * * *//В процессе сражения const int * AF_AFTER * * * * * * * * * *= 2; * * * *//После сражения const int * AF_AFTER_PLUS_DAMAGE * * * *= 3; * * * *//ГГ нечестно выиграл сражение
// ------ Криминал ------------------------------ const int AIV_CrimeAbsolutionLevel * * * * *= 46; * //Абсолютный уровень криминальной репутации ГГ
// ------ Атака --------------------------------- const int AIV_LastPlayerAR * * * * * * * * *= 47; * //Причина последнего нападения ГГ
// ------ Без сознания -------------------------- const int AIV_DuelLost * * * * * * * * * * *= 48; * //TRUE, если НПС из ополчения был побит ГГ
// ------ Торговля ------------------------------ const int AIV_ChapterInv * * * * * * * * * *= 49; * //Отвечает за обновление товаров у торговцев в начале главы
// ------ Стая монстров ------------------------- const int AIV_MM_Packhunter * * * * * * * * = 50; * //TRUE, если монстры одного вида охотятся и атакуют стаей
// ------ Магия --------------------------------- const int AIV_MagicUser * * * * * * * * * * = 51; * //Использует ли НПС магию const int * MAGIC_NEVER * * * * * * * * = 0; * * * *//Не использует const int * MAGIC_ALWAYS * * * * * * * *= 1; * * * *//Всегда использует
// ------ Послушники ---------------------------- const int AIV_DropDeadAndKill * * * * * * * = 52; * //TRUE, если этого НПС разрешено убить
// ------ Магия заморозки ----------------------- const int AIV_FreezeStateTime * * * * * * * = 53; * //Время начала действия заклинаний заморозки
// ------ Игнорирование криминала --------------- const int AIV_IGNORE_Murder * * * * * * * * = 54; * //Игнорирование убийства const int AIV_IGNORE_Theft * * * * * * * * *= 55; * //Игнорирование воровства const int AIV_IGNORE_Sheepkiller * * * * * *= 56; * //Игнорирование убийства овцы
// ------ Крутой парень ------------------------- const int AIV_ToughGuy * * * * * * * * * * *= 57; * //TRUE, если НПС является крутым парнем
// ------ Отвергнутые новости ------------------- const int AIV_NewsOverride * * * * * * * * *= 58; * //TRUE, если НПС не знает никаких новостей
// ------ Атака монстров ------------------------ const int AIV_MaxDistToWp * * * * * * * * * = 59; * //Макс. дистанция, на которой монстр начинает атаковать const int AIV_OriginalFightTactic * * * * * = 60; * //Тактика нападения монстра
// ------ Оценка врага -------------------------- const int AIV_EnemyOverride * * * * * * * * = 61; * //TRUE, если врагов у НПС нет
// ------ Вызванные монстры --------------------- const int AIV_SummonTime * * * * * * * * * *= 62; * //Время от начала вызова монстра
// ------ Атака --------------------------------- const int AIV_FightDistCancel * * * * * * * = 63; * //Дистанция, на которой прекращается сражение const int AIV_LastFightComment * * * * * * *= 64; * //TRUE, если НПС комментировал последнее сражение
// ---------------------------------------------- const int AIV_LOADGAME * * * * * * * * * * *= 65; * //TRUE, если была загрузка игры (other не инициализирован)
// ------ Без сознания -------------------------- const int AIV_DefeatedByPlayer * * * * * * *= 66; * //TRUE, если НПС побежден ГГ
// ------ Смерть -------------------------------- const int AIV_KilledByPlayer * * * * * * * *= 67; * //TRUE, если НПС убит ГГ
// ------ Различные функции --------------------- const int AIV_StateTime * * * * * * * * * * = 68; * //Время нахождения НПС в конкретном состоянии
// ---------------------------------------------- const int AIV_Dist * * * * * * * * * * * * *= 69; * //Дистанция между НПС const int AIV_IgnoresFakeGuild * * * * * * *= 70; * //TRUE, если НПС игнорирует поддельную гильдию const int AIV_NoFightParker * * * * * * * * = 71; * //TRUE, если НПС не может атаковать const int AIV_NPCIsRanger * * * * * * * * * = 72; * //TRUE, если НПС принадлежит к "Кольцу Воды" const int AIV_IgnoresArmor * * * * * * * * *= 73; * //НПС не носит броню const int AIV_StoryBandit * * * * * * * * * = 74; * //Бандиты, с которыми можно сражаться const int AIV_StoryBandit_Esteban * * * * * = 75; * //Эстебан
// ------ Смерч --------------------------------- const int AIV_WhirlwindStateTime * * * * * *= 76; * //Время начала запуска смерча
// ------ Вздутие ------------------------------- const int AIV_InflateStateTime * * * * * * *= 77; * //Время начала запуска вздутия
// ------ Рой ----------------------------------- const int AIV_SwarmStateTime * * * * * * * *= 78; * //Время начала запуска роя
// ------ Опустошение --------------------------- const int AIV_SuckEnergyStateTime * * * * * = 79; * //Время начала запуска опустошения
// ------ Пираты -------------------------------- const int AIV_FollowDist * * * * * * * * * *= 80; * //Дистанция следования НПС друг за другом
// ------ Реальные атрибуты НПС ----------------- const int REAL_STRENGTH * * * * * * * * * * = 81; * //Сила const int REAL_DEXTERITY * * * * * * * * * *= 82; * //Ловкость const int REAL_MANA_MAX * * * * * * * * * * = 83; * //Мана const int REAL_TALENT_1H * * * * * * * * * *= 84; * //Владение одноручником const int REAL_TALENT_2H * * * * * * * * * *= 85; * //Владение двуручником const int REAL_TALENT_BOW * * * * * * * * * = 86; * //Владение луком const int REAL_TALENT_CROSSBOW * * * * * * *= 87; * //Владение арбалетом
const int AIV_SpellLevel * * * * * * * * * *= 88; * //Круг магии
|
|
|
26.01.2005, 10:39
|
#83
|
|
Re: Уроки скриптологии
2. Состояния тела НПС, фокусы камеры и параметры гильдий.
Все состояния тела НПС описаны в файле ..\AI_Intern\BodyStates.d, правда многие из них в игре не используются.
// ************************************************* // Состояния тела // *************************************************
// Флаги прерываний const int BS_FLAG_INTERRUPTABLE * * = * 32768; *//Состояние прерываемо const int BS_FLAG_FREEHANDS * * * * = * 65536; *//Свободные руки
// ****************************************** // Флаги состояние тела // ****************************************** const int BS_STAND * * * * * * * * *= * 0 | BS_FLAG_INTERRUPTABLE | BS_FLAG_FREEHANDS; *//Стоит const int BS_WALK * * * * * * * * * = * 1 | BS_FLAG_INTERRUPTABLE; * * *//Идет const int BS_SNEAK * * * * * * * * *= * 2 | BS_FLAG_INTERRUPTABLE; * * *//Подкрадывается const int BS_RUN * * * * * * * * * *= * 3; * * * * * * * * * * * * * * *//Бежит const int BS_SPRINT * * * * * * * * = * 4; * * * * * * * * * * * * * * *//Быстро бежит const int BS_SWIM * * * * * * * * * = * 5; * * * * * * * * * * * * * * *//Плывет const int BS_CRAWL * * * * * * * * *= * 6; * * * * * * * * * * * * * * *//Ползет const int BS_DIVE * * * * * * * * * = * 7; * * * * * * * * * * * * * * *//Ныряет const int BS_JUMP * * * * * * * * * = * 8; * * * * * * * * * * * * * * *//Прыгает const int BS_CLIMB * * * * * * * * *= * 9 | BS_FLAG_INTERRUPTABLE; * * *//Взбирается const int BS_FALL * * * * * * * * * = * 10; * * * * * * * * * * * * * * //Падает const int BS_SIT * * * * * * * * * *= * 11 | BS_FLAG_FREEHANDS; * * * * //Сидит const int BS_LIE * * * * * * * * * *= * 12; * * * * * * * * * * * * * * //Лежит const int BS_INVENTORY * * * * * * *= * 13; * * * * * * * * * * * * * * //Открывает инвентарь const int BS_ITEMINTERACT * * * * * = * 14 | BS_FLAG_INTERRUPTABLE; * * //Действие с предметом const int BS_MOBINTERACT * * * * * *= * 15; * * * * * * * * * * * * * * //Действие с MOBом const int BS_MOBINTERACT_INTERRUPT *= * 16 | BS_FLAG_INTERRUPTABLE; * * //Прерываемое действие с MOBом
const int BS_TAKEITEM * * * * * * * = * 17; * * * * * * * * * * * * * * //Берет предмет const int BS_DROPITEM * * * * * * * = * 18; * * * * * * * * * * * * * * //Выкидывает предмет const int BS_THROWITEM * * * * * * *= * 19; * * * * * * * * * * * * * * //Бросает предмет const int BS_PICKPOCKET * * * * * * = * 20 | BS_FLAG_INTERRUPTABLE; * * //Карманная кража
const int BS_STUMBLE * * * * * * * *= * 21; * * * * * * * * * * * * * * //(не используется) const int BS_UNCONSCIOUS * * * * * *= * 22; * * * * * * * * * * * * * * //Без сознания const int BS_DEAD * * * * * * * * * = * 23; * * * * * * * * * * * * * * //Мертвый
const int BS_AIMNEAR * * * * * * * *= * 24; * * * * * * * * * * * * * * //Близкая цель const int BS_AIMFAR * * * * * * * * = * 25; * * * * * * * * * * * * * * //Далекая цель const int BS_HIT * * * * * * * * * *= * 26 | BS_FLAG_INTERRUPTABLE; * * //Удар const int BS_PARADE * * * * * * * * = * 27; * * * * * * * * * * * * * * //(не используется)
// Магия const int BS_CASTING * * * * * * * *= * 28; * * * * * * * * * * * * * * //Кастует const int BS_PETRIFIED * * * * * * *= * 29; * * * * * * * * * * * * * * //Ошеломленный const int BS_CONTROLLING * * * * * *= * 30 | BS_FLAG_INTERRUPTABLE; * * //Управляемый
const int BS_MAX * * * * * * * * * *= * 31; * * * * * * * * * * * * * * //Макс. кол-во состояний тела
// Модификаторы состояний const int BS_MOD_HIDDEN * * * * * * = * 128; * * * * * * * * * * * * * *//Скрытый const int BS_MOD_DRUNK * * * * * * *= * 256; * * * * * * * * * * * * * *//Пьяный const int BS_MOD_NUTS * * * * * * * = * 512; * * * * * * * * * * * * * *//??? const int BS_MOD_BURNING * * * * * *= * 1024; * * * * * * * * * * * * * //Горящий const int BS_MOD_CONTROLLED * * * * = * 2048; * * * * * * * * * * * * * //Управляемый const int BS_MOD_TRANSFORMED * * * *= * 4096; * * * * * * * * * * * * * //Трансформируемый
// имена MOBов const string MOB_SIT * * * * * * * *= * "BENCH,CHAIR,GROUND,THRONE"; const string MOB_LIE * * * * * * * *= * "BED,BEDHIGH,BEDLOW"; const string MOB_CLIMB * * * * * * *= * "CLIMB,LADDER,RANKE"; const string MOB_NOTINTERRUPTABLE * = * "DOOR,LEVER,TOUCHPLATE,TURNSWITCH,VWHEEL,CHESTBIG, CHESTSMALL,HERB,IDOL,PAN, SMOKE,INNOS"; // Все другие MOBы, здесь не приведенные, являются прерываемыми, это: // BOOK,BSANVIL,BSCOOL,BSFIRE,BSSHARP,CAULDRON,DRUM,G RAVE,LAB,ORE,REPAIR,RMAKER,BAU MSAEGE,STOVE,SDW(Stein des Wissens)
В файле ..\AI_Intern\Focus.d описываются фокусы камеры (производные INSTANCE от класса C_Focus) для следующих ситуаций: Focus_Normal - обычный фокус камеры Focus_Melee - фокус камеры при сражении оружием ближнег радиуса поражения Focus_Ranged - фокус камеры при сражении оружием дальнего радиуса поражения Focus_Throw_Item - фокус камеры при броске (метании) предмета Focus_Throw_Mob - фокус камеры при броске (метании) МОВа Focus_Magic - фокус камеры при кастовании заклинания
В файле ..\AI_Intern\Species.d описывается значение параметров всех гильдий (производная INSTANCE Gil_Values от класса C_GILVALUES)
С этими двумя файлами разберетесь сами (кому нужно)!
************************************************** ********* Сделаем небольшой перерывчик. Попрошу критически отозваться о предоставляемом метериале (что не устраивает, стиль изложения, краткость, что хотелось бы). Короче, жду критики! ************************************************** *********
|
|
|
28.01.2005, 12:57
|
#84
|
|
Re: Уроки скриптологии
Замечаний и предложений нет - можно сделать два вывода; либо народ не посещает уроки (что маловероятно), либо всех все устраивает (что более вероятно). Это так информация к размышлению. Продолжим...
3. Вывод отладочной информации.
Функции, ответственные за вывод отладочной информации, находятся в файле ..\AI_Intern\PrintDebug.d К сожалению, все эти функции выводят информацию в окно zSpy с идентификатором определенного канала. На мой взгляд их применение очень проблематично и пользы от него мало. В скриптах по понятной причине вызов этих функций отсутствует, поэтому мы их рассматривать не будем. В файле ..\AI_Intern\PrintPlus.d приведена функция вывода на экран строки текста со случайным числом в диапазоне от 0 до 100 в следующем формате: <text> <random value 0-100>. Хоть эта функция и вызывается из одного файла, смысла ее применения я не вижу. Эти файлы можно вообще исключить из компиляции.
Есть еще один файл ..\AI_Intern\NPC_SetToMad.d, правда он к отладке отношения не имеет, но заслуживает удаления по причине его бесполезности.
P.S. В скриптах очень много неиспользуемой и ненужной информации, для убыстрения работы игры и минимизации памяти все неиспользуемые функции и переменные можно удалить. ВНИМАНИЕ!!! Нельзя удалять неиспользуемые поля в классах, а также их добавлять, это потребует переделки экзешника!
|
|
|
28.01.2005, 15:44
|
#85
|
|
Re: Уроки скриптологии
2Mitrich:
Опа, кажется приехали... Т.е. написать свой класс НПС не получится?
|
Имеются в виду только типы данных - класс (СLASS), есть еще другие производные типы от типа класс (PROTOTYPE и INSTANCE), с ними можно делать что угодно, можно создавать новые, можно удалять ненужные, можно менять значения но только в пределах тех полей, которые заданы базовым классом. Базовые классы, их всего несколько C_Npc, C_Item, C_Focus, C_Info, C_Spell, C_SVM и C_GilValues (это все используемые классы), нельзя ни дополнить, ни удалить из них неиспользуемые поля, нельзя создать новый класс, нельзя удалить весь класс. CLASS создан в экзешнике и перенесен в скрипты, а PROTOTYPE и INSTANCE реализованы только в скриптах! *;)
|
|
|
28.01.2005, 16:59
|
#86
|
|
Re: Уроки скриптологии
2Vam:
CLASS создан в экзешнике и перенесен в скрипты, а PROTOTYPE и INSTANCE реализованы только в скриптах!
|
Спасибо за разъяснение - так действительно понятнее. не мог бы ты поподробнее раскрыть возможности работы с PROTOTYPE и INSTANCE, т.к. вначале ты описывал их только как
Тема первая: Типы переменных. В скриптах используется всего несколько типов переменных: VOID - "пустой" тип INT - целое число FLOAT - число с плавающей точкой STRING - строка текста CLASS - структура с внутренними типами и функциями PROTOTYPE - обычно инициализация класса, но возможно и другое использование INSTANCE - пока сказать нечего.
|
Можно даже на теории+примере - так всегда достурнее.
|
|
|
28.01.2005, 18:07
|
#87
|
|
Re: Уроки скриптологии
2Mitrich:
не мог бы ты поподробнее раскрыть возможности работы с PROTOTYPE и INSTANCE
|
CLASS имеет жесткий набор переменных, в нем ничего нельзя изменить. Последовательность полей и их размер задаются в экзешнике. При загрузке экзешником класса из дат файла производится проверка его размера, и если он не совпадает с заданным в экзешнике, получаем ошибку, "дат файл негодный, выполните компиляцию по-новому", и программа прекращает свою работу, можешь проверить! PROTOTYPE является производной от класса и инициализирует переменные класса конкретными значениями. Могут быть инициализированы или все переменные или только их часть. Прототипов от класса можно сделать сколь угодно много с разной инициализацией. Например, один прототип от класса C_NPC может описывать общие параметры всех монстров, а другой прототип общие параметры всех людей и т.д. INSTANCE является производной от класса или от прототипа, помимо инициализации переменных класса она выполняет и другие функции. Внутри инстанции могут вызываться многие специальные функции, первым параметром которых является ссылка на на саму инстанцию (self). Эти функции работают с переменными конкретно этой инстанции и никакой другой, если это явно не указано. Инстанций может быть реализовано очень много, например, каждый конкретный НПС и т.д. Если инстанция произведена от прототипа, то в ней нет надобности производить инициализацию тех переменных, которые были инициализированы в прототипе (если, конечно, нет на то необходимости). Если кто знает С++, то в реализации классов и их производных в скриптах нет ничего сложного, но по сравнению с С++ немного запутано. В С++ всей этой классовой иерархии скриптов соответствует простой класс с объявленными для него функциями. Надеюсь большинству понятны мои высказывания. *:)
|
|
|
29.01.2005, 11:06
|
#88
|
|
Re: Уроки скриптологии
4. Инициализация восприятий.
Функции инициализации восприятий описаны в файле ..\AI_Intern\Perception.d
// ************************************************** // Устанавливается дальность действия восприятий НПС // **************************************************
FUNC VOID InitPerceptions() { * *// Дальность действия всех активных восприятий определена константой PERC_DIST_ACTIVE_MAX, которая записывается в поле senses_range производной от класса C_Npc. * *// PERC_ASSESSPLAYER - восприятие ГГ другими НПС * *// PERC_ASSESSENEMY - восприятие одного НПС другим НПС, у которого установлен флаг ATT_HOSTILE (враг), если Temp_Att != GilAtt, то возмется Temp_Att. * *// PERC_ASSESSBODY - восприятие НПС мертвого тела, в настоящее время используется только в Monster-AI функциях. * *// PERC_ASSESSFIGHTER - восприятие НПС ГГ с поднятым оружием или восприятие НПС всех монстров (они всегда находятся в режиме Fightmode) * *// PERC_ASSESSITEM - восприятие НПС предметов
* *// *** ВНИМАНИЕ *** Активное восприятие работает только в случае, если у НПС активированы одно или несколько чувств. Зона действия активных восприятий 180° перед НПС по радиусу PERC_DIST_ACTIVE_MAX.
* *// *** ВНИМАНИЕ *** Зона действия пассивных восприятий 360° вокруг НПС на заданное расстояние.
* *// Сражение * *Perc_SetRange(PERC_ASSESSDAMAGE,9999); * * * * * * * * * * *//Посылается НПС, получившему повреждение. Дальность действия не используется. * *Perc_SetRange(PERC_ASSESSOTHERSDAMAGE,PERC_DIST_I NTERMEDIAT); * //Посылается всем другим (other) НПС, если НПС получил повреждение * *Perc_SetRange(PERC_ASSESSDEFEAT,WATCHFIGHT_DIST_M AX); * * * //Посылается всем другим НПС, если НПС находится в бессознательном состоянии * *Perc_SetRange(PERC_ASSESSMURDER,PERC_DIST_ACTIVE_ MAX); * * *//Посылается всем другим НПС, если НПС умер * *Perc_SetRange(PERC_ASSESSTHREAT,PERC_DIST_INTERME DIAT); * * //Посылается НПС в течении 2 секунд, если в него целится ГГ * *Perc_SetRange(PERC_DRAWWEAPON,PERC_DIST_DIALOG); * * * * * *//Посылается всем другим НПС, если ГГ достает оружие
* *// Слух * *Perc_SetRange(PERC_ASSESSFIGHTSOUND,3000); * * * * * * * * *//Посылается всем другим НПС, если НПС на кого-то нападает с оружием * *Perc_SetRange(PERC_ASSESSQUIETSOUND,PERC_DIST_INT ERMEDIAT); //Посылается раз в секунду всем другим НПС, если ГГ идет или бежит, а так же, когда выброшен (уронен) какой либо предмет
* *// Воровство * *Perc_SetRange(PERC_ASSESSTHEFT,PERC_DIST_INTERMED IAT); * * *//Посылается всем другим НПС, если ГГ украл какой-либо предмет. При карманной краже обворованному не посылается. При телекинезе посылается всем. * *Perc_SetRange(PERC_ASSESSUSEMOB,PERC_DIST_INTERME DIAT); * * //Посылается всем другим НПС, если ГГ использует MOBsi * *Perc_SetRange(PERC_ASSESSENTERROOM,PERC_DIST_INTE RMEDIAT); *//Посылается всем другим НПС, если ГГ входит в помещение
* *// Магия * *Perc_SetRange(PERC_ASSESSMAGIC,9999); * * * * * * * * * * * //Посылается НПС, против которого применена магия * *Perc_SetRange(PERC_ASSESSSTOPMAGIC,9999); * * * * * * * * * //Посылается НПС (жертве), если магия прекращает свое действие
* *// Разговор * *Perc_SetRange(PERC_ASSESSTALK,PERC_DIST_DIALOG); * * * * * *//Посылается НПС, если у ГГ есть важная информация для разговора
* *// Взаимодействие НПС * *Perc_SetRange(PERC_ASSESSWARN,PERC_DIST_INTERMEDI AT); * * * //Чисто скриптовое восприятие, кому посылаем, тот и реагирует
* *// Открытие дверей * *Perc_SetRange(PERC_MOVEMOB,PERC_DIST_DIALOG); * * * * * * * //Посылается всем другим НПС, если ГГ открывает дверь (сундук)
* *// Превращение * *Perc_SetRange(PERC_ASSESSSURPRISE,FIGHT_DIST_CANC EL); * * * //Посылается всем другим НПС, если ГГ превращается в себя из животного
* *// Не используются! * *Perc_SetRange(PERC_OBSERVEINTRUDER,100); * * * * * * * * * *//Посылается всем другим НПС, если ГГ останавливается (кроме режима подкрадывания) * *Perc_SetRange(PERC_ASSESSREMOVEWEAPON,100); * * * * * * * * //Посылается всем другим НПС, если ГГ прячет оружие * *Perc_SetRange(PERC_CATCHTHIEF,100); * * * * * * * * * * * * //Посылается всем другим НПС, если ГГ пойман на карманной краже * *Perc_SetRange(PERC_ASSESSCALL,100); * * * * * * * * * * * * //Посылается НПС, если ГГ призывает его к разговору (дальняя дистанция) * *Perc_SetRange(PERC_MOVENPC,100); * * * * * * * * * * * * * *//Посылается всем другим НПС, если ГГ идет вместе с НПС * *Perc_SetRange(PERC_ASSESSCASTER,100); * * * * * * * * * * * //Посылается всем другим НПС, если ГГ инвестирует ману * *Perc_SetRange(PERC_NPCCOMMAND,100); * * * * * * * * * * * * //Чисто скриптовое восприятие, можно использовать по своему усмотрению * *Perc_SetRange(PERC_OBSERVESUSPECT,100); * * * * * * * * * * //Посылается всем другим НПС, если ГГ подкрадывается (в движении)
* *//Мной не обнаружены упоминания о следующих восприятиях: PERC_ASSESSGIVENITEM, PERC_ASSESSFAKEGUILD };
// ************************************************** *********** // Установка функций реакций НПС на нормальный набор восприятий для людей // ************************************************** ***********
func void Perception_Set_Normal() { * *// Активные чувства при каждом состоянии активизируются по-новому, т.к. они изменяются в функции ZS_Guide_Player * *self.senses * * * * = * SENSE_HEAR ¦ SENSE_SEE; * *self.senses_range * = * PERC_DIST_ACTIVE_MAX;
* *// Частота проверки активных восприятий * *if(Npc_KnowsInfo(self,1) ¦¦ C_NpcIsGateGuard(self)) * * //НПС имеет важную информацию или НПС охраняет вход * *{ * * * *Npc_SetPercTime(self,0.3); * * * * * * * * * * * * *//восприятия проверяются раз в 0.3 секунды * *} * *else * *{ * * * *Npc_SetPercTime(self,1); * * * * * * * * * * * * * *//восприятия проверяются раз в секунду * *};
* *// Активные восприятия (приоритет наивысший) * *Npc_PercEnable(self,PERC_ASSESSPLAYER, * * *B_AssessPlayer); * *Npc_PercEnable(self,PERC_ASSESSENEMY, * * * B_AssessEnemy);
* *// Пассивные восприятия (приоритет задается последовательностью регистрации) * *Npc_PercEnable(self,PERC_ASSESSMAGIC, * * * B_AssessMagic); * *Npc_PercEnable(self,PERC_ASSESSDAMAGE, * * *B_AssessDamage); * *Npc_PercEnable(self,PERC_ASSESSMURDER, * * *B_AssessMurder); * *Npc_PercEnable(self,PERC_ASSESSTHEFT, * * * B_AssessTheft); * *Npc_PercEnable(self,PERC_ASSESSUSEMOB, * * *B_AssessUseMob); * *Npc_PercEnable(self,PERC_ASSESSENTERROOM, * B_AssessPortalCollision); * *Npc_PercEnable(self,PERC_ASSESSTHREAT, * * *B_AssessThreat); * *Npc_PercEnable(self,PERC_DRAWWEAPON, * * * *B_AssessDrawWeapon); * *Npc_PercEnable(self,PERC_ASSESSFIGHTSOUND, *B_AssessFightSound); * *Npc_PercEnable(self,PERC_ASSESSQUIETSOUND, *B_AssessQuietSound); * *Npc_PercEnable(self,PERC_ASSESSWARN, * * * *B_AssessWarn); * *Npc_PercEnable(self,PERC_ASSESSTALK, * * * *B_AssessTalk); * *Npc_PercEnable(self,PERC_MOVEMOB, * * * * * B_MoveMob); };
// ************************************************** ****************** // Установка функций реакций НПС на минимальный набор восприятий для людей (всегда должны быть активны) // ************************************************** ******************
func void Perception_Set_Minimal() { * *self.senses * * * * = * SENSE_HEAR ¦ SENSE_SEE; * *self.senses_range * = * PERC_DIST_ACTIVE_MAX;
* *Npc_PercEnable(self,PERC_ASSESSMAGIC, * * * B_AssessMagic); * *Npc_PercEnable(self,PERC_ASSESSDAMAGE, * * *B_AssessDamage); * *Npc_PercEnable(self,PERC_ASSESSMURDER, * * *B_AssessMurder); * *Npc_PercEnable(self,PERC_ASSESSTHEFT, * * * B_AssessTheft); * *Npc_PercEnable(self,PERC_ASSESSUSEMOB, * * *B_AssessUseMob); * *Npc_PercEnable(self,PERC_ASSESSENTERROOM, * B_AssessPortalCollision); };
// ************************************************** ********** // Закрытие реакций НПС slf на восприятия для людей и монстров // ************************************************** **********
func void B_ClearPerceptions(var C_NPC slf) { * *Npc_PercDisable(slf,PERC_ASSESSPLAYER); * *Npc_PercDisable(slf,PERC_ASSESSENEMY);
* *Npc_PercDisable(slf,PERC_ASSESSBODY);
* *Npc_PercDisable(slf,PERC_ASSESSMAGIC); * *Npc_PercDisable(slf,PERC_ASSESSDAMAGE); * *Npc_PercDisable(slf,PERC_ASSESSMURDER); * *Npc_PercDisable(slf,PERC_ASSESSTHEFT); * *Npc_PercDisable(slf,PERC_ASSESSUSEMOB); * *Npc_PercDisable(slf,PERC_ASSESSENTERROOM); * *Npc_PercDisable(slf,PERC_ASSESSTHREAT); * *Npc_PercDisable(slf,PERC_DRAWWEAPON); * *Npc_PercDisable(slf,PERC_ASSESSFIGHTSOUND); * *Npc_PercDisable(slf,PERC_ASSESSQUIETSOUND); * *Npc_PercDisable(slf,PERC_ASSESSWARN); * *Npc_PercDisable(slf,PERC_ASSESSTALK); * *Npc_PercDisable(slf,PERC_MOVEMOB);
* *Npc_PercDisable(slf,PERC_ASSESSOTHERSDAMAGE); * *Npc_PercDisable(slf,PERC_ASSESSSTOPMAGIC); * *Npc_PercDisable(slf,PERC_ASSESSSURPRISE); };
// ************************************************** ******* // Установка функций реакций монстров и орков на восприятия // ************************************************** *******
func void Perception_Set_Monster_Rtn() { * *Npc_SetPercTime(self,1); * * * * * * * *//частота проверки восприятия раз в секунду
* *Npc_PercEnable(self,PERC_ASSESSENEMY, * * * * * B_MM_AssessEnemy); * *Npc_PercEnable(self,PERC_ASSESSBODY, * * * * * *B_MM_AssessBody);
* *Npc_PercEnable(self,PERC_ASSESSMAGIC, * * * * * B_AssessMagic); * *Npc_PercEnable(self,PERC_ASSESSDAMAGE, * * * * *B_MM_AssessDamage); * *Npc_PercEnable(self,PERC_ASSESSOTHERSDAMAGE, * *B_MM_AssessOthersDamage); * *Npc_PercEnable(self,PERC_ASSESSMURDER, * * * * *B_MM_AssessOthersDamage); * *Npc_PercEnable(self,PERC_ASSESSWARN, * * * * * *B_MM_AssessWarn); };
|
|
|
31.01.2005, 13:09
|
#89
|
|
Re: Уроки скриптологии
5. Функции обработки восприятий людей.
Реакция НПС (людей) на ГГ.
// ************************************************** ***** // Функция реакции НПС (людей) на ГГ (обработка активного восприятия PERC_ASSESSPLAYER). // ГГ должен быть в поле зрения НПС (люди не имеют чувства обоняния) // Макс. дистанция реакции на ГГ - PERC_DIST_ACTIVE_MAX. // ************************************************** *****
func void B_AssessPlayer() { * *// other в функции - ГГ, self - НПС * *// Тестовый режим: Игнорирование Инспектора уровня * *var C_NPC PCL; * *PCL = Hlp_GetNpc(PC_Levelinspektor); * *// Если ГГ является Инспектором уровня * *if(Hlp_GetInstanceID(other) == Hlp_GetInstanceID(PCL)) * *{ * * * *return; * *}; * *// Если ГГ находится в режиме диалога * *if(other.aivar[AIV_INVINCIBLE] == TRUE) * *{ * * * *return; * *}; * *// Если ГГ мертв, безсознания или в магическом сне * *if(C_NpcIsDown(other)) * *{ * * * *return; * *}; * *// Если ГГ превращен в монстра * *if(other.guild > GIL_SEPERATOR_HUM) * *{ * * * *// Если НПС охранник, то он должен задержать любого монстра * * * *if(C_NpcIsGateGuard(self)) * * * *{ * * * * * *// НПС встает * * * * * *AI_StandUpQuick(self); * * * * * *// вызов функции сражения * * * * * *B_Attack(self,other,AR_MonsterCloseToGate,0); * * * * * *return; * * * *} * * * *// если гильдии ГГ и НПС враждебны * * * *else if(Wld_GetGuildAttitude(self.guild,other.guild) == ATT_HOSTILE) * * * *{ * * * * * *// если НПС не сопровождает ГГ и НПС не является другом ГГ * * * * * *if(self.aivar[AIV_PARTYMEMBER] == FALSE) && (self.npctype != NPCTYPE_FRIEND) * * * * * *{ * * * * * * * *// вызов функции сражения * * * * * * * *B_Attack(self,other,AR_GuildEnemy,0); * * * * * * * *return; * * * * * *}; * * * *}; * *}; * *// Если ГГ враг * *if(B_AssessEnemy()) * *{ * * * *return; * *}; * *// Если ГГ бандит и НПС не бандит * *if(C_PlayerIsFakeBandit(self,other) && (self.guild != GIL_BDT)) * *{ * * * *// вызов функции сражения * * * *B_Attack(self,other,AR_GuildEnemy,0); * *}; * *// Если ГГ убийца и НПС должен атаковать убийцу и расстояние между ГГ и НПС <= PERC_DIST_INTERMEDIAT * *if(B_GetPlayerCrime(self) == CRIME_MURDER) && C_WantToAttackMurder(self,other) && (Npc_GetDistToNpc(self,other) <= PERC_DIST_INTERMEDIAT) * *{ * * * *// вызов функции сражения * * * *B_Attack(self,other,AR_HumanMurderedHuman,0); * * * * *return; * *}; * *// Если ГГ вошел в помещение, ему не принадлежащее * *if(B_AssessEnterRoom()) * *{ * * * *return; * *}; * *// Если оружие ГГ обнажено * *if(B_AssessDrawWeapon()) * *{ * * * *return; * *} * *else // сброс флага комментирования обнаженного оружия * *{ * * * *Player_DrawWeaponComment = FALSE; * *}; * *// Если ГГ подкрадывается * *if(C_BodyStateContains(other,BS_SNEAK)) * *{ * * * *// если НПС не наблюдает за ГГ и НПС должен реагировать на крадущегося ГГ * * * *if(!Npc_IsInState(self,ZS_ObservePlayer) && C_WantToReactToSneaker(self,other)) * * * *{ * * * * * *// очистка AI команд НПС * * * * * *Npc_ClearAIQueue(self); * * * * * *// очистка восприятий НПС * * * * * *B_ClearPerceptions(self); * * * * * *// перевод НПС в состояние наблюдения за ГГ * * * * * *AI_StartState(self,ZS_ObservePlayer,1,""); * * * * * *return; * * * *}; * *} * *else // ГГ не подкрадывается * *{ * * * *// если ГГ не стоит * * * *if(!C_BodyStateContains(other,BS_STAND)) * * * *{ * * * * * *// сброс флага комментирования крадущегося ГГ * * * * * *Player_SneakerComment = FALSE; * * * *}; * *}; * *// Если ГГ не лежит * *if(!C_BodyStateContains(other,BS_LIE)) * *{ * * * *// сброс флага комментирования, что ГГ лег на чужую кровать * * * *Player_GetOutOfMyBedComment = FALSE; * *}; * *// Важная информация для окружающих черных магов (я так понимаю, что это ищущие) * *B_AssignDementorTalk(self); * *// *********** Диалог ************* * *// Если расстояние между ГГ и НПС <= дистанции начала разговора и НПС имеет важную информацию * *if(Npc_GetDistToNpc(self,other) <= PERC_DIST_DIALOG) && (Npc_CheckInfo(self,1)) * *{ * * * *// Если НПС охраняет ворота * * * *if(C_NpcIsGateGuard(self)) * * * *{ * * * * * *// установка флага для НПС при обращении с важной информацией к ГГ * * * * * *self.aivar[AIV_NpcStartedTalk] = TRUE; * * * * * *// функция диалога * * * * * *B_AssessTalk(); * * * * * *return; * * * *} * * * *else //для других НПС * * * *{ * * * * * *// если ГГ не падает и не плывет и не ныряет * * * * * *if(!C_BodyStateContains(other,BS_FALL)) && (!C_BodyStateContains(other,BS_SWIM)) && (!C_BodyStateContains(other,BS_DIVE)) * * * * * *// и ГГ не занимается криминалом * * * * * *&& (B_GetPlayerCrime(self) == CRIME_NONE) * * * * * *// и ГГ не отказался от разговора с НПС * * * * * *&& (C_RefuseTalk(self,other) == FALSE) * * * * * *// и ГГ не является членом подставной гильдии * * * * * *&& (C_PlayerHasFakeGuild(self,other) == FALSE) * * * * * *{ * * * * * * * *// установка флага для НПС при обращении с важной информацией к ГГ * * * * * * * *self.aivar[AIV_NpcStartedTalk] = TRUE; * * * * * * * *// функция диалога * * * * * * * *B_AssessTalk(); * * * * * * * *return; * * * * * *}; * * * *}; * *}; * * *// *********** Приветствие ************* * *// если НПС идет и расстояние между ГГ и НПС <= дистанции начала разговора * *if (C_BodyStateContains(self,BS_WALK)) && (Npc_GetDistToNpc(self,other) <= PERC_DIST_DIALOG) * *// и ГГ не отказался от диалога и НПС не охранник * *&& (Npc_RefuseTalk(other) == FALSE) && (!C_NpcIsGateGuard(self)) * *// и ГГ не является членом подставной гильдии * *&& (C_PlayerHasFakeGuild(self,other) == FALSE) * * * * * * *{ * * * * *// НПС и ГГ смотрят друг на друга * * * *B_LookAtNpc(self,other); * * * *// звучит приветственная фраза * * * *B_Say_GuildGreetings(self,other); * * * *// НПС и ГГ перестают смотреть друг на друга * * * *B_StopLookAt(self); * * * *// отказ ГГ от диалога на 20 секунд * * * *Npc_SetRefuseTalk(other,20); * *}; * *// *********** Сброс предупреждений охраной ************* * *// если НПС охранник и расстояние между ГГ и НПС > дистанции начала разговора * *if(C_NpcIsGateGuard(self)) && (Npc_GetDistToNpc(self,other) > PERC_DIST_DIALOG) * *{ * * * *// Статус предупреждений охраны = Нет предупреждений * * * *self.aivar[AIV_Guardpassage_Status] = GP_NONE; * *}; * *return; };
|
|
|
01.02.2005, 11:54
|
#90
|
|
Re: Уроки скриптологии
Реакция НПС людей на врага.
// ************************************************** ****************************** // Функция реакции НПС (людей) на врага (обработка активного восприятия PERC_ASSESSENEMY). // враг должен быть в поле зрения НПС (люди не имеют чувства обоняния) // Макс. дистанция реакции на врага - PERC_DIST_ACTIVE_MAX. // ************************************************** ****************************** // Возвращает TRUE, если реакция НПС на врага закончилась сражением // ************************************************** ******************************
func int B_AssessEnemy() { * *// other в функции - враг, self - НПС * *// Тестовый режим: Игнорирование Инспектора уровня * *var C_NPC PCL; * *PCL = Hlp_GetNpc(PC_Levelinspektor); * *// Если враг является Инспектором уровня * *if(Hlp_GetInstanceID(other) == Hlp_GetInstanceID(PCL)) * *{ * * * *return FALSE; * *}; * *// Аддон * *// Если (враг не ГГ и враг человек * *if((Hlp_GetInstanceID(other) != Hlp_GetInstanceID(hero)) && (other.guild < GIL_SEPERATOR_HUM) * *// и (НПС не может атаковать или враг не может атаковать)) * * * *&& ((self.aivar[AIV_NoFightParker] == TRUE) ¦¦ (other.aivar[AIV_NoFightParker] == TRUE))) * *// или (враг монстр и враг не может атаковать) * * * *¦¦ ((other.guild > GIL_SEPERATOR_HUM) && (other.aivar[AIV_NoFightParker] == TRUE)) * *{ * * * *return FALSE; * *}; * * *// Аддон * *// Если (враг плывет или враг ныряет) и НПС не хочет лезть в воду * *if(C_BodyStateContains(other,BS_SWIM) ¦¦ C_BodyStateContains(other,BS_DIVE)) && (self.aivar[AIV_MM_FollowInWater] == FALSE) * *{ * * * *return FALSE; * *}; * *// Если расстояние по высоте между НПС и врагом > дистанции реагирования по высоте * *if(Npc_GetHeightToNpc(self,other) > PERC_DIST_HEIGHT) * *{ * * * *return FALSE; * *}; * *// Если НПС член партии * *if(self.aivar[AIV_PARTYMEMBER] == TRUE) * *{ * * * *// если дистанция между НПС и врагом > 1.5 метра * * * *if(Npc_GetDistToNpc(self,other) > 1500) * * * *{ * * * * * *return FALSE; * * * *}; * * * *// если НПС не видит врага * * * *if(!Npc_CanSeeNpc(self, other)) * * * *{ * * * * * * *return FALSE; * * * *}; * *}; * *// Если враг является переодетым бандитом и НПС бандит * *if(C_PlayerisFakeBandit(self,other)) && (self.guild == GIL_BDT) * *{ * * * *return FALSE; * *}; * *// Магический Голем * *var C_NPC MGO; MGO = Hlp_GetNpc(MagicGolem); * *// Ларес * *var C_NPC LAR; LAR = Hlp_GetNpc(VLK_449_Lares); * *// Если НПС есть Ларес и враг есть Магический Голем * *if(Hlp_GetInstanceID(self) == Hlp_GetInstanceID(LAR)) && (Hlp_GetInstanceID(other) == Hlp_GetInstanceID(MGO)) * *{ * * * *return FALSE; * *}; * *// Если (врагов у НПС нет или врагов у врага нет) и враг человек * *if((self.aivar[AIV_EnemyOverride] == TRUE) ¦¦ (other.aivar[AIV_EnemyOverride] == TRUE)) && (other.guild < GIL_SEPERATOR_HUM) * *{ * * * *return FALSE; * *}; * *// Если отношения между НПС и врагом не вражеские * *if(Npc_GetAttitude(self,other) != ATT_HOSTILE) * *{ * * * *return FALSE; * *}; * *// Если НПС охраняет ворота * *if(C_NpcIsGateGuard(self)) * *{ * * * *return FALSE; * *}; * * * *// Если враг есть ГГ и НПС ему друг * *if(Npc_IsPlayer(other) && (self.npctype == NPCTYPE_FRIEND)) * *{ * * * *return FALSE; * *}; * *// Если гильдии НПС и врага не враждуют между собой * *if(Wld_GetGuildAttitude(self.guild,other.guild) != ATT_HOSTILE) * *{ * * * *// Если НПС враждебен к врагу [Примечание, далее врагом может быть только ГГ, т.к. прочие НПС не имеют temp_att к другим НПС] * * * *if(Npc_GetAttitude(self,other) == ATT_HOSTILE) * * * *// и (НПС находится в текущем состоянии > 2 секунд или НПС наблюдает за ГГ) * * * *&& ((Npc_GetStateTime(self) > 2) ¦¦ Npc_IsInState(self,ZS_ObservePlayer)) * * * *// и дистанция между НПС и ГГ <= дальности действия пассивного восприятия * * * *&& (Npc_GetDistToNpc(self,other) <= PERC_DIST_INTERMEDIAT) * * * *{ * * * * * *// вызов функции сражения * * * * * *B_Attack(self, other, self.aivar[AIV_LastPlayerAR], 0); * * * * * *return TRUE; * * * *} * * * *else * * * *{ * * * * * *return FALSE; * * * *}; * *}; * *// В любом другом случае вызов функции сражения * *B_Attack(self,other,AR_GuildEnemy,0); * *return TRUE; };
|
|
|
02.02.2005, 14:23
|
#91
|
|
Re: Уроки скриптологии
Реакция людей и монстров на магию.
// ************************************************** **************** // Функция реакции НПС (людей и монстров) на магию. // ************************************************** ****************
func void B_AssessMagic () { * *// self - жертва заклинания * *// Если применено заклинание нападения * *if(Npc_GetLastHitSpellCat(self) == SPELL_BAD) * *{ * * * *// всем другим НПС посылается пассивное восприятие, что на НПС self осуществлено нападение * * * *Npc_SendPassivePerc(self,PERC_ASSESSFIGHTSOUND,se lf,other); * *}; * *// Если применено заклинание "Смерч" * *if(Npc_GetLastHitSpellID(self) == SPL_Whirlwind) * *{ * * * *// очистка AI команд НПС * * * *Npc_ClearAIQueue(self); * * * *// очистка восприятий НПС * * * *B_ClearPerceptions(self); * * * *// вызов функции реакции на заклинание "Смерч" * * * *AI_StartState(self,ZS_Whirlwind,0,""); * * * *return; * *}; * *// Если применено заклинание "Украсть энергию" * *if(Npc_GetLastHitSpellID(self) == SPL_SuckEnergy) * *{ * * * *Npc_ClearAIQueue(self); * * * *B_ClearPerceptions(self); * * * *AI_StartState(self,ZS_SuckEnergy,0,""); * * * *return; * *}; * *// Если применено заклинание "Зеленые щупальца" * *if(Npc_GetLastHitSpellID(self) == SPL_Greententacle) * * * *{ * * * *Npc_ClearAIQueue(self); * * * *B_ClearPerceptions(self); * * * *AI_StartState(self,ZS_Greententacle,0,""); * * * *return; * *}; * *// Если применено заклинание "Рой" * *if(Npc_GetLastHitSpellID(self) == SPL_Swarm) * *{ * * * *Npc_ClearAIQueue(self); * * * *B_ClearPerceptions(self); * * * *AI_StartState(self,ZS_Swarm,0,""); * * * *return; * *}; * *// Если применено заклинание "Ледяная глыба" или "Ледяная волна" * *if(Npc_GetLastHitSpellID(self) == SPL_IceCube) ¦¦ (Npc_GetLastHitSpellID(self) == SPL_IceWave) * *{ * * * *Npc_ClearAIQueue(self); * * * *B_ClearPerceptions(self); * * * *AI_StartState(self,ZS_MagicFreeze,0,""); * * * *return; * *}; * *// Если применено заклинание "Шаровая молния" * *if(Npc_GetLastHitSpellID(self) == SPL_ChargeZap) * *{ * * * *Npc_ClearAIQueue(self); * * * *B_ClearPerceptions(self); * * * *AI_StartState(self,ZS_ShortZapped,0,""); * * * *return; * *}; * *// Если применено заклинание "Страх" * *if(Npc_GetLastHitSpellID(self) == SPL_Fear) * *{ * * * *Npc_ClearAIQueue(self); * * * *B_ClearPerceptions(self); * * * *Npc_SetTarget(self,other); * * * *// если НПС человек и НПС не Маг огня и НПС не Паладин * * * *if(self.guild < GIL_SEPERATOR_HUM) && (self.guild != GIL_KDF) && (self.guild != GIL_PAL) * * * *{ * * * * * *AI_StartState(self,ZS_MagicFlee,0,""); * * * * * *return; * * * *} * * * *// иначе, если НПС монстр и не дракон и не троль и не големы * * * *else if (self.guild > GIL_SEPERATOR_HUM) && (self.guild != GIL_DRAGON) && (self.guild != GIL_TROLL) * * * *&& (self.guild != GIL_STONEGOLEM) && (self.guild != GIL_ICEGOLEM) && (self.guild != GIL_FIREGOLEM) * * * *{ * * * * * *AI_StartState(self,ZS_MM_Flee,0,""); * * * * * *return; * * * *}; * *}; * *// Если применено заклинание "Огненный дождь" * *if(Npc_GetLastHitSpellID(self) == SPL_Firerain) * * * *{ * * * * *Npc_ClearAIQueue(self); * * * *AI_StartState(self,ZS_MagicBurnShort,0,""); * * * *return; * *}; };
// ************************************************** * // Объявление функции реакции на магию для ГГ // У ГГ восприятие PERC_ASSESSMAGIC всегда активно. // ************************************************** * // Функция PLAYER_PERC_ASSESSMAGIC вызывается только ядром системы // ************************************************** *
const func PLAYER_PERC_ASSESSMAGIC = B_AssessMagic; * *
|
|
|
03.02.2005, 11:26
|
#92
|
|
Re: Уроки скриптологии
// ************************************************** ************** // Функция реакции людей на повреждение // ************************************************** **************
func void B_AssessDamage() { * *// self - жертва, other - агрессор * *var C_NPC Quarho; * *// Куарходрон * *Quarho = Hlp_GetNpc(NONE_ADDON_111_Quarhodron); * *var C_NPC Rhadem; * *// Радемес * *Rhadem = Hlp_GetNpc(NONE_ADDON_112_Rhademes); * *// Если жертва Куарходрон или Радемес * *if((Hlp_GetInstanceID(self) == Hlp_GetInstanceID(Quarho))) ¦¦ ((Hlp_GetInstanceID(self) == Hlp_GetInstanceID(Rhadem))) * *{ * * * *// вызов функции реакции на повреждение для призраков * * * *B_GhostSpecialDamage(other,self); * * * *return; * *}; * *// вызов функции реакции на повреждение "Когтем Белиара" * *B_BeliarsWeaponSpecialDamage(other,self); * *// если жертва Альрик получает повреждение после того, как он сдался * *if(self.aivar[AIV_ArenaFight] == AF_AFTER) * *{ * * * *// ГГ нечестно выиграл сражение с Альриком * * * *self.aivar[AIV_ArenaFight] = AF_AFTER_PLUS_DAMAGE; * *}; * *// если у жертвы врагов не было * *if(self.aivar[AIV_EnemyOverride] == TRUE) * *{ * * * *var C_NPC RAV; * * * *// Равен * * * *RAV = Hlp_GetNpc(BDT_1090_Addon_Raven); * * * *// если Равен жертва * * * *if(Hlp_GetInstanceID(self) == (Hlp_GetInstanceID(RAV))) * * * *{ * * * * * *// теперь у Равена есть враг * * * * * *self.aivar[AIV_EnemyOverride] = FALSE; * * * *}; * *}; * *// если жертва находится в состоянии атаки * *if(Npc_IsInState(self,ZS_Attack)) * *{ * * * *// если ГГ агрессор и жертва друг ГГ (Примечание: защита от нанесения повреждений ГГ своему другу, если они вместе с кем-то сражаются) * * * *if(Npc_IsPlayer(other)) && (self.npctype == NPCTYPE_FRIEND) * * * *{ * * * * * *return; * * * *}; * * * *// если ГГ агрессор и жертва член партии ГГ * * * *if(Npc_IsPlayer(other)) && (self.aivar[AIV_PARTYMEMBER] == TRUE) * * * *{ * * * * * *return; * * * *}; * * * *// если НПС агрессор не является НПС, атакованным жертвой * * * *if(Hlp_GetInstanceID(other) != self.aivar[AIV_LASTTARGET]) * * * *{ * * * * * *// если удар жертве нанесен агрессором не первый раз или агрессор не ГГ * * * * * *if(self.aivar[AIV_HitByOtherNpc] == Hlp_GetInstanceID(other)) ¦¦ (Hlp_GetInstanceID(other) != Hlp_GetInstanceID(hero)) * * * * * *{ * * * * * * * *// смена цели (жертва будет атаковать агрессора) * * * * * * * *Npc_SetTarget(self,other); * * * * * *} * * * * * *else * * * * * *{ * * * * * * * *// при первом ударе жертве записывается ID агрессора * * * * * * * *self.aivar[AIV_HitByOtherNpc] = Hlp_GetInstanceID(other); * * * * * *}; * * * *}; * * * *return; * *}; * *// реакция жертвы на врага * *if(B_AssessEnemy()) * *{ * * * *return; * *}; * *// если НПС агрессор не ГГ и причины нападать у него не было * *if(!Npc_IsPlayer(other)) && (other.aivar[AIV_ATTACKREASON] == AR_NONE) * *{ * * * *// жертва атакует НПС агрессора * * * *B_Attack(self,other,AR_NONE,0); * * * *return; * *}; * *// если агрессор нападает с мечом или с кулаками или вышел из режима нападения (спрятал оружие) * *if(Npc_IsInFightMode(other,FMODE_MELEE)) ¦¦ (Npc_IsInFightMode(other,FMODE_FIST)) ¦¦ (Npc_IsInFightMode(other,FMODE_NONE)) * *{ * * * *// если отношения между агрессором и жертвой дружеские или жертва является другом агрессора ГГ * * * *if(Npc_GetAttitude(self,other) == ATT_FRIENDLY) ¦¦ ((self.npctype == NPCTYPE_FRIEND) && Npc_IsPlayer(other)) * * * *{ * * * * * *// если жертва не находится в состоянии реакции на повреждение * * * * * *if(!Npc_IsInState(self,ZS_ReactToDamage)) * * * * * *{ * * * * * * * *// очистка очереди состояний жертвы * * * * * * * *Npc_ClearAIQueue(self); * * * * * * * *// очистка восприятий жертвы * * * * * * * *B_ClearPerceptions(self); * * * * * * * *// перевод жертвы в состояние реакции на повреждение * * * * * * * *AI_StartState(self,ZS_ReactToDamage,0,""); * * * * * * * *return; * * * * * *}; * * * *}; * *}; * *// жертва атакует агрессора * *B_Attack(self,other,AR_ReactToDamage,0); * *return; };
|
|
|
07.02.2005, 09:55
|
#93
|
|
Re: Уроки скриптологии
// ************************************************** ** // Функция реакции людей на убийство // ************************************************** **
func void B_AssessMurder() { * *// self - свидетель убийства, other - преступник (убийца), victim - жертва (труп) * *// если свидетель убийца * *if(Hlp_GetInstanceID(self) == Hlp_GetInstanceID(other)) * *{ * * * *return; * *}; * *// если расстояния между (свидетелем и преступником) и (свидетелем и жертвой) > макс. дальности действия восприятия * *if(Npc_GetDistToNpc(self,other) > PERC_DIST_INTERMEDIAT) && (Npc_GetDistToNpc(self,victim) > PERC_DIST_INTERMEDIAT) * *{ * * * *return; * *}; * *// если расстояния по высоте между (свидетелем и преступником) и (свидетелем и жертвой) > дальности реакций НПС * *if(Npc_GetHeightToNpc(self,other) > PERC_DIST_HEIGHT) && (Npc_GetHeightToNpc(self,victim) > PERC_DIST_HEIGHT) * *{ * * * *return; * *}; * *// если свидетель не видит преступника и свидетель не видит жертву * *if(!Npc_CanSeeNpcFreeLOS(self,other)) && (!Npc_CanSeeNpcFreeLOS(self,victim)) * *{ * * * *return; * *}; * *// вызов функции реакции свидетеля на преступника (врага) * *if(B_AssessEnemy()) * *{ * * * *return; * *}; * * * * * * * * * * *// если жертва овца и она убита не "крутым парнем" * *if(victim.guild == GIL_SHEEP) && (victim.aivar[AIV_ToughGuy] == FALSE) * *{ * * * *// если есть причина свидетелю атаковать преступника * * * *if(C_WantToAttackSheepKiller(self,other)) * * * *{ * * * * * *// вызов функции атаки * * * * * *B_Attack(self,other,AR_SheepKiller,0); * * * * * *return; * * * *} * * * *else // в противном случае * * * *{ * * * * * *// если свидетель является охранником ворот * * * * * *if(C_NpcIsGateGuard(self)) * * * * * *{ * * * * * * * *// свидетель запоминает новость, что преступник убил овцу * * * * * * * *B_MemorizePlayerCrime(self,other,CRIME_SHEEPKILLE R); * * * * * *}; * * * *}; * *}; * *// если преступник монстр и жертва монстр * *if(other.guild > GIL_SEPERATOR_HUM) && (victim.guild > GIL_SEPERATOR_HUM) * *{ * * * *return; * *}; * *// если преступник монстр * *if(other.guild > GIL_SEPERATOR_HUM) * *{ * * * *// свидетель атакует монстра * * * *B_Attack(self,other,AR_MonsterMurderedHuman,0); * * * *return; * *}; * *// если жертва монстр * *if(victim.guild > GIL_SEPERATOR_HUM) * *{ * * * *return; * *}; * *// если у свидетеля врагов не было * *if(self.aivar[AIV_EnemyOverride] == TRUE) * *{ * * * * *// теперь у свидетеля есть враг * * * *self.aivar[AIV_EnemyOverride] = FALSE; * * * *// свидетелю разрешено воспринимать все объекты в зоне действия восприятия * * * *Npc_PerceiveAll(self); * * * *// поиск свидетелем цели * * * *Npc_GetNextTarget(self); * * * *// если преступник существует и он не бессознателен * * * *if(Hlp_IsValidNpc(other)) && (!C_NpcIsDown(other)) * * * *{ * * * * * *// свидетель атакует преступника * * * * * *B_Attack(self,other,AR_GuildEnemy,0); * * * * * *return; * * * *}; * * * *return; * *}; * *// если (свидетель враждебен к жертве или свидетель зол на жертву) * *if((Npc_GetAttitude(self,victim) == ATT_HOSTILE) ¦¦ (Npc_GetAttitude(self,victim) == ATT_ANGRY)) * *// и (свидетель друг преступника или свидетель нейтрален к преступнику) * *&& ((Npc_GetAttitude(self,other) == ATT_FRIENDLY) ¦¦ (Npc_GetAttitude(self,other) == ATT_NEUTRAL)) * *{ * * * *return; * *}; * *// если преступник ГГ и свидетель его друг * *if(Npc_IsPlayer(other) && (self.npctype == NPCTYPE_FRIEND)) * *{ * * * *return; * *}; * *// если свидетель не должен реагировать на убийство * *if(!C_WantToAttackMurder(self,other)) * *{ * * * *// если свидетель является охранником ворот * * * *if(C_NpcIsGateGuard(self)) * * * *{ * * * * * *// свидетель запоминает новость, что преступник убийца * * * * * *B_MemorizePlayerCrime(self,other,CRIME_MURDER); * * * *}; * * * *return; * *}; * *// если преступник и жертва являются НПС, которым разрешено убить друг друга * *if(other.aivar[AIV_DropDeadAndKill] == TRUE) ¦¦ (victim.aivar[AIV_DropDeadAndKill] == TRUE) * *{ * * * *return; * *}; * *// если жертва черный маг (ищущий) или (жертва бандит и он не из Лагеря бандитов) * *if(victim.guild == GIL_DMT) ¦¦ ((victim.guild == GIL_BDT) && !C_NpcBelongsToBL(victim)) * *{ * * * *return; * *}; * *// свидетель атакует преступника * *B_Attack(self,other,AR_HumanMurderedHuman,0); * *return; };
|
|
|
08.02.2005, 11:03
|
#94
|
|
Re: Уроки скриптологии
// ************************************************** ********* // Функция реакции людей на воровство // ************************************************** ********* // Вызывается в качестве реакции на пассивное восприятие PERC_ASSESSTHEFT // в зоне действия PERC_DIST_INTERMEDIAT когда НПС поднимает какой-либо предмет // ************************************************** *********
func void B_AssessTheft() { * *// other - вор, self - свидетель * *// если вор не ГГ * *if(!Npc_IsPlayer(other)) * *{ * * * *return; * *}; * *// если ГГ находится в доме, принадлежащим любой гильдии, и расстояние между свидетелем и вором > дистанции реакции через закрытые двери * *if(Wld_GetPlayerPortalGuild() >= GIL_NONE) && (Npc_GetHeightToNpc(self,other) > PERC_DIST_INDOOR_HEIGHT) * *{ * * * *return; * *}; * *// если гильдии вора и свидетеля дружественны * *if(Wld_GetGuildAttitude(self.guild,other.guild) == ATT_FRIENDLY) * *{ * * * *// если предмет существует и он принадлежит свидетелю * * * *if(Hlp_IsValidItem(item)) && (Npc_OwnedByNpc(item,self)) * * * *{ * * * * * *// продолжаем анализ ситуации дальше * * * *} * * * *else * * * *{ * * * * * *return; * * * *}; * * * * *}; * *// если предмет принадлежал ГГ ранее * *if(!C_IsTakenItemMyPossession(self,other,item)) * *{ * * * *return; * *}; * *// если свидетель не видит вора * *if(!Npc_CanSeeNpc(self,other)) * *{ * * * *// если свидетель и ГГ находится в одном помещении и если (свидетель наблюдает за ГГ или свидетель находится в состоянии "незваного гостя") * * * *if(Npc_IsInPlayersRoom(self)) && ((Npc_IsInState(self,ZS_ObservePlayer)) ¦¦ (Npc_IsInState(self,ZS_ClearRoom))) * * * *{ * * * * * *// продолжаем анализ ситуации дальше * * * *} * * * *else * * * *{ * * * * * *return; * * * *}; * *}; * *// если свидетель игнорирует вора * *if(!C_WantToAttackThief(self,other)) * *{ * * * *// если свидетель является охранником ворот * * * *if(C_NpcIsGateGuard(self)) * * * *{ * * * * * *// свидетель запоминает новость, что ГГ вор * * * * * *B_MemorizePlayerCrime(self,other,CRIME_THEFT); * * * *}; * * * *return; * *}; * *// свидетель атакует вора * *B_Attack(self,other,AR_Theft,0); * *return; };
... и еще одна функция, очень похожая на предыдущую
// ************************************************** ** // Функция реакции людей на использование МОB's // ************************************************** **
func void B_AssessUseMob() { * *// other - пользователь, self - свидетель * *// если пользователь не ГГ * *if(!Npc_IsPlayer(other)) * *{ * * * *return; * *}; * *// если ГГ находится в доме, принадлежащим любой гильдии * *if(Wld_GetPlayerPortalGuild() >= GIL_NONE) * *{ * * * *// если расстояние между свидетелем и пользователем > дистанции реакции через закрытые двери * * * *if (Npc_GetHeightToNpc(self,other) > PERC_DIST_INDOOR_HEIGHT) * * * *{ * * * * * *return; * * * *}; * *}; * *// если гильдии пользователя и свидетеля дружественны * *if(Wld_GetGuildAttitude(self.guild,other.guild) == ATT_FRIENDLY) * *{ * * * *// если МОВ принадлежит свидетелю * * * *if(Npc_IsDetectedMobOwnedByNpc(other,self)) * * * *{ * * * * * *// продолжаем анализ ситуации дальше * * * *} * * * *else * * * *{ * * * * * *return; * * * *}; * * * * *}; * *// если МОВ принадлежал ГГ ранее * *if(!C_IsUsedMobMyPossession(self,other)) * *{ * * * *return; * *}; * *// если свидетель не видит пользователя * *if(!Npc_CanSeeNpc(self,other)) * *{ * * * *// если свидетель и ГГ находятся в одном помещении и если (свидетель наблюдает за ГГ или свидетель находится в состоянии "незваного гостя") * * * *if(Npc_IsInPlayersRoom(self)) && ((Npc_IsInState(self,ZS_ObservePlayer)) ¦¦ (Npc_IsInState(self,ZS_ClearRoom))) * * * *{ * * * * * *// продолжаем анализ ситуации дальше * * * *} * * * *else * * * *{ * * * * * *return; * * * *}; * *}; * *var string detMob; * *// получить название МОВа, используемого ГГ * *detMob = Npc_GetDetectedMob(other); * *// если МОВ не "Большой сундук" и МОВ не "Маленький сундук" * *if(Hlp_StrCmp(detMob,"CHESTBIG") == FALSE) && (Hlp_StrCmp(detMob,"CHESTSMALL") == FALSE) * *{ * * * *return; * *}; * *// если свидетель игнорирует пользователя * *if(!C_WantToAttackThief(self,other)) * *{ * * * *// если свидетель является охранником ворот * * * *if (C_NpcIsGateGuard(self)) * * * *{ * * * * * *// свидетель запоминает новость, что ГГ вор * * * * * *B_MemorizePlayerCrime(self,other,CRIME_THEFT); * * * *}; * * * *return; * *}; * *// свидетель атакует пользователя * *B_Attack(self,other,AR_UseMob,0); * *return; };
|
|
|
09.02.2005, 10:25
|
#95
|
|
Re: Уроки скриптологии
// ************************************************** ****************************** // Функция реакции людей на вход НПС в помещение // ---------------------------------------- // Возвращает TRUE при реакции на вошедшего или FALSE, когда на вошедшего не реагируют // ************************************************** ******************************
func int B_AssessEnterRoom() { * *// other - вошедший, self - свидетель * *var int portalguild; * *// получить номер гильдии, которой принадлежит помещение (-1 помещение никому не принадлежит) * *portalguild = Wld_GetPlayerPortalGuild(); * *// если вошедший ГГ и комментарий входа уже был и помещение принадлежит какой-либо гильдии и помещение не публичное * *if(Npc_IsPlayer(other)) && (Player_LeftRoomComment == TRUE) && (portalguild > GIL_NONE) && (portalguild != GIL_PUBLIC) * *{ * * * *// сброс комментария входа * * * *Player_LeftRoomComment = FALSE; * *}; * *// если расстояние между вошедшим и свидетелем > 10м * *if(Npc_GetDistToNpc(self,other) > 1000) * *{ * * * *return FALSE; * *}; * *// если свидетель и вошедший (ГГ) находятся не в одном помещении и свидетель находится не снаружи помещения * *if(!Npc_IsInPlayersRoom(self)) && (!(Npc_GetPortalGuild(self) < GIL_NONE)) * *{ * * * *return FALSE; * *}; * *// если свидетель находится в состоянии атаки * *if(Npc_IsInState(self,ZS_Attack)) * *{ * * * *return FALSE; * *}; * *// если свидетель является охранником ворот * *if(C_NpcIsGateGuard(self)) * *{ * * * *return FALSE; * *}; * *// если вошедший не ГГ * *if(!Npc_IsPlayer(other)) * *{ * * * *return FALSE; * *}; * *// если свидетель друг ГГ * *if(self.npctype == NPCTYPE_FRIEND) * *{ * * * *return FALSE; * *}; * *// если отношения между свидетелем и ГГ дружеские * *if(Npc_GetAttitude(self,other) == ATT_FRIENDLY) * *{ * * * *return FALSE; * *}; * *// если ГГ крадется или ГГ стоит * *if(C_BodyStateContains(other,BS_SNEAK)) ¦¦ (C_BodyStateContains(other,BS_STAND)) * *{ * * * *// если свидетель не видит ГГ и свидетель не наблюдает за ГГ * * * *if(!Npc_CanSeeNpc(self,other)) && (!Npc_IsInState(self,ZS_ObservePlayer)) * * * *{ * * * * * *return FALSE; * * * *}; * *}; * *// если свидетель не принадлежит к гильдии * *if(self.guild == GIL_NONE) * *{ * * * *return FALSE; * *}; * *// если свидетель и ГГ находятся не в одном помещениии и свидетель спит * *if(!Npc_IsInPlayersRoom(self)) && (Npc_IsInState(self,ZS_Sleep)) * *{ * * * *return FALSE; * *}; * *// если помещение публично и свидетель находится в одном помещении с ГГ * *if(portalguild == GIL_PUBLIC) && (Npc_IsInPlayersRoom(self)) * *{ * * * *// если свидетель наблюдает за ГГ * * * *if(Npc_IsInState(self,ZS_ObservePlayer)) * * * *{ * * * * * *return FALSE; * * * *}; * * * *// если свидетель лежит * * * *if(C_BodyStateContains(self,BS_LIE)) * * * *{ * * * * * *// свидетель встает (Примечание: мне непонятно как он это делает) * * * * * *B_MM_DeSynchronize(); * * * *}; * * * *// если свидетель * * * *if(Npc_IsInState(self,ZS_Potion_Alchemy)) * * * // занимается алхимией * * * *¦¦ (Npc_IsInState(self,ZS_Read_Bookstand)) * * *// или читает книгу * * * *¦¦ (Npc_IsInState(self,ZS_Sit_Bench)) * * * * * // или сидит на скамье * * * *¦¦ (Npc_IsInState(self,ZS_Sit_Campfire)) * * * *// или сидит у костра * * * *¦¦ (Npc_IsInState(self,ZS_Sit_Chair)) * * * * * // или сидит на стуле * * * *¦¦ (Npc_IsInState(self,ZS_Sit_Throne)) * * * * *// или сидит на троне * * * *¦¦ (Npc_IsInState(self,ZS_Sleep)) * * * * * * * // или спит * * * *¦¦ (Npc_IsInState(self,ZS_Smalltalk)) * * * * * // или ведет светскую беседу * * * *¦¦ (Npc_IsInState(self,ZS_Smoke_Joint)) * * * * // или курит * * * *¦¦ (Npc_IsInState(self,ZS_Stand_ArmsCrossed)) * // или стоит со скрещенными руками * * * *¦¦ (Npc_IsInState(self,ZS_Stand_Drinking)) * * *// или пьет * * * *¦¦ (Npc_IsInState(self,ZS_Stand_Eating)) * * * *// или ест * * * *¦¦ (Npc_IsInState(self,ZS_Stand_Guarding)) * * *// или охраняет * * * *¦¦ (Npc_IsInState(self,ZS_Stand_WP)) * * * * * *// или стоит на вайпоинте * * * *{ * * * * * *// очистка очереди состояний свидетеля * * * * * *Npc_ClearAIQueue(self); * * * * * *// очистка восприятий свидетеля * * * * * *B_ClearPerceptions(self); * * * * * *// если свидетель сидит * * * * * *if(C_BodyStateContains(self,BS_SIT)) * * * * * *{ * * * * * * * *// перевод свидетеля в состояние наблюдения за ГГ * * * * * * * *AI_StartState(self,ZS_ObservePlayer,0,""); * * * * * *} * * * * * *else * * * * * *{ * * * * * * * *// перевод свидетеля в состояние наблюдения за ГГ (выполняется только функция конца состояния) * * * * * * * *AI_StartState(self,ZS_ObservePlayer,1,""); * * * * * *}; * * * * * *return TRUE; * * * *} * * * *else * * * *{ * * * * * *return FALSE; * * * *}; * *}; * *// если ГГ находится в частном помещении * *if(C_NpcIsBotheredByPlayerRoomGuild(self)) * *{ * * * *Npc_ClearAIQueue(self); * * * *B_ClearPerceptions(self); * * * *// перевод свидетеля в состояние "защиты помещения" * * * *AI_StartState(self,ZS_ClearRoom,1,""); * * * *return TRUE; * *}; * *return FALSE; };
// ************************************************** *********** // Функция реакции людей на вход НПС в помещение // ------------------------------------------------ // Вызывается как реакция на пассивное восприятие PERC_ASSESSENTERROOM // ************************************************** ***********
func void B_AssessPortalCollision() { * *// other - вошедший, self - свидетель * *var int formerportalguild; * *// получить номер гильдии, которой принадлежит помещение в котором прежде находился ГГ (-1 помещение никому не принадлежит) * *formerportalguild = Wld_GetFormerPlayerPortalGuild(); * *// если есть реакция на вошедшего в помещение * *if(B_AssessEnterRoom()) * *{ * * * *return; * *}; * *// если свидетель не видит вошедшего и (вошедший крадется или вошедший стоит) * *if(!Npc_CanSeeNpc(self,other)) && (C_BodyStateContains(other,BS_SNEAK) ¦¦ C_BodyStateContains(other,BS_STAND)) * *{ * * * *return; * *}; * *// свидетелю разрешено воспринимать все объекты в зоне действия восприятия * *Npc_PerceiveAll(self); * *// если свидетель находит другого НПС в состоянии "защиты помещения" * *if(Wld_DetectNpcEx(self,-1,ZS_ClearRoom,-1,FALSE)) * *{ * * * *return; * *}; * *// если покинутое ГГ помещение принадлежит гильдии свидетеля или свидетель друг гильдии, которой принадлежит помещение * *if(self.guild == formerportalguild) ¦¦ (Wld_GetGuildAttitude(self.guild,formerportalguild ) == ATT_FRIENDLY) * *{ * * * *// если отношения между гильдиями ГГ и свидетеля дружеские или (вошедший ГГ и друг свидетеля) * * * *if(Wld_GetGuildAttitude(self.guild,other.guild) == ATT_FRIENDLY) ¦¦ (Npc_IsPlayer(other) && (self.npctype == NPCTYPE_FRIEND)) * * * *{ * * * * * *return; * * * *}; * * * *// если свидетель не принадлежит к гильдии * * * *if(self.guild == GIL_NONE) * * * *{ * * * * * *return; * * * *}; * * * *// если (помещение принадлежит милиции или ополчению) и свидетель является другом этих гильдии * * * *if((formerportalguild == GIL_MIL) ¦¦ (formerportalguild == GIL_SLD)) && (Wld_GetGuildAttitude(self.guild,formerportalguild ) == ATT_FRIENDLY) * * * *{ * * * * * *// свидетель атакует ГГ * * * * * *B_Attack(self,other,AR_LeftPortalRoom,0); * * * * * *return; * * * *} * * * *else // иначе * * * *{ * * * * * *// свидетель наблюдает за помещением * * * * * *self.aivar[AIV_SeenLeftRoom] = TRUE; * * * * * *// очистка очереди состояний свидетеля * * * * * *Npc_ClearAIQueue(self); * * * * * *// очистка восприятий свидетеля * * * * * *B_ClearPerceptions(self); * * * * * *// перевод свидетеля в состояние наблюдения за ГГ * * * * * *AI_StartState(self,ZS_ObservePlayer,0,""); * * * * * *return; * * * *}; * *}; };
|
|
|
10.02.2005, 10:07
|
#96
|
|
Re: Уроки скриптологии
// ************************************************** *************** // Функция реакции НПС, когда в него целится ГГ оружием дальнего радиуса поражения // ---------------------------------------------------- // Вызывается как реакция на пассивное восприятие PERC_ASSESSTHREAT // ************************************************** ***************
func void B_AssessThreat() { * *// other - ГГ, self - НПС цель * *// если расстояние между ГГ и целью > макс. дальности действия пассивного восприятия * *if(Npc_GetDistToNpc(self,other) > PERC_DIST_INTERMEDIAT) * *{ * * * *return; * *}; * *// если цель не видит ГГ * *if(!Npc_CanSeeNpc(self,other)) * *{ * * * *return; * *}; * *// если оружие, из которого целится ГГ, не может нанести урон цели * *if(!C_NpcIsBotheredByWeapon(self,other)) * *{ * * * *return; * *}; * *// очистка очереди состояний цели * *Npc_ClearAIQueue(self); * *// очистка восприятий цели * *B_ClearPerceptions(self); * *// переход цели в состояние реакции на оружие ГГ * *AI_StartState(self,ZS_ReactToWeapon,0,""); * *return; };
Еще один файл с функцией реакции на обнаженное оружие.
// ************************************************** ************* // Функция реакции НПС, когда ГГ достает оружие // --------------------------------------------------------------- // Вызывается как реакция на пассивное восприятие PERC_DRAWWEAPON и в некоторых других функциях // --------------------------------------------------------------- // Возвращает FALSE, если НПС не реагирует на оружие ГГ, в противном случае - TRUE. // ************************************************** *************
func int B_AssessDrawWeapon() { * *// other - ГГ, self - НПС * *// если ГГ вышел из режима нападения (убрал оружие) * *if(Npc_IsInFightMode(other,FMODE_NONE)) * *{ * * * *return FALSE; * *}; * * *// если расстояние между ГГ и НПС > дистанции начала диалога * *if(Npc_GetDistToNpc(self,other) > PERC_DIST_DIALOG) * *{ * * * *return FALSE; * *}; * *// если оружие ГГ не может нанести урон НПС * *if(!C_NpcIsBotheredByWeapon(self,other)) * *{ * * * *return FALSE; * *}; * *// если НПС уже находится в состоянии реакции на оружие ГГ * *if(Npc_IsInState(self,ZS_ReactToWeapon)) * *{ * * * *return FALSE; * *}; * *// если НПС находится в состоянии наблюдения за ГГ и предыдущее состояние НПС было наблюдение за сражением ГГ * *if(Npc_IsInState(self,ZS_ObservePlayer)) && (Npc_WasInState(self,ZS_WatchFight)) * *{ * * * *return FALSE; * *}; * *// если НПС не видит ГГ * *if(!Npc_CanSeeNpc(self,other)) * *{ * * * * *return FALSE; * *}; * *// очистка очереди состояний НПС * *Npc_ClearAIQueue(self); * *// очистка восприятий НПС * *B_ClearPerceptions(self); * *// переход НПС в состояние реакции на оружие ГГ * *AI_StartState(self,ZS_ReactToWeapon,0,""); * *return TRUE; };
|
|
|
11.02.2005, 10:07
|
#97
|
|
Re: Уроки скриптологии
Внимание - неточность!!!
В описании AI констант вместо: const int AIV_ToughGuy * * * * * * * * * * *= 57; * //TRUE, если НПС является крутым парнем ... const int AIV_StoryBandit_Esteban * * * * * = 75; * //Эстебан ... const int FAI_NAILED * * * * * * * * * *= 1; * *//Полуживой
необходимо читать: const int AIV_ToughGuy * * * * * * * * * * *= 57; * //TRUE, если НПС имеет дело с "крутым парнем" ... const int AIV_StoryBandit_Esteban * * * * * = 75; * //НПС является охранником Эстебана ... const int FAI_NAILED * * * * * * * * * *= 1; * *//Тактика сражения охранников крепостных стен
Если модераторам не трудно, то можно поправить эти строки в посте №140, а последнюю константу в посте №141.
// ************************************************** ********** // Функция реакции НПС, наблюдающего сражение двух других НПС // ------------------------------------------------------------ // Вызывается как реакция на пассивное восприятие PERC_ASSESSFIGHTSOUND // ************************************************** **********
func void B_AssessFightSound() { * *// self - свидетель, other - нападающий, victim - жертва * *// если жертва отсутствует * *if(!Hlp_IsValidNpc(victim)) * *{ * * * *return; * *}; * *// если расстояния между (свидетелем и жертвой) и (свидетелем и нападающим) > макс. дальности действия пассивного восприятия * *if(Npc_GetDistToNpc(self,victim) > PERC_DIST_INTERMEDIAT) && (Npc_GetDistToNpc(self,other) > PERC_DIST_INTERMEDIAT) * *{ * * * *// если (свидетель чужеземец или бандит) и (гильдии жертвы и свидетеля одинаковы или гильдии нападающего и свидетеля одинаковы) * * * *if((self.guild == GIL_OUT) ¦¦ (self.guild == GIL_BDT)) && ((victim.guild == self.guild) ¦¦ (other.guild == self.guild)) * * * *{ * * * * * *// продолжение анализа * * * *} * * * *else * * * *{ * * * * * *return; * * * *}; * *}; * *// если свидетель боится воды * *if(self.aivar[AIV_MM_FollowInWater] == FALSE) * *{ * * * *// если нападающий плывет или ныряет или жертва плывет или ныряет * * * *if(C_BodyStateContains(other,BS_SWIM) ¦¦ C_BodyStateContains(other,BS_DIVE) * * * *¦¦ C_BodyStateContains(victim,BS_SWIM) ¦¦ C_BodyStateContains(victim,BS_DIVE)) * * * *{ * * * * * *return; * * * *}; * *}; * *// если нападающий или жертва являются охранниками крепостных стен * *if(other.fight_tactic == FAI_NAILED) ¦¦ (victim.fight_tactic == FAI_NAILED) * *{ * * * *return; * *}; * *// если расстояние по высоте между свидетелем и нападающим и свидетелем и жертвой > расстояния реакции по высоте * *if(Npc_GetHeightToNpc(self,other) > PERC_DIST_HEIGHT) && (Npc_GetHeightToNpc(self,victim) > PERC_DIST_HEIGHT) * *{ * * * *return; * *}; * *// если расстояние по высоте между свидетелем и нападающим > 5м и свидетель находится не более чем в 30м от "NW_MONASTERY_PLACE_04" (точка перед входом в главное здание монастыря) * *if(Npc_GetHeightToNpc(self,other) > 500) && (Npc_GetDistToWP(self,"NW_MONASTERY_PLACE_04") <= 3000) * *{ * * * *return; * *}; * *// если жертва наблюдатель или нападающий наблюдатель (мое примечание: если это условие перенести вторым в теле функции, то общее быстродействие увеличится) * *if(Hlp_GetInstanceID(victim) == Hlp_GetInstanceID(self)) ¦¦ (Hlp_GetInstanceID(other) == Hlp_GetInstanceID(self)) * *{ * * * *return; * *}; * *// если жертва овца и она атакована не "крутым парнем" * *if(victim.guild == GIL_SHEEP) && (victim.aivar[AIV_ToughGuy] == FALSE) * *{ * * * *// если есть причина свидетеля атаковать нападающего на овец * * * *if(C_WantToAttackSheepKiller(self,other)) * * * *{ * * * * * *// свидетель атакует нападающего на овец * * * * * *B_Attack(self,other,AR_SheepKiller,0); * * * * * *return; * * * *} * * * *else // в противном случае * * * *{ * * * * * *// если свидетель охранник ворот * * * * * *if(C_NpcIsGateGuard(self)) * * * * * *{ * * * * * * * *// свидетель запоминает новость, что было нападение на овцу * * * * * * * *B_MemorizePlayerCrime(self,other,CRIME_SHEEPKILLE R); * * * * * * * *return; * * * * * *}; * * * *}; * * * *return; * *}; * *// если свидетель охранник ворот * *if(C_NpcIsGateGuard(self)) * *{ * * * *return; * *}; * *// если нападающий и жертва монстры * *if(other.guild > GIL_SEPERATOR_HUM) && (victim.guild > GIL_SEPERATOR_HUM) * *{ * * * *return; * *}; * *// если нападающий монстр и свидетель не враг жертве * *if(other.guild > GIL_SEPERATOR_HUM) && (Npc_GetAttitude(self,victim) != ATT_HOSTILE) * *{ * * * *// свидетель атакует монстра * * * *B_Attack(self,other,AR_MonsterVsHuman,0); * * * *return; * *}; * *// если жертва монстр и свидетель не враг нападающему и жертва жива * *if(victim.guild > GIL_SEPERATOR_HUM) && (Npc_GetAttitude(self,other) != ATT_HOSTILE) && (!Npc_IsDead(victim)) * *{ * * * *// свидетель атакует жертву (помогает нападающему) * * * *B_Attack(self,victim,AR_MonsterVsHuman,0); * * * *return; * *}; * *// если у свидетеля врагов не было * *if(self.aivar[AIV_EnemyOverride] == TRUE) * *{ * * * * *// теперь у свидетеля есть враг * * * *self.aivar[AIV_EnemyOverride] = FALSE; * * * *// свидетелю разрешено воспринимать все объекты в зоне действия восприятия * * * *Npc_PerceiveAll(self); * * * *// поиск свидетелем цели * * * *Npc_GetNextTarget(self); * * * * * *// если нападающий существует и он не бессознателен * * * *if(Hlp_IsValidNpc(other)) && (!C_NpcIsDown(other)) * * * *{ * * * * * *// свидетель атакует нападающего * * * * * *B_Attack(self,other,AR_GuildEnemy,0); * * * * * *return; * * * *}; * * * *return; * *}; * *// -------------------------------------------------- * *// Дальше нападающий и жертва являются только людьми! * *// -------------------------------------------------- * *// если нападающий ГГ является переодетым бандитом или жертва ГГ является переодетым бандитом * *if((C_PlayerIsFakeBandit(self,other) == TRUE) ¦¦ (C_PlayerIsFakeBandit(self,victim) == TRUE)) * *// и (нападающий бандит или жертва бандит) * *&& ((other.guild == GIL_BDT) || (victim.guild == GIL_BDT)) * *{ * * * *// если свидетель бандит * * * *if(self.guild == GIL_BDT) * * * *{ * * * * * *// если свидетель и нападающий являются охранниками Эстебана * * * * * *if(self.aivar[AIV_STORYBANDIT_ESTEBAN] == TRUE) && (other.aivar[AIV_STORYBANDIT_ESTEBAN] == TRUE) * * * * * *{ * * * * * * * *// свидетель атакует жертву * * * * * * * *B_Attack(self,victim,AR_NONE,0); * * * * * * * *return; * * * * * *}; * * * * * *// если свидетель и жертва являются охранниками Эстебана * * * * * *if(self.aivar[AIV_STORYBANDIT_ESTEBAN] == TRUE) && (victim.aivar[AIV_STORYBANDIT_ESTEBAN] == TRUE) * * * * * *{ * * * * * * * *// свидетель атакует нападающего * * * * * * * *B_Attack(self,other,AR_NONE,0); * * * * * * * *return; * * * * * *}; * * * * * *// если нападающий и жертва не имели причины для сражения * * * * * *if(other.aivar[AIV_ATTACKREASON] == AR_NONE) && (victim.aivar[AIV_ATTACKREASON] == AR_NONE) * * * * * *{ * * * * * * * *// очистка очереди состояний свидетеля * * * * * * * *Npc_ClearAIQueue(self); * * * * * * * *// очистка восприятий свидетеля * * * * * * * *B_ClearPerceptions(self); * * * * * * * *// перевод свидетеля в состояние наблюдения на сражением * * * * * * * *AI_StartState(self,ZS_WatchFight,0,""); * * * * * * * *return; * * * * * *}; * * * * * *// если нападающий или жертва являются свободными (с которыми можно сражаться) бандитами * * * * * *if(other.aivar[AIV_StoryBandit] == TRUE) ¦¦ (victim.aivar[AIV_StoryBandit] == TRUE) * * * * * *{ * * * * * * * *Npc_ClearAIQueue(self); * * * * * * * *B_ClearPerceptions(self); * * * * * * * *// перевод свидетеля в состояние наблюдения на сражением * * * * * * * *AI_StartState(self,ZS_WatchFight,0,""); * * * * * * * *return; * * * * * *}; * * * *} * * * *else // иначе (свидетель не бандит) * * * *{ * * * * * *// продолжение анализа * * * *}; * *}; * *// если нападающий имел причину для сражения * *if((other.aivar[AIV_ATTACKREASON] == AR_GuardStopsIntruder) * * // охрана ворот атакует незваного гостя * * * ¦¦ (other.aivar[AIV_ATTACKREASON] == AR_MonsterCloseToGate) *// охрана ворот атакует враждебного монстра * * * ¦¦ (other.aivar[AIV_ATTACKREASON] == AR_HumanMurderedHuman) *// человек убил человека * * * ¦¦ (other.aivar[AIV_ATTACKREASON] == AR_GuildEnemy) * * * * *// НПС является врагом гильдии * * * ¦¦ (other.aivar[AIV_ATTACKREASON] == AR_GuardCalledToKill)) *// охрана вызвана по факту убийства * *// и свидетель друг нападающему * *&& (Npc_GetAttitude(self,other) == ATT_FRIENDLY) * *{ * * * *// свидетель атакует жертву * * * *B_Attack(self,victim,AR_GuardCalledToKill,0); * * * *return; * *}; * *// тоже самое, что и выше, только свидетель помогает жертве * *if((victim.aivar[AIV_ATTACKREASON] == AR_GuardStopsIntruder) * * * ¦¦ (victim.aivar[AIV_ATTACKREASON] == AR_MonsterCloseToGate) * * * ¦¦ (victim.aivar[AIV_ATTACKREASON] == AR_HumanMurderedHuman) * * * ¦¦ (victim.aivar[AIV_ATTACKREASON] == AR_GuildEnemy) * * * ¦¦ (victim.aivar[AIV_ATTACKREASON] == AR_GuardCalledToKill)) * *&& (Npc_GetAttitude(self,victim) == ATT_FRIENDLY) * *{ * * * *B_Attack(self,other,AR_GuardCalledToKill,0); * * * *return; * *}; * *// если нападающий имел причину для сражения * *if((other.aivar[AIV_ATTACKREASON] == AR_GuardStopsFight) * * * *// охрана прекратила атаковать преступника * * * ¦¦ (other.aivar[AIV_ATTACKREASON] == AR_ReactToDamage) * * * // преступник ранил НПС * * * ¦¦ (other.aivar[AIV_ATTACKREASON] == AR_ReactToWeapon)) * * *// преступник не убрал оружие после двукратного предупреждения или пустился в бега * *// свидетель друг нападающему * *&& (Npc_GetAttitude(self,other) == ATT_FRIENDLY) * *{ * * * *// если нападающий ополченец или охотник на драконов или не принадлежит к гильдиям * * * *if((other.guild == GIL_SLD) ¦¦ (other.guild == GIL_DJG) ¦¦ (other.guild == GIL_NONE)) * * * *// и если жертва ополченец или охотник на драконов или не принадлежит к гильдиям * * * *&& ((victim.guild == GIL_SLD) ¦¦ (victim.guild == GIL_DJG) ¦¦ (victim.guild == GIL_NONE)) * * * *{ * * * * * *// продолжение анализа * * * *} * * * *// иначе, если нападающий и жертва не ГГ * * * *else if(!Npc_IsPlayer(other)) && (!Npc_IsPlayer(victim)) * * * *{ * * * * * *// продолжение анализа * * * *} * * * *else // иначе * * * *{ * * * * * *// свидетель атакует жертву * * * * * *B_Attack(self,victim,AR_GuardStopsFight,0); * * * * * *return; * * * *}; * *}; * * *// тоже самое, что и предыдущий if, только свидетель помогает жертве * *if((victim.aivar[AIV_ATTACKREASON] == AR_GuardStopsFight) * * * ¦¦ (victim.aivar[AIV_ATTACKREASON] == AR_ReactToDamage) * * * ¦¦ (victim.aivar[AIV_ATTACKREASON] == AR_ReactToWeapon)) * *&& (Npc_GetAttitude(self,victim) == ATT_FRIENDLY) * *{ * * * *if((other.guild == GIL_SLD) ¦¦ (other.guild == GIL_DJG) ¦¦ (other.guild == GIL_NONE)) * * * *&& ((victim.guild == GIL_SLD) ¦¦ (victim.guild == GIL_DJG) ¦¦ (victim.guild == GIL_NONE)) * * * *{ * * * *} * * * *else if(!Npc_IsPlayer(other)) && (!Npc_IsPlayer(victim)) * * * *{ * * * *} * * * *else * * * *{ * * * * * *// свидетель атакует нападающего * * * * * *B_Attack(self,other,AR_GuardStopsFight,0); * * * * * *return; * * * *}; * *}; * *// если нападающий не имел причины к нападению или причиной было убийство НПС ГГ * *if((other.aivar[AIV_ATTACKREASON] == AR_NONE) ¦¦ (other.aivar[AIV_ATTACKREASON] == AR_KILL)) * *// и если жертва не имела причины к нападению или причиной было убийство НПС ГГ * *&& ((victim.aivar[AIV_ATTACKREASON] == AR_NONE) ¦¦ (victim.aivar[AIV_ATTACKREASON] == AR_KILL)) * *// и свидетель милиция * *&& (self.guild == GIL_MIL) * *{ * * * *// если свидетель друг нападающему и свидетель не друг жертве * * * *if(Npc_GetAttitude(self,other) == ATT_FRIENDLY) && (Npc_GetAttitude(self,victim) != ATT_FRIENDLY) * * * *{ * * * * * *// свидетель атакует жертву * * * * * *B_Attack(self,victim,AR_GuardStopsFight,0); * * * * * *return; * * * *} * * * *// иначе, если свидетель друг жертве и свидетель не друг нападающему * * * *else if(Npc_GetAttitude(self,victim) == ATT_FRIENDLY) && (Npc_GetAttitude(self,other) != ATT_FRIENDLY) * * * *{ * * * * * *// свидетель атакует нападающего * * * * * *B_Attack(self,other,AR_GuardStopsFight,0); * * * * * *return; * * * *} * * * *else // иначе (или оба друга или оба не друга) * * * *{ * * * * * *// если нападающий ГГ * * * * * *if(Npc_IsPlayer(other)) * * * * * *{ * * * * * * * *// свидетель атакует жертву * * * * * * * *B_Attack(self,victim,AR_GuardStopsFight,0); * * * * * * * *return; * * * * * *} * * * * * *// иначе, если жертва ГГ * * * * * *else if(Npc_IsPlayer(victim)) * * * * * *{ * * * * * * * *// свидетель атакует нападающего * * * * * * * *B_Attack(self,other,AR_GuardStopsFight,0); * * * * * * * *return; * * * * * *} * * * * * *else // иначе * * * * * *{ * * * * * * * *// свидетель атакует нападающего * * * * * * * *B_Attack(self,other,AR_GuardStopsFight,0); * * * * * * * *return; * * * * * *}; * * * *}; * *}; * *// ***** помощь нападающему, сражающемуся с вором ***** * *// если нападающий имел причину для сражения * *if((other.aivar[AIV_ATTACKREASON] == AR_UseMob) * * * * * * // использование чужого МОВа * * * ¦¦ (other.aivar[AIV_ATTACKREASON] == AR_Theft) * * * * * // воровство * * * ¦¦ (other.aivar[AIV_ATTACKREASON] == AR_LeftPortalRoom)) // вход в чужое помещение * *// и свидетель друг нападающему * *&& (Npc_GetAttitude(self,other) == ATT_FRIENDLY) * *{ * * * *// если у свидетеля есть причина атаковать вора жертву * * * *if(C_WantToAttackThief(self,victim)) * * * *{ * * * * * *// свидетель атакует жертву * * * * * *B_Attack(self,victim,AR_GuardCalledToThief,0); * * * *}; * * * *return; * *}; * * *// ***** помощь жертве, сражающейся с вором ***** * *// аналогично предыдущему if * *if((victim.aivar[AIV_ATTACKREASON] == AR_UseMob) * * * ¦¦ (victim.aivar[AIV_ATTACKREASON] == AR_Theft) * * * ¦¦ (victim.aivar[AIV_ATTACKREASON] == AR_LeftPortalRoom)) * *&& (Npc_GetAttitude(self,victim) == ATT_FRIENDLY) * *{ * * * *if(C_WantToAttackThief(self,other)) * * * *{ * * * * * *B_Attack(self,other,AR_GuardCalledToThief,0); * * * *}; * * * *return; * *}; * * *// если нападающий имел причину для сражения как защита своего помещения и свидетель друг нападающему * *if(other.aivar[AIV_ATTACKREASON] == AR_ClearRoom) && (Npc_GetAttitude(self,other) == ATT_FRIENDLY) * *{ * * * *// свидетель атакует жертву * * * *B_Attack(self,victim,AR_GuardCalledToRoom,0); * * * *return; * *}; * * *// аналогично предыдущему, только свидетель помогает жертве * *if(victim.aivar[AIV_ATTACKREASON] == AR_ClearRoom) && (Npc_GetAttitude(self,victim) == ATT_FRIENDLY) * *{ * * * *B_Attack(self,other,AR_GuardCalledToRoom,0); * * * *return; * *}; * * *// если расстояния между (свидетелем и жертвой) и (свидетелем и нападающим) > макс. дальности действия пассивного восприятия * *if(Npc_GetDistToNpc(self,other) > PERC_DIST_INTERMEDIAT) && (Npc_GetDistToNpc(self,victim) > PERC_DIST_INTERMEDIAT) * *{ * * * *return; * *}; * *// если свидетель враг нападающему или жертве * *if(Npc_GetAttitude(self,other) == ATT_HOSTILE) ¦¦ (Npc_GetAttitude(self,victim) == ATT_HOSTILE) * *{ * * * *// если свидетель бандит * * * *if(self.guild == GIL_BDT) * * * *{ * * * * * *// продолжение анализа * * * *} * * * *else * * * *{ * * * * * *return; * * * *}; * *}; * *// если свидетель не видит по прямой жертву * *if(!Npc_CanSeeNpcFreeLOS(self,victim)) * *{ * * * * * * *return; * *}; * *// очистка очереди состояний свидетеля * *Npc_ClearAIQueue(self); * *// очистка восприятий свидетеля * *B_ClearPerceptions(self); * *// перевод свидетеля в состояние наблюдения на сражением * *AI_StartState(self,ZS_WatchFight,0,""); * *return; };
|
|
|
12.02.2005, 22:27
|
#98
|
|
Re: Уроки скриптологии
// ************************************************** *************** // Функция реакции НПС на звук шагов ГГ или на звук упавшего предмета // ----------------------------------------------------------------- // Вызывается в качестве реакции на пассивное восприятие PERC_ASSESSQUIETSOUND // ************************************************** ***************
func void B_AssessQuietSound() { * *// other - НПС источник шума (ГГ), self - свидетель * *// если источник шума отсутствует * *if(!Hlp_IsValidNpc(other)) * *{ * * * *return; * *}; * *// если расстояние по высоте между источником шума и свидетелем > дистанции реагирования по высоте * *if(Npc_GetHeightToNpc(self,other) > PERC_DIST_HEIGHT) * *{ * * * *return; * *}; * *// если ГГ находится в доме, принадлежащим любой гильдии, и расстояние по высоте между свидетелем и ГГ > дистанции реакции через закрытые двери * *if(Wld_GetPlayerPortalGuild() >= GIL_NONE) && (Npc_GetHeightToNpc(self,other) > PERC_DIST_INDOOR_HEIGHT) * *{ * * * *return; * *}; * *// если есть реакция на вошедшего в помещение * *if(B_AssessEnterRoom()) * *{ * * * *return; * *}; * *// если свидетель является охранником ворот * *if(C_NpcIsGateGuard(self)) * *{ * * * *return; * *}; * *// если ГГ и свидетель не враги и свидетель не имеет для ГГ важной информации * *if(Npc_GetAttitude(self,other) != ATT_HOSTILE) && (Npc_CheckInfo(self,1) == FALSE) * *{ * * * *return; * *}; * *// если ГГ и свидетель враги * *if(Npc_GetAttitude(self,other) == ATT_HOSTILE) * *// и (у свидетеля личных врагов не было или (ГГ переодетый бандит и свидетель бандит)) * *&& ((self.aivar[AIV_EnemyOverride] == TRUE) ¦¦ (C_PlayerIsFakeBandit(self,other) && (self.guild == GIL_BDT))) * *{ * * * *return; * *}; * *// если свидетель видит источник звука (моё примечание: возможно здесь ошибка, необходимо поменять условие на противоположное???) * *if(Npc_CanSeeSource(self)) * *{ * * * *return; * *}; * * *// очистка очереди AI команд свидетеля * *Npc_ClearAIQueue(self); * *// очистка восприятий свидетеля * *B_ClearPerceptions(self); * *// перевод свидетеля в состояние наблюдения за ГГ * *AI_StartState(self,ZS_ObservePlayer,1,""); * *return; }; *
// ************************************************** ************ // Функция реакции НПС на предупреждение // --------------------------------------- // Предупреждение посылается только скриптами (вызов функции Npc_SendPassivePerc), ядром не испоьзуется // ************************************************** ************
func void B_AssessWarn() { * *// self - свидетель, other - преступник, victim - жертва * *// если свидетель жертва * *if(Hlp_GetInstanceID(victim) == Hlp_GetInstanceID(self)) * *{ * * * *return; * *}; * *// если свидетель находится в состоянии реакции на обнаженное оружие или наблюдает за ГГ * *if(Npc_IsInState(self,ZS_ReactToWeapon)) ¦¦ (Npc_IsInState(self,ZS_ObservePlayer)) * *{ * * * *return; * *}; * *// если преступник монстр * *if(other.guild > GIL_SEPERATOR_HUM) * *{ * * * *return; * *}; * *// если свидетель охранник ворот * *if(C_NpcIsGateGuard(self)) * *{ * * * *return; * *}; * *// очистка очереди AI команд свидетеля * *Npc_ClearAIQueue(self); * *// очистка восприятий свидетеля * *B_ClearPerceptions(self); * *// перевод свидетеля в состояние наблюдения за ГГ * *AI_StartState(self,ZS_ObservePlayer,0,""); * *return; };
|
|
|
13.02.2005, 13:34
|
#99
|
|
Re: Уроки скриптологии
// ************************************************** ** // Функция реакции НПС на важную информацию для разговора // ---------------------------------------------------- // Вызывается в качестве реакции на пассивное восприятие PERC_ASSESSTALK // ************************************************** **
func void B_AssessTalk() { * *// other - НПС приемник информации (обычно ГГ), self - НПС источник информации
* *// Тестовый кусок (можно выкинуть из скрипта) [не рассматриваю] * *var C_NPC PCL; * *// Инспектор уровня * *PCL = Hlp_GetNpc(PC_Levelinspektor); * *var C_NPC PCR; * *// Рокфеллер * *PCR = Hlp_GetNpc(PC_Rockefeller); * *// если приемник информации Инспектор уровня или Рокфеллер * *if(Hlp_GetInstanceID(other) == Hlp_GetInstanceID(PCL)) ¦¦ (Hlp_GetInstanceID(other) == Hlp_GetInstanceID(PCR)) * *{ * * * *PrintScreen(ConcatStrings("Stimme: ",IntToString(self.voice)),-1,70,FONT_Screen,2); * * * *PrintScreen("KEIN HERO!",-1,-1,FONT_Screen,2); * * * * *PrintScreen(IntToString(self.aivar[AIV_FollowDist]),-1,70,FONT_Screen,2); * * * *if(C_NpcIsInQuarter(self) == Q_KASERNE) * * * *{ * * * * * *PrintScreen("Q_KASERNE",-1,30,FONT_Screen,2); * * * *}; * * * *if(C_NpcIsInQuarter(self) == Q_GALGEN) * * * *{ * * * * * *PrintScreen("Q_GALGEN",-1,30,FONT_Screen,2); * * * *}; * * * *if(C_NpcIsInQuarter(self) == Q_MARKT) * * * *{ * * * * * *PrintScreen("Q_MARKT",-1,30,FONT_Screen,2); * * * *}; * * * *if(C_NpcIsInQuarter(self) == Q_TEMPEL) * * * *{ * * * * * *PrintScreen("Q_TEMPEL",-1,30,FONT_Screen,2); * * * *}; * * * *if(C_NpcIsInQuarter(self) == Q_UNTERSTADT) * * * *{ * * * * * *PrintScreen("Q_UNTERSTADT",-1,30,FONT_Screen,2); * * * *}; * * * *if(C_NpcIsInQuarter(self) == Q_HAFEN) * * * *{ * * * * * *PrintScreen("Q_HAFEN",-1,30,FONT_Screen,2); * * * *}; * * * *if(C_NpcIsInQuarter(self) == Q_OBERSTADT) * * * *{ * * * * * *PrintScreen("Q_OBERSTADT",-1,30,FONT_Screen,2); * * * *}; * * * *return; * *}; * * * *// Нормальное начала функции * *// если источник информации монстр * *if(self.guild > GIL_SEPERATOR_HUM) * *{ * * * *// если монстр не имеет важной информации * * * *if(Npc_CheckInfo(self,1) == FALSE) * * * *{ * * * * * *// если монстру вообще нечего сказать * * * * * *if(Npc_CheckInfo(self,0) == FALSE) * * * * * *{ * * * * * * * *return; * * * * * *}; * * * *}; * *}; * *// если источник информации человек * *if(self.guild < GIL_SEPERATOR_HUM) * *{ * * * * * * * *// если НПС источник информации враг ГГ * * * *if(B_AssessEnemy()) * * * *{ * * * * * *return; * * * *}; * * * *// если НПС источник информации знает, что ГГ убийца и у него есть причина атакоывать убийцу * * * *if(B_GetPlayerCrime(self) == CRIME_MURDER) && (C_WantToAttackMurder(self,other)) * * * *{ * * * * * *// источник информации атакует ГГ убийцу * * * * * *B_Attack(self,other,AR_HumanMurderedHuman,0); * * * * * * *return; * * * *}; * * * *// если ГГ переодетый бандит и источник информации не бандит * * * *if(C_PlayerIsFakeBandit(self,other) == TRUE) && (self.guild != GIL_BDT) * * * *{ * * * * * *// источник информации атакует ГГ * * * * * *B_Attack(self,other,AR_GuildEnemy,0); * * * * * *return; * * * *}; * * * *// если ГГ отказался от разговора * * * *if(C_RefuseTalk(self,other)) * * * *{ * * * * * *// если ГГ член подставной гильдии * * * * * *ifC_PlayerHasFakeGuild(self,other) * * * * * *{ * * * * * * * *// очистка очереди AI состояний источника информации * * * * * * * *Npc_ClearAIQueue(self); * * * * * * * *// источник информации переходит в конечное состояние комментирования подставной гильдии * * * * * * * *AI_StartState(self,ZS_CommentFakeGuild,1,""); * * * * * * * *return; * * * * * *} * * * * * *else * * * * * *{ * * * * * * * *// источник информации произносит SVM фразу "Оставь меня в покое!" * * * * * * * *B_Say(self,other,"$NOTNOW"); * * * * * * * *return; * * * * * *}; * * * * *}; * *}; * *// если ГГ еще не говорил с источником информации * *if(self.aivar[AIV_NpcStartedTalk] == FALSE) * *{ * * * *// если источник идет или бежит * * * *if(C_BodyStateContains(self,BS_WALK) ¦¦ C_BodyStateContains(self,BS_RUN)) * * * *{ * * * * * *// ГГ произносит SVM фразу "Подожди!" * * * * * *B_Say(other,self,"$SC_HEYWAITASECOND"); * * * *} * * * *// иначе, если источник информации не видит ГГ * * * *else if(!Npc_CanSeeNpc(self,other)) * * * *{ * * * * * *var int rnd; * * * * * *// генерация случайного числа от 0 до 99 * * * * * *rnd = Hlp_Random(100); * * * * * *// ГГ призносит фразу * * * * * *if(rnd <= 25) * * * { B_Say(other,self,"$SC_HEYTURNAROUND"); * *} * // звучит SVM фраза "Эй ты!" * * * * * *else if (rnd <= 50) { B_Say(other,self,"$SC_HEYTURNAROUND02"); *} * // звучит SVM фраза "Эй ты!" * * * * * *else if (rnd <= 75) { B_Say(other,self,"$SC_HEYTURNAROUND03"); *} * // звучит SVM фраза "Эй!" * * * * * *else if (rnd <= 99) { B_Say(other,self,"$SC_HEYTURNAROUND04"); *}; *// звучит SVM фраза "Эй!" * * * *}; * *}; * *// очистка очереди AI состояний источника информации * *Npc_ClearAIQueue(self); * *// очистка восприятий источника информации * *B_ClearPerceptions(self); * * *// если источник информации сидит * *if(C_BodyStateContains(self,BS_SIT)) * *{ * * * *// если ГГ заговорил с источником информации * * * *if(self.aivar[AIV_NpcStartedTalk] == TRUE) * * * *{ * * * * * *// ГГ быстро останавливается * * * * * *AI_StandUpQuick(other); * * * *} * * * *else // иначе * * * *{ * * * * * *// ГГ останавливается * * * * * *AI_StandUp(other); * * * *}; * * * *// если источник информации видит ГГ * * * *if(Npc_CanSeeNpc(self,other)) * * * *{ * * * * * *// источник информации переходит в состояние разговора, оставаясь сидеть * * * * * *AI_StartState(self,ZS_Talk,0,""); * * * *} * * * * *else // иначе (не видит ГГ) * * * *{ * * * * * *// если источник информации наблюдал за ГГ * * * * * *if(Npc_IsInState(self,ZS_ObservePlayer)) * * * * * *{ * * * * * * * *// источник информации встает * * * * * * * *AI_StandUp(self); * * * * * *}; * * * * * *// источник информации переходит в состояние разговора * * * * * *AI_StartState(self,ZS_Talk,1,""); * * * *}; * * * *return; * *} * *else // иначе (не сидит) * *{ * * * *// если ГГ заговорил с источником информации * * * *if(self.aivar[AIV_NpcStartedTalk] == TRUE) * * * *{ * * * * * *// оба быстро останавливаются * * * * * *AI_StandUpQuick(self); * * * * * *AI_StandUpQuick(other); * * * *} * * * *else * * * *{ * * * * * *// оба останавливаются * * * * * *AI_StandUp(self); * * * * * *AI_StandUp(other); * * * *}; * * * *// источник информации переходит в состояние разговора * * * *AI_StartState(self,ZS_Talk,0,""); * * * *return; * *}; };
// ************************************** // Функция реакции НПС перемещение МОВа // -------------------------------------- // Вызывается ядром системы как реакция на пассивное восприятие PERC_MOVEMOB // **************************************
func void B_MoveMob() { * * *// self - НПС перемещающий МОВ (ГГ) * *var string door; * *// получить имя перемещаемого МОВа * *door = Npc_GetDetectedMob(self); * *// если МОВ дверь * *if(Hlp_StrCmp(door,"DOOR")) * *{ * * * *// если дверь закрыта * * * *if(Wld_GetMobState(self,door) == 0) * * * *{ * * * * * *// очистка очереди AI состояний ГГ * * * * * *Npc_ClearAIQueue (self); * * * * * *// ГГ открывает дверь * * * * * *AI_UseMob(self,door,1); * * * * * *// зафиксировать состояние двери * * * * * *AI_UseMob(self,door,-1); * * * *}; * *} * *else // иначе * *{ * * * *return; * *}; * *// ГГ продолжает свои дела * *AI_ContinueRoutine(self); };
Конец 5 параграфа. Вот и все основные восприятия, на которые реагируют люди, есть еще дополнительные восприятия, которые инициализируются в функциях состояний, их мы рассмотрим позже. Все файлы активных и пассивных восприятий людей находятся в директории ..\AI\Human\B_Human\ и имеют имена эквивалентные функциям восприятий. Файл восприятия магии находится в директории ..\AI\Magic\
Примечание: Файл ..\AI\Human\B_Human\B_AssessObserveSuspect.d можно удалить из скриптов, по причине его абсолютной бесполезности.
|
|
|
14.02.2005, 10:48
|
#100
|
|
Re: Уроки скриптологии
6. Функции обработки восприятий монстров.
// ************************************************** // Функция реакции монстров на врага. // -------------------------------------------------- // Вызывается ядром системы в качестве реакции на активное восприятие PERC_ASSESSENEMY. // **************************************************
func void B_MM_AssessEnemy() { * *// self - НПС монстр, other - враг * *// если монстр дракон и ГГ имеет "Заряженный глаз Инноса" * *if(self.guild == GIL_DRAGON) && (Npc_HasItems(hero,ItMi_InnosEye_Mis) >= 1) * *{ * * * *return; * *}; * *// если монстр или враг не могут атаковать * *if((self.aivar[AIV_NoFightParker] == TRUE) ¦¦ (other.aivar[AIV_NoFightParker] == TRUE)) * *{ * * * *return; * *}; * *// если личных врагов у монстра нет и враг человек * *if(self.aivar[AIV_EnemyOverride] == TRUE) && (other.guild < GIL_SEPERATOR_HUM) * *{ * * * *return; * *}; * *// ------- TESTMODE: Levelinspektor wird ignoriert ------ * *var C_NPC PCL; * *// "Инспектор уровня" * *PCL = Hlp_GetNpc(PC_Levelinspektor); * *// если враг "Инспектор уровня" * *if(Hlp_GetInstanceID(other) == Hlp_GetInstanceID(PCL)) * *{ * * * *return; * *}; * *var C_NPC MGO; * *// Магический голем * *MGO = Hlp_GetNpc(MagicGolem); * *var C_NPC LAR; * *// Ларес * *LAR = Hlp_GetNpc(VLK_449_Lares); * *// если враг Ларес и монстр Магический голем * *if(Hlp_GetInstanceID(other) == Hlp_GetInstanceID(LAR)) && (Hlp_GetInstanceID(self) == Hlp_GetInstanceID(MGO)) * *{ * * * *return; * *}; * *// если монстр находится не далее 5м от точки "OC_RAMP_07" * *if(Npc_GetDistToWP(self,"OC_RAMP_07") <= 500) * *{ * * * *return; * *}; * *// если враг находится в режиме диалога * *if(other.aivar[AIV_INVINCIBLE] == TRUE) * *{ * * * *return; * *}; * *// если враг (плывет или ныряет) и монстр не полезет в воду * *if(C_BodyStateContains(other,BS_SWIM) ¦¦ C_BodyStateContains(other,BS_DIVE)) && (self.aivar[AIV_MM_FollowInWater] == FALSE) * *{ * * * *return; * *}; * *// если расстояние по высоте между монстром и врагом > расстояния реакции по высоте * *if(Npc_GetHeightToNpc(self,other) > PERC_DIST_HEIGHT) * *{ * * * *return; * *}; * *// если ГГ враг и он превращен в монстра * *if(Npc_IsPlayer(other)) && (other.guild > GIL_SEPERATOR_HUM) * *{ * * * *// если гильдии монстра и превращенного ГГ не враждебны * * * *if(Wld_GetGuildAttitude(self.guild,other.guild) != ATT_HOSTILE) * * * *{ * * * * * *return; * * * *}; * *}; * *// если дальность обоняния монстра > макс. дальности действия активного восприятия монстров * *if(self.senses_range > PERC_DIST_MONSTER_ACTIVE_MAX) * *{ * * * *// если расстояние между монстром и врагом > макс. дальности действия активного восприятия монстров * * * *if(Npc_GetDistToNpc(self,other) > PERC_DIST_MONSTER_ACTIVE_MAX) * * * *{ * * * * * *// если монстр не видит врага * * * * * *if(!Npc_CanSeeNpc(self,other)) * * * * * *{ * * * * * * * *return; * * * * * *}; * * * *}; * *}; * *// если монстр орк или дружественный орк * *if(self.guild == GIL_ORC) ¦¦ (self.guild == GIL_FRIENDLY_ORC) * *{ * * * *// если враг подкрадавается или стоит * * * *if(C_BodyStateContains(other,BS_SNEAK)) ¦¦ (C_BodyStateContains(other,BS_STAND)) * * * *{ * * * * * *// если монстр не видит врага * * * * * *if(!Npc_CanSeeNpc(self,other)) * * * * * *{ * * * * * * * *return; * * * * * *}; * * * *}; * *}; * *// если монстр не видит врага по прямой (например, враг за стеной) * *if(!Npc_CanSeeNpcFreeLOS(self,other)) * *{ * * * *return; * *}; * *// если монстр является членом партии (вызванный) * *if(self.aivar[AIV_PARTYMEMBER] == TRUE) * *{ * * * *// если враг монстра является другом НПС * * * *if(other.npctype == NPCTYPE_FRIEND) * * * *{ * * * * * *return; * * * *}; * * * *// очистка очереди AI состояний монстра * * * *Npc_ClearAIQueue(self); * * * *// монстр выбирает цель * * * *Npc_SetTarget(self,other); * * * *// очистка восприятий монстра * * * *B_ClearPerceptions(self); * * * *// переход монстра в состояние атаки * * * *AI_StartState(self,ZS_MM_Attack,0,""); * * * *return; * *}; * *// если монстр не угрожает перед атакой (атакует сразу) * *if(self.aivar[AIV_MM_ThreatenBeforeAttack] == FALSE) * *{ * * * *Npc_ClearAIQueue(self); * * * *Npc_SetTarget(self,other); * * * *B_ClearPerceptions(self); * * * *// переход монстра в состояние атаки * * * *AI_StartState(self,ZS_MM_Attack,0,""); * * * *return; * *}; * *// если монстр находится в состоянии "пожирания падали" * *if(Npc_IsInState(self,ZS_MM_EatBody)) * *{ * * * *// если расстояние между монстром и врагом <= дистанции атаки монстров * * * *if(Npc_GetDistToNpc(self,other) <= FIGHT_DIST_MONSTER_ATTACKRANGE) * * * *{ * * * * * *Npc_ClearAIQueue(self); * * * * * *Npc_SetTarget(self,other); * * * * * *B_ClearPerceptions(self); * * * * * *// переход монстра в состояние атаки * * * * * *AI_StartState(self,ZS_MM_Attack,0,""); * * * * * *return; * * * *}; * * * *return; * * * *}; * *// если монстр находится в соостоянии охоты * *if(Npc_IsInState(self,ZS_MM_Hunt)) * *{ * * * *// если расстояние между монстром и врагом <= дистанции атаки монстров * * * *if(Npc_GetDistToNpc(self,other) <= FIGHT_DIST_MONSTER_ATTACKRANGE) * * * *{ * * * * * *Npc_ClearAIQueue(self); * * * * * *Npc_SetTarget(self,other); * * * * * *B_ClearPerceptions(self); * * * * * *// переход монстра в состояние атаки * * * * * *AI_StartState(self,ZS_MM_Attack,0,""); * * * * * *return; * * * *} * * * *else * * * *{ * * * * * *return; * * * *}; * *}; * *// если монстра устраивает добыча в виде врага * *if(C_PredatorFoundPrey(self,other)) * * * *{ * * * *Npc_ClearAIQueue(self); * * * *Npc_SetTarget(self,other); * * * *B_ClearPerceptions(self); * * * *// переход монстра в состояние охоты на врага * * * *AI_StartState(self,ZS_MM_Hunt,0,""); * * * *return; * *}; * *// если врага устраивает добыча в виде монстра * *if(C_PredatorFoundPrey(other,self)) * *{ * * * *// если враг находится в соостоянии охоты и если расстояние между монстром и врагом <= дистанции преследования * * * *if(!Npc_IsInState(other,ZS_MM_Hunt)) && (Npc_GetDistToNpc(self,other) <= FIGHT_DIST_MONSTER_FLEE) * * * *{ * * * * * *Npc_ClearAIQueue(self); * * * * * *Npc_SetTarget(self,other); * * * * * *B_ClearPerceptions(self); * * * * * *// переход монстра в состояние преследования * * * * * *AI_StartState(self,ZS_MM_Flee,0,""); * * * * * *return; * * * *} * * * *else * * * *{ * * * * * *return; * * * *}; * *}; * *// очистка очереди AI состояний монстра * *Npc_ClearAIQueue(self); * *// очистка восприятий монстра * *B_ClearPerceptions(self); * *// переход монстра в состояние угрозы * *AI_StartState(self,ZS_MM_ThreatenEnemy,0,""); * *return; };
|
|
|
14.02.2005, 18:13
|
#101
|
|
Re: Уроки скриптологии
// ****************************************** // Функция реакции монстров на мертвое тело // ------------------------------------------ // Вызывается ядром системы в качестве реакции на пассивное восприятие PERC_ASSESSBODY // ******************************************
func void B_MM_AssessBody() { * *// self - монстр, other - труп * *// если монстр принадлежит к оркам * *if(self.guild > GIL_SEPERATOR_ORC) * *{ * * * *return; * *}; * *// если расстояние по высоте между монстром и трупом > расстояния реакции по высоте * *if(Npc_GetHeightToNpc(self,other) > PERC_DIST_HEIGHT) * *{ * * * *return; * *}; * *// если приоритетом монстра является нападение * *if(self.aivar[AIV_MM_PRIORITY] == PRIO_ATTACK) * *{ * * * *return; * *}; * *// если труп не нравится монстру * *if(!C_WantToEat(self,other)) * * * * * * * * * * * *{ * * * *return; * *}; * *// если монстр находится в состоянии атаки * *if(Npc_IsInState(self,ZS_MM_Attack)) * *{ * * * *var C_NPC stoerenfried; * * * *// последний атакованный НПС * * * *stoerenfried = Hlp_GetNpc(self.aivar[AIV_LASTTARGET]); * * * *// если расстояние между атакованным НПС и трупом <= дистанции атаки монстров * * * *if(Npc_GetDistToNpc(stoerenfried,other) <= FIGHT_DIST_MONSTER_ATTACKRANGE) * * * *{ * * * * * *return; * * * *}; * *}; * *// очистка очереди AI состояний монстра * *Npc_ClearAIQueue(self); * *// очистка восприятий монстра * *B_ClearPerceptions(self); * *// переход в состояние пожирания трупа * *AI_StartState(self,ZS_MM_EatBody,0,""); * *return; };
... и еще одна функция
// ************************************************** ****** // Функция реакции монстра на повреждение // -------------------------------------------------------- // Вызывается ядром системы в качестве реакции на пассивное восприятие PERC_ASSESSDAMAGE // ************************************************** ******
func void B_MM_AssessDamage() { * *// self - монстр жертва, other - НПС агрессор * *// установить монстру приоритет на атаку * *self.aivar[AIV_MM_PRIORITY] = PRIO_ATTACK; * *// вызов функции реакции на повреждение "Когтем Белиара" * *B_BeliarsWeaponSpecialDamage(other,self); * *// если агрессор имеет "Святой молот" * *if(Npc_HasItems(other,Holy_Hammer_MIS) > 0) * *{ * * * *var C_NPC MagGol; * * * *// Магический голем * * * *MagGol = Hlp_GetNpc(MagicGolem); * * * *// проинициализировать глобальную переменную item "Святым молотом" * * * *Npc_GetInvItem(other,Holy_Hammer_MIS); * * * *var C_ITEM OthWeap; * * * *// оружие, которое агрессор держит в руке * * * *OthWeap = Npc_GetReadiedWeapon(other); * * * *// если жертва Магический голем и оружие у агрессора в руке "Святой молот" * * * *if(Hlp_GetInstanceID(self) == Hlp_GetInstanceID(MagGol)) && (Hlp_GetInstanceID(OthWeap) == Hlp_GetInstanceID(item)) * * * *{ * * * * * *// Жизнь Магического голема -= 1000 LP * * * * * *Npc_ChangeAttribute(self,ATR_HITPOINTS,-1000); * * * * * *return; * * * *}; * *}; * * * * *// если жертва Каменный сторож и у него нет врагов * *if(self.guild == GIL_STONEGUARDIAN) && (self.aivar[AIV_EnemyOverride] == TRUE) * *{ * * * *// пробуждение Каменного сторожа * * * *B_AWAKE_STONEGUARDIAN(self); * *}; * * *// если агрессора устраивает добыча в виде жертвы * *if(C_PredatorFoundPrey(other,self)) * *{ * * * *// очистка очереди AI состояний жертвы * * * *Npc_ClearAIQueue(self); * * * *// установка цели для жертвы * * * *Npc_SetTarget(self,other); * * * *// очистка восприятий жертвы * * * *B_ClearPerceptions(self); * * * *// жертва убегает от агрессора * * * *AI_StartState(self,ZS_MM_Flee,0,""); * * * * * *return; * *}; * *// если жертва находится в состоянии атаки * *if(Npc_IsInState(self,ZS_MM_Attack)) * *{ * * * *// если агрессор ГГ и жертва член партии * * * *if(Npc_IsPlayer(other)) && (self.aivar[AIV_PARTYMEMBER] == TRUE) * * * *{ * * * * * *return; * * * *}; * * * *// если жертва скелет и агрессор маг скелетов * * * *if(self.aivar[AIV_MM_REAL_ID] == ID_SKELETON) && (other.aivar[AIV_MM_REAL_ID] == ID_SKELETON_MAGE) * * * *{ * * * * * *return; * * * *}; * * * *// если агрессор не является НПС, атакованным жертвой * * * *if(Hlp_GetInstanceID(other) != self.aivar[AIV_LASTTARGET]) * * * *{ * * * * * *// если удар жертве нанесен агрессором не первый раз * * * * * *if(self.aivar[AIV_HitByOtherNpc] == Hlp_GetInstanceID(other)) * * * * * *{ * * * * * * * *// смена цели (жертва будет атаковать агрессора) * * * * * * * *Npc_SetTarget(self,other); * * * * * *} * * * * * *else * * * * * *{ * * * * * * * *// при первом ударе жертве записывается ID агрессора * * * * * * * *self.aivar[AIV_HitByOtherNpc] = Hlp_GetInstanceID(other); * * * * * *}; * * * *}; * * * *return; * *}; * *// очистка очереди AI состояний жертвы * *Npc_ClearAIQueue(self); * *// установка цели для жертвы * *Npc_SetTarget(self,other); * *// очистка восприятий жертвы * *B_ClearPerceptions(self); * *// жертва атакует агрессора * *AI_StartState(self,ZS_MM_Attack,0,""); * *return; };
|
|
|
15.02.2005, 09:48
|
#102
|
|
Re: Уроки скриптологии
// ************************************************** ************** // Функция реакции монстра на убийство и на повреждение других НПС // ---------------------------------------------------------------- // Вызывается в качестве реакции на пассивные восприятия PERC_ASSESSOTHERSDAMAGE и PERC_ASSESSMURDER // ************************************************** **************
func void B_MM_AssessOthersDamage() { * *// self - монстр наблюдатель, other - агрессор, victim - жертва (труп) * *// если расстояния между (наблюдателем и жертвой) и (наблюдателем и агрессором) > макс. дальности действия восприятия * *if(Npc_GetDistToNpc(self,victim) > PERC_DIST_INTERMEDIAT) && (Npc_GetDistToNpc(self,other) > PERC_DIST_INTERMEDIAT) * *{ * * * *return; * *}; * *// если наблюдатель не видит жертву * *if(!Npc_CanSeeNpcFreeLOS(self,victim)) * *{ * * * *return; * *}; * *// если наблюдатель член партии * *if(self.aivar[AIV_PARTYMEMBER] == TRUE) * *{ * * * *// если жертва ГГ * * * *if(Npc_IsPlayer(victim)) * * * *{ * * * * * *// очистка очереди AI состояний наблюдателя * * * * * *Npc_ClearAIQueue(self); * * * * * *// очистка восприятий наблюдателя * * * * * *B_ClearPerceptions(self); * * * * * *// установка в качестве цели агрессора * * * * * *Npc_SetTarget(self,other); * * * * * *// монстр наблюдатель атакует агрессора * * * * * *AI_StartState(self,ZS_MM_Attack,0,""); * * * * * *return; * * * *}; * * * *// если агрессор ГГ и жертва жива * * * *if(Npc_IsPlayer(other)) && (!Npc_IsDead(victim)) * * * *{ * * * * * *// очистка очереди AI состояний наблюдателя * * * * * *Npc_ClearAIQueue(self); * * * * * *// очистка восприятий наблюдателя * * * * * *B_ClearPerceptions(self); * * * * * *// установка в качестве цели жертвы * * * * * *Npc_SetTarget(self,victim); * * * * * *// монстр наблюдатель атакует жертву * * * * * *AI_StartState(self,ZS_MM_Attack,0,""); * * * * * *return; * * * *}; * *}; * *// если наблюдатель волк * *if(self.guild == GIL_WOLF) * *{ * * * *// если жертва волк и агрессор волк и волк агрессор есть ГГ и жертва убита * * * *if(victim.guild == GIL_WOLF) && (other.guild == GIL_WOLF) && Npc_IsPlayer(other) && Npc_IsDead(victim) * * * *{ * * * * * *Npc_ClearAIQueue(self); * * * * * *B_ClearPerceptions(self); * * * * * *// перевод наблюдателя в состояние вызванного монстра * * * * * *self.start_aistate = ZS_MM_Rtn_Summoned; * * * * * *AI_StartState(self,ZS_MM_Rtn_Summoned,0,""); * * * * * *return; * * * *}; * *}; * *// если наблюдатель каменный страж и жертва каменный страж и у наблюдателя нет врагов * *if(self.guild == GIL_STONEGUARDIAN) && (victim.guild == GIL_STONEGUARDIAN) && (self.aivar[AIV_EnemyOverride] == TRUE) * *{ * * * *// пробуждение каменного стража наблюдателя * * * *B_AWAKE_STONEGUARDIAN(self); * *}; * * *// если гильдии наблюдателя и жертвы дружественны и гильдии наблюдателя и агрессора не дружественные * *if(Wld_GetGuildAttitude(self.guild,victim.guild) == ATT_FRIENDLY) && (Wld_GetGuildAttitude(self.guild,other.guild) != ATT_FRIENDLY) * *{ * * * *Npc_ClearAIQueue(self); * * * *B_ClearPerceptions(self); * * * *Npc_SetTarget(self,other); * * * *// наблюдатель атакует агрессора * * * *AI_StartState(self,ZS_MM_Attack,0,""); * * * *return; * *}; * *// если гильдии наблюдателя и агрессора дружественны и гильдии наблюдателя и жертвы не дружественные * *if(Wld_GetGuildAttitude(self.guild,other.guild) == ATT_FRIENDLY) && (Wld_GetGuildAttitude(self.guild,victim.guild) != ATT_FRIENDLY) * *// и жертва не мертва * *&& (!Npc_IsDead(victim)) * *{ * * * *Npc_ClearAIQueue(self); * * * *B_ClearPerceptions(self); * * * *Npc_SetTarget(self,victim); * * * *// наблюдатель атакует жертву * * * *AI_StartState(self,ZS_MM_Attack,0,""); * * * *return; * *}; };
|
|
|
16.02.2005, 09:11
|
#103
|
|
Re: Уроки скриптологии
// ************************************************** **** // Функция реакции монстров на предупреждение // ------------------------------------------------------ // Предупреждение посылается только скриптами (вызов функции Npc_SendPassivePerc), ядром не испоьзуется // ************************************************** ****
func void B_MM_AssessWarn() { * *// self - наблюдатель, other - агрессор, victim - жертва * *// если наблюдатель орк * *if(self.guild > GIL_SEPERATOR_ORC) * *{ * * * *// если наблюдатель находится в состоянии атаки * * * *if(Npc_IsInState(self,ZS_MM_Attack)) * * * *{ * * * * * *return; * * * *}; * * * *// если гильдия наблюдателя дружественна гильдии агрессора * * * *if(Wld_GetGuildAttitude(self.guild,other.guild) == ATT_FRIENDLY) * * * *{ * * * * * *// очистка очереди AI команд наблюдателя * * * * * *Npc_ClearAIQueue(self); * * * * * *// установка жертвы в качестве цели наблюдателю * * * * * *Npc_SetTarget(self,victim); * * * * * *// очистка восприятий наблюдателя * * * * * *B_ClearPerceptions(self); * * * * * *// наблюдатель атакует жертву * * * * * *AI_StartState(self,ZS_MM_Attack,0,""); * * * * * *return; * * * *}; * * * *return; * *}; * *// если агрессор человек * *if(other.guild < GIL_SEPERATOR_HUM) * *{ * * * *return; * *}; * *// если расстояние по высоте между наблюдателем и агрессором > дистанции реагирования по высоте * *if(Npc_GetHeightToNpc(self,other) > PERC_DIST_HEIGHT) * *{ * * * *return; * *}; * *// если наблюдатель находится в состоянии атаки * *if(Npc_IsInState(self,ZS_MM_Attack)) * *{ * * * *// если наблюдателя устраивает добыча в виде агрессора и приоритет наблюдателя "пожирание падали" * * * *if(C_PredatorFoundPrey(self,other)) && (self.aivar[AIV_MM_PRIORITY] == PRIO_EAT) * * * *{ * * * * * *// очистка очереди AI команд наблюдателя * * * * * *Npc_ClearAIQueue(self); * * * * * *// установка агрессора в качестве цели наблюдателю * * * * * *Npc_SetTarget(self,other); * * * *} * * * *else // иначе цель не меняется * * * *{ * * * * * *// возврат цели для наблюдателя (последняя бывшая цель) * * * * * *other = Hlp_GetNpc(self.aivar[AIV_LASTTARGET]); * * * *}; * * * *return; * *}; * *// если гильдии наблюдателя и агрессора одинаковы и наблюдатель охотится стаей * *if(self.guild == other.guild) && (self.aivar[AIV_MM_Packhunter] == TRUE) * *{ * * * *// если наблюдатель волк и жертва волк и жертва ГГ (превращенный в волка) * * * *if(self.guild == GIL_WOLF) && (victim.guild == GIL_WOLF) && Npc_IsPlayer(victim) * * * *{ * * * * * *return; * * * *}; * * * *// если агрессор находится в состоянии атаки * * * *if(Npc_IsInState(other,ZS_MM_Attack)) * * * *{ * * * * * *Npc_ClearAIQueue(self); * * * * * *Npc_SetTarget(self,victim); * * * * * *B_ClearPerceptions(self); * * * * * *// наблюдатель атакует жертву * * * * * *AI_StartState(self,ZS_MM_Attack,0,""); * * * * * *return; * * * *}; * * * *// если агрессор находится в состоянии угрозы врагу * * * *if(Npc_IsInState(other,ZS_MM_ThreatenEnemy)) * * * *{ * * * * * *// агрессор бежит * * * * * *AI_SetWalkmode(self,NPC_RUN); * * * * * *// к жертве * * * * * *AI_GotoNpc(self,victim); * * * * * *return; * * * *}; * *}; * *return; };
... и еще одна функция
// ************************************************** ****** // Функция реакции монстров на ГГ // -------------------------------------------------------- // Вызывается ядром системы в качестве реакции на активное восприятие PERC_ASSESSPLAYER // Используется только конкретными монстрами // ************************************************** ******
func void B_MM_AssessPlayer() { * *// other - ГГ, self - монстр * *// если ГГ в состоянии диалога * *if(other.aivar[AIV_INVINCIBLE] == TRUE) * *{ * * * *return; * *}; * *// если ГГ мертв, безсознания и т.д. (обездвижен) * *if(C_NpcIsDown(other)) * *{ * * * *return; * *}; * *// подготовка разговора ГГ с драконами * *B_AssignDragonTalk(self); * *// если расстояние между ГГ и монстром < 7м и монстр имеет важную информацию * *if(Npc_GetDistToNpc(self,other) <= 700) && (Npc_CheckInfo(self,1)) * *{ * * * *// если монстр дракон или (монстр не дракон и расстояние между монстром и ГГ <= дистанции начала диалога) * * * *if(self.guild == GIL_DRAGON) ¦¦ ((self.guild != GIL_DRAGON) && (Npc_GetDistToNpc(self,other) <= PERC_DIST_DIALOG)) * * * *{ * * * * * *// если ГГ не падает и не плывет и не ныряет * * * * * *if(!C_BodyStateContains(other,BS_FALL)) && (!C_BodyStateContains(other,BS_SWIM)) && (!C_BodyStateContains(other,BS_DIVE)) * * * * * *{ * * * * * * * *// у монстра устанавливается флаг начала разговора * * * * * * * *self.aivar[AIV_NpcStartedTalk] = TRUE; * * * * * * * *// реакция ГГ на предлагаемый разговор * * * * * * * *B_AssessTalk(); * * * * * * * *return; * * * * * *}; * * * *}; * *}; * *// если монстр член партии ГГ * *if(self.aivar[AIV_PARTYMEMBER] == TRUE) * *{ * * * *// если расстояние между ГГ и монстром < 5м и монстр не стоит * * * *if(Npc_GetDistToNpc(self,hero) < 500) && (!C_BodyStateContains(self,BS_STAND)) * * * *{ * * * * * *// очистка очереди AI состояний монстра * * * * * *Npc_ClearAIQueue(self); * * * * * *// монстр останавливается * * * * * *AI_StandUp(self); * * * * * *// и поворачивается к ГГ * * * * * *AI_TurnToNpc(self,hero); * * * *}; * *}; };
Все файлы активных и пассивных восприятий монстров находятся в директории ..\AI\Monster\B_Monster\ и имеют имена эквивалентные функциям восприятий.
|
|
|
17.02.2005, 09:40
|
#104
|
|
Re: Уроки скриптологии
7. Описание обработчиков состояний НПС.
Все имена функций состояний должны начинаться с ZS_. Каждый процесс обработки соответствующего состояния состоит из 3х функций: ZS_xxx, ZS_xxx-Loop, ZS_xxx_End, где ххх - имя соответствующего состояния. Этим функциям соответствуют 3 фазы одного состояния НПС. 1 фаза - Begin: инициализация состояния НПС. 2 фаза - Loop: цикл выполнения последовательности действий НПС. Функция 2 фазы должна возвращать или LOOP_CONTINUE - продолжение фазы или LOOP_END - конец фазы. 3 фаза - End: завершение состояния НПС.
Системная функция AI_StartState может управлять последовательностью выполнения фаз состояний, за это отвечает параметр stateBehaviour, если он = 0, то выполняются все фазы состояния последовательно, если он = 1, то выполняется только заключительная фаза 3. Эта функция подробно описана в соответствующей теме.
8. Функции состояний людей.
Все файлы состояний людей расположены в директории ..AI\Human\ZS_Human
// ****************************** // Состояние атаки // ******************************
// Функция обработки вспомогательного восприятия PERC_ASSESSSURPRISE // Вызывается ядром системы когда ГГ превращается в человека из животного func void B_AssessSurprise() { * *// self - наблюдатель, other - ГГ * *// целью наблюдателя становится ГГ * *Npc_SetTarget(self,other); * *// причина нападения наблюдателя на ГГ - ГГ враг гильдии * *self.aivar[AIV_ATTACKREASON] = AR_GuildEnemy; };
// Функция инициализации состояния атаки func void ZS_Attack() { * *// установить минимальный набор восприятий НПС * *Perception_Set_Minimal(); * *// установить дополнительное восприятие на превращение * *Npc_PercEnable(self,PERC_ASSESSSURPRISE,B_AssessS urprise); * *// инициализировать переменную other (последняя цель) * *B_ValidateOther(); * *// записать НПС id последней цели * *self.aivar[AIV_LASTTARGET] = Hlp_GetInstanceID(other); * *// если НПС должен убегать от цели * *if(C_WantToFlee(self,other)) * * * * * * * * * * * *{ * * * *// очистка очереди AI состояний НПС * * * *Npc_ClearAIQueue(self); * * * *// очистка восприятий НПС * * * *B_ClearPerceptions(self); * * * *// установка цели для НПС * * * *Npc_SetTarget(self,other); * * * *// НПС убегает от цели * * * *AI_StartState(self,ZS_Flee,0,""); * * * *return; * *}; * *// если загрузки игры во время атаки не было * *if(self.aivar[AIV_LOADGAME] == FALSE) * *{ * * * *// НПС называет причину атаки * * * *B_Say_AttackReason(); * *}; * *// если режим сражения у НПС выключен * *if(Npc_IsInFightMode(self,FMODE_NONE)) * *{ * * * *// НПС достает лучшее оружие дальнего радиуса поражения * * * *AI_EquipBestRangedWeapon(self); * * * *// НПС достает лучшее оружие ближнего радиуса поражения * * * *AI_EquipBestMeleeWeapon(self); * *}; * *// НПС встает * *AI_StandUp(self); * *// перестает смотреть на других * *B_StopLookAt(self); * *// поворачивается к цели * *B_TurnToNpc(self,other); * *// бежит к цели * *AI_SetWalkmode(self,NPC_RUN); * *// сброс статуса предупреждений охраной * *self.aivar[AIV_Guardpassage_Status] = GP_NONE; * *// получить репутацию ГГ для конкретной локации * *self.aivar[AIV_LastAbsolutionLevel] = B_GetCurrentAbsolutionLevel(self); * *// сброс флага окончания преследования * *self.aivar[AIV_PursuitEnd] = FALSE; * *// сброс времени нахождения в состоянии * *self.aivar[AIV_StateTime] = 0; * *// сброс переменной вызова охраны (переменная AIV_TAPOSITION переопределена в этом состоянии) * *self.aivar[AIV_TAPOSITION] = 0; * *// сброс флага первого удара * *self.aivar[AIV_HitByOtherNpc] = 0; * *// сброс выбранного заклинания * *self.aivar[AIV_SelectSpell] = 0; };
// Функция цикла атаки func int ZS_Attack_Loop() { * *// Грег идет к Декстеру * *B_Greg_ComesToDexter(); * *// повторно инициализировать other целью * *Npc_GetTarget(self); * *// если расстояние между НПС и целью > дистанции прекращения сражения * *if(Npc_GetDistToNpc(self,other) > self.aivar[AIV_FightDistCancel]) * *{ * * * *// очистка очереди 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); * * * *// если цель человек * * * *if(other.guild < GIL_SEPERATOR_HUM) * * * *{ * * * * * *// НПС говорит цели "Беги, трус!" (SVM фраза) * * * * * *B_Say(self,other,"$RUNCOWARD"); * * * *}; * *}; * *// если НПС завершил преследование цели * *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 * * * * * *{ * * * * * * * *// НПС поворачивается к цели * * * * * * * *B_TurnToNpc(self,other); * * * * * * * *// получить дистанцию до цели * * * * * * * *self.aivar[AIV_Dist] = Npc_GetDistToNpc(self,other); * * * * * * * *// обновить время состояния НПС * * * * * * * *self.aivar[AIV_StateTime] = Npc_GetStateTime(self); * * * * * *}; * * * *}; * * * *return LOOP_CONTINUE; * *}; * *// если уровень достигнутый ГГ в сражении > первоначального уровня * *if(B_GetCurrentAbsolutionLevel(self) > self.aivar[AIV_LastAbsolutionLevel]) * *{ * * * *// очистка очереди AI состояний НПС * * * *Npc_ClearAIQueue(self); * * * *// НПС встает * * * *AI_StandUp(self); * * * *// прекращение атаки * * * *return LOOP_END; * *}; * *// если (цель плывет или ныряет) и НПС не преследует цель в воде * *if(C_BodyStateContains(other,BS_SWIM) ¦¦ C_BodyStateContains(other,BS_DIVE)) && (self.aivar[AIV_MM_FollowInWater] == FALSE) * *{ * * * *Npc_ClearAIQueue(self); * * * *AI_StandUp(self); * * * *// НПС закончил преследование * * * *self.aivar[AIV_PursuitEnd] = TRUE; * * * *return LOOP_END; * *}; * *// если НПС выжидает перед атакой * *if(self.aivar[AIV_WaitBeforeAttack] >= 1) * *{ * * * *// ожидание 0.8 сек * * * *AI_Wait(self,0.8 ); * * * *// сброс флага задержки * * * *self.aivar[AIV_WaitBeforeAttack] = 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_BodyStateContains(other,BS_RUN)) && (!C_BodyStateContains(other,BS_JUMP))) * *{ * * * *// сброс времени текущего состояния * * * *Npc_SetStateTime(self,0); * *}; * *// если время в состоянии > 2 сек (от последнего сброса) и охрана не вызывалась * *if(Npc_GetStateTime(self) > 2) && (self.aivar[AIV_TAPOSITION] == 0) * *{ * * * *// вызов охраны * * * *B_CallGuards(); * * * *// установка следующей фазы вызова охраны * * * *self.aivar[AIV_TAPOSITION] = 1; * *}; * *// если время в состоянии > 8 сек и охрана вызывалась * *if(Npc_GetStateTime(self) > 8 ) && (self.aivar[AIV_TAPOSITION] == 1) * *{ * * * *// вызов охраны * * * *B_CallGuards(); * * * *// установка следующей фазы вызова охраны (было 2 вызова) * * * *self.aivar[AIV_TAPOSITION] = 2; * *}; * *// подготовка НПС боезапаса * *B_CreateAmmo(self); * *// выбор соответствующего цели оружия * *B_SelectWeapon(self,other); * *// если цель существует и не обездвижена * *if((Hlp_IsValidNpc(other)) && (C_NpcIsDown(other) == FALSE)) * *{ * * * *// если цель не в состоянии разговора * * * *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 // иначе (если цель отсутствует или обездвижена) * *{ * * * *// очистка очереди AI состояний НПС * * * *Npc_ClearAIQueue(self); * * * *// если цель существует и цель ГГ и ГГ обездвижен * * * *if(Hlp_IsValidNpc(other)) && (Npc_IsPlayer(other)) && (C_NpcIsDown(other)) * * * *{ * * * * * *// замена временного отношения НПС к ГГ на постоянное * * * * * *Npc_SetTempAttitude(self,Npc_GetPermAttitude(self ,hero)); * * * *}; * * * *// если причина атаки НПС не убийство цели * * * *if(self.aivar[AIV_ATTACKREASON] != AR_KILL) * * * *{ * * * * * *// НПС разрешено воспринимать все объекты * * * * * *Npc_PerceiveAll(self); * * * * * *// НПС ищет новую цель other * * * * * *Npc_GetNextTarget(self); * * * *}; * * * *// если цель существует и она не обездвижена * * * *if(Hlp_IsValidNpc(other)) && (!C_NpcIsDown(other)) * * * *// и (расстояние от НПС до цели < дистанции восприятия или цель ГГ) * * * *&& ((Npc_GetDistToNpc(self,other) < PERC_DIST_INTERMEDIAT) ¦¦ (Npc_IsPlayer(other))) * * * *// и расстояние между НПС и целью по высоте < дистанции восприятия по высоте * * * *&& (Npc_GetHeightToNpc(self,other) < PERC_DIST_HEIGHT) * * * *// и цель не в разговоре * * * *&& (other.aivar[AIV_INVINCIBLE] == FALSE) * * * *// и цель ГГ не является переодетым бандитом и НПС бандит * * * *&& (!(C_PlayerIsFakeBandit(self,other) && (self.guild == GIL_BDT))) * * * *{ * * * * * *// если гильдии НПС и цели враждебны * * * * * *if(Wld_GetGuildAttitude(self.guild,other.guild) == ATT_HOSTILE) * * * * * *{ * * * * * * * *// причина атаки - враждебная гильдия * * * * * * * *self.aivar[AIV_ATTACKREASON] = AR_GuildEnemy; * * * * * * * *// если цель ГГ * * * * * * * *if(Npc_IsPlayer(other)) * * * * * * * *{ * * * * * * * * * *// установить причину последнего нападения на ГГ * * * * * * * * * *self.aivar[AIV_LastPlayerAR] = AR_GuildEnemy; * * * * * * * * * *// параметр последнего сражения с ГГ - прервано * * * * * * * * * *self.aivar[AIV_LastFightAgainstPlayer] = FIGHT_CANCEL; * * * * * * * * * *// сброс комментария сражения * * * * * * * * * *self.aivar[AIV_LastFightComment] = FALSE; * * * * * * * *}; * * * * * *} * * * * * *// иначе, если сам НПС является врагом цели * * * * * *else if(Npc_GetAttitude(self,other) == ATT_HOSTILE) * * * * * *{ * * * * * * * *// причина атаки = причину последнего нападения на ГГ * * * * * * * *self.aivar[AIV_ATTACKREASON] = self.aivar[AIV_LastPlayerAR]; * * * * * *}; * * * * * *return LOOP_CONTINUE; * * * *} * * * *else * * * *{ * * * * * *// очистка очереди AI состояний НПС * * * * * *Npc_ClearAIQueue(self); * * * * * *// если последнее сражение с ГГ прервано и последняя цель не ГГ * * * * * *if(self.aivar[AIV_LastFightAgainstPlayer] == FIGHT_CANCEL) && (self.aivar[AIV_LASTTARGET] != Hlp_GetInstanceID(hero)) * * * * * *{ * * * * * * * *// комментировать сражение не нужно * * * * * * * *self.aivar[AIV_LastFightComment] = TRUE; * * * * * *}; * * * * * *return LOOP_END; * * * *}; * *}; };
//Функция завершения состояния атаки func void ZS_Attack_End() { * *// установить other на последнюю цель * *other = Hlp_GetNpc(self.aivar[AIV_LASTTARGET]); * *// усли преследование было прекращено * *if(self.aivar[AIV_PursuitEnd] == TRUE) * *{ * * * * * * *// если цель существует и цель ГГ и НПС не друг цели * * * *if(Hlp_IsValidNpc(other)) && (Npc_IsPlayer(other)) && (self.npctype != NPCTYPE_FRIEND) * * * *{ * * * * * *// установить временное отношение НПС к ГГ на враждебное * * * * * *Npc_SetTempAttitude(self,ATT_HOSTILE); * * * *}; * * * *// если НПС сражался на арене (состояние - в процессе сражения) * * * *if(self.aivar[AIV_ArenaFight] == AF_RUNNING) * * * *{ * * * * * *// установить состояние после сражения * * * * * *self.aivar[AIV_ArenaFight] = AF_AFTER; * * * *}; * *}; * *// если преследования не было * *if(self.aivar[AIV_PursuitEnd] == FALSE) * *{ * * * *// если уровень достигнутый ГГ в сражении > первоначального уровня * * * *if(B_GetCurrentAbsolutionLevel(self) > self.aivar[AIV_LastAbsolutionLevel]) * * * *{ * * * * * *// НПС говорит цели "Умный малый!" (SVM фраза) * * * * * *B_Say(self,other,"$WISEMOVE"); * * * *} * * * *else * * * *{ * * * * * *// обычная фраза завершения атаки * * * * * *B_Say_AttackEnd(); * * * *}; * *}; * *// если цель убита ГГ и отношения гильдий НПС и ГГ не враждебные * *if(other.aivar[AIV_KilledByPlayer] == TRUE) && (Wld_GetGuildAttitude(self.guild,hero.guild) != ATT_HOSTILE) * *{ * * * *// НПС становится другом ГГ * * * *B_SetAttitude(self,ATT_FRIENDLY); * *}; * *// если цель находится безсознания и причиной атаки было убийство цели * *if(Npc_IsInState(other,ZS_Unconscious)) && (C_NpcHasAttackReasonToKill(self)) * *{ * * * *// НПС добивает цель * * * *B_FinishingMove(self,other); * *}; * *// НПС прячет оружие * *AI_RemoveWeapon(self); * *// если цель обездвижена и НПС может обыскать цель и (цель не обыскивалась или должна быть обыскана) * *if(C_NpcIsDown(other)) && (C_WantToRansack(self)) && ((other.aivar[AIV_RANSACKED] == FALSE) ¦¦ C_NpcRansacksAlways(self)) * *// и расстояние между НПС и целью < дистанции восприятия * *&& (Npc_GetDistToNpc(self,other) < PERC_DIST_INTERMEDIAT) * *{ * * * *// установка флага, что цель обыскана * * * *other.aivar[AIV_RANSACKED] = TRUE; * * * *// цель человек * * * *if(other.guild < GIL_SEPERATOR_HUM) * * * *{ * * * * * *// переход НПС в состояние грабежа цели * * * * * *AI_StartState(self,ZS_RansackBody,0,""); * * * * * *return; * * * *} * * * *else // (не человек) * * * *{ * * * * * *// если НПС "Аллигатор Джек" и цель имеет "Сырое мясо" * * * * * *if(Hlp_GetInstanceID(self) == Hlp_GetInstanceID(AlligatorJack)) && (Npc_HasItems(other,ItFoMuttonRaw) > 0) * * * * * *{ * * * * * * * * *// Джек ест мясо * * * * * * * *AI_StartState(self,ZS_GetMeat,0,""); * * * * * * * *return; * * * * * *}; * * * *}; * *}; * *// если жизнь НПС меньше половинной * *if(self.attribute[ATR_HITPOINTS] < (self.attribute[ATR_HITPOINTS_MAX]/2)) * *{ * * * *// НПС лечит себя * * * *AI_StartState(self,ZS_HealSelf,0,""); * * * *return; * *}; };
|
|
|
18.02.2005, 09:54
|
#105
|
|
Re: Уроки скриптологии
// ************************************************** ***** // Состояние защиты своего помещения // ************************************************** ***** // Здесь: self - НПС хозяин помещения, other - "незванный гость" (ГГ) // ************************************************** *****
// Функция обработки восприятия разговора (вызывается когда ГГ обращается к НПС хозяину) func void B_ClearRoomTalk() { * *// если НПС хочет напасть на "гостя" * *if(C_WantToAttackRoomIntruder(self)) * *{ * * * *// НПС предупреждает "гостя" (SVM фраза "Пошел вон!") * * * *B_Say(self,other,"$GETOUTOFHERE"); * *} * *else * *{ * * * *// НПС спрашивает "гостя" (SVM фраза "Что ты тут ищешь!?") * * * *B_Say(self,other,"$WHYAREYOUINHERE"); * *}; };
// Функция обработки восприятия выхода ГГ из помещения // Возвращает TRUE если ГГ покинул помещение, иначе - FALSE func int B_ExitIfRoomLeft() { * *var int portalguild; * *// получить номер гильдии, которой принадлежит помещение (-1 помещение никому не принадлежит) * *portalguild = Wld_GetPlayerPortalGuild(); * *// если ГГ покинул помещение или помещение публичное * *if(!C_NpcIsBotheredByPlayerRoomGuild(self)) ¦¦ (portalguild == GIL_PUBLIC) * *{ * * * *// очистка очереди AI состояний НПС * * * *Npc_ClearAIQueue(self); * * * *// НПС встает * * * *AI_StandUp(self); * * * *// НПС перестает смотреть на ГГ * * * *B_StopLookAt(self); * * * *// если НПС хочет напасть на "гостя" * * * *if(C_WantToAttackRoomIntruder(self)) * * * *{ * * * * * *// НПС говорит "гостю" (SVM фраза "Да, иди прочь!") * * * * * *B_Say(self,other,"$YESGOOUTOFHERE"); * * * *} * * * *else * * * *{ * * * * * *// НПС говорит "гостю" (SVM фраза "Умный малый!") * * * * * *B_Say(self,other,"$WISEMOVE"); * * * *}; * * * *// НПС продолжает выполнение распорядка дня * * * *AI_ContinueRoutine(self); * * * *return TRUE; * *}; * *return FALSE; };
// Инициализация состояния защиты помещения func void ZS_ClearRoom() { * * *// установить минимальный набор восприятий НПС * *Perception_Set_Minimal(); * *// заменить восприятие входа в помещение на восприятие выхода "гостя" из помещения * *Npc_PercEnable(self,PERC_ASSESSENTERROOM,B_ExitIf RoomLeft); * *// включить восприятие на перемещение МОВа * *Npc_PercEnable(self,PERC_MOVEMOB,B_MoveMob); * *// заменить восприятие разговора НПС * *Npc_PercEnable(self,PERC_ASSESSTALK,B_ClearRoomTa lk); * *// НПС встает * *AI_StandUp(self); * *// НПС смотрит на "гостя" * *B_LookAtNpc(self,other); * *// НПС бежит к "гостю" * *AI_SetWalkmode(self,NPC_RUN); * *// если НПС находится вне помещения * *if(!Npc_IsInPlayersRoom(self)) * * *{ * * * *// НПС бежит в точку, ближайшую к ГГ * * * *AI_GotoWP(self,Npc_GetNearestWP(other)); * *}; * *// установка признака входа в цикл * *self.aivar[AIV_TAPOSITION] = NOTINPOS; };
// Функция цикла защиты помещения func int ZS_ClearRoom_Loop() { * *// если осуществен первый вход в цикл * *if(self.aivar[AIV_TAPOSITION] == NOTINPOS) * *{ * * * *// НПС поворачивается к "гостю" * * * *B_TurnToNpc(self,other); * * * *// если НПС хочет напасть на "гостя" * * * *if(C_WantToAttackRoomIntruder(self)) * * * *{ * * * * * *// НПС выбирает соответствующее "гостю" оружие * * * * * *B_SelectWeapon(self,other); * * * * * *// НПС предупреждает "гостя" (SVM фраза "Пошел вон!") * * * * * *B_Say(self,other,"$GETOUTOFHERE"); * * * *} * * * *else * * * *{ * * * * * *// если НПС не является другом "гостя" * * * * * *if(Npc_GetAttitude(other,self) != ATT_FRIENDLY) * * * * * *{ * * * * * * * *// НПС спрашивает "гостя" (SVM фраза "Что ты тут ищешь!?") * * * * * * * *B_Say(self,other,"$WHYAREYOUINHERE"); * * * * * *}; * * * *}; * * * *// сброс времени нахождения НПС в этом состоянии * * * *Npc_SetStateTime(self, 0); * * * *// закрытие первого входа в цикл * * * *self.aivar[AIV_TAPOSITION] = ISINPOS; * *}; * *// если ГГ покинул помещение * *if(B_ExitIfRoomLeft()) * *{ * * * *return LOOP_END; * *}; * *// если НПС хочет напасть на "гостя" * *if(C_WantToAttackRoomIntruder(self)) * *{ * * * *// если с момента входа в помещение прошло > 5 сек * * * *if(Npc_GetStateTime(self) > 5) * * * *{ * * * * * *// НПС атакует "гостя" * * * * * *B_Attack(self,other,AR_ClearRoom,0); * * * * * *return LOOP_END; * * * *}; * *} * *else // НПС не хочет нападать (повторяется каждые две секунды) * *{ * * * *// если с момента входа в помещение прошло >= 2 сек * * * *if(Npc_GetStateTime(self) >= 2) * * * *{ * * * * * *// если НПС не видит "гостя" по прямой * * * * * *if(!Npc_CanSeeNpcFreeLOS(self,other)) * * * * * * *{ * * * * * * * *// НПС бежит в точку, ближайшую к ГГ * * * * * * * *AI_GotoWP(self,Npc_GetNearestWP(other)); * * * * * * * *// НПС поворачивается к "гостю" * * * * * * * *B_TurnToNpc(self,other); * * * * * *} * * * * * *// иначе, если НПС вообще не видит "гостя" * * * * * *else if(!Npc_CanSeeNpc(self,other)) * * * * * *{ * * * * * * * * *// НПС поворачивается в направлении "гостя" * * * * * * * *B_TurnToNpc(self,other); * * * * * *}; * * * * * *// сброс времени состояния * * * * * *Npc_SetStateTime(self,0); * * * *}; * *}; * *return LOOP_CONTINUE; };
// Функция выхода из состояния защиты помещения func void ZS_ClearRoom_End() { * *// НПС перестает смотреть на "гостя" * *B_StopLookAt (self); };
|
|
|
19.02.2005, 15:49
|
#106
|
|
Re: Уроки скриптологии
// ************************************************** ** // Обработчик состояния когда НПС убегает от агрессора // ---------------------------------------------------- // self - убегающий НПС, other - агрессор // ************************************************** **
// Функция инициализации состояния func void ZS_Flee() { * * *// разрешить восприятие примененной магии * *Npc_PercEnable(self,PERC_ASSESSMAGIC,B_AssessMagi c); * * * * * * * *// получить other - агрессор * *B_ValidateOther(); * *// если загрузки игры не было * *if(self.aivar[AIV_LOADGAME] == FALSE) * *{ * * * *// НПС кричит агрессору (SVM фраза "Я сматываюсь!") * * * *B_Say_Overlay(self,other,"$RUNAWAY"); * *}; * *// НПС прячет оружие * *AI_RemoveWeapon(self); * *// НПС переходит на бег * *AI_SetWalkmode(self,NPC_RUN); * *// проигрывается анимация убегающего человека * *Mdl_ApplyOverlayMds(self,"HUMANS_FLEE.MDS"); };
// Цикл состояния убегания func int ZS_Flee_Loop() { * *// получить для НПС цель (инициализировать other агрессором) * *Npc_GetTarget(self); * *// если расстояние между НПС и агрессором > дистанции преследования * *if(Npc_GetDistToNpc(self,other) > FIGHT_DIST_CANCEL) * *{ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *// очистка очереди AI состояний НПС * * * *Npc_ClearAIQueue(self); * * * *return LOOP_END; * * * * * * * * * * * * * * * * * * * *}; * *// если агрессор обездвижен (мертв, безсознания и т.д.) * *if(C_NpcIsDown(other)) * *{ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *// очистка очереди AI состояний НПС * * * *Npc_ClearAIQueue(self); * * * *return LOOP_END; * *}; * *// НПС продолжает убегать * *AI_Flee(self); * *return LOOP_CONTINUE; };
// Функция завершения состояния убегания func void ZS_Flee_End() { * *// прекратить проигрывание анимации убегающего человека * *Mdl_RemoveOverlayMDS(self,"HUMANS_FLEE.MDS"); * *// НПС останавливается * *AI_StandUp(self); * *// вызов функции завершения состояния лечения НПС * *AI_StartState(self,ZS_HealSelf,1,""); * *return; };
... еще описание одного состояния
// ********************************* // Обработчик состояния лечения НПС // *********************************
// Инициализация состояния func void ZS_HealSelf() { * *// разрешить НПС минимальный набор восприятий * *Perception_Set_Minimal(); };
// Цикл состояния func int ZS_HealSelf_Loop() { * *// если текущая жизнь НПС равняется максимальной * *if(self.attribute[ATR_HITPOINTS] == self.attribute[ATR_HITPOINTS_MAX]) * *{ * * * *// очистка очереди AI состояний НПС * * * *Npc_ClearAIQueue(self); * * * *return LOOP_END; * *}; * *// если НПС имеет "Лечебный эликсир" * *if(Npc_HasItems(self,ItPo_Health_03) > 0) * * * * * * *{ * * * *// НПС пьет "Лечебный эликсир" * * * *AI_UseItem(self,ItPo_Health_03); * * * *return LOOP_CONTINUE; * *} * *// если НПС имеет "Лечебный экстракт" * *else if(Npc_HasItems(self,ItPo_Health_02) > 0) * *{ * * * *// НПС пьет "Лечебный экстракт" * * * *AI_UseItem(self,ItPo_Health_02); * * * *return LOOP_CONTINUE; * *} * *// если НРС имеет "Лечебную эссенцию" * *else if(Npc_HasItems(self,ItPo_Health_01) > 0) * *{ * * * *// НПС пьет "Лечебную эссенцию" * * * *AI_UseItem(self,ItPo_Health_01); * * * *return LOOP_CONTINUE; * *} * *else //иначе * *{ * * * *// очистка очереди AI состояний НПС * * * *Npc_ClearAIQueue(self); * * * *return LOOP_END; * *}; };
// Функция завершения состояния лечения func void ZS_HealSelf_End() { };
|
|
|
20.02.2005, 11:54
|
#107
|
|
Re: Уроки скриптологии
// ******************************************* // Обработчик состояния наблюдения НПС за ГГ // ------------------------------------------- // self - наблюдающий НПС, other - ГГ // *******************************************
// Инициализация наблюдения func void ZS_ObservePlayer() { * * *// установить НПС нормальный набор восприятий * *Perception_Set_Normal(); * *// если НПС не сидит * *if(!C_BodystateContains(self,BS_SIT)) * *{ * * * *// НПС останавливается * * * *AI_StandUp(self); * * * *// НПС смотрит на ГГ * * * *B_LookAtNpc(self,other); * * * *// НПС поворачивается к ГГ * * * *B_TurnToNpc(self,other); * *} * *else // иначе (если НПС сидит) * *{ * * * *// НПС смотрит на ГГ * * * *B_LookAtNpc(self,other); * *}; * *// если в предудущем состоянии НПС спал * *if(Npc_WasInState(self,ZS_Sleep)) * *{ * * * *// НПС спрашивает ГГ (SVM фраза "Что случилось?") * * * *B_Say(self,other,"$YOUDISTURBEDMYSLUMBER"); * *}; * *// если НПС наблюдает за своим помещением и other есть ГГ * *if(self.aivar[AIV_SeenLeftRoom] == TRUE) && (Npc_IsPlayer(other)) * *{ * * * *// сброс наблюдения за своим помещением * * * *self.aivar[AIV_SeenLeftRoom] = FALSE; * * * *// если комментария входа в чужое помещение не было * * * *if(Player_LeftRoomComment == FALSE) * * * *{ * * * * * *// НПС говорит ГГ (SVM фраза "Чего ты там ищешь?") * * * * * *B_Say(self,other,"$WHATDIDYOUDOINTHERE"); * * * * * *// установка флага состоявшегося комментария * * * * * *Player_LeftRoomComment = TRUE; * * * *}; * *}; * *// установить время нахождения НПС в этом состоянии (1 или 2 сек) * *self.aivar[AIV_StateTime] = (Hlp_Random(2) + 1); };
// Цикл состояния наблюдения func int ZS_ObservePlayer_Loop () { * *// если ГГ крадется и комментария подкрадывания не было * *if(C_BodyStateContains(other,BS_SNEAK)) && (Player_SneakerComment == FALSE) * *{ * * * * *// установка флага состоявшегося комментария * * * *Player_SneakerComment = TRUE; * * * *// НПС показывает на ГГ * * * *AI_PointAtNpc(self,other); * * * *// НПС говорит ГГ (SVM фраза "Эй, ты! Что ты там шастаешь?") * * * *B_Say(self,other,"$WHATSTHISSUPPOSEDTOBE"); * * * *// НПС перестает указывать на ГГ * * * *AI_StopPointAt(self); * * * *// НПС посылает ГГ предупреждение * * * *Npc_SendPassivePerc(self,PERC_ASSESSWARN,self,oth er); * *}; * *// если время нахождения в состоянии > 1 или 2 сек * *if(Npc_GetStateTime(self) > self.aivar[AIV_StateTime]) * *{ * * * *// если НПС не сидит * * * *if(!C_BodystateContains(self,BS_SIT)) * * * *{ * * * * * *// НПС поворачивается к ГГ * * * * * *B_TurnToNpc(self,other); * * * *}; * * * *// установить время нахождения НПС в этом состоянии (1 или 2 сек) * * * *self.aivar[AIV_StateTime] = (Hlp_Random(2) + 1); * * * *// сброс времени состояния * * * *Npc_SetStateTime(self,0); * *}; * *// если расстояние между НПС и ГГ > дальности действия восприятия * *if(Npc_GetDistToNpc(self,other) > PERC_DIST_INTERMEDIAT) * *{ * * * *// очистка очереди состояний НПС * * * *Npc_ClearAIQueue(self); * * * *return LOOP_END; * *} * *else // [Прим. else здесь лишнее, можно просто: return LOOP_CONTINUE;] * *{ * * * *return LOOP_CONTINUE; * *}; };
// Выход из состояния наблюдения func void ZS_ObservePlayer_End () { * *// НПС перестает смотреть на ГГ * *B_StopLookAt(self); };
|
|
|
20.02.2005, 13:18
|
#108
|
|
|
|
|
Регистрация: 15.04.2004
Адрес: Санкт-Петербург
Сообщений: 372
|
|
|
|
|
|
Re: Уроки скриптологии
2Vam:
В посте №136 этой темы товарищ TycoooN предложил Вашему вниманию первую часть уроков. Когда выйдет вторая часть, и кто её оформит, пока сказать не могу
|
Я еще несколько раз обновлял файл. На данный момент в нем не хватает постов 5-6 ::) Еще раз ссылка: http://gothic3.allgothic.ru/filezzz/Vam_tutor.rar
|
|
|
21.02.2005, 11:01
|
#109
|
|
Re: Уроки скриптологии
// ***************************************** // Обработчик состояния грабежа предметов с тел НПС // ----------------------------------------- // self - грабитель, other - тело // *****************************************
// Инициализация состояния func void ZS_RansackBody() { * *// установить грабителю нормальный набор восприятий * *Perception_Set_Normal(); * *// грабитель встает * *AI_StandUp(self); * *// грабитель идет к телу * *AI_GotoNpc(self,other); }; * * // Цикл грабежа func int ZS_RansackBody_Loop() { * *return LOOP_END; };
// Завершающая фаза грабежа func void ZS_RansackBody_End() { * * *// грабитель поворачивается к телу * *B_TurnToNpc(self,other); * * * *// включить анимацию грабежа * *AI_PlayAni(self,"T_PLUNDER"); * *// если тело имеет "Святой молот" и грабитель "Гарвиг" * *if(Npc_HasItems(other,Holy_Hammer_MIS) > 0) && (Hlp_GetInstanceID(self) == Hlp_GetInstanceID(Garwig)) * *{ * * * *// создать в инвентаре грабителя "Святой молот" * * * *CreateInvItems(self,Holy_Hammer_MIS,1); * * * *// удалить из инвентаря тела "Святой молот" * * * *Npc_RemoveInvItems(other,Holy_Hammer_MIS,1); * * * *}; * *// если тело имеет "Меч Рода" и грабитель "Род" * *if(Npc_HasItems(other,ItMw_2h_Rod) > 0) && (Hlp_GetInstanceID(self) == Hlp_GetInstanceID(Rod)) * *{ * * * *// переместить "Меч Рода" из инвентаря тела в инвентарь грабителя * * * *CreateInvItems(self,ItMw_2h_Rod,1); * * * *Npc_RemoveInvItems(other,ItMw_2h_Rod,1); * * * *// грабитель экипируется лучшим оружием ближнего радиуса поражения * * * *AI_EquipBestMeleeWeapon(self); * *}; * *// если тело имеет "Ключ к хибаре капитана Грега" и грабитель "Фрэнсис" * *if(Npc_HasItems(other,ITKE_Greg_ADDON_MIS)) && (Hlp_GetInstanceID(self) == Hlp_GetInstanceID(Francis)) * *{ * * * *// передать предмет грабителю * * * *CreateInvItems(self,ITKE_Greg_ADDON_MIS,1); * * * *Npc_RemoveInvItems(other,ITKE_Greg_ADDON_MIS,1); * *}; * * *// если тело имеет "Золото" * *if(Npc_HasItems(other,ItMi_Gold) > 0) * *{ * * * *var int x; * * * *// кол-во золота у тела * * * *x = Npc_HasItems(other,ItMi_Gold); * * * *// передать все золдото грабителю * * * *CreateInvItems(self,ItMi_Gold,x); * * * *Npc_RemoveInvItems(other,ItMi_Gold,x); * * * * * * * * * * *// грабитель говорит телу (SVM фраза "Спасибо за золото, герой!") * * * *B_Say(self,other,"$ITOOKYOURGOLD"); * *} * *else // иначе * *{ * * * *// грабитель говорит телу (SVM фраза "Ты, жалкое ничтожество, разве у тебя нет золота!") * * * *B_Say(self,other,"$SHITNOGOLD"); * *}; * *// грабителю разрешается воспринимать все объекты в зоне действия восприятий * *Npc_PerceiveAll(self); * *// если грабитель находит оружие ближнего или дальнего радиуса поражения * *if(Wld_DetectItem(self,ITEM_KAT_NF) ¦¦ Wld_DetectItem(self,ITEM_KAT_FF)) * *{ * * * *// если ссылка на предмет item существует * * * *if(Hlp_IsValidItem(item)) * * * *{ * * * * * *// если расстояние от грабителя до предмета < 5 метров * * * * * *if(Npc_GetDistToItem(self,item) < 500) * * * * * *{ * * * * * * * *// грабитель берет предмет * * * * * * * *AI_TakeItem(self,item); * * * * * * * *// грабитель говорит сам себе (SVM фраза "Твое оружие я возьму с собой.") * * * * * * * *B_Say(self,self,"$ITAKEYOURWEAPON"); * * * * * * * * * * * *// экипировка лучшим оружием * * * * * * * *AI_EquipBestMeleeWeapon(self); * * * * * * * *AI_EquipBestRangedWeapon(self); * * * * * *}; * * * *}; * *}; * *// если жизнь грабителя < половинной * *if(self.attribute[ATR_HITPOINTS] < (self.attribute[ATR_HITPOINTS_MAX]/2)) * *{ * * * *// переход в состояние самолечения * * * *AI_StartState(self,ZS_HealSelf,0,""); * * * *return; * *}; };
// *********************************************** // Обработчик состояния когда Джек забирает сырое мясо у жертвы // ----------------------------------------------- // self - НПС Джек, other - тело // ***********************************************
// Инициализация состояния func void ZS_GetMeat() { * * *// разрешить минимальный набор восприятий * *Perception_Set_Minimal(); * *// НПС встает * *AI_StandUp(self); * *// идет к телу * *AI_GotoNpc(self,other); * *// поворачивается к телу * *AI_TurnToNpc(self,other); * *// проигрывание анимации грабежа * *AI_PlayAni(self,"T_PLUNDER"); * *var int x; * *// кол-во "Сырого мяса" у тела * *x = Npc_HasItems(other,ItFoMuttonRaw); * *// передать мясо от тела НПС * *CreateInvItems(self,ItFoMuttonRaw,x); * *Npc_RemoveInvItems(other,ItFoMuttonRaw,x); * *// если жизнь НПС < половинной * *if(self.attribute[ATR_HITPOINTS] < (self.attribute[ATR_HITPOINTS_MAX]/2)) * *{ * * * *// переход в состояние самолечения * * * *AI_StartState(self,ZS_HealSelf,0,""); * * * *return; * *}; };
|
|
|
21.02.2005, 17:51
|
#110
|
|
Re: Уроки скриптологии
// ************************************************** ********** // Обработчик состояния реакции НПС на повреждение // ------------------------------------------------------------ // self - НПС, получивший повреждение, other - агрессор // ************************************************** **********
// Инициализация состояния func void ZS_ReactToDamage() { * * *// разрешить НПС нормальный набор восприятий * *Perception_Set_Normal(); * *// НПС смотрит на агрессора * *B_LookAtNpc(self,other); * *// НПС выбирает оружие для поражения агрессора * *B_SelectWeapon(self,other); * *// НПС поворачивается к агрессору * *B_TurnToNpc(self,other); * *// НПС говорит агрессору (SVM фраза "Парень, никогда так больше не делай!") * *B_Say (self, other, "$WHATAREYOUDOING"); * *// очистка счетчика секунд * *self.aivar[AIV_StateTime] = 0; };
// Цикл состояния func int ZS_ReactToDamage_Loop() { * *// если прошла одна секунда * *if(Npc_GetStateTime(self) > self.aivar[AIV_StateTime]) * *{ * * * *// если НПС не видит агрессора * * * *if(!Npc_CanSeeNpc(self,other)) * * * *{ * * * * * * *// НПС поворачивается к агрессору * * * * * *AI_TurnToNpc(self,other); * * * *}; * * * *// счетчик секунд ++ * * * *self.aivar[AIV_StateTime] = self.aivar[AIV_StateTime] + 1; * *}; * *// если прошло более 10 секунд * *if(Npc_GetStateTime (self) > 10) * *{ * * * *return LOOP_END; * *} * *else // [Примечание: else можно убрать, просто - return LOOP_CONTINUE;] * *{ * * * *return LOOP_CONTINUE; * *}; };
// Завершения состояния func void ZS_ReactToDamage_End() { * *// НПС убирает оружие * *AI_RemoveWeapon(self); * *// перестает смотреть на агрессора * *B_StopLookAt(self); };
... и еще один файл
// ******************************************** // Обработчик состояния реакции НПС на оружие // -------------------------------------------- // self - реагирующий НПС, other - агрессор // ********************************************
// Инициализация состояния func void ZS_ReactToWeapon() { * * *// разрешить НПС минимальный набор восприятий * *Perception_Set_Minimal(); * *// разрешить НПС восприятие сражения двух других НПС * *Npc_PercEnable(self,PERC_ASSESSFIGHTSOUND,B_Asses sFightSound); * *// реакция НПС на врага агрессора * *if(B_AssessEnemy()) * *{ * * * *return; * *}; * *// НПС встает * *AI_StandUp(self); * *// смотрит на агрессора * *B_LookAtNpc(self,other); * *// выбирает оружие * *B_SelectWeapon(self,other); * *// поворачивается к агрессору * *B_TurnToNpc(self,other); * *// если НПС выиграл последнее сражение с ГГ и была причина сражения с ГГ и агрессор ГГ * *if(self.aivar[AIV_LastFightAgainstPlayer] == FIGHT_WON) && (self.aivar[AIV_LastPlayerAR] != AR_NONE) && (Npc_IsPlayer(other)) * *{ * * * *// НПС говорит ГГ (SVM фраза "Хочешь еще получить?") * * * *B_Say(self,other,"$LOOKINGFORTROUBLEAGAIN"); * *} * *// иначе, если комментария обнаженного оружия не было * *else if(Player_DrawWeaponComment == FALSE) * *{ * * * *// если агрессор хочет применить магию * * * *if(Npc_IsInFightMode(other,FMODE_MAGIC)) * * * *{ * * * * * *// НПС говорит агрессору (SVM фраза "Перестань колдовать!") * * * * * *B_Say(self,other,"$STOPMAGIC"); * * * *} * * * *else // иначе * * * *{ * * * * * *// НПС говорит агрессору (SVM фраза "Убери оружие!") * * * * * *B_Say(self,other,"$WEAPONDOWN"); * * * *}; * * * *// установка флага состоявшегося комментария * * * *Player_DrawWeaponComment = TRUE; * *}; * *// НПС посылает предупреждение агрессору * *Npc_SendPassivePerc(self,PERC_ASSESSWARN,self,oth er); * *// сброс флага второго предупреждения * *self.aivar[AIV_TAPOSITION] = FALSE; * *// сброс счетчика времени * *self.aivar[AIV_StateTime] = 0; };
// Цикл состояния func int ZS_ReactToWeapon_Loop() { * * *// если расстояние между НПС и агрессором > дистанции действия восприятия * *if(Npc_GetDistToNpc(self,other) > PERC_DIST_INTERMEDIAT) * *{ * * * *// очистка очереди AI состояний НПС * * * *Npc_ClearAIQueue(self); * * * *// НПС убирает оружие * * * *AI_RemoveWeapon(self); * * * *// перестает смотреть на агрессора * * * *B_StopLookAt(self); * * * *return LOOP_END; * *}; * *// если агрессор убрал оружие * *if(Npc_IsInFightMode(other,FMODE_NONE)) * *{ * * * *// очистка очереди AI состояний НПС * * * *Npc_ClearAIQueue(self); * * * *// НПС говорит агрессору (SVM фраза "Умный малый!") * * * *B_Say(self,other,"$WISEMOVE"); * * * *// НПС убирает оружие * * * *AI_RemoveWeapon(self); * * * *// перестает смотреть на агрессора * * * *B_StopLookAt (self); * * * *return LOOP_END; * *}; * *// если прошла одна секунда * *if(Npc_GetStateTime(self) > self.aivar[AIV_StateTime]) * *{ * * * *// если НПС не видит агрессора * * * *if(!Npc_CanSeeNpc(self,other)) * * * *{ * * * * * * *// НПС поворачивается к агрессору * * * * * *B_TurnToNpc(self,other); * * * *}; * * * *// счетчик времени ++ * * * *self.aivar[AIV_StateTime] = self.aivar[AIV_StateTime] + 1; * *}; * *// если второго предупреждения не было и время в состоянии > 5 сек * *if(self.aivar[AIV_TAPOSITION] == FALSE) && (Npc_GetStateTime(self) > 5) * *{ * * * * *// если агрессор хочет применить магию * * * *if(Npc_IsInFightMode(other,FMODE_MAGIC)) * * * *{ * * * * * *// НПС говорит агрессору (SVM фраза "Убери свою магию! Ты что, оглох!?") * * * * * *B_Say(self,other,"$ISAIDSTOPMAGIC"); * * * *} * * * *else * * * *{ * * * * * *// НПС говорит агрессору (SVM фраза "Да убери же чертово оружие!") * * * * * *B_Say(self,other,"$ISAIDWEAPONDOWN"); * * * *}; * * * *// установить флаг второго предупреждения * * * *self.aivar[AIV_TAPOSITION] = TRUE; * *}; * *// если время в состоянии > 10 сек * *if(Npc_GetStateTime(self) > 10) * * * * * * * * * * * * * * * * * * * * * *{ * * * *// НПС атакует агрессора * * * *B_Attack(self,other,AR_ReactToWeapon,0); * *}; * * *return LOOP_CONTINUE; };
// Завершение состояния func void ZS_ReactToWeapon_End() { * * *// НПС перестает смотреть на агрессора * *B_StopLookAt(self); * *// НПС переходит в заключительную фазу состояния наблюдения за ГГ * *AI_StartState(self,ZS_ObservePlayer,1,""); };
|
|
|
22.02.2005, 10:01
|
#111
|
|
Re: Уроки скриптологии
// ***************************************** // Обработчик состояния разговора между НПС // ----------------------------------------- // self - НПС источник информации, other - слушатель (всегда ГГ) // *****************************************
var int zsTalkBugfix; * // флаг выхода из разговора
// Инициализация состояния разговора func void ZS_Talk() { * *// если ГГ уже с кем-то разговаривает * *if(other.aivar[AIV_INVINCIBLE] == TRUE) * *{ * * * *return; * * * * * * * *}; * *// установка флагов начала разговора (для обоих участников) * *self.aivar[AIV_INVINCIBLE] = TRUE; * *other.aivar[AIV_INVINCIBLE] = TRUE; * *// если НПС человек * *if(self.guild < GIL_SEPERATOR_HUM) * *{ * * * * * * *// если НПС сидит * * * *if(C_BodyStateContains(self,BS_SIT)) * * * *{ * * * * * *var C_NPC target; * * * * * *// инициализация глобальной переменной target ссылкой на НПС, на которого смотрит источник информации * * * * * *target = Npc_GetLookAtTarget(self); * * * * * *// если target не существует * * * * * *if(!Hlp_IsValidNpc(target)) * * * * * *{ * * * * * * * *// НПС смотрит на ГГ * * * * * * * *AI_LookAtNpc(self,other); * * * * * *}; * * * *} * * * *else // иначе * * * *{ * * * * * *// НПС смотрит на ГГ * * * * * *B_LookAtNpc(self,other); * * * *}; * * * *// НПС прячет оружие * * * *AI_RemoveWeapon(self); * *}; * *// если НПС не сидит * *if(!C_BodystateContains(self,BS_SIT)) * *{ * * * * *// НПС поворачивается к ГГ * * * *B_TurnToNpc(self,other); * *}; * *// если ГГ не сидит * *if(!C_BodystateContains(other,BS_SIT)) * *{ * * * * *// ГГ поворачивается к НПС * * * *B_TurnToNpc(other,self); * * * *// если расстояние между ГГ и НПС < 80 см * * * *if(Npc_GetDistToNpc(other,self) < 80) * * * *{ * * * * * *// ГГ отспупает назад * * * * * *AI_Dodge(other); * * * *}; * *}; * *// если НПС человек * *if(self.guild < GIL_SEPERATOR_HUM) * *{ * * * * *// если НПС сердит на ГГ или НПС враг ГГ * * * *if(Npc_GetAttitude(self,other) == ATT_ANGRY) ¦¦ (Npc_GetAttitude(self,other) == ATT_HOSTILE) * * * *{ * * * * * *// если ГГ не переодет в бандита или НПС не бандит * * * * * *if(!C_PlayerIsFakeBandit(self,other)) ¦¦ (self.guild != GIL_BDT) * * * * * *{ * * * * * * * *// включить "злую" анимацию лица НПС * * * * * * * *Mdl_StartFaceAni(self,"S_ANGRY",1,-1); * * * * * *}; * * * *}; * * * *// если НПС принадлежит к окружающему народу * * * *if(self.npctype == NPCTYPE_AMBIENT) * * * * // общему * * * *¦¦ (self.npctype == NPCTYPE_OCAMBIENT) * * *// или из Миненталя * * * *¦¦ (self.npctype == NPCTYPE_BL_AMBIENT) * * // или из Лагеря бандитов * * * *¦¦ (self.npctype == NPCTYPE_TAL_AMBIENT) * *// или из Долины бандитов * * * *{ * * * * * *// инициализация диалога НПС об окружающей информации (сплетни) * * * * * *B_AssignAmbientInfos(self); * * * * * *// если НПС принадлежит городу * * * * * *if(C_NpcBelongsToCity(self)) * * * * * *{ * * * * * * * *// инициализация диалога НПС о городской жизни * * * * * * * *B_AssignCityGuide(self); * * * * * *}; * * * *}; * * * *// если НПС является членом партии ГГ и * * * *if(self.aivar[AIV_PARTYMEMBER] == TRUE) * * * *&& (Hlp_GetInstanceID(self) != Hlp_GetInstanceID(Biff)) * * * * // НПС не Бифф * * * *&& (Hlp_GetInstanceID(self) != Hlp_GetInstanceID(Biff_NW)) * * *// и НПС не Бифф в Новом мире * * * *&& (Hlp_GetInstanceID(self) != Hlp_GetInstanceID(Biff_DI)) * * *// и НПС не Бифф на Острове драконов * * * *&& (Hlp_GetInstanceID(self) != Hlp_GetInstanceID(Pardos)) * * * // и НПС не Пардос * * * *&& (Hlp_GetInstanceID(self) != Hlp_GetInstanceID(Pardos_NW)) * *// и НПС не Пардос в Новом мире * * * *{ * * * * * *// ГГ дает НПС напиток лечения * * * * * *B_Addon_GivePotion(self); * * * *}; * * * *// если НПС имеет дело с "крутым парнем" и НПС не имеет новостей о "крутом парне" * * * *if(C_NpcIsToughGuy(self)) && (self.aivar[AIV_ToughGuyNewsOverride] == FALSE) * * * *{ * * * * * *// инициализация диалога НПС о "крутом парне" * * * * * *B_AssignToughGuyNEWS(self); * * * *}; * * * *// если НПС имеет новости об окружающей жизни * * * *if(C_NpcHasAmbientNews(self)) * * * *{ * * * * * *// инициализация диалога НПС об окружающих новостях * * * * * *B_AssignAmbientNEWS(self); * * * *}; * *}; * * * * *// если НПС дракон * *if (self.guild == GIL_DRAGON) * *{ * * * *// проиграть анимацию дракона T_STAND_2_TALK * * * *AI_PlayAni(self,"T_STAND_2_TALK"); * *}; * *// начать выбранный диалог * *AI_ProcessInfos(self); * *// сброс флага выхода из разговора * *zsTalkBugfix = FALSE; };
// Цикл состояния разговора func INT ZS_Talk_Loop () { * *// если диалог закончен и флаг выхода установлен * *if(InfoManager_HasFinished()) && (zsTalkBugfix == TRUE) * *{ * * * *// сброс флагов разговора для обоих участников * * * *self.aivar[AIV_INVINCIBLE] = FALSE; * * * *other.aivar[AIV_INVINCIBLE] = FALSE; * * * *// сброс флага важной информации * * * *self.aivar[AIV_NpcStartedTalk] = FALSE; * * * *// установка флага, что НПС говорил с ГГ * * * *self.aivar[AIV_TalkedToPlayer] = TRUE; * * * *// если НПС человек * * * *if(self.guild < GIL_SEPERATOR_HUM) * * * *{ * * * * * *// НПС перестает смотреть на ГГ * * * * * *B_StopLookAt(self); * * * * * *// сменить выражение лица НПС на обычное * * * * * *Mdl_StartFaceAni(self,"S_NEUTRAL",1,-1); * * * *}; * * * * *// если НПС дракон * * * *if(self.guild == GIL_DRAGON) * * * *{ * * * * * *// запустить обычную анимацию стоящего дракона * * * * * *AI_PlayAni(self,"T_TALK_2_STAND"); * * * *}; * * * *return LOOP_END; * *} * *else // иначе * *{ * * * *// установить флаг выхода из разговора (нельзя завершить цикл разговора при первом вхождении) * * * *zsTalkBugfix = TRUE; * * * *return LOOP_CONTINUE; * *}; };
// Окончание состояния разговора func void ZS_Talk_End() { * *// отказ ГГ от других диалогов на 20 сек * *Npc_SetRefuseTalk(other,20); * *// когда НПС находится в своем помещении или (помещение публично и НПС не друг ГГ * *if(C_NpcIsBotheredByPlayerRoomGuild(self)) ¦¦ ((Wld_GetPlayerPortalGuild() == GIL_PUBLIC) && (Npc_GetAttitude(self,other) != ATT_FRIENDLY)) * *{ * * * *// НПС переходит в состояние наблюдения за ГГ * * * *AI_StartState(self,ZS_ObservePlayer,0,""); * *} * *else * *// [лишнее, можно удалить] * *{
* *}; };
|
|
|
23.02.2005, 10:37
|
#112
|
|
Re: Уроки скриптологии
// ************************************************** ********* // Обработчик состояния наблюдения за сражением // ----------------------------------------------------------- // self - НПС наблюдатель, other - агрессор, victim - жертва // ************************************************** *********
// Функция реакции НПС наблюдателя когда другой НПС получает повреждение func void B_CheerFight() { * *// если время нахождения наблюдателя в этом состоянии <= 2 сек * *if(Npc_GetStateTime(self) <= 2) * * * * * * * *{ * * * *return; * *}; * *// если агрессор монстр или жертва монстр * *if((other.guild > GIL_SEPERATOR_HUM) ¦¦ (victim.guild > GIL_SEPERATOR_HUM)) * *{ * * * *return; * *}; * *// сброс времени нахождения в состоянии * *Npc_SetStateTime(self,0); * *// если наблюдатель имеет дело с "крутым парнем" * *if(C_NpcIsToughGuy(self)) * *{ * * * *var int zufall; * * * *// случайное число * * * *zufall = Hlp_Random(3); * * * *// если наблюдатель друг жертвы и наблюдатель не друг агрессору * * * *if(Npc_GetAttitude(self,victim) == ATT_FRIENDLY) && (Npc_GetAttitude(self,other) != ATT_FRIENDLY) * * * *{ * * * * * *// наблюдатель говорит сам себе (SVM фраза) * * * * * *if(zufall == 0) { B_Say_Overlay(self,self,"$OOH01"); }; // "Смотри, не делай так!" * * * * * *if(zufall == 1) { B_Say_Overlay(self,self,"$OOH02"); }; // "Вот тогда ты еще успеешь это сделать!" * * * * * *if(zufall == 2) { B_Say_Overlay(self,self,"$OOH03"); }; // "Ох! Это же больно!" * * * * * *// проиграть анимацию * * * * * *AI_PlayAni(self,"T_WATCHFIGHT_OHNO"); * * * *} * * * *else // иначе * * * *{ * * * * * *// наблюдатель говорит сам себе (SVM фраза) * * * * * *if(zufall == 0) { B_Say_Overlay(self,self,"$CHEERFRIEND01"); }; // "Да, это хорошо!" * * * * * *if(zufall == 1) { B_Say_Overlay(self,self,"$CHEERFRIEND02"); }; // "Ну, сделай уже!" * * * * * *if(zufall == 2) { B_Say_Overlay(self,self,"$CHEERFRIEND03"); }; // "Все просто здорово!" * * * * * *// проиграть анимацию * * * * * *AI_PlayAni(self,"T_WATCHFIGHT_YEAH"); * * * *}; * *}; };
// Функция реакции НПС наблюдателя когда другой НПС падает безсознания func void B_AssessDefeat() { * *// очистка очереди AI состояний наблюдателя * *Npc_ClearAIQueue(self); * *// если наблюдатель имеет дело с "крутым парнем" или (агрессор ГГ и наблюдатель друг ГГ) * *if(C_NpcIsToughGuy(self)) ¦¦ (Npc_IsPlayer(other) && (self.npctype == NPCTYPE_FRIEND)) * *{ * * * *// если наблюдатель друг ГГ * * * *if(Npc_GetAttitude(self,other) == ATT_FRIENDLY) * * * *{ * * * * * *// наблюдатель говорит ГГ (SVM фраза "Ну и показал же ты ему!") * * * * * *B_Say(self,other,"$GOODVICTORY"); * * * *} * * * *else // иначе * * * *{ * * * * * *// наблюдатель говорит ГГ (SVM фраза "Неплохо...") * * * * * *B_Say(self,other,"$NOTBAD"); * * * *}; * *} * *else // иначе * *{ * * * *// если у жертвы не было причины сражаться * * * *if(victim.aivar[AIV_ATTACKREASON] != AR_NONE) * * * *{ * * * * * *// наблюдатель говорит агрессору (SVM фраза "Боже мой! Какая жестокость...") * * * * * *B_Say(self,other,"$OHMYGODHESDOWN"); * * * * * *// наблюдатель запоминает новость, что агрессор сражался с НПС жертвой * * * * * *B_MemorizePlayerCrime(self,other,CRIME_ATTACK); * * * *} * * * *else // иначе * * * *{ * * * * * *// наблюдатель говорит агрессору (SVM фраза "Неплохо...") * * * * * *B_Say(self,other,"$NOTBAD"); * * * *}; * *}; };
// Инициализация состояния наблюдения за сражением func void ZS_WatchFight () { * *// разрешить наблюдателю локальное восприятие бессознательного состояния НПС * *Npc_PercEnable(self,PERC_ASSESSDEFEAT,B_AssessDef eat); * *// разрешить наблюдателю локальное восприятие если НПС получил повреждение * *Npc_PercEnable(self,PERC_ASSESSOTHERSDAMAGE,B_Che erFight); * *// разрешить минимальный набор восприятий * *Perception_Set_Minimal(); * *// наблюдатель встает * *AI_StandUp(self); * *// поворачивается к жертве * *B_TurnToNpc(self,victim); * *// прячет оружие * *AI_RemoveWeapon(self); * * * * * * *// если (расстояние между наблюдателем и агрессором или наблюдателем и жертвой < дистанции действия восприятия) * *if((Npc_GetDistToNpc(self,other) < PERC_DIST_INTERMEDIAT) ¦¦ (Npc_GetDistToNpc(self,victim) < PERC_DIST_INTERMEDIAT)) * *// и агрессор и жертва не безсознания * *&& (!Npc_IsInState(other,ZS_Unconscious)) && (!Npc_IsInState(victim,ZS_Unconscious)) * *// и агрессор и жертва люди * *&& ((other.guild < GIL_SEPERATOR_HUM) && (victim.guild < GIL_SEPERATOR_HUM)) * *{ * * * *// если наблюдатель имеет дело с "крутым парнем"" * * * *if(C_NpcIsToughGuy(self)) * * * *{ * * * * * *// наблюдатель говорит агрессору (SVM фраза "Ух ты, это же битва!") * * * * * *B_Say(self,other,"$THERESAFIGHT"); * * * *} * * * *else // иначе * * * *{ * * * * * *// наблюдатель говорит агрессору (SVM фраза "Боже мой, вот это битва!") * * * * * *B_Say(self,other,"$OHMYGODITSAFIGHT"); * * * *}; * *}; * *// сброс флага выхода из цикла * *self.aivar[AIV_TAPOSITION] = NOTINPOS; * *// очистить счетчик времени * *self.aivar[AIV_StateTime] = 0; };
// Цикл состояния наблюдения за сражением func int ZS_WatchFight_Loop() { * *// если расстояние между наблюдателем и агрессором и наблюдателем и жертвой > дистанции наблюдения сражения * *if(Npc_GetDistToNpc(self,other) > WATCHFIGHT_DIST_MAX) && (Npc_GetDistToNpc(self,victim) > WATCHFIGHT_DIST_MAX) * *{ * * * *// очистка очереди AI состояний наблюдателя * * * *Npc_ClearAIQueue(self); * * * *return LOOP_END; * *}; * *// если (агрессор не атакует или не реагирует на повреждение) * *if(!(Npc_IsInState(other,ZS_Attack) ¦¦ Npc_IsInState(other,ZS_ReactToDamage))) * *// и (жертва не атакует или не реагирует на повреждение) * *&& (!(Npc_IsInState(victim,ZS_Attack) ¦¦ Npc_IsInState(victim,ZS_ReactToDamage))) * *// и время в состоянии > 0 * *&& (Npc_GetStateTime(self) > 0) * *{ * * * *// если агрессор или жертва безсознания * * * *if(Npc_IsInState(other,ZS_Unconscious)) ¦¦ (Npc_IsInState(victim,ZS_Unconscious)) * * * *// или агрессор или жертва мертвы * * * *¦¦ (Npc_IsInState(other,ZS_Dead)) ¦¦ (Npc_IsInState(victim,ZS_Dead)) * * * *{ * * * * * *// если флаг выхода из цикла сброшен * * * * * *if(self.aivar[AIV_TAPOSITION] == NOTINPOS) * * * * * *{ * * * * * * * *// установить флаг * * * * * * * *self.aivar[AIV_TAPOSITION] = ISINPOS; * * * * * * * *return LOOP_CONTINUE; * * * * * *} * * * * * *else // иначе, флаг выхода из цикла установлен * * * * * *{ * * * * * * * *// очистка очереди AI состояний наблюдателя * * * * * * * *Npc_ClearAIQueue(self); * * * * * * * *// выход из цикла выполняется после второго прохода, если кто-либо из сражающихся мертв или безсознания (чтобы сработало соответствующее восприятие) * * * * * * * *return LOOP_END; * * * * * *}; * * * *} * * * *else * * * *{ * * * * * * * * *// очистка очереди AI состояний наблюдателя * * * * * *Npc_ClearAIQueue(self); * * * * * *return LOOP_END; * * * *}; * *}; * *// если наблюдатель имеет дело с "крутым парнем" * *if(C_NpcIsToughGuy(self)) * *{ * * * *// анимация удалена!!! * * * *//AI_PlayAni(self,"T_STAND_2_WATCHFIGHT"); * *}; * *// если расстояние между наблюдателем и агрессором или наблюдателем и жертвой <= мин. дистанции наблюдения сражения * *if(Npc_GetDistToNpc(self,other) *<= WATCHFIGHT_DIST_MIN) ¦¦ (Npc_GetDistToNpc(self,victim) <= WATCHFIGHT_DIST_MIN) * *{ * * * *// очистка очереди AI состояний наблюдателя * * * *Npc_ClearAIQueue(self); * * * *// если расстояние между наблюдателем и агрессором <= расстояния между наблюдателем и жертвой * * * *if(Npc_GetDistToNpc(self,other) <= Npc_GetDistToNpc(self,victim)) * * * *{ * * * * * *// наблюдатель поворачивается к жертве * * * * * *B_TurnToNpc(self,victim); * * * *} * * * *else // иначе * * * *{ * * * * * *// наблюдатель поворачивается к агрессору * * * * * *B_TurnToNpc(self,other); * * * *}; * * * *// наблюдатель делает шаг назад * * * *AI_Dodge(self); * *} * *else // иначе (расстояние нормальное для наблюдения) * *{ * * * *// если прошла секунда * * * *if(Npc_GetStateTime(self) != self.aivar[AIV_StateTime]) * * * *{ * * * * * *// если если расстояние между наблюдателем и агрессором <= расстояния между наблюдателем и жертвой * * * * * *if(Npc_GetDistToNpc(self,other) <= Npc_GetDistToNpc(self,victim)) * * * * * *{ * * * * * * * *// наблюдатель поворачивается к агрессору * * * * * * * *B_TurnToNpc(self,other); * * * * * *} * * * * * *else // иначе * * * * * *{ * * * * * * * *// наблюдатель поворачивается к жертве * * * * * * * *B_TurnToNpc(self,victim); * * * * * *}; * * * * * *// запись в счетчик текущего времени цикла * * * * * *self.aivar[AIV_StateTime] = Npc_GetStateTime(self); * * * *}; * *}; * *return LOOP_CONTINUE; };
// Завершение состояния func void ZS_WatchFight_End() { * *// анимация удалена!!! * *//AI_PlayAni(self,"T_WATCHFIGHT_2_STAND"); };
|
|
|
24.02.2005, 09:52
|
#113
|
|
Re: Уроки скриптологии
// ************************************************** *** // Обработчик состояния когда НПС находится безсознания // Примечание: НПС в это состояние переводит ядро системы, когда у НПС кончается жизнь, а не скрипты! // ----------------------------------------------------- // self - НПС безсознания, other - агрессор // ************************************************** ***
// Инициализация состояния func void ZS_Unconscious() { * * *// разрешить НПС воспринимать магию * *Npc_PercEnable(self,PERC_ASSESSMAGIC,B_AssessMagi c); * *// если НПС плыл или нырял * *if(C_BodyStateContains(self,BS_SWIM)) ¦¦ (C_BodyStateContains(self,BS_DIVE)) * *{ * * * *// очистка очереди AI состояний НПС * * * *Npc_ClearAIQueue(self); * * * *// очистка всех восприятий * * * *B_ClearPerceptions(self); * * * *// переход НПС в состояние трупа (смерть) * * * *AI_StartState(self,ZS_Dead,0,""); * * * *return; * *}; * *// сброс статуса предупреждения охраной * *self.aivar[AIV_Guardpassage_Status] = GP_NONE; * *// сброс счетчика отказа от диалога * *Npc_SetRefuseTalk(self,0); * *// сброс временного отношения НПС к ГГ (устанавливается равным постоянному отношению) * *Npc_SetTempAttitude(self,Npc_GetPermAttitude(self ,hero)); * *// НПС перестает смотреть на кого-либо * *B_StopLookAt(self); * *// НПС прекращает на что-либо указывать * *AI_StopPointAt(self); * *// если НПС человек и агрессор ГГ * *if(self.guild < GIL_SEPERATOR_HUM) && (Npc_IsPlayer(other)) * * * * * * * * * * * * * * * *{ * * * *// установить флаг, что НПС побежден ГГ * * * *self.aivar[AIV_DefeatedByPlayer] = TRUE; * * * *// установить, что НПС проиграл сражение с ГГ * * * *self.aivar[AIV_LastFightAgainstPlayer] = FIGHT_LOST; * * * *// если причины у НПС нападать на ГГ не было и ГГ этого НПС из наемников еще не бил и НПС наемник * * * *if(self.aivar[AIV_LastPlayerAR] == AR_NONE) && (self.aivar[AIV_DuelLost] == FALSE) && (self.guild == GIL_SLD) * * * *{ * * * * * *// увеличить счетчик для задания Торлофа (побить > 3 наемников) * * * * * *Sld_Duelle_gewonnen = Sld_Duelle_gewonnen + 1; * * * * * *// установить флаг, что наемник побит ГГ * * * * * *self.aivar[AIV_DuelLost] = TRUE; * * * *}; * * * *// *если НПС сражался на арене с Альриком * * * *if(self.aivar[AIV_ArenaFight] == AF_RUNNING) * * * *{ * * * * * *// запись следующей фазы сражения на арене НПС * * * * * *self.aivar[AIV_ArenaFight] = AF_AFTER; * * * *}; * *}; * *// если НПС безсознания ГГ * *if(Npc_IsPlayer(self)) * *{ * * * *// установить, что агрессор выиграл сражение с ГГ * * * *other.aivar[AIV_LastFightAgainstPlayer] = FIGHT_WON; * * * *// если ГГ сражался на арене с Альриком * * * *if(other.aivar[AIV_ArenaFight] == AF_RUNNING) * * * *{ * * * * * *// запись следующей фазы сражения на арене Альрику * * * * * *other.aivar[AIV_ArenaFight] = AF_AFTER; * * * *}; * *}; * *// удаление продаваемых предметов у торговцев * *B_GiveTradeInv(self); * *// удаление рун у НПС * *B_ClearRuneInv(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; * *}; * *// убрать оружие экипированное НПС * *AI_UnequipWeapons(self); * *// если НПС "Дар" и агрессор "Сайфер" * *if(Hlp_GetInstanceID(self) == Hlp_GetInstanceID(Dar)) && (Hlp_GetInstanceID(other) == Hlp_GetInstanceID(Cipher)) * *{ * * * *// установка флага для квеста с пакетом болотника * * * *Dar_LostAgainstCipher = TRUE; * *}; }; * * // Цикл состояния func int ZS_Unconscious_Loop() { * *// если время цикла < времени нахождения в бессознательном состоянии * *if(Npc_GetStateTime(self) < HAI_TIME_UNCONSCIOUS) * *{ * * * *return LOOP_CONTINUE; * *} * *else // иначе * *{ * * * *return LOOP_END; * *}; };
// Завершение состояния func void ZS_Unconscious_End() { * * *// сброс флага, что тело обыскивалось * *self.aivar[AIV_RANSACKED] = FALSE; * *// НПС встает * *AI_StandUp(self); * *// если НПС ГГ * *if(Npc_IsPlayer(self)) * *{ * * * *return; * *}; * *// если НПС "Равен" * *if(Hlp_GetInstanceID(self) == Hlp_GetInstanceID(Raven)) * *{ * * * *// установка флага, что НПС всегда использует магию * * * *self.aivar[AIV_MagicUser] = MAGIC_ALWAYS; * * * *// Равен атакует ГГ * * * *B_Attack(self,hero,AR_GuildEnemy,0); * * * *return; * *}; * *// если НПС видит агрессора по прямой и расстояние между НПС и агрессором < дистанции действия восприятия * *if(Npc_CanSeeNpcFreeLOS(self,other)) && (Npc_GetDistToNpc(self,other) < PERC_DIST_INTERMEDIAT) * *{ * * * *// НПС поворачивается к агрессору * * * *B_TurnToNpc (self,other); * * * *// если НПС имел дело с "крутым парнем" и НПС не враг агрессору и НПС не друг ГГ * * * *if(C_NpcIsToughGuy(self)) && (Npc_GetPermAttitude(self,other) != ATT_HOSTILE) && (self.npctype != NPCTYPE_FRIEND) * * * *{ * * * * * *// НПС говорит ГГ (SVM фраза "В следующий раз мы это увидим...") * * * * * *B_Say(self,other,"$NEXTTIMEYOUREINFORIT"); * * * *} * * * *else // иначе * * * *{ * * * * * *// НПС говорит ГГ (SVM фраза "О, мой череп...") * * * * * *B_Say(self,other,"$OHMYHEAD"); * * * *}; * *}; * *// разрешить НПС воспринимать все объекты в зоне действия восприятия * *Npc_PerceiveAll(self); * *// если НПС находит оружие ближнего или дальнего радиуса поражения * *if(Wld_DetectItem(self,ITEM_KAT_NF)) ¦¦ (Wld_DetectItem(self,ITEM_KAT_FF)) * *{ * * * *// если ссылка на предмет item существует * * * *if(Hlp_IsValidItem(item)) * * * *{ * * * * * *// если расстояние от НПС до предмета < 5 метров * * * * * *if(Npc_GetDistToItem(self,item) <= 500) * * * * * *{ * * * * * * * *// НПС берет предмет * * * * * * * *AI_TakeItem(self,item); * * * * * *}; * * * *}; * *}; * *// экипировка лучшим оружием * *AI_EquipBestMeleeWeapon(self); * *AI_EquipBestRangedWeapon(self); * *// переход НПС в состояние самолечения * *AI_StartState(self,ZS_HealSelf,0,""); * *return; };
|
|
|
26.02.2005, 10:57
|
#114
|
|
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; * *}; };
|
|
|
28.02.2005, 12:19
|
#115
|
|
Re: Уроки скриптологии
// ************************************************* // Обработчик состояния когда монстр поедает добычу // ------------------------------------------------- // self - НПС монстр, other - добыча (труп) // *************************************************
// Инициализация состояния func void ZS_MM_EatBody() { * *// установка времени реакции на восприятия 1 сек * *Npc_SetPercTime(self,1); * *// разрешить восприятие магии * *Npc_PercEnable(self,PERC_ASSESSMAGIC,B_AssessMagi c); * *// разрешить восприятие повреждения * *Npc_PercEnable(self,PERC_ASSESSDAMAGE,B_MM_Assess Damage); * *// разрешить восприятие повреждения, нанесенного другому НПС * *Npc_PercEnable(self,PERC_ASSESSOTHERSDAMAGE,B_MM_ AssessOthersDamage); * *// разрешить восприятие смерти * *Npc_PercEnable(self,PERC_ASSESSMURDER,B_MM_Assess OthersDamage); * *// монстр идет к телу * *AI_GotoNpc(self,other); * *// монстр поворачивается к добыче * *AI_TurnToNpc(self,other); * *// проигрывается анимация поедания * *AI_PlayAni(self,"T_STAND_2_EAT"); * *// установить приоритет на поедание * *self.aivar[AIV_MM_PRIORITY] = PRIO_EAT; * *// ссылка на последнее съеденное тело * *self.aivar[AIV_LASTBODY] = Hlp_GetInstanceID(other); * *// сброс флага восприятия врага * *self.aivar[AIV_TAPOSITION] = NOTINPOS; };
// Цикл состояния func int ZS_MM_EatBody_loop() { * *// если восприятие врага выключено * *if (self.aivar[AIV_TAPOSITION] == NOTINPOS) * *{ * * * *// разрешить восприятие врага * * * *Npc_PercEnable(self,PERC_ASSESSENEMY,B_MM_AssessE nemy); * * * *// установить флаг разрешения восприятия * * * *self.aivar[AIV_TAPOSITION] = ISINPOS; * *}; * *// если добыча съедена * *if(!Hlp_IsValidNpc(other)) * *{ * * * *// очистка очереди AI состояний монстра * * * *Npc_ClearAIQueue(self); * * * *return LOOP_END; * *}; * *return LOOP_CONTINUE; };
// Завершение состояния func void ZS_MM_EatBody_end() { * *// прекратить анимацию поедания * *AI_PlayAni(self,"T_EAT_2_STAND"); };
... еще один файл
//************************************************** ** // Обработчик состояния когда монстр убегает от врага //---------------------------------------------------- // self - монстр, other - враг //************************************************** **
// Инициализация состояния func void ZS_MM_Flee() { * *// разрешить восприятие магии * *Npc_PercEnable(self,PERC_ASSESSMAGIC,B_AssessMagi c); * * * *// инициализировать переменную other врагом * *B_ValidateOther(); * *// монстр встает * *AI_StandUp(self); * *// монстр переходит в режим бега * *AI_SetWalkmode(self,NPC_RUN); * *// монстру посылается предупреждение от врага * *Npc_SendPassivePerc(self,PERC_ASSESSWARN,other,se lf); * *// рассинхронизация [Примечание: мне непонятно зачем?] * *B_MM_DeSynchronize(); };
// Цикл состояния func int ZS_MM_Flee_Loop() { * *// обновить ссылку на врага * *Npc_GetTarget(self); * *// если расстояние между монстром и врагом < 20 метров * *if(Npc_GetDistToNpc(self,other) < 2000) * *{ * * * * *// если прошла одна секунда * * * *if(Npc_GetStateTime(self) > 0) * * * *{ * * * * * *// враг посылает монстру предупреждение * * * * * *Npc_SendPassivePerc(self,PERC_ASSESSWARN,other,se lf); * * * * * *// сброс времени состояния * * * * * *Npc_SetStateTime(self,0); * * * *}; * * * *// монстр убегает от врага * * * *AI_Flee(self); * * * *return LOOP_CONTINUE; * *} * *else * *{ * * * * *// очистка очереди AI состояний монстра * * * *Npc_ClearAIQueue(self); * * * *return LOOP_END; * * * * * * * * * * * * * * * * * * * * * * * * * * * *}; };
// Завершение состояния func void ZS_MM_Flee_End() { };
... и еще файл // ******************************************** // Обработчик состояния охоты монстра // -------------------------------------------- // self - монстр, other - жертва // ********************************************
// Инициализация состояния охоты func void ZS_MM_Hunt() { * *// разрешить базовые восприятия монстров * *Perception_Set_Monster_Rtn(); * *// монстр встает * *AI_StandUp(self); * *// поворачивается к жертве * *AI_TurnToNpc(self,other); * *// переходит на шаг * *AI_SetWalkmode(self,NPC_WALK); * *// идет к жертве * *AI_GotoNpc(self,other); };
// Цикл состояния func int ZS_MM_Hunt_Loop() { * *return LOOP_END; };
// Завершение состояния func void ZS_MM_Hunt_End() { };
... и еще файл // ************************************************** // Обработчик состояния когда монстр угрожает врагу // -------------------------------------------------- // self - монстр, other - враг // **************************************************
// Инициализация состояния угрозы func void ZS_MM_ThreatenEnemy() { * *// установка времени реакции на восприятия 2 сек * *Npc_SetPercTime(self,2); * *// разрешить восприятие мертвого тела * *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_ASSESSOTHERSDAMAGE,B_MM_ AssessOthersDamage); * *// разрешить восприятие смерти * *Npc_PercEnable(self,PERC_ASSESSMURDER,B_MM_Assess OthersDamage); * *// монстр встает * *AI_StandUp(self); * *// враг посылает монстру предупреждение * *Npc_SendPassivePerc(self,PERC_ASSESSWARN,other,se lf); };
// Цикл состояния угрозы func int ZS_MM_ThreatenEnemy_loop() { * *// если расстояние между монстром и врагом > дистанции действия активных восприятий * *if(Npc_GetDistToNpc(self,other) > PERC_DIST_MONSTER_ACTIVE_MAX) * *{ * * * *// очистка очереди AI состояний монстра * * * *Npc_ClearAIQueue(self); * * * *return LOOP_END; * *}; * *// если расстояние между монстром и врагом <= дистанции начала атаки * *if(Npc_GetDistToNpc(self,other) <= FIGHT_DIST_MONSTER_ATTACKRANGE) * *{ * * * *// очистка очереди AI состояний монстра * * * *Npc_ClearAIQueue(self); * * * *// установка цели для монстра * * * *Npc_SetTarget(self, other); * * * *// переход в состояние атаки * * * *AI_StartState(self,ZS_MM_Attack,0,""); * * * *return LOOP_END; * *}; * *// если время в состоянии >= времени угрозы * *if(Npc_GetStateTime(self) >= MONSTER_THREATEN_TIME) * *{ * * * * *Npc_ClearAIQueue(self); * * * *Npc_SetTarget(self,other); * * * *// переход в состояние атаки * * * *AI_StartState(self,ZS_MM_Attack,0,""); * * * *return LOOP_END; * *}; * *// монстр поворачивается к врагу * *AI_TurnToNpc(self,other); * *// играется анимация угрозы * *AI_PlayAni(self,"T_WARN"); * *return LOOP_CONTINUE; }; *
// Завершение состояния угрозы func void ZS_MM_ThreatenEnemy_end() { };
Добавление от 02/28/05, в 11:39:03
Системная функция AI_StartState может управлять последовательностью выполнения фаз состояний, за это отвечает параметр stateBehaviour, если он = 0, то сразу выполняется переход в указанное состояние, если он = 1, то переход в новое состояние выполнится только после полного завершения текущего состояния.
|
|
|
28.02.2005, 13:56
|
#116
|
|
Re: Уроки скриптологии
2Mitrich:
Если это все еще актуально
|
Пока еще актуально. В добавлении к предыдущему посту №198 приведено правильное описание параметра stateBehaviour функции AI_StartState. Предыдущие трактовки этого параметра ошибочны. Извиняюсь, что сразу в этом не разобрался. 10. Функции распорядка дня людей. Все функции распорядка дня людей регистрируются в файле ..\AI\Human\TA.d Шаблон регистрации любой функции: func void TA_name(var int start_h,var int start_m,var int stop_h,var int stop_m,var string waypoint) { * * *// регистрация обработчика состояния ZS_name с временами начала и конца работы в точке waypoint * * *TA_Min(self,start_h,start_m,stop_h,stop_m,ZS_name ,waypoint); };
где: * * *name - имя выполняемой функции, * * *start_h - час начала выполнения, * * *start_m - минута начала выполнения, * * *stop_h - час окончания выполнения, * * *stop_m - минута окончания выполнения, * * *waypoint - имя WP точки выполнения функции
Сами обработчики состояний функций распорядка дня людей находятся в директории ..\AI\Human\TA_Human\ Понятно, что вызов всех обработчиков состояний производится ядром системы в заданном интервале времени. Обработчики состояний функций распорядка дня я рассматривать не буду, но если кому-то интересны некоторые обработчики, можно сделать заказ на их рассмотрение.
|
|
|
01.03.2005, 09:23
|
#117
|
|
Re: Уроки скриптологии
11. Функции распорядка дня монстров.
Как таковой (по сравнению с людьми) распорядок дня у монстров отсутствует, есть функция планировщика суточного цикла монстров ZS_MM_AllScheduler, которая вызывает обработчики конкретных состояний. Все файлы обработчиков суточных состояний монстров расположены в директории ..\AI\Monster\RTN_Monster
// ************************************** // Планировщик суточного цикла монстров // **************************************
func void ZS_MM_AllScheduler() { * * *// установить приоритет на питание вместо атаки * * *self.aivar[AIV_MM_PRIORITY] = PRIO_EAT; * * *// если НПС Каменный страж и Равен убит * * *if(self.guild == GIL_STONEGUARDIAN) && (RavenIsDead == TRUE) * * *{ * * * * * * * * *// убить Каменного стража * * * * * *B_KillNpc(self); * * *}; * * *// если наступило время сна монстра или время контролируется программой поведения монстра * * *if(Wld_IsTime(self.aivar[AIV_MM_SleepStart],00,self.aivar[AIV_MM_SleepEnd] ,00) ¦¦ (self.aivar[AIV_MM_SleepStart] == OnlyRoutine)) * * *{ * * * * * *// перейти в состояние сна (обратить внимание на параметр stateBehaviour = 1, переход в состояние сна возможен только после полного завершения текущего состояния) * * * * * *AI_StartState(self,ZS_MM_Rtn_Sleep,1,""); * * *} * * *// иначе, если наступило время отдыха монстра или время контролируется программой поведения монстра * * *else if(Wld_IsTime(self.aivar[AIV_MM_RestStart],00,self.aivar[AIV_MM_RestEnd],00) ¦¦ (self.aivar[AIV_MM_RestStart] == OnlyRoutine)) * * *{ * * * * * *// перейти в состояние отдыха * * * * * *AI_StartState(self,ZS_MM_Rtn_Rest,1,""); * * *} * * *// иначе, если наступило время брожения монстра или время контролируется программой поведения монстра * * *else if(Wld_IsTime(self.aivar[AIV_MM_RoamStart],00,self.aivar[AIV_MM_RoamEnd],00) ¦¦ (self.aivar[AIV_MM_RoamStart] == OnlyRoutine)) * * *{ * * * * * *// перейти в состояние брожения * * * * * *AI_StartState(self,ZS_MM_Rtn_Roam,1,""); * * *} * * *// иначе, если наступило время кормежки монстра или время контролируется программой поведения монстра * * *else if(Wld_IsTime(self.aivar[AIV_MM_EatGroundStart],00,self.aivar[AIV_MM_EatGroundEnd],00) ¦¦ (self.aivar[AIV_MM_EatGroundStart] == OnlyRoutine)) * * *{ * * * * * *// перейти в состояние кормежки * * * * * *AI_StartState(self,ZS_MM_Rtn_EatGround,1,""); * * *} * * *// иначе, если наступило время резвости монстра или время контролируется программой поведения монстра * * *else if(Wld_IsTime(self.aivar[AIV_MM_WuselStart],00,self.aivar[AIV_MM_WuselEnd],00) ¦¦ (self.aivar[AIV_MM_WuselStart] == OnlyRoutine)) * * *{ * * * * * *// перейти в состояние резвости * * * * * *AI_StartState(self,ZS_MM_Rtn_Wusel,1,""); * * *} * * *// иначе, если наступило время посидеть орку или время контролируется программой поведения монстра * * *else if(Wld_IsTime(self.aivar[AIV_MM_OrcSitStart],00,self.aivar[AIV_MM_OrcSitEnd],00) ¦¦ (self.aivar[AIV_MM_OrcSitStart] == OnlyRoutine)) * * *{ * * * * * *// перейти орку в сидячее состояние * * * * * *AI_StartState(self,ZS_MM_Rtn_OrcSit,1,""); * * *} * * *else // иначе (по умолчанию) * * *{ * * * * * *// перейти в состояние отдыха * * * * * *AI_StartState(self,ZS_MM_Rtn_Rest,1,""); * * *}; };
... еще один файл
// ********************************* // Обработчик состояния сна монстра // *********************************
// Функция обработки локального восприятия тихих звуков во время сна func void B_MM_AssessQuietSound_Sleep() { * * *// если спящий монстр услышал врага * * *if(Wld_GetGuildAttitude(self.guild,other.guild) == ATT_HOSTILE) * * *{ * * * * * *// реакция монстра на врага * * * * * *B_MM_AssessEnemy(); * * *}; };
// Инициализация состояния сна func void ZS_MM_Rtn_Sleep() { * * *// разрешить восприятие магии * * *Npc_PercEnable(self,PERC_ASSESSMAGIC,B_AssessMagi c); * * *// разрешить восприятие повреждения * * *Npc_PercEnable(self,PERC_ASSESSDAMAGE,B_MM_Assess Damage); ** * * * * * * * *// разрешить восприятие повреждения, нанесенного другому НПС * * *Npc_PercEnable(self,PERC_ASSESSOTHERSDAMAGE,B_MM_ AssessOthersDamage); ** * * * * *// разрешить восприятие смерти * * *Npc_PercEnable(self,PERC_ASSESSMURDER,B_MM_Assess OthersDamage); * * *// разрешить восприятие предупреждения * * *Npc_PercEnable(self,PERC_ASSESSWARN,B_MM_AssessWa rn); * * *// разрешить восприятие тихих звуков (шаги, звон падающего предмета) * * *Npc_PercEnable(self,PERC_ASSESSQUIETSOUND,B_MM_As sessQuietSound_Sleep); * * *// установить режим передвижения шагом * * *AI_SetWalkmode ** * *(self, NPC_WALK); * * *B_MM_DeSynchronize(); * * *// если монстр не находится в заданной точке * * *if(Hlp_StrCmp(Npc_GetNearestWP(self),self.wp) == FALSE) * * *{ * * * * * *// монстр идет в заданную точку * * * * * *AI_GotoWP(self,self.WP); * * *}; * * *// если есть свободная точка с именем "FP_ROAM" * * *if(Wld_IsFPAvailable(self,"FP_ROAM")) * * *{ * * * * * *// монстр идет в эту точку * * * * * *AI_GotoFP(self,"FP_ROAM"); * * *}; * * *// анимация "T_PERCEPTION" * * *AI_PlayAni(self,"T_PERCEPTION"); * * *// анимация перехода ко сну * * *AI_PlayAniBS(self,"T_STAND_2_SLEEP",BS_LIE); };
// Цикл состояния сна func int ZS_MM_Rtn_Sleep_loop() { * * *// если время сна истекло или время не контролируется программой поведения монстра * * *if((!Wld_IsTime(self.aivar[AIV_MM_SleepStart],00,self.aivar[AIV_MM_SleepEnd],00)) && (self.aivar[AIV_MM_SleepStart] != OnlyRoutine)) * * *{ * * * * * *// переход в планировщик суточного цикла * * * * * *AI_StartState(self,ZS_MM_AllScheduler,1,""); * * * * * *return LOOP_END; * * *}; * * *return LOOP_CONTINUE; };
// Завершение состояния сна func void ZS_MM_Rtn_Sleep_end() { * * *// анимация пробуждения * * *AI_PlayAniBS(self,"T_SLEEP_2_STAND",BS_STAND); };
... и еще файл
// ************************************* // Обработчик состояния отдыха монстров // *************************************
// Инициализация состояния отдыха func void ZS_MM_Rtn_Rest() { * * *// разрешить нормальный набор восприятий * * *Perception_Set_Monster_Rtn(); * * *// режим пережвижения шагом * * *AI_SetWalkmode(self,NPC_WALK); * * *B_MM_DeSynchronize(); * * *// если монстр не находится в заданной точке * * *if(Hlp_StrCmp(Npc_GetNearestWP(self),self.wp) == FALSE) * * *{ * * * * * *// монстр идет в заданную точку * * * * * *AI_GotoWP(self,self.WP); * * *}; * * *// сброс флага достижения точки отдыха * * *self.aivar[AIV_TAPOSITION] = NOTINPOS; };
// Цикл состояния отдыха func int ZS_MM_Rtn_Rest_Loop() { * * *// если НПС Каменный страж и Равен убит * * *if(self.guild == GIL_STONEGUARDIAN) && (RavenIsDead == TRUE) * * *{ * * * * * * * * *// убить Каменного стража * * * * * *B_KillNpc(self); * * *}; * * *// если время отдыха истекло или время не контролируется программой поведения монстра * * *if((!Wld_IsTime(self.aivar[AIV_MM_RestStart],00,self.aivar[AIV_MM_RestEnd] ,00)) && (self.aivar[AIV_MM_RestStart] != OnlyRoutine)) * * *{ * * * * * *// переход в планировщик суточного цикла * * * * * *AI_StartState(self,ZS_MM_AllScheduler,1,""); * * * * * *return LOOP_END; * * *}; * * *// если точка отдыха не достигнута * * *if(self.aivar[AIV_TAPOSITION] == NOTINPOS) * * *{ * * *// если есть свободная точка с именем "FP_ROAM" * * * * * *if(Wld_IsFPAvailable(self,"FP_ROAM")) * * * * * *{ * * * * * * * * *// монстр идет в эту точку * * * * * * * * *AI_GotoFP(self,"FP_ROAM"); * * * * * *}; * * * * * *// если монстр дошел до точки * * * * * *if(Npc_IsOnFP(self,"FP_ROAM")) * * * * * *{ * * * * * * * * *// установить флаг достижения точки отдыха * * * * * * * * *self.aivar[AIV_TAPOSITION] = ISINPOS; * * * * * *}; * * *} * * *else // иначе (монстр находится в точке отдыха) * * *{ * * * * * *// с вероятностью 0,005 менять анимацию монстра * * * * * *if(Hlp_Random(1000) <= 5) * * * * * *{ * * * * * * * * *var int randomMove; * * * * * * * * *randomMove = Hlp_Random(3); * * * * * * * * *if(randomMove == 0) { AI_PlayAni(self,"R_ROAM1"); }; * * * * * * * * *if(randomMove == 1) { AI_PlayAni(self,"R_ROAM2"); }; * * * * * * * * *if(randomMove == 2) { AI_PlayAni(self,"R_ROAM3"); }; * * * * * *}; * * *}; * * *return LOOP_CONTINUE; };
// Завершение состояния отдыха func void ZS_MM_Rtn_Rest_End() { };
|
|
|
02.03.2005, 09:30
|
#118
|
|
Re: Уроки скриптологии
// ************************************** // Обработчик состояния брожения монстра // **************************************
// Инициализация состояния func void ZS_MM_Rtn_Roam() { * *// разрешить нормальный набор восприятий * *Perception_Set_Monster_Rtn(); * *// установить режим передвижения шагом * *AI_SetWalkmode(self,NPC_WALK); * *B_MM_DeSynchronize(); * *// если монстр не находится в заданной точке * *if(Hlp_StrCmp(Npc_GetNearestWP(self),self.wp) == FALSE) * *{ * * * *// монстр идет в заданную точку * * * *AI_GotoWP(self,self.WP); * *}; * * *// сброс флага чередования циклов (стоит или бродит) * *self.aivar[AIV_TAPOSITION] = NOTINPOS; };
// Цикл состояния брожения func int ZS_MM_Rtn_Roam_loop() { * *// если время брожения истекло и время не контролируется программой поведения монстра * *if((!Wld_IsTime(self.aivar[AIV_MM_RoamStart],00,self.aivar[AIV_MM_RoamEnd] ,00)) && (self.aivar[AIV_MM_RoamStart] != OnlyRoutine)) * *{ * * * *// переход в планировщик суточного цикла * * * *AI_StartState(self,ZS_MM_AllScheduler,1,""); * * * *return LOOP_END; * *}; * *// фаза передвижения завершена * *if (self.aivar[AIV_TAPOSITION] == NOTINPOS) * *{ * * * *var int wanderTime; * * * *// время стояния * * * *wanderTime = Hlp_Random(5); * * * *// сброс времени цикла * * * *Npc_SetStateTime(self,0); * * * *// установить флаг стояния * * * *self.aivar[AIV_TAPOSITION] = ISINPOS; * *}; * *// если время стояния закончилось * *if(Npc_GetStateTime(self) > wanderTime) * *{ * * * *// если есть свободная точка "FP_ROAM" * * * *if(Wld_IsNextFPAvailable(self,"FP_ROAM")) * * * *{ * * * * * *// монстр идет в эту мочку * * * * * *AI_GotoNextFP(self,"FP_ROAM"); * * * *}; * * * *// сброс флага стояния * * * *self.aivar[AIV_TAPOSITION] = NOTINPOS; * *} * *else // иначе (стояние) * *{ * * * *// с вероятностью 0,005 менять анимацию монстра * * * *if(Hlp_Random(1000) <= 5) * * * *{ * * * * * *var int randomMove; * * * * * *randomMove = Hlp_Random(3); * * * * * *if(randomMove == 0) { AI_PlayAni(self,"R_ROAM1"); }; * * * * * *if(randomMove == 1) { AI_PlayAni(self,"R_ROAM2"); }; * * * * * *if(randomMove == 2) { AI_PlayAni(self,"R_ROAM3"); }; * * * *}; * *}; * *return LOOP_CONTINUE; };
// Завершение состояния func void ZS_MM_Rtn_Roam_end() { };
... еще файл
// ************************************** // Обработчик состояния кормежки монстра // **************************************
// Инициализация состояния кормежки func void ZS_MM_Rtn_EatGround() { * *// разрешить нормальный набор восприятий * *Perception_Set_Monster_Rtn(); * *// режим пережвижения шагом * *AI_SetWalkmode(self,NPC_WALK); * *B_MM_DeSynchronize(); * *// если монстр не находится в заданной точке * *if(Hlp_StrCmp(Npc_GetNearestWP(self),self.wp) == FALSE) * *{ * * * *// монстр идет в заданную точку * * * *AI_GotoWP(self,self.WP); * *}; * *// если есть свободная точка с именем "FP_ROAM" * *if(Wld_IsFPAvailable(self,"FP_ROAM")) * * *{ * * * *// монстр идет в эту точку * * * *AI_GotoFP(self,"FP_ROAM"); * *}; * *// анимация перехода в состояние кормежки * *AI_PlayAni(self,"T_STAND_2_EAT"); * *// анимация кормежки * *Mdl_ApplyRandomAni(self,"S_EAT","R_ROAM1"); * *Mdl_ApplyRandomAni(self,"S_EAT","R_ROAM2"); * *Mdl_ApplyRandomAni(self,"S_EAT","R_ROAM3"); * *Mdl_ApplyRandomAniFreq(self,"S_EAT",8.0); };
// Цткл состояния кормежки func int ZS_MM_Rtn_EatGround_Loop() { * *// если время кормежки истекло и время не контролируется программой поведения монстра * *if((!Wld_IsTime(self.aivar[AIV_MM_EatGroundStart],00,self.aivar[AIV_MM_EatGroundEnd],00)) && (self.aivar[AIV_MM_EatGroundStart] != OnlyRoutine)) * *{ * * * *// переход в планировщик суточного цикла * * * *AI_StartState(self,ZS_MM_AllScheduler,1,""); * * * *return LOOP_END; * *}; * *return LOOP_CONTINUE; };
// Завершение состояния кормежки func void ZS_MM_Rtn_EatGround_End() { * *// анимация выхода из состояния кормежки * *AI_PlayAni(self,"T_EAT_2_STAND"); };
... еще файл
// ************************************** // Обработчик состояния резвости монстра // **************************************
// Инициализация состояния резвости func void ZS_MM_Rtn_Wusel() { * *// разрешить нормальный набор восприятий * *Perception_Set_Monster_Rtn(); * *// режим пережвижения бегом * *AI_SetWalkmode(self,NPC_RUN); * *// если монстр не находится в заданной точке * *if(Hlp_StrCmp(Npc_GetNearestWP(self),self.wp) == FALSE) * *{ * * * *// монстр бежит в заданную точку * * * *AI_GotoWP(self,self.WP); * *}; * *// монстр бежит на свободную точку "FP_ROAM" * *AI_GotoFP(self,"FP_ROAM"); };
// Цикл состояния резвости func int ZS_MM_Rtn_Wusel_loop() { * *// если время резвости истекло и время не контролируется программой поведения монстра * *if((!Wld_IsTime(self.aivar[AIV_MM_WuselStart],00,self.aivar[AIV_MM_WuselEnd],00)) && (self.aivar[AIV_MM_WuselStart] != OnlyRoutine)) * *{ * * * *// переход в планировщик суточного цикла * * * *AI_StartState(self,ZS_MM_AllScheduler,1,""); * * * *return LOOP_END; * *}; * *// если монстр находится в этом состоянии >= 1 сек * *if(Npc_GetStateTime (self) >= 1) * *{ * * * *// если монстр находится в точке "FP_ROAM" * * * *if(Npc_IsOnFP(self,"FP_ROAM")) * * * *{ * * * * * *// поиск следующей свободной точки * * * * * *if(Wld_IsNextFPAvailable(self,"FP_ROAM")) * * * * * *{ * * * * * * * *// очистка очереди AI состояний монстра * * * * * * * *Npc_ClearAIQueue(self); * * * * * * * *// переход на новую свободную точку * * * * * * * *AI_GotoNextFP(self,"FP_ROAM"); * * * * * *}; * * * *} * * * *else // если не дошел до точки * * * *{ * * * * * *// если монстр не идет и не бежит * * * * * *if(!C_BodyStateContains(self,BS_WALK)) && (!C_BodyStateContains(self,BS_RUN)) * * * * * *{ * * * * * * * *// переход в свободную точку * * * * * * * *AI_GotoFP(self,"FP_ROAM"); * * * * * *}; * * * *}; * * * *// сброс времени цикла * * * *Npc_SetStateTime(self,0); * * * *// здесь лишний (можно удалить) * * * *self.aivar[AIV_TAPOSITION] = NOTINPOS; * *}; * * *return LOOP_CONTINUE; };
// Завершение состояния резвости func void ZS_MM_Rtn_Wusel_end() { };
... и еще файл
// ************************************ // Обработчик сидячего состояния орков // ************************************
// Инициализация состояния func void ZS_MM_Rtn_OrcSit() { * *// разрешить нормальный набор восприятий * *Perception_Set_Monster_Rtn(); * *// установить режим передвижения шагом * *AI_SetWalkmode(self,NPC_WALK); * *B_MM_DeSynchronize(); * *// если монстр не находится в заданной точке * *if(Hlp_StrCmp(Npc_GetNearestWP(self),self.wp) == FALSE) * *{ * * * *// монстр идет в заданную точку * * * *AI_GotoWP(self,self.WP); * *}; * *// сброс флага достижения точки сидения * *self.aivar[AIV_TAPOSITION] = NOTINPOS; };
// Цикл состояния func int ZS_MM_Rtn_OrcSit_loop() { * *// если время сидения истекло и время не контролируется программой поведения монстра * *if((!Wld_IsTime(self.aivar[AIV_MM_OrcSitStart],00,self.aivar[AIV_MM_OrcSitEnd],00)) && (self.aivar[AIV_MM_OrcSitStart] != OnlyRoutine)) * *{ * * * *// переход в планировщик суточного цикла * * * *AI_StartState(self,ZS_MM_AllScheduler,1,""); * * * *return LOOP_END; * *}; * *// если точка сидения не достигнута * *if(self.aivar[AIV_TAPOSITION] == NOTINPOS) * *{ * * * *// если есть свободная точка "FP_CAMPFIRE" * * * *if(Wld_IsFPAvailable(self,"FP_CAMPFIRE")) * * * *{ * * * * * *// монстр идет в эту точку * * * * * *AI_GotoFP(self,"FP_CAMPFIRE"); * * * *}; * * * *// если монстр находится в точке "FP_CAMPFIRE" * * * *if(Npc_IsOnFP(self,"FP_CAMPFIRE")) * * * *{ * * * * * *// анимация сидящего орка * * * * * *AI_PlayAniBS(self,"T_STAND_2_GUARDSLEEP",BS_SIT); * * * * * *// установка флага достижения точки * * * * * *self.aivar[AIV_TAPOSITION] = ISINPOS; * * * *}; * *} * *else // лишнее, можно удалить! * *{ * *}; * *return LOOP_CONTINUE; };
// Завершение состояния func void ZS_MM_Rtn_OrcSit_end() { * *// анимация выхода из сидячего положения * *AI_PlayAniBS(self,"T_GUARDSLEEP_2_STAND",BS_STAND ); };
|
|
|
03.03.2005, 09:30
|
#119
|
|
Re: Уроки скриптологии
Несколько обработчиков состояний для некоторых типов монстров.
// ************************************ // Обработчик состояния отдыха дракона // ************************************
// Инициализация состояния func void ZS_MM_Rtn_DragonRest() * { * *// установить время реакции на восприятия 1 сек * *Npc_SetPercTime(self,1); * *// приоритет на питание * *self.aivar[AIV_MM_PRIORITY] = PRIO_EAT; * *// если дракон не тестовый (строки программы, отмеченные в конце //*** можно удалить) * *if(Hlp_GetInstanceID(self) != Hlp_GetInstanceID(Dragon_Testmodell)) //*** * *{ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //*** * * * *// разрешить нормальный набор восприятий * * * *Perception_Set_Monster_Rtn(); * * * *// разрешить восприятие ГГ * * * *Npc_PercEnable(self,PERC_ASSESSPLAYER,B_MM_Assess Player); * *}; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//*** * *// разрешить восприятие разговора * *Npc_PercEnable(self,PERC_ASSESSTALK,B_AssessTalk) ; * *// установить режим передвижения шагом * *AI_SetWalkmode(self,NPC_WALK); * *B_MM_DeSynchronize(); * *// если монстр не находится в заданной точке * *if(Hlp_StrCmp(Npc_GetNearestWP(self),self.wp) == FALSE) * *{ * * * *// монстр идет в заданную точку * * * *AI_GotoWP(self,self.WP); * *}; * *// если есть свободная точка с именем "FP_ROAM" * *if(Wld_IsFPAvailable(self,"FP_ROAM")) * * *{ * * * *// монстр идет в эту точку * * * *AI_GotoFP(self,"FP_ROAM"); * *} * *else // иначе * *{ * * * *// выравнивание в точке * * * *AI_AlignToWP(self); * *}; * *// сброс счетчика цикла регенерации * *self.aivar[AIV_TAPOSITION] = 0; };
// Цикл состояния func int ZS_MM_Rtn_DragonRest_Loop() { * *// если время отдыха истекло и время не контролируется программой поведения монстра * *if((!Wld_IsTime(self.aivar[AIV_MM_RestStart],00,self.aivar[AIV_MM_RestEnd],00)) && (self.aivar[AIV_MM_RestStart] != OnlyRoutine)) * *{ * * * *// переход в планировщик суточного цикла * * * *AI_StartState(self,ZS_MM_AllScheduler,1,""); * * * *return LOOP_END; * *}; * *// если НПС дракон * *if(self.guild == GIL_DRAGON) * *{ * * * *// счетчик цикла регенерации ++ * * * *self.aivar[AIV_TAPOSITION] += 1; * * * *// если жизнь дракона < максимальной и прошло не менее 2 сек * * * *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; * * * *}; * *}; * *// с вероятностью 0,005 менять анимацию монстра * *if(Hlp_Random(1000) <= 5) * *{ * * * *var int randomMove; * * * *randomMove = Hlp_Random(3); * * * *AI_StandUp(self); * * * *if(randomMove == 0) { AI_PlayAni(self,"R_ROAM1"); }; * * * *if(randomMove == 1) { AI_PlayAni(self,"R_ROAM2"); }; * * * *if(randomMove == 2) { AI_PlayAni(self,"R_ROAM3"); }; * *}; * *return LOOP_CONTINUE; };
// Завершение состояния func void ZS_MM_Rtn_DragonRest_End() { * *// анимация выхода из отдыха * *AI_PlayAni(self,"T_REST_2_STAND"); };
... еще файл
// ******************************************* // Обработчик состояния когда овца идет за ГГ // *******************************************
// Инициализация состояния func void ZS_MM_Rtn_Follow_Sheep() { * *// установить время реакции на восприятия 1 сек * *Npc_SetPercTime(self,1); * *// разрешить восприятие ГГ * *Npc_PercEnable(self,PERC_ASSESSPLAYER,B_MM_Assess Player); * *// разрешить восприятие разговора * *Npc_PercEnable(self,PERC_ASSESSTALK,B_AssessTalk) ; * *// разрешить восприятие магии * *Npc_PercEnable(self,PERC_ASSESSMAGIC,B_AssessMagi c); };
// Цикл состояния func int ZS_MM_Rtn_Follow_Sheep_Loop() { * *// если НПС член партии ГГ * *if(self.aivar[AIV_PARTYMEMBER] == TRUE) * *{ * * * *// если расстояние между НПС и ГГ > 5 метров * * * *if(Npc_GetDistToNpc(self,hero) > 500) * * * *{ * * * * * *// если НПС не плывет * * * * * *if(!C_BodyStateContains(self,BS_SWIM)) * * * * * *{ * * * * * * * * *// НПС переходит на бег * * * * * * * *AI_SetWalkmode(self,NPC_RUN); * * * * * *}; * * * * * *// НПС движется к ГГ * * * * * *AI_GotoNpc(self,hero); * * * *} * * * *else // иначе * * * *{ * * * * * *// НПС поворачивается к ГГ * * * * * *AI_TurnToNpc(self,hero); * * * * * *// установить для НПС ближайшую свободную точку * * * * * *self.wp = Npc_GetNearestWP(self); * * * *}; * *} * *else // иначе * *{ * * * *// анимация * * * *var int randomMove; * * * *randomMove = Hlp_Random(3); * * * *if(randomMove == 0) { AI_PlayAni(self,"R_ROAM1"); }; * * * *if(randomMove == 1) { AI_PlayAni(self,"R_ROAM2"); }; * * * *if(randomMove == 2) { AI_PlayAni(self,"R_ROAM3"); }; * *}; * *return LOOP_CONTINUE; };
// Завершение состояния func void ZS_MM_Rtn_Follow_Sheep_End() { };
// ************************************************** ** // Обработчик состояния когда овца идет за Бальтасаром // ************************************************** **
// Инициализация состояния func void ZS_MM_Rtn_Follow_Sheep_Balthasar() { * *// установить время реакции на восприятия 1 сек * *Npc_SetPercTime(self,1); * *// разрешить восприятие ГГ * *Npc_PercEnable(self,PERC_ASSESSPLAYER,B_MM_Assess Player); };
// Цикл состояния func int ZS_MM_Rtn_Follow_Sheep_Balthasar_Loop() { * *// если расстояние между Бальтасаром и точкой "NW_BIGMILL_FARM3_BALTHASAR" > 5 м * *if(Npc_GetDistToWP(Balthasar,"NW_BIGMILL_FARM3_BA LTHASAR") > 500) * *{ * * * *// если расстояние между НПС и Бальтасаром > 5 метров * * * *if(Npc_GetDistToNpc(self,Balthasar) > 500) * * * *{ * * * * * *// если НПС не плывет * * * * * *if(!C_BodyStateContains(self,BS_SWIM)) * * * * * *{ * * * * * * * * *// НПС переходит на бег * * * * * * * *AI_SetWalkmode(self,NPC_RUN); * * * * * *}; * * * * * *// НПС движется к Бальтасару * * * * * *AI_GotoNpc(self,Balthasar); * * * *} * * * *else // иначе * * * *{ * * * * * *// НПС поворачивается к Бальтасару * * * * * *AI_TurnToNpc(self,Balthasar); * * * * * *// установить для НПС ближайшую свободную точку * * * * * *self.WP = Npc_GetNearestWP(self); * * * *}; * *} * *else // иначе (когда пришли) * *{ * * * *// переход НПС в состояние брожения около точки "NW_BIGMILL_FARM3_BALTHASAR" * * * *AI_StartState(self,ZS_MM_Rtn_Roam,1,"NW_BIGMILL_F ARM3_BALTHASAR" ); * *}; * *return LOOP_CONTINUE; };
// Завершение состояния func void ZS_MM_Rtn_Follow_Sheep_Balthasar_End () { };
... и еще файл
// **************************************** // Обработчик поведения вызванного монстра // ****************************************
// Локальное восприятие разговора с ГГ func void B_SummonedAssessTalk() { * *// вызванный монстр умирает (жизнь = 0) * *Npc_ChangeAttribute(self,ATR_HITPOINTS,-self.attribute[ATR_HITPOINTS_MAX]) ; };
// Инициализация состояния func void ZS_MM_Rtn_Summoned() { * *// установить время реакции на восприятия 1 сек * *Npc_SetPercTime(self,1); * *// разрешить восприятие ГГ * *Npc_PercEnable(self,PERC_ASSESSPLAYER,B_MM_Assess Player); * *// разрешить восприятие врага * *Npc_PercEnable(self,PERC_ASSESSENEMY,B_MM_AssessE nemy); * *// разрешить восприятие магии * *Npc_PercEnable(self,PERC_ASSESSMAGIC,B_AssessMagi c); * *// разрешить восприятие повреждения * *Npc_PercEnable(self,PERC_ASSESSDAMAGE,B_MM_Assess Damage); * *// разрешить восприятие сражения двух других НПС * *Npc_PercEnable(self,PERC_ASSESSFIGHTSOUND,B_MM_As sessOthersDamage); * *// если вызванный НПС Огонек * *if(Hlp_GetInstanceID(self) == Hlp_GetInstanceID(Wisp_Detector)) * *{ * * * *// разрешить восприятие разговора * * * *Npc_PercEnable(self,PERC_ASSESSTALK,B_AssessTalk) ; * *} * *else // иначе (если монстр) * *{ * * * *// разрешить локальное восприятие разговора * * * *Npc_PercEnable(self,PERC_ASSESSTALK,B_SummonedAss essTalk); * *}; * *// установить дружеское отношение к ГГ * *B_SetAttitude(self,ATT_FRIENDLY); * *// НПС член партии ГГ * *self.aivar[AIV_PARTYMEMBER] = TRUE; * *// НПС встает * *AI_StandUp(self); * *// режим передвижения - бег * *AI_SetWalkmode(self,NPC_RUN); };
// Цикл состояния func int ZS_MM_Rtn_Summoned_Loop() { * *// Выполнение Огоньком заданий * *B_MM_WispDetect(); * *// если расстояние между НПС и ГГ > 5 метров * *if(Npc_GetDistToNpc (self, hero) > 500) * *{ * * * *// НПС бежит к ГГ * * * *AI_GotoNpc(self,hero); * *} * *else //иначе * *{ * * * *// если прошла секунда * * * *if(Npc_GetStateTime(self) >= 1) * * * *{ * * * * * *// если НПС не видит ГГ * * * * * *if(!Npc_CanSeeNpc(self,hero)) * * * * * *{ * * * * * * * *// НПС поворачивается к ГГ * * * * * * * *AI_TurnToNpc(self,hero); * * * * * *}; * * * * * *// увеличение времени вызова монстра * * * * * *self.aivar[AIV_SummonTime] = (self.aivar[AIV_SummonTime] + Npc_GetStateTime(self)); * * * * * *// если время вызова монстра превысило время жизни * * * * * *if(self.aivar[AIV_SummonTime] >= MONSTER_SUMMON_TIME) * * * * * *{ * * * * * * * *// вызванный монстр умирает (жизнь = 0) * * * * * * * *Npc_ChangeAttribute(self,ATR_HITPOINTS,-self.attribute[ATR_HITPOINTS_MAX]) ; * * * * * *}; * * * * * *// сброс времени состояния * * * * * *Npc_SetStateTime (self, 0); * * * *}; * *}; * *// установить для НПС ближайшую свободную точку * *self.wp = Npc_GetNearestWP(self); * *return LOOP_CONTINUE; };
// Завершение состояния func void ZS_MM_Rtn_Summoned_End() { };
|
|
|
04.03.2005, 09:40
|
#120
|
|
Re: Уроки скриптологии
12. Вспомогательные В_ функции для людей.
Все В_ функции расположены в директории ..\AI\Human\B_Human\
// ************************************************** ****** // Функция переводящая НПС в состояние атаки // ************************************************** ****** * * // ====================================== // Аргументы: // -------------------------------------- // slf * * * * * * *- атакующий НПС (далее - агрессор) // oth * * * * * * *- атакуемый НПС (далее - жертва) // attack_reason * *- причина атаки // wait * * * * * * - время выжидания перед атакой // ======================================
func void B_Attack(var C_NPC slf,var C_NPC oth,var int attack_reason,var int wait) { * *// установить агрессору время задержки перед атакой * *slf.aivar[AIV_WaitBeforeAttack] = wait; * *// если агрессор должен атаковать немедленно * *if(attack_reason == AR_SuddenEnemyInferno) * *{ * * * *// установить агрессору флаг наличия врага * * * *slf.aivar[AIV_EnemyOverride] = FALSE; * * * *// послать жертве восприятие нападения * * * *Npc_SendPassivePerc(slf,PERC_ASSESSFIGHTSOUND,slf ,oth); * *}; * *// если агрессор находится в состоянии разговора * *if(Npc_IsInState(slf,ZS_Talk)) * *{ * * * *// закончить разговор агрессору * * * *slf.aivar[AIV_INVINCIBLE] = FALSE; * * * *// закончить разговор жертве * * * *oth.aivar[AIV_INVINCIBLE] = FALSE; * *}; * *// если агрессор находится в состоянии атаки и жертва есть последняя цель агрессора * *if(Npc_IsInState(slf,ZS_Attack)) && (Hlp_GetInstanceID(oth) == slf.aivar[AIV_LASTTARGET]) * *{ * * * *// если причина атаки агрессора не убийство жертвы и новая причина атаки приоритетней существующей причины атаки * * * *if(!C_NpcHasAttackReasonToKill(slf)) && (attack_reason > slf.aivar[AIV_ATTACKREASON]) * * * *{ * * * * * *// установить агрессору новую причину атаки * * * * * *slf.aivar[AIV_ATTACKREASON] = attack_reason; * * * * * *// если жертва ГГ * * * * * *if(Npc_IsPlayer(oth)) * * * * * *{ * * * * * * * *// установить агрессору причину атаки ГГ * * * * * * * *slf.aivar[AIV_LastPlayerAR] = attack_reason; * * * * * *}; * * * *}; * *} * *else // иначе * *{ * * * * *// установить агрессору новую причину атаки * * * *slf.aivar[AIV_ATTACKREASON] = attack_reason; * * * *// если жертва ГГ * * * *if (Npc_IsPlayer(oth)) * * * *{ * * * * * *// установить агрессору причину атаки ГГ * * * * * *slf.aivar[AIV_LastPlayerAR] = attack_reason; * * * *}; * *}; * *// если агрессор атакует убийцу овец * *if(slf.aivar[AIV_ATTACKREASON] == AR_SheepKiller) * *{ * * * *// запоминается новость, что жертва убила овцу * * * *B_MemorizePlayerCrime(slf,oth,CRIME_SHEEPKILLER); * *}; * *// если причина атаки вызвана повреждением агрессора или является реакцией на обнаженное оружие * *if(slf.aivar[AIV_ATTACKREASON] == AR_ReactToDamage) ¦¦ (slf.aivar[AIV_ATTACKREASON] == AR_ReactToWeapon) * *{ * * * *// если агрессор имеет дело не с "крутым парнем" и (жертва не ГГ и не друг агрессору) * * * *if(!C_NpcIsToughGuy(slf)) && (!(Npc_IsPlayer(oth) && (slf.npctype == NPCTYPE_FRIEND))) * * * *{ * * * * * *// запоминается новость, что ГГ сражался с НПС * * * * * *B_MemorizePlayerCrime(slf,oth,CRIME_ATTACK); * * * *}; * *}; * *// если причина атаки воровство или использование МОВа * *if(slf.aivar[AIV_ATTACKREASON] == AR_Theft) ¦¦ (slf.aivar[AIV_ATTACKREASON] == AR_UseMob) * *{ * * * *// запоминается новость, что ГГ воровал * * * *B_MemorizePlayerCrime(slf,oth,CRIME_THEFT); * *}; * *// если причина атаки убийство человека * *if(slf.aivar[AIV_ATTACKREASON] == AR_HumanMurderedHuman) * *{ * * * *// запоминается новость, что ГГ совершил убийство * * * *B_MemorizePlayerCrime(slf,oth,CRIME_MURDER); * *}; * *// если агрессор уже в состоянии атаки * *if(Npc_IsInState(slf,ZS_Attack)) * *{ * * * *return; * *}; * *// если причина атаки убийство * *if (slf.aivar[AIV_ATTACKREASON] == AR_KILL) * *{ * * * *// установить враждебное отношение агрессора к ГГ * * * *B_SetAttitude(slf,ATT_HOSTILE); * *}; * *// если ГГ жертва * *if(Npc_IsPlayer(oth)) * *{ * * * *// параметр последнего сражения с ГГ - прервано * * * *slf.aivar[AIV_LastFightAgainstPlayer] = FIGHT_CANCEL; * * * *// последнее сражение не комментировалось * * * *slf.aivar[AIV_LastFightComment] = FALSE; * *}; * *// если агрессор не в состоянии разговора * *if(!Npc_IsInState(slf,ZS_Talk)) * *{ * * * *// очистить очередь AI состояний агрессора * * * *Npc_ClearAIQueue(slf); * *}; * *// запретить агрессору восприятия * *B_ClearPerceptions(slf); * *// установить в качестве цели жертву * *Npc_SetTarget(slf,oth); * *// если агрессор лежит * *if(C_BodyStateContains(slf,BS_LIE)) * *{ * * * *// переход в состояние атаки с завершением предыдущего состояния * * * *AI_StartState(slf,ZS_Attack,1,""); * *} * *else // иначе * *{ * * * *// немедленный переход в состояние атаки * * * *AI_StartState(slf,ZS_Attack,0,""); * *}; * *return; };
... еще один файл
// ************************************** // Функция вызова охраны // -------------------------------------- // self - НПС агрессор, other - НПС жертва // **************************************
// Функция проверки, может ли НПС вызвать охрану // ================================================== ========= // Аргумент: slf - НПС вызывающий охрану // ----------------------------------------------------------- // Возвращает: TRUE - охрана может быть вызвана, иначе - FALSE. // ================================================== ========= func int C_WantToCallGuards(var C_NPC slf) { * *// если агрессор не является членом партии ГГ * *if(self.aivar[AIV_PARTYMEMBER] == FALSE) * *{ * * * *// если НПС принадлежит к * * * *if(slf.guild == GIL_PAL) * *// паладинам * * * *¦¦ (slf.guild == GIL_MIL) * // или милиции * * * *¦¦ (slf.guild == GIL_VLK) * // или горожанам * * * *¦¦ (slf.guild == GIL_SLD) * // или наемникам * * * *¦¦ (slf.guild == GIL_BAU) * // или крестьянам * * * *{ * * * * * *// охрана может быть вызвана * * * * * *return TRUE; * * * *}; * *}; * *// охрану вызвать нельзя * *return FALSE; };
// Вызов охраны func void B_CallGuards() { * *// если агрессор не может вызвать охрану * *if(!C_WantToCallGuards(self)) * *{ * * * *return; * *}; * *// если причина атаки * *if(self.aivar[AIV_ATTACKREASON] == AR_GuardCalledToKill) * *// вызвана охрана по факту убийства * *¦¦ (self.aivar[AIV_ATTACKREASON] == AR_GuardStopsFight) * * // или охрана прекратила атаковать преступника * *¦¦ (self.aivar[AIV_ATTACKREASON] == AR_GuardCalledToThief) *// или охрана вызвана по факту воровства * *¦¦ (self.aivar[AIV_ATTACKREASON] == AR_GuardCalledToRoom) * // или охрана вызвана для защиты помещения * *{ * * * *// агрессор говорит жертве (SVM фраза "ТРЕВОГА!") * * * *B_Say_Overlay(self,other,"$ALARM"); * * * *return; * *}; * * * * *// если причина атаки - нападение на врага или убийство человека * *if(self.aivar[AIV_ATTACKREASON] == AR_GuildEnemy) ¦¦ (self.aivar[AIV_ATTACKREASON] == AR_HumanMurderedHuman) * *{ * * * *// если агрессор милиционер или паладин или наемник * * * *if(self.guild == GIL_MIL) ¦¦ (self.guild == GIL_PAL) ¦¦ (self.guild == GIL_SLD) * * * *{ * * * * * *// агрессор говорит жертве (SVM фраза "ТРЕВОГА!") * * * * * *B_Say_Overlay(self,other,"$ALARM"); * * * * * *// агрессор посылает восприятие нападения * * * * * *Npc_SendPassivePerc(self,PERC_ASSESSFIGHTSOUND,se lf,other); * * * * * *return; * * * *}; * * * *// если агрессор имеет дело не с "крутым парнем" * * * *if(!C_NpcIsToughGuy(self)) * * * *{ * * * * * *// агрессор говорит жертве (SVM фраза "ОХРАНА!") * * * * * *B_Say_Overlay(self,other,"$GUARDS"); * * * * * *// агрессор посылает восприятие нападения * * * * * *Npc_SendPassivePerc(self,PERC_ASSESSFIGHTSOUND,se lf,other); * * * * * *return; * * * *}; * * * *return; * *}; * *// если охрана ворот атакует незваного гостя * *if(self.aivar[AIV_ATTACKREASON] == AR_GuardStopsIntruder) * *{ * * * *// агрессор говорит жертве (SVM фраза "ТРЕВОГА!") * * * *B_Say_Overlay(self,other,"$ALARM"); * * * *// агрессор посылает восприятие нападения * * * *Npc_SendPassivePerc(self,PERC_ASSESSFIGHTSOUND,se lf,other); * * * *return; * *}; * *// если причина атаки воровство или использование чужого МОВа * *if(self.aivar[AIV_ATTACKREASON] == AR_Theft) ¦¦ (self.aivar[AIV_ATTACKREASON] == AR_UseMob) * *{ * * * *// если агрессор имеет дело не с "крутым парнем" * * * *if(!C_NpcIsToughGuy(self)) * * * *{ * * * * * *// агрессор говорит жертве (SVM фраза "ОХРАНА!") * * * * * *B_Say_Overlay(self,other,"$GUARDS"); * * * * * *// агрессор посылает восприятие нападения * * * * * *Npc_SendPassivePerc(self,PERC_ASSESSFIGHTSOUND,se lf,other); * * * *}; * * * *return; * *}; * *// если причина нападения - реакция на обнаженное оружие * *if (self.aivar[AIV_ATTACKREASON] == AR_ReactToWeapon) * *{ * * * *// если агрессор имеет дело не с "крутым парнем" * * * *if(!C_NpcIsToughGuy(self)) * * * *{ * * * * * *// агрессор говорит жертве (SVM фраза "ОХРАНА!") * * * * * *B_Say_Overlay(self,other,"$GUARDS"); * * * * * *// агрессор посылает восприятие нападения * * * * * *Npc_SendPassivePerc(self,PERC_ASSESSFIGHTSOUND,se lf,other); * * * *}; * * * *return; * *}; * *// если причина нападения - посягательство на чужое помещение * *if(self.aivar[AIV_ATTACKREASON] == AR_ClearRoom) * *{ * * * *// если агрессор милиционер или паладин или наемник * * * *if(self.guild == GIL_MIL) ¦¦ (self.guild == GIL_PAL) ¦¦ (self.guild == GIL_SLD) * * * *{ * * * * * *// агрессор говорит жертве (SVM фраза "ТРЕВОГА!") * * * * * *B_Say_Overlay(self,other,"$ALARM"); * * * * * *// агрессор посылает восприятие нападения * * * * * *Npc_SendPassivePerc(self,PERC_ASSESSFIGHTSOUND,se lf,other); * * * * * *return; * * * *}; * * * *// если агрессор имеет дело не с "крутым парнем" * * * *if(!C_NpcIsToughGuy(self)) * * * *{ * * * * * *// агрессор говорит жертве (SVM фраза "ОХРАНА!") * * * * * *B_Say_Overlay(self,other,"$GUARDS"); * * * * * *// агрессор посылает восприятие нападения * * * * * *Npc_SendPassivePerc(self,PERC_ASSESSFIGHTSOUND,se lf,other); * * * * * *return; * * * *}; * * * *return; * *}; * *return; }; *
|
|
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
Опции темы |
Поиск в этой теме |
|
|
Ваши права в разделе
|
|
|
|
Текущее время: 05:19. Часовой пояс GMT +4.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|