diff options
Diffstat (limited to 'src/hexen/p_ceilng.c')
-rw-r--r-- | src/hexen/p_ceilng.c | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/src/hexen/p_ceilng.c b/src/hexen/p_ceilng.c new file mode 100644 index 00000000..fdf09ef0 --- /dev/null +++ b/src/hexen/p_ceilng.c @@ -0,0 +1,294 @@ + +//************************************************************************** +//** +//** p_ceilng.c : Heretic 2 : Raven Software, Corp. +//** +//** $RCSfile: p_ceilng.c,v $ +//** $Revision: 1.17 $ +//** $Date: 95/09/11 22:06:25 $ +//** $Author: cjr $ +//** +//************************************************************************** + +#include "h2def.h" +#include "p_local.h" +#include "soundst.h" + +//================================================================== +//================================================================== +// +// CEILINGS +// +//================================================================== +//================================================================== + +ceiling_t *activeceilings[MAXCEILINGS]; + +//================================================================== +// +// T_MoveCeiling +// +//================================================================== +void T_MoveCeiling (ceiling_t *ceiling) +{ + result_e res; + + switch(ceiling->direction) + { +// case 0: // IN STASIS +// break; + case 1: // UP + res = T_MovePlane(ceiling->sector,ceiling->speed, + ceiling->topheight, false, 1, ceiling->direction); + if (res == RES_PASTDEST) + { + SN_StopSequence((mobj_t *)&ceiling->sector->soundorg); + switch(ceiling->type) + { + case CLEV_CRUSHANDRAISE: + ceiling->direction = -1; + ceiling->speed = ceiling->speed*2; + break; + default: + P_RemoveActiveCeiling(ceiling); + break; + } + } + break; + case -1: // DOWN + res = T_MovePlane(ceiling->sector,ceiling->speed, + ceiling->bottomheight, ceiling->crush, 1, ceiling->direction); + if(res == RES_PASTDEST) + { + SN_StopSequence((mobj_t *)&ceiling->sector->soundorg); + switch(ceiling->type) + { + case CLEV_CRUSHANDRAISE: + case CLEV_CRUSHRAISEANDSTAY: + ceiling->direction = 1; + ceiling->speed = ceiling->speed/2; + break; + default: + P_RemoveActiveCeiling(ceiling); + break; + } + } + else if(res == RES_CRUSHED) + { + switch(ceiling->type) + { + case CLEV_CRUSHANDRAISE: + case CLEV_LOWERANDCRUSH: + case CLEV_CRUSHRAISEANDSTAY: + //ceiling->speed = ceiling->speed/4; + break; + default: + break; + } + } + break; + } +} + +//================================================================== +// +// EV_DoCeiling +// Move a ceiling up/down and all around! +// +//================================================================== +int EV_DoCeiling (line_t *line, byte *arg, ceiling_e type) +{ + int secnum,rtn; + sector_t *sec; + ceiling_t *ceiling; + + secnum = -1; + rtn = 0; + +/* Old Ceiling stasis code + // + // Reactivate in-stasis ceilings...for certain types. + // + switch(type) + { + case CLEV_CRUSHANDRAISE: + P_ActivateInStasisCeiling(line); + default: + break; + } +*/ + while ((secnum = P_FindSectorFromTag(arg[0], secnum)) >= 0) + { + sec = §ors[secnum]; + if (sec->specialdata) + continue; + + // + // new door thinker + // + rtn = 1; + ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVSPEC, 0); + P_AddThinker (&ceiling->thinker); + sec->specialdata = ceiling; + ceiling->thinker.function = T_MoveCeiling; + ceiling->sector = sec; + ceiling->crush = 0; + ceiling->speed = arg[1]*(FRACUNIT/8); + switch(type) + { + case CLEV_CRUSHRAISEANDSTAY: + ceiling->crush = arg[2]; // arg[2] = crushing value + ceiling->topheight = sec->ceilingheight; + ceiling->bottomheight = sec->floorheight + (8*FRACUNIT); + ceiling->direction = -1; + break; + case CLEV_CRUSHANDRAISE: + ceiling->topheight = sec->ceilingheight; + case CLEV_LOWERANDCRUSH: + ceiling->crush = arg[2]; // arg[2] = crushing value + case CLEV_LOWERTOFLOOR: + ceiling->bottomheight = sec->floorheight; + if(type != CLEV_LOWERTOFLOOR) + { + ceiling->bottomheight += 8*FRACUNIT; + } + ceiling->direction = -1; + break; + case CLEV_RAISETOHIGHEST: + ceiling->topheight = P_FindHighestCeilingSurrounding(sec); + ceiling->direction = 1; + break; + case CLEV_LOWERBYVALUE: + ceiling->bottomheight = sec->ceilingheight-arg[2]*FRACUNIT; + ceiling->direction = -1; + break; + case CLEV_RAISEBYVALUE: + ceiling->topheight = sec->ceilingheight+arg[2]*FRACUNIT; + ceiling->direction = 1; + break; + case CLEV_MOVETOVALUETIMES8: + { + int destHeight = arg[2]*FRACUNIT*8; + + if(arg[3]) + { + destHeight = -destHeight; + } + if(sec->ceilingheight <= destHeight) + { + ceiling->direction = 1; + ceiling->topheight = destHeight; + if(sec->ceilingheight == destHeight) + { + rtn = 0; + } + } + else if(sec->ceilingheight > destHeight) + { + ceiling->direction = -1; + ceiling->bottomheight = destHeight; + } + break; + } + default: + rtn = 0; + break; + } + ceiling->tag = sec->tag; + ceiling->type = type; + P_AddActiveCeiling(ceiling); + if(rtn) + { + SN_StartSequence((mobj_t *)&ceiling->sector->soundorg, + SEQ_PLATFORM+ceiling->sector->seqType); + } + } + return rtn; +} + +//================================================================== +// +// Add an active ceiling +// +//================================================================== +void P_AddActiveCeiling(ceiling_t *c) +{ + int i; + for (i = 0; i < MAXCEILINGS;i++) + if (activeceilings[i] == NULL) + { + activeceilings[i] = c; + return; + } +} + +//================================================================== +// +// Remove a ceiling's thinker +// +//================================================================== +void P_RemoveActiveCeiling(ceiling_t *c) +{ + int i; + + for (i = 0;i < MAXCEILINGS;i++) + if (activeceilings[i] == c) + { + activeceilings[i]->sector->specialdata = NULL; + P_RemoveThinker (&activeceilings[i]->thinker); + P_TagFinished(activeceilings[i]->sector->tag); + activeceilings[i] = NULL; + break; + } +} + +#if 0 +//================================================================== +// +// Restart a ceiling that's in-stasis +// +//================================================================== +void P_ActivateInStasisCeiling(line_t *line) +{ + int i; + + for (i = 0;i < MAXCEILINGS;i++) + if (activeceilings[i] && (activeceilings[i]->tag == line->arg1) && + (activeceilings[i]->direction == 0)) + { + activeceilings[i]->direction = activeceilings[i]->olddirection; + activeceilings[i]->thinker.function = T_MoveCeiling; + SN_StartSequence((mobj_t *)&activeceilings[i]->sector->soundorg, + SEQ_PLATFORM+activeceilings[i]->sector->seqType); + } +} +#endif + +//================================================================== +// +// EV_CeilingCrushStop +// Stop a ceiling from crushing! +// +//================================================================== + +int EV_CeilingCrushStop(line_t *line, byte *args) +{ + int i; + int rtn; + + rtn = 0; + for (i = 0;i < MAXCEILINGS;i++) + { + if(activeceilings[i] && activeceilings[i]->tag == args[0]) + { + rtn = 1; + SN_StopSequence((mobj_t*)&activeceilings[i]->sector->soundorg); + activeceilings[i]->sector->specialdata = NULL; + P_RemoveThinker (&activeceilings[i]->thinker); + P_TagFinished(activeceilings[i]->sector->tag); + activeceilings[i] = NULL; + break; + } + } + return rtn; +} |