Code:
import "Turbine.UI.Lotro"
-------------------------------------------------------------------------------
local WindowLeft = Turbine.UI.Display:GetWidth() / 2
local WindowTop = 0
local debug = false
-------------------------------------------------------------------------------
local StatLabels = {}
local TextBoxes = {}
local UnitLabels = {}
local EquivLabels = {}
local StatOrder = {"Maximum Morale", "Maximum Power", "in-Combat Morale Regen",
"in-Combat Power Regen", "Might", "Agility", "Vitality", "Will",
"Fate", "Critical Rating", "Finesse Rating", "Physical Mastery Rating",
"Tactical Mastery Rating", "Resistance Rating", "Incoming Healing Rating",
"Block Rating", "Parry Rating", "Evade Rating", "Physical Mitigation",
"Tactical Mitigation"}
local QualityNames = {"uncommon", "rare", "incomparable", "epic"}
local CategoryNames = {"light armour", "medium armour", "heavy armour", "cloak",
"jewellery", "shield", "melee 1h", "melee 2h", "ranged"}
local ArmourNames = {"head", "shoulders", "chest", "hands", "legs", "feet"}
local JewelleryNames = {"bracelet", "earring", "necklace", "pocket", "ring"}
local ShieldNames = {"light", "warden", "heavy"}
local Melee1Names = {"axe", "club", "dagger", "hammer", "mace", "spear", "sword"}
local Melee2Names = {"axe", "club", "halberd", "hammer", "rune-stone", "staff", "sword"}
local RangedNames = {"bow", "crossbow", "javelin"}
local QualityColours = {Turbine.UI.Color(1, 1, 0), --ffff00 (from lorebook.css)
Turbine.UI.Color(0.761, 0, 0.780), --c200c7
Turbine.UI.Color(0, 0.996, 1), --00feff
Turbine.UI.Color(0.949, 0.671, 0.047)} --f2ab0c
-------------------------------------------------------------------------------
function round(number, zeroes)
local zeroes = zeroes or 0
return math.floor(number * (10 ^ zeroes) + .5) / (10 ^ zeroes)
end
-------------------------------------------------------------------------------
-- level-guessing and stat-allocation functions
function TypicalRatingsByLevel(stat, level)
local typical
if stat == "Maximum Morale" then
if level > 49 then
typical = level * 3.5 - 125.5
else
typical = level * 0.9 + 0.9
end
elseif stat == "Maximum Power" then
if level > 49 then
typical = level * 3 - 104
else
typical = level * 0.9 + 0.9
end
elseif stat == "in-Combat Morale Regen" then
if level > 49 then
typical = level * 0.9 - 14.1
else
typical = level * 0.6 + 0.6
end
elseif stat == "in-Combat Power Regen" then
if level > 49 then
typical = level * 0.3 + 30.3
else
typical = level * 0.9 + 0.9
end
elseif stat == "Might"
or stat == "Agility"
or stat == "Vitality"
or stat == "Will"
or stat == "Fate" then
if level > 59 then
typical = level * 0.5 - 10.5
elseif level > 49 then
typical = level * 0.3 + 1.3
else
typical = level * 0.3 + 0.1
end
elseif stat == "Critical Rating" then
typical = level * 4
elseif stat == "Finesse Rating" then
if level > 51 then
typical = level * 12 + 12
elseif level < 50 then
typical = level * 12 + 48
else
typical = 636
end
elseif stat == "Physical Mastery Rating" then
typical = level * 4
elseif stat == "Tactical Mastery Rating" then
typical = level * 4
elseif stat == "Resistance Rating" then
typical = level * 6
elseif stat == "Incoming Healing Rating" then
typical = level * 8
elseif stat == "Block Rating" then
if CategoryButton:GetText() == "shield" then -- ugly and ominous
typical = level * 6
else
typical = level * 4
end
elseif stat == "Parry Rating" then
typical = level * 4
elseif stat == "Evade Rating" then
typical = level * 4
elseif stat == "Physical Mitigation" then
typical = level * 8.1
elseif stat == "Tactical Mitigation" then
typical = level * 8.1
end
if typical < 1 then -- avoid later div-by-0 and other oddities
return 1
else
return typical
end
end
function GuessLevel(stat, rating)
local slope, ambiguous
local constant = 0
if stat == "Maximum Morale" then
slope = 3.5
constant = - 125.5
elseif stat == "Maximum Power" then
slope = 3
constant = - 104
elseif stat == "in-Combat Morale Regen" then
slope = 0.9
constant = - 14.1
elseif stat == "in-Combat Power Regen" then
slope = 0.3
constant = 30.3
ambiguous = true
elseif stat == "Might"
or stat == "Agility"
or stat == "Vitality"
or stat == "Will"
or stat == "Fate" then
slope = 0.5
constant = - 10.5
ambiguous = true
elseif stat == "Critical Rating" then
slope = 4
elseif stat == "Finesse Rating" then
slope = 12
constant = 12
elseif stat == "Physical Mastery Rating" then
slope = 4
elseif stat == "Tactical Mastery Rating" then
slope = 4
elseif stat == "Resistance Rating" then
slope = 6
elseif stat == "Incoming Healing Rating" then
slope = 8
elseif stat == "Block Rating" then
if CategoryButton:GetText() == "shield" then -- ugly and ominous
slope = 6
else
slope = 4
end
elseif stat == "Parry Rating" then
slope = 4
elseif stat == "Evade Rating" then
slope = 4
elseif stat == "Physical Mitigation" then
slope = 8.1
elseif stat == "Tactical Mitigation" then
slope = 8.1
end
local BestGuess, NewGuess, mult
for i = 1, 4 do
NewGuess = math.floor(((rating / i) - constant) / slope)
-- assume the mult that leads closest to 75 is correct
if not BestGuess or math.abs(75 - NewGuess) < math.abs(75 - BestGuess) then
BestGuess = NewGuess
mult = i
end
end
if ambiguous and (mult == 1 or mult == 3) then -- don't trust
if debug then
Turbine.Shell.WriteLine(string.format("[calc] ((%s %s / %d) - %s) / %s = %s?",
rating, stat, mult, constant, slope, BestGuess))
end
return BestGuess, false
else -- trust, but I could be wrong
if debug then
Turbine.Shell.WriteLine(string.format("[calc] ((%s %s / %d) - %s) / %s = %s",
rating, stat, mult, constant, slope, BestGuess))
end
return BestGuess, true
end
end
-------------------------------------------------------------------------------
-- armour-guessing functions
function GuessArmour(level)
local QualityText = QualityButton:GetText()
if QualityText == "epic" then -- insufficient data to implement
return "?"
end
local multiplier
local category = CategoryButton:GetText()
local ArmourText = ArmourButton:GetText()
local ShieldText = ShieldButton:GetText()
if ArmourText == "chest" then
multiplier = 8.1 * 1.2
elseif ArmourText == "feet" then
multiplier = 8.1 * 0.48
elseif ArmourText == "hands" then
multiplier = 8.1 * 0.6
elseif ArmourText == "head" then
multiplier = 8.1 * 0.36
elseif ArmourText == "legs" then
multiplier = 8.1
elseif ArmourText == "shoulders" then
multiplier = 8.1 * 0.36
end
if category == "medium armour" then
multiplier = multiplier * 17 / 12
elseif category == "heavy armour" then
multiplier = multiplier * 11 / 6
elseif category == "cloak" then
multiplier = 8.1 * 11 / 15
elseif category == "shield" then
if ShieldText == "light" then
multiplier = 8.1 * 31 / 24
elseif ShieldText == "warden" then
multiplier = 15.24
else
multiplier = 8.1 * 25 / 6
end
end
-- shields are frustrating
if category == "shield" and ShieldText == "light" then
if QualityText == "incomparable" then
return round(level * multiplier)
elseif QualityText == "rare" then
return round((level - 2) * multiplier)
else
return round(level * multiplier * 0.785)
end
elseif category == "shield" and ShieldText == "heavy" then
if QualityText == "incomparable" then
return math.ceil(level * multiplier)
elseif QualityText == "rare" then
return round(math.ceil(level * multiplier) * 0.8)
else
return round(math.ceil((level - 3) * multiplier) * 0.8)
end
else
if QualityText == "incomparable" then
return round(level * multiplier)
elseif QualityText == "rare" then
return round(round(level * multiplier) * 0.95)
else
return round(round((level - 3) * multiplier) * 0.95)
end
end
end
-------------------------------------------------------------------------------
-- dps-guessing functions
local hardcodedDPS = {} -- ugly, hopefully U7 will simplify this
hardcodedDPS[51] = 38
hardcodedDPS[52] = 39
hardcodedDPS[53] = 40.1
hardcodedDPS[54] = 42.1
hardcodedDPS[55] = 44.2
hardcodedDPS[56] = 46.5
hardcodedDPS[57] = 48.3
hardcodedDPS[58] = 50.1
function GuessDamage(level)
local QualityText = QualityButton:GetText()
if QualityText == "epic" then -- insufficient data to implement
return "damage prediction: ?"
end
local result = hardcodedDPS[level]
if level > 64 then
result = level * 3.25 - 149.4
elseif level > 58 then
result = level * 1.4 - 30.6
elseif level < 51 then
result = level * 0.7 + 2.1
end
local category = CategoryButton:GetText()
if category == "melee 2h" or category == "ranged" then
if level > 50 then
result = result * 17 / 15
else
result = result * 1.14
end
end
if QualityText == "incomparable" then
result = result * 1.038
elseif QualityText == "uncommon" then
result = result * 0.9375 -- 15 / 16
end
local min, max
if category == "melee 1h" then
min = round(result * 1.425) -- 1.9 * 3 / 4
max = round(result * 2.375) -- 1.9 * 5 / 4
elseif category == "melee 2h" then
min = round(result * 1.875) -- 2.5 * 3 / 4
max = round(result * 3.125) -- 2.5 * 5 / 4
elseif category == "ranged" then
if RangedButton:GetText() == "javelin" then
min = round(result * 1.875) -- 2.5 * 3 / 4
max = round(result * 3.125) -- 2.5 * 5 / 4
else
min = round(result * 1.562) -- 2.2 * 0.71
max = round(result * 2.838) -- 2.2 * 1.29
end
end
return string.format("\ndamage prediction: %s DPS\n(%s - %s Damage)", round(result, 1), min, max)
end
-------------------------------------------------------------------------------
function GuessVendor(level)
local copper
local category = CategoryButton:GetText()
local ArmourText = ArmourButton:GetText()
local JewelleryText = JewelleryButton:GetText()
local ShieldText = ShieldButton:GetText()
local Melee1Text = Melee1Button:GetText()
local Melee2Text = Melee2Button:GetText()
local RangedText = RangedButton:GetText()
if category == "light armour" then
if ArmourText == "chest" then
copper = math.min(level, 50) * 15 + math.max(level - 50, 0) * 16 + 76
elseif ArmourText == "legs" then
copper = math.min(level, 50) * 15 + math.max(level - 50, 0) * 16 + 60
elseif ArmourText == "head" then
copper = math.min(level, 50) * 15 + math.max(level - 50, 0) * 16 + 50
elseif ArmourText == "hands" then
copper = math.min(level, 50) * 15 + math.max(level - 50, 0) * 16 + 40
elseif ArmourText == "feet" then
copper = math.min(level, 50) * 15 + math.max(level - 50, 0) * 16 + 40
elseif ArmourText == "shoulders" then
copper = math.min(level, 50) * 15 + math.max(level - 50, 0) * 16 + 36
end
elseif category == "medium armour" then
if ArmourText == "chest" then
copper = math.min(level, 50) * 16.5 + math.max(level - 50, 0) * 16 + 83
elseif ArmourText == "legs" then
copper = math.min(level, 50) * 16.5 + math.max(level - 50, 0) * 16 + 67
elseif ArmourText == "head" then
copper = math.min(level, 50) * 16.5 + math.max(level - 50, 0) * 16 + 55
elseif ArmourText == "hands" then
copper = math.min(level, 50) * 16.5 + math.max(level - 50, 0) * 16 + 45
elseif ArmourText == "feet" then
copper = math.min(level, 50) * 16.5 + math.max(level - 50, 0) * 16 + 45
elseif ArmourText == "shoulders" then
copper = math.min(level, 50) * 16.5 + math.max(level - 50, 0) * 16 + 39
end
elseif category == "heavy armour" then
if ArmourText == "chest" then
copper = math.min(level, 50) * 21.5 + math.max(level - 50, 0) * 18 + 107
elseif ArmourText == "legs" then
copper = math.min(level, 50) * 21.5 + math.max(level - 50, 0) * 18 + 85
elseif ArmourText == "head" then
copper = math.min(level, 50) * 20 + math.max(level - 50, 0) * 18 + 56
elseif ArmourText == "hands" then
copper = math.min(level, 50) * 20 + math.max(level - 50, 0) * 18 + 44
elseif ArmourText == "feet" then
copper = math.min(level, 50) * 20 + math.max(level - 50, 0) * 18 + 44
elseif ArmourText == "shoulders" then
copper = math.min(level, 50) * 20 + math.max(level - 50, 0) * 18 + 38
end
elseif category == "cloak" then
copper = math.min(level, 50) * 15 + math.max(level - 50, 0) * 16 + 0
elseif category == "jewellery" then
if JewelleryText == "bracelet" then
copper = math.min(level, 50) * 5 + math.max(level - 50, 0) * 6 + 50
elseif JewelleryText == "earring" then
copper = math.min(level, 50) * 5 + math.max(level - 50, 0) * 6 + 0
elseif JewelleryText == "necklace" then
copper = math.min(level, 50) * 5 + math.max(level - 50, 0) * 6 + 150
elseif JewelleryText == "ring" then
copper = math.min(level, 50) * 5 + math.max(level - 50, 0) * 6 + 50
elseif JewelleryText == "pocket" then
copper = math.min(level, 50) * 22 + math.max(level - 50, 0) * 24 + 82
end
elseif category == "shield" then
if ShieldText == "light" then
copper = math.min(level, 50) * 11 + math.max(level - 50, 0) * 12 + 110
elseif ShieldText == "warden" then
copper = math.min(level, 50) * 12 + math.max(level - 50, 0) * 12 + 110
elseif ShieldText == "heavy" then
copper = math.min(level, 50) * 14 + math.max(level - 50, 0) * 14 + 560
end
elseif category == "melee 1h" then
if Melee1Text == "axe" then
copper = math.min(level, 50) * 14 + math.max(level - 50, 0) * 14 + 150
elseif Melee1Text == "club" then
copper = math.min(level, 50) * 14 + math.max(level - 50, 0) * 14 + 148
elseif Melee1Text == "dagger" then
copper = math.min(level, 50) * 8 + math.max(level - 50, 0) * 10 + 130
elseif Melee1Text == "hammer" then
copper = math.min(level, 50) * 14 + math.max(level - 50, 0) * 14 + 148
elseif Melee1Text == "mace" then
copper = math.min(level, 50) * 14 + math.max(level - 50, 0) * 14 + 148
elseif Melee1Text == "spear" then
copper = math.min(level, 50) * 14 + math.max(level - 50, 0) * 14 + 50
elseif Melee1Text == "sword" then
copper = math.min(level, 50) * 14 + math.max(level - 50, 0) * 14 + 150
end
elseif category == "melee 2h" then
if Melee2Text == "axe" then
copper = math.min(level, 50) * 14 + math.max(level - 50, 0) * 14 + 560
elseif Melee2Text == "club" then
copper = math.min(level, 50) * 14 + math.max(level - 50, 0) * 14 + 560
elseif Melee2Text == "halberd" then
copper = math.min(level, 50) * 14 + math.max(level - 50, 0) * 14 + 200
elseif Melee2Text == "hammer" then
copper = math.min(level, 50) * 14 + math.max(level - 50, 0) * 14 + 560
elseif Melee2Text == "rune-stone" then
copper = math.min(level, 50) * 14 + math.max(level - 50, 0) * 14 + 100
elseif Melee2Text == "staff" then
copper = math.min(level, 50) * 14 + math.max(level - 50, 0) * 14 + 100
elseif Melee2Text == "sword" then
copper = math.min(level, 50) * 14 + math.max(level - 50, 0) * 14 + 560
end
elseif category == "ranged" then
if RangedText == "bow" then
copper = math.min(level, 50) * 14 + math.max(level - 50, 0) * 14 + 120
elseif RangedText == "crossbow" then
copper = math.min(level, 50) * 14 + math.max(level - 50, 0) * 14 + 500
elseif RangedText == "javelin" then
copper = math.min(level, 50) * 14 + math.max(level - 50, 0) * 14 + 120
end
end
local QualityText = QualityButton:GetText()
if QualityText == "uncommon" then
copper = copper * 0.6
elseif QualityText == "incomparable" then
copper = copper * 1.5
elseif QualityText == "epic" then
copper = copper * 2
end
local output = "vendor prediction:"
local silver = math.floor(copper / 100)
if silver > 0 then
copper = copper - (silver * 100)
output = string.format("%s %ss", output, silver)
end
if copper ~= 0 then
output = string.format("%s %dc", output, copper) -- forced to integer
end
return output
end
-------------------------------------------------------------------------------
-- main function
function Calculate()
-- determine valid inputs and best-guess of level
local ValidInputs = {}
local best = 0
local trustbest = false
for i = 1, #StatOrder do
local rating = tonumber(TextBoxes[i]:GetText())
if rating then
ValidInputs[i] = rating
TextBoxes[i]:SetText(rating) -- fix whitespace problems
local guess, trustguess = GuessLevel(StatOrder[i], rating)
if trustguess and (not trustbest or guess > best) then
best = guess
trustbest = true
elseif not trustbest and guess > best then
best = guess
end
else
TextBoxes[i]:SetText("") -- clear bad inputs
end
end
LevelLabel:SetText("suspected level: "..best)
if best < 66 then
LevelLabel:SetForeColor(Turbine.UI.Color(1, 0, 0))
else
LevelLabel:SetForeColor(Turbine.UI.Color(0, 1, 0))
end
-- calculate units, equivs, and totals
local override = tonumber(OverrideBox:GetText()) or best
local UnitTotal = 0
local EquivTotal = 0
local primary = TypicalRatingsByLevel("Might", override) -- all the primary stats are the same
for i = 1, #StatOrder do
if ValidInputs[i] then
local unit = ValidInputs[i] / TypicalRatingsByLevel(StatOrder[i], override)
local equiv = unit * primary
UnitTotal = UnitTotal + unit
EquivTotal = EquivTotal + equiv
UnitLabels[i]:SetText(unit)
EquivLabels[i]:SetText(equiv)
else
UnitLabels[i]:SetText(".")
EquivLabels[i]:SetText(".")
end
end
UnitTotalLabel:SetText(UnitTotal)
EquivTotalLabel:SetText(EquivTotal)
local QualitySize = 8
if QualityButton:GetText() == "uncommon" then
QualitySize = 5
elseif QualityButton:GetText() == "rare" then
QualitySize = 6
elseif QualityButton:GetText() == "incomparable" then
QualitySize = 7
end
local category = CategoryButton:GetText()
if category == "melee 2h" then
QualitySize = QualitySize * 2
end
UnitMaxLabel:SetText("of "..QualitySize)
EquivMaxLabel:SetText("of "..QualitySize * primary)
local extra = GuessVendor(override)
if category == "melee 1h" or category == "melee 2h" or category == "ranged" then
extra = extra..GuessDamage(override)
elseif category ~= "jewellery" then
extra = extra.."\narmour prediction: "..GuessArmour(override)
if category == "shield" then
if ShieldButton:GetText() == "heavy" then
extra = extra.."\ncritical defence: "..(override + 1) * 20
elseif ShieldButton:GetText() == "warden" then
extra = extra.."\ncritical defence: "..(override + 1) * 16
else
extra = extra.."\ncritical defence: "..(override + 1) * 8
end
end
end
ExtraLabel:SetText(extra)
end
function Reset()
for i = 1, #StatOrder do
TextBoxes[i]:SetText("")
end
OverrideBox:SetText("")
Calculate()
end
-------------------------------------------------------------------------------
-- tedious window-layout and menu functions
local WindowWidth = 380
local WindowHeight = 580
CalcWindow = Turbine.UI.Lotro.Window()
CalcWindow:SetPosition(WindowLeft, WindowTop)
CalcWindow:SetSize(WindowWidth, WindowHeight)
CalcWindow:SetText("ItemCalc")
CalcWindow:SetVisible(true)
function MakeLabel(Left, Top, Width, Height)
local TempLabel = Turbine.UI.Label()
TempLabel:SetParent(CalcWindow)
TempLabel:SetPosition(Left, Top)
TempLabel:SetSize(Width, Height)
TempLabel:SetFont(Turbine.UI.Lotro.Font.Verdana16)
TempLabel:SetMouseVisible(false)
return TempLabel
end
function MakeTextbox(Left, Top, Width, Height)
local TempTextbox = Turbine.UI.Lotro.TextBox()
TempTextbox:SetParent(CalcWindow)
TempTextbox:SetPosition(Left, Top)
TempTextbox:SetSize(Width, Height)
TempTextbox:SetFont(Turbine.UI.Lotro.Font.Verdana16)
return TempTextbox
end
function MakeButton(Left, Top, Width, Height, Text)
local TempButton = Turbine.UI.Lotro.Button()
TempButton:SetParent(CalcWindow)
TempButton:SetPosition(Left, Top)
TempButton:SetSize(Width, Height)
TempButton:SetFont(Turbine.UI.Lotro.Font.Verdana16)
TempButton:SetText(Text)
return TempButton
end
for i = 1, #StatOrder do
StatLabels[i] = MakeLabel(20, 10 + i * 20, 170, 20)
StatLabels[i]:SetText(StatOrder[i])
TextBoxes[i] = MakeTextbox(190, 10 + i * 20, 50, 20)
UnitLabels[i] = MakeLabel(250, 10 + i * 20, 40, 19)
UnitLabels[i]:SetTextAlignment(Turbine.UI.ContentAlignment.TopRight)
EquivLabels[i] = MakeLabel(300, 10 + i * 20, 60, 19)
EquivLabels[i]:SetTextAlignment(Turbine.UI.ContentAlignment.TopRight)
end
LevelLabel = MakeLabel(20, 10 + (#StatOrder + 1) * 20, 140, 19)
UnitTotalLabel = MakeLabel(250, 10 + (#StatOrder + 1) * 20, 40, 19)
UnitTotalLabel:SetTextAlignment(Turbine.UI.ContentAlignment.TopRight)
EquivTotalLabel = MakeLabel(300, 10 + (#StatOrder + 1) * 20, 60, 19)
EquivTotalLabel:SetTextAlignment(Turbine.UI.ContentAlignment.TopRight)
OverrideLabel = MakeLabel(20, 10 + (#StatOrder + 2) * 20, 100, 19)
OverrideLabel:SetText("level override:")
OverrideBox = MakeTextbox(120, 10 + (#StatOrder + 2) * 20, 50, 20)
UnitMaxLabel = MakeLabel(250, 10 + (#StatOrder + 2) * 20, 40, 19)
UnitMaxLabel:SetTextAlignment(Turbine.UI.ContentAlignment.TopRight)
EquivMaxLabel = MakeLabel(300, 10 + (#StatOrder + 2) * 20, 60, 19)
EquivMaxLabel:SetTextAlignment(Turbine.UI.ContentAlignment.TopRight)
CalculateButton = MakeButton(20, 10 + (#StatOrder + 3) * 20, 70, 20, "calculate")
CalculateButton.Click = function(sender, args)
Calculate()
end
DebugButton = MakeButton(90, 10 + (#StatOrder + 3) * 20, 50, 20, "debug")
DebugButton.Click = function(sender, args)
if debug then
debug = false
Turbine.Shell.WriteLine("ItemCalc debugging is now off.")
else
debug = true
Turbine.Shell.WriteLine("ItemCalc debugging is now on.")
end
end
ResetButton = MakeButton(140, 10 + (#StatOrder + 3) * 20, 50, 20, "reset")
ResetButton.Click = function(sender, args)
Reset()
end
QualityButton = MakeButton(20, 10 + (#StatOrder + 4) * 20, 100, 20, QualityNames[1])
QualityButton:SetForeColor(QualityColours[1])
QualityContext = Turbine.UI.ContextMenu()
QualityContextItems = QualityContext:GetItems()
for i = 1, #QualityNames do
local menuItem = Turbine.UI.MenuItem(QualityNames[i])
menuItem.Click = function(sender, args)
QualityButton:SetText(QualityNames[i])
QualityButton:SetForeColor(QualityColours[i])
Calculate()
end
QualityContextItems:Add(menuItem)
end
QualityButton.Click = function(sender, args)
QualityContext:ShowMenu()
end
CategoryButton = MakeButton(120, 10 + (#StatOrder + 4) * 20, 110, 20, CategoryNames[1])
CategoryContext = Turbine.UI.ContextMenu()
CategoryContextItems = CategoryContext:GetItems()
for i = 1, #CategoryNames do
local menuItem = Turbine.UI.MenuItem(CategoryNames[i])
menuItem.Click = function(sender, args)
CategoryButton:SetText(CategoryNames[i])
ArmourButton:SetVisible(false)
JewelleryButton:SetVisible(false)
ShieldButton:SetVisible(false)
Melee1Button:SetVisible(false)
Melee2Button:SetVisible(false)
RangedButton:SetVisible(false)
if CategoryNames[i] == "light armour"
or CategoryNames[i] == "medium armour"
or CategoryNames[i] == "heavy armour" then
ArmourButton:SetVisible(true)
elseif CategoryNames[i] == "jewellery" then
JewelleryButton:SetVisible(true)
elseif CategoryNames[i] == "shield" then
ShieldButton:SetVisible(true)
elseif CategoryNames[i] == "melee 1h" then
Melee1Button:SetVisible(true)
elseif CategoryNames[i] == "melee 2h" then
Melee2Button:SetVisible(true)
elseif CategoryNames[i] == "ranged" then
RangedButton:SetVisible(true)
end
Calculate()
end
CategoryContextItems:Add(menuItem)
end
CategoryButton.Click = function(sender, args)
CategoryContext:ShowMenu()
end
ArmourButton = MakeButton(230, 10 + (#StatOrder + 4) * 20, 80, 20, ArmourNames[1])
ArmourContext = Turbine.UI.ContextMenu()
ArmourContextItems = ArmourContext:GetItems()
for i = 1, #ArmourNames do
local menuItem = Turbine.UI.MenuItem(ArmourNames[i])
menuItem.Click = function(sender, args)
ArmourButton:SetText(ArmourNames[i])
Calculate()
end
ArmourContextItems:Add(menuItem)
end
ArmourButton.Click = function(sender, args)
ArmourContext:ShowMenu()
end
JewelleryButton = MakeButton(230, 10 + (#StatOrder + 4) * 20, 80, 20, JewelleryNames[1])
JewelleryContext = Turbine.UI.ContextMenu()
JewelleryContextItems = JewelleryContext:GetItems()
for i = 1, #JewelleryNames do
local menuItem = Turbine.UI.MenuItem(JewelleryNames[i])
menuItem.Click = function(sender, args)
JewelleryButton:SetText(JewelleryNames[i])
Calculate()
end
JewelleryContextItems:Add(menuItem)
end
JewelleryButton.Click = function(sender, args)
JewelleryContext:ShowMenu()
end
JewelleryButton:SetVisible(false) -- since we start with armour
ShieldButton = MakeButton(230, 10 + (#StatOrder + 4) * 20, 80, 20, ShieldNames[1])
ShieldContext = Turbine.UI.ContextMenu()
ShieldContextItems = ShieldContext:GetItems()
for i = 1, #ShieldNames do
local menuItem = Turbine.UI.MenuItem(ShieldNames[i])
menuItem.Click = function(sender, args)
ShieldButton:SetText(ShieldNames[i])
Calculate()
end
ShieldContextItems:Add(menuItem)
end
ShieldButton.Click = function(sender, args)
ShieldContext:ShowMenu()
end
ShieldButton:SetVisible(false) -- since we start with armour
Melee1Button = MakeButton(230, 10 + (#StatOrder + 4) * 20, 80, 20, Melee1Names[1])
Melee1Context = Turbine.UI.ContextMenu()
Melee1ContextItems = Melee1Context:GetItems()
for i = 1, #Melee1Names do
local menuItem = Turbine.UI.MenuItem(Melee1Names[i])
menuItem.Click = function(sender, args)
Melee1Button:SetText(Melee1Names[i])
Calculate()
end
Melee1ContextItems:Add(menuItem)
end
Melee1Button.Click = function(sender, args)
Melee1Context:ShowMenu()
end
Melee1Button:SetVisible(false) -- since we start with armour
Melee2Button = MakeButton(230, 10 + (#StatOrder + 4) * 20, 80, 20, Melee2Names[1])
Melee2Context = Turbine.UI.ContextMenu()
Melee2ContextItems = Melee2Context:GetItems()
for i = 1, #Melee2Names do
local menuItem = Turbine.UI.MenuItem(Melee2Names[i])
menuItem.Click = function(sender, args)
Melee2Button:SetText(Melee2Names[i])
Calculate()
end
Melee2ContextItems:Add(menuItem)
end
Melee2Button.Click = function(sender, args)
Melee2Context:ShowMenu()
end
Melee2Button:SetVisible(false) -- since we start with armour
RangedButton = MakeButton(230, 10 + (#StatOrder + 4) * 20, 80, 20, RangedNames[1])
RangedContext = Turbine.UI.ContextMenu()
RangedContextItems = RangedContext:GetItems()
for i = 1, #RangedNames do
local menuItem = Turbine.UI.MenuItem(RangedNames[i])
menuItem.Click = function(sender, args)
RangedButton:SetText(RangedNames[i])
Calculate()
end
RangedContextItems:Add(menuItem)
end
RangedButton.Click = function(sender, args)
RangedContext:ShowMenu()
end
RangedButton:SetVisible(false) -- since we start with armour
ExtraLabel = MakeLabel(20, 10 + (#StatOrder + 5) * 20, 300, 48)
-------------------------------------------------------------------------------
-- command-line processing
CommandLine = Turbine.ShellCommand()
CommandLine.Execute = function(sender, cmd, args)
if CalcWindow:IsVisible() then
CalcWindow:SetVisible(false)
else
CalcWindow:SetVisible(true)
end
end
Turbine.Shell.AddCommand("ItemCalc", CommandLine)
-------------------------------------------------------------------------------
-- create a dummy window, and update until loaded, at which point set loaded=true and set the unload commands.
local loaded = false
tmpWindow = Turbine.UI.Window()
tmpWindow.Update = function()
if Plugins["ItemCalc"] ~= nil and not loaded then
loaded = true
Plugins["ItemCalc"].Unload = function(self, sender, args)
Turbine.Shell.RemoveCommand(CommandLine)
end
tmpWindow:SetWantsUpdates(false)
Turbine.Shell.WriteLine("ItemCalc plugin loaded.".._VERSION)
Reset()
end
end
tmpWindow:SetWantsUpdates(true)