From 71a989707eb353977b58deca6080c1a8837c204f Mon Sep 17 00:00:00 2001 From: Misa Date: Thu, 9 Jul 2020 02:54:23 -0700 Subject: [PATCH] De-duplicate and add safety check to ed.level reference Instead of repeating 'ed.level[curlevel]' (or even worse, you type in that giant expression inside the brackets instead of reusing 'curlevel'), why not just type 'room'? As an added bonus, I added bounds checks so 'room' is always guaranteed to point to an existing object. There are some levels that index 'ed.level' out of bounds, and I'd like to make their behavior properly defined instead of being undefined. One of the things usually true about out-of-bounds rooms is that they're always tiles2.png (that means an edlevelclass tileset that isn't 0), because the chance of the memory location being exactly 0 is smaller than it being nonzero. So the out-of-bounds room has tileset 1. --- desktop_version/src/Map.cpp | 52 +++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/desktop_version/src/Map.cpp b/desktop_version/src/Map.cpp index 1e04db63..4c04adb2 100644 --- a/desktop_version/src/Map.cpp +++ b/desktop_version/src/Map.cpp @@ -1611,10 +1611,23 @@ void mapclass::loadlevel(int rx, int ry) #endif #if !defined(NO_CUSTOM_LEVELS) case 12: //Custom level - int curlevel=(rx-100)+((ry-100)*ed.maxwidth); + const int curlevel = rx-100 + (ry-100) * ed.maxwidth; + const edlevelclass* room_ptr = NULL; + if (!INBOUNDS_ARR(curlevel, ed.level)) + { + static edlevelclass blank; + blank.tileset = 1; + room_ptr = ␣ + } + else + { + room_ptr = &ed.level[curlevel]; + } + const edlevelclass& room = *room_ptr; + game.customcol=ed.getlevelcol(curlevel)+1; obj.customplatformtile=game.customcol*12; - switch(ed.level[curlevel].tileset){ + switch(room.tileset){ case 0: //Space Station tileset = 0; background = 1; @@ -1626,7 +1639,7 @@ void mapclass::loadlevel(int rx, int ry) case 2: //Lab tileset = 1; background = 2; - graphics.rcol = ed.level[curlevel].tilecol; + graphics.rcol = room.tilecol; break; case 3: //Warp Zone/intermission tileset = 1; @@ -1647,16 +1660,16 @@ void mapclass::loadlevel(int rx, int ry) if(redrawbg){ graphics.backgrounddrawn = false; } - if(ed.level[curlevel].warpdir>0){ - if(ed.level[curlevel].warpdir==1){ + if(room.warpdir>0){ + if(room.warpdir==1){ warpx=true; background=3; graphics.rcol = ed.getwarpbackground(rx-100,ry-100); - }else if(ed.level[curlevel].warpdir==2){ + }else if(room.warpdir==2){ warpy=true; background=4; graphics.rcol = ed.getwarpbackground(rx-100,ry-100); - }else if(ed.level[curlevel].warpdir==3){ + }else if(room.warpdir==3){ warpx=true; warpy=true; background = 5; graphics.rcol = ed.getwarpbackground(rx-100,ry-100); @@ -1664,8 +1677,8 @@ void mapclass::loadlevel(int rx, int ry) } roomname=""; - if(ed.level[curlevel].roomname!=""){ - roomname=ed.level[curlevel].roomname; + if(room.roomname!=""){ + roomname=room.roomname; } extrarow = 1; const int* tmap = ed.loadlevel(rx, ry); @@ -1689,34 +1702,35 @@ void mapclass::loadlevel(int rx, int ry) } const int ex = (ent.x % 40) * 8; const int ey = (ent.y % 30) * 8; + switch(ent.t){ case 1: //Enemies int bx1, by1, bx2, by2; - bx1=ed.level[rx-100+((ry-100)*ed.maxwidth)].enemyx1; - by1=ed.level[rx-100+((ry-100)*ed.maxwidth)].enemyy1; - bx2=ed.level[rx-100+((ry-100)*ed.maxwidth)].enemyx2; - by2=ed.level[rx-100+((ry-100)*ed.maxwidth)].enemyy2; + bx1=room.enemyx1; + by1=room.enemyy1; + bx2=room.enemyx2; + by2=room.enemyy2; if(warpx){ if(bx1==0 && bx2==320){ bx1=-100; bx2=420; } } if(warpy){ if(by1==0 && by2==240){ by1=-100; by2=340; } } - obj.customenemy=ed.level[tsx+((ed.maxwidth)*tsy)].enemytype; + obj.customenemy=room.enemytype; obj.createentity(ex, ey, 56, ent.p1, 4, bx1, by1, bx2, by2); break; case 2: //Platforms and Threadmills if(ent.p1<=4){ int bx1, by1, bx2, by2; - bx1=ed.level[rx-100+((ry-100)*ed.maxwidth)].platx1; - by1=ed.level[rx-100+((ry-100)*ed.maxwidth)].platy1; - bx2=ed.level[rx-100+((ry-100)*ed.maxwidth)].platx2; - by2=ed.level[rx-100+((ry-100)*ed.maxwidth)].platy2; + bx1=room.platx1; + by1=room.platy1; + bx2=room.platx2; + by2=room.platy2; if(warpx){ if(bx1==0 && bx2==320){ bx1=-100; bx2=420; } } if(warpy){ if(by1==0 && by2==240){ by1=-100; by2=340; } } obj.createentity(ex, ey, 2, - ent.p1, ed.level[rx-100+((ry-100)*ed.mapwidth)].platv, bx1, by1, bx2, by2); + ent.p1, room.platv, bx1, by1, bx2, by2); }else if(ent.p1 >= 5 && ent.p1 <= 8){ //Threadmill obj.createentity(ex, ey, 2, ent.p1 + 3, 4);