summaryrefslogtreecommitdiff
path: root/Data/BuiltIn/Libraries/lua-addons/addons/JobChange/jobchange.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Data/BuiltIn/Libraries/lua-addons/addons/JobChange/jobchange.lua')
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/JobChange/jobchange.lua207
1 files changed, 207 insertions, 0 deletions
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/JobChange/jobchange.lua b/Data/BuiltIn/Libraries/lua-addons/addons/JobChange/jobchange.lua
new file mode 100644
index 0000000..e5068ba
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/JobChange/jobchange.lua
@@ -0,0 +1,207 @@
+--[[
+Copyright © 2017, Sammeh of Quetzalcoatl
+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 JobChange 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 Sammeh 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 = 'Job Change'
+_addon.author = 'Sammeh; Akaden'
+_addon.version = '1.0.4'
+_addon.command = 'jc'
+
+-- 1.0.1 first release
+-- 1.0.2 added 'reset' command to simply reset to existing job. Changes sub job to a random starting job and back.
+-- 1.0.3 Code clean-up
+-- 1.0.4 Added /jc main/sub command and organized solve for fewest changes.
+
+require('tables')
+packets = require('packets')
+res = require ('resources')
+
+local temp_jobs = T { 'NIN', 'DNC', 'WAR', 'MNK', 'WHM', 'BLM', 'RDM', 'THF' }
+local mog_zones = S { 'Selbina', 'Mhaura', 'Tavnazian Safehold', 'Nashmau', 'Rabao', 'Kazham', 'Norg', 'Walk of Echoes [P1]', 'Walk of Echoes [P2]' }
+local moogles = S { 'Moogle', 'Nomad Moogle', 'Green Thumb Moogle', 'Pilgrim Moogle' }
+
+local log = function(msg)
+ windower.add_to_chat(4,'JobChange: '..msg)
+end
+
+local jobchange = function(job, main)
+ local packet = packets.new('outgoing', 0x100, {
+ [(main and 'Main' or 'Sub')..' Job'] = job,
+ })
+ packets.inject(packet)
+end
+
+local find_conflict = function(job_name, p)
+ if p.main_job == job_name:upper() then
+ return 'main'
+ end
+ if p.sub_job == job_name:upper() then
+ return 'sub'
+ end
+end
+
+local find_temp_job = function(p)
+ for _, job_name in ipairs(temp_jobs) do
+ if not find_conflict(job_name, p) and p.jobs[job_name:upper()] > 0 then
+ for index,value in pairs(res.jobs) do
+ if value.ens == job_name then
+ return index
+ end
+ end
+ end
+ end
+end
+
+local find_job = function(job,p)
+ if job == nil then return nil end
+ local jobLevel = p.jobs[job:upper()]
+ for index,value in pairs(res.jobs) do
+ if value.ens:lower() == job and jobLevel > 0 then
+ return index
+ end
+ end
+end
+
+local find_job_change_npc = function()
+ local info = windower.ffxi.get_info()
+ if not (info.mog_house or mog_zones:contains(res.zones[info.zone].english)) then
+ log('Not in a zone with a Change NPC')
+ return
+ end
+
+ for _, v in pairs(windower.ffxi.get_mob_array()) do
+ if v.distance < 36 and v.valid_target and moogles:contains(v.name) then
+ return v
+ end
+ end
+end
+
+windower.register_event('addon command', function(command, ...)
+ local p = windower.ffxi.get_player()
+ local args = L{...}
+ local job = ''
+ if args[1] then
+ job = args[1]:lower()
+ end
+ local main = nil
+ local sub = nil
+ if command:lower() == 'main' then
+ main = job
+ if main and main:upper() == p.main_job then main = nil end
+ elseif command:lower() == 'sub' then
+ sub = job
+ if sub and sub:upper() == p.sub_job then main = nil end
+ elseif command:lower() == 'reset' then
+ log('Resetting Job')
+ sub = p.sub_job:lower()
+ elseif command:contains('/') or command:contains('\\') then
+ command = command:gsub('\\','/')
+ local js = command:split('/')
+ main = (js[1] ~= '' and js[1] or nil)
+ sub = (js[2] ~= '' and js[2] or nil)
+ -- remove identicals.
+ if main and main:upper() == p.main_job then main = nil end
+ if sub and sub:upper() == p.sub_job then sub = nil end
+ elseif command ~= nil and command ~= '' then
+ main = command:lower()
+ if main and main:upper() == p.main_job then main = nil end
+ else
+ log('Syntax: //jc main|sub JOB -- Chnages main or sub to target JOB')
+ log('Syntax: //jc main/sub -- Changes main and sub')
+ log('Syntax: //jc reset -- Resets Current Job')
+ return
+ end
+
+ local changes = T{}
+
+ local main_id = find_job(main, p)
+ if main ~= nil and main_id == nil then
+ log('Could not change main job to to '..main:upper()..' ---Mistype|NotUnlocked')
+ return
+ end
+ local sub_id = find_job(sub, p)
+ if sub ~= nil and sub_id == nil then
+ log('Could not change sub job to to '..sub:upper()..' ---Mistype|NotUnlocked')
+ return
+ end
+
+ if main_id == nil and sub_id == nil then
+ log('No change required.')
+ return
+ end
+
+ if main_id ~= nil and main:upper() == p.sub_job then
+ if sub_id ~= nil and sub:upper() == p.main_job then
+ changes:append({job_id=find_temp_job(p), is_conflict=true, is_main=false})
+ changes:append({job_id=main_id, is_main=true})
+ changes:append({job_id=sub_id, is_main=false})
+ else
+ if sub_id ~= nil then
+ changes:append({job_id=sub_id, is_main=false})
+ else
+ changes:append({job_id=find_temp_job(p), is_conflict=true, is_main=false})
+ end
+ changes:append({job_id=main_id, is_main=true})
+ end
+ elseif sub_id ~= nil and sub:upper() == p.main_job then
+ if main_id ~= nil then
+ changes:append({job_id=main_id, is_main=true})
+ else
+ changes:append({job_id=find_temp_job(p), is_conflict=true, is_main=true})
+ end
+ changes:append({job_id=sub_id, is_main=false})
+ else
+ if main_id ~= nil then
+ if main:upper() == p.main_job then
+ changes:append({job_id=find_temp_job(p), is_conflict=true, is_main=true})
+ end
+ changes:append({job_id=main_id, is_main=true})
+ end
+ if sub_id ~= nil then
+ if sub:upper() == p.sub_job then
+ changes:append({job_id=find_temp_job(p), is_conflict=true, is_main=false})
+ end
+ changes:append({job_id=sub_id, is_main=false})
+ end
+ end
+
+ local npc = find_job_change_npc()
+ if npc then
+ for _, change in ipairs(changes) do
+ if change.is_conflict then
+ log('Conflict with '..(change.is_main and 'main' or 'sub')..' job. Changing to: '..res.jobs[change.job_id].ens)
+ else
+ log('Changing '..(change.is_main and 'main' or 'sub')..' job to: '..res.jobs[change.job_id].ens)
+ end
+ jobchange(change.job_id, change.is_main)
+
+ coroutine.sleep(0.5)
+ end
+ else
+ log('Not close enough to a Moogle!')
+ end
+end)