mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'lightning-attack' into 'master'
Lightning attack See merge request kart-krew-dev/ring-racers-internal!2691
This commit is contained in:
commit
f8c5764276
11 changed files with 188 additions and 15 deletions
|
|
@ -833,6 +833,7 @@ struct player_t
|
|||
UINT16 flamedash; // Flame Shield dash power
|
||||
UINT16 flamemeter; // Flame Shield dash meter left
|
||||
UINT8 flamelength; // Flame Shield dash meter, number of segments
|
||||
UINT8 lightningcharge; // Lightning Shield attack timer
|
||||
|
||||
UINT16 counterdash; // Flame Shield boost without the flame, largely. Used in places where awarding thrust would affect player control.
|
||||
|
||||
|
|
|
|||
|
|
@ -2011,6 +2011,12 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
|
|||
"S_THNC2",
|
||||
"S_THNB1",
|
||||
|
||||
"S_THND",
|
||||
"S_THNE",
|
||||
"S_THNH",
|
||||
"S_THNF",
|
||||
"S_THNG",
|
||||
|
||||
// Bubble Shield
|
||||
"S_BUBBLESHIELD1",
|
||||
"S_BUBBLESHIELD2",
|
||||
|
|
@ -3664,6 +3670,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
|
|||
|
||||
"MT_LIGHTNINGSHIELD", // Shields
|
||||
"MT_LIGHTNINGSHIELD_VISUAL",
|
||||
"MT_LIGHTNINGATTACK_VISUAL",
|
||||
"MT_BUBBLESHIELD",
|
||||
"MT_BUBBLESHIELD_VISUAL",
|
||||
"MT_FLAMESHIELD",
|
||||
|
|
|
|||
38
src/info.c
38
src/info.c
|
|
@ -388,6 +388,11 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"THNC", // Lightning Shield Top Flash
|
||||
"THNA", // Lightning Shield Top Swoosh
|
||||
"THNB", // Lightning Shield Bottom Swoosh
|
||||
"THND", // Lightning attack
|
||||
"THNE", // Lightning attack
|
||||
"THNH", // Lightning attack
|
||||
"THNF", // Lightning attack
|
||||
"THNG", // Lightning attack
|
||||
"BUBS", // Bubble Shield (not Bubs)
|
||||
"BUBT", // Bubble Shield trap
|
||||
"BUBA", // Bubble Shield Outline
|
||||
|
|
@ -2580,6 +2585,12 @@ state_t states[NUMSTATES] =
|
|||
{SPR_THNC, FF_ADD|FF_FULLBRIGHT|FF_ANIMATE, 11, {NULL}, 10, 1, S_THNB1}, // S_THNC2
|
||||
{SPR_THNB, FF_ADD|FF_FULLBRIGHT|FF_ANIMATE, 43, {NULL}, 42, 1, S_THNC1}, // S_THNB1
|
||||
|
||||
{SPR_THND, FF_ADD|FF_FULLBRIGHT|FF_ANIMATE, -1, {NULL}, 10, 1, S_THND}, // S_THND
|
||||
{SPR_THNE, FF_FULLBRIGHT|FF_ANIMATE, 34, {NULL}, 33, 1, S_THNH}, // S_THNE
|
||||
{SPR_NULL, FF_FULLBRIGHT, 34, {NULL}, 33, 1, S_THNE}, // S_THNH
|
||||
{SPR_THNF, FF_FULLBRIGHT|FF_ANIMATE, 4, {NULL}, 3, 1, S_THNG}, // S_THNF
|
||||
{SPR_THNG, FF_FULLBRIGHT|FF_ANIMATE, 64, {NULL}, 63, 1, S_THNF}, // S_THNG
|
||||
|
||||
{SPR_BUBS, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_BUBBLESHIELD2}, // S_BUBBLESHIELD1
|
||||
{SPR_BUBS, FF_FULLBRIGHT|13, 2, {NULL}, 0, 0, S_BUBBLESHIELD3}, // S_BUBBLESHIELD2
|
||||
{SPR_BUBS, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_BUBBLESHIELD4}, // S_BUBBLESHIELD3
|
||||
|
|
@ -15603,6 +15614,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_LIGHTNINGATTACK_VISUAL
|
||||
-1, // doomednum
|
||||
S_THND, // 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_BUBBLESHIELD
|
||||
-1, // doomednum
|
||||
S_BUBBLESHIELD1, // spawnstate
|
||||
|
|
|
|||
12
src/info.h
12
src/info.h
|
|
@ -929,6 +929,11 @@ typedef enum sprite
|
|||
SPR_THNC, // Lightning Shield Top Flash
|
||||
SPR_THNA, // Lightning Shield Top Swoosh
|
||||
SPR_THNB, // Lightning Shield Bottom Swoosh
|
||||
SPR_THND, // Lightning Attack
|
||||
SPR_THNE, // Lightning Attack
|
||||
SPR_THNH, // Lightning Attack
|
||||
SPR_THNF, // Lightning Attack
|
||||
SPR_THNG, // Lightning Attack
|
||||
SPR_BUBS, // Bubble Shield (not Bubs)
|
||||
SPR_BUBT, // Bubble Shield trap
|
||||
SPR_BUBA, // Bubble Shield Outline
|
||||
|
|
@ -3073,6 +3078,12 @@ typedef enum state
|
|||
S_THNC2,
|
||||
S_THNB1,
|
||||
|
||||
S_THND,
|
||||
S_THNE,
|
||||
S_THNH,
|
||||
S_THNF,
|
||||
S_THNG,
|
||||
|
||||
// Bubble Shield
|
||||
S_BUBBLESHIELD1,
|
||||
S_BUBBLESHIELD2,
|
||||
|
|
@ -4753,6 +4764,7 @@ typedef enum mobj_type
|
|||
|
||||
MT_LIGHTNINGSHIELD, // Shields
|
||||
MT_LIGHTNINGSHIELD_VISUAL,
|
||||
MT_LIGHTNINGATTACK_VISUAL,
|
||||
MT_BUBBLESHIELD,
|
||||
MT_BUBBLESHIELD_VISUAL,
|
||||
MT_FLAMESHIELD,
|
||||
|
|
|
|||
77
src/k_kart.c
77
src/k_kart.c
|
|
@ -1488,6 +1488,9 @@ static boolean K_HasInfiniteTether(player_t *player)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (player->lightningcharge)
|
||||
return true;
|
||||
|
||||
if (player->eggmanexplode > 0)
|
||||
return true;
|
||||
|
||||
|
|
@ -1618,7 +1621,7 @@ static boolean K_TryDraft(player_t *player, mobj_t *dest, fixed_t minDist, fixed
|
|||
player->draftpower -= 3*add/4;
|
||||
}
|
||||
|
||||
if (gametyperules & GTR_CLOSERPLAYERS)
|
||||
if (gametyperules & GTR_CLOSERPLAYERS || player->curshield == KSHIELD_LIGHTNING || player->lightningcharge)
|
||||
{
|
||||
// Double speed in smaller environments
|
||||
player->draftpower += add;
|
||||
|
|
@ -10713,6 +10716,45 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
K_FlameDashLeftoverSmoke(player->mo);
|
||||
}
|
||||
|
||||
if (player->curshield != KSHIELD_LIGHTNING)
|
||||
{
|
||||
player->lightningcharge = 0;
|
||||
}
|
||||
|
||||
if (player->lightningcharge)
|
||||
{
|
||||
player->lightningcharge++;
|
||||
|
||||
/*
|
||||
if (onground)
|
||||
P_Thrust(player->mo, player->mo->angle, player->mo->scale);
|
||||
*/
|
||||
|
||||
if (player->lightningcharge == LIGHTNING_CHARGE)
|
||||
{
|
||||
K_DoLightningShield(player);
|
||||
P_Thrust(player->mo, onground ? player->mo->angle : K_MomentumAngle(player->mo), 100*player->mo->scale);
|
||||
// player->tiregrease = TICRATE/4;
|
||||
player->lightningcharge = 0;
|
||||
|
||||
if (player->itemamount > 0)
|
||||
{
|
||||
// Why is this a conditional?
|
||||
// Lightning shield: the only item that allows you to
|
||||
// activate a mine while you're out of its radius,
|
||||
// the SAME tic it sets your itemamount to 0
|
||||
// ...:dumbestass:
|
||||
player->itemamount--;
|
||||
K_PlayAttackTaunt(player->mo);
|
||||
player->botvars.itemconfirm = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
S_StopSoundByID(player->mo, LIGHTNING_SOUND);
|
||||
}
|
||||
|
||||
if (P_IsObjectOnGround(player->mo) && player->trickpanel != TRICKSTATE_NONE)
|
||||
{
|
||||
if (P_MobjFlip(player->mo) * player->mo->momz <= 0)
|
||||
|
|
@ -14745,20 +14787,27 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
|||
Obj_SpawnLightningShieldVisuals(shield);
|
||||
}
|
||||
|
||||
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO)
|
||||
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO && !player->lightningcharge)
|
||||
{
|
||||
K_DoLightningShield(player);
|
||||
if (player->itemamount > 0)
|
||||
{
|
||||
// Why is this a conditional?
|
||||
// Lightning shield: the only item that allows you to
|
||||
// activate a mine while you're out of its radius,
|
||||
// the SAME tic it sets your itemamount to 0
|
||||
// ...:dumbestass:
|
||||
player->itemamount--;
|
||||
K_PlayAttackTaunt(player->mo);
|
||||
player->botvars.itemconfirm = 0;
|
||||
}
|
||||
// K_DoLightningShield(player);
|
||||
player->lightningcharge = 1;
|
||||
|
||||
mobj_t *at1 = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_LIGHTNINGATTACK_VISUAL);
|
||||
mobj_t *at2 = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_LIGHTNINGATTACK_VISUAL);
|
||||
mobj_t *at3 = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_LIGHTNINGATTACK_VISUAL);
|
||||
|
||||
P_SetMobjState(at1, S_THNG);
|
||||
P_SetMobjState(at2, S_THND);
|
||||
P_SetMobjState(at3, S_THNH);
|
||||
|
||||
at2->dispoffset = 2;
|
||||
at3->dispoffset = -1;
|
||||
|
||||
P_SetTarget(&at1->target, player->mo);
|
||||
P_SetTarget(&at2->target, player->mo);
|
||||
P_SetTarget(&at3->target, player->mo);
|
||||
|
||||
S_StartSound(player->mo, LIGHTNING_SOUND);
|
||||
}
|
||||
break;
|
||||
case KITEM_GARDENTOP:
|
||||
|
|
|
|||
|
|
@ -59,6 +59,9 @@ Make sure this matches the actual number of states
|
|||
|
||||
#define TIMEATTACK_START (TICRATE*10)
|
||||
|
||||
#define LIGHTNING_CHARGE (TICRATE*2)
|
||||
#define LIGHTNING_SOUND (sfx_s3k84)
|
||||
|
||||
#define OVERDRIVE_STARTUP (0)
|
||||
|
||||
#define AMPLEVEL (15)
|
||||
|
|
|
|||
|
|
@ -464,6 +464,10 @@ boolean Obj_TickBubbleShieldVisual(mobj_t *mobj);
|
|||
void Obj_SpawnLightningShieldVisuals(mobj_t *source);
|
||||
boolean Obj_TickLightningShieldVisual(mobj_t *mobj);
|
||||
|
||||
/* Lightning Attack */
|
||||
void Obj_SpawnLightningAttackVisuals(mobj_t *source);
|
||||
boolean Obj_TickLightningAttackVisual(mobj_t *mobj);
|
||||
|
||||
/* Flame Shield */
|
||||
void Obj_SpawnFlameShieldVisuals(mobj_t *source);
|
||||
boolean Obj_TickFlameShieldVisual(mobj_t *mobj);
|
||||
|
|
|
|||
|
|
@ -494,6 +494,8 @@ static int player_get(lua_State *L)
|
|||
lua_pushinteger(L, plr->flamemeter);
|
||||
else if (fastcmp(field,"flamelength"))
|
||||
lua_pushinteger(L, plr->flamelength);
|
||||
else if (fastcmp(field,"lightningcharge"))
|
||||
lua_pushinteger(L, plr->lightningcharge);
|
||||
else if (fastcmp(field,"ballhogcharge"))
|
||||
lua_pushinteger(L, plr->ballhogcharge);
|
||||
else if (fastcmp(field,"ballhogtap"))
|
||||
|
|
@ -1133,6 +1135,8 @@ static int player_set(lua_State *L)
|
|||
plr->flamemeter = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"flamelength"))
|
||||
plr->flamelength = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"lightningcharge"))
|
||||
plr->lightningcharge = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"ballhogcharge"))
|
||||
plr->ballhogcharge = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"ballhogtap"))
|
||||
|
|
|
|||
53
src/p_mobj.c
53
src/p_mobj.c
|
|
@ -6721,6 +6721,59 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case MT_LIGHTNINGATTACK_VISUAL:
|
||||
{
|
||||
if (!(mobj->target && !P_MobjWasRemoved(mobj->target)))
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mobj->target->player || !mobj->target->player->lightningcharge)
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
}
|
||||
|
||||
UINT8 SHRINK = 5;
|
||||
|
||||
UINT8 timer = (LIGHTNING_CHARGE - mobj->target->player->lightningcharge);
|
||||
UINT8 target = timer/10 + 1;
|
||||
|
||||
fixed_t myscale = (5*mobj->target->scale)>>2;
|
||||
if (timer <= SHRINK)
|
||||
{
|
||||
myscale = Easing_InSine(FRACUNIT*(SHRINK - timer)/SHRINK, myscale, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT8 pretimer = LIGHTNING_CHARGE - SHRINK;
|
||||
fixed_t scalefactor = FRACUNIT * (timer - SHRINK) / pretimer;
|
||||
myscale = Easing_Linear(scalefactor, 5*myscale/4, myscale);
|
||||
}
|
||||
|
||||
P_SetScale(mobj, (mobj->destscale = myscale));
|
||||
|
||||
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z + mobj->target->height/2);
|
||||
// Taken from K_FlipFromObject. We just want to flip the visual according to its target, but that's it.
|
||||
mobj->eflags = (mobj->eflags & ~MFE_VERTICALFLIP)|(mobj->target->eflags & MFE_VERTICALFLIP);
|
||||
|
||||
mobj->extravalue1++;
|
||||
|
||||
if (mobj->extravalue1 > target)
|
||||
{
|
||||
mobj->color = SKINCOLOR_WHITE;
|
||||
mobj->colorized = true;
|
||||
mobj->extravalue1 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj->colorized = false;
|
||||
mobj->renderflags &= ~RF_DONTDRAW;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MT_FLAMESHIELD_VISUAL:
|
||||
{
|
||||
if (!Obj_TickFlameShieldVisual(mobj))
|
||||
|
|
|
|||
|
|
@ -560,6 +560,7 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
|||
WRITEUINT16(save->p, players[i].counterdash);
|
||||
WRITEUINT16(save->p, players[i].flamemeter);
|
||||
WRITEUINT8(save->p, players[i].flamelength);
|
||||
WRITEUINT8(save->p, players[i].lightningcharge);
|
||||
|
||||
WRITEUINT16(save->p, players[i].ballhogcharge);
|
||||
WRITEUINT8(save->p, players[i].ballhogtap);
|
||||
|
|
@ -1225,6 +1226,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
|||
players[i].counterdash = READUINT16(save->p);
|
||||
players[i].flamemeter = READUINT16(save->p);
|
||||
players[i].flamelength = READUINT8(save->p);
|
||||
players[i].lightningcharge = READUINT8(save->p);
|
||||
|
||||
players[i].ballhogcharge = READUINT16(save->p);
|
||||
players[i].ballhogtap = READUINT8(save->p);
|
||||
|
|
|
|||
|
|
@ -534,7 +534,7 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"s3k81", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Burst"},
|
||||
{"s3k82", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Burst"},
|
||||
{"s3k83", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Collapsing"},
|
||||
{"s3k84", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powering up"},
|
||||
{"s3k84", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Powering up"}, // Lightning Shield Charge
|
||||
{"s3k85", false, 64, 24, -1, NULL, 0, -1, -1, LUMPERROR, "Powering down"},
|
||||
{"s3k86", false, 128, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Alarm"},
|
||||
{"s3k87", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bounce"},
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue