From 1381a56077d924681caa502019f3d474f57debf4 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 7 May 2022 22:59:38 -0400 Subject: [PATCH] Rewrite mines Get rid of the tons of extra objects it uses for sounds & collision, do it all from the actual object PLEASE... --- src/deh_tables.c | 6 +- src/info.c | 65 ++-------------------- src/info.h | 6 +- src/k_collide.c | 134 ++++++++++++++++++++++++++++++++++++--------- src/k_collide.h | 12 +++- src/k_kart.c | 84 +--------------------------- src/k_kart.h | 1 - src/lua_baselib.c | 20 ------- src/p_enemy.c | 137 ++++------------------------------------------ src/p_map.c | 21 ------- src/p_mobj.c | 46 +++++----------- 11 files changed, 157 insertions(+), 375 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index a8fd4612c..004adf30e 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -3784,8 +3784,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_SSMINE_DEPLOY12", "S_SSMINE_DEPLOY13", "S_SSMINE_EXPLODE", - "S_MINEEXPLOSION1", - "S_MINEEXPLOSION2", + "S_SSMINE_EXPLODE2", // New explosion "S_QUICKBOOM1", @@ -4540,6 +4539,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_EBARREL16", "S_EBARREL17", "S_EBARREL18", + "S_EBARREL19", "S_MERRYHORSE", "S_BLUEFRUIT", "S_ORANGEFRUIT", @@ -5533,8 +5533,6 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_SSMINE_SHIELD", // Special Stage Mine stuff "MT_SSMINE", - "MT_MINEEXPLOSION", - "MT_MINEEXPLOSIONSOUND", "MT_SMOLDERING", // New explosion "MT_BOOMEXPLODE", diff --git a/src/info.c b/src/info.c index 672c0401d..414d11447 100644 --- a/src/info.c +++ b/src/info.c @@ -4349,10 +4349,8 @@ state_t states[NUMSTATES] = {SPR_SSMN, 12, 3, {NULL}, 0, 0, S_SSMINE_DEPLOY12}, // S_SSMINE_DEPLOY11 {SPR_SSMN, 13, 3, {NULL}, 0, 0, S_SSMINE_DEPLOY13}, // S_SSMINE_DEPLOY12 {SPR_SSMN, 14, 3, {NULL}, 0, 0, S_SSMINE1}, // S_SSMINE_DEPLOY13 - {SPR_SSMN, 3, 1, {A_SSMineExplode}, MT_MINEEXPLOSION, 0, S_NULL}, // S_SSMINE_EXPLODE - - {SPR_NULL, 0, 6, {NULL}, 0, 0, S_MINEEXPLOSION2}, // S_MINEEXPLOSION1 - {SPR_NULL, 1, 22, {A_ForceStop}, 0, 0, S_NULL}, // S_MINEEXPLOSION2 + {SPR_SSMN, 3, 1, {A_SSMineExplode}, 0, 0, S_SSMINE_EXPLODE2}, // S_SSMINE_EXPLODE + {SPR_NULL, 0, 12, {A_SSMineExplode}, 1, 0, S_NULL}, // S_SSMINE_EXPLODE2 {SPR_KRBM, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_QUICKBOOM2}, // S_QUICKBOOM1 {SPR_KRBM, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_QUICKBOOM3}, // S_QUICKBOOM2 @@ -5093,7 +5091,7 @@ state_t states[NUMSTATES] = {SPR_TOAH, 2, 3, {NULL}, 0, 0, S_TOADHIT4}, // S_TOADHIT3 {SPR_TOAH, 3, 3, {NULL}, 0, 0, S_EBARREL18}, // S_TOADHIT4 - {SPR_BRRL, 0, 1, {A_Look}, (96<<16)|1, 0, S_EBARRELIDLE}, // S_EBARRELIDLE + {SPR_BRRL, 0, 1, {A_Look}, (96<<16)|1, 0, S_EBARRELIDLE}, // S_EBARRELIDLE {SPR_BRRR, 0, 4, {NULL}, 0, 0, S_EBARREL2}, // S_EBARREL1 {SPR_BRRR, 1, 4, {NULL}, 0, 0, S_EBARREL3}, // S_EBARREL2 {SPR_BRRR, 2, 4, {NULL}, 0, 0, S_EBARREL4}, // S_EBARREL3 @@ -5111,7 +5109,8 @@ state_t states[NUMSTATES] = {SPR_BRRR, 14, 4, {NULL}, 0, 0, S_EBARREL16}, // S_EBARREL15 {SPR_BRRR, 15, 4, {NULL}, 0, 0, S_EBARREL17}, // S_EBARREL16 {SPR_BRRR, 16, 4, {NULL}, 0, 0, S_EBARREL18}, // S_EBARREL17 - {SPR_BRRR, 16, 0, {A_SSMineExplode}, MT_MINEEXPLOSION, 0, S_NULL}, // S_EBARREL18 + {SPR_BRRR, 16, 1, {A_SSMineExplode}, 0, 0, S_EBARREL19}, // S_EBARREL18 + {SPR_NULL, 0, 12, {A_SSMineExplode}, 1, 0, S_NULL}, // S_EBARREL19 {SPR_HRSE, 0, 230, {A_PlaySeeSound}, 0, 0, S_MERRYHORSE}, // S_MERRYHORSE @@ -24055,60 +24054,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_MINEEXPLOSION - -1, // doomednum - S_MINEEXPLOSION1, // 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 - 32*FRACUNIT, // radius - 32*FRACUNIT, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - MF_SOLID|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags - S_NULL // raisestate - }, - - { // MT_MINEEXPLOSIONSOUND - -1, // doomednum - S_INVISIBLE, // spawnstate - 100, // 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 - 0, // speed - 16*FRACUNIT, // radius - 16*FRACUNIT, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY, // flags - S_NULL // raisestate - }, - { // MT_SMOLDERING -1, // doomednum S_INVISIBLE, // spawnstate diff --git a/src/info.h b/src/info.h index e64dae3de..bfea27003 100644 --- a/src/info.h +++ b/src/info.h @@ -4767,8 +4767,7 @@ typedef enum state S_SSMINE_DEPLOY12, S_SSMINE_DEPLOY13, S_SSMINE_EXPLODE, - S_MINEEXPLOSION1, - S_MINEEXPLOSION2, + S_SSMINE_EXPLODE2, // New explosion S_QUICKBOOM1, @@ -5532,6 +5531,7 @@ typedef enum state S_EBARREL16, S_EBARREL17, S_EBARREL18, + S_EBARREL19, S_MERRYHORSE, @@ -6553,8 +6553,6 @@ typedef enum mobj_type MT_SSMINE, // Mine stuff MT_SSMINE_SHIELD, - MT_MINEEXPLOSION, - MT_MINEEXPLOSIONSOUND, MT_SMOLDERING, // New explosion MT_BOOMEXPLODE, diff --git a/src/k_collide.c b/src/k_collide.c index f08f7a00b..665a3ff0a 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -296,6 +296,115 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2) return true; } +static mobj_t *grenade; +static fixed_t explodedist; +static boolean explodespin; + +static inline boolean PIT_SSMineChecks(mobj_t *thing) +{ + if (thing == grenade) // Don't explode yourself! Endless loop! + return true; + + if (thing->health <= 0) + return true; + + if (!(thing->flags & MF_SHOOTABLE) || (thing->flags & MF_SCENERY)) + return true; + + if (thing->player && thing->player->spectator) + return true; + + if (P_AproxDistance(P_AproxDistance(thing->x - grenade->x, thing->y - grenade->y), thing->z - grenade->z) > explodedist) + return true; // Too far away + + if (P_CheckSight(grenade, thing) == false) + return true; // Not in sight + + return false; +} + +static inline boolean PIT_SSMineSearch(mobj_t *thing) +{ + if (grenade == NULL || P_MobjWasRemoved(grenade)) + return false; // There's the possibility these can chain react onto themselves after they've already died if there are enough all in one spot + + if (grenade->flags2 & MF2_DEBRIS) // don't explode twice + return false; + + if (thing->type != MT_PLAYER) // Don't explode for anything but an actual player. + return true; + + if (thing == grenade->target && grenade->threshold != 0) // Don't blow up at your owner instantly. + return true; + + if (PIT_SSMineChecks(thing) == true) + return true; + + // Explode! + P_SetMobjState(grenade, grenade->info->deathstate); + return false; +} + +void K_DoMineSearch(mobj_t *actor, fixed_t size) +{ + INT32 bx, by, xl, xh, yl, yh; + + explodedist = FixedMul(size, actor->scale); + grenade = actor; + + yh = (unsigned)(actor->y + explodedist - bmaporgy)>>MAPBLOCKSHIFT; + yl = (unsigned)(actor->y - explodedist - bmaporgy)>>MAPBLOCKSHIFT; + xh = (unsigned)(actor->x + explodedist - bmaporgx)>>MAPBLOCKSHIFT; + xl = (unsigned)(actor->x - explodedist - bmaporgx)>>MAPBLOCKSHIFT; + + BMBOUNDFIX (xl, xh, yl, yh); + + for (by = yl; by <= yh; by++) + for (bx = xl; bx <= xh; bx++) + P_BlockThingsIterator(bx, by, PIT_SSMineSearch); +} + +static inline boolean PIT_SSMineExplode(mobj_t *thing) +{ + if (grenade == NULL || P_MobjWasRemoved(grenade)) + return false; // There's the possibility these can chain react onto themselves after they've already died if there are enough all in one spot + +#if 0 + if (grenade->flags2 & MF2_DEBRIS) // don't explode twice + return false; +#endif + + if (PIT_SSMineChecks(thing) == true) + return true; + + P_DamageMobj(thing, grenade, grenade->target, 1, (explodespin ? DMG_NORMAL : DMG_EXPLODE)); + return true; +} + +void K_MineExplodeAttack(mobj_t *actor, fixed_t size, boolean spin) +{ + INT32 bx, by, xl, xh, yl, yh; + + explodespin = spin; + explodedist = FixedMul(size, actor->scale); + grenade = actor; + + // Use blockmap to check for nearby shootables + yh = (unsigned)(actor->y + explodedist - bmaporgy)>>MAPBLOCKSHIFT; + yl = (unsigned)(actor->y - explodedist - bmaporgy)>>MAPBLOCKSHIFT; + xh = (unsigned)(actor->x + explodedist - bmaporgx)>>MAPBLOCKSHIFT; + xl = (unsigned)(actor->x - explodedist - bmaporgx)>>MAPBLOCKSHIFT; + + BMBOUNDFIX (xl, xh, yl, yh); + + for (by = yl; by <= yh; by++) + for (bx = xl; bx <= xh; bx++) + P_BlockThingsIterator(bx, by, PIT_SSMineExplode); + + // Set this flag to ensure that the inital action won't be triggered twice. + actor->flags2 |= MF2_DEBRIS; +} + boolean K_MineCollide(mobj_t *t1, mobj_t *t2) { if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0)) @@ -349,31 +458,6 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2) return true; } -boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2) -{ - if (t2->player) - { - if (t2->player->flashing > 0 && t2->hitlag == 0) - return true; - - if (t1->state == &states[S_MINEEXPLOSION1]) - { - P_DamageMobj(t2, t1, t1->target, 1, DMG_EXPLODE); - } - else - { - P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL); - } - } - else if (t2->flags & MF_SHOOTABLE) - { - // Shootable damage - P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL); - } - - return true; -} - boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2) { if ((t1->threshold > 0 && t2->hitlag > 0) || (t2->threshold > 0 && t1->hitlag > 0)) diff --git a/src/k_collide.h b/src/k_collide.h index 11af0502b..49cc3fa08 100644 --- a/src/k_collide.h +++ b/src/k_collide.h @@ -5,17 +5,27 @@ #include "p_mobj.h" angle_t K_GetCollideAngle(mobj_t *t1, mobj_t *t2); + boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2); + boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2); boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2); + +void K_DoMineSearch(mobj_t *actor, fixed_t size); +void K_MineExplodeAttack(mobj_t *actor, fixed_t size, boolean spin); boolean K_MineCollide(mobj_t *t1, mobj_t *t2); -boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2); + boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2); + boolean K_DropTargetCollide(mobj_t *t1, mobj_t *t2); + boolean K_BubbleShieldCollide(mobj_t *t1, mobj_t *t2); + boolean K_KitchenSinkCollide(mobj_t *t1, mobj_t *t2); + boolean K_FallingRockCollide(mobj_t *t1, mobj_t *t2); boolean K_SMKIceBlockCollide(mobj_t *t1, mobj_t *t2); + boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2); #endif diff --git a/src/k_kart.c b/src/k_kart.c index 92fda8de3..a4fe51256 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3695,88 +3695,6 @@ void K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount) K_HandleBumperChanges(victim, oldVictimBumpers); } -// source is the mobj that originally threw the bomb that exploded etc. -// Spawns the sphere around the explosion that handles spinout -void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit, mobj_t *source) -{ - mobj_t *mobj; - mobj_t *ghost = NULL; - INT32 i; - TVector v; - TVector *res; - fixed_t finalx, finaly, finalz, dist; - //mobj_t hoopcenter; - angle_t degrees, fa, closestangle; - fixed_t mobjx, mobjy, mobjz; - - //hoopcenter.x = x; - //hoopcenter.y = y; - //hoopcenter.z = z; - - //hoopcenter.z = z - mobjinfo[type].height/2; - - degrees = FINEANGLES/number; - - closestangle = 0; - - // Create the hoop! - for (i = 0; i < number; i++) - { - fa = (i*degrees); - v[0] = FixedMul(FINECOSINE(fa),radius); - v[1] = 0; - v[2] = FixedMul(FINESINE(fa),radius); - v[3] = FRACUNIT; - - res = VectorMatrixMultiply(v, *RotateXMatrix(rotangle)); - M_Memcpy(&v, res, sizeof (v)); - res = VectorMatrixMultiply(v, *RotateZMatrix(closestangle)); - M_Memcpy(&v, res, sizeof (v)); - - finalx = x + v[0]; - finaly = y + v[1]; - finalz = z + v[2]; - - mobj = P_SpawnMobj(finalx, finaly, finalz, type); - - mobj->z -= mobj->height>>1; - - // change angle - P_InitAngle(mobj, R_PointToAngle2(mobj->x, mobj->y, x, y)); - - // change slope - dist = P_AproxDistance(P_AproxDistance(x - mobj->x, y - mobj->y), z - mobj->z); - - if (dist < 1) - dist = 1; - - mobjx = mobj->x; - mobjy = mobj->y; - mobjz = mobj->z; - - if (ghostit) - { - ghost = P_SpawnGhostMobj(mobj); - P_SetMobjState(mobj, S_NULL); - mobj = ghost; - } - - if (spawncenter) - { - mobj->x = x; - mobj->y = y; - mobj->z = z; - } - - mobj->momx = FixedMul(FixedDiv(mobjx - x, dist), FixedDiv(dist, 6*FRACUNIT)); - mobj->momy = FixedMul(FixedDiv(mobjy - y, dist), FixedDiv(dist, 6*FRACUNIT)); - mobj->momz = FixedMul(FixedDiv(mobjz - z, dist), FixedDiv(dist, 6*FRACUNIT)); - - if (source && !P_MobjWasRemoved(source)) - P_SetTarget(&mobj->target, source); - } -} - #define MINEQUAKEDIST 4096 // Does the proximity screen flash and quake for explosions @@ -3822,6 +3740,8 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color) radius = source->radius>>FRACBITS; height = source->height>>FRACBITS; + S_StartSound(smoldering, sfx_s3k4e); + if (!color) color = SKINCOLOR_KETCHUP; diff --git a/src/k_kart.h b/src/k_kart.h index 95e24d7cd..12c03ae5d 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -75,7 +75,6 @@ void K_DebtStingPlayer(player_t *player, mobj_t *source); void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers); void K_DestroyBumpers(player_t *player, UINT8 amount); void K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount); -void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit, mobj_t *source); void K_MineFlashScreen(mobj_t *source); void K_SpawnMineExplosion(mobj_t *source, UINT8 color); void K_RunFinishLineBeam(void); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 04b37601f..decf683f4 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3550,25 +3550,6 @@ static int lib_kTakeBumpersFromPlayer(lua_State *L) return 0; } -static int lib_kSpawnKartExplosion(lua_State *L) -{ - fixed_t x = luaL_checkfixed(L, 1); - fixed_t y = luaL_checkfixed(L, 2); - fixed_t z = luaL_checkfixed(L, 3); - fixed_t radius = (fixed_t)luaL_optinteger(L, 4, 32*FRACUNIT); - INT32 number = (INT32)luaL_optinteger(L, 5, 32); - mobjtype_t type = luaL_optinteger(L, 6, MT_MINEEXPLOSION); - angle_t rotangle = luaL_optinteger(L, 7, 0); - boolean spawncenter = lua_opttrueboolean(L, 8); - boolean ghostit = lua_optboolean(L, 9); - mobj_t *source = NULL; - NOHUD - if (!lua_isnone(L, 10) && lua_isuserdata(L, 10)) - source = *((mobj_t **)luaL_checkudata(L, 10, META_MOBJ)); - K_SpawnKartExplosion(x, y, z, radius, number, type, rotangle, spawncenter, ghostit, source); - return 0; -} - static int lib_kSpawnMineExplosion(lua_State *L) { mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -4101,7 +4082,6 @@ static luaL_Reg lib[] = { {"K_TumblePlayer",lib_kTumblePlayer}, {"K_ExplodePlayer",lib_kExplodePlayer}, {"K_TakeBumpersFromPlayer",lib_kTakeBumpersFromPlayer}, - {"K_SpawnKartExplosion",lib_kSpawnKartExplosion}, {"K_SpawnMineExplosion",lib_kSpawnMineExplosion}, {"K_SpawnBoostTrail",lib_kSpawnBoostTrail}, {"K_SpawnSparkleTrail",lib_kSpawnSparkleTrail}, diff --git a/src/p_enemy.c b/src/p_enemy.c index 0edfbb5e8..2e020ecd2 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -25,10 +25,13 @@ #include "i_video.h" #include "z_zone.h" #include "lua_hook.h" -#include "k_kart.h" // SRB2kart + +// SRB2kart +#include "k_kart.h" #include "k_waypoint.h" #include "k_battle.h" #include "k_respawn.h" +#include "k_collide.h" #ifdef HW3SOUND #include "hardware/hw3sound.h" @@ -14050,55 +14053,9 @@ void A_SPBChase(mobj_t *actor) return; } -static mobj_t *grenade; -static fixed_t explodedist; - -static inline boolean PIT_SSMineSearch(mobj_t *thing) -{ - if (!grenade) - return false; - - if (grenade->flags2 & MF2_DEBRIS) - return false; - - if (thing->type != MT_PLAYER) // Don't explode for anything but an actual player. - return true; - - if (!(thing->flags & MF_SHOOTABLE)) - { - // didn't do any damage - return true; - } - - if (netgame && thing->player && thing->player->spectator) - return true; - - if (thing == grenade->target && grenade->threshold != 0) // Don't blow up at your owner. - return true; - - if (thing->player && (thing->player->hyudorotimer - || ((gametyperules & GTR_BUMPERS) && thing->player && thing->player->bumpers <= 0 && thing->player->karmadelay))) - return true; - - // see if it went over / under - if (grenade->z - explodedist > thing->z + thing->height) - return true; // overhead - if (grenade->z + grenade->height + explodedist < thing->z) - return true; // underneath - - if (P_AproxDistance(P_AproxDistance(thing->x - grenade->x, thing->y - grenade->y), - thing->z - grenade->z) > explodedist) - return true; // Too far away - - // Explode! - P_SetMobjState(grenade, grenade->info->deathstate); - return false; -} - void A_SSMineSearch(mobj_t *actor) { - INT32 bx, by, xl, xh, yl, yh; - explodedist = FixedMul(actor->info->painchance, mapobjectscale); + fixed_t dis = INT32_MAX; if (LUA_CallAction(A_SSMINESEARCH, actor)) return; @@ -14106,66 +14063,19 @@ void A_SSMineSearch(mobj_t *actor) if (actor->flags2 & MF2_DEBRIS) return; - if (actor->state == &states[S_SSMINE_DEPLOY8]) - explodedist = (3*explodedist)/2; - if (leveltime % 35 == 0) S_StartSound(actor, actor->info->activesound); - // Use blockmap to check for nearby shootables - yh = (unsigned)(actor->y + explodedist - bmaporgy)>>MAPBLOCKSHIFT; - yl = (unsigned)(actor->y - explodedist - bmaporgy)>>MAPBLOCKSHIFT; - xh = (unsigned)(actor->x + explodedist - bmaporgx)>>MAPBLOCKSHIFT; - xl = (unsigned)(actor->x - explodedist - bmaporgx)>>MAPBLOCKSHIFT; + dis = actor->info->painchance; + if (actor->state == &states[S_SSMINE_DEPLOY8]) + dis = (3*dis)>>1; - grenade = actor; - - for (by = yl; by <= yh; by++) - for (bx = xl; bx <= xh; bx++) - P_BlockThingsIterator(bx, by, PIT_SSMineSearch); -} - -static inline boolean PIT_MineExplode(mobj_t *thing) -{ - if (!grenade || P_MobjWasRemoved(grenade)) - return false; // There's the possibility these can chain react onto themselves after they've already died if there are enough all in one spot - - if (grenade->flags2 & MF2_DEBRIS) // don't explode twice - return false; - - if (thing == grenade || thing->type == MT_MINEEXPLOSIONSOUND) // Don't explode yourself! Endless loop! - return true; - - if (!(thing->flags & MF_SHOOTABLE) || (thing->flags & MF_SCENERY)) - return true; - - if (netgame && thing->player && thing->player->spectator) - return true; - - if ((gametyperules & GTR_BUMPERS) && grenade->target && grenade->target->player && grenade->target->player->bumpers <= 0 && thing == grenade->target) - return true; - - // see if it went over / under - if (grenade->z - explodedist > thing->z + thing->height) - return true; // overhead - if (grenade->z + grenade->height + explodedist < thing->z) - return true; // underneath - - if (P_AproxDistance(P_AproxDistance(thing->x - grenade->x, thing->y - grenade->y), - thing->z - grenade->z) > explodedist) - return true; // Too far away - - P_DamageMobj(thing, grenade, grenade->target, 1, DMG_EXPLODE); - return true; + K_DoMineSearch(actor, dis); } void A_SSMineExplode(mobj_t *actor) { - INT32 bx, by, xl, xh, yl, yh; - INT32 d; INT32 locvar1 = var1; - mobjtype_t type; - explodedist = FixedMul((3*actor->info->painchance)/2, actor->scale); if (LUA_CallAction(A_SSMINEEXPLODE, actor)) return; @@ -14173,33 +14083,8 @@ void A_SSMineExplode(mobj_t *actor) if (actor->flags2 & MF2_DEBRIS) return; - type = (mobjtype_t)locvar1; - - // Use blockmap to check for nearby shootables - yh = (unsigned)(actor->y + explodedist - bmaporgy)>>MAPBLOCKSHIFT; - yl = (unsigned)(actor->y - explodedist - bmaporgy)>>MAPBLOCKSHIFT; - xh = (unsigned)(actor->x + explodedist - bmaporgx)>>MAPBLOCKSHIFT; - xl = (unsigned)(actor->x - explodedist - bmaporgx)>>MAPBLOCKSHIFT; - - BMBOUNDFIX (xl, xh, yl, yh); - - grenade = actor; - - for (by = yl; by <= yh; by++) - for (bx = xl; bx <= xh; bx++) - P_BlockThingsIterator(bx, by, PIT_MineExplode); - - for (d = 0; d < 16; d++) - K_SpawnKartExplosion(actor->x, actor->y, actor->z, explodedist + 32*mapobjectscale, 32, type, d*(ANGLE_45/4), true, false, actor->target); // 32 <-> 64 - - if (actor->target && actor->target->player) - K_SpawnMineExplosion(actor, actor->target->player->skincolor); - else - K_SpawnMineExplosion(actor, SKINCOLOR_KETCHUP); - - P_SpawnMobj(actor->x, actor->y, actor->z, MT_MINEEXPLOSIONSOUND); - - actor->flags2 |= MF2_DEBRIS; // Set this flag to ensure that the explosion won't be effective more than 1 frame. + K_SpawnMineExplosion(actor, (actor->target && actor->target->player) ? actor->target->player->skincolor : SKINCOLOR_KETCHUP); + K_MineExplodeAttack(actor, (3*actor->info->painchance)>>1, (boolean)locvar1); } void A_LandMineExplode(mobj_t *actor) diff --git a/src/p_map.c b/src/p_map.c index 6954d6e11..f755894e5 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -892,27 +892,6 @@ static boolean PIT_CheckThing(mobj_t *thing) return K_MineCollide(thing, tmthing); } - if (tmthing->type == MT_MINEEXPLOSION) - { - // see if it went over / under - if (tmthing->z > thing->z + thing->height) - return true; // overhead - if (tmthing->z + tmthing->height < thing->z) - return true; // underneath - - return K_MineExplosionCollide(tmthing, thing); - } - else if (thing->type == MT_MINEEXPLOSION) - { - // see if it went over / under - if (tmthing->z > thing->z + thing->height) - return true; // overhead - if (tmthing->z + tmthing->height < thing->z) - return true; // underneath - - return K_MineExplosionCollide(thing, tmthing); - } - if (tmthing->type == MT_LANDMINE) { // see if it went over / under diff --git a/src/p_mobj.c b/src/p_mobj.c index 00744229f..3405f204a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -42,6 +42,7 @@ #include "k_respawn.h" #include "k_bot.h" #include "k_terrain.h" +#include "k_collide.h" static CV_PossibleValue_t CV_BobSpeed[] = {{0, "MIN"}, {4*FRACUNIT, "MAX"}, {0, NULL}}; consvar_t cv_movebob = CVAR_INIT ("movebob", "1.0", CV_FLOAT|CV_SAVE, CV_BobSpeed, NULL); @@ -6281,9 +6282,6 @@ static boolean P_MobjDeadThink(mobj_t *mobj) return false; } break; - case MT_MINEEXPLOSIONSOUND: - P_RemoveMobj(mobj); - return false; case MT_CDUFO: if (mobj->fuse > TICRATE) mobj->renderflags ^= RF_DONTDRAW; // only by good fortune does this end with it having RF_DONTDRAW... don't touch! @@ -6972,34 +6970,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj) case MT_SPBEXPLOSION: mobj->health--; break; - case MT_MINEEXPLOSION: - if ((mobj->z < mobj->floorz - mobj->height) || (mobj->z > mobj->ceilingz + mobj->height)) - { - P_KillMobj(mobj, NULL, NULL, DMG_NORMAL); - break; - } - - if (mobj->tics != -1) - { - mobj->tics--; - - // you can cycle through multiple states in a tic - if (!mobj->tics) - if (!P_SetMobjState(mobj, mobj->state->nextstate)) - return false; // freed itself - } - - P_UnsetThingPosition(mobj); - mobj->x += mobj->momx; - mobj->y += mobj->momy; - mobj->z += mobj->momz; - P_SetThingPosition(mobj); - return false; - case MT_MINEEXPLOSIONSOUND: - if (mobj->health == 100) - S_StartSound(mobj, sfx_s3k4e); - mobj->health--; - break; case MT_EMERALD: { if (battleovertime.enabled >= 10*TICRATE) @@ -8962,6 +8932,17 @@ static void P_FiringThink(mobj_t *mobj) mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); } +static void K_MineExplodeThink(mobj_t *mobj) +{ + if (mobj->state->action.acp1 == (actionf_p1)A_SSMineExplode) + { + if (mobj->state->tics > 1) + { + K_MineExplodeAttack(mobj, mobj->info->painchance, (boolean)mobj->state->var1); + } + } +} + static void P_MonitorFuseThink(mobj_t *mobj) { mobj_t *newmobj; @@ -9313,6 +9294,9 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->flags2 & MF2_FIRING) P_FiringThink(mobj); + if (mobj->flags2 & MF2_DEBRIS) + K_MineExplodeThink(mobj); + if (mobj->flags & MF_AMBIENT) { if (!(leveltime % mobj->health) && mobj->info->seesound)