mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'mega-barrier' into 'master'
Mega Barrier See merge request KartKrew/Kart!1636
This commit is contained in:
commit
f54ad00662
16 changed files with 263 additions and 13 deletions
|
|
@ -2564,6 +2564,7 @@ void CL_ClearPlayer(INT32 playernum)
|
|||
// TODO: Any better handling in store?
|
||||
P_SetTarget(&players[playernum].flickyAttacker, NULL);
|
||||
P_SetTarget(&players[playernum].powerup.flickyController, NULL);
|
||||
P_SetTarget(&players[playernum].powerup.barrier, NULL);
|
||||
|
||||
// These are camera items and possibly belong to multiple players.
|
||||
P_SetTarget(&players[playernum].skybox.viewpoint, NULL);
|
||||
|
|
|
|||
|
|
@ -212,6 +212,8 @@ typedef enum
|
|||
NUMPOWERUPS = ENDOFPOWERUPS - FIRSTPOWERUP,
|
||||
} kartitems_t;
|
||||
|
||||
#define POWERUP_BIT(x) (1 << ((x) - FIRSTPOWERUP))
|
||||
|
||||
typedef enum
|
||||
{
|
||||
KSHIELD_NONE = 0,
|
||||
|
|
@ -545,6 +547,7 @@ struct powerupvars_t {
|
|||
UINT16 barrierTimer;
|
||||
UINT16 rhythmBadgeTimer;
|
||||
mobj_t *flickyController;
|
||||
mobj_t *barrier;
|
||||
};
|
||||
|
||||
// player_t struct for all alternative viewpoint variables
|
||||
|
|
|
|||
|
|
@ -4787,6 +4787,10 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
|
|||
"S_BLENDEYE_PUYO_SHOCK",
|
||||
"S_BLENDEYE_PUYO_DIE",
|
||||
"S_BLENDEYE_PUYO_DUST",
|
||||
|
||||
"S_MEGABARRIER1",
|
||||
"S_MEGABARRIER2",
|
||||
"S_MEGABARRIER3",
|
||||
};
|
||||
|
||||
// RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1",
|
||||
|
|
@ -5994,6 +5998,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
|
|||
"MT_BLENDEYE_PUYO",
|
||||
"MT_BLENDEYE_PUYO_DUST",
|
||||
"MT_BLENDEYE_PUYO_DUST_COFFEE",
|
||||
"MT_MEGABARRIER",
|
||||
};
|
||||
|
||||
const char *const MOBJFLAG_LIST[] = {
|
||||
|
|
|
|||
|
|
@ -2256,6 +2256,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
P_SetTarget(&players[player].awayview.mobj, NULL);
|
||||
P_SetTarget(&players[player].flickyAttacker, NULL);
|
||||
P_SetTarget(&players[player].powerup.flickyController, NULL);
|
||||
P_SetTarget(&players[player].powerup.barrier, NULL);
|
||||
|
||||
// The following pointers are safe to set directly, because the end goal should be refcount consistency before and after remanifestation.
|
||||
ringShooter = players[player].ringShooter;
|
||||
|
|
|
|||
33
src/info.c
33
src/info.c
|
|
@ -966,6 +966,8 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"PUYD",
|
||||
"PUYE",
|
||||
|
||||
"MGSH", // Mega Barrier
|
||||
|
||||
// First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later
|
||||
"VIEW",
|
||||
};
|
||||
|
|
@ -5613,6 +5615,10 @@ state_t states[NUMSTATES] =
|
|||
{SPR_PUYA, 3, -1, {A_BlendEyePuyoHack}, 0, 0, S_NULL}, // S_BLENDEYE_PUYO_SHOCK,
|
||||
{SPR_PUYA, 4|FF_ANIMATE, 5, {A_BlendEyePuyoHack}, 2, 2, S_NULL}, // S_BLENDEYE_PUYO_DIE,
|
||||
{SPR_PUYA, 5, 2, {A_BlendEyePuyoHack}, 0, 0, S_BLENDEYE_PUYO_DIE}, // S_BLENDEYE_PUYO_DUST,
|
||||
|
||||
{SPR_MGSH, 2|FF_PAPERSPRITE|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_MEGABARRIER1,
|
||||
{SPR_MGSH, 1|FF_PAPERSPRITE|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_MEGABARRIER2,
|
||||
{SPR_MGSH, 0|FF_PAPERSPRITE|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_MEGABARRIER3,
|
||||
};
|
||||
|
||||
mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||
|
|
@ -31738,6 +31744,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
MF_SCENERY|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_MEGABARRIER
|
||||
-1, // doomednum
|
||||
S_MEGABARRIER1, // 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
|
||||
0, // radius
|
||||
0, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY|MF_NOSQUISH, // flags
|
||||
S_NULL // raisestate
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1520,6 +1520,8 @@ typedef enum sprite
|
|||
SPR_PUYD,
|
||||
SPR_PUYE,
|
||||
|
||||
SPR_MGSH, // Mega Barrier
|
||||
|
||||
// First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later
|
||||
SPR_VIEW,
|
||||
|
||||
|
|
@ -6038,6 +6040,10 @@ typedef enum state
|
|||
S_BLENDEYE_PUYO_DIE,
|
||||
S_BLENDEYE_PUYO_DUST,
|
||||
|
||||
S_MEGABARRIER1,
|
||||
S_MEGABARRIER2,
|
||||
S_MEGABARRIER3,
|
||||
|
||||
S_FIRSTFREESLOT,
|
||||
S_LASTFREESLOT = S_FIRSTFREESLOT + NUMSTATEFREESLOTS - 1,
|
||||
NUMSTATES
|
||||
|
|
@ -7264,6 +7270,8 @@ typedef enum mobj_type
|
|||
MT_BLENDEYE_PUYO_DUST,
|
||||
MT_BLENDEYE_PUYO_DUST_COFFEE,
|
||||
|
||||
MT_MEGABARRIER,
|
||||
|
||||
MT_FIRSTFREESLOT,
|
||||
MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1,
|
||||
NUMMOBJTYPES
|
||||
|
|
|
|||
|
|
@ -293,6 +293,9 @@ void Obj_BallSwitchThink(mobj_t *mobj);
|
|||
void Obj_BallSwitchTouched(mobj_t *mobj, mobj_t *toucher);
|
||||
void Obj_BallSwitchDamaged(mobj_t *mobj, mobj_t *inflictor, mobj_t *source);
|
||||
|
||||
/* Barrier Power-Up */
|
||||
void Obj_SpawnMegaBarrier(player_t *player);
|
||||
boolean Obj_MegaBarrierThink(mobj_t *mobj);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -27,17 +27,19 @@ tic_t K_PowerUpRemaining(const player_t* player, kartitems_t powerup)
|
|||
}
|
||||
}
|
||||
|
||||
boolean K_AnyPowerUpRemaining(const player_t* player)
|
||||
UINT32 K_AnyPowerUpRemaining(const player_t* player)
|
||||
{
|
||||
UINT32 mask = 0;
|
||||
|
||||
for (int k = FIRSTPOWERUP; k < ENDOFPOWERUPS; ++k)
|
||||
{
|
||||
if (K_PowerUpRemaining(player, static_cast<kartitems_t>(k)))
|
||||
{
|
||||
return true;
|
||||
mask |= POWERUP_BIT(k);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return mask;
|
||||
}
|
||||
|
||||
void K_GivePowerUp(player_t* player, kartitems_t powerup, tic_t time)
|
||||
|
|
@ -56,6 +58,7 @@ void K_GivePowerUp(player_t* player, kartitems_t powerup, tic_t time)
|
|||
|
||||
case POWERUP_BARRIER:
|
||||
player->powerup.barrierTimer += time;
|
||||
Obj_SpawnMegaBarrier(player);
|
||||
break;
|
||||
|
||||
case POWERUP_BUMPER:
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
tic_t K_PowerUpRemaining(const player_t *player, kartitems_t powerup);
|
||||
boolean K_AnyPowerUpRemaining(const player_t *player);
|
||||
UINT32 K_AnyPowerUpRemaining(const player_t *player); // returns POWERUP_BIT mask
|
||||
void K_GivePowerUp(player_t *player, kartitems_t powerup, tic_t timer);
|
||||
void K_DropPowerUps(player_t *player);
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ target_sources(SRB2SDL2 PRIVATE
|
|||
shadow.cpp
|
||||
ball-switch.cpp
|
||||
charge.c
|
||||
mega-barrier.cpp
|
||||
)
|
||||
|
||||
add_subdirectory(versus)
|
||||
|
|
|
|||
|
|
@ -5,11 +5,6 @@
|
|||
#include "../k_kart.h"
|
||||
#include "../k_powerup.h"
|
||||
|
||||
static INT16 guard_upscale (player_t *player)
|
||||
{
|
||||
return K_PowerUpRemaining(player, POWERUP_BARRIER) ? 40 : player->spheres;
|
||||
}
|
||||
|
||||
void Obj_BlockRingThink (mobj_t *ring)
|
||||
{
|
||||
if (P_MobjWasRemoved(ring->target) || !ring->target->player)
|
||||
|
|
@ -28,7 +23,7 @@ void Obj_BlockRingThink (mobj_t *ring)
|
|||
ring->color = mo->color;
|
||||
|
||||
fixed_t baseScale = mo->scale / 2;
|
||||
baseScale += (mo->scale / 30) * guard_upscale(player);
|
||||
baseScale += (mo->scale / 30) * player->spheres;
|
||||
P_SetScale(ring, baseScale);
|
||||
|
||||
// Twirl
|
||||
|
|
@ -41,7 +36,7 @@ void Obj_BlockRingThink (mobj_t *ring)
|
|||
else
|
||||
ring->renderflags |= RF_DONTDRAW;
|
||||
|
||||
if (!K_PlayerGuard(player))
|
||||
if (K_PowerUpRemaining(player, POWERUP_BARRIER) || !K_PlayerGuard(player))
|
||||
ring->renderflags |= RF_DONTDRAW;
|
||||
}
|
||||
}
|
||||
|
|
@ -61,7 +56,7 @@ void Obj_BlockBodyThink (mobj_t *body)
|
|||
body->flags &= ~(MF_NOCLIPTHING);
|
||||
|
||||
fixed_t baseScale = mo->scale / 2;
|
||||
baseScale += (mo->scale / 30) * guard_upscale(player);
|
||||
baseScale += (mo->scale / 30) * player->spheres;
|
||||
P_SetScale(body, baseScale);
|
||||
|
||||
P_MoveOrigin(body, mo->x, mo->y, mo->z + mo->height/2);
|
||||
|
|
@ -76,7 +71,7 @@ void Obj_BlockBodyThink (mobj_t *body)
|
|||
else
|
||||
body->renderflags |= RF_DONTDRAW;
|
||||
|
||||
if (!K_PlayerGuard(player))
|
||||
if (K_PowerUpRemaining(player, POWERUP_BARRIER) || !K_PlayerGuard(player))
|
||||
body->renderflags |= RF_DONTDRAW;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
161
src/objects/mega-barrier.cpp
Normal file
161
src/objects/mega-barrier.cpp
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2023 by James Robert Roman
|
||||
//
|
||||
// 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 <cstddef>
|
||||
|
||||
#include "../doomdef.h"
|
||||
#include "../d_player.h"
|
||||
#include "../g_game.h"
|
||||
#include "../info.h"
|
||||
#include "../k_kart.h"
|
||||
#include "../k_objects.h"
|
||||
#include "../k_powerup.h"
|
||||
#include "../m_fixed.h"
|
||||
#include "../p_local.h"
|
||||
#include "../p_mobj.h"
|
||||
#include "../r_defs.h"
|
||||
|
||||
#define barrier_player(o) ((o)->extravalue1)
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
struct Barrier;
|
||||
|
||||
// TODO: header
|
||||
struct Mobj : mobj_t
|
||||
{
|
||||
struct PosArg
|
||||
{
|
||||
fixed_t x, y, z;
|
||||
|
||||
PosArg(fixed_t x_, fixed_t y_, fixed_t z_) : x(x_), y(y_), z(z_) {}
|
||||
PosArg(const mobj_t* mobj) : x(mobj->x), y(mobj->y), z(mobj->z) {}
|
||||
};
|
||||
|
||||
bool valid() const { return !P_MobjWasRemoved(this); }
|
||||
|
||||
PosArg center() const { return {x, y, z + (height / 2)}; }
|
||||
|
||||
template <typename T>
|
||||
T* spawn_offset(mobjtype_t type) { return static_cast<T*>(P_SpawnMobjFromMobj(this, 0, 0, 0, type)); }
|
||||
|
||||
void state(statenum_t state) { P_SetMobjState(this, state); }
|
||||
statenum_t statenum() const { return static_cast<statenum_t>(mobj_t::state - states); }
|
||||
|
||||
fixed_t scale() const { return mobj_t::scale; }
|
||||
|
||||
void scale(fixed_t n)
|
||||
{
|
||||
mobj_t::scale = n;
|
||||
mobj_t::destscale = n;
|
||||
}
|
||||
|
||||
void move_origin(const PosArg& p) { P_MoveOrigin(this, p.x, p.y, p.z); }
|
||||
|
||||
void remove() { P_RemoveMobj(this); }
|
||||
};
|
||||
|
||||
struct Player : player_t
|
||||
{
|
||||
struct Powerups : powerupvars_t
|
||||
{
|
||||
Barrier* barrier() const { return reinterpret_cast<Barrier*>(powerupvars_t::barrier); }
|
||||
void barrier(Barrier* n) { P_SetTarget(&this->powerupvars_t::barrier, reinterpret_cast<mobj_t*>(n)); }
|
||||
};
|
||||
|
||||
static Player* at(std::size_t i) { return static_cast<Player*>(&players[i]); }
|
||||
|
||||
bool valid() const { return this >= players && this < &players[MAXPLAYERS] && playeringame[num()]; }
|
||||
|
||||
std::size_t num() const { return this - Player::at(0); }
|
||||
Mobj* mobj() const { return static_cast<Mobj*>(mo); }
|
||||
|
||||
Powerups& powerups() { return static_cast<Powerups&>(player_t::powerup); }
|
||||
const Powerups& powerups() const { return static_cast<const Powerups&>(player_t::powerup); }
|
||||
};
|
||||
|
||||
struct Barrier : Mobj
|
||||
{
|
||||
static constexpr angle_t kSpinSpeed = ANGLE_22h;
|
||||
static constexpr angle_t kSpinGap = 20*ANG1;
|
||||
|
||||
static Barrier* spawn(Player* player, statenum_t state, int idx)
|
||||
{
|
||||
Barrier* child = player->mobj()->spawn_offset<Barrier>(MT_MEGABARRIER);
|
||||
|
||||
child->angle = player->mobj()->angle + (idx * kSpinGap);
|
||||
child->player(player);
|
||||
child->renderflags |= RF_DONTDRAW;
|
||||
child->state(state);
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
static void spawn_chain(Player* player)
|
||||
{
|
||||
player->powerups().barrier(spawn(player, S_MEGABARRIER1, 0));
|
||||
spawn(player, S_MEGABARRIER2, 1);
|
||||
spawn(player, S_MEGABARRIER2, 2);
|
||||
spawn(player, S_MEGABARRIER2, 3);
|
||||
spawn(player, S_MEGABARRIER2, 4);
|
||||
spawn(player, S_MEGABARRIER3, 5);
|
||||
}
|
||||
|
||||
int playernum() const { return barrier_player(this); }
|
||||
Player* player() const { return Player::at(playernum()); }
|
||||
void player(player_t* n) { barrier_player(this) = n - players; }
|
||||
|
||||
bool valid() const { return Mobj::valid() && player()->valid() && player()->mobj()->valid(); }
|
||||
|
||||
bool think()
|
||||
{
|
||||
if (!valid() || !K_PowerUpRemaining(player(), POWERUP_BARRIER))
|
||||
{
|
||||
remove();
|
||||
return false;
|
||||
}
|
||||
|
||||
Mobj* source = player()->mobj();
|
||||
color = source->color;
|
||||
scale(8 * source->scale() / 9);
|
||||
move_origin(source->center());
|
||||
angle += kSpinSpeed;
|
||||
eflags = (eflags & ~MFE_VERTICALFLIP) | (source->eflags & MFE_VERTICALFLIP);
|
||||
|
||||
if (K_PlayerGuard(player()))
|
||||
{
|
||||
renderflags &= ~RF_DONTDRAW;
|
||||
renderflags ^= RF_ADD | RF_TRANS90;
|
||||
}
|
||||
else
|
||||
{
|
||||
renderflags |= RF_DONTDRAW;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}; // namespace
|
||||
|
||||
void Obj_SpawnMegaBarrier(player_t* p)
|
||||
{
|
||||
Player* player = static_cast<Player*>(p);
|
||||
|
||||
if (!static_cast<Mobj*>(player->powerups().barrier())->valid())
|
||||
{
|
||||
Barrier::spawn_chain(player);
|
||||
}
|
||||
}
|
||||
|
||||
boolean Obj_MegaBarrierThink(mobj_t* mobj)
|
||||
{
|
||||
return static_cast<Barrier*>(mobj)->think();
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
#include "../doomtype.h"
|
||||
#include "../info.h"
|
||||
#include "../g_game.h"
|
||||
#include "../m_fixed.h"
|
||||
|
|
@ -85,6 +86,15 @@ struct Aura : mobj_t
|
|||
P_InstaScale(this, 11 * origin()->scale / 10);
|
||||
|
||||
translate();
|
||||
|
||||
if (K_AnyPowerUpRemaining(&players[seek()]) & ~POWERUP_BIT(POWERUP_BARRIER))
|
||||
{
|
||||
renderflags &= ~RF_DONTDRAW;
|
||||
}
|
||||
else
|
||||
{
|
||||
renderflags |= RF_DONTDRAW;
|
||||
}
|
||||
}
|
||||
|
||||
void translate()
|
||||
|
|
|
|||
|
|
@ -6807,6 +6807,14 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
mobj->angle += ANG2;
|
||||
break;
|
||||
}
|
||||
case MT_MEGABARRIER:
|
||||
{
|
||||
if (!Obj_MegaBarrierThink(mobj))
|
||||
{
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MT_VWREF:
|
||||
case MT_VWREB:
|
||||
{
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ typedef enum
|
|||
FLICKYATTACKER = 0x0800,
|
||||
FLICKYCONTROLLER = 0x1000,
|
||||
TRICKINDICATOR = 0x2000,
|
||||
BARRIER = 0x4000,
|
||||
} player_saveflags;
|
||||
|
||||
static inline void P_ArchivePlayer(savebuffer_t *save)
|
||||
|
|
@ -332,6 +333,9 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
|||
if (players[i].powerup.flickyController)
|
||||
flags |= FLICKYCONTROLLER;
|
||||
|
||||
if (players[i].powerup.barrier)
|
||||
flags |= BARRIER;
|
||||
|
||||
WRITEUINT16(save->p, flags);
|
||||
|
||||
if (flags & SKYBOXVIEW)
|
||||
|
|
@ -373,6 +377,9 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
|||
if (flags & FLICKYCONTROLLER)
|
||||
WRITEUINT32(save->p, players[i].powerup.flickyController->mobjnum);
|
||||
|
||||
if (flags & BARRIER)
|
||||
WRITEUINT32(save->p, players[i].powerup.barrier->mobjnum);
|
||||
|
||||
WRITEUINT32(save->p, (UINT32)players[i].followitem);
|
||||
|
||||
WRITEUINT32(save->p, players[i].charflags);
|
||||
|
|
@ -911,6 +918,9 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
|||
if (flags & FLICKYCONTROLLER)
|
||||
players[i].powerup.flickyController = (mobj_t *)(size_t)READUINT32(save->p);
|
||||
|
||||
if (flags & BARRIER)
|
||||
players[i].powerup.barrier = (mobj_t *)(size_t)READUINT32(save->p);
|
||||
|
||||
players[i].followitem = (mobjtype_t)READUINT32(save->p);
|
||||
|
||||
//SetPlayerSkinByNum(i, players[i].skin);
|
||||
|
|
@ -5743,6 +5753,13 @@ static void P_RelinkPointers(void)
|
|||
if (!P_SetTarget(&players[i].powerup.flickyController, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "powerup.flickyController not found on player %d\n", i);
|
||||
}
|
||||
if (players[i].powerup.barrier)
|
||||
{
|
||||
temp = (UINT32)(size_t)players[i].powerup.barrier;
|
||||
players[i].powerup.barrier = NULL;
|
||||
if (!P_SetTarget(&players[i].powerup.barrier, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "powerup.barrier not found on player %d\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4069,6 +4069,7 @@ void P_PlayerThink(player_t *player)
|
|||
PlayerPointerErase(player->hoverhyudoro);
|
||||
PlayerPointerErase(player->flickyAttacker);
|
||||
PlayerPointerErase(player->powerup.flickyController);
|
||||
PlayerPointerErase(player->powerup.barrier);
|
||||
|
||||
#undef PlayerPointerErase
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue