public Beam(Vector2 srcCenter, int Thickness, Ship Owner, GameplayObject target) { this.Target = target; this.owner = Owner; Vector2 TargetPosition = Vector2.Normalize(target.Center); if (Owner.InFrustum) { this.DamageToggleSound = AudioManager.GetCue("sd_shield_static_1"); } if (this.owner.isInDeepSpace || this.owner.GetSystem() == null) { UniverseScreen.DeepSpaceManager.BeamList.Add(this); } else { this.system = this.owner.GetSystem(); this.system.spatialManager.BeamList.Add(this); } this.Source = srcCenter; this.BeamOffsetAngle = Owner.Rotation - MathHelper.ToRadians(HelperFunctions.findAngleToTarget(srcCenter, TargetPosition)); this.Destination = HelperFunctions.findPointFromAngleAndDistanceUsingRadians(srcCenter, Owner.Rotation + this.BeamOffsetAngle, this.range); this.ActualHitDestination = this.Destination; this.Vertices = new VertexPositionNormalTexture[4]; this.Indexes = new int[6]; this.BeamZ = RandomMath2.RandomBetween(-1f, 1f); Vector3[] points = HelperFunctions.BeamPoints(srcCenter, TargetPosition, (float)Thickness, new Vector2[4], 0, this.BeamZ); this.UpperLeft = points[0]; this.UpperRight = points[1]; this.LowerLeft = points[2]; this.LowerRight = points[3]; this.FillVertices(); }
public SpaceJunk(Vector2 Position, GameplayObject source) { this.Position.X = RandomMath2.RandomBetween(Position.X - 20f, Position.X + 20f); this.Position.Y = RandomMath2.RandomBetween(Position.Y - 20f, Position.Y + 20f); this.Position.Z = RandomMath2.RandomBetween(-20f, 20f); this.initialVel = source.Velocity; }
public void SetTarget(GameplayObject target) { if (target == null) return; this.TargetSet = true; this.Target = target; }
public void ChooseTarget() { this.Target = null; //List<GameplayObject> nearby = UniverseScreen.ShipSpatialManager.GetNearby(this.Owner); //List<GameplayObject> nearby = this.Owner.owner.GetAI().FriendliesNearby; List<Ship> Potentials = new List<Ship>(); //foreach (GameplayObject go in nearby) foreach (Ship go in this.Owner.owner.GetAI().FriendliesNearby) { bool isShip = go is Ship; Ship goShip = go as Ship; if (!isShip || goShip.loyalty != this.Owner.loyalty || goShip.Health >= goShip.HealthMax) { continue; } Potentials.Add(goShip); } IOrderedEnumerable<Ship> sortedList = from ship in Potentials orderby ship.Health / ship.HealthMax select ship; for (int i = 0; i < sortedList.Count<Ship>(); i++) { if (Vector2.Distance(sortedList.ElementAt<Ship>(i).Center, this.Owner.Position) < 20000f && sortedList.ElementAt<Ship>(i).Active && sortedList.ElementAt<Ship>(i).Health > 0f) { this.Target = sortedList.ElementAt<Ship>(i); return; } } }
public override void Die(GameplayObject source, bool cleanupOnly) { DebugInfoScreen.ModulesDied = DebugInfoScreen.ModulesDied + 1; if (!this.isDummy) { foreach (ShipModule link in this.LinkedModulesList) { if (!link.Active) { continue; } link.Die(source, true); } } if (this.shield_power_max > 0f) { base.Health = 0f; } this.SetNewExternals(); base.Health = 0f; Vector3 center = new Vector3(this.Center.X, this.Center.Y, -100f); if (this.Active) { ((this.Parent.GetSystem() != null ? this.Parent.GetSystem().RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(5f, 15f); if (!this.Parent.dying && this.Parent.InFrustum) { for (int i = 0; i < 30; i++) { ShipModule.universeScreen.explosionParticles.AddParticleThreadA(center, Vector3.Zero); } } else if (this.Parent.InFrustum) { for (int i = 0; i < 30; i++) { ShipModule.universeScreen.explosionParticles.AddParticleThreadA(new Vector3(this.Parent.Center, ((this.Parent.GetSystem() != null ? this.Parent.GetSystem().RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-25f, 25f)), Vector3.Zero); } } } base.Die(source, cleanupOnly); if (!cleanupOnly) { if (this.Parent.Active && this.Parent.InFrustum && ShipModule.universeScreen.viewState == UniverseScreen.UnivScreenState.ShipView) { GameplayObject.audioListener.Position = ShipModule.universeScreen.camPos; Cue dieCue = AudioManager.GetCue("sd_explosion_module_small"); dieCue.Apply3D(GameplayObject.audioListener, this.Parent.emitter); dieCue.Play(); } if (this.explodes) { if (this.Parent.GetSystem() == null) { UniverseScreen.DeepSpaceManager.ExplodeAtModule(this.Parent.LastDamagedBy, this, (float)(2500 * this.XSIZE * this.YSIZE), (float)(this.XSIZE * this.YSIZE * 64)); } else { this.Parent.GetSystem().spatialManager.ExplodeAtModule(this.Parent.LastDamagedBy, this, (float)(2500 * this.XSIZE * this.YSIZE), (float)(this.XSIZE * this.YSIZE * 64)); } } if (this.PowerFlowMax > 0 || this.PowerRadius > 0) { this.Parent.NeedRecalculate = true; } } if (((this.Parent.GetSystem() != null ? this.Parent.GetSystem().RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(0f, 100f) < 10f) { List<SpaceJunk> junk = SpaceJunk.MakeJunk(1, this.Center, this.Parent.GetSystem()); lock (GlobalStats.ObjectManagerLocker) { foreach (SpaceJunk j in junk) { j.wasAddedToScene = true; ShipModule.universeScreen.ScreenManager.inter.ObjectManager.Submit(j.JunkSO); UniverseScreen.JunkList.Add(j); } } } //this.SetNewExternals(); }
public override bool Touch(GameplayObject target) { if (this.Miss) { return false; } if (target != null) { if (target == this.owner && !this.weapon.HitsFriendlies) { return false; } Projectile projectile = target as Projectile; if (projectile != null) { if (this.owner != null && projectile.loyalty == this.owner.loyalty) { return false; } if (projectile.WeaponType == "Missile") { float ran = ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(0f, 1f); if (projectile.loyalty != null && ran >= projectile.loyalty.data.MissileDodgeChance) { projectile.DamageMissile(this, this.damageAmount); return true; } } else if (this.weapon.Tag_Intercept || projectile.weapon.Tag_Intercept) { this.DieNextFrame = true; projectile.DieNextFrame = true; } return false; } if (target is Asteroid) { if (!this.explodes) { target.Damage(this, this.damageAmount); } this.Die(null, false); return true; } if (target is ShipModule) { ShipModule module = target as ShipModule; if (module != null && module.GetParent().loyalty == this.loyalty && !this.weapon.HitsFriendlies || module == null) return false; if (this.weapon.TruePD) { this.DieNextFrame = true; return true; } if (module.GetParent().Role == "fighter" && module.GetParent().loyalty.data.Traits.DodgeMod > 0f) { if (((module.GetParent().GetSystem() != null ? module.GetParent().GetSystem().RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(0f, 100f) < module.GetParent().loyalty.data.Traits.DodgeMod * 100f) { this.Miss = true; } } if (this.Miss) { return false; } // Moving this to the Damage function - doesn't seem to be working? Also seems nonsensical. /* if (module.ModuleType == ShipModuleType.Armor || (module.ModuleType == ShipModuleType.Dummy && module.ParentOfDummy.ModuleType == ShipModuleType.Armor)) { this.damageRadius -= module.GetParent().loyalty.data.ExplosiveRadiusReduction * this.damageRadius; this.damageAmount -= module.GetParent().loyalty.data.ExplosiveRadiusReduction * this.damageAmount; this.damageAmount *= this.weapon.EffectVsArmor; this.damageAmount *= this.damageAmount + this.ArmorDamageBonus; } if (module.ModuleType == ShipModuleType.Shield && module.shield_power > 0) { this.damageAmount *= this.weapon.EffectVSShields; this.damageAmount *= this.damageAmount + this.ShieldDamageBonus; //projectiles penetrate weak shields if (this.damageAmount > module.shield_power) { float remainder = 0; module.Damage(this, this.damageAmount, ref remainder); if (remainder > 0) { this.damageAmount = remainder; return false; } else { this.damageAmount = 0; this.explodes = false; this.DieNextFrame = true; return base.Touch(target); } } } */ //Non exploding projectiles should go through multiple modules if it has enough damage if (!this.explodes && module.Active) { float remainder; //Doc: If module has resistance to Armour Piercing effects, deduct that from the projectile's AP before starting AP and damage checks if (module.APResist > 0) { this.ArmorPiercing -= (byte)module.APResist; if (this.ArmorPiercing < 0) this.ArmorPiercing = 0; } if (this.ArmorPiercing == 0 || !(module.ModuleType == ShipModuleType.Armor || (module.ModuleType == ShipModuleType.Dummy && module.ParentOfDummy.ModuleType == ShipModuleType.Armor))) { remainder = 0; module.Damage(this, this.damageAmount, ref remainder); } else { this.ArmorPiercing--; remainder = this.damageAmount; } if (remainder > 0) { this.damageAmount = remainder; bool SlotFound; int depth = 10; Vector2 UnitVector = this.velocity; while (this.damageAmount > 0) { UnitVector.Normalize(); UnitVector *= depth; SlotFound = false; foreach (ModuleSlot slot in module.GetParent().ModuleSlotList) { if (Vector2.Distance(this.Center + UnitVector, slot.module.Center) < 8f) { SlotFound = true; if (slot.module.Active) { if (this.ArmorPiercing > 0 && (slot.module.ModuleType == ShipModuleType.Armor || (slot.module.ModuleType == ShipModuleType.Dummy && slot.module.ParentOfDummy.ModuleType == ShipModuleType.Armor))) break; else { remainder = 0; slot.module.Damage(this, this.damageAmount, ref remainder); if (remainder > 0) this.damageAmount = remainder; else this.damageAmount = 0f; } } break; } } //Slot found means it is still in the ship if (SlotFound) { depth += 8; this.ArmorPiercing--; } else break; } } } base.Health = 0f; } if (this.WeaponEffectType == "Plasma") { Vector3 center = new Vector3(this.Center.X, this.Center.Y, -100f); Vector2 forward = new Vector2((float)Math.Sin((double)base.Rotation), -(float)Math.Cos((double)base.Rotation)); Vector2 right = new Vector2(-forward.Y, forward.X); right = Vector2.Normalize(right); for (int i = 0; i < 20; i++) { Vector3 random = new Vector3(right.X * ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-250f, 250f), right.Y * ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-250f, 250f), ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-250f, 250f)); Projectile.universeScreen.flameParticles.AddParticleThreadA(center, random); random = new Vector3(-forward.X + ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-150f, 150f), -forward.Y + ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-150f, 150f), ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-150f, 150f)); Projectile.universeScreen.flameParticles.AddParticleThreadA(center, random); } } if (this.WeaponEffectType == "MuzzleBlast") // currently unused { Vector3 center = new Vector3(this.Center.X, this.Center.Y, -100f); Vector2 forward = new Vector2((float)Math.Sin((double)base.Rotation), -(float)Math.Cos((double)base.Rotation)); Vector2 right = new Vector2(-forward.Y, forward.X); right = Vector2.Normalize(right); for (int i = 0; i < 20; i++) { Vector3 random = new Vector3(right.X * ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-500f, 500f), right.Y * ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-500f, 500f), ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-250f, 250f)); Projectile.universeScreen.fireTrailParticles.AddParticleThreadA(center, random); random = new Vector3(-forward.X + ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-500f, 500f), -forward.Y + ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-500f, 500f), ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-150f, 150f)); Projectile.universeScreen.fireTrailParticles.AddParticleThreadA(center, random); } } else if (this.WeaponType == "Ballistic Cannon") { ShipModule SMtarget = target as ShipModule; if (SMtarget != null && SMtarget.ModuleType != ShipModuleType.Shield) { Cue impact = AudioManager.GetCue("sd_impact_bullet_small_01"); impact.Apply3D(Projectile.universeScreen.listener, this.emitter); impact.Play(); } } } this.DieNextFrame = true; return base.Touch(target); }
public override void Die(GameplayObject source, bool cleanupOnly) { DebugInfoScreen.ProjDied = DebugInfoScreen.ProjDied + 1; if (this.Active) { Vector3 vector3 = new Vector3(this.Center.X, this.Center.Y, -100f); Vector3 vector31 = new Vector3(this.velocity.X, base.Velocity.Y, 0f); if (this.light != null) { lock (GlobalStats.ObjectManagerLocker) { Projectile.universeScreen.ScreenManager.inter.LightManager.Remove(this.light); } } if (!string.IsNullOrEmpty(this.InFlightCue) && this.inFlight != null) { this.inFlight.Stop(AudioStopOptions.Immediate); } if (this.explodes) { if (this.weapon.OrdinanceRequiredToFire > 0f && this.Owner != null) { this.damageAmount += this.Owner.loyalty.data.OrdnanceEffectivenessBonus * this.damageAmount; this.damageRadius += this.Owner.loyalty.data.OrdnanceEffectivenessBonus * this.damageRadius; } if (this.WeaponType == "Photon") { if (!string.IsNullOrEmpty(this.dieCueName)) { this.dieCue = AudioManager.GetCue(this.dieCueName); } if (this.dieCue != null) { this.dieCue.Apply3D(GameplayObject.audioListener, this.emitter); this.dieCue.Play(); } if (!cleanupOnly && Projectile.universeScreen.viewState <= UniverseScreen.UnivScreenState.SystemView) { ExplosionManager.AddProjectileExplosion(new Vector3(base.Position, -50f), this.damageRadius * 4.5f, 2.5f, 0.2f, this.weapon.ExpColor); Projectile.universeScreen.flash.AddParticleThreadB(new Vector3(base.Position, -50f), Vector3.Zero); } if (this.system == null) { UniverseScreen.DeepSpaceManager.ProjectileExplode(this, this.damageAmount, this.damageRadius); } else { this.system.spatialManager.ProjectileExplode(this, this.damageAmount, this.damageRadius); } } else if (!string.IsNullOrEmpty(this.dieCueName)) { if (Projectile.universeScreen.viewState <= UniverseScreen.UnivScreenState.SystemView) { this.dieCue = AudioManager.GetCue(this.dieCueName); if (this.dieCue != null) { this.dieCue.Apply3D(GameplayObject.audioListener, this.emitter); this.dieCue.Play(); } } if (!cleanupOnly && Projectile.universeScreen.viewState <= UniverseScreen.UnivScreenState.SystemView) { ExplosionManager.AddExplosion(new Vector3(base.Position, -50f), this.damageRadius * this.explosionradiusmod, 2.5f, 0.2f); if (this.flashExplode) { Projectile.universeScreen.flash.AddParticleThreadB(new Vector3(base.Position, -50f), Vector3.Zero); } } if (this.system == null) { UniverseScreen.DeepSpaceManager.ProjectileExplode(this, this.damageAmount, this.damageRadius); } else { this.system.spatialManager.ProjectileExplode(this, this.damageAmount, this.damageRadius); } } else if (this.system == null) { UniverseScreen.DeepSpaceManager.ProjectileExplode(this, this.damageAmount, this.damageRadius); } else { this.system.spatialManager.ProjectileExplode(this, this.damageAmount, this.damageRadius); } } else if (this.weapon.FakeExplode && Projectile.universeScreen.viewState <= UniverseScreen.UnivScreenState.SystemView) { ExplosionManager.AddExplosion(new Vector3(base.Position, -50f), this.damageRadius * this.explosionradiusmod, 2.5f, 0.2f); if (this.flashExplode) { Projectile.universeScreen.flash.AddParticleThreadB(new Vector3(base.Position, -50f), Vector3.Zero); } } } if (this.ProjSO != null && this.Active) { lock (GlobalStats.ObjectManagerLocker) { Projectile.universeScreen.ScreenManager.inter.ObjectManager.Remove(this.ProjSO); } this.ProjSO.Clear(); } if (this.droneAI != null) { foreach (Beam beam in this.droneAI.Beams) { beam.Die(this, true); } this.droneAI.Beams.Clear(); } if (this.muzzleFlashAdded) { lock (GlobalStats.ObjectManagerLocker) { Projectile.universeScreen.ScreenManager.inter.LightManager.Remove(this.MuzzleFlash); } } if (this.system == null) { UniverseScreen.DeepSpaceManager.CollidableProjectiles.QueuePendingRemoval(this); } else { this.system.spatialManager.CollidableProjectiles.QueuePendingRemoval(this); } base.Die(source, cleanupOnly); }
protected virtual void CreateProjectiles(Vector2 direction, GameplayObject target, bool playSound) { if (target != null && (target is ShipModule) && (target as ShipModule).GetParent().Role == "fighter" && this.AltFireMode && this.AltFireTriggerFighter && this.SecondaryFire != null) { Weapon AltFire = ResourceManager.GetWeapon(this.SecondaryFire); Projectile projectile; if (this.owner.Projectiles.pendingRemovals.TryPop(out projectile)) { projectile.ProjectileRecreate(this.owner, direction, this.moduleAttachedTo); projectile.range = AltFire.Range; projectile.weapon = this; projectile.explodes = AltFire.explodes; projectile.damageAmount = AltFire.DamageAmount; projectile.damageRadius = AltFire.DamageRadius; projectile.explosionradiusmod = AltFire.ExplosionRadiusVisual; projectile.Health = AltFire.HitPoints; projectile.speed = AltFire.ProjectileSpeed; projectile.WeaponEffectType = AltFire.WeaponEffectType; projectile.WeaponType = AltFire.WeaponType; projectile.RotationRadsPerSecond = AltFire.RotationRadsPerSecond; projectile.ArmorPiercing = (byte)AltFire.ArmourPen; } else projectile = new Projectile(this.owner, direction, this.moduleAttachedTo) { range = AltFire.Range, weapon = this, explodes = AltFire.explodes, damageAmount = AltFire.DamageAmount, damageRadius = AltFire.DamageRadius, explosionradiusmod = AltFire.ExplosionRadiusVisual, Health = AltFire.HitPoints, speed = AltFire.ProjectileSpeed, WeaponEffectType = AltFire.WeaponEffectType, WeaponType = AltFire.WeaponType, RotationRadsPerSecond = AltFire.RotationRadsPerSecond, ArmorPiercing = (byte)AltFire.ArmourPen, }; //damage increase by level if (this.owner.Level > 0) { projectile.damageAmount += projectile.damageAmount * (float)this.owner.Level * 0.05f; } if (AltFire.RangeVariance) { projectile.range *= RandomMath.RandomBetween(0.9f, 1.1f); } //Hull bonus damage increase if (GlobalStats.ActiveModInfo != null && GlobalStats.ActiveModInfo.useHullBonuses) { HullBonus mod; if (ResourceManager.HullBonuses.TryGetValue(this.owner.shipData.Hull, out mod)) projectile.damageAmount += projectile.damageAmount * mod.DamageBonus; } projectile.LoadContent(AltFire.ProjectileTexturePath, AltFire.ModelPath); AltFire.ModifyProjectile(projectile); if (AltFire.Tag_Guided) projectile.InitializeMissile(projectile.speed, direction, target); else projectile.Initialize(projectile.speed, direction, this.moduleAttachedTo.Center); projectile.Radius = this.ProjectileRadius; if (AltFire.Animated == 1) { string remainder = 0.ToString("00000.##"); projectile.texturePath = string.Concat(AltFire.AnimationPath, remainder); } //if(HelperFunctions.GetRandomIndex((int)(Ship.universeScreen.Lag *100)) <2) if (Weapon.universeScreen.viewState == UniverseScreen.UnivScreenState.ShipView && this.owner.InFrustum && playSound) { projectile.DieSound = true; if (!string.IsNullOrEmpty(this.ToggleSoundName) && (this.ToggleCue == null || this.ToggleCue != null && !this.ToggleCue.IsPlaying)) { this.ToggleSoundOn = true; this.ToggleCue = AudioManager.GetCue(AltFire.ToggleSoundName); this.ToggleCue.Apply3D(Weapon.audioListener, this.owner.emitter); this.ToggleCue.Play(); if (AltFire.fireCue != null) { //Added by McShooterz: Use sounds from new sound dictionary SoundEffect soundeffect = null; if (ResourceManager.SoundEffectDict.TryGetValue(AltFire.fireCueName,out soundeffect)) { AudioManager.PlaySoundEffect(soundeffect, Weapon.audioListener, this.owner.emitter, 0.5f); } else { this.fireCue = AudioManager.GetCue(this.fireCueName); if (!this.owner.isPlayerShip()) { this.fireCue.Apply3D(Weapon.audioListener, this.owner.emitter); } this.lastFireSound = 0f; if (this.fireCue != null) { this.fireCue.Play(); } } } } if (!string.IsNullOrEmpty(ResourceManager.WeaponsDict[AltFire.UID].dieCue)) { projectile.dieCueName = ResourceManager.WeaponsDict[AltFire.UID].dieCue; } if (!string.IsNullOrEmpty(this.InFlightCue)) { projectile.InFlightCue = AltFire.InFlightCue; } if (this.ToggleCue == null && this.owner.ProjectilesFired.Count < 30) { this.lastFireSound = 0f; this.owner.ProjectilesFired.Add(new ProjectileTracker()); //Added by McShooterz: Use sounds from new sound dictionary if (ResourceManager.SoundEffectDict.ContainsKey(AltFire.fireCueName)) { AudioManager.PlaySoundEffect(ResourceManager.SoundEffectDict[fireCueName], Weapon.audioListener, this.owner.emitter, 0.5f); } else { this.fireCue = AudioManager.GetCue(this.fireCueName); if (!this.owner.isPlayerShip()) { this.fireCue.Apply3D(Weapon.audioListener, this.owner.emitter); } if (this.fireCue != null) { this.fireCue.Play(); } } } } projectile.isSecondary = true; this.owner.Projectiles.Add(projectile); projectile = null; } else { Projectile projectile; if (this.owner.Projectiles.pendingRemovals.TryPop(out projectile)) { projectile.ProjectileRecreate(this.owner, direction, this.moduleAttachedTo); projectile.range = this.Range; projectile.weapon = this; projectile.explodes = this.explodes; projectile.damageAmount = this.DamageAmount; projectile.damageRadius = this.DamageRadius; projectile.explosionradiusmod = this.ExplosionRadiusVisual; projectile.Health = this.HitPoints; projectile.speed = this.ProjectileSpeed; projectile.WeaponEffectType = this.WeaponEffectType; projectile.WeaponType = this.WeaponType; projectile.RotationRadsPerSecond = this.RotationRadsPerSecond; projectile.ArmorPiercing = (byte)this.ArmourPen; } projectile = new Projectile(this.owner, direction, this.moduleAttachedTo) { range = this.Range, weapon = this, explodes = this.explodes, damageAmount = this.DamageAmount, damageRadius = this.DamageRadius, explosionradiusmod = this.ExplosionRadiusVisual, Health = this.HitPoints, speed = this.ProjectileSpeed, WeaponEffectType = this.WeaponEffectType, WeaponType = this.WeaponType, RotationRadsPerSecond = this.RotationRadsPerSecond, ArmorPiercing = (byte)this.ArmourPen, }; //damage increase by level if (this.owner.Level > 0) { projectile.damageAmount += projectile.damageAmount * (float)this.owner.Level * 0.05f; } if (this.RangeVariance) { projectile.range *= RandomMath.RandomBetween(0.9f, 1.1f); } //Hull bonus damage increase if (GlobalStats.ActiveModInfo != null && GlobalStats.ActiveModInfo.useHullBonuses) { HullBonus mod; if (ResourceManager.HullBonuses.TryGetValue(this.owner.shipData.Hull, out mod)) projectile.damageAmount += projectile.damageAmount * mod.DamageBonus; } projectile.LoadContent(this.ProjectileTexturePath, this.ModelPath); this.ModifyProjectile(projectile); if (this.Tag_Guided) projectile.InitializeMissile(projectile.speed, direction, target); else projectile.Initialize(projectile.speed, direction, this.moduleAttachedTo.Center); projectile.Radius = this.ProjectileRadius; if (this.Animated == 1) { string remainder = 0.ToString("00000.##"); projectile.texturePath = string.Concat(this.AnimationPath, remainder); } if (Weapon.universeScreen.viewState == UniverseScreen.UnivScreenState.ShipView && this.owner.InFrustum && playSound) { projectile.DieSound = true; if (!string.IsNullOrEmpty(this.ToggleSoundName) && (this.ToggleCue == null || this.ToggleCue != null && !this.ToggleCue.IsPlaying)) { this.ToggleSoundOn = true; this.ToggleCue = AudioManager.GetCue(this.ToggleSoundName); this.ToggleCue.Apply3D(Weapon.audioListener, this.owner.emitter); this.ToggleCue.Play(); if (this.fireCue != null) { //Added by McShooterz: Use sounds from new sound dictionary if (ResourceManager.SoundEffectDict.ContainsKey(this.fireCueName)) { AudioManager.PlaySoundEffect(ResourceManager.SoundEffectDict[fireCueName], Weapon.audioListener, this.owner.emitter, 0.5f); } else { this.fireCue = AudioManager.GetCue(this.fireCueName); if (!this.owner.isPlayerShip()) { this.fireCue.Apply3D(Weapon.audioListener, this.owner.emitter); } this.lastFireSound = 0f; if (this.fireCue != null) { this.fireCue.Play(); } } } } if (!string.IsNullOrEmpty(ResourceManager.WeaponsDict[this.UID].dieCue)) { projectile.dieCueName = ResourceManager.WeaponsDict[this.UID].dieCue; } if (!string.IsNullOrEmpty(this.InFlightCue)) { projectile.InFlightCue = this.InFlightCue; } if (this.ToggleCue == null && this.owner.ProjectilesFired.Count < 30) { this.lastFireSound = 0f; this.owner.ProjectilesFired.Add(new ProjectileTracker()); //Added by McShooterz: Use sounds from new sound dictionary if (ResourceManager.SoundEffectDict.ContainsKey(this.fireCueName)) { AudioManager.PlaySoundEffect(ResourceManager.SoundEffectDict[fireCueName], Weapon.audioListener, this.owner.emitter, 0.5f); } else { this.fireCue = AudioManager.GetCue(this.fireCueName); if (!this.owner.isPlayerShip()) { this.fireCue.Apply3D(Weapon.audioListener, this.owner.emitter); } if (this.fireCue != null) { this.fireCue.Play(); } } } } this.owner.Projectiles.Add(projectile); projectile = null; } }
public virtual void Update(float elapsedTime) { this.lastFireSound += elapsedTime; if (this.timeToNextFire > 0f) { this.timeToNextFire = MathHelper.Max(this.timeToNextFire - elapsedTime, 0f); } foreach (Weapon.Salvo salvo in this.SalvoList) { salvo.Timing -= elapsedTime; if (salvo.Timing > 0f) { continue; } //this.FireSalvo(salvo.Direction, this.SalvoTarget); if (this.SalvoTarget !=null && this.owner.CheckIfInsideFireArc(this,SalvoTarget)) { if (this.Tag_Guided) this.FireSalvo(salvo.Direction, SalvoTarget); else this.GetOwner().GetAI().CalculateAndFire(this, SalvoTarget, true); } else if (this.SalvoTarget != null) this.FireSalvo(salvo.Direction, null); this.SalvoList.QueuePendingRemoval(salvo); } this.SalvoList.ApplyPendingRemovals(); if (this.SalvoList.Count == 0) this.SalvoTarget = null; this.Center = this.moduleAttachedTo.Center; }
public virtual void FireSalvo(Vector2 direction, GameplayObject target) { if (this.owner.engineState == Ship.MoveState.Warp ) //|| (this.owner !=null && this.owner.CheckIfInsideFireArc(this,target))) { return; } this.owner.InCombatTimer = 15f; if (this.moduleAttachedTo.Active && this.owner.PowerCurrent > this.PowerRequiredToFire && this.OrdinanceRequiredToFire <= this.owner.Ordinance) { this.owner.Ordinance -= this.OrdinanceRequiredToFire; this.owner.PowerCurrent -= this.PowerRequiredToFire; if (this.FireArc != 0) { float DegreesBetweenShots = (float)(this.FireArc / this.ProjectileCount); float angleToTarget = this.findAngleToTarget(direction); for (int i = 0; i < this.ProjectileCount; i++) { Vector2 newTarget = this.findTargetFromAngleAndDistance(this.moduleAttachedTo.Center, angleToTarget - (float)(this.FireArc / 2) + DegreesBetweenShots * (float)i, this.Range); Vector2 fireDirection = this.findVectorToTarget(this.moduleAttachedTo.Center, newTarget); fireDirection.Y = fireDirection.Y * -1f; this.CreateProjectiles(Vector2.Normalize(fireDirection), target, !this.PlaySoundOncePerSalvo); } return; } if (this.FireCone > 0) { float spread = RandomMath2.RandomBetween((float)(-this.FireCone / 2), (float)(this.FireCone / 2)); float angleToTarget = this.findAngleToTarget(direction); Vector2 newTarget = this.findTargetFromAngleAndDistance(this.moduleAttachedTo.Center, angleToTarget + spread, this.Range); Vector2 fireDirection = this.findVectorToTarget(this.moduleAttachedTo.Center, newTarget); fireDirection.Y = fireDirection.Y * -1f; this.CreateProjectiles(Vector2.Normalize(fireDirection), target, !this.PlaySoundOncePerSalvo); return; } for (int i = 0; i < this.ProjectileCount; i++) { this.CreateProjectiles(direction, target, !this.PlaySoundOncePerSalvo); } return; } }
private void FireOnTargetNonVisible(Weapon w, GameplayObject fireTarget) { if (this.Owner.Ordinance < w.OrdinanceRequiredToFire || this.Owner.PowerCurrent < w.PowerRequiredToFire) { return; } w.timeToNextFire = w.fireDelay; if (w.IsRepairDrone) { return; } if (TargetShip == null || !TargetShip.Active || TargetShip.dying || !w.TargetValid(TargetShip.Role) || TargetShip.engineState == Ship.MoveState.Warp || !this.Owner.CheckIfInsideFireArc(w, TargetShip)) return; Ship owner = this.Owner; owner.Ordinance = owner.Ordinance - w.OrdinanceRequiredToFire; Ship powerCurrent = this.Owner; powerCurrent.PowerCurrent = powerCurrent.PowerCurrent - w.PowerRequiredToFire; powerCurrent.PowerCurrent -= w.BeamPowerCostPerSecond * w.BeamDuration; this.Owner.InCombatTimer = 15f; if (fireTarget is Projectile) { fireTarget.Damage(w.GetOwner(), w.DamageAmount); return; } if (!(fireTarget is Ship)) { if (fireTarget is ShipModule) { w.timeToNextFire = w.fireDelay; IOrderedEnumerable<ModuleSlot> sortedList = from slot in (fireTarget as ShipModule).GetParent().ExternalSlots orderby Vector2.Distance(slot.module.Center, this.Owner.Center) select slot; float damage = w.DamageAmount; if (w.isBeam) { damage = damage * 90f; } if (w.SalvoCount > 0) { damage = damage * (float)w.SalvoCount; } sortedList.First<ModuleSlot>().module.Damage(this.Owner, damage); } return; } w.timeToNextFire = w.fireDelay; if ((fireTarget as Ship).ExternalSlots.Count == 0) { (fireTarget as Ship).Die(null, true); return; } float nearest = 0; ModuleSlot ClosestES = null; foreach (ModuleSlot ES in (fireTarget as Ship).ExternalSlots) { if (ES.module.ModuleType == ShipModuleType.Dummy || !ES.module.Active || ES.module.Health <= 0) continue; float temp = Vector2.Distance(ES.module.Center, w.GetOwner().Center); if (nearest == 0 || temp < nearest) { nearest = temp; ClosestES = ES; } } if (ClosestES == null) return; // List<ModuleSlot> IEnumerable<ModuleSlot> ExternalSlots = (fireTarget as Ship).ExternalSlots.Where(close => close.module.Active && close.module.quadrant == ClosestES.module.quadrant && close.module.Health > 0);//.ToList(); //.OrderByDescending(shields=> shields.Shield_Power >0);//.ToList(); if ((fireTarget as Ship).shield_power > 0f) { for (int i = 0; i < (fireTarget as Ship).GetShields().Count; i++) { if ((fireTarget as Ship).GetShields()[i].Active && (fireTarget as Ship).GetShields()[i].shield_power > 0f) { float damage = w.DamageAmount; if (w.isBeam) { damage = damage * 90f; } if (w.SalvoCount > 0) { damage = damage * (float)w.SalvoCount; } (fireTarget as Ship).GetShields()[i].Damage(this.Owner, damage); return; } } return; } //this.Owner.GetSystem() != null ? this.Owner.GetSystem().RNG : ArtificialIntelligence.universeScreen.DeepSpaceRNG)).RandomBetween(0f, 100f) <= 50f || if (ExternalSlots.ElementAt(0).module.shield_power > 0f) { for (int i = 0; i < ExternalSlots.Count(); i++) { if (ExternalSlots.ElementAt(i).module.Active && ExternalSlots.ElementAt(i).module.shield_power <= 0f) { float damage = w.DamageAmount; if (w.isBeam) { damage = damage * 90f; } if (w.SalvoCount > 0) { damage = damage * (float)w.SalvoCount; } ExternalSlots.ElementAt(i).module.Damage(this.Owner, damage); return; } } return; } for (int i = 0; i < ExternalSlots.Count(); i++) { if (ExternalSlots.ElementAt(i).module.Active && ExternalSlots.ElementAt(i).module.shield_power <= 0f) { float damage = w.DamageAmount; if (w.isBeam) { damage = damage * 90f; } if (w.SalvoCount > 0) { damage = damage * (float)w.SalvoCount; } ExternalSlots.ElementAt(i).module.Damage(this.Owner, damage); return; } } }
private Vector2 findVectorBehindTarget(GameplayObject ship, float distance) { Vector2 vector2 = new Vector2(0f, 0f); Vector2 forward = new Vector2((float)Math.Sin((double)ship.Rotation), -(float)Math.Cos((double)ship.Rotation)); forward = Vector2.Normalize(forward); return ship.Position - (forward * distance); }
private void DoCombat(float elapsedTime) { this.awaitClosest = null; this.State = AIState.Combat; this.Owner.InCombat = true; this.Owner.InCombatTimer = 15f; #region modified 07/28/15 float radius = 30000f; //Added by Ermenildo V. Castro, Jr.; 07/28/15 Vector2 senseCenter = this.Owner.Center; //Added by Ermenildo V. Castro, Jr.; 07/28/15 //If there is a target, and the target is inactive //remove inactive target from consideration if (this.Target != null && !this.Target.Active) { this.Target = null; this.Intercepting = false; if (!this.BadGuysNear) //Modified by Ermenildo V. Castro, Jr; 07/28/15: re-instated commented out conditional { this.State = this.DefaultAIState; this.OrderQueue.Clear(); this.Target = this.ScanForCombatTargets(senseCenter, radius); //Modified by Modified by Ermenildo V. Castro, Jr; 07/28/15; //this.Target = null; if (Target != null) { this.PotentialTargets.Add((Ship)Target); } } return; } //if no target available if (this.Target == null ) { this.Target = null; this.Intercepting = false; this.ScanForThreatTimer = 0; if (!this.BadGuysNear) //Modified by Ermenildo V. Castro, Jr; 07/28/15: re-instated commented out conditional { this.OrderQueue.Clear(); this.State = this.DefaultAIState; this.Target = this.ScanForCombatTargets(senseCenter, radius); //Modified by Modified by Ermenildo V. Castro, Jr; 07/28/15; //this.Target = null; if (Target != null) { this.PotentialTargets.Add((Ship)Target); } } return; } #endregion if (this.Owner.Mothership != null && this.Owner.Mothership.Active) { //if (!this.hasPriorityTarget // && !this.HasPriorityOrder&& this.Target != null // && this.Owner.Mothership.GetAI().Target == null // && !this.Owner.Mothership.GetAI().HasPriorityOrder // && !this.Owner.Mothership.GetAI().hasPriorityTarget) //{ // this.Owner.Mothership.GetAI().Target = this.Target; // this.Owner.Mothership.GetAI().State = AIState.Combat; // this.Owner.Mothership.InCombatTimer = 15f; //} if(this.Owner.Role != "troop" && (this.Owner.Health/ this.Owner.HealthMax <.5f || (this.Owner.shield_max>0 && this.Owner.shield_percent <=0.0)) || (this.Owner.OrdinanceMax > 0 && this.Owner.Ordinance / this.Owner.OrdinanceMax <= .1f) || (this.Owner.PowerCurrent <=1f && this.Owner.PowerDraw / this.Owner.PowerFlowMax <=.1f) ) this.OrderReturnToHangar(); } if (this.Owner.OrdinanceMax > 0f && this.Owner.Ordinance / this.Owner.OrdinanceMax < 0.05f && !this.hasPriorityTarget)//this.Owner.loyalty != ArtificialIntelligence.universeScreen.player) { if (FriendliesNearby.Where(supply => supply.HasSupplyBays && supply.Ordinance >= 100).Count() == 0) { this.OrderResupplyNearest(); return; } } if(this.Owner.Level >2 && this.Owner.Health / this.Owner.HealthMax <.5f&& !(this.HasPriorityOrder||this.hasPriorityTarget)) { this.OrderResupplyNearest(); return; } if (Vector2.Distance(this.Target.Center, this.Owner.Center) < 10000f) { if (this.Owner.engineState != Ship.MoveState.Warp && this.Owner.GetHangars().Count > 0 && !this.Owner.ManualHangarOverride) { if (!this.Owner.FightersOut) this.Owner.FightersOut = true; } if (this.Owner.engineState == Ship.MoveState.Warp) { this.Owner.HyperspaceReturn(); } } else if (this.CombatState != CombatState.HoldPosition && this.CombatState != CombatState.Evade) { this.ThrustTowardsPosition(this.Target.Center, elapsedTime, this.Owner.speed); return; } if (!this.HasPriorityOrder && !this.hasPriorityTarget && this.Owner.Weapons.Count == 0 && this.Owner.GetHangars().Count == 0) { this.CombatState = CombatState.Evade; } if (!this.Owner.loyalty.isFaction && this.Owner.GetSystem() != null && this.TroopsOut == false && this.Owner.GetHangars().Where(troops => troops.IsTroopBay).Count() > 0 || this.Owner.hasTransporter) { if (this.Owner.TroopList.Where(troop => troop.GetOwner() == this.Owner.loyalty).Count() > 0 && this.Owner.TroopList.Where(troop => troop.GetOwner() != this.Owner.loyalty).Count() == 0) { Planet invadeThis = null; foreach (Planet invade in this.Owner.GetSystem().PlanetList.Where(owner => owner.Owner != null && owner.Owner != this.Owner.loyalty).OrderBy(troops => troops.TroopsHere.Count)) { if (this.Owner.loyalty.GetRelations()[invade.Owner].AtWar) { invadeThis = invade; break; } } if (!this.TroopsOut && !this.Owner.hasTransporter) { if (invadeThis != null) { this.TroopsOut = true; foreach (Ship troop in this.Owner.GetHangars().Where(troop => troop.IsTroopBay && troop.GetHangarShip() != null).Select(ship => ship.GetHangarShip())) { troop.GetAI().OrderAssaultPlanet(invadeThis); } } else if (this.Target != null && this.Target is Ship && (this.Target as Ship).Role == "frigate" || (this.Target as Ship).Role == "carrier" || (this.Target as Ship).Role == "corvette" || (this.Target as Ship).Role == "cruiser" || (this.Target as Ship).Role == "capital") { if (this.Owner.GetHangars().Where(troop => troop.IsTroopBay).Count() * 60 >= (this.Target as Ship).MechanicalBoardingDefense) { this.TroopsOut = true; foreach (ShipModule hangar in this.Owner.GetHangars()) { if (hangar.GetHangarShip() == null || this.Target == null || !(hangar.GetHangarShip().Role == "troop") || !((this.Target as Ship).Role == "frigate") && !((this.Target as Ship).Role == "carrier") && !((this.Target as Ship).Role == "corvette") && !((this.Target as Ship).Role == "cruiser") && !((this.Target as Ship).Role == "capital")) { continue; } hangar.GetHangarShip().GetAI().OrderTroopToBoardShip(this.Target as Ship); } } } else { this.TroopsOut = false; } } } } //if this ship does not belong to a fleet #region if (this.Owner.fleet == null) { switch (this.CombatState) { case CombatState.Artillery: { this.DoNonFleetArtillery(elapsedTime); break; } case CombatState.OrbitLeft: { this.OrbitShipLeft(this.Target as Ship, elapsedTime); break; } case CombatState.BroadsideLeft: { this.DoNonFleetBroadsideLeft(elapsedTime); break; } case CombatState.OrbitRight: { this.OrbitShip(this.Target as Ship, elapsedTime); break; } case CombatState.BroadsideRight: { this.DoNonFleetBroadsideRight(elapsedTime); break; } case CombatState.AttackRuns: { this.DoAttackRun(elapsedTime); break; } case CombatState.HoldPosition: { this.DoHoldPositionCombat(elapsedTime); break; } case CombatState.Evade: { this.DoEvadeCombat(elapsedTime); break; } case CombatState.AssaultShip: { this.DoAssaultShipCombat(elapsedTime); break; } } } #endregion //if ship belongs to a fleet #region else if (this.Owner.fleet != null) { switch (this.CombatState) { case CombatState.Artillery: { this.DoNonFleetArtillery(elapsedTime); break; } case CombatState.OrbitLeft: { this.OrbitShipLeft(this.Target as Ship, elapsedTime); break; } case CombatState.BroadsideLeft: { this.DoNonFleetBroadsideLeft(elapsedTime); break; } case CombatState.OrbitRight: { this.OrbitShip(this.Target as Ship, elapsedTime); break; } case CombatState.BroadsideRight: { this.DoNonFleetBroadsideRight(elapsedTime); break; } case CombatState.AttackRuns: { this.DoAttackRun(elapsedTime); break; } case CombatState.HoldPosition: { this.DoHoldPositionCombat(elapsedTime); break; } case CombatState.Evade: { this.DoEvadeCombat(elapsedTime); break; } case CombatState.AssaultShip: { this.DoAssaultShipCombat(elapsedTime); break; } } if (this.Target != null) return; this.Owner.InCombat = false; } #endregion }
//(float elapsedTime) public void FireOnTarget() { //Reasons not to fire //try { TargetShip = this.Target as Ship; Relationship enemy =null; if (!this.Owner.hasCommand ||this.Owner.engineState == Ship.MoveState.Warp || this.Owner.disabled || this.Owner .Weapons.Count==0 || ((TargetShip != null && !this.Owner.loyalty.isFaction) && (this.Owner.loyalty.GetRelations().TryGetValue(TargetShip.loyalty, out enemy) && enemy != null && (enemy.Treaty_Peace || enemy.Treaty_Alliance || enemy.Treaty_NAPact)))) { return; } //Determine if there is something to shoot at if (this.BadGuysNear || this.Owner.InCombat) { //Target is dead or dying, will need a new one. if (this.Target != null && (!this.Target.Active || TargetShip != null && TargetShip.dying)) { this.Target = null; TargetShip = null; } this.TrackProjectiles.Clear(); //update projectile list { if (this.Owner.GetSystem() != null) { //Find non friendly planets foreach (Planet p in this.Owner.GetSystem().PlanetList) { if (p.Owner == this.Owner.loyalty) continue; foreach (Projectile proj in p.Projectiles) { this.TrackProjectiles.Add(proj); } } } { foreach (Ship ship in PotentialTargets) { for (int i = 0; i < ship.Projectiles.Count; i++) { Projectile proj; { proj = ship.Projectiles[i]; } if (proj == null || !proj.Active || proj.Health <= 0 || !proj.weapon.Tag_Intercept) continue; this.TrackProjectiles.Add(proj); } } } this.TrackProjectiles = this.TrackProjectiles.OrderBy(prj => Vector2.Distance(this.Owner.Center, prj.Center)).ToList(); } float lag = Ship.universeScreen.Lag; //Go through each weapon float index = 0; //count up weapons. //save target ship if it is a ship. this.TargetShip = this.Target as Ship; //group of weapons into chunks per thread available var source = Enumerable.Range(0, this.Owner.Weapons.Count).ToArray(); var rangePartitioner = Partitioner.Create(0, source.Length); //handle each weapon group in parallel Parallel.ForEach(rangePartitioner, (range, loopState) => { //standard for loop through each weapon group. for (int T = range.Item1; T < range.Item2; T++) { Weapon weapon = this.Owner.Weapons[T]; //Reasons for this weapon not to fire if ( !weapon.moduleAttachedTo.Active || weapon.timeToNextFire > 0f || !weapon.moduleAttachedTo.Powered || weapon.IsRepairDrone || weapon.isRepairBeam) { //continue; return; } ShipModule moduletarget = weapon.fireTarget as ShipModule; //if firing at the primary target mark weapon as firing on primary. if (!(weapon.fireTarget is Projectile) &&( weapon.fireTarget == this.Target || (moduletarget !=null && (moduletarget.GetParent() as GameplayObject) ==this.Target))) weapon.PrimaryTarget = true; //check if weapon target as a gameplay object is still a valid target if (weapon.fireTarget !=null ) { if ( (weapon.PrimaryTarget && weapon.fireTarget != this.Target) || !this.Owner.CheckIfInsideFireArc(weapon, weapon.fireTarget) //check here if the weapon can fire on main target. || (this.Target !=null &&(!weapon.PrimaryTarget && !(weapon.fireTarget is Projectile) && this.Owner.CheckIfInsideFireArc(weapon, this.Target) )) ) { weapon.TargetChangeTimer = .5f; weapon.fireTarget = null; if (weapon.isBeam || weapon.isMainGun) weapon.TargetChangeTimer = .90f; if (weapon.isTurret) weapon.TargetChangeTimer *= .5f; if(weapon.Tag_PD) { weapon.TargetChangeTimer *= .5f; } } } //if weapon target is null reset primary target and decrement target change timer. if (weapon.fireTarget == null) { weapon.TargetChangeTimer -= 0.0167f; if (weapon.PrimaryTarget != false) weapon.PrimaryTarget = false; } //Reasons for this weapon not to fire if (weapon.fireTarget == null && weapon.TargetChangeTimer >0 ) // ||!weapon.moduleAttachedTo.Active || weapon.timeToNextFire > 0f || !weapon.moduleAttachedTo.Powered || weapon.IsRepairDrone || weapon.isRepairBeam) { //continue; return; } //main targeting loop. little check here to disable the whole thing for debugging. if (true) { //Can this weapon fire on ships if (this.BadGuysNear && !weapon.TruePD ) { //if there are projectile to hit and weapons that can shoot at them. do so. if(this.TrackProjectiles.Count >0 && weapon.Tag_PD) { for (int i = 0; i < this.TrackProjectiles.Count; i++) { Projectile proj; { proj = this.TrackProjectiles[i]; } if (proj == null || !proj.Active || proj.Health <= 0 || !proj.weapon.Tag_Intercept) continue; if (this.Owner.CheckIfInsideFireArc(weapon, proj as GameplayObject)) { weapon.fireTarget = proj; break; } } } //Is primary target valid if (weapon.fireTarget == null) if (this.Owner.CheckIfInsideFireArc(weapon, this.Target)) { weapon.fireTarget = this.Target; weapon.PrimaryTarget = true; } //Find alternate target to fire on //this seems to be very expensive code. if (weapon.fireTarget == null) { //limit to one target per level. for (int i = 0; i < this.PotentialTargets.Count && i < this.Owner.Level+1; i++) // { Ship PotentialTarget = this.PotentialTargets[i]; if (PotentialTarget == this.TargetShip || !this.Owner.CheckIfInsideFireArc(weapon, PotentialTarget)) { continue; } weapon.fireTarget = PotentialTarget; break; } } //If a ship was found to fire on, change to target an internal module if target is visible || weapon.Tag_Intercept if (weapon.fireTarget != null) { if (weapon.fireTarget is Ship && (GlobalStats.ForceFullSim || this.Owner.InFrustum || (weapon.fireTarget as Ship).InFrustum))// || (this.Owner.InFrustum || this.Target != null && TargetShip.InFrustum))) { weapon.fireTarget = (weapon.fireTarget as Ship).GetRandomInternalModule(weapon); //weapon.fireTarget;// = fireTarget; } } } //No ship to target, check for projectiles if (weapon.fireTarget == null && weapon.Tag_PD) { //projectile list is created in teh scan for combat combats method. if (weapon.fireTarget == null) { for (int i = 0; i < this.TrackProjectiles.Count && i < this.Owner.Level+1;i++) { Projectile proj; { proj = this.TrackProjectiles[i]; } if (proj == null || !proj.Active || proj.Health <= 0 || !proj.weapon.Tag_Intercept) continue; if (this.Owner.CheckIfInsideFireArc(weapon, proj as GameplayObject)) { weapon.fireTarget = proj; break; } } } } } } }); //this section actually fires the weapons. This whole firing section can be moved to some other area of the code. This code is very expensive. if(1==1) foreach (Weapon weapon in this.Owner.Weapons) { if (weapon.fireTarget != null &&(weapon.moduleAttachedTo.Active && weapon.timeToNextFire <= 0f && weapon.moduleAttachedTo.Powered )) { if (!(weapon.fireTarget is Ship)) { GameplayObject target = weapon.fireTarget; if (weapon.isBeam) weapon.FireTargetedBeam(target); else if (weapon.Tag_Guided) { if (index > 10 && lag > .03 && !GlobalStats.ForceFullSim && (!weapon.Tag_Intercept) && (weapon.fireTarget is ShipModule)) this.FireOnTargetNonVisible(weapon, (weapon.fireTarget as ShipModule).GetParent()); else weapon.Fire(new Vector2((float)Math.Sin((double)this.Owner.Rotation + MathHelper.ToRadians(weapon.moduleAttachedTo.facing)), -(float)Math.Cos((double)this.Owner.Rotation + MathHelper.ToRadians(weapon.moduleAttachedTo.facing))), target); index++; } else { if (index > 10 && lag > .03 && !GlobalStats.ForceFullSim && (weapon.fireTarget is ShipModule)) this.FireOnTargetNonVisible(weapon, (weapon.fireTarget as ShipModule).GetParent()); else CalculateAndFire(weapon, target, false); index++; } } else this.FireOnTargetNonVisible(weapon, weapon.fireTarget); } } } } //catch (Exception e) { #if DEBUG //System.Diagnostics.Debug.WriteLine(e.InnerException); #endif } this.TargetShip = null; }
//added by gremlin Devekmod AuUpdate(fixed) public void Update(float elapsedTime) { this.CombatAI.UpdateCombatAI(this.Owner); ArtificialIntelligence.ShipGoal toEvaluate; if (this.State == AIState.AwaitingOrders && this.DefaultAIState == AIState.Exterminate) { this.State = AIState.Exterminate; } if (this.Owner.Name == "Subspace Projector") { this.BadGuysNear = true; return; } if (this.ClearOrdersNext) { this.OrderQueue.Clear(); this.ClearOrdersNext = false; this.State = AIState.AwaitingOrders; } List<Ship> ToRemove = new List<Ship>(); foreach (Ship target in this.TargetQueue) { if (target.Active) { continue; } ToRemove.Add(target); } foreach (Ship ship in ToRemove) { this.TargetQueue.Remove(ship); } if (!this.hasPriorityTarget) { this.TargetQueue.Clear(); } if (this.Owner.loyalty == ArtificialIntelligence.universeScreen.player && ( this.State == AIState.MoveTo && Vector2.Distance(this.Owner.Center, this.MovePosition) > 100f || this.State == AIState.Orbit || (this.State == AIState.Bombard || this.State == AIState.AssaultPlanet || this.State == AIState.BombardTroops) || this.State == AIState.Rebase || this.State == AIState.Scrap || this.State == AIState.Resupply || this.State == AIState.Refit || this.State == AIState.FormationWarp)) { this.HasPriorityOrder = true; } if (this.State == AIState.Resupply) { this.HasPriorityOrder = true; if (this.Owner.Ordinance >= this.Owner.OrdinanceMax) { this.HasPriorityOrder = false; } } //if (this.State == AIState.Flee && !this.BadGuysNear)// Vector2.Distance(this.OrbitTarget.Position, this.Owner.Position) < this.Owner.SensorRange + 10000) //{ // if(this.OrderQueue.Count > 0) // this.OrderQueue.Remove(this.OrderQueue.Last); // if (this.Owner.CargoSpace_Used > 0) // this.State = AIState.SystemTrader; // else // this.State = this.DefaultAIState; //} this.ScanForThreatTimer -= elapsedTime; if (this.ScanForThreatTimer < 0f) { if (this.inOrbit == true )//&& !(this.State == AIState.Orbit || this.State == AIState.Flee)) { this.inOrbit = false; } this.SetCombatStatus(elapsedTime); this.ScanForThreatTimer = 2f; if (this.Owner.loyalty.data.Traits.Pack) { this.Owner.DamageModifier = -0.25f; Ship owner = this.Owner; owner.DamageModifier = owner.DamageModifier + 0.05f * (float)this.FriendliesNearby.Count; if (this.Owner.DamageModifier > 0.5f) { this.Owner.DamageModifier = 0.5f; } } } this.UtilityModuleCheckTimer -= elapsedTime; if (this.UtilityModuleCheckTimer <= 0f) { this.UtilityModuleCheckTimer = 1f; //Added by McShooterz: logic for transporter moduels if (this.Owner.hasTransporter) { foreach (ShipModule module in this.Owner.Transporters) { if (module.TransporterTimer <= 0f && module.Active && module.Powered && module.TransporterPower < this.Owner.PowerCurrent) { if (this.FriendliesNearby.Count > 0 && module.TransporterOrdnance > 0 && this.Owner.Ordinance > 0) this.DoOrdinanceTransporterLogic(module); if (module.TransporterTroopAssault > 0 && this.Owner.TroopList.Count() > 0) this.DoAssaultTransporterLogic(module); } } } //Do repair check if friendly ships around and no combat if (!this.Owner.InCombat && this.FriendliesNearby.Count > 0) { //Added by McShooterz: logic for repair beams if (this.Owner.hasRepairBeam) { foreach (ShipModule module in this.Owner.RepairBeams) { if (module.InstalledWeapon.timeToNextFire <= 0f && module.InstalledWeapon.moduleAttachedTo.Powered && this.Owner.Ordinance >= module.InstalledWeapon.OrdinanceRequiredToFire && this.Owner.PowerCurrent >= module.InstalledWeapon.PowerRequiredToFire) { this.DoRepairBeamLogic(module.InstalledWeapon); } } } if (this.Owner.HasRepairModule) { foreach (Weapon weapon in this.Owner.Weapons) { if (weapon.timeToNextFire > 0f || !weapon.moduleAttachedTo.Powered || this.Owner.Ordinance < weapon.OrdinanceRequiredToFire || this.Owner.PowerCurrent < weapon.PowerRequiredToFire || !weapon.IsRepairDrone) { continue; } this.DoRepairDroneLogic(weapon); } } } } if (this.State == AIState.ManualControl) { return; } this.ReadyToWarp = true; this.Owner.isThrusting = false; this.Owner.isTurning = false; #region old flee code //if (!this.HasPriorityOrder // && (this.BadGuysNear || this.Owner.InCombat) // && (this.Owner.shipData == null || this.Owner.shipData.ShipCategory == ShipData.Category.Civilian) // && this.Owner.Weapons.Count == 0 && this.Owner.GetHangars().Count == 0 && this.Owner.Transporters.Count() == 0 // && (this.Owner.Role !="troop" // && this.Owner.Role != "construction" // && this.State !=AIState.Colonize // && !this.IgnoreCombat && this.State != AIState.Rebase) // && (this.Owner.Role == "freighter" || this.Owner.fleet == null || this.Owner.Mothership != null)) //{ // if (this.State != AIState.Flee ) // { // this.HasPriorityOrder = true; // this.State = AIState.Flee; // if (this.State == AIState.Flee) // { // this.OrderFlee(false); // this.Owner.InCombatTimer = 15f; // } // } // else if (this.State == AIState.Flee && (this.OrbitTarget != null && Vector2.Distance(this.OrbitTarget.Position, this.Owner.Position) < this.Owner.SensorRange + 10000)) // { // this.State = this.DefaultAIState; // } //} #endregion if (this.State == AIState.SystemTrader && this.start != null && this.end != null && (this.start.Owner != this.Owner.loyalty || this.end.Owner != this.Owner.loyalty)) { this.start = null; this.end = null; this.OrderTrade(); return; } if (this.State == AIState.PassengerTransport && this.start != null && this.end != null && (this.start.Owner != this.Owner.loyalty || this.end.Owner != this.Owner.loyalty)) { this.start = null; this.end = null; this.OrderTransportPassengers(); return; } #if !DEBUG try { #endif if (this.OrderQueue.Count == 0) { if (this.Owner.fleet == null) { lock (this.wayPointLocker) { this.ActiveWayPoints.Clear(); } AIState state = this.State; if (state <= AIState.MoveTo) { if (state <= AIState.SystemTrader) { if (state == AIState.DoNothing) { this.AwaitOrders(elapsedTime); } else { switch (state) { case AIState.AwaitingOrders: { if (this.Owner.loyalty != ArtificialIntelligence.universeScreen.player) { this.AwaitOrders(elapsedTime); } else { this.AwaitOrdersPlayer(elapsedTime); } if (this.Owner.OrdinanceMax == 0 || this.Owner.OrdinanceMax > 0 && this.Owner.Ordinance / this.Owner.OrdinanceMax >= 0.2f) { break; } if (FriendliesNearby.Where(supply => supply.HasSupplyBays && supply.Ordinance >= 100).Count() > 0) { break; } List<Planet> shipyards = new List<Planet>(); for (int i = 0; i < this.Owner.loyalty.GetPlanets().Count; i++) { Planet item = this.Owner.loyalty.GetPlanets()[i]; if (item.HasShipyard) { shipyards.Add(item); } } IOrderedEnumerable<Planet> sortedList = from p in shipyards orderby Vector2.Distance(this.Owner.Center, p.Position) select p; if (sortedList.Count<Planet>() <= 0) { break; } this.OrderResupply(sortedList.First<Planet>(), true); break; } case AIState.Escort: { if (this.EscortTarget != this.Owner.Mothership || this.Owner.Mothership == null || !this.Owner.Mothership.InCombat) { if (this.EscortTarget == null || !this.EscortTarget.Active) { this.State = AIState.AwaitingOrders; //fbedard break; } this.OrbitShip(this.EscortTarget, elapsedTime); break; } else { if(this.Target == null && !(this.hasPriorityTarget || this.HasPriorityOrder)) this.Target = this.Owner.Mothership.GetAI().Target; this.DoCombat(elapsedTime); break; } } case AIState.SystemTrader: { this.OrderTrade(); if (this.end != null && this.start != null) { break; } this.AwaitOrders(elapsedTime); break; } } } } else if (state == AIState.PassengerTransport) { this.OrderTransportPassengers(); if (this.end == null || this.start == null) { this.AwaitOrders(elapsedTime); } } else if (state != AIState.MoveTo) { } } else if (state <= AIState.ReturnToHangar) { switch (state) { case AIState.SystemDefender: { if (this.Target != null) System.Diagnostics.Debug.WriteLine("SD Tatget" + this.Owner.VanityName); //if(this.Target == null) this.AwaitOrders(elapsedTime); break; } case AIState.AwaitingOffenseOrders: { break; } case AIState.Resupply: { if (this.Owner.Ordinance != this.Owner.OrdinanceMax) { break; } this.State = AIState.AwaitingOrders; break; } default: { if (state == AIState.ReturnToHangar) { this.DoReturnToHangar(elapsedTime); break; } else { break; } } } } else if (state != AIState.Intercept) { if (state == AIState.Exterminate) { this.OrderFindExterminationTarget(true); } } else if (this.Target != null) { this.OrbitShip(this.Target as Ship, elapsedTime); } } else { float DistanceToFleetOffset = Vector2.Distance(this.Owner.Center, this.Owner.fleet.Position + this.Owner.FleetOffset); Vector2 toAdd = (this.Owner.Velocity != Vector2.Zero ? Vector2.Normalize(this.Owner.Velocity) : Vector2.Zero) * 100f; Vector2.Distance(this.Owner.Center, (this.Owner.fleet.Position + this.Owner.FleetOffset) + toAdd); Vector2 vector2 = HelperFunctions.findPointFromAngleAndDistanceUsingRadians(this.Owner.fleet.Position + this.Owner.FleetOffset, this.Owner.fleet.facing, 1f); Vector2 fvec = HelperFunctions.FindVectorToTarget(Vector2.Zero, vector2); if (DistanceToFleetOffset <= 75f || this.HasPriorityOrder) { this.Owner.Velocity = Vector2.Zero; vector2 = HelperFunctions.findPointFromAngleAndDistanceUsingRadians(Vector2.Zero, this.Owner.fleet.facing, 1f); fvec = HelperFunctions.FindVectorToTarget(Vector2.Zero, vector2); Vector2 wantedForward = Vector2.Normalize(fvec); Vector2 forward = new Vector2((float)Math.Sin((double)this.Owner.Rotation), -(float)Math.Cos((double)this.Owner.Rotation)); Vector2 right = new Vector2(-forward.Y, forward.X); float angleDiff = (float)Math.Acos((double)Vector2.Dot(wantedForward, forward)); float facing = (Vector2.Dot(wantedForward, right) > 0f ? 1f : -1f); if (angleDiff > 0.02f) { this.RotateToFacing(elapsedTime, angleDiff, facing); } this.State = AIState.AwaitingOrders; } else { this.ThrustTowardsPosition(this.Owner.fleet.Position + this.Owner.FleetOffset, elapsedTime, this.Owner.fleet.speed); lock (this.wayPointLocker) { this.ActiveWayPoints.Clear(); this.ActiveWayPoints.Enqueue(this.Owner.fleet.Position + this.Owner.FleetOffset); if (this.Owner.fleet.GetStack().Count > 0) { this.ActiveWayPoints.Enqueue(this.Owner.fleet.GetStack().Peek().MovePosition + this.Owner.FleetOffset); } } } } } else if (this.OrderQueue.Count > 0) { #if DEBUG try #endif { toEvaluate = this.OrderQueue.First<ArtificialIntelligence.ShipGoal>(); } #if DEBUG catch { return; } #endif Planet target = toEvaluate.TargetPlanet; switch (toEvaluate.Plan) { case ArtificialIntelligence.Plan.HoldPosition: { // // this.HoldPosition(); break; } case ArtificialIntelligence.Plan.Stop: { this.Stop(elapsedTime, toEvaluate); break; } case ArtificialIntelligence.Plan.Scrap: { this.ScrapShip(elapsedTime, toEvaluate); break; } case ArtificialIntelligence.Plan.Bombard: //target = toEvaluate.TargetPlanet; //Modified by Ermenildo V. Castro, Jr.; 07/29/15: Removed redunant statement, assignment occurs before SWITCH if (this.Owner.Ordinance < 0.05* this.Owner.OrdinanceMax || (target.TroopsHere.Count <= target.TroopsHere.Count * .40f || target.Population <= target.Population * .10f) //Legacy Code: (target.BuildingList.Count == 0 && target.TroopsHere.Count == 0 && target.Population <0f) //Modified by Ermenildo V. Castro, Jr. for Issue #488 //Issue #488: //The ai needs to soften planets more for invasion but try not to kill all the populace //Modified conditional to reflect goals for Issue #488: // - Stop bombarding if planet population is less than 10% of the original target population // - Stop bombarding if opposition troops are attrited by at least 60%, id est: target troops less than 40% of original troop count || target.GetGroundStrengthOther(this.Owner.loyalty) * 1.5 <= target.GetGroundStrength(this.Owner.loyalty) ) { this.OrderQueue.Clear(); if(this.CombatState == CombatState.Evade) this.State = AIState.AwaitingOrders; this.HasPriorityOrder = false; } this.DoOrbit(toEvaluate.TargetPlanet, elapsedTime); float radius = toEvaluate.TargetPlanet.ObjectRadius + this.Owner.Radius + 1000; if (toEvaluate.TargetPlanet.Owner == this.Owner.loyalty) //cannot bombard friednly planets { this.OrderQueue.Clear(); return; } else if (Vector2.Distance(this.Owner.Center, toEvaluate.TargetPlanet.Position) < radius) { using (List<ShipModule>.Enumerator enumerator = this.Owner.BombBays.GetEnumerator()) { while (enumerator.MoveNext()) { ShipModule current = enumerator.Current; if ((double)current.BombTimer <= 0.0) { Bomb bomb = new Bomb(new Vector3(this.Owner.Center, 0.0f), this.Owner.loyalty); bomb.WeaponName = current.BombType; if ((double)this.Owner.Ordinance > (double)ResourceManager.WeaponsDict[current.BombType].OrdinanceRequiredToFire) { this.Owner.Ordinance -= ResourceManager.WeaponsDict[current.BombType].OrdinanceRequiredToFire; bomb.SetTarget(toEvaluate.TargetPlanet); //lock (GlobalStats.BombLock) ArtificialIntelligence.universeScreen.BombList.Add(bomb); current.BombTimer = ResourceManager.WeaponsDict[current.BombType].fireDelay; } } } break; } } else break; case ArtificialIntelligence.Plan.BombTroops: target = toEvaluate.TargetPlanet; if (target.TroopsHere.Where(unfriendlyTroops => unfriendlyTroops.GetOwner() != this.Owner.loyalty).Count() * 1.5 >= target.TilesList.Sum(space => space.number_allowed_troops)) { if ((double)this.Owner.Ordinance < 0.0500000007450581 * (double)this.Owner.OrdinanceMax) { this.OrderQueue.Clear(); this.State = AIState.AwaitingOrders; this.HasPriorityOrder = false; } this.DoOrbit(toEvaluate.TargetPlanet, elapsedTime); radius = toEvaluate.TargetPlanet.ObjectRadius + this.Owner.Radius + 1000; if (toEvaluate.TargetPlanet.Owner == this.Owner.loyalty) { this.OrderQueue.Clear(); return; } else if ((double)Vector2.Distance(this.Owner.Center, toEvaluate.TargetPlanet.Position) < radius) { using (List<ShipModule>.Enumerator enumerator = this.Owner.BombBays.GetEnumerator()) { while (enumerator.MoveNext()) { ShipModule current = enumerator.Current; if ((double)current.BombTimer <= 0.0) { Bomb bomb = new Bomb(new Vector3(this.Owner.Center, 0.0f), this.Owner.loyalty); bomb.WeaponName = current.BombType; if ((double)this.Owner.Ordinance > (double)ResourceManager.WeaponsDict[current.BombType].OrdinanceRequiredToFire) { this.Owner.Ordinance -= ResourceManager.WeaponsDict[current.BombType].OrdinanceRequiredToFire; bomb.SetTarget(toEvaluate.TargetPlanet); //lock (GlobalStats.BombLock) ArtificialIntelligence.universeScreen.BombList.Add(bomb); current.BombTimer = ResourceManager.WeaponsDict[current.BombType].fireDelay; } } } break; } } else break; } else if (this.Owner.HasTroopBay || (this.Owner.hasTransporter)) { this.State = AIState.AssaultPlanet; this.OrderAssaultPlanet(target); } else this.OrderQueue.Clear(); break; case ArtificialIntelligence.Plan.Exterminate: { this.DoOrbit(toEvaluate.TargetPlanet, elapsedTime); radius = toEvaluate.TargetPlanet.ObjectRadius + this.Owner.Radius + 1000; if (toEvaluate.TargetPlanet.Owner == this.Owner.loyalty || toEvaluate.TargetPlanet.Owner == null) { this.OrderQueue.Clear(); this.OrderFindExterminationTarget(true); return; } else { if (Vector2.Distance(this.Owner.Center, toEvaluate.TargetPlanet.Position) >= radius) break; List<ShipModule>.Enumerator enumerator1 = this.Owner.BombBays.GetEnumerator(); try { while (enumerator1.MoveNext()) { ShipModule mod = enumerator1.Current; if (mod.BombTimer > 0f) continue; Bomb b = new Bomb(new Vector3(this.Owner.Center, 0f), this.Owner.loyalty) { WeaponName = mod.BombType }; if (this.Owner.Ordinance <= ResourceManager.WeaponsDict[mod.BombType].OrdinanceRequiredToFire) { continue; } Ship owner1 = this.Owner; owner1.Ordinance = owner1.Ordinance - ResourceManager.WeaponsDict[mod.BombType].OrdinanceRequiredToFire; b.SetTarget(toEvaluate.TargetPlanet); //lock (GlobalStats.BombLock) { ArtificialIntelligence.universeScreen.BombList.Add(b); } mod.BombTimer = ResourceManager.WeaponsDict[mod.BombType].fireDelay; } break; } finally { ((IDisposable)enumerator1).Dispose(); } } } case ArtificialIntelligence.Plan.RotateToFaceMovePosition: { this.RotateToFaceMovePosition(elapsedTime, toEvaluate); break; } case ArtificialIntelligence.Plan.RotateToDesiredFacing: { this.RotateToDesiredFacing(elapsedTime, toEvaluate); break; } case ArtificialIntelligence.Plan.MoveToWithin1000: { this.MoveToWithin1000(elapsedTime, toEvaluate); break; } case ArtificialIntelligence.Plan.MakeFinalApproachFleet: { if (this.Owner.fleet != null) { this.MakeFinalApproachFleet(elapsedTime, toEvaluate); break; } else { this.State = AIState.AwaitingOrders; break; } } case ArtificialIntelligence.Plan.MoveToWithin1000Fleet: { if (this.Owner.fleet != null) { this.MoveToWithin1000Fleet(elapsedTime, toEvaluate); break; } else { this.State = AIState.AwaitingOrders; break; } } case ArtificialIntelligence.Plan.MakeFinalApproach: { this.MakeFinalApproach(elapsedTime, toEvaluate); break; } case ArtificialIntelligence.Plan.RotateInlineWithVelocity: { this.RotateInLineWithVelocity(elapsedTime, toEvaluate); break; } case ArtificialIntelligence.Plan.StopWithBackThrust: { this.StopWithBackwardsThrust(elapsedTime, toEvaluate); break; } case ArtificialIntelligence.Plan.Orbit: { this.DoOrbit(toEvaluate.TargetPlanet, elapsedTime); break; } case ArtificialIntelligence.Plan.Colonize: { this.Colonize(toEvaluate.TargetPlanet); break; } case ArtificialIntelligence.Plan.Explore: { this.DoExplore(elapsedTime); break; } case ArtificialIntelligence.Plan.Rebase: { this.DoRebase(toEvaluate); break; } case ArtificialIntelligence.Plan.DefendSystem: { if (this.Target != null) System.Diagnostics.Debug.WriteLine(this.Target); this.DoSystemDefense(elapsedTime); break; } case ArtificialIntelligence.Plan.DoCombat: { this.DoCombat(elapsedTime); break; } case ArtificialIntelligence.Plan.MoveTowards: { this.MoveTowardsPosition(this.MovePosition, elapsedTime); break; } case ArtificialIntelligence.Plan.PickupPassengers: { if (this.start != null) this.PickupPassengers(); else this.State = AIState.AwaitingOrders; break; } case ArtificialIntelligence.Plan.DropoffPassengers: { try { this.DropoffPassengers(); } catch { System.Diagnostics.Debug.WriteLine("DropoffPassengers failed"); } break; } case ArtificialIntelligence.Plan.DeployStructure: { this.DoDeploy(toEvaluate); break; } case ArtificialIntelligence.Plan.PickupGoods: { try { this.PickupGoods(); } catch { } break; } case ArtificialIntelligence.Plan.DropOffGoods: { this.DropoffGoods(); break; } case ArtificialIntelligence.Plan.ReturnToHangar: { this.DoReturnToHangar(elapsedTime); break; } case ArtificialIntelligence.Plan.TroopToShip: { this.DoTroopToShip(elapsedTime); break; } case ArtificialIntelligence.Plan.BoardShip: { this.DoBoardShip(elapsedTime); break; } case ArtificialIntelligence.Plan.SupplyShip: { this.DoSupplyShip(elapsedTime, toEvaluate); break; } case ArtificialIntelligence.Plan.Refit: { this.DoRefit(elapsedTime, toEvaluate); break; } case ArtificialIntelligence.Plan.LandTroop: { this.DoLandTroop(elapsedTime, toEvaluate); break; } } } goto Label0; #if !DEBUG } catch { } #endif Label0: AIState aIState = this.State; if (aIState == AIState.SystemTrader) { foreach (ArtificialIntelligence.ShipGoal goal in this.OrderQueue) { if (goal.Plan == ArtificialIntelligence.Plan.TransportPassengers && goal.TargetPlanet != null && goal.TargetPlanet.Owner != this.Owner.loyalty) { this.OrderQueue.Clear(); this.State = AIState.AwaitingOrders; break; } else if (goal.Plan == ArtificialIntelligence.Plan.PickupPassengers && goal.TargetPlanet != null && goal.TargetPlanet.Owner != this.Owner.loyalty) { this.OrderQueue.Clear(); this.State = AIState.AwaitingOrders; break; } else if (goal.Plan == ArtificialIntelligence.Plan.PickupGoods && goal.TargetPlanet != null && goal.TargetPlanet.Owner != this.Owner.loyalty) { this.OrderQueue.Clear(); this.State = AIState.AwaitingOrders; break; } else if (goal.Plan != ArtificialIntelligence.Plan.DropoffPassengers || goal.TargetPlanet == null || goal.TargetPlanet.Owner == this.Owner.loyalty) { if (goal.Plan != ArtificialIntelligence.Plan.DropOffGoods || goal.TargetPlanet == null || goal.TargetPlanet.Owner == this.Owner.loyalty) { continue; } this.OrderQueue.Clear(); this.State = AIState.AwaitingOrders; break; } else { this.OrderQueue.Clear(); this.State = AIState.AwaitingOrders; break; } } } else if (aIState == AIState.PassengerTransport) { foreach (ArtificialIntelligence.ShipGoal goal in this.OrderQueue) { if (goal.Plan == ArtificialIntelligence.Plan.TransportPassengers && goal.TargetPlanet != null && goal.TargetPlanet.Owner != this.Owner.loyalty) { this.OrderQueue.Clear(); this.State = AIState.AwaitingOrders; break; } else if (goal.Plan == ArtificialIntelligence.Plan.PickupPassengers && goal.TargetPlanet != null && goal.TargetPlanet.Owner != this.Owner.loyalty) { this.OrderQueue.Clear(); this.State = AIState.AwaitingOrders; break; } else if (goal.Plan == ArtificialIntelligence.Plan.PickupGoods && goal.TargetPlanet != null && goal.TargetPlanet.Owner != this.Owner.loyalty) { this.OrderQueue.Clear(); this.State = AIState.AwaitingOrders; break; } else if (goal.Plan != ArtificialIntelligence.Plan.DropoffPassengers || goal.TargetPlanet == null || goal.TargetPlanet.Owner == this.Owner.loyalty) { if (goal.Plan != ArtificialIntelligence.Plan.DropOffGoods || goal.TargetPlanet == null || goal.TargetPlanet.Owner == this.Owner.loyalty) { continue; } this.OrderQueue.Clear(); this.State = AIState.AwaitingOrders; break; } else { this.OrderQueue.Clear(); this.State = AIState.AwaitingOrders; break; } } } else if (aIState == AIState.Rebase) { foreach (ArtificialIntelligence.ShipGoal goal in this.OrderQueue) //Parallel.ForEach(this.OrderQueue, (goal, state) => { if (goal.Plan != ArtificialIntelligence.Plan.Rebase || goal.TargetPlanet == null || goal.TargetPlanet.Owner == this.Owner.loyalty) { continue; } this.OrderQueue.Clear(); this.State = AIState.AwaitingOrders; break; } } //if(targetChangeTimer >-1) //targetChangeTimer -= elapsedTime; //if(TriggerDelay >-1) TriggerDelay -= elapsedTime; if (this.Owner.InCombat && this.BadGuysNear && !this.IgnoreCombat) { if (this.TriggerDelay < 0) { TriggerDelay = elapsedTime * 2; bool docombat = false; LinkedListNode<ArtificialIntelligence.ShipGoal> tempShipGoal = this.OrderQueue.First; ShipGoal firstgoal = tempShipGoal != null ? tempShipGoal.Value : null; //.FirstOrDefault<ArtificialIntelligence.ShipGoal>(); if (this.Owner.Weapons.Count > 0 || this.Owner.GetHangars().Count > 0) #if !DEBUG try #endif { docombat = (!this.HasPriorityOrder && (this.OrderQueue.Count == 0 || firstgoal != null && firstgoal.Plan != ArtificialIntelligence.Plan.DoCombat)); if (docombat)//|| this.OrderQueue.Count == 0)) { this.OrderQueue.AddFirst(new ArtificialIntelligence.ShipGoal(ArtificialIntelligence.Plan.DoCombat, Vector2.Zero, 0f)); } //this.fireTask = Task.Factory.StartNew(this.FireOnTarget);//,TaskCreationOptions.LongRunning); //fireTask = new Task(this.FireOnTarget); this.FireOnTarget(); } #if !DEBUG catch { } #endif } } else { if (this.Owner.GetHangars().Count > 0 && this.Owner.loyalty != ArtificialIntelligence.universeScreen.player) { foreach (ShipModule hangar in this.Owner.GetHangars()) { if (hangar.IsTroopBay || hangar.IsSupplyBay || hangar.GetHangarShip() == null //||hangar.GetHangarShip().InCombat || hangar.GetHangarShip().GetAI().State == AIState.ReturnToHangar) { continue; } hangar.GetHangarShip().GetAI().OrderReturnToHangar(); } } else if (this.Owner.GetHangars().Count > 0) { foreach (ShipModule hangar in this.Owner.GetHangars()) { if (hangar.IsTroopBay || hangar.IsSupplyBay || hangar.GetHangarShip() == null || hangar.GetHangarShip().GetAI().State == AIState.ReturnToHangar //|| hangar.GetHangarShip().InCombat || hangar.GetHangarShip().GetAI().hasPriorityTarget || hangar.GetHangarShip().GetAI().HasPriorityOrder ) { continue; } hangar.GetHangarShip().DoEscort(this.Owner); } } } if (this.State == AIState.Resupply && !this.HasPriorityOrder) { this.HasPriorityOrder = true; } //if (this.Owner.Weapons.Count() == 0 && this.BadGuysNear) //||( this.State != AIState.AssaultPlanet && this.State != AIState.Boarding //{ // this.CombatState = Gameplay.CombatState.Evade; //} if (!this.Owner.isTurning) { this.DeRotate(); return; } else { return; } }
public virtual void FireDroneBeam(Vector2 direction, GameplayObject target, DroneAI source) { this.drowner = source.Owner; if (this.timeToNextFire > 0f) { return; } this.timeToNextFire = this.fireDelay; this.CreateDroneBeam(direction, target, source); }
public virtual void FireFromPlanet(Vector2 direction, Planet p, GameplayObject target) { if (target is ShipModule) (target as ShipModule).GetParent().InCombatTimer = 15f; Vector2 StartPos = p.Position; if (this.FireArc != 0) { float DegreesBetweenShots = (float)(this.FireArc / this.ProjectileCount); float angleToTarget = this.findAngleToTarget(direction); for (int i = 0; i < this.ProjectileCount; i++) { Vector2 newTarget = this.findTargetFromAngleAndDistance(StartPos, angleToTarget - (float)(this.FireArc / 2) + DegreesBetweenShots * (float)i, this.Range); Vector2 fireDirection = this.findVectorToTarget(StartPos, newTarget); fireDirection.Y = fireDirection.Y * -1f; this.CreateProjectilesFromPlanet(Vector2.Normalize(fireDirection), p, target); } return; } if (this.FireCone <= 0) { if (!this.isBeam) { for (int i = 0; i < this.ProjectileCount; i++) { if (this.WeaponType != "Missile") { this.CreateProjectilesFromPlanet(direction, p, target); } else { this.CreateProjectilesFromPlanet(Vector2.Normalize(direction), p, target); } } } return; } float spread = RandomMath2.RandomBetween((float)(-this.FireCone / 2), (float)(this.FireCone / 2)); float angleToTarget2 = this.findAngleToTarget(direction); Vector2 newTarget2 = this.findTargetFromAngleAndDistance(StartPos, angleToTarget2 + spread, this.Range); Vector2 fireDirection2 = this.findVectorToTarget(StartPos, newTarget2); fireDirection2.Y = fireDirection2.Y * -1f; this.CreateProjectilesFromPlanet(Vector2.Normalize(fireDirection2), p, target); }
private void SetCombatStatus(float elapsedTime) { //if(this.State==AIState.Scrap) //{ // this.Target = null; // this.Owner.InCombatTimer = 0f; // this.Owner.InCombat = false; // this.TargetQueue.Clear(); // return; //} float radius = 30000f; Vector2 senseCenter = this.Owner.Center; if (UseSensorsForTargets) { if (this.Owner.Mothership != null) { if (Vector2.Distance(this.Owner.Center, this.Owner.Mothership.Center) <= this.Owner.Mothership.SensorRange - this.Owner.SensorRange) { senseCenter = this.Owner.Mothership.Center; radius = this.Owner.Mothership.SensorRange; } } else { radius = this.Owner.SensorRange; if (this.Owner.inborders) radius += 10000; } } if (this.Owner.fleet != null) { if (!this.hasPriorityTarget) { this.Target = this.ScanForCombatTargets(senseCenter, radius); } else { this.ScanForCombatTargets(senseCenter, radius); } } else if (!this.hasPriorityTarget) { //#if DEBUG // if (this.State == AIState.Intercept && this.Target != null) // System.Diagnostics.Debug.WriteLine(this.Target); //#endif this.Target = this.ScanForCombatTargets(senseCenter, radius); } else { this.ScanForCombatTargets(senseCenter, radius); } if (this.State == AIState.Resupply) { return; } if (((this.Owner.Role == "freighter" && this.Owner.CargoSpace_Max > 0) || this.Owner.Role == "scout" || this.Owner.Role == "construction" || this.Owner.Role == "troop" || this.IgnoreCombat || this.State == AIState.Resupply || this.State == AIState.ReturnToHangar || this.State == AIState.Colonize) || this.Owner.VanityName == "Resupply Shuttle") { return; } if (this.Owner.fleet != null && this.State == AIState.FormationWarp) { bool doreturn = true; if (this.Owner.fleet != null && this.State == AIState.FormationWarp && Vector2.Distance(this.Owner.Center, this.Owner.fleet.Position + this.Owner.FleetOffset) < 15000f) { doreturn = false; } if (doreturn) { //if (this.Owner.engineState == Ship.MoveState.Sublight && this.NearbyShips.Count > 0) //{ // this.Owner.ShieldsUp = true; //} return; } } if (this.Owner.fleet != null) { foreach (FleetDataNode datanode in this.Owner.fleet.DataNodes) { if (datanode.GetShip() != this.Owner) { continue; } this.node = datanode; break; } } if (this.Target != null && !this.Owner.InCombat) { this.Owner.InCombatTimer = 15f; if (!this.HasPriorityOrder && this.OrderQueue.Count > 0 && this.OrderQueue.ElementAt<ArtificialIntelligence.ShipGoal>(0).Plan != ArtificialIntelligence.Plan.DoCombat) { ArtificialIntelligence.ShipGoal combat = new ArtificialIntelligence.ShipGoal(ArtificialIntelligence.Plan.DoCombat, Vector2.Zero, 0f); this.State = AIState.Combat; this.OrderQueue.AddFirst(combat); return; } else if (!this.HasPriorityOrder) { ArtificialIntelligence.ShipGoal combat = new ArtificialIntelligence.ShipGoal(ArtificialIntelligence.Plan.DoCombat, Vector2.Zero, 0f); this.State = AIState.Combat; this.OrderQueue.AddFirst(combat); return; } else { if (!this.HasPriorityOrder || this.CombatState == CombatState.HoldPosition || this.OrderQueue.Count != 0) return; ArtificialIntelligence.ShipGoal combat = new ArtificialIntelligence.ShipGoal(ArtificialIntelligence.Plan.DoCombat, Vector2.Zero, 0f); this.State = AIState.Combat; this.OrderQueue.AddFirst(combat); } } }
public virtual void FireTargetedBeam(GameplayObject target) { if (this.timeToNextFire > 0f) { return; } this.owner.InCombatTimer = 15f; this.timeToNextFire = this.fireDelay; if (this.moduleAttachedTo.Active && this.owner.PowerCurrent > this.PowerRequiredToFire && this.OrdinanceRequiredToFire <= this.owner.Ordinance) { this.CreateTargetedBeam(target); this.owner.Ordinance -= this.OrdinanceRequiredToFire; this.owner.PowerCurrent -= this.PowerRequiredToFire; } }
private void SetCombatStatusorig(float elapsedTime) { if (this.Owner.fleet != null) { if (!this.hasPriorityTarget) { this.Target = this.ScanForCombatTargets(this.Owner.Center, 30000f); } else { this.ScanForCombatTargets(this.Owner.Center, 30000f); } } else if (!this.hasPriorityTarget) { this.Target = this.ScanForCombatTargets(this.Owner.Center, 30000f); } else { this.ScanForCombatTargets(this.Owner.Center, 30000f); } if (this.State == AIState.Resupply) { return; } if ((this.Owner.Role == "freighter" || this.Owner.Role == "scout" || this.Owner.Role == "construction" || this.Owner.Role == "troop" || this.IgnoreCombat || this.State == AIState.Resupply || this.State == AIState.ReturnToHangar) && !this.Owner.IsSupplyShip) { return; } if (this.Owner.fleet != null && this.State == AIState.FormationWarp) { bool doreturn = true; if (this.Owner.fleet != null && this.State == AIState.FormationWarp && Vector2.Distance(this.Owner.Center, this.Owner.fleet.Position + this.Owner.FleetOffset) < 15000f) { doreturn = false; } if (doreturn) { return; } } if (this.Owner.fleet != null) { foreach (FleetDataNode datanode in this.Owner.fleet.DataNodes) { if (datanode.GetShip() != this.Owner) { continue; } this.node = datanode; break; } } if (this.Target != null && !this.Owner.InCombat) { this.Owner.InCombat = true; this.Owner.InCombatTimer = 15f; if (!this.HasPriorityOrder && this.OrderQueue.Count > 0 && this.OrderQueue.ElementAt<ArtificialIntelligence.ShipGoal>(0).Plan != ArtificialIntelligence.Plan.DoCombat) { ArtificialIntelligence.ShipGoal combat = new ArtificialIntelligence.ShipGoal(ArtificialIntelligence.Plan.DoCombat, Vector2.Zero, 0f); this.State = AIState.Combat; this.OrderQueue.AddFirst(combat); return; } if (!this.HasPriorityOrder) { ArtificialIntelligence.ShipGoal combat = new ArtificialIntelligence.ShipGoal(ArtificialIntelligence.Plan.DoCombat, Vector2.Zero, 0f); this.State = AIState.Combat; this.OrderQueue.AddFirst(combat); return; } if (this.HasPriorityOrder && this.CombatState != Ship_Game.Gameplay.CombatState.HoldPosition && this.OrderQueue.Count == 0) { ArtificialIntelligence.ShipGoal combat = new ArtificialIntelligence.ShipGoal(ArtificialIntelligence.Plan.DoCombat, Vector2.Zero, 0f); this.State = AIState.Combat; this.OrderQueue.AddFirst(combat); return; } } else if (this.Target == null) { this.Owner.InCombat = false; } }
protected virtual void CreateDroneBeam(Vector2 destination, GameplayObject target, DroneAI source) { if (source == null) return; Beam beam = new Beam(source.Owner.Center, target.Center, this.BeamThickness, source.Owner, target); beam.moduleAttachedTo = this.moduleAttachedTo; beam.PowerCost = (float)this.BeamPowerCostPerSecond; beam.range = this.Range; beam.thickness = this.BeamThickness; beam.Duration = (float)this.BeamDuration > 0 ? this.BeamDuration : 2f; beam.damageAmount = this.DamageAmount; beam.weapon = this; if(!beam.LoadContent(Weapon.universeScreen.ScreenManager, Weapon.universeScreen.view, Weapon.universeScreen.projection)) { beam.Die(null, true); return; } source.Beams.Add(beam); this.ToggleSoundOn = false; if (Weapon.universeScreen.viewState <= UniverseScreen.UnivScreenState.SystemView) { //Added by McShooterz: Use sounds from new sound dictionary if (ResourceManager.SoundEffectDict.ContainsKey(this.fireCueName)) { AudioManager.PlaySoundEffect(ResourceManager.SoundEffectDict[fireCueName], Weapon.audioListener, source.Owner.emitter, 0.5f); } else { if (!string.IsNullOrEmpty(this.fireCueName)) { this.fireCue = AudioManager.GetCue(this.fireCueName); this.fireCue.Apply3D(Weapon.audioListener, source.Owner.emitter); this.fireCue.Play(); } } if (!string.IsNullOrEmpty(this.ToggleSoundName)) { this.ToggleSoundOn = true; this.ToggleCue = AudioManager.GetCue(this.ToggleSoundName); this.ToggleCue.Apply3D(Weapon.audioListener, source.Owner.emitter); this.ToggleCue.Play(); } } }
public void OrderAttackSpecificTarget(Ship toAttack) { this.TargetQueue.Clear(); if (toAttack == null) { return; } if (this.Owner.loyalty.GetRelations().ContainsKey(toAttack.loyalty)) { if (!this.Owner.loyalty.GetRelations()[toAttack.loyalty].Treaty_Peace) { if (this.State == AIState.AttackTarget && this.Target == toAttack) { return; } if (this.State == AIState.SystemDefender && this.Target == toAttack) { return; } if (this.Owner.Weapons.Count == 0 || this.Owner.Role == "troop") { this.OrderInterceptShip(toAttack); return; } this.Intercepting = true; lock (this.wayPointLocker) { this.ActiveWayPoints.Clear(); } this.State = AIState.AttackTarget; this.Target = toAttack; this.Owner.InCombatTimer = 15f; this.OrderQueue.Clear(); this.IgnoreCombat = false; this.TargetQueue.Add(toAttack); this.hasPriorityTarget = true; this.HasPriorityOrder = false; ArtificialIntelligence.ShipGoal combat = new ArtificialIntelligence.ShipGoal(ArtificialIntelligence.Plan.DoCombat, Vector2.Zero, 0f); this.OrderQueue.AddLast(combat); return; } this.OrderInterceptShip(toAttack); } }
public void DamageMissile(GameplayObject source, float damageAmount) { this.Health -= damageAmount; if (base.Health <= 0f && this.Active) { this.DieNextFrame = true; } }
//added by gremlin to run away public void OrderFlee(bool ClearOrders) { lock (this.wayPointLocker) { this.ActiveWayPoints.Clear(); } this.Target = null; this.Intercepting = false; this.Owner.HyperspaceReturn(); if (ClearOrders) { this.OrderQueue.Clear(); } IOrderedEnumerable<SolarSystem> systemList = from solarsystem in this.Owner.loyalty.GetOwnedSystems() where solarsystem.combatTimer <=0 && Vector2.Distance(solarsystem.Position,this.Owner.Position) >300000 orderby Vector2.Distance(this.Owner.Center, solarsystem.Position) select solarsystem; if (systemList.Count<SolarSystem>() > 0) { Planet item = systemList.First<SolarSystem>().PlanetList[0]; this.OrbitTarget = item; ArtificialIntelligence.ShipGoal orbit = new ArtificialIntelligence.ShipGoal(ArtificialIntelligence.Plan.Orbit, Vector2.Zero, 0f) { TargetPlanet = item }; this.resupplyTarget = item; this.OrderQueue.AddLast(orbit); this.State = AIState.Flee; } }
public void InitializeMissilePlanet(float initialSpeed, Vector2 direction, GameplayObject Target, Ship_Game.Planet p) { this.direction = direction; this.Center = p.Position; this.zStart = -2500f; this.velocity = (initialSpeed * direction) + (this.owner != null ? this.owner.Velocity : Vector2.Zero); this.radius = 1f; this.velocityMaximum = initialSpeed + (this.owner != null ? this.owner.Velocity.Length() : 0f); this.duration = this.range / initialSpeed * 2f; this.initialDuration = this.duration; this.planet = p; if (this.weapon.Animated == 1) { this.switchFrames = this.initialDuration / (float)this.weapon.Frames; if (this.weapon.LoopAnimation == 1) { this.AnimationFrame = (int)((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(0f, (float)(this.weapon.Frames - 1)); } } Projectile projectile1 = this; projectile1.particleDelay = projectile1.particleDelay + this.weapon.particleDelay; if (this.weapon.Tag_Guided) { this.missileAI = new MissileAI(this); this.missileAI.SetTarget(Target); } if (this.ProjSO !=null &&(this.WeaponType == "Missile" || this.WeaponType == "Drone" || this.WeaponType == "Rocket") && (this.system != null && this.system.isVisible || this.isInDeepSpace)) { this.wasAddedToSceneGraph = true; lock (GlobalStats.ObjectManagerLocker) { Projectile.universeScreen.ScreenManager.inter.ObjectManager.Submit(this.ProjSO); } } if (this.system == null) { Projectile.universeScreen.DSProjectilesToAdd.Add(this); UniverseScreen.DeepSpaceManager.CollidableProjectiles.Add(this); } else { //lock (GlobalStats.BucketLock) { this.system.spatialManager.CollidableProjectiles.Add(this); this.system.spatialManager.RegisterObject(this); this.system.spatialManager.CollidableObjects.Add(this); } } base.Initialize(); }
protected virtual void CreateProjectilesFromPlanet(Vector2 direction, Planet p, GameplayObject target) { Projectile projectile = new Projectile(p, direction) { range = this.Range, weapon = this, explodes = this.explodes, damageAmount = this.DamageAmount }; if (this.RangeVariance) { projectile.range *= RandomMath.RandomBetween(0.9f, 1.1f); } projectile.explodes = this.explodes; projectile.damageRadius = this.DamageRadius; projectile.explosionradiusmod = this.ExplosionRadiusVisual; projectile.Health = this.HitPoints; projectile.speed = this.ProjectileSpeed; projectile.WeaponEffectType = this.WeaponEffectType; projectile.WeaponType = this.WeaponType; projectile.LoadContent(this.ProjectileTexturePath, this.ModelPath); projectile.RotationRadsPerSecond = this.RotationRadsPerSecond; projectile.ArmorPiercing = (byte)this.ArmourPen; /* if (this.ShieldPenChance > 0) { projectile.IgnoresShields = RandomMath.RandomBetween(0, 100) <= this.ShieldPenChance; } */ this.ModifyProjectile(projectile); if(this.Tag_Guided) projectile.InitializeMissilePlanet(projectile.speed, direction, target, p); else projectile.InitializePlanet(projectile.speed, direction, p.Position); projectile.Radius = this.ProjectileRadius; if (this.Animated == 1) { string remainder = 0.ToString("00000.##"); projectile.texturePath = string.Concat(this.AnimationPath, remainder); } p.Projectiles.Add(projectile); this.planetEmitter = new AudioEmitter() { Position = new Vector3(p.Position, 2500f) }; if (Weapon.universeScreen.viewState <= UniverseScreen.UnivScreenState.SystemView) { projectile.DieSound = true; if (!string.IsNullOrEmpty(this.ToggleSoundName) && !this.ToggleSoundOn) { this.ToggleSoundOn = true; this.ToggleCue = AudioManager.GetCue(this.ToggleSoundName); this.ToggleCue.Apply3D(Weapon.audioListener, this.planetEmitter); this.ToggleCue.Play(); this.lastFireSound = 0f; //Added by McShooterz: Use sounds from new sound dictionary if (ResourceManager.SoundEffectDict.ContainsKey(this.fireCueName)) { AudioManager.PlaySoundEffect(ResourceManager.SoundEffectDict[fireCueName], Weapon.audioListener, this.planetEmitter, 0.5f); } else { this.fireCue = AudioManager.GetCue(this.fireCueName); if (!this.owner.isPlayerShip()) { this.fireCue.Apply3D(Weapon.audioListener, this.planetEmitter); } if (this.fireCue != null) { this.fireCue.Play(); } } } if (!string.IsNullOrEmpty(ResourceManager.WeaponsDict[this.UID].dieCue)) { projectile.dieCueName = ResourceManager.WeaponsDict[this.UID].dieCue; } if (!string.IsNullOrEmpty(this.InFlightCue)) { projectile.InFlightCue = this.InFlightCue; } try { if (this.ToggleCue == null) { this.planetEmitter.Position = new Vector3(p.Position, -2500f); this.lastFireSound = 0f; //Added by McShooterz: Use sounds from new sound dictionary if (ResourceManager.SoundEffectDict.ContainsKey(this.fireCueName)) { AudioManager.PlaySoundEffect(ResourceManager.SoundEffectDict[fireCueName], Weapon.audioListener, this.planetEmitter, 0.5f); } else { this.fireCue = AudioManager.GetCue(this.fireCueName); this.fireCue.Apply3D(Weapon.audioListener, this.planetEmitter); if (this.fireCue != null) { this.fireCue.Play(); } } } } catch { } } }
public static void FireShieldAnimation(GameplayObject Obj, float Rotation, float Scale) { Shield shield = new Shield(); Matrix w = ((Matrix.Identity * Matrix.CreateScale(1f)) * Matrix.CreateRotationZ(Rotation)) * Matrix.CreateTranslation(Obj.Center.X, Obj.Center.Y, 0f); shield.World = w; shield.Owner = Obj; shield.displacement = ShieldManager.y; shield.texscale = ShieldManager.z; shield.Rotation = Rotation; ShieldManager.shieldList.Add(shield); }
protected virtual void CreateTargetedBeam(GameplayObject target) { Beam beam; //if (this.owner.Beams.pendingRemovals.TryPop(out beam)) //{ // //beam = new Beam(this.moduleAttachedTo.Center, this.BeamThickness, this.moduleAttachedTo.GetParent(), target); // beam.BeamRecreate(this.moduleAttachedTo.Center, this.BeamThickness, this.moduleAttachedTo.GetParent(), target); // beam.moduleAttachedTo = this.moduleAttachedTo; // beam.PowerCost = (float)this.BeamPowerCostPerSecond; // beam.range = this.Range; // beam.thickness = this.BeamThickness; // beam.Duration = (float)this.BeamDuration > 0 ? this.BeamDuration : 2f; // beam.damageAmount = this.DamageAmount; // beam.weapon = this; //} //else { beam = new Beam(this.moduleAttachedTo.Center, this.BeamThickness, this.moduleAttachedTo.GetParent(), target) { moduleAttachedTo = this.moduleAttachedTo, PowerCost = (float)this.BeamPowerCostPerSecond, range = this.Range, thickness = this.BeamThickness, Duration = (float)this.BeamDuration > 0 ? this.BeamDuration : 2f, damageAmount = this.DamageAmount, weapon = this, Destination=target.Center }; } //damage increase by level if (this.owner.Level > 0) { beam.damageAmount += beam.damageAmount * (float)this.owner.Level * 0.05f; } //Hull bonus damage increase if (GlobalStats.ActiveModInfo != null && GlobalStats.ActiveModInfo.useHullBonuses) { HullBonus mod; if (ResourceManager.HullBonuses.TryGetValue(this.owner.shipData.Hull, out mod)) beam.damageAmount += beam.damageAmount * mod.DamageBonus; } this.ModifyProjectile(beam); if ( !beam.LoadContent(Weapon.universeScreen.ScreenManager, Weapon.universeScreen.view, Weapon.universeScreen.projection)) { beam.Die(null, true); return; } this.moduleAttachedTo.GetParent().Beams.Add(beam); this.ToggleSoundOn = false; if (Weapon.universeScreen.viewState <= UniverseScreen.UnivScreenState.SystemView && this.moduleAttachedTo.GetParent().InFrustum) { //Added by McShooterz: Use sounds from new sound dictionary SoundEffect beamsound = null; if (ResourceManager.SoundEffectDict.TryGetValue(this.fireCueName,out beamsound)) { AudioManager.PlaySoundEffect(beamsound, Weapon.audioListener, this.owner.emitter, 0.5f); } else { if (!string.IsNullOrEmpty(this.fireCueName)) { this.fireCue = AudioManager.GetCue(this.fireCueName); if (!this.owner.isPlayerShip()) { this.fireCue.Apply3D(Weapon.audioListener, this.owner.emitter); } this.fireCue.Play(); } } if (!string.IsNullOrEmpty(this.ToggleSoundName)) { this.ToggleSoundOn = true; this.ToggleCue = AudioManager.GetCue(this.ToggleSoundName); this.ToggleCue.Apply3D(Weapon.audioListener, this.owner.emitter); this.ToggleCue.Play(); } } }
public override bool Damage(GameplayObject source, float damageAmount) { if (this.ModuleType == ShipModuleType.Dummy) { this.ParentOfDummy.Damage(source, damageAmount); return true; } this.Parent.InCombatTimer = 15f; this.Parent.ShieldRechargeTimer = 0f; //Added by McShooterz: Fix for Ponderous, now negative dodgemod increases damage taken. if (source is Projectile) { this.Parent.LastDamagedBy = source; if (this.Parent.Role == "fighter" && this.Parent.loyalty.data.Traits.DodgeMod < 0f) { damageAmount += damageAmount * Math.Abs(this.Parent.loyalty.data.Traits.DodgeMod); } } if (source is Ship && (source as Ship).Role == "fighter" && this.Parent.loyalty.data.Traits.DodgeMod < 0f) { damageAmount += damageAmount * Math.Abs(this.Parent.loyalty.data.Traits.DodgeMod); } //Added by McShooterz: shields keep charge when manually turned off if (this.shield_power <= 0f || shieldsOff || source is Projectile && (source as Projectile).IgnoresShields) { // Vulnerabilities and resistances for modules, XML-defined. if (source is Projectile && (source as Projectile).weapon.Tag_Kinetic) { damageAmount = damageAmount - (damageAmount * this.KineticResist); } if (source is Projectile && (source as Projectile).weapon.Tag_Energy) { damageAmount = damageAmount - (damageAmount * this.EnergyResist); } if (source is Projectile && (source as Projectile).weapon.Tag_Guided) { damageAmount = damageAmount - (damageAmount * this.GuidedResist); } if (source is Projectile && (source as Projectile).weapon.Tag_Missile) { damageAmount = damageAmount - (damageAmount * this.MissileResist); } if (source is Projectile && (source as Projectile).weapon.Tag_Hybrid) { damageAmount = damageAmount - (damageAmount * this.HybridResist); } if (source is Projectile && (source as Projectile).weapon.Tag_Intercept) { damageAmount = damageAmount - (damageAmount * this.InterceptResist); } if (source is Projectile && (source as Projectile).weapon.Tag_Explosive) { damageAmount = damageAmount - (damageAmount * this.ExplosiveResist); } if (source is Projectile && (source as Projectile).weapon.Tag_Railgun) { damageAmount = damageAmount - (damageAmount * this.RailgunResist); } if (source is Projectile && (source as Projectile).weapon.Tag_SpaceBomb) { damageAmount = damageAmount - (damageAmount * this.SpaceBombResist); } if (source is Projectile && (source as Projectile).weapon.Tag_Bomb) { damageAmount = damageAmount - (damageAmount * this.BombResist); } if (source is Projectile && (source as Projectile).weapon.Tag_BioWeapon) { damageAmount = damageAmount - (damageAmount * this.BioWeaponResist); } if (source is Projectile && (source as Projectile).weapon.Tag_Drone) { damageAmount = damageAmount - (damageAmount * this.DroneResist); } if (source is Projectile && (source as Projectile).weapon.Tag_Warp) { damageAmount = damageAmount - (damageAmount * this.WarpResist); } if (source is Projectile && (source as Projectile).weapon.Tag_Torpedo) { damageAmount = damageAmount - (damageAmount * this.TorpedoResist); } if (source is Projectile && (source as Projectile).weapon.Tag_Cannon) { damageAmount = damageAmount - (damageAmount * this.CannonResist); } if (source is Projectile && (source as Projectile).weapon.Tag_Subspace) { damageAmount = damageAmount - (damageAmount * this.SubspaceResist); } if (source is Projectile && (source as Projectile).weapon.Tag_PD) { damageAmount = damageAmount - (damageAmount * this.PDResist); } if (source is Projectile && (source as Projectile).weapon.Tag_Flak) { damageAmount = damageAmount - (damageAmount * this.FlakResist); } if (source is Beam && (source as Beam).weapon.Tag_Beam) { damageAmount = damageAmount - (damageAmount * this.BeamResist); // most of these simply don't apply to beam weapons, but calculated within this if to ensure different beam types also have resistances/vulnerabilities applied if ((source as Beam).weapon.Tag_Kinetic) { damageAmount = damageAmount - (damageAmount * this.KineticResist); } if ((source as Beam).weapon.Tag_Energy) { damageAmount = damageAmount - (damageAmount * this.EnergyResist); } if ((source as Beam).weapon.Tag_Guided) { damageAmount = damageAmount - (damageAmount * this.GuidedResist); } if ((source as Beam).weapon.Tag_Missile) { damageAmount = damageAmount - (damageAmount * this.MissileResist); } if ((source as Beam).weapon.Tag_Hybrid) { damageAmount = damageAmount - (damageAmount * this.HybridResist); } if ((source as Beam).weapon.Tag_Intercept) { damageAmount = damageAmount - (damageAmount * this.InterceptResist); } if ((source as Beam).weapon.Tag_Explosive) { damageAmount = damageAmount - (damageAmount * this.ExplosiveResist); } if ((source as Beam).weapon.Tag_Railgun) { damageAmount = damageAmount - (damageAmount * this.RailgunResist); } if ((source as Beam).weapon.Tag_SpaceBomb) { damageAmount = damageAmount - (damageAmount * this.SpaceBombResist); } if ((source as Beam).weapon.Tag_Bomb) { damageAmount = damageAmount - (damageAmount * this.BombResist); } if ((source as Beam).weapon.Tag_BioWeapon) { damageAmount = damageAmount - (damageAmount * this.BioWeaponResist); } if ((source as Beam).weapon.Tag_Drone) { damageAmount = damageAmount - (damageAmount * this.DroneResist); } if ((source as Beam).weapon.Tag_Warp) { damageAmount = damageAmount - (damageAmount * this.WarpResist); } if ((source as Beam).weapon.Tag_Torpedo) { damageAmount = damageAmount - (damageAmount * this.TorpedoResist); } if ((source as Beam).weapon.Tag_Cannon) { damageAmount = damageAmount - (damageAmount * this.CannonResist); } if ((source as Beam).weapon.Tag_Subspace) { damageAmount = damageAmount - (damageAmount * this.SubspaceResist); } if ((source as Beam).weapon.Tag_PD) { damageAmount = damageAmount - (damageAmount * this.PDResist); } if ((source as Beam).weapon.Tag_Flak) { damageAmount = damageAmount - (damageAmount * this.FlakResist); } } //Doc: If the resistance-modified damage amount is less than an armour's damage threshold, no damage is applied. if (damageAmount <= this.DamageThreshold) damageAmount = 0f; //Added by McShooterz: ArmorBonus Hull Bonus if (GlobalStats.ActiveModInfo != null && GlobalStats.ActiveModInfo.useHullBonuses) { HullBonus mod; if (ResourceManager.HullBonuses.TryGetValue(this.GetParent().shipData.Hull, out mod)) damageAmount *= (1f - mod.ArmoredBonus); } if (source is Projectile && (source as Projectile).weapon.EMPDamage > 0f) { Ship parent = this.Parent; parent.EMPDamage = parent.EMPDamage + (source as Projectile).weapon.EMPDamage; } if (source is Beam) { Vector2 vel = Vector2.Normalize((source as Beam).Source - this.Center); if (RandomMath.RandomBetween(0f, 100f) > 90f && this.Parent.InFrustum) { ShipModule.universeScreen.flash.AddParticleThreadB(new Vector3((source as Beam).ActualHitDestination, this.Center3D.Z), Vector3.Zero); } if (this.Parent.InFrustum) { for (int i = 0; i < 20; i++) { ShipModule.universeScreen.sparks.AddParticleThreadB(new Vector3((source as Beam).ActualHitDestination, this.Center3D.Z), new Vector3(vel * RandomMath.RandomBetween(40f, 80f), RandomMath.RandomBetween(-25f, 25f))); } } if ((source as Beam).weapon.PowerDamage > 0f) { this.Parent.PowerCurrent -= (source as Beam).weapon.PowerDamage; if (this.Parent.PowerCurrent < 0f) { this.Parent.PowerCurrent = 0f; } } if ((source as Beam).weapon.TroopDamageChance > 0f) { if (this.Parent.TroopList.Count > 0) { if (((this.Parent.GetSystem() != null ? this.Parent.GetSystem().RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(0f, 100f) < (source as Beam).weapon.TroopDamageChance) { Troop item = this.Parent.TroopList[0]; item.Strength = item.Strength - 1; if (this.Parent.TroopList[0].Strength <= 0) { this.Parent.TroopList.RemoveAt(0); } } } else if (this.Parent.MechanicalBoardingDefense > 0f && RandomMath.RandomBetween(0f, 100f) < (source as Beam).weapon.TroopDamageChance) { this.Parent.MechanicalBoardingDefense -= 1f; } } if ((source as Beam).weapon.MassDamage > 0f) { this.Parent.Mass += (source as Beam).weapon.MassDamage; this.Parent.velocityMaximum = this.Parent.Thrust / this.Parent.Mass; this.Parent.speed = this.Parent.velocityMaximum; this.Parent.rotationRadiansPerSecond = this.Parent.speed / 700f; } if ((source as Beam).weapon.RepulsionDamage > 0f) { Vector2 vtt = this.Center - (source as Beam).Owner.Center; Ship velocity = this.Parent; this.Parent.Velocity += (vtt * (source as Beam).weapon.RepulsionDamage) / this.Parent.Mass; } } if (this.shield_power_max > 0f && !this.isExternal) { return false; } if (this.ModuleType == ShipModuleType.Armor && source is Projectile) { if ((source as Projectile).isSecondary) { Weapon shooter = (source as Projectile).weapon; ResourceManager.WeaponsDict.TryGetValue(shooter.SecondaryFire, out shooter); damageAmount *= shooter.EffectVsArmor; //damageAmount *= (ResourceManager.GetWeapon(shooter.SecondaryFire).EffectVsArmor); } else { damageAmount *= (source as Projectile).weapon.EffectVsArmor; } } else if (this.ModuleType == ShipModuleType.Armor && source is Beam) { damageAmount *= (source as Beam).weapon.EffectVsArmor; } if (damageAmount > this.Health) { this.Health = 0; } else { this.Health -= damageAmount; } if (base.Health >= this.HealthMax) { base.Health = this.HealthMax; this.Active = true; this.onFire = false; } if (base.Health / this.HealthMax < 0.5f) { this.onFire = true; } if ((double)(this.Parent.Health / this.Parent.HealthMax) < 0.5 && (double)base.Health < 0.5 * (double)this.HealthMax) { this.reallyFuckedUp = true; } foreach (ShipModule dummy in this.LinkedModulesList) { dummy.DamageDummy(damageAmount); } } else { //Damage module health if shields fail from damage float damageAmountvsShields = damageAmount; if (source is Projectile) { if ((source as Projectile).isSecondary) { Weapon shooter = (source as Projectile).weapon; ResourceManager.WeaponsDict.TryGetValue(shooter.SecondaryFire, out shooter); damageAmountvsShields *= shooter.EffectVSShields; //damageAmountvsShields *= (ResourceManager.GetWeapon(shooter.SecondaryFire).EffectVSShields); } else { damageAmountvsShields *= (source as Projectile).weapon.EffectVSShields; } } else if (source is Beam) { damageAmountvsShields *= (source as Beam).weapon.EffectVSShields; } if (source is Projectile) { if ((source as Projectile).weapon.Tag_Kinetic) { damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_kinetic_resist); } if ((source as Projectile).weapon.Tag_Energy) { damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_energy_resist); } if ((source as Projectile).weapon.Tag_Explosive) { damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_explosive_resist); } if ((source as Projectile).weapon.Tag_Missile) { damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_missile_resist); } if ((source as Projectile).weapon.Tag_Flak) { damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_flak_resist); } if ((source as Projectile).weapon.Tag_Hybrid) { damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_hybrid_resist); } if ((source as Projectile).weapon.Tag_Railgun) { damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_railgun_resist); } if ((source as Projectile).weapon.Tag_Subspace) { damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_subspace_resist); } if ((source as Projectile).weapon.Tag_Warp) { damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_warp_resist); } } else if (source is Beam) { if ((source as Beam).weapon.Tag_Kinetic) { damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_kinetic_resist); } if ((source as Beam).weapon.Tag_Energy) { damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_energy_resist); } if ((source as Beam).weapon.Tag_Explosive) { damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_explosive_resist); } if ((source as Beam).weapon.Tag_Missile) { damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_missile_resist); } if ((source as Beam).weapon.Tag_Flak) { damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_flak_resist); } if ((source as Beam).weapon.Tag_Hybrid) { damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_hybrid_resist); } if ((source as Beam).weapon.Tag_Railgun) { damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_railgun_resist); } if ((source as Beam).weapon.Tag_Subspace) { damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_subspace_resist); } if ((source as Beam).weapon.Tag_Warp) { damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_warp_resist); } } if (damageAmountvsShields <= this.shield_threshold) damageAmountvsShields = 0f; if (damageAmountvsShields > this.shield_power) { this.shield_power = 0; this.Parent.UpdateShields(); } else { this.shield_power -= damageAmountvsShields; this.Parent.UpdateShields(); } if (ShipModule.universeScreen.viewState == UniverseScreen.UnivScreenState.ShipView && this.Parent.InFrustum) { base.findAngleToTarget(this.Parent.Center, source.Center); this.shield.Rotation = source.Rotation - 3.14159274f; this.shield.displacement = 0f; this.shield.texscale = 2.8f; lock (GlobalStats.ObjectManagerLocker) { ShipModule.universeScreen.ScreenManager.inter.LightManager.Remove(this.shield.pointLight); ShipModule.universeScreen.ScreenManager.inter.LightManager.Submit(this.shield.pointLight); } if (source is Beam) { if ((source as Beam).weapon.SiphonDamage > 0f) { this.shield_power -= (source as Beam).weapon.SiphonDamage; if (this.shield_power < 0f) { this.shield_power = 0f; } (source as Beam).owner.PowerCurrent += (source as Beam).weapon.SiphonDamage; if ((source as Beam).owner.PowerCurrent > (source as Beam).owner.PowerStoreMax) { (source as Beam).owner.PowerCurrent = (source as Beam).owner.PowerStoreMax; } } this.shield.Rotation = MathHelper.ToRadians(HelperFunctions.findAngleToTarget(this.Center, (source as Beam).Source)); this.shield.pointLight.World = Matrix.CreateTranslation(new Vector3((source as Beam).ActualHitDestination, 0f)); this.shield.pointLight.DiffuseColor = new Vector3(0.5f, 0.5f, 1f); this.shield.pointLight.Radius = this.shield_radius * 2f; this.shield.pointLight.Intensity = RandomMath.RandomBetween(4f, 10f); this.shield.displacement = 0f; this.shield.Radius = this.radius; this.shield.displacement = 0.085f * RandomMath.RandomBetween(1f, 10f); this.shield.texscale = 2.8f; this.shield.texscale = 2.8f - 0.185f * RandomMath.RandomBetween(1f, 10f); this.shield.pointLight.Enabled = true; Vector2 vel = (source as Beam).Source - this.Center; vel = Vector2.Normalize(vel); if (RandomMath.RandomBetween(0f, 100f) > 90f && this.Parent.InFrustum) { ShipModule.universeScreen.flash.AddParticleThreadA(new Vector3((source as Beam).ActualHitDestination, this.Center3D.Z), Vector3.Zero); } if (this.Parent.InFrustum) { for (int i = 0; i < 20; i++) { ShipModule.universeScreen.sparks.AddParticleThreadA(new Vector3((source as Beam).ActualHitDestination, this.Center3D.Z), new Vector3(vel * RandomMath.RandomBetween(40f, 80f), RandomMath.RandomBetween(-25f, 25f))); } } if ((source as Beam).weapon.SiphonDamage > 0f) { this.shield_power -= (source as Beam).weapon.SiphonDamage; if (this.shield_power < 0f) { this.shield_power = 0f; } } } else if (source is Projectile && !(source as Projectile).IgnoresShields && this.Parent.InFrustum) { Cue shieldcue = AudioManager.GetCue("sd_impact_shield_01"); shieldcue.Apply3D(ShipModule.universeScreen.listener, this.Parent.emitter); shieldcue.Play(); this.shield.Radius = this.radius; this.shield.displacement = 0.085f * RandomMath.RandomBetween(1f, 10f); this.shield.texscale = 2.8f; this.shield.texscale = 2.8f - 0.185f * RandomMath.RandomBetween(1f, 10f); this.shield.pointLight.World = (source as Projectile).GetWorld(); this.shield.pointLight.DiffuseColor = new Vector3(0.5f, 0.5f, 1f); this.shield.pointLight.Radius = this.radius; this.shield.pointLight.Intensity = 8f; this.shield.pointLight.Enabled = true; Vector2 vel = Vector2.Normalize((source as Projectile).Center - this.Center); ShipModule.universeScreen.flash.AddParticleThreadB(new Vector3((source as Projectile).Center, this.Center3D.Z), Vector3.Zero); for (int i = 0; i < 20; i++) { ShipModule.universeScreen.sparks.AddParticleThreadB(new Vector3((source as Projectile).Center, this.Center3D.Z), new Vector3(vel * RandomMath.RandomBetween(40f, 80f), RandomMath.RandomBetween(-25f, 25f))); } } } } //Added by McShooterz: shields keep charge when manually turned off if (this.shield_power > 0f && !shieldsOff) { this.radius = this.shield_radius; } else { this.radius = 8f; } return true; }
public virtual void Fire(Vector2 direction, GameplayObject target) { if (this.owner.engineState == Ship.MoveState.Warp || this.timeToNextFire > 0f ||! this.owner.CheckRangeToTarget(this,target)) return; this.owner.InCombatTimer = 15f; this.timeToNextFire = this.fireDelay; if (this.moduleAttachedTo.Active && this.owner.PowerCurrent > this.PowerRequiredToFire && this.OrdinanceRequiredToFire <= this.owner.Ordinance) { //this.owner.supplyLock.EnterWriteLock(); this.owner.Ordinance -= this.OrdinanceRequiredToFire; this.owner.PowerCurrent -= this.PowerRequiredToFire; //this.owner.supplyLock.ExitWriteLock(); if (this.SalvoCount == 1) { if (this.FireArc != 0) { float DegreesBetweenShots = (float)(this.FireArc / this.ProjectileCount); float angleToTarget = this.findAngleToTarget(direction); for (int i = 0; i < this.ProjectileCount; i++) { Vector2 newTarget = this.findTargetFromAngleAndDistance(this.moduleAttachedTo.Center, angleToTarget - (float)(this.FireArc / 2) + DegreesBetweenShots * (float)i, this.Range); Vector2 fireDirection = this.findVectorToTarget(this.moduleAttachedTo.Center, newTarget); fireDirection.Y = fireDirection.Y * -1f; this.CreateProjectiles(Vector2.Normalize(fireDirection), target, true); } return; } if (this.FireCone <= 0) { for (int i = 0; i < this.ProjectileCount; i++) { this.CreateProjectiles(direction, target, true); } return; } float spread = RandomMath2.RandomBetween((float)(-this.FireCone / 2), (float)(this.FireCone / 2)); //renamed angletotarget,newtarget,firedirection float angleToTarget2 = this.findAngleToTarget(direction); Vector2 newTarget2 = this.findTargetFromAngleAndDistance(this.moduleAttachedTo.Center, angleToTarget2 + spread, this.Range); Vector2 fireDirection2 = this.findVectorToTarget(this.moduleAttachedTo.Center, newTarget2); fireDirection2.Y = fireDirection2.Y * -1f; this.CreateProjectiles(Vector2.Normalize(fireDirection2), target, true); return; } if (this.SalvoCount > 1) { float TimeBetweenShots = this.SalvoTimer / (float)this.SalvoCount; for (int j = 1; j < this.SalvoCount; j++) { Weapon.Salvo sal = new Weapon.Salvo() { Timing = (float)j * TimeBetweenShots, Direction = direction }; this.SalvoList.Add(sal); } this.SalvoTarget = target; if (this.FireArc != 0) { float DegreesBetweenShots = (float)(this.FireArc / this.ProjectileCount); float angleToTarget = this.findAngleToTarget(direction); for (int i = 0; i < this.ProjectileCount; i++) { Vector2 newTarget = this.findTargetFromAngleAndDistance(this.moduleAttachedTo.Center, angleToTarget - (float)(this.FireArc / 2) + DegreesBetweenShots * (float)i, this.Range); Vector2 fireDirection = this.findVectorToTarget(this.moduleAttachedTo.Center, newTarget); fireDirection.Y = fireDirection.Y * -1f; this.CreateProjectiles(Vector2.Normalize(fireDirection), target, true); } return; } if (this.FireCone > 0) { float spread = RandomMath2.RandomBetween((float)(-this.FireCone / 2), (float)(this.FireCone / 2)); float angleToTarget = this.findAngleToTarget(direction); Vector2 newTarget = this.findTargetFromAngleAndDistance(this.moduleAttachedTo.Center, angleToTarget + spread, this.Range); Vector2 fireDirection = this.findVectorToTarget(this.moduleAttachedTo.Center, newTarget); fireDirection.Y = fireDirection.Y * -1f; this.CreateProjectiles(Vector2.Normalize(fireDirection), target, true); return; } for (int i = 0; i < this.ProjectileCount; i++) { this.CreateProjectiles(direction, target, true); } return; } } }