From 20396e14cb5e956c7c4bd085b81b538c5b2dc9fe Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Tue, 6 May 2025 20:43:31 +0200 Subject: [PATCH] Operation: Save Megablock Castle Two new finish line flags: Single-Use, to make a finish line that only works on lap 0 and nowhere else Require Sector Special, for the maps with FOF finish lines For waypoints, the "flip finish line" flag on arg0 has been removed. Instead, arg4 is now dedicated to holding flags applied to the finish line. --- .../blanudmf/Includes/BlanKart_linedefs.cfg | 10 +++++-- extras/blanudmf/Includes/BlanKart_things.cfg | 12 +++++++- src/k_kart.c | 2 +- src/p_mobj.c | 26 ++++++++-------- src/p_spec.c | 30 +++++++++++++++++++ src/p_spec.h | 5 ++-- 6 files changed, 66 insertions(+), 19 deletions(-) diff --git a/extras/blanudmf/Includes/BlanKart_linedefs.cfg b/extras/blanudmf/Includes/BlanKart_linedefs.cfg index c32780194..a9734db93 100644 --- a/extras/blanudmf/Includes/BlanKart_linedefs.cfg +++ b/extras/blanudmf/Includes/BlanKart_linedefs.cfg @@ -82,8 +82,14 @@ udmf prefix = "(2001)"; arg0 { - title = "Flip?"; - type = 3; + title = "Flags"; + type = 12; + enum + { + 1 = "Flip"; + 2 = "Single-use"; + 4 = "Require sector special"; + } } } diff --git a/extras/blanudmf/Includes/BlanKart_things.cfg b/extras/blanudmf/Includes/BlanKart_things.cfg index f72c66c88..876cf637e 100644 --- a/extras/blanudmf/Includes/BlanKart_things.cfg +++ b/extras/blanudmf/Includes/BlanKart_things.cfg @@ -5372,7 +5372,6 @@ udmf 2 = "Shortcut"; 4 = "No respawn"; 8 = "Finish line"; - 16 = "Flip special (patch)"; } } arg3 @@ -5389,6 +5388,17 @@ udmf 5 = "End drift"; } } + arg4 + { + title = "Patch finish flags"; + type = 12; + enum + { + 1 = "Flip"; + 2 = "Single-use"; + 4 = "Require sector special"; + } + } } 2004 diff --git a/src/k_kart.c b/src/k_kart.c index 7ead79de4..d962b75c1 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -11004,7 +11004,7 @@ boolean K_SlipdashActive(void) boolean K_UsingLegacyCheckpoints(void) { - if (patch_version && waypointcap) + if (K_UsingPatchedMap() && waypointcap) { // we're presumably adding waypoints to an existing map return false; diff --git a/src/p_mobj.c b/src/p_mobj.c index 67df9b58b..852d81357 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12870,7 +12870,7 @@ static boolean P_SetupParticleGen(mapthing_t *mthing, mobj_t *mobj) return true; } -static void SpreadFinishLine(line_t *line, line_t *prev, boolean flip) +static void SpreadFinishLine(line_t *line, line_t *prev, INT32 args) { size_t i; for (i = 0; i < numlines; i++) @@ -12879,12 +12879,11 @@ static void SpreadFinishLine(line_t *line, line_t *prev, boolean flip) if (line2 != line && line2 != prev && (line2->slopetype == ST_HORIZONTAL || line2->slopetype == ST_VERTICAL) && line2->slopetype == line->slopetype && (line->v1 == line2->v1 || line->v2 == line2->v2 || line->v1 == line2->v2 || line->v2 == line2->v1)) { - boolean flipped = line->v1 == line2->v1 || line->v2 == line2->v2; + boolean flipped = line->v1 == line2->v1 || line->v2 == line2->v2 ? TMCFF_FLIP : 0; line2->special = 2001; // Finish Line line2->activation = SPAC_CROSS|SPAC_REPEATSPECIAL; - if (flipped != flip) - line2->args[0] |= TMCFF_FLIP; - SpreadFinishLine(line2, line, flipped != flip); + line2->args[0] = args ^ flipped; + SpreadFinishLine(line2, line, args ^ flipped); } } } @@ -13181,19 +13180,20 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean mobj->reactiontime = 0; // Also don't respawn at finish lines line_t *finishline = P_FindNearestLine(mobj->x, mobj->y, - mobj->subsector->sector, -1); - if (K_UsingPatchedMap() && finishline != NULL) + mobj->subsector->sector, K_UsingPatchedMap() ? -1 : 2001); // case 2001: Finish Line + if (finishline != NULL) { P_UnsetThingPosition(mobj); P_ClosestPointOnLine(mobj->x, mobj->y, finishline, (vertex_t *)&mobj->x); P_SetThingPosition(mobj); - boolean flip = mthing->args[2] & TMWPF_FLIPFINISH; - finishline->special = 2001; // Finish Line - finishline->activation = SPAC_CROSS|SPAC_REPEATSPECIAL; - if (flip) - finishline->args[0] |= TMCFF_FLIP; - SpreadFinishLine(finishline, NULL, flip); + if (K_UsingPatchedMap()) + { + finishline->special = 2001; // Finish Line + finishline->activation = SPAC_CROSS|SPAC_REPEATSPECIAL; + finishline->args[0] = mthing->args[4]; + SpreadFinishLine(finishline, NULL, mthing->args[4]); + } } } else diff --git a/src/p_spec.c b/src/p_spec.c index 1f73a6f74..ebe8584e3 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4451,6 +4451,36 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha if ((gametyperules & GTR_CIRCUIT) && (mo->player->exiting == 0) && !(mo->player->pflags & PF_HITFINISHLINE)) { + // megablock cope 1: single-use finish lines + if (args[0] & TMCFF_SINGLEUSE && mo->player->laps > 0) + return false; + + // megablock cope 2: require a circuit finish line special to be hit at the same time + if (args[0] & TMCFF_NEEDSECTOR) + { + boolean touching = false; + if (P_MobjTouchingSectorSpecialFlag(mo, SSF_FINISHLINE)) + touching = true; + + // we have to check if we WERE touching a finish line sector last tic too! + // otherwise lap decrementing wouldn't work! + // YAAAAAAAAAAAAAAY + fixed_t realx = mo->x, realy = mo->y; + P_UnsetThingPosition(mo); + mo->x = mo->old_x, mo->y = mo->old_y; + P_SetThingPosition(mo); + + if (P_MobjTouchingSectorSpecialFlag(mo, SSF_FINISHLINE)) + touching = true; + + P_UnsetThingPosition(mo); + mo->x = realx, mo->y = realy; + P_SetThingPosition(mo); + + if (!touching) + return false; + } + if (((args[0] & TMCFF_FLIP) && (side == 0)) || (!(args[0] & TMCFF_FLIP) && (side == 1))) // crossed from behind to infront { diff --git a/src/p_spec.h b/src/p_spec.h index a4ed56192..9b247ab7f 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -63,7 +63,6 @@ typedef enum TMWPF_SHORTCUT = 1<<1, TMWPF_NORESPAWN = 1<<2, TMWPF_FINISHLINE = 1<<3, - TMWPF_FLIPFINISH = 1<<4, } textmapwaypointflags_t; typedef enum @@ -488,7 +487,9 @@ typedef enum typedef enum { - TMCFF_FLIP = 1, + TMCFF_FLIP = 1, + TMCFF_SINGLEUSE = 1<<1, + TMCFF_NEEDSECTOR = 1<<2, } textmapcrossfinishflags_t; typedef enum