summaryrefslogtreecommitdiff
path: root/Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper
diff options
context:
space:
mode:
Diffstat (limited to 'Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper')
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper/Alliance.lua498
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper/blackboard.lua150
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper/data/settings.xml21
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper/readme.md94
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper/shoutHelper.lua172
5 files changed, 935 insertions, 0 deletions
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper/Alliance.lua b/Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper/Alliance.lua
new file mode 100644
index 0000000..7cb5606
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper/Alliance.lua
@@ -0,0 +1,498 @@
+--[[
+Copyright (c) 2013, Chiara De Acetis
+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 <addon name> 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 <your name> 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.
+]]
+
+-- Object Alliance
+--[[
+Concept
+list = {party1={} party2={} party3={}}
+list = {party1={WHM="ppl" PLD="ppl" WAR="ppl" DD="ppl" } party2={} party3={}}
+if there's "add war" and only DD slots are left, it has to put the war in the DD slot
+]]
+local Alliance = {}
+
+require 'logger'
+local files = require 'files'
+
+local JobList = T{
+ 'blm',
+ 'blu',
+ 'brd',
+ 'bst',
+ 'dnc',
+ 'drg',
+ 'drk',
+ 'whm',
+ 'rdm',
+ 'pup',
+ 'cor',
+ 'pld',
+ 'geo',
+ 'run',
+ 'sch',
+ 'mnk',
+ 'thf',
+ 'war',
+ 'sam',
+ 'nin',
+ 'smn',
+ 'rng',
+ 'dd',
+ 'support',
+ 'heal',
+ 'tank'
+}
+
+local DDlist = T{
+ 'blm',
+ 'blu',
+ 'bst',
+ 'dnc',
+ 'drg',
+ 'drk',
+ 'pup',
+ 'pld',
+ 'run',
+ 'mnk',
+ 'thf',
+ 'war',
+ 'sam',
+ 'nin',
+ 'smn',
+ 'rng'
+}
+
+local SupportList = T{
+ 'cor',
+ 'brd',
+ 'geo'
+}
+
+local HealList = T{
+ 'whm',
+ 'rdm',
+ 'sch'
+}
+
+--create and empty alliance
+function Alliance:new()
+ local ally = {
+ party1 = {},
+ party2 = {},
+ party3 = {}
+ }
+ setmetatable(ally, self)
+ self.__index = self
+ return ally
+end
+
+--sets one or multiple job in party1
+function Alliance:setParty1(jobs)
+ local length = 0
+ local numJob = #self.party1
+ if numJob == 6 then
+ return
+ end
+ if #jobs <= (6 - numJob) then
+ length = #jobs
+ else
+ length = (6 - numJob)
+ end
+ j = 1
+ for i = 1, length do
+ job = jobs[i]:lower()
+ if JobList:contains(job) then
+ self.party1[j+numJob] = {job}
+ j = j+1
+ end
+ end
+end
+
+--sets one or multiple job in the party2
+function Alliance:setParty2(jobs)
+ local length = 0
+ local numJob = #self.party2
+ if numJob == 6 then
+ return
+ end
+ if #jobs <= (6 - numJob) then
+ length = #jobs
+ else
+ length = (6 - numJob)
+ end
+ j = 1
+ for i = 1, length do
+ job = jobs[i]:lower()
+ if JobList:contains(job) then
+ self.party2[j+numJob] = {job}
+ j = j+1
+ end
+ end
+end
+
+--sets one or multiple job in party3
+function Alliance:setParty3(jobs)
+ local length = 0
+ local numJob = #self.party3
+ if numJob == 6 then
+ return
+ end
+ if #jobs <= (6 - numJob) then
+ length = #jobs
+ else
+ length = (6 - numJob)
+ end
+ j = 1
+ for i = 1, length do
+ job = jobs[i]:lower()
+ if JobList:contains(job) then
+ self.party3[j+numJob] = {job}
+ j = j+1
+ end
+ end
+end
+
+--delete a job inside the ally
+function Alliance:deleteJob(job, party) --it rescale the player list too
+ job = job:lower()
+ -- party slot not given
+ if (party == nil ) then
+ party = self:findJob(job)
+ if party[1] == 1 then
+ table.remove(self.party1, party[2])
+ elseif party[1] == 2 then
+ table.remove(self.party2, party[2])
+ elseif party[1] == 3 then
+ table.remove(self.party3, party[2])
+ end
+ else -- party given
+ if (party == "party1") then
+ for i=1, #self.party1 do
+ local slot = self.party1[i]
+ local v = slot[1]
+ if(v == job) then
+ table.remove(self.party1, i)
+ return
+ end
+ end
+ elseif (party == "party2") then
+ for i=1, #self.party2 do
+ local slot = self.party2[i]
+ local v = slot[1]
+ if(v == job) then
+ table.remove(self.party2, i)
+ return
+ end
+ end
+ elseif (party == "party3") then
+ for i=1, #self.party3 do
+ if(v == job) then
+ table.remove(self.party3, i)
+ return
+ end
+ end
+ end
+ end
+end
+
+--returns the first party table that contains the given job
+function Alliance:findJob(job)
+ local party = nil
+ for i=1, #self.party1 do
+ local slot = self.party1[i]
+ local v = slot[1]
+ if( v == job ) then
+ party = {1, i}
+ return party
+ end
+ end
+ if(party == nil) then
+ for i=1, #self.party2 do
+ local slot = self.party2[i]
+ local v = slot[1]
+ if( v == job ) then
+ party = {2, i}
+ return party
+ end
+ end
+ end
+ if(party == nil) then
+ for i=1, #self.party3 do
+ local slot = self.party3[i]
+ local v = slot[1]
+ if( v == job ) then
+ party = {3, i}
+ return party
+ end
+ end
+ end
+ if(party == nil ) then
+ error(job..' not found')
+ return
+ end
+end
+
+--returns the string representing the party
+function Alliance:printAlly()
+ local s = ''
+ if(#self.party1 > 0) then
+ s = s..'\nPARTY 1\n'
+ for i=1, #self.party1 do
+ slot = self.party1[i]
+ job = slot[1]
+ name = slot[2]
+ s = s..'['..job:upper()..']'
+ if name then
+ s = s..' '..name
+ end
+ s = s..' \n'
+ end
+ end
+ if(#self.party2 > 0) then
+ s = s..'\nPARTY 2\n'
+ for i=1, #self.party2 do
+ slot = self.party2[i]
+ job = slot[1]
+ name = slot[2]
+ s = s..'['..job:upper()..']'
+ if name then
+ s = s..' '..name
+ end
+ s = s..' \n'
+ end
+ end
+ if(#self.party3 > 0) then
+ s = s..'\nPARTY 3\n'
+ for i=1, #self.party3 do
+ slot = self.party3[i]
+ job = slot[1]
+ name = slot[2]
+ s = s..'['..job:upper()..']'
+ if name then
+ s = s..' '..name
+ end
+ s = s..' \n'
+ end
+ end
+ return s
+end
+
+--delete the ally
+function Alliance:deleteAll()
+ self.party1 = {}
+ self.party2 = {}
+ self.party3 = {}
+end
+
+--delete the party
+function Alliance:delete(party)
+ if party == "party1" then
+ self.party1 = {}
+ elseif party == "party2" then
+ self.party2 = {}
+ elseif party == "party3" then
+ self.party3 = {}
+ end
+end
+
+--sets one player to the first <job> slot free
+function Alliance:addPlayer(job, name)
+ local party = self:findFreeSlot(job)
+ local rightJob = true
+ --if party is null the job wasn't found
+ --it means the there isn't the given job (example: one's looking for mnk and only slot DD are left)
+ if not party and job then
+ if DDlist:contains(job:lower()) then
+ party = self:findFreeSlot('dd')
+ rightJob = false
+ elseif SupportList:contains(job:lower())then
+ party = self:findFreeSlot('support')
+ rightJob = false
+ elseif HealList:contains(job:lower()) then
+ party = self:findFreeSlot('heal')
+ rightJob = false
+ end
+ if not party then
+ error("Can't find a free slot")
+ return
+ end
+ end
+ local pos = party[2]
+ if (party[1] == 1) then
+ local slot = self.party1[pos]
+ if rightJob then
+ self.party1[pos] = {slot[1], name}
+ else
+ self.party1[pos] = {job:lower(), name}
+ end
+ end
+ if (party[1] == 2) then
+ local slot = self.party2[pos]
+ if rightJob then
+ self.party2[pos] = {slot[1], name}
+ else
+ self.party2[pos] = {job, name}
+ end
+ end
+ if (party[1] == 3) then
+ local slot = self.party3[pos]
+ if rightJob then
+ self.party3[pos] = {slot[1], name}
+ else
+ self.party3[pos] = {job, name}
+ end
+ end
+ --if I'm here it means it the given job is missing
+end
+
+--find the first free party slot (job is optional)
+function Alliance:findFreeSlot(job)
+ local party = nil --first position is pt, second is party slot
+ for i=1, #self.party1 do
+ local slot = self.party1[i]
+ local jobName = slot[1]
+ local name = slot[2]
+ if ((not job) and name == nil) then
+ --no job given, I'm looking for the first free slot in party
+ party = {1, i}
+ return party
+ elseif (job and name == nil) then
+ --the job is given, I'm looking for the first free slot for the given job
+ job = job:lower()
+ if(jobName == job)then
+ party = {1, i}
+ return party
+ end
+ end
+ end
+ for i=1, #self.party2 do
+ local slot = self.party2[i]
+ local jobName = slot[1]
+ local name = slot[2]
+ if ((not job) and name == nil) then
+ --no job given, I'm looking for the first free slot in party
+ party = {2, i}
+ return party
+ elseif (job and name == nil) then
+ --the job is given, I'm looking for the first free slot for the given job
+ job = job:lower()
+ if(jobName == job)then
+ party = {2, i}
+ return party
+ end
+ end
+ end
+ for i=1, #self.party3 do
+ local slot = self.party3[i]
+ local jobName = slot[1]
+ local name = slot[2]
+ if ((not job) and name == nil) then
+ --no job given, I'm looking for the first free slot in party
+ party = {3, i}
+ return party
+ elseif (job and name == nil) then
+ --the job is given, I'm looking for the first free slot for the given job
+ job = job:lower()
+ if(jobName == job)then
+ party = {3, i}
+ return party
+ end
+ end
+ end
+end
+
+-- removes the player from alliance list (i remove the player in i-esim position)
+function Alliance:removePlayer(name)
+ name = name:lower()
+ --looks through the pts
+ local v = ''
+ local slot = nil
+ for k=1, #self.party1 do
+ slot = self.party1[k]
+ v = slot[2]
+ if(v~= nil)then
+ v = v:lower()
+ if v == name then
+ self.party1[k] = {slot[1]}
+ return
+ end
+ end
+ end
+ for k=1, #self.party2 do
+ slot = self.party2[k]
+ v = slot[2]
+ if(v~= nil)then
+ v = v:lower()
+ if v == name then
+ self.party2[k] = {slot[1]}
+ return
+ end
+ end
+ end
+ for k=1, #self.party3 do
+ slot = self.party3[k]
+ v = slot[2]
+ if(v~= nil)then
+ v = v:lower()
+ if v == name then
+ self.party3[k] = {slot[1]}
+ return
+ end
+ end
+ end
+end
+
+--save the current ally in an xml file
+function Alliance:save()
+ --TODO (now creates only a string xml)
+ local a = '<?xml version="1.0" ?>\n'
+ a = a..'<alliance>\n'
+ a = a..'\t<party1>\n'
+ for i=1, #self.party1 do
+ slot = self.party1[i]
+ job = slot[1]
+ a = a..'\t\t<job'..i..'>'..job:upper()..'</job'..i..'>\n'
+ end
+ a = a..'\t</party1>\n'
+ a = a..'\t<party2>\n'
+ for i=1, #self.party2 do
+ slot = self.party2[i]
+ job = slot[1]
+ a = a..'\t\t<job'..i..'>'..job:upper()..'</job'..i..'>\n'
+ end
+ a = a..'\t</party2>\n'
+ a = a..'\t<party3>\n'
+ for i=1, #self.party3 do
+ slot = self.party3[i]
+ job = slot[1]
+ a = a..'\t\t<job'..i..'>'..job:upper()..'</job'..i..'>\n'
+ end
+ a = a..'\t</party3>\n'
+ a = a..'</alliance>\n'
+end
+
+return Alliance
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper/blackboard.lua b/Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper/blackboard.lua
new file mode 100644
index 0000000..998e7bb
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper/blackboard.lua
@@ -0,0 +1,150 @@
+--[[
+Copyright (c) 2013, Chiara De Acetis
+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 <addon name> 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 <your name> 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.
+]]
+
+-- Blackboard object (wrapper to text box)
+-- Manage the textbox alliance list
+local Alliance = require 'Alliance'
+require 'logger'
+
+local Blackboard = {
+visible = true,
+settings = nil,
+tb_name = 'shoutHelper',
+allyName = 'Alliance'
+}
+
+function Blackboard:new(settings)
+ local o = {}
+ self.settings = settings
+ o = {ally = Alliance:new()}
+ setmetatable(o, self)
+ self.__index = self
+ windower.text.create(self.tb_name)
+ windower.text.set_bg_color(self.tb_name, self.settings.bgtransparency, 30, 30, 30)
+ windower.text.set_color(self.tb_name, 255, 225, 225, 225)
+ windower.text.set_location(self.tb_name, self.settings.posx, self.settings.posy)
+ windower.text.set_visibility(self.tb_name, self.visible)
+ windower.text.set_bg_visibility(self.tb_name, 1)
+ return o
+end
+
+function Blackboard:set_position(posx, posy)
+ self.settings.posx = posx
+ self.settings.posy = posy
+ windower.text.set_location(self.tb_name, posx, posy)
+end
+
+function Blackboard:show()
+ self.visible = true
+ windower.text.set_visibility(self.tb_name, true)
+end
+
+function Blackboard:hide()
+ self.visible = false
+ windower.text.set_visibility(self.tb_name, false)
+end
+
+function Blackboard:set(party, jobs)
+ --need to check here party format string
+ local ptBool = (party == ('party1')) or (party == ('pt1')) or (party == ('1'))
+ if(ptBool) then
+ self.ally:setParty1(jobs)
+ end
+ ptBool = (party == ('party2')) or (party == ('pt2')) or (party == ('2'))
+ if(ptBool) then
+ self.ally:setParty2(jobs)
+ end
+ ptBool = (party == ('party3')) or (party == ('pt3')) or (party == ('3'))
+ if(ptBool) then
+ self.ally:setParty3(jobs)
+ end
+ self:update()
+end
+
+function Blackboard:deleteJob(job, party)
+ local ptBool = (party == ('party1')) or (party == ('pt1')) or (party == ('1'))
+ local party = nil
+ if(ptBool) then
+ party = 'party1'
+ end
+ ptBool = (party == ('party2')) or (party == ('pt2')) or (party == ('2'))
+ if(ptBool) then
+ party = 'party2'
+ end
+ ptBool = (party == ('party3')) or (party == ('pt3')) or (party == ('3'))
+ if(ptBool) then
+ party = 'party3'
+ end
+ self.ally:deleteJob(job, party)
+ self:update()
+end
+
+function Blackboard:addPlayer(job, name)
+ self.ally:addPlayer(job, name)
+ self:update()
+end
+
+function Blackboard:rmPlayer(name)
+ self.ally:removePlayer(name)
+ self:update()
+end
+
+function Blackboard:update()
+ local string = self.ally:printAlly()
+ windower.text.set_text(self.tb_name, self.allyName..'\n'..string)
+ if (not self.visible) then
+ self:show()
+ end
+end
+
+function Blackboard:reset(party)
+ if not party then
+ self.ally:deleteAll()
+ else
+ local ptBool = (party == ('party1')) or (party == ('pt1')) or (party == ('1'))
+ if(ptBool) then
+ party = 'party1'
+ end
+ ptBool = (party == ('party2')) or (party == ('pt2')) or (party == ('2'))
+ if(ptBool) then
+ party = 'party2'
+ end
+ ptBool = (party == ('party3')) or (party == ('pt3')) or (party == ('3'))
+ if(ptBool) then
+ party = 'party3'
+ end
+ self.ally:delete(party)
+ end
+ self:update()
+end
+
+function Blackboard:destroy()
+windower.text.delete(self.tb_name)
+end
+
+return Blackboard
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper/data/settings.xml b/Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper/data/settings.xml
new file mode 100644
index 0000000..133f21c
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper/data/settings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" ?>
+<settings>
+ <!--
+ This file controls the settings for the Scoreboard plugin.
+ Settings in the <global> section apply to all characters
+
+ The available settings are:
+ posX - x coordinate for position
+ posY - y coordinate for position
+ bgTransparency - Transparency level for the background. 0-255 range
+ -->
+ <global>
+ <posX>300</posX>
+ <posY>140</posY>
+ <bgTransparency>200</bgTransparency>
+ </global>
+
+ <!--
+ You may also override specific settings on a per-character basis here.
+ -->
+</settings>
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper/readme.md b/Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper/readme.md
new file mode 100644
index 0000000..5a6f0b2
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper/readme.md
@@ -0,0 +1,94 @@
+Author: Jandel
+Version: 0.2
+Addon to help manage alliance while shouting.
+Abbreviation: //sh
+
+This addon allows you to create a virtual alliance list in game. Why using the old piece of paper
+or switching to a file .txt to manage your alliance shout?
+This addon will allow you to create a job list and assign a player to the wanted job
+Example:
+Alliance
+PARTY 1
+[JOB]
+[JOB]
+[JOB]
+...
+
+PARTY 2
+[JOB]
+[JOB]
+[JOB]
+...
+
+PARTY 3
+[JOB]
+[JOB]
+[JOB]
+...
+
+All in-game commands are prefixed with "//sh", for example: "//sh help".
+
+Command list:
+* HELP
+ Displays the help text
+
+* POS <x> <y>
+ Positions the alliance list to the given coordinates
+
+* Clear [<party>]
+ Clears the alliance list if no <party> is given. It will clear all the jobs
+ only on <party> list if <party> is given.
+ <party> formats are 'party1', 'pt1', '1', 'party2', 'pt2', '2',
+ 'party3', 'pt3', '3'
+
+* SET <party> <job1> <job2> ...
+ Insert the <job> into the <party> list.
+ Both <party> and <job> are required.
+ Support <party> formats are 'party1', 'pt1', '1', 'party2', 'pt2', '2',
+ 'party3', 'pt3', '3'
+ Support <job> formats are all FFXI short jobs name ('whm', 'rdm', 'mnk', ...)
+ and 'healer', 'support', 'dd'
+ Examples:
+ //sh set pt1 mnk Adds a mnk to the party1 job list
+ //sh set party2 mnk healer dd Adds a mnk, an healer and a dd to the party2 job list
+ //sh set 3 healer support brd dd dd dd Adds the six jobs to the party3 job list
+
+* DEL [<party>] <job>
+ removes a job from the job list. <party> is optional and if is not given, the first
+ occurrence of the given job will be deleted
+
+* VISIBLE
+ Toggles the visibility of the scoreboard. Data will continue to
+ accumulate even while it is hidden.
+
+* ADD [<job>] <player>
+ Adds the <player> to the first free slot.
+ If <job> is given then the <player> will be added to the first free slot of
+ that corresponding <job>
+ Examples:
+ //sh add mnk Grievesk Put the name Grievesk near the first free MNK slot in
+ the three party
+ //sh add Jandel Put the name Jandel near the first job slot that is free
+
+* RM <player>
+ Removes the <player> from the party list
+
+* SAVE <name>
+ This function is not implemented yet
+
+* LOAD <name>
+ This function is not implemented yet
+
+The settings file, located in addons/shoutHelper/data/settings.xml, contains
+additional configuration options:
+* posX - x coordinate for position
+* posY - y coordinate for position
+* bgTransparency - Transparency level for the background. 0-255 range
+
+Caveats:
+
+* This addon is still in development. Please report any issues or feedback to
+ to me (Jandel on Ragnarok) on FFXIAH or Guildwork.
+
+Thanks to Grievesk for encouraging me to write this addon :)
+
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper/shoutHelper.lua b/Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper/shoutHelper.lua
new file mode 100644
index 0000000..c4ccc3e
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/shoutHelper/shoutHelper.lua
@@ -0,0 +1,172 @@
+--[[
+Copyright (c) 2013, Chiara De Acetis
+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 <addon name> 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 <your name> 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.
+]]
+
+
+_addon.name = 'shoutHelper'
+_addon.version = '0.2'
+_addon.commands = {'shouthelper','sh'}
+_addon.author = 'Jandel'
+
+require 'tables'
+require 'strings'
+require 'logger'
+--local file = require 'files'
+local Blackboard = require 'blackboard'
+local lavagna = nil
+local config = require 'config'
+
+-- Memo: //lua load shoutHelper
+
+-- Constructor
+windower.register_event('load',function ()
+ settings = config.load({
+ posx = 300,
+ posy = 140,
+ bgtransparency = 200,
+ font = 'courier',
+ fontsize = 10
+ })
+ lavagna = Blackboard:new(settings)
+end)
+
+-- Handle addon args
+windower.register_event('addon command',function (...)
+ local params = {...};
+
+ if #params < 1 then
+ return
+ end
+ if params[1] then
+ if params[1]:lower() == "help" then
+ --Idea of helper
+ local color = '204' -- !!there is a function in scoreboard for add_to_chat
+ windower.add_to_chat(color, 'SH: ShoutHelper v' .. _addon.version .. '. Author: Jandel')
+ windower.add_to_chat(color, 'SH: sh help : Shows help message')
+ windower.add_to_chat(color, 'SH: sh pos <x> <y> : Positions the list')
+ windower.add_to_chat(color, 'SH: sh clear [<party>]: Reset list (if no party is given, it will reset all alliance).')
+ --the following two line are commented because there's no function implemented
+ --windower.add_to_chat(color, 'SH: sh save <filename> : Save alliance settings. If the file already exists it will overwrite it.')
+ --windower.add_to_chat(color, 'SH: sh load <filename> : Load the <filename> alliance settings.')
+ windower.add_to_chat(color, "SH: sh set <party> <job1> <job2> ... : Add a job to the party. pt1 is for first party, pt2 and pt3 for second and third party. ".."Won\'t add jobs if the party list is full")
+ windower.add_to_chat(color, 'SH: sh add [<job>] <player> : assign the name of that player to the corrisponding job.')
+ windower.add_to_chat(color, 'SH: sh del [<party>] <job> : deletes the job from the alliance list. Party from wich delet it is optional')
+ windower.add_to_chat(color, 'SH: sh rm <player>: removes the player from the alliance list')
+ windower.add_to_chat(color, 'SH: sh visible : shows/hide the current alliance list')
+ elseif params[1]:lower() == "pos" then
+ if params[3] then
+ local posx, posy = tonumber(params[2]), tonumber(params[3])
+ lavagna:set_position(posx, posy)
+ --TODO check this if to save settings
+ if posx ~= settings.posx or posy ~= settings.posy then
+ settings.posx = posx
+ settings.posy = posy
+ settings:save()
+ end
+ end
+ elseif params[1]:lower() == "clear" then
+ lavagna:reset(params[2])
+ --elseif params[1]:lower() == "save" then
+ --if --[[the filename isn't legit(emplty string too)]] --then
+ --error('Invalid name')
+ --return
+ --end
+ -- TODO function that create&save xml
+ --log('This function needs to be implemented')
+ --elseif params[1]:lower() == "load" then
+ --if --[[the filename isn't legit(emplty string too)] --then
+ --error('Invalid name')
+ --return
+ --end
+ -- TODO function that load xml
+ --log('This function needs to be implemented')
+ elseif params[1]:lower() == "set" then --add jobs to party list
+ local party = params[2]
+ if not party then
+ error('No input given')
+ return
+ end
+ if not params[3] then
+ error('no jobs given')
+ return
+ end
+ local jobs = {}
+ local j = 1
+ for i=3, #params do
+ jobs[j] = params[i]
+ j = j + 1
+ end
+ lavagna:set(party, jobs)
+ elseif params[1]:lower() == "add" then --add playername to party
+ local job = params[2]
+ if not job then
+ error('No input given')
+ return
+ end
+ local name = params[3]
+ if not name then
+ name = job
+ job = nil
+ end
+ lavagna:addPlayer(job, name)
+ elseif params[1]:lower() == "del" then --delete job
+ local party = params[2]
+ if not party then
+ error('No input given')
+ return
+ end
+ local job = nil
+ if (party and params[3]) then
+ job = params[3]
+ else
+ job = party
+ end
+ lavagna:deleteJob(job, party)
+ elseif params[1]:lower() == "rm" then --remove player
+ if not params[2] then
+ error('Missing player name')
+ return
+ end
+ lavagna:rmPlayer(params[2])
+ elseif params[1]:lower() == "visible" then
+ if(lavagna.visible) then
+ lavagna:hide()
+ else
+ lavagna:show()
+ end
+ else --I don't know if leave the error message or "do nothing" (deleting else) in case the command isn't legit
+ error('Invalid command')
+ end
+ end
+end)
+
+
+
+-- Destructor
+windower.register_event('unload',function ()
+ lavagna:destroy()
+end) \ No newline at end of file