示例#1
0
DEFINE_ACTION_FUNCTION(AActor, A_KnightAttack)
{
	PARAM_ACTION_PROLOGUE;

	if (!self->target)
	{
		return 0;
	}
	if (self->CheckMeleeRange ())
	{
		int damage = pr_knightatk.HitDice (3);
		int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
		P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
		S_Sound (self, CHAN_BODY, "hknight/melee", 1, ATTN_NORM);
		return 0;
	}
	// Throw axe
	S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NORM);
	if (self->flags & MF_SHADOW || pr_knightatk () < 40)
	{ // Red axe
		P_SpawnMissileZ (self, self->Z() + 36, self->target, PClass::FindActor("RedAxe"));
		return 0;
	}
	// Green axe
	P_SpawnMissileZ (self, self->Z() + 36, self->target, PClass::FindActor("KnightAxe"));
	return 0;
}
示例#2
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);
	}
}
示例#3
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;
}
示例#4
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 );
}
示例#5
0
void A_Srcr2Attack (AActor *actor)
{
	int chance;

	if (!actor->target)
	{
		return;
	}
	S_SoundID (actor, CHAN_BODY, actor->AttackSound, 1, ATTN_NONE);
	if (actor->CheckMeleeRange())
	{
		int damage = pr_s2a.HitDice (20);
		P_DamageMobj (actor->target, actor, actor, damage, NAME_Melee);
		P_TraceBleed (damage, actor->target, actor);
		return;
	}
	chance = actor->health < actor->GetDefault()->health/2 ? 96 : 48;
	if (pr_s2a() < chance)
	{ // Wizard spawners
		P_SpawnMissileAngle (actor, RUNTIME_CLASS(ASorcerer2FX2),
			actor->angle-ANG45, FRACUNIT/2);
		P_SpawnMissileAngle (actor, RUNTIME_CLASS(ASorcerer2FX2),
			actor->angle+ANG45, FRACUNIT/2);
	}
	else
	{ // Blue bolt
		P_SpawnMissile (actor, actor->target, RUNTIME_CLASS(ASorcerer2FX1));
	}
}
示例#6
0
DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Attack)
{
	int chance;

	if (!self->target)
	{
		return;
	}
	S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NONE);
	if (self->CheckMeleeRange())
	{
		int damage = pr_s2a.HitDice (20);
		int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
		P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
		return;
	}
	chance = self->health < self->SpawnHealth()/2 ? 96 : 48;
	if (pr_s2a() < chance)
	{ // Wizard spawners

		const PClass *fx = PClass::FindClass("Sorcerer2FX2");
		if (fx)
		{
			P_SpawnMissileAngle (self, fx, self->angle-ANG45, FRACUNIT/2);
			P_SpawnMissileAngle (self, fx, self->angle+ANG45, FRACUNIT/2);
		}
	}
	else
	{ // Blue bolt
		P_SpawnMissile (self, self->target, PClass::FindClass("Sorcerer2FX1"));
	}
}
示例#7
0
DEFINE_ACTION_FUNCTION(AActor, A_ChicAttack)
{
	if (!self->target)
	{
		return;
	}
	if (self->CheckMeleeRange())
	{
		int damage = 1 + (pr_chicattack() & 1);
		int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
		P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
	}
}
void A_ImpMeAttack (AActor *self)
{
	if (!self->target)
	{
		return;
	}
	S_SoundID (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
	if (self->CheckMeleeRange ())
	{
		int damage = 5+(pr_impmeatk()&7);
		P_DamageMobj (self->target, self, self, damage, MOD_HIT);
		P_TraceBleed (damage, self->target, self);
	}
}
示例#9
0
DEFINE_ACTION_FUNCTION(AActor, A_Srcr1Attack)
{
	PARAM_ACTION_PROLOGUE;

	AActor *mo;
	DAngle angle;

	if (!self->target)
	{
		return 0;
	}
	S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NORM);
	if (self->CheckMeleeRange ())
	{
		int damage = pr_scrc1atk.HitDice (8);
		int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
		P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
		return 0;
	}

	PClassActor *fx = PClass::FindActor("SorcererFX1");
	if (self->health > (self->SpawnHealth()/3)*2)
	{ // Spit one fireball
		P_SpawnMissileZ (self, self->Z() + 48, self->target, fx );
	}
	else
	{ // Spit three fireballs
		mo = P_SpawnMissileZ (self, self->Z() + 48, self->target, fx);
		if (mo != NULL)
		{
			angle = mo->Angles.Yaw;
			P_SpawnMissileAngleZ(self, self->Z() + 48, fx, angle - 3, mo->Vel.Z);
			P_SpawnMissileAngleZ(self, self->Z() + 48, fx, angle + 3, mo->Vel.Z);
		}
		if (self->health < self->SpawnHealth()/3)
		{ // Maybe attack again
			if (self->special1)
			{ // Just attacked, so don't attack again
				self->special1 = 0;
			}
			else
			{ // Set state to attack again
				self->special1 = 1;
				self->SetState (self->FindState("Missile2"));
			}
		}
	}
	return 0;
}
示例#10
0
DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk3)
{
    PARAM_ACTION_PROLOGUE;

    AActor *mo;
    player_t *player;
    bool friendly = !!(self->flags5 & MF5_SUMMONEDMONSTER);

    if (!self->target)
    {
        return 0;
    }
    S_Sound (self, CHAN_VOICE, "minotaur/attack3", 1, ATTN_NORM);
    if (self->CheckMeleeRange())
    {
        int damage;

        damage = pr_minotauratk3.HitDice (friendly ? 3 : 5);
        int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
        P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
        if ((player = self->target->player) != NULL &&
                player->mo == self->target)
        {   // Squish the player
            player->deltaviewheight = -16;
        }
    }
    else
    {
        if (self->Floorclip > 0 && (i_compatflags & COMPATF_MINOTAUR))
        {
            // only play the sound.
            S_Sound (self, CHAN_WEAPON, "minotaur/fx2hit", 1, ATTN_NORM);
        }
        else
        {
            mo = P_SpawnMissile (self, self->target, PClass::FindActor("MinotaurFX2"));
            if (mo != NULL)
            {
                S_Sound (mo, CHAN_WEAPON, "minotaur/attack1", 1, ATTN_NORM);
            }
        }
    }
    if (pr_minotauratk3() < 192 && self->special2 == 0)
    {
        self->SetState (self->FindState ("HammerLoop"));
        self->special2 = 1;
    }
    return 0;
}
示例#11
0
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack)
{		
	ACTION_PARAM_START(7);
	ACTION_PARAM_SOUND(snd,0);
	ACTION_PARAM_INT(dmg,1);
	ACTION_PARAM_INT(blastdmg,2);
	ACTION_PARAM_INT(blastrad,3);
	ACTION_PARAM_FIXED(thrust,4);
	ACTION_PARAM_NAME(dmgtype,5);
	ACTION_PARAM_INT(flags,6);

	AActor *fire, *target;
	angle_t an;
		
	if (NULL == (target = self->target))
		return;
	
	A_FaceTarget (self);

	if (!P_CheckSight (self, target, 0) )
		return;

	S_Sound (self, CHAN_WEAPON, snd, 1, ATTN_NORM);

	int newdam;

	if (flags & VAF_DMGTYPEAPPLYTODIRECT)
		newdam = P_DamageMobj (target, self, self, dmg, dmgtype);

	else
		newdam = P_DamageMobj (target, self, self, dmg, NAME_None);

	P_TraceBleed (newdam > 0 ? newdam : dmg, target);
		
	an = self->angle >> ANGLETOFINESHIFT;
	fire = self->tracer;

	if (fire != NULL)
	{
		// move the fire between the vile and the player
		fire->SetOrigin (target->x - FixedMul (24*FRACUNIT, finecosine[an]),
						 target->y - FixedMul (24*FRACUNIT, finesine[an]),
						 target->z);
		
		P_RadiusAttack (fire, self, blastdmg, blastrad, dmgtype, 0);
	}
	if (!(target->flags7 & MF7_DONTTHRUST))
		target->velz = Scale(thrust, 1000, target->Mass);
}
示例#12
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 );
		}

	}
}
示例#13
0
DEFINE_ACTION_FUNCTION(AActor, A_SkelFist)
{
	if (!self->target)
		return;
				
	A_FaceTarget (self);
		
	if (self->CheckMeleeRange ())
	{
		int damage = ((pr_skelfist()%10)+1)*6;
		S_Sound (self, CHAN_WEAPON, "skeleton/melee", 1, ATTN_NORM);
		int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
		P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
	}
}
示例#14
0
DEFINE_ACTION_FUNCTION(AActor, A_Srcr1Attack)
{
	AActor *mo;
	fixed_t velz;
	angle_t angle;

	if (!self->target)
	{
		return;
	}
	S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NORM);
	if (self->CheckMeleeRange ())
	{
		int damage = pr_scrc1atk.HitDice (8);
		int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
		P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
		return;
	}

	const PClass *fx = PClass::FindClass("SorcererFX1");
	if (self->health > (self->SpawnHealth()/3)*2)
	{ // Spit one fireball
		P_SpawnMissileZ (self, self->Z() + 48*FRACUNIT, self->target, fx );
	}
	else
	{ // Spit three fireballs
		mo = P_SpawnMissileZ (self, self->Z() + 48*FRACUNIT, self->target, fx);
		if (mo != NULL)
		{
			velz = mo->velz;
			angle = mo->angle;
			P_SpawnMissileAngleZ (self, self->Z() + 48*FRACUNIT, fx, angle-ANGLE_1*3, velz);
			P_SpawnMissileAngleZ (self, self->Z() + 48*FRACUNIT, fx, angle+ANGLE_1*3, velz);
		}
		if (self->health < self->SpawnHealth()/3)
		{ // Maybe attack again
			if (self->special1)
			{ // Just attacked, so don't attack again
				self->special1 = 0;
			}
			else
			{ // Set state to attack again
				self->special1 = 1;
				self->SetState (self->FindState("Missile2"));
			}
		}
	}
}
示例#15
0
DEFINE_ACTION_FUNCTION(AActor, A_BishopAttack)
{
	if (!self->target)
	{
		return;
	}
	S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NORM);
	if (self->CheckMeleeRange())
	{
		int damage = pr_atk.HitDice (4);
		int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
		P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
		return;
	}
	self->special1 = (pr_atk() & 3) + 5;
}
示例#16
0
void A_ImpMsAttack2 (AActor *self)
{
	if (!self->target)
	{
		return;
	}
	S_SoundID (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
	if (self->CheckMeleeRange ())
	{
		int damage = 5+(pr_impmsatk2()&7);
		P_DamageMobj (self->target, self, self, damage, MOD_HIT);
		P_TraceBleed (damage, self->target, self);
		return;
	}
	P_SpawnMissile (self, self->target, RUNTIME_CLASS(AHereticImpBall));
}
示例#17
0
DEFINE_ACTION_FUNCTION(AActor, A_SargAttack)
{
	PARAM_ACTION_PROLOGUE;

	if (!self->target)
		return 0;
				
	A_FaceTarget (self);
	if (self->CheckMeleeRange ())
	{
		int damage = ((pr_sargattack()%10)+1)*4;
		int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
		P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
	}
	return 0;
}
示例#18
0
void P_MinotaurSlam (AActor *source, AActor *target)
{
    DAngle angle;
    double thrust;
    int damage;

    angle = source->AngleTo(target);
    thrust = 16 + pr_minotaurslam() / 64.;
    target->VelFromAngle(angle, thrust);
    damage = pr_minotaurslam.HitDice (static_cast<AMinotaur *>(source) ? 4 : 6);
    int newdam = P_DamageMobj (target, NULL, NULL, damage, NAME_Melee);
    P_TraceBleed (newdam > 0 ? newdam : damage, target, angle, 0.);
    if (target->player)
    {
        target->reactiontime = 14+(pr_minotaurslam()&7);
    }
}
示例#19
0
void A_Srcr1Attack (AActor *actor)
{
	AActor *mo;
	fixed_t momz;
	angle_t angle;

	if (!actor->target)
	{
		return;
	}
	S_SoundID (actor, CHAN_BODY, actor->AttackSound, 1, ATTN_NORM);
	if (actor->CheckMeleeRange ())
	{
		int damage = pr_scrc1atk.HitDice (8);
		P_DamageMobj (actor->target, actor, actor, damage, NAME_Melee);
		P_TraceBleed (damage, actor->target, actor);
		return;
	}
	if (actor->health > (actor->GetDefault()->health/3)*2)
	{ // Spit one fireball
		P_SpawnMissileZ (actor, actor->z + 48*FRACUNIT, actor->target, RUNTIME_CLASS(ASorcererFX1));
	}
	else
	{ // Spit three fireballs
		mo = P_SpawnMissileZ (actor, actor->z + 48*FRACUNIT, actor->target, RUNTIME_CLASS(ASorcererFX1));
		if (mo != NULL)
		{
			momz = mo->momz;
			angle = mo->angle;
			P_SpawnMissileAngleZ (actor, actor->z + 48*FRACUNIT, RUNTIME_CLASS(ASorcererFX1), angle-ANGLE_1*3, momz);
			P_SpawnMissileAngleZ (actor, actor->z + 48*FRACUNIT, RUNTIME_CLASS(ASorcererFX1), angle+ANGLE_1*3, momz);
		}
		if (actor->health < actor->GetDefault()->health/3)
		{ // Maybe attack again
			if (actor->special1)
			{ // Just attacked, so don't attack again
				actor->special1 = 0;
			}
			else
			{ // Set state to attack again
				actor->special1 = 1;
				actor->SetState (&ASorcerer1::States[S_SRCR1_ATK+3]);
			}
		}
	}
}
示例#20
0
DEFINE_ACTION_FUNCTION(AActor, A_SerpentMeleeAttack)
{
    if (!self->target)
    {
        return;
    }
    if (self->CheckMeleeRange ())
    {
        int damage = pr_serpentmeattack.HitDice (5);
        int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
        P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
        S_Sound (self, CHAN_BODY, "SerpentMeleeHit", 1, ATTN_NORM);
    }
    if (pr_serpentmeattack() < 96)
    {
        CALL_ACTION(A_SerpentCheckForAttack, self);
    }
}
示例#21
0
DEFINE_ACTION_FUNCTION(AActor, A_ProgrammerMelee)
{
	int damage;

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

	A_FaceTarget (self);

	if (!self->CheckMeleeRange ())
		return;

	S_Sound (self, CHAN_WEAPON, "programmer/clank", 1, ATTN_NORM);

	damage = ((pr_prog() % 10) + 1) * 6;
	int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
	P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
}
示例#22
0
//
// A_TroopAttack
//
DEFINE_ACTION_FUNCTION(AActor, A_TroopAttack)
{
    if (!self->target)
        return;

    A_FaceTarget (self);
    if (self->CheckMeleeRange ())
    {
        int damage = (pr_troopattack()%8+1)*3;
        S_Sound (self, CHAN_WEAPON, "imp/melee", 1, ATTN_NORM);
        int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
        P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
        return;
    }

    // launch a missile
    P_SpawnMissile (self, self->target, PClass::FindClass("DoomImpBall"));
}
示例#23
0
DEFINE_ACTION_FUNCTION(AActor, A_StalkerAttack)
{
	if (self->flags & MF_NOGRAVITY)
	{
		self->SetState (self->FindState("Drop"));
	}
	else if (self->target != NULL)
	{
		A_FaceTarget (self);
		if (self->CheckMeleeRange ())
		{
			int damage = (pr_stalker() & 7) * 2 + 2;

			int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
			P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
		}
	}
}
示例#24
0
DEFINE_ACTION_FUNCTION(AActor, A_HeadAttack)
{
	if (!self->target)
		return;
				
	A_FaceTarget (self);
	if (self->CheckMeleeRange ())
	{
		int damage = (pr_headattack()%6+1)*10;
		S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
		int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
		P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
		return;
	}
	
	// launch a missile
	P_SpawnMissile (self, self->target, PClass::FindClass("CacodemonBall"));
}
示例#25
0
DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk2)
{
    PARAM_ACTION_PROLOGUE;

    AActor *mo;
    DAngle angle;
    double vz;
    double z;
    bool friendly = !!(self->flags5 & MF5_SUMMONEDMONSTER);

    if (self->target == NULL)
    {
        return 0;
    }
    S_Sound (self, CHAN_WEAPON, "minotaur/attack2", 1, ATTN_NORM);
    if (self->CheckMeleeRange())
    {
        int damage;
        damage = pr_atk.HitDice (friendly ? 3 : 5);
        int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
        P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
        return 0;
    }
    z = self->Z() + 40;
    PClassActor *fx = PClass::FindActor("MinotaurFX1");
    if (fx)
    {
        mo = P_SpawnMissileZ (self, z, self->target, fx);
        if (mo != NULL)
        {
//			S_Sound (mo, CHAN_WEAPON, "minotaur/attack2", 1, ATTN_NORM);
            vz = mo->Vel.Z;
            angle = mo->Angles.Yaw;
            P_SpawnMissileAngleZ (self, z, fx, angle-(45./8), vz);
            P_SpawnMissileAngleZ (self, z, fx, angle+(45./8), vz);
            P_SpawnMissileAngleZ (self, z, fx, angle-(45./16), vz);
            P_SpawnMissileAngleZ (self, z, fx, angle+(45./16), vz);
        }
    }
    return 0;
}
示例#26
0
DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk1)
{
	player_t *player;

	if (!self->target)
	{
		return;
	}
	S_Sound (self, CHAN_WEAPON, "minotaur/melee", 1, ATTN_NORM);
	if (self->CheckMeleeRange())
	{
		int damage = pr_minotauratk1.HitDice (4);
		int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
		P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
		if ((player = self->target->player) != NULL &&
			player->mo == self->target)
		{ // Squish the player
			player->deltaviewheight = -16*FRACUNIT;
		}
	}
}
示例#27
0
void A_KnightAttack (AActor *actor)
{
	if (!actor->target)
	{
		return;
	}
	if (actor->CheckMeleeRange ())
	{
		int damage = pr_knightatk.HitDice (3);
		P_DamageMobj (actor->target, actor, actor, damage, MOD_HIT);
		P_TraceBleed (damage, actor->target, actor);
		S_Sound (actor, CHAN_BODY, "hknight/melee", 1, ATTN_NORM);
		return;
	}
	// Throw axe
	S_SoundID (actor, CHAN_BODY, actor->AttackSound, 1, ATTN_NORM);
	if (actor->flags & MF_SHADOW || pr_knightatk () < 40)
	{ // Red axe
		P_SpawnMissileZ (actor, actor->z + 36*FRACUNIT, actor->target, RUNTIME_CLASS(ARedAxe));
		return;
	}
	// Green axe
	P_SpawnMissileZ (actor, actor->z + 36*FRACUNIT, actor->target, RUNTIME_CLASS(AKnightAxe));
}
示例#28
0
void A_WizAtk3 (AActor *actor)
{
	AActor *mo;

	A_GhostOff (actor);
	if (!actor->target)
	{
		return;
	}
	S_SoundID (actor, CHAN_WEAPON, actor->AttackSound, 1, ATTN_NORM);
	if (actor->CheckMeleeRange())
	{
		int damage = pr_wizatk3.HitDice (4);
		P_DamageMobj (actor->target, actor, actor, damage, NAME_Melee);
		P_TraceBleed (damage, actor->target, actor);
		return;
	}
	mo = P_SpawnMissile (actor, actor->target, RUNTIME_CLASS(AWizardFX1));
	if (mo != NULL)
	{
		P_SpawnMissileAngle(actor, RUNTIME_CLASS(AWizardFX1), mo->angle-(ANG45/8), mo->momz);
		P_SpawnMissileAngle(actor, RUNTIME_CLASS(AWizardFX1), mo->angle+(ANG45/8), mo->momz);
	}
}
示例#29
0
DEFINE_ACTION_FUNCTION(AActor, A_LichAttack)
{
	int i;
	AActor *fire;
	AActor *baseFire;
	AActor *mo;
	AActor *target;
	int randAttack;
	static const int atkResolve1[] = { 50, 150 };
	static const int atkResolve2[] = { 150, 200 };
	int dist;

	// Ice ball		(close 20% : far 60%)
	// Fire column	(close 40% : far 20%)
	// Whirlwind	(close 40% : far 20%)
	// Distance threshold = 8 cells

	target = self->target;
	if (target == NULL)
	{
		return;
	}
	A_FaceTarget (self);
	if (self->CheckMeleeRange ())
	{
		int damage = pr_atk.HitDice (6);
		P_DamageMobj (target, self, self, damage, NAME_Melee);
		P_TraceBleed (damage, target, self);
		return;
	}
	dist = P_AproxDistance (self->x-target->x, self->y-target->y)
		> 8*64*FRACUNIT;
	randAttack = pr_atk ();
	if (randAttack < atkResolve1[dist])
	{ // Ice ball
		P_SpawnMissile (self, target, PClass::FindClass("HeadFX1"));
		S_Sound (self, CHAN_BODY, "ironlich/attack2", 1, ATTN_NORM);
	}
	else if (randAttack < atkResolve2[dist])
	{ // Fire column
		baseFire = P_SpawnMissile (self, target, PClass::FindClass("HeadFX3"));
		if (baseFire != NULL)
		{
			baseFire->SetState (baseFire->FindState("NoGrow"));
			for (i = 0; i < 5; i++)
			{
				fire = Spawn("HeadFX3", baseFire->x, baseFire->y,
					baseFire->z, ALLOW_REPLACE);
				if (i == 0)
				{
					S_Sound (self, CHAN_BODY, "ironlich/attack1", 1, ATTN_NORM);
				}
				fire->target = baseFire->target;
				fire->angle = baseFire->angle;
				fire->velx = baseFire->velx;
				fire->vely = baseFire->vely;
				fire->velz = baseFire->velz;
				fire->Damage = 0;
				fire->health = (i+1) * 2;
				P_CheckMissileSpawn (fire);
			}
		}
	}
	else
	{ // Whirlwind
		mo = P_SpawnMissile (self, target, RUNTIME_CLASS(AWhirlwind));
		if (mo != NULL)
		{
			mo->z -= 32*FRACUNIT;
			mo->tracer = target;
			mo->special1 = 60;
			mo->special2 = 50; // Timer for active sound
			mo->health = 20*TICRATE; // Duration
			S_Sound (self, CHAN_BODY, "ironlich/attack3", 1, ATTN_NORM);
		}
	}
}