1
0
Fork 0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-12-23 10:09:43 +01:00

Refactor room properties to use setter and getter funcs

This replaces all raw ed.level accesses with new setter and getter
funcs, which makes it easier to add bounds checks later. And I've also
removed all the manually-written bounds checks, since they will go into
the new getter and setter.

To get the room properties of a specific room, you use
editorclass::getroomprop(), which returns a pointer to the room
properties - then you just read off of that pointer. To set a room
property, you use editorclass::setroom<PROP>(), where <PROP> is the name
of the property. These are maintained using X macros to avoid
copy-pasting. editorclass::getroompropidx() is a helper function and
shouldn't be used directly.
This commit is contained in:
Misa 2021-03-24 11:59:36 -07:00 committed by Ethan Lee
parent cfd5be1bc5
commit 945d5f244a
6 changed files with 207 additions and 200 deletions

View file

@ -1250,9 +1250,8 @@ void entityclass::createentity( float xp, float yp, int t, float vx /*= 0*/, flo
#if !defined(NO_CUSTOM_LEVELS) #if !defined(NO_CUSTOM_LEVELS)
// Special case for gray Warp Zone tileset! // Special case for gray Warp Zone tileset!
int room = game.roomx-100 + (game.roomy-100) * ed.maxwidth; const edlevelclass* const room = ed.getroomprop(game.roomx - 100, game.roomy - 100);
bool custom_gray = INBOUNDS_ARR(room, ed.level) bool custom_gray = room->tileset == 3 && room->tilecol == 6;
&& ed.level[room].tileset == 3 && ed.level[room].tilecol == 6;
#else #else
bool custom_gray = false; bool custom_gray = false;
#endif #endif

View file

@ -1726,9 +1726,8 @@ void Graphics::drawentity(const int i, const int yoff)
#if !defined(NO_CUSTOM_LEVELS) #if !defined(NO_CUSTOM_LEVELS)
// Special case for gray Warp Zone tileset! // Special case for gray Warp Zone tileset!
const int room = game.roomx-100 + (game.roomy-100) * ed.maxwidth; const edlevelclass* const room = ed.getroomprop(game.roomx - 100, game.roomy - 100);
const bool custom_gray = INBOUNDS_ARR(room, ed.level) const bool custom_gray = room->tileset == 3 && room->tilecol == 6;
&& ed.level[room].tileset == 3 && ed.level[room].tilecol == 6;
#else #else
const bool custom_gray = false; const bool custom_gray = false;
#endif #endif

View file

@ -1571,24 +1571,11 @@ void mapclass::loadlevel(int rx, int ry)
#if !defined(NO_CUSTOM_LEVELS) #if !defined(NO_CUSTOM_LEVELS)
case 12: //Custom level case 12: //Custom level
{ {
const int curlevel = rx-100 + (ry-100) * ed.maxwidth; const edlevelclass* const room = ed.getroomprop(rx - 100, ry - 100);
const edlevelclass* room_ptr = NULL; game.customcol = ed.getlevelcol(room->tileset, room->tilecol) + 1;
if (!INBOUNDS_ARR(curlevel, ed.level))
{
static edlevelclass blank;
blank.tileset = 1;
room_ptr = &blank;
}
else
{
room_ptr = &ed.level[curlevel];
}
const edlevelclass& room = *room_ptr;
game.customcol = ed.getlevelcol(curlevel) + 1;
obj.customplatformtile = game.customcol * 12; obj.customplatformtile = game.customcol * 12;
switch (room.tileset) switch (room->tileset)
{ {
case 0: // Space Station case 0: // Space Station
tileset = 0; tileset = 0;
@ -1601,7 +1588,7 @@ void mapclass::loadlevel(int rx, int ry)
case 2: // Lab case 2: // Lab
tileset = 1; tileset = 1;
background = 2; background = 2;
graphics.rcol = room.tilecol; graphics.rcol = room->tilecol;
break; break;
case 3: // Warp Zone/intermission case 3: // Warp Zone/intermission
tileset = 1; tileset = 1;
@ -1624,7 +1611,7 @@ void mapclass::loadlevel(int rx, int ry)
graphics.backgrounddrawn = false; graphics.backgrounddrawn = false;
} }
switch (room.warpdir) switch (room->warpdir)
{ {
case 1: case 1:
warpx = true; warpx = true;
@ -1644,7 +1631,7 @@ void mapclass::loadlevel(int rx, int ry)
break; break;
} }
roomname = room.roomname; roomname = room->roomname;
extrarow = 1; extrarow = 1;
const short* tmap = ed.loadlevel(rx, ry); const short* tmap = ed.loadlevel(rx, ry);
SDL_memcpy(contents, tmap, sizeof(contents)); SDL_memcpy(contents, tmap, sizeof(contents));
@ -1680,17 +1667,17 @@ void mapclass::loadlevel(int rx, int ry)
{ {
if (enemy) if (enemy)
{ {
bx1 = room.enemyx1; bx1 = room->enemyx1;
by1 = room.enemyy1; by1 = room->enemyy1;
bx2 = room.enemyx2; bx2 = room->enemyx2;
by2 = room.enemyy2; by2 = room->enemyy2;
} }
else if (moving_plat) else if (moving_plat)
{ {
bx1 = room.platx1; bx1 = room->platx1;
by1 = room.platy1; by1 = room->platy1;
bx2 = room.platx2; bx2 = room->platx2;
by2 = room.platy2; by2 = room->platy2;
} }
// Enlarge bounding boxes to fix warping entities // Enlarge bounding boxes to fix warping entities
@ -1709,13 +1696,13 @@ void mapclass::loadlevel(int rx, int ry)
switch (ent.t) switch (ent.t)
{ {
case 1: // Enemies case 1: // Enemies
obj.customenemy = room.enemytype; obj.customenemy = room->enemytype;
obj.createentity(ex, ey, 56, ent.p1, 4, bx1, by1, bx2, by2); obj.createentity(ex, ey, 56, ent.p1, 4, bx1, by1, bx2, by2);
break; break;
case 2: // Platforms and conveyors case 2: // Platforms and conveyors
if (ent.p1 <= 4) if (ent.p1 <= 4)
{ {
obj.createentity(ex, ey, 2, ent.p1, room.platv, bx1, by1, bx2, by2); obj.createentity(ex, ey, 2, ent.p1, room->platv, bx1, by1, bx2, by2);
} }
else if (ent.p1 >= 5 && ent.p1 <= 8) // Conveyor else if (ent.p1 >= 5 && ent.p1 <= 8) // Conveyor
{ {

View file

@ -117,38 +117,36 @@ void scriptclass::run(void)
{ {
int temprx=ss_toi(words[1])-1; int temprx=ss_toi(words[1])-1;
int tempry=ss_toi(words[2])-1; int tempry=ss_toi(words[2])-1;
int curlevel=temprx+(ed.maxwidth*(tempry)); const edlevelclass* room;
bool inbounds = INBOUNDS_ARR(curlevel, ed.level); ed.setroomwarpdir(temprx, tempry, ss_toi(words[3]));
if (inbounds)
{ room = ed.getroomprop(temprx, tempry);
ed.level[curlevel].warpdir=ss_toi(words[3]);
}
//Do we update our own room? //Do we update our own room?
if(inbounds && game.roomx-100==temprx && game.roomy-100==tempry){ if(game.roomx-100==temprx && game.roomy-100==tempry){
//If screen warping, then override all that: //If screen warping, then override all that:
graphics.backgrounddrawn = false; graphics.backgrounddrawn = false;
map.warpx=false; map.warpy=false; map.warpx=false; map.warpy=false;
if(ed.level[curlevel].warpdir==0){ if(room->warpdir==0){
map.background = 1; map.background = 1;
//Be careful, we could be in a Lab or Warp Zone room... //Be careful, we could be in a Lab or Warp Zone room...
if(ed.level[curlevel].tileset==2){ if(room->tileset==2){
//Lab //Lab
map.background = 2; map.background = 2;
graphics.rcol = ed.level[curlevel].tilecol; graphics.rcol = room->tilecol;
}else if(ed.level[curlevel].tileset==3){ }else if(room->tileset==3){
//Warp Zone //Warp Zone
map.background = 6; map.background = 6;
} }
}else if(ed.level[curlevel].warpdir==1){ }else if(room->warpdir==1){
map.warpx=true; map.warpx=true;
map.background=3; map.background=3;
graphics.rcol = ed.getwarpbackground(temprx,tempry); graphics.rcol = ed.getwarpbackground(temprx,tempry);
}else if(ed.level[curlevel].warpdir==2){ }else if(room->warpdir==2){
map.warpy=true; map.warpy=true;
map.background=4; map.background=4;
graphics.rcol = ed.getwarpbackground(temprx,tempry); graphics.rcol = ed.getwarpbackground(temprx,tempry);
}else if(ed.level[curlevel].warpdir==3){ }else if(room->warpdir==3){
map.warpx=true; map.warpy=true; map.warpx=true; map.warpy=true;
map.background = 5; map.background = 5;
graphics.rcol = ed.getwarpbackground(temprx,tempry); graphics.rcol = ed.getwarpbackground(temprx,tempry);
@ -157,8 +155,8 @@ void scriptclass::run(void)
} }
if (words[0] == "ifwarp") if (words[0] == "ifwarp")
{ {
int room = ss_toi(words[1])-1+(ed.maxwidth*(ss_toi(words[2])-1)); const edlevelclass* const room = ed.getroomprop(ss_toi(words[1])-1, ss_toi(words[2])-1);
if (INBOUNDS_ARR(room, ed.level) && ed.level[room].warpdir == ss_toi(words[3])) if (room->warpdir == ss_toi(words[3]))
{ {
load("custom_"+words[4]); load("custom_"+words[4]);
position--; position--;

View file

@ -547,27 +547,27 @@ const short* editorclass::loadlevel( int rxi, int ryi )
return result; return result;
} }
int editorclass::getlevelcol(int t) int editorclass::getlevelcol(const int tileset, const int tilecol)
{ {
if(level[t].tileset==0) //Space Station if(tileset==0) //Space Station
{ {
return level[t].tilecol; return tilecol;
} }
else if(level[t].tileset==1) //Outside else if(tileset==1) //Outside
{ {
return 32+level[t].tilecol; return 32+tilecol;
} }
else if(level[t].tileset==2) //Lab else if(tileset==2) //Lab
{ {
return 40+level[t].tilecol; return 40+tilecol;
} }
else if(level[t].tileset==3) //Warp Zone else if(tileset==3) //Warp Zone
{ {
return 46+level[t].tilecol; return 46+tilecol;
} }
else if(level[t].tileset==4) //Ship else if(tileset==4) //Ship
{ {
return 52+level[t].tilecol; return 52+tilecol;
} }
return 0; return 0;
} }
@ -666,11 +666,11 @@ int editorclass::getenemycol(int t)
int editorclass::getwarpbackground(int rx, int ry) int editorclass::getwarpbackground(int rx, int ry)
{ {
int tmp=rx+(maxwidth*ry); const edlevelclass* const room = getroomprop(rx, ry);
switch(level[tmp].tileset) switch(room->tileset)
{ {
case 0: //Space Station case 0: //Space Station
switch(level[tmp].tilecol) switch(room->tilecol)
{ {
case 0: case 0:
return 3; return 3;
@ -774,7 +774,7 @@ int editorclass::getwarpbackground(int rx, int ry)
} }
break; break;
case 1: //Outside case 1: //Outside
switch(level[tmp].tilecol) switch(room->tilecol)
{ {
case 0: case 0:
return 3; return 3;
@ -806,7 +806,7 @@ int editorclass::getwarpbackground(int rx, int ry)
} }
break; break;
case 2: //Lab case 2: //Lab
switch(level[tmp].tilecol) switch(room->tilecol)
{ {
case 0: case 0:
return 0; return 0;
@ -835,7 +835,7 @@ int editorclass::getwarpbackground(int rx, int ry)
} }
break; break;
case 3: //Warp Zone case 3: //Warp Zone
switch(level[tmp].tilecol) switch(room->tilecol)
{ {
case 0: case 0:
return 0; return 0;
@ -864,7 +864,7 @@ int editorclass::getwarpbackground(int rx, int ry)
} }
break; break;
case 4: //Ship case 4: //Ship
switch(level[tmp].tilecol) switch(room->tilecol)
{ {
case 0: case 0:
return 5; return 5;
@ -1023,6 +1023,31 @@ int editorclass::getabstile(const int x, const int y)
} }
int editorclass::getroompropidx(const int rx, const int ry)
{
return rx + ry*maxwidth;
}
const edlevelclass* editorclass::getroomprop(const int rx, const int ry)
{
const int idx = getroompropidx(rx, ry);
return &level[idx];
}
#define FOREACH_PROP(NAME, TYPE) \
void editorclass::setroom##NAME(const int rx, const int ry, const TYPE NAME) \
{ \
const int idx = getroompropidx(rx, ry); \
\
level[idx].NAME = NAME; \
}
ROOM_PROPERTIES
#undef FOREACH_PROP
void editorclass::placetilelocal( int x, int y, int t ) void editorclass::placetilelocal( int x, int y, int t )
{ {
if(x>=0 && y>=0 && x<40 && y<30) if(x>=0 && y>=0 && x<40 && y<30)
@ -1035,37 +1060,37 @@ void editorclass::placetilelocal( int x, int y, int t )
int editorclass::base( int x, int y ) int editorclass::base( int x, int y )
{ {
//Return the base tile for the given tileset and colour //Return the base tile for the given tileset and colour
int temp=x+(y*maxwidth); const edlevelclass* const room = getroomprop(x, y);
if(level[temp].tileset==0) //Space Station if(room->tileset==0) //Space Station
{ {
if(level[temp].tilecol>=22) if(room->tilecol>=22)
{ {
return 483 + ((level[temp].tilecol-22)*3); return 483 + ((room->tilecol-22)*3);
} }
else if(level[temp].tilecol>=11) else if(room->tilecol>=11)
{ {
return 283 + ((level[temp].tilecol-11)*3); return 283 + ((room->tilecol-11)*3);
} }
else else
{ {
return 83 + (level[temp].tilecol*3); return 83 + (room->tilecol*3);
} }
} }
else if(level[temp].tileset==1) //Outside else if(room->tileset==1) //Outside
{ {
return 480 + (level[temp].tilecol*3); return 480 + (room->tilecol*3);
} }
else if(level[temp].tileset==2) //Lab else if(room->tileset==2) //Lab
{ {
return 280 + (level[temp].tilecol*3); return 280 + (room->tilecol*3);
} }
else if(level[temp].tileset==3) //Warp Zone/Intermission else if(room->tileset==3) //Warp Zone/Intermission
{ {
return 80 + (level[temp].tilecol*3); return 80 + (room->tilecol*3);
} }
else if(level[temp].tileset==4) //SHIP else if(room->tileset==4) //SHIP
{ {
return 101 + (level[temp].tilecol*3); return 101 + (room->tilecol*3);
} }
return 0; return 0;
} }
@ -1073,11 +1098,11 @@ int editorclass::base( int x, int y )
int editorclass::backbase( int x, int y ) int editorclass::backbase( int x, int y )
{ {
//Return the base tile for the background of the given tileset and colour //Return the base tile for the background of the given tileset and colour
int temp=x+(y*maxwidth); const edlevelclass* const room = getroomprop(x, y);
if(level[temp].tileset==0) //Space Station if(room->tileset==0) //Space Station
{ {
//Pick depending on tilecol //Pick depending on tilecol
switch(level[temp].tilecol) switch(room->tilecol)
{ {
case 0: case 0:
case 5: case 5:
@ -1135,21 +1160,21 @@ int editorclass::backbase( int x, int y )
} }
} }
else if(level[temp].tileset==1) //outside else if(room->tileset==1) //outside
{ {
return 680 + (level[temp].tilecol*3); return 680 + (room->tilecol*3);
} }
else if(level[temp].tileset==2) //Lab else if(room->tileset==2) //Lab
{ {
return 0; return 0;
} }
else if(level[temp].tileset==3) //Warp Zone/Intermission else if(room->tileset==3) //Warp Zone/Intermission
{ {
return 120 + (level[temp].tilecol*3); return 120 + (room->tilecol*3);
} }
else if(level[temp].tileset==4) //SHIP else if(room->tileset==4) //SHIP
{ {
return 741 + (level[temp].tilecol*3); return 741 + (room->tilecol*3);
} }
return 0; return 0;
} }
@ -1578,14 +1603,8 @@ int editorclass::findwarptoken(int t)
void editorclass::switch_tileset(const bool reversed /*= false*/) void editorclass::switch_tileset(const bool reversed /*= false*/)
{ {
const char* tilesets[] = {"Space Station", "Outside", "Lab", "Warp Zone", "Ship"}; const char* tilesets[] = {"Space Station", "Outside", "Lab", "Warp Zone", "Ship"};
const size_t roomnum = levx + levy*maxwidth;
if (!INBOUNDS_ARR(roomnum, level))
{
return;
}
edlevelclass& room = level[roomnum];
int tiles = room.tileset; int tiles = getroomprop(levx, levy)->tileset;
if (reversed) if (reversed)
{ {
@ -1598,7 +1617,7 @@ void editorclass::switch_tileset(const bool reversed /*= false*/)
const int modulus = SDL_arraysize(tilesets); const int modulus = SDL_arraysize(tilesets);
tiles = (tiles % modulus + modulus) % modulus; tiles = (tiles % modulus + modulus) % modulus;
room.tileset = tiles; setroomtileset(levx, levy, tiles);
clamp_tilecol(levx, levy); clamp_tilecol(levx, levy);
@ -1612,22 +1631,19 @@ void editorclass::switch_tileset(const bool reversed /*= false*/)
void editorclass::switch_tilecol(const bool reversed /*= false*/) void editorclass::switch_tilecol(const bool reversed /*= false*/)
{ {
const size_t roomnum = levx + levy*maxwidth; int tilecol = getroomprop(levx, levy)->tilecol;
if (!INBOUNDS_ARR(roomnum, level))
{
return;
}
edlevelclass& room = level[roomnum];
if (reversed) if (reversed)
{ {
room.tilecol--; tilecol--;
} }
else else
{ {
room.tilecol++; tilecol++;
} }
setroomtilecol(levx, levy, tilecol);
clamp_tilecol(levx, levy, true); clamp_tilecol(levx, levy, true);
notedelay = 45; notedelay = 45;
@ -1637,15 +1653,9 @@ void editorclass::switch_tilecol(const bool reversed /*= false*/)
void editorclass::clamp_tilecol(const int rx, const int ry, const bool wrap /*= false*/) void editorclass::clamp_tilecol(const int rx, const int ry, const bool wrap /*= false*/)
{ {
const size_t roomnum = rx + ry*maxwidth; const edlevelclass* const room = getroomprop(rx, ry);
if (!INBOUNDS_ARR(roomnum, level)) const int tileset = room->tileset;
{ int tilecol = room->tilecol;
return;
}
edlevelclass& room = level[rx + ry*maxwidth];
const int tileset = room.tileset;
int tilecol = room.tilecol;
int mincol = -1; int mincol = -1;
int maxcol = 5; int maxcol = 5;
@ -1682,19 +1692,14 @@ void editorclass::clamp_tilecol(const int rx, const int ry, const bool wrap /*=
tilecol = (wrap ? maxcol : mincol); tilecol = (wrap ? maxcol : mincol);
} }
room.tilecol = tilecol; setroomtilecol(rx, ry, tilecol);
} }
void editorclass::switch_enemy(const bool reversed /*= false*/) void editorclass::switch_enemy(const bool reversed /*= false*/)
{ {
const size_t roomnum = levx + levy*maxwidth; const edlevelclass* const room = getroomprop(levx, levy);
if (!INBOUNDS_ARR(roomnum, level))
{
return;
}
edlevelclass& room = level[roomnum];
int enemy = room.enemytype; int enemy = room->enemytype;
if (reversed) if (reversed)
{ {
@ -1707,7 +1712,7 @@ void editorclass::switch_enemy(const bool reversed /*= false*/)
const int modulus = 10; const int modulus = 10;
enemy = (enemy % modulus + modulus) % modulus; enemy = (enemy % modulus + modulus) % modulus;
room.enemytype = enemy; setroomenemytype(levx, levy, enemy);
note = "Enemy Type Changed"; note = "Enemy Type Changed";
notedelay = 45; notedelay = 45;
@ -1930,6 +1935,11 @@ bool editorclass::load(std::string& _path)
int i = 0; int i = 0;
for( tinyxml2::XMLElement* edLevelClassElement = pElem->FirstChildElement(); edLevelClassElement; edLevelClassElement=edLevelClassElement->NextSiblingElement()) for( tinyxml2::XMLElement* edLevelClassElement = pElem->FirstChildElement(); edLevelClassElement; edLevelClassElement=edLevelClassElement->NextSiblingElement())
{ {
if (!INBOUNDS_ARR(i, level))
{
continue;
}
if(edLevelClassElement->GetText() != NULL) if(edLevelClassElement->GetText() != NULL)
{ {
level[i].roomname = std::string(edLevelClassElement->GetText()) ; level[i].roomname = std::string(edLevelClassElement->GetText()) ;
@ -2248,7 +2258,7 @@ void editorclass::generatecustomminimap(void)
{ {
//Ok, now scan over each square //Ok, now scan over each square
tm=196; tm=196;
if(level[i2 + (j2*maxwidth)].tileset==1) tm=96; if(getroomprop(i2, j2)->tileset==1) tm=96;
for(int j=0; j<36; j++) for(int j=0; j<36; j++)
{ {
@ -2274,7 +2284,7 @@ void editorclass::generatecustomminimap(void)
{ {
//Ok, now scan over each square //Ok, now scan over each square
tm=196; tm=196;
if(level[i2 + (j2*maxwidth)].tileset==1) tm=96; if(getroomprop(i2, j2)->tileset==1) tm=96;
for(int j=0; j<18; j++) for(int j=0; j<18; j++)
{ {
@ -2299,7 +2309,7 @@ void editorclass::generatecustomminimap(void)
{ {
//Ok, now scan over each square //Ok, now scan over each square
tm=196; tm=196;
if(level[i2 + (j2*maxwidth)].tileset==1) tm=96; if(getroomprop(i2, j2)->tileset==1) tm=96;
for(int j=0; j<9; j++) for(int j=0; j<9; j++)
{ {
@ -2501,6 +2511,8 @@ static void editormenurender(int tr, int tg, int tb)
void editorrender(void) void editorrender(void)
{ {
extern editorclass ed; extern editorclass ed;
const edlevelclass* const room = ed.getroomprop(ed.levx, ed.levy);
//Draw grid //Draw grid
ClearSurface(graphics.backBuffer); ClearSurface(graphics.backBuffer);
@ -2527,7 +2539,7 @@ void editorrender(void)
//Or draw background //Or draw background
if(!ed.settingsmod) if(!ed.settingsmod)
{ {
switch(ed.level[ed.levx+(ed.levy*ed.maxwidth)].warpdir) switch(room->warpdir)
{ {
case 1: case 1:
graphics.rcol=ed.getwarpbackground(ed.levx, ed.levy); graphics.rcol=ed.getwarpbackground(ed.levx, ed.levy);
@ -2548,7 +2560,7 @@ void editorrender(void)
//Draw map, in function //Draw map, in function
int temp; int temp;
if(ed.level[ed.levx+(ed.maxwidth*ed.levy)].tileset==0 || ed.level[ed.levx+(ed.maxwidth*ed.levy)].tileset==10) if(room->tileset==0 || room->tileset==10)
{ {
for (int j = 0; j < 30; j++) for (int j = 0; j < 30; j++)
{ {
@ -2607,9 +2619,7 @@ void editorrender(void)
int temp2=edentat(ed.tilex+ (ed.levx*40),ed.tiley+ (ed.levy*30)); int temp2=edentat(ed.tilex+ (ed.levx*40),ed.tiley+ (ed.levy*30));
// Special case for drawing gray entities // Special case for drawing gray entities
int current_room = (ed.levx+(ed.levy*ed.maxwidth)); bool custom_gray = room->tileset == 3 && room->tilecol == 6;
bool custom_gray = INBOUNDS_ARR(current_room, ed.level)
&& ed.level[current_room].tileset == 3 && ed.level[current_room].tilecol == 6;
colourTransform gray_ct; colourTransform gray_ct;
gray_ct.colour = 0xFFFFFFFF; gray_ct.colour = 0xFFFFFFFF;
@ -2629,7 +2639,7 @@ void editorrender(void)
graphics.setcol(18); graphics.setcol(18);
ed.entcolreal = graphics.ct.colour; ed.entcolreal = graphics.ct.colour;
} }
graphics.drawsprite((edentity[i].x*8)- (ed.levx*40*8),(edentity[i].y*8)- (ed.levy*30*8),ed.getenemyframe(ed.level[ed.levx+(ed.levy*ed.maxwidth)].enemytype),ed.entcolreal); graphics.drawsprite((edentity[i].x*8)- (ed.levx*40*8),(edentity[i].y*8)- (ed.levy*30*8),ed.getenemyframe(room->enemytype),ed.entcolreal);
if(edentity[i].p1==0) graphics.Print((edentity[i].x*8)- (ed.levx*40*8)+4,(edentity[i].y*8)- (ed.levy*30*8)+4, "V", 255, 255, 255 - help.glow, false); if(edentity[i].p1==0) graphics.Print((edentity[i].x*8)- (ed.levx*40*8)+4,(edentity[i].y*8)- (ed.levy*30*8)+4, "V", 255, 255, 255 - help.glow, false);
if(edentity[i].p1==1) graphics.Print((edentity[i].x*8)- (ed.levx*40*8)+4,(edentity[i].y*8)- (ed.levy*30*8)+4, "^", 255, 255, 255 - help.glow, false); if(edentity[i].p1==1) graphics.Print((edentity[i].x*8)- (ed.levx*40*8)+4,(edentity[i].y*8)- (ed.levy*30*8)+4, "^", 255, 255, 255 - help.glow, false);
if(edentity[i].p1==2) graphics.Print((edentity[i].x*8)- (ed.levx*40*8)+4,(edentity[i].y*8)- (ed.levy*30*8)+4, "<", 255, 255, 255 - help.glow, false); if(edentity[i].p1==2) graphics.Print((edentity[i].x*8)- (ed.levx*40*8)+4,(edentity[i].y*8)- (ed.levy*30*8)+4, "<", 255, 255, 255 - help.glow, false);
@ -2915,22 +2925,21 @@ void editorrender(void)
else else
{ {
//Draw boundaries //Draw boundaries
int tmp=ed.levx+(ed.levy*ed.maxwidth); if(room->enemyx1!=0 && room->enemyy1!=0
if(ed.level[tmp].enemyx1!=0 && ed.level[tmp].enemyy1!=0 && room->enemyx2!=320 && room->enemyy2!=240)
&& ed.level[tmp].enemyx2!=320 && ed.level[tmp].enemyy2!=240)
{ {
fillboxabs( ed.level[tmp].enemyx1, ed.level[tmp].enemyy1, fillboxabs( room->enemyx1, room->enemyy1,
ed.level[tmp].enemyx2-ed.level[tmp].enemyx1, room->enemyx2-room->enemyx1,
ed.level[tmp].enemyy2-ed.level[tmp].enemyy1, room->enemyy2-room->enemyy1,
graphics.getBGR(255-(help.glow/2),64,64)); graphics.getBGR(255-(help.glow/2),64,64));
} }
if(ed.level[tmp].platx1!=0 && ed.level[tmp].platy1!=0 if(room->platx1!=0 && room->platy1!=0
&& ed.level[tmp].platx2!=320 && ed.level[tmp].platy2!=240) && room->platx2!=320 && room->platy2!=240)
{ {
fillboxabs( ed.level[tmp].platx1, ed.level[tmp].platy1, fillboxabs( room->platx1, room->platy1,
ed.level[tmp].platx2-ed.level[tmp].platx1, room->platx2-room->platx1,
ed.level[tmp].platy2-ed.level[tmp].platy1, room->platy2-room->platy1,
graphics.getBGR(64,64,255-(help.glow/2))); graphics.getBGR(64,64,255-(help.glow/2)));
} }
} }
@ -3030,7 +3039,7 @@ void editorrender(void)
} }
//If in directmode, show current directmode tile //If in directmode, show current directmode tile
if(ed.level[ed.levx+(ed.levy*ed.maxwidth)].directmode==1) if(room->directmode==1)
{ {
//Tile box for direct mode //Tile box for direct mode
int t2=0; int t2=0;
@ -3046,7 +3055,7 @@ void editorrender(void)
temp-=80; temp-=80;
FillRect(graphics.backBuffer, 0,-t2,320,40, graphics.getRGB(0,0,0)); FillRect(graphics.backBuffer, 0,-t2,320,40, graphics.getRGB(0,0,0));
FillRect(graphics.backBuffer, 0,-t2+40,320,2, graphics.getRGB(255,255,255)); FillRect(graphics.backBuffer, 0,-t2+40,320,2, graphics.getRGB(255,255,255));
if(ed.level[ed.levx+(ed.levy*ed.maxwidth)].tileset==0) if(room->tileset==0)
{ {
for(int i=0; i<40; i++) for(int i=0; i<40; i++)
{ {
@ -3080,7 +3089,7 @@ void editorrender(void)
FillRect(graphics.backBuffer, 44,44-t2,10,10, graphics.getRGB(196, 196, 255 - help.glow)); FillRect(graphics.backBuffer, 44,44-t2,10,10, graphics.getRGB(196, 196, 255 - help.glow));
FillRect(graphics.backBuffer, 45,45-t2,8,8, graphics.getRGB(0,0,0)); FillRect(graphics.backBuffer, 45,45-t2,8,8, graphics.getRGB(0,0,0));
if(ed.level[ed.levx+(ed.levy*ed.maxwidth)].tileset==0) if(room->tileset==0)
{ {
graphics.drawtile(45,45-t2,ed.dmtile); graphics.drawtile(45,45-t2,ed.dmtile);
} }
@ -3096,7 +3105,7 @@ void editorrender(void)
FillRect(graphics.backBuffer, 44,11,10,10, graphics.getRGB(196, 196, 255 - help.glow)); FillRect(graphics.backBuffer, 44,11,10,10, graphics.getRGB(196, 196, 255 - help.glow));
FillRect(graphics.backBuffer, 45,12,8,8, graphics.getRGB(0,0,0)); FillRect(graphics.backBuffer, 45,12,8,8, graphics.getRGB(0,0,0));
if(ed.level[ed.levx+(ed.levy*ed.maxwidth)].tileset==0) if(room->tileset==0)
{ {
graphics.drawtile(45,12,ed.dmtile); graphics.drawtile(45,12,ed.dmtile);
} }
@ -3448,7 +3457,7 @@ void editorrender(void)
{ {
//FillRect(graphics.backBuffer, 0,230,72,240, graphics.RGB(32,32,32)); //FillRect(graphics.backBuffer, 0,230,72,240, graphics.RGB(32,32,32));
//FillRect(graphics.backBuffer, 0,231,71,240, graphics.RGB(0,0,0)); //FillRect(graphics.backBuffer, 0,231,71,240, graphics.RGB(0,0,0));
if(ed.level[ed.levx+(ed.maxwidth*ed.levy)].roomname!="") if(room->roomname!="")
{ {
if (graphics.translucentroomname) if (graphics.translucentroomname)
{ {
@ -3459,7 +3468,7 @@ void editorrender(void)
{ {
FillRect(graphics.backBuffer, 0,230+ed.roomnamehide,320,10, graphics.getRGB(0,0,0)); FillRect(graphics.backBuffer, 0,230+ed.roomnamehide,320,10, graphics.getRGB(0,0,0));
} }
graphics.bprint(5,231+ed.roomnamehide,ed.level[ed.levx+(ed.maxwidth*ed.levy)].roomname, 196, 196, 255 - help.glow, true); graphics.bprint(5,231+ed.roomnamehide,room->roomname, 196, 196, 255 - help.glow, true);
graphics.bprint(4, 222, "SPACE ^ SHIFT ^", 196, 196, 255 - help.glow, false); graphics.bprint(4, 222, "SPACE ^ SHIFT ^", 196, 196, 255 - help.glow, false);
graphics.bprint(268,222, "("+help.String(ed.levx+1)+","+help.String(ed.levy+1)+")",196, 196, 255 - help.glow, false); graphics.bprint(268,222, "("+help.String(ed.levx+1)+","+help.String(ed.levy+1)+")",196, 196, 255 - help.glow, false);
} }
@ -3569,9 +3578,10 @@ void editorrender(void)
void editorrenderfixed(void) void editorrenderfixed(void)
{ {
extern editorclass ed; extern editorclass ed;
const edlevelclass* const room = ed.getroomprop(ed.levx, ed.levy);
graphics.updatetitlecolours(); graphics.updatetitlecolours();
game.customcol=ed.getlevelcol(ed.levx+(ed.levy*ed.maxwidth))+1; game.customcol=ed.getlevelcol(room->tileset, room->tilecol)+1;
ed.entcol=ed.getenemycol(game.customcol); ed.entcol=ed.getenemycol(game.customcol);
graphics.setcol(ed.entcol); graphics.setcol(ed.entcol);
@ -3602,7 +3612,7 @@ void editorrenderfixed(void)
if (!ed.settingsmod) if (!ed.settingsmod)
{ {
switch(ed.level[ed.levx+(ed.levy*ed.maxwidth)].warpdir) switch(room->warpdir)
{ {
case 1: case 1:
graphics.rcol=ed.getwarpbackground(ed.levx, ed.levy); graphics.rcol=ed.getwarpbackground(ed.levx, ed.levy);
@ -3676,7 +3686,7 @@ void editorrenderfixed(void)
} }
} }
if (ed.level[ed.levx + ed.maxwidth*ed.levy].directmode == 1) if (ed.getroomprop(ed.levx, ed.levy)->directmode == 1)
{ {
if (ed.dmtileeditor > 0) if (ed.dmtileeditor > 0)
{ {
@ -3688,7 +3698,7 @@ void editorrenderfixed(void)
ed.dmtileeditor = 0; ed.dmtileeditor = 0;
} }
if (ed.level[ed.levx + ed.maxwidth*ed.levy].roomname != "") if (ed.getroomprop(ed.levx, ed.levy)->roomname != "")
{ {
if (ed.tiley < 28) if (ed.tiley < 28)
{ {
@ -4633,14 +4643,14 @@ void editorinput(void)
} }
if(key.keymap[SDLK_F10]) if(key.keymap[SDLK_F10])
{ {
if(ed.level[ed.levx+(ed.levy*ed.maxwidth)].directmode==1) if(ed.getroomprop(ed.levx, ed.levy)->directmode==1)
{ {
ed.level[ed.levx+(ed.levy*ed.maxwidth)].directmode=0; ed.setroomdirectmode(ed.levx, ed.levy, 0);
ed.note="Direct Mode Disabled"; ed.note="Direct Mode Disabled";
} }
else else
{ {
ed.level[ed.levx+(ed.levy*ed.maxwidth)].directmode=1; ed.setroomdirectmode(ed.levx, ed.levy, 1);
ed.note="Direct Mode Enabled"; ed.note="Direct Mode Enabled";
} }
graphics.backgrounddrawn=false; graphics.backgrounddrawn=false;
@ -4669,26 +4679,26 @@ void editorinput(void)
if(key.keymap[SDLK_w]) if(key.keymap[SDLK_w])
{ {
ed.level[ed.levx+(ed.levy*ed.maxwidth)].warpdir=(ed.level[ed.levx+(ed.levy*ed.maxwidth)].warpdir+1)%4; ed.setroomwarpdir(ed.levx, ed.levy, (ed.getroomprop(ed.levx, ed.levy)->warpdir+1)%4);
if(ed.level[ed.levx+(ed.levy*ed.maxwidth)].warpdir==0) if(ed.getroomprop(ed.levx, ed.levy)->warpdir==0)
{ {
ed.note="Room warping disabled"; ed.note="Room warping disabled";
ed.notedelay=45; ed.notedelay=45;
graphics.backgrounddrawn=false; graphics.backgrounddrawn=false;
} }
else if(ed.level[ed.levx+(ed.levy*ed.maxwidth)].warpdir==1) else if(ed.getroomprop(ed.levx, ed.levy)->warpdir==1)
{ {
ed.note="Room warps horizontally"; ed.note="Room warps horizontally";
ed.notedelay=45; ed.notedelay=45;
graphics.backgrounddrawn=false; graphics.backgrounddrawn=false;
} }
else if(ed.level[ed.levx+(ed.levy*ed.maxwidth)].warpdir==2) else if(ed.getroomprop(ed.levx, ed.levy)->warpdir==2)
{ {
ed.note="Room warps vertically"; ed.note="Room warps vertically";
ed.notedelay=45; ed.notedelay=45;
graphics.backgrounddrawn=false; graphics.backgrounddrawn=false;
} }
else if(ed.level[ed.levx+(ed.levy*ed.maxwidth)].warpdir==3) else if(ed.getroomprop(ed.levx, ed.levy)->warpdir==3)
{ {
ed.note="Room warps in all directions"; ed.note="Room warps in all directions";
ed.notedelay=45; ed.notedelay=45;
@ -4699,7 +4709,7 @@ void editorinput(void)
if(key.keymap[SDLK_e]) if(key.keymap[SDLK_e])
{ {
ed.keydelay = 6; ed.keydelay = 6;
ed.getlin(TEXT_ROOMNAME, "Enter new room name:", &(ed.level[ed.levx+(ed.levy*ed.maxwidth)].roomname)); ed.getlin(TEXT_ROOMNAME, "Enter new room name:", const_cast<std::string*>(&(ed.getroomprop(ed.levx, ed.levy)->roomname)));
game.mapheld=true; game.mapheld=true;
} }
if (key.keymap[SDLK_g]) if (key.keymap[SDLK_g])
@ -4936,20 +4946,18 @@ void editorinput(void)
else if(ed.boundarytype==1) else if(ed.boundarytype==1)
{ {
//Enemy bounds //Enemy bounds
int tmp=ed.levx+(ed.levy*ed.maxwidth); ed.setroomenemyx1(ed.levx, ed.levy, ed.boundx1);
ed.level[tmp].enemyx1=ed.boundx1; ed.setroomenemyy1(ed.levx, ed.levy, ed.boundy1);
ed.level[tmp].enemyy1=ed.boundy1; ed.setroomenemyx2(ed.levx, ed.levy, ed.boundx2);
ed.level[tmp].enemyx2=ed.boundx2; ed.setroomenemyy2(ed.levx, ed.levy, ed.boundy2);
ed.level[tmp].enemyy2=ed.boundy2;
} }
else if(ed.boundarytype==2) else if(ed.boundarytype==2)
{ {
//Platform bounds //Platform bounds
int tmp=ed.levx+(ed.levy*ed.maxwidth); ed.setroomplatx1(ed.levx, ed.levy, ed.boundx1);
ed.level[tmp].platx1=ed.boundx1; ed.setroomplaty1(ed.levx, ed.levy, ed.boundy1);
ed.level[tmp].platy1=ed.boundy1; ed.setroomplatx2(ed.levx, ed.levy, ed.boundx2);
ed.level[tmp].platx2=ed.boundx2; ed.setroomplaty2(ed.levx, ed.levy, ed.boundy2);
ed.level[tmp].platy2=ed.boundy2;
} }
else if(ed.boundarytype==3) else if(ed.boundarytype==3)
{ {
@ -5009,7 +5017,7 @@ void editorinput(void)
{ {
//place tiles //place tiles
//Are we in direct mode? //Are we in direct mode?
if(ed.level[ed.levx+(ed.levy*ed.maxwidth)].directmode>=1) if(ed.getroomprop(ed.levx, ed.levy)->directmode>=1)
{ {
if(ed.bmod) if(ed.bmod)
{ {
@ -5488,11 +5496,11 @@ void editorinput(void)
} }
} }
if(ed.updatetiles && ed.level[ed.levx + (ed.levy*ed.maxwidth)].directmode==0) if(ed.updatetiles && ed.getroomprop(ed.levx, ed.levy)->directmode==0)
{ {
ed.updatetiles=false; ed.updatetiles=false;
//Correctly set the tiles in the current room //Correctly set the tiles in the current room
switch(ed.level[ed.levx + (ed.levy*ed.maxwidth)].tileset) switch(ed.getroomprop(ed.levx, ed.levy)->tileset)
{ {
case 0: //The Space Station case 0: //The Space Station
for(int j=0; j<30; j++) for(int j=0; j<30; j++)
@ -5583,7 +5591,7 @@ void editorinput(void)
ed.labspikedir( ed.labspikedir(
i, i,
j, j,
ed.level[ed.levx + (ed.maxwidth*ed.levy)].tilecol ed.getroomprop(ed.levx, ed.levy)->tilecol
) )
); );
} }
@ -5691,16 +5699,11 @@ void editorinput(void)
// Much kudos to Dav999 for saving me a lot of work, because I stole these colors from const.lua in Ved! -Info Teddy // Much kudos to Dav999 for saving me a lot of work, because I stole these colors from const.lua in Ved! -Info Teddy
Uint32 editorclass::getonewaycol(const int rx, const int ry) Uint32 editorclass::getonewaycol(const int rx, const int ry)
{ {
const int roomnum = rx + ry*maxwidth; const edlevelclass* const room = getroomprop(rx, ry);
if (roomnum < 0 || roomnum >= 400) switch (room->tileset) {
{
return graphics.getRGB(255, 255, 255);
}
const edlevelclass& room = level[roomnum];
switch (room.tileset) {
case 0: // Space Station case 0: // Space Station
switch (room.tilecol) { switch (room->tilecol) {
case -1: case -1:
return graphics.getRGB(109, 109, 109); return graphics.getRGB(109, 109, 109);
case 0: case 0:
@ -5771,7 +5774,7 @@ Uint32 editorclass::getonewaycol(const int rx, const int ry)
break; break;
case 1: // Outside case 1: // Outside
switch (room.tilecol) { switch (room->tilecol) {
case 0: case 0:
return graphics.getRGB(57, 86, 140); return graphics.getRGB(57, 86, 140);
case 1: case 1:
@ -5792,7 +5795,7 @@ Uint32 editorclass::getonewaycol(const int rx, const int ry)
break; break;
case 2: // Lab case 2: // Lab
switch (room.tilecol) { switch (room->tilecol) {
case 0: case 0:
return graphics.getRGB(0, 165, 206); return graphics.getRGB(0, 165, 206);
case 1: case 1:
@ -5811,7 +5814,7 @@ Uint32 editorclass::getonewaycol(const int rx, const int ry)
break; break;
case 3: // Warp Zone case 3: // Warp Zone
switch (room.tilecol) { switch (room->tilecol) {
case 0: case 0:
return graphics.getRGB(113, 178, 197); return graphics.getRGB(113, 178, 197);
case 1: case 1:
@ -5830,7 +5833,7 @@ Uint32 editorclass::getonewaycol(const int rx, const int ry)
break; break;
case 4: // Ship case 4: // Ship
switch (room.tilecol) { switch (room->tilecol) {
case 0: case 0:
return graphics.getRGB(0, 206, 39); return graphics.getRGB(0, 206, 39);
case 1: case 1:

View file

@ -41,15 +41,29 @@ public:
}; };
#define ROOM_PROPERTIES \
FOREACH_PROP(tileset, int) \
FOREACH_PROP(tilecol, int) \
FOREACH_PROP(roomname, std::string) \
FOREACH_PROP(warpdir, int) \
FOREACH_PROP(platx1, int) \
FOREACH_PROP(platy1, int) \
FOREACH_PROP(platx2, int) \
FOREACH_PROP(platy2, int) \
FOREACH_PROP(platv, int) \
FOREACH_PROP(enemyx1, int) \
FOREACH_PROP(enemyy1, int) \
FOREACH_PROP(enemyx2, int) \
FOREACH_PROP(enemyy2, int) \
FOREACH_PROP(enemytype, int) \
FOREACH_PROP(directmode, int)
class edlevelclass{ class edlevelclass{
public: public:
edlevelclass(void); edlevelclass(void);
int tileset, tilecol; #define FOREACH_PROP(NAME, TYPE) TYPE NAME;
std::string roomname; ROOM_PROPERTIES
int warpdir; #undef FOREACH_PROP
int platx1, platy1, platx2, platy2, platv;
int enemyx1, enemyy1, enemyx2, enemyy2, enemytype;
int directmode;
}; };
struct LevelMetaData struct LevelMetaData
@ -141,6 +155,13 @@ class editorclass{
); );
int getabstile(const int x, const int y); int getabstile(const int x, const int y);
int getroompropidx(const int rx, const int ry);
const edlevelclass* getroomprop(const int rx, const int ry);
#define FOREACH_PROP(NAME, TYPE) \
void setroom##NAME(const int rx, const int ry, const TYPE NAME);
ROOM_PROPERTIES
#undef FOREACH_PROP
void placetilelocal(int x, int y, int t); void placetilelocal(int x, int y, int t);
int getenemyframe(int t); int getenemyframe(int t);
@ -184,7 +205,7 @@ class editorclass{
int findcrewmate(int t); int findcrewmate(int t);
int findwarptoken(int t); int findwarptoken(int t);
void findstartpoint(void); void findstartpoint(void);
int getlevelcol(int t); int getlevelcol(const int tileset, const int tilecol);
int getenemycol(int t); int getenemycol(int t);
int entcol; int entcol;
Uint32 entcolreal; Uint32 entcolreal;