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.
This commit is contained in:
GenericHeroGuy 2025-05-06 20:43:31 +02:00
parent 67888c237d
commit 20396e14cb
6 changed files with 66 additions and 19 deletions

View file

@ -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";
}
}
}

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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
{

View file

@ -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