ReGameDLL_CS/regamedll/dlls/bot/states/cs_bot_hunt.cpp

190 lines
5.0 KiB
C++
Raw Normal View History

2015-06-30 12:46:07 +03:00
#include "precompiled.h"
2016-01-25 20:02:57 +03:00
// Begin the hunt
void HuntState::OnEnter(CCSBot *me)
2015-06-30 12:46:07 +03:00
{
2016-01-25 20:02:57 +03:00
// lurking death
if (me->IsUsingKnife() && me->IsWellPastSafe() && !me->IsHurrying())
me->Walk();
else
me->Run();
me->StandUp();
me->SetDisposition(CCSBot::ENGAGE_AND_INVESTIGATE);
me->SetTask(CCSBot::SEEK_AND_DESTROY);
me->DestroyPath();
2015-06-30 12:46:07 +03:00
}
2016-01-25 20:02:57 +03:00
// Hunt down our enemies
void HuntState::OnUpdate(CCSBot *me)
2015-06-30 12:46:07 +03:00
{
2016-01-25 20:02:57 +03:00
// if we've been hunting for a long time, drop into Idle for a moment to
// select something else to do
const float huntingTooLongTime = 30.0f;
if (gpGlobals->time - me->GetStateTimestamp() > huntingTooLongTime)
{
// stop being a rogue and do the scenario, since there must not be many enemies left to hunt
me->PrintIfWatched("Giving up hunting, and being a rogue\n");
me->SetRogue(false);
me->Idle();
return;
}
// scenario logic
if (TheCSBots()->GetScenario() == CCSBotManager::SCENARIO_DEFUSE_BOMB)
2016-01-25 20:02:57 +03:00
{
if (me->m_iTeam == TERRORIST)
{
// if we have the bomb and it's time to plant, or we happen to be in a bombsite and it seems safe, do it
if (me->IsCarryingBomb())
{
const float safeTime = 3.0f;
if (TheCSBots()->IsTimeToPlantBomb() || (me->IsAtBombsite() && gpGlobals->time - me->GetLastSawEnemyTimestamp() > safeTime))
2016-01-25 20:02:57 +03:00
{
me->Idle();
return;
}
}
// if we notice the bomb lying on the ground, go get it
if (me->NoticeLooseBomb())
{
me->FetchBomb();
return;
}
// if bomb has been planted, and we hear it, move to a hiding spot near the bomb and watch it
const Vector *bombPos = me->GetGameState()->GetBombPosition();
2017-10-12 17:50:56 +03:00
if (!me->IsRogue() && me->GetGameState()->IsBombPlanted() && bombPos)
2016-01-25 20:02:57 +03:00
{
me->SetTask(CCSBot::GUARD_TICKING_BOMB);
me->Hide(TheNavAreaGrid.GetNavArea(bombPos));
return;
}
}
// CT
else
{
if (!me->IsRogue() && me->CanSeeLooseBomb())
{
// if we are near the loose bomb and can see it, hide nearby and guard it
me->SetTask(CCSBot::GUARD_LOOSE_BOMB);
me->Hide(TheCSBots()->GetLooseBombArea());
me->GetChatter()->AnnouncePlan("GoingToGuardLooseBomb", TheCSBots()->GetLooseBombArea()->GetPlace());
2016-01-25 20:02:57 +03:00
return;
}
else if (TheCSBots()->IsBombPlanted())
2016-01-25 20:02:57 +03:00
{
// rogues will defuse a bomb, but not guard the defuser
if (!me->IsRogue() || !TheCSBots()->GetBombDefuser())
2016-01-25 20:02:57 +03:00
{
// search for the planted bomb to defuse
me->Idle();
return;
}
}
}
}
else if (TheCSBots()->GetScenario() == CCSBotManager::SCENARIO_RESCUE_HOSTAGES)
2016-01-25 20:02:57 +03:00
{
if (me->m_iTeam == TERRORIST)
{
if (me->GetGameState()->AreAllHostagesBeingRescued())
{
// all hostages are being rescued, head them off at the escape zones
if (me->GuardRandomZone())
{
me->SetTask(CCSBot::GUARD_HOSTAGE_RESCUE_ZONE);
me->PrintIfWatched("Trying to beat them to an escape zone!\n");
me->SetDisposition(CCSBot::OPPORTUNITY_FIRE);
me->GetChatter()->GuardingHostageEscapeZone(IS_PLAN);
return;
}
}
// if safe time is up, and we stumble across a hostage, guard it
if (!me->IsRogue() && !me->IsSafe())
{
2017-10-12 17:50:56 +03:00
CHostage *pHostage = me->GetGameState()->GetNearestVisibleFreeHostage();
if (pHostage)
2016-01-25 20:02:57 +03:00
{
2017-10-12 17:50:56 +03:00
CNavArea *area = TheNavAreaGrid.GetNearestNavArea(&pHostage->pev->origin);
if (area)
2016-01-25 20:02:57 +03:00
{
// we see a free hostage, guard it
me->SetTask(CCSBot::GUARD_HOSTAGES);
me->Hide(area);
me->PrintIfWatched("I'm guarding hostages\n");
me->GetChatter()->GuardingHostages(area->GetPlace(), IS_PLAN);
return;
}
}
}
}
}
// listen for enemy noises
if (me->ShouldInvestigateNoise())
{
me->InvestigateNoise();
return;
}
// look around
me->UpdateLookAround();
// if we have reached our destination area, pick a new one
// if our path fails, pick a new one
if (me->GetLastKnownArea() == m_huntArea || me->UpdatePathMovement() != CCSBot::PROGRESSING)
{
2017-10-12 17:50:56 +03:00
m_huntArea = nullptr;
2016-01-25 20:02:57 +03:00
float oldest = 0.0f;
int areaCount = 0;
const float minSize = 150.0f;
2017-10-12 17:50:56 +03:00
for (auto area : TheNavAreaList)
2016-01-25 20:02:57 +03:00
{
2017-10-12 17:50:56 +03:00
areaCount++;
2016-01-25 20:02:57 +03:00
// skip the small areas
const Extent *extent = area->GetExtent();
if (extent->hi.x - extent->lo.x < minSize || extent->hi.y - extent->lo.y < minSize)
continue;
// keep track of the least recently cleared area
float_precision age = gpGlobals->time - area->GetClearedTimestamp(me->m_iTeam - 1);
if (age > oldest)
{
oldest = age;
m_huntArea = area;
}
}
// if all the areas were too small, pick one at random
int which = RANDOM_LONG(0, areaCount - 1);
areaCount = 0;
2017-10-12 17:50:56 +03:00
for (auto area : TheNavAreaList)
2016-01-25 20:02:57 +03:00
{
2017-10-12 17:50:56 +03:00
m_huntArea = area;
2016-01-25 20:02:57 +03:00
if (which == areaCount)
break;
2017-10-12 17:50:56 +03:00
which--;
2016-01-25 20:02:57 +03:00
}
2017-10-12 17:50:56 +03:00
if (m_huntArea)
2016-01-25 20:02:57 +03:00
{
// create a new path to a far away area of the map
2017-10-12 17:50:56 +03:00
me->ComputePath(m_huntArea, nullptr, SAFEST_ROUTE);
2016-01-25 20:02:57 +03:00
}
}
2015-06-30 12:46:07 +03:00
}
2016-01-25 20:02:57 +03:00
// Done hunting
void HuntState::OnExit(CCSBot *me)
2015-06-30 12:46:07 +03:00
{
2016-01-25 20:02:57 +03:00
;
2015-06-30 12:46:07 +03:00
}