mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
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.
This commit is contained in:
parent
f9aae8c2e8
commit
ce7161e81d
4 changed files with 370 additions and 0 deletions
|
|
@ -215,4 +215,11 @@ typedef struct
|
|||
|
||||
#define NUMMAPS 1035
|
||||
|
||||
/* slope thing types */
|
||||
enum
|
||||
{
|
||||
FLOOR_SLOPE_THING = 777,
|
||||
CEILING_SLOPE_THING = 778,
|
||||
};
|
||||
|
||||
#endif // __DOOMDATA__
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
341
src/slope_anchors.c
Normal file
341
src/slope_anchors.c
Normal file
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue