iw2_bot_warfare/maps/mp/bots/_bot_script.gsc
2023-12-18 16:19:11 -06:00

614 lines
19 KiB
Plaintext

#include maps\mp\_utility;
#include maps\mp\bots\_bot_utility;
/*
When the bot gets added into the game.
*/
added()
{
self endon( "disconnect" );
self set_diff();
}
/*
When the bot connects to the game.
*/
connected()
{
self endon( "disconnect" );
self.killerlocation = undefined;
self.lastkiller = undefined;
self.bot_change_class = true;
self thread difficulty();
self thread teamWatch();
self thread classWatch();
self thread onBotSpawned();
self thread onSpawned();
}
/*
The callback for when the bot gets killed.
*/
onKilled( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration )
{
self.killerlocation = undefined;
self.lastkiller = undefined;
if ( !isdefined( self ) || !isdefined( self.team ) )
return;
if ( sMeansOfDeath == "MOD_FALLING" || sMeansOfDeath == "MOD_SUICIDE" )
return;
if ( iDamage <= 0 )
return;
if ( !isdefined( eAttacker ) || !isdefined( eAttacker.team ) )
return;
if ( eAttacker == self )
return;
if ( level.teambased && eAttacker.team == self.team )
return;
if ( !isdefined( eInflictor ) || eInflictor.classname != "player" )
return;
if ( !isalive( eAttacker ) )
return;
self.killerlocation = eAttacker.origin;
self.lastkiller = eAttacker;
}
/*
The callback for when the bot gets damaged.
*/
onDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset )
{
if ( !isdefined( self ) || !isdefined( self.team ) )
return;
if ( !isalive( self ) )
return;
if ( sMeansOfDeath == "MOD_FALLING" || sMeansOfDeath == "MOD_SUICIDE" )
return;
if ( iDamage <= 0 )
return;
if ( !isdefined( eAttacker ) || !isdefined( eAttacker.team ) )
return;
if ( eAttacker == self )
return;
if ( level.teambased && eAttacker.team == self.team )
return;
if ( !isdefined( eInflictor ) || eInflictor.classname != "player" )
return;
if ( !isalive( eAttacker ) )
return;
self bot_cry_for_help( eAttacker );
self SetAttacker( eAttacker );
}
/*
When the bot gets attacked, have the bot ask for help from teammates.
*/
bot_cry_for_help( attacker )
{
if ( !level.teambased )
{
return;
}
theTime = gettime();
if ( isdefined( self.help_time ) && theTime - self.help_time < 1000 )
{
return;
}
self.help_time = theTime;
for ( i = level.players.size - 1; i >= 0; i-- )
{
player = level.players[i];
if ( !player is_bot() )
{
continue;
}
if ( !isdefined( player.team ) )
continue;
if ( !player IsPlayerModelOK() )
continue;
if ( !isalive( player ) )
{
continue;
}
if ( player == self )
{
continue;
}
if ( player.team != self.team )
{
continue;
}
dist = player.pers["bots"]["skill"]["help_dist"];
dist *= dist;
if ( distancesquared( self.origin, player.origin ) > dist )
{
continue;
}
if ( randomint( 100 ) < 50 )
{
self SetAttacker( attacker );
if ( randomint( 100 ) > 70 )
{
break;
}
}
}
}
/*
Sets the bot difficulty.
*/
set_diff()
{
rankVar = getcvarint( "bots_skill" );
switch ( rankVar )
{
case 0:
self.pers["bots"]["skill"]["base"] = RoundNum( random_normal_distribution( 3.5, 1.75, 1, 7 ) );
break;
case 8:
break;
case 9:
self.pers["bots"]["skill"]["base"] = randomintrange( 1, 7 );
self.pers["bots"]["skill"]["aim_time"] = 0.05 * randomintrange( 1, 20 );
self.pers["bots"]["skill"]["init_react_time"] = 50 * randomint( 100 );
self.pers["bots"]["skill"]["reaction_time"] = 50 * randomint( 100 );
self.pers["bots"]["skill"]["no_trace_ads_time"] = 50 * randomint( 100 );
self.pers["bots"]["skill"]["no_trace_look_time"] = 50 * randomint( 100 );
self.pers["bots"]["skill"]["remember_time"] = 50 * randomint( 100 );
self.pers["bots"]["skill"]["fov"] = randomfloatrange( -1, 1 );
randomNum = randomintrange( 500, 25000 );
self.pers["bots"]["skill"]["dist_start"] = randomNum;
self.pers["bots"]["skill"]["dist_max"] = randomNum * 2;
self.pers["bots"]["skill"]["spawn_time"] = 0.05 * randomint( 20 );
self.pers["bots"]["skill"]["help_dist"] = randomintrange( 500, 25000 );
self.pers["bots"]["skill"]["semi_time"] = randomfloatrange( 0.05, 1 );
self.pers["bots"]["skill"]["shoot_after_time"] = randomfloatrange( 0.05, 1 );
self.pers["bots"]["skill"]["aim_offset_time"] = randomfloatrange( 0.05, 1 );
self.pers["bots"]["skill"]["aim_offset_amount"] = randomfloatrange( 0.05, 1 );
self.pers["bots"]["skill"]["bone_update_interval"] = randomfloatrange( 0.05, 1 );
self.pers["bots"]["skill"]["bones"] = "j_head,j_spine4,j_ankle_ri,j_ankle_le";
self.pers["bots"]["behavior"]["strafe"] = randomint( 100 );
self.pers["bots"]["behavior"]["nade"] = randomint( 100 );
self.pers["bots"]["behavior"]["camp"] = randomint( 100 );
self.pers["bots"]["behavior"]["follow"] = randomint( 100 );
self.pers["bots"]["behavior"]["crouch"] = randomint( 100 );
self.pers["bots"]["behavior"]["switch"] = randomint( 100 );
self.pers["bots"]["behavior"]["class"] = randomint( 100 );
self.pers["bots"]["behavior"]["jump"] = randomint( 100 );
break;
default:
self.pers["bots"]["skill"]["base"] = rankVar;
break;
}
}
/*
Updates the bot's difficulty variables.
*/
difficulty()
{
self endon( "disconnect" );
for ( ;; )
{
if ( getcvarint( "bots_skill" ) != 9 )
{
switch ( self.pers["bots"]["skill"]["base"] )
{
case 1:
self.pers["bots"]["skill"]["aim_time"] = 0.6;
self.pers["bots"]["skill"]["init_react_time"] = 1500;
self.pers["bots"]["skill"]["reaction_time"] = 1000;
self.pers["bots"]["skill"]["no_trace_ads_time"] = 500;
self.pers["bots"]["skill"]["no_trace_look_time"] = 600;
self.pers["bots"]["skill"]["remember_time"] = 750;
self.pers["bots"]["skill"]["fov"] = 0.7;
self.pers["bots"]["skill"]["dist_max"] = 2500;
self.pers["bots"]["skill"]["dist_start"] = 1000;
self.pers["bots"]["skill"]["spawn_time"] = 0.75;
self.pers["bots"]["skill"]["help_dist"] = 0;
self.pers["bots"]["skill"]["semi_time"] = 0.9;
self.pers["bots"]["skill"]["shoot_after_time"] = 1;
self.pers["bots"]["skill"]["aim_offset_time"] = 1.5;
self.pers["bots"]["skill"]["aim_offset_amount"] = 4;
self.pers["bots"]["skill"]["bone_update_interval"] = 2;
self.pers["bots"]["skill"]["bones"] = "j_spine4,j_ankle_le,j_ankle_ri";
self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5;
self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5;
self.pers["bots"]["behavior"]["strafe"] = 0;
self.pers["bots"]["behavior"]["nade"] = 10;
self.pers["bots"]["behavior"]["camp"] = 5;
self.pers["bots"]["behavior"]["follow"] = 5;
self.pers["bots"]["behavior"]["crouch"] = 20;
self.pers["bots"]["behavior"]["switch"] = 2;
self.pers["bots"]["behavior"]["class"] = 2;
self.pers["bots"]["behavior"]["jump"] = 0;
break;
case 2:
self.pers["bots"]["skill"]["aim_time"] = 0.55;
self.pers["bots"]["skill"]["init_react_time"] = 1000;
self.pers["bots"]["skill"]["reaction_time"] = 800;
self.pers["bots"]["skill"]["no_trace_ads_time"] = 1000;
self.pers["bots"]["skill"]["no_trace_look_time"] = 1250;
self.pers["bots"]["skill"]["remember_time"] = 1500;
self.pers["bots"]["skill"]["fov"] = 0.65;
self.pers["bots"]["skill"]["dist_max"] = 3000;
self.pers["bots"]["skill"]["dist_start"] = 1500;
self.pers["bots"]["skill"]["spawn_time"] = 0.65;
self.pers["bots"]["skill"]["help_dist"] = 500;
self.pers["bots"]["skill"]["semi_time"] = 0.75;
self.pers["bots"]["skill"]["shoot_after_time"] = 0.75;
self.pers["bots"]["skill"]["aim_offset_time"] = 1;
self.pers["bots"]["skill"]["aim_offset_amount"] = 3;
self.pers["bots"]["skill"]["bone_update_interval"] = 1.5;
self.pers["bots"]["skill"]["bones"] = "j_spine4,j_ankle_le,j_ankle_ri,j_head";
self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5;
self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5;
self.pers["bots"]["behavior"]["strafe"] = 10;
self.pers["bots"]["behavior"]["nade"] = 15;
self.pers["bots"]["behavior"]["camp"] = 5;
self.pers["bots"]["behavior"]["follow"] = 5;
self.pers["bots"]["behavior"]["crouch"] = 15;
self.pers["bots"]["behavior"]["switch"] = 2;
self.pers["bots"]["behavior"]["class"] = 2;
self.pers["bots"]["behavior"]["jump"] = 10;
break;
case 3:
self.pers["bots"]["skill"]["aim_time"] = 0.4;
self.pers["bots"]["skill"]["init_react_time"] = 750;
self.pers["bots"]["skill"]["reaction_time"] = 500;
self.pers["bots"]["skill"]["no_trace_ads_time"] = 1000;
self.pers["bots"]["skill"]["no_trace_look_time"] = 1500;
self.pers["bots"]["skill"]["remember_time"] = 2000;
self.pers["bots"]["skill"]["fov"] = 0.6;
self.pers["bots"]["skill"]["dist_max"] = 4000;
self.pers["bots"]["skill"]["dist_start"] = 2250;
self.pers["bots"]["skill"]["spawn_time"] = 0.5;
self.pers["bots"]["skill"]["help_dist"] = 750;
self.pers["bots"]["skill"]["semi_time"] = 0.65;
self.pers["bots"]["skill"]["shoot_after_time"] = 0.65;
self.pers["bots"]["skill"]["aim_offset_time"] = 0.75;
self.pers["bots"]["skill"]["aim_offset_amount"] = 2.5;
self.pers["bots"]["skill"]["bone_update_interval"] = 1;
self.pers["bots"]["skill"]["bones"] = "j_spine4,j_spine4,j_ankle_le,j_ankle_ri,j_head";
self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5;
self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5;
self.pers["bots"]["behavior"]["strafe"] = 20;
self.pers["bots"]["behavior"]["nade"] = 20;
self.pers["bots"]["behavior"]["camp"] = 5;
self.pers["bots"]["behavior"]["follow"] = 5;
self.pers["bots"]["behavior"]["crouch"] = 10;
self.pers["bots"]["behavior"]["switch"] = 2;
self.pers["bots"]["behavior"]["class"] = 2;
self.pers["bots"]["behavior"]["jump"] = 25;
break;
case 4:
self.pers["bots"]["skill"]["aim_time"] = 0.3;
self.pers["bots"]["skill"]["init_react_time"] = 600;
self.pers["bots"]["skill"]["reaction_time"] = 400;
self.pers["bots"]["skill"]["no_trace_ads_time"] = 1000;
self.pers["bots"]["skill"]["no_trace_look_time"] = 1500;
self.pers["bots"]["skill"]["remember_time"] = 3000;
self.pers["bots"]["skill"]["fov"] = 0.55;
self.pers["bots"]["skill"]["dist_max"] = 5000;
self.pers["bots"]["skill"]["dist_start"] = 3350;
self.pers["bots"]["skill"]["spawn_time"] = 0.35;
self.pers["bots"]["skill"]["help_dist"] = 1000;
self.pers["bots"]["skill"]["semi_time"] = 0.5;
self.pers["bots"]["skill"]["shoot_after_time"] = 0.5;
self.pers["bots"]["skill"]["aim_offset_time"] = 0.5;
self.pers["bots"]["skill"]["aim_offset_amount"] = 2;
self.pers["bots"]["skill"]["bone_update_interval"] = 0.75;
self.pers["bots"]["skill"]["bones"] = "j_spine4,j_spine4,j_ankle_le,j_ankle_ri,j_head,j_head";
self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5;
self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5;
self.pers["bots"]["behavior"]["strafe"] = 30;
self.pers["bots"]["behavior"]["nade"] = 25;
self.pers["bots"]["behavior"]["camp"] = 5;
self.pers["bots"]["behavior"]["follow"] = 5;
self.pers["bots"]["behavior"]["crouch"] = 10;
self.pers["bots"]["behavior"]["switch"] = 2;
self.pers["bots"]["behavior"]["class"] = 2;
self.pers["bots"]["behavior"]["jump"] = 35;
break;
case 5:
self.pers["bots"]["skill"]["aim_time"] = 0.25;
self.pers["bots"]["skill"]["init_react_time"] = 500;
self.pers["bots"]["skill"]["reaction_time"] = 300;
self.pers["bots"]["skill"]["no_trace_ads_time"] = 1500;
self.pers["bots"]["skill"]["no_trace_look_time"] = 2000;
self.pers["bots"]["skill"]["remember_time"] = 4000;
self.pers["bots"]["skill"]["fov"] = 0.5;
self.pers["bots"]["skill"]["dist_max"] = 7500;
self.pers["bots"]["skill"]["dist_start"] = 5000;
self.pers["bots"]["skill"]["spawn_time"] = 0.25;
self.pers["bots"]["skill"]["help_dist"] = 1500;
self.pers["bots"]["skill"]["semi_time"] = 0.4;
self.pers["bots"]["skill"]["shoot_after_time"] = 0.35;
self.pers["bots"]["skill"]["aim_offset_time"] = 0.35;
self.pers["bots"]["skill"]["aim_offset_amount"] = 1.5;
self.pers["bots"]["skill"]["bone_update_interval"] = 0.5;
self.pers["bots"]["skill"]["bones"] = "j_spine4,j_head";
self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5;
self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5;
self.pers["bots"]["behavior"]["strafe"] = 40;
self.pers["bots"]["behavior"]["nade"] = 35;
self.pers["bots"]["behavior"]["camp"] = 5;
self.pers["bots"]["behavior"]["follow"] = 5;
self.pers["bots"]["behavior"]["crouch"] = 10;
self.pers["bots"]["behavior"]["switch"] = 2;
self.pers["bots"]["behavior"]["class"] = 2;
self.pers["bots"]["behavior"]["jump"] = 50;
break;
case 6:
self.pers["bots"]["skill"]["aim_time"] = 0.2;
self.pers["bots"]["skill"]["init_react_time"] = 250;
self.pers["bots"]["skill"]["reaction_time"] = 150;
self.pers["bots"]["skill"]["no_trace_ads_time"] = 2000;
self.pers["bots"]["skill"]["no_trace_look_time"] = 3000;
self.pers["bots"]["skill"]["remember_time"] = 5000;
self.pers["bots"]["skill"]["fov"] = 0.45;
self.pers["bots"]["skill"]["dist_max"] = 10000;
self.pers["bots"]["skill"]["dist_start"] = 7500;
self.pers["bots"]["skill"]["spawn_time"] = 0.2;
self.pers["bots"]["skill"]["help_dist"] = 2000;
self.pers["bots"]["skill"]["semi_time"] = 0.25;
self.pers["bots"]["skill"]["shoot_after_time"] = 0.25;
self.pers["bots"]["skill"]["aim_offset_time"] = 0.25;
self.pers["bots"]["skill"]["aim_offset_amount"] = 1;
self.pers["bots"]["skill"]["bone_update_interval"] = 0.25;
self.pers["bots"]["skill"]["bones"] = "j_spine4,j_head,j_head";
self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5;
self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5;
self.pers["bots"]["behavior"]["strafe"] = 50;
self.pers["bots"]["behavior"]["nade"] = 45;
self.pers["bots"]["behavior"]["camp"] = 5;
self.pers["bots"]["behavior"]["follow"] = 5;
self.pers["bots"]["behavior"]["crouch"] = 10;
self.pers["bots"]["behavior"]["switch"] = 2;
self.pers["bots"]["behavior"]["class"] = 2;
self.pers["bots"]["behavior"]["jump"] = 75;
break;
case 7:
self.pers["bots"]["skill"]["aim_time"] = 0.1;
self.pers["bots"]["skill"]["init_react_time"] = 100;
self.pers["bots"]["skill"]["reaction_time"] = 50;
self.pers["bots"]["skill"]["no_trace_ads_time"] = 2500;
self.pers["bots"]["skill"]["no_trace_look_time"] = 4000;
self.pers["bots"]["skill"]["remember_time"] = 7500;
self.pers["bots"]["skill"]["fov"] = 0.4;
self.pers["bots"]["skill"]["dist_max"] = 15000;
self.pers["bots"]["skill"]["dist_start"] = 10000;
self.pers["bots"]["skill"]["spawn_time"] = 0.05;
self.pers["bots"]["skill"]["help_dist"] = 3000;
self.pers["bots"]["skill"]["semi_time"] = 0.1;
self.pers["bots"]["skill"]["shoot_after_time"] = 0;
self.pers["bots"]["skill"]["aim_offset_time"] = 0;
self.pers["bots"]["skill"]["aim_offset_amount"] = 0;
self.pers["bots"]["skill"]["bone_update_interval"] = 0.05;
self.pers["bots"]["skill"]["bones"] = "j_head";
self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5;
self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5;
self.pers["bots"]["behavior"]["strafe"] = 65;
self.pers["bots"]["behavior"]["nade"] = 65;
self.pers["bots"]["behavior"]["camp"] = 5;
self.pers["bots"]["behavior"]["follow"] = 5;
self.pers["bots"]["behavior"]["crouch"] = 5;
self.pers["bots"]["behavior"]["switch"] = 2;
self.pers["bots"]["behavior"]["class"] = 2;
self.pers["bots"]["behavior"]["jump"] = 90;
break;
}
}
wait 5;
}
}
/*
Makes sure the bot is on a team.
*/
teamWatch()
{
self endon( "disconnect" );
for ( ;; )
{
while ( !isdefined( self.pers["team"] ) || !allowTeamChoice() )
wait .05;
wait 0.1;
if ( self.team != "axis" && self.team != "allies" )
self notify( "menuresponse", game["menu_team"], getcvar( "bots_team" ) );
while ( isdefined( self.pers["team"] ) )
wait .05;
}
}
/*
Chooses a random class
*/
chooseRandomClass()
{
weap = "";
weapons = [];
if ( self.team == "axis" )
{
weapons[weapons.size] = "mp40_mp";
weapons[weapons.size] = "mp44_mp";
weapons[weapons.size] = "kar98k_mp";
weapons[weapons.size] = "kar98k_sniper_mp";
weapons[weapons.size] = "shotgun_mp";
weapons[weapons.size] = "g43_mp";
}
else
{
if ( game["allies"] == "american" )
{
weapons[weapons.size] = "shotgun_mp";
weapons[weapons.size] = "bar_mp";
weapons[weapons.size] = "thompson_mp";
weapons[weapons.size] = "springfield_mp";
weapons[weapons.size] = "m1garand_mp";
weapons[weapons.size] = "m1carbine_mp";
weapons[weapons.size] = "greasegun_mp";
}
else if ( game["allies"] == "british" )
{
weapons[weapons.size] = "shotgun_mp";
weapons[weapons.size] = "sten_mp";
weapons[weapons.size] = "bren_mp";
weapons[weapons.size] = "enfield_mp";
weapons[weapons.size] = "enfield_scope_mp";
weapons[weapons.size] = "m1garand_mp";
weapons[weapons.size] = "thompson_mp";
}
else
{
weapons[weapons.size] = "shotgun_mp";
weapons[weapons.size] = "ppsh_mp";
weapons[weapons.size] = "mosin_nagant_mp";
weapons[weapons.size] = "mosin_nagant_sniper_mp";
weapons[weapons.size] = "SVT40_mp";
weapons[weapons.size] = "PPS42_mp";
}
}
weap = weapons[randomint( weapons.size )];
return weap;
}
/*
Selects a class for the bot.
*/
classWatch()
{
self endon( "disconnect" );
// cod2 has to wait this long or else theres a crash?
wait 3;
for ( ;; )
{
while ( !isdefined( self.pers["team"] ) || !allowClassChoice() )
wait .05;
wait 0.5;
if ( !isdefined( self.pers["weapon"] ) || self.pers["weapon"] == "" || !isdefined( self.bot_change_class ) )
self notify( "menuresponse", game["menu_weapon_" + self.team], self chooseRandomClass() );
self.bot_change_class = true;
while ( isdefined( self.pers["team"] ) && isdefined( self.pers["weapon"] ) && self.pers["weapon"] != "" && isdefined( self.bot_change_class ) )
wait .05;
}
}
/*
When the bot spawns.
*/
onSpawned()
{
self endon( "disconnect" );
for ( ;; )
{
self waittill( "spawned_player" );
if ( randomint( 100 ) <= self.pers["bots"]["behavior"]["class"] )
self.bot_change_class = undefined;
self.bot_lock_goal = false;
self.help_time = undefined;
self.bot_was_follow_script_update = undefined;
}
}
/*
When the bot spawned, after the difficulty wait. Start the logic for the bot.
*/
onBotSpawned()
{
self endon( "disconnect" );
level endon( "game_ended" );
for ( ;; )
{
self waittill( "bot_spawned" );
self thread start_bot_threads();
}
}
/*
Starts all the bot thinking
*/
start_bot_threads()
{
self endon( "disconnect" );
level endon( "game_ended" );
self endon( "death" );
}