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); }
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)); }
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()); }
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)); }
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); }
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); }
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); }
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); }
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)); }
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]); } } } }
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); }