Hardcode MT_DASHRING & MT_RAINBOWDASHRING

This commit is contained in:
Lach 2023-07-19 21:47:41 +10:00
parent a59896ef88
commit a21e509a94
12 changed files with 443 additions and 20 deletions

View file

@ -129,6 +129,7 @@ typedef enum
// Specific level gimmicks.
CR_SLIDING,
CR_ZOOMTUBE,
CR_DASHRING,
} carrytype_t; // carry
/*
@ -691,6 +692,9 @@ struct player_t
UINT8 trickboostdecay; // used to know how long you've waited
UINT8 trickboost; // Trick boost. This one is weird and has variable speed. Dear god.
UINT8 dashRingPullTics; // Timer during which the player is pulled towards a dash ring
UINT8 dashRingPushTics; // Timer during which the player displays effects and has no gravity after being thrust by a dash ring
tic_t ebrakefor; // Ebrake timer, used for visuals.
UINT16 faultflash; // Used for misc FAULT visuals
@ -804,7 +808,7 @@ struct player_t
UINT8 ringboxdelay; // Delay until Ring Box auto-activates
UINT8 ringboxaward; // Where did we stop?
fixed_t outrun; // Milky Way road effect
uint8_t public_key[PUBKEYLENGTH];

View file

@ -4236,6 +4236,20 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_FZSLOWSMOKE4",
"S_FZSLOWSMOKE5",
// Dash Rings
"S_DASHRING_HORIZONTAL",
"S_DASHRING_30DEGREES",
"S_DASHRING_60DEGREES",
"S_DASHRING_VERTICAL",
"S_DASHRING_HORIZONTAL_FLASH1",
"S_DASHRING_HORIZONTAL_FLASH2",
"S_DASHRING_30DEGREES_FLASH1",
"S_DASHRING_30DEGREES_FLASH2",
"S_DASHRING_60DEGREES_FLASH1",
"S_DASHRING_60DEGREES_FLASH2",
"S_DASHRING_VERTICAL_FLASH1",
"S_DASHRING_VERTICAL_FLASH2",
// Various plants
"S_SONICBUSH",
@ -5603,6 +5617,10 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_FZEROBOOM",
// Dash Rings
"MT_DASHRING",
"MT_RAINBOWDASHRING",
// Various plants
"MT_SONICBUSH",

View file

@ -717,6 +717,9 @@ char sprnames[NUMSPRITES + 1][5] =
"FZSM", // F-Zero NO CONTEST explosion
"FZBM",
// Dash Rings
"RAIR",
// Various plants
"SBUS",
@ -4918,6 +4921,20 @@ state_t states[NUMSTATES] =
{SPR_SMOK, 3, 30, {NULL}, 0, 0, S_FZSLOWSMOKE5}, // S_FZSLOWSMOKE4
{SPR_SMOK, 4, 30, {NULL}, 0, 0, S_NULL}, // S_FZSLOWSMOKE5
// Dash Rings
{SPR_RAIR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_DASHRING_HORIZONTAL
{SPR_RAIR, 1, -1, {NULL}, 0, 0, S_NULL}, // S_DASHRING_30DEGREES
{SPR_RAIR, 2, -1, {NULL}, 0, 0, S_NULL}, // S_DASHRING_60DEGREES
{SPR_RAIR, 3, -1, {NULL}, 0, 0, S_NULL}, // S_DASHRING_VERTICAL
{SPR_NULL, 0, TICRATE/3 - 2, {NULL}, 0, 0, S_DASHRING_HORIZONTAL_FLASH2}, // S_DASHRING_HORIZONTAL_FLASH1
{SPR_RAIR, FF_ADD|0, 2, {NULL}, 0, 0, S_DASHRING_HORIZONTAL_FLASH1}, // S_DASHRING_HORIZONTAL_FLASH2
{SPR_NULL, 0, TICRATE/3 - 2, {NULL}, 0, 0, S_DASHRING_30DEGREES_FLASH2}, // S_DASHRING_30DEGREES_FLASH1
{SPR_RAIR, FF_ADD|1, 2, {NULL}, 0, 0, S_DASHRING_30DEGREES_FLASH1}, // S_DASHRING_30DEGREES_FLASH2
{SPR_NULL, 0, TICRATE/3 - 2, {NULL}, 0, 0, S_DASHRING_60DEGREES_FLASH2}, // S_DASHRING_60DEGREES_FLASH1
{SPR_RAIR, FF_ADD|2, 2, {NULL}, 0, 0, S_DASHRING_60DEGREES_FLASH1}, // S_DASHRING_60DEGREES_FLASH2
{SPR_NULL, 0, TICRATE/3 - 2, {NULL}, 0, 0, S_DASHRING_VERTICAL_FLASH2}, // S_DASHRING_VERTICAL_FLASH1
{SPR_RAIR, FF_ADD|3, 2, {NULL}, 0, 0, S_DASHRING_VERTICAL_FLASH1}, // S_DASHRING_VERTICAL_FLASH2
// Various plants
{SPR_SBUS, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SONICBUSH
@ -26726,6 +26743,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_DASHRING
3441, // doomednum
S_DASHRING_HORIZONTAL, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_dashr, // 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
112*FRACUNIT, // radius
192*FRACUNIT, // height
0, // display offset
0, // mass
0, // damage
sfx_None, // activesound
MF_NOGRAVITY|MF_SPECIAL, // flags
S_NULL // raisestate
},
{ // MT_RAINBOWDASHRING
3442, // doomednum
S_DASHRING_HORIZONTAL, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_rainbr, // 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
112*FRACUNIT, // radius
192*FRACUNIT, // height
0, // display offset
0, // mass
0, // damage
sfx_None, // activesound
MF_NOGRAVITY|MF_SPECIAL, // flags
S_NULL // raisestate
},
{ // MT_SONICBUSH,
715, // doomednum
S_SONICBUSH, // spawnstate

View file

@ -1268,6 +1268,9 @@ typedef enum sprite
SPR_FZSM, // F-Zero NO CONTEST explosion
SPR_FZBM,
// Dash Rings
SPR_RAIR,
// Various plants
SPR_SBUS,
@ -5366,6 +5369,20 @@ typedef enum state
S_FZSLOWSMOKE4,
S_FZSLOWSMOKE5,
// Dash Rings
S_DASHRING_HORIZONTAL,
S_DASHRING_30DEGREES,
S_DASHRING_60DEGREES,
S_DASHRING_VERTICAL,
S_DASHRING_HORIZONTAL_FLASH1,
S_DASHRING_HORIZONTAL_FLASH2,
S_DASHRING_30DEGREES_FLASH1,
S_DASHRING_30DEGREES_FLASH2,
S_DASHRING_60DEGREES_FLASH1,
S_DASHRING_60DEGREES_FLASH2,
S_DASHRING_VERTICAL_FLASH1,
S_DASHRING_VERTICAL_FLASH2,
// Various plants
S_SONICBUSH,
@ -6768,6 +6785,10 @@ typedef enum mobj_type
MT_FZEROBOOM,
// Dash Rings
MT_DASHRING,
MT_RAINBOWDASHRING,
// Various plants
MT_SONICBUSH,

View file

@ -2027,7 +2027,7 @@ void K_SpawnMagicianParticles(mobj_t *mo, int spread)
{
fixed_t hmomentum = P_RandomRange(PR_DECORATION, spread * -1, spread) * mo->scale;
fixed_t vmomentum = P_RandomRange(PR_DECORATION, spread * -1, spread) * mo->scale;
UINT16 color = P_RandomKey(PR_DECORATION, numskincolors);
UINT16 color = P_RandomKey(PR_DECORATION, numskincolors);
fixed_t ang = FixedAngle(P_RandomRange(PR_DECORATION, 0, 359)*FRACUNIT);
SINT8 flip = 1;
@ -2679,7 +2679,7 @@ void K_TryHurtSoundExchange(mobj_t *victim, mobj_t *attacker)
return;
}
// In a perfect world we could move this here, but there's
// In a perfect world we could move this here, but there's
// a few niche situations where we want a pain sound from
// the victim, but no confirm sound from the attacker.
// (ex: DMG_STING)
@ -4148,7 +4148,7 @@ static boolean K_IsLosingSliptideZip(player_t *player)
return true;
if (!K_Sliptiding(player) && player->sliptideZip < MIN_WAVEDASH_CHARGE)
return true;
if (!K_Sliptiding(player) && player->drift == 0
if (!K_Sliptiding(player) && player->drift == 0
&& P_IsObjectOnGround(player->mo) && player->sneakertimer == 0
&& player->driftboost == 0)
return true;
@ -4211,7 +4211,7 @@ void K_UpdateSliptideZipIndicator(player_t *player)
if (leveltime % 2 == 0)
mobj->renderflags |= RF_TRANS50;
}
else
else
{
// Storing boost
mobj->rollangle += 3*ANG15/4;
@ -4357,7 +4357,7 @@ INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) // A
{
if (inflictor->type == MT_SPBEXPLOSION && inflictor->movefactor)
{
if (modeattacking & ATTACKING_SPB)
if (modeattacking & ATTACKING_SPB)
{
P_DamageMobj(player->mo, inflictor, source, 1, DMG_INSTAKILL);
player->SPBdistance = 0;
@ -4676,7 +4676,7 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I
speed,
FixedMul(
FixedDiv(source->player->speed, topspeed),
deltaFactor
deltaFactor
)
));
}
@ -7747,6 +7747,8 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
K_UpdateDraft(player);
K_UpdateEngineSounds(player); // Thanks, VAda!
Obj_DashRingPlayerThink(player);
// update boost angle if not spun out
if (!player->spinouttimer && !player->wipeoutslow)
player->boostangle = player->mo->angle;
@ -8065,7 +8067,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
if (player->guardCooldown)
player->guardCooldown--;
if (player->whip && P_MobjWasRemoved(player->whip))
P_SetTarget(&player->whip, NULL);
@ -8952,7 +8954,7 @@ void K_UpdateDistanceFromFinishLine(player_t *const player)
bestPoint = pDist;
bestDist =
bestDist =
P_AproxDistance(
(result.x >> FRACBITS) - (line[0].x >> FRACBITS),
(result.y >> FRACBITS) - (line[0].y >> FRACBITS));
@ -9113,7 +9115,7 @@ INT16 K_UpdateSteeringValue(INT16 inputSteering, INT16 destSteering)
INT16 diff = destSteering - inputSteering;
INT16 outputSteering = inputSteering;
// We switched steering directions, lighten up on easing for a more responsive countersteer.
// (Don't do this for steering 0, let digital inputs tap-adjust!)
if ((inputSteering > 0 && destSteering < 0) || (inputSteering < 0 && destSteering > 0))
@ -9257,13 +9259,13 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue)
fixed_t finalhandleboost = player->handleboost;
// If you're sliptiding, don't interact with handling boosts.
// You need turning power proportional to your speed, no matter what!
// You need turning power proportional to your speed, no matter what!
fixed_t topspeed = K_GetKartSpeed(player, false, false);
if (K_Sliptiding(player))
{
finalhandleboost = FixedMul(5*SLIPTIDEHANDLING/4, FixedDiv(player->speed, topspeed));
}
if (finalhandleboost > 0 && player->respawn.state == RESPAWNST_NONE)
{
turnfixed = FixedMul(turnfixed, FRACUNIT + finalhandleboost);
@ -9348,7 +9350,7 @@ void K_SpawnDriftBoostExplosion(player_t *player, int stage)
break;
case 2:
overlay->fuse = 32;
S_StartSound(player->mo, sfx_kc5b);
break;
@ -9616,7 +9618,7 @@ static void K_KartDrift(player_t *player, boolean onground)
&& player->speed >= K_GetKartSpeed(player, false, true)) // and we're above the threshold to spawn dust...
{
keepsliptide = true; // Then keep your current sliptide, but note the behavior change for sliptidezip handling.
}
}
else
{
if (!player->drift)
@ -9625,7 +9627,7 @@ static void K_KartDrift(player_t *player, boolean onground)
player->aizdriftstrat = ((player->drift > 0) ? 1 : -1);
}
}
if ((player->aizdriftstrat && !player->drift)
|| (keepsliptide))
{
@ -9635,7 +9637,7 @@ static void K_KartDrift(player_t *player, boolean onground)
{
// Give charge proportional to your angle. Sharp turns are rewarding, slow analog slides are not—remember, this is giving back the speed you gave up.
UINT16 addCharge = FixedInt(
FixedMul(10*FRACUNIT,
FixedMul(10*FRACUNIT,
FixedDiv(abs(player->steering)*FRACUNIT, (9*KART_FULLTURN/10)*FRACUNIT)
));
addCharge = min(10, max(addCharge, 1));
@ -9647,7 +9649,7 @@ static void K_KartDrift(player_t *player, boolean onground)
if (player->sliptideZip >= MIN_WAVEDASH_CHARGE && (player->sliptideZip - addCharge) < MIN_WAVEDASH_CHARGE)
S_StartSound(player->mo, sfx_waved5);
}
}
if (abs(player->aizdrifttilt) < ANGLE_22h)
{
@ -10411,7 +10413,7 @@ static void K_KartSpindash(player_t *player)
player->spindash++;
if (!S_SoundPlaying(player->mo, sfx_kc38))
S_StartSound(player->mo, sfx_kc38);
}
}
if (player->spindash >= SPINDASHTHRUSTTIME)
{

View file

@ -183,6 +183,15 @@ void Obj_SymbolSpawn(mobj_t *mobj);
void Obj_SymbolSetup(mobj_t *mobj, mapthing_t *mthing);
void Obj_SymbolThink(mobj_t *mobj);
/* Dash Rings */
void Obj_RegularDashRingSpawn(mobj_t *mobj);
void Obj_RainbowDashRingSpawn(mobj_t *mobj);
void Obj_DashRingSetup(mobj_t *mobj, mapthing_t *mthing);
void Obj_RainbowDashRingThink(mobj_t *mobj);
void Obj_DashRingTouch(mobj_t *mobj, player_t *player);
void Obj_DashRingPlayerThink(player_t *player);
boolean Obj_DashRingPlayerHasNoGravity(player_t *player);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -25,4 +25,5 @@ target_sources(SRB2SDL2 PRIVATE
battle-ufo.cpp
powerup-aura.cpp
symbol.c
dash-rings.c
)

266
src/objects/dash-rings.c Normal file
View file

@ -0,0 +1,266 @@
#include "../p_local.h"
#include "../k_kart.h"
#include "../s_sound.h"
// Dash Rings are scaled by this much relative to the map scale
#define DASHRING_SCALE (3*FRACUNIT/2)
// Dash Ring angles are defined by their mapthing's args[0] (previously used mapthing->options flags, hence the selections)
#define DASHRING_TYPE_HORIZONTAL 0
#define DASHRING_TYPE_30DEGREES 1
#define DASHRING_TYPE_60DEGREES 4
#define DASHRING_TYPE_VERTICAL 8
// Dash Rings must be this far apart for players to interact with them in succession
#define DASHRING_MIN_SPACING_HORIZONTAL (512*FRACUNIT)
#define DASHRING_MIN_SPACING_VERTICAL (384*FRACUNIT)
// timer values
#define DASHRING_PULL_TICS 5
#define DASHRING_PUSH_TICS (TICRATE/2)
#define DASHRING_ANTIGRAVITY_TICS 5
// base launch speed
#define DASHRING_BASE_LAUNCH_SPEED (48*FRACUNIT)
// factor of distance traveled per tic while being pulled towards a Dash Ring
#define DASHRING_PULL_FACTOR (FRACUNIT/3)
static const skincolornum_t ring_colors[] = {
SKINCOLOR_GREY, // 1x
SKINCOLOR_TAN, // 1.25x
SKINCOLOR_YELLOW, // 1.5x
SKINCOLOR_TANGERINE, // 1.75x
SKINCOLOR_KETCHUP, // 2x
SKINCOLOR_MOONSET, // 2.25x
SKINCOLOR_ULTRAMARINE, // 2.5x +
};
static const skincolornum_t rainbow_colors[] = {
SKINCOLOR_PINK,
SKINCOLOR_CREAMSICLE,
SKINCOLOR_TAN,
SKINCOLOR_TURTLE,
SKINCOLOR_TURQUOISE,
SKINCOLOR_THISTLE,
};
void Obj_RegularDashRingSpawn(mobj_t *mobj)
{
P_SetScale(mobj, mobj->destscale = FixedMul(mobj->scale, DASHRING_SCALE));
mobj->renderflags |= RF_SEMIBRIGHT;
P_SetTarget(&mobj->tracer, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_OVERLAY));
P_SetTarget(&mobj->tracer->target, mobj);
P_SetMobjState(mobj->tracer, S_DASHRING_HORIZONTAL_FLASH1);
mobj->tracer->color = SKINCOLOR_WHITE;
mobj->tracer->renderflags |= RF_SEMIBRIGHT;
}
void Obj_RainbowDashRingSpawn(mobj_t *mobj)
{
P_SetScale(mobj, mobj->destscale = FixedMul(mobj->scale, DASHRING_SCALE));
mobj->renderflags |= RF_FULLBRIGHT;
}
void Obj_DashRingSetup(mobj_t *mobj, mapthing_t *mthing)
{
static const UINT8 numColors = sizeof(rainbow_colors) / sizeof(skincolornum_t);
const UINT8 additionalThrust = mthing->args[1];
statenum_t ringState, overlayState;
mobj->extravalue1 = mthing->args[0];
mobj->cusval = 4 + additionalThrust;
switch (mobj->extravalue1)
{
case DASHRING_TYPE_30DEGREES:
ringState = S_DASHRING_30DEGREES;
overlayState = S_DASHRING_30DEGREES_FLASH1;
break;
case DASHRING_TYPE_60DEGREES:
ringState = S_DASHRING_60DEGREES;
overlayState = S_DASHRING_60DEGREES_FLASH1;
break;
case DASHRING_TYPE_VERTICAL:
ringState = S_DASHRING_VERTICAL;
overlayState = S_DASHRING_VERTICAL_FLASH1;
break;
case DASHRING_TYPE_HORIZONTAL:
default:
ringState = S_DASHRING_HORIZONTAL;
overlayState = S_DASHRING_HORIZONTAL_FLASH1;
break;
}
P_SetMobjState(mobj, ringState);
if (!P_MobjWasRemoved(mobj->tracer))
P_SetMobjState(mobj->tracer, overlayState);
mobj->spriteyoffset = mobj->info->height >> 1; // I think this is to center the sprite within its hitbox regardless of height
mobj->color = ring_colors[min(additionalThrust, numColors - 1)];
}
void Obj_RainbowDashRingThink(mobj_t *mobj)
{
static const UINT8 numColors = sizeof(rainbow_colors) / sizeof(skincolornum_t);
mobj->color = rainbow_colors[(leveltime / 2) % numColors];
}
static boolean DashRingsAreTooClose(mobj_t *ring1, mobj_t *ring2)
{
if (ring1 == ring2)
return true;
if ((FixedHypot(ring2->x - ring1->x, ring2->y - ring1->y) < FixedMul(DASHRING_MIN_SPACING_HORIZONTAL, mapobjectscale))
&& (abs(ring1->z - ring2->z) < FixedMul(DASHRING_MIN_SPACING_VERTICAL, mapobjectscale)))
return true;
return false;
}
void Obj_DashRingTouch(mobj_t *ring, player_t *player)
{
if (player->carry != CR_NONE)
{
if (player->carry != CR_DASHRING) // being carried by something else
return;
if (player->dashRingPullTics > 0) // being pulled into a dash ring already
return;
if (player->dashRingPushTics > 0 && !P_MobjWasRemoved(player->mo->tracer) && DashRingsAreTooClose(player->mo->tracer, ring)) // dash ring is too close to recently used dash ring
return;
}
P_SetTarget(&player->mo->tracer, ring);
player->carry = CR_DASHRING;
player->dashRingPullTics = DASHRING_PULL_TICS;
player->dashRingPushTics = 0;
}
static fixed_t GetPlayerDashRingZ(player_t *player, mobj_t *ring)
{
return (ring->z + (ring->height >> 1) - (player->mo->height >> 1));
}
static void DashRingLaunch(player_t *player, mobj_t *ring)
{
mobj_t *ghost = P_SpawnGhostMobj(ring);
const fixed_t launchSpeed = FixedMul(DASHRING_BASE_LAUNCH_SPEED * ring->cusval / 4, mapobjectscale);
angle_t pitch;
ghost->destscale = ring->scale * 8;
ghost->scalespeed = ring->scale / 12;
ghost->old_z = ghost->z += P_MobjFlip(ring) * FixedMul(ghost->spriteyoffset, ghost->scale); // apply sprite offset to physical position instead, so ghost is centered
ghost->spriteyoffset = 0;
P_MoveOrigin(player->mo, ring->x, ring->y, GetPlayerDashRingZ(player, ring));
player->dashRingPullTics = 0;
player->dashRingPushTics = DASHRING_PUSH_TICS;
player->mo->rollangle = 0;
player->flashing = 0;
player->fastfall = 0;
switch (ring->extravalue1)
{
case DASHRING_TYPE_30DEGREES:
pitch = 30 * ANG1;
break;
case DASHRING_TYPE_60DEGREES:
pitch = 60 * ANG1;
break;
case DASHRING_TYPE_VERTICAL:
pitch = 90 * ANG1;
break;
case DASHRING_TYPE_HORIZONTAL:
default:
pitch = 0;
break;
}
P_InstaThrust(player->mo, ring->angle, P_ReturnThrustX(NULL, pitch, launchSpeed));
player->mo->momz = P_MobjFlip(ring) * P_ReturnThrustY(NULL, pitch, launchSpeed);
S_StartSound(player->mo, ring->info->seesound);
}
static void RegularDashRingLaunch(player_t *player, mobj_t *ring)
{
player->springstars = TICRATE/2;
player->springcolor = ring->color;
DashRingLaunch(player, ring);
}
static void RainbowDashRingLaunch(player_t *player, mobj_t *ring)
{
player->mo->eflags &= ~MFE_SPRUNG;
player->trickpanel = 1;
player->pflags |= PF_TRICKDELAY;
K_DoPogoSpring(player->mo, 0, 0);
DashRingLaunch(player, ring);
}
void Obj_DashRingPlayerThink(player_t *player)
{
if (player->carry != CR_DASHRING)
return;
if (player->dashRingPullTics > 0)
{
mobj_t *ring = player->mo->tracer;
if (P_MobjWasRemoved(player->mo->tracer))
{
player->carry = CR_NONE;
player->dashRingPullTics = 0;
}
else
{
player->mo->momx = FixedMul(DASHRING_PULL_FACTOR, ring->x - player->mo->x);
player->mo->momy = FixedMul(DASHRING_PULL_FACTOR, ring->y - player->mo->y);
player->mo->momz = FixedMul(DASHRING_PULL_FACTOR, GetPlayerDashRingZ(player, ring) - player->mo->z);
player->mo->rollangle = (angle_t)FixedMul(DASHRING_PULL_FACTOR, (fixed_t)player->mo->rollangle);
if (--player->dashRingPullTics == 0)
{
if (ring->type == MT_DASHRING)
{
RegularDashRingLaunch(player, ring);
}
else
{
RainbowDashRingLaunch(player, ring);
}
}
}
}
if (player->dashRingPushTics > 0)
{
if (leveltime & 1)
{
mobj_t *ghost = P_SpawnGhostMobj(player->mo);
ghost->colorized = true;
ghost->fuse = 3;
}
if (--player->dashRingPushTics == 0)
{
player->carry = CR_NONE;
P_SetTarget(&player->mo->tracer, NULL);
}
}
}
boolean Obj_DashRingPlayerHasNoGravity(player_t *player)
{
if (player->dashRingPullTics > 0)
return true;
if (player->dashRingPushTics >= DASHRING_PUSH_TICS - DASHRING_ANTIGRAVITY_TICS)
return true;
return false;
}

View file

@ -664,6 +664,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
Obj_SuperFlickyPlayerCollide(special, toucher);
return;
case MT_DASHRING:
case MT_RAINBOWDASHRING:
Obj_DashRingTouch(special, player);
return;
default: // SOC or script pickup
P_SetTarget(&special->target, toucher);
break;

View file

@ -1159,6 +1159,11 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
gravityadd = FixedMul(TUMBLEGRAVITY, gravityadd);
}
if (mo->player->carry == CR_DASHRING && Obj_DashRingPlayerHasNoGravity(mo->player))
{
gravityadd = 0;
}
if (K_IsHoldingDownTop(mo->player))
{
gravityadd *= 3;
@ -9593,6 +9598,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
return false;
}
break;
case MT_RAINBOWDASHRING:
Obj_RainbowDashRingThink(mobj);
break;
default:
// check mobj against possible water content, before movement code
P_MobjCheckWater(mobj);
@ -10980,6 +10988,12 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
case MT_SYMBOL:
Obj_SymbolSpawn(mobj);
break;
case MT_DASHRING:
Obj_RegularDashRingSpawn(mobj);
break;
case MT_RAINBOWDASHRING:
Obj_RainbowDashRingSpawn(mobj);
break;
default:
break;
}
@ -13504,6 +13518,12 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj)
Obj_SymbolSetup(mobj, mthing);
break;
}
case MT_DASHRING:
case MT_RAINBOWDASHRING:
{
Obj_DashRingSetup(mobj, mthing);
break;
}
default:
break;
}

View file

@ -475,7 +475,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"s3k47", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Rising dust"}, // Kart AIZ dust
{"s3k48", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pulse"},
{"s3k49", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Impact"}, // Kart bump sound
{"s3k4a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Grab"},
{"s3k4a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Grab"},
{"s3k4b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Splash"},
{"s3k4c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Heavy hit"},
{"s3k4d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing bullet"},
@ -505,7 +505,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"s3k65", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got sphere"}, // Blue Spheres
{"s3k66", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Special stage end"},
{"s3k67", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing missile"},
{"s3k68", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Discovery"}, // Kart final lap
{"s3k68", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Discovery"}, // Kart final lap
{"s3k69", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Switch click"},
{"s3k6a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Special stage clear"}, // Kart finish
{"s3k6b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Punch"},
@ -1197,6 +1197,9 @@ sfxinfo_t S_sfx[NUMSFX] =
{"fhurt1", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Whipped
{"fhurt2", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Hunting
{"dashr", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Regular Dash Ring
{"rainbr", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Rainbow Dash Ring
// SRB2Kart - Engine sounds
// Engine class A
{"krta00", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR, ""},

View file

@ -1265,6 +1265,9 @@ typedef enum
sfx_fhurt1,
sfx_fhurt2,
sfx_dashr,
sfx_rainbr,
// Next up: UNIQUE ENGINE SOUNDS! Hoooooo boy...
// Engine class A - Low Speed, Low Weight
sfx_krta00,