Skip to content

Commit 90b832c

Browse files
committed
Reimplement coins as a usable feature
- Make coins use their own ID array in save files, instead of sharing the trinket ID array - Add coin editor entities to allow external tools to use coins, and help the game figure out when it should render the coin display - Unlimits the coin amount and stores it differently than other collectibles - Add `ifcoins` logic command to match trinkets
1 parent d9859d4 commit 90b832c

File tree

10 files changed

+105
-6
lines changed

10 files changed

+105
-6
lines changed

desktop_version/src/CustomLevels.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,17 @@ int customlevelclass::findtrinket(int t)
952952
return 0;
953953
}
954954

955+
int customlevelclass::findcoin(int t)
956+
{
957+
int tcoin = 0;
958+
for (int i = 0; i < (int)customentities.size(); i++)
959+
{
960+
if (i == t) return tcoin;
961+
if (customentities[i].t == 8) tcoin++;
962+
}
963+
return 0;
964+
}
965+
955966
int customlevelclass::findcrewmate(int t)
956967
{
957968
int ttrinket=0;
@@ -1808,6 +1819,19 @@ int customlevelclass::numtrinkets(void)
18081819
return temp;
18091820
}
18101821

1822+
int customlevelclass::numcoins(void)
1823+
{
1824+
int temp = 0;
1825+
for (size_t i = 0; i < customentities.size(); i++)
1826+
{
1827+
if (customentities[i].t == 8 && inbounds(&customentities[i]))
1828+
{
1829+
temp++;
1830+
}
1831+
}
1832+
return temp;
1833+
}
1834+
18111835
int customlevelclass::numcrewmates(void)
18121836
{
18131837
int temp = 0;

desktop_version/src/CustomLevels.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ class customlevelclass
134134
void generatecustomminimap(void);
135135

136136
int findtrinket(int t);
137+
int findcoin(int t);
137138
int findcrewmate(int t);
138139
int findwarptoken(int t);
139140
void findstartpoint(void);
@@ -147,6 +148,7 @@ class customlevelclass
147148
static const int numrooms = maxwidth * maxheight;
148149
int contents[40 * 30 * numrooms];
149150
int numtrinkets(void);
151+
int numcoins(void);
150152
int numcrewmates(void);
151153
RoomProperty roomproperties[numrooms]; //Maxwidth*maxheight
152154

desktop_version/src/Editor.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,10 @@ void editorrender(void)
699699
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);
700700
fillboxabs((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),32,8,graphics.getRGB(255,255,255));
701701
break;
702+
case 8: // Coin
703+
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));
704+
fillboxabs((customentities[i].x * 8) - (ed.levx * 40 * 8), (customentities[i].y * 8) - (ed.levy * 30 * 8), 8, 8, graphics.getRGB(255, 164, 164));
705+
break;
702706
case 9: //Shiny Trinket
703707
graphics.draw_sprite((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),22,196,196,196);
704708
fillboxabs((customentities[i].x*8)- (ed.levx*40*8),(customentities[i].y*8)- (ed.levy*30*8),16,16,graphics.getRGB(255, 164, 164));

desktop_version/src/Entity.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,7 +1517,7 @@ void entityclass::createentity(int xp, int yp, int t, int meta1, int meta2, int
15171517

15181518
//Check if it's already been collected
15191519
entity.para = meta1;
1520-
if (!INBOUNDS_ARR(meta1, collect) || collect[meta1]) return;
1520+
if (coincollect.find(meta1) != coincollect.end()) return;
15211521
break;
15221522
case 9: //Something Shiny
15231523
entity.rule = 3;
@@ -2650,10 +2650,7 @@ bool entityclass::updateentities( int i )
26502650
if (entities[i].state == 1)
26512651
{
26522652
music.playef(4);
2653-
if (INBOUNDS_ARR(entities[i].para, collect))
2654-
{
2655-
collect[(int) entities[i].para] = true;
2656-
}
2653+
coincollect.insert(entities[i].para);
26572654

26582655
return disableentity(i);
26592656
}

desktop_version/src/Entity.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define ENTITY_H
33

44
#include <SDL.h>
5+
#include <set>
56
#include <string>
67
#include <vector>
78

@@ -175,6 +176,7 @@ class entityclass
175176
std::vector<blockclass> blocks;
176177
bool flags[100];
177178
bool collect[100];
179+
std::set<int> coincollect;
178180
bool customcollect[100];
179181

180182
int platformtile;

desktop_version/src/Game.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,23 @@ void Game::deletecustomlevelstats(void)
453453
}
454454
}
455455

456+
457+
#define LOAD_SET_RENAME(SET_NAME, DEST) \
458+
if (SDL_strcmp(pKey, #SET_NAME) == 0 && pText[0] != '\0') \
459+
{ \
460+
/* We're loading in 32-bit integers. If we need more than 16 chars,
461+
* something is seriously wrong */ \
462+
char buffer[16]; \
463+
size_t start = 0; \
464+
size_t i = 0; \
465+
\
466+
while (next_split_s(buffer, sizeof(buffer), &start, pText, ',')) \
467+
{ \
468+
DEST.insert(help.Int(buffer)); \
469+
++i; \
470+
} \
471+
}
472+
456473
#define LOAD_ARRAY_RENAME(ARRAY_NAME, DEST) \
457474
if (SDL_strcmp(pKey, #ARRAY_NAME) == 0 && pText[0] != '\0') \
458475
{ \
@@ -5306,6 +5323,8 @@ void Game::customloadquick(const std::string& savfile)
53065323

53075324
LOAD_ARRAY_RENAME(collect, obj.collect)
53085325

5326+
LOAD_SET_RENAME(coincollect, obj.coincollect)
5327+
53095328
LOAD_ARRAY_RENAME(customcollect, obj.customcollect)
53105329

53115330
if (SDL_strcmp(pKey, "finalmode") == 0)
@@ -5848,6 +5867,16 @@ bool Game::customsavequick(const std::string& savfile)
58485867
}
58495868
xml::update_tag(msgs, "collect", collect.c_str());
58505869

5870+
std::string coincollect;
5871+
std::set<int>::iterator iterator = obj.coincollect.begin();
5872+
while (iterator != obj.coincollect.end()) {
5873+
{
5874+
coincollect += help.String(*iterator) + ",";
5875+
iterator++;
5876+
}
5877+
}
5878+
xml::update_tag(msgs, "coincollect", coincollect.c_str());
5879+
58515880
std::string customcollect;
58525881
for(size_t i = 0; i < SDL_arraysize(obj.customcollect); i++ )
58535882
{
@@ -6979,6 +7008,11 @@ int Game::trinkets(void)
69797008
return temp;
69807009
}
69817010

7011+
int Game::coins(void)
7012+
{
7013+
return (int)obj.coincollect.size();
7014+
}
7015+
69827016
int Game::crewmates(void)
69837017
{
69847018
int temp = 0;

desktop_version/src/Game.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ class Game
414414
int deathseq, lifeseq;
415415

416416
int trinkets(void);
417+
int coins(void);
417418
int crewmates(void);
418419
int savepoint, teleportxpos;
419420
bool teleport;

desktop_version/src/Map.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1962,6 +1962,9 @@ void mapclass::loadlevel(int rx, int ry)
19621962
case 3: // Disappearing platforms
19631963
obj.createentity(ex, ey, 3);
19641964
break;
1965+
case 8: // Coins
1966+
obj.createentity(ex, ey, 8, cl.findcoin(edi));
1967+
break;
19651968
case 9: // Trinkets
19661969
obj.createentity(ex, ey, 9, cl.findtrinket(edi));
19671970
break;

desktop_version/src/Render.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1939,6 +1939,28 @@ void gamerender(void)
19391939
graphics.render_roomname(roomname, roomname_r, roomname_g, roomname_b);
19401940
}
19411941

1942+
bool show_coins = game.coins() > 0;
1943+
#ifndef NO_CUSTOM_LEVELS
1944+
show_coins = show_coins || (map.custommode && (cl.numcoins() > 0));
1945+
#endif
1946+
1947+
if (show_coins) {
1948+
std::string coinstring = help.String(game.coins());
1949+
1950+
int color = 255 - help.glow / 2;
1951+
1952+
graphics.bprint(304 - coinstring.length() * 8, 231, coinstring, color, color, 196);
1953+
1954+
if (!graphics.notextoutline) {
1955+
graphics.draw_grid_tile(graphics.grphx.im_tiles_white, 48, 310, 230, 8, 8, graphics.getRGB(0, 0, 0));
1956+
graphics.draw_grid_tile(graphics.grphx.im_tiles_white, 48, 312, 230, 8, 8, graphics.getRGB(0, 0, 0));
1957+
graphics.draw_grid_tile(graphics.grphx.im_tiles_white, 48, 311, 229, 8, 8, graphics.getRGB(0, 0, 0));
1958+
graphics.draw_grid_tile(graphics.grphx.im_tiles_white, 48, 311, 231, 8, 8, graphics.getRGB(0, 0, 0));
1959+
}
1960+
1961+
graphics.draw_grid_tile(graphics.grphx.im_tiles_white, 48, 311, 230, 8, 8, graphics.getRGB(color, color, 196));
1962+
}
1963+
19421964
if (map.roomtexton)
19431965
{
19441966
//Draw room text!
@@ -2216,7 +2238,6 @@ void gamerender(void)
22162238
graphics.drawtrophytext();
22172239
}
22182240

2219-
22202241
graphics.renderwithscreeneffects();
22212242
}
22222243

desktop_version/src/Script.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,6 +1243,14 @@ void scriptclass::run(void)
12431243
position--;
12441244
}
12451245
}
1246+
else if (words[0] == "ifcoins")
1247+
{
1248+
if (game.coins() >= ss_toi(words[1]))
1249+
{
1250+
load("custom_" + raw_words[2]);
1251+
position--;
1252+
}
1253+
}
12461254
else if (words[0] == "hidecoordinates")
12471255
{
12481256
map.setexplored(ss_toi(words[1]), ss_toi(words[2]), false);
@@ -1391,6 +1399,7 @@ void scriptclass::run(void)
13911399
obj.collect[i] = false;
13921400
obj.customcollect[i] = false;
13931401
}
1402+
obj.coincollect.clear();
13941403
game.deathcounts = 0;
13951404
game.advancetext = false;
13961405
game.hascontrol = true;
@@ -3192,6 +3201,8 @@ void scriptclass::hardreset(void)
31923201
SDL_memset(obj.customcollect, false, sizeof(obj.customcollect));
31933202
i = 100; //previously a for-loop iterating over collect/customcollect set this to 100
31943203

3204+
obj.coincollect.clear();
3205+
31953206
int theplayer = obj.getplayer();
31963207
if (INBOUNDS_VEC(theplayer, obj.entities)){
31973208
obj.entities[theplayer].tile = 0;

0 commit comments

Comments
 (0)