private void doLaunchProjectile(Combatant attacker, AbilityStats abilityStats, double quantity, Combatant target) { this.game.Projectiles.Add(new Projectile( attacker.Owner, (long)quantity, abilityStats, target, attacker.Position )); }
private double doDirectAttack(Combatant attacker, AbilityStats abilityStats, double quantity, Combatant target) { var targetStats = this.mainGame.Derivates.Of(target.Owner).DesignStats[target.Ships.Design]; var spent = 0.0; while (quantity > spent && target.Ships.Quantity > 0) { spent = +attackTop(attacker, abilityStats, quantity - spent, target, targetStats); } //TODO(later) do different calculation for multiple ships below top of the stack return(spent); }
private double attackTop(Combatant attacker, AbilityStats abilityStats, double quantity, Combatant target, DesignStats targetStats) { var distance = Methods.HexDistance(attacker.Position, target.Position); var detection = sensorStrength(target.Position, attacker.Owner); var targetStealth = targetStats.Jamming + (target.CloakedFor.Contains(attacker.Owner) ? this.mainGame.Statics.ShipFormulas.NaturalCloakBonus : 0); var spent = 0.0; while (target.HitPoints > 0 && quantity > spent) { spent++; if (targetStealth > detection && Math.Pow(sigmoidBase, targetStealth - detection) > this.game.Rng.NextDouble()) { continue; } if (Probability(abilityStats.Accuracy - targetStats.Evasion + distance * abilityStats.AccuracyRangePenalty) < this.game.Rng.NextDouble()) { continue; } double firePower = abilityStats.FirePower; if (target.ShieldPoints > 0) { double shieldFire = firePower - Reduce(firePower, targetStats.ShieldThickness, abilityStats.ShieldEfficiency); double shieldDamage = Reduce(shieldFire, targetStats.ShieldReduction, 1); firePower -= shieldFire - shieldDamage; //damage reduction difference shieldDamage = Math.Min(shieldDamage, target.ShieldPoints); target.ShieldPoints -= shieldDamage; firePower -= shieldDamage; } double armorDamage = Reduce(firePower, targetStats.ArmorReduction, abilityStats.ArmorEfficiency); target.HitPoints -= armorDamage; } if (target.HitPoints <= 0) { target.Ships.Quantity--; target.HitPoints = targetStats.HitPoints; target.ShieldPoints = targetStats.ShieldPoints; } return(spent); }
/*TODO(later) add methods for attacking other kind of targets, * extrude functionality form UseAbiliy methods in SpaceBattleProcessor */ protected static double attackPlanet(AbilityStats abilityStats, double quantity, CombatPlanet planet) { var spent = 0.0; if (abilityStats.IsInstantDamage && planet.Colony != null) { var killsPerShot = abilityStats.FirePower / planet.PopulationHitPoints; var casualties = Math.Min(quantity * killsPerShot, planet.Colony.Population); //TODO(later) factor in shields and armor //TODO(later) roll for target, building or population planet.Colony.Population -= casualties; spent = Math.Ceiling(casualties / killsPerShot); } return(spent); }
private long doProjectileAttack(Player attackSide, AbilityStats abilityStats, double quantity, IEnumerable <Combatant> targetOrder) { var targets = targetOrder.ToArray(); var targetStats = targets. Select(x => this.mainGame.Derivates[x.Owner].DesignStats[x.Ships.Design]). ToList(); var mainTarget = targets[0]; var hitChance = chanceToHit( abilityStats.Accuracy, sensorStrength(mainTarget.Position, attackSide), targetStats[0], mainTarget.CloakedFor.Contains(attackSide)); long spent = 0; while (quantity > spent && targets[0].Ships.Quantity > 0) { spent++; var splashTargets = abilityStats.SplashMaxTargets; for (int i = 0; i < targets.Length; i++) { bool hit = (i == 0) && hitChance > this.game.Rng.NextDouble(); if (hit) { doTopDamage(abilityStats.FirePower, abilityStats.ShieldEfficiency, abilityStats.ArmorEfficiency, targets[i], targetStats[i]); } else if (splashTargets > 0) { doTopDamage(abilityStats.SplashFirePower, abilityStats.SplashShieldEfficiency, abilityStats.SplashArmorEfficiency, targets[i], targetStats[i]); } doRestDamage( splashTargets - 1, abilityStats.SplashFirePower, abilityStats.SplashShieldEfficiency, abilityStats.SplashArmorEfficiency, targets[i], targetStats[i]); splashTargets -= Methods.Clamp(splashTargets, 0, Math.Max(targets[i].Ships.Quantity, 0)); updateStackTop(targets[i]); } } return(spent); }
private double doDirectAttack(Player attackSide, Vector2D attackFrom, AbilityStats abilityStats, double quantity, Combatant target) { var targetStats = this.mainGame.Derivates[target.Owner].DesignStats[target.Ships.Design]; var hitChance = chanceToHit( abilityStats.Accuracy + Methods.HexDistance(attackFrom, target.Position) * abilityStats.AccuracyRangePenalty, sensorStrength(target.Position, attackSide), targetStats, target.CloakedFor.Contains(attackSide)); var spent = 0.0; while (quantity > spent && target.Ships.Quantity > 0) { spent++; if (hitChance > this.game.Rng.NextDouble()) { doTopDamage(abilityStats.FirePower, abilityStats.ShieldEfficiency, abilityStats.ArmorEfficiency, target, targetStats); updateStackTop(target); } } //TODO(later) do different calculation for multiple ships below top of the stack return(spent); }