Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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();
	}
}
Ejemplo n.º 3
0
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();
	}
}
Ejemplo n.º 4
0
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;
	}
}
Ejemplo n.º 5
0
// [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);
}
Ejemplo n.º 6
0
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);
}
Ejemplo n.º 7
0
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);
		}
	}
Ejemplo n.º 8
0
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 ();
	}
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
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 ();
            }
        }
    }
}
Ejemplo n.º 11
0
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;
	}
}
Ejemplo n.º 12
0
void gl_RecreateAllAttachedLights()
{
	TThinkerIterator<AActor> it;
	AActor * a;

	while ((a=it.Next())) 
	{
		gl_SetActorLights(a);
	}
}
Ejemplo n.º 13
0
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 ();
	}
}
Ejemplo n.º 14
0
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 ();
	}
}
Ejemplo n.º 15
0
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);
	}
}
Ejemplo n.º 16
0
void EV_StopLightEffect (int tag)
{
	TThinkerIterator<DLighting> iterator;
	DLighting *effect;

	while ((effect = iterator.Next()) != NULL)
	{
		if (effect->GetSector()->tag == tag)
		{
			effect->Destroy();
		}
	}
}
Ejemplo n.º 17
0
//
// 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 ();
		}
	}
}
Ejemplo n.º 18
0
//*****************************************************************************
//
DCeiling *P_GetCeilingByID( LONG lID )
{
	DCeiling	*pCeiling;

	TThinkerIterator<DCeiling>		Iterator;

	while (( pCeiling = Iterator.Next( )))
	{
		if ( pCeiling->GetID( ) == lID )
			return ( pCeiling );
	}

	return ( NULL );
}
Ejemplo n.º 19
0
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(&sectors[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());
		}
	}
}
Ejemplo n.º 20
0
//*****************************************************************************
//
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;
}
Ejemplo n.º 21
0
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();
}
Ejemplo n.º 22
0
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;
}
Ejemplo n.º 23
0
//
// 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;
}
Ejemplo n.º 24
0
//
// 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);
}
Ejemplo n.º 25
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( ));
			}
		}
	}
}
Ejemplo n.º 26
0
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;
	}


}
Ejemplo n.º 27
0
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);
}
Ejemplo n.º 28
0
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;
	}
}
Ejemplo n.º 29
0
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 ();
}
Ejemplo n.º 30
0
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 ));
			}
		}
	}
}