Improve action system.

Fix objective system to use entity numbers instead of infinitely increasing ids. Fix all known script errors. Add the ability for bots to revive players and pickup powerups automatically.
This commit is contained in:
JezuzLizard 2023-05-01 08:09:33 -07:00
parent da170b8f9e
commit 1c835bd77b
3 changed files with 255 additions and 147 deletions

View File

@ -112,33 +112,30 @@ init()
level thread onPlayerConnect(); level thread onPlayerConnect();
level thread handleBots(); level thread handleBots();
maps\_bot_script::register_bot_action( "objective", "powerup", maps\_bot_script::bot_grab_powerup, maps\bots\_bot_script::register_bot_action( "objective", "powerup", maps\bots\_bot_script::bot_grab_powerup,
maps\_bot_script::bot_powerup_process_order, maps\bots\_bot_script::bot_powerup_process_order,
maps\_bot_script::bot_should_grab_powerup, maps\bots\_bot_script::bot_powerup_init,
maps\_bot_script::bot_check_complete_grab_powerup, maps\bots\_bot_script::bot_powerup_post_think,
maps\_bot_script::bot_set_complete_grab_powerup, maps\bots\_bot_script::bot_should_grab_powerup,
maps\_bot_script::bot_powerup_on_completion, maps\bots\_bot_script::bot_check_complete_grab_powerup,
maps\_bot_script::bot_powerup_should_cancel, maps\bots\_bot_script::bot_powerup_should_cancel,
maps\_bot_script::bot_powerup_on_cancel, maps\bots\_bot_script::bot_powerup_should_postpone,
maps\_bot_script::bot_powerup_should_postpone, maps\bots\_bot_script::bot_powerup_priority );
maps\_bot_script::bot_powerup_on_postpone,
maps\_bot_script::bot_powerup_priority );
maps\_bot_script::register_bot_action( "objective", "revive", maps\_bot_script::bot_revive_player, maps\bots\_bot_script::register_bot_action( "objective", "revive", maps\bots\_bot_script::bot_revive_player,
maps\_bot_script::bot_revive_process_order, maps\bots\_bot_script::bot_revive_process_order,
maps\_bot_script::bot_should_revive_player, maps\bots\_bot_script::bot_revive_player_init,
maps\_bot_script::bot_check_complete_revive_player, maps\bots\_bot_script::bot_revive_player_post_think,
maps\_bot_script::bot_set_complete_revive_player, maps\bots\_bot_script::bot_should_revive_player,
maps\_bot_script::bot_revive_player_on_completion, maps\bots\_bot_script::bot_check_complete_revive_player,
maps\_bot_script::bot_revive_player_should_cancel, maps\bots\_bot_script::bot_revive_player_should_cancel,
maps\_bot_script::bot_revive_player_on_cancel, maps\bots\_bot_script::bot_revive_player_should_postpone,
maps\_bot_script::bot_revive_player_should_postpone, maps\bots\_bot_script::bot_revive_player_priority );
maps\_bot_script::bot_revive_player_on_postpone, maps\bots\_bot_script::register_bot_objective( "powerup" );
maps\_bot_script::bot_revive_player_priority ); maps\bots\_bot_script::register_bot_objective( "revive" );
maps\_bot_script::register_bot_objective( "powerup" );
level thread maps\_bot_script::store_powerups_dropped(); level thread maps\bots\_bot_script::store_powerups_dropped();
level thread maps\_bot_script::watch_for_downed_players(); level thread maps\bots\_bot_script::watch_for_downed_players();
} }
/* /*
@ -179,6 +176,22 @@ onPlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon,
self [[level.prevCallbackPlayerDamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime ); self [[level.prevCallbackPlayerDamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime );
} }
on_actor_spawned()
{
if ( isDefined( level.prevCallbackActorSpawned ) )
{
self [[ level.prevCallbackActorSpawned ]]();
}
}
on_actor_killed( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, iTimeOffset )
{
if ( isDefined( level.prevCallbackActorKilled ) )
{
self [[ level.prevCallbackActorKilled ]]( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, iTimeOffset );
}
}
/* /*
Starts the callbacks. Starts the callbacks.
*/ */
@ -187,6 +200,10 @@ hook_callbacks()
wait 0.05; wait 0.05;
level.prevCallbackPlayerDamage = level.callbackPlayerDamage; level.prevCallbackPlayerDamage = level.callbackPlayerDamage;
level.callbackPlayerDamage = ::onPlayerDamage; level.callbackPlayerDamage = ::onPlayerDamage;
level.prevCallbackActorSpawned = level.callbackActorSpawned;
level.callbackActorSpawned = ::on_actor_spawned;
level.prevCallbackActorKilled = level.callbackActorKilled;
level.callbackActorKilled = ::on_actor_killed;
} }
/* /*

View File

@ -22,6 +22,10 @@ connected()
self thread difficulty(); self thread difficulty();
self thread onBotSpawned(); self thread onBotSpawned();
self thread onSpawned(); self thread onSpawned();
self thread initialize_bot_actions_queue();
self.on_powerup_grab_func = ::bot_on_powerup_grab;
self.on_revive_success_func = ::bot_on_revive_success;
} }
/* /*
@ -385,15 +389,22 @@ register_bot_objective( objective_group )
} }
} }
add_possible_bot_objective( objective_group, id, is_global_shared, target_ent ) add_possible_bot_objective( objective_group, target_ent, is_global_shared )
{ {
assert( isDefined( level.zbot_objective_glob ), "Trying to add objective before calling register_bot_objective" ); 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" ); assert( isDefined( level.zbot_objective_glob[ objective_group ] ), "Trying to add objective to group " + objective_group + " before calling register_bot_objective" );
if ( !isDefined( target_ent ) )
{
assertMsg( "target_ent is undefined" );
return;
}
id = target_ent getEntityNumber();
objective_struct = spawnStruct(); objective_struct = spawnStruct();
objective_struct.group = objective_group; objective_struct.group = objective_group;
objective_struct.id = id;
objective_struct.is_global_shared = is_global_shared; objective_struct.is_global_shared = is_global_shared;
objective_struct.target_ent = target_ent; objective_struct.target_ent = target_ent;
objective_struct.owner = undefined; objective_struct.owner = undefined;
@ -402,8 +413,16 @@ add_possible_bot_objective( objective_group, id, is_global_shared, target_ent )
level.zbot_objective_glob[ objective_group ].active_objectives[ "obj_id_" + id ] = objective_struct; level.zbot_objective_glob[ objective_group ].active_objectives[ "obj_id_" + id ] = objective_struct;
} }
get_bot_objective_by_id( objective_group, id ) get_bot_objective_by_entity_ref( objective_group, ent )
{ {
if ( !isDefined( ent ) )
{
assertMsg( "Ent is undefined" );
return;
}
id = ent getEntityNumber();
active_objectives = level.zbot_objective_glob[ objective_group ].active_objectives; active_objectives = level.zbot_objective_glob[ objective_group ].active_objectives;
objective = active_objectives[ "obj_id_" + id ]; objective = active_objectives[ "obj_id_" + id ];
@ -418,10 +437,18 @@ get_all_objectives_for_group( objective_group )
return level.zbot_objective_glob[ objective_group ].active_objectives; return level.zbot_objective_glob[ objective_group ].active_objectives;
} }
set_objective_for_bot( objective_group, id ) set_objective_for_bot( objective_group, ent )
{ {
if ( !isDefined( ent ) )
{
assertMsg( "Ent is undefined" );
return;
}
possible_objectives = level.zbot_objective_glob[ objective_group ].active_objectives; possible_objectives = level.zbot_objective_glob[ objective_group ].active_objectives;
id = ent getEntityNumber();
objective = possible_objectives[ "obj_id_" + id ]; objective = possible_objectives[ "obj_id_" + id ];
objective_exists = isDefined( objective ); objective_exists = isDefined( objective );
@ -440,8 +467,24 @@ clear_objective_for_bot()
self.zbot_current_objective = undefined; self.zbot_current_objective = undefined;
} }
set_bot_objective_blocked_by_objective( primary_objective_group, primary_id, blocked_by_objective_group, blocked_by_id ) set_bot_objective_blocked_by_objective( primary_objective_group, primary_ent, blocked_by_objective_group, blocked_by_ent )
{ {
if ( !isDefined( primary_ent ) )
{
assertMsg( "Primary_ent is undefined" );
return;
}
if ( !isDefined( blocked_by_ent ) )
{
assertMsg( "Blocked_by_ent is undefined" );
return;
}
primary_id = primary_ent getEntityNumber();
blocked_by_id = blocked_by_ent getEntityNumber();
primary_active_objectives = level.zbot_objective_glob[ primary_objective_group ].active_objectives; primary_active_objectives = level.zbot_objective_glob[ primary_objective_group ].active_objectives;
primary_objective = primary_active_objectives[ "obj_id_" + primary_id ]; primary_objective = primary_active_objectives[ "obj_id_" + primary_id ];
@ -491,8 +534,16 @@ set_bot_objective_blocked_by_objective( primary_objective_group, primary_id, blo
} }
} }
set_bot_global_shared_objective_owner_by_id( objective_group, id, new_owner ) set_bot_global_shared_objective_owner_by_ent( objective_group, ent, new_owner )
{ {
if ( !isDefined( ent ) )
{
assertMsg( "Ent is undefined" );
return;
}
id = ent getEntityNumber();
active_objectives = level.zbot_objective_glob[ objective_group ].active_objectives; active_objectives = level.zbot_objective_glob[ objective_group ].active_objectives;
objective = active_objectives[ "obj_id_" + id ]; objective = active_objectives[ "obj_id_" + id ];
@ -530,9 +581,17 @@ set_bot_global_shared_objective_owner_by_reference( objective_group, objective,
objective.owner = new_owner; objective.owner = new_owner;
} }
free_bot_objective( objective_group, id ) free_bot_objective( objective_group, ent )
{ {
active_objectives = level.zbot_global_shared_objective_glob[ objective_group ].active_objectives; if ( !isDefined( ent ) )
{
assertMsg( "Ent is undefined" );
return;
}
id = ent getEntityNumber();
active_objectives = level.zbot_objective_glob[ objective_group ].active_objectives;
objective = active_objectives[ "obj_id_" + id ]; objective = active_objectives[ "obj_id_" + id ];
@ -555,10 +614,10 @@ free_bot_objective( objective_group, id )
} }
} }
objective = undefined; active_objectives[ "obj_id_" + id ] = undefined;
} }
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 ) register_bot_action( group_name, action_name, action_func, action_process_order_func, init_func, post_think_func, should_do_func, check_if_complete_func, should_cancel_func, should_postpone_func, priority_func )
{ {
if ( !isDefined( level.zbots_actions ) ) if ( !isDefined( level.zbots_actions ) )
{ {
@ -573,23 +632,23 @@ register_bot_action( group_name, action_name, action_func, action_process_order_
level.zbots_actions[ group_name ][ action_name ] = spawnStruct(); 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 ].action = action_func;
level.zbots_actions[ group_name ][ action_name ].init_func = init_func;
level.zbots_actions[ group_name ][ action_name ].post_think_func = post_think_func;
level.zbots_actions[ group_name ][ action_name ].should_do_func = should_do_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 ].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 ].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 ].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 ].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; level.zbots_actions[ group_name ][ action_name ].priority_func = priority_func;
} }
initialize_bot_actions_queue() initialize_bot_actions_queue()
{ {
self.action_queue = [];
group_keys = getArrayKeys( level.zbots_actions ); group_keys = getArrayKeys( level.zbots_actions );
for ( i = 0; i < group_keys.size; i++ ) for ( i = 0; i < group_keys.size; i++ )
{ {
self.action_queue[ group_keys[ i ] ] = [];
action_keys = getArrayKeys( level.zbots_actions[ group_keys[ i ] ] ); action_keys = getArrayKeys( level.zbots_actions[ group_keys[ i ] ] );
for ( j = 0; j < action_keys.size; j++ ) for ( j = 0; j < action_keys.size; j++ )
{ {
@ -613,9 +672,7 @@ register_bot_objective_action_for_queue( group_name, action_name )
self.zbot_actions_in_queue[ group_name ][ action_name ] = spawnStruct(); 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 ].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 ].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; self.zbot_actions_in_queue[ group_name ][ action_name ].is_current = false;
} }
@ -628,6 +685,8 @@ process_next_queued_action( group_name )
self.action_queue[ group_name ] = self sort_array_by_priority_field( self.action_queue[ group_name ] ); self.action_queue[ group_name ] = self sort_array_by_priority_field( self.action_queue[ group_name ] );
self [[ self.action_queue[ group_name ][ 0 ].init_func ]]();
self thread [[ self.action_queue[ group_name ][ 0 ].action ]](); 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.zbot_actions_in_queue[ group_name ][ self.action_queue[ group_name ][ 0 ].action_name ].is_current = true;
@ -646,48 +705,47 @@ wait_for_action_completion( group_name, action_name )
action_postpone_name = action_name + "_postpone"; action_postpone_name = action_name + "_postpone";
result = self waittill_any_return( action_complete_name, action_cancel_name, action_postpone_name ); result = self waittill_any_return( action_complete_name, action_cancel_name, action_postpone_name );
save_action = false;
end_state = undefined;
if ( ( result == action_complete_name ) ) if ( ( result == action_complete_name ) )
{ {
self.zbot_actions_in_queue[ group_name ][ action_name ].postponed = false; 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 ].queued = false;
self.zbot_actions_in_queue[ group_name ][ action_name ].completed = false; end_state = "completed";
self.action_queue[ group_name ][ 0 ] = undefined;
self thread [[ self.action_queue[ group_name ][ 0 ].on_completion_func ]]();
} }
else if ( result == action_cancel_name ) else if ( result == action_cancel_name )
{ {
self.zbot_actions_in_queue[ group_name ][ action_name ].postponed = false; 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 ].queued = false;
self.zbot_actions_in_queue[ group_name ][ action_name ].completed = false; end_state = "canceled";
self.action_queue[ group_name ][ 0 ] = undefined;
self thread [[ self.action_queue[ group_name ][ 0 ].on_cancel_func ]]();
} }
else if ( result == action_postpone_name ) else if ( result == action_postpone_name )
{ {
self.zbot_actions_in_queue[ group_name ][ action_name ].postponed = true; self.zbot_actions_in_queue[ group_name ][ action_name ].postponed = true;
postponed_action = self.action_queue[ group_name ][ 0 ]; save_action = true;
self.action_queue[ group_name ][ 0 ] = undefined; end_state = "postponed";
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.zbot_actions_in_queue[ group_name ][ action_name ].is_current = false;
self notify( action_name + "_end_think" ); self notify( action_name + "_end_think" );
self.zbot_actions_in_queue[ group_name ][ action_name ].is_current = false; self [[ self.action_queue[ group_name ][ 0 ].post_think_func ]]( end_state );
}
copy_default_action_settings_to_queue( group_name, action_name ) if ( save_action )
{ {
//self.group = level.zbots_actions[ group_name ][ action_name ].group; postponed_action = self.action_queue[ group_name ][ 0 ];
self.action = level.zbots_actions[ group_name ][ action_name ].action; postponed_action.priority = self [[ level.zbots_actions[ group_name ][ action_name ].priority_func ]]();
//self.should_do_func = level.zbots_actions[ group_name ][ action_name ].should_do_func; self.action_queue[ group_name ] = array_insert( self.action_queue[ group_name ], postponed_action, 2 );
self.on_completion_func = level.zbots_actions[ group_name ][ action_name ].on_completion_func; self.action_queue[ group_name ][ 0 ] = undefined;
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; else
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.action_queue[ group_name ][ 0 ] = undefined;
self.priority_func = level.zbots_actions[ group_name ][ action_name ].priority_func; }
} }
pick_actions_to_add_to_queue( group_name ) pick_actions_to_add_to_queue( group_name )
@ -803,7 +861,7 @@ bot_action_think()
while ( true ) while ( true )
{ {
wait 0.05; wait 1;
group_name = "objective"; group_name = "objective";
@ -852,12 +910,9 @@ bot_grab_powerup()
{ {
return; return;
} }
set_bot_global_shared_objective_owner_by_reference( "powerup", self.available_powerups[ 0 ], self ); set_bot_global_shared_objective_owner_by_ent( "powerup", self.available_powerups[ 0 ].target_ent, self );
while ( true )
{
self SetScriptGoal( self.available_powerups[ 0 ].target_ent.origin ); self SetScriptGoal( self.available_powerups[ 0 ].target_ent.origin );
wait 0.05;
}
} }
bot_powerup_process_order() bot_powerup_process_order()
@ -865,6 +920,18 @@ bot_powerup_process_order()
return 0; return 0;
} }
bot_powerup_init()
{
self.successfully_grabbed_powerup = false;
}
bot_powerup_post_think( state )
{
self.successfully_grabbed_powerup = false;
self ClearScriptGoal();
self ClearScriptAimPos();
}
bot_should_grab_powerup() bot_should_grab_powerup()
{ {
if ( level.zbot_objective_glob[ "powerup" ].active_objectives.size <= 0 ) if ( level.zbot_objective_glob[ "powerup" ].active_objectives.size <= 0 )
@ -881,6 +948,10 @@ bot_should_grab_powerup()
{ {
obj = powerup_objectives[ obj_keys[ i ] ]; obj = powerup_objectives[ obj_keys[ i ] ];
powerup = obj.target_ent; powerup = obj.target_ent;
if ( !isDefined( powerup ) )
{
continue;
}
if ( isDefined( obj.owner ) ) if ( isDefined( obj.owner ) )
{ {
continue; continue;
@ -908,31 +979,12 @@ bot_should_grab_powerup()
bot_check_complete_grab_powerup() bot_check_complete_grab_powerup()
{ {
if ( self.successfully_grabbed_powerup ) return 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() bot_powerup_should_cancel()
{ {
return ( !isDefined( self.available_powerups ) || self.available_powerups.size <= 0 ); return !isDefined( self.available_powerups ) || self.available_powerups.size <= 0 || !isDefined( self.available_powerups[ 0 ].target_ent );
}
bot_powerup_on_cancel()
{
} }
bot_powerup_should_postpone() bot_powerup_should_postpone()
@ -940,11 +992,6 @@ bot_powerup_should_postpone()
return false; return false;
} }
bot_powerup_on_postpone()
{
}
bot_powerup_priority() bot_powerup_priority()
{ {
if ( !isDefined( self.available_powerups ) ) if ( !isDefined( self.available_powerups ) )
@ -962,28 +1009,56 @@ bot_revive_player()
} }
self endon( "disconnect" ); self endon( "disconnect" );
self endon( "revive_end_think" );
self endon( "player_downed" );
level endon( "end_game" ); level endon( "end_game" );
player_to_revive_obj = self.available_revives[ 0 ]; player_to_revive_obj = self.available_revives[ 0 ];
set_bot_global_shared_objective_owner_by_reference( "revive", player_to_revive_obj, self ); set_bot_global_shared_objective_owner_by_ent( "revive", player_to_revive_obj.target_ent, self );
player_to_revive = player_to_revive_obj.target_ent; 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 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 //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 ) while ( isDefined( player_to_revive ) && isDefined( player_to_revive_obj ) )
{ {
self.target_pos = player_to_revive.origin; wait 0.05;
//Constantly update the goal just in case the player is moving(T5 or higher only)
self ClearScriptAimPos();
self SetScriptGoal( player_to_revive.origin, 16 );
if ( self.can_do_objective_now ) if ( !self AtScriptGoal() )
{ {
continue;
//TODO: Add check to see if another player is reviving target player //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? //TODO: Add code to revive player, possibly add the ability to circle revive?
} }
wait 0.2; if ( !isDefined( player_to_revive.revivetrigger ) )
{
return;
}
//Check if the bot is reviving the player already and also that the player isn't being revived already
if ( player_to_revive.revivetrigger.beingrevived && !self maps\_laststand::is_reviving( player_to_revive ) )
{
continue;
}
SetScriptAimPos( player_to_revive.origin );
time = 3;
if ( self hasPerk( "specialty_quickrevive" ) )
{
time /= 2;
}
self BotPressUse( time );
while ( self maps\_laststand::is_reviving( player_to_revive ) )
{
wait 0.05;
}
//Wait to see if we cleared the objective by successfully reviving the player
waittillframeend;
} }
} }
@ -992,6 +1067,18 @@ bot_revive_process_order()
return 0; return 0;
} }
bot_revive_player_init()
{
self.successfully_revived_player = false;
}
bot_revive_player_post_think( state )
{
self.successfully_revived_player = false;
self ClearScriptGoal();
self ClearScriptAimPos();
}
bot_should_revive_player() bot_should_revive_player()
{ {
downed_players_objs = get_all_objectives_for_group( "revive" ); downed_players_objs = get_all_objectives_for_group( "revive" );
@ -1017,31 +1104,12 @@ bot_should_revive_player()
bot_check_complete_revive_player() bot_check_complete_revive_player()
{ {
if ( self.successfully_revived_player ) return 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() bot_revive_player_should_cancel()
{ {
return !isDefined( self.available_revives[ 0 ].target_ent.revivetrigger ); return !isDefined( self.available_revives[ 0 ] ) || !isDefined( self.available_revives[ 0 ].target_ent ) || !isDefined( self.available_revives[ 0 ].target_ent.revivetrigger );
}
bot_revive_player_on_cancel()
{
} }
bot_revive_player_should_postpone() bot_revive_player_should_postpone()
@ -1049,11 +1117,6 @@ bot_revive_player_should_postpone()
return false; return false;
} }
bot_revive_player_on_postpone()
{
}
bot_revive_player_priority() bot_revive_player_priority()
{ {
return 0; return 0;
@ -1066,7 +1129,6 @@ store_powerups_dropped()
level thread free_powerups_dropped(); level thread free_powerups_dropped();
level.zbots_powerups = []; level.zbots_powerups = [];
id = 0;
while ( true ) while ( true )
{ {
level waittill( "powerup_dropped", powerup ); level waittill( "powerup_dropped", powerup );
@ -1074,12 +1136,9 @@ store_powerups_dropped()
{ {
continue; continue;
} }
powerup.id = id; add_possible_bot_objective( "powerup", powerup, true );
add_possible_bot_objective( "powerup", id, true, powerup ); maps\bots\_bot_utility::assign_priority_to_powerup( powerup );
level thread objective_think( "powerup", id ); level.zbots_powerups = maps\bots\_bot_utility::sort_array_by_priority_field( level.zbots_powerups, powerup );
scripts\sp\bots\bot_utility::assign_priority_to_powerup( powerup );
level.zbots_powerups = scripts\sp\bots\bot_utility::sort_array_by_priority_field( level.zbots_powerups, powerup );
id++;
} }
} }
@ -1090,7 +1149,7 @@ free_powerups_dropped()
while ( true ) while ( true )
{ {
level waittill( "powerup_freed", powerup ); level waittill( "powerup_freed", powerup );
free_bot_objective( "powerup", powerup.id ); free_bot_objective( "powerup", powerup );
} }
} }
@ -1105,7 +1164,7 @@ watch_for_downed_players()
{ {
continue; continue;
} }
add_possible_bot_objective( "revive", player.client_id, true, player ); add_possible_bot_objective( "revive", player, true );
player thread free_revive_objective_when_needed(); player thread free_revive_objective_when_needed();
} }
} }
@ -1120,5 +1179,15 @@ free_revive_objective_when_needed()
wait 0.05; wait 0.05;
} }
free_bot_objective( "revive", id ); free_bot_objective( "revive", self );
}
bot_on_powerup_grab( powerup )
{
self.successfully_grabbed_powerup = true;
}
bot_on_revive_success( revivee )
{
self.successfully_revived_player = true;
} }

View File

@ -267,6 +267,15 @@ ClearScriptGoal()
self SetScriptGoal( undefined, 0 ); self SetScriptGoal( undefined, 0 );
} }
/*
Returns whether the bot is at it's goal
*/
AtScriptGoal()
{
return distanceSquared( self.bot.script_goal, self.origin ) <= self.bot.script_goal_dist * self.bot.script_goal_dist;
}
/* /*
Sets the aim position of the bot Sets the aim position of the bot
*/ */
@ -1009,11 +1018,22 @@ targetIsGibbed()
return isDefined( self.gibbed ) && self.gibbed; return isDefined( self.gibbed ) && self.gibbed;
} }
quickSort(array, compare_func) swap_array_index( array, index1, index2 )
{ {
return quickSortMid(array, 0, array.size - 1, compare_func); temp = array[ index1 ];
array[ index1 ] = array[ index2 ];
array[ index2 ] = temp;
return array;
} }
quickSort(array, compare_func, compare_func_arg1)
{
return quickSortMid( array, 0, array.size - 1, compare_func, compare_func_arg1 );
}
/*
Quicksort algorithm copied from T7 modified for T4
*/
quickSortMid( array, start, end, compare_func, compare_func_arg1 ) quickSortMid( array, start, end, compare_func, compare_func_arg1 )
{ {
i = start; i = start;
@ -1033,9 +1053,9 @@ quickSortMid( array, start, end, compare_func, compare_func_arg1 )
while ( ![[ compare_func ]](array[k], pivot, compare_func_arg1) && k >= start && k >= i) while ( ![[ compare_func ]](array[k], pivot, compare_func_arg1) && k >= start && k >= i)
k--; k--;
if (k > i) if (k > i)
array = swap(array, i, k); array = swap_array_index(array, i, k);
} }
array = swap(array, start, k); array = swap_array_index(array, start, k);
array = quickSortMid(array, start, k - 1, compare_func); array = quickSortMid(array, start, k - 1, compare_func);
array = quickSortMid(array, k + 1, end, compare_func); array = quickSortMid(array, k + 1, end, compare_func);
} }
@ -1098,9 +1118,11 @@ assign_priority_to_powerup( powerup )
{ {
LOW_AMMO_THRESHOLD = 0.3; LOW_AMMO_THRESHOLD = 0.3;
for ( i = 0; i < level.players.size; i++ ) players = getPlayers();
for ( i = 0; i < players.size; i++ )
{ {
weapons = level.players[ i ] getWeaponsListPrimaries(); weapons = players[ i ] getWeaponsListPrimaries();
for ( j = 0; j < weapons.size; j++ ) for ( j = 0; j < weapons.size; j++ )
{ {
if ( self getWeaponAmmoStock( weapons[ j ] ) <= int( weaponmaxammo( weapons[ j ] ) * LOW_AMMO_THRESHOLD ) ) if ( self getWeaponAmmoStock( weapons[ j ] ) <= int( weaponmaxammo( weapons[ j ] ) * LOW_AMMO_THRESHOLD ) )