Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
288 changes: 198 additions & 90 deletions addons/rolltracker/rolltracker.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,91 +25,192 @@
--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

_addon.name = 'RollTracker'
_addon.version = '1.8.1.1'
_addon.author = 'Balloon'
_addon.version = '1.8.2.0'
_addon.author = 'Balloon, Aragan'
_addon.commands = {'rolltracker','rt'}
_addon.update = 'update by Aurthor Aragan 2024'

require('luau')
chat = require('chat')
chars = require('chat.chars')
packets = require('packets')

texts = require('texts')

local hudText
local hudVisible = false
local hudTimestamp = 0
local lastHudSave = 0

local function initHud()
if hudText then return end
hudText = texts.new({
pos = {x = 900, y = 300},
bg = {alpha = 80, red = 0, green = 0, blue = 0},
text = {font = 'Arial', size = 12, alpha = 255, red = 255, green = 255, blue = 255},
flags = {draggable = true},
padding = 6,
})
hudText:hide()
end

local function applyHudSettings()
if not hudText or not settings then return end
hudText:pos(settings.hudX or 900, settings.hudY or 300)
pcall(function() hudText:draggable(settings.hudDrag ~= false) end)
end

local function showHud(msg)
if not settings or not settings.hud then return end
initHud()
applyHudSettings()
hudText:text(msg)
hudText:show()
hudVisible = true
hudTimestamp = os.time()
end

local function hideHud()
if hudText and hudVisible then
hudText:hide()
end
hudVisible = false
end

windower.register_event('prerender', function()
if settings and settings.hud and hudVisible and settings.hudTime and settings.hudTime > 0 then
if os.time() - hudTimestamp >= settings.hudTime then
hideHud()
end
end

if settings and settings.hud and hudText then
local x, y = hudText:pos()
if type(x) == 'table' then
y = x.y
x = x.x
end
if type(x) == 'number' and type(y) == 'number' then
if x ~= settings.hudX or y ~= settings.hudY then
local now = os.clock()
if now - lastHudSave >= 0.5 then
settings.hudX = x
settings.hudY = y
config.save(settings, 'all')
lastHudSave = now
end
end
end
end
end)

defaults = {}
defaults.autostopper = true
defaults.bust = 1
defaults.effected = 1
defaults.fold = 1
defaults.luckyinfo = true
defaults.channel = {}
defaults.channel.roll = 1 -- This should be 101, but the current default is 1
defaults.channel.warn = 1
defaults.color = {}
defaults.color.bonus = 13
defaults.color.lucky = 158
defaults.color.warn = 159
defaults.color.unlucky = 167

defaults.hud = false
defaults.hudTime = 5
defaults.hudX = 900
defaults.hudY = 300
defaults.hudDrag = true
defaults.view = 'all'
settings = config.load(defaults)

windower.register_event('addon command',function (...)
cmd = {...}
local command = ((cmd[1] ~= nil) and cmd[1]:lower()) or "help"

if command == "autostop" then
if settings.autostopper then
settings.autostopper = false
log('Will no longer stop Double-UP on a Lucky Roll.')
else
settings.autostopper = true
log('Will stop Double-UP on a Lucky Roll.')
end
elseif command == "luckyinfo" then
if settings.luckyinfo then
settings.luckyinfo = false
log('Lucky/Unlucky Info will no longer be displayed.')
else
settings.luckyinfo = true
log('Lucky/Unlucky Info will now be displayed.')
end
elseif command == "channel" then
local subcommand = ((cmd[2] ~= nil) and cmd[2]:lower()) or "help"
if subcommand == "help" then
log('Chat Channels: roll(' .. settings.channel.roll .. '), warn(' .. settings.channel.warn .. ')')
return
end
if settings.channel[subcommand] == nil then
log('Valid chat channels are: roll and warn')
return
end
local channel = tonumber(((cmd[3] ~= nil) and cmd[3]) or 0)
if (channel == nil) or (channel < 1) or (channel > 255) then
log('Valid channnel values are 1 through 255')
return
end
settings.channel[subcommand] = channel
log('Chat Channel set to ' .. channel)
elseif command == "color" then
local subcommand = ((cmd[2] ~= nil) and cmd[2]:lower()) or "help"
if subcommand == "help" then
log('Colors: bonus(' .. settings.color.bonus .. '), lucky(' .. settings.color.lucky .. '), unlucky(' .. settings.color.unlucky .. '), warn(' .. settings.color.warn .. ')')
return
end
if settings.color[subcommand] == nil then
log('Valid color types are: roll, bonus, lucky, unlucky, and warn')
return
end
local color = tonumber(((cmd[3] ~= nil) and cmd[3]) or 0)
if (color == nil) or (color < 1) or (color > 255) then
log('Valid color values are 1 through 255')
return
if cmd[1] ~= nil then
if cmd[1]:lower() == "help" then
log('To toggle rolltracker from allowing/stopping rolls type: //rolltracker autostop')
log('To toggle rolltracker from showing/hiding Lucky Info type: //rolltracker luckyinfo')
log('To toggle HUD on/off type: //rolltracker hud [on|off|toggle|status]')
log('To set HUD time (seconds) type: //rolltracker hudtime <seconds>')
log('To set HUD position type: //rolltracker hudpos <x> <y>')
log('To view rolls from self/others/all type: //rolltracker view <self|others|all>')
elseif cmd[1]:lower() == "autostop" then
if settings.autostopper then
settings.autostopper = false
log('Will no longer stop Double-UP on a Lucky Roll.')
else
settings.autostopper = true
log('Will stop Double-UP on a Lucky Roll.')
end
elseif cmd[1]:lower() == "luckyinfo" then
if settings.luckyinfo then
settings.luckyinfo = false
log('Lucky/Unlucky Info will no longer be displayed.')
else
settings.luckyinfo = true
log('Lucky/Unlucky Info will now be displayed.')
end
elseif cmd[1]:lower() == "hud" then
local sub = cmd[2] and cmd[2]:lower() or "toggle"
if sub == "on" then
settings.hud = true
initHud()
applyHudSettings()
log('HUD Enabled.')
elseif sub == "off" then
settings.hud = false
hideHud()
log('HUD Disabled.')
elseif sub == "status" then
log('HUD: ' .. (settings.hud and 'ON' or 'OFF'))
else
settings.hud = not settings.hud
if not settings.hud then
hideHud()
else
initHud()
applyHudSettings()
end
log('HUD: ' .. (settings.hud and 'ON' or 'OFF'))
end
elseif cmd[1]:lower() == "hudtime" then
local t = tonumber(cmd[2])
if t then
settings.hudTime = t
log('HUD Time: ' .. tostring(settings.hudTime) .. 's')
else
log('Usage: //rolltracker hudtime <seconds>')
end
elseif cmd[1]:lower() == "hudpos" then
local x = tonumber(cmd[2])
local y = tonumber(cmd[3])
if x and y then
settings.hudX = x
settings.hudY = y
initHud()
applyHudSettings()
log('HUD Position: ' .. tostring(x) .. ', ' .. tostring(y))
else
log('Usage: //rolltracker hudpos <x> <y>')
end
elseif cmd[1]:lower() == "hudlock" then
settings.hudDrag = false
applyHudSettings()
log('HUD Drag: OFF')
elseif cmd[1]:lower() == "hudunlock" then
settings.hudDrag = true
initHud()
applyHudSettings()
log('HUD Drag: ON')
elseif cmd[1]:lower() == "view" then
local mode = cmd[2] and cmd[2]:lower() or ""
if mode == "me" or mode == "my" or mode == "mine" then
mode = "self"
end
if mode == "self" or mode == "others" or mode == "all" then
settings.view = mode
log('View Mode: ' .. settings.view)
else
log('Usage: //rolltracker view <self|others|all>')
end
end
settings.color[subcommand] = color
log('Color for \'' .. subcommand .. '\' set to ' .. color)
else
printHelp()
return
config.save(settings, 'all')
end
config.save(settings, 'all')
end)

--This is done because GearSwap swaps out too fast, and sometimes things aren't reported in memory.
Expand All @@ -125,19 +226,6 @@ windower.register_event('incoming chunk', function(id, data)
end
end)

function printHelp()
log('rt autostop : Toggle allowing/stopping rolls')
log('rt luckyinfo : Toggle showing/hiding Lucky Info')
log('rt channel : Show current chat channels for rolltracker messages')
log('rt channel roll <channel> : Set the chat channel for rolls (1-255, ex. 101)')
log('rt channel warn <channel> : Set the chat channel for warnings (1-255, ex. 101)')
log('rt color : Show current color settings')
log('rt color bonus <color> : Set the color for the Roll Bonus text (1-255, ex. 158)')
log('rt color lucky <color> : Set the color for the Lucky text (1-255, ex. 158)')
log('rt color unlucky <color> : Set the color for the Unlucky text (1-255, ex. 167)')
log('rt color warn <color> : Set the color for warning messages (1-255, ex. 159)')
end

function getGear(slot)
local equip = windower.ffxi.get_items()['equipment']
return windower.ffxi.get_items(equip[slot..'_bag'])[equip[slot]]~= nil and windower.ffxi.get_items(equip[slot..'_bag'])[equip[slot]].id or 0
Expand Down Expand Up @@ -234,6 +322,14 @@ windower.register_event('action', function(act)
local rollID = act.param
local rollNum = act.targets[1].actions[1].param

if settings and settings.view and player and player.id then
if settings.view == 'self' and rollActor ~= player.id then
return
elseif settings.view == 'others' and rollActor == player.id then
return
end
end

-- anonymous function that checks if the player.id is in the targets without wrapping it in another layer of for loops.
if
function(act)
Expand Down Expand Up @@ -264,25 +360,38 @@ windower.register_event('action', function(act)
isLucky = false
if rollNum == rollInfo[rollID][15] or rollNum == 11 then
isLucky = true
windower.add_to_chat(settings.channel.roll, 'Lucky roll!':color(settings.color.lucky))
luckChat = " (Lucky!)":color(settings.color.lucky)
windower.add_to_chat(158,'Lucky roll!')
luckChat = string.char(31,158).." (Lucky!)"
elseif rollNum == rollInfo[rollID][16] then
luckChat = " (Unlucky!)":color(settings.color.unlucky)
luckChat = string.char(31,167).." (Unlucky!)"
end

-- HUD details (roll number + Lucky/Unlucky numbers)
local lucky_num = rollInfo[rollID][15]
local unlucky_num = rollInfo[rollID][16]

local hud_lu = ''
if settings.luckyinfo then
hud_lu = string.format('\nLucky: %d Unlucky: %d', lucky_num, unlucky_num)
end

local hud_status = ''
if rollNum == lucky_num or rollNum == 11 then
hud_status = ' (Lucky!)'
elseif rollNum == unlucky_num then
hud_status = ' (Unlucky!)'
end
if rollNum == 12 and #rollMembers > 0 then
local bustchat = amountHit..'Bust! '..chat.controls.reset..chars.implies..' '..membersHit..' '..chars.implies..' ('..rollInfo[rollID][rollNum+1]..rollInfo[rollID][14]..')'
windower.add_to_chat(settings.channel.roll, bustchat:color(settings.color.bust))
windower.add_to_chat(1, string.char(31,167)..amountHit..'Bust! '..chat.controls.reset..chars.implies..' '..membersHit..' '..chars.implies..' ('..rollInfo[rollID][rollNum+1]..rollInfo[rollID][14]..')')
showHud(string.format('%s Roll\nBust!%s', rollInfo[rollID][1], hud_lu))
else
local bonuschat = ' (+'..rollBonus..')'
windower.add_to_chat(settings.channel.roll, amountHit..membersHit..chat.controls.reset..' '..chars.implies..' '..rollInfo[rollID][1]..' Roll '..chars['circle' .. rollNum]..luckChat.. bonuschat:color(settings.color.bonus) ..BustRate(rollNum, rollActor)..ReportRollInfo(rollID, rollActor))
windower.add_to_chat(1, amountHit..membersHit..chat.controls.reset..' '..chars.implies..' '..rollInfo[rollID][1]..' Roll '..chars['circle' .. rollNum]..luckChat..string.char(31,13)..' (+'..rollBonus..')'..BustRate(rollNum, rollActor)..ReportRollInfo(rollID, rollActor))
showHud(string.format('%s Roll %d%s\n+%s%s', rollInfo[rollID][1], rollNum, hud_status, rollBonus, hud_lu))
end
end
end
end)


function RollEffect(rollid, rollnum)
if rollnum == 13 then
return
Expand Down Expand Up @@ -389,7 +498,6 @@ function RollEffect(rollid, rollnum)
return rollVal..rollInfo[rollid][14]
end


function BustRate(rollNum, rollActor)
if rollNum <= 5 or rollNum == 11 or rollActor ~= player.id or settings.bust == 0 then
return ''
Expand Down Expand Up @@ -418,7 +526,7 @@ windower.register_event('outgoing text', function(original, modified)
modified = original
if cleaned:match('/jobability \"?Double.*Up') or cleaned:match('/ja \"?Double.*Up') then
if isLucky and settings.autostopper and rollActor == player.id then
windower.add_to_chat(settings.channel.warn, 'Attempting to Doubleup on a Lucky Roll: Re-double up to continue.':color(settings.color.warn))
windower.add_to_chat(159,'Attempting to Doubleup on a Lucky Roll: Re-double up to continue.')
isLucky = false
modified = ""
end
Expand All @@ -435,7 +543,7 @@ windower.register_event('outgoing text', function(original, modified)
modified = cleaned
ranMultiple = false
else
windower.add_to_chat(settings.channel.warn, 'No \'Bust\'. Fold again to continue.':color(settings.color.warn))
windower.add_to_chat(159, 'No \'Bust\'. Fold again to continue.')
ranMultiple = true
modified = ""
end
Expand All @@ -444,4 +552,4 @@ windower.register_event('outgoing text', function(original, modified)
end
return modified

end)
end)