Anonymous

Module:Items/ComparisonTables: Difference between revisions

From Melvor Idle
Implement equipment category table generation for specific styles (Melee, Ranged, Magic, Other)
No edit summary
(Implement equipment category table generation for specific styles (Melee, Ranged, Magic, Other))
Line 26: Line 26:
['Enhancement'] = 'melvorD:Enhancement'
['Enhancement'] = 'melvorD:Enhancement'
}
}
local itemStyleOverrides = {
['Melee'] = {
'melvorF:Slayer_Helmet_Basic',
'melvorF:Slayer_Platebody_Basic',
'melvorF:Paladin_Gloves',
'melvorF:Desert_Wrappings',
'melvorF:Knights_Defender',
},
['Ranged'] = {
'melvorF:Slayer_Cowl_Basic',
'melvorF:Slayer_Leather_Body_Basic',
'melvorD:Cape_Of_Prat',
'melvorD:Ice_Arrows',
},
['Magic'] = {
'melvorF:Slayer_Wizard_Hat_Basic',
'melvorF:Slayer_Wizard_Robes_Basic',
'melvorF:Skull_Cape',
'melvorD:Enchanted_Shield',
'melvorF:Elementalist_Gloves',
'melvorTotH:Freezing_Touch_Body',
'melvorTotH:Lightning_Boots',
},
['Other'] = {
}
}
-- Categorise equipment by:
-- - Equipment slot ID
-- - Style (Melee, Ranged, Magic, Other)
p.SlotEquipment = {}
function p.populateSlotEquipment()
-- Populate from item data
local hiddenItems = {}
for _, itemID in ipairs(Items.HiddenItems) do
hiddenItems[itemID] = true
end
-- Transform style overrides into a form where items are indexed by ID
local styleOverrides = {}
for overType, itemIDs in pairs(itemStyleOverrides) do
for _, itemID in ipairs(itemIDs) do
styleOverrides[itemID] = overType
end
end
for _, item in ipairs(GameData.rawData.items) do
if (
-- Item is not hidden (includes debug items)
hiddenItems[item.id] == nil
-- Item isn't exclusive to Golbin Raid minigame
and (item.golbinRaidExclusive == nil or not item.golbinRaidExclusive)
-- Item can be equipped to any slot
and item.validSlots ~= nil
) then
-- Item is equippment to be included within equipment tables
local equipEntry = {
['item'] = item,
['slots'] = {},
['isWeapon'] = nil,
['style'] = nil
}
-- Determine which slots the equipment can be equipped to
local occupiesSlots = item.occupiesSlots or {}
for _, slotLocalID in ipairs(item.validSlots) do
local newSlotID = slotLocalID
-- Separate two-handed weapons from other weapons
if slotLocalID == 'Weapon' and Items._getItemStat(item, 'isTwoHanded') then
newSlotID = '2hWeapons'
-- Classify javelins and throwing knives as weapons
elseif slotLocalID == 'Quiver' and Shared.contains({'Javelins', 'ThrowingKnives'}, item.ammoType) then
newSlotID = 'Weapon'
-- Combine all enhancements
elseif Shared.contains({'Enhancement1', 'Enhancement2', 'Enhancment3'}, slotLocalID) then
newSlotID = 'Enhancement'
end
equipEntry.slots[newSlotID] = true
end
equipEntry.isWeapon = equipEntry.slots['Weapon'] or equipEntry.slots['2hWeapons'] or Shared.contains(occupiesSlots, 'Weapon')
-- Determine the style of the item (Melee, Ranged, Magic, Other)
local function hasSkillReq(reqs, localSkillID)
if reqs ~= nil then
local skillID = Shared.getNamespacedID('melvorD', localSkillID)
for levelType, typeReqs in pairs(reqs) do
if typeReqs[skillID] ~= nil then
return true
end
end
end
return false
end
local levelReqs = Items._getItemLevelReqs(item)
-- Apply any overrides first
if styleOverrides[item.id] ~= nil then
equipEntry.style = styleOverrides[item.id]
-- Weapon styles can be checked using the attackType property
elseif equipEntry.isWeapon and Shared.contains({'melee', 'ranged', 'magic'}, item.attackType) then
equipEntry.style = Shared.titleCase(item.attackType)
-- Magic
elseif hasSkillReq(levelReqs, 'Magic') then
equipEntry.style = 'Magic'
-- Ranged
elseif (
hasSkillReq(levelReqs, 'Ranged')
or equipEntry.slots.Quiver ~= nil
or item.ammoType ~= nil
) then
equipEntry.style = 'Ranged'
-- Melee
elseif (
hasSkillReq(levelReqs, 'Attack')
or hasSkillReq(levelReqs, 'Defence')
) then
equipEntry.style = 'Melee'
-- Other, default style if unmatched
else
equipEntry.style = 'Other'
end
-- Finally, add the entry into the slotEquipment table
table.insert(p.SlotEquipment, equipEntry)
end
end
end
p.populateSlotEquipment()
local function getEquipItemList(filter)
local equip = GameData.getEntities(p.SlotEquipment, function(x) return filter(x) end)
local items = {}
for _, entry in ipairs(equip) do
table.insert(items, entry.item)
end
return items
end


local function getSlotID(slot)
local function getSlotID(slot)
Line 56: Line 194:
end
end


local function getAttackSpeed(item)
local function getItems(slotID, style)
if item.equipmentStats ~= nil and item.equipmentStats['attackSpeed'] ~= nil then
return item.equipmentStats['attackSpeed'] or 4000
end
return 0
end
 
local function getItems(slotID)
local _, slotLocalID = Shared.getLocalID(slotID)
local _, slotLocalID = Shared.getLocalID(slotID)


local sortFunc = function(item)
return getEquipItemList(
-- Exclude the debug item
function(entry)
if item.id == 'melvorD:DEBUG_ITEM' then
return (
return false
entry.slots[slotLocalID] ~= nil
and (style == nil or style == '' or style == entry.style)
)
end
end
-- Exclude Golbin raid exclusives for now, such that they don't pollute various equipment tables
)
if item.golbinRaidExclusive ~= nil and item.golbinRaidExclusive then
return false
end
if item.name == 'Gods Enhancement (Superior)' then
mw.logObject(item)
end
if not Shared.contains(item.validSlots, slotLocalID) then
-- Special case for when the slot is Weapon but the data slot is Quiver (throwables)
if slotLocalID == 'Weapon' and Shared.contains({'Javelins', 'ThrowingKnives'}, item.ammoType) then
return true
end
-- Special case when the slot ID is for two handed weapons (this ID doesn't actually exist in game)
if slotLocalID == '2hWeapons' then
return Items._getItemStat(item, 'isTwoHanded')
end
if slotLocalID == 'Enhancement' then
return Shared.contains(item.validSlots, 'Enhancement1') or
  Shared.contains(item.validSlots, 'Enhancement2') or
  Shared.contains(item.validSlots, 'Enhancement3')
end
return false
end
-- Don't leap in one handed weapons with two handed.
-- Include throwables with one handed weapons
if slotLocalID == 'Weapon' then
if Items._getItemStat(item, 'isTwoHanded') then
return false
end
-- Exclude throwables from ammo.
elseif slotLocalID == 'Quiver' then
if Shared.contains({'Javelins', 'ThrowingKnives'}, item.ammoType) then
return false
end
end
 
return true
end
 
return Items.getItems(sortFunc)
end
end


Line 125: Line 214:
elseif statVal < 0 then
elseif statVal < 0 then
cell:addClass('table-negative')
cell:addClass('table-negative')
end
if math.abs(statVal) >= 1000 then
cell:attr('data-sort-value', statVal)
end
end
cell:css('text-align', 'right')
cell:css('text-align', 'right')
Line 137: Line 229:
return createStatCell(row, statVal)
return createStatCell(row, statVal)
:wikitext(statVal)
:wikitext(Num.formatnum(statVal))
end
end


Line 219: Line 311:
end
end


function p.getEquipmentTable(itemList, slot)
function p.getEquipmentTable(itemList, slot, style)
local iconSize = 20
local iconSize = 20
local fl = FL.new(itemList)
local fl = FL.new(itemList)
Line 298: Line 390:
-- Add attack speed.
-- Add attack speed.
if isWeapon == true then
if isWeapon == true then
local atkSpeed = getAttackSpeed(item)
local atkSpeed = Items._getItemStat(item, 'attackSpeed')
if atkSpeed > 0 then
if atkSpeed > 0 then
row:tag('td'):wikitext(Num.round(atkSpeed / 1000, 3, 1) .. 's')
row:tag('td'):wikitext(Num.round(atkSpeed / 1000, 3, 1) .. 's')
Line 343: Line 435:


function p.getCategoryTable(frame)
function p.getCategoryTable(frame)
local slot = frame.args ~= nil and frame.args[1] or frame[1]
local args = frame.args ~= nil and frame.args or frame
local slot, style = args[1], Shared.titleCase(args[2] or '')
local slotID = getSlotID(slot)
local slotID = getSlotID(slot)
if slotID == nil then
if slotID == nil then
return Shared.printError('Invalid slot ID: ' .. (slot or 'nil'))
return Shared.printError('Invalid slot ID: ' .. (slot or 'nil'))
elseif style ~= nil and style ~= '' and itemStyleOverrides[style] == nil then
return Shared.printError('Invalid style: ' .. (style or 'nil'))
end
end


return p.getEquipmentTable(getItems(slotID), slot)
return p.getEquipmentTable(getItems(slotID, style), slot)
end
end


Line 595: Line 690:
function p.getDRTable(frame)
function p.getDRTable(frame)
local style = frame.args ~= nil and frame.args[1] or frame
local style = frame.args ~= nil and frame.args[1] or frame
local SlotNames = {}
local slotNames = {}
local ItemList = {}
if style == 'Other' then
if style == 'Other' then
SlotNames = {'Helmet', 'Platelegs', 'Gloves', 'Shield', 'Cape', 'Amulet', 'Ring'}
slotNames = {'Helmet', 'Platelegs', 'Gloves', 'Shield', 'Cape', 'Amulet', 'Ring'}
else
else
SlotNames = {'Helmet', 'Platebody', 'Platelegs', 'Boots', 'Gloves', 'Weapon', 'Shield'}
slotNames = {'Helmet', 'Platebody', 'Platelegs', 'Boots', 'Gloves', 'Weapon', 'Shield'}
end
end
ItemList = Items.getItems(function(item)
local itemList = getEquipItemList(
local isMatch = true
function(entry)
if Items._getItemStat(item, 'damageReduction', true) <= 0 then
if Items._getItemStat(entry.item, 'damageReduction', true) <= 0 then
return false
-- Item provides no DR: Exclude
end
return false
-- Exclude Golbin raid exclusives for now, such that they don't
end
-- pollute various equipment tables
 
if item.golbinRaidExclusive ~= nil and item.golbinRaidExclusive then
-- Check equipment slot matches
return false
local slotMatch = false
end
for _, slotName in ipairs(slotNames) do
--Using the same checks for Melee/Ranged/Magic that the Equipment Tables use
if entry.slots[slotName] ~= nil then
if style == 'Melee' then
slotMatch = true
if ((Items._getItemStat(item, 'defenceLevelRequired') == nil and Items._getItemStat(item, 'attackLevelRequired') == nil) and not Shared.contains(styleOverrides.Melee, item.name)) or Shared.contains(styleOverrides.NotMelee, item.name) then isMatch = false end
break
elseif style == 'Ranged' then
end
if (Items._getItemStat(item, 'rangedLevelRequired') == nil and not Shared.contains(styleOverrides.Ranged, item.name)) or Shared.contains(styleOverrides.NotRanged, item.name)  then isMatch = false end
end
elseif style == 'Magic' then
if not slotMatch then
if (Items._getItemStat(item, 'magicLevelRequired') == nil and not Shared.contains(styleOverrides.Magic, item.name)) or Shared.contains(styleOverrides.NotMagic, item.name) then isMatch = false end
return false
else
end
if (Items._getItemStat(item, 'attackLevelRequired') ~= nil or Items._getItemStat(item, 'defenceLevelRequired') ~= nil or Items._getItemStat(item, 'rangedLevelRequired') ~= nil or Items._getItemStat(item, 'magicLevelRequired') ~= nil or
 
Shared.contains(styleOverrides.Melee, item.name) or Shared.contains(styleOverrides.Ranged, item.name) or Shared.contains(styleOverrides.Magic, item.name)) and
-- Finally, ensure the style matches. If no style specified then return evertyhing
not Shared.contains(styleOverrides.None, item.name) then
return (style == nil or style == '' or style == entry.style)
isMatch = false
end
end
)
end
 
if isMatch and not Shared.contains(SlotNames, Items._getItemEquipSlot(item)) then
return p._getDRTable(slotNames, itemList)
isMatch = false
end
return isMatch
end)
return p._getDRTable(SlotNames, ItemList)
end
end


return p
return p