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;