Difference between revisions of "Module:Items"
From Melvor Idle
Falterfire (talk | contribs) (Moving code over to Items/SourceTables (Will temporarily break stuff)) |
Falterfire (talk | contribs) (Moving p.GetOtherItemBoxText back over) |
||
Line 203: | Line 203: | ||
end | end | ||
return 'Invalid' | return 'Invalid' | ||
+ | end | ||
+ | |||
+ | function p._getOtherItemBoxText(item) | ||
+ | result = '' | ||
+ | --For equipment, show the slot they go in | ||
+ | if item.equipmentSlot ~= nil then | ||
+ | result = result..'\r\n|-\r\n|Equipment Slot: '..p.getEquipmentSlotName(item.equipmentSlot) | ||
+ | end | ||
+ | --For weapons with a special attack, show the details | ||
+ | if item.hasSpecialAttack then | ||
+ | local spAtt = p.getSpecialAttackByID(item.specialAttackID) | ||
+ | result = result..'\r\n|-\r\n|Special Attack:' | ||
+ | result = result..'\r\n* '..spAtt.chance..'% chance for '..spAtt.name..':' | ||
+ | result = result..'\r\n** '..spAtt.description | ||
+ | end | ||
+ | --For potions, show the number of charges | ||
+ | if item.potionCharges ~= nil then | ||
+ | result = result..'\r\n|-\r\n|Charges: '..item.potionCharges | ||
+ | end | ||
+ | --For food, show how much it heals for | ||
+ | if item.healsFor ~= nil then | ||
+ | result = result..'\r\n|-\r\n|Heals for: '..Icons.Icon({"Hitpoints", type="skill", notext="true"})..' '..(item.healsFor * 10) | ||
+ | end | ||
+ | --For Prayer Points, show how many you get | ||
+ | if item.prayerPoints ~= nil then | ||
+ | result = result..'\r\n|-\r\n|'..Icons.Icon({'Prayer', type='skill'})..' Points: '..item.prayerPoints | ||
+ | end | ||
+ | return result | ||
+ | end | ||
+ | |||
+ | function p.getOtherItemBoxText(frame) | ||
+ | local itemName = frame.args ~= nil and frame.args[1] or frame | ||
+ | local item = p.getItem(itemName) | ||
+ | local asList = false | ||
+ | if frame.args ~= nil then | ||
+ | asList = frame.args.asList ~= nil and frame.args.asList ~= '' and frame.args.asList ~= 'false' | ||
+ | end | ||
+ | if item == nil then | ||
+ | return "ERROR: No item named "..itemName.." exists in the data module" | ||
+ | end | ||
+ | |||
+ | return p._getOtherItemBoxText(item, asList) | ||
end | end | ||
Revision as of 20:47, 17 November 2020
Lua module for generating various item tables. Pulls data from Module:Items/data
--This module contains all sorts of functions for getting data on items --Several functions related to use tables can be found at Module:Items/UseTables --Functions related to source tables can be found at Module:Items/SourceTables local p = {} local MonsterData = mw.loadData('Module:Monsters/data') local ItemData = mw.loadData('Module:Items/data') local SkillData = mw.loadData('Module:Skills/data') local Constants = mw.loadData('Module:Constants/data') local Shared = require('Module:Shared') local Magic = require('Module:Magic') local Areas = require('Module:CombatAreas') local Icons = require('Module:Icons') local EasterEggs = {'Amulet of Calculated Promotion', 'Clue Chasers Insignia', '8', 'Lemon'} local OtherShopItems = {'Cooking Gloves', 'Mining Gloves', 'Gem Gloves', 'Smithing Gloves', 'Thieving Gloves'} --This is hardcoded, so there's no easy way to scrape it. Hopefully it doesn't change local GemTable = {["Topaz"] = {name = 'Topaz', id = 128, chance = 50}, ["Sapphire"] = {name = "Sapphire", id = 129, chance = 17.5}, ["Ruby"] = {name = "Ruby", id = 130, chance = 17.5}, ["Emerald"] = {name = "Emerald", id = 131, chance = 10}, ["Diamond"] = {name = "Diamond", id = 132, chance = 5}} --The base chance to receive a gem while mining local GemChance = .01 --The number of different fishing junk items local junkCount = 8 --Items (aside from bars & gems) which can be created via Alt Magic local AltMagicProducts = {'Rune Essence', 'Bones', 'Holy Dust'} --The kinds of gloves with cost & charges p.GloveTable = {['Cooking Gloves'] = {cost=50000, charges=500}, ['Mining Gloves'] = {cost=75000, charges=500}, ['Smithing Gloves'] = {cost=100000, charges=500}, ['Thieving Gloves'] = {cost=100000, charges=500}, ['Gem Gloves'] = {cost=500000, charges=2000}} p.specialFishWt = 6722 p.specialFishLoot = {{128, 2000}, {129, 1600}, {130, 1400}, {131, 1000}, {132, 400}, {667, 10}, {668, 10}, {902, 1}, {670, 1}, {669, 50}, {120, 250}} function p.buildSpecialFishingTable() --This shouldn't ever be included in a page --This is for generating the above 'specialFishLoot' variable if it ever needs to change --To re-run, edit the module, type in "console.log(p.buildSpecialFishingTable())" and copy+paste the result as the new value of the variable --Also gives you the total fishing weight for saving time later local lootArray = {} local totalWt = 0 for i, item in pairs(ItemData.Items) do if item.fishingCatchWeight ~= nil then totalWt = totalWt + item.fishingCatchWeight table.insert(lootArray, '{'..(i - 1)..', '..item.fishingCatchWeight..'}') end end local result = 'p.specialFishWt = '..totalWt..'\r\n' result = result..'p.specialFishLoot = {'..table.concat(lootArray, ', ')..'}' return result end function p.getSpecialAttackByID(ID) local result = Shared.clone(ItemData.SpecialAttacks[ID + 1]) if result ~= nil then result.id = ID end return result end function p.getItemByID(ID) local result = Shared.clone(ItemData.Items[ID + 1]) if result ~= nil then result.id = ID end return result end function p.getItem(name) local result = nil name = string.gsub(name, "%%27", "'") name = string.gsub(name, "'", "'") name = string.gsub(name, "'", "'") for i, item in pairs(ItemData.Items) do local itemName = string.gsub(item.name, '#', '') if(name == itemName) then result = Shared.clone(item) --Make sure every item has an id, and account for Lua being 1-index result.id = i - 1 break end end return result end function p.getItems(checkFunc) local result = {} for i, item in pairs(ItemData.Items) do if checkFunc(item) then local newItem = Shared.clone(item) newItem.id = i - 1 table.insert(result, newItem) end end return result end function p._getItemStat(item, StatName, ZeroIfNil) local result = item[StatName] --Special Overrides: if StatName == 'stabAttackBonus' then if item.attackBonus == nil then result = nil else result = item.attackBonus[1] end elseif StatName == 'slashAttackBonus' then if item.attackBonus == nil then result = nil else result = item.attackBonus[2] end elseif StatName == 'blockAttackBonus' then if item.attackBonus == nil then result = nil else result = item.attackBonus[3] end elseif StatName == 'attackType' then result = p._getWeaponAttackType(item) elseif StatName == 'description' then result = item.description if result == nil or result == '' then result = 'No Description' end end if result == nil and ZeroIfNil then result = 0 end return result end function p.getItemStat(frame) local args = frame.args ~= nil and frame.args or frame local ItemName = args[1] local StatName = args[2] local ZeroIfNil = args.ForceZero ~= nil and args.ForceZero ~= '' and args.ForceZero ~= 'false' local formatNum = args.formatNum ~= nil and args.formatNum ~= '' and args.formatNum ~= 'false' local item = p.getItem(ItemName) if item == nil then return "ERROR: No item named "..ItemName.." exists in the data module" end local result = p._getItemStat(item, StatName, ZeroIfNil) if formatNum then result = Shared.formatnum(result) end return result end function p._getWeaponAttackType(item) if item.type == 'Weapon' then return Icons.Icon({'Melee', nolink='true'}) elseif item.type == 'Ranged Weapon' then return Icons.Icon({'Ranged', type='skill', nolink='true'}) elseif item.type == 'Magic Staff' or item.type == 'Magic Wand' then return Icons.Icon({'Magic', type='skill', nolink='true'}) else return "Invalid" end end function p.getWeaponAttackType(frame) local itemName = frame.args ~= nil and frame.args[1] or frame local item = p.getItem(itemName) if item == nil then return "ERROR: No item named "..ItemName.." exists in the data module" end return p._getWeaponAttackType(item) end function p.getPotionTable(frame) local potionName = frame.args ~= nil and frame.args[1] or frame local tiers = {'I', 'II', 'III', 'IV'} local result = '{| class="wikitable"' result = result..'\r\n!Potion!!Tier!!Charges!!Effect' local tier1potion = p.getItem(potionName..' I') for i, tier in pairs(tiers) do local tierName = potionName..' '..tier local potion = p.getItemByID(tier1potion.id + i - 1) if potion ~= nil then result = result..'\r\n|-' result = result..'\r\n|'..Icons.Icon({tierName, type='item', notext='true', size='60'}) result = result..'||'..'[['..tierName..'|'..tier..']]' result = result..'||'..potion.potionCharges..'||'..potion.description end end result = result..'\r\n|}' return result end function p.getEquipmentSlotName(id) for slotName, i in Shared.skpairs(Constants.equipmentSlot) do if i == id then return slotName end end return 'Invalid' end function p._getOtherItemBoxText(item) result = '' --For equipment, show the slot they go in if item.equipmentSlot ~= nil then result = result..'\r\n|-\r\n|Equipment Slot: '..p.getEquipmentSlotName(item.equipmentSlot) end --For weapons with a special attack, show the details if item.hasSpecialAttack then local spAtt = p.getSpecialAttackByID(item.specialAttackID) result = result..'\r\n|-\r\n|Special Attack:' result = result..'\r\n* '..spAtt.chance..'% chance for '..spAtt.name..':' result = result..'\r\n** '..spAtt.description end --For potions, show the number of charges if item.potionCharges ~= nil then result = result..'\r\n|-\r\n|Charges: '..item.potionCharges end --For food, show how much it heals for if item.healsFor ~= nil then result = result..'\r\n|-\r\n|Heals for: '..Icons.Icon({"Hitpoints", type="skill", notext="true"})..' '..(item.healsFor * 10) end --For Prayer Points, show how many you get if item.prayerPoints ~= nil then result = result..'\r\n|-\r\n|'..Icons.Icon({'Prayer', type='skill'})..' Points: '..item.prayerPoints end return result end function p.getOtherItemBoxText(frame) local itemName = frame.args ~= nil and frame.args[1] or frame local item = p.getItem(itemName) local asList = false if frame.args ~= nil then asList = frame.args.asList ~= nil and frame.args.asList ~= '' and frame.args.asList ~= 'false' end if item == nil then return "ERROR: No item named "..itemName.." exists in the data module" end return p._getOtherItemBoxText(item, asList) end function p.getEquipmentTable(frame) local args = frame.args ~= nil and frame.args or frame local type = args.type local tier = args.tier local slotStr = args.slot local ammoTypeStr = args.ammoType local category = args.category ~= nil and args.category or 'Combat' --Find out what Ammo Type we're working with local ammoType = nil if ammoTypeStr ~= nil then if ammoTypeStr == "Arrows" then ammoType = 0 elseif ammoTypeStr == 'Bolts' then ammoType = 1 elseif ammoTypeStr == 'Javelins' then ammoType = 2 elseif ammoTypeStr == 'Throwing Knives' then ammoType = 3 end end --Find out what slot we're working with local slot = nil if slotStr ~= nil then slot = Constants.equipmentSlot[slotStr] end --Getting some lists set up here that will be used later --First, the list of columns used by both weapons & armour local statColumns = {'stabAttackBonus', 'slashAttackBonus','blockAttackBonus','rangedAttackBonus', 'magicAttackBonus', 'strengthBonus', 'rangedStrengthBonus', 'magicDamageBonus', 'defenceBonus', 'rangedDefenceBonus', 'magicDefenceBonus', 'damageReduction', 'attackLevelRequired', 'defenceLevelRequired', 'rangedLevelRequired', 'magicLevelRequired'} --Then the lists for just weapons/just armour --Then the list of weapon types local weaponTypes = {'Magic Staff', 'Magic Wand', 'Ranged Weapon', 'Weapon'} local isWeaponType = Shared.contains(weaponTypes, type) --Now we need to figure out which items are in this list local itemList = {} for i, itemBase in pairs(ItemData.Items) do local item = Shared.clone(itemBase) item.id = i - 1 local listItem = false if isWeaponType then listItem = item.type == type and item.category == category if ammoType ~= nil then listItem = listItem and item.ammoTypeRequired == ammoType end else --Now for handling armour if type == "Armour" or type == "Melee" then listItem = item.defenceLevelRequired ~= nil or (item.category == 'Combat' and item.type == 'Armour') elseif type == "Ranged Armour" or type == "Ranged" then listItem = item.rangedLevelRequired ~= nil or (item.category == 'Combat' and item.type == 'Ranged Armour') elseif type == "Magic Armour" or type == "Magic" then listItem = item.magicLevelRequired ~= nil or (item.category == 'Combat' and item.type == 'Magic Armour') else listItem = item.type == type and item.category ~= 'Combat' end if ammoType ~= nil then listItem = listItem and item.ammoType == ammoType end if slot ~= nil then listItem = listItem and item.equipmentSlot == slot end end if listItem then table.insert(itemList, item) end end --Now that we have a preliminary list, let's figure out which columns are irrelevant (IE are zero for all items in the selection) local ignoreColumns = Shared.clone(statColumns) for i, item in pairs(itemList) do local ndx = 1 while Shared.tableCount(ignoreColumns) >= ndx do if p._getItemStat(item, ignoreColumns[ndx], true) ~= 0 then table.remove(ignoreColumns, ndx) else ndx = ndx + 1 end end end --Now to remove the ignored columns (and also we need to track groups like defence bonuses to see how many remain) local attBonusCols = 5 local strBonusCols = 2 local defBonusCols = 3 local lvlReqCols = 4 local ndx = 1 while Shared.tableCount(statColumns) >= ndx do local colName = statColumns[ndx] if Shared.contains(ignoreColumns, colName) then if Shared.contains(colName, 'AttackBonus') then attBonusCols = attBonusCols - 1 end if Shared.contains(colName, 'trengthBonus') then strBonusCols = strBonusCols - 1 end if Shared.contains(colName, 'efenceBonus') then defBonusCols = defBonusCols - 1 end if Shared.contains(colName, 'LevelRequired') then lvlReqCols = lvlReqCols - 1 end table.remove(statColumns, ndx) else ndx = ndx + 1 end end --Alright, let's start the table by building the shared header local result = '{| class="wikitable sortable stickyHeader"\r\n|-class="headerRow-0"' if isWeaponType then --Weapons have extra columns here for Attack Speed and "Two Handed?" result = result..'\r\n!colspan="4"|' else result = result..'\r\n!colspan="2"|' end if attBonusCols > 0 then result = result..'\r\n!colspan="'..attBonusCols..'"style="padding:0 0.5em 0 0.5em;"|Attack Bonus' end if strBonusCols > 0 then result = result..'\r\n!colspan="'..strBonusCols..'"style="padding:0 0.5em 0 0.5em;"|Strength Bonus' end if Shared.contains(statColumns, 'magicDamageBonus') then result = result..'\r\n!colspan="1"style="padding:0 0.5em 0 0.5em;"|% Damage Bonus' end if defBonusCols > 0 then result = result..'\r\n!colspan="'..defBonusCols..'"style="padding:0 0.5em 0 0.5em;"|Defence Bonus' end if Shared.contains(statColumns, 'damageReduction') then result = result..'\r\n!colspan="1"style="padding:0 0.5em 0 0.5em;"|Damage Reduction' end if lvlReqCols > 0 then result = result..'\r\n!colspan="'..lvlReqCols..'"style="padding:0 0.5em 0 0.5em;"|Levels Required' end result = result..'\r\n!colspan="1"|' --One header row down, one to go result = result..'\r\n|-class="headerRow-1"' result = result..'\r\n!style="padding:0 1em 0 0.5em;"|Item' result = result..'\r\n!style="padding:0 1em 0 0.5em;"|Name' --Weapons have Attack Speed here if isWeaponType then result = result..'\r\n!style="padding:0 1em 0 0.5em;"|Attack Speed' result = result..'\r\n!style="padding:0 1em 0 0.5em;"|Two Handed?' end --Attack bonuses if Shared.contains(statColumns, 'slashAttackBonus') then result = result..'\r\n!style="padding:0 1em 0 0.5em;"|'..Icons.Icon({'Attack', type='skill', notext='true'}) end if Shared.contains(statColumns, 'stabAttackBonus') then result = result..'\r\n!style="padding:0 1em 0 0.5em;"|'..Icons.Icon({'Strength', type='skill', notext='true'}) end if Shared.contains(statColumns, 'blockAttackBonus') then result = result..'\r\n!style="padding:0 1em 0 0.5em;"|'..Icons.Icon({'Defence', type='skill', notext='true'}) end if Shared.contains(statColumns, 'rangedAttackBonus') then result = result..'\r\n!style="padding:0 1em 0 0.5em;"|'..Icons.Icon({'Ranged', type='skill', notext='true'}) end if Shared.contains(statColumns, 'magicAttackBonus') then result = result..'\r\n!style="padding:0 1em 0 0.5em;"|'..Icons.Icon({'Magic', type='skill', notext='true'}) end --Strength bonuses if Shared.contains(statColumns, 'strengthBonus') then result = result..'\r\n!style="padding:0 1em 0 0.5em;"|'..Icons.Icon({'Strength', type='skill', notext='true'}) end if Shared.contains(statColumns, 'rangedStrengthBonus') then result = result..'\r\n!style="padding:0 1em 0 0.5em;"|'..Icons.Icon({'Ranged', type='skill', notext='true'}) end if Shared.contains(statColumns, 'magicDamageBonus') then result = result..'\r\n!style="padding:0 1em 0 0.5em;"|'..Icons.Icon({'Magic', type='skill', notext='true'}) end --Defence bonuses if Shared.contains(statColumns, 'defenceBonus') then result = result..'\r\n!style="padding:0 1em 0 0.5em;"|'..Icons.Icon({'Defence', type='skill', notext='true'}) end if Shared.contains(statColumns, 'rangedDefenceBonus') then result = result..'\r\n!style="padding:0 1em 0 0.5em;"|'..Icons.Icon({'Ranged', type='skill', notext='true'}) end if Shared.contains(statColumns, 'magicDefenceBonus') then result = result..'\r\n!style="padding:0 1em 0 0.5em;"|'..Icons.Icon({'Magic', type='skill', notext='true'}) end if Shared.contains(statColumns, 'damageReduction') then result = result..'\r\n!style="padding:0 1em 0 0.5em;"|'..Icons.Icon({'Defence', type='skill', notext='true'}) end --Level requirements if Shared.contains(statColumns, 'attackLevelRequired') then result = result..'\r\n!style="padding:0 1em 0 0.5em;"|'..Icons.Icon({'Attack', type='skill', notext='true'}) end if Shared.contains(statColumns, 'defenceLevelRequired') then result = result..'\r\n!style="padding:0 1em 0 0.5em;"|'..Icons.Icon({'Defence', type='skill', notext='true'}) end if Shared.contains(statColumns, 'rangedLevelRequired') then result = result..'\r\n!style="padding:0 1em 0 0.5em;"|'..Icons.Icon({'Ranged', type='skill', notext='true'}) end if Shared.contains(statColumns, 'magicLevelRequired') then result = result..'\r\n!style="padding:0 1em 0 0.5em;"|'..Icons.Icon({'Magic', type='skill', notext='true'}) end --And finally Sources result = result..'\r\n!style="padding:0 1em 0 0.5em;"|Sources' table.sort(itemList, function(a, b) return a.id < b.id end) for i, item in pairs(itemList) do if isWeaponType then --Building rows for weapons result = result..'\r\n|-' result = result..'\r\n|style ="text-align: left;padding: 0 0 0 0;"|'..Icons.Icon({item.name, type='item', size=50, notext=true}) result = result..'\r\n|style ="text-align: left;padding: 0 0.5em 0 0.5em;"|[['..item.name..']]' result = result..'\r\n| style ="text-align: right;padding: 0 0.5em 0 0;" |'..Shared.formatnum(item.attackSpeed) --That's the first list out of the way, now for 2-Handed result = result..'\r\n| style ="text-align: right;"|' if item.isTwoHanded then result = result..'Yes' else result = result..'No' end for j, statName in pairs(statColumns) do local statValue = p._getItemStat(item, statName, true) result = result..'\r\n| style ="text-align: right;padding: 0 0.5em 0 0;' if not Shared.contains(statName, 'LevelRequired') then if statValue > 0 then result = result..'background-color:lightgreen;' elseif statValue < 0 then result = result..'background-color:lightpink;' end end result = result..'"|'..Shared.formatnum(statValue) if statName == 'magicDamageBonus' or statName == 'damageReduction' then result = result..'%' end end --Finally, the Sources result = result..'\r\n| style ="text-align: right;white-space: nowrap;padding: 0 0.5em 0 0.5em;" |' result = result..p._getItemSources(item) else --Building rows for armour result = result..'\r\n|-' result = result..'\r\n|style ="text-align: left;padding: 0 0 0 0;"|'..Icons.Icon({item.name, type='item', size=50, notext=true}) result = result..'\r\n|style ="text-align: left;padding: 0 0.5em 0 0.5em;"|[['..item.name..']]' for j, statName in pairs(statColumns) do local statValue = p._getItemStat(item, statName, true) result = result..'\r\n| style ="text-align: right;padding: 0 0.5em 0 0;' if statValue > 0 then result = result..'background-color:lightgreen;' elseif statValue < 0 then result = result..'background-color:lightpink;' end result = result..'"|'..Shared.formatnum(statValue) if statName == 'magicDamageBonus' or statName == 'damageReduction' then result = result..'%' end end --Finally, the Sources result = result..'\r\n| style ="text-align: right;white-space: nowrap;padding: 0 0.5em 0 0.5em;" |' result = result..p._getItemSources(item) end end result = result..'\r\n|}' return result end function p._getItemCategories(item) local result = '' if item.category ~= nil then result = result..'[[Category:'..item.category..']]' end if item.type ~= nil then result = result..'[[Category:'..item.type..']]' end return result end function p.getItemCategories(frame) local itemName = frame.args ~= nil and frame.args[1] or frame local item = p.getItem(itemName) if item == nil then return "ERROR: No item named "..itemName.." exists in the data module" end return p._getItemCategories(item) end function p.getSkillcapeTable(frame) local skillName = frame.args ~= nil and frame.args[1] or frame local cape = p.getItem(skillName..' Skillcape') local result = '{| class="wikitable"\r\n' result = result..'!Skillcape!!Name!!Effect' result = result..'\r\n|-\r\n|'..Icons.Icon({cape.name, type='item', size='60', notext=true}) result = result..'||[['..cape.name..']]||'..cape.description result = result..'\r\n|}' return result end function p.getShopSkillcapeTable() local result = '' local capeList = {} for i, item in pairs(ItemData.Items) do if Shared.contains(item.name, 'Skillcape') or item.name == 'Cape of Completion' then table.insert(capeList, item) end end result = result..'\r\n{|class="wikitable sortable"' result = result..'\r\n!colspan="2" style="width:200px"|Cape' result = result..'!!Description!!style="width:120px"|Price' --Sort the table by cost and then name table.sort(capeList, function(a, b) if a.buysFor == b.buysFor then return a.name < b.name else return a.sellsFor < b.buysFor end end) for i, thisItem in pairs(capeList) do result = result..'\r\n|-\r\n|'..Icons.Icon({thisItem.name, type='item', size='50', notext=true}) result = result..'||[['..thisItem.name..']]' result = result..'\r\n||'..thisItem.description result = result..'||style="text-align:left" data-sort-value="'..thisItem.buysFor..'"' result = result..'|'..Icons.GP(thisItem.buysFor) end result = result..'\r\n|}' return result end function p.getItemGrid(frame) result = '{|' for i, item in Shared.skpairs(ItemData.Items) do if i % 17 == 1 then result = result..'\r\n|-\r\n|' else result = result..'||' end result = result..'style="padding:3px"|'..Icons.Icon({item.name, type='item', notext=true, size='40'}) end result = result..'\r\n|}' return result end return p