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]); 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) void K_SpawnBattleCapsules(void)
{ {
mapthing_t *mt; mapthing_t *mt;
@ -269,6 +330,7 @@ void K_SpawnBattleCapsules(void)
UINT8 numfloors = 1; UINT8 numfloors = 1;
mobj_t *mobj = NULL; mobj_t *mobj = NULL;
boolean fly = true; boolean fly = true;
UINT8 j;
mt->mobj = NULL; mt->mobj = NULL;
@ -352,9 +414,9 @@ void K_SpawnBattleCapsules(void)
mobj->flags2 |= MF2_OBJECTFLIP; 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; fly = false;
break; break;
@ -368,6 +430,10 @@ void K_SpawnBattleCapsules(void)
mobj->extravalue1 = 1; // Set extravalue1 for later reference 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 // Moved from P_SpawnMobj due to order of operations mumbo jumbo
{ {
mobj_t *cur, *prev = mobj; mobj_t *cur, *prev = mobj;
@ -392,16 +458,17 @@ void K_SpawnBattleCapsules(void)
prev = cur; prev = cur;
// Supports on the bottom // 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 = 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) // Flying capsule, moving or not
if (mobj->extravalue1)
P_SetMobjState(cur, S_BATTLECAPSULE_SUPPORTFLY); P_SetMobjState(cur, S_BATTLECAPSULE_SUPPORTFLY);
else if (mobj->target && !P_MobjWasRemoved(mobj->target)) // Grounded, moving capsule
P_SetMobjState(cur, S_KARMAWHEEL);
else else
P_SetMobjState(cur, S_BATTLECAPSULE_SUPPORT); P_SetMobjState(cur, S_BATTLECAPSULE_SUPPORT); // Grounded, stationary capsule
P_SetTarget(&cur->target, mobj); P_SetTarget(&cur->target, mobj);
P_SetTarget(&cur->hprev, prev); P_SetTarget(&cur->hprev, prev);
@ -410,12 +477,12 @@ void K_SpawnBattleCapsules(void)
} }
// Side paneling // 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 = 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); P_SetMobjState(cur, S_BATTLECAPSULE_SIDE2);
else else
P_SetMobjState(cur, S_BATTLECAPSULE_SIDE1); P_SetMobjState(cur, S_BATTLECAPSULE_SIDE1);
@ -427,7 +494,6 @@ void K_SpawnBattleCapsules(void)
} }
} }
mobj->angle = FixedAngle(mt->angle * FRACUNIT);
mt->mobj = mobj; mt->mobj = mobj;
} }
} }

View file

@ -9130,7 +9130,147 @@ void P_MobjThinker(mobj_t *mobj)
mobj->momz = sine/2; 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) if (flip == -1)
bottom = mobj->z + mobj->height; bottom = mobj->z + mobj->height;
@ -9159,7 +9299,9 @@ void P_MobjThinker(mobj_t *mobj)
newz += (80 * mobj->scale * flip); newz += (80 * mobj->scale * flip);
else if (state == S_BATTLECAPSULE_BUTTON) else if (state == S_BATTLECAPSULE_BUTTON)
newz += (108 * mobj->scale * flip); 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 offx = mobj->radius;
fixed_t offy = mobj->radius; fixed_t offy = mobj->radius;
@ -9173,7 +9315,8 @@ void P_MobjThinker(mobj_t *mobj)
newx += offx; newx += offx;
newy += offy; 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; fixed_t offset = 48 * mobj->scale;
angle_t angle = (ANGLE_45 * cur->extravalue1); angle_t angle = (ANGLE_45 * cur->extravalue1);