Revert Rewrite mines
As much as this pains me, this might be needed for lua compat.
This reverts commit 1381a56077.
This commit is contained in:
parent
c5eb38bd0e
commit
9584982685
13 changed files with 318 additions and 235 deletions
|
|
@ -1472,7 +1472,7 @@ struct int_const_s const INT_CONST[] = {
|
|||
{"PRECIPFX_THUNDER",PRECIPFX_THUNDER},
|
||||
{"PRECIPFX_LIGHTNING",PRECIPFX_LIGHTNING},
|
||||
{"PRECIPFX_WATERPARTICLES",PRECIPFX_WATERPARTICLES},
|
||||
|
||||
|
||||
// followermode_t
|
||||
{"FOLLOWERMODE_FLOAT",FOLLOWERMODE_FLOAT},
|
||||
{"FOLLOWERMODE_GROUND",FOLLOWERMODE_GROUND},
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#define NOMD5
|
||||
#define NOFILEHASH
|
||||
|
||||
// Uncheck this to compile debugging code
|
||||
//#define RANGECHECK
|
||||
|
|
|
|||
|
|
@ -191,8 +191,6 @@ _(A_FlickyHeightCheck, FLICKYHEIGHTCHECK)
|
|||
_(A_FlickyFlutter, FLICKYFLUTTER)
|
||||
_(A_FlameParticle, FLAMEPARTICLE)
|
||||
_(A_FadeOverlay, FADEOVERLAY)
|
||||
_(A_MineExplode, MINEEXPLODE)
|
||||
_(A_MineRange, MINERANGE)
|
||||
_(A_ConnectToGround, CONNECTTOGROUND)
|
||||
_(A_SpawnParticleRelative, SPAWNPARTICLERELATIVE)
|
||||
_(A_ParticleSpawn, PARTICLESPAWN)
|
||||
|
|
@ -212,6 +210,8 @@ _(A_JawzExplode, JAWZEXPLODE)
|
|||
_(A_SPBChase, SPBCHASE)
|
||||
_(A_SSMineSearch, SSMINESEARCH)
|
||||
_(A_SSMineExplode, SSMINEEXPLODE)
|
||||
_(A_SSMineSearch, GRENADERING)
|
||||
_(A_SSMineExplode, MINEEXPLODE)
|
||||
_(A_LandMineExplode, LANDMINEEXPLODE)
|
||||
_(A_BallhogExplode, BALLHOGEXPLODE)
|
||||
_(A_LightningFollowPlayer, LIGHTNINGFOLLOWPLAYER)
|
||||
|
|
|
|||
|
|
@ -595,8 +595,8 @@ _(PLAYERRETICULE) // Jawz reticule
|
|||
|
||||
_(SSMINE) // Mine stuff
|
||||
_(SSMINE_SHIELD)
|
||||
|
||||
_(MINEEXPLOSION) // to keep compatmode scripts happy
|
||||
_(MINEEXPLOSION)
|
||||
_(MINEEXPLOSIONSOUND)
|
||||
|
||||
_(SMOLDERING) // New explosion
|
||||
_(BOOMEXPLODE)
|
||||
|
|
|
|||
|
|
@ -2784,7 +2784,9 @@ _(SSMINE_DEPLOY11)
|
|||
_(SSMINE_DEPLOY12)
|
||||
_(SSMINE_DEPLOY13)
|
||||
_(SSMINE_EXPLODE)
|
||||
_(SSMINE_EXPLODE2)
|
||||
_(MINEEXPLOSION1)
|
||||
_(MINEEXPLOSION2)
|
||||
|
||||
|
||||
// New explosion
|
||||
_(QUICKBOOM1)
|
||||
|
|
@ -3476,7 +3478,6 @@ _(EBARREL15)
|
|||
_(EBARREL16)
|
||||
_(EBARREL17)
|
||||
_(EBARREL18)
|
||||
_(EBARREL19)
|
||||
|
||||
_(MERRYHORSE)
|
||||
|
||||
|
|
|
|||
136
src/k_collide.c
136
src/k_collide.c
|
|
@ -286,115 +286,6 @@ 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 BlockItReturn_t PIT_SSMineSearch(mobj_t *thing)
|
||||
{
|
||||
if (grenade == NULL || P_MobjWasRemoved(grenade))
|
||||
return BMIT_ABORT; // 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 BMIT_ABORT;
|
||||
|
||||
if (thing->type != MT_PLAYER) // Don't explode for anything but an actual player.
|
||||
return BMIT_CONTINUE;
|
||||
|
||||
if (thing == grenade->target && grenade->threshold != 0) // Don't blow up at your owner instantly.
|
||||
return BMIT_CONTINUE;
|
||||
|
||||
if (PIT_SSMineChecks(thing) == true)
|
||||
return BMIT_CONTINUE;
|
||||
|
||||
// Explode!
|
||||
P_SetMobjState(grenade, grenade->info->deathstate);
|
||||
return BMIT_ABORT;
|
||||
}
|
||||
|
||||
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 + MAXRADIUS) - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
yl = (unsigned)(actor->y - (explodedist + MAXRADIUS) - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
xh = (unsigned)(actor->x + (explodedist + MAXRADIUS) - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
xl = (unsigned)(actor->x - (explodedist + MAXRADIUS) - 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 BlockItReturn_t PIT_SSMineExplode(mobj_t *thing)
|
||||
{
|
||||
if (grenade == NULL || P_MobjWasRemoved(grenade))
|
||||
return BMIT_ABORT; // 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 BMIT_ABORT;
|
||||
#endif
|
||||
|
||||
if (PIT_SSMineChecks(thing) == true)
|
||||
return BMIT_CONTINUE;
|
||||
|
||||
P_DamageMobj(thing, grenade, grenade->target, 1, (explodespin ? DMG_NORMAL : DMG_EXPLODE));
|
||||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
||||
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->target == t2) || (!(t2->flags & (MF_ENEMY|MF_BOSS)) && (t1->target == t2->target))) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
|
||||
|
|
@ -410,7 +301,7 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2)
|
|||
|
||||
// Bomb punting
|
||||
if ((t1->state >= &states[S_SSMINE1] && t1->state <= &states[S_SSMINE4])
|
||||
|| (t1->state >= &states[S_SSMINE_DEPLOY8] && t1->state <= &states[S_SSMINE_EXPLODE2]))
|
||||
|| (t1->state >= &states[S_SSMINE_DEPLOY8] && t1->state <= &states[S_SSMINE_DEPLOY13]))
|
||||
{
|
||||
P_KillMobj(t1, t2, t2, DMG_NORMAL);
|
||||
}
|
||||
|
|
@ -445,6 +336,31 @@ 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)
|
||||
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->target == t2) || (!(t2->flags & (MF_ENEMY|MF_BOSS)) && (t1->target == t2->target))) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0)))
|
||||
|
|
|
|||
|
|
@ -9,31 +9,22 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
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);
|
||||
|
||||
void K_ThunderShieldAttack(mobj_t *actor, fixed_t size);
|
||||
|
||||
boolean K_BubbleShieldReflect(mobj_t *t1, mobj_t *t2);
|
||||
boolean K_BubbleShieldCanReflect(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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
86
src/k_kart.c
86
src/k_kart.c
|
|
@ -4257,6 +4257,90 @@ 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
|
||||
mobj->angle = 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
|
||||
|
||||
// Spawns the purely visual explosion
|
||||
void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
|
||||
{
|
||||
|
|
@ -4271,8 +4355,6 @@ 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;
|
||||
|
||||
|
|
|
|||
|
|
@ -154,6 +154,7 @@ INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, 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_SpawnMineExplosion(mobj_t *source, UINT8 color);
|
||||
UINT16 K_DriftSparkColor(player_t *player, INT32 charge);
|
||||
void K_SpawnBoostTrail(player_t *player);
|
||||
|
|
|
|||
|
|
@ -3692,6 +3692,25 @@ 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));
|
||||
|
|
@ -4467,6 +4486,7 @@ static luaL_Reg lib[] = {
|
|||
{"K_SpinPlayer",lib_kSpinPlayer},
|
||||
{"K_ExplodePlayer",lib_kExplodePlayer},
|
||||
{"K_TakeBumpersFromPlayer",lib_kTakeBumpersFromPlayer},
|
||||
{"K_SpawnKartExplosion",lib_kSpawnKartExplosion},
|
||||
{"K_SpawnMineExplosion",lib_kSpawnMineExplosion},
|
||||
{"K_SpawnBoostTrail",lib_kSpawnBoostTrail},
|
||||
{"K_SpawnSparkleTrail",lib_kSpawnSparkleTrail},
|
||||
|
|
|
|||
215
src/p_enemy.c
215
src/p_enemy.c
|
|
@ -26,9 +26,7 @@
|
|||
#include "i_video.h"
|
||||
#include "z_zone.h"
|
||||
#include "lua_hook.h"
|
||||
|
||||
// SRB2kart
|
||||
#include "k_kart.h"
|
||||
#include "k_kart.h" // SRB2kart
|
||||
#include "k_waypoint.h"
|
||||
#include "k_battle.h"
|
||||
#include "k_collide.h"
|
||||
|
|
@ -10149,84 +10147,6 @@ void A_FadeOverlay(mobj_t *actor)
|
|||
P_SetTarget(&actor->tracer, fade);
|
||||
}
|
||||
|
||||
// Function: A_MineExplode
|
||||
// Description: Handles the explosion of a DSZ mine.
|
||||
//
|
||||
// var1 = unused
|
||||
// var2 = unused
|
||||
//
|
||||
void A_MineExplode(mobj_t *actor)
|
||||
{
|
||||
// INT32 locvar1 = var1;
|
||||
// INT32 locvar2 = var2;
|
||||
|
||||
if (LUA_CallAction(A_MINEEXPLODE, actor))
|
||||
return;
|
||||
|
||||
A_Scream(actor);
|
||||
actor->flags = MF_NOGRAVITY|MF_NOCLIP;
|
||||
|
||||
/*
|
||||
quake.epicenter = NULL;
|
||||
quake.radius = 512*FRACUNIT;
|
||||
quake.intensity = 8*FRACUNIT;
|
||||
quake.time = TICRATE/3;
|
||||
*/
|
||||
P_StartQuake(8<<FRACBITS, TICRATE/3);
|
||||
|
||||
P_RadiusAttack(actor, actor->tracer, 192*FRACUNIT, 0, true);
|
||||
P_MobjCheckWater(actor);
|
||||
|
||||
{
|
||||
#define dist 64
|
||||
UINT8 i;
|
||||
mobjtype_t type = ((actor->eflags & MFE_UNDERWATER) ? MT_UWEXPLODE : MT_SONIC3KBOSSEXPLODE);
|
||||
S_StartSound(actor, ((actor->eflags & MFE_UNDERWATER) ? sfx_s3k57 : sfx_s3k4e));
|
||||
P_SpawnMobj(actor->x, actor->y, actor->z, type);
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
mobj_t *b = P_SpawnMobj(actor->x+P_RandomRange(-dist, dist)*FRACUNIT,
|
||||
actor->y+P_RandomRange(-dist, dist)*FRACUNIT,
|
||||
actor->z+P_RandomRange(((actor->eflags & MFE_UNDERWATER) ? -dist : 0), dist)*FRACUNIT,
|
||||
type);
|
||||
fixed_t dx = b->x - actor->x, dy = b->y - actor->y, dz = b->z - actor->z;
|
||||
fixed_t dm = P_AproxDistance(dz, P_AproxDistance(dy, dx));
|
||||
b->momx = FixedDiv(dx, dm)*3;
|
||||
b->momy = FixedDiv(dy, dm)*3;
|
||||
b->momz = FixedDiv(dz, dm)*3;
|
||||
if ((actor->watertop == INT32_MAX) || (b->z + b->height > actor->watertop))
|
||||
b->flags &= ~MF_NOGRAVITY;
|
||||
}
|
||||
#undef dist
|
||||
|
||||
if (actor->watertop != INT32_MAX)
|
||||
P_SpawnMobj(actor->x, actor->y, actor->watertop, (actor->eflags & MFE_TOUCHLAVA) ? MT_LAVASPLISH : MT_SPLISH);
|
||||
}
|
||||
}
|
||||
|
||||
// Function: A_MineRange
|
||||
// Description: If the target gets too close, change the state to meleestate.
|
||||
//
|
||||
// var1 = Distance to alert at
|
||||
// var2 = unused
|
||||
//
|
||||
void A_MineRange(mobj_t *actor)
|
||||
{
|
||||
fixed_t dm;
|
||||
INT32 locvar1 = var1;
|
||||
// INT32 locvar2 = var2;
|
||||
|
||||
if (LUA_CallAction(A_MINERANGE, actor))
|
||||
return;
|
||||
|
||||
if (!actor->target)
|
||||
return;
|
||||
|
||||
dm = P_AproxDistance(actor->z - actor->target->z, P_AproxDistance(actor->y - actor->target->y, actor->x - actor->target->x));
|
||||
if ((dm>>FRACBITS) < locvar1)
|
||||
P_SetMobjState(actor, actor->info->meleestate);
|
||||
}
|
||||
|
||||
// Function: A_ConnectToGround
|
||||
// Description: Create a palm tree trunk/mine chain.
|
||||
//
|
||||
|
|
@ -11081,9 +11001,55 @@ void A_SPBChase(mobj_t *actor)
|
|||
return;
|
||||
}
|
||||
|
||||
static mobj_t *grenade;
|
||||
static fixed_t explodedist;
|
||||
|
||||
static inline BlockItReturn_t PIT_SSMineSearch(mobj_t *thing)
|
||||
{
|
||||
if (!grenade)
|
||||
return BMIT_ABORT;
|
||||
|
||||
if (grenade->flags2 & MF2_DEBRIS)
|
||||
return BMIT_ABORT;
|
||||
|
||||
if (thing->type != MT_PLAYER) // Don't explode for anything but an actual player.
|
||||
return BMIT_CONTINUE;
|
||||
|
||||
if (!(thing->flags & MF_SHOOTABLE))
|
||||
{
|
||||
// didn't do any damage
|
||||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
||||
if (netgame && thing->player && thing->player->spectator)
|
||||
return BMIT_CONTINUE;
|
||||
|
||||
if (thing == grenade->target && grenade->threshold != 0) // Don't blow up at your owner.
|
||||
return BMIT_CONTINUE;
|
||||
|
||||
if (thing->player && (thing->player->hyudorotimer
|
||||
|| ((gametyperules & GTR_BUMPERS) && thing->player && thing->player->bumper <= 0 && thing->player->karmadelay)))
|
||||
return BMIT_CONTINUE;
|
||||
|
||||
// see if it went over / under
|
||||
if (grenade->z - explodedist > thing->z + thing->height)
|
||||
return BMIT_CONTINUE; // overhead
|
||||
if (grenade->z + grenade->height + explodedist < thing->z)
|
||||
return BMIT_CONTINUE; // underneath
|
||||
|
||||
if (P_AproxDistance(P_AproxDistance(thing->x - grenade->x, thing->y - grenade->y),
|
||||
thing->z - grenade->z) > explodedist)
|
||||
return BMIT_CONTINUE; // Too far away
|
||||
|
||||
// Explode!
|
||||
P_SetMobjState(grenade, grenade->info->deathstate);
|
||||
return BMIT_ABORT;
|
||||
}
|
||||
|
||||
void A_SSMineSearch(mobj_t *actor)
|
||||
{
|
||||
fixed_t dis = INT32_MAX;
|
||||
INT32 bx, by, xl, xh, yl, yh;
|
||||
explodedist = FixedMul(actor->info->painchance, mapobjectscale);
|
||||
|
||||
if (LUA_CallAction(A_SSMINESEARCH, actor))
|
||||
return;
|
||||
|
|
@ -11091,19 +11057,66 @@ 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);
|
||||
|
||||
dis = actor->info->painchance;
|
||||
if (actor->state == &states[S_SSMINE_DEPLOY8])
|
||||
dis = (3*dis)>>1;
|
||||
// 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;
|
||||
|
||||
K_DoMineSearch(actor, dis);
|
||||
grenade = actor;
|
||||
|
||||
for (by = yl; by <= yh; by++)
|
||||
for (bx = xl; bx <= xh; bx++)
|
||||
P_BlockThingsIterator(bx, by, PIT_SSMineSearch);
|
||||
}
|
||||
|
||||
static inline BlockItReturn_t PIT_MineExplode(mobj_t *thing)
|
||||
{
|
||||
if (!grenade || P_MobjWasRemoved(grenade))
|
||||
return BMIT_ABORT; // 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 BMIT_ABORT;
|
||||
|
||||
if (thing == grenade || thing->type == MT_MINEEXPLOSIONSOUND) // Don't explode yourself! Endless loop!
|
||||
return BMIT_CONTINUE;
|
||||
|
||||
if (!(thing->flags & MF_SHOOTABLE) || (thing->flags & MF_SCENERY))
|
||||
return BMIT_CONTINUE;
|
||||
|
||||
if (netgame && thing->player && thing->player->spectator)
|
||||
return BMIT_CONTINUE;
|
||||
|
||||
if ((gametyperules & GTR_BUMPERS) && grenade->target && grenade->target->player && grenade->target->player->bumper <= 0 && thing == grenade->target)
|
||||
return BMIT_CONTINUE;
|
||||
|
||||
// see if it went over / under
|
||||
if (grenade->z - explodedist > thing->z + thing->height)
|
||||
return BMIT_CONTINUE; // overhead
|
||||
if (grenade->z + grenade->height + explodedist < thing->z)
|
||||
return BMIT_CONTINUE; // underneath
|
||||
|
||||
if (P_AproxDistance(P_AproxDistance(thing->x - grenade->x, thing->y - grenade->y),
|
||||
thing->z - grenade->z) > explodedist)
|
||||
return BMIT_CONTINUE; // Too far away
|
||||
|
||||
P_DamageMobj(thing, grenade, grenade->target, 1, DMG_EXPLODE);
|
||||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
@ -11111,13 +11124,33 @@ void A_SSMineExplode(mobj_t *actor)
|
|||
if (actor->flags2 & MF2_DEBRIS)
|
||||
return;
|
||||
|
||||
K_MineExplodeAttack(actor, (3*actor->info->painchance)>>1, (boolean)locvar1);
|
||||
type = (mobjtype_t)locvar1;
|
||||
|
||||
skincolornum_t color = SKINCOLOR_KETCHUP;
|
||||
if (!P_MobjWasRemoved(actor->target) && actor->target->player)
|
||||
color = actor->target->player->skincolor;
|
||||
// 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;
|
||||
|
||||
K_SpawnMineExplosion(actor, color);
|
||||
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.
|
||||
}
|
||||
|
||||
void A_LandMineExplode(mobj_t *actor)
|
||||
|
|
|
|||
21
src/p_map.c
21
src/p_map.c
|
|
@ -812,6 +812,27 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
|
|||
return K_MineCollide(thing, g_tm.thing) ? BMIT_CONTINUE : BMIT_ABORT;
|
||||
}
|
||||
|
||||
if (g_tm.thing->type == MT_MINEEXPLOSION)
|
||||
{
|
||||
// see if it went over / under
|
||||
if (g_tm.thing->z > thing->z + thing->height)
|
||||
return true; // overhead
|
||||
if (g_tm.thing->z + g_tm.thing->height < thing->z)
|
||||
return true; // underneath
|
||||
|
||||
return K_MineExplosionCollide(g_tm.thing, thing);
|
||||
}
|
||||
else if (thing->type == MT_MINEEXPLOSION)
|
||||
{
|
||||
// see if it went over / under
|
||||
if (g_tm.thing->z > thing->z + thing->height)
|
||||
return true; // overhead
|
||||
if (g_tm.thing->z + g_tm.thing->height < thing->z)
|
||||
return true; // underneath
|
||||
|
||||
return K_MineExplosionCollide(thing, g_tm.thing);
|
||||
}
|
||||
|
||||
if (g_tm.thing->type == MT_LANDMINE)
|
||||
{
|
||||
// see if it went over / under
|
||||
|
|
|
|||
45
src/p_mobj.c
45
src/p_mobj.c
|
|
@ -7833,6 +7833,9 @@ 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!
|
||||
|
|
@ -8624,6 +8627,34 @@ 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_BOOSTFLAME:
|
||||
if (!mobj->target || !mobj->target->health)
|
||||
{
|
||||
|
|
@ -9987,17 +10018,6 @@ 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;
|
||||
|
|
@ -10302,9 +10322,6 @@ 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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue