Merge branch 'next' into roundqueue

This commit is contained in:
NepDisk 2026-03-27 21:01:47 -04:00
commit 50bbd3c561
12 changed files with 171 additions and 45 deletions

View file

@ -94,7 +94,7 @@
#define ASSET_HASH_TEXTURES_KART 0xb4211b2f32b6a291
#define ASSET_HASH_CHARS_KART 0x1e68a3e01aa5c68b
#define ASSET_HASH_MAPS_KART 0x38558ed00da41ce9
#define ASSET_HASH_MAIN_PK3 0x049b68caee0ba709
#define ASSET_HASH_MAIN_PK3 0x28ffde2e8c416914
#define ASSET_HASH_MAPPATCH_PK3 0x1745690024efbaf8
#define ASSET_HASH_BONUSCHARS_KART 0x60e6f13d822a7461
#ifdef USE_PATCH_FILE

View file

@ -546,6 +546,15 @@ consvar_t cv_kartstacking_flame_accelboost = CVAR_INIT ("vanillaboost_flame_acce
consvar_t cv_kartstacking_flame_handleboost = CVAR_INIT ("vanillaboost_flame_handleboost", "0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_flame_stackable = CVAR_INIT ("vanillaboost_flame_stackable", "On", CV_NETVAR|CV_GUARD, CV_OnOff, NULL);
consvar_t cv_kartstacking_attraction_speedboost_himin = CVAR_INIT ("vanillaboost_attraction_speedboost_himin", "0.5", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_attraction_speedboost_himax = CVAR_INIT ("vanillaboost_attraction_speedboost_himax", "0.6", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_attraction_speedboost_normmin = CVAR_INIT ("vanillaboost_attraction_speedboost_normmin", "0.25", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_attraction_speedboost_normmax = CVAR_INIT ("vanillaboost_attraction_speedboost_normmax", "0.3", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_attraction_accelboost_hi = CVAR_INIT ("vanillaboost_attraction_accelboost_hi", "10.0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_attraction_accelboost_norm = CVAR_INIT ("vanillaboost_attraction_accelboost_norm", "4.0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_attraction_handleboost = CVAR_INIT ("vanillaboost_sttraction_handleboost", "0.25", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_attraction_stackable = CVAR_INIT ("vanillaboost_sttraction_stackable", "On", CV_NETVAR|CV_GUARD, CV_OnOff, NULL);
consvar_t cv_kartstacking_start_speedboost = CVAR_INIT ("vanillaboost_start_speedboost", "0.25", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_start_accelboost = CVAR_INIT ("vanillaboost_start_accelboost", "6.0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_start_handleboost = CVAR_INIT ("vanillaboost_start_handleboost", "0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);

View file

@ -134,6 +134,15 @@ extern consvar_t cv_kartstacking_flame_accelboost;
extern consvar_t cv_kartstacking_flame_handleboost;
extern consvar_t cv_kartstacking_flame_stackable;
extern consvar_t cv_kartstacking_attraction_speedboost_himin;
extern consvar_t cv_kartstacking_attraction_speedboost_himax;
extern consvar_t cv_kartstacking_attraction_speedboost_normmin;
extern consvar_t cv_kartstacking_attraction_speedboost_normmax;
extern consvar_t cv_kartstacking_attraction_accelboost_hi;
extern consvar_t cv_kartstacking_attraction_accelboost_norm;
extern consvar_t cv_kartstacking_attraction_handleboost;
extern consvar_t cv_kartstacking_attraction_stackable;
extern consvar_t cv_kartstacking_grow_speedboost;
extern consvar_t cv_kartstacking_grow_accelboost;
extern consvar_t cv_kartstacking_grow_handleboost;

View file

@ -1472,31 +1472,37 @@ fixed_t localshakinessfac[MAXSPLITSCREENPLAYERS];
vector3_t localsmoothedaccel[MAXSPLITSCREENPLAYERS];
vector3_t localgravityvectors[MAXSPLITSCREENPLAYERS];
// the time it takes in our acceleration smoothing for 'A' to get halfway to 'B'
#define SmoothingHalfTime (0.025)
// thresholds of trust for accel shakiness. less shakiness = more trust
#define ShakinessMaxThreshold (80*FRACUNIT/100)
#define ShakinessMaxThreshold (50*FRACUNIT/100)
#define ShakinessMinThreshold (32*FRACUNIT/100)
// when we trust the accel a lot (the controller is "still"), how quickly do we correct our gravity vector?
#define CorrectionStillRate (FRACUNIT)
// when we don't trust the accel (the controller is "shaky"), how quickly do we correct our gravity vector?
#define CorrectionShakyRate (FRACUNIT/8)
// if our old gravity vector is close enough to our new one, limit further corrections to this proportion of the rotation speed
#define CorrectionGyroFactor (FRACUNIT/5)
#define CorrectionGyroFactor (FRACUNIT/4)
// thresholds for what's considered "close enough"
#define CorrectionGyroMinThreshold (2*FRACUNIT/100)
#define CorrectionGyroMaxThreshold (FRACUNIT/4)
#define CorrectionGyroMinThreshold (5*FRACUNIT/100)
#define CorrectionGyroMaxThreshold (FRACUNIT/3)
// no matter what, always apply a minimum of this much correction to our gravity vector
#define CorrectionMinimumSpeed (9*FRACUNIT/100)
#define CorrectionMinimumSpeed (10*FRACUNIT/100)
void G_UpdateGamepadGravity(INT32 p, vector3_t gyro, vector3_t accel)
{
// convert gyro input to reverse rotation
const fixed_t smoothFactor = 800*FRACUNIT/1000;
vector3_t invAccel = {-accel.x, -accel.y, -accel.z};
fixed_t gravCorrectionRate = 0;
// scaling is reversed, smaller time scales = larger steps in this code
// (1/timescale)/dt
fixed_t deltaseconds = FixedDiv(FRACUNIT, max(cv_timescale.value, FRACUNIT/20))/TICRATE;
// we don't have exp2 and we actually need it here to take timescale into account :(
fixed_t smoothFactor = FloatToFixed(exp2(-FixedToFloat(deltaseconds) / SmoothingHalfTime));
fixed_t angleRate;
fixed_t correctionLimit;
vector4_t invRotation = AngleAxis(
FixedMul(FV3_Length(&gyro), FRACUNIT/TICRATE),
FixedMul(FV3_Length(&gyro), deltaseconds),
-gyro.x,
-gyro.y,
-gyro.z
@ -1556,9 +1562,9 @@ void G_UpdateGamepadGravity(INT32 p, vector3_t gyro, vector3_t accel)
CONS_Debug(DBG_IMU, "Correction Rate: %4.2f\n", FixedToFloat(gravCorrectionRate));
FV3_Load(&correction,
FixedMul(gravityToAccel.x, gravCorrectionRate/TICRATE),
FixedMul(gravityToAccel.y, gravCorrectionRate/TICRATE),
FixedMul(gravityToAccel.z, gravCorrectionRate/TICRATE)
FixedMul(gravityToAccel.x, FixedMul(deltaseconds, gravCorrectionRate)),
FixedMul(gravityToAccel.y, FixedMul(deltaseconds, gravCorrectionRate)),
FixedMul(gravityToAccel.z, FixedMul(deltaseconds, gravCorrectionRate))
);
if (FV3_LengthSquared(&correction) < FV3_LengthSquared(&gravityToAccel))
{

View file

@ -154,7 +154,8 @@ typedef enum
} motionsensortype_e;
#define MAXGAMEPADTILT (50*FRACUNIT/100)
#define ACCELEROMETERGRAVITY ((fixed_t)(9.80665f * ((float)FRACUNIT)))
// #define ACCELEROMETERGRAVITY ((fixed_t)(9.80665f * ((float)FRACUNIT)))
#define ACCELEROMETERGRAVITY 642688
#define GAMEPADSHAKETHRESHOLD (UINT8_MAX/2)
#define TILTTOSTICKEASE 6
boolean G_GetGamepadCanUseTilt(INT32 p);

View file

@ -301,6 +301,12 @@ void K_DisplayItemTimers(void)
{qche("K_TIFLMS")},
1,
},
{ // attractionshield
"attractionshield",
stplyr->attractionattack,
{qche("K_TIATTR")},
1,
},
};
// insert sortable timers

View file

@ -1206,6 +1206,20 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
return true;
}
// Attraction Shield tackle damage
t1Condition = (t1->player->attractionattack && t1->player->attractionattack_hipower);
t2Condition = (t2->player->attractionattack && t2->player->attractionattack_hipower);
if (t1Condition == true && t2Condition == false)
{
P_DamageMobj(t2, t1, t1, 1, DMG_FLIPOVER);
return true;
}
else if (t1Condition == false && t2Condition == true)
{
P_DamageMobj(t1, t2, t2, 1, DMG_FLIPOVER);
return true;
}
// Battle Mode Sneaker and Bubble damage
// (Pogo Spring damage is handled in head-stomping code)
if (gametypes[gametype]->rules & GTR_BUMPERS)

View file

@ -1533,6 +1533,20 @@ static void K_drawKartItem(void)
}
else if (stplyr->attractioncharge > 0)
{
if (leveltime & 2)
{
if (stplyr->attractioncharge >= ATTRACTIONCHARGETIME)
{
colormode = TC_BLINK;
localcolor = SKINCOLOR_WHITE;
}
localpatch = K_GetCachedItemPatch(KITEM_THUNDERSHIELD, tiny, 0);
}
else
{
localpatch = kp_nodraw;
}
itembar = FixedDiv(stplyr->attractioncharge, ATTRACTIONCHARGETIME);
}
else if (stplyr->bricktimer > 0)

View file

@ -1928,16 +1928,6 @@ void K_DoAttractionShield(player_t *player, boolean hipower)
mo->color = SKINCOLOR_CYAN;
mo->scale = player->mo->scale*3 + (player->mo->scale/2);
// spawn horizontal bolts;
for (i=0; i<7; i++)
{
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_THOK);
mo->angle = P_RandomRange(0, 359)*ANG1;
mo->fuse = P_RandomRange(20, 50);
P_SetTarget(&mo->target, player->mo);
P_SetMobjState(mo, S_KLIT1);
}
// spawn the radius thing:
an = ANGLE_22h;
for (i=0; i<15; i++)
@ -2336,6 +2326,11 @@ void K_PlayerItemThink(player_t *player, boolean onground)
K_PlayAttackTaunt(player->mo);
K_UpdateHnextList(player, false);
K_BotResetItemConfirm(player, false);
if (player->itemamount <= 0)
{
player->itemflags &= ~IF_SEEKING;
}
}
break;
case KITEM_MINE:

View file

@ -340,6 +340,15 @@ void K_RegisterKartStuff(void)
CV_RegisterVar(&cv_kartstacking_flame_handleboost);
CV_RegisterVar(&cv_kartstacking_flame_stackable);
CV_RegisterVar(&cv_kartstacking_attraction_speedboost_himin);
CV_RegisterVar(&cv_kartstacking_attraction_speedboost_himax);
CV_RegisterVar(&cv_kartstacking_attraction_speedboost_normmin);
CV_RegisterVar(&cv_kartstacking_attraction_speedboost_normmax);
CV_RegisterVar(&cv_kartstacking_attraction_accelboost_hi);
CV_RegisterVar(&cv_kartstacking_attraction_accelboost_norm);
CV_RegisterVar(&cv_kartstacking_attraction_handleboost);
CV_RegisterVar(&cv_kartstacking_attraction_stackable);
CV_RegisterVar(&cv_kartstacking_start_speedboost);
CV_RegisterVar(&cv_kartstacking_start_accelboost);
CV_RegisterVar(&cv_kartstacking_start_handleboost);
@ -2921,7 +2930,7 @@ static void K_GetKartBoostPower(player_t *player)
if (player->attractionboost)
{
K_DoBoost(player, player->attractionboost, (player->attractionattack_hipower) ? 3*FRACUNIT : FRACUNIT, FRACUNIT/4, true, false); // + ???% top speed, + 300% acceleration
K_DoBoost(player, player->attractionboost, (player->attractionattack_hipower) ? ATTRACTIONACCELHI : ATTRACTIONACCELNORM, ATTRACTIONHANDLEBOOST, ATTRACTIONSTACKABLE, false); // + ???% top speed, + 300% acceleration
}
if (player->slopeboost || player->slopeaccel)
@ -8034,7 +8043,6 @@ void K_KartPlayerAfterThink(player_t *player)
{
player->attractionboost = 0;
player->attractionattack_hipower = false;
player->itemflags &= ~(IF_SEEKING|IF_PASSIVESEEKING);
}
}
@ -11786,9 +11794,11 @@ boolean K_NullDriftTiltEnabled(void)
}
#define TargetThreshold (80*FRACUNIT/100)
#define TargetAngleAssist (FRACUNIT/2)
void K_KartAttractHomingAttack(player_t *player)
{
fixed_t influence = 0;
fixed_t angleassist = 0;
INT32 lastTarg = player->lastitemtarget;
if (lastTarg >= 0)
@ -11801,10 +11811,25 @@ void K_KartAttractHomingAttack(player_t *player)
mobj_t *targMo = players[lastTarg].mo;
vector2_t targetdirection = {targMo->x - player->mo->x, targMo->y - player->mo->y};
vector2_t movedirection = {P_ReturnThrustX(NULL, player->mo->angle, FRACUNIT), P_ReturnThrustY(NULL, player->mo->angle, FRACUNIT)};
fixed_t targetangle = AngleFixed(R_PointToAngle2(player->mo->x + player->mo->momx, player->mo->y + player->mo->momy, targMo->x + targMo->momx, targMo->y + targMo->momy));
FV2_Normalize(&movedirection);
FV2_Normalize(&targetdirection);
influence = FixedDiv(CLAMP(FV2_Dot(&movedirection, &targetdirection), 0, TargetThreshold), TargetThreshold);
influence = FixedDiv(CLAMP(FV2_Dot(&targetdirection, &movedirection), 0, TargetThreshold), TargetThreshold);
if (FV2_Dot(&targetdirection, &movedirection) > 0)
{
angleassist = (targetangle - AngleFixed(player->mo->angle));
if (angleassist < -180*FRACUNIT)
{
angleassist += 360*FRACUNIT;
}
else if (angleassist > 180*FRACUNIT)
{
angleassist -= 360*FRACUNIT;
}
angleassist = FixedMul(CLAMP(angleassist, -TargetAngleAssist, TargetAngleAssist), influence);
}
}
}
@ -11813,28 +11838,48 @@ void K_KartAttractHomingAttack(player_t *player)
&& player->bumpUnstuck == 0)
{
mobj_t *mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_THOK);
mo->angle = P_RandomRange(-30, 30)*ANG1 + R_PointToAngle2(0,0, player->mo->momx, player->mo->momy) - ANGLE_180;
angle_t effectangle = player->mo->angle;
if (player->speed > 0)
{
effectangle = R_PointToAngle2(0,0, player->mo->momx, player->mo->momy);
}
mo->angle = P_RandomRange(-30, 30)*ANG1 + (effectangle - ANGLE_180);
mo->fuse = P_RandomRange(10, 20);
P_SetScale(mo, player->mo->scale);
mo->destscale = mo->scale/2;
P_SetScale(mo, player->mo->scale/2);
mo->destscale = mo->scale/3;
P_SetTarget(&mo->target, player->mo);
P_SetMobjState(mo, S_KLIT1);
mo->renderflags |= RF_ADD|RF_FULLBRIGHT;
P_SpawnGhostMobj(player->mo);
mo->renderflags |= RF_ADD|RF_FULLBRIGHT|RF_TRANS50;
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_THOK);
P_SetMobjState(mo, S_KSPARK1);
mo->renderflags |= RF_ADD|RF_FULLBRIGHT|RF_TRANS30;
P_SpawnGhostMobj(player->mo);
if (player->attractionattack_hipower)
if (player->attractionattack_hipower && lastTarg >= 0)
{
player->attractionboost = Easing_InCubic(influence, 50*FRACUNIT/100, 60*FRACUNIT/100);
player->attractionboost = Easing_InCubic(influence, ATTRACTIONSPEEDHIMIN, ATTRACTIONSPEEDHIMAX);
}
else
{
player->attractionboost = Easing_InCubic(influence, 25*FRACUNIT/100, 30*FRACUNIT/100);
player->attractionboost = Easing_InCubic(influence, ATTRACTIONSPEEDNORMMIN, ATTRACTIONSPEEDNORMMAX);
}
if (angleassist)
{
player->mo->angle += FixedAngle(angleassist);
P_SetPlayerAngle(player, player->mo->angle);
}
player->attractionattack--;
}
else
{
player->attractionattack = 0;
}
if (player->attractionattack <= 0)
{
player->attractionattack = 0;
player->attractionattack_hipower = false;

View file

@ -139,6 +139,15 @@ extern vector3_t clusterpoint, clusterdtf;
#define FLAMEHANDLEBOOST CV_Get(&cv_kartstacking_flame_handleboost)
#define FLAMESTACKABLE CV_Get(&cv_kartstacking_flame_stackable)
#define ATTRACTIONSPEEDHIMIN CV_Get(&cv_kartstacking_attraction_speedboost_himin)
#define ATTRACTIONSPEEDHIMAX CV_Get(&cv_kartstacking_attraction_speedboost_himax)
#define ATTRACTIONSPEEDNORMMIN CV_Get(&cv_kartstacking_attraction_speedboost_normmin)
#define ATTRACTIONSPEEDNORMMAX CV_Get(&cv_kartstacking_attraction_speedboost_normmax)
#define ATTRACTIONACCELHI CV_Get(&cv_kartstacking_attraction_accelboost_hi)
#define ATTRACTIONACCELNORM CV_Get(&cv_kartstacking_attraction_accelboost_norm)
#define ATTRACTIONHANDLEBOOST CV_Get(&cv_kartstacking_attraction_handleboost)
#define ATTRACTIONSTACKABLE CV_Get(&cv_kartstacking_attraction_stackable)
#define ALTSHRINKTIME CV_Get(&cv_kartaltshrinktime)
#define SHRINKSPEEDBOOST CV_Get(&cv_kartstacking_altshrink_speedboost)
#define SHRINKACCELBOOST CV_Get(&cv_kartstacking_altshrink_accelboost)

View file

@ -24,6 +24,7 @@
#include "st_stuff.h"
#include "hu_stuff.h"
#include "lua_hook.h"
#include "lua_script.h" // lua_compatmode
#include "m_cond.h" // unlockables, emblems, etc
#include "p_setup.h"
#include "m_cheat.h" // objectplace
@ -2041,21 +2042,38 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
// Determines what ShouldX Hook's status should be used.
static UINT8 P_ShouldHookDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype)
{
UINT8 shouldDamage = LUA_HookShouldDamage(target, inflictor, source, damage, damagetype);
UINT8 shouldSpin = LUA_HookShouldSpin(target, inflictor, source, damage, damagetype);
UINT8 shouldExplode = LUA_HookShouldExplode(target, inflictor, source, damage, damagetype);
UINT8 shouldSquish = LUA_HookShouldSquish(target, inflictor, source, damage, damagetype);
boolean targetisplayer = false;
const boolean killer = (damagetype & DMG_DEATHMASK);
INT32 use_damage = damage;
if (target && (!P_MobjWasRemoved(target)) && target->player)
{
targetisplayer = true;
}
if (lua_compatmode && targetisplayer && killer)
{
// Before the introduction of dedicated damage types, this magic number was used to kill players.
use_damage = 10000;
}
UINT8 shouldDamage = LUA_HookShouldDamage(target, inflictor, source, use_damage, damagetype);
UINT8 shouldSpin = LUA_HookShouldSpin(target, inflictor, source, use_damage, damagetype);
UINT8 shouldExplode = LUA_HookShouldExplode(target, inflictor, source, use_damage, damagetype);
UINT8 shouldSquish = LUA_HookShouldSquish(target, inflictor, source, use_damage, damagetype);
UINT8 status;
const UINT8 type = (damagetype & DMG_TYPEMASK);
status = shouldDamage;
if (shouldSpin > 0 && ((type == DMG_NORMAL) || (type == DMG_WIPEOUT) || (type == DMG_FLIPOVER)))
status = shouldSpin;
else if (shouldExplode > 0 && ((type == DMG_EXPLODE) || (type == DMG_KARMA)))
status = shouldExplode;
else if (shouldSquish > 0 && (type == DMG_SQUISH))
status = shouldSquish;
if (!killer)
{
if (shouldSpin > 0 && ((type == DMG_NORMAL) || (type == DMG_WIPEOUT) || (type == DMG_FLIPOVER)))
status = shouldSpin;
else if (shouldExplode > 0 && ((type == DMG_EXPLODE) || (type == DMG_KARMA)))
status = shouldExplode;
else if (shouldSquish > 0 && (type == DMG_SQUISH))
status = shouldSquish;
}
return status;
}