Merge branch 'more-polyobject-cleanup' into 'next'
Smooth polyobject movement and other cleanup See merge request STJr/SRB2!947
This commit is contained in:
commit
6f854f2de3
|
@ -631,6 +631,7 @@ mobj_t *P_GetLastWaypoint(UINT8 sequence);
|
||||||
mobj_t *P_GetPreviousWaypoint(mobj_t *current, boolean wrap);
|
mobj_t *P_GetPreviousWaypoint(mobj_t *current, boolean wrap);
|
||||||
mobj_t *P_GetNextWaypoint(mobj_t *current, boolean wrap);
|
mobj_t *P_GetNextWaypoint(mobj_t *current, boolean wrap);
|
||||||
mobj_t *P_GetClosestWaypoint(UINT8 sequence, mobj_t *mo);
|
mobj_t *P_GetClosestWaypoint(UINT8 sequence, mobj_t *mo);
|
||||||
|
boolean P_IsDegeneratedWaypointSequence(UINT8 sequence);
|
||||||
|
|
||||||
// =====================================
|
// =====================================
|
||||||
// Internal parameters, used for engine.
|
// Internal parameters, used for engine.
|
||||||
|
|
301
src/p_polyobj.c
301
src/p_polyobj.c
|
@ -1569,15 +1569,39 @@ void T_PolyObjMove(polymove_t *th)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void T_MovePolyObj(polyobj_t *po, fixed_t distx, fixed_t disty, fixed_t distz)
|
||||||
|
{
|
||||||
|
polyobj_t *child;
|
||||||
|
INT32 start;
|
||||||
|
|
||||||
|
Polyobj_moveXY(po, distx, disty, true);
|
||||||
|
// TODO: use T_MovePlane
|
||||||
|
po->lines[0]->backsector->floorheight += distz;
|
||||||
|
po->lines[0]->backsector->ceilingheight += distz;
|
||||||
|
// Sal: Remember to check your sectors!
|
||||||
|
// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
|
||||||
|
// updating objects in the front one too just added teleporting to ground bugs
|
||||||
|
P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
|
||||||
|
// Apply action to mirroring polyobjects as well
|
||||||
|
start = 0;
|
||||||
|
while ((child = Polyobj_GetChild(po, &start)))
|
||||||
|
{
|
||||||
|
if (child->isBad)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Polyobj_moveXY(child, distx, disty, true);
|
||||||
|
// TODO: use T_MovePlane
|
||||||
|
child->lines[0]->backsector->floorheight += distz;
|
||||||
|
child->lines[0]->backsector->ceilingheight += distz;
|
||||||
|
P_CheckSector(child->lines[0]->backsector, (boolean)(child->damage));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void T_PolyObjWaypoint(polywaypoint_t *th)
|
void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||||
{
|
{
|
||||||
mobj_t *target = NULL;
|
mobj_t *target = NULL;
|
||||||
mobj_t *waypoint = NULL;
|
|
||||||
fixed_t adjustx, adjusty, adjustz;
|
|
||||||
fixed_t momx, momy, momz, dist;
|
|
||||||
INT32 start;
|
|
||||||
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
|
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
|
||||||
polyobj_t *oldpo = po;
|
fixed_t speed = th->speed;
|
||||||
|
|
||||||
if (!po)
|
if (!po)
|
||||||
#ifdef RANGECHECK
|
#ifdef RANGECHECK
|
||||||
|
@ -1594,7 +1618,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||||
if (!po->thinker)
|
if (!po->thinker)
|
||||||
po->thinker = &th->thinker;
|
po->thinker = &th->thinker;
|
||||||
|
|
||||||
target = th->target;
|
target = waypoints[th->sequence][th->pointnum];
|
||||||
|
|
||||||
if (!target)
|
if (!target)
|
||||||
{
|
{
|
||||||
|
@ -1602,152 +1626,93 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compensate for position offset
|
// Move along the waypoint sequence until speed for the current tic is exhausted
|
||||||
adjustx = po->centerPt.x + th->diffx;
|
while (speed > 0)
|
||||||
adjusty = po->centerPt.y + th->diffy;
|
|
||||||
adjustz = po->lines[0]->backsector->floorheight + (po->lines[0]->backsector->ceilingheight - po->lines[0]->backsector->floorheight)/2 + th->diffz;
|
|
||||||
|
|
||||||
dist = P_AproxDistance(P_AproxDistance(target->x - adjustx, target->y - adjusty), target->z - adjustz);
|
|
||||||
|
|
||||||
if (dist < 1)
|
|
||||||
dist = 1;
|
|
||||||
|
|
||||||
momx = FixedMul(FixedDiv(target->x - adjustx, dist), (th->speed));
|
|
||||||
momy = FixedMul(FixedDiv(target->y - adjusty, dist), (th->speed));
|
|
||||||
momz = FixedMul(FixedDiv(target->z - adjustz, dist), (th->speed));
|
|
||||||
|
|
||||||
// Calculate the distance between the polyobject and the waypoint
|
|
||||||
// 'dist' already equals this.
|
|
||||||
|
|
||||||
// Will the polyobject be FURTHER away if the momx/momy/momz is added to
|
|
||||||
// its current coordinates, or closer? (shift down to fracunits to avoid approximation errors)
|
|
||||||
if (dist>>FRACBITS <= P_AproxDistance(P_AproxDistance(target->x - adjustx - momx, target->y - adjusty - momy), target->z - adjustz - momz)>>FRACBITS)
|
|
||||||
{
|
{
|
||||||
// If further away, set XYZ of polyobject to waypoint location
|
mobj_t *waypoint = NULL;
|
||||||
fixed_t amtx, amty, amtz;
|
fixed_t pox, poy, poz;
|
||||||
fixed_t diffz;
|
fixed_t distx, disty, distz, dist;
|
||||||
amtx = (target->x - th->diffx) - po->centerPt.x;
|
|
||||||
amty = (target->y - th->diffy) - po->centerPt.y;
|
// Current position of polyobject
|
||||||
Polyobj_moveXY(po, amtx, amty, true);
|
pox = po->centerPt.x;
|
||||||
// TODO: use T_MovePlane
|
poy = po->centerPt.y;
|
||||||
amtz = (po->lines[0]->backsector->ceilingheight - po->lines[0]->backsector->floorheight)/2;
|
poz = (po->lines[0]->backsector->floorheight + po->lines[0]->backsector->ceilingheight)/2;
|
||||||
diffz = po->lines[0]->backsector->floorheight - (target->z - amtz);
|
|
||||||
po->lines[0]->backsector->floorheight = target->z - amtz;
|
// Calculate the distance between the polyobject and the waypoint
|
||||||
po->lines[0]->backsector->ceilingheight = target->z + amtz;
|
distx = target->x - pox;
|
||||||
// Sal: Remember to check your sectors!
|
disty = target->y - poy;
|
||||||
// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
|
distz = target->z - poz;
|
||||||
// updating objects in the front one too just added teleporting to ground bugs
|
dist = P_AproxDistance(P_AproxDistance(distx, disty), distz);
|
||||||
P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
|
|
||||||
// Apply action to mirroring polyobjects as well
|
if (dist < 1)
|
||||||
start = 0;
|
dist = 1;
|
||||||
while ((po = Polyobj_GetChild(oldpo, &start)))
|
|
||||||
|
// Will the polyobject overshoot its target?
|
||||||
|
if (speed < dist)
|
||||||
{
|
{
|
||||||
if (po->isBad)
|
// No. Move towards waypoint
|
||||||
continue;
|
fixed_t momx, momy, momz;
|
||||||
|
|
||||||
Polyobj_moveXY(po, amtx, amty, true);
|
momx = FixedMul(FixedDiv(target->x - pox, dist), speed);
|
||||||
// TODO: use T_MovePlane
|
momy = FixedMul(FixedDiv(target->y - poy, dist), speed);
|
||||||
po->lines[0]->backsector->floorheight += diffz; // move up/down by same amount as the parent did
|
momz = FixedMul(FixedDiv(target->z - poz, dist), speed);
|
||||||
po->lines[0]->backsector->ceilingheight += diffz;
|
T_MovePolyObj(po, momx, momy, momz);
|
||||||
// Sal: Remember to check your sectors!
|
return;
|
||||||
// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
|
|
||||||
// updating objects in the front one too just added teleporting to ground bugs
|
|
||||||
P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
|
|
||||||
}
|
|
||||||
|
|
||||||
po = oldpo;
|
|
||||||
|
|
||||||
if (!th->stophere)
|
|
||||||
{
|
|
||||||
CONS_Debug(DBG_POLYOBJ, "Looking for next waypoint...\n");
|
|
||||||
waypoint = (th->direction == -1) ? P_GetPreviousWaypoint(target, false) : P_GetNextWaypoint(target, false);
|
|
||||||
|
|
||||||
if (!waypoint && th->wrap) // If specified, wrap waypoints
|
|
||||||
{
|
|
||||||
if (!th->continuous)
|
|
||||||
{
|
|
||||||
th->wrap = 0;
|
|
||||||
th->stophere = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
waypoint = (th->direction == -1) ? P_GetLastWaypoint(th->sequence) : P_GetFirstWaypoint(th->sequence);
|
|
||||||
}
|
|
||||||
else if (!waypoint && th->comeback) // Come back to the start
|
|
||||||
{
|
|
||||||
th->direction = -th->direction;
|
|
||||||
|
|
||||||
if (!th->continuous)
|
|
||||||
th->comeback = false;
|
|
||||||
|
|
||||||
waypoint = (th->direction == -1) ? P_GetPreviousWaypoint(target, false) : P_GetNextWaypoint(target, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (waypoint)
|
|
||||||
{
|
|
||||||
CONS_Debug(DBG_POLYOBJ, "Found waypoint (sequence %d, number %d).\n", waypoint->threshold, waypoint->health);
|
|
||||||
|
|
||||||
target = waypoint;
|
|
||||||
th->pointnum = target->health;
|
|
||||||
// Set the mobj as your target! -- Monster Iestyn 27/12/19
|
|
||||||
P_SetTarget(&th->target, target);
|
|
||||||
|
|
||||||
// calculate MOMX/MOMY/MOMZ for next waypoint
|
|
||||||
// change slope
|
|
||||||
dist = P_AproxDistance(P_AproxDistance(target->x - adjustx, target->y - adjusty), target->z - adjustz);
|
|
||||||
|
|
||||||
if (dist < 1)
|
|
||||||
dist = 1;
|
|
||||||
|
|
||||||
momx = FixedMul(FixedDiv(target->x - adjustx, dist), (th->speed));
|
|
||||||
momy = FixedMul(FixedDiv(target->y - adjusty, dist), (th->speed));
|
|
||||||
momz = FixedMul(FixedDiv(target->z - adjustz, dist), (th->speed));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
momx = momy = momz = 0;
|
// Yes. Teleport to waypoint and look for the next one
|
||||||
|
T_MovePolyObj(po, distx, disty, distz);
|
||||||
|
|
||||||
if (!th->stophere)
|
if (!th->stophere)
|
||||||
CONS_Debug(DBG_POLYOBJ, "Next waypoint not found!\n");
|
{
|
||||||
|
CONS_Debug(DBG_POLYOBJ, "Looking for next waypoint...\n");
|
||||||
|
waypoint = (th->direction == -1) ? P_GetPreviousWaypoint(target, false) : P_GetNextWaypoint(target, false);
|
||||||
|
|
||||||
if (po->thinker == &th->thinker)
|
if (!waypoint && th->returnbehavior == PWR_WRAP) // If specified, wrap waypoints
|
||||||
po->thinker = NULL;
|
{
|
||||||
|
if (!th->continuous)
|
||||||
|
{
|
||||||
|
th->returnbehavior = PWR_STOP;
|
||||||
|
th->stophere = true;
|
||||||
|
}
|
||||||
|
|
||||||
P_RemoveThinker(&th->thinker);
|
waypoint = (th->direction == -1) ? P_GetLastWaypoint(th->sequence) : P_GetFirstWaypoint(th->sequence);
|
||||||
return;
|
}
|
||||||
|
else if (!waypoint && th->returnbehavior == PWR_COMEBACK) // Come back to the start
|
||||||
|
{
|
||||||
|
th->direction = -th->direction;
|
||||||
|
|
||||||
|
if (!th->continuous)
|
||||||
|
th->returnbehavior = PWR_STOP;
|
||||||
|
|
||||||
|
waypoint = (th->direction == -1) ? P_GetPreviousWaypoint(target, false) : P_GetNextWaypoint(target, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (waypoint)
|
||||||
|
{
|
||||||
|
CONS_Debug(DBG_POLYOBJ, "Found waypoint (sequence %d, number %d).\n", waypoint->threshold, waypoint->health);
|
||||||
|
|
||||||
|
target = waypoint;
|
||||||
|
th->pointnum = target->health;
|
||||||
|
|
||||||
|
// Calculate remaining speed
|
||||||
|
speed -= dist;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!th->stophere)
|
||||||
|
CONS_Debug(DBG_POLYOBJ, "Next waypoint not found!\n");
|
||||||
|
|
||||||
|
if (po->thinker == &th->thinker)
|
||||||
|
po->thinker = NULL;
|
||||||
|
|
||||||
|
P_RemoveThinker(&th->thinker);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// momx/momy/momz already equals the right speed
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move the polyobject
|
|
||||||
Polyobj_moveXY(po, momx, momy, true);
|
|
||||||
// TODO: use T_MovePlane
|
|
||||||
po->lines[0]->backsector->floorheight += momz;
|
|
||||||
po->lines[0]->backsector->ceilingheight += momz;
|
|
||||||
// Sal: Remember to check your sectors!
|
|
||||||
// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
|
|
||||||
// updating objects in the front one too just added teleporting to ground bugs
|
|
||||||
P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
|
|
||||||
|
|
||||||
// Apply action to mirroring polyobjects as well
|
|
||||||
start = 0;
|
|
||||||
while ((po = Polyobj_GetChild(oldpo, &start)))
|
|
||||||
{
|
|
||||||
if (po->isBad)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Polyobj_moveXY(po, momx, momy, true);
|
|
||||||
// TODO: use T_MovePlane
|
|
||||||
po->lines[0]->backsector->floorheight += momz;
|
|
||||||
po->lines[0]->backsector->ceilingheight += momz;
|
|
||||||
// Sal: Remember to check your sectors!
|
|
||||||
// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
|
|
||||||
// updating objects in the front one too just added teleporting to ground bugs
|
|
||||||
P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void T_PolyDoorSlide(polyslidedoor_t *th)
|
void T_PolyDoorSlide(polyslidedoor_t *th)
|
||||||
|
@ -2166,8 +2131,6 @@ boolean EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata)
|
||||||
polyobj_t *po;
|
polyobj_t *po;
|
||||||
polywaypoint_t *th;
|
polywaypoint_t *th;
|
||||||
mobj_t *first = NULL;
|
mobj_t *first = NULL;
|
||||||
mobj_t *last = NULL;
|
|
||||||
mobj_t *target = NULL;
|
|
||||||
|
|
||||||
if (!(po = Polyobj_GetForNum(pwdata->polyObjNum)))
|
if (!(po = Polyobj_GetForNum(pwdata->polyObjNum)))
|
||||||
{
|
{
|
||||||
|
@ -2191,17 +2154,16 @@ boolean EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata)
|
||||||
// set fields
|
// set fields
|
||||||
th->polyObjNum = pwdata->polyObjNum;
|
th->polyObjNum = pwdata->polyObjNum;
|
||||||
th->speed = pwdata->speed;
|
th->speed = pwdata->speed;
|
||||||
th->sequence = pwdata->sequence; // Used to specify sequence #
|
th->sequence = pwdata->sequence;
|
||||||
th->direction = pwdata->reverse ? -1 : 1;
|
th->direction = (pwdata->flags & PWF_REVERSE) ? -1 : 1;
|
||||||
|
|
||||||
th->comeback = pwdata->comeback;
|
th->returnbehavior = pwdata->returnbehavior;
|
||||||
th->continuous = pwdata->continuous;
|
if (pwdata->flags & PWF_LOOP)
|
||||||
th->wrap = pwdata->wrap;
|
th->continuous = true;
|
||||||
th->stophere = false;
|
th->stophere = false;
|
||||||
|
|
||||||
// Find the first waypoint we need to use
|
// Find the first waypoint we need to use
|
||||||
first = (th->direction == -1) ? P_GetLastWaypoint(th->sequence) : P_GetFirstWaypoint(th->sequence);
|
first = (th->direction == -1) ? P_GetLastWaypoint(th->sequence) : P_GetFirstWaypoint(th->sequence);
|
||||||
last = (th->direction == -1) ? P_GetFirstWaypoint(th->sequence) : P_GetLastWaypoint(th->sequence);
|
|
||||||
|
|
||||||
if (!first)
|
if (!first)
|
||||||
{
|
{
|
||||||
|
@ -2211,47 +2173,16 @@ boolean EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hotfix to not crash on single-waypoint sequences -Red
|
// Sanity check: If all waypoints are in the same location,
|
||||||
if (!last)
|
// don't allow the movement to be continuous so we don't get stuck in an infinite loop.
|
||||||
last = first;
|
if (th->continuous && P_IsDegeneratedWaypointSequence(th->sequence))
|
||||||
|
|
||||||
// Set diffx, diffy, diffz
|
|
||||||
// Put these at 0 for now...might not be needed after all.
|
|
||||||
th->diffx = 0;//first->x - po->centerPt.x;
|
|
||||||
th->diffy = 0;//first->y - po->centerPt.y;
|
|
||||||
th->diffz = 0;//first->z - (po->lines[0]->backsector->floorheight + (po->lines[0]->backsector->ceilingheight - po->lines[0]->backsector->floorheight)/2);
|
|
||||||
|
|
||||||
if (last->x == po->centerPt.x
|
|
||||||
&& last->y == po->centerPt.y
|
|
||||||
&& last->z == (po->lines[0]->backsector->floorheight + (po->lines[0]->backsector->ceilingheight - po->lines[0]->backsector->floorheight)/2))
|
|
||||||
{
|
{
|
||||||
// Already at the destination point...
|
CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjWaypoint: All waypoints are in the same location!\n");
|
||||||
if (!th->wrap)
|
th->continuous = false;
|
||||||
{
|
|
||||||
po->thinker = NULL;
|
|
||||||
P_RemoveThinker(&th->thinker);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the actual target movement waypoint
|
th->pointnum = first->health;
|
||||||
target = first;
|
|
||||||
|
|
||||||
if (!target)
|
|
||||||
{
|
|
||||||
CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjWaypoint: Missing target waypoint!\n");
|
|
||||||
po->thinker = NULL;
|
|
||||||
P_RemoveThinker(&th->thinker);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set pointnum
|
|
||||||
th->pointnum = target->health;
|
|
||||||
th->target = NULL; // set to NULL first so the below doesn't go wrong
|
|
||||||
// Set the mobj as your target! -- Monster Iestyn 27/12/19
|
|
||||||
P_SetTarget(&th->target, target);
|
|
||||||
|
|
||||||
// We don't deal with the mirror crap here, we'll
|
|
||||||
// handle that in the T_Thinker function.
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,26 +140,26 @@ typedef struct polymove_s
|
||||||
UINT32 angle; // angle along which to move
|
UINT32 angle; // angle along which to move
|
||||||
} polymove_t;
|
} polymove_t;
|
||||||
|
|
||||||
|
// PolyObject waypoint movement return behavior
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
PWR_STOP, // Stop after reaching last waypoint
|
||||||
|
PWR_WRAP, // Wrap back to first waypoint
|
||||||
|
PWR_COMEBACK, // Repeat sequence in reverse
|
||||||
|
} polywaypointreturn_e;
|
||||||
|
|
||||||
typedef struct polywaypoint_s
|
typedef struct polywaypoint_s
|
||||||
{
|
{
|
||||||
thinker_t thinker; // must be first
|
thinker_t thinker; // must be first
|
||||||
|
|
||||||
INT32 polyObjNum; // numeric id of polyobject
|
INT32 polyObjNum; // numeric id of polyobject
|
||||||
INT32 speed; // resultant velocity
|
INT32 speed; // resultant velocity
|
||||||
INT32 sequence; // waypoint sequence #
|
INT32 sequence; // waypoint sequence #
|
||||||
INT32 pointnum; // waypoint #
|
INT32 pointnum; // waypoint #
|
||||||
INT32 direction; // 1 for normal, -1 for backwards
|
INT32 direction; // 1 for normal, -1 for backwards
|
||||||
UINT8 comeback; // reverses and comes back when the end is reached
|
UINT8 returnbehavior; // behavior after reaching the last waypoint
|
||||||
UINT8 wrap; // Wrap around waypoints
|
UINT8 continuous; // continuously move - used with PWR_WRAP or PWR_COMEBACK
|
||||||
UINT8 continuous; // continuously move - used with COMEBACK or WRAP
|
UINT8 stophere; // Will stop after it reaches the next waypoint
|
||||||
UINT8 stophere; // Will stop after it reaches the next waypoint
|
|
||||||
|
|
||||||
// Difference between location of PO and location of waypoint (offset)
|
|
||||||
fixed_t diffx;
|
|
||||||
fixed_t diffy;
|
|
||||||
fixed_t diffz;
|
|
||||||
|
|
||||||
mobj_t *target; // next waypoint mobj
|
|
||||||
} polywaypoint_t;
|
} polywaypoint_t;
|
||||||
|
|
||||||
typedef struct polyslidedoor_s
|
typedef struct polyslidedoor_s
|
||||||
|
@ -254,15 +254,19 @@ typedef struct polymovedata_s
|
||||||
UINT8 overRide; // if true, will override any action on the object
|
UINT8 overRide; // if true, will override any action on the object
|
||||||
} polymovedata_t;
|
} polymovedata_t;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
PWF_REVERSE = 1, // Move through waypoints in reverse order
|
||||||
|
PWF_LOOP = 1<<1, // Loop movement (used with PWR_WRAP or PWR_COMEBACK)
|
||||||
|
} polywaypointflags_e;
|
||||||
|
|
||||||
typedef struct polywaypointdata_s
|
typedef struct polywaypointdata_s
|
||||||
{
|
{
|
||||||
INT32 polyObjNum; // numeric id of polyobject to affect
|
INT32 polyObjNum; // numeric id of polyobject to affect
|
||||||
INT32 sequence; // waypoint sequence #
|
INT32 sequence; // waypoint sequence #
|
||||||
fixed_t speed; // linear speed
|
fixed_t speed; // linear speed
|
||||||
UINT8 reverse; // if true, will go in reverse waypoint order
|
UINT8 returnbehavior; // behavior after reaching the last waypoint
|
||||||
UINT8 comeback; // reverses and comes back when the end is reached
|
UINT8 flags; // PWF_ flags
|
||||||
UINT8 wrap; // Wrap around waypoints
|
|
||||||
UINT8 continuous; // continuously move - used with COMEBACK or WRAP
|
|
||||||
} polywaypointdata_t;
|
} polywaypointdata_t;
|
||||||
|
|
||||||
// polyobject door types
|
// polyobject door types
|
||||||
|
|
|
@ -2018,14 +2018,9 @@ static void SavePolywaypointThinker(const thinker_t *th, UINT8 type)
|
||||||
WRITEINT32(save_p, ht->sequence);
|
WRITEINT32(save_p, ht->sequence);
|
||||||
WRITEINT32(save_p, ht->pointnum);
|
WRITEINT32(save_p, ht->pointnum);
|
||||||
WRITEINT32(save_p, ht->direction);
|
WRITEINT32(save_p, ht->direction);
|
||||||
WRITEUINT8(save_p, ht->comeback);
|
WRITEUINT8(save_p, ht->returnbehavior);
|
||||||
WRITEUINT8(save_p, ht->wrap);
|
|
||||||
WRITEUINT8(save_p, ht->continuous);
|
WRITEUINT8(save_p, ht->continuous);
|
||||||
WRITEUINT8(save_p, ht->stophere);
|
WRITEUINT8(save_p, ht->stophere);
|
||||||
WRITEFIXED(save_p, ht->diffx);
|
|
||||||
WRITEFIXED(save_p, ht->diffy);
|
|
||||||
WRITEFIXED(save_p, ht->diffz);
|
|
||||||
WRITEUINT32(save_p, SaveMobjnum(ht->target));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SavePolyslidedoorThinker(const thinker_t *th, const UINT8 type)
|
static void SavePolyslidedoorThinker(const thinker_t *th, const UINT8 type)
|
||||||
|
@ -3157,14 +3152,9 @@ static inline thinker_t* LoadPolywaypointThinker(actionf_p1 thinker)
|
||||||
ht->sequence = READINT32(save_p);
|
ht->sequence = READINT32(save_p);
|
||||||
ht->pointnum = READINT32(save_p);
|
ht->pointnum = READINT32(save_p);
|
||||||
ht->direction = READINT32(save_p);
|
ht->direction = READINT32(save_p);
|
||||||
ht->comeback = READUINT8(save_p);
|
ht->returnbehavior = READUINT8(save_p);
|
||||||
ht->wrap = READUINT8(save_p);
|
|
||||||
ht->continuous = READUINT8(save_p);
|
ht->continuous = READUINT8(save_p);
|
||||||
ht->stophere = READUINT8(save_p);
|
ht->stophere = READUINT8(save_p);
|
||||||
ht->diffx = READFIXED(save_p);
|
|
||||||
ht->diffy = READFIXED(save_p);
|
|
||||||
ht->diffz = READFIXED(save_p);
|
|
||||||
ht->target = LoadMobj(READUINT32(save_p));
|
|
||||||
return &ht->thinker;
|
return &ht->thinker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3411,7 +3401,6 @@ static void P_NetUnArchiveThinkers(void)
|
||||||
|
|
||||||
case tc_polywaypoint:
|
case tc_polywaypoint:
|
||||||
th = LoadPolywaypointThinker((actionf_p1)T_PolyObjWaypoint);
|
th = LoadPolywaypointThinker((actionf_p1)T_PolyObjWaypoint);
|
||||||
restoreNum = true;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tc_polyslidedoor:
|
case tc_polyslidedoor:
|
||||||
|
@ -3471,7 +3460,6 @@ static void P_NetUnArchiveThinkers(void)
|
||||||
if (restoreNum)
|
if (restoreNum)
|
||||||
{
|
{
|
||||||
executor_t *delay = NULL;
|
executor_t *delay = NULL;
|
||||||
polywaypoint_t *polywp = NULL;
|
|
||||||
UINT32 mobjnum;
|
UINT32 mobjnum;
|
||||||
for (currentthinker = thlist[THINK_MAIN].next; currentthinker != &thlist[THINK_MAIN]; currentthinker = currentthinker->next)
|
for (currentthinker = thlist[THINK_MAIN].next; currentthinker != &thlist[THINK_MAIN]; currentthinker = currentthinker->next)
|
||||||
{
|
{
|
||||||
|
@ -3482,15 +3470,6 @@ static void P_NetUnArchiveThinkers(void)
|
||||||
continue;
|
continue;
|
||||||
delay->caller = P_FindNewPosition(mobjnum);
|
delay->caller = P_FindNewPosition(mobjnum);
|
||||||
}
|
}
|
||||||
for (currentthinker = thlist[THINK_POLYOBJ].next; currentthinker != &thlist[THINK_POLYOBJ]; currentthinker = currentthinker->next)
|
|
||||||
{
|
|
||||||
if (currentthinker->function.acp1 != (actionf_p1)T_PolyObjWaypoint)
|
|
||||||
continue;
|
|
||||||
polywp = (void *)currentthinker;
|
|
||||||
if (!(mobjnum = (UINT32)(size_t)polywp->target))
|
|
||||||
continue;
|
|
||||||
polywp->target = P_FindNewPosition(mobjnum);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -239,6 +239,38 @@ mobj_t *P_GetClosestWaypoint(UINT8 sequence, mobj_t *mo)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return true if all waypoints are in the same location
|
||||||
|
boolean P_IsDegeneratedWaypointSequence(UINT8 sequence)
|
||||||
|
{
|
||||||
|
mobj_t *first, *waypoint;
|
||||||
|
UINT8 wp;
|
||||||
|
|
||||||
|
if (numwaypoints[sequence] <= 1)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
first = waypoints[sequence][0];
|
||||||
|
|
||||||
|
for (wp = 1; wp < numwaypoints[sequence]; wp++)
|
||||||
|
{
|
||||||
|
waypoint = waypoints[sequence][wp];
|
||||||
|
|
||||||
|
if (!waypoint)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (waypoint->x != first->x)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (waypoint->y != first->y)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (waypoint->z != first->z)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Logs an error about a map being corrupt, then terminate.
|
/** Logs an error about a map being corrupt, then terminate.
|
||||||
* This allows reporting highly technical errors for usefulness, without
|
* This allows reporting highly technical errors for usefulness, without
|
||||||
* confusing a novice map designer who simply needs to run ZenNode.
|
* confusing a novice map designer who simply needs to run ZenNode.
|
||||||
|
|
19
src/p_spec.c
19
src/p_spec.c
|
@ -1276,10 +1276,21 @@ static boolean PolyWaypoint(line_t *line)
|
||||||
pwd.polyObjNum = line->tag;
|
pwd.polyObjNum = line->tag;
|
||||||
pwd.speed = sides[line->sidenum[0]].textureoffset / 8;
|
pwd.speed = sides[line->sidenum[0]].textureoffset / 8;
|
||||||
pwd.sequence = sides[line->sidenum[0]].rowoffset >> FRACBITS; // Sequence #
|
pwd.sequence = sides[line->sidenum[0]].rowoffset >> FRACBITS; // Sequence #
|
||||||
pwd.reverse = (line->flags & ML_EFFECT1) == ML_EFFECT1; // Reverse?
|
|
||||||
pwd.comeback = (line->flags & ML_EFFECT2) == ML_EFFECT2; // Return when reaching end?
|
// Behavior after reaching the last waypoint?
|
||||||
pwd.wrap = (line->flags & ML_EFFECT3) == ML_EFFECT3; // Wrap around waypoints
|
if (line->flags & ML_EFFECT3)
|
||||||
pwd.continuous = (line->flags & ML_EFFECT4) == ML_EFFECT4; // Continuously move - used with COMEBACK or WRAP
|
pwd.returnbehavior = PWR_WRAP; // Wrap back to first waypoint
|
||||||
|
else if (line->flags & ML_EFFECT2)
|
||||||
|
pwd.returnbehavior = PWR_COMEBACK; // Go through sequence in reverse
|
||||||
|
else
|
||||||
|
pwd.returnbehavior = PWR_STOP; // Stop
|
||||||
|
|
||||||
|
// Flags
|
||||||
|
pwd.flags = 0;
|
||||||
|
if (line->flags & ML_EFFECT1)
|
||||||
|
pwd.flags |= PWF_REVERSE;
|
||||||
|
if (line->flags & ML_EFFECT4)
|
||||||
|
pwd.flags |= PWF_LOOP;
|
||||||
|
|
||||||
return EV_DoPolyObjWaypoint(&pwd);
|
return EV_DoPolyObjWaypoint(&pwd);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue