Read the weapon block from the cache template item_weapon
Range, speed, damage list and swing anims now come from engine.parsers.objects.ItemTemplate.getWeapon(templateID). Non-weapons and missing templates get an empty block, matching the legacy zero defaults. Offline parity (scripts/p15b.py, 811 WEAPON rows vs COBJECTS/ITEM): 0 differences in speed, range, projectile, idle anim, damage list or either anim list. No duplicate damage types exist, so sum vs first is moot; first entry is used as before. 26 weapons (ammo, lutes, no-stats crossbows) have an empty damage list, same as the DB. No value changes. No comparator removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
441a935bd9
commit
6b2f000434
5 files changed
+48
-33
No files matched your search
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -33,6 +33,9 @@ public class ItemTemplate implements CObjectTemplate {
|
||||
|
||||
public static HashMap<Integer, ItemTemplate> _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 {
|
||||
|
||||
Reference in new issue
Block a user