two(!!) new modes for airdrop
bouncy = a-la ring racers heavy = even faster and gives a small boost on landing
This commit is contained in:
parent
ca2420fb0f
commit
1bb3df7435
8 changed files with 131 additions and 65 deletions
|
|
@ -613,7 +613,12 @@ consvar_t cv_kartdrafting_closedraft = CVAR_INIT ("kartdrafting_closedraft", "Of
|
|||
consvar_t cv_kartdrafting_closedeadzone = CVAR_INIT ("kartdrafting_closedeadzone", "640", CV_NETVAR|CV_CHEAT, CV_Unsigned, NULL);
|
||||
consvar_t cv_kartdrafting_basedistance = CVAR_INIT ("kartdrafting_basedistance", "2560", CV_NETVAR|CV_CHEAT, CV_Unsigned, NULL);
|
||||
|
||||
consvar_t cv_kartairdrop = CVAR_INIT ("kartairdrop", "No", CV_NETVAR|CV_CALL|CV_NOINIT|CV_GUARD, CV_YesNo, KartAirDrop_OnChange);
|
||||
static CV_PossibleValue_t airdrop_cons_t[] = {{AIRDROP_NONE, "Off"},
|
||||
{AIRDROP_LIGHT, "Light"},
|
||||
{AIRDROP_BOUNCY, "Bouncy"},
|
||||
{AIRDROP_HEAVY, "Heavy"},
|
||||
{0, NULL}};
|
||||
consvar_t cv_kartairdrop = CVAR_INIT ("kartairdrop", "Off", CV_NETVAR|CV_CALL|CV_NOINIT|CV_GUARD, airdrop_cons_t, KartAirDrop_OnChange);
|
||||
|
||||
consvar_t cv_kartairthrust = CVAR_INIT ("kartairthrust", "No", CV_NETVAR|CV_CALL|CV_NOINIT|CV_GUARD, CV_YesNo, KartAirThrust_OnChange);
|
||||
consvar_t cv_kartairthrust_reductionrate = CVAR_INIT ("kartairthrust_reductionrate", "0.5", CV_NETVAR|CV_FLOAT|CV_CHEAT|CV_GUARD, CV_Unsigned, NULL);
|
||||
|
|
@ -8473,24 +8478,11 @@ static void KartAirDrop_OnChange(void)
|
|||
{
|
||||
if (leveltime < starttime)
|
||||
{
|
||||
airdropactive = true;
|
||||
CONS_Printf(M_GetText("Air Drop has been turned \"On\".\n"));
|
||||
CONS_Printf(M_GetText("Air Drop has been set to \"%s\".\n"), cv_kartairdrop.string);
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf(M_GetText("Air Drop will be turned \"On\" Next Round.\n"));
|
||||
}
|
||||
}
|
||||
else if (K_AirDropActive() && !cv_kartairdrop.value)
|
||||
{
|
||||
if (leveltime < starttime)
|
||||
{
|
||||
airdropactive = false;
|
||||
CONS_Printf(M_GetText("Air Drop has been turned \"Off\".\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf(M_GetText("Air Drop will be turned \"Off\" next round.\n"));
|
||||
CONS_Printf(M_GetText("Air Drop will be set to \"%s\" Next Round.\n"), cv_kartairdrop.string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,8 +71,9 @@ typedef enum
|
|||
// TODO: Is there a better way to track this?
|
||||
PF_GAINAX = 1<<3,
|
||||
PF_KICKSTARTACCEL = 1<<4, // Accessibility feature: Is accelerate in kickstart mode?
|
||||
// 1<<5 free
|
||||
// 1<<6 free
|
||||
|
||||
PF_WANTSAIRDROP = 1<<5, // Wants air drop (active while holding down brake, used for bouncy air drop)
|
||||
PF_AIRDROP = 1<<6, // Is in Air Drop (activation / deactivation criteria change if light or heavy)
|
||||
|
||||
PF_WANTSTOJOIN = 1<<7, // Spectator that wants to join
|
||||
|
||||
|
|
@ -672,7 +673,7 @@ struct player_t
|
|||
UINT8 ringvolume; // When consuming lots of rings, lower the sound a little.
|
||||
UINT8 ringtransparency; // When consuming lots of rings, fade out the rings again.
|
||||
|
||||
UINT8 airdroptime; // Tracks how long airdrop has been active, used for delay before airdrop kicks in.
|
||||
fixed_t airdroptime; // Tracks how long airdrop has been active, used for delay before airdrop kicks in.
|
||||
//boolean ringdrop; // Set when having ringdrop applied.
|
||||
|
||||
mobj_t *shieldtracer; // Blankart: Shield mobj
|
||||
|
|
|
|||
|
|
@ -2542,7 +2542,8 @@ static void K_DrawServerMods(INT32 x, INT32 y)
|
|||
{"Chain Offroad", 0, &cv_kartchainingoffroad, -1, true},
|
||||
{"Slope Boost", 0, NULL, K_PurpleDriftActive() > 0, true},
|
||||
{"Drafting", 0, NULL, K_DraftingActive() > 0, true},
|
||||
{"Air Drop", 0, NULL, K_AirDropActive() > 0, true},
|
||||
{"Light Air Drop", 0, NULL, K_AirDropActive() == AIRDROP_LIGHT, true},
|
||||
{"Heavy Air Drop", 0, NULL, K_AirDropActive() >= AIRDROP_HEAVY, true},
|
||||
{"Air Thrust", 0, NULL, K_AirThrustActive() > 0, true},
|
||||
{"Recovery Dash", 0, NULL, K_RecoveryDashActive() > 0, true},
|
||||
{"Bump Spark", 0, &cv_kartbumpspark, -1, true},
|
||||
|
|
|
|||
143
src/k_kart.c
143
src/k_kart.c
|
|
@ -6978,65 +6978,130 @@ static void K_SpawnFallLines(player_t *player, boolean ringdrop)
|
|||
|
||||
static void K_AirDrop(player_t *player, ticcmd_t *cmd)
|
||||
{
|
||||
if (!(cmd->buttons & BT_BRAKE))
|
||||
{
|
||||
player->pflags &= ~PF_WANTSAIRDROP;
|
||||
}
|
||||
|
||||
if (!K_AirDropActive() || P_IsObjectOnGround(player->mo)
|
||||
|| P_PlayerInPain(player) || player->loop.radius
|
||||
|| (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT)
|
||||
|| player->respawn
|
||||
)
|
||||
{
|
||||
// Conditions!
|
||||
if ((player->pflags & PF_AIRDROP))
|
||||
{
|
||||
if (airdropactive == AIRDROP_BOUNCY)
|
||||
{
|
||||
const fixed_t maxBounce = mapobjectscale * 10;
|
||||
const fixed_t minBounce = mapobjectscale;
|
||||
fixed_t bounce = 2 * abs(player->airdroptime) / 3;
|
||||
|
||||
// Lose speed on bad bounce.
|
||||
// Slow down more as horizontal momentum shrinks
|
||||
// compared to vertical momentum.
|
||||
angle_t a = R_PointToAngle2(0, 0, 4 * maxBounce, player->speed);
|
||||
fixed_t f = FSIN(a);
|
||||
player->mo->momx = FixedMul(player->mo->momx, f);
|
||||
player->mo->momy = FixedMul(player->mo->momy, f);
|
||||
if (bounce > maxBounce)
|
||||
{
|
||||
bounce = maxBounce;
|
||||
}
|
||||
else if (bounce < minBounce)
|
||||
{
|
||||
bounce = minBounce;
|
||||
}
|
||||
|
||||
if (player->mo->eflags & MFE_UNDERWATER)
|
||||
bounce = (117 * bounce) / 200;
|
||||
|
||||
// Nudge the player in their facing angle, and provide a little starting momentum if they need it.
|
||||
// The bounce is already a strong tradeoff, so this allows it to be used for saves and get you back into flow.
|
||||
angle_t momangle = K_MomentumAngle(player->mo);
|
||||
fixed_t minspeed = K_GetKartSpeed(player, false, false)/2;
|
||||
fixed_t returnspeed = max(FixedHypot(player->mo->momx, player->mo->momy), minspeed);
|
||||
|
||||
// Initial momentum set uses real speed to avoid some weird twitchy behavior at low XY speed
|
||||
P_InstaThrust(player->mo, momangle, FixedHypot(player->mo->momx, player->mo->momy)/2);
|
||||
P_Thrust(player->mo, player->mo->angle, returnspeed/2);
|
||||
|
||||
player->mo->z += P_MobjFlip(player->mo);
|
||||
player->mo->momz = bounce * P_MobjFlip(player->mo);
|
||||
|
||||
if (S_SoundPlaying(player->mo, sfx_s3kd9l))
|
||||
{
|
||||
S_StopSoundByID(player->mo, sfx_s3kd9l);
|
||||
}
|
||||
}
|
||||
else if (airdropactive == AIRDROP_HEAVY)
|
||||
{
|
||||
if (player->rings > 0)
|
||||
{
|
||||
P_PlayerRingBurst(player, min(2, player->rings));
|
||||
}
|
||||
player->startboost = TICRATE/2;
|
||||
}
|
||||
}
|
||||
player->airdroptime = 0;
|
||||
//player->ringdrop = false;
|
||||
player->pflags &= ~PF_AIRDROP;
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd->buttons & BT_BRAKE)
|
||||
if ((cmd->buttons & BT_BRAKE) && !(player->pflags & PF_WANTSAIRDROP))
|
||||
{
|
||||
SINT8 airbrakedelay = TICRATE/3;
|
||||
if (player->airdroptime < airbrakedelay)
|
||||
if (airdropactive == AIRDROP_HEAVY && !(player->pflags & PF_AIRDROP))
|
||||
{
|
||||
/*if (player->rings > 0)
|
||||
{
|
||||
player->ringlock = 6;
|
||||
}
|
||||
// TODO: heavy air drop should allow keeping current boost stack
|
||||
S_StartSound(player->mo, sfx_cdfm01);
|
||||
S_StartSound(player->mo, sfx_s3k51);
|
||||
|
||||
player->ringdrop = false;*/
|
||||
player->mo->momx = FixedMul(player->mo->momx, 90*FRACUNIT/100);
|
||||
player->mo->momy = FixedMul(player->mo->momy, 90*FRACUNIT/100);
|
||||
player->mo->momz -= 8*P_MobjFlip(player->mo)*mapobjectscale;
|
||||
}
|
||||
player->pflags |= PF_AIRDROP|PF_WANTSAIRDROP;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (airdropactive == AIRDROP_LIGHT)
|
||||
player->pflags &= ~PF_AIRDROP;
|
||||
}
|
||||
|
||||
if (player->pflags & PF_AIRDROP)
|
||||
{
|
||||
|
||||
K_SpawnFallLines(player, false);
|
||||
|
||||
if (airdropactive == AIRDROP_BOUNCY)
|
||||
{
|
||||
player->airdroptime = player->mo->momz;
|
||||
if (!S_SoundPlaying(player->mo, sfx_s3kd9l))
|
||||
{
|
||||
S_StartSound(player->mo, sfx_s3kd9l);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*if (!player->ringdelay && player->rings > 0)
|
||||
{
|
||||
mobj_t *ring = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_RING);
|
||||
P_SetMobjState(ring, S_FASTRING1);
|
||||
|
||||
ring->renderflags |= RF_ADD;
|
||||
ring->renderflags |= RF_TRANS60;
|
||||
ring->colorized = true;
|
||||
ring->color = SKINCOLOR_SILVER;
|
||||
|
||||
ring->extravalue1 = 17; // Ring use animation timer
|
||||
ring->extravalue2 = 1; // Ring use animation flag
|
||||
ring->extravalue3 = 1; // Ring airdrop use flag
|
||||
ring->shadowscale = 0;
|
||||
P_SetTarget(&ring->target, player->mo); // user
|
||||
player->rings--;
|
||||
player->ringdelay = 7;
|
||||
player->ringlock = 6;
|
||||
}
|
||||
|
||||
if (player->rings <= 0)
|
||||
{
|
||||
player->ringdrop = false;
|
||||
}*/
|
||||
|
||||
K_SpawnFallLines(player, /*player->ringdrop*/ false);
|
||||
if (player->airdroptime < UINT8_MAX)
|
||||
player->airdroptime++;
|
||||
}
|
||||
|
||||
if (airdropactive == AIRDROP_HEAVY && player->airdroptime <= TICRATE/4)
|
||||
{
|
||||
player->mo->momz -= FixedMul(4*gravity, mapobjectscale)*P_MobjFlip(player->mo);
|
||||
K_SpawnAirdropTrail(player);
|
||||
}
|
||||
else if (airdropactive == AIRDROP_LIGHT)
|
||||
{
|
||||
player->mo->momz -= FixedMul(gravity, mapobjectscale)*P_MobjFlip(player->mo);
|
||||
K_SpawnAirdropTrail(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
player->mo->momz -= FixedMul(2*gravity, mapobjectscale)*P_MobjFlip(player->mo);
|
||||
}
|
||||
}
|
||||
|
||||
if (player->airdroptime < UINT8_MAX)
|
||||
player->airdroptime++;
|
||||
}
|
||||
|
||||
// Returns the bumpspark value as an enum.
|
||||
|
|
|
|||
|
|
@ -419,6 +419,14 @@ typedef enum
|
|||
BUMPSPARK_ALL
|
||||
} bumpsparktype_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AIRDROP_NONE = 0,
|
||||
AIRDROP_LIGHT,
|
||||
AIRDROP_HEAVY,
|
||||
AIRDROP_BOUNCY,
|
||||
} airdroptype_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -617,7 +617,7 @@ extern boolean slipdashactive;
|
|||
extern boolean purpledriftactive;
|
||||
extern boolean slopeboostactive;
|
||||
extern boolean draftingactive;
|
||||
extern boolean airdropactive;
|
||||
extern UINT8 airdropactive;
|
||||
extern boolean airthrustactive;
|
||||
extern boolean recoverydashactive;
|
||||
extern boolean waterskipbricks;
|
||||
|
|
|
|||
|
|
@ -4239,13 +4239,13 @@ static boolean P_NetSyncMisc(savebuffer_t *save, boolean resending)
|
|||
SYNCBOOLEAN(purpledriftactive);
|
||||
SYNCBOOLEAN(slopeboostactive);
|
||||
SYNCBOOLEAN(draftingactive);
|
||||
SYNCBOOLEAN(airdropactive);
|
||||
SYNCBOOLEAN(airthrustactive);
|
||||
SYNCBOOLEAN(recoverydashactive);
|
||||
SYNCBOOLEAN(waterskipbricks);
|
||||
SYNCBOOLEAN(itemlittering);
|
||||
SYNCBOOLEAN(itempushing);
|
||||
SYNCBOOLEAN(itemlistactive);
|
||||
SYNC(airdropactive);
|
||||
SYNC(bumpsparkactive);
|
||||
SYNC(antibumptime);
|
||||
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ boolean slipdashactive;
|
|||
boolean purpledriftactive;
|
||||
boolean slopeboostactive;
|
||||
boolean draftingactive;
|
||||
boolean airdropactive;
|
||||
UINT8 airdropactive;
|
||||
boolean airthrustactive;
|
||||
boolean recoverydashactive;
|
||||
boolean waterskipbricks;
|
||||
|
|
@ -8183,7 +8183,7 @@ static void P_InitLevelSettings(boolean reloadinggamestate)
|
|||
purpledriftactive = false;
|
||||
slopeboostactive = false;
|
||||
draftingactive = false;
|
||||
airdropactive = false;
|
||||
airdropactive = 0;
|
||||
airthrustactive = false;
|
||||
recoverydashactive = false;
|
||||
waterskipbricks = false;
|
||||
|
|
@ -8214,8 +8214,7 @@ static void P_InitLevelSettings(boolean reloadinggamestate)
|
|||
if (cv_kartdrafting.value)
|
||||
draftingactive = true;
|
||||
|
||||
if (cv_kartairdrop.value)
|
||||
airdropactive = true;
|
||||
airdropactive = (UINT8)cv_kartairdrop.value;
|
||||
|
||||
if (cv_kartairthrust.value)
|
||||
airthrustactive = true;
|
||||
|
|
|
|||
Loading…
Reference in a new issue