mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-02-04 04:36:21 +00:00
Added rings.
This commit is contained in:
parent
4096212282
commit
129268121d
14 changed files with 529 additions and 822 deletions
|
|
@ -324,6 +324,7 @@ consvar_t cv_1up = {"tv_1up", "5", CV_NETVAR|CV_CHEAT, chanc
|
|||
consvar_t cv_eggmanbox = {"tv_eggman", "5", CV_NETVAR|CV_CHEAT, chances_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};*/
|
||||
|
||||
// SRB2kart
|
||||
consvar_t cv_superring = {"superring", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_sneaker = {"sneaker", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_rocketsneaker = {"rocketsneaker", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_invincibility = {"invincibility", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ extern consvar_t cv_1up, cv_eggmanbox;
|
|||
extern consvar_t cv_recycler;*/
|
||||
|
||||
// SRB2kart items
|
||||
extern consvar_t cv_sneaker, cv_rocketsneaker, cv_invincibility, cv_banana;
|
||||
extern consvar_t cv_superring, cv_sneaker, cv_rocketsneaker, cv_invincibility, cv_banana;
|
||||
extern consvar_t cv_eggmanmonitor, cv_orbinaut, cv_jawz, cv_mine;
|
||||
extern consvar_t cv_ballhog, cv_selfpropelledbomb, cv_grow, cv_shrink;
|
||||
extern consvar_t cv_thundershield, cv_hyudoro, cv_pogospring, cv_kitchensink;
|
||||
|
|
|
|||
|
|
@ -234,6 +234,7 @@ typedef enum
|
|||
{
|
||||
KITEM_SAD = -1,
|
||||
KITEM_NONE = 0,
|
||||
KITEM_SUPERRING,
|
||||
KITEM_SNEAKER,
|
||||
KITEM_ROCKETSNEAKER,
|
||||
KITEM_INVINCIBILITY,
|
||||
|
|
@ -288,7 +289,7 @@ typedef enum
|
|||
k_enginesnd, // Engine sound number you're on.
|
||||
|
||||
k_floorboost, // Prevents Sneaker sounds for a breif duration when triggered by a floor panel
|
||||
k_spinouttype, // Determines whether to thrust forward or not while spinning out; 0 = move forwards, 1 = stay still
|
||||
k_spinouttype, // Determines whether to thrust forward or not while spinning out; 0 = move forwards, 1 = stay still, 2 = stay still & no flashing tics
|
||||
|
||||
k_drift, // Drifting Left or Right, plus a bigger counter = sharper turn
|
||||
k_driftend, // Drift has ended, used to adjust character angle after drift
|
||||
|
|
@ -296,6 +297,9 @@ typedef enum
|
|||
k_driftboost, // Boost you get from drifting
|
||||
k_boostcharge, // Charge-up for boosting at the start of the race
|
||||
k_startboost, // Boost you get from start of race or respawn drop dash
|
||||
k_rings, // Number of held rings
|
||||
k_ringdelay, // 3 tic delay between every ring usage
|
||||
k_ringboost, // Ring boost timer
|
||||
k_jmp, // In Mario Kart, letting go of the jump button stops the drift
|
||||
k_offroad, // In Super Mario Kart, going offroad has lee-way of about 1 second before you start losing speed
|
||||
k_pogospring, // Pogo spring bounce effect
|
||||
|
|
@ -325,6 +329,7 @@ typedef enum
|
|||
k_hyudorotimer, // Duration of the Hyudoro offroad effect itself
|
||||
k_stealingtimer, // You are stealing an item, this is your timer
|
||||
k_stolentimer, // You are being stolen from, this is your timer
|
||||
k_superring, // Spawn rings on top of you every tic!
|
||||
k_sneakertimer, // Duration of the Sneaker Boost itself
|
||||
k_growshrinktimer, // > 0 = Big, < 0 = small
|
||||
k_squishedtimer, // Squished frame timer
|
||||
|
|
|
|||
|
|
@ -8283,6 +8283,9 @@ static const char *const KARTSTUFF_LIST[] = {
|
|||
"DRIFTBOOST",
|
||||
"BOOSTCHARGE",
|
||||
"STARTBOOST",
|
||||
"RINGS",
|
||||
"RINGDELAY",
|
||||
"RINGBOOST",
|
||||
"JMP",
|
||||
"OFFROAD",
|
||||
"POGOSPRING",
|
||||
|
|
@ -8309,6 +8312,7 @@ static const char *const KARTSTUFF_LIST[] = {
|
|||
"HYUDOROTIMER",
|
||||
"STEALINGTIMER",
|
||||
"STOLENTIMER",
|
||||
"SUPERRING",
|
||||
"SNEAKERTIMER",
|
||||
"GROWSHRINKTIMER",
|
||||
"SQUISHEDTIMER",
|
||||
|
|
@ -8866,6 +8870,7 @@ struct {
|
|||
// kartitems_t
|
||||
{"KITEM_SAD",KITEM_SAD}, // Actual items (can be set for k_itemtype)
|
||||
{"KITEM_NONE",KITEM_NONE},
|
||||
{"KITEM_SUPERRING",KITEM_SUPERRING},
|
||||
{"KITEM_SNEAKER",KITEM_SNEAKER},
|
||||
{"KITEM_ROCKETSNEAKER",KITEM_ROCKETSNEAKER},
|
||||
{"KITEM_INVINCIBILITY",KITEM_INVINCIBILITY},
|
||||
|
|
|
|||
10
src/info.c
10
src/info.c
|
|
@ -5444,8 +5444,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // xdeathstate
|
||||
sfx_itemup, // deathsound
|
||||
38*FRACUNIT, // speed
|
||||
16*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
24*FRACUNIT, // radius
|
||||
48*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
|
|
@ -5471,13 +5471,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // xdeathstate
|
||||
sfx_itemup, // deathsound
|
||||
38*FRACUNIT, // speed
|
||||
15*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
24*FRACUNIT, // radius
|
||||
48*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_SLIDEME|MF_SPECIAL, // flags
|
||||
MF_SLIDEME|MF_BOUNCE|MF_SPECIAL|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
|
|
|||
308
src/k_kart.c
308
src/k_kart.c
|
|
@ -397,6 +397,7 @@ UINT8 K_GetKartColorByName(const char *name)
|
|||
|
||||
void K_RegisterKartStuff(void)
|
||||
{
|
||||
CV_RegisterVar(&cv_superring);
|
||||
CV_RegisterVar(&cv_sneaker);
|
||||
CV_RegisterVar(&cv_rocketsneaker);
|
||||
CV_RegisterVar(&cv_invincibility);
|
||||
|
|
@ -496,12 +497,13 @@ boolean K_IsPlayerWanted(player_t *player)
|
|||
static INT32 K_KartItemOddsRace[NUMKARTRESULTS][10] =
|
||||
{
|
||||
//P-Odds 0 1 2 3 4 5 6 7 8 9
|
||||
/*Sneaker*/ {20, 0, 0, 4, 6, 6, 0, 0, 0, 0 }, // Sneaker
|
||||
/*Super Ring*/ {10, 2, 1, 1, 0, 0, 0, 0, 0, 0 }, // Super Ring
|
||||
/*Sneaker*/ {10, 0, 0, 4, 6, 6, 0, 0, 0, 0 }, // Sneaker
|
||||
/*Rocket Sneaker*/ { 0, 0, 0, 0, 0, 1, 3, 5, 3, 0 }, // Rocket Sneaker
|
||||
/*Invincibility*/ { 0, 0, 0, 0, 0, 1, 4, 6,14, 0 }, // Invincibility
|
||||
/*Banana*/ { 0,10, 4, 2, 1, 0, 0, 0, 0, 0 }, // Banana
|
||||
/*Eggman Monitor*/ { 0, 3, 2, 1, 0, 0, 0, 0, 0, 0 }, // Eggman Monitor
|
||||
/*Orbinaut*/ { 0, 8, 6, 4, 2, 0, 0, 0, 0, 0 }, // Orbinaut
|
||||
/*Orbinaut*/ { 0, 6, 5, 3, 2, 0, 0, 0, 0, 0 }, // Orbinaut
|
||||
/*Jawz*/ { 0, 0, 3, 2, 1, 1, 0, 0, 0, 0 }, // Jawz
|
||||
/*Mine*/ { 0, 0, 2, 2, 1, 0, 0, 0, 0, 0 }, // Mine
|
||||
/*Ballhog*/ { 0, 0, 0, 2, 1, 0, 0, 0, 0, 0 }, // Ballhog
|
||||
|
|
@ -523,6 +525,7 @@ static INT32 K_KartItemOddsRace[NUMKARTRESULTS][10] =
|
|||
static INT32 K_KartItemOddsBattle[NUMKARTRESULTS][6] =
|
||||
{
|
||||
//P-Odds 0 1 2 3 4 5
|
||||
/*Super Ring*/ { 0, 0, 0, 0, 0, 0 }, // Super Ring
|
||||
/*Sneaker*/ { 3, 2, 2, 2, 0, 2 }, // Sneaker
|
||||
/*Rocket Sneaker*/ { 0, 0, 0, 0, 0, 0 }, // Rocket Sneaker
|
||||
/*Invincibility*/ { 0, 1, 2, 3, 4, 2 }, // Invincibility
|
||||
|
|
@ -617,6 +620,7 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed)
|
|||
SINT8 first = -1, second = -1;
|
||||
INT32 secondist = 0;
|
||||
boolean itemenabled[NUMKARTRESULTS-1] = {
|
||||
cv_superring.value,
|
||||
cv_sneaker.value,
|
||||
cv_rocketsneaker.value,
|
||||
cv_invincibility.value,
|
||||
|
|
@ -1051,6 +1055,33 @@ static fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against)
|
|||
return weight;
|
||||
}
|
||||
|
||||
// This kind of wipeout happens with no rings -- doesn't remove a bumper, has no invulnerability, and is much shorter.
|
||||
static void K_BumpWipeoutPlayer(player_t *player, INT32 length)
|
||||
{
|
||||
if (player->health <= 0)
|
||||
return;
|
||||
|
||||
if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || player->kartstuff[k_spinouttimer] > 0
|
||||
|| player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_hyudorotimer] > 0
|
||||
|| (G_BattleGametype() && ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || player->kartstuff[k_comebackmode] == 1)))
|
||||
return;
|
||||
|
||||
player->kartstuff[k_driftboost] = 0;
|
||||
player->kartstuff[k_drift] = 0;
|
||||
player->kartstuff[k_driftcharge] = 0;
|
||||
player->kartstuff[k_pogospring] = 0;
|
||||
|
||||
player->kartstuff[k_spinouttype] = 2;
|
||||
player->kartstuff[k_spinouttimer] = length;
|
||||
player->kartstuff[k_wipeoutslow] = min(length-1, wipeoutslowtime+1);
|
||||
|
||||
if (player->mo->state != &states[S_KART_SPIN])
|
||||
P_SetPlayerMobjState(player->mo, S_KART_SPIN);
|
||||
|
||||
K_DropHnextList(player);
|
||||
return;
|
||||
}
|
||||
|
||||
void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
|
||||
{
|
||||
mobj_t *fx;
|
||||
|
|
@ -1199,11 +1230,21 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
|
|||
mobj1->player->rmomx = mobj1->momx - mobj1->player->cmomx;
|
||||
mobj1->player->rmomy = mobj1->momy - mobj1->player->cmomy;
|
||||
mobj1->player->kartstuff[k_justbumped] = bumptime;
|
||||
|
||||
if (mobj1->player->kartstuff[k_spinouttimer])
|
||||
{
|
||||
mobj1->player->kartstuff[k_wipeoutslow] = wipeoutslowtime+1;
|
||||
mobj1->player->kartstuff[k_spinouttimer] = max(wipeoutslowtime+1, mobj1->player->kartstuff[k_spinouttimer]);
|
||||
}
|
||||
else if (mobj2->player) // Player VS player bumping only
|
||||
{
|
||||
if (mobj1->player->kartstuff[k_rings] <= 0)
|
||||
{
|
||||
K_BumpWipeoutPlayer(mobj1->player, TICRATE + (4 * (mobj2->player->kartweight - mobj1->player->kartweight)));
|
||||
P_PlayRinglossSound(mobj1);
|
||||
}
|
||||
P_PlayerRingBurst(mobj1->player, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (mobj2->player)
|
||||
|
|
@ -1211,11 +1252,21 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
|
|||
mobj2->player->rmomx = mobj2->momx - mobj2->player->cmomx;
|
||||
mobj2->player->rmomy = mobj2->momy - mobj2->player->cmomy;
|
||||
mobj2->player->kartstuff[k_justbumped] = bumptime;
|
||||
|
||||
if (mobj2->player->kartstuff[k_spinouttimer])
|
||||
{
|
||||
mobj2->player->kartstuff[k_wipeoutslow] = wipeoutslowtime+1;
|
||||
mobj2->player->kartstuff[k_spinouttimer] = max(wipeoutslowtime+1, mobj2->player->kartstuff[k_spinouttimer]);
|
||||
}
|
||||
else if (mobj1->player) // Player VS player bumping only
|
||||
{
|
||||
if (mobj2->player->kartstuff[k_rings] <= 0)
|
||||
{
|
||||
K_BumpWipeoutPlayer(mobj2->player, TICRATE + (4 * (mobj1->player->kartweight - mobj2->player->kartweight)));
|
||||
P_PlayRinglossSound(mobj2);
|
||||
}
|
||||
P_PlayerRingBurst(mobj2->player, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1281,6 +1332,67 @@ static void K_UpdateOffroad(player_t *player)
|
|||
player->kartstuff[k_offroad] = 0;
|
||||
}
|
||||
|
||||
void K_KartPainEnergyFling(player_t *player)
|
||||
{
|
||||
static const UINT8 numfling = 5;
|
||||
INT32 i;
|
||||
mobj_t *mo;
|
||||
angle_t fa;
|
||||
fixed_t ns;
|
||||
fixed_t z;
|
||||
|
||||
// Better safe than sorry.
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
// P_PlayerRingBurst: "There's no ring spilling in kart, so I'm hijacking this for the same thing as TD"
|
||||
// :oh:
|
||||
|
||||
for (i = 0; i < numfling; i++)
|
||||
{
|
||||
INT32 objType = mobjinfo[MT_FLINGENERGY].reactiontime;
|
||||
fixed_t momxy, momz; // base horizonal/vertical thrusts
|
||||
|
||||
z = player->mo->z;
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
z += player->mo->height - mobjinfo[objType].height;
|
||||
|
||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, z, objType);
|
||||
|
||||
mo->fuse = 8*TICRATE;
|
||||
P_SetTarget(&mo->target, player->mo);
|
||||
|
||||
mo->destscale = player->mo->scale;
|
||||
P_SetScale(mo, player->mo->scale);
|
||||
|
||||
// Angle offset by player angle, then slightly offset by amount of fling
|
||||
fa = ((i*FINEANGLES/16) + (player->mo->angle>>ANGLETOFINESHIFT) - ((numfling-1)*FINEANGLES/32)) & FINEMASK;
|
||||
|
||||
if (i > 15)
|
||||
{
|
||||
momxy = 3*FRACUNIT;
|
||||
momz = 4*FRACUNIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
momxy = 28*FRACUNIT;
|
||||
momz = 3*FRACUNIT;
|
||||
}
|
||||
|
||||
ns = FixedMul(momxy, mo->scale);
|
||||
mo->momx = FixedMul(FINECOSINE(fa),ns);
|
||||
|
||||
ns = momz;
|
||||
P_SetObjectMomZ(mo, ns, false);
|
||||
|
||||
if (i & 1)
|
||||
P_SetObjectMomZ(mo, ns, true);
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
mo->momz *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
// These have to go earlier than its sisters because of K_RespawnChecker...
|
||||
void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master)
|
||||
{
|
||||
|
|
@ -1447,6 +1559,7 @@ void K_RespawnChecker(player_t *player)
|
|||
player->mo->colorized = false;
|
||||
player->kartstuff[k_dropdash] = 0;
|
||||
player->kartstuff[k_respawn] = 0;
|
||||
P_PlayerRingBurst(player, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1572,6 +1685,16 @@ void K_PlayOvertakeSound(mobj_t *source)
|
|||
K_RegularVoiceTimers(source->player);
|
||||
}
|
||||
|
||||
void K_PlayPainSound(mobj_t *source)
|
||||
{
|
||||
sfxenum_t pick = P_RandomKey(2); // Gotta roll the RNG every time this is called for sync reasons
|
||||
|
||||
if (cv_kartvoices.value)
|
||||
S_StartSound(source, sfx_khurt1 + pick);
|
||||
|
||||
K_RegularVoiceTimers(source->player);
|
||||
}
|
||||
|
||||
void K_PlayHitEmSound(mobj_t *source)
|
||||
{
|
||||
if (cv_kartvoices.value)
|
||||
|
|
@ -1667,6 +1790,12 @@ static void K_GetKartBoostPower(player_t *player)
|
|||
speedboost = max(speedboost, FRACUNIT/5); // + 20%
|
||||
}
|
||||
|
||||
if (player->kartstuff[k_ringboost]) // Ring Boost
|
||||
{
|
||||
speedboost = max(speedboost, FRACUNIT/8); // + 12.5%
|
||||
accelboost = max(accelboost, 2*FRACUNIT); // + 200%
|
||||
}
|
||||
|
||||
if (player->kartstuff[k_driftboost]) // Drift Boost
|
||||
{
|
||||
speedboost = max(speedboost, FRACUNIT/4); // + 25%
|
||||
|
|
@ -1867,7 +1996,6 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflicto
|
|||
(void)inflictor; // in case some weirdo doesn't want Lua.
|
||||
#endif
|
||||
|
||||
|
||||
if (!trapitem && G_BattleGametype())
|
||||
{
|
||||
if (K_IsPlayerWanted(player))
|
||||
|
|
@ -1879,7 +2007,7 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflicto
|
|||
if (player->health <= 0)
|
||||
return;
|
||||
|
||||
if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || player->kartstuff[k_spinouttimer] > 0
|
||||
if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || (player->kartstuff[k_spinouttimer] > 0 && player->kartstuff[k_spinouttype] != 2)
|
||||
|| player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_hyudorotimer] > 0
|
||||
|| (G_BattleGametype() && ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || player->kartstuff[k_comebackmode] == 1)))
|
||||
{
|
||||
|
|
@ -1949,7 +2077,7 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflicto
|
|||
|
||||
player->kartstuff[k_spinouttype] = type;
|
||||
|
||||
if (player->kartstuff[k_spinouttype] <= 0) // type 0 is spinout, type 1 is wipeout
|
||||
if (player->kartstuff[k_spinouttype] <= 0) // type 0 is spinout, type 1 is wipeout, type 2 is no-invuln wipeout
|
||||
{
|
||||
// At spinout, player speed is increased to 1/4 their regular speed, moving them forward
|
||||
if (player->speed < K_GetKartSpeed(player, true)/4)
|
||||
|
|
@ -1960,6 +2088,10 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflicto
|
|||
player->kartstuff[k_spinouttimer] = (3*TICRATE/2)+2;
|
||||
player->powers[pw_flashing] = K_GetKartFlashing(player);
|
||||
|
||||
P_PlayRinglossSound(player->mo);
|
||||
P_PlayerRingBurst(player, 5);
|
||||
K_PlayPainSound(player->mo);
|
||||
|
||||
if (player->mo->state != &states[S_KART_SPIN])
|
||||
P_SetPlayerMobjState(player->mo, S_KART_SPIN);
|
||||
|
||||
|
|
@ -2096,6 +2228,8 @@ void K_SquishPlayer(player_t *player, mobj_t *source, mobj_t *inflictor)
|
|||
P_SetPlayerMobjState(player->mo, S_KART_SQUISH);
|
||||
|
||||
P_PlayRinglossSound(player->mo);
|
||||
P_PlayerRingBurst(player, 5);
|
||||
K_PlayPainSound(player->mo);
|
||||
|
||||
player->kartstuff[k_instashield] = 15;
|
||||
if (cv_kartdebughuddrop.value && !modeattacking)
|
||||
|
|
@ -2132,8 +2266,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b
|
|||
if (player->health <= 0)
|
||||
return;
|
||||
|
||||
if (/*player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || player->kartstuff[k_spinouttimer] > 0 // Explosions should combo, because of SPB and Eggman
|
||||
||*/player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_hyudorotimer] > 0
|
||||
if (player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_hyudorotimer] > 0 // Do not check spinout, because SPB and Eggman should combo
|
||||
|| (G_BattleGametype() && ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || player->kartstuff[k_comebackmode] == 1)))
|
||||
{
|
||||
if (!force) // ShouldDamage can bypass that, again.
|
||||
|
|
@ -2162,7 +2295,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b
|
|||
player->kartstuff[k_pogospring] = 0;
|
||||
|
||||
// This is the only part that SHOULDN'T combo :VVVVV
|
||||
if (G_BattleGametype() && !(player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || player->kartstuff[k_spinouttimer] > 0))
|
||||
if (G_BattleGametype() && !(player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || (player->kartstuff[k_spinouttimer] > 0 && player->kartstuff[k_spinouttype] != 2)))
|
||||
{
|
||||
if (source && source->player && player != source->player)
|
||||
{
|
||||
|
|
@ -2216,6 +2349,8 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b
|
|||
P_SetPlayerMobjState(player->mo, S_KART_SPIN);
|
||||
|
||||
P_PlayRinglossSound(player->mo);
|
||||
P_PlayerRingBurst(player, 5);
|
||||
K_PlayPainSound(player->mo);
|
||||
|
||||
if (P_IsLocalPlayer(player))
|
||||
{
|
||||
|
|
@ -2250,7 +2385,7 @@ void K_StealBumper(player_t *player, player_t *victim, boolean force)
|
|||
if (player->kartstuff[k_squishedtimer] > 0 || player->kartstuff[k_spinouttimer] > 0)
|
||||
return;
|
||||
|
||||
if (victim->powers[pw_flashing] > 0 || victim->kartstuff[k_squishedtimer] > 0 || victim->kartstuff[k_spinouttimer] > 0
|
||||
if (victim->powers[pw_flashing] > 0 || victim->kartstuff[k_squishedtimer] > 0 || (victim->kartstuff[k_spinouttimer] > 0 && victim->kartstuff[k_spinouttype] != 2)
|
||||
|| victim->kartstuff[k_invincibilitytimer] > 0 || victim->kartstuff[k_growshrinktimer] > 0 || victim->kartstuff[k_hyudorotimer] > 0)
|
||||
{
|
||||
K_DoInstashield(victim);
|
||||
|
|
@ -4185,7 +4320,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
K_GetKartBoostPower(player);
|
||||
|
||||
// Speed lines
|
||||
if ((player->kartstuff[k_sneakertimer] || player->kartstuff[k_driftboost] || player->kartstuff[k_startboost]) && player->speed > 0)
|
||||
if ((player->kartstuff[k_sneakertimer] || player->kartstuff[k_ringboost] || player->kartstuff[k_driftboost] || player->kartstuff[k_startboost]) && player->speed > 0)
|
||||
{
|
||||
mobj_t *fast = P_SpawnMobj(player->mo->x + (P_RandomRange(-36,36) * player->mo->scale),
|
||||
player->mo->y + (P_RandomRange(-36,36) * player->mo->scale),
|
||||
|
|
@ -4243,6 +4378,10 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
player->mo->color = player->skincolor;
|
||||
}
|
||||
}
|
||||
else if (player->kartstuff[k_ringboost] && (leveltime & 1)) // ring boosting
|
||||
{
|
||||
player->mo->colorized = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->mo->colorized = false;
|
||||
|
|
@ -4280,8 +4419,13 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
player->kartstuff[k_timeovercam] = 0;
|
||||
|
||||
// Specific hack because it insists on setting flashing tics during this anyway...
|
||||
if (player->kartstuff[k_spinouttype] == 2)
|
||||
{
|
||||
player->powers[pw_flashing] = 0;
|
||||
}
|
||||
// Make ABSOLUTELY SURE that your flashing tics don't get set WHILE you're still in hit animations.
|
||||
if (player->kartstuff[k_spinouttimer] != 0
|
||||
else if (player->kartstuff[k_spinouttimer] != 0
|
||||
|| player->kartstuff[k_wipeoutslow] != 0
|
||||
|| player->kartstuff[k_squishedtimer] != 0)
|
||||
{
|
||||
|
|
@ -4294,19 +4438,21 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
if (player->kartstuff[k_spinouttimer])
|
||||
{
|
||||
if ((P_IsObjectOnGround(player->mo) || player->kartstuff[k_spinouttype] == 1)
|
||||
if ((P_IsObjectOnGround(player->mo)
|
||||
|| (player->kartstuff[k_spinouttype] != 0))
|
||||
&& (player->kartstuff[k_sneakertimer] == 0))
|
||||
{
|
||||
player->kartstuff[k_spinouttimer]--;
|
||||
if (player->kartstuff[k_wipeoutslow] > 1)
|
||||
player->kartstuff[k_wipeoutslow]--;
|
||||
if (player->kartstuff[k_spinouttimer] == 0)
|
||||
player->kartstuff[k_spinouttype] = 0; // Reset type
|
||||
// Actually, this caused more problems than it solved. Just make sure you set type before you spinout. Which K_SpinPlayer always does.
|
||||
/*if (player->kartstuff[k_spinouttimer] == 0)
|
||||
player->kartstuff[k_spinouttype] = 0;*/ // Reset type
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (player->kartstuff[k_wipeoutslow] == 1)
|
||||
if (player->kartstuff[k_wipeoutslow] >= 1)
|
||||
player->mo->friction = ORIG_FRICTION;
|
||||
player->kartstuff[k_wipeoutslow] = 0;
|
||||
if (!comeback)
|
||||
|
|
@ -4322,6 +4468,17 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
/*if (player->kartstuff[k_thunderanim])
|
||||
player->kartstuff[k_thunderanim]--;*/
|
||||
|
||||
if (player->kartstuff[k_rings] > 20)
|
||||
player->kartstuff[k_rings] = 20;
|
||||
else if (player->kartstuff[k_rings] < -20)
|
||||
player->kartstuff[k_rings] = -20;
|
||||
|
||||
if (player->kartstuff[k_ringdelay])
|
||||
player->kartstuff[k_ringdelay]--;
|
||||
|
||||
if (player->kartstuff[k_ringboost])
|
||||
player->kartstuff[k_ringboost]--;
|
||||
|
||||
if (player->kartstuff[k_sneakertimer])
|
||||
{
|
||||
player->kartstuff[k_sneakertimer]--;
|
||||
|
|
@ -4353,6 +4510,20 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
K_RemoveGrowShrink(player);
|
||||
}
|
||||
|
||||
if (player->kartstuff[k_superring])
|
||||
{
|
||||
if (player->kartstuff[k_superring] % 3 == 0)
|
||||
{
|
||||
mobj_t *ring = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_RING);
|
||||
ring->extravalue1 = 1; // Ring collect animation timer
|
||||
ring->angle = player->mo->angle; // animation angle
|
||||
P_SetTarget(&ring->target, player->mo); // toucher for thinker
|
||||
if (player->kartstuff[k_superring] <= 3)
|
||||
ring->cvmem = 1; // play caching when collected
|
||||
}
|
||||
player->kartstuff[k_superring]--;
|
||||
}
|
||||
|
||||
if (player->kartstuff[k_stealingtimer] == 0 && player->kartstuff[k_stolentimer] == 0
|
||||
&& player->kartstuff[k_rocketsneakertimer])
|
||||
player->kartstuff[k_rocketsneakertimer]--;
|
||||
|
|
@ -5027,6 +5198,21 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
|||
if (player->kartstuff[k_rocketsneakertimer] < 1)
|
||||
player->kartstuff[k_rocketsneakertimer] = 1;
|
||||
}
|
||||
// Ring boosts with no item
|
||||
else if (player->kartstuff[k_itemtype] == KITEM_NONE)
|
||||
{
|
||||
if ((player->pflags & PF_ATTACKDOWN) && !HOLDING_ITEM && NO_HYUDORO
|
||||
&& !player->kartstuff[k_itemroulette] && !player->kartstuff[k_ringdelay]
|
||||
&& player->kartstuff[k_rings] > 0)
|
||||
{
|
||||
mobj_t *ring = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_RING);
|
||||
ring->extravalue1 = 1; // Ring use animation timer
|
||||
ring->extravalue2 = 1; // Ring use animation flag
|
||||
P_SetTarget(&ring->target, player->mo); // user
|
||||
player->kartstuff[k_rings]--;
|
||||
player->kartstuff[k_ringdelay] = 3;
|
||||
}
|
||||
}
|
||||
else if (player->kartstuff[k_itemamount] <= 0)
|
||||
{
|
||||
player->kartstuff[k_itemamount] = player->kartstuff[k_itemheld] = 0;
|
||||
|
|
@ -5035,6 +5221,13 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
|||
{
|
||||
switch (player->kartstuff[k_itemtype])
|
||||
{
|
||||
case KITEM_SUPERRING:
|
||||
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO)
|
||||
{
|
||||
player->kartstuff[k_superring] += (10*3);
|
||||
player->kartstuff[k_itemamount]--;
|
||||
}
|
||||
break;
|
||||
case KITEM_SNEAKER:
|
||||
if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO)
|
||||
{
|
||||
|
|
@ -5373,6 +5566,10 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
|||
}
|
||||
}
|
||||
|
||||
// Prevent ring misfire
|
||||
if (player->kartstuff[k_itemtype] != KITEM_NONE)
|
||||
player->kartstuff[k_ringdelay] = 15;
|
||||
|
||||
// No more!
|
||||
if (!player->kartstuff[k_itemamount])
|
||||
{
|
||||
|
|
@ -5899,6 +6096,10 @@ static patch_t *kp_winnernum[NUMPOSFRAMES];
|
|||
static patch_t *kp_facenum[MAXPLAYERS+1];
|
||||
static patch_t *kp_facehighlight[8];
|
||||
|
||||
static patch_t *kp_ringsticker[2];
|
||||
static patch_t *kp_ring[6];
|
||||
static patch_t *kp_ringdebtminus;
|
||||
|
||||
static patch_t *kp_rankbumper;
|
||||
static patch_t *kp_tinybumper[2];
|
||||
static patch_t *kp_ranknobumpers;
|
||||
|
|
@ -5917,6 +6118,7 @@ static patch_t *kp_itemtimer[2];
|
|||
static patch_t *kp_itemmulsticker[2];
|
||||
static patch_t *kp_itemx;
|
||||
|
||||
static patch_t *kp_superring[2];
|
||||
static patch_t *kp_sneaker[2];
|
||||
static patch_t *kp_rocketsneaker[2];
|
||||
static patch_t *kp_invincibility[13];
|
||||
|
|
@ -6037,6 +6239,19 @@ void K_LoadKartHUDGraphics(void)
|
|||
kp_facehighlight[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX);
|
||||
}
|
||||
|
||||
// Rings & Lives
|
||||
kp_ringsticker[0] = W_CachePatchName("RNGBACKA", PU_HUDGFX);
|
||||
kp_ringsticker[1] = W_CachePatchName("RNGBACKB", PU_HUDGFX);
|
||||
|
||||
sprintf(buffer, "K_RINGx");
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
buffer[6] = '0'+(i+1);
|
||||
kp_ring[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX);
|
||||
}
|
||||
|
||||
kp_ringdebtminus = W_CachePatchName("RDEBTMIN", PU_HUDGFX);
|
||||
|
||||
// Extra ranking icons
|
||||
kp_rankbumper = W_CachePatchName("K_BLNICO", PU_HUDGFX);
|
||||
kp_tinybumper[0] = W_CachePatchName("K_BLNA", PU_HUDGFX);
|
||||
|
|
@ -6060,6 +6275,7 @@ void K_LoadKartHUDGraphics(void)
|
|||
kp_itemmulsticker[0] = W_CachePatchName("K_ITMUL", PU_HUDGFX);
|
||||
kp_itemx = W_CachePatchName("K_ITX", PU_HUDGFX);
|
||||
|
||||
kp_superring[0] = W_CachePatchName("K_ITRING", PU_HUDGFX);
|
||||
kp_sneaker[0] = W_CachePatchName("K_ITSHOE", PU_HUDGFX);
|
||||
kp_rocketsneaker[0] = W_CachePatchName("K_ITRSHE", PU_HUDGFX);
|
||||
|
||||
|
|
@ -6095,6 +6311,7 @@ void K_LoadKartHUDGraphics(void)
|
|||
kp_itemtimer[1] = W_CachePatchName("K_ISIMER", PU_HUDGFX);
|
||||
kp_itemmulsticker[1] = W_CachePatchName("K_ISMUL", PU_HUDGFX);
|
||||
|
||||
kp_superring[1] = W_CachePatchName("K_ISRING", PU_HUDGFX);
|
||||
kp_sneaker[1] = W_CachePatchName("K_ISSHOE", PU_HUDGFX);
|
||||
kp_rocketsneaker[1] = W_CachePatchName("K_ISRSHE", PU_HUDGFX);
|
||||
sprintf(buffer, "K_ISINVx");
|
||||
|
|
@ -6205,6 +6422,8 @@ const char *K_GetItemPatch(UINT8 item, boolean tiny)
|
|||
{
|
||||
switch (item)
|
||||
{
|
||||
case KITEM_SUPERRING:
|
||||
return (tiny ? "K_ISRING" : "K_ITRING");
|
||||
case KITEM_SNEAKER:
|
||||
case KRITEM_TRIPLESNEAKER:
|
||||
return (tiny ? "K_ISSHOE" : "K_ITSHOE");
|
||||
|
|
@ -6457,7 +6676,7 @@ static void K_drawKartItem(void)
|
|||
if (stplyr->skincolor)
|
||||
localcolor = stplyr->skincolor;
|
||||
|
||||
switch((stplyr->kartstuff[k_itemroulette] % (14*3)) / 3)
|
||||
switch((stplyr->kartstuff[k_itemroulette] % (15*3)) / 3)
|
||||
{
|
||||
// Each case is handled in threes, to give three frames of in-game time to see the item on the roulette
|
||||
case 0: // Sneaker
|
||||
|
|
@ -6516,11 +6735,15 @@ static void K_drawKartItem(void)
|
|||
localpatch = kp_thundershield[offset];
|
||||
//localcolor = SKINCOLOR_CYAN;
|
||||
break;
|
||||
/*case 14: // Pogo Spring
|
||||
case 14: // Super Ring
|
||||
localpatch = kp_superring[offset];
|
||||
//localcolor = SKINCOLOR_GOLD;
|
||||
break;
|
||||
/*case 15: // Pogo Spring
|
||||
localpatch = kp_pogospring[offset];
|
||||
localcolor = SKINCOLOR_TANGERINE;
|
||||
break;
|
||||
case 15: // Kitchen Sink
|
||||
case 16: // Kitchen Sink
|
||||
localpatch = kp_kitchensink[offset];
|
||||
localcolor = SKINCOLOR_STEEL;
|
||||
break;*/
|
||||
|
|
@ -6581,6 +6804,9 @@ static void K_drawKartItem(void)
|
|||
|
||||
switch(stplyr->kartstuff[k_itemtype])
|
||||
{
|
||||
case KITEM_SUPERRING:
|
||||
localpatch = kp_superring[offset];
|
||||
break;
|
||||
case KITEM_SNEAKER:
|
||||
localpatch = kp_sneaker[offset];
|
||||
break;
|
||||
|
|
@ -6736,7 +6962,6 @@ static void K_drawKartItem(void)
|
|||
// Quick Eggman numbers
|
||||
if (stplyr->kartstuff[k_eggmanexplode] > 1 /*&& stplyr->kartstuff[k_eggmanexplode] <= 3*TICRATE*/)
|
||||
V_DrawScaledPatch(fx+17, fy+13-offset, V_HUDTRANS|fflags, kp_eggnum[min(3, G_TicsToSeconds(stplyr->kartstuff[k_eggmanexplode]))]);
|
||||
|
||||
}
|
||||
|
||||
void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UINT8 mode)
|
||||
|
|
@ -7327,6 +7552,47 @@ static void K_drawKartLaps(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void K_drawKartRingsAndLives(void)
|
||||
{
|
||||
INT32 splitflags = K_calcSplitFlags(V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
UINT8 firstnum = ((abs(stplyr->kartstuff[k_rings]) / 10) % 10);
|
||||
UINT8 secondnum = (abs(stplyr->kartstuff[k_rings]) % 10);
|
||||
UINT8 *debtmap = NULL;
|
||||
|
||||
if (stplyr->kartstuff[k_rings] <= 0 && (leveltime/5 & 1))
|
||||
debtmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_CRIMSON, GTC_CACHE);
|
||||
|
||||
if (netgame)
|
||||
V_DrawScaledPatch(LAPS_X, LAPS_Y-11, V_HUDTRANS|splitflags, kp_ringsticker[1]);
|
||||
else
|
||||
V_DrawScaledPatch(LAPS_X, LAPS_Y-11, V_HUDTRANS|splitflags, kp_ringsticker[0]);
|
||||
|
||||
V_DrawMappedPatch(LAPS_X+7, LAPS_Y-17, V_HUDTRANS|splitflags, kp_ring[0], debtmap);
|
||||
|
||||
if (stplyr->kartstuff[k_rings] < 0)
|
||||
{
|
||||
V_DrawMappedPatch(LAPS_X+23, LAPS_Y-11, V_HUDTRANS|splitflags, kp_ringdebtminus, debtmap);
|
||||
V_DrawMappedPatch(LAPS_X+29, LAPS_Y-11, V_HUDTRANS|splitflags, kp_facenum[firstnum], debtmap);
|
||||
V_DrawMappedPatch(LAPS_X+35, LAPS_Y-11, V_HUDTRANS|splitflags, kp_facenum[secondnum], debtmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawMappedPatch(LAPS_X+23, LAPS_Y-11, V_HUDTRANS|splitflags, kp_facenum[firstnum], debtmap);
|
||||
V_DrawMappedPatch(LAPS_X+29, LAPS_Y-11, V_HUDTRANS|splitflags, kp_facenum[secondnum], debtmap);
|
||||
}
|
||||
|
||||
if (!netgame)
|
||||
{
|
||||
UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->mo->color, GTC_CACHE);
|
||||
|
||||
if (stplyr->mo->colorized)
|
||||
colormap = R_GetTranslationColormap(TC_RAINBOW, stplyr->mo->color, GTC_CACHE);
|
||||
|
||||
V_DrawMappedPatch(LAPS_X+46, LAPS_Y-16, V_HUDTRANS|splitflags, facerankprefix[stplyr->skin], colormap);
|
||||
V_DrawScaledPatch(LAPS_X+63, LAPS_Y-11, V_HUDTRANS|splitflags, kp_facenum[(stplyr->lives % 10)]);
|
||||
}
|
||||
}
|
||||
|
||||
static void K_drawKartSpeedometer(void)
|
||||
{
|
||||
fixed_t convSpeed;
|
||||
|
|
@ -8287,6 +8553,7 @@ static void K_drawLapStartAnim(void)
|
|||
void K_drawKartFreePlay(UINT32 flashtime)
|
||||
{
|
||||
// no splitscreen support because it's not FREE PLAY if you have more than one player in-game
|
||||
// (you fool, you can take splitscreen online. :V)
|
||||
|
||||
if ((flashtime % TICRATE) < TICRATE/2)
|
||||
return;
|
||||
|
|
@ -8299,6 +8566,7 @@ static void K_drawDistributionDebugger(void)
|
|||
{
|
||||
patch_t *items[NUMKARTRESULTS] = {
|
||||
kp_sadface[1],
|
||||
kp_superring[1],
|
||||
kp_sneaker[1],
|
||||
kp_rocketsneaker[1],
|
||||
kp_invincibility[7],
|
||||
|
|
@ -8497,6 +8765,8 @@ void K_drawKartHUD(void)
|
|||
#endif
|
||||
K_drawKartLaps();
|
||||
|
||||
K_drawKartRingsAndLives();
|
||||
|
||||
if (!splitscreen)
|
||||
{
|
||||
// Draw the speedometer
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ void K_RegisterKartStuff(void);
|
|||
boolean K_IsPlayerLosing(player_t *player);
|
||||
boolean K_IsPlayerWanted(player_t *player);
|
||||
void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid);
|
||||
void K_KartPainEnergyFling(player_t *player);
|
||||
void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master);
|
||||
void K_RespawnChecker(player_t *player);
|
||||
void K_KartMoveAnimation(player_t *player);
|
||||
|
|
@ -69,6 +70,7 @@ void K_CheckSpectateStatus(void);
|
|||
void K_PlayAttackTaunt(mobj_t *source);
|
||||
void K_PlayBoostTaunt(mobj_t *source);
|
||||
void K_PlayOvertakeSound(mobj_t *source);
|
||||
void K_PlayPainSound(mobj_t *source);
|
||||
void K_PlayHitEmSound(mobj_t *source);
|
||||
void K_PlayPowerGloatSound(mobj_t *source);
|
||||
|
||||
|
|
|
|||
|
|
@ -1205,37 +1205,6 @@ static int lib_pPlayerRingBurst(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pPlayerWeaponPanelBurst(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
NOHUD
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
P_PlayerWeaponPanelBurst(player);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pPlayerWeaponAmmoBurst(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
NOHUD
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
P_PlayerWeaponAmmoBurst(player);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pPlayerEmeraldBurst(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
boolean toss = lua_optboolean(L, 2);
|
||||
NOHUD
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
P_PlayerEmeraldBurst(player, toss);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pPlayerFlagBurst(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
|
|
@ -2163,6 +2132,16 @@ static int lib_kOvertakeSound(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kPainSound(lua_State *L)
|
||||
{
|
||||
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
NOHUD
|
||||
if (!mobj->player)
|
||||
return luaL_error(L, "K_PlayPainSound: mobj_t isn't a player object."); //Nothing bad would happen if we let it run the func, but telling why it ain't doing anything is helpful.
|
||||
K_PlayPainSound(mobj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kHitEmSound(lua_State *L)
|
||||
{
|
||||
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
|
|
@ -2682,9 +2661,6 @@ static luaL_Reg lib[] = {
|
|||
{"P_DamageMobj",lib_pDamageMobj},
|
||||
{"P_KillMobj",lib_pKillMobj},
|
||||
{"P_PlayerRingBurst",lib_pPlayerRingBurst},
|
||||
{"P_PlayerWeaponPanelBurst",lib_pPlayerWeaponPanelBurst},
|
||||
{"P_PlayerWeaponAmmoBurst",lib_pPlayerWeaponAmmoBurst},
|
||||
{"P_PlayerEmeraldBurst",lib_pPlayerEmeraldBurst},
|
||||
{"P_PlayerFlagBurst",lib_pPlayerFlagBurst},
|
||||
{"P_PlayRinglossSound",lib_pPlayRinglossSound},
|
||||
{"P_PlayDeathSound",lib_pPlayDeathSound},
|
||||
|
|
@ -2769,6 +2745,7 @@ static luaL_Reg lib[] = {
|
|||
{"K_PlayPowerGloatSund", lib_kGloatSound},
|
||||
{"K_PlayOvertakeSound", lib_kOvertakeSound},
|
||||
{"K_PlayLossSound", lib_kLossSound},
|
||||
{"K_PlayPainSound", lib_kPainSound},
|
||||
{"K_PlayHitEmSound", lib_kHitEmSound},
|
||||
{"K_GetKartColorByName",lib_kGetKartColorByName},
|
||||
{"K_IsPlayerLosing",lib_kIsPlayerLosing},
|
||||
|
|
|
|||
|
|
@ -1513,7 +1513,7 @@ static menuitem_t OP_AdvServerOptionsMenu[] =
|
|||
{IT_STRING | IT_CVAR, NULL, "Karma Comeback", &cv_kartcomeback, 66},
|
||||
};*/
|
||||
|
||||
#define ITEMTOGGLEBOTTOMRIGHT
|
||||
//#define ITEMTOGGLEBOTTOMRIGHT
|
||||
|
||||
static menuitem_t OP_MonitorToggleMenu[] =
|
||||
{
|
||||
|
|
@ -1541,6 +1541,7 @@ static menuitem_t OP_MonitorToggleMenu[] =
|
|||
{IT_KEYHANDLER | IT_NOTHING, NULL, "Thunder Shields", M_HandleMonitorToggles, KITEM_THUNDERSHIELD},
|
||||
{IT_KEYHANDLER | IT_NOTHING, NULL, "Hyudoros", M_HandleMonitorToggles, KITEM_HYUDORO},
|
||||
{IT_KEYHANDLER | IT_NOTHING, NULL, "Pogo Springs", M_HandleMonitorToggles, KITEM_POGOSPRING},
|
||||
{IT_KEYHANDLER | IT_NOTHING, NULL, "Super Rings", M_HandleMonitorToggles, KITEM_SUPERRING},
|
||||
{IT_KEYHANDLER | IT_NOTHING, NULL, "Kitchen Sinks", M_HandleMonitorToggles, KITEM_KITCHENSINK},
|
||||
#ifdef ITEMTOGGLEBOTTOMRIGHT
|
||||
{IT_KEYHANDLER | IT_NOTHING, NULL, "---", M_HandleMonitorToggles, 255},
|
||||
|
|
@ -9563,6 +9564,7 @@ static void M_HandleVideoMode(INT32 ch)
|
|||
// Monitor Toggles
|
||||
// ===============
|
||||
static consvar_t *kartitemcvs[NUMKARTRESULTS-1] = {
|
||||
&cv_superring,
|
||||
&cv_sneaker,
|
||||
&cv_rocketsneaker,
|
||||
&cv_invincibility,
|
||||
|
|
|
|||
170
src/p_enemy.c
170
src/p_enemy.c
|
|
@ -3615,57 +3615,137 @@ void A_AttractChase(mobj_t *actor)
|
|||
if (LUA_CallAction("A_AttractChase", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (actor->flags2 & MF2_NIGHTSPULL || !actor->health)
|
||||
return;
|
||||
|
||||
// spilled rings flicker before disappearing
|
||||
if (leveltime & 1 && actor->type == (mobjtype_t)actor->info->reactiontime && actor->fuse && actor->fuse < 2*TICRATE)
|
||||
actor->flags2 |= MF2_DONTDRAW;
|
||||
if (actor->extravalue1) // SRB2Kart
|
||||
{
|
||||
if (!actor->target || P_MobjWasRemoved(actor->target) || !actor->target->player)
|
||||
{
|
||||
P_RemoveMobj(actor);
|
||||
return;
|
||||
}
|
||||
|
||||
if (actor->extravalue2) // Using for ring boost
|
||||
{
|
||||
if (actor->extravalue1 >= 21)
|
||||
{
|
||||
#define RINGBOOSTPWR (((9 - actor->target->player->kartspeed) + (9 - actor->target->player->kartweight)) / 2)
|
||||
// Base add is 3 tics for 9,9, adds 1.5 tics for each point closer to the 1,1 end
|
||||
actor->target->player->kartstuff[k_ringboost] += ((3*RINGBOOSTPWR)/2) + 3;
|
||||
S_StartSound(actor->target, sfx_s1b5);
|
||||
actor->momx = (3*actor->target->momx)/4;
|
||||
actor->momy = (3*actor->target->momy)/4;
|
||||
actor->momz = (3*actor->target->momz)/4;
|
||||
P_KillMobj(actor, actor->target, actor->target);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed_t offz = FixedMul(80*actor->target->scale, FINESINE(FixedAngle((90 - (9 * abs(10 - actor->extravalue1))) << FRACBITS) >> ANGLETOFINESHIFT));
|
||||
//P_SetScale(actor, (actor->destscale = actor->target->scale));
|
||||
P_TeleportMove(actor, actor->target->x, actor->target->y, actor->target->z + actor->target->height + offz);
|
||||
actor->extravalue1++;
|
||||
}
|
||||
}
|
||||
else // Collecting
|
||||
{
|
||||
if (actor->extravalue1 >= 16)
|
||||
{
|
||||
P_GivePlayerRings(actor->target->player, 1);
|
||||
if (actor->cvmem) // caching
|
||||
S_StartSound(actor->target, sfx_s1c5);
|
||||
else
|
||||
S_StartSound(actor->target, sfx_s227);
|
||||
P_RemoveMobj(actor);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed_t dist = (actor->target->radius/4) * (16 - actor->extravalue1);
|
||||
|
||||
P_SetScale(actor, (actor->destscale = actor->target->scale - ((actor->target->scale/14) * actor->extravalue1)));
|
||||
P_TeleportMove(actor,
|
||||
actor->target->x + FixedMul(dist, FINECOSINE(actor->angle >> ANGLETOFINESHIFT)),
|
||||
actor->target->y + FixedMul(dist, FINESINE(actor->angle >> ANGLETOFINESHIFT)),
|
||||
actor->target->z + (24 * actor->target->scale));
|
||||
|
||||
actor->angle += ANG30;
|
||||
actor->extravalue1++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
actor->flags2 &= ~MF2_DONTDRAW;
|
||||
|
||||
// Turn flingrings back into regular rings if attracted.
|
||||
if (actor->tracer && actor->tracer->player
|
||||
&& (actor->tracer->player->powers[pw_shield] & SH_NOSTACK) != SH_ATTRACT
|
||||
&& actor->info->reactiontime && actor->type != (mobjtype_t)actor->info->reactiontime)
|
||||
{
|
||||
mobj_t *newring;
|
||||
newring = P_SpawnMobj(actor->x, actor->y, actor->z, actor->info->reactiontime);
|
||||
newring->momx = actor->momx;
|
||||
newring->momy = actor->momy;
|
||||
newring->momz = actor->momz;
|
||||
P_RemoveMobj(actor);
|
||||
return;
|
||||
// Don't immediately pick up spilled rings
|
||||
if (actor->threshold > 0)
|
||||
actor->threshold--;
|
||||
|
||||
// spilled rings flicker before disappearing
|
||||
if (leveltime & 1 && actor->type == (mobjtype_t)actor->info->reactiontime && actor->fuse && actor->fuse < 2*TICRATE)
|
||||
actor->flags2 |= MF2_DONTDRAW;
|
||||
else
|
||||
actor->flags2 &= ~MF2_DONTDRAW;
|
||||
|
||||
// Flung rings lose speed over time
|
||||
if (actor->type == (mobjtype_t)actor->info->reactiontime)
|
||||
{
|
||||
const fixed_t destspeed = FRACUNIT;
|
||||
fixed_t oldspeed = R_PointToDist2(0, 0, actor->momx, actor->momy);
|
||||
|
||||
if (oldspeed > destspeed)
|
||||
{
|
||||
fixed_t newspeed = max(destspeed, oldspeed - (FRACUNIT / TICRATE));
|
||||
|
||||
actor->momx = FixedMul(FixedDiv(actor->momx, oldspeed), newspeed);
|
||||
actor->momy = FixedMul(FixedDiv(actor->momy, oldspeed), newspeed);
|
||||
}
|
||||
}
|
||||
|
||||
// Turn flingrings back into regular rings if attracted.
|
||||
if (actor->tracer && actor->tracer->player
|
||||
&& (actor->tracer->player->powers[pw_shield] & SH_NOSTACK) != SH_ATTRACT
|
||||
&& actor->info->reactiontime && actor->type != (mobjtype_t)actor->info->reactiontime)
|
||||
{
|
||||
mobj_t *newring;
|
||||
newring = P_SpawnMobj(actor->x, actor->y, actor->z, actor->info->reactiontime);
|
||||
newring->momx = actor->momx;
|
||||
newring->momy = actor->momy;
|
||||
newring->momz = actor->momz;
|
||||
P_RemoveMobj(actor);
|
||||
return;
|
||||
}
|
||||
|
||||
P_LookForShield(actor); // Go find 'em, boy!
|
||||
|
||||
if (!actor->tracer
|
||||
|| !actor->tracer->player
|
||||
|| !actor->tracer->health
|
||||
|| !P_CheckSight(actor, actor->tracer)) // You have to be able to SEE it...sorta
|
||||
{
|
||||
// Lost attracted rings don't through walls anymore.
|
||||
actor->flags &= ~MF_NOCLIP;
|
||||
P_SetTarget(&actor->tracer, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
// If a FlingRing gets attracted by a shield, change it into a normal ring.
|
||||
if (actor->type == (mobjtype_t)actor->info->reactiontime)
|
||||
{
|
||||
P_SpawnMobj(actor->x, actor->y, actor->z, actor->info->painchance);
|
||||
P_RemoveMobj(actor);
|
||||
return;
|
||||
}
|
||||
|
||||
// Keep stuff from going down inside floors and junk
|
||||
actor->flags &= ~MF_NOCLIPHEIGHT;
|
||||
|
||||
// Let attracted rings move through walls and such.
|
||||
actor->flags |= MF_NOCLIP;
|
||||
|
||||
P_Attract(actor, actor->tracer, false);
|
||||
}
|
||||
|
||||
P_LookForShield(actor); // Go find 'em, boy!
|
||||
|
||||
if (!actor->tracer
|
||||
|| !actor->tracer->player
|
||||
|| !actor->tracer->health
|
||||
|| !P_CheckSight(actor, actor->tracer)) // You have to be able to SEE it...sorta
|
||||
{
|
||||
// Lost attracted rings don't through walls anymore.
|
||||
actor->flags &= ~MF_NOCLIP;
|
||||
P_SetTarget(&actor->tracer, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
// If a FlingRing gets attracted by a shield, change it into a normal ring.
|
||||
if (actor->type == (mobjtype_t)actor->info->reactiontime)
|
||||
{
|
||||
P_SpawnMobj(actor->x, actor->y, actor->z, actor->info->painchance);
|
||||
P_RemoveMobj(actor);
|
||||
return;
|
||||
}
|
||||
|
||||
// Keep stuff from going down inside floors and junk
|
||||
actor->flags &= ~MF_NOCLIPHEIGHT;
|
||||
|
||||
// Let attracted rings move through walls and such.
|
||||
actor->flags |= MF_NOCLIP;
|
||||
|
||||
P_Attract(actor, actor->tracer, false);
|
||||
}
|
||||
|
||||
// Function: A_DropMine
|
||||
|
|
|
|||
720
src/p_inter.c
720
src/p_inter.c
|
|
@ -116,7 +116,7 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon)
|
|||
{
|
||||
// Invulnerable
|
||||
if (player->powers[pw_flashing] > 0
|
||||
|| player->kartstuff[k_spinouttimer] > 0
|
||||
|| (player->kartstuff[k_spinouttimer] > 0 && player->kartstuff[k_spinouttype] != 2)
|
||||
|| player->kartstuff[k_squishedtimer] > 0
|
||||
|| player->kartstuff[k_invincibilitytimer] > 0
|
||||
|| player->kartstuff[k_growshrinktimer] > 0
|
||||
|
|
@ -678,15 +678,26 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
/* FALLTHRU */
|
||||
case MT_RING:
|
||||
case MT_FLINGRING:
|
||||
if (special->extravalue1)
|
||||
return;
|
||||
|
||||
// Don't immediately pick up spilled rings
|
||||
if (special->threshold > 0)
|
||||
return;
|
||||
|
||||
if (!(P_CanPickupItem(player, 0)))
|
||||
return;
|
||||
|
||||
special->momx = special->momy = special->momz = 0;
|
||||
P_GivePlayerRings(player, 1);
|
||||
// Reached the cap, don't waste 'em!
|
||||
if (player->kartstuff[k_rings] >= 20)
|
||||
return;
|
||||
|
||||
if ((maptol & TOL_NIGHTS) && special->type != MT_FLINGRING)
|
||||
P_DoNightsScore(player);
|
||||
break;
|
||||
special->momx = special->momy = special->momz = 0;
|
||||
// SRB2Kart
|
||||
special->extravalue1 = 1; // Ring collect animation timer
|
||||
special->angle = R_PointToAngle2(toucher->x, toucher->y, special->x, special->y); // animation angle
|
||||
P_SetTarget(&special->target, toucher); // toucher for thinker
|
||||
return;
|
||||
|
||||
case MT_COIN:
|
||||
case MT_FLINGCOIN:
|
||||
|
|
@ -2806,16 +2817,8 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou
|
|||
return true;
|
||||
}
|
||||
|
||||
if (target->health <= 1) // Death
|
||||
{
|
||||
P_PlayDeathSound(target);
|
||||
P_PlayVictorySound(source); // Killer laughs at you! LAUGHS! BWAHAHAHHAHAA!!
|
||||
}
|
||||
else if (target->health > 1) // Ring loss
|
||||
{
|
||||
P_PlayRinglossSound(target);
|
||||
P_PlayerRingBurst(player, player->mo->health - 1);
|
||||
}
|
||||
P_PlayRinglossSound(target);
|
||||
P_PlayerRingBurst(player, 5);
|
||||
|
||||
if (inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))
|
||||
{
|
||||
|
|
@ -2871,14 +2874,9 @@ static inline boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj
|
|||
|
||||
static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
|
||||
{
|
||||
player->pflags &= ~(PF_CARRIED|PF_SLIDING|PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG|PF_NIGHTSMODE);
|
||||
(void)source;
|
||||
|
||||
// Burst weapons and emeralds in Match/CTF only
|
||||
if (source && (G_BattleGametype()))
|
||||
{
|
||||
P_PlayerRingBurst(player, player->health - 1);
|
||||
P_PlayerEmeraldBurst(player, false);
|
||||
}
|
||||
player->pflags &= ~(PF_CARRIED|PF_SLIDING|PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG|PF_NIGHTSMODE);
|
||||
|
||||
// Get rid of shield
|
||||
player->powers[pw_shield] = SH_NONE;
|
||||
|
|
@ -2894,32 +2892,6 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
|
|||
|
||||
P_SetPlayerMobjState(player->mo, player->mo->info->deathstate);
|
||||
|
||||
/*if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
|
||||
{
|
||||
P_PlayerFlagBurst(player, false);
|
||||
if (source && source->player)
|
||||
{
|
||||
// Award no points when players shoot each other when cv_friendlyfire is on.
|
||||
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
|
||||
P_AddPlayerScore(source->player, 1);
|
||||
}
|
||||
}
|
||||
if (source && source->player && !player->powers[pw_super]) //don't score points against super players
|
||||
{
|
||||
// Award no points when players shoot each other when cv_friendlyfire is on.
|
||||
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
|
||||
P_AddPlayerScore(source->player, 1);
|
||||
}
|
||||
|
||||
// If the player was super, tell them he/she ain't so super nomore.
|
||||
if (gametype != GT_COOP && player->powers[pw_super])
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3k66); //let all players hear it.
|
||||
HU_SetCEchoFlags(0);
|
||||
HU_SetCEchoDuration(5);
|
||||
HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[player-players]));
|
||||
}*/
|
||||
|
||||
if (player->pflags & PF_TIMEOVER)
|
||||
{
|
||||
mobj_t *boom;
|
||||
|
|
@ -2952,66 +2924,6 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
static inline void P_SuperDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage) // SRB2kart - unused.
|
||||
{
|
||||
fixed_t fallbackspeed;
|
||||
angle_t ang;
|
||||
|
||||
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
player->mo->z--;
|
||||
else
|
||||
player->mo->z++;
|
||||
|
||||
if (player->mo->eflags & MFE_UNDERWATER)
|
||||
P_SetObjectMomZ(player->mo, FixedDiv(10511*FRACUNIT,2600*FRACUNIT), false);
|
||||
else
|
||||
P_SetObjectMomZ(player->mo, FixedDiv(69*FRACUNIT,10*FRACUNIT), false);
|
||||
|
||||
ang = R_PointToAngle2(inflictor->x, inflictor->y, player->mo->x, player->mo->y);
|
||||
|
||||
// explosion and rail rings send you farther back, making it more difficult
|
||||
// to recover
|
||||
if (inflictor->flags2 & MF2_SCATTER && source)
|
||||
{
|
||||
fixed_t dist = P_AproxDistance(P_AproxDistance(source->x-player->mo->x, source->y-player->mo->y), source->z-player->mo->z);
|
||||
|
||||
dist = FixedMul(128*FRACUNIT, inflictor->scale) - dist/4;
|
||||
|
||||
if (dist < FixedMul(4*FRACUNIT, inflictor->scale))
|
||||
dist = FixedMul(4*FRACUNIT, inflictor->scale);
|
||||
|
||||
fallbackspeed = dist;
|
||||
}
|
||||
else if (inflictor->flags2 & MF2_EXPLOSION)
|
||||
{
|
||||
if (inflictor->flags2 & MF2_RAILRING)
|
||||
fallbackspeed = FixedMul(28*FRACUNIT, inflictor->scale); // 7x
|
||||
else
|
||||
fallbackspeed = FixedMul(20*FRACUNIT, inflictor->scale); // 5x
|
||||
}
|
||||
else if (inflictor->flags2 & MF2_RAILRING)
|
||||
fallbackspeed = FixedMul(16*FRACUNIT, inflictor->scale); // 4x
|
||||
else
|
||||
fallbackspeed = FixedMul(4*FRACUNIT, inflictor->scale); // the usual amount of force
|
||||
|
||||
P_InstaThrust(player->mo, ang, fallbackspeed);
|
||||
|
||||
// SRB2kart - This shouldn't be reachable, but this frame is invalid.
|
||||
//if (player->charflags & SF_SUPERANIMS)
|
||||
// P_SetPlayerMobjState(player->mo, S_PLAY_SUPERHIT);
|
||||
//else
|
||||
P_SetPlayerMobjState(player->mo, player->mo->info->painstate);
|
||||
|
||||
P_ResetPlayer(player);
|
||||
|
||||
if (player->timeshit != UINT8_MAX)
|
||||
++player->timeshit;
|
||||
}
|
||||
*/
|
||||
|
||||
void P_RemoveShield(player_t *player)
|
||||
{
|
||||
if (player->powers[pw_shield] & SH_FORCE)
|
||||
|
|
@ -3040,75 +2952,6 @@ void P_RemoveShield(player_t *player)
|
|||
player->powers[pw_shield] = player->powers[pw_shield] & SH_STACK;
|
||||
}
|
||||
|
||||
/*
|
||||
static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage) // SRB2kart - unused.
|
||||
{
|
||||
// Must do pain first to set flashing -- P_RemoveShield can cause damage
|
||||
P_DoPlayerPain(player, source, inflictor);
|
||||
|
||||
P_RemoveShield(player);
|
||||
|
||||
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
|
||||
|
||||
if (source && (source->type == MT_SPIKE || (source->type == MT_NULL && source->threshold == 43))) // spikes
|
||||
S_StartSound(player->mo, sfx_spkdth);
|
||||
else
|
||||
S_StartSound (player->mo, sfx_shldls); // Ba-Dum! Shield loss.
|
||||
|
||||
if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
|
||||
{
|
||||
P_PlayerFlagBurst(player, false);
|
||||
if (source && source->player)
|
||||
{
|
||||
// Award no points when players shoot each other when cv_friendlyfire is on.
|
||||
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
|
||||
P_AddPlayerScore(source->player, 25);
|
||||
}
|
||||
}
|
||||
if (source && source->player && !player->powers[pw_super]) //don't score points against super players
|
||||
{
|
||||
// Award no points when players shoot each other when cv_friendlyfire is on.
|
||||
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
|
||||
P_AddPlayerScore(source->player, cv_match_scoring.value == 1 ? 25 : 50);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage)
|
||||
{
|
||||
//const UINT8 scoremultiply = ((K_IsWantedPlayer(player) && !trapitem) : 2 ? 1);
|
||||
|
||||
if (!(inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])))
|
||||
{
|
||||
P_DoPlayerPain(player, source, inflictor);
|
||||
|
||||
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
|
||||
|
||||
if (source && (source->type == MT_SPIKE || (source->type == MT_NULL && source->threshold == 43))) // spikes
|
||||
S_StartSound(player->mo, sfx_spkdth);
|
||||
}
|
||||
|
||||
/*if (source && source->player && !player->powers[pw_super]) //don't score points against super players
|
||||
{
|
||||
// Award no points when players shoot each other when cv_friendlyfire is on.
|
||||
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
|
||||
P_AddPlayerScore(source->player, scoremultiply);
|
||||
}
|
||||
|
||||
if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
|
||||
{
|
||||
P_PlayerFlagBurst(player, false);
|
||||
if (source && source->player)
|
||||
{
|
||||
// Award no points when players shoot each other when cv_friendlyfire is on.
|
||||
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
|
||||
P_AddPlayerScore(source->player, scoremultiply);
|
||||
}
|
||||
}*/
|
||||
|
||||
// Ring loss sound plays despite hitting spikes
|
||||
P_PlayRinglossSound(player->mo); // Ringledingle!
|
||||
}
|
||||
|
||||
/** Damages an object, which may or may not be a player.
|
||||
* For melee attacks, source and inflictor are the same.
|
||||
|
|
@ -3326,10 +3169,10 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
|| inflictor->type == MT_SMK_THWOMP || inflictor->player))
|
||||
{
|
||||
player->kartstuff[k_sneakertimer] = 0;
|
||||
|
||||
K_SpinPlayer(player, source, 1, inflictor, false);
|
||||
damage = player->mo->health - 1;
|
||||
P_RingDamage(player, inflictor, source, damage);
|
||||
P_PlayerRingBurst(player, 5);
|
||||
K_KartPainEnergyFling(player);
|
||||
|
||||
if (P_IsLocalPlayer(player))
|
||||
{
|
||||
quake.intensity = 32*FRACUNIT;
|
||||
|
|
@ -3337,110 +3180,10 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
K_SpinPlayer(player, source, 0, inflictor, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/* // SRB2kart - don't need these
|
||||
else if (metalrecording)
|
||||
{
|
||||
if (!inflictor)
|
||||
inflictor = source;
|
||||
if (inflictor && inflictor->flags & MF_ENEMY)
|
||||
{ // Metal Sonic destroy enemy !!
|
||||
P_KillMobj(inflictor, NULL, target);
|
||||
return false;
|
||||
}
|
||||
else if (inflictor && inflictor->flags & MF_MISSILE)
|
||||
return false; // Metal Sonic walk through flame !!
|
||||
else
|
||||
{ // Oh no! Metal Sonic is hit !!
|
||||
P_ShieldDamage(player, inflictor, source, damage);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (player->powers[pw_invulnerability] || player->powers[pw_flashing] // ignore bouncing & such in invulnerability
|
||||
|| (player->powers[pw_super] && !(ALL7EMERALDS(player->powers[pw_emeralds]) && inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player))))
|
||||
{
|
||||
if (force || (inflictor && (inflictor->flags & MF_MISSILE)
|
||||
&& (inflictor->flags2 & MF2_SUPERFIRE)
|
||||
&& player->powers[pw_super]))
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
if (!LUAh_MobjDamage(target, inflictor, source, damage))
|
||||
#endif
|
||||
P_SuperDamage(player, inflictor, source, damage);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
#ifdef HAVE_BLUA
|
||||
else if (LUAh_MobjDamage(target, inflictor, source, damage))
|
||||
return true;
|
||||
#endif
|
||||
else if (!player->powers[pw_super] && (player->powers[pw_shield] || player->bot)) //If One-Hit Shield
|
||||
{
|
||||
P_ShieldDamage(player, inflictor, source, damage);
|
||||
damage = 0;
|
||||
}
|
||||
else if (player->mo->health > 1) // No shield but have rings.
|
||||
{
|
||||
damage = player->mo->health - 1;
|
||||
P_RingDamage(player, inflictor, source, damage);
|
||||
}
|
||||
else // No shield, no rings, no invincibility.
|
||||
{
|
||||
// To reduce griefing potential, don't allow players to be killed
|
||||
// by friendly fire. Spilling their rings and other items is enough.
|
||||
if (force || !(G_GametypeHasTeams()
|
||||
&& source && source->player && (source->player->ctfteam == player->ctfteam)
|
||||
&& cv_friendlyfire.value))
|
||||
{
|
||||
damage = 1;
|
||||
P_KillPlayer(player, source, damage);
|
||||
}
|
||||
else
|
||||
{
|
||||
damage = 0;
|
||||
P_ShieldDamage(player, inflictor, source, damage);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))
|
||||
{
|
||||
if (player->powers[pw_shield])
|
||||
{
|
||||
P_RemoveShield(player);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->health -= (10 * (1 << (INT32)(player->powers[pw_super] / 10500)));
|
||||
if (player->health < 2)
|
||||
player->health = 2;
|
||||
}
|
||||
|
||||
if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
|
||||
P_PlayerFlagBurst(player, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
player->health -= damage; // mirror mobj health here
|
||||
if (damage < 10000)
|
||||
{
|
||||
target->player->powers[pw_flashing] = K_GetKartFlashing(target->player);
|
||||
if (damage > 0) // don't spill emeralds/ammo/panels for shield damage
|
||||
P_PlayerRingBurst(player, damage);
|
||||
}
|
||||
}
|
||||
|
||||
if (player->health < 0)
|
||||
player->health = 0;
|
||||
|
||||
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
|
||||
}
|
||||
|
||||
// Killing dead. Just for kicks.
|
||||
|
|
@ -3515,7 +3258,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
/** Spills an injured player's rings.
|
||||
*
|
||||
* \param player The player who is losing rings.
|
||||
* \param num_rings Number of rings lost. A maximum of 32 rings will be
|
||||
* \param num_rings Number of rings lost. A maximum of 20 rings will be
|
||||
* spawned.
|
||||
* \sa P_PlayerFlagBurst
|
||||
*/
|
||||
|
|
@ -3526,32 +3269,34 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
|
|||
angle_t fa;
|
||||
fixed_t ns;
|
||||
fixed_t z;
|
||||
fixed_t momxy = 5<<FRACBITS, momz = 12<<FRACBITS; // base horizonal/vertical thrusts
|
||||
|
||||
// Rings shouldn't be in Battle!
|
||||
if (G_BattleGametype())
|
||||
return;
|
||||
|
||||
// Better safe than sorry.
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
// Never have health in kart I think
|
||||
if (player->mo->health <= 1)
|
||||
num_rings = 5;
|
||||
// 20 is the ring cap in kart
|
||||
if (num_rings > 20)
|
||||
num_rings = 20;
|
||||
else if (num_rings <= 0)
|
||||
return;
|
||||
|
||||
if (num_rings > 32 && !(player->pflags & PF_NIGHTSFALL))
|
||||
num_rings = 32;
|
||||
// Cap the maximum loss automatically to 2 in ring debt
|
||||
if (player->kartstuff[k_rings] < 0 && num_rings > 2)
|
||||
num_rings = 2;
|
||||
|
||||
if (player->powers[pw_emeralds])
|
||||
P_PlayerEmeraldBurst(player, false);
|
||||
P_GivePlayerRings(player, -num_rings);
|
||||
|
||||
// Spill weapons first
|
||||
if (player->ringweapons)
|
||||
P_PlayerWeaponPanelBurst(player);
|
||||
// determine first angle
|
||||
fa = player->mo->angle + ((P_RandomByte() & 1) ? -ANGLE_90 : ANGLE_90);
|
||||
|
||||
// Spill the ammo
|
||||
P_PlayerWeaponAmmoBurst(player);
|
||||
|
||||
// There's no ring spilling in kart, so I'm hijacking this for the same thing as TD
|
||||
for (i = 0; i < num_rings; i++)
|
||||
{
|
||||
INT32 objType = mobjinfo[MT_FLINGENERGY].reactiontime;
|
||||
INT32 objType = mobjinfo[MT_RING].reactiontime;
|
||||
|
||||
z = player->mo->z;
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
|
|
@ -3559,379 +3304,34 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
|
|||
|
||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, z, objType);
|
||||
|
||||
mo->fuse = 8*TICRATE;
|
||||
mo->threshold = 10;
|
||||
mo->fuse = 15*TICRATE;
|
||||
P_SetTarget(&mo->target, player->mo);
|
||||
|
||||
mo->destscale = player->mo->scale;
|
||||
P_SetScale(mo, player->mo->scale);
|
||||
|
||||
// Angle offset by player angle, then slightly offset by amount of rings
|
||||
fa = ((i*FINEANGLES/16) + (player->mo->angle>>ANGLETOFINESHIFT) - ((num_rings-1)*FINEANGLES/32)) & FINEMASK;
|
||||
|
||||
// Make rings spill out around the player in 16 directions like SA, but spill like Sonic 2.
|
||||
// Technically a non-SA way of spilling rings. They just so happen to be a little similar.
|
||||
if (player->pflags & PF_NIGHTSFALL)
|
||||
// Angle / height offset changes every other ring
|
||||
if (i != 0)
|
||||
{
|
||||
ns = FixedMul(((i*FRACUNIT)/16)+2*FRACUNIT, mo->scale);
|
||||
mo->momx = FixedMul(FINECOSINE(fa),ns);
|
||||
|
||||
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD)))
|
||||
mo->momy = FixedMul(FINESINE(fa),ns);
|
||||
|
||||
P_SetObjectMomZ(mo, 8*FRACUNIT, false);
|
||||
mo->fuse = 20*TICRATE; // Adjust fuse for NiGHTS
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed_t momxy, momz; // base horizonal/vertical thrusts
|
||||
|
||||
if (i > 15)
|
||||
{
|
||||
momxy = 3*FRACUNIT;
|
||||
momz = 4*FRACUNIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
momxy = 28*FRACUNIT;
|
||||
momz = 3*FRACUNIT;
|
||||
}
|
||||
|
||||
ns = FixedMul(momxy, mo->scale);
|
||||
mo->momx = FixedMul(FINECOSINE(fa),ns);
|
||||
|
||||
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD)))
|
||||
mo->momy = FixedMul(FINESINE(fa),ns);
|
||||
|
||||
ns = momz;
|
||||
P_SetObjectMomZ(mo, ns, false);
|
||||
|
||||
if (i & 1)
|
||||
P_SetObjectMomZ(mo, ns, true);
|
||||
{
|
||||
momxy -= FRACUNIT;
|
||||
momz += 2<<FRACBITS;
|
||||
}
|
||||
fa += ANGLE_180;
|
||||
}
|
||||
|
||||
ns = FixedMul(momxy, mo->scale);
|
||||
mo->momx = FixedMul(FINECOSINE(fa>>ANGLETOFINESHIFT), ns);
|
||||
mo->momy = FixedMul(FINESINE(fa>>ANGLETOFINESHIFT), ns);
|
||||
|
||||
ns = FixedMul(momz, mo->scale);
|
||||
P_SetObjectMomZ(mo, ns, false);
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
mo->momz *= -1;
|
||||
}
|
||||
|
||||
player->losstime += 10*TICRATE;
|
||||
|
||||
if (P_IsObjectOnGround(player->mo))
|
||||
player->pflags &= ~PF_NIGHTSFALL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void P_PlayerWeaponPanelBurst(player_t *player)
|
||||
{
|
||||
mobj_t *mo;
|
||||
angle_t fa;
|
||||
fixed_t ns;
|
||||
INT32 i;
|
||||
fixed_t z;
|
||||
|
||||
INT32 num_weapons = M_CountBits((UINT32)player->ringweapons, NUM_WEAPONS-1);
|
||||
UINT16 ammoamt = 0;
|
||||
|
||||
for (i = 0; i < num_weapons; i++)
|
||||
{
|
||||
mobjtype_t weptype = 0;
|
||||
powertype_t power = 0;
|
||||
|
||||
if (player->ringweapons & RW_BOUNCE) // Bounce
|
||||
{
|
||||
weptype = MT_BOUNCEPICKUP;
|
||||
player->ringweapons &= ~RW_BOUNCE;
|
||||
power = pw_bouncering;
|
||||
}
|
||||
else if (player->ringweapons & RW_RAIL) // Rail
|
||||
{
|
||||
weptype = MT_RAILPICKUP;
|
||||
player->ringweapons &= ~RW_RAIL;
|
||||
power = pw_railring;
|
||||
}
|
||||
else if (player->ringweapons & RW_AUTO) // Auto
|
||||
{
|
||||
weptype = MT_AUTOPICKUP;
|
||||
player->ringweapons &= ~RW_AUTO;
|
||||
power = pw_automaticring;
|
||||
}
|
||||
else if (player->ringweapons & RW_EXPLODE) // Explode
|
||||
{
|
||||
weptype = MT_EXPLODEPICKUP;
|
||||
player->ringweapons &= ~RW_EXPLODE;
|
||||
power = pw_explosionring;
|
||||
}
|
||||
else if (player->ringweapons & RW_SCATTER) // Scatter
|
||||
{
|
||||
weptype = MT_SCATTERPICKUP;
|
||||
player->ringweapons &= ~RW_SCATTER;
|
||||
power = pw_scatterring;
|
||||
}
|
||||
else if (player->ringweapons & RW_GRENADE) // Grenade
|
||||
{
|
||||
weptype = MT_GRENADEPICKUP;
|
||||
player->ringweapons &= ~RW_GRENADE;
|
||||
power = pw_grenadering;
|
||||
}
|
||||
|
||||
if (!weptype) // ???
|
||||
continue;
|
||||
|
||||
if (player->powers[power] >= mobjinfo[weptype].reactiontime)
|
||||
ammoamt = (UINT16)mobjinfo[weptype].reactiontime;
|
||||
else
|
||||
ammoamt = player->powers[power];
|
||||
|
||||
player->powers[power] -= ammoamt;
|
||||
|
||||
z = player->mo->z;
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
z += player->mo->height - mobjinfo[weptype].height;
|
||||
|
||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, z, weptype);
|
||||
mo->reactiontime = ammoamt;
|
||||
mo->flags2 |= MF2_DONTRESPAWN;
|
||||
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT);
|
||||
P_SetTarget(&mo->target, player->mo);
|
||||
mo->fuse = 12*TICRATE;
|
||||
mo->destscale = player->mo->scale;
|
||||
P_SetScale(mo, player->mo->scale);
|
||||
|
||||
// Angle offset by player angle
|
||||
fa = ((i*FINEANGLES/16) + (player->mo->angle>>ANGLETOFINESHIFT)) & FINEMASK;
|
||||
|
||||
// Make rings spill out around the player in 16 directions like SA, but spill like Sonic 2.
|
||||
// Technically a non-SA way of spilling rings. They just so happen to be a little similar.
|
||||
|
||||
// >16 ring type spillout
|
||||
ns = FixedMul(3*FRACUNIT, mo->scale);
|
||||
mo->momx = FixedMul(FINECOSINE(fa),ns);
|
||||
|
||||
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD)))
|
||||
mo->momy = FixedMul(FINESINE(fa),ns);
|
||||
|
||||
P_SetObjectMomZ(mo, 4*FRACUNIT, false);
|
||||
|
||||
if (i & 1)
|
||||
P_SetObjectMomZ(mo, 4*FRACUNIT, true);
|
||||
}
|
||||
}
|
||||
|
||||
void P_PlayerWeaponAmmoBurst(player_t *player)
|
||||
{
|
||||
mobj_t *mo;
|
||||
angle_t fa;
|
||||
fixed_t ns;
|
||||
INT32 i = 0;
|
||||
fixed_t z;
|
||||
|
||||
mobjtype_t weptype = 0;
|
||||
powertype_t power = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (player->powers[pw_bouncering])
|
||||
{
|
||||
weptype = MT_BOUNCERING;
|
||||
power = pw_bouncering;
|
||||
}
|
||||
else if (player->powers[pw_railring])
|
||||
{
|
||||
weptype = MT_RAILRING;
|
||||
power = pw_railring;
|
||||
}
|
||||
else if (player->powers[pw_infinityring])
|
||||
{
|
||||
weptype = MT_INFINITYRING;
|
||||
power = pw_infinityring;
|
||||
}
|
||||
else if (player->powers[pw_automaticring])
|
||||
{
|
||||
weptype = MT_AUTOMATICRING;
|
||||
power = pw_automaticring;
|
||||
}
|
||||
else if (player->powers[pw_explosionring])
|
||||
{
|
||||
weptype = MT_EXPLOSIONRING;
|
||||
power = pw_explosionring;
|
||||
}
|
||||
else if (player->powers[pw_scatterring])
|
||||
{
|
||||
weptype = MT_SCATTERRING;
|
||||
power = pw_scatterring;
|
||||
}
|
||||
else if (player->powers[pw_grenadering])
|
||||
{
|
||||
weptype = MT_GRENADERING;
|
||||
power = pw_grenadering;
|
||||
}
|
||||
else
|
||||
break; // All done!
|
||||
|
||||
z = player->mo->z;
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
z += player->mo->height - mobjinfo[weptype].height;
|
||||
|
||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, z, weptype);
|
||||
mo->health = player->powers[power];
|
||||
mo->flags2 |= MF2_DONTRESPAWN;
|
||||
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT);
|
||||
P_SetTarget(&mo->target, player->mo);
|
||||
|
||||
player->powers[power] = 0;
|
||||
mo->fuse = 12*TICRATE;
|
||||
|
||||
mo->destscale = player->mo->scale;
|
||||
P_SetScale(mo, player->mo->scale);
|
||||
|
||||
// Angle offset by player angle
|
||||
fa = ((i*FINEANGLES/16) + (player->mo->angle>>ANGLETOFINESHIFT)) & FINEMASK;
|
||||
|
||||
// Spill them!
|
||||
ns = FixedMul(2*FRACUNIT, mo->scale);
|
||||
mo->momx = FixedMul(FINECOSINE(fa), ns);
|
||||
|
||||
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD)))
|
||||
mo->momy = FixedMul(FINESINE(fa),ns);
|
||||
|
||||
P_SetObjectMomZ(mo, 3*FRACUNIT, false);
|
||||
|
||||
if (i & 1)
|
||||
P_SetObjectMomZ(mo, 3*FRACUNIT, true);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_PlayerEmeraldBurst
|
||||
//
|
||||
// Spills ONLY emeralds.
|
||||
//
|
||||
void P_PlayerEmeraldBurst(player_t *player, boolean toss)
|
||||
{
|
||||
INT32 i;
|
||||
angle_t fa;
|
||||
fixed_t ns;
|
||||
fixed_t z = 0, momx = 0, momy = 0;
|
||||
|
||||
// Better safe than sorry.
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
// Spill power stones
|
||||
if (player->powers[pw_emeralds])
|
||||
{
|
||||
INT32 num_stones = 0;
|
||||
|
||||
if (player->powers[pw_emeralds] & EMERALD1)
|
||||
num_stones++;
|
||||
if (player->powers[pw_emeralds] & EMERALD2)
|
||||
num_stones++;
|
||||
if (player->powers[pw_emeralds] & EMERALD3)
|
||||
num_stones++;
|
||||
if (player->powers[pw_emeralds] & EMERALD4)
|
||||
num_stones++;
|
||||
if (player->powers[pw_emeralds] & EMERALD5)
|
||||
num_stones++;
|
||||
if (player->powers[pw_emeralds] & EMERALD6)
|
||||
num_stones++;
|
||||
if (player->powers[pw_emeralds] & EMERALD7)
|
||||
num_stones++;
|
||||
|
||||
for (i = 0; i < num_stones; i++)
|
||||
{
|
||||
INT32 stoneflag = 0;
|
||||
statenum_t statenum = S_CEMG1;
|
||||
mobj_t *mo;
|
||||
|
||||
if (player->powers[pw_emeralds] & EMERALD1)
|
||||
{
|
||||
stoneflag = EMERALD1;
|
||||
statenum = S_CEMG1;
|
||||
}
|
||||
else if (player->powers[pw_emeralds] & EMERALD2)
|
||||
{
|
||||
stoneflag = EMERALD2;
|
||||
statenum = S_CEMG2;
|
||||
}
|
||||
else if (player->powers[pw_emeralds] & EMERALD3)
|
||||
{
|
||||
stoneflag = EMERALD3;
|
||||
statenum = S_CEMG3;
|
||||
}
|
||||
else if (player->powers[pw_emeralds] & EMERALD4)
|
||||
{
|
||||
stoneflag = EMERALD4;
|
||||
statenum = S_CEMG4;
|
||||
}
|
||||
else if (player->powers[pw_emeralds] & EMERALD5)
|
||||
{
|
||||
stoneflag = EMERALD5;
|
||||
statenum = S_CEMG5;
|
||||
}
|
||||
else if (player->powers[pw_emeralds] & EMERALD6)
|
||||
{
|
||||
stoneflag = EMERALD6;
|
||||
statenum = S_CEMG6;
|
||||
}
|
||||
else if (player->powers[pw_emeralds] & EMERALD7)
|
||||
{
|
||||
stoneflag = EMERALD7;
|
||||
statenum = S_CEMG7;
|
||||
}
|
||||
|
||||
if (!stoneflag) // ???
|
||||
continue;
|
||||
|
||||
player->powers[pw_emeralds] &= ~stoneflag;
|
||||
|
||||
if (toss)
|
||||
{
|
||||
fa = player->mo->angle>>ANGLETOFINESHIFT;
|
||||
|
||||
z = player->mo->z + player->mo->height;
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
z -= mobjinfo[MT_FLINGEMERALD].height + player->mo->height;
|
||||
ns = FixedMul(8*FRACUNIT, player->mo->scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
fa = ((255 / num_stones) * i) * FINEANGLES/256;
|
||||
|
||||
z = player->mo->z + (player->mo->height / 2);
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
z -= mobjinfo[MT_FLINGEMERALD].height;
|
||||
ns = FixedMul(4*FRACUNIT, player->mo->scale);
|
||||
}
|
||||
|
||||
momx = FixedMul(FINECOSINE(fa), ns);
|
||||
|
||||
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD)))
|
||||
momy = FixedMul(FINESINE(fa),ns);
|
||||
else
|
||||
momy = 0;
|
||||
|
||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, z, MT_FLINGEMERALD);
|
||||
mo->health = 1;
|
||||
mo->threshold = stoneflag;
|
||||
mo->flags2 |= (MF2_DONTRESPAWN|MF2_SLIDEPUSH);
|
||||
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT);
|
||||
P_SetTarget(&mo->target, player->mo);
|
||||
mo->fuse = 12*TICRATE;
|
||||
P_SetMobjState(mo, statenum);
|
||||
|
||||
mo->momx = momx;
|
||||
mo->momy = momy;
|
||||
|
||||
P_SetObjectMomZ(mo, 3*FRACUNIT, false);
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
mo->momz = -mo->momz;
|
||||
|
||||
if (toss)
|
||||
player->tossdelay = 2*TICRATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Makes an injured or dead player lose possession of the flag.
|
||||
|
|
|
|||
|
|
@ -393,9 +393,6 @@ void P_RemoveShield(player_t *player);
|
|||
boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage);
|
||||
void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source);
|
||||
void P_PlayerRingBurst(player_t *player, INT32 num_rings); /// \todo better fit in p_user.c
|
||||
void P_PlayerWeaponPanelBurst(player_t *player);
|
||||
void P_PlayerWeaponAmmoBurst(player_t *player);
|
||||
void P_PlayerEmeraldBurst(player_t *player, boolean toss);
|
||||
|
||||
void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck);
|
||||
void P_PlayerFlagBurst(player_t *player, boolean toss);
|
||||
|
|
|
|||
17
src/p_mobj.c
17
src/p_mobj.c
|
|
@ -2021,7 +2021,7 @@ void P_XYMovement(mobj_t *mo)
|
|||
#endif
|
||||
|
||||
//{ SRB2kart stuff
|
||||
if (mo->type == MT_ORBINAUT || mo->type == MT_JAWZ_DUD || mo->type == MT_JAWZ || mo->type == MT_BALLHOG) //(mo->type == MT_JAWZ && !mo->tracer))
|
||||
if (mo->type == MT_ORBINAUT || mo->type == MT_JAWZ_DUD || mo->type == MT_JAWZ || mo->type == MT_BALLHOG || mo->type == MT_FLINGRING) //(mo->type == MT_JAWZ && !mo->tracer))
|
||||
return;
|
||||
|
||||
if (mo->player && (mo->player->kartstuff[k_spinouttimer] && !mo->player->kartstuff[k_wipeoutslow]) && mo->player->speed <= mo->player->normalspeed/2)
|
||||
|
|
@ -2572,11 +2572,11 @@ static boolean P_ZMovement(mobj_t *mo)
|
|||
mom.z = -mom.z;
|
||||
else
|
||||
// Flingrings bounce
|
||||
if (mo->type == MT_FLINGRING
|
||||
if (/*mo->type == MT_FLINGRING
|
||||
|| mo->type == MT_FLINGCOIN
|
||||
|| P_WeaponOrPanel(mo->type)
|
||||
|| mo->type == MT_FLINGEMERALD
|
||||
|| mo->type == MT_BIGTUMBLEWEED
|
||||
||*/ mo->type == MT_BIGTUMBLEWEED
|
||||
|| mo->type == MT_LITTLETUMBLEWEED
|
||||
|| mo->type == MT_CANNONBALLDECOR
|
||||
|| mo->type == MT_FALLINGROCK)
|
||||
|
|
@ -10371,8 +10371,8 @@ void P_RemoveMobj(mobj_t *mobj)
|
|||
|
||||
// Rings only, please!
|
||||
if (mobj->spawnpoint &&
|
||||
(mobj->type == MT_RING
|
||||
|| mobj->type == MT_COIN
|
||||
(/*mobj->type == MT_RING
|
||||
||*/ mobj->type == MT_COIN
|
||||
|| mobj->type == MT_BLUEBALL
|
||||
|| mobj->type == MT_REDTEAMRING
|
||||
|| mobj->type == MT_BLUETEAMRING
|
||||
|
|
@ -12073,7 +12073,7 @@ ML_NOCLIMB : Direction not controllable
|
|||
void P_SpawnHoopsAndRings(mapthing_t *mthing)
|
||||
{
|
||||
mobj_t *mobj = NULL;
|
||||
INT32 /*r,*/ i;
|
||||
INT32 r, i;
|
||||
fixed_t x, y, z, finalx, finaly, finalz;
|
||||
sector_t *sec;
|
||||
TVector v, *res;
|
||||
|
|
@ -12360,8 +12360,6 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
|
|||
|
||||
return;
|
||||
}
|
||||
else return; // srb2kart - no rings or ring-like objects in R1
|
||||
/*
|
||||
// Wing logo item.
|
||||
else if (mthing->type == mobjinfo[MT_NIGHTSWING].doomednum)
|
||||
{
|
||||
|
|
@ -12655,7 +12653,8 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
|
|||
}
|
||||
}
|
||||
return;
|
||||
}*/
|
||||
}
|
||||
else return;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
57
src/p_user.c
57
src/p_user.c
|
|
@ -946,50 +946,19 @@ void P_ResetPlayer(player_t *player)
|
|||
//
|
||||
void P_GivePlayerRings(player_t *player, INT32 num_rings)
|
||||
{
|
||||
if (player->bot)
|
||||
player = &players[consoleplayer];
|
||||
|
||||
if (!player->mo)
|
||||
return;
|
||||
|
||||
player->mo->health += num_rings;
|
||||
player->health += num_rings;
|
||||
if (G_BattleGametype()) // No rings in Battle Mode
|
||||
return;
|
||||
|
||||
if (!G_IsSpecialStage(gamemap) || !useNightsSS)
|
||||
player->totalring += num_rings;
|
||||
player->kartstuff[k_rings] += num_rings;
|
||||
//player->totalring += num_rings; // Used for GP lives later
|
||||
|
||||
//{ SRB2kart - rings don't really do anything, but we don't want the player spilling them later.
|
||||
/*
|
||||
// Can only get up to 9999 rings, sorry!
|
||||
if (player->mo->health > 10000)
|
||||
{
|
||||
player->mo->health = 10000;
|
||||
player->health = 10000;
|
||||
}
|
||||
else if (player->mo->health < 1)*/
|
||||
{
|
||||
player->mo->health = 1;
|
||||
player->health = 1;
|
||||
}
|
||||
//}
|
||||
|
||||
// Now extra life bonuses are handled here instead of in P_MovePlayer, since why not?
|
||||
if (!ultimatemode && !modeattacking && !G_IsSpecialStage(gamemap) && G_GametypeUsesLives())
|
||||
{
|
||||
INT32 gainlives = 0;
|
||||
|
||||
while (player->xtralife < maxXtraLife && player->health > 100 * (player->xtralife+1))
|
||||
{
|
||||
++gainlives;
|
||||
++player->xtralife;
|
||||
}
|
||||
|
||||
if (gainlives)
|
||||
{
|
||||
P_GivePlayerLives(player, gainlives);
|
||||
P_PlayLivesJingle(player);
|
||||
}
|
||||
}
|
||||
if (player->kartstuff[k_rings] > 20)
|
||||
player->kartstuff[k_rings] = 20; // Caps at 20 rings, sorry!
|
||||
else if (player->kartstuff[k_rings] < -20)
|
||||
player->kartstuff[k_rings] = -20; // Chaotix ring debt!
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -1114,11 +1083,10 @@ void P_PlayLivesJingle(player_t *player)
|
|||
|
||||
void P_PlayRinglossSound(mobj_t *source)
|
||||
{
|
||||
sfxenum_t key = P_RandomKey(2);
|
||||
if (cv_kartvoices.value)
|
||||
S_StartSound(source, (mariomode) ? sfx_mario8 : sfx_khurt1 + key);
|
||||
if (source->player && source->player->kartstuff[k_rings] <= 0)
|
||||
S_StartSound(source, sfx_s1a6);
|
||||
else
|
||||
S_StartSound(source, sfx_slip);
|
||||
S_StartSound(source, sfx_s1c6);
|
||||
}
|
||||
|
||||
void P_PlayDeathSound(mobj_t *source)
|
||||
|
|
@ -9294,7 +9262,8 @@ void P_PlayerThink(player_t *player)
|
|||
#if 1
|
||||
// "Blur" a bit when you have speed shoes and are going fast enough
|
||||
if ((player->powers[pw_super] || player->powers[pw_sneakers]
|
||||
|| player->kartstuff[k_driftboost] || player->kartstuff[k_sneakertimer] || player->kartstuff[k_startboost]) && !player->kartstuff[k_invincibilitytimer] // SRB2kart
|
||||
|| player->kartstuff[k_driftboost] || player->kartstuff[k_ringboost] || player->kartstuff[k_sneakertimer] || player->kartstuff[k_startboost])
|
||||
&& !player->kartstuff[k_invincibilitytimer] // SRB2kart
|
||||
&& (player->speed + abs(player->mo->momz)) > FixedMul(20*FRACUNIT,player->mo->scale))
|
||||
{
|
||||
mobj_t *gmobj = P_SpawnGhostMobj(player->mo);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue