public Battle()
 {
     ID = sCounter++;
     fighters = new List<Fighter>();
     turnQueue = new Queue<Fighter>();
     currentFighter = null;
 }
        public bool Step()
        {
            // Check battle end conditions
            if (checkEnd()) {
                Ended(this, EventArgs.Empty);
                return false;
            }

            // Fill the turn queue and sort it by speed
            if (turnQueue.Count() == 0) {
                if (fighters.Count() == 0) {
                    return true;
                }

                turnQueue = new Queue<Fighter>(fighters);
                turnQueue.OrderBy(fighter => fighter.Stats.Speed);
            }

            // Assign first fighter
            if (currentFighter == null) {
                currentFighter = turnQueue.Dequeue();
                currentFighter.PreStep();
            } else if (!currentFighter.IsAlive() || currentFighter.Step(this)) {
                currentFighter = null;
            }

            return false;
        }
 public void AddFighter(Fighter fighter)
 {
     fighters.Add(fighter);
     FighterAdded(this, new BattleEventArgs {
         Fighter = fighter
     });
 }
        public Fighter()
        {
            ID = sCounter++;
            Health = 0;
            Mana = 0;
            Stats = new Stats();
            Position = new Point();

            IsDisabled = false;
            IsEngaged = false;
            IsRanged = false;
            TryEscaping = false;
            CanLink = false;
            IsLinkable = false;

            next = null;
            children = new List<Fighter>();
            statusEffects = new Dictionary<Type, StatusEffect>();
        }
 public abstract void End(Fighter linker, Fighter target);
 public abstract void Apply(Fighter linker, Fighter target);
 public abstract void OnRemove(Fighter fighter);
        private void unlink()
        {
            if (next != null) {
                Fighter oldNext = next;
                next.children.Remove(this);
                next = null;

                // Notify
                Unlinked(this, new FighterEventArgs {
                    Target = oldNext
                });

                // Remove link skill
                if (Style.LinkSkill == null) {
                    Style.LinkSkill.End(this, oldNext);
                }
            }
        }
        private void link(Fighter target)
        {
            if (Team.IsFriendly(target.Team)) {
                // Link to root of target's tree
                Fighter root = target.GetRoot();

                // Check if fighters are already linked
                bool alreadyLinked = false;
                foreach (Fighter c in root.children) {
                    if (this == c) {
                        alreadyLinked = true;
                        break;
                    }
                }

                // Link the two fighters
                if (!alreadyLinked) {
                    next = target;
                    root.children.Add(this);

                    // Apply link skill
                    if (Style.LinkSkill != null) {
                        Style.LinkSkill.Apply(this, target);
                    }

                    // Notify
                    Linked(this, new FighterEventArgs {
                        Target = root
                    });
                }
            }
        }
Beispiel #10
0
 public abstract void Apply(Fighter linker, Fighter target);
        private void hit(Fighter by, int damage, byte elements)
        {
            int reflectedDamage = 0;

            ForEach(delegate(Fighter fighter) {
                // Apply damage
                int inflicted = 0;
                byte encoding;

                // Get affinity based on total elements
                Affinity affinity = Style.GetAffinity(elements);

                // If the combination yields no affinity, find one from individual elements
                if (affinity == Affinity.None) {
                    for (int i = 0; i < 8; i++) {
                        encoding = (byte)(elements & (1 << i));
                        if (encoding != 0) {
                            affinity = Style.GetAffinity(encoding);
                            break;
                        }
                    }
                }

                // Apply damage
                switch (affinity) {
                    case Affinity.None:
                        inflicted = damage - Stats.Defense;
                        break;
                    case Affinity.Strong:
                        inflicted = damage - 2 * Stats.Defense;
                        break;
                    case Affinity.Weak:
                        inflicted = damage - Stats.Defense / 2;
                        AddStatusEffect(new StatusEffects.KnockDown(2));
                        break;
                    case Affinity.Nullify:
                        inflicted = 0;
                        break;
                    case Affinity.Absorb:
                        inflicted = -damage;
                        break;
                    case Affinity.Reflect:
                        reflectedDamage += damage;
                        break;
                }

                // Notify views of an affinity'd attack
                if (affinity != Affinity.None) {
                    AffinityInvoked(fighter, new FighterEventArgs {
                        Affinity = affinity
                    });
                }

                // Apply damage
                if (inflicted > 0) {
                    Hurt(inflicted);
                    // Destroy all links
                    unlinkInternal(fighter);
                }
            });
        }
        public bool Step(Battle battle)
        {
            if (IsDisabled) {
                return true;
            }

            target = findTarget(battle);
            if (target == null) {
                return false;
            }

            if (Team.IsFriendly(target.Team)) {
                if (ChildrenCount() == 0) {
                    link(target);
                } else {
                    support(target);
                }
            } else {
                attack(target);
            }

            target = null;
            return false;
        }
 public abstract int Apply(Fighter attacker, Fighter target, int damage, byte elements);
 public bool HasFighter(Fighter fighter)
 {
     return fighters.Contains(fighter);
 }
        private void attack(Fighter target)
        {
            if (!target.IsAlive()) {
                return;
            }

            // Calculate distance modifiers
            float modifier = 1.0f;

            // Get damage count
            int damage = Stats.Attack;
            if (next == this) {
                damage += Stats.Attack / 2;
            }

            // Fix this calculation later
            byte elements = (byte)(1 << (int)Style.AttackElement);
            foreach (Fighter c in children) {
                if (c != null && c.IsAlive()) {
                    // Accumulate /something/
                    damage += c.Stats.Magic;

                    // Accumulate attack elements
                    elements |= (byte)(1 << (int)Style.AttackElement);
                }
            }

            // Apply damage modifier
            damage = (int)(damage * modifier);

            // Apply attack skill
            if (Style.AttackSkill != null) {
                damage = Style.AttackSkill.Apply(this, target, damage, elements);
            }

            // Unlink
            unlinkAll();

            // Notify observers
            Attacked(this, new FighterEventArgs {
                Target = target,
                Health = -damage
            });
        }
Beispiel #16
0
 public abstract void End(Fighter linker, Fighter target);
        private void hit(Fighter by, int damage, byte elements)
        {
            ForEach(delegate(Fighter fighter) {
                // Apply damage
                int inflicted = damage - fighter.Stats.Defense;
                Hurt(inflicted);

                // Destroy all links
                unlinkInternal(fighter);
            });
        }
 public abstract void OnAdd(Fighter fighter);
        private void support(Fighter target)
        {
            if (Team.IsFriendly(target.Team)) {
                // Temporary heal
                int healed = target.Heal(1);
                Supported(this, new FighterEventArgs {
                    SupportElement = SupportElement.Heal,
                    Health = healed
                });

                unlinkAll();
            }
        }
 public abstract void OnRemove(Fighter fighter);
        private void unlinkInternal(Fighter fighter)
        {
            if (fighter.next != null) {
                Fighter oldNext = fighter.next;
                fighter.next = null;

                Unlinked(fighter, new FighterEventArgs {
                    Target = oldNext
                });
            }

            fighter.children.Clear();
        }
 public abstract bool Step(Fighter fighter);
 public abstract void OnAdd(Fighter fighter);
        private void hit(Fighter by, int damage, byte elements)
        {
            int reflectedDamage = 0;

            ForEach(delegate(Fighter fighter) {
                // Apply damage
                int inflicted = 0;
                byte encoding;

                // Get affinity based on total elements
                Affinity affinity = Style.GetAffinity(elements);

                // If the combination yields no affinity, find one from individual elements
                if (affinity == Affinity.None)
                {
                    for (int i = 0; i < 8; i++)
                    {
                        encoding = (byte)(elements & (1 << i));
                        if (encoding != 0)
                        {
                            affinity = Style.GetAffinity(encoding);
                            break;
                        }
                    }
                }

                // Apply damage
                switch (affinity)
                {
                case Affinity.None:
                    inflicted = damage - Stats.Defense;
                    break;

                case Affinity.Strong:
                    inflicted = damage - 2 * Stats.Defense;
                    break;

                case Affinity.Weak:
                    inflicted = damage - Stats.Defense / 2;
                    AddStatusEffect(new StatusEffects.KnockDown(2));
                    break;

                case Affinity.Nullify:
                    inflicted = 0;
                    break;

                case Affinity.Absorb:
                    inflicted = -damage;
                    break;

                case Affinity.Reflect:
                    reflectedDamage += damage;
                    break;
                }

                // Notify views of an affinity'd attack
                if (affinity != Affinity.None)
                {
                    AffinityInvoked(fighter, new FighterEventArgs {
                        Affinity = affinity
                    });
                }

                // Apply damage
                if (inflicted > 0)
                {
                    Hurt(inflicted);
                    // Destroy all links
                    unlinkInternal(fighter);
                }
            });
        }
 public abstract bool Step(Fighter fighter);
 public abstract int Apply(Fighter attacker, Fighter target, int damage, byte elements);