// *******************************************************
// Функция реакции НПС (людей) на ГГ (обработка активного восприятия PERC_ASSESSPLAYER).
// ГГ должен быть в поле зрения НПС (люди не имеют чувства обоняния)
// Макс. дистанция реакции на ГГ - PERC_DIST_ACTIVE_MAX.
// *******************************************************
func void B_AssessPlayer()
{
// other в функции - ГГ, self - НПС
// Если ГГ находится в режиме диалога
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;
};