From dd108a035f115bc435791265ec4976f8b1afdd37 Mon Sep 17 00:00:00 2001 From: AllyTally Date: Sun, 11 Dec 2022 19:05:20 -0400 Subject: [PATCH] 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. --- desktop_version/src/CustomLevels.cpp | 66 ++++++++++++++++++++++++++++ desktop_version/src/Game.cpp | 12 ++++- desktop_version/src/Map.cpp | 56 +++++++++++++++++++++++ desktop_version/src/Map.h | 25 +++++++++++ desktop_version/src/RenderFixed.cpp | 4 ++ desktop_version/src/Script.cpp | 10 +++++ 6 files changed, 172 insertions(+), 1 deletion(-) diff --git a/desktop_version/src/CustomLevels.cpp b/desktop_version/src/CustomLevels.cpp index 66453d69..0525e965 100644 --- a/desktop_version/src/CustomLevels.cpp +++ b/desktop_version/src/CustomLevels.cpp @@ -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) diff --git a/desktop_version/src/Game.cpp b/desktop_version/src/Game.cpp index 03087fad..66a605f3 100644 --- a/desktop_version/src/Game.cpp +++ b/desktop_version/src/Game.cpp @@ -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()); diff --git a/desktop_version/src/Map.cpp b/desktop_version/src/Map.cpp index 46cde1c8..2f2257ae 100644 --- a/desktop_version/src/Map.cpp +++ b/desktop_version/src/Map.cpp @@ -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; diff --git a/desktop_version/src/Map.h b/desktop_version/src/Map.h index 65987b87..97dda76f 100644 --- a/desktop_version/src/Map.h +++ b/desktop_version/src/Map.h @@ -2,6 +2,7 @@ #define MAPGAME_H #include +#include #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 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 specialroomnames; + //Special tower stuff bool towermode; int ypos; diff --git a/desktop_version/src/RenderFixed.cpp b/desktop_version/src/RenderFixed.cpp index c8ee3809..3ecaf44c 100644 --- a/desktop_version/src/RenderFixed.cpp +++ b/desktop_version/src/RenderFixed.cpp @@ -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); diff --git a/desktop_version/src/Script.cpp b/desktop_version/src/Script.cpp index 9e710b43..0a9ffc5d 100644 --- a/desktop_version/src/Script.cpp +++ b/desktop_version/src/Script.cpp @@ -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;