Merge branch 'battle-unfuck-xiv-special' into 'master'

BATTLE UNFUCK XIV SPECIAL

Closes #866, #849, #847, #853, #856, #861, #850, #863, and #864

See merge request KartKrew/Kart!1790
This commit is contained in:
Oni 2024-01-07 08:49:46 +00:00
commit db421b68e8
11 changed files with 85 additions and 33 deletions

View file

@ -788,6 +788,8 @@ consvar_t cv_votetime = UnsavedNetVar("votetime", "20").min_max(10, 3600);
// Cheats don't save...
//
consvar_t cv_barriertime = OnlineCheat("barriertime", "30").values(CV_Natural).description("How long it takes for the Barrier to shrink in Battle Overtime");
consvar_t cv_battlespawn = OnlineCheat("battlespawn", "0").values(CV_Unsigned).description("Spawn every player at the same spawnpoint in Battle (0 = random spawns)");
consvar_t cv_battletest = OnlineCheat("battletest", "Off").on_off().description("Free Play goes to Battle instead of Prisons");
#ifdef DEVELOP

View file

@ -2603,12 +2603,22 @@ mapthing_t *G_FindBattleStart(INT32 playernum)
if (numdmstarts)
{
for (j = 0; j < 64; j++)
extern consvar_t cv_battlespawn;
if (cv_battlespawn.value)
{
i = P_RandomKey(PR_PLAYERSTARTS, numdmstarts);
if (G_CheckSpot(playernum, deathmatchstarts[i]))
i = cv_battlespawn.value - 1;
if (i < numdmstarts)
return deathmatchstarts[i];
}
else
{
for (j = 0; j < 64; j++)
{
i = P_RandomKey(PR_PLAYERSTARTS, numdmstarts);
if (G_CheckSpot(playernum, deathmatchstarts[i]))
return deathmatchstarts[i];
}
}
if (doprints)
CONS_Alert(CONS_WARNING, M_GetText("Could not spawn at any Deathmatch starts!\n"));
return NULL;

View file

@ -4166,7 +4166,7 @@ state_t states[NUMSTATES] =
//{SPR_ICAP, FF_FLOORSPRITE|5, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_INSIDE
{SPR_NULL, 0, 1, {NULL}, 6, 1, S_SPAWNSTATE}, // S_MONITOR_DAMAGE
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_MONITOR_DEATH
{SPR_NULL, 0, 50, {NULL}, 0, 0, S_NULL}, // S_MONITOR_DEATH
{SPR_IMON, FF_PAPERSPRITE|1, 1, {NULL}, 3, 1, S_MONITOR_SCREEN1B}, // S_MONITOR_SCREEN1A
{SPR_IMON, FF_PAPERSPRITE|0, 1, {NULL}, 3, 1, S_MONITOR_SCREEN2A}, // S_MONITOR_SCREEN1B
{SPR_IMON, FF_PAPERSPRITE|2, 1, {NULL}, 3, 1, S_MONITOR_SCREEN2B}, // S_MONITOR_SCREEN2A

View file

@ -150,7 +150,7 @@ void K_CheckBumpers(void)
}
}
if (numingame <= 2 && battleovertime.enabled && battleovertime.radius <= BARRIER_MIN_RADIUS)
if (numingame - eliminated <= 2 && battleovertime.enabled && battleovertime.radius <= BARRIER_MIN_RADIUS)
{
Music_Stop("battle_overtime");
S_StartSound(NULL, sfx_kc4b); // Loud noise helps mask transition
@ -383,7 +383,7 @@ void K_RunPaperItemSpawners(void)
return;
}
if (leveltime == g_battleufo.due)
if (leveltime == g_battleufo.due && overtime == false)
{
Obj_SpawnBattleUFOFromSpawner();
}
@ -722,8 +722,9 @@ void K_RunBattleOvertime(void)
if (battleovertime.radius > minradius)
{
extern consvar_t cv_barriertime;
tic_t t = leveltime - battleovertime.start;
const tic_t duration = 30*TICRATE;
const tic_t duration = cv_barriertime.value * TICRATE;
battleovertime.radius = Easing_OutSine(min(t, duration) * FRACUNIT / duration, battleovertime.initial_radius, minradius);
}

View file

@ -858,7 +858,9 @@ boolean K_InstaWhipCollide(mobj_t *shield, mobj_t *victim)
angle_t thrangle = R_PointToAngle2(victim->x, victim->y, shield->x, shield->y);
attacker->momx = attacker->momy = 0;
P_Thrust(attacker, thrangle, FRACUNIT*7);
P_Thrust(attacker, thrangle, mapobjectscale*7);
P_DamageMobj(attacker, victim, victim, 1, DMG_TUMBLE);
// A little extra juice, so successful reads are usually positive or zero on spheres.
victimPlayer->spheres = std::min(victimPlayer->spheres + 10, 40);
@ -875,14 +877,14 @@ boolean K_InstaWhipCollide(mobj_t *shield, mobj_t *victim)
attackerPlayer->flashing = 0;
// Localized broly for a local event.
if (mobj_t *broly = Obj_SpawnBrolyKi(victim, victimHitlag))
if (mobj_t *broly = Obj_SpawnBrolyKi(victim, victimHitlag/2))
{
broly->extravalue2 = 16*mapobjectscale;
}
P_PlayVictorySound(victim);
P_DamageMobj(attacker, victim, victim, 1, DMG_STING);
P_DamageMobj(attacker, victim, victim, 1, DMG_TUMBLE);
S_StartSound(victim, sfx_mbv92);
K_AddHitLag(attacker, victimHitlag, true);
@ -890,9 +892,6 @@ boolean K_InstaWhipCollide(mobj_t *shield, mobj_t *victim)
K_DoPowerClash(shield, victim); // REJECTED
attacker->hitlag = victimHitlag; // No, seriously, we do not care about K_AddHitLag's idea of a normal maximum
shield->hitlag = attacker->hitlag;
shield->extravalue2 = 1;
return true;

View file

@ -33,9 +33,9 @@ namespace
enum class Visibility
{
kHidden,
kVisible,
kTransparent,
kFlicker,
};
struct TargetTracking
@ -280,31 +280,29 @@ bool is_object_tracking_target(const mobj_t* mobj)
return is_player_tracking_target() && Obj_MonitorGetEmerald(mobj) != 0;
case MT_SUPER_FLICKY:
return Obj_IsSuperFlickyTargettingYou(mobj, stplyr->mo);
return Obj_IsSuperFlickyWhippable(mobj, stplyr->mo);
case MT_SPRAYCAN:
return !(mobj->renderflags & (RF_TRANSMASK | RF_DONTDRAW)); // the spraycan wasn't collected yet
return !(mobj->renderflags & (RF_TRANSMASK | RF_DONTDRAW)) && // the spraycan wasn't collected yet
P_CheckSight(stplyr->mo, const_cast<mobj_t*>(mobj));
default:
return false;
}
}
Visibility is_object_visible(mobj_t* mobj)
Visibility is_object_visible(const mobj_t* mobj)
{
switch (mobj->type)
{
case MT_SPRAYCAN:
case MT_SUPER_FLICKY:
// Always flickers.
return (leveltime & 1) ? Visibility::kVisible : Visibility::kHidden;
case MT_SPRAYCAN:
// Flickers, but only when visible.
return P_CheckSight(stplyr->mo, mobj) && (leveltime & 1) ? Visibility::kVisible : Visibility::kHidden;
return Visibility::kFlicker;
default:
// Transparent when not visible.
return P_CheckSight(stplyr->mo, mobj) ? Visibility::kVisible : Visibility::kTransparent;
return P_CheckSight(stplyr->mo, const_cast<mobj_t*>(mobj)) ? Visibility::kVisible : Visibility::kTransparent;
}
}
@ -312,7 +310,7 @@ void K_DrawTargetTracking(const TargetTracking& target)
{
Visibility visibility = is_object_visible(target.mobj);
if (visibility == Visibility::kHidden)
if (visibility == Visibility::kFlicker && (leveltime & 1))
{
return;
}

View file

@ -3471,7 +3471,7 @@ fixed_t K_GetKartSpeed(const player_t *player, boolean doboostpower, boolean dor
if (player->spheres > 0)
{
fixed_t sphereAdd = (FRACUNIT/40); // 100% at max
fixed_t sphereAdd = (FRACUNIT/60); // 66% at max
finalspeed = FixedMul(finalspeed, FRACUNIT + (sphereAdd * player->spheres));
}
@ -3552,7 +3552,7 @@ UINT16 K_GetKartFlashing(const player_t *player)
if (gametyperules & GTR_BUMPERS)
{
return 1;
return 0;
}
if (player == NULL)
@ -3831,7 +3831,11 @@ void K_DoGuardBreak(mobj_t *t1, mobj_t *t2) {
S_StartSound(t1, sfx_gbrk);
K_AddHitLag(t1, 24, true);
P_DamageMobj(t1, t2, t2, 1, DMG_STING);
angle_t thrangle = R_PointToAngle2(t1->x, t1->y, t2->x, t2->y);
P_Thrust(t1, thrangle, 7*mapobjectscale);
P_DamageMobj(t1, t2, t2, 1, DMG_TUMBLE);
clash = P_SpawnMobj((t1->x/2) + (t2->x/2), (t1->y/2) + (t2->y/2), (t1->z/2) + (t2->z/2), MT_GUARDBREAK);
@ -8446,12 +8450,16 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
if (player->spheredigestion == 0)
{
player->spheres--;
if (player->spheres > 5)
player->spheres--;
player->spheredigestion = spheredigestion;
}
if (K_PlayerGuard(player) && !K_PowerUpRemaining(player, POWERUP_BARRIER) && (player->ebrakefor%6 == 0))
player->spheres--;
if (player->instaWhipCharge && !K_PowerUpRemaining(players, POWERUP_BADGE) && leveltime%6 == 0)
player->spheres--;
}
else
{
@ -8694,6 +8702,14 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
if (player->justbumped > 0)
player->justbumped--;
if (K_PressingEBrake(player) == true && onground)
{
if (gametyperules & GTR_BUMPERS)
player->instaWhipCooldown = INSTAWHIP_DROPGUARD; // Delay whip out of spindash and guard.
else
player->instaWhipCharge = 0; // Not that important in race, avoid black flash.
}
if (player->instaWhipCooldown)
{
player->instaWhipCharge = 0;
@ -11568,9 +11584,18 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (K_PowerUpRemaining(player, POWERUP_BADGE))
{
if (P_PlayerInPain(player))
{
releasedwhip = false;
player->instaWhipCharge = 0;
}
else
{
releasedwhip = (ATTACK_IS_DOWN && player->rings <= 0 && player->itemflags & IF_USERINGS);
player->instaWhipCharge = INSTAWHIP_CHARGETIME;
}
chargingwhip = false;
releasedwhip = (ATTACK_IS_DOWN && player->rings <= 0);
player->instaWhipCharge = INSTAWHIP_CHARGETIME;
player->instaWhipCooldown = 0;
}

View file

@ -8,6 +8,7 @@
#include "../k_battle.h"
#include "../m_random.h"
#include "../r_main.h"
#include "../s_sound.h"
#define FINE90 (FINEANGLES/4)
#define FINE180 (FINEANGLES/2)
@ -664,7 +665,8 @@ Obj_MonitorOnDamage
monitor_rammingspeed(monitor) = inflictor
? FixedDiv(FixedHypot(inflictor->momx, inflictor->momy), 4 * inflictor->radius) : 0;
monitor->hitlag =
6 * get_damage_multiplier(monitor) / FRACUNIT;
3 * get_damage_multiplier(monitor) / FRACUNIT;
S_StartSound(monitor, sfx_kc40);
}
void
@ -707,6 +709,8 @@ Obj_MonitorOnDeath (mobj_t *monitor)
spawn_monitor_explosion(monitor);
S_StartSound(monitor, sfx_gshcc);
// There is hitlag from being damaged, so remove
// tangibility RIGHT NOW.
monitor->flags &= ~(MF_SOLID);

View file

@ -147,6 +147,10 @@ void Obj_RandomItemVisuals(mobj_t *mobj)
boolean Obj_RandomItemSpawnIn(mobj_t *mobj)
{
// battleprisons isn't set in time to do this on spawn. GROAN
if ((mobj->flags2 & MF2_BOSSFLEE) && (gametyperules & GTR_BUMPERS) && !battleprisons)
mobj->renderflags |= RF_DONTDRAW;
if ((leveltime == starttime) && !(gametyperules & GTR_CIRCUIT) && (mobj->flags2 & MF2_BOSSFLEE)) // here on map start?
{
if (gametyperules & GTR_PAPERITEMS)

View file

@ -3211,7 +3211,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
source->player->invincibilitytimer += kinvextend;
// This has a scaling boost type now, don't let it get too crazy
source->player->invincibilitytimer = max(source->player->invincibilitytimer, 20*TICRATE);
source->player->invincibilitytimer = min(source->player->invincibilitytimer, 20*TICRATE);
if (P_IsDisplayPlayer(source->player))
S_StartSound(NULL, sfx_gsha7);
@ -3329,7 +3329,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
}
if (gametyperules & GTR_BUMPERS)
player->spheres = min(player->spheres + 5, 40);
player->spheres = min(player->spheres + 10, 40);
if ((hardhit == true) || cv_kartdebughuddrop.value)
{
@ -3411,6 +3411,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (source && source->player && target)
G_GhostAddHit((INT32) (source->player - players), target);
if ((gametyperules & GTR_BUMPERS) && !battleprisons)
laglength /= 2;
K_SetHitLagForObjects(target, inflictor, source, laglength, true);
target->flags2 |= MF2_ALREADYHIT;

View file

@ -50,6 +50,7 @@
#include "acs/interface.h"
#include "m_easing.h"
#include "music.h"
#include "k_battle.h" // battleprisons
// Not sure if this is necessary, but it was in w_wad.c, so I'm putting it here too -Shadow Hog
#include <errno.h>
@ -9517,6 +9518,11 @@ void P_DoQuakeOffset(UINT8 view, mappoint_t *viewPos, mappoint_t *offset)
addZ = -addZ;
}
if ((gametyperules & GTR_PRISONS) && !battleprisons)
{
addZ /= 2;
}
if (cv_screenshake.value == 1) // Half
{
addZ /= 2;