8--! \brief Items
module for FrameworkZ. Defines and interacts with ITEM \object.
9--! \class FrameworkZ.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")
31ITEM.description = "No description available."
32ITEM.category = "Uncategorized"
38ITEM.shouldConsume = true
40function ITEM:Initialize()
41 return FrameworkZ.Items:Initialize(self)
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)
58 if worldItem == secondaryItem then
59 isoPlayer:setSecondaryHandItem(nil)
62 ISTimedActionQueue.add(ISWearClothing:new(isoPlayer, worldItem, self.equipTime))
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))
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))
78function ITEM:OnUse(isoPlayer, worldItem) end
80function ITEM:GetName()
81 return self.name or "Unnamed Item"
85 return FrameworkZ.Items:RemoveInstance(self.instanceID)
88function FrameworkZ.Items:New(uniqueID, itemID, isBase)
89 if not uniqueID then return false, "Missing unique ID." end
92 isBase = isBase or false,
94 itemID = itemID or "Base.Plank",
98 setmetatable(object, ITEM)
100 return object, "Item created."
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.
109 for k, v in pairs(base) do
110 if data[k] == nil or data[k] == ITEM[k] then
116 self.List[data.uniqueID] = data
118 self.Bases[data.uniqueID] = data
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
128 local worldItem = isoPlayer:getInventory():AddItem(InventoryItemFactory.CreateItem(fullItemID))
130 return true, "Created world item.", worldItem
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
142 local item = self:GetItemByUniqueID(uniqueID)
144 if not item then return false, "Item not found." end
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 {}
167 FrameworkZ.Items:LinkWorldItemToInstanceData(worldItem, instanceData)
169 return instance, "Created " .. instance.uniqueID .. " item.", worldItem
172function FrameworkZ.Items:AddInstance(item, isoPlayer, worldItem, callback)
173 local instanceID = #self.Instances + 1
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))
181 local itemInstance = self.Instances[instanceID]
183 if not self.InstanceMap[item.uniqueID] then
184 self.InstanceMap[item.uniqueID] = {}
187 if not self.InstanceMap[item.uniqueID][isoPlayer:getUsername()] then
188 self.InstanceMap[item.uniqueID][isoPlayer:getUsername()] = {}
191 table.insert(self.InstanceMap[item.uniqueID][isoPlayer:getUsername()], itemInstance)
194 callback(isoPlayer, itemInstance, worldItem)
197 if itemInstance.OnInstanced then
198 itemInstance:OnInstanced(isoPlayer, worldItem)
201 return instanceID, itemInstance
204function FrameworkZ.Items:LinkWorldItemToInstanceData(worldItem, instanceData)
205 worldItem:getModData()["FZ_ITM"] = instanceData
206 worldItem:setName(instanceData.name)
207 worldItem:setActualWeight(instanceData.weight)
210function FrameworkZ.Items:GetStoredData(worldItem)
211 if not worldItem then return false, "Missing world item." end
213 local itemData = worldItem:getModData()["FZ_ITM"]
215 return itemData or false, "No stored item data found."
218function FrameworkZ.Items:GetItemByUniqueID(uniqueID)
219 local item = self.List[uniqueID] or nil
224function FrameworkZ.Items:GetInstance(instanceID)
225 if not instanceID or instanceID == "" then return false, "Missing instance ID." end
227 local instance = self.Instances[instanceID]
229 if not instance then return false, "Instance not found." end
231 return self.Instances[instanceID]
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
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
249 local instance = FrameworkZ.Items:FindFirstInstanceByID(owner, uniqueID)
251 if not instance then return false, "Instance not found." end
253 return FrameworkZ.Items:RemoveInstance(instance.instanceID)
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
269 if instance.OnRemoved then
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)
280 inventory:RemoveItem(instance)
282 local instanceMap = self.InstanceMap[instance.uniqueID][instance.owner]
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)
293 self.Instances[instanceID] = nil
295 return true, "Removed item instance #" .. instanceID .. "."
298-- TODO use multiple items, not just one
299function FrameworkZ.Items:OnUseItemCallback(parameters)
300 local worldItem, item, playerObject = parameters[1], parameters[2], parameters[3]
302 item:OnUse(playerObject, worldItem)
305function FrameworkZ.Items:OnExamineItemCallback(parameters)
306 local worldItem, instance, playerObject = parameters[1], parameters[2], parameters[3]
308 playerObject:Say(instance.description)
311function FrameworkZ.Items:OnEquipItemCallback(parameters)
312 local worldItem, selectedWorldItems, instance, isoPlayer, equipType = parameters[1], parameters[2], parameters[3], parameters[4], parameters[5]
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)
319 if selectedInstance then
320 selectedInstance:OnEquip(isoPlayer, v, selectedWorldItems, equipType)
322 if v:IsClothing() then
323 local primaryItem = isoPlayer:getPrimaryHandItem()
324 local secondaryItem = isoPlayer:getSecondaryHandItem()
326 if v == primaryItem then
327 isoPlayer:setPrimaryHandItem(nil)
330 if v == secondaryItem then
331 isoPlayer:setSecondaryHandItem(nil)
334 ISTimedActionQueue.add(ISWearClothing:new(isoPlayer, v, 50))
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))
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()
358 if worldItem == primaryItem then
359 isoPlayer:setPrimaryHandItem(nil)
362 if worldItem == secondaryItem then
363 isoPlayer:setSecondaryHandItem(nil)
366 ISTimedActionQueue.add(ISWearClothing:new(isoPlayer, worldItem, 50))
370function FrameworkZ.Items:OnUnequipItemCallback(parameters)
371 local worldItem, selectedWorldItems, instance, isoPlayer, equipType = parameters[1], parameters[2], parameters[3], parameters[4], parameters[5]
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)
379 if selectedInstance then
380 selectedInstance:OnUnequip(isoPlayer, v, selectedWorldItems, equipType)
382 ISTimedActionQueue.add(ISUnequipAction:new(isoPlayer, v, 50))
387 instance:OnUnequip(isoPlayer, worldItem, selectedWorldItems, equipType)
388 elseif worldItem:isEquipped() then
389 ISTimedActionQueue.add(ISUnequipAction:new(isoPlayer, worldItem, 50))
393function FrameworkZ.Items:OnDropItemCallback(parameters)
394 local worldItems, player, isoPlayer = ISInventoryPane.getActualItems(parameters[1]), parameters[2], parameters[3]
396 for _, worldItem in ipairs(worldItems) do
397 if not worldItem:isFavorite() then
398 local itemData = FrameworkZ.Items:GetStoredData(worldItem)
401 local instance = self:GetInstance(itemData.instanceID)
404 local canDrop = false
406 if instance.CanDrop then
407 canDrop = instance:CanDrop(isoPlayer, worldItem)
411 if instance.OnDrop then
412 instance:OnDrop(isoPlayer, worldItem)
415 ISInventoryPaneContextMenu.dropItem(worldItem, player)
419 ISInventoryPaneContextMenu.dropItem(worldItem, player)
425function FrameworkZ.Items:OnFillInventoryObjectContextMenu(player, context, items)
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")
435 items = ISInventoryPane.getActualItems(items)
437 local uniqueIDCounts = {}
438 for k, v in pairs(items) do
439 if instanceof(v, "InventoryItem") then
440 local itemData = FrameworkZ.Items:GetStoredData(v)
443 local uniqueID = itemData.uniqueID
444 uniqueIDCounts[uniqueID] = (uniqueIDCounts[uniqueID] or 0) + 1
446 local uniqueID = v:getFullType()
447 uniqueIDCounts[uniqueID] = (uniqueIDCounts[uniqueID] or 0) + 1
454 for _, _ in pairs(uniqueIDCounts) do
455 uidLength = uidLength + 1
458 local itemEquipSubMenus = {}
460 for k, v in pairs(items) do
461 if instanceof(v, "InventoryItem") then
463 local itemData = FrameworkZ.Items:GetStoredData(v)
465 local instanceID = nil
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
479 uniqueID = itemData.uniqueID
480 instanceID = itemData.instanceID
481 instance = self:GetInstance(instanceID)
484 local canContext = false
485 local canDrop = false
488 if instance.CanContext then
489 canContext = instance:CanContext(isoPlayer, v)
493 if instance.OnContext then
494 context = instance:OnContext(isoPlayer, v, items, menuManager, uniqueIDCounts[uniqueID])
497 if instance.CanUse then
498 canUse = instance:CanUse(isoPlayer, v)
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)
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)
511 if instance.CanDrop then
512 canDrop = instance:CanDrop(isoPlayer, v)
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)
522 local option = Options.new()
523 option:setText("Malformed Item")
524 menuManager:addOption(option, interactSubMenu)
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)
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
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)
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)
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
554 local function GenerateEquipSubMenu(optionID, option, optionTarget, equipType)
555 local canEquip = false
557 if instance and instance.CanEquip then
558 canEquip = instance:CanEquip(isoPlayer, v, items, equipType)
564 menuManager:addAggregatedOption(optionID, option, optionTarget)
568 local function GenerateUnequipSubMenu(optionID, option, optionTarget)
569 menuManager:addAggregatedOption(optionID, option, optionTarget)
572 local dynamicEquipSubMenu = itemEquipSubMenus[uniqueID or v:getFullType()] or equipSubMenu
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),
579 FZ_EQUIP_TYPE_BOTH_HANDS
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),
588 FZ_EQUIP_TYPE_PRIMARY
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),
597 FZ_EQUIP_TYPE_SECONDARY
601 if v:IsClothing() 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),
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),
613 FZ_EQUIP_TYPE_CLOTHING
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)
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),
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),
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),
649 menuManager:buildMenu()
651 if interactSubMenu:getContext():isEmpty() then
652 local option = Options.new()
653 option:setText("No Interactions Available")
654 menuManager:addOption(option, interactSubMenu)
657 if inspectSubMenu:getContext():isEmpty() then
658 local option = Options.new()
659 option:setText("No Inspections Available")
660 menuManager:addOption(option, inspectSubMenu)
663 if equipSubMenu:getContext():isEmpty() then
664 local option = Options.new()
665 option:setText("No Equipments Available")
666 menuManager:addOption(option, equipSubMenu)
669 if manageSubMenu:getContext():isEmpty() then
670 local option = Options.new()
671 option:setText("No Management Options Available")
672 menuManager:addOption(option, manageSubMenu)
676FrameworkZ.Foundation:RegisterModule(FrameworkZ.Items)
void local instanceData()
void local canEquipSecondary()
void local primaryHandIsSelected()
void ISTimedActionQueue()
void local dynamicEquipSubMenu()
void local itemEquipSubMenus()
void local canEquipPrimary()
void ISEquipWeaponAction()
void local secondaryInstance()
void local primaryInstance()
void local unequipOption()
void local secondaryHandIsSelected()
void local primaryItemData()
void local secondaryItem()
void local multipleTypesSelected()
void local canEquipBothHands()
void local bothHandsAreSelected()
void local secondaryItemData()
void local examineOption()
Items module for FrameworkZ. Defines and interacts with ITEM object.
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 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 InstanceMap
An instance map. Contains references to item instances indexed by an item's unique ID and instance ID...
FrameworkZ Items Instances
void OnUnequip(isoPlayer, worldItem, equipItems, equipType)
void OnEquip(isoPlayer, worldItem, equipItems, equipType)