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_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 ); } } }
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(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 ); }
DEFINE_ACTION_FUNCTION(AActor, A_InquisitorAttack) { AActor *proj; // [BC] This is handled server-side. if ( NETWORK_InClientMode() ) { return; } if (self->target == NULL) return; A_FaceTarget (self); self->z += 32*FRACUNIT; self->angle -= ANGLE_45/32; proj = P_SpawnMissileZAimed (self, self->z, self->target, PClass::FindClass("InquisitorShot")); if (proj != NULL) { proj->velz += 9*FRACUNIT; // [BC] Tell clients to spawn the missile. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_SpawnMissile( proj ); } self->angle += ANGLE_45/16; proj = P_SpawnMissileZAimed (self, self->z, self->target, PClass::FindClass("InquisitorShot")); if (proj != NULL) { proj->velz += 16*FRACUNIT; // [BC] Tell clients to spawn the missile. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_SpawnMissile( proj ); } self->z -= 32*FRACUNIT; }
DEFINE_ACTION_FUNCTION(AActor, A_M_FireBFG) { AActor *pMissile; // [BC] Don't do this in client mode. if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) || ( CLIENTDEMO_IsPlaying( ))) { return; } if (self->target == NULL) return; A_FaceTarget (self); pMissile = P_SpawnMissile (self, self->target, PClass::FindClass("BFGBall")); self->special1 = level.maptime + 30; self->PainChance = MARINE_PAIN_CHANCE; // [BC] If we're the server, tell clients to spawn this missile. if (( pMissile ) && ( NETWORK_GetState( ) == NETSTATE_SERVER )) SERVERCOMMANDS_SpawnMissile( pMissile ); }
DEFINE_ACTION_FUNCTION(AActor, A_BishopAttack2) { AActor *mo; // [BB] This is server-side. if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) || ( CLIENTDEMO_IsPlaying( ))) { return; } if (!self->target || !self->special1) { self->special1 = 0; self->SetState (self->SeeState); // [BB] If we're the server, tell the clients of the state change. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_SetThingState( self, STATE_SEE ); return; } mo = P_SpawnMissile (self, self->target, PClass::FindClass("BishopFX")); if (mo != NULL) { mo->tracer = self->target; mo->special2 = 16; // High word == x/y, Low word == z // [BB] If we're the server, tell the clients to spawn this missile. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) { SERVERCOMMANDS_SpawnMissile( mo ); SERVERCOMMANDS_SetThingSpecial2( mo ); } } self->special1--; }
DEFINE_ACTION_FUNCTION(AActor, A_Spectre3Attack) { if (self->target == NULL) return; AActor *foo = Spawn("SpectralLightningV2", self->x, self->y, self->z + 32*FRACUNIT, ALLOW_REPLACE); foo->momz = -12*FRACUNIT; foo->target = self; foo->health = -2; foo->tracer = self->target; // [CW] Tell clients to spawn the actor. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_SpawnMissile( foo ); self->angle -= ANGLE_180 / 20 * 10; for (int i = 0; i < 20; ++i) { self->angle += ANGLE_180 / 20; P_SpawnSubMissile (self, PClass::FindClass("SpectralLightningBall2"), self); } self->angle -= ANGLE_180 / 20 * 10; }
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 ); } } }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BrainSpit) { DSpotState *state = DSpotState::GetSpotState(); AActor *targ; AActor *spit; bool isdefault = false; // [BC] Brain spitting is server-side. if ( NETWORK_InClientMode() ) { return; } ACTION_PARAM_START(1); ACTION_PARAM_CLASS(spawntype, 0); // shoot a cube at current target targ = state->GetNextInList(PClass::FindClass("BossTarget"), G_SkillProperty(SKILLP_EasyBossBrain)); if (targ != NULL) { if (spawntype == NULL) { spawntype = PClass::FindClass("SpawnShot"); isdefault = true; } // spawn brain missile spit = P_SpawnMissile (self, targ, spawntype); if (spit != NULL) { // Boss cubes should move freely to their destination so it's // probably best to disable all collision detection for them. if (spit->flags & MF_NOCLIP) spit->flags5 |= MF5_NOINTERACTION; spit->target = targ; spit->master = self; // [RH] Do this correctly for any trajectory. Doom would divide by 0 // if the target had the same y coordinate as the spitter. if ((spit->velx | spit->vely) == 0) { spit->special2 = 0; } else if (abs(spit->vely) > abs(spit->velx)) { spit->special2 = (targ->y - self->y) / spit->vely; } else { spit->special2 = (targ->x - self->x) / spit->velx; } // [GZ] Calculates when the projectile will have reached destination spit->special2 += level.maptime; spit->flags6 |= MF6_BOSSCUBE; // [BC] If we're the server, tell clients to spawn the actor. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_SpawnMissile( spit ); } if (!isdefault) { S_Sound(self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NONE); // [BC] If we're the server, tell clients create the sound. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_SoundPoint( self->x, self->y, self->z, CHAN_WEAPON, self->AttackSound, 1, ATTN_NONE ); } else { // compatibility fallback S_Sound (self, CHAN_WEAPON, "brain/spit", 1, ATTN_NONE); // [BC] If we're the server, tell clients create the sound. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_SoundPoint( self->x, self->y, self->z, CHAN_WEAPON, "brain/spit", 1, ATTN_NONE ); } } }