This repository has been archived by the owner on May 10, 2022. It is now read-only.
forked from semlar/NomiCakes
-
Notifications
You must be signed in to change notification settings - Fork 0
/
NomiCakes.lua
594 lines (564 loc) · 26.9 KB
/
NomiCakes.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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
--[[
Operating under the following assumptions about how recipes are discovered:
1) You must know the base rank of a recipe to receive higher ranked versions of it
2) You must already know all recipes which are reagents for the recipe (No longer true in 7.1)
--]]
NomiCakesGossipButtonName = 'GossipTitleButton' -- Allow other addons to override the buttons we hook, if needed
local HookedButtons = {} -- [button] = true
local Undiscoverable = { -- List of rank 1 recipes that can't be obtained from nomi
-- [recipeID] = recipeName,
-- Quests
[201513] = 'Dropped by |Hunit:Creature-0-0-0-0-93371-0|h[Mordvigbjorn]|h (Stormheim 72.6, 50.0)', -- Bear Tartare
[201496] = 'Quest: |cffffff00|Hquest:39117|h[Shriek No More]|h|r, |Hunit:Creature-0-0-0-0-94117-0|h[Cecily Radcliffe]|h (Val\'sharah 36.0, 57.0)', -- Deep-Fried Mossgill
[201512] = 'Quest: |cffffff00|Hquest:40988|h[Too Many Cooks]|h|r, |Hunit:Creature-0-0-0-0-101846-0|h[Nomi]|h (Dalaran)', -- Dried Mackerel Strips
[201498] = 'Quest: |cffffff00|Hquest:37727|h[The Magister of Mixology]|h|r, |Hunit:Creature-0-0-0-0-89341-0|h[Magister Garuhod]|h (47.0, 41.4)', -- Faronaar Fizz
[201514] = 'Quest: |cffffff00|Hquest:37536|h[Morale Booster]|h|r, |Hunit:Creature-0-0-0-0-88923-0|h[Sternfathom]|h (48.0, 48.6)', -- Fighter Chow
[201497] = 'Quest: |cffffff00|Hquest:40078|h[A Heavy Burden]|h|r, |Hunit:Creature-0-0-0-0-92539-0|h[Havi]|h (Stormheim 60.2, 50.8)', -- Pickled Stormray
[201413] = 'Quest: |cffffff00|Hquest:39867|h[I\'m Not Lion!]|h|r, |Hunit:Creature-0-0-0-0-95438-0|h[Ellias]|h (Highmountain 40.0, 52.2)', -- Salt and Pepper Shank
[201499] = 'Quest chain: |cffffff00|Hquest:39789|h[Eating Into Our Business]|h|r, |Hunit:Creature-0-0-0-0-97258-0|h[Ootasa Galehoof]|h (Stormheim 51.2, 57.0)', -- Spiced Rib Roast
[201503] = 'Sold by |Hunit:Creature-0-0-0-0-112226-0|h[Markus Hjolbruk]|h (Suramar 71.6, 48.8)', -- Koi-Scented Stormray
-- Other stuff
[201501] = '|cff1eff00|Hitem:141011|h[Surf]|h|r dropped by |Hunit:Creature-0-0-0-0-99720-0|h[Coastal Spikeback]|h (Suramar 76,50) |cff1eff00|Hitem:141012|h[Turf]|h|r dropped by |Hunit:Creature-0-0-0-0-110042-0|h[Heartwood Stag]|h (Suramar 65,45)', -- Suramar Surf and Turf
[201502] = 'Quest: |cffffff00|Hquest:40102|h[Murlocs: The Next Generation]|h|r, |Hunit:Creature-0-0-0-0-98067-0|h[King Mrgl-Mrgl]|h (Highmountain 42.6, 10.8)', -- 'Barracuda Mrglgagh',
[201500] = 'Dropped by |Hunit:Creature-0-0-0-0-110340-0|h[Myonix]|h (Suramar 40.8, 32.8)', -- Leybeque Ribs
[201504] = 'Dropped (rarely) by Drogbar (Highmountain 53.3, 62.4)', -- Drogbar-Style Salmon
}
local Requisites = { -- List of recipes you must (probably) already know in order to discover a recipe from nomi
-- While technically you need to know the previous rank of a spell to receive the next one,
-- we'll use the base rank as the requirement for all ranks because it's more intuitive
-- I only want to grey-out recipes that we can't learn because we don't know the base rank
--[[
-- 7.1 patch notes imply that recipes no longer require knowing other recipes to learn
[201506] = {201501}, -- Azshari Salad: Suramar Surf and Turf
[201508] = {201503}, -- Seed-Battered Fish Plate: Kio-Scented Stormray
[201507] = {201502}, -- Nightborne Delicacy Platter: Barracuda Mrglgagh
[201505] = {201500}, -- The Hungry Magister: Leybeque Ribs
[201511] = {201504}, -- Fishbrul Special: Drogbar-Style Salmon
[201538] = {201511}, -- Fishbrul Special
[201558] = {201511}, -- Fishbrul Special
[201534] = {201505}, -- The Hungry Magister
[201554] = {201505}, -- The Hungry Magister
[201535] = {201506}, -- Azshari Salad
[201555] = {201506}, -- Azshari Salad
[201536] = {201507}, -- Nightborne Delicacy Platter
[201556] = {201507}, -- Nightborne Delicacy Platter
[201537] = {201508}, -- Seed-Battered Fish Plate
[201557] = {201508}, -- Seed-Battered Fish Plate
--]]
[201515] = {201413, 201496, 201497, 201498, 201499}, -- Hearty Feast
[201542] = {201515}, -- Hearty Feast
[201562] = {201515}, -- Hearty Feast
[201516] = {201500, 201501, 201502, 201503, 201504}, -- Lavish Suramar Feast
[201543] = {201516}, -- Lavish Suramar Feast
[201563] = {201516}, -- Lavish Suramar Feast
[201531] = {201502}, -- Barracuda Mrglgagh
[201551] = {201502}, -- Barracuda Mrglgagh
[201533] = {201504}, -- Drogbar-Style Salmon
[201553] = {201504}, -- Drogbar-Style Salmon
[201539] = {201512}, -- Dried Mackerel Strips
[201559] = {201512}, -- Dried Mackerel Strips
[201541] = {201514}, -- Fighter Chow
[201561] = {201514}, -- Fighter Chow
[201530] = {201501}, -- Suramar Surf and Turf
[201550] = {201501}, -- Suramar Surf and Turf
[201524] = {201413}, -- Salt and Pepper Shank
[201544] = {201413}, -- Salt and Pepper Shank
[201526] = {201497}, -- Pickled Stormray
[201546] = {201497}, -- Pickled Stormray
[201532] = {201503}, -- Koi-Scented Stormray
[201552] = {201503}, -- Koi-Scented Stormray
[201528] = {201499}, -- Spiced Rib Roast
[201548] = {201499}, -- Spiced Rib Roast
[201525] = {201496}, -- Deep-Fried Mossgill
[201545] = {201496}, -- Deep-Fried Mossgill
[201540] = {201513}, -- Bear Tartare
[201560] = {201513}, -- Bear Tartare
[201529] = {201500}, -- Leybeque Ribs
[201549] = {201500}, -- Leybeque Ribs
[201527] = {201498}, -- Faronaar Fizz
[201547] = {201498}, -- Faronaar Fizz
}
local IngredientList = { -- In the order they appear in Nomi's dialog options
[124117] = {201506,201555,201544,201516,201563,201550,201524,201543,201530,201535,201515,201542,201562}, -- Lean Shank
[124121] = {201536,201547,201562,201507,201515,201527,201542,201556}, -- Wildfowl Egg
[124119] = {201562,201549,201542,201529,201516,201548,201505,201528,201554,201534,201543,201515,201563}, -- Big Gamy Ribs
[124118] = {201560,201554,201534,201505,201540}, -- Fatty Bearsteak
[124120] = {201534,201551,201536,201529,201531,201563,201505,201507,201554,201556,201543,201549,201516}, -- Leyblood
[124107] = {201511,201561,201541,201558,201538}, -- Cursed Queenfish
[124108] = {201525,201545,201562,201542,201515,201558,201538,201511}, -- Mossgill Perch
[124109] = {201534,201538,201516,201533,201505,201558,201554,201511,201543,201553,201563}, -- Highmountain Salmon
[124110] = {201532,201508,201542,201537,201516,201563,201557,201552,201546,201526,201543,201515,201562}, -- Stormray
[124111] = {201532,201506,201508,201555,201557,201516,201563,201550,201552,201537,201543,201530,201535}, -- Runescale Koi
[124112] = {201551,201538,201531,201563,201558,201507,201536,201556,201543,201511,201516}, -- Black Barracuda
[133680] = {201562,201684,201542,201516,201683,201685,201543,201515,201563}, -- Slabs of Bacon
[133607] = {201539,201557,201537,201559,201508}, -- Silver Mackerel
}
local IngredientOrder = {
124117, -- Lean Shank
124121, -- Wildfowl Egg
124119, -- Big Gamy Ribs
124118, -- Fatty Bearsteak
124120, -- Leyblood
124107, -- Cursed Queenfish
124108, -- Mossgill Perch
124109, -- Highmountain Salmon
124110, -- Stormray
124111, -- Runescale Koi
124112, -- Black Barracuda
133680, -- Slabs of Bacon
133607, -- Silver Mackerel
}
local LocalizedIngredientList = {} -- [itemID] = {itemName, itemLink}
local TooltipInfo = {} -- [button] = {[i] = 'recipe name?'}
local function GetRank(info)
return not info.nextRecipeID and 3 or info.previousRecipeID and 2 or 1
end
local RecipeCache = {} -- [recipeID] = info
local f = CreateFrame('frame')
local function GossipResize(titleButton)
titleButton:SetHeight( titleButton:GetTextHeight() + 2);
end
local RegisteredFrames = {} -- Holds a list of frames that should be registered for TRADE_SKILL_SHOW after our addon is finished
local Callback
local function RequestCookingStuff(callback)
Callback = callback
if C_TradeSkillUI.GetTradeSkillLine() ~= 185 then
RegisteredFrames = {GetFramesRegisteredForEvent('TRADE_SKILL_SHOW')}
for _, frame in pairs(RegisteredFrames) do
frame:UnregisterEvent('TRADE_SKILL_SHOW')
end
f:RegisterEvent('TRADE_SKILL_SHOW')
-- There seems to be no other way to prevent the tradeskill ui from opening when we call this function,
-- so we have to make SURE that the event always get re-registered or we'll break the other tradeskills
local opened = C_TradeSkillUI.OpenTradeSkill(185)
if not opened then
f:UnregisterEvent('TRADE_SKILL_SHOW')
for _, frame in pairs(RegisteredFrames) do
frame:RegisterEvent('TRADE_SKILL_SHOW')
end
end
else
f:GetScript('OnEvent')(f, 'TRADE_SKILL_LIST_UPDATE')
end
end
-- Cache relevent recipe info for lookups
local function CacheRecipes()
wipe(RecipeCache)
for ingredientItemID, recipes in pairs(IngredientList) do
for _, recipeID in pairs(recipes) do
RecipeCache[recipeID] = C_TradeSkillUI.GetRecipeInfo(recipeID)
end
end
for _, recipes in pairs(Requisites) do
for _, recipeID in pairs(recipes) do
RecipeCache[recipeID] = C_TradeSkillUI.GetRecipeInfo(recipeID)
end
end
end
local IsNomi = false -- Are we currently interacting with Nomi?
local function DecorateNomi()
wipe(TooltipInfo)
local WorkOrders = NomiCakesDatas and NomiCakesDatas.WorkOrders
local activeWorkOrders = {}
if WorkOrders then -- count number of pending work orders to display on their buttons
local now = time()
local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, _, _, _, _, followerID = C_Garrison.GetLandingPageShipmentInfoByContainerID(122) -- can return nil if no active shipments
local startIndex = shipmentsTotal and (#WorkOrders - shipmentsTotal + 1) or 1
--local startIndex = not shipmentsTotal and 1 or (#WorkOrders - shipmentsTotal + shipmentsReady + 1)
if startIndex >= 1 and shipmentsTotal then -- this can be called before WorkOrders has been populated, so account for that
local currentIndex = startIndex + shipmentsReady
if WorkOrders[currentIndex] then
local timeOffset = creationTime + duration - WorkOrders[currentIndex][3] - (GetServerTime() - time())
for i = startIndex, #WorkOrders do
local workOrder = WorkOrders[i]
local ingredientItemID = workOrder[1]
local endTime = workOrder[3]
local timeLeft = endTime - now + timeOffset
if timeLeft > 0 and i >= currentIndex then -- still active
if not activeWorkOrders[ingredientItemID] then
activeWorkOrders[ingredientItemID] = 1
else
activeWorkOrders[ingredientItemID] = activeWorkOrders[ingredientItemID] + 1
end
end
end
end
end
end
local i = 0
for j = 1, #IngredientOrder do
local ingredientItemID = IngredientOrder[j]
local count = GetItemCount(ingredientItemID, true) or 0
local _, _, _, _, ingredientIcon = GetItemInfoInstant(ingredientItemID)
if count >= 5 then -- we have enough of an ingredient for nomi to display it
i = i + 1
local buttonName = NomiCakesGossipButtonName .. i
local button = GossipFrame_GetTitleButton(i) -- local button = _G[buttonName]
local buttonIcon = GossipFrame_GetTitleButton(i).Icon -- local buttonIcon = _G[buttonName .. 'GossipIcon']
if button and button:IsShown() and buttonIcon and buttonIcon:GetTexture():lower() == 'interface/gossipframe/workordergossipicon' then -- changed \\ to /
if not HookedButtons[button] then
button:HookScript('OnEnter', function(self)
if not IsNomi then return end
if TooltipInfo[self] and #TooltipInfo[self] > 0 then
GameTooltip:SetOwner(self, 'ANCHOR_RIGHT')
GameTooltip:AddLine('Potential Recipes')
table.sort(TooltipInfo[self])
for _, name in pairs(TooltipInfo[self]) do
GameTooltip:AddLine(name)
end
GameTooltip:Show()
end
end)
button:HookScript('OnLeave', function(self)
GameTooltip_Hide()
end)
HookedButtons[button] = i
end
local ingredient, recipeList = LocalizedIngredientList[ingredientItemID], IngredientList[ingredientItemID]
if ingredient and recipeList then -- and recipes then
local unlearned = 0
local canLearn = 0
local ingredientName, ingredientLink = ingredient[1], ingredient[2]
for _, recipeID in pairs(recipeList) do
local info = RecipeCache[recipeID]
if info and not info.learned then
unlearned = unlearned + 1
local learnable = true
if Requisites[recipeID] then
for _, requisiteID in pairs(Requisites[recipeID]) do
-- we must know all requisites to be able to receive this item
local requisiteInfo = RecipeCache[requisiteID] -- C_TradeSkillUI.GetRecipeInfo(requisiteID)
if requisiteInfo and not requisiteInfo.learned then
-- we're missing one of the requisites, can't make this
learnable = false
if not TooltipInfo[button] then
TooltipInfo[button] = {}
end
local rank = GetRank(info)
local name = format('|T%d:16|t |cffcccccc%s %d', info.icon, info.name, rank)
tinsert(TooltipInfo[button], name)
break
end
end
end
if learnable then
canLearn = canLearn + 1
if not TooltipInfo[button] then
TooltipInfo[button] = {}
end
local rank = GetRank(info)
local name = format('|T%d:16|t %s %d', info.icon, info.name, rank)
tinsert(TooltipInfo[button], name)
end
end
end
--buttonIcon:SetTexture(ingredientIcon)
local text
if unlearned ~= 0 then
if canLearn ~= 0 then
--button:SetFormattedText('|T%d:16|t %d [%s] x%d', ingredientIcon, canLearn, ingredientName, count)
text = format('|T%d:16|t %d [%s] x%d', ingredientIcon, canLearn, ingredientName, count)
else
-- button:SetText('|cff660000' .. canLearn .. ' [' .. ingredientName .. ']')
--button:SetFormattedText('|T%d:16|t |cff660000%d [%s] x%d|r', ingredientIcon, canLearn, ingredientName, count)
text = format('|T%d:16|t |cff660000%d [%s] x%d|r', ingredientIcon, canLearn, ingredientName, count)
end
else
--button:SetFormattedText('|cff660000No more |T%d:16|t [%s]', ingredientIcon, ingredientName)
text = format('|cff660000No more |T%d:16|t [%s]', ingredientIcon, ingredientName)
end
if text then
if activeWorkOrders[ingredientItemID] then
-- spell_holy_borrowedtime
text = text .. ' |Tinterface/icons/spell_holy_borrowedtime:16|t |cff660000' .. activeWorkOrders[ingredientItemID] .. '|r'
end
button:SetText(text)
end
GossipResize(button)
end
else
break
end
end
end
end
f:SetScript('OnEvent', function(self, event, ...)
if event == 'GOSSIP_SHOW' then
local guid = UnitGUID('npc')
if guid then
local _, _, _, _, _, npcID = strsplit('-', guid)
if npcID == '101846' then -- Nomi
IsNomi = true
RequestCookingStuff(DecorateNomi)
end
end
elseif event == 'GOSSIP_CLOSED' then
IsNomi = false
elseif event == 'TRADE_SKILL_SHOW' then
self:UnregisterEvent('TRADE_SKILL_SHOW')
self:RegisterEvent('TRADE_SKILL_LIST_UPDATE')
for _, frame in pairs(RegisteredFrames) do
frame:RegisterEvent('TRADE_SKILL_SHOW')
end
elseif event == 'TRADE_SKILL_LIST_UPDATE' then
self:UnregisterEvent('TRADE_SKILL_LIST_UPDATE')
if Callback then
CacheRecipes()
Callback()
end
C_TradeSkillUI.CloseTradeSkill()
elseif event == 'GET_ITEM_INFO_RECEIVED' then
local itemID = ...
if IngredientList[itemID] then
local itemName, itemLink = GetItemInfo(itemID)
LocalizedIngredientList[itemID] = {itemName, itemLink}
end
elseif event == 'PLAYER_LOGIN' then
C_Garrison.RequestLandingPageShipmentInfo()
for itemID, recipes in pairs(IngredientList) do
local itemName, itemLink = GetItemInfo(itemID)
if itemName and itemLink then
LocalizedIngredientList[itemID] = {itemName, itemLink}
end
end
end
end)
f:RegisterEvent('GOSSIP_SHOW')
f:RegisterEvent('GOSSIP_CLOSED')
f:RegisterEvent('GET_ITEM_INFO_RECEIVED')
f:RegisterEvent('PLAYER_LOGIN')
local function OutputRecipes()
local results = {}
local unavailable = {}
for j = 1, #IngredientOrder do
local ingredientItemID = IngredientOrder[j]
local ingredient, recipeList = LocalizedIngredientList[ingredientItemID], IngredientList[ingredientItemID]
if ingredient and recipeList then
local unlearned = 0
local canLearn = 0
local ingredientName, ingredientLink = ingredient[1], ingredient[2]
for _, recipeID in pairs(recipeList) do
local info = RecipeCache[recipeID]
if info and not info.learned then
unlearned = unlearned + 1
local learnable = true
if Requisites[recipeID] then
-- todo: figure out why this isn't ignoring multiple ranks when we don't know its prerequisite
for _, requisiteID in pairs(Requisites[recipeID]) do
-- we must know all requisites to be able to receive this item
local requisiteInfo = RecipeCache[requisiteID] --C_TradeSkillUI.GetRecipeInfo(requisiteID)
if requisiteInfo and not requisiteInfo.learned then
-- we're missing one of the requisites, can't make this
learnable = false
--break
if not info.previousRecipeID then -- this is a rank 1 recipe and we can't learn it, so there is some other requirement
if not unavailable[recipeID] then
unavailable[recipeID] = {}
end
unavailable[recipeID][requisiteID] = true
end
end
end
end
if learnable then
if not results[ingredientLink] then
results[ingredientLink] = {}
end
--if not info.previousRecipeID or not results[ingredientLink][info.previousRecipeID] then
results[ingredientLink][recipeID] = true
--end
--tinsert(results[ingredientLink], recipeID)
end
end
end
end
end
for ingredientLink, recipes in pairs(results) do
print('|cff66ff66Available|r ' .. ingredientLink .. ' |cff66ff66recipes:|r')
--table.sort(recipes)
for recipeID in pairs(recipes) do
local prevRecipe = RecipeCache[recipeID].previousRecipeID
if not prevRecipe or not recipes[prevRecipe] then -- skip higher ranks of the same item
local recipeLink = GetSpellLink(recipeID)
print(' |cff66ff66-|r ' .. recipeLink)
end
end
end
for recipeID, requisites in pairs(unavailable) do
print('|cffffff66Missing|r ' .. GetSpellLink(recipeID) .. ' |cffffff66requisites:|r')
for requisite in pairs(requisites) do
--local prevRecipe = RecipeCache[recipeID].previousRecipeID
--if not prevRecipe or not recipes[prevRecipe] then -- skip higher ranks of the same item
local recipeLink = GetSpellLink(requisite)
print(' |cffffff66-|r ' .. recipeLink)
--end
end
end
print('|cffffff66Missing recipes obtained from sources other than Nomi:|r')
local i = 1
for recipeID, description in pairs(Undiscoverable) do
local info = RecipeCache[recipeID]
if info and not info.learned then
print(format('%d) %s %s', i, GetSpellLink(recipeID) or ('Recipe ' .. recipeID), description or '???'))
i = i + 1
end
end
end
SLASH_NOMICAKES1, SLASH_NOMICAKES2 = '/nomicakes', '/nomi'
function SlashCmdList.NOMICAKES()
RequestCookingStuff(OutputRecipes)
end
--------------------------------------
do -- Experimental work order stuff
local WorkOrderItemIDs = { -- cross-reference item IDs from work orders with the actual ingredient item ID
[133877] = 124117, -- Lean Shank
[133886] = 124121, -- Wildfowl Egg
[133915] = 124119, -- Big Gamy Ribs
[133914] = 124118, -- Fatty Bearsteak
[133916] = 124120, -- Leyblood
[133917] = 124107, -- Cursed Queenfish
[133918] = 124108, -- Mossgill Perch
[133919] = 124109, -- Highmountain Salmon
[133920] = 124110, -- Stormray
[133921] = 124111, -- Runescale Koi
[133922] = 124112, -- Black Barracuda
[133923] = 133680, -- Slabs of Bacon
[141700] = 133607, -- Silver Mackerel
}
NomiCakesDatas = { WorkOrders = {} }
local WorkOrders = NomiCakesDatas.WorkOrders -- [i] = {itemID, placementTime, endTime}
local addonName = ...
local ShipmentOpenTime
local NumWorkOrdersOrdered, WorkOrderType = 0
local f = CreateFrame('frame')
f:SetScript('OnEvent', function(self, event, ...)
if event == 'SHIPMENT_CRAFTER_OPENED' then
if ... == 122 then -- we're talking to nomi
ShipmentOpenTime = time()
NumWorkOrdersOrdered, WorkOrderType = 0, nil
self:RegisterEvent('SHIPMENT_UPDATE')
self:RegisterEvent('SHIPMENT_CRAFTER_CLOSED')
self:RegisterEvent('SHIPMENT_CRAFTER_INFO')
else -- these events shouldn't be registered, but make absolutely certain we don't respond to them when not talking to nomi
self:UnregisterEvent('SHIPMENT_UPDATE')
self:UnregisterEvent('SHIPMENT_CRAFTER_CLOSED')
self:UnregisterEvent('SHIPMENT_CRAFTER_INFO')
end
elseif event == 'SHIPMENT_CRAFTER_INFO' and ... then
-- shipment information should be available at this point, record it
self:UnregisterEvent('SHIPMENT_CRAFTER_INFO')
local success, pendingShipments, maxShipments, ownedShipments = ...
if maxShipments == 0 then -- nomi is bugged (no work order window), we can't fetch work order data
print('|cffffff66Nomi is bugged, try again!|r') -- outputting a message might confuse people, but I think it's better than nothing
C_Garrison.CloseTradeskillCrafter() -- end interaction so we don't have to walk away from him
else
local now = time()
wipe(WorkOrders)
for i = 1, C_Garrison.GetNumPendingShipments() do
-- "name" is not guaranteed to exist, if the item info hasn't been cached yet it will return nil, so don't bother recording it
-- we might need to manually cache the names for all of our items using GET_ITEM_INFO_UPDATE so we can add them to the tooltip later
local name, texture, _, itemID, _, startDelta, timeRemaining = C_Garrison.GetPendingShipmentInfo(i)
local ingredientItemID = itemID and WorkOrderItemIDs[itemID]
if ingredientItemID then
local orderPlaced = now - startDelta -- time the work order was placed, not when the work order will start
local endTime = now + timeRemaining
-- local startTime = endTime - 14400 -- start time is end time of previous recipe, or endTime - 14400, which makes recording it kind of pointless
-- WorkOrders[i] = {ingredientItemID, orderPlaced, endTime}
tinsert(WorkOrders, {ingredientItemID, orderPlaced, endTime})
else
-- we're missing information for whatever this is supposed to be?
end
end
end
elseif event == 'SHIPMENT_UPDATE' then
if ... then -- this will fire for each separate shipment if you queue multiple work orders at once
local name, texture, quality, itemID, followerID, duration = C_Garrison.GetShipmentItemInfo()
local ingredientItemID = itemID and WorkOrderItemIDs[itemID]
if ingredientItemID then
-- if itemID and WorkOrderItemIDs[itemID] then -- todo: sanity check if all else fails, but I would prefer this error out if something isn't working as expected
local numWorkOrders = #WorkOrders
local orderPlaced = time()
local startTime = numWorkOrders > 0 and WorkOrders[numWorkOrders][3] or orderPlaced
local endTime = startTime + duration
--WorkOrders[ #WorkOrders + 1 ] = {ingredientItemID, orderPlaced, endTime}
tinsert(WorkOrders, {ingredientItemID, orderPlaced, endTime})
WorkOrderType = ingredientItemID
NumWorkOrdersOrdered = NumWorkOrdersOrdered + 1
-- print(GetTime(), 'SHIPMENT_UPDATE', name, itemID, duration, 'started')
C_Garrison.RequestLandingPageShipmentInfo() -- request update for shipment info
else
-- missing ingredient item information for this shipment somehow
--print('NomiCakes missing ingredient information for itemID', itemID)
end
end
elseif event == 'SHIPMENT_CRAFTER_CLOSED' then -- if this event doesn't fire for some reason, we won't unregister events properly and will bug the next time the player talks to a work order npc
-- output what work orders were placed when the window is closed
-- todo: figure out how this could possibly print twice, since the event is being unregistered
self:UnregisterEvent('SHIPMENT_UPDATE')
self:UnregisterEvent('SHIPMENT_CRAFTER_CLOSED')
self:UnregisterEvent('SHIPMENT_CRAFTER_INFO') -- this shouldn't be necessary
if WorkOrderType and NumWorkOrdersOrdered > 0 then
local itemID = WorkOrderType
local name = LocalizedIngredientList[itemID] and LocalizedIngredientList[itemID][2] or '???'
local _, _, _, _, ingredientIcon = GetItemInfoInstant(itemID)
if ingredientIcon then
name = format('|T%d:16|t %s', ingredientIcon, name)
end
print(format('%d |4Work Order:Work Orders; placed for %s', NumWorkOrdersOrdered, name))
NumWorkOrdersOrdered, WorkOrderType = 0, nil
end
elseif event == 'ADDON_LOADED' and ... == addonName then
self:UnregisterEvent('ADDON_LOADED')
WorkOrders = NomiCakesDatas.WorkOrders
if NomiCakesDatas.Version ~= 2 then
NomiCakesDatas.Version = 2
wipe(NomiCakesDatas.WorkOrders)
end
self:RegisterEvent('SHIPMENT_CRAFTER_OPENED')
end
end)
f:RegisterEvent('ADDON_LOADED')
local READY_FOR_PICKUP = GARRISON_LANDING_RETURN:gsub('%s*%%d%s*', '')
local IgnoreShow = false
GameTooltip:HookScript('OnHide', function() IgnoreShow = false end)
hooksecurefunc(GameTooltip, 'Show', function(self)
if IgnoreShow then return end
local owner = self:GetOwner()
if owner and owner.containerID == 122 and WorkOrders then -- probably should add a better check for the tooltip owner than this
local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, _, _, _, _, followerID = C_Garrison.GetLandingPageShipmentInfoByContainerID(122)
if not shipmentsTotal then return end
local numWorkOrders = #WorkOrders
local startIndex = numWorkOrders - shipmentsTotal + 1
if startIndex <= 0 then return end
if numWorkOrders == 0 then return end
-- Try and account for data being desynchronized from the cache
-- (eg. if work orders are completed from Nomi Snacks or something)
-- Get the time difference between what the api reports for the active work order
-- and the cache and add it to every order's end time
-- I think "creationTime" is based on server time, so subtract the difference between GetServerTime() and time()
-- I don't know if creationTime is updated when someone uses something to instantly complete work orders, so this may all fail miserably
local currentIndex = startIndex + shipmentsReady -- currentIndex will be greater than numWorkOrders if all of our shipments are ready
local timeOffset = WorkOrders[currentIndex] and (creationTime + duration - WorkOrders[currentIndex][3] - (GetServerTime() - time())) or 0
if numWorkOrders - startIndex > 0 then
self:AddLine(' ')
end
for i = startIndex, numWorkOrders do
local workOrder = WorkOrders[i]
local itemID, orderPlaced, endTime = workOrder[1], workOrder[2], workOrder[3]
local name = LocalizedIngredientList[itemID] and LocalizedIngredientList[itemID][1] or '???'
local _, _, _, _, ingredientIcon = GetItemInfoInstant(itemID)
if ingredientIcon then
name = format('|T%d:16|t %s', ingredientIcon, name)
end
local timeLeft = endTime - time() + timeOffset
if timeLeft > 0 and i >= currentIndex then
self:AddDoubleLine(name, SecondsToTime(timeLeft), 1, 1, 0.4, 1, 1, 0.4)
elseif shipmentsReady > 0 then
self:AddDoubleLine(name, READY_FOR_PICKUP, 0.4, 1, 0.4, 0.4, 1, 0.4)
end
end
IgnoreShow = true
self:Show()
end
end)
end