Skip to content

Commit

Permalink
Add disenchant feature
Browse files Browse the repository at this point in the history
  • Loading branch information
Anonomit committed Nov 9, 2022
1 parent e8f08c0 commit 31f1e4e
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 5 deletions.
75 changes: 73 additions & 2 deletions Server.lua
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ LootReserve.Server =
RollLimitDuration = false,
RollDuration = 30,
RollFinishOnExpire = false,
Disenchanters = { },
RollDisenchant = false,
RollDisenchanters = { },
RollFinishOnAllReservingRolled = true,
RollFinishOnRaidRoll = false,
RollSkipNotContested = true,
Expand Down Expand Up @@ -160,6 +163,20 @@ StaticPopupDialogs["LOOTRESERVE_CONFIRM_CUSTOM_ROLL_RESERVED_ITEM"] =
end,
};

StaticPopupDialogs["LOOTRESERVE_CONFIRM_DISENCHANT_RESERVED_ITEM"] =
{
text = "Are you sure you want to send to disenchanter?|n|n%s has been reserved by:|n%s.",
button1 = YES,
button2 = NO,
timeout = 0,
whileDead = 1,
hideOnEscape = 1,
OnAccept = function(self)
self.data.Frame:SetItem(nil);
LootReserve.Server:RecordDisenchant(self.data.Item, self.data.Disenchanter, true);
end,
};

StaticPopupDialogs["LOOTRESERVE_CONFIRM_ROLL_RESERVED_ITEM_AGAIN"] =
{
text = "Are you sure you want to roll %s among reserving players?|n|nIt has already been won by %s.",
Expand Down Expand Up @@ -299,6 +316,20 @@ StaticPopupDialogs["LOOTRESERVE_CONFIRM_RESET_PHASES"] =
end,
};

StaticPopupDialogs["LOOTRESERVE_CONFIRM_RESET_DISENCHANTERS"] =
{
text = "Are you sure you want to clear the list of disenchanters?",
button1 = YES,
button2 = NO,
timeout = 0,
whileDead = 1,
hideOnEscape = 1,
OnAccept = function(self)
LootReserve.Server.Settings.RollDisenchanters = { };
LootReserve.Server.Settings.Disenchanters = { };
end,
};

StaticPopupDialogs["LOOTRESERVE_CONFIRM_CLEAR_HISTORY"] =
{
text = "Are you sure you want to clear all %d roll%s?",
Expand Down Expand Up @@ -2472,10 +2503,15 @@ end

function LootReserve.Server:ExpireRollRequest()
if self.RequestedRoll then
local item = self.RequestedRoll.Item;
local disenchanter = self:GetDisenchanter();
if self:GetWinningRollAndPlayers() then
-- If someone rolled on this phase - end the roll
if self.Settings.RollFinishOnExpire then
self:FinishRollRequest(self.RequestedRoll.Item);
if disenchanter then
self:RecordDisenchant(item, disenchanter);
end
end
else
-- If nobody rolled on this phase - advance to the next
Expand All @@ -2484,12 +2520,18 @@ function LootReserve.Server:ExpireRollRequest()
-- If the phase cannot advance (i.e. because we ran out of phases) - end the roll
if self.Settings.RollFinishOnExpire then
self:FinishRollRequest(self.RequestedRoll.Item);
if disenchanter then
self:RecordDisenchant(item, disenchanter);
end
end
end
elseif not self.RequestedRoll.Phases or #self.RequestedRoll.Phases <= 1 then
-- If no more phases remaining - end the roll
if self.Settings.RollFinishOnExpire then
self:FinishRollRequest(self.RequestedRoll.Item);
if disenchanter then
self:RecordDisenchant(item, disenchanter);
end
end
end
end
Expand Down Expand Up @@ -2837,7 +2879,7 @@ function LootReserve.Server:CancelRollRequest(item, winners, noHistory, advancin
end
end

function LootReserve.Server:RecordRollHistory(roll, winner, excludePlayers)
function LootReserve.Server:RecordRollHistory(roll, winner)
if winner then
roll.Winners = { winner };
end
Expand Down Expand Up @@ -2865,6 +2907,33 @@ function LootReserve.Server:RecordRollHistory(roll, winner, excludePlayers)
end
end

function LootReserve.Server:RecordDisenchant(item, disenchanter, handleRecentLootRemoval)
LootReserve.Server:RecordRollHistory(
{
Players = { [disenchanter] = { 0 } },
Item = item,
StartTime = time(),
Disenchant = true,
}, disenchanter);
if handleRecentLootRemoval and self.Settings.RemoveRecentLootAfterRolling then
LootReserve:TableRemove(self.RecentLoot, item);
end
self:UpdateRollList();
end

function LootReserve.Server:GetDisenchanter()
local names = { };
LootReserve:ForEachRaider(function(name) names[name] = true end);
if self.Settings.RollDisenchant then
for _, name in ipairs(self.Settings.RollDisenchanters) do
if names[name] then
return name;
end
end
end
return nil;
end

function LootReserve.Server:GetContinueRollData(oldRoll)
-- Copy historical roll into RequestedRoll
local Roll = LootReserve:Deepcopy(oldRoll);
Expand All @@ -2887,7 +2956,9 @@ function LootReserve.Server:GetContinueRollData(oldRoll)
end

local doRequestRoll = true;
if Roll.Custom then
if Roll.Disenchant then
doRequestRoll = false;
elseif Roll.Custom then
for _, winner in ipairs(Roll.Winners or {}) do
Roll.Players[winner] = nil;
end
Expand Down
2 changes: 1 addition & 1 deletion Windows/ServerWindow.lua
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ function LootReserve.Server:UpdateRollList(lockdown)
end
end

frame.ReservesFrame.HeaderPlayer:SetText(roll.RaidRoll and "Raid-rolled to" or roll.Custom and format("Rolled%s by", roll.Phases and format(" for |cFF00FF00%s|r", roll.Phases[1] or "") or "") or "Reserved by");
frame.ReservesFrame.HeaderPlayer:SetText(roll.RaidRoll and "Raid-rolled to" or roll.Disenchant and "Disenchanted" or roll.Custom and format("Rolled%s by", roll.Phases and format(" for |cFF00FF00%s|r", roll.Phases[1] or "") or "") or "Reserved by");
frame.ReservesFrame.NoRollsPlaceholder:SetShown(last == 0);
if frame.ReservesFrame.NoRollsPlaceholder:IsShown() then
reservesHeight = reservesHeight + 16;
Expand Down
109 changes: 107 additions & 2 deletions Windows/ServerWindow.xml
Original file line number Diff line number Diff line change
Expand Up @@ -446,10 +446,16 @@
players[i] = LootReserve:ColoredPlayer(players[i]);
end
end
local disenchanter = LootReserve.Server:GetDisenchanter();
local menu =
{
{ text = "End Roll", isTitle = true },
{ text = players and format("Announce %d |4Winner:Winners; (%s)", #players, strjoin(", ", unpack(players))) or "Announce Winner", disabled = not players or #players == 0, func = function() LootReserve.Server:FinishRollRequest(self:GetParent().Item); end },
{
text = format(disenchanter and "Send to Disenchanter: %s" or "Send to Disenchanter", disenchanter and LootReserve:ColoredPlayer(disenchanter)),
disabled = not disenchanter,
func = function() LootReserve.Server:FinishRollRequest(self:GetParent().Item, nil, true); LootReserve.Server:RecordDisenchant(self:GetParent().Item); end,
},
{ text = "End Silently", func = function() LootReserve.Server:FinishRollRequest(self:GetParent().Item, nil, true); end },
{ text = "Cancel Roll", func = function() LootReserve.Server:CancelRollRequest(self:GetParent().Item, nil, true); end },
LootReserve:MakeMenuSeparator(),
Expand Down Expand Up @@ -972,7 +978,7 @@
end
if i == 1 then
if frame.Roll.Winners then
LootReserve:SendChatMessage(format(" Reserved by %s", frame.Roll.Winners[1]), info.arg1, recipient);
LootReserve:SendChatMessage(format(" %s by %s", frame.Roll.Disenchant and "Disenchanted" or "Reserved", frame.Roll.Winners[1]), info.arg1, recipient);
else
LootReserve:SendChatMessage(" No Rolls", info.arg1, recipient);
end
Expand Down Expand Up @@ -1254,12 +1260,89 @@
checked = LootReserve.Server.Settings.RollCountdown == time,
});
end

-- Disenchanter
local disenchanterMenu = { };
for _, contains in ipairs({ true, false }) do
local first = true;
local i = 0;
for _, name in ipairs(contains and LootReserve.Server.Settings.RollDisenchanters or LootReserve.Server.Settings.Disenchanters) do
if LootReserve:Contains(LootReserve.Server.Settings.RollDisenchanters, name) == contains then
if #disenchanterMenu > 0 and first then
table.insert(disenchanterMenu, LootReserve:MakeMenuSeparator());
end
first = false;
i = i + 1;
table.insert(disenchanterMenu,
{
text = contains and format("|cFF00FF00%d. %s|r", i, LootReserve:ColoredPlayer(name)) or LootReserve:ColoredPlayer(name),
arg1 = name,
arg2 = contains,
func = function(info, name, contains)
if contains then
for index, i in ipairs(LootReserve.Server.Settings.RollDisenchanters) do
if i == name then
table.remove(LootReserve.Server.Settings.RollDisenchanters, index);
break;
end
end
else
table.insert(LootReserve.Server.Settings.RollDisenchanters, name);
end
LootReserve:ReopenMenu(self, "#disenchanters");
end,
checked = contains,
});
end
end
end
if #disenchanterMenu > 0 then
table.insert(disenchanterMenu, LootReserve:MakeMenuSeparator());
end
table.insert(disenchanterMenu, { text = "Manage", isTitle = true });
local disenchanters = { };
LootReserve:ForEachRaider(function(name)
disenchanters[name] = true;
end)
for name in pairs(LootReserve.Server.CurrentSession and LootReserve.Server.CurrentSession.Members or LootReserve.Server.NewSessionSettings and LootReserve.Server.NewSessionSettings.ImportedMembers or {}) do
disenchanters[name] = true;
end
local disenchantersList = { };
for name in pairs(disenchanters) do
if not LootReserve:Contains(LootReserve.Server.Settings.Disenchanters, name) then
table.insert(disenchantersList, name);
end
end
table.sort(disenchantersList, function(a, b) return b >= a end);
local addDisenchantersMenu = { };
for _, name in ipairs(disenchantersList) do
table.insert(addDisenchantersMenu, { text = LootReserve:ColoredPlayer(name), func = function(info)
table.insert(LootReserve.Server.Settings.Disenchanters, name);
LootReserve:ReopenMenu(self, "#disenchanters");
end });
end
table.insert(disenchanterMenu, { text = "Add...", menuList = addDisenchantersMenu });
local removeDisenchantersMenu = { };
for _, name in ipairs(LootReserve.Server.Settings.Disenchanters) do
table.insert(removeDisenchantersMenu, { text = LootReserve:ColoredPlayer(name), arg1 = name, func = function(info)
LootReserve:TableRemove(LootReserve.Server.Settings.Disenchanters, info.arg1);
LootReserve:TableRemove(LootReserve.Server.Settings.RollDisenchanters, info.arg1);
LootReserve:ReopenMenu(self, "#disenchanters");
end });
end
table.insert(disenchanterMenu, { text = "Remove...", menuList = removeDisenchantersMenu });
table.insert(disenchanterMenu, { text = "Clear", func = function()
CloseMenus();
StaticPopup_Show("LOOTRESERVE_CONFIRM_RESET_DISENCHANTERS");
end });

local item, link = self:GetParent().Item, self:GetParent().Link;
local token;
if not LootReserve.Server.ReservableIDs[item:GetID()] and LootReserve.Server.ReservableRewardIDs[item:GetID()] then
token = LootReserve.ItemCache:Item(LootReserve.Data:GetToken(item:GetID())) or LootReserve.ItemCache:Item(LootReserve.Data:GetToken(item:GetID()));
end

local disenchanter = LootReserve.Server:GetDisenchanter();
local menu =
{
{ text = "Start Roll", isTitle = true },
Expand All @@ -1280,6 +1363,8 @@
end, },
{ text = "Auto Raid-Roll", func = RaidRoll },
LootReserve:MakeMenuSeparator(),
-- Master Loot options go here
LootReserve:MakeMenuSeparator(),
{ text = "Settings for \"Reserving Players\"", isTitle = true },
{
text = "Skip Roll if Not Contested",
Expand All @@ -1303,6 +1388,14 @@
hasArrow = LootReserve.Server.Settings.RollUsePhases,
menuList = phaseMenu,
},
{
text = format(disenchanter and "Disenchanter: %s" or "Disenchant", disenchanter and LootReserve:ColoredPlayer(disenchanter)),
arg1 = "#disenchanters",
checked = LootReserve.Server.Settings.RollDisenchant,
func = function(_, _, _, checked) LootReserve.Server.Settings.RollDisenchant = checked; LootReserve:ReopenMenu(self); end,
hasArrow = LootReserve.Server.Settings.RollDisenchant,
menuList = disenchanterMenu,
},
{
text = format(LootReserve.Server.Settings.RollLimitDuration and (LootReserve.Server.Settings.RollCountdown and "Limit Duration: |cFF00FF00%s|r|cFF808080 (%d secs C/D)|r" or "Limit Duration: |cFF00FF00%s|r") or "Limit Duration", FormatTime(LootReserve.Server.Settings.RollDuration), LootReserve.Server.Settings.RollCountdown),
arg1 = "#duration",
Expand Down Expand Up @@ -1337,7 +1430,6 @@
{ text = "Cancel" },
};

table.insert(menu, 5, LootReserve:MakeMenuSeparator());
local warning = (function()
if not IsMasterLooter() or GetLootMethod() ~= "master" then
return "Not master looter";
Expand Down Expand Up @@ -1365,6 +1457,19 @@
func = function(_, _, _, checked) LootReserve.Server.Settings.RollMasterLoot = checked; end,
});

table.insert(menu, 3,
{ text = format(disenchanter and "To Disenchanter: %s" or "To Disenchanter", disenchanter and LootReserve:ColoredPlayer(disenchanter)),
disabled = not disenchanter,
func = function(...)
if not LootReserve.Server.CurrentSession or not LootReserve.Server.CurrentSession.ItemReserves[token and token:GetID() or item:GetID()] then
self:GetParent():SetItem(nil);
LootReserve.Server:RecordDisenchant(item, true);
else
StaticPopup_Show("LOOTRESERVE_CONFIRM_DISENCHANT_RESERVED_ITEM", link, LootReserve:FormatReservesTextColored(LootReserve.Server.CurrentSession.ItemReserves[token and token:GetID() or item:GetID()].Players), {Item = item, Disenchanter = disenchanter, Frame = self:GetParent()});
end
end,
});

if LootReserve.Server.Settings.RollUsePhases and #LootReserve.Server.Settings.RollPhases > 0 then
for i = #LootReserve.Server.Settings.RollPhases, 1, -1 do
table.insert(menu, 3,
Expand Down

0 comments on commit 31f1e4e

Please sign in to comment.