コード例 #1
0
void A_BarrelRespawn (AActor *actor)
{
	fixed_t x = actor->SpawnPoint[0] << FRACBITS;
	fixed_t y = actor->SpawnPoint[1] << FRACBITS;
	sector_t *sec;
	// [BC]
	AActor	*pFog;

	actor->flags |= MF_SOLID;
	sec = R_PointInSubsector (x, y)->sector;
	actor->SetOrigin (x, y, sec->floorplane.ZatPoint (x, y));
	if (P_TestMobjLocation (actor))
	{
		AActor *defs = actor->GetDefault();
		actor->health = defs->health;
		actor->flags = defs->flags;
		actor->flags2 = defs->flags2;
		actor->SetState (actor->SpawnState);
		actor->renderflags &= ~RF_INVISIBLE;
		// [BC] pFog =
		pFog = Spawn<ATeleportFog> (x, y, actor->z + TELEFOGHEIGHT, ALLOW_REPLACE);

		// [BC] If we're the server, set the barrel's flags2, and spawn the fog.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
		{
			SERVERCOMMANDS_SpawnThing( actor );
			SERVERCOMMANDS_SpawnThing( pFog );
		}
	}
	else
	{
		actor->flags &= ~MF_SOLID;
	}
}
コード例 #2
0
DEFINE_ACTION_FUNCTION(AActor, A_SpectreChunkLarge)
{
	// [BB] Clients may not do this.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) || ( CLIENTDEMO_IsPlaying( )))
		return;

	AActor *foo = Spawn("AlienChunkLarge", self->x, self->y, self->z + 10*FRACUNIT, ALLOW_REPLACE);

	if (foo != NULL)
	{
		int t;

		t = pr_spectrechunk() & 7;
		foo->momx = (t - (pr_spectrechunk() & 15)) << FRACBITS;
		
		t = pr_spectrechunk() & 7;
		foo->momy = (t - (pr_spectrechunk() & 15)) << FRACBITS;

		foo->momz = (pr_spectrechunk() & 7) << FRACBITS;

		// [BB] Tell clients to spawn the actor.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVERCOMMANDS_SpawnThing( foo );
	}

}
コード例 #3
0
DEFINE_ACTION_FUNCTION(AActor, A_SpectreChunkSmall)
{
	// [BB] Clients may not do this.
	if ( NETWORK_InClientMode() )
		return;

	AActor *foo = Spawn("AlienChunkSmall", self->x, self->y, self->z + 10*FRACUNIT, ALLOW_REPLACE);

	if (foo != NULL)
	{
		int t;

		t = pr_spectrechunk() & 15;
		foo->velx = (t - (pr_spectrechunk() & 7)) << FRACBITS;
		
		t = pr_spectrechunk() & 15;
		foo->vely = (t - (pr_spectrechunk() & 7)) << FRACBITS;

		foo->velz = (pr_spectrechunk() & 15) << FRACBITS;

		// [BB] Tell clients to spawn the actor.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVERCOMMANDS_SpawnThing( foo );
	}
}
コード例 #4
0
DEFINE_ACTION_FUNCTION(AActor, A_BishopSpawnBlur)
{
	// [BB] This is server-side.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return;
	}

	AActor *mo;

	if (!--self->special1)
	{
		self->momx = 0;
		self->momy = 0;

		// [BB] If we're the server, update the thing's momentum.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVERCOMMANDS_MoveThingExact( self, CM_MOMX|CM_MOMY );

		if (pr_sblur() > 96)
		{
			// [BB] If we're the server, tell the clients of the state change.
			if ( NETWORK_GetState( ) == NETSTATE_SERVER )
				SERVERCOMMANDS_SetThingState( self, STATE_SEE );

			self->SetState (self->SeeState);
		}
		else
		{
			// [BB] If we're the server, tell the clients of the state change.
			if ( NETWORK_GetState( ) == NETSTATE_SERVER )
				SERVERCOMMANDS_SetThingState( self, STATE_MISSILE );
			
			self->SetState (self->MissileState);
		}
	}
	mo = Spawn ("BishopBlur", self->x, self->y, self->z, ALLOW_REPLACE);
	if (mo)
	{
		mo->angle = self->angle;

		// [BB] If we're the server, tell the clients to spawn the thing and set its angle.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
		{
			SERVERCOMMANDS_SpawnThing( mo );
			SERVERCOMMANDS_SetThingAngle( mo );
		}
	}
}
コード例 #5
0
DEFINE_ACTION_FUNCTION(AActor, A_BishopPainBlur)
{
	AActor *mo;

	// [BB] This is server-side.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return;
	}

	if (pr_pain() < 64)
	{
		// [BB] If we're the server, tell the clients to update this thing's state.
		if ( ( NETWORK_GetState( ) == NETSTATE_SERVER ) )
			SERVERCOMMANDS_SetThingFrame( self, self->FindState ("Blur") );

		self->SetState (self->FindState ("Blur"));
		return;
	}
	fixed_t x = self->x + (pr_pain.Random2()<<12);
	fixed_t y = self->y + (pr_pain.Random2()<<12);
	fixed_t z = self->z + (pr_pain.Random2()<<11);
	mo = Spawn ("BishopPainBlur", x, y, z, ALLOW_REPLACE);
	if (mo)
	{
		mo->angle = self->angle;

		// [BB] If we're the server, tell the clients to spawn the thing and set its angle.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
		{
			SERVERCOMMANDS_SpawnThing( mo );
			SERVERCOMMANDS_SetThingAngle( mo );
		}
	}
}
コード例 #6
0
static void SpawnFly(AActor *self, const PClass *spawntype, FSoundID sound)
{
	AActor *newmobj;
	AActor *fog = NULL;
	AActor *eye = self->master; // The eye is the spawnshot's master, not the target!
	AActor *targ = self->target; // Unlike other projectiles, the target is the intended destination.
	int r;
		
	// [BC] Brain spitting is server-side.
	if ( NETWORK_InClientMode() )
	{
		return;
	}

	// [GZ] Should be more viable than a countdown...
	if (self->special2 != 0)
	{
		if (self->special2 > level.maptime)
			return;		// still flying
	}
	else
	{
		if (self->reactiontime == 0 || --self->reactiontime != 0)
			return;		// still flying
	}
	
	if (spawntype != NULL)
	{
		fog = Spawn (spawntype, targ->x, targ->y, targ->z, ALLOW_REPLACE);
		if (fog != NULL) S_Sound (fog, CHAN_BODY, sound, 1, ATTN_NORM);
	}

	// [BC] If we're the server, spawn the fire, and tell clients to play the sound.
	if (( NETWORK_GetState( ) == NETSTATE_SERVER ) && ( fog ))
	{
		SERVERCOMMANDS_SpawnThing( fog );
		SERVERCOMMANDS_SoundPoint( fog->x, fog->y, fog->z, CHAN_BODY, "brain/spawn", 1, ATTN_NORM );
	}

	FName SpawnName;

	FDropItem *di;   // di will be our drop item list iterator
	FDropItem *drop; // while drop stays as the reference point.
	int n = 0;

	// First see if this cube has its own actor list
	drop = self->GetDropItems();

	// If not, then default back to its master's list
	if (drop == NULL && eye != NULL)
		drop = eye->GetDropItems();

	if (drop != NULL)
	{
		for (di = drop; di != NULL; di = di->Next)
		{
			if (di->Name != NAME_None)
			{
				if (di->amount < 0)
				{
					di->amount = 1; // default value is -1, we need a positive value.
				}
				n += di->amount; // this is how we can weight the list.
			}
		}
		di = drop;
		n = pr_spawnfly(n);
		while (n >= 0)
		{
			if (di->Name != NAME_None)
			{
				n -= di->amount; // logically, none of the -1 values have survived by now.
			}
			if ((di->Next != NULL) && (n >= 0))
			{
				di = di->Next;
			}
			else
			{
				n = -1;
			}
		}
		SpawnName = di->Name;
	}
	if (SpawnName == NAME_None)
	{
		// Randomly select monster to spawn.
		r = pr_spawnfly ();

		// Probability distribution (kind of :),
		// decreasing likelihood.
			 if (r < 50)  SpawnName = "DoomImp";
		else if (r < 90)  SpawnName = "Demon";
		else if (r < 120) SpawnName = "Spectre";
		else if (r < 130) SpawnName = "PainElemental";
		else if (r < 160) SpawnName = "Cacodemon";
		else if (r < 162) SpawnName = "Archvile";
		else if (r < 172) SpawnName = "Revenant";
		else if (r < 192) SpawnName = "Arachnotron";
		else if (r < 222) SpawnName = "Fatso";
		else if (r < 246) SpawnName = "HellKnight";
		else			  SpawnName = "BaronOfHell";
	}
	spawntype = PClass::FindClass(SpawnName);
	if (spawntype != NULL)
	{
		newmobj = Spawn (spawntype, targ->x, targ->y, targ->z, ALLOW_REPLACE);
		if (newmobj != NULL)
		{
			// Make the new monster hate what the boss eye hates
			if (eye != NULL)
			{
				newmobj->CopyFriendliness (eye, false);
			}
			// Make it act as if it was around when the player first made noise
			// (if the player has made noise).
			newmobj->LastHeard = newmobj->Sector->SoundTarget;

			if (newmobj->SeeState != NULL && P_LookForPlayers (newmobj, true, NULL))
			{
				newmobj->SetState (newmobj->SeeState);
			}
			if (!(newmobj->ObjectFlags & OF_EuthanizeMe))
			{
				// telefrag anything in this spot
				P_TeleportMove (newmobj, newmobj->x, newmobj->y, newmobj->z, true);

				// [BC] If we're the server, tell clients to spawn the new monster.
				if ( NETWORK_GetState( ) == NETSTATE_SERVER )
				{
					SERVERCOMMANDS_SpawnThing( newmobj );
					if ( newmobj->state == newmobj->SeeState )
						SERVERCOMMANDS_SetThingState( newmobj, STATE_SEE );
				}
			}
			newmobj->flags4 |= MF4_BOSSSPAWNED;
		}
	}

	// [BC] Tell clients to destroy the cube.
	if ( NETWORK_GetState( ) == NETSTATE_SERVER )
		SERVERCOMMANDS_DestroyThing( self );

	// remove self (i.e., cube).
	self->Destroy ();
}
コード例 #7
0
ファイル: a_rebels.cpp プロジェクト: WChrisK/Zandronum
DEFINE_ACTION_FUNCTION(AActor, A_Beacon)
{
	AActor *owner = self->target;
	AActor *rebel;
	angle_t an;
	// [BC]
	AActor	*pFog;

	// [BC] This is handled server-side.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return;
	}

	rebel = Spawn("Rebel1", self->x, self->y, self->floorz, ALLOW_REPLACE);
	if (!P_TryMove (rebel, rebel->x, rebel->y, true))
	{
		rebel->Destroy ();
		return;
	}
	// Once the rebels start teleporting in, you can't pick up the beacon anymore.
	self->flags &= ~MF_SPECIAL;
	static_cast<AInventory *>(self)->DropTime = 0;
	// Set up the new rebel.
	rebel->threshold = BASETHRESHOLD;
	rebel->target = NULL;
	rebel->flags4 |= MF4_INCOMBAT;
	rebel->LastHeard = owner;	// Make sure the rebels look for targets
	if (deathmatch)
	{
		rebel->health *= 2;
	}
	if (owner != NULL)
	{
		// Rebels are the same color as their owner (but only in multiplayer)
		// [BB] Changed "multiplayer" check
		if ( NETWORK_GetState( ) != NETSTATE_SINGLE )
		{
			rebel->Translation = owner->Translation;
		}
		rebel->FriendPlayer = owner->player != NULL ? BYTE(owner->player - players + 1) : 0;
		// Set the rebel's target to whatever last hurt the player, so long as it's not
		// one of the player's other rebels.
		if (owner->target != NULL && !rebel->IsFriend (owner->target))
		{
			rebel->target = owner->target;
		}
	}

	// [BC] Spawn the rebel, and put him in the see state.
	if ( NETWORK_GetState( ) == NETSTATE_SERVER )
	{
		SERVERCOMMANDS_SpawnThing( rebel );
		SERVERCOMMANDS_SetThingState( rebel, STATE_SEE );
	}

	rebel->SetState (rebel->SeeState);
	rebel->angle = self->angle;
	an = self->angle >> ANGLETOFINESHIFT;
	pFog = Spawn<ATeleportFog> (rebel->x + 20*finecosine[an], rebel->y + 20*finesine[an], rebel->z + TELEFOGHEIGHT, ALLOW_REPLACE);
	// [BC] Spawn the teleport fog.
	if (( NETWORK_GetState( ) == NETSTATE_SERVER ) &&
		( pFog ))
	{
		SERVERCOMMANDS_SpawnThing( pFog );
	}

	if (--self->health < 0)
	{
		// [BB] Tell clients to set the thing's state.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVERCOMMANDS_SetThingState( self, STATE_DEATH );

		self->SetState(self->FindState(NAME_Death));
	}
}
コード例 #8
0
ファイル: a_randomspawner.cpp プロジェクト: WChrisK/Zandronum
	// 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(x, y, z, target, target->target, cls, false);
		}
		else newmobj = Spawn(cls, x, y, z, 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;
			newmobj->HandleSpawnFlags();
			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->z = 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->z = MulScale8 (space, pr_randomspawn()) + newmobj->floorz + 40*FRACUNIT;
				}
				newmobj->z += SpawnPoint[2];
			}
			if (newmobj->flags & MF_MISSILE)
				P_CheckMissileSpawn(newmobj);
			// 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;

			// [BB] If we're the server, tell clients to spawn the actor.
			if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			{
				SERVERCOMMANDS_SpawnThing( newmobj );
				// [BB] Also set the angle and momentum if necessary.
				SERVER_SetThingNonZeroAngleAndMomentum( newmobj );
			}
			// [BB] The client did the spawning, so this has to be a client side only actor.
			else if ( ( NETWORK_GetState( ) == NETSTATE_CLIENT ) || ( CLIENTDEMO_IsPlaying( ) ) )
				newmobj->ulNetworkFlags |= NETFL_CLIENTSIDEONLY;
		}
		if (boss) this->tracer = newmobj;
		// [BB] Only destroy the actor if it's not needed for a map reset. Otherwise just hide it.
		else HideOrDestroyIfSafe();	// "else" because a boss-replacing spawner must wait until it can call A_BossDeath.

		// [BB] Workaround to ensure that the spawner is properly reset in GAME_ResetMap.
		this->ulSTFlags |= STFL_POSITIONCHANGED;
	}
コード例 #9
0
//
// A_PainShootSkull
// Spawn a lost soul and launch it at the target
//
void A_PainShootSkull (AActor *self, angle_t angle)
{
	fixed_t x, y, z;
	
	AActor *other;
	angle_t an;
	int prestep;

	// [BC] Spawning of additional lost souls is server-side.
	if ( NETWORK_GetState( ) == NETSTATE_CLIENT )
		return;

	const PClass *spawntype = NULL;

	int index=CheckIndex(1, NULL);
	if (index>=0) 
	{
		spawntype = PClass::FindClass((ENamedName)StateParameters[index]);
	}
	if (spawntype == NULL) spawntype = RUNTIME_CLASS(ALostSoul);

	// [RH] check to make sure it's not too close to the ceiling
	if (self->z + self->height + 8*FRACUNIT > self->ceilingz)
	{
		if (self->flags & MF_FLOAT)
		{
			self->momz -= 2*FRACUNIT;
			self->flags |= MF_INFLOAT;
			self->flags4 |= MF4_VFRICTION;
		}
		return;
	}

	// [RH] make this optional
	if (i_compatflags & COMPATF_LIMITPAIN)
	{
		// count total number of skulls currently on the level
		// if there are already 20 skulls on the level, don't spit another one
		int count = 20;
		FThinkerIterator iterator (spawntype);
		DThinker *othink;

		while ( (othink = iterator.Next ()) )
		{
			if (--count == 0)
				return;
		}
	}

	// okay, there's room for another one
	an = angle >> ANGLETOFINESHIFT;
	
	prestep = 4*FRACUNIT +
		3*(self->radius + GetDefaultByType(spawntype)->radius)/2;
	
	x = self->x + FixedMul (prestep, finecosine[an]);
	y = self->y + FixedMul (prestep, finesine[an]);
	z = self->z + 8*FRACUNIT;
				
	// Check whether the Lost Soul is being fired through a 1-sided	// phares
	// wall or an impassible line, or a "monsters can't cross" line.//   |
	// If it is, then we don't allow the spawn.						//   V

	if (Check_Sides (self, x, y))
	{
		return;
	}

	other = Spawn (spawntype, x, y, z, ALLOW_REPLACE);

	// [BC] If we're the server, tell clients to spawn the actor.
	if ( NETWORK_GetState( ) == NETSTATE_SERVER )
		SERVERCOMMANDS_SpawnThing( other );

	// Check to see if the new Lost Soul's z value is above the
	// ceiling of its new sector, or below the floor. If so, kill it.

	if ((other->z >
         (other->Sector->ceilingplane.ZatPoint (other->x, other->y) - other->height)) ||
        (other->z < other->Sector->floorplane.ZatPoint (other->x, other->y)))
	{
		// kill it immediately
		P_DamageMobj (other, self, self, 1000000, MOD_UNKNOWN);		//   ^
		return;														//   |
	}																// phares

	// Check for movements.

	if (!P_CheckPosition (other, other->x, other->y))
	{
		// kill it immediately
		P_DamageMobj (other, self, self, 1000000, MOD_UNKNOWN);		
		return;
	}

	// [RH] Lost souls hate the same things as their pain elementals
	other->CopyFriendliness (self, true);

	A_SkullAttack (other);
}