From e4930535f344d8203ade9242930f5e91c4357c85 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 24 Dec 2021 12:45:51 -0500 Subject: [PATCH] P_InitAngle, to fix angle interpolation on spawning objects --- src/p_enemy.c | 69 +++++++++++++++++++++++------------------------ src/p_inter.c | 10 +++---- src/p_local.h | 3 +++ src/p_map.c | 24 +++++++++++++++++ src/p_mobj.c | 72 ++++++++++++++++++++++++++++---------------------- src/p_mobj.h | 2 +- src/p_saveg.c | 20 +++++++------- src/p_spec.c | 2 +- src/p_telept.c | 4 +-- src/p_user.c | 2 +- src/r_fps.c | 5 ++++ src/r_fps.h | 2 ++ 12 files changed, 130 insertions(+), 85 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 87aa5ff2f..40aab9ec1 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -1406,7 +1406,7 @@ void A_StatueBurst(mobj_t *actor) if (!locvar1 || !(new = P_SpawnMobjFromMobj(actor, 0, 0, 0, locvar1))) return; - new->angle = actor->angle; + P_InitAngle(new, actor->angle); P_SetTarget(&new->target, actor->target); if (locvar2) P_SetMobjState(new, (statenum_t)locvar2); @@ -2700,8 +2700,8 @@ void A_LobShot(mobj_t *actor) P_SetTarget(&shot->target, actor); // where it came from - shot->angle = an = actor->angle; - an >>= ANGLETOFINESHIFT; + P_InitAngle(shot, actor->angle); + an = actor->angle >> ANGLETOFINESHIFT; dist = P_AproxDistance(actor->target->x - shot->x, actor->target->y - shot->y); @@ -3067,7 +3067,7 @@ void A_Boss1Laser(mobj_t *actor) S_StartSound(actor, mobjinfo[locvar1].seesound); point = P_SpawnMobj(x + P_ReturnThrustX(actor, actor->angle, actor->radius), y + P_ReturnThrustY(actor, actor->angle, actor->radius), actor->z - actor->height / 2, MT_EGGMOBILE_TARGET); - point->angle = actor->angle; + P_InitAngle(point, actor->angle); point->fuse = dur+1; P_SetTarget(&point->target, actor->target); P_SetTarget(&actor->target, point); @@ -3077,7 +3077,7 @@ void A_Boss1Laser(mobj_t *actor) point = P_SpawnMobj(x, y, z, locvar1); P_SetTarget(&point->target, actor); - point->angle = actor->angle; + P_InitAngle(point, actor->angle); speed = point->radius; point->momz = FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT), speed); point->momx = FixedMul(FINESINE(angle>>ANGLETOFINESHIFT), FixedMul(FINECOSINE(point->angle>>ANGLETOFINESHIFT), speed)); @@ -3086,7 +3086,7 @@ void A_Boss1Laser(mobj_t *actor) for (i = 0; i < 256; i++) { mobj_t *mo = P_SpawnMobj(point->x, point->y, point->z, point->type); - mo->angle = point->angle; + P_InitAngle(mo, point->angle); mo->color = LASERCOLORS[((UINT8)(i + 3*dur) >> 2) % sizeof(LASERCOLORS)]; // codeing P_UnsetThingPosition(mo); mo->flags = MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY; @@ -3118,7 +3118,7 @@ void A_Boss1Laser(mobj_t *actor) if (z - floorz < mobjinfo[MT_EGGMOBILE_FIRE].height>>1 && dur & 1) { point = P_SpawnMobj(x, y, floorz, MT_EGGMOBILE_FIRE); - point->angle = actor->angle; + P_InitAngle(point, actor->angle); point->destscale = actor->scale; P_SetScale(point, point->destscale); P_SetTarget(&point->target, actor); @@ -3970,7 +3970,7 @@ bossjustdie: P_ReturnThrustX(mo, mo->angle - ANGLE_90, 32<angle - ANGLE_90, 32<angle = mo->angle; + P_InitAngle(mo2, mo->angle); P_InstaThrust(mo2, mo2->angle - ANGLE_90, 4*mo2->scale); P_SetObjectMomZ(mo2, 4*FRACUNIT, false); P_SetMobjState(mo2, S_BOSSEGLZ1); @@ -3979,7 +3979,7 @@ bossjustdie: P_ReturnThrustX(mo, mo->angle + ANGLE_90, 32<angle + ANGLE_90, 32<angle = mo->angle; + P_InitAngle(mo2, mo->angle); P_InstaThrust(mo2, mo2->angle + ANGLE_90, 4*mo2->scale); P_SetObjectMomZ(mo2, 4*FRACUNIT, false); P_SetMobjState(mo2, S_BOSSEGLZ2); @@ -3991,7 +3991,7 @@ bossjustdie: P_ReturnThrustX(mo, mo->angle - ANGLE_90, 32<angle - ANGLE_90, 32<angle = mo->angle; + P_InitAngle(mo2, mo->angle); P_InstaThrust(mo2, mo2->angle - ANGLE_90, 4*mo2->scale); P_SetObjectMomZ(mo2, 4*FRACUNIT, false); P_SetMobjState(mo2, S_BOSSTANK1); @@ -4000,7 +4000,7 @@ bossjustdie: P_ReturnThrustX(mo, mo->angle + ANGLE_90, 32<angle + ANGLE_90, 32<angle = mo->angle; + P_InitAngle(mo2, mo->angle); P_InstaThrust(mo2, mo2->angle + ANGLE_90, 4*mo2->scale); P_SetObjectMomZ(mo2, 4*FRACUNIT, false); P_SetMobjState(mo2, S_BOSSTANK2); @@ -4008,7 +4008,7 @@ bossjustdie: mo2 = P_SpawnMobjFromMobj(mo, 0, 0, mobjinfo[MT_EGGMOBILE2].height + (32<angle = mo->angle; + P_InitAngle(mo2, mo->angle); P_SetObjectMomZ(mo2, 4*FRACUNIT, false); mo2->momz += mo->momz; P_SetMobjState(mo2, S_BOSSSPIGOT); @@ -4017,7 +4017,7 @@ bossjustdie: case MT_EGGMOBILE3: { mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_BOSSJUNK); - mo2->angle = mo->angle; + P_InitAngle(mo2, mo->angle); P_SetMobjState(mo2, S_BOSSSEBH1); } break; @@ -4091,7 +4091,8 @@ bossjustdie: pole->tracer->flags |= MF_NOCLIPTHING; P_SetScale(pole, (pole->destscale = 2*FRACUNIT)); P_SetScale(pole->tracer, (pole->tracer->destscale = 2*FRACUNIT)); - pole->angle = pole->tracer->angle = mo->tracer->angle; + P_InitAngle(pole, mo->tracer->angle); + P_InitAngle(pole->tracer, mo->tracer->angle); pole->tracer->tracer->angle = pole->angle - ANGLE_90; pole->momx = P_ReturnThrustX(pole, pole->angle, speed); pole->momy = P_ReturnThrustY(pole, pole->angle, speed); @@ -6254,7 +6255,7 @@ void A_RockSpawn(mobj_t *actor) mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_FALLINGROCK); P_SetMobjState(mo, mobjinfo[type].spawnstate); - mo->angle = R_PointToAngle2(line->v2->x, line->v2->y, line->v1->x, line->v1->y); + P_InitAngle(mo, R_PointToAngle2(line->v2->x, line->v2->y, line->v1->x, line->v1->y)); P_InstaThrust(mo, mo->angle, dist + randomoomph); mo->momz = dist + randomoomph; @@ -8312,7 +8313,7 @@ void A_Boss3ShockThink(mobj_t *actor) snew->momx = (actor->momx + snext->momx) >> 1; snew->momy = (actor->momy + snext->momy) >> 1; snew->momz = (actor->momz + snext->momz) >> 1; // is this really needed? - snew->angle = (actor->angle + snext->angle) >> 1; + P_InitAngle(snew, (actor->angle + snext->angle) >> 1); P_SetTarget(&snew->target, actor->target); snew->fuse = actor->fuse; @@ -8468,7 +8469,7 @@ void A_SpawnObjectAbsolute(mobj_t *actor) mo = P_SpawnMobj(x<angle = actor->angle; + P_InitAngle(mo, actor->angle); if (actor->eflags & MFE_VERTICALFLIP) mo->flags2 |= MF2_OBJECTFLIP; @@ -8510,7 +8511,7 @@ void A_SpawnObjectRelative(mobj_t *actor) (actor->eflags & MFE_VERTICALFLIP) ? ((actor->z + actor->height - mobjinfo[type].height) - FixedMul(z<scale)) : (actor->z + FixedMul(z<scale)), type); // Spawn objects with an angle matching the spawner's, rather than spawning Eastwards - Monster Iestyn - mo->angle = actor->angle; + P_InitAngle(mo, actor->angle); if (actor->eflags & MFE_VERTICALFLIP) mo->flags2 |= MF2_OBJECTFLIP; @@ -9220,7 +9221,7 @@ void A_BossJetFume(mobj_t *actor) P_SetScale(filler, filler->destscale); if (actor->eflags & MFE_VERTICALFLIP) filler->flags2 |= MF2_OBJECTFLIP; - filler->angle = actor->angle - ANGLE_180; + P_InitAngle(filler, actor->angle - ANGLE_180); P_SetTarget(&actor->tracer, filler); }*/ @@ -10982,7 +10983,7 @@ void A_TrapShot(mobj_t *actor) S_StartSound(missile, missile->info->seesound); P_SetTarget(&missile->target, actor); - missile->angle = actor->angle; + P_InitAngle(missile, actor->angle); speed = FixedMul(missile->info->speed, missile->scale); @@ -11561,7 +11562,7 @@ void A_BrakLobShot(mobj_t *actor) S_StartSound(shot, shot->info->seesound); P_SetTarget(&shot->target, actor); // where it came from - shot->angle = actor->angle; + P_InitAngle(shot, actor->angle); // Horizontal axes first. First parameter is initial horizontal impulse, second is to correct its angle. shot->momx = FixedMul(FixedMul(v, FINECOSINE(theta >> ANGLETOFINESHIFT)), FINECOSINE(shot->angle >> ANGLETOFINESHIFT)); @@ -11628,7 +11629,7 @@ void A_NapalmScatter(mobj_t *actor) mo = P_SpawnMobj(actor->x, actor->y, actor->z, typeOfShot); P_SetTarget(&mo->target, actor->target); // Transfer target so Brak doesn't hit himself like an idiot - mo->angle = fa << ANGLETOFINESHIFT; + P_InitAngle(mo, fa << ANGLETOFINESHIFT); mo->momx = FixedMul(FINECOSINE(fa),vx); mo->momy = FixedMul(FINESINE(fa),vx); mo->momz = vy; @@ -11652,7 +11653,7 @@ void A_SpawnFreshCopy(mobj_t *actor) newObject = P_SpawnMobjFromMobj(actor, 0, 0, 0, actor->type); newObject->flags2 = actor->flags2 & MF2_AMBUSH; - newObject->angle = actor->angle; + P_InitAngle(newObject, actor->angle); newObject->color = actor->color; P_SetTarget(&newObject->target, actor->target); P_SetTarget(&newObject->tracer, actor->tracer); @@ -11686,7 +11687,7 @@ mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz } flicky = P_SpawnMobjFromMobj(actor, offsx, offsy, 0, flickytype); - flicky->angle = actor->angle; + P_InitAngle(flicky, actor->angle); if (flickytype == MT_SEED) flicky->z += P_MobjFlip(actor)*(actor->height - flicky->height)/2; @@ -11836,7 +11837,7 @@ void A_FlickyCenter(mobj_t *actor) else if (actor->flags & MF_SLIDEME) // aimless { actor->tracer->fuse = 0; // less than 2*TICRATE means move aimlessly. - actor->tracer->angle = P_RandomKey(180)*ANG2; + P_InitAngle(actor->tracer, P_RandomKey(180)*ANG2); } else //orbit actor->tracer->fuse = FRACUNIT; @@ -12532,7 +12533,7 @@ void A_ConnectToGround(mobj_t *actor) { work = P_SpawnMobjFromMobj(actor, 0, 0, workz, locvar1); if (work) - work->angle = ang; + P_InitAngle(work, ang); ang += ANGLE_90; workz += workh; } @@ -12578,7 +12579,7 @@ void A_SpawnParticleRelative(mobj_t *actor) (actor->eflags & MFE_VERTICALFLIP) ? ((actor->z + actor->height - mobjinfo[MT_PARTICLE].height) - FixedMul(z<scale)) : (actor->z + FixedMul(z<scale)), MT_PARTICLE); // Spawn objects with an angle matching the spawner's, rather than spawning Eastwards - Monster Iestyn - mo->angle = actor->angle; + P_InitAngle(mo, actor->angle); if (actor->eflags & MFE_VERTICALFLIP) mo->flags2 |= MF2_OBJECTFLIP; @@ -13325,7 +13326,7 @@ void A_Boss5MakeJunk(mobj_t *actor) broked->fuse = TICRATE; else broked->fuse = (((locvar2 & 1) ? 4 : 2)*TICRATE)/3; - broked->angle = ang; + P_InitAngle(broked, ang); P_InstaThrust(broked, ang, ((locvar2 & 2) ? 8 : 5)*actor->scale); P_SetObjectMomZ(broked, (((locvar2) ? 4 : 0) + P_RandomRange(2, 5))< 0) @@ -13404,7 +13405,7 @@ static void P_DustRing(mobjtype_t mobjtype, UINT32 div, fixed_t x, fixed_t y, fi mobjtype ); - dust->angle = ang*i + ANGLE_90; + P_InitAngle(dust, ang*i + ANGLE_90); P_SetScale(dust, FixedMul(initscale, scale)); dust->destscale = FixedMul(4*FRACUNIT + P_RandomFixed(), scale); dust->scalespeed = scale/24; @@ -13758,7 +13759,7 @@ static mobj_t *P_TrainSeg(mobj_t *src, fixed_t x, fixed_t y, fixed_t z, angle_t s->fuse = 16*TICRATE; s->sprite = spr; s->frame = frame|FF_PAPERSPRITE; - s->angle = ang; + P_InitAngle(s, ang); P_Thrust(s, src->angle, 7*FRACUNIT); return s; } @@ -14130,7 +14131,7 @@ void A_SaloonDoorSpawn(mobj_t *actor) // One door... if (!(door = P_SpawnMobjFromMobj(actor, c, s, 0, locvar1))) return; - door->angle = ang + ANGLE_180; + P_InitAngle(door, ang + ANGLE_180); door->extravalue1 = AngleFixed(door->angle); // Origin angle door->extravalue2 = 0; // Angular speed P_SetTarget(&door->tracer, actor); // Origin door @@ -14138,7 +14139,7 @@ void A_SaloonDoorSpawn(mobj_t *actor) // ...two door! if (!(door = P_SpawnMobjFromMobj(actor, -c, -s, 0, locvar1))) return; - door->angle = ang; + P_InitAngle(door, ang); door->extravalue1 = AngleFixed(door->angle); // Origin angle door->extravalue2 = 0; // Angular speed P_SetTarget(&door->tracer, actor); // Origin door @@ -14334,7 +14335,7 @@ void A_SpawnPterabytes(mobj_t *actor) c = FINECOSINE(fa); s = FINESINE(fa); waypoint = P_SpawnMobjFromMobj(actor, FixedMul(c, rad), FixedMul(s, rad), 0, MT_PTERABYTEWAYPOINT); - waypoint->angle = ang + ANGLE_90; + P_InitAngle(waypoint, ang + ANGLE_90); P_SetTarget(&waypoint->tracer, actor); ptera = P_SpawnMobjFromMobj(waypoint, 0, 0, 0, MT_PTERABYTE); ptera->angle = waypoint->angle; @@ -14514,7 +14515,7 @@ void A_DragonbomberSpawn(mobj_t *actor) segment = P_SpawnMobjFromMobj(mo, x, y, 0, MT_DRAGONTAIL); P_SetTarget(&segment->target, mo); P_SetTarget(&mo->tracer, segment); - segment->angle = mo->angle; + P_InitAngle(segment, mo->angle); mo = segment; } for (i = 0; i < 2; i++) // spawn wings diff --git a/src/p_inter.c b/src/p_inter.c index 582cdb0d0..56ef23578 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2749,7 +2749,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget mo->angle = FixedAngle((P_RandomKey(36)*10)<angle = mo->angle; + P_InitAngle(mo2, mo->angle); P_SetMobjState(mo2, S_BOSSSEBH2); if (++i == 2) // we've already removed 2 of these, let's stop now @@ -2852,7 +2852,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_SPIKE);\ P_SetMobjState(chunk, target->info->xdeathstate);\ chunk->health = 0;\ - chunk->angle = angtweak;\ + P_InitAngle(chunk, angtweak);\ P_UnsetThingPosition(chunk);\ chunk->flags = MF_NOCLIP;\ chunk->x += xmov;\ @@ -2874,7 +2874,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_SPIKE); P_SetMobjState(chunk, target->info->deathstate); chunk->health = 0; - chunk->angle = ang + ANGLE_180; + P_InitAngle(chunk, ang + ANGLE_180); P_UnsetThingPosition(chunk); chunk->flags = MF_NOCLIP; chunk->x -= xoffs; @@ -2920,7 +2920,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget chunk = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_WALLSPIKE);\ P_SetMobjState(chunk, target->info->xdeathstate);\ chunk->health = 0;\ - chunk->angle = target->angle;\ + P_InitAngle(chunk, target->angle);\ P_UnsetThingPosition(chunk);\ chunk->flags = MF_NOCLIP;\ chunk->x += xmov - forwardxoffs;\ @@ -2946,7 +2946,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget P_SetMobjState(chunk, target->info->deathstate); chunk->health = 0; - chunk->angle = target->angle; + P_InitAngle(chunk, target->angle); P_UnsetThingPosition(chunk); chunk->flags = MF_NOCLIP; chunk->x += forwardxoffs - xoffs; diff --git a/src/p_local.h b/src/p_local.h index ba8cbe166..ec7e65b71 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -415,6 +415,9 @@ 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); +void P_InitAngle(mobj_t *thing, angle_t newValue); +void P_InitPitch(mobj_t *thing, angle_t newValue); +void P_InitRoll(mobj_t *thing, angle_t newValue); void P_SlideMove(mobj_t *mo); void P_BounceMove(mobj_t *mo); boolean P_CheckSight(mobj_t *t1, mobj_t *t2); diff --git a/src/p_map.c b/src/p_map.c index 145f9bbe9..1f02123d5 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -108,6 +108,30 @@ boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z) return true; } +// +// P_InitAngle - Change an object's angle, including interp values. +// +void P_InitAngle(mobj_t *thing, angle_t newValue) +{ + thing->angle = thing->old_angle = newValue; +} + +// +// P_InitPitch - Change an object's pitch, including interp values. +// +void P_InitPitch(mobj_t *thing, angle_t newValue) +{ + thing->pitch = thing->old_pitch = newValue; +} + +// +// P_InitRoll - Change an object's roll, including interp values. +// +void P_InitRoll(mobj_t *thing, angle_t newValue) +{ + thing->roll = thing->old_roll = newValue; +} + // ========================================================================= // MOVEMENT ITERATOR FUNCTIONS // ========================================================================= diff --git a/src/p_mobj.c b/src/p_mobj.c index 90707eae5..57af599cf 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -903,6 +903,8 @@ void P_ResetInterpolationState(mobj_t *mobj) mobj->old_y = mobj->y; mobj->old_z = mobj->z; mobj->old_angle = mobj->angle; + mobj->old_pitch = mobj->pitch; + mobj->old_roll = mobj->roll; if (mobj->player) { @@ -6372,7 +6374,7 @@ void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 numb mobj->z -= mobj->height>>1; // change angle - mobj->angle = R_PointToAngle2(mobj->x, mobj->y, x, y); + P_InitAngle(mobj, R_PointToAngle2(mobj->x, mobj->y, x, y)); // change slope dist = P_AproxDistance(P_AproxDistance(x - mobj->x, y - mobj->y), z - mobj->z); @@ -7256,7 +7258,7 @@ static void P_FlameJetSceneryThink(mobj_t *mobj) flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME); P_SetMobjState(flame, S_FLAMEJETFLAME4); - flame->angle = mobj->angle; + P_InitAngle(flame, mobj->angle); if (mobj->flags2 & MF2_AMBUSH) // Wave up and down instead of side-to-side flame->momz = mobj->fuse << (FRACBITS - 2); @@ -10730,7 +10732,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_CRUSHSTACEAN: { mobj_t *bigmeatyclaw = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_CRUSHCLAW); - bigmeatyclaw->angle = mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270);; + P_InitAngle(bigmeatyclaw, mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270)); P_SetTarget(&mobj->tracer, bigmeatyclaw); P_SetTarget(&bigmeatyclaw->tracer, mobj); mobj->reactiontime >>= 1; @@ -10739,7 +10741,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_BANPYURA: { mobj_t *bigmeatyclaw = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_BANPSPRING); - bigmeatyclaw->angle = mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270);; + P_InitAngle(bigmeatyclaw, mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270)); P_SetTarget(&mobj->tracer, bigmeatyclaw); P_SetTarget(&bigmeatyclaw->tracer, mobj); mobj->reactiontime >>= 1; @@ -10861,7 +10863,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) break; case MT_MINECARTEND: P_SetTarget(&mobj->tracer, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_MINECARTENDSOLID)); - mobj->tracer->angle = mobj->angle + ANGLE_90; + P_InitAngle(mobj->tracer, mobj->angle + ANGLE_90); break; case MT_TORCHFLOWER: { @@ -11492,7 +11494,7 @@ void P_SpawnPlayer(INT32 playernum) mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER); (mobj->player = p)->mo = mobj; - mobj->angle = 0; + P_InitAngle(mobj, 0); // set color translations for player sprites mobj->color = p->skincolor; @@ -11560,6 +11562,12 @@ void P_AfterPlayerSpawn(INT32 playernum) player_t *p = &players[playernum]; mobj_t *mobj = p->mo; + // Update interpolation + mobj->old_x = mobj->x; + mobj->old_y = mobj->y; + mobj->old_z = mobj->z; + mobj->old_angle = mobj->angle; + P_SetPlayerAngle(p, mobj->angle); p->viewheight = 41*p->height/48; @@ -12345,7 +12353,7 @@ static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) spawnee->friction = mroll;\ spawnee->movefactor = mwidthset;\ spawnee->movecount = dist;\ - spawnee->angle = myaw;\ + P_InitAngle(spawnee, myaw);\ spawnee->flags |= (MF_NOGRAVITY|mflagsapply);\ spawnee->flags2 |= (mflags2apply|moreflags2);\ spawnee->eflags |= meflagsapply;\ @@ -12663,29 +12671,29 @@ static boolean P_SetupBooster(mapthing_t* mthing, mobj_t* mobj, boolean strong) statenum_t rollerstate = strong ? S_REDBOOSTERROLLER : S_YELLOWBOOSTERROLLER; mobj_t *seg = P_SpawnMobjFromMobj(mobj, 26*x1, 26*y1, 0, MT_BOOSTERSEG); - seg->angle = angle - ANGLE_90; + P_InitAngle(seg, angle - ANGLE_90); P_SetMobjState(seg, facestate); seg = P_SpawnMobjFromMobj(mobj, -26*x1, -26*y1, 0, MT_BOOSTERSEG); - seg->angle = angle + ANGLE_90; + P_InitAngle(seg, angle + ANGLE_90); P_SetMobjState(seg, facestate); seg = P_SpawnMobjFromMobj(mobj, 21*x2, 21*y2, 0, MT_BOOSTERSEG); - seg->angle = angle; + P_InitAngle(seg, angle); P_SetMobjState(seg, leftstate); seg = P_SpawnMobjFromMobj(mobj, -21*x2, -21*y2, 0, MT_BOOSTERSEG); - seg->angle = angle; + P_InitAngle(seg, angle); P_SetMobjState(seg, rightstate); seg = P_SpawnMobjFromMobj(mobj, 13*(x1 + x2), 13*(y1 + y2), 0, MT_BOOSTERROLLER); - seg->angle = angle; + P_InitAngle(seg, angle); P_SetMobjState(seg, rollerstate); seg = P_SpawnMobjFromMobj(mobj, 13*(x1 - x2), 13*(y1 - y2), 0, MT_BOOSTERROLLER); - seg->angle = angle; + P_InitAngle(seg, angle); P_SetMobjState(seg, rollerstate); seg = P_SpawnMobjFromMobj(mobj, -13*(x1 + x2), -13*(y1 + y2), 0, MT_BOOSTERROLLER); - seg->angle = angle; + P_InitAngle(seg, angle); P_SetMobjState(seg, rollerstate); seg = P_SpawnMobjFromMobj(mobj, -13*(x1 - x2), -13*(y1 - y2), 0, MT_BOOSTERROLLER); - seg->angle = angle; + P_InitAngle(seg, angle); P_SetMobjState(seg, rollerstate); return true; @@ -12901,9 +12909,9 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean case MT_THZTREE: { // Spawn the branches angle_t mobjangle = FixedAngle((mthing->angle % 113) << FRACBITS); - P_SpawnMobjFromMobj(mobj, FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_22h; - P_SpawnMobjFromMobj(mobj, 0, FRACUNIT, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_157h; - P_SpawnMobjFromMobj(mobj, -FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_270; + P_InitAngle(P_SpawnMobjFromMobj(mobj, FRACUNIT, 0, 0, MT_THZTREEBRANCH), mobjangle + ANGLE_22h); + P_InitAngle(P_SpawnMobjFromMobj(mobj, 0, FRACUNIT, 0, MT_THZTREEBRANCH), mobjangle + ANGLE_157h); + P_InitAngle(P_SpawnMobjFromMobj(mobj, -FRACUNIT, 0, 0, MT_THZTREEBRANCH), mobjangle + ANGLE_270); } break; case MT_TUTORIALPLANT: @@ -12929,10 +12937,10 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean case MT_CEZPOLE2: { // Spawn the banner angle_t mobjangle = FixedAngle(mthing->angle << FRACBITS); - P_SpawnMobjFromMobj(mobj, + P_InitAngle(P_SpawnMobjFromMobj(mobj, P_ReturnThrustX(mobj, mobjangle, 4 << FRACBITS), P_ReturnThrustY(mobj, mobjangle, 4 << FRACBITS), - 0, ((mobj->type == MT_CEZPOLE1) ? MT_CEZBANNER1 : MT_CEZBANNER2))->angle = mobjangle + ANGLE_90; + 0, ((mobj->type == MT_CEZPOLE1) ? MT_CEZBANNER1 : MT_CEZBANNER2)), mobjangle + ANGLE_90); } break; case MT_HHZTREE_TOP: @@ -12941,7 +12949,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean mobj_t* leaf; #define doleaf(x, y) \ leaf = P_SpawnMobjFromMobj(mobj, x, y, 0, MT_HHZTREE_PART);\ - leaf->angle = mobjangle;\ + P_InitAngle(leaf, mobjangle);\ P_SetMobjState(leaf, leaf->info->seestate);\ mobjangle += ANGLE_90 doleaf(FRACUNIT, 0); @@ -12982,7 +12990,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean fixed_t xoffs = FINECOSINE(fa); fixed_t yoffs = FINESINE(fa); mobj_t* leaf = P_SpawnMobjFromMobj(mobj, xoffs, yoffs, 0, MT_BIGFERNLEAF); - leaf->angle = angle; + P_InitAngle(leaf, angle); angle += ANGLE_45; } break; @@ -13108,7 +13116,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean mobj->x - P_ReturnThrustX(mobj, mobjangle, baseradius), mobj->y - P_ReturnThrustY(mobj, mobjangle, baseradius), mobj->z, MT_WALLSPIKEBASE); - base->angle = mobjangle + ANGLE_90; + P_InitAngle(base, mobjangle + ANGLE_90); base->destscale = mobj->destscale; P_SetScale(base, mobj->scale); P_SetTarget(&base->target, mobj); @@ -13236,10 +13244,12 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, return mobj; if (doangle) - mobj->angle = FixedAngle(mthing->angle << FRACBITS); + { + P_InitAngle(mobj, FixedAngle(mthing->angle << FRACBITS)); + } - mobj->pitch = FixedAngle(mthing->pitch << FRACBITS); - mobj->roll = FixedAngle(mthing->roll << FRACBITS); + P_InitPitch(mobj, FixedAngle(mthing->pitch << FRACBITS)); + P_InitRoll(mobj, FixedAngle(mthing->roll << FRACBITS)); mthing->mobj = mobj; @@ -13675,7 +13685,7 @@ mobj_t *P_SpawnXYZMissile(mobj_t *source, mobj_t *dest, mobjtype_t type, P_SetTarget(&th->target, source); // where it came from an = R_PointToAngle2(x, y, dest->x, dest->y); - th->angle = an; + P_InitAngle(th, an); an >>= ANGLETOFINESHIFT; th->momx = FixedMul(speed, FINECOSINE(an)); th->momy = FixedMul(speed, FINESINE(an)); @@ -13737,7 +13747,7 @@ mobj_t *P_SpawnAlteredDirectionMissile(mobj_t *source, mobjtype_t type, fixed_t P_SetTarget(&th->target, source->target); // where it came from an = R_PointToAngle2(0, 0, source->momx, source->momy) + (ANG1*shiftingAngle); - th->angle = an; + P_InitAngle(th, an); an >>= ANGLETOFINESHIFT; th->momx = FixedMul(speed, FINECOSINE(an)); th->momy = FixedMul(speed, FINESINE(an)); @@ -13802,7 +13812,7 @@ mobj_t *P_SpawnPointMissile(mobj_t *source, fixed_t xa, fixed_t ya, fixed_t za, P_SetTarget(&th->target, source); // where it came from an = R_PointToAngle2(x, y, xa, ya); - th->angle = an; + P_InitAngle(th, an); an >>= ANGLETOFINESHIFT; th->momx = FixedMul(speed, FINECOSINE(an)); th->momy = FixedMul(speed, FINESINE(an)); @@ -13881,7 +13891,7 @@ mobj_t *P_SpawnMissile(mobj_t *source, mobj_t *dest, mobjtype_t type) else an = R_PointToAngle2(source->x, source->y, dest->x, dest->y); - th->angle = an; + P_InitAngle(th, an); an >>= ANGLETOFINESHIFT; th->momx = FixedMul(speed, FINECOSINE(an)); th->momy = FixedMul(speed, FINESINE(an)); @@ -13971,7 +13981,7 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 allowai if (source->player && source->player->charability == CA_FLY) speed = FixedMul(speed, 3*FRACUNIT/2); - th->angle = an; + P_InitAngle(th, an); th->momx = FixedMul(speed, FINECOSINE(an>>ANGLETOFINESHIFT)); th->momy = FixedMul(speed, FINESINE(an>>ANGLETOFINESHIFT)); diff --git a/src/p_mobj.h b/src/p_mobj.h index 9975075a1..371dc49dc 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -287,7 +287,7 @@ typedef struct mobj_s // More drawing info: to determine current sprite. angle_t angle, pitch, roll; // orientation - angle_t old_angle; + angle_t old_angle, old_pitch, old_roll; // orientation interpolation angle_t rollangle; spritenum_t sprite; // used to find patch_t and flip value UINT32 frame; // frame number, plus bits see p_pspr.h diff --git a/src/p_saveg.c b/src/p_saveg.c index 99ec58bb9..46b509d19 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2758,19 +2758,19 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) mobj->info = &mobjinfo[mobj->type]; if (diff & MD_POS) { - mobj->x = READFIXED(save_p); - mobj->y = READFIXED(save_p); - mobj->angle = READANGLE(save_p); - mobj->pitch = READANGLE(save_p); - mobj->roll = READANGLE(save_p); + mobj->x = mobj->old_x = READFIXED(save_p); + mobj->y = mobj->old_y = READFIXED(save_p); + mobj->angle = mobj->old_angle = READANGLE(save_p); + mobj->pitch = mobj->old_pitch = READANGLE(save_p); + mobj->roll = mobj->old_roll = READANGLE(save_p); } else { - mobj->x = mobj->spawnpoint->x << FRACBITS; - mobj->y = mobj->spawnpoint->y << FRACBITS; - mobj->angle = FixedAngle(mobj->spawnpoint->angle*FRACUNIT); - mobj->pitch = FixedAngle(mobj->spawnpoint->pitch*FRACUNIT); - mobj->roll = FixedAngle(mobj->spawnpoint->roll*FRACUNIT); + mobj->x = mobj->old_x = mobj->spawnpoint->x << FRACBITS; + mobj->y = mobj->old_y = mobj->spawnpoint->y << FRACBITS; + mobj->angle = mobj->old_angle = FixedAngle(mobj->spawnpoint->angle*FRACUNIT); + mobj->pitch = mobj->old_pitch = FixedAngle(mobj->spawnpoint->pitch*FRACUNIT); + mobj->roll = mobj->old_roll = FixedAngle(mobj->spawnpoint->roll*FRACUNIT); } if (diff & MD_MOM) { diff --git a/src/p_spec.c b/src/p_spec.c index 6147a8392..34dcd917d 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3755,7 +3755,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) if (mobj) { if (line->flags & ML_EFFECT1) - mobj->angle = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y); + P_InitAngle(mobj, R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y)); CONS_Debug(DBG_GAMELOGIC, "Linedef Type %d - Spawn Object: %d spawned at (%d, %d, %d)\n", line->special, mobj->type, mobj->x>>FRACBITS, mobj->y>>FRACBITS, mobj->z>>FRACBITS); //TODO: Convert mobj->type to a string somehow. } else diff --git a/src/p_telept.c b/src/p_telept.c index cbbd0ff6b..cfd7be1e2 100644 --- a/src/p_telept.c +++ b/src/p_telept.c @@ -101,7 +101,7 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, P_FlashPal(thing->player, PAL_MIXUP, 10); } - thing->angle = angle; + P_InitAngle(thing, angle); thing->momx = thing->momy = thing->momz = 0; @@ -174,7 +174,7 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle P_FlashPal(thing->player, PAL_MIXUP, 10); } - thing->angle = angle; + P_InitAngle(thing, angle); return true; } diff --git a/src/p_user.c b/src/p_user.c index 8e8194da0..f047499d0 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -393,7 +393,7 @@ 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); - flag->angle = angle; + P_InitAngle(flag, angle); angle += FixedAngle(120*FRACUNIT); P_SetTarget(&flag->target, player->mo); diff --git a/src/r_fps.c b/src/r_fps.c index 863e9613a..708add820 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -211,6 +211,9 @@ void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out) { out->angle = R_LerpAngle(mobj->old_angle, mobj->angle, frac); } + + out->pitch = R_LerpAngle(mobj->old_pitch, mobj->pitch, frac); + out->roll = R_LerpAngle(mobj->old_roll, mobj->roll, frac); } void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjstate_t *out) @@ -219,6 +222,8 @@ void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjst out->y = R_LerpFixed(mobj->old_y, mobj->y, frac); out->z = R_LerpFixed(mobj->old_z, mobj->z, frac); out->angle = R_LerpAngle(mobj->old_angle, mobj->angle, frac); + out->pitch = 0; + out->roll = 0; } static void AddInterpolator(levelinterpolator_t* interpolator) diff --git a/src/r_fps.h b/src/r_fps.h index aa6213ae3..1eb53b346 100644 --- a/src/r_fps.h +++ b/src/r_fps.h @@ -49,6 +49,8 @@ typedef struct { fixed_t y; fixed_t z; angle_t angle; + angle_t pitch; + angle_t roll; } interpmobjstate_t; // Level interpolators