Merge branch 'battle-tweak-update' into 'master'

Huge Battle W

See merge request KartKrew/Kart!636
This commit is contained in:
SteelT 2022-08-04 16:55:26 +00:00
commit 5ebcf86d7d
11 changed files with 196 additions and 64 deletions

View file

@ -2541,6 +2541,13 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_GREYSPRING3",
"S_GREYSPRING4",
// Orange Spring (Pogo)
"S_POGOSPRING1",
"S_POGOSPRING2",
"S_POGOSPRING2B",
"S_POGOSPRING3",
"S_POGOSPRING4",
// Yellow Diagonal Spring
"S_YDIAG1",
"S_YDIAG2",
@ -4631,6 +4638,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_REDSPRING",
"MT_BLUESPRING",
"MT_GREYSPRING",
"MT_POGOSPRING",
"MT_YELLOWDIAG", // Yellow Diagonal Spring
"MT_REDDIAG", // Red Diagonal Spring
"MT_BLUEDIAG", // Blue Diagonal Spring

View file

@ -3072,6 +3072,13 @@ state_t states[NUMSTATES] =
{SPR_SPVG, 0, 1, {NULL}, 0, 0, S_GREYSPRING4}, // S_GREYSPRING3
{SPR_SPVG, 2, 4, {NULL}, 0, 0, S_GREYSPRING1}, // S_GREYSPRING4
// Orange Spring (Pogo)
{SPR_SPVB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_POGOSPRING1
{SPR_SPVB, 1, 1, {A_Pain}, 0, 0, S_POGOSPRING3}, // S_POGOSPRING2
{SPR_SPVB, 1, 1, {A_PlaySeeSound}, 0, 0, S_POGOSPRING3}, // S_POGOSPRING2B
{SPR_SPVB, 0, 1, {NULL}, 0, 0, S_POGOSPRING4}, // S_POGOSPRING3
{SPR_SPVB, 2, 4, {NULL}, 0, 0, S_POGOSPRING1}, // S_POGOSPRING4
// Yellow Diagonal Spring
{SPR_SPDY, 0, -1, {NULL}, 0, 0, S_NULL}, // S_YDIAG1
{SPR_SPDY, 1, 1, {A_Pain}, 0, 0, S_YDIAG3}, // S_YDIAG2
@ -8236,6 +8243,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_GREYSPRING2 // raisestate
},
{ // MT_POGOSPRING
-1, // doomednum
S_POGOSPRING1, // spawnstate
1000, // spawnhealth
S_POGOSPRING2B, // seestate
sfx_eggspr, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
SKINCOLOR_SUNSLAM, // painchance
sfx_s3kb1, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
48*FRACUNIT, // radius
32*FRACUNIT, // height
0, // display offset
32*FRACUNIT, // mass
0, // damage
sfx_None, // activesound
MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
S_POGOSPRING2 // raisestate
},
{ // MT_YELLOWDIAG
554, // doomednum
S_YDIAG1, // spawnstate

View file

@ -3529,6 +3529,13 @@ typedef enum state
S_GREYSPRING3,
S_GREYSPRING4,
// Orange Spring (Pogo)
S_POGOSPRING1,
S_POGOSPRING2,
S_POGOSPRING2B,
S_POGOSPRING3,
S_POGOSPRING4,
// Yellow Diagonal Spring
S_YDIAG1,
S_YDIAG2,
@ -5656,6 +5663,7 @@ typedef enum mobj_type
MT_REDSPRING,
MT_BLUESPRING,
MT_GREYSPRING,
MT_POGOSPRING,
MT_YELLOWDIAG, // Yellow Diagonal Spring
MT_REDDIAG, // Red Diagonal Spring
MT_BLUEDIAG, // Blue Diagonal Spring

View file

@ -856,6 +856,9 @@ boolean K_SMKIceBlockCollide(mobj_t *t1, mobj_t *t2)
boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
{
const boolean flameT1 = (t1->player->flamedash > 0 && t1->player->itemtype == KITEM_FLAMESHIELD);
const boolean flameT2 = (t2->player->flamedash > 0 && t2->player->itemtype == KITEM_FLAMESHIELD);
boolean t1Condition = false;
boolean t2Condition = false;
boolean stungT1 = false;
@ -864,7 +867,12 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
t1Condition = (t1->scale > t2->scale + (mapobjectscale/8)) || (t1->player->invincibilitytimer > 0);
t2Condition = (t2->scale > t1->scale + (mapobjectscale/8)) || (t2->player->invincibilitytimer > 0);
if (t1Condition == true && t2Condition == false)
if ((t1Condition == true || flameT1 == true) && (t2Condition == true || flameT2 == true))
{
K_DoPowerClash(t1->player, t2->player);
return false;
}
else if (t1Condition == true && t2Condition == false)
{
P_DamageMobj(t2, t1, t1, 1, DMG_TUMBLE);
return true;
@ -873,14 +881,11 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
{
P_DamageMobj(t1, t2, t2, 1, DMG_TUMBLE);
return true;
} else if (t1Condition == true && t2Condition == true) {
K_DoPowerClash(t1->player, t2->player);
return false;
}
// Flame Shield dash damage
t1Condition = (t1->player->flamedash > 0 && t1->player->itemtype == KITEM_FLAMESHIELD);
t2Condition = (t2->player->flamedash > 0 && t2->player->itemtype == KITEM_FLAMESHIELD);
t1Condition = flameT1;
t2Condition = flameT2;
if (t1Condition == true && t2Condition == false)
{

View file

@ -387,32 +387,32 @@ static INT32 K_KartItemOddsBattle[NUMKARTRESULTS][2] =
//P-Odds 0 1
/*Sneaker*/ { 2, 1 }, // Sneaker
/*Rocket Sneaker*/ { 0, 0 }, // Rocket Sneaker
/*Invincibility*/ { 2, 1 }, // Invincibility
/*Banana*/ { 1, 0 }, // Banana
/*Invincibility*/ { 4, 1 }, // Invincibility
/*Banana*/ { 0, 0 }, // Banana
/*Eggman Monitor*/ { 1, 0 }, // Eggman Monitor
/*Orbinaut*/ { 8, 0 }, // Orbinaut
/*Jawz*/ { 8, 1 }, // Jawz
/*Mine*/ { 6, 1 }, // Mine
/*Land Mine*/ { 0, 0 }, // Land Mine
/*Land Mine*/ { 2, 0 }, // Land Mine
/*Ballhog*/ { 2, 1 }, // Ballhog
/*Self-Propelled Bomb*/ { 0, 0 }, // Self-Propelled Bomb
/*Grow*/ { 2, 1 }, // Grow
/*Shrink*/ { 0, 0 }, // Shrink
/*Lightning Shield*/ { 4, 0 }, // Lightning Shield
/*Bubble Shield*/ { 1, 0 }, // Bubble Shield
/*Flame Shield*/ { 0, 0 }, // Flame Shield
/*Flame Shield*/ { 1, 0 }, // Flame Shield
/*Hyudoro*/ { 2, 0 }, // Hyudoro
/*Pogo Spring*/ { 2, 0 }, // Pogo Spring
/*Pogo Spring*/ { 3, 0 }, // Pogo Spring
/*Super Ring*/ { 0, 0 }, // Super Ring
/*Kitchen Sink*/ { 0, 0 }, // Kitchen Sink
/*Drop Target*/ { 0, 0 }, // Drop Target
/*Drop Target*/ { 2, 0 }, // Drop Target
/*Sneaker x2*/ { 0, 0 }, // Sneaker x2
/*Sneaker x3*/ { 1, 1 }, // Sneaker x3
/*Banana x3*/ { 1, 0 }, // Banana x3
/*Sneaker x3*/ { 0, 1 }, // Sneaker x3
/*Banana x3*/ { 0, 0 }, // Banana x3
/*Banana x10*/ { 1, 1 }, // Banana x10
/*Orbinaut x3*/ { 2, 0 }, // Orbinaut x3
/*Orbinaut x4*/ { 1, 1 }, // Orbinaut x4
/*Jawz x2*/ { 2, 1 } // Jawz x2
/*Jawz x2*/ { 5, 1 } // Jawz x2
};
#define DISTVAR (2048) // Magic number distance for use with item roulette tiers
@ -1775,17 +1775,20 @@ static void K_UpdateDraft(player_t *player)
draftdistance = FixedMul(draftdistance, K_GetKartGameSpeedScalar(gamespeed));
}
// On the contrary, the leniency period biases toward high weight.
// (See also: the leniency variable in K_SpawnDraftDust)
leniency = (3*TICRATE)/4 + ((player->kartweight-1) * (TICRATE/4));
minDist = 640 * player->mo->scale;
if (gametype == GT_BATTLE)
{
// TODO: gametyperules
minDist /= 4;
draftdistance *= 2;
leniency *= 4;
}
// On the contrary, the leniency period biases toward high weight.
// (See also: the leniency variable in K_SpawnDraftDust)
leniency = (3*TICRATE)/4 + ((player->kartweight-1) * (TICRATE/4));
// Not enough speed to draft.
if (player->speed >= 20*player->mo->scale)
{
@ -1865,6 +1868,13 @@ static void K_UpdateDraft(player_t *player)
// Double speed for the rival!
player->draftpower += add;
}
if (gametype == GT_BATTLE)
{
// TODO: gametyperules
// Double speed in Battle
player->draftpower += add;
}
}
if (player->draftpower > FRACUNIT)
@ -2967,7 +2977,10 @@ fixed_t K_GetSpindashChargeSpeed(player_t *player)
// more speed for higher weight & speed
// Tails = +6.25%, Fang = +20.31%, Mighty = +20.31%, Metal = +25%
// (can be higher than this value when overcharged)
return (player->kartspeed + player->kartweight) * (FRACUNIT/32);
const fixed_t val = (player->kartspeed + player->kartweight) * (FRACUNIT/32);
// TODO: gametyperules
return (gametype == GT_BATTLE) ? (4 * val) : val;
}
@ -3159,9 +3172,12 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower, boolean dorubberb
const boolean mobjValid = (player->mo != NULL && P_MobjWasRemoved(player->mo) == false);
fixed_t finalspeed = K_GetKartSpeedFromStat(player->kartspeed);
if (gametyperules & GTR_BUMPERS && player->bumpers <= 0)
finalspeed = 3 * finalspeed / 2;
if (player->spheres > 0)
{
fixed_t sphereAdd = (FRACUNIT/80); // 50% at max
fixed_t sphereAdd = (FRACUNIT/40); // 100% at max
finalspeed = FixedMul(finalspeed, FRACUNIT + (sphereAdd * player->spheres));
}
@ -3205,11 +3221,9 @@ fixed_t K_GetKartAccel(player_t *player)
k_accel += 17 * (9 - player->kartspeed); // 121 - 257
if (player->spheres > 0)
{
fixed_t sphereAdd = (FRACUNIT/10); // 500% at max
k_accel = FixedMul(k_accel, FRACUNIT + (sphereAdd * player->spheres));
}
// karma bomb gets 2x acceleration
if (gametype == GT_BATTLE && player->bumpers <= 0)
k_accel *= 2;
return FixedMul(k_accel, (FRACUNIT + player->accelboost) / 4);
}
@ -3804,6 +3818,8 @@ void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers)
if (player->bumpers > 0 && prevBumpers == 0)
{
K_DoInvincibility(player, 8 * TICRATE);
if (netgame)
{
CONS_Printf(M_GetText("%s is back in the game!\n"), player_names[player-players]);
@ -4725,6 +4741,9 @@ void K_SpawnDraftDust(mobj_t *mo)
{
UINT8 leniency = (3*TICRATE)/4 + ((mo->player->kartweight-1) * (TICRATE/4));
if (gametype == GT_BATTLE)
leniency *= 4;
ang = mo->player->drawangle;
if (mo->player->drift != 0)
@ -5738,6 +5757,30 @@ static void K_ThrowLandMine(player_t *player)
throwmo->movecount = 0; // above player
}
void K_DoInvincibility(player_t *player, tic_t time)
{
if (!player->invincibilitytimer)
{
mobj_t *overlay = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_INVULNFLASH);
P_SetTarget(&overlay->target, player->mo);
overlay->destscale = player->mo->scale;
P_SetScale(overlay, player->mo->scale);
}
player->invincibilitytimer += time;
if (P_IsLocalPlayer(player) == true)
{
S_ChangeMusicSpecial("kinvnc");
}
else //used to be "if (P_IsDisplayPlayer(player) == false)"
{
S_StartSound(player->mo, (cv_kartinvinsfx.value ? sfx_alarmi : sfx_kinvnc));
}
P_RestoreMusic(player);
}
void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source)
{
mobj_t *cachenext;
@ -8957,9 +9000,10 @@ static INT32 K_FlameShieldMax(player_t *player)
disttofinish = players[i].distancetofinish;
}
if (numplayers <= 1)
if (numplayers <= 1 || gametype == GT_BATTLE)
{
return 16; // max when alone, for testing
// and when in battle, for chaos
}
else if (player->position == 1)
{
@ -9198,8 +9242,14 @@ static void K_KartSpindash(player_t *player)
// if spindash was charged enough, give a small thrust.
if (player->spindash >= SPINDASHTHRUSTTIME)
{
fixed_t thrust = FixedMul(player->mo->scale, player->spindash*FRACUNIT/5);
// TODO: gametyperules
if (gametype == GT_BATTLE)
thrust *= 2;
// Give a bit of a boost depending on charge.
P_InstaThrust(player->mo, player->mo->angle, FixedMul(player->mo->scale, player->spindash*FRACUNIT/5));
P_InstaThrust(player->mo, player->mo->angle, thrust);
}
if (!player->tiregrease)
@ -9659,25 +9709,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
case KITEM_INVINCIBILITY:
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) // Doesn't hold your item slot hostage normally, so you're free to waste it if you have multiple
{
if (!player->invincibilitytimer)
{
mobj_t *overlay = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_INVULNFLASH);
P_SetTarget(&overlay->target, player->mo);
overlay->destscale = player->mo->scale;
P_SetScale(overlay, player->mo->scale);
}
player->invincibilitytimer += itemtime+(2*TICRATE); // 10 seconds
if (P_IsLocalPlayer(player) == true)
{
S_ChangeMusicSpecial("kinvnc");
}
else //used to be "if (P_IsDisplayPlayer(player) == false)"
{
S_StartSound(player->mo, (cv_kartinvinsfx.value ? sfx_alarmi : sfx_kinvnc));
}
P_RestoreMusic(player);
K_DoInvincibility(player, 10 * TICRATE);
K_PlayPowerGloatSound(player->mo);
player->itemamount--;
}
@ -9925,7 +9957,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->mo->destscale = FixedMul(player->mo->destscale, SHRINK_SCALE);
}
player->growshrinktimer = itemtime+(4*TICRATE); // 12 seconds
// TODO: gametyperules
player->growshrinktimer = (gametype == GT_BATTLE ? 8 : 12) * TICRATE;
if (player->invincibilitytimer > 0)
{
@ -10049,14 +10082,17 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if ((cmd->buttons & BT_ATTACK) && (player->pflags & PF_HOLDREADY))
{
// TODO: gametyperules
const INT32 incr = gametype == GT_BATTLE ? 4 : 2;
if (player->flamedash == 0)
{
S_StartSound(player->mo, sfx_s3k43);
K_PlayBoostTaunt(player->mo);
}
player->flamedash += 2;
player->flamemeter += 2;
player->flamedash += incr;
player->flamemeter += incr;
if (!onground)
{
@ -10083,8 +10119,12 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
{
player->pflags |= PF_HOLDREADY;
if (player->flamemeter > 0)
player->flamemeter--;
// TODO: gametyperules
if (gametype != GT_BATTLE || leveltime % 6 == 0)
{
if (player->flamemeter > 0)
player->flamemeter--;
}
if (player->flamelength > destlen)
{
@ -10113,9 +10153,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO && player->trickpanel == 0)
{
K_PlayBoostTaunt(player->mo);
K_DoPogoSpring(player->mo, 32<<FRACBITS, 2);
player->trickpanel = 1;
player->pflags |= PF_TRICKDELAY;
//K_DoPogoSpring(player->mo, 32<<FRACBITS, 2);
P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_POGOSPRING);
player->itemamount--;
}
break;

View file

@ -92,6 +92,7 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing,
void K_PuntMine(mobj_t *mine, mobj_t *punter);
void K_DoSneaker(player_t *player, INT32 type);
void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound);
void K_DoInvincibility(player_t *player, tic_t time);
void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source);
void K_UpdateHnextList(player_t *player, boolean clean);
void K_DropHnextList(player_t *player, boolean keepshields);

View file

@ -1833,7 +1833,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
boolean force = false;
INT32 laglength = 6;
INT32 kinvextend = 0;
if (objectplacing)
return false;
@ -2006,9 +2005,14 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
// Extend the invincibility if the hit was a direct hit.
if (inflictor == source && source->player->invincibilitytimer)
{
kinvextend = (source->player->invincibilitytimer)+5*TICRATE;
//CONS_Printf("extend k_invincibilitytimer for %s - old value %d new value %d\n", player_names[source->player - players], source->player->invincibilitytimer/TICRATE, kinvextend/TICRATE);
source->player->invincibilitytimer = kinvextend;
tic_t kinvextend;
if (gametype == GT_BATTLE)
kinvextend = 2*TICRATE;
else
kinvextend = 5*TICRATE;
source->player->invincibilitytimer += kinvextend;
}
K_PlayHitEmSound(source, target);

View file

@ -298,6 +298,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
UINT16 starcolor = (spring->info->painchance % numskincolors);
fixed_t savemomx = 0;
fixed_t savemomy = 0;
statenum_t raisestate = spring->info->raisestate;
// Object was already sprung this tic
if (object->eflags & MFE_SPRUNG)
@ -409,8 +410,6 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
// Re-solidify
spring->flags |= (spring->info->flags & (MF_SPRING|MF_SPECIAL));
P_SetMobjState(spring, spring->info->raisestate);
if (object->player)
{
if (spring->flags & MF_ENEMY) // Spring shells
@ -441,8 +440,37 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
{
object->player->tiregrease = greasetics;
}
if (spring->type == MT_POGOSPRING)
{
if (spring->reactiontime == 0)
{
object->player->tricktime = 0; // Reset post-hitlag timer
// Setup the boost for potential upwards trick, at worse, make it your regular max speed. (boost = curr speed*1.25)
object->player->trickboostpower = max(FixedDiv(object->player->speed, K_GetKartSpeed(object->player, false, false)) - FRACUNIT, 0)*125/100;
//CONS_Printf("Got boost: %d%\n", mo->player->trickboostpower*100 / FRACUNIT);
object->player->trickpanel = 1;
object->player->pflags |= PF_TRICKDELAY;
}
else
{
raisestate = spring->info->seestate;
object->player->tumbleBounces = 1;
object->player->pflags &= ~PF_TUMBLESOUND;
object->player->tumbleHeight = 50;
P_SetPlayerMobjState(object->player->mo, S_KART_SPINOUT);
// FIXME: try to compensate tumbling gravity
object->momz = 3 * object->momz / 2;
}
spring->reactiontime++;
}
}
P_SetMobjState(spring, raisestate);
return true;
}

View file

@ -9763,6 +9763,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing)
case MT_BLUESPHERE:
case MT_EMERALD:
case MT_ITEMCAPSULE:
case MT_POGOSPRING:
thing->shadowscale = FRACUNIT/2;
break;
case MT_DRIFTCLIP:
@ -10013,6 +10014,11 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
mobj->color = BALLOONCOLORS[P_RandomKey(sizeof(BALLOONCOLORS))];
}
break;
case MT_POGOSPRING:
P_SetScale(mobj, (mobj->destscale = 3 * mobj->destscale / 2));
mobj->color = SKINCOLOR_SUNSLAM;
mobj->colorized = true;
break;
case MT_KART_LEFTOVER:
mobj->color = SKINCOLOR_RED;
break;
@ -13602,9 +13608,6 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo
newmobj->old_z2 = mobj->old_z2 + zofs;
}
newmobj->destscale = mobj->destscale;
P_SetScale(newmobj, mobj->scale);
newmobj->old_x2 = mobj->old_x2 + xofs;
newmobj->old_y2 = mobj->old_y2 + yofs;
newmobj->old_x = mobj->old_x + xofs;

View file

@ -1102,6 +1102,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"kstart", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Sonic Adventure shwing!
{"typri1", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // SA2 boss typewriting 1
{"typri2", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // SA2 final boss-type typewriting
{"eggspr", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Sonic Unleashed Trap Spring
// SRB2Kart - Drop target sounds
{"kdtrg1", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Low energy, SF_X8AWAYSOUND

View file

@ -1166,6 +1166,7 @@ typedef enum
sfx_kstart,
sfx_typri1,
sfx_typri2,
sfx_eggspr,
// SRB2Kart - Drop target sounds
sfx_kdtrg1,