mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-17 10:11:02 +00:00
Merge branch 'slopethinkers' into thinkerlists
Signed-off-by: Nev3r <apophycens@gmail.com>
This commit is contained in:
commit
d264d06879
8 changed files with 425 additions and 450 deletions
|
@ -8191,10 +8191,8 @@ struct {
|
||||||
#endif
|
#endif
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
// Slope flags
|
// Slope flags
|
||||||
{"SL_NOPHYSICS",SL_NOPHYSICS}, // Don't do momentum adjustment with this slope
|
{"SL_NOPHYSICS",SL_NOPHYSICS},
|
||||||
{"SL_NODYNAMIC",SL_NODYNAMIC}, // Slope will never need to move during the level, so don't fuss with recalculating it
|
{"SL_DYNAMIC",SL_DYNAMIC},
|
||||||
{"SL_ANCHORVERTEX",SL_ANCHORVERTEX},// Slope is using a Slope Vertex Thing to anchor its position
|
|
||||||
{"SL_VERTEXSLOPE",SL_VERTEXSLOPE}, // Slope is built from three Slope Vertex Things
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Angles
|
// Angles
|
||||||
|
|
|
@ -292,8 +292,6 @@ enum slope_e {
|
||||||
slope_normal,
|
slope_normal,
|
||||||
slope_zangle,
|
slope_zangle,
|
||||||
slope_xydirection,
|
slope_xydirection,
|
||||||
slope_sourceline,
|
|
||||||
slope_refpos,
|
|
||||||
slope_flags
|
slope_flags
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -305,8 +303,6 @@ static const char *const slope_opt[] = {
|
||||||
"normal",
|
"normal",
|
||||||
"zangle",
|
"zangle",
|
||||||
"xydirection",
|
"xydirection",
|
||||||
"sourceline",
|
|
||||||
"refpos",
|
|
||||||
"flags",
|
"flags",
|
||||||
NULL};
|
NULL};
|
||||||
|
|
||||||
|
@ -1831,12 +1827,6 @@ static int slope_get(lua_State *L)
|
||||||
case slope_xydirection: // xydirection
|
case slope_xydirection: // xydirection
|
||||||
lua_pushangle(L, slope->xydirection);
|
lua_pushangle(L, slope->xydirection);
|
||||||
return 1;
|
return 1;
|
||||||
case slope_sourceline: // source linedef
|
|
||||||
LUA_PushUserdata(L, slope->sourceline, META_LINE);
|
|
||||||
return 1;
|
|
||||||
case slope_refpos: // refpos
|
|
||||||
lua_pushinteger(L, slope->refpos);
|
|
||||||
return 1;
|
|
||||||
case slope_flags: // flags
|
case slope_flags: // flags
|
||||||
lua_pushinteger(L, slope->flags);
|
lua_pushinteger(L, slope->flags);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1858,11 +1848,9 @@ static int slope_set(lua_State *L)
|
||||||
switch(field) // todo: reorganize this shit
|
switch(field) // todo: reorganize this shit
|
||||||
{
|
{
|
||||||
case slope_valid: // valid
|
case slope_valid: // valid
|
||||||
case slope_sourceline: // sourceline
|
|
||||||
case slope_d: // d
|
case slope_d: // d
|
||||||
case slope_flags: // flags
|
case slope_flags: // flags
|
||||||
case slope_normal: // normal
|
case slope_normal: // normal
|
||||||
case slope_refpos: // refpos
|
|
||||||
default:
|
default:
|
||||||
return luaL_error(L, "pslope_t field " LUA_QS " cannot be set.", slope_opt[field]);
|
return luaL_error(L, "pslope_t field " LUA_QS " cannot be set.", slope_opt[field]);
|
||||||
case slope_o: { // o
|
case slope_o: { // o
|
||||||
|
|
|
@ -1304,6 +1304,10 @@ typedef enum
|
||||||
tc_fade,
|
tc_fade,
|
||||||
tc_fadecolormap,
|
tc_fadecolormap,
|
||||||
tc_planedisplace,
|
tc_planedisplace,
|
||||||
|
#ifdef ESLOPE
|
||||||
|
tc_dynslopeline,
|
||||||
|
tc_dynslopevert,
|
||||||
|
#endif // ESLOPE
|
||||||
#ifdef POLYOBJECTS
|
#ifdef POLYOBJECTS
|
||||||
tc_polyrotate, // haleyjd 03/26/06: polyobjects
|
tc_polyrotate, // haleyjd 03/26/06: polyobjects
|
||||||
tc_polymove,
|
tc_polymove,
|
||||||
|
@ -1342,6 +1346,14 @@ static inline UINT32 SavePlayer(const player_t *player)
|
||||||
return 0xFFFFFFFF;
|
return 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ESLOPE
|
||||||
|
static UINT32 SaveSlope(const pslope_t *slope)
|
||||||
|
{
|
||||||
|
if (slope) return (UINT32)(slope->id);
|
||||||
|
return 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
#endif // ESLOPE
|
||||||
|
|
||||||
//
|
//
|
||||||
// SaveMobjThinker
|
// SaveMobjThinker
|
||||||
//
|
//
|
||||||
|
@ -1979,6 +1991,23 @@ static void SavePlaneDisplaceThinker(const thinker_t *th, const UINT8 type)
|
||||||
WRITEFIXED(save_p, ht->speed);
|
WRITEFIXED(save_p, ht->speed);
|
||||||
WRITEUINT8(save_p, ht->type);
|
WRITEUINT8(save_p, ht->type);
|
||||||
}
|
}
|
||||||
|
#ifdef ESLOPE
|
||||||
|
/// Save a dynamic slope thinker.
|
||||||
|
static inline void SaveDynamicSlopeThinker(const thinker_t *th, const UINT8 type)
|
||||||
|
{
|
||||||
|
const dynplanethink_t* ht = (const void*)th;
|
||||||
|
|
||||||
|
WRITEUINT8(save_p, type);
|
||||||
|
WRITEUINT8(save_p, ht->type);
|
||||||
|
WRITEUINT32(save_p, SaveSlope(ht->slope));
|
||||||
|
WRITEUINT32(save_p, SaveLine(ht->sourceline));
|
||||||
|
WRITEFIXED(save_p, ht->extent);
|
||||||
|
|
||||||
|
WRITEMEM(save_p, ht->tags, sizeof(ht->tags));
|
||||||
|
WRITEMEM(save_p, ht->vex, sizeof(ht->vex));
|
||||||
|
}
|
||||||
|
#endif // ESLOPE
|
||||||
|
|
||||||
#ifdef POLYOBJECTS
|
#ifdef POLYOBJECTS
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -2313,7 +2342,7 @@ static void P_NetArchiveThinkers(void)
|
||||||
SavePlaneDisplaceThinker(th, tc_planedisplace);
|
SavePlaneDisplaceThinker(th, tc_planedisplace);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#ifdef POLYOBJECTS
|
#ifdef POLYOBJECTS
|
||||||
else if (th->function.acp1 == (actionf_p1)T_PolyObjRotate)
|
else if (th->function.acp1 == (actionf_p1)T_PolyObjRotate)
|
||||||
{
|
{
|
||||||
SavePolyrotatetThinker(th, tc_polyrotate);
|
SavePolyrotatetThinker(th, tc_polyrotate);
|
||||||
|
@ -2360,6 +2389,18 @@ static void P_NetArchiveThinkers(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ESLOPE
|
||||||
|
else if (th->function.acp1 == (actionf_p1)T_DynamicSlopeLine)
|
||||||
|
{
|
||||||
|
SaveDynamicSlopeThinker(th, tc_dynslopeline);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (th->function.acp1 == (actionf_p1)T_DynamicSlopeVert)
|
||||||
|
{
|
||||||
|
SaveDynamicSlopeThinker(th, tc_dynslopevert);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif // ESLOPE
|
||||||
#ifdef PARANOIA
|
#ifdef PARANOIA
|
||||||
else if (th->function.acv != P_RemoveThinkerDelayed) // wait garbage collection
|
else if (th->function.acv != P_RemoveThinkerDelayed) // wait garbage collection
|
||||||
I_Error("unknown thinker type %p", th->function.acp1);
|
I_Error("unknown thinker type %p", th->function.acp1);
|
||||||
|
@ -2418,6 +2459,20 @@ static inline player_t *LoadPlayer(UINT32 player)
|
||||||
return &players[player];
|
return &players[player];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ESLOPE
|
||||||
|
static inline pslope_t *LoadSlope(UINT32 slopeid)
|
||||||
|
{
|
||||||
|
pslope_t *p = slopelist;
|
||||||
|
if (slopeid > slopecount) return NULL;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (p->id == slopeid)
|
||||||
|
return p;
|
||||||
|
} while ((p = p->next));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif // ESLOPE
|
||||||
|
|
||||||
//
|
//
|
||||||
// LoadMobjThinker
|
// LoadMobjThinker
|
||||||
//
|
//
|
||||||
|
@ -3110,6 +3165,7 @@ static inline thinker_t* LoadPlaneDisplaceThinker(actionf_p1 thinker)
|
||||||
{
|
{
|
||||||
planedisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
planedisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
||||||
ht->thinker.function.acp1 = thinker;
|
ht->thinker.function.acp1 = thinker;
|
||||||
|
|
||||||
ht->affectee = READINT32(save_p);
|
ht->affectee = READINT32(save_p);
|
||||||
ht->control = READINT32(save_p);
|
ht->control = READINT32(save_p);
|
||||||
ht->last_height = READFIXED(save_p);
|
ht->last_height = READFIXED(save_p);
|
||||||
|
@ -3118,6 +3174,23 @@ static inline thinker_t* LoadPlaneDisplaceThinker(actionf_p1 thinker)
|
||||||
return &ht->thinker;
|
return &ht->thinker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ESLOPE
|
||||||
|
/// Save a dynamic slope thinker.
|
||||||
|
static inline thinker_t* LoadDynamicSlopeThinker(actionf_p1 thinker)
|
||||||
|
{
|
||||||
|
dynplanethink_t* ht = Z_Malloc(sizeof(*ht), PU_LEVSPEC, NULL);
|
||||||
|
ht->thinker.function.acp1 = thinker;
|
||||||
|
|
||||||
|
ht->type = READUINT8(save_p);
|
||||||
|
ht->slope = LoadSlope(READUINT32(save_p));
|
||||||
|
ht->sourceline = LoadLine(READUINT32(save_p));
|
||||||
|
ht->extent = READFIXED(save_p);
|
||||||
|
READMEM(save_p, ht->tags, sizeof(ht->tags));
|
||||||
|
READMEM(save_p, ht->vex, sizeof(ht->vex));
|
||||||
|
return &ht->thinker;
|
||||||
|
}
|
||||||
|
#endif // ESLOPE
|
||||||
|
|
||||||
#ifdef POLYOBJECTS
|
#ifdef POLYOBJECTS
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -3457,7 +3530,7 @@ static void P_NetUnArchiveThinkers(void)
|
||||||
case tc_planedisplace:
|
case tc_planedisplace:
|
||||||
th = LoadPlaneDisplaceThinker((actionf_p1)T_PlaneDisplace);
|
th = LoadPlaneDisplaceThinker((actionf_p1)T_PlaneDisplace);
|
||||||
break;
|
break;
|
||||||
#ifdef POLYOBJECTS
|
#ifdef POLYOBJECTS
|
||||||
case tc_polyrotate:
|
case tc_polyrotate:
|
||||||
th = LoadPolyrotatetThinker((actionf_p1)T_PolyObjRotate);
|
th = LoadPolyrotatetThinker((actionf_p1)T_PolyObjRotate);
|
||||||
break;
|
break;
|
||||||
|
@ -3493,7 +3566,17 @@ static void P_NetUnArchiveThinkers(void)
|
||||||
case tc_polyfade:
|
case tc_polyfade:
|
||||||
th = LoadPolyfadeThinker((actionf_p1)T_PolyObjFade);
|
th = LoadPolyfadeThinker((actionf_p1)T_PolyObjFade);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ESLOPE
|
||||||
|
case tc_dynslopeline:
|
||||||
|
th = LoadDynamicSlopeThinker((actionf_p1)T_DynamicSlopeLine);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tc_dynslopevert:
|
||||||
|
th = LoadDynamicSlopeThinker((actionf_p1)T_DynamicSlopeVert);
|
||||||
|
break;
|
||||||
|
#endif // ESLOPE
|
||||||
|
|
||||||
case tc_scroll:
|
case tc_scroll:
|
||||||
th = LoadScrollThinker((actionf_p1)T_Scroll);
|
th = LoadScrollThinker((actionf_p1)T_Scroll);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -2911,7 +2911,8 @@ boolean P_SetupLevel(boolean skipprecip)
|
||||||
P_InitSpecials();
|
P_InitSpecials();
|
||||||
|
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
P_ResetDynamicSlopes();
|
P_ResetDynamicSlopes(fromnetsave);
|
||||||
|
P_LinkSlopeThinkers(); // Spawn slope thinkers just after plane move thinkers to avoid movement/update delays.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
P_LoadThings(loademblems);
|
P_LoadThings(loademblems);
|
||||||
|
|
667
src/p_slopes.c
667
src/p_slopes.c
|
@ -25,68 +25,106 @@
|
||||||
|
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
|
|
||||||
static pslope_t *slopelist = NULL;
|
pslope_t *slopelist = NULL;
|
||||||
static UINT16 slopecount = 0;
|
UINT16 slopecount = 0;
|
||||||
|
|
||||||
|
thinker_t *dynthinklist;
|
||||||
|
size_t dynthinknum;
|
||||||
|
|
||||||
|
/// Links previously queued thinker list to the main thinker list.
|
||||||
|
void P_LinkSlopeThinkers (void)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
thinker_t *th = dynthinklist;
|
||||||
|
|
||||||
|
CONS_Printf("Number of dynamic thinkers: %d\n", dynthinknum);
|
||||||
|
|
||||||
|
for (i = 0; i < dynthinknum; i++)
|
||||||
|
{
|
||||||
|
thinker_t *next = th->next;
|
||||||
|
P_AddThinker(th);
|
||||||
|
th = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Queues a thinker to a partial linked list to be immediately incorporated later via P_LinkSlopeThinkers().
|
||||||
|
static void P_QueueSlopeThinker (thinker_t* th)
|
||||||
|
{
|
||||||
|
thinker_t* last = dynthinklist;
|
||||||
|
|
||||||
|
// First entry.
|
||||||
|
if (!last)
|
||||||
|
{
|
||||||
|
dynthinklist = th;
|
||||||
|
dynthinknum++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (last->next)
|
||||||
|
last = last->next;
|
||||||
|
|
||||||
|
last->next = th;
|
||||||
|
|
||||||
|
dynthinknum++;
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate line normal
|
// Calculate line normal
|
||||||
void P_CalculateSlopeNormal(pslope_t *slope) {
|
void P_CalculateSlopeNormal(pslope_t *slope) {
|
||||||
slope->normal.z = FINECOSINE(slope->zangle>>ANGLETOFINESHIFT);
|
slope->normal.z = FINECOSINE(slope->zangle>>ANGLETOFINESHIFT);
|
||||||
slope->normal.x = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.x);
|
slope->normal.x = FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.x);
|
||||||
slope->normal.y = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.y);
|
slope->normal.y = FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// With a vertex slope that has its vertices set, configure relevant slope info
|
/// Setup slope via 3 vertexes.
|
||||||
static void P_ReconfigureVertexSlope(pslope_t *slope)
|
static void ReconfigureViaVertexes (pslope_t *slope, const vector3_t v1, const vector3_t v2, const vector3_t v3)
|
||||||
{
|
{
|
||||||
vector3_t vec1, vec2;
|
vector3_t vec1, vec2;
|
||||||
|
|
||||||
// Set slope normal
|
// Set origin.
|
||||||
vec1.x = (slope->vertices[1]->x - slope->vertices[0]->x) << FRACBITS;
|
FV3_Copy(&slope->o, &v1);
|
||||||
vec1.y = (slope->vertices[1]->y - slope->vertices[0]->y) << FRACBITS;
|
|
||||||
vec1.z = (slope->vertices[1]->z - slope->vertices[0]->z) << FRACBITS;
|
|
||||||
|
|
||||||
vec2.x = (slope->vertices[2]->x - slope->vertices[0]->x) << FRACBITS;
|
// Get slope's normal.
|
||||||
vec2.y = (slope->vertices[2]->y - slope->vertices[0]->y) << FRACBITS;
|
FV3_SubEx(&v2, &v1, &vec1);
|
||||||
vec2.z = (slope->vertices[2]->z - slope->vertices[0]->z) << FRACBITS;
|
FV3_SubEx(&v3, &v1, &vec2);
|
||||||
|
|
||||||
// ugggggggh fixed-point maaaaaaath
|
// Set some defaults for a non-sloped "slope"
|
||||||
slope->extent = max(
|
if (vec1.z == 0 && vec2.z == 0)
|
||||||
max(max(abs(vec1.x), abs(vec1.y)), abs(vec1.z)),
|
{
|
||||||
max(max(abs(vec2.x), abs(vec2.y)), abs(vec2.z))
|
/// \todo Fix fully flat cases.
|
||||||
) >> (FRACBITS+5);
|
|
||||||
vec1.x /= slope->extent;
|
|
||||||
vec1.y /= slope->extent;
|
|
||||||
vec1.z /= slope->extent;
|
|
||||||
vec2.x /= slope->extent;
|
|
||||||
vec2.y /= slope->extent;
|
|
||||||
vec2.z /= slope->extent;
|
|
||||||
|
|
||||||
FV3_Cross(&vec1, &vec2, &slope->normal);
|
|
||||||
|
|
||||||
slope->extent = R_PointToDist2(0, 0, R_PointToDist2(0, 0, slope->normal.x, slope->normal.y), slope->normal.z);
|
|
||||||
if (slope->normal.z < 0)
|
|
||||||
slope->extent = -slope->extent;
|
|
||||||
|
|
||||||
slope->normal.x = FixedDiv(slope->normal.x, slope->extent);
|
|
||||||
slope->normal.y = FixedDiv(slope->normal.y, slope->extent);
|
|
||||||
slope->normal.z = FixedDiv(slope->normal.z, slope->extent);
|
|
||||||
|
|
||||||
// Set origin
|
|
||||||
slope->o.x = slope->vertices[0]->x << FRACBITS;
|
|
||||||
slope->o.y = slope->vertices[0]->y << FRACBITS;
|
|
||||||
slope->o.z = slope->vertices[0]->z << FRACBITS;
|
|
||||||
|
|
||||||
if (slope->normal.x == 0 && slope->normal.y == 0) { // Set some defaults for a non-sloped "slope"
|
|
||||||
slope->zangle = slope->xydirection = 0;
|
slope->zangle = slope->xydirection = 0;
|
||||||
slope->zdelta = slope->d.x = slope->d.y = 0;
|
slope->zdelta = slope->d.x = slope->d.y = 0;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/// \note Using fixed point for vectorial products easily leads to overflows so we work around by downscaling them.
|
||||||
|
fixed_t m = max(
|
||||||
|
max(max(abs(vec1.x), abs(vec1.y)), abs(vec1.z)),
|
||||||
|
max(max(abs(vec2.x), abs(vec2.y)), abs(vec2.z))
|
||||||
|
) >> 5; // shifting right by 5 is good enough.
|
||||||
|
|
||||||
|
FV3_Cross(
|
||||||
|
FV3_Divide(&vec1, m),
|
||||||
|
FV3_Divide(&vec2, m),
|
||||||
|
&slope->normal
|
||||||
|
);
|
||||||
|
|
||||||
|
// NOTE: FV3_Magnitude() doesn't work properly in some cases, and chaining FixedHypot() seems to give worse results.
|
||||||
|
m = R_PointToDist2(0, 0, R_PointToDist2(0, 0, slope->normal.x, slope->normal.y), slope->normal.z);
|
||||||
|
|
||||||
|
// Invert normal if it's facing down.
|
||||||
|
if (slope->normal.z < 0)
|
||||||
|
m = -m;
|
||||||
|
|
||||||
|
FV3_Divide(&slope->normal, m);
|
||||||
|
|
||||||
// Get direction vector
|
// Get direction vector
|
||||||
slope->extent = R_PointToDist2(0, 0, slope->normal.x, slope->normal.y);
|
m = FixedHypot(slope->normal.x, slope->normal.y);
|
||||||
slope->d.x = -FixedDiv(slope->normal.x, slope->extent);
|
slope->d.x = -FixedDiv(slope->normal.x, m);
|
||||||
slope->d.y = -FixedDiv(slope->normal.y, slope->extent);
|
slope->d.y = -FixedDiv(slope->normal.y, m);
|
||||||
|
|
||||||
// Z delta
|
// Z delta
|
||||||
slope->zdelta = FixedDiv(slope->extent, slope->normal.z);
|
slope->zdelta = FixedDiv(m, slope->normal.z);
|
||||||
|
|
||||||
// Get angles
|
// Get angles
|
||||||
slope->xydirection = R_PointToAngle2(0, 0, slope->d.x, slope->d.y)+ANGLE_180;
|
slope->xydirection = R_PointToAngle2(0, 0, slope->d.x, slope->d.y)+ANGLE_180;
|
||||||
|
@ -94,88 +132,95 @@ static void P_ReconfigureVertexSlope(pslope_t *slope)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recalculate dynamic slopes
|
/// Recalculate dynamic slopes.
|
||||||
void P_RunDynamicSlopes(void) {
|
void T_DynamicSlopeLine (dynplanethink_t* th)
|
||||||
pslope_t *slope;
|
{
|
||||||
|
pslope_t* slope = th->slope;
|
||||||
|
line_t* srcline = th->sourceline;
|
||||||
|
|
||||||
for (slope = slopelist; slope; slope = slope->next) {
|
fixed_t zdelta;
|
||||||
fixed_t zdelta;
|
|
||||||
|
|
||||||
if (slope->flags & SL_NODYNAMIC)
|
switch(th->type) {
|
||||||
continue;
|
case DP_FRONTFLOOR:
|
||||||
|
zdelta = srcline->backsector->floorheight - srcline->frontsector->floorheight;
|
||||||
|
slope->o.z = srcline->frontsector->floorheight;
|
||||||
|
break;
|
||||||
|
|
||||||
switch(slope->refpos) {
|
case DP_FRONTCEIL:
|
||||||
case 1: // front floor
|
zdelta = srcline->backsector->ceilingheight - srcline->frontsector->ceilingheight;
|
||||||
zdelta = slope->sourceline->backsector->floorheight - slope->sourceline->frontsector->floorheight;
|
slope->o.z = srcline->frontsector->ceilingheight;
|
||||||
slope->o.z = slope->sourceline->frontsector->floorheight;
|
break;
|
||||||
break;
|
|
||||||
case 2: // front ceiling
|
|
||||||
zdelta = slope->sourceline->backsector->ceilingheight - slope->sourceline->frontsector->ceilingheight;
|
|
||||||
slope->o.z = slope->sourceline->frontsector->ceilingheight;
|
|
||||||
break;
|
|
||||||
case 3: // back floor
|
|
||||||
zdelta = slope->sourceline->frontsector->floorheight - slope->sourceline->backsector->floorheight;
|
|
||||||
slope->o.z = slope->sourceline->backsector->floorheight;
|
|
||||||
break;
|
|
||||||
case 4: // back ceiling
|
|
||||||
zdelta = slope->sourceline->frontsector->ceilingheight - slope->sourceline->backsector->ceilingheight;
|
|
||||||
slope->o.z = slope->sourceline->backsector->ceilingheight;
|
|
||||||
break;
|
|
||||||
case 5: // vertices
|
|
||||||
{
|
|
||||||
mapthing_t *mt;
|
|
||||||
size_t i;
|
|
||||||
INT32 l;
|
|
||||||
line_t *line;
|
|
||||||
|
|
||||||
for (i = 0; i < 3; i++) {
|
case DP_BACKFLOOR:
|
||||||
mt = slope->vertices[i];
|
zdelta = srcline->frontsector->floorheight - srcline->backsector->floorheight;
|
||||||
l = P_FindSpecialLineFromTag(799, mt->angle, -1);
|
slope->o.z = srcline->backsector->floorheight;
|
||||||
if (l != -1) {
|
break;
|
||||||
line = &lines[l];
|
|
||||||
mt->z = line->frontsector->floorheight >> FRACBITS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
P_ReconfigureVertexSlope(slope);
|
case DP_BACKCEIL:
|
||||||
}
|
zdelta = srcline->frontsector->ceilingheight - srcline->backsector->ceilingheight;
|
||||||
continue; // TODO
|
slope->o.z = srcline->backsector->ceilingheight;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
I_Error("P_RunDynamicSlopes: slope has invalid type!");
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slope->zdelta != FixedDiv(zdelta, slope->extent)) {
|
if (slope->zdelta != FixedDiv(zdelta, th->extent)) {
|
||||||
slope->zdelta = FixedDiv(zdelta, slope->extent);
|
slope->zdelta = FixedDiv(zdelta, th->extent);
|
||||||
slope->zangle = R_PointToAngle2(0, 0, slope->extent, -zdelta);
|
slope->zangle = R_PointToAngle2(0, 0, th->extent, -zdelta);
|
||||||
P_CalculateSlopeNormal(slope);
|
P_CalculateSlopeNormal(slope);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/// Mapthing-defined
|
||||||
// P_MakeSlope
|
void T_DynamicSlopeVert (dynplanethink_t* th)
|
||||||
//
|
|
||||||
// Alocates and fill the contents of a slope structure.
|
|
||||||
//
|
|
||||||
static pslope_t *P_MakeSlope(const vector3_t *o, const vector2_t *d,
|
|
||||||
const fixed_t zdelta, UINT8 flags)
|
|
||||||
{
|
{
|
||||||
pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL);
|
pslope_t* slope = th->slope;
|
||||||
memset(ret, 0, sizeof(*ret));
|
|
||||||
|
|
||||||
ret->o.x = o->x;
|
size_t i;
|
||||||
ret->o.y = o->y;
|
INT32 l;
|
||||||
ret->o.z = o->z;
|
|
||||||
|
|
||||||
ret->d.x = d->x;
|
for (i = 0; i < 3; i++) {
|
||||||
ret->d.y = d->y;
|
l = P_FindSpecialLineFromTag(799, th->tags[i], -1);
|
||||||
|
if (l != -1) {
|
||||||
|
th->vex[i].z = lines[l].frontsector->floorheight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
th->vex[i].z = 0;
|
||||||
|
}
|
||||||
|
|
||||||
ret->zdelta = zdelta;
|
ReconfigureViaVertexes(slope, th->vex[0], th->vex[1], th->vex[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void P_AddDynSlopeThinker (pslope_t* slope, dynplanetype_t type, line_t* sourceline, fixed_t extent, const INT16 tags[3], const vector3_t vx[3])
|
||||||
|
{
|
||||||
|
dynplanethink_t* th = Z_Calloc(sizeof (*th), PU_LEVSPEC, NULL);
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case DP_VERTEX:
|
||||||
|
th->thinker.function.acp1 = (actionf_p1)T_DynamicSlopeVert;
|
||||||
|
memcpy(th->tags, tags, sizeof(th->tags));
|
||||||
|
memcpy(th->vex, vx, sizeof(th->vex));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
th->thinker.function.acp1 = (actionf_p1)T_DynamicSlopeLine;
|
||||||
|
th->sourceline = sourceline;
|
||||||
|
th->extent = extent;
|
||||||
|
}
|
||||||
|
|
||||||
|
th->slope = slope;
|
||||||
|
th->type = type;
|
||||||
|
|
||||||
|
P_QueueSlopeThinker(&th->thinker);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Create a new slope and add it to the slope list.
|
||||||
|
static inline pslope_t* Slope_Add (const UINT8 flags)
|
||||||
|
{
|
||||||
|
pslope_t *ret = Z_Calloc(sizeof(pslope_t), PU_LEVEL, NULL);
|
||||||
ret->flags = flags;
|
ret->flags = flags;
|
||||||
|
|
||||||
// Add to the slope list
|
|
||||||
ret->next = slopelist;
|
ret->next = slopelist;
|
||||||
slopelist = ret;
|
slopelist = ret;
|
||||||
|
|
||||||
|
@ -185,13 +230,24 @@ static pslope_t *P_MakeSlope(const vector3_t *o, const vector2_t *d,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/// Alocates and fill the contents of a slope structure.
|
||||||
// P_GetExtent
|
static pslope_t *MakeViaVectors(const vector3_t *o, const vector2_t *d,
|
||||||
//
|
const fixed_t zdelta, UINT8 flags)
|
||||||
// Returns the distance to the first line within the sector that
|
{
|
||||||
// is intersected by a line parallel to the plane normal with the point (ox, oy)
|
pslope_t *ret = Slope_Add(flags);
|
||||||
//
|
|
||||||
static fixed_t P_GetExtent(sector_t *sector, line_t *line)
|
FV3_Copy(&ret->o, o);
|
||||||
|
FV2_Copy(&ret->d, d);
|
||||||
|
|
||||||
|
ret->zdelta = zdelta;
|
||||||
|
|
||||||
|
ret->flags = flags;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get furthest perpendicular distance from all vertexes in a sector for a given line.
|
||||||
|
static fixed_t GetExtent(sector_t *sector, line_t *line)
|
||||||
{
|
{
|
||||||
// ZDoom code reference: v3float_t = vertex_t
|
// ZDoom code reference: v3float_t = vertex_t
|
||||||
fixed_t fardist = -FRACUNIT;
|
fixed_t fardist = -FRACUNIT;
|
||||||
|
@ -224,14 +280,8 @@ static fixed_t P_GetExtent(sector_t *sector, line_t *line)
|
||||||
return fardist;
|
return fardist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates one or more slopes based on the given line type and front/back sectors.
|
||||||
//
|
static void line_SpawnViaLine(const int linenum, const boolean spawnthinker)
|
||||||
// P_SpawnSlope_Line
|
|
||||||
//
|
|
||||||
// Creates one or more slopes based on the given line type and front/back
|
|
||||||
// sectors.
|
|
||||||
//
|
|
||||||
void P_SpawnSlope_Line(int linenum)
|
|
||||||
{
|
{
|
||||||
// With dynamic slopes, it's fine to just leave this function as normal,
|
// With dynamic slopes, it's fine to just leave this function as normal,
|
||||||
// because checking to see if a slope had changed will waste more memory than
|
// because checking to see if a slope had changed will waste more memory than
|
||||||
|
@ -251,10 +301,8 @@ void P_SpawnSlope_Line(int linenum)
|
||||||
UINT8 flags = 0; // Slope flags
|
UINT8 flags = 0; // Slope flags
|
||||||
if (line->flags & ML_NOSONIC)
|
if (line->flags & ML_NOSONIC)
|
||||||
flags |= SL_NOPHYSICS;
|
flags |= SL_NOPHYSICS;
|
||||||
if (!(line->flags & ML_NOTAILS))
|
if (line->flags & ML_NOTAILS)
|
||||||
flags |= SL_NODYNAMIC;
|
flags |= SL_DYNAMIC;
|
||||||
if (line->flags & ML_NOKNUX)
|
|
||||||
flags |= SL_ANCHORVERTEX;
|
|
||||||
|
|
||||||
if(!frontfloor && !backfloor && !frontceil && !backceil)
|
if(!frontfloor && !backfloor && !frontceil && !backceil)
|
||||||
{
|
{
|
||||||
|
@ -274,6 +322,7 @@ void P_SpawnSlope_Line(int linenum)
|
||||||
ny = -FixedDiv(line->dx, len);
|
ny = -FixedDiv(line->dx, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set origin to line's center.
|
||||||
origin.x = line->v1->x + (line->v2->x - line->v1->x)/2;
|
origin.x = line->v1->x + (line->v2->x - line->v1->x)/2;
|
||||||
origin.y = line->v1->y + (line->v2->y - line->v1->y)/2;
|
origin.y = line->v1->y + (line->v2->y - line->v1->y)/2;
|
||||||
|
|
||||||
|
@ -286,7 +335,7 @@ void P_SpawnSlope_Line(int linenum)
|
||||||
direction.x = nx;
|
direction.x = nx;
|
||||||
direction.y = ny;
|
direction.y = ny;
|
||||||
|
|
||||||
extent = P_GetExtent(line->frontsector, line);
|
extent = GetExtent(line->frontsector, line);
|
||||||
|
|
||||||
if(extent < 0)
|
if(extent < 0)
|
||||||
{
|
{
|
||||||
|
@ -304,104 +353,43 @@ void P_SpawnSlope_Line(int linenum)
|
||||||
|
|
||||||
if(frontfloor)
|
if(frontfloor)
|
||||||
{
|
{
|
||||||
fixed_t highest, lowest;
|
|
||||||
size_t l;
|
|
||||||
point.z = line->frontsector->floorheight; // Startz
|
point.z = line->frontsector->floorheight; // Startz
|
||||||
dz = FixedDiv(origin.z - point.z, extent); // Destinationz
|
dz = FixedDiv(origin.z - point.z, extent); // Destinationz
|
||||||
|
|
||||||
// In P_SpawnSlopeLine the origin is the centerpoint of the sourcelinedef
|
// In P_SpawnSlopeLine the origin is the centerpoint of the sourcelinedef
|
||||||
|
|
||||||
fslope = line->frontsector->f_slope =
|
fslope = line->frontsector->f_slope =
|
||||||
P_MakeSlope(&point, &direction, dz, flags);
|
MakeViaVectors(&point, &direction, dz, flags);
|
||||||
|
|
||||||
// Set up some shit
|
|
||||||
fslope->extent = extent;
|
|
||||||
fslope->refpos = 1;
|
|
||||||
|
|
||||||
// Now remember that f_slope IS a vector
|
// Now remember that f_slope IS a vector
|
||||||
// fslope->o = origin 3D point 1 of the vector
|
// fslope->o = origin 3D point 1 of the vector
|
||||||
// fslope->d = destination 3D point 2 of the vector
|
// fslope->d = destination 3D point 2 of the vector
|
||||||
// fslope->normal is a 3D line perpendicular to the 3D vector
|
// fslope->normal is a 3D line perpendicular to the 3D vector
|
||||||
|
|
||||||
// Sync the linedata of the line that started this slope
|
|
||||||
// TODO: Anything special for control sector based slopes later?
|
|
||||||
fslope->sourceline = line;
|
|
||||||
|
|
||||||
// To find the real highz/lowz of a slope, you need to check all the vertexes
|
|
||||||
// in the slope's sector with P_GetZAt to get the REAL lowz & highz
|
|
||||||
// Although these slopes are set by floorheights the ANGLE is what a slope is,
|
|
||||||
// so technically any slope can extend on forever (they are just bound by sectors)
|
|
||||||
// *You can use sourceline as a reference to see if two slopes really are the same
|
|
||||||
|
|
||||||
// Default points for high and low
|
|
||||||
highest = point.z > origin.z ? point.z : origin.z;
|
|
||||||
lowest = point.z < origin.z ? point.z : origin.z;
|
|
||||||
|
|
||||||
// Now check to see what the REAL high and low points of the slope inside the sector
|
|
||||||
// TODO: Is this really needed outside of FOFs? -Red
|
|
||||||
|
|
||||||
for (l = 0; l < line->frontsector->linecount; l++)
|
|
||||||
{
|
|
||||||
fixed_t height = P_GetZAt(line->frontsector->f_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y);
|
|
||||||
|
|
||||||
if (height > highest)
|
|
||||||
highest = height;
|
|
||||||
|
|
||||||
if (height < lowest)
|
|
||||||
lowest = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets extra clipping data for the frontsector's slope
|
|
||||||
fslope->highz = highest;
|
|
||||||
fslope->lowz = lowest;
|
|
||||||
|
|
||||||
fslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z);
|
fslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z);
|
||||||
fslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y);
|
fslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y);
|
||||||
|
|
||||||
P_CalculateSlopeNormal(fslope);
|
P_CalculateSlopeNormal(fslope);
|
||||||
|
|
||||||
|
if (spawnthinker && (flags & SL_DYNAMIC))
|
||||||
|
P_AddDynSlopeThinker(fslope, DP_FRONTFLOOR, line, extent, NULL, NULL);
|
||||||
}
|
}
|
||||||
if(frontceil)
|
if(frontceil)
|
||||||
{
|
{
|
||||||
fixed_t highest, lowest;
|
|
||||||
size_t l;
|
|
||||||
origin.z = line->backsector->ceilingheight;
|
origin.z = line->backsector->ceilingheight;
|
||||||
point.z = line->frontsector->ceilingheight;
|
point.z = line->frontsector->ceilingheight;
|
||||||
dz = FixedDiv(origin.z - point.z, extent);
|
dz = FixedDiv(origin.z - point.z, extent);
|
||||||
|
|
||||||
cslope = line->frontsector->c_slope =
|
cslope = line->frontsector->c_slope =
|
||||||
P_MakeSlope(&point, &direction, dz, flags);
|
MakeViaVectors(&point, &direction, dz, flags);
|
||||||
|
|
||||||
// Set up some shit
|
|
||||||
cslope->extent = extent;
|
|
||||||
cslope->refpos = 2;
|
|
||||||
|
|
||||||
// Sync the linedata of the line that started this slope
|
|
||||||
// TODO: Anything special for control sector based slopes later?
|
|
||||||
cslope->sourceline = line;
|
|
||||||
|
|
||||||
// Remember the way the slope is formed
|
|
||||||
highest = point.z > origin.z ? point.z : origin.z;
|
|
||||||
lowest = point.z < origin.z ? point.z : origin.z;
|
|
||||||
|
|
||||||
for (l = 0; l < line->frontsector->linecount; l++)
|
|
||||||
{
|
|
||||||
fixed_t height = P_GetZAt(line->frontsector->c_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y);
|
|
||||||
|
|
||||||
if (height > highest)
|
|
||||||
highest = height;
|
|
||||||
|
|
||||||
if (height < lowest)
|
|
||||||
lowest = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This line special sets extra clipping data for the frontsector's slope
|
|
||||||
cslope->highz = highest;
|
|
||||||
cslope->lowz = lowest;
|
|
||||||
|
|
||||||
cslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z);
|
cslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z);
|
||||||
cslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y);
|
cslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y);
|
||||||
|
|
||||||
P_CalculateSlopeNormal(cslope);
|
P_CalculateSlopeNormal(cslope);
|
||||||
|
|
||||||
|
if (spawnthinker && (flags & SL_DYNAMIC))
|
||||||
|
P_AddDynSlopeThinker(cslope, DP_FRONTCEIL, line, extent, NULL, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(backfloor || backceil)
|
if(backfloor || backceil)
|
||||||
|
@ -413,7 +401,7 @@ void P_SpawnSlope_Line(int linenum)
|
||||||
direction.x = -nx;
|
direction.x = -nx;
|
||||||
direction.y = -ny;
|
direction.y = -ny;
|
||||||
|
|
||||||
extent = P_GetExtent(line->backsector, line);
|
extent = GetExtent(line->backsector, line);
|
||||||
|
|
||||||
if(extent < 0)
|
if(extent < 0)
|
||||||
{
|
{
|
||||||
|
@ -429,88 +417,36 @@ void P_SpawnSlope_Line(int linenum)
|
||||||
|
|
||||||
if(backfloor)
|
if(backfloor)
|
||||||
{
|
{
|
||||||
fixed_t highest, lowest;
|
|
||||||
size_t l;
|
|
||||||
point.z = line->backsector->floorheight;
|
point.z = line->backsector->floorheight;
|
||||||
dz = FixedDiv(origin.z - point.z, extent);
|
dz = FixedDiv(origin.z - point.z, extent);
|
||||||
|
|
||||||
fslope = line->backsector->f_slope =
|
fslope = line->backsector->f_slope =
|
||||||
P_MakeSlope(&point, &direction, dz, flags);
|
MakeViaVectors(&point, &direction, dz, flags);
|
||||||
|
|
||||||
// Set up some shit
|
|
||||||
fslope->extent = extent;
|
|
||||||
fslope->refpos = 3;
|
|
||||||
|
|
||||||
// Sync the linedata of the line that started this slope
|
|
||||||
// TODO: Anything special for control sector based slopes later?
|
|
||||||
fslope->sourceline = line;
|
|
||||||
|
|
||||||
// Remember the way the slope is formed
|
|
||||||
highest = point.z > origin.z ? point.z : origin.z;
|
|
||||||
lowest = point.z < origin.z ? point.z : origin.z;
|
|
||||||
|
|
||||||
for (l = 0; l < line->backsector->linecount; l++)
|
|
||||||
{
|
|
||||||
fixed_t height = P_GetZAt(line->backsector->f_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y);
|
|
||||||
|
|
||||||
if (height > highest)
|
|
||||||
highest = height;
|
|
||||||
|
|
||||||
if (height < lowest)
|
|
||||||
lowest = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This line special sets extra clipping data for the frontsector's slope
|
|
||||||
fslope->highz = highest;
|
|
||||||
fslope->lowz = lowest;
|
|
||||||
|
|
||||||
fslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z);
|
fslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z);
|
||||||
fslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y);
|
fslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y);
|
||||||
|
|
||||||
P_CalculateSlopeNormal(fslope);
|
P_CalculateSlopeNormal(fslope);
|
||||||
|
|
||||||
|
if (spawnthinker && (flags & SL_DYNAMIC))
|
||||||
|
P_AddDynSlopeThinker(fslope, DP_BACKFLOOR, line, extent, NULL, NULL);
|
||||||
}
|
}
|
||||||
if(backceil)
|
if(backceil)
|
||||||
{
|
{
|
||||||
fixed_t highest, lowest;
|
|
||||||
size_t l;
|
|
||||||
origin.z = line->frontsector->ceilingheight;
|
origin.z = line->frontsector->ceilingheight;
|
||||||
point.z = line->backsector->ceilingheight;
|
point.z = line->backsector->ceilingheight;
|
||||||
dz = FixedDiv(origin.z - point.z, extent);
|
dz = FixedDiv(origin.z - point.z, extent);
|
||||||
|
|
||||||
cslope = line->backsector->c_slope =
|
cslope = line->backsector->c_slope =
|
||||||
P_MakeSlope(&point, &direction, dz, flags);
|
MakeViaVectors(&point, &direction, dz, flags);
|
||||||
|
|
||||||
// Set up some shit
|
|
||||||
cslope->extent = extent;
|
|
||||||
cslope->refpos = 4;
|
|
||||||
|
|
||||||
// Sync the linedata of the line that started this slope
|
|
||||||
// TODO: Anything special for control sector based slopes later?
|
|
||||||
cslope->sourceline = line;
|
|
||||||
|
|
||||||
// Remember the way the slope is formed
|
|
||||||
highest = point.z > origin.z ? point.z : origin.z;
|
|
||||||
lowest = point.z < origin.z ? point.z : origin.z;
|
|
||||||
|
|
||||||
for (l = 0; l < line->backsector->linecount; l++)
|
|
||||||
{
|
|
||||||
fixed_t height = P_GetZAt(line->backsector->c_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y);
|
|
||||||
|
|
||||||
if (height > highest)
|
|
||||||
highest = height;
|
|
||||||
|
|
||||||
if (height < lowest)
|
|
||||||
lowest = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This line special sets extra clipping data for the backsector's slope
|
|
||||||
cslope->highz = highest;
|
|
||||||
cslope->lowz = lowest;
|
|
||||||
|
|
||||||
cslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z);
|
cslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z);
|
||||||
cslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y);
|
cslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y);
|
||||||
|
|
||||||
P_CalculateSlopeNormal(cslope);
|
P_CalculateSlopeNormal(cslope);
|
||||||
|
|
||||||
|
if (spawnthinker && (flags & SL_DYNAMIC))
|
||||||
|
P_AddDynSlopeThinker(cslope, DP_BACKCEIL, line, extent, NULL, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,63 +454,99 @@ void P_SpawnSlope_Line(int linenum)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/// Creates a new slope from three mapthings with the specified IDs
|
||||||
// P_NewVertexSlope
|
static pslope_t *MakeViaMapthings(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flags, const boolean spawnthinker)
|
||||||
//
|
|
||||||
// Creates a new slope from three vertices with the specified IDs
|
|
||||||
//
|
|
||||||
static pslope_t *P_NewVertexSlope(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flags)
|
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
mapthing_t *mt = mapthings;
|
mapthing_t* mt = mapthings;
|
||||||
|
mapthing_t* vertices[3] = {0};
|
||||||
|
INT16 tags[3] = {tag1, tag2, tag3};
|
||||||
|
|
||||||
pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL);
|
vector3_t vx[3];
|
||||||
memset(ret, 0, sizeof(*ret));
|
pslope_t* ret = Slope_Add(flags);
|
||||||
|
|
||||||
// Start by setting flags
|
|
||||||
ret->flags = flags;
|
|
||||||
|
|
||||||
// Now set up the vertex list
|
|
||||||
ret->vertices = Z_Malloc(3*sizeof(mapthing_t), PU_LEVEL, NULL);
|
|
||||||
memset(ret->vertices, 0, 3*sizeof(mapthing_t));
|
|
||||||
|
|
||||||
// And... look for the vertices in question.
|
// And... look for the vertices in question.
|
||||||
for (i = 0; i < nummapthings; i++, mt++) {
|
for (i = 0; i < nummapthings; i++, mt++) {
|
||||||
if (mt->type != 750) // Haha, I'm hijacking the old Chaos Spawn thingtype for something!
|
if (mt->type != 750) // Haha, I'm hijacking the old Chaos Spawn thingtype for something!
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!ret->vertices[0] && mt->angle == tag1)
|
if (!vertices[0] && mt->angle == tag1)
|
||||||
ret->vertices[0] = mt;
|
vertices[0] = mt;
|
||||||
else if (!ret->vertices[1] && mt->angle == tag2)
|
else if (!vertices[1] && mt->angle == tag2)
|
||||||
ret->vertices[1] = mt;
|
vertices[1] = mt;
|
||||||
else if (!ret->vertices[2] && mt->angle == tag3)
|
else if (!vertices[2] && mt->angle == tag3)
|
||||||
ret->vertices[2] = mt;
|
vertices[2] = mt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now set heights for each vertex, because they haven't been set yet
|
// Now set heights for each vertex, because they haven't been set yet
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
mt = ret->vertices[i];
|
mt = vertices[i];
|
||||||
if (!mt) // If a vertex wasn't found, it's game over. There's nothing you can do to recover (except maybe try and kill the slope instead - TODO?)
|
if (!mt) // If a vertex wasn't found, it's game over. There's nothing you can do to recover (except maybe try and kill the slope instead - TODO?)
|
||||||
I_Error("P_NewVertexSlope: Slope vertex %s (for linedef tag %d) not found!", sizeu1(i), tag1);
|
I_Error("MakeViaMapthings: Slope vertex %s (for linedef tag %d) not found!", sizeu1(i), tag1);
|
||||||
|
vx[i].x = mt->x << FRACBITS;
|
||||||
|
vx[i].y = mt->y << FRACBITS;
|
||||||
if (mt->extrainfo)
|
if (mt->extrainfo)
|
||||||
mt->z = mt->options;
|
vx[i].z = mt->options << FRACBITS;
|
||||||
else
|
else
|
||||||
mt->z = (R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)->sector->floorheight >> FRACBITS) + (mt->options >> ZSHIFT);
|
vx[i].z = (R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)->sector->floorheight) + ((mt->options >> ZSHIFT) << FRACBITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
P_ReconfigureVertexSlope(ret);
|
ReconfigureViaVertexes(ret, vx[0], vx[1], vx[2]);
|
||||||
ret->refpos = 5;
|
|
||||||
|
|
||||||
// Add to the slope list
|
if (spawnthinker && (flags & SL_DYNAMIC))
|
||||||
ret->next = slopelist;
|
P_AddDynSlopeThinker(ret, DP_VERTEX, NULL, 0, tags, vx);
|
||||||
slopelist = ret;
|
|
||||||
|
|
||||||
slopecount++;
|
|
||||||
ret->id = slopecount;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create vertex based slopes.
|
||||||
|
static void line_SpawnViaVertexes(const int linenum, const boolean spawnthinker)
|
||||||
|
{
|
||||||
|
line_t *line = lines + linenum;
|
||||||
|
side_t *side;
|
||||||
|
pslope_t **slopetoset;
|
||||||
|
UINT16 tag1, tag2, tag3;
|
||||||
|
|
||||||
|
UINT8 flags = 0;
|
||||||
|
if (line->flags & ML_NOSONIC)
|
||||||
|
flags |= SL_NOPHYSICS;
|
||||||
|
if (line->flags & ML_NOTAILS)
|
||||||
|
flags |= SL_DYNAMIC;
|
||||||
|
|
||||||
|
switch(line->special)
|
||||||
|
{
|
||||||
|
case 704:
|
||||||
|
slopetoset = &line->frontsector->f_slope;
|
||||||
|
side = &sides[line->sidenum[0]];
|
||||||
|
break;
|
||||||
|
case 705:
|
||||||
|
slopetoset = &line->frontsector->c_slope;
|
||||||
|
side = &sides[line->sidenum[0]];
|
||||||
|
break;
|
||||||
|
case 714:
|
||||||
|
slopetoset = &line->backsector->f_slope;
|
||||||
|
side = &sides[line->sidenum[1]];
|
||||||
|
break;
|
||||||
|
case 715:
|
||||||
|
slopetoset = &line->backsector->c_slope;
|
||||||
|
side = &sides[line->sidenum[1]];
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line->flags & ML_NOKNUX)
|
||||||
|
{
|
||||||
|
tag1 = line->tag;
|
||||||
|
tag2 = side->textureoffset >> FRACBITS;
|
||||||
|
tag3 = side->rowoffset >> FRACBITS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tag1 = tag2 = tag3 = line->tag;
|
||||||
|
|
||||||
|
*slopetoset = MakeViaMapthings(tag1, tag2, tag3, flags, spawnthinker);
|
||||||
|
|
||||||
|
side->sector->hasslope = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -615,56 +587,23 @@ pslope_t *P_SlopeById(UINT16 id)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the dynamic slopes pointer, and read all of the fancy schmancy slopes
|
/// Reset slopes and read them from special lines.
|
||||||
void P_ResetDynamicSlopes(void) {
|
void P_ResetDynamicSlopes(const UINT32 fromsave) {
|
||||||
size_t i;
|
size_t i;
|
||||||
#ifdef ESLOPE_TYPESHIM // Rewrite old specials to new ones, and give a console warning
|
|
||||||
boolean warned = false;
|
boolean spawnthinkers = !(boolean)fromsave;
|
||||||
#endif
|
|
||||||
|
|
||||||
slopelist = NULL;
|
slopelist = NULL;
|
||||||
slopecount = 0;
|
slopecount = 0;
|
||||||
|
|
||||||
// We'll handle copy slopes later, after all the tag lists have been made.
|
dynthinklist = NULL;
|
||||||
// Yes, this means copied slopes won't affect things' spawning heights. Too bad for you.
|
dynthinknum = 0;
|
||||||
|
|
||||||
|
/// Generates line special-defined slopes.
|
||||||
for (i = 0; i < numlines; i++)
|
for (i = 0; i < numlines; i++)
|
||||||
{
|
{
|
||||||
switch (lines[i].special)
|
switch (lines[i].special)
|
||||||
{
|
{
|
||||||
#ifdef ESLOPE_TYPESHIM // Rewrite old specials to new ones, and give a console warning
|
|
||||||
#define WARNME if (!warned) {warned = true; CONS_Alert(CONS_WARNING, "This level uses old slope specials.\nA conversion will be needed before 2.2's release.\n");}
|
|
||||||
case 386:
|
|
||||||
case 387:
|
|
||||||
case 388:
|
|
||||||
lines[i].special += 700-386;
|
|
||||||
WARNME
|
|
||||||
P_SpawnSlope_Line(i);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 389:
|
|
||||||
case 390:
|
|
||||||
case 391:
|
|
||||||
case 392:
|
|
||||||
lines[i].special += 710-389;
|
|
||||||
WARNME
|
|
||||||
P_SpawnSlope_Line(i);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 393:
|
|
||||||
lines[i].special = 703;
|
|
||||||
WARNME
|
|
||||||
P_SpawnSlope_Line(i);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 394:
|
|
||||||
case 395:
|
|
||||||
case 396:
|
|
||||||
lines[i].special += 720-394;
|
|
||||||
WARNME
|
|
||||||
break;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case 700:
|
case 700:
|
||||||
case 701:
|
case 701:
|
||||||
case 702:
|
case 702:
|
||||||
|
@ -673,63 +612,35 @@ void P_ResetDynamicSlopes(void) {
|
||||||
case 711:
|
case 711:
|
||||||
case 712:
|
case 712:
|
||||||
case 713:
|
case 713:
|
||||||
P_SpawnSlope_Line(i);
|
line_SpawnViaLine(i, spawnthinkers);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 704:
|
case 704:
|
||||||
case 705:
|
case 705:
|
||||||
case 714:
|
case 714:
|
||||||
case 715:
|
case 715:
|
||||||
{
|
line_SpawnViaVertexes(i, spawnthinkers);
|
||||||
pslope_t **slopetoset;
|
|
||||||
size_t which = lines[i].special;
|
|
||||||
|
|
||||||
UINT8 flags = SL_VERTEXSLOPE;
|
|
||||||
if (lines[i].flags & ML_NOSONIC)
|
|
||||||
flags |= SL_NOPHYSICS;
|
|
||||||
if (!(lines[i].flags & ML_NOTAILS))
|
|
||||||
flags |= SL_NODYNAMIC;
|
|
||||||
|
|
||||||
if (which == 704)
|
|
||||||
{
|
|
||||||
slopetoset = &lines[i].frontsector->f_slope;
|
|
||||||
which = 0;
|
|
||||||
}
|
|
||||||
else if (which == 705)
|
|
||||||
{
|
|
||||||
slopetoset = &lines[i].frontsector->c_slope;
|
|
||||||
which = 0;
|
|
||||||
}
|
|
||||||
else if (which == 714)
|
|
||||||
{
|
|
||||||
slopetoset = &lines[i].backsector->f_slope;
|
|
||||||
which = 1;
|
|
||||||
}
|
|
||||||
else // 715
|
|
||||||
{
|
|
||||||
slopetoset = &lines[i].backsector->c_slope;
|
|
||||||
which = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lines[i].flags & ML_NOKNUX)
|
|
||||||
*slopetoset = P_NewVertexSlope(lines[i].tag, sides[lines[i].sidenum[which]].textureoffset >> FRACBITS,
|
|
||||||
sides[lines[i].sidenum[which]].rowoffset >> FRACBITS, flags);
|
|
||||||
else
|
|
||||||
*slopetoset = P_NewVertexSlope(lines[i].tag, lines[i].tag, lines[i].tag, flags);
|
|
||||||
|
|
||||||
sides[lines[i].sidenum[which]].sector->hasslope = true;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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++)
|
||||||
|
switch (lines[i].special)
|
||||||
|
{
|
||||||
|
case 720:
|
||||||
|
case 721:
|
||||||
|
case 722:
|
||||||
|
P_CopySectorSlope(&lines[i]);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
//
|
//
|
||||||
// Various utilities related to slopes
|
// Various utilities related to slopes
|
||||||
|
|
|
@ -10,17 +10,17 @@
|
||||||
/// \file p_slopes.c
|
/// \file p_slopes.c
|
||||||
/// \brief ZDoom + Eternity Engine Slopes, ported and enhanced by Kalaron
|
/// \brief ZDoom + Eternity Engine Slopes, ported and enhanced by Kalaron
|
||||||
|
|
||||||
#ifndef P_SLOPES_H__
|
#include "m_fixed.h" // Vectors
|
||||||
#define P_SLOPES_H__
|
|
||||||
|
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
|
|
||||||
|
extern pslope_t *slopelist;
|
||||||
|
extern UINT16 slopecount;
|
||||||
|
|
||||||
|
void P_LinkSlopeThinkers (void);
|
||||||
|
|
||||||
void P_CalculateSlopeNormal(pslope_t *slope);
|
void P_CalculateSlopeNormal(pslope_t *slope);
|
||||||
void P_ResetDynamicSlopes(void);
|
void P_ResetDynamicSlopes(const UINT32 fromsave);
|
||||||
void P_RunDynamicSlopes(void);
|
|
||||||
// P_SpawnSlope_Line
|
|
||||||
// Creates one or more slopes based on the given line type and front/back
|
|
||||||
// sectors.
|
|
||||||
void P_SpawnSlope_Line(int linenum);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// P_CopySectorSlope
|
// P_CopySectorSlope
|
||||||
|
@ -42,7 +42,33 @@ fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope);
|
||||||
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope);
|
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope);
|
||||||
void P_ButteredSlope(mobj_t *mo);
|
void P_ButteredSlope(mobj_t *mo);
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// EOF
|
/// Dynamic plane type enum for the thinker. Will have a different functionality depending on this.
|
||||||
|
typedef enum {
|
||||||
|
DP_FRONTFLOOR,
|
||||||
|
DP_FRONTCEIL,
|
||||||
|
DP_BACKFLOOR,
|
||||||
|
DP_BACKCEIL,
|
||||||
|
DP_VERTEX
|
||||||
|
} dynplanetype_t;
|
||||||
|
|
||||||
|
/// Permit slopes to be dynamically altered through a thinker.
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
thinker_t thinker;
|
||||||
|
|
||||||
|
pslope_t* slope;
|
||||||
|
dynplanetype_t type;
|
||||||
|
|
||||||
|
// Used by line slopes.
|
||||||
|
line_t* sourceline;
|
||||||
|
fixed_t extent;
|
||||||
|
|
||||||
|
// Used by mapthing vertex slopes.
|
||||||
|
INT16 tags[3];
|
||||||
|
vector3_t vex[3];
|
||||||
|
} dynplanethink_t;
|
||||||
|
|
||||||
|
void T_DynamicSlopeLine (dynplanethink_t* th);
|
||||||
|
void T_DynamicSlopeVert (dynplanethink_t* th);
|
||||||
#endif // #ifdef ESLOPE
|
#endif // #ifdef ESLOPE
|
||||||
|
|
13
src/p_spec.c
13
src/p_spec.c
|
@ -5558,11 +5558,6 @@ void P_UpdateSpecials(void)
|
||||||
// POINT LIMIT
|
// POINT LIMIT
|
||||||
P_CheckPointLimit();
|
P_CheckPointLimit();
|
||||||
|
|
||||||
#ifdef ESLOPE
|
|
||||||
// Dynamic slopeness
|
|
||||||
P_RunDynamicSlopes();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ANIMATE TEXTURES
|
// ANIMATE TEXTURES
|
||||||
for (anim = anims; anim < lastanim; anim++)
|
for (anim = anims; anim < lastanim; anim++)
|
||||||
{
|
{
|
||||||
|
@ -7356,14 +7351,6 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
sectors[s].extra_colormap = sectors[s].spawn_extra_colormap = sides[lines[i].sidenum[0]].colormap_data;
|
sectors[s].extra_colormap = sectors[s].spawn_extra_colormap = sides[lines[i].sidenum[0]].colormap_data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef ESLOPE // Slope copy specials. Handled here for sanity.
|
|
||||||
case 720:
|
|
||||||
case 721:
|
|
||||||
case 722:
|
|
||||||
P_CopySectorSlope(&lines[i]);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
39
src/r_defs.h
39
src/r_defs.h
|
@ -237,46 +237,27 @@ typedef struct linechain_s
|
||||||
// Slopes
|
// Slopes
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SL_NOPHYSICS = 1, // Don't do momentum adjustment with this slope
|
SL_NOPHYSICS = 1, /// This plane will have no physics applied besides the positioning.
|
||||||
SL_NODYNAMIC = 1<<1, // Slope will never need to move during the level, so don't fuss with recalculating it
|
SL_DYNAMIC = 1<<1, /// This plane slope will be assigned a thinker to make it dynamic.
|
||||||
SL_ANCHORVERTEX = 1<<2, // Slope is using a Slope Vertex Thing to anchor its position
|
|
||||||
SL_VERTEXSLOPE = 1<<3, // Slope is built from three Slope Vertex Things
|
|
||||||
} slopeflags_t;
|
} slopeflags_t;
|
||||||
|
|
||||||
typedef struct pslope_s
|
typedef struct pslope_s
|
||||||
{
|
{
|
||||||
UINT16 id; // The number of the slope, mostly used for netgame syncing purposes
|
UINT16 id; // The number of the slope, mostly used for netgame syncing purposes
|
||||||
|
struct pslope_s *next; // Make a linked list of dynamic slopes, for easy reference later
|
||||||
|
|
||||||
// --- Information used in clipping/projection ---
|
// The plane's definition.
|
||||||
// Origin vector for the plane
|
vector3_t o; /// Plane origin.
|
||||||
vector3_t o;
|
vector3_t normal; /// Plane normal.
|
||||||
|
|
||||||
// 2-Dimentional vector (x, y) normalized. Used to determine distance from
|
vector2_t d; /// Precomputed normalized projection of the normal over XY.
|
||||||
// the origin in 2d mapspace. (Basically a thrust of FRACUNIT in xydirection angle)
|
fixed_t zdelta; /// Precomputed Z unit increase per XY unit.
|
||||||
vector2_t d;
|
|
||||||
|
|
||||||
// The rate at which z changes based on distance from the origin plane.
|
|
||||||
fixed_t zdelta;
|
|
||||||
|
|
||||||
// The normal of the slope; will always point upward, and thus be inverted on ceilings. I think it's only needed for physics? -Red
|
|
||||||
vector3_t normal;
|
|
||||||
|
|
||||||
// For comparing when a slope should be rendered
|
|
||||||
fixed_t lowz;
|
|
||||||
fixed_t highz;
|
|
||||||
|
|
||||||
// This values only check and must be updated if the slope itself is modified
|
// This values only check and must be updated if the slope itself is modified
|
||||||
angle_t zangle; // Angle of the plane going up from the ground (not mesured in degrees)
|
angle_t zangle; /// Precomputed angle of the plane going up from the ground (not measured in degrees).
|
||||||
angle_t xydirection; // The direction the slope is facing (north, west, south, etc.)
|
angle_t xydirection;/// Precomputed angle of the normal's projection on the XY plane.
|
||||||
|
|
||||||
struct line_s *sourceline; // The line that generated the slope
|
|
||||||
fixed_t extent; // Distance value used for recalculating zdelta
|
|
||||||
UINT8 refpos; // 1=front floor 2=front ceiling 3=back floor 4=back ceiling (used for dynamic sloping)
|
|
||||||
|
|
||||||
UINT8 flags; // Slope options
|
UINT8 flags; // Slope options
|
||||||
mapthing_t **vertices; // List should be three long for slopes made by vertex things, or one long for slopes using one vertex thing to anchor
|
|
||||||
|
|
||||||
struct pslope_s *next; // Make a linked list of dynamic slopes, for easy reference later
|
|
||||||
} pslope_t;
|
} pslope_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue