Moving capsules

This commit is contained in:
TehRealSalt 2019-09-15 23:36:55 -04:00
parent 1ef09699d1
commit 88578f0534
2 changed files with 223 additions and 14 deletions

View file

@ -233,6 +233,67 @@ void K_CheckBumpers(void)
P_DoPlayerExit(&players[i]);
}
static void K_SetupMovingCapsule(mapthing_t *mt, mobj_t *mobj)
{
UINT8 sequence = mt->extrainfo-1;
fixed_t speed = (FRACUNIT >> 3) * mt->angle;
boolean backandforth = (mt->options & MTF_AMBUSH);
boolean reverse = (mt->options & MTF_OBJECTSPECIAL);
mobj_t *mo2;
mobj_t *target = NULL;
thinker_t *th;
// Find the inital target
for (th = thinkercap.next; th != &thinkercap; th = th->next)
{
if (th->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker
continue;
mo2 = (mobj_t *)th;
if (mo2->type != MT_TUBEWAYPOINT)
continue;
if (mo2->threshold == sequence)
{
if (reverse) // Use the highest waypoint number as first
{
if (mo2->health != 0)
{
if (target == NULL)
target = mo2;
else if (mo2->health > target->health)
target = mo2;
}
}
else // Use the lowest waypoint number as first
{
if (mo2->health == 0)
target = mo2;
}
}
}
if (!target)
{
CONS_Alert(CONS_WARNING, "No target waypoint found for moving capsule (seq: #%d)\n", sequence);
return;
}
P_SetTarget(&mobj->target, target);
mobj->lastlook = sequence;
mobj->movecount = target->health;
mobj->movefactor = speed;
if (backandforth)
mobj->cusval = 1;
if (reverse)
mobj->cvmem = -1;
else
mobj->cvmem = 1;
}
void K_SpawnBattleCapsules(void)
{
mapthing_t *mt;
@ -269,6 +330,7 @@ void K_SpawnBattleCapsules(void)
UINT8 numfloors = 1;
mobj_t *mobj = NULL;
boolean fly = true;
UINT8 j;
mt->mobj = NULL;
@ -352,9 +414,9 @@ void K_SpawnBattleCapsules(void)
mobj->flags2 |= MF2_OBJECTFLIP;
}
for (i = 0; i < numfloors; i++)
for (j = 0; j < numfloors; j++)
{
if (z == floorheights[i])
if (z == floorheights[j])
{
fly = false;
break;
@ -368,6 +430,10 @@ void K_SpawnBattleCapsules(void)
mobj->extravalue1 = 1; // Set extravalue1 for later reference
}
// Moving capsules!
if (mt->extrainfo && mt->angle)
K_SetupMovingCapsule(mt, mobj);
// Moved from P_SpawnMobj due to order of operations mumbo jumbo
{
mobj_t *cur, *prev = mobj;
@ -392,16 +458,17 @@ void K_SpawnBattleCapsules(void)
prev = cur;
// Supports on the bottom
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
{
cur = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_BATTLECAPSULE_PIECE);
cur->extravalue1 = i;
cur->extravalue1 = j;
// TODO: use karma bomb wheels on grounded, moving capsules
if (mobj->extravalue1)
if (mobj->extravalue1) // Flying capsule, moving or not
P_SetMobjState(cur, S_BATTLECAPSULE_SUPPORTFLY);
else if (mobj->target && !P_MobjWasRemoved(mobj->target)) // Grounded, moving capsule
P_SetMobjState(cur, S_KARMAWHEEL);
else
P_SetMobjState(cur, S_BATTLECAPSULE_SUPPORT);
P_SetMobjState(cur, S_BATTLECAPSULE_SUPPORT); // Grounded, stationary capsule
P_SetTarget(&cur->target, mobj);
P_SetTarget(&cur->hprev, prev);
@ -410,12 +477,12 @@ void K_SpawnBattleCapsules(void)
}
// Side paneling
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
{
cur = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_BATTLECAPSULE_PIECE);
cur->extravalue1 = i;
cur->extravalue1 = j;
if (i & 1)
if (j & 1)
P_SetMobjState(cur, S_BATTLECAPSULE_SIDE2);
else
P_SetMobjState(cur, S_BATTLECAPSULE_SIDE1);
@ -427,7 +494,6 @@ void K_SpawnBattleCapsules(void)
}
}
mobj->angle = FixedAngle(mt->angle * FRACUNIT);
mt->mobj = mobj;
}
}

View file

@ -9130,7 +9130,147 @@ void P_MobjThinker(mobj_t *mobj)
mobj->momz = sine/2;
}
// TODO: insert moving capsule code here
// Moving capsules
if (mobj->target && !P_MobjWasRemoved(mobj->target))
{
fixed_t speed = mobj->movefactor;
UINT8 sequence = mobj->lastlook;
UINT8 num = mobj->movecount;
boolean backandforth = mobj->cusval;
SINT8 direction = mobj->cvmem;
mobj_t *next = NULL;
thinker_t *th;
fixed_t dist, momx, momy, momz;
dist = P_AproxDistance(mobj->target->x - mobj->x, mobj->target->y - mobj->y);
if (mobj->extravalue1)
dist = P_AproxDistance(dist, mobj->target->z - mobj->z);
if (dist < 1)
dist = 1;
if (speed <= dist)
{
momx = FixedMul(FixedDiv(mobj->target->x - mobj->x, dist), speed);
momy = FixedMul(FixedDiv(mobj->target->y - mobj->y, dist), speed);
if (mobj->extravalue1)
momz = mobj->momz + FixedMul(FixedDiv(mobj->target->z - mobj->z, dist), speed);
mobj->momx = momx;
mobj->momy = momy;
if (mobj->extravalue1)
mobj->momz = momz;
}
else
{
mobj_t *mo2;
speed -= dist;
P_UnsetThingPosition(mobj);
mobj->x = mobj->target->x;
mobj->y = mobj->target->y;
mobj->z = mobj->target->z;
P_SetThingPosition(mobj);
mobj->floorz = mobj->subsector->sector->floorheight;
mobj->ceilingz = mobj->subsector->sector->ceilingheight;
// Onto the next waypoint!
for (th = thinkercap.next; th != &thinkercap; th = th->next)
{
if (th->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker
continue;
mo2 = (mobj_t *)th;
if (mo2->type != MT_TUBEWAYPOINT)
continue;
if (mo2->threshold == sequence)
{
if (mo2->health == num + direction)
{
next = mo2;
break;
}
}
}
// Are we at the end of the waypoint chain?
// If so, search again for the first/previous waypoint (depending on settings)
if (next == NULL)
{
if (backandforth)
{
mobj->cvmem = -mobj->cvmem;
direction = mobj->cvmem;
}
for (th = thinkercap.next; th != &thinkercap; th = th->next)
{
if (th->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker
continue;
mo2 = (mobj_t *)th;
if (mo2->type != MT_TUBEWAYPOINT)
continue;
if (mo2->threshold == sequence)
{
if (backandforth)
{
if (mo2->health == num + direction)
{
next = mo2;
break;
}
}
else
{
if (direction < 0)
{
if (next == NULL || mo2->health > next->health)
next = mo2;
}
else
{
if (next == NULL || mo2->health < next->health)
next = mo2;
}
}
}
}
}
if (next && !P_MobjWasRemoved(next))
{
P_SetTarget(&mobj->target, next);
mobj->movecount = next->health;
dist = P_AproxDistance(mobj->target->x - mobj->x, mobj->target->y - mobj->y);
if (mobj->extravalue1)
dist = P_AproxDistance(dist, mobj->target->z - mobj->z);
if (dist < 1)
dist = 1;
momx = FixedMul(FixedDiv(mobj->target->x - mobj->x, dist), speed);
momy = FixedMul(FixedDiv(mobj->target->y - mobj->y, dist), speed);
if (mobj->extravalue1)
momz = mobj->momz + FixedMul(FixedDiv(mobj->target->z - mobj->z, dist), speed);
mobj->momx = momx;
mobj->momy = momy;
if (mobj->extravalue1)
mobj->momz = momz;
}
else
{
CONS_Alert(CONS_WARNING, "Moving capsule could not find next waypoint! (seq: %d)\n", sequence);
P_SetTarget(&mobj->target, NULL);
}
}
}
if (flip == -1)
bottom = mobj->z + mobj->height;
@ -9159,7 +9299,9 @@ void P_MobjThinker(mobj_t *mobj)
newz += (80 * mobj->scale * flip);
else if (state == S_BATTLECAPSULE_BUTTON)
newz += (108 * mobj->scale * flip);
else if (state == S_BATTLECAPSULE_SUPPORT || state == S_BATTLECAPSULE_SUPPORTFLY)
else if (state == S_BATTLECAPSULE_SUPPORT
|| state == S_BATTLECAPSULE_SUPPORTFLY
|| state == S_KARMAWHEEL)
{
fixed_t offx = mobj->radius;
fixed_t offy = mobj->radius;
@ -9173,7 +9315,8 @@ void P_MobjThinker(mobj_t *mobj)
newx += offx;
newy += offy;
}
else if (state == S_BATTLECAPSULE_SIDE1 || state == S_BATTLECAPSULE_SIDE2)
else if (state == S_BATTLECAPSULE_SIDE1
|| state == S_BATTLECAPSULE_SIDE2)
{
fixed_t offset = 48 * mobj->scale;
angle_t angle = (ANGLE_45 * cur->extravalue1);