-
Notifications
You must be signed in to change notification settings - Fork 0
/
Instance.lua
205 lines (192 loc) · 6.26 KB
/
Instance.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
-- namespace
local _, ns = ...;
-- imports
local ITEM_LIST = ns.ITEM_LIST
local Raids = ns.Raids
local utils = ns.utils
---
-- The instance represents a raid ID to preserve the priority lists for each
-- player invited to the raid.
--
local Instance = {
-- the name of the instance
name,
-- a set of raid names, e.g. Molten Core
raids,
-- the custom priority level
prio,
-- the date and time this instance was created
created,
-- a map of player names pointing to their priority lists
players,
-- a set of items that dropped in the instance so far
history,
-- a set of players that responded to the role check
rolecheck
}
Instance.__index = Instance
ns.Instance = Instance
---
-- Creates a new Instance with the given name and raid.
--
-- @param #string name
-- the name of the instance
-- @param #string raids
-- a set of raid names, e.g. Molten Core
-- @param #number prio
-- the custom priority level, defaults to 0
--
-- @return #Instance
-- the new Instance
--
function Instance.new(name, raids, prio)
local self = setmetatable({}, Instance)
self.name = name
self.raids = raids
self.prio = prio or 0
self.created = date("%y-%m-%d %H:%M:%S")
self.players = {}
self.history = {}
self.rolecheck = {}
return self
end
---
-- Creates a new Instance based on the contents of the given instance.
--
-- @param #Instance instance
-- the instance to be copied
--
-- @return #Instance
-- the copy of the instance, not nil
--
function Instance.copy(instance)
local copy = setmetatable({}, Instance)
copy.name = instance.name
copy.prio = instance.prio or 0
copy.created = instance.created
copy.history = utils.copy(instance.history) or {}
copy.rolecheck = utils.copy(instance.rolecheck) or {}
copy.players = {}
for name, list in pairs(instance.players) do
copy.players[name] = utils.copy(list)
end
if (instance.raid) then
-- backwards compatibility since raid was a single raid string before
copy.raids = { [instance.raid] = true }
else
copy.raids = instance.raids
end
return copy
end
---
-- Creates the random priority loot list for the given player and instance.
-- Every item that can drop in the given raid instance, is on the players
-- need-list and corresponds to the players class and role will be added to the
-- list. Finally the order of the items in the list will be shuffled.
--
-- @param #Instance instance
-- the instance the player is attending
-- @param #Player player
-- the player to create the list for
--
-- @return #table
-- the list of items for the player
--
local function createLootList(instance, player)
local itemsPerPriority = {}
-- get custom priority items
local customPrioItems = {}
local rolecheck = instance.rolecheck[player.name]
if (rolecheck and type(rolecheck) == "table") then
local items = {}
for index, itemId in ipairs(rolecheck.prioItems or {}) do
local item = ITEM_LIST[itemId]
if (item and item:dropsIn(instance.raids) and player:needsItem(item)) then
table.insert(items, itemId)
customPrioItems[itemId] = true
end
end
-- consider custom priority as prio 0
itemsPerPriority[0] = items
end
-- create a loot list
for itemId, item in pairs(ITEM_LIST) do
-- check exclusion filter
if (not(ns.DB.options.excludeLegendaries and item.legendary) and
item:dropsIn(instance.raids) and player:needsItem(item)) then
if (not customPrioItems[itemId]) then
local priority = item:getPriority(player)
local items = itemsPerPriority[priority] or {}
table.insert(items, itemId)
itemsPerPriority[priority] = items
end
end
end
-- concatenate the item lists
local items = {}
for i = 0, 10, 1 do
local prioItems = itemsPerPriority[i]
if (prioItems) then
-- shuffle the items
if (i > 0) then
prioItems = utils.shuffle(prioItems)
end
for index, itemId in ipairs(prioItems) do
table.insert(items, itemId)
end
end
end
return items
end
---
-- Adds the given player to this instance. This will automatically create the
-- priority list for the player.
-- Does nothing if the player is already present in this instance. However, if
-- the given force flag is set to true, the player will be re-added and the
-- priority list is shuffled again.
--
-- @param #Player player
-- the player to be added to the instance
-- @param #boolean force
-- if the player should be re-added
--
-- @return #boolean
-- true if the player was added to the instance, nil otherwise
--
function Instance:addPlayer(player, force)
local instance = self
if (player) then
if ((not instance.players[player.name]) or force) then
instance.players[player.name] = createLootList(instance, player)
-- update the role check status
local rolecheck = instance.rolecheck[player.name] or {}
rolecheck.roles = utils.copy(player.roles)
rolecheck.trial = player.trial or false
instance.rolecheck[player.name] = rolecheck
return true
end
end
end
---
-- Adds the given item to the loot history of this instance. Does nothing
-- if the item is already present.
--
-- @param #Item item
-- the item to be added
--
function Instance:addItem(item)
local instance = self
if (item) then
instance.history[item.itemId] = true
end
end
---
-- Prints the instance information to the console output.
--
function Instance:print()
local instance = self
print("> Instance '"..instance.name.."':")
print(" Raid: '"..Raids.toString(instance.raids).."'")
print(" Prio: '"..tostring(instance.prio).."'")
print(" created: "..instance.created)
end