DEFINE_ACTION_FUNCTION(AActor, A_CrusaderChoose) { if (self->target == NULL) return; if (Sys_1ed64 (self)) { A_FaceTarget (self); self->angle -= ANGLE_180/16; P_SpawnMissileZAimed (self, self->z + 40*FRACUNIT, self->target, PClass::FindClass("FastFlameMissile")); } else { if (P_CheckMissileRange (self)) { A_FaceTarget (self); P_SpawnMissileZAimed (self, self->z + 56*FRACUNIT, self->target, PClass::FindClass("CrusaderMissile")); self->angle -= ANGLE_45/32; P_SpawnMissileZAimed (self, self->z + 40*FRACUNIT, self->target, PClass::FindClass("CrusaderMissile")); self->angle += ANGLE_45/16; P_SpawnMissileZAimed (self, self->z + 40*FRACUNIT, self->target, PClass::FindClass("CrusaderMissile")); self->angle -= ANGLE_45/16; self->reactiontime += 15; } self->SetState (self->SeeState); } }
void A_20c74 (AActor *selfa) { AEntityBoss *self = static_cast<AEntityBoss *>(selfa); AEntitySecond *second; fixed_t secondRadius = GetDefault<AEntitySecond>()->radius * 2; angle_t an; an = self->angle >> ANGLETOFINESHIFT; second = Spawn<AEntitySecond> (self->SpawnX + FixedMul (secondRadius, finecosine[an]), self->SpawnY + FixedMul (secondRadius, finesine[an]), self->SpawnZ, ALLOW_REPLACE); second->target = self->target; A_FaceTarget (second); an = second->angle >> ANGLETOFINESHIFT; second->momx += FixedMul (finecosine[an], 320000); second->momy += FixedMul (finesine[an], 320000); an = (self->angle + ANGLE_90) >> ANGLETOFINESHIFT; second = Spawn<AEntitySecond> (self->SpawnX + FixedMul (secondRadius, finecosine[an]), self->SpawnY + FixedMul (secondRadius, finesine[an]), self->SpawnZ, ALLOW_REPLACE); second->target = self->target; second->momx = FixedMul (secondRadius, finecosine[an]) << 2; second->momy = FixedMul (secondRadius, finesine[an]) << 2; A_FaceTarget (second); an = (self->angle - ANGLE_90) >> ANGLETOFINESHIFT; second = Spawn<AEntitySecond> (self->SpawnX + FixedMul (secondRadius, finecosine[an]), self->SpawnY + FixedMul (secondRadius, finesine[an]), self->SpawnZ, ALLOW_REPLACE); second->target = self->target; second->momx = FixedMul (secondRadius, finecosine[an]) << 2; second->momy = FixedMul (secondRadius, finesine[an]) << 2; A_FaceTarget (second); }
DEFINE_ACTION_FUNCTION(AActor, A_MinotaurDecide) { PARAM_ACTION_PROLOGUE; bool friendly = !!(self->flags5 & MF5_SUMMONEDMONSTER); AActor *target; double dist; target = self->target; if (!target) { return 0; } if (!friendly) { S_Sound (self, CHAN_WEAPON, "minotaur/sight", 1, ATTN_NORM); } dist = self->Distance2D(target); if (target->Top() > self->Z() && target->Top() < self->Top() && dist < (friendly ? 16*64. : 8*64.) && dist > 1*64. && pr_minotaurdecide() < 150) { // Charge attack // Don't call the state function right away self->SetState (self->FindState ("Charge"), true); self->flags |= MF_SKULLFLY; if (!friendly) { // Heretic's Minotaur is invulnerable during charge attack self->flags2 |= MF2_INVULNERABLE; } A_FaceTarget (self); self->VelFromAngle(MNTR_CHARGE_SPEED); self->special1 = TICRATE/2; // Charge duration } else if (target->Z() == target->floorz && dist < 9*64. && pr_minotaurdecide() < (friendly ? 100 : 220)) { // Floor fire attack self->SetState (self->FindState ("Hammer")); self->special2 = 0; } else { // Swing attack A_FaceTarget (self); // Don't need to call P_SetMobjState because the current state // falls through to the swing attack } return 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; } }
DEFINE_ACTION_FUNCTION(AActor, A_InquisitorAttack) { PARAM_ACTION_PROLOGUE; AActor *proj; if (self->target == NULL) return 0; A_FaceTarget (self); self->AddZ(32); self->Angles.Yaw -= 45./32; proj = P_SpawnMissileZAimed (self, self->Z(), self->target, PClass::FindActor("InquisitorShot")); if (proj != NULL) { proj->Vel.Z += 9; } self->Angles.Yaw += 45./16; proj = P_SpawnMissileZAimed (self, self->Z(), self->target, PClass::FindActor("InquisitorShot")); if (proj != NULL) { proj->Vel.Z += 16; } self->AddZ(-32); return 0; }
// // A_SpidRefire // // Spider Mastermind line-of-sight checking. // void A_SpidRefire(actionargs_t *actionargs) { Mobj *actor = actionargs->actor; // keep firing unless target got out of sight A_FaceTarget(actionargs); // killough 12/98: Stop firing if a friend has gotten in the way if(actor->flags & MF_FRIEND && P_HitFriend(actor)) { P_SetMobjState(actor, actor->info->seestate); return; } if(P_Random(pr_spidrefire) < 10) return; // killough 11/98: prevent refiring on friends continuously if(!actor->target || actor->target->health <= 0 || actor->flags & actor->target->flags & MF_FRIEND || !P_CheckSight(actor, actor->target)) { P_SetMobjState(actor, actor->info->seestate); } }
DEFINE_ACTION_FUNCTION(AActor, A_InquisitorJump) { fixed_t dist; fixed_t speed; angle_t an; if (self->target == NULL) return; S_Sound (self, CHAN_ITEM|CHAN_LOOP, "inquisitor/jump", 1, ATTN_NORM); self->AddZ(64*FRACUNIT); A_FaceTarget (self); an = self->angle >> ANGLETOFINESHIFT; speed = self->Speed * 2/3; self->velx += FixedMul (speed, finecosine[an]); self->vely += FixedMul (speed, finesine[an]); dist = self->AproxDistance (self->target); dist /= speed; if (dist < 1) { dist = 1; } self->velz = (self->target->Z() - self->Z()) / dist; self->reactiontime = 60; self->flags |= MF_NOGRAVITY; }
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); } }
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; }
DEFINE_ACTION_FUNCTION(AActor, A_WizAtk2) { A_FaceTarget (self); self->alpha = HR_SHADOW; self->RenderStyle = STYLE_Translucent; self->flags3 |= MF3_GHOST; }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack1) { AActor *missile; angle_t an; if (!self->target) return; ACTION_PARAM_START(1); ACTION_PARAM_CLASS(spawntype, 0); if (spawntype == NULL) spawntype = PClass::FindClass("FatShot"); A_FaceTarget (self); // Change direction to ... self->angle += FATSPREAD; missile = P_SpawnMissile (self, self->target, spawntype); // [BC] If we're the server, tell clients to spawn the missile. if (( NETWORK_GetState( ) == NETSTATE_SERVER ) && ( missile )) SERVERCOMMANDS_SpawnMissile( missile ); missile = P_SpawnMissile (self, self->target, spawntype); if (missile != NULL) { missile->angle += FATSPREAD; an = missile->angle >> ANGLETOFINESHIFT; missile->velx = FixedMul (missile->Speed, finecosine[an]); missile->vely = FixedMul (missile->Speed, finesine[an]); // [BC] If we're the server, tell clients to spawn the missile. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_SpawnMissile( missile ); }
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; }
DEFINE_ACTION_FUNCTION(AActor, A_SkelWhoosh) { if (!self->target) return; A_FaceTarget (self); S_Sound (self, CHAN_WEAPON, "skeleton/swing", 1, ATTN_NORM); }
DEFINE_ACTION_FUNCTION(AActor, A_CPosAttack) { int angle; int bangle; int damage; int slope; if (!self->target) return; // [RH] Andy Baker's stealth monsters if (self->flags & MF_STEALTH) { self->visdir = 1; } S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); A_FaceTarget (self); bangle = self->angle; slope = P_AimLineAttack (self, bangle, MISSILERANGE); angle = bangle + (pr_cposattack.Random2() << 20); damage = ((pr_cposattack()%5)+1)*3; P_LineAttack (self, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff); }
// // A_PosAttack // DEFINE_ACTION_FUNCTION(AActor, A_PosAttack) { int angle; int damage; int slope; // [BC] Server takes care of the rest of this. if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) || ( CLIENTDEMO_IsPlaying( ))) { S_Sound( self, CHAN_WEAPON, "grunt/attack", 1, ATTN_NORM ); return; } if (!self->target) return; A_FaceTarget (self); angle = self->angle; slope = P_AimLineAttack (self, angle, MISSILERANGE); S_Sound (self, CHAN_WEAPON, "grunt/attack", 1, ATTN_NORM); angle += pr_posattack.Random2() << 20; damage = ((pr_posattack()%5)+1)*3; P_LineAttack (self, angle, MISSILERANGE, slope, damage, NAME_None, NAME_BulletPuff); }
DEFINE_ACTION_FUNCTION(AActor, A_InquisitorDecide) { // [BC] This is handled server-side. if ( NETWORK_InClientMode() ) { return; } if (self->target == NULL) return; A_FaceTarget (self); if (!InquisitorCheckDistance (self)) { // [BC] Set the thing's state. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_SetThingFrame( self, self->FindState("Grenade") ); self->SetState (self->FindState("Grenade")); } if (self->target->z != self->z) { if (self->z + self->height + 54*FRACUNIT < self->ceilingz) { // [BC] Set the thing's state. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_SetThingFrame( self, self->FindState("Jump") ); self->SetState (self->FindState("Jump")); } } }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack1) { AActor *missile; angle_t an; if (!self->target) return; ACTION_PARAM_START(1); ACTION_PARAM_CLASS(spawntype, 0); if (spawntype == NULL) spawntype = PClass::FindClass("FatShot"); A_FaceTarget (self); // Change direction to ... self->angle += FATSPREAD; P_SpawnMissile (self, self->target, spawntype); missile = P_SpawnMissile (self, self->target, spawntype); if (missile != NULL) { missile->angle += FATSPREAD; an = missile->angle >> ANGLETOFINESHIFT; missile->velx = FixedMul (missile->Speed, finecosine[an]); missile->vely = FixedMul (missile->Speed, finesine[an]); }
DEFINE_ACTION_FUNCTION(AActor, A_M_FireMissile) { // [BC] AActor *pMissile; // [BC] Don't do this in client mode. if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) || ( CLIENTDEMO_IsPlaying( ))) { return; } if (self->target == NULL) return; if (self->CheckMeleeRange ()) { // If too close, punch it MarinePunch(self, 1); } else { A_FaceTarget (self); pMissile = P_SpawnMissile (self, self->target, PClass::FindClass("Rocket")); // [BC] If we're the server, tell clients to spawn this missile. if (( pMissile ) && ( NETWORK_GetState( ) == NETSTATE_SERVER )) SERVERCOMMANDS_SpawnMissile( pMissile ); } }
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)); }
static void MarinePunch(AActor *self, int damagemul) { angle_t angle; int damage; int pitch; AActor *linetarget; 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, &linetarget); // turn to face target if (linetarget) { S_Sound (self, CHAN_WEAPON, "*fist", 1, ATTN_NORM); self->angle = self->AngleTo(linetarget); } }
void A_InquisitorJump (AActor *self) { fixed_t dist; fixed_t speed; angle_t an; if (self->target == NULL) return; S_LoopedSound (self, CHAN_ITEM, "inquisitor/jump", 1, ATTN_NORM); self->z += 64*FRACUNIT; A_FaceTarget (self); an = self->angle >> ANGLETOFINESHIFT; speed = self->Speed * 2/3; self->momx += FixedMul (speed, finecosine[an]); self->momy += FixedMul (speed, finesine[an]); dist = P_AproxDistance (self->target->x - self->x, self->target->y - self->y); dist /= speed; if (dist < 1) { dist = 1; } self->momz = (self->target->z - self->z) / dist; self->reactiontime = 60; self->flags |= MF_NOGRAVITY; }
void A_ImpMsAttack (AActor *self) { AActor *dest; angle_t an; int dist; if (!self->target || pr_impmsatk() > 64) { self->SetState (self->SeeState); return; } dest = self->target; self->flags |= MF_SKULLFLY; S_SoundID (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); A_FaceTarget (self); an = self->angle >> ANGLETOFINESHIFT; self->momx = FixedMul (12*FRACUNIT, finecosine[an]); self->momy = FixedMul (12*FRACUNIT, finesine[an]); dist = P_AproxDistance (dest->x - self->x, dest->y - self->y); dist = dist/(12*FRACUNIT); if (dist < 1) { dist = 1; } self->momz = (dest->z + (dest->height>>1) - self->z)/dist; }
void A_WizAtk2 (AActor *actor) { A_FaceTarget (actor); actor->alpha = HR_SHADOW; actor->RenderStyle = STYLE_Translucent; actor->flags3 |= MF3_GHOST; }
DEFINE_ACTION_FUNCTION(AActor, A_CPosRefire) { // keep firing unless target got out of sight A_FaceTarget (self); // [BC] Client chaingunners continue to fire until told by the server to stop. if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) || ( CLIENTDEMO_IsPlaying( ))) { return; } if (pr_cposrefire() < 40) return; if (!self->target || P_HitFriend (self) || self->target->health <= 0 || !P_CheckSight (self, self->target, SF_SEEPASTBLOCKEVERYTHING|SF_SEEPASTSHOOTABLELINES)) { // [BC] If we're the server, tell clients to update this thing's state. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_SetThingState( self, STATE_SEE ); self->SetState (self->SeeState); } }
// // A_PainAttack // Spawn a lost soul and launch it at the target // void A_PainAttack (AActor *self) { if (!self->target) return; A_FaceTarget (self); A_PainShootSkull (self, self->angle); }
// // A_SkelWhoosh // // Fist swing sound for Revenant. // void A_SkelWhoosh(actionargs_t *actionargs) { Mobj *actor = actionargs->actor; if(!actor->target) return; A_FaceTarget(actionargs); S_StartSound(actor, sfx_skeswg); }
DEFINE_ACTION_FUNCTION(AActor, A_BetaSkullAttack) { int damage; if (!self || !self->target || self->target->GetSpecies() == self->GetSpecies()) return; S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); A_FaceTarget(self); damage = (pr_oldsoul()%8+1)*self->Damage; P_DamageMobj(self->target, self, self, damage, NAME_None); }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DualPainAttack) { if (!self->target) return; const PClass *spawntype = GetSpawnType(PUSH_PARAMINFO); A_FaceTarget (self); A_PainShootSkull (self, self->angle + ANG45, spawntype); A_PainShootSkull (self, self->angle - ANG45, spawntype); }
DEFINE_ACTION_FUNCTION(AActor, A_CyberAttack) { PARAM_ACTION_PROLOGUE; if (!self->target) return 0; A_FaceTarget (self); P_SpawnMissile (self, self->target, PClass::FindActor("Rocket")); return 0; }
DEFINE_ACTION_FUNCTION(AActor, A_EntityDeath) { AActor *second; fixed_t secondRadius = GetDefaultByName("EntitySecond")->radius * 2; angle_t an; AActor *spot = self->tracer; if (spot == NULL) spot = self; fixed_t SpawnX = spot->x; fixed_t SpawnY = spot->y; fixed_t SpawnZ = spot->z + self->tracer? 70*FRACUNIT : 0; an = self->angle >> ANGLETOFINESHIFT; second = Spawn("EntitySecond", SpawnX + FixedMul (secondRadius, finecosine[an]), SpawnY + FixedMul (secondRadius, finesine[an]), SpawnZ, ALLOW_REPLACE); second->CopyFriendliness(self, true); //second->target = self->target; A_FaceTarget (second); an = second->angle >> ANGLETOFINESHIFT; second->velx += FixedMul (finecosine[an], 320000); second->vely += FixedMul (finesine[an], 320000); an = (self->angle + ANGLE_90) >> ANGLETOFINESHIFT; second = Spawn("EntitySecond", SpawnX + FixedMul (secondRadius, finecosine[an]), SpawnY + FixedMul (secondRadius, finesine[an]), SpawnZ, ALLOW_REPLACE); second->CopyFriendliness(self, true); //second->target = self->target; second->velx = FixedMul (secondRadius, finecosine[an]) << 2; second->vely = FixedMul (secondRadius, finesine[an]) << 2; A_FaceTarget (second); an = (self->angle - ANGLE_90) >> ANGLETOFINESHIFT; second = Spawn("EntitySecond", SpawnX + FixedMul (secondRadius, finecosine[an]), SpawnY + FixedMul (secondRadius, finesine[an]), SpawnZ, ALLOW_REPLACE); second->CopyFriendliness(self, true); //second->target = self->target; second->velx = FixedMul (secondRadius, finecosine[an]) << 2; second->vely = FixedMul (secondRadius, finesine[an]) << 2; A_FaceTarget (second); }