Exemplo n.º 1
0
        private bool RollToHit(Soldier s, HitEvent evt)
        {
            int tohit_roll = Constants.Random(100);

            if (tohit_roll == 0)
            {
                evt.Results.Add(HitEvent.Code.CriticalHitFail);
                return(false);
            }
            if (tohit_roll == 99)
            {
                evt.Results.Add(HitEvent.Code.CriticalHit);
            }
            else
            {
                tohit_roll -= s.Weapon.HitModifier;
                if (tohit_roll >= s.SkillLevel)
                {
                    evt.Results.Add(HitEvent.Code.NoHit);
                    return(false);
                }
            }
            return(true);
        }
Exemplo n.º 2
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);
        }
Exemplo n.º 3
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;
        }