Merge branch 'adventure-air-booster-hardcode' into 'master'

Hardcode Adventure Air Booster & Dimension Disaster objects

Closes #1116

See merge request KartKrew/Kart!2038
This commit is contained in:
Oni 2024-03-09 08:28:51 +00:00
commit 1b3c63f24a
9 changed files with 470 additions and 4 deletions

View file

@ -2437,6 +2437,12 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_DASHRING_VERTICAL_FLASH1", "S_DASHRING_VERTICAL_FLASH1",
"S_DASHRING_VERTICAL_FLASH2", "S_DASHRING_VERTICAL_FLASH2",
// Adventure Air Booster
"S_ADVENTUREAIRBOOSTER",
"S_ADVENTUREAIRBOOSTER_EXHAUST1",
"S_ADVENTUREAIRBOOSTER_EXHAUST2",
"S_ADVENTUREAIRBOOSTER_PART",
// Sneaker Panels // Sneaker Panels
"S_SNEAKERPANEL", "S_SNEAKERPANEL",
"S_SNEAKERPANEL_SMALL", "S_SNEAKERPANEL_SMALL",
@ -2523,6 +2529,17 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_KANNA", "S_KANNA",
"S_OGAMI", "S_OGAMI",
// Dimension Disaster
"S_DVDTRUMPET",
"S_DVDSHINE1",
"S_DVDSHINE2",
"S_DVDSHINE3",
"S_DVDSHINE4",
"S_DVDSHINE5",
"S_DVDSPARK1",
"S_DVDSPARK2",
"S_DVDSPARK3",
"S_SUNBEAMPALM_STEM", "S_SUNBEAMPALM_STEM",
"S_SUNBEAMPALM_LEAF", "S_SUNBEAMPALM_LEAF",
@ -3639,6 +3656,11 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_DASHRING", "MT_DASHRING",
"MT_RAINBOWDASHRING", "MT_RAINBOWDASHRING",
// Adventure Air Booster
"MT_ADVENTUREAIRBOOSTER",
"MT_ADVENTUREAIRBOOSTER_HITBOX",
"MT_ADVENTUREAIRBOOSTER_PART",
// Sneaker Panels // Sneaker Panels
"MT_SNEAKERPANEL", "MT_SNEAKERPANEL",
"MT_SNEAKERPANELSPAWNER", "MT_SNEAKERPANELSPAWNER",
@ -3699,6 +3721,10 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_HANAGUMIHALL_STEAM", "MT_HANAGUMIHALL_STEAM",
"MT_HANAGUMIHALL_NPC", "MT_HANAGUMIHALL_NPC",
// Dimension Disaster
"MT_DVDTRUMPET",
"MT_DVDPARTICLE",
"MT_SUNBEAMPALM_STEM", "MT_SUNBEAMPALM_STEM",
"MT_SUNBEAMPALM_LEAF", "MT_SUNBEAMPALM_LEAF",

View file

@ -501,6 +501,9 @@ char sprnames[NUMSPRITES + 1][5] =
// Dash Rings // Dash Rings
"RAIR", "RAIR",
// Adventure Air Booster
"ADVR",
// Sneaker Panels // Sneaker Panels
"BSTP", "BSTP",
"BSTS", "BSTS",
@ -549,6 +552,10 @@ char sprnames[NUMSPRITES + 1][5] =
"HGCF", "HGCF",
"HGCG", "HGCG",
// Dimension Disaster
"DVDD",
"SPRC",
"TUST", "TUST",
"TULE", "TULE",
@ -2929,6 +2936,12 @@ state_t states[NUMSTATES] =
{SPR_NULL, 0, TICRATE/3 - 2, {NULL}, 0, 0, S_DASHRING_VERTICAL_FLASH2}, // S_DASHRING_VERTICAL_FLASH1 {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 {SPR_RAIR, FF_ADD|3, 2, {NULL}, 0, 0, S_DASHRING_VERTICAL_FLASH1}, // S_DASHRING_VERTICAL_FLASH2
// Adventure Air Booster
{SPR_ADVR, 17|FF_FULLBRIGHT|FF_ADD, 1, {A_RollAngle}, 8, 0, S_ADVENTUREAIRBOOSTER}, // S_ADVENTUREAIRBOOSTER
{SPR_ADVR, 5|FF_FULLBRIGHT|FF_ADD|FF_ANIMATE|FF_PAPERSPRITE, 10, {NULL}, 4, 2, S_NULL}, // S_ADVENTUREAIRBOOSTER_EXHAUST1
{SPR_ADVR, 11|FF_FULLBRIGHT|FF_ADD|FF_ANIMATE|FF_PAPERSPRITE, 10, {NULL}, 4, 2, S_NULL}, // S_ADVENTUREAIRBOOSTER_EXHAUST2
{SPR_ADVR, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_ADVENTUREAIRBOOSTER_PART
// Sneaker Panels // Sneaker Panels
{SPR_BSTP, FF_ANIMATE|FF_GLOBALANIM|FF_FLOORSPRITE|FF_FULLBRIGHT, -1, {NULL}, 5, 2, S_SNEAKERPANEL}, // S_SNEAKERPANEL {SPR_BSTP, FF_ANIMATE|FF_GLOBALANIM|FF_FLOORSPRITE|FF_FULLBRIGHT, -1, {NULL}, 5, 2, S_SNEAKERPANEL}, // S_SNEAKERPANEL
{SPR_BSTS, FF_ANIMATE|FF_GLOBALANIM|FF_FLOORSPRITE|FF_FULLBRIGHT, -1, {NULL}, 5, 2, S_SNEAKERPANEL_SMALL}, // S_SNEAKERPANEL_SMALL {SPR_BSTS, FF_ANIMATE|FF_GLOBALANIM|FF_FLOORSPRITE|FF_FULLBRIGHT, -1, {NULL}, 5, 2, S_SNEAKERPANEL_SMALL}, // S_SNEAKERPANEL_SMALL
@ -3019,6 +3032,17 @@ state_t states[NUMSTATES] =
{SPR_HGCF, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KANNA {SPR_HGCF, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KANNA
{SPR_HGCG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_OGAMI {SPR_HGCG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_OGAMI
// Dimension Disaster
{SPR_DVDD, 1, -1, {NULL}, 0, 0, S_NULL}, // S_DVDTRUMPET
{SPR_SPRC, 1|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_DVDSHINE2}, // S_DVDSHINE1
{SPR_SPRC, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_DVDSHINE3}, // S_DVDSHINE2
{SPR_SPRC, 3|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_DVDSHINE4}, // S_DVDSHINE3
{SPR_SPRC, 4|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_DVDSHINE5}, // S_DVDSHINE4
{SPR_SPRC, 5|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_DVDSHINE1}, // S_DVDSHINE5
{SPR_SPRC, FF_FULLBRIGHT|6, 3, {NULL}, 0, 0, S_DVDSPARK2}, // S_DVDSPARK1
{SPR_SPRC, FF_TRANS20|FF_FULLBRIGHT|7, 3, {NULL}, 0, 0, S_DVDSPARK3}, // S_DVDSPARK2
{SPR_SPRC, FF_TRANS40|FF_FULLBRIGHT|8, 3, {NULL}, 0, 0, S_NULL}, // S_DVDSPARK3
{SPR_TUST, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SUNBEAMPALM_STEM {SPR_TUST, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SUNBEAMPALM_STEM
{SPR_TULE, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SUNBEAMPALM_LEAF {SPR_TULE, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SUNBEAMPALM_LEAF
@ -16834,6 +16858,87 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate S_NULL // raisestate
}, },
{ // MT_ADVENTUREAIRBOOSTER
3500, // doomednum
S_ADVENTUREAIRBOOSTER, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_spdpad, // seesound
0, // 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
50*FRACUNIT, // radius
2*FRACUNIT, // height
0, // dispoffset
0, // mass
0, // damage
sfx_supert, // activesound
MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_ADVENTUREAIRBOOSTER_HITBOX
-1, // doomednum
S_INVISIBLE, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // 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
127*FRACUNIT, // radius
256*FRACUNIT, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_NOCLIPHEIGHT|MF_SPECIAL|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_ADVENTUREAIRBOOSTER_PART
-1, // doomednum
S_ADVENTUREAIRBOOSTER_PART, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // 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
32*FRACUNIT, // radius
64*FRACUNIT, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_SNEAKERPANEL { // MT_SNEAKERPANEL
510, // doomednum 510, // doomednum
S_SNEAKERPANEL, // spawnstate S_SNEAKERPANEL, // spawnstate
@ -17779,6 +17884,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate S_NULL // raisestate
}, },
{ // MT_DVDTRUMPET
3181, // doomednum
S_DVDTRUMPET, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // 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
14*FRACUNIT, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_NOTHINK|MF_SCENERY, // flags
S_NULL // raisestate
},
{ // MT_DVDPARTICLE
-1, // doomednum
S_DVDSPARK1, // spawnstate
1, // 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
2*FRACUNIT, // speed
8*FRACUNIT, // radius
14*FRACUNIT, // height
0, // dispoffset
100, // mass
62*FRACUNIT, // damage
sfx_None, // activesound
MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_NOBLOCKMAP, // flags
S_NULL // raisestate
},
{ // MT_SUNBEAMPALM_STEM { // MT_SUNBEAMPALM_STEM
2697, // doomednum 2697, // doomednum
S_SUNBEAMPALM_STEM, // spawnstate S_SUNBEAMPALM_STEM, // spawnstate

View file

@ -1040,6 +1040,9 @@ typedef enum sprite
// Dash Rings // Dash Rings
SPR_RAIR, SPR_RAIR,
// Adventure Air Booster
SPR_ADVR,
// Sneaker Panels // Sneaker Panels
SPR_BSTP, SPR_BSTP,
SPR_BSTS, SPR_BSTS,
@ -1088,6 +1091,10 @@ typedef enum sprite
SPR_HGCF, SPR_HGCF,
SPR_HGCG, SPR_HGCG,
// Dimension Disaster
SPR_DVDD,
SPR_SPRC,
SPR_TUST, SPR_TUST,
SPR_TULE, SPR_TULE,
@ -3430,6 +3437,12 @@ typedef enum state
S_DASHRING_VERTICAL_FLASH1, S_DASHRING_VERTICAL_FLASH1,
S_DASHRING_VERTICAL_FLASH2, S_DASHRING_VERTICAL_FLASH2,
// Adventure Air Booster
S_ADVENTUREAIRBOOSTER,
S_ADVENTUREAIRBOOSTER_EXHAUST1,
S_ADVENTUREAIRBOOSTER_EXHAUST2,
S_ADVENTUREAIRBOOSTER_PART,
// Sneaker Panels // Sneaker Panels
S_SNEAKERPANEL, S_SNEAKERPANEL,
S_SNEAKERPANEL_SMALL, S_SNEAKERPANEL_SMALL,
@ -3516,6 +3529,17 @@ typedef enum state
S_KANNA, S_KANNA,
S_OGAMI, S_OGAMI,
// Dimension Disaster
S_DVDTRUMPET,
S_DVDSHINE1,
S_DVDSHINE2,
S_DVDSHINE3,
S_DVDSHINE4,
S_DVDSHINE5,
S_DVDSPARK1,
S_DVDSPARK2,
S_DVDSPARK3,
S_SUNBEAMPALM_STEM, S_SUNBEAMPALM_STEM,
S_SUNBEAMPALM_LEAF, S_SUNBEAMPALM_LEAF,
@ -4659,6 +4683,11 @@ typedef enum mobj_type
MT_DASHRING, MT_DASHRING,
MT_RAINBOWDASHRING, MT_RAINBOWDASHRING,
// Adventure Air Booster
MT_ADVENTUREAIRBOOSTER,
MT_ADVENTUREAIRBOOSTER_HITBOX,
MT_ADVENTUREAIRBOOSTER_PART,
// Sneaker Panels // Sneaker Panels
MT_SNEAKERPANEL, MT_SNEAKERPANEL,
MT_SNEAKERPANELSPAWNER, MT_SNEAKERPANELSPAWNER,
@ -4719,6 +4748,10 @@ typedef enum mobj_type
MT_HANAGUMIHALL_STEAM, MT_HANAGUMIHALL_STEAM,
MT_HANAGUMIHALL_NPC, MT_HANAGUMIHALL_NPC,
// Dimension Disaster
MT_DVDTRUMPET,
MT_DVDPARTICLE,
MT_SUNBEAMPALM_STEM, MT_SUNBEAMPALM_STEM,
MT_SUNBEAMPALM_LEAF, MT_SUNBEAMPALM_LEAF,

View file

@ -208,6 +208,12 @@ void Obj_RainbowDashRingThink(mobj_t *mobj);
void Obj_DashRingTouch(mobj_t *mobj, player_t *player); void Obj_DashRingTouch(mobj_t *mobj, player_t *player);
void Obj_DashRingPlayerThink(player_t *player); void Obj_DashRingPlayerThink(player_t *player);
boolean Obj_DashRingPlayerHasNoGravity(player_t *player); boolean Obj_DashRingPlayerHasNoGravity(player_t *player);
boolean Obj_DashRingIsUsableByPlayer(mobj_t *mobj, player_t *player);
/* Adventure Dash Ring */
void Obj_AdventureAirBoosterSetup(mobj_t *mobj, mapthing_t *mthing);
void Obj_AdventureAirBoosterHitboxTouch(mobj_t *hitbox, player_t *player);
void Obj_AdventureAirBoosterFuse(mobj_t *mobj);
/* Sneaker Panels */ /* Sneaker Panels */
void Obj_SneakerPanelSpriteScale(mobj_t *mobj); void Obj_SneakerPanelSpriteScale(mobj_t *mobj);

View file

@ -55,6 +55,7 @@ target_sources(SRB2SDL2 PRIVATE
sealed-star.c sealed-star.c
talk-point.cpp talk-point.cpp
powerup-spinner.cpp powerup-spinner.cpp
adventure-air-booster.c
) )
add_subdirectory(versus) add_subdirectory(versus)

View file

@ -0,0 +1,218 @@
#include "../p_local.h"
#include "../k_kart.h"
#include "../k_objects.h"
#include "../s_sound.h"
#include "../m_random.h"
#include "../r_main.h"
// Hardcoder note: I renamed anything using "Adventure Dash Ring"/"ADR" to "Adventure Air Booster"/"AAB" for consistency with the HVR config
// Hardcoder note: AAB_DIST used to be 64, but it was halved everywhere it was used, so I just halved the base value instead of during calculations
// Hardcoder note: AAB_STRENGTH_ADD used to be 75 to be multiplied with AAB_STRENGTH/100 at runtime, I just baked that calculation into it instead
#define AAB_DIST (32*FRACUNIT) // distance between the back and front of the booster
#define AAB_FRONTBACKSPACE (8*FRACUNIT) // distance between the 2 sides of the front & back part of the booster
#define AAB_RADIUS (225*FRACUNIT) // radius (width) of the booster (in pixels). Used to determine where to spawn the 2 arrows on the sides
#define AAB_STRENGTH (55*FRACUNIT) // default speed for the booster
static const fixed_t AAB_STRENGTH_ADD = (75*AAB_STRENGTH/100); // each time the booster is used, add AAB_STRENGTH_ADD speed to the next player
#define AAB_DASHRINGPUSHTICS (3*TICRATE/2)
#define AAB_SPRINGSTARSTICS (TICRATE/2)
static const skincolornum_t AAB_COLORS[] = {
SKINCOLOR_YELLOW,
SKINCOLOR_GREEN,
SKINCOLOR_RED,
SKINCOLOR_BLUE,
};
static const UINT8 AAB_NUM_COLORS = sizeof(AAB_COLORS) / sizeof(skincolornum_t);
static void AdventureAirBoosterUpdateColor(mobj_t *mobj)
{
mobj_t *part = mobj->hnext;
mobj->color = AAB_COLORS[mobj->extravalue1];
while (!P_MobjWasRemoved(part))
{
part->color = mobj->color;
part = part->hnext;
}
}
void Obj_AdventureAirBoosterSetup(mobj_t *mobj, mapthing_t *mthing)
{
mobj_t *prev = mobj;
mobj_t *part;
angle_t positionAngle = mobj->angle;
fixed_t oldHeight = mobj->height;
fixed_t baseScale = mobj->scale;
fixed_t xPos, yPos;
SINT8 i;
// arg1: double scale (pre-dates UDMF)
if (mthing->thing_args[0])
{
baseScale *= 2;
}
// set scale and flip
P_SetScale(mobj, mobj->movefactor = mobj->old_scale = mobj->destscale = baseScale);
mobj->scalespeed = mobj->scale >> 2;
if (mthing->options & MTF_OBJECTFLIP)
{
mobj->eflags |= MFE_VERTICALFLIP;
mobj->flags2 |= MF2_OBJECTFLIP;
mobj->old_z = mobj->z -= (mobj->height - oldHeight);
}
#define SpawnPart()\
{\
part = P_SpawnMobjFromMobj(mobj, xPos, yPos, 0, MT_ADVENTUREAIRBOOSTER_PART);\
P_SetTarget(&part->target, mobj);\
P_SetTarget(&prev->hnext, part);\
P_SetTarget(&part->hprev, prev);\
prev = part;\
}
// Spawn the back rings
for (i = 0; i < 2; i++)
{
xPos = -P_ReturnThrustX(NULL, positionAngle, (AAB_FRONTBACKSPACE * i) + AAB_DIST);
yPos = -P_ReturnThrustY(NULL, positionAngle, (AAB_FRONTBACKSPACE * i) + AAB_DIST);
// with this order of operations, the first part to spawn is the front, then the back.
SpawnPart();
part->frame |= (1 - i);
part->old_angle = part->angle = mobj->angle + ANGLE_90; // put it sideways
}
// Now the front ring
for (i = 0; i < 2; i++)
{
xPos = P_ReturnThrustX(NULL, positionAngle, -(AAB_FRONTBACKSPACE * i) + AAB_DIST);
yPos = P_ReturnThrustY(NULL, positionAngle, -(AAB_FRONTBACKSPACE * i) + AAB_DIST);
// with this order of operations, the first part to spawn is the front, then the back.
SpawnPart();
part->frame |= (3 - i);
part->old_angle = part->angle = mobj->angle + ANGLE_90; // put it sideways
}
// and now the 2 arrows
positionAngle = mobj->angle + ANGLE_90; // put the angle to the side!
for (i = -1; i < 2; i += 2)
{
xPos = P_ReturnThrustX(NULL, positionAngle, AAB_RADIUS * i) / 2;
yPos = P_ReturnThrustY(NULL, positionAngle, AAB_RADIUS * i) / 2;
// with this order of operations, the first arrow we spawn is the right one, then the left one. Angle them accordingly.
SpawnPart();
part->frame |= 4;
part->old_angle = part->angle = mobj->angle - (ANGLE_45 * i);
}
#undef SpawnPart
part = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_ADVENTUREAIRBOOSTER_HITBOX);
part->old_angle = part->angle = mobj->angle;
part->old_z = part->z -= P_MobjFlip(part) * (part->height >> 1);
P_SetTarget(&part->target, mobj);
P_SetTarget(&mobj->tracer, part); // Hardcoder note: Since the hitbox doesn't need to be colored, I decided not to tack it on the end of the hnext chain; tracer is more easily accessible to scripters
mobj->extravalue1 = 1; // default to green
AdventureAirBoosterUpdateColor(mobj);
}
void Obj_AdventureAirBoosterHitboxTouch(mobj_t *hitbox, player_t *player)
{
mobj_t *mo = player->mo;
mobj_t *booster = hitbox->target;
mobj_t *part;
angle_t finalAngle = hitbox->angle;
angle_t playerAngle;
fixed_t finalSpeed, playerSpeed, xPos, yPos;
SINT8 i;
if (P_MobjWasRemoved(booster) || !Obj_DashRingIsUsableByPlayer(booster, player))
{
return;
}
// reflect angles like springs
finalSpeed = FixedMul(AAB_STRENGTH + (booster->extravalue1 * AAB_STRENGTH_ADD), mapobjectscale);
playerSpeed = FixedHypot(mo->momx, mo->momy);
if (playerSpeed > 0)
{
playerAngle = R_PointToAngle2(0, 0, mo->momx, mo->momy);
}
else
{
playerAngle = mo->angle;
}
finalAngle = K_ReflectAngle(playerAngle, finalAngle, playerSpeed, finalSpeed);
mo->momz = 0;
P_InstaThrust(mo, finalAngle, finalSpeed);
P_SetTarget(&mo->tracer, booster);
player->carry = CR_DASHRING;
player->dashRingPullTics = 0;
player->dashRingPushTics = AAB_DASHRINGPUSHTICS;
player->springstars = AAB_SPRINGSTARSTICS;
player->springcolor = booster->color;
player->turbine = 0;
player->flashing = 0;
player->fastfall = 0;
K_TumbleInterrupt(player);
S_StartSound(mo, booster->info->seesound);
// before we change the colour, spawn a buncha sparkles
for (i = 0; i < 12; i++)
{
part = P_SpawnMobjFromMobj(
hitbox,
FixedMul(AAB_RADIUS << 1, P_RandomFixed(PR_DECORATION)) - AAB_RADIUS,
FixedMul(AAB_RADIUS << 1, P_RandomFixed(PR_DECORATION)) - AAB_RADIUS,
FixedMul(AAB_RADIUS << 1, P_RandomFixed(PR_DECORATION)) - AAB_RADIUS,
MT_DVDPARTICLE
);
part->color = booster->color;
P_SetMobjState(part, S_DVDSHINE1);
P_SetScale(part, part->old_scale = hitbox->scale * P_RandomRange(PR_DECORATION, 2, 4));
part->tics = P_RandomRange(PR_DECORATION, 1, 8);
part->fuse = TICRATE >> 1;
part->destscale = 1;
part->scalespeed = part->scale / part->fuse;
P_InstaThrust(part, finalAngle, FixedMul(finalSpeed, P_RandomRange(PR_DECORATION, FRACUNIT*80/100, FRACUNIT*120/100)));
}
// visuals
booster->fuse = TICRATE >> 1;
booster->destscale = 1;
// spawn the 3 layers
for (i = -1; i < 2; i++)
{
xPos = P_ReturnThrustX(NULL, booster->angle + ANGLE_90, (AAB_RADIUS >> 1) * i) + P_ReturnThrustX(NULL, booster->angle, AAB_RADIUS);
yPos = P_ReturnThrustY(NULL, booster->angle + ANGLE_90, (AAB_RADIUS >> 1) * i) + P_ReturnThrustY(NULL, booster->angle, AAB_RADIUS);
part = P_SpawnMobjFromMobj(hitbox, xPos, yPos, hitbox->info->height >> 1, MT_PARTICLE);
part->old_angle = part->angle = booster->angle;
part->color = booster->color;
P_SetMobjState(part, i == 0 ? S_ADVENTUREAIRBOOSTER_EXHAUST2 : S_ADVENTUREAIRBOOSTER_EXHAUST1);
}
if (++booster->extravalue1 >= AAB_NUM_COLORS)
{
booster->extravalue1 = 0;
// we just went through a blue booster, play sparkle sfx
S_StartSound(mo, booster->info->activesound);
}
AdventureAirBoosterUpdateColor(booster);
}
void Obj_AdventureAirBoosterFuse(mobj_t *mobj)
{
mobj_t *ghost = P_SpawnGhostMobj(mobj);
mobj->destscale = mobj->movefactor;
ghost->destscale = mobj->movefactor * 8;
ghost->scalespeed = mobj->movefactor;
ghost->height = mobj->height;
}

View file

@ -120,18 +120,27 @@ static boolean DashRingsAreTooClose(mobj_t *ring1, mobj_t *ring2)
return false; return false;
} }
void Obj_DashRingTouch(mobj_t *ring, player_t *player) boolean Obj_DashRingIsUsableByPlayer(mobj_t *ring, player_t *player)
{ {
if (player->carry != CR_NONE) if (player->carry != CR_NONE)
{ {
if (player->carry != CR_DASHRING) // being carried by something else if (player->carry != CR_DASHRING) // being carried by something else
return; return false;
if (player->dashRingPullTics > 0) // being pulled into a dash ring already if (player->dashRingPullTics > 0) // being pulled into a dash ring already
return; return false;
if (player->dashRingPushTics > 0 && !P_MobjWasRemoved(player->mo->tracer) && DashRingsAreTooClose(player->mo->tracer, ring)) // dash ring is too close to recently used dash ring 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; return false;
}
return true;
}
void Obj_DashRingTouch(mobj_t *ring, player_t *player)
{
if (!Obj_DashRingIsUsableByPlayer(ring, player))
{
return;
} }
P_SetTarget(&player->mo->tracer, ring); P_SetTarget(&player->mo->tracer, ring);

View file

@ -938,6 +938,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
Obj_DashRingTouch(special, player); Obj_DashRingTouch(special, player);
return; return;
case MT_ADVENTUREAIRBOOSTER_HITBOX:
Obj_AdventureAirBoosterHitboxTouch(special, player);
return;
case MT_DLZ_ROCKET: case MT_DLZ_ROCKET:
Obj_DLZRocketSpecial(special, player); Obj_DLZRocketSpecial(special, player);
return; return;

View file

@ -10053,6 +10053,11 @@ static boolean P_FuseThink(mobj_t *mobj)
P_RemoveMobj(mobj); P_RemoveMobj(mobj);
return false; return false;
} }
case MT_ADVENTUREAIRBOOSTER:
{
Obj_AdventureAirBoosterFuse(mobj);
break;
}
case MT_SNEAKERPANELSPAWNER: case MT_SNEAKERPANELSPAWNER:
{ {
Obj_SneakerPanelSpawnerFuse(mobj); Obj_SneakerPanelSpawnerFuse(mobj);
@ -13810,6 +13815,11 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj)
Obj_DashRingSetup(mobj, mthing); Obj_DashRingSetup(mobj, mthing);
break; break;
} }
case MT_ADVENTUREAIRBOOSTER:
{
Obj_AdventureAirBoosterSetup(mobj, mthing);
break;
}
case MT_SNEAKERPANEL: case MT_SNEAKERPANEL:
{ {
Obj_SneakerPanelSetup(mobj, mthing); Obj_SneakerPanelSetup(mobj, mthing);