From 845b377efffc8230ba8a9fe0d6a9a91b630bcae1 Mon Sep 17 00:00:00 2001 From: JezuzLizard Date: Mon, 3 Jul 2023 20:12:04 -0700 Subject: [PATCH] Progress. --- maps/bots/_bot_script.gsc | 8 +- maps/bots/script_objectives/_obj_actions.gsc | 201 ++++++++++---- maps/bots/script_objectives/_obj_common.gsc | 250 ++++++++++-------- maps/bots/script_objectives/_obj_init.gsc | 28 +- maps/bots/script_objectives/_obj_trackers.gsc | 228 +++++++++------- 5 files changed, 443 insertions(+), 272 deletions(-) diff --git a/maps/bots/_bot_script.gsc b/maps/bots/_bot_script.gsc index b2b164d..709f1b6 100644 --- a/maps/bots/_bot_script.gsc +++ b/maps/bots/_bot_script.gsc @@ -7,7 +7,7 @@ */ bot_script_init() { - //level thread maps\bots\script_objectives\_obj_init::init(); + level thread maps\bots\script_objectives\_obj_init::init(); } /* @@ -31,7 +31,7 @@ connected() self thread onBotSpawned(); self thread onSpawned(); - //self thread maps\bots\script_objectives\_obj_init::connected(); + self thread maps\bots\script_objectives\_obj_init::connected(); } /* @@ -370,7 +370,7 @@ onSpawned() self.bot_lock_goal = false; self.bot_was_follow_script_update = undefined; - //self thread maps\bots\script_objectives::spawned(); + self thread maps\bots\script_objectives\_obj_init::spawned(); } } @@ -383,5 +383,5 @@ start_bot_threads() level endon( "intermission" ); self endon( "zombified" ); - //self thread maps\bots\script_objectives::start_bot_threads(); + self thread maps\bots\script_objectives\_obj_init::start_bot_threads(); } diff --git a/maps/bots/script_objectives/_obj_actions.gsc b/maps/bots/script_objectives/_obj_actions.gsc index 6dd279f..1ad6344 100644 --- a/maps/bots/script_objectives/_obj_actions.gsc +++ b/maps/bots/script_objectives/_obj_actions.gsc @@ -3,25 +3,25 @@ #include maps\bots\_bot_utility; #include maps\bots\script_objectives\_obj_common; -bot_post_think_common( state, obj_ent ) +bot_post_think_common( state ) { obj = bot_objective_history_get_current(); switch ( state ) { case "completed": - bot_objective_print( "powerup", obj.id, "Bot <" + self.playername + "> objective was completed", "bot_post_think_common" ); + self bot_objective_print( obj.group, obj.id, "Bot <" + self.playername + "> objective was completed", "bot_post_think_common" ); break; case "postponed": - bot_objective_print( "powerup", obj.id, "Bot <" + self.playername + "> objective was postponed Reason: " + self.obj_postponed_reason, "bot_post_think_common" ); + self bot_objective_print( obj.group, obj.id, "Bot <" + self.playername + "> objective was postponed Reason: " + self.obj_postponed_reason, "bot_post_think_common" ); break; case "canceled": - bot_objective_print( "powerup", obj.id, "Bot <" + self.playername + "> objective was canceled Reason: " + self.obj_cancel_reason, "bot_post_think_common" ); + self bot_objective_print( obj.group, obj.id, "Bot <" + self.playername + "> objective was canceled Reason: " + self.obj_cancel_reason, "bot_post_think_common" ); break; } self.obj_postponed_reason = ""; self.obj_cancel_reason = ""; - self ClearScriptGoal(); + self thread ClearScriptGoal(); self ClearScriptAimPos(); self ClearPriorityObjective(); self bot_clear_objective(); @@ -31,7 +31,6 @@ bot_grab_powerup() { self endon( "disconnect" ); self endon( "powerup_end_think" ); - self endon( "bot_in_invalid_state" ); level endon( "end_game" ); if ( !isDefined( self.available_powerups ) || self.available_powerups.size <= 0 ) @@ -44,7 +43,7 @@ bot_grab_powerup() self bot_set_objective( "powerup", powerup_obj_ent ); self bot_set_objective_owner( "powerup", powerup_obj_ent ); - bot_objective_print( "powerup", powerup_obj.id, "Bot <" + self.playername + "> starts objective", "bot_grab_powerup" ); + self bot_objective_print( "powerup", powerup_obj.id, "Bot <" + self.playername + "> starts objective", "bot_grab_powerup" ); while ( true ) { wait 1; @@ -55,7 +54,7 @@ bot_grab_powerup() if ( result != "goal" ) { - bot_objective_print( "powerup", powerup_obj.id, "Bot <" + self.playername + "> bad path", "bot_grab_powerup" ); + self bot_objective_print( "powerup", powerup_obj.id, "Bot <" + self.playername + "> bad path", "bot_grab_powerup" ); continue; } //Wait to see if the bot was able to grab the powerup @@ -83,7 +82,7 @@ bot_grab_powerup() if ( powerup_obj.bad ) { - bot_objective_print( "powerup", powerup_obj.id, "Bot <" + self.playername + "> objective was marked as bad", "bot_grab_powerup" ); + self bot_objective_print( "powerup", powerup_obj.id, "Bot <" + self.playername + "> objective was marked as bad", "bot_grab_powerup" ); break; } } @@ -102,9 +101,7 @@ bot_powerup_init() bot_powerup_post_think( state ) { - obj = self bot_get_objective(); - powerup_obj_ent = obj.target_ent; - self bot_post_think_common( state, powerup_obj_ent ); + self bot_post_think_common( state ); self.successfully_grabbed_powerup = false; } @@ -166,17 +163,13 @@ bot_powerup_should_cancel() { obj = self bot_get_objective(); - canceled_goal = false; + goal_canceled = false; if ( !self bot_is_objective_owner( "powerup", obj.target_ent ) ) { self.obj_cancel_reason = "No longer the obj owner"; - canceled_goal = true; + goal_canceled = true; } - if ( canceled_goal ) - { - self notify( "goal" ); - } - return canceled_goal; + return goal_canceled; } bot_powerup_should_postpone() @@ -204,7 +197,6 @@ bot_revive_player() self endon( "disconnect" ); self endon( "revive_end_think" ); - self endon( "bot_in_invalid_state" ); level endon( "end_game" ); player_to_revive_obj = self.available_revives[ 0 ]; @@ -212,7 +204,7 @@ bot_revive_player() player_to_revive = player_to_revive_obj.target_ent; self bot_set_objective( "revive", player_to_revive ); self bot_set_objective_owner( "revive", player_to_revive ); - bot_objective_print( "revive", player_to_revive_obj.id, "Bot <" + self.playername + "> objective started", "bot_revive_player" ); + self bot_objective_print( "revive", player_to_revive_obj.id, "Bot <" + self.playername + "> objective started", "bot_revive_player" ); //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 ( true ) @@ -227,7 +219,7 @@ bot_revive_player() if ( result != "goal" ) { - bot_objective_print( "revive", player_to_revive_obj.id, "Bot <" + self.playername + "> bad path", "bot_revive_player" ); + self bot_objective_print( "revive", player_to_revive_obj.id, "Bot <" + self.playername + "> bad path", "bot_revive_player" ); continue; } if ( !isDefined( player_to_revive.revivetrigger ) ) @@ -265,16 +257,12 @@ bot_revive_process_order() bot_revive_player_init() { - self.should_cancel_revive_obj = false; self.successfully_revived_player = false; } bot_revive_player_post_think( state ) { - obj = self bot_get_objective(); - revive_obj_ent = obj.target_ent; - self bot_post_think_common( state, revive_obj_ent ); - self.should_cancel_revive_obj = false; + self bot_post_think_common( state ); self.successfully_revived_player = false; } @@ -300,6 +288,10 @@ bot_should_revive_player() { continue; } + if ( !isDefined( generatePath( self.origin, obj.target_ent.origin, self.team, level.bot_allowed_negotiation_links ) ) ) + { + continue; + } self.available_revives[ self.available_revives.size ] = obj; } return self.available_revives.size > 0; @@ -325,10 +317,6 @@ bot_revive_player_should_cancel() self.obj_cancel_reason = "No longer the obj owner"; goal_canceled = true; } - if ( goal_canceled ) - { - self notify( "goal" ); - } return goal_canceled; } @@ -344,24 +332,101 @@ bot_revive_player_priority() bot_magicbox_purchase() { - self.target_pos = self.available_chests[ 0 ].origin; + if ( !isDefined( self.available_chests ) || self.available_chests.size <= 0 ) + { + return; + } + + self endon( "disconnect" ); + self endon( "magicbox_end_think" ); + level endon( "end_game" ); + + magicbox_obj = self.available_chests[ 0 ]; + + magicbox = magicbox_obj.target_ent; + self bot_set_objective( "magicbox", magicbox ); + self bot_set_objective_owner( "magicbox", magicbox ); + self bot_objective_print( "magicbox", magicbox_obj.id, "Bot <" + self.playername + "> objective started", "bot_magicbox_purchase" ); + magicbox_obj.magicbox_weapon_spawn_time = undefined; + magicbox_obj.magicbox_weapon_string = undefined; + while ( true ) + { + wait 1; + self ClearScriptAimPos(); + self SetPriorityObjective(); + self SetScriptGoal( magicbox.bot_use_node, 32 ); + + result = self waittill_any_return( "goal", "bad_path", "new_goal" ); + + if ( result != "goal" ) + { + self bot_objective_print( "magicbox", magicbox_obj.id, "Bot <" + self.playername + "> bad path", "bot_magicbox_purchase" ); + continue; + } + + self SetScriptAimPos( magicbox.origin ); + + self thread BotPressUse( 0.1 ); + wait 0.1; + waittillframeend; + if ( !magicbox._box_open ) + { + self bot_objective_print( "magicbox", magicbox_obj.id, "Bot <" + self.playername + "> magicbox didn't open", "bot_magicbox_purchase" ); + continue; + } + // self ClearScriptGoal(); + // self ClearScriptAimPos(); + // self ClearPriorityObjective(); + break; + } + + while ( !isDefined( magicbox.weapon_spawn_org ) ) + { + wait 0.05; + } + magicbox.weapon_spawn_org waittill( "randomization_done" ); + + magicbox_obj.magicbox_weapon_spawn_time = getTime(); + magicbox_obj.magicbox_weapon_string = magicbox.weapon_string; + + //Pickup logic + while ( true ) + { + wait 1; + self ClearScriptAimPos(); + self SetPriorityObjective(); + self SetScriptGoal( magicbox.bot_use_node, 32 ); + + result = self waittill_any_return( "goal", "bad_path", "new_goal" ); + + if ( result != "goal" ) + { + self bot_objective_print( "magicbox", magicbox_obj.id, "Bot <" + self.playername + "> bad path on pickup", "bot_magicbox_purchase" ); + continue; + } + + self SetScriptAimPos( magicbox.origin ); + + self thread BotPressUse( 0.1 ); + wait 0.1; + waittillframeend; + } } bot_magicbox_purchase_process_order() { - + return 0; } bot_magicbox_purchase_init() { - + self.successfully_grabbed_magicbox_weapon = false; } bot_magicbox_purchase_post_think( state ) { - obj = self bot_get_objective(); - magicbox_obj_ent = obj.target_ent; - self bot_post_think_common( state, magicbox_obj_ent ); + self bot_post_think_common( state ); + self.successfully_grabbed_magicbox_weapon = false; } bot_should_purchase_magicbox() @@ -371,49 +436,72 @@ bot_should_purchase_magicbox() { return false; } - if ( !level.enable_magic ) - { - return false; - } - if ( level.chests.size <= 0 ) + if ( isDefined( level.enable_magic ) && !level.enable_magic ) { return false; } self.available_chests = []; + magicbox_objs_keys = getArrayKeys( magicbox_objs ); for ( i = 0; i < magicbox_objs.size; i++ ) { - if ( level.chests[ i ].hidden ) + obj = magicbox_objs[ magicbox_objs_keys[ i ] ]; + magicbox = obj.target_ent; + if ( magicbox.hidden ) { + self bot_objective_print( "magicbox", obj.id, "Bot <" + self.playername + "> not purchasing this magicbox box because it is hidden", "bot_should_purchase_magicbox" ); continue; } - if ( self.score < level.chests[ i ].zombie_cost ) + if ( isDefined( obj.owner ) ) { + self bot_objective_print( "magicbox", obj.id, "Bot <" + self.playername + "> not purchasing this magicbox box because it has an owner", "bot_should_purchase_magicbox" ); 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 ( self.score < magicbox.zombie_cost ) { - if ( isDefined( self.available_chests[ i ].chest_user ) ) - { - maps\_utility::array_remove_index( self.available_chests, i ); - i--; - } + self bot_objective_print( "magicbox", obj.id, "Bot <" + self.playername + "> not purchasing this magicbox box because it is unaffordable", "bot_should_purchase_magicbox" ); + continue; } + if ( !isDefined( generatePath( self.origin, magicbox.bot_use_node, self.team, level.bot_allowed_negotiation_links ) ) ) + { + self bot_objective_print( "magicbox", obj.id, "Bot <" + self.playername + "> not purchasing this magicbox box because it cannot be pathed to", "bot_should_purchase_magicbox" ); + continue; + } + self.available_chests[ self.available_chests.size ] = obj; } return self.available_chests.size > 0; } bot_check_complete_purchase_magicbox() +{ + return self.successfully_grabbed_magicbox_weapon; +} + +bot_should_reject_magicbox_weapon( obj ) { return false; } bot_magicbox_purchase_should_cancel() { - return false; + obj = self bot_get_objective(); + + goal_canceled = false; + if ( !self bot_is_objective_owner( "magicbox", obj.target_ent ) ) + { + self.obj_cancel_reason = "No longer the obj owner"; + goal_canceled = true; + } + else if ( isDefined( obj.magicbox_weapon_string ) && self bot_should_reject_magicbox_weapon( obj ) ) + { + self.obj_cancel_reason = "Rejected magicbox weapon: " + obj.magicbox_weapon_string; + goal_canceled = true; + } + else if ( isDefined( obj.magicbox_weapon_spawn_time ) && ( getTime() >= ( obj.magicbox_weapon_spawn_time + 12000 ) ) ) + { + self.obj_cancel_reason = "Weapon timed out"; + goal_canceled = true; + } + return goal_canceled; } bot_magicbox_purchase_should_postpone() @@ -423,6 +511,7 @@ bot_magicbox_purchase_should_postpone() bot_magicbox_purchase_priority() { + /* priority = 0; LOW_AMMO_THRESHOLD = 0.3; weapons = self getWeaponsListPrimaries(); @@ -438,4 +527,6 @@ bot_magicbox_purchase_priority() } } return priority; + */ + return 0; } \ No newline at end of file diff --git a/maps/bots/script_objectives/_obj_common.gsc b/maps/bots/script_objectives/_obj_common.gsc index 51e6d66..2361f53 100644 --- a/maps/bots/script_objectives/_obj_common.gsc +++ b/maps/bots/script_objectives/_obj_common.gsc @@ -47,6 +47,8 @@ add_possible_bot_objective( objective_group, target_ent, is_global_shared ) objective_struct.id = id; level.zbot_objective_glob[ objective_group ].active_objectives[ "obj_id_" + id ] = objective_struct; + + return level.zbot_objective_glob[ objective_group ].active_objectives[ "obj_id_" + id ]; } get_objective( objective_group, ent, id ) @@ -69,7 +71,7 @@ bot_has_objective() return isDefined( self.zbot_current_objective ); } -bot_set_objective( objective_group, ent ) +bot_set_objective( objective_group, ent, id ) { objective = get_objective_safe( objective_group, ent, id, "bot_set_objective" ); if ( !isDefined( objective ) ) @@ -100,82 +102,16 @@ bot_set_objective( objective_group, ent ) bot_clear_objective() { + objective = self.zbot_current_objective; + if ( !isDefined( objective ) ) + { + return; + } + self bot_clear_objective_owner( objective.group, objective.target_ent ); self.zbot_current_objective = undefined; } -objective_set_blocked( 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_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; - } -} - -objective_remove_blocked() -{ - -} - -objective_has_owner( objective_group, ent ) +objective_has_owner( objective_group, ent, id ) { objective = get_objective_safe( objective_group, ent, id, "objective_has_owner" ); if ( !isDefined( objective ) ) @@ -183,18 +119,21 @@ objective_has_owner( objective_group, ent ) return false; } - id = ent getEntityNumber(); + if ( !isDefined( id ) ) + { + id = ent getEntityNumber(); + } if ( !objective.is_global_shared ) { - objective_assert( objective_group, id, "objective_has_owner", "Objective with " + id + " id number cannot be set to have an owner because is_global_shared field is false in group " + objective_group ) + objective_assert( objective_group, id, "objective_has_owner", "Objective with " + id + " id number cannot be set to have an owner because is_global_shared field is false in group " + objective_group ); return false; } return isDefined( objective.owner ); } -bot_is_objective_owner( objective_group, ent ) +bot_is_objective_owner( objective_group, ent, id ) { objective = get_objective_safe( objective_group, ent, id, "bot_is_objective_owner" ); if ( !isDefined( objective ) ) @@ -202,18 +141,21 @@ bot_is_objective_owner( objective_group, ent ) return false; } - id = ent getEntityNumber(); + if ( !isDefined( id ) ) + { + id = ent getEntityNumber(); + } if ( !objective.is_global_shared ) { - objective_assert( objective_group, id, "bot_is_objective_owner", "Objective with " + id + " id number cannot be set to have an owner because is_global_shared field is false in group " + objective_group ) + objective_assert( objective_group, id, "bot_is_objective_owner", "Objective with " + id + " id number cannot be set to have an owner because is_global_shared field is false in group " + objective_group ); return false; } return isDefined( objective.owner ) && objective.owner == self; } -bot_set_objective_owner( objective_group, ent ) +bot_set_objective_owner( objective_group, ent, id ) { objective = get_objective_safe( objective_group, ent, id, "bot_set_objective_owner" ); if ( !isDefined( objective ) ) @@ -221,18 +163,42 @@ bot_set_objective_owner( objective_group, ent ) return; } - id = ent getEntityNumber(); - + if ( !isDefined( id ) ) + { + id = ent getEntityNumber(); + } + if ( !objective.is_global_shared ) { - objective_assert( objective_group, id, "bot_set_objective_owner", "Objective with " + id + " id number cannot be set to have an owner because is_global_shared field is false in group " + objective_group ) + objective_assert( objective_group, id, "bot_set_objective_owner", "Objective with " + id + " id number cannot be set to have an owner because is_global_shared field is false in group " + objective_group ); return; } objective.owner = self; } -mark_objective_bad( objective_group, ent ) +bot_clear_objective_owner( objective_group, ent, id ) +{ + objective = get_objective_safe( objective_group, ent, id, "clear_objective_owner" ); + if ( !isDefined( objective ) ) + { + return; + } + + if ( !isDefined( objective.owner ) ) + { + return; + } + + if ( objective.owner != self ) + { + return; + } + + objective.owner = undefined; +} + +mark_objective_bad( objective_group, ent, id ) { objective = get_objective_safe( objective_group, ent, id, "mark_objective_bad" ); if ( !isDefined( objective ) ) @@ -249,6 +215,10 @@ free_bot_objective( objective_group, ent, id ) { return; } + if ( isDefined( ent ) ) + { + id = ent getEntityNumber(); + } players = getPlayers(); for ( i = 0; i < players.size; i++ ) { @@ -300,7 +270,7 @@ bot_objective_print( objective_group, id, message, function_name ) { if ( getDvarInt( "bot_obj_debug_all" ) != 0 || getDvarInt( "bot_obj_debug_" + objective_group ) != 0 ) { - objective_info_print( objective_group, id, function_name, message ); + self objective_info_print( objective_group, id, function_name, message ); } } @@ -311,11 +281,11 @@ objective_assert( objective_group, id, function_name, message ) { if ( !isDefined( id ) ) { - error_message = "ERROR: " + function_name + "() Obj <" + objective_group + "> " + message; + error_message = "BOT_OBJ_ERROR: Time <" + getTime() + "> " + function_name + "() Obj <" + objective_group + "> " + message; } else { - error_message = "ERROR: " + function_name + "() Obj <" + objective_group + "> ent <" + id + "> " + message; + error_message = "BOT_OBJ_ERROR: Time <" + getTime() + "> " + function_name + "() Obj <" + objective_group + "> Ent <" + id + "> " + message; } logprint( error_message + "\n" ); printConsole( error_message ); @@ -324,8 +294,7 @@ objective_assert( objective_group, id, function_name, message ) objective_info_print( objective_group, id, function_name, message ) { - obj = bot_objective_history_get_current(); - message = "INFO: " + function_name + "() Obj <" + objective_group + "> ent <" + id + "> pos <" + obj.ent_end_pos + "> " + message; + message = "BOT_OBJ_INFO: Time <" + getTime() + "> " + function_name + "() Obj <" + objective_group + "> ent <" + id + "> " + message; logprint( message + "\n" ); printConsole( message ); } @@ -346,12 +315,12 @@ bot_objective_history_get_oldest() bot_objective_history_get_current() { - return self.obj_history[ level.bot_obj_history_index ]; + return self.obj_history[ self.bot_obj_history_index ]; } bot_objective_history_get_previous() { - return self.obj_history[ level.bot_obj_history_prev_index ]; + return self.obj_history[ self.bot_obj_history_prev_index ]; } /**********Action Section**********/ @@ -489,7 +458,7 @@ wait_for_action_completion( group_name, action_name ) } self.obj_history[ self.bot_obj_history_index ].end_time = getTime(); - end_time = self.obj_history[ self.bot_obj_history_index ].end_time + end_time = self.obj_history[ self.bot_obj_history_index ].end_time; start_time = self.obj_history[ self.bot_obj_history_index ].start_time; self.obj_history[ self.bot_obj_history_index ].time_spent = end_time - start_time; self.obj_history[ self.bot_obj_history_index ].bot_end_pos = self.origin; @@ -553,42 +522,58 @@ check_if_action_is_completed_in_group( group_name, action_name ) { assert( isDefined( level.zbots_actions[ group_name ][ action_name ].check_if_complete_func ) ); - if ( self [[ level.zbots_actions[ group_name ][ action_name ].check_if_complete_func ]]() ) + is_complete = self [[ level.zbots_actions[ group_name ][ action_name ].check_if_complete_func ]](); + + if ( is_complete ) { self notify( action_name + "_complete" ); } + return is_complete; } check_if_action_should_be_postponed_in_group( group_name, action_name ) { - if ( self [[ level.zbots_actions[ group_name ][ action_name ].should_postpone_func ]]() ) + should_postpone = self [[ level.zbots_actions[ group_name ][ action_name ].should_postpone_func ]](); + if ( should_postpone ) { self notify( action_name + "_postpone" ); + self notify( "goal" ); } + return should_postpone; } check_if_action_should_be_canceled_in_group( group_name, action_name ) { - if ( self [[ level.zbots_actions[ group_name ][ action_name ].should_cancel_func ]]() ) + should_cancel = self [[ level.zbots_actions[ group_name ][ action_name ].should_cancel_func ]](); + if ( should_cancel ) { self notify( action_name + "_cancel" ); + self notify( "goal" ); } + + return should_cancel; } check_if_action_should_be_postponed_globally( group_name, action_name ) { - if ( action_should_be_postponed_global( group_name, action_name ) ) + should_postpone = self action_should_be_postponed_global( group_name, action_name ); + if ( should_postpone ) { self notify( action_name + "_postpone" ); + self notify( "goal" ); } + return should_postpone; } check_if_action_should_be_canceled_globally( group_name, action_name ) { - if ( action_should_be_canceled_global( group_name, action_name ) ) + should_cancel = self action_should_be_canceled_global( group_name, action_name ); + if ( should_cancel ) { self notify( action_name + "_cancel" ); + self notify( "goal" ); } + return should_cancel; } //TODO: Figure out way of overriding the current action for flee movement action @@ -618,7 +603,14 @@ bot_action_think() while ( true ) { - wait 0.05; + if ( getDvarInt( "bot_obj_debug_all" ) != 0 ) + { + wait 1; + } + else + { + wait 0.05; + } //Wait until the end of the frame so any variables set by _bot_internal in the current frame will have up to date values waittillframeend; @@ -642,12 +634,31 @@ bot_action_think() action_name = self.action_queue[ group_name ][ 0 ].action_name; - self check_if_action_is_completed_in_group( group_name, action_name ); - self check_if_action_should_be_postponed_in_group( group_name, action_name ); - self check_if_action_should_be_canceled_in_group( group_name, action_name ); - - self check_if_action_should_be_postponed_globally( group_name, action_name ); - self check_if_action_should_be_canceled_globally( group_name, action_name ); + if ( self check_if_action_is_completed_in_group( group_name, action_name ) ) + { + wait 0.1; + continue; + } + if ( self check_if_action_should_be_postponed_globally( group_name, action_name ) ) + { + wait 0.1; + continue; + } + if ( self check_if_action_should_be_canceled_globally( group_name, action_name ) ) + { + wait 0.1; + continue; + } + if ( self check_if_action_should_be_postponed_in_group( group_name, action_name ) ) + { + wait 0.1; + continue; + } + if ( self check_if_action_should_be_canceled_in_group( group_name, action_name ) ) + { + wait 0.1; + continue; + } } } @@ -671,9 +682,14 @@ action_should_be_canceled_global( primary_group_name, action_name ) self.obj_cancel_reason = "Obj entity doesn't exist"; canceled_goal = true; } - else if ( self GetPathIsInaccessible( obj.target_ent.origin ) ) + else if ( !isDefined( obj.target_ent.bot_use_node ) && self GetPathIsInaccessible( obj.target_ent.origin ) ) { - self.obj_cancel_reason = "Path was inaccessible"; + self.obj_cancel_reason = "Path to ent was inaccessible"; + goal_canceled = true; + } + else if ( isDefined( obj.target_ent.bot_use_node ) && self GetPathIsInaccessible( obj.target_ent.bot_use_node ) ) + { + self.obj_cancel_reason = "Path to use node was inaccessible"; goal_canceled = true; } else if ( obj.bad ) @@ -683,12 +699,24 @@ action_should_be_canceled_global( primary_group_name, action_name ) } else if ( !maps\so\zm_common\_zm_utility::is_player_valid( self ) ) { - self.obj_cancel_reason = "In laststand"; + self.obj_cancel_reason = "In invalid state"; goal_canceled = true; } - if ( goal_canceled ) - { - self notify( "goal" ); - } return goal_canceled; +} + +get_angle_offset_node( ent, angle_offset, forward_size, offset ) +{ + angles = ent.angles; + angles += angle_offset; + angles = ( 0, AngleClamp180( angles[ 1 ] ), 0 ); + node = ent.origin + ( AnglesToForward( angles ) * forward_size ); + node = clamp_to_ground( node ) + offset; + return node; +} + +clamp_to_ground( org ) +{ + trace = playerPhysicsTrace( org + ( 0, 0, 20 ), org - ( 0, 0, 2000 ) ); + return trace; } \ No newline at end of file diff --git a/maps/bots/script_objectives/_obj_init.gsc b/maps/bots/script_objectives/_obj_init.gsc index 5297846..a69feee 100644 --- a/maps/bots/script_objectives/_obj_init.gsc +++ b/maps/bots/script_objectives/_obj_init.gsc @@ -38,18 +38,22 @@ init() ::bot_magicbox_purchase_should_cancel, ::bot_magicbox_purchase_should_postpone, ::bot_magicbox_purchase_priority ); - register_bot_objective( "powerup" ); - register_bot_objective( "revive" ); + register_bot_objective( "magicbox" ); + register_bot_objective( "wallbuy" ); + register_bot_objective( "wallbuyammo" ); + register_bot_objective( "perk" ); + register_bot_objective( "door" ); + register_bot_objective( "debris" ); + register_bot_objective( "trap" ); + register_bot_objective( "packapunch" ); + register_bot_objective( "revive" ); + //register_bot_objective( "grabbuildable" ); + //register_bot_objective( "buildbuildable" ); + //register_bot_objective( "part" ); + register_bot_objective( "powerup" ); - if ( isDefined( level.chests ) && level.chests.size > 0 ) - { - level thread watch_magicbox_objectives(); - } - - //maps\bots\script_objectives\_obj_trackers; - level thread store_powerups_dropped(); - level thread watch_for_downed_players(); + create_static_objectives(); } connected() @@ -57,11 +61,10 @@ connected() self endon( "disconnect" ); self thread initialize_bot_actions_queue(); - self thread bot_valid_pump(); - //self thread bot_objective_inaccessible_pump(); self.on_powerup_grab_func = ::bot_on_powerup_grab; self.on_revive_success_func = ::bot_on_revive_success; + self.on_magicbox_weapon_grab_func = ::bot_on_magicbox_weapon_grab; self.obj_postponed_reason = ""; self.obj_cancel_reason = ""; @@ -79,6 +82,7 @@ spawned() self endon( "zombified" ); self thread bot_action_think(); + //self thread cleanup_on_disconnect(); } start_bot_threads() diff --git a/maps/bots/script_objectives/_obj_trackers.gsc b/maps/bots/script_objectives/_obj_trackers.gsc index e0e3698..f9b4c58 100644 --- a/maps/bots/script_objectives/_obj_trackers.gsc +++ b/maps/bots/script_objectives/_obj_trackers.gsc @@ -3,6 +3,94 @@ #include maps\bots\_bot_utility; #include maps\bots\script_objectives\_obj_common; +create_static_objectives() +{ + weapon_spawns = GetEntArray( "weapon_upgrade", "targetname" ); + + if ( isDefined( weapon_spawns ) && weapon_spawns.size > 0 ) + { + for( i = 0; i < weapon_spawns.size; i++ ) + { + obj = add_possible_bot_objective( "wallbuy", weapon_spawns[ i ], false ); + obj = add_possible_bot_objective( "wallbuyammo", weapon_spawns[ i ], false ); + } + } + + vending_triggers = GetEntArray( "zombie_vending", "targetname" ); + + if ( isDefined( vending_triggers ) && vending_triggers.size > 0 ) + { + for ( i = 0; i < vending_triggers.size; i++ ) + { + obj = add_possible_bot_objective( "perk", vending_triggers[ i ], false ); + } + } + + //TODO: See if its possible to automatically detect if a door is blocking an objective + zombie_doors = GetEntArray( "zombie_door", "targetname" ); + + if ( isDefined( zombie_doors ) && zombie_doors.size > 0 ) + { + for ( i = 0; i < zombie_doors.size; i++ ) + { + obj = add_possible_bot_objective( "door", zombie_doors[ i ], true ); + } + level thread watch_door_objectives( zombie_doors ); + } + + zombie_debris = GetEntArray( "zombie_debris", "targetname" ); + + if ( isDefined( zombie_debris ) && zombie_debris.size > 0 ) + { + for ( i = 0; i < zombie_debris.size; i++ ) + { + obj = add_possible_bot_objective( "debris", zombie_debris[ i ], true ); + } + level thread watch_debris_objectives( zombie_debris ); + } + + vending_upgrade_trigger = GetEntArray("zombie_vending_upgrade", "targetname"); + + if ( isDefined( vending_upgrade_trigger ) && vending_upgrade_trigger.size > 0 ) + { + for ( i = 0; i < vending_upgrade_trigger.size; i++ ) + { + obj = add_possible_bot_objective( "packapunch", vending_upgrade_trigger[ i ], false ); + } + } + + if ( isDefined( level.chests ) && level.chests.size > 0 ) + { + level thread watch_magicbox_objectives(); + } + + //maps\bots\script_objectives\_obj_trackers; + level thread store_powerups_dropped(); + level thread watch_for_downed_players(); +} + +watch_door_objectives( zombie_doors ) +{ + level endon( "end_game" ); + + for ( doors_opened_count = 0; doors_opened_count < zombie_doors.size; doors_opened_count++ ) + { + level waittill( "door_opened", door, player ); + free_bot_objective( "door", door ); + } +} + +watch_debris_objectives( zombie_debris ) +{ + level endon( "end_game" ); + + for ( debris_opened_count = 0; debris_opened_count < zombie_debris.size; debris_opened_count++ ) + { + level waittill( "debris_opened", debris, player ); + free_bot_objective( "debris", debris ); + } +} + store_powerups_dropped() { level endon( "end_game" ); @@ -18,7 +106,8 @@ store_powerups_dropped() { continue; } - add_possible_bot_objective( "powerup", powerup, true ); + obj = add_possible_bot_objective( "powerup", powerup, true ); + obj.accessible = true; //maps\bots\_bot_utility::assign_priority_to_powerup( powerup ); //level.zbots_powerups = maps\bots\_bot_utility::sort_array_by_priority_field( level.zbots_powerups, powerup ); } @@ -31,7 +120,9 @@ free_powerups_dropped() while ( true ) { level waittill( "powerup_freed", powerup ); - free_bot_objective( "powerup", powerup ); + id = powerup getEntityNumber(); + waittillframeend; + free_bot_objective( "powerup", powerup, id ); } } @@ -46,7 +137,8 @@ watch_for_downed_players() { continue; } - add_possible_bot_objective( "revive", player, true ); + obj = add_possible_bot_objective( "revive", player, true ); + obj.accessible = true; player thread free_revive_objective_when_needed(); } } @@ -55,114 +147,70 @@ free_revive_objective_when_needed() { level endon( "end_game" ); - id = self.id; - while ( isDefined( self ) && isDefined( self.revivetrigger ) ) - { - wait 0.05; - } + id = self getEntityNumber(); + self waittill_any( "disconnect", "zombified", "player_revived" ); + + waittillframeend; free_bot_objective( "revive", self, id ); } -bot_valid_pump() -{ - level endon( "end_game" ); - - obj_sav = undefined; - - while ( true ) - { - obj_sav = self.zbot_current_objective; - wait 0.5; - if ( !maps\so\zm_common\_zm_utility::is_player_valid( self ) ) - { - if ( isDefined( self ) ) - { - self notify( "bot_in_invalid_state" ); - self bot_clear_objective(); - } - else if ( isDefined( obj_sav ) ) - { - //set_bot_global_shared_objective_owner_by_ent( obj_sav.group, obj_sav.target_ent, undefined ); - } - - while ( isDefined( self ) && !maps\so\zm_common\_zm_utility::is_player_valid( self ) ) - { - wait 0.5; - } - if ( !isDefined( self ) ) - { - return; - } - } - } -} - -bot_objective_inaccessible_pump() -{ - self endon( "disconnect" ); - level endon( "end_game" ); - - while ( true ) - { - invalid_obj = false; - wait 0.5; - while ( !self bot_has_objective() ) - { - wait 0.5; - } - - while ( self bot_has_objective() ) - { - wait 1; - obj = self bot_get_objective(); - - if ( !isDefined( obj ) || !isDefined( obj.target_ent ) ) - { - invalid_obj = true; - } - else if ( !isDefined( generatePath( self.origin, obj.target_ent.origin, self.team, level.bot_allowed_negotiation_links ) ) ) - { - invalid_obj = true; - } - if ( invalid_obj ) - { - self notify( "bot_objective_inaccessible" ); - self.bot.path_inaccessible = true; - break; - } - } - } -} - watch_magicbox_objectives() { level endon( "end_game" ); level waittill( "connected", player ); - prev_magicbox = maps\so\zm_common\_zm_magicbox::get_active_magicbox(); + cur_magicbox = maps\so\zm_common\_zm_magicbox::get_active_magicbox(); + add_possible_bot_objective( "magicbox", cur_magicbox, true ); + cur_magicbox.bot_use_node = get_angle_offset_node( cur_magicbox maps\so\zm_common\_zm_magicbox::get_chest_pieces()[ 1 ], ( 0, 90, 0 ), 40, ( 0, 0, 1 ) ); + + cur_magicbox thread magicbox_debug(); + while ( true ) { - cur_magicbox = maps\so\zm_common\_zm_magicbox::get_active_magicbox(); - if ( prev_magicbox != cur_magicbox ) - { - add_possible_bot_objective( "magicbox", cur_magicbox, false ); - free_bot_objective( "magicbox", prev_magicbox ); - prev_magicbox = cur_magicbox; - } - wait 1; + level waittill( "magicbox_teddy_bear", old_magicbox ); + waittillframeend; + free_bot_objective( "magicbox", old_magicbox ); + level waittill( "new_magicbox", new_magicbox ); + add_possible_bot_objective( "magicbox", new_magicbox, true ); + new_magicbox.bot_use_node = get_angle_offset_node( new_magicbox maps\so\zm_common\_zm_magicbox::get_chest_pieces()[ 1 ], ( 0, 90, 0 ), 40, ( 0, 0, 1 ) ); + new_magicbox thread magicbox_debug(); + } +} + +magicbox_debug() +{ + self notify( "magicbox_debug" ); + self endon( "magicbox_debug"); + level endon( "magicbox_teddy_bear" ); + if ( getDvarInt( "bot_obj_debug_all" ) == 0 && getDvarInt( "bot_obj_debug_magicbox" ) == 0 ) + { + return; + } + while ( true ) + { + node = get_angle_offset_node( self maps\so\zm_common\_zm_magicbox::get_chest_pieces()[ 1 ], ( 0, 90, 0 ), getDvarInt( "magicbox_node_forward_size" ), ( 0, 0, 1 ) ); + self.bot_use_node = node; + line( self.origin, node, ( 1.0, 1.0, 1.0 ) ); + wait 0.05; } } bot_on_powerup_grab( powerup ) { - bot_objective_print( "powerup", powerup getEntityNumber(), "Bot <" + self.playername + "> grabbed powerup" ); + self bot_objective_print( "powerup", powerup getEntityNumber(), "bot_on_powerup_grab", "Bot <" + self.playername + "> grabbed powerup" ); self.successfully_grabbed_powerup = true; } bot_on_revive_success( revivee ) { - bot_objective_print( "revive", revivee getEntityNumber(), "Bot <" + self.playername + "> revived <" + revivee.playername + ">" ); + self bot_objective_print( "revive", revivee getEntityNumber(), "bot_on_revive_success", "Bot <" + self.playername + "> revived <" + revivee.playername + ">" ); self.successfully_revived_player = true; +} + +bot_on_magicbox_weapon_grab( magicbox, weapon ) +{ + self bot_objective_print( "magicbox", magicbox getEntityNumber(), "bot_on_magicbox_weapon_grab", "Bot <" + self.playername + "> grabbed <" + weapon + "> from the box" ); + self.successfully_grabbed_magicbox_weapon = true; } \ No newline at end of file