diff options
Diffstat (limited to 'Data/BuiltIn/Libraries/lua-addons/addons/Nostrum')
23 files changed, 2629 insertions, 0 deletions
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/Nostrum.lua b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/Nostrum.lua new file mode 100644 index 0000000..586abda --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/Nostrum.lua @@ -0,0 +1,769 @@ +--[[Copyright © 2014-2015, trv +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 Nostrum 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 trv 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 = 'Nostrum' +_addon.author = 'trv' +_addon.version = '2.2.0' +_addon.commands = {'Nostrum','nos',} + +packets=require('packets') +require('tables') +require('strings') +require('variables') +require('logger') +require('helperfunctions') +require('sets') +require('lists') +config = require('config') +prims = require('prims') + +defaults={ + text={ + buttons={ + color={a=255,r=255,g=255,b=255}, + }, + name={ + color={a=255,r=255,g=255,b=255}, + visible=true + }, + tp={ + color={a=255,r=255,g=255,b=255}, + visible=true + }, + hp={ + color={a=255,r=255,g=255,b=255}, + visible=true + }, + mp={ + color={a=255,r=255,g=255,b=255}, + visible=true + }, + hpp={ + color={a=255,r=255,g=255,b=255}, + visible=true + }, + na={ + color={a=255,r=255,g=255,b=255}, + visible=true + }, + buffs={ + color={a=255,r=255,g=255,b=255}, + visible=true} + }, + primitives={ + buttons={ + visible=false, + color={a=0, r=0, g=0, b=0}, + }, + highlight={ + color={a=100, r=255, g=255, b=255}, + }, + curaga_buttons={ + visible=false, + color={a=0, r=0,g=0, b=0}, + }, + background={ + visible=true, + color={a=100, r=0, g=0, b=0}, + }, + hp_bar={ + green={a=176, r=1, g=100, b=14}, + yellow={a=176, r=255,g=255,b=0}, + orange={a=176, r=255, g=100, b=1}, + red={a=176, r=255, g=0, b=0}, + }, + mp_bar={ + visible=true, + color={a=100, r=149, g=212, b=255}, + }, + hp_bar_background={ + visible=true, + color={a=200, r=0, g=0, b=0}, + }, + na_buttons={ + visible=false, + color={a=0,r=255,g=255,b=255}, + }, + buff_buttons={ + visible=false, + color={a=0, r=255, g=255, b=255}, + }, + }, + window={x_offset=0,y_offset=0,}, + profiles={ + default={ + ["cure"]=true, + ["cureii"]=true, + ["cureiii"]=true, + ["cureiv"]=true, + ["curev"]=true, + ["curevi"]=true, + ["curaga"]=true, + ["curagaii"]=true, + ["curagaiii"]=true, + ["curagaiv"]=true, + ["curagav"]=true, + ["sacrifice"]=true, + ["erase"]=true, + ["paralyna"]=true, + ["silena"]=true, + ["blindna"]=true, + ["poisona"]=true, + ["viruna"]=true, + ["stona"]=true, + ["cursna"]=true, + ["haste"]=true, + ["hasteii"]=false, + ["flurry"]=false, + ["flurryii"]=false, + ["protect"]=false, + ["shell"]=false, + ["protectii"]=false, + ["shellii"]=false, + ["protectiii"]=false, + ["shelliii"]=false, + ["protectiv"]=false, + ["shelliv"]=false, + ["protectv"]=true, + ["shellv"]=true, + ["refresh"]=false, + ["refreshii"]=false, + ["regen"]=false, + ["regenii"]=false, + ["regeniii"]=false, + ["regeniv"]=true, + ["regenv"]=false, + ["phalanxii"]=false, + ["adloquium"]=false, + ["animusaugeo"]=false, + ["animusminuo"]=false, + ["embrava"]=false, + ["curingwaltz"]=false, + ["curingwaltzii"]=false, + ["curingwaltziii"]=false, + ["curingwaltziv"]=false, + ["curingwaltzv"]=false, + ["divinewaltz"]=false, + ["divinewaltzii"]=false, + ["healingwaltz"]=false, + }, + }, +} +_defaults = config.load(defaults) + +_settings=merge_user_file_and_settings(_defaults,settings) +profile=_settings.profiles.default + +function build_macro() + local x_start=_settings.window.x_res-1-_defaults.window.x_offset + local y_start=_settings.window.y_res-h-1-_defaults.window.y_offset + local prim = _settings.primitives + local text = _settings.text + + for k=1,3 do + local pt = party[k] + if pt.n ~= 0 then + prim_simple("BG"..tostring(k),prim.background,x_start-(macro_order[k].n)*(w+1)-153,y_start-pt.n*(h+1)+h,macro_order[k].n*(w+1)+1,pt.n*(h+1)+1) + prim_simple("info"..tostring(k),prim.hp_bar_background,x_start-152,y_start-pt.n*(h+1)+h,152,pt.n*(h+1)+1) + macro[k]:add("BG"..tostring(k)) + end + for j=pt.n,1,-1 do + local stats = stat_table[pt[j]] + local n = position_lookup[pt[j]] + local s = tostring(n) + prim_simple("phpp" .. s,prim.hp_bar,x_start-151,y_start,150/100*stats.hpp,h) + local color = prim.hp_bar[choose_color(stats.hpp)] + windower.prim.set_color("phpp" .. s,color.a,color.r,color.g,color.b) + prim_simple("pmpp" .. s,prim.mp_bar,x_start-151,y_start+19,150/100*stats.mpp,5) + text_simple("tp" .. s, text.tp, x_start-151, y_start+11,stats.tp) + text_simple("name" .. s, text.name, x_start-151, y_start-3, prepare_names(stats.name)) + text_simple("hpp" .. s, text.hpp, x_start, y_start-4, stats.hpp) + text_simple("hp" .. s, text.hp, x_start-40, y_start-3, stats.hp) + text_simple("mp" .. s, text.mp, x_start-40, y_start+11,stats.mp) + prims_by_layer[n]:extend(L{"phpp" .. s,"pmpp" .. s}) + texts_by_layer[n]:extend(L{"tp" .. s,"name" .. s,"hpp" .. s,"hp" .. s,"mp" .. s}) + + prim_rose(macro_order[k],n,x_start,y_start,k) + y_start=y_start-(h+1) + + end + + y_start=y_start-(175-75*k) + + end + + prim_simple("target_background",prim.hp_bar_background,x_start-152,prim_coordinates.y['info1']-52,152,32) + text_simple("target_name", text.name, x_start-151, prim_coordinates.y['info1']-50,'') + windower.text.set_font_size("target_name11", 13) + prim_simple("target",prim.hp_bar,x_start-151,prim_coordinates.y['info1']-50,150,30) + text_simple("targethpp",text.tp, x_start-151, prim_coordinates.y['info1']-34, '0') + local color = prim.hp_bar[choose_color(100)] + windower.prim.set_color("target",color.a,color.r,color.g,color.b) + misc_hold_for_up.prims:append("target_background") + misc_hold_for_up.prims:append("target") + misc_hold_for_up.texts:append("target_name") + misc_hold_for_up.texts:append("targethpp") + prim_simple("pmenu",prim.hp_bar_background,x_start-152,prim_coordinates.y['info1']-20,152,20) + text_simple("menu",text.name, x_start-94, prim_coordinates.y['info1']-18, 'menu') + misc_hold_for_up.prims:append("pmenu") + misc_hold_for_up.texts:append("menu") + + y_start=prim_coordinates.y['BG1']-27 + if macro_order[4].n~=0 then + prim_simple("BGna",prim.background,x_start-33*macro_order[4].n-153,y_start,(macro_order[4].n)*(33)+1,27) + misc_hold_for_up.prims:append("BGna") + macro[1]:add("BGna") + image_row(macro_order[4],x_start,y_start+1) + y_start=y_start-27 + end + + if macro_order[5].n~=0 then + prim_simple("BGbuffs",prim.background,x_start-33*macro_order[5].n-153,y_start,(macro_order[5].n)*(33)+1,27) + misc_hold_for_up.prims:append("BGbuffs") + macro[1]:add("BGbuffs") + image_row(macro_order[5],x_start,y_start+1) + end + + prim_simple("hover24",table.set(_defaults.primitives.highlight,'visible',false),0,0,29,24) + prim_simple("hover32",table.set(_defaults.primitives.highlight,'visible',false),0,0,25,25) + misc_hold_for_up.prims:append("hover24") + misc_hold_for_up.prims:append("hover32") + + + toggle_macro_visibility(1) + toggle_macro_visibility(2) + toggle_macro_visibility(3) + +end + +do + local initialized = false + initialize = function(bool) + if bool ~= nil then initialized = bool return end + if initialized or not windower.ffxi.get_info().logged_in then return end + initialized = true + local alliance_keys = {'p0', 'p1', 'p2', 'p3', 'p4', 'p5', 'a10', 'a11', 'a12', 'a13', 'a14', 'a15', 'a20', 'a21', 'a22', 'a23', 'a24', 'a25'} + local party_from_memory = windower.ffxi.get_party() + local player = windower.ffxi.get_player() + + player_id = player.id + position_lookup = {} + stat_table = {} + party = {L{},L{},L{}} + count_cures(profile) + count_na(profile) + count_buffs(profile) + + for i=1,18 do + local party_member_from_memory = party_from_memory[alliance_keys[i]] + + if party_member_from_memory and party_member_from_memory.mob then + local id = party_member_from_memory.mob.id + local n = math.ceil(i/6) + + party[n]:append(id) + + local m = 6*n + 1 - party[n].n + + position_lookup[id] = m + + position[1][m] = party_member_from_memory.mob.x + position[2][m] = party_member_from_memory.mob.y + stat_table[id]={ + hp = party_member_from_memory.hp, + mp = party_member_from_memory.mp, + mpp = party_member_from_memory.mpp, + hpp = party_member_from_memory.hpp, + tp = party_member_from_memory.tp, + name = party_member_from_memory.name, + buffs = {{n=0},{n=0}} + } + end + end + + build_macro() + define_active_regions() + register_events(true) + stat_table[player_id].index = player.index + end +end + +windower.register_event('load', initialize) + +windower.register_event('login', function() + coroutine.sleep(6) + initialize() +end) + +windower.register_event('logout', function() + wrecking_ball() + initialize(false) + register_events(false) +end) + +windower.register_event('addon command', function(...) + local args={...} + local c = args[1] and args[1]:lower() or 'help' + if c == 'help' then + print(help_text) + elseif c == 'hide' or c == 'h' then + toggle_visibility() + elseif c == 'cut' or c == 'c' then + trim_macro() + elseif c == 'refresh' or c == 'r' then + compare_alliance_to_memory() + elseif c == 'send' or c == 's' then + if args[2] then + send_string = 'send ' .. tostring(args[2]) .. ' ' + print('Commands will be sent to: ' .. tostring(args[2])) + else + send_string = '' + print('Input contained no name. Send disabled.') + end + elseif c == 'profile' or c == 'p' then + if args[2] == 'reload' or args[2] == 'r' then + config.reload(defaults) + elseif _settings.profiles[args[2]] then + profile = _settings.profiles[args[2]] + switch_profiles() + else + print('Profile ' .. args[2] .. ' not found.') + end + end +end) + +do + local incoming_chunk_event + local outgoing_chunk_event + local zone_change_event + local keyboard_event + local mouse_event + local last_x,last_y = 0,0 + local last_x32,last_y32 = 0,0 + local prim_coordinates = prim_coordinates + local x_offset = _defaults.window.x_offset + local y_offset = _defaults.window.y_offset + local x_res = settings.window.x_res + local y_res = settings.window.y_res + +register_events = function(bool) + if bool then + keyboard_event = windower.register_event('keyboard', function(dik,down,flags,blocked) + if down and tab_keys[dik] and not bit.is_set(flags, 6) then + coroutine.sleep(.02) + local target = windower.ffxi.get_mob_by_target('st') or windower.ffxi.get_mob_by_target('t') + if target then update_target(target) end + end + end) + + mouse_event = windower.register_event('mouse', function(type, x, y, delta, blocked) + if is_hidden then return end + if type == 0 then + local _x = math.ceil((x_res-x-x_offset-152)/30) + local _y = math.ceil((y_res-y-y_offset)/25) + if mouse_map[_y] and mouse_map[_y][_x] then + if not macro_visibility[position_to_region_map[_y]] then + toggle_macro_visibility(position_to_region_map[_y]) + end + if not prim_coordinates.visible['hover24'] then + windower.prim.set_visibility("hover24",true) + windower.prim.set_visibility("hover32",false) + prim_coordinates.visible['hover32'] = false + prim_coordinates.visible['hover24'] = true + end + if _x ~= last_x or _y ~= last_y then + prim_coordinates.x['hover24'] = x_res-153-x_offset-_x*30 + prim_coordinates.y['hover24'] = y_res-y_offset-25*_y + windower.prim.set_position("hover24",prim_coordinates.x['hover24'],prim_coordinates.y['hover24']) + last_x = _x + last_y = _y + end + return + end + _y = math.ceil((y_res-y-y_offset-25*(party[1].n+vacancies[1]))/28) + _x = math.ceil((x_res-x-x_offset-152)/26) + if mouse_map2[_y] and mouse_map2[_y][_x] then + if not macro_visibility[1] then + toggle_macro_visibility(1) + end + if not prim_coordinates.visible['hover32'] then + windower.prim.set_visibility("hover32",true) + windower.prim.set_visibility("hover24",false) + prim_coordinates.visible['hover32'] = true + prim_coordinates.visible['hover24'] = false + end + if _x ~= last_x32 or _y ~= last_y32 then + prim_coordinates.x['hover32'] = x_res-153-x_offset-_x*26 + prim_coordinates.y['hover32'] = y_res-y_offset-25*_y-25*(party[1].n+vacancies[1])-2*_y + windower.prim.set_position("hover32",prim_coordinates.x['hover32'],prim_coordinates.y['hover32']) + last_x32 = _x + last_y32 = _y + end + return + end + for i = 1,3 do + if macro_visibility[i] then + toggle_macro_visibility(i) + end + end + if prim_coordinates.visible['hover32'] then + windower.prim.set_visibility("hover32",false) + prim_coordinates.visible['hover32'] = false + end + if prim_coordinates.visible['hover24'] then + windower.prim.set_visibility("hover24",false) + prim_coordinates.visible['hover24'] = false + end + elseif type == 1 then + local _x = (x_res-x-x_offset) + local _y = math.ceil((y_res-y-y_offset)/25) + if _x < 153 then + if region_to_name_map[_y] then + windower.send_command('%sinput /target %s':format(send_string,region_to_name_map[_y])) + dragged = true + return true + end + else + _x = math.ceil((_x-152)/30) + if mouse_map[_y] and mouse_map[_y][_x] then + local spell = mouse_map[_y][_x] + windower.send_command('%sinput %s "%s" %s':format(send_string, prefix[spell], spell, region_to_name_map[_y])) + dragged = true + return true + end + _y = math.ceil((y_res-y-y_offset-25*(party[1].n+vacancies[1]))/28) + _x = math.ceil((x_res-x-x_offset-152)/26) + if mouse_map2[_y] and mouse_map2[_y][_x] then + local spell = mouse_map2[_y][_x] + windower.send_command('%sinput %s "%s" %s':format(send_string, prefix[spell], spell, '<t>')) + dragged = true + return true + end + end + elseif type == 2 then + if dragged then + dragged = false + return true + end + elseif type == 4 then + local _x = (x_res-x-x_offset) + local _y = math.ceil((y_res-y-y_offset)/25) + if _x < 153 then + if region_to_name_map[_y] then + windower.send_command('%sinput %s "%s" %s':format(send_string, prefix[spell_default] or '', spell_default, region_to_name_map[_y])) + dragged = true + return true + end + else + _y = math.ceil((y_res-y-y_offset-25*(party[1].n+vacancies[1]))/28) + _x = math.ceil((_x-152)/26) + if mouse_map2[_y] and mouse_map2[_y][_x] then + spell_default = mouse_map2[_y][_x] + windower.text.set_text('menu', spell_default) + text_coordinates.x['menu'] = prim_coordinates.x['pmenu'] + 1 + (150 - 7.55 * string.length(spell_default))/2 + windower.text.set_location('menu',text_coordinates.x['menu'],text_coordinates.y['menu']) + dragged = true + return true + end + end + elseif type == 5 then + if dragged then + dragged = false + return true + end + end + end) + + outgoing_chunk_event = windower.register_event('outgoing chunk', function(id,data) + if id == 0x015 then + local packet = packets.parse('outgoing', data) + + if packet['Target Index'] ~= last_index or last_index == stat_table[player_id].index then + update_target(windower.ffxi.get_mob_by_index(packet['Target Index'])) + end + + local position = position + + if position[1][6] ~= packet['X'] or position[2][6] ~= packet['Y'] then + position[1][6],position[2][6] = packet['X'],packet['Y'] + + local party = party + + for i = 5,7-party[1].n,-1 do + if not (out_of_zone[party[1][7 - i]] or out_of_view[i]) then + indicate_distance(false,i,position[1][i],position[2][i]) + end + end + + for j = 2,3 do + for i = j*6,j*6-party[j].n+1,-1 do + if not (out_of_zone[party[j][j*6-i+1]] or out_of_view[i]) then + indicate_distance(false,i,position[1][i],position[2][i]) + end + end + end + end + elseif id == 0x00D then + is_zoning = true + if not is_hidden then + for key in pairs(saved_prims) do + if prim_coordinates.visible[key] then + windower.prim.set_visibility(key,false) + end + end + for key in pairs(saved_texts) do + if text_coordinates.visible[key] then + windower.text.set_visibility(key,false) + end + end + + toggle_buff_visibility(false) + + for i = 1,party[1].n do + stat_table[party[1][i]].buffs={{n = 0},{n = 0}} -- wipe buffs on zone + end + end + end + end) + + incoming_chunk_event = windower.register_event('incoming chunk', function(id, data) + if id == 0x00D or id == 0x00E then -- kind of weird + local Mask = data:unpack('C',0x0B) + if data:unpack('H',9) == last_index and bit.band(Mask,4) > 0 then + update_target_hp(data:unpack('C',0x1F)) + end + local f = position_lookup[data:unpack('I',5)] + if f and f ~= 6 then + if bit.band(Mask,1) > 0 then --Mask + local X,Z,Y = data:unpack('fff',0x0D) --0b000001 position updated + position[1][f] = X --0b000100 hp updated + position[2][f] = Y --0b011111 model appear i.e. update all + indicate_distance(false,f,X,Y) --0b100000 model disappear + elseif bit.band(Mask,32) > 0 then + indicate_distance(true,f) + end + end + elseif id == 0x0DF then + local packet = packets.parse('incoming', data) + local id = packet['ID'] + if not position_lookup[id] then return end + local to_update = L{} + local stats = stat_table[id] + if stats.hp ~= packet['HP'] then + stats.hp = packet['HP'] + to_update:append('hp') + end + if stats.mp ~= packet['MP'] then + stats.mp = packet['MP'] + to_update:append('mp') + end + if stats.tp ~= packet['TP'] then + stats.tp = packet['TP'] + to_update:append('tp') + end + if stats.hpp ~= packet['HPP'] then + if math.floor(stats.hpp/25) ~= math.floor(packet['HPP']/25) then + local color=_settings.primitives.hp_bar[choose_color(packet['HPP'])] + windower.prim.set_color('phpp'..position_lookup[id],color.a,color.r,color.g,color.b) + end + stats.hpp = packet['HPP'] + to_update:append('hpp') + windower.prim.set_size('phpp'..position_lookup[id],150/100*stats['hpp'],h) + end + if stats.mpp ~= packet['MPP'] then + stats.mpp = packet['MPP'] + windower.prim.set_size('pmpp'..position_lookup[id],150/100*stats['mpp'],5) + end + + update_macro_data(id,to_update) + elseif id == 0x076 then + for i = 0,4 do + local id = data:unpack('I', i*48+5) + + if id == 0 then + break + elseif position_lookup[id] then + local packet_buffs = L{} + local packet_debuffs = L{} + local buff + + for j = 1,32 do + buff = data:byte(i*48+5+16+j-1) + 256*( math.floor( data:byte(i*48+5+8+ math.floor((j-1)/4)) / 4^((j-1)%4) )%4) -- Credit: Byrth, GearSwap + + if buff == 255 then + break + elseif tracked_buffs[1][buff] then + packet_buffs:append(buff) + elseif tracked_buffs[2][buff] then + packet_debuffs:append(buff) + end + end + + draw_buff_display(packet_buffs, id, 1) + draw_buff_display(packet_debuffs, id, 2) + + stat_table[id].buffs[1] = packet_buffs + stat_table[id].buffs[2] = packet_debuffs + end + end + elseif id == 0x0DD then + local packet = packets.parse('incoming',data) + local id = packet['ID'] + if not position_lookup[id] then return end + local pos_tostring = tostring(position_lookup[id]) + if packet['Zone'] ~= 0 then + if not out_of_zone[id] then + remove_macro_information(pos_tostring,false) + out_of_zone[id] = true + seeking_information[id] = true + end + if who_am_i[id] then + stat_table[id].name = packet['Name'] + windower.text.set_text("name"..pos_tostring,prepare_names(packet['Name'])) + who_am_i[id] = nil + update_name_map(id,packet['Name']) + end + elseif is_zoning or seeking_information[packet['ID']] then + local to_update = L{} + local stats = stat_table[id] + stats.hp = packet['HP'] + to_update:append('hp') + stats.mp = packet['MP'] + to_update:append('mp') + stats.tp = packet['TP'] + to_update:append('tp') + local color=_settings.primitives.hp_bar[choose_color(packet['HP%'])] + windower.prim.set_color('phpp'..pos_tostring,color.a,color.r,color.g,color.b) + stats.hpp = packet['HP%'] + to_update:append('hpp') + windower.prim.set_size('phpp'..pos_tostring,150/100*stats['hpp'],h) + stats.mpp = packet['MP%'] + windower.prim.set_size('pmpp'..pos_tostring,150/100*stats['mpp'],5) + update_macro_data(id,to_update) + if who_am_i[id] then + stats.name = packet['Name'] + windower.text.set_text("name"..pos_tostring,prepare_names(packet['Name'])) + who_am_i[id] = false + update_name_map(id,packet['Name']) + end + seeking_information[id] = false + out_of_zone[id] = false + end + elseif id == 0x0C8 then + local packet = packets.parse('incoming', data) + + local packet_id_struc = { + packet['ID 1'], + packet['ID 2'], + packet['ID 3'], + packet['ID 4'], + packet['ID 5'], + packet['ID 6'], + packet['ID 7'], + packet['ID 8'], + packet['ID 9'], + packet['ID 10'], + packet['ID 11'], + packet['ID 12'], + packet['ID 13'], + packet['ID 14'], + packet['ID 15'], + packet['ID 16'], + packet['ID 17'], + packet['ID 18'] + } + local packet_flag_struc = { + packet['Flags 1'], + packet['Flags 2'], + packet['Flags 3'], + packet['Flags 4'], + packet['Flags 5'], + packet['Flags 6'], + packet['Flags 7'], + packet['Flags 8'], + packet['Flags 9'], + packet['Flags 10'], + packet['Flags 11'], + packet['Flags 12'], + packet['Flags 13'], + packet['Flags 14'], + packet['Flags 15'], + packet['Flags 16'], + packet['Flags 17'], + packet['Flags 18'] + } + local packet_pt_struc = {S{},S{},S{}} + for i = 1,18 do + if packet_id_struc[i]~=0 then + if bit.band(packet_flag_struc[i],2) == 2 then + if bit.band(packet_flag_struc[i],1) == 1 then --Flags + packet_pt_struc[3]:add(packet_id_struc[i]) --0b0000 Solo (trusts) + else --0b0001 Party A + packet_pt_struc[1]:add(packet_id_struc[i]) --0b0010 Party B + end --0b0011 Party C + elseif bit.band(packet_flag_struc[i],1) == 1 then --The order of the parties + packet_pt_struc[2]:add(packet_id_struc[i]) --is not determined by which + else --party contains the player + packet_pt_struc[1]:add(packet_id_struc[i]) + end + end + end + + if packet_pt_struc[3]:contains(player_id) then + packet_pt_struc[1],packet_pt_struc[3] = packet_pt_struc[3],packet_pt_struc[1] + elseif packet_pt_struc[2]:contains(player_id) then + packet_pt_struc[1],packet_pt_struc[2] = packet_pt_struc[2],packet_pt_struc[1] + end + + if packet_pt_struc[2]:length() == 0 then + packet_pt_struc[2],packet_pt_struc[3] = packet_pt_struc[3],packet_pt_struc[2] + end + new_members(packet_pt_struc) + end + end) + zone_change_event = windower.register_event('zone change', function() + if not is_hidden then + for key in pairs(saved_prims - (macro[1] + macro[2] + macro[3])) do + windower.prim.set_visibility(key,prim_coordinates.visible[key]) + end + for key in pairs(saved_texts - (macro[1] + macro[2] + macro[3])) do + windower.text.set_visibility(key,text_coordinates.visible[key]) + end + end + is_zoning = false + if windower.ffxi.get_info().logged_in then + stat_table[player_id].index = windower.ffxi.get_player().index + end + end) + else + windower.unregister_event(keyboard_event) + windower.unregister_event(mouse_event) + windower.unregister_event(incoming_chunk_event) + windower.unregister_event(outgoing_chunk_event) + windower.unregister_event(zone_change_event) + end +end +end diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/ReadMe.md b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/ReadMe.md new file mode 100644 index 0000000..36fb810 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/ReadMe.md @@ -0,0 +1,51 @@ +#Nostrum + +Creates a click-able onscreen macro to help avoid targeting issues while curing. (MsJans clone) +MsJans was originally written by Janice (BG), was further developed by Ragns (BG), and was most recently maintained by Arcon. + +### Settings +The color, contents, and position of the macro can be modified by editing the Nostrum/data/settings.xml file. + +### Using the Macro +The macro consists of two basic units: a list of your current party members, and a palette of cure spells. These automatically resize when the party structure changes. However, in order to avoid constant resizing during bard rotations and other busy moments, the macro does not automatically shrink when members leave the party. It can be manually resized by using the 'cut' command. + +To use the macro, click on the appropriate region of the display. + + +####Left Click + +Region | Action +------ | ------ +Status Removal Icons | Casts the corresponding spell on `'<t>'` +Buff Icons | Casts the corresponding spell on `'<t>'` +Party Lists | Targets the corresponding party member +Cure Palette | Casts the corresponding cure on the party member + +####Right Click + +Region | Action +------ | ------ +Status Removal Icons | Saves the corresponding spell to the right-click button +Buff Icons | Saves the corresponding spell to the right-click button +Party Lists | Casts the saved spell on the corresponding party member + +### Commands + +command(shortcut) + +#####Abbreviation: //nos +1. help(h): + - Prints a list of these commands in the console. +2. refresh(r): + - Compares the macro's current party structures to the party structure in memory. Adds new members and removes any old members (trusts). Only people nearby you will be added to the macro, and current party members who are not nearby will be removed. +3. hide(h): + - Toggles the macro's visibility. +4. cut(c): + - Trims the macro down to size, removing blank spaces. +5. send(s) <name>: + - Requires send addon. Sends commands to the character whose name was provided. If no name was provided, send settings will reset and Nostrum will function normally. +6. profile(p) <name>: + - Loads a new profile from the settings file. + +###Issues +1.Loading profiles in a busy area may be a bad idea.
\ No newline at end of file diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/helperfunctions.lua b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/helperfunctions.lua new file mode 100644 index 0000000..663d657 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/helperfunctions.lua @@ -0,0 +1,783 @@ +--[[Copyright © 2014-2015, trv +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 Nostrum 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 trv 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.--]] + +function prim_simple(name,settings_table,pos_x,pos_y,width,height) + windower.prim.create(name) + windower.prim.set_position(name,pos_x,pos_y) + windower.prim.set_size(name,width,height) + windower.prim.set_color(name,settings_table.color.a,settings_table.color.r,settings_table.color.g,settings_table.color.b) + windower.prim.set_visibility(name, not is_hidden and settings_table.visible) + saved_prims:add(name) + prim_coordinates.x[name]=pos_x + prim_coordinates.y[name]=pos_y + prim_coordinates.visible[name]=settings_table.visible + prim_coordinates.a[name]=settings_table.color.a + prim_coordinates.r[name]=settings_table.color.r + prim_coordinates.g[name]=settings_table.color.g + prim_coordinates.b[name]=settings_table.color.b +end + +function img_simple(name,texture,pos_x,pos_y) + windower.prim.create(name) + windower.prim.set_position(name,pos_x,pos_y) + windower.prim.set_size(name,25,25) + windower.prim.set_visibility(name,not is_hidden) + windower.prim.set_fit_to_texture(name, false) + windower.prim.set_texture(name, texture) + saved_prims:add(name) + prim_coordinates.x[name]=pos_x + prim_coordinates.y[name]=pos_y + prim_coordinates.visible[name]=true +end + +function text_simple(name, settings_table, pos_x, pos_y, text) + windower.text.create(name) + windower.text.set_color(name, settings_table.color.a, settings_table.color.r, settings_table.color.g, settings_table.color.b) + windower.text.set_bold(name,settings_table.bold) + windower.text.set_font(name,settings_table.font) + windower.text.set_font_size(name,settings_table.font_size) + windower.text.set_location(name, pos_x, pos_y) + windower.text.set_right_justified(name,settings_table.right_justified) + windower.text.set_text(name,text) + windower.text.set_visibility(name, not is_hidden and settings_table.visible) + saved_texts:add(name) + text_coordinates.x[name]=pos_x + text_coordinates.y[name]=pos_y + text_coordinates.visible[name]=settings_table.visible +end + +function count_cures(t) + for i=options.cures.n,1,-1 do + if t[options.cures[i]] then + macro_order[2]:append(xml_to_lua[options.cures[i]]) + end + macro_order[3] = macro_order[2] + end + macro_order[1] = macro_order[2]:copy(false) + for i=options.curagas.n,1,-1 do + if t[options.curagas[i]] then + macro_order[1]:append(xml_to_lua[options.curagas[i]]) + end + end +end + +function count_na(t) + for i=1,options.na['n'] do + if t[options.na[i]] then + macro_order[4]:append(xml_to_lua[options.na[i]]) + end + end + if macro_order[4].n ~= 0 then + mouse_map2:append(T(macro_order[4])) + end +end + +function count_buffs(t) + for i=1,options.buffs['n'] do + if t[options.buffs[i]] then + macro_order[5]:append(xml_to_lua[options.buffs[i]]) + end + end + if macro_order[5].n ~= 0 then + mouse_map2:append(T(macro_order[5])) + end +end + +function choose_color(hpp) + if hpp >= 75 then + return 'green' + elseif hpp >= 50 + then return 'yellow' + elseif hpp >= 25 then + return 'orange' + else + return 'red' + end +end + +function prepare_names(s) + if string.len(s)>10 then + return(string.sub(s,1,10)..'.') + else + return(s) + end +end + +function merge_user_file_and_settings(t,u) + for k,v in pairs(t) do + if u[k] then + if type(u[k]) == 'table' then + u[k] = merge_user_file_and_settings(t[k],u[k]) + end + else + u[k] = v + end + end + return u +end + +function indicate_distance(bool,n,x,y) + if bool then --Invisible conflict? + out_of_view[n] = true + if not out_of_range[n] then + out_of_range[n] = true + windower.text.set_color('name'..tostring(n), 255, 175, 98, 177) + end + elseif ((position[1][6] - x)^2 + (position[2][6] - y)^2) > 441 then + out_of_view[n] = false + if not out_of_range[n] then + out_of_range[n] = true + windower.text.set_color('name'..tostring(n), 255, 175, 98, 177) + end + elseif out_of_range[n] then + out_of_view[n] = false + out_of_range[n] = false + windower.text.set_color('name'..tostring(n), 255, 255, 255, 255) + end +end + +function remove_macro_information(s,bool) + windower.text.set_text('hp'..s,'') + windower.text.set_text('mp'..s,'') + windower.text.set_text('tp'..s,'') + windower.text.set_text('hpp'..s,'') + windower.text.set_text('mpp'..s,'') + windower.prim.set_size('phpp'..s,0,h) + windower.prim.set_size('pmpp'..s,0,5) + if bool then + windower.text.set_text('name'..s,'') + end +end + +function wrecking_ball() + for i = 1,18 do + prims_by_layer[i]:clear() + texts_by_layer[i]:clear() + end + misc_hold_for_up.texts:clear() + misc_hold_for_up.prims:clear() + for i = 1,3 do + macro[i]:clear() + end + for key in pairs(saved_texts) do + windower.text.delete(key) + saved_texts:remove(key) + end + for key in pairs(saved_prims) do + windower.prim.delete(key) + saved_prims:remove(key) + end + for i=1,5 do + macro_order[i]:clear() + end + mouse_map2:clear() +end + +function toggle_visibility() + is_hidden = not is_hidden + if is_hidden then + for key in pairs(saved_prims) do + if prim_coordinates.visible[key] then + windower.prim.set_visibility(key,false) + end + end + for key in pairs(saved_texts) do + if text_coordinates.visible[key] then + windower.text.set_visibility(key,false) + end + end + else + for key in pairs(saved_prims) do + windower.prim.set_visibility(key,prim_coordinates.visible[key]) + end + for key in pairs(saved_texts) do + windower.text.set_visibility(key,text_coordinates.visible[key]) + end + end + toggle_buff_visibility(not is_hidden) +end + +function toggle_buff_visibility(b) + local party = party[1] + for i = 1, party.n do + local id = party[i] + local buffs = stat_table[id].buffs[1] + local debuffs = stat_table[id].buffs[2] + local prims = buff_map[position_lookup[id]] + + for j = 1, buffs.n do + prims[1][j]:visible(b) + end + for j = 1, debuffs.n do + prims[2][j]:visible(b) + end + end +end + +function toggle_macro_visibility(n) + macro_visibility[n] = not macro_visibility[n] + if macro_visibility[n] then + for key in pairs(macro[n]) do + if saved_prims:contains(key) then + windower.prim.set_visibility(key,prim_coordinates.visible[key]) + else + windower.text.set_visibility(key,text_coordinates.visible[key]) + end + end + else + for key in pairs(macro[n]) do + if saved_prims:contains(key) then + windower.prim.set_visibility(key,false) + else + windower.text.set_visibility(key,false) + end + end + end + if n == 1 then + toggle_buff_visibility(not macro_visibility[1]) + end +end + +function switch_profiles() + wrecking_ball() + count_cures(profile) + count_na(profile) + count_buffs(profile) + coroutine.sleep(1) + build_macro() + define_active_regions() + last_index=-1 +end + +function image_row(t,x_start,y_start) + local s + for i = 1,t.n do + s = t[i] + prim_simple('p' .. s,_settings.primitives.buff_buttons,x_start-26*i-152,y_start,26,26) + img_simple(s..'i',windower.windower_path.."/plugins/icons/"..options.images[s],x_start-26*i-152,y_start) + text_simple(s, _settings.text.buffs, x_start-26*i-152, y_start, options.aliases[s]) + misc_hold_for_up.texts:append(s) + misc_hold_for_up.prims:extend({s..'i','p' .. s}) + macro[1]:add(s) + macro[1]:add(s..'i') + macro[1]:add('p' .. s) + windower.text.set_stroke_color(s, 255, 0, 0, 0) + windower.text.set_stroke_width(s, 1) + end +end + +function prim_rose(t,pos,x_start,y_start,n) --Pun! + local spell + local s + local prim = _settings.primitives.buttons + local text = _settings.text.buttons + + for i = 1,t.n do + spell = t[i] + s = spell .. tostring(pos) + prim_simple('p' .. s,prim,x_start-(i)*(w+1)+1-153,y_start,w,h) + text_simple(s, text, x_start-(i)*(w+1)+1+((w-font_widths[options.aliases[spell]])/2)-153, y_start, options.aliases[spell]) + prims_by_layer[pos]:append('p' .. s) + texts_by_layer[pos]:append(s) + macro[n]:add('p' .. s) + macro[n]:add(s) + if not macro_visibility[n] then + windower.prim.set_visibility('p' .. s,false) + windower.text.set_visibility(s,false) + end + end +end + +last_hpp=0 +last_index=-1 +function update_target(mob) + if not mob or mob.index == 0 then + if prim_coordinates.visible['target'] then + windower.prim.set_visibility("target_background",false) + windower.prim.set_visibility("target",false) + windower.text.set_visibility("targethpp",false) + windower.text.set_visibility("target_name",false) + text_coordinates.visible["targethpp"]=false + text_coordinates.visible["target_name"]=false + prim_coordinates.visible["target_background"]=false + prim_coordinates.visible["target"]=false + end + last_index = 0 + else + if not prim_coordinates.visible['target'] and not is_hidden then + windower.prim.set_visibility("target_background",true) + windower.prim.set_visibility("target",true) + windower.text.set_visibility("targethpp",true) + windower.text.set_visibility("target_name",true) + text_coordinates.visible["targethpp"]=true + text_coordinates.visible["target_name"]=true + prim_coordinates.visible["target_background"]=_settings.primitives.hp_bar_background.visible + prim_coordinates.visible["target"]=true + end + if mob.index ~= last_index then + windower.text.set_text("target_name",string.sub(mob.name,1,20)) + last_index = mob.index + end + if mob.hpp ~= last_hpp then + update_target_hp(mob.hpp) + end + end +end + +function update_target_hp(hpp) + if hpp~=last_hpp then + windower.text.set_text("targethpp",tostring(hpp)) + windower.prim.set_size("target",150/100*hpp,30) + if math.floor(hpp/25) ~= math.floor(last_hpp/25) then + local color=_settings.primitives.hp_bar[choose_color(hpp)] + windower.prim.set_color("target",color.a,color.r,color.g,color.b) + end + end + last_hpp = hpp +end + +function compare_alliance_to_memory() + local alliance_keys = {'p5', 'p4', 'p3', 'p2', 'p1', 'p0', 'a15', 'a14', 'a13', 'a12', 'a11', 'a10', 'a25', 'a24', 'a23', 'a22', 'a21', 'a20'} + local alliance_clone = windower.ffxi.get_party() + local ally_id=(table.keyset(alliance_clone)) + local party1 = (party_keys * ally_id) + local party2 = (party_two_keys * ally_id) + local party3 = (party_three_keys * ally_id) + local names = {} + local packet_pt_struc = {S{},S{},S{}} + for i=1,18 do + if ally_id[alliance_keys[i]] and alliance_clone[alliance_keys[i]].mob then + names[alliance_clone[alliance_keys[i]].mob.id]=alliance_clone[alliance_keys[i]].mob.name + end + if party1[alliance_keys[i]] and alliance_clone[alliance_keys[i]].mob then + packet_pt_struc[1]:add(alliance_clone[alliance_keys[i]].mob.id) + elseif party2[alliance_keys[i]] and alliance_clone[alliance_keys[i]].mob then + packet_pt_struc[2]:add(alliance_clone[alliance_keys[i]].mob.id) + elseif party3[alliance_keys[i]] and alliance_clone[alliance_keys[i]].mob then + packet_pt_struc[3]:add(alliance_clone[alliance_keys[i]].mob.id) + end + end + new_members(packet_pt_struc) + for k,v in pairs(names) do + if who_am_i[k] then + windower.text.set_text('name'..position_lookup[k],prepare_names(v)) + stat_table[k].name = v + who_am_i[k] = nil + update_name_map(k,v) + end + end +end + +function new_members(packet_pt_struc) -- snippet from invite, reused in c_a_t_m + local p = {S(party[1]),S(party[2]),S(party[3])} + local to_kick = p[1] + p[2] + p[3] - (packet_pt_struc[3] + packet_pt_struc[2] + packet_pt_struc[1]) + for k in pairs(to_kick) do + kick(k,math.ceil(position_lookup[k]/6)) + end + for i=1,3 do + local to_invite = packet_pt_struc[i] - p[i] + for k in pairs(to_invite) do + invite(k,i) + end + end + define_active_regions() +end + +function invite(id,n) + local prim = _settings.primitives + local text = _settings.text + local x_start=_settings.window.x_res-1-_defaults.window.x_offset + party[n]:append(id) + local ptn = party[n].n + position_lookup[id] = 1 + 6 * n - ptn + local pos_id = position_lookup[id] + stat_table[id]={hp=0,mp=0,mpp=0,hpp=0,name='???',tp=0,buffs={{n = 0},{n = 0}}} + seeking_information[id] = true + who_am_i[id] = true + local m = tostring(n) + local pos_tostring = tostring(pos_id) + if vacancies[n] == 0 then + lift_macro(n) + if not saved_prims:contains('BG'..m) then + local y_start = prim_coordinates.y['BG'..tostring(n-1)]-(175-75*(n-1))-ptn*(h+1) + prim_simple('BG'..m,prim.background,x_start-macro_order[n].n*(w+1)-153,y_start,macro_order[n].n*(w+1)+1,ptn*(h+1)+1) + prim_simple("info"..m,prim.hp_bar_background,x_start-152,y_start,152,ptn*(h+1)+1) + macro[n]:add('BG'..m) + if not macro_visibility[n] then + windower.prim.set_visibility('BG'..m,false) + end + else + windower.prim.set_size('info'..m,152,ptn*(h+1)+1) + windower.prim.set_size('BG'..m,macro_order[n].n*(w+1)+1,ptn*(h+1)+1) + end + local y_start = prim_coordinates.y['BG'..m]+1+(h+1)*(ptn-1) + prim_rose(macro_order[n],pos_id,x_start,y_start,n) + prim_simple("phpp"..pos_tostring,prim.hp_bar,x_start-151,y_start,150,h) + prim_simple("pmpp"..pos_tostring,prim.mp_bar,x_start-151,y_start+19,150,5) + text_simple("tp"..pos_tostring, text.tp, x_start-151, y_start+11, '') + text_simple("name"..pos_tostring, text.name, x_start-151, y_start-3, stat_table[id].name) + text_simple("hpp"..pos_tostring, text.hpp, x_start, y_start-4, '') + text_simple("hp"..pos_tostring, text.hp, x_start-40, y_start-3, '') + text_simple("mp"..pos_tostring, text.mp, x_start-40, y_start+11,'') + prims_by_layer[pos_id]:extend(L{"phpp" ..pos_tostring,"pmpp" ..pos_tostring}) + texts_by_layer[pos_id]:extend(L{"tp" ..pos_tostring,"name" ..pos_tostring,"hpp" ..pos_tostring,"hp" ..pos_tostring,"mp" ..pos_tostring}) + else + vacancies[n] = vacancies[n]-1 + windower.text.set_text('name'..pos_id,stat_table[id].name) + end + local pos = windower.ffxi.get_mob_by_id(id) + if pos then + position[1][pos_id] = pos.x + position[2][pos_id] = pos.y + indicate_distance(false,pos_id,pos.x,pos.y) + elseif not out_of_view[pos_id] then + indicate_distance(true,pos_id) + end +end + +function lift_macro(n) + if n == 1 then + up(misc_hold_for_up.texts) + up(misc_hold_for_up.prims) + end + for k=n,3 do + if saved_prims:contains("BG" .. tostring(k)) then + up("BG" .. tostring(k)) + up("info" .. tostring(k)) + end + end + for j=6*n-party[n].n+1,18 do--+2? + up(prims_by_layer[j]) + up(texts_by_layer[j]) + end +end + +function up(t) + if not t then return end + if class(t) == 'List' then + for i=1,t.n do + if saved_prims:contains(t[i]) then + windower.prim.set_position(t[i],prim_coordinates.x[t[i]],prim_coordinates.y[t[i]]-25) + prim_coordinates.y[t[i]]=prim_coordinates.y[t[i]]-25 + elseif saved_texts:contains(t[i]) then + windower.text.set_location(t[i],text_coordinates.x[t[i]],text_coordinates.y[t[i]]-25) + text_coordinates.y[t[i]]=text_coordinates.y[t[i]]-25 + elseif class(t[i]) == 'Prim' then + t[i]:up(25) + end + end + elseif type(t) == 'table' then + for _,v in pairs(t) do + if saved_prims:contains(v) then + windower.prim.set_position(v,prim_coordinates.x[v],prim_coordinates.y[v]-25) + prim_coordinates.y[v]=prim_coordinates.y[v]-25 + elseif saved_texts:contains(v) then + windower.text.set_location(v,text_coordinates.x[v],text_coordinates.y[v]-25) + text_coordinates.y[v]=text_coordinates.y[v]-25 + elseif class(v) == 'Prim' then + v:up(25) + end + end + else + if saved_prims:contains(t) then + windower.prim.set_position(t,prim_coordinates.x[t],prim_coordinates.y[t]-25) + prim_coordinates.y[t]=prim_coordinates.y[t]-25 + elseif saved_texts:contains(t) then + windower.text.set_location(t,text_coordinates.x[t],text_coordinates.y[t]-25) + text_coordinates.y[t]=text_coordinates.y[t]-25 + end + end +end + +function lower_macro(n) + if n == 1 then + down(misc_hold_for_up.texts) + down(misc_hold_for_up.prims) + end + for k=n,3 do + if saved_prims:contains("BG" .. k) then + down("BG" .. tostring(k)) + down("info" .. tostring(k)) + end + end + for j=6*n-party[n].n+1,18 do + down(prims_by_layer[j]) + down(texts_by_layer[j]) + end +end + +function down(periscope) + if not periscope then return end + if class(periscope) == 'list' then + for i=1,periscope.n do + if saved_prims:contains(i) then + windower.prim.set_position(i,prim_coordinates.x[i],prim_coordinates.y[i]+25) + prim_coordinates.y[i]=prim_coordinates.y[i]+25 + elseif saved_texts:contains(i) then + windower.text.set_location(i,text_coordinates.x[i],text_coordinates.y[i]+25) + text_coordinates.y[i]=text_coordinates.y[i]+25 + elseif class(i) == 'Prim' then + i:down(25) + end + end + elseif type(periscope) == 'table' then + for _,v in pairs(periscope) do + if saved_prims:contains(v) then + windower.prim.set_position(v,prim_coordinates.x[v],prim_coordinates.y[v]+25) + prim_coordinates.y[v]=prim_coordinates.y[v]+25 + elseif saved_texts:contains(v) then + windower.text.set_location(v,text_coordinates.x[v],text_coordinates.y[v]+25) + text_coordinates.y[v]=text_coordinates.y[v]+25 + elseif class(v) == 'Prim' then + v:down(25) + end + end + else + if saved_prims:contains(periscope) then + windower.prim.set_position(periscope,prim_coordinates.x[periscope],prim_coordinates.y[periscope]+25) + prim_coordinates.y[periscope]=prim_coordinates.y[periscope]+25 + elseif saved_texts:contains(periscope) then + windower.text.set_location(periscope,text_coordinates.x[periscope],text_coordinates.y[periscope]+25) + text_coordinates.y[periscope]=text_coordinates.y[periscope]+25 + end + end +end + +function trim_macro() + for j = 1,3 do + for i = 6*j-party[j].n,1+6*(j-1),-1 do + local prim = prims_by_layer[i] + for k=1,prim.n do + if class(prim[k]) == 'Prim' then + prim[k]:destroy() + else + windower.prim.delete(prim[k]) + saved_prims:remove(prim[k]) + prim_coordinates.x[prim[k]]=nil + prim_coordinates.y[prim[k]]=nil + macro[j]:remove(prim[k]) + end + end + local text = texts_by_layer[i] + for k=1,text.n do + windower.text.delete(text[k]) + saved_texts:remove(text[k]) + text_coordinates.x[text[k]]=nil + text_coordinates.y[text[k]]=nil + macro[j]:remove(text[k]) + end + if prim.n ~= 0 or text.n ~= 0 then + lower_macro(j) + end + prims_by_layer[i]:clear() + texts_by_layer[i]:clear() + end + if saved_prims:contains('BG'..tostring(j)) then + local s1 = 'BG'..tostring(j) + local s2 = 'info'..tostring(j) + if party[j].n == 0 then + windower.prim.delete(s1) + windower.prim.delete(s2) + saved_prims:remove(s1) + saved_prims:remove(s2) + macro[j]:remove(s1) + misc_hold_for_up.prims:delete(s1) + misc_hold_for_up.prims:delete(s2) + else + windower.prim.set_size(s1,macro_order[j].n*(w+1)+1,party[j].n*(h+1)+1) + windower.prim.set_size(s2,152,party[j].n*(h+1)+1) + end + end + end + vacancies={0,0,0} + define_active_regions() +end + +function update_macro_data(id,t) + for i=1,t:length() do + windower.text.set_text(t[i]..tostring(position_lookup[id]),tostring(stat_table[id][t[i]])) + end +end + +function kick(id,n) + local i = position_lookup[id] + + if i < 6 then + local party = party[1] + local last = party[party.n] + + for k = 1, 2 do + local prim = buff_map[position_lookup[last]][k] + for j = 1, stat_table[last].buffs[k].n do + prim[j]:hide() + end + end + + for j = party.n, 8 - i, -1 do + draw_buff_display(stat_table[party[j]].buffs[1], party[j - 1], 1) + draw_buff_display(stat_table[party[j]].buffs[2], party[j - 1], 1) + end + end + + party[n]:remove(6*n+1-i) + local j = 6*(n)-party[n].n + vacancies[n] = vacancies[n] + 1 + + while i > j do + local m = 6*n+1-i + local m_id = party[n][m] + local pos_tostring = tostring(i) + + position_lookup[m_id] = position_lookup[m_id] + 1 + update_macro_data(m_id,L{'tp','hp','mp','hpp','mpp'}) + windower.text.set_text('name'..pos_tostring,prepare_names(stat_table[m_id]['name']))--shouldn't send name to update_macro... since it won't truncate + local color=_settings.primitives.hp_bar[choose_color(stat_table[m_id].hpp)] + windower.prim.set_color('phpp'..pos_tostring,color.a,color.r,color.g,color.b) + windower.prim.set_size('phpp'..pos_tostring,150/100*stat_table[m_id]['hpp'],h) + windower.prim.set_size('pmpp'..pos_tostring,150/100*stat_table[m_id]['mpp'],5) + if out_of_range[i] and not out_of_range[i-1] then + windower.text.set_color('name' .. tostring(i), 255, 255, 255, 255) + end + if out_of_range[i-1] and not out_of_range[i] then + windower.text.set_color('name' .. tostring(i), 255, 175, 98, 177) + end + out_of_range[i] = out_of_range[i-1] + out_of_view[i] = out_of_view[i-1] + position[1][i] = position[1][i-1] + position[2][i] = position[2][i-1] + + i = i - 1 + end + + remove_macro_information(tostring(i),true) + stat_table[id] = nil + out_of_zone[id] = nil + who_am_i[id] = nil + seeking_information[id] = nil + position_lookup[id] = nil +end + +function draw_buff_display(t, id, type) + local p_id = position_lookup[id] + local buffs = stat_table[id].buffs[type] + + for i = 1, t.n do + if t[i] ~= buffs[i] then + local prim = buff_map[p_id][type] + + if not prim[i] then + local hpp_string = 'phpp'..tostring(p_id) + prim[i] = prims.new({ + pos = {prim_coordinates.x[hpp_string] - 1 - 12 * i, prim_coordinates.y[hpp_string] + (type == 2 and 12 or 0)}, + w = 12, + color = color_over_texture[t[i]], + h = 12, + visible = not is_hidden and not macro_visibility[1], + set_texture = true, + texture = tracked_buffs[type][t[i]], + fit_texture = false, + }) + prims_by_layer[p_id]:append(prim[i]) + else + prim[i]:texture(tracked_buffs[type][t[i]]) + if color_over_texture[t[i]] then + prim[i]:argb(unpack(color_over_texture[t[i]])) + else + prim[i]:argb(255, 255, 255, 255) + end + prim[i]:visible(not macro_visibility[1]) + end + end + end + for i = t.n + 1, buffs.n do + buff_map[p_id][type][i]:hide() + end +end + +function update_name_map(id,name) + local pos_id = position_lookup[id] + if pos_id < 7 then + region_to_name_map[pos_id-(6-(party[1].n+vacancies[1]))] = name + elseif pos_id < 13 then + region_to_name_map[party[1].n+vacancies[1]+pos_id-6-(6-(party[2].n+vacancies[2]))+4] = name + elseif pos_id < 19 then + region_to_name_map[party[1].n+vacancies[1]+party[2].n+vacancies[2]+pos_id-12-(6-(party[3].n+vacancies[3]))+5] = name + end +end + +function define_active_regions() + mouse_map=T{} + region_to_name_map=T{} + position_to_region_map=T{} + local copy={{},{},{}} -- lists accept negative indices + for j = 1,3 do + for i = 1,macro_order[j].n do + copy[j][i] = macro_order[j][i] + end + end + for i = 1,vacancies[1] do + mouse_map:append(false) + region_to_name_map:append(false) + position_to_region_map:append(false) + end + for i = 1,party[1].n do + mouse_map:append(copy[1]) + region_to_name_map:append(stat_table[party[1][party[1].n-i+1]].name) + position_to_region_map:append(1) + end + for i = 1,4 do + mouse_map:append(false) + region_to_name_map:append(false) + position_to_region_map:append(false) + end + for i = 1,vacancies[2] do + mouse_map:append(false) + region_to_name_map:append(false) + position_to_region_map:append(false) + end + for i = 1,party[2].n do + mouse_map:append(copy[2]) + region_to_name_map:append(stat_table[party[2][party[2].n-i+1]].name) + position_to_region_map:append(2) + end + mouse_map:append(false) + region_to_name_map:append(false) + position_to_region_map:append(false) + for i = 1,vacancies[3] do + mouse_map:append(false) + region_to_name_map:append(false) + position_to_region_map:append(false) + end + for i = 1,party[3].n do + mouse_map:append(copy[3]) + region_to_name_map:append(stat_table[party[3][party[3].n-i+1]].name) + position_to_region_map:append(3) + end +end + +function bit.is_set(val, pos) -- Credit: Arcon + return bit.band(val, 2^(pos - 1)) > 0 +end diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/amnesia.png b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/amnesia.png Binary files differnew file mode 100644 index 0000000..a875559 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/amnesia.png diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/bind.png b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/bind.png Binary files differnew file mode 100644 index 0000000..0ab506b --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/bind.png diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/charm.png b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/charm.png Binary files differnew file mode 100644 index 0000000..e2dbdd2 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/charm.png diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/defdown.png b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/defdown.png Binary files differnew file mode 100644 index 0000000..4fc1bb2 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/defdown.png diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/doom.png b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/doom.png Binary files differnew file mode 100644 index 0000000..846a570 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/doom.png diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/embrava.png b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/embrava.png Binary files differnew file mode 100644 index 0000000..d5b392a --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/embrava.png diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/haste.png b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/haste.png Binary files differnew file mode 100644 index 0000000..2fe2109 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/haste.png diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/protect.png b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/protect.png Binary files differnew file mode 100644 index 0000000..db5a74b --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/protect.png diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/regen.png b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/regen.png Binary files differnew file mode 100644 index 0000000..c281f40 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/regen.png diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/reraise.png b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/reraise.png Binary files differnew file mode 100644 index 0000000..19fa2b3 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/reraise.png diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/roll.png b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/roll.png Binary files differnew file mode 100644 index 0000000..fc4244a --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/roll.png diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/shell.png b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/shell.png Binary files differnew file mode 100644 index 0000000..6bc145f --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/shell.png diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/sleep.png b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/sleep.png Binary files differnew file mode 100644 index 0000000..c866580 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/sleep.png diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/slow.png b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/slow.png Binary files differnew file mode 100644 index 0000000..7db572c --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/slow.png diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/song.png b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/song.png Binary files differnew file mode 100644 index 0000000..acdee62 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/song.png diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/sublimation.png b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/sublimation.png Binary files differnew file mode 100644 index 0000000..caf8ae3 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/sublimation.png diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/weakness.png b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/weakness.png Binary files differnew file mode 100644 index 0000000..42005c8 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/weakness.png diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/weight.png b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/weight.png Binary files differnew file mode 100644 index 0000000..685e804 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/icons/weight.png diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/prims.lua b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/prims.lua new file mode 100644 index 0000000..292c4a6 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/prims.lua @@ -0,0 +1,433 @@ +--[[ + A library to facilitate primitive creation and manipulation. +]] + +windower.prim.saved_prims = {} +local prims = {} +local meta = {} + +_libs = _libs or {} +_libs.prims = prims + +_meta = _meta or {} +_meta.Prim = _meta.Prim or {} +_meta.Prim.__class = 'Prim' +_meta.Prim.__index = prims + +--[[ + settings = { + pos = {x,y}, + w = number, + color = {a,r,g,b}, + h = number, + visible = boolean, + image = boolean, + texture = string, + fit = boolean, + tile = {x_rep,y_rep} + } +--]] + +local events = { + left_click = true, + right_click = true, + middle_click = true, + scroll_up = true, + scroll_down = true, + hover = true, + hover_begin = true, + hover_end = true, + drag = true, + right_drag = true, +} + +function prims.new(settings) + local t = {} + settings = settings or {} + settings.pos = settings.pos or {0, 0} + local m = { + color = settings.color and {unpack(settings.color)} or {255, 255, 255, 255}, + width = settings.w or 0, + height = settings.h or 0, + visible = settings.visible or false, + image = settings.set_texture or false, + texture = settings.texture, + fit = settings.fit_texture or false, + tile = settings.tile or {1, 1}, + events = {} + } + m.x1, m.x2 = m.width >= 0 and settings.pos[1], m.width + settings.pos[1] or m.width + settings.pos[1], settings.pos[1] + m.y1, m.y2 = m.height >= 0 and m.height + settings.pos[2], settings.pos[2] or settings.pos[2], m.height + settings.pos[2] + + meta[t] = m + m.name = (_addon and _addon.name or 'prim') .. '_gensym_' .. tostring(t):sub(8) .. '_%.8X':format(16^8 * math.random()):sub(3) + windower.prim.create(m.name) + --defaults for prims seem pointless, but these will prevent errors if people forget information. + + if settings.color then + windower.prim.set_color(m.name, unpack(m.color)) + end + + windower.prim.set_position(m.name, m.x1, m.y2) + windower.prim.set_size(m.name, m.width, m.height) + windower.prim.set_visibility(m.name, m.visible) + + if m.image then + windower.prim.set_fit_to_texture(m.name, m.fit) + windower.prim.set_texture(m.name, m.texture) + if settings.tile then + windower.prim.set_repeat(m.name, unpack(m.tile)) + end + end + + return setmetatable(t, _meta.Prim) +end + +-- Makes the primitive visible +function prims.show(t) + windower.prim.set_visibility(meta[t].name, true) + meta[t].visible = true +end + +-- Makes the primitive invisible +function prims.hide(t) + windower.prim.set_visibility(meta[t].name, false) + meta[t].visible = false +end + +--[[ + The following methods all either set the respective values or return them, if no arguments to set them are provided. +]] + +-- Returns whether or not the prim object is visible +function prims.visible(t, visible) + if visible == nil then + return meta[t].visible + end + windower.prim.set_visibility(meta[t].name, visible) + meta[t].visible = visible +end + +function prims.append_label(t, str) +end + +function prims.pos(t, x, y) + if not y then + return meta[t].width >= 0 and meta[t].x1 or meta[t].x2, + meta[t].height >= 0 and meta[t].y2 or meta[t].y1 + end + + local m = meta[t] + windower.prim.set_position(m.name, x, y) + + m.x1, m.x2 = m.width >= 0 and x, m.width + x or m.width + x, x + m.y1, m.y2 = m.height >= 0 and m.height + y, y or y, m.height + y +end + +function prims.pos_x(t, x) + if not x then + return meta[t].width >= 0 and meta[t].x1 or meta[t].x2 + end + + local m = meta[t] + windower.prim.set_position(m.name, x, meta[t].height >= 0 and m.y2 or m.y1) -- swapped these + + m.x1, m.x2 = m.width >= 0 and x, m.width + x or m.width + x, x +end + +function prims.pos_y(t, y) + if not y then + return meta[t].height >= 0 and meta[t].y2 or meta[t].y1 -- swapped these + end + + local m = meta[t] + windower.prim.set_position(m.name, m.width >= 0 and m.x1 or m.x2, y) + + m.y1, m.y2 = m.height >= 0 and m.height + y, y or y, m.height + y +end + +function prims.right(t, d) + local m = meta[t] + t:pos_x((m.width >= 0 and m.x1 or m.x2) + d) +end + +function prims.left(t, d) + local m = meta[t] + t:pos_x((m.width >= 0 and m.x1 or m.x2) - d) +end + +function prims.up(t, d) + local m = meta[t] + t:pos_y((m.height >= 0 and m.y2 or m.y1) - d) +end + +function prims.down(t, d) + local m = meta[t] + t:pos_y((m.height >= 0 and m.y2 or m.y1) + d) +end + +function prims.width(t, width) + if not width then + return meta[t].width + end + + local m = meta[t] + local w = m.width + + windower.prim.set_size(m.name, width, m.height) + m.width = width + if w * width >= 0 then + if w >= 0 then + m.x2 = m.x1 + width + else + m.x1 = m.x2 + width + end + else + if w >= 0 then + m.x1, m.x2 = m.x2 + width, m.x2 + else + m.x1, m.x2 = m.x1 + width, m.x1 + end + end +end + +local newanimator = function(n) + return function(fn) + while fn() do + coroutine.sleep(n) + end + end +end + +function prims.width_smooth(t, width, time_interval, dwidth) + local m = meta[t] + m.width_actual = width + + if not t.animator then + dwidth = (width - m.width) * dwidth > 0 and dwidth or -dwidth + t.animator = newanimator(time_interval) + t.animator(function() + local n = m.width + dwidth + if dwidth > 0 and n >= m.width_actual or dwidth < 0 and n <= m.width_actual then + t:width(m.width_actual) + t.animator = nil + return false + else + t:width(n) + return true + end + end) + end +end + +function prims.height(t, height) + if not height then + return meta[t].height + end + + local m = meta[t] + local h = m.height + + windower.prim.set_size(m.name, m.width, height) + m.height = height + if h * height >= 0 then + if h >= 0 then + m.y1 = m.y2 + height + else + m.y2 = m.y1 + height + end + else + if h >= 0 then + m.y1, m.y2 = m.y2, m.y2 + height + else + m.y1, m.y2 = m.y1 + height, m.y1 + end + end +end + +function prims.height_smooth(t, height, time_interval, dheight) + local m = meta[t] + m.height_actual = height + + if not t.animator then + dheight = (height - m.height) * dheight > 0 and dheight or -dheight + t.animator = newanimator(time_interval) + t.animator(function() + local n = m.height + dheight + if dheight > 0 and n >= m.height_actual or dheight < 0 and n <= m.height_actual then + t:height(m.height_actual) + t.animator = nil + return false + else + t:height(n) + return true + end + end) + end +end + +function prims.size(t, width, height) + if not height then + return meta[t].width, meta[t].height + end + + local m = meta[t] + local w = m.width + local h = m.height + + if w * width >= 0 then + if w >= 0 then + m.x2 = m.x1 + width + else + m.x1 = m.x2 + width + end + else + if w >= 0 then + m.x1, m.x2 = m.x2 + width, m.x2 + else + m.x1, m.x2 = m.x1 + width, m.x1 + end + end + + if h * height >= 0 then + if h >= 0 then + m.y1 = m.y2 + height + else + m.y2 = m.y1 + height + end + else + if h >= 0 then + m.y1, m.y2 = m.y2, m.y2 + height + else + m.y1, m.y2 = m.y1 + height, m.y1 + end + end + + windower.prim.set_size(m.name, width, height) + m.width, m.height = width, height +end + +function prims.extents(t) + return meta[t].width, meta[t].height +end + +function prims.color(t, red, green, blue) + if not blue then + return unpack(meta[t].color,2,4) + end + + local m = meta[t] + windower.prim.set_color(m.name, m.color[1], red, green, blue) + m.color[2], m.color[3], m.color[4] = red, green, blue +end + +function prims.alpha(t, alpha) + if not alpha then + return meta[t].color[1] + end + local m = meta[t] + windower.prim.set_color(m.name, alpha, m.color[2], m.color[3], m.color[4]) + m.color[1] = alpha +end + +function prims.argb(t, a, r, g, b) + if not b then + return unpack(meta[t].color) + end + + local m = meta[t] + windower.prim.set_color(m.name, a, r, g, b) + m.color[1], m.color[2], m.color[3], m.color[4] = a, r, g, b +end +-- Sets/returns prim transparency. Based on percentage values, with 1 being fully transparent, while 0 is fully opaque. +function prims.transparency(t, alpha) + if not alpha then + return 1 - meta[t].color[1]/255 + end + + alpha = math.floor(255*(1-alpha)) + local m = meta[t] + windower.prim.set_color(m.name, alpha, m.color[2], m.color[3], m.color[4]) + m.color[1] = alpha +end + +function prims.tile(t, x_rep, y_rep) + if not y_rep then + return unpack(meta[t].tile) + end + + local m = meta[t] + windower.prim.set_repeat(m.name, x_rep, y_rep) + m.tile[1], m.tile[2] = x_rep, y_rep +end + +function prims.texture(t, path) + if not path then + return meta[t].texture + end + + windower.prim.set_texture(meta[t].name, path) + meta[t].texture = path +end + +function prims.fit(t, fit) + if fit == nil then + return meta[t].fit + end + + windower.prim.set_fit_to_texture(meta[t].name, fit) + meta[t].fit = fit +end + +function prims.hover(t, x, y) + local m = meta[t] + return (m.x2 >= x + and m.x1 <= x + and m.y1 >= y + and m.y2 <= y) +end + +function prims.destroy(t) + windower.prim.delete(meta[t].name) + meta[t] = nil + t = nil +end + +function prims.get_events(t) + return meta[t].events +end + +function prims.register_event(t, event, fn) + if not events[event] then + error('The event ' .. event .. ' is not available to the ' .. class(t) .. ' class.') + return + end + + local m = meta[t].events + + m[event] = m[event] or {n = 0} + local n = #m[event] + 1 + m[event][n] = fn + m[event].n = m[event].n > n and m[event].n or n + + return n +end + +function prims.unregister_event(t, event, n) + if not (events[event] and meta[t].events[event]) then + return + end + + if type(n) == 'number' then + meta[t].events[event][n] = nil + else + for i = 1, meta[t].events[event].n do + if meta[t].events[event][i] == n then + meta[t].events[event][i] = nil + return + end + end + end +end + +return prims diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/variables.lua b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/variables.lua new file mode 100644 index 0000000..bf7a024 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/Nostrum/variables.lua @@ -0,0 +1,593 @@ +--[[Copyright © 2014-2015, trv +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 Nostrum 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 trv 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.--]] + +w=29 +h=24 +tab_keys={[15]=true,[16]=true,[18]=true,[28]=true,[82]=true,[203]=true,[205]=true,[210]=true,} +spell_default='' +send_string = '' + +saved_prims=S{} +saved_texts=S{} +prims_by_layer={L{},L{},L{},L{},L{},L{},L{},L{},L{},L{},L{},L{},L{},L{},L{},L{},L{},L{}} +texts_by_layer={L{},L{},L{},L{},L{},L{},L{},L{},L{},L{},L{},L{},L{},L{},L{},L{},L{},L{}} +misc_hold_for_up={texts=T{},prims=T{}} +macro = {S{},S{},S{}} +macro_visibility = {[1]=true,[2]=true,[3]=true} +text_coordinates={x=T{},y=T{},visible=T{}} +prim_coordinates={x=T{},y=T{},visible=T{},a=T{},r=T{},g=T{},b=T{}} +party_keys = S{'p0', 'p1', 'p2', 'p3', 'p4', 'p5'} +party_two_keys = S{'a10', 'a11', 'a12', 'a13', 'a14', 'a15'} +party_three_keys = S{'a20', 'a21', 'a22', 'a23', 'a24', 'a25'} +seeking_information={} +macro_order=T{nil,L{},nil,L{},L{}} +mouse_map2=T{} +buff_map={{{},{}},{{},{}},{{},{}},{{},{}},{{},{}},{{},{}},} +vacancies={0,0,0} + +help_text = [[Nostrum command list. +help: Prints a list of these commands in the console. +refresh(r): Compares the macro's current party structures to + - the alliance structure in memory. +hide(h): Toggles the macro's visibility. +cut(c): Trims the macro down to size, removing blank spaces. +profile(p) <name>: Loads a new profile from the settings file. +send(s) <name>: Requires 'send' addon. Sends commands to the + - character whose name is provided. If no name is provided, + - send will reset and commands will be sent to the character + - with Nostrum loaded.]] + +position = { + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +} +out_of_zone={} +out_of_range={ + false,false,false,false,false,false, + false,false,false,false,false,false, + false,false,false,false,false,false, +} +out_of_view={ + false,false,false,false,false,false, + false,false,false,false,false,false, + false,false,false,false,false,false, +} +who_am_i={} + +dragged = false +is_zoning = false +is_hidden = false + +font_widths={ + ['I']=9,['II']=17,['III']=25,['IV']=24,['V']=16, + ['1']=10,['2']=11,['3']=11,['4']=11,['5']=11,['6']=12, + ['˹1˼']=25,['˹2˼']=25,['˹3˼']=25,['˹4˼']=25,['˹5˼']=25, + ['˹I˼']=23,['˹II˼']=31, +} + +tracked_buffs = { + { + [42] = 'regen', + [233] = 'regen', + [539] = 'regen', + [43] = 'regen',-- = 'refresh', + [234] = 'regen',-- = 'refresh', + [541] = 'regen',-- = 'refresh', + [228] = 'embrava', + [580] = 'haste', + [33] = 'haste', + [40] = 'protect', + [41] = 'shell', + [113] = 'reraise', + [600] = 'roll', + [310] = 'roll', + [314] = 'roll', + [318] = 'roll', + [322] = 'roll', + [326] = 'roll', + [334] = 'roll', + [315] = 'roll', + [319] = 'roll', + [323] = 'roll', + [327] = 'roll', + [331] = 'roll', + [312] = 'roll', + [316] = 'roll', + [320] = 'roll', + [324] = 'roll', + [328] = 'roll', + [332] = 'roll', + [581] = 'haste', + [188] = 'sublimation', + [187] = 'sublimation', + [336] = 'roll', + [265] = 'haste', + [339] = 'roll', + [338] = 'roll', + [337] = 'roll', + [313] = 'roll', + [317] = 'roll', + [321] = 'roll', + [325] = 'roll', + [329] = 'roll', + [333] = 'roll', + [335] = 'roll', + [330] = 'roll', + [311] = 'roll', + [193] = 'song', + [197] = 'song', + [201] = 'song', + [205] = 'song', + [209] = 'song', + [213] = 'song', + [221] = 'song', + [198] = 'song', + [202] = 'song', + [206] = 'song', + [210] = 'song', + [214] = 'song', + [218] = 'song', + [222] = 'song', + [195] = 'song', + [199] = 'song', + [203] = 'song', + [207] = 'song', + [211] = 'song', + [215] = 'song', + [219] = 'song', + [196] = 'song', + [200] = 'song', + [208] = 'song', + [212] = 'song', + [216] = 'song', + [220] = 'song', + [223] = 'song', + }, + { + [194] = 'song', + [16] = 'amnesia', + [17] = 'charm', + [11] = 'bind', + [12] = 'weight', + [13] = 'slow', + [14] = 'charm', + [565] = 'slow', + [567] = 'weight', + [15] = 'doom', + [149] = 'defdown', + [558] = 'defdown', + [2] = 'sleep', + [19] = 'sleep', + [26] = 'weakness', + [1] = 'weakness', + } +} + +for k, v in pairs(tracked_buffs[1]) do + tracked_buffs[1][k] = windower.windower_path .. 'addons/Nostrum/icons/' .. v .. '.png' +end +for k, v in pairs(tracked_buffs[2]) do + tracked_buffs[2][k] = windower.windower_path .. 'addons/Nostrum/icons/' .. v .. '.png' +end + +tracked_buffs[2][540] = windower.windower_path .. "\\plugins\\icons\\spells\\00293.png" +tracked_buffs[2][3] = windower.windower_path .. "\\plugins\\icons\\spells\\00293.png" +tracked_buffs[2][4] = windower.windower_path .. "\\plugins\\icons\\spells\\00289.png" +tracked_buffs[2][5] = windower.windower_path .. "\\plugins\\icons\\spells\\00295.png" +tracked_buffs[2][6] = windower.windower_path .. "\\plugins\\icons\\spells\\00290.png" +tracked_buffs[2][7] = windower.windower_path .. "\\plugins\\icons\\spells\\00291.png" +tracked_buffs[2][8] = windower.windower_path .. "\\plugins\\icons\\spells\\00293.png" +tracked_buffs[2][9] = windower.windower_path .. "\\plugins\\icons\\spells\\00292.png" +tracked_buffs[2][15] = windower.windower_path .. "\\plugins\\icons\\spells\\00293.png" +tracked_buffs[2][566] = windower.windower_path .. "\\plugins\\icons\\spells\\00289.png" + +color_over_texture = { + [43] = {255, 255, 100, 255}, + [234] = {255, 255, 100, 255}, + [541] = {255, 255, 100, 255}, + [310] = {255, 208, 132, 124}, --'Fighter\'s Roll', + [314] = {255, 210, 179, 160}, --'Warlock\'s Roll', + [318] = {255, 250, 192, 220}, --'Beast Roll', + [322] = {255, 162, 206, 172}, --'Ninja Roll', + [326] = {255, 230, 233, 122}, --'Corsair\'s Roll', + [334] = {255, 162, 157, 189}, --'Tactician\'s Roll', + [315] = {255, 193, 165, 193}, --'Rogue\'s Roll', + [319] = {255, 97, 92, 83}, --'Choral Roll', + [327] = {255, 205, 125, 200}, --'Puppet Roll', + [316] = {255, 250, 250, 218}, --'Gallant\'s Roll', + [320] = {255, 197, 159, 184}, --'Hunter\'s Roll', + [324] = {255, 141, 202, 141}, --'Evoker\'s Roll', + [328] = {255, 0, 151, 255}, --'Dancer\'s Roll', + [332] = {255, 198, 158, 160}, --'Courser\'s Roll', + [581] = {255, 0, 255, 0}, --'Flurry', + [336] = {255, 217, 196, 213}, --'Miser\'s Roll', + [265] = {255, 0, 255, 0}, --'Flurry', + [338] = {255, 236, 252, 245}, --'Avenger\'s Roll', + [337] = {255, 120, 152, 179}, --'Companion\'s Roll', + [313] = {255, 182, 166, 195}, --'Wizard\'s Roll', + [317] = {255, 202, 66, 1}, --'Chaos Roll', + [321] = {255, 225, 162, 117}, --'Samurai Roll', + [325] = {255, 119, 164, 207}, --'Magus\'s Roll', + [329] = {255, 255, 217, 179}, --'Scholar\'s Roll', + [333] = {255, 240, 227, 179}, --'Blitzer\'s Roll', + [311] = {255, 145, 197, 207}, --'Monk\'s Roll', + [193] = {255, 51, 51, 102}, --'Lullaby' + [197] = {255, 204, 204, 0}, --'Minne', + [201] = {255, 0, 204, 0}, --'Mambo', + [221] = {255, 102, 153, 153}, --'Dirge', + [198] = {255, 204, 51, 51}, --'Minuet', + [214] = {255, 0, 153, 204}, --'March', + [218] = {255, 248, 224, 152}, --'Hymnus', + [222] = {255, 153, 204, 204}, --'Scherzo', + [195] = {255, 0, 102, 204}, --'Paeon', + [199] = {255, 153, 51, 204}, --'Madrigal', + [215] = {255, 153, 131, 102}, --'Etude', + [196] = {255, 0, 153, 0}, --'Ballad', + [200] = {255, 184, 243, 189}, --'Prelude', + [216] = {255, 153, 102, 0}, --'Carol', + [220] = {255, 255, 102, 102}, --'Sirvente', +} + +xml_to_lua = { + ["cure"]="Cure", + ["cureii"]="Cure II", + ["cureiii"]="Cure III", + ["cureiv"]="Cure IV", + ["curev"]="Cure V", + ["curevi"]="Cure VI", + ["curaga"]="Curaga", + ["curagaii"]="Curaga II", + ["curagaiii"]="Curaga III", + ["curagaiv"]="Curaga IV", + ["curagav"]="Curaga V", + ["sacrifice"]="Sacrifice", + ["erase"]="Erase", + ["paralyna"]="Paralyna", + ["silena"]="Silena", + ["blindna"]="Blindna", + ["poisona"]="Poisona", + ["viruna"]="Viruna", + ["stona"]="Stona", + ["cursna"]="Cursna", + ["haste"]="Haste", + ["hasteii"]="Haste II", + ["flurry"]="Flurry", + ["flurryii"]="Flurry II", + ["protect"]="Protect", + ["shell"]="Shell", + ["protectii"]="Protect II", + ["shellii"]="Shell II", + ["protectiii"]="Protect III", + ["shelliii"]="Shell III", + ["protectiv"]="Protect IV", + ["shelliv"]="Shell IV", + ["protectv"]="Protect V", + ["shellv"]="Shell V", + ["refresh"]="Refresh", + ["refreshii"]="Refresh II", + ["regen"]="Regen", + ["regenii"]="Regen II", + ["regeniii"]="Regen III", + ["regeniv"]="Regen IV", + ["regenv"]="Regen V", + ["phalanxii"]="Phalanx II", + ["adloquium"]="Adloquium", + ["animusaugeo"]="Animus Augeo", + ["animusminuo"]="Animus Minuo", + ["embrava"]="Embrava", + ["curingwaltz"]="Curing Waltz", + ["curingwaltzii"]="Curing Waltz II", + ["curingwaltziii"]="Curing Waltz III", + ["curingwaltziv"]="Curing Waltz IV", + ["curingwaltzv"]="Curing Waltz V", + ["divinewaltz"]="Divine Waltz", + ["divinewaltzii"]="Divine Waltz II", + ["healingwaltz"]="Healing Waltz", +} + +prefix={ + ["Blindna"]='/ma', + ["Poisona"]='/ma', + ["Cure III"]='/ma', + ["Curaga V"]='/ma', + ["Sacrifice"]='/ma', + ["Embrava"]='/ma', + ["Curaga II"]='/ma', + ["Stona"]='/ma', + ["Protect III"]='/ma', + ["Shell IV"]='/ma', + ["Curaga IV"]='/ma', + ["Paralyna"]='/ma', + ["Protect"]='/ma', + ["Phalanx II"]='/ma', + ["Protect V"]='/ma', + ["Curaga III"]='/ma', + ["Adloquium"]='/ma', + ["Divine Waltz II"]='/ja', + ["Cure"]='/ma', + ["Divine Waltz"]='/ja', + ["Curing Waltz V"]='/ja', + ["Cure II"]='/ma', + ["Erase"]='/ma', + ["Cure VI"]='/ma', + ["Haste II"]='/ma', + ["Curing Waltz"]='/ja', + ["Animus Augeo"]='/ma', + ["Curing Waltz III"]='/ja', + ["Cure IV"]='/ma', + ["Regen II"]='/ma', + ["Animus Minuo"]='/ma', + ["Curing Waltz IV"]='/ja', + ["Cure V"]='/ma', + ["Regen V"]='/ma', + ["Regen"]='/ma', + ["Refresh"]='/ma', + ["Regen IV"]='/ma', + ["Viruna"]='/ma', + ["Haste"]='/ma', + ["Curing Waltz II"]='/ja', + ["Healing Waltz"]='/ja', + ["Protect IV"]='/ma', + ["Cursna"]='/ma', + ["Silena"]='/ma', + ["Curaga"]='/ma', + ["Shell II"]='/ma', + ["Refresh II"]='/ma', + ["Shell"]='/ma', + ["Protect II"]='/ma', + ["Shell III"]='/ma', + ["Flurry II"]='/ma', + ["Flurry"]='/ma', + ["Regen III"]='/ma', + ["Shell V"]='/ma', + [""]='/echo No spell selected: ', +} + +options={ + cures=L{ + "cure", + "cureii", + "cureiii", + "cureiv", + "curev", + "curevi", + "curingwaltz", + "curingwaltzii", + "curingwaltziii", + "curingwaltziv", + "curingwaltzv", + }, + curagas=L{ + "curaga", + "curagaii", + "curagaiii", + "curagaiv", + "curagav", + "divinewaltz", + "divinewaltzii", + }, + buffs=L{ + "haste", + "hasteii", + "flurry", + "flurryii", + "protect", + "shell", + "protectii", + "shellii", + "protectiii", + "shelliii", + "protectiv", + "shelliv", + "protectv", + "shellv", + "refresh", + "refreshii", + "regen", + "regenii", + "regeniii", + "regeniv", + "regenv", + "phalanxii", + "adloquium", + "animusminuo", + "animusaugeo", + "embrava" + }, + na=L{ + "erase", + "paralyna", + "silena", + "blindna", + "poisona", + "viruna", + "stona", + "cursna", + "sacrifice", + "healingwaltz", + }, + aliases={ + ["Cure"]="1", + ["Cure II"]="2", + ["Cure III"]="3", + ["Cure IV"]="4", + ["Cure V"]="5", + ["Cure VI"]="6", + ["Curaga"]="I", + ["Curaga II"]="II", + ["Curaga III"]="III", + ["Curaga IV"]="IV", + ["Curaga V"]="V", + ["Sacrifice"]="Sac", + ["Erase"]="Eras", + ["Paralyna"]="Para", + ["Silena"]="Slna", + ["Blindna"]="Blnd", + ["Poisona"]="Psna", + ["Viruna"]="Viru", + ["Stona"]="Stna", + ["Cursna"]="Curs", + ["Haste"]="Haste", + ["Haste II"]="Haste", + ["Flurry"]="Flry", + ["Flurry II"]="Flry", + ["Protect"]="Pro", + ["Protect II"]="Pro", + ["Protect III"]="Pro", + ["Protect IV"]="Pro", + ["Protect V"]="Pro", + ["Shell"]="Shl", + ["Shell II"]="Shl", + ["Shell III"]="Shl", + ["Shell IV"]="Shl", + ["Shell V"]="Shl", + ["Refresh"]="Ref", + ["Refresh II"]="Ref", + ["Regen"]="Reg", + ["Regen II"]="Reg", + ["Regen III"]="Reg", + ["Regen IV"]="Reg", + ["Regen V"]="Reg", + ["Phalanx II"]="Phlx", + ["Adloquium"]="TP+", + ["Animus Augeo"]="Enm+", + ["Animus Minuo"]="Enm-", + ["Embrava"]="Embr", + ["Curing Waltz"]="˹1˼", + ["Curing Waltz II"]="˹2˼", + ["Curing Waltz III"]="˹3˼", + ["Curing Waltz IV"]="˹4˼", + ["Curing Waltz V"]="˹5˼", + ["Divine Waltz"]="˹I˼", + ["Divine Waltz II"]="˹II˼", + ["Healing Waltz"]="HW", + }, + images={ + ["Sacrifice"]="spells\\00294.png", + ["Erase"]="spells\\00294.png", + ["Paralyna"]="spells\\00289.png", + ["Silena"]="spells\\00290.png", + ["Blindna"]="spells\\00295.png", + ["Poisona"]="spells\\00293.png", + ["Viruna"]="spells\\00288.png", + ["Stona"]="spells\\00291.png", + ["Cursna"]="spells\\00292.png", + ["Haste"]="spells\\00057.png", + ["Haste II"]="spells\\00358.png", + ["Flurry"]="spells\\00056.png", + ["Flurry II"]="spells\\00357.png", + ["Protect"]="spells\\00043.png", + ["Protect II"]="spells\\00044.png", + ["Protect III"]="spells\\00045.png", + ["Protect IV"]="spells\\00046.png", + ["Protect V"]="spells\\00047.png", + ["Shell"]="spells\\00048.png", + ["Shell II"]="spells\\00049.png", + ["Shell III"]="spells\\00050.png", + ["Shell IV"]="spells\\00051.png", + ["Shell V"]="spells\\00052.png", + ["Refresh"]="spells\\00109.png", + ["Refresh II"]="spells\\00473.png", + ["Regen"]="spells\\00108.png", + ["Regen II"]="spells\\00110.png", + ["Regen III"]="spells\\00111.png", + ["Regen IV"]="spells\\00477.png", + ["Regen V"]="spells\\00504.png", + ["Phalanx II"]="spells\\00107.png", + ["Adloquium"]="spells\\00495.png", + ["Animus Augeo"]="spells\\00308.png", + ["Animus Minuo"]="spells\\00309.png", + ["Embrava"]="spells\\00478.png", + ["Healing Waltz"]="abilities\\00215.png", + }, +} + +settings={ + text={ + buttons={ + bold=true, + font="Times", + visible=true, + font_size=15, + position={x=0,y=0}, + right_justified=false + }, + name={ + bold=true, + font="Consolas", + font_size=10, + position={x=0,y=0}, + right_justified=false + }, + tp={ + bold=true, + font="Consolas", + font_size=10, + position={x=0,y=0}, + right_justified=false + }, + hp={ + bold=true, + font="Consolas", + font_size=10, + right_justified=true + }, + mp={ + bold=true, + font="Consolas", + font_size=10, + right_justified=true + }, + hpp={ + bold=true, + font="Times", + font_size=20, + right_justified=true + }, + na={ + bold=true, + font="Times", + font_size=10, + right_justified=false + }, + buffs={ + bold=true, + font="Times", + font_size=9, + right_justified=false, + }, + }, + primitives={ + hp_bar={ + color={a=176, r=176, g=176, b=176}, + visible=true + }, + }, + window={ + x_res=windower.get_windower_settings().x_res, + y_res=windower.get_windower_settings().y_res, + }, +} |