Merge branch 'next' into rridport

This commit is contained in:
NepDisk 2026-03-30 18:02:00 -04:00
commit 12a2e13a58
10 changed files with 112 additions and 74 deletions

View file

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

View file

@ -546,14 +546,14 @@ 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_himin = CVAR_INIT ("vanillaboost_attraction_speedboost_himin", "0.60", 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.75", 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_attraction_accelboost_hi = CVAR_INIT ("vanillaboost_attraction_accelboost_hi", "16.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", "8.0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_attraction_handleboost = CVAR_INIT ("vanillaboost_attraction_handleboost", "0.50", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
consvar_t cv_kartstacking_attraction_stackable = CVAR_INIT ("vanillaboost_attraction_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);

View file

@ -157,6 +157,7 @@ typedef enum
KSHIELD_THUNDER = 1,
KSHIELD_BUBBLE = 2,
KSHIELD_FLAME = 3,
KSHIELD_ATTRACTION = 4,
NUMKARTSHIELDS
} kartshields_t;

View file

@ -1586,6 +1586,7 @@ struct int_const_s const INT_CONST[] = {
{"KSHIELD_LIGHTNING",KSHIELD_THUNDER},
{"KSHIELD_BUBBLE",KSHIELD_BUBBLE},
{"KSHIELD_FLAME",KSHIELD_FLAME},
{"KSHIELD_ATTRACTION",KSHIELD_ATTRACTION},
{"NUMKARTSHIELDS",NUMKARTSHIELDS},
// kartitemequip_e

View file

@ -617,6 +617,7 @@ _(SPBEXPLOSION)
_(THUNDERSHIELD) // Shields
_(BUBBLESHIELD)
_(FLAMESHIELD)
_(ATTRACTIONSHIELD)
_(BUBBLESHIELDTRAP)
_(BUBBLESHIELD_DEBRIS)

View file

@ -818,8 +818,7 @@ static boolean K_BubbleReflectingTrapItem(const mobj_t *t)
static boolean K_StrongPlayerBump(const player_t *player)
{
return ((player->invincibilitytimer)
|| (player->growshrinktimer > 0)
|| (player->attractionattack));
|| (player->growshrinktimer > 0));
}
boolean K_BubbleShieldReflect(mobj_t *t1, mobj_t *t2)
@ -867,7 +866,11 @@ boolean K_BubbleShieldReflect(mobj_t *t1, mobj_t *t2)
else if (t2->player->attractionattack)
{
// trolled
t2->player->attractioncharge = 0;
t2->player->attractionattack = 0;
t2->player->attractionattack_hipower = 0;
t2->player->attractionboost = 0;
t2->player->itemflags &= ~(IF_SEEKING|IF_PASSIVESEEKING);
}
S_StartSound(t1, sfx_s3k44);
@ -1207,8 +1210,9 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
}
// Attraction Shield tackle damage
t1Condition = (t1->player->attractionattack && t1->player->attractionattack_hipower);
t2Condition = (t2->player->attractionattack && t2->player->attractionattack_hipower);
// players with Bubble Shield equipped are protected
t1Condition = (t1->player->attractionattack && t1->player->attractionattack_hipower && (K_GetShieldFromPlayer(t2->player) != KSHIELD_BUBBLE));
t2Condition = (t2->player->attractionattack && t2->player->attractionattack_hipower && (K_GetShieldFromPlayer(t1->player) != KSHIELD_BUBBLE));
if (t1Condition == true && t2Condition == false)
{
P_DamageMobj(t2, t1, t1, 1, DMG_FLIPOVER);

View file

@ -2436,28 +2436,28 @@ void K_PlayerItemThink(player_t *player, boolean onground)
}
break;
case KITEM_THUNDERSHIELD:
if (K_GetShieldFromPlayer(player) != KSHIELD_THUNDER)
{
mobj_t *shield = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_THUNDERSHIELD);
P_SetScale(shield, (shield->destscale = (5*shield->destscale)>>2));
P_SetTarget(&shield->target, player->mo);
P_SetTarget(&player->shieldtracer, shield);
S_StartSound(player->mo, sfx_s3k41);
}
if (K_IsKartItemAlternate(KITEM_THUNDERSHIELD))
{
if (K_GetShieldFromPlayer(player) != KSHIELD_ATTRACTION)
{
mobj_t *shield = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_ATTRACTIONSHIELD);
P_SetScale(shield, (shield->destscale = (5*shield->destscale)>>2));
P_SetTarget(&shield->target, player->mo);
P_SetTarget(&player->shieldtracer, shield);
S_StartSound(player->mo, sfx_attrsg);
}
if (!HOLDING_ITEM && NO_HYUDORO)
{
if (buttons & BT_ATTACK)
if (buttons & BT_ATTACK &&
((player->itemflags & IF_HOLDREADY) || player->attractioncharge > 0))
{
fixed_t effectscale = 75*player->mo->scale/100;
if (player->itemflags & IF_HOLDREADY)
if (player->attractioncharge == 0)
{
S_StartSound(player->mo, sfx_vwre);
}
player->itemflags &= ~IF_HOLDREADY;
if (player->attractioncharge >= ATTRACTIONCHARGETIME)
{
@ -2470,7 +2470,7 @@ void K_PlayerItemThink(player_t *player, boolean onground)
{
S_StopSoundByID(player->mo, sfx_vwre);
}
player->itemflags |= (IF_SEEKING|IF_PASSIVESEEKING);
player->itemflags |= IF_SEEKING;
player->bananadrag += 4;
}
else
@ -2537,13 +2537,30 @@ void K_PlayerItemThink(player_t *player, boolean onground)
player->itemflags |= (IF_SEEKING|IF_PASSIVESEEKING);
}
player->itemflags |= IF_HOLDREADY;
player->attractioncharge = 0;
}
if (buttons & BT_ATTACK || player->attractioncharge > 0)
{
player->itemflags &= ~IF_HOLDREADY;
}
else
{
player->itemflags |= IF_HOLDREADY;
}
}
}
else
{
if (K_GetShieldFromPlayer(player) != KSHIELD_THUNDER)
{
mobj_t *shield = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_THUNDERSHIELD);
P_SetScale(shield, (shield->destscale = (5*shield->destscale)>>2));
P_SetTarget(&shield->target, player->mo);
P_SetTarget(&player->shieldtracer, shield);
S_StartSound(player->mo, sfx_s3k41);
}
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO)
{
K_DoThunderShield(player);

View file

@ -784,6 +784,14 @@ static void K_SetPlayerBumped(player_t *player, mobj_t *comparemobj)
// Play a distinct "crack!" noise to clue the player in.
S_StartSound(player->mo, sfx_s3k6e);
}
if (comparemobj->player != NULL && comparemobj->player->attractionattack)
{
comparemobj->player->attractionattack = 0;
comparemobj->player->attractionattack_hipower = 0;
comparemobj->player->attractionboost = 0;
comparemobj->player->itemflags &= ~(IF_SEEKING|IF_PASSIVESEEKING);
}
}
else if (pshield == KSHIELD_NONE)
{
@ -5465,25 +5473,19 @@ void K_PopPlayerShield(player_t *player)
switch (shield)
{
case KSHIELD_THUNDER:
if (K_IsKartItemAlternate(KITEM_THUNDERSHIELD))
{
if (player->attractioncharge >= ATTRACTIONCHARGETIME)
{
K_DoThunderShield(player);
}
else
{
player->mo->momz += 4*mapobjectscale*P_MobjFlip(player->mo);
player->mo->z += player->mo->momz;
}
}
else
{
K_DoThunderShield(player);
}
K_DoThunderShield(player);
player->itemtype = KITEM_NONE;
player->itemamount = 0;
break;
case KSHIELD_ATTRACTION:
K_DoAttractionShield(player, false);
player->itemtype = KITEM_NONE;
player->itemamount = 0;
player->attractioncharge = 0;
player->attractionattack = 0;
player->attractionattack_hipower = 0;
player->attractionboost = 0;
player->itemflags &= ~(IF_SEEKING|IF_PASSIVESEEKING);
break;
case KSHIELD_BUBBLE:
K_BreakBubbleShield(player);
@ -10842,6 +10844,7 @@ INT32 K_GetShieldFromPlayer(const player_t *player)
switch (player->shieldtracer->type)
{
case MT_THUNDERSHIELD: return KSHIELD_THUNDER;
case MT_ATTRACTIONSHIELD: return KSHIELD_ATTRACTION;
case MT_BUBBLESHIELD: return KSHIELD_BUBBLE;
case MT_FLAMESHIELD: return KSHIELD_FLAME;
default: return KSHIELD_NONE;
@ -10852,7 +10855,10 @@ INT32 K_GetShieldFromItem(INT32 item)
{
switch (item)
{
case KITEM_THUNDERSHIELD: return KSHIELD_THUNDER;
case KITEM_THUNDERSHIELD:
{
return K_IsKartItemAlternate(KITEM_THUNDERSHIELD) ? KSHIELD_ATTRACTION : KSHIELD_THUNDER;
}
case KITEM_BUBBLESHIELD: return KSHIELD_BUBBLE;
case KITEM_FLAMESHIELD: return KSHIELD_FLAME;
default: return KSHIELD_NONE;

View file

@ -9224,6 +9224,27 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
break;
}
case MT_ATTRACTIONSHIELD:
{
if (!mobj->target || !mobj->target->health || !mobj->target->player
|| K_GetShieldFromPlayer(mobj->target->player) != KSHIELD_ATTRACTION)
{
P_RemoveMobj(mobj);
return false;
}
P_SetScale(mobj, (mobj->destscale = (5*mobj->target->scale)>>2));
// Don't sloperoll Shields
mobj->pitch = 0;
mobj->roll = 0;
mobj->slopepitch = 0;
mobj->sloperoll = 0;
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
break;
}
case MT_BUBBLESHIELD:
{
const player_t *player = P_MobjWasRemoved(mobj->target) ? NULL : mobj->target->player;
@ -11021,6 +11042,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing)
case MT_THUNDERSHIELD:
case MT_BUBBLESHIELD:
case MT_FLAMESHIELD:
case MT_ATTRACTIONSHIELD:
case MT_BLUEFRUIT:
case MT_ORANGEFRUIT:
case MT_REDFRUIT:

View file

@ -924,45 +924,31 @@ static void P_NetSyncParties(savebuffer_t *save)
TracyCZoneEnd(__zone);
}
static void P_NetArchiveRoundQueue(savebuffer_t *save)
static void P_NetSyncRoundQueue(savebuffer_t *save)
{
UINT8 i;
WRITEUINT32(save->p, ARCHIVEBLOCK_ROUNDQUEUE);
WRITEUINT8(save->p, roundqueue.position);
WRITEUINT8(save->p, roundqueue.size);
WRITEUINT8(save->p, roundqueue.roundnum);
if (P_SyncUINT32(save, ARCHIVEBLOCK_ROUNDQUEUE) != ARCHIVEBLOCK_ROUNDQUEUE)
I_Error("Bad $$$.sav at archive block RoundQueue");
if (!save->write)
memset(&roundqueue, 0, sizeof(struct roundqueue));
SYNC(roundqueue.position);
SYNC(roundqueue.size);
SYNC(roundqueue.roundnum);
for (i = 0; i < roundqueue.size; i++)
{
//WRITEUINT16(save->p, roundqueue.entries[i].mapnum);
//SYNC(roundqueue.entries[i].mapnum);
/* NOPE! Clients do not need to know what is in the roundqueue.
* This disincentivises cheaty clients in future tournament environments.
* ~toast 080423 */
WRITEUINT8(save->p, roundqueue.entries[i].gametype);
WRITEUINT8(save->p, (UINT8)roundqueue.entries[i].encore);
WRITEUINT8(save->p, (UINT8)roundqueue.entries[i].rankrestricted);
}
}
static void P_NetUnArchiveRoundQueue(savebuffer_t *save)
{
UINT8 i;
if (READUINT32(save->p) != ARCHIVEBLOCK_ROUNDQUEUE)
I_Error("Bad $$$.sav at archive block RoundQueue");
memset(&roundqueue, 0, sizeof(struct roundqueue));
roundqueue.position = READUINT8(save->p);
roundqueue.size = READUINT8(save->p);
roundqueue.roundnum = READUINT8(save->p);
for (i = 0; i < roundqueue.size; i++)
{
roundqueue.entries[i].mapnum = 0; // TEST RUN -- dummy, has to be < nummapheaders
roundqueue.entries[i].gametype = READUINT8(save->p);
roundqueue.entries[i].encore = (boolean)READUINT8(save->p);
roundqueue.entries[i].rankrestricted = (boolean)READUINT8(save->p);
if (!save->write)
roundqueue.entries[i].mapnum = 0; // TEST RUN -- dummy, has to be < nummapheaders
SYNC(roundqueue.entries[i].gametype);
SYNCBOOLEAN(roundqueue.entries[i].encore);
SYNCBOOLEAN(roundqueue.entries[i].rankrestricted);
}
}
@ -4608,7 +4594,7 @@ void P_SaveNetGame(savebuffer_t *save, boolean resending)
P_NetSyncPlayers(save);
P_NetSyncParties(save);
P_NetArchiveRoundQueue(save);
P_NetSyncRoundQueue(save);
if (gamestate == GS_LEVEL)
{
@ -4661,7 +4647,7 @@ boolean P_LoadNetGame(savebuffer_t *save, boolean reloading)
return false;
P_NetSyncPlayers(save);
P_NetSyncParties(save);
P_NetUnArchiveRoundQueue(save);
P_NetSyncRoundQueue(save);
if (gamestate == GS_LEVEL)
{