Move Walls into d_level_unique_wall_state

This commit is contained in:
Kp 2018-12-30 00:43:58 +00:00
parent ac476be19b
commit 9be3c8e2e8
36 changed files with 247 additions and 29 deletions

View file

@ -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

View file

@ -193,7 +193,17 @@ struct cloaking_wall : public prohibit_void_ptr<cloaking_wall>
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<wclip>
{

View file

@ -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; i<MAX_SIDES_PER_SEGMENT; i++) {
const auto wall_num = segp.sides[i].wall_num;

View file

@ -105,6 +105,8 @@ static void apply_light_intensity(const vmsegptr_t segp, const unsigned sidenum,
if (intensity == 0)
return;
auto &Walls = LevelUniqueWallSubsystemState.Walls;
auto &vcwallptr = Walls.vcptr;
const auto wid_result = WALL_IS_DOORWAY(GameBitmaps, Textures, vcwallptr, segp, segp, sidenum);
if (!(wid_result & WID_RENDPAST_FLAG)) {
add_light_intensity_all_verts(segp->unique_segment::sides[sidenum], intensity);

View file

@ -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)

View file

@ -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());

View file

@ -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;

View file

@ -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;

View file

@ -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 ========================

View file

@ -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.

View file

@ -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<MAX_SIDES_PER_SEGMENT; sidenum++) {

View file

@ -1102,6 +1102,8 @@ static void ai_fire_laser_at_player(const d_level_shared_segment_state &LevelSha
}
}
#elif defined(DXX_BUILD_DESCENT_II)
auto &Walls = LevelUniqueWallSubsystemState.Walls;
auto &vcwallptr = Walls.vcptr;
// Handle problem of a robot firing through a wall because its gun tip is on the other
// side of the wall than the robot's center. For speed reasons, we normally only compute
// the vector from the gun point to the player. But we need to know whether the gun point
@ -1729,6 +1731,8 @@ int ai_door_is_openable(
if (wall_num == wall_none) //if there's no door at all...
return 0; //..then say it can't be opened
auto &Walls = LevelUniqueWallSubsystemState.Walls;
auto &vcwallptr = Walls.vcptr;
auto &wall = *vcwallptr(wall_num);
// The mighty console object can open all doors (for purposes of determining paths).
if (objp == ConsoleObject) {
@ -2042,6 +2046,8 @@ static void init_boss_segments(const segment_array &segments, const object &boss
#endif
auto &Vertices = LevelSharedVertexState.get_vertices();
auto &Walls = LevelUniqueWallSubsystemState.Walls;
auto &vcwallptr = Walls.vcptr;
{
int head, tail;
array<segnum_t, QUEUE_SIZE> 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)) {

View file

@ -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)

View file

@ -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)

View file

@ -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;i<ControlCenterTriggers.num_links;i++)
wall_toggle(vmwallptr, vmsegptridx(ControlCenterTriggers.seg[i]), ControlCenterTriggers.side[i]);

View file

@ -554,8 +554,12 @@ int check_effect_blowup(const d_level_shared_destructible_light_state &LevelShar
if (Game_mode & GM_MULTI)
trigger_check = (!(blower.parent_type == OBJ_PLAYER && (blower.parent_num == get_local_player().objnum || remote)));
if ( wall_num != wall_none )
{
auto &Walls = LevelUniqueWallSubsystemState.Walls;
auto &vcwallptr = Walls.vcptr;
if (vcwallptr(wall_num)->trigger != 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);

View file

@ -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<trgnum_t>(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 = {};

View file

@ -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));

View file

@ -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.

View file

@ -1982,6 +1982,8 @@ constexpr std::integral_constant<fix, INT32_MIN> 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

View file

@ -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);

View file

@ -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 ))

View file

@ -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);

View file

@ -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];

View file

@ -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

View file

@ -99,7 +99,7 @@ valptridx<cloaking_wall>::array_managed_type CloakingWalls;
d_level_unique_object_state LevelUniqueObjectState;
valptridx<object>::array_managed_type Objects;
valptridx<trigger>::array_managed_type Triggers;
valptridx<wall>::array_managed_type Walls;
d_level_unique_wall_subsystem_state LevelUniqueWallSubsystemState;
}
/*

View file

@ -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;

View file

@ -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;

View file

@ -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; }

View file

@ -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)

View file

@ -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))

View file

@ -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;

View file

@ -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;l<Render_depth;l++) {
for (scnt=0;scnt < ecnt;scnt++) {
auto segnum = rstate.Render_list[scnt];
@ -1522,6 +1528,8 @@ void render_mine(grs_canvas &canvas, const vms_vector &Viewer_eye, const vcsegid
auto &Vertices = LevelSharedVertexState.get_vertices();
auto &vcvertptr = Vertices.vcptr;
auto &Walls = LevelUniqueWallSubsystemState.Walls;
auto &vcwallptr = Walls.vcptr;
// First Pass: render opaque level geometry and level geometry with alpha pixels (high Alpha-Test func)
range_for (const auto segnum, reversed_render_range)
{

View file

@ -1100,6 +1100,9 @@ int state_save_all_sub(const char *filename, const char *desc)
}
//Save wall info
{
auto &Walls = LevelUniqueWallSubsystemState.Walls;
auto &vcwallptr = Walls.vcptr;
{
const int i = Walls.get_count();
PHYSFS_write(fp, &i, sizeof(int), 1);
@ -1111,6 +1114,7 @@ int state_save_all_sub(const char *filename, const char *desc)
//Save exploding wall info
expl_wall_write(Walls.vmptr, fp);
#endif
}
//Save door info
{
@ -1684,14 +1688,16 @@ int state_restore_all_sub(const d_level_shared_destructible_light_state &LevelSh
//Restore wall info
init_exploding_walls();
{
auto &Walls = LevelUniqueWallSubsystemState.Walls;
Walls.set_count(PHYSFSX_readSXE32(fp, swap));
range_for (const auto &&w, vmwallptr)
range_for (const auto &&w, Walls.vmptr)
wall_read(fp, *w);
#if defined(DXX_BUILD_DESCENT_II)
//now that we have the walls, check if any sounds are linked to
//walls that are now open
range_for (const auto &&wp, vcwallptr)
range_for (const auto &&wp, Walls.vcptr)
{
auto &w = *wp;
if (w.type == WALL_OPEN)
@ -1704,6 +1710,7 @@ int state_restore_all_sub(const d_level_shared_destructible_light_state &LevelSh
expl_wall_read_n_swap(Walls.vmptr, fp, swap, i);
}
#endif
}
//Restore door info
ActiveDoors.set_count(PHYSFSX_readSXE32(fp, swap));

View file

@ -82,7 +82,9 @@ static inline void trigger_wall_op(const trigger &t, T1 &segment_factory, const
// Opens doors, Blasts blast walls, turns off illusions.
static void do_link(const trigger &t)
{
const auto &&op = [](const vmsegptridx_t segnum, const unsigned sidenum) {
auto &Walls = LevelUniqueWallSubsystemState.Walls;
auto &vmwallptr = Walls.vmptr;
const auto &&op = [&vmwallptr](const vmsegptridx_t segnum, const unsigned sidenum) {
wall_toggle(vmwallptr, segnum, sidenum);
};
trigger_wall_op(t, vmsegptridx, op);
@ -93,8 +95,9 @@ namespace dsx {
//close a door
static void do_close_door(const trigger &t)
{
const auto &&op = [](const vmsegptridx_t segnum, const unsigned sidenum) {
wall_close_door(vmwallptr, segnum, sidenum);
auto &Walls = LevelUniqueWallSubsystemState.Walls;
const auto &&op = [&Walls](const vmsegptridx_t segnum, const unsigned sidenum) {
wall_close_door(Walls, segnum, sidenum);
};
trigger_wall_op(t, vmsegptridx, op);
}
@ -136,7 +139,9 @@ static int do_light_off(const d_level_shared_destructible_light_state &LevelShar
// Unlocks all doors linked to the switch.
static void do_unlock_doors(const trigger &t)
{
const auto op = [](const shared_segment &segp, const unsigned sidenum) {
auto &Walls = LevelUniqueWallSubsystemState.Walls;
auto &vmwallptr = Walls.vmptr;
const auto op = [&vmwallptr](const shared_segment &segp, const unsigned sidenum) {
const auto wall_num = segp.sides[sidenum].wall_num;
auto &w = *vmwallptr(wall_num);
w.flags &= ~WALL_DOOR_LOCKED;
@ -148,7 +153,9 @@ static void do_unlock_doors(const trigger &t)
// Locks all doors linked to the switch.
static void do_lock_doors(const trigger &t)
{
const auto op = [](const shared_segment &segp, const unsigned sidenum) {
auto &Walls = LevelUniqueWallSubsystemState.Walls;
auto &vmwallptr = Walls.vmptr;
const auto op = [&vmwallptr](const shared_segment &segp, const unsigned sidenum) {
const auto wall_num = segp.sides[sidenum].wall_num;
auto &w = *vmwallptr(wall_num);
w.flags |= WALL_DOOR_LOCKED;
@ -161,6 +168,8 @@ static int do_change_walls(const trigger &t, const uint8_t new_wall_type)
{
int ret=0;
auto &Walls = LevelUniqueWallSubsystemState.Walls;
auto &vmwallptr = Walls.vmptr;
for (unsigned i = 0; i < t.num_links; ++i)
{
uint8_t cside;
@ -267,7 +276,9 @@ static void do_matcen(const trigger &t)
static void do_il_on(const trigger &t)
{
const auto &&op = [](const vcsegptridx_t seg, const unsigned side) {
auto &Walls = LevelUniqueWallSubsystemState.Walls;
auto &vmwallptr = Walls.vmptr;
const auto &&op = [&vmwallptr](const vcsegptridx_t seg, const unsigned side) {
wall_illusion_on(vmwallptr, seg, side);
};
trigger_wall_op(t, vcsegptridx, op);
@ -276,7 +287,9 @@ static void do_il_on(const trigger &t)
namespace dsx {
static void do_il_off(const trigger &t)
{
const auto &&op = [](const vcsegptridx_t seg, const unsigned side) {
auto &Walls = LevelUniqueWallSubsystemState.Walls;
auto &vmwallptr = Walls.vmptr;
const auto &&op = [&vmwallptr](const vcsegptridx_t seg, const unsigned side) {
wall_illusion_off(vmwallptr, seg, side);
#if defined(DXX_BUILD_DESCENT_II)
auto &Vertices = LevelSharedVertexState.get_vertices();
@ -536,7 +549,9 @@ window_event_result check_trigger(const vcsegptridx_t seg, short side, object &p
const auto wall_num = seg->shared_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;
}

View file

@ -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);
}