diff options
Diffstat (limited to 'Data/BuiltIn/Libraries/lua-addons/addons/pointwatch')
5 files changed, 790 insertions, 0 deletions
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/pointwatch/FIXING POINTWATCH.txt b/Data/BuiltIn/Libraries/lua-addons/addons/pointwatch/FIXING POINTWATCH.txt new file mode 100644 index 0000000..61bb39c --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/pointwatch/FIXING POINTWATCH.txt @@ -0,0 +1,35 @@ +Updating Message IDs: A guide + + Pointwatch relies on zone-based message IDs for some of its features. +These IDs change on a regular basis. Fortunately, their positions relative +to one another rarely change, which means that most of the time you only +have to change one number and the entire zone will work again. + +I have written this guide to explain how to change those numbers in the +hopes that members of the community will maintain pointwatch's message- +dependent features. + +Method 1 - POLUtils +1) Download POLUtils (if you don't already have it) from the google code site +2) Install it and run it +3) Click "FFXI Data Browser" +4) Go to the "Dialog Tables" menu and select the zone you are interested in +5) Wait for it to load, then export the entire table as xml +6) Open the xml file up in a text editor, like Notepad or Notepad++. +7) Control-F for the key phrase. +8) The associated message ID is the offset value for that zone. + +Method 2 - message_printing +1) Load Pointwatch (//lua l pointwatch) +2) Enable message printing (//pw message_printing) +3) Generate the key message (for instance, by resting in Abyssea) +4) This will print message IDs to your windower console. They appear in the + order they were generated. Select the one that you want (for instance, + the second one when you rest in Abyssea). +5) That value is your offset. +6) Disable message printing (//pw message_printing) + +Both methods: +* Open message_ids.lua +* Find the zone and replace the zone.offset value with the correct value. +* Submit your file to Github, so that everyone can have a working copy! diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/pointwatch/ReadMe.txt b/Data/BuiltIn/Libraries/lua-addons/addons/pointwatch/ReadMe.txt new file mode 100644 index 0000000..b3f1964 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/pointwatch/ReadMe.txt @@ -0,0 +1,79 @@ +=== PointWatch === +Allows you to monitor your XP/CP gains and keep track of the Dynamis time limit. + +Abbreviation: //pw + +Text Box Commands: +* show - Shows the text box. +* hide - Hides the text box. +* pos <X> <Y> - Moves the upper left corner of the text box to the coordinates X/Y. +* font <font name> - Changes the text's font. +* size <point size> - Changes the size of the text's font. +* color <R> <G> <B> - Changes the text color. Numbers should be between 0 and 255. +* bg_color <R> <G> <B> - Changes the background color. Numbers should be between 0 and 255. +* bg_transparency <number> - Changes the background transparency. Number should be between 0 and 1 +** pos_x, pos_y, pad, transparency, alpha, and bg_alpha are also valid commands and are documented in the texts library. + +Other Commands: +* message_printing - See FIXING POINTWATCH.txt in this directory for a full explanation. + + + +Strings Options: +The two strings options in settings.xml are loaded as Lua code and run accordingly, +so you can do things like adjust numbers and format things as you wish. The default +is designed to look somewhat like the Attainment plugin, but you are free to change +it however you wish. Be aware that the code will give very unhelpful errors when it fails. + +Here are the available values: +* xp.current = Current Experience Points (number from 0 to 55,999 XP) +* xp.tnl = Number of Experience Points in your current level (number from 500 to 56,000) +* xp.rate = Current XP gain rate per hour. This is calculated over a 10 minute window and requires at least two gains within the window. +* xp.total = Total Experience Points gained since the last time the addon was loaded (number) + +* lp.current = Current Experience Points (number from 0 to 55,999 XP) +* lp.tnl = Similar to a "To Next Level", but this value is always 10,000 because that's always the number of Limit Points per merit point. +* lp.number_of_merits = Number of merit points you have. +* lp.maximum_merits = Maximum number of merits you can store. + +* cp.current = Current Capacity Points (number from 0 to 29,999 CP) +* cp.rate = Current CP gain rate per hour. This is calculated over a 10 minute window and requires at least two gains within the window. +* cp.total = Total Capacity Points gained since the last time the addon was loaded (number) +* cp.tnjp = Similar to a "To Next Level", but this value is always 30,000 because that's always the number of CPs per job point. +* cp.number_of_job_points = Number of job points you currently have on your current job. + +* sparks.current = Current number of RoE Sparks (number between 0 and 50,000) +* sparks.maximum = Maximum number of RoE Sparks (always 50,000) + +* accolades.current = Current number of Unity Accolades (number between 0 and 50,000) +* accolades.maximum = Maximum number of Unity Accolades (always 50,000) + +* dynamis.KIs = Series of Xs and Os indicating whether or not you have the 5 KIs. +* dynamis.entry_time = Your Dynamis entry time, in seconds. -- If the addon is loaded in dynamis, this will be the time of addon load. +* dynamis.time_limit = Your current Dynamis time limit, in seconds. -- If the addon is loaded in dynamis, you will need to gain a KI for this to be accurate. +* dynamis.time_remaining = The current dynamis time remaining, in seconds. -- Will not be accurate if the addon is loaded in dynamis. + +* abyssea.amber = Amber light estimation +* abyssea.azure = Azure light estimation +* abyssea.ruby = Ruby light estimation +* abyssea.pearlescent = Pearlescent light estimation +* abyssea.golden = Gold light estimation +* abyssea.silvery = Silvery light estimation +* abyssea.ebon = Ebon light estimation +* abyssea.last_time = The last time you got a time message, in seconds. -- Not implemented +* abyssea.time_limit = The current abyssea time remaining, in seconds. -- Approximate to the minute, not fully implemented +* abyssea.time_remaining = The current abyssea time remaining, in seconds. -- Approximate to the minute, not fully implemented + + + +Version History: +0.150811 - Changed job_points from a char to a short. +0.150201 - Added Unity Accolades. +0.141111 - Adjusted Pointwatch to account for a recent packet change. +0.141101 - Reversed my versioning scheme, adjusted the limit point and experience point calculations slightly. +0.101214 - Made pointwatch hide itself while zoning. +0.062014 - Added lp.maximum_merits. +0.050214 - Fixed the Dynamis clock. Added Abyssea lights. +0.042314 - Addition of strings system +0.042014 - Addition of strings system +0.041214 - Initial commit
\ No newline at end of file diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/pointwatch/message_ids.lua b/Data/BuiltIn/Libraries/lua-addons/addons/pointwatch/message_ids.lua new file mode 100644 index 0000000..3cd91ff --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/pointwatch/message_ids.lua @@ -0,0 +1,189 @@ +--Copyright (c) 2014, Byrthnoth +--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. + +-- Offset messages: +-- Abyssea's offset message is the one that reports your Pearlescent, Ebon, Gold, and Silvery light when you /heal. +-- Do a Control-F for Pearlescent to find it if using the POLUtils method. It should be the first result. + +-- SEE THE "FIXING POINTWATCH" FILE IN THIS FOLDER FOR INSTRUCTIONS ON HOW TO FIX POINTWATCH. + +local messages = { + z15 = { + name = 'Abyssea - Konschtat', + offset = 7315, + pearl_ebon_gold_silvery = 0, + azure_ruby_amber = 1, + visitant_status_update = 9, + visitant_status_wears_off = 10, + visitant_status_extend = 12, + visitant_status_gain = 45, + pearlescent_light = 183, + golden_light = 184, + silvery_light = 185, + ebon_light = 186, + azure_light = 187, + ruby_light = 188, + amber_light = 189, + }, + z132 = { + name = 'Abyssea - La Theine', + offset = 7315, + pearl_ebon_gold_silvery = 0, + azure_ruby_amber = 1, + visitant_status_update = 9, + visitant_status_wears_off = 10, + visitant_status_extend = 12, + visitant_status_gain = 45, + pearlescent_light = 183, + golden_light = 184, + silvery_light = 185, + ebon_light = 186, + azure_light = 187, + ruby_light = 188, + amber_light = 189, + }, + z45 = { + name = 'Abyssea - Tahrongi', + offset = 7315, + pearl_ebon_gold_silvery = 0, + azure_ruby_amber = 1, + visitant_status_update = 9, + visitant_status_wears_off = 10, + visitant_status_extend = 12, + visitant_status_gain = 45, + pearlescent_light = 183, + golden_light = 184, + silvery_light = 185, + ebon_light = 186, + azure_light = 187, + ruby_light = 188, + amber_light = 189, + }, + z215 = { + name = 'Abyssea - Attohwa', + offset = 7215, + pearl_ebon_gold_silvery = 0, + azure_ruby_amber = 1, + visitant_status_update = 9, + visitant_status_wears_off = 10, -- Could also be 7194, the singular message. That is less than 10 minutes though, so shouldn't need to update for it. + visitant_status_extend = 12, + visitant_status_gain = 45, -- Could also be 7228 or 7229 + pearlescent_light = 183, + golden_light = 184, + silvery_light = 185, + ebon_light = 186, + azure_light = 187, + ruby_light = 188, + amber_light = 189, + }, + z216 = { + name = 'Abyssea - Misareaux', + offset = 7315, + pearl_ebon_gold_silvery = 0, + azure_ruby_amber = 1, + visitant_status_update = 9, + visitant_status_wears_off = 10, + visitant_status_extend = 12, + visitant_status_gain = 45, + pearlescent_light = 183, + golden_light = 184, + silvery_light = 185, + ebon_light = 186, + azure_light = 187, + ruby_light = 188, + amber_light = 189, + }, + z217 = { + name = 'Abyssea - Vunkerl', + offset = 7315, + pearl_ebon_gold_silvery = 0, + azure_ruby_amber = 1, + visitant_status_update = 9, + visitant_status_wears_off = 10, + visitant_status_extend = 12, + visitant_status_gain = 45, + pearlescent_light = 183, + golden_light = 184, + silvery_light = 185, + ebon_light = 186, + azure_light = 187, + ruby_light = 188, + amber_light = 189, + }, + z218 = { + name = 'Abyssea - Altepa', + offset = 7315, + pearl_ebon_gold_silvery = 0, + azure_ruby_amber = 1, + visitant_status_update = 9, + visitant_status_wears_off = 10, + visitant_status_extend = 12, + visitant_status_gain = 45, + pearlescent_light = 183, + golden_light = 184, + silvery_light = 185, + ebon_light = 186, + azure_light = 187, + ruby_light = 188, + amber_light = 189, + }, + z254 = { + name = 'Abyssea - Grauberg', + offset = 7315, + pearl_ebon_gold_silvery = 0, + azure_ruby_amber = 1, + visitant_status_update = 9, + visitant_status_wears_off = 10, + visitant_status_extend = 12, + visitant_status_gain = 45, + pearlescent_light = 183, + golden_light = 184, + silvery_light = 185, + ebon_light = 186, + azure_light = 187, + ruby_light = 188, + amber_light = 189, + }, + z253 = { + name = 'Abyssea - Uleguerand', + offset = 7215, + pearl_ebon_gold_silvery = 0, + azure_ruby_amber = 1, + visitant_status_update = 9, + visitant_status_wears_off = 10, + visitant_status_extend = 12, + visitant_status_gain = 45, + pearlescent_light = 183, + golden_light = 184, + silvery_light = 185, + ebon_light = 186, + azure_light = 187, + ruby_light = 188, + amber_light = 189, + }, +} + +return messages diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/pointwatch/pointwatch.lua b/Data/BuiltIn/Libraries/lua-addons/addons/pointwatch/pointwatch.lua new file mode 100644 index 0000000..8eac64d --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/pointwatch/pointwatch.lua @@ -0,0 +1,328 @@ +--Copyright (c) 2014, Byrthnoth +--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. + +texts = require 'texts' +config = require 'config' +require 'sets' +res = require 'resources' +require 'statics' +messages = require 'message_ids' +require 'pack' + +_addon.name = 'PointWatch' +_addon.author = 'Byrth' +_addon.version = 0.150811 +_addon.command = 'pw' + +settings = config.load('data\\settings.xml',default_settings) +config.register(settings,initialize) + +box = texts.new('${current_string}',settings.text_box_settings,settings) +box.current_string = '' +box:show() + +initialize() + +windower.register_event('incoming chunk',function(id,org,modi,is_injected,is_blocked) + if is_injected then return end + if id == 0x29 then -- Action Message, used in Abyssea for xp + local val = org:unpack('I',0xD) + local msg = org:unpack('H',0x19)%1024 + exp_msg(val,msg) + elseif id == 0x2A then -- Resting message + local zone = 'z'..windower.ffxi.get_info().zone + if settings.options.message_printing then + print('Message ID: '..(org:unpack('H',0x1B)%2^14)) + end + + if messages[zone] then + local msg = org:unpack('H',0x1B)%2^14 + for i,v in pairs(messages[zone]) do + if tonumber(v) and v + messages[zone].offset == msg then + local param_1 = org:unpack('I',0x9) + local param_2 = org:unpack('I',0xD) + local param_3 = org:unpack('I',0x11) + local param_4 = org:unpack('I',0x15) + -- print(param_1,param_2,param_3,param_4) -- DEBUGGING STATEMENT ------------------------- + if zone_message_functions[i] then + zone_message_functions[i](param_1,param_2,param_3,param_4) + end + if i:contains("visitant_status_") then + abyssea.update_time = os.clock() + end + end + end + end + elseif id == 0x2D then + local val = org:unpack('I',0x11) + local msg = org:unpack('H',0x19)%1024 + exp_msg(val,msg) + elseif id == 0x55 then + if org:byte(0x85) == 3 then + local dyna_KIs = math.floor((org:byte(6)%64)/2) -- 5 bits (32, 16, 8, 4, and 2 originally -> shifted to 16, 8, 4, 2, and 1) + dynamis._KIs = { + ['Crimson'] = dyna_KIs%2 == 1, + ['Azure'] = math.floor(dyna_KIs/2)%2 == 1, + ['Amber'] = math.floor(dyna_KIs/4)%2 == 1, + ['Alabaster'] = math.floor(dyna_KIs/8)%2 == 1, + ['Obsidian'] = math.floor(dyna_KIs/16) == 1, + } + if dynamis_map[dynamis.zone] then + dynamis.time_limit = 3600 + for KI,TE in pairs(dynamis_map[dynamis.zone]) do + if dynamis._KIs[KI] then + dynamis.time_limit = dynamis.time_limit + TE*60 + end + end + update_box() + end + end + elseif id == 0x61 then + xp.current = org:unpack('H',0x11) + xp.tnl = org:unpack('H',0x13) + accolades.current = math.floor(org:byte(0x5A)/4) + org:byte(0x5B)*2^6 + org:byte(0x5C)*2^14 + elseif id == 0x63 and org:byte(5) == 2 then + lp.current = org:unpack('H',9) + lp.number_of_merits = org:byte(11)%128 + lp.maximum_merits = org:byte(0x0D)%128 + elseif id == 0x63 and org:byte(5) == 5 then + local offset = windower.ffxi.get_player().main_job_id*6+13 -- So WAR (ID==1) starts at byte 19 + cp.current = org:unpack('H',offset) + cp.number_of_job_points = org:unpack('H',offset+2) + elseif id == 0x110 then + sparks.current = org:unpack('I',5) + elseif id == 0xB and box:visible() then + zoning_bool = true + box:hide() + elseif id == 0xA and zoning_bool then + zoning_bool = nil + box:show() + end +end) + +windower.register_event('zone change',function(new,old) + if res.zones[new].english:sub(1,7) == 'Dynamis' then + dynamis.entry_time = os.clock() + abyssea.update_time = 0 + abyssea.time_remaining = 0 + dynamis.time_limit = 3600 + dynamis.zone = new + cur_func,loadstring_err = loadstring("current_string = "..settings.strings.dynamis) + elseif res.zones[new].english:sub(1,7) == 'Abyssea' then + abyssea.update_time = os.clock() + abyssea.time_remaining = 5 + dynamis.entry_time = 0 + dynamis.time_limit = 0 + dynamis.zone = 0 + cur_func,loadstring_err = loadstring("current_string = "..settings.strings.abyssea) + else + abyssea.update_time = 0 + abyssea.time_remaining = 0 + dynamis.entry_time = 0 + dynamis.time_limit = 0 + dynamis.zone = 0 + cur_func,loadstring_err = loadstring("current_string = "..settings.strings.default) + end + if not cur_func or loadstring_err then + cur_func = loadstring("current_string = ''") + error(loadstring_err) + end +end) + +windower.register_event('addon command',function(...) + local commands = {...} + local first_cmd = table.remove(commands,1):lower() + if approved_commands[first_cmd] and #commands >= approved_commands[first_cmd].n then + local tab = {} + for i,v in ipairs(commands) do + tab[i] = tonumber(v) or v + if i <= approved_commands[first_cmd].n and type(tab[i]) ~= approved_commands[first_cmd].t then + print('Pointwatch: texts library command ('..first_cmd..') requires '..approved_commands[first_cmd].n..' '..approved_commands[first_cmd].t..'-type input'..(approved_commands[first_cmd].n > 1 and 's' or '')) + return + end + end + texts[first_cmd](box,unpack(tab)) + settings.text_box_settings = box._settings + config.save(settings) + elseif first_cmd == 'reload' then + windower.send_command('lua r pointwatch') + elseif first_cmd == 'unload' then + windower.send_command('lua u pointwatch') + elseif first_cmd == 'reset' then + initialize() + elseif first_cmd == 'message_printing' then + settings.options.message_printing = not settings.options.message_printing + print('Pointwatch: Message printing is '..tostring(settings.options.message_printing)..'.') + elseif first_cmd == 'eval' then + assert(loadstring(table.concat(commands, ' ')))() + end +end) + +windower.register_event('prerender',function() + if frame_count%30 == 0 and box:visible() then + update_box() + end + frame_count = frame_count + 1 +end) + +function update_box() + if not windower.ffxi.get_info().logged_in or not windower.ffxi.get_player() then + box.current_string = '' + return + end + cp.rate = analyze_points_table(cp.registry) + xp.rate = analyze_points_table(xp.registry) + if dynamis.entry_time ~= 0 and dynamis.entry_time+dynamis.time_limit-os.clock() > 0 then + dynamis.time_remaining = os.date('!%H:%M:%S',dynamis.entry_time+dynamis.time_limit-os.clock()) + dynamis.KIs = X_or_O(dynamis._KIs.Crimson)..X_or_O(dynamis._KIs.Azure)..X_or_O(dynamis._KIs.Amber)..X_or_O(dynamis._KIs.Alabaster)..X_or_O(dynamis._KIs.Obsidian) + elseif abyssea.update_time ~= 0 then + local time_less_then = math.floor((os.clock() - abyssea.update_time)/60) + abyssea.time_remaining = abyssea.time_remaining-time_less_then + if time_less_then >= 1 then + abyssea.update_time = os.clock() + end + else + dynamis.time_remaining = 0 + dynamis.KIs = '' + end + assert(cur_func)() + + if box.current_string ~= current_string then + box.current_string = current_string + end +end + +function X_or_O(bool) + if bool then return 'O' else return 'X' end +end + +function analyze_points_table(tab) + local t = os.clock() + local running_total = 0 + local maximum_timestamp = 29 + for ts,points in pairs(tab) do + local time_diff = t - ts + if t - ts > 600 then + tab[ts] = nil + else + running_total = running_total + points + if time_diff > maximum_timestamp then + maximum_timestamp = time_diff + end + end + end + + local rate + if maximum_timestamp == 29 then + rate = 0 + else + rate = math.floor((running_total/maximum_timestamp)*3600) + end + + return rate +end + +zone_message_functions = { + amber_light = function(p1,p2,p3,p4) + abyssea.amber = math.min(abyssea.amber + 8,255) + end, + azure_light = function(p1,p2,p3,p4) + abyssea.azure = math.min(abyssea.azure + 8,255) + end, + ruby_light = function(p1,p2,p3,p4) + abyssea.ruby = math.min(abyssea.ruby + 8,255) + end, + pearlescent_light = function(p1,p2,p3,p4) + abyssea.pearlescent = math.min(abyssea.pearlescent + 5,230) + end, + ebon_light = function(p1,p2,p3,p4) + abyssea.ebon = math.min(abyssea.ebon + p1+1,200) -- NM kill = 1, faint = 1, mild = 2, strong = 3 + end, + silvery_light = function(p1,p2,p3,p4) + abyssea.silvery = math.min(abyssea.silvery + 5*(p1+1),200) -- faint = 5, mild = 10, strong = 15 + end, + golden_light = function(p1,p2,p3,p4) + abyssea.golden = math.min(abyssea.golden + 5*(p1+1),200) -- faint = 5, mild = 10, strong = 15 + end, + pearl_ebon_gold_silvery = function(p1,p2,p3,p4) + abyssea.pearlescent = p1 + abyssea.ebon = p2 + abyssea.golden = p3 + abyssea.silvery = p4 + end, + azure_ruby_amber = function(p1,p2,p3,p4) + abyssea.azure = p1 + abyssea.ruby = p2 + abyssea.amber = p3 + end, + visitant_status_gain = function(p1,p2,p3,p4) + abyssea.time_remaining = p1 + end, + visitant_status_update = function(p1,p2,p3,p4) + abyssea.time_remaining = p1 + end, + visitant_status_wears_off = function(p1,p2,p3,p4) + abyssea.time_remaining = p1 + end, + visitant_status_extend = function(p1,p2,p3,p4) + abyssea.time_remaining = abyssea.time_remaining + p1 + end, +} + +function exp_msg(val,msg) + local t = os.clock() + if msg == 718 or msg == 735 then + cp.registry[t] = (cp.registry[t] or 0) + val + cp.total = cp.total + val + cp.current = cp.current + val + if cp.current > cp.tnjp and cp.number_of_job_points ~= cp.maximum_job_points then + cp.number_of_job_points = math.min(cp.number_of_job_points + math.floor(cp.current/cp.tnjp),cp.maximum_job_points) + cp.current = cp.current%cp.tnjp + end + elseif msg == 8 or msg == 105 then + xp.registry[t] = (xp.registry[t] or 0) + val + xp.total = xp.total + val + xp.current = math.min(xp.current + val,55999) + -- 98 to 99 is 56000 XP, so 55999 is the most you can ever have + if xp.current > xp.tnl then + -- I have capped all jobs, but I assume that a 0x61 packet is sent after you + -- level up, which will update the TNL and make this adjustment meaningless. + xp.current = xp.current - xp.tnl + end + elseif msg == 371 or msg == 372 then + lp.registry[t] = (lp.registry[t] or 0) + val + lp.current = lp.current + val + if lp.current >= lp.tnm and lp.number_of_merits ~= lp.maximum_merits then + -- Merit Point gained! + lp.number_of_merits = math.min(lp.number_of_merits + math.floor(lp.current/lp.tnm),lp.maximum_merits) + lp.current = lp.current%lp.tnm + else + -- If a merit point was not gained, + lp.current = math.min(lp.current,lp.tnm-1) + end + end + update_box() +end diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/pointwatch/statics.lua b/Data/BuiltIn/Libraries/lua-addons/addons/pointwatch/statics.lua new file mode 100644 index 0000000..902cc46 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/pointwatch/statics.lua @@ -0,0 +1,159 @@ +--Copyright (c) 2014, Byrthnoth +--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. + + +--Default settings file: +default_settings = { + strings = { + default = "xp.current..'/'..xp.tnl..'XP '..lp.current..'/'..lp.tnm..'LP ['..lp.number_of_merits..'/'..lp.maximum_merits..'] XP/hr:'..string.format('%.1f',math.floor(xp.rate/100)/10)..'k '..cp.current..'/'..cp.tnjp..'CP ['..cp.number_of_job_points..'] CP/hr:'..string.format('%.1f',math.floor(cp.rate/100)/10)..'k'", + dynamis = "xp.current..'/'..xp.tnl..'XP '..lp.current..'/'..lp.tnm..'LP ['..lp.number_of_merits..'/'..lp.maximum_merits..'] XP/hr:'..string.format('%.1f',math.floor(xp.rate/100)/10)..'k '..cp.current..'/'..cp.tnjp..'CP ['..cp.number_of_job_points..'] '..dynamis.KIs..' '..dynamis.time_remaining", + abyssea = "xp.current..'/'..xp.tnl..'XP '..lp.current..'/'..lp.tnm..'LP ['..lp.number_of_merits..'/'..lp.maximum_merits..'] XP/hr:'..string.format('%.1f',math.floor(xp.rate/100)/10)..'k Amber:'..(abyssea.amber or 0)..'/Azure:'..(abyssea.azure or 0)..'/Ruby:'..(abyssea.ruby or 0)..'/Pearlescent:'..(abyssea.pearlescent or 0)..'/Ebon:'..(abyssea.ebon or 0)..'/Silvery:'..(abyssea.silvery or 0)..'/Golden:'..(abyssea.golden or 0)..'/Time Remaining:'..(abyssea.time_remaining or 0)" + }, + text_box_settings = { + pos = { + x = 0, + y = 0, + }, + bg = { + alpha = 255, + red = 0, + green = 0, + blue = 0, + visible = true + }, + flags = { + right = false, + bottom = false, + bold = false, + italic = false + }, + padding = 0, + text = { + size = 12, + font = 'Consolas', + fonts = {}, + alpha = 255, + red = 255, + green = 255, + blue = 255 + } + }, + options = { + message_printing = false, + }, +} + +-- Approved textbox commands: +approved_commands = S{'show','hide','pos','pos_x','pos_y','font','size','pad','color','alpha','transparency','bg_color','bg_alpha','bg_transparency'} +approved_commands = {show={n=0},hide={n=0},pos={n=2,t='number'},pos_x={n=1,t='number'},pos_y={n=1,t='number'}, + font={n=2,t='string'},size={n=1,t='number'},pad={n=1,t='number'},color={n=3,t='number'},alpha={n=1,t='number'}, + transparency={n=1,t='number'},bg_color={n=3,t='number'},bg_alpha={n=1,t='number'},bg_transparency={n=1,t='number'}} + + +-- Dynamis TE lists: +city_table = {Crimson=10,Azure=10,Amber=10,Alabaster=15,Obsidian=15} +other_table = {Crimson=10,Azure=10,Amber=10,Alabaster=10,Obsidian=20} + +-- Mapping of zone ID to TE list: +dynamis_map = {[185]=city_table,[186]=city_table,[187]=city_table,[188]=city_table, + [134]=other_table,[135]=other_table,[39]=other_table,[40]=other_table,[41]=other_table,[42]=other_table} + + +-- Not technically static, but sets the initial values for all features: +function initialize() + cp = { + registry = {}, + current = 0, + rate = 0, + total = 0, + tnjp = 30000, + number_of_job_points = 0, + maximum_job_points = 500, + } + + + xp = { + registry = {}, + total = 0, + rate = 0, + current = 0, + tnl = 0, + } + + lp = { + registry = xp.registry, + current = 0, + tnm = 10000, + number_of_merits = 0, + maximum_merits = 30, + } + + sparks = { + current = 0, + maximum = 99999, + } + + accolades = { + current = 0, + maximum = 99999, + } + + abyssea = { + amber = 0, + azure = 0, + ruby = 0, + pearlescent = 0, + ebon = 0, + silvery = 0, + golden = 0, + update_time = 0, + time_remaining = 0, + } + + + local info = windower.ffxi.get_info() + + frame_count = 0 + + dynamis = { + KIs = '', + _KIs = {}, + entry_time = 0, + time_limit = 0, + zone = 0, + } + if info.logged_in and res.zones[info.zone].english:sub(1,7) == 'Dynamis' then + cur_func = loadstring("current_string = "..settings.strings.dynamis) + setfenv(cur_func,_G) + dynamis.entry_time = os.clock() + dynamis.zone = info.zone + windower.add_to_chat(123,'Loading PointWatch in Dynamis results in an inaccurate timer. Number of KIs is displayed.') + elseif info.logged_in then + cur_func = loadstring("current_string = "..settings.strings.default) + setfenv(cur_func,_G) + end + +end |