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; }
void G_UnSnapshotLevel (bool hubLoad) { if (level.info->Snapshot.mBuffer == nullptr) return; if (level.info->isValid()) { FSerializer arc; if (!arc.OpenReader(&level.info->Snapshot)) { I_Error("Failed to load savegame"); return; } G_SerializeLevel (arc, hubLoad); level.FromSnapshot = true; TThinkerIterator<APlayerPawn> it; APlayerPawn *pawn, *next; next = it.Next(); while ((pawn = next) != 0) { next = it.Next(); if (pawn->player == NULL || pawn->player->mo == NULL || !playeringame[pawn->player - players]) { int i; // If this isn't the unmorphed original copy of a player, destroy it, because it's extra. for (i = 0; i < MAXPLAYERS; ++i) { if (playeringame[i] && players[i].morphTics && players[i].mo->tracer == pawn) { break; } } if (i == MAXPLAYERS) { pawn->Destroy (); } } } } // No reason to keep the snapshot around once the level's been entered. level.info->Snapshot.Clean(); if (hubLoad) { // Unlock ACS global strings that were locked when the snapshot was made. FBehavior::StaticUnlockLevelVarStrings(); } }
void G_UnSnapshotLevel (bool hubLoad) { if (level.info->snapshot == NULL) return; if (level.info->isValid()) { SaveVersion = level.info->snapshotVer; level.info->snapshot->Reopen (); FArchive arc (*level.info->snapshot); if (hubLoad) arc.SetHubTravel (); G_SerializeLevel (arc, hubLoad); arc.Close (); level.FromSnapshot = true; TThinkerIterator<APlayerPawn> it; APlayerPawn *pawn, *next; next = it.Next(); while ((pawn = next) != 0) { next = it.Next(); if (pawn->player == NULL || pawn->player->mo == NULL || !playeringame[pawn->player - players]) { int i; // If this isn't the unmorphed original copy of a player, destroy it, because it's extra. for (i = 0; i < MAXPLAYERS; ++i) { if (playeringame[i] && players[i].morphTics && players[i].mo->tracer == pawn) { break; } } if (i == MAXPLAYERS) { pawn->Destroy (); } } } } // No reason to keep the snapshot around once the level's been entered. level.info->ClearSnapshot(); if (hubLoad) { // Unlock ACS global strings that were locked when the snapshot was made. FBehavior::StaticUnlockLevelVarStrings(); } }
void ASorcerer2::BeginPlay () { TThinkerIterator<ABossSpot> iterator; ABossSpot *spot; Super::BeginPlay (); NumBossSpots = 0; spot = iterator.Next (); FirstBossSpot = static_cast<ABossSpot *> (spot); while (spot) { NumBossSpots++; spot->NextSpot = iterator.Next (); spot = spot->NextSpot; } }
// [SP] modified - now allows showing count only, new arg must be passed. Also now still counts regardless, if lists are printed. static void PrintFilteredActorList(const ActorTypeChecker IsActorType, const char *FilterName, bool countOnly) { AActor *mo; const PClass *FilterClass = NULL; int counter = 0; if (FilterName != NULL) { FilterClass = PClass::FindActor(FilterName); if (FilterClass == NULL) { Printf("%s is not an actor class.\n", FilterName); return; } } TThinkerIterator<AActor> it; while ( (mo = it.Next()) ) { if ((FilterClass == NULL || mo->IsA(FilterClass)) && IsActorType(mo)) { counter++; if (!countOnly) Printf ("%s at (%f,%f,%f)\n", mo->GetClass()->TypeName.GetChars(), mo->X(), mo->Y(), mo->Z()); } } Printf("%i match(s) found.\n", counter); }
DEFINE_ACTION_FUNCTION(AActor, A_BrainDie) { // [RH] If noexit, then don't end the level. if ((deathmatch || alwaysapplydmflags) && (dmflags & DF_NO_EXIT)) return; // New dmflag: Kill all boss spawned monsters before ending the level. if (dmflags2 & DF2_KILLBOSSMONST) { int count; // Repeat until we have no more boss-spawned monsters. do // (e.g. Pain Elementals can spawn more to kill upon death.) { TThinkerIterator<AActor> it; AActor *mo; count = 0; while ((mo = it.Next())) { if (mo->health > 0 && mo->flags4 & MF4_BOSSSPAWNED) { P_DamageMobj(mo, self, self, mo->health, NAME_None, DMG_NO_ARMOR|DMG_FORCED|DMG_THRUSTLESS|DMG_NO_FACTOR); count++; } } } while (count != 0); } G_ExitLevel (0, false); }
static void PrintFilteredActorList(const ActorTypeChecker IsActorType, const char *FilterName) { AActor *mo; const PClass *FilterClass = NULL; if (FilterName != NULL) { FilterClass = PClass::FindClass(FilterName); if (FilterClass == NULL || FilterClass->ActorInfo == NULL) { Printf("%s is not an actor class.\n", FilterName); return; } } TThinkerIterator<AActor> it; while ( (mo = it.Next()) ) { if ((FilterClass == NULL || mo->IsA(FilterClass)) && IsActorType(mo)) { Printf ("%s at (%d,%d,%d)\n", mo->GetClass()->TypeName.GetChars(), mo->x >> FRACBITS, mo->y >> FRACBITS, mo->z >> FRACBITS); } }
void ASoundSequence::PostBeginPlay () { FName slot = SN_GetSequenceSlot (args[0], SEQ_ENVIRONMENT); if (slot != NAME_None) { // This is a slotted sound, so add it to the master for that slot ASoundSequenceSlot *master; TThinkerIterator<ASoundSequenceSlot> locator; while (NULL != (master = locator.Next ())) { if (master->Sequence->GetSequenceName() == slot) { break; } } if (master == NULL) { master = Spawn<ASoundSequenceSlot> (0, 0, 0, NO_REPLACE); master->Sequence = SN_StartSequence (master, slot, 0); GC::WriteBarrier(master, master->Sequence); } master->Sequence->AddChoice (args[0], SEQ_ENVIRONMENT); Destroy (); } }
int DEarthquake::StaticGetQuakeIntensity (AActor *victim) { int intensity = 0; TThinkerIterator<DEarthquake> iterator (STAT_EARTHQUAKE); DEarthquake *quake; if (victim->player != NULL && (victim->player->cheats & CF_NOCLIP)) { return 0; } while ( (quake = iterator.Next()) != NULL) { if (quake->m_Spot != NULL) { fixed_t dist = P_AproxDistance (victim->x - quake->m_Spot->x, victim->y - quake->m_Spot->y); if (dist < quake->m_TremorRadius) { if (intensity < quake->m_Intensity) intensity = quake->m_Intensity; } } } return intensity; }
void AMinotaurFriend::Die (AActor *source, AActor *inflictor, int dmgflags) { Super::Die (source, inflictor, dmgflags); if (tracer && tracer->health > 0 && tracer->player) { // Search thinker list for minotaur TThinkerIterator<AMinotaurFriend> iterator; AMinotaurFriend *mo; while ((mo = iterator.Next()) != NULL) { if (mo->health <= 0) continue; // [RH] Minotaurs can't be morphed, so this isn't needed //if (!(mo->flags&MF_COUNTKILL)) continue; // for morphed minotaurs if (mo->flags&MF_CORPSE) continue; if (mo->StartTime >= 0 && (level.maptime - StartTime) >= MAULATORTICS) continue; if (mo->tracer != NULL && mo->tracer->player == tracer->player) break; } if (mo == NULL) { AInventory *power = tracer->FindInventory(PClass::FindActor("PowerMinotaur")); if (power != NULL) { power->Destroy (); } } } }
void EV_StopPlat (int tag, bool remove) { DPlat *scan; TThinkerIterator<DPlat> iterator; scan = iterator.Next(); while (scan != nullptr) { DPlat *next = iterator.Next(); if (scan->m_Status != DPlat::in_stasis && scan->m_Tag == tag) { if (!remove) scan->Stop(); else scan->Destroy(); } scan = next; } }
void gl_RecreateAllAttachedLights() { TThinkerIterator<AActor> it; AActor * a; while ((a=it.Next())) { gl_SetActorLights(a); } }
void P_ActivateInStasis (int tag) { DPlat *scan; TThinkerIterator<DPlat> iterator; while ( (scan = iterator.Next ()) ) { if (scan->m_Tag == tag && scan->m_Status == DPlat::in_stasis) scan->Reactivate (); } }
void EV_StopPlat (int tag) { DPlat *scan; TThinkerIterator<DPlat> iterator; while ( (scan = iterator.Next ()) ) { if (scan->m_Status != DPlat::in_stasis && scan->m_Tag == tag) scan->Stop (); } }
void A_WakeOracleSpectre (AActor *self) { TThinkerIterator<AAlienSpectre3> it; AActor *spectre = it.Next(); if (spectre != NULL) { spectre->Sector->SoundTarget = spectre->LastHeard = self->LastHeard; spectre->target = self->target; spectre->SetState (spectre->SeeState); } }
void EV_StopLightEffect (int tag) { TThinkerIterator<DLighting> iterator; DLighting *effect; while ((effect = iterator.Next()) != NULL) { if (effect->GetSector()->tag == tag) { effect->Destroy(); } } }
// // Restart a ceiling that's in-stasis // [RH] Passed a tag instead of a line and rewritten to use list // void P_ActivateInStasisCeiling (int tag) { DCeiling *scan; TThinkerIterator<DCeiling> iterator; while ( (scan = iterator.Next ()) ) { if (scan->m_Tag == tag && scan->m_Direction == 0) { scan->m_Direction = scan->m_OldDirection; scan->PlayCeilingSound (); } } }
//***************************************************************************** // DCeiling *P_GetCeilingByID( LONG lID ) { DCeiling *pCeiling; TThinkerIterator<DCeiling> Iterator; while (( pCeiling = Iterator.Next( ))) { if ( pCeiling->GetID( ) == lID ) return ( pCeiling ); } return ( NULL ); }
void gl_InitPortals() { TThinkerIterator<AStackPoint> it; AStackPoint *pt; while ((pt = it.Next())) { FPortal *portal = NULL; int plane; for(int i=0;i<numsectors;i++) { if (sectors[i].linecount == 0) { continue; } else if (sectors[i].FloorSkyBox == pt) { plane = 1; } else if (sectors[i].CeilingSkyBox == pt) { plane = 2; } else continue; // we only process portals that actually are in use. if (portal == NULL) { pt->special1 = portals.Size(); // Link portal thing to render data portal = &portals[portals.Reserve(1)]; portal->origin = pt; portal->plane = 0; portal->xDisplacement = pt->x - pt->Mate->x; portal->yDisplacement = pt->y - pt->Mate->y; } portal->AddSectorToPortal(§ors[i]); portal->plane|=plane; } if (portal != NULL) { // if the first vertex is duplicated at the end it'll save time in a time critical function // because that code does not need to check for wraparounds anymire. portal->Shape.Resize(portal->Shape.Size()+1); portal->Shape[portal->Shape.Size()-1] = portal->Shape[0]; portal->Shape.ShrinkToFit(); portal->ClipAngles.Resize(portal->Shape.Size()); } } }
//***************************************************************************** // bool COOP_PlayersVoodooDollsNeedToBeSpawned ( const ULONG ulPlayer ) { // [BB] The current game mode doesn't need voodoo dolls. if ( COOP_VoodooDollsSelectedByGameMode() == false ) return false; // [BB] The map doesn't have any voodoo doll starts for this player. if ( AllPlayerStarts[ulPlayer].Size() <= 1 ) return false; // [BB] When we are using unassigned voodoo dolls, all dolls for all players // (even those who are not in the game) are already spawned in P_SpawnThings. // Therefore, we don't need to spawn any dolls afterwards. if ( sv_coopunassignedvoodoodolls == true ) return false; TThinkerIterator<AActor> Iterator; AActor *pActor; while (( pActor = Iterator.Next( ))) { // [BB] This actor doesn't belong to a player, so it can't be a voodoo doll. if ( pActor->player == NULL ) continue; // [BB] Belongs to a different player. if ( static_cast<ULONG>(pActor->player - players) != ulPlayer ) continue; // [BB] If we come here, we found a body belonging to the player. if ( // [BB] The current player doesn't have a body assigned, so we found a voodoo doll. ( players[ulPlayer].mo == NULL ) // [BB] A different body is assigned to the player, so we found a voodoo doll. || ( players[ulPlayer].mo != pActor ) ) { // [BB] There already is a voodoo doll for the player, so we don't need to spawn it. return false; } } return true; }
void ACustomBridge::Destroy() { // Hexen originally just set a flag to make the bridge balls remove themselves in A_BridgeOrbit. // But this is not safe with custom bridge balls that do not necessarily call that function. // So the best course of action is to look for all bridge balls here and destroy them ourselves. TThinkerIterator<AActor> it; AActor *thing; while ((thing = it.Next())) { if (thing->target == this) { thing->Destroy(); } } Super::Destroy(); }
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; }
// // EV_CeilingCrushStop // Stop a ceiling from crushing! // [RH] Passed a tag instead of a line and rewritten to use 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) { S_StopSound (scan->m_Sector->soundorg); scan->m_OldDirection = scan->m_Direction; scan->m_Direction = 0; // in-stasis; rtn = true; } } return rtn; }
// // A_KeenDie // DOOM II special, map 32. // Uses special tag 666. // void A_KeenDie (AActor *self) { A_NoBlocking (self); // scan the remaining thinkers to see if all Keens are dead AActor *other; TThinkerIterator<AActor> iterator; const PClass *matchClass = self->GetClass (); while ( (other = iterator.Next ()) ) { if (other != self && other->health > 0 && other->IsA (matchClass)) { // other Keen not dead return; } } EV_DoDoor (DDoor::doorOpen, NULL, NULL, 666, 2*FRACUNIT, 0, 0, 0); }
// // Restart a ceiling that's in-stasis // [RH] Passed a tag instead of a line and rewritten to use a list // void P_ActivateInStasisCeiling (int tag) { DCeiling *scan; TThinkerIterator<DCeiling> iterator; while ( (scan = iterator.Next ()) ) { if (scan->m_Tag == tag && scan->m_Direction == 0) { scan->m_Direction = scan->m_OldDirection; scan->PlayCeilingSound (); // [BC] If we're the server, tell clients to change the ceiling direction, and // play the ceiling sound. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) { SERVERCOMMANDS_ChangeCeilingDirection( scan->GetID( ), scan->GetDirection( )); SERVERCOMMANDS_PlayCeilingSound( scan->GetID( )); } } } }
void gl_DeleteAllAttachedLights() { TThinkerIterator<AActor> it; AActor * a; ADynamicLight * l; while ((a=it.Next())) { a->dynamiclights.Clear(); } TThinkerIterator<ADynamicLight> it2; l=it2.Next(); while (l) { ADynamicLight * ll = it2.Next(); if (l->owned) l->Destroy(); l=ll; } }
DEFINE_ACTION_FUNCTION(AActor, A_BrainDie) { // [RH] If noexit, then don't end the level. if ((deathmatch || alwaysapplydmflags) && (dmflags & DF_NO_EXIT)) return; // New dmflag: Kill all boss spawned monsters before ending the level. if (dmflags2 & DF2_KILLBOSSMONST) { TThinkerIterator<AActor> it; AActor *mo; while ((mo = it.Next())) { if (mo->flags4 & MF4_BOSSSPAWNED) { P_DamageMobj(mo, self, self, mo->health, NAME_None, DMG_NO_ARMOR|DMG_FORCED|DMG_THRUSTLESS|DMG_NO_FACTOR); } } } G_ExitLevel (0, false); }
static void StoreLevelStats() { unsigned int i; if (gamestate != GS_LEVEL) return; if (!(level.flags2&LEVEL2_NOSTATISTICS)) // don't consider maps that were excluded from statistics { for(i=0;i<LevelData.Size();i++) { if (!stricmp(LevelData[i].levelname, level.MapName)) break; } if (i==LevelData.Size()) { LevelData.Reserve(1); strncpy(LevelData[i].levelname, level.MapName, 8); LevelData[i].levelname[8] = 0; } LevelData[i].totalkills = level.total_monsters; LevelData[i].killcount = level.killed_monsters; LevelData[i].totalsecrets = level.total_secrets; LevelData[i].secretcount = level.found_secrets; LevelData[i].leveltime = AdjustTics(level.maptime); // Check for living monsters. On some maps it can happen // that the counter misses some. TThinkerIterator<AActor> it; AActor *ac; int mc = 0; while ((ac = it.Next())) { if ((ac->flags & MF_COUNTKILL) && ac->health > 0) mc++; } if (mc == 0) LevelData[i].killcount = LevelData[i].totalkills; } }
void AdjustPusher (int tag, int magnitude, int angle, DPusher::EPusher type) { // Find pushers already attached to the sector, and change their parameters. { TThinkerIterator<DPusher> iterator; FThinkerCollection collect; while ( (collect.Obj = iterator.Next ()) ) { if ((collect.RefNum = ((DPusher *)collect.Obj)->CheckForSectorMatch (type, tag)) >= 0) { ((DPusher *)collect.Obj)->ChangeValues (magnitude, angle); Collection.Push (collect); } } } int numcollected = Collection.Size (); int secnum = -1; // Now create pushers for any sectors that don't already have them. while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) { int i; for (i = 0; i < numcollected; i++) { if (Collection[i].RefNum == sectors[secnum].tag) break; } if (i == numcollected) { new DPusher (type, NULL, magnitude, angle, NULL, secnum); } } Collection.Clear (); }
void EV_StopLightEffect (int tag) { TThinkerIterator<DLighting> iterator; DLighting *effect; while ((effect = iterator.Next()) != NULL) { if (effect->GetSector()->tag == tag) { effect->Destroy(); // [BC] Since this sector's light level most likely changed, mark it as such so // that we can tell clients when they come in. effect->GetSector( )->bLightChange = true; // [BC] If we're the server, tell clients to stop this light effect. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) { SERVERCOMMANDS_StopSectorLightEffect( ULONG( effect->GetSector( ) - sectors )); SERVERCOMMANDS_SetSectorLightLevel( ULONG( effect->GetSector( ) - sectors )); } } } }