mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-12 16:21:04 +02:00
162 lines
3.9 KiB
C++
162 lines
3.9 KiB
C++
// BotAI_Battle_Retreat.cpp
|
|
//
|
|
|
|
#pragma hdrstop
|
|
#include "precompiled.h"
|
|
#include "../Game_local.h"
|
|
|
|
/*
|
|
=====================
|
|
rvmBot::state_Retreat
|
|
=====================
|
|
*/
|
|
stateResult_t rvmBot::state_Retreat(stateParms_t* parms)
|
|
{
|
|
bot_goal_t goal;
|
|
idPlayer* entinfo;
|
|
rvmBot* owner;
|
|
idVec3 target, dir;
|
|
float attack_skill, range;
|
|
|
|
// respawn if dead.
|
|
if( BotIsDead( &bs ) )
|
|
{
|
|
stateThread.SetState("state_Respawn");
|
|
return SRESULT_DONE_FRAME;
|
|
}
|
|
|
|
// if no enemy.
|
|
if( bs.enemy < 0 || bs.enemy >= gameLocal.num_entities || gameLocal.entities[bs.enemy] == NULL )
|
|
{
|
|
stateThread.SetState("state_SeekLTG");
|
|
return SRESULT_DONE_FRAME;
|
|
}
|
|
|
|
// Ensure the target is a player.
|
|
entinfo = gameLocal.entities[bs.enemy]->Cast<idPlayer>();
|
|
if( !entinfo )
|
|
{
|
|
stateThread.SetState("state_SeekLTG");
|
|
return SRESULT_DONE_FRAME;
|
|
}
|
|
|
|
owner = gameLocal.entities[bs.entitynum]->Cast<rvmBot>();
|
|
|
|
// If our enemy is dead, search for another LTG.
|
|
if( EntityIsDead( entinfo ) )
|
|
{
|
|
stateThread.SetState("state_SeekLTG");
|
|
return SRESULT_DONE_FRAME;
|
|
}
|
|
|
|
//if there is another better enemy
|
|
if( BotFindEnemy( &bs, bs.enemy ) )
|
|
{
|
|
common->DPrintf( "found new better enemy\n" );
|
|
}
|
|
|
|
//update the attack inventory values
|
|
BotUpdateBattleInventory( &bs, bs.enemy );
|
|
BotChooseWeapon( &bs );
|
|
|
|
// Before switching back to chase, opportunistically grab a nearby tactical
|
|
// pickup. This keeps the bot from running past a rocket launcher, shells, or
|
|
// health while it is already committed to a fight.
|
|
if( bs.check_time < Bot_Time() )
|
|
{
|
|
bs.check_time = Bot_Time() + 0.5f;
|
|
bot_goal_t pickupAnchor;
|
|
pickupAnchor.Reset();
|
|
pickupAnchor.entitynum = bs.enemy;
|
|
pickupAnchor.origin = entinfo->GetOrigin();
|
|
pickupAnchor.mins = idVec3( -8.0f, -8.0f, -8.0f );
|
|
pickupAnchor.maxs = idVec3( 8.0f, 8.0f, 8.0f );
|
|
if( BotNearbyGoal( &bs, 0, &pickupAnchor, 260.0f ) )
|
|
{
|
|
bs.nbg_time = Bot_Time() + 18.0f;
|
|
stateThread.SetState("state_BattleNBG");
|
|
return SRESULT_DONE_FRAME;
|
|
}
|
|
}
|
|
|
|
//if the bot doesn't want to retreat anymore... probably picked up some nice items
|
|
if( BotWantsToChase( &bs ) )
|
|
{
|
|
//empty the goal stack, when chasing, only the enemy is the goal
|
|
botGoalManager.BotEmptyGoalStack( bs.gs );
|
|
|
|
//go chase the enemy
|
|
//AIEnter_Battle_Chase(bs, "battle retreat: wants to chase");
|
|
stateThread.SetState("state_Chase");
|
|
return SRESULT_DONE_FRAME;
|
|
}
|
|
|
|
//update the last time the enemy was visible
|
|
if( BotEntityVisible( bs.entitynum, bs.eye, bs.viewangles, 360, bs.enemy ) )
|
|
{
|
|
bs.enemyvisible_time = Bot_Time();
|
|
target = entinfo->GetOrigin();
|
|
bs.lastenemyorigin = target;
|
|
bs.last_enemy_visible_position = target;
|
|
}
|
|
|
|
//if the enemy is NOT visible for 4 seconds
|
|
if( bs.enemyvisible_time < Bot_Time() - 4 )
|
|
{
|
|
stateThread.SetState("state_SeekLTG");
|
|
return SRESULT_DONE_FRAME;
|
|
}
|
|
//else if the enemy is NOT visible
|
|
else if( bs.enemyvisible_time < Bot_Time() )
|
|
{
|
|
//if there is another enemy
|
|
if( BotFindEnemy( &bs, -1 ) )
|
|
{
|
|
//AIEnter_Battle_Fight(bs, "battle retreat: another enemy");
|
|
stateThread.SetState("state_BattleFight");
|
|
return SRESULT_DONE_FRAME;
|
|
}
|
|
}
|
|
|
|
//use holdable items
|
|
BotBattleUseItems( &bs );
|
|
|
|
//get the current long term goal while retreating
|
|
if( !BotGetItemLongTermGoal( &bs, 0, &bs.currentGoal ) )
|
|
{
|
|
//AIEnter_Battle_SuicidalFight(bs, "battle retreat: no way out");
|
|
stateThread.SetState("state_BattleFight");
|
|
bs.flags |= BFL_FIGHTSUICIDAL;
|
|
return SRESULT_DONE_FRAME;
|
|
}
|
|
|
|
//check for nearby goals periodically while retreating along the long-term item path
|
|
if( bs.check_time < Bot_Time() )
|
|
{
|
|
bs.check_time = Bot_Time() + 0.5f;
|
|
range = 260.0f;
|
|
|
|
if( BotNearbyGoal( &bs, 0, &goal, range ) )
|
|
{
|
|
bs.nbg_time = Bot_Time() + 18.0f;
|
|
stateThread.SetState("state_BattleNBG");
|
|
return SRESULT_DONE_FRAME;
|
|
}
|
|
}
|
|
|
|
MoveToCoverPoint();
|
|
|
|
if (bot_skill.GetInteger() > 1)
|
|
{
|
|
bs.firethrottlewait_time = 0;
|
|
}
|
|
|
|
BotChooseWeapon( &bs );
|
|
|
|
BotAimAtEnemy( &bs );
|
|
|
|
//attack the enemy if possible
|
|
BotCheckAttack( &bs );
|
|
|
|
return SRESULT_WAIT;
|
|
} |