123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932 |
- //**************************************************************************
- //**
- //** p_floor.c : Heretic 2 : Raven Software, Corp.
- //**
- //** $RCSfile: p_floor.c,v $
- //** $Revision: 1.23 $
- //** $Date: 95/10/06 16:53:19 $
- //** $Author: paul $
- //**
- //**************************************************************************
- #include "h2def.h"
- #include "p_local.h"
- #include "soundst.h"
- extern fixed_t FloatBobOffsets[64];
- //==================================================================
- //==================================================================
- //
- // FLOORS
- //
- //==================================================================
- //==================================================================
- //==================================================================
- //
- // Move a plane (floor or ceiling) and check for crushing
- //
- //==================================================================
- result_e T_MovePlane(sector_t *sector,fixed_t speed,
- fixed_t dest, int crush,int floorOrCeiling,int direction)
- {
- boolean flag;
- fixed_t lastpos;
- switch(floorOrCeiling)
- {
- case 0: // FLOOR
- switch(direction)
- {
- case -1: // DOWN
- if (sector->floorheight - speed < dest)
- {
- lastpos = sector->floorheight;
- sector->floorheight = dest;
- flag = P_ChangeSector(sector,crush);
- if (flag == true)
- {
- sector->floorheight =lastpos;
- P_ChangeSector(sector,crush);
- //return RES_CRUSHED;
- }
- return RES_PASTDEST;
- }
- else
- {
- lastpos = sector->floorheight;
- sector->floorheight -= speed;
- flag = P_ChangeSector(sector,crush);
- if (flag == true)
- {
- sector->floorheight = lastpos;
- P_ChangeSector(sector,crush);
- return RES_CRUSHED;
- }
- }
- break;
- case 1: // UP
- if (sector->floorheight + speed > dest)
- {
- lastpos = sector->floorheight;
- sector->floorheight = dest;
- flag = P_ChangeSector(sector,crush);
- if (flag == true)
- {
- sector->floorheight = lastpos;
- P_ChangeSector(sector,crush);
- //return RES_CRUSHED;
- }
- return RES_PASTDEST;
- }
- else // COULD GET CRUSHED
- {
- lastpos = sector->floorheight;
- sector->floorheight += speed;
- flag = P_ChangeSector(sector,crush);
- if (flag == true)
- {
- //if (crush == true)
- //{
- // return RES_CRUSHED;
- //}
- sector->floorheight = lastpos;
- P_ChangeSector(sector,crush);
- return RES_CRUSHED;
- }
- }
- break;
- }
- break;
- case 1: // CEILING
- switch(direction)
- {
- case -1: // DOWN
- if (sector->ceilingheight - speed < dest)
- {
- lastpos = sector->ceilingheight;
- sector->ceilingheight = dest;
- flag = P_ChangeSector(sector,crush);
- if (flag == true)
- {
- sector->ceilingheight = lastpos;
- P_ChangeSector(sector,crush);
- //return RES_CRUSHED;
- }
- return RES_PASTDEST;
- }
- else // COULD GET CRUSHED
- {
- lastpos = sector->ceilingheight;
- sector->ceilingheight -= speed;
- flag = P_ChangeSector(sector,crush);
- if (flag == true)
- {
- //if (crush == true)
- //{
- // return RES_CRUSHED;
- //}
- sector->ceilingheight = lastpos;
- P_ChangeSector(sector,crush);
- return RES_CRUSHED;
- }
- }
- break;
- case 1: // UP
- if (sector->ceilingheight + speed > dest)
- {
- lastpos = sector->ceilingheight;
- sector->ceilingheight = dest;
- flag = P_ChangeSector(sector,crush);
- if (flag == true)
- {
- sector->ceilingheight = lastpos;
- P_ChangeSector(sector,crush);
- //return RES_CRUSHED;
- }
- return RES_PASTDEST;
- }
- else
- {
- lastpos = sector->ceilingheight;
- sector->ceilingheight += speed;
- flag = P_ChangeSector(sector,crush);
- #if 0
- if (flag == true)
- {
- sector->ceilingheight = lastpos;
- P_ChangeSector(sector,crush);
- return RES_CRUSHED;
- }
- #endif
- }
- break;
- }
- break;
- }
- return RES_OK;
- }
- //==================================================================
- //
- // MOVE A FLOOR TO IT'S DESTINATION (UP OR DOWN)
- //
- //==================================================================
- void T_MoveFloor(floormove_t *floor)
- {
- result_e res;
- if(floor->resetDelayCount)
- {
- floor->resetDelayCount--;
- if(!floor->resetDelayCount)
- {
- floor->floordestheight = floor->resetHeight;
- floor->direction = -floor->direction;
- floor->resetDelay = 0;
- floor->delayCount = 0;
- floor->delayTotal = 0;
- }
- }
- if(floor->delayCount)
- {
- floor->delayCount--;
- if(!floor->delayCount && floor->textureChange)
- {
- floor->sector->floorpic += floor->textureChange;
- }
- return;
- }
- res = T_MovePlane(floor->sector,floor->speed,
- floor->floordestheight,floor->crush,0,floor->direction);
- if(floor->type == FLEV_RAISEBUILDSTEP)
- {
- if((floor->direction == 1 && floor->sector->floorheight >=
- floor->stairsDelayHeight) || (floor->direction == -1 &&
- floor->sector->floorheight <= floor->stairsDelayHeight))
- {
- floor->delayCount = floor->delayTotal;
- floor->stairsDelayHeight += floor->stairsDelayHeightDelta;
- }
- }
- if (res == RES_PASTDEST)
- {
- SN_StopSequence((mobj_t *)&floor->sector->soundorg);
- if(floor->delayTotal)
- {
- floor->delayTotal = 0;
- }
- if(floor->resetDelay)
- {
- // floor->resetDelayCount = floor->resetDelay;
- // floor->resetDelay = 0;
- return;
- }
- floor->sector->specialdata = NULL;
- /*
- if (floor->direction == 1)
- switch(floor->type)
- {
- case donutRaise:
- floor->sector->special = floor->newspecial;
- floor->sector->floorpic = floor->texture;
- default:
- break;
- }
- else if (floor->direction == -1)
- switch(floor->type)
- {
- case lowerAndChange:
- floor->sector->special = floor->newspecial;
- floor->sector->floorpic = floor->texture;
- default:
- break;
- }
- */
- if(floor->textureChange)
- {
- floor->sector->floorpic -= floor->textureChange;
- }
- P_TagFinished(floor->sector->tag);
- P_RemoveThinker(&floor->thinker);
- }
- }
- //==================================================================
- //
- // HANDLE FLOOR TYPES
- //
- //==================================================================
- int EV_DoFloor(line_t *line, byte *args, floor_e floortype)
- {
- int secnum;
- int rtn;
- sector_t *sec;
- floormove_t *floor=NULL;
- secnum = -1;
- rtn = 0;
- while ((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0)
- {
- sec = §ors[secnum];
- // ALREADY MOVING? IF SO, KEEP GOING...
- if (sec->specialdata)
- continue;
- //
- // new floor thinker
- //
- rtn = 1;
- floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
- memset(floor, 0, sizeof(*floor));
- P_AddThinker (&floor->thinker);
- sec->specialdata = floor;
- floor->thinker.function = T_MoveFloor;
- floor->type = floortype;
- floor->crush = 0;
- floor->speed = args[1]*(FRACUNIT/8);
- if(floortype == FLEV_LOWERTIMES8INSTANT ||
- floortype == FLEV_RAISETIMES8INSTANT)
- {
- floor->speed = 2000<<FRACBITS;
- }
- switch(floortype)
- {
- case FLEV_LOWERFLOOR:
- floor->direction = -1;
- floor->sector = sec;
- floor->floordestheight =
- P_FindHighestFloorSurrounding(sec);
- break;
- case FLEV_LOWERFLOORTOLOWEST:
- floor->direction = -1;
- floor->sector = sec;
- floor->floordestheight =
- P_FindLowestFloorSurrounding(sec);
- break;
- case FLEV_LOWERFLOORBYVALUE:
- floor->direction = -1;
- floor->sector = sec;
- floor->floordestheight = floor->sector->floorheight-
- args[2]*FRACUNIT;
- break;
- case FLEV_LOWERTIMES8INSTANT:
- case FLEV_LOWERBYVALUETIMES8:
- floor->direction = -1;
- floor->sector = sec;
- floor->floordestheight = floor->sector->floorheight-
- args[2]*FRACUNIT*8;
- break;
- case FLEV_RAISEFLOORCRUSH:
- floor->crush = args[2]; // arg[2] = crushing value
- floor->direction = 1;
- floor->sector = sec;
- floor->floordestheight = sec->ceilingheight-8*FRACUNIT;
- break;
- case FLEV_RAISEFLOOR:
- floor->direction = 1;
- floor->sector = sec;
- floor->floordestheight =
- P_FindLowestCeilingSurrounding(sec);
- if (floor->floordestheight > sec->ceilingheight)
- floor->floordestheight = sec->ceilingheight;
- break;
- case FLEV_RAISEFLOORTONEAREST:
- floor->direction = 1;
- floor->sector = sec;
- floor->floordestheight =
- P_FindNextHighestFloor(sec,sec->floorheight);
- break;
- case FLEV_RAISEFLOORBYVALUE:
- floor->direction = 1;
- floor->sector = sec;
- floor->floordestheight = floor->sector->floorheight+
- args[2]*FRACUNIT;
- break;
- case FLEV_RAISETIMES8INSTANT:
- case FLEV_RAISEBYVALUETIMES8:
- floor->direction = 1;
- floor->sector = sec;
- floor->floordestheight = floor->sector->floorheight+
- args[2]*FRACUNIT*8;
- break;
- case FLEV_MOVETOVALUETIMES8:
- floor->sector = sec;
- floor->floordestheight = args[2]*FRACUNIT*8;
- if(args[3])
- {
- floor->floordestheight = -floor->floordestheight;
- }
- if(floor->floordestheight > floor->sector->floorheight)
- {
- floor->direction = 1;
- }
- else if(floor->floordestheight < floor->sector->floorheight)
- {
- floor->direction = -1;
- }
- else
- { // already at lowest position
- rtn = 0;
- }
- break;
- default:
- rtn = 0;
- break;
- }
- }
- if(rtn)
- {
- SN_StartSequence((mobj_t *)&floor->sector->soundorg,
- SEQ_PLATFORM+floor->sector->seqType);
- }
- return rtn;
- }
- //============================================================================
- //
- // EV_DoFloorAndCeiling
- //
- //============================================================================
- int EV_DoFloorAndCeiling(line_t *line, byte *args, boolean raise)
- {
- boolean floor, ceiling;
- int secnum;
- sector_t *sec;
- if(raise)
- {
- floor = EV_DoFloor(line, args, FLEV_RAISEFLOORBYVALUE);
- secnum = -1;
- while((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0)
- {
- sec = §ors[secnum];
- sec->specialdata = NULL;
- }
- ceiling = EV_DoCeiling(line, args, CLEV_RAISEBYVALUE);
- }
- else
- {
- floor = EV_DoFloor(line, args, FLEV_LOWERFLOORBYVALUE);
- secnum = -1;
- while ((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0)
- {
- sec = §ors[secnum];
- sec->specialdata = NULL;
- }
- ceiling = EV_DoCeiling(line, args, CLEV_LOWERBYVALUE);
- }
- return (floor|ceiling);
- }
-
- // ===== Build Stairs Private Data =====
- #define STAIR_SECTOR_TYPE 26
- #define STAIR_QUEUE_SIZE 32
- struct
- {
- sector_t *sector;
- int type;
- int height;
- } StairQueue[STAIR_QUEUE_SIZE];
- static int QueueHead;
- static int QueueTail;
- static int StepDelta;
- static int Direction;
- static int Speed;
- static int Texture;
- static int StartDelay;
- static int StartDelayDelta;
- static int TextureChange;
- static int StartHeight;
- //==========================================================================
- //
- // QueueStairSector
- //
- //==========================================================================
- static void QueueStairSector(sector_t *sec, int type, int height)
- {
- if((QueueTail+1)%STAIR_QUEUE_SIZE == QueueHead)
- {
- I_Error("BuildStairs: Too many branches located.\n");
- }
- StairQueue[QueueTail].sector = sec;
- StairQueue[QueueTail].type = type;
- StairQueue[QueueTail].height = height;
- QueueTail = (QueueTail+1)%STAIR_QUEUE_SIZE;
- }
- //==========================================================================
- //
- // DequeueStairSector
- //
- //==========================================================================
- static sector_t *DequeueStairSector(int *type, int *height)
- {
- sector_t *sec;
- if(QueueHead == QueueTail)
- { // queue is empty
- return NULL;
- }
- *type = StairQueue[QueueHead].type;
- *height = StairQueue[QueueHead].height;
- sec = StairQueue[QueueHead].sector;
- QueueHead = (QueueHead+1)%STAIR_QUEUE_SIZE;
- return sec;
- }
- //==========================================================================
- //
- // ProcessStairSector
- //
- //==========================================================================
- static void ProcessStairSector(sector_t *sec, int type, int height,
- stairs_e stairsType, int delay, int resetDelay)
- {
- int i;
- sector_t *tsec;
- floormove_t *floor;
- //
- // new floor thinker
- //
- height += StepDelta;
- floor = Z_Malloc(sizeof(*floor), PU_LEVSPEC, 0);
- memset(floor, 0, sizeof(*floor));
- P_AddThinker(&floor->thinker);
- sec->specialdata = floor;
- floor->thinker.function = T_MoveFloor;
- floor->type = FLEV_RAISEBUILDSTEP;
- floor->direction = Direction;
- floor->sector = sec;
- floor->floordestheight = height;
- switch(stairsType)
- {
- case STAIRS_NORMAL:
- floor->speed = Speed;
- if(delay)
- {
- floor->delayTotal = delay;
- floor->stairsDelayHeight = sec->floorheight+StepDelta;
- floor->stairsDelayHeightDelta = StepDelta;
- }
- floor->resetDelay = resetDelay;
- floor->resetDelayCount = resetDelay;
- floor->resetHeight = sec->floorheight;
- break;
- case STAIRS_SYNC:
- floor->speed = FixedMul(Speed, FixedDiv(height-StartHeight,
- StepDelta));
- floor->resetDelay = delay; //arg4
- floor->resetDelayCount = delay;
- floor->resetHeight = sec->floorheight;
- break;
- /*
- case STAIRS_PHASED:
- floor->floordestheight = sec->floorheight+StepDelta;
- floor->speed = Speed;
- floor->delayCount = StartDelay;
- StartDelay += StartDelayDelta;
- floor->textureChange = TextureChange;
- floor->resetDelayCount = StartDelay;
- break;
- */
- default:
- break;
- }
- SN_StartSequence((mobj_t *)&sec->soundorg, SEQ_PLATFORM+sec->seqType);
- //
- // Find next sector to raise
- // Find nearby sector with sector special equal to type
- //
- for (i = 0; i < sec->linecount; i++)
- {
- if(!((sec->lines[i])->flags&ML_TWOSIDED))
- {
- continue;
- }
- tsec = (sec->lines[i])->frontsector;
- if(tsec->special == type+STAIR_SECTOR_TYPE && !tsec->specialdata
- && tsec->floorpic == Texture && tsec->validcount != validcount)
- {
- QueueStairSector(tsec, type^1, height);
- tsec->validcount = validcount;
- //tsec->special = 0;
- }
- tsec = (sec->lines[i])->backsector;
- if(tsec->special == type+STAIR_SECTOR_TYPE && !tsec->specialdata
- && tsec->floorpic == Texture && tsec->validcount != validcount)
- {
- QueueStairSector(tsec, type^1, height);
- tsec->validcount = validcount;
- //tsec->special = 0;
- }
- }
- }
- //==================================================================
- //
- // BUILD A STAIRCASE!
- //
- // Direction is either positive or negative, denoting build stairs
- // up or down.
- //==================================================================
- int EV_BuildStairs(line_t *line, byte *args, int direction,
- stairs_e stairsType)
- {
- int secnum;
- int height;
- int delay;
- int resetDelay;
- sector_t *sec;
- sector_t *qSec;
- int type;
- // Set global stairs variables
- TextureChange = 0;
- Direction = direction;
- StepDelta = Direction*(args[2]*FRACUNIT);
- Speed = args[1]*(FRACUNIT/8);
- resetDelay = args[4];
- delay = args[3];
- if(stairsType == STAIRS_PHASED)
- {
- StartDelayDelta = args[3];
- StartDelay = StartDelayDelta;
- resetDelay = StartDelayDelta;
- delay = 0;
- TextureChange = args[4];
- }
- secnum = -1;
- validcount++;
- while ((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0)
- {
- sec = §ors[secnum];
- Texture = sec->floorpic;
- StartHeight = sec->floorheight;
- // ALREADY MOVING? IF SO, KEEP GOING...
- if (sec->specialdata)
- continue;
- QueueStairSector(sec, 0, sec->floorheight);
- sec->special = 0;
- }
- while((qSec = DequeueStairSector(&type, &height)) != NULL)
- {
- ProcessStairSector(qSec, type, height, stairsType, delay, resetDelay);
- }
- return(1);
- }
- //=========================================================================
- //
- // T_BuildPillar
- //
- //=========================================================================
- void T_BuildPillar(pillar_t *pillar)
- {
- result_e res1;
- result_e res2;
- // First, raise the floor
- res1 = T_MovePlane(pillar->sector, pillar->floorSpeed, pillar->floordest,
- pillar->crush, 0, pillar->direction); // floorOrCeiling, direction
- // Then, lower the ceiling
- res2 = T_MovePlane(pillar->sector, pillar->ceilingSpeed,
- pillar->ceilingdest, pillar->crush, 1, -pillar->direction);
- if (res1 == RES_PASTDEST && res2 == RES_PASTDEST)
- {
- pillar->sector->specialdata = NULL;
- SN_StopSequence((mobj_t *)&pillar->sector->soundorg);
- P_TagFinished(pillar->sector->tag);
- P_RemoveThinker(&pillar->thinker);
- }
- }
- //=========================================================================
- //
- // EV_BuildPillar
- //
- //=========================================================================
- int EV_BuildPillar(line_t *line, byte *args, boolean crush)
- {
- int secnum;
- sector_t *sec;
- pillar_t *pillar;
- int newHeight;
- int rtn;
- rtn = 0;
- secnum = -1;
- while((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0)
- {
- sec = §ors[secnum];
- if(sec->specialdata)
- continue; // already moving
- if(sec->floorheight == sec->ceilingheight)
- { // pillar is already closed
- continue;
- }
- rtn = 1;
- if(!args[2])
- {
- newHeight = sec->floorheight+
- ((sec->ceilingheight-sec->floorheight)/2);
- }
- else
- {
- newHeight = sec->floorheight+(args[2]<<FRACBITS);
- }
- pillar = Z_Malloc(sizeof(*pillar), PU_LEVSPEC, 0);
- sec->specialdata = pillar;
- P_AddThinker(&pillar->thinker);
- pillar->thinker.function = T_BuildPillar;
- pillar->sector = sec;
- if(!args[2])
- {
- pillar->ceilingSpeed = pillar->floorSpeed = args[1]*(FRACUNIT/8);
- }
- else if(newHeight-sec->floorheight > sec->ceilingheight-newHeight)
- {
- pillar->floorSpeed = args[1]*(FRACUNIT/8);
- pillar->ceilingSpeed = FixedMul(sec->ceilingheight-newHeight,
- FixedDiv(pillar->floorSpeed, newHeight-sec->floorheight));
- }
- else
- {
- pillar->ceilingSpeed = args[1]*(FRACUNIT/8);
- pillar->floorSpeed = FixedMul(newHeight-sec->floorheight,
- FixedDiv(pillar->ceilingSpeed, sec->ceilingheight-newHeight));
- }
- pillar->floordest = newHeight;
- pillar->ceilingdest = newHeight;
- pillar->direction = 1;
- pillar->crush = crush*args[3];
- SN_StartSequence((mobj_t *)&pillar->sector->soundorg,
- SEQ_PLATFORM+pillar->sector->seqType);
- }
- return rtn;
- }
- //=========================================================================
- //
- // EV_OpenPillar
- //
- //=========================================================================
- int EV_OpenPillar(line_t *line, byte *args)
- {
- int secnum;
- sector_t *sec;
- pillar_t *pillar;
- int rtn;
- rtn = 0;
- secnum = -1;
- while((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0)
- {
- sec = §ors[secnum];
- if(sec->specialdata)
- continue; // already moving
- if(sec->floorheight != sec->ceilingheight)
- { // pillar isn't closed
- continue;
- }
- rtn = 1;
- pillar = Z_Malloc(sizeof(*pillar), PU_LEVSPEC, 0);
- sec->specialdata = pillar;
- P_AddThinker(&pillar->thinker);
- pillar->thinker.function = T_BuildPillar;
- pillar->sector = sec;
- if(!args[2])
- {
- pillar->floordest = P_FindLowestFloorSurrounding(sec);
- }
- else
- {
- pillar->floordest = sec->floorheight-(args[2]<<FRACBITS);
- }
- if(!args[3])
- {
- pillar->ceilingdest = P_FindHighestCeilingSurrounding(sec);
- }
- else
- {
- pillar->ceilingdest = sec->ceilingheight+(args[3]<<FRACBITS);
- }
- if(sec->floorheight-pillar->floordest >= pillar->ceilingdest-
- sec->ceilingheight)
- {
- pillar->floorSpeed = args[1]*(FRACUNIT/8);
- pillar->ceilingSpeed = FixedMul(sec->ceilingheight-
- pillar->ceilingdest, FixedDiv(pillar->floorSpeed,
- pillar->floordest-sec->floorheight));
- }
- else
- {
- pillar->ceilingSpeed = args[1]*(FRACUNIT/8);
- pillar->floorSpeed = FixedMul(pillar->floordest-sec->floorheight,
- FixedDiv(pillar->ceilingSpeed, sec->ceilingheight-
- pillar->ceilingdest));
- }
- pillar->direction = -1; // open the pillar
- SN_StartSequence((mobj_t *)&pillar->sector->soundorg,
- SEQ_PLATFORM+pillar->sector->seqType);
- }
- return rtn;
- }
- //=========================================================================
- //
- // EV_FloorCrushStop
- //
- //=========================================================================
- int EV_FloorCrushStop(line_t *line, byte *args)
- {
- thinker_t *think;
- floormove_t *floor;
- boolean rtn;
- rtn = 0;
- for(think = thinkercap.next; think != &thinkercap; think = think->next)
- {
- if(think->function != T_MoveFloor)
- {
- continue;
- }
- floor = (floormove_t *)think;
- if(floor->type != FLEV_RAISEFLOORCRUSH)
- {
- continue;
- }
- // Completely remove the crushing floor
- SN_StopSequence((mobj_t *)&floor->sector->soundorg);
- floor->sector->specialdata = NULL;
- P_TagFinished(floor->sector->tag);
- P_RemoveThinker(&floor->thinker);
- rtn = 1;
- }
- return rtn;
- }
- //==========================================================================
- //
- // T_FloorWaggle
- //
- //==========================================================================
- #define WGLSTATE_EXPAND 1
- #define WGLSTATE_STABLE 2
- #define WGLSTATE_REDUCE 3
- void T_FloorWaggle(floorWaggle_t *waggle)
- {
- switch(waggle->state)
- {
- case WGLSTATE_EXPAND:
- if((waggle->scale += waggle->scaleDelta)
- >= waggle->targetScale)
- {
- waggle->scale = waggle->targetScale;
- waggle->state = WGLSTATE_STABLE;
- }
- break;
- case WGLSTATE_REDUCE:
- if((waggle->scale -= waggle->scaleDelta) <= 0)
- { // Remove
- waggle->sector->floorheight = waggle->originalHeight;
- P_ChangeSector(waggle->sector, true);
- waggle->sector->specialdata = NULL;
- P_TagFinished(waggle->sector->tag);
- P_RemoveThinker(&waggle->thinker);
- return;
- }
- break;
- case WGLSTATE_STABLE:
- if(waggle->ticker != -1)
- {
- if(!--waggle->ticker)
- {
- waggle->state = WGLSTATE_REDUCE;
- }
- }
- break;
- }
- waggle->accumulator += waggle->accDelta;
- waggle->sector->floorheight = waggle->originalHeight
- +FixedMul(FloatBobOffsets[(waggle->accumulator>>FRACBITS)&63],
- waggle->scale);
- P_ChangeSector(waggle->sector, true);
- }
- //==========================================================================
- //
- // EV_StartFloorWaggle
- //
- //==========================================================================
- boolean EV_StartFloorWaggle(int tag, int height, int speed, int offset,
- int timer)
- {
- int sectorIndex;
- sector_t *sector;
- floorWaggle_t *waggle;
- boolean retCode;
- retCode = false;
- sectorIndex = -1;
- while((sectorIndex = P_FindSectorFromTag(tag, sectorIndex)) >= 0)
- {
- sector = §ors[sectorIndex];
- if(sector->specialdata)
- { // Already busy with another thinker
- continue;
- }
- retCode = true;
- waggle = Z_Malloc(sizeof(*waggle), PU_LEVSPEC, 0);
- sector->specialdata = waggle;
- waggle->thinker.function = T_FloorWaggle;
- waggle->sector = sector;
- waggle->originalHeight = sector->floorheight;
- waggle->accumulator = offset*FRACUNIT;
- waggle->accDelta = speed<<10;
- waggle->scale = 0;
- waggle->targetScale = height<<10;
- waggle->scaleDelta = waggle->targetScale
- /(35+((3*35)*height)/255);
- waggle->ticker = timer ? timer*35 : -1;
- waggle->state = WGLSTATE_EXPAND;
- P_AddThinker(&waggle->thinker);
- }
- return retCode;
- }
|