diff --git a/desktop_version/lang/ar/strings.xml b/desktop_version/lang/ar/strings.xml
index dc4ab172a4..d415c59d65 100644
--- a/desktop_version/lang/ar/strings.xml
+++ b/desktop_version/lang/ar/strings.xml
@@ -249,6 +249,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/ca/strings.xml b/desktop_version/lang/ca/strings.xml
index 9067a50d8f..a81210338b 100644
--- a/desktop_version/lang/ca/strings.xml
+++ b/desktop_version/lang/ca/strings.xml
@@ -244,6 +244,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/cy/strings.xml b/desktop_version/lang/cy/strings.xml
index 75233e0a01..b293efe0e1 100644
--- a/desktop_version/lang/cy/strings.xml
+++ b/desktop_version/lang/cy/strings.xml
@@ -244,6 +244,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/de/strings.xml b/desktop_version/lang/de/strings.xml
index 8bc440f81a..057f9178eb 100644
--- a/desktop_version/lang/de/strings.xml
+++ b/desktop_version/lang/de/strings.xml
@@ -244,6 +244,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/en/strings.xml b/desktop_version/lang/en/strings.xml
index 86a4217f37..b15abd005a 100644
--- a/desktop_version/lang/en/strings.xml
+++ b/desktop_version/lang/en/strings.xml
@@ -244,6 +244,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/eo/strings.xml b/desktop_version/lang/eo/strings.xml
index 6c08504366..77e2884863 100644
--- a/desktop_version/lang/eo/strings.xml
+++ b/desktop_version/lang/eo/strings.xml
@@ -244,6 +244,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/es/strings.xml b/desktop_version/lang/es/strings.xml
index 68c8a2468d..812efa152c 100644
--- a/desktop_version/lang/es/strings.xml
+++ b/desktop_version/lang/es/strings.xml
@@ -244,6 +244,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/es_419/strings.xml b/desktop_version/lang/es_419/strings.xml
index 827a3b97f9..3d2e6585f0 100644
--- a/desktop_version/lang/es_419/strings.xml
+++ b/desktop_version/lang/es_419/strings.xml
@@ -244,6 +244,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/es_AR/strings.xml b/desktop_version/lang/es_AR/strings.xml
index e2cdc45706..90ecaad166 100644
--- a/desktop_version/lang/es_AR/strings.xml
+++ b/desktop_version/lang/es_AR/strings.xml
@@ -244,6 +244,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/fr/strings.xml b/desktop_version/lang/fr/strings.xml
index 411cc564be..908d2a01fd 100644
--- a/desktop_version/lang/fr/strings.xml
+++ b/desktop_version/lang/fr/strings.xml
@@ -244,6 +244,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/ga/strings.xml b/desktop_version/lang/ga/strings.xml
index cbdf99877c..4f278b3465 100644
--- a/desktop_version/lang/ga/strings.xml
+++ b/desktop_version/lang/ga/strings.xml
@@ -245,6 +245,14 @@ Déan cóip chúltaca, ar eagla na heagla." explanation="translation maintenance
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/it/strings.xml b/desktop_version/lang/it/strings.xml
index f4798b2b6a..42226339d7 100644
--- a/desktop_version/lang/it/strings.xml
+++ b/desktop_version/lang/it/strings.xml
@@ -244,6 +244,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/ja/strings.xml b/desktop_version/lang/ja/strings.xml
index f7fe0042f1..43f206d30e 100644
--- a/desktop_version/lang/ja/strings.xml
+++ b/desktop_version/lang/ja/strings.xml
@@ -258,6 +258,14 @@ Escキーを押すと表示を終了する。" explanation="" max="38*6" max_loc
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/ko/strings.xml b/desktop_version/lang/ko/strings.xml
index e7b69f1f94..f33b999efa 100755
--- a/desktop_version/lang/ko/strings.xml
+++ b/desktop_version/lang/ko/strings.xml
@@ -244,6 +244,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/nl/strings.xml b/desktop_version/lang/nl/strings.xml
index 6d1aeebc24..af335ea782 100644
--- a/desktop_version/lang/nl/strings.xml
+++ b/desktop_version/lang/nl/strings.xml
@@ -244,6 +244,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/pl/strings.xml b/desktop_version/lang/pl/strings.xml
index 059bd1edd8..ed1fcf8d82 100644
--- a/desktop_version/lang/pl/strings.xml
+++ b/desktop_version/lang/pl/strings.xml
@@ -244,6 +244,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/pt_BR/strings.xml b/desktop_version/lang/pt_BR/strings.xml
index 0d084ab8a1..346fa40e5a 100644
--- a/desktop_version/lang/pt_BR/strings.xml
+++ b/desktop_version/lang/pt_BR/strings.xml
@@ -244,6 +244,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/pt_PT/strings.xml b/desktop_version/lang/pt_PT/strings.xml
index 3d24a84f57..5cc4fac82e 100644
--- a/desktop_version/lang/pt_PT/strings.xml
+++ b/desktop_version/lang/pt_PT/strings.xml
@@ -244,6 +244,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/ru/strings.xml b/desktop_version/lang/ru/strings.xml
index 04c6476b5e..b2cebd4af8 100644
--- a/desktop_version/lang/ru/strings.xml
+++ b/desktop_version/lang/ru/strings.xml
@@ -244,6 +244,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/szl/strings.xml b/desktop_version/lang/szl/strings.xml
index 3eadda2581..eb41bb9e94 100644
--- a/desktop_version/lang/szl/strings.xml
+++ b/desktop_version/lang/szl/strings.xml
@@ -244,6 +244,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/tr/strings.xml b/desktop_version/lang/tr/strings.xml
index c7cfdf82b7..14c269b605 100644
--- a/desktop_version/lang/tr/strings.xml
+++ b/desktop_version/lang/tr/strings.xml
@@ -244,6 +244,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/uk/strings.xml b/desktop_version/lang/uk/strings.xml
index dbfc81a9c6..2b4f8424ca 100644
--- a/desktop_version/lang/uk/strings.xml
+++ b/desktop_version/lang/uk/strings.xml
@@ -244,6 +244,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/zh/strings.xml b/desktop_version/lang/zh/strings.xml
index d437c5ba4c..73e1c34788 100644
--- a/desktop_version/lang/zh/strings.xml
+++ b/desktop_version/lang/zh/strings.xml
@@ -250,6 +250,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/lang/zh_TW/strings.xml b/desktop_version/lang/zh_TW/strings.xml
index 157c0cbaaf..2ab10df716 100644
--- a/desktop_version/lang/zh_TW/strings.xml
+++ b/desktop_version/lang/zh_TW/strings.xml
@@ -250,6 +250,14 @@
+
+
+
+
+
+
+
+
diff --git a/desktop_version/src/Entity.cpp b/desktop_version/src/Entity.cpp
index f70246d725..c7ab52fd1b 100644
--- a/desktop_version/src/Entity.cpp
+++ b/desktop_version/src/Entity.cpp
@@ -2783,6 +2783,14 @@ bool entityclass::updateentities( int i )
{
if (INBOUNDS_VEC(temp, entities) && entities[temp].vy > -3) entities[temp].vy = -3;
}
+
+ if (game.glitchlessmode && INBOUNDS_VEC(temp, entities))
+ {
+ /* Fix line clipping: Invalidate flipping eligibility so
+ * a second flip is impossible. */
+ entities[temp].onground = 0;
+ entities[temp].onroof = 0;
+ }
}
else if (entities[i].state == 2)
{
@@ -3945,6 +3953,10 @@ int entityclass::getscm(void)
}
}
+ if (game.glitchlessmode)
+ {
+ return -1;
+ }
return 0;
}
@@ -3962,6 +3974,10 @@ int entityclass::getlineat( int t )
}
}
+ if (game.glitchlessmode)
+ {
+ return -1;
+ }
return 0;
}
@@ -3981,6 +3997,10 @@ int entityclass::getcrewman( int t, int fallback /*= 0*/ )
}
}
+ if (game.glitchlessmode)
+ {
+ return -1;
+ }
return fallback;
}
@@ -4005,6 +4025,10 @@ int entityclass::getcustomcrewman( int t )
}
}
+ if (game.glitchlessmode)
+ {
+ return -1;
+ }
return 0;
}
@@ -4242,31 +4266,35 @@ static int yline( int a, int b )
return 1;
}
-bool entityclass::entityhlinecollide( int t, int l )
+bool entityclass::entityhlinecollide(const int person_idx, const int line_idx)
{
- if (!INBOUNDS_VEC(t, entities) || !INBOUNDS_VEC(l, entities))
+ if (!INBOUNDS_VEC(person_idx, entities) || !INBOUNDS_VEC(line_idx, entities))
{
vlog_error("entityhlinecollide() out-of-bounds!");
return false;
}
- //Returns true is entity t collided with the horizontal line l.
- if(entities[t].xp + entities[t].cx+entities[t].w>=entities[l].xp)
+ const entclass* person = &entities[person_idx];
+ const entclass* line = &entities[line_idx];
+
+ const bool in_vicinity =
+ person->xp + person->cx + person->w >= line->xp &&
+ person->xp + person->cx <= line->xp + line->w;
+ if (!in_vicinity)
{
- if(entities[t].xp + entities[t].cx<=entities[l].xp+entities[l].w)
- {
- int linetemp = 0;
+ return false;
+ }
- linetemp += yline(entities[t].yp, entities[l].yp);
- linetemp += yline(entities[t].yp + entities[t].h, entities[l].yp);
- linetemp += yline(entities[t].oldyp, entities[l].yp);
- linetemp += yline(entities[t].oldyp + entities[t].h, entities[l].yp);
+ /* Here we compare the person's old position versus their new one.
+ * All points are either above or below the line. Else, it's a collision. */
+ int linetemp = 0;
- if (linetemp > -4 && linetemp < 4) return true;
- return false;
- }
- }
- return false;
+ linetemp += yline(person->yp, line->yp);
+ linetemp += yline(person->yp + person->h, line->yp);
+ linetemp += yline(person->oldyp, line->yp);
+ linetemp += yline(person->oldyp + person->h, line->yp);
+
+ return linetemp > -4 && linetemp < 4;
}
bool entityclass::entityvlinecollide( int t, int l )
@@ -4848,32 +4876,40 @@ void entityclass::collisioncheck(int i, int j, bool scm /*= false*/)
}
break;
case 4: //Person vs horizontal line!
- if(game.deathseq==-1)
+ {
+ const bool collision =
+ game.deathseq == -1
+ && entities[j].onentity > 0
+ && entityhlinecollide(i, j);
+ if (!collision)
{
- //Here we compare the person's old position versus his new one versus the line.
- //All points either be above or below it. Otherwise, there was a collision this frame.
- if (entities[j].onentity > 0)
- {
- if (entityhlinecollide(i, j))
- {
- music.playef(Sound_GRAVITYLINE);
- game.gravitycontrol = (game.gravitycontrol + 1) % 2;
- game.totalflips++;
- if (game.gravitycontrol == 0)
- {
- if (entities[i].vy < 1) entities[i].vy = 1;
- }
- else
- {
- if (entities[i].vy > -1) entities[i].vy = -1;
- }
+ break;
+ }
- entities[j].state = entities[j].onentity;
- entities[j].life = 6;
- }
- }
+ music.playef(Sound_GRAVITYLINE);
+ game.gravitycontrol = (game.gravitycontrol + 1) % 2;
+ game.totalflips++;
+ if (game.gravitycontrol == 0)
+ {
+ if (entities[i].vy < 1) entities[i].vy = 1;
+ }
+ else
+ {
+ if (entities[i].vy > -1) entities[i].vy = -1;
+ }
+
+ entities[j].state = entities[j].onentity;
+ entities[j].life = 6;
+
+ if (game.glitchlessmode)
+ {
+ /* Fix line clipping: Invalidate flipping eligibility so
+ * a second flip is impossible. */
+ entities[i].onground = 0;
+ entities[i].onroof = 0;
}
break;
+ }
case 5: //Person vs vertical gravity/warp line!
if(game.deathseq==-1)
{
diff --git a/desktop_version/src/Game.cpp b/desktop_version/src/Game.cpp
index 1d7bad140c..fad16998d2 100644
--- a/desktop_version/src/Game.cpp
+++ b/desktop_version/src/Game.cpp
@@ -154,6 +154,7 @@ void Game::init(void)
musicmutebutton = 0;
glitchrunkludge = false;
+ glitchlessmode = false;
gamestate = TITLEMODE;
prevgamestate = TITLEMODE;
hascontrol = true;
@@ -4826,6 +4827,11 @@ void Game::deserializesettings(tinyxml2::XMLElement* dataNode, struct ScreenSett
GlitchrunnerMode_set(GlitchrunnerMode_string_to_enum(pText));
}
+ if (SDL_strcmp(pKey, "glitchlessmode") == 0)
+ {
+ glitchlessmode = help.Int(pText);
+ }
+
if (SDL_strcmp(pKey, "showingametimer") == 0)
{
showingametimer = help.Int(pText);
@@ -4939,6 +4945,14 @@ void Game::deserializesettings(tinyxml2::XMLElement* dataNode, struct ScreenSett
}
setdefaultcontrollerbuttons();
+
+ if (GlitchrunnerMode_get() != GlitchrunnerNone && glitchlessmode)
+ {
+ /* Glitchrunner and glitchless mode are incompatible.
+ * If the file was manually edited to enable both, disable both. */
+ GlitchrunnerMode_set(GlitchrunnerNone);
+ glitchlessmode = false;
+ }
}
bool Game::savestats(bool sync /*= true*/)
@@ -5115,6 +5129,8 @@ void Game::serializesettings(tinyxml2::XMLElement* dataNode, const struct Screen
GlitchrunnerMode_enum_to_string(GlitchrunnerMode_get())
);
+ xml::update_tag(dataNode, "glitchlessmode", (int) glitchlessmode);
+
xml::update_tag(dataNode, "showingametimer", (int) showingametimer);
xml::update_tag(dataNode, "vsync", (int) screen_settings->useVsync);
@@ -6826,7 +6842,8 @@ void Game::createmenu( enum Menu::MenuName t, bool samemenu/*= false*/ )
maxspacing = 15;
break;
case Menu::speedrunneroptions:
- option(loc::gettext("glitchrunner mode"));
+ option(loc::gettext("glitchrunner mode"), !glitchlessmode);
+ option(loc::gettext("glitchless mode"), GlitchrunnerMode_get() == GlitchrunnerNone);
option(loc::gettext("input delay"));
option(loc::gettext("interact button"));
option(loc::gettext("fake load screen"));
diff --git a/desktop_version/src/Game.h b/desktop_version/src/Game.h
index 362a956ced..fdac0c0d34 100644
--- a/desktop_version/src/Game.h
+++ b/desktop_version/src/Game.h
@@ -330,6 +330,7 @@ class Game
int state, statedelay;
bool glitchrunkludge;
+ bool glitchlessmode;
enum GameGamestate gamestate;
enum GameGamestate prevgamestate; //only used sometimes
diff --git a/desktop_version/src/Input.cpp b/desktop_version/src/Input.cpp
index 468c265aac..fce36a0df6 100644
--- a/desktop_version/src/Input.cpp
+++ b/desktop_version/src/Input.cpp
@@ -787,36 +787,56 @@ static void menuactionpress(void)
{
case 0:
// Glitchrunner mode
+ if (game.glitchlessmode)
+ {
+ music.playef(Sound_CRY);
+ break;
+ }
+
music.playef(Sound_VIRIDIAN);
game.createmenu(Menu::setglitchrunner);
game.currentmenuoption = GlitchrunnerMode_get();
map.nexttowercolour();
break;
case 1:
+ /* Glitchless mode */
+ if (GlitchrunnerMode_get() != GlitchrunnerNone)
+ {
+ music.playef(2);
+ break;
+ }
+
+ music.playef(11);
+ game.glitchlessmode = !game.glitchlessmode;
+
+ /* Recreate menu to update glitchrunner mode */
+ game.createmenu(game.currentmenuname, true);
+ break;
+ case 2:
/* Input delay */
music.playef(Sound_VIRIDIAN);
game.inputdelay = !game.inputdelay;
game.savestatsandsettings_menu();
break;
- case 2:
+ case 3:
/* Interact button toggle */
music.playef(Sound_VIRIDIAN);
game.separate_interact = !game.separate_interact;
game.savestatsandsettings_menu();
break;
- case 3:
+ case 4:
// toggle fake load screen
game.skipfakeload = !game.skipfakeload;
game.savestatsandsettings_menu();
music.playef(Sound_VIRIDIAN);
break;
- case 4:
+ case 5:
// toggle in game timer
game.showingametimer = !game.showingametimer;
game.savestatsandsettings_menu();
music.playef(Sound_VIRIDIAN);
break;
- case 5:
+ case 6:
// english sprites
loc::english_sprites = !loc::english_sprites;
if (!loc::english_sprites)
@@ -2989,7 +3009,10 @@ void gameinput(void)
game.menupage = 30; // Pause screen
}
- if (game.deathseq == -1 && (key.isDown(SDLK_r) || key.isDown(game.controllerButton_restart)) && !game.nodeathmode)// && map.custommode) //Have fun glitchrunners!
+ if (game.deathseq == -1 &&
+ (key.isDown(SDLK_r) || key.isDown(game.controllerButton_restart))
+ && !game.nodeathmode
+ && (map.custommode || !game.glitchlessmode)) /* Have fun glitchrunners! */
{
game.deathseq = 30;
}
diff --git a/desktop_version/src/Map.cpp b/desktop_version/src/Map.cpp
index 747ebc383d..8670f6032b 100644
--- a/desktop_version/src/Map.cpp
+++ b/desktop_version/src/Map.cpp
@@ -854,6 +854,20 @@ void mapclass::resetplayer(const bool player_died)
game.scmprogress = game.roomx - 40;
}
}
+
+ if (game.glitchlessmode)
+ {
+ /* Fix warp token death warps:
+ * Reset the state of all warp tokens to 0. */
+ for (size_t i = 0; i < obj.entities.size(); i++)
+ {
+ entclass* entity = &obj.entities[i];
+ if (entity->type == 11)
+ {
+ entity->state = 0;
+ }
+ }
+ }
}
void mapclass::warpto(int rx, int ry , int t, int tx, int ty)
diff --git a/desktop_version/src/Render.cpp b/desktop_version/src/Render.cpp
index 20efc8ffd0..a42352d647 100644
--- a/desktop_version/src/Render.cpp
+++ b/desktop_version/src/Render.cpp
@@ -1022,10 +1022,38 @@ static void menurender(void)
{
font::print(PR_2X | PR_CEN, -1, 30, loc::gettext("Glitchrunner Mode"), tr, tg, tb);
int next_y = font::print_wrap(PR_CEN, -1, 65, loc::gettext("Re-enable glitches that existed in previous versions of the game."), tr, tg, tb);
+
+ if (game.glitchlessmode)
+ {
+ font::print_wrap(PR_CEN, -1, next_y, loc::gettext("Glitchrunner mode is incompatible with glitchless mode."), tr, tg, tb);
+ break;
+ }
+
drawglitchrunnertext(next_y);
break;
}
case 1:
+ {
+ font::print(PR_2X | PR_CEN, -1, 30, loc::gettext("Glitchless Mode"), tr, tg, tb);
+ const int next_y = font::print_wrap(PR_CEN, -1, 65, loc::gettext("Disable glitches that might otherwise be useful for speedruns."), tr, tg, tb);
+
+ if (GlitchrunnerMode_get() != GlitchrunnerNone)
+ {
+ font::print_wrap(PR_CEN, -1, next_y, loc::gettext("Glitchless mode is incompatible with glitchrunner mode."), tr, tg, tb);
+ break;
+ }
+
+ if (game.glitchlessmode)
+ {
+ font::print_wrap(PR_CEN, -1, next_y, loc::gettext("Glitchless mode is ON"), tr, tg, tb);
+ }
+ else
+ {
+ font::print_wrap(PR_CEN, -1, next_y, loc::gettext("Glitchless mode is OFF"), tr / 2, tg / 2, tb / 2);
+ }
+ break;
+ }
+ case 2:
{
font::print(PR_2X | PR_CEN, -1, 30, loc::gettext("Input Delay"), tr, tg, tb);
int next_y = font::print_wrap(PR_CEN, -1, 65, loc::gettext("Re-enable the 1-frame input delay from previous versions of the game."), tr, tg, tb);
@@ -1039,7 +1067,7 @@ static void menurender(void)
}
break;
}
- case 2:
+ case 3:
{
char buffer[SCREEN_WIDTH_CHARS + 1];
const char* button;
@@ -1060,7 +1088,7 @@ static void menurender(void)
font::print_wrap(PR_CEN, -1, next_y, buffer, tr, tg, tb);
break;
}
- case 3:
+ case 4:
{
font::print(PR_2X | PR_CEN, -1, 30, loc::gettext("Fake Load Screen"), tr, tg, tb);
int next_y = font::print_wrap(PR_CEN, -1, 65, loc::gettext("Disable the fake loading screen which appears on game launch."), tr, tg, tb);
@@ -1070,7 +1098,7 @@ static void menurender(void)
font::print_wrap(PR_CEN, -1, next_y, loc::gettext("Fake loading screen is ON"), tr, tg, tb);
break;
}
- case 4:
+ case 5:
{
font::print(PR_2X | PR_CEN, -1, 30, loc::gettext("In-Game Timer"), tr, tg, tb);
int next_y = font::print_wrap(PR_CEN, -1, 65, loc::gettext("Toggle the in-game timer outside of time trials."), tr, tg, tb);
@@ -1084,7 +1112,7 @@ static void menurender(void)
}
break;
}
- case 5:
+ case 6:
{
font::print(PR_2X | PR_CEN, -1, 30, loc::gettext("English Sprites"), tr, tg, tb);
int next_y = font::print_wrap(PR_CEN, -1, 65, loc::gettext("Show the original English word enemies regardless of your language setting."), tr, tg, tb);
@@ -2265,6 +2293,12 @@ static void mode_indicator_text(const int alpha)
y += spacing;
}
+ if (game.glitchlessmode)
+ {
+ font::print(flags, x, y, loc::gettext("Glitchless mode enabled"), r, g, b);
+ y += spacing;
+ }
+
if (graphics.flipmode)
{
const char* english = "Flip Mode enabled";
@@ -2356,6 +2390,7 @@ void gamerender(void)
);
bool any_mode_active = map.invincibility
|| GlitchrunnerMode_get() != GlitchrunnerNone
+ || game.glitchlessmode
|| graphics.flipmode
|| game.slowdown < 30;
bool draw_mode_indicator_text = mode_indicator_alpha > 100 && any_mode_active;
diff --git a/desktop_version/src/Script.cpp b/desktop_version/src/Script.cpp
index a58b1735a1..8c93566bc1 100644
--- a/desktop_version/src/Script.cpp
+++ b/desktop_version/src/Script.cpp
@@ -131,7 +131,7 @@ void scriptclass::tokenize( const std::string& t )
}
}
-static int getcolorfromname(std::string name)
+static int getcolorfromname(const std::string& name)
{
if (name == "player") return CYAN;
else if (name == "cyan") return CYAN;
@@ -149,7 +149,7 @@ static int getcolorfromname(std::string name)
return color; // Last effort to give a valid color, maybe they just input the color?
}
-static int getcrewmanfromname(std::string name)
+static int getcrewmanfromname(const std::string& name)
{
if (name == "player") return obj.getplayer(); // Return the player
int color = getcolorfromname(name); // Maybe they passed in a crewmate name, or an id?
@@ -157,6 +157,28 @@ static int getcrewmanfromname(std::string name)
return obj.getcrewman(color);
}
+static bool color_valid(const int index, const std::string& name)
+{
+ if (!INBOUNDS_VEC(index, obj.entities))
+ {
+ return false;
+ }
+
+ if (!game.glitchlessmode)
+ {
+ return true;
+ }
+
+ const int color = getcolorfromname(name);
+ const bool using_aem = color == -1;
+ if (using_aem)
+ {
+ return true;
+ }
+
+ return obj.entities[index].colour == color;
+}
+
/* Also used in gamestate 1001. */
void foundtrinket_textbox1(textboxclass* THIS);
@@ -1022,7 +1044,7 @@ void scriptclass::run(void)
int crewmate = getcrewmanfromname(words[1]);
if (crewmate != -1) i = crewmate; // Ensure AEM is kept
- if (INBOUNDS_VEC(i, obj.entities))
+ if (color_valid(i, words[1]))
{
obj.entities[i].tile = ss_toi(words[2]);
}