예제 #1
0
        private void HitPerson(Soldier s)
        {
            // Pick target
            ArrayList targets = new ArrayList();
            int       st      = 0;
            int       en      = Soldiers.Count - 1;

            if (s.Side == Side.Attacker)
            {
                st = FirstDefender;
            }
            else
            {
                en = FirstDefender - 1;
            }

            if (s.Weapon.Ranged)
            {
                // Ranged weapons
                for (int pass = 1; pass <= 3; pass++)
                {
                    for (int j = st; j <= en; j++)
                    {
                        Soldier tg = (Soldier)Soldiers[j];

                        // Ranged weapons does not target units inside buildings
                        if (tg.OutOfAction || tg.Building != null)
                        {
                            continue;
                        }

                        // Fleeing persons and chosen attacked last
                        if (pass == 1 && (tg.Flee || tg.Person.Chosen))
                        {
                            continue;
                        }
                        if (pass == 2 && tg.Person.Chosen)
                        {
                            continue;
                        }
                        targets.Add(tg);
                    }

                    if (targets.Count > 0)
                    {
                        break;
                    }
                }
            }
            else
            {
                // Melee weapons
                // If soldier inside building, go out
                if (s.Building != null)
                {
                    BattleReport.Add(String.Format("{0} goes out.|{1} выходит наружу.",
                                                   s.Person.ToString(Lang.En), s.Person.ToString(Lang.Ru)));
                    s.Building = null;
                }

                // Pick target
                for (int pass = 1; pass <= 2; pass++)
                {
                    for (int j = st; j <= en; j++)
                    {
                        Soldier tg = (Soldier)Soldiers[j];
                        if (tg.OutOfAction)
                        {
                            continue;
                        }
                        if (pass == 1 && tg.Person.Chosen)
                        {
                            continue;
                        }
                        targets.Add(tg);
                    }

                    if (targets.Count > 0)
                    {
                        break;
                    }
                }
            }

            // Noone to attack
            if (targets.Count == 0)
            {
                throw new NoTargetException();
            }

            Soldier target = (Soldier)targets[Constants.Random(targets.Count)];

            HitEvent evt = new HitEvent(s.Person, target.Person);

            BattleReport.Add(evt);

            // Roll to hit
            if (!RollToHit(s, evt))
            {
                return;
            }

            if (!s.Weapon.Ranged && (target.Weapon != null && !target.Weapon.Ranged))
            {
                // Roll to parry
                int parry_roll = Constants.Random(100);
                if (parry_roll == 99)
                {
                    evt.Results.Add(HitEvent.Code.CriticalBlock);
                    return;
                }
                if (parry_roll == 0)
                {
                    evt.Results.Add(HitEvent.Code.CriticalBlockFail);
                }
                else
                {
                    if (target.SkillLevel > parry_roll)
                    {
                        evt.Results.Add(HitEvent.Code.Block);
                        return;
                    }
                }
            }

            // Anti-tank weapons ignore wound rolls and armor save
            if (!s.Weapon.AntiTank)
            {
                // Armor save
                int save_roll = Constants.Random(100);
                if (save_roll == 99)
                {
                    evt.Results.Add(HitEvent.Code.CriticalSave);
                    return;
                }
                if (save_roll == 0)
                {
                    evt.Results.Add(HitEvent.Code.CriticalSaveFail);
                }
                else
                {
                    if (s.Weapon != null)
                    {
                        save_roll -= s.Weapon.ArmorModifier;
                    }
                    if (target.Armor != null && save_roll < target.Armor.ArmorSave)
                    {
                        evt.Results.Add(HitEvent.Code.ArmorSave);
                        return;
                    }
                }

                // Roll to wound
                if (!RollToWound(s, evt))
                {
                    return;
                }
            }

            // Target is hit
            KillTarget(s, target, evt);
        }
예제 #2
0
        private void ExplodeTank(Soldier s)
        {
            // Pick target
            Building target = TargetBuilding(s);

            // If no buildings to attack, flee
            if (target == null)
            {
                s.Flee = true;
                throw new NoTargetException();
            }

            HitEvent evt = new HitEvent(s.Person, target);

            BattleReport.Add(evt);

            // Roll to hit
            if (!RollToHit(s, evt))
            {
                return;
            }

            // Target is hit, explode
            evt.Results.Add(HitEvent.Code.Exploded);
            target.Damage();

            // Hit soldiers
            ArrayList targets = new ArrayList();

            foreach (Soldier s2 in Soldiers)
            {
                if (s2.Building == target)
                {
                    targets.Add(s2);
                }
            }
            int escape_roll = Constants.Random(100);

            if (escape_roll < s.SkillLevel)
            {
                targets.Add(s);
            }

            foreach (Soldier s2 in targets)
            {
                s2.Building = null;

                // Roll to wound
                int towound_roll = Constants.Random(100);
                if (towound_roll == 99)
                {
                    continue;
                }
                if (towound_roll > 0 && towound_roll >= s.Weapon.ToWound)
                {
                    continue;
                }

                // Incapacitate target
                KillTarget(s, s2, evt);
            }

            s.Person.Items.RemoveItems(s.Weapon, 1);
            s.Flee = true;
        }
예제 #3
0
        private void Run()
        {
            ArrayList reflexes = new ArrayList();

            foreach (Soldier s in Soldiers)
            {
                if (!reflexes.Contains(s.Reflexes))
                {
                    reflexes.Add(s.Reflexes);
                }
            }
            reflexes.Sort();

            for (int turn = 1; turn <= 50; turn++)
            {
                bool shooters = (turn == 1 && ShootersPresent());
                BattleReport.Add("");
                BattleReport.Add(String.Format("Round {0}{1}|Раунд {0}{2}",
                                               turn.ToString(),
                                               (shooters ? " (ranged only)" : ""),
                                               (shooters ? " (только стрелки)" : "")
                                               ));

                // Process all soldiers in order of reflexes
                bool attackers_moved = false;
                bool defenders_moved = false;
                for (int i = reflexes.Count - 1; i >= 0; i--)
                {
                    ArrayList acting = new ArrayList();
                    foreach (Soldier s in Soldiers)
                    {
                        if (s.Reflexes == (int)reflexes[i])
                        {
                            acting.Add(s);
                        }
                    }

                    while (acting.Count > 0)
                    {
                        int     idx = Constants.Random(acting.Count);
                        Soldier s   = (Soldier)acting[idx];
                        if (!s.OutOfAction)
                        {
                            try
                            {
                                MoveSoldier(s, turn);
                                if (s.Side == Side.Attacker)
                                {
                                    attackers_moved = true;
                                }
                                else
                                {
                                    defenders_moved = true;
                                }
                            }
                            catch (NoTargetException)
                            {
                                BattleReport.Add(String.Format("{0}: can't attack anybody.|{1}: не может никого атаковать.",
                                                               s.Person.ToString(Lang.En), s.Person.ToString(Lang.Ru)));
                            }
                        }
                        acting.RemoveAt(idx);

                        if (BattleEnded())
                        {
                            return;
                        }
                    }
                }

                if (turn > 1)
                {
                    if (!attackers_moved)
                    {
                        BattleReport.Add("Attackers panicked and ran away.|Атакующие запаниковали и убегают.");
                        for (int i = 0; i < FirstDefender; i++)
                        {
                            ((Soldier)Soldiers[i]).Flee = true;
                        }
                    }
                    if (!defenders_moved)
                    {
                        BattleReport.Add("Defenders panicked and ran away.|Защитники запаниковали и убегают.");
                        for (int i = FirstDefender; i < Soldiers.Count; i++)
                        {
                            ((Soldier)Soldiers[i]).Flee = true;
                        }
                    }
                }
            }
        }
예제 #4
0
        private void MoveSoldier(Soldier s, int round)
        {
            if (s.Weapon == null || s.SkillLevel == 0 || s.Person.Avoiding)
            {
                s.Flee = true;
            }

            if (s.Flee)
            {
                OOASoldier(s);
                s.FleedAway = true;
                BattleReport.Add(String.Format("{0} ran away from combat.|{1} убегает из боя.",
                                               s.Person.ToString(Lang.En), s.Person.ToString(Lang.Ru)));
                return;
            }

            // First turn is for ranged weapon only if shooters on field
            if (round == 1 && ShootersPresent() && !s.Weapon.Ranged)
            {
                return;
            }

            for (int i = 0; i < s.Weapon.Attacks; i++)
            {
                if (OutOfAmmo(s))
                {
                    break;
                }

                for (int j = 0; j < s.Weapon.Targets; j++)
                {
                    MakeHit(s);
                    if (BattleEnded())
                    {
                        break;
                    }
                }

                if (s.Ammo > 0)
                {
                    s.Ammo--;
                }
                if (s.Weapon.Ammo != null)
                {
                    if (s.Weapon.Ammo.Case != null)
                    {
                        Spoils.AddItems(s.Weapon.Ammo.Case, 1);
                    }
                    s.Person.Items.RemoveItems(s.Weapon.Ammo, 1);
                }
                if (OutOfAmmo(s))
                {
                    break;
                }

                if (BattleEnded())
                {
                    break;
                }
            }
        }
예제 #5
0
        private void PrintSoldier(Soldier soldier)
        {
            // En
            string s = soldier.Person.ToString(Lang.En);

            if (!soldier.Person.HideFaction && soldier.Person.Faction != null)
            {
                s += ", " + soldier.Person.Faction.ToString(Lang.En);
            }
            if (soldier.Person.Avoiding)
            {
                s += ", avoiding";
            }
            if (soldier.Weapon != null)
            {
                if (soldier.Weapon.IsMan)
                {
                    s += ", unarmed";
                }
                else
                {
                    s += ", " + soldier.Weapon.ToString(1, Lang.En);
                }
                if (soldier.Weapon.Ammo != null)
                {
                    s += " (ammo: " + soldier.Ammo.ToString() + ")";
                }
            }
            if (soldier.Armor != null && !soldier.Armor.IsMan)
            {
                s += ", " + soldier.Armor.ToString(1, Lang.En);
            }
            s += ", skill " + soldier.SkillLevel.ToString();
            s += ", reflexes " + soldier.Reflexes;
            if (soldier.Building != null)
            {
                s += ", inside " + soldier.Building.ToString(Lang.En) + " (" +
                     Hits[soldier.Building].ToString() + " hp)";
            }
            s += ".";

            // Ru
            s += "|" + soldier.Person.ToString(Lang.Ru);
            if (!soldier.Person.HideFaction && soldier.Person.Faction != null)
            {
                s += ", " + soldier.Person.Faction.ToString(Lang.Ru);
            }
            if (soldier.Person.Avoiding)
            {
                s += ", избегает боя";
            }
            if (soldier.Weapon != null)
            {
                if (soldier.Weapon.IsMan)
                {
                    s += ", без оружия";
                }
                else
                {
                    s += ", " + soldier.Weapon.ToString(1, Lang.Ru);
                }
                if (soldier.Weapon.Ammo != null)
                {
                    s += " (заряды: " + soldier.Ammo.ToString() + ")";
                }
            }
            if (soldier.Armor != null && !soldier.Armor.IsMan)
            {
                s += ", " + soldier.Armor.ToString(1, Lang.Ru);
            }
            s += ", навык " + soldier.SkillLevel.ToString();
            s += ", рефлексы " + soldier.Reflexes;
            if (soldier.Building != null)
            {
                s += ", объект: " + soldier.Building.ToString(Lang.Ru) + " (" +
                     Hits[soldier.Building].ToString() + " хитов)";
            }
            s += ".";

            BattleReport.Add(s);
        }