示例#1
0
        private int crt_target(Game_Unit target)
        {
            Data_Weapon weapon = this.attacker_weapon;

            // Staves can't crit
            if (weapon.is_staff())
            {
                return(0);
            }
            if (weapon.Crt < 0)
            {
                return(0);
            }

            // 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;
            int         target_dod;
            int         actor_crt, weapon_crt, skill_crt, support_crt, s_bonus;

            actor_crt = base_crt();
            // Bonus to crit for hit > 100
            if (Constants.Combat.HIT_OVERFLOW)
            {
                int hit_bonus = (int)((hit() - 100) *
                                      Constants.Combat.HIT_OVERFLOW_RATE);
                actor_crt += Math.Max(0, hit_bonus);
            }
            weapon_crt = weapon.Crt;
            skill_crt  = 0;
            attacker.crt_skill(
                ref skill_crt, ref weapon_crt, ref actor_crt,
                weapon, target, magic_attack, Distance);
            support_crt = support_bonus(Combat_Stat_Labels.Crt);
            s_bonus     = attacker.actor.s_rank_bonus(weapon);

            target_dod = this.target_stats().dodge();
            int crit_rate = actor_crt + weapon_crt + skill_crt + support_crt + s_bonus;
            int total_crt = Math.Max(0, crit_rate - target_dod);

            if (magic_attack && attacker.actor.power_type() == Power_Types.Strength)
            {
                total_crt = (int)(total_crt * Constants.Combat.MAGIC_WEAPON_CRT_RATE);
            }
            int result = attacker.crt_target_skill(target, weapon, Distance, total_crt);

            return(result);
        }
 protected override bool is_valid_item(List <Item_Data> items, int i)
 {
     if (unit.actor.is_equippable(items, i))
     {
         var         item_data = items[i];
         Data_Weapon weapon    = item_data.to_weapon;
         if (unit.actor.is_equippable(weapon) && weapon.is_staff())
         {
             if (unit.allies_in_staff_range(new HashSet <Vector2> {
                 unit.loc
             }, i)[0].Count > 0)
             {
                 return(true);
             }
             else if (unit.enemies_in_staff_range(new HashSet <Vector2> {
                 unit.loc
             }, i)[0].Count > 0)
             {
                 return(true);
             }
             else if (unit.untargeted_staff_range(i)[1].Count > 0)
             {
                 return(true);
             }
         }
     }
     return(false);
 }
示例#3
0
        internal virtual int crt()
        {
            if (!has_weapon)
            {
                return(0);
            }
            Data_Weapon weapon = this.attacker_weapon;

            if (weapon.is_staff())
            {
                return(0);
            }

            if (!can_crit())
            {
                return(0);
            }

            // Checks if weapon is magic
            bool magic_attack = attacker.check_magic_attack(weapon);
            int  actor_crt, weapon_crt, skill_crt, support_crt, s_bonus;

            actor_crt  = base_crt();
            weapon_crt = weapon.Crt;
            skill_crt  = 0;
            attacker.crt_skill(
                ref skill_crt, ref weapon_crt, ref actor_crt,
                weapon, null, magic_attack, 1);
            support_crt = support_bonus(Combat_Stat_Labels.Crt);
            s_bonus     = attacker.actor.s_rank_bonus(weapon);
            return(Math.Max(0, actor_crt + weapon_crt + skill_crt + support_crt + s_bonus));
        }
示例#4
0
        public List <Item_Data> valid_sold_items()
        {
            Weapon_Ranks highest_weapon_rank = (Weapon_Ranks)(Enum_Values.GetEnumCount(typeof(Weapon_Ranks)) - 1);

            return(Sold_Items.Where(item_data =>
            {
                // Only weapons are allowed
                if (!item_data.is_weapon)
                {
                    return false;
                }
                Data_Weapon weapon = item_data.to_weapon;
                // Weapons with infinite uses are not allowed, because they really can't be repaired
                if (weapon.infinite_uses)
                {
                    return false;
                }
                // S rank weapons and Prf weapons are not allowed
                if (weapon.is_prf || weapon.Rank == Weapon_Ranks.None || weapon.Rank == highest_weapon_rank)
                {
                    return false;
                }
                // No Hammerne
                if (weapon.is_staff() && weapon.Staff_Traits[(int)Stave_Traits.Repair])
                {
                    return false;
                }
                return true;
            }).ToList());
        }
示例#5
0
        internal virtual int dmg()
        {
            if (!has_weapon)
            {
                return(0);
            }
            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();
            int  actor_dmg, weapon_dmg, skill_dmg, support_dmg;

            if (is_staff)
            {
                return(0); //Yeti
            }
            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));
                skill_dmg   = 0;
                support_dmg = support_bonus(Combat_Stat_Labels.Dmg);
                attacker.dmg_skill(
                    ref skill_dmg, ref weapon_dmg, ref actor_dmg, ref support_dmg,
                    weapon, magic_attack, Distance);
            }
            return(Math.Max(0, actor_dmg + weapon_dmg + skill_dmg + support_dmg));
        }
示例#6
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);
        }
示例#7
0
        internal static float effective_multiplier(
            this Data_Weapon weapon,
            Tactile.Game_Unit unit,
            Tactile.Game_Unit target,
            bool halveOnHealingTerrain = true)
        {
            int effectiveness = 1;

            if (target == null)
            {
                return(effectiveness);
            }
            // Skills: Nullify
            if (target.actor.has_skill("NULL"))
            {
                return(effectiveness);
            }

            foreach (TactileLibrary.ClassTypes type in target.actor.actor_class.Class_Types)
            {
                if (weapon.Effectiveness[(int)type] > effectiveness)
                {
                    effectiveness = weapon.Effectiveness[(int)type];
                }
            }
            // Skills: Smite
            if (unit != null && unit.actor.has_skill("SMITE"))
            {
                if (target != null && !unit.nihil(target))
                {
                    if (target.actor.weapon != null && !weapon.is_staff() && (
                            target.actor.weapon.main_type().Name == "Dark" ||
                            target.actor.weapon.scnd_type().Name == "Dark"))
                    {
                        //target.actor.weapon.Main_Type == TactileLibrary.Weapon_Types.Dark || //Debug
                        //target.actor.weapon.Scnd_Type == TactileLibrary.Weapon_Types.Dark))
                        effectiveness = Math.Max(2, effectiveness);
                    }
                }
            }

            float result = effectiveness;

            if (halveOnHealingTerrain)
            {
                if (target.halve_effectiveness() && effectiveness > 1)
                {
                    result = 1 + (effectiveness - 1) / 2f;
                }
            }
            return(result);
        }
示例#8
0
 protected override bool is_valid_item(List <Item_Data> items, int i)
 {
     if (unit.actor.is_equippable(items, i))
     {
         var         item_data = items[i];
         Data_Weapon weapon    = item_data.to_weapon;
         if (!weapon.is_staff())
         {
             return(unit.enemies_in_range(i, Skill)[0].Any());
         }
     }
     return(false);
 }
示例#9
0
        public bool can_crit()
        {
            Data_Weapon weapon = this.attacker_weapon;

            if (weapon == null)
            {
                return(false);
            }

            if (weapon.is_staff())
            {
                return(false);
            }

            return(weapon.Crt >= 0);
        }
        protected override bool is_valid_item(List <Item_Data> items, int i)
        {
            var item_data = items[i];

            if (item_data.non_equipment || !item_data.is_weapon)
            {
                return(false);
            }

            Data_Weapon weapon = item_data.to_weapon;

            if (unit.actor.is_equippable(weapon) && !weapon.is_staff())
            {
                return(true);
            }
            return(false);
        }
示例#11
0
        internal virtual int hit()
        {
            if (!has_weapon)
            {
                return(0);
            }
            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();
            int  actor_hit, weapon_hit, skill_hit, support_hit, s_bonus;

            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, null, magic_attack, Distance);
                support_hit = support_bonus(Combat_Stat_Labels.Hit);
                s_bonus     = 0;
            }
            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, null, magic_attack, Distance);
                support_hit = support_bonus(Combat_Stat_Labels.Hit);
                s_bonus     = attacker.actor.s_rank_bonus(weapon);
            }
            return(Math.Max(0, actor_hit + weapon_hit + skill_hit + support_hit + s_bonus));
        }
示例#12
0
        protected void initialize(Item_Data item_data, Game_Actor actor)
        {
            Data_Weapon weapon    = item_data.to_weapon;
            int         stats     = !weapon.is_staff() ? 6 : 3;
            bool        effective = false;

            foreach (int bonus in weapon.Effectiveness)
            {
                if (bonus != 1)
                {
                    effective = true;
                    stats++;
                    break;
                }
            }
            for (int i = 0; i < stats; i++)
            {
                Labels.Add(new TextSprite());
                Labels[Labels.Count - 1].loc = new Vector2((i % 3) * 60, (i / 3) * 16);
                if (i % 3 == 2)
                {
                    Labels[Labels.Count - 1].loc += new Vector2(4, 0);
                }
                Labels[Labels.Count - 1].SetFont(Config.UI_FONT, Global.Content, "Yellow");
            }
            //@Yeti: handle weapon type replacement skills better than hardcoding
            bool knife    = (actor != null && actor.has_skill("KNIFE") && weapon.main_type().Name == "Sword" && !weapon.is_magic());
            bool crossbow = (actor != null && actor.has_skill("CROSSBOW") && weapon.main_type().Name == "Bow" && !weapon.Ballista());

            Labels[0].text = weapon.type;
            if (knife)
            {
                Labels[0].text = "Knife";
            }
            if (crossbow)
            {
                Labels[0].text = "Crossbow";
            }
            Labels[1].text = "Rng";
            Labels[2].text = "Wgt";
            // If not a staff
            if (!weapon.is_staff())
            {
                Labels[3].text = "Mgt";
                Labels[4].text = "Hit";
                Labels[5].text = "Crit";
            }
            if (effective)
            {
                Labels[Labels.Count - 1].text = "Effective";
            }

            // Rank
            Rank     = new TextSprite();
            Rank.loc = new Vector2(32, 0);
            if (crossbow)
            {
                Rank.loc.X += 16;
            }
            Rank.SetFont(
                weapon.Rank == Weapon_Ranks.None ? Config.UI_FONT : Config.UI_FONT + "L",
                Global.Content, "Blue", Config.UI_FONT);
            Rank.text = weapon.rank;
            // Range
            Stats.Add(new TextSprite());
            Stats[Stats.Count - 1].loc = new Vector2(92, 0);
            Stats[Stats.Count - 1].SetFont(Config.UI_FONT, Global.Content, "Blue");
            int min_range = weapon.Min_Range;
            int max_range = weapon.Max_Range;

            if (knife && max_range == 1)
            {
                max_range = 2;
            }
            if (weapon.Mag_Range)
            {
                Stats[0].text   = min_range.ToString() + "-Mg/2";
                Stats[0].offset = new Vector2(15, 0);
            }
            else
            {
                if (min_range == max_range)
                {
                    Stats[0].text = min_range.ToString();
                }
                else
                {
                    Stats[0].text = min_range.ToString() + "-" + max_range.ToString();
                }
                Stats[0].offset = new Vector2(Stats[0].text.Length > 1 ? 12 : 0, 0);
            }
            for (int i = 2; i < stats; i++)
            {
                Stats.Add(new RightAdjustedText());
                Stats[Stats.Count - 1].loc = new Vector2((i % 3) * 60 + 40, (i / 3) * 16);
                if (i % 3 == 2)
                {
                    Stats[Stats.Count - 1].loc += new Vector2(4, 0);
                }
                Stats[Stats.Count - 1].SetFont(Config.UI_FONT, Global.Content, "Blue");
            }
            // Wgt
            Stats[1].text = weapon.Wgt.ToString();
            if (actor != null)
            {
                int actor_wgt = actor.weapon_wgt(weapon);
                if (actor_wgt != weapon.Wgt)
                {
                    int difference = actor_wgt - weapon.Wgt;

                    Stat_Bonuses.Add(new TextSprite());
                    Stat_Bonuses[Stat_Bonuses.Count - 1].loc = Stats[1].loc + new Vector2(0, 0);
                    Stat_Bonuses[Stat_Bonuses.Count - 1].SetFont(
                        Config.UI_FONT + "Bonus", Global.Content,
                        difference <= 0 ? "Green" : "Red", Config.UI_FONT);
                    Stat_Bonuses[Stat_Bonuses.Count - 1].text = difference.ToString();
                }
            }
            // Stats
            if (!weapon.is_staff())
            {
                Stats[2].text = weapon.Mgt.ToString();
                if (knife)
                {
                    Stat_Bonuses.Add(new TextSprite());
                    Stat_Bonuses[Stat_Bonuses.Count - 1].loc = Stats[2].loc + new Vector2(0, 0);
                    Stat_Bonuses[Stat_Bonuses.Count - 1].SetFont(
                        Config.UI_FONT + "Bonus", Global.Content, "Red", Config.UI_FONT);
                    Stat_Bonuses[Stat_Bonuses.Count - 1].text = "-3";
                }
                Stats[3].text = weapon.Hit.ToString();
                if (!knife)
                {
                    Stats[3].offset.X = -((Stats[3].text.Length - 1) / 2) * 8;
                }
                if (knife)
                {
                    Stat_Bonuses.Add(new TextSprite());
                    Stat_Bonuses[Stat_Bonuses.Count - 1].loc = Stats[3].loc - Stats[3].offset + new Vector2(0, 0);
                    Stat_Bonuses[Stat_Bonuses.Count - 1].SetFont(
                        Config.UI_FONT + "Bonus", Global.Content, "Green", Config.UI_FONT);
                    Stat_Bonuses[Stat_Bonuses.Count - 1].text = "+10";
                }
                Stats[4].text = weapon.Crt == -1 ? "--" : weapon.Crt.ToString();
            }
            if (effective)
            {
                for (int i = 0; i < weapon.Effectiveness.Length; i++)
                {
                    if (weapon.Effectiveness[i] != 1)
                    {
                        Effectiveness_Icons.Add(new Icon_Sprite());
                        Effectiveness_Icons[Effectiveness_Icons.Count - 1].texture = Global.Content.Load <Texture2D>(@"Graphics/Icons/Class_Types");
                        Effectiveness_Icons[Effectiveness_Icons.Count - 1].size    = new Vector2(16, 16);
                        Effectiveness_Icons[Effectiveness_Icons.Count - 1].columns = 1;
                        Effectiveness_Icons[Effectiveness_Icons.Count - 1].loc     = new Vector2(
                            48 + ((Effectiveness_Icons.Count - 1) * 16), 32);
                        Effectiveness_Icons[Effectiveness_Icons.Count - 1].index = i;

                        Effectiveness_Multipliers.Add(new Effective_WT_Arrow());
                        Effectiveness_Multipliers[Effectiveness_Icons.Count - 1].loc = new Vector2(
                            48 + ((Effectiveness_Icons.Count - 1) * 16), 32);
                        Effectiveness_Multipliers[Effectiveness_Icons.Count - 1].draw_offset = new Vector2(8, 8);
                        Effectiveness_Multipliers[Effectiveness_Icons.Count - 1].set_effectiveness(weapon.Effectiveness[i]);
                    }
                }
            }
        }
示例#13
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);
        }