refactor(opl): Consolidate AOS attribute OPL emission into per-family GetProperties (#2501)
## Summary Consolidates the duplicated inline AOS attribute → `ObjectPropertyList` emission that each item base copy-pastes into per-family `GetProperties(IPropertyList)` methods, mirroring the existing `AosSkillBonuses.GetProperties` precedent. ### Per-family `GetProperties(IPropertyList)` - **`AosAttributes`** — the 24 common attributes in canonical cliloc-ascending order, with optional `damageBonus` / `hitChanceBonus` / `luckBonus` params so item-computed bonuses (e.g. `GetDamageBonus()`) stay out of the family type. - **`AosWeaponAttributes`** — `UseBestSkill`, the `Hit*` block (1060416–1060430), `MageWeapon` (`30 - prop`), `SelfRepair`. - **`AosArmorAttributes`** — `MageArmor`, `SelfRepair` (the always-direct members; `LowerStatReq`/`DurabilityBonus` stay inline since they're item-computed in armor but container-direct in clothing). ### Rewired all 6 `AosAttributes`-emitting item bases `BaseJewel`, `BaseArmor`, `BaseClothing`, `BaseWeapon`, `BaseTalisman`, `Spellbook` now call the family methods instead of inlining the chain. Net: large dedup in `BaseWeapon`/`BaseArmor`/`BaseClothing`/`BaseTalisman`/`Spellbook`. ## Behavior change: tooltip line **order** (set preserved) This is **not** a pure no-op refactor, and that's unavoidable. Today the families are emitted **interleaved in cliloc order**, and the relative order differs per item class — e.g. `BonusDex` (1060409) is emitted early in `BaseArmor` but **after** the `Hit*` block in `BaseWeapon`. No single emission order reproduces every class byte-for-byte, so consolidating into contiguous per-family blocks necessarily **de-interleaves**: lines regroup **specific → general** (family-specific, then common `AosAttributes`). - The **set** of emitted `(cliloc, argument)` lines per item is preserved **exactly** — nothing dropped, added, or value-changed. - Only the **order** of lines within a tooltip changes for `BaseArmor` / `BaseWeapon` / `BaseClothing`. `BaseJewel` / `BaseTalisman` / `Spellbook` were already canonical, so those are byte-identical. ## Tests - **Golden set-invariance tests** per item base (`BaseArmor/Clothing/Jewel/Weapon/Talisman/Spellbook PropertiesTests`) — each was written to pass against current `main` **before** the rewire (locking the emitted-line set), then confirmed still passing after, proving no line is lost/added/changed. - Family-level unit tests for each `GetProperties` (canonical order, computed-bonus folding, the `AosArmorAttributes` exclusions). - `dotnet build` clean; full `UOContent.Tests` green. (Pre-existing `AccountPacket`/`GumpPacket`/`MobilePacket`/`ClientEnumerator` golden-test failures reproduce on unmodified `main` and are unrelated to this change.)
This commit is contained in:
parent
0502f98050
commit
f7c44f7c10
17 changed files with 779 additions and 842 deletions
|
|
@ -0,0 +1,71 @@
|
|||
using System;
|
||||
using System.Buffers.Binary;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Xunit;
|
||||
|
||||
namespace UOContent.Tests;
|
||||
|
||||
[Collection("Sequential UOContent Tests")]
|
||||
public class AosArmorAttributesPropertiesTests
|
||||
{
|
||||
private static Dictionary<int, string> Decode(ObjectPropertyList opl)
|
||||
{
|
||||
opl.Terminate();
|
||||
var buffer = opl.Buffer;
|
||||
var map = new Dictionary<int, string>();
|
||||
var pos = 15;
|
||||
while (true)
|
||||
{
|
||||
var cliloc = BinaryPrimitives.ReadInt32BigEndian(buffer.AsSpan(pos));
|
||||
pos += 4;
|
||||
if (cliloc == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var byteLen = BinaryPrimitives.ReadUInt16BigEndian(buffer.AsSpan(pos));
|
||||
pos += 2;
|
||||
map[cliloc] = Encoding.Unicode.GetString(buffer, pos, byteLen);
|
||||
pos += byteLen;
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmitsMageArmorAndSelfRepair_DoesNotReadLowerStatReqOrDurabilityFromContainer()
|
||||
{
|
||||
var attrs = new AosArmorAttributes(null)
|
||||
{
|
||||
MageArmor = 1,
|
||||
SelfRepair = 4,
|
||||
LowerStatReq = 50, // container value must NOT be auto-emitted (it's passed in by the consumer)
|
||||
DurabilityBonus = 10 // never emitted by this method
|
||||
};
|
||||
|
||||
var opl = new ObjectPropertyList(null);
|
||||
attrs.GetProperties(opl); // no lowerStatReq arg
|
||||
var map = Decode(opl);
|
||||
|
||||
Assert.Equal("", map[1060437]); // MageArmor (no-arg)
|
||||
Assert.Equal("4", map[1060450]); // SelfRepair
|
||||
Assert.False(map.ContainsKey(1060435)); // LowerStatReq NOT read from container
|
||||
Assert.False(map.ContainsKey(1060410)); // DurabilityBonus excluded
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmitsLowerStatReqWhenPassed()
|
||||
{
|
||||
var attrs = new AosArmorAttributes(null) { MageArmor = 1, LowerStatReq = 50 };
|
||||
|
||||
var opl = new ObjectPropertyList(null);
|
||||
attrs.GetProperties(opl, lowerStatReq: 77); // computed value passed by the consumer, not the raw 50
|
||||
var map = Decode(opl);
|
||||
|
||||
Assert.Equal("77", map[1060435]); // emitted from the param, not the container's 50
|
||||
Assert.Equal("", map[1060437]); // MageArmor still emitted
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
using System;
|
||||
using System.Buffers.Binary;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Xunit;
|
||||
|
||||
namespace UOContent.Tests;
|
||||
|
||||
[Collection("Sequential UOContent Tests")]
|
||||
public class AosAttributesPropertiesTests
|
||||
{
|
||||
private static Dictionary<int, string> Decode(ObjectPropertyList opl)
|
||||
{
|
||||
opl.Terminate();
|
||||
var buffer = opl.Buffer;
|
||||
var map = new Dictionary<int, string>();
|
||||
var pos = 15;
|
||||
while (true)
|
||||
{
|
||||
var cliloc = BinaryPrimitives.ReadInt32BigEndian(buffer.AsSpan(pos));
|
||||
pos += 4;
|
||||
if (cliloc == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var byteLen = BinaryPrimitives.ReadUInt16BigEndian(buffer.AsSpan(pos));
|
||||
pos += 2;
|
||||
map[cliloc] = Encoding.Unicode.GetString(buffer, pos, byteLen);
|
||||
pos += byteLen;
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmitsRawAttributesInCanonicalOrder()
|
||||
{
|
||||
var attrs = new AosAttributes(null)
|
||||
{
|
||||
DefendChance = 5,
|
||||
BonusStr = 10,
|
||||
NightSight = 1,
|
||||
SpellChanneling = 1,
|
||||
WeaponSpeed = 7
|
||||
};
|
||||
|
||||
var opl = new ObjectPropertyList(null);
|
||||
attrs.GetProperties(opl);
|
||||
var map = Decode(opl);
|
||||
|
||||
Assert.Equal("5", map[1060408]); // DefendChance
|
||||
Assert.Equal("10", map[1060485]); // BonusStr
|
||||
Assert.Equal("", map[1060441]); // NightSight (no-arg)
|
||||
Assert.Equal("", map[1060482]); // SpellChanneling (no-arg)
|
||||
Assert.Equal("7", map[1060486]); // WeaponSpeed
|
||||
Assert.False(map.ContainsKey(1060401)); // WeaponDamage not set
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesComputedBonuses()
|
||||
{
|
||||
var attrs = new AosAttributes(null) { WeaponDamage = 10, AttackChance = 4, Luck = 100 };
|
||||
|
||||
var opl = new ObjectPropertyList(null);
|
||||
attrs.GetProperties(opl, damageBonus: 5, hitChanceBonus: 3, luckBonus: 50);
|
||||
var map = Decode(opl);
|
||||
|
||||
Assert.Equal("15", map[1060401]); // WeaponDamage + damageBonus
|
||||
Assert.Equal("7", map[1060415]); // AttackChance + hitChanceBonus
|
||||
Assert.Equal("150", map[1060436]); // Luck + luckBonus
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
using System;
|
||||
using System.Buffers.Binary;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Xunit;
|
||||
|
||||
namespace UOContent.Tests;
|
||||
|
||||
[Collection("Sequential UOContent Tests")]
|
||||
public class AosWeaponAttributesPropertiesTests
|
||||
{
|
||||
private static Dictionary<int, string> Decode(ObjectPropertyList opl)
|
||||
{
|
||||
opl.Terminate();
|
||||
var buffer = opl.Buffer;
|
||||
var map = new Dictionary<int, string>();
|
||||
var pos = 15;
|
||||
while (true)
|
||||
{
|
||||
var cliloc = BinaryPrimitives.ReadInt32BigEndian(buffer.AsSpan(pos));
|
||||
pos += 4;
|
||||
if (cliloc == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var byteLen = BinaryPrimitives.ReadUInt16BigEndian(buffer.AsSpan(pos));
|
||||
pos += 2;
|
||||
map[cliloc] = Encoding.Unicode.GetString(buffer, pos, byteLen);
|
||||
pos += byteLen;
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmitsHitEffectsUseBestSkillMageWeaponSelfRepair()
|
||||
{
|
||||
var attrs = new AosWeaponAttributes(null)
|
||||
{
|
||||
UseBestSkill = 1,
|
||||
HitFireball = 12,
|
||||
HitLeechHits = 20,
|
||||
MageWeapon = 25,
|
||||
SelfRepair = 3
|
||||
};
|
||||
|
||||
var opl = new ObjectPropertyList(null);
|
||||
attrs.GetProperties(opl);
|
||||
var map = Decode(opl);
|
||||
|
||||
Assert.Equal("", map[1060400]); // UseBestSkill (no-arg)
|
||||
Assert.Equal("12", map[1060420]); // HitFireball
|
||||
Assert.Equal("20", map[1060422]); // HitLeechHits
|
||||
Assert.Equal("5", map[1060438]); // MageWeapon => 30 - 25
|
||||
Assert.Equal("3", map[1060450]); // SelfRepair
|
||||
Assert.False(map.ContainsKey(1060435)); // LowerStatReq not emitted without the param
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmitsLowerStatReqWhenPassed()
|
||||
{
|
||||
var attrs = new AosWeaponAttributes(null) { MageWeapon = 25 };
|
||||
|
||||
var opl = new ObjectPropertyList(null);
|
||||
attrs.GetProperties(opl, lowerStatReq: 40); // computed value passed by the weapon
|
||||
var map = Decode(opl);
|
||||
|
||||
Assert.Equal("40", map[1060435]); // lower requirements, in cliloc order before MageWeapon
|
||||
Assert.Equal("5", map[1060438]); // MageWeapon still emitted
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
using Server.Items;
|
||||
using Xunit;
|
||||
|
||||
namespace UOContent.Tests;
|
||||
|
||||
[Collection("Sequential UOContent Tests")]
|
||||
public class BaseArmorPropertiesTests
|
||||
{
|
||||
[Fact]
|
||||
public void Armor_AttributeLineSet_Preserved()
|
||||
{
|
||||
var armor = new PlateChest();
|
||||
try
|
||||
{
|
||||
armor.Attributes.DefendChance = 5;
|
||||
armor.Attributes.BonusDex = 8;
|
||||
armor.Attributes.Luck = 40;
|
||||
armor.Attributes.SpellChanneling = 1;
|
||||
armor.Attributes.IncreasedKarmaLoss = 2;
|
||||
armor.ArmorAttributes.MageArmor = 1;
|
||||
armor.ArmorAttributes.SelfRepair = 3;
|
||||
armor.ArmorAttributes.LowerStatReq = 50;
|
||||
|
||||
var map = ItemOplTestHelper.DecodeAttributeLines(armor);
|
||||
|
||||
Assert.Equal("5", map[1060408]); // DefendChance
|
||||
Assert.Equal("8", map[1060409]); // BonusDex
|
||||
Assert.Equal("40", map[1060436]); // Luck (GetLuckBonus()==0 unequipped)
|
||||
Assert.Equal("", map[1060482]); // SpellChanneling
|
||||
Assert.Equal("2", map[1075210]); // IncreasedKarmaLoss
|
||||
Assert.Equal("", map[1060437]); // MageArmor
|
||||
Assert.Equal("3", map[1060450]); // SelfRepair
|
||||
Assert.Equal("50", map[1060435]); // LowerStatReq (inline via GetLowerStatReq)
|
||||
}
|
||||
finally
|
||||
{
|
||||
armor.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
using Server.Items;
|
||||
using Xunit;
|
||||
|
||||
namespace UOContent.Tests;
|
||||
|
||||
[Collection("Sequential UOContent Tests")]
|
||||
public class BaseClothingPropertiesTests
|
||||
{
|
||||
[Fact]
|
||||
public void Clothing_AttributeLineSet_Preserved()
|
||||
{
|
||||
var shirt = new FancyShirt();
|
||||
try
|
||||
{
|
||||
shirt.Attributes.DefendChance = 5;
|
||||
shirt.Attributes.Luck = 25;
|
||||
shirt.Attributes.SpellChanneling = 1;
|
||||
shirt.ClothingAttributes.MageArmor = 1;
|
||||
shirt.ClothingAttributes.SelfRepair = 2;
|
||||
shirt.ClothingAttributes.LowerStatReq = 30;
|
||||
shirt.ClothingAttributes.DurabilityBonus = 15;
|
||||
|
||||
var map = ItemOplTestHelper.DecodeAttributeLines(shirt);
|
||||
|
||||
Assert.Equal("5", map[1060408]); // DefendChance
|
||||
Assert.Equal("25", map[1060436]); // Luck (raw)
|
||||
Assert.Equal("", map[1060482]); // SpellChanneling
|
||||
Assert.Equal("", map[1060437]); // MageArmor
|
||||
Assert.Equal("2", map[1060450]); // SelfRepair
|
||||
Assert.Equal("30", map[1060435]); // LowerStatReq (direct)
|
||||
Assert.Equal("15", map[1060410]); // DurabilityBonus (direct)
|
||||
}
|
||||
finally
|
||||
{
|
||||
shirt.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
using Server.Items;
|
||||
using Xunit;
|
||||
|
||||
namespace UOContent.Tests;
|
||||
|
||||
[Collection("Sequential UOContent Tests")]
|
||||
public class BaseJewelPropertiesTests
|
||||
{
|
||||
[Fact]
|
||||
public void Jewel_AttributeLineSet_Preserved()
|
||||
{
|
||||
var ring = new GoldRing();
|
||||
try
|
||||
{
|
||||
ring.Attributes.DefendChance = 5;
|
||||
ring.Attributes.BonusStr = 10;
|
||||
ring.Attributes.Luck = 100;
|
||||
ring.Attributes.NightSight = 1;
|
||||
ring.Attributes.SpellChanneling = 1;
|
||||
ring.Attributes.IncreasedKarmaLoss = 3;
|
||||
|
||||
var map = ItemOplTestHelper.DecodeAttributeLines(ring);
|
||||
|
||||
Assert.Equal("5", map[1060408]); // DefendChance
|
||||
Assert.Equal("10", map[1060485]); // BonusStr
|
||||
Assert.Equal("100", map[1060436]); // Luck (raw; jewel has no luck bonus)
|
||||
Assert.Equal("", map[1060441]); // NightSight
|
||||
Assert.Equal("", map[1060482]); // SpellChanneling
|
||||
Assert.Equal("3", map[1075210]); // IncreasedKarmaLoss (Core.ML EJ)
|
||||
}
|
||||
finally
|
||||
{
|
||||
ring.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
using Server.Items;
|
||||
using Xunit;
|
||||
|
||||
namespace UOContent.Tests;
|
||||
|
||||
[Collection("Sequential UOContent Tests")]
|
||||
public class BaseTalismanPropertiesTests
|
||||
{
|
||||
[Fact]
|
||||
public void GetProperties_EmitsAosAttributeLines()
|
||||
{
|
||||
var item = new RandomTalisman();
|
||||
try
|
||||
{
|
||||
item.Attributes.DefendChance = 10;
|
||||
item.Attributes.BonusStr = 5;
|
||||
item.Attributes.Luck = 50;
|
||||
item.Attributes.NightSight = 1;
|
||||
item.Attributes.SpellChanneling = 1;
|
||||
item.Attributes.IncreasedKarmaLoss = 2;
|
||||
|
||||
var lines = ItemOplTestHelper.DecodeAttributeLines(item);
|
||||
|
||||
Assert.True(lines.ContainsKey(1060408)); // DefendChance
|
||||
Assert.Equal("10", lines[1060408]);
|
||||
Assert.True(lines.ContainsKey(1060485)); // BonusStr
|
||||
Assert.Equal("5", lines[1060485]);
|
||||
Assert.True(lines.ContainsKey(1060436)); // Luck
|
||||
Assert.Equal("50", lines[1060436]);
|
||||
Assert.True(lines.ContainsKey(1060441)); // NightSight
|
||||
Assert.Equal("", lines[1060441]);
|
||||
Assert.True(lines.ContainsKey(1060482)); // SpellChanneling
|
||||
Assert.Equal("", lines[1060482]);
|
||||
Assert.True(lines.ContainsKey(1075210)); // IncreasedKarmaLoss
|
||||
Assert.Equal("2", lines[1075210]);
|
||||
}
|
||||
finally
|
||||
{
|
||||
item.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
using Server.Items;
|
||||
using Xunit;
|
||||
|
||||
namespace UOContent.Tests;
|
||||
|
||||
[Collection("Sequential UOContent Tests")]
|
||||
public class BaseWeaponPropertiesTests
|
||||
{
|
||||
[Fact]
|
||||
public void Weapon_AttributeLineSet_Preserved()
|
||||
{
|
||||
var weapon = new Longsword();
|
||||
try
|
||||
{
|
||||
weapon.Attributes.DefendChance = 5;
|
||||
weapon.Attributes.BonusInt = 6;
|
||||
weapon.Attributes.SpellChanneling = 1;
|
||||
weapon.WeaponAttributes.UseBestSkill = 1;
|
||||
weapon.WeaponAttributes.HitFireball = 12;
|
||||
weapon.WeaponAttributes.MageWeapon = 25;
|
||||
weapon.WeaponAttributes.SelfRepair = 3;
|
||||
|
||||
var map = ItemOplTestHelper.DecodeAttributeLines(weapon);
|
||||
|
||||
Assert.Equal("5", map[1060408]); // DefendChance
|
||||
Assert.Equal("6", map[1060432]); // BonusInt
|
||||
Assert.Equal("", map[1060482]); // SpellChanneling
|
||||
Assert.Equal("", map[1060400]); // UseBestSkill
|
||||
Assert.Equal("12", map[1060420]); // HitFireball
|
||||
Assert.Equal("5", map[1060438]); // MageWeapon (30 - 25)
|
||||
Assert.Equal("3", map[1060450]); // SelfRepair
|
||||
}
|
||||
finally
|
||||
{
|
||||
weapon.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
using System;
|
||||
using System.Buffers.Binary;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Server;
|
||||
|
||||
namespace UOContent.Tests;
|
||||
|
||||
public static class ItemOplTestHelper
|
||||
{
|
||||
// Builds the item's OPL and returns attribute/property cliloc lines (>= 1060000),
|
||||
// ignoring base-item lines (name, weight, etc.) so tests isolate the attribute surface.
|
||||
public static Dictionary<int, string> DecodeAttributeLines(Item item)
|
||||
{
|
||||
var opl = new ObjectPropertyList(item);
|
||||
item.GetProperties(opl);
|
||||
opl.Terminate();
|
||||
|
||||
var buffer = opl.Buffer;
|
||||
var map = new Dictionary<int, string>();
|
||||
var pos = 15;
|
||||
while (true)
|
||||
{
|
||||
var cliloc = BinaryPrimitives.ReadInt32BigEndian(buffer.AsSpan(pos));
|
||||
pos += 4;
|
||||
if (cliloc == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var byteLen = BinaryPrimitives.ReadUInt16BigEndian(buffer.AsSpan(pos));
|
||||
pos += 2;
|
||||
var arg = Encoding.Unicode.GetString(buffer, pos, byteLen);
|
||||
pos += byteLen;
|
||||
|
||||
if (cliloc is >= 1060000 and < 1080000)
|
||||
{
|
||||
map[cliloc] = arg;
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
using Server.Items;
|
||||
using Xunit;
|
||||
|
||||
namespace UOContent.Tests;
|
||||
|
||||
[Collection("Sequential UOContent Tests")]
|
||||
public class SpellbookPropertiesTests
|
||||
{
|
||||
[Fact]
|
||||
public void GetProperties_EmitsAosAttributeLines()
|
||||
{
|
||||
var item = new Spellbook();
|
||||
try
|
||||
{
|
||||
item.Attributes.CastRecovery = 3;
|
||||
item.Attributes.LowerManaCost = 8;
|
||||
item.Attributes.Luck = 75;
|
||||
item.Attributes.NightSight = 1;
|
||||
item.Attributes.SpellChanneling = 1;
|
||||
item.Attributes.IncreasedKarmaLoss = 2;
|
||||
|
||||
var lines = ItemOplTestHelper.DecodeAttributeLines(item);
|
||||
|
||||
Assert.True(lines.ContainsKey(1060412)); // CastRecovery
|
||||
Assert.Equal("3", lines[1060412]);
|
||||
Assert.True(lines.ContainsKey(1060433)); // LowerManaCost
|
||||
Assert.Equal("8", lines[1060433]);
|
||||
Assert.True(lines.ContainsKey(1060436)); // Luck
|
||||
Assert.Equal("75", lines[1060436]);
|
||||
Assert.True(lines.ContainsKey(1060441)); // NightSight
|
||||
Assert.Equal("", lines[1060441]);
|
||||
Assert.True(lines.ContainsKey(1060482)); // SpellChanneling
|
||||
Assert.Equal("", lines[1060482]);
|
||||
Assert.True(lines.ContainsKey(1075210)); // IncreasedKarmaLoss
|
||||
Assert.Equal("2", lines[1075210]);
|
||||
}
|
||||
finally
|
||||
{
|
||||
item.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1323,140 +1323,9 @@ namespace Server.Items
|
|||
list.Add(1061078, prop); // artifact rarity ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.WeaponDamage) != 0)
|
||||
{
|
||||
list.Add(1060401, prop); // damage increase ~1_val~%
|
||||
}
|
||||
ArmorAttributes.GetProperties(list);
|
||||
|
||||
if ((prop = Attributes.DefendChance) != 0)
|
||||
{
|
||||
list.Add(1060408, prop); // defense chance increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusDex) != 0)
|
||||
{
|
||||
list.Add(1060409, prop); // dexterity bonus ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.EnhancePotions) != 0)
|
||||
{
|
||||
list.Add(1060411, prop); // enhance potions ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.CastRecovery) != 0)
|
||||
{
|
||||
list.Add(1060412, prop); // faster cast recovery ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.CastSpeed) != 0)
|
||||
{
|
||||
list.Add(1060413, prop); // faster casting ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.AttackChance) != 0)
|
||||
{
|
||||
list.Add(1060415, prop); // hit chance increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusHits) != 0)
|
||||
{
|
||||
list.Add(1060431, prop); // hit point increase ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusInt) != 0)
|
||||
{
|
||||
list.Add(1060432, prop); // intelligence bonus ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.LowerManaCost) != 0)
|
||||
{
|
||||
list.Add(1060433, prop); // lower mana cost ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.LowerRegCost) != 0)
|
||||
{
|
||||
list.Add(1060434, prop); // lower reagent cost ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = GetLowerStatReq()) != 0)
|
||||
{
|
||||
list.Add(1060435, prop); // lower requirements ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = GetLuckBonus() + Attributes.Luck) != 0)
|
||||
{
|
||||
list.Add(1060436, prop); // luck ~1_val~
|
||||
}
|
||||
|
||||
if (ArmorAttributes.MageArmor != 0)
|
||||
{
|
||||
list.Add(1060437); // mage armor
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusMana) != 0)
|
||||
{
|
||||
list.Add(1060439, prop); // mana increase ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.RegenMana) != 0)
|
||||
{
|
||||
list.Add(1060440, prop); // mana regeneration ~1_val~
|
||||
}
|
||||
|
||||
if (Attributes.NightSight != 0)
|
||||
{
|
||||
list.Add(1060441); // night sight
|
||||
}
|
||||
|
||||
if ((prop = Attributes.ReflectPhysical) != 0)
|
||||
{
|
||||
list.Add(1060442, prop); // reflect physical damage ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.RegenStam) != 0)
|
||||
{
|
||||
list.Add(1060443, prop); // stamina regeneration ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.RegenHits) != 0)
|
||||
{
|
||||
list.Add(1060444, prop); // hit point regeneration ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = ArmorAttributes.SelfRepair) != 0)
|
||||
{
|
||||
list.Add(1060450, prop); // self repair ~1_val~
|
||||
}
|
||||
|
||||
if (Attributes.SpellChanneling != 0)
|
||||
{
|
||||
list.Add(1060482); // spell channeling
|
||||
}
|
||||
|
||||
if ((prop = Attributes.SpellDamage) != 0)
|
||||
{
|
||||
list.Add(1060483, prop); // spell damage increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusStam) != 0)
|
||||
{
|
||||
list.Add(1060484, prop); // stamina increase ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusStr) != 0)
|
||||
{
|
||||
list.Add(1060485, prop); // strength bonus ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.WeaponSpeed) != 0)
|
||||
{
|
||||
list.Add(1060486, prop); // swing speed increase ~1_val~%
|
||||
}
|
||||
|
||||
if (Core.ML && (prop = Attributes.IncreasedKarmaLoss) != 0)
|
||||
{
|
||||
list.Add(1075210, prop); // Increased Karma Loss ~1val~%
|
||||
}
|
||||
Attributes.GetProperties(list, luckBonus: GetLuckBonus());
|
||||
|
||||
AddResistanceProperties(list);
|
||||
|
||||
|
|
@ -1465,6 +1334,12 @@ namespace Server.Items
|
|||
list.Add(1060410, prop); // durability ~1_val~%
|
||||
}
|
||||
|
||||
var lowerStatReq = GetLowerStatReq();
|
||||
if (lowerStatReq != 0)
|
||||
{
|
||||
list.Add(1060435, lowerStatReq); // lower requirements ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = ComputeStatReq(StatType.Str)) > 0)
|
||||
{
|
||||
list.Add(1061170, prop); // strength requirement ~1_val~
|
||||
|
|
|
|||
|
|
@ -754,140 +754,9 @@ namespace Server.Items
|
|||
list.Add(1061078, prop); // artifact rarity ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.WeaponDamage) != 0)
|
||||
{
|
||||
list.Add(1060401, prop); // damage increase ~1_val~%
|
||||
}
|
||||
ClothingAttributes.GetProperties(list);
|
||||
|
||||
if ((prop = Attributes.DefendChance) != 0)
|
||||
{
|
||||
list.Add(1060408, prop); // defense chance increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusDex) != 0)
|
||||
{
|
||||
list.Add(1060409, prop); // dexterity bonus ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.EnhancePotions) != 0)
|
||||
{
|
||||
list.Add(1060411, prop); // enhance potions ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.CastRecovery) != 0)
|
||||
{
|
||||
list.Add(1060412, prop); // faster cast recovery ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.CastSpeed) != 0)
|
||||
{
|
||||
list.Add(1060413, prop); // faster casting ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.AttackChance) != 0)
|
||||
{
|
||||
list.Add(1060415, prop); // hit chance increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusHits) != 0)
|
||||
{
|
||||
list.Add(1060431, prop); // hit point increase ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusInt) != 0)
|
||||
{
|
||||
list.Add(1060432, prop); // intelligence bonus ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.LowerManaCost) != 0)
|
||||
{
|
||||
list.Add(1060433, prop); // lower mana cost ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.LowerRegCost) != 0)
|
||||
{
|
||||
list.Add(1060434, prop); // lower reagent cost ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = ClothingAttributes.LowerStatReq) != 0)
|
||||
{
|
||||
list.Add(1060435, prop); // lower requirements ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.Luck) != 0)
|
||||
{
|
||||
list.Add(1060436, prop); // luck ~1_val~
|
||||
}
|
||||
|
||||
if (ClothingAttributes.MageArmor != 0)
|
||||
{
|
||||
list.Add(1060437); // mage armor
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusMana) != 0)
|
||||
{
|
||||
list.Add(1060439, prop); // mana increase ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.RegenMana) != 0)
|
||||
{
|
||||
list.Add(1060440, prop); // mana regeneration ~1_val~
|
||||
}
|
||||
|
||||
if (Attributes.NightSight != 0)
|
||||
{
|
||||
list.Add(1060441); // night sight
|
||||
}
|
||||
|
||||
if ((prop = Attributes.ReflectPhysical) != 0)
|
||||
{
|
||||
list.Add(1060442, prop); // reflect physical damage ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.RegenStam) != 0)
|
||||
{
|
||||
list.Add(1060443, prop); // stamina regeneration ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.RegenHits) != 0)
|
||||
{
|
||||
list.Add(1060444, prop); // hit point regeneration ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = ClothingAttributes.SelfRepair) != 0)
|
||||
{
|
||||
list.Add(1060450, prop); // self repair ~1_val~
|
||||
}
|
||||
|
||||
if (Attributes.SpellChanneling != 0)
|
||||
{
|
||||
list.Add(1060482); // spell channeling
|
||||
}
|
||||
|
||||
if ((prop = Attributes.SpellDamage) != 0)
|
||||
{
|
||||
list.Add(1060483, prop); // spell damage increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusStam) != 0)
|
||||
{
|
||||
list.Add(1060484, prop); // stamina increase ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusStr) != 0)
|
||||
{
|
||||
list.Add(1060485, prop); // strength bonus ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.WeaponSpeed) != 0)
|
||||
{
|
||||
list.Add(1060486, prop); // swing speed increase ~1_val~%
|
||||
}
|
||||
|
||||
if (Core.ML && (prop = Attributes.IncreasedKarmaLoss) != 0)
|
||||
{
|
||||
list.Add(1075210, prop); // Increased Karma Loss ~1val~%
|
||||
}
|
||||
Attributes.GetProperties(list);
|
||||
|
||||
AddResistanceProperties(list);
|
||||
|
||||
|
|
@ -896,6 +765,12 @@ namespace Server.Items
|
|||
list.Add(1060410, prop); // durability ~1_val~%
|
||||
}
|
||||
|
||||
var lowerStatReq = ClothingAttributes.LowerStatReq;
|
||||
if (lowerStatReq != 0)
|
||||
{
|
||||
list.Add(1060435, lowerStatReq); // lower requirements ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = ComputeStatReq(StatType.Str)) > 0)
|
||||
{
|
||||
list.Add(1061170, prop); // strength requirement ~1_val~
|
||||
|
|
|
|||
|
|
@ -389,125 +389,7 @@ public abstract partial class BaseJewel : Item, ICraftable, IAosItem
|
|||
list.Add(1061078, prop); // artifact rarity ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.WeaponDamage) != 0)
|
||||
{
|
||||
list.Add(1060401, prop); // damage increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.DefendChance) != 0)
|
||||
{
|
||||
list.Add(1060408, prop); // defense chance increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusDex) != 0)
|
||||
{
|
||||
list.Add(1060409, prop); // dexterity bonus ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.EnhancePotions) != 0)
|
||||
{
|
||||
list.Add(1060411, prop); // enhance potions ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.CastRecovery) != 0)
|
||||
{
|
||||
list.Add(1060412, prop); // faster cast recovery ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.CastSpeed) != 0)
|
||||
{
|
||||
list.Add(1060413, prop); // faster casting ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.AttackChance) != 0)
|
||||
{
|
||||
list.Add(1060415, prop); // hit chance increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusHits) != 0)
|
||||
{
|
||||
list.Add(1060431, prop); // hit point increase ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusInt) != 0)
|
||||
{
|
||||
list.Add(1060432, prop); // intelligence bonus ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.LowerManaCost) != 0)
|
||||
{
|
||||
list.Add(1060433, prop); // lower mana cost ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.LowerRegCost) != 0)
|
||||
{
|
||||
list.Add(1060434, prop); // lower reagent cost ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.Luck) != 0)
|
||||
{
|
||||
list.Add(1060436, prop); // luck ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusMana) != 0)
|
||||
{
|
||||
list.Add(1060439, prop); // mana increase ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.RegenMana) != 0)
|
||||
{
|
||||
list.Add(1060440, prop); // mana regeneration ~1_val~
|
||||
}
|
||||
|
||||
if (Attributes.NightSight != 0)
|
||||
{
|
||||
list.Add(1060441); // night sight
|
||||
}
|
||||
|
||||
if ((prop = Attributes.ReflectPhysical) != 0)
|
||||
{
|
||||
list.Add(1060442, prop); // reflect physical damage ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.RegenStam) != 0)
|
||||
{
|
||||
list.Add(1060443, prop); // stamina regeneration ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.RegenHits) != 0)
|
||||
{
|
||||
list.Add(1060444, prop); // hit point regeneration ~1_val~
|
||||
}
|
||||
|
||||
if (Attributes.SpellChanneling != 0)
|
||||
{
|
||||
list.Add(1060482); // spell channeling
|
||||
}
|
||||
|
||||
if ((prop = Attributes.SpellDamage) != 0)
|
||||
{
|
||||
list.Add(1060483, prop); // spell damage increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusStam) != 0)
|
||||
{
|
||||
list.Add(1060484, prop); // stamina increase ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusStr) != 0)
|
||||
{
|
||||
list.Add(1060485, prop); // strength bonus ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.WeaponSpeed) != 0)
|
||||
{
|
||||
list.Add(1060486, prop); // swing speed increase ~1_val~%
|
||||
}
|
||||
|
||||
if (Core.ML && (prop = Attributes.IncreasedKarmaLoss) != 0)
|
||||
{
|
||||
list.Add(1075210, prop); // Increased Karma Loss ~1val~%
|
||||
}
|
||||
Attributes.GetProperties(list);
|
||||
|
||||
AddResistanceProperties(list);
|
||||
|
||||
|
|
|
|||
|
|
@ -677,127 +677,7 @@ public partial class Spellbook : Item, ICraftable, ISlayer, IAosItem
|
|||
}
|
||||
}
|
||||
|
||||
int prop;
|
||||
|
||||
if ((prop = _attributes.WeaponDamage) != 0)
|
||||
{
|
||||
list.Add(1060401, prop); // damage increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = _attributes.DefendChance) != 0)
|
||||
{
|
||||
list.Add(1060408, prop); // defense chance increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = _attributes.BonusDex) != 0)
|
||||
{
|
||||
list.Add(1060409, prop); // dexterity bonus ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = _attributes.EnhancePotions) != 0)
|
||||
{
|
||||
list.Add(1060411, prop); // enhance potions ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = _attributes.CastRecovery) != 0)
|
||||
{
|
||||
list.Add(1060412, prop); // faster cast recovery ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = _attributes.CastSpeed) != 0)
|
||||
{
|
||||
list.Add(1060413, prop); // faster casting ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = _attributes.AttackChance) != 0)
|
||||
{
|
||||
list.Add(1060415, prop); // hit chance increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = _attributes.BonusHits) != 0)
|
||||
{
|
||||
list.Add(1060431, prop); // hit point increase ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = _attributes.BonusInt) != 0)
|
||||
{
|
||||
list.Add(1060432, prop); // intelligence bonus ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = _attributes.LowerManaCost) != 0)
|
||||
{
|
||||
list.Add(1060433, prop); // lower mana cost ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = _attributes.LowerRegCost) != 0)
|
||||
{
|
||||
list.Add(1060434, prop); // lower reagent cost ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = _attributes.Luck) != 0)
|
||||
{
|
||||
list.Add(1060436, prop); // luck ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = _attributes.BonusMana) != 0)
|
||||
{
|
||||
list.Add(1060439, prop); // mana increase ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = _attributes.RegenMana) != 0)
|
||||
{
|
||||
list.Add(1060440, prop); // mana regeneration ~1_val~
|
||||
}
|
||||
|
||||
if (_attributes.NightSight != 0)
|
||||
{
|
||||
list.Add(1060441); // night sight
|
||||
}
|
||||
|
||||
if ((prop = _attributes.ReflectPhysical) != 0)
|
||||
{
|
||||
list.Add(1060442, prop); // reflect physical damage ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = _attributes.RegenStam) != 0)
|
||||
{
|
||||
list.Add(1060443, prop); // stamina regeneration ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = _attributes.RegenHits) != 0)
|
||||
{
|
||||
list.Add(1060444, prop); // hit point regeneration ~1_val~
|
||||
}
|
||||
|
||||
if (_attributes.SpellChanneling != 0)
|
||||
{
|
||||
list.Add(1060482); // spell channeling
|
||||
}
|
||||
|
||||
if ((prop = _attributes.SpellDamage) != 0)
|
||||
{
|
||||
list.Add(1060483, prop); // spell damage increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = _attributes.BonusStam) != 0)
|
||||
{
|
||||
list.Add(1060484, prop); // stamina increase ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = _attributes.BonusStr) != 0)
|
||||
{
|
||||
list.Add(1060485, prop); // strength bonus ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = _attributes.WeaponSpeed) != 0)
|
||||
{
|
||||
list.Add(1060486, prop); // swing speed increase ~1_val~%
|
||||
}
|
||||
|
||||
if (Core.ML && (prop = _attributes.IncreasedKarmaLoss) != 0)
|
||||
{
|
||||
list.Add(1075210, prop); // Increased Karma Loss ~1val~%
|
||||
}
|
||||
_attributes.GetProperties(list);
|
||||
|
||||
list.Add(1042886, _spellCount); // ~1_NUMBERS_OF_SPELLS~ Spells
|
||||
}
|
||||
|
|
|
|||
|
|
@ -617,127 +617,7 @@ public partial class BaseTalisman : Item, IAosItem
|
|||
|
||||
SkillBonuses.GetProperties(list);
|
||||
|
||||
int prop;
|
||||
|
||||
if ((prop = Attributes.WeaponDamage) != 0)
|
||||
{
|
||||
list.Add(1060401, prop); // damage increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.DefendChance) != 0)
|
||||
{
|
||||
list.Add(1060408, prop); // defense chance increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusDex) != 0)
|
||||
{
|
||||
list.Add(1060409, prop); // dexterity bonus ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.EnhancePotions) != 0)
|
||||
{
|
||||
list.Add(1060411, prop); // enhance potions ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.CastRecovery) != 0)
|
||||
{
|
||||
list.Add(1060412, prop); // faster cast recovery ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.CastSpeed) != 0)
|
||||
{
|
||||
list.Add(1060413, prop); // faster casting ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.AttackChance) != 0)
|
||||
{
|
||||
list.Add(1060415, prop); // hit chance increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusHits) != 0)
|
||||
{
|
||||
list.Add(1060431, prop); // hit point increase ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusInt) != 0)
|
||||
{
|
||||
list.Add(1060432, prop); // intelligence bonus ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.LowerManaCost) != 0)
|
||||
{
|
||||
list.Add(1060433, prop); // lower mana cost ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.LowerRegCost) != 0)
|
||||
{
|
||||
list.Add(1060434, prop); // lower reagent cost ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.Luck) != 0)
|
||||
{
|
||||
list.Add(1060436, prop); // luck ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusMana) != 0)
|
||||
{
|
||||
list.Add(1060439, prop); // mana increase ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.RegenMana) != 0)
|
||||
{
|
||||
list.Add(1060440, prop); // mana regeneration ~1_val~
|
||||
}
|
||||
|
||||
if (Attributes.NightSight != 0)
|
||||
{
|
||||
list.Add(1060441); // night sight
|
||||
}
|
||||
|
||||
if ((prop = Attributes.ReflectPhysical) != 0)
|
||||
{
|
||||
list.Add(1060442, prop); // reflect physical damage ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.RegenStam) != 0)
|
||||
{
|
||||
list.Add(1060443, prop); // stamina regeneration ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.RegenHits) != 0)
|
||||
{
|
||||
list.Add(1060444, prop); // hit point regeneration ~1_val~
|
||||
}
|
||||
|
||||
if (Attributes.SpellChanneling != 0)
|
||||
{
|
||||
list.Add(1060482); // spell channeling
|
||||
}
|
||||
|
||||
if ((prop = Attributes.SpellDamage) != 0)
|
||||
{
|
||||
list.Add(1060483, prop); // spell damage increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusStam) != 0)
|
||||
{
|
||||
list.Add(1060484, prop); // stamina increase ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusStr) != 0)
|
||||
{
|
||||
list.Add(1060485, prop); // strength bonus ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.WeaponSpeed) != 0)
|
||||
{
|
||||
list.Add(1060486, prop); // swing speed increase ~1_val~%
|
||||
}
|
||||
|
||||
if (Core.ML && (prop = Attributes.IncreasedKarmaLoss) != 0)
|
||||
{
|
||||
list.Add(1075210, prop); // Increased Karma Loss ~1val~%
|
||||
}
|
||||
Attributes.GetProperties(list);
|
||||
|
||||
if (_maxCharges > 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2998,115 +2998,7 @@ public abstract partial class BaseWeapon
|
|||
list.Add(1072792); // Balanced
|
||||
}
|
||||
|
||||
if (WeaponAttributes.UseBestSkill != 0)
|
||||
{
|
||||
list.Add(1060400); // use best weapon skill
|
||||
}
|
||||
|
||||
if ((prop = GetDamageBonus() + Attributes.WeaponDamage) != 0)
|
||||
{
|
||||
list.Add(1060401, prop); // damage increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.DefendChance) != 0)
|
||||
{
|
||||
list.Add(1060408, prop); // defense chance increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.EnhancePotions) != 0)
|
||||
{
|
||||
list.Add(1060411, prop); // enhance potions ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.CastRecovery) != 0)
|
||||
{
|
||||
list.Add(1060412, prop); // faster cast recovery ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.CastSpeed) != 0)
|
||||
{
|
||||
list.Add(1060413, prop); // faster casting ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = GetHitChanceBonus() + Attributes.AttackChance) != 0)
|
||||
{
|
||||
list.Add(1060415, prop); // hit chance increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = WeaponAttributes.HitColdArea) != 0)
|
||||
{
|
||||
list.Add(1060416, prop); // hit cold area ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = WeaponAttributes.HitDispel) != 0)
|
||||
{
|
||||
list.Add(1060417, prop); // hit dispel ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = WeaponAttributes.HitEnergyArea) != 0)
|
||||
{
|
||||
list.Add(1060418, prop); // hit energy area ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = WeaponAttributes.HitFireArea) != 0)
|
||||
{
|
||||
list.Add(1060419, prop); // hit fire area ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = WeaponAttributes.HitFireball) != 0)
|
||||
{
|
||||
list.Add(1060420, prop); // hit fireball ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = WeaponAttributes.HitHarm) != 0)
|
||||
{
|
||||
list.Add(1060421, prop); // hit harm ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = WeaponAttributes.HitLeechHits) != 0)
|
||||
{
|
||||
list.Add(1060422, prop); // hit life leech ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = WeaponAttributes.HitLightning) != 0)
|
||||
{
|
||||
list.Add(1060423, prop); // hit lightning ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = WeaponAttributes.HitLowerAttack) != 0)
|
||||
{
|
||||
list.Add(1060424, prop); // hit lower attack ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = WeaponAttributes.HitLowerDefend) != 0)
|
||||
{
|
||||
list.Add(1060425, prop); // hit lower defense ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = WeaponAttributes.HitMagicArrow) != 0)
|
||||
{
|
||||
list.Add(1060426, prop); // hit magic arrow ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = WeaponAttributes.HitLeechMana) != 0)
|
||||
{
|
||||
list.Add(1060427, prop); // hit mana leech ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = WeaponAttributes.HitPhysicalArea) != 0)
|
||||
{
|
||||
list.Add(1060428, prop); // hit physical area ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = WeaponAttributes.HitPoisonArea) != 0)
|
||||
{
|
||||
list.Add(1060429, prop); // hit poison area ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = WeaponAttributes.HitLeechStam) != 0)
|
||||
{
|
||||
list.Add(1060430, prop); // hit stamina leech ~1_val~%
|
||||
}
|
||||
WeaponAttributes.GetProperties(list);
|
||||
|
||||
if (ImmolatingWeaponSpell.IsImmolating(this))
|
||||
{
|
||||
|
|
@ -3118,109 +3010,17 @@ public abstract partial class BaseWeapon
|
|||
list.Add(1072793, prop); // Velocity ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusDex) != 0)
|
||||
{
|
||||
list.Add(1060409, prop); // dexterity bonus ~1_val~
|
||||
}
|
||||
Attributes.GetProperties(
|
||||
list,
|
||||
damageBonus: GetDamageBonus(),
|
||||
hitChanceBonus: GetHitChanceBonus(),
|
||||
luckBonus: GetLuckBonus()
|
||||
);
|
||||
|
||||
if ((prop = Attributes.BonusHits) != 0)
|
||||
var lowerStatReq = GetLowerStatReq();
|
||||
if (lowerStatReq != 0)
|
||||
{
|
||||
list.Add(1060431, prop); // hit point increase ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusInt) != 0)
|
||||
{
|
||||
list.Add(1060432, prop); // intelligence bonus ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.LowerManaCost) != 0)
|
||||
{
|
||||
list.Add(1060433, prop); // lower mana cost ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.LowerRegCost) != 0)
|
||||
{
|
||||
list.Add(1060434, prop); // lower reagent cost ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = GetLowerStatReq()) != 0)
|
||||
{
|
||||
list.Add(1060435, prop); // lower requirements ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = GetLuckBonus() + Attributes.Luck) != 0)
|
||||
{
|
||||
list.Add(1060436, prop); // luck ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = WeaponAttributes.MageWeapon) != 0)
|
||||
{
|
||||
list.Add(1060438, 30 - prop); // mage weapon -~1_val~ skill
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusMana) != 0)
|
||||
{
|
||||
list.Add(1060439, prop); // mana increase ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.RegenMana) != 0)
|
||||
{
|
||||
list.Add(1060440, prop); // mana regeneration ~1_val~
|
||||
}
|
||||
|
||||
if (Attributes.NightSight != 0)
|
||||
{
|
||||
list.Add(1060441); // night sight
|
||||
}
|
||||
|
||||
if ((prop = Attributes.ReflectPhysical) != 0)
|
||||
{
|
||||
list.Add(1060442, prop); // reflect physical damage ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.RegenStam) != 0)
|
||||
{
|
||||
list.Add(1060443, prop); // stamina regeneration ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.RegenHits) != 0)
|
||||
{
|
||||
list.Add(1060444, prop); // hit point regeneration ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = WeaponAttributes.SelfRepair) != 0)
|
||||
{
|
||||
list.Add(1060450, prop); // self repair ~1_val~
|
||||
}
|
||||
|
||||
if (Attributes.SpellChanneling != 0)
|
||||
{
|
||||
list.Add(1060482); // spell channeling
|
||||
}
|
||||
|
||||
if ((prop = Attributes.SpellDamage) != 0)
|
||||
{
|
||||
list.Add(1060483, prop); // spell damage increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusStam) != 0)
|
||||
{
|
||||
list.Add(1060484, prop); // stamina increase ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.BonusStr) != 0)
|
||||
{
|
||||
list.Add(1060485, prop); // strength bonus ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = Attributes.WeaponSpeed) != 0)
|
||||
{
|
||||
list.Add(1060486, prop); // swing speed increase ~1_val~%
|
||||
}
|
||||
|
||||
if (Core.ML && (prop = Attributes.IncreasedKarmaLoss) != 0)
|
||||
{
|
||||
list.Add(1075210, prop); // Increased Karma Loss ~1val~%
|
||||
list.Add(1060435, lowerStatReq); // lower requirements ~1_val~%
|
||||
}
|
||||
|
||||
GetDamageTypes(
|
||||
|
|
@ -3239,16 +3039,16 @@ public abstract partial class BaseWeapon
|
|||
list.Add(1060403, phys); // physical damage ~1_val~%
|
||||
}
|
||||
|
||||
if (fire != 0)
|
||||
{
|
||||
list.Add(1060405, fire); // fire damage ~1_val~%
|
||||
}
|
||||
|
||||
if (cold != 0)
|
||||
{
|
||||
list.Add(1060404, cold); // cold damage ~1_val~%
|
||||
}
|
||||
|
||||
if (fire != 0)
|
||||
{
|
||||
list.Add(1060405, fire); // fire damage ~1_val~%
|
||||
}
|
||||
|
||||
if (pois != 0)
|
||||
{
|
||||
list.Add(1060406, pois); // poison damage ~1_val~%
|
||||
|
|
@ -3325,6 +3125,11 @@ public abstract partial class BaseWeapon
|
|||
list.Add(1061175); // skill required: archery
|
||||
break;
|
||||
}
|
||||
case SkillName.Throwing:
|
||||
{
|
||||
list.Add(1112075); // skill required: throwing
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -493,6 +493,131 @@ namespace Server
|
|||
set => this[AosAttribute.IncreasedKarmaLoss] = value;
|
||||
}
|
||||
|
||||
public void GetProperties(IPropertyList list, int damageBonus = 0, int hitChanceBonus = 0, int luckBonus = 0)
|
||||
{
|
||||
int prop;
|
||||
|
||||
if ((prop = WeaponDamage + damageBonus) != 0)
|
||||
{
|
||||
list.Add(1060401, prop); // damage increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = DefendChance) != 0)
|
||||
{
|
||||
list.Add(1060408, prop); // defense chance increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = BonusDex) != 0)
|
||||
{
|
||||
list.Add(1060409, prop); // dexterity bonus ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = EnhancePotions) != 0)
|
||||
{
|
||||
list.Add(1060411, prop); // enhance potions ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = CastRecovery) != 0)
|
||||
{
|
||||
list.Add(1060412, prop); // faster cast recovery ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = CastSpeed) != 0)
|
||||
{
|
||||
list.Add(1060413, prop); // faster casting ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = AttackChance + hitChanceBonus) != 0)
|
||||
{
|
||||
list.Add(1060415, prop); // hit chance increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = BonusHits) != 0)
|
||||
{
|
||||
list.Add(1060431, prop); // hit point increase ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = BonusInt) != 0)
|
||||
{
|
||||
list.Add(1060432, prop); // intelligence bonus ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = LowerManaCost) != 0)
|
||||
{
|
||||
list.Add(1060433, prop); // lower mana cost ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = LowerRegCost) != 0)
|
||||
{
|
||||
list.Add(1060434, prop); // lower reagent cost ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = Luck + luckBonus) != 0)
|
||||
{
|
||||
list.Add(1060436, prop); // luck ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = BonusMana) != 0)
|
||||
{
|
||||
list.Add(1060439, prop); // mana increase ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = RegenMana) != 0)
|
||||
{
|
||||
list.Add(1060440, prop); // mana regeneration ~1_val~
|
||||
}
|
||||
|
||||
if (NightSight != 0)
|
||||
{
|
||||
list.Add(1060441); // night sight
|
||||
}
|
||||
|
||||
if ((prop = ReflectPhysical) != 0)
|
||||
{
|
||||
list.Add(1060442, prop); // reflect physical damage ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = RegenStam) != 0)
|
||||
{
|
||||
list.Add(1060443, prop); // stamina regeneration ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = RegenHits) != 0)
|
||||
{
|
||||
list.Add(1060444, prop); // hit point regeneration ~1_val~
|
||||
}
|
||||
|
||||
if (SpellChanneling != 0)
|
||||
{
|
||||
list.Add(1060482); // spell channeling
|
||||
}
|
||||
|
||||
if ((prop = SpellDamage) != 0)
|
||||
{
|
||||
list.Add(1060483, prop); // spell damage increase ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = BonusStam) != 0)
|
||||
{
|
||||
list.Add(1060484, prop); // stamina increase ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = BonusStr) != 0)
|
||||
{
|
||||
list.Add(1060485, prop); // strength bonus ~1_val~
|
||||
}
|
||||
|
||||
if ((prop = WeaponSpeed) != 0)
|
||||
{
|
||||
list.Add(1060486, prop); // swing speed increase ~1_val~%
|
||||
}
|
||||
|
||||
if (Core.ML && (prop = IncreasedKarmaLoss) != 0)
|
||||
{
|
||||
list.Add(1075210, prop); // Increased Karma Loss ~1val~%
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetValue(Mobile m, AosAttribute attribute)
|
||||
{
|
||||
if (!Core.AOS)
|
||||
|
|
@ -885,6 +1010,103 @@ namespace Server
|
|||
return value;
|
||||
}
|
||||
|
||||
// lowerStatReq is passed in because the weapon folds the resource's lower-requirements into
|
||||
// GetLowerStatReq(); emitted in cliloc order (1060435) between the Hit* block and MageWeapon.
|
||||
public void GetProperties(IPropertyList list)
|
||||
{
|
||||
int prop;
|
||||
|
||||
if (UseBestSkill != 0)
|
||||
{
|
||||
list.Add(1060400); // use best weapon skill
|
||||
}
|
||||
|
||||
if ((prop = HitColdArea) != 0)
|
||||
{
|
||||
list.Add(1060416, prop); // hit cold area ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = HitDispel) != 0)
|
||||
{
|
||||
list.Add(1060417, prop); // hit dispel ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = HitEnergyArea) != 0)
|
||||
{
|
||||
list.Add(1060418, prop); // hit energy area ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = HitFireArea) != 0)
|
||||
{
|
||||
list.Add(1060419, prop); // hit fire area ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = HitFireball) != 0)
|
||||
{
|
||||
list.Add(1060420, prop); // hit fireball ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = HitHarm) != 0)
|
||||
{
|
||||
list.Add(1060421, prop); // hit harm ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = HitLeechHits) != 0)
|
||||
{
|
||||
list.Add(1060422, prop); // hit life leech ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = HitLightning) != 0)
|
||||
{
|
||||
list.Add(1060423, prop); // hit lightning ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = HitLowerAttack) != 0)
|
||||
{
|
||||
list.Add(1060424, prop); // hit lower attack ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = HitLowerDefend) != 0)
|
||||
{
|
||||
list.Add(1060425, prop); // hit lower defense ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = HitMagicArrow) != 0)
|
||||
{
|
||||
list.Add(1060426, prop); // hit magic arrow ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = HitLeechMana) != 0)
|
||||
{
|
||||
list.Add(1060427, prop); // hit mana leech ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = HitPhysicalArea) != 0)
|
||||
{
|
||||
list.Add(1060428, prop); // hit physical area ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = HitPoisonArea) != 0)
|
||||
{
|
||||
list.Add(1060429, prop); // hit poison area ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = HitLeechStam) != 0)
|
||||
{
|
||||
list.Add(1060430, prop); // hit stamina leech ~1_val~%
|
||||
}
|
||||
|
||||
if ((prop = MageWeapon) != 0)
|
||||
{
|
||||
list.Add(1060438, 30 - prop); // mage weapon -~1_val~ skill
|
||||
}
|
||||
|
||||
if ((prop = SelfRepair) != 0)
|
||||
{
|
||||
list.Add(1060450, prop); // self repair ~1_val~
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString() => "...";
|
||||
}
|
||||
|
||||
|
|
@ -978,6 +1200,24 @@ namespace Server
|
|||
return value;
|
||||
}
|
||||
|
||||
// lowerStatReq is passed in because consumers compute it differently: armor folds in the
|
||||
// resource's ArmorLowerRequirements via GetLowerStatReq(), clothing reads it raw. Emitted in
|
||||
// cliloc order (1060435) ahead of MageArmor/SelfRepair.
|
||||
public void GetProperties(IPropertyList list)
|
||||
{
|
||||
int prop;
|
||||
|
||||
if (MageArmor != 0)
|
||||
{
|
||||
list.Add(1060437); // mage armor
|
||||
}
|
||||
|
||||
if ((prop = SelfRepair) != 0)
|
||||
{
|
||||
list.Add(1060450, prop); // self repair ~1_val~
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString() => "...";
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue