From e39389e159302fe262877db6ddfc9e2658549392 Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 28 Apr 2020 18:45:40 -0500 Subject: [PATCH 1/3] Migrated JobChange addon from v4 --- jobchange/README.md | 17 ++++ jobchange/jobchange.lua | 212 ++++++++++++++++++++++++++++++++++++++++ jobchange/manifest.xml | 16 +++ 3 files changed, 245 insertions(+) create mode 100644 jobchange/README.md create mode 100644 jobchange/jobchange.lua create mode 100644 jobchange/manifest.xml diff --git a/jobchange/README.md b/jobchange/README.md new file mode 100644 index 00000000..62f64a85 --- /dev/null +++ b/jobchange/README.md @@ -0,0 +1,17 @@ +**Author:** Sammeh
+**v5 Migration:** Akaden
+**Version:** 1.0.0.0
+**Date:** April 28, 2020
+ +# Job Change # + +* Change jobs with a single text command +* Reset job ability timers by changing jobs quickly. + +---- + +**Main Command:** `/jc` + +#### Commands: #### +* 1: /jc main/sub - Changes main and sub jobs to the given values. Also accepts "/jc /sub" and even "/jc main/" or "/jc main". (EG: "/jc cor/nin", "/jc /blm", "/jc war") +* 2: /jc reset - Resets job ability timers by changing sub job to another job and then back to your current sub job. diff --git a/jobchange/jobchange.lua b/jobchange/jobchange.lua new file mode 100644 index 00000000..8bb248da --- /dev/null +++ b/jobchange/jobchange.lua @@ -0,0 +1,212 @@ +--[[ +Copyright © 2020, JobChange +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 THE AUTHOR 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. +]] + +string = require('string.ext') +table = require('table') +packets = require('packets') +client_data = require ('client_data') +entities = require('entities') +player = require('player') +set = require('set') +list = require('list') +world = require('world') +chat = require('core.chat') +command = require('core.command')settings = require('settings') + +local defaults = { + log_to_chat = false, +} +options = settings.load(defaults) + +local temp_jobs = list(13, 19, 1, 2, 3, 4, 5) +local mog_zones = set('Selbina', 'Mhaura', 'Tavnazian Safehold', 'Nashmau', 'Rabao', 'Kazham', 'Norg') +local moogles = set('Moogle', 'Nomad Moogle', 'Green Thumb Moogle') + +local log = function(msg) + if options.log_to_chat then + chat.add_text('JobChange: '..msg) + end +end + +local jobchange = function(job, main) + main = main and "main_job_id" or "sub_job_id" + packets.outgoing[0x100]:inject({ + [main] = job, + }) +end + +local find_job = function(job) + if job == nil or job == '' then + return nil + end + + for index,value in pairs(client_data.jobs) do + local jobLevel = player.job_levels[index] + if value.abbreviation:lower() == job:lower() and jobLevel > 0 then + return index + end + end +end + +local find_job_change_npc = function() + if not (world.mog_house or mog_zones:contains(client_data.zones[world.zone_id].english)) then + log('Not in a zone with a Change NPC') + return + end + + local closest_moogle, closest_distance + for i, v in pairs(entities.npcs) do + if v ~= nil and not v.flags.hidden and v.distance < 36 and moogles:contains(v.name) then + if closest_distance == nil or v.distance < closest_distance then + closest_moogle = v + closest_distance = v.distance + end + end + end + return closest_moogle +end + +local find_conflict = function(job) + if player.main_job_id == job then + return "main" + end + if player.sub_job_id == job then + return "sub" + end +end + +local find_temp_job = function() + for _, i in pairs(temp_jobs) do -- check temp jobs (nin, dnc, war, mnk, whm, blm, rdm, thf) + if not find_conflict(i) then + return i + end + end +end + +local solve_jobchange = function(mainid, subid) + if mainid == nil and subid == nil then + log("No change required.") + + return + end + local changes = list() + + if mainid ~= nil and mainid == player.sub_job_id then + if subid ~= nil and subid == player.main_job_id then + changes:add({job=find_temp_job(), conflict=true, main=false}) + changes:add({job=mainid, main=true}) + changes:add({job=subid, main=false}) + else + if subid ~= nil then + changes:add({job=subid, main=false}) + else + changes:add({job=find_temp_job(), conflict=true, main=false}) + end + changes:add({job=mainid, main=true}) + end + elseif subid ~= nil and subid == player.main_job_id then + if mainid ~= nil then + changes:add({job=mainid, main=true}) + else + changes:add({job=find_temp_job(), conflict=true, main=true}) + end + changes:add({job=subid, main=false}) + else + if mainid ~= nil then + if mainid == player.main_job_id then + changes:add({job=find_temp_job(), conflict=true, main=true}) + end + changes:add({job=mainid, main=true}) + end + if subid ~= nil then + if subid == player.sub_job_id then + changes:add({job=find_temp_job(), conflict=true, main=false}) + end + changes:add({job=subid, main=false}) + end + end + + local npc = find_job_change_npc() + if npc then + for i, change in ipairs(changes) do + if change.conflict then + log("Conflict with "..(change.main and 'main' or 'sub')..' job. Changing to: '..client_data.jobs[change.job].abbreviation) + else + log("Changing "..(change.main and 'main' or 'sub').." job to: "..client_data.jobs[change.job].abbreviation) + end + jobchange(change.job, change.main) + + coroutine.sleep(0.5) + end + else + log("Not close enough to a Moogle!") + end +end + +local handle_jobchange = function(main, sub) + local mainid = find_job(main) + local subid = find_job(sub) + + if main ~= '' and mainid == nil then + log("Could not change main job to "..main:upper().." ---Mistype|NotUnlocked") + return + end + local subid = find_job(sub, p) + if sub ~= '' and subid == nil then + log("Could not change sub job to "..sub:upper().." ---Mistype|NotUnlocked") + return + end + + if mainid == player.main_job_id then + mainid = nil + end + if subid == player.sub_job_id then + subid = nil + end + + coroutine.schedule(solve_jobchange, 0, mainid, subid) +end + +local handle_reset = function() + coroutine.schedule(solve_jobchange,0, nil, player.sub_job_id) +end + +local handle_command = function(command) + if command:lower() == 'reset' then + handle_reset() + elseif command:contains('/') then + mainsub = command:split('/') + handle_jobchange(table.unpack(mainsub)) + else + -- assume main job. + handle_jobchange(command, '') + end +end + +local jc = command.new('jc') +jc:register(handle_command, '') \ No newline at end of file diff --git a/jobchange/manifest.xml b/jobchange/manifest.xml new file mode 100644 index 00000000..851b24f1 --- /dev/null +++ b/jobchange/manifest.xml @@ -0,0 +1,16 @@ + + jobchange + 1.0.0.0 + addon + + packets + client_data + entities + player + set + list + world + string + settings + + From 63b5d5e9222843d367f475770fe0961c08b17299 Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 28 Apr 2020 19:30:49 -0500 Subject: [PATCH 2/3] Organized and updated for code standards and guidelines. --- jobchange/jobchange.lua | 143 ++++++++++++++++++++-------------------- 1 file changed, 73 insertions(+), 70 deletions(-) diff --git a/jobchange/jobchange.lua b/jobchange/jobchange.lua index 8bb248da..266b28e8 100644 --- a/jobchange/jobchange.lua +++ b/jobchange/jobchange.lua @@ -28,20 +28,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. string = require('string.ext') table = require('table') +set = require('set') +list = require('list') + packets = require('packets') client_data = require ('client_data') + entities = require('entities') player = require('player') -set = require('set') -list = require('list') world = require('world') + chat = require('core.chat') command = require('core.command')settings = require('settings') local defaults = { log_to_chat = false, } -options = settings.load(defaults) +local options = settings.load(defaults) local temp_jobs = list(13, 19, 1, 2, 3, 4, 5) local mog_zones = set('Selbina', 'Mhaura', 'Tavnazian Safehold', 'Nashmau', 'Rabao', 'Kazham', 'Norg') @@ -53,21 +56,21 @@ local log = function(msg) end end -local jobchange = function(job, main) - main = main and "main_job_id" or "sub_job_id" +local jobchange = function(job_id, is_main) + local field_name = is_main and 'main_job_id' or 'sub_job_id' packets.outgoing[0x100]:inject({ - [main] = job, + [field_name] = job_id, }) end -local find_job = function(job) - if job == nil or job == '' then +local find_job = function(job_name) + if job_name == nil or job_name == '' then return nil end - for index,value in pairs(client_data.jobs) do - local jobLevel = player.job_levels[index] - if value.abbreviation:lower() == job:lower() and jobLevel > 0 then + for index, value in pairs(client_data.jobs) do + local job_level = player.job_levels[index] + if value.abbreviation:lower() == job_name:lower() and job_level > 0 then return index end end @@ -80,116 +83,116 @@ local find_job_change_npc = function() end local closest_moogle, closest_distance - for i, v in pairs(entities.npcs) do - if v ~= nil and not v.flags.hidden and v.distance < 36 and moogles:contains(v.name) then - if closest_distance == nil or v.distance < closest_distance then - closest_moogle = v - closest_distance = v.distance + for _, npc in pairs(entities.npcs) do + if npc ~= nil and not npc.flags.hidden and npc.distance < 36 and moogles:contains(npc.name) then + if closest_distance == nil or npc.distance < closest_distance then + closest_moogle = npc + closest_distance = npc.distance end end end return closest_moogle end -local find_conflict = function(job) - if player.main_job_id == job then - return "main" +local find_conflict = function(job_id) + if player.main_job_id == job_id then + return true end - if player.sub_job_id == job then - return "sub" + if player.sub_job_id == job_id then + return true end end local find_temp_job = function() - for _, i in pairs(temp_jobs) do -- check temp jobs (nin, dnc, war, mnk, whm, blm, rdm, thf) - if not find_conflict(i) then - return i + for _, job_id in pairs(temp_jobs) do -- check temp jobs (nin, dnc, war, mnk, whm, blm, rdm, thf) + if not find_conflict(job_id) then + return job_id end end end -local solve_jobchange = function(mainid, subid) - if mainid == nil and subid == nil then - log("No change required.") +local solve_jobchange = function(main_id, sub_id) + if main_id == nil and sub_id == nil then + log('No change required.') return end local changes = list() - if mainid ~= nil and mainid == player.sub_job_id then - if subid ~= nil and subid == player.main_job_id then - changes:add({job=find_temp_job(), conflict=true, main=false}) - changes:add({job=mainid, main=true}) - changes:add({job=subid, main=false}) + if main_id ~= nil and main_id == player.sub_job_id then + if sub_id ~= nil and sub_id == player.main_job_id then + changes:add({job_id=find_temp_job(), is_conflict=true, is_main=false}) + changes:add({job_id=main_id, is_main=true}) + changes:add({job_id=sub_id, is_main=false}) else - if subid ~= nil then - changes:add({job=subid, main=false}) + if sub_id ~= nil then + changes:add({job_id=sub_id, is_main=false}) else - changes:add({job=find_temp_job(), conflict=true, main=false}) + changes:add({job_id=find_temp_job(), is_conflict=true, is_main=false}) end - changes:add({job=mainid, main=true}) + changes:add({job_id=main_id, is_main=true}) end - elseif subid ~= nil and subid == player.main_job_id then - if mainid ~= nil then - changes:add({job=mainid, main=true}) + elseif sub_id ~= nil and sub_id == player.main_job_id then + if main_id ~= nil then + changes:add({job_id=main_id, is_main=true}) else - changes:add({job=find_temp_job(), conflict=true, main=true}) + changes:add({job_id=find_temp_job(), is_conflict=true, is_main=true}) end - changes:add({job=subid, main=false}) + changes:add({job_id=sub_id, is_main=false}) else - if mainid ~= nil then - if mainid == player.main_job_id then - changes:add({job=find_temp_job(), conflict=true, main=true}) + if main_id ~= nil then + if main_id == player.main_job_id then + changes:add({job_id=find_temp_job(), is_conflict=true, is_main=true}) end - changes:add({job=mainid, main=true}) + changes:add({job_id=main_id, is_main=true}) end - if subid ~= nil then - if subid == player.sub_job_id then - changes:add({job=find_temp_job(), conflict=true, main=false}) + if sub_id ~= nil then + if sub_id == player.sub_job_id then + changes:add({job_id=find_temp_job(), is_conflict=true, is_main=false}) end - changes:add({job=subid, main=false}) + changes:add({job_id=sub_id, is_main=false}) end end local npc = find_job_change_npc() if npc then - for i, change in ipairs(changes) do - if change.conflict then - log("Conflict with "..(change.main and 'main' or 'sub')..' job. Changing to: '..client_data.jobs[change.job].abbreviation) + for _, change in ipairs(changes) do + if change.is_conflict then + log('Conflict with '..(change.is_main and 'main' or 'sub')..' job. Changing to: '..client_data.jobs[change.job_id].abbreviation) else - log("Changing "..(change.main and 'main' or 'sub').." job to: "..client_data.jobs[change.job].abbreviation) + log('Changing '..(change.is_main and 'main' or 'sub')..' job to: '..client_data.jobs[change.job_id].abbreviation) end - jobchange(change.job, change.main) + jobchange(change.job_id, change.is_main) coroutine.sleep(0.5) end else - log("Not close enough to a Moogle!") + log('Not close enough to a Moogle!') end end -local handle_jobchange = function(main, sub) - local mainid = find_job(main) - local subid = find_job(sub) +local handle_jobchange = function(main_name, sub_name) + local main_id = find_job(main_name) + local sub_id = find_job(sub_name) - if main ~= '' and mainid == nil then - log("Could not change main job to "..main:upper().." ---Mistype|NotUnlocked") + if main_name ~= '' and main_id == nil then + log('Could not change main job to '..main_name:upper()..' ---Mistype|NotUnlocked') return end - local subid = find_job(sub, p) - if sub ~= '' and subid == nil then - log("Could not change sub job to "..sub:upper().." ---Mistype|NotUnlocked") + local sub_id = find_job(sub_name, p) + if sub_name ~= '' and sub_id == nil then + log('Could not change sub job to '..sub_name:upper()..' ---Mistype|NotUnlocked') return end - if mainid == player.main_job_id then - mainid = nil + if main_id == player.main_job_id then + main_id = nil end - if subid == player.sub_job_id then - subid = nil + if sub_id == player.sub_job_id then + sub_id = nil end - coroutine.schedule(solve_jobchange, 0, mainid, subid) + coroutine.schedule(solve_jobchange, 0, main_id, sub_id) end local handle_reset = function() @@ -200,8 +203,8 @@ local handle_command = function(command) if command:lower() == 'reset' then handle_reset() elseif command:contains('/') then - mainsub = command:split('/') - handle_jobchange(table.unpack(mainsub)) + local main_sub = command:split('/') + handle_jobchange(table.unpack(main_sub)) else -- assume main job. handle_jobchange(command, '') From 5e866b4eadc7bbeaa194cc8b99c317767f9b1679 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 29 Apr 2020 21:47:35 -0500 Subject: [PATCH 3/3] Fix for if the player doesn't have nin or dnc unlocked when /jc reset --- jobchange/jobchange.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jobchange/jobchange.lua b/jobchange/jobchange.lua index 266b28e8..218cdd2b 100644 --- a/jobchange/jobchange.lua +++ b/jobchange/jobchange.lua @@ -105,7 +105,7 @@ end local find_temp_job = function() for _, job_id in pairs(temp_jobs) do -- check temp jobs (nin, dnc, war, mnk, whm, blm, rdm, thf) - if not find_conflict(job_id) then + if not find_conflict(job_id) and player.job_levels[job_id] > 0 then return job_id end end