diff --git a/src/doomdata.h b/src/doomdata.h index 6319238b7..aa4ea1a54 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -46,6 +46,9 @@ enum ML_BLOCKMAP, // LUT, motion clipping, walls/grid element }; +// Extra flag for objects +#define MTF_EXTRA 1 + // Reverse gravity flag for objects. #define MTF_OBJECTFLIP 2 diff --git a/src/k_waypoint.c b/src/k_waypoint.c index 13a203c07..d179d68c2 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -20,12 +20,49 @@ static const size_t NODESARRAY_BASE_SIZE = 256U; static waypoint_t **waypointheap = NULL; static waypoint_t *firstwaypoint = NULL; +static waypoint_t *finishline = NULL; static size_t numwaypoints = 0U; static size_t numwaypointmobjs = 0U; static size_t baseopensetsize = OPENSET_BASE_SIZE; static size_t baseclosedsetsize = CLOSEDSET_BASE_SIZE; static size_t basenodesarraysize = NODESARRAY_BASE_SIZE; + +/*-------------------------------------------------- + waypoint_t *K_GetFinishLineWaypoint(void) + + See header file for description. +--------------------------------------------------*/ +waypoint_t *K_GetFinishLineWaypoint(void) +{ + return finishline; +} + +/*-------------------------------------------------- + boolean K_GetWaypointIsFinishline(waypoint_t *waypoint) + + See header file for description. +--------------------------------------------------*/ +boolean K_GetWaypointIsFinishline(waypoint_t *waypoint) +{ + boolean waypointisfinishline = false; + + if (waypoint == NULL) + { + CONS_Debug(DBG_GAMELOGIC, "NULL waypoint in K_GetWaypointIsShortcut.\n"); + } + else if (waypoint->mobj == NULL) + { + CONS_Debug(DBG_GAMELOGIC, "NULL waypoint mobj in K_GetWaypointIsShortcut.\n"); + } + else + { + waypointisfinishline = (waypoint->mobj->extravalue2 == 1); + } + + return waypointisfinishline; +} + /*-------------------------------------------------- boolean K_GetWaypointIsShortcut(waypoint_t *waypoint) @@ -45,7 +82,7 @@ boolean K_GetWaypointIsShortcut(waypoint_t *waypoint) } else { - // TODO + waypointisshortcut = (waypoint->mobj->lastlook == 1); } return waypointisshortcut; @@ -58,7 +95,7 @@ boolean K_GetWaypointIsShortcut(waypoint_t *waypoint) --------------------------------------------------*/ boolean K_GetWaypointIsEnabled(waypoint_t *waypoint) { - boolean waypointisshortcut = true; + boolean waypointisenabled = true; if (waypoint == NULL) { @@ -70,10 +107,10 @@ boolean K_GetWaypointIsEnabled(waypoint_t *waypoint) } else { - // TODO + waypointisenabled = (waypoint->mobj->extravalue1 == 1); } - return waypointisshortcut; + return waypointisenabled; } /*-------------------------------------------------- @@ -1581,6 +1618,19 @@ static waypoint_t *K_SetupWaypoint(mobj_t *const mobj) firstwaypoint = thiswaypoint; } + if (K_GetWaypointIsFinishline(thiswaypoint)) + { + if (finishline != NULL) + { + const INT32 oldfinishlineid = K_GetWaypointID(finishline); + const INT32 thiswaypointid = K_GetWaypointID(thiswaypoint); + CONS_Alert( + CONS_WARNING, "Multiple finish line waypoints with IDs %d and %d! Using %d.", + oldfinishlineid, thiswaypointid, thiswaypointid); + } + finishline = thiswaypoint; + } + if (thiswaypoint->numnextwaypoints > 0) { waypoint_t *nextwaypoint = NULL; @@ -1747,18 +1797,19 @@ boolean K_SetupWaypointList(void) K_SetupWaypoint(waypointmobj); } - if (!firstwaypoint) + if (firstwaypoint == NULL) { CONS_Alert(CONS_ERROR, "No waypoints in map.\n"); } else { CONS_Debug(DBG_SETUP, "Successfully setup %zu waypoints.\n", numwaypoints); - if (numwaypoints < numwaypointmobjs) + if (finishline == NULL) { - CONS_Alert(CONS_WARNING, - "Not all waypoints in the map are connected! %zu waypoints setup but %zu waypoint mobjs.\n", - numwaypoints, numwaypointmobjs); + CONS_Alert( + CONS_WARNING, "No finish line waypoint in the map! Using first setup waypoint with ID %d.\n", + K_GetWaypointID(firstwaypoint)); + finishline = firstwaypoint; } setupsuccessful = true; } @@ -1775,8 +1826,9 @@ boolean K_SetupWaypointList(void) --------------------------------------------------*/ void K_ClearWaypoints(void) { - waypointheap = NULL; - firstwaypoint = NULL; - numwaypoints = 0; + waypointheap = NULL; + firstwaypoint = NULL; + finishline = NULL; + numwaypoints = 0; numwaypointmobjs = 0; } diff --git a/src/k_waypoint.h b/src/k_waypoint.h index c54cb439e..f93df802f 100644 --- a/src/k_waypoint.h +++ b/src/k_waypoint.h @@ -34,6 +34,36 @@ typedef struct path_s { // AVAILABLE FOR LUA +/*-------------------------------------------------- + waypoint_t *K_GetFinishLineWaypoint(void); + + Returns the waypoint actually being used as the finish line. + + Input Arguments:- + None + + Return:- + The waypoint that is being used as the finishline. +--------------------------------------------------*/ + +waypoint_t *K_GetFinishLineWaypoint(void); + + +/*-------------------------------------------------- + boolean K_GetWaypointIsFinishline(waypoint_t *waypoint) + + Returns whether the waypoint is marked as the finishline. This may not actually be the finishline. + + Input Arguments:- + waypoint - The waypoint to return finishline status of. + + Return:- + true if the waypoint is marked as being the finishline, false if it isn't. +--------------------------------------------------*/ + +boolean K_GetWaypointIsFinishline(waypoint_t *waypoint); + + /*-------------------------------------------------- boolean K_GetWaypointIsShortcut(waypoint_t *waypoint) diff --git a/src/p_mobj.c b/src/p_mobj.c index d4fd3c693..ffac8e678 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11805,16 +11805,44 @@ ML_NOCLIMB : Direction not controllable // Use threshold to store the next waypoint ID // movecount is being used for the current waypoint ID // reactiontime lets us know if we can respawn at it + // lastlook is used for indicating the waypoint is a shortcut + // extravalue1 is used for indicating the waypoint is disabled + // extravalue2 is used for indicating the waypoint is the finishline mobj->threshold = ((mthing->options >> ZSHIFT)); mobj->movecount = mthing->angle; + if (mthing->options & MTF_EXTRA) + { + mobj->extravalue1 = 0; // The waypoint is disabled if extra is on + } + else + { + mobj->extravalue1 = 1; + } + if (mthing->options & MTF_OBJECTSPECIAL) + { + mobj->lastlook = 1; // the waypoint is a shortcut if objectspecial is on + } + else + { + mobj->lastlook = 0; + } if (mthing->options & MTF_AMBUSH) { - mobj->reactiontime = 0; // Can't respawn at if Ambush is off + mobj->reactiontime = 0; // Can't respawn at if Ambush is on } else { mobj->reactiontime = 1; } + if (mthing->extrainfo == 1) + { + mobj->extravalue2 = 1; // extrainfo of 1 means the waypoint is at the finish line + } + else + { + mobj->extravalue2 = 0; + } + // Sryder 2018-12-7: Grabbed this from the old MT_BOSS3WAYPOINT section so they'll be in the waypointcap instead P_SetTarget(&mobj->tracer, waypointcap);