diff --git a/src/d_main.cpp b/src/d_main.cpp index 0feac0c38..a160c8577 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -95,7 +95,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 diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 67d3a13d2..a08b606a9 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -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); diff --git a/src/d_player.h b/src/d_player.h index 3421fa63b..1f593acc7 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -157,6 +157,7 @@ typedef enum KSHIELD_THUNDER = 1, KSHIELD_BUBBLE = 2, KSHIELD_FLAME = 3, + KSHIELD_ATTRACTION = 4, NUMKARTSHIELDS } kartshields_t; diff --git a/src/deh_tables.c b/src/deh_tables.c index bf06d47d5..e172647af 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -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 diff --git a/src/info/mobjs.h b/src/info/mobjs.h index a7e4a6fcb..2dd2aaca6 100644 --- a/src/info/mobjs.h +++ b/src/info/mobjs.h @@ -617,6 +617,7 @@ _(SPBEXPLOSION) _(THUNDERSHIELD) // Shields _(BUBBLESHIELD) _(FLAMESHIELD) +_(ATTRACTIONSHIELD) _(BUBBLESHIELDTRAP) _(BUBBLESHIELD_DEBRIS) diff --git a/src/k_collide.c b/src/k_collide.c index 2df3c9214..a222b2103 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -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); diff --git a/src/k_items.c b/src/k_items.c index c543f8d93..6b296c9cf 100644 --- a/src/k_items.c +++ b/src/k_items.c @@ -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); diff --git a/src/k_kart.c b/src/k_kart.c index d321bbb9f..f5abc82ab 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -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; diff --git a/src/p_mobj.c b/src/p_mobj.c index 8a2b5760e..eb6dcdb95 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -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: