FrameworkZ 10.8.3
Provides a framework for Project Zomboid with various systems.
Loading...
Searching...
No Matches
Items.lua
Go to the documentation of this file.
5
7
8--! \brief Items module for FrameworkZ. Defines and interacts with ITEM \object.
9--! \class FrameworkZ.Items
10FrameworkZ.Items = {}
11FrameworkZ.Items.__index = FrameworkZ.Items
13FZ_EQUIP_TYPE_IDEAL = "Ideal"
14FZ_EQUIP_TYPE_CLOTHING = "Clothing"
15FZ_EQUIP_TYPE_PRIMARY = "Primary"
16FZ_EQUIP_TYPE_SECONDARY = "Secondary"
17FZ_EQUIP_TYPE_BOTH_HANDS = "BothHands"
19FrameworkZ.Items.List = {}
20FrameworkZ.Items.Bases = {}
21FrameworkZ.Items.Instances = {}
23--! \brief An instance map. Contains references to item instances indexed by an item's unique ID and instance ID as a string for optimized lookups. Instance Map is structured as follows: [uniqueID][username][#index] = instance
24FrameworkZ.Items.InstanceMap = {}
25FrameworkZ.Items = FrameworkZ.Foundation:NewModule(FrameworkZ.Items, "Items")
27local ITEM = {}
28ITEM.__index = ITEM
29
30ITEM.name = "Unknown"
31ITEM.description = "No description available."
32ITEM.category = "Uncategorized"
33ITEM.equipTime = 50
34ITEM.unequipTime = 50
35ITEM.useText = "Use"
36ITEM.useTime = 1
37ITEM.weight = 1
38ITEM.shouldConsume = true
39
40function ITEM:Initialize()
41 return FrameworkZ.Items:Initialize(self)
42end
44function ITEM:CanContext(isoPlayer, worldItem) return true end
45function ITEM:CanDrop(isoPlayer, worldItem) return true end
46function ITEM:CanEquip(isoPlayer, worldItem, equipItems, equipType) return true end
47function ITEM:CanUse(isoPlayer, worldItem) return true end
48function ITEM:OnContext(isoPlayer, worldItem, worldItems, menuManager, itemCount) end
49function ITEM:OnEquip(isoPlayer, worldItem, equipItems, equipType)
50 if equipType == FZ_EQUIP_TYPE_CLOTHING or worldItem:IsClothing() then
51 local primaryItem = isoPlayer:getPrimaryHandItem()
52 local secondaryItem = isoPlayer:getSecondaryHandItem()
54 if worldItem == primaryItem then
55 isoPlayer:setPrimaryHandItem(nil)
56 end
58 if worldItem == secondaryItem then
59 isoPlayer:setSecondaryHandItem(nil)
60 end
62 ISTimedActionQueue.add(ISWearClothing:new(isoPlayer, worldItem, self.equipTime))
63 else
64 if equipType == FZ_EQUIP_TYPE_BOTH_HANDS or worldItem:isTwoHandWeapon() then
65 ISTimedActionQueue.add(ISEquipWeaponAction:new(isoPlayer, worldItem, self.equipTime, true, true))
66 elseif equipType == FZ_EQUIP_TYPE_PRIMARY or not isoPlayer:getPrimaryHandItem() then
67 ISTimedActionQueue.add(ISEquipWeaponAction:new(isoPlayer, worldItem, self.equipTime, true, false))
68 elseif equipType == FZ_EQUIP_TYPE_SECONDARY or not isoPlayer:getSecondaryHandItem() then
69 ISTimedActionQueue.add(ISEquipWeaponAction:new(isoPlayer, worldItem, self.equipTime, false, false))
70 end
71 end
72end
73function ITEM:OnInstanced(isoPlayer, worldItem) end
74function ITEM:OnRemoved() end
75function ITEM:OnUnequip(isoPlayer, worldItem, equipItems, equipType)
76 ISTimedActionQueue.add(ISUnequipAction:new(isoPlayer, worldItem, self.unequipTime))
77end
78function ITEM:OnUse(isoPlayer, worldItem) end
79
80function ITEM:GetName()
81 return self.name or "Unnamed Item"
82end
83
84function ITEM:Remove()
85 return FrameworkZ.Items:RemoveInstance(self.instanceID)
86end
87
88function FrameworkZ.Items:New(uniqueID, itemID, isBase)
89 if not uniqueID then return false, "Missing unique ID." end
91 local object = {
92 isBase = isBase or false,
93 uniqueID = uniqueID,
94 itemID = itemID or "Base.Plank",
95 owner = nil,
96 }
97
98 setmetatable(object, ITEM)
99
100 return object, "Item created."
101end
103function FrameworkZ.Items:Initialize(data)
104 if not data.isBase then
105 local base = self.Bases[data.base]
107 -- If the base item exists, copy its properties to the new item but skip any overrides implemented by the new item.
108 if base then
109 for k, v in pairs(base) do
110 if data[k] == nil or data[k] == ITEM[k] then
111 data[k] = v
112 end
113 end
114 end
116 self.List[data.uniqueID] = data
117 else
118 self.Bases[data.uniqueID] = data
119 end
120
121 return data.uniqueID
122end
124function FrameworkZ.Items:CreateWorldItem(isoPlayer, fullItemID)
125 if not isoPlayer then return false, "Missing ISO Player." end
126 if not fullItemID then return false, "Missing full item ID." end
127
128 local worldItem = isoPlayer:getInventory():AddItem(InventoryItemFactory.CreateItem(fullItemID))
129
130 return true, "Created world item.", worldItem
131end
132
133--! \brief Creates an item instance and links it to a world item.
134--! \param uniqueID \string The unique ID of the item to create.
135--! \param isoPlayer \object The ISO Player to create the item for.
136--! \param callback \function (Optional) A callback function to execute after the item is created but before OnInstanced is called.
137--! \return \boolean \string \object \object Success status and message, also the item instance and world item.
138function FrameworkZ.Items:CreateItem(uniqueID, isoPlayer, callback)
139 if not uniqueID then return false, "Missing item ID." end
140 if not isoPlayer then return false, "Missing ISO Player." end
141
142 local item = self:GetItemByUniqueID(uniqueID)
143
144 if not item then return false, "Item not found." end
145
146 local success, message, worldItem = FrameworkZ.Items:CreateWorldItem(isoPlayer, item.itemID)
148 if not success or not worldItem then return false, message end
150 local instanceID, instance = self:AddInstance(item, isoPlayer, worldItem, callback)
152 local instanceData = {
153 uniqueID = instance.uniqueID,
154 itemID = worldItem:getFullType(),
155 instanceID = instanceID,
156 owner = isoPlayer:getUsername(),
157 name = instance.name or "Unknown",
158 description = instance.description or "No description available.",
159 category = instance.category or "Uncategorized",
160 shouldConsume = instance.shouldConsume or false,
161 weight = instance.weight or 1,
162 useAction = instance.useAction or nil,
163 useTime = instance.useTime or nil,
164 customFields = instance.customFields or {}
165 }
166
167 FrameworkZ.Items:LinkWorldItemToInstanceData(worldItem, instanceData)
168
169 return instance, "Created " .. instance.uniqueID .. " item.", worldItem
170end
172function FrameworkZ.Items:AddInstance(item, isoPlayer, worldItem, callback)
173 local instanceID = #self.Instances + 1
174
175 item["instanceID"] = instanceID
176 item["owner"] = isoPlayer:getUsername()
177 item["worldItemID"] = worldItem:getID()
178 item["worldItem"] = worldItem
179 table.insert(self.Instances, FrameworkZ.Utilities:CopyTable(item))
180
181 local itemInstance = self.Instances[instanceID]
182
183 if not self.InstanceMap[item.uniqueID] then
184 self.InstanceMap[item.uniqueID] = {}
185 end
186
187 if not self.InstanceMap[item.uniqueID][isoPlayer:getUsername()] then
188 self.InstanceMap[item.uniqueID][isoPlayer:getUsername()] = {}
189 end
190
191 table.insert(self.InstanceMap[item.uniqueID][isoPlayer:getUsername()], itemInstance)
192
193 if callback then
194 callback(isoPlayer, itemInstance, worldItem)
195 end
196
197 if itemInstance.OnInstanced then
198 itemInstance:OnInstanced(isoPlayer, worldItem)
199 end
200
201 return instanceID, itemInstance
202end
204function FrameworkZ.Items:LinkWorldItemToInstanceData(worldItem, instanceData)
205 worldItem:getModData()["FZ_ITM"] = instanceData
206 worldItem:setName(instanceData.name)
207 worldItem:setActualWeight(instanceData.weight)
208end
209
210function FrameworkZ.Items:GetStoredData(worldItem)
211 if not worldItem then return false, "Missing world item." end
212
213 local itemData = worldItem:getModData()["FZ_ITM"]
214
215 return itemData or false, "No stored item data found."
216end
218function FrameworkZ.Items:GetItemByUniqueID(uniqueID)
219 local item = self.List[uniqueID] or nil
220
221 return item
222end
224function FrameworkZ.Items:GetInstance(instanceID)
225 if not instanceID or instanceID == "" then return false, "Missing instance ID." end
226
227 local instance = self.Instances[instanceID]
228
229 if not instance then return false, "Instance not found." end
230
231 return self.Instances[instanceID]
232end
234function FrameworkZ.Items:FindFirstInstanceByID(owner, uniqueID)
235 if not owner or owner == "" then return false, "Missing owner." end
236 if not uniqueID or uniqueID == "" then return false, "Missing unique ID." end
238 local instance = self.InstanceMap[uniqueID][owner][1]
240 if not instance then return false, "Instance not found." end
241
242 return instance
243end
244
245function FrameworkZ.Items:RemoveItemInstanceByUniqueID(owner, uniqueID)
246 if not owner or owner == "" then return false, "Missing owner." end
247 if not uniqueID or uniqueID == "" then return false, "Missing unique ID." end
248
249 local instance = FrameworkZ.Items:FindFirstInstanceByID(owner, uniqueID)
250
251 if not instance then return false, "Instance not found." end
252
253 return FrameworkZ.Items:RemoveInstance(instance.instanceID)
254end
256--! \brief Removes an item instance from the game world and the item instance list.
257--! \param instanceID \integer The instance ID of the item to remove.
258--! \param username \object (Optional) The player's username whose inventory the item should be removed from.
259--! \return \boolean \string Success status and message.
260function FrameworkZ.Items:RemoveInstance(instanceID, username)
261 if not instanceID or instanceID == "" then return false, "Missing instance ID." end
262 local instance = self:GetInstance(instanceID)
263 if not instance then return false, "Instance not found." end
264 local player = FrameworkZ.Players:GetPlayerByID(username or instance.owner)
265 if not player then return false, "Player not found." end
266 local inventory = player:GetCharacter():GetInventory()
267 if not inventory then return false, "Inventory not found." end
268
269 if instance.OnRemoved then
270 instance:OnRemoved()
271 end
272
273 if instance.owner then
274 player.isoPlayer:getInventory():DoRemoveItem(instance.worldItem)
275 elseif instance.worldItem:getContainer() then
276 instance.worldItem:getContainer():removeItemOnServer(instance.worldItem)
277 instance.worldItem:getContainer():DoRemoveItem(instance.worldItem)
278 end
280 inventory:RemoveItem(instance)
282 local instanceMap = self.InstanceMap[instance.uniqueID][instance.owner]
283
284 -- It was a choice to either loop the item instance map on item removal, or loop the item instance list on item lookup. This seemed more efficient because the item
285 -- instance list is every single instance across every character, while the instance map is only the instances for a specific item on a specific character.
286 for k, v in ipairs(instanceMap) do
287 if v.instanceID == instanceID then
288 table.remove(self.InstanceMap[instance.uniqueID][instance.owner], k)
289 break
290 end
291 end
292
293 self.Instances[instanceID] = nil
294
295 return true, "Removed item instance #" .. instanceID .. "."
296end
297
298-- TODO use multiple items, not just one
299function FrameworkZ.Items:OnUseItemCallback(parameters)
300 local worldItem, item, playerObject = parameters[1], parameters[2], parameters[3]
301
302 item:OnUse(playerObject, worldItem)
303end
304
305function FrameworkZ.Items:OnExamineItemCallback(parameters)
306 local worldItem, instance, playerObject = parameters[1], parameters[2], parameters[3]
307
308 playerObject:Say(instance.description)
309end
310
311function FrameworkZ.Items:OnEquipItemCallback(parameters)
312 local worldItem, selectedWorldItems, instance, isoPlayer, equipType = parameters[1], parameters[2], parameters[3], parameters[4], parameters[5]
313
314 if equipType == FZ_EQUIP_TYPE_IDEAL then
315 for _, v in pairs(selectedWorldItems) do
316 local itemData = FrameworkZ.Items:GetStoredData(v)
317 local selectedInstance = self:GetInstance(itemData and itemData.instanceID or nil)
318
319 if selectedInstance then
320 selectedInstance:OnEquip(isoPlayer, v, selectedWorldItems, equipType)
321 else
322 if v:IsClothing() then
323 local primaryItem = isoPlayer:getPrimaryHandItem()
324 local secondaryItem = isoPlayer:getSecondaryHandItem()
325
326 if v == primaryItem then
327 isoPlayer:setPrimaryHandItem(nil)
328 end
329
330 if v == secondaryItem then
331 isoPlayer:setSecondaryHandItem(nil)
332 end
333
334 ISTimedActionQueue.add(ISWearClothing:new(isoPlayer, v, 50))
335 else
336 if v:isTwoHandWeapon() then
337 ISTimedActionQueue.add(ISEquipWeaponAction:new(isoPlayer, v, 50, true, true))
338 elseif not isoPlayer:getPrimaryHandItem() then
339 ISTimedActionQueue.add(ISEquipWeaponAction:new(isoPlayer, v, 50, true, false))
340 elseif not isoPlayer:getSecondayrHandItem() then
341 ISTimedActionQueue.add(ISEquipWeaponAction:new(isoPlayer, v, 50, false, false))
342 end
343 end
344 end
345 end
346 elseif instance then
347 instance:OnEquip(isoPlayer, worldItem, selectedWorldItems, equipType)
348 elseif equipType == FZ_EQUIP_TYPE_BOTH_HANDS then
349 ISTimedActionQueue.add(ISEquipWeaponAction:new(isoPlayer, worldItem, 50, true, true))
350 elseif equipType == FZ_EQUIP_TYPE_PRIMARY then
351 ISTimedActionQueue.add(ISEquipWeaponAction:new(isoPlayer, worldItem, 50, true, false))
352 elseif equipType == FZ_EQUIP_TYPE_SECONDARY then
353 ISTimedActionQueue.add(ISEquipWeaponAction:new(isoPlayer, worldItem, 50, false, false))
354 elseif equipType == FZ_EQUIP_TYPE_CLOTHING then
355 local primaryItem = isoPlayer:getPrimaryHandItem()
356 local secondaryItem = isoPlayer:getSecondaryHandItem()
357
358 if worldItem == primaryItem then
359 isoPlayer:setPrimaryHandItem(nil)
360 end
361
362 if worldItem == secondaryItem then
363 isoPlayer:setSecondaryHandItem(nil)
364 end
365
366 ISTimedActionQueue.add(ISWearClothing:new(isoPlayer, worldItem, 50))
367 end
368end
369
370function FrameworkZ.Items:OnUnequipItemCallback(parameters)
371 local worldItem, selectedWorldItems, instance, isoPlayer, equipType = parameters[1], parameters[2], parameters[3], parameters[4], parameters[5]
372
373 if equipType == FZ_EQUIP_TYPE_IDEAL then
374 for _, v in pairs(selectedWorldItems) do
375 if v:isEquipped() then
376 local itemData = FrameworkZ.Items:GetStoredData(v)
377 local selectedInstance = self:GetInstance(itemData and itemData.instanceID or nil)
378
379 if selectedInstance then
380 selectedInstance:OnUnequip(isoPlayer, v, selectedWorldItems, equipType)
381 else
382 ISTimedActionQueue.add(ISUnequipAction:new(isoPlayer, v, 50))
383 end
384 end
385 end
386 elseif instance then
387 instance:OnUnequip(isoPlayer, worldItem, selectedWorldItems, equipType)
388 elseif worldItem:isEquipped() then
389 ISTimedActionQueue.add(ISUnequipAction:new(isoPlayer, worldItem, 50))
390 end
391end
392
393function FrameworkZ.Items:OnDropItemCallback(parameters)
394 local worldItems, player, isoPlayer = ISInventoryPane.getActualItems(parameters[1]), parameters[2], parameters[3]
395
396 for _, worldItem in ipairs(worldItems) do
397 if not worldItem:isFavorite() then
398 local itemData = FrameworkZ.Items:GetStoredData(worldItem)
399
400 if itemData then
401 local instance = self:GetInstance(itemData.instanceID)
402
403 if instance then
404 local canDrop = false
405
406 if instance.CanDrop then
407 canDrop = instance:CanDrop(isoPlayer, worldItem)
408 end
409
410 if canDrop then
411 if instance.OnDrop then
412 instance:OnDrop(isoPlayer, worldItem)
413 end
414
415 ISInventoryPaneContextMenu.dropItem(worldItem, player)
416 end
417 end
418 else
419 ISInventoryPaneContextMenu.dropItem(worldItem, player)
420 end
421 end
422 end
423end
424
425function FrameworkZ.Items:OnFillInventoryObjectContextMenu(player, context, items)
426 context:clear()
427
428 local isoPlayer = getSpecificPlayer(player)
429 local menuManager = MenuManager.new(context)
430 local interactSubMenu = menuManager:addSubMenu("Interact")
431 local inspectSubMenu = menuManager:addSubMenu("Inspect")
432 local equipSubMenu = menuManager:addSubMenu("Equip")
433 local manageSubMenu = menuManager:addSubMenu("Manage")
434
435 items = ISInventoryPane.getActualItems(items)
436
437 local uniqueIDCounts = {}
438 for k, v in pairs(items) do
439 if instanceof(v, "InventoryItem") then
440 local itemData = FrameworkZ.Items:GetStoredData(v)
441
442 if itemData then
443 local uniqueID = itemData.uniqueID
444 uniqueIDCounts[uniqueID] = (uniqueIDCounts[uniqueID] or 0) + 1
445 else
446 local uniqueID = v:getFullType()
447 uniqueIDCounts[uniqueID] = (uniqueIDCounts[uniqueID] or 0) + 1
448 end
449 end
450 end
451
452 local uidLength = 0
453
454 for _, _ in pairs(uniqueIDCounts) do
455 uidLength = uidLength + 1
456 end
457
458 local itemEquipSubMenus = {}
459
460 for k, v in pairs(items) do
461 if instanceof(v, "InventoryItem") then
462
463 local itemData = FrameworkZ.Items:GetStoredData(v)
464 local uniqueID = nil
465 local instanceID = nil
466 local instance = nil
467
468 local multipleTypesSelected = uidLength > 1
469 local primaryItem = isoPlayer:getPrimaryHandItem()
470 local secondaryItem = isoPlayer:getSecondaryHandItem()
471 local bothHandsAreSelected = false
472 local primaryHandIsSelected = false
473 local secondaryHandIsSelected = false
474 local canEquipPrimary = false
475 local canEquipSecondary = false
476 local canEquipBothHands = false
477
478 if itemData then
479 uniqueID = itemData.uniqueID
480 instanceID = itemData.instanceID
481 instance = self:GetInstance(instanceID)
482
483 if instance then
484 local canContext = false
485 local canDrop = false
486 local canUse = false
487
488 if instance.CanContext then
489 canContext = instance:CanContext(isoPlayer, v)
490 end
491
492 if canContext then
493 if instance.OnContext then
494 context = instance:OnContext(isoPlayer, v, items, menuManager, uniqueIDCounts[uniqueID])
495 end
496
497 if instance.CanUse then
498 canUse = instance:CanUse(isoPlayer, v)
499 end
500
501 if canUse and instance.OnUse then
502 local useText = (instance.useText or "Use") .. " " .. instance.name
503 local useOption = Options.new(useText, self, FrameworkZ.Items.OnUseItemCallback, {v, instance, isoPlayer}, true, true, uniqueIDCounts[uniqueID])
504 menuManager:addAggregatedOption(uniqueID, useOption, interactSubMenu)
505 end
506
507 local examineText = "Examine " .. instance.name
508 local examineOption = Options.new(examineText, self, FrameworkZ.Items.OnExamineItemCallback, {v, instance, isoPlayer}, false, true, uniqueIDCounts[uniqueID])
509 menuManager:addAggregatedOption("Examine" .. uniqueID, examineOption, inspectSubMenu)
510
511 if instance.CanDrop then
512 canDrop = instance:CanDrop(isoPlayer, v)
513 end
514
515 if canDrop then
516 local dropText = multipleTypesSelected and "Drop Selected Items" or "Drop " .. instance.name
517 local dropOption = Options.new(dropText, self, FrameworkZ.Items.OnDropItemCallback, {items, player, isoPlayer}, false, true, multipleTypesSelected and 1 or uniqueIDCounts[uniqueID])
518 menuManager:addAggregatedOption(multipleTypesSelected and "DropSelectedItems" or uniqueID, dropOption, manageSubMenu)
519 end
520 end
521 else
522 local option = Options.new()
523 option:setText("Malformed Item")
524 menuManager:addOption(option, interactSubMenu)
525 end
526 else
527 local dropText = multipleTypesSelected and "Drop Selected Items" or "Drop " .. v:getName()
528 local dropOption = Options.new(dropText, self, FrameworkZ.Items.OnDropItemCallback, {items, player, isoPlayer}, false, true, multipleTypesSelected and 1 or uniqueIDCounts[v:getFullType()])
529 menuManager:addAggregatedOption(multipleTypesSelected and "DropSelectedItems" or v:getFullType(), dropOption, manageSubMenu)
530 end
531
532 if primaryItem and secondaryItem and v == primaryItem and v == secondaryItem then
533 bothHandsAreSelected = v == primaryItem and v == secondaryItem
534 elseif not bothHandsAreSelected then
535 primaryHandIsSelected = primaryItem and v == primaryItem
536 secondaryHandIsSelected = secondaryItem and v == secondaryItem
537 end
538
539 if multipleTypesSelected then
540 local unequipText = multipleTypesSelected and "Unequip Selected Items" or nil
541 local unequipOption = Options.new(unequipText, self, FrameworkZ.Items.OnUnequipItemCallback, {v, items, instance, isoPlayer, FZ_EQUIP_TYPE_IDEAL}, true, true, 1)
542 menuManager:addAggregatedOption(multipleTypesSelected and "UnequipSelectedItems", unequipOption, equipSubMenu)
543
544 local equipText = multipleTypesSelected and "Equip Selected Items" or nil
545 local equipOption = Options.new(equipText, self, FrameworkZ.Items.OnEquipItemCallback, {v, items, instance, isoPlayer, FZ_EQUIP_TYPE_IDEAL}, true, true, 1)
546 menuManager:addAggregatedOption(multipleTypesSelected and "EquipSelectedItems", equipOption, equipSubMenu)
547
548 if not itemEquipSubMenus[uniqueID or v:getFullType()] then
549 local option, subMenu = menuManager:getSubMenu("Equip"):addSubMenu(v:getName())
550 itemEquipSubMenus[uniqueID or v:getFullType()] = subMenu
551 end
552 end
553
554 local function GenerateEquipSubMenu(optionID, option, optionTarget, equipType)
555 local canEquip = false
556
557 if instance and instance.CanEquip then
558 canEquip = instance:CanEquip(isoPlayer, v, items, equipType)
559 else
560 canEquip = true
561 end
562
563 if canEquip then
564 menuManager:addAggregatedOption(optionID, option, optionTarget)
565 end
566 end
567
568 local function GenerateUnequipSubMenu(optionID, option, optionTarget)
569 menuManager:addAggregatedOption(optionID, option, optionTarget)
570 end
571
572 local dynamicEquipSubMenu = itemEquipSubMenus[uniqueID or v:getFullType()] or equipSubMenu
573
574 if not bothHandsAreSelected then
575 GenerateEquipSubMenu(
576 "EquipBothHands" .. (uniqueID or v:getFullType()),
577 Options.new("Equip " .. (instance and instance.name or v:getName()) .. " (Both Hands)", self, FrameworkZ.Items.OnEquipItemCallback, {v, items, instance, isoPlayer, FZ_EQUIP_TYPE_BOTH_HANDS}, false, true, 1),
578 dynamicEquipSubMenu,
579 FZ_EQUIP_TYPE_BOTH_HANDS
580 )
581 end
582
583 if not primaryHandIsSelected then
584 GenerateEquipSubMenu(
585 "EquipPrimary" .. (uniqueID or v:getFullType()),
586 Options.new("Equip " .. (instance and instance.name or v:getName()) .. " (Primary)", self, FrameworkZ.Items.OnEquipItemCallback, {v, items, instance, isoPlayer, FZ_EQUIP_TYPE_PRIMARY}, false, true, 1),
587 dynamicEquipSubMenu,
588 FZ_EQUIP_TYPE_PRIMARY
589 )
590 end
591
592 if not secondaryHandIsSelected then
593 GenerateEquipSubMenu(
594 "EquipSecondary" .. (uniqueID or v:getFullType()),
595 Options.new("Equip " .. (instance and instance.name or v:getName()) .. " (Secondary)", self, FrameworkZ.Items.OnEquipItemCallback, {v, items, instance, isoPlayer, FZ_EQUIP_TYPE_SECONDARY}, false, true, 1),
596 dynamicEquipSubMenu,
597 FZ_EQUIP_TYPE_SECONDARY
598 )
599 end
600
601 if v:IsClothing() then
602 if v:isWorn() then
603 GenerateUnequipSubMenu(
604 "UnequipClothing" .. (uniqueID or v:getFullType()),
605 Options.new("Unequip " .. (instance and instance.name or v:getName()) .. " (Clothing)", self, FrameworkZ.Items.OnUnequipItemCallback, {v, items, instance, isoPlayer, FZ_EQUIP_TYPE_CLOTHING}, false, true, 1),
606 dynamicEquipSubMenu
607 )
608 else
609 GenerateEquipSubMenu(
610 "EquipClothing" .. (uniqueID or v:getFullType()),
611 Options.new("Equip " .. (instance and instance.name or v:getName()) .. " (Clothing)", self, FrameworkZ.Items.OnEquipItemCallback, {v, items, instance, isoPlayer, FZ_EQUIP_TYPE_CLOTHING}, false, true, 1),
612 dynamicEquipSubMenu,
613 FZ_EQUIP_TYPE_CLOTHING
614 )
615 end
616 end
617
618 local primaryItemData = FrameworkZ.Items:GetStoredData(primaryItem)
619 local primaryInstance = self:GetInstance(primaryItemData and primaryItemData.instanceID or nil)
620 local secondaryItemData = FrameworkZ.Items:GetStoredData(secondaryItem)
621 local secondaryInstance = self:GetInstance(secondaryItemData and secondaryItemData.instanceID or nil)
622
623 if bothHandsAreSelected then
624 GenerateUnequipSubMenu(
625 "UnequipBothHands" .. (primaryInstance and primaryInstance.uniqueID or primaryItem:getFullType()),
626 Options.new("Unequip " .. (primaryInstance and primaryInstance.name or primaryItem:getName()) .. " (Both Hands)", self, FrameworkZ.Items.OnUnequipItemCallback, {primaryItem, items, primaryInstance, isoPlayer, FZ_EQUIP_TYPE_BOTH_HANDS}, false, true, 1),
627 dynamicEquipSubMenu
628 )
629 end
630
631 if primaryHandIsSelected then
632 GenerateUnequipSubMenu(
633 "UnequipPrimary" .. (primaryInstance and primaryInstance.uniqueID or primaryItem:getFullType()),
634 Options.new("Unequip " .. (primaryInstance and primaryInstance.name or primaryItem:getName()) .. " (Primary)", self, FrameworkZ.Items.OnUnequipItemCallback, {primaryItem, items, primaryInstance, isoPlayer, FZ_EQUIP_TYPE_PRIMARY}, false, true, 1),
635 dynamicEquipSubMenu
636 )
637 end
638
639 if secondaryHandIsSelected then
640 GenerateUnequipSubMenu(
641 "UnequipSecondary" .. (secondaryInstance and secondaryInstance.uniqueID or secondaryItem:getFullType()),
642 Options.new("Unequip " .. (secondaryInstance and secondaryInstance.name or secondaryItem:getName()) .. " (Secondary)", self, FrameworkZ.Items.OnUnequipItemCallback, {secondaryItem, items, secondaryInstance, isoPlayer, FZ_EQUIP_TYPE_SECONDARY}, false, true, 1),
643 dynamicEquipSubMenu
644 )
645 end
646 end
647 end
648
649 menuManager:buildMenu()
650
651 if interactSubMenu:getContext():isEmpty() then
652 local option = Options.new()
653 option:setText("No Interactions Available")
654 menuManager:addOption(option, interactSubMenu)
655 end
656
657 if inspectSubMenu:getContext():isEmpty() then
658 local option = Options.new()
659 option:setText("No Inspections Available")
660 menuManager:addOption(option, inspectSubMenu)
661 end
662
663 if equipSubMenu:getContext():isEmpty() then
664 local option = Options.new()
665 option:setText("No Equipments Available")
666 menuManager:addOption(option, equipSubMenu)
667 end
668
669 if manageSubMenu:getContext():isEmpty() then
670 local option = Options.new()
671 option:setText("No Management Options Available")
672 menuManager:addOption(option, manageSubMenu)
673 end
674end
675
676FrameworkZ.Foundation:RegisterModule(FrameworkZ.Items)
void context()
void uniqueID()
void items()
void local instanceID
void item()
void local worldItem()
void itemID()
void owner()
void local instanceData()
void local canEquipSecondary()
void local dropText()
void local canDrop()
void local dropOption()
void ISUnequipAction()
void local primaryHandIsSelected()
void local examineText()
void ISTimedActionQueue()
void local dynamicEquipSubMenu()
void local equipText()
void local itemEquipSubMenus()
void local canEquip()
void local useOption()
void local primaryItem()
void if equipType()
void local canEquipPrimary()
void local canContext()
void UnnamedFunction()
void local subMenu()
void local uidLength()
void ISEquipWeaponAction()
void local secondaryInstance()
void local uniqueID()
void local equipOption()
void local instanceMap()
void local useText()
void local primaryInstance()
void context()
void if v instanceID()
void local unequipOption()
void local secondaryHandIsSelected()
void if worldItem()
void local primaryItemData()
void if v()
void local secondaryItem()
void local unequipText()
void ISWearClothing()
void local multipleTypesSelected()
void local option
Definition Items.lua:263
void local canUse()
void local canEquipBothHands()
void local bothHandsAreSelected()
void local secondaryItemData()
void FrameworkZ()
void local instance()
void local examineOption()
void local itemData()
void self self
Definition MainMenu.lua:89
void local player()
void self username()
void local data()
void local callback()
void isoPlayer()
Items module for FrameworkZ. Defines and interacts with ITEM object.
Definition Items.lua:18
FrameworkZ Items __index
Definition Items.lua:20
void New(uniqueID, itemID, isBase)
void GetInstance(instanceID)
void OnExamineItemCallback(parameters)
void OnFillInventoryObjectContextMenu(player, context, items)
void GetItemByUniqueID(uniqueID)
void LinkWorldItemToInstanceData(worldItem, instanceData)
void OnUseItemCallback(parameters)
void OnEquipItemCallback(parameters)
void OnUnequipItemCallback(parameters)
void RemoveItemInstanceByUniqueID(owner, uniqueID)
void CreateWorldItem(isoPlayer, fullItemID)
void OnDropItemCallback(parameters)
void GetStoredData(worldItem)
void Initialize(data)
void AddInstance(item, isoPlayer, worldItem, callback)
boolean CreateItem(uniqueID, isoPlayer, callback)
Creates an item instance and links it to a world item.
void FindFirstInstanceByID(owner, uniqueID)
boolean RemoveInstance(instanceID, username)
Removes an item instance from the game world and the item instance list.
FrameworkZ Items List
Definition Items.lua:32
FrameworkZ Items InstanceMap
An instance map. Contains references to item instances indexed by an item's unique ID and instance ID...
Definition Items.lua:41
FrameworkZ Items Bases
Definition Items.lua:34
FrameworkZ Items Instances
Definition Items.lua:36
Definition Items.lua:2
void Remove()
void GetName()
void OnUnequip(isoPlayer, worldItem, equipItems, equipType)
void Initialize()
void OnEquip(isoPlayer, worldItem, equipItems, equipType)