mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-04-26 04:30:58 +00:00
112 lines
No EOL
3.4 KiB
C
112 lines
No EOL
3.4 KiB
C
// [RH] p_pillar.c: New file to handle pillars
|
|
|
|
#include "z_zone.h"
|
|
#include "doomdef.h"
|
|
#include "p_local.h"
|
|
#include "p_spec.h"
|
|
#include "g_level.h"
|
|
#include "s_sndseq.h"
|
|
|
|
void T_Pillar (pillar_t *pillar)
|
|
{
|
|
int r, s;
|
|
|
|
if (pillar->type == pillarBuild) {
|
|
r = T_MovePlane (pillar->sector, pillar->floorspeed, pillar->floortarget,
|
|
pillar->crush, 0, 1);
|
|
s = T_MovePlane (pillar->sector, pillar->ceilingspeed, pillar->ceilingtarget,
|
|
pillar->crush, 1, -1);
|
|
} else {
|
|
r = T_MovePlane (pillar->sector, pillar->floorspeed, pillar->floortarget,
|
|
pillar->crush, 0, -1);
|
|
s = T_MovePlane (pillar->sector, pillar->ceilingspeed, pillar->ceilingtarget,
|
|
pillar->crush, 1, 1);
|
|
}
|
|
|
|
if (r == pastdest && s == pastdest) {
|
|
SN_StopSequence ((mobj_t *)&pillar->sector->soundorg);
|
|
pillar->sector->floordata = NULL;
|
|
pillar->sector->ceilingdata = NULL;
|
|
P_RemoveThinker (&pillar->thinker);
|
|
}
|
|
}
|
|
|
|
BOOL EV_DoPillar (pillar_e type, int tag, fixed_t speed, fixed_t height,
|
|
fixed_t height2, int crush)
|
|
{
|
|
BOOL rtn = false;
|
|
int secnum = -1;
|
|
pillar_t *pillar;
|
|
|
|
while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) {
|
|
sector_t *sec = §ors[secnum];
|
|
fixed_t ceilingdist, floordist;
|
|
|
|
if (sec->floordata || sec->ceilingdata)
|
|
continue;
|
|
|
|
if (type == pillarBuild && sec->floorheight == sec->ceilingheight)
|
|
continue;
|
|
|
|
if (type == pillarOpen && sec->floorheight != sec->ceilingheight)
|
|
continue;
|
|
|
|
rtn = true;
|
|
pillar = Z_Malloc (sizeof(*pillar), PU_LEVSPEC, 0);
|
|
P_AddThinker (&pillar->thinker);
|
|
sec->floordata = pillar;
|
|
sec->ceilingdata = pillar;
|
|
pillar->thinker.function.acp1 = (actionf_p1) T_Pillar;
|
|
pillar->type = type;
|
|
pillar->sector = sec;
|
|
pillar->crush = crush;
|
|
|
|
if (type == pillarBuild) {
|
|
// If the pillar height is 0, have the floor and ceiling meet halfway
|
|
if (height == 0) {
|
|
pillar->floortarget = pillar->ceilingtarget =
|
|
(sec->ceilingheight - sec->floorheight) / 2 + sec->floorheight;
|
|
floordist = pillar->floortarget - sec->floorheight;
|
|
} else {
|
|
pillar->floortarget = pillar->ceilingtarget =
|
|
sec->floorheight + height;
|
|
floordist = height;
|
|
}
|
|
ceilingdist = sec->ceilingheight - pillar->ceilingtarget;
|
|
} else {
|
|
// If one of the heights is 0, figure it out based on the
|
|
// surrounding sectors
|
|
if (height == 0) {
|
|
pillar->floortarget = P_FindLowestFloorSurrounding (sec);
|
|
floordist = sec->floorheight - pillar->floortarget;
|
|
} else {
|
|
floordist = height;
|
|
pillar->floortarget = sec->floorheight - height;
|
|
}
|
|
if (height2 == 0) {
|
|
pillar->ceilingtarget = P_FindHighestCeilingSurrounding (sec);
|
|
ceilingdist = pillar->ceilingtarget - sec->ceilingheight;
|
|
} else {
|
|
pillar->ceilingtarget = sec->ceilingheight + height2;
|
|
ceilingdist = height2;
|
|
}
|
|
}
|
|
|
|
// The speed parameter applies to whichever part of the pillar
|
|
// travels the farthest. The other part's speed is then set so
|
|
// that it arrives at its destination at the same time.
|
|
if (floordist > ceilingdist) {
|
|
pillar->floorspeed = speed;
|
|
pillar->ceilingspeed = FixedDiv (FixedMul (speed, ceilingdist), floordist);
|
|
} else {
|
|
pillar->ceilingspeed = speed;
|
|
pillar->floorspeed = FixedDiv (FixedMul (speed, floordist), ceilingdist);
|
|
}
|
|
|
|
if (sec->seqType >= 0)
|
|
SN_StartSequence ((mobj_t *)&sec->soundorg, sec->seqType, SEQ_PLATFORM);
|
|
else
|
|
SN_StartSequenceName ((mobj_t *)&sec->soundorg, "Floor");
|
|
}
|
|
return rtn;
|
|
} |