summaryrefslogtreecommitdiff
path: root/Data/BuiltIn/Libraries/lua-addons/addons/DistancePlus/DistancePlus.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Data/BuiltIn/Libraries/lua-addons/addons/DistancePlus/DistancePlus.lua')
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/DistancePlus/DistancePlus.lua423
1 files changed, 423 insertions, 0 deletions
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/DistancePlus/DistancePlus.lua b/Data/BuiltIn/Libraries/lua-addons/addons/DistancePlus/DistancePlus.lua
new file mode 100644
index 0000000..760924a
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/DistancePlus/DistancePlus.lua
@@ -0,0 +1,423 @@
+--[[
+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 DistancePlus 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 = 'DistancePlus'
+_addon.author = 'Sammeh'
+_addon.version = '1.3.0.10'
+_addon.command = 'dp'
+
+-- 1.3.0.2 Fixed up nil's per recommendation on submission to Windower
+-- 1.3.0.3 Replaced all tabs for 4 spaces to normalize indentations.
+-- 1.3.0.4 Moving some expensive functions to on-load vs per-render.
+-- 1.3.0.5 Implement config plugin.
+-- 1.3.0.6 Fix ability list on job change.
+-- 1.3.0.7 Implement ranged fix w/o ja_distance
+-- 1.3.0.8 Wasn't refreshing 'self' upon job change. Fixed up spacing.
+-- 1.3.0.9 Fixup MaxDecimal from config plugin addition.
+-- 1.3.0.10 Changed slightly some variable scopes for lower mem usage.
+
+require('tables')
+
+res = require 'resources'
+config = require('config')
+texts = require('texts')
+
+defaults = {}
+defaults.main = {}
+defaults.main.pos = {}
+defaults.main.pos.x = -178
+defaults.main.pos.y = 21
+defaults.main.text = {}
+defaults.main.text.font = 'Arial'
+defaults.main.text.size = 14
+defaults.main.flags = {}
+defaults.main.flags.right = true
+
+defaults.pettxt = {}
+defaults.pettxt.pos = {}
+defaults.pettxt.pos.x = -178
+defaults.pettxt.pos.y = 45
+defaults.pettxt.text = {}
+defaults.pettxt.text.font = 'Arial'
+defaults.pettxt.text.size = 14
+defaults.pettxt.flags = {}
+defaults.pettxt.flags.right = true
+
+
+defaults.abilitytxt = {}
+defaults.abilitytxt.pos = {}
+defaults.abilitytxt.pos.x = -80
+defaults.abilitytxt.pos.y = 45
+defaults.abilitytxt.text = {}
+defaults.abilitytxt.text.font = 'Arial'
+defaults.abilitytxt.text.size = 10
+defaults.abilitytxt.flags = {}
+defaults.abilitytxt.flags.right = true
+
+defaults.heighttxt = {}
+defaults.heighttxt.pos = {}
+defaults.heighttxt.pos.x = -238
+defaults.heighttxt.pos.y = 21
+defaults.heighttxt.text = {}
+defaults.heighttxt.text.font = 'Arial'
+defaults.heighttxt.text.size = 14
+defaults.heighttxt.flags = {}
+defaults.heighttxt.flags.right = true
+
+height_upper_threshold = 8.5
+height_lower_threshold = -7.5
+
+
+settings = config.load(defaults)
+distance = texts.new('${value||%.2f}', settings.main)
+petdistance = texts.new('${value||%.2f}', settings.pettxt)
+abilities = texts.new('${value}', settings.abilitytxt)
+height = texts.new('${value||%.2f}', settings.heighttxt)
+
+
+option = "Default"
+showabilities = false
+showheight = false
+
+function displayabilities(distance,master_pet_distance,s,t)
+ local range_mult = {
+ [2] = 1.55,
+ [3] = 1.490909,
+ [4] = 1.44,
+ [5] = 1.377778,
+ [6] = 1.30,
+ [7] = 1.15,
+ [8] = 1.25,
+ [9] = 1.377778,
+ [10] = 1.45,
+ [11] = 1.454545454545455,
+ [12] = 1.666666666666667,
+ }
+ local list = 'Abilities:\n'
+ if abilitylist then
+ for key,ability in pairs(abilitylist) do
+ ability_en = res.job_abilities[ability].name
+ ability_type = res.job_abilities[ability].type
+ ability_targets = res.job_abilities[ability].targets
+ ability_distance = res.job_abilities[ability].range
+ if distance and ability_en and (ability_type == 'JobAbility' or ability_type == 'PetCommand' or ability_type == 'BloodPactRage' or ability_type == 'BloodPactWard' or ability_type == 'Monster' or ability_type == 'Step') and ability_en ~= "Flourishes II" then
+ if ability_targets.Self ~= true then
+ if distance < (t.model_size + ability_distance * range_mult[ability_distance] + s.model_size) and distance ~= 0 then
+ list = list..'\\cs(0,255,0)'..ability_en..'\\cs(255,255,255)'..'\n'
+ else
+ list = list..'\\cs(255,255,255)'..ability_en..'\n'
+ end
+ --[[ too much crap on screen!!!
+ elseif ability_targets.Self == true and (ability_type == 'Monster' or ability_type == 'PetCommand') and master_pet_distance then
+ if master_pet_distance < (4 + s.model_size + t.model_size) and distance ~= 0 then
+ list = list..'\\cs(0,255,0)'..ability_en..'\\cs(255,255,255)'..'\n'
+ else
+ list = list..'\\cs(255,255,255)'..ability_en..'\n'
+ end
+ --]]
+ end
+ end
+ end
+ end
+ abilities.value = list
+ abilities:visible(showabilities)
+end
+
+function check_job()
+ windower.add_to_chat(8,'*****DP Job Selection:'..self.main_job..'*****')
+ if self.main_job == 'RDM' or self.main_job == 'BLM' or self.main_job == 'GEO' or self.main_job == 'SCH' or self.main_job == 'WHM' or self.main_job == 'BRD' then
+ option = "Magic"
+ windower.add_to_chat(8,'Mode: Magic.')
+ windower.add_to_chat(8,' White = Can not cast.')
+ windower.add_to_chat(8,' Green = Casting Range')
+ MaxDistance = 20
+ elseif self.main_job == 'COR' then
+ windower.add_to_chat(8,'Mode: Gun.')
+ windower.add_to_chat(8,' White = Can not shoot.')
+ windower.add_to_chat(8,' Yellow = Ranged Attack Capable (No Buff)')
+ windower.add_to_chat(8,' Green = Shoots Squarely (Good)')
+ windower.add_to_chat(8,' Blue = True Shot (Best)')
+ option = "Gun"
+ MaxDistance = 25
+ elseif self.main_job == 'RNG' then
+ windower.add_to_chat(8,'RANGER should do //dp Bow, //dp XBow, or //dp Gun')
+ windower.add_to_chat(8,'Mode: Default.')
+ option = "Default"
+ MaxDistance = 25
+ elseif self.main_job == 'NIN' then
+ option = "Ninjutsu"
+ windower.add_to_chat(8,'Mode: Ninjutsu.')
+ windower.add_to_chat(8,' White = Can not cast.')
+ windower.add_to_chat(8,' Green = Casting Range')
+ else
+ windower.add_to_chat(8,'Mode: Default.')
+ option = "Default"
+ MaxDistance = 25
+ end
+end
+
+
+windower.register_event('prerender', function()
+ local t = windower.ffxi.get_mob_by_target('t') or windower.ffxi.get_mob_by_target('st')
+ local s = windower.ffxi.get_mob_by_target('me')
+ if windower.ffxi.get_mob_by_target('pet') then
+ pet = windower.ffxi.get_mob_by_target('pet')
+ else
+ pet = nil
+ end
+ if pet and self.main_job ~= 'DRG' then
+ if self.main_job == 'BST' then
+ local PetMaxDistance = 4
+ local pettargetdistance = PetMaxDistance + pet.model_size + s.model_size
+ if pet.model_size > 1.6 then
+ pettargetdistance = PetMaxDistance + pet.model_size + s.model_size + 0.1
+ end
+ if pet.distance:sqrt() < pettargetdistance then
+ petdistance:color(0,255,0) -- Green
+ else
+ petdistance:color(255,255,255) -- White
+ end
+ --else
+ -- may add some stuff here for SMN
+ end
+ petdistance.value = pet.distance:sqrt()
+ petdistance:visible(pet ~= nil)
+ else
+ petdistance:visible(false)
+ end
+ if t then
+ if pet then
+ displayabilities(t.distance:sqrt(),pet.distance:sqrt(),s,t)
+ else
+ displayabilities(t.distance:sqrt(),nil,s,t)
+ end
+ if t.distance:sqrt() == 0 then
+ distance:color(255,255,255)
+ else
+ if option == 'Default' then
+ distance:color(255,255,255)
+ elseif option == 'Bow' then
+ MaxDistance = 25
+ trueshotmax = s.model_size + t.model_size + 9.5199
+ trueshotmin = s.model_size + t.model_size + 6.02
+ squareshot_far_max = s.model_size + t.model_size + 14.5199
+ squareshot_close_min = s.model_size + t.model_size + 4.62
+ if t.model_size > 1.6 then
+ trueshotmax = trueshotmax + 0.1
+ trueshotmin = trueshotmin + 0.1
+ squareshot_far_max = squareshot_far_max + 0.1
+ squareshot_close_min = squareshot_close_min + 0.1
+ end
+ if t.distance:sqrt() < MaxDistance and (t.distance:sqrt() > squareshot_far_max or t.distance:sqrt() < squareshot_close_min) then
+ distance:color(255,255,0) -- Yellow (No Ranged Boost)
+ elseif (t.distance:sqrt() <= squareshot_far_max and t.distance:sqrt() > trueshotmax) or (t.distance:sqrt() < trueshotmin and t.distance:sqrt() >= squareshot_close_min) then
+ distance:color(0,255,0) -- Green (Square Shot)
+ elseif (t.distance:sqrt() <= trueshotmax and t.distance:sqrt() >= trueshotmin) then
+ distance:color(0,0,255) -- Blue (Strikes True)
+ else
+ distance:color(255,255,255) -- White (Can't Shoot)
+ end
+ elseif option == 'Xbow' then
+ MaxDistance = 25
+ trueshotmax = s.model_size + t.model_size + 8.3999
+ trueshotmin = s.model_size + t.model_size + 5.0007
+ squareshot_far_max = s.model_size + t.model_size + 11.7199
+ squareshot_close_min = s.model_size + t.model_size + 3.6199
+ if t.model_size > 1.6 then
+ trueshotmax = trueshotmax + 0.1
+ trueshotmin = trueshotmin + 0.1
+ squareshot_far_max = squareshot_far_max + 0.1
+ squareshot_close_min = squareshot_close_min + 0.1
+ end
+ if t.distance:sqrt() < MaxDistance and (t.distance:sqrt() > squareshot_far_max or t.distance:sqrt() < squareshot_close_min) then
+ distance:color(255,255,0) -- Yellow (No Ranged Boost)
+ elseif (t.distance:sqrt() <= squareshot_far_max and t.distance:sqrt() > trueshotmax) or (t.distance:sqrt() < trueshotmin and t.distance:sqrt() >= squareshot_close_min) then
+ distance:color(0,255,0) -- Green (Square Shot)
+ elseif (t.distance:sqrt() <= trueshotmax and t.distance:sqrt() >= trueshotmin) then
+ distance:color(0,0,255) -- Blue (Strikes True)
+ else
+ distance:color(255,255,255) -- White (Can't Shoot)
+ end
+ elseif option == 'Gun' then
+ MaxDistance = 25
+ trueshotmax = s.model_size + t.model_size + 4.3189
+ trueshotmin = s.model_size + t.model_size + 3.0209
+ squareshot_far_max = s.model_size + t.model_size + 6.8199
+ squareshot_close_min = s.model_size + t.model_size + 2.2219
+ if t.model_size > 1.6 then
+ trueshotmax = trueshotmax + 0.1
+ trueshotmin = trueshotmin + 0.1
+ squareshot_far_max = squareshot_far_max + 0.1
+ squareshot_close_min = squareshot_close_min + 0.1
+ end
+ if t.distance:sqrt() < MaxDistance and (t.distance:sqrt() > squareshot_far_max or t.distance:sqrt() < squareshot_close_min) then
+ distance:color(255,255,0) -- Yellow (No Ranged Boost)
+ elseif (t.distance:sqrt() <= squareshot_far_max and t.distance:sqrt() > trueshotmax) or (t.distance:sqrt() < trueshotmin and t.distance:sqrt() >= squareshot_close_min) then
+ distance:color(0,255,0) -- Green (Square Shot)
+ elseif (t.distance:sqrt() <= trueshotmax and t.distance:sqrt() >= trueshotmin) then
+ distance:color(0,0,255) -- Blue (Strikes True)
+ else
+ distance:color(255,255,255) -- White (Can't Shoot)
+ end
+ elseif option == 'Magic' then
+ MaxDistance = 20
+ if t.model_size > 2 then
+ MaxDistance = MaxDistance + 0.1
+ elseif math.floor(t.model_size * 10) == 44 then
+ MaxDistance = 20.0666
+ elseif math.floor(t.model_size * 10) == 53 then
+ MaxDistance = 20
+ end
+ targetdistance = MaxDistance + t.model_size + s.model_size
+ if t.distance:sqrt() < targetdistance then
+ distance:color(0,255,0) -- Green
+ else
+ distance:color(255,255,255) -- White can't Cast
+ end
+ elseif option == 'Ninjutsu' then
+ MaxDistance = 16.1
+ if t.model_size > 2 then
+ MaxDistance = MaxDistance + 0.1
+ elseif math.floor(t.model_size * 10) == 44 then
+ MaxDistance = 16.1
+ elseif math.floor(t.model_size * 10) == 53 then
+ MaxDistance = 16.1
+ end
+ targetdistance = MaxDistance + t.model_size + s.model_size
+ if t.distance:sqrt() < targetdistance then
+ distance:color(0,255,0) -- Green
+ else
+ distance:color(255,255,255) -- White can't Cast
+ end
+ else
+ distance:color(255,255,255)
+ end
+ end
+ distance.value = t.distance:sqrt()
+
+ height.value = t.z - s.z
+ if (t.z - s.z) >= height_upper_threshold or (t.z - s.z) <= height_lower_threshold then
+ height:color(0,255,0) -- green
+ else
+ height:color(255,0,0) -- red
+ end
+
+ end
+ distance:visible(t ~= nil)
+ height:visible(t ~= nil and showheight)
+end)
+
+
+windower.register_event('addon command', function(command)
+ if command:lower() == 'help' then
+ windower.add_to_chat(8,'DistancePlus: Valid Modes are //DP <command>:')
+ windower.add_to_chat(8,' Gun, Bow, Xbow, Magic, JA')
+ windower.add_to_chat(8,' MaxDecimal - Expand MaxDecimal for Max Accuracy. DP Calculates to the Thousand')
+ windower.add_to_chat(8,' Default - Reset to Defaults')
+ windower.add_to_chat(8,' Pets - Not a command. If a pet is out another dialog will pop up with distance between you and Pet.')
+ elseif command:lower() == 'gun' then
+ windower.add_to_chat(8,'Mode: Gun.')
+ windower.add_to_chat(8,' White = Can not shoot.')
+ windower.add_to_chat(8,' Yellow = Ranged Attack Capable (No Buff)')
+ windower.add_to_chat(8,' Green = Shoots Squarely (Good)')
+ windower.add_to_chat(8,' Blue = True Shot (Best)')
+ option = "Gun"
+ elseif command:lower() == 'xbow' then
+ option = "Xbow"
+ windower.add_to_chat(8,'Mode: XBOW.')
+ windower.add_to_chat(8,' White = Can not shoot.')
+ windower.add_to_chat(8,' Yellow = Ranged Attack Capable (No Buff)')
+ windower.add_to_chat(8,' Green = Shoots Squarely (Good)')
+ windower.add_to_chat(8,' Blue = True Shot (Best)')
+ elseif command:lower() == 'bow' then
+ option = "Bow"
+ windower.add_to_chat(8,'Mode: BOW.')
+ windower.add_to_chat(8,' White = Can not shoot.')
+ windower.add_to_chat(8,' Yellow = Ranged Attack Capable (No Buff)')
+ windower.add_to_chat(8,' Green = Shoots Squarely (Good)')
+ windower.add_to_chat(8,' Blue = True Shot (Best)')
+ elseif command:lower() == 'magic' then
+ option = "Magic"
+ windower.add_to_chat(8,'Mode: Magic.')
+ windower.add_to_chat(8,' White = Can not cast.')
+ windower.add_to_chat(8,' Green = Casting Range')
+ elseif command:lower() == 'ninjutsu' then
+ option = "Ninjutsu"
+ windower.add_to_chat(8,'Mode: Ninjutsu.')
+ windower.add_to_chat(8,' White = Can not cast.')
+ windower.add_to_chat(8,' Green = Casting Range')
+ elseif command:lower() == 'default' then
+ windower.add_to_chat(8,'Mode: Default.')
+ option = "Default"
+ MaxDistance = 25
+ distance:visible(false)
+ distance = texts.new('${value||%.2f}', settings.main)
+ elseif command:lower() == 'maxdecimal' then
+ distance:visible(false)
+ distance = texts.new('${value||%.12f}', settings.main)
+ elseif command:lower() == 'abilitylist' or command:lower() == 'ja' then
+ if showabilities then
+ showabilities = false
+ else
+ windower.add_to_chat(8,'Mode: JA.')
+ showabilities = true
+ displayabilities()
+ end
+ elseif command:lower() == 'height' then
+ showheight = true
+ end
+end)
+
+windower.register_event('job change', function()
+ coroutine.sleep(2) -- sleeping because jobchange too fast doesn't show new abilities
+ self = windower.ffxi.get_player()
+ check_job()
+ abilitylist = windower.ffxi.get_abilities().job_abilities
+ abilities:visible(false)
+ abilities.value = ""
+ displayabilities()
+end)
+
+windower.register_event('load', function()
+ if windower.ffxi.get_player() then
+ coroutine.sleep(2) -- sleeping because jobchange too fast doesn't show new abilities
+ self = windower.ffxi.get_player()
+ check_job()
+ abilitylist = windower.ffxi.get_abilities().job_abilities
+ displayabilities()
+ end
+end)
+
+
+windower.register_event('login', function()
+ coroutine.sleep(2) -- sleeping because jobchange too fast doesn't show new abilities
+ self = windower.ffxi.get_player()
+ check_job()
+ abilitylist = windower.ffxi.get_abilities().job_abilities
+ displayabilities()
+end)