Last active
July 11, 2020 02:00
-
-
Save Ivaar/819e831cfb0d8cbbf1e25e5491bf7bf0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
_addon.name = 'FollowMe' | |
_addon.author = 'Ivaar' | |
_addon.command = 'fm' | |
require('luau') | |
require('pack') | |
actions = true | |
nolockon = true | |
follow_leader = '' | |
pos = {} | |
local player_name = (windower.ffxi.get_mob_by_target('me') or {}).name | |
local zone_id = windower.ffxi.get_info().zone | |
windower.register_event('incoming chunk',function(id, data, modified, is_injected, is_blocked) | |
if id == 0x0A then | |
zone_id = data:unpack('H', 49) | |
pos = {} | |
end | |
end) | |
windower.register_event('outgoing chunk',function(id, data, modified, is_injected, is_blocked) | |
if id == 0x5C then | |
pos = {} | |
elseif id == 0x05E then | |
if follow_leader == player_name and data:unpack('I', 0x04+1) ~= 1903324538 then | |
windower.send_ipc_message('zone %d ':format(zone_id)..table.concat(last_coords, ' ')) | |
end | |
zone_line = nil | |
end | |
end) | |
windower.register_event('ipc message', function(message) | |
message = message:split(' ') | |
if message[1] == 'set' then | |
if message[2] == 'follow' then | |
follow_leader = message[3] | |
pos = {} | |
elseif message[2] == 'actions' then | |
actions = message[3] == 'on' | |
last_coords = nil | |
end | |
return | |
end | |
if not actions then return end | |
leader_zone = tonumber(message[2]) | |
if leader_zone ~= zone_id then return end | |
table.remove(message, 2) | |
if message[1] == 'pos' then | |
table.remove(message, 1) | |
table.insert(pos, message) | |
elseif message[1] == 'zone' then | |
table.remove(message, 1) | |
zone_line = message | |
end | |
end) | |
local function get_distance(a, b) | |
return math.sqrt((a[1]-b[1])^2 + (a[3]-b[3])^2) | |
end | |
local function run_to_point(a, b) | |
if nolockon and windower.ffxi.get_player().target_locked then | |
windower.send_command('input /lockon') | |
end | |
if not b then | |
windower.ffxi.run(a[4]) | |
return | |
end | |
local x, y = a[1]-b[1], a[3]-b[3] | |
local r = -math.atan2(y,x) | |
local v = windower.ffxi.get_player().autorun | |
if not v or not running or running ~= r then | |
windower.ffxi.run(r) | |
windower.ffxi.turn(r) | |
running = r | |
end | |
end | |
local states = S{0,1,5,85} | |
function do_loop() | |
local player = windower.ffxi.get_mob_by_target('me') | |
if not player or not states:contains(player.status) then return end | |
local coords = {player.x,player.z,player.y,player.heading} | |
if coords[1] == 0 and coords[3] == 0 then return end | |
if player.name == follow_leader then | |
if not last_coords or last_coords[3] ~= coords[3] or last_coords[1] ~= coords[1] then | |
last_coords = coords | |
windower.send_ipc_message('pos %d ':format(zone_id)..table.concat(coords, ' ')) | |
end | |
return | |
end | |
while pos[1] and get_distance(pos[1], coords) < 1 do | |
table.remove(pos, 1) | |
end | |
local dist = pos[1] and get_distance(pos[1], coords) | |
if dist and dist < 30 then | |
run_to_point(pos[1], coords) | |
elseif not pos[1] and zone_line then | |
run_to_point(zone_line) | |
elseif zone_id == leader_zone and running then | |
if windower.ffxi.get_player().autorun then | |
windower.ffxi.run(false) | |
running = false | |
end | |
end | |
end | |
--do_loop:loop(0.1) | |
windower.register_event('postrender', do_loop) | |
windower.register_event('addon command', function(...) | |
arg = T(arg):map(string.lower) | |
if not arg[1] then | |
elseif arg[1] == 'eval' then | |
assert(loadstring(table.concat(arg, ' ',2)))() | |
elseif arg[1] == 'off' or arg[1] == 'on' then | |
actions = arg[1] == 'on' | |
last_coords = nil | |
windower.send_ipc_message('set actions %s':format(arg[1])) | |
else | |
local targ = windower.ffxi.get_mob_by_target(arg[1]) or windower.ffxi.get_mob_by_name(arg[1]:ucfirst()) | |
follow_leader = targ and targ.name or arg[1]:ucfirst() | |
last_coords = nil | |
actions = true | |
windower.send_ipc_message('set actions %s':format('on')) | |
windower.send_ipc_message('set follow %s':format(follow_leader)) | |
end | |
end) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment