diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 666c208c1..4bfe87f14 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -147,6 +147,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32 k_zvote.c k_mapuser.c k_powerup.cpp + k_hitlag.c ) if(SRB2_CONFIG_ENABLE_WEBM_MOVIES) diff --git a/src/deh_tables.c b/src/deh_tables.c index 78aaeca84..323bf3bc0 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4563,6 +4563,15 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_JANKSPARK3", "S_JANKSPARK4", + "S_HITLAG_1", + "S_HITLAG_2", + "S_HITLAG_3", + "S_HITLAG_4", + "S_HITLAG_5", + "S_HITLAG_6", + "S_HITLAG_8", + "S_HITLAG_9", + // Broly Ki Orb "S_BROLY1", "S_BROLY2", @@ -5394,6 +5403,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_DRIFTELECTRICITY", "MT_DRIFTELECTRICSPARK", "MT_JANKSPARK", + "MT_HITLAG", "MT_ROCKETSNEAKER", // Rocket sneakers diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 59aee511e..f40f21818 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -44,7 +44,7 @@ #include "hw_md2.h" // SRB2Kart -#include "../k_kart.h" // HITLAGJITTERS +#include "../k_hitlag.h" // HITLAGJITTERS #include "../r_fps.h" #include "../r_plane.h" // R_FlatDimensionsFromLumpSize diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 8772e152a..5720223a9 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -46,7 +46,7 @@ // SRB2Kart #include "../k_color.h" -#include "../k_kart.h" // HITLAGJITTERS +#include "../k_hitlag.h" // HITLAGJITTERS #include "../r_fps.h" #ifdef HAVE_PNG diff --git a/src/info.c b/src/info.c index 394f73f99..8a1f4e29e 100644 --- a/src/info.c +++ b/src/info.c @@ -573,6 +573,14 @@ char sprnames[NUMSPRITES + 1][5] = "DREL", // Drift electricity "DRES", // Drift electric sparks "JANK", // Stair janking sparks + "HFX1", // Hitlag stage 1 + "HFX2", // Hitlag stage 2 + "HFX3", // Hitlag stage 3 + "HFX4", // Hitlag stage 4 + "HFX5", // Hitlag stage 5 + "HFX6", // Hitlag stage 6 + "HFX8", // Hitlag stage 8 + "HFX9", // Hitlag stage 9 // Kart Items "RSHE", // Rocket sneaker @@ -5236,6 +5244,15 @@ state_t states[NUMSTATES] = {SPR_JANK, 0, 0, {A_SetCustomValue}, -1, 5, S_JANKSPARK4}, // S_JANKSPARK3 {SPR_JANK, 0, 0, {A_ChangeAngleRelative}, 180, 180, S_JANKSPARK2}, // S_JANKSPARK4 + {SPR_HFX1, FF_FULLBRIGHT|FF_PAPERSPRITE, 1, {NULL}, 0, 1, S_NULL}, // S_HITLAG_1 + {SPR_HFX2, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE, 2, {NULL}, 1, 1, S_NULL}, // S_HITLAG_2 + {SPR_HFX3, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE, 3, {NULL}, 2, 1, S_NULL}, // S_HITLAG_3 + {SPR_HFX4, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE, 4, {NULL}, 3, 1, S_NULL}, // S_HITLAG_4 + {SPR_HFX5, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE, 5, {NULL}, 4, 1, S_NULL}, // S_HITLAG_5 + {SPR_HFX6, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE, 6, {NULL}, 5, 1, S_NULL}, // S_HITLAG_6 + {SPR_HFX8, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE, 8, {NULL}, 7, 1, S_NULL}, // S_HITLAG_8 + {SPR_HFX9, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE, 9, {NULL}, 8, 1, S_NULL}, // S_HITLAG_9 + // Broly Ki Orb {SPR_LSSJ, FF_REVERSESUBTRACT|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_BROLY2}, // S_BROLY1 {SPR_NULL, 0, 5*TICRATE, {A_SSMineFlash}, 0, 0, S_NULL}, // S_BROLY2 @@ -23478,6 +23495,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_HITLAG + -1, // doomednum + S_HITLAG_1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 1, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + { // MT_ROCKETSNEAKER -1, // doomednum S_ROCKETSNEAKER_L, // spawnstate diff --git a/src/info.h b/src/info.h index f5f402566..c52ec8541 100644 --- a/src/info.h +++ b/src/info.h @@ -1124,6 +1124,14 @@ typedef enum sprite SPR_DREL, // Drift electricity SPR_DRES, // Drift electric sparks SPR_JANK, // Stair janking sparks + SPR_HFX1, // Hitlag stage 1 + SPR_HFX2, // Hitlag stage 2 + SPR_HFX3, // Hitlag stage 3 + SPR_HFX4, // Hitlag stage 4 + SPR_HFX5, // Hitlag stage 5 + SPR_HFX6, // Hitlag stage 6 + SPR_HFX8, // Hitlag stage 8 + SPR_HFX9, // Hitlag stage 9 // Kart Items SPR_RSHE, // Rocket sneaker @@ -5666,6 +5674,15 @@ typedef enum state S_JANKSPARK3, S_JANKSPARK4, + S_HITLAG_1, + S_HITLAG_2, + S_HITLAG_3, + S_HITLAG_4, + S_HITLAG_5, + S_HITLAG_6, + S_HITLAG_8, + S_HITLAG_9, + // Broly Ki Orb S_BROLY1, S_BROLY2, @@ -6516,6 +6533,7 @@ typedef enum mobj_type MT_DRIFTELECTRICITY, MT_DRIFTELECTRICSPARK, MT_JANKSPARK, + MT_HITLAG, MT_ROCKETSNEAKER, diff --git a/src/k_collide.cpp b/src/k_collide.cpp index ad780a044..2f65d1536 100644 --- a/src/k_collide.cpp +++ b/src/k_collide.cpp @@ -17,6 +17,7 @@ #include "k_roulette.h" #include "k_podium.h" #include "k_powerup.h" +#include "k_hitlag.h" angle_t K_GetCollideAngle(mobj_t *t1, mobj_t *t2) { @@ -423,7 +424,7 @@ boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2) { // Melt item S_StartSound(t2, sfx_s3k43); - K_SetHitLagForObjects(t2, t1, 3, false); + K_SetHitLagForObjects(t2, t1, t1->target, 3, false); } else { diff --git a/src/k_hitlag.c b/src/k_hitlag.c new file mode 100644 index 000000000..fd682c4c1 --- /dev/null +++ b/src/k_hitlag.c @@ -0,0 +1,268 @@ +// DR. ROBOTNIK'S RING RACERS +//----------------------------------------------------------------------------- +// Copyright (C) by Sally "TehRealSalt" Cochenour +// Copyright (C) by Kart Krew +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file k_hitlag.c +/// \brief Hitlag functions + +#include "k_hitlag.h" + +#include "doomdef.h" +#include "doomstat.h" +#include "k_kart.h" +#include "m_random.h" +#include "p_local.h" +#include "r_main.h" + +/*-------------------------------------------------- + void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage) + + See header file for description. +--------------------------------------------------*/ +void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage) +{ + if (mo == NULL || P_MobjWasRemoved(mo) || (mo->flags & MF_NOHITLAGFORME && mo->type != MT_PLAYER)) + { + return; + } + + mo->hitlag += tics; + mo->hitlag = min(mo->hitlag, MAXHITLAGTICS); + + if (mo->player != NULL) + { + // Reset each time. We want to explicitly set this for bananas afterwards, + // so make sure an old value doesn't possibly linger. + mo->player->flipDI = false; + } + + if (fromDamage == true) + { + // Dunno if this should flat-out &~ the flag out too. + // Decided it probably just just keep it since it's "adding" hitlag. + mo->eflags |= MFE_DAMAGEHITLAG; + } +} + +/*-------------------------------------------------- + static void K_SpawnSingleHitLagSpark( + mobj_t *parent, + vector3_t *offset, fixed_t scale, + UINT8 tics, UINT8 pause, + skincolornum_t color) + + Spawns a set of damage hitlag spark papersprites. + + Input Arguments:- + parent - Object that the hitlag was added to. + offset - Offset from the parent to spawn the spark. + scale - The scale of the spark. + tics - Which hitlag state to use. + pause - How long to wait before it displays. + color - The color of the damage source. + + Return:- + N/A +--------------------------------------------------*/ +static void K_SpawnSingleHitLagSpark( + mobj_t *parent, + vector3_t *offset, fixed_t scale, + UINT8 tics, UINT8 pause, + skincolornum_t color) +{ + INT32 i; + + if (tics == 0) + { + return; + } + + for (i = 0; i < 2; i++) + { + mobj_t *spark = P_SpawnMobj( + parent->x + offset->x, + parent->y + offset->y, + parent->z + offset->z, + MT_HITLAG + ); + P_SetMobjState(spark, spark->info->spawnstate + (tics - 1)); + P_SetTarget(&spark->target, parent); + + spark->destscale = scale; + P_SetScale(spark, scale); + + if (parent->eflags & MFE_VERTICALFLIP) + { + spark->eflags |= MFE_VERTICALFLIP; + spark->flags2 |= MF2_OBJECTFLIP; + spark->z = parent->z + parent->height - offset->z; + } + + spark->angle = R_PointToAngle2( + parent->x, parent->y, + spark->x, spark->y + ); + + if (i & 1) + { + spark->angle += ANGLE_90; + } + + if (pause > 0) + { + spark->hitlag = pause+1; // A little dumb, but hitlag is decremented on the same tic we spawn, so naively setting is off-by-one. + // spark->renderflags |= RF_DONTDRAW; // "Re-visible" behavior in P_MobjThinker, under a type check. (Currently unused.) + } + + if (color != SKINCOLOR_NONE) + { + spark->color = color; + spark->colorized = true; + } + + K_ReduceVFX(spark, NULL); + } +} + +/*-------------------------------------------------- + static void K_SpawnHitLagEFX(mobj_t *victim, mobj_t *inflictor, mobj_t *source, UINT8 tics) + + Spawns several hitlag sparks for damage. + + Input Arguments:- + victim - Object getting touched. + inflictor - Object touching the victim. May be NULL. + source - Object that inflictor came from. May be NULL or same as inflictor. + tics - How long the hitlag was. + + Return:- + N/A +--------------------------------------------------*/ +static void K_SpawnHitLagEFX(mobj_t *victim, mobj_t *inflictor, mobj_t *source, UINT8 tics) +{ + vector3_t offset = { 0, 0, 0 }; + fixed_t newScale = FRACUNIT; + UINT8 startTics = 0, endTics = 0; + skincolornum_t color = SKINCOLOR_NONE; + + I_Assert(P_MobjWasRemoved(victim) == false); + + P_StartQuakeFromMobj(tics, tics * 2 * mapobjectscale, 512 * mapobjectscale, victim); + + if (P_MobjWasRemoved(inflictor) == false) + { + offset.x = (inflictor->x - victim->x) / 2; + offset.y = (inflictor->y - victim->y) / 2; + offset.z = (P_GetMobjHead(inflictor) - P_GetMobjHead(victim)) / 2; + + newScale = (3 * (victim->destscale + inflictor->destscale) / 2); + } + else + { + offset.z = victim->height; + newScale = 3 * victim->destscale; + } + + if (P_MobjWasRemoved(source) == false) + { + color = (source->player != NULL) ? source->player->skincolor : source->color; + } + + // CONS_Printf("== HITLAG VFX START: endTics %d tics %d ==\n", endTics, tics); + + while (endTics < tics) + { + UINT8 particle = max(1, FixedMul((tics * FRACUNIT) + (FRACUNIT/2), FRACUNIT*2/3) / FRACUNIT); + + // CONS_Printf("trying particle %d\n", particle); + + if (particle > NUM_HITLAG_STATES) + { + particle = NUM_HITLAG_STATES; + // CONS_Printf("* corrected to %d (states - %d)\n", particle, NUM_HITLAG_STATES); + } + + UINT8 ticsLeft = tics - endTics; + // CONS_Printf("? ticsleft %d\n", ticsLeft); + + if (particle > ticsLeft) + { + particle = ticsLeft; + // CONS_Printf("* corrected to %d (ticsleft - %d)\n", particle, ticsLeft); + } + + // CONS_Printf("spawning, startTics %d\n", startTics); + + K_SpawnSingleHitLagSpark(victim, &offset, newScale, particle, startTics, color); + + startTics += max(1, FixedMul((particle * FRACUNIT) + (FRACUNIT/2), FRACUNIT/3) / FRACUNIT); + endTics += particle; + + offset.x += P_RandomRange(PR_DECORATION, -45, 45) * newScale; + offset.y += P_RandomRange(PR_DECORATION, -45, 45) * newScale; + offset.z += P_RandomRange(PR_DECORATION, -45, 45) * newScale; + + newScale = (newScale * 2) / 3; + + // CONS_Printf("next: startTics %d, endTics %d, tics %d, newScale %d\n", startTics, endTics, tics, newScale); + } +} + +/*-------------------------------------------------- + void K_SetHitLagForObjects(mobj_t *victim, mobj_t *inflictor, mobj_t *source, INT32 tics, boolean fromDamage) + + See header file for description. +--------------------------------------------------*/ +void K_SetHitLagForObjects(mobj_t *victim, mobj_t *inflictor, mobj_t *source, INT32 tics, boolean fromDamage) +{ + INT32 finalTics = tics; + + if (tics <= 0) + { + return; + } + + if (P_MobjWasRemoved(victim) == false && P_MobjWasRemoved(inflictor) == false) + { + const fixed_t speedTicFactor = (mapobjectscale * 8); + const INT32 angleTicFactor = ANGLE_22h; + + const fixed_t victimSpeed = FixedHypot(FixedHypot(victim->momx, victim->momy), victim->momz); + const fixed_t inflictorSpeed = FixedHypot(FixedHypot(inflictor->momx, inflictor->momy), inflictor->momz); + const fixed_t speedDiff = abs(inflictorSpeed - victimSpeed); + + const fixed_t scaleDiff = abs(inflictor->scale - victim->scale); + + angle_t victimAngle = K_MomentumAngle(victim); + angle_t inflictorAngle = K_MomentumAngle(inflictor); + INT32 angleDiff = 0; + + if (victimSpeed > 0 && inflictorSpeed > 0) + { + // If either object is completely not moving, their speed doesn't matter. + angleDiff = AngleDelta(victimAngle, inflictorAngle); + } + + // Add extra "damage" based on what was happening to the objects on impact. + finalTics += (FixedMul(speedDiff, FRACUNIT + scaleDiff) / speedTicFactor) + (angleDiff / angleTicFactor); + + // This shouldn't happen anymore, but just in case something funky happens. + if (finalTics < tics) + { + finalTics = tics; + } + } + + K_AddHitLag(victim, finalTics, fromDamage); + K_AddHitLag(inflictor, finalTics, false); // Don't use the damage property. + + if (P_MobjWasRemoved(victim) == false && fromDamage == true) + { + K_SpawnHitLagEFX(victim, inflictor, source, finalTics); + } +} diff --git a/src/k_hitlag.h b/src/k_hitlag.h new file mode 100644 index 000000000..02dedfc2a --- /dev/null +++ b/src/k_hitlag.h @@ -0,0 +1,68 @@ +// DR. ROBOTNIK'S RING RACERS +//----------------------------------------------------------------------------- +// Copyright (C) by Sally "TehRealSalt" Cochenour +// Copyright (C) by Kart Krew +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file k_hitlag.h +/// \brief Race Mode specific code. + +#ifndef __K_HITLAG__ +#define __K_HITLAG__ + +#include "doomtype.h" +#include "doomstat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAXHITLAGTICS (30) +#define HITLAGJITTERS (FRACUNIT / 20) +#define NUM_HITLAG_STATES (8) + +/*-------------------------------------------------- + void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage); + + Adds hitlag to an object. + + Input Arguments:- + mo - Object to add hitlag to. + tics - How much hitlag to add. + fromDamage - Whenever or not this was a damage interaction. + + Return:- + N/A +--------------------------------------------------*/ + +void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage); + + +/*-------------------------------------------------- + void K_SetHitLagForObjects(mobj_t *victim, mobj_t *inflictor, mobj_t *source, INT32 tics, boolean fromDamage); + + Sets the hitlag for two objects, victim and inflictor, + in a touch-related interaction (typically damage). + + Input Arguments:- + victim - Object getting touched. + inflictor - Object touching the victim. May be NULL. + source - Object that inflictor came from. May be NULL or same as inflictor. + tics - Minimum time for the hitlag to be. Can be increased if it is a damage interaction. + fromDamage - Whenever or not this was a damage interaction. + + Return:- + N/A +--------------------------------------------------*/ + +void K_SetHitLagForObjects(mobj_t *victim, mobj_t *inflictor, mobj_t *source, INT32 tics, boolean fromDamage); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // __K_HITLAG__ diff --git a/src/k_hud.c b/src/k_hud.c index bcd784306..660974a05 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -42,6 +42,7 @@ #include "k_bot.h" #include "k_rank.h" #include "g_party.h" +#include "k_hitlag.h" //{ Patch Definitions static patch_t *kp_nodraw; diff --git a/src/k_kart.c b/src/k_kart.c index 150b14ac3..31ee0be8e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -46,6 +46,7 @@ #include "k_roulette.h" #include "k_podium.h" #include "k_powerup.h" +#include "k_hitlag.h" // SOME IMPORTANT VARIABLES DEFINED IN DOOMDEF.H: // gamespeed is cc (0 for easy, 1 for normal, 2 for hard) @@ -3625,75 +3626,6 @@ angle_t K_MomentumAngleReal(const mobj_t *mo) } } -void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage) -{ - if (mo == NULL || P_MobjWasRemoved(mo) || (mo->flags & MF_NOHITLAGFORME && mo->type != MT_PLAYER)) - { - return; - } - - mo->hitlag += tics; - mo->hitlag = min(mo->hitlag, MAXHITLAGTICS); - - if (mo->player != NULL) - { - // Reset each time. We want to explicitly set this for bananas afterwards, - // so make sure an old value doesn't possibly linger. - mo->player->flipDI = false; - } - - if (fromDamage == true) - { - // Dunno if this should flat-out &~ the flag out too. - // Decided it probably just just keep it since it's "adding" hitlag. - mo->eflags |= MFE_DAMAGEHITLAG; - } -} - -void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics, boolean fromDamage) -{ - INT32 finalTics = tics; - - if (tics <= 0) - { - return; - } - - if ((mo1 && !P_MobjWasRemoved(mo1)) == true && (mo2 && !P_MobjWasRemoved(mo2)) == true) - { - const fixed_t speedTicFactor = (mapobjectscale * 8); - const INT32 angleTicFactor = ANGLE_22h; - - const fixed_t mo1speed = FixedHypot(FixedHypot(mo1->momx, mo1->momy), mo1->momz); - const fixed_t mo2speed = FixedHypot(FixedHypot(mo2->momx, mo2->momy), mo2->momz); - const fixed_t speedDiff = abs(mo2speed - mo1speed); - - const fixed_t scaleDiff = abs(mo2->scale - mo1->scale); - - angle_t mo1angle = K_MomentumAngleReal(mo1); - angle_t mo2angle = K_MomentumAngleReal(mo2); - INT32 angleDiff = 0; - - if (mo1speed > 0 && mo2speed > 0) - { - // If either object is completely not moving, their speed doesn't matter. - angleDiff = AngleDelta(mo1angle, mo2angle); - } - - // Add extra "damage" based on what was happening to the objects on impact. - finalTics += (FixedMul(speedDiff, FRACUNIT + scaleDiff) / speedTicFactor) + (angleDiff / angleTicFactor); - - // This shouldn't happen anymore, but just in case something funky happens. - if (finalTics < tics) - { - finalTics = tics; - } - } - - K_AddHitLag(mo1, finalTics, fromDamage); - K_AddHitLag(mo2, finalTics, false); // mo2 is the inflictor, so don't use the damage property. -} - void K_AwardPlayerRings(player_t *player, INT32 rings, boolean overload) { UINT16 superring; @@ -3957,7 +3889,6 @@ void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) player->mo->momz = K_TumbleZ(player->mo, player->tumbleHeight * FRACUNIT); P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); - P_StartQuakeFromMobj(10, 64 * player->mo->scale, 512 * player->mo->scale, player->mo); } angle_t K_StumbleSlope(angle_t angle, angle_t pitch, angle_t roll) @@ -3996,7 +3927,6 @@ void K_StumblePlayer(player_t *player) player->mo->momz = K_TumbleZ(player->mo, player->tumbleHeight * FRACUNIT); P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); - P_StartQuakeFromMobj(10, 64 * player->mo->scale, 512 * player->mo->scale, player->mo); // Reset slope. player->mo->pitch = player->mo->roll = 0; @@ -4471,7 +4401,6 @@ INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) // A player->mo->momz = (117 * player->mo->momz) / 200; P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); - P_StartQuakeFromMobj(5, 64 * player->mo->scale, 512 * player->mo->scale, player->mo); return ringburst; } @@ -5946,7 +5875,7 @@ void K_PuntMine(mobj_t *origMine, mobj_t *punter) mine->momy = punter->momy + FixedMul(FINESINE(fa >> ANGLETOFINESHIFT), spd); P_SetObjectMomZ(mine, z, false); - //K_SetHitLagForObjects(punter, mine, 5); + //K_SetHitLagForObjects(punter, mine, mine->target, 5); mine->flags &= ~(MF_NOCLIP|MF_NOCLIPTHING); } diff --git a/src/k_kart.h b/src/k_kart.h index ecf32b771..809c8673c 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -23,9 +23,6 @@ Make sure this matches the actual number of states */ #define KART_NUMINVSPARKLESANIM 12 -#define MAXHITLAGTICS 18 //12 -#define HITLAGJITTERS (FRACUNIT / 20) - #define GROW_SCALE (2*FRACUNIT) #define SHRINK_SCALE (FRACUNIT/2) @@ -92,8 +89,6 @@ void K_KartPlayerAfterThink(player_t *player); angle_t K_MomentumAngleEx(const mobj_t *mo, const fixed_t threshold); angle_t K_MomentumAngleReal(const mobj_t *mo); #define K_MomentumAngle(mo) K_MomentumAngleEx(mo, 6 * mo->scale) -void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage); -void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics, boolean fromDamage); void K_AwardPlayerRings(player_t *player, INT32 rings, boolean overload); void K_DoInstashield(player_t *player); void K_DoPowerClash(mobj_t *t1, mobj_t *t2); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 5e6db3967..6419572bc 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -37,6 +37,7 @@ #include "i_system.h" // I_GetPreciseTime, I_GetPrecisePrecision #include "hu_stuff.h" // for the cecho #include "k_powerup.h" +#include "k_hitlag.h" #include "lua_script.h" #include "lua_libs.h" diff --git a/src/objects/hyudoro.c b/src/objects/hyudoro.c index 24a902a78..4b104b9d0 100644 --- a/src/objects/hyudoro.c +++ b/src/objects/hyudoro.c @@ -21,6 +21,7 @@ #include "../r_main.h" #include "../s_sound.h" #include "../g_game.h" +#include "../k_hitlag.h" enum { HYU_PATROL, diff --git a/src/objects/ufo.c b/src/objects/ufo.c index ce994081b..a06c6021d 100644 --- a/src/objects/ufo.c +++ b/src/objects/ufo.c @@ -24,6 +24,7 @@ #include "../k_waypoint.h" #include "../k_specialstage.h" #include "../r_skins.h" +#include "../k_hitlag.h" #include "../acs/interface.h" #define UFO_BASE_SPEED (42 * FRACUNIT) // UFO's slowest speed. @@ -762,8 +763,6 @@ boolean Obj_SpecialUFODamage(mobj_t *ufo, mobj_t *inflictor, mobj_t *source, UIN const fixed_t addSpeed = FixedMul(UFO_DAMAGED_SPEED, K_GetKartGameSpeedScalar(gamespeed)); UINT8 damage = 1; - (void)source; - if (UFOEmeraldChase(ufo) == true) { // Damaged fully already, no need for any more. @@ -793,7 +792,7 @@ boolean Obj_SpecialUFODamage(mobj_t *ufo, mobj_t *inflictor, mobj_t *source, UIN ufo->health = max(1, ufo->health - damage); - K_SetHitLagForObjects(ufo, inflictor, (damage / 3) + 2, true); + K_SetHitLagForObjects(ufo, inflictor, source, (damage / 3) + 2, true); UFOCopyHitlagToPieces(ufo); if (ufo->health == 1) diff --git a/src/p_inter.c b/src/p_inter.c index dadc45fd9..edc48a28b 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -40,6 +40,7 @@ #include "k_objects.h" #include "k_roulette.h" #include "k_boss.h" +#include "k_hitlag.h" #include "acs/interface.h" #include "k_powerup.h" @@ -523,7 +524,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) firework->color = toucher->color; }*/ - K_SetHitLagForObjects(special, toucher, 2, true); + K_SetHitLagForObjects(special, toucher, toucher, 2, true); break; @@ -1151,7 +1152,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget P_ActivateThingSpecial(target, source); - //K_SetHitLagForObjects(target, inflictor, MAXHITLAGTICS, true); + //K_SetHitLagForObjects(target, inflictor, source, MAXHITLAGTICS, true); // SRB2kart // I wish I knew a better way to do this @@ -1983,8 +1984,6 @@ static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *sou static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 type) { - (void)source; - if (player->respawn.state != RESPAWNST_NONE) { K_DoInstashield(player); @@ -2057,7 +2056,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, } K_DropEmeraldsFromPlayer(player, player->emeralds); - K_SetHitLagForObjects(player->mo, inflictor, MAXHITLAGTICS, true); + K_SetHitLagForObjects(player->mo, inflictor, source, MAXHITLAGTICS, true); player->carry = CR_NONE; @@ -2351,7 +2350,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } laglength = max(laglength / 2, 1); - K_SetHitLagForObjects(target, inflictor, laglength, false); + K_SetHitLagForObjects(target, inflictor, source, laglength, false); AddNullHitlag(player, oldHitlag); AddNullHitlag(playerInflictor, oldHitlagInflictor); @@ -2415,7 +2414,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } else if (target->flags2 & MF2_ALREADYHIT) // do not deal extra damage in the same tic { - K_SetHitLagForObjects(target, inflictor, laglength, true); + K_SetHitLagForObjects(target, inflictor, source, laglength, true); return false; } } @@ -2545,7 +2544,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da ringburst = K_ExplodePlayer(player, inflictor, source); break; case DMG_WIPEOUT: - P_StartQuakeFromMobj(5, 32 * player->mo->scale, 512 * player->mo->scale, player->mo); K_SpinPlayer(player, inflictor, source, KSPIN_WIPEOUT); K_KartPainEnergyFling(player); break; @@ -2611,7 +2609,7 @@ 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); - K_SetHitLagForObjects(target, inflictor, laglength, true); + K_SetHitLagForObjects(target, inflictor, source, laglength, true); target->flags2 |= MF2_ALREADYHIT; @@ -2621,7 +2619,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return true; } - //K_SetHitLagForObjects(target, inflictor, laglength, true); + //K_SetHitLagForObjects(target, inflictor, source, laglength, true); if (!player) { diff --git a/src/p_mobj.c b/src/p_mobj.c index 39c7710f7..0c02af316 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9909,6 +9909,14 @@ void P_MobjThinker(mobj_t *mobj) K_HandleDirectionalInfluence(mobj->player); } + // Hitlag VFX "stagger" behavior. + // Oni likes the look better if all sparks visibly hold on their 1st frame, + // but if we ever reverse course, this is here. + /* + if (mobj->type == MT_HITLAG && mobj->hitlag == 0) + mobj->renderflags &= ~RF_DONTDRAW; + */ + return; } diff --git a/src/r_things.c b/src/r_things.c index 4d1c17263..d10c402a3 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -46,7 +46,7 @@ // SRB2kart #include "k_color.h" -#include "k_kart.h" // HITLAGJITTERS +#include "k_hitlag.h" // HITLAGJITTERS #include "r_fps.h" #define MINZ (FRACUNIT*4)