diff --git a/desktop_version/src/CustomLevels.cpp b/desktop_version/src/CustomLevels.cpp index e9feafecbe8..7ec6bea1091 100644 --- a/desktop_version/src/CustomLevels.cpp +++ b/desktop_version/src/CustomLevels.cpp @@ -952,6 +952,17 @@ int customlevelclass::findtrinket(int t) return 0; } +int customlevelclass::findcoin(int t) +{ + int tcoin = 0; + for (int i = 0; i < (int)customentities.size(); i++) + { + if (i == t) return tcoin; + if (customentities[i].t == 8) tcoin++; + } + return 0; +} + int customlevelclass::findcrewmate(int t) { int ttrinket=0; @@ -1808,6 +1819,19 @@ int customlevelclass::numtrinkets(void) return temp; } +int customlevelclass::numcoins(void) +{ + int temp = 0; + for (size_t i = 0; i < customentities.size(); i++) + { + if (customentities[i].t == 8 && inbounds(&customentities[i])) + { + temp++; + } + } + return temp; +} + int customlevelclass::numcrewmates(void) { int temp = 0; diff --git a/desktop_version/src/CustomLevels.h b/desktop_version/src/CustomLevels.h index 8ce02e93b46..68806d4302e 100644 --- a/desktop_version/src/CustomLevels.h +++ b/desktop_version/src/CustomLevels.h @@ -134,6 +134,7 @@ class customlevelclass void generatecustomminimap(void); int findtrinket(int t); + int findcoin(int t); int findcrewmate(int t); int findwarptoken(int t); void findstartpoint(void); @@ -147,6 +148,7 @@ class customlevelclass static const int numrooms = maxwidth * maxheight; int contents[40 * 30 * numrooms]; int numtrinkets(void); + int numcoins(void); int numcrewmates(void); RoomProperty roomproperties[numrooms]; //Maxwidth*maxheight diff --git a/desktop_version/src/Editor.cpp b/desktop_version/src/Editor.cpp index 9201e82c96f..348d15efd7a 100644 --- a/desktop_version/src/Editor.cpp +++ b/desktop_version/src/Editor.cpp @@ -699,6 +699,10 @@ void editorrender(void) graphics.Print((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8), "////", 255 - help.glow, 255 - help.glow, 255 - help.glow, false); fillboxabs((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),32,8,graphics.getRGB(255,255,255)); break; + case 8: // Coin + graphics.draw_grid_tile(graphics.grphx.im_tiles_white, 48, (customentities[i].x * 8) - (ed.levx * 40 * 8), (customentities[i].y * 8) - (ed.levy * 30 * 8), 8, 8, graphics.huetilegetcol(8)); + fillboxabs((customentities[i].x * 8) - (ed.levx * 40 * 8), (customentities[i].y * 8) - (ed.levy * 30 * 8), 8, 8, graphics.getRGB(255, 164, 164)); + break; case 9: //Shiny Trinket graphics.draw_sprite((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),22,196,196,196); fillboxabs((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),16,16,graphics.getRGB(255, 164, 164)); diff --git a/desktop_version/src/Entity.cpp b/desktop_version/src/Entity.cpp index 912213bd78f..306de210825 100644 --- a/desktop_version/src/Entity.cpp +++ b/desktop_version/src/Entity.cpp @@ -1517,7 +1517,7 @@ void entityclass::createentity(int xp, int yp, int t, int meta1, int meta2, int //Check if it's already been collected entity.para = meta1; - if (!INBOUNDS_ARR(meta1, collect) || collect[meta1]) return; + if (coincollect.find(meta1) != coincollect.end()) return; break; case 9: //Something Shiny entity.rule = 3; @@ -2650,10 +2650,7 @@ bool entityclass::updateentities( int i ) if (entities[i].state == 1) { music.playef(4); - if (INBOUNDS_ARR(entities[i].para, collect)) - { - collect[(int) entities[i].para] = true; - } + coincollect.insert(entities[i].para); return disableentity(i); } diff --git a/desktop_version/src/Entity.h b/desktop_version/src/Entity.h index 0c7ffe2a0a6..b7a5bc08079 100644 --- a/desktop_version/src/Entity.h +++ b/desktop_version/src/Entity.h @@ -2,6 +2,7 @@ #define ENTITY_H #include +#include #include #include @@ -175,6 +176,7 @@ class entityclass std::vector blocks; bool flags[100]; bool collect[100]; + std::set coincollect; bool customcollect[100]; int platformtile; diff --git a/desktop_version/src/Game.cpp b/desktop_version/src/Game.cpp index 1a239c82781..f1f374df48e 100644 --- a/desktop_version/src/Game.cpp +++ b/desktop_version/src/Game.cpp @@ -453,6 +453,23 @@ void Game::deletecustomlevelstats(void) } } + +#define LOAD_SET_RENAME(SET_NAME, DEST) \ + if (SDL_strcmp(pKey, #SET_NAME) == 0 && pText[0] != '\0') \ + { \ + /* We're loading in 32-bit integers. If we need more than 16 chars, + * something is seriously wrong */ \ + char buffer[16]; \ + size_t start = 0; \ + size_t i = 0; \ + \ + while (next_split_s(buffer, sizeof(buffer), &start, pText, ',')) \ + { \ + DEST.insert(help.Int(buffer)); \ + ++i; \ + } \ + } + #define LOAD_ARRAY_RENAME(ARRAY_NAME, DEST) \ if (SDL_strcmp(pKey, #ARRAY_NAME) == 0 && pText[0] != '\0') \ { \ @@ -5306,6 +5323,8 @@ void Game::customloadquick(const std::string& savfile) LOAD_ARRAY_RENAME(collect, obj.collect) + LOAD_SET_RENAME(coincollect, obj.coincollect) + LOAD_ARRAY_RENAME(customcollect, obj.customcollect) if (SDL_strcmp(pKey, "finalmode") == 0) @@ -5848,6 +5867,16 @@ bool Game::customsavequick(const std::string& savfile) } xml::update_tag(msgs, "collect", collect.c_str()); + std::string coincollect; + std::set::iterator iterator = obj.coincollect.begin(); + while (iterator != obj.coincollect.end()) { + { + coincollect += help.String(*iterator) + ","; + iterator++; + } + } + xml::update_tag(msgs, "coincollect", coincollect.c_str()); + std::string customcollect; for(size_t i = 0; i < SDL_arraysize(obj.customcollect); i++ ) { @@ -6979,6 +7008,11 @@ int Game::trinkets(void) return temp; } +int Game::coins(void) +{ + return (int)obj.coincollect.size(); +} + int Game::crewmates(void) { int temp = 0; diff --git a/desktop_version/src/Game.h b/desktop_version/src/Game.h index a93ed3e0973..6c0cbe3c2d4 100644 --- a/desktop_version/src/Game.h +++ b/desktop_version/src/Game.h @@ -414,6 +414,7 @@ class Game int deathseq, lifeseq; int trinkets(void); + int coins(void); int crewmates(void); int savepoint, teleportxpos; bool teleport; diff --git a/desktop_version/src/Map.cpp b/desktop_version/src/Map.cpp index 3fc40b34c77..095c7c62bcd 100644 --- a/desktop_version/src/Map.cpp +++ b/desktop_version/src/Map.cpp @@ -1962,6 +1962,9 @@ void mapclass::loadlevel(int rx, int ry) case 3: // Disappearing platforms obj.createentity(ex, ey, 3); break; + case 8: // Coins + obj.createentity(ex, ey, 8, cl.findcoin(edi)); + break; case 9: // Trinkets obj.createentity(ex, ey, 9, cl.findtrinket(edi)); break; diff --git a/desktop_version/src/Render.cpp b/desktop_version/src/Render.cpp index a147e720af8..3d7441d0a22 100644 --- a/desktop_version/src/Render.cpp +++ b/desktop_version/src/Render.cpp @@ -1939,6 +1939,28 @@ void gamerender(void) graphics.render_roomname(roomname, roomname_r, roomname_g, roomname_b); } + bool show_coins = game.coins() > 0; +#ifndef NO_CUSTOM_LEVELS + show_coins = show_coins || (map.custommode && (cl.numcoins() > 0)); +#endif + + if (show_coins) { + std::string coinstring = help.String(game.coins()); + + int color = 255 - help.glow / 2; + + graphics.bprint(304 - coinstring.length() * 8, 231, coinstring, color, color, 196); + + if (!graphics.notextoutline) { + graphics.draw_grid_tile(graphics.grphx.im_tiles_white, 48, 310, 230, 8, 8, graphics.getRGB(0, 0, 0)); + graphics.draw_grid_tile(graphics.grphx.im_tiles_white, 48, 312, 230, 8, 8, graphics.getRGB(0, 0, 0)); + graphics.draw_grid_tile(graphics.grphx.im_tiles_white, 48, 311, 229, 8, 8, graphics.getRGB(0, 0, 0)); + graphics.draw_grid_tile(graphics.grphx.im_tiles_white, 48, 311, 231, 8, 8, graphics.getRGB(0, 0, 0)); + } + + graphics.draw_grid_tile(graphics.grphx.im_tiles_white, 48, 311, 230, 8, 8, graphics.getRGB(color, color, 196)); + } + if (map.roomtexton) { //Draw room text! @@ -2216,7 +2238,6 @@ void gamerender(void) graphics.drawtrophytext(); } - graphics.renderwithscreeneffects(); } diff --git a/desktop_version/src/Script.cpp b/desktop_version/src/Script.cpp index f972f0fdb76..85120815ba0 100644 --- a/desktop_version/src/Script.cpp +++ b/desktop_version/src/Script.cpp @@ -1243,6 +1243,14 @@ void scriptclass::run(void) position--; } } + else if (words[0] == "ifcoins") + { + if (game.coins() >= ss_toi(words[1])) + { + load("custom_" + raw_words[2]); + position--; + } + } else if (words[0] == "hidecoordinates") { map.setexplored(ss_toi(words[1]), ss_toi(words[2]), false); @@ -1391,6 +1399,7 @@ void scriptclass::run(void) obj.collect[i] = false; obj.customcollect[i] = false; } + obj.coincollect.clear(); game.deathcounts = 0; game.advancetext = false; game.hascontrol = true; @@ -3192,6 +3201,8 @@ void scriptclass::hardreset(void) SDL_memset(obj.customcollect, false, sizeof(obj.customcollect)); i = 100; //previously a for-loop iterating over collect/customcollect set this to 100 + obj.coincollect.clear(); + int theplayer = obj.getplayer(); if (INBOUNDS_VEC(theplayer, obj.entities)){ obj.entities[theplayer].tile = 0;