// // Do Platforms // [RH] Changed amount to height and added delay, // lip, change, tag, and speed parameters. // BOOL EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, int height, int speed, int delay, int lip, int change) { DPlat *plat; int secnum; sector_t *sec; int rtn = false; BOOL manual = false; // [RH] If tag is zero, use the sector on the back side // of the activating line (if any). if (!tag) { if (!line || !(sec = line->backsector)) return false; secnum = sec - sectors; manual = true; goto manual_plat; } // Activate all <type> plats that are in_stasis switch (type) { case DPlat::platToggle: rtn = true; case DPlat::platPerpetualRaise: P_ActivateInStasis (tag); break; default: break; } secnum = -1; while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) { sec = §ors[secnum]; manual_plat: if (sec->floordata) continue; // Find lowest & highest floors around sector rtn = true; plat = new DPlat (sec); plat->m_Type = type; plat->m_Crush = false; plat->m_Tag = tag; plat->m_Speed = speed; plat->m_Wait = delay; //jff 1/26/98 Avoid raise plat bouncing a head off a ceiling and then //going down forever -- default lower to plat height when triggered plat->m_Low = sec->floorheight; if (change) { if (line) sec->floorpic = sides[line->sidenum[0]].sector->floorpic; if (change == 1) sec->special = 0; // Stop damage and other stuff, if any } switch (type) { case DPlat::platRaiseAndStay: plat->m_High = P_FindNextHighestFloor (sec, sec->floorheight); plat->m_Status = DPlat::midup; plat->PlayPlatSound(); break; case DPlat::platUpByValue: case DPlat::platUpByValueStay: plat->m_High = sec->floorheight + height; plat->m_Status = DPlat::midup; plat->PlayPlatSound(); break; case DPlat::platDownByValue: plat->m_Low = sec->floorheight - height; plat->m_Status = DPlat::middown; plat->PlayPlatSound(); break; case DPlat::platDownWaitUpStay: plat->m_Low = P_FindLowestFloorSurrounding (sec) + lip*FRACUNIT; if (plat->m_Low > sec->floorheight) plat->m_Low = sec->floorheight; plat->m_High = sec->floorheight; plat->m_Status = DPlat::down; plat->PlayPlatSound(); break; case DPlat::platUpWaitDownStay: plat->m_High = P_FindHighestFloorSurrounding (sec); if (plat->m_High < sec->floorheight) plat->m_High = sec->floorheight; plat->m_Status = DPlat::up; plat->PlayPlatSound(); break; case DPlat::platPerpetualRaise: plat->m_Low = P_FindLowestFloorSurrounding (sec) + lip*FRACUNIT; if (plat->m_Low > sec->floorheight) plat->m_Low = sec->floorheight; plat->m_High = P_FindHighestFloorSurrounding (sec); if (plat->m_High < sec->floorheight) plat->m_High = sec->floorheight; plat->m_Status = P_Random () & 1 ? DPlat::down : DPlat::up; plat->PlayPlatSound(); break; case DPlat::platToggle: //jff 3/14/98 add new type to support instant toggle plat->m_Crush = false; //jff 3/14/98 crush anything in the way // set up toggling between ceiling, floor inclusive plat->m_Low = sec->ceilingheight; plat->m_High = sec->floorheight; plat->m_Status = DPlat::down; // SN_StartSequence (sec, "Silence"); break; case DPlat::platDownToNearestFloor: plat->m_Low = P_FindNextLowestFloor (sec, sec->floorheight) + lip*FRACUNIT; plat->m_Status = DPlat::down; plat->m_High = sec->floorheight; plat->PlayPlatSound(); break; case DPlat::platDownToLowestCeiling: plat->m_Low = P_FindLowestCeilingSurrounding (sec); plat->m_High = sec->floorheight; if (plat->m_Low > sec->floorheight) plat->m_Low = sec->floorheight; plat->m_Status = DPlat::down; plat->PlayPlatSound(); break; default: break; } if (manual) return rtn; } return rtn; }
bool FLevelLocals::EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, double height, double speed, int delay, int lip, int change) { DPlat *plat; int secnum; sector_t *sec; bool rtn = false; bool manual = false; double newheight = 0; vertex_t *spot; if (tag != 0) { // Activate all <type> plats that are in_stasis switch (type) { case DPlat::platToggle: rtn = true; case DPlat::platPerpetualRaise: ActivateInStasisPlat (tag); break; default: break; } } // [RH] If tag is zero, use the sector on the back side // of the activating line (if any). auto itr = GetSectorTagIterator(tag, line); while ((secnum = itr.Next()) >= 0) { sec = §ors[secnum]; if (sec->PlaneMoving(sector_t::floor)) { continue; } // Find lowest & highest floors around sector rtn = true; plat = CreateThinker<DPlat> (sec); plat->m_Type = type; plat->m_Crush = -1; plat->m_Tag = tag; plat->m_Speed = speed; plat->m_Wait = delay; //jff 1/26/98 Avoid raise plat bouncing a head off a ceiling and then //going down forever -- default lower to plat height when triggered plat->m_Low = sec->floorplane.fD(); if (change) { if (line) sec->SetTexture(sector_t::floor, line->sidedef[0]->sector->GetTexture(sector_t::floor)); if (change == 1) sec->ClearSpecial(); } switch (type) { case DPlat::platRaiseAndStay: case DPlat::platRaiseAndStayLockout: newheight = FindNextHighestFloor (sec, &spot); plat->m_High = sec->floorplane.PointToDist (spot, newheight); plat->m_Low = sec->floorplane.fD(); plat->m_Status = DPlat::up; plat->PlayPlatSound ("Floor"); sec->ClearSpecial(); break; case DPlat::platUpByValue: case DPlat::platUpByValueStay: newheight = sec->floorplane.ZatPoint (sec->centerspot) + height; plat->m_High = sec->floorplane.PointToDist (sec->centerspot, newheight); plat->m_Low = sec->floorplane.fD(); plat->m_Status = DPlat::up; plat->PlayPlatSound ("Floor"); break; case DPlat::platDownByValue: newheight = sec->floorplane.ZatPoint (sec->centerspot) - height; plat->m_Low = sec->floorplane.PointToDist (sec->centerspot, newheight); plat->m_High = sec->floorplane.fD(); plat->m_Status = DPlat::down; plat->PlayPlatSound ("Floor"); break; case DPlat::platDownWaitUpStay: case DPlat::platDownWaitUpStayStone: newheight = FindLowestFloorSurrounding (sec, &spot) + lip; plat->m_Low = sec->floorplane.PointToDist (spot, newheight); if (plat->m_Low < sec->floorplane.fD()) plat->m_Low = sec->floorplane.fD(); plat->m_High = sec->floorplane.fD(); plat->m_Status = DPlat::down; plat->PlayPlatSound (type == DPlat::platDownWaitUpStay ? "Platform" : "Floor"); break; case DPlat::platUpNearestWaitDownStay: newheight = FindNextHighestFloor (sec, &spot); // Intentional fall-through case DPlat::platUpWaitDownStay: if (type == DPlat::platUpWaitDownStay) { newheight = FindHighestFloorSurrounding (sec, &spot); } plat->m_High = sec->floorplane.PointToDist (spot, newheight); plat->m_Low = sec->floorplane.fD(); if (plat->m_High > sec->floorplane.fD()) plat->m_High = sec->floorplane.fD(); plat->m_Status = DPlat::up; plat->PlayPlatSound ("Platform"); break; case DPlat::platPerpetualRaise: newheight = FindLowestFloorSurrounding (sec, &spot) + lip; plat->m_Low = sec->floorplane.PointToDist (spot, newheight); if (plat->m_Low < sec->floorplane.fD()) plat->m_Low = sec->floorplane.fD(); newheight = FindHighestFloorSurrounding (sec, &spot); plat->m_High = sec->floorplane.PointToDist (spot, newheight); if (plat->m_High > sec->floorplane.fD()) plat->m_High = sec->floorplane.fD(); plat->m_Status = pr_doplat() & 1 ? DPlat::up : DPlat::down; plat->PlayPlatSound ("Platform"); break; case DPlat::platToggle: //jff 3/14/98 add new type to support instant toggle plat->m_Crush = 10; //jff 3/14/98 crush anything in the way // set up toggling between ceiling, floor inclusive newheight = FindLowestCeilingPoint(sec, &spot); plat->m_Low = sec->floorplane.PointToDist (spot, newheight); plat->m_High = sec->floorplane.fD(); plat->m_Status = DPlat::down; SN_StartSequence (sec, CHAN_FLOOR, "Silence", 0); break; case DPlat::platDownToNearestFloor: newheight = FindNextLowestFloor (sec, &spot) + lip; plat->m_Low = sec->floorplane.PointToDist (spot, newheight); plat->m_Status = DPlat::down; plat->m_High = sec->floorplane.fD(); plat->PlayPlatSound ("Platform"); break; case DPlat::platDownToLowestCeiling: newheight = FindLowestCeilingSurrounding (sec, &spot); plat->m_Low = sec->floorplane.PointToDist (spot, newheight); plat->m_High = sec->floorplane.fD(); if (plat->m_Low < sec->floorplane.fD()) plat->m_Low = sec->floorplane.fD(); plat->m_Status = DPlat::down; plat->PlayPlatSound ("Platform"); break; default: break; } } return rtn; }