diff --git a/src/deh_tables.c b/src/deh_tables.c index c5acec7f8..faa5010ad 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -3955,6 +3955,8 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_INSTASHIELDB6", "S_INSTASHIELDB7", + "S_POWERCLASH", // Invinc/Grow no damage collide VFX + "S_PLAYERARROW", // Above player arrow "S_PLAYERARROW_BOX", "S_PLAYERARROW_ITEM", @@ -5384,6 +5386,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_INSTASHIELDA", "MT_INSTASHIELDB", + "MT_POWERCLASH", // Invinc/Grow no damage clash VFX + "MT_PLAYERARROW", "MT_PLAYERWANTED", diff --git a/src/info.c b/src/info.c index 8d3b31f52..9279f0578 100644 --- a/src/info.c +++ b/src/info.c @@ -24,6 +24,7 @@ #include "lzf.h" // Hey, moron! If you change this table, don't forget about the sprite enum in info.h and the sprite lights in hw_light.c! +// EXCEPT HW_LIGHT.C DOESN'T EXIST ANYMORE LOVE CONTINUOUSLY FALLING ON MY ASS THROUGHOUT THIS CODEBASE - Tyron 2022-05-12 // For the sake of constant merge conflicts, let's spread this out char sprnames[NUMSPRITES + 1][5] = { @@ -600,6 +601,8 @@ char sprnames[NUMSPRITES + 1][5] = "ISTA", // instashield layer A "ISTB", // instashield layer B + "PWCL", // Invinc/grow clash VFX + "ARRO", // player arrows "ITEM", "ITMO", @@ -4498,6 +4501,8 @@ state_t states[NUMSTATES] = {SPR_ISTB, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_INSTASHIELDB7}, // S_INSTASHIELDB6 {SPR_ISTB, FF_FULLBRIGHT|6, 2, {NULL}, 0, 0, S_NULL}, // S_INSTASHIELDB7 + {SPR_PWCL, FF_FULLBRIGHT|FF_ANIMATE|FF_PAPERSPRITE, 10, {NULL}, 9, 1, S_NULL}, + // Above player arrow {SPR_ARRO, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW {SPR_ARRO, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_BOX @@ -25358,6 +25363,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_POWERCLASH + -1, // doomednum + S_POWERCLASH, // 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 + 8*FRACUNIT, // height + 2, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + { // MT_PLAYERARROW -1, // doomednum S_PLAYERARROW, // spawnstate diff --git a/src/info.h b/src/info.h index 5e4ef6418..f8dbb90bd 100644 --- a/src/info.h +++ b/src/info.h @@ -1147,6 +1147,8 @@ typedef enum sprite SPR_ISTA, // instashield layer A SPR_ISTB, // instashield layer B + SPR_PWCL, // Invinc/grow clash VFX + SPR_ARRO, // player arrows SPR_ITEM, SPR_ITMO, @@ -4938,6 +4940,8 @@ typedef enum state S_INSTASHIELDB6, S_INSTASHIELDB7, + S_POWERCLASH, // Grow/Invinc clash VFX + S_PLAYERARROW, // Above player arrow S_PLAYERARROW_BOX, S_PLAYERARROW_ITEM, @@ -6404,6 +6408,8 @@ typedef enum mobj_type MT_INSTASHIELDA, MT_INSTASHIELDB, + MT_POWERCLASH, // Grow/Invinc clash VFX + MT_PLAYERARROW, MT_PLAYERWANTED, diff --git a/src/k_collide.c b/src/k_collide.c index 665a3ff0a..fbe6af02d 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -788,24 +788,8 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2) boolean stungT1 = false; boolean stungT2 = false; - // Grow damage - t1Condition = (t1->scale > t2->scale + (mapobjectscale/8)); - t2Condition = (t2->scale > t1->scale + (mapobjectscale/8)); - - if (t1Condition == true && t2Condition == false) - { - P_DamageMobj(t2, t1, t1, 1, DMG_TUMBLE); - return true; - } - else if (t1Condition == false && t2Condition == true) - { - P_DamageMobj(t1, t2, t2, 1, DMG_TUMBLE); - return true; - } - - // Invincibility damage - t1Condition = (t1->player->invincibilitytimer > 0); - t2Condition = (t2->player->invincibilitytimer > 0); + t1Condition = (t1->scale > t2->scale + (mapobjectscale/8)) || (t1->player->invincibilitytimer > 0); + t2Condition = (t2->scale > t1->scale + (mapobjectscale/8)) || (t2->player->invincibilitytimer > 0); if (t1Condition == true && t2Condition == false) { @@ -816,6 +800,9 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2) { P_DamageMobj(t1, t2, t2, 1, DMG_TUMBLE); return true; + } else if (t1Condition == true && t2Condition == true) { + K_DoPowerClash(t1->player, t2->player); + return false; } // Flame Shield dash damage diff --git a/src/k_kart.c b/src/k_kart.c index 1071f0371..4edb34b5c 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3388,6 +3388,28 @@ void K_DoInstashield(player_t *player) P_SetTarget(&layerb->target, player->mo); } +void K_DoPowerClash(player_t *t1, player_t *t2) { + mobj_t *clash; + + // short-circuit instashield for vfx visibility + t1->instashield = 1; + t2->instashield = 1; + + S_StartSound(t1->mo, sfx_parry); + K_AddHitLag(t1->mo, 6, false); + K_AddHitLag(t2->mo, 6, false); + + clash = P_SpawnMobj((t1->mo->x/2) + (t2->mo->x/2), (t1->mo->y/2) + (t2->mo->y/2), (t1->mo->z/2) + (t2->mo->z/2), MT_POWERCLASH); + + // needs to handle mixed scale collisions (t1 grow t2 invinc)... + clash->z = clash->z + (t1->mo->height/4) + (t2->mo->height/4); + clash->angle = R_PointToAngle2(clash->x, clash->y, t1->mo->x, t1->mo->y) + ANGLE_90; + + // Shrink over time (accidental behavior that looked good) + clash->destscale = (t1->mo->scale/2) + (t2->mo->scale/2); + P_SetScale(clash, 3*clash->destscale/2); +} + void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved) { UINT8 points = 1; diff --git a/src/k_kart.h b/src/k_kart.h index aef18b19e..d6ba0f720 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -67,6 +67,7 @@ angle_t K_MomentumAngle(mobj_t *mo); 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_DoInstashield(player_t *player); +void K_DoPowerClash(player_t *t1, player_t *t2); void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved); void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type); void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); diff --git a/src/sounds.c b/src/sounds.c index 851c69518..761fa109c 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1108,6 +1108,9 @@ sfxinfo_t S_sfx[NUMSFX] = {"kdtrg2", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Medium energy, SF_X8AWAYSOUND {"kdtrg3", false, 64, 80, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // High energy, SF_X2AWAYSOUND|SF_X8AWAYSOUND + // SRB2kart - Grow/invinc clash + {"parry", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // SF_X8AWAYSOUND + // SRB2Kart - Engine sounds // Engine class A {"krta00", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR, ""}, diff --git a/src/sounds.h b/src/sounds.h index 0686cab46..336cd8b74 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -1172,6 +1172,9 @@ typedef enum sfx_kdtrg2, sfx_kdtrg3, + // SRB2Kart - Powerup clash SFX + sfx_parry, + // Next up: UNIQUE ENGINE SOUNDS! Hoooooo boy... // Engine class A - Low Speed, Low Weight sfx_krta00,