P_MobjThinker(): Separate scale thinking and scenery thinking into their own functions
This commit is contained in:
parent
13eb71e1ee
commit
ddccfbd73d
926
src/p_mobj.c
926
src/p_mobj.c
|
@ -7143,46 +7143,7 @@ static void P_PyreFlyBurn(mobj_t *mobj, fixed_t hoffs, INT16 vrange, mobjtype_t
|
|||
particle->momz = momz;
|
||||
}
|
||||
|
||||
//
|
||||
// P_MobjThinker
|
||||
//
|
||||
void P_MobjThinker(mobj_t *mobj)
|
||||
{
|
||||
I_Assert(mobj != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(mobj));
|
||||
|
||||
if (mobj->flags & MF_NOTHINK)
|
||||
return;
|
||||
|
||||
if ((mobj->flags & MF_BOSS) && mobj->spawnpoint && (bossdisabled & (1<<mobj->spawnpoint->extrainfo)))
|
||||
return;
|
||||
|
||||
// Remove dead target/tracer.
|
||||
if (mobj->target && P_MobjWasRemoved(mobj->target))
|
||||
P_SetTarget(&mobj->target, NULL);
|
||||
if (mobj->tracer && P_MobjWasRemoved(mobj->tracer))
|
||||
P_SetTarget(&mobj->tracer, NULL);
|
||||
if (mobj->hnext && P_MobjWasRemoved(mobj->hnext))
|
||||
P_SetTarget(&mobj->hnext, NULL);
|
||||
if (mobj->hprev && P_MobjWasRemoved(mobj->hprev))
|
||||
P_SetTarget(&mobj->hprev, NULL);
|
||||
|
||||
mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG);
|
||||
|
||||
tmfloorthing = tmhitthing = NULL;
|
||||
|
||||
// 970 allows ANY mobj to trigger a linedef exec
|
||||
if (mobj->subsector && GETSECSPECIAL(mobj->subsector->sector->special, 2) == 8)
|
||||
{
|
||||
sector_t *sec2;
|
||||
|
||||
sec2 = P_ThingOnSpecial3DFloor(mobj);
|
||||
if (sec2 && GETSECSPECIAL(sec2->special, 2) == 1)
|
||||
P_LinedefExecute(sec2->tag, mobj, sec2);
|
||||
}
|
||||
|
||||
// Slowly scale up/down to reach your destscale.
|
||||
if (mobj->scale != mobj->destscale)
|
||||
static void P_MobjScaleThink(mobj_t *mobj)
|
||||
{
|
||||
fixed_t oldheight = mobj->height;
|
||||
UINT8 correctionType = 0; // Don't correct Z position, just gain height
|
||||
|
@ -7218,48 +7179,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
}
|
||||
}
|
||||
|
||||
if ((mobj->type == MT_GHOST || mobj->type == MT_THOK) && mobj->fuse > 0) // Not guaranteed to be MF_SCENERY or not MF_SCENERY!
|
||||
{
|
||||
if (mobj->flags2 & MF2_BOSSNOTRAP) // "fast" flag
|
||||
{
|
||||
if ((signed)((mobj->frame & FF_TRANSMASK) >> FF_TRANSSHIFT) < (NUMTRANSMAPS-1) - (2*mobj->fuse)/3)
|
||||
// fade out when nearing the end of fuse...
|
||||
mobj->frame = (mobj->frame & ~FF_TRANSMASK) | (((NUMTRANSMAPS-1) - (2*mobj->fuse)/3) << FF_TRANSSHIFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((signed)((mobj->frame & FF_TRANSMASK) >> FF_TRANSSHIFT) < (NUMTRANSMAPS-1) - mobj->fuse / 2)
|
||||
// fade out when nearing the end of fuse...
|
||||
mobj->frame = (mobj->frame & ~FF_TRANSMASK) | (((NUMTRANSMAPS-1) - mobj->fuse / 2) << FF_TRANSSHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
// Special thinker for scenery objects
|
||||
if (mobj->flags & MF_SCENERY)
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUAh_MobjThinker(mobj))
|
||||
return;
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (mobj->flags2 & MF2_SHIELD)
|
||||
if (!P_AddShield(mobj))
|
||||
return;
|
||||
|
||||
switch (mobj->type)
|
||||
{
|
||||
case MT_BOSSJUNK:
|
||||
mobj->flags2 ^= MF2_DONTDRAW;
|
||||
break;
|
||||
case MT_MACEPOINT:
|
||||
case MT_CHAINMACEPOINT:
|
||||
case MT_SPRINGBALLPOINT:
|
||||
case MT_CHAINPOINT:
|
||||
case MT_FIREBARPOINT:
|
||||
case MT_CUSTOMMACEPOINT:
|
||||
case MT_HIDDEN_SLING:
|
||||
static void P_MaceSceneryThink(mobj_t *mobj)
|
||||
{
|
||||
angle_t oldmovedir = mobj->movedir;
|
||||
|
||||
|
@ -7295,8 +7215,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
|
||||
mobj->flags2 |= MF2_BEYONDTHEGRAVE;
|
||||
}
|
||||
|
||||
break; // don't make bubble!
|
||||
return; // don't make bubble!
|
||||
}
|
||||
else if (mobj->flags2 & MF2_BEYONDTHEGRAVE)
|
||||
{
|
||||
|
@ -7321,6 +7240,419 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
// Okay, time to MOVE
|
||||
P_MaceRotate(mobj, mobj->movedir, oldmovedir);
|
||||
}
|
||||
|
||||
static boolean P_DrownNumbersSceneryThink(mobj_t *mobj)
|
||||
{
|
||||
if (!mobj->target)
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
return false;
|
||||
}
|
||||
if (!mobj->target->player || !(mobj->target->player->powers[pw_underwater] || mobj->target->player->powers[pw_spacetime]))
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
return false;
|
||||
}
|
||||
mobj->x = mobj->target->x;
|
||||
mobj->y = mobj->target->y;
|
||||
|
||||
mobj->destscale = mobj->target->destscale;
|
||||
P_SetScale(mobj, mobj->target->scale);
|
||||
|
||||
if (mobj->target->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
mobj->z = mobj->target->z - FixedMul(16*FRACUNIT, mobj->target->scale) - mobj->height;
|
||||
if (mobj->target->player->pflags & PF_FLIPCAM)
|
||||
mobj->eflags |= MFE_VERTICALFLIP;
|
||||
}
|
||||
else
|
||||
mobj->z = mobj->target->z + (mobj->target->height) + FixedMul(8*FRACUNIT, mobj->target->scale); // Adjust height for height changes
|
||||
|
||||
if (mobj->threshold <= 35)
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
else
|
||||
mobj->flags2 &= ~MF2_DONTDRAW;
|
||||
if (mobj->threshold <= 30)
|
||||
mobj->threshold = 40;
|
||||
mobj->threshold--;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void P_FlameJetSceneryThink(mobj_t *mobj)
|
||||
{
|
||||
mobj_t *flame;
|
||||
fixed_t strength;
|
||||
|
||||
if (!(mobj->flags2 & MF2_FIRING))
|
||||
return;
|
||||
|
||||
if ((leveltime & 3) == 0)
|
||||
return;
|
||||
|
||||
// Wave the flames back and forth. Reactiontime determines which direction it's going.
|
||||
if (mobj->fuse <= -16)
|
||||
mobj->reactiontime = 1;
|
||||
else if (mobj->fuse >= 16)
|
||||
mobj->reactiontime = 0;
|
||||
|
||||
if (mobj->reactiontime)
|
||||
mobj->fuse += 2;
|
||||
else
|
||||
mobj->fuse -= 2;
|
||||
|
||||
flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME);
|
||||
P_SetMobjState(flame, S_FLAMEJETFLAME4);
|
||||
|
||||
flame->angle = mobj->angle;
|
||||
|
||||
if (mobj->flags2 & MF2_AMBUSH) // Wave up and down instead of side-to-side
|
||||
flame->momz = mobj->fuse << (FRACBITS - 2);
|
||||
else
|
||||
flame->angle += FixedAngle(mobj->fuse<<FRACBITS);
|
||||
|
||||
strength = 20*FRACUNIT;
|
||||
strength -= ((20*FRACUNIT)/16)*mobj->movedir;
|
||||
|
||||
P_InstaThrust(flame, flame->angle, strength);
|
||||
S_StartSound(flame, sfx_fire);
|
||||
}
|
||||
|
||||
static void P_VerticalFlameJetSceneryThink(mobj_t *mobj)
|
||||
{
|
||||
mobj_t *flame;
|
||||
fixed_t strength;
|
||||
|
||||
if (!(mobj->flags2 & MF2_FIRING))
|
||||
return;
|
||||
|
||||
if ((leveltime & 3) == 0)
|
||||
return;
|
||||
|
||||
// Wave the flames back and forth. Reactiontime determines which direction it's going.
|
||||
if (mobj->fuse <= -16)
|
||||
mobj->reactiontime = 1;
|
||||
else if (mobj->fuse >= 16)
|
||||
mobj->reactiontime = 0;
|
||||
|
||||
if (mobj->reactiontime)
|
||||
mobj->fuse++;
|
||||
else
|
||||
mobj->fuse--;
|
||||
|
||||
flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME);
|
||||
|
||||
strength = 20*FRACUNIT;
|
||||
strength -= ((20*FRACUNIT)/16)*mobj->movedir;
|
||||
|
||||
// If deaf'd, the object spawns on the ceiling.
|
||||
if (mobj->flags2 & MF2_AMBUSH)
|
||||
{
|
||||
mobj->z = mobj->ceilingz - mobj->height;
|
||||
flame->momz = -strength;
|
||||
}
|
||||
else
|
||||
{
|
||||
flame->momz = strength;
|
||||
P_SetMobjState(flame, S_FLAMEJETFLAME7);
|
||||
}
|
||||
P_InstaThrust(flame, mobj->angle, FixedDiv(mobj->fuse*FRACUNIT, 3*FRACUNIT));
|
||||
S_StartSound(flame, sfx_fire);
|
||||
}
|
||||
|
||||
static boolean P_ParticleGenSceneryThink(mobj_t *mobj)
|
||||
{
|
||||
if (!mobj->lastlook)
|
||||
return false;
|
||||
|
||||
if (!mobj->threshold)
|
||||
return false;
|
||||
|
||||
if (--mobj->fuse <= 0)
|
||||
{
|
||||
INT32 i = 0;
|
||||
mobj_t *spawn;
|
||||
fixed_t bottomheight, topheight;
|
||||
INT32 type = mobj->threshold, line = mobj->cvmem;
|
||||
|
||||
mobj->fuse = (tic_t)mobj->reactiontime;
|
||||
|
||||
bottomheight = lines[line].frontsector->floorheight;
|
||||
topheight = lines[line].frontsector->ceilingheight - mobjinfo[(mobjtype_t)type].height;
|
||||
|
||||
if (mobj->waterbottom != bottomheight || mobj->watertop != topheight)
|
||||
{
|
||||
if (mobj->movefactor && (topheight > bottomheight))
|
||||
mobj->health = (tic_t)(FixedDiv((topheight - bottomheight), abs(mobj->movefactor)) >> FRACBITS);
|
||||
else
|
||||
mobj->health = 0;
|
||||
|
||||
mobj->z = ((mobj->flags2 & MF2_OBJECTFLIP) ? topheight : bottomheight);
|
||||
}
|
||||
|
||||
if (!mobj->health)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < mobj->lastlook; i++)
|
||||
{
|
||||
spawn = P_SpawnMobj(
|
||||
mobj->x + FixedMul(FixedMul(mobj->friction, mobj->scale), FINECOSINE(mobj->angle >> ANGLETOFINESHIFT)),
|
||||
mobj->y + FixedMul(FixedMul(mobj->friction, mobj->scale), FINESINE(mobj->angle >> ANGLETOFINESHIFT)),
|
||||
mobj->z,
|
||||
(mobjtype_t)mobj->threshold);
|
||||
P_SetScale(spawn, mobj->scale);
|
||||
spawn->momz = FixedMul(mobj->movefactor, spawn->scale);
|
||||
spawn->destscale = spawn->scale/100;
|
||||
spawn->scalespeed = spawn->scale/mobj->health;
|
||||
spawn->tics = (tic_t)mobj->health;
|
||||
spawn->flags2 |= (mobj->flags2 & MF2_OBJECTFLIP);
|
||||
spawn->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones
|
||||
|
||||
mobj->angle += mobj->movedir;
|
||||
}
|
||||
|
||||
mobj->angle += (angle_t)mobj->movecount;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void P_RosySceneryThink(mobj_t *mobj)
|
||||
{
|
||||
UINT8 i;
|
||||
fixed_t pdist = 1700*mobj->scale, work, actualwork;
|
||||
player_t *player = NULL;
|
||||
statenum_t stat = (mobj->state - states);
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
if (!players[i].mo)
|
||||
continue;
|
||||
if (players[i].bot)
|
||||
continue;
|
||||
if (!players[i].mo->health)
|
||||
continue;
|
||||
actualwork = work = FixedHypot(mobj->x - players[i].mo->x, mobj->y - players[i].mo->y);
|
||||
if (player)
|
||||
{
|
||||
if (players[i].skin == 0 || players[i].skin == 5)
|
||||
work = (2*work)/3;
|
||||
if (work >= pdist)
|
||||
continue;
|
||||
}
|
||||
pdist = actualwork;
|
||||
player = &players[i];
|
||||
}
|
||||
|
||||
if (stat == S_ROSY_JUMP || stat == S_ROSY_PAIN)
|
||||
{
|
||||
if (P_IsObjectOnGround(mobj))
|
||||
{
|
||||
mobj->momx = mobj->momy = 0;
|
||||
if (player && mobj->cvmem < (-2*TICRATE))
|
||||
stat = S_ROSY_UNHAPPY;
|
||||
else
|
||||
stat = S_ROSY_WALK;
|
||||
P_SetMobjState(mobj, stat);
|
||||
}
|
||||
else if (P_MobjFlip(mobj)*mobj->momz < 0)
|
||||
mobj->frame = mobj->state->frame + mobj->state->var1;
|
||||
}
|
||||
|
||||
if (!player)
|
||||
{
|
||||
if ((stat < S_ROSY_IDLE1 || stat > S_ROSY_IDLE4) && stat != S_ROSY_JUMP)
|
||||
{
|
||||
mobj->momx = mobj->momy = 0;
|
||||
P_SetMobjState(mobj, S_ROSY_IDLE1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean dojump = false, targonground, love, makeheart = false;
|
||||
if (mobj->target != player->mo)
|
||||
P_SetTarget(&mobj->target, player->mo);
|
||||
// Tatsuru: Don't try to hug them if they're above or below you!
|
||||
targonground = (P_IsObjectOnGround(mobj->target) && (player->panim == PA_IDLE || player->panim == PA_WALK || player->panim == PA_RUN) && player->mo->z == mobj->z);
|
||||
love = (player->skin == 0 || player->skin == 5);
|
||||
|
||||
switch (stat)
|
||||
{
|
||||
case S_ROSY_IDLE1:
|
||||
case S_ROSY_IDLE2:
|
||||
case S_ROSY_IDLE3:
|
||||
case S_ROSY_IDLE4:
|
||||
dojump = true;
|
||||
break;
|
||||
case S_ROSY_JUMP:
|
||||
case S_ROSY_PAIN:
|
||||
// handled above
|
||||
break;
|
||||
case S_ROSY_WALK:
|
||||
{
|
||||
fixed_t x = mobj->x, y = mobj->y, z = mobj->z;
|
||||
angle_t angletoplayer = R_PointToAngle2(x, y, mobj->target->x, mobj->target->y);
|
||||
boolean allowed = P_TryMove(mobj, mobj->target->x, mobj->target->y, false);
|
||||
|
||||
P_UnsetThingPosition(mobj);
|
||||
mobj->x = x;
|
||||
mobj->y = y;
|
||||
mobj->z = z;
|
||||
P_SetThingPosition(mobj);
|
||||
|
||||
if (allowed)
|
||||
{
|
||||
fixed_t mom, max;
|
||||
P_Thrust(mobj, angletoplayer, (3*FRACUNIT) >> 1);
|
||||
mom = FixedHypot(mobj->momx, mobj->momy);
|
||||
max = pdist;
|
||||
if ((--mobj->extravalue1) <= 0)
|
||||
{
|
||||
if (++mobj->frame > mobj->state->frame + mobj->state->var1)
|
||||
mobj->frame = mobj->state->frame;
|
||||
if (mom > 12*mobj->scale)
|
||||
mobj->extravalue1 = 2;
|
||||
else if (mom > 6*mobj->scale)
|
||||
mobj->extravalue1 = 3;
|
||||
else
|
||||
mobj->extravalue1 = 4;
|
||||
}
|
||||
if (max < (mobj->radius + mobj->target->radius))
|
||||
{
|
||||
mobj->momx = mobj->target->player->cmomx;
|
||||
mobj->momy = mobj->target->player->cmomy;
|
||||
if ((mobj->cvmem > TICRATE && !player->exiting) || !targonground)
|
||||
P_SetMobjState(mobj, (stat = S_ROSY_STND));
|
||||
else
|
||||
{
|
||||
mobj->target->momx = mobj->momx;
|
||||
mobj->target->momy = mobj->momy;
|
||||
P_SetMobjState(mobj, (stat = S_ROSY_HUG));
|
||||
S_StartSound(mobj, sfx_cdpcm6);
|
||||
mobj->angle = angletoplayer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
max /= 3;
|
||||
if (max > 30*mobj->scale)
|
||||
max = 30*mobj->scale;
|
||||
if (mom > max && max > mobj->scale)
|
||||
{
|
||||
max = FixedDiv(max, mom);
|
||||
mobj->momx = FixedMul(mobj->momx, max);
|
||||
mobj->momy = FixedMul(mobj->momy, max);
|
||||
}
|
||||
if (abs(mobj->momx) > mobj->scale || abs(mobj->momy) > mobj->scale)
|
||||
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
|
||||
}
|
||||
}
|
||||
else
|
||||
dojump = true;
|
||||
}
|
||||
break;
|
||||
case S_ROSY_HUG:
|
||||
if (targonground)
|
||||
{
|
||||
player->pflags |= PF_STASIS;
|
||||
if (mobj->cvmem < 5*TICRATE)
|
||||
mobj->cvmem++;
|
||||
if (love && !(leveltime & 7))
|
||||
makeheart = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mobj->cvmem < (love ? 5*TICRATE : 0))
|
||||
{
|
||||
P_SetMobjState(mobj, (stat = S_ROSY_PAIN));
|
||||
S_StartSound(mobj, sfx_cdpcm7);
|
||||
}
|
||||
else
|
||||
P_SetMobjState(mobj, (stat = S_ROSY_JUMP));
|
||||
var1 = var2 = 0;
|
||||
A_DoNPCPain(mobj);
|
||||
mobj->cvmem -= TICRATE;
|
||||
}
|
||||
break;
|
||||
case S_ROSY_STND:
|
||||
if ((pdist > (mobj->radius + mobj->target->radius + 3*(mobj->scale + mobj->target->scale))))
|
||||
P_SetMobjState(mobj, (stat = S_ROSY_WALK));
|
||||
else if (!targonground)
|
||||
;
|
||||
else
|
||||
{
|
||||
if (love && !(leveltime & 15))
|
||||
makeheart = true;
|
||||
if (player->exiting || --mobj->cvmem < TICRATE)
|
||||
{
|
||||
P_SetMobjState(mobj, (stat = S_ROSY_HUG));
|
||||
S_StartSound(mobj, sfx_cdpcm6);
|
||||
mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y);
|
||||
mobj->target->momx = mobj->momx;
|
||||
mobj->target->momy = mobj->momy;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case S_ROSY_UNHAPPY:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (stat == S_ROSY_HUG)
|
||||
{
|
||||
if (player->panim != PA_IDLE)
|
||||
P_SetPlayerMobjState(mobj->target, S_PLAY_STND);
|
||||
player->pflags |= PF_STASIS;
|
||||
}
|
||||
|
||||
if (dojump)
|
||||
{
|
||||
P_SetMobjState(mobj, S_ROSY_JUMP);
|
||||
mobj->z += P_MobjFlip(mobj);
|
||||
mobj->momx = mobj->momy = 0;
|
||||
P_SetObjectMomZ(mobj, 6 << FRACBITS, false);
|
||||
S_StartSound(mobj, sfx_cdfm02);
|
||||
}
|
||||
|
||||
if (makeheart)
|
||||
{
|
||||
mobj_t *cdlhrt = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_CDLHRT);
|
||||
cdlhrt->destscale = (5*mobj->scale) >> 4;
|
||||
P_SetScale(cdlhrt, cdlhrt->destscale);
|
||||
cdlhrt->fuse = (5*TICRATE) >> 1;
|
||||
cdlhrt->momz = mobj->scale;
|
||||
P_SetTarget(&cdlhrt->target, mobj);
|
||||
cdlhrt->extravalue1 = mobj->x;
|
||||
cdlhrt->extravalue2 = mobj->y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void P_MobjSceneryThink(mobj_t *mobj)
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUAh_MobjThinker(mobj))
|
||||
return;
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if ((mobj->flags2 & MF2_SHIELD) && !P_AddShield(mobj))
|
||||
return;
|
||||
|
||||
switch (mobj->type)
|
||||
{
|
||||
case MT_BOSSJUNK:
|
||||
mobj->flags2 ^= MF2_DONTDRAW;
|
||||
break;
|
||||
case MT_MACEPOINT:
|
||||
case MT_CHAINMACEPOINT:
|
||||
case MT_SPRINGBALLPOINT:
|
||||
case MT_CHAINPOINT:
|
||||
case MT_FIREBARPOINT:
|
||||
case MT_CUSTOMMACEPOINT:
|
||||
case MT_HIDDEN_SLING:
|
||||
P_MaceSceneryThink(mobj);
|
||||
break;
|
||||
case MT_HOOP:
|
||||
if (mobj->fuse > 1)
|
||||
|
@ -7558,109 +7890,14 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->z = mobj->threshold - FixedMul((16 + abs((signed)(leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->scale);
|
||||
break;
|
||||
case MT_DROWNNUMBERS:
|
||||
if (!mobj->target)
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
if (!P_DrownNumbersSceneryThink(mobj))
|
||||
return;
|
||||
}
|
||||
if (!mobj->target->player || !(mobj->target->player->powers[pw_underwater] || mobj->target->player->powers[pw_spacetime]))
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
}
|
||||
mobj->x = mobj->target->x;
|
||||
mobj->y = mobj->target->y;
|
||||
|
||||
mobj->destscale = mobj->target->destscale;
|
||||
P_SetScale(mobj, mobj->target->scale);
|
||||
|
||||
if (mobj->target->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
mobj->z = mobj->target->z - FixedMul(16*FRACUNIT, mobj->target->scale) - mobj->height;
|
||||
if (mobj->target->player->pflags & PF_FLIPCAM)
|
||||
mobj->eflags |= MFE_VERTICALFLIP;
|
||||
}
|
||||
else
|
||||
mobj->z = mobj->target->z + (mobj->target->height) + FixedMul(8*FRACUNIT, mobj->target->scale); // Adjust height for height changes
|
||||
|
||||
if (mobj->threshold <= 35)
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
else
|
||||
mobj->flags2 &= ~MF2_DONTDRAW;
|
||||
if (mobj->threshold <= 30)
|
||||
mobj->threshold = 40;
|
||||
mobj->threshold--;
|
||||
break;
|
||||
case MT_FLAMEJET:
|
||||
if ((mobj->flags2 & MF2_FIRING) && (leveltime & 3) == 0)
|
||||
{
|
||||
mobj_t *flame;
|
||||
fixed_t strength;
|
||||
|
||||
// Wave the flames back and forth. Reactiontime determines which direction it's going.
|
||||
if (mobj->fuse <= -16)
|
||||
mobj->reactiontime = 1;
|
||||
else if (mobj->fuse >= 16)
|
||||
mobj->reactiontime = 0;
|
||||
|
||||
if (mobj->reactiontime)
|
||||
mobj->fuse += 2;
|
||||
else
|
||||
mobj->fuse -= 2;
|
||||
|
||||
flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME);
|
||||
P_SetMobjState(flame, S_FLAMEJETFLAME4);
|
||||
|
||||
flame->angle = mobj->angle;
|
||||
|
||||
if (mobj->flags2 & MF2_AMBUSH) // Wave up and down instead of side-to-side
|
||||
flame->momz = mobj->fuse << (FRACBITS-2);
|
||||
else
|
||||
flame->angle += FixedAngle(mobj->fuse*FRACUNIT);
|
||||
|
||||
strength = 20*FRACUNIT;
|
||||
strength -= ((20*FRACUNIT)/16)*mobj->movedir;
|
||||
|
||||
P_InstaThrust(flame, flame->angle, strength);
|
||||
S_StartSound(flame, sfx_fire);
|
||||
}
|
||||
P_FlameJetSceneryThink(mobj);
|
||||
break;
|
||||
case MT_VERTICALFLAMEJET:
|
||||
if ((mobj->flags2 & MF2_FIRING) && (leveltime & 3) == 0)
|
||||
{
|
||||
mobj_t *flame;
|
||||
fixed_t strength;
|
||||
|
||||
// Wave the flames back and forth. Reactiontime determines which direction it's going.
|
||||
if (mobj->fuse <= -16)
|
||||
mobj->reactiontime = 1;
|
||||
else if (mobj->fuse >= 16)
|
||||
mobj->reactiontime = 0;
|
||||
|
||||
if (mobj->reactiontime)
|
||||
mobj->fuse++;
|
||||
else
|
||||
mobj->fuse--;
|
||||
|
||||
flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME);
|
||||
|
||||
strength = 20*FRACUNIT;
|
||||
strength -= ((20*FRACUNIT)/16)*mobj->movedir;
|
||||
|
||||
// If deaf'd, the object spawns on the ceiling.
|
||||
if (mobj->flags2 & MF2_AMBUSH)
|
||||
{
|
||||
mobj->z = mobj->ceilingz-mobj->height;
|
||||
flame->momz = -strength;
|
||||
}
|
||||
else
|
||||
{
|
||||
flame->momz = strength;
|
||||
P_SetMobjState(flame, S_FLAMEJETFLAME7);
|
||||
}
|
||||
P_InstaThrust(flame, mobj->angle, FixedDiv(mobj->fuse*FRACUNIT,3*FRACUNIT));
|
||||
S_StartSound(flame, sfx_fire);
|
||||
}
|
||||
P_VerticalFlameJetSceneryThink(mobj);
|
||||
break;
|
||||
case MT_FLICKY_01_CENTER:
|
||||
case MT_FLICKY_02_CENTER:
|
||||
|
@ -7721,273 +7958,15 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
}
|
||||
break;
|
||||
case MT_PARTICLEGEN:
|
||||
if (!mobj->lastlook)
|
||||
if (!P_ParticleGenSceneryThink(mobj))
|
||||
return;
|
||||
|
||||
if (!mobj->threshold)
|
||||
return;
|
||||
|
||||
if (--mobj->fuse <= 0)
|
||||
{
|
||||
INT32 i = 0;
|
||||
mobj_t *spawn;
|
||||
fixed_t bottomheight, topheight;
|
||||
INT32 type = mobj->threshold, line = mobj->cvmem;
|
||||
|
||||
mobj->fuse = (tic_t)mobj->reactiontime;
|
||||
|
||||
bottomheight = lines[line].frontsector->floorheight;
|
||||
topheight = lines[line].frontsector->ceilingheight - mobjinfo[(mobjtype_t)type].height;
|
||||
|
||||
if (mobj->waterbottom != bottomheight || mobj->watertop != topheight)
|
||||
{
|
||||
if (mobj->movefactor && (topheight > bottomheight))
|
||||
mobj->health = (tic_t)(FixedDiv((topheight - bottomheight), abs(mobj->movefactor)) >> FRACBITS);
|
||||
else
|
||||
mobj->health = 0;
|
||||
|
||||
mobj->z = ((mobj->flags2 & MF2_OBJECTFLIP) ? topheight : bottomheight);
|
||||
}
|
||||
|
||||
if (!mobj->health)
|
||||
return;
|
||||
|
||||
for (i = 0; i < mobj->lastlook; i++)
|
||||
{
|
||||
spawn = P_SpawnMobj(
|
||||
mobj->x + FixedMul(FixedMul(mobj->friction, mobj->scale), FINECOSINE(mobj->angle>>ANGLETOFINESHIFT)),
|
||||
mobj->y + FixedMul(FixedMul(mobj->friction, mobj->scale), FINESINE(mobj->angle>>ANGLETOFINESHIFT)),
|
||||
mobj->z,
|
||||
(mobjtype_t)mobj->threshold);
|
||||
P_SetScale(spawn, mobj->scale);
|
||||
spawn->momz = FixedMul(mobj->movefactor, spawn->scale);
|
||||
spawn->destscale = spawn->scale/100;
|
||||
spawn->scalespeed = spawn->scale/mobj->health;
|
||||
spawn->tics = (tic_t)mobj->health;
|
||||
spawn->flags2 |= (mobj->flags2 & MF2_OBJECTFLIP);
|
||||
spawn->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones
|
||||
|
||||
mobj->angle += mobj->movedir;
|
||||
}
|
||||
|
||||
mobj->angle += (angle_t)mobj->movecount;
|
||||
}
|
||||
break;
|
||||
case MT_FSGNA:
|
||||
if (mobj->movedir)
|
||||
mobj->angle += mobj->movedir;
|
||||
break;
|
||||
case MT_ROSY:
|
||||
{
|
||||
UINT8 i;
|
||||
fixed_t pdist = 1700*mobj->scale, work, actualwork;
|
||||
player_t *player = NULL;
|
||||
statenum_t stat = (mobj->state-states);
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
if (!players[i].mo)
|
||||
continue;
|
||||
if (players[i].bot)
|
||||
continue;
|
||||
if (!players[i].mo->health)
|
||||
continue;
|
||||
actualwork = work = FixedHypot(mobj->x-players[i].mo->x, mobj->y-players[i].mo->y);
|
||||
if (player)
|
||||
{
|
||||
if (players[i].skin == 0 || players[i].skin == 5)
|
||||
work = (2*work)/3;
|
||||
if (work >= pdist)
|
||||
continue;
|
||||
}
|
||||
pdist = actualwork;
|
||||
player = &players[i];
|
||||
}
|
||||
|
||||
if (stat == S_ROSY_JUMP || stat == S_ROSY_PAIN)
|
||||
{
|
||||
if (P_IsObjectOnGround(mobj))
|
||||
{
|
||||
mobj->momx = mobj->momy = 0;
|
||||
if (player && mobj->cvmem < (-2*TICRATE))
|
||||
stat = S_ROSY_UNHAPPY;
|
||||
else
|
||||
stat = S_ROSY_WALK;
|
||||
P_SetMobjState(mobj, stat);
|
||||
}
|
||||
else if (P_MobjFlip(mobj)*mobj->momz < 0)
|
||||
mobj->frame = mobj->state->frame+mobj->state->var1;
|
||||
}
|
||||
|
||||
if (!player)
|
||||
{
|
||||
if ((stat < S_ROSY_IDLE1 || stat > S_ROSY_IDLE4) && stat != S_ROSY_JUMP)
|
||||
{
|
||||
mobj->momx = mobj->momy = 0;
|
||||
P_SetMobjState(mobj, S_ROSY_IDLE1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean dojump = false, targonground, love, makeheart = false;
|
||||
if (mobj->target != player->mo)
|
||||
P_SetTarget(&mobj->target, player->mo);
|
||||
// Tatsuru: Don't try to hug them if they're above or below you!
|
||||
targonground = (P_IsObjectOnGround(mobj->target) && (player->panim == PA_IDLE || player->panim == PA_WALK || player->panim == PA_RUN) && player->mo->z == mobj->z);
|
||||
love = (player->skin == 0 || player->skin == 5);
|
||||
|
||||
switch (stat)
|
||||
{
|
||||
case S_ROSY_IDLE1:
|
||||
case S_ROSY_IDLE2:
|
||||
case S_ROSY_IDLE3:
|
||||
case S_ROSY_IDLE4:
|
||||
dojump = true;
|
||||
break;
|
||||
case S_ROSY_JUMP:
|
||||
case S_ROSY_PAIN:
|
||||
// handled above
|
||||
break;
|
||||
case S_ROSY_WALK:
|
||||
{
|
||||
fixed_t x = mobj->x, y = mobj->y, z = mobj->z;
|
||||
angle_t angletoplayer = R_PointToAngle2(x, y, mobj->target->x, mobj->target->y);
|
||||
boolean allowed = P_TryMove(mobj, mobj->target->x, mobj->target->y, false);
|
||||
|
||||
P_UnsetThingPosition(mobj);
|
||||
mobj->x = x;
|
||||
mobj->y = y;
|
||||
mobj->z = z;
|
||||
P_SetThingPosition(mobj);
|
||||
|
||||
if (allowed)
|
||||
{
|
||||
fixed_t mom, max;
|
||||
P_Thrust(mobj, angletoplayer, (3*FRACUNIT)>>1);
|
||||
mom = FixedHypot(mobj->momx, mobj->momy);
|
||||
max = pdist;
|
||||
if ((--mobj->extravalue1) <= 0)
|
||||
{
|
||||
if (++mobj->frame > mobj->state->frame+mobj->state->var1)
|
||||
mobj->frame = mobj->state->frame;
|
||||
if (mom > 12*mobj->scale)
|
||||
mobj->extravalue1 = 2;
|
||||
else if (mom > 6*mobj->scale)
|
||||
mobj->extravalue1 = 3;
|
||||
else
|
||||
mobj->extravalue1 = 4;
|
||||
}
|
||||
if (max < (mobj->radius + mobj->target->radius))
|
||||
{
|
||||
mobj->momx = mobj->target->player->cmomx;
|
||||
mobj->momy = mobj->target->player->cmomy;
|
||||
if ((mobj->cvmem > TICRATE && !player->exiting) || !targonground)
|
||||
P_SetMobjState(mobj, (stat = S_ROSY_STND));
|
||||
else
|
||||
{
|
||||
mobj->target->momx = mobj->momx;
|
||||
mobj->target->momy = mobj->momy;
|
||||
P_SetMobjState(mobj, (stat = S_ROSY_HUG));
|
||||
S_StartSound(mobj, sfx_cdpcm6);
|
||||
mobj->angle = angletoplayer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
max /= 3;
|
||||
if (max > 30*mobj->scale)
|
||||
max = 30*mobj->scale;
|
||||
if (mom > max && max > mobj->scale)
|
||||
{
|
||||
max = FixedDiv(max, mom);
|
||||
mobj->momx = FixedMul(mobj->momx, max);
|
||||
mobj->momy = FixedMul(mobj->momy, max);
|
||||
}
|
||||
if (abs(mobj->momx) > mobj->scale || abs(mobj->momy) > mobj->scale)
|
||||
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
|
||||
}
|
||||
}
|
||||
else
|
||||
dojump = true;
|
||||
}
|
||||
break;
|
||||
case S_ROSY_HUG:
|
||||
if (targonground)
|
||||
{
|
||||
player->pflags |= PF_STASIS;
|
||||
if (mobj->cvmem < 5*TICRATE)
|
||||
mobj->cvmem++;
|
||||
if (love && !(leveltime & 7))
|
||||
makeheart = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mobj->cvmem < (love ? 5*TICRATE : 0))
|
||||
{
|
||||
P_SetMobjState(mobj, (stat = S_ROSY_PAIN));
|
||||
S_StartSound(mobj, sfx_cdpcm7);
|
||||
}
|
||||
else
|
||||
P_SetMobjState(mobj, (stat = S_ROSY_JUMP));
|
||||
var1 = var2 = 0;
|
||||
A_DoNPCPain(mobj);
|
||||
mobj->cvmem -= TICRATE;
|
||||
}
|
||||
break;
|
||||
case S_ROSY_STND:
|
||||
if ((pdist > (mobj->radius + mobj->target->radius + 3*(mobj->scale + mobj->target->scale))))
|
||||
P_SetMobjState(mobj, (stat = S_ROSY_WALK));
|
||||
else if (!targonground)
|
||||
;
|
||||
else
|
||||
{
|
||||
if (love && !(leveltime & 15))
|
||||
makeheart = true;
|
||||
if (player->exiting || --mobj->cvmem < TICRATE)
|
||||
{
|
||||
P_SetMobjState(mobj, (stat = S_ROSY_HUG));
|
||||
S_StartSound(mobj, sfx_cdpcm6);
|
||||
mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y);
|
||||
mobj->target->momx = mobj->momx;
|
||||
mobj->target->momy = mobj->momy;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case S_ROSY_UNHAPPY:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (stat == S_ROSY_HUG)
|
||||
{
|
||||
if (player->panim != PA_IDLE)
|
||||
P_SetPlayerMobjState(mobj->target, S_PLAY_STND);
|
||||
player->pflags |= PF_STASIS;
|
||||
}
|
||||
|
||||
if (dojump)
|
||||
{
|
||||
P_SetMobjState(mobj, S_ROSY_JUMP);
|
||||
mobj->z += P_MobjFlip(mobj);
|
||||
mobj->momx = mobj->momy = 0;
|
||||
P_SetObjectMomZ(mobj, 6<<FRACBITS, false);
|
||||
S_StartSound(mobj, sfx_cdfm02);
|
||||
}
|
||||
|
||||
if (makeheart)
|
||||
{
|
||||
mobj_t *cdlhrt = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_CDLHRT);
|
||||
cdlhrt->destscale = (5*mobj->scale)>>4;
|
||||
P_SetScale(cdlhrt, cdlhrt->destscale);
|
||||
cdlhrt->fuse = (5*TICRATE)>>1;
|
||||
cdlhrt->momz = mobj->scale;
|
||||
P_SetTarget(&cdlhrt->target, mobj);
|
||||
cdlhrt->extravalue1 = mobj->x;
|
||||
cdlhrt->extravalue2 = mobj->y;
|
||||
}
|
||||
}
|
||||
}
|
||||
P_RosySceneryThink(mobj);
|
||||
break;
|
||||
case MT_CDLHRT:
|
||||
{
|
||||
|
@ -8037,6 +8016,69 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
}
|
||||
|
||||
P_SceneryThinker(mobj);
|
||||
}
|
||||
|
||||
//
|
||||
// P_MobjThinker
|
||||
//
|
||||
void P_MobjThinker(mobj_t *mobj)
|
||||
{
|
||||
I_Assert(mobj != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(mobj));
|
||||
|
||||
if (mobj->flags & MF_NOTHINK)
|
||||
return;
|
||||
|
||||
if ((mobj->flags & MF_BOSS) && mobj->spawnpoint && (bossdisabled & (1<<mobj->spawnpoint->extrainfo)))
|
||||
return;
|
||||
|
||||
// Remove dead target/tracer.
|
||||
if (mobj->target && P_MobjWasRemoved(mobj->target))
|
||||
P_SetTarget(&mobj->target, NULL);
|
||||
if (mobj->tracer && P_MobjWasRemoved(mobj->tracer))
|
||||
P_SetTarget(&mobj->tracer, NULL);
|
||||
if (mobj->hnext && P_MobjWasRemoved(mobj->hnext))
|
||||
P_SetTarget(&mobj->hnext, NULL);
|
||||
if (mobj->hprev && P_MobjWasRemoved(mobj->hprev))
|
||||
P_SetTarget(&mobj->hprev, NULL);
|
||||
|
||||
mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG);
|
||||
|
||||
tmfloorthing = tmhitthing = NULL;
|
||||
|
||||
// Sector special (2,8) allows ANY mobj to trigger a linedef exec
|
||||
if (mobj->subsector && GETSECSPECIAL(mobj->subsector->sector->special, 2) == 8)
|
||||
{
|
||||
sector_t *sec2;
|
||||
|
||||
sec2 = P_ThingOnSpecial3DFloor(mobj);
|
||||
if (sec2 && GETSECSPECIAL(sec2->special, 2) == 1)
|
||||
P_LinedefExecute(sec2->tag, mobj, sec2);
|
||||
}
|
||||
|
||||
if (mobj->scale != mobj->destscale)
|
||||
P_MobjScaleThink(mobj); // Slowly scale up/down to reach your destscale.
|
||||
|
||||
if ((mobj->type == MT_GHOST || mobj->type == MT_THOK) && mobj->fuse > 0) // Not guaranteed to be MF_SCENERY or not MF_SCENERY!
|
||||
{
|
||||
if (mobj->flags2 & MF2_BOSSNOTRAP) // "fast" flag
|
||||
{
|
||||
if ((signed)((mobj->frame & FF_TRANSMASK) >> FF_TRANSSHIFT) < (NUMTRANSMAPS-1) - (2*mobj->fuse)/3)
|
||||
// fade out when nearing the end of fuse...
|
||||
mobj->frame = (mobj->frame & ~FF_TRANSMASK) | (((NUMTRANSMAPS-1) - (2*mobj->fuse)/3) << FF_TRANSSHIFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((signed)((mobj->frame & FF_TRANSMASK) >> FF_TRANSSHIFT) < (NUMTRANSMAPS-1) - mobj->fuse / 2)
|
||||
// fade out when nearing the end of fuse...
|
||||
mobj->frame = (mobj->frame & ~FF_TRANSMASK) | (((NUMTRANSMAPS-1) - mobj->fuse / 2) << FF_TRANSSHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
// Special thinker for scenery objects
|
||||
if (mobj->flags & MF_SCENERY)
|
||||
{
|
||||
P_MobjSceneryThink(mobj);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue