The Lightning Update

- 30 sec cooldown on all lightning types
- Delay before Blue Lightning hits, based off of distance
- Blue Lightning can swap targets if 1st place is passed
- Blue Lightning can only be handed out if 2nd is far away enough from first
This commit is contained in:
TehRealSalt 2018-06-05 21:36:48 -04:00
parent 8de3890f26
commit 5f610982ea
7 changed files with 399 additions and 234 deletions

View File

@ -279,6 +279,7 @@ typedef enum
k_spinouttimer, // Spin-out from a banana peel or oil slick (was "pw_bananacam")
k_laserwisptimer, // The duration and relative angle of the laser
k_justbumped, // Prevent players from endlessly bumping into each other
k_deathsentence, // 30 seconds to live... (Blue Shell murder timer (not actually 30 sec, I just couldn't help the FF reference :p))
k_poweritemtimer, // Battle mode, how long before you're allowed another power item (Star, Megashroom)
k_comebacktimer, // Battle mode, how long before you become a bomb after death

View File

@ -7584,6 +7584,7 @@ static const char *const KARTSTUFF_LIST[] = {
"SPINOUTTIMER",
"LASERWISPTIMER",
"JUSTBUMPED",
"DEATHSENTENCE",
"POWERITEMTIMER",
"COMEBACKTIMER",

View File

@ -445,6 +445,10 @@ extern boolean franticitems;
extern boolean mirrormode;
extern boolean comeback;
extern tic_t lightningcooldown;
extern tic_t blueshellincoming;
extern UINT8 blueshellplayer;
extern boolean legitimateexit;
extern boolean comebackshowninfo;
extern tic_t curlap, bestlap;

View File

@ -252,6 +252,11 @@ INT16 votelevels[4]; // Levels that were rolled by the host
SINT8 votes[MAXPLAYERS]; // Each player's vote
SINT8 pickedvote; // What vote the host rolls
// Server-sided variables
tic_t lightningcooldown; // Cooldown before any more lightning/blue shell is awarded
tic_t blueshellincoming; // Timer before blue shell hits, can switch targets at this point
UINT8 blueshellplayer; // Player num that used the last blue shell
// Client-sided variables (NEVER use in anything that needs to be synced with other players)
boolean legitimateexit; // Did this client actually finish the match?
boolean comebackshowninfo; // Have you already seen the "ATTACK OR PROTECT" message?

View File

@ -25,6 +25,9 @@
// franticitems is Frantic Mode items, bool
// mirrormode is Mirror Mode (duh), bool
// comeback is Battle Mode's karma comeback, also bool
// lightningcooldown is timer before anyone's allowed another lightning/blue shell
// blueshellincoming is the timer before k_deathsentence is cast on the player in 1st
// blueshellplayer is the last player who fired one
//{ SRB2kart Color Code
@ -473,6 +476,7 @@ static void K_KartGetItemResult(player_t *player, fixed_t getitem, boolean retro
player->kartstuff[k_blueshell] = 1;
else
player->kartstuff[k_bobomb] |= 2;
lightningcooldown = 30*TICRATE;
break;
case 16: // Fire Flower - or - Deton (Blue Shell)
if (retrokart)
@ -488,6 +492,7 @@ static void K_KartGetItemResult(player_t *player, fixed_t getitem, boolean retro
break;
case 18: // Lightning
player->kartstuff[k_lightning] = 1;
lightningcooldown = 30*TICRATE;
break;
case 19: // Feather
player->kartstuff[k_feather] |= 1;
@ -537,6 +542,7 @@ static void K_KartItemRouletteByDistance(player_t *player, ticcmd_t *cmd)
INT32 chance = 0, numchoices = 0;
INT32 distvar = (64*14);
INT32 avgballoon = 0;
INT32 secondist = 0;
// This makes the roulette cycle through items - if this is 0, you shouldn't be here.
if (player->kartstuff[k_itemroulette])
@ -567,8 +573,9 @@ static void K_KartItemRouletteByDistance(player_t *player, ticcmd_t *cmd)
// Gotta check how many players are active at this moment.
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && !players[i].spectator)
pingame++;
if (!playeringame[i] || players[i].spectator)
continue;
pingame++;
if (players[i].exiting)
pexiting++;
if (players[i].kartstuff[k_balloon] > 0)
@ -580,13 +587,29 @@ static void K_KartItemRouletteByDistance(player_t *player, ticcmd_t *cmd)
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && !players[i].spectator && players[i].mo
&& players[i].kartstuff[k_position] < player->kartstuff[k_position])
pdis += P_AproxDistance(P_AproxDistance(players[i].mo->x - player->mo->x,
players[i].mo->y - player->mo->y),
players[i].mo->z - player->mo->z) / mapheaderinfo[gamemap-1]->mobj_scale
* (pingame - players[i].kartstuff[k_position])
/ ((pingame - 1) * (pingame + 1) / 3);
SINT8 first = -1;
SINT8 second = -1;
if (playeringame[i] && !players[i].spectator && players[i].mo)
{
if (players[i].kartstuff[k_position] < player->kartstuff[k_position])
pdis += P_AproxDistance(P_AproxDistance(players[i].mo->x - player->mo->x,
players[i].mo->y - player->mo->y),
players[i].mo->z - player->mo->z) / mapheaderinfo[gamemap-1]->mobj_scale
* (pingame - players[i].kartstuff[k_position])
/ ((pingame - 1) * (pingame + 1) / 3);
if (players[i].kartstuff[k_position] == 1 && first == -1)
first = i;
if (players[i].kartstuff[k_position] == 2 && second == -1)
second = i;
}
if (first != -1 && second != -1 && !secondist) // calculate 2nd's distance from 1st, for blue shell
secondist = P_AproxDistance(P_AproxDistance(players[first].mo->x - players[second].mo->x,
players[first].mo->y - players[second].mo->y),
players[first].mo->z - players[second].mo->z) / mapheaderinfo[gamemap-1]->mobj_scale
* (pingame - 1)
/ ((pingame - 1) * (pingame + 1) / 3);
}
player->kartstuff[k_itemclose] = 0; // Reset the item window closer.
@ -626,25 +649,26 @@ static void K_KartItemRouletteByDistance(player_t *player, ticcmd_t *cmd)
// Check the game type to differentiate odds.
//if (gametype == GT_RETRO)
//{
if (cv_magnet.value) SETITEMRESULT(useodds, 1); // Magnet
if (cv_boo.value) SETITEMRESULT(useodds, 2); // Boo
if (cv_mushroom.value || modeattacking) SETITEMRESULT(useodds, 3); // Mushroom
if (cv_triplemushroom.value) SETITEMRESULT(useodds, 4); // Triple Mushroom
if (cv_megashroom.value && !player->kartstuff[k_poweritemtimer]) SETITEMRESULT(useodds, 5); // Mega Mushroom
if (cv_goldshroom.value) SETITEMRESULT(useodds, 6); // Gold Mushroom
if (cv_star.value && !player->kartstuff[k_poweritemtimer]) SETITEMRESULT(useodds, 7); // Star
if (cv_triplebanana.value) SETITEMRESULT(useodds, 8); // Triple Banana
if (cv_fakeitem.value) SETITEMRESULT(useodds, 9); // Fake Item
if (cv_banana.value) SETITEMRESULT(useodds, 10); // Banana
if (cv_greenshell.value) SETITEMRESULT(useodds, 11); // Green Shell
if (cv_redshell.value) SETITEMRESULT(useodds, 12); // Red Shell
if (cv_triplegreenshell.value) SETITEMRESULT(useodds, 13); // Triple Green Shell
if (cv_bobomb.value) SETITEMRESULT(useodds, 14); // Bob-omb
if (cv_blueshell.value && pexiting == 0) SETITEMRESULT(useodds, 15); // Blue Shell
if (cv_fireflower.value) SETITEMRESULT(useodds, 16); // Fire Flower
if (cv_tripleredshell.value && pingame > 2) SETITEMRESULT(useodds, 17); // Triple Red Shell
if (cv_lightning.value && pingame > pexiting) SETITEMRESULT(useodds, 18); // Lightning
if (cv_feather.value) SETITEMRESULT(useodds, 19); // Feather
if (cv_magnet.value) SETITEMRESULT(useodds, 1); // Magnet
if (cv_boo.value) SETITEMRESULT(useodds, 2); // Boo
if (cv_mushroom.value || modeattacking) SETITEMRESULT(useodds, 3); // Mushroom
if (cv_triplemushroom.value) SETITEMRESULT(useodds, 4); // Triple Mushroom
if (cv_megashroom.value && !player->kartstuff[k_poweritemtimer]) SETITEMRESULT(useodds, 5); // Mega Mushroom
if (cv_goldshroom.value) SETITEMRESULT(useodds, 6); // Gold Mushroom
if (cv_star.value && !player->kartstuff[k_poweritemtimer]) SETITEMRESULT(useodds, 7); // Star
if (cv_triplebanana.value) SETITEMRESULT(useodds, 8); // Triple Banana
if (cv_fakeitem.value) SETITEMRESULT(useodds, 9); // Fake Item
if (cv_banana.value) SETITEMRESULT(useodds, 10); // Banana
if (cv_greenshell.value) SETITEMRESULT(useodds, 11); // Green Shell
if (cv_redshell.value) SETITEMRESULT(useodds, 12); // Red Shell
if (cv_triplegreenshell.value) SETITEMRESULT(useodds, 13); // Triple Green Shell
if (cv_bobomb.value) SETITEMRESULT(useodds, 14); // Bob-omb
if (cv_blueshell.value && pexiting == 0
&& !lightningcooldown && secondist > distvar*6) SETITEMRESULT(useodds, 15); // Blue Shell
if (cv_fireflower.value) SETITEMRESULT(useodds, 16); // Fire Flower
if (cv_tripleredshell.value && pingame > 2) SETITEMRESULT(useodds, 17); // Triple Red Shell
if (cv_lightning.value && pingame > pexiting && !lightningcooldown) SETITEMRESULT(useodds, 18); // Lightning
if (cv_feather.value) SETITEMRESULT(useodds, 19); // Feather
prandom = P_RandomKey(numchoices);
@ -988,206 +1012,6 @@ void K_KartMoveAnimation(player_t *player)
}
}
/** \brief Decreases various kart timers and powers per frame. Called in P_PlayerThink in p_user.c
\param player player object passed from P_PlayerThink
\param cmd control input from player
\return void
*/
void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
{
K_UpdateOffroad(player);
// setting players to use the star colormap and spawning afterimages
if (player->kartstuff[k_startimer])
{
mobj_t *ghost;
player->mo->colorized = true;
ghost = P_SpawnGhostMobj(player->mo);
ghost->fuse = 4;
ghost->frame |= FF_FULLBRIGHT;
}
else
{
player->mo->colorized = false;
}
if (player->kartstuff[k_itemclose])
player->kartstuff[k_itemclose]--;
if (player->kartstuff[k_spinout])
player->kartstuff[k_spinout]--;
if (player->kartstuff[k_spinouttimer])
player->kartstuff[k_spinouttimer]--;
else if (!comeback)
player->kartstuff[k_comebacktimer] = comebacktime;
else if (player->kartstuff[k_comebacktimer])
{
player->kartstuff[k_comebacktimer]--;
if (player == &players[consoleplayer] && player->kartstuff[k_balloon] <= 0 && player->kartstuff[k_comebacktimer] <= 0)
comebackshowninfo = true; // client has already seen the message
}
if (player->kartstuff[k_spinout] == 0 && player->kartstuff[k_spinouttimer] == 0 && player->powers[pw_flashing] == K_GetKartFlashing())
player->powers[pw_flashing]--;
if (player->kartstuff[k_magnettimer])
player->kartstuff[k_magnettimer]--;
if (player->kartstuff[k_mushroomtimer])
player->kartstuff[k_mushroomtimer]--;
if (player->kartstuff[k_floorboost])
player->kartstuff[k_floorboost]--;
if (player->kartstuff[k_driftboost])
player->kartstuff[k_driftboost]--;
if (player->kartstuff[k_startimer])
player->kartstuff[k_startimer]--;
if (player->kartstuff[k_growshrinktimer] > 0)
player->kartstuff[k_growshrinktimer]--;
if (player->kartstuff[k_growshrinktimer] < 0)
player->kartstuff[k_growshrinktimer]++;
if (player->kartstuff[k_growshrinktimer] == 1 || player->kartstuff[k_growshrinktimer] == -1)
{
player->mo->destscale = mapheaderinfo[gamemap-1]->mobj_scale;
P_RestoreMusic(player);
}
if (player->kartstuff[k_bootaketimer] == 0 && player->kartstuff[k_boostolentimer] == 0
&& player->kartstuff[k_goldshroomtimer])
player->kartstuff[k_goldshroomtimer]--;
if (player->kartstuff[k_bootimer])
player->kartstuff[k_bootimer]--;
if (player->kartstuff[k_bootaketimer])
player->kartstuff[k_bootaketimer]--;
if (player->kartstuff[k_boostolentimer])
player->kartstuff[k_boostolentimer]--;
if (player->kartstuff[k_squishedtimer])
player->kartstuff[k_squishedtimer]--;
if (player->kartstuff[k_laserwisptimer])
player->kartstuff[k_laserwisptimer]--;
if (player->kartstuff[k_justbumped])
player->kartstuff[k_justbumped]--;
if (player->kartstuff[k_poweritemtimer])
player->kartstuff[k_poweritemtimer]--;
if (player->kartstuff[k_lapanimation])
player->kartstuff[k_lapanimation]--;
if (G_BattleGametype() && (player->exiting || player->kartstuff[k_comebacktimer]))
{
if (player->exiting)
{
if (player->exiting < 6*TICRATE)
player->kartstuff[k_cardanimation] += ((164-player->kartstuff[k_cardanimation])/8)+1;
}
else
{
if (player->kartstuff[k_comebacktimer] < 6*TICRATE)
player->kartstuff[k_cardanimation] -= ((164-player->kartstuff[k_cardanimation])/8)+1;
else if (player->kartstuff[k_comebacktimer] < 9*TICRATE)
player->kartstuff[k_cardanimation] += ((164-player->kartstuff[k_cardanimation])/8)+1;
}
if (player->kartstuff[k_cardanimation] > 164)
player->kartstuff[k_cardanimation] = 164;
if (player->kartstuff[k_cardanimation] < 0)
player->kartstuff[k_cardanimation] = 0;
}
else
player->kartstuff[k_cardanimation] = 0;
if (player->kartstuff[k_sounds])
player->kartstuff[k_sounds]--;
// ???
/*
if (player->kartstuff[k_jmp] > 1 && onground)
{
S_StartSound(player->mo, sfx_spring);
P_DoJump(player, false);
player->mo->momz *= player->kartstuff[k_jmp];
player->kartstuff[k_jmp] = 0;
}
*/
if (player->kartstuff[k_comebacktimer])
player->kartstuff[k_comebackmode] = 0;
if (P_IsObjectOnGround(player->mo) && !(player->mo->momz)
&& player->kartstuff[k_feather] & 2)
player->kartstuff[k_feather] &= ~2;
if (cmd->buttons & BT_DRIFT)
player->kartstuff[k_jmp] = 1;
else
player->kartstuff[k_jmp] = 0;
// Lakitu Checker
if (player->kartstuff[k_lakitu])
K_LakituChecker(player);
// Roulette Code
//K_KartItemRouletteByPosition(player, cmd); // Old, position-based
K_KartItemRouletteByDistance(player, cmd); // New, distance-based
// Stopping of the horrible star SFX
if (player->mo->health <= 0 || player->mo->player->kartstuff[k_startimer] <= 0
|| player->mo->player->kartstuff[k_growshrinktimer] > 0) // If you don't have invincibility (or mega is active too)
{
if (S_SoundPlaying(player->mo, sfx_star)) // But the sound is playing
S_StopSoundByID(player->mo, sfx_star); // Stop it
}
// And the same for the mega mushroom SFX
if (!(player->mo->health > 0 && player->mo->player->kartstuff[k_growshrinktimer] > 0)) // If you aren't big
{
if (S_SoundPlaying(player->mo, sfx_mega)) // But the sound is playing
S_StopSoundByID(player->mo, sfx_mega); // Stop it
}
// AAAAAAND handle the SMK star alarm
if (player->mo->health > 0 && (player->mo->player->kartstuff[k_startimer] > 0
|| player->mo->player->kartstuff[k_growshrinktimer] > 0))
{
if (leveltime % 13 == 0 && cv_kartstarsfx.value && !P_IsLocalPlayer(player))
S_StartSound(player->mo, sfx_smkinv);
}
else if (S_SoundPlaying(player->mo, sfx_smkinv))
S_StopSoundByID(player->mo, sfx_smkinv);
// Plays the music after the starting countdown.
if (P_IsLocalPlayer(player) && leveltime == 158)
S_ChangeMusic(mapmusname, mapmusflags, true);
}
void K_KartPlayerAfterThink(player_t *player)
{
if (player->kartstuff[k_startimer])
{
player->mo->frame |= FF_FULLBRIGHT;
}
else
{
if (!(player->mo->state->frame & FF_FULLBRIGHT))
player->mo->frame &= ~FF_FULLBRIGHT;
}
}
static void K_PlayTauntSound(mobj_t *source)
{
S_StartSound(source, sfx_taunt1+P_RandomKey(4));
@ -2261,7 +2085,7 @@ void K_DoMushroom(player_t *player, boolean doPFlag)
player->kartstuff[k_sounds] = 50;
}
static void K_DoLightning(player_t *player, boolean bluelightning)
static void K_DoLightning(player_t *player)
{
mobj_t *mo;
thinker_t *think;
@ -2284,7 +2108,7 @@ static void K_DoLightning(player_t *player, boolean bluelightning)
if (mo->player && !mo->player->spectator
&& mo->player->kartstuff[k_position] < player->kartstuff[k_position])
P_DamageMobj(mo, player->mo, player->mo, bluelightning ? 65 : 64);
P_DamageMobj(mo, player->mo, player->mo, 64);
else
continue;
}
@ -2296,6 +2120,21 @@ static void K_DoLightning(player_t *player, boolean bluelightning)
player->kartstuff[k_sounds] = 50;
}
static void K_DoBlueShell(player_t *victim, player_t *source)
{
INT32 i;
S_StartSound(victim->mo, sfx_bkpoof); // Sound the BANG!
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i])
P_FlashPal(&players[i], PAL_NUKE, 10);
}
if (victim->mo && !victim->spectator)
P_DamageMobj(victim->mo, source->mo, source->mo, 65);
}
void K_DoBouncePad(mobj_t *mo, fixed_t vertispeed)
{
if (mo->player && mo->player->spectator)
@ -2346,6 +2185,213 @@ void K_DoBouncePad(mobj_t *mo, fixed_t vertispeed)
S_StartSound(mo, sfx_boing);
}
/** \brief Decreases various kart timers and powers per frame. Called in P_PlayerThink in p_user.c
\param player player object passed from P_PlayerThink
\param cmd control input from player
\return void
*/
void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
{
K_UpdateOffroad(player);
// setting players to use the star colormap and spawning afterimages
if (player->kartstuff[k_startimer])
{
mobj_t *ghost;
player->mo->colorized = true;
ghost = P_SpawnGhostMobj(player->mo);
ghost->fuse = 4;
ghost->frame |= FF_FULLBRIGHT;
}
else
{
player->mo->colorized = false;
}
if (player->kartstuff[k_itemclose])
player->kartstuff[k_itemclose]--;
if (player->kartstuff[k_spinout])
player->kartstuff[k_spinout]--;
if (player->kartstuff[k_spinouttimer])
player->kartstuff[k_spinouttimer]--;
else if (!comeback)
player->kartstuff[k_comebacktimer] = comebacktime;
else if (player->kartstuff[k_comebacktimer])
{
player->kartstuff[k_comebacktimer]--;
if (player == &players[consoleplayer] && player->kartstuff[k_balloon] <= 0 && player->kartstuff[k_comebacktimer] <= 0)
comebackshowninfo = true; // client has already seen the message
}
if (player->kartstuff[k_spinout] == 0 && player->kartstuff[k_spinouttimer] == 0 && player->powers[pw_flashing] == K_GetKartFlashing())
player->powers[pw_flashing]--;
if (player->kartstuff[k_magnettimer])
player->kartstuff[k_magnettimer]--;
if (player->kartstuff[k_mushroomtimer])
player->kartstuff[k_mushroomtimer]--;
if (player->kartstuff[k_floorboost])
player->kartstuff[k_floorboost]--;
if (player->kartstuff[k_driftboost])
player->kartstuff[k_driftboost]--;
if (player->kartstuff[k_startimer])
player->kartstuff[k_startimer]--;
if (player->kartstuff[k_growshrinktimer] > 0)
player->kartstuff[k_growshrinktimer]--;
if (player->kartstuff[k_growshrinktimer] < 0)
player->kartstuff[k_growshrinktimer]++;
if (player->kartstuff[k_growshrinktimer] == 1 || player->kartstuff[k_growshrinktimer] == -1)
{
player->mo->destscale = mapheaderinfo[gamemap-1]->mobj_scale;
P_RestoreMusic(player);
}
if (player->kartstuff[k_bootaketimer] == 0 && player->kartstuff[k_boostolentimer] == 0
&& player->kartstuff[k_goldshroomtimer])
player->kartstuff[k_goldshroomtimer]--;
if (player->kartstuff[k_bootimer])
player->kartstuff[k_bootimer]--;
if (player->kartstuff[k_bootaketimer])
player->kartstuff[k_bootaketimer]--;
if (player->kartstuff[k_boostolentimer])
player->kartstuff[k_boostolentimer]--;
if (player->kartstuff[k_squishedtimer])
player->kartstuff[k_squishedtimer]--;
if (player->kartstuff[k_laserwisptimer])
player->kartstuff[k_laserwisptimer]--;
if (player->kartstuff[k_justbumped])
player->kartstuff[k_justbumped]--;
if (player->kartstuff[k_deathsentence])
{
if (player->kartstuff[k_deathsentence] == 1)
K_DoBlueShell(player, &players[blueshellplayer]);
player->kartstuff[k_deathsentence]--;
}
if (player->kartstuff[k_poweritemtimer])
player->kartstuff[k_poweritemtimer]--;
if (player->kartstuff[k_lapanimation])
player->kartstuff[k_lapanimation]--;
if (G_BattleGametype() && (player->exiting || player->kartstuff[k_comebacktimer]))
{
if (player->exiting)
{
if (player->exiting < 6*TICRATE)
player->kartstuff[k_cardanimation] += ((164-player->kartstuff[k_cardanimation])/8)+1;
}
else
{
if (player->kartstuff[k_comebacktimer] < 6*TICRATE)
player->kartstuff[k_cardanimation] -= ((164-player->kartstuff[k_cardanimation])/8)+1;
else if (player->kartstuff[k_comebacktimer] < 9*TICRATE)
player->kartstuff[k_cardanimation] += ((164-player->kartstuff[k_cardanimation])/8)+1;
}
if (player->kartstuff[k_cardanimation] > 164)
player->kartstuff[k_cardanimation] = 164;
if (player->kartstuff[k_cardanimation] < 0)
player->kartstuff[k_cardanimation] = 0;
}
else
player->kartstuff[k_cardanimation] = 0;
if (player->kartstuff[k_sounds])
player->kartstuff[k_sounds]--;
// ???
/*
if (player->kartstuff[k_jmp] > 1 && onground)
{
S_StartSound(player->mo, sfx_spring);
P_DoJump(player, false);
player->mo->momz *= player->kartstuff[k_jmp];
player->kartstuff[k_jmp] = 0;
}
*/
if (player->kartstuff[k_comebacktimer])
player->kartstuff[k_comebackmode] = 0;
if (P_IsObjectOnGround(player->mo) && !(player->mo->momz)
&& player->kartstuff[k_feather] & 2)
player->kartstuff[k_feather] &= ~2;
if (cmd->buttons & BT_DRIFT)
player->kartstuff[k_jmp] = 1;
else
player->kartstuff[k_jmp] = 0;
// Lakitu Checker
if (player->kartstuff[k_lakitu])
K_LakituChecker(player);
// Roulette Code
//K_KartItemRouletteByPosition(player, cmd); // Old, position-based
K_KartItemRouletteByDistance(player, cmd); // New, distance-based
// Stopping of the horrible star SFX
if (player->mo->health <= 0 || player->mo->player->kartstuff[k_startimer] <= 0
|| player->mo->player->kartstuff[k_growshrinktimer] > 0) // If you don't have invincibility (or mega is active too)
{
if (S_SoundPlaying(player->mo, sfx_star)) // But the sound is playing
S_StopSoundByID(player->mo, sfx_star); // Stop it
}
// And the same for the mega mushroom SFX
if (!(player->mo->health > 0 && player->mo->player->kartstuff[k_growshrinktimer] > 0)) // If you aren't big
{
if (S_SoundPlaying(player->mo, sfx_mega)) // But the sound is playing
S_StopSoundByID(player->mo, sfx_mega); // Stop it
}
// AAAAAAND handle the SMK star alarm
if (player->mo->health > 0 && (player->mo->player->kartstuff[k_startimer] > 0
|| player->mo->player->kartstuff[k_growshrinktimer] > 0))
{
if (leveltime % 13 == 0 && cv_kartstarsfx.value && !P_IsLocalPlayer(player))
S_StartSound(player->mo, sfx_smkinv);
}
else if (S_SoundPlaying(player->mo, sfx_smkinv))
S_StopSoundByID(player->mo, sfx_smkinv);
// Plays the music after the starting countdown.
if (P_IsLocalPlayer(player) && leveltime == 158)
S_ChangeMusic(mapmusname, mapmusflags, true);
}
void K_KartPlayerAfterThink(player_t *player)
{
if (player->kartstuff[k_startimer])
{
player->mo->frame |= FF_FULLBRIGHT;
}
else
{
if (!(player->mo->state->frame & FF_FULLBRIGHT))
player->mo->frame &= ~FF_FULLBRIGHT;
}
}
// Returns false if this player being placed here causes them to collide with any other player
// Used in g_game.c for match etc. respawning
// This does not check along the z because the z is not correctly set for the spawnee at this point
@ -3141,14 +3187,47 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
// Thunder
else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_lightning] == 1 && NO_BOO)
{
K_DoLightning(player, false);
K_DoLightning(player);
player->kartstuff[k_lightning] = 0;
player->kartstuff[k_itemclose] = 10;
}
// Blue Shell
else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_blueshell] == 1 && NO_BOO)
{
K_DoLightning(player, true);
UINT8 i;
UINT8 bestrank = 0;
fixed_t dist = 0;
//K_DoLightning(player, true);
for (i = 0; i < MAXPLAYERS; i++)
{
fixed_t thisdist;
if (!playeringame[i] || players[i].spectator)
continue;
if (&players[i] == player)
continue;
if (!players[i].mo)
continue;
if (players[i].exiting)
continue;
thisdist = R_PointToDist2(player->mo->x, player->mo->y, players[i].mo->x, players[i].mo->y);
if (bestrank == 0 || players[i].kartstuff[k_position] < bestrank)
{
bestrank = players[i].kartstuff[k_position];
dist = thisdist;
}
}
if (dist == 0)
blueshellincoming = 6*TICRATE; // If you couldn't find anyone, just set an abritary timer
else
blueshellincoming = (tic_t)max(1, FixedDiv(dist, 64*FRACUNIT)/FRACUNIT);
blueshellplayer = player-players;
player->pflags |= PF_ATTACKDOWN;
K_PlayTauntSound(player->mo);
player->kartstuff[k_sounds] = 50;
player->kartstuff[k_blueshell] = 0;
player->kartstuff[k_itemclose] = 10;
}
@ -3526,6 +3605,7 @@ static patch_t *kp_checkmega;
static patch_t *kp_checkmegaw;
static patch_t *kp_rankballoon;
static patch_t *kp_ranknoballoons;
static patch_t *kp_bswarning[2];
/*
static patch_t *kp_neonoitem;
static patch_t *kp_electroshield;
@ -3694,6 +3774,10 @@ void K_LoadKartHUDGraphics(void)
kp_rankballoon = W_CachePatchName("K_BLNICO", PU_HUDGFX);
kp_ranknoballoons = W_CachePatchName("K_NOBLNS", PU_HUDGFX);
// Blue Shell warning
kp_bswarning[0] = W_CachePatchName("K_BSWRN1", PU_HUDGFX);
kp_bswarning[1] = W_CachePatchName("K_BSWRN2", PU_HUDGFX);
/*
// Neo-Kart item windows
kp_electroshield = W_CachePatchName("KNITELEC", PU_HUDGFX);
@ -3737,6 +3821,7 @@ INT32 FACE_X, FACE_Y; // Top-four Faces
INT32 LAKI_X, LAKI_Y; // Lakitu
INT32 CHEK_Y; // CHECK graphic
INT32 MINI_X, MINI_Y; // Minimap
INT32 BSWR_X, BSWR_Y; // Blue Shell warning
static void K_initKartHUD(void)
{
@ -3804,6 +3889,9 @@ static void K_initKartHUD(void)
// Minimap
MINI_X = BASEVIDWIDTH - 50; // 270
MINI_Y = BASEVIDHEIGHT/2; // 100
// Blue Shell warning
BSWR_X = BASEVIDWIDTH/2; // 270
BSWR_Y = BASEVIDHEIGHT- 24; // 176
if (splitscreen) // Splitscreen
{
@ -3816,6 +3904,8 @@ static void K_initKartHUD(void)
MINI_Y = (BASEVIDHEIGHT/2);
BSWR_Y = (BASEVIDHEIGHT/2)-8;
if (splitscreen > 1) // 3P/4P Small Splitscreen
{
ITEM_X = 0;
@ -3829,6 +3919,8 @@ static void K_initKartHUD(void)
MINI_X = (3*BASEVIDWIDTH/4);
MINI_Y = (3*BASEVIDHEIGHT/4);
BSWR_X = BASEVIDWIDTH/4;
if (splitscreen > 2) // 4P-only
{
MINI_X = (BASEVIDWIDTH/2);
@ -4534,6 +4626,23 @@ static void K_drawKartBalloonsOrKarma(void)
}
}
static void K_drawBlueShellWarning(void)
{
patch_t *localpatch = kp_nodraw;
INT32 splitflags = K_calcSplitFlags(V_SNAPTOBOTTOM);
if (!(stplyr->kartstuff[k_deathsentence] > 0
|| (blueshellincoming > 0 && blueshellincoming < 2*TICRATE && stplyr->kartstuff[k_position] == 1)))
return;
if (leveltime % 8 > 3)
localpatch = kp_bswarning[1];
else
localpatch = kp_bswarning[0];
V_DrawScaledPatch(BSWR_X, BSWR_Y, splitflags, localpatch);
}
fixed_t K_FindCheckX(fixed_t px, fixed_t py, angle_t ang, fixed_t mx, fixed_t my)
{
fixed_t dist, x;
@ -5103,6 +5212,9 @@ void K_drawKartHUD(void)
// Draw the numerical position
K_DrawKartPositionNum(stplyr->kartstuff[k_position]);
}
// You're about to DIEEEEE
K_drawBlueShellWarning();
}
else if (G_BattleGametype()) // Battle-only
{

View File

@ -3248,11 +3248,16 @@ static void P_NetArchiveMisc(void)
WRITEUINT32(save_p, hidetime);
// SRB2kart
WRITEINT32(save_p, numgotboxes);
WRITEUINT8(save_p, gamespeed);
WRITEUINT8(save_p, mirrormode);
WRITEUINT8(save_p, franticitems);
WRITEUINT8(save_p, comeback);
WRITEINT32(save_p, numgotboxes); // Probably shouldn't need nummapboxes
WRITEUINT32(save_p, lightningcooldown);
WRITEUINT32(save_p, blueshellincoming);
WRITEUINT8(save_p, blueshellplayer);
// Is it paused?
if (paused)
@ -3340,11 +3345,16 @@ static inline boolean P_NetUnArchiveMisc(void)
hidetime = READUINT32(save_p);
// SRB2kart
numgotboxes = READINT32(save_p);
gamespeed = READUINT8(save_p);
mirrormode = (boolean)READUINT8(save_p);
franticitems = (boolean)READUINT8(save_p);
comeback = (boolean)READUINT8(save_p);
numgotboxes = READINT32(save_p);
lightningcooldown = READUINT32(save_p);
blueshellincoming = READUINT32(save_p);
blueshellplayer = READUINT8(save_p);
// Is it paused?
if (READUINT8(save_p) == 0x2f)

View File

@ -677,6 +677,38 @@ void P_Ticker(boolean run)
if (countdown2)
countdown2--;
if (blueshellincoming && --blueshellincoming <= 0)
{
UINT8 best = 0;
SINT8 hurtthisguy = -1;
blueshellincoming = 0;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
continue;
if (!players[i].mo)
continue;
if (players[i].exiting)
continue;
if (best <= 0 || players[i].kartstuff[k_position] < best)
{
best = players[i].kartstuff[k_position];
hurtthisguy = i;
}
}
if (hurtthisguy != -1)
players[hurtthisguy].kartstuff[k_deathsentence] = TICRATE+1;
}
if (lightningcooldown)
lightningcooldown--;
if (quake.time)
{
fixed_t ir = quake.intensity>>1;