Merge branch 'plane-displacement' into 'master'

Plane displacement

Basic support for plane displacement, no netplay support as of writing but this is what Nev3r wanted moreorless at least.

Linedef types 66-68 are the plane displacement specials; 66 = move floor only, 67 = move ceiling only, 68 = both

Front sector = control sector
Tag = tag of target sectors to be moved whenever the control sector floor moves
Linedef length = movement factor relative to control sector movement, 256 = 1:1 with control sector. 128 is half as much, 512 is twice as much, etc.

Whenever the control sector floor moves (not ceiling, never ceiling), the selected planes of the tagged sectors all move (mind, they have a tic delay due to how it all works, it's not perfect really). No support for reverse speeds yet sorry.

EDIT: oh, btw, test exe and test map are included in my folder on the FTP (srb2win-plane-displacement.exe and plane-disp-test.wad, respectively)

See merge request !61
This commit is contained in:
Monster Iestyn 2017-01-24 14:29:38 -05:00
commit 4b97333ed7
4 changed files with 127 additions and 0 deletions

View File

@ -2523,6 +2523,29 @@ void T_CameraScanner(elevator_t *elevator)
}
}
void T_PlaneDisplace(planedisplace_t *pd)
{
sector_t *control, *target;
INT32 direction;
fixed_t diff;
control = &sectors[pd->control];
target = &sectors[pd->affectee];
if (control->floorheight == pd->last_height)
return; // no change, no movement
direction = (control->floorheight > pd->last_height) ? 1 : -1;
diff = FixedMul(control->floorheight-pd->last_height, pd->speed);
if (pd->type == pd_floor || pd->type == pd_both)
T_MovePlane(target, INT32_MAX/2, target->floorheight+diff, 0, 0, direction); // move floor
if (pd->type == pd_ceiling || pd->type == pd_both)
T_MovePlane(target, INT32_MAX/2, target->ceilingheight+diff, 0, 1, direction); // move ceiling
pd->last_height = control->floorheight;
}
//
// EV_DoFloor
//

View File

@ -974,6 +974,7 @@ typedef enum
tc_noenemies,
tc_eachtime,
tc_disappear,
tc_planedisplace,
#ifdef POLYOBJECTS
tc_polyrotate, // haleyjd 03/26/06: polyobjects
tc_polymove,
@ -1537,6 +1538,21 @@ static void SaveDisappearThinker(const thinker_t *th, const UINT8 type)
WRITEINT32(save_p, ht->exists);
}
//
// SavePlaneDisplaceThinker
//
// Saves a planedisplace_t thinker
//
static void SavePlaneDisplaceThinker(const thinker_t *th, const UINT8 type)
{
const planedisplace_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEINT32(save_p, ht->affectee);
WRITEINT32(save_p, ht->control);
WRITEFIXED(save_p, ht->last_height);
WRITEFIXED(save_p, ht->speed);
WRITEUINT8(save_p, ht->type);
}
#ifdef POLYOBJECTS
//
@ -1818,6 +1834,12 @@ static void P_NetArchiveThinkers(void)
SaveDisappearThinker(th, tc_disappear);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_PlaneDisplace)
{
SavePlaneDisplaceThinker(th, tc_planedisplace);
continue;
}
#ifdef POLYOBJECTS
else if (th->function.acp1 == (actionf_p1)T_PolyObjRotate)
{
@ -2486,6 +2508,23 @@ static inline void LoadDisappearThinker(actionf_p1 thinker)
P_AddThinker(&ht->thinker);
}
//
// LoadPlaneDisplaceThinker
//
// Loads a planedisplace_t thinker
//
static inline void LoadPlaneDisplaceThinker(actionf_p1 thinker)
{
planedisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->affectee = READINT32(save_p);
ht->control = READINT32(save_p);
ht->last_height = READFIXED(save_p);
ht->speed = READFIXED(save_p);
ht->type = READUINT8(save_p);
P_AddThinker(&ht->thinker);
}
#ifdef POLYOBJECTS
//
@ -2769,6 +2808,10 @@ static void P_NetUnArchiveThinkers(void)
case tc_disappear:
LoadDisappearThinker((actionf_p1)T_Disappear);
break;
case tc_planedisplace:
LoadPlaneDisplaceThinker((actionf_p1)T_PlaneDisplace);
break;
#ifdef POLYOBJECTS
case tc_polyrotate:
LoadPolyrotatetThinker((actionf_p1)T_PolyObjRotate);

View File

@ -108,6 +108,7 @@ static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinker
static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec);
static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer);
static void P_AddSpikeThinker(sector_t *sec, INT32 referrer);
static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee);
//SoM: 3/7/2000: New sturcture without limits.
@ -5083,6 +5084,33 @@ static inline void P_AddBridgeThinker(line_t *sourceline, sector_t *sec)
}
*/
/**
* Adds a plane displacement thinker.
* Whenever the "control" sector moves,
* the "affectee" sector's floor or ceiling plane moves too!
*
* \param speed Rate of movement relative to control sector
* \param control Control sector.
* \param affectee Target sector.
* \sa P_SpawnSpecials, T_PlaneDisplace
* \author Monster Iestyn
*/
static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee)
{
planedisplace_t *displace;
// create and initialize new displacement thinker
displace = Z_Calloc(sizeof (*displace), PU_LEVSPEC, NULL);
P_AddThinker(&displace->thinker);
displace->thinker.function.acp1 = (actionf_p1)T_PlaneDisplace;
displace->affectee = affectee;
displace->control = control;
displace->last_height = sectors[control].floorheight;
displace->speed = speed;
displace->type = type;
}
/** Adds a Mario block thinker, which changes the block's texture between blank
* and ? depending on whether it has contents.
* Needed in case objects respawn inside.
@ -5795,6 +5823,19 @@ void P_SpawnSpecials(INT32 fromnetsave)
P_AddBridgeThinker(&lines[i], &sectors[s]);*/
break;
case 66: // Displace floor by front sector
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
P_AddPlaneDisplaceThinker(pd_floor, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s);
break;
case 67: // Displace ceiling by front sector
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
P_AddPlaneDisplaceThinker(pd_ceiling, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s);
break;
case 68: // Displace both floor AND ceiling by front sector
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
P_AddPlaneDisplaceThinker(pd_both, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s);
break;
case 100: // FOF (solid, opaque, shadows)
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers);
break;

View File

@ -450,6 +450,26 @@ void T_Disappear(disappear_t *d);
void T_Pusher(pusher_t *p);
mobj_t *P_GetPushThing(UINT32 s);
// Plane displacement
typedef struct
{
thinker_t thinker; ///< Thinker structure for plane displacement effect.
INT32 affectee; ///< Number of affected sector.
INT32 control; ///< Control sector used to control plane positions.
fixed_t last_height; ///< Last known height of control sector.
fixed_t speed; ///< Plane movement speed.
/** Types of plane displacement effects.
*/
enum
{
pd_floor, ///< Displace floor.
pd_ceiling, ///< Displace ceiling.
pd_both, ///< Displace both floor AND ceiling.
} type;
} planedisplace_t;
void T_PlaneDisplace(planedisplace_t *pd);
void P_CalcHeight(player_t *player);
sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo);