Exemplo n.º 1
0
 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);
        }
Exemplo n.º 4
0
        /*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);
        }
Exemplo n.º 5
0
        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);
        }
Exemplo n.º 6
0
        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);
        }