boiii-scripts/mp/bots/_bot_combat.gsc
2023-04-13 17:30:38 +02:00

242 lines
10 KiB
Plaintext

#using scripts\shared\array_shared;
#using scripts\shared\gameobjects_shared;
#using scripts\shared\math_shared;
#using scripts\shared\util_shared;
#using scripts\shared\weapons_shared;
#using scripts\shared\weapons\_weapon_utils;
#using scripts\shared\weapons\_weapons;
#using scripts\mp\_util;
#using scripts\mp\bots\_bot;
#using scripts\shared\bots\_bot;
#using scripts\shared\bots\_bot_combat;
#using scripts\shared\bots\bot_traversals;
#using scripts\shared\killstreaks_shared;
// 128 * 128
#namespace bot_combat;
function bot_ignore_threat( entity )
{
if ( threat_requires_launcher( entity ) && !self bot::has_launcher() )
{
return true;
/* TODO:
eyePos = self GetEye();
pitchMax = GetDvarFloat( "player_view_pitch_up" );
pitchMin = -GetDvarFloat( "player_view_pitch_down" );
// Entity is in FOV but outside pitch range
threatAngles = VectorToAngles( entity.origin - eyePos );
// TODO: Is threatAngles[0] in 0 to 360 or -180 to 180?
if ( threatAngles[0] > pitchMax || threatAngles[0] < pitchMin )
{
continue;
}
*/
}
return false;
}
function mp_pre_combat()
{
self bot_combat::bot_pre_combat();
if ( self IsReloading() ||
self IsSwitchingWeapons() ||
self IsThrowingGrenade() ||
self IsMeleeing() ||
self IsRemoteControlling() ||
self IsInVehicle() ||
self IsWeaponViewOnlyLinked() )
{
return;
}
if ( self has_threat() )
{
self threat_switch_weapon();
return;
}
if ( self switch_weapon() )
{
return;
}
if ( self reload_weapon() )
{
return;
}
self bot::use_killstreak();
}
function mp_post_combat()
{
// Dogtag handling
if( !IsDefined( level.dogtags ) )
{
return;
}
if ( isdefined( self.bot.goalTag ) )
{
if ( !self.bot.goalTag gameobjects::can_interact_with( self ) )
{
// Cancel the tag
self.bot.goalTag = undefined;
if ( !self bot_combat::has_threat() && self BotGoalSet() )
{
self BotSetGoal( self.origin );
}
}
else if ( !self.bot.goalTagOnGround &&
!self bot_combat::has_threat() &&
self IsOnGround() &&
Distance2DSquared( self.origin , self.bot.goalTag.origin ) < 16384 &&
self BotSightTrace( self.bot.goalTag ) )
{
self thread bot::jump_to( self.bot.goalTag.origin );
}
}
else if ( !self BotGoalSet() )
{
closestTag = self get_closest_tag();
if ( isdefined( closestTag ) )
{
// Trigger radius from _dogtags.gsc
self set_goal_tag( closestTag );
}
}
}
function threat_requires_launcher( enemy )
{
if ( !isdefined( enemy ) || IsPlayer( enemy ) )
{
return false;
}
killstreakType = undefined;
if ( isdefined( enemy.killstreakType ) )
{
killstreakType = enemy.killstreakType;
}
else if ( isdefined( enemy.parentStruct ) && isdefined( enemy.parentStruct.killstreakType ) )
{
killstreakType = enemy.parentStruct.killstreakType;
}
if ( !isdefined( killstreakType ) )
{
return false;
}
switch( killstreakType )
{
case "uav":
case "counteruav":
case "satellite":
case "helicopter_gunner":
return true;
}
return false;
}
function combat_throw_proximity( origin )
{
}
function combat_throw_smoke( origin )
{
}
function combat_throw_lethal( origin )
{
}
function combat_throw_tactical( origin )
{
}
function combat_toss_frag( origin )
{
}
function combat_toss_flash( origin )
{
}
function combat_tactical_insertion( origin )
{
return false;
}
function nearest_node( origin )
{
return undefined;
}
function dot_product( origin )
{
return bot::fwd_dot( origin );
}
// Dogtags
//========================================
function get_closest_tag()
{
closestTag = undefined;
closestTagDistSq = undefined;
foreach( tag in level.dogtags )
{
if ( !tag gameobjects::can_interact_with( self ) )
{
continue;
}
distSq = DistanceSquared( self.origin, tag.origin );
if ( !isdefined( closestTag ) || distSq < closestTagDistSq )
{
closestTag = tag;
closestTagDistSq = distSq;
}
}
return closestTag;
}
function set_goal_tag( tag )
{
self.bot.goalTag = tag;
traceStart = tag.origin;
traceEnd = tag.origin + (0,0,-64);
trace = BulletTrace( traceStart, traceEnd, false, undefined );
self.bot.goalTagOnGround = ( trace["fraction"] < 1 );
self bot::path_to_trigger( tag.trigger );
self bot::sprint_to_goal();
}