mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'slope-anchors-take-2' into 'master'
Vertex snapping 'slope anchors' See merge request KartKrew/Kart!317
This commit is contained in:
commit
908d38e656
7 changed files with 559 additions and 19 deletions
|
|
@ -215,4 +215,11 @@ typedef struct
|
|||
|
||||
#define NUMMAPS 1035
|
||||
|
||||
/* slope thing types */
|
||||
enum
|
||||
{
|
||||
FLOOR_SLOPE_THING = 777,
|
||||
CEILING_SLOPE_THING = 778,
|
||||
};
|
||||
|
||||
#endif // __DOOMDATA__
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -3206,19 +3206,24 @@ 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_SpawnSpecialsThatRequireObjects();
|
||||
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
43
src/p_spec.c
43
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,28 +6842,19 @@ 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)
|
||||
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();
|
||||
|
|
|
|||
10
src/p_spec.h
10
src/p_spec.h
|
|
@ -38,6 +38,8 @@ void P_SetupLevelFlatAnims(void);
|
|||
// at map load
|
||||
void P_InitSpecials(void);
|
||||
void P_SpawnSpecials(INT32 fromnetsave);
|
||||
void P_RaiseThings(void);
|
||||
void P_SpawnSpecialsThatRequireObjects(void);
|
||||
|
||||
// every tic
|
||||
void P_UpdateSpecials(void);
|
||||
|
|
@ -461,4 +463,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
|
||||
|
|
|
|||
491
src/slope_anchors.c
Normal file
491
src/slope_anchors.c
Normal file
|
|
@ -0,0 +1,491 @@
|
|||
// 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;
|
||||
fixed_t * closeness;
|
||||
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);
|
||||
list->closeness = new_list(list->count * sizeof *list->closeness);
|
||||
}
|
||||
|
||||
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 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
|
||||
(
|
||||
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 * 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(&v, closeness, x, y, sector->lines[i]->v1);
|
||||
compare_vertex_distance(&v, closeness, x, y, sector->lines[i]->v2);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static INT16
|
||||
anchor_height
|
||||
(
|
||||
const mapthing_t * a,
|
||||
const sector_t * s
|
||||
){
|
||||
{
|
||||
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;
|
||||
|
||||
fixed_t closeness;
|
||||
|
||||
a->z = anchor_height(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->closeness[list->count] = closeness;
|
||||
|
||||
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 void
|
||||
get_anchor
|
||||
(
|
||||
mapthing_t ** anchors,
|
||||
fixed_t distances[3],
|
||||
const struct anchor_list * list,
|
||||
const INT16 tag,
|
||||
const vertex_t * v
|
||||
){
|
||||
size_t i;
|
||||
|
||||
int k;
|
||||
|
||||
for (i = 0; i < list->count; ++i)
|
||||
{
|
||||
if (list->points[i] == v && list->anchors[i]->extrainfo == tag)
|
||||
{
|
||||
for (k = 0; k < 3; ++k)
|
||||
{
|
||||
if (list->closeness[i] < distances[k])
|
||||
{
|
||||
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 if (list->anchors[i] == anchors[k])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
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, tag, sector->lines[i]->v1);
|
||||
get_anchor(anchors, distances, list, tag, sector->lines[i]->v2);
|
||||
}
|
||||
}
|
||||
|
||||
static mapthing_t **
|
||||
find_closest_anchors
|
||||
(
|
||||
const sector_t * sector,
|
||||
const struct anchor_list * list,
|
||||
const INT16 tag
|
||||
){
|
||||
fixed_t distances[3] = { INT32_MAX, INT32_MAX, INT32_MAX };
|
||||
|
||||
mapthing_t ** anchors;
|
||||
|
||||
int last = 0;
|
||||
|
||||
size_t i;
|
||||
|
||||
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);
|
||||
|
||||
if (sector->numattached > 0)
|
||||
{
|
||||
for (i = 0; i < sector->numattached; ++i)
|
||||
{
|
||||
get_sector_anchors
|
||||
(anchors, distances, list, tag, §ors[sector->attached[i]]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
get_sector_anchors(anchors, distances, list, tag, sector);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (sector->numattached > 0)
|
||||
{
|
||||
CONS_Printf("\nSearched for anchors in sectors...\n\n");
|
||||
|
||||
for (i = 0; i < sector->numattached; ++i)
|
||||
{
|
||||
CONS_Printf("#%s\n", sizeu1 (sector->attached[i]));
|
||||
}
|
||||
|
||||
I_Error(
|
||||
"(Control Sector #%s)"
|
||||
" 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
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
I_Error(
|
||||
"(Sector #%s)"
|
||||
" Slope requires anchors (with Parameter %d)"
|
||||
" near 3 of its vertices (%d found)",
|
||||
|
||||
sizeu1 (sector - sectors),
|
||||
tag,
|
||||
last
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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 ) == 0)
|
||||
{
|
||||
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 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,
|
||||
const INT16 tag
|
||||
){
|
||||
mapthing_t ** anchors = find_closest_anchors(sector, list, tag);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
make_anchored_slope
|
||||
(
|
||||
const line_t * line,
|
||||
const int plane
|
||||
){
|
||||
enum
|
||||
{
|
||||
FLOOR = 0x1,
|
||||
CEILING = 0x2,
|
||||
};
|
||||
|
||||
INT16 flags = line->flags;
|
||||
|
||||
const int side = ( flags & ML_NOCLIMB ) != 0;
|
||||
|
||||
sector_t * s;
|
||||
|
||||
if (side == 0 || flags & ML_TWOSIDED)
|
||||
{
|
||||
s = sides[line->sidenum[side]].sector;
|
||||
|
||||
if (plane == (FLOOR|CEILING))
|
||||
{
|
||||
flags &= ~ML_NOKNUX;
|
||||
}
|
||||
|
||||
if (plane & FLOOR)
|
||||
{
|
||||
slope_sector
|
||||
(&s->f_slope, &s->c_slope, s, flags, &floor_anchors, line->tag);
|
||||
}
|
||||
|
||||
if (plane & CEILING)
|
||||
{
|
||||
slope_sector
|
||||
(&s->c_slope, &s->f_slope, s, flags, &ceiling_anchors, line->tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue