mirror of
https://github.com/JezuzLizard/Recompilable-gscs-for-BO2-zombies-and-multiplayer.git
synced 2025-06-08 01:47:50 -05:00
uploaded 11 bot related scripts as a baseline
This commit is contained in:
parent
1970197ae0
commit
a36e6f7fdf
2684
patch_mp/maps/mp/bots/_bot.gsc
Normal file
2684
patch_mp/maps/mp/bots/_bot.gsc
Normal file
File diff suppressed because it is too large
Load Diff
1936
patch_mp/maps/mp/bots/_bot_combat.gsc
Normal file
1936
patch_mp/maps/mp/bots/_bot_combat.gsc
Normal file
File diff suppressed because it is too large
Load Diff
103
patch_mp/maps/mp/bots/_bot_conf.gsc
Normal file
103
patch_mp/maps/mp/bots/_bot_conf.gsc
Normal file
@ -0,0 +1,103 @@
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
|
||||
bot_conf_think()
|
||||
{
|
||||
time = getTime();
|
||||
if ( time < self.bot.update_objective )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self.bot.update_objective = time + randomintrange( 500, 1500 );
|
||||
goal = self getgoal( "conf_dogtag" );
|
||||
if ( isDefined( goal ) )
|
||||
{
|
||||
if ( !conf_tag_in_radius( goal, 64 ) )
|
||||
{
|
||||
self cancelgoal( "conf_dogtag" );
|
||||
}
|
||||
}
|
||||
conf_get_tag_in_sight();
|
||||
}
|
||||
|
||||
conf_get_tag_in_sight()
|
||||
{
|
||||
angles = self getplayerangles();
|
||||
forward = anglesToForward( angles );
|
||||
forward = vectornormalize( forward );
|
||||
closest = 999999;
|
||||
_a41 = level.dogtags;
|
||||
_k41 = getFirstArrayKey( _a41 );
|
||||
while ( isDefined( _k41 ) )
|
||||
{
|
||||
tag = _a41[ _k41 ];
|
||||
if ( is_true( tag.unreachable ) )
|
||||
{
|
||||
}
|
||||
else distsq = distancesquared( tag.curorigin, self.origin );
|
||||
if ( distsq > closest )
|
||||
{
|
||||
}
|
||||
else delta = tag.curorigin - self.origin;
|
||||
delta = vectornormalize( delta );
|
||||
dot = vectordot( forward, delta );
|
||||
if ( dot < self.bot.fov && distsq > 40000 )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( dot > self.bot.fov && distsq > 1440000 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
nearest = getnearestnode( tag.curorigin );
|
||||
if ( !isDefined( nearest ) )
|
||||
{
|
||||
tag.unreachable = 1;
|
||||
break;
|
||||
}
|
||||
else if ( ( tag.curorigin[ 2 ] - nearest.origin[ 2 ] ) > 18 )
|
||||
{
|
||||
tag.unreachable = 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !isDefined( tag.unreachable ) && !findpath( self.origin, tag.curorigin, tag, 0, 1 ) )
|
||||
{
|
||||
tag.unreachable = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
tag.unreachable = 0;
|
||||
}
|
||||
closest = distsq;
|
||||
closetag = tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
_k41 = getNextArrayKey( _a41, _k41 );
|
||||
}
|
||||
if ( isDefined( closetag ) )
|
||||
{
|
||||
self addgoal( closetag.curorigin, 16, 3, "conf_dogtag" );
|
||||
}
|
||||
}
|
||||
|
||||
conf_tag_in_radius( origin, radius )
|
||||
{
|
||||
_a106 = level.dogtags;
|
||||
_k106 = getFirstArrayKey( _a106 );
|
||||
while ( isDefined( _k106 ) )
|
||||
{
|
||||
tag = _a106[ _k106 ];
|
||||
if ( distancesquared( origin, tag.curorigin ) < ( radius * radius ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
_k106 = getNextArrayKey( _a106, _k106 );
|
||||
}
|
||||
return 0;
|
||||
}
|
404
patch_mp/maps/mp/bots/_bot_ctf.gsc
Normal file
404
patch_mp/maps/mp/bots/_bot_ctf.gsc
Normal file
@ -0,0 +1,404 @@
|
||||
#include maps/mp/gametypes/_gameobjects;
|
||||
#include maps/mp/bots/_bot_combat;
|
||||
#include maps/mp/bots/_bot;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/gametypes/ctf;
|
||||
|
||||
bot_ctf_think()
|
||||
{
|
||||
time = getTime();
|
||||
if ( time < self.bot.update_objective )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self.bot.update_objective = time + randomintrange( 500, 1500 );
|
||||
if ( maps/mp/bots/_bot::bot_get_difficulty() != "easy" )
|
||||
{
|
||||
flag_mine = ctf_get_flag( self.team );
|
||||
if ( flag_mine ishome() && distancesquared( self.origin, flag_mine.curorigin ) < 262144 )
|
||||
{
|
||||
nodes = getnodesinradius( flag_mine.curorigin, 256, 0, 64, "any", 8 );
|
||||
node = random( nodes );
|
||||
if ( cointoss() )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( node.origin, flag_mine.curorigin );
|
||||
if ( cointoss() )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
self maps/mp/bots/_bot_combat::bot_combat_toss_frag( node.origin, flag_mine.curorigin );
|
||||
if ( cointoss() )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
self maps/mp/bots/_bot_combat::bot_combat_toss_flash( node.origin, flag_mine.curorigin );
|
||||
}
|
||||
}
|
||||
if ( bot_should_patrol_flag() )
|
||||
{
|
||||
bot_patrol_flag();
|
||||
return;
|
||||
}
|
||||
self cancelgoal( "ctf_flag_patrol" );
|
||||
if ( !bot_ctf_defend() )
|
||||
{
|
||||
bot_ctf_capture();
|
||||
}
|
||||
flag_mine = ctf_get_flag( self.team );
|
||||
flag_enemy = ctf_get_flag( getotherteam( self.team ) );
|
||||
home_mine = flag_mine ctf_flag_get_home();
|
||||
if ( ctf_has_flag( flag_enemy ) && self issprinting() && distancesquared( self.origin, home_mine ) < 36864 )
|
||||
{
|
||||
if ( bot_dot_product( home_mine ) > 0,9 )
|
||||
{
|
||||
self bot_dive_to_prone( "stand" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !flag_mine ishome() && !isDefined( flag_mine.carrier ) )
|
||||
{
|
||||
if ( self issprinting() && distancesquared( self.origin, flag_mine.curorigin ) < 36864 )
|
||||
{
|
||||
if ( bot_dot_product( flag_mine.curorigin ) > 0,9 )
|
||||
{
|
||||
self bot_dive_to_prone( "stand" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_should_patrol_flag()
|
||||
{
|
||||
flag_mine = ctf_get_flag( self.team );
|
||||
flag_enemy = ctf_get_flag( getotherteam( self.team ) );
|
||||
home_mine = flag_mine ctf_flag_get_home();
|
||||
if ( self hasgoal( "ctf_flag" ) && !self atgoal( "ctf_flag" ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( ctf_has_flag( flag_enemy ) )
|
||||
{
|
||||
if ( !flag_mine ishome() )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if ( !flag_mine ishome() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( distancesquared( self.origin, flag_enemy.curorigin ) < 262144 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( bot_get_friends().size && self maps/mp/bots/_bot::bot_friend_goal_in_radius( "ctf_flag_patrol", home_mine, 1024 ) == 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctf_get_flag( team )
|
||||
{
|
||||
_a115 = level.flags;
|
||||
_k115 = getFirstArrayKey( _a115 );
|
||||
while ( isDefined( _k115 ) )
|
||||
{
|
||||
f = _a115[ _k115 ];
|
||||
if ( f maps/mp/gametypes/_gameobjects::getownerteam() == team )
|
||||
{
|
||||
return f;
|
||||
}
|
||||
_k115 = getNextArrayKey( _a115, _k115 );
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
ctf_flag_get_home()
|
||||
{
|
||||
return self.trigger.baseorigin;
|
||||
}
|
||||
|
||||
ctf_has_flag( flag )
|
||||
{
|
||||
if ( isDefined( flag.carrier ) )
|
||||
{
|
||||
return flag.carrier == self;
|
||||
}
|
||||
}
|
||||
|
||||
bot_ctf_capture()
|
||||
{
|
||||
flag_enemy = ctf_get_flag( getotherteam( self.team ) );
|
||||
flag_mine = ctf_get_flag( self.team );
|
||||
home_enemy = flag_enemy ctf_flag_get_home();
|
||||
home_mine = flag_mine ctf_flag_get_home();
|
||||
if ( ctf_has_flag( flag_enemy ) )
|
||||
{
|
||||
self addgoal( home_mine, 16, 4, "ctf_flag" );
|
||||
}
|
||||
else if ( isDefined( flag_enemy.carrier ) )
|
||||
{
|
||||
if ( self atgoal( "ctf_flag" ) )
|
||||
{
|
||||
self cancelgoal( "ctf_flag" );
|
||||
}
|
||||
goal = self getgoal( "ctf_flag" );
|
||||
if ( isDefined( goal ) && distancesquared( goal, flag_enemy.carrier.origin ) < 589824 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
nodes = getnodesinradius( flag_enemy.carrier.origin, 512, 64, 256, "any", 8 );
|
||||
if ( nodes.size )
|
||||
{
|
||||
self addgoal( random( nodes ), 16, 3, "ctf_flag" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self addgoal( flag_enemy.carrier.origin, 16, 3, "ctf_flag" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "ctf_flag", flag_enemy.curorigin, 16 ) <= 1 )
|
||||
{
|
||||
self addgoal( flag_enemy.curorigin, 16, 3, "ctf_flag" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_ctf_defend()
|
||||
{
|
||||
flag_enemy = ctf_get_flag( getotherteam( self.team ) );
|
||||
flag_mine = ctf_get_flag( self.team );
|
||||
home_enemy = flag_enemy ctf_flag_get_home();
|
||||
home_mine = flag_mine ctf_flag_get_home();
|
||||
if ( flag_mine ishome() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( ctf_has_flag( flag_enemy ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( !isDefined( flag_mine.carrier ) )
|
||||
{
|
||||
if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "ctf_flag", flag_mine.curorigin, 16 ) <= 1 )
|
||||
{
|
||||
return self bot_ctf_add_goal( flag_mine.curorigin, 4, "ctf_flag" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !flag_enemy ishome() || distance2dsquared( self.origin, home_enemy ) > 250000 )
|
||||
{
|
||||
return self bot_ctf_add_goal( flag_mine.curorigin, 4, "ctf_flag" );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "ctf_flag", home_enemy, 16 ) <= 1 )
|
||||
{
|
||||
self addgoal( home_enemy, 16, 4, "ctf_flag" );
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
bot_ctf_add_goal( origin, goal_priority, goal_name )
|
||||
{
|
||||
goal = undefined;
|
||||
if ( findpath( self.origin, origin, undefined, 0, 1 ) )
|
||||
{
|
||||
goal = origin;
|
||||
}
|
||||
else
|
||||
{
|
||||
node = bot_ctf_random_visible_node( origin );
|
||||
if ( isDefined( node ) )
|
||||
{
|
||||
if ( findpath( self.origin, node.origin, undefined, 0, 1 ) )
|
||||
{
|
||||
goal = node;
|
||||
self.bot.update_objective += randomintrange( 3000, 5000 );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( isDefined( goal ) )
|
||||
{
|
||||
self addgoal( goal, 16, goal_priority, goal_name );
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_get_look_at()
|
||||
{
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( self.origin, 1 );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
}
|
||||
enemies = self maps/mp/bots/_bot::bot_get_enemies( 0 );
|
||||
if ( enemies.size )
|
||||
{
|
||||
enemy = random( enemies );
|
||||
}
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
}
|
||||
flag_mine = ctf_get_flag( self.team );
|
||||
home_mine = flag_mine ctf_flag_get_home();
|
||||
return home_mine;
|
||||
}
|
||||
|
||||
bot_patrol_flag()
|
||||
{
|
||||
self cancelgoal( "ctf_flag" );
|
||||
flag_mine = ctf_get_flag( self.team );
|
||||
if ( self atgoal( "ctf_flag_patrol" ) )
|
||||
{
|
||||
node = getnearestnode( self.origin );
|
||||
if ( !isDefined( node ) )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "ctf_flag_patrol" );
|
||||
return;
|
||||
}
|
||||
if ( node.type == "Path" )
|
||||
{
|
||||
self setstance( "crouch" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self setstance( "stand" );
|
||||
}
|
||||
if ( getTime() > self.bot.update_lookat )
|
||||
{
|
||||
origin = self bot_get_look_at();
|
||||
z = 20;
|
||||
if ( distancesquared( origin, self.origin ) > 262144 )
|
||||
{
|
||||
z = randomintrange( 16, 60 );
|
||||
}
|
||||
self lookat( origin + ( 0, 0, z ) );
|
||||
if ( distancesquared( origin, self.origin ) > 65536 )
|
||||
{
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = vectorScale( dir, 256 );
|
||||
origin += dir;
|
||||
}
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( origin );
|
||||
self.bot.update_lookat = getTime() + randomintrange( 1500, 3000 );
|
||||
}
|
||||
goal = self getgoal( "ctf_flag_patrol" );
|
||||
nearest = base_nearest_node( flag_mine );
|
||||
mine = getnearestnode( goal );
|
||||
if ( isDefined( mine ) && !nodesvisible( mine, nearest ) )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "ctf_flag_patrol" );
|
||||
}
|
||||
if ( getTime() > self.bot.update_objective_patrol )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "ctf_flag_patrol" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
nearest = base_nearest_node( flag_mine );
|
||||
if ( self hasgoal( "ctf_flag_patrol" ) )
|
||||
{
|
||||
goal = self getgoal( "ctf_flag_patrol" );
|
||||
if ( distancesquared( self.origin, goal ) < 65536 )
|
||||
{
|
||||
origin = self bot_get_look_at();
|
||||
self lookat( origin );
|
||||
}
|
||||
if ( distancesquared( self.origin, goal ) < 16384 )
|
||||
{
|
||||
self.bot.update_objective_patrol = getTime() + randomintrange( 3000, 6000 );
|
||||
}
|
||||
mine = getnearestnode( goal );
|
||||
if ( isDefined( mine ) && !nodesvisible( mine, nearest ) )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "ctf_flag_patrol" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ( getTime() < self.bot.update_objective_patrol )
|
||||
{
|
||||
return;
|
||||
}
|
||||
nodes = getvisiblenodes( nearest );
|
||||
/#
|
||||
assert( nodes.size );
|
||||
#/
|
||||
i = randomint( nodes.size );
|
||||
while ( i < nodes.size )
|
||||
{
|
||||
if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "ctf_flag_patrol", nodes[ i ].origin, 256 ) == 0 )
|
||||
{
|
||||
self addgoal( nodes[ i ], 24, 3, "ctf_flag_patrol" );
|
||||
self.bot.update_objective_patrol = getTime() + randomintrange( 3000, 6000 );
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
base_nearest_node( flag )
|
||||
{
|
||||
home = flag ctf_flag_get_home();
|
||||
nodes = getnodesinradiussorted( home, 256, 0 );
|
||||
/#
|
||||
assert( nodes.size );
|
||||
#/
|
||||
return nodes[ 0 ];
|
||||
}
|
||||
|
||||
bot_ctf_random_visible_node( origin )
|
||||
{
|
||||
nodes = getnodesinradius( origin, 384, 0, 256 );
|
||||
nearest = maps/mp/bots/_bot_combat::bot_nearest_node( origin );
|
||||
while ( isDefined( nearest ) && nodes.size )
|
||||
{
|
||||
current = randomintrange( 0, nodes.size );
|
||||
i = 0;
|
||||
while ( i < nodes.size )
|
||||
{
|
||||
current = ( current + 1 ) % nodes.size;
|
||||
if ( nodesvisible( nodes[ current ], nearest ) )
|
||||
{
|
||||
return nodes[ current ];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
381
patch_mp/maps/mp/bots/_bot_dem.gsc
Normal file
381
patch_mp/maps/mp/bots/_bot_dem.gsc
Normal file
@ -0,0 +1,381 @@
|
||||
#include maps/mp/bots/_bot_combat;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/gametypes/dem;
|
||||
|
||||
bot_dem_think()
|
||||
{
|
||||
while ( !isDefined( level.bombzones[ 0 ].dem_nodes ) )
|
||||
{
|
||||
_a11 = level.bombzones;
|
||||
_k11 = getFirstArrayKey( _a11 );
|
||||
while ( isDefined( _k11 ) )
|
||||
{
|
||||
zone = _a11[ _k11 ];
|
||||
zone.dem_nodes = [];
|
||||
zone.dem_nodes = getnodesinradius( zone.trigger.origin, 1024, 64, 128, "Path" );
|
||||
_k11 = getNextArrayKey( _a11, _k11 );
|
||||
}
|
||||
}
|
||||
if ( self.team == game[ "attackers" ] )
|
||||
{
|
||||
bot_dem_attack_think();
|
||||
}
|
||||
else
|
||||
{
|
||||
bot_dem_defend_think();
|
||||
}
|
||||
}
|
||||
|
||||
bot_dem_attack_think()
|
||||
{
|
||||
zones = dem_get_alive_zones();
|
||||
if ( !zones.size )
|
||||
{
|
||||
return;
|
||||
}
|
||||
while ( !isDefined( self.goal_flag ) )
|
||||
{
|
||||
zones = array_randomize( zones );
|
||||
_a42 = zones;
|
||||
_k42 = getFirstArrayKey( _a42 );
|
||||
while ( isDefined( _k42 ) )
|
||||
{
|
||||
zone = _a42[ _k42 ];
|
||||
if ( zones.size == 1 || is_true( zone.bombplanted ) && !is_true( zone.bombexploded ) )
|
||||
{
|
||||
self.goal_flag = zone;
|
||||
break;
|
||||
}
|
||||
else if ( randomint( 100 ) < 50 )
|
||||
{
|
||||
self.goal_flag = zone;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
_k42 = getNextArrayKey( _a42, _k42 );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( isDefined( self.goal_flag ) )
|
||||
{
|
||||
if ( is_true( self.goal_flag.bombexploded ) )
|
||||
{
|
||||
self.goal_flag = undefined;
|
||||
self cancelgoal( "dem_guard" );
|
||||
self cancelgoal( "bomb" );
|
||||
return;
|
||||
}
|
||||
else if ( is_true( self.goal_flag.bombplanted ) )
|
||||
{
|
||||
self bot_dem_guard( self.goal_flag, self.goal_flag.dem_nodes, self.goal_flag.trigger.origin );
|
||||
return;
|
||||
}
|
||||
else if ( self bot_dem_friend_interacting( self.goal_flag.trigger.origin ) )
|
||||
{
|
||||
self bot_dem_guard( self.goal_flag, self.goal_flag.dem_nodes, self.goal_flag.trigger.origin );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
self bot_dem_attack( self.goal_flag );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_dem_defend_think()
|
||||
{
|
||||
zones = dem_get_alive_zones();
|
||||
if ( !zones.size )
|
||||
{
|
||||
return;
|
||||
}
|
||||
while ( !isDefined( self.goal_flag ) )
|
||||
{
|
||||
zones = array_randomize( zones );
|
||||
_a95 = zones;
|
||||
_k95 = getFirstArrayKey( _a95 );
|
||||
while ( isDefined( _k95 ) )
|
||||
{
|
||||
zone = _a95[ _k95 ];
|
||||
if ( zones.size == 1 || is_true( zone.bombplanted ) && !is_true( zone.bombexploded ) )
|
||||
{
|
||||
self.goal_flag = zone;
|
||||
break;
|
||||
}
|
||||
else if ( randomint( 100 ) < 50 )
|
||||
{
|
||||
self.goal_flag = zone;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
_k95 = getNextArrayKey( _a95, _k95 );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( isDefined( self.goal_flag ) )
|
||||
{
|
||||
if ( is_true( self.goal_flag.bombexploded ) )
|
||||
{
|
||||
self.goal_flag = undefined;
|
||||
self cancelgoal( "dem_guard" );
|
||||
self cancelgoal( "bomb" );
|
||||
return;
|
||||
}
|
||||
else if ( is_true( self.goal_flag.bombplanted ) && !self bot_dem_friend_interacting( self.goal_flag.trigger.origin ) )
|
||||
{
|
||||
self bot_dem_defuse( self.goal_flag );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
self bot_dem_guard( self.goal_flag, self.goal_flag.dem_nodes, self.goal_flag.trigger.origin );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_dem_attack( zone )
|
||||
{
|
||||
self cancelgoal( "dem_guard" );
|
||||
if ( !self hasgoal( "bomb" ) )
|
||||
{
|
||||
self.bomb_goal = self dem_get_bomb_goal( zone.visuals[ 0 ] );
|
||||
if ( isDefined( self.bomb_goal ) )
|
||||
{
|
||||
self addgoal( self.bomb_goal, 48, 2, "bomb" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ( !self atgoal( "bomb" ) )
|
||||
{
|
||||
if ( !self maps/mp/bots/_bot_combat::bot_combat_throw_smoke( self.bomb_goal ) )
|
||||
{
|
||||
if ( !self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( self.bomb_goal ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_lethal( self.bomb_goal );
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
self addgoal( self.bomb_goal, 48, 4, "bomb" );
|
||||
self setstance( "prone" );
|
||||
self pressusebutton( level.planttime + 1 );
|
||||
wait 0,5;
|
||||
if ( is_true( self.isplanting ) )
|
||||
{
|
||||
wait ( level.planttime + 1 );
|
||||
}
|
||||
self pressusebutton( 0 );
|
||||
defenders = self bot_get_enemies();
|
||||
_a172 = defenders;
|
||||
_k172 = getFirstArrayKey( _a172 );
|
||||
while ( isDefined( _k172 ) )
|
||||
{
|
||||
defender = _a172[ _k172 ];
|
||||
if ( defender is_bot() )
|
||||
{
|
||||
defender.goal_flag = undefined;
|
||||
}
|
||||
_k172 = getNextArrayKey( _a172, _k172 );
|
||||
}
|
||||
self setstance( "crouch" );
|
||||
wait 0,25;
|
||||
self cancelgoal( "bomb" );
|
||||
self setstance( "stand" );
|
||||
}
|
||||
|
||||
bot_dem_guard( zone, nodes, origin )
|
||||
{
|
||||
self cancelgoal( "bomb" );
|
||||
enemy = self bot_dem_enemy_interacting( origin );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_lethal( enemy.origin );
|
||||
self addgoal( enemy.origin, 128, 3, "dem_guard" );
|
||||
return;
|
||||
}
|
||||
enemy = self bot_dem_enemy_nearby( origin );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_lethal( enemy.origin );
|
||||
self addgoal( enemy.origin, 128, 3, "dem_guard" );
|
||||
return;
|
||||
}
|
||||
if ( self hasgoal( "dem_guard" ) && !self atgoal( "dem_guard" ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( origin );
|
||||
return;
|
||||
}
|
||||
node = random( nodes );
|
||||
self addgoal( node, 24, 2, "dem_guard" );
|
||||
}
|
||||
|
||||
bot_dem_defuse( zone )
|
||||
{
|
||||
self cancelgoal( "dem_guard" );
|
||||
if ( !self hasgoal( "bomb" ) )
|
||||
{
|
||||
self.bomb_goal = self dem_get_bomb_goal( zone.visuals[ 0 ] );
|
||||
if ( isDefined( self.bomb_goal ) )
|
||||
{
|
||||
self addgoal( self.bomb_goal, 48, 2, "bomb" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ( !self atgoal( "bomb" ) )
|
||||
{
|
||||
if ( !self maps/mp/bots/_bot_combat::bot_combat_throw_smoke( self.bomb_goal ) )
|
||||
{
|
||||
if ( !self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( self.bomb_goal ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_lethal( self.bomb_goal );
|
||||
}
|
||||
}
|
||||
if ( ( self.goal_flag.detonatetime - getTime() ) < 12000 )
|
||||
{
|
||||
self addgoal( self.bomb_goal, 48, 4, "bomb" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
self addgoal( self.bomb_goal, 48, 4, "bomb" );
|
||||
if ( cointoss() )
|
||||
{
|
||||
self setstance( "crouch" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self setstance( "prone" );
|
||||
}
|
||||
self pressusebutton( level.defusetime + 1 );
|
||||
wait 0,5;
|
||||
if ( is_true( self.isdefusing ) )
|
||||
{
|
||||
wait ( level.defusetime + 1 );
|
||||
}
|
||||
self pressusebutton( 0 );
|
||||
self setstance( "crouch" );
|
||||
wait 0,25;
|
||||
self cancelgoal( "bomb" );
|
||||
self setstance( "stand" );
|
||||
}
|
||||
|
||||
bot_dem_enemy_interacting( origin )
|
||||
{
|
||||
enemies = maps/mp/bots/_bot::bot_get_enemies();
|
||||
_a288 = enemies;
|
||||
_k288 = getFirstArrayKey( _a288 );
|
||||
while ( isDefined( _k288 ) )
|
||||
{
|
||||
enemy = _a288[ _k288 ];
|
||||
if ( distancesquared( enemy.origin, origin ) > 65536 )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( is_true( enemy.isdefusing ) || is_true( enemy.isplanting ) )
|
||||
{
|
||||
return enemy;
|
||||
}
|
||||
}
|
||||
_k288 = getNextArrayKey( _a288, _k288 );
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
bot_dem_friend_interacting( origin )
|
||||
{
|
||||
friends = maps/mp/bots/_bot::bot_get_friends();
|
||||
_a308 = friends;
|
||||
_k308 = getFirstArrayKey( _a308 );
|
||||
while ( isDefined( _k308 ) )
|
||||
{
|
||||
friend = _a308[ _k308 ];
|
||||
if ( distancesquared( friend.origin, origin ) > 65536 )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( is_true( friend.isdefusing ) || is_true( friend.isplanting ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
_k308 = getNextArrayKey( _a308, _k308 );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_dem_enemy_nearby( origin )
|
||||
{
|
||||
enemy = maps/mp/bots/_bot::bot_get_closest_enemy( origin, 1 );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
if ( distancesquared( enemy.origin, origin ) < 1048576 )
|
||||
{
|
||||
return enemy;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
dem_get_alive_zones()
|
||||
{
|
||||
zones = [];
|
||||
_a343 = level.bombzones;
|
||||
_k343 = getFirstArrayKey( _a343 );
|
||||
while ( isDefined( _k343 ) )
|
||||
{
|
||||
zone = _a343[ _k343 ];
|
||||
if ( is_true( zone.bombexploded ) )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
zones[ zones.size ] = zone;
|
||||
}
|
||||
_k343 = getNextArrayKey( _a343, _k343 );
|
||||
}
|
||||
return zones;
|
||||
}
|
||||
|
||||
dem_get_bomb_goal( ent )
|
||||
{
|
||||
while ( !isDefined( ent.bot_goals ) )
|
||||
{
|
||||
goals = [];
|
||||
ent.bot_goals = [];
|
||||
dir = anglesToForward( ent.angles );
|
||||
dir = vectorScale( dir, 32 );
|
||||
goals[ 0 ] = ent.origin + dir;
|
||||
goals[ 1 ] = ent.origin - dir;
|
||||
dir = anglesToRight( ent.angles );
|
||||
dir = vectorScale( dir, 48 );
|
||||
goals[ 2 ] = ent.origin + dir;
|
||||
goals[ 3 ] = ent.origin - dir;
|
||||
_a375 = goals;
|
||||
_k375 = getFirstArrayKey( _a375 );
|
||||
while ( isDefined( _k375 ) )
|
||||
{
|
||||
goal = _a375[ _k375 ];
|
||||
start = goal + vectorScale( ( 0, 0, 1 ), 128 );
|
||||
trace = bullettrace( start, goal, 0, undefined );
|
||||
ent.bot_goals[ ent.bot_goals.size ] = trace[ "position" ];
|
||||
_k375 = getNextArrayKey( _a375, _k375 );
|
||||
}
|
||||
}
|
||||
goals = array_randomize( ent.bot_goals );
|
||||
_a386 = goals;
|
||||
_k386 = getFirstArrayKey( _a386 );
|
||||
while ( isDefined( _k386 ) )
|
||||
{
|
||||
goal = _a386[ _k386 ];
|
||||
if ( findpath( self.origin, goal, 0 ) )
|
||||
{
|
||||
return goal;
|
||||
}
|
||||
_k386 = getNextArrayKey( _a386, _k386 );
|
||||
}
|
||||
return undefined;
|
||||
}
|
483
patch_mp/maps/mp/bots/_bot_dom.gsc
Normal file
483
patch_mp/maps/mp/bots/_bot_dom.gsc
Normal file
@ -0,0 +1,483 @@
|
||||
#include maps/mp/bots/_bot;
|
||||
#include maps/mp/bots/_bot_combat;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/gametypes/dom;
|
||||
|
||||
bot_dom_think()
|
||||
{
|
||||
time = getTime();
|
||||
if ( time < self.bot.update_objective )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self.bot.update_objective = time + randomintrange( 500, 1500 );
|
||||
if ( self bot_is_capturing_flag() )
|
||||
{
|
||||
flag = self dom_get_closest_flag();
|
||||
self bot_capture_flag( flag );
|
||||
return;
|
||||
}
|
||||
flag = self dom_get_closest_flag();
|
||||
if ( flag getflagteam() != self.team && distance2dsquared( self.origin, flag.origin ) < 147456 && !bot_has_flag_goal( flag ) )
|
||||
{
|
||||
self bot_move_to_flag( flag );
|
||||
return;
|
||||
}
|
||||
flag = dom_get_weighted_flag( "neutral" );
|
||||
if ( !isDefined( flag ) )
|
||||
{
|
||||
flag = dom_get_best_flag( self.team );
|
||||
}
|
||||
if ( dom_has_two_flags( self.team ) )
|
||||
{
|
||||
flag = dom_get_best_flag( self.team );
|
||||
}
|
||||
if ( !isDefined( flag ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( !bot_has_flag_goal( flag ) && !self bot_goal_is_enemy_flag() )
|
||||
{
|
||||
self bot_move_to_flag( flag );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !dom_is_game_start() )
|
||||
{
|
||||
self bot_flag_grenade( flag );
|
||||
}
|
||||
if ( distancesquared( self.origin, flag.origin ) < ( flag.radius * flag.radius ) && self istouching( flag.useobj.trigger ) )
|
||||
{
|
||||
self bot_capture_flag( flag );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_move_to_flag( flag )
|
||||
{
|
||||
if ( level.script == "mp_frostbite" )
|
||||
{
|
||||
nodes = getnodesinradius( flag.origin, flag.radius, 0, 32 );
|
||||
}
|
||||
else
|
||||
{
|
||||
nodes = getnodesinradius( flag.origin, flag.radius, 0 );
|
||||
}
|
||||
/#
|
||||
assert( nodes.size );
|
||||
#/
|
||||
node = random( nodes );
|
||||
self addgoal( node, 24, 3, "dom_flag" );
|
||||
}
|
||||
|
||||
bot_is_capturing_flag()
|
||||
{
|
||||
return self atgoal( "dom_flag" );
|
||||
}
|
||||
|
||||
bot_has_flag_goal( flag )
|
||||
{
|
||||
origin = self getgoal( "dom_flag" );
|
||||
if ( isDefined( origin ) )
|
||||
{
|
||||
if ( distancesquared( flag.origin, origin ) < ( flag.radius * flag.radius ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_has_no_goal()
|
||||
{
|
||||
origin = self getgoal( "dom_flag" );
|
||||
if ( isDefined( origin ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
bot_goal_is_enemy_flag()
|
||||
{
|
||||
origin = self getgoal( "dom_flag" );
|
||||
while ( isDefined( origin ) )
|
||||
{
|
||||
_a130 = level.flags;
|
||||
_k130 = getFirstArrayKey( _a130 );
|
||||
while ( isDefined( _k130 ) )
|
||||
{
|
||||
flag = _a130[ _k130 ];
|
||||
if ( distancesquared( flag.origin, origin ) < ( flag.radius * flag.radius ) )
|
||||
{
|
||||
if ( flag getflagteam() != self.team || dom_is_flag_contested( flag ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
_k130 = getNextArrayKey( _a130, _k130 );
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_flag_grenade( flag )
|
||||
{
|
||||
if ( flag getflagteam() != self.team )
|
||||
{
|
||||
if ( bot_tactical_insertion( flag ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_smoke( flag.origin );
|
||||
}
|
||||
if ( !dom_is_flag_contested( flag ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( !self maps/mp/bots/_bot_combat::bot_combat_throw_lethal( flag.origin ) )
|
||||
{
|
||||
if ( !self maps/mp/bots/_bot_combat::bot_combat_throw_tactical( flag.origin ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( flag.origin );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_get_look_at( flag )
|
||||
{
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( self.origin, 0 );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
}
|
||||
spawn = random( level.spawn_all );
|
||||
node = getvisiblenode( self.origin, spawn.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
return flag.origin;
|
||||
}
|
||||
|
||||
bot_capture_flag( flag )
|
||||
{
|
||||
time = getTime();
|
||||
if ( flag getflagteam() != self.team )
|
||||
{
|
||||
if ( self getstance() == "prone" )
|
||||
{
|
||||
self addgoal( self.origin, 24, 4, "dom_flag" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self addgoal( self.origin, 24, 3, "dom_flag" );
|
||||
}
|
||||
if ( time > self.bot.update_lookat )
|
||||
{
|
||||
origin = self bot_get_look_at( flag );
|
||||
z = 20;
|
||||
if ( distancesquared( origin, self.origin ) > 262144 )
|
||||
{
|
||||
z = randomintrange( 16, 60 );
|
||||
}
|
||||
self lookat( origin + ( 0, 0, z ) );
|
||||
self.bot.update_lookat = time + randomintrange( 1500, 3000 );
|
||||
if ( distancesquared( origin, self.origin ) > 65536 )
|
||||
{
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = vectorScale( dir, 256 );
|
||||
origin += dir;
|
||||
}
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( origin );
|
||||
self maps/mp/bots/_bot_combat::bot_combat_toss_frag( self.origin );
|
||||
self maps/mp/bots/_bot_combat::bot_combat_toss_flash( self.origin );
|
||||
if ( !dom_is_game_start() )
|
||||
{
|
||||
weapon = self getcurrentweapon();
|
||||
if ( weapon == "riotshield_mp" || weapon == "minigun_mp" )
|
||||
{
|
||||
if ( cointoss() )
|
||||
{
|
||||
self addgoal( self.origin, 24, 4, "dom_flag" );
|
||||
self setstance( "crouch" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( cointoss() && !bot_friend_in_radius( self.origin, 384 ) )
|
||||
{
|
||||
self addgoal( self.origin, 24, 4, "dom_flag" );
|
||||
wait randomfloatrange( 0,5, 1 );
|
||||
self setstance( "prone" );
|
||||
self.bot.update_lookat += 5000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !dom_is_game_start() )
|
||||
{
|
||||
if ( self getstance() == "stand" )
|
||||
{
|
||||
wait randomfloatrange( 0,5, 1 );
|
||||
self setstance( "crouch" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else self clearlookat();
|
||||
self cancelgoal( "dom_flag" );
|
||||
if ( self getstance() == "crouch" )
|
||||
{
|
||||
self setstance( "stand" );
|
||||
wait 0,25;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( self getstance() == "prone" )
|
||||
{
|
||||
self setstance( "crouch" );
|
||||
wait 0,25;
|
||||
self setstance( "stand" );
|
||||
wait 0,25;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dom_is_game_start()
|
||||
{
|
||||
/#
|
||||
assert( isDefined( level.flags ) );
|
||||
#/
|
||||
_a289 = level.flags;
|
||||
_k289 = getFirstArrayKey( _a289 );
|
||||
while ( isDefined( _k289 ) )
|
||||
{
|
||||
flag = _a289[ _k289 ];
|
||||
if ( flag getflagteam() != "neutral" )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
_k289 = getNextArrayKey( _a289, _k289 );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
dom_get_closest_flag()
|
||||
{
|
||||
flags = arraysort( level.flags, self.origin );
|
||||
return flags[ 0 ];
|
||||
}
|
||||
|
||||
dom_get_weighted_flag( owner )
|
||||
{
|
||||
/#
|
||||
assert( isDefined( level.flags ) );
|
||||
#/
|
||||
best = undefined;
|
||||
distsq = 9999999;
|
||||
_a313 = level.flags;
|
||||
_k313 = getFirstArrayKey( _a313 );
|
||||
while ( isDefined( _k313 ) )
|
||||
{
|
||||
flag = _a313[ _k313 ];
|
||||
if ( isDefined( owner ) && flag getflagteam() != owner )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
d = distancesquared( self.origin, flag.origin );
|
||||
if ( distsq != 9999999 && d < distsq || randomint( 100 ) < 70 && randomint( 100 ) > 70 )
|
||||
{
|
||||
best = flag;
|
||||
distsq = d;
|
||||
}
|
||||
}
|
||||
_k313 = getNextArrayKey( _a313, _k313 );
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
dom_get_weighted_enemy_flag( team )
|
||||
{
|
||||
/#
|
||||
assert( isDefined( level.flags ) );
|
||||
#/
|
||||
best = undefined;
|
||||
distsq = 9999999;
|
||||
_a339 = level.flags;
|
||||
_k339 = getFirstArrayKey( _a339 );
|
||||
while ( isDefined( _k339 ) )
|
||||
{
|
||||
flag = _a339[ _k339 ];
|
||||
if ( flag getflagteam() == team )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
d = distancesquared( self.origin, flag.origin );
|
||||
if ( distsq != 9999999 && d < distsq || randomint( 100 ) < 80 && randomint( 100 ) > 80 )
|
||||
{
|
||||
best = flag;
|
||||
distsq = d;
|
||||
}
|
||||
}
|
||||
_k339 = getNextArrayKey( _a339, _k339 );
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
dom_is_flag_contested( flag )
|
||||
{
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( flag.origin, 0 );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
return distancesquared( enemy.origin, flag.origin ) < 147456;
|
||||
}
|
||||
}
|
||||
|
||||
dom_has_two_flags( team )
|
||||
{
|
||||
count = 0;
|
||||
_a368 = level.flags;
|
||||
_k368 = getFirstArrayKey( _a368 );
|
||||
while ( isDefined( _k368 ) )
|
||||
{
|
||||
flag = _a368[ _k368 ];
|
||||
if ( dom_is_flag_contested( flag ) )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( flag getflagteam() == team )
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
_k368 = getNextArrayKey( _a368, _k368 );
|
||||
}
|
||||
return count >= 2;
|
||||
}
|
||||
|
||||
dom_get_weighted_contested_flag( team )
|
||||
{
|
||||
/#
|
||||
assert( isDefined( level.flags ) );
|
||||
#/
|
||||
best = undefined;
|
||||
distsq = 9999999;
|
||||
_a391 = level.flags;
|
||||
_k391 = getFirstArrayKey( _a391 );
|
||||
while ( isDefined( _k391 ) )
|
||||
{
|
||||
flag = _a391[ _k391 ];
|
||||
if ( !dom_is_flag_contested( flag ) )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
d = distancesquared( self.origin, flag.origin );
|
||||
if ( distsq != 9999999 && d < distsq || randomint( 100 ) < 80 && randomint( 100 ) > 80 )
|
||||
{
|
||||
best = flag;
|
||||
distsq = d;
|
||||
}
|
||||
}
|
||||
_k391 = getNextArrayKey( _a391, _k391 );
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
dom_get_random_flag( owner )
|
||||
{
|
||||
/#
|
||||
assert( isDefined( level.flags ) );
|
||||
#/
|
||||
flagindex = randomintrange( 0, level.flags.size );
|
||||
if ( !isDefined( owner ) )
|
||||
{
|
||||
return level.flags[ flagindex ];
|
||||
}
|
||||
i = 0;
|
||||
while ( i < level.flags.size )
|
||||
{
|
||||
if ( level.flags[ flagindex ] getflagteam() == owner )
|
||||
{
|
||||
return level.flags[ flagindex ];
|
||||
}
|
||||
flagindex = ( flagindex + 1 ) % level.flags.size;
|
||||
i++;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
dom_get_best_flag( team )
|
||||
{
|
||||
flag1 = dom_get_weighted_enemy_flag( team );
|
||||
flag2 = dom_get_weighted_contested_flag( team );
|
||||
if ( !isDefined( flag1 ) )
|
||||
{
|
||||
return flag2;
|
||||
}
|
||||
if ( !isDefined( flag2 ) )
|
||||
{
|
||||
return flag1;
|
||||
}
|
||||
offchance = randomint( 100 ) > 80;
|
||||
if ( distancesquared( self.origin, flag1.origin ) < distancesquared( self.origin, flag2.origin ) )
|
||||
{
|
||||
if ( !offchance )
|
||||
{
|
||||
return flag1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return flag2;
|
||||
}
|
||||
}
|
||||
if ( !offchance )
|
||||
{
|
||||
return flag2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return flag1;
|
||||
}
|
||||
}
|
||||
|
||||
bot_tactical_insertion( flag )
|
||||
{
|
||||
if ( self getweaponammostock( "tactical_insertion_mp" ) <= 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
dist = self getlookaheaddist();
|
||||
dir = self getlookaheaddir();
|
||||
if ( !isDefined( dist ) || !isDefined( dir ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
node = bot_nearest_node( flag.origin );
|
||||
mine = bot_nearest_node( self.origin );
|
||||
if ( isDefined( mine ) && !nodesvisible( mine, node ) )
|
||||
{
|
||||
origin = self.origin + vectorScale( dir, dist );
|
||||
next = bot_nearest_node( origin );
|
||||
if ( next isdangerous( self.team ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( isDefined( next ) && nodesvisible( next, node ) )
|
||||
{
|
||||
return bot_combat_tactical_insertion( self.origin );
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
202
patch_mp/maps/mp/bots/_bot_hack.gsc
Normal file
202
patch_mp/maps/mp/bots/_bot_hack.gsc
Normal file
@ -0,0 +1,202 @@
|
||||
#include maps/mp/bots/_bot;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/gametypes/ctf;
|
||||
|
||||
bot_hack_tank_get_goal_origin( tank )
|
||||
{
|
||||
nodes = getnodesinradiussorted( tank.origin, 256, 0, 64, "Path" );
|
||||
_a11 = nodes;
|
||||
_k11 = getFirstArrayKey( _a11 );
|
||||
while ( isDefined( _k11 ) )
|
||||
{
|
||||
node = _a11[ _k11 ];
|
||||
dir = vectornormalize( node.origin - tank.origin );
|
||||
dir = vectorScale( dir, 32 );
|
||||
goal = tank.origin + dir;
|
||||
if ( findpath( self.origin, goal, 0 ) )
|
||||
{
|
||||
return goal;
|
||||
}
|
||||
_k11 = getNextArrayKey( _a11, _k11 );
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
bot_hack_has_goal( tank )
|
||||
{
|
||||
goal = self getgoal( "hack" );
|
||||
if ( isDefined( goal ) )
|
||||
{
|
||||
if ( distancesquared( goal, tank.origin ) < 16384 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_hack_at_goal()
|
||||
{
|
||||
if ( self atgoal( "hack" ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
goal = self getgoal( "hack" );
|
||||
while ( isDefined( goal ) )
|
||||
{
|
||||
tanks = getentarray( "talon", "targetname" );
|
||||
tanks = arraysort( tanks, self.origin );
|
||||
_a56 = tanks;
|
||||
_k56 = getFirstArrayKey( _a56 );
|
||||
while ( isDefined( _k56 ) )
|
||||
{
|
||||
tank = _a56[ _k56 ];
|
||||
if ( distancesquared( goal, tank.origin ) < 16384 )
|
||||
{
|
||||
if ( isDefined( tank.trigger ) && self istouching( tank.trigger ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
_k56 = getNextArrayKey( _a56, _k56 );
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_hack_goal_pregame( tanks )
|
||||
{
|
||||
_a73 = tanks;
|
||||
_k73 = getFirstArrayKey( _a73 );
|
||||
while ( isDefined( _k73 ) )
|
||||
{
|
||||
tank = _a73[ _k73 ];
|
||||
if ( isDefined( tank.owner ) )
|
||||
{
|
||||
}
|
||||
else if ( isDefined( tank.team ) && tank.team == self.team )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
goal = self bot_hack_tank_get_goal_origin( tank );
|
||||
if ( isDefined( goal ) )
|
||||
{
|
||||
if ( self addgoal( goal, 24, 2, "hack" ) )
|
||||
{
|
||||
self.goal_flag = tank;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
_k73 = getNextArrayKey( _a73, _k73 );
|
||||
}
|
||||
}
|
||||
|
||||
bot_hack_think()
|
||||
{
|
||||
if ( bot_hack_at_goal() )
|
||||
{
|
||||
self setstance( "crouch" );
|
||||
wait 0,25;
|
||||
self addgoal( self.origin, 24, 4, "hack" );
|
||||
self pressusebutton( level.drone_hack_time + 1 );
|
||||
wait ( level.drone_hack_time + 1 );
|
||||
self setstance( "stand" );
|
||||
self cancelgoal( "hack" );
|
||||
}
|
||||
tanks = getentarray( "talon", "targetname" );
|
||||
tanks = arraysort( tanks, self.origin );
|
||||
if ( !is_true( level.drones_spawned ) )
|
||||
{
|
||||
self bot_hack_goal_pregame( tanks );
|
||||
}
|
||||
else
|
||||
{
|
||||
_a122 = tanks;
|
||||
_k122 = getFirstArrayKey( _a122 );
|
||||
while ( isDefined( _k122 ) )
|
||||
{
|
||||
tank = _a122[ _k122 ];
|
||||
if ( isDefined( tank.owner ) && tank.owner == self )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !isDefined( tank.owner ) )
|
||||
{
|
||||
if ( self bot_hack_has_goal( tank ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
goal = self bot_hack_tank_get_goal_origin( tank );
|
||||
if ( isDefined( goal ) )
|
||||
{
|
||||
self addgoal( goal, 24, 2, "hack" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ( tank.isstunned && distancesquared( self.origin, tank.origin ) < 262144 )
|
||||
{
|
||||
goal = self bot_hack_tank_get_goal_origin( tank );
|
||||
if ( isDefined( goal ) )
|
||||
{
|
||||
self addgoal( goal, 24, 3, "hack" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
_k122 = getNextArrayKey( _a122, _k122 );
|
||||
}
|
||||
if ( !maps/mp/bots/_bot::bot_vehicle_weapon_ammo( "emp_grenade_mp" ) )
|
||||
{
|
||||
ammo = getentarray( "weapon_scavenger_item_hack_mp", "classname" );
|
||||
ammo = arraysort( ammo, self.origin );
|
||||
_a162 = ammo;
|
||||
_k162 = getFirstArrayKey( _a162 );
|
||||
while ( isDefined( _k162 ) )
|
||||
{
|
||||
bag = _a162[ _k162 ];
|
||||
if ( findpath( self.origin, bag.origin, 0 ) )
|
||||
{
|
||||
self addgoal( bag.origin, 24, 2, "hack" );
|
||||
return;
|
||||
}
|
||||
_k162 = getNextArrayKey( _a162, _k162 );
|
||||
}
|
||||
return;
|
||||
}
|
||||
_a174 = tanks;
|
||||
_k174 = getFirstArrayKey( _a174 );
|
||||
while ( isDefined( _k174 ) )
|
||||
{
|
||||
tank = _a174[ _k174 ];
|
||||
if ( isDefined( tank.owner ) && tank.owner == self )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( tank.isstunned )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( self throwgrenade( "emp_grenade_mp", tank.origin ) )
|
||||
{
|
||||
self waittill( "grenade_fire" );
|
||||
goal = self bot_hack_tank_get_goal_origin( tank );
|
||||
if ( isDefined( goal ) )
|
||||
{
|
||||
self addgoal( goal, 24, 3, "hack" );
|
||||
wait 0,5;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_k174 = getNextArrayKey( _a174, _k174 );
|
||||
}
|
||||
}
|
||||
}
|
373
patch_mp/maps/mp/bots/_bot_hq.gsc
Normal file
373
patch_mp/maps/mp/bots/_bot_hq.gsc
Normal file
@ -0,0 +1,373 @@
|
||||
#include maps/mp/bots/_bot_combat;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/gametypes/koth;
|
||||
|
||||
bot_hq_think()
|
||||
{
|
||||
time = getTime();
|
||||
if ( time < self.bot.update_objective )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self.bot.update_objective = time + randomintrange( 500, 1500 );
|
||||
if ( bot_should_patrol_hq() )
|
||||
{
|
||||
self bot_patrol_hq();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !bot_has_hq_goal() )
|
||||
{
|
||||
self bot_move_to_hq();
|
||||
}
|
||||
}
|
||||
if ( self bot_is_capturing_hq() )
|
||||
{
|
||||
self bot_capture_hq();
|
||||
}
|
||||
bot_hq_tactical_insertion();
|
||||
bot_hq_grenade();
|
||||
if ( !bot_is_capturing_hq() && !self atgoal( "hq_patrol" ) )
|
||||
{
|
||||
mine = getnearestnode( self.origin );
|
||||
node = hq_nearest_node();
|
||||
if ( isDefined( mine ) && nodesvisible( mine, node ) )
|
||||
{
|
||||
self lookat( level.radio.baseorigin + vectorScale( ( 0, 0, 1 ), 30 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_has_hq_goal()
|
||||
{
|
||||
origin = self getgoal( "hq_radio" );
|
||||
while ( isDefined( origin ) )
|
||||
{
|
||||
_a53 = level.radio.nodes;
|
||||
_k53 = getFirstArrayKey( _a53 );
|
||||
while ( isDefined( _k53 ) )
|
||||
{
|
||||
node = _a53[ _k53 ];
|
||||
if ( distancesquared( origin, node.origin ) < 4096 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
_k53 = getNextArrayKey( _a53, _k53 );
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_is_capturing_hq()
|
||||
{
|
||||
return self atgoal( "hq_radio" );
|
||||
}
|
||||
|
||||
bot_should_patrol_hq()
|
||||
{
|
||||
if ( level.radio.gameobject.ownerteam == "neutral" )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( level.radio.gameobject.ownerteam != self.team )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( hq_is_contested() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
bot_patrol_hq()
|
||||
{
|
||||
self cancelgoal( "hq_radio" );
|
||||
if ( self atgoal( "hq_patrol" ) )
|
||||
{
|
||||
node = getnearestnode( self.origin );
|
||||
if ( node.type == "Path" )
|
||||
{
|
||||
self setstance( "crouch" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self setstance( "stand" );
|
||||
}
|
||||
if ( getTime() > self.bot.update_lookat )
|
||||
{
|
||||
origin = self bot_get_look_at();
|
||||
z = 20;
|
||||
if ( distancesquared( origin, self.origin ) > 262144 )
|
||||
{
|
||||
z = randomintrange( 16, 60 );
|
||||
}
|
||||
self lookat( origin + ( 0, 0, z ) );
|
||||
if ( distancesquared( origin, self.origin ) > 65536 )
|
||||
{
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = vectorScale( dir, 256 );
|
||||
origin += dir;
|
||||
}
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( origin );
|
||||
self.bot.update_lookat = getTime() + randomintrange( 1500, 3000 );
|
||||
}
|
||||
goal = self getgoal( "hq_patrol" );
|
||||
nearest = hq_nearest_node();
|
||||
mine = getnearestnode( goal );
|
||||
if ( isDefined( mine ) && !nodesvisible( mine, nearest ) )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "hq_patrol" );
|
||||
}
|
||||
if ( getTime() > self.bot.update_objective_patrol )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "hq_patrol" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
nearest = hq_nearest_node();
|
||||
if ( self hasgoal( "hq_patrol" ) )
|
||||
{
|
||||
goal = self getgoal( "hq_patrol" );
|
||||
if ( distancesquared( self.origin, goal ) < 65536 )
|
||||
{
|
||||
origin = self bot_get_look_at();
|
||||
self lookat( origin );
|
||||
}
|
||||
if ( distancesquared( self.origin, goal ) < 16384 )
|
||||
{
|
||||
self.bot.update_objective_patrol = getTime() + randomintrange( 3000, 6000 );
|
||||
}
|
||||
mine = getnearestnode( goal );
|
||||
if ( isDefined( mine ) && !nodesvisible( mine, nearest ) )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "hq_patrol" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
nodes = getvisiblenodes( nearest );
|
||||
/#
|
||||
assert( nodes.size );
|
||||
#/
|
||||
i = randomint( nodes.size );
|
||||
while ( i < nodes.size )
|
||||
{
|
||||
if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "hq_radio", nodes[ i ].origin, 128 ) == 0 )
|
||||
{
|
||||
if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "hq_patrol", nodes[ i ].origin, 256 ) == 0 )
|
||||
{
|
||||
self addgoal( nodes[ i ], 24, 3, "hq_patrol" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
bot_move_to_hq()
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "hq_radio" );
|
||||
self cancelgoal( "hq_patrol" );
|
||||
if ( self getstance() == "prone" )
|
||||
{
|
||||
self setstance( "crouch" );
|
||||
wait 0,25;
|
||||
}
|
||||
if ( self getstance() == "crouch" )
|
||||
{
|
||||
self setstance( "stand" );
|
||||
wait 0,25;
|
||||
}
|
||||
nodes = array_randomize( level.radio.nodes );
|
||||
_a219 = nodes;
|
||||
_k219 = getFirstArrayKey( _a219 );
|
||||
while ( isDefined( _k219 ) )
|
||||
{
|
||||
node = _a219[ _k219 ];
|
||||
if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "hq_radio", node.origin, 64 ) == 0 )
|
||||
{
|
||||
self addgoal( node, 24, 3, "hq_radio" );
|
||||
return;
|
||||
}
|
||||
_k219 = getNextArrayKey( _a219, _k219 );
|
||||
}
|
||||
self addgoal( random( nodes ), 24, 3, "hq_radio" );
|
||||
}
|
||||
|
||||
bot_get_look_at()
|
||||
{
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( self.origin, 1 );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
}
|
||||
enemies = self maps/mp/bots/_bot::bot_get_enemies( 0 );
|
||||
if ( enemies.size )
|
||||
{
|
||||
enemy = random( enemies );
|
||||
}
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
}
|
||||
spawn = random( level.spawnpoints );
|
||||
node = getvisiblenode( self.origin, spawn.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
return level.radio.baseorigin;
|
||||
}
|
||||
|
||||
bot_capture_hq()
|
||||
{
|
||||
self addgoal( self.origin, 24, 3, "hq_radio" );
|
||||
self setstance( "crouch" );
|
||||
if ( getTime() > self.bot.update_lookat )
|
||||
{
|
||||
origin = self bot_get_look_at();
|
||||
z = 20;
|
||||
if ( distancesquared( origin, self.origin ) > 262144 )
|
||||
{
|
||||
z = randomintrange( 16, 60 );
|
||||
}
|
||||
self lookat( origin + ( 0, 0, z ) );
|
||||
if ( distancesquared( origin, self.origin ) > 65536 )
|
||||
{
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = vectorScale( dir, 256 );
|
||||
origin += dir;
|
||||
}
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( origin );
|
||||
self.bot.update_lookat = getTime() + randomintrange( 1500, 3000 );
|
||||
}
|
||||
}
|
||||
|
||||
any_other_team_touching( skip_team )
|
||||
{
|
||||
_a307 = level.teams;
|
||||
_k307 = getFirstArrayKey( _a307 );
|
||||
while ( isDefined( _k307 ) )
|
||||
{
|
||||
team = _a307[ _k307 ];
|
||||
if ( team == skip_team )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( level.radio.gameobject.numtouching[ team ] )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
_k307 = getNextArrayKey( _a307, _k307 );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
is_hq_contested( skip_team )
|
||||
{
|
||||
if ( any_other_team_touching( skip_team ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( level.radio.baseorigin, 1 );
|
||||
if ( isDefined( enemy ) && distancesquared( enemy.origin, level.radio.baseorigin ) < 262144 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_hq_grenade()
|
||||
{
|
||||
enemies = bot_get_enemies();
|
||||
if ( !enemies.size )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( self atgoal( "hq_patrol" ) || self atgoal( "hq_radio" ) )
|
||||
{
|
||||
if ( self getweaponammostock( "proximity_grenade_mp" ) > 0 )
|
||||
{
|
||||
origin = bot_get_look_at();
|
||||
if ( self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( origin ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !is_hq_contested( self.team ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_smoke( level.radio.baseorigin );
|
||||
return;
|
||||
}
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( level.radio.baseorigin, 0 );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
origin = enemy.origin;
|
||||
}
|
||||
else
|
||||
{
|
||||
origin = level.radio.baseorigin;
|
||||
}
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = ( 0, dir[ 1 ], 0 );
|
||||
origin += vectorScale( dir, 128 );
|
||||
if ( !self maps/mp/bots/_bot_combat::bot_combat_throw_lethal( origin ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_tactical( origin );
|
||||
}
|
||||
}
|
||||
|
||||
bot_hq_tactical_insertion()
|
||||
{
|
||||
if ( !self hasweapon( "tactical_insertion_mp" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
dist = self getlookaheaddist();
|
||||
dir = self getlookaheaddir();
|
||||
if ( !isDefined( dist ) || !isDefined( dir ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
node = hq_nearest_node();
|
||||
mine = getnearestnode( self.origin );
|
||||
if ( isDefined( mine ) && !nodesvisible( mine, node ) )
|
||||
{
|
||||
origin = self.origin + vectorScale( dir, dist );
|
||||
next = getnearestnode( origin );
|
||||
if ( isDefined( next ) && nodesvisible( next, node ) )
|
||||
{
|
||||
bot_combat_tactical_insertion( self.origin );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hq_nearest_node()
|
||||
{
|
||||
return random( level.radio.nodes );
|
||||
}
|
||||
|
||||
hq_is_contested()
|
||||
{
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( level.radio.baseorigin, 0 );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
return distancesquared( enemy.origin, level.radio.baseorigin ) < ( level.radio.node_radius * level.radio.node_radius );
|
||||
}
|
||||
}
|
308
patch_mp/maps/mp/bots/_bot_koth.gsc
Normal file
308
patch_mp/maps/mp/bots/_bot_koth.gsc
Normal file
@ -0,0 +1,308 @@
|
||||
#include maps/mp/bots/_bot_combat;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/gametypes/koth;
|
||||
|
||||
bot_koth_think()
|
||||
{
|
||||
if ( !isDefined( level.zone.trig.goal_radius ) )
|
||||
{
|
||||
maxs = level.zone.trig getmaxs();
|
||||
maxs = level.zone.trig.origin + maxs;
|
||||
level.zone.trig.goal_radius = distance( level.zone.trig.origin, maxs );
|
||||
/#
|
||||
println( "distance: " + level.zone.trig.goal_radius );
|
||||
#/
|
||||
ground = bullettrace( level.zone.gameobject.curorigin, level.zone.gameobject.curorigin - vectorScale( ( 0, 0, 1 ), 1024 ), 0, undefined );
|
||||
level.zone.trig.goal = ground[ "position" ] + vectorScale( ( 0, 0, 1 ), 8 );
|
||||
}
|
||||
if ( !bot_has_hill_goal() )
|
||||
{
|
||||
self bot_move_to_hill();
|
||||
}
|
||||
if ( self bot_is_at_hill() )
|
||||
{
|
||||
self bot_capture_hill();
|
||||
}
|
||||
bot_hill_tactical_insertion();
|
||||
bot_hill_grenade();
|
||||
}
|
||||
|
||||
bot_has_hill_goal()
|
||||
{
|
||||
origin = self getgoal( "koth_hill" );
|
||||
if ( isDefined( origin ) )
|
||||
{
|
||||
if ( distance2dsquared( level.zone.gameobject.curorigin, origin ) < ( level.zone.trig.goal_radius * level.zone.trig.goal_radius ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_is_at_hill()
|
||||
{
|
||||
return self atgoal( "koth_hill" );
|
||||
}
|
||||
|
||||
bot_move_to_hill()
|
||||
{
|
||||
if ( getTime() < ( self.bot.update_objective + 4000 ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self clearlookat();
|
||||
self cancelgoal( "koth_hill" );
|
||||
if ( self getstance() == "prone" )
|
||||
{
|
||||
self setstance( "crouch" );
|
||||
wait 0,25;
|
||||
}
|
||||
if ( self getstance() == "crouch" )
|
||||
{
|
||||
self setstance( "stand" );
|
||||
wait 0,25;
|
||||
}
|
||||
nodes = getnodesinradiussorted( level.zone.trig.goal, level.zone.trig.goal_radius, 0, 128 );
|
||||
_a80 = nodes;
|
||||
_k80 = getFirstArrayKey( _a80 );
|
||||
while ( isDefined( _k80 ) )
|
||||
{
|
||||
node = _a80[ _k80 ];
|
||||
if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "koth_hill", node.origin, 64 ) == 0 )
|
||||
{
|
||||
if ( findpath( self.origin, node.origin, self, 0, 1 ) )
|
||||
{
|
||||
self addgoal( node, 24, 3, "koth_hill" );
|
||||
self.bot.update_objective = getTime();
|
||||
return;
|
||||
}
|
||||
}
|
||||
_k80 = getNextArrayKey( _a80, _k80 );
|
||||
}
|
||||
}
|
||||
|
||||
bot_get_look_at()
|
||||
{
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( self.origin, 1 );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 1024 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
}
|
||||
enemies = self maps/mp/bots/_bot::bot_get_enemies( 0 );
|
||||
if ( enemies.size )
|
||||
{
|
||||
enemy = random( enemies );
|
||||
}
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 1024 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
}
|
||||
spawn = random( level.spawnpoints );
|
||||
node = getvisiblenode( self.origin, spawn.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 1024 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
return level.zone.gameobject.curorigin;
|
||||
}
|
||||
|
||||
bot_capture_hill()
|
||||
{
|
||||
self addgoal( self.origin, 24, 3, "koth_hill" );
|
||||
self setstance( "crouch" );
|
||||
if ( getTime() > self.bot.update_lookat )
|
||||
{
|
||||
origin = self bot_get_look_at();
|
||||
z = 20;
|
||||
if ( distancesquared( origin, self.origin ) > 262144 )
|
||||
{
|
||||
z = randomintrange( 16, 60 );
|
||||
}
|
||||
self lookat( origin + ( 0, 0, z ) );
|
||||
if ( distancesquared( origin, self.origin ) > 65536 )
|
||||
{
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = vectorScale( dir, 256 );
|
||||
origin += dir;
|
||||
}
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( origin );
|
||||
while ( cointoss() && lengthsquared( self getvelocity() ) < 2 )
|
||||
{
|
||||
nodes = getnodesinradius( level.zone.trig.goal, level.zone.trig.goal_radius + 128, 0, 128 );
|
||||
i = randomintrange( 0, nodes.size );
|
||||
while ( i < nodes.size )
|
||||
{
|
||||
node = nodes[ i ];
|
||||
if ( distancesquared( node.origin, self.origin ) > 1024 )
|
||||
{
|
||||
if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "koth_hill", node.origin, 128 ) == 0 )
|
||||
{
|
||||
if ( findpath( self.origin, node.origin, self, 0, 1 ) )
|
||||
{
|
||||
self addgoal( node, 24, 3, "koth_hill" );
|
||||
self.bot.update_objective = getTime();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.bot.update_lookat = getTime() + randomintrange( 1500, 3000 );
|
||||
}
|
||||
}
|
||||
|
||||
any_other_team_touching( skip_team )
|
||||
{
|
||||
_a194 = level.teams;
|
||||
_k194 = getFirstArrayKey( _a194 );
|
||||
while ( isDefined( _k194 ) )
|
||||
{
|
||||
team = _a194[ _k194 ];
|
||||
if ( team == skip_team )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( level.zone.gameobject.numtouching[ team ] )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
_k194 = getNextArrayKey( _a194, _k194 );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
is_hill_contested( skip_team )
|
||||
{
|
||||
if ( any_other_team_touching( skip_team ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( level.zone.gameobject.curorigin, 1 );
|
||||
if ( isDefined( enemy ) && distancesquared( enemy.origin, level.zone.gameobject.curorigin ) < 262144 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_hill_grenade()
|
||||
{
|
||||
enemies = bot_get_enemies();
|
||||
if ( !enemies.size )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( self atgoal( "hill_patrol" ) || self atgoal( "koth_hill" ) )
|
||||
{
|
||||
if ( self getweaponammostock( "proximity_grenade_mp" ) > 0 )
|
||||
{
|
||||
origin = bot_get_look_at();
|
||||
if ( self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( origin ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !is_hill_contested( self.team ) )
|
||||
{
|
||||
if ( !isDefined( level.next_smoke_time ) )
|
||||
{
|
||||
level.next_smoke_time = 0;
|
||||
}
|
||||
if ( getTime() > level.next_smoke_time )
|
||||
{
|
||||
if ( self maps/mp/bots/_bot_combat::bot_combat_throw_smoke( level.zone.gameobject.curorigin ) )
|
||||
{
|
||||
level.next_smoke_time = getTime() + randomintrange( 60000, 120000 );
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( level.zone.gameobject.curorigin, 0 );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
origin = enemy.origin;
|
||||
}
|
||||
else
|
||||
{
|
||||
origin = level.zone.gameobject.curorigin;
|
||||
}
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = ( 0, dir[ 1 ], 0 );
|
||||
origin += vectorScale( dir, 128 );
|
||||
if ( maps/mp/bots/_bot::bot_get_difficulty() == "easy" )
|
||||
{
|
||||
if ( !isDefined( level.next_grenade_time ) )
|
||||
{
|
||||
level.next_grenade_time = 0;
|
||||
}
|
||||
if ( getTime() > level.next_grenade_time )
|
||||
{
|
||||
if ( !self maps/mp/bots/_bot_combat::bot_combat_throw_lethal( origin ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_tactical( origin );
|
||||
}
|
||||
else
|
||||
{
|
||||
level.next_grenade_time = getTime() + randomintrange( 60000, 120000 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !self maps/mp/bots/_bot_combat::bot_combat_throw_lethal( origin ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_tactical( origin );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_hill_tactical_insertion()
|
||||
{
|
||||
if ( !self hasweapon( "tactical_insertion_mp" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
dist = self getlookaheaddist();
|
||||
dir = self getlookaheaddir();
|
||||
if ( !isDefined( dist ) || !isDefined( dir ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
node = hill_nearest_node();
|
||||
mine = getnearestnode( self.origin );
|
||||
if ( isDefined( mine ) && !nodesvisible( mine, node ) )
|
||||
{
|
||||
origin = self.origin + vectorScale( dir, dist );
|
||||
next = getnearestnode( origin );
|
||||
if ( isDefined( next ) && nodesvisible( next, node ) )
|
||||
{
|
||||
bot_combat_tactical_insertion( self.origin );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hill_nearest_node()
|
||||
{
|
||||
nodes = getnodesinradiussorted( level.zone.gameobject.curorigin, 256, 0 );
|
||||
/#
|
||||
assert( nodes.size );
|
||||
#/
|
||||
return nodes[ 0 ];
|
||||
}
|
609
patch_mp/maps/mp/bots/_bot_loadout.gsc
Normal file
609
patch_mp/maps/mp/bots/_bot_loadout.gsc
Normal file
@ -0,0 +1,609 @@
|
||||
#include maps/mp/gametypes/_rank;
|
||||
#include maps/mp/bots/_bot;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
|
||||
init()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
level.bot_banned_killstreaks = array( "KILLSTREAK_RCBOMB", "KILLSTREAK_QRDRONE", "KILLSTREAK_REMOTE_MISSILE", "KILLSTREAK_REMOTE_MORTAR", "KILLSTREAK_HELICOPTER_GUNNER" );
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
if ( !player istestclient() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
player thread on_bot_connect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
on_bot_connect()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
if ( isDefined( self.pers[ "bot_loadout" ] ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
wait 0,1;
|
||||
if ( ( self getentitynumber() % 2 ) == 0 )
|
||||
{
|
||||
wait 0,05;
|
||||
}
|
||||
self maps/mp/bots/_bot::bot_set_rank();
|
||||
if ( level.onlinegame && !sessionmodeisprivate() )
|
||||
{
|
||||
self botsetdefaultclass( 5, "class_assault" );
|
||||
self botsetdefaultclass( 6, "class_smg" );
|
||||
self botsetdefaultclass( 7, "class_lmg" );
|
||||
self botsetdefaultclass( 8, "class_cqb" );
|
||||
self botsetdefaultclass( 9, "class_sniper" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self botsetdefaultclass( 5, "class_assault" );
|
||||
self botsetdefaultclass( 6, "class_smg" );
|
||||
self botsetdefaultclass( 7, "class_lmg" );
|
||||
self botsetdefaultclass( 8, "class_cqb" );
|
||||
self botsetdefaultclass( 9, "class_sniper" );
|
||||
}
|
||||
max_allocation = 10;
|
||||
i = 1;
|
||||
while ( i <= 3 )
|
||||
{
|
||||
if ( self isitemlocked( maps/mp/gametypes/_rank::getitemindex( "feature_allocation_slot_" + i ) ) )
|
||||
{
|
||||
max_allocation--;
|
||||
|
||||
}
|
||||
i++;
|
||||
}
|
||||
self bot_construct_loadout( max_allocation );
|
||||
self.pers[ "bot_loadout" ] = 1;
|
||||
}
|
||||
|
||||
bot_construct_loadout( allocation_max )
|
||||
{
|
||||
if ( self isitemlocked( maps/mp/gametypes/_rank::getitemindex( "feature_cac" ) ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
pixbeginevent( "bot_construct_loadout" );
|
||||
item_list = bot_build_item_list();
|
||||
bot_construct_class( 0, item_list, allocation_max );
|
||||
bot_construct_class( 1, item_list, allocation_max );
|
||||
bot_construct_class( 2, item_list, allocation_max );
|
||||
bot_construct_class( 3, item_list, allocation_max );
|
||||
bot_construct_class( 4, item_list, allocation_max );
|
||||
killstreaks = item_list[ "killstreak1" ];
|
||||
if ( isDefined( item_list[ "killstreak2" ] ) )
|
||||
{
|
||||
killstreaks = arraycombine( killstreaks, item_list[ "killstreak2" ], 1, 0 );
|
||||
}
|
||||
if ( isDefined( item_list[ "killstreak3" ] ) )
|
||||
{
|
||||
killstreaks = arraycombine( killstreaks, item_list[ "killstreak3" ], 1, 0 );
|
||||
}
|
||||
if ( isDefined( killstreaks ) && killstreaks.size )
|
||||
{
|
||||
bot_choose_weapon( 0, killstreaks );
|
||||
bot_choose_weapon( 0, killstreaks );
|
||||
bot_choose_weapon( 0, killstreaks );
|
||||
}
|
||||
self.claimed_items = undefined;
|
||||
pixendevent();
|
||||
}
|
||||
|
||||
bot_construct_class( class, items, allocation_max )
|
||||
{
|
||||
allocation = 0;
|
||||
claimed_count = bot_build_claimed_list( items );
|
||||
self.claimed_items = [];
|
||||
while ( allocation < allocation_max )
|
||||
{
|
||||
secondary_chance = 40;
|
||||
remaining = allocation_max - allocation;
|
||||
if ( remaining >= 1 && bot_make_choice( 95, claimed_count[ "primary" ], 1 ) )
|
||||
{
|
||||
weapon = bot_choose_weapon( class, items[ "primary" ] );
|
||||
claimed_count[ "primary" ]++;
|
||||
allocation++;
|
||||
bot_choose_weapon_option( class, "camo", 0 );
|
||||
bot_choose_weapon_option( class, "reticle", 0 );
|
||||
allocation += bot_choose_primary_attachments( class, weapon, allocation, allocation_max );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !claimed_count[ "primary" ] )
|
||||
{
|
||||
secondary_chance = 100;
|
||||
}
|
||||
}
|
||||
remaining = allocation_max - allocation;
|
||||
if ( remaining >= 1 && bot_make_choice( secondary_chance, claimed_count[ "secondary" ], 1 ) )
|
||||
{
|
||||
if ( remaining >= 2 && randomint( 100 ) < 10 )
|
||||
{
|
||||
self botclassadditem( class, "BONUSCARD_OVERKILL" );
|
||||
weapon = bot_choose_weapon( class, items[ "primary" ] );
|
||||
allocation++;
|
||||
allocation++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
weapon = bot_choose_weapon( class, items[ "secondary" ] );
|
||||
bot_choose_weapon_option( class, "camo", 1 );
|
||||
}
|
||||
allocation++;
|
||||
claimed_count[ "secondary" ]++;
|
||||
allocation += bot_choose_secondary_attachments( class, weapon, allocation, allocation_max );
|
||||
}
|
||||
perks_chance = 50;
|
||||
lethal_chance = 30;
|
||||
tactical_chance = 20;
|
||||
if ( claimed_count[ "specialty1" ] && claimed_count[ "specialty2" ] && claimed_count[ "specialty3" ] )
|
||||
{
|
||||
perks_chance = 0;
|
||||
}
|
||||
if ( claimed_count[ "primarygrenade" ] )
|
||||
{
|
||||
lethal_chance = 0;
|
||||
}
|
||||
if ( claimed_count[ "specialgrenade" ] )
|
||||
{
|
||||
tactical_chance = 0;
|
||||
}
|
||||
if ( ( perks_chance + lethal_chance + tactical_chance ) <= 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
next_action = bot_chose_action( "perks", perks_chance, "lethal", lethal_chance, "tactical", tactical_chance, "none", 0 );
|
||||
if ( next_action == "perks" )
|
||||
{
|
||||
remaining = allocation_max - allocation;
|
||||
if ( remaining >= 3 && !claimed_count[ "specialty1" ] && randomint( 100 ) < 25 )
|
||||
{
|
||||
self botclassadditem( class, "BONUSCARD_PERK_1_GREED" );
|
||||
bot_choose_weapon( class, items[ "specialty1" ] );
|
||||
bot_choose_weapon( class, items[ "specialty1" ] );
|
||||
claimed_count[ "specialty1" ] = 2;
|
||||
allocation += 3;
|
||||
}
|
||||
remaining = allocation_max - allocation;
|
||||
if ( remaining >= 3 && !claimed_count[ "specialty2" ] && randomint( 100 ) < 25 )
|
||||
{
|
||||
self botclassadditem( class, "BONUSCARD_PERK_2_GREED" );
|
||||
bot_choose_weapon( class, items[ "specialty2" ] );
|
||||
bot_choose_weapon( class, items[ "specialty2" ] );
|
||||
claimed_count[ "specialty2" ] = 2;
|
||||
allocation += 3;
|
||||
}
|
||||
remaining = allocation_max - allocation;
|
||||
if ( remaining >= 3 && !claimed_count[ "specialty3" ] && randomint( 100 ) < 25 )
|
||||
{
|
||||
self botclassadditem( class, "BONUSCARD_PERK_3_GREED" );
|
||||
bot_choose_weapon( class, items[ "specialty3" ] );
|
||||
bot_choose_weapon( class, items[ "specialty3" ] );
|
||||
claimed_count[ "specialty3" ] = 2;
|
||||
allocation += 3;
|
||||
}
|
||||
remaining = allocation_max - allocation;
|
||||
i = 0;
|
||||
while ( i < 3 )
|
||||
{
|
||||
perks = [];
|
||||
remaining = allocation_max - allocation;
|
||||
if ( remaining > 0 )
|
||||
{
|
||||
if ( !claimed_count[ "specialty1" ] )
|
||||
{
|
||||
perks[ perks.size ] = "specialty1";
|
||||
}
|
||||
if ( !claimed_count[ "specialty2" ] )
|
||||
{
|
||||
perks[ perks.size ] = "specialty2";
|
||||
}
|
||||
if ( !claimed_count[ "specialty3" ] )
|
||||
{
|
||||
perks[ perks.size ] = "specialty3";
|
||||
}
|
||||
if ( perks.size )
|
||||
{
|
||||
perk = random( perks );
|
||||
bot_choose_weapon( class, items[ perk ] );
|
||||
claimed_count[ perk ]++;
|
||||
allocation++;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
else i++;
|
||||
}
|
||||
}
|
||||
else if ( next_action == "lethal" )
|
||||
{
|
||||
remaining = allocation_max - allocation;
|
||||
if ( remaining >= 2 && randomint( 100 ) < 50 )
|
||||
{
|
||||
if ( !claimed_count[ "primarygrenade" ] )
|
||||
{
|
||||
bot_choose_weapon( class, items[ "primarygrenade" ] );
|
||||
claimed_count[ "primarygrenade" ]++;
|
||||
allocation++;
|
||||
}
|
||||
self botclassadditem( class, "BONUSCARD_DANGER_CLOSE" );
|
||||
allocation++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( remaining >= 1 && !claimed_count[ "primarygrenade" ] )
|
||||
{
|
||||
bot_choose_weapon( class, items[ "primarygrenade" ] );
|
||||
claimed_count[ "primarygrenade" ]++;
|
||||
allocation++;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if ( next_action == "tactical" )
|
||||
{
|
||||
remaining = allocation_max - allocation;
|
||||
if ( remaining >= 2 && !claimed_count[ "specialgrenade" ] && randomint( 100 ) < 50 )
|
||||
{
|
||||
weapon = bot_choose_weapon( class, items[ "specialgrenade" ] );
|
||||
if ( weapon == "WEAPON_TACTICAL_INSERTION" || weapon == "WEAPON_WILLY_PETE" )
|
||||
{
|
||||
claimed_count[ "specialgrenade" ] = 1;
|
||||
allocation += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
self botclassadditem( class, weapon );
|
||||
claimed_count[ "specialgrenade" ] = 2;
|
||||
allocation += 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( remaining >= 1 && !claimed_count[ "specialgrenade" ] )
|
||||
{
|
||||
bot_choose_weapon( class, items[ "specialgrenade" ] );
|
||||
claimed_count[ "specialgrenade" ]++;
|
||||
allocation++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_make_choice( chance, claimed, max_claim )
|
||||
{
|
||||
if ( claimed < max_claim )
|
||||
{
|
||||
return randomint( 100 ) < chance;
|
||||
}
|
||||
}
|
||||
|
||||
bot_chose_action( action1, chance1, action2, chance2, action3, chance3, action4, chance4 )
|
||||
{
|
||||
chance1 = int( chance1 / 10 );
|
||||
chance2 = int( chance2 / 10 );
|
||||
chance3 = int( chance3 / 10 );
|
||||
chance4 = int( chance4 / 10 );
|
||||
actions = [];
|
||||
i = 0;
|
||||
while ( i < chance1 )
|
||||
{
|
||||
actions[ actions.size ] = action1;
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
while ( i < chance2 )
|
||||
{
|
||||
actions[ actions.size ] = action2;
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
while ( i < chance3 )
|
||||
{
|
||||
actions[ actions.size ] = action3;
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
while ( i < chance4 )
|
||||
{
|
||||
actions[ actions.size ] = action4;
|
||||
i++;
|
||||
}
|
||||
return random( actions );
|
||||
}
|
||||
|
||||
bot_item_is_claimed( item )
|
||||
{
|
||||
_a370 = self.claimed_items;
|
||||
_k370 = getFirstArrayKey( _a370 );
|
||||
while ( isDefined( _k370 ) )
|
||||
{
|
||||
claim = _a370[ _k370 ];
|
||||
if ( claim == item )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
_k370 = getNextArrayKey( _a370, _k370 );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_choose_weapon( class, items )
|
||||
{
|
||||
if ( !isDefined( items ) || !items.size )
|
||||
{
|
||||
return undefined;
|
||||
}
|
||||
start = randomint( items.size );
|
||||
i = 0;
|
||||
while ( i < items.size )
|
||||
{
|
||||
weapon = items[ start ];
|
||||
if ( !bot_item_is_claimed( weapon ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
start = ( start + 1 ) % items.size;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
self.claimed_items[ self.claimed_items.size ] = weapon;
|
||||
self botclassadditem( class, weapon );
|
||||
return weapon;
|
||||
}
|
||||
|
||||
bot_build_weapon_options_list( optiontype )
|
||||
{
|
||||
level.botweaponoptionsid[ optiontype ] = [];
|
||||
level.botweaponoptionsprob[ optiontype ] = [];
|
||||
prob = 0;
|
||||
row = 0;
|
||||
while ( row < 255 )
|
||||
{
|
||||
if ( tablelookupcolumnforrow( "mp/attachmentTable.csv", row, 1 ) == optiontype )
|
||||
{
|
||||
index = level.botweaponoptionsid[ optiontype ].size;
|
||||
level.botweaponoptionsid[ optiontype ][ index ] = int( tablelookupcolumnforrow( "mp/attachmentTable.csv", row, 0 ) );
|
||||
prob += int( tablelookupcolumnforrow( "mp/attachmentTable.csv", row, 15 ) );
|
||||
level.botweaponoptionsprob[ optiontype ][ index ] = prob;
|
||||
}
|
||||
row++;
|
||||
}
|
||||
}
|
||||
|
||||
bot_choose_weapon_option( class, optiontype, primary )
|
||||
{
|
||||
if ( !isDefined( level.botweaponoptionsid ) )
|
||||
{
|
||||
level.botweaponoptionsid = [];
|
||||
level.botweaponoptionsprob = [];
|
||||
bot_build_weapon_options_list( "camo" );
|
||||
bot_build_weapon_options_list( "reticle" );
|
||||
}
|
||||
if ( !level.onlinegame && !level.systemlink )
|
||||
{
|
||||
return;
|
||||
}
|
||||
numoptions = level.botweaponoptionsprob[ optiontype ].size;
|
||||
maxprob = level.botweaponoptionsprob[ optiontype ][ numoptions - 1 ];
|
||||
if ( !level.systemlink && self.pers[ "rank" ] < 20 )
|
||||
{
|
||||
maxprob += ( 4 * maxprob ) * ( ( 20 - self.pers[ "rank" ] ) / 20 );
|
||||
}
|
||||
rnd = randomint( int( maxprob ) );
|
||||
i = 0;
|
||||
while ( i < numoptions )
|
||||
{
|
||||
if ( level.botweaponoptionsprob[ optiontype ][ i ] > rnd )
|
||||
{
|
||||
self botclasssetweaponoption( class, primary, optiontype, level.botweaponoptionsid[ optiontype ][ i ] );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_choose_primary_attachments( class, weapon, allocation, allocation_max )
|
||||
{
|
||||
attachments = getweaponattachments( weapon );
|
||||
remaining = allocation_max - allocation;
|
||||
if ( !attachments.size || !remaining )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
attachment_action = bot_chose_action( "3_attachments", 25, "2_attachments", 35, "1_attachments", 35, "none", 5 );
|
||||
if ( remaining >= 4 && attachment_action == "3_attachments" )
|
||||
{
|
||||
a1 = random( attachments );
|
||||
self botclassaddattachment( class, weapon, a1, "primaryattachment1" );
|
||||
count = 1;
|
||||
attachments = getweaponattachments( weapon, a1 );
|
||||
if ( attachments.size )
|
||||
{
|
||||
a2 = random( attachments );
|
||||
self botclassaddattachment( class, weapon, a2, "primaryattachment2" );
|
||||
count++;
|
||||
attachments = getweaponattachments( weapon, a1, a2 );
|
||||
if ( attachments.size )
|
||||
{
|
||||
a3 = random( attachments );
|
||||
self botclassadditem( class, "BONUSCARD_PRIMARY_GUNFIGHTER" );
|
||||
self botclassaddattachment( class, weapon, a3, "primaryattachment3" );
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( remaining >= 2 && attachment_action == "2_attachments" )
|
||||
{
|
||||
a1 = random( attachments );
|
||||
self botclassaddattachment( class, weapon, a1, "primaryattachment1" );
|
||||
attachments = getweaponattachments( weapon, a1 );
|
||||
if ( attachments.size )
|
||||
{
|
||||
a2 = random( attachments );
|
||||
self botclassaddattachment( class, weapon, a2, "primaryattachment2" );
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( remaining >= 1 && attachment_action == "1_attachments" )
|
||||
{
|
||||
a = random( attachments );
|
||||
self botclassaddattachment( class, weapon, a, "primaryattachment1" );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_choose_secondary_attachments( class, weapon, allocation, allocation_max )
|
||||
{
|
||||
attachments = getweaponattachments( weapon );
|
||||
remaining = allocation_max - allocation;
|
||||
if ( !attachments.size || !remaining )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
attachment_action = bot_chose_action( "2_attachments", 10, "1_attachments", 40, "none", 50, "none", 0 );
|
||||
if ( remaining >= 3 && attachment_action == "2_attachments" )
|
||||
{
|
||||
a1 = random( attachments );
|
||||
self botclassaddattachment( class, weapon, a1, "secondaryattachment1" );
|
||||
attachments = getweaponattachments( weapon, a1 );
|
||||
if ( attachments.size )
|
||||
{
|
||||
a2 = random( attachments );
|
||||
self botclassadditem( class, "BONUSCARD_SECONDARY_GUNFIGHTER" );
|
||||
self botclassaddattachment( class, weapon, a2, "secondaryattachment2" );
|
||||
return 3;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( remaining >= 1 && attachment_action == "1_attachments" )
|
||||
{
|
||||
a = random( attachments );
|
||||
self botclassaddattachment( class, weapon, a, "secondaryattachment1" );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_build_item_list()
|
||||
{
|
||||
pixbeginevent( "bot_build_item_list" );
|
||||
items = [];
|
||||
i = 0;
|
||||
while ( i < 256 )
|
||||
{
|
||||
row = tablelookuprownum( level.statstableid, 0, i );
|
||||
if ( row > -1 )
|
||||
{
|
||||
slot = tablelookupcolumnforrow( level.statstableid, row, 13 );
|
||||
if ( slot == "" )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else number = int( tablelookupcolumnforrow( level.statstableid, row, 0 ) );
|
||||
if ( self isitemlocked( number ) )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else allocation = int( tablelookupcolumnforrow( level.statstableid, row, 12 ) );
|
||||
if ( allocation < 0 )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else name = tablelookupcolumnforrow( level.statstableid, row, 3 );
|
||||
if ( bot_item_is_banned( slot, name ) )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !isDefined( items[ slot ] ) )
|
||||
{
|
||||
items[ slot ] = [];
|
||||
}
|
||||
items[ slot ][ items[ slot ].size ] = name;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
pixendevent();
|
||||
return items;
|
||||
}
|
||||
|
||||
bot_item_is_banned( slot, item )
|
||||
{
|
||||
if ( item == "WEAPON_KNIFE_BALLISTIC" )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if ( getDvarInt( #"97A055DA" ) == 0 && item == "WEAPON_PEACEKEEPER" )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if ( slot != "killstreak1" && slot != "killstreak2" && slot != "killstreak3" )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
_a633 = level.bot_banned_killstreaks;
|
||||
_k633 = getFirstArrayKey( _a633 );
|
||||
while ( isDefined( _k633 ) )
|
||||
{
|
||||
banned = _a633[ _k633 ];
|
||||
if ( item == banned )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
_k633 = getNextArrayKey( _a633, _k633 );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_build_claimed_list( items )
|
||||
{
|
||||
claimed = [];
|
||||
keys = getarraykeys( items );
|
||||
_a649 = keys;
|
||||
_k649 = getFirstArrayKey( _a649 );
|
||||
while ( isDefined( _k649 ) )
|
||||
{
|
||||
key = _a649[ _k649 ];
|
||||
claimed[ key ] = 0;
|
||||
_k649 = getNextArrayKey( _a649, _k649 );
|
||||
}
|
||||
return claimed;
|
||||
}
|
466
patch_mp/maps/mp/bots/_bot_sd.gsc
Normal file
466
patch_mp/maps/mp/bots/_bot_sd.gsc
Normal file
@ -0,0 +1,466 @@
|
||||
#include maps/mp/gametypes/_globallogic_utils;
|
||||
#include maps/mp/bots/_bot_combat;
|
||||
#include maps/mp/gametypes/_gameobjects;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
|
||||
bot_sd_think()
|
||||
{
|
||||
_a8 = level.bombzones;
|
||||
_k8 = getFirstArrayKey( _a8 );
|
||||
while ( isDefined( _k8 ) )
|
||||
{
|
||||
zone = _a8[ _k8 ];
|
||||
if ( !isDefined( zone.nearest_node ) )
|
||||
{
|
||||
nodes = getnodesinradiussorted( zone.trigger.origin, 256, 0 );
|
||||
/#
|
||||
assert( nodes.size );
|
||||
#/
|
||||
zone.nearest_node = nodes[ 0 ];
|
||||
}
|
||||
_k8 = getNextArrayKey( _a8, _k8 );
|
||||
}
|
||||
zone = sd_get_planted_zone();
|
||||
if ( isDefined( zone ) )
|
||||
{
|
||||
self bot_sd_defender( zone, 1 );
|
||||
}
|
||||
else if ( self.team == game[ "attackers" ] )
|
||||
{
|
||||
if ( level.multibomb )
|
||||
{
|
||||
self.isbombcarrier = 1;
|
||||
}
|
||||
self bot_sd_attacker();
|
||||
}
|
||||
else
|
||||
{
|
||||
zone = random( level.bombzones );
|
||||
self bot_sd_defender( zone );
|
||||
}
|
||||
}
|
||||
|
||||
bot_sd_attacker()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
if ( !level.multibomb && !isDefined( level.sdbomb.carrier ) && !level.bombplanted )
|
||||
{
|
||||
self cancelgoal( "sd_protect_carrier" );
|
||||
if ( !level.sdbomb maps/mp/gametypes/_gameobjects::isobjectawayfromhome() )
|
||||
{
|
||||
if ( !self maps/mp/bots/_bot::bot_friend_goal_in_radius( "sd_pickup", level.sdbomb.curorigin, 64 ) )
|
||||
{
|
||||
self addgoal( level.sdbomb.curorigin, 16, 4, "sd_pickup" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self addgoal( level.sdbomb.curorigin, 16, 4, "sd_pickup" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self cancelgoal( "sd_pickup" );
|
||||
}
|
||||
if ( is_true( self.isbombcarrier ) )
|
||||
{
|
||||
goal = self getgoal( "sd_plant" );
|
||||
if ( isDefined( goal ) )
|
||||
{
|
||||
if ( distancesquared( self.origin, goal ) < 2304 )
|
||||
{
|
||||
self setstance( "prone" );
|
||||
wait 0,5;
|
||||
self pressusebutton( level.planttime + 1 );
|
||||
wait 0,5;
|
||||
if ( is_true( self.isplanting ) )
|
||||
{
|
||||
wait ( level.planttime + 1 );
|
||||
}
|
||||
self pressusebutton( 0 );
|
||||
self setstance( "crouch" );
|
||||
wait 0,25;
|
||||
self cancelgoal( "sd_plant" );
|
||||
self setstance( "stand" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( getTime() > self.bot[ "patrol_update" ] )
|
||||
{
|
||||
frac = sd_get_time_frac();
|
||||
if ( randomint( 100 ) < ( frac * 100 ) || frac > 0,85 )
|
||||
{
|
||||
zone = sd_get_closest_bomb();
|
||||
goal = sd_get_bomb_goal( zone.visuals[ 0 ] );
|
||||
if ( isDefined( goal ) )
|
||||
{
|
||||
if ( frac > 0,85 )
|
||||
{
|
||||
self addgoal( goal, 24, 4, "sd_plant" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self addgoal( goal, 24, 3, "sd_plant" );
|
||||
}
|
||||
}
|
||||
}
|
||||
self.bot[ "patrol_update" ] = getTime() + randomintrange( 2500, 5000 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isDefined( level.sdbomb.carrier ) && !isplayer( level.sdbomb.carrier ) )
|
||||
{
|
||||
if ( !isDefined( self.protectcarrier ) )
|
||||
{
|
||||
if ( randomint( 100 ) > 70 )
|
||||
{
|
||||
self.protectcarrier = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.protectcarrier = 0;
|
||||
}
|
||||
}
|
||||
if ( self.protectcarrier )
|
||||
{
|
||||
goal = level.sdbomb.carrier getgoal( "sd_plant" );
|
||||
if ( isDefined( goal ) )
|
||||
{
|
||||
nodes = getnodesinradiussorted( goal, 256, 0 );
|
||||
if ( isDefined( nodes ) && nodes.size > 0 && !isDefined( self getgoal( "sd_protect_carrier" ) ) )
|
||||
{
|
||||
self addgoal( nodes[ randomint( nodes.size ) ], 24, 3, "sd_protect_carrier" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_sd_defender( zone, isplanted )
|
||||
{
|
||||
bot_sd_grenade();
|
||||
while ( isDefined( isplanted ) && isplanted && self hasgoal( "sd_defend" ) )
|
||||
{
|
||||
goal = self getgoal( "sd_defend" );
|
||||
planted = sd_get_planted_zone();
|
||||
_a159 = level.bombzones;
|
||||
_k159 = getFirstArrayKey( _a159 );
|
||||
while ( isDefined( _k159 ) )
|
||||
{
|
||||
zone = _a159[ _k159 ];
|
||||
if ( planted != zone && distance2d( goal, zone.nearest_node.origin ) < distance2d( goal, planted.nearest_node.origin ) )
|
||||
{
|
||||
self cancelgoal( "sd_defend" );
|
||||
}
|
||||
_k159 = getNextArrayKey( _a159, _k159 );
|
||||
}
|
||||
}
|
||||
if ( self atgoal( "sd_defend" ) || self bot_need_to_defuse() )
|
||||
{
|
||||
bot_sd_defender_think( zone );
|
||||
if ( self hasgoal( "sd_defend" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ( self hasgoal( "enemy_patrol" ) )
|
||||
{
|
||||
goal = self getgoal( "enemy_patrol" );
|
||||
closezone = sd_get_closest_bomb();
|
||||
if ( distancesquared( goal, closezone.nearest_node.origin ) < 262144 )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "sd_defend" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ( self hasgoal( "sd_defend" ) )
|
||||
{
|
||||
self.bot[ "patrol_update" ] = getTime() + randomintrange( 2500, 5000 );
|
||||
return;
|
||||
}
|
||||
if ( self hasgoal( "enemy_patrol" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
nodes = getvisiblenodes( zone.nearest_node );
|
||||
best = undefined;
|
||||
highest = -100;
|
||||
_a208 = nodes;
|
||||
_k208 = getFirstArrayKey( _a208 );
|
||||
while ( isDefined( _k208 ) )
|
||||
{
|
||||
node = _a208[ _k208 ];
|
||||
if ( node.type == "BAD NODE" )
|
||||
{
|
||||
}
|
||||
else if ( !canclaimnode( node, self.team ) )
|
||||
{
|
||||
}
|
||||
else if ( distancesquared( node.origin, self.origin ) < 65536 )
|
||||
{
|
||||
}
|
||||
else if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "sd_defend", node.origin, 256 ) > 0 )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
height = node.origin[ 2 ] - zone.nearest_node.origin[ 2 ];
|
||||
if ( isDefined( isplanted ) && isplanted )
|
||||
{
|
||||
dist = distance2d( node.origin, zone.nearest_node.origin );
|
||||
score = ( 10000 - dist ) + height;
|
||||
}
|
||||
else
|
||||
{
|
||||
score = height;
|
||||
}
|
||||
if ( score > highest )
|
||||
{
|
||||
highest = score;
|
||||
best = node;
|
||||
}
|
||||
}
|
||||
_k208 = getNextArrayKey( _a208, _k208 );
|
||||
}
|
||||
if ( !isDefined( best ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self addgoal( best, 24, 3, "sd_defend" );
|
||||
}
|
||||
|
||||
bot_get_look_at()
|
||||
{
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( self.origin, 1 );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
}
|
||||
enemies = self maps/mp/bots/_bot::bot_get_enemies( 0 );
|
||||
if ( enemies.size )
|
||||
{
|
||||
enemy = random( enemies );
|
||||
}
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
}
|
||||
zone = sd_get_closest_bomb();
|
||||
node = getvisiblenode( self.origin, zone.nearest_node.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
forward = anglesToForward( self getplayerangles() );
|
||||
origin = self geteye() + ( forward * 1024 );
|
||||
return origin;
|
||||
}
|
||||
|
||||
bot_sd_defender_think( zone )
|
||||
{
|
||||
if ( self bot_need_to_defuse() )
|
||||
{
|
||||
if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "sd_defuse", level.sdbombmodel.origin, 16 ) > 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self clearlookat();
|
||||
goal = self getgoal( "sd_defuse" );
|
||||
if ( isDefined( goal ) && distancesquared( self.origin, goal ) < 2304 )
|
||||
{
|
||||
self setstance( "prone" );
|
||||
wait 0,5;
|
||||
self pressusebutton( level.defusetime + 1 );
|
||||
wait 0,5;
|
||||
if ( is_true( self.isdefusing ) )
|
||||
{
|
||||
wait ( level.defusetime + 1 );
|
||||
}
|
||||
self pressusebutton( 0 );
|
||||
self setstance( "crouch" );
|
||||
wait 0,25;
|
||||
self cancelgoal( "sd_defuse" );
|
||||
self setstance( "stand" );
|
||||
return;
|
||||
}
|
||||
if ( !isDefined( goal ) && distance2dsquared( self.origin, level.sdbombmodel.origin ) < 1000000 )
|
||||
{
|
||||
self addgoal( level.sdbombmodel.origin, 24, 4, "sd_defuse" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ( getTime() > self.bot[ "patrol_update" ] )
|
||||
{
|
||||
if ( cointoss() )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "sd_defend" );
|
||||
return;
|
||||
}
|
||||
self.bot[ "patrol_update" ] = getTime() + randomintrange( 2500, 5000 );
|
||||
}
|
||||
if ( self hasgoal( "enemy_patrol" ) )
|
||||
{
|
||||
goal = self getgoal( "enemy_patrol" );
|
||||
zone = sd_get_closest_bomb();
|
||||
if ( distancesquared( goal, zone.nearest_node.origin ) < 262144 )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "sd_defend" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ( getTime() > self.bot[ "lookat_update" ] )
|
||||
{
|
||||
origin = self bot_get_look_at();
|
||||
z = 20;
|
||||
if ( distancesquared( origin, self.origin ) > 262144 )
|
||||
{
|
||||
z = randomintrange( 16, 60 );
|
||||
}
|
||||
self lookat( origin + ( 0, 0, z ) );
|
||||
self.bot[ "lookat_update" ] = getTime() + randomintrange( 1500, 3000 );
|
||||
if ( distancesquared( origin, self.origin ) > 65536 )
|
||||
{
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = vectorScale( dir, 256 );
|
||||
origin += dir;
|
||||
}
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( origin );
|
||||
}
|
||||
}
|
||||
|
||||
bot_need_to_defuse()
|
||||
{
|
||||
if ( level.bombplanted )
|
||||
{
|
||||
return self.team == game[ "defenders" ];
|
||||
}
|
||||
}
|
||||
|
||||
sd_get_bomb_goal( ent )
|
||||
{
|
||||
goals = [];
|
||||
dir = anglesToForward( ent.angles );
|
||||
dir = vectorScale( dir, 32 );
|
||||
goals[ 0 ] = ent.origin + dir;
|
||||
goals[ 1 ] = ent.origin - dir;
|
||||
dir = anglesToRight( ent.angles );
|
||||
dir = vectorScale( dir, 48 );
|
||||
goals[ 2 ] = ent.origin + dir;
|
||||
goals[ 3 ] = ent.origin - dir;
|
||||
goals = array_randomize( goals );
|
||||
_a419 = goals;
|
||||
_k419 = getFirstArrayKey( _a419 );
|
||||
while ( isDefined( _k419 ) )
|
||||
{
|
||||
goal = _a419[ _k419 ];
|
||||
if ( findpath( self.origin, goal, 0 ) )
|
||||
{
|
||||
return goal;
|
||||
}
|
||||
_k419 = getNextArrayKey( _a419, _k419 );
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
sd_get_time_frac()
|
||||
{
|
||||
remaining = maps/mp/gametypes/_globallogic_utils::gettimeremaining();
|
||||
end = ( level.timelimit * 60 ) * 1000;
|
||||
if ( end == 0 )
|
||||
{
|
||||
end = self.spawntime + 120000;
|
||||
remaining = end - getTime();
|
||||
}
|
||||
return 1 - ( remaining / end );
|
||||
}
|
||||
|
||||
sd_get_closest_bomb()
|
||||
{
|
||||
best = undefined;
|
||||
distsq = 9999999;
|
||||
_a450 = level.bombzones;
|
||||
_k450 = getFirstArrayKey( _a450 );
|
||||
while ( isDefined( _k450 ) )
|
||||
{
|
||||
zone = _a450[ _k450 ];
|
||||
d = distancesquared( self.origin, zone.curorigin );
|
||||
if ( !isDefined( best ) )
|
||||
{
|
||||
best = zone;
|
||||
distsq = d;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( d < distsq )
|
||||
{
|
||||
best = zone;
|
||||
distsq = d;
|
||||
}
|
||||
}
|
||||
_k450 = getNextArrayKey( _a450, _k450 );
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
sd_get_planted_zone()
|
||||
{
|
||||
while ( level.bombplanted )
|
||||
{
|
||||
_a475 = level.bombzones;
|
||||
_k475 = getFirstArrayKey( _a475 );
|
||||
while ( isDefined( _k475 ) )
|
||||
{
|
||||
zone = _a475[ _k475 ];
|
||||
if ( zone.interactteam == "none" )
|
||||
{
|
||||
return zone;
|
||||
}
|
||||
_k475 = getNextArrayKey( _a475, _k475 );
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
bot_sd_grenade()
|
||||
{
|
||||
enemies = bot_get_enemies();
|
||||
if ( !enemies.size )
|
||||
{
|
||||
return;
|
||||
}
|
||||
zone = sd_get_closest_bomb();
|
||||
_a498 = enemies;
|
||||
_k498 = getFirstArrayKey( _a498 );
|
||||
while ( isDefined( _k498 ) )
|
||||
{
|
||||
enemy = _a498[ _k498 ];
|
||||
if ( distancesquared( enemy.origin, zone.nearest_node.origin ) < 147456 )
|
||||
{
|
||||
if ( !self maps/mp/bots/_bot_combat::bot_combat_throw_lethal( enemy.origin ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_tactical( enemy.origin );
|
||||
}
|
||||
return;
|
||||
}
|
||||
_k498 = getNextArrayKey( _a498, _k498 );
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user