mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-02-19 03:51:34 +00:00
Merge branch 'spindash-tweaks' into 'master'
Spindash tweaks See merge request KartKrew/Kart!578
This commit is contained in:
commit
1fbe04bd6d
8 changed files with 306 additions and 5 deletions
|
|
@ -488,6 +488,7 @@ typedef struct player_s
|
|||
UINT8 trickboostdecay; // used to know how long you've waited
|
||||
UINT8 trickboost; // Trick boost. This one is weird and has variable speed. Dear god.
|
||||
|
||||
tic_t ebrakefor; // Ebrake timer, used for visuals.
|
||||
|
||||
UINT32 roundscore; // battle score this round
|
||||
UINT8 emeralds;
|
||||
|
|
|
|||
|
|
@ -4662,6 +4662,20 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
|
|||
"S_SPINDASHDUST",
|
||||
"S_SPINDASHWIND",
|
||||
|
||||
"S_SOFTLANDING1",
|
||||
"S_SOFTLANDING2",
|
||||
"S_SOFTLANDING3",
|
||||
"S_SOFTLANDING4",
|
||||
"S_SOFTLANDING5",
|
||||
|
||||
"S_DOWNLINE1",
|
||||
"S_DOWNLINE2",
|
||||
"S_DOWNLINE3",
|
||||
"S_DOWNLINE4",
|
||||
"S_DOWNLINE5",
|
||||
|
||||
"S_HOLDBUBBLE",
|
||||
|
||||
// Finish line beam
|
||||
"S_FINISHBEAM1",
|
||||
"S_FINISHBEAM2",
|
||||
|
|
@ -5781,6 +5795,9 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
|
|||
|
||||
"MT_SPINDASHDUST",
|
||||
"MT_SPINDASHWIND",
|
||||
"MT_SOFTLANDING",
|
||||
"MT_DOWNLINE",
|
||||
"MT_HOLDBUBBLE",
|
||||
|
||||
"MT_PAPERITEMSPOT",
|
||||
|
||||
|
|
|
|||
101
src/info.c
101
src/info.c
|
|
@ -752,6 +752,9 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
|
||||
"SDDS", // Spindash dust
|
||||
"SDWN", // Spindash wind
|
||||
"EBRK", // Soft Landing / Ebrake aura stuff.
|
||||
"HMTR", // Down Lines
|
||||
"HBUB", // HOLD! Bubble
|
||||
|
||||
"TRCK",
|
||||
|
||||
|
|
@ -5246,6 +5249,23 @@ state_t states[NUMSTATES] =
|
|||
{SPR_SDDS, FF_ANIMATE, 9, {NULL}, 9, 1, S_NULL}, // S_SPINDASHDUST
|
||||
{SPR_SDWN, FF_ANIMATE|FF_PAPERSPRITE, 18, {NULL}, 9, 2, S_NULL}, // S_SPINDASHWIND
|
||||
|
||||
// Soft Landing
|
||||
{SPR_EBRK, 0|FF_ADD|FF_FLOORSPRITE, 4, {NULL}, 0, 0, S_SOFTLANDING2}, // S_SOFTLANDING1
|
||||
{SPR_EBRK, 1|FF_ADD|FF_FLOORSPRITE, 4, {NULL}, 0, 0, S_SOFTLANDING3}, // S_SOFTLANDING2
|
||||
{SPR_EBRK, 2|FF_ADD|FF_FLOORSPRITE, 4, {NULL}, 0, 0, S_SOFTLANDING4}, // S_SOFTLANDING3
|
||||
{SPR_EBRK, 3|FF_ADD|FF_FLOORSPRITE, 4, {NULL}, 0, 0, S_SOFTLANDING5}, // S_SOFTLANDING4
|
||||
{SPR_EBRK, 4|FF_ADD|FF_FLOORSPRITE, 4, {NULL}, 0, 0, S_NULL}, // S_SOFTLANDING5
|
||||
|
||||
// Downwards Lines
|
||||
{SPR_HMTR, 0|FF_ADD, 1, {NULL}, 0, 0, S_DOWNLINE2}, // S_DOWNLINE1
|
||||
{SPR_HMTR, 1|FF_ADD, 1, {NULL}, 0, 0, S_DOWNLINE3}, // S_DOWNLINE2
|
||||
{SPR_HMTR, 2|FF_ADD, 1, {NULL}, 0, 0, S_DOWNLINE4}, // S_DOWNLINE3
|
||||
{SPR_HMTR, 3|FF_ADD, 1, {NULL}, 0, 0, S_DOWNLINE5}, // S_DOWNLINE4
|
||||
{SPR_HMTR, 4|FF_ADD, 1, {NULL}, 0, 0, S_NULL}, // S_DOWNLINE5
|
||||
|
||||
// HOLD Bubble
|
||||
{SPR_HBUB, 0|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_HOLDBUBBLE}, // S_HOLDBUBBLE
|
||||
|
||||
// Finish line beam
|
||||
{SPR_FLBM, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_FINISHBEAM1
|
||||
{SPR_FLBM, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_NULL}, // S_FINISHBEAM2
|
||||
|
|
@ -29197,6 +29217,87 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_SOFTLANDING
|
||||
-1, // doomednum
|
||||
S_SOFTLANDING1, // 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
|
||||
0, // speed
|
||||
12*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_DOWNLINE
|
||||
-1, // doomednum
|
||||
S_DOWNLINE1, // 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
|
||||
0, // speed
|
||||
12*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_HOLDBUBBLE
|
||||
-1, // doomednum
|
||||
S_HOLDBUBBLE, // 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
|
||||
0, // speed
|
||||
12*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_PAPERITEMSPOT
|
||||
-1, // doomednum
|
||||
S_INVISIBLE, // spawnstate
|
||||
|
|
|
|||
20
src/info.h
20
src/info.h
|
|
@ -1300,6 +1300,9 @@ typedef enum sprite
|
|||
|
||||
SPR_SDDS, // Spindash dust
|
||||
SPR_SDWN, // Spindash wind
|
||||
SPR_EBRK, // Soft Landing / Ebrake aura stuff.
|
||||
SPR_HMTR, // downwards line
|
||||
SPR_HBUB, // HOLD! Bubble
|
||||
|
||||
SPR_TRCK,
|
||||
|
||||
|
|
@ -5662,6 +5665,20 @@ typedef enum state
|
|||
S_SPINDASHDUST,
|
||||
S_SPINDASHWIND,
|
||||
|
||||
S_SOFTLANDING1,
|
||||
S_SOFTLANDING2,
|
||||
S_SOFTLANDING3,
|
||||
S_SOFTLANDING4,
|
||||
S_SOFTLANDING5,
|
||||
|
||||
S_DOWNLINE1,
|
||||
S_DOWNLINE2,
|
||||
S_DOWNLINE3,
|
||||
S_DOWNLINE4,
|
||||
S_DOWNLINE5,
|
||||
|
||||
S_HOLDBUBBLE,
|
||||
|
||||
S_FINISHBEAM1,
|
||||
S_FINISHBEAM2,
|
||||
S_FINISHBEAM3,
|
||||
|
|
@ -6798,6 +6815,9 @@ typedef enum mobj_type
|
|||
|
||||
MT_SPINDASHDUST,
|
||||
MT_SPINDASHWIND,
|
||||
MT_SOFTLANDING,
|
||||
MT_DOWNLINE,
|
||||
MT_HOLDBUBBLE,
|
||||
|
||||
MT_PAPERITEMSPOT,
|
||||
|
||||
|
|
|
|||
157
src/k_kart.c
157
src/k_kart.c
|
|
@ -1592,6 +1592,10 @@ static UINT8 K_CheckOffroadCollide(mobj_t *mo)
|
|||
I_Assert(mo != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(mo));
|
||||
|
||||
// If tiregrease is active, don't
|
||||
if (mo->player && mo->player->tiregrease)
|
||||
return 0;
|
||||
|
||||
for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
if (!node->m_sector)
|
||||
|
|
@ -2773,8 +2777,8 @@ static fixed_t K_FlameShieldDashVar(INT32 val)
|
|||
INT16 K_GetSpindashChargeTime(player_t *player)
|
||||
{
|
||||
// more charge time for higher speed
|
||||
// Tails = 2s, Mighty = 3s, Fang = 4s, Metal = 4s
|
||||
return (player->kartspeed + 4) * (TICRATE/3);
|
||||
// Tails = 2s, Knuckles = 2.6s, Metal = 3.2s
|
||||
return (player->kartspeed + 8) * (TICRATE/5);
|
||||
}
|
||||
|
||||
fixed_t K_GetSpindashChargeSpeed(player_t *player)
|
||||
|
|
@ -7416,6 +7420,8 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
player->tripWireState = TRIP_NONE;
|
||||
}
|
||||
|
||||
K_KartEbrakeVisuals(player);
|
||||
}
|
||||
|
||||
void K_KartPlayerAfterThink(player_t *player)
|
||||
|
|
@ -8585,6 +8591,134 @@ INT32 K_StairJankFlip(INT32 value)
|
|||
return P_AltFlip(value, 2);
|
||||
}
|
||||
|
||||
// Ebraking visuals for mo
|
||||
// we use mo->hprev for the hold bubble. If another hprev exists for some reason, remove it.
|
||||
|
||||
void K_KartEbrakeVisuals(player_t *p)
|
||||
{
|
||||
mobj_t *wave;
|
||||
mobj_t *spdl;
|
||||
fixed_t sx, sy;
|
||||
|
||||
if (K_PlayerEBrake(p))
|
||||
{
|
||||
|
||||
if (p->ebrakefor % 20 == 0)
|
||||
{
|
||||
wave = P_SpawnMobj(p->mo->x, p->mo->y, p->mo->z, MT_SOFTLANDING);
|
||||
P_SetScale(wave, p->mo->scale);
|
||||
wave->momx = p->mo->momx;
|
||||
wave->momy = p->mo->momy;
|
||||
wave->momz = p->mo->momz;
|
||||
wave->standingslope = p->mo->standingslope;
|
||||
}
|
||||
|
||||
// sound
|
||||
if (!S_SoundPlaying(p->mo, sfx_s3kd9s))
|
||||
S_StartSound(p->mo, sfx_s3kd9s);
|
||||
|
||||
// HOLD! bubble.
|
||||
if (!p->ebrakefor)
|
||||
{
|
||||
if (p->mo->hprev && !P_MobjWasRemoved(p->mo->hprev))
|
||||
{
|
||||
// for some reason, there's already an hprev. Remove it.
|
||||
P_RemoveMobj(p->mo->hprev);
|
||||
}
|
||||
|
||||
p->mo->hprev = P_SpawnMobj(p->mo->x, p->mo->y, p->mo->z, MT_HOLDBUBBLE);
|
||||
p->mo->hprev->renderflags |= (RF_DONTDRAW & ~K_GetPlayerDontDrawFlag(p));
|
||||
}
|
||||
|
||||
// Update HOLD bubble.
|
||||
if (p->mo->hprev && !P_MobjWasRemoved(p->mo->hprev))
|
||||
{
|
||||
P_MoveOrigin(p->mo->hprev, p->mo->x, p->mo->y, p->mo->z);
|
||||
p->mo->hprev->angle = p->mo->angle;
|
||||
p->mo->hprev->fuse = TICRATE/2; // When we leave spindash for any reason, make sure this bubble goes away soon after.
|
||||
K_FlipFromObject(p->mo->hprev, p->mo);
|
||||
}
|
||||
|
||||
|
||||
if (!p->spindash)
|
||||
{
|
||||
// Spawn downwards fastline
|
||||
sx = p->mo->x + P_RandomRange(-48, 48)*p->mo->scale;
|
||||
sy = p->mo->y + P_RandomRange(-48, 48)*p->mo->scale;
|
||||
|
||||
spdl = P_SpawnMobj(sx, sy, p->mo->z, MT_DOWNLINE);
|
||||
spdl->colorized = true;
|
||||
spdl->color = SKINCOLOR_WHITE;
|
||||
K_MatchGenericExtraFlags(spdl, p->mo);
|
||||
P_SetScale(spdl, p->mo->scale);
|
||||
|
||||
// squish the player a little bit.
|
||||
p->mo->spritexscale = FRACUNIT*115/100;
|
||||
p->mo->spriteyscale = FRACUNIT*85/100;
|
||||
}
|
||||
else
|
||||
{
|
||||
const UINT16 MAXCHARGETIME = K_GetSpindashChargeTime(p);
|
||||
const fixed_t MAXSHAKE = FRACUNIT;
|
||||
|
||||
// update HOLD bubble with numbers based on charge.
|
||||
if (p->mo->hprev && !P_MobjWasRemoved(p->mo->hprev))
|
||||
{
|
||||
UINT8 frame = min(1 + ((p->spindash*3) / MAXCHARGETIME), 4);
|
||||
|
||||
// ?! limit.
|
||||
if (p->spindash >= MAXCHARGETIME +TICRATE)
|
||||
frame = 5;
|
||||
|
||||
p->mo->hprev->frame = frame|FF_FULLBRIGHT;
|
||||
}
|
||||
|
||||
// shake the player as they charge their spindash!
|
||||
|
||||
// "gentle" shaking as we start...
|
||||
if (p->spindash < MAXCHARGETIME)
|
||||
{
|
||||
fixed_t shake = FixedMul(((p->spindash)*FRACUNIT/MAXCHARGETIME), MAXSHAKE);
|
||||
SINT8 mult = leveltime & 1 ? 1 : -1;
|
||||
|
||||
p->mo->spritexoffset = shake*mult;
|
||||
}
|
||||
else // get VIOLENT on overcharge :)
|
||||
{
|
||||
fixed_t shake = MAXSHAKE + FixedMul(((p->spindash-MAXCHARGETIME)*FRACUNIT/TICRATE), MAXSHAKE)*3;
|
||||
SINT8 mult = leveltime & 1 ? 1 : -1;
|
||||
|
||||
p->mo->spritexoffset = shake*mult;
|
||||
}
|
||||
|
||||
// sqish them a little MORE....
|
||||
p->mo->spritexscale = FRACUNIT*12/10;
|
||||
p->mo->spriteyscale = FRACUNIT*8/10;
|
||||
}
|
||||
|
||||
|
||||
p->ebrakefor++;
|
||||
}
|
||||
else if (p->ebrakefor) // cancel effects
|
||||
{
|
||||
// reset scale
|
||||
p->mo->spritexscale = FRACUNIT;
|
||||
p->mo->spriteyscale = FRACUNIT;
|
||||
|
||||
// reset shake
|
||||
p->mo->spritexoffset = 0;
|
||||
|
||||
// remove the bubble instantly unless it's in the !? state
|
||||
if (p->mo->hprev && !P_MobjWasRemoved(p->mo->hprev) && (p->mo->hprev->frame & FF_FRAMEMASK) != 5)
|
||||
{
|
||||
P_RemoveMobj(p->mo->hprev);
|
||||
p->mo->hprev = NULL;
|
||||
}
|
||||
|
||||
p->ebrakefor = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void K_KartSpindashDust(mobj_t *parent)
|
||||
{
|
||||
fixed_t rad = FixedDiv(FixedHypot(parent->radius, parent->radius), parent->scale);
|
||||
|
|
@ -8641,6 +8775,9 @@ static void K_KartSpindashWind(mobj_t *parent)
|
|||
K_MatchGenericExtraFlags(wind, parent);
|
||||
}
|
||||
|
||||
// Time after which you get a thrust for releasing spindash
|
||||
#define SPINDASHTHRUSTTIME 20
|
||||
|
||||
static void K_KartSpindash(player_t *player)
|
||||
{
|
||||
const INT16 MAXCHARGETIME = K_GetSpindashChargeTime(player);
|
||||
|
|
@ -8652,11 +8789,18 @@ static void K_KartSpindash(player_t *player)
|
|||
player->spindash = 0;
|
||||
}
|
||||
|
||||
if (player->spindash > 0 && (cmd->buttons & (BT_DRIFT|BT_BRAKE)) != (BT_DRIFT|BT_BRAKE))
|
||||
if (player->spindash > 0 && (cmd->buttons & (BT_DRIFT|BT_BRAKE|BT_ACCELERATE)) != (BT_DRIFT|BT_BRAKE|BT_ACCELERATE))
|
||||
{
|
||||
player->spindashspeed = (player->spindash * FRACUNIT) / MAXCHARGETIME;
|
||||
player->spindashboost = TICRATE;
|
||||
|
||||
// if spindash was charged enough, give a small thrust.
|
||||
if (player->spindash >= SPINDASHTHRUSTTIME)
|
||||
{
|
||||
// Give a bit of a boost depending on charge.
|
||||
P_InstaThrust(player->mo, player->mo->angle, FixedMul(player->mo->scale, player->spindash*FRACUNIT/5));
|
||||
}
|
||||
|
||||
if (!player->tiregrease)
|
||||
{
|
||||
UINT8 i;
|
||||
|
|
@ -8703,10 +8847,11 @@ static void K_KartSpindash(player_t *player)
|
|||
{
|
||||
if ((cmd->buttons & (BT_DRIFT|BT_BRAKE)) == (BT_DRIFT|BT_BRAKE))
|
||||
{
|
||||
UINT8 ringdropframes = 2 + (player->kartspeed + player->kartweight);
|
||||
INT16 chargetime = MAXCHARGETIME - ++player->spindash;
|
||||
boolean spawnOldEffect = true;
|
||||
|
||||
if (chargetime <= (MAXCHARGETIME / 2))
|
||||
if (player->spindash >= SPINDASHTHRUSTTIME)
|
||||
{
|
||||
K_KartSpindashDust(player->mo);
|
||||
spawnOldEffect = false;
|
||||
|
|
@ -8717,7 +8862,7 @@ static void K_KartSpindash(player_t *player)
|
|||
K_KartSpindashWind(player->mo);
|
||||
}
|
||||
|
||||
if (player->flashing > 0 && (leveltime & 1) && player->hyudorotimer == 0)
|
||||
if (player->flashing > 0 && (player->spindash % ringdropframes == 0) && player->hyudorotimer == 0)
|
||||
{
|
||||
// Every frame that you're invisible from flashing, spill a ring.
|
||||
// Intentionally a lop-sided trade-off, so the game doesn't become
|
||||
|
|
@ -8753,6 +8898,8 @@ static void K_KartSpindash(player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
#undef SPINDASHTHRUSTTIME
|
||||
|
||||
static void K_AirFailsafe(player_t *player)
|
||||
{
|
||||
const fixed_t maxSpeed = 6*player->mo->scale;
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ void K_CheckSpectateStatus(void);
|
|||
UINT8 K_GetInvincibilityItemFrame(void);
|
||||
UINT8 K_GetOrbinautItemFrame(UINT8 count);
|
||||
boolean K_IsSPBInGame(void);
|
||||
void K_KartEbrakeVisuals(player_t *p);
|
||||
|
||||
// sound stuff for lua
|
||||
void K_PlayAttackTaunt(mobj_t *source);
|
||||
|
|
|
|||
10
src/p_mobj.c
10
src/p_mobj.c
|
|
@ -9590,6 +9590,16 @@ void P_SceneryThinker(mobj_t *mobj)
|
|||
|
||||
P_CycleMobjState(mobj);
|
||||
|
||||
// Flicker softlanding mobj, this just prevents us from needing like 20 states.
|
||||
if (mobj->type == MT_SOFTLANDING)
|
||||
{
|
||||
mobj->renderflags |= RF_NOSPLATBILLBOARD|RF_OBJECTSLOPESPLAT;
|
||||
if (mobj->tics & 1)
|
||||
mobj->renderflags |= RF_DONTDRAW;
|
||||
else
|
||||
mobj->renderflags &= ~RF_DONTDRAW;
|
||||
}
|
||||
|
||||
if (mobj->type != MT_RANDOMAUDIENCE)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -326,6 +326,8 @@ static void P_NetArchivePlayers(void)
|
|||
WRITEUINT8(save_p, players[i].trickboostdecay);
|
||||
WRITEUINT8(save_p, players[i].trickboost);
|
||||
|
||||
WRITEUINT32(save_p, players[i].ebrakefor);
|
||||
|
||||
WRITEUINT32(save_p, players[i].roundscore);
|
||||
WRITEUINT8(save_p, players[i].emeralds);
|
||||
WRITEUINT8(save_p, players[i].bumpers);
|
||||
|
|
@ -592,6 +594,8 @@ static void P_NetUnArchivePlayers(void)
|
|||
players[i].trickboostdecay = READUINT8(save_p);
|
||||
players[i].trickboost = READUINT8(save_p);
|
||||
|
||||
players[i].ebrakefor = READUINT32(save_p);
|
||||
|
||||
players[i].roundscore = READUINT32(save_p);
|
||||
players[i].emeralds = READUINT8(save_p);
|
||||
players[i].bumpers = READUINT8(save_p);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue