Merge branch 'mt-null-spawning' into 'next'

Remove MT_NULL hacks

Closes #721

See merge request STJr/SRB2!1729
This commit is contained in:
sphere 2022-02-19 20:24:34 +00:00
commit d532546e46
10 changed files with 133 additions and 67 deletions

View file

@ -3496,6 +3496,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
// because sadly no one remembers this place while searching for full state names.
const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity testing later.
"MT_NULL",
"MT_RAY",
"MT_UNKNOWN",
"MT_THOK", // Thok! mobj

View file

@ -3964,6 +3964,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_RAY
-1, // doomednum
S_NULL, // spawnstate
0, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // 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
0, // radius
0, // height
0, // display offset
0, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags
S_NULL // raisestate
},
{ // MT_UNKNOWN
-1, // doomednum
S_UNKNOWN, // spawnstate

View file

@ -4316,6 +4316,7 @@ extern playersprite_t free_spr2;
typedef enum mobj_type
{
MT_NULL,
MT_RAY, // General purpose mobj
MT_UNKNOWN,
MT_THOK, // Thok! mobj

View file

@ -347,6 +347,10 @@ static boolean prepare_mobj_hook
int hook_type,
mobjtype_t mobj_type
){
#ifdef PARANOIA
if (mobj_type == MT_NULL)
I_Error("MT_NULL has been passed to a mobj hook\n");
#endif
return init_hook_type(hook, default_status,
hook_type, mobj_type, NULL,
mobj_hook_available(hook_type, mobj_type));

View file

@ -2655,7 +2655,7 @@ void A_LobShot(mobj_t *actor)
{
INT32 locvar1 = var1;
INT32 locvar2 = var2 >> 16;
mobj_t *shot, *hitspot;
mobj_t *shot;
angle_t an;
fixed_t z;
fixed_t dist;
@ -2694,11 +2694,6 @@ void A_LobShot(mobj_t *actor)
P_SetScale(shot, actor->scale);
}
// Keep track of where it's going to land
hitspot = P_SpawnMobj(actor->target->x&(64*FRACUNIT-1), actor->target->y&(64*FRACUNIT-1), actor->target->subsector->sector->floorheight, MT_NULL);
hitspot->tics = airtime;
P_SetTarget(&shot->tracer, hitspot);
P_SetTarget(&shot->target, actor); // where it came from
shot->angle = an = actor->angle;
@ -3334,20 +3329,18 @@ void A_SkullAttack(mobj_t *actor)
actor->angle += (P_RandomChance(FRACUNIT/2)) ? ANGLE_90 : -ANGLE_90;
else if (locvar1 == 3)
{
statenum_t oldspawnstate = mobjinfo[MT_NULL].spawnstate;
UINT32 oldflags = mobjinfo[MT_NULL].flags;
fixed_t oldradius = mobjinfo[MT_NULL].radius;
fixed_t oldheight = mobjinfo[MT_NULL].height;
mobj_t *check;
statenum_t oldspawnstate = mobjinfo[MT_RAY].spawnstate;
UINT32 oldflags = mobjinfo[MT_RAY].flags;
fixed_t oldradius = mobjinfo[MT_RAY].radius;
fixed_t oldheight = mobjinfo[MT_RAY].height;
INT32 i, j;
static INT32 k;/* static for (at least) GCC 9.1 weirdness */
boolean allow;
angle_t testang = 0;
mobjinfo[MT_NULL].spawnstate = S_INVISIBLE;
mobjinfo[MT_NULL].flags = MF_NOGRAVITY|MF_NOTHINK|MF_NOCLIPTHING|MF_NOBLOCKMAP;
mobjinfo[MT_NULL].radius = mobjinfo[actor->type].radius;
mobjinfo[MT_NULL].height = mobjinfo[actor->type].height;
mobjinfo[MT_RAY].spawnstate = S_INVISIBLE;
mobjinfo[MT_RAY].flags = MF_NOGRAVITY|MF_NOTHINK|MF_NOCLIPTHING|MF_NOBLOCKMAP;
mobjinfo[MT_RAY].radius = mobjinfo[actor->type].radius;
mobjinfo[MT_RAY].height = mobjinfo[actor->type].height;
if (P_RandomChance(FRACUNIT/2)) // port priority 1?
{
@ -3360,15 +3353,12 @@ void A_SkullAttack(mobj_t *actor)
j = 9;
}
#define dostuff(q) check = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_NULL);\
#define dostuff(q) \
testang = actor->angle + ((i+(q))*ANG10);\
allow = (P_TryMove(check,\
P_ReturnThrustX(check, testang, dist + 2*actor->radius),\
P_ReturnThrustY(check, testang, dist + 2*actor->radius),\
true));\
P_RemoveMobj(check);\
if (allow)\
break;
if (P_CheckMove(actor,\
P_ReturnThrustX(actor, testang, dist + 2*actor->radius),\
P_ReturnThrustY(actor, testang, dist + 2*actor->radius),\
true)) break;
if (P_RandomChance(FRACUNIT/2)) // port priority 2?
{
@ -3394,10 +3384,10 @@ void A_SkullAttack(mobj_t *actor)
#undef dostuff
mobjinfo[MT_NULL].spawnstate = oldspawnstate;
mobjinfo[MT_NULL].flags = oldflags;
mobjinfo[MT_NULL].radius = oldradius;
mobjinfo[MT_NULL].height = oldheight;
mobjinfo[MT_RAY].spawnstate = oldspawnstate;
mobjinfo[MT_RAY].flags = oldflags;
mobjinfo[MT_RAY].radius = oldradius;
mobjinfo[MT_RAY].height = oldheight;
}
an = actor->angle >> ANGLETOFINESHIFT;
@ -4189,7 +4179,6 @@ void A_CustomPower(mobj_t *actor)
player_t *player;
INT32 locvar1 = var1;
INT32 locvar2 = var2;
boolean spawnshield = false;
if (LUA_CallAction(A_CUSTOMPOWER, actor))
return;
@ -4208,15 +4197,10 @@ void A_CustomPower(mobj_t *actor)
player = actor->target->player;
if (locvar1 == pw_shield && player->powers[pw_shield] != locvar2)
spawnshield = true;
P_SetPower(player, locvar1, locvar2);
player->powers[locvar1] = (UINT16)locvar2;
if (actor->info->seesound)
S_StartSound(player->mo, actor->info->seesound);
if (spawnshield) //workaround for a bug
P_SpawnShieldOrb(player);
}
// Function: A_GiveWeapon
@ -8292,7 +8276,7 @@ void A_Boss3ShockThink(mobj_t *actor)
snew->angle = (actor->angle + snext->angle) >> 1;
P_SetTarget(&snew->target, actor->target);
snew->fuse = actor->fuse;
P_SetScale(snew, actor->scale);
snew->destscale = actor->destscale;
snew->scalespeed = actor->scalespeed;

View file

@ -155,6 +155,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff);
void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative);
void P_RestoreMusic(player_t *player);
void P_SetPower(player_t *player, powertype_t power, UINT16 value);
void P_SpawnShieldOrb(player_t *player);
void P_SwitchShield(player_t *player, UINT16 shieldtype);
mobj_t *P_SpawnGhostMobj(mobj_t *mobj);
@ -410,6 +411,7 @@ void P_SetUnderlayPosition(mobj_t *thing);
boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y);
boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam);
boolean P_CheckMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff);
boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff);
boolean P_Move(mobj_t *actor, fixed_t speed);
boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z);

View file

@ -2654,17 +2654,17 @@ boolean PIT_PushableMoved(mobj_t *thing)
return true;
}
//
// P_TryMove
// Attempt to move to a new position.
//
boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
static boolean
increment_move
( mobj_t * thing,
fixed_t x,
fixed_t y,
boolean allowdropoff)
{
fixed_t tryx = thing->x;
fixed_t tryy = thing->y;
fixed_t radius = thing->radius;
fixed_t thingtop;
fixed_t startingonground = P_IsObjectOnGround(thing);
floatok = false;
if (radius < MAXRADIUS/2)
@ -2802,7 +2802,38 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
}
} while (tryx != x || tryy != y);
return true;
}
//
// P_CheckMove
// Check if a P_TryMove would be successful.
//
boolean P_CheckMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
{
boolean moveok;
mobj_t *hack = P_SpawnMobjFromMobj(thing, 0, 0, 0, MT_RAY);
hack->radius = thing->radius;
hack->height = thing->height;
moveok = increment_move(hack, x, y, allowdropoff);
P_RemoveMobj(hack);
return moveok;
}
//
// P_TryMove
// Attempt to move to a new position.
//
boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
{
fixed_t startingonground = P_IsObjectOnGround(thing);
// The move is ok!
if (!increment_move(thing, x, y, allowdropoff))
return false;
// If it's a pushable object, check if anything is
// standing on top and move it, too.

View file

@ -10481,7 +10481,17 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
const mobjinfo_t *info = &mobjinfo[type];
SINT8 sc = -1;
state_t *st;
mobj_t *mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL);
mobj_t *mobj;
if (type == MT_NULL)
{
#ifdef PARANOIA
I_Error("Tried to spawn MT_NULL\n");
#endif
return NULL;
}
mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL);
// this is officially a mobj, declared as soon as possible.
mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker;

View file

@ -2888,25 +2888,20 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
case 434: // Custom Power
if (mo && mo->player)
{
mobj_t *dummy = P_SpawnMobj(mo->x, mo->y, mo->z, MT_NULL);
var1 = sides[line->sidenum[0]].toptexture; //(line->dx>>FRACBITS)-1;
powertype_t power = sides[line->sidenum[0]].toptexture; //(line->dx>>FRACBITS)-1;
UINT16 value;
if (line->sidenum[1] != 0xffff && line->flags & ML_BLOCKMONSTERS) // read power from back sidedef
var2 = sides[line->sidenum[1]].toptexture;
value = sides[line->sidenum[1]].toptexture;
else if (line->flags & ML_NOCLIMB) // 'Infinite'
var2 = UINT16_MAX;
value = UINT16_MAX;
else
var2 = sides[line->sidenum[0]].textureoffset>>FRACBITS;
value = sides[line->sidenum[0]].textureoffset>>FRACBITS;
P_SetTarget(&dummy->target, mo);
A_CustomPower(dummy);
P_SetPower(mo->player, power, value);
if (bot) {
P_SetTarget(&dummy->target, bot);
A_CustomPower(dummy);
}
P_RemoveMobj(dummy);
if (bot)
P_SetPower(bot->player, power, value);
}
break;

View file

@ -2011,6 +2011,24 @@ void P_SwitchShield(player_t *player, UINT16 shieldtype)
}
}
//
// P_SetPower
//
// Sets a power and spawns a shield orb if required.
//
void P_SetPower(player_t *player, powertype_t power, UINT16 value)
{
boolean spawnshield = false;
if (power == pw_shield && player->powers[pw_shield] != value)
spawnshield = true;
player->powers[power] = value;
if (spawnshield) //workaround for a bug
P_SpawnShieldOrb(player);
}
//
// P_SpawnGhostMobj
//
@ -6281,18 +6299,11 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad
if (player->exiting)
return;
if (!P_CheckMove(player->mo,
player->mo->x + player->mo->momx,
player->mo->y + player->mo->momy, true))
{
boolean notallowed;
mobj_t *hack = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_NULL);
hack->flags = MF_NOGRAVITY;
hack->radius = player->mo->radius;
hack->height = player->mo->height;
hack->z = player->mo->z;
P_SetThingPosition(hack);
notallowed = (!(P_TryMove(hack, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, true)));
P_RemoveMobj(hack);
if (notallowed)
return;
return;
}
{