summaryrefslogtreecommitdiff
path: root/Data/BuiltIn/Libraries/lua-addons/addons/bluguide
diff options
context:
space:
mode:
Diffstat (limited to 'Data/BuiltIn/Libraries/lua-addons/addons/bluguide')
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/bluguide/bluguide.lua290
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/bluguide/masterlist.lua192
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/bluguide/res/spellinfo.lua206
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/bluguide/res/traits.lua426
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/bluguide/ui/buttons.lua119
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/bluguide/ui/pages.lua67
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/bluguide/ui/spellboxes.lua157
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/bluguide/ui/spellbuttons.lua102
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/bluguide/ui/traitboxes.lua204
9 files changed, 1763 insertions, 0 deletions
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/bluguide.lua b/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/bluguide.lua
new file mode 100644
index 0000000..e541b98
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/bluguide.lua
@@ -0,0 +1,290 @@
+traits = require ('res/traits')
+buttons = require ('ui/buttons')
+spellinfo = require ('res/spellinfo')
+pages = require("ui/pages")
+traitboxes = require("ui/traitboxes")
+spellboxes = require("ui/spellboxes")
+setspells = require("masterlist")
+
+_addon.version = '1.2'
+_addon.name = 'bluGuide'
+_addon.author = 'Anissa of Cerberus'
+
+local button_settings = {
+ text = { size = 15, font = 'Arial',},
+ bg = { alpha = 200, red = 0, green = 100, blue = 100, visible = false },
+}
+
+windower.register_event('load',function ()
+
+ giftexempttraits = {
+ ['Double/Triple Attack'] = true,
+ ['Auto Refresh'] = true,
+ ['Gilfinder/Treasure Hunter'] = true,
+ }
+ lineheight = 14
+ updatelist = {}
+ setspells.create(30, 50, update)
+ build_columns()
+
+ local player = windower.ffxi.get_player()
+ job = player.main_job
+ sub = player.sub_job
+
+ traitsbutton = buttons.new("Traits", button_settings)
+ traitsbutton.pos(80, 360)
+ traitsbutton.show()
+ traitsbutton.left_click = show_traits
+ traitsbutton.hover_on = function() traitsbutton.bg_visible(true) end
+ traitsbutton.hover_off = function() traitsbutton.bg_visible(false) end
+
+ utilbutton = buttons.new("Utility", button_settings)
+ utilbutton.pos(80, 390)
+ utilbutton.show()
+ utilbutton.left_click = show_utilities
+ utilbutton.hover_on = function() utilbutton.bg_visible(true) end
+ utilbutton.hover_off = function() utilbutton.bg_visible(false) end
+
+ scbutton = buttons.new("Damage", button_settings)
+ scbutton.pos(80, 420)
+ scbutton.show()
+ scbutton.left_click = show_skillchain
+ scbutton.hover_on = function() scbutton.bg_visible(true) end
+ scbutton.hover_off = function() scbutton.bg_visible(false) end
+
+ procsbutton = buttons.new("Procs", button_settings)
+ procsbutton.pos(80, 450)
+ procsbutton.show()
+ procsbutton.left_click = show_procs
+ procsbutton.hover_on = function() procsbutton.bg_visible(true) end
+ procsbutton.hover_off = function() procsbutton.bg_visible(false) end
+
+ closebutton = buttons.new("Close", button_settings)
+ closebutton.pos(80, 480)
+ closebutton.show()
+ closebutton.left_click = close
+ closebutton.hover_on = function() closebutton.bg_visible(true) end
+ closebutton.hover_off = function() closebutton.bg_visible(false) end
+end)
+
+function update()
+ for _, v in pairs(updatelist) do
+ v:update()
+ end
+end
+
+windower.register_event('job change', function(new, old)
+ jobchange = coroutine.schedule(check_job, 5)
+end)
+
+function check_job()
+ local player = windower.ffxi.get_player()
+ local t = {}
+ if player.main_job == "BLU" then
+ if job ~= "BLU" then
+ print("Reloading bluGuide. Changed job/subjob combo.")
+ windower.send_command('lua reload bluguide')
+ end
+ elseif player.sub_job == "BLU" then
+ if sub ~= "BLU" then
+ print("Reloading bluGuide. Changed job/subjob combo.")
+ windower.send_command('lua reload bluguide')
+ end
+ else
+ print("Unloading bluGuide. Invalid job/subjob combo.")
+ windower.send_command('lua unload bluguide')
+ end
+end
+
+function build_columns()
+ traitpage = pages.new(260, 50)
+
+ traitpage:add(traitboxes.new(traits['Dual Wield']))
+ traitpage:add(traitboxes.new(traits['Double/Triple Attack']))
+ traitpage:add(traitboxes.new(traits['Attack Bonus']))
+ traitpage:add(traitboxes.new(traits['Accuracy Bonus']))
+ traitpage:add(traitboxes.new(traits['Store TP']))
+ traitpage:add(traitboxes.new(traits['Skillchain Bonus']))
+ traitpage:add(traitboxes.new(traits['Critical Attack Bonus']))
+ traitpage:add(traitboxes.new(traits['Magic Attack Bonus']))
+ traitpage:add(traitboxes.new(traits['Magic Accuracy Bonus']))
+ traitpage:add(traitboxes.new(traits['Fast Cast']))
+ traitpage:add(traitboxes.new(traits['Magic Burst Bonus']))
+ traitpage:add(traitboxes.new(traits['Conserve MP']))
+ traitpage:add(traitboxes.new(traits['Auto Refresh']))
+ traitpage:add(traitboxes.new(traits['Clear Mind']))
+ traitpage:add(traitboxes.new(traits['Max MP Boost']))
+ traitpage:add(traitboxes.new(traits['Counter']))
+ traitpage:add(traitboxes.new(traits['Defense Bonus']))
+ traitpage:add(traitboxes.new(traits['Magic Defense Bonus']))
+ traitpage:add(traitboxes.new(traits['Magic Evasion Bonus']))
+ traitpage:add(traitboxes.new(traits['Evasion Bonus']))
+ traitpage:add(traitboxes.new(traits['Inquartata']))
+ traitpage:add(traitboxes.new(traits['Auto Regen']))
+ traitpage:add(traitboxes.new(traits['Max HP Boost']))
+ traitpage:add(traitboxes.new(traits['Tenacity']))
+ traitpage:add(traitboxes.new(traits['Resist Gravity']))
+ traitpage:add(traitboxes.new(traits['Resist Silence']))
+ traitpage:add(traitboxes.new(traits['Resist Sleep']))
+ traitpage:add(traitboxes.new(traits['Resist Slow']))
+ traitpage:add(traitboxes.new(traits['Gilfinder/TH']))
+ traitpage:add(traitboxes.new(traits['Beast Killer']))
+ traitpage:add(traitboxes.new(traits['Lizard Killer']))
+ traitpage:add(traitboxes.new(traits['Undead Killer']))
+ traitpage:add(traitboxes.new(traits['Plantoid Killer']))
+ traitpage:add(traitboxes.new(traits['Rapid Shot']))
+ traitpage:add(traitboxes.new(traits['Zanshin']))
+
+ updatelist[#updatelist+1] = traitpage
+ traitpage:show()
+
+ buffpage = pages.new(260, 50)
+ buffpage:add(spellboxes.new('Cure', function(s) return s.effect['Cure'] end))
+ buffpage:add(spellboxes.new('Erase', function(s) return s.effect['Erase'] end))
+ buffpage:add(spellboxes.new('Haste', function(s) return s.effect['Haste'] end))
+ buffpage:add(spellboxes.new('Attack Boost', function(s) return s.effect['Attack Boost'] end))
+ buffpage:add(spellboxes.new('Refresh', function(s) return s.effect['Refresh'] end))
+ buffpage:add(spellboxes.new('Accuracy Boost', function(s) return s.effect['Accuracy Boost'] end))
+ buffpage:add(spellboxes.new('Magic Attack Boost', function(s) return s.effect['Magic Attack Boost'] end))
+
+ buffpage:add(spellboxes.new('Blink', function(s) return s.effect['Blink'] end))
+ buffpage:add(spellboxes.new('Defense Boost', function(s) return s.effect['Defense Boost'] end))
+ buffpage:add(spellboxes.new('Phalanx', function(s) return s.effect['Phalanx'] end))
+ buffpage:add(spellboxes.new('Stoneskin', function(s) return s.effect['Stoneskin'] end))
+ buffpage:add(spellboxes.new('Spikes', function(s) return s.effect['Spikes'] end))
+ buffpage:add(spellboxes.new('Magic Defense Boost', function(s) return s.effect['Magic Defense Boost'] end))
+ buffpage:add(spellboxes.new('Evasion Boost', function(s) return s.effect['Evasion Boost'] end))
+ buffpage:add(spellboxes.new('Regen', function(s) return s.effect['Regen'] end))
+ buffpage:add(spellboxes.new('Counter', function(s) return s.effect['Counter'] end))
+
+ buffpage:add(spellboxes.new('Sleep', function(s) return s.effect['Sleep'] end))
+ buffpage:add(spellboxes.new('Dispel', function(s) return s.effect['Dispel'] end))
+ buffpage:add(spellboxes.new('Defense Down', function(s) return s.effect['Defense Down'] end))
+ buffpage:add(spellboxes.new('Evasion Down', function(s) return s.effect['Evasion Down'] end))
+ buffpage:add(spellboxes.new('Magic Defense Down', function(s) return s.effect['Magic Defense Down'] end))
+
+ buffpage:add(spellboxes.new('Aspir', function(s) return s.effect['Aspir'] end))
+ buffpage:add(spellboxes.new('Drain', function(s) return s.effect['Drain'] end))
+ buffpage:add(spellboxes.new('Poison', function(s) return s.effect['Poison'] end))
+ buffpage:add(spellboxes.new('Stun', function(s) return s.effect['Stun'] end))
+ buffpage:add(spellboxes.new('Terror', function(s) return s.effect['Terror'] end))
+
+ buffpage:add(spellboxes.new('Silence', function(s) return s.effect['Silence'] end))
+ buffpage:add(spellboxes.new('Slow', function(s) return s.effect['Slow'] end))
+ buffpage:add(spellboxes.new('Paralyze', function(s) return s.effect['Paralyze'] end))
+ buffpage:add(spellboxes.new('Reduce TP', function(s) return s.effect['Reduce TP'] end))
+ buffpage:add(spellboxes.new('Plague', function(s) return s.effect['Plague'] end))
+
+ buffpage:add(spellboxes.new('Bind', function(s) return s.effect['Bind'] end))
+ buffpage:add(spellboxes.new('Gravity', function(s) return s.effect['Gravity'] end))
+ buffpage:add(spellboxes.new('Petrify', function(s) return s.effect['Petrify'] end))
+ buffpage:add(spellboxes.new('Flash', function(s) return s.effect['Flash'] end))
+ buffpage:add(spellboxes.new('Blind', function(s) return s.effect['Blind'] end))
+ buffpage:add(spellboxes.new('Accuracy Down', function(s) return s.effect['Accuracy Down'] end))
+
+ buffpage:add(spellboxes.new('Bio', function(s) return s.effect['Bio'] end))
+ buffpage:add(spellboxes.new('Doom', function(s) return s.effect['Doom'] end))
+ buffpage:add(spellboxes.new('Frost', function(s) return s.effect['Frost'] end))
+ buffpage:add(spellboxes.new('Burn', function(s) return s.effect['Burn'] end))
+ buffpage:add(spellboxes.new('Drown', function(s) return s.effect['Drown'] end))
+ buffpage:add(spellboxes.new('Vit Down', function(s) return s.effect['Vit Down'] end))
+ buffpage:add(spellboxes.new('Int Down', function(s) return s.effect['Int Down'] end))
+ buffpage:add(spellboxes.new('Str Down', function(s) return s.effect['Str Down'] end))
+ buffpage:add(spellboxes.new('Dex Down', function(s) return s.effect['Dex Down'] end))
+
+ updatelist[#updatelist+1] = buffpage
+
+ procpage = pages.new(260, 50)
+ procpage:add(spellboxes.new('Voidwatch - Fire', function(s) return s.Voidwatch ~= nil and s.element == 0 end))
+ procpage:add(spellboxes.new('Voidwatch - Ice', function(s) return s.Voidwatch and s.element == 1 end))
+ procpage:add(spellboxes.new('Voidwatch - Wind', function(s) return s.Voidwatch and s.element == 2 end))
+ procpage:add(spellboxes.new('Voidwatch - Earth', function(s) return s.Voidwatch and s.element == 3 end))
+ procpage:add(spellboxes.new('Voidwatch - Thunder', function(s) return s.Voidwatch and s.element == 4 end))
+ procpage:add(spellboxes.new('Voidwatch - Water', function(s) return s.Voidwatch and s.element == 5 end))
+ procpage:add(spellboxes.new('Voidwatch - Light', function(s) return s.Voidwatch and s.element == 6 end))
+ procpage:add(spellboxes.new('Voidwatch - Dark', function(s) return s.Voidwatch and s.element == 7 end))
+ procpage:add(spellboxes.new('Abyssea', function(s) return s.Abyssea end))
+ updatelist[#updatelist+1] = procpage
+
+ scpage = pages.new(260, 50)
+ scpage:add(spellboxes.new('Gravitation', function(s) return s.SCA == "Gravitation" or s.SCB == "Gravitation" end, function(s) if s.SCB == "Gravitation" then return s.name.." ("..string.sub(s.SCA, 1, 3)..")" end end))
+ scpage:add(spellboxes.new('Fusion', function(s) return s.SCA == "Fusion" or s.SCB == "Fusion" end, function(s) if s.SCB == "Fusion" then return s.name.." ("..string.sub(s.SCA, 1, 3)..")" end end))
+ scpage:add(spellboxes.new('Distortion', function(s) return s.SCA == "Distortion" or s.SCB == "Distortion" end, function(s) if s.SCB == "Distortion" then return s.name.." ("..string.sub(s.SCA, 1, 3)..")" end end))
+ scpage:add(spellboxes.new('Fragmentation', function(s) return s.SCA == "Fragmentation" or s.SCB == "Fragmentation" end, function(s) if s.SCB == "Fragmentation" then return s.name.." ("..string.sub(s.SCA, 1, 3)..")" end end))
+ scpage:add(spellboxes.new('Transfixion', function(s) return s.SCA == "Transfixion" or s.SCB == "Transfixion" end, function(s) if s.SCB == "Transfixion" then return s.name.." ("..string.sub(s.SCA, 1, 3)..")" end end))
+ scpage:add(spellboxes.new('Compression', function(s) return s.SCA == "Compression" or s.SCB == "Compression" end, function(s) if s.SCB == "Compression" then return s.name.." ("..string.sub(s.SCA, 1, 3)..")" end end))
+ scpage:add(spellboxes.new('Reverberation', function(s) return s.SCA == "Reverberation" or s.SCB == "Reverberation" end, function(s) if s.SCB == "Reverberation" then return s.name.." ("..string.sub(s.SCA, 1, 3)..")" end end))
+ scpage:add(spellboxes.new('Induration', function(s) return s.SCA == "Induration" or s.SCB == "Induration" end, function(s) if s.SCB == "Induration" then return s.name.." ("..string.sub(s.SCA, 1, 3)..")" end end))
+ scpage:add(spellboxes.new('Impaction', function(s) return s.SCA == "Impaction" or s.SCB == "Impaction" end, function(s) if s.SCB == "Impaction" then return s.name.." ("..string.sub(s.SCA, 1, 3)..")" end end))
+ scpage:add(spellboxes.new('Liquifaction', function(s) return s.SCA == "Liquifaction" or s.SCB == "Liquifaction" end, function(s) if s.SCB == "Liquifaction" then return s.name.." ("..string.sub(s.SCA, 1, 3)..")" end end))
+ scpage:add(spellboxes.new('Detonation', function(s) return s.SCA == "Detonation" or s.SCB == "Detonation" end, function(s) if s.SCB == "Detonation" then return s.name.." ("..string.sub(s.SCA, 1, 3)..")" end end))
+ scpage:add(spellboxes.new('Scission', function(s) return s.SCA == "Scission" or s.SCB == "Scission" end, function(s) if s.SCB == "Scission" then return s.name.." ("..string.sub(s.SCA, 1, 3)..")" end end))
+
+ scpage:add(spellboxes.new("Fire", function(s) return s.Nuke and s.element == 0 end))
+ scpage:add(spellboxes.new("Ice", function(s) return s.Nuke and s.element == 1 end))
+ scpage:add(spellboxes.new("Wind", function(s) return s.Nuke and s.element == 2 end))
+ scpage:add(spellboxes.new("Earth", function(s) return s.Nuke and s.element == 3 end))
+ scpage:add(spellboxes.new("Thunder", function(s) return s.Nuke and s.element == 4 end))
+ scpage:add(spellboxes.new("Water", function(s) return s.Nuke and s.element == 5 end))
+ scpage:add(spellboxes.new("Light", function(s) return s.Nuke and s.element == 6 end))
+ scpage:add(spellboxes.new("Dark", function(s) return s.Nuke and s.element == 7 end))
+ updatelist[#updatelist+1] = scpage
+end
+
+function show_traits()
+ traitpage:show()
+ buffpage:hide()
+ procpage:hide()
+ scpage:hide()
+end
+
+function show_utilities()
+ traitpage:hide()
+ buffpage:show()
+ procpage:hide()
+ scpage:hide()
+end
+
+function show_procs()
+ traitpage:hide()
+ buffpage:hide()
+ procpage:show()
+ scpage:hide()
+end
+
+function show_skillchain()
+ traitpage:hide()
+ buffpage:hide()
+ procpage:hide()
+ scpage:show()
+end
+
+function close()
+ windower.send_command('lua unload bluguide')
+end
+
+--Copyright © 2015, Anissa
+--All rights reserved.
+
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are met:
+
+-- * Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- * Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+-- * Neither the name of bluGuide nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+--ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+--WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+--DISCLAIMED. IN NO EVENT SHALL ANISSA BE LIABLE FOR ANY
+--DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+--(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+--LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+--ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+--(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/masterlist.lua b/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/masterlist.lua
new file mode 100644
index 0000000..eaed220
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/masterlist.lua
@@ -0,0 +1,192 @@
+texts = require("texts")
+spellbuttons = require("ui/spellbuttons")
+spelllist = {}
+display = {}
+
+local function get_limits()
+ local player = windower.ffxi.get_player()
+ local slots = 0
+ local points = 0
+ local gifts = 0
+ local level = 0
+
+ if player.main_job == "BLU" then
+ if player.main_job_level > 70 then
+ slots = 20
+ else
+ slots = (math.floor((player.sub_job_level + 9) / 10) * 2) + 4
+ end
+
+ points = (math.floor((player.main_job_level + 9) / 10) * 5) + 5
+ if player.main_job_level >= 75 then
+ points = points + player.merits.assimilation
+ if player.main_job_level == 99 then
+ points = points + player.job_points.blu.blue_magic_point_bonus
+ end
+ end
+ level = player.main_job_level
+ elseif player.sub_job == "BLU" then
+ points = (math.floor((player.sub_job_level + 9) / 10) * 5) + 5
+ slots = (math.floor((player.sub_job_level + 9) / 10) * 2) + 4
+ level = player.sub_job_level
+ end
+
+ local jobpointsspent = player.job_points.blu.jp_spent
+ if jobpointsspent >= 1200 then
+ gifts = 2
+ elseif jobpointsspent >= 100 then
+ gifts = 1
+ end
+
+ spelllist.limits = { slots = slots, points = points, level = level }
+ spelllist.gifts = gifts
+ spelllist.learned = windower.ffxi.get_spells()
+end
+
+function spelllist.create(px, py, updatefn)
+ local textsettings = {
+ text = { size = 10, font = 'Lucida Console' },
+ bg = { alpha = 120, red = 0, green = 0, blue = 0, visible = true },
+ flags = { draggable = false },
+ pos = {x = px, y = py} }
+
+ slots = texts.new("Slots: 0/20 Points: 0/70", textsettings)
+ x = px
+ y = py
+ slots:pos(px, py)
+ slots:show()
+
+ spelllist.slots = 0
+ spelllist.points = 0
+ spelllist.update = updatefn
+ get_limits()
+
+ t = get_set_spells()
+ if not t.spells then return end
+ for _,v in pairs(t.spells) do
+ spelllist.add(v)
+ end
+end
+
+function get_set_spells()
+ local player = windower.ffxi.get_player()
+ local t = {}
+ if player.main_job == "BLU" then
+ t = windower.ffxi.get_mjob_data()
+ elseif player.sub_job == "BLU" then
+ t = windower.ffxi.get_sjob_data()
+ end
+ return t
+end
+
+function spelllist.add(spell)
+ spelllist[spell] = true
+ spelllist.slots = spelllist.slots + 1
+ spelllist.points = spelllist.points + spellinfo[spell].cost
+
+ local newspell = spellbuttons.new(string.format('%-24s %i', spellinfo[spell].name, spellinfo[spell].cost), spell, spellinfo[spell].cost, x, y + spelllist.slots * lineheight)
+ if spellinfo[spell].element == 0 then --fire
+ newspell:color(255, 0, 0)
+ elseif spellinfo[spell].element == 1 then --ice
+ newspell:color(180, 180, 255)
+ elseif spellinfo[spell].element == 2 then --wind
+ newspell:color(0, 255, 0)
+ elseif spellinfo[spell].element == 3 then --earth
+ newspell:color(255, 255, 0)
+ elseif spellinfo[spell].element == 4 then --thunder
+ newspell:color(255, 0, 255)
+ elseif spellinfo[spell].element == 5 then --water
+ newspell:color(100, 100, 255)
+ elseif spellinfo[spell].element == 6 then --light
+ newspell:color(235, 235, 255)
+ elseif spellinfo[spell].element == 7 then --dark
+ newspell:color(180, 180, 180)
+ elseif spellinfo[spell].element == 15 then --physical
+ newspell:color(200, 100, 0)
+ end
+
+ newspell:show()
+ display[spell] = newspell
+
+ spelllist.sort()
+
+ local t = get_set_spells()
+ for i = 1, spelllist.limits.slots do
+ if t.spells[i] == nil then
+ windower.ffxi.set_blue_magic_spell(spell, i)
+ return
+ end
+ end
+end
+
+function spelllist.remove(spell)
+ display[spell]:destroy()
+ display[spell] = nil
+
+ spelllist[spell] = nil
+
+ spelllist.slots = spelllist.slots - 1
+ spelllist.points = spelllist.points - spellinfo[spell].cost
+
+ spelllist.sort()
+
+
+ local t = get_set_spells()
+ for i = 1, spelllist.limits.slots do
+ if t.spells[i] == spell then
+ windower.ffxi.remove_blue_magic_spell(i)
+
+ return
+ end
+ end
+
+end
+
+function spelllist.sort()
+ local pos = 1
+ vspace = "\n"
+ for _, v in pairs(display) do
+ vspace = vspace.."\n"
+ v:pos(x, y + (pos*lineheight))
+ v:update()
+ pos = pos + 1
+ end
+ slots:text(string.format('Slots: %2i/%2i Points: %2i/%2i', spelllist.slots, spelllist.limits.slots, spelllist.points, spelllist.limits.points)..vspace)
+ spelllist.update()
+end
+
+function spelllist.toggle(spell)
+ if spelllist[spell] then
+ spelllist.remove(spell)
+ else
+ spelllist.add(spell)
+ end
+end
+
+return spelllist
+
+--Copyright © 2015, Anissa
+--All rights reserved.
+
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are met:
+
+-- * Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- * Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+-- * Neither the name of bluGuide nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+--ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+--WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+--DISCLAIMED. IN NO EVENT SHALL ANISSA BE LIABLE FOR ANY
+--DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+--(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+--LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+--ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+--(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/res/spellinfo.lua b/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/res/spellinfo.lua
new file mode 100644
index 0000000..092b0ef
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/res/spellinfo.lua
@@ -0,0 +1,206 @@
+return {
+[584] = { name = "Sheep Song", id = 584, level = 16, cost = 2, element = 6, effect = { ["Sleep"] = true, }, },
+[616] = { name = "Temporal Shift", id = 616, level = 73, cost = 5, element = 4, effect = { ["Stun"] = true, }, Voidwatch = true, },
+[648] = { name = "Regurgitation", id = 648, level = 69, cost = 1, element = 5, effect = { ["Bind"] = true, }, Nuke = true },
+[680] = { name = "Charged Whisker", id = 680, level = 88, cost = 5, element = 4, effect = {}, Voidwatch = true, Nuke = true },
+[712] = { name = "Rail Cannon", id = 712, level = 99, cost = 6, element = 6, effect = {}, Nuke = true },
+[521] = { name = "MP Drainkiss", id = 521, level = 42, cost = 4, element = 7, effect = { ["Aspir"] = true, }, },
+[585] = { name = "Ram Charge", id = 585, level = 73, cost = 4, element = 15, effect = {}, SCA = "Fragmentation"},
+[617] = { name = "Vertical Cleave", id = 617, level = 75, cost = 3, element = 15, effect = {}, SCA = "Gravitation"},
+[681] = { name = "Winds of Promy.", id = 681, level = 89, cost = 5, element = 6, effect = { ["Erase"] = true, }, },
+[713] = { name = "Diffusion Ray", id = 713, level = 99, cost = 6, element = 6, effect = {}, Nuke = true },
+[522] = { name = "Death Ray", id = 522, level = 34, cost = 2, element = 7, effect = {}, Voidwatch = true, Nuke = true },
+[554] = { name = "Death Scissors", id = 554, level = 60, cost = 5, element = 15, effect = {}, SCA = "Compression", SCB = "Reverberation"},
+[618] = { name = "Blastbomb", id = 618, level = 18, cost = 2, element = 0, effect = { ["Bind"] = true, }, Voidwatch = true, Nuke = true },
+[650] = { name = "Seedspray", id = 650, level = 61, cost = 4, element = 15, effect = { ["Defense Down"] = true, }, SCA = "Induration", SCB = "Detonation", },
+[682] = { name = "Delta Thrust", id = 682, level = 89, cost = 2, element = 15, effect = { ["Plague"] = true, }, SCA = "Liquifaction", SCB = "Detonation"},
+[714] = { name = "Sinker Drill", id = 714, level = 99, cost = 6, element = 15, effect = {}, SCA = "Gravitation", SCB = "Reverberation"},
+[555] = { name = "Magnetite Cloud", id = 555, level = 46, cost = 3, element = 3, effect = { ["Gravity"] = true, }, Voidwatch = true, Abyssea = true, Nuke = true },
+[587] = { name = "Claw Cyclone", id = 587, level = 20, cost = 2, element = 15, effect = {}, SCA = "Scission"},
+[651] = { name = "Corrosive Ooze", id = 651, level = 66, cost = 4, element = 5, effect = { ["Defense Down"] = true, ["Attack Down"] = true, }, Voidwatch = true, Nuke = true },
+[683] = { name = "Evryone. Grudge", id = 683, level = 90, cost = 4, element = 7, effect = {}, Nuke = true },
+[715] = { name = "Molting Plumage", id = 715, level = 99, cost = 6, element = 2, effect = {}, Nuke = true },
+[524] = { name = "Sandspin", id = 524, level = 1, cost = 2, element = 3, effect = { ["Accuracy Down"] = true, }, Voidwatch = true, Nuke = true },
+[588] = { name = "Lowing", id = 588, level = 71, cost = 2, element = 0, effect = { ["Plague"] = true, }, },
+[620] = { name = "Battle Dance", id = 620, level = 12, cost = 3, element = 15, effect = { ["Dex Down"] = true, }, SCA = "Impaction"},
+[652] = { name = "Spiral Spin", id = 652, level = 60, cost = 3, element = 15, effect = { ["Accuracy Down"] = true, }, SCA = "Transfixion"},
+[684] = { name = "Reaving Wind", id = 684, level = 90, cost = 4, element = 2, effect = { ["Reduce TP"] = true, }, Voidwatch = true, },
+[716] = { name = "Nectarous Deluge", id = 716, level = 99, cost = 6, element = 5, effect = { ["Poison"] = true, }, Nuke = true },
+[557] = { name = "Eyes On Me", id = 557, level = 61, cost = 4, element = 7, effect = {}, Voidwatch = true, Abyssea = true, Nuke = true },
+[589] = { name = "Dimensional Death", id = 589, level = 60, cost = 5, element = 15, effect = {}, SCA = "Impaction"},
+[621] = { name = "Sandspray", id = 621, level = 66, cost = 2, element = 7, effect = { ["Blind"] = true, }, Voidwatch = true, },
+[653] = { name = "Asuran Claws", id = 653, level = 70, cost = 2, element = 15, effect = {}, SCA = "Liquifaction", SCB = "Impaction"},
+[685] = { name = "Barrier Tusk", id = 685, level = 91, cost = 3, element = 3, effect = { ["Phalanx"] = true, }, },
+[717] = { name = "Sweeping Gouge", id = 717, level = 99, cost = 6, element = 15, effect = { ["Defense Down"] = true, }, SCA = "Fragmentation", SCB = "Scission"},
+[622] = { name = "Grand Slam", id = 622, level = 30, cost = 2, element = 15, effect = {}, SCA = "Induration"},
+[654] = { name = "Sub-zero Smash", id = 654, level = 72, cost = 4, element = 15, effect = { ["Paralyze"] = true, }, SCA = "Fragmentation"},
+[686] = { name = "Mortal Ray", id = 686, level = 91, cost = 4, element = 7, effect = { ["Doom"] = true, }, },
+[718] = { name = "Atra. Libations", id = 718, level = 99, cost = 6, element = 7, effect = { ["Drain"] = true, }, Nuke = true },
+[527] = { name = "Smite of Rage", id = 527, level = 34, cost = 3, element = 15, effect = {}, SCA = "Detonation"},
+[591] = { name = "Heat Breath", id = 591, level = 71, cost = 4, element = 0, effect = {}, Voidwatch = true, Abyssea = true, Nuke = true },
+[623] = { name = "Head Butt", id = 623, level = 12, cost = 3, element = 15, effect = { ["Stun"] = true, }, SCA = "Impaction"},
+[655] = { name = "Triumphant Roar", id = 655, level = 71, cost = 3, element = 0, effect = { ["Attack Boost"] = true, }, },
+[687] = { name = "Water Bomb", id = 687, level = 92, cost = 2, element = 5, effect = { ["Silence"] = true, }, Nuke = true },
+[719] = { name = "Searing Tempest", id = 719, level = 99, cost = 8, element = 0, effect = { ["Burn"] = true, }, Nuke = true },
+[560] = { name = "Frenetic Rip", id = 560, level = 63, cost = 3, element = 15, effect = {}, SCA = "Induration"},
+[592] = { name = "Blank Gaze", id = 592, level = 38, cost = 2, element = 6, effect = { ["Dispel"] = true, }, Voidwatch = true, },
+[656] = { name = "Acrid Stream", id = 656, level = 77, cost = 3, element = 5, effect = { ["Magic Defense Down"] = true, }, Voidwatch = true, Nuke = true },
+[688] = { name = "Heavy Strike", id = 688, level = 92, cost = 2, element = 15, effect = {}, SCA = "Fragmentation", SCB = "Transfixion"},
+[720] = { name = "Spectral Floe", id = 720, level = 99, cost = 8, element = 1, effect = { ["Terror"] = true, }, Nuke = true },
+[529] = { name = "Bludgeon", id = 529, level = 18, cost = 2, element = 15, effect = {}, SCA = "Liquifaction"},
+[561] = { name = "Frightful Roar", id = 561, level = 50, cost = 3, element = 2, effect = { ["Defense Down"] = true, }, },
+[593] = { name = "Magic Fruit", id = 593, level = 58, cost = 3, element = 6, effect = { ["Cure"] = true, }, },
+[657] = { name = "Blazing Bound", id = 657, level = 80, cost = 3, element = 0, effect = {}, Nuke = true },
+[689] = { name = "Dark Orb", id = 689, level = 93, cost = 3, element = 7, effect = {}, Nuke = true },
+[721] = { name = "Anvil Lightning", id = 721, level = 99, cost = 8, element = 4, effect = { ["Stun"] = true, }, Nuke = true },
+[530] = { name = "Refueling", id = 530, level = 48, cost = 4, element = 2, effect = { ["Haste"] = true, }, },
+[594] = { name = "Uppercut", id = 594, level = 38, cost = 3, element = 15, effect = {}, SCA = "Liquifaction"},
+[626] = { name = "Bomb Toss", id = 626, level = 28, cost = 3, element = 0, effect = {}, Nuke = true },
+[658] = { name = "Plenilune Embrace", id = 658, level = 76, cost = 4, element = 6, effect = { ["Cure"] = true, }, },
+[690] = { name = "White Wind", id = 690, level = 94, cost = 5, element = 2, effect = { ["Cure"] = true, }, },
+[722] = { name = "Entomb", id = 722, level = 99, cost = 8, element = 3, effect = { ["Petrify"] = true, }, Nuke = true },
+[531] = { name = "Ice Break", id = 531, level = 50, cost = 3, element = 1, effect = { ["Bind"] = true, }, Voidwatch = true, Abyssea = true, Nuke = true },
+[563] = { name = "Hecatomb Wave", id = 563, level = 54, cost = 3, element = 2, effect = { ["Blind"] = true, }, Voidwatch = true, Nuke = true },
+[595] = { name = "1000 Needles", id = 595, level = 62, cost = 5, element = 6, effect = {}, Nuke = true },
+[659] = { name = "Demoralizing Roar", id = 659, level = 80, cost = 4, element = 5, effect = {}, },
+[723] = { name = "Saurian Slide", id = 723, level = 99, cost = 7, element = 15, effect = { ["Attack Down"] = true, }, SCA = "Fragmentation", SCB = "Distortion"},
+[532] = { name = "Blitzstrahl", id = 532, level = 44, cost = 4, element = 4, effect = { ["Stun"] = true, }, Voidwatch = true, Nuke = true },
+[564] = { name = "Body Slam", id = 564, level = 62, cost = 4, element = 15, effect = {}, SCA = "Impaction"},
+[596] = { name = "Pinecone Bomb", id = 596, level = 36, cost = 2, element = 15, effect = { ["Sleep"] = true, }, SCA = "Liquifaction"},
+[628] = { name = "Frypan", id = 628, level = 63, cost = 3, element = 15, effect = { ["Stun"] = true, }, SCA = "Impaction"},
+[660] = { name = "Cimicine Discharge", id = 660, level = 78, cost = 3, element = 3, effect = { ["Slow"] = true, }, Voidwatch = true, },
+[692] = { name = "Sudden Lunge", id = 692, level = 95, cost = 4, element = 15, effect = { ["Stun"] = true, }, SCA = "Detonation", SCB = "Impaction"},
+[724] = { name = "Palling Salvo", id = 724, level = 99, cost = 7, element = 7, effect = { ["Bio"] = true, }, Nuke = true },
+[533] = { name = "Self-Destruct", id = 533, level = 50, cost = 3, element = 0, effect = {}, Nuke = true },
+[565] = { name = "Radiant Breath", id = 565, level = 54, cost = 4, element = 6, effect = { ["Slow"] = true, ["Silence"] = true, }, Voidwatch = true, Abyssea = true, Nuke = true },
+[597] = { name = "Sprout Smack", id = 597, level = 4, cost = 2, element = 15, effect = { ["Slow"] = true, }, SCA = "Reverberation"},
+[629] = { name = "Flying Hip Press", id = 629, level = 58, cost = 3, element = 2, effect = {}, Nuke = true },
+[661] = { name = "Animating Wail", id = 661, level = 79, cost = 5, element = 2, effect = { ["Haste"] = true, }, },
+[693] = { name = "Quadrastrike", id = 693, level = 96, cost = 5, element = 15, effect = {}, SCA = "Liquifaction", SCB = "Scission"},
+[725] = { name = "Blinding Fulgor", id = 725, level = 99, cost = 8, element = 6, effect = { ["Flash"] = true, }, Nuke = true },
+[534] = { name = "Mysterious Light", id = 534, level = 40, cost = 4, element = 2, effect = { ["Gravity"] = true, }, Voidwatch = true, Abyssea = true, Nuke = true },
+[598] = { name = "Soporific", id = 598, level = 24, cost = 4, element = 7, effect = { ["Sleep"] = true, }, },
+[662] = { name = "Battery Charge", id = 662, level = 79, cost = 3, element = 6, effect = { ["Refresh"] = true, }, },
+[694] = { name = "Vapor Spray", id = 694, level = 96, cost = 3, element = 5, effect = {}, Nuke = true },
+[726] = { name = "Scouring Spate", id = 726, level = 99, cost = 8, element = 5, effect = { ["Attack Down"] = true, }, Nuke = true },
+[535] = { name = "Cold Wave", id = 535, level = 52, cost = 1, element = 1, effect = { ["Frost"] = true, }, Voidwatch = true, },
+[567] = { name = "Helldive", id = 567, level = 16, cost = 2, element = 15, effect = {}, SCA = "Transfixion"},
+[599] = { name = "Queasyshroom", id = 599, level = 8, cost = 2, element = 15, effect = { ["Poison"] = true, }, SCA = "Compression"},
+[631] = { name = "Hydro Shot", id = 631, level = 63, cost = 3, element = 15, effect = {}, SCA = "Reverberation"},
+[663] = { name = "Leafstorm", id = 663, level = 77, cost = 4, element = 2, effect = {}, Voidwatch = true, Nuke = true },
+[695] = { name = "Thunder Breath", id = 695, level = 97, cost = 4, element = 4, effect = {}, Nuke = true },
+[727] = { name = "Silent Storm", id = 727, level = 99, cost = 8, element = 2, effect = { ["Silence"] = true, }, Nuke = true },
+[536] = { name = "Poison Breath", id = 536, level = 22, cost = 1, element = 5, effect = { ["Poison"] = true, }, Nuke = true },
+[632] = { name = "Diamondhide", id = 632, level = 67, cost = 3, element = 3, effect = { ["Stoneskin"] = true, }, },
+[664] = { name = "Regeneration", id = 664, level = 78, cost = 2, element = 6, effect = { ["Regen"] = true, }, },
+[696] = { name = "O. Counterstance", id = 696, level = 98, cost = 5, element = 0, effect = { ["Counter"] = true, }, },
+[728] = { name = "Tenebral Crush", id = 728, level = 99, cost = 8, element = 7, effect = { ["Defense Down"] = true, }, Nuke = true },
+[537] = { name = "Stinking Gas", id = 537, level = 44, cost = 2, element = 2, effect = { ["Vit Down"] = true, }, },
+[569] = { name = "Jet Stream", id = 569, level = 38, cost = 4, element = 15, effect = {}, SCA = "Impaction"},
+[633] = { name = "Enervation", id = 633, level = 67, cost = 5, element = 7, effect = { ["Defense Down"] = true, ["Magic Defense Down"] = true, }, },
+[665] = { name = "Final Sting", id = 665, level = 81, cost = 1, element = 15, effect = {}, SCA = "Fusion"},
+[697] = { name = "Amorphic Spikes", id = 697, level = 98, cost = 4, element = 15, effect = {}, SCA = "Gravitation", SCB = "Transfixion"},
+[538] = { name = "Memento Mori", id = 538, level = 62, cost = 4, element = 1, effect = { ["Magic Attack Boost"] = true, }, },
+[570] = { name = "Blood Drain", id = 570, level = 20, cost = 2, element = 7, effect = { ["Drain"] = true, }, Nuke = true },
+[634] = { name = "Light of Penance", id = 634, level = 58, cost = 5, element = 6, effect = { ["Blind"] = true, ["Bind"] = true, ["Reduce TP"] = true, }, Voidwatch = true, },
+[666] = { name = "Goblin Rush", id = 666, level = 81, cost = 3, element = 15, effect = {}, SCA = "Fusion"},
+[698] = { name = "Wind Breath", id = 698, level = 99, cost = 2, element = 2, effect = {}, Nuke = true },
+[539] = { name = "Terror Touch", id = 539, level = 40, cost = 3, element = 15, effect = { ["Attack Down"] = true, }, SCA = "Compression", SCB = "Reverberation"},
+[603] = { name = "Wild Oats", id = 603, level = 4, cost = 3, element = 15, effect = { ["Vit Down"] = true, }, SCA = "Transfixion"},
+[667] = { name = "Vanity Dive", id = 667, level = 82, cost = 2, element = 15, effect = {}, SCA = "Scission"},
+[699] = { name = "Barbed Crescent", id = 699, level = 99, cost = 2, element = 15, effect = { ["Accuracy Down"] = true, }, SCA = "Distortion", SCB = "Liquifaction"},
+[540] = { name = "Spinal Cleave", id = 540, level = 63, cost = 4, element = 15, effect = {}, SCA = "Scission", SCB = "Detonation"},
+[572] = { name = "Sound Blast", id = 572, level = 32, cost = 1, element = 0, effect = { ["Int Down"] = true, }, },
+[604] = { name = "Bad Breath", id = 604, level = 61, cost = 5, element = 3, effect = { ["Poison"] = true, ["Blind"] = true, ["Silence"] = true, ["Slow"] = true, ["Paralyze"] = true, ["Bind"] = true, ["Gravity"] = true, }, Voidwatch = true, },
+[636] = { name = "Warm-Up", id = 636, level = 68, cost = 4, element = 3, effect = { ["Accuracy Boost"] = true, ["Evasion Boost"] = true, }, },
+[668] = { name = "Magic Barrier", id = 668, level = 82, cost = 3, element = 7, effect = { ["Stoneskin"] = true, }, },
+[700] = { name = "Nat. Meditation", id = 700, level = 99, cost = 6, element = 0, effect = { ["Attack Boost"] = true, }, },
+[541] = { name = "Blood Saber", id = 541, level = 48, cost = 2, element = 7, effect = { ["Drain"] = true, }, Nuke = true },
+[573] = { name = "Feather Tickle", id = 573, level = 64, cost = 3, element = 2, effect = { ["Reduce TP"] = true, }, SCA = "Transfixion"},
+[605] = { name = "Geist Wall", id = 605, level = 46, cost = 3, element = 7, effect = { ["Dispel"] = true, }, },
+[637] = { name = "Firespit", id = 637, level = 68, cost = 5, element = 0, effect = {}, Voidwatch = true, Nuke = true },
+[669] = { name = "Whirl of Rage", id = 669, level = 83, cost = 2, element = 15, effect = { ["Stun"] = true, }, SCA = "Scission", SCB = "Detonation"},
+[701] = { name = "Tem. Upheaval", id = 701, level = 99, cost = 6, element = 2, effect = {}, Nuke = true },
+[542] = { name = "Digest", id = 542, level = 36, cost = 2, element = 7, effect = { ["Drain"] = true, }, Nuke = true },
+[574] = { name = "Feather Barrier", id = 574, level = 56, cost = 2, element = 2, effect = { ["Evasion Boost"] = true, }, },
+[606] = { name = "Awful Eye", id = 606, level = 46, cost = 2, element = 5, effect = { ["Str Down"] = true, }, },
+[638] = { name = "Feather Storm", id = 638, level = 12, cost = 3, element = 15, effect = { ["Poison"] = true, }, SCA = "Transfixion"},
+[670] = { name = "Benthic Typhoon", id = 670, level = 83, cost = 4, element = 15, effect = { ["Defense Down"] = true, }, SCA = "Gravitation", SCB = "Transfixion"},
+[702] = { name = "Rending Deluge", id = 702, level = 99, cost = 6, element = 5, effect = { ["Dispel"] = true, }, Nuke = true },
+[543] = { name = "Mandibular Bite", id = 543, level = 44, cost = 2, element = 15, effect = {}, SCA = "Induration"},
+[575] = { name = "Jettatura", id = 575, level = 48, cost = 4, element = 7, effect = { ["Terror"] = true, }, },
+[671] = { name = "Auroral Drape", id = 671, level = 84, cost = 4, element = 2, effect = { ["Silence"] = true, ["Blind"] = true, }, },
+[703] = { name = "Embalming Earth", id = 703, level = 99, cost = 6, element = 3, effect = { ["Slow"] = true, }, Nuke = true },
+[544] = { name = "Cursed Sphere", id = 544, level = 18, cost = 2, element = 5, effect = { ["Poison"] = true, }, Voidwatch = true, },
+[576] = { name = "Yawn", id = 576, level = 64, cost = 3, element = 6, effect = { ["Sleep"] = true, }, },
+[608] = { name = "Frost Breath", id = 608, level = 66, cost = 3, element = 1, effect = { ["Paralyze"] = true, }, Voidwatch = true, Nuke = true },
+[640] = { name = "Tail Slap", id = 640, level = 69, cost = 4, element = 15, effect = { ["Stun"] = true, }, SCA = "Reverberation"},
+[672] = { name = "Osmosis", id = 672, level = 84, cost = 5, element = 7, effect = { ["Drain"] = true, }, Nuke = true },
+[704] = { name = "Paralyzing Triad", id = 704, level = 99, cost = 6, element = 15, effect = { ["Paralyze"] = true, }, SCA = "Gravitation"},
+[513] = { name = "Venom Shell", id = 513, level = 42, cost = 3, element = 5, effect = { ["Poison"] = true, }, },
+[545] = { name = "Sickle Slash", id = 545, level = 48, cost = 4, element = 15, effect = {}, SCA = "Compression"},
+[577] = { name = "Foot Kick", id = 577, level = 1, cost = 2, element = 15, effect = {}, SCA = "Detonation"},
+[641] = { name = "Hysteric Barrage", id = 641, level = 69, cost = 5, element = 15, effect = {}, SCA = "Detonation"},
+[673] = { name = "Quad. Continuum", id = 673, level = 85, cost = 4, element = 15, effect = {}, SCA = "Gravitation"},
+[705] = { name = "Foul Waters", id = 705, level = 99, cost = 3, element = 5, effect = { ["Drown"] = true, }, Nuke = true },
+[578] = { name = "Wild Carrot", id = 578, level = 30, cost = 3, element = 6, effect = { ["Cure"] = true, }, },
+[610] = { name = "Infrasonics", id = 610, level = 65, cost = 4, element = 1, effect = { ["Evasion Down"] = true, }, Voidwatch = true, },
+[642] = { name = "Amplification", id = 642, level = 70, cost = 3, element = 5, effect = { ["Magic Attack Boost"] = true, }, },
+[674] = { name = "Fantod", id = 674, level = 85, cost = 1, element = 0, effect = { ["Attack Boost"] = true, }, },
+[706] = { name = "Glutinous Dart", id = 706, level = 99, cost = 2, element = 15, effect = {}, SCA = "Fragmentation"},
+[515] = { name = "Maelstrom", id = 515, level = 61, cost = 5, element = 5, effect = { ["Str Down"] = true, }, Voidwatch = true, Abyssea = true, Nuke = true },
+[547] = { name = "Cocoon", id = 547, level = 8, cost = 1, element = 3, effect = { ["Defense Boost"] = true, }, },
+[579] = { name = "Voracious Trunk", id = 579, level = 64, cost = 4, element = 2, effect = { ["Dispel"] = true, }, },
+[611] = { name = "Disseverment", id = 611, level = 72, cost = 5, element = 15, effect = { ["Poison"] = true, }, SCA = "Distortion"},
+[643] = { name = "Cannonball", id = 643, level = 70, cost = 3, element = 15, effect = {}, SCA = "Fusion"},
+[675] = { name = "Thermal Pulse", id = 675, level = 86, cost = 3, element = 0, effect = { ["Blind"] = true, }, Voidwatch = true, Nuke = true },
+[707] = { name = "Retinal Glare", id = 707, level = 99, cost = 5, element = 6, effect = { ["Flash"] = true, }, Nuke = true },
+[548] = { name = "Filamented Hold", id = 548, level = 52, cost = 3, element = 3, effect = { ["Slow"] = true, }, },
+[612] = { name = "Actinic Burst", id = 612, level = 74, cost = 4, element = 6, effect = { ["Flash"] = true, }, Voidwatch = true, },
+[644] = { name = "Mind Blast", id = 644, level = 73, cost = 4, element = 4, effect = { ["Paralyze"] = true, }, Voidwatch = true, Abyssea = true, Nuke = true },
+[708] = { name = "Subduction", id = 708, level = 99, cost = 6, element = 2, effect = { ["Gravity"] = true, }, Nuke = true },
+[517] = { name = "Metallic Body", id = 517, level = 8, cost = 1, element = 3, effect = { ["Stoneskin"] = true, }, },
+[549] = { name = "Pollen", id = 549, level = 1, cost = 1, element = 6, effect = { ["Cure"] = true, }, },
+[581] = { name = "Healing Breeze", id = 581, level = 16, cost = 4, element = 2, effect = { ["Cure"] = true, }, },
+[613] = { name = "Reactor Cool", id = 613, level = 74, cost = 5, element = 1, effect = { ["Defense Boost"] = true, ["Spikes"] = true, }, },
+[645] = { name = "Exuviation", id = 645, level = 75, cost = 4, element = 0, effect = { ["Erase"] = true, }, },
+[677] = { name = "Empty Thrash", id = 677, level = 87, cost = 3, element = 15, effect = {}, SCA = "Compression", SCB = "Scission"},
+[709] = { name = "Thrashing Assault", id = 709, level = 99, cost = 7, element = 15, effect = {}, SCA = "Fusion"},
+[582] = { name = "Chaotic Eye", id = 582, level = 32, cost = 2, element = 2, effect = { ["Silence"] = true, }, },
+[614] = { name = "Saline Coat", id = 614, level = 72, cost = 3, element = 6, effect = { ["Magic Defense Boost"] = true, }, },
+[646] = { name = "Magic Hammer", id = 646, level = 74, cost = 4, element = 6, effect = { ["Aspir"] = true, }, Nuke = true },
+[678] = { name = "Dream Flower", id = 678, level = 87, cost = 3, element = 7, effect = { ["Sleep"] = true, }, },
+[710] = { name = "Erratic Flutter", id = 710, level = 99, cost = 6, element = 2, effect = { ["Haste"] = true, }, },
+[519] = { name = "Screwdriver", id = 519, level = 26, cost = 3, element = 15, effect = {}, SCA = "Transfixion", SCB = "Scission"},
+[551] = { name = "Power Attack", id = 551, level = 4, cost = 1, element = 15, effect = {}, SCA = "Reverberation"},
+[615] = { name = "Plasma Charge", id = 615, level = 75, cost = 5, element = 4, effect = { ["Spikes"] = true, }, },
+[647] = { name = "Zephyr Mantle", id = 647, level = 65, cost = 2, element = 2, effect = { ["Blink"] = true, }, },
+[679] = { name = "Occultation", id = 679, level = 88, cost = 3, element = 2, effect = { ["Blink"] = true, }, },
+[711] = { name = "Restoral", id = 711, level = 99, cost = 7, element = 6, effect = { ["Cure"] = true, }, },
+}
+
+--Copyright © 2015, Anissa
+--All rights reserved.
+
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are met:
+
+-- * Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- * Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+-- * Neither the name of bluGuide nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+--ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+--WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+--DISCLAIMED. IN NO EVENT SHALL ANISSA BE LIABLE FOR ANY
+--DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+--(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+--LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+--ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+--(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/res/traits.lua b/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/res/traits.lua
new file mode 100644
index 0000000..b4d8175
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/res/traits.lua
@@ -0,0 +1,426 @@
+return {
+ ['Accuracy Bonus'] = {
+ name = "Accuracy Bonus",
+ spells = {
+ { name = "Dimensional Death", points = 4, cost = 5, id = 589 },
+ { name = "Frenetic Rip", points = 4, cost = 3, id = 560 },
+ { name = "Disseverment", points = 4, cost = 5, id = 611 },
+ { name = "Vanity Dive", points = 4, cost = 2, id = 667 },
+ { name = "Nat. Meditation", points = 8, cost = 6, id = 700 },
+ { name = "Anvil Lightning", points = 8, cost = 8, id = 721 },
+ },
+ --tiers = { 8, 16, 24, 32 },
+ tiers = { [8] = 10, [16] = 22, [24] = 35, [32] = 48, [40] = 60, [48] = 72 },
+ subs = { ['DNC'] = 8, ['DRG'] = 8, ['RNG'] = 16 },
+ },
+ ['Attack Bonus'] = {
+ name = "Attack Bonus",
+ spells = {
+ { name = "Battle Dance", points = 4, cost = 3, id = 620 },
+ { name = "Uppercut", points = 4, cost = 3, id = 594 },
+ { name = "Death Scissors", points = 4, cost = 5, id = 554 },
+ { name = "Spinal Cleave", points = 4, cost = 4, id = 540 },
+ { name = "Temporal Shift", points = 4, cost = 5, id = 616 },
+ { name = "Thermal Pulse", points = 4, cost = 3, id = 675 },
+ { name = "Embalming Earth", points = 8, cost = 6, id = 703 },
+ { name = "Searing Tempest", points = 8, cost = 8, id = 719 },
+ },
+ tiers = { [8] = 10, [16] = 22, [24] = 35, [32] = 48, [40] = 60, [48] = 72 },
+ subs = { ['WAR'] = 8, ['DRG'] = 8, ['DRK'] = 16 },
+ },
+ ['Auto Refresh'] = {
+ name = "Auto Refresh",
+ spells = {
+ { name = "Stinking Gas", points = 1, cost = 2, id = 537 },
+ { name = "Frightful Roar", points = 2, cost = 3, id = 561 },
+ { name = "Self-Destruct", points = 2, cost = 3, id = 533 },
+ { name = "Cold Wave", points = 1, cost = 1, id = 535 },
+ { name = "Light of Penance", points = 2, cost = 5, id = 634 },
+ { name = "Voracious Trunk", points = 3, cost = 4, id = 579 },
+ { name = "Actinic Burst", points = 4, cost = 4, id = 612 },
+ { name = "Plasma Charge", points = 4, cost = 5, id = 615 },
+ { name = "Winds of Promy.", points = 4, cost = 5, id = 681 },
+ },
+ tiers = { [8] = 1 },
+ subs = { ['PLD'] = 8, ['SMN'] = 8 },
+ },
+ ['Auto Regen'] = {
+ name = "Auto Regen",
+ spells = {
+ { name = "Sheep Song", points = 4, cost = 2, id = 584 },
+ { name = "Healing Breeze", points = 4, cost = 4, id = 581 },
+ { name = "White Wind", points = 4, cost = 5, id = 690 },
+ },
+ tiers = { [8] = 1, [16] = 2, [24] = 3 },
+ tiers = { [8] = 1, [16] = 2, [24] = 3 },
+ subs = { ['WHM'] = 8, ['RUN'] = 8 },
+ },
+ ['Beast Killer'] = {
+ name = "Beast Killer",
+ spells = {
+ { name = "Wild Oats", points = 4, cost = 3, id = 603 },
+ { name = "Sprout Smack", points = 4, cost = 2, id = 597 },
+ { name = "Seedspray", points = 4, cost = 4, id = 650 },
+ { name = "1000 Needles", points = 4, cost = 5, id = 595 },
+ { name = "Nectarous Deluge", points = 8, cost = 6, id = 716 },
+ },
+ tiers = { [8] = "I" },
+ subs = { },
+ },
+ ['Clear Mind'] = {
+ name = "Clear Mind",
+ spells = {
+ { name = "Poison Breath", points = 4, cost = 1, id = 536 },
+ { name = "Sopoforic", points = 4, cost = 4, id = 598 },
+ { name = "Venom Shell", points = 4, cost = 3, id = 513 },
+ { name = "Awful Eye", points = 4, cost = 2, id = 606 },
+ { name = "Filamented Hold", points = 4, cost = 3, id = 548 },
+ { name = "Maelstrom", points = 4, cost = 5, id = 515 },
+ { name = "Feather Tickle", points = 4, cost = 3, id = 573 },
+ { name = "Corrosive Ooze", points = 4, cost = 4, id = 651 },
+ { name = "Sandspray", points = 4, cost = 2, id = 621 },
+ { name = "Warm-Up", points = 4, cost = 4, id = 636 },
+ { name = "Lowing", points = 4, cost = 2, id = 588 },
+ { name = "Mind Blast", points = 4, cost = 4, id = 644 },
+ },
+ tiers = { [8] = 3, [16] = 6, [24] = 9, [32] = 12, [40] = 15 },
+ subs = { ['SMN'] = 24, ['BLM'] = 24, ['SCH'] = 16, ['GEO'] = 16, ['RDM'] = 8, },
+ },
+ ['Conserve MP'] = {
+ name = "Conserve MP",
+ spells = {
+ { name = "Chaotic Eye", points = 4, cost = 2, id = 582 },
+ { name = "Zephyr Mantle", points = 4, cost = 2, id = 647 },
+ { name = "Frost Breath", points = 4, cost = 3, id = 608 },
+ { name = "Firespit", points = 4, cost = 5, id = 637 },
+ { name = "Water Bomb", points = 4, cost = 2, id = 687 },
+ { name = "Retinal Glare", points = 8, cost = 6, id = 707 },
+ },
+ tiers = { [8] = 25, [16] = 28, [24] = 31, [32] = 34, [40] = 37 },
+ subs = { ['SCH'] = 8, ['BLM'] = 16, ['GEO'] = 24, },
+ },
+ ['Counter'] = {
+ name = "Counter",
+ spells = {
+ { name = "Enervation", points = 4, cost = 5, id = 633 },
+ { name = "Asuran Claws", points = 4, cost = 2, id = 653 },
+ { name = "Dark Orb", points = 4, cost = 3, id = 689 },
+ { name = "O. Counterstance", points = 4, cost = 5, id = 696 },
+ },
+ tiers = { [8] = 10, [16] = 12 },
+ subs = { ['MNK'] = 8 },
+ },
+ ['Defense Bonus'] = {
+ name = "Defense Bonus",
+ spells = {
+ { name = "Grand Slam", points = 4, cost = 2, id = 622 },
+ { name = "Terror Touch", points = 4, cost = 3, id = 539 },
+ { name = "Saline Coat", points = 4, cost = 3, id = 614 },
+ { name = "Vertical Cleave", points = 4, cost = 3, id = 617 },
+ { name = "Atra. Libations", points = 8, cost = 6, id = 718 },
+ { name = "Entomb", points = 8, cost = 8, id = 722 },
+ },
+ tiers = { [8] = 10, [16] = 22, [24] = 35, [32] = 48, [40] = 60, [48] = 72 },
+ subs = { ['WAR'] = 8, ['PLD'] = 16 },
+ },
+ ['Double/Triple Attack'] = {
+ name = "Double/Triple Attack",
+ spells = {
+ { name = "Acrid Stream", points = 4, cost = 3, id = 656 },
+ { name = "Demoralizing Roar", points = 4, cost = 4, id = 659 },
+ { name = "Empty Thrash", points = 4, cost = 3, id = 677 },
+ { name = "Heavy Strike", points = 4, cost = 2, id = 688 },
+ { name = "Thrashing Assault", points = 8, cost = 7, id = 709 },
+ },
+ tiers = { [8] = "DA", [16] = "TA" },
+ subs = { ['WAR'] = 8, ['THF'] = 16 },
+ },
+ ['Dual Wield'] = {
+ name = "Dual Wield",
+ spells = {
+ { name = "Animating Wail", points = 4, cost = 5, id = 661 },
+ { name = "Blazing Bound", points = 4, cost = 3, id = 657 },
+ { name = "Quad. Continuum", points = 4, cost = 4, id = 673 },
+ { name = "Delta Thrust", points = 4, cost = 2, id = 682 },
+ { name = "Mortal Ray", points = 4, cost = 4, id = 686 },
+ { name = "Barbed Crescent", points = 4, cost = 2, id = 699 },
+ { name = "Molting Plumage", points = 8, cost = 6, id = 715 },
+ },
+ tiers = { [8] = 10, [16] = 15, [24] = 25, [32] = 30, [40] = 35 },
+ subs = { ['NIN'] = 24, ['DNC'] = 16 },
+ },
+ ['Evasion Bonus'] = {
+ name = "Evasion Bonus",
+ spells = {
+ { name = "Screwdriver", points = 4, cost = 3, id = 519 },
+ { name = "Hysteric Barrage", points = 4, cost = 5, id = 641 },
+ { name = "Occultation", points = 4, cost = 3, id = 679 },
+ { name = "Tem. Upheaval", points = 8, cost = 6, id = 701 },
+ { name = "Silent Storm", points = 8, cost = 8, id = 727 },
+ },
+ tiers = { [8] = 10, [16] = 22, [24] = 35, [32] = 48, [40] = 60 },
+ subs = { ['THF'] = 16, ['DNC'] = 16, ['PUP'] = 8 },
+ },
+ ['Fast Cast'] = {
+ name = "Fast Cast",
+ spells = {
+ { name = "Bad Breath", points = 4, cost = 5, id = 604 },
+ { name = "Sub-Zero Smash", points = 4, cost = 4, id = 654 },
+ { name = "Auroral Drape", points = 4, cost = 4, id = 671 },
+ { name = "Wind Breath", points = 4, cost = 2, id = 698 },
+ { name = "Erratic Flutter", points = 8, cost = 6, id = 710 },
+ },
+ tiers = { [8] = 5, [16] = 10, [24] = 15, [32] = 20, [40] = 25 },
+ subs = { ['RDM'] = 24 },
+ },
+ ['Gilfinder/TH'] = {
+ name = "Gilfinder/TH",
+ spells = {
+ { name = "Charged Whisker", points = 6, cost = 5, id = 680 },
+ { name = "Evryone. Grudge", points = 6, cost = 4, id = 683 },
+ { name = "Amorphic Spikes", points = 6, cost = 4, id = 697 },
+ },
+ tiers = { [8] = "GF", [16] = "TH" },
+ subs = { ['THF'] = 16 },
+ },
+ ['Lizard Killer'] = {
+ name = "Lizard Killer",
+ spells = {
+ { name = "Foot Kick", points = 4, cost = 2, id = 577 },
+ { name = "Claw Cyclone", points = 4, cost = 2, id = 587 },
+ { name = "Ram Charge", points = 4, cost = 4, id = 585 },
+ { name = "Sweeping Gouge", points = 8, cost = 6, id = 717 },
+ },
+ tiers = { [8] = "I" },
+ subs = { ['BST'] = 8 },
+ },
+ ['Magic Attack Bonus'] = {
+ name = "Magic Attack Bonus",
+ spells = {
+ { name = "Cursed Sphere", points = 4, cost = 2, id = 544 },
+ { name = "Sound Blast", points = 4, cost = 1, id = 572 },
+ { name = "Eyes On Me", points = 4, cost = 4, id = 557 },
+ { name = "Memento Mori", points = 4, cost = 4, id = 538 },
+ { name = "Heat Breath", points = 4, cost = 4, id = 591 },
+ { name = "Reactor Cool", points = 4, cost = 5, id = 613 },
+ { name = "Magic Hammer", points = 4, cost = 4, id = 646 },
+ { name = "Dream Flower", points = 4, cost = 3, id = 678 },
+ { name = "Subduction", points = 8, cost = 6, id = 708 },
+ { name = "Spectral Floe", points = 8, cost = 8, id = 720 },
+ },
+ tiers = { [8] = 20, [16] = 24, [24] = 28, [32] = 32, [40] = 36, [48] = 40 },
+ subs = { ['BLM'] = 16, ['RDM'] = 16 },
+ },
+ ['Magic Burst Bonus'] = {
+ name = "Magic Burst Bonus",
+ spells = {
+ { name = "Leafstorm", points = 6, cost = 4, id = 663 },
+ { name = "Cimicine Discharge", points = 6, cost = 3, id = 660 },
+ { name = "Reaving Wind", points = 6, cost = 4, id = 684 },
+ { name = "Rail Cannon", points = 8, cost = 6, id = 712 },
+ },
+ tiers = { [8] = 5, [16] = 7, [24] = 9, [32] = 11, [40] = 13 },
+ subs = { ['BLM'] = 8 },
+ },
+ ['Magic Defense Bonus'] = {
+ name = "Magic Defense Bonus",
+ spells = {
+ { name = "Magnetite Cloud", points = 4, cost = 3, id = 555 },
+ { name = "Ice Break", points = 4, cost = 3, id = 531 },
+ { name = "Osmosis", points = 4, cost = 5, id = 672 },
+ { name = "Rending Deluge", points = 8, cost = 6, id = 702 },
+ { name = "Scouring Spate", points = 8, cost = 8, id = 726 },
+ },
+ tiers = { [8] = 10, [16] = 12, [24] = 14, [32] = 16, [40] = 18 },
+ subs = { ['RUN'] = 16, ['WHM'] = 16, ['RDM'] = 16 },
+ },
+ ['Max HP Boost'] = {
+ name = "Max HP Boost",
+ spells = {
+ { name = "Flying Hip Press", points = 4, cost = 3, id = 629 },
+ { name = "Body Slam", points = 4, cost = 4, id = 564 },
+ { name = "Frypan", points = 4, cost = 3, id = 628 },
+ { name = "Barrier Tusk", points = 4, cost = 3, id = 685 },
+ { name = "Thunder Breath", points = 4, cost = 4, id = 695 },
+ { name = "Glutinous Dart", points = 4, cost = 2, id = 706 },
+ { name = "Restoral", points = 8, cost = 7, id = 711 },
+ },
+ tiers = { [8] = 30, [16] = 60, [24] = 120, [32] = 180, [40] = 240, [48] = 280 },
+ subs = { ['RUN'] = 16, ['MNK'] = 16, ['NIN'] = 16, ['WAR'] = 8, ['PLD'] = 8 },
+ },
+ ['Max MP Boost'] = {
+ name = "Max MP Boost",
+ spells = {
+ { name = "Metallic Body", points = 4, cost = 1, id = 517 },
+ { name = "Mysterious Light", points = 4, cost = 4, id = 534 },
+ { name = "Hecatomb Wave", points = 4, cost = 3, id = 563 },
+ { name = "Magic Barrier", points = 4, cost = 3, id = 668 },
+ { name = "Vapor Spray", points = 4, cost = 3, id = 694 },
+ },
+ tiers = { [8] = 10, [16] = 20, [24] = 40, [32] = 60 },
+ subs = { ['SMN'] = 16, ['GEO'] = 8, ['SCH'] = 8 },
+ },
+ ['Plantoid Killer'] = {
+ name = "Plantoid Killer",
+ spells = {
+ { name = "Power Attack", points = 4, cost = 1, id = 551 },
+ { name = "Mandibular Bite", points = 4, cost = 2, id = 543 },
+ { name = "Spiral Spin", points = 4, cost = 3, id = 652 },
+ },
+ tiers = { [8] = "I" },
+ subs = { },
+ },
+ ['Rapid Shot'] = {
+ name = "Rapid Shot",
+ spells = {
+ { name = "Feather Storm", points = 4, cost = 3, id = 638 },
+ { name = "Jet Stream", points = 4, cost = 4, id = 569 },
+ { name = "Hydro Shot", points = 4, cost = 3, id = 631 },
+ },
+ tiers = { [8] = "I" },
+ subs = { ['RNG'] = 8, ['COR'] = 8 },
+ },
+ ['Resist Silence'] = {
+ name = "Resist Silence",
+ spells = {
+ { name = "Foul Waters", points = 8, cost = 3, id = 705 },
+ },
+ tiers = { [8] = "I" },
+ subs = { ['BRD'] = 8, ['SCH'] = 8 },
+ },
+ ['Resist Gravity'] = {
+ name = "Resist Gravity",
+ spells = {
+ { name = "Feather Barrier", points = 4, cost = 2, id = 574 },
+ { name = "Regurgitation", points = 4, cost = 1, id = 648 },
+ },
+ tiers = { [8] = "I", [16] = "II", [24] = "III" },
+ subs = { ['THF'] = 16 },
+ },
+ ['Resist Sleep'] = {
+ name = "Resist Sleep",
+ spells = {
+ { name = "Pollen", points = 4, cost = 1, id = 549 },
+ { name = "Wild Carrot", points = 4, cost = 3, id = 578 },
+ { name = "Magic Fruit", points = 4, cost = 3, id = 593 },
+ { name = "Yawn", points = 4, cost = 3, id = 576 },
+ { name = "Exuviation", points = 4, cost = 4, id = 645 },
+ },
+ tiers = { [8] = "I", [16] = "II", [24] = "III", [32] = "IV" },
+ subs = { ['PLD'] = 16 },
+ },
+ ['Skillchain Bonus'] = {
+ name = "Skillchain Bonus",
+ spells = {
+ { name = "Goblin Rush", points = 6, cost = 3, id = 666 },
+ { name = "Benthic Typhoon", points = 6, cost = 4, id = 670 },
+ { name = "Quadrastrike", points = 6, cost = 5, id = 693 },
+ { name = "Paralyzing Triad", points = 8, cost = 6, id = 704 },
+ },
+ tiers = { [8] = 8, [16] = 12, [24] = 16, [32] = 20, [40] = 23 },
+ subs = { ['DNC'] = 8 },
+ },
+ ['Store TP'] = {
+ name = "Store TP",
+ spells = {
+ { name = "Sickle Slash", points = 4, cost = 4, id = 545 },
+ { name = "Tail Slap", points = 4, cost = 4, id = 640 },
+ { name = "Fantod", points = 4, cost = 1, id = 674 },
+ { name = "Sudden Lunge", points = 4, cost = 4, id = 692 },
+ { name = "Diffusion Ray", points = 8, cost = 6, id = 713 },
+ },
+ tiers = { [8] = 10, [16] = 15, [24] = 20, [32] = 25, [40] = 30 },
+ subs = { ['SAM'] = 16 },
+ },
+ ['Undead Killer'] = {
+ name = "Undead Killer",
+ spells = {
+ { name = "Bludgeon", points = 4, cost = 2, id = 529 },
+ { name = "Smite of Rage", points = 4, cost = 3, id = 527 },
+ },
+ tiers = { [8] = "I" },
+ subs = { ['PLD'] = 8 },
+ },
+ ['Zanshin'] = {
+ name = "Zanshin",
+ spells = {
+ { name = "Final Sting", points = 4, cost = 1, id = 665 },
+ { name = "Whirl of Rage", points = 4, cost = 2, id = 669 },
+ },
+ tiers = { [8] = 15, [16] = 25, [24] = 35, },
+ subs = { ['SAM'] = 16 },
+ },
+ ['Critical Attack Bonus'] = {
+ name = "Critical Attack Bonus",
+ spells = {
+ { name = "Sinker Drill", points = 8, cost = 6, id = 714 },
+ },
+ tiers = { [8] = 5, [16] = 8, [24] = 11 },
+ subs = { },
+ },
+ ['Inquartata'] = {
+ name = "Inquartata",
+ spells = {
+ { name = "Saurian Slide", points = 8, cost = 7, id = 723 },
+ },
+ tiers = { [8] = 5, [16] = 7, [24] = 9 },
+ subs = { ['RUN'] = 24 },
+ },
+ ['Tenacity'] = {
+ name = "Tenacity",
+ spells = {
+ { name = "Palling Salvo", points = 8, cost = 7, id = 724 },
+ },
+ tiers = { [8] = 5, [16] = 7, [24] = 9 },
+ subs = { ['RUN'] = 24 },
+ },
+ ['Magic Accuracy Bonus'] = {
+ name = "Magic Accuracy Bonus",
+ spells = {
+ { name = "Tenebral Crush", points = 8, cost = 8, id = 728 },
+ },
+ tiers = { [8] = "I", [16] = "II", [24] = "III" },
+ subs = { },
+ },
+ ['Magic Evasion Bonus'] = {
+ name = "Magic Evasion Bonus",
+ spells = {
+ { name = "Blinding Fulgor", points = 8, cost = 8, id = 725 },
+ },
+ tiers = { [8] = "I", [16] = "II", [24] = "III" },
+ subs = { },
+ },
+ ['Resist Slow'] = {
+ name = "Resist Slow",
+ spells = {
+ { name = "Refueling", points = 4, cost = 4, id = 530 },
+ },
+ tiers = { [8] = "I" },
+ subs = { ['PUP'] = 16, ['BST'] = 16, ['SMN'] = 16, ['DNC'] = 8, },
+ },
+}
+--Copyright © 2015, Anissa
+--All rights reserved.
+
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are met:
+
+-- * Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- * Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+-- * Neither the name of bluGuide nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+--ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+--WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+--DISCLAIMED. IN NO EVENT SHALL ANISSA BE LIABLE FOR ANY
+--DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+--(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+--LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+--ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+--(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/ui/buttons.lua b/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/ui/buttons.lua
new file mode 100644
index 0000000..98c52ef
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/ui/buttons.lua
@@ -0,0 +1,119 @@
+local texts = require('texts')
+
+local buttons = {}
+local buttonlist = {}
+
+function buttons.new(label, settings)
+ label = label or ""
+ settings = settings or {}
+
+ settings.flags = settings.flags or {}
+ settings.flags.draggable = false
+
+ local button = {}
+
+ button.left_click = settings.left_click
+ button.hover_on = settings.hover_on
+ button.hover_off = settings.hover_off
+
+ button.text = texts.new(label, settings)
+ button.destroy = function() buttons.destroy(button) end
+
+ setmetatable(button, {__index = function(t, k)
+ if t.text[k] ~= nil then
+ return function(...)
+ return t.text[k](t.text, ...)
+ end
+ end
+ end })
+
+ buttonlist[#buttonlist +1] = button
+ return button
+end
+
+function buttons.destroy(me)
+ for k, v in pairs(buttonlist) do
+ if v == me then
+ buttonlist[k] = nil
+ end
+ end
+ me.text.destroy(me.text)
+end
+
+local mousemoved = true
+local ignorerelease = false
+
+windower.register_event('mouse', function(eventtype, x, y, delta, blocked)
+ if blocked then
+ return
+ end
+
+ -- Mouse drag
+ if eventtype == 0 then
+ mousemoved = true
+
+ for _, button in pairs(buttonlist) do
+ if type(button.hover_on) == "function" and type(button.hover_off) == "function" then
+ if button.text:hover(x, y) then
+ button:hover_on()
+ else
+ button:hover_off()
+ end
+ end
+ end
+
+ -- Mouse left click
+ elseif eventtype == 1 then
+ mousemoved = false
+ for _, button in pairs(buttonlist) do
+ if button.text:hover(x, y) then
+ ignorerelease = true
+ return true
+ end
+ end
+ ignorerelease = false
+
+ -- Mouse left release
+ elseif eventtype == 2 then
+ for _, button in pairs(buttonlist) do
+ if button.text:hover(x, y) and button.text:visible() and not mousemoved and type(button.left_click) == "function" then
+ button:left_click()
+ return true
+ end
+ end
+
+ if ignorerelease then
+ return true
+ end
+ end
+
+ return false
+end)
+
+return buttons
+
+--Copyright © 2015, Anissa
+--All rights reserved.
+
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are met:
+
+-- * Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- * Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+-- * Neither the name of bluGuide nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+--ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+--WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+--DISCLAIMED. IN NO EVENT SHALL ANISSA BE LIABLE FOR ANY
+--DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+--(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+--LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+--ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+--(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/ui/pages.lua b/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/ui/pages.lua
new file mode 100644
index 0000000..8e170b4
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/ui/pages.lua
@@ -0,0 +1,67 @@
+local pgs = {}
+
+function pgs.new(x, y)
+ return setmetatable({ x = x, y = y, boxlist = {} }, {__index = pgs})
+end
+
+function pgs.add(me, newbox)
+ if newbox then
+ me.boxlist[#me.boxlist+1] = newbox
+ end
+ me:update()
+end
+
+function pgs.update(me)
+ for i = 1, #me.boxlist do
+ me.boxlist[i]:update()
+ if i > 1 then
+ me.boxlist[i]:pos(me.boxlist[i - 1]:left(), me.boxlist[i - 1]:bottom() + lineheight)
+ local info = windower.get_windower_settings()
+ if me.boxlist[i]:bottom() > info.ui_y_res - 150 then
+ me.boxlist[i]:pos(me.boxlist[i]:left() + 240, me.y)
+ end
+ else
+ me.boxlist[i]:pos(me.x, me.y)
+ end
+ end
+end
+
+function pgs.show(me)
+ for _, v in pairs(me.boxlist) do
+ v:show()
+ end
+end
+
+function pgs.hide(me)
+ for _, v in pairs(me.boxlist) do
+ v:hide()
+ end
+end
+
+return pgs
+
+--Copyright © 2015, Anissa
+--All rights reserved.
+
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are met:
+
+-- * Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- * Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+-- * Neither the name of bluGuide nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+--ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+--WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+--DISCLAIMED. IN NO EVENT SHALL ANISSA BE LIABLE FOR ANY
+--DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+--(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+--LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+--ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+--(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/ui/spellboxes.lua b/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/ui/spellboxes.lua
new file mode 100644
index 0000000..4f8b910
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/ui/spellboxes.lua
@@ -0,0 +1,157 @@
+local sbx = {}
+buttons = require("ui/buttons")
+texts = require("texts")
+spellbuttons = require("ui/spellbuttons")
+
+
+local default_settings = {
+ text = { size = 10, font = 'Lucida Console' },
+ bg = { alpha = 120, red = 0, green = 0, blue = 0, visible = true },
+ flags = {draggable = false}
+}
+
+local header_settings = {
+ text = { size = 10, font = 'Lucida Console',},
+ bg = { alpha = 200, red = 0, green = 100, blue = 100, visible = false },
+}
+
+function sbx.new(name, filter, namefn)
+ local me = { name = name, x = 0, y = 0, splist = {}, collapsed = false}
+
+ me.bg = texts.new(" ", default_settings)
+
+ me.header = buttons.new(string.format('- %-24s', me.name), header_settings)
+ me.header.bold(false)
+ me.header.color(255, 255, 255)
+ me.header.bg_color(0, 100, 100)
+ me.header.left_click = function() collapse(me) end
+ me.header.hover_on = function() show_bg(me) end
+ me.header.hover_off = function() hide_bg(me) end
+
+ local linenum = 1
+ local totalpoints = 0
+ for k, v in pairs(spellinfo) do
+ if filter(v) and v.level <= setspells.limits.level then
+ local buttonname = nil
+ if namefn ~= nil then
+ buttonname = namefn(v)
+ end
+ buttonname = buttonname or v.name
+ me.splist[#me.splist+1] = spellbuttons.new(string.format(' %-22s %i', buttonname, v.cost), v.id, v.cost, me.x, me.y + (linenum * lineheight))
+ me.splist[#me.splist]:update()
+ linenum = linenum + 1
+ end
+ end
+
+ if #me.splist > 0 then return setmetatable(me, {__index = sbx}) end
+end
+
+function sbx.update(me)
+ local vspace = " "
+ for _, v in pairs(me.splist) do
+ v:update()
+ if not me.collapsed then
+ vspace = vspace.."\n "
+ end
+ end
+
+ me.bg:text(vspace)
+end
+
+function sbx.bottom(me)
+ if not me.collapsed then
+ return me.y + ((1 + #me.splist) * lineheight)
+ else
+ return me.y + lineheight
+ end
+end
+
+function sbx.left(me)
+ return me.x
+end
+
+function sbx.show(me)
+ if not me.collapsed then
+ for _, v in pairs(me.splist) do
+ v:show()
+ end
+ end
+ me.bg:show()
+ me.header.show()
+end
+
+function sbx.pos(me, x, y)
+ me.x = x
+ me.y = y
+ me.bg:pos(x, y)
+ me.header.pos(x, y)
+ local by = 0
+ for i = 1, #me.splist do
+ by = by + lineheight
+ me.splist[i]:pos(x, y+by)
+ end
+end
+
+function sbx.hide(me)
+ for _, v in pairs(me.splist) do
+ v:hide()
+ end
+ me.header.hide()
+ me.bg:hide()
+end
+
+function show_bg(me)
+ me.header.bg_visible(true)
+end
+
+function hide_bg(me)
+ me.header.bg_visible(false)
+end
+
+function collapse(me)
+ me.collapsed = not me.collapsed
+ if me.collapsed then
+ me.header.text:text(string.format('+ %-24s', me.name))
+ me.header.bold(true)
+ for _, v in pairs(me.splist) do
+ v:hide()
+ end
+ me:update()
+ else
+ me.header.text:text(string.format('- %-24s', me.name))
+ me.header.bold(false)
+ for _, v in pairs(me.splist) do
+ v:show()
+ end
+ end
+ update()
+end
+
+return sbx
+
+--Copyright © 2015, Anissa
+--All rights reserved.
+
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are met:
+
+-- * Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- * Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+-- * Neither the name of bluGuide nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+--ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+--WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+--DISCLAIMED. IN NO EVENT SHALL ANISSA BE LIABLE FOR ANY
+--DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+--(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+--LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+--ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+--(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (c) 2015, Anissa
+--All rights reserved. \ No newline at end of file
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/ui/spellbuttons.lua b/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/ui/spellbuttons.lua
new file mode 100644
index 0000000..c853921
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/ui/spellbuttons.lua
@@ -0,0 +1,102 @@
+local spbt = {}
+buttons = require("ui/buttons")
+
+local default_settings = {
+ text = { size = 10, font = 'Lucida Console',},
+ bg = { alpha = 200, red = 0, green = 100, blue = 100, visible = false },
+}
+
+function spbt.new(label, spell, cost, x, y)
+ local me = { spell = spell, cost = cost}
+ me.settings = default_settings
+ me.settings.pos = { x = x, y = y }
+ me.set = {red = 100, green = 255, blue = 100 }
+ me.disabled = true
+ me.button = buttons.new(label, me.settings)
+ me.button.left_click = function() toggle_spell(me) end
+ me.button.hover_on = function() hover_on(me) end
+ me.button.hover_off = function() hover_off(me) end
+ return setmetatable(me, {__index = spbt})
+end
+
+function spbt.update(me)
+ if setspells[me.spell] ~= nil then
+ me.button.color(me.set.red, me.set.green, me.set.blue)
+ me.disabled = false
+ elseif not setspells.learned[me.spell] then
+ me.button.color(150, 150, 150)
+ me.disabled = true
+ elseif setspells.limits.points - setspells.points < me.cost or setspells.slots == setspells.limits.slots then
+ me.button.color(255, 100, 100)
+ me.disabled = true
+ else
+ me.button.color(255, 255, 255)
+ me.disabled = false
+ end
+end
+
+function spbt.show(me)
+ me.button.show()
+end
+
+function spbt.hide(me)
+ me.button.hide()
+end
+
+function spbt.destroy(me)
+ me.button.destroy(me.button)
+ me = nil
+end
+
+function spbt.pos(me, x, y)
+ me.button.pos(x, y)
+end
+
+function hover_on(me)
+ me.button.bg_visible(true)
+end
+
+function hover_off(me)
+ me.button.bg_visible(false)
+end
+
+function spbt.color(me,r,g,b)
+ me.button.color(r,g,b)
+ me.set.red = r
+ me.set.green = g
+ me.set.blue = b
+end
+
+function toggle_spell(me)
+ if not me.disabled then
+ setspells.toggle(me.spell)
+ end
+end
+
+return spbt
+
+--Copyright © 2015, Anissa
+--All rights reserved.
+
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are met:
+
+-- * Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- * Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+-- * Neither the name of bluGuide nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+--ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+--WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+--DISCLAIMED. IN NO EVENT SHALL ANISSA BE LIABLE FOR ANY
+--DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+--(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+--LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+--ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+--(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/ui/traitboxes.lua b/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/ui/traitboxes.lua
new file mode 100644
index 0000000..85edb30
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/bluguide/ui/traitboxes.lua
@@ -0,0 +1,204 @@
+local tbx = {}
+buttons = require("ui/buttons")
+texts = require("texts")
+spellbuttons = require("ui/spellbuttons")
+
+local default_settings = {
+ text = { size = 10, font = 'Lucida Console' },
+ bg = { alpha = 120, red = 0, green = 0, blue = 0, visible = false },
+ flags = {draggable = false}
+}
+
+local header_settings = {
+ text = { size = 10, font = 'Lucida Console',},
+ bg = { alpha = 200, red = 0, green = 100, blue = 100, visible = false },
+}
+
+function tbx.new(trait)
+ local me = { trait = trait, x = 0, y = 0, splist = {}, collapsed = false}
+
+ me.greybox = texts.new("", default_settings)
+ me.greenbox = texts.new("", default_settings)
+ me.greybox:color(190, 190, 190)
+ me.greenbox:color(50, 255, 50)
+ me.greenbox:bg_visible(true)
+ me.greybox:bg_visible(false)
+
+ me.header = buttons.new(string.format('- %-24s', trait.name), header_settings)
+ me.header.bold(false)
+ me.header.color(255, 255, 255)
+ me.header.bg_color(0, 100, 100)
+ me.header.left_click = function() collapsetrait(me) end
+ me.header.hover_on = function() show_bg(me) end
+ me.header.hover_off = function() hide_bg(me) end
+
+ local linenum = 1
+ local totalpoints = 0
+ for k, v in pairs(trait.spells) do
+ if spellinfo[v.id].level <= setspells.limits.level then
+ me.splist[#me.splist+1] = spellbuttons.new(string.format(' %-20s %i %i', v.name, v.cost, v.points), v.id, v.cost, me.x, me.y + (linenum * lineheight))
+ me.splist[#me.splist]:update()
+ linenum = linenum + 1
+ totalpoints = totalpoints + v.points
+ end
+ end
+
+ if totalpoints >= 8 then return setmetatable(me, {__index = tbx}) end
+
+ for _, v in pairs(me.splist) do
+ v:destroy()
+ end
+ return nil
+end
+
+function tbx.update(me)
+ local vspace = " \n "
+ for _, v in pairs(me.splist) do
+ v:update()
+ if not me.collapsed then
+ vspace = vspace.."\n "
+ end
+ end
+
+ local traitpoints = 0
+ for k, v in pairs(me.trait.spells) do
+ if setspells[v.id] then
+ traitpoints = traitpoints + v.points
+ end
+ end
+
+ if traitpoints > 7 and giftexempttraits[me.trait.name] == nil then
+ traitpoints = traitpoints + (8 * setspells.gifts)
+ end
+
+ me.greybox:text(vspace)
+ me.greenbox:text(vspace)
+
+ for v = 8, 48 do
+ if me.trait.tiers[v] ~= nil then
+ if me.trait.name == "Double/Triple Attack" then
+ if v == 8 then
+ if traitpoints == 8 or traitpoints == 12 or sub == 'WAR' then
+ me.greenbox:append(string.format('%s ', me.trait.tiers[v]))
+ me.greybox:append(string.gsub(me.trait.tiers[v], ".", " ").." ")
+ else
+ me.greybox:append(string.format('%s ', me.trait.tiers[v]))
+ me.greenbox:append(string.gsub(me.trait.tiers[v], ".", " ").." ")
+ end
+ elseif traitpoints >= 16 or sub == "THF" then
+ me.greenbox:append(string.format('%s ', me.trait.tiers[v]))
+ me.greybox:append(string.gsub(me.trait.tiers[v], ".", " ").." ")
+ else
+ me.greybox:append(string.format('%s ', me.trait.tiers[v]))
+ me.greenbox:append(string.gsub(me.trait.tiers[v], ".", " ").." ")
+ end
+ elseif v <= traitpoints or (me.trait.subs[sub] and me.trait.subs[sub] >= v) then
+ me.greenbox:append(string.format('%s ', me.trait.tiers[v]))
+ me.greybox:append(string.gsub(me.trait.tiers[v], ".", " ").." ")
+ else
+ me.greybox:append(string.format('%s ', me.trait.tiers[v]))
+ me.greenbox:append(string.gsub(me.trait.tiers[v], ".", " ").." ")
+ end
+ end
+ end
+end
+
+function tbx.bottom(me)
+ if not me.collapsed then
+ return me.y + ((2 + #me.splist) * lineheight)
+ else
+ return me.y + (2 * lineheight)
+ end
+end
+
+function tbx.left(me)
+ return me.x
+end
+
+function tbx.show(me)
+ if not me.collapsed then
+ for _, v in pairs(me.splist) do
+ v:show()
+ end
+ end
+ me.greenbox:show()
+ me.greybox:show()
+ me.header.show()
+end
+
+function tbx.pos(me, x, y)
+ me.x = x
+ me.y = y
+ me.greybox:pos(x, y)
+ me.greenbox:pos(x, y)
+ me.header.pos(x, y)
+ local by = 0
+ for i = 1, #me.splist do
+ by = by + lineheight
+ me.splist[i]:pos(x, y+by)
+ end
+end
+
+function tbx.hide(me)
+ for _, v in pairs(me.splist) do
+ v:hide()
+ end
+ me.greenbox:hide()
+ me.greybox:hide()
+ me.header.hide()
+end
+
+function show_bg(me)
+ me.header.bg_visible(true)
+end
+
+function hide_bg(me)
+ me.header.bg_visible(false)
+end
+
+function collapsetrait(me)
+ me.collapsed = not me.collapsed
+ if me.collapsed then
+ me.header.text:text(string.format('+ %-24s', me.trait.name))
+ me.header.bold(true)
+ for _, v in pairs(me.splist) do
+ v:hide()
+ end
+ me:update()
+ else
+ me.header.text:text(string.format('- %-24s', me.trait.name))
+ me.header.bold(false)
+ for _, v in pairs(me.splist) do
+ v:show()
+ end
+ end
+ update()
+end
+
+return tbx
+
+--Copyright © 2015, Anissa
+--All rights reserved.
+
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are met:
+
+-- * Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- * Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+-- * Neither the name of bluGuide nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+--ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+--WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+--DISCLAIMED. IN NO EVENT SHALL ANISSA BE LIABLE FOR ANY
+--DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+--(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+--LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+--ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+--(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file