bool EV_CeilingCrushStop (int tag, bool remove) { bool rtn = false; DCeiling *scan; TThinkerIterator<DCeiling> iterator; scan = iterator.Next(); while (scan != nullptr) { DCeiling *next = iterator.Next(); if (scan->m_Tag == tag && scan->m_Direction != 0) { if (!remove) { SN_StopSequence(scan->m_Sector, CHAN_CEILING); scan->m_OldDirection = scan->m_Direction; scan->m_Direction = 0; // in-stasis; } else { scan->Destroy(); } rtn = true; } scan = next; } return rtn; }
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; }
void SN_StartSequence(mobj_t *mobj, int sequence) { seqnode_t *node; SN_StopSequence(mobj); // Stop any previous sequence node = (seqnode_t *)Z_Malloc(sizeof(seqnode_t), PU_STATIC, NULL); node->sequencePtr = SequenceData[SequenceTranslate[sequence].scriptNum]; node->sequence = sequence; node->mobj = mobj; node->delayTics = 0; node->stopSound = SequenceTranslate[sequence].stopSound; node->volume = 127; // Start at max volume if(!SequenceListHead) { SequenceListHead = node; node->next = node->prev = NULL; } else { SequenceListHead->prev = node; node->next = SequenceListHead; node->prev = NULL; SequenceListHead = node; } ActiveSequences++; return; }
void SN_StopAllSequences(void) { seqnode_t *node; for(node = SequenceListHead; node; node = node->next) { node->stopSound = 0; // don't play any stop sounds SN_StopSequence(node->mobj); } }
// same as above but stops any floor mover that was active on the given sector. bool EV_StopFloor(int tag, line_t *line) { int sec; FSectorTagIterator it(tag, line); while ((sec = it.Next()) >= 0) { if (level.sectors[sec].floordata) { SN_StopSequence(&level.sectors[sec], CHAN_FLOOR); level.sectors[sec].floordata->Destroy(); level.sectors[sec].floordata = nullptr; } } return true; }
bool EV_StopCeiling(int tag, line_t *line) { int sec; FSectorTagIterator it(tag, line); while ((sec = it.Next()) >= 0) { if (level.sectors[sec].ceilingdata) { SN_StopSequence(&level.sectors[sec], CHAN_CEILING); level.sectors[sec].ceilingdata->Destroy(); level.sectors[sec].ceilingdata = nullptr; } } return true; }
bool EV_FloorCrushStop (int tag, line_t *line) { int secnum; FSectorTagIterator it(tag, line); while ((secnum = it.Next()) >= 0) { sector_t *sec = &level.sectors[secnum]; if (sec->floordata && sec->floordata->IsKindOf (RUNTIME_CLASS(DFloor)) && barrier_cast<DFloor *>(sec->floordata)->m_Type == DFloor::floorRaiseAndCrush) { SN_StopSequence (sec, CHAN_FLOOR); sec->floordata->Destroy (); sec->floordata = NULL; } } return true; }
// Stop a ceiling from crushing! int Map::EV_StopCeiling(unsigned tag) { int rtn = 0; list<ceiling_t *>::iterator i; for (i = activeceilings.begin(); i != activeceilings.end(); i++) { ceiling_t *ceil = *i; if (!(ceil->type & ceiling_t::InStasis) && ceil->sector->tag == tag) { SN_StopSequence(&ceil->sector->soundorg); ceil->sector->ceilingdata = NULL; TagFinished(ceil->sector->tag); ceil->type |= ceiling_t::InStasis; rtn++; } } return rtn; }
void DElevator::Tick () { EMoveResult res; double oldfloor, oldceiling; oldfloor = m_Sector->floorplane.fD(); oldceiling = m_Sector->ceilingplane.fD(); if (m_Direction < 0) // moving down { res = m_Sector->MoveFloor (m_Speed, m_FloorDestDist, m_Direction); if (res == EMoveResult::ok || res == EMoveResult::pastdest) { res = m_Sector->MoveCeiling (m_Speed, m_CeilingDestDist, m_Direction); if (res == EMoveResult::crushed) { m_Sector->MoveFloor (m_Speed, oldfloor, -m_Direction); } } } else // up { res = m_Sector->MoveCeiling (m_Speed, m_CeilingDestDist, m_Direction); if (res == EMoveResult::ok || res == EMoveResult::pastdest) { res = m_Sector->MoveFloor (m_Speed, m_FloorDestDist, m_Direction); if (res == EMoveResult::crushed) { m_Sector->MoveCeiling (m_Speed, oldceiling, -m_Direction); } } } if (res == EMoveResult::pastdest) // if destination height acheived { // make floor stop sound SN_StopSequence (m_Sector, CHAN_FLOOR); m_Sector->floordata = NULL; //jff 2/22/98 m_Sector->ceilingdata = NULL; //jff 2/22/98 Destroy (); // remove elevator from actives } }
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); } }
bool EV_CeilingCrushStop (int tag) { bool rtn = false; DCeiling *scan; TThinkerIterator<DCeiling> iterator; while ( (scan = iterator.Next ()) ) { if (scan->m_Tag == tag && scan->m_Direction != 0) { SN_StopSequence (scan->m_Sector, CHAN_CEILING); scan->m_OldDirection = scan->m_Direction; scan->m_Direction = 0; // in-stasis; rtn = true; } } return rtn; }
int EV_CeilingCrushStop(line_t *line, byte *args) { int i; int rtn; rtn = 0; for(i = 0; i < MAXCEILINGS; i++) { if(activeceilings[i] && activeceilings[i]->tag == args[0]) { rtn = 1; SN_StopSequence((mobj_t *) &activeceilings[i]->sector->soundorg); activeceilings[i]->sector->specialdata = NULL; P_RemoveThinker(&activeceilings[i]->thinker); P_TagFinished(activeceilings[i]->sector->tag); activeceilings[i] = NULL; break; } } return rtn; }
// // EV_CeilingCrushStop // Stop a ceiling from crushing! // [RH] Passed a tag instead of a line and rewritten to use a list // bool EV_CeilingCrushStop (int tag) { bool rtn = false; DCeiling *scan; TThinkerIterator<DCeiling> iterator; while ( (scan = iterator.Next ()) ) { if (scan->m_Tag == tag && scan->m_Direction != 0) { // [BC] If we're stopping, this is probably a good time to verify all the clients // have the correct floor/ceiling height for this sector. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) { if ( scan->m_Sector->floorOrCeiling == 0 ) SERVERCOMMANDS_SetSectorFloorPlane( ULONG( scan->m_Sector - sectors )); else SERVERCOMMANDS_SetSectorCeilingPlane( ULONG( scan->m_Sector - sectors )); // Tell clients to stop the floor's sound sequence. SERVERCOMMANDS_StopSectorSequence( scan->m_Sector ); } SN_StopSequence (scan->m_Sector); scan->m_OldDirection = scan->m_Direction; scan->m_Direction = 0; // in-stasis; rtn = true; // [BB] Also tell the updated direction to the clients. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_ChangeCeilingDirection( scan->GetID( ), scan->GetDirection( )); } } return rtn; }
void DPillar::Tick () { EMoveResult r, s; double oldfloor, oldceiling; oldfloor = m_Sector->floorplane.fD(); oldceiling = m_Sector->ceilingplane.fD(); if (m_Type == pillarBuild) { r = m_Sector->MoveFloor (m_FloorSpeed, m_FloorTarget, m_Crush, 1, m_Hexencrush); s = m_Sector->MoveCeiling (m_CeilingSpeed, m_CeilingTarget, m_Crush, -1, m_Hexencrush); } else { r = m_Sector->MoveFloor (m_FloorSpeed, m_FloorTarget, m_Crush, -1, m_Hexencrush); s = m_Sector->MoveCeiling (m_CeilingSpeed, m_CeilingTarget, m_Crush, 1, m_Hexencrush); } if (r == EMoveResult::pastdest && s == EMoveResult::pastdest) { SN_StopSequence (m_Sector, CHAN_FLOOR); Destroy (); } else { if (r == EMoveResult::crushed) { m_Sector->MoveFloor (m_FloorSpeed, oldfloor, -1, -1, m_Hexencrush); } if (s == EMoveResult::crushed) { m_Sector->MoveCeiling (m_CeilingSpeed, oldceiling, -1, 1, m_Hexencrush); } } }
//================================================================== // // T_VerticalDoor // //================================================================== void T_VerticalDoor(vldoor_t *door) { result_e res; switch(door->direction) { case 0: // WAITING if(!--door->topcountdown) switch(door->type) { case DREV_NORMAL: door->direction = -1; // time to go back down SN_StartSequence((mobj_t *)&door->sector->soundorg, SEQ_DOOR_STONE+door->sector->seqType); break; case DREV_CLOSE30THENOPEN: door->direction = 1; break; default: break; } break; case 2: // INITIAL WAIT if(!--door->topcountdown) { switch(door->type) { case DREV_RAISEIN5MINS: door->direction = 1; door->type = DREV_NORMAL; break; default: break; } } break; case -1: // DOWN res = T_MovePlane(door->sector, door->speed, door->sector->floorheight, false, 1, door->direction); if(res == RES_PASTDEST) { SN_StopSequence((mobj_t *)&door->sector->soundorg); switch(door->type) { case DREV_NORMAL: case DREV_CLOSE: door->sector->specialdata = NULL; P_TagFinished(door->sector->tag); P_RemoveThinker(&door->thinker); // unlink and free break; case DREV_CLOSE30THENOPEN: door->direction = 0; door->topcountdown = 35*30; break; default: break; } } else if(res == RES_CRUSHED) { switch(door->type) { case DREV_CLOSE: // DON'T GO BACK UP! break; default: door->direction = 1; break; } } break; case 1: // UP res = T_MovePlane(door->sector, door->speed, door->topheight, false, 1, door->direction); if(res == RES_PASTDEST) { SN_StopSequence((mobj_t *)&door->sector->soundorg); switch(door->type) { case DREV_NORMAL: door->direction = 0; // wait at top door->topcountdown = door->topwait; break; case DREV_CLOSE30THENOPEN: case DREV_OPEN: door->sector->specialdata = NULL; P_TagFinished(door->sector->tag); P_RemoveThinker (&door->thinker); // unlink and free break; default: break; } } break; } }
void DDoor::Tick () { EResult res; if (m_Sector->floorplane.d != m_OldFloorDist) { if (!m_Sector->floordata || !m_Sector->floordata->IsKindOf(RUNTIME_CLASS(DPlat)) || !(barrier_cast<DPlat*>(m_Sector->floordata))->IsLift()) { m_OldFloorDist = m_Sector->floorplane.d; m_BotDist = m_Sector->ceilingplane.PointToDist (m_BotSpot, m_Sector->floorplane.ZatPoint (m_BotSpot)); } } switch (m_Direction) { case 0: // WAITING if (!--m_TopCountdown) { switch (m_Type) { case doorRaise: m_Direction = -1; // time to go back down DoorSound (false); break; case doorCloseWaitOpen: m_Direction = 1; DoorSound (true); break; default: break; } } break; case 2: // INITIAL WAIT if (!--m_TopCountdown) { switch (m_Type) { case doorRaiseIn5Mins: m_Direction = 1; m_Type = doorRaise; DoorSound (true); break; default: break; } } break; case -1: // DOWN res = MoveCeiling (m_Speed, m_BotDist, -1, m_Direction, false); // killough 10/98: implement gradual lighting effects if (m_LightTag != 0 && m_TopDist != -m_Sector->floorplane.d) { EV_LightTurnOnPartway (m_LightTag, FixedDiv (m_Sector->ceilingplane.d + m_Sector->floorplane.d, m_TopDist + m_Sector->floorplane.d)); } if (res == pastdest) { SN_StopSequence (m_Sector, CHAN_CEILING); switch (m_Type) { case doorRaise: case doorClose: m_Sector->ceilingdata = NULL; //jff 2/22/98 Destroy (); // unlink and free break; case doorCloseWaitOpen: m_Direction = 0; m_TopCountdown = m_TopWait; break; default: break; } } else if (res == crushed) { switch (m_Type) { case doorClose: // DO NOT GO BACK UP! break; default: m_Direction = 1; DoorSound (true); break; } } break; case 1: // UP res = MoveCeiling (m_Speed, m_TopDist, -1, m_Direction, false); // killough 10/98: implement gradual lighting effects if (m_LightTag != 0 && m_TopDist != -m_Sector->floorplane.d) { EV_LightTurnOnPartway (m_LightTag, FixedDiv (m_Sector->ceilingplane.d + m_Sector->floorplane.d, m_TopDist + m_Sector->floorplane.d)); } if (res == pastdest) { SN_StopSequence (m_Sector, CHAN_CEILING); switch (m_Type) { case doorRaise: m_Direction = 0; // wait at top m_TopCountdown = m_TopWait; break; case doorCloseWaitOpen: case doorOpen: m_Sector->ceilingdata = NULL; //jff 2/22/98 Destroy (); // unlink and free break; default: break; } } else if (res == crushed) { switch (m_Type) { case doorRaise: case doorRaiseIn5Mins: m_Direction = -1; DoorSound(false); break; default: break; } } break; } }
void DCeiling::Tick () { EResult res; switch (m_Direction) { case 0: // IN STASIS break; case 1: // UP res = MoveCeiling (m_Speed, m_TopHeight, m_Direction); if (res == pastdest) { switch (m_Type) { case ceilCrushAndRaise: m_Direction = -1; m_Speed = m_Speed1; if (!SN_IsMakingLoopingSound (m_Sector)) PlayCeilingSound (); break; // movers with texture change, change the texture then get removed case genCeilingChgT: case genCeilingChg0: m_Sector->special = m_NewSpecial; // fall through case genCeilingChg: m_Sector->SetTexture(sector_t::ceiling, m_Texture); // fall through default: SN_StopSequence (m_Sector, CHAN_CEILING); Destroy (); break; } } break; case -1: // DOWN res = MoveCeiling (m_Speed, m_BottomHeight, m_Crush, m_Direction, m_Hexencrush); if (res == pastdest) { switch (m_Type) { case ceilCrushAndRaise: case ceilCrushRaiseAndStay: m_Speed = m_Speed2; m_Direction = 1; if (!SN_IsMakingLoopingSound (m_Sector)) PlayCeilingSound (); break; // in the case of ceiling mover/changer, change the texture // then remove the active ceiling case genCeilingChgT: case genCeilingChg0: m_Sector->special = m_NewSpecial; // fall through case genCeilingChg: m_Sector->SetTexture(sector_t::ceiling, m_Texture); // fall through default: SN_StopSequence (m_Sector, CHAN_CEILING); Destroy (); break; } } else // ( res != pastdest ) { if (res == crushed) { switch (m_Type) { case ceilCrushAndRaise: case ceilLowerAndCrush: case ceilLowerAndCrushDist: if (m_Speed1 == FRACUNIT && m_Speed2 == FRACUNIT) m_Speed = FRACUNIT / 8; break; default: break; } } } break; } }
void SN_UpdateActiveSequences(void) { seqnode_t *node; boolean sndPlaying; if(!ActiveSequences || paused) { // No sequences currently playing/game is paused return; } for(node = SequenceListHead; node; node = node->next) { if(node->delayTics) { node->delayTics--; continue; } sndPlaying = S_GetSoundPlayingInfo(node->mobj, node->currentSoundID); switch(*node->sequencePtr) { case SS_CMD_PLAY: if(!sndPlaying) { node->currentSoundID = *(node->sequencePtr+1); S_StartSoundAtVolume(node->mobj, node->currentSoundID, node->volume); } node->sequencePtr += 2; break; case SS_CMD_WAITUNTILDONE: if(!sndPlaying) { node->sequencePtr++; node->currentSoundID = 0; } break; case SS_CMD_PLAYREPEAT: if(!sndPlaying) { node->currentSoundID = *(node->sequencePtr+1); S_StartSoundAtVolume(node->mobj, node->currentSoundID, node->volume); } break; case SS_CMD_DELAY: node->delayTics = *(node->sequencePtr+1); node->sequencePtr += 2; node->currentSoundID = 0; break; case SS_CMD_DELAYRAND: node->delayTics = *(node->sequencePtr+1)+ M_Random()%(*(node->sequencePtr+2)-*(node->sequencePtr+1)); node->sequencePtr += 2; node->currentSoundID = 0; break; case SS_CMD_VOLUME: node->volume = (127*(*(node->sequencePtr+1)))/100; node->sequencePtr += 2; break; case SS_CMD_STOPSOUND: // Wait until something else stops the sequence break; case SS_CMD_END: SN_StopSequence(node->mobj); break; default: break; } } }
//================================================================== // // T_MoveCeiling // //================================================================== void T_MoveCeiling(ceiling_t * ceiling) { result_e res; switch (ceiling->direction) { // case 0: // IN STASIS // break; case 1: // UP res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false, 1, ceiling->direction); if(res == RES_PASTDEST) { SN_StopSequence((mobj_t *) &ceiling->sector->soundorg); switch (ceiling->type) { case CLEV_CRUSHANDRAISE: ceiling->direction = -1; ceiling->speed = ceiling->speed * 2; break; default: P_RemoveActiveCeiling(ceiling); break; } } break; case -1: // DOWN res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, 1, ceiling->direction); if(res == RES_PASTDEST) { SN_StopSequence((mobj_t *) &ceiling->sector->soundorg); switch (ceiling->type) { case CLEV_CRUSHANDRAISE: case CLEV_CRUSHRAISEANDSTAY: ceiling->direction = 1; ceiling->speed = ceiling->speed / 2; break; default: P_RemoveActiveCeiling(ceiling); break; } } else if(res == RES_CRUSHED) { switch (ceiling->type) { case CLEV_CRUSHANDRAISE: case CLEV_LOWERANDCRUSH: case CLEV_CRUSHRAISEANDSTAY: //ceiling->speed = ceiling->speed/4; break; default: break; } } break; } }
void DPlat::Tick () { EMoveResult res; switch (m_Status) { case up: res = m_Sector->MoveFloor (m_Speed, m_High, m_Crush, 1, false); if (res == EMoveResult::crushed && (m_Crush == -1)) { m_Count = m_Wait; m_Status = down; PlayPlatSound ("Platform"); } else if (res == EMoveResult::pastdest) { SN_StopSequence (m_Sector, CHAN_FLOOR); if (m_Type != platToggle) { m_Count = m_Wait; m_Status = waiting; switch (m_Type) { case platRaiseAndStayLockout: // Instead of keeping the dead thinker like Heretic did let's // better use a flag to avoid problems elsewhere. For example, // keeping the thinker would make tagwait wait indefinitely. m_Sector->planes[sector_t::floor].Flags |= PLANEF_BLOCKED; case platRaiseAndStay: case platDownByValue: case platDownWaitUpStay: case platDownWaitUpStayStone: case platUpByValueStay: case platDownToNearestFloor: case platDownToLowestCeiling: Destroy (); break; default: break; } } else { m_OldStatus = m_Status; //jff 3/14/98 after action wait m_Status = in_stasis; //for reactivation of toggle } } break; case down: res = m_Sector->MoveFloor (m_Speed, m_Low, -1, -1, false); if (res == EMoveResult::pastdest) { SN_StopSequence (m_Sector, CHAN_FLOOR); // if not an instant toggle, start waiting if (m_Type != platToggle) //jff 3/14/98 toggle up down { // is silent, instant, no waiting m_Count = m_Wait; m_Status = waiting; switch (m_Type) { case platUpWaitDownStay: case platUpNearestWaitDownStay: case platUpByValue: Destroy (); break; default: break; } } else { // instant toggles go into stasis awaiting next activation m_OldStatus = m_Status; //jff 3/14/98 after action wait m_Status = in_stasis; //for reactivation of toggle } } else if (res == EMoveResult::crushed && m_Crush < 0 && m_Type != platToggle) { m_Status = up; m_Count = m_Wait; PlayPlatSound ("Platform"); } //jff 1/26/98 remove the plat if it bounced so it can be tried again //only affects plats that raise and bounce // remove the plat if it's a pure raise type switch (m_Type) { case platUpByValueStay: case platRaiseAndStay: case platRaiseAndStayLockout: Destroy (); default: break; } break; case waiting: if (m_Count > 0 && !--m_Count) { if (m_Sector->floorplane.fD() == m_Low) m_Status = up; else m_Status = down; if (m_Type == platToggle) SN_StartSequence (m_Sector, CHAN_FLOOR, "Silence", 0); else PlayPlatSound ("Platform"); } break; case in_stasis: break; } }
//================================================================== // // 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); } }
void ASoundSequence::Deactivate (AActor *activator) { SN_StopSequence (this); }
void ASoundSequence::Destroy () { SN_StopSequence (this); Super::Destroy(); }
void DFloor::Tick () { EMoveResult res; // [RH] Handle resetting stairs if (m_Type == buildStair || m_Type == waitStair) { if (m_ResetCount) { if (--m_ResetCount == 0) { m_Type = resetStair; m_Direction = (m_Direction > 0) ? -1 : 1; m_FloorDestDist = m_OrgDist; } } if (m_PauseTime) { m_PauseTime--; return; } else if (m_StepTime) { if (--m_StepTime == 0) { m_PauseTime = m_Delay; m_StepTime = m_PerStepTime; } } } if (m_Type == waitStair) return; res = m_Sector->MoveFloor (m_Speed, m_FloorDestDist, m_Crush, m_Direction, m_Hexencrush, m_Instant); if (res == EMoveResult::pastdest) { SN_StopSequence (m_Sector, CHAN_FLOOR); if (m_Type == buildStair) m_Type = waitStair; if (m_Type != waitStair || m_ResetCount == 0) { if (m_Direction == 1) { switch (m_Type) { case donutRaise: case genFloorChgT: case genFloorChg0: m_Sector->SetSpecial(&m_NewSpecial); //fall thru case genFloorChg: m_Sector->SetTexture(sector_t::floor, m_Texture); break; default: break; } } else if (m_Direction == -1) { switch (m_Type) { case floorLowerAndChange: case genFloorChgT: case genFloorChg0: m_Sector->SetSpecial(&m_NewSpecial); //fall thru case genFloorChg: m_Sector->SetTexture(sector_t::floor, m_Texture); break; default: break; } } m_Sector->floordata = NULL; //jff 2/22/98 StopInterpolation(); //jff 2/26/98 implement stair retrigger lockout while still building // note this only applies to the retriggerable generalized stairs if (m_Sector->stairlock == -2) // if this sector is stairlocked { sector_t *sec = m_Sector; sec->stairlock = -1; // thinker done, promote lock to -1 while (sec->prevsec != -1 && level.sectors[sec->prevsec].stairlock != -2) sec = &level.sectors[sec->prevsec]; // search for a non-done thinker if (sec->prevsec == -1) // if all thinkers previous are done { sec = m_Sector; // search forward while (sec->nextsec != -1 && level.sectors[sec->nextsec].stairlock != -2) sec = &level.sectors[sec->nextsec]; if (sec->nextsec == -1) // if all thinkers ahead are done too { while (sec->prevsec != -1) // clear all locks { sec->stairlock = 0; sec = &level.sectors[sec->prevsec]; } sec->stairlock = 0; } } } Destroy (); } } }
// // T_VerticalDoor // void DDoor::RunThink () { fixed_t ceilingheight = P_CeilingHeight(m_Sector); fixed_t floorheight = P_FloorHeight(m_Sector); EResult res; switch (m_Status) { case finished: PlayDoorSound(); // fall through case destroy: P_SetDoorDestroy(this); return; case waiting: // WAITING if (!--m_TopCountdown) { switch (m_Type) { case doorRaise: // time to go back down m_Status = closing; PlayDoorSound(); break; case doorCloseWaitOpen: m_Status = opening; PlayDoorSound(); break; default: break; } } break; case init: // INITIAL WAIT if (!--m_TopCountdown) { switch (m_Type) { case doorRaiseIn5Mins: m_Type = doorRaise; m_Status = opening; PlayDoorSound(); break; default: break; } } break; case closing: res = MoveCeiling(m_Speed, floorheight, false, -1); if (m_Line && m_Line->id) { EV_LightTurnOnPartway(m_Line->id, FixedDiv(ceilingheight - floorheight, m_TopHeight - floorheight)); } if (res == pastdest) { //S_StopSound (m_Sector->soundorg); SN_StopSequence (m_Sector); switch (m_Type) { case doorRaise: case doorClose: m_Status = finished; return; case doorCloseWaitOpen: m_TopCountdown = m_TopWait; m_Status = waiting; break; default: break; } if (m_Line && m_Line->id) { EV_LightTurnOnPartway(m_Line->id, 0); } } else if (res == crushed) { switch (m_Type) { case doorClose: // DO NOT GO BACK UP! break; default: m_Status = reopening; PlayDoorSound(); break; } } break; case reopening: case opening: res = MoveCeiling(m_Speed, m_TopHeight, false, 1); if (m_Line && m_Line->id) { EV_LightTurnOnPartway(m_Line->id, FixedDiv(ceilingheight - floorheight, m_TopHeight - floorheight)); } if (res == pastdest) { //S_StopSound (m_Sector->soundorg); SN_StopSequence (m_Sector); switch (m_Type) { case doorRaise: // wait at top m_TopCountdown = m_TopWait; m_Status = waiting; break; case doorCloseWaitOpen: case doorOpen: m_Status = finished; return; default: break; } if (m_Line && m_Line->id) { EV_LightTurnOnPartway(m_Line->id, FRACUNIT); } } break; default: break; } }
// // T_MoveCeiling // void DCeiling::Tick () { EResult res; switch (m_Direction) { case 0: // IN STASIS break; case 1: // UP res = MoveCeiling (m_Speed, m_TopHeight, m_Direction); // [BC] Don't need to do anything more here if we're a client. if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) || ( CLIENTDEMO_IsPlaying( ))) break; if (res == pastdest) { // [BC] If the sector has reached its destination, this is probably a good time to verify all the clients // have the correct floor/ceiling height for this sector. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) { if ( m_Sector->floorOrCeiling == 0 ) SERVERCOMMANDS_SetSectorFloorPlane( ULONG( m_Sector - sectors )); else SERVERCOMMANDS_SetSectorCeilingPlane( ULONG( m_Sector - sectors )); } switch (m_Type) { case ceilCrushAndRaise: m_Direction = -1; m_Speed = m_Speed1; if (!SN_IsMakingLoopingSound (m_Sector)) PlayCeilingSound (); // [BC] If we're the server, send out a bunch of updates to clients. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) { // Tell clients to change the direction of the ceiling. SERVERCOMMANDS_ChangeCeilingDirection( m_lCeilingID, m_Direction ); // Tell clients to change the speed of the ceiling. SERVERCOMMANDS_ChangeCeilingSpeed( m_lCeilingID, m_Speed ); // Potentially tell clients to stop playing a ceiling sound. if ( SN_IsMakingLoopingSound( m_Sector ) == false ) SERVERCOMMANDS_PlayCeilingSound( m_lCeilingID ); } break; // movers with texture change, change the texture then get removed case genCeilingChgT: case genCeilingChg0: m_Sector->special = m_NewSpecial; // fall through case genCeilingChg: m_Sector->SetTexture(sector_t::ceiling, m_Texture); // fall through default: // [BC] If we're the server, tell the client to destroy this ceiling. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) { SERVERCOMMANDS_StopSectorSequence( m_Sector ); SERVERCOMMANDS_DestroyCeiling( m_lCeilingID ); } SN_StopSequence (m_Sector); Destroy (); break; } } break; case -1: // DOWN res = MoveCeiling (m_Speed, m_BottomHeight, m_Crush, m_Direction, m_Hexencrush); // [BC] Don't need to do anything more here if we're a client. if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) || ( CLIENTDEMO_IsPlaying( ))) break; if (res == pastdest) { // [BC] If the sector has reached its destination, this is probably a good time to verify all the clients // have the correct floor/ceiling height for this sector. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) { if ( m_Sector->floorOrCeiling == 0 ) SERVERCOMMANDS_SetSectorFloorPlane( ULONG( m_Sector - sectors )); else SERVERCOMMANDS_SetSectorCeilingPlane( ULONG( m_Sector - sectors )); } switch (m_Type) { case ceilCrushAndRaise: case ceilCrushRaiseAndStay: m_Speed = m_Speed2; m_Direction = 1; if (!SN_IsMakingLoopingSound (m_Sector)) PlayCeilingSound (); // [BC] If we're the server, send out a bunch of updates to clients. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) { // Tell clients to change the direction of the ceiling. SERVERCOMMANDS_ChangeCeilingDirection( m_lCeilingID, m_Direction ); // Tell clients to change the speed of the ceiling. SERVERCOMMANDS_ChangeCeilingSpeed( m_lCeilingID, m_Speed ); // Potentially tell clients to stop playing a ceiling sound. if ( SN_IsMakingLoopingSound( m_Sector ) == false ) SERVERCOMMANDS_PlayCeilingSound( m_lCeilingID ); } break; // in the case of ceiling mover/changer, change the texture // then remove the active ceiling case genCeilingChgT: case genCeilingChg0: m_Sector->special = m_NewSpecial; // fall through case genCeilingChg: m_Sector->SetTexture(sector_t::ceiling, m_Texture); // fall through default: // [BC] If we're the server, tell the client to destroy this ceiling. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) { SERVERCOMMANDS_StopSectorSequence( m_Sector ); SERVERCOMMANDS_DestroyCeiling( m_lCeilingID ); } SN_StopSequence (m_Sector); Destroy (); break; } } else // ( res != pastdest ) { if (res == crushed) { switch (m_Type) { case ceilCrushAndRaise: case ceilLowerAndCrush: if (m_Speed1 == FRACUNIT && m_Speed2 == FRACUNIT) { m_Speed = FRACUNIT / 8; // [BC] If we're the server, tell clients to change the ceiling's speed. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_ChangeCeilingSpeed( m_lCeilingID, m_Speed ); } break; default: break; } } } break; } }