예제 #1
0
void AScriptedMarine::Tick ()
{
	Super::Tick ();

	// Override the standard sprite, if desired
	if (SpriteOverride != 0 && sprite == GetClass()->ActorInfo->OwnedStates[0].sprite)
	{
		sprite = SpriteOverride;
	}

	if (special1 != 0)
	{
		if (CurrentWeapon == WEAPON_SuperShotgun)
		{ // Play SSG reload sounds
			int ticks = level.maptime - special1;
			if (ticks < 47)
			{
				switch (ticks)
				{
				case 14:
					S_Sound (this, CHAN_WEAPON, "weapons/sshoto", 1, ATTN_NORM);

					// [BC] If we're the server, tell clients to play this sound.
					if ( NETWORK_GetState( ) == NETSTATE_SERVER )
						SERVERCOMMANDS_SoundActor( this, CHAN_WEAPON, "weapons/sshoto", 1, ATTN_NORM );
					break;
				case 28:
					S_Sound (this, CHAN_WEAPON, "weapons/sshotl", 1, ATTN_NORM);

					// [BC] If we're the server, tell clients to play this sound.
					if ( NETWORK_GetState( ) == NETSTATE_SERVER )
						SERVERCOMMANDS_SoundActor( this, CHAN_WEAPON, "weapons/sshotl", 1, ATTN_NORM );
					break;
				case 41:
					S_Sound (this, CHAN_WEAPON, "weapons/sshotc", 1, ATTN_NORM);

					// [BC] If we're the server, tell clients to play this sound.
					if ( NETWORK_GetState( ) == NETSTATE_SERVER )
						SERVERCOMMANDS_SoundActor( this, CHAN_WEAPON, "weapons/sshotc", 1, ATTN_NORM );
					break;
				}
			}
			else
			{
				special1 = 0;
			}
		}
		else
		{ // Wait for a long refire time
			if (level.maptime >= special1)
			{
				special1 = 0;
			}
			else
			{
				flags |= MF_JUSTATTACKED;
			}
		}
	}
}
예제 #2
0
DEFINE_ACTION_FUNCTION(AActor, A_GetHurt)
{
	// [BB] The server handles this.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		if (( self->ulNetworkFlags & NETFL_CLIENTSIDEONLY ) == false )
			return;
	}

	self->flags4 |= MF4_INCOMBAT;
	if ((pr_gethurt() % 5) == 0)
	{
		S_Sound (self, CHAN_VOICE, self->PainSound, 1, ATTN_NORM);

		// [BB] If we're the server, tell clients to play the sound.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVERCOMMANDS_SoundActor( self, CHAN_VOICE, S_GetName( self->PainSound ), 1, ATTN_NORM );

		self->health--;
	}
	if (self->health <= 0)
	{
		self->Die (self->target, self->target);
	}
}
예제 #3
0
DEFINE_ACTION_FUNCTION(AActor, A_TemplarAttack)
{
	int damage;
	angle_t angle;
	int pitch;
	int pitchdiff;

	if (self->target == NULL)
		return;

	S_Sound (self, CHAN_WEAPON, "templar/shoot", 1, ATTN_NORM);

	// [CW] Tell clients to play the sound.
	if ( NETWORK_GetState( ) == NETSTATE_SERVER )
		SERVERCOMMANDS_SoundActor( self, CHAN_WEAPON, "templar/shoot", 1, ATTN_NORM );

	A_FaceTarget (self);
	pitch = P_AimLineAttack (self, self->angle, MISSILERANGE);

	for (int i = 0; i < 10; ++i)
	{
		damage = (pr_templar() & 4) * 2;
		angle = self->angle + (pr_templar.Random2() << 19);
		pitchdiff = pr_templar.Random2() * 332063;
		P_LineAttack (self, angle, MISSILERANGE+64*FRACUNIT, pitch+pitchdiff, damage, NAME_None, NAME_MaulerPuff);
	}
}
예제 #4
0
DEFINE_ACTION_FUNCTION(AActor, A_BishopAttack)
{
	// [BB] This is server-side.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return;
	}

	if (!self->target)
	{
		return;
	}
	S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NORM);

	// [BB] If we're the server, tell the clients to play the sound.
	if ( NETWORK_GetState( ) == NETSTATE_SERVER )
		SERVERCOMMANDS_SoundActor( self, CHAN_BODY, S_GetName(self->AttackSound), 1, ATTN_NORM );

	if (self->CheckMeleeRange())
	{
		int damage = pr_atk.HitDice (4);
		P_DamageMobj (self->target, self, self, damage, NAME_Melee);
		P_TraceBleed (damage, self->target, self);
		return;
	}
	self->special1 = (pr_atk() & 3) + 5;
}
예제 #5
0
DEFINE_ACTION_FUNCTION(AActor, A_M_BFGsound)
{
	// [BC] Don't do this in client mode.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return;
	}

	if (self->target == NULL)
		return;

	if (self->special1 != 0)
	{
		self->SetState (self->SeeState);
	}
	else
	{
		A_FaceTarget (self);
		S_Sound (self, CHAN_WEAPON, "weapons/bfgf", 1, ATTN_NORM);

		// [BC] If we're the server, tell clients to play this sound.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVERCOMMANDS_SoundActor( self, CHAN_WEAPON, "weapons/bfgf", 1, ATTN_NORM );

		// Don't interrupt the firing sequence
		self->PainChance = 0;
	}
}
예제 #6
0
DEFINE_ACTION_FUNCTION(AActor, A_SerpentMeleeAttack)
{
	// [BB] This is server-side.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return;
	}

	if (!self->target)
	{
		return;
	}
	if (self->CheckMeleeRange ())
	{
		int damage = pr_serpentmeattack.HitDice (5);
		P_DamageMobj (self->target, self, self, damage, NAME_Melee);
		P_TraceBleed (damage, self->target, self);
		S_Sound (self, CHAN_BODY, "SerpentMeleeHit", 1, ATTN_NORM);

		// [BB] If we're the server, tell the clients to play the sound.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVERCOMMANDS_SoundActor( self, CHAN_BODY, "SerpentMeleeHit", 1, ATTN_NORM );
	}
	if (pr_serpentmeattack() < 96)
	{
		CALL_ACTION(A_SerpentCheckForAttack, self);
	}
}
예제 #7
0
DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun2)
{
	int pitch;

	// [BC] Don't do this in client mode.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return;
	}

	if (self->target == NULL)
		return;

	S_Sound (self, CHAN_WEAPON, "weapons/sshotf", 1, ATTN_NORM);

	// [BC] If we're the server, tell clients to play this sound.
	if ( NETWORK_GetState( ) == NETSTATE_SERVER )
		SERVERCOMMANDS_SoundActor( self, CHAN_WEAPON, "weapons/sshotf", 1, ATTN_NORM );

	A_FaceTarget (self);
	pitch = P_AimLineAttack (self, self->angle, MISSILERANGE);
	for (int i = 0; i < 20; ++i)
	{
		int damage = 5*(pr_m_fireshotgun2()%3+1);
		angle_t angle = self->angle + (pr_m_fireshotgun2.Random2() << 19);

		P_LineAttack (self, angle, MISSILERANGE,
					  pitch + (pr_m_fireshotgun2.Random2() * 332063), damage,
					  NAME_None, PClass::FindClass(NAME_BulletPuff));
	}
	self->special1 = level.maptime;
}
예제 #8
0
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_FireCGun)
{
	// [BC] Don't do this in client mode.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return;
	}

	if (self->target == NULL)
		return;

	ACTION_PARAM_START(1);
	ACTION_PARAM_BOOL(accurate, 0);

	S_Sound (self, CHAN_WEAPON, "weapons/chngun", 1, ATTN_NORM);

	// [BC] If we're the server, tell clients to play this sound.
	if ( NETWORK_GetState( ) == NETSTATE_SERVER )
		SERVERCOMMANDS_SoundActor( self, CHAN_WEAPON, "weapons/chngun", 1, ATTN_NORM );

	A_FaceTarget (self);
	P_GunShot2 (self, accurate, P_AimLineAttack (self, self->angle, MISSILERANGE),
		PClass::FindClass(NAME_BulletPuff));
}
예제 #9
0
DEFINE_ACTION_FUNCTION(AActor, A_BishopDoBlur)
{
	// [BB] This is server-side.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return;
	}

	self->special1 = (pr_doblur() & 3) + 3; // Random number of blurs
	if (pr_doblur() < 120)
	{
		P_ThrustMobj (self, self->angle + ANG90, 11*FRACUNIT);
	}
	else if (pr_doblur() > 125)
	{
		P_ThrustMobj (self, self->angle - ANG90, 11*FRACUNIT);
	}
	else
	{ // Thrust forward
		P_ThrustMobj (self, self->angle, 11*FRACUNIT);
	}
	S_Sound (self, CHAN_BODY, "BishopBlur", 1, ATTN_NORM);

	// [BB] If we're the server, update the thing's momentum and play the sound.
	if ( NETWORK_GetState( ) == NETSTATE_SERVER )
	{
		SERVERCOMMANDS_MoveThingExact( self, CM_MOMX|CM_MOMY );
		SERVERCOMMANDS_SoundActor( self, CHAN_BODY, "BishopBlur", 1, ATTN_NORM );
	}
}
예제 #10
0
DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun)
{
	int pitch;

	// [BC] Don't do this in client mode.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return;
	}

	if (self->target == NULL)
		return;

	S_Sound (self, CHAN_WEAPON,  "weapons/shotgf", 1, ATTN_NORM);

	// [BC] If we're the server, tell clients to play this sound.
	if ( NETWORK_GetState( ) == NETSTATE_SERVER )
		SERVERCOMMANDS_SoundActor( self, CHAN_WEAPON, "weapons/shotgf", 1, ATTN_NORM );

	A_FaceTarget (self);
	pitch = P_AimLineAttack (self, self->angle, MISSILERANGE);
	for (int i = 0; i < 7; ++i)
	{
		P_GunShot2 (self, false, pitch, PClass::FindClass(NAME_BulletPuff));
	}
	self->special1 = level.maptime + 27;
}
예제 #11
0
DEFINE_ACTION_FUNCTION(AActor, A_BruisAttack)
{
	AActor	*pMissile;

	if (!self->target)
		return;
				
	if (self->CheckMeleeRange ())
	{
		int damage = (pr_bruisattack()%8+1)*10;
		S_Sound (self, CHAN_WEAPON, "baron/melee", 1, ATTN_NORM);

		// [BC] If we're the server, tell clients play this sound.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVERCOMMANDS_SoundActor( self, CHAN_WEAPON, "baron/melee", 1, ATTN_NORM );

		P_DamageMobj (self->target, self, self, damage, NAME_Melee);
		P_TraceBleed (damage, self->target, self);
		return;
	}
	
	// launch a missile
	pMissile = P_SpawnMissile (self, self->target, PClass::FindClass("BaronBall"));

	// [BC] If we're the server, tell clients to spawn the missile.
	if (( NETWORK_GetState( ) == NETSTATE_SERVER ) && ( pMissile ))
		SERVERCOMMANDS_SpawnMissile( pMissile );
}
예제 #12
0
DEFINE_ACTION_FUNCTION(AActor, A_SerpentHumpDecide)
{
	// [BB] This is server-side.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return;
	}

	if (self->MissileState != NULL)
	{
		if (pr_serpenthump() > 30)
		{
			return;
		}
		else if (pr_serpenthump() < 40)
		{ // Missile attack
			// [BB] If we're the server, set the thing's state.
			if ( NETWORK_GetState( ) == NETSTATE_SERVER )
				SERVERCOMMANDS_SetThingState( self, STATE_MELEE );

			self->SetState (self->MeleeState);
			return;
		}
	}
	else if (pr_serpenthump() > 3)
	{
		return;
	}
	if (!self->CheckMeleeRange ())
	{ // The hump shouldn't occur when within melee range
		if (self->MissileState != NULL && pr_serpenthump() < 128)
		{
			// [BB] If we're the server, set the thing's state.
			if ( NETWORK_GetState( ) == NETSTATE_SERVER )
				SERVERCOMMANDS_SetThingState( self, STATE_MELEE );

			self->SetState (self->MeleeState);
		}
		else
		{	
			// [BB] If we're the server, set the thing's state and play the sound.
			if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			{
				SERVERCOMMANDS_SetThingFrame( self, self->FindState ("Hump") );
				SERVERCOMMANDS_SoundActor( self, CHAN_BODY, "SerpentActive", 1, ATTN_NORM );
			}

			self->SetState (self->FindState ("Hump"));
			S_Sound (self, CHAN_BODY, "SerpentActive", 1, ATTN_NORM);
		}
	}
}
예제 #13
0
DEFINE_ACTION_FUNCTION(AActor, A_WizAtk3)
{
	AActor *mo;

	CALL_ACTION(A_GhostOff, self);

	// [BB] This is server-side, the client only needs to run A_GhostOff.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return;
	}

	if (!self->target)
	{
		return;
	}
	S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);

	// [BB] If we're the server, tell the clients to play the sound.
	if ( NETWORK_GetState( ) == NETSTATE_SERVER )
		SERVERCOMMANDS_SoundActor( self, CHAN_WEAPON, S_GetName( self->AttackSound ), 1, ATTN_NORM );

	if (self->CheckMeleeRange())
	{
		int damage = pr_wizatk3.HitDice (4);
		P_DamageMobj (self->target, self, self, damage, NAME_Melee);
		P_TraceBleed (damage, self->target, self);
		return;
	}
	const PClass *fx = PClass::FindClass("WizardFX1");
	mo = P_SpawnMissile (self, self->target, fx);
	if (mo != NULL)
	{
		AActor *missile1 = P_SpawnMissileAngle(self, fx, mo->angle-(ANG45/8), mo->velz);
		AActor *missile2 = P_SpawnMissileAngle(self, fx, mo->angle+(ANG45/8), mo->velz);

		// [BB] If we're the server, tell the clients to spawn the missiles.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
		{
			SERVERCOMMANDS_SpawnMissile( mo );
			if ( missile1 )
				SERVERCOMMANDS_SpawnMissile( missile1 );
			if ( missile2 )
				SERVERCOMMANDS_SpawnMissile( missile2 );
		}

	}
}
예제 #14
0
DEFINE_ACTION_FUNCTION(AActor, A_MarineNoise)
{
	// [BC] Don't do this in client mode.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return;
	}

	if (static_cast<AScriptedMarine *>(self)->CurrentWeapon == AScriptedMarine::WEAPON_Chainsaw)
	{
		S_Sound (self, CHAN_WEAPON, "weapons/sawidle", 1, ATTN_NORM);

		// [BC] If we're the server, tell clients to play this sound.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVERCOMMANDS_SoundActor( self, CHAN_WEAPON, "weapons/sawidle", 1, ATTN_NORM );
	}
}
예제 #15
0
DEFINE_ACTION_FUNCTION(AActor, A_ShootGun)
{
	int pitch;

	if (self->target == NULL)
		return;

	// [BC] Play this sound to clients.
	if ( NETWORK_GetState( ) == NETSTATE_SERVER )
		SERVERCOMMANDS_SoundActor( self, CHAN_WEAPON, "monsters/rifle", 1, ATTN_NORM );

	S_Sound (self, CHAN_WEAPON, "monsters/rifle", 1, ATTN_NORM);
	A_FaceTarget (self);
	pitch = P_AimLineAttack (self, self->angle, MISSILERANGE);
	P_LineAttack (self, self->angle + (pr_shootgun.Random2() << 19),
		MISSILERANGE, pitch,
		3*(pr_shootgun() % 5 + 1), NAME_None, NAME_StrifePuff);
}
예제 #16
0
void A_SkullAttack(AActor *self, fixed_t speed)
{
	AActor *dest;
	angle_t an;
	int dist;

	// [BC] This is handled server-side.
	if ( NETWORK_InClientMode() )
	{
		return;
	}

	if (!self->target)
		return;
				
	dest = self->target;		
	self->flags |= MF_SKULLFLY;

	S_Sound (self, CHAN_VOICE, self->AttackSound, 1, ATTN_NORM);

	// [BC] If we're the server, tell clients play this sound.
	// [BB] And tell them of MF_SKULLFLY.
	if ( NETWORK_GetState( ) == NETSTATE_SERVER )
	{
		SERVERCOMMANDS_SetThingFlags( self, FLAGSET_FLAGS );
		SERVERCOMMANDS_SoundActor( self, CHAN_VOICE, S_GetName( self->AttackSound ), 1, ATTN_NORM );
	}

	A_FaceTarget (self);
	an = self->angle >> ANGLETOFINESHIFT;
	self->velx = FixedMul (speed, finecosine[an]);
	self->vely = FixedMul (speed, finesine[an]);
	dist = P_AproxDistance (dest->x - self->x, dest->y - self->y);
	dist = dist / speed;
	
	if (dist < 1)
		dist = 1;
	self->velz = (dest->z + (dest->height>>1) - self->z) / dist;

	// [BC] Update the lost soul's momentum.
	if ( NETWORK_GetState( ) == NETSTATE_SERVER )
		SERVERCOMMANDS_MoveThingExact( self, CM_X|CM_Y|CM_Z|CM_MOMX|CM_MOMY|CM_MOMZ );
}
예제 #17
0
DEFINE_ACTION_FUNCTION(AActor, A_SnoutAttack)
{
	angle_t angle;
	int damage;
	int slope;
	player_t *player;
	AActor *puff;
	AActor *linetarget;

	if (NULL == (player = self->player))
	{
		return;
	}

	damage = 3+(pr_snoutattack()&3);
	angle = player->mo->angle;
	slope = P_AimLineAttack(player->mo, angle, MELEERANGE, &linetarget);
	puff = P_LineAttack(player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "SnoutPuff", true);
	S_Sound(player->mo, CHAN_VOICE, "PigActive", 1, ATTN_NORM);

	// [Dusk] clients aren't properly aware of linetarget, thus they stop here.
	if (NETWORK_InClientMode()) return;

	if(linetarget)
	{
		AdjustPlayerAngle(player->mo, linetarget);

		// [Dusk] update angle
		if (NETWORK_GetState() == NETSTATE_SERVER)
			SERVERCOMMANDS_MoveThing(player->mo, CM_ANGLE);

		if(puff != NULL)
		{ // Bit something
			S_Sound(player->mo, CHAN_VOICE, "PigAttack", 1, ATTN_NORM);

			// [Dusk] tell clients of the attack sound
			if (NETWORK_GetState() == NETSTATE_SERVER)
				SERVERCOMMANDS_SoundActor (player->mo, CHAN_VOICE, "PigAttack", 1, ATTN_NORM);
		}
	}
}
예제 #18
0
static void MarinePunch(AActor *self, int damagemul)
{
	angle_t 	angle;
	int 		damage;
	int 		pitch;
	AActor		*linetarget;

	// [BC] Don't do this in client mode.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return;
	}

	if (self->target == NULL)
		return;

	damage = ((pr_m_punch()%10+1) << 1) * damagemul;

	A_FaceTarget (self);
	angle = self->angle + (pr_m_punch.Random2() << 18);
	pitch = P_AimLineAttack (self, angle, MELEERANGE, &linetarget);
	P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, true);

	// turn to face target
	if (linetarget)
	{
		S_Sound (self, CHAN_WEAPON, "*fist", 1, ATTN_NORM);

		// [BC] If we're the server, tell clients to play this sound.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVERCOMMANDS_SoundActor( self, CHAN_WEAPON, "*fist", 1, ATTN_NORM );

		self->angle = R_PointToAngle2 (self->x, self->y, linetarget->x, linetarget->y);
	}
}
예제 #19
0
DEFINE_ACTION_FUNCTION(AActor, A_FiredAttack)
{
	// [BC] Let the server do this.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return;
	}

	if (self->target == NULL)
		return;
	AActor *mo = P_SpawnMissile (self, self->target, PClass::FindClass ("FireDemonMissile"));
	if (mo)
	{
		S_Sound (self, CHAN_BODY, "FireDemonAttack", 1, ATTN_NORM);

		// [BC] If we're the server, spawn this and make the sound for clients.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
		{
			SERVERCOMMANDS_SpawnMissile( mo );
			SERVERCOMMANDS_SoundActor( self, CHAN_BODY, "FireDemonAttack", 1, ATTN_NORM );
		}
	}
}
예제 #20
0
DEFINE_ACTION_FUNCTION(AActor, A_M_Saw)
{
	// [BC] Don't do this in client mode.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return;
	}

	if (self->target == NULL)
		return;

	A_FaceTarget (self);
	if (self->CheckMeleeRange ())
	{
		angle_t 	angle;
		int 		damage;
		AActor		*linetarget;

		damage = 2 * (pr_m_saw()%10+1);
		angle = self->angle + (pr_m_saw.Random2() << 18);
		
		P_LineAttack (self, angle, MELEERANGE+1,
					P_AimLineAttack (self, angle, MELEERANGE+1, &linetarget), damage,
					NAME_Melee, NAME_BulletPuff);

		if (!linetarget)
		{
			S_Sound (self, CHAN_WEAPON, "weapons/sawfull", 1, ATTN_NORM);

			// [BC] If we're the server, tell clients to play this sound.
			if ( NETWORK_GetState( ) == NETSTATE_SERVER )
				SERVERCOMMANDS_SoundActor( self, CHAN_WEAPON, "weapons/sawfull", 1, ATTN_NORM );
			return;
		}
		S_Sound (self, CHAN_WEAPON, "weapons/sawhit", 1, ATTN_NORM);

		// [BC] If we're the server, tell clients to play this sound.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVERCOMMANDS_SoundActor( self, CHAN_WEAPON, "weapons/sawhit", 1, ATTN_NORM );
			
		// turn to face target
		angle = R_PointToAngle2 (self->x, self->y, linetarget->x, linetarget->y);
		if (angle - self->angle > ANG180)
		{
			if (angle - self->angle < (angle_t)(-ANG90/20))
				self->angle = angle + ANG90/21;
			else
				self->angle -= ANG90/20;
		}
		else
		{
			if (angle - self->angle > ANG90/20)
				self->angle = angle - ANG90/21;
			else
				self->angle += ANG90/20;
		}
	}
	else
	{
		S_Sound (self, CHAN_WEAPON, "weapons/sawfull", 1, ATTN_NORM);

		// [BC] If we're the server, tell clients to play this sound.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVERCOMMANDS_SoundActor( self, CHAN_WEAPON, "weapons/sawfull", 1, ATTN_NORM );
	}
	//A_Chase (self);
}
예제 #21
0
bool AArtiTeleport::Use (bool pickup)
{
	fixed_t destX;
	fixed_t destY;
	angle_t destAngle;

	// [BC] Let the server decide where we go.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return ( true );
	}

	// [BB] If this is a team game and there are valid team starts for the team
	// the owner is on, teleport to one of the team starts.
	const ULONG ownerTeam = Owner->player ? Owner->player->ulTeam : teams.Size( );
	if ( ( GAMEMODE_GetFlags( GAMEMODE_GetCurrentMode( )) & GMF_PLAYERSONTEAMS )
	     && TEAM_CheckIfValid ( ownerTeam )
	     && ( teams[ownerTeam].TeamStarts.Size( ) > 0 ) )
	{
		unsigned int selections = teams[ownerTeam].TeamStarts.Size ();
		unsigned int i = pr_tele() % selections;
		destX = teams[ownerTeam].TeamStarts[i].x;
		destY = teams[ownerTeam].TeamStarts[i].y;
		destAngle = ANG45 * (teams[ownerTeam].TeamStarts[i].angle/45);
	}
	else if (deathmatch)
	{
		unsigned int selections = deathmatchstarts.Size ();
		unsigned int i = pr_tele() % selections;
		destX = deathmatchstarts[i].x;
		destY = deathmatchstarts[i].y;
		destAngle = ANG45 * (deathmatchstarts[i].angle/45);
	}
	else
	{
		FMapThing *pSpot = NULL;
		// [BB] If there is a designated start for this player use it.
		if ( playerstarts[Owner->player - players].type != 0 )
			pSpot = &playerstarts[Owner->player - players];
		// [BB] Otherwise we just have to select a start at random from all available player starts.
		else
			pSpot = SelectRandomCooperativeSpot( Owner->player - players );

		if ( pSpot != NULL )
		{
			destX = pSpot->x;
			destY = pSpot->y;
			destAngle = ANG45 * (pSpot->angle/45);
		}
		else
			I_Error( "ArtiTeleport: No player start found!" );
	}
	P_Teleport (Owner, destX, destY, ONFLOORZ, destAngle, true, true, false);
	bool canlaugh = true;
 	if (Owner->player->morphTics && (Owner->player->MorphStyle & MORPH_UNDOBYCHAOSDEVICE))
 	{ // Teleporting away will undo any morph effects (pig)
		if (!P_UndoPlayerMorph (Owner->player, Owner->player, MORPH_UNDOBYCHAOSDEVICE)
			&& (Owner->player->MorphStyle & MORPH_FAILNOLAUGH))
		{
			canlaugh = false;
		}
 	}
	if (canlaugh)
 	{ // Full volume laugh
 		S_Sound (Owner, CHAN_VOICE, "*evillaugh", 1, ATTN_NONE);

		// [BC] Play the laugh for clients.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVERCOMMANDS_SoundActor( Owner, CHAN_VOICE, "*evillaugh", 1, ATTN_NONE );
 	}
	return true;
}