mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'destroy-kart' into 'master'
Destroyed Kart effects Closes #1146 See merge request KartKrew/Kart!2196
This commit is contained in:
commit
531e4ccd4a
13 changed files with 681 additions and 148 deletions
|
|
@ -370,6 +370,13 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
|
|||
"S_KART_TIRE1",
|
||||
"S_KART_TIRE2",
|
||||
|
||||
"S_KART_FIRE",
|
||||
"S_KART_SMOKE",
|
||||
|
||||
"S_KART_XPL01",
|
||||
"S_KART_XPL02",
|
||||
"S_KART_XPL03",
|
||||
|
||||
// Boss Explosion
|
||||
"S_BOSSEXPLODE",
|
||||
|
||||
|
|
@ -3061,6 +3068,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
|
|||
"MT_PLAYER",
|
||||
"MT_KART_LEFTOVER",
|
||||
"MT_KART_TIRE",
|
||||
"MT_KART_PARTICLE",
|
||||
|
||||
// Generic Boss Items
|
||||
"MT_BOSSEXPLODE",
|
||||
|
|
|
|||
60
src/info.c
60
src/info.c
|
|
@ -746,6 +746,22 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
// Tutorial
|
||||
"TLKP", // Talk Point
|
||||
|
||||
// Destroyed Kart
|
||||
"DIEA", // tire
|
||||
"DIEB", // pipeframe bar
|
||||
"DIEC", // pedal tip
|
||||
"DIED", // right pedal
|
||||
"DIEE", // steering wheel
|
||||
"DIEF", // kart
|
||||
"DIEG", // left pedal
|
||||
"DIEH", // strut
|
||||
"DIEI", // wheel axle bar
|
||||
"DIEJ", // screw
|
||||
"DIEK", // electric engine
|
||||
"DIEL", // fire
|
||||
"DIEM", // smoke
|
||||
"DIEN", // explosion
|
||||
|
||||
// First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later
|
||||
"VIEW",
|
||||
};
|
||||
|
|
@ -873,18 +889,25 @@ state_t states[NUMSTATES] =
|
|||
{SPR_PLAY, SPR2_DRRO, 1, {NULL}, 0, 0, S_KART_DRIFT_R_OUT}, // S_KART_DRIFT_R_OUT
|
||||
{SPR_PLAY, SPR2_DRRI, 1, {NULL}, 0, 0, S_KART_DRIFT_R_IN}, // S_KART_DRIFT_R_IN
|
||||
{SPR_PLAY, SPR2_SPIN|FF_ANIMATE, 350, {NULL}, 0, 1, S_KART_STILL}, // S_KART_SPINOUT
|
||||
{SPR_PLAY, SPR2_DEAD, 3, {NULL}, 0, 0, S_KART_DEAD}, // S_KART_DEAD
|
||||
{SPR_PLAY, SPR2_DEAD|FF_SEMIBRIGHT, 3, {NULL}, 0, 0, S_KART_DEAD}, // S_KART_DEAD
|
||||
{SPR_PLAY, SPR2_SIGN|FF_ANIMATE|FF_PAPERSPRITE, -1, {NULL}, 0, 1, 0}, // S_KART_SIGN
|
||||
{SPR_PLAY, SPR2_SIGL|FF_ANIMATE|FF_PAPERSPRITE, -1, {NULL}, 0, 1, 0}, // S_KART_SIGL
|
||||
|
||||
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_OBJPLACE_DUMMY}, // S_OBJPLACE_DUMMY
|
||||
|
||||
{SPR_KART, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KART_LEFTOVER
|
||||
{SPR_KART, 1, -1, {NULL}, 0, 0, S_NULL}, // S_KART_LEFTOVER_NOTIRES
|
||||
{SPR_DIEF, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KART_LEFTOVER_NOTIRES
|
||||
|
||||
{SPR_TIRE, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KART_TIRE1
|
||||
{SPR_TIRE, 1, -1, {NULL}, 0, 0, S_NULL}, // S_KART_TIRE2
|
||||
|
||||
{SPR_DIEL, 0|FF_ANIMATE, 12, {NULL}, 11, 1, S_NULL}, // S_KART_FIRE
|
||||
{SPR_DIEM, FF_SEMIBRIGHT|FF_ANIMATE|FF_TRANS30, 30, {NULL}, 9, 3, S_NULL}, // S_KART_SMOKE
|
||||
|
||||
{SPR_DIEN, 0|FF_PAPERSPRITE|FF_ADD, 3, {NULL}, 0, 0, S_KART_XPL02}, // S_KART_XPL01
|
||||
{SPR_DIEN, 1|FF_PAPERSPRITE|FF_ADD|FF_ANIMATE, 4, {NULL}, 1, 2, S_KART_XPL03}, // S_KART_XPL02
|
||||
{SPR_DIEN, 3|FF_PAPERSPRITE|FF_ADD|FF_ANIMATE, 10, {NULL}, 4, 2, S_NULL}, // S_KART_XPL03
|
||||
|
||||
// Boss Explosion
|
||||
{SPR_BOM2, FF_FULLBRIGHT|FF_ANIMATE, (5*7), {NULL}, 6, 5, S_NULL}, // S_BOSSEXPLODE
|
||||
|
||||
|
|
@ -3722,7 +3745,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_KART_DEAD, // deathstate
|
||||
S_KART_SPINOUT, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
1, // speed
|
||||
|
|
@ -3738,13 +3761,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
|
||||
{ // MT_KART_LEFTOVER
|
||||
4095, // doomednum
|
||||
S_KART_LEFTOVER, // spawnstate
|
||||
S_KART_LEFTOVER_NOTIRES, // spawnstate
|
||||
2, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
S_KART_LEFTOVER_NOTIRES, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
|
|
@ -3790,6 +3813,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_KART_PARTICLE
|
||||
-1, // doomednum
|
||||
S_INVISIBLE, // spawnstate
|
||||
1, // 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
|
||||
1, // speed
|
||||
6*FRACUNIT, // radius
|
||||
12*FRACUNIT, // height
|
||||
-1, // display offset
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPTHING|MF_DONTENCOREMAP|MF_NOSQUISH, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_BOSSEXPLODE
|
||||
-1, // doomednum
|
||||
S_BOSSEXPLODE, // spawnstate
|
||||
|
|
|
|||
24
src/info.h
24
src/info.h
|
|
@ -1281,6 +1281,22 @@ typedef enum sprite
|
|||
// Tutorial
|
||||
SPR_TLKP, // Talk Point
|
||||
|
||||
// Destroyed Kart
|
||||
SPR_DIEA, // tire
|
||||
SPR_DIEB, // pipeframe bar
|
||||
SPR_DIEC, // pedal tip
|
||||
SPR_DIED, // right pedal
|
||||
SPR_DIEE, // steering wheel
|
||||
SPR_DIEF, // kart
|
||||
SPR_DIEG, // left pedal
|
||||
SPR_DIEH, // strut
|
||||
SPR_DIEI, // wheel axle bar
|
||||
SPR_DIEJ, // screw
|
||||
SPR_DIEK, // electric engine
|
||||
SPR_DIEL, // fire
|
||||
SPR_DIEM, // smoke
|
||||
SPR_DIEN, // explosion
|
||||
|
||||
// First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later
|
||||
SPR_VIEW,
|
||||
|
||||
|
|
@ -1371,6 +1387,13 @@ typedef enum state
|
|||
S_KART_TIRE1,
|
||||
S_KART_TIRE2,
|
||||
|
||||
S_KART_FIRE,
|
||||
S_KART_SMOKE,
|
||||
|
||||
S_KART_XPL01,
|
||||
S_KART_XPL02,
|
||||
S_KART_XPL03,
|
||||
|
||||
// Boss Explosion
|
||||
S_BOSSEXPLODE,
|
||||
|
||||
|
|
@ -4089,6 +4112,7 @@ typedef enum mobj_type
|
|||
MT_PLAYER,
|
||||
MT_KART_LEFTOVER,
|
||||
MT_KART_TIRE,
|
||||
MT_KART_PARTICLE,
|
||||
|
||||
// Generic Boss Items
|
||||
MT_BOSSEXPLODE,
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ void Obj_DuelBombInit(mobj_t *bomb);
|
|||
|
||||
/* Broly Ki */
|
||||
mobj_t *Obj_SpawnBrolyKi(mobj_t *source, tic_t duration);
|
||||
mobj_t *Obj_SpawnCustomBrolyKi(mobj_t *source, tic_t duration, fixed_t start, fixed_t end);
|
||||
boolean Obj_BrolyKiThink(mobj_t *ki);
|
||||
|
||||
/* Special Stage UFO */
|
||||
|
|
@ -417,6 +418,13 @@ void Obj_TalkPointOrbThink(mobj_t* mo);
|
|||
void Obj_SpawnPowerUpSpinner(mobj_t *source, INT32 powerup, tic_t duration);
|
||||
void Obj_TickPowerUpSpinner(mobj_t *mobj);
|
||||
|
||||
/* Destroyed Kart */
|
||||
void Obj_SpawnDestroyedKart(mobj_t *player);
|
||||
void Obj_DestroyedKartThink(mobj_t *kart);
|
||||
boolean Obj_DestroyKart(mobj_t *kart);
|
||||
void Obj_DestroyedKartParticleThink(mobj_t *part);
|
||||
void Obj_DestroyedKartParticleLanding(mobj_t *part);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2023 by James Robert Roman
|
||||
// Copyright (C) 2023-2024 by James Robert Roman
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
@ -157,7 +157,7 @@ struct Mobj : mobj_t
|
|||
statenum_t num() const { return static_cast<statenum_t>(static_cast<const state_t*>(this) - states); }
|
||||
};
|
||||
|
||||
void state(statenum_t state) { P_SetMobjState(this, state); }
|
||||
void state(statenum_t state) { (player ? P_SetPlayerMobjState : P_SetMobjState)(this, state); }
|
||||
const State* state() const { return static_cast<const State*>(mobj_t::state); }
|
||||
|
||||
|
||||
|
|
@ -276,6 +276,11 @@ struct Mobj : mobj_t
|
|||
{
|
||||
K_SetHitLagForObjects(this, inflictor, source, tics, damage);
|
||||
}
|
||||
void exact_hitlag(INT32 tics, bool damage)
|
||||
{
|
||||
mobj_t::hitlag = tics;
|
||||
mobj_t::eflags = (mobj_t::eflags & ~MFE_DAMAGEHITLAG) | (MFE_DAMAGEHITLAG * damage);
|
||||
}
|
||||
};
|
||||
|
||||
}; // namespace srb2
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ target_sources(SRB2SDL2 PRIVATE
|
|||
talk-point.cpp
|
||||
powerup-spinner.cpp
|
||||
adventure-air-booster.c
|
||||
destroyed-kart.cpp
|
||||
)
|
||||
|
||||
add_subdirectory(versus)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2023 by James Robert Roman
|
||||
// Copyright (C) 2023-2024 by James Robert Roman
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
@ -16,11 +16,13 @@
|
|||
using namespace srb2::objects;
|
||||
|
||||
mobj_t *
|
||||
Obj_SpawnBrolyKi
|
||||
Obj_SpawnCustomBrolyKi
|
||||
( mobj_t * source,
|
||||
tic_t duration)
|
||||
tic_t duration,
|
||||
fixed_t start,
|
||||
fixed_t end)
|
||||
{
|
||||
Broly* x = Broly::spawn<Broly>(static_cast<Mobj*>(source), duration, {64 * mapobjectscale, 0});
|
||||
Broly* x = Broly::spawn<Broly>(static_cast<Mobj*>(source), duration, {start, end});
|
||||
|
||||
if (!x)
|
||||
{
|
||||
|
|
@ -36,6 +38,14 @@ Obj_SpawnBrolyKi
|
|||
return x;
|
||||
}
|
||||
|
||||
mobj_t *
|
||||
Obj_SpawnBrolyKi
|
||||
( mobj_t * source,
|
||||
tic_t duration)
|
||||
{
|
||||
return Obj_SpawnCustomBrolyKi(source, duration, 64 * mapobjectscale, 0);
|
||||
}
|
||||
|
||||
boolean
|
||||
Obj_BrolyKiThink (mobj_t *x)
|
||||
{
|
||||
|
|
|
|||
511
src/objects/destroyed-kart.cpp
Normal file
511
src/objects/destroyed-kart.cpp
Normal file
|
|
@ -0,0 +1,511 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2024 by James Robert Roman.
|
||||
// Copyright (C) 2024 by Kart Krew.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "../cxxutil.hpp"
|
||||
#include "objects.hpp"
|
||||
|
||||
#include "../m_easing.h"
|
||||
#include "../m_random.h"
|
||||
#include "../r_skins.h"
|
||||
#include "../tables.h"
|
||||
|
||||
using namespace srb2::objects;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
Vec2<Fixed> angle_vector(angle_t x)
|
||||
{
|
||||
return Vec2<Fixed> {FCOS(x), FSIN(x)};
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void radial_generic(int ofs, int spokes, F&& f)
|
||||
{
|
||||
int ang = 360 / spokes;
|
||||
for (int i = 0; i < spokes; ++i)
|
||||
{
|
||||
f((ofs + (ang * i)) % 360);
|
||||
}
|
||||
}
|
||||
|
||||
angle_t degr_to_angle(int degr)
|
||||
{
|
||||
return FixedAngle(degr * FRACUNIT);
|
||||
}
|
||||
|
||||
struct Particle : Mobj
|
||||
{
|
||||
void extravalue1() = delete;
|
||||
UINT8 bounces() const { return mobj_t::extravalue1; }
|
||||
void bounces(UINT8 n) { mobj_t::extravalue1 = n; }
|
||||
|
||||
void extravalue2() = delete;
|
||||
UINT8 counter() const { return mobj_t::extravalue2; }
|
||||
void counter(UINT8 n) { mobj_t::extravalue2 = n; }
|
||||
|
||||
bool is_shrapnel() const { return sprite == SPR_KRBM; }
|
||||
|
||||
static void spew(Mobj* source)
|
||||
{
|
||||
auto generic = [&](spritenum_t sprite, int degr, Fixed scale, int momx, const Vec2<int>& momz)
|
||||
{
|
||||
Particle* x = source->spawn_from<Particle>({}, MT_KART_PARTICLE);
|
||||
if (x)
|
||||
{
|
||||
x->sprite = sprite;
|
||||
x->color = source->color;
|
||||
x->frame = FF_SEMIBRIGHT;
|
||||
x->lightlevel = 112;
|
||||
x->scale(scale * x->scale());
|
||||
|
||||
x->instathrust(source->angle + degr_to_angle(degr), momx * mapobjectscale);
|
||||
x->momz = P_RandomRange(PR_ITEM_DEBRIS, momz.x, momz.y) * mapobjectscale * 2;
|
||||
|
||||
x->angle = P_Random(PR_ITEM_DEBRIS);
|
||||
x->rollangle = P_Random(PR_ITEM_DEBRIS);
|
||||
|
||||
x->renderflags |= RF_DONTDRAW;
|
||||
}
|
||||
return x;
|
||||
};
|
||||
|
||||
auto part = [&](spritenum_t sprite, int degr, Fixed scale)
|
||||
{
|
||||
return generic(sprite, degr, scale, 2, {8, 16});
|
||||
};
|
||||
|
||||
auto radial = [&](spritenum_t sprite, int ofs, int spokes, Fixed scale)
|
||||
{
|
||||
radial_generic(ofs, spokes, [&](int ang) { part(sprite, ang, scale); });
|
||||
};
|
||||
|
||||
constexpr Fixed kSmall = 3*FRACUNIT/2;
|
||||
constexpr Fixed kMedium = 7*FRACUNIT/4;
|
||||
constexpr Fixed kLarge = 2*FRACUNIT;
|
||||
|
||||
part(SPR_DIEE, 0, kLarge); // steering wheel
|
||||
part(SPR_DIEK, 180 + 45, kLarge); // engine
|
||||
|
||||
part(SPR_DIEG, 90, kLarge); // left pedal base
|
||||
part(SPR_DIED, -90, kLarge); // right pedal base
|
||||
|
||||
radial(SPR_DIEI, 90, 2, kLarge); // wheel axle bars
|
||||
radial(SPR_DIEC, 90, 2, kLarge); // pedal tips
|
||||
radial(SPR_DIEA, 45, 4, kMedium); // tires
|
||||
radial(SPR_DIEH, 45, 4, kMedium); // struts / springs
|
||||
radial(SPR_DIEB, 360/12, 6, kSmall); // pipeframe bars
|
||||
radial(SPR_DIEJ, 360/16, 8, kSmall); // screws
|
||||
|
||||
radial_generic(0, 6, [&](int degr) { generic(SPR_KRBM, degr, kSmall, 8, {22, 28}); }); // shrapnel
|
||||
|
||||
// explosion
|
||||
radial_generic(
|
||||
45, 4,
|
||||
[&](int degr)
|
||||
{
|
||||
if (Mobj* x = source->spawn_from<Mobj>({0, 0, source->height}, MT_KART_PARTICLE))
|
||||
{
|
||||
x->flags |= MF_NOGRAVITY | MF_NOCLIPHEIGHT;
|
||||
x->height = 0;
|
||||
x->scale(2 * x->scale());
|
||||
x->angle = degr_to_angle(degr);
|
||||
x->state(S_KART_XPL01);
|
||||
x->renderflags |= RF_REDUCEVFX;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void think()
|
||||
{
|
||||
if (state()->num() == S_BRAKEDRIFT)
|
||||
{
|
||||
renderflags ^= RF_DONTDRAW;
|
||||
return;
|
||||
}
|
||||
|
||||
// explosion
|
||||
if (sprite == SPR_DIEN)
|
||||
{
|
||||
counter(counter() + 1);
|
||||
if (counter() > 6)
|
||||
{
|
||||
renderflags ^= RF_DONTDRAW;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
constexpr tic_t kReappear = 16;
|
||||
if (counter() < kReappear && !is_shrapnel())
|
||||
{
|
||||
counter(counter() + 1);
|
||||
if (counter() == kReappear)
|
||||
{
|
||||
renderflags &= ~RF_DONTDRAW;
|
||||
}
|
||||
}
|
||||
|
||||
angle += ANGLE_11hh;
|
||||
rollangle += ANGLE_11hh;
|
||||
|
||||
if (is_shrapnel() && leveltime % 2 == 0)
|
||||
{
|
||||
if (Mobj* x = spawn_from<Mobj>({}, MT_BOOMEXPLODE))
|
||||
{
|
||||
x->color = SKINCOLOR_RUBY;
|
||||
x->scale_between(x->scale() / 2, x->scale() * 8, x->scale() / 16);
|
||||
x->state(S_SLOWBOOM2);
|
||||
}
|
||||
}
|
||||
|
||||
spritescale({FRACUNIT, FRACUNIT}); // unsquish
|
||||
}
|
||||
|
||||
void on_land()
|
||||
{
|
||||
if (!fuse)
|
||||
{
|
||||
fuse = (is_shrapnel() ? 70 : 90);
|
||||
}
|
||||
|
||||
auto squash = [&](int tics)
|
||||
{
|
||||
hitlag(tics);
|
||||
spritescale({2*FRACUNIT, FRACUNIT/2}); // squish
|
||||
};
|
||||
|
||||
switch (sprite)
|
||||
{
|
||||
case SPR_DIEB: // bar
|
||||
squash(2);
|
||||
break;
|
||||
|
||||
case SPR_DIEH: // struts
|
||||
squash(4);
|
||||
break;
|
||||
|
||||
case SPR_DIEI: // screws
|
||||
squash(1);
|
||||
break;
|
||||
|
||||
case SPR_DIEK: // engine
|
||||
squash(5);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!is_shrapnel() && fuse > 7 && (bounces() & 1)) // 7 = 0.2/(1/35)
|
||||
{
|
||||
voice(
|
||||
static_cast<sfxenum_t>(P_RandomRange(PR_ITEM_DEBRIS, sfx_die01, sfx_die03)),
|
||||
P_RandomRange(PR_ITEM_DEBRIS, 20, 40) * 255 / 100
|
||||
);
|
||||
}
|
||||
|
||||
bounces(bounces() + 1);
|
||||
}
|
||||
};
|
||||
|
||||
struct Kart : Mobj
|
||||
{
|
||||
static constexpr tic_t kVibrateTimer = 70;
|
||||
static constexpr UINT32 kNoClipFlags = MF_NOCLIP | MF_NOCLIPTHING;
|
||||
|
||||
static tic_t burn_duration() { return (gametyperules & GTR_CLOSERPLAYERS ? 10 : 20) * TICRATE; }
|
||||
|
||||
void extravalue1() = delete;
|
||||
UINT8 weight() const { return mobj_t::extravalue1; }
|
||||
void weight(UINT8 n) { mobj_t::extravalue1 = n; }
|
||||
|
||||
void extravalue2() = delete;
|
||||
tic_t timer() const { return mobj_t::extravalue2; }
|
||||
void timer(tic_t n) { mobj_t::extravalue2 = n; }
|
||||
|
||||
void threshold() = delete;
|
||||
tic_t cooldown() const { return mobj_t::threshold; }
|
||||
void cooldown(tic_t n) { mobj_t::threshold = n; }
|
||||
|
||||
void movecount() = delete;
|
||||
tic_t burning() const { return mobj_t::movecount; }
|
||||
void burning(tic_t n) { mobj_t::movecount = n; }
|
||||
|
||||
void target() = delete;
|
||||
Mobj* player() const { return Mobj::target(); }
|
||||
void player(Mobj* n) { Mobj::target(n); }
|
||||
|
||||
static void spawn(Mobj* target)
|
||||
{
|
||||
SRB2_ASSERT(target->player != nullptr);
|
||||
|
||||
Kart* kart = target->spawn_from<Kart>({}, MT_KART_LEFTOVER);
|
||||
if (!kart)
|
||||
return;
|
||||
|
||||
kart->angle = target->angle;
|
||||
kart->color = target->color;
|
||||
P_SetObjectMomZ(kart, 20*FRACUNIT, false);
|
||||
kart->weight(target->player->kartweight);
|
||||
kart->flags |= kNoClipFlags;
|
||||
|
||||
if (target->player->pflags & PF_NOCONTEST)
|
||||
target->tracer(kart);
|
||||
|
||||
kart->state(S_INVISIBLE);
|
||||
kart->timer(kVibrateTimer);
|
||||
kart->exact_hitlag(15, true);
|
||||
kart->player(target);
|
||||
|
||||
Obj_SpawnCustomBrolyKi(target, kart->hitlag() - 2, 32 * mapobjectscale, 0);
|
||||
|
||||
target->exact_hitlag(kart->hitlag() + 1, true);
|
||||
target->frame |= FF_SEMIBRIGHT;
|
||||
target->lightlevel = 128;
|
||||
}
|
||||
|
||||
void think()
|
||||
{
|
||||
if (burning() > 0)
|
||||
{
|
||||
burning(burning() - 1);
|
||||
fire();
|
||||
}
|
||||
|
||||
if (cooldown() > 0)
|
||||
{
|
||||
cooldown(cooldown() - 1);
|
||||
}
|
||||
|
||||
if (timer() > 0)
|
||||
{
|
||||
timer(timer() - 1);
|
||||
animate();
|
||||
}
|
||||
}
|
||||
|
||||
bool destroy()
|
||||
{
|
||||
if (cooldown())
|
||||
{
|
||||
// no-op P_DamageMobj
|
||||
return true;
|
||||
}
|
||||
|
||||
if (health <= 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Particle::spew(this);
|
||||
scale(3 * scale() / 2);
|
||||
health = 1;
|
||||
state(S_KART_LEFTOVER_NOTIRES);
|
||||
cooldown(20);
|
||||
burning(burn_duration());
|
||||
|
||||
if (!cv_reducevfx.value)
|
||||
{
|
||||
voice(sfx_die00);
|
||||
}
|
||||
|
||||
if (Mobj* p = player(); Mobj::valid(p))
|
||||
{
|
||||
if (p->player && skins[p->player->skin].flags & SF_BADNIK)
|
||||
{
|
||||
P_SpawnBadnikExplosion(p);
|
||||
p->spritescale({2*FRACUNIT, 2*FRACUNIT});
|
||||
p->flags |= MF_NOSQUISH;
|
||||
}
|
||||
|
||||
p->state(S_KART_DEAD);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
void fire()
|
||||
{
|
||||
auto spread = [&](const Vec2<Fixed>& range, const Vec2<Fixed>& zrange)
|
||||
{
|
||||
angle_t ang = P_Random(PR_ITEM_DEBRIS);
|
||||
Fixed r = P_RandomRange(PR_ITEM_DEBRIS, range.x, range.y) * mapobjectscale * 4;
|
||||
Fixed z = P_RandomRange(PR_ITEM_DEBRIS, zrange.x, zrange.y) * mapobjectscale * 4;
|
||||
return spawn_from<Mobj>({angle_vector(ang) * r, z}, MT_THOK);
|
||||
};
|
||||
|
||||
auto vfx = [&](fixed_t f)
|
||||
{
|
||||
if (Mobj* x = spread({16, 32}, {0, 0}))
|
||||
{
|
||||
x->state(S_KART_FIRE);
|
||||
x->lightlevel = 176;
|
||||
x->renderflags |= RF_ABSOLUTELIGHTLEVEL | RF_SEMIBRIGHT | RF_REDUCEVFX;
|
||||
}
|
||||
|
||||
if (f < 3*FRACUNIT/4)
|
||||
{
|
||||
auto smoke = [&]
|
||||
{
|
||||
if (Mobj* x = spread({3, 6}, {0, 8}))
|
||||
{
|
||||
Fixed from = x->scale() / 3;
|
||||
Fixed to = 5 * x->scale() / 4;
|
||||
x->scale_between(from, to, (to - from) / 35);
|
||||
x->state(S_KART_SMOKE);
|
||||
x->lightlevel = -112;
|
||||
x->momz = 16 * mapobjectscale;
|
||||
}
|
||||
};
|
||||
|
||||
smoke();
|
||||
smoke();
|
||||
}
|
||||
};
|
||||
|
||||
UINT32 rf = RF_SEMIBRIGHT;
|
||||
|
||||
if (burning() && P_IsObjectOnGround(this))
|
||||
{
|
||||
fixed_t f = burning() * FRACUNIT / burn_duration();
|
||||
|
||||
if ((leveltime % std::max(1, Easing_OutCubic(f, 8, 1))) == 0)
|
||||
{
|
||||
vfx(f);
|
||||
}
|
||||
|
||||
if (f < 3*FRACUNIT/4)
|
||||
{
|
||||
auto spark = [&](int degr)
|
||||
{
|
||||
angle_t ang = angle + degr_to_angle(degr);
|
||||
if (Particle* x = spawn_from<Particle>({angle_vector(ang) * Fixed {radius}, 0}, MT_KART_PARTICLE))
|
||||
{
|
||||
x->state(S_BRAKEDRIFT);
|
||||
x->fuse = 12;
|
||||
x->color = SKINCOLOR_PASTEL;
|
||||
x->angle = ang - ANGLE_90;
|
||||
x->scale(2 * x->scale() / 5);
|
||||
x->flags |= MF_NOGRAVITY | MF_NOCLIPHEIGHT;
|
||||
x->renderflags |= RF_ADD;
|
||||
}
|
||||
};
|
||||
|
||||
if (leveltime % 16 == 0)
|
||||
{
|
||||
radial_generic(45, 4, spark);
|
||||
}
|
||||
}
|
||||
|
||||
if (leveltime & 1)
|
||||
{
|
||||
rf = RF_FULLBRIGHT;
|
||||
}
|
||||
|
||||
voice_loop(sfx_kc51);
|
||||
}
|
||||
|
||||
renderflags = (renderflags & ~RF_BRIGHTMASK) | rf;
|
||||
}
|
||||
|
||||
void animate()
|
||||
{
|
||||
Mobj* p = player();
|
||||
|
||||
if (!Mobj::valid(p))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (timer())
|
||||
{
|
||||
// Vibration on the death sprite eases downward
|
||||
p->exact_hitlag(Easing_InCubic(timer() * FRACUNIT / kVibrateTimer, 2, 90), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
flags &= ~kNoClipFlags;
|
||||
P_PlayDeathSound(p);
|
||||
}
|
||||
|
||||
// First tick after hitlag: destroyed kart appears!
|
||||
if (state()->num() == S_INVISIBLE)
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
static void P_SpawnBadnikExplosion(mobj_t *target)
|
||||
{
|
||||
UINT8 count = 24;
|
||||
angle_t ang = 0;
|
||||
angle_t step = ANGLE_MAX / count;
|
||||
fixed_t spd = 8 * mapobjectscale;
|
||||
for (UINT8 i = 0; i < count; ++i)
|
||||
{
|
||||
mobj_t *x = P_SpawnMobjFromMobjUnscaled(
|
||||
target,
|
||||
P_RandomRange(PR_EXPLOSION, -48, 48) * target->scale,
|
||||
P_RandomRange(PR_EXPLOSION, -48, 48) * target->scale,
|
||||
P_RandomRange(PR_EXPLOSION, -48, 48) * target->scale,
|
||||
MT_THOK
|
||||
);
|
||||
x->hitlag = 0;
|
||||
P_InstaScale(x, 3 * x->scale / 2);
|
||||
P_InstaThrust(x, ang, spd);
|
||||
x->momz = P_RandomRange(PR_EXPLOSION, -4, 4) * mapobjectscale;
|
||||
P_SetMobjStateNF(x, S_BADNIK_EXPLOSION1);
|
||||
ang += step;
|
||||
}
|
||||
// burst effects (copied from MT_ITEMCAPSULE)
|
||||
ang = FixedAngle(360*P_RandomFixed(PR_ITEM_DEBRIS));
|
||||
for (UINT8 i = 0; i < 2; i++)
|
||||
{
|
||||
mobj_t *blast = P_SpawnMobjFromMobj(target, 0, 0, target->info->height >> 1, MT_BATTLEBUMPER_BLAST);
|
||||
blast->hitlag = 0;
|
||||
blast->angle = ang + i*ANGLE_90;
|
||||
P_SetScale(blast, 2*blast->scale/3);
|
||||
blast->destscale = 6*blast->scale;
|
||||
blast->scalespeed = (blast->destscale - blast->scale) / 30;
|
||||
P_SetMobjStateNF(blast, static_cast<statenum_t>(S_BADNIK_EXPLOSION_SHOCKWAVE1 + i));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}; // namespace
|
||||
|
||||
void Obj_SpawnDestroyedKart(mobj_t *player)
|
||||
{
|
||||
Kart::spawn(static_cast<Mobj*>(player));
|
||||
}
|
||||
|
||||
void Obj_DestroyedKartThink(mobj_t *kart)
|
||||
{
|
||||
static_cast<Kart*>(kart)->think();
|
||||
}
|
||||
|
||||
boolean Obj_DestroyKart(mobj_t *kart)
|
||||
{
|
||||
return static_cast<Kart*>(kart)->destroy();
|
||||
}
|
||||
|
||||
void Obj_DestroyedKartParticleThink(mobj_t *part)
|
||||
{
|
||||
static_cast<Particle*>(part)->think();
|
||||
}
|
||||
|
||||
void Obj_DestroyedKartParticleLanding(mobj_t *part)
|
||||
{
|
||||
static_cast<Particle*>(part)->on_land();
|
||||
}
|
||||
|
|
@ -1656,40 +1656,6 @@ boolean P_CheckRacers(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
static void P_SpawnBadnikExplosion(mobj_t *target)
|
||||
{
|
||||
UINT8 count = 24;
|
||||
angle_t ang = 0;
|
||||
angle_t step = ANGLE_MAX / count;
|
||||
fixed_t spd = 8 * mapobjectscale;
|
||||
for (UINT8 i = 0; i < count; ++i)
|
||||
{
|
||||
mobj_t *x = P_SpawnMobjFromMobjUnscaled(
|
||||
target,
|
||||
P_RandomRange(PR_EXPLOSION, -48, 48) * target->scale,
|
||||
P_RandomRange(PR_EXPLOSION, -48, 48) * target->scale,
|
||||
P_RandomRange(PR_EXPLOSION, -48, 48) * target->scale,
|
||||
MT_THOK
|
||||
);
|
||||
P_InstaScale(x, 3 * x->scale / 2);
|
||||
P_InstaThrust(x, ang, spd);
|
||||
x->momz = P_RandomRange(PR_EXPLOSION, -4, 4) * mapobjectscale;
|
||||
P_SetMobjStateNF(x, S_BADNIK_EXPLOSION1);
|
||||
ang += step;
|
||||
}
|
||||
// burst effects (copied from MT_ITEMCAPSULE)
|
||||
ang = FixedAngle(360*P_RandomFixed(PR_ITEM_DEBRIS));
|
||||
for (UINT8 i = 0; i < 2; i++)
|
||||
{
|
||||
mobj_t *blast = P_SpawnMobjFromMobj(target, 0, 0, target->info->height >> 1, MT_BATTLEBUMPER_BLAST);
|
||||
blast->angle = ang + i*ANGLE_90;
|
||||
P_SetScale(blast, 2*blast->scale/3);
|
||||
blast->destscale = 6*blast->scale;
|
||||
blast->scalespeed = (blast->destscale - blast->scale) / 30;
|
||||
P_SetMobjStateNF(blast, S_BADNIK_EXPLOSION_SHOCKWAVE1 + i);
|
||||
}
|
||||
}
|
||||
|
||||
/** Kills an object.
|
||||
*
|
||||
* \param target The victim.
|
||||
|
|
@ -1890,31 +1856,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
{
|
||||
fixed_t flingSpeed = FixedHypot(target->momx, target->momy);
|
||||
angle_t flingAngle;
|
||||
mobj_t *kart;
|
||||
|
||||
target->fuse = TICRATE*3; // timer before mobj disappears from view (even if not an actual player)
|
||||
target->momx = target->momy = target->momz = 0;
|
||||
|
||||
kart = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_KART_LEFTOVER);
|
||||
|
||||
if (kart && !P_MobjWasRemoved(kart))
|
||||
{
|
||||
kart->angle = target->angle;
|
||||
kart->color = target->color;
|
||||
kart->hitlag = target->hitlag;
|
||||
kart->eflags |= MFE_DAMAGEHITLAG;
|
||||
P_SetObjectMomZ(kart, 6*FRACUNIT, false);
|
||||
kart->extravalue1 = target->player->kartweight;
|
||||
|
||||
// Copy interp data
|
||||
kart->old_angle = target->old_angle;
|
||||
kart->old_x = target->old_x;
|
||||
kart->old_y = target->old_y;
|
||||
kart->old_z = target->old_z;
|
||||
|
||||
if (target->player->pflags & PF_NOCONTEST)
|
||||
P_SetTarget(&target->tracer, kart);
|
||||
}
|
||||
Obj_SpawnDestroyedKart(target);
|
||||
|
||||
if (source && !P_MobjWasRemoved(source))
|
||||
{
|
||||
|
|
@ -1956,16 +1902,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
boolean battle = (gametyperules & (GTR_BUMPERS | GTR_BOSS)) == GTR_BUMPERS;
|
||||
P_InstaThrust(target, flingAngle, max(flingSpeed, 6 * target->scale) / (battle ? 1 : 3));
|
||||
P_SetObjectMomZ(target, battle ? 20*FRACUNIT : 18*FRACUNIT, false);
|
||||
|
||||
P_PlayDeathSound(target);
|
||||
|
||||
if (skins[target->player->skin].flags & SF_BADNIK)
|
||||
{
|
||||
P_SpawnBadnikExplosion(target);
|
||||
target->spritexscale = 2*FRACUNIT;
|
||||
target->spriteyscale = 2*FRACUNIT;
|
||||
target->flags |= MF_NOSQUISH;
|
||||
}
|
||||
}
|
||||
|
||||
// Prisons Free Play: don't eliminate P1 for
|
||||
|
|
@ -2554,6 +2490,9 @@ static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *sou
|
|||
|
||||
static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 type)
|
||||
{
|
||||
(void)inflictor;
|
||||
(void)source;
|
||||
|
||||
const boolean beforeexit = !(player->exiting || (player->pflags & PF_NOCONTEST));
|
||||
|
||||
if (type == DMG_SPECTATOR && (G_GametypeHasTeams() || G_GametypeHasSpectators()))
|
||||
|
|
@ -2672,7 +2611,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
|
|||
}
|
||||
|
||||
K_DropEmeraldsFromPlayer(player, player->emeralds);
|
||||
K_SetHitLagForObjects(player->mo, inflictor, source, MAXHITLAGTICS, true);
|
||||
//K_SetHitLagForObjects(player->mo, inflictor, source, MAXHITLAGTICS, true);
|
||||
|
||||
player->carry = CR_NONE;
|
||||
|
||||
|
|
@ -2697,19 +2636,6 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
|
|||
|
||||
if (type == DMG_TIMEOVER)
|
||||
{
|
||||
if (gametyperules & GTR_CIRCUIT)
|
||||
{
|
||||
mobj_t *boom;
|
||||
|
||||
player->mo->flags |= (MF_NOGRAVITY|MF_NOCLIP);
|
||||
player->mo->renderflags |= RF_DONTDRAW;
|
||||
|
||||
boom = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_FZEROBOOM);
|
||||
boom->scale = player->mo->scale;
|
||||
boom->angle = player->mo->angle;
|
||||
P_SetTarget(&boom->target, player->mo);
|
||||
}
|
||||
|
||||
player->pflags |= PF_ELIMINATED;
|
||||
}
|
||||
|
||||
|
|
@ -2898,6 +2824,14 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
case MT_ICECAPBLOCK:
|
||||
return Obj_TryCrateDamage(target, inflictor);
|
||||
|
||||
case MT_KART_LEFTOVER:
|
||||
// intangible (do not let instawhip shred damage)
|
||||
if (Obj_DestroyKart(target))
|
||||
return false;
|
||||
|
||||
P_SetObjectMomZ(target, 12*FRACUNIT, false);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -3467,7 +3401,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
if ((damagetype & DMG_TYPEMASK) != DMG_WHUMBLE && (gametyperules & GTR_BUMPERS) && !battleprisons)
|
||||
laglength /= 2;
|
||||
|
||||
K_SetHitLagForObjects(target, inflictor, source, laglength, true);
|
||||
if (!(target->player && (damagetype & DMG_DEATHMASK)))
|
||||
K_SetHitLagForObjects(target, inflictor, source, laglength, true);
|
||||
|
||||
target->flags2 |= MF2_ALREADYHIT;
|
||||
|
||||
|
|
|
|||
82
src/p_mobj.c
82
src/p_mobj.c
|
|
@ -1282,6 +1282,10 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
|||
if (mo->fuse)
|
||||
gravityadd /= 10;
|
||||
break;
|
||||
case MT_KART_PARTICLE:
|
||||
if (!mo->fuse)
|
||||
gravityadd *= 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -2468,68 +2472,17 @@ boolean P_ZMovement(mobj_t *mo)
|
|||
mom.z = -mom.z;
|
||||
else if (mo->type == MT_KART_LEFTOVER)
|
||||
{
|
||||
if (mo->health > 1)
|
||||
{
|
||||
const fixed_t tireOffset = 32;
|
||||
const angle_t aOffset = ANGLE_22h;
|
||||
|
||||
UINT8 i;
|
||||
angle_t tireAngle;
|
||||
mobj_t *tire;
|
||||
|
||||
// Spawn tires!
|
||||
mo->health = 1;
|
||||
P_SetMobjState(mo, S_KART_LEFTOVER_NOTIRES);
|
||||
|
||||
// Front tires
|
||||
tireAngle = mo->angle - aOffset;
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
tire = P_SpawnMobjFromMobj(
|
||||
mo,
|
||||
tireOffset * FINECOSINE(tireAngle >> ANGLETOFINESHIFT),
|
||||
tireOffset * FINESINE(tireAngle >> ANGLETOFINESHIFT),
|
||||
0,
|
||||
MT_KART_TIRE
|
||||
);
|
||||
|
||||
tire->angle = mo->angle;
|
||||
tire->fuse = 3*TICRATE;
|
||||
P_InstaThrust(tire, tireAngle, 4 * mo->scale);
|
||||
P_SetObjectMomZ(tire, 4*FRACUNIT, false);
|
||||
|
||||
tireAngle += (aOffset * 2);
|
||||
}
|
||||
|
||||
// Back tires
|
||||
tireAngle = (mo->angle + ANGLE_180) - aOffset;
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
tire = P_SpawnMobjFromMobj(
|
||||
mo,
|
||||
tireOffset * FINECOSINE(tireAngle >> ANGLETOFINESHIFT),
|
||||
tireOffset * FINESINE(tireAngle >> ANGLETOFINESHIFT),
|
||||
0,
|
||||
MT_KART_TIRE
|
||||
);
|
||||
|
||||
tire->angle = mo->angle;
|
||||
tire->fuse = 3*TICRATE;
|
||||
P_InstaThrust(tire, tireAngle, 4 * mo->scale);
|
||||
P_SetObjectMomZ(tire, 4*FRACUNIT, false);
|
||||
|
||||
P_SetMobjState(tire, S_KART_TIRE2);
|
||||
|
||||
tireAngle += (aOffset * 2);
|
||||
}
|
||||
}
|
||||
|
||||
mom.z = 0;
|
||||
}
|
||||
else if (mo->type == MT_KART_TIRE)
|
||||
{
|
||||
mom.z = -mom.z;
|
||||
}
|
||||
else if (mo->type == MT_KART_PARTICLE)
|
||||
{
|
||||
mom.z = -mom.z / (mo->fuse ? 1 : 2);
|
||||
Obj_DestroyedKartParticleLanding(mo);
|
||||
}
|
||||
else if (mo->type == MT_BIGTUMBLEWEED
|
||||
|| mo->type == MT_LITTLETUMBLEWEED
|
||||
|| mo->type == MT_CANNONBALLDECOR
|
||||
|
|
@ -9895,6 +9848,22 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
break;
|
||||
}
|
||||
|
||||
case MT_KART_PARTICLE:
|
||||
{
|
||||
Obj_DestroyedKartParticleThink(mobj);
|
||||
break;
|
||||
}
|
||||
|
||||
case MT_KART_LEFTOVER:
|
||||
{
|
||||
Obj_DestroyedKartThink(mobj);
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// check mobj against possible water content, before movement code
|
||||
P_MobjCheckWater(mobj);
|
||||
|
|
@ -9958,6 +9927,7 @@ static boolean P_CanFlickerFuse(mobj_t *mobj)
|
|||
case MT_POGOSPRING:
|
||||
case MT_EMERALD:
|
||||
case MT_BLENDEYE_PUYO:
|
||||
case MT_KART_PARTICLE:
|
||||
if (mobj->fuse <= TICRATE)
|
||||
{
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -2828,7 +2828,6 @@ static void P_DeathThink(player_t *player)
|
|||
if (player->mo)
|
||||
{
|
||||
player->mo->flags |= (MF_NOGRAVITY|MF_NOCLIP);
|
||||
player->mo->renderflags |= RF_DONTDRAW;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1529,6 +1529,12 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
// Patching up base sounds
|
||||
{"s226l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // s2 spikes LOUD
|
||||
|
||||
// Destroyed Kart
|
||||
{"die00", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"die01", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"die02", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"die03", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
|
||||
// SRB2kart - Skin sounds
|
||||
{"kwin", false, 64, 96, -1, NULL, 0, SKSKWIN, -1, LUMPERROR, ""},
|
||||
{"klose", false, 64, 96, -1, NULL, 0, SKSKLOSE, -1, LUMPERROR, ""},
|
||||
|
|
|
|||
|
|
@ -1605,6 +1605,12 @@ typedef enum
|
|||
// Patch-up
|
||||
sfx_s226l,
|
||||
|
||||
// Destroyed Kart
|
||||
sfx_die00,
|
||||
sfx_die01,
|
||||
sfx_die02,
|
||||
sfx_die03,
|
||||
|
||||
// And LASTLY, Kart's skin sounds.
|
||||
sfx_kwin,
|
||||
sfx_klose,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue