mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2025-06-01 00:17:43 +03:00
Shadow Walker: WIP extract most shadow walker functionality into base class
This commit is contained in:
parent
6284c20d20
commit
5416871138
@ -294,7 +294,7 @@ bool CNPC_BaseCustomNPC::HasRangedWeapon()
|
|||||||
CBaseCombatWeapon *pWeapon = GetActiveWeapon();
|
CBaseCombatWeapon *pWeapon = GetActiveWeapon();
|
||||||
|
|
||||||
if (pWeapon)
|
if (pWeapon)
|
||||||
return !(FClassnameIs(pWeapon, "weapon_crowbar") || FClassnameIs(pWeapon, "weapon_stunstick"));
|
return !(FClassnameIs(pWeapon, "weapon_crowbar") || FClassnameIs(pWeapon, "weapon_stunstick") || FClassnameIs(pWeapon, "weapon_custommelee"));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -13,10 +13,8 @@
|
|||||||
#include "cbase.h"
|
#include "cbase.h"
|
||||||
#include "npc_shadow_walker.h"
|
#include "npc_shadow_walker.h"
|
||||||
#include "ai_hull.h"
|
#include "ai_hull.h"
|
||||||
#include "soundent.h"
|
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "npcevent.h"
|
#include "npcevent.h"
|
||||||
#include "engine/IEngineSound.h"
|
|
||||||
#include "basehlcombatweapon_shared.h"
|
#include "basehlcombatweapon_shared.h"
|
||||||
#include "ai_squadslot.h"
|
#include "ai_squadslot.h"
|
||||||
#include "weapon_custom_melee.h"
|
#include "weapon_custom_melee.h"
|
||||||
@ -25,13 +23,15 @@
|
|||||||
// memdbgon must be the last include file in a .cpp file!!!
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
#include "tier0/memdbgon.h"
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Constants
|
// Purpose: Initialize the custom schedules
|
||||||
//---------------------------------------------------------
|
// Input :
|
||||||
const float MIN_TIME_NEXT_SOUND = 0.5f;
|
// Output :
|
||||||
const float MAX_TIME_NEXT_SOUND = 1.0f;
|
//-----------------------------------------------------------------------------
|
||||||
const float MIN_TIME_NEXT_FOUNDENEMY_SOUND = 2.0f;
|
void CNPC_ShadowWalker::InitCustomSchedules(void)
|
||||||
const float MAX_TIME_NEXT_FOUNDENEMY_SOUND = 5.0f;
|
{
|
||||||
|
INIT_CUSTOM_AI(CNPC_ShadowWalker);
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Purpose:
|
// Purpose:
|
||||||
@ -183,41 +183,6 @@ int CNPC_ShadowWalker::SelectFailSchedule(int failedSchedule, int failedTask, AI
|
|||||||
return BaseClass::SelectFailSchedule(failedSchedule, failedTask, taskFailCode);
|
return BaseClass::SelectFailSchedule(failedSchedule, failedTask, taskFailCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Purpose: Select a schedule to retrieve better weapons if they are available.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
int CNPC_ShadowWalker::SelectScheduleRetrieveItem()
|
|
||||||
{
|
|
||||||
if (m_bCanPickupWeapons && HasCondition(COND_BETTER_WEAPON_AVAILABLE))
|
|
||||||
{
|
|
||||||
CBaseHLCombatWeapon *pWeapon = dynamic_cast<CBaseHLCombatWeapon *>(Weapon_FindUsable(WEAPON_SEARCH_DELTA));
|
|
||||||
if (pWeapon)
|
|
||||||
{
|
|
||||||
m_flNextWeaponSearchTime = gpGlobals->curtime + 10.0;
|
|
||||||
// Now lock the weapon for several seconds while we go to pick it up.
|
|
||||||
pWeapon->Lock(10.0, this);
|
|
||||||
SetTarget(pWeapon);
|
|
||||||
return SCHED_NEW_WEAPON;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return SCHED_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Purpose: Select a schedule to retrieve better weapons if they are available.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
int CNPC_ShadowWalker::SelectScheduleWander()
|
|
||||||
{
|
|
||||||
m_bWanderToggle = !m_bWanderToggle;
|
|
||||||
if (m_bWanderToggle) {
|
|
||||||
return SCHED_IDLE_WANDER;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return SCHED_NONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Purpose: Select a schedule to execute based on conditions.
|
// Purpose: Select a schedule to execute based on conditions.
|
||||||
// This is the most critical AI method.
|
// This is the most critical AI method.
|
||||||
@ -433,16 +398,6 @@ int CNPC_ShadowWalker::SelectCombatSchedule()
|
|||||||
return SCHED_FAIL;
|
return SCHED_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CNPC_ShadowWalker::HasRangedWeapon()
|
|
||||||
{
|
|
||||||
CBaseCombatWeapon *pWeapon = GetActiveWeapon();
|
|
||||||
|
|
||||||
if (pWeapon)
|
|
||||||
return !(FClassnameIs(pWeapon, "weapon_crowbar") || FClassnameIs(pWeapon, "weapon_stunstick") || FClassnameIs(pWeapon, "weapon_custommelee"));
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Purpose: Override base class schedules
|
// Purpose: Override base class schedules
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -482,111 +437,6 @@ Activity CNPC_ShadowWalker::NPC_TranslateActivity(Activity activity)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Purpose: Play sound when an enemy is spotted. This sound has a separate
|
|
||||||
// timer from other sounds to prevent looping if the NPC gets caught
|
|
||||||
// in a 'found enemy' condition.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void CNPC_ShadowWalker::FoundEnemySound(void)
|
|
||||||
{
|
|
||||||
if (gpGlobals->curtime > m_flNextFoundEnemySoundTime)
|
|
||||||
{
|
|
||||||
m_flNextFoundEnemySoundTime = gpGlobals->curtime + random->RandomFloat(MIN_TIME_NEXT_FOUNDENEMY_SOUND, MAX_TIME_NEXT_FOUNDENEMY_SOUND);
|
|
||||||
PlaySound(m_iszFoundEnemySound, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Purpose: Play NPC soundscript
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void CNPC_ShadowWalker::PlaySound(string_t soundname, bool required /*= false */)
|
|
||||||
{
|
|
||||||
// TODO: Check if silent
|
|
||||||
if (required || gpGlobals->curtime > m_flNextSoundTime)
|
|
||||||
{
|
|
||||||
m_flNextSoundTime = gpGlobals->curtime + random->RandomFloat(MIN_TIME_NEXT_SOUND, MAX_TIME_NEXT_SOUND);
|
|
||||||
//CPASAttenuationFilter filter2(this, STRING(soundname));
|
|
||||||
EmitSound(STRING(soundname));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Purpose: Assign a default soundscript if none is provided, then precache
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void CNPC_ShadowWalker::PrecacheNPCSoundScript(string_t * SoundName, string_t defaultSoundName)
|
|
||||||
{
|
|
||||||
if (!SoundName) {
|
|
||||||
*SoundName = defaultSoundName;
|
|
||||||
}
|
|
||||||
PrecacheScriptSound(STRING(*SoundName));
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Purpose: Get movement speed, multipled by modifier
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
float CNPC_ShadowWalker::GetSequenceGroundSpeed(CStudioHdr *pStudioHdr, int iSequence)
|
|
||||||
{
|
|
||||||
float t = SequenceDuration(pStudioHdr, iSequence);
|
|
||||||
|
|
||||||
if (t > 0)
|
|
||||||
{
|
|
||||||
return (GetSequenceMoveDist(pStudioHdr, iSequence) * m_flSpeedModifier / t);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Purpose: Hammer input to change the speed of the NPC
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void CNPC_ShadowWalker::InputSetSpeedModifier(inputdata_t &inputdata)
|
|
||||||
{
|
|
||||||
this->m_flSpeedModifier = inputdata.value.Float();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Purpose: Hammer input to enable opening doors
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void CNPC_ShadowWalker::InputEnableOpenDoors(inputdata_t &inputdata)
|
|
||||||
{
|
|
||||||
m_bCannotOpenDoors = false;
|
|
||||||
if (!HasSpawnFlags(SF_NPC_START_EFFICIENT))
|
|
||||||
{
|
|
||||||
CapabilitiesAdd(bits_CAP_DOORS_GROUP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Purpose: Hammer input to enable opening doors
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void CNPC_ShadowWalker::InputDisableOpenDoors(inputdata_t &inputdata)
|
|
||||||
{
|
|
||||||
m_bCannotOpenDoors = true;
|
|
||||||
if (!HasSpawnFlags(SF_NPC_START_EFFICIENT))
|
|
||||||
{
|
|
||||||
CapabilitiesRemove(bits_CAP_DOORS_GROUP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Purpose: Hammer input to enable weapon pickup behavior
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void CNPC_ShadowWalker::InputEnablePickupWeapons(inputdata_t &inputdata)
|
|
||||||
{
|
|
||||||
m_bCanPickupWeapons = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Purpose: Hammer input to enable weapon pickup behavior
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void CNPC_ShadowWalker::InputDisablePickupWeapons(inputdata_t &inputdata)
|
|
||||||
{
|
|
||||||
m_bCanPickupWeapons = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Purpose:
|
// Purpose:
|
||||||
//
|
//
|
||||||
|
@ -12,168 +12,40 @@
|
|||||||
//=============================================================================//
|
//=============================================================================//
|
||||||
#include "cbase.h"
|
#include "cbase.h"
|
||||||
#include "ai_default.h"
|
#include "ai_default.h"
|
||||||
#include "ai_task.h"
|
#include "npc_base_custom.h"
|
||||||
#include "ai_schedule.h"
|
|
||||||
#include "entitylist.h"
|
|
||||||
#include "activitylist.h"
|
|
||||||
#include "ai_basenpc.h"
|
|
||||||
#include "ai_blended_movement.h"
|
|
||||||
#include "ai_behavior_actbusy.h"
|
|
||||||
|
|
||||||
//=========================================================
|
//=========================================================
|
||||||
// schedules
|
|
||||||
//=========================================================
|
//=========================================================
|
||||||
enum
|
class CNPC_ShadowWalker : public CNPC_BaseCustomNPC
|
||||||
{
|
{
|
||||||
SCHED_MELEE_ATTACK_NOINTERRUPT = LAST_SHARED_SCHEDULE,
|
DECLARE_CLASS(CNPC_ShadowWalker, CNPC_BaseCustomNPC);
|
||||||
SCHED_HIDE,
|
|
||||||
|
|
||||||
LAST_SHADOW_WALKER_SCHED
|
|
||||||
};
|
|
||||||
|
|
||||||
//=========================================================
|
|
||||||
//=========================================================
|
|
||||||
typedef CAI_BlendingHost< CAI_BehaviorHost<CAI_BaseNPC> > CAI_CustomNPCBase;
|
|
||||||
|
|
||||||
class CNPC_ShadowWalker : public CAI_CustomNPCBase
|
|
||||||
{
|
|
||||||
DECLARE_CLASS(CNPC_ShadowWalker, CAI_CustomNPCBase);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Precache(void);
|
void Precache(void);
|
||||||
void Spawn(void);
|
void Spawn(void);
|
||||||
Class_T Classify(void);
|
Class_T Classify(void);
|
||||||
virtual int SelectFailSchedule(int failedSchedule, int failedTask, AI_TaskFailureCode_t taskFailCode);
|
virtual int SelectFailSchedule(int failedSchedule, int failedTask, AI_TaskFailureCode_t taskFailCode);
|
||||||
virtual int SelectScheduleRetrieveItem();
|
|
||||||
virtual int SelectScheduleWander();
|
|
||||||
virtual int SelectSchedule();
|
virtual int SelectSchedule();
|
||||||
virtual int SelectIdleSchedule();
|
virtual int SelectIdleSchedule();
|
||||||
virtual int SelectAlertSchedule();
|
virtual int SelectAlertSchedule();
|
||||||
virtual int SelectCombatSchedule();
|
virtual int SelectCombatSchedule();
|
||||||
virtual float GetSequenceGroundSpeed(CStudioHdr *pStudioHdr, int iSequence);
|
|
||||||
virtual Activity NPC_TranslateActivity(Activity eNewActivity);
|
virtual Activity NPC_TranslateActivity(Activity eNewActivity);
|
||||||
virtual int TranslateSchedule(int scheduleType);
|
virtual int TranslateSchedule(int scheduleType);
|
||||||
|
|
||||||
// Sounds
|
|
||||||
virtual void PlaySound(string_t soundname, bool optional);
|
|
||||||
virtual void DeathSound(const CTakeDamageInfo &info) { PlaySound(m_iszDeathSound, true); }
|
|
||||||
virtual void AlertSound(void) { PlaySound(m_iszAlertSound, false); };
|
|
||||||
virtual void IdleSound(void) { PlaySound(m_iszIdleSound, false); };
|
|
||||||
virtual void PainSound(const CTakeDamageInfo &info) { PlaySound(m_iszPainSound, true); };
|
|
||||||
virtual void FearSound(void) { PlaySound(m_iszFearSound, false); };
|
|
||||||
virtual void LostEnemySound(void) { PlaySound(m_iszLostEnemySound, false); };
|
|
||||||
virtual void FoundEnemySound(void);
|
|
||||||
|
|
||||||
void Activate();
|
void Activate();
|
||||||
void FixupWeapon();
|
void FixupWeapon();
|
||||||
|
|
||||||
// Inputs
|
|
||||||
virtual void InputSetSpeedModifier(inputdata_t &inputdata);
|
|
||||||
virtual void InputEnableOpenDoors(inputdata_t &inputdata);
|
|
||||||
virtual void InputDisableOpenDoors(inputdata_t &inputdata);
|
|
||||||
virtual void InputEnablePickupWeapons(inputdata_t &inputdata);
|
|
||||||
virtual void InputDisablePickupWeapons(inputdata_t &inputdata);
|
|
||||||
|
|
||||||
DECLARE_DATADESC();
|
DECLARE_DATADESC();
|
||||||
|
|
||||||
string_t m_iszWeaponModelName; // Path/filename of model to override weapon model.
|
|
||||||
|
|
||||||
string_t m_iszFearSound; // Path/filename of WAV file to play.
|
|
||||||
string_t m_iszDeathSound; // Path/filename of WAV file to play.
|
|
||||||
string_t m_iszIdleSound; // Path/filename of WAV file to play.
|
|
||||||
string_t m_iszPainSound; // Path/filename of WAV file to play.
|
|
||||||
string_t m_iszAlertSound; // Path/filename of WAV file to play.
|
|
||||||
string_t m_iszLostEnemySound; // Path/filename of WAV file to play.
|
|
||||||
string_t m_iszFoundEnemySound; // Path/filename of WAV file to play.
|
|
||||||
|
|
||||||
DEFINE_CUSTOM_AI;
|
DEFINE_CUSTOM_AI;
|
||||||
|
|
||||||
private:
|
|
||||||
bool HasRangedWeapon();
|
|
||||||
void PrecacheNPCSoundScript(string_t* SoundName, string_t defaultSoundName);
|
|
||||||
|
|
||||||
|
|
||||||
bool m_bUseBothSquadSlots; // If true use two squad slots, if false use one squad slot
|
|
||||||
bool m_bCannotOpenDoors; // If true, this NPC cannot open doors. The condition is reversed because originally it could.
|
|
||||||
bool m_bCanPickupWeapons; // If true, this NPC is able to pick up weapons off of the ground just like npc_citizen.
|
|
||||||
bool m_bWanderToggle; // Boolean to toggle wandering / standing every think cycle
|
|
||||||
float m_flNextSoundTime; // Next time at which this NPC is allowed to play an NPC sound
|
|
||||||
float m_flNextFoundEnemySoundTime; // Next time at which this NPC is allowed to play an NPC sound
|
|
||||||
float m_flSpeedModifier; // Modifier to apply to move distance
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
LINK_ENTITY_TO_CLASS(npc_shadow_walker, CNPC_ShadowWalker);
|
LINK_ENTITY_TO_CLASS(npc_shadow_walker, CNPC_ShadowWalker);
|
||||||
|
IMPLEMENT_CUSTOM_AI(npc_base_custom, CNPC_ShadowWalker);
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// Save/Restore
|
// Save/Restore
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
BEGIN_DATADESC(CNPC_ShadowWalker)
|
BEGIN_DATADESC(CNPC_ShadowWalker)
|
||||||
DEFINE_KEYFIELD(m_iszWeaponModelName, FIELD_STRING, "WeaponModel"),
|
/// Custom fields go here
|
||||||
DEFINE_KEYFIELD(m_iHealth, FIELD_INTEGER, "Health"),
|
|
||||||
DEFINE_KEYFIELD(m_iszFearSound, FIELD_SOUNDNAME, "FearSound"),
|
|
||||||
DEFINE_KEYFIELD(m_iszDeathSound, FIELD_SOUNDNAME, "DeathSound"),
|
|
||||||
DEFINE_KEYFIELD(m_iszIdleSound, FIELD_SOUNDNAME, "IdleSound"),
|
|
||||||
DEFINE_KEYFIELD(m_iszPainSound, FIELD_SOUNDNAME, "PainSound"),
|
|
||||||
DEFINE_KEYFIELD(m_iszAlertSound, FIELD_SOUNDNAME, "AlertSound"),
|
|
||||||
DEFINE_KEYFIELD(m_iszLostEnemySound, FIELD_SOUNDNAME, "LostEnemySound"),
|
|
||||||
DEFINE_KEYFIELD(m_iszFoundEnemySound, FIELD_SOUNDNAME, "FoundEnemySound"),
|
|
||||||
DEFINE_KEYFIELD(m_bUseBothSquadSlots, FIELD_BOOLEAN, "UseBothSquadSlots"),
|
|
||||||
DEFINE_KEYFIELD(m_bCannotOpenDoors, FIELD_BOOLEAN, "CannotOpenDoors"),
|
|
||||||
DEFINE_KEYFIELD(m_bCanPickupWeapons, FIELD_BOOLEAN, "CanPickupWeapons"),
|
|
||||||
|
|
||||||
DEFINE_FIELD(m_bWanderToggle, FIELD_BOOLEAN),
|
|
||||||
DEFINE_FIELD(m_flNextSoundTime, FIELD_TIME),
|
|
||||||
DEFINE_FIELD(m_flNextFoundEnemySoundTime, FIELD_TIME),
|
|
||||||
DEFINE_FIELD(m_flSpeedModifier, FIELD_TIME),
|
|
||||||
|
|
||||||
DEFINE_INPUTFUNC(FIELD_FLOAT, "SetSpeedModifier", InputSetSpeedModifier),
|
|
||||||
DEFINE_INPUTFUNC(FIELD_VOID, "EnableOpenDoors", InputEnableOpenDoors),
|
|
||||||
DEFINE_INPUTFUNC(FIELD_VOID, "DisableOpenDoors", InputDisableOpenDoors),
|
|
||||||
DEFINE_INPUTFUNC(FIELD_VOID, "EnablePickupWeapons", InputEnablePickupWeapons),
|
|
||||||
DEFINE_INPUTFUNC(FIELD_VOID, "DisablePickupWeapons", InputDisablePickupWeapons)
|
|
||||||
END_DATADESC()
|
END_DATADESC()
|
||||||
|
|
||||||
|
|
||||||
AI_BEGIN_CUSTOM_NPC(npc_shadow_walker, CNPC_ShadowWalker)
|
|
||||||
//=========================================================
|
|
||||||
// > Melee_Attack_NoInterrupt
|
|
||||||
//=========================================================
|
|
||||||
DEFINE_SCHEDULE
|
|
||||||
(
|
|
||||||
SCHED_MELEE_ATTACK_NOINTERRUPT,
|
|
||||||
|
|
||||||
" Tasks"
|
|
||||||
" TASK_STOP_MOVING 0"
|
|
||||||
" TASK_FACE_ENEMY 0"
|
|
||||||
" TASK_ANNOUNCE_ATTACK 1" // 1 = primary attack
|
|
||||||
" TASK_MELEE_ATTACK1 0"
|
|
||||||
""
|
|
||||||
" Interrupts"
|
|
||||||
" COND_ENEMY_DEAD"
|
|
||||||
" COND_ENEMY_OCCLUDED"
|
|
||||||
);
|
|
||||||
|
|
||||||
//=========================================================
|
|
||||||
// SCHED_HIDE
|
|
||||||
//=========================================================
|
|
||||||
DEFINE_SCHEDULE
|
|
||||||
(
|
|
||||||
SCHED_HIDE,
|
|
||||||
|
|
||||||
" Tasks"
|
|
||||||
" TASK_SET_FAIL_SCHEDULE SCHEDULE:SCHED_COMBAT_FACE"
|
|
||||||
" TASK_STOP_MOVING 0"
|
|
||||||
" TASK_FIND_COVER_FROM_ENEMY 0"
|
|
||||||
" TASK_RUN_PATH 0"
|
|
||||||
" TASK_WAIT_FOR_MOVEMENT 0"
|
|
||||||
" TASK_REMEMBER MEMORY:INCOVER"
|
|
||||||
" TASK_FACE_ENEMY 0"
|
|
||||||
""
|
|
||||||
" Interrupts"
|
|
||||||
" COND_HEAR_DANGER"
|
|
||||||
" COND_NEW_ENEMY"
|
|
||||||
" COND_ENEMY_DEAD"
|
|
||||||
);
|
|
||||||
AI_END_CUSTOM_NPC()
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user