mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-02-21 11:21:11 +00:00
Merge branch 'delag_maces' into 'master'
Delag Maces See merge request STJr/SRB2Internal!141
This commit is contained in:
commit
5f79a2f1df
10 changed files with 363 additions and 210 deletions
|
@ -6554,7 +6554,6 @@ static const char *const MOBJFLAG2_LIST[] = {
|
|||
"AMBUSH", // Alternate behaviour typically set by MTF_AMBUSH
|
||||
"LINKDRAW", // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position)
|
||||
"SHIELD", // Thinker calls P_AddShield/P_ShieldLook (must be partnered with MF_SCENERY to use)
|
||||
"MACEROTATE", // Thinker calls P_MaceRotate around tracer
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
16
src/info.c
16
src/info.c
|
@ -9046,7 +9046,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
10000, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
|
||||
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
@ -9073,7 +9073,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
10000, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
|
||||
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
@ -9100,7 +9100,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
10000, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
|
||||
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
@ -9127,7 +9127,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
10000, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
|
||||
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
@ -9154,7 +9154,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
|
||||
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
@ -9181,7 +9181,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
200, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
|
||||
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
@ -9208,7 +9208,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
200, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
|
||||
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
@ -9230,7 +9230,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_None, // deathsound
|
||||
24*FRACUNIT, // speed
|
||||
24*FRACUNIT, // radius
|
||||
48*FRACUNIT, // height
|
||||
32*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
1, // damage
|
||||
|
|
|
@ -768,6 +768,19 @@ static int lib_pCanRunOnWater(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int lib_pMaceRotate(lua_State *L)
|
||||
{
|
||||
mobj_t *center = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
INT32 baserot = luaL_checkinteger(L, 2);
|
||||
INT32 baseprevrot = luaL_checkinteger(L, 3);
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!center)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
P_MaceRotate(center, baserot, baseprevrot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// P_USER
|
||||
////////////
|
||||
|
||||
|
@ -2517,6 +2530,7 @@ static luaL_Reg lib[] = {
|
|||
{"P_CheckDeathPitCollide",lib_pCheckDeathPitCollide},
|
||||
{"P_CheckSolidLava",lib_pCheckSolidLava},
|
||||
{"P_CanRunOnWater",lib_pCanRunOnWater},
|
||||
{"P_MaceRotate",lib_pMaceRotate},
|
||||
|
||||
// p_user
|
||||
{"P_GetPlayerHeight",lib_pGetPlayerHeight},
|
||||
|
|
|
@ -530,10 +530,22 @@ static int mobj_set(lua_State *L)
|
|||
case mobj_bprev:
|
||||
return UNIMPLEMENTED;
|
||||
case mobj_hnext:
|
||||
mo->hnext = luaL_checkudata(L, 3, META_MOBJ);
|
||||
if (lua_isnil(L, 3))
|
||||
P_SetTarget(&mo->hnext, NULL);
|
||||
else
|
||||
{
|
||||
mobj_t *hnext = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
|
||||
P_SetTarget(&mo->hnext, hnext);
|
||||
}
|
||||
break;
|
||||
case mobj_hprev:
|
||||
mo->hprev = luaL_checkudata(L, 3, META_MOBJ);
|
||||
if (lua_isnil(L, 3))
|
||||
P_SetTarget(&mo->hprev, NULL);
|
||||
else
|
||||
{
|
||||
mobj_t *hprev = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
|
||||
P_SetTarget(&mo->hprev, hprev);
|
||||
}
|
||||
break;
|
||||
case mobj_type: // yeah sure, we'll let you change the mobj's type.
|
||||
{
|
||||
|
|
|
@ -4910,6 +4910,7 @@ void A_SlingAppear(mobj_t *actor)
|
|||
boolean firsttime = true;
|
||||
UINT8 mlength = 4;
|
||||
mobj_t *spawnee;
|
||||
mobj_t *hprev = actor;
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_SlingAppear", actor))
|
||||
return;
|
||||
|
@ -4920,7 +4921,6 @@ void A_SlingAppear(mobj_t *actor)
|
|||
P_SetThingPosition(actor);
|
||||
actor->lastlook = 128;
|
||||
actor->movecount = actor->lastlook;
|
||||
actor->health = actor->angle>>ANGLETOFINESHIFT;
|
||||
actor->threshold = 0;
|
||||
actor->movefactor = actor->threshold;
|
||||
actor->friction = 128;
|
||||
|
@ -4929,10 +4929,13 @@ void A_SlingAppear(mobj_t *actor)
|
|||
{
|
||||
spawnee = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SMALLMACECHAIN);
|
||||
|
||||
P_SetTarget(&spawnee->target, actor);
|
||||
P_SetTarget(&spawnee->tracer, actor);
|
||||
P_SetTarget(&spawnee->hprev, hprev);
|
||||
P_SetTarget(&hprev->hnext, spawnee);
|
||||
hprev = spawnee;
|
||||
|
||||
spawnee->threshold = 0;
|
||||
spawnee->reactiontime = mlength;
|
||||
spawnee->flags |= MF_NOCLIP|MF_NOCLIPHEIGHT;
|
||||
spawnee->movecount = mlength;
|
||||
|
||||
if (firsttime)
|
||||
{
|
||||
|
|
|
@ -1505,10 +1505,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
if (player->powers[pw_flashing])
|
||||
return;
|
||||
|
||||
if (special->movefactor && special->tracer && (angle_t)special->tracer->health != ANGLE_90 && (angle_t)special->tracer->health != ANGLE_270)
|
||||
if (special->movefactor && special->tracer && special->tracer->angle != ANGLE_90 && special->tracer->angle != ANGLE_270)
|
||||
{ // I don't expect you to understand this, Mr Bond...
|
||||
angle_t ang = R_PointToAngle2(special->x, special->y, toucher->x, toucher->y) - special->tracer->threshold;
|
||||
if ((special->movefactor > 0) == ((angle_t)special->tracer->health > ANGLE_90 && (angle_t)special->tracer->health < ANGLE_270))
|
||||
angle_t ang = R_PointToAngle2(special->x, special->y, toucher->x, toucher->y) - special->tracer->angle;
|
||||
if ((special->movefactor > 0) == (special->tracer->angle > ANGLE_90 && special->tracer->angle < ANGLE_270))
|
||||
ang += ANGLE_180;
|
||||
if (ang < ANGLE_180)
|
||||
return; // I expect you to die.
|
||||
|
|
|
@ -280,6 +280,8 @@ mobj_t *P_GetClosestAxis(mobj_t *source);
|
|||
|
||||
boolean P_CanRunOnWater(player_t *player, ffloor_t *rover);
|
||||
|
||||
void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot);
|
||||
|
||||
void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration);
|
||||
#define PAL_WHITE 1
|
||||
#define PAL_MIXUP 2
|
||||
|
|
493
src/p_mobj.c
493
src/p_mobj.c
|
@ -6176,124 +6176,217 @@ static void P_NightsItemChase(mobj_t *thing)
|
|||
|
||||
//
|
||||
// P_MaceRotate
|
||||
// Spins an object around its target, or, swings it from side to side.
|
||||
// Spins a hnext-chain of objects around its centerpoint, side to side or periodically.
|
||||
//
|
||||
static void P_MaceRotate(mobj_t *mobj)
|
||||
void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot)
|
||||
{
|
||||
TVector v;
|
||||
TVector unit_lengthways, unit_sideways, pos_lengthways, pos_sideways;
|
||||
TVector *res;
|
||||
fixed_t radius, dist;
|
||||
fixed_t radius, dist, zstore;
|
||||
angle_t fa;
|
||||
INT32 prevswing;
|
||||
boolean donetwice = false;
|
||||
boolean dosound = false;
|
||||
mobj_t *mobj = center->hnext, *hnext = NULL;
|
||||
|
||||
// Tracer was removed.
|
||||
if (!mobj->health)
|
||||
return;
|
||||
else if (!mobj->tracer)
|
||||
INT32 rot = (baserot &= FINEMASK);
|
||||
INT32 prevrot = (baseprevrot &= FINEMASK);
|
||||
|
||||
INT32 lastthreshold = FINEMASK; // needs to never be equal at start of loop
|
||||
fixed_t lastfriction = INT32_MIN; // ditto; almost certainly never, but...
|
||||
|
||||
dist = pos_sideways[0] = pos_sideways[1] = pos_sideways[2] = pos_sideways[3] = unit_sideways[3] = pos_lengthways[0] = pos_lengthways[1] = pos_lengthways[2] = pos_lengthways[3] = 0;
|
||||
|
||||
while (mobj)
|
||||
{
|
||||
P_KillMobj(mobj, NULL, NULL, 0);
|
||||
return;
|
||||
}
|
||||
if (!mobj->health)
|
||||
{
|
||||
mobj = mobj->hnext;
|
||||
continue;
|
||||
}
|
||||
|
||||
mobj->momx = mobj->momy = mobj->momz = 0;
|
||||
mobj->momx = mobj->momy = mobj->momz = 0;
|
||||
|
||||
prevswing = mobj->threshold;
|
||||
mobj->threshold += mobj->tracer->lastlook;
|
||||
mobj->threshold &= FINEMASK;
|
||||
if (mobj->threshold != lastthreshold
|
||||
|| mobj->friction != lastfriction)
|
||||
{
|
||||
rot = (baserot + mobj->threshold) & FINEMASK;
|
||||
prevrot = (baseprevrot + mobj->threshold) & FINEMASK;
|
||||
|
||||
dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed);
|
||||
pos_lengthways[0] = pos_lengthways[1] = pos_lengthways[2] = pos_lengthways[3] = 0;
|
||||
|
||||
// Radius of the link's rotation.
|
||||
radius = FixedMul(dist * mobj->movecount, mobj->tracer->scale) + mobj->tracer->extravalue1;
|
||||
dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed);
|
||||
dist = ((center->scale == FRACUNIT) ? dist : FixedMul(dist, center->scale));
|
||||
|
||||
maceretry:
|
||||
fa = (FixedAngle(center->movefactor*FRACUNIT) >> ANGLETOFINESHIFT);
|
||||
radius = FixedMul(dist, FINECOSINE(fa));
|
||||
unit_lengthways[1] = -FixedMul(dist, FINESINE(fa));
|
||||
unit_lengthways[3] = FRACUNIT;
|
||||
|
||||
fa = (FixedAngle(mobj->tracer->movefactor*FRACUNIT) >> ANGLETOFINESHIFT);
|
||||
radius = FixedMul(FINECOSINE(fa), radius);
|
||||
v[1] = -FixedMul(FINESINE(fa), radius)
|
||||
+ FixedMul(dist * mobj->movefactor, mobj->tracer->scale);
|
||||
v[3] = FRACUNIT;
|
||||
// Swinging Chain.
|
||||
if (center->flags2 & MF2_STRONGBOX)
|
||||
{
|
||||
fixed_t swingmag = FixedMul(FINECOSINE(rot), center->lastlook << FRACBITS);
|
||||
fixed_t prevswingmag = FINECOSINE(prevrot);
|
||||
|
||||
// Swinging Chain.
|
||||
if (mobj->tracer->flags2 & MF2_STRONGBOX)
|
||||
{
|
||||
fixed_t swingmagnitude = FixedMul(FINECOSINE(mobj->threshold), mobj->tracer->lastlook << FRACBITS);
|
||||
prevswing = FINECOSINE(prevswing);
|
||||
if ((prevswingmag > 0) != (swingmag > 0)) // just passed its lowest point
|
||||
dosound = true;
|
||||
|
||||
if (!donetwice
|
||||
&& (mobj->flags2 & MF2_BOSSNOTRAP) // at the end of the chain and can play a sound
|
||||
&& ((prevswing > 0) != (swingmagnitude > 0))) // just passed its lowest point
|
||||
fa = ((FixedAngle(swingmag) >> ANGLETOFINESHIFT) + mobj->friction) & FINEMASK;
|
||||
|
||||
unit_lengthways[0] = FixedMul(FINESINE(fa), -radius);
|
||||
unit_lengthways[2] = FixedMul(FINECOSINE(fa), -radius);
|
||||
}
|
||||
// Rotating Chain.
|
||||
else
|
||||
{
|
||||
angle_t prevfa = (prevrot + mobj->friction) & FINEMASK;
|
||||
fa = (rot + mobj->friction) & FINEMASK;
|
||||
|
||||
if (!(prevfa > (FINEMASK/2)) && (fa > (FINEMASK/2))) // completed a full swing
|
||||
dosound = true;
|
||||
|
||||
unit_lengthways[0] = FixedMul(FINECOSINE(fa), radius);
|
||||
unit_lengthways[2] = FixedMul(FINESINE(fa), radius);
|
||||
}
|
||||
|
||||
// Calculate the angle matrixes for the link.
|
||||
res = VectorMatrixMultiply(unit_lengthways, *RotateXMatrix(center->threshold << ANGLETOFINESHIFT));
|
||||
M_Memcpy(&unit_lengthways, res, sizeof(unit_lengthways));
|
||||
res = VectorMatrixMultiply(unit_lengthways, *RotateZMatrix(center->angle));
|
||||
M_Memcpy(&unit_lengthways, res, sizeof(unit_lengthways));
|
||||
|
||||
lastthreshold = mobj->threshold;
|
||||
lastfriction = mobj->friction;
|
||||
}
|
||||
|
||||
if (dosound && (mobj->flags2 & MF2_BOSSNOTRAP))
|
||||
{
|
||||
S_StartSound(mobj, mobj->info->activesound);
|
||||
dosound = false;
|
||||
}
|
||||
|
||||
fa = ((FixedAngle(swingmagnitude) >> ANGLETOFINESHIFT) + mobj->friction) & FINEMASK;
|
||||
if (pos_sideways[3] != mobj->movefactor)
|
||||
{
|
||||
if (!unit_sideways[3])
|
||||
{
|
||||
unit_sideways[1] = dist;
|
||||
unit_sideways[0] = unit_sideways[2] = 0;
|
||||
unit_sideways[3] = FRACUNIT;
|
||||
|
||||
v[0] = FixedMul(FINESINE(fa), -radius);
|
||||
v[2] = FixedMul(FINECOSINE(fa), -radius);
|
||||
res = VectorMatrixMultiply(unit_sideways, *RotateXMatrix(center->threshold << ANGLETOFINESHIFT));
|
||||
M_Memcpy(&unit_sideways, res, sizeof(unit_sideways));
|
||||
res = VectorMatrixMultiply(unit_sideways, *RotateZMatrix(center->angle));
|
||||
M_Memcpy(&unit_sideways, res, sizeof(unit_sideways));
|
||||
}
|
||||
|
||||
if (pos_sideways[3] > mobj->movefactor)
|
||||
{
|
||||
do
|
||||
{
|
||||
pos_sideways[0] -= unit_sideways[0];
|
||||
pos_sideways[1] -= unit_sideways[1];
|
||||
pos_sideways[2] -= unit_sideways[2];
|
||||
}
|
||||
while ((--pos_sideways[3]) != mobj->movefactor);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
pos_sideways[0] += unit_sideways[0];
|
||||
pos_sideways[1] += unit_sideways[1];
|
||||
pos_sideways[2] += unit_sideways[2];
|
||||
}
|
||||
while ((++pos_sideways[3]) != mobj->movefactor);
|
||||
}
|
||||
}
|
||||
|
||||
hnext = mobj->hnext; // just in case the mobj is removed
|
||||
|
||||
if (pos_lengthways[3] > mobj->movecount)
|
||||
{
|
||||
do
|
||||
{
|
||||
pos_lengthways[0] -= unit_lengthways[0];
|
||||
pos_lengthways[1] -= unit_lengthways[1];
|
||||
pos_lengthways[2] -= unit_lengthways[2];
|
||||
}
|
||||
while ((--pos_lengthways[3]) != mobj->movecount);
|
||||
}
|
||||
else if (pos_lengthways[3] < mobj->movecount)
|
||||
{
|
||||
do
|
||||
{
|
||||
pos_lengthways[0] += unit_lengthways[0];
|
||||
pos_lengthways[1] += unit_lengthways[1];
|
||||
pos_lengthways[2] += unit_lengthways[2];
|
||||
}
|
||||
while ((++pos_lengthways[3]) != mobj->movecount);
|
||||
}
|
||||
|
||||
P_UnsetThingPosition(mobj);
|
||||
|
||||
mobj->x = center->x;
|
||||
mobj->y = center->y;
|
||||
mobj->z = center->z;
|
||||
|
||||
// Add on the appropriate distances to the center's co-ordinates.
|
||||
if (pos_lengthways[3])
|
||||
{
|
||||
mobj->x += pos_lengthways[0];
|
||||
mobj->y += pos_lengthways[1];
|
||||
zstore = pos_lengthways[2] + pos_sideways[2];
|
||||
}
|
||||
else
|
||||
zstore = pos_sideways[2];
|
||||
|
||||
mobj->x += pos_sideways[0];
|
||||
mobj->y += pos_sideways[1];
|
||||
|
||||
// Cut the height to align the link with the axis.
|
||||
if (mobj->type == MT_SMALLMACECHAIN || mobj->type == MT_BIGMACECHAIN)
|
||||
zstore -= P_MobjFlip(mobj)*mobj->height/4;
|
||||
else
|
||||
zstore -= P_MobjFlip(mobj)*mobj->height/2;
|
||||
|
||||
mobj->z += zstore;
|
||||
|
||||
#if 0 // toaster's testing flashie!
|
||||
if (!(mobj->movecount & 1) && !(leveltime & TICRATE)) // I had a brainfart and the flashing isn't exactly what I expected it to be, but it's actually much more useful.
|
||||
mobj->flags2 ^= MF2_DONTDRAW;
|
||||
#endif
|
||||
|
||||
P_SetThingPosition(mobj);
|
||||
|
||||
#if 0 // toaster's height-clipping dealie!
|
||||
if (!pos_lengthways[3] || P_MobjWasRemoved(mobj) || (mobj->flags & MF_NOCLIPHEIGHT))
|
||||
goto cont;
|
||||
|
||||
if ((fa = ((center->threshold & (FINEMASK/2)) << ANGLETOFINESHIFT)) > ANGLE_45 && fa < ANGLE_135) // only move towards center when the motion is towards/away from the ground, rather than alongside it
|
||||
goto cont;
|
||||
|
||||
if (mobj->subsector->sector->ffloors)
|
||||
P_AdjustMobjFloorZ_FFloors(mobj, mobj->subsector->sector, 2);
|
||||
|
||||
if (mobj->floorz > mobj->z)
|
||||
zstore = (mobj->floorz - zstore);
|
||||
else if (mobj->ceilingz < mobj->z)
|
||||
zstore = (mobj->ceilingz - mobj->height - zstore);
|
||||
else
|
||||
goto cont;
|
||||
|
||||
zstore = FixedDiv(zstore, dist); // Still needs work... scaling factor is wrong!
|
||||
|
||||
P_UnsetThingPosition(mobj);
|
||||
|
||||
mobj->x -= FixedMul(unit_lengthways[0], zstore);
|
||||
mobj->y -= FixedMul(unit_lengthways[1], zstore);
|
||||
|
||||
P_SetThingPosition(mobj);
|
||||
|
||||
cont:
|
||||
#endif
|
||||
mobj = hnext;
|
||||
}
|
||||
// Rotating Chain.
|
||||
else
|
||||
{
|
||||
prevswing = (prevswing + mobj->friction) & FINEMASK;
|
||||
fa = (mobj->threshold + mobj->friction) & FINEMASK;
|
||||
|
||||
if (!donetwice
|
||||
&& (mobj->flags2 & MF2_BOSSNOTRAP) // at the end of the chain and can play a sound
|
||||
&& (!(prevswing > (FINEMASK/2)) && (fa > (FINEMASK/2)))) // completed a full swing
|
||||
S_StartSound(mobj, mobj->info->activesound);
|
||||
|
||||
v[0] = FixedMul(FINECOSINE(fa), radius);
|
||||
v[2] = FixedMul(FINESINE(fa), radius);
|
||||
}
|
||||
|
||||
// Calculate the angle matrixes for the link.
|
||||
res = VectorMatrixMultiply(v, *RotateXMatrix(mobj->tracer->threshold << ANGLETOFINESHIFT));
|
||||
M_Memcpy(&v, res, sizeof(v));
|
||||
res = VectorMatrixMultiply(v, *RotateZMatrix(mobj->tracer->health << ANGLETOFINESHIFT));
|
||||
M_Memcpy(&v, res, sizeof(v));
|
||||
|
||||
// Cut the height to align the link with the axis.
|
||||
if (mobj->type == MT_SMALLMACECHAIN || mobj->type == MT_BIGMACECHAIN)
|
||||
v[2] -= P_MobjFlip(mobj)*mobj->height/4;
|
||||
else
|
||||
v[2] -= P_MobjFlip(mobj)*mobj->height/2;
|
||||
|
||||
P_UnsetThingPosition(mobj);
|
||||
|
||||
// Add on the appropriate distances to the center's co-ordinates.
|
||||
mobj->x = mobj->tracer->x + v[0];
|
||||
mobj->y = mobj->tracer->y + v[1];
|
||||
mobj->z = mobj->tracer->z + v[2];
|
||||
|
||||
P_SetThingPosition(mobj);
|
||||
|
||||
if (donetwice || P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
|
||||
if (mobj->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT))
|
||||
return;
|
||||
|
||||
if ((fa = ((mobj->tracer->threshold & (FINEMASK/2)) << ANGLETOFINESHIFT)) > ANGLE_45 && fa < ANGLE_135) // only move towards center when the motion is towards/away from the ground, rather than alongside it
|
||||
return;
|
||||
|
||||
if (mobj->subsector->sector->ffloors)
|
||||
P_AdjustMobjFloorZ_FFloors(mobj, mobj->subsector->sector, 2);
|
||||
|
||||
// Variable reuse
|
||||
if (mobj->floorz > mobj->z)
|
||||
dist = (mobj->floorz - mobj->tracer->z);
|
||||
else if (mobj->ceilingz < mobj->z)
|
||||
dist = (mobj->ceilingz - mobj->tracer->z);
|
||||
else
|
||||
return;
|
||||
|
||||
if ((dist = FixedDiv(dist, v[2])) > FRACUNIT)
|
||||
return;
|
||||
|
||||
radius = FixedMul(radius, dist);
|
||||
donetwice = true;
|
||||
dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed);
|
||||
goto maceretry;
|
||||
}
|
||||
|
||||
static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield)
|
||||
|
@ -6664,13 +6757,6 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
}
|
||||
}
|
||||
|
||||
if (mobj->flags2 & MF2_MACEROTATE)
|
||||
{
|
||||
P_MaceRotate(mobj);
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
}
|
||||
|
||||
// Special thinker for scenery objects
|
||||
if (mobj->flags & MF_SCENERY)
|
||||
{
|
||||
|
@ -6687,6 +6773,18 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
|
||||
switch (mobj->type)
|
||||
{
|
||||
case MT_MACEPOINT:
|
||||
case MT_CHAINMACEPOINT:
|
||||
case MT_SPRINGBALLPOINT:
|
||||
case MT_CHAINPOINT:
|
||||
case MT_FIREBARPOINT:
|
||||
case MT_CUSTOMMACEPOINT:
|
||||
case MT_HIDDEN_SLING:
|
||||
// The following was pretty good, but liked breaking whenever mobj->lastlook changed.
|
||||
//P_MaceRotate(mobj, ((leveltime + 1) * mobj->lastlook), (leveltime * mobj->lastlook));
|
||||
P_MaceRotate(mobj, mobj->movedir + mobj->lastlook, mobj->movedir);
|
||||
mobj->movedir = (mobj->movedir + mobj->lastlook) & FINEMASK;
|
||||
break;
|
||||
case MT_HOOP:
|
||||
if (mobj->fuse > 1)
|
||||
P_MoveHoop(mobj);
|
||||
|
@ -7337,19 +7435,6 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case MT_CHAINPOINT:
|
||||
case MT_CHAINMACEPOINT:
|
||||
if (leveltime & 1)
|
||||
{
|
||||
if (mobj->lastlook > mobj->movecount)
|
||||
mobj->lastlook--;
|
||||
/*
|
||||
if (mobj->threshold > mobj->movefactor)
|
||||
mobj->threshold -= FRACUNIT;
|
||||
else if (mobj->threshold < mobj->movefactor)
|
||||
mobj->threshold += FRACUNIT;*/
|
||||
}
|
||||
break;
|
||||
case MT_EGGCAPSULE:
|
||||
if (!mobj->reactiontime)
|
||||
{
|
||||
|
@ -8615,6 +8700,13 @@ void P_RemoveMobj(mobj_t *mobj)
|
|||
// Remove any references to other mobjs.
|
||||
P_SetTarget(&mobj->target, P_SetTarget(&mobj->tracer, NULL));
|
||||
|
||||
if (mobj->hnext && !P_MobjWasRemoved(mobj->hnext))
|
||||
P_SetTarget(&mobj->hnext->hprev, mobj->hprev);
|
||||
if (mobj->hprev && !P_MobjWasRemoved(mobj->hprev))
|
||||
P_SetTarget(&mobj->hprev->hnext, mobj->hnext);
|
||||
|
||||
P_SetTarget(&mobj->hnext, P_SetTarget(&mobj->hprev, NULL));
|
||||
|
||||
// free block
|
||||
// DBG: set everything in mobj_t to 0xFF instead of leaving it. debug memory error.
|
||||
if (mobj->flags & MF_NOTHINK && !mobj->thinker.next)
|
||||
|
@ -9301,6 +9393,7 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
|||
mobj_t *mobj;
|
||||
fixed_t x, y, z;
|
||||
subsector_t *ss;
|
||||
boolean doangle = true;
|
||||
|
||||
if (!mthing->type)
|
||||
return; // Ignore type-0 things as NOPs
|
||||
|
@ -9706,11 +9799,11 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
|||
case MT_FIREBARPOINT:
|
||||
case MT_CUSTOMMACEPOINT:
|
||||
{
|
||||
fixed_t mlength, mlengthset, mspeed, mphase, myaw, mpitch, mmaxspeed, mnumspokes, mnumspokesset, mpinch, mroll, mnumnospokes, mwidth, mmin, msound, radiusfactor;
|
||||
fixed_t mlength, mmaxlength, mlengthset, mspeed, mphase, myaw, mpitch, mminlength, mnumspokes, mpinch, mroll, mnumnospokes, mwidth, mwidthset, mmin, msound, radiusfactor, widthfactor;
|
||||
angle_t mspokeangle;
|
||||
mobjtype_t chainlink, macetype, firsttype, linktype;
|
||||
boolean mdoall = true;
|
||||
mobj_t *spawnee;
|
||||
boolean mdosound, mdocenter;
|
||||
mobj_t *spawnee = NULL, *hprev = mobj;
|
||||
mobjflag_t mflagsapply;
|
||||
mobjflag2_t mflags2apply;
|
||||
mobjeflag_t meflagsapply;
|
||||
|
@ -9747,8 +9840,10 @@ ML_EFFECT4 : Don't clip inside the ground
|
|||
mlength = abs(lines[line].dx >> FRACBITS);
|
||||
mspeed = abs(lines[line].dy >> (FRACBITS - 4));
|
||||
mphase = (sides[lines[line].sidenum[0]].textureoffset >> FRACBITS) % 360;
|
||||
if ((mmaxspeed = sides[lines[line].sidenum[0]].rowoffset >> (FRACBITS - 4)) < mspeed)
|
||||
mmaxspeed = mspeed << 1;
|
||||
if ((mminlength = -sides[lines[line].sidenum[0]].rowoffset>>FRACBITS) < 0)
|
||||
mminlength = 0;
|
||||
else if (mminlength > mlength-1)
|
||||
mminlength = mlength-1;
|
||||
mpitch = (lines[line].frontsector->floorheight >> FRACBITS) % 360;
|
||||
myaw = (lines[line].frontsector->ceilingheight >> FRACBITS) % 360;
|
||||
|
||||
|
@ -9767,30 +9862,29 @@ ML_EFFECT4 : Don't clip inside the ground
|
|||
mpinch = mroll = mnumnospokes = mwidth = 0;
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "Mace/Chain (mapthing #%s):\n"
|
||||
"Length is %d\n"
|
||||
"Length is %d (minus %d)\n"
|
||||
"Speed is %d\n"
|
||||
"Phase is %d\n"
|
||||
"Yaw is %d\n"
|
||||
"Pitch is %d\n"
|
||||
"Max. speed is %d\n"
|
||||
"No. of spokes is %d\n"
|
||||
"No. of spokes is %d (%d antispokes)\n"
|
||||
"Pinch is %d\n"
|
||||
"Roll is %d\n"
|
||||
"No. of antispokes is %d\n"
|
||||
"Width is %d\n",
|
||||
sizeu1(mthingi), mlength, mspeed, mphase, myaw, mpitch, mmaxspeed, mnumspokes, mpinch, mroll, mnumnospokes, mwidth);
|
||||
sizeu1(mthingi), mlength, mminlength, mspeed, mphase, myaw, mpitch, mnumspokes, mnumnospokes, mpinch, mroll, mwidth);
|
||||
|
||||
if (mnumnospokes > 0 && (mnumnospokes < mnumspokes))
|
||||
mnumnospokes = mnumspokes/mnumnospokes;
|
||||
else
|
||||
mnumnospokes = ((mobj->type == MT_CHAINMACEPOINT) ? (mnumspokes - 1) : 0);
|
||||
mnumnospokes = ((mobj->type == MT_CHAINMACEPOINT) ? (mnumspokes) : 0);
|
||||
|
||||
mobj->lastlook = mspeed;
|
||||
mobj->movecount = mobj->lastlook;
|
||||
mobj->health = (FixedAngle(myaw*FRACUNIT)>>ANGLETOFINESHIFT);
|
||||
mobj->angle = FixedAngle(myaw*FRACUNIT);
|
||||
doangle = false;
|
||||
mobj->threshold = (FixedAngle(mpitch*FRACUNIT)>>ANGLETOFINESHIFT);
|
||||
mobj->friction = mmaxspeed;
|
||||
mobj->movefactor = mpinch;
|
||||
mobj->movedir = 0;
|
||||
|
||||
// Mobjtype selection
|
||||
switch(mobj->type)
|
||||
|
@ -9828,7 +9922,7 @@ ML_EFFECT4 : Don't clip inside the ground
|
|||
break;
|
||||
}
|
||||
|
||||
if (!macetype)
|
||||
if (!macetype && !chainlink)
|
||||
break;
|
||||
|
||||
if (mobj->type != MT_CHAINPOINT)
|
||||
|
@ -9857,7 +9951,7 @@ ML_EFFECT4 : Don't clip inside the ground
|
|||
mmin = mnumspokes;
|
||||
|
||||
// Make the links the same type as the end - repeated below
|
||||
if ((mobj->type != MT_CHAINPOINT) && ((lines[line].flags & ML_EFFECT2) != (mobj->type == MT_FIREBARPOINT))) // exclusive or
|
||||
if ((mobj->type != MT_CHAINPOINT) && (((lines[line].flags & ML_EFFECT2) == ML_EFFECT2) != (mobj->type == MT_FIREBARPOINT))) // exclusive or
|
||||
{
|
||||
linktype = macetype;
|
||||
radiusfactor = 2; // Double the radius.
|
||||
|
@ -9865,8 +9959,10 @@ ML_EFFECT4 : Don't clip inside the ground
|
|||
else
|
||||
radiusfactor = (((linktype = chainlink) == MT_NULL) ? 2 : 1);
|
||||
|
||||
widthfactor = ((firsttype == chainlink) ? 1 : 2);
|
||||
|
||||
mflagsapply = ((lines[line].flags & ML_EFFECT4) ? 0 : (MF_NOCLIP|MF_NOCLIPHEIGHT));
|
||||
mflags2apply = (MF2_MACEROTATE|((mthing->options & MTF_OBJECTFLIP) ? MF2_OBJECTFLIP : 0));
|
||||
mflags2apply = ((mthing->options & MTF_OBJECTFLIP) ? MF2_OBJECTFLIP : 0);
|
||||
meflagsapply = ((mthing->options & MTF_OBJECTFLIP) ? MFE_VERTICALFLIP : 0);
|
||||
|
||||
msound = ((firsttype == chainlink) ? 0 : (mwidth & 1));
|
||||
|
@ -9875,25 +9971,27 @@ ML_EFFECT4 : Don't clip inside the ground
|
|||
mphase = (FixedAngle(mphase*FRACUNIT)>>ANGLETOFINESHIFT);
|
||||
mroll = (FixedAngle(mroll*FRACUNIT)>>ANGLETOFINESHIFT);
|
||||
|
||||
#define makemace(mobjtype, dist, moreflags2) P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobjtype);\
|
||||
P_SetTarget(&spawnee->tracer, mobj);\
|
||||
spawnee->threshold = mphase;\
|
||||
spawnee->friction = mroll;\
|
||||
spawnee->movefactor = mwidth;\
|
||||
spawnee->movecount = dist;\
|
||||
spawnee->angle = myaw;\
|
||||
spawnee->flags |= (MF_NOGRAVITY|mflagsapply);\
|
||||
spawnee->flags2 |= (mflags2apply|moreflags2);\
|
||||
spawnee->eflags |= meflagsapply
|
||||
#define makemace(mobjtype, dist, moreflags2) {\
|
||||
spawnee = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobjtype);\
|
||||
P_SetTarget(&spawnee->tracer, mobj);\
|
||||
spawnee->threshold = mphase;\
|
||||
spawnee->friction = mroll;\
|
||||
spawnee->movefactor = mwidthset;\
|
||||
spawnee->movecount = dist;\
|
||||
spawnee->angle = myaw;\
|
||||
spawnee->flags |= (MF_NOGRAVITY|mflagsapply);\
|
||||
spawnee->flags2 |= (mflags2apply|moreflags2);\
|
||||
spawnee->eflags |= meflagsapply;\
|
||||
P_SetTarget(&hprev->hnext, spawnee);\
|
||||
P_SetTarget(&spawnee->hprev, hprev);\
|
||||
hprev = spawnee;\
|
||||
}
|
||||
|
||||
domaceagain:
|
||||
mnumspokesset = mnumspokes;
|
||||
|
||||
if (mdoall && lines[line].flags & ML_EFFECT3) // Innermost mace/link
|
||||
{ spawnee = makemace(macetype, 0, MF2_AMBUSH); }
|
||||
mdosound = (mspeed && !(mthing->options & MTF_OBJECTSPECIAL));
|
||||
mdocenter = (macetype && (lines[line].flags & ML_EFFECT3));
|
||||
|
||||
// The actual spawning of spokes
|
||||
while (mnumspokesset-- > 0)
|
||||
while (mnumspokes-- > 0)
|
||||
{
|
||||
// Offsets
|
||||
if (lines[line].flags & ML_EFFECT1) // Swinging
|
||||
|
@ -9901,14 +9999,14 @@ domaceagain:
|
|||
else // Spinning
|
||||
mphase = (mphase - mspokeangle) & FINEMASK;
|
||||
|
||||
if (mnumnospokes && !(mnumspokesset % mnumnospokes)) // Skipping a "missing" spoke
|
||||
if (mnumnospokes && !(mnumspokes % mnumnospokes)) // Skipping a "missing" spoke
|
||||
{
|
||||
if (mobj->type != MT_CHAINMACEPOINT)
|
||||
continue;
|
||||
|
||||
firsttype = linktype = chainlink;
|
||||
mlengthset = 1 + (mlength - 1)*radiusfactor;
|
||||
radiusfactor = 1;
|
||||
mmaxlength = 1 + (mlength - 1)*radiusfactor;
|
||||
radiusfactor = widthfactor = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -9927,36 +10025,73 @@ domaceagain:
|
|||
}
|
||||
|
||||
firsttype = macetype;
|
||||
widthfactor = 2;
|
||||
}
|
||||
|
||||
mlengthset = mlength;
|
||||
mmaxlength = mlength;
|
||||
}
|
||||
|
||||
mwidthset = mwidth;
|
||||
mlengthset = mminlength;
|
||||
|
||||
if (mdocenter) // Innermost mace/link
|
||||
makemace(macetype, 0, 0);
|
||||
|
||||
// Out from the center...
|
||||
if (linktype)
|
||||
{
|
||||
while ((++mlengthset) < mmaxlength)
|
||||
makemace(linktype, radiusfactor*mlengthset, 0);
|
||||
}
|
||||
else
|
||||
mlengthset = mmaxlength;
|
||||
|
||||
// Outermost mace/link
|
||||
spawnee = makemace(firsttype, radiusfactor*(mlengthset--), MF2_AMBUSH);
|
||||
if (firsttype)
|
||||
makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH);
|
||||
|
||||
if (mspeed && (mwidth == msound) && !(mthing->options & MTF_OBJECTSPECIAL) && mnumspokesset <= mmin) // Can it make a sound?
|
||||
spawnee->flags2 |= MF2_BOSSNOTRAP;
|
||||
if (!mwidth)
|
||||
{
|
||||
if (mdosound && mnumspokes <= mmin) // Can it make a sound?
|
||||
spawnee->flags2 |= MF2_BOSSNOTRAP;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Across the bar!
|
||||
if (!firsttype)
|
||||
mwidthset = -mwidth;
|
||||
else if (mwidth > 0)
|
||||
{
|
||||
while ((mwidthset -= widthfactor) > -mwidth)
|
||||
{
|
||||
makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH);
|
||||
if (mdosound && (mwidthset == msound) && mnumspokes <= mmin) // Can it make a sound?
|
||||
spawnee->flags2 |= MF2_BOSSNOTRAP;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((mwidthset += widthfactor) < -mwidth)
|
||||
{
|
||||
makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH);
|
||||
if (mdosound && (mwidthset == msound) && mnumspokes <= mmin) // Can it make a sound?
|
||||
spawnee->flags2 |= MF2_BOSSNOTRAP;
|
||||
}
|
||||
}
|
||||
mwidth = -mwidth;
|
||||
|
||||
if (!mdoall || !linktype)
|
||||
continue;
|
||||
// Outermost mace/link again!
|
||||
if (firsttype)
|
||||
makemace(firsttype, radiusfactor*(mlengthset--), MF2_AMBUSH);
|
||||
|
||||
// The rest of the links
|
||||
while (mlengthset > 0)
|
||||
{ spawnee = makemace(linktype, radiusfactor*(mlengthset--), 0); }
|
||||
}
|
||||
// ...and then back into the center!
|
||||
if (linktype)
|
||||
while (mlengthset > mminlength)
|
||||
makemace(linktype, radiusfactor*(mlengthset--), 0);
|
||||
|
||||
if (mwidth > 0)
|
||||
{
|
||||
mwidth *= -1;
|
||||
goto domaceagain;
|
||||
}
|
||||
else if (mwidth != 0)
|
||||
{
|
||||
if ((mwidth = -(mwidth + ((firsttype == chainlink) ? 1 : 2))) < 0)
|
||||
break;
|
||||
mdoall = false;
|
||||
goto domaceagain;
|
||||
if (mdocenter) // Innermost mace/link
|
||||
makemace(macetype, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#undef makemace
|
||||
|
@ -10261,16 +10396,16 @@ domaceagain:
|
|||
}
|
||||
}
|
||||
|
||||
if (doangle)
|
||||
mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
|
||||
|
||||
// ignore MTF_ flags and return early
|
||||
if (i == MT_NIGHTSBUMPER)
|
||||
{
|
||||
mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
|
||||
mthing->mobj = mobj;
|
||||
return;
|
||||
}
|
||||
|
||||
mobj->angle = FixedAngle(mthing->angle*FRACUNIT);
|
||||
|
||||
if ((mthing->options & MTF_AMBUSH)
|
||||
&& (mthing->options & MTF_OBJECTSPECIAL)
|
||||
&& (mobj->flags & MF_PUSHABLE))
|
||||
|
|
|
@ -194,7 +194,6 @@ typedef enum
|
|||
MF2_AMBUSH = 1<<27, // Alternate behaviour typically set by MTF_AMBUSH
|
||||
MF2_LINKDRAW = 1<<28, // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position)
|
||||
MF2_SHIELD = 1<<29, // Thinker calls P_AddShield/P_ShieldLook (must be partnered with MF_SCENERY to use)
|
||||
MF2_MACEROTATE = 1<<30, // Thinker calls P_MaceRotate around tracer
|
||||
// free: to and including 1<<31
|
||||
} mobjflag2_t;
|
||||
|
||||
|
|
13
src/p_user.c
13
src/p_user.c
|
@ -10444,21 +10444,10 @@ void P_PlayerAfterThink(player_t *player)
|
|||
player->secondjump = 0;
|
||||
player->pflags &= ~PF_THOKKED;
|
||||
|
||||
if (cmd->forwardmove > 0)
|
||||
{
|
||||
if ((player->mo->tracer->tracer->lastlook += 2) > player->mo->tracer->tracer->friction)
|
||||
player->mo->tracer->tracer->lastlook = player->mo->tracer->tracer->friction;
|
||||
}
|
||||
else if (cmd->forwardmove < 0)
|
||||
{
|
||||
if ((player->mo->tracer->tracer->lastlook -= 2) < player->mo->tracer->tracer->movecount)
|
||||
player->mo->tracer->tracer->lastlook = player->mo->tracer->tracer->movecount;
|
||||
}
|
||||
|
||||
if ((player->mo->tracer->tracer->flags & MF_SLIDEME) // Noclimb on chain parameters gives this
|
||||
&& !(twodlevel || player->mo->flags2 & MF2_TWOD)) // why on earth would you want to turn them in 2D mode?
|
||||
{
|
||||
player->mo->tracer->tracer->health += cmd->sidemove;
|
||||
player->mo->tracer->tracer->angle += cmd->sidemove<<ANGLETOFINESHIFT;
|
||||
player->mo->angle += cmd->sidemove<<ANGLETOFINESHIFT; // 2048 --> ANGLE_MAX
|
||||
|
||||
if (!demoplayback || P_AnalogMove(player))
|
||||
|
|
Loading…
Reference in a new issue