mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-02-01 06:00:45 +00:00
Merge branch 'fix-segfault-removemobj-spawn' into 'next'
Fix segfaults when P_RemoveMobj is called from MobjSpawn hook See merge request STJr/SRB2!1973
This commit is contained in:
commit
b5a4f227f6
10 changed files with 1671 additions and 951 deletions
|
@ -614,6 +614,9 @@ void B_HandleFlightIndicator(player_t *player)
|
|||
|
||||
// otherwise, spawn it
|
||||
P_SetTarget(&tails->hnext, P_SpawnMobjFromMobj(tails, 0, 0, 0, MT_OVERLAY));
|
||||
if (P_MobjWasRemoved(tails->hnext))
|
||||
return; // we can't spawn one, so it can't exist
|
||||
|
||||
P_SetTarget(&tails->hnext->target, tails);
|
||||
P_SetTarget(&tails->hnext->hprev, tails);
|
||||
P_SetMobjState(tails->hnext, S_FLIGHTINDICATOR);
|
||||
|
|
143
src/g_demo.c
143
src/g_demo.c
|
@ -798,32 +798,40 @@ void G_GhostTicker(void)
|
|||
if (type == MT_GHOST)
|
||||
{
|
||||
mobj = P_SpawnGhostMobj(g->mo); // does a large portion of the work for us
|
||||
mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|tr_trans60<<FF_TRANSSHIFT; // P_SpawnGhostMobj sets trans50, we want trans60
|
||||
if (!P_MobjWasRemoved(mobj))
|
||||
mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|tr_trans60<<FF_TRANSSHIFT; // P_SpawnGhostMobj sets trans50, we want trans60
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj = P_SpawnMobjFromMobj(g->mo, 0, 0, -FixedDiv(FixedMul(g->mo->info->height, g->mo->scale) - g->mo->height,3*FRACUNIT), MT_THOK);
|
||||
mobj->sprite = states[mobjinfo[type].spawnstate].sprite;
|
||||
mobj->frame = (states[mobjinfo[type].spawnstate].frame & FF_FRAMEMASK) | tr_trans60<<FF_TRANSSHIFT;
|
||||
mobj->color = g->mo->color;
|
||||
mobj->skin = g->mo->skin;
|
||||
P_SetScale(mobj, (mobj->destscale = g->mo->scale));
|
||||
|
||||
if (type == MT_THOK) // spintrail-specific modification for MT_THOK
|
||||
if (!P_MobjWasRemoved(mobj))
|
||||
{
|
||||
mobj->frame = FF_TRANS80;
|
||||
mobj->fuse = mobj->tics;
|
||||
mobj->sprite = states[mobjinfo[type].spawnstate].sprite;
|
||||
mobj->frame = (states[mobjinfo[type].spawnstate].frame & FF_FRAMEMASK) | tr_trans60<<FF_TRANSSHIFT;
|
||||
mobj->color = g->mo->color;
|
||||
mobj->skin = g->mo->skin;
|
||||
P_SetScale(mobj, (mobj->destscale = g->mo->scale));
|
||||
|
||||
if (type == MT_THOK) // spintrail-specific modification for MT_THOK
|
||||
{
|
||||
mobj->frame = FF_TRANS80;
|
||||
mobj->fuse = mobj->tics;
|
||||
}
|
||||
mobj->tics = -1; // nope.
|
||||
}
|
||||
mobj->tics = -1; // nope.
|
||||
}
|
||||
mobj->floorz = mobj->z;
|
||||
mobj->ceilingz = mobj->z+mobj->height;
|
||||
P_UnsetThingPosition(mobj);
|
||||
mobj->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up...
|
||||
P_SetThingPosition(mobj);
|
||||
if (!mobj->fuse)
|
||||
mobj->fuse = 8;
|
||||
P_SetTarget(&mobj->target, g->mo);
|
||||
|
||||
if (!P_MobjWasRemoved(mobj))
|
||||
{
|
||||
mobj->floorz = mobj->z;
|
||||
mobj->ceilingz = mobj->z+mobj->height;
|
||||
P_UnsetThingPosition(mobj);
|
||||
mobj->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up...
|
||||
P_SetThingPosition(mobj);
|
||||
if (!mobj->fuse)
|
||||
mobj->fuse = 8;
|
||||
P_SetTarget(&mobj->target, g->mo);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (xziptic & EZT_HIT)
|
||||
|
@ -847,6 +855,8 @@ void G_GhostTicker(void)
|
|||
|| health != 0 || i >= 4) // only spawn for the first 4 hits per frame, to prevent ghosts from splode-spamming too bad.
|
||||
continue;
|
||||
poof = P_SpawnMobj(x, y, z, MT_GHOST);
|
||||
if (P_MobjWasRemoved(poof))
|
||||
continue;
|
||||
poof->angle = angle;
|
||||
poof->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up...
|
||||
poof->health = 0;
|
||||
|
@ -892,19 +902,22 @@ void G_GhostTicker(void)
|
|||
if (follow)
|
||||
P_RemoveMobj(follow);
|
||||
P_SetTarget(&follow, P_SpawnMobjFromMobj(g->mo, 0, 0, 0, MT_GHOST));
|
||||
P_SetTarget(&follow->tracer, g->mo);
|
||||
follow->tics = -1;
|
||||
temp = READINT16(g->p)<<FRACBITS;
|
||||
follow->height = FixedMul(follow->scale, temp);
|
||||
if (!P_MobjWasRemoved(follow))
|
||||
{
|
||||
P_SetTarget(&follow->tracer, g->mo);
|
||||
follow->tics = -1;
|
||||
temp = READINT16(g->p)<<FRACBITS;
|
||||
follow->height = FixedMul(follow->scale, temp);
|
||||
|
||||
if (followtic & FZT_LINKDRAW)
|
||||
follow->flags2 |= MF2_LINKDRAW;
|
||||
if (followtic & FZT_LINKDRAW)
|
||||
follow->flags2 |= MF2_LINKDRAW;
|
||||
|
||||
if (followtic & FZT_COLORIZED)
|
||||
follow->colorized = true;
|
||||
if (followtic & FZT_COLORIZED)
|
||||
follow->colorized = true;
|
||||
|
||||
if (followtic & FZT_SKIN)
|
||||
follow->skin = &skins[READUINT8(g->p)];
|
||||
if (followtic & FZT_SKIN)
|
||||
follow->skin = &skins[READUINT8(g->p)];
|
||||
}
|
||||
}
|
||||
if (follow)
|
||||
{
|
||||
|
@ -1097,28 +1110,35 @@ void G_ReadMetalTic(mobj_t *metal)
|
|||
else
|
||||
{
|
||||
mobj = P_SpawnMobjFromMobj(metal, 0, 0, -FixedDiv(FixedMul(metal->info->height, metal->scale) - metal->height,3*FRACUNIT), MT_THOK);
|
||||
mobj->sprite = states[mobjinfo[type].spawnstate].sprite;
|
||||
mobj->frame = states[mobjinfo[type].spawnstate].frame;
|
||||
mobj->angle = metal->angle;
|
||||
mobj->color = metal->color;
|
||||
mobj->skin = metal->skin;
|
||||
P_SetScale(mobj, (mobj->destscale = metal->scale));
|
||||
|
||||
if (type == MT_THOK) // spintrail-specific modification for MT_THOK
|
||||
if (!P_MobjWasRemoved(mobj))
|
||||
{
|
||||
mobj->frame = FF_TRANS70;
|
||||
mobj->fuse = mobj->tics;
|
||||
mobj->sprite = states[mobjinfo[type].spawnstate].sprite;
|
||||
mobj->frame = states[mobjinfo[type].spawnstate].frame;
|
||||
mobj->angle = metal->angle;
|
||||
mobj->color = metal->color;
|
||||
mobj->skin = metal->skin;
|
||||
P_SetScale(mobj, (mobj->destscale = metal->scale));
|
||||
|
||||
if (type == MT_THOK) // spintrail-specific modification for MT_THOK
|
||||
{
|
||||
mobj->frame = FF_TRANS70;
|
||||
mobj->fuse = mobj->tics;
|
||||
}
|
||||
mobj->tics = -1; // nope.
|
||||
}
|
||||
mobj->tics = -1; // nope.
|
||||
}
|
||||
mobj->floorz = mobj->z;
|
||||
mobj->ceilingz = mobj->z+mobj->height;
|
||||
P_UnsetThingPosition(mobj);
|
||||
mobj->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up...
|
||||
P_SetThingPosition(mobj);
|
||||
if (!mobj->fuse)
|
||||
mobj->fuse = 8;
|
||||
P_SetTarget(&mobj->target, metal);
|
||||
|
||||
if (!P_MobjWasRemoved(mobj))
|
||||
{
|
||||
mobj->floorz = mobj->z;
|
||||
mobj->ceilingz = mobj->z+mobj->height;
|
||||
P_UnsetThingPosition(mobj);
|
||||
mobj->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up...
|
||||
P_SetThingPosition(mobj);
|
||||
if (!mobj->fuse)
|
||||
mobj->fuse = 8;
|
||||
P_SetTarget(&mobj->target, metal);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (xziptic & EZT_SPRITE)
|
||||
|
@ -1140,19 +1160,22 @@ void G_ReadMetalTic(mobj_t *metal)
|
|||
if (follow)
|
||||
P_RemoveMobj(follow);
|
||||
P_SetTarget(&follow, P_SpawnMobjFromMobj(metal, 0, 0, 0, MT_GHOST));
|
||||
P_SetTarget(&follow->tracer, metal);
|
||||
follow->tics = -1;
|
||||
temp = READINT16(metal_p)<<FRACBITS;
|
||||
follow->height = FixedMul(follow->scale, temp);
|
||||
if (!P_MobjWasRemoved(follow))
|
||||
{
|
||||
P_SetTarget(&follow->tracer, metal);
|
||||
follow->tics = -1;
|
||||
temp = READINT16(metal_p)<<FRACBITS;
|
||||
follow->height = FixedMul(follow->scale, temp);
|
||||
|
||||
if (followtic & FZT_LINKDRAW)
|
||||
follow->flags2 |= MF2_LINKDRAW;
|
||||
if (followtic & FZT_LINKDRAW)
|
||||
follow->flags2 |= MF2_LINKDRAW;
|
||||
|
||||
if (followtic & FZT_COLORIZED)
|
||||
follow->colorized = true;
|
||||
if (followtic & FZT_COLORIZED)
|
||||
follow->colorized = true;
|
||||
|
||||
if (followtic & FZT_SKIN)
|
||||
follow->skin = &skins[READUINT8(metal_p)];
|
||||
if (followtic & FZT_SKIN)
|
||||
follow->skin = &skins[READUINT8(metal_p)];
|
||||
}
|
||||
}
|
||||
if (follow)
|
||||
{
|
||||
|
@ -2535,7 +2558,9 @@ void G_AddGhost(char *defdemoname)
|
|||
{ // A bit more complex than P_SpawnPlayer because ghosts aren't solid and won't just push themselves out of the ceiling.
|
||||
fixed_t z,f,c;
|
||||
fixed_t offset = mthing->z << FRACBITS;
|
||||
gh->mo = P_SpawnMobj(mthing->x << FRACBITS, mthing->y << FRACBITS, 0, MT_GHOST);
|
||||
P_SetTarget(&gh->mo, P_SpawnMobj(mthing->x << FRACBITS, mthing->y << FRACBITS, 0, MT_GHOST));
|
||||
if (P_MobjWasRemoved(gh->mo))
|
||||
return;
|
||||
gh->mo->angle = FixedAngle(mthing->angle << FRACBITS);
|
||||
f = gh->mo->floorz;
|
||||
c = gh->mo->ceilingz - mobjinfo[MT_PLAYER].height;
|
||||
|
|
914
src/p_enemy.c
914
src/p_enemy.c
File diff suppressed because it is too large
Load diff
|
@ -1921,6 +1921,9 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
|
|||
for (c = topz; c > bottomz; c -= spacing)
|
||||
{
|
||||
spawned = P_SpawnMobj(a, b, c, type);
|
||||
if (P_MobjWasRemoved(spawned))
|
||||
continue;
|
||||
|
||||
spawned->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones
|
||||
|
||||
if (fromcenter)
|
||||
|
|
261
src/p_inter.c
261
src/p_inter.c
|
@ -256,6 +256,9 @@ void P_DoNightsScore(player_t *player)
|
|||
player->linktimer = nightslinktics;
|
||||
}
|
||||
|
||||
if (P_MobjWasRemoved(dummymo))
|
||||
return;
|
||||
|
||||
// Award 10-100 score, doubled if bonus time is active
|
||||
P_AddPlayerScore(player, min(player->linkcount,10)*(player->bonustime ? 20 : 10));
|
||||
P_SetMobjState(dummymo, (player->bonustime ? dummymo->info->xdeathstate : dummymo->info->spawnstate) + min(player->linkcount,10)-1);
|
||||
|
@ -1301,7 +1304,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
{
|
||||
// A flicky orbits us now
|
||||
mobj_t *flickyobj = P_SpawnMobj(toucher->x, toucher->y, toucher->z + toucher->info->height, MT_NIGHTOPIANHELPER);
|
||||
P_SetTarget(&flickyobj->target, toucher);
|
||||
if (!P_MobjWasRemoved(flickyobj))
|
||||
P_SetTarget(&flickyobj->target, toucher);
|
||||
|
||||
player->powers[pw_nights_helper] = (UINT16)special->info->speed;
|
||||
}
|
||||
|
@ -1312,7 +1316,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
if (playeringame[i] && players[i].mo && players[i].powers[pw_carry] == CR_NIGHTSMODE) {
|
||||
players[i].powers[pw_nights_helper] = (UINT16)special->info->speed;
|
||||
flickyobj = P_SpawnMobj(players[i].mo->x, players[i].mo->y, players[i].mo->z + players[i].mo->info->height, MT_NIGHTOPIANHELPER);
|
||||
P_SetTarget(&flickyobj->target, players[i].mo);
|
||||
if (!P_MobjWasRemoved(flickyobj))
|
||||
P_SetTarget(&flickyobj->target, players[i].mo);
|
||||
}
|
||||
if (special->info->deathsound != sfx_None)
|
||||
S_StartSound(NULL, special->info->deathsound);
|
||||
|
@ -1821,9 +1826,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
if (!player->bot && player->bot != BOT_MPAI && special->fuse <= TICRATE && player->powers[pw_carry] != CR_MINECART && !(player->powers[pw_ignorelatch] & (1<<15)))
|
||||
{
|
||||
mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART);
|
||||
P_SetTarget(&mcart->target, toucher);
|
||||
mcart->angle = toucher->angle = player->drawangle = special->angle;
|
||||
mcart->friction = FRACUNIT;
|
||||
if (!P_MobjWasRemoved(mcart))
|
||||
{
|
||||
P_SetTarget(&mcart->target, toucher);
|
||||
mcart->angle = toucher->angle = player->drawangle = special->angle;
|
||||
mcart->friction = FRACUNIT;
|
||||
}
|
||||
|
||||
P_ResetPlayer(player);
|
||||
player->pflags |= PF_JUMPDOWN;
|
||||
|
@ -2593,7 +2601,8 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
break;
|
||||
}
|
||||
|
||||
P_SetMobjState(scoremobj, scorestate);
|
||||
if (!P_MobjWasRemoved(scoremobj))
|
||||
P_SetMobjState(scoremobj, scorestate);
|
||||
|
||||
source->player->scoreadd = locscoreadd;
|
||||
}
|
||||
|
@ -2754,6 +2763,8 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
mo = P_SpawnMobj(inflictor->x + inflictor->momx, inflictor->y + inflictor->momy, inflictor->z + (inflictor->height / 2) + inflictor->momz, MT_EXTRALARGEBUBBLE);
|
||||
else
|
||||
mo = P_SpawnMobj(target->x, target->y, target->z, MT_EXTRALARGEBUBBLE);
|
||||
if (P_MobjWasRemoved(mo))
|
||||
break;
|
||||
mo->destscale = target->scale;
|
||||
P_SetScale(mo, mo->destscale);
|
||||
P_SetMobjState(mo, mo->info->raisestate);
|
||||
|
@ -2832,8 +2843,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
mo->angle = FixedAngle((P_RandomKey(36)*10)<<FRACBITS);
|
||||
|
||||
mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_BOSSJUNK);
|
||||
mo2->angle = mo->angle;
|
||||
P_SetMobjState(mo2, S_BOSSSEBH2);
|
||||
if (!P_MobjWasRemoved(mo2))
|
||||
{
|
||||
mo2->angle = mo->angle;
|
||||
P_SetMobjState(mo2, S_BOSSSEBH2);
|
||||
}
|
||||
|
||||
if (++i == 2) // we've already removed 2 of these, let's stop now
|
||||
break;
|
||||
|
@ -2932,7 +2946,10 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
if (flip)
|
||||
momz *= -1;
|
||||
#define makechunk(angtweak, xmov, ymov) \
|
||||
do {\
|
||||
chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_SPIKE);\
|
||||
if (P_MobjWasRemoved(chunk))\
|
||||
break;\
|
||||
P_SetMobjState(chunk, target->info->xdeathstate);\
|
||||
chunk->health = 0;\
|
||||
chunk->angle = angtweak;\
|
||||
|
@ -2942,7 +2959,8 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
chunk->y += ymov;\
|
||||
P_SetThingPosition(chunk);\
|
||||
P_InstaThrust(chunk,chunk->angle, 4*scale);\
|
||||
chunk->momz = momz
|
||||
chunk->momz = momz;\
|
||||
} while (0)
|
||||
|
||||
makechunk(ang + ANGLE_180, -xoffs, -yoffs);
|
||||
makechunk(ang, xoffs, yoffs);
|
||||
|
@ -2955,20 +2973,23 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
momz *= -1;
|
||||
|
||||
chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_SPIKE);
|
||||
P_SetMobjState(chunk, target->info->deathstate);
|
||||
chunk->health = 0;
|
||||
chunk->angle = ang + ANGLE_180;
|
||||
P_UnsetThingPosition(chunk);
|
||||
chunk->flags = MF_NOCLIP;
|
||||
chunk->x -= xoffs;
|
||||
chunk->y -= yoffs;
|
||||
if (flip)
|
||||
chunk->z -= 12*scale;
|
||||
else
|
||||
chunk->z += 12*scale;
|
||||
P_SetThingPosition(chunk);
|
||||
P_InstaThrust(chunk, chunk->angle, 2*scale);
|
||||
chunk->momz = momz;
|
||||
if (!P_MobjWasRemoved(chunk))
|
||||
{
|
||||
P_SetMobjState(chunk, target->info->deathstate);
|
||||
chunk->health = 0;
|
||||
chunk->angle = ang + ANGLE_180;
|
||||
P_UnsetThingPosition(chunk);
|
||||
chunk->flags = MF_NOCLIP;
|
||||
chunk->x -= xoffs;
|
||||
chunk->y -= yoffs;
|
||||
if (flip)
|
||||
chunk->z -= 12*scale;
|
||||
else
|
||||
chunk->z += 12*scale;
|
||||
P_SetThingPosition(chunk);
|
||||
P_InstaThrust(chunk, chunk->angle, 2*scale);
|
||||
chunk->momz = momz;
|
||||
}
|
||||
|
||||
P_SetMobjState(target, target->info->deathstate);
|
||||
target->health = 0;
|
||||
|
@ -2977,7 +2998,10 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
target->flags = MF_NOCLIP;
|
||||
target->x += xoffs;
|
||||
target->y += yoffs;
|
||||
target->z = chunk->z;
|
||||
if (flip)
|
||||
target->z -= 12*scale;
|
||||
else
|
||||
target->z += 12*scale;
|
||||
P_SetThingPosition(target);
|
||||
P_InstaThrust(target, target->angle, 2*scale);
|
||||
target->momz = momz;
|
||||
|
@ -3000,21 +3024,25 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
sprflip = P_RandomChance(FRACUNIT/2);
|
||||
|
||||
#define makechunk(angtweak, xmov, ymov) \
|
||||
chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_WALLSPIKE);\
|
||||
P_SetMobjState(chunk, target->info->xdeathstate);\
|
||||
chunk->health = 0;\
|
||||
chunk->angle = target->angle;\
|
||||
P_UnsetThingPosition(chunk);\
|
||||
chunk->flags = MF_NOCLIP;\
|
||||
chunk->x += xmov - forwardxoffs;\
|
||||
chunk->y += ymov - forwardyoffs;\
|
||||
P_SetThingPosition(chunk);\
|
||||
P_InstaThrust(chunk, angtweak, 4*scale);\
|
||||
chunk->momz = P_RandomRange(5, 7)*scale;\
|
||||
if (flip)\
|
||||
chunk->momz *= -1;\
|
||||
if (sprflip)\
|
||||
chunk->frame |= FF_VERTICALFLIP
|
||||
do {\
|
||||
chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_WALLSPIKE);\
|
||||
if (P_MobjWasRemoved(chunk))\
|
||||
break;\
|
||||
P_SetMobjState(chunk, target->info->xdeathstate);\
|
||||
chunk->health = 0;\
|
||||
chunk->angle = target->angle;\
|
||||
P_UnsetThingPosition(chunk);\
|
||||
chunk->flags = MF_NOCLIP;\
|
||||
chunk->x += xmov - forwardxoffs;\
|
||||
chunk->y += ymov - forwardyoffs;\
|
||||
P_SetThingPosition(chunk);\
|
||||
P_InstaThrust(chunk, angtweak, 4*scale);\
|
||||
chunk->momz = P_RandomRange(5, 7)*scale;\
|
||||
if (flip)\
|
||||
chunk->momz *= -1;\
|
||||
if (sprflip)\
|
||||
chunk->frame |= FF_VERTICALFLIP;\
|
||||
} while (0)
|
||||
|
||||
makechunk(ang + ANGLE_180, -xoffs, -yoffs);
|
||||
sprflip = !sprflip;
|
||||
|
@ -3026,21 +3054,23 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
sprflip = P_RandomChance(FRACUNIT/2);
|
||||
|
||||
chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_WALLSPIKE);
|
||||
|
||||
P_SetMobjState(chunk, target->info->deathstate);
|
||||
chunk->health = 0;
|
||||
chunk->angle = target->angle;
|
||||
P_UnsetThingPosition(chunk);
|
||||
chunk->flags = MF_NOCLIP;
|
||||
chunk->x += forwardxoffs - xoffs;
|
||||
chunk->y += forwardyoffs - yoffs;
|
||||
P_SetThingPosition(chunk);
|
||||
P_InstaThrust(chunk, ang + ANGLE_180, 2*scale);
|
||||
chunk->momz = P_RandomRange(5, 7)*scale;
|
||||
if (flip)
|
||||
chunk->momz *= -1;
|
||||
if (sprflip)
|
||||
chunk->frame |= FF_VERTICALFLIP;
|
||||
if (!P_MobjWasRemoved(chunk))
|
||||
{
|
||||
P_SetMobjState(chunk, target->info->deathstate);
|
||||
chunk->health = 0;
|
||||
chunk->angle = target->angle;
|
||||
P_UnsetThingPosition(chunk);
|
||||
chunk->flags = MF_NOCLIP;
|
||||
chunk->x += forwardxoffs - xoffs;
|
||||
chunk->y += forwardyoffs - yoffs;
|
||||
P_SetThingPosition(chunk);
|
||||
P_InstaThrust(chunk, ang + ANGLE_180, 2*scale);
|
||||
chunk->momz = P_RandomRange(5, 7)*scale;
|
||||
if (flip)
|
||||
chunk->momz *= -1;
|
||||
if (sprflip)
|
||||
chunk->frame |= FF_VERTICALFLIP;
|
||||
}
|
||||
|
||||
P_SetMobjState(target, target->info->deathstate);
|
||||
target->health = 0;
|
||||
|
@ -3921,6 +3951,8 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
|
|||
z += player->mo->height - mobjinfo[objType].height;
|
||||
|
||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, z, objType);
|
||||
if (P_MobjWasRemoved(mo))
|
||||
continue;
|
||||
|
||||
mo->fuse = 8*TICRATE;
|
||||
P_SetTarget(&mo->target, player->mo);
|
||||
|
@ -4054,6 +4086,9 @@ void P_PlayerWeaponPanelBurst(player_t *player)
|
|||
z += player->mo->height - mobjinfo[weptype].height;
|
||||
|
||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, z, weptype);
|
||||
if (P_MobjWasRemoved(mo))
|
||||
continue;
|
||||
|
||||
mo->reactiontime = ammoamt;
|
||||
mo->flags2 |= MF2_DONTRESPAWN;
|
||||
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT);
|
||||
|
@ -4087,13 +4122,13 @@ void P_PlayerWeaponAmmoBurst(player_t *player)
|
|||
mobj_t *mo;
|
||||
angle_t fa;
|
||||
fixed_t ns;
|
||||
INT32 i = 0;
|
||||
INT32 i;
|
||||
fixed_t z;
|
||||
|
||||
mobjtype_t weptype = 0;
|
||||
powertype_t power = 0;
|
||||
|
||||
while (true)
|
||||
for (i = 0;; i++)
|
||||
{
|
||||
if (player->powers[pw_bouncering])
|
||||
{
|
||||
|
@ -4138,6 +4173,8 @@ void P_PlayerWeaponAmmoBurst(player_t *player)
|
|||
z += player->mo->height - mobjinfo[weptype].height;
|
||||
|
||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, z, weptype);
|
||||
if (P_MobjWasRemoved(mo))
|
||||
continue;
|
||||
mo->health = player->powers[power];
|
||||
mo->flags2 |= MF2_DONTRESPAWN;
|
||||
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT);
|
||||
|
@ -4163,8 +4200,6 @@ void P_PlayerWeaponAmmoBurst(player_t *player)
|
|||
|
||||
if (i & 1)
|
||||
P_SetObjectMomZ(mo, 3*FRACUNIT, true);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4189,45 +4224,50 @@ void P_PlayerWeaponPanelOrAmmoBurst(player_t *player)
|
|||
player->ringweapons &= ~rwflag; \
|
||||
SETUP_DROP(pickup) \
|
||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, z, pickup); \
|
||||
mo->reactiontime = 0; \
|
||||
mo->flags2 |= MF2_DONTRESPAWN; \
|
||||
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \
|
||||
P_SetTarget(&mo->target, player->mo); \
|
||||
mo->fuse = 12*TICRATE; \
|
||||
mo->destscale = player->mo->scale; \
|
||||
P_SetScale(mo, player->mo->scale); \
|
||||
mo->momx = FixedMul(FINECOSINE(fa),ns); \
|
||||
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \
|
||||
mo->momy = FixedMul(FINESINE(fa),ns); \
|
||||
P_SetObjectMomZ(mo, 4*FRACUNIT, false); \
|
||||
if (i & 1) \
|
||||
P_SetObjectMomZ(mo, 4*FRACUNIT, true); \
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP) \
|
||||
mo->flags2 |= MF2_OBJECTFLIP; \
|
||||
++i; \
|
||||
if (!P_MobjWasRemoved(mo)) \
|
||||
{ \
|
||||
mo->reactiontime = 0; \
|
||||
mo->flags2 |= MF2_DONTRESPAWN; \
|
||||
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \
|
||||
P_SetTarget(&mo->target, player->mo); \
|
||||
mo->fuse = 12*TICRATE; \
|
||||
mo->destscale = player->mo->scale; \
|
||||
P_SetScale(mo, player->mo->scale); \
|
||||
mo->momx = FixedMul(FINECOSINE(fa),ns); \
|
||||
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \
|
||||
mo->momy = FixedMul(FINESINE(fa),ns); \
|
||||
P_SetObjectMomZ(mo, 4*FRACUNIT, false); \
|
||||
if (i & 1) \
|
||||
P_SetObjectMomZ(mo, 4*FRACUNIT, true); \
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP) \
|
||||
mo->flags2 |= MF2_OBJECTFLIP; \
|
||||
} \
|
||||
} \
|
||||
else if (player->powers[power] > 0) \
|
||||
{ \
|
||||
SETUP_DROP(ammo) \
|
||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, z, ammo); \
|
||||
mo->health = player->powers[power]; \
|
||||
mo->flags2 |= MF2_DONTRESPAWN; \
|
||||
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \
|
||||
P_SetTarget(&mo->target, player->mo); \
|
||||
mo->fuse = 12*TICRATE; \
|
||||
mo->destscale = player->mo->scale; \
|
||||
P_SetScale(mo, player->mo->scale); \
|
||||
mo->momx = FixedMul(FINECOSINE(fa),ns); \
|
||||
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \
|
||||
mo->momy = FixedMul(FINESINE(fa),ns); \
|
||||
P_SetObjectMomZ(mo, 3*FRACUNIT, false); \
|
||||
if (i & 1) \
|
||||
P_SetObjectMomZ(mo, 3*FRACUNIT, true); \
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP) \
|
||||
mo->flags2 |= MF2_OBJECTFLIP; \
|
||||
player->powers[power] = 0; \
|
||||
++i; \
|
||||
}
|
||||
if (!P_MobjWasRemoved(mo)) \
|
||||
{ \
|
||||
mo->health = player->powers[power]; \
|
||||
mo->flags2 |= MF2_DONTRESPAWN; \
|
||||
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \
|
||||
P_SetTarget(&mo->target, player->mo); \
|
||||
mo->fuse = 12*TICRATE; \
|
||||
mo->destscale = player->mo->scale; \
|
||||
P_SetScale(mo, player->mo->scale); \
|
||||
mo->momx = FixedMul(FINECOSINE(fa),ns); \
|
||||
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \
|
||||
mo->momy = FixedMul(FINESINE(fa),ns); \
|
||||
P_SetObjectMomZ(mo, 3*FRACUNIT, false); \
|
||||
if (i & 1) \
|
||||
P_SetObjectMomZ(mo, 3*FRACUNIT, true); \
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP) \
|
||||
mo->flags2 |= MF2_OBJECTFLIP; \
|
||||
player->powers[power] = 0; \
|
||||
} \
|
||||
} \
|
||||
++i
|
||||
|
||||
DROP_WEAPON(RW_BOUNCE, MT_BOUNCEPICKUP, MT_BOUNCERING, pw_bouncering);
|
||||
DROP_WEAPON(RW_RAIL, MT_RAILPICKUP, MT_RAILRING, pw_railring);
|
||||
|
@ -4351,23 +4391,26 @@ void P_PlayerEmeraldBurst(player_t *player, boolean toss)
|
|||
momy = 0;
|
||||
|
||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, z, MT_FLINGEMERALD);
|
||||
mo->health = 1;
|
||||
mo->threshold = stoneflag;
|
||||
mo->flags2 |= (MF2_DONTRESPAWN|MF2_SLIDEPUSH);
|
||||
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT);
|
||||
P_SetTarget(&mo->target, player->mo);
|
||||
mo->fuse = 12*TICRATE;
|
||||
P_SetMobjState(mo, statenum);
|
||||
|
||||
mo->momx = momx;
|
||||
mo->momy = momy;
|
||||
|
||||
P_SetObjectMomZ(mo, 3*FRACUNIT, false);
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
if (!P_MobjWasRemoved(mo))
|
||||
{
|
||||
mo->momz = -mo->momz;
|
||||
mo->flags2 |= MF2_OBJECTFLIP;
|
||||
mo->health = 1;
|
||||
mo->threshold = stoneflag;
|
||||
mo->flags2 |= (MF2_DONTRESPAWN|MF2_SLIDEPUSH);
|
||||
mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT);
|
||||
P_SetTarget(&mo->target, player->mo);
|
||||
mo->fuse = 12*TICRATE;
|
||||
P_SetMobjState(mo, statenum);
|
||||
|
||||
mo->momx = momx;
|
||||
mo->momy = momy;
|
||||
|
||||
P_SetObjectMomZ(mo, 3*FRACUNIT, false);
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
mo->momz = -mo->momz;
|
||||
mo->flags2 |= MF2_OBJECTFLIP;
|
||||
}
|
||||
}
|
||||
|
||||
if (toss)
|
||||
|
@ -4395,6 +4438,8 @@ void P_PlayerFlagBurst(player_t *player, boolean toss)
|
|||
type = MT_BLUEFLAG;
|
||||
|
||||
flag = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, type);
|
||||
if (P_MobjWasRemoved(flag))
|
||||
return;
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
|
|
|
@ -288,7 +288,7 @@ mobjtype_t P_GetMobjtype(UINT16 mthingtype);
|
|||
|
||||
void P_RespawnSpecials(void);
|
||||
|
||||
mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type);
|
||||
mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...);
|
||||
|
||||
void P_RecalcPrecipInSector(sector_t *sector);
|
||||
void P_PrecipitationEffects(void);
|
||||
|
|
|
@ -2865,6 +2865,8 @@ 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);
|
||||
if (P_MobjWasRemoved(hack))
|
||||
return false;
|
||||
|
||||
hack->radius = thing->radius;
|
||||
hack->height = thing->height;
|
||||
|
|
851
src/p_mobj.c
851
src/p_mobj.c
File diff suppressed because it is too large
Load diff
|
@ -1243,6 +1243,8 @@ boolean Polyobj_rotate(polyobj_t *po, angle_t delta, boolean turnplayers, boolea
|
|||
// Returns NULL if no such polyobject exists.
|
||||
polyobj_t *Polyobj_GetForNum(INT32 id)
|
||||
{
|
||||
if (numPolyObjects == 0)
|
||||
return NULL;
|
||||
INT32 curidx = PolyObjects[id % numPolyObjects].first;
|
||||
|
||||
while (curidx != numPolyObjects && PolyObjects[curidx].id != id)
|
||||
|
|
441
src/p_user.c
441
src/p_user.c
|
@ -393,6 +393,8 @@ void P_GiveFinishFlags(player_t *player)
|
|||
fixed_t xoffs = FINECOSINE(fa);
|
||||
fixed_t yoffs = FINESINE(fa);
|
||||
mobj_t* flag = P_SpawnMobjFromMobj(player->mo, xoffs, yoffs, 0, MT_FINISHFLAG);
|
||||
if (P_MobjWasRemoved(flag))
|
||||
continue;
|
||||
flag->angle = angle;
|
||||
angle += FixedAngle(120*FRACUNIT);
|
||||
|
||||
|
@ -1889,6 +1891,9 @@ void P_SpawnShieldOrb(player_t *player)
|
|||
}
|
||||
|
||||
shieldobj = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, orbtype);
|
||||
if (P_MobjWasRemoved(shieldobj))
|
||||
return;
|
||||
|
||||
shieldobj->flags2 |= MF2_SHIELD;
|
||||
P_SetTarget(&shieldobj->target, player->mo);
|
||||
P_SetTarget(&shieldobj->dontdrawforviewmobj, player->mo); // Hide the shield in first-person
|
||||
|
@ -1904,24 +1909,33 @@ void P_SpawnShieldOrb(player_t *player)
|
|||
if (shieldobj->info->seestate)
|
||||
{
|
||||
ov = P_SpawnMobj(shieldobj->x, shieldobj->y, shieldobj->z, MT_OVERLAY);
|
||||
P_SetTarget(&ov->target, shieldobj);
|
||||
if (!P_MobjWasRemoved(ov))
|
||||
{
|
||||
P_SetTarget(&ov->target, shieldobj);
|
||||
P_SetTarget(&ov->dontdrawforviewmobj, player->mo); // Hide the shield in first-person
|
||||
P_SetMobjState(ov, shieldobj->info->seestate);
|
||||
P_SetTarget(&shieldobj->tracer, ov);
|
||||
P_SetMobjState(ov, shieldobj->info->seestate);
|
||||
P_SetTarget(&shieldobj->tracer, ov);
|
||||
}
|
||||
}
|
||||
if (shieldobj->info->meleestate)
|
||||
{
|
||||
ov = P_SpawnMobj(shieldobj->x, shieldobj->y, shieldobj->z, MT_OVERLAY);
|
||||
P_SetTarget(&ov->target, shieldobj);
|
||||
if (!P_MobjWasRemoved(ov))
|
||||
{
|
||||
P_SetTarget(&ov->target, shieldobj);
|
||||
P_SetTarget(&ov->dontdrawforviewmobj, player->mo); // Hide the shield in first-person
|
||||
P_SetMobjState(ov, shieldobj->info->meleestate);
|
||||
P_SetMobjState(ov, shieldobj->info->meleestate);
|
||||
}
|
||||
}
|
||||
if (shieldobj->info->missilestate)
|
||||
{
|
||||
ov = P_SpawnMobj(shieldobj->x, shieldobj->y, shieldobj->z, MT_OVERLAY);
|
||||
P_SetTarget(&ov->target, shieldobj);
|
||||
if (!P_MobjWasRemoved(ov))
|
||||
{
|
||||
P_SetTarget(&ov->target, shieldobj);
|
||||
P_SetTarget(&ov->dontdrawforviewmobj, player->mo); // Hide the shield in first-person
|
||||
P_SetMobjState(ov, shieldobj->info->missilestate);
|
||||
P_SetMobjState(ov, shieldobj->info->missilestate);
|
||||
}
|
||||
}
|
||||
if (player->powers[pw_shield] & SH_FORCE)
|
||||
{
|
||||
|
@ -2017,6 +2031,8 @@ void P_SetPower(player_t *player, powertype_t power, UINT16 value)
|
|||
mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
|
||||
{
|
||||
mobj_t *ghost = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_GHOST);
|
||||
if (P_MobjWasRemoved(ghost))
|
||||
return NULL;
|
||||
|
||||
P_SetTarget(&ghost->target, mobj);
|
||||
P_SetTarget(&ghost->dontdrawforviewmobj, mobj); // Hide the ghost in first-person
|
||||
|
@ -2063,10 +2079,13 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
|
|||
if (mobj->player && mobj->player->followmobj)
|
||||
{
|
||||
mobj_t *ghost2 = P_SpawnGhostMobj(mobj->player->followmobj);
|
||||
P_SetTarget(&ghost2->tracer, ghost);
|
||||
P_SetTarget(&ghost->tracer, ghost2);
|
||||
if (!P_MobjWasRemoved(ghost2))
|
||||
{
|
||||
P_SetTarget(&ghost2->tracer, ghost);
|
||||
P_SetTarget(&ghost->tracer, ghost2);
|
||||
P_SetTarget(&ghost2->dontdrawforviewmobj, mobj); // Hide the follow-ghost for the non-follow target
|
||||
ghost2->flags2 |= (mobj->player->followmobj->flags2 & MF2_LINKDRAW);
|
||||
ghost2->flags2 |= (mobj->player->followmobj->flags2 & MF2_LINKDRAW);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy interpolation data :)
|
||||
|
@ -2116,6 +2135,8 @@ void P_SpawnThokMobj(player_t *player)
|
|||
zheight = player->mo->ceilingz - FixedMul(mobjinfo[type].height, player->mo->scale);
|
||||
|
||||
mobj = P_SpawnMobj(player->mo->x, player->mo->y, zheight, type);
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
|
||||
// set to player's angle, just in case
|
||||
mobj->angle = player->drawangle;
|
||||
|
@ -2139,7 +2160,8 @@ void P_SpawnThokMobj(player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
P_SetTarget(&mobj->target, player->mo); // the one thing P_SpawnGhostMobj doesn't do
|
||||
if (!P_MobjWasRemoved(mobj))
|
||||
P_SetTarget(&mobj->target, player->mo); // the one thing P_SpawnGhostMobj doesn't do
|
||||
G_GhostAddThok();
|
||||
}
|
||||
|
||||
|
@ -2177,6 +2199,8 @@ void P_SpawnSpinMobj(player_t *player, mobjtype_t type)
|
|||
zheight = player->mo->ceilingz - FixedMul(mobjinfo[type].height, player->mo->scale);
|
||||
|
||||
mobj = P_SpawnMobj(player->mo->x, player->mo->y, zheight, type);
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
|
||||
// set to player's angle, just in case
|
||||
mobj->angle = player->drawangle;
|
||||
|
@ -2201,7 +2225,8 @@ void P_SpawnSpinMobj(player_t *player, mobjtype_t type)
|
|||
}
|
||||
}
|
||||
|
||||
P_SetTarget(&mobj->target, player->mo); // the one thing P_SpawnGhostMobj doesn't do
|
||||
if (!P_MobjWasRemoved(mobj))
|
||||
P_SetTarget(&mobj->target, player->mo); // the one thing P_SpawnGhostMobj doesn't do
|
||||
}
|
||||
|
||||
/** Called when \p player finishes the level.
|
||||
|
@ -2426,15 +2451,18 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
|
|||
while (i < 5)
|
||||
{
|
||||
missile = P_SpawnMobjFromMobj(player->mo, xo, yo, zo, type);
|
||||
P_SetTarget(&missile->target, player->mo);
|
||||
missile->angle = throwang + player->drawangle;
|
||||
P_Thrust(missile, player->drawangle + ANGLE_90,
|
||||
P_ReturnThrustY(missile, throwang, mu)); // side to side component
|
||||
P_Thrust(missile, player->drawangle, mu2); // forward component
|
||||
P_SetObjectMomZ(missile, (4 + ((i&1)<<1))*FRACUNIT, true);
|
||||
missile->momz += player->mo->pmomz;
|
||||
missile->fuse = TICRATE/2;
|
||||
missile->extravalue2 = ev;
|
||||
if (!P_MobjWasRemoved(missile))
|
||||
{
|
||||
P_SetTarget(&missile->target, player->mo);
|
||||
missile->angle = throwang + player->drawangle;
|
||||
P_Thrust(missile, player->drawangle + ANGLE_90,
|
||||
P_ReturnThrustY(missile, throwang, mu)); // side to side component
|
||||
P_Thrust(missile, player->drawangle, mu2); // forward component
|
||||
P_SetObjectMomZ(missile, (4 + ((i&1)<<1))*FRACUNIT, true);
|
||||
missile->momz += player->mo->pmomz;
|
||||
missile->fuse = TICRATE/2;
|
||||
missile->extravalue2 = ev;
|
||||
}
|
||||
|
||||
i++;
|
||||
throwang += ANG30;
|
||||
|
@ -2989,24 +3017,29 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player)
|
|||
: player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, FixedMul(player->mo->scale, player->shieldscale));
|
||||
|
||||
mobj_t *numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS);
|
||||
|
||||
timeleft /= (2*TICRATE); // To be strictly accurate it'd need to be ((timeleft/TICRATE) - 1)/2, but integer division rounds down for us
|
||||
|
||||
if (player->charflags & SF_MACHINE)
|
||||
if (!P_MobjWasRemoved(numbermobj))
|
||||
{
|
||||
S_StartSound(player->mo, sfx_buzz1);
|
||||
timeleft += 6;
|
||||
timeleft /= (2*TICRATE); // To be strictly accurate it'd need to be ((timeleft/TICRATE) - 1)/2, but integer division rounds down for us
|
||||
|
||||
if (player->charflags & SF_MACHINE)
|
||||
{
|
||||
S_StartSound(player->mo, sfx_buzz1);
|
||||
timeleft += 6;
|
||||
}
|
||||
else
|
||||
S_StartSound(player->mo, sfx_dwnind);
|
||||
|
||||
if (!P_MobjWasRemoved(numbermobj))
|
||||
{
|
||||
if (timeleft) // Don't waste time setting the state if the time is 0.
|
||||
P_SetMobjState(numbermobj, numbermobj->info->spawnstate+timeleft);
|
||||
|
||||
P_SetTarget(&numbermobj->target, player->mo);
|
||||
numbermobj->threshold = 40;
|
||||
numbermobj->destscale = player->mo->scale;
|
||||
P_SetScale(numbermobj, player->mo->scale);
|
||||
}
|
||||
}
|
||||
else
|
||||
S_StartSound(player->mo, sfx_dwnind);
|
||||
|
||||
if (timeleft) // Don't waste time setting the state if the time is 0.
|
||||
P_SetMobjState(numbermobj, numbermobj->info->spawnstate+timeleft);
|
||||
|
||||
P_SetTarget(&numbermobj->target, player->mo);
|
||||
numbermobj->threshold = 40;
|
||||
numbermobj->destscale = player->mo->scale;
|
||||
P_SetScale(numbermobj, player->mo->scale);
|
||||
}
|
||||
// Underwater timer runs out
|
||||
else if (timeleft == 1)
|
||||
|
@ -3065,8 +3098,11 @@ static void P_CheckInvincibilityTimer(player_t *player)
|
|||
else if (leveltime % (TICRATE/7) == 0)
|
||||
{
|
||||
mobj_t *sparkle = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_IVSP);
|
||||
sparkle->destscale = player->mo->scale;
|
||||
P_SetScale(sparkle, player->mo->scale);
|
||||
if (!P_MobjWasRemoved(sparkle))
|
||||
{
|
||||
sparkle->destscale = player->mo->scale;
|
||||
P_SetScale(sparkle, player->mo->scale);
|
||||
}
|
||||
}
|
||||
|
||||
// Resume normal music stuff.
|
||||
|
@ -3121,7 +3157,8 @@ static void P_DoBubbleBreath(player_t *player)
|
|||
y += (P_RandomRange(r, -r)<<FRACBITS);
|
||||
z += (P_RandomKey(player->mo->height>>FRACBITS)<<FRACBITS);
|
||||
bubble = P_SpawnMobj(x, y, z, MT_WATERZAP);
|
||||
S_StartSound(bubble, sfx_beelec);
|
||||
if (!P_MobjWasRemoved(bubble))
|
||||
S_StartSound(bubble, sfx_beelec);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -3162,15 +3199,21 @@ static void P_DoBubbleBreath(player_t *player)
|
|||
player->mo->x + stirwaterx,
|
||||
player->mo->y + stirwatery,
|
||||
stirwaterz, MT_SMALLBUBBLE);
|
||||
bubble->destscale = player->mo->scale;
|
||||
P_SetScale(bubble,bubble->destscale);
|
||||
if (!P_MobjWasRemoved(bubble))
|
||||
{
|
||||
bubble->destscale = player->mo->scale;
|
||||
P_SetScale(bubble,bubble->destscale);
|
||||
}
|
||||
|
||||
bubble = P_SpawnMobj(
|
||||
player->mo->x - stirwaterx,
|
||||
player->mo->y - stirwatery,
|
||||
stirwaterz, MT_SMALLBUBBLE);
|
||||
bubble->destscale = player->mo->scale;
|
||||
P_SetScale(bubble,bubble->destscale);
|
||||
if (!P_MobjWasRemoved(bubble))
|
||||
{
|
||||
bubble->destscale = player->mo->scale;
|
||||
P_SetScale(bubble,bubble->destscale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3190,22 +3233,25 @@ static void P_DoPlayerHeadSigns(player_t *player)
|
|||
if (player->pflags & PF_TAGIT && (!P_IsLocalPlayer(player) || consoleplayer != displayplayer || splitscreen))
|
||||
{
|
||||
sign = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_TAG);
|
||||
sign->x = player->mo->x;
|
||||
sign->y = player->mo->y;
|
||||
sign->z = player->mo->z;
|
||||
sign->old_x = player->mo->old_x;
|
||||
sign->old_y = player->mo->old_y;
|
||||
sign->old_z = player->mo->old_z;
|
||||
if (!P_MobjWasRemoved(sign))
|
||||
{
|
||||
sign->x = player->mo->x;
|
||||
sign->y = player->mo->y;
|
||||
sign->z = player->mo->z;
|
||||
sign->old_x = player->mo->old_x;
|
||||
sign->old_y = player->mo->old_y;
|
||||
sign->old_z = player->mo->old_z;
|
||||
|
||||
if (!(player->mo->eflags & MFE_VERTICALFLIP))
|
||||
{
|
||||
sign->z += player->mo->height;
|
||||
sign->old_z += player->mo->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
sign->z -= mobjinfo[MT_TAG].height;
|
||||
sign->old_z -= mobjinfo[MT_TAG].height;
|
||||
if (!(player->mo->eflags & MFE_VERTICALFLIP))
|
||||
{
|
||||
sign->z += player->mo->height;
|
||||
sign->old_z += player->mo->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
sign->z -= mobjinfo[MT_TAG].height;
|
||||
sign->old_z -= mobjinfo[MT_TAG].height;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3229,24 +3275,26 @@ static void P_DoPlayerHeadSigns(player_t *player)
|
|||
}
|
||||
|
||||
sign = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_GOTFLAG);
|
||||
sign->x = player->mo->x;
|
||||
sign->y = player->mo->y;
|
||||
sign->z = player->mo->z + zofs;
|
||||
sign->old_x = player->mo->old_x;
|
||||
sign->old_y = player->mo->old_y;
|
||||
sign->old_z = player->mo->old_z + zofs;
|
||||
|
||||
if (player_is_flipped)
|
||||
if (!P_MobjWasRemoved(sign))
|
||||
{
|
||||
sign->eflags |= MFE_VERTICALFLIP;
|
||||
}
|
||||
sign->x = player->mo->x;
|
||||
sign->y = player->mo->y;
|
||||
sign->z = player->mo->z + zofs;
|
||||
sign->old_x = player->mo->old_x;
|
||||
sign->old_y = player->mo->old_y;
|
||||
sign->old_z = player->mo->old_z + zofs;
|
||||
|
||||
if (player->gotflag & GF_REDFLAG)
|
||||
sign->frame = 1|FF_FULLBRIGHT;
|
||||
else //if (player->gotflag & GF_BLUEFLAG)
|
||||
sign->frame = 2|FF_FULLBRIGHT;
|
||||
if (player_is_flipped)
|
||||
{
|
||||
sign->eflags |= MFE_VERTICALFLIP;
|
||||
}
|
||||
|
||||
if (player->gotflag & GF_REDFLAG)
|
||||
sign->frame = 1|FF_FULLBRIGHT;
|
||||
else //if (player->gotflag & GF_BLUEFLAG)
|
||||
sign->frame = 2|FF_FULLBRIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!P_MobjWasRemoved(sign) && splitscreen) // Hide the sign from yourself in splitscreen - In single-screen, it wouldn't get spawned if it shouldn't be visible
|
||||
{
|
||||
|
@ -3284,6 +3332,7 @@ static void P_DoPlayerHeadSigns(player_t *player)
|
|||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -4371,8 +4420,11 @@ static void P_DoSuperStuff(player_t *player)
|
|||
&& !(leveltime % TICRATE) && (player->mo->momx || player->mo->momy))
|
||||
{
|
||||
spark = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SUPERSPARK);
|
||||
spark->destscale = player->mo->scale;
|
||||
P_SetScale(spark, player->mo->scale);
|
||||
if (!P_MobjWasRemoved(spark))
|
||||
{
|
||||
spark->destscale = player->mo->scale;
|
||||
P_SetScale(spark, player->mo->scale);
|
||||
}
|
||||
}
|
||||
|
||||
// Ran out of rings while super!
|
||||
|
@ -4613,6 +4665,8 @@ void P_DoSpinDashDust(player_t *player)
|
|||
INT32 prandom[3];
|
||||
for (i = 0; i <= (leveltime%7)/2; i++) { // 1, 2, 3 or 4 particles
|
||||
particle = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_SPINDUST);
|
||||
if (P_MobjWasRemoved(particle))
|
||||
return;
|
||||
|
||||
if (player->mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)) // overrides fire version
|
||||
P_SetMobjState(particle, S_SPINDUST_BUBBLE1);
|
||||
|
@ -4760,7 +4814,8 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
|
|||
if (P_IsLocalPlayer(player)) // Only display it on your own view. Don't display it for spectators
|
||||
{
|
||||
mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker
|
||||
P_SetTarget(&visual->target, lockon);
|
||||
if (!P_MobjWasRemoved(visual))
|
||||
P_SetTarget(&visual->target, lockon);
|
||||
visual->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating
|
||||
}
|
||||
}
|
||||
|
@ -4903,10 +4958,13 @@ void P_DoJumpShield(player_t *player)
|
|||
for (i = 0; i < numangles; i++)
|
||||
{
|
||||
spark = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_THUNDERCOIN_SPARK);
|
||||
P_InstaThrust(spark, travelangle + i*(ANGLE_MAX/numangles), FixedMul(4*FRACUNIT, spark->scale));
|
||||
if (i % 2)
|
||||
P_SetObjectMomZ(spark, -4*FRACUNIT, false);
|
||||
spark->fuse = 18;
|
||||
if (!P_MobjWasRemoved(spark))
|
||||
{
|
||||
P_InstaThrust(spark, travelangle + i*(ANGLE_MAX/numangles), FixedMul(4*FRACUNIT, spark->scale));
|
||||
if (i % 2)
|
||||
P_SetObjectMomZ(spark, -4*FRACUNIT, false);
|
||||
spark->fuse = 18;
|
||||
}
|
||||
}
|
||||
#undef limitangle
|
||||
#undef numangles
|
||||
|
@ -5013,14 +5071,17 @@ void P_TwinSpinRejuvenate(player_t *player, mobjtype_t type)
|
|||
yo,
|
||||
player->mo->height/2 + zo,
|
||||
type);
|
||||
P_SetTarget(&missile->target, player->mo);
|
||||
P_SetScale(missile, (missile->destscale >>= 1));
|
||||
missile->angle = ang + movang;
|
||||
missile->fuse = TICRATE/2;
|
||||
missile->extravalue2 = (99*FRACUNIT)/100;
|
||||
missile->momx = xo;
|
||||
missile->momy = yo;
|
||||
missile->momz = zo;
|
||||
if (!P_MobjWasRemoved(missile))
|
||||
{
|
||||
P_SetTarget(&missile->target, player->mo);
|
||||
P_SetScale(missile, (missile->destscale >>= 1));
|
||||
missile->angle = ang + movang;
|
||||
missile->fuse = TICRATE/2;
|
||||
missile->extravalue2 = (99*FRACUNIT)/100;
|
||||
missile->momx = xo;
|
||||
missile->momy = yo;
|
||||
missile->momz = zo;
|
||||
}
|
||||
|
||||
ang += ANGLE_45;
|
||||
}
|
||||
|
@ -5118,9 +5179,12 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock
|
|||
if (dovis)
|
||||
{
|
||||
visual = P_SpawnMobj(lockonshield->x, lockonshield->y, lockonshield->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker
|
||||
P_SetTarget(&visual->target, lockonshield);
|
||||
if (!P_MobjWasRemoved(visual))
|
||||
{
|
||||
P_SetTarget(&visual->target, lockonshield);
|
||||
visual->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating
|
||||
P_SetMobjStateNF(visual, visual->info->spawnstate+1);
|
||||
P_SetMobjStateNF(visual, visual->info->spawnstate+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5226,7 +5290,8 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
|
|||
if (P_IsLocalPlayer(player)) // Only display it on your own view. Don't display it for spectators
|
||||
{
|
||||
visual = P_SpawnMobj(lockonthok->x, lockonthok->y, lockonthok->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker
|
||||
P_SetTarget(&visual->target, lockonthok);
|
||||
if (!P_MobjWasRemoved(visual))
|
||||
P_SetTarget(&visual->target, lockonthok);
|
||||
visual->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating
|
||||
}
|
||||
}
|
||||
|
@ -6912,10 +6977,14 @@ static void P_DoNiGHTSCapsule(player_t *player)
|
|||
|
||||
// Spawn a 'pop' for every 2 tics
|
||||
if (!((tictimer - firstpoptic) % 2))
|
||||
S_StartSound(P_SpawnMobj(player->capsule->x + ((P_SignedRandom()/2)<<FRACBITS),
|
||||
player->capsule->y + ((P_SignedRandom()/2)<<FRACBITS),
|
||||
player->capsule->z + (player->capsule->height/2) + ((P_SignedRandom()/2)<<FRACBITS),
|
||||
MT_SONIC3KBOSSEXPLODE),sfx_s3kb4);
|
||||
{
|
||||
mobj_t *explodemo = P_SpawnMobj(player->capsule->x + ((P_SignedRandom()/2)<<FRACBITS),
|
||||
player->capsule->y + ((P_SignedRandom()/2)<<FRACBITS),
|
||||
player->capsule->z + (player->capsule->height/2) + ((P_SignedRandom()/2)<<FRACBITS),
|
||||
MT_SONIC3KBOSSEXPLODE);
|
||||
if (!P_MobjWasRemoved(explodemo))
|
||||
S_StartSound(explodemo,sfx_s3kb4);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -6972,10 +7041,13 @@ static void P_DoNiGHTSCapsule(player_t *player)
|
|||
UINT8 em = P_GetNextEmerald();
|
||||
// Only give it to ONE person, and THAT player has to get to the goal!
|
||||
mobj_t *emmo = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height, MT_GOTEMERALD);
|
||||
emmo->health = em; // for identification
|
||||
P_SetTarget(&emmo->target, player->mo);
|
||||
P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em);
|
||||
P_SetTarget(&player->mo->tracer, emmo);
|
||||
if (!P_MobjWasRemoved(emmo))
|
||||
{
|
||||
emmo->health = em; // for identification
|
||||
P_SetTarget(&emmo->target, player->mo);
|
||||
P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em);
|
||||
P_SetTarget(&player->mo->tracer, emmo);
|
||||
}
|
||||
}
|
||||
|
||||
// Okay, we're doing this down here because we're handling time weirdly for co-op special stages
|
||||
|
@ -6998,19 +7070,22 @@ static void P_DoNiGHTSCapsule(player_t *player)
|
|||
P_InstaThrust(flicky, flicky->angle, 8*FRACUNIT);
|
||||
}*/
|
||||
mobj_t *idya = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height, MT_GOTEMERALD);
|
||||
idya->extravalue2 = player->mare/5;
|
||||
idya->health = player->mare + 1; // for identification
|
||||
P_SetTarget(&idya->target, player->mo);
|
||||
P_SetMobjState(idya, mobjinfo[MT_GOTEMERALD].missilestate + ((player->mare + 1) % 5));
|
||||
|
||||
if (player->mo->tracer)
|
||||
if (!P_MobjWasRemoved(idya))
|
||||
{
|
||||
P_SetTarget(&idya->hnext, player->mo->tracer);
|
||||
idya->extravalue1 = (angle_t)(player->mo->tracer->extravalue1 - 72*ANG1);
|
||||
if (idya->extravalue1 > player->mo->tracer->extravalue1)
|
||||
idya->extravalue1 -= (72*ANG1)/idya->extravalue1;
|
||||
idya->extravalue2 = player->mare/5;
|
||||
idya->health = player->mare + 1; // for identification
|
||||
P_SetTarget(&idya->target, player->mo);
|
||||
P_SetMobjState(idya, mobjinfo[MT_GOTEMERALD].missilestate + ((player->mare + 1) % 5));
|
||||
|
||||
if (player->mo->tracer)
|
||||
{
|
||||
P_SetTarget(&idya->hnext, player->mo->tracer);
|
||||
idya->extravalue1 = (angle_t)(player->mo->tracer->extravalue1 - 72*ANG1);
|
||||
if (idya->extravalue1 > player->mo->tracer->extravalue1)
|
||||
idya->extravalue1 -= (72*ANG1)/idya->extravalue1;
|
||||
}
|
||||
P_SetTarget(&player->mo->tracer, idya);
|
||||
}
|
||||
P_SetTarget(&player->mo->tracer, idya);
|
||||
}
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].mare == player->mare)
|
||||
|
@ -7335,19 +7410,25 @@ static void P_NiGHTSMovement(player_t *player)
|
|||
z -= FixedMul(mobjinfo[MT_NIGHTSPARKLE].height, player->mo->scale);
|
||||
|
||||
firstmobj = P_SpawnMobj(player->mo->x + P_ReturnThrustX(player->mo, player->mo->angle+ANGLE_90, spawndist), player->mo->y + P_ReturnThrustY(player->mo, player->mo->angle+ANGLE_90, spawndist), z, MT_NIGHTSPARKLE);
|
||||
secondmobj = P_SpawnMobj(player->mo->x + P_ReturnThrustX(player->mo, player->mo->angle-ANGLE_90, spawndist), player->mo->y + P_ReturnThrustY(player->mo, player->mo->angle-ANGLE_90, spawndist), z, MT_NIGHTSPARKLE);
|
||||
|
||||
firstmobj->destscale = secondmobj->destscale = player->mo->scale;
|
||||
P_SetTarget(&firstmobj->target, player->mo);
|
||||
P_SetScale(firstmobj, player->mo->scale);
|
||||
P_SetTarget(&secondmobj->target, player->mo);
|
||||
P_SetScale(secondmobj, player->mo->scale);
|
||||
|
||||
// Superloop turns sparkles red
|
||||
if (player->powers[pw_nights_superloop])
|
||||
if (!P_MobjWasRemoved(firstmobj))
|
||||
{
|
||||
P_SetMobjState(firstmobj, mobjinfo[MT_NIGHTSPARKLE].seestate);
|
||||
P_SetMobjState(secondmobj, mobjinfo[MT_NIGHTSPARKLE].seestate);
|
||||
firstmobj->destscale = player->mo->scale;
|
||||
P_SetTarget(&firstmobj->target, player->mo);
|
||||
P_SetScale(firstmobj, player->mo->scale);
|
||||
// Superloop turns sparkles red
|
||||
if (player->powers[pw_nights_superloop])
|
||||
P_SetMobjState(firstmobj, mobjinfo[MT_NIGHTSPARKLE].seestate);
|
||||
}
|
||||
secondmobj = P_SpawnMobj(player->mo->x + P_ReturnThrustX(player->mo, player->mo->angle-ANGLE_90, spawndist), player->mo->y + P_ReturnThrustY(player->mo, player->mo->angle-ANGLE_90, spawndist), z, MT_NIGHTSPARKLE);
|
||||
if (!P_MobjWasRemoved(secondmobj))
|
||||
{
|
||||
secondmobj->destscale = player->mo->scale;
|
||||
P_SetTarget(&secondmobj->target, player->mo);
|
||||
P_SetScale(secondmobj, player->mo->scale);
|
||||
|
||||
// Superloop turns sparkles red
|
||||
if (player->powers[pw_nights_superloop])
|
||||
P_SetMobjState(secondmobj, mobjinfo[MT_NIGHTSPARKLE].seestate);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7355,9 +7436,12 @@ static void P_NiGHTSMovement(player_t *player)
|
|||
// It also spawns every tic to avoid failed paraloops
|
||||
{
|
||||
mobj_t *helpermobj = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, MT_NIGHTSLOOPHELPER);
|
||||
helpermobj->fuse = player->mo->fuse = leveltime;
|
||||
P_SetTarget(&helpermobj->target, player->mo);
|
||||
P_SetScale(helpermobj, player->mo->scale);
|
||||
if (!P_MobjWasRemoved(helpermobj))
|
||||
{
|
||||
helpermobj->fuse = player->mo->fuse = leveltime;
|
||||
P_SetTarget(&helpermobj->target, player->mo);
|
||||
P_SetScale(helpermobj, player->mo->scale);
|
||||
}
|
||||
}
|
||||
|
||||
if (player->bumpertime)
|
||||
|
@ -7546,19 +7630,22 @@ static void P_NiGHTSMovement(player_t *player)
|
|||
mobjtype_t splishtype = (player->mo->eflags & MFE_TOUCHLAVA) ? MT_LAVASPLISH : MT_SPLISH;
|
||||
mobj_t *water = P_SpawnMobj(player->mo->x, player->mo->y,
|
||||
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[splishtype].height, player->mo->scale) : player->mo->watertop), splishtype);
|
||||
if (player->mo->eflags & MFE_GOOWATER)
|
||||
S_StartSound(water, sfx_ghit);
|
||||
else if (player->mo->eflags & MFE_TOUCHLAVA)
|
||||
S_StartSound(water, sfx_splash);
|
||||
else
|
||||
S_StartSound(water, sfx_wslap);
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
if (!P_MobjWasRemoved(water))
|
||||
{
|
||||
water->flags2 |= MF2_OBJECTFLIP;
|
||||
water->eflags |= MFE_VERTICALFLIP;
|
||||
if (player->mo->eflags & MFE_GOOWATER)
|
||||
S_StartSound(water, sfx_ghit);
|
||||
else if (player->mo->eflags & MFE_TOUCHLAVA)
|
||||
S_StartSound(water, sfx_splash);
|
||||
else
|
||||
S_StartSound(water, sfx_wslap);
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
water->flags2 |= MF2_OBJECTFLIP;
|
||||
water->eflags |= MFE_VERTICALFLIP;
|
||||
}
|
||||
water->destscale = player->mo->scale;
|
||||
P_SetScale(water, player->mo->scale);
|
||||
}
|
||||
water->destscale = player->mo->scale;
|
||||
P_SetScale(water, player->mo->scale);
|
||||
}
|
||||
|
||||
if (player->mo->momx || player->mo->momy)
|
||||
|
@ -7791,6 +7878,8 @@ void P_ElementalFire(player_t *player, boolean cropcircle)
|
|||
for (i = 0; i < numangles; i++)
|
||||
{
|
||||
flame = P_SpawnMobj(player->mo->x, player->mo->y, ground, MT_SPINFIRE);
|
||||
if (P_MobjWasRemoved(flame))
|
||||
continue;
|
||||
flame->flags &= ~MF_NOGRAVITY;
|
||||
P_SetTarget(&flame->target, player->mo);
|
||||
flame->angle = travelangle + i*(ANGLE_MAX/numangles);
|
||||
|
@ -7828,6 +7917,8 @@ void P_ElementalFire(player_t *player, boolean cropcircle)
|
|||
}
|
||||
|
||||
flame = P_SpawnMobj(newx, newy, ground, MT_SPINFIRE);
|
||||
if (P_MobjWasRemoved(flame))
|
||||
continue;
|
||||
P_SetTarget(&flame->target, player->mo);
|
||||
flame->angle = travelangle;
|
||||
flame->fuse = TICRATE*6;
|
||||
|
@ -7869,6 +7960,8 @@ void P_SpawnSkidDust(player_t *player, fixed_t radius, boolean sound)
|
|||
mobj_t *particle;
|
||||
|
||||
particle = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_SPINDUST);
|
||||
if (P_MobjWasRemoved(particle))
|
||||
return;
|
||||
if (radius >>= FRACBITS)
|
||||
{
|
||||
P_UnsetThingPosition(particle);
|
||||
|
@ -8455,19 +8548,22 @@ void P_MovePlayer(player_t *player)
|
|||
mobjtype_t splishtype = (player->mo->eflags & MFE_TOUCHLAVA) ? MT_LAVASPLISH : MT_SPLISH;
|
||||
mobj_t *water = P_SpawnMobj(player->mo->x - P_ReturnThrustX(NULL, player->mo->angle, player->mo->radius), player->mo->y - P_ReturnThrustY(NULL, player->mo->angle, player->mo->radius),
|
||||
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[splishtype].height, player->mo->scale) : player->mo->watertop), splishtype);
|
||||
if (player->mo->eflags & MFE_GOOWATER)
|
||||
S_StartSound(water, sfx_ghit);
|
||||
else if (player->mo->eflags & MFE_TOUCHLAVA)
|
||||
S_StartSound(water, sfx_splash);
|
||||
else
|
||||
S_StartSound(water, sfx_wslap);
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
if (!P_MobjWasRemoved(water))
|
||||
{
|
||||
water->flags2 |= MF2_OBJECTFLIP;
|
||||
water->eflags |= MFE_VERTICALFLIP;
|
||||
if (player->mo->eflags & MFE_GOOWATER)
|
||||
S_StartSound(water, sfx_ghit);
|
||||
else if (player->mo->eflags & MFE_TOUCHLAVA)
|
||||
S_StartSound(water, sfx_splash);
|
||||
else
|
||||
S_StartSound(water, sfx_wslap);
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
water->flags2 |= MF2_OBJECTFLIP;
|
||||
water->eflags |= MFE_VERTICALFLIP;
|
||||
}
|
||||
water->destscale = player->mo->scale;
|
||||
P_SetScale(water, player->mo->scale);
|
||||
}
|
||||
water->destscale = player->mo->scale;
|
||||
P_SetScale(water, player->mo->scale);
|
||||
}
|
||||
|
||||
// Little water sound while touching water - just a nicety.
|
||||
|
@ -10893,6 +10989,8 @@ static void P_SpawnSparks(mobj_t *mo, angle_t maindir)
|
|||
fixed_t fm = (maindir >> ANGLETOFINESHIFT) & FINEMASK;
|
||||
|
||||
spark = P_SpawnMobj(mo->x - b2*s + b1*c, mo->y + b2*c + b1*s, mo->z, MT_MINECARTSPARK);
|
||||
if (P_MobjWasRemoved(spark))
|
||||
return;
|
||||
spark->momx = mo->momx + r1 + 8*FINECOSINE(fm);
|
||||
spark->momy = mo->momy + r2 + 8*FINESINE(fm);
|
||||
spark->momz = mo->momz + r3;
|
||||
|
@ -12194,17 +12292,20 @@ void P_PlayerThink(player_t *player)
|
|||
if ((player->powers[pw_super] || player->powers[pw_sneakers]) && (player->speed + abs(player->mo->momz)) > FixedMul(20*FRACUNIT,player->mo->scale))
|
||||
{
|
||||
mobj_t *gmobj = P_SpawnGhostMobj(player->mo);
|
||||
gmobj->fuse = 2;
|
||||
if (gmobj->tracer)
|
||||
gmobj->tracer->fuse = 2;
|
||||
if (leveltime & 1)
|
||||
if (!P_MobjWasRemoved(gmobj))
|
||||
{
|
||||
gmobj->frame &= ~FF_TRANSMASK;
|
||||
gmobj->frame |= tr_trans70<<FF_TRANSSHIFT;
|
||||
gmobj->fuse = 2;
|
||||
if (gmobj->tracer)
|
||||
gmobj->tracer->fuse = 2;
|
||||
if (leveltime & 1)
|
||||
{
|
||||
gmobj->tracer->frame &= ~FF_TRANSMASK;
|
||||
gmobj->tracer->frame |= tr_trans70<<FF_TRANSSHIFT;
|
||||
gmobj->frame &= ~FF_TRANSMASK;
|
||||
gmobj->frame |= tr_trans70<<FF_TRANSSHIFT;
|
||||
if (gmobj->tracer)
|
||||
{
|
||||
gmobj->tracer->frame &= ~FF_TRANSMASK;
|
||||
gmobj->tracer->frame |= tr_trans70<<FF_TRANSSHIFT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12423,9 +12524,12 @@ void P_PlayerThink(player_t *player)
|
|||
if (player->normalspeed >= skins[player->skin].normalspeed*2)
|
||||
{
|
||||
mobj_t *ghost = P_SpawnGhostMobj(player->mo); // Spawns afterimages
|
||||
ghost->fuse = 2; // Makes the images fade quickly
|
||||
if (ghost->tracer && !P_MobjWasRemoved(ghost->tracer))
|
||||
ghost->tracer->fuse = ghost->fuse;
|
||||
if (!P_MobjWasRemoved(ghost))
|
||||
{
|
||||
ghost->fuse = 2; // Makes the images fade quickly
|
||||
if (ghost->tracer && !P_MobjWasRemoved(ghost->tracer))
|
||||
ghost->tracer->fuse = ghost->fuse;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (dashmode)
|
||||
|
@ -13026,15 +13130,18 @@ void P_PlayerAfterThink(player_t *player)
|
|||
if (!player->followmobj || P_MobjWasRemoved(player->followmobj))
|
||||
{
|
||||
P_SetTarget(&player->followmobj, P_SpawnMobjFromMobj(player->mo, 0, 0, 0, player->followitem));
|
||||
P_SetTarget(&player->followmobj->tracer, player->mo);
|
||||
switch (player->followmobj->type)
|
||||
if (!P_MobjWasRemoved(player->followmobj))
|
||||
{
|
||||
case MT_METALJETFUME:
|
||||
player->followmobj->colorized = true;
|
||||
break;
|
||||
default:
|
||||
player->followmobj->flags2 |= MF2_LINKDRAW;
|
||||
break;
|
||||
P_SetTarget(&player->followmobj->tracer, player->mo);
|
||||
switch (player->followmobj->type)
|
||||
{
|
||||
case MT_METALJETFUME:
|
||||
player->followmobj->colorized = true;
|
||||
break;
|
||||
default:
|
||||
player->followmobj->flags2 |= MF2_LINKDRAW;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue