Exemple #1
0
DEFINE_ACTION_FUNCTION(AActor, A_GenWizard)
{
	AActor *mo;

	mo = Spawn("Wizard", self->Pos(), ALLOW_REPLACE);
	if (mo != NULL)
	{
		mo->AddZ(-mo->GetDefault()->height / 2, false);
		if (!P_TestMobjLocation (mo))
		{ // Didn't fit
			mo->ClearCounters();
			mo->Destroy ();
		}
		else
		{ // [RH] Make the new wizards inherit D'Sparil's target
			mo->CopyFriendliness (self->target, true);

			self->velx = self->vely = self->velz = 0;
			self->SetState (self->FindState(NAME_Death));
			self->flags &= ~MF_MISSILE;
			mo->master = self->target;
			// Heretic did not offset it by TELEFOGHEIGHT, so I won't either.
			Spawn<ATeleportFog> (self->Pos(), ALLOW_REPLACE);
		}
	}
}
Exemple #2
0
DEFINE_ACTION_FUNCTION(AActor, A_GenWizard)
{
	PARAM_ACTION_PROLOGUE;

	AActor *mo;

	mo = Spawn("Wizard", self->Pos(), ALLOW_REPLACE);
	if (mo != NULL)
	{
		mo->AddZ(-mo->GetDefault()->Height / 2, false);
		if (!P_TestMobjLocation (mo))
		{ // Didn't fit
			mo->ClearCounters();
			mo->Destroy ();
		}
		else
		{ // [RH] Make the new wizards inherit D'Sparil's target
			mo->CopyFriendliness (self->target, true);

			self->Vel.Zero();
			self->SetState (self->FindState(NAME_Death));
			self->flags &= ~MF_MISSILE;
			mo->master = self->target;
			P_SpawnTeleportFog(self, self->Pos(), false, true);
		}
	}
	return 0;
}
	// The second half of random spawning. Now that the spawner is initialized, the
	// real actor can be created. If the following code were in BeginPlay instead,
	// missiles would not have yet obtained certain information that is absolutely
	// necessary to them -- such as their source and destination.
	void PostBeginPlay()
	{
		AActor * newmobj = NULL;
		bool boss = false;
		Super::PostBeginPlay();
		if (Species == NAME_None) 
		{ 
			Destroy(); 
			return; 
		}
		const PClass * cls = PClass::FindClass(Species);
		if (this->flags & MF_MISSILE && target && target->target) // Attempting to spawn a missile.
		{
			if ((tracer == NULL) && (flags2 & MF2_SEEKERMISSILE)) tracer = target->target;
			newmobj = P_SpawnMissileXYZ(Pos(), target, target->target, cls, false);
		}
		else newmobj = Spawn(cls, Pos(), NO_REPLACE);
		if (newmobj != NULL)
		{
			// copy everything relevant
			newmobj->SpawnAngle = newmobj->angle = angle;
			newmobj->SpawnPoint[2] = SpawnPoint[2];
			newmobj->special    = special;
			newmobj->args[0]    = args[0];
			newmobj->args[1]    = args[1];
			newmobj->args[2]    = args[2];
			newmobj->args[3]    = args[3];
			newmobj->args[4]    = args[4];
			newmobj->special1   = special1;
			newmobj->special2   = special2;
			newmobj->SpawnFlags = SpawnFlags & ~MTF_SECRET;	// MTF_SECRET needs special treatment to avoid incrementing the secret counter twice. It had already been processed for the spawner itself.
			newmobj->HandleSpawnFlags();
			newmobj->SpawnFlags = SpawnFlags;
			newmobj->tid        = tid;
			newmobj->AddToHash();
			newmobj->velx = velx;
			newmobj->vely = vely;
			newmobj->velz = velz;
			newmobj->master = master;	// For things such as DamageMaster/DamageChildren, transfer mastery.
			newmobj->target = target;
			newmobj->tracer = tracer;
			newmobj->CopyFriendliness(this, false);
			// This handles things such as projectiles with the MF4_SPECTRAL flag that have
			// a health set to -2 after spawning, for internal reasons.
			if (health != SpawnHealth()) newmobj->health = health;
			if (!(flags & MF_DROPPED)) newmobj->flags &= ~MF_DROPPED;
			// Handle special altitude flags
			if (newmobj->flags & MF_SPAWNCEILING)
			{
				newmobj->SetZ(newmobj->ceilingz - newmobj->height - SpawnPoint[2]);
			}
			else if (newmobj->flags2 & MF2_SPAWNFLOAT) 
			{
				fixed_t space = newmobj->ceilingz - newmobj->height - newmobj->floorz;
				if (space > 48*FRACUNIT)
				{
					space -= 40*FRACUNIT;
					newmobj->SetZ(MulScale8 (space, pr_randomspawn()) + newmobj->floorz + 40*FRACUNIT);
				}
				newmobj->AddZ(SpawnPoint[2]);
			}
			if (newmobj->flags & MF_MISSILE)
				P_CheckMissileSpawn(newmobj, 0);
			// Bouncecount is used to count how many recursions we're in.
			if (newmobj->IsKindOf(PClass::FindClass("RandomSpawner")))
				newmobj->bouncecount = ++bouncecount;
			// If the spawned actor has either of those flags, it's a boss.
			if ((newmobj->flags4 & MF4_BOSSDEATH) || (newmobj->flags2 & MF2_BOSS))
				boss = true;
			// If a replaced actor has either of those same flags, it's also a boss.
			AActor * rep = GetDefaultByType(GetClass()->ActorInfo->GetReplacee()->Class);
			if (rep && ((rep->flags4 & MF4_BOSSDEATH) || (rep->flags2 & MF2_BOSS)))
				boss = true;
		}
		if (boss)
			this->tracer = newmobj;
		else	// "else" because a boss-replacing spawner must wait until it can call A_BossDeath.
			Destroy();
	}