Merge branch 'rewrite-mines' into 'master'

Rewrite mines

See merge request KartKrew/Kart!581
This commit is contained in:
James R 2022-05-09 05:15:31 +00:00
commit 5293b151be
11 changed files with 157 additions and 375 deletions

View file

@ -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",

View file

@ -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

View file

@ -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,

View file

@ -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))

View file

@ -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

View file

@ -3711,88 +3711,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
@ -3838,6 +3756,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;

View file

@ -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);

View file

@ -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},

View file

@ -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)

View file

@ -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

View file

@ -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)
@ -8953,6 +8923,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;
@ -9304,6 +9285,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)