Speed Pads are now a TERRAIN effect

- Use `SpeedPad` to set the strength. Intended to be scaled like Trick Panels, so 1 for yellow, 2 for red, so on. Can use floating point.
- Use `SpeedPadAngle` to rotate the thrust direction. This is in the same system as map angles, so east is 0, north is 90, west is 180, and south is 270. Also accepts floating point.
- Speed Pad angle accounts for the flat alignment itself, as well.
- Like Sneaker and Trick Panels, the sector / line special are now deprecated.
This commit is contained in:
Sally Coolatta 2022-10-11 02:26:54 -04:00
parent 7559169144
commit 8953cf54bb
9 changed files with 80 additions and 127 deletions

View file

@ -175,21 +175,6 @@ udmf
}
}
4
{
title = "Speed Pad Parameters";
prefix = "(4)";
arg0
{
title = "Speed";
}
stringarg0
{
title = "Sound";
type = 2;
}
}
8
{
title = "Set Camera Collision Planes";

View file

@ -94,7 +94,6 @@ sectorflags
nostepup = "Wall Sector (no step-up)";
doublestepup = "Ramp Sector (double step-up/down)";
nostepdown = "Non-Ramp Sector (no step-down)";
speedpad = "Speed Pad";
starpostactivator = "Star Post Activator";
exit = "Exit";
fan = "Fan Sector";

View file

@ -5838,7 +5838,7 @@ const char *const SSF_LIST[] = {
"DOUBLESTEPUP",
"WINDCURRENT",
"CONVEYOR",
"SPEEDPAD",
"\x01", // free (name un-matchable)
"STARPOSTACTIVATOR",
"EXIT",
"\x01", // free (name un-matchable)

View file

@ -496,6 +496,64 @@ void K_ProcessTerrainEffect(mobj_t *mo)
P_InstaThrust(mo, mo->angle, speed);
}
// Speed pad
if (terrain->speedPad > 0)
{
if (player->floorboost != 0)
{
player->floorboost = 2;
}
else
{
fixed_t thrustSpeed = terrain->speedPad * 16;
angle_t thrustAngle = terrain->speedPadAngle;
fixed_t playerSpeed = P_AproxDistance(player->mo->momx, player->mo->momy);
// FIXME: come up with a better way to get the touched
// texture's rotation to this function. At least this
// will work for 90% of scenarios...
if (player->mo->eflags & MFE_VERTICALFLIP)
{
if (player->mo->ceilingrover != NULL)
{
thrustAngle += *player->mo->ceilingrover->bottomangle;
}
else
{
thrustAngle += player->mo->subsector->sector->ceilingpic_angle;
}
}
else
{
if (player->mo->floorrover != NULL)
{
thrustAngle += *player->mo->floorrover->topangle;
}
else
{
thrustAngle += player->mo->subsector->sector->floorpic_angle;
}
}
// Map scale for Shrink, object scale for Grow.
thrustSpeed = FixedMul(thrustSpeed, max(mapobjectscale, player->mo->scale));
thrustAngle = K_ReflectAngle(
K_MomentumAngle(player->mo), thrustAngle,
playerSpeed, thrustSpeed
);
P_InstaThrust(player->mo, thrustAngle, max(thrustSpeed, 2*playerSpeed));
player->dashpadcooldown = TICRATE/3;
player->trickpanel = 0;
player->floorboost = 2;
S_StartSound(player->mo, sfx_cdfm62);
}
}
// Bumpy floor
if (terrain->flags & TRF_STAIRJANK)
{
@ -1426,6 +1484,8 @@ static void K_TerrainDefaults(terrain_t *terrain)
terrain->offroad = 0;
terrain->damageType = -1;
terrain->trickPanel = 0;
terrain->speedPad = 0;
terrain->speedPadAngle = 0;
terrain->flags = 0;
}
@ -1496,6 +1556,14 @@ static void K_ParseTerrainParameter(size_t i, char *param, char *val)
{
terrain->trickPanel = FLOAT_TO_FIXED(atof(val));
}
else if (stricmp(param, "speedPad") == 0)
{
terrain->speedPad = FLOAT_TO_FIXED(atof(val));
}
else if (stricmp(param, "speedPadAngle") == 0)
{
terrain->speedPadAngle = FixedAngle(FLOAT_TO_FIXED(atof(val)));
}
else if (stricmp(param, "floorClip") == 0)
{
terrain->floorClip = FLOAT_TO_FIXED(atof(val));

View file

@ -114,6 +114,8 @@ typedef struct terrain_s
fixed_t offroad; // The default offroad level of this texture.
INT16 damageType; // The default damage type of this texture. (Negative means no damage).
fixed_t trickPanel; // Trick panel strength
fixed_t speedPad; // Speed pad strength
angle_t speedPadAngle; // Speed pad angle
fixed_t floorClip; // Offset for sprites on this ground
UINT32 flags; // Flag values (see: terrain_flags_t)
} terrain_t;

View file

@ -1089,19 +1089,6 @@ static void P_LoadSidedefs(UINT8 *data)
break;
}
case 4: // Speed pad parameters
{
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
if (msd->toptexture[0] != '-' || msd->toptexture[1] != '\0')
{
char process[8+1];
M_Memcpy(process,msd->toptexture,8);
process[8] = '\0';
sd->toptexture = get_number(process);
}
break;
}
case 414: // Play SFX
{
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
@ -1502,8 +1489,6 @@ static void ParseTextmapSectorParameter(UINT32 i, const char *param, const char
sectors[i].specialflags |= SSF_DOUBLESTEPUP;
else if (fastcmp(param, "nostepdown") && fastcmp("true", val))
sectors[i].specialflags |= SSF_NOSTEPDOWN;
else if (fastcmp(param, "speedpad") && fastcmp("true", val))
sectors[i].specialflags |= SSF_SPEEDPAD;
else if (fastcmp(param, "starpostactivator") && fastcmp("true", val))
sectors[i].specialflags |= SSF_STARPOSTACTIVATOR;
else if (fastcmp(param, "exit") && fastcmp("true", val))
@ -2335,8 +2320,6 @@ static void P_WriteTextmap(void)
fprintf(f, "doublestepup = true;\n");
if (wsectors[i].specialflags & SSF_NOSTEPDOWN)
fprintf(f, "nostepdown = true;\n");
if (wsectors[i].specialflags & SSF_SPEEDPAD)
fprintf(f, "speedpad = true;\n");
if (wsectors[i].specialflags & SSF_STARPOSTACTIVATOR)
fprintf(f, "starpostactivator = true;\n");
if (wsectors[i].specialflags & SSF_EXIT)
@ -3965,12 +3948,7 @@ static void P_ConvertBinaryLinedefTypes(void)
lines[i].args[2] = !!(lines[i].flags & ML_MIDSOLID);
break;
case 4: //Speed pad parameters
lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
if (lines[i].flags & ML_MIDSOLID)
lines[i].args[1] |= TMSP_NOTELEPORT;
if (lines[i].flags & ML_WRAPMIDTEX)
lines[i].args[1] |= TMSP_FORCESPIN;
P_WriteConstant(sides[lines[i].sidenum[0]].toptexture ? sides[lines[i].sidenum[0]].toptexture : sfx_spdpad, &lines[i].stringargs[0]);
CONS_Alert(CONS_WARNING, "Speed Pad linedef is deprecated. Use the TERRAIN effect!\n");
break;
case 7: //Sector flat alignment
lines[i].args[0] = tag;
@ -5923,7 +5901,7 @@ static void P_ConvertBinarySectorTypes(void)
CONS_Alert(CONS_WARNING, "Trick Panel special is deprecated. Use the TERRAIN effect!\n");
break;
case 5: //Speed pad
sectors[i].specialflags |= SSF_SPEEDPAD;
CONS_Alert(CONS_WARNING, "Speed Pad special is deprecated. Use the TERRAIN effect!\n");
break;
default:
break;

View file

@ -4368,88 +4368,6 @@ static void P_ProcessEggCapsule(player_t *player, sector_t *sector)
}
}
static void P_ProcessSpeedPad(player_t *player, sector_t *sector, sector_t *roversector, mtag_t sectag)
{
INT32 lineindex = -1;
angle_t lineangle;
fixed_t linespeed;
fixed_t playerspeed;
fixed_t sfxnum;
size_t i;
(void)roversector;
// Try for lines facing the sector itself, with tag 0.
for (i = 0; i < sector->linecount; i++)
{
line_t *li = sector->lines[i];
if (li->frontsector != sector)
continue;
if (li->special != 4)
continue;
if (!Tag_Find(&li->tags, 0))
continue;
lineindex = li - lines;
break;
}
// Nothing found? Look via tag.
if (lineindex == -1)
lineindex = Tag_FindLineSpecial(4, sectag);
if (lineindex == -1)
{
CONS_Debug(DBG_GAMELOGIC, "ERROR: Speed pad missing line special #4.\n");
return;
}
lineangle = lines[lineindex].angle;
linespeed = lines[lineindex].args[0] << FRACBITS;
if (linespeed == 0)
{
CONS_Debug(DBG_GAMELOGIC, "ERROR: Speed pad (tag %d) at zero speed.\n", sectag);
return;
}
if (player->floorboost != 0)
{
player->floorboost = 2;
return;
}
playerspeed = P_AproxDistance(player->mo->momx, player->mo->momy);
// SRB2Kart: Scale the speed you get from them!
// This is scaled differently from other horizontal speed boosts from stuff like springs, because of how this is used for some ramp jumps.
if (player->mo->scale > mapobjectscale)
{
linespeed = FixedMul(linespeed, mapobjectscale + (player->mo->scale - mapobjectscale));
}
lineangle = K_ReflectAngle(
K_MomentumAngle(player->mo), lineangle,
playerspeed, linespeed
);
P_InstaThrust(player->mo, lineangle, max(linespeed, 2*playerspeed));
player->dashpadcooldown = TICRATE/3;
player->trickpanel = 0;
player->floorboost = 2;
sfxnum = lines[lineindex].stringargs[0] ? get_number(lines[lineindex].stringargs[0]) : sfx_cdfm62;
if (!sfxnum)
sfxnum = sfx_cdfm62;
S_StartSound(player->mo, sfxnum);
}
static void P_ProcessExitSector(player_t *player, mtag_t sectag)
{
INT32 lineindex;
@ -4566,12 +4484,13 @@ static void P_EvaluateSpecialFlags(player_t *player, sector_t *sector, sector_t
{
mtag_t sectag = Tag_FGet(&sector->tags);
(void)roversector;
(void)isTouching;
if (sector->specialflags & SSF_WINDCURRENT)
player->onconveyor = 2;
if (sector->specialflags & SSF_CONVEYOR)
player->onconveyor = 4;
if ((sector->specialflags & SSF_SPEEDPAD) && isTouching)
P_ProcessSpeedPad(player, sector, roversector, sectag);
if (sector->specialflags & SSF_STARPOSTACTIVATOR)
{
mobj_t *post = P_GetObjectTypeInSectorNum(MT_STARPOST, sector - sectors);

View file

@ -47,7 +47,9 @@ boolean R_NoEncore(sector_t *sector, levelflat_t *flat, boolean ceiling)
const terrain_t *terrain = (flat != NULL ? flat->terrain : NULL);
if ((terrain == NULL)
|| (terrain->trickPanel <= 0 && !(terrain->flags & TRF_SNEAKERPANEL)))
|| (terrain->trickPanel <= 0
&& terrain->speedPad <= 0
&& !(terrain->flags & TRF_SNEAKERPANEL)))
{
return invertEncore;
}

View file

@ -356,7 +356,7 @@ typedef enum
SSF_NOSTEPDOWN = 1<<2,
SSF_WINDCURRENT = 1<<3,
SSF_CONVEYOR = 1<<4,
SSF_SPEEDPAD = 1<<5,
// free: 1<<5,
SSF_STARPOSTACTIVATOR = 1<<6,
SSF_EXIT = 1<<7,
SSF_DELETEITEMS = 1<<8,