aukmoo

PetTP

Dec 12th, 2015
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 17.95 KB | None | 0 0
  1. config = require ('config')
  2. texts  = require('texts')
  3. require('pack')
  4.  
  5. _addon.name     = 'PetTP'
  6. _addon.author   = 'SnickySnacks'
  7. _addon.version  = '1.02'
  8. _addon.commands = {'ptp','pettp'}
  9.  
  10. petname            = nil
  11. mypet_idx          = nil
  12. current_hp         = 0
  13. max_hp             = 0
  14. current_mp         = 0
  15. max_mp             = 0
  16. current_hp_percent = 0
  17. current_mp_percent = 0
  18. current_tp_percent = 0
  19. petactive          = false
  20. verbose            = false
  21. superverbose       = false
  22. timercountdown     = 0
  23.  
  24. defaults = T{}
  25.  
  26. defaults.autocolor = true
  27.  
  28. defaults.pos   = T{}
  29. defaults.pos.x = windower.get_windower_settings().x_res*2/3
  30. defaults.pos.y = windower.get_windower_settings().y_res-17
  31.  
  32. defaults.bg         = T{}
  33. defaults.bg.alpha   = 255
  34. defaults.bg.red     = 0
  35. defaults.bg.green   = 0
  36. defaults.bg.blue    = 0
  37. defaults.bg.visible = true
  38.  
  39. defaults.flags        = {}
  40. defaults.flags.right  = false
  41. defaults.flags.bottom = false
  42. defaults.flags.bold   = false
  43. defaults.flags.italic = false
  44.  
  45. defaults.text       = {}
  46. defaults.text.size  = 10
  47. defaults.text.font  = 'Courier New'
  48. defaults.text.alpha = 255
  49. defaults.text.red   = 255
  50. defaults.text.green = 255
  51. defaults.text.blue  = 255
  52.  
  53. settings = config.load(defaults)
  54. pettp    = texts.new(settings)
  55.  
  56. function make_visible()
  57.     petactive = true
  58.     pettp:visible(true);
  59.     if verbose == true then windower.add_to_chat(8, 'PetTP Visible') end
  60. end
  61.  
  62. function make_invisible()
  63.     if petactive then
  64.         pettp:text('')
  65.         pettp:visible(false)
  66.         if verbose == true then windower.add_to_chat(8, 'PetTP Invisible') end
  67.     end
  68.     petactive = false
  69.     mypet_idx = nil
  70.     petname = nil
  71.     current_hp = 0
  72.     max_hp       = 0
  73.     current_mp = 0
  74.     max_mp       = 0
  75.     current_hp_percent = 0
  76.     current_mp_percent = 0
  77.     current_tp_percent = 0
  78. end
  79.  
  80. function valid_pet(source,pet_idx_in, own_idx_in)
  81.     local player = windower.ffxi.get_player()
  82.     if superverbose == true then windower.add_to_chat(8, 'valid_pet('..source..'): petactive: '..tostring(petactive)..', mypet_idx: '..(mypet_idx or 'nil')..', pet_idx_in: '..(pet_idx_in or 'nil')..', own_idx_in: '..(own_idx_in or 'nil')..', player.index '..player.index) end
  83.     if player.vitals.hp == 0 then
  84.         if superverbose == true then windower.add_to_chat(8, 'valid_pet() : false : Player is dead') end
  85.         timercountdown = 0
  86.         return
  87.     end
  88.  
  89.     if petactive then
  90.         if mypet_idx then
  91.             if not pet_idx_in or mypet_idx == pet_idx_in then
  92.                 if superverbose == true then windower.add_to_chat(8, 'valid_pet() : true : using mypet_idx') end
  93.                 return mypet_idx
  94.             else
  95.                 if superverbose == true then
  96.                     windower.add_to_chat(8, 'mypet_idx ~= pet_idx_in '..mypet_idx..' vs. '..pet_idx_in)
  97.                 end
  98.             end
  99.         elseif own_idx_in and player.index == own_idx_in then
  100.             if superverbose == true then windower.add_to_chat(8, 'valid_pet() : true : using pet_idx_in') end
  101.             mypet_idx = pet_idx_in
  102.             return mypet_idx
  103.         end
  104.     end
  105.    
  106.     local pet = windower.ffxi.get_mob_by_target('pet')    
  107.     if pet_idx_in and pet and pet_idx_in ~= pet.index then
  108.         if superverbose == true then windower.add_to_chat(8, 'valid_pet() : false : pet.index ~= pet_idx_in '..pet.index..' vs. '..pet_idx_in) end
  109.         return
  110.     elseif pet_idx_in and player.mob and player.mob.pet_index and pet_idx_in ~= player.mob.pet_index then
  111.         if superverbose == true then windower.add_to_chat(8, 'valid_pet() : false : player.mob.pet_index ~= pet_idx_in '..player.mob.pet_index..' vs. '..pet_idx_in) end
  112.         return
  113.     elseif pet then
  114.         if superverbose == true then windower.add_to_chat(8, 'valid_pet() : true : Using pet.index') end
  115.         mypet_idx = pet.index
  116.         return mypet_idx
  117.     elseif player.mob and player.mob.pet_index then
  118.         if superverbose == true then windower.add_to_chat(8, 'valid_pet() : true : Using player.mob.pet_index') end
  119.         mypet_idx = player.mob.pet_index    
  120.         return mypet_idx
  121.     end
  122.     if superverbose == true then windower.add_to_chat(8, 'valid_pet() : false : No pet found') end
  123.     return
  124. end
  125. function update_pet(source,pet_idx_in,own_idx_in)
  126.     pet_idx = valid_pet(source,pet_idx_in,own_idx_in)
  127.  
  128.     if pet_idx == nil then
  129.         if superverbose == true then windower.add_to_chat(8, 'update_pet() : false : pet_idx == nil, pet_idx_in: '..(pet_idx_in or 'nil')..', own_idx_in: '..(own_idx_in or 'nil')) end
  130.         return false
  131.     end
  132.  
  133.     local pet_table = windower.ffxi.get_mob_by_index(pet_idx)
  134.     if pet_table == nil then
  135.         if petactive then -- presumably we have a pet, he just hasn't loaded, yet...
  136.             if superverbose == true then windower.add_to_chat(8, 'update_pet() : true : pet_table == nil, pet_idx: '..(pet_idx or 'nil')..', '..(own_idx_in or 'nil')) end
  137.             return true
  138.         end
  139.         if superverbose == true then windower.add_to_chat(8, 'update_pet() : false: pet_table == nil, pet_idx: '..(pet_idx or 'nil')..', '..(own_idx_in or 'nil')) end
  140.         make_invisible()
  141.         return false
  142.     end
  143.  
  144.     petname = pet_table['name']
  145.     if superverbose == true then windower.add_to_chat(8, 'update_pet() : Updating PetName: '..petname) end
  146.     current_hp_percent = pet_table['hpp']
  147.     --current_tp_percent = pet_table['tp']
  148.     if not petactive and current_hp_percent == 0 then  -- we're likely picking up a dead or despawning pet
  149.         if superverbose == true then windower.add_to_chat(8, 'update_pet() : Picked up a likely dead pet') end
  150.         make_invisible()
  151.         return false
  152.     end
  153.     if superverbose == true then windower.add_to_chat(8, 'update_pet() : true : Picked up a pet: '..petname..', hp%: '..current_hp_percent..', pet_idx: '..pet_idx) end
  154.     return true
  155. end
  156.  
  157. function printpettp(pet_idx_in,own_idx_in)
  158.     if not petactive then
  159.         return
  160.     end
  161.     if petname == nil then
  162.         if update_pet('printpettp',pet_idx_in,own_idx_in) == false then
  163.             return
  164.         end
  165.     end
  166.  
  167.     local output
  168.  
  169.     output = (petname or 'Unknown')..': '
  170.     if settings.autocolor == true then
  171.         if current_hp_percent > 75 then
  172.             output = output..'\\cr\\cs(128,255,128)'        
  173.         elseif current_hp_percent > 50 then
  174.             output = output..'\\cr\\cs(255,255,0)'
  175.         elseif current_hp_percent > 25 then
  176.             output = output..'\\cr\\cs(255,160,0)'
  177.         else
  178.             output = output..'\\cr\\cs(255,0,0)'
  179.         end
  180.     end
  181.     if max_hp > 0 then
  182.         output = output..current_hp..'/'..max_hp..' '..'('..current_hp_percent..'%)'
  183.     else
  184.         output = output..current_hp_percent..'%'
  185.     end
  186.     if settings.autocolor == true then output = output..'\\cr\\cs('..settings.text.red..','..settings.text.green..','..settings.text.blue..')' end    
  187.     output = output..' ['
  188.     if settings.autocolor == true and current_tp_percent >= 1000 then output = output..'\\cr\\cs(128,255,128)' end
  189.     output = output..current_tp_percent
  190.     if settings.autocolor == true and current_tp_percent >= 1000 then output = output..'\\cr\\cs('..settings.text.red..','..settings.text.green..','..settings.text.blue..')' end    
  191.     output = output..']'
  192.     if max_mp > 0 then
  193.         if current_mp_percent > 75 then
  194.             output = output..'\\cr\\cs(128,255,128)'        
  195.         elseif current_mp_percent > 50 then
  196.             output = output..'\\cr\\cs(255,255,0)'
  197.         elseif current_mp_percent > 25 then
  198.             output = output..'\\cr\\cs(255,160,0)'
  199.         else
  200.             output = output..'\\cr\\cs(255,0,0)'
  201.         end
  202.         output = output..' '..current_mp..'/'..max_mp..' ('..current_mp_percent..'%)'
  203.         if settings.autocolor == true then output = output..'\\cr\\cs('..settings.text.red..','..settings.text.green..','..settings.text.blue..')' end    
  204.     end
  205.     output = output..'\\cr'
  206.  
  207.     pettp:text(output)
  208. end
  209.  
  210. windower.register_event('time change', function()
  211.     if timercountdown == 0 then
  212.         return
  213.     elseif petactive then
  214.         if superverbose == true then windower.add_to_chat(8, 'SCAN: Pet appeared between scans!') end
  215.         timercountdown = 0
  216.     else
  217.         timercountdown = timercountdown - 1
  218.         if update_pet('scan') == true then
  219.             if superverbose == true then windower.add_to_chat(8, 'SCAN: Found a pet!') end
  220.             timercountdown = 0
  221.             make_visible()
  222.             printpettp()
  223.         elseif timercountdown == 0 then
  224.             if superverbose == true then windower.add_to_chat(8, 'SCAN: No pet found in 5 ticks') end
  225.         end
  226.     end
  227. end)
  228.  
  229. windower.register_event('incoming chunk',function(id,original,modified,injected,blocked)
  230.     if not injected then
  231.         if id == 0x44 then
  232.             if original:unpack('C', 0x05) == 0x12 then    -- puppet update
  233.                 local new_current_hp, new_max_hp, new_current_mp, new_max_mp = original:unpack('HHHH', 0x069)
  234.  
  235.                 if (not petactive) or (petname == nil) or (petname == "") or (new_current_hp ~= current_hp) or (new_max_hp ~= max_hp) or (new_current_mp ~= current_mp) or (new_max_mp ~= max_mp) then
  236.                     if superverbose == true then                
  237.                         windower.add_to_chat(8, '0x44'
  238.                             ..', cur_hp: '..new_current_hp
  239.                             ..', max_hp: '..new_max_hp
  240.                             ..', cur_mp: '..new_current_mp
  241.                             ..', max_mp: '..new_max_mp
  242.                             ..', name: '.. original:unpack('z', 0x59)
  243.                         )
  244.                     end
  245.  
  246.                     if petactive then
  247.                         local new_petname = original:unpack('z', 0x59)
  248.                         if petname == nil or petname == "" then
  249.                             if superverbose == true then windower.add_to_chat(8, 'Updating PuppetName: '..new_petname) end
  250.                             petname = new_petname
  251.                         end
  252.                         if petname == new_petname then -- make sure we only update if we actually have a puppet out
  253.                             current_hp = new_current_hp
  254.                             max_hp     = new_max_hp
  255.                             current_mp = new_current_mp
  256.                             max_mp     = new_max_mp
  257.                             if max_hp ~= 0 then
  258.                                 current_hp_percent=math.floor(100*current_hp/max_hp)
  259.                             else
  260.                                 current_hp_percent=0
  261.                             end
  262.                             if max_mp ~= 0 then
  263.                                 current_mp_percent=math.floor(100*current_mp/max_mp)
  264.                             else
  265.                                 current_mp_percent=0
  266.                             end
  267.                             printpettp()
  268.                         else
  269.                             if superverbose == true then windower.add_to_chat(8, '0x44, pet is not a puppet') end
  270.                         end
  271.                     else
  272.                         if superverbose == true then windower.add_to_chat(8, '0x44, puppet not active') end
  273.                     end
  274.                 end
  275.             end
  276.         elseif id == 0x67 then    -- general hp/tp/mp update
  277.             local msg_type,msg_len = original:unpack('b6b10',0x05);
  278.             pet_idx = original:unpack('H', 0x07)
  279.             own_idx = original:unpack('H', 0x0D)
  280.  
  281.             if (msg_type == 0x04) then
  282.                 pet_idx, own_idx = own_idx, pet_idx
  283.             end
  284.  
  285.             if superverbose == true and not (
  286.                    (msg_type == 0x02) -- not pet related
  287.                 or (msg_type == 0x03 and (own_idx == 0)) -- NPC pops
  288.                 or (msg_type == 0x03 and (own_idx ~= windower.ffxi.get_player().index)) -- other people summoning
  289.             ) then
  290.                 windower.add_to_chat(8, '0x67'
  291.                        ..', msg_type: '..string.format('0x%02x', msg_type)
  292.                        ..', msg_len: '..msg_len
  293.                        ..', pet_idx: '..pet_idx
  294.                        ..', pet_id: '..(original:byte(0x09)+original:byte(0x0A)*256)
  295.                        ..', own_idx: '..own_idx
  296.                        ..', hp%: '..original:byte(0x0F)
  297.                        ..', mp%: '..original:byte(0x10)
  298.                        ..', tp%: '..(original:byte(0x11)+original:byte(0x12)*256)
  299.                        ..', name: '.. ((msg_len > 24) and original:unpack('z', 0x19) or "")
  300.                     )
  301.             end
  302.             if (msg_type == 0x04) then
  303.                 if (pet_idx == 0) then
  304.                     if verbose == true then windower.add_to_chat(8, 'Pet died/despawned') end
  305.                     make_invisible()
  306.                 else
  307.                     local newpet = false
  308.                     if not petactive then
  309.                         petactive = true  -- force our pet to appear even if it's not attached to us yet
  310.                         if update_pet('0x67-0x*4',pet_idx,own_idx) == true then
  311.                             make_visible()
  312.                             newpet = true
  313.                         else
  314.                             if superverbose == true then windower.add_to_chat(8, 'Pet not found') end
  315.                             make_invisible()
  316.                         end
  317.                     end
  318.                     local new_hp_percent, new_mp_percent, new_tp_percent = original:unpack('CCH', 0x0F)
  319.                     new_tp_percent = new_tp_percent
  320.                     if newpet or (new_hp_percent ~= current_hp_percent) or (new_mp_percent ~= current_mp_percent) or (new_tp_percent ~= current_tp_percent) or (petname == nil) or (petname == "") then
  321.                         if (max_hp ~= 0) and (new_hp_percent ~= current_hp_percent) then
  322.                             current_hp = math.floor(new_hp_percent * max_hp / 100)
  323.                         end
  324.                         if (max_mp ~= 0) and (new_mp_percent ~= current_mp_percent) then
  325.                             current_mp = math.floor(new_mp_percent * max_mp / 100)
  326.                         end
  327.                         if ((petname == nil) or (petname == "")) and (msg_len > 24) then
  328.                             petname = original:unpack('S16', 0x19)
  329.                             if superverbose == true then windower.add_to_chat(8, 'Updated PetName: '..petname) end
  330.                         end
  331.                         current_hp_percent = new_hp_percent
  332.                         current_mp_percent = new_mp_percent
  333.                         current_tp_percent = new_tp_percent
  334.                         printpettp(pet_idx,own_idx)
  335.                     end
  336.                 end
  337.             elseif not petactive and (msg_type == 0x03) and (own_idx == windower.ffxi.get_player().index) then
  338.                 if update_pet('0x67-0x03',pet_idx,own_idx) == true then
  339.                     make_visible()
  340.                     printpettp(pet_idx,own_idx_in)
  341.                 else    -- last resort
  342.                     timercountdown = 5
  343.                     if superverbose == true then windower.add_to_chat(8, 'Starting to scan for a pet...') end
  344.                 end
  345.             end
  346.         elseif id==0x0E and S{0x07,0x0F}:contains(original:byte(0x0B)) then    -- npc update
  347.             if mypet_idx == original:unpack('H', 0x09) then
  348.                 if current_hp_percent ~= original:byte(0x1F) then
  349.                     if superverbose == true then windower.add_to_chat(8, '0x0E - '..original:byte(0x0B)..': '..original:byte(0x1F)) end
  350.                     current_hp_percent = original:byte(0x1F)
  351.                     if max_hp ~= 0 then
  352.                         current_hp = math.floor(current_hp_percent * max_hp / 100)
  353.                     end
  354.                     printpettp(mypet_idx)
  355.                 end
  356.             end
  357.         elseif id==0x0E and not S{0x00,0X01,0x08,0x09,0x20}:contains(original:byte(0x0B)) and mypet_idx == (original:byte(0x09)+original:byte(0x0A)*256) then
  358.             if superverbose == true then windower.add_to_chat(8, '0x0E ~ '..original:byte(0x0B)..': '..original:byte(0x1F)) end
  359.         end
  360.     end
  361. end)
  362.  
  363. windower.register_event('load', function()
  364.     if superverbose == true then
  365.         windower.add_to_chat(8, 'Player index: '..windower.ffxi.get_player().index)
  366.         if windower.ffxi.get_mob_by_target('pet') then
  367.             windower.add_to_chat(8, 'Pet index: '..windower.ffxi.get_mob_by_target('pet').index)
  368.         end
  369.     end
  370.     if windower.ffxi.get_player() then
  371.         if update_pet('load') == true then
  372.             make_visible()
  373.             printpettp()
  374.         end
  375.     end
  376. end)
  377.  
  378. windower.register_event('zone change', function()
  379.     mypet_idx = nil
  380.     if update_pet('zone') == true then
  381.         if verbose == true then windower.add_to_chat(8, 'Found pet after zoning...') end
  382.         make_visible()
  383.         printpettp()
  384.     elseif petactive then
  385.         make_invisible()
  386.         if verbose == true then windower.add_to_chat(8, 'Lost pet after zoning...') end
  387.     end
  388. end)
  389.  
  390. windower.register_event('job change', function()
  391.     make_invisible()
  392. end)
  393.  
  394. windower.register_event('addon command', function(...)
  395.     local splitarr = {...}
  396.  
  397.     for i,v in pairs(splitarr) do
  398.         if v:lower() == 'save' then
  399.             config.save(settings, 'all')
  400.         elseif v:lower() == 'verbose' then
  401.             verbose = not verbose
  402.             windower.add_to_chat(121,'PetTP: Verbose Mode flipped! - '..tostring(verbose))
  403.         elseif v:lower() == 'superverbose' then
  404.             superverbose = not superverbose
  405.             windower.add_to_chat(121,'PetTP: SuperVerbose Mode flipped! - '..tostring(superverbose))
  406.         elseif v:lower() == 'help' then
  407.             print('   :::   '.._addon.name..' ('.._addon.version..')   :::')
  408.             print('Utilities:')
  409.             print(' 1. verbose --- Some light logging, Default = false')
  410.             print(' 2. help    --- shows this menu')
  411.         end
  412.     end
  413. end)
Advertisement
Add Comment
Please, Sign In to add comment