//************************************************************************** //** //** ## ## ## ## ## #### #### ### ### //** ## ## ## ## ## ## ## ## ## ## #### #### //** ## ## ## ## ## ## ## ## ## ## ## ## ## ## //** ## ## ######## ## ## ## ## ## ## ## ### ## //** ### ## ## ### ## ## ## ## ## ## //** # ## ## # #### #### ## ## //** //** $Id: StairStepMover.vc 1744 2006-10-01 12:40:46Z dj_jl $ //** //** Copyright (C) 1999-2006 Jānis Legzdiņš //** //** This program is free software; you can redistribute it and/or //** modify it under the terms of the GNU General Public License //** as published by the Free Software Foundation; either version 2 //** of the License, or (at your option) any later version. //** //** This program is distributed in the hope that it will be useful, //** but WITHOUT ANY WARRANTY; without even the implied warranty of //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //** GNU General Public License for more details. //** //************************************************************************** class StairStepMover : SectorMover; enum { STAIRSEV_DownNormal, STAIRSEV_UpNormal, STAIRSEV_DownSync, STAIRSEV_UpSync }; float Speed; int Direction; int Crush; float FloorDestDist; float DelayTime; float DelayTotal; float StairsDelayDist; float StairsDelayDistDelta; float ResetDist; float ResetDelay; float ResetDelayTime; // Variables that were stored in stair queue array. int QueueType; float QueueHeight; StairStepMover QueueNext; // These were global variables, used only during initialisation. int StairsType; float StairStepDelta; float StairSpeed; int StairTexture; float StairStartHeight; //========================================================================== // // Init // //========================================================================== void Init(sector_t* InSector, int Arg1, int Arg2, int Arg3, int Arg4, int Arg5, int InStairsType) { int Dir; float Height; Dir = (InStairsType == STAIRSEV_DownNormal || InStairsType == STAIRSEV_DownSync) ? -1 : 1; Height = GetPlanePointZ(&InSector->floor, vector(0.0, 0.0, 0.0)); switch (InStairsType) { case STAIRSEV_DownNormal: case STAIRSEV_UpNormal: QueueInit(InSector, 0, Height, InStairsType, itof(Dir * Arg3), Dir, itof(Arg2) * 35.0 / 8.0, InSector->floor.pic, Height, itof(Arg4) / 35.0, itof(Arg5) / 35.0); break; case STAIRSEV_DownSync: case STAIRSEV_UpSync: QueueInit(InSector, 0, Height, InStairsType, itof(Dir * Arg3), Dir, itof(Arg2) * 35.0 / 8.0, InSector->floor.pic, Height, 0.0, itof(Arg4) / 35.0); break; } } //========================================================================== // // QueueInit // // New stairStep thinker // //========================================================================== void QueueInit(sector_t* InSector, int InType, float InHeight, int InStairsType, float InStairStepDelta, int InDirection, float InStairSpeed, int InStairTexture, float InStairStartHeight, float InDelay, float InResetDelay) { TVec Spot; Sector = InSector; Sector->FloorData = self; QueueType = InType; QueueHeight = InHeight; StairsType = InStairsType; StairStepDelta = InStairStepDelta; StairSpeed = InStairSpeed; StairTexture = InStairTexture; StairStartHeight = InStairStartHeight; Direction = InDirection; QueueHeight += StairStepDelta; Spot = vector(0.0, 0.0, QueueHeight); FloorDestDist = DotProduct(Sector->floor.normal, Spot); DelayTotal = InDelay; if (DelayTotal) { Spot.z = GetPlanePointZ(&Sector->floor, Spot) + StairStepDelta; StairsDelayDist = DotProduct(Sector->floor.normal, Spot); StairsDelayDistDelta = StairStepDelta; } ResetDelay = InResetDelay; ResetDelayTime = ResetDelay; ResetDist = Sector->floor.dist; switch (StairsType) { case STAIRSEV_DownNormal: case STAIRSEV_UpNormal: Speed = StairSpeed; break; case STAIRSEV_DownSync: case STAIRSEV_UpSync: Speed = StairSpeed * (QueueHeight - StairStartHeight) / StairStepDelta; break; } StartFloorSound(); } //========================================================================== // // QueueStairSector // //========================================================================== void QueueStairSector(sector_t* sec, float height) { StairStepMover Other; Other = Spawn(StairStepMover); Other.QueueInit(sec, QueueType ^ 1, height, StairsType, StairStepDelta, Direction, StairSpeed, StairTexture, StairStartHeight, DelayTotal, ResetDelay); AppendToQueue(Other); } //========================================================================== // // AppendToQueue // //========================================================================== void AppendToQueue(StairStepMover Other) { StairStepMover Tail; Tail = self; while (Tail.QueueNext) Tail = Tail.QueueNext; Tail.QueueNext = Other; } //========================================================================== // // ProcessStairSector // //========================================================================== void ProcessStairSector() { int i; sector_t* tsec; line_t* line; // // Find next sector to raise // Find nearby sector with sector special equal to type // for (i = 0; i < Sector->linecount; i++) { line = Sector->lines[i]; if (!(line->flags & ML_TWOSIDED)) { continue; } tsec = line->frontsector; if ((tsec->special & SECSPEC_BASE_MASK) == QueueType + SECSPEC_StairsSpecial1 && !tsec->FloorData && tsec->floor.pic == StairTexture) { QueueStairSector(tsec, QueueHeight); } tsec = line->backsector; if ((tsec->special & SECSPEC_BASE_MASK) == QueueType + SECSPEC_StairsSpecial1 && !tsec->FloorData && tsec->floor.pic == StairTexture) { QueueStairSector(tsec, QueueHeight); } } } //========================================================================== // // Tick // // MOVE A FLOOR TO IT'S DESTINATION (UP OR DOWN) // //========================================================================== void Tick(float deltaTime) { int res; if (ResetDelayTime) { ResetDelayTime -= deltaTime; if (ResetDelayTime <= 0.0) { ResetDelayTime = 0.0; FloorDestDist = ResetDist; Direction = -Direction; ResetDelay = 0.0; DelayTime = 0.0; DelayTotal = 0.0; } } if (DelayTime) { DelayTime -= deltaTime; if (DelayTime <= 0.0) { DelayTime = 0.0; } return; } res = MovePlane(Sector, Speed * deltaTime, FloorDestDist, Crush, 0, Direction, true); if ((Direction == 1 && Sector->floor.dist >= StairsDelayDist) || (Direction == -1 && Sector->floor.dist <= StairsDelayDist)) { DelayTime = DelayTotal; StairsDelayDist += StairsDelayDistDelta; } if (res == RES_PASTDEST) { SectorStopSequence(Sector); if (DelayTotal) { DelayTotal = 0.0; } if (ResetDelay) { // ResetDelayTime = ResetDelay; // ResetDelay = 0.0; return; } Finished(); } } //========================================================================== // // StartFloorSound // //========================================================================== void StartFloorSound() { if (!LineSpecialLevelInfo(Level).DefaultStairStepSound || Sector->seqType >= 0) { SectorStartSequence(Sector, GetSeqTrans(Sector->seqType, SEQ_Platform), 0); } else { SectorStartSequence(Sector, LineSpecialLevelInfo(Level).DefaultStairStepSound, 0); } } defaultproperties { }