mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-28 13:01:56 +00:00
Merge branch 'jartha/bubble-shield-new-sprite' into 'master'
New sprite for the Bubble Shield See merge request kart-krew-dev/ring-racers-internal!2540
This commit is contained in:
commit
249f1b6789
8 changed files with 223 additions and 0 deletions
|
|
@ -2028,6 +2028,15 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
|
||||||
"S_BUBBLESHIELDWAVE5",
|
"S_BUBBLESHIELDWAVE5",
|
||||||
"S_BUBBLESHIELDWAVE6",
|
"S_BUBBLESHIELDWAVE6",
|
||||||
|
|
||||||
|
// Bubble Shield Visuals
|
||||||
|
"S_BUBA1",
|
||||||
|
"S_BUBB1",
|
||||||
|
"S_BUBB2",
|
||||||
|
"S_BUBC1",
|
||||||
|
"S_BUBC2",
|
||||||
|
"S_BUBD1",
|
||||||
|
"S_BUBE1",
|
||||||
|
|
||||||
// Flame Shield
|
// Flame Shield
|
||||||
"S_FLAMESHIELD1",
|
"S_FLAMESHIELD1",
|
||||||
"S_FLAMESHIELD2",
|
"S_FLAMESHIELD2",
|
||||||
|
|
@ -3616,6 +3625,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
|
||||||
|
|
||||||
"MT_LIGHTNINGSHIELD", // Shields
|
"MT_LIGHTNINGSHIELD", // Shields
|
||||||
"MT_BUBBLESHIELD",
|
"MT_BUBBLESHIELD",
|
||||||
|
"MT_BUBBLESHIELD_VISUAL",
|
||||||
"MT_FLAMESHIELD",
|
"MT_FLAMESHIELD",
|
||||||
"MT_FLAMESHIELDUNDERLAY",
|
"MT_FLAMESHIELDUNDERLAY",
|
||||||
"MT_FLAMESHIELDPAPER",
|
"MT_FLAMESHIELDPAPER",
|
||||||
|
|
|
||||||
41
src/info.c
41
src/info.c
|
|
@ -376,6 +376,11 @@ char sprnames[NUMSPRITES + 1][5] =
|
||||||
"TRNQ", // SPB Manta Ring loop
|
"TRNQ", // SPB Manta Ring loop
|
||||||
"THNS", // Lightning Shield
|
"THNS", // Lightning Shield
|
||||||
"BUBS", // Bubble Shield (not Bubs)
|
"BUBS", // Bubble Shield (not Bubs)
|
||||||
|
"BUBA", // Bubble Shield Outline
|
||||||
|
"BUBB", // Bubble Shield Top Wave
|
||||||
|
"BUBC", // Bubble Shield Bottom Wave
|
||||||
|
"BUBD", // Bubble Shield Reflection
|
||||||
|
"BUBE", // Bubble Shield Underline
|
||||||
"BWVE", // Bubble Shield waves
|
"BWVE", // Bubble Shield waves
|
||||||
"FLMS", // Flame Shield
|
"FLMS", // Flame Shield
|
||||||
"FLMD", // Flame Shield dash
|
"FLMD", // Flame Shield dash
|
||||||
|
|
@ -2564,6 +2569,15 @@ state_t states[NUMSTATES] =
|
||||||
{SPR_BWVE, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BUBBLESHIELDWAVE6}, // S_BUBBLESHIELDWAVE5
|
{SPR_BWVE, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BUBBLESHIELDWAVE6}, // S_BUBBLESHIELDWAVE5
|
||||||
{SPR_BWVE, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_NULL}, // S_BUBBLESHIELDWAVE6
|
{SPR_BWVE, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_NULL}, // S_BUBBLESHIELDWAVE6
|
||||||
|
|
||||||
|
// Bubble Shield Visuals
|
||||||
|
{SPR_BUBA, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_BUBA1}, // S_BUBA1
|
||||||
|
{SPR_BUBB, FF_FULLBRIGHT|FF_ANIMATE, 36, {NULL}, 8, 4, S_BUBB1}, // S_BUBB1
|
||||||
|
{SPR_NULL, 0, 5, {NULL}, 0, 0, S_BUBB1}, // S_BUBB2
|
||||||
|
{SPR_BUBC, FF_FULLBRIGHT|FF_ANIMATE, 36, {NULL}, 8, 4, S_BUBC1}, // S_BUBC1
|
||||||
|
{SPR_NULL, 0, 5, {NULL}, 0, 0, S_BUBC1}, // S_BUBC2
|
||||||
|
{SPR_BUBD, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_BUBD1}, // S_BUBD1
|
||||||
|
{SPR_BUBE, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_BUBE1}, // S_BUBE1
|
||||||
|
|
||||||
{SPR_FLMS, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_FLAMESHIELD2}, // S_FLAMESHIELD1
|
{SPR_FLMS, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_FLAMESHIELD2}, // S_FLAMESHIELD1
|
||||||
{SPR_FLMS, FF_FULLBRIGHT|9, 2, {NULL}, 0, 0, S_FLAMESHIELD3}, // S_FLAMESHIELD2
|
{SPR_FLMS, FF_FULLBRIGHT|9, 2, {NULL}, 0, 0, S_FLAMESHIELD3}, // S_FLAMESHIELD2
|
||||||
{SPR_FLMS, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_FLAMESHIELD4}, // S_FLAMESHIELD3
|
{SPR_FLMS, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_FLAMESHIELD4}, // S_FLAMESHIELD3
|
||||||
|
|
@ -15395,6 +15409,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ // MT_BUBBLESHIELD_VISUAL
|
||||||
|
-1, // doomednum
|
||||||
|
S_INVISIBLE, // 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
|
||||||
|
8, // speed
|
||||||
|
28*FRACUNIT, // radius
|
||||||
|
56*FRACUNIT, // height
|
||||||
|
1, // display offset
|
||||||
|
16, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
{ // MT_FLAMESHIELD
|
{ // MT_FLAMESHIELD
|
||||||
-1, // doomednum
|
-1, // doomednum
|
||||||
S_FLAMESHIELD1, // spawnstate
|
S_FLAMESHIELD1, // spawnstate
|
||||||
|
|
|
||||||
15
src/info.h
15
src/info.h
|
|
@ -915,6 +915,11 @@ typedef enum sprite
|
||||||
SPR_TRNQ, // SPB Manta Ring loop
|
SPR_TRNQ, // SPB Manta Ring loop
|
||||||
SPR_THNS, // Thunder Shield
|
SPR_THNS, // Thunder Shield
|
||||||
SPR_BUBS, // Bubble Shield (not Bubs)
|
SPR_BUBS, // Bubble Shield (not Bubs)
|
||||||
|
SPR_BUBA, // Bubble Shield Outline
|
||||||
|
SPR_BUBB, // Bubble Shield Top Wave
|
||||||
|
SPR_BUBC, // Bubble Shield Bottom Wave
|
||||||
|
SPR_BUBD, // Bubble Shield Reflection
|
||||||
|
SPR_BUBE, // Bubble Shield Underline
|
||||||
SPR_BWVE, // Bubble Shield waves
|
SPR_BWVE, // Bubble Shield waves
|
||||||
SPR_FLMS, // Flame Shield
|
SPR_FLMS, // Flame Shield
|
||||||
SPR_FLMD, // Flame Shield dash
|
SPR_FLMD, // Flame Shield dash
|
||||||
|
|
@ -3059,6 +3064,15 @@ typedef enum state
|
||||||
S_BUBBLESHIELDWAVE5,
|
S_BUBBLESHIELDWAVE5,
|
||||||
S_BUBBLESHIELDWAVE6,
|
S_BUBBLESHIELDWAVE6,
|
||||||
|
|
||||||
|
// Bubble Shield Visuals
|
||||||
|
S_BUBA1,
|
||||||
|
S_BUBB1,
|
||||||
|
S_BUBB2,
|
||||||
|
S_BUBC1,
|
||||||
|
S_BUBC2,
|
||||||
|
S_BUBD1,
|
||||||
|
S_BUBE1,
|
||||||
|
|
||||||
// Flame Shield
|
// Flame Shield
|
||||||
S_FLAMESHIELD1,
|
S_FLAMESHIELD1,
|
||||||
S_FLAMESHIELD2,
|
S_FLAMESHIELD2,
|
||||||
|
|
@ -4674,6 +4688,7 @@ typedef enum mobj_type
|
||||||
|
|
||||||
MT_LIGHTNINGSHIELD, // Shields
|
MT_LIGHTNINGSHIELD, // Shields
|
||||||
MT_BUBBLESHIELD,
|
MT_BUBBLESHIELD,
|
||||||
|
MT_BUBBLESHIELD_VISUAL,
|
||||||
MT_FLAMESHIELD,
|
MT_FLAMESHIELD,
|
||||||
MT_FLAMESHIELDUNDERLAY,
|
MT_FLAMESHIELDUNDERLAY,
|
||||||
MT_FLAMESHIELDPAPER,
|
MT_FLAMESHIELDPAPER,
|
||||||
|
|
|
||||||
|
|
@ -14092,6 +14092,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
P_SetTarget(&shield->target, player->mo);
|
P_SetTarget(&shield->target, player->mo);
|
||||||
S_StartSound(player->mo, sfx_s3k3f);
|
S_StartSound(player->mo, sfx_s3k3f);
|
||||||
player->curshield = KSHIELD_BUBBLE;
|
player->curshield = KSHIELD_BUBBLE;
|
||||||
|
|
||||||
|
Obj_SpawnBubbleShieldVisuals(shield);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!HOLDING_ITEM && NO_HYUDORO)
|
if (!HOLDING_ITEM && NO_HYUDORO)
|
||||||
|
|
|
||||||
|
|
@ -449,6 +449,10 @@ UINT8 K_HogChargeToHogCount(INT32 charge, UINT8 cap);
|
||||||
void K_UpdateBallhogReticules(player_t *player, UINT8 num_hogs, boolean on_release);
|
void K_UpdateBallhogReticules(player_t *player, UINT8 num_hogs, boolean on_release);
|
||||||
void K_DoBallhogAttack(player_t *player, UINT8 num_hogs);
|
void K_DoBallhogAttack(player_t *player, UINT8 num_hogs);
|
||||||
|
|
||||||
|
/* Bubble Shield */
|
||||||
|
void Obj_SpawnBubbleShieldVisuals(mobj_t *source);
|
||||||
|
boolean Obj_TickBubbleShieldVisual(mobj_t *mobj);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ target_sources(SRB2SDL2 PRIVATE
|
||||||
pulley.cpp
|
pulley.cpp
|
||||||
amps.c
|
amps.c
|
||||||
ballhog.cpp
|
ballhog.cpp
|
||||||
|
bubble-shield.cpp
|
||||||
flybot767.c
|
flybot767.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
136
src/objects/bubble-shield.cpp
Normal file
136
src/objects/bubble-shield.cpp
Normal file
|
|
@ -0,0 +1,136 @@
|
||||||
|
// DR. ROBOTNIK'S RING RACERS
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2025 by James Robert Roman
|
||||||
|
// Copyright (C) 2025 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 "objects.hpp"
|
||||||
|
|
||||||
|
#include "../m_easing.h"
|
||||||
|
#include "../m_fixed.h"
|
||||||
|
#include "../tables.h"
|
||||||
|
|
||||||
|
using namespace srb2::objects;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
struct Bubble : Mobj
|
||||||
|
{
|
||||||
|
static constexpr fixed_t kBaseScale = 5*FRACUNIT/4;
|
||||||
|
static constexpr fixed_t kMaxScale = 5*FRACUNIT;
|
||||||
|
static constexpr fixed_t kScaleRange = kMaxScale - kBaseScale;
|
||||||
|
|
||||||
|
void target() = delete;
|
||||||
|
Mobj* follow() const { return Mobj::target(); }
|
||||||
|
void follow(Mobj* n) { Mobj::target(n); }
|
||||||
|
|
||||||
|
player_t* player() const { return follow()->player; }
|
||||||
|
|
||||||
|
bool valid() const { return Mobj::valid(follow()) && player(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Visual : Mobj
|
||||||
|
{
|
||||||
|
void target() = delete;
|
||||||
|
Bubble* bubble() const { return Mobj::target<Bubble>(); }
|
||||||
|
void bubble(Bubble* n) { Mobj::target(n); }
|
||||||
|
|
||||||
|
void extravalue1() = delete;
|
||||||
|
Fixed prev_scale() const { return Mobj::extravalue1; }
|
||||||
|
void prev_scale(Fixed n) { Mobj::extravalue1 = n; }
|
||||||
|
|
||||||
|
bool valid() const { return Mobj::valid(bubble()) && bubble()->valid(); }
|
||||||
|
|
||||||
|
static void spawn
|
||||||
|
( Bubble* bubble,
|
||||||
|
statenum_t state,
|
||||||
|
int flicker,
|
||||||
|
int offset)
|
||||||
|
{
|
||||||
|
if (!bubble->valid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Visual* x = Mobj::spawn<Visual>(bubble->pos(), MT_BUBBLESHIELD_VISUAL);
|
||||||
|
//x->scale(5 * x->scale() / 4);
|
||||||
|
x->state(state);
|
||||||
|
x->spriteyoffset(22*FRACUNIT);
|
||||||
|
x->bubble(bubble);
|
||||||
|
x->linkdraw(bubble->follow(), offset);
|
||||||
|
|
||||||
|
if (flicker)
|
||||||
|
x->renderflags |= RF_DONTDRAW;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tick()
|
||||||
|
{
|
||||||
|
if (!valid())
|
||||||
|
{
|
||||||
|
remove();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
move_origin(bubble()->pos());
|
||||||
|
|
||||||
|
renderflags = ((renderflags ^ RF_DONTDRAW) & RF_DONTDRAW);
|
||||||
|
|
||||||
|
// ATTENTION: this object relies on the original MT_BUBBLESHIELD object for scale
|
||||||
|
fixed_t f = Fixed {bubble()->scale() / bubble()->follow()->scale() - Bubble::kBaseScale} / Fixed {Bubble::kScaleRange};
|
||||||
|
|
||||||
|
scale(Easing_Linear(f,
|
||||||
|
bubble()->follow()->scale() * Fixed {Bubble::kBaseScale},
|
||||||
|
bubble()->follow()->scale() * 4));
|
||||||
|
|
||||||
|
if (sprite != SPR_BUBB &&
|
||||||
|
sprite != SPR_BUBC &&
|
||||||
|
bubble()->player()->bubblecool &&
|
||||||
|
f == 0) // base size
|
||||||
|
renderflags |= RF_DONTDRAW;
|
||||||
|
|
||||||
|
if (scale() > prev_scale())
|
||||||
|
spritescale({ 3*FRACUNIT/2, 3*FRACUNIT/4 });
|
||||||
|
else if (scale() < prev_scale())
|
||||||
|
spritescale({ 3*FRACUNIT/4, 3*FRACUNIT/2 });
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (f == FRACUNIT) // max size
|
||||||
|
{
|
||||||
|
if (leveltime & 1)
|
||||||
|
spritescale({ 3*FRACUNIT/4, 3*FRACUNIT/2 });
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spritescale({ FRACUNIT, FRACUNIT });
|
||||||
|
renderflags |= RF_ADD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
spritescale({ FRACUNIT, FRACUNIT });
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_scale(scale());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}; // namespace
|
||||||
|
|
||||||
|
void Obj_SpawnBubbleShieldVisuals(mobj_t *bubble)
|
||||||
|
{
|
||||||
|
Visual::spawn(static_cast<Bubble*>(bubble), S_BUBA1, 1, 2);
|
||||||
|
Visual::spawn(static_cast<Bubble*>(bubble), S_BUBB1, 0, 1);
|
||||||
|
Visual::spawn(static_cast<Bubble*>(bubble), S_BUBC1, 1, -1);
|
||||||
|
Visual::spawn(static_cast<Bubble*>(bubble), S_BUBD1, 0, -2);
|
||||||
|
Visual::spawn(static_cast<Bubble*>(bubble), S_BUBE1, 1, -3);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean Obj_TickBubbleShieldVisual(mobj_t *mobj)
|
||||||
|
{
|
||||||
|
return static_cast<Visual*>(mobj)->tick();
|
||||||
|
}
|
||||||
14
src/p_mobj.c
14
src/p_mobj.c
|
|
@ -6658,6 +6658,14 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
||||||
Obj_PulleyThink(mobj);
|
Obj_PulleyThink(mobj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
case MT_BUBBLESHIELD_VISUAL:
|
||||||
|
{
|
||||||
|
if (!Obj_TickBubbleShieldVisual(mobj))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
if (mobj->fuse)
|
if (mobj->fuse)
|
||||||
{ // Scenery object fuse! Very basic!
|
{ // Scenery object fuse! Very basic!
|
||||||
|
|
@ -8534,6 +8542,12 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Old Bubble Shield code is still running.
|
||||||
|
// Some of it is visual, some gameplay.
|
||||||
|
// I left it alone and just tell it to go invisible~
|
||||||
|
// See objects/bubble-shield.cpp
|
||||||
|
mobj->renderflags |= RF_DONTDRAW;
|
||||||
|
|
||||||
scale = (5*mobj->target->scale)>>2;
|
scale = (5*mobj->target->scale)>>2;
|
||||||
curstate = ((mobj->tics == 1) ? (mobj->state->nextstate) : ((statenum_t)(mobj->state-states)));
|
curstate = ((mobj->tics == 1) ? (mobj->state->nextstate) : ((statenum_t)(mobj->state-states)));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue