Example #1
0
        internal int avo(Game_Unit target, bool staff = false, WeaponTriangle tri = WeaponTriangle.Nothing)
        {
            int actor_avo, bonus = 0, skill_avo;

            // Terrain avoid bonus
            if (Global.scene.is_map_scene)
            {
                bool magic_attack = target != null &&
                                    target.check_magic_attack(target.actor.weapon, Distance);
                var terrain_bonus = attacker.terrain_avo_bonus(target, magic_attack);
                if (terrain_bonus.IsSomething)
                {
                    bonus += terrain_bonus;
                }
            }
            if (staff)
            {
                actor_avo = res() * 5;
                bonus    += Distance * 2;
            }
            else
            {
                actor_avo = base_avo();
            }
            skill_avo = 0;
            attacker.avo_skill(ref skill_avo, ref actor_avo, ref bonus,
                               attacker_weapon, target, tri);
            // Support avoid bonus
            bonus += support_bonus(Combat_Stat_Labels.Avo);
            return(Math.Max(0, actor_avo + bonus + skill_avo));
        }
Example #2
0
        private int hit_target(Game_Unit target)
        {
            Data_Weapon weapon = this.attacker_weapon;

            // Checks if weapon is magic
            bool        magic_attack = attacker.check_magic_attack(weapon, Distance);
            bool        is_staff = weapon.is_staff();
            Game_Actor  actor2 = target.actor;
            Data_Weapon weapon2 = actor2.weapon;
            bool        boss_staff = false;
            int         actor_hit, weapon_hit, skill_hit, support_hit, s_bonus;
            int         hit_rate, target_avo;

            if (is_staff)
            {
                actor_hit = attacker.atk_pow(weapon, magic_attack) * 5 +
                            attacker.stat(Stat_Labels.Skl);
                weapon_hit = weapon.Hit;
                skill_hit  = 0;
                attacker.hit_skill(
                    ref skill_hit, ref weapon_hit, ref actor_hit,
                    weapon, target, magic_attack, Distance);
                support_hit = support_bonus(Combat_Stat_Labels.Hit);
                s_bonus     = 0;
                hit_rate    = Math.Max(0, actor_hit + weapon_hit + skill_hit + support_hit + s_bonus);

                target_avo = this.target_stats().staff_avo();
                boss_staff = target.boss;
            }
            else
            {
                actor_hit = base_hit(weapon, magic_attack);

                weapon_hit = weapon.Hit;
                skill_hit  = 0;
                attacker.hit_skill(
                    ref skill_hit, ref weapon_hit, ref actor_hit,
                    weapon, target, magic_attack, Distance);
                support_hit = support_bonus(Combat_Stat_Labels.Hit);
                s_bonus     = attacker.actor.s_rank_bonus(weapon);
                // Weapon triangle
                WeaponTriangle tri = Combat.weapon_triangle(attacker, target, weapon, weapon2, Distance);
                if (tri != WeaponTriangle.Nothing)
                {
                    weapon_hit += Weapon_Triangle.HIT_BONUS * (tri == WeaponTriangle.Advantage ? 1 : -1) *
                                  Combat.weapon_triangle_mult(attacker, target, weapon, weapon2, Distance);
                }

                hit_rate = Math.Max(0, actor_hit + weapon_hit + skill_hit + support_hit + s_bonus);

                target_avo = this.target_stats().avo(Combat.reverse_wta(tri));
            }
            int total_hit = hit_rate - target_avo;
            int result = attacker.hit_target_skill(
                target, weapon, Distance, Math.Max(total_hit, 0) / (boss_staff ? 2 : 1));

            return(result);
        }
Example #3
0
        public static void SetWeaponTriangle(
            Weapon_Triangle_Arrow wta1,
            Weapon_Triangle_Arrow wta2,
            Game_Unit attacker,
            Combat_Map_Object target,
            TactileLibrary.Data_Weapon weapon1,
            TactileLibrary.Data_Weapon weapon2,
            int distance)
        {
            //@Yeti: use in all the places weapon triangle arrow is used
            Game_Unit targetUnit = null;

            if (target.is_unit())
            {
                targetUnit = target as Game_Unit;
            }

            ResetWeaponTriangle(wta1, wta2);
            WeaponTriangle tri = WeaponTriangle.Nothing;

            if (targetUnit != null)
            {
                tri = Combat.weapon_triangle(attacker, targetUnit, weapon1, weapon2, distance);
            }
            if (tri != WeaponTriangle.Nothing)
            {
                wta1.value = tri;
                if (wta2 != null && weapon2 != null)
                {
                    wta2.value = Combat.reverse_wta(tri);
                }
            }

            float effectiveness = weapon1.effective_multiplier(attacker, targetUnit, false);

            wta1.set_effectiveness((int)effectiveness,
                                   targetUnit != null && targetUnit.halve_effectiveness());

            if (wta2 != null && weapon2 != null)
            {
                effectiveness = weapon2.effective_multiplier(targetUnit, attacker, false);
                wta2.set_effectiveness((int)effectiveness, attacker.halve_effectiveness());
            }
        }
Example #4
0
        private int dmg_target(Game_Unit target)
        {
            Data_Weapon weapon = this.attacker_weapon;

            // Checks if weapon is magic
            bool        magic_attack = attacker.check_magic_attack(weapon, Distance);
            bool        imbue = (magic_attack && attacker.actor.power_type() == Power_Types.Strength);
            bool        is_staff = weapon.is_staff();
            Game_Actor  actor2 = target.actor;
            Data_Weapon weapon2 = actor2.weapon;
            int         total_damage, target_def;
            int         actor_dmg, weapon_dmg, skill_dmg, support_dmg;

            // Staff
            if (is_staff)
            {
                actor_dmg  = attacker.atk_pow(weapon, magic_attack);
                weapon_dmg = weapon.Mgt;
                skill_dmg  = 0;
                attacker.dmg_staff_skill(
                    ref skill_dmg, ref weapon_dmg, ref actor_dmg,
                    target, magic_attack, Distance);
                support_dmg = support_bonus(Combat_Stat_Labels.Dmg);
                target_def  = 0;
            }
            // Weapon
            else
            {
                var target_stats = this.target_stats();
                target_def = magic_attack ?
                             target_stats.res() : target_stats.def();
                target_def = (weapon.Ignores_Def() ? target_def / 2 : target_def);
                if (weapon.Halves_HP())
                {
                    int total_weapon_damage = target_def + (int)Math.Ceiling(target.actor.hp / 2.0f);
                    actor_dmg  = (int)Math.Ceiling(total_weapon_damage / 2.0f);
                    weapon_dmg = (int)Math.Floor(total_weapon_damage / 2.0f);
                }
                else
                {
                    actor_dmg = weapon.Ignores_Pow() ?
                                0 : ((int)(attacker.atk_pow(weapon, magic_attack) *
                                           (imbue ? Constants.Combat.MAGIC_WEAPON_STR_RATE : 1)));
                    weapon_dmg = (int)(weapon.Mgt * (imbue ? Constants.Combat.MAGIC_WEAPON_MGT_RATE : 1));
                    if (weapon.Ignores_Def())
                    {
                        weapon_dmg += target_def;
                    }
                }
                // Weapon triangle
                skill_dmg = 0;
                WeaponTriangle tri = Combat.weapon_triangle(attacker, target, weapon, weapon2, Distance);
                if (tri != WeaponTriangle.Nothing)
                {
                    skill_dmg += Weapon_Triangle.DMG_BONUS * (tri == WeaponTriangle.Advantage ? 1 : -1) *
                                 Combat.weapon_triangle_mult(attacker, target, weapon, weapon2, Distance);
                }

                float effectiveness = weapon.effective_multiplier(attacker, target);
                skill_dmg  += (int)((weapon_dmg + skill_dmg) * (effectiveness - 1));
                support_dmg = support_bonus(Combat_Stat_Labels.Dmg);
                attacker.dmg_skill(
                    ref skill_dmg, ref weapon_dmg, ref actor_dmg, ref support_dmg,
                    ref target_def, weapon, target, weapon2, tri, magic_attack,
                    Distance, effectiveness);
            }
            total_damage = actor_dmg + weapon_dmg + skill_dmg + support_dmg - target_def;
            int result = attacker.dmg_target_skill(target, weapon, Distance, Math.Max(0, total_damage));

            return(result);
        }
Example #5
0
 internal override int avo(WeaponTriangle tri)
 {
     return(avo(this.target as Game_Unit, tri));
 }
        protected override void set_images()
        {
            Icon1.flash = false;
            Icon2.flash = false;
            Mult1.value = 0;
            Mult2.value = 0;
            WTA1.set_effectiveness(1);
            WTA2.set_effectiveness(1);
            Game_Unit         unit   = get_unit();
            Game_Actor        actor1 = unit.actor;
            Combat_Map_Object target =
                Global.game_map.attackable_map_object(this.target);
            Game_Unit  target_unit    = null;
            Game_Actor actor2         = null;
            bool       is_target_unit = false;

            if (target.is_unit())
            {
                is_target_unit = true;
                target_unit    = (Game_Unit)target;
                actor2         = target_unit.actor;
                Window.team2   = target_unit.team;
            }
            else
            {
                Window.team2 = target.team;
            }
            int distance = combat_distance(unit.id, this.target);

            // Get weapon data
            TactileLibrary.Data_Weapon weapon1 = actor1.weapon, weapon2 = null;
            if (is_target_unit)
            {
                weapon2 = actor2.weapon;
            }
            // Weapon triangle arrows
            WTA1.value = 0;
            WTA2.value = 0;
            WeaponTriangle tri = WeaponTriangle.Nothing;

            if (is_target_unit)
            {
                tri = Combat.weapon_triangle(unit, target_unit, weapon1, weapon2, distance);
            }
            if (tri != WeaponTriangle.Nothing)
            {
                WTA1.value = tri;
                if (weapon2 != null)
                {
                    WTA2.value = Combat.reverse_wta(tri);
                }
            }

            List <int?> combat_stats = get_combat_stats(unit.id, this.target, distance);

            Stats = new List <Sprite>();
            for (int i = 0; i < stat_rows * 2; i++)
            {
                RightAdjustedText text = new RightAdjustedText();
                Stats.Add(text);
                text.draw_offset = new Vector2(68 - (48 * (i / 4)), 4 + ((i % 4 + 1) * LINE_HEIGHT));
                text.SetFont(Config.UI_FONT, Global.Content, "Blue");
                text.text = "0";
            }
            // Sets first units's stats //
            Name1.draw_offset = new Vector2(44, 4);
            Name1.text        = actor1.name;
            Name1.offset      = new Vector2(Name1.text_width / 2, 0);
            // Multiplier
            Mult1.value = Mult1.get_multi(unit, target, weapon1, distance);
            // Icon
            Icon1.index   = weapon1.Image_Index;
            Icon1.texture = Global.Content.Load <Texture2D>(@"Graphics/Icons/" + weapon1.Image_Name);
            if (weapon1.effective_multiplier(unit, target_unit) > 1)
            {
                Icon1.flash = true;
            }
            float effectiveness = weapon1.effective_multiplier(unit, target_unit, false);

            WTA1.set_effectiveness((int)effectiveness,
                                   is_target_unit && target_unit.halve_effectiveness());
            // Hp
            if (actor1.hp >= Math.Pow(10, Global.BattleSceneConfig.StatusHpCounterValues))
            {
                ((RightAdjustedText)Stats[0]).text = "--";
            }
            else
            {
                ((RightAdjustedText)Stats[0]).text = actor1.hp.ToString();
            }
            // Dmg
            ((RightAdjustedText)Stats[1]).text = combat_stats[1].ToString();
            // Hit
            if (combat_stats[0] >= 100)
            {
                ((RightAdjustedText)Stats[2]).SetFont("Blue_100", Global.Content);
            }
            ((RightAdjustedText)Stats[2]).text = combat_stats[0].ToString();
            // Crt
            if (combat_stats[2] >= 100)
            {
                ((RightAdjustedText)Stats[3]).SetFont("Blue_100", Global.Content);
            }
            ((RightAdjustedText)Stats[3]).text = combat_stats[2].ToString();
            // Sets second units's stats //
            string name2 = is_target_unit ? actor2.name : target.name;

            Name2.draw_offset = new Vector2(28, 4 + (Window.rows + 1) * LINE_HEIGHT);
            Name2.offset      = new Vector2(Font_Data.text_width(name2, Config.UI_FONT) / 2, 0);
            Name2.text        = name2;
            // Icon
            if (weapon2 != null)
            {
                Target_Weapon.text        = weapon2.Name;
                Target_Weapon.draw_offset = new Vector2(
                    32 - Target_Weapon.text_width / 2, 4 + (Window.rows + 2) * LINE_HEIGHT);
                Icon2.index   = weapon2.Image_Index;
                Icon2.texture = Global.Content.Load <Texture2D>(@"Graphics/Icons/" + weapon2.Image_Name);
                if (weapon2.effective_multiplier(target_unit, unit) > 1)
                {
                    Icon2.flash = true;
                }
                effectiveness = weapon2.effective_multiplier(target_unit, unit, false);
                WTA2.set_effectiveness((int)effectiveness, unit.halve_effectiveness());
            }
            else
            {
                Target_Weapon.draw_offset = new Vector2(
                    32 - Font_Data.text_width("---", Config.UI_FONT) / 2, 4 + (Window.rows + 2) * LINE_HEIGHT);
                Target_Weapon.text = "---";
                Icon2.texture      = null;
            }
            // Hp
            //int target_hp = is_target_unit ? actor2.hp : ((Destroyable_Object)target).hp; //Debug

            if (target.hp >= Math.Pow(10, Global.BattleSceneConfig.StatusHpCounterValues))
            {
                ((RightAdjustedText)Stats[4]).text = "--";
            }
            else
            {
                ((RightAdjustedText)Stats[4]).text = target.hp.ToString();
            }
            if (is_target_unit && can_counter(unit, target_unit, weapon1, distance))
            {
                // Multiplier
                Mult2.value = Mult2.get_multi(target_unit, unit, weapon2, distance);
                // Dmg
                ((RightAdjustedText)Stats[5]).text = combat_stats[5].ToString();
                // Hit
                if (combat_stats[4] >= 100)
                {
                    ((RightAdjustedText)Stats[6]).SetFont("Blue_100", Global.Content);
                }
                ((RightAdjustedText)Stats[6]).text = combat_stats[4].ToString();
                // Crt
                if (combat_stats[6] >= 100)
                {
                    ((RightAdjustedText)Stats[7]).SetFont("Blue_100", Global.Content);
                }
                ((RightAdjustedText)Stats[7]).text = combat_stats[6].ToString();
            }
            else
            {
                ((RightAdjustedText)Stats[5]).text = "--";
                ((RightAdjustedText)Stats[6]).text = "--";
                ((RightAdjustedText)Stats[7]).text = "--";
            }
            refresh();
        }
Example #7
0
        protected void refresh_battle_stats(bool just_stats)
        {
            if (!just_stats)
            {
                foreach (Item_Icon_Sprite icon in Weapon_Icons)
                {
                    icon.texture = null;
                }
                foreach (TextSprite name in Weapon_Names)
                {
                    name.text = "";
                }

                TactileLibrary.Data_Weapon weapon1 = null;
                TactileLibrary.Data_Weapon weapon2 = null;
                WTAs[0].value = 0;
                if (Global.scene.scene_type == "Scene_Dance" || Global.scene.scene_type == "Scene_Promotion")
                {
                    int item_index = -1;
                    if (Global.scene.scene_type == "Scene_Dance")
                    {
                        item_index = Global.game_state.dance_item;
                    }
                    else if (Global.scene.scene_type == "Scene_Promotion")
                    {
                        item_index = Global.game_state.item_used;
                    }
                    if (item_index > -1)
                    {
                        TactileLibrary.Item_Data      item_data = battler_1.actor.items[item_index];
                        TactileLibrary.Data_Equipment item1     = item_data.to_equipment;
                        Weapon_Icons[0].texture  = Global.Content.Load <Texture2D>(@"Graphics/Icons/" + item1.Image_Name);
                        Weapon_Icons[0].index    = item1.Image_Index;
                        Weapon_Names[0].offset.X = Font_Data.text_width(item1.full_name()) / 2;
                        Weapon_Names[0].text     = item1.full_name();
                    }

                    if (battler_2 != null)
                    {
                        WTAs[1].value = 0;
                        weapon2       = battler_2.actor.weapon;
                        if (weapon2 != null)
                        {
                            Weapon_Icons[1].texture  = Global.Content.Load <Texture2D>(@"Graphics/Icons/" + weapon2.Image_Name);
                            Weapon_Icons[1].index    = weapon2.Image_Index;
                            Weapon_Names[1].offset.X = Font_Data.text_width(weapon2.full_name()) / 2;
                            Weapon_Names[1].text     = weapon2.full_name();
                        }
                    }
                }
                else
                {
                    weapon1 = battler_1.actor.weapon;
                    Weapon_Icons[0].texture = Global.Content.Load <Texture2D>(@"Graphics/Icons/" + weapon1.Image_Name);
                    Weapon_Icons[0].index   = weapon1.Image_Index;
                    if (!(Data is Staff_Data) || ((Staff_Data)Data).attack_staff)
                    {
                        Weapon_Icons[0].flash = weapon1.effective_multiplier(battler_1, battler_2) > 1;
                    }
                    Weapon_Names[0].offset.X = Font_Data.text_width(weapon1.full_name()) / 2;
                    Weapon_Names[0].text     = weapon1.full_name();


                    if (battler_2 != null)
                    {
                        WTAs[1].value = 0;
                        weapon2       = battler_2.actor.weapon;
                        if (weapon2 != null)
                        {
                            Weapon_Icons[1].texture = Global.Content.Load <Texture2D>(@"Graphics/Icons/" + weapon2.Image_Name);
                            Weapon_Icons[1].index   = weapon2.Image_Index;
                            if (!(Data is Staff_Data) || ((Staff_Data)Data).attack_staff)
                            {
                                Weapon_Icons[1].flash = weapon2.effective_multiplier(battler_2, battler_1) > 1;
                            }
                            Weapon_Names[1].offset.X = Font_Data.text_width(weapon2.full_name()) / 2;
                            Weapon_Names[1].text     = weapon2.full_name();
                            // Attack Multiplier
                            if (!weapon1.is_staff())
                            {
                            }  // Mults[1].value = Mults[1].get_multi(battler_2, battler_1, weapon2); //Debug
                        }
                        if (!weapon1.is_staff())
                        {
                            // Weapon triangle arrows
                            WeaponTriangle tri = Combat.weapon_triangle(battler_1, battler_2, weapon1, weapon2, Data.Distance);
                            if (tri != WeaponTriangle.Nothing)
                            {
                                WTAs[0].value = tri;
                                if (weapon2 != null)
                                {
                                    WTAs[1].value = Combat.reverse_wta(tri);
                                }
                            }
                            // Attack Multiplier
                            //Mults[0].value = Mults[0].get_multi(battler_1, battler_2, weapon1); //Debug
                        }
                    }
                }
            }
            for (int i = 0; i < Stat_Imgs.Count; i++)
            {
                if (Stats[i] == null)
                {
                    Stat_Imgs[i].text = "--";
                }
                else if (Stats[i] < 0)
                {
                    Stat_Imgs[i].text = "--";
                }
                else
                {
                    Stat_Imgs[i].text = Stats[i].ToString();
                }
            }
        }
        List <GameAction> InitiateCombat(FE7UnitEntity attacker, FE7UnitEntity defender, int engagementRange)
        {
            List <GameAction> ret = new List <GameAction>();

            if (!attacker.EquippedWeapon.Range.Contains(engagementRange))
            {
                throw new WeaponException("Attack at improper range");
            }
            bool defenderCanRetalliate = defender.EquippedWeapon.Range.Contains(engagementRange);

            int attackerAttackSpeed = attacker.AttackSpeed;
            int defenderAttackSpeed = defender.AttackSpeed;

            bool attackerDouble = attackerAttackSpeed - defenderAttackSpeed >= 4;
            bool defenderDouble = defenderAttackSpeed - attackerAttackSpeed >= 4;

            WeaponTriangle attackerWeapTriBonus = CalculateWeaponTriangle(attacker.EquippedWeapon.WeaponType, defender.EquippedWeapon.WeaponType);
            WeaponTriangle defenderWeapTriBonus = CalculateWeaponTriangle(defender.EquippedWeapon.WeaponType, attacker.EquippedWeapon.WeaponType);

            //[Precalculated -- Weapon Hit + (Skill x 2) + (Luck / 2) ]+ Support bonus + Weapon Triangle bonus + S Rank bonus + Tactician bonus
            int attackerHit = attacker.HitChance + 0 + ((int)attackerWeapTriBonus * 15) + 0 + 0;
            int defenderHit = defender.HitChance + 0 + ((int)defenderWeapTriBonus * 15) + 0 + 0;

            // [Precalculated -- (Attack Speed x 2) + Luck ]+ Support bonus + Terrain bonus + Tactician bonus
            defenderHit -= attacker.Avoid + 0 + CalcTerrainAvoidBonus(attacker.Terrain) + 0;
            attackerHit -= defender.Avoid + 0 + CalcTerrainAvoidBonus(defender.Terrain) + 0;

            // Weapon Critical + (Skill / 2) + Support bonus + Critical bonus + S Rank bonus - Crit Avoid [opponent's Luck + Support + Tactician Bonus]
            int attackerCrit = attacker.CritChance + 0 + 0 + 0 - defender.Luck - 0 - 0;
            int defenderCrit = defender.CritChance + 0 + 0 + 0 - attacker.Luck - 0 - 0;

            // StrengthMagic + Weapon Might + [ Weapon Triangle bonus x Effective coefficient] + Support bonus
            int attackerDamage = attacker.Might + ((int)attackerWeapTriBonus * 1) + 0 - CalcTerrainDefBonus(defender.Terrain);
            int defenderDamage = defender.Might + ((int)defenderWeapTriBonus * 1) + 0 - CalcTerrainDefBonus(attacker.Terrain);


            //attacker attacks first.
            GameAction attackerResult = ProcessAttack(MakeAttack(attackerHit, attackerCrit, attackerDamage), attacker, defender);

            ret.Add(attackerResult);

            //check to see if Defender is still alive.
            defender.TakeDamage(attackerResult);

            if (defender.HP > 0 && defenderCanRetalliate && defender.EquippedWeapon.WeaponType != FE7WeaponType.None)
            {
                //defender attacks

                GameAction defenderResult = ProcessAttack(MakeAttack(defenderHit, defenderCrit, defenderDamage), defender, attacker);
                ret.Add(defenderResult);

                attacker.TakeDamage(defenderResult);
            }

            //check to see if attacker is still alive
            if (attacker.HP > 0 && attackerDouble)
            {
                //attack again.
                GameAction followupResult = ProcessAttack(MakeAttack(attackerHit, attackerCrit, attackerDamage), attacker, defender);
                ret.Add(followupResult);

                //check to see if Defender is still alive.
                defender.TakeDamage(followupResult);
            }
            else if (defender.HP > 0 && defenderDouble && defender.EquippedWeapon.WeaponType != FE7WeaponType.None)
            {
                //defender attacks again.
                GameAction followupResult = ProcessAttack(MakeAttack(defenderHit, defenderCrit, defenderDamage), defender, attacker);
                ret.Add(followupResult);

                attacker.TakeDamage(followupResult);
            }

            //Now we check if either died.
            if (defender.HP > 0 && attacker.HP > 0)
            {
                //no one died.
                ret.Add(new CombatDrawAction(attacker, defender));
            }
            else if (attacker.HP > 0)
            {
                //defender died
                ret.Add(new CombatDefenderDefeatAction(attacker, defender));
            }
            else if (defender.HP > 0)
            {
                //attacker died
                ret.Add(new CombatAttackerDefeatAction(attacker, defender));
            }
            else
            {
                //they both died. This shouldn't happen. Oops.
                throw new CombatEngineException("Both units dead after combat");
            }

            return(ret);
        }
Example #9
0
 internal int avo(Game_Unit target, WeaponTriangle tri)
 {
     return(avo(target, false, tri));
 }
Example #10
0
 internal virtual int avo(WeaponTriangle tri)
 {
     return(avo(null, tri));
 }