From ce7161e81d53774b226d071d3af3b979413f8dc9 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 20 Sep 2020 23:41:18 -0700 Subject: [PATCH 01/10] Check out this massive slopes Line specials 777 - slope floor by anchors, 778 - slope ceiling by anchors, 779 - slope floor and ceiling by anchors. Thing types 777 - floor anchors, 778 - ceiling anchors. Summary. These line specials slope the front or back sector's floor/ceiling by 'anchor' things. Anchors are floor or ceiling specific and snap to the nearest vertex. Using this method it is possible to create seamless slopes, without even tagging. Details. Normal slope flags apply. To slope the backside sector, set No Climb on the line. An anchor each is required to be near three of a sector's vertices in order to slope it. More may be present but the order is undefined. --- src/doomdata.h | 7 + src/p_slopes.c | 14 ++ src/p_spec.h | 8 ++ src/slope_anchors.c | 341 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 370 insertions(+) create mode 100644 src/slope_anchors.c diff --git a/src/doomdata.h b/src/doomdata.h index 767e47383..f42b13889 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -215,4 +215,11 @@ typedef struct #define NUMMAPS 1035 +/* slope thing types */ +enum +{ + FLOOR_SLOPE_THING = 777, + CEILING_SLOPE_THING = 778, +}; + #endif // __DOOMDATA__ diff --git a/src/p_slopes.c b/src/p_slopes.c index d90b583c5..2102dd7b2 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -24,6 +24,9 @@ #include "w_wad.h" #include "k_kart.h" // K_PlayerEBrake +static void P_BuildSlopeAnchorList (void); +static void P_SetupAnchoredSlopes (void); + static pslope_t *slopelist = NULL; static UINT16 slopecount = 0; @@ -731,6 +734,14 @@ void P_ResetDynamicSlopes(void) { } } + // jart + + /// Build list of slope anchors--faster searching. + P_BuildSlopeAnchorList(); + + /// Setup anchor based slopes. + P_SetupAnchoredSlopes(); + /// Copies slopes from tagged sectors via line specials. /// \note Doesn't actually copy, but instead they share the same pointers. for (i = 0; i < numlines; i++) @@ -920,5 +931,8 @@ void P_ButteredSlope(mobj_t *mo) P_Thrust(mo, mo->standingslope->xydirection, thrust); } +// jart +#include "slope_anchors.c" + // EOF #endif // #ifdef ESLOPE diff --git a/src/p_spec.h b/src/p_spec.h index 6c918ef11..6c85c6d1a 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -461,4 +461,12 @@ void P_CalcHeight(player_t *player); sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo); +/* line specials */ +enum +{ + LT_SLOPE_ANCHORS_FLOOR = 777, + LT_SLOPE_ANCHORS_CEILING = 778, + LT_SLOPE_ANCHORS = 779, +}; + #endif diff --git a/src/slope_anchors.c b/src/slope_anchors.c new file mode 100644 index 000000000..270707577 --- /dev/null +++ b/src/slope_anchors.c @@ -0,0 +1,341 @@ +// SONIC ROBO BLAST 2 KART +//----------------------------------------------------------------------------- +// Copyright (C) 2020 by James R. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \brief Charyb's vertex slope anchors. +/// This file is self contained to avoid a Big Large merge conflict. + +/* +FIXME +FIXME +FIXME +FIXME WHEN 2.2 MERGE IS OVER, REFACTOR A LOT OF THE CODE IN P_SLOPES.C AND +FIXME MAKE THIS NOT REDUNDANT. +FIXME +FIXME +FIXME +*/ + +struct anchor_list +{ + mapthing_t ** anchors; + const vertex_t ** points; + size_t count; +}; + +struct anchor_list floor_anchors; +struct anchor_list ceiling_anchors; + +static void * new_list (size_t n) { + return Z_Malloc(n, PU_LEVEL, NULL); +} + +static void make_new_anchor_list (struct anchor_list * list) { + list->anchors = new_list(list->count * sizeof *list->anchors); + list->points = new_list(list->count * sizeof *list->points); +} + +static void allocate_anchors (void) { + size_t i; + + floor_anchors.count = 0; + ceiling_anchors.count = 0; + + for (i = 0; i < nummapthings; ++i) + { + switch (mapthings[i].type) + { + case FLOOR_SLOPE_THING: + floor_anchors.count++; + break; + + case CEILING_SLOPE_THING: + ceiling_anchors.count++; + break; + } + } + + make_new_anchor_list(&floor_anchors); + make_new_anchor_list(&ceiling_anchors); +} + +static const vertex_t * +nearest_point +( + mapthing_t * a, + const subsector_t * sub +){ + const fixed_t x = a->x << FRACBITS; + const fixed_t y = a->y << FRACBITS; + + const UINT16 lastline = sub->firstline + sub->numlines; + + vertex_t * nearest = NULL;/* shut compiler up, but should never be NULL */ + fixed_t nearest_distance = INT32_MAX; + + vertex_t * v = NULL; + + fixed_t distance; + + UINT16 i; + + for (i = sub->firstline; i < lastline; ++i) + { + if (segs[i].v1 != v) + { + v = segs[i].v1; + } + else + { + v = segs[i].v2; + } + + distance = abs(P_AproxDistance(( x - v->x ), ( y - v->y ))); + + if (distance < nearest_distance) + { + nearest = v; + nearest_distance = distance; + } + } + + return nearest; +} + +static INT16 +anchor_height +( + const mapthing_t * a, + const sector_t * s +){ + if (a->extrainfo) + { + return a->options; + } + else + { + INT16 z = ( a->options >> ZSHIFT ); + + if (a->options & MTF_OBJECTFLIP) + { + return ( s->ceilingheight >> FRACBITS ) - z; + } + else + { + return ( s->floorheight >> FRACBITS ) + z; + } + } +} + +static void +set_anchor +( + struct anchor_list * list, + mapthing_t * a +){ + const subsector_t * sub = R_PointInSubsector + ( + a->x << FRACBITS, + a->y << FRACBITS + ); + + const vertex_t * v; + + a->z = anchor_height(a, sub->sector); + + v = nearest_point(a, sub); + + a->x = ( v->x >> FRACBITS ); + a->y = ( v->y >> FRACBITS ); + + list->anchors[list->count] = a; + list->points [list->count] = v; + + list->count++; +} + +static void build_anchors (void) { + size_t i; + + floor_anchors.count = 0; + ceiling_anchors.count = 0; + + for (i = 0; i < nummapthings; ++i) + { + switch (mapthings[i].type) + { + case FLOOR_SLOPE_THING: + set_anchor(&floor_anchors, &mapthings[i]); + break; + + case CEILING_SLOPE_THING: + set_anchor(&ceiling_anchors, &mapthings[i]); + break; + } + } +} + +static mapthing_t ** +find_closest_anchors +( + const sector_t * sector, + const struct anchor_list * list +){ + mapthing_t ** anchors; + + size_t i; + size_t a; + + vertex_t * v = NULL; + + int next_anchor = 0; + + if (list->count < 3) + { + I_Error("At least three slope anchors are required to make a slope."); + } + + anchors = Z_Malloc(3 * sizeof *anchors, PU_LEVEL, NULL); + + for (i = 0; i < sector->linecount; ++i) + { + if (sector->lines[i]->v1 != v) + { + v = sector->lines[i]->v1; + } + else + { + v = sector->lines[i]->v2; + } + + for (a = 0; a < list->count; ++a) + { + if (list->points[a] == v) + { + anchors[next_anchor] = list->anchors[a]; + + if (++next_anchor == 3) + { + return anchors; + } + } + } + } + + I_Error( + "(Sector #%s)" + " Slope requires anchors near 3 of its vertices (%d found)", + + sizeu1 (sector - sectors), + next_anchor + ); +} + +static pslope_t * +new_vertex_slope +( + mapthing_t ** anchors, + const INT16 flags +){ + pslope_t * slope = Z_Calloc(sizeof (pslope_t), PU_LEVEL, NULL); + + slope->flags = SL_VERTEXSLOPE; + + if (flags & ML_NOSONIC) + { + slope->flags |= SL_NOPHYSICS; + } + + if (flags & ML_NOTAILS) + { + slope->flags |= SL_NODYNAMIC; + } + + slope->vertices = anchors; + + P_ReconfigureVertexSlope(slope); + slope->refpos = 5; + + // Add to the slope list + slope->next = slopelist; + slopelist = slope; + + slopecount++; + slope->id = slopecount; + + return slope; +} + +static void +make_anchored_slope +( + const line_t * line, + const int plane +){ + enum + { + FLOOR = 0x1, + CEILING = 0x2, + }; + + const INT16 flags = line->flags; + + const int side = ( flags & ML_NOCLIMB ) != 0; + + sector_t * sector; + mapthing_t ** anchors; + + if (side == 0 || flags & ML_TWOSIDED) + { + sector = sides[line->sidenum[side]].sector; + + if (plane & FLOOR) + { + anchors = find_closest_anchors(sector, &floor_anchors); + sector->f_slope = new_vertex_slope(anchors, flags); + } + + if (plane & CEILING) + { + anchors = find_closest_anchors(sector, &ceiling_anchors); + sector->c_slope = new_vertex_slope(anchors, flags); + } + + sector->hasslope = true; + } +} + +static void P_BuildSlopeAnchorList (void) { + allocate_anchors(); + build_anchors(); +} + +static void P_SetupAnchoredSlopes (void) { + enum + { + FLOOR = 0x1, + CEILING = 0x2, + }; + + size_t i; + + for (i = 0; i < numlines; ++i) + { + if (lines[i].special == LT_SLOPE_ANCHORS_FLOOR) + { + make_anchored_slope(&lines[i], FLOOR); + } + else if (lines[i].special == LT_SLOPE_ANCHORS_CEILING) + { + make_anchored_slope(&lines[i], CEILING); + } + else if (lines[i].special == LT_SLOPE_ANCHORS) + { + make_anchored_slope(&lines[i], FLOOR|CEILING); + } + } +} From 0999fa7096770b77376503b29f3616bcde4e7d0b Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 21 Sep 2020 19:09:48 -0700 Subject: [PATCH 02/10] Fix vertex iteration and Not Dynamic flag --- src/slope_anchors.c | 117 +++++++++++++++++++++++++++----------------- 1 file changed, 73 insertions(+), 44 deletions(-) diff --git a/src/slope_anchors.c b/src/slope_anchors.c index 270707577..8c8d04e76 100644 --- a/src/slope_anchors.c +++ b/src/slope_anchors.c @@ -63,6 +63,28 @@ static void allocate_anchors (void) { make_new_anchor_list(&ceiling_anchors); } +static void +compare_vertex_distance +( + const vertex_t ** nearest, + fixed_t * nearest_distance, + const fixed_t origin_x, + const fixed_t origin_y, + const vertex_t * v +){ + const fixed_t distance = abs(P_AproxDistance + ( + origin_x - v->x, + origin_y - v->y + )); + + if (distance < (*nearest_distance)) + { + (*nearest) = v; + (*nearest_distance) = distance; + } +} + static const vertex_t * nearest_point ( @@ -74,33 +96,15 @@ nearest_point const UINT16 lastline = sub->firstline + sub->numlines; - vertex_t * nearest = NULL;/* shut compiler up, but should never be NULL */ - fixed_t nearest_distance = INT32_MAX; - - vertex_t * v = NULL; - - fixed_t distance; + const vertex_t * nearest = NULL;/* shut compiler up, should never be NULL */ + fixed_t nearest_distance = INT32_MAX; UINT16 i; for (i = sub->firstline; i < lastline; ++i) { - if (segs[i].v1 != v) - { - v = segs[i].v1; - } - else - { - v = segs[i].v2; - } - - distance = abs(P_AproxDistance(( x - v->x ), ( y - v->y ))); - - if (distance < nearest_distance) - { - nearest = v; - nearest_distance = distance; - } + compare_vertex_distance(&nearest, &nearest_distance, x, y, segs[i].v1); + compare_vertex_distance(&nearest, &nearest_distance, x, y, segs[i].v2); } return nearest; @@ -179,20 +183,57 @@ static void build_anchors (void) { } } +static int +get_anchor +( + const vertex_t * points[3], + mapthing_t ** anchors, + int * last_anchor, + const struct anchor_list * list, + const vertex_t * v +){ + size_t i; + + if ( + v != points[0] && + v != points[1] && + v != points[2] + ){ + for (i = 0; i < list->count; ++i) + { + if (list->points[i] == v) + { + points [*last_anchor] = v; + anchors[*last_anchor] = list->anchors[i]; + + if (++(*last_anchor) == 3) + { + return 1; + } + else + { + return 0; + } + } + } + } + + return 0; +} + static mapthing_t ** find_closest_anchors ( const sector_t * sector, const struct anchor_list * list ){ + const vertex_t * points[3] = {0}; + mapthing_t ** anchors; size_t i; - size_t a; - vertex_t * v = NULL; - - int next_anchor = 0; + int last = 0; if (list->count < 3) { @@ -203,26 +244,14 @@ find_closest_anchors for (i = 0; i < sector->linecount; ++i) { - if (sector->lines[i]->v1 != v) + if (get_anchor(points, anchors, &last, list, sector->lines[i]->v1) != 0) { - v = sector->lines[i]->v1; - } - else - { - v = sector->lines[i]->v2; + return anchors; } - for (a = 0; a < list->count; ++a) + if (get_anchor(points, anchors, &last, list, sector->lines[i]->v2) != 0) { - if (list->points[a] == v) - { - anchors[next_anchor] = list->anchors[a]; - - if (++next_anchor == 3) - { - return anchors; - } - } + return anchors; } } @@ -231,7 +260,7 @@ find_closest_anchors " Slope requires anchors near 3 of its vertices (%d found)", sizeu1 (sector - sectors), - next_anchor + last ); } @@ -250,7 +279,7 @@ new_vertex_slope slope->flags |= SL_NOPHYSICS; } - if (flags & ML_NOTAILS) + if (( flags & ML_NOTAILS ) == 0) { slope->flags |= SL_NODYNAMIC; } From 0cddfdee747ed8702fef8090528e5f330164f14b Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 21 Sep 2020 19:11:13 -0700 Subject: [PATCH 03/10] Ignore slope anchors in P_SpawnMapThing --- src/p_mobj.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index d58772f5c..c309b6a4f 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12072,6 +12072,8 @@ void P_SpawnMapThing(mapthing_t *mthing) else if (mthing->type == 750) // Slope vertex point (formerly chaos spawn) return; + else if (mthing->type == 777 || mthing->type == 778) // Slope anchors + return; else if (mthing->type == 300 // Ring || mthing->type == 308 || mthing->type == 309 // Team Rings From ff7813ef3822f1dafd1b8adfae1dccd87747b276 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 22 Sep 2020 01:30:59 -0700 Subject: [PATCH 04/10] Use sector lines when snapping anchor to point Sometimes segs skip a point! --- src/slope_anchors.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/slope_anchors.c b/src/slope_anchors.c index 8c8d04e76..da2fad2e8 100644 --- a/src/slope_anchors.c +++ b/src/slope_anchors.c @@ -89,22 +89,20 @@ static const vertex_t * nearest_point ( mapthing_t * a, - const subsector_t * sub + const sector_t * sector ){ const fixed_t x = a->x << FRACBITS; const fixed_t y = a->y << FRACBITS; - const UINT16 lastline = sub->firstline + sub->numlines; - const vertex_t * nearest = NULL;/* shut compiler up, should never be NULL */ fixed_t nearest_distance = INT32_MAX; - UINT16 i; + size_t i; - for (i = sub->firstline; i < lastline; ++i) + for (i = 0; i < sector->linecount; ++i) { - compare_vertex_distance(&nearest, &nearest_distance, x, y, segs[i].v1); - compare_vertex_distance(&nearest, &nearest_distance, x, y, segs[i].v2); + compare_vertex_distance(&nearest, &nearest_distance, x, y, sector->lines[i]->v1); + compare_vertex_distance(&nearest, &nearest_distance, x, y, sector->lines[i]->v2); } return nearest; @@ -151,7 +149,7 @@ set_anchor a->z = anchor_height(a, sub->sector); - v = nearest_point(a, sub); + v = nearest_point(a, sub->sector); a->x = ( v->x >> FRACBITS ); a->y = ( v->y >> FRACBITS ); From b35e2ac9b3bb4f12e1f172929416d7bc5294ebc8 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 23 Sep 2020 23:17:05 -0700 Subject: [PATCH 05/10] Use the closest of three slope anchors to their respective vertices Previously it just used the first three anchors that had snapped to a vertex in the sector. btw fuck DOOM --- src/slope_anchors.c | 118 ++++++++++++++++++++++++++++---------------- 1 file changed, 76 insertions(+), 42 deletions(-) diff --git a/src/slope_anchors.c b/src/slope_anchors.c index da2fad2e8..0102b68bf 100644 --- a/src/slope_anchors.c +++ b/src/slope_anchors.c @@ -24,6 +24,7 @@ struct anchor_list { mapthing_t ** anchors; const vertex_t ** points; + fixed_t * closeness; size_t count; }; @@ -35,8 +36,9 @@ static void * new_list (size_t n) { } static void make_new_anchor_list (struct anchor_list * list) { - list->anchors = new_list(list->count * sizeof *list->anchors); - list->points = new_list(list->count * sizeof *list->points); + list->anchors = new_list(list->count * sizeof *list->anchors); + list->points = new_list(list->count * sizeof *list->points); + list->closeness = new_list(list->count * sizeof *list->closeness); } static void allocate_anchors (void) { @@ -88,24 +90,26 @@ compare_vertex_distance static const vertex_t * nearest_point ( + fixed_t * closeness, mapthing_t * a, const sector_t * sector ){ const fixed_t x = a->x << FRACBITS; const fixed_t y = a->y << FRACBITS; - const vertex_t * nearest = NULL;/* shut compiler up, should never be NULL */ - fixed_t nearest_distance = INT32_MAX; + const vertex_t * v = NULL;/* shut compiler up, should never be NULL */ size_t i; + (*closeness) = INT32_MAX; + for (i = 0; i < sector->linecount; ++i) { - compare_vertex_distance(&nearest, &nearest_distance, x, y, sector->lines[i]->v1); - compare_vertex_distance(&nearest, &nearest_distance, x, y, sector->lines[i]->v2); + compare_vertex_distance(&v, closeness, x, y, sector->lines[i]->v1); + compare_vertex_distance(&v, closeness, x, y, sector->lines[i]->v2); } - return nearest; + return v; } static INT16 @@ -147,15 +151,18 @@ set_anchor const vertex_t * v; + fixed_t closeness; + a->z = anchor_height(a, sub->sector); - v = nearest_point(a, sub->sector); + v = nearest_point(&closeness, a, sub->sector); a->x = ( v->x >> FRACBITS ); a->y = ( v->y >> FRACBITS ); - list->anchors[list->count] = a; - list->points [list->count] = v; + list->anchors [list->count] = a; + list->points [list->count] = v; + list->closeness[list->count] = closeness; list->count++; } @@ -181,42 +188,70 @@ static void build_anchors (void) { } } -static int +static void get_anchor ( - const vertex_t * points[3], mapthing_t ** anchors, - int * last_anchor, + fixed_t distances[3], const struct anchor_list * list, const vertex_t * v ){ size_t i; - if ( - v != points[0] && - v != points[1] && - v != points[2] - ){ - for (i = 0; i < list->count; ++i) - { - if (list->points[i] == v) - { - points [*last_anchor] = v; - anchors[*last_anchor] = list->anchors[i]; + int k; - if (++(*last_anchor) == 3) + for (i = 0; i < list->count; ++i) + { + if (list->points[i] == v) + { + for (k = 0; k < 3; ++k) + { + if (list->closeness[i] < distances[k]) { - return 1; + if (k == 0) + { + distances[2] = distances[1]; + distances[1] = distances[0]; + + anchors [2] = anchors [1]; + anchors [1] = anchors [0]; + } + else if (k == 1) + { + distances[2] = distances[1]; + anchors [2] = anchors [1]; + } + + distances[k] = list->closeness[i]; + + anchors[k] = list->anchors[i]; + + break; } - else + else if (list->anchors[i] == anchors[k]) { - return 0; + break; } } } } +} - return 0; +static void +get_sector_anchors +( + mapthing_t ** anchors, + fixed_t distances[3], + const struct anchor_list * list, + const sector_t * sector +){ + size_t i; + + for (i = 0; i < sector->linecount; ++i) + { + get_anchor(anchors, distances, list, sector->lines[i]->v1); + get_anchor(anchors, distances, list, sector->lines[i]->v2); + } } static mapthing_t ** @@ -225,12 +260,10 @@ find_closest_anchors const sector_t * sector, const struct anchor_list * list ){ - const vertex_t * points[3] = {0}; + fixed_t distances[3] = { INT32_MAX, INT32_MAX, INT32_MAX }; mapthing_t ** anchors; - size_t i; - int last = 0; if (list->count < 3) @@ -240,19 +273,20 @@ find_closest_anchors anchors = Z_Malloc(3 * sizeof *anchors, PU_LEVEL, NULL); - for (i = 0; i < sector->linecount; ++i) - { - if (get_anchor(points, anchors, &last, list, sector->lines[i]->v1) != 0) - { - return anchors; - } + get_sector_anchors(anchors, distances, list, sector); - if (get_anchor(points, anchors, &last, list, sector->lines[i]->v2) != 0) - { - return anchors; - } + if (distances[2] < INT32_MAX) + { + return anchors; } + if (distances[1] < INT32_MAX) + last = 2; + else if (distances[0] < INT32_MAX) + last = 1; + else + last = 0; + I_Error( "(Sector #%s)" " Slope requires anchors near 3 of its vertices (%d found)", From 388d56a5f8a5eb9983700a3b9820aa3a015d2e94 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 24 Sep 2020 01:56:03 -0700 Subject: [PATCH 06/10] Search FOF target sectors for slope anchors Requires spawning fake floors before slopes, and therefore before things, basically before everything. Hopefully nothing breaks! --- src/p_setup.c | 9 +++++--- src/p_spec.c | 36 +++++++++++++++++--------------- src/p_spec.h | 1 + src/slope_anchors.c | 50 ++++++++++++++++++++++++++++++++++++++------- 4 files changed, 70 insertions(+), 26 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index c2af9b3b2..51bdbce89 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3206,19 +3206,22 @@ boolean P_SetupLevel(boolean skipprecip) // anything that P_ResetDynamicSlopes/P_LoadThings needs to know P_InitSpecials(); + // set up world state + // jart: needs to be done here so anchored slopes know the attached list + P_SpawnSpecials(fromnetsave); + P_ResetDynamicSlopes(); P_LoadThings(); + P_RaiseThings(); + P_SpawnSecretItems(loademblems); for (numcoopstarts = 0; numcoopstarts < MAXPLAYERS; numcoopstarts++) if (!playerstarts[numcoopstarts]) break; - // set up world state - P_SpawnSpecials(fromnetsave); - K_AdjustWaypointsParameters(); if (loadprecip) // ugly hack for P_NetUnArchiveMisc (and P_LoadNetGame) diff --git a/src/p_spec.c b/src/p_spec.c index 4c86714eb..47e476478 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5358,6 +5358,26 @@ P_RaiseTaggedThingsToFakeFloor ( } } +void +P_RaiseThings (void) +{ + size_t i; + + for (i = 0; i < numlines; ++i) + { + switch (lines[i].special) + { + case 80: // Raise tagged things by type to this FOF + P_RaiseTaggedThingsToFakeFloor( + ( sides[lines[i].sidenum[0]].textureoffset >> FRACBITS ), + lines[i].tag, + lines[i].frontsector + ); + break; + } + } +} + // // SPECIAL SPAWNING // @@ -6822,22 +6842,6 @@ void P_SpawnSpecials(INT32 fromnetsave) } } - /* some things have to be done after FOF spawn */ - - for (i = 0; i < numlines; ++i) - { - switch (lines[i].special) - { - case 80: // Raise tagged things by type to this FOF - P_RaiseTaggedThingsToFakeFloor( - ( sides[lines[i].sidenum[0]].textureoffset >> FRACBITS ), - lines[i].tag, - lines[i].frontsector - ); - break; - } - } - // Allocate each list for (i = 0; i < numsectors; i++) if(secthinkers[i].thinkers) diff --git a/src/p_spec.h b/src/p_spec.h index 6c85c6d1a..ea497fb19 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -38,6 +38,7 @@ void P_SetupLevelFlatAnims(void); // at map load void P_InitSpecials(void); void P_SpawnSpecials(INT32 fromnetsave); +void P_RaiseThings(void); // every tic void P_UpdateSpecials(void); diff --git a/src/slope_anchors.c b/src/slope_anchors.c index 0102b68bf..ff1504a37 100644 --- a/src/slope_anchors.c +++ b/src/slope_anchors.c @@ -266,6 +266,8 @@ find_closest_anchors int last = 0; + size_t i; + if (list->count < 3) { I_Error("At least three slope anchors are required to make a slope."); @@ -273,7 +275,18 @@ find_closest_anchors anchors = Z_Malloc(3 * sizeof *anchors, PU_LEVEL, NULL); - get_sector_anchors(anchors, distances, list, sector); + if (sector->numattached > 0) + { + for (i = 0; i < sector->numattached; ++i) + { + get_sector_anchors + (anchors, distances, list, §ors[sector->attached[i]]); + } + } + else + { + get_sector_anchors(anchors, distances, list, sector); + } if (distances[2] < INT32_MAX) { @@ -287,13 +300,36 @@ find_closest_anchors else last = 0; - I_Error( - "(Sector #%s)" - " Slope requires anchors near 3 of its vertices (%d found)", + if (sector->numattached > 0) + { + CONS_Printf("\nSearched for anchors in sectors...\n\n"); - sizeu1 (sector - sectors), - last - ); + for (i = 0; i < sector->numattached; ++i) + { + CONS_Printf("#%s\n", sizeu1 (sector->attached[i])); + } + + I_Error( + "(Control Sector #%s)" + " Slope requires anchors near 3 of its target sectors' vertices" + " (%d found)" + + "\n\nCheck the log to see which sectors were searched.", + + sizeu1 (sector - sectors), + last + ); + } + else + { + I_Error( + "(Sector #%s)" + " Slope requires anchors near 3 of its vertices (%d found)", + + sizeu1 (sector - sectors), + last + ); + } } static pslope_t * From 1403c49f501c75a6f20878b560d83f7871baf815 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 24 Sep 2020 03:18:31 -0700 Subject: [PATCH 07/10] Use Parameter on slope anchors as a tag This makes FOF sloping over other slopes possible! Had to remove the absolute height function though. --- src/slope_anchors.c | 58 +++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/src/slope_anchors.c b/src/slope_anchors.c index ff1504a37..add9a33b7 100644 --- a/src/slope_anchors.c +++ b/src/slope_anchors.c @@ -118,11 +118,6 @@ anchor_height const mapthing_t * a, const sector_t * s ){ - if (a->extrainfo) - { - return a->options; - } - else { INT16 z = ( a->options >> ZSHIFT ); @@ -194,6 +189,7 @@ get_anchor mapthing_t ** anchors, fixed_t distances[3], const struct anchor_list * list, + const INT16 tag, const vertex_t * v ){ size_t i; @@ -202,7 +198,7 @@ get_anchor for (i = 0; i < list->count; ++i) { - if (list->points[i] == v) + if (list->points[i] == v && list->anchors[i]->extrainfo == tag) { for (k = 0; k < 3; ++k) { @@ -243,14 +239,15 @@ get_sector_anchors mapthing_t ** anchors, fixed_t distances[3], const struct anchor_list * list, + const INT16 tag, const sector_t * sector ){ size_t i; for (i = 0; i < sector->linecount; ++i) { - get_anchor(anchors, distances, list, sector->lines[i]->v1); - get_anchor(anchors, distances, list, sector->lines[i]->v2); + get_anchor(anchors, distances, list, tag, sector->lines[i]->v1); + get_anchor(anchors, distances, list, tag, sector->lines[i]->v2); } } @@ -258,7 +255,8 @@ static mapthing_t ** find_closest_anchors ( const sector_t * sector, - const struct anchor_list * list + const struct anchor_list * list, + const INT16 tag ){ fixed_t distances[3] = { INT32_MAX, INT32_MAX, INT32_MAX }; @@ -280,12 +278,12 @@ find_closest_anchors for (i = 0; i < sector->numattached; ++i) { get_sector_anchors - (anchors, distances, list, §ors[sector->attached[i]]); + (anchors, distances, list, tag, §ors[sector->attached[i]]); } } else { - get_sector_anchors(anchors, distances, list, sector); + get_sector_anchors(anchors, distances, list, tag, sector); } if (distances[2] < INT32_MAX) @@ -311,12 +309,13 @@ find_closest_anchors I_Error( "(Control Sector #%s)" - " Slope requires anchors near 3 of its target sectors' vertices" - " (%d found)" + " Slope requires anchors (with Parameter %d)" + " near 3 of its target sectors' vertices (%d found)" "\n\nCheck the log to see which sectors were searched.", sizeu1 (sector - sectors), + tag, last ); } @@ -324,9 +323,11 @@ find_closest_anchors { I_Error( "(Sector #%s)" - " Slope requires anchors near 3 of its vertices (%d found)", + " Slope requires anchors (with Parameter %d)" + " near 3 of its vertices (%d found)", sizeu1 (sector - sectors), + tag, last ); } @@ -367,6 +368,24 @@ new_vertex_slope return slope; } +static void +slope_sector +( + pslope_t ** slope, + sector_t * sector, + const INT16 flags, + const struct anchor_list * list, + const INT16 tag +){ + mapthing_t ** anchors = find_closest_anchors(sector, list, tag); + + if (anchors != NULL) + { + (*slope) = new_vertex_slope(anchors, flags); + sector->hasslope = true; + } +} + static void make_anchored_slope ( @@ -384,7 +403,6 @@ make_anchored_slope const int side = ( flags & ML_NOCLIMB ) != 0; sector_t * sector; - mapthing_t ** anchors; if (side == 0 || flags & ML_TWOSIDED) { @@ -392,17 +410,15 @@ make_anchored_slope if (plane & FLOOR) { - anchors = find_closest_anchors(sector, &floor_anchors); - sector->f_slope = new_vertex_slope(anchors, flags); + slope_sector + (§or->f_slope, sector, flags, &floor_anchors, line->tag); } if (plane & CEILING) { - anchors = find_closest_anchors(sector, &ceiling_anchors); - sector->c_slope = new_vertex_slope(anchors, flags); + slope_sector + (§or->c_slope, sector, flags, &ceiling_anchors, line->tag); } - - sector->hasslope = true; } } From efbec2c2527dc279d12294f623e86c69d8c312ed Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 24 Sep 2020 12:19:19 -0700 Subject: [PATCH 08/10] Line special 777/778: No Knuckles to mirror slope on opposite plane --- src/slope_anchors.c | 47 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/src/slope_anchors.c b/src/slope_anchors.c index add9a33b7..acabd0caa 100644 --- a/src/slope_anchors.c +++ b/src/slope_anchors.c @@ -368,10 +368,35 @@ new_vertex_slope return slope; } +static mapthing_t ** +flip_slope +( + mapthing_t ** origin, + const sector_t * sector +){ + mapthing_t * copy = Z_Malloc(3 * sizeof (mapthing_t), PU_LEVEL, NULL); + mapthing_t ** anchors = Z_Malloc(3 * sizeof (mapthing_t *), PU_LEVEL, NULL); + + size_t i; + + for (i = 0; i < 3; ++i) + { + memcpy(©[i], origin[i], sizeof copy[i]); + + copy[i].options ^= MTF_OBJECTFLIP; + copy[i].z = anchor_height(©[i], sector); + + anchors[i] = ©[i]; + } + + return anchors; +} + static void slope_sector ( pslope_t ** slope, + pslope_t ** alt, sector_t * sector, const INT16 flags, const struct anchor_list * list, @@ -382,6 +407,13 @@ slope_sector if (anchors != NULL) { (*slope) = new_vertex_slope(anchors, flags); + + /* No Knuckles - invert slope to opposite side */ + if (flags & ML_NOKNUX) + { + (*alt) = new_vertex_slope(flip_slope(anchors, sector), flags); + } + sector->hasslope = true; } } @@ -398,26 +430,31 @@ make_anchored_slope CEILING = 0x2, }; - const INT16 flags = line->flags; + INT16 flags = line->flags; const int side = ( flags & ML_NOCLIMB ) != 0; - sector_t * sector; + sector_t * s; if (side == 0 || flags & ML_TWOSIDED) { - sector = sides[line->sidenum[side]].sector; + s = sides[line->sidenum[side]].sector; + + if (plane == FLOOR|CEILING) + { + flags &= ~ML_NOKNUX; + } if (plane & FLOOR) { slope_sector - (§or->f_slope, sector, flags, &floor_anchors, line->tag); + (&s->f_slope, &s->c_slope, s, flags, &floor_anchors, line->tag); } if (plane & CEILING) { slope_sector - (§or->c_slope, sector, flags, &ceiling_anchors, line->tag); + (&s->c_slope, &s->f_slope, s, flags, &ceiling_anchors, line->tag); } } } From 3d6ed19d55da2bdc3246fccb46698cbdd52517af Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 24 Sep 2020 12:20:32 -0700 Subject: [PATCH 09/10] oops --- src/slope_anchors.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slope_anchors.c b/src/slope_anchors.c index acabd0caa..d66c9d9dd 100644 --- a/src/slope_anchors.c +++ b/src/slope_anchors.c @@ -440,7 +440,7 @@ make_anchored_slope { s = sides[line->sidenum[side]].sector; - if (plane == FLOOR|CEILING) + if (plane == (FLOOR|CEILING)) { flags &= ~ML_NOKNUX; } From 0d573b514e592cf4e12723760db85d0d1ebb770c Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 24 Sep 2020 15:10:07 -0700 Subject: [PATCH 10/10] Stupid polyobjects require things to be spawned >:( --- src/p_setup.c | 2 ++ src/p_spec.c | 7 +++++++ src/p_spec.h | 1 + 3 files changed, 10 insertions(+) diff --git a/src/p_setup.c b/src/p_setup.c index 51bdbce89..6b92a405f 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3216,6 +3216,8 @@ boolean P_SetupLevel(boolean skipprecip) P_RaiseThings(); + P_SpawnSpecialsThatRequireObjects(); + P_SpawnSecretItems(loademblems); for (numcoopstarts = 0; numcoopstarts < MAXPLAYERS; numcoopstarts++) diff --git a/src/p_spec.c b/src/p_spec.c index 47e476478..84b4a7dd1 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6848,6 +6848,13 @@ void P_SpawnSpecials(INT32 fromnetsave) Z_Free(secthinkers[i].thinkers); Z_Free(secthinkers); +} + +/** Fuck polyobjects + */ +void P_SpawnSpecialsThatRequireObjects(void) +{ + size_t i; // haleyjd 02/20/06: spawn polyobjects Polyobj_InitLevel(); diff --git a/src/p_spec.h b/src/p_spec.h index ea497fb19..24bbfadd9 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -39,6 +39,7 @@ void P_SetupLevelFlatAnims(void); void P_InitSpecials(void); void P_SpawnSpecials(INT32 fromnetsave); void P_RaiseThings(void); +void P_SpawnSpecialsThatRequireObjects(void); // every tic void P_UpdateSpecials(void);