diff --git a/.pkgmeta b/.pkgmeta index 97b964e..35d3b8e 100644 --- a/.pkgmeta +++ b/.pkgmeta @@ -38,3 +38,6 @@ externals: url: https://repos.curseforge.com/wow/libuidropdownmenu/trunk Libs/LibDBIcon-1.0: url: https://repos.curseforge.com/wow/libdbicon-1-0/trunk + +ignore: + - test diff --git a/PallyPower.lua b/PallyPower.lua index 64c4ed9..a7d0e5b 100644 --- a/PallyPower.lua +++ b/PallyPower.lua @@ -290,7 +290,7 @@ local function tablecopy(tbl) end local function safeget(t,k) -- always return nil or t[k] if at least t is a table / Treeston - return t and t[k] + return t and t[k] end function PallyPowerBlessings_Clear() @@ -2078,7 +2078,7 @@ function PallyPower:UpdateRoster() local n = select(3, unitid:find("(%d+)")) tmp.name, tmp.rank, tmp.subgroup = GetRaidRosterInfo(n) tmp.zone = select(7, GetRaidRosterInfo(n)) - + if self.opt.hideHighGroups then local maxPlayerCount = (select(5, GetInstanceInfo())) if maxPlayerCount and (maxPlayerCount > 5) then @@ -2088,10 +2088,10 @@ function PallyPower:UpdateRoster() end end end - + local raidtank = select(10, GetRaidRosterInfo(n)) tmp.tank = ((raidtank == "MAINTANK") or (self.opt.mainAssist and (raidtank == "MAINASSIST"))) - + local class = self:GetClassID(pclass) -- Warriors and Death Knights if (class == 1 or (self.isWrath and class == 10)) then @@ -2625,7 +2625,7 @@ function PallyPower:UpdateButton(button, baseName, classID) if (not unit.visible) and InCombatLockdown() then state = "have" end - + if state == "need_big" then nneed = nneed + 1 elseif state == "need_small" then @@ -2822,7 +2822,7 @@ function PallyPower:UpdatePButton(button, baseName, classID, playerID, mousebutt buffIcon:SetTexture(self.BlessingIcons[spellID]) buffIcon:SetVertexColor(1, 1, 1) time:SetText(self:FormatTime(unit.hasbuff)) - + -- The following logic keeps Blessing of Salvation from being assigned to Warrior, Druid and Paladin tanks while in a RAID -- and SalvInCombat isn't enabled. Allows Normal Blessing of Salvation on everyone else and all other blessings. if not InCombatLockdown() then @@ -2857,7 +2857,7 @@ function PallyPower:UpdatePButton(button, baseName, classID, playerID, mousebutt button:SetAttribute("spell2", nSpell) end end - + local state = ClassifyUnitBuffStateForButton(unit) if state == "need_big" then self:ApplyBackdrop(button, self.opt.cBuffNeedAll) @@ -2866,7 +2866,7 @@ function PallyPower:UpdatePButton(button, baseName, classID, playerID, mousebutt else self:ApplyBackdrop(button, self.opt.cBuffGood) end - + if unit.hasbuff then buffIcon:SetAlpha(1) if not unit.visible and not unit.inrange then @@ -3485,7 +3485,7 @@ function PallyPower:AutoBuff(button, mousebutton) buffExpire = 0 penalty = 0 end - + if not self.isWrath and gspellID == 4 then -- If for some reason the targeted unit is in combat and there is a tank present -- in the Class Group then disable Greater Blessing of Salvation for this unit. @@ -3501,7 +3501,7 @@ function PallyPower:AutoBuff(button, mousebutton) penalty = 9999 end end - + if (not PallyPower.petsShareBaseClass) and unit.unitid:find("pet") then buffExpire = 9999 penalty = 9999 @@ -3590,7 +3590,7 @@ function PallyPower:AutoBuff(button, mousebutton) -- Raid than there are buffs to assign so an Alternate Blessing might not be in -- use to wipe Salvation from a tank. Prevents getting stuck buffing a tank when -- auto buff rotates among players in the class group. - + if unit.tank then if not self.isWrath and (spellID == 4 and not self.opt.SalvInCombat) then buffExpire = 9999 @@ -3844,7 +3844,7 @@ function PallyPower:LoadPreset() for pname, passignments in pairs(PallyPower_NormalAssignments) do if (AllPallys[pname] and PallyPower:GetUnitIdByName(pname) and passignments) then for class, cassignments in pairs(passignments) do - if cassignments then + if cassignments then for tname, value in pairs(cassignments) do PallyPower:SendNormalBlessings(pname, class, tname) end @@ -4007,125 +4007,74 @@ function PallyPower:SelectBuffsByClass(pallycount, class, prioritylist) tinsert(pallys, name) end end - local bufftable = prioritylist - if pallycount > 0 then - local pallycounter = 1 - for _, nextspell in pairs(bufftable) do - if pallycounter <= pallycount then - local buffer = self:BuffSelections(nextspell, class, pallys) - for i in pairs(pallys) do - if buffer == pallys[i] then - tremove(pallys, i) - end - end - if buffer ~= "" then - pallycounter = pallycounter + 1 - end + + local buffers = self.isWrath and { + [1] = WisdomPallys, + [2] = MightPallys, + [3] = KingsPallys, + [4] = SancPallys, + } or { + [1] = WisdomPallys, + [2] = MightPallys, + [3] = KingsPallys, + [4] = SalvPallys, + [5] = LightPallys, + [6] = SancPallys, + } + + local assignments = PallyPowerAutoAssignments(pallys, prioritylist, buffers) + if assignments ~= nil then + for buff, buffer in pairs(assignments) do + if PallyPower_Assignments[buffer] == nil then + PallyPower_Assignments[buffer] = {} end + PallyPower_Assignments[buffer][class] = buff + self:TankNormalBlessingOverride(buff, class, buffer) end end end -function PallyPower:BuffSelections(buff, class, pallys) - local t = {} - if buff == 1 then - t = WisdomPallys - end - if buff == 2 then - t = MightPallys - end - if buff == 3 then - t = KingsPallys - end - if not self.isWrath and buff == 4 then - t = SalvPallys - end - if not self.isWrath and buff == 5 then - t = LightPallys - end - if not self.isWrath and buff == 6 then - t = SancPallys - end - if self.isWrath and buff == 4 then - t = SancPallys - end - local Buffer = "" - tsort( - t, - function(a, b) - return a.skill > b.skill - end - ) - for _, v in pairs(t) do - if self:PallyAvailable(v.pallyname, pallys) then --removed check if v.skill / Zid - Buffer = v.pallyname - break - end - end - if Buffer ~= "" then - if (IsInRaid() and buff > 2) then - for pclass = 1, PALLYPOWER_MAXCLASSES do - PallyPower_Assignments[Buffer][pclass] = buff - end - elseif PallyPower_Assignments and not PallyPower_Assignments[Buffer] then - PallyPower_Assignments[Buffer] = {} - PallyPower_Assignments[Buffer][class] = buff - else - PallyPower_Assignments[Buffer][class] = buff - end - if IsInRaid() then - ----------------------------------------------------------------------------------------------------------------- - -- Warriors and Death Knights - ----------------------------------------------------------------------------------------------------------------- - if (buff == self.opt.mainTankGSpellsW) and (class == 1 or (self.isWrath and class == 10)) and self.opt.mainTank then - for i = 1, MAX_RAID_MEMBERS do - local playerName, _, _, _, playerClass = GetRaidRosterInfo(i) - if playerName and self:CheckMainTanks(playerName) and (class == self:GetClassID(string.upper(playerClass))) then - SetNormalBlessings(Buffer, class, playerName, self.opt.mainTankSpellsW) - end +function PallyPower:TankNormalBlessingOverride(buff, class, Buffer) + if IsInRaid() then + ----------------------------------------------------------------------------------------------------------------- + -- Warriors and Death Knights + ----------------------------------------------------------------------------------------------------------------- + if (buff == self.opt.mainTankGSpellsW) and (class == 1 or (self.isWrath and class == 10)) and self.opt.mainTank then + for i = 1, MAX_RAID_MEMBERS do + local playerName, _, _, _, playerClass = GetRaidRosterInfo(i) + if playerName and self:CheckMainTanks(playerName) and (class == self:GetClassID(string.upper(playerClass))) then + SetNormalBlessings(Buffer, class, playerName, self.opt.mainTankSpellsW) end end - if (buff == self.opt.mainAssistGSpellsW) and (class == 1 or (self.isWrath and class == 10)) and self.opt.mainAssist then - for i = 1, MAX_RAID_MEMBERS do - local playerName, _, _, _, playerClass = GetRaidRosterInfo(i) - if playerName and self:CheckMainAssists(playerName) and (class == self:GetClassID(string.upper(playerClass))) then - SetNormalBlessings(Buffer, class, playerName, self.opt.mainAssistSpellsW) - end + end + if (buff == self.opt.mainAssistGSpellsW) and (class == 1 or (self.isWrath and class == 10)) and self.opt.mainAssist then + for i = 1, MAX_RAID_MEMBERS do + local playerName, _, _, _, playerClass = GetRaidRosterInfo(i) + if playerName and self:CheckMainAssists(playerName) and (class == self:GetClassID(string.upper(playerClass))) then + SetNormalBlessings(Buffer, class, playerName, self.opt.mainAssistSpellsW) end end - ----------------------------------------------------------------------------------------------------------------- - -- Druids and Paladins - ----------------------------------------------------------------------------------------------------------------- - if (buff == self.opt.mainTankGSpellsDP) and (class == 4 or class == 5) and self.opt.mainTank then - for i = 1, MAX_RAID_MEMBERS do - local playerName, _, _, _, playerClass = GetRaidRosterInfo(i) - if playerName and self:CheckMainTanks(playerName) and (class == self:GetClassID(string.upper(playerClass))) then - SetNormalBlessings(Buffer, class, playerName, self.opt.mainTankSpellsDP) - end + end + ----------------------------------------------------------------------------------------------------------------- + -- Druids and Paladins + ----------------------------------------------------------------------------------------------------------------- + if (buff == self.opt.mainTankGSpellsDP) and (class == 4 or class == 5) and self.opt.mainTank then + for i = 1, MAX_RAID_MEMBERS do + local playerName, _, _, _, playerClass = GetRaidRosterInfo(i) + if playerName and self:CheckMainTanks(playerName) and (class == self:GetClassID(string.upper(playerClass))) then + SetNormalBlessings(Buffer, class, playerName, self.opt.mainTankSpellsDP) end end - if (buff == self.opt.mainAssistGSpellsDP) and (class == 4 or class == 5) and self.opt.mainAssist then - for i = 1, MAX_RAID_MEMBERS do - local playerName, _, _, _, playerClass = GetRaidRosterInfo(i) - if playerName and self:CheckMainAssists(playerName) and (class == self:GetClassID(string.upper(playerClass))) then - SetNormalBlessings(Buffer, class, playerName, self.opt.mainAssistSpellsDP) - end + end + if (buff == self.opt.mainAssistGSpellsDP) and (class == 4 or class == 5) and self.opt.mainAssist then + for i = 1, MAX_RAID_MEMBERS do + local playerName, _, _, _, playerClass = GetRaidRosterInfo(i) + if playerName and self:CheckMainAssists(playerName) and (class == self:GetClassID(string.upper(playerClass))) then + SetNormalBlessings(Buffer, class, playerName, self.opt.mainAssistSpellsDP) end end end - else - end - return Buffer -end - -function PallyPower:PallyAvailable(pally, pallys) - local available = false - for i in pairs(pallys) do - if pallys[i] == pally then - available = true - end end - return available end function PallyPowerAuraButton_OnClick(btn, mouseBtn) diff --git a/PallyPower.toc b/PallyPower.toc index aa3e608..be7026f 100644 --- a/PallyPower.toc +++ b/PallyPower.toc @@ -31,4 +31,5 @@ locale\zhTW.lua PallyPower.lua PallyPowerValues.lua PallyPowerOptions.lua +PallyPowerAutoAssignment.lua PallyPower_Wrath.xml diff --git a/PallyPowerAutoAssignment.lua b/PallyPowerAutoAssignment.lua new file mode 100644 index 0000000..4956b60 --- /dev/null +++ b/PallyPowerAutoAssignment.lua @@ -0,0 +1,310 @@ +local function is_wrath() + return PallyPower.isWrath +end + +local wisdom = 1 +local might = 2 +local kings = 3 +local salv = 4 +local light = 5 +local sanc = 6 + +if is_wrath() then + sanc = 4 + salv = nil + light = nil +end + +local function is_talented_buff(buff) + if is_wrath() then + return buff == sanc + end + + return tContains({ kings, sanc}, buff) +end + +local function is_improvable_buff(buff) + return tContains({ might, wisdom}, buff) +end + +local function should_reset_skill(buff) + return not is_wrath() and (buff == salv or buff == light) +end + +local function get_preferred_imp_buff(buff_prio) + for _, buff in ipairs(buff_prio) do + if buff == wisdom or buff == might then + return buff + end + end + + return nil +end + +local function get_remaining_buffs(pallys, preferred_buffs, assignments) + local remaining_buffs = {} + local assigned_buffs = {} + local num_assignments = 0 + for buff, _ in pairs(assignments) do + table.insert(assigned_buffs, buff) + num_assignments = num_assignments + 1 + end + + for _, buff in ipairs(preferred_buffs) do + if num_assignments < #pallys and not tContains(assigned_buffs, buff) then + table.insert(remaining_buffs, buff) + num_assignments = num_assignments + 1 + end + end + + return remaining_buffs +end + +local function get_assigned_buff(buffer, assignments) + for buff, b in pairs(assignments) do + if b == buffer then + return buff + end + end + + return nil +end + +local function get_buffer_skill(buffer, buff_buffers) + for _, b in ipairs(buff_buffers) do + if b.pallyname == buffer then + return b.skill + end + end + + return 0 +end + +local function recalc_buff_skills(pallys, orig_buffers) + local new_buffers = {} + for buff, buffers in ipairs(orig_buffers) do + new_buffers[buff] = {} + for _, buffer in ipairs(buffers) do + if tContains(pallys, buffer.pallyname) then + local effective_skill = buffer.skill + if should_reset_skill(buff) then + effective_skill = 1 + end + table.insert(new_buffers[buff], {pallyname = buffer.pallyname, skill = effective_skill}) + end + end + end + + return new_buffers +end + +local function calc_imp_skills(pallys, buffers, pref_imp_buff) + local imp_skills = {} + for _, pally in ipairs(pallys) do + local wisdom_skill = get_buffer_skill(pally, buffers[wisdom]) + local might_skill = get_buffer_skill(pally, buffers[might]) + if pref_imp_buff == wisdom then + wisdom_skill = wisdom_skill * 2 + else + might_skill = might_skill * 2 + end + + imp_skills[pally] = wisdom_skill + might_skill + end + + return imp_skills +end + +local function filter_available(buff_prio, available_buffers) + local available_buffs = {} + for _, buff in ipairs(buff_prio) do + if #available_buffers[buff] > 0 then + table.insert(available_buffs, buff) + end + end + + return available_buffs +end + +local function remove_talented(buff_prio) + local untalented = {} + for _, buff in ipairs(buff_prio) do + if not is_talented_buff(buff) then + table.insert(untalented, buff) + end + end + + return untalented +end + +local function get_buff_position(buff_prio, buff) + for i, b in ipairs(buff_prio) do + if b == buff then + return i + end + end + + return -1 +end + +local function will_get_buff(buff, buff_prio, num_pallys) + local buff_pos = get_buff_position(buff_prio, buff) + if buff_pos == -1 then + return false + end + + return buff_pos <= num_pallys +end + +local function get_most_skilled_buffer(buffers, buff, assignments) + local candidates = {} + for _, candidate in ipairs(buffers[buff]) do + if not is_talented_buff(get_assigned_buff(candidate.pallyname, assignments)) then + table.insert(candidates, candidate) + end + end + + + if #candidates == 0 then + return nil + elseif #candidates == 1 then + return candidates[1].pallyname + end + + table.sort(candidates, function(a, b) return a.skill > b.skill end) + local most_skilled = candidates[1] + + -- swapping only works assuming both players can do both buffs. true because we only do this for untalented buffs + if is_improvable_buff(buff) and tContains(assignments, most_skilled.pallyname) then + local current = get_assigned_buff(most_skilled.pallyname, assignments) + local skill_at_current = get_buffer_skill(most_skilled.pallyname, buffers[current]) + + -- find someone unassigned that has the same skill at the current buff + local backup_buffer + for _, candidate in ipairs(buffers[current]) do + if not tContains(assignments, candidate.pallyname) and candidate.skill == skill_at_current then + backup_buffer = candidate + end + end + + if backup_buffer ~= nil then + assignments[current] = backup_buffer.pallyname + return most_skilled.pallyname + end + + local next_available_most_skilled + for i = 2, #candidates, 1 do + if next_available_most_skilled == nil and not tContains(assignments, candidates[i].pallyname) then + next_available_most_skilled = candidates[i] + end + end + + if next_available_most_skilled == nil then + return nil + end + + most_skilled = next_available_most_skilled + end + + return most_skilled.pallyname +end + +local function get_least_skilled_imp_buffer(buff_buffers, imp_buffers, current_assignments) + local least_skilled + for _, candidate in ipairs(buff_buffers) do + if not tContains(current_assignments, candidate.pallyname) then + if least_skilled == nil or imp_buffers[candidate.pallyname] < imp_buffers[least_skilled] then + least_skilled = candidate.pallyname + end + end + end + + return least_skilled +end + +local function assign_talented_buffers(buff_prio, buffers, num_pallys, imp_buffers) + -- talented buffs, so if they are needed they will get special treatment + local assignments = {} + local needs_sanc = will_get_buff(sanc, buff_prio, num_pallys) + + -- in wrath everyone gets kings, so the only talented buff is sanc + if is_wrath() and needs_sanc then + return {[sanc] = get_least_skilled_imp_buffer(buffers[sanc], imp_buffers, assignments)} + end + + local needs_kings = will_get_buff(kings, buff_prio, num_pallys) + + if needs_kings and needs_sanc then + if #buffers[kings] == 1 and #buffers[sanc] == 1 then + if buffers[kings][1].pallyname == buffers[sanc][1].pallyname then + if get_buff_position(buff_prio, kings) < get_buff_position(buff_prio, sanc) then + assignments[kings] = get_least_skilled_imp_buffer(buffers[kings], imp_buffers, assignments) + else + assignments[sanc] = get_least_skilled_imp_buffer(buffers[sanc], imp_buffers, assignments) + end + else + assignments[kings] = get_least_skilled_imp_buffer(buffers[kings], imp_buffers, assignments) + assignments[sanc] = get_least_skilled_imp_buffer(buffers[sanc], imp_buffers, assignments) + end + elseif #buffers[kings] > 1 and #buffers[sanc] == 1 then + assignments[sanc] = get_least_skilled_imp_buffer(buffers[sanc], imp_buffers, assignments) + assignments[kings] = get_least_skilled_imp_buffer(buffers[kings], imp_buffers, assignments) + else + -- #buffers[kings] == 1 and #buffers[sanc] > 1 or both > 1. + -- either way we can assign kings first and there will be someone to do sanc + assignments[kings] = get_least_skilled_imp_buffer(buffers[kings], imp_buffers, assignments) + assignments[sanc] = get_least_skilled_imp_buffer(buffers[sanc], imp_buffers, assignments) + end + elseif needs_kings and not needs_sanc then + assignments[kings] = get_least_skilled_imp_buffer(buffers[kings], imp_buffers, assignments) + elseif needs_sanc and not needs_kings then + assignments[sanc] = get_least_skilled_imp_buffer(buffers[sanc], imp_buffers, assignments) + end + + return assignments +end + +function PallyPowerAutoAssignments(pallys, preferred_buffs, orig_buffers) + local buffers = recalc_buff_skills(pallys, orig_buffers) + local buff_prio = filter_available(preferred_buffs, buffers) + local pref_imp_buff = get_preferred_imp_buff(buff_prio) + local imp_skills = calc_imp_skills(pallys, buffers, buff_prio, pref_imp_buff) + local assignments = {} + + for buff, buffer in pairs(assign_talented_buffers(buff_prio, buffers, #pallys, imp_skills)) do + assignments[buff] = buffer + end + + buff_prio = remove_talented(buff_prio) + buff_prio = get_remaining_buffs(pallys, buff_prio, assignments) + + for _, buff in ipairs(buff_prio) do + local buffer + if is_improvable_buff(buff) then + buffer = get_most_skilled_buffer(buffers, buff, assignments) + else + buffer = get_least_skilled_imp_buffer(buffers[buff], imp_skills, assignments) + end + + if buffer == nil then + return nil + end + + assignments[buff] = buffer + end + + -- make sure a pally is assigned to only one buff, and some nil checks, otherwise return nil + local verify = {} + for buff, buffer in pairs(assignments) do + if buff == nil or buffer == nil then + return nil + end + if tContains(verify, buffer) then + return nil + end + + table.insert(verify, buffer) + end + + return assignments +end diff --git a/PallyPower_TBC.toc b/PallyPower_TBC.toc index 9d1b655..7f0e513 100644 --- a/PallyPower_TBC.toc +++ b/PallyPower_TBC.toc @@ -31,4 +31,5 @@ locale\zhTW.lua PallyPower.lua PallyPowerValues.lua PallyPowerOptions.lua +PallyPowerAutoAssignment.lua PallyPower_TBC.xml diff --git a/PallyPower_Vanilla.toc b/PallyPower_Vanilla.toc index 98a233b..bff6cad 100644 --- a/PallyPower_Vanilla.toc +++ b/PallyPower_Vanilla.toc @@ -31,4 +31,5 @@ locale\zhTW.lua PallyPower.lua PallyPowerValues.lua PallyPowerOptions.lua +PallyPowerAutoAssignment.lua PallyPower_Vanilla.xml diff --git a/PallyPower_Wrath.toc b/PallyPower_Wrath.toc index aa3e608..be7026f 100644 --- a/PallyPower_Wrath.toc +++ b/PallyPower_Wrath.toc @@ -31,4 +31,5 @@ locale\zhTW.lua PallyPower.lua PallyPowerValues.lua PallyPowerOptions.lua +PallyPowerAutoAssignment.lua PallyPower_Wrath.xml diff --git a/test/test_auto_assignments_tbc.lua b/test/test_auto_assignments_tbc.lua new file mode 100644 index 0000000..f00238b --- /dev/null +++ b/test/test_auto_assignments_tbc.lua @@ -0,0 +1,240 @@ +PallyPower = {isWrath = false} +function tContains(t, val) + for _, v in pairs(t) do + if v == val then + return true + end + end + return false +end + +dofile ("./PallyPowerAutoAssignment.lua") + +local wisdom = 1 +local might = 2 +local kings = 3 +local salv = 4 +local light = 5 +local sanc = 6 + +local pallys = {"holy", "prot", "ret"} +local available_buffers = { + [wisdom] = { + {pallyname = "holy", skill = 9}, + {pallyname = "prot", skill = 7}, + {pallyname = "ret", skill = 7}, + }, + [might] = { + {pallyname = "holy", skill = 13}, + {pallyname = "prot", skill = 8}, + {pallyname = "ret", skill = 8}, + }, + [kings] = { + {pallyname = "holy", skill = 1}, + {pallyname = "prot", skill = 1}, + {pallyname = "ret", skill = 1}, + }, + [salv] = { + {pallyname = "holy", skill = 38}, + {pallyname = "prot", skill = -17}, + {pallyname = "ret", skill = -17}, + }, + [light] = { + {pallyname = "holy", skill = 10}, + {pallyname = "prot", skill = 1}, + {pallyname = "ret", skill = 1}, + }, + [sanc] = { + {pallyname = "prot", skill = 6}, + }, +} + +local assignments = PallyPowerAutoAssignments(pallys, {salv, might, kings, sanc, light}, available_buffers) +assert(assignments[might] == "holy") +assert((assignments[salv] == "prot" and assignments[kings] == "ret") or (assignments[kings] == "prot" and assignments[salv] == "ret")) + +-- prot pally doesn't have kings anymore +available_buffers[kings] = { + {pallyname = "holy", skill = 1}, + {pallyname = "ret", skill = 1}, +} +assignments = PallyPowerAutoAssignments(pallys, {salv, might, kings, sanc, light}, available_buffers) +assert(assignments[might] == "holy") +assert(assignments[salv] == "prot" and assignments[kings] == "ret") + +pallys = {"prot", "ret"} +available_buffers = { + [wisdom] = { + {pallyname = "prot", skill = 7}, + {pallyname = "ret", skill = 7}, + }, + [might] = { + {pallyname = "prot", skill = 13}, + {pallyname = "ret", skill = 8}, + }, + [kings] = { + {pallyname = "prot", skill = 1}, + }, + [salv] = { + {pallyname = "prot", skill = 1}, + {pallyname = "ret", skill = 1}, + }, + [light] = { + {pallyname = "prot", skill = 1}, + {pallyname = "ret", skill = 1}, + }, + [sanc] = { + {pallyname = "prot", skill = 1}, + }, +} + +assignments = PallyPowerAutoAssignments(pallys, {might, kings}, available_buffers) +assert(assignments[might] == "ret") +assert(assignments[kings] == "prot") +assignments = PallyPowerAutoAssignments(pallys, {kings, sanc, might}, available_buffers) +assert(assignments[kings] == "prot") +assert(assignments[might] == "ret") +assert(assignments[sanc] == nil) + +pallys = {"prot"} +assignments = PallyPowerAutoAssignments(pallys, {might, kings}, available_buffers) +assert(assignments[might] == "prot") +assignments = PallyPowerAutoAssignments(pallys, {kings, sanc}, available_buffers) +assert(assignments[kings] == "prot") +assert(assignments[sanc] == nil) +assignments = PallyPowerAutoAssignments(pallys, {sanc, kings}, available_buffers) +assert(assignments[kings] == nil) +assert(assignments[sanc] == "prot") + +pallys = {"prot", "ret"} +available_buffers[kings] = {{pallyname = "ret", skill = 1}} +assignments = PallyPowerAutoAssignments(pallys, {kings, sanc}, available_buffers) +assert(assignments[kings] == "ret") +assert(assignments[sanc] == "prot") + +pallys = {"prot", "ret"} +available_buffers = { + [wisdom] = { + {pallyname = "prot", skill = 7}, + {pallyname = "ret", skill = 7}, + }, + [might] = { + {pallyname = "prot", skill = 13}, + {pallyname = "ret", skill = 8}, + }, + [kings] = { + {pallyname = "prot", skill = 1}, + }, + [salv] = { + {pallyname = "prot", skill = 1}, + {pallyname = "ret", skill = 1}, + }, + [light] = { + {pallyname = "prot", skill = 1}, + {pallyname = "ret", skill = 1}, + }, + [sanc] = { + {pallyname = "prot", skill = 1}, + }, +} + +assignments = PallyPowerAutoAssignments(pallys, {wisdom, might}, available_buffers) +assert(assignments[might] == "prot") +assert(assignments[wisdom] == "ret") +-- different order, same outcome +assignments = PallyPowerAutoAssignments(pallys, {might, wisdom}, available_buffers) +assert(assignments[might] == "prot") +assert(assignments[wisdom] == "ret") + +available_buffers[kings] = {} +assignments = PallyPowerAutoAssignments(pallys, {might, kings, sanc}, available_buffers) +assert(assignments[might] == "ret") +assert(assignments[sanc] == "prot") + +pallys = {"holy1", "holy2", "prot1", "prot2", "ret"} +available_buffers = { + [wisdom] = { + {pallyname = "holy1", skill = 9}, + {pallyname = "holy2", skill = 9}, + {pallyname = "prot1", skill = 7}, + {pallyname = "prot2", skill = 7}, + {pallyname = "ret", skill = 7}, + }, + [might] = { + {pallyname = "holy1", skill = 13}, + {pallyname = "holy2", skill = 12}, + {pallyname = "prot1", skill = 8}, + {pallyname = "prot2", skill = 9}, + {pallyname = "ret", skill = 8}, + }, + [kings] = { + {pallyname = "holy1", skill = 1}, + {pallyname = "prot1", skill = 1}, + {pallyname = "ret", skill = 1} + }, + [salv] = { + {pallyname = "holy1", skill = 1}, + {pallyname = "holy2", skill = 1}, + {pallyname = "prot1", skill = 1}, + {pallyname = "prot2", skill = 1}, + {pallyname = "ret", skill = 1}, + }, + [light] = { + {pallyname = "holy1", skill = 1}, + {pallyname = "holy2", skill = 1}, + {pallyname = "prot1", skill = 1}, + {pallyname = "prot2", skill = 1}, + {pallyname = "ret", skill = 1}, + }, + [sanc] = { + {pallyname = "prot1", skill = 1}, + } +} +assignments = PallyPowerAutoAssignments(pallys, {salv, kings, wisdom, might, sanc, light}, available_buffers) +assert(assignments[salv] == "prot2") +assert(assignments[kings] == "ret") +assert(assignments[wisdom] == "holy2") +assert(assignments[might] == "holy1") +assert(assignments[sanc] == "prot1") + +available_buffers[sanc][1].pallyname = "prot2" +assignments = PallyPowerAutoAssignments(pallys, {salv, kings, wisdom, might, sanc, light}, available_buffers) +assert((assignments[salv] == "prot1" and assignments[kings] == "ret") or (assignments[salv] == "ret" and assignments[kings] == "prot1")) +assert(assignments[wisdom] == "holy2") +assert(assignments[might] == "holy1") +assert(assignments[sanc] == "prot2") + +-- different order, same outcome +assignments = PallyPowerAutoAssignments(pallys, {sanc, salv, might, wisdom, kings, light}, available_buffers) +assert((assignments[salv] == "prot1" and assignments[kings] == "ret") or (assignments[salv] == "ret" and assignments[kings] == "prot1")) +assert(assignments[wisdom] == "holy2") +assert(assignments[might] == "holy1") +assert(assignments[sanc] == "prot2") + +pallys = {"holy", "prot"} +available_buffers = { + [wisdom] = { + {pallyname = "holy", skill = 9}, + {pallyname = "prot", skill = 7}, + }, + [might] = { + {pallyname = "holy", skill = 13}, + {pallyname = "prot", skill = 8}, + }, + [kings] = {}, + [salv] = { + {pallyname = "holy", skill = 1}, + {pallyname = "prot", skill = 1}, + }, + [light] = { + {pallyname = "holy", skill = 1}, + {pallyname = "prot", skill = 1}, + }, + [sanc] = {}, +} +assignments = PallyPowerAutoAssignments(pallys, {sanc, kings, might, wisdom, light}, available_buffers) +assert(assignments[might] == "holy") +assert(assignments[wisdom] == "prot") +assignments = PallyPowerAutoAssignments(pallys, {wisdom, kings, sanc, might, light, salv}, available_buffers) +assert(assignments[wisdom] == "holy") +assert(assignments[might] == "prot") diff --git a/test/test_auto_assignments_wrath.lua b/test/test_auto_assignments_wrath.lua new file mode 100644 index 0000000..6be0c6e --- /dev/null +++ b/test/test_auto_assignments_wrath.lua @@ -0,0 +1,56 @@ +PallyPower = {isWrath = true} +function tContains(t, val) + for _, v in pairs(t) do + if v == val then + return true + end + end + return false +end + +dofile ("./PallyPowerAutoAssignment.lua") + +local wisdom = 1 +local might = 2 +local kings = 3 +local sanc = 4 + +local pallys = {"holy", "prot", "ret"} +local available_buffers = { + [wisdom] = { + {pallyname = "holy", skill = 11}, + {pallyname = "prot", skill = 9}, + {pallyname = "ret", skill = 9}, + }, + [might] = { + {pallyname = "holy", skill = 15}, + {pallyname = "prot", skill = 10}, + {pallyname = "ret", skill = 10}, + }, + [kings] = { + {pallyname = "holy", skill = 1}, + {pallyname = "prot", skill = 1}, + {pallyname = "ret", skill = 1}, + }, + [sanc] = {} +} +local assignments = PallyPowerAutoAssignments(pallys, {kings, wisdom, sanc, might}, available_buffers) +assert(assignments[wisdom] == "holy") +assert((assignments[might] == "prot" and assignments[kings] == "ret") or (assignments[might] == "ret" and assignments[kings] == "prot")) + +pallys[4] = "holy2" +available_buffers[wisdom][4] = {pallyname = "holy2", skill = 10} +available_buffers[might][4] = {pallyname = "holy2", skill = 14} +available_buffers[kings][4] = {pallyname = "holy2", skill = 1} +available_buffers[sanc][1] = {pallyname = "holy2", skill = 1} +assignments = PallyPowerAutoAssignments(pallys, {kings, wisdom, sanc, might}, available_buffers) +assert(assignments[wisdom] == "holy") +assert((assignments[might] == "prot" and assignments[kings] == "ret") or (assignments[might] == "ret" and assignments[kings] == "prot")) +assert(assignments[sanc] == "holy2") + +available_buffers[wisdom][4].skill = 11 +available_buffers[sanc] = {} +assignments = PallyPowerAutoAssignments(pallys, {kings, wisdom, sanc, might}, available_buffers) +assert(assignments[wisdom] == "holy2") +assert(assignments[might] == "holy") +assert(assignments[kings] == "prot" or assignments[kings] == "ret")