Dynamic tripwire

This commit is contained in:
AJ Martinez 2025-05-01 17:12:40 -04:00
parent 1c6a286adf
commit 95cd51cada
8 changed files with 172 additions and 6 deletions

View file

@ -2162,6 +2162,8 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_TRIPWIREBOOST_BLAST_TOP",
"S_TRIPWIREBOOST_BLAST_BOTTOM",
"S_TRIPWIREAPPROACH",
"S_SMOOTHLANDING",
"S_TRICKINDICATOR_OVERLAY",
@ -3644,6 +3646,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_BATTLEBUMPER_BLAST",
"MT_TRIPWIREBOOST",
"MT_TRIPWIREAPPROACH",
"MT_SMOOTHLANDING",
"MT_TRICKINDICATOR",

View file

@ -923,6 +923,16 @@ void F_IntroTicker(void)
S_StartSound(NULL, sfx_supflk);
}
if (skiptype == 5) // Quick Thunderdome
{
ResetSkipSequences();
CV_StealthSetValue(&cv_kartbot, 13);
CV_StealthSetValue(&cv_maxplayers, 8);
CV_StealthSetValue(&cv_thunderdome, 1);
D_MapChange(G_RandMap(TOL_RACE, UINT16_MAX-1, true, false, NULL), GT_RACE, (cv_kartencore.value == 1), true, 0, false, false);
return;
}
if (doskip && disclaimerskippable)
{
if (dc_state == DISCLAIMER_FINAL) {
@ -1013,16 +1023,21 @@ static void AdvanceSkipSequences(UINT8 input)
UINT8 s2cheat[] = {1, 1, 1};
UINT8 s3cheat[] = {2, 2, 2};
UINT8 s3kcheat[] = {3, 3, 3};
UINT8 thundercheat[] = {4, 4, 4};
#else
UINT8 s2cheat[] = {1, 1, 1, 3, 3, 3, 1};
UINT8 s3cheat[] = {1, 1, 3, 3, 1, 1, 1, 1};
UINT8 s3kcheat[] = {4, 4, 4, 2, 2, 2, 1, 1, 1};
UINT8 thundercheat[] = {2, 4, 2, 4, 3, 3, 1, 1};
#endif
UINT8 nicetry[] = {1, 1, 3, 3, 4, 2, 4, 2};
UINT8 *cheats[4] = {s2cheat, s3cheat, s3kcheat, nicetry};
UINT8 cheatlengths[4] = {sizeof(s2cheat), sizeof(s3cheat), sizeof(s3kcheat), sizeof(nicetry)};
for (UINT8 i = 0; i < 4; i++) // for each cheat...
#define NUMCHEATSPLUSONE 5
UINT8 *cheats[NUMCHEATSPLUSONE] = {s2cheat, s3cheat, s3kcheat, nicetry, thundercheat};
UINT8 cheatlengths[NUMCHEATSPLUSONE] = {sizeof(s2cheat), sizeof(s3cheat), sizeof(s3kcheat), sizeof(nicetry), sizeof(thundercheat)};
for (UINT8 i = 0; i < NUMCHEATSPLUSONE; i++) // for each cheat...
{
UINT8 cheatsize = cheatlengths[i];
boolean matched = true;
@ -1040,6 +1055,8 @@ static void AdvanceSkipSequences(UINT8 input)
skiptype = i+1;
}
#undef NUMCHEATSPLUSONE
skipinputindex++;
}

View file

@ -399,6 +399,7 @@ char sprnames[NUMSPRITES + 1][5] =
"BEXB", // Battle Bumper Explosion: Blast
"TWBS", // Tripwire Boost
"TWBT", // Tripwire BLASTER
"TWBP", // Tripwire approach
"SMLD", // Smooth landing
// Trick Effects
@ -2687,6 +2688,8 @@ state_t states[NUMSTATES] =
{SPR_TWBT, FF_FULLBRIGHT|FF_ADD|FF_ANIMATE, -1, {NULL}, 6, 2, S_NULL}, // S_TRIPWIREBOOST_BLAST_TOP
{SPR_TWBT, FF_FULLBRIGHT|FF_ADD|FF_ANIMATE|FF_VERTICALFLIP|FF_HORIZONTALFLIP, -1, {NULL}, 6, 2, S_NULL}, // S_TRIPWIREBOOST_BLAST_BOTTOM
{SPR_TWBP, FF_FULLBRIGHT|FF_ADD|FF_ANIMATE, -1, {NULL}, 11, 1, S_NULL}, // S_TRIPWIREAPPROACH
{SPR_SMLD, FF_FULLBRIGHT|FF_ADD|FF_ANIMATE, -1, {NULL}, 7, 2, S_NULL}, // S_SMOOTHLANDING
{SPR_TRK1, FF_FULLBRIGHT|FF_ANIMATE|FF_PAPERSPRITE|FF_ADD, -1, {NULL}, 3, 3, S_NULL}, // S_TRICKINDICATOR_OVERLAY,
@ -16061,6 +16064,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_TRIPWIREAPPROACH
-1, // doomednum
S_TRIPWIREAPPROACH, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
8*FRACUNIT, // radius
16*FRACUNIT, // height
1, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_DONTENCOREMAP, // flags
S_NULL // raisestate
},
{ // MT_SMOOTHLANDING
-1, // doomednum
S_SMOOTHLANDING, // spawnstate

View file

@ -938,6 +938,7 @@ typedef enum sprite
SPR_BEXB, // Battle Bumper Explosion: Blast
SPR_TWBS, // Tripwire Boost
SPR_TWBT, // Tripwire BLASTER
SPR_TWBP, // Tripwire approach
SPR_SMLD, // Smooth landing
// Trick Effects
@ -3189,6 +3190,8 @@ typedef enum state
S_TRIPWIREBOOST_BLAST_TOP,
S_TRIPWIREBOOST_BLAST_BOTTOM,
S_TRIPWIREAPPROACH,
S_SMOOTHLANDING,
S_TRICKINDICATOR_OVERLAY,
@ -4698,6 +4701,7 @@ typedef enum mobj_type
MT_BATTLEBUMPER_BLAST,
MT_TRIPWIREBOOST,
MT_TRIPWIREAPPROACH,
MT_SMOOTHLANDING,
MT_TRICKINDICATOR,

View file

@ -448,7 +448,7 @@ boolean K_IsPlayerScamming(player_t *player)
// "Why 8?" Consistency
// "Why 2000?" Vibes
return (K_GetItemRouletteDistance(player, 8) < 2000);
return (K_GetItemRouletteDistance(player, 8) < SCAMDIST);
}
fixed_t K_GetKartGameSpeedScalar(SINT8 value)
@ -2998,6 +2998,18 @@ fixed_t K_PlayerTripwireSpeedThreshold(const player_t *player)
{
fixed_t required_speed = 2 * K_GetKartSpeed(player, false, false); // 200%
UINT32 distance = K_GetItemRouletteDistance(player, 8);
if (gametype == GT_RACE)
{
if (distance < SCAMDIST) // Players near 1st need more speed!
{
fixed_t percentscam = FixedDiv(FRACUNIT*(SCAMDIST - distance), FRACUNIT*SCAMDIST);
required_speed += FixedMul(required_speed, percentscam);
}
}
if (player->offroad && K_ApplyOffroad(player))
{
// Increase to 300% if you're lawnmowering.
@ -8800,6 +8812,13 @@ static void K_UpdateTripwire(player_t *player)
mobj_t *front = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_TRIPWIREBOOST);
mobj_t *back = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_TRIPWIREBOOST);
if (P_IsDisplayPlayer(player))
{
S_StartSound(player->mo, sfx_s3k40);
S_StopSoundByID(player->mo, sfx_gshaf);
}
P_SetTarget(&front->target, player->mo);
P_SetTarget(&back->target, player->mo);

View file

@ -58,6 +58,8 @@ Make sure this matches the actual number of states
#define RR_PROJECTILE_FUSE (8*TICRATE)
#define SCAMDIST (2000)
// 2023-08-26 +ang20 to Sal's OG values to make them friendlier - Tyron
#define STUMBLE_STEEP_VAL (ANG60 + ANG20)
#define STUMBLE_STEEP_VAL_AIR (ANG30 + ANG10 + ANG20)

View file

@ -448,7 +448,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (special->fuse) // This box is respawning, but was broken very recently (see P_FuseThink)
{
// What was this box broken as?
if (special->cvmem && !(special->flags2 & MF2_BOSSDEAD))
if (cv_thunderdome.value)
K_StartItemRoulette(player, true);
else if (special->cvmem && !(special->flags2 & MF2_BOSSDEAD))
K_StartItemRoulette(player, false);
else
K_StartItemRoulette(player, true);

View file

@ -7747,6 +7747,78 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
}
}
break;
case MT_TRIPWIREAPPROACH: {
if (!mobj->target || !mobj->target->health || !mobj->target->player)
{
P_RemoveMobj(mobj);
return false;
}
mobj_t *target = mobj->target;
player_t *player = target->player;
fixed_t myspeed = (player->speed);
fixed_t maxspeed = K_PlayerTripwireSpeedThreshold(player); // Centered at this speed.
fixed_t minspeed = max(2 * maxspeed / 4, 16 * K_GetKartSpeed(player, false, false) / 10); // Starts appearing at this speed.
fixed_t alertspeed = 9 * maxspeed / 10; // When to flash?
fixed_t frontoffset = 5*target->scale; // How far in front?
fixed_t percentvisible = 0;
if (myspeed > minspeed)
percentvisible = min(FRACUNIT, FixedDiv(myspeed - minspeed, maxspeed - minspeed));
if (myspeed >= maxspeed || player->tripwireLeniency)
percentvisible = 0;
#if 0
fixed_t hang = 85*FRACUNIT/100; // Dampen inward movement past a certain point
if (percentvisible > hang && percentvisible < (95*FRACUNIT/100))
percentvisible = (percentvisible + hang) / 2;
#endif
fixed_t easedoffset = Easing_InOutCubic(percentvisible, 0, FRACUNIT);
fixed_t easedscale = FRACUNIT;
fixed_t dynamicoffset = FixedMul(target->scale * 100, FRACUNIT - easedoffset);
fixed_t xofs = (mobj->extravalue1) ? dynamicoffset : dynamicoffset * -1;
fixed_t zofs = (mobj->extravalue2) ? dynamicoffset : dynamicoffset * -1;
angle_t facing = K_MomentumAngle(mobj->target);
fixed_t sin = FINESINE(facing >> ANGLETOFINESHIFT);
fixed_t cos = FINECOSINE(facing >> ANGLETOFINESHIFT);
P_MoveOrigin(mobj,
target->x - FixedMul(xofs, sin) + FixedMul(frontoffset, cos),
target->y + FixedMul(xofs, cos) + FixedMul(frontoffset, sin),
target->z + zofs + (target->height / 2));
mobj->angle = facing + ANGLE_90 + (mobj->extravalue1 ? ANGLE_45 : -1*ANGLE_45);
K_MatchGenericExtraFlags(mobj, target);
P_InstaScale(mobj, FixedMul(target->scale, easedscale));
UINT8 maxtranslevel = NUMTRANSMAPS - 2;
UINT8 trans = FixedInt(FixedMul(percentvisible, FRACUNIT*(maxtranslevel+1)));
if (trans > maxtranslevel)
trans = maxtranslevel;
trans = NUMTRANSMAPS - trans;
mobj->renderflags &= ~(RF_TRANSMASK);
if (trans != 0)
{
mobj->renderflags |= (trans << RF_TRANSSHIFT);
}
mobj->renderflags |= RF_PAPERSPRITE;
mobj->colorized = true;
if (myspeed > alertspeed)
mobj->color = (leveltime & 1) ? SKINCOLOR_LILAC : SKINCOLOR_JAWZ;
else
mobj->color = SKINCOLOR_WHITE;
mobj->renderflags |= (RF_DONTDRAW & ~K_GetPlayerDontDrawFlag(player));
break;
}
case MT_TRIPWIREBOOST: {
mobj_t *top;
fixed_t newHeight;
@ -7755,12 +7827,18 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
if (!mobj->target || !mobj->target->health
|| !mobj->target->player || !mobj->target->player->tripwireLeniency)
{
if (mobj->target && mobj->target->player && P_IsDisplayPlayer(mobj->target->player))
{
S_StopSoundByID(mobj->target, sfx_s3k40);
S_StartSound(mobj->target, sfx_gshaf);
}
P_RemoveMobj(mobj);
return false;
}
newHeight = mobj->target->height;
newScale = mobj->target->scale;
newScale = 3 * mobj->target->scale / 2;
top = K_GetGardenTop(mobj->target->player);
@ -12229,6 +12307,17 @@ void P_SpawnPlayer(INT32 playernum)
K_InitWavedashIndicator(p);
K_InitTrickIndicator(p);
for (UINT8 approaches = 0; approaches < 4; approaches++)
{
mobj_t *approach = P_SpawnMobjFromMobj(p->mo, 0, 0, 0, MT_TRIPWIREAPPROACH);
P_SetTarget(&approach->target, p->mo);
approach->extravalue1 = (approaches == 0 || approaches == 2) ? 1 : 0;
approach->extravalue2 = (approaches == 0 || approaches == 1) ? 1 : 0;
approach->renderflags |= approach->extravalue1 ? 0 : RF_HORIZONTALFLIP;
approach->renderflags |= approach->extravalue2 ? 0 : RF_VERTICALFLIP;
}
if ((gametyperules & GTR_BUMPERS) && !p->spectator)
{
mobj->health = K_BumpersToHealth(K_StartingBumperCount());