mirror of
https://github.com/TerryCavanagh/VVVVVV.git
synced 2024-12-23 01:59:43 +01:00
Animated roomnames, setroomname command
This commit adds a better system for animated roomnames. The old system, like many other systems, were very hardcoded, and can be described as mostly else-if chains, with some fun string comparisons. The new system uses lists of text for transformations and glitchy names, making it much easier to add new cases if needeed. This commit implements the system but does not replace the old system, where that is done in the next commit. The settings for special roomnames can be read from level XML, and `setroomname()` can be used from commands to set a new, static name.
This commit is contained in:
parent
27da7fe935
commit
dd108a035f
6 changed files with 172 additions and 1 deletions
|
@ -388,6 +388,7 @@ void customlevelclass::reset(void)
|
|||
onewaycol_override = false;
|
||||
|
||||
customcolours.clear();
|
||||
map.specialroomnames.clear();
|
||||
}
|
||||
|
||||
const int* customlevelclass::loadlevel( int rxi, int ryi )
|
||||
|
@ -1313,6 +1314,71 @@ next:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (SDL_strcmp(pKey, "SpecialRoomnames") == 0)
|
||||
{
|
||||
for (tinyxml2::XMLElement* roomnameElement = pElem->FirstChildElement(); roomnameElement; roomnameElement = roomnameElement->NextSiblingElement())
|
||||
{
|
||||
const char* roomnameType = roomnameElement->Value();
|
||||
Roomname name;
|
||||
name.x = 0;
|
||||
name.y = 0;
|
||||
name.flag = -1;
|
||||
name.loop = false;
|
||||
name.type = STATIC;
|
||||
name.progress = 0;
|
||||
name.delay = 0;
|
||||
if (SDL_strcmp(roomnameType, "transform") == 0)
|
||||
{
|
||||
name.type = TRANSFORM;
|
||||
name.delay = 2;
|
||||
}
|
||||
else if (SDL_strcmp(roomnameType, "glitch") == 0)
|
||||
{
|
||||
name.type = GLITCH;
|
||||
name.progress = 1;
|
||||
name.delay = -1;
|
||||
}
|
||||
|
||||
name.text.clear();
|
||||
|
||||
roomnameElement->QueryIntAttribute("x", &name.x);
|
||||
roomnameElement->QueryIntAttribute("y", &name.y);
|
||||
roomnameElement->QueryIntAttribute("flag", &name.flag);
|
||||
|
||||
roomnameElement->QueryBoolAttribute("loop", &name.loop);
|
||||
|
||||
if (name.type == STATIC)
|
||||
{
|
||||
const char* text = roomnameElement->GetText();
|
||||
if (text != NULL)
|
||||
{
|
||||
name.text.push_back(std::string(text));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Does it have children?
|
||||
if (roomnameElement->FirstChildElement() == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (tinyxml2::XMLElement* textElement = roomnameElement->FirstChildElement(); textElement; textElement = textElement->NextSiblingElement())
|
||||
{
|
||||
if (SDL_strcmp(textElement->Value(), "text") == 0)
|
||||
{
|
||||
const char* text = textElement->GetText();
|
||||
if (text != NULL)
|
||||
{
|
||||
name.text.push_back(std::string(text));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map.specialroomnames.push_back(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mapwidth < maxwidth)
|
||||
|
|
|
@ -5498,7 +5498,12 @@ void Game::customloadquick(const std::string& savfile)
|
|||
{
|
||||
map.showtrinkets = help.Int(pText);
|
||||
}
|
||||
|
||||
else if (SDL_strcmp(pKey, "roomname") == 0)
|
||||
{
|
||||
map.setroomname(pText);
|
||||
map.roomnameset = true;
|
||||
map.roomname_special = true;
|
||||
}
|
||||
}
|
||||
|
||||
map.showteleporters = true;
|
||||
|
@ -5972,6 +5977,11 @@ bool Game::customsavequick(const std::string& savfile)
|
|||
|
||||
xml::update_tag(msgs, "showtrinkets", (int) map.showtrinkets);
|
||||
|
||||
if (map.roomnameset)
|
||||
{
|
||||
xml::update_tag(msgs, "roomname", map.roomname);
|
||||
}
|
||||
|
||||
std::string summary = savearea + ", " + timestring();
|
||||
xml::update_tag(msgs, "summary", summary.c_str());
|
||||
|
||||
|
|
|
@ -88,6 +88,8 @@ mapclass::mapclass(void)
|
|||
hiddenname = "";
|
||||
|
||||
roomname_special = false;
|
||||
specialroomnames.clear();
|
||||
roomnameset = false;
|
||||
}
|
||||
|
||||
static char roomname_static[SCREEN_WIDTH_CHARS];
|
||||
|
@ -396,6 +398,59 @@ void mapclass::transformname(int t)
|
|||
}
|
||||
}
|
||||
|
||||
void mapclass::updateroomnames(void)
|
||||
{
|
||||
if (roomnameset)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const int rx = game.roomx - 100;
|
||||
const int ry = game.roomy - 100;
|
||||
|
||||
for (int i = specialroomnames.size() - 1; i >= 0; i--)
|
||||
{
|
||||
Roomname &roomname = specialroomnames[i];
|
||||
if (rx == roomname.x && ry == roomname.y && (roomname.flag == -1 || (INBOUNDS_ARR(roomname.flag, obj.flags) && obj.flags[roomname.flag])))
|
||||
{
|
||||
roomname_special = true;
|
||||
if (roomname.type == STATIC)
|
||||
{
|
||||
setroomname(roomname.text[0].c_str());
|
||||
}
|
||||
if (roomname.type == GLITCH)
|
||||
{
|
||||
roomname.delay--;
|
||||
if (roomname.delay <= 0)
|
||||
{
|
||||
roomname.progress = (roomname.progress + 1) % 2;
|
||||
roomname.delay = 5;
|
||||
if (roomname.progress == 0)
|
||||
{
|
||||
roomname.delay = 25 + (int) (fRandom() * 10);
|
||||
}
|
||||
}
|
||||
setroomname(roomname.text[roomname.progress].c_str());
|
||||
}
|
||||
if (roomname.type == TRANSFORM)
|
||||
{
|
||||
roomname.delay--;
|
||||
if (roomname.delay <= 0)
|
||||
{
|
||||
roomname.progress++;
|
||||
roomname.delay = 2;
|
||||
if (roomname.progress >= roomname.text.size())
|
||||
{
|
||||
roomname.progress = roomname.loop ? 0 : roomname.text.size() - 1;
|
||||
}
|
||||
}
|
||||
setroomname(roomname.text[roomname.progress].c_str());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* mapclass::getglitchname(int x, int y)
|
||||
{
|
||||
//Returns the name in the final area.
|
||||
|
@ -1414,6 +1469,7 @@ void mapclass::loadlevel(int rx, int ry)
|
|||
|
||||
roomtexton = false;
|
||||
roomtext.clear();
|
||||
roomnameset = false;
|
||||
|
||||
obj.platformtile = 0;
|
||||
obj.customplatformtile=0;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define MAPGAME_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "Finalclass.h"
|
||||
#include "Labclass.h"
|
||||
|
@ -17,6 +18,25 @@ struct Roomtext
|
|||
const char* text;
|
||||
};
|
||||
|
||||
enum RoomnameType
|
||||
{
|
||||
STATIC,
|
||||
GLITCH,
|
||||
TRANSFORM
|
||||
};
|
||||
|
||||
struct Roomname
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
bool loop;
|
||||
int flag;
|
||||
RoomnameType type;
|
||||
std::vector<std::string> text;
|
||||
int progress;
|
||||
int delay;
|
||||
};
|
||||
|
||||
class mapclass
|
||||
{
|
||||
public:
|
||||
|
@ -39,6 +59,8 @@ public:
|
|||
|
||||
void resetnames(void);
|
||||
|
||||
void updateroomnames(void);
|
||||
|
||||
void transformname(int t);
|
||||
|
||||
const char* getglitchname(int x, int y);
|
||||
|
@ -114,8 +136,11 @@ public:
|
|||
|
||||
const char* roomname;
|
||||
bool roomname_special;
|
||||
bool roomnameset;
|
||||
const char* hiddenname;
|
||||
|
||||
std::vector<Roomname> specialroomnames;
|
||||
|
||||
//Special tower stuff
|
||||
bool towermode;
|
||||
int ypos;
|
||||
|
|
|
@ -114,6 +114,8 @@ void gamerenderfixed(void)
|
|||
obj.entities[i].updatecolour();
|
||||
}
|
||||
|
||||
map.updateroomnames();
|
||||
|
||||
if (map.finalmode)
|
||||
{
|
||||
map.glitchname = map.getglitchname(game.roomx, game.roomy);
|
||||
|
@ -245,6 +247,8 @@ void maprenderfixed(void)
|
|||
map.cursordelay++;
|
||||
}
|
||||
|
||||
map.updateroomnames();
|
||||
|
||||
if (map.finalmode)
|
||||
{
|
||||
map.glitchname = map.getglitchname(game.roomx, game.roomy);
|
||||
|
|
|
@ -176,6 +176,16 @@ void scriptclass::run(void)
|
|||
scriptdelay = 1;
|
||||
}
|
||||
#if !defined(NO_CUSTOM_LEVELS)
|
||||
if (words[0] == "setroomname")
|
||||
{
|
||||
++position;
|
||||
if (INBOUNDS_VEC(position, commands))
|
||||
{
|
||||
map.roomname_special = true;
|
||||
map.roomnameset = true;
|
||||
map.setroomname(commands[position].c_str());
|
||||
}
|
||||
}
|
||||
if (words[0] == "warpdir")
|
||||
{
|
||||
int temprx = ss_toi(words[1]) - 1;
|
||||
|
|
Loading…
Reference in a new issue