mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 09:11:48 +00:00
Merge branch 'failed-level-lua' into 'next'
[SUGOI] Make stagefailed more useful, add linedef executor to toggle, and expose to Lua Closes #361 See merge request STJr/SRB2!1463
This commit is contained in:
commit
2cb920a5a6
6 changed files with 112 additions and 42 deletions
|
@ -496,7 +496,7 @@ extern UINT32 lastcustomtol;
|
|||
|
||||
extern tic_t totalplaytime;
|
||||
|
||||
extern UINT8 stagefailed;
|
||||
extern boolean stagefailed;
|
||||
|
||||
// Emeralds stored as bits to throw savegame hackers off.
|
||||
extern UINT16 emeralds;
|
||||
|
|
15
src/g_game.c
15
src/g_game.c
|
@ -169,7 +169,7 @@ static boolean exitgame = false;
|
|||
static boolean retrying = false;
|
||||
static boolean retryingmodeattack = false;
|
||||
|
||||
UINT8 stagefailed; // Used for GEMS BONUS? Also to see if you beat the stage.
|
||||
boolean stagefailed = false; // Used for GEMS BONUS? Also to see if you beat the stage.
|
||||
|
||||
UINT16 emeralds;
|
||||
INT32 luabanks[NUM_LUABANKS];
|
||||
|
@ -3743,7 +3743,7 @@ static void G_UpdateVisited(void)
|
|||
// Update visitation flags?
|
||||
if ((!modifiedgame || savemoddata) // Not modified
|
||||
&& !multiplayer && !demoplayback && (gametype == GT_COOP) // SP/RA/NiGHTS mode
|
||||
&& !(spec && stagefailed)) // Not failed the special stage
|
||||
&& !stagefailed) // Did not fail the stage
|
||||
{
|
||||
UINT8 earnedEmblems;
|
||||
|
||||
|
@ -3964,7 +3964,7 @@ static void G_DoCompleted(void)
|
|||
// If the current gametype has no intermission screen set, then don't start it.
|
||||
Y_DetermineIntermissionType();
|
||||
|
||||
if ((skipstats && !modeattacking) || (spec && modeattacking && stagefailed) || (intertype == int_none))
|
||||
if ((skipstats && !modeattacking) || (modeattacking && stagefailed) || (intertype == int_none))
|
||||
{
|
||||
G_UpdateVisited();
|
||||
G_HandleSaveLevel();
|
||||
|
@ -3996,8 +3996,15 @@ void G_AfterIntermission(void)
|
|||
|
||||
HU_ClearCEcho();
|
||||
|
||||
if ((gametyperules & GTR_CUTSCENES) && mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking && skipstats <= 1 && (gamecomplete || !(marathonmode & MA_NOCUTSCENES))) // Start a custom cutscene.
|
||||
if ((gametyperules & GTR_CUTSCENES) && mapheaderinfo[gamemap-1]->cutscenenum
|
||||
&& !modeattacking
|
||||
&& skipstats <= 1
|
||||
&& (gamecomplete || !(marathonmode & MA_NOCUTSCENES))
|
||||
&& stagefailed == false)
|
||||
{
|
||||
// Start a custom cutscene.
|
||||
F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nextmap < 1100-1)
|
||||
|
|
|
@ -380,6 +380,9 @@ int LUA_PushGlobals(lua_State *L, const char *word)
|
|||
} else if (fastcmp(word, "gamestate")) {
|
||||
lua_pushinteger(L, gamestate);
|
||||
return 1;
|
||||
} else if (fastcmp(word, "stagefailed")) {
|
||||
lua_pushboolean(L, stagefailed);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -429,6 +432,8 @@ int LUA_CheckGlobals(lua_State *L, const char *word)
|
|||
}
|
||||
else if (fastcmp(word, "mapmusflags"))
|
||||
mapmusflags = (UINT16)luaL_checkinteger(L, 2);
|
||||
else if (fastcmp(word, "stagefailed"))
|
||||
stagefailed = luaL_checkboolean(L, 2);
|
||||
else
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -3443,8 +3443,10 @@ static void P_InitLevelSettings(void)
|
|||
numstarposts = 0;
|
||||
ssspheres = timeinmap = 0;
|
||||
|
||||
// special stage
|
||||
stagefailed = true; // assume failed unless proven otherwise - P_GiveEmerald or emerald touchspecial
|
||||
// Assume Special Stages were failed in unless proven otherwise - via P_GiveEmerald or emerald touchspecial
|
||||
// Normal stages will default to be OK, until a Lua script / linedef executor says otherwise.
|
||||
stagefailed = G_IsSpecialStage(gamemap);
|
||||
|
||||
// Reset temporary record data
|
||||
memset(&ntemprecords, 0, sizeof(nightsdata_t));
|
||||
|
||||
|
|
15
src/p_spec.c
15
src/p_spec.c
|
@ -3902,6 +3902,21 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
}
|
||||
break;
|
||||
|
||||
case 466: // Set level failure state
|
||||
{
|
||||
if (line->flags & ML_NOCLIMB)
|
||||
{
|
||||
stagefailed = false;
|
||||
CONS_Debug(DBG_GAMELOGIC, "Stage can be completed successfully!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
stagefailed = true;
|
||||
CONS_Debug(DBG_GAMELOGIC, "Stage will end in failure...\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 480: // Polyobj_DoorSlide
|
||||
case 481: // Polyobj_DoorSwing
|
||||
PolyDoor(line);
|
||||
|
|
111
src/y_inter.c
111
src/y_inter.c
|
@ -1330,24 +1330,40 @@ void Y_StartIntermission(void)
|
|||
usetile = false;
|
||||
|
||||
// set up the "got through act" message according to skin name
|
||||
// too long so just show "YOU GOT THROUGH THE ACT"
|
||||
if (strlen(skins[players[consoleplayer].skin].realname) > 13)
|
||||
if (stagefailed)
|
||||
{
|
||||
strcpy(data.coop.passed1, "you got");
|
||||
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "through act" : "through the act");
|
||||
strcpy(data.coop.passed1, mapheaderinfo[gamemap-1]->lvlttl);
|
||||
|
||||
if (mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)
|
||||
{
|
||||
data.spec.passed2[0] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(data.coop.passed2, "Zone");
|
||||
}
|
||||
}
|
||||
// long enough that "X GOT" won't fit so use "X PASSED THE ACT"
|
||||
else if (strlen(skins[players[consoleplayer].skin].realname) > 8)
|
||||
{
|
||||
strcpy(data.coop.passed1, skins[players[consoleplayer].skin].realname);
|
||||
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "passed act" : "passed the act");
|
||||
}
|
||||
// length is okay for normal use
|
||||
else
|
||||
{
|
||||
snprintf(data.coop.passed1, sizeof data.coop.passed1, "%s got",
|
||||
skins[players[consoleplayer].skin].realname);
|
||||
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "through act" : "through the act");
|
||||
// too long so just show "YOU GOT THROUGH THE ACT"
|
||||
if (strlen(skins[players[consoleplayer].skin].realname) > 13)
|
||||
{
|
||||
strcpy(data.coop.passed1, "you got");
|
||||
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "through act" : "through the act");
|
||||
}
|
||||
// long enough that "X GOT" won't fit so use "X PASSED THE ACT"
|
||||
else if (strlen(skins[players[consoleplayer].skin].realname) > 8)
|
||||
{
|
||||
strcpy(data.coop.passed1, skins[players[consoleplayer].skin].realname);
|
||||
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "passed act" : "passed the act");
|
||||
}
|
||||
// length is okay for normal use
|
||||
else
|
||||
{
|
||||
snprintf(data.coop.passed1, sizeof data.coop.passed1, "%s got",
|
||||
skins[players[consoleplayer].skin].realname);
|
||||
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "through act" : "through the act");
|
||||
}
|
||||
}
|
||||
|
||||
// set X positions
|
||||
|
@ -1364,6 +1380,13 @@ void Y_StartIntermission(void)
|
|||
// The above value is not precalculated because it needs only be computed once
|
||||
// at the start of intermission, and precalculating it would preclude mods
|
||||
// changing the font to one of a slightly different width.
|
||||
|
||||
if ((stagefailed) && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
|
||||
{
|
||||
// Bit of a hack, offset so that the "Zone" text is right aligned like title cards.
|
||||
data.coop.passedx2 = (data.coop.passedx1 + V_LevelNameWidth(data.coop.passed1)) - V_LevelNameWidth(data.coop.passed2);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1784,21 +1807,30 @@ static void Y_SetTimeBonus(player_t *player, y_bonus_t *bstruct)
|
|||
strncpy(bstruct->patch, "YB_TIME", sizeof(bstruct->patch));
|
||||
bstruct->display = true;
|
||||
|
||||
// calculate time bonus
|
||||
secs = player->realtime / TICRATE;
|
||||
if (secs < 30) /* :30 */ bonus = 50000;
|
||||
else if (secs < 60) /* 1:00 */ bonus = 10000;
|
||||
else if (secs < 90) /* 1:30 */ bonus = 5000;
|
||||
else if (secs < 120) /* 2:00 */ bonus = 4000;
|
||||
else if (secs < 180) /* 3:00 */ bonus = 3000;
|
||||
else if (secs < 240) /* 4:00 */ bonus = 2000;
|
||||
else if (secs < 300) /* 5:00 */ bonus = 1000;
|
||||
else if (secs < 360) /* 6:00 */ bonus = 500;
|
||||
else if (secs < 420) /* 7:00 */ bonus = 400;
|
||||
else if (secs < 480) /* 8:00 */ bonus = 300;
|
||||
else if (secs < 540) /* 9:00 */ bonus = 200;
|
||||
else if (secs < 600) /* 10:00 */ bonus = 100;
|
||||
else /* TIME TAKEN: TOO LONG */ bonus = 0;
|
||||
if (stagefailed == true)
|
||||
{
|
||||
// Time Bonus would be very easy to cheese by failing immediately.
|
||||
bonus = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// calculate time bonus
|
||||
secs = player->realtime / TICRATE;
|
||||
if (secs < 30) /* :30 */ bonus = 50000;
|
||||
else if (secs < 60) /* 1:00 */ bonus = 10000;
|
||||
else if (secs < 90) /* 1:30 */ bonus = 5000;
|
||||
else if (secs < 120) /* 2:00 */ bonus = 4000;
|
||||
else if (secs < 180) /* 3:00 */ bonus = 3000;
|
||||
else if (secs < 240) /* 4:00 */ bonus = 2000;
|
||||
else if (secs < 300) /* 5:00 */ bonus = 1000;
|
||||
else if (secs < 360) /* 6:00 */ bonus = 500;
|
||||
else if (secs < 420) /* 7:00 */ bonus = 400;
|
||||
else if (secs < 480) /* 8:00 */ bonus = 300;
|
||||
else if (secs < 540) /* 9:00 */ bonus = 200;
|
||||
else if (secs < 600) /* 10:00 */ bonus = 100;
|
||||
else /* TIME TAKEN: TOO LONG */ bonus = 0;
|
||||
}
|
||||
|
||||
bstruct->points = bonus;
|
||||
}
|
||||
|
||||
|
@ -1851,12 +1883,21 @@ static void Y_SetGuardBonus(player_t *player, y_bonus_t *bstruct)
|
|||
strncpy(bstruct->patch, "YB_GUARD", sizeof(bstruct->patch));
|
||||
bstruct->display = true;
|
||||
|
||||
if (player->timeshit == 0) bonus = 10000;
|
||||
else if (player->timeshit == 1) bonus = 5000;
|
||||
else if (player->timeshit == 2) bonus = 1000;
|
||||
else if (player->timeshit == 3) bonus = 500;
|
||||
else if (player->timeshit == 4) bonus = 100;
|
||||
else bonus = 0;
|
||||
if (stagefailed == true)
|
||||
{
|
||||
// "No-hit" runs would be very easy to cheese by failing immediately.
|
||||
bonus = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (player->timeshit == 0) bonus = 10000;
|
||||
else if (player->timeshit == 1) bonus = 5000;
|
||||
else if (player->timeshit == 2) bonus = 1000;
|
||||
else if (player->timeshit == 3) bonus = 500;
|
||||
else if (player->timeshit == 4) bonus = 100;
|
||||
else bonus = 0;
|
||||
}
|
||||
|
||||
bstruct->points = bonus;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue