From 9ba0e7d881734bebf7ce7bb4784aa0e82e5bb0b3 Mon Sep 17 00:00:00 2001 From: austin Date: Sun, 11 May 2025 12:44:37 -0400 Subject: [PATCH] serialization inventory work --- docs/src/progress/renderertodo.md | 4 + .../engine/loadingthreads/LoadingUtils.java | 4 +- .../types/creature/CreatureInventoryData.java | 158 ++++++++++++++++++ .../types/creature/CreatureTemplate.java | 25 +-- .../entity/types/creature/CreatureUtils.java | 129 ++++++++------ .../server/protocol/CharacterProtocol.java | 4 +- .../macro/character/CharacterUtils.java | 2 +- .../character/data/CharacterAssociatedId.java | 4 +- .../character/data/CharacterDataStrings.java | 5 + 9 files changed, 260 insertions(+), 75 deletions(-) create mode 100644 src/main/java/electrosphere/entity/types/creature/CreatureInventoryData.java diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index f661a6c7..6830163a 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1713,6 +1713,10 @@ Structures are stored in character data as IDs into macro data now Item acquisition tree can be triggered by setting macro goal correctly Macro sim triggers character to try to get mats to build structure +(05/11/2025) +Fix inventory handling in creature templates +Fix character data associated ids serialization bug + diff --git a/src/main/java/electrosphere/engine/loadingthreads/LoadingUtils.java b/src/main/java/electrosphere/engine/loadingthreads/LoadingUtils.java index 0ffad7b8..308565be 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/LoadingUtils.java +++ b/src/main/java/electrosphere/engine/loadingthreads/LoadingUtils.java @@ -175,7 +175,7 @@ public class LoadingUtils { }; int i = 0; for(String itemId : itemIds){ - template.getCreatureToolbarData().setSlotItem(i + "", ContentSerialization.createNewSerialization(EntityType.ITEM, itemId)); + template.getInventoryData().addToolbarItem(i + "", ContentSerialization.createNewSerialization(EntityType.ITEM, itemId)); i++; } //set player character template @@ -184,7 +184,7 @@ public class LoadingUtils { //set player world-space coordinates Player playerObject = Globals.playerManager.getFirstPlayer(); - Realm realm = Globals.realmManager.getRealms().iterator().next(); + Realm realm = Globals.realmManager.getRealms().iterator(). next(); Vector3d spawnPoint = realm.getSpawnPoint(); playerObject.setWorldPos(new Vector3i( ServerWorldData.convertRealToChunkSpace(spawnPoint.x), diff --git a/src/main/java/electrosphere/entity/types/creature/CreatureInventoryData.java b/src/main/java/electrosphere/entity/types/creature/CreatureInventoryData.java new file mode 100644 index 00000000..3be31400 --- /dev/null +++ b/src/main/java/electrosphere/entity/types/creature/CreatureInventoryData.java @@ -0,0 +1,158 @@ +package electrosphere.entity.types.creature; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import electrosphere.server.entity.serialization.EntitySerialization; + +/** + * Inventory data for a creature template + */ +public class CreatureInventoryData { + + /** + * Toolbar items + */ + Map toolbarItemMap = new HashMap(); + + /** + * Equipped items + */ + Map equipItemMap = new HashMap(); + + /** + * Natural inventory items + */ + List naturalItems = new LinkedList(); + + /** + * Maps toolbar slot -> id of the entity that was serialized + */ + Map toolbarIdMap = new HashMap(); + + /** + * Maps equipped slot -> id of the entity that was serialized + */ + Map equippedIdMap = new HashMap(); + + /** + * Maps natural slot -> id of the entity that was serialized + */ + Map naturalIdMap = new HashMap(); + + /** + * Adds an item to the toolbar + * @param slot The slot to add it at + * @param itemSerialization The item serialization + */ + public void addToolbarItem(String slot, EntitySerialization itemSerialization){ + if(toolbarItemMap.containsKey(slot)){ + throw new Error("Item slot already occupied " + slot); + } + toolbarItemMap.put(slot, itemSerialization); + } + + /** + * Adds an item to the equipped item set + * @param slot The slot to add it at + * @param itemSerialization The item serialization + */ + public void addEquippedItem(String slot, EntitySerialization itemSerialization){ + if(equipItemMap.containsKey(slot)){ + throw new Error("Item slot already occupied " + slot); + } + equipItemMap.put(slot, itemSerialization); + } + + /** + * Adds an item to the natural inventory + * @param itemSerialization The item serialization + */ + public void addNaturalItem(EntitySerialization itemSerialization){ + naturalItems.add(itemSerialization); + } + + /** + * Gets the set of entries of toolbar items + * @return The set + */ + public Set> getToolbarItems(){ + return toolbarItemMap.entrySet(); + } + + /** + * Gets the set of entries of equipped items + * @return The set + */ + public Set> getEquipItems(){ + return equipItemMap.entrySet(); + } + + /** + * Gets the list of natural items + * @return The list of natural items + */ + public List getNaturalItems(){ + return naturalItems; + } + + /** + * Sets the id of a toolbar entity + * @param slot The slot of the entity on the toolbar + * @param id The id + */ + public void setToolbarId(String slot, int id){ + toolbarIdMap.put(slot, id); + } + + /** + * Gets the id of a toolbar entity + * @param slot The slot in the toolbar + * @return The id + */ + public int getToolbarId(String slot){ + return toolbarIdMap.get(slot); + } + + /** + * Sets the id of an equipped entity + * @param slot The slot of the equipped entity + * @param id The id + */ + public void setEquippedId(String slot, int id){ + equippedIdMap.put(slot, id); + } + + /** + * Gets the id of an euqipped entity + * @param slot The slot equipped to + * @return The id + */ + public int getEquippedId(String slot){ + return equippedIdMap.get(slot); + } + + /** + * Sets the id of a natural inventory entity + * @param slot The slot of the natural item + * @param id The id + */ + public void setNaturalId(int slot, int id){ + naturalIdMap.put(slot, id); + } + + /** + * Gets the id of a natural inventory item + * @param slot The slot of the natural item + * @return The id + */ + public int getNaturalId(int slot){ + return naturalIdMap.get(slot); + } + +} + diff --git a/src/main/java/electrosphere/entity/types/creature/CreatureTemplate.java b/src/main/java/electrosphere/entity/types/creature/CreatureTemplate.java index fa39a353..ff5ce073 100644 --- a/src/main/java/electrosphere/entity/types/creature/CreatureTemplate.java +++ b/src/main/java/electrosphere/entity/types/creature/CreatureTemplate.java @@ -24,14 +24,9 @@ public class CreatureTemplate { private Map attributeMap = new HashMap(); /** - * The equip data for the creature + * Data about the inventory of the creature */ - private CreatureEquipData equipData = new CreatureEquipData(); - - /** - * The toolbar data for the creature - */ - private CreatureToolbarData toolbarData = new CreatureToolbarData(); + private CreatureInventoryData inventoryData = new CreatureInventoryData(); /** * The collection of synchronized values @@ -85,19 +80,11 @@ public class CreatureTemplate { } /** - * Gets the creature equip data for the template - * @return The creature equip data for the template + * Gets the inventory data for the creature + * @return The inventory data */ - public CreatureEquipData getCreatureEquipData(){ - return this.equipData; - } - - /** - * Gets the toolbar data for the template - * @return The toolbar data for the template - */ - public CreatureToolbarData getCreatureToolbarData(){ - return this.toolbarData; + public CreatureInventoryData getInventoryData(){ + return this.inventoryData; } /** diff --git a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java index 5a2dfb7e..890f3171 100644 --- a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java +++ b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java @@ -1,5 +1,7 @@ package electrosphere.entity.types.creature; +import java.util.Map.Entry; + import org.joml.Quaterniond; import org.joml.Vector3d; @@ -21,11 +23,11 @@ import electrosphere.entity.state.equip.ServerToolbarState; import electrosphere.entity.state.idle.ClientIdleTree; import electrosphere.entity.state.inventory.InventoryUtils; import electrosphere.entity.state.inventory.RelationalInventoryState; +import electrosphere.entity.state.inventory.UnrelationalInventoryState; import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree; import electrosphere.entity.state.movement.groundmove.ServerGroundMovementTree; import electrosphere.entity.types.EntityTypes.EntityType; import electrosphere.entity.types.common.CommonEntityUtils; -import electrosphere.entity.types.creature.CreatureEquipData.EquippedItem; import electrosphere.entity.types.item.ItemUtils; import electrosphere.game.data.creature.type.CreatureData; import electrosphere.game.data.creature.type.visualattribute.AttributeVariant; @@ -156,35 +158,44 @@ public class CreatureUtils { //must happen after the player is attached to the entity, or server won't send packet to add item to player's entity //now that creature has been spawned, need to create all attached items if(template != null){ - if(template.getCreatureEquipData() != null && template.getCreatureEquipData().getSlots() != null){ - for(String equipSlotId : template.getCreatureEquipData().getSlots()){ - + if(template.getInventoryData() != null){ + CreatureInventoryData inventoryData = template.getInventoryData(); + for(Entry toolbarItem : inventoryData.getToolbarItems()){ + EntitySerialization serialization = toolbarItem.getValue(); + String toolbarSlot = toolbarItem.getKey(); //add the item to the creature's inventory - EquippedItem itemDefinition = template.getCreatureEquipData().getSlotItem(equipSlotId); - Entity itemInInventory = InventoryUtils.clientConstructInInventoryItem(creature,itemDefinition.getItemType()); - - //equip the item to the slot defined in the template - ClientEquipState clientEquipState = ClientEquipState.getEquipState(creature); - clientEquipState.attemptEquip(itemInInventory, clientEquipState.getEquipPoint(equipSlotId)); - - //map the constructed item to its server id - Globals.clientSceneWrapper.mapIdToId(itemInInventory.getId(), itemDefinition.getEntityId()); - } - } - if(template.getCreatureToolbarData() != null && template.getCreatureToolbarData().getSlots() != null){ - for(String equipSlotId : template.getCreatureToolbarData().getSlots()){ - - //add the item to the creature's inventory - EntitySerialization itemDefinition = template.getCreatureToolbarData().getSlotItem(equipSlotId); - Entity itemInWorld = ContentSerialization.clientHydrateEntitySerialization(itemDefinition); + Entity itemInWorld = ContentSerialization.clientHydrateEntitySerialization(serialization); Entity itemInInventory = ItemUtils.clientRecreateContainerItem(itemInWorld, creature); //equip the item to the slot defined in the template ClientToolbarState clientToolbarState = ClientToolbarState.getClientToolbarState(creature); - clientToolbarState.attemptAddToToolbar(itemInInventory, Integer.parseInt(equipSlotId)); + clientToolbarState.attemptAddToToolbar(itemInInventory, Integer.parseInt(toolbarSlot)); //map the constructed item to its server id - Globals.clientSceneWrapper.mapIdToId(itemInInventory.getId(), template.getCreatureToolbarData().getId(equipSlotId)); + Globals.clientSceneWrapper.mapIdToId(itemInInventory.getId(), inventoryData.getToolbarId(toolbarSlot)); + } + for(Entry equippedItem : inventoryData.getEquipItems()){ + EntitySerialization serialization = equippedItem.getValue(); + String equipSlot = equippedItem.getKey(); + + //add the item to the creature's inventory + Entity itemInInventory = InventoryUtils.clientConstructInInventoryItem(creature,serialization.getSubtype()); + + //equip the item to the slot defined in the template + ClientEquipState clientEquipState = ClientEquipState.getEquipState(creature); + clientEquipState.attemptEquip(itemInInventory, clientEquipState.getEquipPoint(equipSlot)); + + //map the constructed item to its server id + Globals.clientSceneWrapper.mapIdToId(itemInInventory.getId(), inventoryData.getEquippedId(equipSlot)); + } + int i = 0; + for(EntitySerialization naturalItem : inventoryData.getNaturalItems()){ + //add the item to the creature's inventory + Entity itemInInventory = InventoryUtils.clientConstructInInventoryItem(creature,naturalItem.getSubtype()); + + //map the constructed item to its server id + Globals.clientSceneWrapper.mapIdToId(itemInInventory.getId(), inventoryData.getNaturalId(i)); + i++; } } } @@ -306,34 +317,41 @@ public class CreatureUtils { //must happen after the player is attached to the entity, or server won't send packet to add item to player's entity //now that creature has been spawned, need to create all attached items if(template != null){ - if(template.getCreatureEquipData() != null && template.getCreatureEquipData().getSlots() != null){ - for(String equipSlotId : template.getCreatureEquipData().getSlots()){ - - //spawn the item in the world - EquippedItem itemDefinition = template.getCreatureEquipData().getSlotItem(equipSlotId); - Entity itemInWorld = ItemUtils.serverSpawnBasicItem(realm, EntityUtils.getPosition(creature), itemDefinition.getItemType()); - + if(template.getInventoryData() != null){ + CreatureInventoryData inventoryData = template.getInventoryData(); + for(Entry toolbarItem : inventoryData.getToolbarItems()){ + EntitySerialization serialization = toolbarItem.getValue(); + String toolbarSlot = toolbarItem.getKey(); //add the item to the creature's inventory - Entity itemInInventory = InventoryUtils.serverAttemptStoreItemTransform(creature, EntityLookupUtils.getEntityById(itemInWorld.getId())); - - //equip the item to the slot defined in the template - ServerEquipState serverEquipState = ServerEquipState.getEquipState(creature); - serverEquipState.commandAttemptEquip(itemInInventory,serverEquipState.getEquipPoint(equipSlotId)); - } - } - if(template.getCreatureToolbarData() != null && template.getCreatureToolbarData().getSlots() != null){ - for(String equipSlotId : template.getCreatureToolbarData().getSlots()){ - - //spawn the item in the world - EntitySerialization itemDefinition = template.getCreatureToolbarData().getSlotItem(equipSlotId); - Entity itemInWorld = ContentSerialization.serverHydrateEntitySerialization(realm, itemDefinition); + Entity itemInWorld = ContentSerialization.serverHydrateEntitySerialization(realm, serialization); //add the item to the creature's inventory Entity itemInInventory = InventoryUtils.serverAttemptStoreItemTransform(creature, EntityLookupUtils.getEntityById(itemInWorld.getId())); //equip the item to the slot defined in the template ServerToolbarState serverToolbarState = ServerToolbarState.getServerToolbarState(creature); - serverToolbarState.attemptEquip(itemInInventory, Integer.parseInt(equipSlotId)); + serverToolbarState.attemptEquip(itemInInventory, Integer.parseInt(toolbarSlot)); + } + for(Entry equippedItem : inventoryData.getEquipItems()){ + EntitySerialization serialization = equippedItem.getValue(); + String equipSlot = equippedItem.getKey(); + + //add the item to the creature's inventory + Entity itemInWorld = ItemUtils.serverSpawnBasicItem(realm, EntityUtils.getPosition(creature), serialization.getSubtype()); + + //add the item to the creature's inventory + Entity itemInInventory = InventoryUtils.serverAttemptStoreItemTransform(creature, EntityLookupUtils.getEntityById(itemInWorld.getId())); + + //equip the item to the slot defined in the template + ServerEquipState serverEquipState = ServerEquipState.getEquipState(creature); + serverEquipState.commandAttemptEquip(itemInInventory,serverEquipState.getEquipPoint(equipSlot)); + } + for(EntitySerialization naturalItem : inventoryData.getNaturalItems()){ + //add the item to the creature's inventory + Entity itemInWorld = ItemUtils.serverSpawnBasicItem(realm, EntityUtils.getPosition(creature), naturalItem.getSubtype()); + + //add the item to the creature's inventory + InventoryUtils.serverAttemptStoreItemTransform(creature, EntityLookupUtils.getEntityById(itemInWorld.getId())); } } } @@ -536,13 +554,14 @@ public class CreatureUtils { */ public static CreatureTemplate getCreatureTemplate(Entity e){ CreatureTemplate template = (CreatureTemplate)e.getData(EntityDataStrings.CREATURE_TEMPLATE); + CreatureInventoryData inventoryData = template.getInventoryData(); if(ServerEquipState.hasEquipState(e)){ ServerEquipState serverEquipState = ServerEquipState.getEquipState(e); - CreatureEquipData equipData = template.getCreatureEquipData(); - equipData.clear(); for(String point : serverEquipState.equippedPoints()){ Entity item = serverEquipState.getEquippedItemAtPoint(point); - equipData.setSlotItem(point, new EquippedItem(item.getId(),ItemUtils.getType(item))); + EntitySerialization itemSerialized = ContentSerialization.constructEntitySerialization(item); + inventoryData.addEquippedItem(point, itemSerialized); + inventoryData.setEquippedId(point, item.getId()); } } if(InventoryUtils.hasToolbarInventory(e)){ @@ -551,8 +570,20 @@ public class CreatureUtils { Entity slotItem = toolbarInventory.getItemSlot(slot); if(slotItem != null){ EntitySerialization itemSerialized = ContentSerialization.constructEntitySerialization(slotItem); - template.getCreatureToolbarData().setSlotItem(slot,itemSerialized); - template.getCreatureToolbarData().setSlotId(slot, slotItem.getId()); + inventoryData.addToolbarItem(slot, itemSerialized); + inventoryData.setToolbarId(slot, slotItem.getId()); + } + } + } + if(InventoryUtils.hasNaturalInventory(e)){ + UnrelationalInventoryState toolbarInventory = InventoryUtils.getNaturalInventory(e); + int i = 0; + for(Entity item : toolbarInventory.getItems()){ + if(item != null){ + EntitySerialization itemSerialized = ContentSerialization.constructEntitySerialization(item); + inventoryData.addNaturalItem(itemSerialized); + inventoryData.setNaturalId(i, item.getId()); + i++; } } } diff --git a/src/main/java/electrosphere/net/server/protocol/CharacterProtocol.java b/src/main/java/electrosphere/net/server/protocol/CharacterProtocol.java index c8b4a0ba..fa8773b3 100644 --- a/src/main/java/electrosphere/net/server/protocol/CharacterProtocol.java +++ b/src/main/java/electrosphere/net/server/protocol/CharacterProtocol.java @@ -159,7 +159,7 @@ public class CharacterProtocol implements ServerProtocolTemplate