diff --git a/common/main/fwd-wall.h b/common/main/fwd-wall.h index f47d15b49..bace8965a 100644 --- a/common/main/fwd-wall.h +++ b/common/main/fwd-wall.h @@ -239,7 +239,7 @@ void wall_open_door(vmsegptridx_t seg, int side); #if defined(DXX_BUILD_DESCENT_I) #elif defined(DXX_BUILD_DESCENT_II) // Closes a door -void wall_close_door(fvmwallptr &vmwallptr, vmsegptridx_t seg, unsigned side); +void wall_close_door(wall_array &Walls, vmsegptridx_t seg, unsigned side); #endif } #endif diff --git a/common/main/wall.h b/common/main/wall.h index 35ecec7b6..843528f5e 100644 --- a/common/main/wall.h +++ b/common/main/wall.h @@ -193,7 +193,17 @@ struct cloaking_wall : public prohibit_void_ptr DXX_VALPTRIDX_DEFINE_GLOBAL_FACTORIES(cloaking_wall, clwall, CloakingWalls); #endif -DXX_VALPTRIDX_DEFINE_GLOBAL_FACTORIES(wall, wall, Walls); +struct d_level_unique_wall_state +{ + wall_array Walls; +}; + +struct d_level_unique_wall_subsystem_state : + d_level_unique_wall_state +{ +}; + +extern d_level_unique_wall_subsystem_state LevelUniqueWallSubsystemState; struct wclip : public prohibit_void_ptr { diff --git a/d2x-rebirth/main/escort.cpp b/d2x-rebirth/main/escort.cpp index a2d38d369..e09655c5a 100644 --- a/d2x-rebirth/main/escort.cpp +++ b/d2x-rebirth/main/escort.cpp @@ -236,6 +236,8 @@ static int ok_for_buddy_to_talk(void) const shared_segment &segp = vcsegptr(buddy->segnum); + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; for (int i=0; iunique_segment::sides[sidenum], intensity); diff --git a/similar/editor/eswitch.cpp b/similar/editor/eswitch.cpp index d1dbd23d0..d2b561a8d 100644 --- a/similar/editor/eswitch.cpp +++ b/similar/editor/eswitch.cpp @@ -129,6 +129,8 @@ static int trigger_flag_Markedside(const TRIGGER_FLAG flag, const int value) if (!value && wall_num == wall_none) return 0; auto &Vertices = LevelSharedVertexState.get_vertices(); auto &vcvertptr = Vertices.vcptr; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; const auto trigger_num = value ? add_trigger(Triggers, vcvertptr, Walls, Markedsegp, Markedside) : vcwallptr(wall_num)->trigger; if (trigger_num == trigger_none) { @@ -157,6 +159,8 @@ static int bind_matcen_to_trigger() { editor_status("No wall at Markedside."); return 0; } + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; const auto trigger_num = vcwallptr(wall_num)->trigger; if (trigger_num == trigger_none) { editor_status("No trigger at Markedside."); @@ -200,6 +204,8 @@ int bind_wall_to_trigger() { editor_status("No wall at Markedside."); return 0; } + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; const auto trigger_num = vcwallptr(wall_num)->trigger; if (trigger_num == trigger_none) { editor_status("No trigger at Markedside."); @@ -244,6 +250,8 @@ int remove_trigger_num(int trigger_num) Triggers.set_count(Triggers.get_count() - 1); std::move(std::next(r.begin()), r.end(), r.begin()); + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vmwallptr = Walls.vmptr; range_for (const auto &&w, vmwallptr) { auto &trigger = w->trigger; @@ -268,6 +276,8 @@ unsigned remove_trigger(shared_segment &seg, const unsigned side) return 0; } + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; return remove_trigger_num(vcwallptr(wall_num)->trigger); } @@ -385,6 +395,8 @@ window_event_result trigger_dialog_handler(UI_DIALOG *dlg,const d_event &event, // of the checkboxes that control the wall flags. //------------------------------------------------------------ const auto Markedwall = Markedsegp->shared_segment::sides[Markedside].wall_num; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; const auto trigger_num = (Markedwall != wall_none) ? vcwallptr(Markedwall)->trigger : trigger_none; if (t->old_trigger_num != trigger_num) diff --git a/similar/editor/info.cpp b/similar/editor/info.cpp index 1ae409bbd..daf4fbc41 100644 --- a/similar/editor/info.cpp +++ b/similar/editor/info.cpp @@ -274,6 +274,7 @@ static void info_display_default(grs_canvas &canvas, int show_all) //--------------- Num walls/links/triggers ------------------------- + auto &Walls = LevelUniqueWallSubsystemState.Walls; if ( old_Num_walls != Walls.get_count() ) { old_Num_walls = Walls.get_count(); gr_uprintf(canvas, *canvas.cv_font, 0, 96, "Walls %3d", Walls.get_count()); diff --git a/similar/editor/meddraw.cpp b/similar/editor/meddraw.cpp index 473a2fa8a..f0433bd3a 100644 --- a/similar/editor/meddraw.cpp +++ b/similar/editor/meddraw.cpp @@ -478,6 +478,8 @@ static void draw_wall_side(const shared_segment &seg, const unsigned side, const // Draws special walls (for now these are just removable walls.) static void draw_special_wall(const shared_segment &seg, const unsigned side) { + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; auto &w = *vcwallptr(seg.sides[side].wall_num); const auto get_color = [=]() { const auto type = w.type; diff --git a/similar/editor/medwall.cpp b/similar/editor/medwall.cpp index 1dae8f662..3383bd4c7 100644 --- a/similar/editor/medwall.cpp +++ b/similar/editor/medwall.cpp @@ -131,6 +131,8 @@ static int wall_assign_door(int door_type) return 0; } + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vmwallptr = Walls.vmptr; auto &wall0 = *vmwallptr(sseg.sides[Curside].wall_num); if (wall0.type != WALL_DOOR && wall0.type != WALL_BLASTABLE) { @@ -167,6 +169,7 @@ int wall_add_blastable() { auto &Vertices = LevelSharedVertexState.get_vertices(); auto &vcvertptr = Vertices.vcptr; + auto &Walls = LevelUniqueWallSubsystemState.Walls; return wall_add_to_side(vcvertptr, Walls, Cursegp, Curside, WALL_BLASTABLE); } @@ -174,6 +177,7 @@ int wall_add_door() { auto &Vertices = LevelSharedVertexState.get_vertices(); auto &vcvertptr = Vertices.vcptr; + auto &Walls = LevelUniqueWallSubsystemState.Walls; return wall_add_to_side(vcvertptr, Walls, Cursegp, Curside, WALL_DOOR); } @@ -181,6 +185,7 @@ int wall_add_closed_wall() { auto &Vertices = LevelSharedVertexState.get_vertices(); auto &vcvertptr = Vertices.vcptr; + auto &Walls = LevelUniqueWallSubsystemState.Walls; return wall_add_to_side(vcvertptr, Walls, Cursegp, Curside, WALL_CLOSED); } @@ -206,6 +211,7 @@ int wall_add_illusion() { auto &Vertices = LevelSharedVertexState.get_vertices(); auto &vcvertptr = Vertices.vcptr; + auto &Walls = LevelUniqueWallSubsystemState.Walls; return wall_add_to_side(vcvertptr, Walls, Cursegp, Curside, WALL_ILLUSION); } @@ -214,6 +220,8 @@ static int GotoPrevWall() { shared_segment &sseg = Cursegp; auto &side = sseg.sides[Curside]; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; if (side.wall_num == wall_none) current_wall = Walls.get_count(); else @@ -247,6 +255,8 @@ static int GotoNextWall() { current_wall++; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; if (current_wall >= Walls.get_count()) current_wall = 0; auto &w = *vcwallptr(current_wall); @@ -275,6 +285,8 @@ static int PrevWall() { return 0; } + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; auto &w = *vcwallptr(cur_wall_num); wall_type = w.clip_num; @@ -314,6 +326,8 @@ static int NextWall() { return 0; } + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; auto &w = *vcwallptr(cur_wall_num); wall_type = w.clip_num; @@ -433,6 +447,8 @@ window_event_result wall_dialog_handler(UI_DIALOG *dlg,const d_event &event, wal //------------------------------------------------------------ ui_button_any_drawn = 0; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &imwallptridx = Walls.imptridx; const auto &&w = imwallptridx(Cursegp->shared_segment::sides[Curside].wall_num); //------------------------------------------------------------ // If we change walls, we need to reset the ui code for all @@ -613,6 +629,9 @@ window_event_result wall_dialog_handler(UI_DIALOG *dlg,const d_event &event, wal // Restore all walls to original status (closed doors, repaired walls) int wall_restore_all() { + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; + auto &vmwallptr = Walls.vmptr; range_for (const auto &&wp, vmwallptr) { auto &w = *wp; @@ -664,6 +683,9 @@ int wall_remove_side(const vmsegptridx_t seg, short side) const auto wall1 = csegp.sides[Connectside].wall_num; const auto lower_wallnum = (wall0 < wall1) ? wall0 : wall1; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; + auto &vmwallptr = Walls.vmptr; { const auto linked_wall = vcwallptr(lower_wallnum)->linked_wall; if (linked_wall != wall_none) @@ -879,6 +901,8 @@ int bind_wall_to_control_center() { int wall_link_doors() { const auto cwall_num = Cursegp->shared_segment::sides[Curside].wall_num; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &imwallptr = Walls.imptr; const auto &&w1 = imwallptr(cwall_num); if (!w1 || w1->type != WALL_DOOR) { @@ -914,6 +938,8 @@ int wall_link_doors() int wall_unlink_door() { const auto cwall_num = Cursegp->shared_segment::sides[Curside].wall_num; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &imwallptr = Walls.imptr; const auto &&w1 = imwallptr(cwall_num); if (!w1 || w1->type != WALL_DOOR) { @@ -927,6 +953,7 @@ int wall_unlink_door() return 0; } + auto &vmwallptr = Walls.vmptr; auto &w2 = *vmwallptr(w1->linked_wall); Assert(w2.linked_wall == cwall_num); @@ -969,6 +996,7 @@ int check_walls() } } + auto &Walls = LevelUniqueWallSubsystemState.Walls; if (wall_count != Walls.get_count()) { if (ui_messagebox(-2, -2, 2, "Num_walls is bogus\nDo you wish to correct it?\n", "Yes", "No") == 1) { @@ -978,6 +1006,7 @@ int check_walls() } // Check validity of Walls array. + auto &vmwallptr = Walls.vmptr; range_for (auto &cw, partial_const_range(CountedWalls, Walls.get_count())) { auto &w = *vmwallptr(cw.wallnum); @@ -1019,6 +1048,7 @@ int delete_all_walls() range_for (auto &side, segp.sides) side.wall_num = wall_none; } + auto &Walls = LevelUniqueWallSubsystemState.Walls; Walls.set_count(0); Triggers.set_count(0); @@ -1031,8 +1061,9 @@ int delete_all_walls() // ------------------------------------------------------------------------------------------------ static void copy_old_wall_data_to_new(wallnum_t owall, wallnum_t nwall) { - auto &o = *vcwallptr(owall); - auto &n = *vmwallptr(nwall); + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &o = *Walls.vcptr(owall); + auto &n = *Walls.vmptr(nwall); n.flags = o.flags; n.type = o.type; n.clip_num = o.clip_num; @@ -1053,6 +1084,8 @@ void copy_group_walls(int old_group, int new_group) { group::segment_array_type_t::const_iterator bn = GroupList[new_group].segments.begin(); + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vmwallptr = Walls.vmptr; range_for (const auto old_seg, GroupList[old_group].segments) { const auto new_seg = *bn++; @@ -1084,6 +1117,8 @@ void check_wall_validity(void) if (!Validate_walls) return; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; range_for (const auto &&w, vcwallptr) { segnum_t segnum; diff --git a/similar/editor/mine.cpp b/similar/editor/mine.cpp index f5d5ec258..7ad35d8dd 100644 --- a/similar/editor/mine.cpp +++ b/similar/editor/mine.cpp @@ -371,6 +371,7 @@ static int save_mine_data(PHYSFS_File * SaveFile) newsegment_offset = segment_offset + (sizeof(segment) * LevelSharedSegmentState.Num_segments); newseg_verts_offset = newsegment_offset + sizeof(segment); walls_offset = newseg_verts_offset + (sizeof(vms_vector)*8); + auto &Walls = LevelUniqueWallSubsystemState.Walls; triggers_offset = walls_offset + (sizeof(wall)*Walls.get_count()); //===================== SAVE FILE INFO ======================== diff --git a/similar/editor/segment.cpp b/similar/editor/segment.cpp index 0335908b6..1fc5341df 100644 --- a/similar/editor/segment.cpp +++ b/similar/editor/segment.cpp @@ -463,6 +463,8 @@ static void compress_segments(void) segnum_t hole,seg; seg = Highest_segment_index; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vmwallptr = Walls.vmptr; for (hole=0; hole < seg; hole++) if (Segments[hole].segnum == segment_none) { // found an unused segment which is a hole if a used segment follows (not necessarily immediately) it. diff --git a/similar/editor/seguvs.cpp b/similar/editor/seguvs.cpp index 1e12bfb12..fa690cec3 100644 --- a/similar/editor/seguvs.cpp +++ b/similar/editor/seguvs.cpp @@ -891,6 +891,8 @@ static void cast_light_from_side(const vmsegptridx_t segp, int light_side, fix l int sidenum,vertnum; auto &Vertices = LevelSharedVertexState.get_vertices(); auto &vcvertptr = Vertices.vcptr; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; const auto segment_center = compute_segment_center(vcvertptr, segp); // Do for four lights, one just inside each corner of side containing light. range_for (const auto lightnum, Side_to_verts[light_side]) @@ -1127,6 +1129,8 @@ static void calim_process_all_lights(int quick_light) { int sidenum; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; range_for (const auto &&segp, vmsegptridx) { for (sidenum=0; sidenum seg_queue; @@ -3379,6 +3385,8 @@ _exit_cheat: } else if (ailp.mode != ai_mode::AIM_STILL) { + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; const auto r = openable_doors_in_segment(vcwallptr, vcsegptr(obj->segnum)); if (r != side_none) { @@ -3440,6 +3448,8 @@ _exit_cheat: return; } + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; // More special ability stuff, but based on a property of a robot, not its ID. if (robot_is_companion(robptr)) { diff --git a/similar/main/aipath.cpp b/similar/main/aipath.cpp index 806e0031d..06a1dc819 100644 --- a/similar/main/aipath.cpp +++ b/similar/main/aipath.cpp @@ -331,6 +331,8 @@ if ((objp->type == OBJ_ROBOT) && (objp->ctype.ai_info.behavior == ai_behavior::A auto &LevelSharedVertexState = LevelSharedSegmentState.get_vertex_state(); auto &Vertices = LevelSharedVertexState.get_vertices(); auto &vcvertptr = Vertices.vcptr; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; while (cur_seg != end_seg) { const auto &&segp = vcsegptr(cur_seg); #if defined(DXX_BUILD_DESCENT_II) diff --git a/similar/main/automap.cpp b/similar/main/automap.cpp index 766b66d7f..dafaa925e 100644 --- a/similar/main/automap.cpp +++ b/similar/main/automap.cpp @@ -1452,6 +1452,8 @@ void automap_build_edge_list(automap *am, int add_all_edges) am->num_edges = 0; am->end_valid_edges = 0; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; if (add_all_edges) { // Cheating, add all edges as visited range_for (const auto &&segp, vcsegptridx) diff --git a/similar/main/cntrlcen.cpp b/similar/main/cntrlcen.cpp index 5af4fc40a..7919c6860 100644 --- a/similar/main/cntrlcen.cpp +++ b/similar/main/cntrlcen.cpp @@ -278,6 +278,8 @@ void do_controlcen_destroyed_stuff(const imobjptridx_t objp) return; // Don't allow resetting if control center and boss on same level #endif + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vmwallptr = Walls.vmptr; // Must toggle walls whether it is a boss or control center. for (i=0;itrigger != trigger_none) is_trigger = 1; + } if (trigger_check && is_trigger) return(0); #endif @@ -2229,6 +2233,8 @@ static vms_vector find_exit_direction(vms_vector result, const vcobjptr_t objp, { auto &Vertices = LevelSharedVertexState.get_vertices(); auto &vcvertptr = Vertices.vcptr; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; for (unsigned side = MAX_SIDES_PER_SEGMENT; side --;) if (WALL_IS_DOORWAY(GameBitmaps, Textures, vcwallptr, segp, segp, side) & WID_FLY_FLAG) { @@ -2674,8 +2680,12 @@ window_event_result collide_object_with_wall( case OBJ_FIREBALL: break; //collide_fireball_and_wall(A,hitspeed,hitseg,hitwall,hitpt); case OBJ_ROBOT: + { + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; collide_robot_and_wall(vcwallptr, A, hitseg, hitwall, hitpt); break; + } case OBJ_HOSTAGE: break; //collide_hostage_and_wall(A,hitspeed,hitseg,hitwall,hitpt); case OBJ_CAMERA: break; //collide_camera_and_wall(A,hitspeed,hitseg,hitwall,hitpt); case OBJ_POWERUP: break; //collide_powerup_and_wall(A,hitspeed,hitseg,hitwall,hitpt); diff --git a/similar/main/dumpmine.cpp b/similar/main/dumpmine.cpp index d153e9860..169c367f9 100644 --- a/similar/main/dumpmine.cpp +++ b/similar/main/dumpmine.cpp @@ -594,6 +594,8 @@ static void write_trigger_text(PHYSFS_File *my_file) { PHYSFSX_printf(my_file, "-----------------------------------------------------------------------------\n"); PHYSFSX_printf(my_file, "Triggers:\n"); + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; range_for (auto &&t, vctrgptridx) { const auto i = static_cast(t); @@ -651,6 +653,8 @@ void write_game_text_file(const char *filename) PHYSFSX_printf(my_file, "\nNumber of segments: %4i\n", Highest_segment_index+1); PHYSFSX_printf(my_file, "Number of objects: %4i\n", Highest_object_index+1); + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptridx = Walls.vcptridx; PHYSFSX_printf(my_file, "Number of walls: %4i\n", Walls.get_count()); PHYSFSX_printf(my_file, "Number of open doors: %4i\n", ActiveDoors.get_count()); PHYSFSX_printf(my_file, "Number of triggers: %4i\n", Triggers.get_count()); @@ -734,6 +738,7 @@ static void determine_used_textures_level(d_level_shared_destructible_light_stat int sidenum; int j; + auto &Walls = LevelUniqueWallSubsystemState.Walls; #if defined(DXX_BUILD_DESCENT_I) tmap_buf = {}; diff --git a/similar/main/fireball.cpp b/similar/main/fireball.cpp index b4ed8c758..cb86bf54e 100644 --- a/similar/main/fireball.cpp +++ b/similar/main/fireball.cpp @@ -476,6 +476,8 @@ imsegidx_t pick_connected_segment(const vcsegidx_t start_seg, int max_depth) swap(side_rand[ind1], side_rand[i]); } + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; while (tail != head) { int sidenum, count; int ind1, ind2; @@ -1324,6 +1326,8 @@ void do_exploding_wall_frame(wall &w1) const auto n = WallAnims[a].num_frames; wall_set_tmap_num(WallAnims[a], seg, w1sidenum, csegp, cside, n - 1); + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vmwallptr = Walls.vmptr; auto &w2 = *vmwallptr(csegp->shared_segment::sides[cside].wall_num); assert(&w1 != &w2); assert((w1.flags & WALL_EXPLODING) || (w2.flags & WALL_EXPLODING)); diff --git a/similar/main/fvi.cpp b/similar/main/fvi.cpp index 9e384a914..ffb4c984b 100644 --- a/similar/main/fvi.cpp +++ b/similar/main/fvi.cpp @@ -927,6 +927,8 @@ static int fvi_sub(vms_vector &intp, segnum_t &ints, const vms_vector &p0, const if (face_hit_type) { //through this wall/door + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; auto wid_flag = WALL_IS_DOORWAY(GameBitmaps, Textures, vcwallptr, seg, seg, side); //if what we have hit is a door, check the adjoining seg @@ -1178,7 +1180,11 @@ int check_trans_wall(const vms_vector &pnt,const vcsegptridx_t seg,int sidenum,i int bmx,bmy; #if defined(DXX_BUILD_DESCENT_I) +#ifndef NDEBUG + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; assert(WALL_IS_DOORWAY(GameBitmaps, Textures, vcwallptr, seg, seg, sidenum) == WID_TRANSPARENT_WALL); +#endif #endif const auto hitpoint = find_hitpoint_uv(pnt,seg,sidenum,facenum); // Don't compute light value. diff --git a/similar/main/game.cpp b/similar/main/game.cpp index f105225fd..1af3cd3ab 100644 --- a/similar/main/game.cpp +++ b/similar/main/game.cpp @@ -1982,6 +1982,8 @@ constexpr std::integral_constant flicker_timer_disabled{}; static void flicker_lights(const d_level_shared_destructible_light_state &LevelSharedDestructibleLightState, d_flickering_light_state &fls, fvmsegptridx &vmsegptridx) { + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; range_for (auto &f, partial_range(fls.Flickering_lights, fls.Num_flickering_lights)) { if (f.timer == flicker_timer_disabled) //disabled diff --git a/similar/main/gamecntl.cpp b/similar/main/gamecntl.cpp index 0f08d9e4c..edd5a77f0 100644 --- a/similar/main/gamecntl.cpp +++ b/similar/main/gamecntl.cpp @@ -1078,6 +1078,8 @@ static void kill_and_so_forth(fvmobjptridx &vmobjptridx, fvmsegptridx &vmsegptri do_controlcen_destroyed_stuff(object_none); + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; for (trgnum_t i = 0; i < Triggers.get_count(); i++) { const auto &&t = vctrgptr(i); diff --git a/similar/main/gamemine.cpp b/similar/main/gamemine.cpp index f4ba68909..314536a1e 100644 --- a/similar/main/gamemine.cpp +++ b/similar/main/gamemine.cpp @@ -616,6 +616,8 @@ int load_mine_data(PHYSFS_File *LoadFile) // [commented out by mk on 11/20/94 (weren't we supposed to hit final in October?) because it looks redundant. I think I'll test it now...] fuelcen_reset(); + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; if ( (mine_fileinfo.segment_offset > -1) && (mine_fileinfo.segment_howmany > 0)) { if (PHYSFSX_fseek( LoadFile, mine_fileinfo.segment_offset,SEEK_SET )) diff --git a/similar/main/gamesave.cpp b/similar/main/gamesave.cpp index 54cac6905..6c86e444f 100644 --- a/similar/main/gamesave.cpp +++ b/similar/main/gamesave.cpp @@ -798,6 +798,8 @@ static void validate_segment_wall(const vcsegptridx_t seg, shared_side &side, co { auto &rwn0 = side.wall_num; const auto wn0 = rwn0; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; auto &w0 = *vcwallptr(wn0); switch (w0.type) { @@ -857,6 +859,7 @@ static int load_game_data( PHYSFSX_fseek(LoadFile, 8, SEEK_CUR); init_exploding_walls(); + auto &Walls = LevelUniqueWallSubsystemState.Walls; Walls.set_count(PHYSFSX_readInt(LoadFile)); PHYSFSX_fseek(LoadFile, 20, SEEK_CUR); @@ -937,6 +940,7 @@ static int load_game_data( //===================== READ WALL INFO ============================ + auto &vmwallptr = Walls.vmptr; range_for (const auto &&vw, vmwallptr) { auto &nw = *vw; @@ -1610,6 +1614,7 @@ static int save_game_data( #define WRITE_HEADER_ENTRY(t, n) do { PHYSFS_writeSLE32(SaveFile, -1); PHYSFS_writeSLE32(SaveFile, n); PHYSFS_writeSLE32(SaveFile, sizeof(t)); } while(0) WRITE_HEADER_ENTRY(object, Highest_object_index + 1); + auto &Walls = LevelUniqueWallSubsystemState.Walls; WRITE_HEADER_ENTRY(wall, Walls.get_count()); WRITE_HEADER_ENTRY(active_door, ActiveDoors.get_count()); WRITE_HEADER_ENTRY(trigger, Triggers.get_count()); @@ -1658,6 +1663,7 @@ static int save_game_data( //==================== SAVE WALL INFO ============================= walls_offset = PHYSFS_tell(SaveFile); + auto &vcwallptr = Walls.vcptr; range_for (const auto &&w, vcwallptr) wall_write(SaveFile, *w, game_top_fileinfo_version); diff --git a/similar/main/gameseg.cpp b/similar/main/gameseg.cpp index 4c1fe2980..2591092ad 100644 --- a/similar/main/gameseg.cpp +++ b/similar/main/gameseg.cpp @@ -824,6 +824,8 @@ vm_distance find_connected_distance(const vms_vector &p0, const vcsegptridx_t se max_depth = MAX_LOC_POINT_SEGS-2; } + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; if (seg0 == seg1) { return vm_vec_dist_quick(p0, p1); } else { @@ -1652,11 +1654,14 @@ static void apply_light_to_segment(visited_segment_bitarray_t &visited, const vm } if (recursion_depth < 2) + { + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; for (int sidenum=0; sidenum<6; sidenum++) { if (WALL_IS_DOORWAY(GameBitmaps, Textures, vcwallptr, segp, segp, sidenum) & WID_RENDPAST_FLAG) apply_light_to_segment(visited, segp.absolute_sibling(segp->children[sidenum]), segment_center, light_intensity, recursion_depth+1); } - + } } @@ -1664,6 +1669,8 @@ static void apply_light_to_segment(visited_segment_bitarray_t &visited, const vm //this code is copied from the editor routine calim_process_all_lights() static void change_segment_light(const vmsegptridx_t segp,int sidenum,int dir) { + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; if (WALL_IS_DOORWAY(GameBitmaps, Textures, vcwallptr, segp, segp, sidenum) & WID_RENDER_FLAG) { auto &sidep = segp->unique_segment::sides[sidenum]; @@ -1793,6 +1800,8 @@ static void ambient_mark_bfs(const vmsegptridx_t segp, segment_lava_depth_array if (!segdepth_lava && !segdepth_water) return; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; for (unsigned i = 0; i < MAX_SIDES_PER_SEGMENT; ++i) { const auto child = segp->children[i]; diff --git a/similar/main/gameseq.cpp b/similar/main/gameseq.cpp index e230f3bb2..4629b9c07 100644 --- a/similar/main/gameseq.cpp +++ b/similar/main/gameseq.cpp @@ -742,6 +742,8 @@ static void set_sound_sources(fvcsegptridx &vcsegptridx, fvcvertptr &vcvertptr) digi_init_sounds(); //clear old sounds #if defined(DXX_BUILD_DESCENT_II) + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; Dont_start_sound_objects = 1; #endif diff --git a/similar/main/mglobal.cpp b/similar/main/mglobal.cpp index 01a8f90c7..39f6ad279 100644 --- a/similar/main/mglobal.cpp +++ b/similar/main/mglobal.cpp @@ -99,7 +99,7 @@ valptridx::array_managed_type CloakingWalls; d_level_unique_object_state LevelUniqueObjectState; valptridx::array_managed_type Objects; valptridx::array_managed_type Triggers; -valptridx::array_managed_type Walls; +d_level_unique_wall_subsystem_state LevelUniqueWallSubsystemState; } /* diff --git a/similar/main/multi.cpp b/similar/main/multi.cpp index 475038bb6..9439836b6 100644 --- a/similar/main/multi.cpp +++ b/similar/main/multi.cpp @@ -2334,7 +2334,7 @@ static void multi_do_drop_marker(object_array &objects, fvmsegptridx &vmsegptrid } #endif -static void multi_do_hostage_door_status(fvmsegptridx &vmsegptridx, fvmwallptr &vmwallptr, const uint8_t *const buf) +static void multi_do_hostage_door_status(fvmsegptridx &vmsegptridx, wall_array &Walls, const uint8_t *const buf) { // Update hit point status of a door @@ -2344,6 +2344,7 @@ static void multi_do_hostage_door_status(fvmsegptridx &vmsegptridx, fvmwallptr & wallnum_t wallnum = GET_INTEL_SHORT(buf + count); count += 2; hps = GET_INTEL_INT(buf + count); count += 4; + auto &vmwallptr = Walls.vmptr; auto &w = *vmwallptr(wallnum); if (wallnum >= Walls.get_count() || hps < 0 || w.type != WALL_BLASTABLE) { @@ -5606,6 +5607,8 @@ static void multi_process_data(const playernum_t pnum, const ubyte *buf, const u { // Take an entire message (that has already been checked for validity, // if necessary) and act on it. + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vmwallptr = Walls.vmptr; switch(type) { case MULTI_POSITION: @@ -5736,7 +5739,7 @@ static void multi_process_data(const playernum_t pnum, const ubyte *buf, const u case MULTI_CREATE_ROBOT_POWERUPS: multi_do_create_robot_powerups(pnum, buf); break; case MULTI_HOSTAGE_DOOR: - multi_do_hostage_door_status(vmsegptridx, vmwallptr, buf); + multi_do_hostage_door_status(vmsegptridx, Walls, buf); break; case MULTI_SAVE_GAME: multi_do_save_game(buf); break; diff --git a/similar/main/net_udp.cpp b/similar/main/net_udp.cpp index bbb1e2532..a8eb27302 100644 --- a/similar/main/net_udp.cpp +++ b/similar/main/net_udp.cpp @@ -1779,6 +1779,8 @@ namespace dsx { #if defined(DXX_BUILD_DESCENT_I) static void net_udp_send_door_updates(void) { + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptridx = Walls.vcptridx; // Send door status when new player joins range_for (const auto &&p, vcwallptridx) { @@ -1794,6 +1796,8 @@ static void net_udp_send_door_updates(void) static void net_udp_send_door_updates(const playernum_t pnum) { // Send door status when new player joins + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptridx = Walls.vcptridx; range_for (const auto &&p, vcwallptridx) { auto &w = *p; diff --git a/similar/main/newdemo.cpp b/similar/main/newdemo.cpp index 19e383b33..58d8f3280 100644 --- a/similar/main/newdemo.cpp +++ b/similar/main/newdemo.cpp @@ -1577,6 +1577,8 @@ void newdemo_set_new_level(int level_num) #if defined(DXX_BUILD_DESCENT_II) if (nd_record_v_juststarted==1) { + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; nd_write_int(Walls.get_count()); range_for (const auto &&wp, vcwallptr) { @@ -1618,6 +1620,8 @@ static void newdemo_record_oneframeevent_update(int wallupdate) // This will record tmaps for all walls and properly show doors which were opened before demo recording started. if (wallupdate) { + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; range_for (const auto &&wp, vcwallptr) { auto &w = *wp; @@ -1942,6 +1946,8 @@ static int newdemo_read_demo_start(enum purpose_type purpose) static void newdemo_pop_ctrlcen_triggers() { + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; for (int i = 0; i < ControlCenterTriggers.num_links; i++) { const auto &&seg = vmsegptridx(ControlCenterTriggers.seg[i]); const auto side = ControlCenterTriggers.side[i]; @@ -1996,6 +2002,11 @@ static int newdemo_read_frame_information(int rewrite) prev_obj = NULL; + auto &Walls = LevelUniqueWallSubsystemState.Walls; +#if defined(DXX_BUILD_DESCENT_II) + auto &vcwallptr = Walls.vcptr; +#endif + auto &vmwallptr = Walls.vmptr; while( !done ) { nd_read_byte(&c); if (nd_playback_v_bad_read) { done = -1; break; } diff --git a/similar/main/object.cpp b/similar/main/object.cpp index ae29e2d36..d4ab75fff 100644 --- a/similar/main/object.cpp +++ b/similar/main/object.cpp @@ -1810,6 +1810,10 @@ static window_event_result object_move_one(const vmobjptridx_t obj) } +#if defined(DXX_BUILD_DESCENT_II) + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; +#endif // If player and moved to another segment, see if hit any triggers. // also check in player under a lavafall if (prepare_seglist) diff --git a/similar/main/paging.cpp b/similar/main/paging.cpp index 383c9ae06..b9a6d9b1b 100644 --- a/similar/main/paging.cpp +++ b/similar/main/paging.cpp @@ -258,6 +258,8 @@ static void paging_touch_object(const d_robot_info_array &Robot_info, const Text static void paging_touch_side(const d_eclip_array &Effects, const Textures_array &Textures, const d_vclip_array &Vclip, const vcsegptr_t segp, int sidenum ) { + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; if (!(WALL_IS_DOORWAY(GameBitmaps, Textures, vcwallptr, segp, segp, sidenum) & WID_RENDER_FLAG)) return; auto &uside = segp->unique_segment::sides[sidenum]; @@ -332,6 +334,8 @@ void paging_touch_all(const d_vclip_array &Vclip) { paging_touch_segment(Effects, Robot_info, Textures, Vclip, Weapon_info, vcobjptridx, vcsegptr, segp); } + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; paging_touch_walls(Textures, WallAnims, vcwallptr); range_for (auto &s, partial_const_range(Powerup_info, N_powerup_types)) diff --git a/similar/main/physics.cpp b/similar/main/physics.cpp index f83c8d4ce..a9ca09995 100644 --- a/similar/main/physics.cpp +++ b/similar/main/physics.cpp @@ -389,6 +389,8 @@ window_event_result do_physics_sim(const vmobjptridx_t obj, phys_visited_seglist int count = 0; auto &Vertices = LevelSharedVertexState.get_vertices(); auto &vcvertptr = Vertices.vcptr; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; do { try_again = 0; diff --git a/similar/main/render.cpp b/similar/main/render.cpp index f45ae3e7c..aa27ee70b 100644 --- a/similar/main/render.cpp +++ b/similar/main/render.cpp @@ -242,6 +242,8 @@ static void render_face(grs_canvas &canvas, const shared_segment &segp, const un //handle cloaked walls if (wid_flags & WID_CLOAKED_FLAG) { const auto wall_num = segp.shared_segment::sides[sidenum].wall_num; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; gr_settransblend(canvas, vcwallptr(wall_num)->cloak_value, GR_BLEND_NORMAL); const uint8_t color = BM_XRGB(0, 0, 0); // set to black (matters for s3) @@ -1085,6 +1087,8 @@ static void build_object_lists(object_array &Objects, fvcsegptr &vcsegptr, const const auto viewer = Viewer; auto &Vertices = LevelSharedVertexState.get_vertices(); auto &vcvertptr = Vertices.vcptr; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; for (nn=0;nn < rstate.N_render_segs;nn++) { const auto segnum = rstate.Render_list[nn]; if (segnum != segment_none) { @@ -1268,6 +1272,8 @@ static void build_segment_list(render_state_t &rstate, const vms_vector &Viewer_ auto &Vertices = LevelSharedVertexState.get_vertices(); auto &vcvertptr = Vertices.vcptr; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; for (l=0;lshared_segment::sides[side].wall_num; if ( wall_num == wall_none ) return window_event_result::ignored; - const auto trigger_num = vmwallptr(wall_num)->trigger; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; + const auto trigger_num = vcwallptr(wall_num)->trigger; if (trigger_num == trigger_none) return window_event_result::ignored; @@ -560,7 +575,7 @@ window_event_result check_trigger(const vcsegptridx_t seg, short side, object &p if (cwall_num == wall_none) return window_event_result::ignored; - const auto ctrigger_num = vmwallptr(cwall_num)->trigger; + const auto ctrigger_num = vcwallptr(cwall_num)->trigger; auto &ct = *vmtrgptr(ctrigger_num); ct.flags &= ~TRIGGER_ON; } diff --git a/similar/main/wall.cpp b/similar/main/wall.cpp index 69a82ca56..a2d3c9871 100644 --- a/similar/main/wall.cpp +++ b/similar/main/wall.cpp @@ -231,6 +231,7 @@ namespace dsx { void wall_init() { init_exploding_walls(); + auto &Walls = LevelUniqueWallSubsystemState.Walls; Walls.set_count(0); range_for (auto &w, Walls) { @@ -293,6 +294,8 @@ static void blast_blastable_wall(const vmsegptridx_t seg, const unsigned side, w auto Connectside = find_connect_side(seg, csegp); Assert(Connectside != side_none); const auto cwall_num = csegp->shared_segment::sides[Connectside].wall_num; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &imwallptr = Walls.imptr; const auto &&w1 = imwallptr(cwall_num); if (w1) LevelUniqueStuckObjectState.kill_stuck_objects(vmobjptr, cwall_num); @@ -323,6 +326,8 @@ static void blast_blastable_wall(const vmsegptridx_t seg, const unsigned side, w // Destroys a blastable wall. void wall_destroy(const vmsegptridx_t seg, const unsigned side) { + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vmwallptr = Walls.vmptr; auto &w = *vmwallptr(seg->shared_segment::sides[side].wall_num); if (w.type == WALL_BLASTABLE) blast_blastable_wall(seg, side, w); @@ -342,6 +347,8 @@ void wall_damage(const vmsegptridx_t seg, const unsigned side, fix damage) return; } + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vmwallptr = Walls.vmptr; auto &w0 = *vmwallptr(wall_num); if (w0.type != WALL_BLASTABLE) return; @@ -352,6 +359,7 @@ void wall_damage(const vmsegptridx_t seg, const unsigned side, fix damage) auto Connectside = find_connect_side(seg, csegp); Assert(Connectside != side_none); const auto cwall_num = csegp->shared_segment::sides[Connectside].wall_num; + auto &imwallptr = Walls.imptr; if (const auto &&w1p = imwallptr(cwall_num)) { auto &w1 = *w1p; @@ -386,6 +394,8 @@ void wall_open_door(const vmsegptridx_t seg, int side) auto &sside = seg->shared_segment::sides[side]; const auto wall_num = sside.wall_num; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vmwallptr = Walls.vmptr; wall *const w = vmwallptr(wall_num); LevelUniqueStuckObjectState.kill_stuck_objects(vmobjptr, wall_num); @@ -432,6 +442,7 @@ void wall_open_door(const vmsegptridx_t seg, int side) if (Connectside != side_none) { const auto cwall_num = csegp->shared_segment::sides[Connectside].wall_num; + auto &imwallptr = Walls.imptr; if (const auto &&w1 = imwallptr(cwall_num)) { w1->state = WALL_DOOR_OPENING; @@ -459,6 +470,7 @@ void wall_open_door(const vmsegptridx_t seg, int side) Connectside = find_connect_side(seg2, vcsegptr(seg2->children[w2->sidenum])); Assert(Connectside != side_none); const auto cwall_num = csegp->shared_segment::sides[Connectside].wall_num; + auto &imwallptr = Walls.imptr; if (const auto &&w3 = imwallptr(cwall_num)) w3->state = WALL_DOOR_OPENING; @@ -494,7 +506,8 @@ void start_wall_cloak(const vmsegptridx_t seg, const unsigned side) if ( Newdemo_state==ND_STATE_PLAYBACK ) return; - const auto &&w = vmwallptridx(seg->shared_segment::sides[side].wall_num); + auto &Walls = LevelUniqueWallSubsystemState.Walls; + const auto &&w = Walls.vmptridx(seg->shared_segment::sides[side].wall_num); if (w->type == WALL_OPEN || w->state == WALL_DOOR_CLOAKING) //already open or cloaking return; @@ -521,7 +534,7 @@ void start_wall_cloak(const vmsegptridx_t seg, const unsigned side) { Int3(); //ran out of cloaking wall slots w->type = WALL_OPEN; - if (const auto &&w1 = imwallptr(cwall_num)) + if (const auto &&w1 = Walls.imptr(cwall_num)) w1->type = WALL_OPEN; return; } @@ -535,7 +548,7 @@ void start_wall_cloak(const vmsegptridx_t seg, const unsigned side) } w->state = WALL_DOOR_CLOAKING; - if (const auto &&w1 = imwallptr(cwall_num)) + if (const auto &&w1 = Walls.imptr(cwall_num)) w1->state = WALL_DOOR_CLOAKING; d->front_wallnum = seg->shared_segment::sides[side].wall_num; @@ -572,7 +585,8 @@ void start_wall_decloak(const vmsegptridx_t seg, const unsigned side) auto &sside = seg->shared_segment::sides[side]; assert(sside.wall_num != wall_none); //Opening door on illegal wall - const auto &&w = vmwallptridx(sside.wall_num); + auto &Walls = LevelUniqueWallSubsystemState.Walls; + const auto &&w = Walls.vmptridx(sside.wall_num); if (w->type == WALL_CLOSED || w->state == WALL_DOOR_DECLOAKING) //already closed or decloaking return; @@ -616,7 +630,7 @@ void start_wall_decloak(const vmsegptridx_t seg, const unsigned side) Assert(Connectside != side_none); auto &csside = csegp->shared_segment::sides[Connectside]; const auto cwall_num = csside.wall_num; - if (const auto &&w1 = imwallptr(cwall_num)) + if (const auto &&w1 = Walls.imptr(cwall_num)) w1->state = WALL_DOOR_DECLOAKING; d->front_wallnum = seg->shared_segment::sides[side].wall_num; @@ -714,12 +728,12 @@ static unsigned is_door_obstructed(fvcobjptridx &vcobjptridx, fvcsegptr &vcsegpt #if defined(DXX_BUILD_DESCENT_II) //----------------------------------------------------------------- // Closes a door -void wall_close_door(fvmwallptr &vmwallptr, const vmsegptridx_t seg, const unsigned side) +void wall_close_door(wall_array &Walls, const vmsegptridx_t seg, const unsigned side) { active_door *d; const auto wall_num = seg->shared_segment::sides[side].wall_num; - wall *const w = vmwallptr(wall_num); + wall *const w = Walls.vmptr(wall_num); if ((w->state == WALL_DOOR_CLOSING) || //already closing (w->state == WALL_DOOR_WAITING) || //open, waiting to close (w->state == WALL_DOOR_CLOSED)) //closed @@ -758,7 +772,7 @@ void wall_close_door(fvmwallptr &vmwallptr, const vmsegptridx_t seg, const unsig const auto &&Connectside = find_connect_side(seg, csegp); Assert(Connectside != side_none); const auto cwall_num = csegp->shared_segment::sides[Connectside].wall_num; - if (const auto &&w1 = imwallptr(cwall_num)) + if (const auto &&w1 = Walls.imptr(cwall_num)) w1->state = WALL_DOOR_CLOSING; d->front_wallnum[0] = seg->shared_segment::sides[side].wall_num; @@ -794,6 +808,8 @@ void wall_close_door(fvmwallptr &vmwallptr, const vmsegptridx_t seg, const unsig static bool do_door_open(active_door &d) { bool remove = false; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vmwallptr = Walls.vmptr; for (unsigned p = 0; p < d.n_parts; ++p) { int side; @@ -865,6 +881,8 @@ static bool do_door_open(active_door &d) // Called from the game loop. static bool do_door_close(active_door &d) { + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vmwallptr = Walls.vmptr; auto &w0 = *vmwallptr(d.front_wallnum[0]); const auto &&wsegp = vmsegptridx(w0.segnum); @@ -1037,6 +1055,8 @@ wall_hit_process_t wall_hit_process(const player_flags powerup_flags, const vmse if (wall_num == wall_none) return wall_hit_process_t::WHP_NOT_SPECIAL; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vmwallptr = Walls.vmptr; wall *const w = vmwallptr(wall_num); if ( Newdemo_state == ND_STATE_RECORDING ) @@ -1152,7 +1172,8 @@ void wall_toggle(fvmwallptr &vmwallptr, const vmsegptridx_t segp, const unsigned bool ad_removal_predicate::operator()(active_door &d) const { - wall &w = *vmwallptr(d.front_wallnum[0]); + auto &Walls = LevelUniqueWallSubsystemState.Walls; + wall &w = *Walls.vmptr(d.front_wallnum[0]); if (w.state == WALL_DOOR_OPENING) return do_door_open(d); else if (w.state == WALL_DOOR_CLOSING) @@ -1161,7 +1182,7 @@ bool ad_removal_predicate::operator()(active_door &d) const d.time += FrameTime; // set flags to fix occasional netgame problem where door is waiting to close but open flag isn't set w.flags |= WALL_DOOR_OPENED; - if (wall *const w1 = imwallptr(d.back_wallnum[0])) + if (wall *const w1 = Walls.imptr(d.back_wallnum[0])) w1->flags |= WALL_DOOR_OPENED; if (d.time > DOOR_WAIT_TIME) #if defined(DXX_BUILD_DESCENT_II) @@ -1291,6 +1312,7 @@ static void process_exploding_walls() return; if (unsigned num_exploding_walls = Num_exploding_walls) { + auto &Walls = LevelUniqueWallSubsystemState.Walls; range_for (auto &&wp, Walls.vmptr) { auto &w1 = *wp; @@ -1325,6 +1347,7 @@ void wall_frame_process() if (Newdemo_state != ND_STATE_PLAYBACK) { const auto &&r = partial_range(CloakingWalls, CloakingWalls.get_count()); + auto &Walls = LevelUniqueWallSubsystemState.Walls; cw_removal_predicate rp{Segments.vmptr, Walls}; std::remove_if(r.begin(), r.end(), std::ref(rp)); CloakingWalls.set_count(rp.num_cloaking_walls); @@ -1556,6 +1579,8 @@ void blast_nearby_glass(const object &objp, const fix damage) { auto &Vertices = LevelSharedVertexState.get_vertices(); auto &vcvertptr = Vertices.vcptr; + auto &Walls = LevelUniqueWallSubsystemState.Walls; + auto &vcwallptr = Walls.vcptr; blast_nearby_glass_context{objp, damage, Effects, GameBitmaps, Textures, TmapInfo, Vclip, vcvertptr, vcwallptr}.process_segment(vmsegptridx(objp.segnum), MAX_BLAST_GLASS_DEPTH); }