diff --git a/src/engine/gameManager/CombatManager.java b/src/engine/gameManager/CombatManager.java index 14d96800..266c8a4e 100644 --- a/src/engine/gameManager/CombatManager.java +++ b/src/engine/gameManager/CombatManager.java @@ -147,7 +147,7 @@ public enum CombatManager { if (bonus != null) rangeMod += bonus.getFloatPercentAll(mbEnums.ModType.WeaponRange, mbEnums.SourceType.None); - attackRange += weapon.template.item_weapon_max_range * rangeMod; + attackRange += engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_max_range * rangeMod; } else if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) { //unarmed mob, add the natural attack range from its rune (0 for most melee mobs) @@ -212,7 +212,7 @@ public enum CombatManager { if (weapon != null) { - float wepSpeed = (int) (weapon.template.item_weapon_wepspeed); + float wepSpeed = (int) (engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_wepspeed); if (weapon.getBonusPercent(mbEnums.ModType.WeaponSpeed, mbEnums.SourceType.None) != 0f) //add weapon speed bonus wepSpeed *= (1 + weapon.getBonus(mbEnums.ModType.WeaponSpeed, mbEnums.SourceType.None)); @@ -417,7 +417,7 @@ public enum CombatManager { if (((Mob) attacker).isSiege()) damageType = mbEnums.DamageType.SIEGE; } else { - damageType = (mbEnums.DamageType) attacker.charItemManager.getEquipped().get(slot).template.item_weapon_damage.keySet().toArray()[0]; + damageType = engine.parsers.objects.ItemTemplate.getWeapon(attacker.charItemManager.getEquipped().get(slot).templateID).weapon_damage.get(0).damage_type; } //get resists @@ -585,6 +585,7 @@ public enum CombatManager { return 75; int token; + engine.parsers.objects.ItemTemplate.Weapon weapon = engine.parsers.objects.ItemTemplate.getWeapon(wb.template_id); if (dpj != null) { @@ -606,16 +607,16 @@ public enum CombatManager { //Item can only be equipped in one slot, return animation for that slot if (wb.item_eq_slots_or.size() == 1) { if (wb.item_eq_slots_or.iterator().next().equals(mbEnums.EquipSlotType.RHELD)) { - anim = wb.weapon_attack_anim_right.get(0)[0]; + anim = weapon.weapon_attack_anim_right.get(0)[0]; if (dpj != null) { - random = ThreadLocalRandom.current().nextInt(wb.weapon_attack_anim_right.size()); - anim = wb.weapon_attack_anim_right.get(random)[0]; + random = ThreadLocalRandom.current().nextInt(weapon.weapon_attack_anim_right.size()); + anim = weapon.weapon_attack_anim_right.get(random)[0]; } } else { - anim = wb.weapon_attack_anim_left.get(0)[0]; + anim = weapon.weapon_attack_anim_left.get(0)[0]; if (dpj != null) { - random = ThreadLocalRandom.current().nextInt(wb.weapon_attack_anim_left.size()); - anim = wb.weapon_attack_anim_left.get(random)[0]; + random = ThreadLocalRandom.current().nextInt(weapon.weapon_attack_anim_left.size()); + anim = weapon.weapon_attack_anim_left.get(random)[0]; } } return anim; @@ -623,16 +624,16 @@ public enum CombatManager { //Item can be equipped in either hand, and should have animation sets for each hand if (slot.equals(mbEnums.EquipSlotType.RHELD)) { - anim = wb.weapon_attack_anim_right.get(0)[0]; + anim = weapon.weapon_attack_anim_right.get(0)[0]; if (dpj != null) { - random = ThreadLocalRandom.current().nextInt(wb.weapon_attack_anim_right.size()); - anim = wb.weapon_attack_anim_right.get(random)[0]; + random = ThreadLocalRandom.current().nextInt(weapon.weapon_attack_anim_right.size()); + anim = weapon.weapon_attack_anim_right.get(random)[0]; } } else { - anim = wb.weapon_attack_anim_left.get(0)[0]; + anim = weapon.weapon_attack_anim_left.get(0)[0]; if (dpj != null) { - random = ThreadLocalRandom.current().nextInt(wb.weapon_attack_anim_left.size()); - anim = wb.weapon_attack_anim_left.get(random)[0]; + random = ThreadLocalRandom.current().nextInt(weapon.weapon_attack_anim_left.size()); + anim = weapon.weapon_attack_anim_left.get(random)[0]; } } return anim; diff --git a/src/engine/gameManager/NPCManager.java b/src/engine/gameManager/NPCManager.java index 8ab554f2..91cd672a 100644 --- a/src/engine/gameManager/NPCManager.java +++ b/src/engine/gameManager/NPCManager.java @@ -321,10 +321,10 @@ public enum NPCManager { else primaryStat = guard.getStatDexCurrent(); - guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin() + weapon.template.item_weapon_damage.values().iterator().next()[0]) * rankModifier) + primaryStat; - guard.maxDamageHandOne = (int) ((guard.mobBase.getDamageMax() + weapon.template.item_weapon_damage.values().iterator().next()[1]) * rankModifier) + primaryStat; - guard.speedHandOne = weapon.template.item_weapon_wepspeed; - guard.rangeHandOne = weapon.template.item_weapon_max_range; + guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin() + engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_damage.get(0).damage_min) * rankModifier) + primaryStat; + guard.maxDamageHandOne = (int) ((guard.mobBase.getDamageMax() + engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_damage.get(0).damage_max) * rankModifier) + primaryStat; + guard.speedHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_wepspeed; + guard.rangeHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_max_range; } else if (guard.charItemManager.equipped.containsKey(mbEnums.EquipSlotType.LHELD) && !ItemManager.isShield(guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD).template)) { //has off hand weapon Item weapon = guard.charItemManager.equipped.get(mbEnums.EquipSlotType.LHELD); @@ -332,10 +332,10 @@ public enum NPCManager { primaryStat = guard.getStatStrCurrent(); else primaryStat = guard.getStatDexCurrent(); - guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin() + weapon.template.item_weapon_damage.values().iterator().next()[0]) * rankModifier) + primaryStat; - guard.maxDamageHandOne = (int) ((guard.mobBase.getDamageMax() + weapon.template.item_weapon_damage.values().iterator().next()[1]) * rankModifier) + primaryStat; - guard.speedHandOne = weapon.template.item_weapon_wepspeed; - guard.rangeHandOne = weapon.template.item_weapon_max_range; + guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin() + engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_damage.get(0).damage_min) * rankModifier) + primaryStat; + guard.maxDamageHandOne = (int) ((guard.mobBase.getDamageMax() + engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_damage.get(0).damage_max) * rankModifier) + primaryStat; + guard.speedHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_wepspeed; + guard.rangeHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_max_range; } else { primaryStat = guard.getStatStrCurrent(); guard.minDamageHandOne = (int) ((guard.mobBase.getDamageMin()) * rankModifier) + primaryStat; diff --git a/src/engine/objects/AbstractCharacter.java b/src/engine/objects/AbstractCharacter.java index 00770cb0..8344eba7 100644 --- a/src/engine/objects/AbstractCharacter.java +++ b/src/engine/objects/AbstractCharacter.java @@ -693,6 +693,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject { // make sure weapon exists boolean noWeapon = false; ItemTemplate weaponTemplate = null; + engine.parsers.objects.ItemTemplate.Damage damage; if (weapon == null) noWeapon = true; @@ -751,9 +752,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject { } else { if (mainHand) - abstractCharacter.rangeHandOne = weapon.template.item_weapon_max_range * (1 + (abstractCharacter.statStrBase / 600)); + abstractCharacter.rangeHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_max_range * (1 + (abstractCharacter.statStrBase / 600)); else - abstractCharacter.rangeHandTwo = weapon.template.item_weapon_max_range * (1 + (abstractCharacter.statStrBase / 600)); + abstractCharacter.rangeHandTwo = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_max_range * (1 + (abstractCharacter.statStrBase / 600)); if (abstractCharacter.bonuses != null) { float range_bonus = 1 + abstractCharacter.bonuses.getFloatPercentAll(ModType.WeaponRange, SourceType.None); @@ -773,10 +774,10 @@ public abstract class AbstractCharacter extends AbstractWorldObject { // mastDam = CharacterSkill.getQuickMastery(this, wb.getMastery()); else mastDam = masteryPercentage; - int[] damages = (int[]) weaponTemplate.item_weapon_damage.values().toArray()[0]; + damage = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_damage.get(0); - min = damages[0]; - max = damages[1]; + min = damage.damage_min; + max = damage.damage_max; strBased = engine.parsers.objects.ItemTemplate._items.get(weapon.templateID).item_primary_attr == AttributeType.Strength; } @@ -827,7 +828,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject { //calculate speed if (weaponTemplate != null) - speed = weaponTemplate.item_weapon_wepspeed; + speed = engine.parsers.objects.ItemTemplate.getWeapon(weaponTemplate.template_id).weapon_wepspeed; else speed = 20f; //unarmed attack speed if (weapon != null) @@ -1508,9 +1509,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject { } float range = 8; if ((this).charItemManager.equipped.get(EquipSlotType.RHELD) != null) { - range = ((Mob) this).charItemManager.equipped.get(EquipSlotType.RHELD).template.item_weapon_max_range; + range = engine.parsers.objects.ItemTemplate.getWeapon(((Mob) this).charItemManager.equipped.get(EquipSlotType.RHELD).templateID).weapon_max_range; } else if (((Mob) this).charItemManager.equipped.get(EquipSlotType.LHELD) != null) { - range = ((Mob) this).charItemManager.equipped.get(EquipSlotType.LHELD).template.item_weapon_max_range; + range = engine.parsers.objects.ItemTemplate.getWeapon(((Mob) this).charItemManager.equipped.get(EquipSlotType.LHELD).templateID).weapon_max_range; } else { // Unarmed: use the rune natural attack range when it has one (e.g. Gasser 150), not clamped. diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index f81b62d2..9dae97f7 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -3791,8 +3791,8 @@ public class PlayerCharacter extends AbstractCharacter { this.bonuses.setBool(ModType.Parry, SourceType.None, false); if ((this.baseClass != null && this.baseClass.getObjectUUID() == 2500) || (this.promotionClass != null && this.promotionClass.getObjectUUID() == 2520)) - if (wbMain == null || wbMain.item_weapon_max_range < MBServerStatics.RANGED_WEAPON_RANGE) - if (wbOff == null || wbOff.item_weapon_max_range < MBServerStatics.RANGED_WEAPON_RANGE) + if (wbMain == null || engine.parsers.objects.ItemTemplate.getWeapon(wbMain.template_id).weapon_max_range < MBServerStatics.RANGED_WEAPON_RANGE) + if (wbOff == null || engine.parsers.objects.ItemTemplate.getWeapon(wbOff.template_id).weapon_max_range < MBServerStatics.RANGED_WEAPON_RANGE) this.bonuses.setBool(ModType.Parry, SourceType.None, true); } diff --git a/src/engine/parsers/objects/ItemTemplate.java b/src/engine/parsers/objects/ItemTemplate.java index 84787ddb..07b16829 100644 --- a/src/engine/parsers/objects/ItemTemplate.java +++ b/src/engine/parsers/objects/ItemTemplate.java @@ -33,6 +33,9 @@ public class ItemTemplate implements CObjectTemplate { public static HashMap _items = new HashMap<>(); + // Legacy templates zero-filled the weapon block on non-weapons; held shields and the like rely on it. + private static final Weapon NO_WEAPON = new Weapon(); + public int template_id; // obj_ @@ -463,6 +466,16 @@ public class ItemTemplate implements CObjectTemplate { return item_ignore_saved_actions; } + public static Weapon getWeapon(int templateID) { + + ItemTemplate template = _items.get(templateID); + + if (template == null || template.item_weapon == null) + return NO_WEAPON; + + return template.item_weapon; + } + // item_weapon (ArcAttackInfo_LoadWeapon, sb.exe 0x61FA60). public static class Weapon {