commit cd19de19bece102c2d8b44f56e6b08418ea332b7 Author: shnee Date: Fri Jan 26 16:36:34 2024 -0500 Initial Code Copied From WoW diff --git a/gather-data-actions.lua b/gather-data-actions.lua new file mode 100644 index 0000000..39af736 --- /dev/null +++ b/gather-data-actions.lua @@ -0,0 +1,440 @@ + +aura_env.gather_data = function() + + aura_env.log(aura_env.LOG.TRACE, "Entering gather_data()") + + local data = {} + + -- Get a sorted list of friends that need help. + if aura_env.config.fake then + data = aura_env.iterate_party_fake() + else + data = aura_env.iterate_party() + print("after iterate_party") + end + + print("type(data.party_members): " .. type(data.party_members)) + aura_env.log(aura_env.LOG.DEBUG, "DEBUG - Got " .. #data.party_members .. " friends that can be helped.") + + aura_env.print_data(data) + members = WA_IterateGroupMembers()() + print("type(WA_IterateGroupMembers()): " .. type(members)) + print("members: " .. members) + for i in WA_IterateGroupMembers() do + print("type(i): " .. type(i)) + end + for i in aura_env.group_members() do + print("type(i): " .. type(i)) + print(i) + end + + return data +end + + +aura_env.interval_has_passed = function() + if GetTime() > aura_env.nextupdate then + aura_env.nextupdate = GetTime() + (aura_env.config.update_interval_ms / 1000) + return true + end + return false +end + + +aura_env.unit_in_range_and_can_help = function(unit) + + in_range = false + + -- 'player' is always in range and API actually returns false when UnitInRange is called on + -- 'player' + if unit == 'player' then + in_range = true + else + in_range, _ = UnitInRange(unit) + end + + if UnitExists(unit) and not UnitIsDead(unit) and UnitIsVisible(unit) and UnitIsFriend('player', unit) then + + -- UnitInRange only works on party members. Therefore if the unit is the target or focus + -- then we need to check the range another way. + if unit == 'target' or unit == 'focus' then + -- TODO make 'Rejeventaion' be a config option. IsSpellInRange requires that the + -- player knows the spell. + if IsSpellInRange('Rejuvenation', unit) == 1 then + return true + end + else -- unit should be in the party/raid + if in_range then + return true + end + end + end + return false +end + + +-- lowest is an object { unit, percent } +-- aura_env.check_for_lowest = function(unit, lowest) +-- local health = UnitHealth(unit) +-- local max = UnitHealthMax(unit) +-- local percent = 1 +-- +-- if max > 0 then +-- percent = health / max +-- end +-- +-- if percent < lowest[2] then +-- lowest = {unit, percent} +-- end +-- +-- return lowest +-- end + + +-- Returns { current: int, max: int, perc: float, adj_perc: float } +aura_env.get_health = function(friend) + + -- Get the current and max health for our friend. + local current = UnitHealth(friend) + local max = UnitHealthMax(friend) + + -- Calculate the percent of health. + -- - We must check for 0 becaue UnitHealMax will return 0 if the unit does not + -- exist. + -- - We default perc to 1 becuase the idea is that if it's full health then it + -- won't bother the algo. + local perc = 1 + if max > 0 then + perc = current / max + end + + local health = { current = current, max = max, perc = perc, adj_perc = aura_env.get_adjusted_health(friend, perc) } + return health +end + + +-- Returns a float that is the users health percentage updated by a weighting system. +-- Input: { current: int, max: int, perc: float } +-- Returns: float +aura_env.get_adjusted_health = function(friend, perc) + return perc +end + + +aura_env.get_mana = function(friend) + + -- Get the current and max mana for our friend. + local current = UnitPower(friend) + local max = UnitPowerMax(friend) + + -- Calculate the percent of mana. + -- - We must check for 0 becaue UnitPowerMax will return 0 if the unit does + -- not exist. _NOTE_ This is not actually verified, just assuming because + -- I found examples for health that stated this. + -- - We default perc to 1 becuase the idea is that if it's full mana then + -- it won't bother the algo. + local perc = 1 + if max > 0 then + perc = current / max + end + + local mana = { current = current, max = max, perc = perc } + return mana +end + + +aura_env.insert_health_sorted = function(friends, friend) + + -- If their health is 100% then jsut append to the end. + if friend.health.adj_perc >= 1 then + table.insert(friends, friend) + return friends + end + + local index = 1 + while index <= #friends and + friend.health.adj_perc > friends[index].health.adj_perc + do + index = index + 1 + end + + table.insert(friends, index, friend) + +end + +-- Iterate over the party and grab useful data. +-- +-- This function will return a table with the following format. +-- { +-- player: Player +-- party_health: Resource +-- party_members: { +-- Player, +-- Player, +-- ... +-- } +-- +-- Player: { +-- name: string +-- health: Resource +-- [mana: Resource] +-- } +-- +-- Resource: { +-- current: int +-- max: int +-- perc: float +-- [adj_perc: float] +-- } +aura_env.iterate_party = function() + + aura_env.log(aura_env.LOG.TRACE, "Entering iterate_party()") + + local data = { + party_health = { current = 0, max = 0, perc = 1 }, + party_members = {} + } + + -- Iterate over party. + for friend in WA_IterateGroupMembers() do + if aura_env.unit_in_range_and_can_help(friend) then + + -- Get our friends health percentage. + local health = aura_env.get_health(friend) + + --local player = { name = friend, health = aura_env.get_health(friend) } + local player = { name = friend, health = health } + + -- Do some special stuff if friend is us. + if friend == "player" then + player.mana = aura_env.get_mana("player") + data.player = player + end + + -- Update the party total health stats + -- + -- perc will be calculated at the end. + data.party_health.current = data.party_health.current + player.health.current + data.party_health.max = data.party_health.max + player.health.max + + -- Insert player into friends based on their adjusted health percentage. + aura_env.insert_health_sorted(data.party_members, player) + + end + end + + print("before party health perc calc") + -- Calculate the party's total health perc. + if data.party_health.max ~= 0 then + data.party_health.perc = data.party_health.current / data.party_health.max + end + + return data + +end + + +aura_env.iterate_party_fake = function() + + aura_env.log(aura_env.LOG.TRACE, "Entering iterate_party_fake()") + + local player = { name = "player", health = { current = 1, max = 1, perc = 1, adj_perc = 1 }} + local unsorted_friends = { + { name = "player", + health = { + current = 1, max = 1, perc = 1, adj_perc = 1 }}, + { name = "party1", + health = { + current = 1, max = 1, perc = 1, adj_perc = 0.9 }}, + { name = "party2", + health = { + current = 1, max = 1, perc = 1, adj_perc = 0.8 }} + } + local data = { + player = player, + party_health = { current = 3, max = 3, perc = 1 }, + party_members = {} + } + + + for _, friend in ipairs(unsorted_friends) do + aura_env.insert_health_sorted(data.party_members, friend) + end + + return data + +end + +-------------------------------------------------------------------------------- +-- Start common code +-- +-- Everything below this point is code that is likely to be shared among +-- serveral auras. +-------------------------------------------------------------------------------- + +aura_env.nextupdate = 0 + +aura_env.LOG = { + NONE = 1, + ERROR = 2, + INFO = 3, + DEBUG = 4, + TRACE = 5 +} +aura_env.log_level = aura_env.LOG.INFO +-- aura_env.log_level = aura_env.LOG.TRACE + +-------------------------------------------------------------------------------- +-- Types +-------------------------------------------------------------------------------- + +-- Data Types +-- data: { +-- player: Player +-- party_health: Resource +-- party_members: { +-- Player, +-- Player, +-- ... +-- } +-- +-- Player: { +-- name: string +-- health: Resource +-- [mana: Resource] +-- } +-- +-- Resource: { +-- current: int +-- max: int +-- perc: float +-- [adj_perc: float] +-- } + +-------------------------------------------------------------------------------- +-- Printing and string formatting +-------------------------------------------------------------------------------- + +aura_env.print_data = function(data) + + aura_env.log(aura_env.LOG.TRACE, "Entering print_data()") + + -- print("data: " .. data) + print("#data: " .. #data.party_members) + -- print("data[1].health: " .. data[1].health.current) + + print("{\n player: " .. aura_env.player_to_str(data.player) .. ",") + print(" party_health: " .. aura_env.resource_to_str(data.party_health) .. ",") + print(" party_members: [") + + for _, player in ipairs(data.party_members) do + print(" " .. aura_env.player_to_str(player) .. ",") + end + print(" ] }") + +end + + +aura_env.player_to_str = function(player, pretty_print, num_spaces) + + aura_env.log(aura_env.LOG.TRACE, "Entering resource_to_str()") + + -- Set defaults and initial values + local player_str = "PLAYER_ERROR" + local num_spaces = num_spaces or 0 + local spaces = string.rep(" ", num_spaces) + if pretty_print == nil then + pretty_print = false + end + local nl_spaces = pretty_print and "\n" .. spaces or "" + + -- Print an error if player is not a table. + if type(player) ~= "table" then + aura_env.log(aura_env.LOG.ERROR, "ERROR - player_to_str() got a player that was not a table.") + else + + -- Add name and health to player string. + player_str = spaces .. "{" .. nl_spaces .. " name: " .. player.name .. + "," .. nl_spaces .. " health: " .. aura_env.resource_to_str(player.health) + + -- Add mana if it exists in player. + if player.mana ~= nil then + player_str = player_str .. "," .. nl_spaces .. " mana: " .. aura_env.resource_to_str(player.mana) + end + + -- Finsh object string. + player_str = player_str .. nl_spaces .. "}" + + end + + return player_str + +end + + +aura_env.resource_to_str = function(resource) + + aura_env.log(aura_env.LOG.TRACE, "Entering resource_to_str()") + + local resource_str = "RESOURCE_ERROR" + + if not (type(resource) == "table") then + aura_env.log(aura_env.LOG.ERROR, "ERROR - resource_to_str() got a resource that was not a table.") + else + + resource_str = "{ current: " .. resource.current .. ", max: " .. + resource.max .. ", perc: " .. resource.perc + + -- Add adj_perc, if it exists + if resource.adj_perc ~= nil then + resource_str = resource_str .. ", adj_perc: " .. resource.adj_perc + end + + resource_str = resource_str .. " }" + end + + return resource_str + +end + + +aura_env.log = function(log_level, msg) + if log_level <= aura_env.log_level then + print(msg) + end +end + +-------------------------------------------------------------------------------- +-- Fake Data +-------------------------------------------------------------------------------- + +aura_env.fake_group = { + player = "yo", + party1 = "yo", + party2 = "yo" +} + +aura_env.group_members = function() + + if aura_env.config.fake then + local i = 0 + local num_members = 3 + local group_type = "party" + + return function() + local ret + if i == 0 then + ret = "player" + elseif i >= 0 and i < num_members then + ret = group_type .. i + end + i = i + 1 + return ret + end + + else + return WA_IterateGroupMembers() + end + +end +