mirror of
https://github.com/JezuzLizard/t4sp_bot_warfare.git
synced 2025-07-07 11:41:49 +00:00
Compare commits
13 Commits
7acc701c04
...
experiment
Author | SHA1 | Date | |
---|---|---|---|
23a64c5e1c | |||
1990b8c79d | |||
558805de77 | |||
bdf933b907 | |||
a6ce1e1923 | |||
a230151228 | |||
ae7cfb991a | |||
872630b7e2 | |||
c23fd0fd2d | |||
f75726147c | |||
31c885a396 | |||
7614efcec3 | |||
7d01471760 |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
219
scripts/sp/bots/actions/combat.gsc
Normal file
219
scripts/sp/bots/actions/combat.gsc
Normal file
@ -0,0 +1,219 @@
|
||||
bot_shoot()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_shoot_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_shoot()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_check_complete_shoot()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_shoot()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_shoot_on_completion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_shoot_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_shoot_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_shoot_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_shoot_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_shoot_priority()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_reload()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_reload_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_reload()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_check_complete_reload()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_reload()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_reload_on_completion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_reload_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_reload_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_reload_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_reload_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_reload_priority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_frag()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_frag_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_frag()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_check_complete_frag()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_frag()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_frag_on_completion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_frag_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_frag_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_frag_should_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_frag_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_frag_priority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_tactical()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_tactical_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_tactical()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_check_complete_tactical()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_tactical()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_tactical_on_completion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_tactical_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_tactical_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_tactical_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_tactical_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_tactical_priority()
|
||||
{
|
||||
return 0;
|
||||
}
|
224
scripts/sp/bots/actions/look.gsc
Normal file
224
scripts/sp/bots/actions/look.gsc
Normal file
@ -0,0 +1,224 @@
|
||||
#include scripts\sp\bots\bot_target_common;
|
||||
|
||||
bot_lookatobjective()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_lookatobjective_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_lookatobjective()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_check_complete_lookatobjective()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_lookatobjective()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_lookatobjective_on_completion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_lookatobjective_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_lookatobjective_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_lookatobjective_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_lookatobjective_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_lookatobjective_priority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_lookattarget()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
while ( self bot_has_target() && isAlive( self.zbot_current_target.target_ent ) )
|
||||
{
|
||||
target = self.zbot_current_target;
|
||||
target_ent = target.target_ent;
|
||||
self bot_lookat( target_ent getTagOrigin( "j_head" ) );
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
bot_lookattarget_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_lookattarget()
|
||||
{
|
||||
return self bot_has_target();
|
||||
}
|
||||
|
||||
bot_check_complete_lookattarget()
|
||||
{
|
||||
return !self bot_has_target();
|
||||
}
|
||||
|
||||
bot_set_complete_lookattarget()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_lookattarget_on_completion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_lookattarget_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_lookattarget_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_lookattarget_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_lookattarget_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_lookattarget_priority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_lookatgoal()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_lookatgoal_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_lookatgoal()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_check_complete_lookatgoal()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_lookatgoal()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_lookatgoal_on_completion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_lookatgoal_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_lookatgoal_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_lookatgoal_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_lookatgoal_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_lookatgoal_priority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_lookat( pos, time, vel, doAimPredict )
|
||||
{
|
||||
self notify( "bots_aim_overlap" );
|
||||
self endon( "bots_aim_overlap" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "player_downed" );
|
||||
level endon( "end_game" );
|
||||
|
||||
if ( !isDefined( pos ) )
|
||||
return;
|
||||
|
||||
if ( !isDefined( doAimPredict ) )
|
||||
doAimPredict = false;
|
||||
|
||||
if ( !isDefined( time ) )
|
||||
time = 0.05;
|
||||
|
||||
if ( !isDefined( vel ) )
|
||||
vel = ( 0, 0, 0 );
|
||||
|
||||
steps = int( time * 20 );
|
||||
|
||||
if ( steps < 1 )
|
||||
steps = 1;
|
||||
|
||||
myEye = self scripts\sp\bots\_bot_utility::GetEyePos(); // get our eye pos
|
||||
|
||||
if ( doAimPredict )
|
||||
{
|
||||
myEye += ( self getVelocity() * 0.05 ) * ( steps - 1 ); // account for our velocity
|
||||
|
||||
pos += ( vel * 0.05 ) * ( steps - 1 ); // add the velocity vector
|
||||
}
|
||||
|
||||
myAngle = self getPlayerAngles();
|
||||
angles = VectorToAngles( ( pos - myEye ) - anglesToForward( myAngle ) );
|
||||
|
||||
X = AngleClamp180( angles[0] - myAngle[0] );
|
||||
X = X / steps;
|
||||
|
||||
Y = AngleClamp180( angles[1] - myAngle[1] );
|
||||
Y = Y / steps;
|
||||
|
||||
for ( i = 0; i < steps; i++ )
|
||||
{
|
||||
myAngle = ( AngleClamp180(myAngle[0] + X), AngleClamp180(myAngle[1] + Y), 0 );
|
||||
self setPlayerAngles( myAngle );
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
240
scripts/sp/bots/actions/movement.gsc
Normal file
240
scripts/sp/bots/actions/movement.gsc
Normal file
@ -0,0 +1,240 @@
|
||||
bot_movetoobjective()
|
||||
{
|
||||
action_id = self.action_queue[ "objective" ][ 0 ].action_id;
|
||||
at_obj_distance_sq = 48 * 48;
|
||||
while ( isDefined( self.action_queue[ "objective" ][ 0 ] ) && action_id == self.action_queue[ "objective" ][ 0 ].action_id )
|
||||
{
|
||||
if ( distanceSquared( self.origin, self.target_pos ) < at_obj_distance_sq )
|
||||
{
|
||||
self bot_set_complete_movetoobjective();
|
||||
break;
|
||||
}
|
||||
wait 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
bot_movetoobjective_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_movetoobjective()
|
||||
{
|
||||
if ( isDefined( self.action_queue[ "objective" ][ 0 ] ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_check_complete_movetoobjective()
|
||||
{
|
||||
return self.successfully_moved_to_objective;
|
||||
}
|
||||
|
||||
bot_set_complete_movetoobjective()
|
||||
{
|
||||
self.successfully_moved_to_objective = true;
|
||||
}
|
||||
|
||||
bot_movetoobjective_on_completion()
|
||||
{
|
||||
self.successfully_moved_to_objective = false;
|
||||
self.can_do_objective_now = true;
|
||||
}
|
||||
|
||||
bot_movetoobjective_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_movetoobjective_on_cancel()
|
||||
{
|
||||
self.successfully_moved_to_objective = false;
|
||||
self.can_do_objective_now = false;
|
||||
}
|
||||
|
||||
bot_movetoobjective_should_postpone()
|
||||
{
|
||||
if ( self bot_should_flee() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_movetoobjective_on_postpone()
|
||||
{
|
||||
self.successfully_moved_to_objective = false;
|
||||
self.can_do_objective_now = false;
|
||||
}
|
||||
|
||||
bot_movetoobjective_priority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_train()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_train_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_train()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_check_complete_train()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_train()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_train_on_completion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_train_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_train_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_train_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_train_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_train_priority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_camp()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_camp_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_camp()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_check_complete_camp()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_camp()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_camp_on_completion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_camp_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_camp_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_camp_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_camp_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_camp_priority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_flee()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_flee_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_flee()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_check_complete_flee()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_flee()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_flee_on_completion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_flee_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_flee_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_flee_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_flee_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_flee_priority()
|
||||
{
|
||||
return 0;
|
||||
}
|
867
scripts/sp/bots/actions/objective.gsc
Normal file
867
scripts/sp/bots/actions/objective.gsc
Normal file
@ -0,0 +1,867 @@
|
||||
#include scripts\sp\bots\bot_objective_common;
|
||||
|
||||
bot_magicbox_purchase()
|
||||
{
|
||||
self.target_pos = self.available_chests[ 0 ].origin;
|
||||
}
|
||||
|
||||
bot_magicbox_process_order()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_should_purchase_magicbox()
|
||||
{
|
||||
if ( !level.enable_magic )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ( level.chests.size <= 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
self.available_chests = [];
|
||||
for ( i = 0; i < level.chests.size; i++ )
|
||||
{
|
||||
if ( level.chests[ i ].hidden )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( self.score < level.chests[ i ].zombie_cost )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
self.available_chests[ self.available_chests.size ] = level.chests[ i ];
|
||||
}
|
||||
if ( self.available_chests.size > 0 )
|
||||
{
|
||||
for ( i = 0; i < self.available_chests.size; i++ )
|
||||
{
|
||||
if ( isDefined( self.available_chests[ i ].chest_user ) )
|
||||
{
|
||||
maps\_utility::array_remove_index( self.available_chests, i );
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
return self.available_chests.size > 0;
|
||||
}
|
||||
|
||||
bot_check_complete_magicbox()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_magicbox()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_magicbox_purchase_on_completion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_magicbox_purchase_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_magicbox_purchase_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_magicbox_purchase_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_magicbox_purchase_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_magicbox_purchase_priority()
|
||||
{
|
||||
priority = 0;
|
||||
LOW_AMMO_THRESHOLD = 0.3;
|
||||
weapons = self getWeaponsListPrimaries();
|
||||
if ( weapons.size < 2 )
|
||||
{
|
||||
priority += 1;
|
||||
}
|
||||
for ( j = 0; j < weapons.size; j++ )
|
||||
{
|
||||
if ( self getWeaponAmmoStock( weapons[ j ] ) <= int( weaponmaxammo( weapons[ j ] ) * LOW_AMMO_THRESHOLD ) )
|
||||
{
|
||||
priority += 1;
|
||||
}
|
||||
}
|
||||
return priority;
|
||||
}
|
||||
|
||||
bot_wallbuy_purchase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_wallbuy_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_purchase_wallbuy()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_check_complete_wallbuy()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_wallbuy()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_wallbuy_purchase_on_completion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_wallbuy_purchase_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_wallbuy_purchase_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_wallbuy_purchase_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_wallbuy_purchase_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_wallbuy_purchase_priority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_wallbuy_ammo_purchase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_wallbuyammo_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_purchase_wallbuy_ammo()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_check_complete_wallbuy_ammo()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_wallbuy_ammo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_wallbuy_ammo_purchase_on_completion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_wallbuy_ammo_purchase_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_wallbuy_ammo_purchase_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_wallbuy_ammo_purchase_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_wallbuy_ammo_purchase_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_wallbuy_ammo_purchase_priority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_perk_purchase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_perk_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_purchase_perk()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_check_complete_perk_purchase()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_perk_purchase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_perk_purchase_on_completion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_perk_purchase_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_perk_purchase_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_perk_purchase_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_perk_purchase_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_perk_purchase_priority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_door_purchase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_door_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_purchase_door()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_check_complete_door_purchase()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_door_purchase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_door_purchase_on_completion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_door_purchase_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_door_purchase_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_door_purchase_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_door_purchase_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_door_purchase_priority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_debris_purchase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_debris_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_purchase_debris()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_check_complete_debris_purchase()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_debris_purchase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_debris_purchase_on_completion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_debris_purchase_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_debris_purchase_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_debris_purchase_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_debris_purchase_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_debris_purchase_priority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_trap_purchase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_trap_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_purchase_trap()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_check_complete_trap_purchase()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_trap_purchase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_trap_purchase_on_completion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_trap_purchase_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_trap_purchase_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_trap_purchase_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_trap_purchase_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_trap_purchase_priority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_packapunch_purchase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_packapunch_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_purchase_packapunch()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_check_complete_packapunch_purchase()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_packapunch_purchase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_packapunch_purchase_on_completion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_packapunch_purchase_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_packapunch_purchase_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_packapunch_purchase_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_packapunch_purchase_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_packapunch_purchase_priority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_revive_player()
|
||||
{
|
||||
if ( !isDefined( self.available_revives ) || self.available_revives.size <= 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self endon( "disconnect" );
|
||||
level endon( "end_game" );
|
||||
|
||||
player_to_revive_obj = self.available_revives[ 0 ];
|
||||
|
||||
set_bot_global_shared_objective_owner_by_reference( "revive", player_to_revive_obj, self );
|
||||
|
||||
player_to_revive = player_to_revive_obj.target_ent;
|
||||
|
||||
action_id = self.action_queue[ "objective" ][ 0 ].action_id;
|
||||
|
||||
//If player is no longer valid to revive stop trying to revive
|
||||
//If bot doesn't have an objective anymore or the objective has changed stop trying to revive
|
||||
while ( isDefined( player_to_revive ) && isDefined( player_to_revive_obj ) && isDefined( self.action_queue[ "objective" ][ 0 ] ) && action_id == self.action_queue[ "objective" ][ 0 ].action_id )
|
||||
{
|
||||
self.target_pos = player_to_revive.origin;
|
||||
|
||||
if ( self.can_do_objective_now )
|
||||
{
|
||||
//TODO: Add check to see if another player is reviving target player
|
||||
//TODO: Add code to revive player, possibly add the ability to circle revive?
|
||||
}
|
||||
wait 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
bot_revive_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_revive_player()
|
||||
{
|
||||
downed_players_objs = get_all_objectives_for_group( "revive" );
|
||||
if ( downed_players_objs.size <= 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
self.available_revives = [];
|
||||
|
||||
obj_keys = getArrayKeys( downed_players_objs );
|
||||
for ( i = 0; i < downed_players_objs.size; i++ )
|
||||
{
|
||||
if ( isDefined( downed_players_objs[ obj_keys[ i ] ].owner ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
self.available_revives[ self.available_revives.size ] = downed_players_objs[ obj_keys[ i ] ];
|
||||
}
|
||||
return self.available_revives.size > 0;
|
||||
}
|
||||
|
||||
bot_check_complete_revive_player()
|
||||
{
|
||||
if ( self.successfully_revived_player )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_revive_player()
|
||||
{
|
||||
self.successfully_revived_player = true;
|
||||
}
|
||||
|
||||
bot_revive_player_on_completion()
|
||||
{
|
||||
self.successfully_revived_player = false;
|
||||
}
|
||||
|
||||
bot_revive_player_should_cancel()
|
||||
{
|
||||
return !isDefined( self.available_revives[ 0 ].target_ent.revivetrigger );
|
||||
}
|
||||
|
||||
bot_revive_player_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_revive_player_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_revive_player_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_revive_player_priority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_grab_buildable()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_grab_buildable_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_grab_buildable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_check_complete_grab_buildable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_grab_buildable()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_grab_buildable_on_completion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_grab_buildable_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_grabbuild_buildable_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_grab_buildable_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_grab_buildable_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_grab_buildable_priority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_build_buildable()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_build_buildable_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_build_buildable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_check_complete_build_buildable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_build_buildable()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_build_buildable_on_completion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_build_buildable_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_build_buildable_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_build_buildable_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_build_buildable_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_build_buildable_priority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_grab_part()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_part_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_grab_part()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_part_on_completion()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_part_should_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_check_complete_grab_part()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_grab_part()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_part_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_part_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_part_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_part_priority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_grab_powerup()
|
||||
{
|
||||
self endon( "powerup_end_think" );
|
||||
|
||||
if ( !isDefined( self.available_powerups ) || self.available_powerups.size <= 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
set_bot_global_shared_objective_owner_by_reference( "powerup", self.available_powerups[ 0 ], self );
|
||||
while ( true )
|
||||
{
|
||||
self SetScriptGoal( self.available_powerups[ 0 ].target_ent.origin );
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
bot_powerup_process_order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_should_grab_powerup()
|
||||
{
|
||||
if ( level.zbot_objective_glob[ "powerup" ].active_objectives.size <= 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
MAX_DISTANCE_SQ = 10000 * 10000;
|
||||
BOT_SPEED_WHILE_SPRINTING_SQ = 285 * 285;
|
||||
self.available_powerups = [];
|
||||
|
||||
powerup_objectives = level.zbot_objective_glob[ "powerup" ].active_objectives;
|
||||
obj_keys = getArrayKeys( powerup_objectives );
|
||||
for ( i = 0; i < powerup_objectives.size; i++ )
|
||||
{
|
||||
obj = powerup_objectives[ obj_keys[ i ] ];
|
||||
powerup = obj.target_ent;
|
||||
if ( isDefined( obj.owner ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
time_left = powerup.time_left_until_timeout;
|
||||
distance_required_to_reach_powerup = distanceSquared( powerup.origin, self.origin );
|
||||
if ( distance_required_to_reach_powerup > BOT_SPEED_WHILE_SPRINTING_SQ * time_left )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( distanceSquared( powerup.origin, self.origin ) > MAX_DISTANCE_SQ )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( !isDefined( generatePath( self.origin, powerup.origin, self.team, false ) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
self.available_powerups[ self.available_powerups.size ] = obj;
|
||||
}
|
||||
|
||||
//TODO: Sort powerups by priority here
|
||||
return self.available_powerups.size > 0;
|
||||
}
|
||||
|
||||
bot_check_complete_grab_powerup()
|
||||
{
|
||||
if ( self.successfully_grabbed_powerup )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_set_complete_grab_powerup()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_powerup_on_completion()
|
||||
{
|
||||
self.successfully_grabbed_powerup = false;
|
||||
}
|
||||
|
||||
bot_powerup_should_cancel()
|
||||
{
|
||||
return ( !isDefined( self.available_powerups ) || self.available_powerups.size <= 0 );
|
||||
}
|
||||
|
||||
bot_powerup_on_cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_powerup_should_postpone()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_powerup_on_postpone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bot_powerup_priority()
|
||||
{
|
||||
if ( !isDefined( self.available_powerups ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return self.available_powerups[ 0 ].target_ent.priority;
|
||||
}
|
279
scripts/sp/bots/bot_actions_common.gsc
Normal file
279
scripts/sp/bots/bot_actions_common.gsc
Normal file
@ -0,0 +1,279 @@
|
||||
/*
|
||||
Bot actions are in two parts
|
||||
*/
|
||||
#include common_scripts\utility;
|
||||
#include maps\_utility;
|
||||
#include maps\so\zm_common\_zm_utility;
|
||||
#include scripts\sp\bots\bot_utility;
|
||||
|
||||
register_bot_action( group_name, action_name, action_func, action_process_order_func, should_do_func, check_if_complete_func, set_complete_func, on_completion_func, should_cancel_func, on_cancel_func, should_postpone_func, on_postpone_func, priority_func )
|
||||
{
|
||||
if ( !isDefined( level.zbots_actions ) )
|
||||
{
|
||||
level.zbots_actions = [];
|
||||
}
|
||||
if ( !isDefined( level.zbots_actions[ group_name ] ) )
|
||||
{
|
||||
level.zbots_actions[ group_name ] = [];
|
||||
}
|
||||
if ( !isDefined( level.zbots_actions[ group_name ][ action_name ] ) )
|
||||
{
|
||||
level.zbots_actions[ group_name ][ action_name ] = spawnStruct();
|
||||
}
|
||||
level.zbots_actions[ group_name ][ action_name ].action = action_func;
|
||||
level.zbots_actions[ group_name ][ action_name ].should_do_func = should_do_func;
|
||||
level.zbots_actions[ group_name ][ action_name ].action_process_order_func = action_process_order_func;
|
||||
level.zbots_actions[ group_name ][ action_name ].check_if_complete_func = check_if_complete_func;
|
||||
level.zbots_actions[ group_name ][ action_name ].set_complete_func = set_complete_func;
|
||||
level.zbots_actions[ group_name ][ action_name ].on_completion_func = on_completion_func;
|
||||
level.zbots_actions[ group_name ][ action_name ].should_cancel_func = should_cancel_func;
|
||||
level.zbots_actions[ group_name ][ action_name ].on_cancel_func = on_cancel_func;
|
||||
level.zbots_actions[ group_name ][ action_name ].should_postpone_func = should_postpone_func;
|
||||
level.zbots_actions[ group_name ][ action_name ].on_postpone_func = on_postpone_func;
|
||||
level.zbots_actions[ group_name ][ action_name ].priority_func = priority_func;
|
||||
}
|
||||
|
||||
initialize_bot_actions_queue()
|
||||
{
|
||||
group_keys = getArrayKeys( level.zbots_actions );
|
||||
for ( i = 0; i < group_keys.size; i++ )
|
||||
{
|
||||
action_keys = getArrayKeys( level.zbots_actions[ group_keys[ i ] ] );
|
||||
for ( j = 0; j < action_keys.size; j++ )
|
||||
{
|
||||
self register_bot_objective_action_for_queue( group_keys[ i ], action_keys[ j ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
register_bot_objective_action_for_queue( group_name, action_name )
|
||||
{
|
||||
if ( !isDefined( self.zbot_actions_in_queue ) )
|
||||
{
|
||||
self.zbot_actions_in_queue = [];
|
||||
}
|
||||
if ( !isDefined( self.zbot_actions_in_queue[ group_name ] ) )
|
||||
{
|
||||
self.zbot_actions_in_queue[ group_name ] = [];
|
||||
}
|
||||
if ( !isDefined( self.zbot_actions_in_queue[ group_name ][ action_name ] ) )
|
||||
{
|
||||
self.zbot_actions_in_queue[ group_name ][ action_name ] = spawnStruct();
|
||||
}
|
||||
self.zbot_actions_in_queue[ group_name ][ action_name ].postponed = false;
|
||||
self.zbot_actions_in_queue[ group_name ][ action_name ].canceled = false;
|
||||
self.zbot_actions_in_queue[ group_name ][ action_name ].queued = false;
|
||||
self.zbot_actions_in_queue[ group_name ][ action_name ].completed = false;
|
||||
self.zbot_actions_in_queue[ group_name ][ action_name ].is_current = false;
|
||||
}
|
||||
|
||||
process_next_queued_action( group_name )
|
||||
{
|
||||
if ( self.zbot_actions_in_queue[ group_name ][ self.action_queue[ group_name ][ 0 ].action_name ].queued )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self.action_queue[ group_name ] = self sort_array_by_priority_field( self.action_queue[ group_name ] );
|
||||
|
||||
self thread [[ self.action_queue[ group_name ][ 0 ].action ]]();
|
||||
|
||||
self.zbot_actions_in_queue[ group_name ][ self.action_queue[ group_name ][ 0 ].action_name ].is_current = true;
|
||||
|
||||
self thread wait_for_action_completion( group_name, self.action_queue[ group_name ][ 0 ].action_name );
|
||||
}
|
||||
|
||||
wait_for_action_completion( group_name, action_name )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "stop_action_think" );
|
||||
level endon( "end_game" );
|
||||
|
||||
result = self waittill_any_return( action_name + "_complete", action_name + "_cancel", action_name + "_postpone" );
|
||||
if ( ( result == action_name + "_complete" ) )
|
||||
{
|
||||
self.zbot_actions_in_queue[ group_name ][ action_name ].postponed = false;
|
||||
self.zbot_actions_in_queue[ group_name ][ action_name ].queued = false;
|
||||
self.zbot_actions_in_queue[ group_name ][ action_name ].completed = false;
|
||||
self.action_queue[ group_name ][ 0 ] = undefined;
|
||||
self thread [[ self.action_queue[ group_name ][ 0 ].on_completion_func ]]();
|
||||
}
|
||||
else if ( result == action_name + "_cancel" )
|
||||
{
|
||||
self.zbot_actions_in_queue[ group_name ][ action_name ].postponed = false;
|
||||
self.zbot_actions_in_queue[ group_name ][ action_name ].queued = false;
|
||||
self.zbot_actions_in_queue[ group_name ][ action_name ].completed = false;
|
||||
self.action_queue[ group_name ][ 0 ] = undefined;
|
||||
self thread [[ self.action_queue[ group_name ][ 0 ].on_cancel_func ]]();
|
||||
}
|
||||
else if ( result == action_name + "_postpone" )
|
||||
{
|
||||
self.zbot_actions_in_queue[ group_name ][ action_name ].postponed = true;
|
||||
postponed_action = self.action_queue[ group_name ][ 0 ];
|
||||
self.action_queue[ group_name ][ 0 ] = undefined;
|
||||
postponed_action.priority = self [[ level.zbots_actions[ group_name ][ action_name ].priority_func ]]();
|
||||
self.action_queue[ group_name ] = array_insert( self.action_queue[ group_name ], postponed_action, 1 );
|
||||
self thread [[ self.action_queue[ group_name ][ 0 ].on_postpone_func ]]();
|
||||
}
|
||||
|
||||
self notify( action_name + "_end_think" );
|
||||
|
||||
self.zbot_actions_in_queue[ group_name ][ action_name ].is_current = false;
|
||||
}
|
||||
|
||||
copy_default_action_settings_to_queue( group_name, action_name )
|
||||
{
|
||||
//self.group = level.zbots_actions[ group_name ][ action_name ].group;
|
||||
self.action = level.zbots_actions[ group_name ][ action_name ].action;
|
||||
//self.should_do_func = level.zbots_actions[ group_name ][ action_name ].should_do_func;
|
||||
self.on_completion_func = level.zbots_actions[ group_name ][ action_name ].on_completion_func;
|
||||
self.should_cancel_func = level.zbots_actions[ group_name ][ action_name ].should_cancel_func;
|
||||
self.on_cancel_func = level.zbots_actions[ group_name ][ action_name ].on_cancel_func;
|
||||
self.should_postpone_func = level.zbots_actions[ group_name ][ action_name ].should_postpone_func;
|
||||
self.on_postpone_func = level.zbots_actions[ group_name ][ action_name ].on_postpone_func;
|
||||
self.priority_func = level.zbots_actions[ group_name ][ action_name ].priority_func;
|
||||
}
|
||||
|
||||
pick_actions_to_add_to_queue( group_name )
|
||||
{
|
||||
action_keys = getArrayKeys( level.zbots_actions[ group_name ] );
|
||||
|
||||
//TODO: Use process order funcs to determine the order of actions being added to the queue
|
||||
//For now just randomize the order of the keys
|
||||
/*
|
||||
for ( i = 0; i < action_keys; i++ )
|
||||
{
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
if ( !isDefined( self.action_id ) )
|
||||
{
|
||||
self.action_id = 0;
|
||||
}
|
||||
|
||||
for ( i = 0; i < action_keys.size; i++ )
|
||||
{
|
||||
if ( !self.zbot_actions_in_queue[ group_name ][ action_keys[ i ] ].queued && [[ level.zbots_actions[ group_name ][ action_keys[ i ] ].should_do_func ]]() )
|
||||
{
|
||||
self.action_queue[ group_name ][ self.action_queue[ group_name ].size ] = spawnStruct();
|
||||
self.action_queue[ group_name ][ self.action_queue[ group_name ].size - 1 ].action_name = action_keys[ i ];
|
||||
self.action_queue[ group_name ][ self.action_queue[ group_name ].size - 1 ].action_id = self.action_id;
|
||||
self.action_queue[ group_name ][ self.action_queue[ group_name ].size - 1 ].priority = self [[ level.zbots_actions[ group_name ][ action_keys[ i ] ].priority_func ]]();
|
||||
self.zbot_actions_in_queue[ group_name ][ action_keys[ i ] ].queued = true;
|
||||
self.action_id++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_clear_actions_queue()
|
||||
{
|
||||
group_keys = getArrayKeys( level.zbots_actions );
|
||||
for ( i = 0; i < group_keys.size; i++ )
|
||||
{
|
||||
self.action_queue[ group_keys[ i ] ] = [];
|
||||
action_keys = getArrayKeys( level.zbots_actions[ group_keys[ i ] ] );
|
||||
for ( j = 0; j < action_keys.size; j++ )
|
||||
{
|
||||
self register_bot_objective_action_for_queue( group_keys[ i ], action_keys[ j ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
check_if_action_is_completed_in_group( group_name )
|
||||
{
|
||||
if ( [[ level.zbots_actions[ group_name ][ self.action_queue[ group_name ][ 0 ].action_name ].check_if_complete_func ]]() )
|
||||
{
|
||||
self notify( self.action_queue[ group_name ][ 0 ].action_name + "_complete" );
|
||||
}
|
||||
}
|
||||
|
||||
check_if_action_should_be_postponed_in_group( group_name )
|
||||
{
|
||||
if ( [[ level.zbots_actions[ group_name ][ self.action_queue[ group_name ][ 0 ].action_name ].should_postpone_func ]]() )
|
||||
{
|
||||
self notify( self.action_queue[ group_name ][ 0 ].action_name + "_postpone" );
|
||||
}
|
||||
}
|
||||
|
||||
check_if_action_should_be_canceled_in_group( group_name )
|
||||
{
|
||||
if ( [[ level.zbots_actions[ group_name ][ self.action_queue[ group_name ][ 0 ].action_name ].should_cancel_func ]]() )
|
||||
{
|
||||
self notify( self.action_queue[ group_name ][ 0 ].action_name + "_cancel" );
|
||||
}
|
||||
}
|
||||
|
||||
check_if_action_should_be_postponed_globally( group_name )
|
||||
{
|
||||
if ( action_should_be_postponed_global( group_name, self.action_queue[ group_name ][ 0 ].action_name ) )
|
||||
{
|
||||
self notify( self.action_queue[ group_name ][ 0 ].action_name + "_postpone" );
|
||||
}
|
||||
}
|
||||
|
||||
check_if_action_should_be_canceled_globally( group_name )
|
||||
{
|
||||
if ( action_should_be_canceled_global( group_name, self.action_queue[ group_name ][ 0 ].action_name ) )
|
||||
{
|
||||
self notify( self.action_queue[ group_name ][ 0 ].action_name + "_cancel" );
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Figure out way of overriding the current action for flee movement action
|
||||
check_for_forced_action( group_name )
|
||||
{
|
||||
action_keys = getArrayKeys( level.zbots_actions[ group_name ] );
|
||||
action_priorities_array = [];
|
||||
for ( i = 0; i < action_keys.size; i++ )
|
||||
{
|
||||
action_priorities_array[ action_priorities_array.size ] = spawnStruct();
|
||||
action_priorities_array[ action_priorities_array.size - 1 ].priority = self [[ level.zbots_actions[ group_name ][ action_keys[ i ] ].priority_func ]]();
|
||||
action_priorities_array[ action_priorities_array.size - 1 ].action_name = action_keys[ i ];
|
||||
}
|
||||
|
||||
action_priorities_array = sort_array_by_priority_field( action_priorities_array );
|
||||
|
||||
if ( self.action_queue[ group_name ][ 0 ].priority < action_priorities_array[ 0 ].priority )
|
||||
{
|
||||
self notify( self.action_queue[ group_name ][ 0 ].action_name + "_cancel" );
|
||||
}
|
||||
}
|
||||
|
||||
bot_action_think( group_name )
|
||||
{
|
||||
self pick_actions_to_add_to_queue( group_name );
|
||||
|
||||
//self check_for_forced_action( group_name );
|
||||
|
||||
if ( self.action_queue[ group_name ].size <= 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self process_next_queued_action( group_name );
|
||||
|
||||
self check_if_action_is_completed_in_group( group_name );
|
||||
self check_if_action_should_be_postponed_in_group( group_name );
|
||||
self check_if_action_should_be_canceled_in_group( group_name );
|
||||
|
||||
self check_if_action_should_be_postponed_globally( group_name );
|
||||
self check_if_action_should_be_canceled_globally( group_name );
|
||||
}
|
||||
|
||||
action_should_be_postponed_global( primary_group_name, action_name )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
action_should_be_canceled_global( primary_group_name, action_name )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//TODO: Add ability to pause an action so the bot won't be doing it while its paused but when its unpaused they can resume the action with the same settings
|
||||
//Similar to postpone except instead of selecting a new action the current action is preserved
|
||||
action_should_be_paused_global( primary_group_name, action_name )
|
||||
{
|
||||
return false;
|
||||
}
|
9
scripts/sp/bots/bot_difficulty_presets_common.gsc
Normal file
9
scripts/sp/bots/bot_difficulty_presets_common.gsc
Normal file
@ -0,0 +1,9 @@
|
||||
register_bot_difficulty( difficulty )
|
||||
{
|
||||
if ( !isDefined( level.zbot_difficulties ) )
|
||||
{
|
||||
level.zbot_difficulties = [];
|
||||
}
|
||||
|
||||
level.zbot_difficulties[ difficulty ] = true;
|
||||
}
|
207
scripts/sp/bots/bot_objective_common.gsc
Normal file
207
scripts/sp/bots/bot_objective_common.gsc
Normal file
@ -0,0 +1,207 @@
|
||||
register_bot_objective( objective_group )
|
||||
{
|
||||
if ( !isDefined( level.zbot_objective_glob ) )
|
||||
{
|
||||
level.zbot_objective_glob = [];
|
||||
}
|
||||
if ( !isDefined( level.zbot_objective_glob[ objective_group ] ) )
|
||||
{
|
||||
level.zbot_objective_glob[ objective_group ] = spawnStruct();
|
||||
level.zbot_objective_glob[ objective_group ].active_objectives = [];
|
||||
}
|
||||
}
|
||||
|
||||
add_possible_bot_objective( objective_group, id, is_global_shared, target_ent )
|
||||
{
|
||||
assert( isDefined( level.zbot_objective_glob ), "Trying to add objective before calling register_bot_objective" );
|
||||
|
||||
assert( isDefined( level.zbot_objective_glob[ objective_group ] ), "Trying to add objective to group " + objective_group + " before calling register_bot_objective" );
|
||||
|
||||
objective_struct = spawnStruct();
|
||||
objective_struct.group = objective_group;
|
||||
objective_struct.id = id;
|
||||
objective_struct.is_global_shared = is_global_shared;
|
||||
objective_struct.target_ent = target_ent;
|
||||
objective_struct.owner = undefined;
|
||||
objective_struct.is_objective = true;
|
||||
|
||||
level.zbot_objective_glob[ objective_group ].active_objectives[ "obj_id_" + id ] = objective_struct;
|
||||
}
|
||||
|
||||
get_bot_objective_by_id( objective_group, id )
|
||||
{
|
||||
active_objectives = level.zbot_objective_glob[ objective_group ].active_objectives;
|
||||
|
||||
objective = active_objectives[ "obj_id_" + id ];
|
||||
|
||||
assert( isDefined( objective ), "Objective with " + id + " id does not point to a objective in group " + objective_group );
|
||||
|
||||
return objective;
|
||||
}
|
||||
|
||||
get_all_objectives_for_group( objective_group )
|
||||
{
|
||||
return level.zbot_objective_glob[ objective_group ].active_objectives;
|
||||
}
|
||||
|
||||
set_objective_for_bot( objective_group, id )
|
||||
{
|
||||
possible_objectives = level.zbot_objective_glob[ objective_group ].active_objectives;
|
||||
|
||||
objective = possible_objectives[ "obj_id_" + id ];
|
||||
|
||||
objective_exists = isDefined( objective );
|
||||
|
||||
assert( objective_exists, "Objective with " + id + " id does not point to a objective in group " + objective_group );
|
||||
if ( !objective_exists )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self.zbot_current_objective = objective;
|
||||
}
|
||||
|
||||
clear_objective_for_bot()
|
||||
{
|
||||
self.zbot_current_objective = undefined;
|
||||
}
|
||||
|
||||
set_bot_objective_blocked_by_objective( primary_objective_group, primary_id, blocked_by_objective_group, blocked_by_id )
|
||||
{
|
||||
primary_active_objectives = level.zbot_objective_glob[ primary_objective_group ].active_objectives;
|
||||
|
||||
primary_objective = primary_active_objectives[ "obj_id_" + primary_id ];
|
||||
|
||||
primary_objective_exists = isDefined( primary_objective );
|
||||
|
||||
assert( primary_objective_exists, "Objective with " + primary_id + " id does not point to a objective in group " + primary_objective_group );
|
||||
if ( !primary_objective_exists )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( primary_objective_group == blocked_by_objective_group )
|
||||
{
|
||||
assert( primary_id != blocked_by_id, "Objective with " + primary_id + " id should not be the same as the blocked_by_id if the objectives are in the same group of " + primary_objective_group );
|
||||
if ( primary_id == blocked_by_id )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
blocking_objective = primary_active_objectives[ "obj_id_" + blocked_by_id ];
|
||||
|
||||
blocking_objective_exists = isDefined( blocking_objective );
|
||||
|
||||
assert( blocking_objective_exists, "Objective with " + blocked_by_id + " id does not point to a objective in group " + blocked_by_objective_group );
|
||||
if ( !blocking_objective_exists )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
primary_objective.blocking_objective = blocking_objective;
|
||||
}
|
||||
else
|
||||
{
|
||||
secondary_active_objectives = level.zbot_objective_glob[ blocked_by_objective_group ].active_objectives;
|
||||
|
||||
blocking_objective = secondary_active_objectives[ "obj_id_" + blocked_by_id ];
|
||||
|
||||
blocking_objective_exists = isDefined( blocking_objective );
|
||||
|
||||
assert( blocking_objective_exists, "Objective with " + blocked_by_id + " id does not point to a objective in group " + blocked_by_objective_group );
|
||||
if ( !blocking_objective_exists )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
primary_objective.blocking_objective = blocking_objective;
|
||||
}
|
||||
}
|
||||
|
||||
set_bot_global_shared_objective_owner_by_id( objective_group, id, new_owner )
|
||||
{
|
||||
active_objectives = level.zbot_objective_glob[ objective_group ].active_objectives;
|
||||
|
||||
objective = active_objectives[ "obj_id_" + id ];
|
||||
|
||||
objective_exists = isDefined( objective );
|
||||
assert( objective_exists, "Objective with " + id + " id number does not point to a objective in group " + objective_group );
|
||||
if ( !objective_exists )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
assert( objective.is_global_shared, "Objective with " + id + " id number cannot be set to have an owner because is_global_shared field is false in group " + objective_group );
|
||||
if ( !objective.is_global_shared )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
objective.owner = new_owner;
|
||||
}
|
||||
|
||||
set_bot_global_shared_objective_owner_by_reference( objective_group, objective, new_owner )
|
||||
{
|
||||
is_objective = isDefined( objective.is_objective );
|
||||
assert( is_objective, "Objective arg is not a valid objective object" );
|
||||
if ( !is_objective )
|
||||
{
|
||||
return;
|
||||
}
|
||||
assert( objective.is_global_shared, "Objective with " + objective.id + " id number cannot be set to have an owner because is_global_shared field is false in group " + objective_group );
|
||||
if ( !objective.is_global_shared )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
objective.owner = new_owner;
|
||||
}
|
||||
|
||||
free_bot_objective( objective_group, id )
|
||||
{
|
||||
active_objectives = level.zbot_global_shared_objective_glob[ objective_group ].active_objectives;
|
||||
|
||||
objective = active_objectives[ "obj_id_" + id ];
|
||||
|
||||
objective_exists = isDefined( objective );
|
||||
assert( objective_exists, "Objective with " + id + " id number does not point to a objective in group " + objective_group );
|
||||
if ( !objective_exists )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
players = getPlayers();
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
if ( players[ i ].pers[ "isBot" ] )
|
||||
{
|
||||
if ( players[ i ].zbot_current_objective == objective )
|
||||
{
|
||||
players[ i ].zbot_current_objective = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
objective = undefined;
|
||||
}
|
||||
|
||||
objective_think( objective_group, id )
|
||||
{
|
||||
active_objectives = level.zbot_global_shared_objective_glob[ objective_group ].active_objectives;
|
||||
|
||||
objective = active_objectives[ "obj_id_" + id ];
|
||||
|
||||
objective_exists = isDefined( objective );
|
||||
assert( objective_exists, "Objective with " + id + " id number does not point to a objective in group " + objective_group );
|
||||
if ( !objective_exists )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
level endon( "end_obj_think_" + objective.target_ent getEntityNumber() );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
if ( )
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
10
scripts/sp/bots/bot_personality_presets_common.gsc
Normal file
10
scripts/sp/bots/bot_personality_presets_common.gsc
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
register_bot_personality_type( personality )
|
||||
{
|
||||
if ( !isDefined( level.zbot_personalities ) )
|
||||
{
|
||||
level.zbot_personalities = [];
|
||||
}
|
||||
|
||||
level.zbot_personalities[ personality ] = true;
|
||||
}
|
194
scripts/sp/bots/bot_target_common.gsc
Normal file
194
scripts/sp/bots/bot_target_common.gsc
Normal file
@ -0,0 +1,194 @@
|
||||
#include common_scripts\utility;
|
||||
#include scripts\sp\bots\_bot_utility;
|
||||
|
||||
register_bot_target_type( target_group )
|
||||
{
|
||||
if ( !isDefined( level.zbot_target_glob ) )
|
||||
{
|
||||
level.zbot_target_glob = [];
|
||||
level.zbot_target_glob_ids = [];
|
||||
}
|
||||
if ( !isDefined( level.zbot_target_glob[ target_group ] ) )
|
||||
{
|
||||
level.zbot_target_glob_ids[ target_group ] = 0;
|
||||
level.zbot_target_glob[ target_group ] = spawnStruct();
|
||||
level.zbot_target_glob[ target_group ].active_targets = [];
|
||||
}
|
||||
}
|
||||
|
||||
add_possible_bot_target( target_group, id, target_ent )
|
||||
{
|
||||
assert( isDefined( level.zbot_target_glob ), "Trying to add target before calling register_bot_target_type" );
|
||||
|
||||
assert( isDefined( level.zbot_target_glob[ target_group ] ), "Trying to add target to group " + target_group + " before calling register_bot_target_type" );
|
||||
|
||||
target_struct = spawnStruct();
|
||||
target_struct.group = target_group;
|
||||
target_struct.target_id = id;
|
||||
target_struct.damaged_by = [];
|
||||
target_struct.targeted_by = [];
|
||||
target_struct.target_ent = target_ent;
|
||||
target_struct.is_target = true;
|
||||
|
||||
level.zbot_target_glob[ target_group ].active_targets[ "targ_id_" + id ] = target_struct;
|
||||
}
|
||||
|
||||
get_bot_target_by_id( target_group, id )
|
||||
{
|
||||
active_targets = level.zbot_target_glob[ target_group ].active_targets;
|
||||
|
||||
target = active_targets[ "targ_id_" + id ];
|
||||
|
||||
assert( isDefined( target ), "Target with " + id + " id does not point to a target in group " + target_group );
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
get_all_targets_for_group( target_group )
|
||||
{
|
||||
return level.zbot_target_glob[ target_group ].active_targets;
|
||||
}
|
||||
|
||||
get_all_groups_for_targets()
|
||||
{
|
||||
return getArrayKeys( level.zbot_target_glob );
|
||||
}
|
||||
|
||||
bot_has_target()
|
||||
{
|
||||
return isDefined( self.zbot_current_target );
|
||||
}
|
||||
|
||||
set_target_for_bot( target_group, id )
|
||||
{
|
||||
possible_targets = level.zbot_target_glob[ target_group ].active_targets;
|
||||
|
||||
target = possible_targets[ "targ_id_" + id ];
|
||||
|
||||
target_exists = isDefined( target );
|
||||
|
||||
assert( target_exists, "Target with " + id + " id does not point to a target in group " + target_group );
|
||||
if ( !target_exists )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self.zbot_current_target = target;
|
||||
|
||||
for ( i = 0; i < target.targeted_by.size; i++ )
|
||||
{
|
||||
if ( target.targeted_by[ i ] == self )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
target.targeted_by[ target.targeted_by.size ] = self;
|
||||
}
|
||||
|
||||
clear_target_for_bot( target_group, id )
|
||||
{
|
||||
possible_targets = level.zbot_target_glob[ target_group ].active_targets;
|
||||
|
||||
target = possible_targets[ "targ_id_" + id ];
|
||||
|
||||
target_exists = isDefined( target );
|
||||
|
||||
assert( target_exists, "Target with " + id + " id does not point to a target in group " + target_group );
|
||||
if ( !target_exists )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for ( i = 0; i < target.targeted_by.size; i++ )
|
||||
{
|
||||
if ( target.targeted_by[ i ] == self )
|
||||
{
|
||||
target.targeted_by[ i ] = undefined;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
self.zbot_current_target = undefined;
|
||||
}
|
||||
|
||||
set_target_damaged_by( target_group, id )
|
||||
{
|
||||
possible_targets = level.zbot_target_glob[ target_group ].active_targets;
|
||||
|
||||
target = possible_targets[ "targ_id_" + id ];
|
||||
|
||||
target_exists = isDefined( target );
|
||||
|
||||
assert( target_exists, "Target with " + id + " id does not point to a target in group " + target_group );
|
||||
if ( !target_exists )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for ( i = 0; i < target.damaged_by.size; i++ )
|
||||
{
|
||||
if ( target.damaged_by[ i ] == self )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
target.damaged_by[ target.damaged_by.size ] = self;
|
||||
}
|
||||
|
||||
clear_target_damaged_by( target_group, id )
|
||||
{
|
||||
possible_targets = level.zbot_target_glob[ target_group ].active_targets;
|
||||
|
||||
target = possible_targets[ "targ_id_" + id ];
|
||||
|
||||
target_exists = isDefined( target );
|
||||
|
||||
assert( target_exists, "Target with " + id + " id does not point to a target in group " + target_group );
|
||||
if ( !target_exists )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for ( i = 0; i < target.damaged_by.size; i++ )
|
||||
{
|
||||
if ( target.damaged_by[ i ] == self )
|
||||
{
|
||||
target.damaged_by[ i ] = undefined;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free_bot_target( target_group, id )
|
||||
{
|
||||
active_targets = level.zbot_global_shared_target_glob[ target_group ].active_targets;
|
||||
|
||||
target = active_targets[ "targ_id_" + id ];
|
||||
|
||||
target_exists = isDefined( target );
|
||||
|
||||
assert( target_exists, "Target with " + id + " id number does not point to a target in group " + target_group );
|
||||
if ( !target_exists )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
players = getPlayers();
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
if ( players[ i ].pers[ "isBot" ] )
|
||||
{
|
||||
if ( players[ i ].zbot_current_target == target )
|
||||
{
|
||||
players[ i ].zbot_current_target = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
target.damaged_by = undefined;
|
||||
target.targeted_by = undefined;
|
||||
|
||||
target = undefined;
|
||||
}
|
625
scripts/sp/bots/bot_utility.gsc
Normal file
625
scripts/sp/bots/bot_utility.gsc
Normal file
@ -0,0 +1,625 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\_utility;
|
||||
#include maps\so\zm_common\_zm_utility;
|
||||
|
||||
register_stats_for_bot_weapon( weapon, score )
|
||||
{
|
||||
if ( !isDefined( level.bot_weapons_stats ) )
|
||||
{
|
||||
level.bot_weapons_stats = [];
|
||||
}
|
||||
level.bot_weapons_stats[ weapon ] = score;
|
||||
}
|
||||
|
||||
parse_bot_weapon_stats_from_table()
|
||||
{
|
||||
WEAPON_COLUMN = 0;
|
||||
SCORE_COLUMN = 1;
|
||||
/*
|
||||
row = 0;
|
||||
while ( true )
|
||||
{
|
||||
weapon = fs_tablelookupcolumnforrow( "tables\bot_weapon_stats.csv", row, WEAPON_COLUMN );
|
||||
if ( !isDefined( weapon ) || weapon == "" )
|
||||
{
|
||||
break;
|
||||
}
|
||||
score = fs_tablelookupcolumnforrow( "tables\bot_weapon_stats.csv", row, SCORE_COLUMN );
|
||||
if ( !isDefined( score ) || score == "" )
|
||||
{
|
||||
row++;
|
||||
continue;
|
||||
}
|
||||
if ( isDefined( level.zombie_include_weapons[ weapon + "_zm" ] ) )
|
||||
{
|
||||
register_stats_for_bot_weapon( weapon + "_zm", int( score ) );
|
||||
if ( isDefined( level.zombie_include_weapons[ weapon + "_upgraded_zm" ] ) )
|
||||
{
|
||||
register_stats_for_bot_weapon( weapon + "_upgraded_zm", int( score ) + 1 );
|
||||
}
|
||||
}
|
||||
else if ( isDefined( level.zombie_include_weapons[ weapon ] ) )
|
||||
{
|
||||
register_stats_for_bot_weapon( weapon, int( score ) );
|
||||
}
|
||||
row++;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
array_add2( array, item )
|
||||
{
|
||||
array[ array.size ] = item;
|
||||
}
|
||||
|
||||
swap( array, index1, index2 )
|
||||
{
|
||||
temp = array[ index1 ];
|
||||
array[ index1 ] = array[ index2 ];
|
||||
array[ index2 ] = temp;
|
||||
return array;
|
||||
}
|
||||
|
||||
merge_sort( current_list, func_sort, param )
|
||||
{
|
||||
if ( current_list.size <= 1 )
|
||||
{
|
||||
return current_list;
|
||||
}
|
||||
|
||||
left = [];
|
||||
right = [];
|
||||
|
||||
middle = current_list.size / 2;
|
||||
|
||||
for ( x = 0; x < middle; x++ )
|
||||
{
|
||||
array_add2( left, current_list[ x ] );
|
||||
}
|
||||
|
||||
for ( ; x < current_list.size; x++ )
|
||||
{
|
||||
array_add2( right, current_list[ x ] );
|
||||
}
|
||||
|
||||
left = merge_sort( left, func_sort, param );
|
||||
right = merge_sort( right, func_sort, param );
|
||||
|
||||
//result = merge( left, right, func_sort, param );
|
||||
|
||||
//return result;
|
||||
}
|
||||
|
||||
quickSort(array, compare_func)
|
||||
{
|
||||
return quickSortMid(array, 0, array.size - 1, compare_func);
|
||||
}
|
||||
|
||||
quickSortMid( array, start, end, compare_func )
|
||||
{
|
||||
i = start;
|
||||
k = end;
|
||||
|
||||
if(!IsDefined(compare_func))
|
||||
compare_func = ::quicksort_compare;
|
||||
|
||||
if (end - start >= 1)
|
||||
{
|
||||
pivot = array[start];
|
||||
|
||||
while (k > i)
|
||||
{
|
||||
while ( [[ compare_func ]](array[i], pivot) && i <= end && k > i)
|
||||
i++;
|
||||
while ( ![[ compare_func ]](array[k], pivot) && k >= start && k >= i)
|
||||
k--;
|
||||
if (k > i)
|
||||
array = swap(array, i, k);
|
||||
}
|
||||
array = swap(array, start, k);
|
||||
array = quickSortMid(array, start, k - 1, compare_func);
|
||||
array = quickSortMid(array, k + 1, end, compare_func);
|
||||
}
|
||||
else
|
||||
return array;
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
quicksort_compare(left, right)
|
||||
{
|
||||
return left <= right;
|
||||
}
|
||||
|
||||
get_allies()
|
||||
{
|
||||
return getPlayers( self.team );
|
||||
}
|
||||
|
||||
get_zombies()
|
||||
{
|
||||
return getAiSpeciesArray( level.zombie_team, "all" );
|
||||
}
|
||||
|
||||
find_gaps()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
are_enemies_horded()
|
||||
{
|
||||
MINIMUM_PERCENT_TO_BE_HORDE = 0.9;
|
||||
DISTANCE_SQ = 120 * 120;
|
||||
zombies = get_zombies();
|
||||
amount_in_horde = 0;
|
||||
if ( isDefined( level.speed_change_round ) )
|
||||
{
|
||||
max_eligible_zombies = zombies.size - level.speed_change_num;
|
||||
}
|
||||
else
|
||||
{
|
||||
max_eligible_zombies = zombies.size;
|
||||
}
|
||||
expected_amount_in_horde_min = int( max_eligible_zombies * MINIMUM_PERCENT_TO_BE_HORDE );
|
||||
if ( isDefined( level.speed_change_round ) )
|
||||
{
|
||||
for ( i = 0; i < zombies.size; i++ )
|
||||
{
|
||||
if ( zombies[ i ].zombie_move_speed == "walk" )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( !isDefined( zombies[ i + 1 ] ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ( zombies[ i + 1 ].zombie_move_speed != "walk" )
|
||||
{
|
||||
if ( distanceSquared( zombies[ i + 1 ].origin, zombies[ i ].origin ) <= DISTANCE_SQ )
|
||||
{
|
||||
amount_in_horde++;
|
||||
}
|
||||
}
|
||||
if ( amount_in_horde >= expected_amount_in_horde_min )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( i = 0; i < zombies.size; i++ )
|
||||
{
|
||||
if ( !isDefined( zombies[ i + 1 ] ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ( distanceSquared( zombies[ i + 1 ].origin, zombies[ i ].origin ) <= DISTANCE_SQ )
|
||||
{
|
||||
amount_in_horde++;
|
||||
}
|
||||
if ( amount_in_horde >= expected_amount_in_horde_min )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
any_enemies_in_direction( dir )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
predict_entity_position_frames( frames )
|
||||
{
|
||||
current_velocity = self getVelocity();
|
||||
predicted_origin = self.origin;
|
||||
for ( i = 0; i < frames; i++ )
|
||||
{
|
||||
predicted_origin += ( current_velocity / 20 );
|
||||
}
|
||||
return predicted_origin;
|
||||
}
|
||||
|
||||
predict_entity_position_seconds( seconds )
|
||||
{
|
||||
current_velocity = self getVelocity();
|
||||
predicted_origin = self.origin;
|
||||
for ( i = 0; i < seconds; i++ )
|
||||
{
|
||||
predicted_origin += current_velocity;
|
||||
}
|
||||
return predicted_origin;
|
||||
}
|
||||
|
||||
any_zombies_targeting_self()
|
||||
{
|
||||
ZOMBIE_TARGETING_DIST_SQ = 10 * 10;
|
||||
zombies = get_zombies();
|
||||
if ( !array_validate( zombies ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for ( i = 0; i < zombies.size; i++ )
|
||||
{
|
||||
if ( isDefined( zombies[ i ].favoriteenemy ) && zombies[ i ].favoriteenemy == self )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ( isDefined( zombies[ i ].goal_pos ) && distanceSquared( zombies[ i ].goal_pos, self.origin ) < ZOMBIE_TARGETING_DIST_SQ )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_is_in_danger( player )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_valid( player )
|
||||
{
|
||||
if ( !isdefined( player ) )
|
||||
return false;
|
||||
|
||||
if ( !isalive( player ) )
|
||||
return false;
|
||||
|
||||
if ( !isplayer( player ) )
|
||||
return false;
|
||||
|
||||
if ( !is_true( player.pers[ "isBot" ] ) )
|
||||
return false;
|
||||
|
||||
if ( isdefined( player.is_zombie ) && player.is_zombie == 1 )
|
||||
return false;
|
||||
|
||||
if ( player.sessionstate == "spectator" )
|
||||
return false;
|
||||
|
||||
if ( player.sessionstate == "intermission" )
|
||||
return false;
|
||||
|
||||
if ( isdefined( player.intermission ) && player.intermission )
|
||||
return false;
|
||||
|
||||
if ( isdefined( level.is_player_valid_override ) )
|
||||
return [[ level.is_player_valid_override ]]( player );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
assign_priority_to_powerup( powerup )
|
||||
{
|
||||
if ( !isDefined( powerup ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
priority = 0;
|
||||
powerup_is_max_ammo = false;
|
||||
switch ( powerup.powerup_name )
|
||||
{
|
||||
case "zombie_blood":
|
||||
case "insta_kill":
|
||||
case "nuke":
|
||||
priority += 2;
|
||||
break;
|
||||
case "full_ammo":
|
||||
powerup_is_max_ammo = true;
|
||||
priority += 1;
|
||||
break;
|
||||
case "double_points":
|
||||
case "fire_sale":
|
||||
case "carpenter":
|
||||
case "free_perk":
|
||||
priority += 1;
|
||||
break;
|
||||
default:
|
||||
priority += 0;
|
||||
break;
|
||||
}
|
||||
if ( powerup_is_max_ammo )
|
||||
{
|
||||
LOW_AMMO_THRESHOLD = 0.3;
|
||||
|
||||
for ( i = 0; i < level.players.size; i++ )
|
||||
{
|
||||
weapons = level.players[ i ] getWeaponsListPrimaries();
|
||||
for ( j = 0; j < weapons.size; j++ )
|
||||
{
|
||||
if ( self getWeaponAmmoStock( weapons[ j ] ) <= int( weaponmaxammo( weapons[ j ] ) * LOW_AMMO_THRESHOLD ) )
|
||||
{
|
||||
priority += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( priority > 3 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( maps\_laststand::player_any_player_in_laststand() )
|
||||
{
|
||||
switch ( powerup.powerup_name )
|
||||
{
|
||||
case "zombie_blood":
|
||||
case "insta_kill":
|
||||
case "nuke":
|
||||
priority += 1;
|
||||
break;
|
||||
case "full_ammo":
|
||||
priority += 0;
|
||||
break;
|
||||
case "double_points":
|
||||
case "fire_sale":
|
||||
case "carpenter":
|
||||
case "free_perk":
|
||||
priority -= 1;
|
||||
break;
|
||||
default:
|
||||
priority += 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( powerup.time_left_until_timeout < 10.0 )
|
||||
{
|
||||
priority += 1;
|
||||
}
|
||||
if ( priority < 0 )
|
||||
{
|
||||
priority = 0;
|
||||
}
|
||||
powerup.priority = priority;
|
||||
}
|
||||
|
||||
sort_array_by_priority_field( array, item )
|
||||
{
|
||||
if ( isDefined( item ) )
|
||||
{
|
||||
array[ array.size ] = item;
|
||||
}
|
||||
|
||||
priority_array = [];
|
||||
for ( i = 0; i < array.size; i++ )
|
||||
{
|
||||
priority_array[ i ] = array[ i ].priority;
|
||||
}
|
||||
priority_array = quickSort( priority_array );
|
||||
sorted_array = [];
|
||||
for ( i = 0; i < priority_array.size; i++ )
|
||||
{
|
||||
for ( j = 0; j < array.size; j++ )
|
||||
{
|
||||
if ( array[ j ].priority == priority_array[ i ] )
|
||||
{
|
||||
sorted_array[ sorted_array.size ] = array[ j ];
|
||||
}
|
||||
}
|
||||
}
|
||||
return sorted_array;
|
||||
}
|
||||
|
||||
/*
|
||||
We need to calculate where the bot should go to next and update their movement constantly here
|
||||
If the calculations predicts death or teammates death based on current course we need recalculate next move
|
||||
Updating every frame(0.05) should be sufficient
|
||||
Key to movement code is determining gaps, and safe lines to follow
|
||||
Bot should try to find the nearest safe line and follow it
|
||||
Due to many different variables(primarily resulting from other players) we need to constantly verify if the line is safe to follow
|
||||
If the bot doesn't detect any danger allow them to stand still far enough away from the zombies to not draw aggro but close enough to shoot at them
|
||||
Questions:
|
||||
Can bots move and use the use button at the same time? Necessary to be able to support circle revive
|
||||
How do we know the bot is safe where they are currently or where they will be moving to?
|
||||
How do we determine gaps in zombies/terrain to slip through?
|
||||
*/
|
||||
movement_think()
|
||||
{
|
||||
while ( true )
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
bot methods docs
|
||||
|
||||
enum BotGoalPriority
|
||||
{
|
||||
GOAL_PRIORITY_UNUSED = 0x0,
|
||||
GOAL_PRIORITY_LOW = 0x1,
|
||||
GOAL_PRIORITY_NORMAL = 0x2,
|
||||
GOAL_PRIORITY_HIGH = 0x3,
|
||||
GOAL_PRIORITY_URGENT = 0x4,
|
||||
GOAL_PRIORITY_MAX = 0x5,
|
||||
};
|
||||
|
||||
|
||||
success = bot addGoal( <origin|pathnode>, float<goalRadius>, BotGoalPriority<priority>, string<notify> );
|
||||
bot cancelGoal( string<notify> );
|
||||
bot atGoal( string[notify] );
|
||||
bot hasGoal( string<notify> );
|
||||
origin = bot getGoal( string<notify> );
|
||||
bot pressUseButton( float<time_in_seconds> );
|
||||
bot pressAttackButton( float<time_in_seconds> );
|
||||
bot pressDtpButton();
|
||||
bot pressAds( <bool> );
|
||||
bot pressMelee();
|
||||
bot throwGrenade( string<weapon_name>, vector<destination> );
|
||||
dist = bot getLookaheadDist();
|
||||
dir = bot getLookAheadDir();
|
||||
bot lookAt( vector<origin> );
|
||||
bot clearLookat();
|
||||
pos = bot predictPosition( entity<ent>, int<num_frames> );
|
||||
success = bot sightTracePassed( entity<ent>, vector[point] );
|
||||
enemies = bot getThreats( float<fov> ); //Fov value can be -1 to find all enemies instead of enemies in fov.
|
||||
bot botSetFailsafeNode( pathnode[node] );
|
||||
|
||||
player methods docs
|
||||
player allowStand( <bool> );
|
||||
player allowCrouch( <bool> );
|
||||
player allowProne( <bool> );
|
||||
player allowAds( <bool> );
|
||||
player allowSprint( <bool> );
|
||||
player allowMelee( <bool> );
|
||||
player setSpawnWeapon( string<weapon_name> );
|
||||
player isLookingAt( <entity> );
|
||||
ads_amount = player playerAds();
|
||||
stance = player getstance();
|
||||
player setStance( string<stance> );
|
||||
dot = player playerSightTrace( vector<item_position>, int<unk>, int<hitnum> );
|
||||
|
||||
entity methods docs
|
||||
mins = entity getMins();
|
||||
maxes = entity getMaxes();
|
||||
absmins = entity getAdbMins();
|
||||
absmaxes = entity getAbsMaxes();
|
||||
eye = entity getEye();
|
||||
centroid = entity getCentroid()
|
||||
velocity = entity getVelocity();
|
||||
vector = entity getpointinbounds( float<x>, float<y>, float<z> );
|
||||
is_touching = entity isTouching( entity<ent>, vector[extra_boundary] );
|
||||
is_touching = entity isTouchingVolume( vector<origin>, vector<mins>, vector<maxes> );
|
||||
|
||||
dot = entity damageConeTrace( vector<damage_origin>, entity[ent], vector[damage_angles], float[damage_amount] );
|
||||
dot = entity sightConeTrace( vector<damage_origin>, entity[ent], vector[damage_angles], float[damage_amount] );
|
||||
|
||||
common functions docs
|
||||
|
||||
nodeStringTable = {
|
||||
"Path",
|
||||
"Cover Stand",
|
||||
"Cover Crouch",
|
||||
"Cover Crouch Window",
|
||||
"Cover Prone",
|
||||
"Cover Right",
|
||||
"Cover Left",
|
||||
"Cover Pillar",
|
||||
"Ambush",
|
||||
"Exposed",
|
||||
"Conceal Stand",
|
||||
"Conceal Crouch",
|
||||
"Conceal Prone",
|
||||
"Reacquire",
|
||||
"Balcony",
|
||||
"Scripted",
|
||||
"Begin",
|
||||
"End",
|
||||
"Turret",
|
||||
"Guard"
|
||||
}
|
||||
|
||||
enum team_t
|
||||
{
|
||||
TEAM_FREE = 0x0,
|
||||
TEAM_BAD = 0x0,
|
||||
TEAM_ALLIES = 0x1,
|
||||
TEAM_AXIS = 0x2,
|
||||
TEAM_THREE = 0x3,
|
||||
TEAM_FOUR = 0x4,
|
||||
TEAM_FIVE = 0x5,
|
||||
TEAM_SIX = 0x6,
|
||||
TEAM_SEVEN = 0x7,
|
||||
TEAM_EIGHT = 0x8,
|
||||
TEAM_NUM_PLAYING_TEAMS = 0x9,
|
||||
TEAM_SPECTATOR = 0x9,
|
||||
TEAM_NUM_TEAMS = 0xA,
|
||||
TEAM_LOCALPLAYERS = 0xB,
|
||||
TEAM_FIRST_PLAYING_TEAM = 0x1,
|
||||
TEAM_LAST_PLAYING_TEAM = 0x8,
|
||||
};
|
||||
|
||||
nodespawn_t nodespawns[21]
|
||||
{
|
||||
'node_pathnode'
|
||||
'node_guard'
|
||||
'node_turret'
|
||||
'node_negotiation_end'
|
||||
'node_negotiation_begin'
|
||||
'node_scripted'
|
||||
'node_balcony'
|
||||
'node_reacquire'
|
||||
'node_concealment_prone'
|
||||
'node_concealment_crouch'
|
||||
'node_concealment_stand'
|
||||
'node_exposed'
|
||||
'node_ambush'
|
||||
'node_cover_pillar'
|
||||
'node_cover_left'
|
||||
'node_cover_right'
|
||||
'node_cover_prone'
|
||||
'node_cover_crouch_window'
|
||||
'node_cover_crouch'
|
||||
'node_cover_stand'
|
||||
}
|
||||
|
||||
node = getNode( string<name>, entkey<key> );
|
||||
nodes = getNodeArray( string<name>, entkey<key );
|
||||
nodes = getNodeArraySorted( string<name>, entkey<key>, vector[origin], float[max_dist] );
|
||||
nodes = getAnyNodeArray( vector<origin>, float<max_dist> );
|
||||
nodes = getCoverNodeArray( vector<origin>, float<max_dist> );
|
||||
nodes = getAllNodes();
|
||||
nodes = getNodesInRadius( vector<origin>, float<max_radius>, float<min_radius>, float[max_height], nodeStringTable[type], int<max_nodes> );
|
||||
nodes = getNodesInRadiusSorted( vector<origin>, float<max_radius>, float<min_radius>, float[max_height], nodeStringTable[type], int<max_nodes> );
|
||||
node = getNearestNode( vector<origin> );
|
||||
node = getVisibleNode( vector<start>, vector<end>, entity[ent] );
|
||||
nodes = getVisibleNodes( node_ent<node> );
|
||||
visible = nodesVisible( node_ent<node>, node_ent<node> );
|
||||
canpath = nodesCanPath( node_ent<node>, node_ent<node> );
|
||||
canclaimnode = canClaimNode( node_ent<node>, team_t<team> );
|
||||
setEnableNode( node_ent<node>, [bool] );
|
||||
linkNodes( node_ent<node>, node_ent<node> );
|
||||
unLinkNodes( node_ent<node>, node_ent<node> );
|
||||
nodesAreLinked( node_ent<node>, node_ent<node> );
|
||||
dropnodetofloor( node_ent<node> );
|
||||
node = spawnPathNode( nodespawn_t<classname>, vector<origin>, vector<angles>, key[key1], value[val1], ... );
|
||||
deletePathNode( node_ent<node> );
|
||||
occupied = isNodeOccupied( node_ent<node> );
|
||||
nodeowner = getNodeOwner( node_ent<node> );
|
||||
foundpath = findPath( vector<start>, vector<end>, entity[ent], bool[allow_negotiation_links], bool[allow_negotiation_hints] );
|
||||
|
||||
vector = vectorFromLineToPoint( vector<<start_pos>, vector<end_pos>, vector<point> );
|
||||
point = pointOnSegmentNearestToPoint( vector<start_pos>, vector<end_pos>, vector<test_origin> );
|
||||
pos_a_is_closer = closer( vector<ref_pos>, vector<a>, vector<b> );
|
||||
dot = vectorDot( vector<a>, vector<b> );
|
||||
cross = vectorCross( vector<a>, vector<b> );
|
||||
normalized_vector = vectorNormalize( vector<vec> );
|
||||
lerped_vector = vectorLerp( vector<from>, vector<to>, float<lerp> );
|
||||
combined_angles = combineAngles( vector<a>, vector<b> );
|
||||
angles = vectorToAngles( vector<vec> );
|
||||
angle = absAngleClamp180( float<angle> );
|
||||
angle = absAngleClamp360( float<angle> );
|
||||
point = rotatePoint( vector<point>, vector<angles> );
|
||||
|
||||
trace
|
||||
{
|
||||
"fraction",
|
||||
"position",
|
||||
"entity",
|
||||
"normal",
|
||||
"surfacetype"
|
||||
}
|
||||
|
||||
trace = bulletTrace( vector<end_pos>, vector<start_pos>, bool<use_content_mask_flag>, entity<ignore_ent>, bool[modify_contents_flags1], bool[modify_contents_flags2] );
|
||||
passed = bulletTracePassed( vector<start_pos>, vector<end_pos>, bool<use_clipmask>, entity<ignore_ent>, entity[ignore_ent2?], bool[check_fx_visibility] );
|
||||
trace = groundTrace( vector<end_pos>, vector<start_pos>, bool<use_content_mask_flag>, entity<ignore_ent>, bool[modify_contents_flags1], bool[modify_contents_flags2] );
|
||||
passed = sightTracePassed( vector<start_pos>, vector<end_pos>, bool<use_clipmask>, entity<ignore_ent> );
|
||||
|
||||
player_physics_trace = playerPhysicsTrace( vector<end_pos>, vector<start_pos> );
|
||||
trace = physicsTrace( vector<end_pos>, vector<smins>, vector[maxes], vector[end_pos], entity[ignore_ent] );
|
||||
trace = worldTrace( vector<end_pos>, vector<start_pos> );
|
||||
|
||||
|
||||
? customs functions to add
|
||||
node = bot getNextNodeInPath( vector<start>, vector<end>, entity[ent], bool[allow_negotiation_links], bool[allow_negotiation_hints] );
|
||||
bot botMovementOverride( byte<forward>, byte<right> );
|
||||
self botButtonOverride( string<button>, string<value> );
|
||||
self botClearMovementOverride();
|
||||
self botClearButtonOverride( string<value> );
|
||||
*/
|
Reference in New Issue
Block a user