Пример #1
0
        /// <summary>
        /// Warning : this method says if this affect may affect this target. But NOT if the target can be the target of the spell 
        /// (cf épée divine, where you cast it on yourself despite it effects only enemies around you)
        /// </summary>
        /// <param name="spellEffect"></param>
        /// <param name="spell"></param>
        /// <param name="caster"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        public static bool canAffectTarget(EffectDice spellEffect, Spell spell, PlayedFighter caster, Fighter target)
        {
            if (spell.LevelTemplate.spellBreed == (uint)BreedEnum.Eniripsa && spell.Categories == Spell.SpellCategory.Healing && caster.HasState(76)) return false;
            //if (!spell.IsAvailable(target == null ? null : (int?)target.Id)) return false;
            //BiM.Behaviors.Game.Spells.Spell.SpellCategory categories = 0;
            uint surface = spellEffect.Surface;
            //categories = BiM.Behaviors.Game.Spells.Spell.GetEffectCategories((uint)spellEffect.Id, spell.LevelTemplate.id);
            if (spellEffect.Targets == SpellTargetType.NONE) spellEffect.Targets = SpellTargetType.ALL;
            //if (target == null) return !spell.LevelTemplate.needTakenCell;

            if (caster == target) // Self
                return ((spellEffect.Targets & (SpellTargetType.ONLY_SELF | SpellTargetType.SELF)) != 0);

           
            if (caster.Team == target.Team) // Ally
                if (target.Summoned)
                    return ((spellEffect.Targets & SpellTargetType.ALLIES_SUMMON) != 0);
                else
                    return ((spellEffect.Targets & SpellTargetType.ALLIES_NON_SUMMON) != 0);

            if (target.Summoned) // Enemies
                return ((spellEffect.Targets & SpellTargetType.ENEMIES_SUMMON) != 0);
            else
                return ((spellEffect.Targets & SpellTargetType.ENEMIES_NON_SUMMON) != 0);
        }
Пример #2
0
        public void SetCurrentPlayer(Fighter fighter)
        {
            CurrentPlayer = fighter;

            var index = GetFighterIndex(fighter);

            if (index == -1)
                throw new Exception(string.Format("Something goes wrong, fighter {0} not found in the timeline", fighter.Id));

            Index = index;
        }
Пример #3
0
        /// <summary>
        /// Get all fighters who will play before the turn of <paramref name="fighter"/>
        /// </summary>
        /// <param name="fighter"></param>
        /// <returns></returns>
        public Fighter[] GetNextPlayers(Fighter fighter)
        {
            var result = new List<Fighter>();
            if (CurrentPlayer == fighter || Fighters.Count == 0 || Fighters.All(entry => !entry.CanPlay()))
            {
                return new Fighter[0];
            }

            var currentFighter = GetNextPlayer();
            int index = ( Index + 1 ) < Fighters.Count ? Index + 1 : 0;
            while (currentFighter != fighter)
            {
                if (currentFighter.CanPlay())
                    result.Add(currentFighter);

                index = ( index + 1 ) < Fighters.Count ? index + 1 : 0;
            }

            return result.ToArray();
        }
Пример #4
0
 public int GetFighterIndex(Fighter fighter)
 {
     return Fighters.IndexOf(fighter);
 }
Пример #5
0
 public void ResetCurrentPlayer()
 {
     CurrentPlayer = null;
     Index = -1;
 }
Пример #6
0
        private void OnTurnStarted(Fighter fighter)
        {
            var bot = BotManager.Instance.GetCurrentBot();

            StartAI();
        }
Пример #7
0
        /// <summary>
        /// Add spellImpact for a given effect, taking into account caster bonus and target resistance. 
        /// </summary>
        /// <param name="effect"></param>
        /// <param name="spellImpact"></param>
        /// <param name="caster"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        public static DamageType CumulEffects(EffectInstanceDice effect, ref SpellImpact spellImpact, PlayedFighter caster, Fighter target/*, Spell.SpellCategory Categories*/, Spell spell)
        {
            bool isFriend = caster.Team.Id == target.Team.Id;
            SpellImpact result = new SpellImpact();

            SpellTargetType targetType = (SpellTargetType)effect.targetId;

                
            //if ((targetType & SpellTargetType.ENEMIES) == 0) return spellImpact; // No enemy can be targeted

            SpellCategory category = GetEffectCategories(effect.effectId, spell.LevelTemplate.id)/* & Categories*/;
            if (category == 0) return 0; // No category selected in this spell

            if (spell.Template.id == 0) // Weapon => ignore non heal or damage effects
                if ( (category & (SpellCategory.Damages | SpellCategory.Healing)) == 0) return 0;

            double chanceToHappen = 1.0; // 

            // When chances to happen is under 100%, then we reduce spellImpact accordingly, for simplicity, but after having apply damage bonus & reduction. 
            // So average damage should remain exact even if Min and Max are not. 
            if (effect.random > 0)
                chanceToHappen = effect.random / 100.0;

            if (target.Summoned && (caster.Breed.Id != (int)BreedEnum.Osamodas || target.Team.Id != caster.Team.Id))
                chanceToHappen /= 2; // It's much better to hit non-summoned foes => effect on summons (except allies summon for Osa) is divided by 2. 

            SpellException spellException = null;
            if (spellExceptions.ContainsKey(spell.LevelTemplate.id))
                spellException = spellExceptions[spell.LevelTemplate.id];
            if ((category & SpellCategory.DamagesNeutral) > 0)
                AdjustDamage(result, spellException != null ? spellException.MinNeutral : effect.diceNum, spellException != null ? spellException.MaxNeutral : effect.diceSide, SpellCategory.DamagesNeutral, chanceToHappen,
                    GetSafetotal(caster, Stats.PlayerField.NeutralDamageBonus) + GetSafetotal(caster, Stats.PlayerField.DamageBonus) + GetSafetotal(caster, Stats.PlayerField.PhysicalDamage),
                    GetSafetotal(caster, Stats.PlayerField.DamageBonusPercent) + GetSafetotal(caster, Stats.PlayerField.Strength),
                    target == null ? 0 : target.Stats.NeutralElementReduction,
                    target == null ? 0 : target.Stats.NeutralResistPercent, isFriend);

            if ((category & SpellCategory.DamagesFire) > 0)
                AdjustDamage(result, spellException != null ? spellException.MinFire : effect.diceNum, spellException != null ? spellException.MaxFire : effect.diceSide, SpellCategory.DamagesFire, chanceToHappen,
                    GetSafetotal(caster, Stats.PlayerField.FireDamageBonus) + GetSafetotal(caster, Stats.PlayerField.DamageBonus) + GetSafetotal(caster, Stats.PlayerField.MagicDamage),
                    GetSafetotal(caster, Stats.PlayerField.DamageBonusPercent) + GetSafetotal(caster, Stats.PlayerField.Intelligence),
                    target == null ? 0 : target.Stats.FireElementReduction,
                    target == null ? 0 : target.Stats.FireResistPercent, isFriend);

            if ((category & SpellCategory.DamagesAir) > 0)
                AdjustDamage(result, spellException != null ? spellException.MinAir : effect.diceNum, spellException != null ? spellException.MaxAir : effect.diceSide, SpellCategory.DamagesAir, chanceToHappen,
                    GetSafetotal(caster, Stats.PlayerField.AirDamageBonus) + GetSafetotal(caster, Stats.PlayerField.DamageBonus) + GetSafetotal(caster, Stats.PlayerField.MagicDamage),
                    GetSafetotal(caster, Stats.PlayerField.DamageBonusPercent) + GetSafetotal(caster, Stats.PlayerField.Agility),
                    target == null ? 0 : target.Stats.AirElementReduction,
                    target == null ? 0 : target.Stats.AirResistPercent, isFriend);

            if ((category & SpellCategory.DamagesWater) > 0)
                AdjustDamage(result, spellException != null ? spellException.MinWater : effect.diceNum, spellException != null ? spellException.MaxWater : effect.diceSide, SpellCategory.DamagesWater, chanceToHappen,
                    GetSafetotal(caster, Stats.PlayerField.WaterDamageBonus) + GetSafetotal(caster, Stats.PlayerField.DamageBonus) + GetSafetotal(caster, Stats.PlayerField.MagicDamage),
                    GetSafetotal(caster, Stats.PlayerField.DamageBonusPercent) + GetSafetotal(caster, Stats.PlayerField.Chance),
                    target == null ? 0 : target.Stats.WaterElementReduction,
                    target == null ? 0 : target.Stats.WaterResistPercent, isFriend);

            if ((category & SpellCategory.DamagesEarth) > 0)
                AdjustDamage(result, spellException != null ? spellException.MinEarth : effect.diceNum, spellException != null ? spellException.MaxEarth : effect.diceSide, SpellCategory.DamagesEarth, chanceToHappen,
                    GetSafetotal(caster, Stats.PlayerField.EarthDamageBonus) + GetSafetotal(caster, Stats.PlayerField.DamageBonus) + GetSafetotal(caster, Stats.PlayerField.MagicDamage),
                    GetSafetotal(caster, Stats.PlayerField.DamageBonusPercent) + GetSafetotal(caster, Stats.PlayerField.Strength),
                    target == null ? 0 : target.Stats.EarthElementReduction,
                    target == null ? 0 : target.Stats.EarthResistPercent, isFriend);

            if ((category & SpellCategory.Healing) > 0)
            {
                bool steal = (category & SpellCategory.Damages) > 0;
                if (steal) target = caster; // Probably hp steal
                uint hptoHeal = (uint)(Math.Max(0, target.Stats.MaxHealth - target.Stats.Health)); // Can't heal over max
                if (steal)
                {
                    result.MinHeal = -Math.Min(hptoHeal, Math.Abs(result.MinDamage));
                    result.MaxHeal = -Math.Min(hptoHeal, Math.Abs(result.MaxDamage));
                }
                else
                {
                    bool skip = false;
                    if (spell.Template.id == 140) // Mot de reconstruction => do only use it on purpose
                    {
                        if (hptoHeal < target.Stats.Health || hptoHeal < 400) skip = true; // Only heal targets with under 50% of health and at least 400 hp to heal
                    }
                    if (!skip && hptoHeal > 0)
                    {
                        AdjustDamage(result, Math.Min(effect.diceNum, hptoHeal), Math.Min(effect.diceSide, hptoHeal), SpellCategory.Healing, chanceToHappen,
                             GetSafetotal(caster, Stats.PlayerField.HealBonus),
                             GetSafetotal(caster, Stats.PlayerField.Intelligence),
                             0,
                             0, isFriend);
                        if (result.Heal > hptoHeal)
                            if (isFriend)
                                result.MinHeal = result.MaxHeal = -hptoHeal;
                            else
                                result.MinHeal = result.MaxHeal = hptoHeal;
                    }
                }
            }
            if ((category & SpellCategory.Buff) > 0)
                if (isFriend)
                    result.Boost -= spell.Level * chanceToHappen;
                else
                    result.Boost += spell.Level * chanceToHappen;

            if ((category & SpellCategory.Curse) > 0)
            {
                DamageType ratio = spell.Level * chanceToHappen;

                if (effect.effectId == (int)EffectsEnum.Effect_SkipTurn) // Let say this effect counts as 2 damage per level of the target
                    ratio = target.Level * 2 * chanceToHappen;

                if (isFriend)
                    result.Curse -= 2 * ratio;
                else
                    result.Curse += ratio;
            }
            if (isFriend)
                result.Add(result); // amplify (double) effects on friends. 


            if (!isFriend && ((category & SpellCategory.Damages) > 0) && result.MinDamage > target.Stats.Health) // Enough damage to kill the target => affect an arbitrary 50% of max heal (with at least current health), so strong spells are not favored anymore. 
            {
                double ratio = Math.Max(target.Stats.MaxHealth / 2, target.Stats.Health) / result.MinDamage;
                result.Multiply(ratio);
            }

            if (spell.Template.id == 114) // Rekop
            {
                if (target.Stats.Health < 1000)
                    result.Multiply(0.1);
                else
                    if (target.Stats.Health < 2000)
                        result.Multiply(0.5);
            }

            // Damage reflection
            if (((category & SpellCategory.Damages) > 0) && result.Damage > 0 && !isFriend)
            {
                DamageType reflected = spell.GetDamageReflection(target);
                if (reflected > 0)
                {
                    if (reflected >= spellImpact.Damage) return 0; // Reflect all damages
                    result.MinHeal += reflected * 2;
                    result.MaxHeal += reflected * 2;
                }
            }

            if (spell.Template.id == 0 && (category & SpellCategory.Damages) > 0) // Weapon => consider effect of "maîtrise"
            {
                Weapon weapon = caster.Character.Inventory.GetEquippedWeapon();
                if (weapon != null)
                    foreach(var boost in caster.GetBoostWeaponDamagesEffects())
                        if (boost.weaponTypeId == weapon.typeId)
                            result.Multiply(1.0+boost.delta/100.0);
            }

            if (spellImpact != null)
                spellImpact.Add(result);
            else
                spellImpact = result;
            return result.Damage;
        }        
Пример #8
0
 public bool RemoveSummon(Fighter fighter)
 {
     return(m_summons.Remove(fighter));
 }
Пример #9
0
        private static void OnTurnStarted(Fight fight, Fighter fighter)
        {
            var bot = BotManager.Instance.GetCurrentBot();

            bot.Character.SendMessage(string.Format("This is '{0}' turn.", fighter.Name), Color.Violet);
        }
Пример #10
0
 /// <summary>
 /// Check if the player can cast a spell to the targeted fighter
 /// </summary>
 /// <param name="spell">Casted spell</param>
 /// <param name="fighter">Targeted fighter</param>
 /// <returns>False if cannot cast the spell</returns>
 public bool CanCastSpell(Spells.Spell spell, Fighter fighter, bool NoRangeCheck = false)
 {
     return(CanCastSpell(spell, fighter.Cell, NoRangeCheck));
 }
Пример #11
0
 /// <summary>
 /// Check if the player can cast a spell to the targeted fighter
 /// </summary>
 /// <param name="spell">Casted spell</param>
 /// <param name="fighter">Targeted fighter</param>
 /// <returns>False if cannot cast the spell</returns>
 public bool CanCastSpell(Spells.Spell spell, Fighter fighter, bool NoRangeCheck = false)
 {
     return CanCastSpell(spell, fighter.Cell, NoRangeCheck);
 }
Пример #12
0
 public bool RemoveSummon(Fighter fighter)
 {
   return m_summons.Remove(fighter);
 }
Пример #13
0
    public bool AddSummon(Fighter fighter)
    {
      if (!fighter.Summoned || fighter.Summoner != this)
        return false;

      m_summons.Add(fighter);
      return true;
    }
Пример #14
0
 public SpellImpact GetSpellDamages(PlayedFighter caster, Fighter target/*, Spell.SpellCategory categories*/)
 {
     SpellImpact damages = null;
     foreach (var effect in LevelTemplate.effects)
         CumulEffects(effect, ref damages, caster, target/*, categories*/, this);
     return damages;
 }
Пример #15
0
 public bool CanCastSpell(Spells.Spell spell, Fighter fighter)
 {
     return CanCastSpell(spell, fighter.Cell);
 }
Пример #16
0
        public void InsertFighter(Fighter fighter, int index)
        {
            m_fighters.Insert(index, fighter);

            if (Index >= index)
                Index++;
        }
Пример #17
0
        private void MoveNear(Fighter fighter, int mp)
        {
            var dest = fighter.Cell.GetAdjacentCells().OrderBy(cell => cell.DistanceTo(m_character.Cell)).FirstOrDefault();

            if (dest == null)
                return;

            m_character.Move(dest);
        }
Пример #18
0
 private int GetRealInitiative(Fighter fighter)
 {
     return fighter.Stats.Initiative * fighter.Stats.Health / fighter.Stats.MaxHealth;
 }
Пример #19
0
 public SpellCastHistory(Fighter fighter)
 {
     Fighter = fighter;
     m_readOnlyCasts = new ReadOnlyObservableCollection<SpellCast>(m_casts);
 }
Пример #20
0
 DamageType GetDamageReflection(Fighter target)
 {
     DamageType reflect = 0;
     foreach (var effect in target.GetFightTriggeredEffects((short)EffectsEnum.Effect_AddDamageReflection))
         reflect += effect.arg3 + effect.arg1 * (1 + effect.arg2) / 2 ;
     return reflect * (1 + target.Level * 0.05);
 }