// // 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; }
// // Handle elevator linedef types, can move floor and ceiling in parallel. // This is from Boom. // int EV_DoElevator(line_t *line, elevator_e elevtype) { int secnum; int rtn; sector_t *sec; elevator_t *elevator; secnum = -1; rtn = 0; // act on all sectors with the same tag as the triggering linedef while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) { sec = §ors[secnum]; // if either floor or ceiling is already activated, skip it if (sec->floordata || sec->ceilingdata) continue; // create and initialize new elevator thinker rtn = 1; elevator = Z_Malloc(sizeof(*elevator), PU_LEVSPEC, (void *)0); P_AddThinker(&elevator->thinker); sec->floordata = elevator; sec->ceilingdata = elevator; elevator->thinker.function.acp1 = (actionf_p1)T_MoveElevator; elevator->type = elevtype; // set up the fields according to the type of elevator action switch (elevtype) { // elevator down to next floor case elevateDown: elevator->direction = -1; elevator->sector = sec; elevator->speed = ELEVATORSPEED; elevator->floordestheight = P_FindNextLowestFloor(sec, sec->floorheight); elevator->ceilingdestheight = elevator->floordestheight + sec->ceilingheight - sec->floorheight; break; // elevator up to next floor case elevateUp: elevator->direction = 1; elevator->sector = sec; elevator->speed = ELEVATORSPEED; elevator->floordestheight = P_FindNextHighestFloor(sec, sec->floorheight); elevator->ceilingdestheight = elevator->floordestheight + sec->ceilingheight - sec->floorheight; break; // elevator to floor height of activating switch's front sector case elevateCurrent: elevator->sector = sec; elevator->speed = ELEVATORSPEED; elevator->floordestheight = line->frontsector->floorheight; elevator->ceilingdestheight = elevator->floordestheight + sec->ceilingheight - sec->floorheight; elevator->direction = elevator->floordestheight > sec->floorheight ? 1 : -1; break; } } return rtn; }
DPlat::DPlat(sector_t *sec, DPlat::EPlatType type, fixed_t height, int speed, int delay, fixed_t lip) : DMovingFloor(sec), m_Status(init) { m_Type = type; m_Crush = false; m_Speed = speed; m_Wait = delay; m_Height = height; m_Lip = lip; //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 m_Low = P_FloorHeight(sec); switch (type) { case DPlat::platRaiseAndStay: m_High = P_FindNextHighestFloor(sec); m_Status = DPlat::midup; PlayPlatSound(); break; case DPlat::platUpByValue: case DPlat::platUpByValueStay: m_High = P_FloorHeight(sec) + height; m_Status = DPlat::midup; PlayPlatSound(); break; case DPlat::platDownByValue: m_Low = P_FloorHeight(sec) - height; m_Status = DPlat::middown; PlayPlatSound(); break; case DPlat::platDownWaitUpStay: m_Low = P_FindLowestFloorSurrounding(sec) + lip; if (m_Low > P_FloorHeight(sec)) m_Low = P_FloorHeight(sec); m_High = P_FloorHeight(sec); m_Status = DPlat::down; PlayPlatSound(); break; case DPlat::platUpWaitDownStay: m_High = P_FindHighestFloorSurrounding(sec); if (m_High < P_FloorHeight(sec)) m_High = P_FloorHeight(sec); m_Status = DPlat::up; PlayPlatSound(); break; case DPlat::platPerpetualRaise: m_Low = P_FindLowestFloorSurrounding(sec) + lip; if (m_Low > P_FloorHeight(sec)) m_Low = P_FloorHeight(sec); m_High = P_FindHighestFloorSurrounding (sec); if (m_High < P_FloorHeight(sec)) m_High = P_FloorHeight(sec); m_Status = P_Random () & 1 ? DPlat::down : DPlat::up; PlayPlatSound(); break; case DPlat::platToggle: //jff 3/14/98 add new type to support instant toggle m_Crush = false; //jff 3/14/98 crush anything in the way // set up toggling between ceiling, floor inclusive m_Low = P_CeilingHeight(sec); m_High = P_FloorHeight(sec); m_Status = DPlat::down; // SN_StartSequence (sec, "Silence"); break; case DPlat::platDownToNearestFloor: m_Low = P_FindNextLowestFloor(sec) + lip; m_Status = DPlat::down; m_High = P_FloorHeight(sec); PlayPlatSound(); break; case DPlat::platDownToLowestCeiling: m_Low = P_FindLowestCeilingSurrounding (sec); m_High = P_FloorHeight(sec); if (m_Low > P_FloorHeight(sec)) m_Low = P_FloorHeight(sec); m_Status = DPlat::down; PlayPlatSound(); break; default: break; } }
// // HANDLE FLOOR TYPES // int EV_DoFloor(line_t *line, floor_e floortype) { int secnum; int rtn; int i; sector_t *sec; floormove_t *floor; secnum = -1; rtn = 0; while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) { sec = §ors[secnum]; // ALREADY MOVING? IF SO, KEEP GOING... if (sec->floordata) continue; // new floor thinker rtn = 1; floor = Z_Malloc(sizeof(*floor), PU_LEVSPEC, (void *)0); P_AddThinker(&floor->thinker); sec->floordata = floor; floor->thinker.function.acp1 = (actionf_p1)T_MoveFloor; floor->type = floortype; floor->crush = false; switch(floortype) { case lowerFloor: floor->direction = -1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindHighestFloorSurrounding(sec); break; case lowerFloorToLowest: floor->direction = -1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindLowestFloorSurrounding(sec); break; case lowerFloorToNearest: floor->direction = -1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindNextLowestFloor(sec, floor->sector->floorheight); break; case turboLower: floor->direction = -1; floor->sector = sec; floor->speed = FLOORSPEED * 4; floor->floordestheight = P_FindHighestFloorSurrounding(sec); if (floor->floordestheight != sec->floorheight) floor->floordestheight += 8 * FRACUNIT; break; case raiseFloorCrush: floor->crush = true; case raiseFloor: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindLowestCeilingSurrounding(sec); if (floor->floordestheight > sec->ceilingheight) floor->floordestheight = sec->ceilingheight; floor->floordestheight -= (8 * FRACUNIT) * (floortype == raiseFloorCrush); break; case raiseFloorTurbo: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED * 4; floor->floordestheight = P_FindNextHighestFloor(sec, sec->floorheight); break; case raiseFloorToNearest: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindNextHighestFloor(sec, sec->floorheight); break; case raiseFloor24: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = floor->sector->floorheight + 24 * FRACUNIT; break; case raiseFloor512: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = floor->sector->floorheight + 512 * FRACUNIT; break; case raiseFloor24AndChange: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = floor->sector->floorheight + 24 * FRACUNIT; sec->floorpic = line->frontsector->floorpic; sec->special = line->frontsector->special; break; case raiseToTexture: { int minsize = MAXINT; side_t *side; floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; for (i = 0; i < sec->linecount; i++) { if (twoSided (secnum, i) ) { side = getSide(secnum, i, 0); if (side->bottomtexture >= 0) if (textureheight[side->bottomtexture] < minsize) minsize = textureheight[side->bottomtexture]; side = getSide(secnum, i, 1); if (side->bottomtexture >= 0) if (textureheight[side->bottomtexture] < minsize) minsize = textureheight[side->bottomtexture]; } } floor->floordestheight = floor->sector->floorheight + minsize; } break; case lowerAndChange: floor->direction = -1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindLowestFloorSurrounding(sec); floor->texture = sec->floorpic; for (i = 0; i < sec->linecount; i++) { if ( twoSided(secnum, i) ) { if (getSide(secnum, i, 0)->sector-sectors == secnum) { sec = getSector(secnum, i, 1); if (sec->floorheight == floor->floordestheight) { floor->texture = sec->floorpic; floor->newspecial = sec->special; break; } } else { sec = getSector(secnum, i, 0); if (sec->floorheight == floor->floordestheight) { floor->texture = sec->floorpic; floor->newspecial = sec->special; break; } } } } default: break; } } return rtn; }