// // 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->specialdata) continue; // new floor thinker rtn = 1; floor = (floormove_t *)Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0); P_AddThinker (&floor->thinker,floor); sec->specialdata = floor; floor->thinker.function = TT_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 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; }
//================================================================== // // Do Platforms // "amount" is only used for SOME platforms. // //================================================================== int EV_DoPlat(line_t * line, plattype_e type, int amount) { plat_t *plat; int secnum; int rtn; sector_t *sec; secnum = -1; rtn = 0; // // Activate all <type> plats that are in_stasis // switch (type) { case perpetualRaise: P_ActivateInStasis(line->tag); break; default: break; } while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) { sec = §ors[secnum]; if (sec->specialdata) continue; // // Find lowest & highest floors around sector // rtn = 1; plat = Z_Malloc(sizeof(*plat), PU_LEVSPEC, 0); P_AddThinker(&plat->thinker); plat->type = type; plat->sector = sec; plat->sector->specialdata = plat; plat->thinker.function = T_PlatRaise; plat->crush = false; plat->tag = line->tag; switch (type) { case raiseToNearestAndChange: plat->speed = PLATSPEED / 2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = P_FindNextHighestFloor(sec, sec->floorheight); plat->wait = 0; plat->status = up; sec->special = 0; // NO MORE DAMAGE, IF APPLICABLE S_StartSound(&sec->soundorg, sfx_stnmov); break; case raiseAndChange: plat->speed = PLATSPEED / 2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = sec->floorheight + amount * FRACUNIT; plat->wait = 0; plat->status = up; S_StartSound(&sec->soundorg, sfx_stnmov); break; case downWaitUpStay: plat->speed = PLATSPEED * 4; plat->low = P_FindLowestFloorSurrounding(sec); if (plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = sec->floorheight; plat->wait = 35 * PLATWAIT; plat->status = down; S_StartSound(&sec->soundorg, sfx_pstart); break; case perpetualRaise: plat->speed = PLATSPEED; plat->low = P_FindLowestFloorSurrounding(sec); if (plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = P_FindHighestFloorSurrounding(sec); if (plat->high < sec->floorheight) plat->high = sec->floorheight; plat->wait = 35 * PLATWAIT; plat->status = P_Random() & 1; S_StartSound(&sec->soundorg, sfx_pstart); break; } P_AddActivePlat(plat); } return rtn; }
// // 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; }
// // EV_DoCeiling // Move a ceiling up/down and all around! // // [RH] Added tag, speed, speed2, height, crush, silent, change params BOOL EV_DoCeiling (DCeiling::ECeiling type, line_t *line, int tag, fixed_t speed, fixed_t speed2, fixed_t height, bool crush, int silent, int change) { int secnum; BOOL rtn; sector_t* sec; DCeiling* ceiling; BOOL manual = false; fixed_t targheight = 0; rtn = false; // check if a manual trigger, if so do just the sector on the backside if (tag == 0) { if (!line || !(sec = line->backsector)) return rtn; secnum = sec-sectors; manual = true; // [RH] Hack to let manual crushers be retriggerable, too tag ^= secnum | 0x1000000; P_ActivateInStasisCeiling (tag); goto manual_ceiling; } // Reactivate in-stasis ceilings...for certain types. // This restarts a crusher after it has been stopped if (type == DCeiling::ceilCrushAndRaise) { P_ActivateInStasisCeiling (tag); } secnum = -1; // affects all sectors with the same tag as the linedef while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) { sec = §ors[secnum]; manual_ceiling: // if ceiling already moving, don't start a second function on it if (sec->ceilingdata) continue; // new door thinker rtn = 1; ceiling = new DCeiling (sec, speed, speed2, silent); switch (type) { case DCeiling::ceilCrushAndRaise: case DCeiling::ceilCrushRaiseAndStay: ceiling->m_TopHeight = sec->ceilingheight; case DCeiling::ceilLowerAndCrush: ceiling->m_Crush = crush; targheight = ceiling->m_BottomHeight = sec->floorheight + 8*FRACUNIT; ceiling->m_Direction = -1; break; case DCeiling::ceilRaiseToHighest: targheight = ceiling->m_TopHeight = P_FindHighestCeilingSurrounding (sec); ceiling->m_Direction = 1; break; case DCeiling::ceilLowerByValue: targheight = ceiling->m_BottomHeight = sec->ceilingheight - height; ceiling->m_Direction = -1; break; case DCeiling::ceilRaiseByValue: targheight = ceiling->m_TopHeight = sec->ceilingheight + height; ceiling->m_Direction = 1; break; case DCeiling::ceilMoveToValue: { int diff = height - sec->ceilingheight; if (diff < 0) { targheight = ceiling->m_BottomHeight = height; ceiling->m_Direction = -1; } else { targheight = ceiling->m_TopHeight = height; ceiling->m_Direction = 1; } } break; case DCeiling::ceilLowerToHighestFloor: targheight = ceiling->m_BottomHeight = P_FindHighestFloorSurrounding (sec); ceiling->m_Direction = -1; break; case DCeiling::ceilRaiseToHighestFloor: targheight = ceiling->m_TopHeight = P_FindHighestFloorSurrounding (sec); ceiling->m_Direction = 1; break; case DCeiling::ceilLowerInstant: targheight = ceiling->m_BottomHeight = sec->ceilingheight - height; ceiling->m_Direction = -1; ceiling->m_Speed = height; break; case DCeiling::ceilRaiseInstant: targheight = ceiling->m_TopHeight = sec->ceilingheight + height; ceiling->m_Direction = 1; ceiling->m_Speed = height; break; case DCeiling::ceilLowerToNearest: targheight = ceiling->m_BottomHeight = P_FindNextLowestCeiling (sec, sec->ceilingheight); ceiling->m_Direction = 1; break; case DCeiling::ceilRaiseToNearest: targheight = ceiling->m_TopHeight = P_FindNextHighestCeiling (sec, sec->ceilingheight); ceiling->m_Direction = 1; break; case DCeiling::ceilLowerToLowest: targheight = ceiling->m_BottomHeight = P_FindLowestCeilingSurrounding (sec); ceiling->m_Direction = -1; break; case DCeiling::ceilRaiseToLowest: targheight = ceiling->m_TopHeight = P_FindLowestCeilingSurrounding (sec); ceiling->m_Direction = -1; break; case DCeiling::ceilLowerToFloor: targheight = ceiling->m_BottomHeight = sec->floorheight; ceiling->m_Direction = -1; break; case DCeiling::ceilRaiseToFloor: targheight = ceiling->m_TopHeight = sec->floorheight; ceiling->m_Direction = 1; break; case DCeiling::ceilLowerToHighest: targheight = ceiling->m_BottomHeight = P_FindHighestCeilingSurrounding (sec); ceiling->m_Direction = -1; break; case DCeiling::ceilLowerByTexture: targheight = ceiling->m_BottomHeight = sec->ceilingheight - P_FindShortestUpperAround (secnum); ceiling->m_Direction = -1; break; case DCeiling::ceilRaiseByTexture: targheight = ceiling->m_TopHeight = sec->ceilingheight + P_FindShortestUpperAround (secnum); ceiling->m_Direction = 1; break; case DCeiling::genCeilingChg0: // denis - fixme - will these need code? case DCeiling::genCeilingChgT: case DCeiling::genCeilingChg: break; } ceiling->m_Tag = tag; ceiling->m_Type = type; // set texture/type change properties if (change & 3) // if a texture change is indicated { if (change & 4) // if a numeric model change { sector_t *sec; //jff 5/23/98 find model with floor at target height if target //is a floor type sec = (type == DCeiling::ceilRaiseToHighest || type == DCeiling::ceilRaiseToFloor || type == DCeiling::ceilLowerToHighest || type == DCeiling::ceilLowerToFloor) ? P_FindModelFloorSector (targheight, secnum) : P_FindModelCeilingSector (targheight, secnum); if (sec) { ceiling->m_Texture = sec->ceilingpic; switch (change & 3) { case 1: // type is zeroed ceiling->m_NewSpecial = 0; ceiling->m_Type = DCeiling::genCeilingChg0; break; case 2: // type is copied ceiling->m_NewSpecial = sec->special; ceiling->m_Type = DCeiling::genCeilingChgT; break; case 3: // type is left alone ceiling->m_Type = DCeiling::genCeilingChg; break; } } } else if (line) // else if a trigger model change { ceiling->m_Texture = line->frontsector->ceilingpic; switch (change & 3) { case 1: // type is zeroed ceiling->m_NewSpecial = 0; ceiling->m_Type = DCeiling::genCeilingChg0; break; case 2: // type is copied ceiling->m_NewSpecial = line->frontsector->special; ceiling->m_Type = DCeiling::genCeilingChgT; break; case 3: // type is left alone ceiling->m_Type = DCeiling::genCeilingChg; break; } } } ceiling->PlayCeilingSound (); if (manual) return rtn; } return rtn; }
// // EV_DoPlat // // Handle Plat linedef types // // Passed the linedef that activated the plat, the type of plat action, // and for some plat types, an amount to raise // Returns true if a thinker is started, or restarted from stasis // int EV_DoPlat ( line_t* line, plattype_e type, int amount ) { plat_t* plat; int secnum; int rtn; sector_t* sec; secnum = -1; rtn = 0; // Activate all <type> plats that are in_stasis switch(type) { case perpetualRaise: P_ActivateInStasis(line->tag); break; case toggleUpDn: P_ActivateInStasis(line->tag); rtn=1; break; default: break; } // act on all sectors tagged the same as the activating linedef while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; // don't start a second floor function if already moving if (P_SectorActive(floor_special,sec)) //jff 2/23/98 multiple thinkers continue; // Create a thinker rtn = 1; plat = Z_Malloc( sizeof(*plat), PU_LEVSPEC, 0); memset(plat, 0, sizeof(*plat)); P_AddThinker(&plat->thinker); plat->type = type; plat->sector = sec; plat->sector->floordata = plat; //jff 2/23/98 multiple thinkers plat->thinker.function = T_PlatRaise; plat->crush = false; plat->tag = line->tag; //jff 1/26/98 Avoid raise plat bouncing a head off a ceiling and then //going down forever -- default low to plat height when triggered plat->low = sec->floorheight; // set up plat according to type switch(type) { case raiseToNearestAndChange: plat->speed = PLATSPEED/2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = P_FindNextHighestFloor(sec,sec->floorheight); plat->wait = 0; plat->status = up; sec->special = 0; //jff 3/14/98 clear old field as well sec->oldspecial = 0; S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov); break; case raiseAndChange: plat->speed = PLATSPEED/2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = sec->floorheight + amount*FRACUNIT; plat->wait = 0; plat->status = up; S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov); break; case downWaitUpStay: plat->speed = PLATSPEED * 4; plat->low = P_FindLowestFloorSurrounding(sec); if (plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = sec->floorheight; plat->wait = 35*PLATWAIT; plat->status = down; S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart); break; case blazeDWUS: plat->speed = PLATSPEED * 8; plat->low = P_FindLowestFloorSurrounding(sec); if (plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = sec->floorheight; plat->wait = 35*PLATWAIT; plat->status = down; S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart); break; case perpetualRaise: plat->speed = PLATSPEED; plat->low = P_FindLowestFloorSurrounding(sec); if (plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = P_FindHighestFloorSurrounding(sec); if (plat->high < sec->floorheight) plat->high = sec->floorheight; plat->wait = 35*PLATWAIT; plat->status = P_Random(pr_plats)&1; S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart); break; case toggleUpDn: //jff 3/14/98 add new type to support instant toggle plat->speed = PLATSPEED; //not used plat->wait = 35*PLATWAIT; //not used plat->crush = true; //jff 3/14/98 crush anything in the way // set up toggling between ceiling, floor inclusive plat->low = sec->ceilingheight; plat->high = sec->floorheight; plat->status = down; break; default: break; } P_AddActivePlat(plat); // add plat to list of active plats } return rtn; }
// // EV_DoCeiling // // Move a ceiling up/down or start a crusher // // Passed the linedef activating the function and the type of function desired // returns true if a thinker started // int EV_DoCeiling (line_t* line, ceiling_e type) { int secnum; int rtn; sector_t* sec; ceiling_t* ceiling; secnum = -1; rtn = 0; // Reactivate in-stasis ceilings...for certain types. // This restarts a crusher after it has been stopped switch (type) { case fastCrushAndRaise: case silentCrushAndRaise: case crushAndRaise: //jff 4/5/98 return if activated rtn = P_ActivateInStasisCeiling(line); default: break; } // affects all sectors with the same tag as the linedef while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) { sec = §ors[secnum]; // if ceiling already moving, don't start a second function on it if (P_SectorActive(ceiling_special, sec)) //jff 2/22/98 continue; // create a new ceiling thinker rtn = 1; ceiling = Z_Malloc(sizeof(*ceiling), PU_LEVSPEC, 0); P_AddThinker(&ceiling->thinker); sec->ceilingdata = ceiling; //jff 2/22/98 ceiling->thinker.function = T_MoveCeiling; ceiling->sector = sec; ceiling->crush = false; // setup ceiling structure according to type of function switch (type) { case fastCrushAndRaise: ceiling->crush = true; ceiling->topheight = sec->ceilingheight; ceiling->bottomheight = sec->floorheight + (8 * FRACUNIT); ceiling->direction = -1; ceiling->speed = CEILSPEED * 2; break; case silentCrushAndRaise: case crushAndRaise: ceiling->crush = true; ceiling->topheight = sec->ceilingheight; case lowerAndCrush: case lowerToFloor: ceiling->bottomheight = sec->floorheight; if (type != lowerToFloor) ceiling->bottomheight += 8 * FRACUNIT; ceiling->direction = -1; ceiling->speed = CEILSPEED; break; case raiseToHighest: ceiling->topheight = P_FindHighestCeilingSurrounding(sec); ceiling->direction = 1; ceiling->speed = CEILSPEED; break; case lowerToLowest: ceiling->bottomheight = P_FindLowestCeilingSurrounding(sec); ceiling->direction = -1; ceiling->speed = CEILSPEED; break; case lowerToMaxFloor: ceiling->bottomheight = P_FindHighestFloorSurrounding(sec); ceiling->direction = -1; ceiling->speed = CEILSPEED; break; default: break; } // add the ceiling to the active list ceiling->tag = sec->tag; ceiling->type = type; P_AddActiveCeiling(ceiling); } return rtn; }
// // EV_DoPlat // // Do Platforms "amount" is only used for SOME platforms. // int EV_DoPlat(line_t* line, plattype_e type, int amount) { plat_t* plat; int secnum; int rtn; sector_t* sec; secnum = -1; rtn = 0; // Activate all <type> plats that are in_stasis switch(type) { case perpetualRaise: P_ActivateInStasis(line->tag); break; default: break; } while((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; if (sec->specialdata) continue; // Find lowest & highest floors around sector rtn = 1; plat = Z_Malloc( sizeof(*plat), PU_LEVSPEC, 0); P_AddThinker(&plat->thinker); plat->type = type; plat->sector = sec; plat->sector->specialdata = plat; plat->thinker.function.acp1 = (actionf_p1) T_PlatRaise; plat->crush = false; plat->tag = line->tag; // haleyjd 20141001 [SVE]: protect against uninitialized plat->low // causing bounced plats that descend forever plat->low = sec->floorheight; switch(type) { case raiseToNearestAndChange: plat->speed = PLATSPEED/2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = P_FindNextHighestFloor(sec,sec->floorheight); plat->wait = 0; plat->status = up; // NO MORE DAMAGE, IF APPLICABLE sec->special = 0; S_StartSound(&sec->soundorg, sfx_stnmov); break; case raiseAndChange: plat->speed = PLATSPEED/2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = sec->floorheight + amount * FRACUNIT; plat->wait = 0; plat->status = up; S_StartSound(&sec->soundorg, sfx_stnmov); break; // villsa [STRIFE] case upWaitDownStay: plat->speed = PLATSPEED * 4; plat->high = P_FindNextHighestFloor(sec, sec->floorheight); plat->low = sec->floorheight; plat->wait = TICRATE * PLATWAIT; plat->status = up; S_StartSound(&sec->soundorg, sfx_pstart); break; case downWaitUpStay: plat->speed = PLATSPEED * 4; plat->low = P_FindLowestFloorSurrounding(sec); if(plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = sec->floorheight; plat->wait = TICRATE * PLATWAIT; plat->status = down; S_StartSound(&sec->soundorg, sfx_pstart); break; // villsa [STRIFE] case slowDWUS: plat->speed = PLATSPEED; plat->low = P_FindLowestFloorSurrounding(sec); if(plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = sec->floorheight; plat->wait = TICRATE * (PLATWAIT * 10); plat->status = down; S_StartSound(&sec->soundorg,sfx_pstart); break; case blazeDWUS: plat->speed = PLATSPEED * 8; plat->low = P_FindLowestFloorSurrounding(sec); if(plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = sec->floorheight; plat->wait = TICRATE * PLATWAIT; plat->status = down; S_StartSound(&sec->soundorg, sfx_pstart); break; case perpetualRaise: plat->speed = PLATSPEED; plat->low = P_FindLowestFloorSurrounding(sec); if(plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = P_FindHighestFloorSurrounding(sec); if(plat->high < sec->floorheight) plat->high = sec->floorheight; plat->wait = TICRATE * PLATWAIT; plat->status = P_Random() & 1; S_StartSound(&sec->soundorg, sfx_pstart); break; } P_AddActivePlat(plat); } return rtn; }
// // Do Platforms // "amount" is only used for SOME platforms. // dboolean EV_DoPlat(line_t *line, plattype_e type, int amount) { plat_t *plat; int secnum = -1; dboolean rtn = false; sector_t *sec = NULL; // Activate all <type> plats that are in_stasis switch (type) { case perpetualRaise: P_ActivateInStasis(line->tag); break; case toggleUpDn: P_ActivateInStasis(line->tag); rtn = true; break; default: break; } while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) { sec = sectors + secnum; if (P_SectorActive(floor_special, sec)) continue; // Find lowest & highest floors around sector rtn = true; plat = Z_Calloc(1, sizeof(*plat), PU_LEVSPEC, NULL); P_AddThinker(&plat->thinker); plat->type = type; plat->sector = sec; plat->sector->floordata = plat; plat->thinker.function = T_PlatRaise; plat->tag = line->tag; plat->low = sec->floorheight; switch (type) { case raiseToNearestAndChange: plat->speed = PLATSPEED / 2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = P_FindNextHighestFloor(sec, sec->floorheight); plat->status = up; sec->special = 0; S_StartSectorSound(&sec->soundorg, sfx_stnmov); break; case raiseAndChange: plat->speed = PLATSPEED / 2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = sec->floorheight + amount * FRACUNIT; plat->status = up; S_StartSectorSound(&sec->soundorg, sfx_stnmov); break; case downWaitUpStay: plat->speed = PLATSPEED * 4; plat->low = MIN(P_FindLowestFloorSurrounding(sec), sec->floorheight); plat->high = sec->floorheight; plat->wait = TICRATE * PLATWAIT; plat->status = down; S_StartSectorSound(&sec->soundorg, sfx_pstart); break; case blazeDWUS: plat->speed = PLATSPEED * 8; plat->low = MIN(P_FindLowestFloorSurrounding(sec), sec->floorheight); plat->high = sec->floorheight; plat->wait = TICRATE * PLATWAIT; plat->status = down; S_StartSectorSound(&sec->soundorg, sfx_pstart); break; case perpetualRaise: plat->speed = PLATSPEED; plat->low = MIN(P_FindLowestFloorSurrounding(sec), sec->floorheight); plat->high = MAX(sec->floorheight, P_FindHighestFloorSurrounding(sec)); plat->wait = TICRATE * PLATWAIT; plat->status = (plat_e)(M_Random() & 1); S_StartSectorSound(&sec->soundorg, sfx_pstart); break; case toggleUpDn: // jff 3/14/98 add new type to support instant toggle plat->speed = PLATSPEED; // not used plat->wait = TICRATE * PLATWAIT; // not used plat->crush = true; // jff 3/14/98 crush anything in the way // set up toggling between ceiling, floor inclusive plat->low = sec->ceilingheight; plat->high = sec->floorheight; plat->status = down; break; default: break; } P_AddActivePlat(plat); } if (sec) for (int i = 0; i < sec->linecount; i++) sec->lines[i]->flags &= ~ML_SECRET; return rtn; }
//================================================================== // // 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; }
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; } }
// // EV_DoCeiling // // Move a ceiling up/down or start a crusher // // Passed the linedef activating the function and the type of function desired // returns true if a thinker started // int EV_DoCeiling(const line_t *line, ceiling_e type) { int secnum = -1; int rtn = 0; int noise = CNOISE_NORMAL; // haleyjd 09/28/06 sector_t *sec; CeilingThinker *ceiling; // Reactivate in-stasis ceilings...for certain types. // This restarts a crusher after it has been stopped switch(type) { case fastCrushAndRaise: case silentCrushAndRaise: case crushAndRaise: //jff 4/5/98 return if activated rtn = P_ActivateInStasisCeiling(line, line->tag); default: break; } // affects all sectors with the same tag as the linedef while((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; // if ceiling already moving, don't start a second function on it if(P_SectorActive(ceiling_special, sec)) //jff 2/22/98 continue; // create a new ceiling thinker rtn = 1; ceiling = new CeilingThinker; ceiling->addThinker(); sec->ceilingdata = ceiling; //jff 2/22/98 ceiling->sector = sec; ceiling->crush = -1; ceiling->crushflags = 0; // ioanch 20160305 // setup ceiling structure according to type of function switch(type) { case fastCrushAndRaise: ceiling->crush = 10; ceiling->topheight = sec->ceilingheight; ceiling->bottomheight = sec->floorheight + (8*FRACUNIT); ceiling->direction = plat_down; ceiling->speed = CEILSPEED * 2; break; case silentCrushAndRaise: noise = CNOISE_SEMISILENT; case crushAndRaise: ceiling->crush = 10; ceiling->topheight = sec->ceilingheight; case lowerAndCrush: case lowerToFloor: ceiling->bottomheight = sec->floorheight; if(type != lowerToFloor) ceiling->bottomheight += 8*FRACUNIT; ceiling->direction = plat_down; ceiling->speed = CEILSPEED; break; case raiseToHighest: ceiling->topheight = P_FindHighestCeilingSurrounding(sec); ceiling->direction = plat_up; ceiling->speed = CEILSPEED; break; case lowerToLowest: ceiling->bottomheight = P_FindLowestCeilingSurrounding(sec); ceiling->direction = plat_down; ceiling->speed = CEILSPEED; break; case lowerToMaxFloor: ceiling->bottomheight = P_FindHighestFloorSurrounding(sec); ceiling->direction = plat_down; ceiling->speed = CEILSPEED; break; default: break; } // add the ceiling to the active list ceiling->tag = sec->tag; ceiling->type = type; P_AddActiveCeiling(ceiling); // haleyjd 09/28/06: sound sequences P_CeilingSequence(ceiling->sector, noise); } return rtn; }
// // EV_DoCeiling // Move a ceiling up/down and all around! // dboolean EV_DoCeiling(line_t *line, ceiling_e type) { int secnum = -1; dboolean rtn = false; sector_t *sec; ceiling_t *ceiling; // Reactivate in-stasis ceilings...for certain types. switch (type) { case fastCrushAndRaise: case silentCrushAndRaise: case crushAndRaise: rtn = P_ActivateInStasisCeiling(line); default: break; } while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) { sec = §ors[secnum]; if (P_SectorActive(ceiling_special, sec)) continue; // new door thinker rtn = true; ceiling = Z_Malloc(sizeof(*ceiling), PU_LEVSPEC, 0); memset(ceiling, 0, sizeof(*ceiling)); P_AddThinker(&ceiling->thinker); sec->ceilingdata = ceiling; ceiling->thinker.function = T_MoveCeiling; ceiling->sector = sec; ceiling->crush = false; switch (type) { case fastCrushAndRaise: ceiling->crush = true; ceiling->topheight = sec->ceilingheight; ceiling->bottomheight = sec->floorheight + 8 * FRACUNIT; ceiling->direction = -1; ceiling->speed = CEILSPEED * 2; break; case silentCrushAndRaise: case crushAndRaise: ceiling->crush = true; ceiling->topheight = sec->ceilingheight; case lowerAndCrush: case lowerToFloor: ceiling->bottomheight = sec->floorheight; if (type != lowerToFloor && !(gamemission == doom2 && gamemap == 4 && canmodify)) ceiling->bottomheight += 8 * FRACUNIT; ceiling->direction = -1; ceiling->speed = CEILSPEED; break; case raiseToHighest: ceiling->topheight = P_FindHighestCeilingSurrounding(sec); ceiling->direction = 1; ceiling->speed = CEILSPEED; break; case lowerToLowest: ceiling->bottomheight = P_FindLowestCeilingSurrounding(sec); ceiling->direction = -1; ceiling->speed = CEILSPEED; break; case lowerToMaxFloor: ceiling->bottomheight = P_FindHighestFloorSurrounding(sec); ceiling->direction = -1; ceiling->speed = CEILSPEED; break; } ceiling->tag = sec->tag; ceiling->type = type; P_AddActiveCeiling(ceiling); } return rtn; }
int EV_DoDoor(line_t* line, vldoor_e type) { int secnum, rtn; sector_t* sec; vldoor_t* door; secnum = -1; rtn = 0; while((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; if(sec->specialdata) continue; // new door thinker rtn = 1; door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0); P_AddThinker (&door->thinker); sec->specialdata = door; door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor; door->sector = sec; door->type = type; door->topwait = VDOORWAIT; door->speed = VDOORSPEED; R_SoundNumForDoor(door); // villsa [STRIFE] set door sounds switch(type) { // villsa [STRIFE] new door type case splitOpen: door->direction = -2; door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->speed = FRACUNIT; // yes, it using topwait to get the floor height door->topwait = P_FindLowestFloorSurrounding(sec); if(door->topheight == sec->ceilingheight) continue; S_StartSound(&sec->soundorg, door->opensound); break; // villsa [STRIFE] new door type case splitRaiseNearest: door->direction = -2; door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->speed = FRACUNIT; // yes, it using topwait to get the floor height door->topwait = P_FindHighestFloorSurrounding(sec); if(door->topheight == sec->ceilingheight) continue; S_StartSound(&sec->soundorg, door->opensound); break; case blazeClose: case shopClose: // villsa [STRIFE] door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->direction = -1; door->speed = VDOORSPEED * 4; S_StartSound(&door->sector->soundorg, sfx_bdcls); break; case close: door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->direction = -1; // villsa [STRIFE] set door sounds S_StartSound(&door->sector->soundorg, door->opensound); break; case close30ThenOpen: door->topheight = sec->ceilingheight; door->direction = -1; // villsa [STRIFE] set door sounds S_StartSound(&door->sector->soundorg, door->closesound); break; case blazeRaise: case blazeOpen: door->direction = 1; door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->speed = VDOORSPEED * 4; if (door->topheight != sec->ceilingheight) S_StartSound(&door->sector->soundorg, sfx_bdopn); break; case normal: case open: door->direction = 1; door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; if(door->topheight != sec->ceilingheight) S_StartSound(&door->sector->soundorg, door->opensound); break; default: break; } } return rtn; }