Skip to content

Commit

Permalink
Implement Monsters Roaming feature
Browse files Browse the repository at this point in the history
  • Loading branch information
FreeSlave committed Jul 17, 2022
1 parent 66fb780 commit 6e0f64b
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 2 deletions.
7 changes: 7 additions & 0 deletions dlls/basemonster.h
Expand Up @@ -109,6 +109,8 @@ class CBaseMonster : public CBaseToggle

float m_flLastYawTime;

short m_freeRoam;

bool Save(CSave& save) override;
bool Restore(CRestore& restore) override;

Expand Down Expand Up @@ -188,6 +190,7 @@ class CBaseMonster : public CBaseToggle
virtual void RunTask(Task_t* pTask);
virtual Schedule_t* GetScheduleOfType(int Type);
virtual Schedule_t* GetSchedule();
Schedule_t* GetFreeroamSchedule();
virtual void ScheduleChange() {}
// virtual bool CanPlaySequence() { return ((m_pCine == NULL) && (m_MonsterState == MONSTERSTATE_NONE || m_MonsterState == MONSTERSTATE_IDLE || m_IdealMonsterState == MONSTERSTATE_IDLE)); }
virtual bool CanPlaySequence(bool fDisregardState, int interruptLevel);
Expand Down Expand Up @@ -358,3 +361,7 @@ class CBaseMonster : public CBaseToggle

CBaseEntity* DropItem(const char* pszItemName, const Vector& vecPos, const Vector& vecAng); // drop an item.
};

#define FREEROAM_MAPDEFAULT 0
#define FREEROAM_NEVER 1
#define FREEROAM_ALWAYS 2
4 changes: 3 additions & 1 deletion dlls/cbase.h
Expand Up @@ -759,6 +759,8 @@ class CWorld : public CBaseEntity
void Spawn() override;
void Precache() override;
bool KeyValue(KeyValueData* pkvd) override;

static bool gFreeRoaming;
};

inline DLL_GLOBAL edict_t* g_pBodyQueueHead = nullptr;
inline DLL_GLOBAL edict_t* g_pBodyQueueHead = nullptr;
32 changes: 32 additions & 0 deletions dlls/defaultai.cpp
Expand Up @@ -893,6 +893,33 @@ Schedule_t slTakeCoverFromEnemy[] =
"tlTakeCoverFromEnemy"},
};

Task_t tlFreeroam[] =
{
{ TASK_STOP_MOVING, (float)0 },
{ TASK_WAIT_RANDOM, 0.5f },
{ TASK_GET_PATH_TO_FREEROAM_NODE, (float)0 },
{ TASK_WALK_PATH, (float)0 },
{ TASK_WAIT_FOR_MOVEMENT, (float)0 },
{ TASK_SET_ACTIVITY, (float)ACT_IDLE },
{ TASK_WAIT, 0.5f },
{ TASK_WAIT_RANDOM, 0.5f },
{ TASK_WAIT_PVS, (float)0 },
};

Schedule_t slFreeroam[] =
{
{
tlFreeroam,
ARRAYSIZE( tlFreeroam ),
bits_COND_NEW_ENEMY |
bits_COND_LIGHT_DAMAGE |
bits_COND_HEAVY_DAMAGE |
bits_COND_HEAR_SOUND,
bits_SOUND_DANGER,
"Free Roaming"
},
};

Schedule_t* CBaseMonster::m_scheduleList[] =
{
slIdleStand,
Expand Down Expand Up @@ -932,6 +959,7 @@ Schedule_t* CBaseMonster::m_scheduleList[] =
slTakeCoverFromOrigin,
slTakeCoverFromBestSound,
slTakeCoverFromEnemy,
slFreeroam,
slFail};

Schedule_t* CBaseMonster::ScheduleFromName(const char* pName)
Expand Down Expand Up @@ -1129,6 +1157,10 @@ Schedule_t* CBaseMonster::GetScheduleOfType(int Type)
{
return &slVictoryDance[0];
}
case SCHED_FREEROAM:
{
return slFreeroam;
}
case SCHED_FAIL:
{
return slFail;
Expand Down
7 changes: 7 additions & 0 deletions dlls/monsters.cpp
Expand Up @@ -100,6 +100,8 @@ TYPEDESCRIPTION CBaseMonster::m_SaveData[] =

DEFINE_FIELD(CBaseMonster, m_scriptState, FIELD_INTEGER),
DEFINE_FIELD(CBaseMonster, m_pCine, FIELD_CLASSPTR),

DEFINE_FIELD( CBaseMonster, m_freeRoam, FIELD_SHORT ),
};

//IMPLEMENT_SAVERESTORE( CBaseMonster, CBaseToggle );
Expand Down Expand Up @@ -2977,6 +2979,11 @@ bool CBaseMonster::KeyValue(KeyValueData* pkvd)
m_iTriggerCondition = atoi(pkvd->szValue);
return true;
}
else if ( FStrEq( pkvd->szKeyName, "freeroam" ) )
{
m_freeRoam = (short)atoi( pkvd->szValue );
return true;
}

return CBaseToggle::KeyValue(pkvd);
}
Expand Down
56 changes: 56 additions & 0 deletions dlls/schedule.cpp
Expand Up @@ -1313,6 +1313,42 @@ void CBaseMonster::StartTask(Task_t* pTask)
TaskComplete();
break;

case TASK_GET_PATH_TO_FREEROAM_NODE:
{
if( !WorldGraph.m_fGraphPresent || !WorldGraph.m_fGraphPointersSet )
{
TaskFail();
}
else
{
for( int i = 0; i < WorldGraph.m_cNodes; i++ )
{
int nodeNumber = ( i + WorldGraph.m_iLastActiveIdleSearch ) % WorldGraph.m_cNodes;

CNode &node = WorldGraph.Node( nodeNumber );

// Don't go to the node if already is close enough
if ((node.m_vecOrigin - pev->origin).Length() < 16.0f)
continue;

TraceResult tr;
UTIL_TraceLine( pev->origin + pev->view_ofs, node.m_vecOrigin + pev->view_ofs, dont_ignore_monsters, ENT( pev ), &tr );

if (tr.flFraction == 1.0f && MoveToLocation( ACT_WALK, 2, node.m_vecOrigin ))
{
TaskComplete();
WorldGraph.m_iLastActiveIdleSearch = nodeNumber + 1;
break;
}
}
if (!TaskIsComplete())
{
TaskFail();
}
}
}
break;

default:
{
ALERT(at_aiconsole, "No StartTask entry for %d\n", (SHARED_TASKS)pTask->iTask);
Expand Down Expand Up @@ -1367,6 +1403,9 @@ Schedule_t* CBaseMonster::GetSchedule()
else if (FRouteClear())
{
// no valid route!
Schedule_t* freeroamSchedule = GetFreeroamSchedule();
if (freeroamSchedule)
return freeroamSchedule;
return GetScheduleOfType(SCHED_IDLE_STAND);
}
else
Expand Down Expand Up @@ -1394,6 +1433,10 @@ Schedule_t* CBaseMonster::GetSchedule()
return GetScheduleOfType(SCHED_ALERT_SMALL_FLINCH);
}
}

Schedule_t* freeroamSchedule = GetFreeroamSchedule();
if (freeroamSchedule)
return freeroamSchedule;

else if (HasConditions(bits_COND_HEAR_SOUND))
{
Expand Down Expand Up @@ -1509,3 +1552,16 @@ Schedule_t* CBaseMonster::GetSchedule()

return &slError[0];
}

Schedule_t* CBaseMonster::GetFreeroamSchedule()
{
if (m_freeRoam == FREEROAM_ALWAYS)
return GetScheduleOfType( SCHED_FREEROAM );
else if (m_freeRoam == FREEROAM_MAPDEFAULT)
{
if (CWorld::gFreeRoaming) {
return GetScheduleOfType( SCHED_FREEROAM );
}
}
return NULL;
}
2 changes: 2 additions & 0 deletions dlls/schedule.h
Expand Up @@ -72,6 +72,7 @@ typedef enum
SCHED_BARNACLE_VICTIM_CHOMP,
SCHED_AISCRIPT,
SCHED_FAIL,
SCHED_FREEROAM,

LAST_COMMON_SCHEDULE // Leave this at the bottom
} SCHEDULE_TYPE;
Expand Down Expand Up @@ -171,6 +172,7 @@ typedef enum
TASK_REMEMBER,
TASK_FORGET,
TASK_WAIT_FOR_MOVEMENT, // wait until MovementIsComplete()
TASK_GET_PATH_TO_FREEROAM_NODE,
LAST_COMMON_TASK, // LEAVE THIS AT THE BOTTOM!! (sjb)
} SHARED_TASKS;

Expand Down
21 changes: 20 additions & 1 deletion dlls/world.cpp
Expand Up @@ -38,6 +38,8 @@ CGlobalState gGlobalState;

extern void W_Precache();

bool CWorld::gFreeRoaming = false;

//
// This must match the list in util.h
//
Expand Down Expand Up @@ -471,6 +473,7 @@ LINK_ENTITY_TO_CLASS(worldspawn, CWorld);
#define SF_WORLD_DARK 0x0001 // Fade from black at startup
#define SF_WORLD_TITLE 0x0002 // Display game title at startup
#define SF_WORLD_FORCETEAM 0x0004 // Force teams
#define SF_WORLD_FREEROAM 0x0008 // Monsters freeroaming by default

void CWorld::Spawn()
{
Expand Down Expand Up @@ -661,6 +664,15 @@ void CWorld::Precache()
{
CVAR_SET_FLOAT("mp_defaultteam", 0);
}

if ((pev->spawnflags & SF_WORLD_FREEROAM) != 0)
{
gFreeRoaming = true;
}
else
{
gFreeRoaming = false;
}
}


Expand Down Expand Up @@ -733,6 +745,13 @@ bool CWorld::KeyValue(KeyValueData* pkvd)
}
return true;
}

else if ( FStrEq( pkvd->szKeyName, "freeroam" ) )
{
if (atoi( pkvd->szValue ))
{
pev->spawnflags |= SF_WORLD_FREEROAM;
}
return true;
}
return CBaseEntity::KeyValue(pkvd);
}

0 comments on commit 6e0f64b

Please sign in to comment.