Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 156 additions & 0 deletions spec/System/TestItemParse_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -465,3 +465,159 @@ describe("TestItemParse", function()
assert.are.equal("+1500 to Armour", item.buffModLines[1].line)
end)
end)

describe("TestAdvancedItemParse", function()
it("parses item", function()
local advancedItem = new("Item", [[
Item Class: Belts
Rarity: Rare
Beast Snare
Cord Belt
--------
Requirements:
Level: 51
--------
Item Level: 83
--------
Allocates Surveillance (enchant)
--------
{ Implicit Modifier }
Can be Anointed
--------
{ Fractured Prefix Modifier "Thorny" (Tier: 2) — Damage, Physical }
Reflects 3(1-4) Physical Damage to Melee Attackers
{ Prefix Modifier "Fecund" (Tier: 1) — Life }
+142(130-144) to maximum Life
{ Prefix Modifier "Glowing" (Tier: 9) — Defences, Energy Shield }
+15(13-15) to maximum Energy Shield
{ Suffix Modifier "of the Tempest" (Tier: 4) — Elemental, Lightning, Resistance }
+34(30-35)% to Lightning Resistance
{ Master Crafted Suffix Modifier "of Craft" (Rank: 3) — Elemental, Cold, Resistance }
+35(29-35)% to Cold Resistance
--------
Fractured Item
]])

local equivalentCraftItem = new("Item", [[
Beast Snare
Cord Belt
Crafted: true
Prefix: {range:0.599}AttackerTakesDamage1
Prefix: {range:0.859}IncreasedLife9
Prefix: {range:0.845}IncreasedEnergyShield4
Suffix: {range:0.732}LightningResist5
Suffix: None
Suffix: None
LevelReq: 51
Implicits: 1
{crafted}Allocates Surveillance
Can be Anointed
+15 to maximum Energy Shield
+142 to maximum Life
+34% to Lightning Resistance
Reflects 3 Physical Damage to Melee Attackers
{tags:elemental,cold,resistance}{crafted}{range:1}+(29-35)% to Cold Resistance
]])

assert.are.equals(advancedItem:BuildRaw(), equivalentCraftItem:BuildRaw())

local catalyst = new("Item", [[
Item Class: Amulets
Rarity: Unique
Astramentis
Onyx Amulet
--------
Quality (Attribute Modifiers): +20% (augmented)
--------
Requirements:
Level: 20
--------
Item Level: 80
--------
Allocates Weathered Hunter (enchant)
--------
{ Implicit Modifier — Attribute — 20% Increased }
+16(10-16) to all Attributes
(Attributes are Strength, Dexterity, and Intelligence)
--------
{ Unique Modifier — Attribute — 20% Increased }
+86(80-100) to all Attributes
(Attributes are Strength, Dexterity, and Intelligence)
{ Unique Modifier — Physical, Attack }
-4 Physical Damage taken from Attack Hits
--------
Mindless rage will shake the world,
Cunning lies will bend it.
Reckless haste will break the world,
And into darkness send it.
--------
Note: ~b/o 50 chaos
]])
local godTestItem = new("Item", [[
Item Class: Sceptres
Rarity: Unique
Nebulis
Synthesised Void Sceptre
--------
Sceptre
Physical Damage: 50-76
Critical Strike Chance: 7.30%
Attacks per Second: 1.25
Weapon Range: 1.1 metres
Memory Strands: 58
--------
Requirements:
Level: 68
Str: 104
Int: 122
--------
Sockets: B R
--------
Item Level: 87
--------
+30% to Fire Resistance (scourge)
22% reduced Global Defences (scourge)
(Armour, Evasion Rating and Energy Shield are the standard Defences) (scourge)
--------
8% increased Explicit Cold Modifier magnitudes (enchant)
Has 1 White Socket (enchant)
--------
{ Searing Exarch Implicit Modifier (Lesser) }
Tempest Shield has 15(15-17)% increased Buff Effect
{ Implicit Modifier — Damage, Critical — 106% Increased }
+15(15-17)% to Global Critical Strike Multiplier
--------
{ Prefix Modifier "Freezing" (Tier: 5) — Damage, Elemental, Cold, Caster — 8% Increased }
Adds 17(16-20) to 35(30-36) Cold Damage to Spells
{ Prefix Modifier "Beetle's" (Tier: 6) — Defences, Armour }
9(6-13)% increased Armour
7(6-7)% increased Stun and Block Recovery
{ Master Crafted Prefix Modifier "Upgraded" — Life, Defences, Armour }
21(18-21)% increased Armour
+18(17-19) to maximum Life
{ Unique Modifier }
106(60-120)% increased Implicit Modifier magnitudes — Unscalable Value
(Implicit Modifiers are those that come from an item's type, rather than its random properties)
{ Master Crafted Suffix Modifier "of Craft" (Rank: 3) — Elemental, Cold, Resistance }
+35(29-35)% to Cold Resistance
{ Fractured Prefix Modifier "Thorny" (Tier: 2) — Damage, Physical }
Reflects 3(1-4) Physical Damage to Melee Attackers
{ Prefix Modifier "Veiled" }
Veiled Prefix
Searing Exarch Item
--------
{ Allocated Crucible Passive Skill (Tier: 2) }
Adds 2 to 6 Physical Damage to Spells
--------
Synthesised Item
--------
Corrupted
--------
Scourged
--------
Hinekora's Lock
--------
Note: ~b/o 2 chaos
]])
end)
end)
54 changes: 54 additions & 0 deletions src/Classes/Item.lua
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ function ItemClass:ParseRaw(raw, rarity, highQuality)
local deferJewelRadiusIndexAssignment
local gameModeStage = "FINDIMPLICIT"
local foundExplicit, foundImplicit
local linePrefix = ""

while self.rawLines[l] do
local line = self.rawLines[l]
Expand Down Expand Up @@ -398,7 +399,42 @@ function ItemClass:ParseRaw(raw, rarity, highQuality)
self[influenceItemMap[line]] = true
elseif line == "Requirements:" then
-- nothing to do
elseif line:match("^{ ") then
-- We're parsing advanced copy/paste format
linePrefix = ""
self.crafted = true
local fullModName, modTags, increasedAmt = line:match("^{ (.-) %- (.-) %- (%d*).*}$")
if not fullModName then
fullModName, modTags = line:match("^{ (.-) %- (.-) }$")
end
if not fullModName then
fullModName = line:match("^{ (.-) }$")
end
local modName = fullModName:match("^.*Modifier \"(.*)\"")
if modName and modName ~= "" then
for modId, modData in pairs(self.affixes) do
if modData.affix == modName then
if modData.type == "Prefix" then
pendingAffix = { modId = modId, table = self.prefixes }
elseif modData.type == "Suffix" then
pendingAffix = { modId = modId, table = self.suffixes }
end
end
end
end
local possibleLineFlags = fullModName:match("(.*)Modifier.*")
if possibleLineFlags then
for flag in possibleLineFlags:gmatch("%a+") do
if lineFlags[flag:lower()] then
linePrefix = linePrefix .. "{" .. flag:lower() .. "}"
end
end
end
if modTags and modTags ~= "" then
linePrefix = linePrefix .. "{tags:" .. modTags:lower():gsub("%s+", "") .. "}"
end
else
line = linePrefix .. line
if self.checkSection then
if gameModeStage == "IMPLICIT" then
if foundImplicit then
Expand Down Expand Up @@ -733,6 +769,24 @@ function ItemClass:ParseRaw(raw, rarity, highQuality)
gameModeStage = "IMPLICIT"
end
local catalystScalar = getCatalystScalar(self.catalyst, modLine.modTags, self.catalystQuality)
for value, range in line:gmatch("(%d+)%((%d+%-%d+)%)") do
-- Find advanced copy paste format: 45(40-50)
if pendingAffix then
local min, max = range:match("(%d+)%-(%d+)")
local numRange = round((value - min) / (tonumber(max) - min), 3)
line = line:gsub(value .. "%(" .. range:gsub("%-", "%%-") .. "%)", value)
t_insert(pendingAffix.table, {
modId = pendingAffix.modId,
range = tonumber(numRange),
})
pendingAffix = nil
else
local min, max = range:match("(%d+)%-(%d+)")
local numRange = round((value - min) / (tonumber(max) - min), 3)
modLine.range = tonumber(numRange)
line = line:gsub(value .. "%(" .. range:gsub("%-", "%%-") .. "%)", "(" .. range .. ")")
end
end
local rangedLine = itemLib.applyRange(line, 1, catalystScalar)
local modList, extra = modLib.parseMod(rangedLine)
if (not modList or extra) and self.rawLines[l+1] then
Expand Down