ref: 58bf0e9f39e85fbd3238458bf18403c41275ab7b
dir: /p_ceilng.c/
//************************************************************************** //** //** p_ceilng.c : Heretic 2 : Raven Software, Corp. //** //** $Revision: 472 $ //** $Date: 2009-05-26 15:45:18 +0300 (Tue, 26 May 2009) $ //** //************************************************************************** #include "h2stdinc.h" #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 *)(void *)&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 *)(void *)&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*, 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 = (ceiling_t *) Z_Malloc (sizeof(*ceiling), PU_LEVSPEC, NULL); 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 *)(void *)&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 *)(void *)&activeceilings[i]->sector->soundorg, SEQ_PLATFORM + activeceilings[i]->sector->seqType); } } } #endif //================================================================== // // EV_CeilingCrushStop // Stop a ceiling from crushing! // //================================================================== int EV_CeilingCrushStop(line_t*, 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*)(void *)&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; }