diff --git a/common/main/ai.h b/common/main/ai.h index 323fa9c22..8345f2e54 100644 --- a/common/main/ai.h +++ b/common/main/ai.h @@ -46,6 +46,22 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. namespace dcx { struct point_seg; + +struct awareness_event +{ + segnum_t segnum; // segment the event occurred in + player_awareness_type_t type; // type of event, defines behavior + vms_vector pos; // absolute 3 space location of event +}; + +struct d_level_unique_robot_awareness_state +{ + unsigned Num_awareness_events; + array Awareness_events; +}; + +extern d_level_unique_robot_awareness_state LevelUniqueRobotAwarenessState; + } struct PHYSFS_File; @@ -89,7 +105,7 @@ extern const object *Ai_last_missile_camera; #endif namespace dsx { -void create_awareness_event(vmobjptr_t objp, player_awareness_type_t type); // object *objp can create awareness of player, amount based on "type" +void create_awareness_event(vmobjptr_t objp, player_awareness_type_t type, d_level_unique_robot_awareness_state &LevelUniqueRobotAwarenessState); // object *objp can create awareness of player, amount based on "type" ai_mode ai_behavior_to_mode(ai_behavior behavior); void do_ai_robot_hit(vmobjptridx_t robot, player_awareness_type_t type); void init_ai_object(vmobjptridx_t objp, ai_behavior initial_mode, imsegidx_t hide_segment); diff --git a/similar/main/ai.cpp b/similar/main/ai.cpp index 5878261fd..6fb02a3b5 100644 --- a/similar/main/ai.cpp +++ b/similar/main/ai.cpp @@ -79,6 +79,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "u_mem.h" //end addition -MM +#include "compiler-exchange.h" #include "compiler-range_for.h" #include "segiter.h" #include "d_enumerate.h" @@ -209,6 +210,8 @@ segnum_t Believed_player_seg; } #endif +namespace dcx { + namespace { struct robot_to_player_visibility_state @@ -218,16 +221,14 @@ struct robot_to_player_visibility_state uint8_t initialized = 0; }; -constexpr std::integral_constant MAX_AWARENESS_EVENTS{}; -struct awareness_event +struct awareness_t : array { - segnum_t segnum; // segment the event occurred in - player_awareness_type_t type; // type of event, defines behavior - vms_vector pos; // absolute 3 space location of event }; } +} + static int ai_evaded; // These globals are set by a call to find_vector_intersection, which is a slow routine, @@ -236,9 +237,6 @@ static vms_vector Hit_pos; static int Hit_type; static fvi_info Hit_data; -static unsigned Num_awareness_events; -static array Awareness_events; - namespace dcx { vms_vector Believed_player_pos; @@ -1209,7 +1207,7 @@ player_led: ; multi_send_robot_fire(obj, obj->ctype.ai_info.CURRENT_GUN, fire_vec); } - create_awareness_event(obj, player_awareness_type_t::PA_NEARBY_ROBOT_FIRED); + create_awareness_event(obj, player_awareness_type_t::PA_NEARBY_ROBOT_FIRED, LevelUniqueRobotAwarenessState); set_next_fire_time(obj, ailp, robptr, gun_num); @@ -4349,7 +4347,7 @@ void init_ai_for_ship() // ---------------------------------------------------------------------------- // Returns false if awareness is considered too puny to add, else returns true. -static int add_awareness_event(const object_base &objp, player_awareness_type_t type) +static int add_awareness_event(const object_base &objp, player_awareness_type_t type, d_level_unique_robot_awareness_state &awareness) { // If player cloaked and hit a robot, then increase awareness if (type == player_awareness_type_t::PA_WEAPON_ROBOT_COLLISION || @@ -4357,14 +4355,15 @@ static int add_awareness_event(const object_base &objp, player_awareness_type_t type == player_awareness_type_t::PA_PLAYER_COLLISION) ai_do_cloak_stuff(); - if (Num_awareness_events < MAX_AWARENESS_EVENTS) { + if (awareness.Num_awareness_events < awareness.Awareness_events.size()) + { if (type == player_awareness_type_t::PA_WEAPON_WALL_COLLISION || type == player_awareness_type_t::PA_WEAPON_ROBOT_COLLISION) if (objp.type == OBJ_WEAPON && get_weapon_id(objp) == weapon_id_type::VULCAN_ID) if (d_rand() > 3276) return 0; // For vulcan cannon, only about 1/10 actually cause awareness - auto &e = Awareness_events[Num_awareness_events++]; + auto &e = awareness.Awareness_events[awareness.Num_awareness_events++]; e.segnum = objp.segnum; e.pos = objp.pos; e.type = type; @@ -4380,12 +4379,13 @@ static int add_awareness_event(const object_base &objp, player_awareness_type_t // ---------------------------------------------------------------------------------- // Robots will become aware of the player based on something that occurred. // The object (probably player or weapon) which created the awareness is objp. -void create_awareness_event(const vmobjptr_t objp, player_awareness_type_t type) +void create_awareness_event(const vmobjptr_t objp, player_awareness_type_t type, d_level_unique_robot_awareness_state &LevelUniqueRobotAwarenessState) { // If not in multiplayer, or in multiplayer with robots, do this, else unnecessary! if (!(Game_mode & GM_MULTI) || (Game_mode & GM_MULTI_ROBOTS)) { - if (add_awareness_event(objp, type)) { + if (add_awareness_event(objp, type, LevelUniqueRobotAwarenessState)) + { if (((d_rand() * (static_cast(type) + 4)) >> 15) > 4) Overall_agitation++; if (Overall_agitation > OVERALL_AGITATION_MAX) @@ -4394,14 +4394,6 @@ void create_awareness_event(const vmobjptr_t objp, player_awareness_type_t type) } } -namespace { - -struct awareness_t : array -{ -}; - -} - // ---------------------------------------------------------------------------------- static void pae_aux(const vcsegptridx_t segnum, const player_awareness_type_t type, const int level, awareness_t &New_awareness) { @@ -4427,24 +4419,23 @@ static void pae_aux(const vcsegptridx_t segnum, const player_awareness_type_t ty // ---------------------------------------------------------------------------------- -static void process_awareness_events(fvcsegptridx &vcsegptridx, awareness_t &New_awareness) +static void process_awareness_events(fvcsegptridx &vcsegptridx, d_level_unique_robot_awareness_state &LevelUniqueRobotAwarenessState, awareness_t &New_awareness) { + const auto Num_awareness_events = exchange(LevelUniqueRobotAwarenessState.Num_awareness_events, 0); if (!(Game_mode & GM_MULTI) || (Game_mode & GM_MULTI_ROBOTS)) { New_awareness.fill(player_awareness_type_t::PA_NONE); - range_for (auto &i, partial_const_range(Awareness_events, Num_awareness_events)) + range_for (auto &i, partial_const_range(LevelUniqueRobotAwarenessState.Awareness_events, Num_awareness_events)) pae_aux(vcsegptridx(i.segnum), i.type, 1, New_awareness); } - - Num_awareness_events = 0; } // ---------------------------------------------------------------------------------- -static void set_player_awareness_all(fvmobjptr &vmobjptr, fvcsegptridx &vcsegptridx) +static void set_player_awareness_all(fvmobjptr &vmobjptr, fvcsegptridx &vcsegptridx, d_level_unique_robot_awareness_state &LevelUniqueRobotAwarenessState) { awareness_t New_awareness; - process_awareness_events(vcsegptridx, New_awareness); + process_awareness_events(vcsegptridx, LevelUniqueRobotAwarenessState, New_awareness); range_for (const auto &&objp, vmobjptr) { @@ -4554,7 +4545,7 @@ void do_ai_frame_all(void) dump_ai_objects_all(); #endif - set_player_awareness_all(vmobjptr, vcsegptridx); + set_player_awareness_all(vmobjptr, vcsegptridx, LevelUniqueRobotAwarenessState); #if defined(DXX_BUILD_DESCENT_II) auto &BossUniqueState = LevelUniqueObjectState.BossState; diff --git a/similar/main/collide.cpp b/similar/main/collide.cpp index 79c2fc401..42c5e7ded 100644 --- a/similar/main/collide.cpp +++ b/similar/main/collide.cpp @@ -403,7 +403,7 @@ static void collide_player_and_wall(const vmobjptridx_t playerobj, const fix hit int volume; volume = (hitspeed-(WALL_DAMAGE_SCALE*WALL_DAMAGE_THRESHOLD)) / WALL_LOUDNESS_SCALE ; - create_awareness_event(playerobj, player_awareness_type_t::PA_WEAPON_WALL_COLLISION); + create_awareness_event(playerobj, player_awareness_type_t::PA_WEAPON_WALL_COLLISION, LevelUniqueRobotAwarenessState); if ( volume > F1_0 ) volume = F1_0; @@ -932,7 +932,7 @@ static window_event_result collide_weapon_and_wall( if (( weapon->ctype.laser_info.parent_type== OBJ_PLAYER ) || robot_escort) { if (!(weapon->flags & OF_SILENT) && (weapon->ctype.laser_info.parent_num == get_local_player().objnum)) - create_awareness_event(weapon, player_awareness_type_t::PA_WEAPON_WALL_COLLISION); // object "weapon" can attract attention to player + create_awareness_event(weapon, player_awareness_type_t::PA_WEAPON_WALL_COLLISION, LevelUniqueRobotAwarenessState); // object "weapon" can attract attention to player // We now allow flares to open doors. { @@ -1052,7 +1052,7 @@ static void collide_robot_and_player(const vmobjptridx_t robot, const vmobjptrid } #endif - create_awareness_event(playerobj, player_awareness_type_t::PA_PLAYER_COLLISION); // object robot can attract attention to player + create_awareness_event(playerobj, player_awareness_type_t::PA_PLAYER_COLLISION, LevelUniqueRobotAwarenessState); // object robot can attract attention to player do_ai_robot_hit_attack(robot, playerobj, collision_point); do_ai_robot_hit(robot, player_awareness_type_t::PA_WEAPON_ROBOT_COLLISION); } @@ -1715,7 +1715,7 @@ static void collide_robot_and_weapon(const vmobjptridx_t robot, const vmobjptri #endif { if (weapon->ctype.laser_info.parent_num == get_local_player().objnum) { - create_awareness_event(weapon, player_awareness_type_t::PA_WEAPON_ROBOT_COLLISION); // object "weapon" can attract attention to player + create_awareness_event(weapon, player_awareness_type_t::PA_WEAPON_ROBOT_COLLISION, LevelUniqueRobotAwarenessState); // object "weapon" can attract attention to player do_ai_robot_hit(robot, player_awareness_type_t::PA_WEAPON_ROBOT_COLLISION); } else diff --git a/similar/main/game.cpp b/similar/main/game.cpp index a492edb6b..46e097ea0 100644 --- a/similar/main/game.cpp +++ b/similar/main/game.cpp @@ -2119,7 +2119,7 @@ bool FireLaser(player_info &player_info) const auto cobjp = vmobjptridx(ConsoleObject); apply_damage_to_player(cobjp, cobjp, d_rand() * 4, 0); } else { - create_awareness_event(vmobjptr(ConsoleObject), player_awareness_type_t::PA_WEAPON_ROBOT_COLLISION); + create_awareness_event(vmobjptr(ConsoleObject), player_awareness_type_t::PA_WEAPON_ROBOT_COLLISION, LevelUniqueRobotAwarenessState); multi_digi_play_sample(SOUND_FUSION_WARMUP, F1_0); } Fusion_next_sound_time = GameTime64 + F1_0/8 + d_rand()/4; diff --git a/similar/main/laser.cpp b/similar/main/laser.cpp index 8df28d602..698560a68 100644 --- a/similar/main/laser.cpp +++ b/similar/main/laser.cpp @@ -1363,7 +1363,7 @@ static imobjptridx_t Laser_player_fire_spread_delay(fvmsegptridx &vmsegptridx, c vms_vector *pnt; #if defined(DXX_BUILD_DESCENT_II) - create_awareness_event(obj, player_awareness_type_t::PA_WEAPON_WALL_COLLISION); + create_awareness_event(obj, player_awareness_type_t::PA_WEAPON_WALL_COLLISION, LevelUniqueRobotAwarenessState); #endif // Find the initial position of the laser diff --git a/similar/main/mglobal.cpp b/similar/main/mglobal.cpp index 4ae057ca0..48174680a 100644 --- a/similar/main/mglobal.cpp +++ b/similar/main/mglobal.cpp @@ -54,6 +54,7 @@ d_interface_unique_state InterfaceUniqueState; d_level_shared_vertex_state LevelSharedVertexState; d_level_unique_automap_state LevelUniqueAutomapState; d_level_unique_fuelcenter_state LevelUniqueFuelcenterState; +d_level_unique_robot_awareness_state LevelUniqueRobotAwarenessState; d_level_unique_segment_state LevelUniqueSegmentState; // Global array of vertices, common to one mine. valptridx::array_managed_type Players;