mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-14 01:01:05 +02:00
217 lines
5.7 KiB
C++
217 lines
5.7 KiB
C++
// BotAI_Battle_Chase.cpp
|
|
//
|
|
|
|
#pragma hdrstop
|
|
#include "precompiled.h"
|
|
#include "../Game_local.h"
|
|
|
|
|
|
/*
|
|
=====================
|
|
rvmBot::state_Chase
|
|
=====================
|
|
*/
|
|
stateResult_t rvmBot::state_Chase(stateParms_t* parms)
|
|
{
|
|
bot_goal_t goal;
|
|
idVec3 target, dir;
|
|
//bot_moveresult_t moveresult;
|
|
float range;
|
|
|
|
//if (BotIsObserver(bs)) {
|
|
// AIEnter_Observer(bs, "battle chase: observer");
|
|
// return qfalse;
|
|
//}
|
|
//
|
|
////if in the intermission
|
|
//if (BotIntermission(bs)) {
|
|
// AIEnter_Intermission(bs, "battle chase: intermission");
|
|
// return qfalse;
|
|
//}
|
|
|
|
// respawn if dead.
|
|
if( BotIsDead( &bs ) )
|
|
{
|
|
stateThread.SetState("state_Respawn");
|
|
return SRESULT_DONE_FRAME;
|
|
}
|
|
|
|
if( parms->stage == 0 )
|
|
{
|
|
if( bs.chase_time <= Bot_Time() )
|
|
{
|
|
bs.chase_time = Bot_Time() + 10.0f;
|
|
}
|
|
parms->stage = 1;
|
|
}
|
|
|
|
//if no enemy
|
|
if( bs.enemy < 0 || bs.enemy >= gameLocal.num_entities || gameLocal.entities[bs.enemy] == NULL ||
|
|
bs.client < 0 || bs.client >= gameLocal.num_entities || gameLocal.entities[bs.client] == NULL )
|
|
{
|
|
stateThread.SetState("state_SeekLTG");
|
|
return SRESULT_DONE_FRAME;
|
|
}
|
|
|
|
//if the enemy is visible
|
|
if( BotEntityVisibleTest( bs.entitynum, bs.eye, bs.viewangles, 360, bs.enemy, false ) )
|
|
{
|
|
//AIEnter_Battle_Fight(bs, "battle chase");
|
|
stateThread.SetState("state_BattleFight");
|
|
return SRESULT_DONE_FRAME;
|
|
}
|
|
|
|
//if there is another enemy
|
|
if( BotFindEnemy( &bs, -1 ) )
|
|
{
|
|
//AIEnter_Battle_Fight(bs, "battle chase: better enemy");
|
|
//stateThread.SetState("state_BattleFight");
|
|
stateThread.SetState("state_BattleFight");
|
|
return SRESULT_DONE_FRAME;
|
|
}
|
|
////there is no last enemy area
|
|
//if (!bs.lastenemyareanum) {
|
|
// AIEnter_Seek_LTG(bs, "battle chase: no enemy area");
|
|
// return qfalse;
|
|
//}
|
|
// jmarshall
|
|
//
|
|
//bs.tfl = TFL_DEFAULT;
|
|
//if (bot_grapple.integer) bs.tfl |= TFL_GRAPPLEHOOK;
|
|
////if in lava or slime the bot should be able to get out
|
|
//if (BotInLavaOrSlime(bs)) bs.tfl |= TFL_LAVA | TFL_SLIME;
|
|
////
|
|
//if (BotCanAndWantsToRocketJump(bs)) {
|
|
// bs.tfl |= TFL_ROCKETJUMP;
|
|
//}
|
|
//map specific code
|
|
//BotMapScripts(bs);
|
|
// jmarshall end
|
|
|
|
//create the chase goal
|
|
goal.entitynum = bs.enemy;
|
|
// goal.areanum = bs.lastenemyareanum;
|
|
VectorCopy( bs.lastenemyorigin, goal.origin );
|
|
|
|
goal.mins = idVec3( -8, -8, -8 );
|
|
goal.maxs = idVec3( 8, 8, 8 );
|
|
|
|
// jmarshall - goal origin is last visible position
|
|
{
|
|
// Do a trace between the last_enemy_visible_position and the goal origin,
|
|
// if for some reason we don't have line of sight to it, switch to LTG.
|
|
trace_t trace;
|
|
|
|
gameLocal.Trace( trace, bs.last_enemy_visible_position, gameLocal.entities[bs.client]->GetOrigin(), CONTENTS_SOLID, bs.entitynum );
|
|
|
|
if( trace.fraction <= 0.9f )
|
|
{
|
|
//AIEnter_Seek_LTG(bs, "can't see last enemy position");
|
|
stateThread.SetState("state_SeekLTG");
|
|
return SRESULT_DONE_FRAME;
|
|
}
|
|
}
|
|
VectorCopy( bs.last_enemy_visible_position, goal.origin );
|
|
// jmarshall end
|
|
|
|
//if the last seen enemy spot is reached the enemy could not be found
|
|
if( botGoalManager.BotTouchingGoal( bs.origin, &goal ) )
|
|
{
|
|
bs.chase_time = 0;
|
|
}
|
|
|
|
//if there's no chase time left
|
|
if( !bs.chase_time || bs.chase_time < Bot_Time() )
|
|
{
|
|
//AIEnter_Seek_LTG(bs, "battle chase: time out");
|
|
stateThread.SetState("state_SeekLTG");
|
|
return SRESULT_DONE_FRAME;
|
|
}
|
|
//check for nearby goals periodically. Chasing should still route through a
|
|
// nearby weapon/ammo pickup instead of running past it, especially when the bot
|
|
// only has pistol/machinegun or is dry on ammo.
|
|
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;
|
|
}
|
|
}
|
|
|
|
BotUpdateBattleInventory( &bs, bs.enemy );
|
|
BotChooseWeapon( &bs );
|
|
|
|
////initialize the movement state
|
|
//BotSetupForMovement(bs);
|
|
|
|
//move towards the goal
|
|
//trap_BotMoveToGoal(&moveresult, bs.ms, &goal, bs.tfl);
|
|
|
|
if( idMath::FRandRange( 0.0f, 4.0f ) <= 2.0f )
|
|
{
|
|
BotMoveToGoal( &bs, &goal );
|
|
}
|
|
else
|
|
{
|
|
BotMoveInRandomDirection( &bs );
|
|
}
|
|
|
|
|
|
//if the movement failed
|
|
//if (moveresult.failure) {
|
|
// //reset the avoid reach, otherwise bot is stuck in current area
|
|
// trap_BotResetAvoidReach(bs.ms);
|
|
// //BotAI_Print(PRT_MESSAGE, "movement failure %d\n", moveresult.traveltype);
|
|
// bs.ltg_time = 0;
|
|
//}
|
|
////
|
|
//BotAIBlocked(bs, &moveresult, qfalse);
|
|
//
|
|
//if (moveresult.flags & (MOVERESULT_MOVEMENTVIEWSET | MOVERESULT_MOVEMENTVIEW | MOVERESULT_SWIMVIEW)) {
|
|
// VectorCopy(moveresult.ideal_viewangles, bs.ideal_viewangles);
|
|
//}
|
|
|
|
if( !( bs.flags & BFL_IDEALVIEWSET ) )
|
|
{
|
|
BotAimAtEnemy( &bs );
|
|
// jmarshall
|
|
//if (bs.chase_time > FloatTime() - 2) {
|
|
// BotAimAtEnemy(bs);
|
|
//}
|
|
//else {
|
|
// if (BotMovementViewTarget(bs.ms, &goal, bs.tfl, 300, target)) {
|
|
// VectorSubtract(target, bs.origin, dir);
|
|
// vectoangles(dir, bs.viewangles);
|
|
// }
|
|
// //else {
|
|
// // vectoangles(moveresult.movedir, bs.ideal_viewangles);
|
|
// //}
|
|
//}
|
|
// jmarshall end
|
|
// bs.ideal_viewangles[2] *= 0.5; // jmarshall <-- view angles!
|
|
}
|
|
|
|
if (BotEntityVisible(bs.entitynum, bs.eye, bs.viewangles, 360, bs.enemy))
|
|
{
|
|
//attack the enemy if possible
|
|
BotCheckAttack(&bs);
|
|
}
|
|
|
|
//if the weapon is used for the bot movement
|
|
//if (moveresult.flags & MOVERESULT_MOVEMENTWEAPON) bs.weaponnum = moveresult.weapon;
|
|
//if the bot is in the area the enemy was last seen in
|
|
//if (bs.areanum == bs.lastenemyareanum) bs.chase_time = 0;
|
|
//if the bot wants to retreat (the bot could have been damage during the chase)
|
|
if( BotWantsToRetreat( &bs ) )
|
|
{
|
|
//AIEnter_Battle_Retreat(bs, "battle chase: wants to retreat");
|
|
stateThread.SetState("state_Retreat");
|
|
return SRESULT_DONE_FRAME;
|
|
}
|
|
|
|
return SRESULT_WAIT;
|
|
} |