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
9 changes: 6 additions & 3 deletions spec/System/TestItemImport_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ describe("Offline Item Import", function ()
["affixEffectModifier"] = 0,
["baseTypeID"] = 34,
["implicits"] = { [1] = '(16-22)% Increased Unique Drop Rate', },
["name"] = 'Grand Winds of Fortune',
["req"] = { ["level"] = 0 },
["subTypeID"] = 112,
["type"] = 'Blessing'
["type"] = 'Blessing',
},
["baseName"] = 'Grand Winds of Fortune',
["explicitMods"] = {},
Expand Down Expand Up @@ -114,10 +115,11 @@ describe("Offline Item Import", function ()
["baseTypeID"] = 26,
["height"] = 1,
["implicits"] = {},
["name"] = 'Minor Weaver Idol',
["req"] = { ["level"] = 0 },
["subTypeID"] = 1,
["type"] = 'Minor Idol',
["width"] = 1
["width"] = 1,
},
["baseName"] = 'Minor Weaver Idol',
["explicitMods"] = {},
Expand Down Expand Up @@ -187,9 +189,10 @@ describe("Offline Item Import", function ()
[6] = { [1] = 4, [2] = 4 }
},
["implicits"] = { [1] = '{rounding:Integer}+(6-10) Health per Equipped Omen Idol' },
["name"] = 'Visage Altar',
["req"] = { ["level"] = 0 },
["subTypeID"] = 5,
["type"] = 'Idol Altar'
["type"] = 'Idol Altar',
},
["baseName"] = 'Visage Altar',
["explicitMods"] = {},
Expand Down
195 changes: 116 additions & 79 deletions src/Classes/ImportTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
-- Stage: input account name (Online)
self.controls.accountNameHeader = new("LabelControl", { "TOPLEFT", self.controls.accountNameGoOffline, "BOTTOMLEFT" },
0, 4, 200, 16,
"^7To start importing an Online character (via lastepochtools.com), click Start Online:")

Check warning on line 54 in src/Classes/ImportTab.lua

View workflow job for this annotation

GitHub Actions / spellcheck

Unknown word (lastepochtools)
self.controls.accountNameHeader.shown = function ()
return self.charImportMode == "GETACCOUNTNAME"
end
Expand Down Expand Up @@ -294,7 +294,7 @@

self.importCodeDetail = colorCodes.NEGATIVE .. "Invalid input"

-- Check if the buffer contains a lastepochtools build (check if a line contains "fromSaveFile")

Check warning on line 297 in src/Classes/ImportTab.lua

View workflow job for this annotation

GitHub Actions / spellcheck

Unknown word (lastepochtools)
local xmlText
if buf:find("fromSaveFile") then
for line in buf:gmatch("([^\n]+)") do
Expand All @@ -313,9 +313,9 @@
end

-- Support for Last Epoch Planner build URLs
if urlText:match("lastepochplanner%.com[^#]*#%w*=") then

Check warning on line 316 in src/Classes/ImportTab.lua

View workflow job for this annotation

GitHub Actions / spellcheck

Unknown word (lastepochplanner)
-- Extract the nested URL or code from the build URL
local nested_url_or_code = urlText:gsub(".*lastepochplanner%.com[^#]*#%w*=([^&]+).*", "%1")

Check warning on line 318 in src/Classes/ImportTab.lua

View workflow job for this annotation

GitHub Actions / spellcheck

Unknown word (lastepochplanner)
urlText = UrlDecode(nested_url_or_code)
buf = urlText
self.controls.importCodeIn:SetText(urlText, false)
Expand All @@ -338,7 +338,7 @@
xmlText = Inflate(common.base64.decode(buf:gsub("-", "+"):gsub("_", "/")))
end

-- Check if the decoded buffer contains a lastepochtools build

Check warning on line 341 in src/Classes/ImportTab.lua

View workflow job for this annotation

GitHub Actions / spellcheck

Unknown word (lastepochtools)
if xmlText and xmlText:find("%w* = {\"data\":{\"fromSaveFile\"") then
for line in xmlText:gmatch("[^\n]+") do
if line:find("fromSaveFile") then
Expand Down Expand Up @@ -575,7 +575,7 @@
if os.getenv("USER") then
-- For Linux
t_insert(localSaveFolders, "/home/" .. os.getenv("USER")
.. "/.local/share/Steam/steamapps/compatdata/899770/pfx/drive_c/users/steamuser/"

Check warning on line 578 in src/Classes/ImportTab.lua

View workflow job for this annotation

GitHub Actions / spellcheck

Unknown word (steamuser)

Check warning on line 578 in src/Classes/ImportTab.lua

View workflow job for this annotation

GitHub Actions / spellcheck

Unknown word (compatdata)
.. saveFolderSuffix:gsub("\\", "/"))
end
local saves = {}
Expand Down Expand Up @@ -725,6 +725,7 @@
[10] = "Ring 2",
[7] = "Belt",
[12] = "Relic",
[29] = "Idols",
[123] = "Idol Altar"
}

Expand All @@ -735,96 +736,132 @@
offlineImportSlotMap[42 + i] = "Blessing " .. (7 + i)
end

local itemDataFields = {
BASETYPE_ID = 4,
SUBTYPE_ID = 5,
RARITY = 6,
IMPLICIT = 7,
UNIQUE_ID = 11,
UNIQUE_MOD_VALUES = 13
}

local itemRarityMap = {
[0] = "COMMON",
[1] = "MAGIC",
[2] = "IDOL",
[3] = "RARE",
[4] = "EXALTED",
[7] = "UNIQUE",
[8] = "SET",
[9] = "LEGENDARY",
}

function ImportTabClass:processItemData(itemData)
if itemData["containerID"] <= 12 or itemData["containerID"] == 29 or
itemData["containerID"] >= 33 and itemData["containerID"] <= 39 or
itemData["containerID"] >= 43 and itemData["containerID"] <= 45 or
itemData["containerID"] == 123 then
local misc = self.build.data.misc -- shorter magic numbers access
local itemBasesDB = self.build.data.itemBases -- shorter item bases db access
local uniquesDB = self.build.data.uniques -- shorter unique db access
local container = itemData["containerID"]
local data = itemData["data"]
if offlineImportSlotMap[container] ~= nil then
local item = {}
local baseTypeID = itemData["data"][4]
local subTypeID = itemData["data"][5]
if itemData["containerID"] == 29 then
local posX = itemData["inventoryPosition"]["x"] + 1
local posY = itemData["inventoryPosition"]["y"] + 1
item["slotName"] = "Idol " .. posX .. "," .. posY
item["rarityType"] = "IDOL"
item["rarity"] = "IDOL"
else
item["slotName"] = offlineImportSlotMap[itemData["containerID"]]
local baseTypeID = data[itemDataFields.BASETYPE_ID]
local subTypeID = data[itemDataFields.SUBTYPE_ID]
local rarity = data[itemDataFields.RARITY]
local itemBase = itemBasesDB[baseTypeID .. "_" .. subTypeID]
local affixDataOffset = misc.BasicItemAffixDataOffset

item.affixes = {}

-- Base item info
if itemBase then
item.base = itemBase
for impIndex, impText in ipairs(itemBase.implicits) do
local affixText = "{implicit}"
if itemLib.hasRange(impText) then
local range = data[itemDataFields.IMPLICIT+ impIndex]

Check warning on line 781 in src/Classes/ImportTab.lua

View workflow job for this annotation

GitHub Actions / lint

src/Classes/ImportTab.lua: missing whitespace before token '+' (code: codestyle-check)
affixText = affixText .. "{range:" .. range .. "}"
end
affixText = affixText .. impText
table.insert(item.affixes, { text = affixText })
end
end

for itemBaseName, itemBase in pairs(self.build.data.itemBases) do
if itemBase.baseTypeID == baseTypeID and itemBase.subTypeID == subTypeID then
item.baseName = itemBaseName
item.base = itemBase
item.implicitMods = {}
for i, implicit in ipairs(itemBase.implicits) do
local range = itemData["data"][7 + i]
table.insert(item.implicitMods, "{range: " .. range .. "}" .. implicit)
-- Item rarity
item.rarity = itemRarityMap[rarity]

-- Unique/Set/Legendary Items
if rarity >= 7 and rarity <= 9 then
local uniqueID = data[itemDataFields.UNIQUE_ID] * 256 + data[itemDataFields.UNIQUE_ID + 1] -- Two bytes for ID
local uniqueData = self.build.data.uniques[uniqueID] -- uniques[uniqueID]
item["name"] = uniqueData.name
for i, modLine in ipairs(uniqueData.mods) do
local modText = modLine
if itemLib.hasRange(modLine) then
local rollId = uniqueData.rollIds[i]
local range = data[itemDataFields.UNIQUE_MOD_VALUES + rollId]
modText = "{range:" ..range.. "}" .. modText

Check warning on line 802 in src/Classes/ImportTab.lua

View workflow job for this annotation

GitHub Actions / lint

src/Classes/ImportTab.lua: missing whitespace before token '..' (code: codestyle-check)

Check warning on line 802 in src/Classes/ImportTab.lua

View workflow job for this annotation

GitHub Actions / lint

src/Classes/ImportTab.lua: missing whitespace after token '..' (code: codestyle-check)
end
local rarity = itemData["data"][6]
item["explicitMods"] = {}
item["affixes"] = {}
local nbAffixesIndex = 12
if rarity >= 7 and rarity <= 9 then
item["rarity"] = "UNIQUE"
item["rarityType"] = item["rarityType"] or "UNIQUE"
local uniqueIDIndex = 8 + 3 -- 3 is the maximum amount of implicits
local uniqueID = itemData["data"][uniqueIDIndex] * 256 + itemData["data"][uniqueIDIndex + 1]
local uniqueBase = self.build.data.uniques[uniqueID]
item["name"] = uniqueBase.name
for i, modLine in ipairs(uniqueBase.mods) do
if itemLib.hasRange(modLine) then
local rollId = uniqueBase.rollIds[i]
local range = itemData["data"][uniqueIDIndex + 2 + rollId]
table.insert(item.explicitMods, "{unique}{range: " .. range .. "}" .. modLine)
else
table.insert(item.explicitMods, "{unique}" .. modLine)
end
end
if rarity == 9 then
item["rarity"] = "LEGENDARY"
modText = "{unique}" .. modText
table.insert(item.affixes, { text = modText })
end
affixDataOffset = misc.UniqueItemAffixDataOffset
end

-- Common affixes
local affixCountComposite = data[affixDataOffset]
if affixCountComposite then
local affixCount = affixCountComposite % 8
local hasCorruptedAffix = math.floor(affixCountComposite / 64) % 2
local hasSealedAffix = math.floor(affixCountComposite / 128) % 2
local affixBlockPosition = affixDataOffset + 1 -- base affix offset for iteration
for i = 0, affixCount - 1 do
local currentAffixOffset = affixBlockPosition + misc.AffixSizeOffset * i
if data[currentAffixOffset] ~= nil and data[currentAffixOffset + 1] ~= nil then
local affixId = (data[currentAffixOffset] % 16) * 256 + data[currentAffixOffset + 1] -- Two bytes for ID
local affixTier = math.floor(data[currentAffixOffset] / 16)
local modId = affixId .. "_" .. affixTier
local modData = self.build.data.itemMods.Item[modId]
local range = data[currentAffixOffset + 2]
local modText = modData[1]
if itemLib.hasRange(modText) then
modText = "{range:"..range.."}"..modText

Check warning on line 827 in src/Classes/ImportTab.lua

View workflow job for this annotation

GitHub Actions / lint

src/Classes/ImportTab.lua: missing whitespace after token '..' (code: codestyle-check)

Check warning on line 827 in src/Classes/ImportTab.lua

View workflow job for this annotation

GitHub Actions / lint

src/Classes/ImportTab.lua: missing whitespace before token '..' (code: codestyle-check)

Check warning on line 827 in src/Classes/ImportTab.lua

View workflow job for this annotation

GitHub Actions / lint

src/Classes/ImportTab.lua: missing whitespace after token '..' (code: codestyle-check)

Check warning on line 827 in src/Classes/ImportTab.lua

View workflow job for this annotation

GitHub Actions / lint

src/Classes/ImportTab.lua: missing whitespace before token '..' (code: codestyle-check)

Check warning on line 827 in src/Classes/ImportTab.lua

View workflow job for this annotation

GitHub Actions / lint

src/Classes/ImportTab.lua: missing whitespace after token '..' (code: codestyle-check)

Check warning on line 827 in src/Classes/ImportTab.lua

View workflow job for this annotation

GitHub Actions / lint

src/Classes/ImportTab.lua: missing whitespace before token '..' (code: codestyle-check)
end
nbAffixesIndex = uniqueIDIndex + 2 + 8 -- 8 is the maximum amount of unique mods
else
item["name"] = itemBaseName
item["rarity"] = item["rarity"] or "RARE"
item["rarityType"] = item["rarityType"] or "BASIC"
end
if itemData["data"][nbAffixesIndex] then
local nbMods = itemData["data"][nbAffixesIndex] % 8
local nbSealedAffix = math.floor(itemData["data"][nbAffixesIndex] / 64) % 2
local nbCorruptedAffix = math.floor(itemData["data"][nbAffixesIndex] / 128) % 2
for i = 0, nbMods - 1 do
local dataId = nbAffixesIndex + 1 + 3 * i
if itemData["data"][dataId] ~= nil and itemData["data"][dataId + 1] ~= nil then
local affixId = itemData["data"][dataId + 1] + (itemData["data"][dataId] % 16) * 256
local affixTier = math.floor(itemData["data"][dataId] / 16)
local modId = affixId .. "_" .. affixTier
local modData = data.itemMods.Item[modId]
local range = itemData["data"][dataId + 2]
local affix = { ["range"] = range, ["modId"] = modId }

if modData then
if nbSealedAffix == 1 then
affix.sealed = true
nbSealedAffix = 0
elseif nbCorruptedAffix == 1 then
affix.corrupted = true
nbCorruptedAffix = 0
elseif modData.type == "Prefix" then
affix.prefix = true
else
affix.suffix = true
end
table.insert(item.affixes, affix)
end
local affix = { modId = modId, text = modText }

if modData then
-- Add affix type tags
if modData.type == "Prefix" then
affix.text = "{prefix}" .. affix.text
elseif modData.type == "Suffix" then
affix.text = "{suffix}" .. affix.text
end

-- Add sealed/corrupted tags
if hasSealedAffix == 1 then
item.sealed = true
affix.text = "{sealed}" .. affix.text
hasSealedAffix = 0
elseif hasCorruptedAffix == 1 then
item.corrupted = true
affix.text = "{corrupted}" .. affix.text
hasCorruptedAffix = 0
end
table.insert(item.affixes, affix)
end
end
return item
end
end

-- Slot name
if container == tableKeys(offlineImportSlotMap)["Idols"] then
local posX = itemData["inventoryPosition"]["x"] + 1
local posY = itemData["inventoryPosition"]["y"] + 1
item["slotName"] = "Idol " .. posX .. "," .. posY
else
item["slotName"] = offlineImportSlotMap[container]
end

return item
end
end

Expand Down
Loading
Loading