From 89a2f8ec8d4746c5f836228a6ca4ce29d0f9d26f Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 4 Apr 2020 01:20:38 -0700 Subject: [PATCH] Thing type 2002, MT_WAYPOINT_RISER - Raise tagged waypoints in sector to FOF sorted by height Thing height refers to the index of FOF. FOF are sorted by top height, lowest to highest. Set Object Flip to sort highest to lowest. If the waypoint thing set Object Flip, it will be placed on the bottom of the FOF. The sorting remains the same though. Set Ambush to raise the waypoint to the same z position. --- src/dehacked.c | 1 + src/info.c | 27 +++++++++++++++ src/info.h | 1 + src/k_waypoint.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ src/k_waypoint.h | 12 ++++++- src/p_local.h | 6 ++++ src/p_map.c | 48 +++++++++++++++++++++++++++ src/p_mobj.c | 5 +++ src/p_setup.c | 6 ++++ src/p_slopes.c | 1 - src/p_spec.c | 37 +++++++++++++++++++++ src/r_defs.h | 8 +++++ 12 files changed, 236 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 60d61903a..ab3340ed1 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7898,6 +7898,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_DEZLASER", "MT_WAYPOINT", + "MT_WAYPOINT_RISER", "MT_RANDOMAUDIENCE", diff --git a/src/info.c b/src/info.c index 9c9759f31..298ca2c8c 100644 --- a/src/info.c +++ b/src/info.c @@ -16528,6 +16528,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_WAYPOINT_RISER + 2002, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 100, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 1*FRACUNIT, // radius + 2*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + { // MT_RANDOMAUDIENCE 1488, // doomednum S_RANDOMAUDIENCE, // spawnstate diff --git a/src/info.h b/src/info.h index ca2f71def..5cb0a8a45 100644 --- a/src/info.h +++ b/src/info.h @@ -4829,6 +4829,7 @@ typedef enum mobj_type MT_DEZLASER, MT_WAYPOINT, + MT_WAYPOINT_RISER, MT_RANDOMAUDIENCE, diff --git a/src/k_waypoint.c b/src/k_waypoint.c index a70e3a249..fc9a7ce1d 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -16,6 +16,7 @@ #include "d_netcmd.h" #include "p_local.h" #include "p_tick.h" +#include "r_state.h" #include "z_zone.h" #include "g_game.h" @@ -1770,3 +1771,88 @@ void K_ClearWaypoints(void) numwaypointmobjs = 0U; circuitlength = 0U; } + +/*-------------------------------------------------- + void K_AdjustWaypointsParameters(void) + + See header file for description. +--------------------------------------------------*/ + +void K_AdjustWaypointsParameters (void) +{ + mobj_t *waypointmobj; + mobj_t *riser; + + fixed_t x; + fixed_t y; + + sector_t *sector; + ffloor_t *rover; + + boolean descending; + + UINT16 fof_no; + + for ( + waypointmobj = waypointcap; + waypointmobj; + waypointmobj = waypointmobj->tracer + ){ + sector = waypointmobj->subsector->sector; + + for ( + riser = sector->thinglist; + riser; + riser = riser->snext + ){ + if ( + riser->type == MT_WAYPOINT_RISER && + riser->spawnpoint->angle == waypointmobj->spawnpoint->angle + ){ + if (( riser->spawnpoint->options & MTF_AMBUSH )) + { + waypointmobj->z = riser->z; + } + else + { + descending = ( riser->spawnpoint->options & MTF_OBJECTFLIP ); + + fof_no = ( riser->spawnpoint->options >> ZSHIFT ); + + if (descending) + rover = sector->highest_ffloor; + else + rover = sector->lowest_ffloor; + + while (rover) + { + if (fof_no > 0) + { + if (descending) + rover = rover->lower; + else + rover = rover->higher; + + fof_no--; + } + else + { + x = waypointmobj->x; + y = waypointmobj->y; + + if (( waypointmobj->flags2 & MF2_OBJECTFLIP )) + { + waypointmobj->z = P_GetFOFBottomZAt(rover, x, y) - + waypointmobj->info->height; + } + else + waypointmobj->z = P_GetFOFTopZAt(rover, x, y); + + break; + } + } + } + } + } + } +} diff --git a/src/k_waypoint.h b/src/k_waypoint.h index f1a678603..0017c443e 100644 --- a/src/k_waypoint.h +++ b/src/k_waypoint.h @@ -345,4 +345,14 @@ boolean K_SetupWaypointList(void); void K_ClearWaypoints(void); -#endif \ No newline at end of file +/*-------------------------------------------------- + void K_AdjustWaypointsParameters(void) + + Adjusts waypoint parameters after P_SpawnSpecials. This is for + raising waypoints to an FOF, which requires that the FOF is + already spawned. +--------------------------------------------------*/ + +void K_AdjustWaypointsParameters (void); + +#endif diff --git a/src/p_local.h b/src/p_local.h index 0d7d3ec3e..a45119a18 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -355,6 +355,12 @@ boolean PIT_PushableMoved(mobj_t *thing); boolean P_DoSpring(mobj_t *spring, mobj_t *object); +fixed_t P_GetFOFTopZAt (ffloor_t *rover, fixed_t x, fixed_t y); +fixed_t P_GetFOFBottomZAt (ffloor_t *rover, fixed_t x, fixed_t y); + +fixed_t P_VeryTopOfFOF (ffloor_t *rover); +fixed_t P_VeryBottomOfFOF (ffloor_t *rover); + // // P_SETUP // diff --git a/src/p_map.c b/src/p_map.c index 9a3864f2c..a6306bb19 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -4749,3 +4749,51 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) return floorz; } + +fixed_t +P_GetFOFTopZAt (ffloor_t *rover, fixed_t x, fixed_t y) +{ + (void)x; + (void)y; +#ifdef ESLOPE + if (*rover->t_slope) + return P_GetZAt(*rover->t_slope, x, y); + else +#endif + return *rover->topheight; +} + +fixed_t +P_GetFOFBottomZAt (ffloor_t *rover, fixed_t x, fixed_t y) +{ + (void)x; + (void)y; +#ifdef ESLOPE + if (*rover->b_slope) + return P_GetZAt(*rover->b_slope, x, y); + else +#endif + return *rover->bottomheight; +} + +fixed_t +P_VeryTopOfFOF (ffloor_t *rover) +{ +#ifdef ESLOPE + if (*rover->t_slope) + return (*rover->t_slope)->highz; + else +#endif + return *rover->topheight; +} + +fixed_t +P_VeryBottomOfFOF (ffloor_t *rover) +{ +#ifdef ESLOPE + if (*rover->b_slope) + return (*rover->b_slope)->lowz; + else +#endif + return *rover->bottomheight; +} diff --git a/src/p_mobj.c b/src/p_mobj.c index 2a12dcc7a..a989b0019 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12324,6 +12324,11 @@ void P_SpawnMapThing(mapthing_t *mthing) y = mthing->y << FRACBITS; ss = R_PointInSubsector(x, y); + if (i == MT_WAYPOINT_RISER) + { + ss->sector->ffloor_sorting = true; + } + if (i == MT_NIGHTSBUMPER) z = ( #ifdef ESLOPE diff --git a/src/p_setup.c b/src/p_setup.c index 40ea643b7..0eb4abc5c 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -741,6 +741,10 @@ static void P_LoadRawSectors(UINT8 *data, size_t i) ss->maxattached = 1; ss->moved = true; + ss->ffloor_sorting = false; + ss->lowest_ffloor = NULL; + ss->highest_ffloor = NULL; + ss->extra_colormap = NULL; ss->floor_xoffs = ss->ceiling_xoffs = ss->floor_yoffs = ss->ceiling_yoffs = 0; @@ -3126,6 +3130,8 @@ boolean P_SetupLevel(boolean skipprecip) // set up world state P_SpawnSpecials(fromnetsave); + K_AdjustWaypointsParameters(); + if (loadprecip) // ugly hack for P_NetUnArchiveMisc (and P_LoadNetGame) P_SpawnPrecipitation(); diff --git a/src/p_slopes.c b/src/p_slopes.c index e623b6f19..6c6842458 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -757,7 +757,6 @@ fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y) return slope->o.z + FixedMul(dist, slope->zdelta); } - // // P_QuantizeMomentumToSlope // diff --git a/src/p_spec.c b/src/p_spec.c index 0e182fa18..158f44dda 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5150,14 +5150,51 @@ static inline void P_AddFFloorToList(sector_t *sec, ffloor_t *ffloor) { ffloor_t *rover; + fixed_t top; + if (!sec->ffloors) { sec->ffloors = ffloor; + if (sec->ffloor_sorting) + { + sec->lowest_ffloor = ffloor; + sec->highest_ffloor = ffloor; + } ffloor->next = 0; ffloor->prev = 0; return; } + if (sec->ffloor_sorting) + { + top = P_VeryTopOfFOF(ffloor); + + for (rover = sec->lowest_ffloor; rover; rover = rover->higher) + { + if (top < P_VeryTopOfFOF(rover)) + break; + } + + if (rover) + { + if (rover->lower) + rover->lower->higher = ffloor; + else + sec->lowest_ffloor = ffloor; + + ffloor->lower = rover->lower; + ffloor->higher = rover; + + rover->lower = ffloor; + } + else + { + sec->highest_ffloor->higher = ffloor; + ffloor->lower = sec->highest_ffloor; + sec->highest_ffloor = ffloor; + } + } + for (rover = sec->ffloors; rover->next; rover = rover->next); rover->next = ffloor; diff --git a/src/r_defs.h b/src/r_defs.h index c8a72044d..399dec087 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -170,6 +170,10 @@ typedef struct ffloor_s struct ffloor_s *next; struct ffloor_s *prev; + /* if sector->ffloor_sorting */ + struct ffloor_s *higher;/* by top height */ + struct ffloor_s *lower;/* by bottom height */ + INT32 lastlight; INT32 alpha; tic_t norender; // for culling @@ -347,6 +351,10 @@ typedef struct sector_s INT32 numlights; boolean moved; + boolean ffloor_sorting; + ffloor_t *lowest_ffloor; + ffloor_t *highest_ffloor; + // per-sector colormaps! extracolormap_t *extra_colormap;