// // 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; }
int EV_DoDoorR ( line_t* line, vldoor_e type, mobj_t* thing ) { int secnum,rtn; int newheight; sector_t* sec; vldoor_t* door; rtn = 0; secnum = -1; while ((secnum = P_FindSectorFromLineTag (line,secnum)) >= 0) { sec = §ors[secnum]; #if 0 if (P_SectorActive(ceiling_special, sec)) continue; #else door = sec->ceilingdata; if (door) { if ((line -> tag == 0) && (door->thinker.function.acp1 == (actionf_p1) T_VerticalDoor)) { switch (door->type) { case normal: // ONLY FOR "RAISE" DOORS, NOT "OPEN"s case blazeRaise: if (door->direction == -1) { door->direction = 1; // go back up } else if ((thing)&&(thing->player))// JDC: bad guys never close doors { door->direction = -1; // start going down immediately } } } continue; } #endif // new door thinker rtn = 1; door = get_door_block (sec); door->type = type; switch(type) { case blazeClose: door->speed = VDOORSPEED * 4; case normalClose: newheight = P_FindLowestCeilingSurrounding(sec); door->topheight = newheight - 4*FRACUNIT; door->direction = -1; T_Makedoorsound (door); break; case close30ThenOpen: door->topheight = sec->ceilingheight; door->direction = -1; T_Makedoorsound (door); break; case blazeRaise: case blazeOpen: door->speed = VDOORSPEED * 4; case normal: case normalOpen: // door->direction = 1; newheight = P_FindNextHighestCeiling (sec, sec->ceilingheight); if (newheight > sec->ceilingheight) // Returns current height if none found... { newheight -= 4*FRACUNIT; if (newheight > sec->ceilingheight) // Is door going to move? T_Makedoorsound (door); } door->topheight = newheight; break; } } return rtn; }