From 70310eaed61f978d88ecb03e3de7a41336e5edbd Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 27 Mar 2023 03:21:50 -0700 Subject: [PATCH 1/4] Rename k_collide.c to k_collide.cpp --- src/CMakeLists.txt | 2 +- src/{k_collide.c => k_collide.cpp} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/{k_collide.c => k_collide.cpp} (99%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d7f4c7705..042ccda03 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -112,7 +112,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32 lua_hudlib_drawlist.c k_kart.c k_respawn.c - k_collide.c + k_collide.cpp k_color.c k_race.c k_battle.c diff --git a/src/k_collide.c b/src/k_collide.cpp similarity index 99% rename from src/k_collide.c rename to src/k_collide.cpp index 5d089c67f..1debfd0c1 100644 --- a/src/k_collide.c +++ b/src/k_collide.cpp @@ -1,4 +1,4 @@ -/// \file k_collide.c +/// \file k_collide.cpp /// \brief SRB2Kart item collision hooks #include "k_collide.h" From 022e6ed5fa6185f3bba4edd0d7191b79c9012ceb Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 27 Mar 2023 03:21:58 -0700 Subject: [PATCH 2/4] player_t: change pflags type to UINT32 Avoids invalid conversion compiler errors when using bitwise operators on pflags from C++ code. --- src/d_player.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_player.h b/src/d_player.h index c343a5701..e362687fb 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -457,7 +457,7 @@ struct player_t // Bit flags. // See pflags_t, above. - pflags_t pflags; + UINT32 pflags; // playing animation. panim_t panim; From b1f0cca51989c783423b7ef17ca31f9b9ee2351f Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 27 Mar 2023 04:42:52 -0700 Subject: [PATCH 3/4] k_collide.cpp: refactor K_PvPTouchDamage to deduplicate code --- src/k_collide.cpp | 153 +++++++++++++++++++++++----------------------- 1 file changed, 78 insertions(+), 75 deletions(-) diff --git a/src/k_collide.cpp b/src/k_collide.cpp index 1debfd0c1..bcdb0d556 100644 --- a/src/k_collide.cpp +++ b/src/k_collide.cpp @@ -845,11 +845,6 @@ boolean K_SMKIceBlockCollide(mobj_t *t1, mobj_t *t2) boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2) { - boolean t1Condition = false; - boolean t2Condition = false; - boolean stungT1 = false; - boolean stungT2 = false; - if (K_PodiumSequence() == true) { // Always regular bumps, no ring toss. @@ -857,49 +852,66 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2) } // Clash instead of damage if both parties have any of these conditions - t1Condition = (K_IsBigger(t1, t2) == true) - || (t1->player->invincibilitytimer > 0) - || (t1->player->flamedash > 0 && t1->player->itemtype == KITEM_FLAMESHIELD) - || (t1->player->curshield == KSHIELD_TOP && !K_IsHoldingDownTop(t1->player)); + auto canClash = [](mobj_t *t1, mobj_t *t2) + { + return (K_IsBigger(t1, t2) == true) + || (t1->player->invincibilitytimer > 0) + || (t1->player->flamedash > 0 && t1->player->itemtype == KITEM_FLAMESHIELD) + || (t1->player->curshield == KSHIELD_TOP && !K_IsHoldingDownTop(t1->player)); + }; - t2Condition = (K_IsBigger(t2, t1) == true) - || (t2->player->invincibilitytimer > 0) - || (t2->player->flamedash > 0 && t2->player->itemtype == KITEM_FLAMESHIELD) - || (t2->player->curshield == KSHIELD_TOP && !K_IsHoldingDownTop(t2->player)); - - if (t1Condition == true && t2Condition == true) + if (canClash(t1, t2) && canClash(t2, t1)) { K_DoPowerClash(t1->player, t2->player); return false; } - // Cause tumble on invincibility - t1Condition = (t1->player->invincibilitytimer > 0); - t2Condition = (t2->player->invincibilitytimer > 0); + auto forEither = [t1, t2](auto conditionCallable, auto damageCallable) + { + const bool t1Condition = conditionCallable(t1, t2); + const bool t2Condition = conditionCallable(t2, t1); - if (t1Condition == true && t2Condition == false) + if (t1Condition == true && t2Condition == false) + { + damageCallable(t1, t2); + return true; + } + else if (t1Condition == false && t2Condition == true) + { + damageCallable(t2, t1); + return true; + } + + return false; + }; + + auto doDamage = [](UINT8 damageType) { - P_DamageMobj(t2, t1, t1, 1, DMG_TUMBLE); - return true; - } - else if (t1Condition == false && t2Condition == true) + return [damageType](mobj_t *t1, mobj_t *t2) + { + P_DamageMobj(t2, t1, t1, 1, damageType); + }; + }; + + // Cause tumble on invincibility + auto shouldTumble = [](mobj_t *t1, mobj_t *t2) + { + return (t1->player->invincibilitytimer > 0); + }; + + if (forEither(shouldTumble, doDamage(DMG_TUMBLE))) { - P_DamageMobj(t1, t2, t2, 1, DMG_TUMBLE); return true; } // Flame Shield dash damage - t1Condition = (t1->player->flamedash > 0 && t1->player->itemtype == KITEM_FLAMESHIELD); - t2Condition = (t2->player->flamedash > 0 && t2->player->itemtype == KITEM_FLAMESHIELD); + auto shouldWipeout = [](mobj_t *t1, mobj_t *t2) + { + return (t1->player->flamedash > 0 && t1->player->itemtype == KITEM_FLAMESHIELD); + }; - if (t1Condition == true && t2Condition == false) + if (forEither(shouldWipeout, doDamage(DMG_WIPEOUT | DMG_WOMBO))) { - P_DamageMobj(t2, t1, t1, 1, DMG_WIPEOUT|DMG_WOMBO); - return true; - } - else if (t1Condition == false && t2Condition == true) - { - P_DamageMobj(t1, t2, t2, 1, DMG_WIPEOUT|DMG_WOMBO); return true; } @@ -907,75 +919,66 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2) // (Pogo Spring damage is handled in head-stomping code) if (gametyperules & GTR_BUMPERS) { - t1Condition = ((t1->player->sneakertimer > 0) - && !P_PlayerInPain(t1->player) - && (t1->player->flashing == 0)); - t2Condition = ((t2->player->sneakertimer > 0) - && !P_PlayerInPain(t2->player) - && (t2->player->flashing == 0)); + auto shouldSteal = [](mobj_t *t1, mobj_t *t2) + { + return ((t1->player->sneakertimer > 0) + && !P_PlayerInPain(t1->player) + && (t1->player->flashing == 0)); + }; - if (t1Condition == true && t2Condition == false) + if (forEither(shouldSteal, doDamage(DMG_WIPEOUT | DMG_STEAL | DMG_WOMBO))) { - P_DamageMobj(t2, t1, t1, 1, DMG_WIPEOUT|DMG_STEAL|DMG_WOMBO); - return true; - } - else if (t1Condition == false && t2Condition == true) - { - P_DamageMobj(t1, t2, t2, 1, DMG_WIPEOUT|DMG_STEAL|DMG_WOMBO); return true; } } // Cause stumble on scale difference - t1Condition = K_IsBigger(t1, t2); - t2Condition = K_IsBigger(t2, t1); + auto shouldStumble = [](mobj_t *t1, mobj_t *t2) + { + return K_IsBigger(t1, t2); + }; - if (t1Condition == true && t2Condition == false) + auto doStumble = [](mobj_t *t1, mobj_t *t2) { K_StumblePlayer(t2->player); - return true; - } - else if (t1Condition == false && t2Condition == true) + }; + + if (forEither(shouldStumble, doStumble)) { - K_StumblePlayer(t1->player); return true; } // Ring sting, this is a bit more unique - t1Condition = (K_GetShieldFromItem(t2->player->itemtype) == KSHIELD_NONE); - t2Condition = (K_GetShieldFromItem(t1->player->itemtype) == KSHIELD_NONE); - - if (t1Condition == true) + auto doSting = [](mobj_t *t1, mobj_t *t2) { + if (K_GetShieldFromItem(t2->player->itemtype) != KSHIELD_NONE) + { + return false; + } + + bool stung = false; + if (t2->player->rings <= 0) { P_DamageMobj(t2, t1, t1, 1, DMG_STING|DMG_WOMBO); - stungT2 = true; + stung = true; } P_PlayerRingBurst(t2->player, 1); - } - if (t2Condition == true) - { - if (t1->player->rings <= 0) - { - P_DamageMobj(t1, t2, t2, 1, DMG_STING|DMG_WOMBO); - stungT1 = true; - } - - P_PlayerRingBurst(t1->player, 1); - } + return stung; + }; // No damage hitlag for stinging. - if (stungT1 == true && stungT2 == false) - { - t2->eflags &= ~MFE_DAMAGEHITLAG; - } - else if (stungT2 == true && stungT1 == false) + auto removeDamageHitlag = [](mobj_t *t1, mobj_t *t2) { t1->eflags &= ~MFE_DAMAGEHITLAG; + }; + + if (forEither(doSting, removeDamageHitlag)) + { + return true; } - return (stungT1 || stungT2); + return false; } From cb963fe81ea9e12164eb8d981e6c8d2d171ad332 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 27 Mar 2023 04:54:37 -0700 Subject: [PATCH 4/4] Clash Bubble Shield blowup with Invincibility etc; bounce players away with Bubble blowup - K_BubbleShieldCollide now calls K_KartBouncing and K_PvPTouchDamage - Lets players get knocked around by Bubble blowup - Lets all clash conditions apply to Bubble blowup too - Bubble blowup now does wipeout damage --- src/k_collide.cpp | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/k_collide.cpp b/src/k_collide.cpp index bcdb0d556..671f3d19a 100644 --- a/src/k_collide.cpp +++ b/src/k_collide.cpp @@ -735,18 +735,13 @@ boolean K_BubbleShieldCollide(mobj_t *t1, mobj_t *t2) thing = oldthing; P_SetTarget(&tm.thing, oldtm.thing);*/ - if (P_PlayerInPain(t2->player) - || t2->player->flashing || t2->player->hyudorotimer - || t2->player->justbumped || K_IsBigger(t2, t1)) + if (K_KartBouncing(t2, t1->target) == true) { - return true; - } + if (t2->player && t1->target && t1->target->player) + { + K_PvPTouchDamage(t2, t1->target); + } - // Player Damage - P_DamageMobj(t2, t1->target, t1, 1, DMG_NORMAL|DMG_WOMBO); - - if (t2->player->timeshit > t2->player->timeshitprev) - { // Don't play from t1 else it gets cut out... for some reason. S_StartSound(t2, sfx_s3k44); } @@ -857,7 +852,8 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2) return (K_IsBigger(t1, t2) == true) || (t1->player->invincibilitytimer > 0) || (t1->player->flamedash > 0 && t1->player->itemtype == KITEM_FLAMESHIELD) - || (t1->player->curshield == KSHIELD_TOP && !K_IsHoldingDownTop(t1->player)); + || (t1->player->curshield == KSHIELD_TOP && !K_IsHoldingDownTop(t1->player)) + || (t1->player->bubbleblowup > 0); }; if (canClash(t1, t2) && canClash(t2, t1)) @@ -905,9 +901,11 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2) } // Flame Shield dash damage + // Bubble Shield blowup damage auto shouldWipeout = [](mobj_t *t1, mobj_t *t2) { - return (t1->player->flamedash > 0 && t1->player->itemtype == KITEM_FLAMESHIELD); + return (t1->player->flamedash > 0 && t1->player->itemtype == KITEM_FLAMESHIELD) + || (t1->player->bubbleblowup > 0); }; if (forEither(shouldWipeout, doDamage(DMG_WIPEOUT | DMG_WOMBO)))