mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-18 07:22:28 +00:00
Implement displacement-based polyobject rotation.
Signed-off-by: Nev3r <apophycens@gmail.com>
This commit is contained in:
parent
07a66e5355
commit
fec991dedb
4 changed files with 178 additions and 3 deletions
|
@ -28,6 +28,10 @@
|
||||||
#include "r_state.h"
|
#include "r_state.h"
|
||||||
#include "r_defs.h"
|
#include "r_defs.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define POLYOBJECTS
|
||||||
|
|
||||||
|
|
||||||
#ifdef POLYOBJECTS
|
#ifdef POLYOBJECTS
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2265,7 +2269,7 @@ void T_PolyDoorSwing(polyswingdoor_t *th)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// T_PolyObjDisplace: shift a polyobject based on a control sector's heights. -Red
|
// T_PolyObjDisplace: shift a polyobject based on a control sector's heights.
|
||||||
void T_PolyObjDisplace(polydisplace_t *th)
|
void T_PolyObjDisplace(polydisplace_t *th)
|
||||||
{
|
{
|
||||||
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
|
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
|
||||||
|
@ -2274,10 +2278,10 @@ void T_PolyObjDisplace(polydisplace_t *th)
|
||||||
|
|
||||||
if (!po)
|
if (!po)
|
||||||
#ifdef RANGECHECK
|
#ifdef RANGECHECK
|
||||||
I_Error("T_PolyDoorSwing: thinker has invalid id %d\n", th->polyObjNum);
|
I_Error("T_PolyObjDisplace: thinker has invalid id %d\n", th->polyObjNum);
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
CONS_Debug(DBG_POLYOBJ, "T_PolyDoorSwing: thinker with invalid id %d removed.\n", th->polyObjNum);
|
CONS_Debug(DBG_POLYOBJ, "T_PolyObjDisplace: thinker with invalid id %d removed.\n", th->polyObjNum);
|
||||||
P_RemoveThinkerDelayed(&th->thinker);
|
P_RemoveThinkerDelayed(&th->thinker);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2305,6 +2309,45 @@ void T_PolyObjDisplace(polydisplace_t *th)
|
||||||
th->oldHeights = newheights;
|
th->oldHeights = newheights;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// T_PolyObjRotDisplace: rotate a polyobject based on a control sector's heights.
|
||||||
|
void T_PolyObjRotDisplace(polyrotdisplace_t *th)
|
||||||
|
{
|
||||||
|
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
|
||||||
|
fixed_t newheights, delta;
|
||||||
|
fixed_t rotangle;
|
||||||
|
|
||||||
|
if (!po)
|
||||||
|
#ifdef RANGECHECK
|
||||||
|
I_Error("T_PolyObjRotDisplace: thinker has invalid id %d\n", th->polyObjNum);
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
CONS_Debug(DBG_POLYOBJ, "T_PolyObjRotDisplace: thinker with invalid id %d removed.\n", th->polyObjNum);
|
||||||
|
P_RemoveThinkerDelayed(&th->thinker);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// check for displacement due to override and reattach when possible
|
||||||
|
if (po->thinker == NULL)
|
||||||
|
{
|
||||||
|
po->thinker = &th->thinker;
|
||||||
|
|
||||||
|
// reset polyobject's thrust
|
||||||
|
po->thrust = FRACUNIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
newheights = th->controlSector->floorheight+th->controlSector->ceilingheight;
|
||||||
|
delta = newheights-th->oldHeights;
|
||||||
|
|
||||||
|
if (!delta)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rotangle = FixedMul(th->rotscale, delta);
|
||||||
|
|
||||||
|
if (Polyobj_rotate(po, FixedAngle(rotangle), th->turnobjs))
|
||||||
|
th->oldHeights = newheights;
|
||||||
|
}
|
||||||
|
|
||||||
static inline INT32 Polyobj_AngSpeed(INT32 speed)
|
static inline INT32 Polyobj_AngSpeed(INT32 speed)
|
||||||
{
|
{
|
||||||
return (speed*ANG1)>>3; // no FixedAngle()
|
return (speed*ANG1)>>3; // no FixedAngle()
|
||||||
|
@ -2764,6 +2807,52 @@ INT32 EV_DoPolyObjDisplace(polydisplacedata_t *prdata)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INT32 EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *prdata)
|
||||||
|
{
|
||||||
|
polyobj_t *po;
|
||||||
|
polyobj_t *oldpo;
|
||||||
|
polyrotdisplace_t *th;
|
||||||
|
INT32 start;
|
||||||
|
|
||||||
|
if (!(po = Polyobj_GetForNum(prdata->polyObjNum)))
|
||||||
|
{
|
||||||
|
CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", prdata->polyObjNum);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't allow line actions to affect bad polyobjects
|
||||||
|
if (po->isBad)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// create a new thinker
|
||||||
|
th = Z_Malloc(sizeof(polyrotdisplace_t), PU_LEVSPEC, NULL);
|
||||||
|
th->thinker.function.acp1 = (actionf_p1)T_PolyObjRotDisplace;
|
||||||
|
PolyObj_AddThinker(&th->thinker);
|
||||||
|
po->thinker = &th->thinker;
|
||||||
|
|
||||||
|
// set fields
|
||||||
|
th->polyObjNum = prdata->polyObjNum;
|
||||||
|
|
||||||
|
th->controlSector = prdata->controlSector;
|
||||||
|
th->oldHeights = th->controlSector->floorheight+th->controlSector->ceilingheight;
|
||||||
|
|
||||||
|
th->rotscale = prdata->rotscale;
|
||||||
|
th->turnobjs = prdata->turnobjs;
|
||||||
|
|
||||||
|
oldpo = po;
|
||||||
|
|
||||||
|
// apply action to mirroring polyobjects as well
|
||||||
|
start = 0;
|
||||||
|
while ((po = Polyobj_GetChild(oldpo, &start)))
|
||||||
|
{
|
||||||
|
prdata->polyObjNum = po->id; // change id to match child polyobject's
|
||||||
|
EV_DoPolyObjRotDisplace(prdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
// action was successful
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void T_PolyObjFlag(polymove_t *th)
|
void T_PolyObjFlag(polymove_t *th)
|
||||||
{
|
{
|
||||||
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
|
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
|
||||||
|
|
|
@ -207,6 +207,17 @@ typedef struct polydisplace_s
|
||||||
fixed_t oldHeights;
|
fixed_t oldHeights;
|
||||||
} polydisplace_t;
|
} polydisplace_t;
|
||||||
|
|
||||||
|
typedef struct polyrotdisplace_s
|
||||||
|
{
|
||||||
|
thinker_t thinker; // must be first
|
||||||
|
|
||||||
|
INT32 polyObjNum;
|
||||||
|
struct sector_s *controlSector;
|
||||||
|
fixed_t rotscale;
|
||||||
|
UINT8 turnobjs;
|
||||||
|
fixed_t oldHeights;
|
||||||
|
} polyrotdisplace_t;
|
||||||
|
|
||||||
typedef struct polyfade_s
|
typedef struct polyfade_s
|
||||||
{
|
{
|
||||||
thinker_t thinker; // must be first
|
thinker_t thinker; // must be first
|
||||||
|
@ -280,6 +291,14 @@ typedef struct polydisplacedata_s
|
||||||
fixed_t dy;
|
fixed_t dy;
|
||||||
} polydisplacedata_t;
|
} polydisplacedata_t;
|
||||||
|
|
||||||
|
typedef struct polyrotdisplacedata_s
|
||||||
|
{
|
||||||
|
INT32 polyObjNum;
|
||||||
|
struct sector_s *controlSector;
|
||||||
|
fixed_t rotscale;
|
||||||
|
UINT8 turnobjs;
|
||||||
|
} polyrotdisplacedata_t;
|
||||||
|
|
||||||
typedef struct polyfadedata_s
|
typedef struct polyfadedata_s
|
||||||
{
|
{
|
||||||
INT32 polyObjNum;
|
INT32 polyObjNum;
|
||||||
|
@ -310,6 +329,7 @@ void T_PolyObjWaypoint (polywaypoint_t *);
|
||||||
void T_PolyDoorSlide(polyslidedoor_t *);
|
void T_PolyDoorSlide(polyslidedoor_t *);
|
||||||
void T_PolyDoorSwing(polyswingdoor_t *);
|
void T_PolyDoorSwing(polyswingdoor_t *);
|
||||||
void T_PolyObjDisplace (polydisplace_t *);
|
void T_PolyObjDisplace (polydisplace_t *);
|
||||||
|
void T_PolyObjRotDisplace (polyrotdisplace_t *);
|
||||||
void T_PolyObjFlag (polymove_t *);
|
void T_PolyObjFlag (polymove_t *);
|
||||||
void T_PolyObjFade (polyfade_t *);
|
void T_PolyObjFade (polyfade_t *);
|
||||||
|
|
||||||
|
@ -318,6 +338,7 @@ INT32 EV_DoPolyObjMove(polymovedata_t *);
|
||||||
INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *);
|
INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *);
|
||||||
INT32 EV_DoPolyObjRotate(polyrotdata_t *);
|
INT32 EV_DoPolyObjRotate(polyrotdata_t *);
|
||||||
INT32 EV_DoPolyObjDisplace(polydisplacedata_t *);
|
INT32 EV_DoPolyObjDisplace(polydisplacedata_t *);
|
||||||
|
INT32 EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *);
|
||||||
INT32 EV_DoPolyObjFlag(struct line_s *);
|
INT32 EV_DoPolyObjFlag(struct line_s *);
|
||||||
INT32 EV_DoPolyObjFade(polyfadedata_t *);
|
INT32 EV_DoPolyObjFade(polyfadedata_t *);
|
||||||
|
|
||||||
|
|
|
@ -1312,6 +1312,7 @@ typedef enum
|
||||||
tc_polyswingdoor,
|
tc_polyswingdoor,
|
||||||
tc_polyflag,
|
tc_polyflag,
|
||||||
tc_polydisplace,
|
tc_polydisplace,
|
||||||
|
tc_polyrotdisplace,
|
||||||
tc_polyfade,
|
tc_polyfade,
|
||||||
#endif
|
#endif
|
||||||
tc_end
|
tc_end
|
||||||
|
@ -2088,6 +2089,17 @@ static void SavePolydisplaceThinker(const thinker_t *th, const UINT8 type)
|
||||||
WRITEFIXED(save_p, ht->oldHeights);
|
WRITEFIXED(save_p, ht->oldHeights);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void SavePolyrotdisplaceThinker(const thinker_t *th, const UINT8 type)
|
||||||
|
{
|
||||||
|
const polyrotdisplace_t *ht = (const void *)th;
|
||||||
|
WRITEUINT8(save_p, type);
|
||||||
|
WRITEINT32(save_p, ht->polyObjNum);
|
||||||
|
WRITEUINT32(save_p, SaveSector(ht->controlSector));
|
||||||
|
WRITEFIXED(save_p, ht->rotscale);
|
||||||
|
WRITEUINT8(save_p, ht->turnobjs);
|
||||||
|
WRITEFIXED(save_p, ht->oldHeights);
|
||||||
|
}
|
||||||
|
|
||||||
static void SavePolyfadeThinker(const thinker_t *th, const UINT8 type)
|
static void SavePolyfadeThinker(const thinker_t *th, const UINT8 type)
|
||||||
{
|
{
|
||||||
const polyfade_t *ht = (const void *)th;
|
const polyfade_t *ht = (const void *)th;
|
||||||
|
@ -2333,6 +2345,11 @@ static void P_NetArchiveThinkers(void)
|
||||||
SavePolydisplaceThinker(th, tc_polydisplace);
|
SavePolydisplaceThinker(th, tc_polydisplace);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
else if (th->function.acp1 == (actionf_p1)T_PolyObjRotDisplace)
|
||||||
|
{
|
||||||
|
SavePolyrotdisplaceThinker(th, tc_polyrotdisplace);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
else if (th->function.acp1 == (actionf_p1)T_PolyObjFade)
|
else if (th->function.acp1 == (actionf_p1)T_PolyObjFade)
|
||||||
{
|
{
|
||||||
SavePolyfadeThinker(th, tc_polyfade);
|
SavePolyfadeThinker(th, tc_polyfade);
|
||||||
|
@ -3217,6 +3234,18 @@ static inline void LoadPolydisplaceThinker(actionf_p1 thinker)
|
||||||
P_AddThinker(&ht->thinker);
|
P_AddThinker(&ht->thinker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void LoadPolyrotdisplaceThinker(actionf_p1 thinker)
|
||||||
|
{
|
||||||
|
polyrotdisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
||||||
|
ht->thinker.function.acp1 = thinker;
|
||||||
|
ht->polyObjNum = READINT32(save_p);
|
||||||
|
ht->controlSector = LoadSector(READUINT32(save_p));
|
||||||
|
ht->rotscale = READFIXED(save_p);
|
||||||
|
ht->turnobjs = READUINT8(save_p);
|
||||||
|
ht->oldHeights = READFIXED(save_p);
|
||||||
|
P_AddThinker(&ht->thinker);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// LoadPolyfadeThinker
|
// LoadPolyfadeThinker
|
||||||
//
|
//
|
||||||
|
@ -3446,6 +3475,10 @@ static void P_NetUnArchiveThinkers(void)
|
||||||
LoadPolydisplaceThinker((actionf_p1)T_PolyObjDisplace);
|
LoadPolydisplaceThinker((actionf_p1)T_PolyObjDisplace);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case tc_polyrotdisplace:
|
||||||
|
LoadPolyrotdisplaceThinker((actionf_p1)T_PolyObjRotDisplace);
|
||||||
|
break;
|
||||||
|
|
||||||
case tc_polyfade:
|
case tc_polyfade:
|
||||||
LoadPolyfadeThinker((actionf_p1)T_PolyObjFade);
|
LoadPolyfadeThinker((actionf_p1)T_PolyObjFade);
|
||||||
break;
|
break;
|
||||||
|
|
32
src/p_spec.c
32
src/p_spec.c
|
@ -1412,6 +1412,34 @@ static boolean PolyDisplace(line_t *line)
|
||||||
return EV_DoPolyObjDisplace(&pdd);
|
return EV_DoPolyObjDisplace(&pdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Similar to PolyDisplace().
|
||||||
|
*/
|
||||||
|
static boolean PolyRotDisplace(line_t *line)
|
||||||
|
{
|
||||||
|
polyrotdisplacedata_t pdd;
|
||||||
|
fixed_t anginter, distinter;
|
||||||
|
|
||||||
|
pdd.polyObjNum = line->tag;
|
||||||
|
pdd.controlSector = line->frontsector;
|
||||||
|
|
||||||
|
// Rotate 'anginter' interval for each 'distinter' interval from the control sector.
|
||||||
|
// Use default values if not provided as fallback.
|
||||||
|
anginter = sides[line->sidenum[0]].rowoffset ? sides[line->sidenum[0]].rowoffset : 90*FRACUNIT;
|
||||||
|
distinter = sides[line->sidenum[0]].textureoffset ? sides[line->sidenum[0]].textureoffset : 128*FRACUNIT;
|
||||||
|
pdd.rotscale = FixedDiv(anginter, distinter);
|
||||||
|
|
||||||
|
// Same behavior as other rotators when carrying things.
|
||||||
|
if (line->flags & ML_NOCLIMB)
|
||||||
|
pdd.turnobjs = 0;
|
||||||
|
else if (line->flags & ML_EFFECT4)
|
||||||
|
pdd.turnobjs = 2;
|
||||||
|
else
|
||||||
|
pdd.turnobjs = 1;
|
||||||
|
|
||||||
|
return EV_DoPolyObjRotDisplace(&pdd);
|
||||||
|
}
|
||||||
|
|
||||||
#endif // ifdef POLYOBJECTS
|
#endif // ifdef POLYOBJECTS
|
||||||
|
|
||||||
/** Changes a sector's tag.
|
/** Changes a sector's tag.
|
||||||
|
@ -7363,6 +7391,10 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
case 31: // Polyobj_Displace
|
case 31: // Polyobj_Displace
|
||||||
PolyDisplace(&lines[i]);
|
PolyDisplace(&lines[i]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 32: // Polyobj_RotDisplace
|
||||||
|
PolyRotDisplace(&lines[i]);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue