lotta inventory work
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2025-04-30 16:57:04 -04:00
parent 756f3ead55
commit 96b59111e8
10 changed files with 151 additions and 79 deletions

View File

@ -1620,6 +1620,7 @@ Using up charges destroys the item (including toolbar instances)
Crafting can consume charges
Products from crafting can add charges to existing items
Cache busting when physics sync pulls player entity TELEPORT distances
Lotta inventory work to bugfix charges, crafting, in-inventory items, etc

View File

@ -777,6 +777,28 @@ public class FoliageCellManager {
foliageCell.setHasRequested(false);
}
/**
* Marks a foliage cell as updateable
* @param worldX The world x position
* @param worldY The world y position
* @param worldZ The world z position
*/
public void markUpdateable(int worldX, int worldY, int worldZ){
for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION; x++){
for(int y = 0; y < ServerTerrainChunk.CHUNK_DIMENSION; y++){
for(int z = 0; z < ServerTerrainChunk.CHUNK_DIMENSION; z++){
int absVoxelX = Globals.clientWorldData.convertRelativeVoxelToAbsoluteVoxelSpace(x,worldX);
int absVoxelY = Globals.clientWorldData.convertRelativeVoxelToAbsoluteVoxelSpace(y,worldY);
int absVoxelZ = Globals.clientWorldData.convertRelativeVoxelToAbsoluteVoxelSpace(z,worldZ);
FoliageCell foliageCell = this.getFoliageCell(absVoxelX, absVoxelY, absVoxelZ);
foliageCell.ejectChunkData();
foliageCell.setHasGenerated(false);
foliageCell.setHasRequested(false);
}
}
}
}
/**
* Requests all chunks for a given foliage cell
* @param cell The cell

View File

@ -182,6 +182,11 @@ public class ClientTerrainManager {
data.setVoxelType(values);
data.setVoxelWeight(weights);
}
if(message.getchunkResolution() == ChunkData.NO_STRIDE && terrainCache.containsChunkDataAtWorldPoint(message.getworldX(), message.getworldY(), message.getworldZ(), ChunkData.NO_STRIDE)){
//this is a full-res chunk, and we already had this chunk in cache
//need to flag foliage cell to update these positions given that we have changed terrain values
Globals.foliageCellManager.markUpdateable(message.getworldX(), message.getworldY(), message.getworldZ());
}
terrainCache.addChunkDataToCache(
message.getworldX(), message.getworldY(), message.getworldZ(),
data

View File

@ -75,7 +75,7 @@ public class ImGuiDrawCell {
}
if(ImGui.button("Request terrain at camera position")){
Vector3i cameraWorldPos = Globals.clientWorldData.convertRealToWorldSpace(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
Globals.clientTerrainManager.requestChunk(cameraWorldPos.x, cameraWorldPos.y, cameraWorldPos.z, 1);
Globals.clientTerrainManager.requestChunk(cameraWorldPos.x, cameraWorldPos.y, cameraWorldPos.z, 0);
}
}
});

View File

@ -95,7 +95,7 @@ public class ClientToolbarState implements BehaviorTree {
boolean targetHasWhitelist = ItemUtils.hasEquipList(toEquip);
String equipItemClass = ItemUtils.getEquipClass(toEquip);
EquipPoint targetPoint = equipInventoryState.getEquipPointFromSlot(toolbarData.getPrimarySlot());
if(targetPoint.getEquipClassWhitelist() != null && !targetPoint.getEquipClassWhitelist().contains(equipItemClass)){
if(equipItemClass != null && targetPoint.getEquipClassWhitelist() != null && !targetPoint.getEquipClassWhitelist().contains(equipItemClass)){
targetPoint = equipInventoryState.getEquipPointFromSlot(toolbarData.getCombinedSlot());
}
equippedEntity = toEquip;

View File

@ -140,7 +140,7 @@ public class ServerToolbarState implements BehaviorTree {
ItemUtils.setRealWorldEntity(inInventoryEntity, realWorldItem);
EquipPoint targetPoint = equipInventoryState.getEquipPointFromSlot(toolbarData.getPrimarySlot());
if(targetPoint.getEquipClassWhitelist() != null && !targetPoint.getEquipClassWhitelist().contains(equipItemClass)){
if(equipItemClass != null && targetPoint.getEquipClassWhitelist() != null && !targetPoint.getEquipClassWhitelist().contains(equipItemClass)){
targetPoint = equipInventoryState.getEquipPointFromSlot(toolbarData.getCombinedSlot());
}

View File

@ -264,8 +264,6 @@ public class InventoryUtils {
Entity inventoryItem = ItemUtils.serverRecreateContainerItem(item, creature);
//store item in inventory
inventory.addItem(inventoryItem);
//set item containing parent
ItemUtils.setContainingParent(inventoryItem, creature);
//if we are the server, immediately send required packets
ServerDataCell dataCell = DataCellSearchUtils.getEntityDataCell(item);
// ServerDataCell dataCell = Globals.dataCellLocationResolver.getDataCellAtPoint(EntityUtils.getPosition(item),item);
@ -458,15 +456,7 @@ public class InventoryUtils {
}
}
}
//
//tell player that the item is no longer in their inventory
if(CreatureUtils.hasControllerPlayerId(creature)){
//get player
int playerId = CreatureUtils.getControllerPlayerId(creature);
Player controllerPlayer = Globals.playerManager.getPlayerFromId(playerId);
//tell the player they don't have the item anymore
controllerPlayer.addMessage(InventoryMessage.constructremoveItemFromInventoryMessage(item.getId()));
}
InventoryUtils.serverRemoveItemFromInventories(creature, item);
//get parent realm
Realm realm = Globals.realmManager.getEntityRealm(creature);
//find "in front of creature"
@ -611,6 +601,15 @@ public class InventoryUtils {
Globals.cursorState.hintClearBlockCursor();
ServerToolbarState.getServerToolbarState(creature).update();
}
//
//tell player that the item is no longer in their inventory
if(CreatureUtils.hasControllerPlayerId(creature)){
//get player
int playerId = CreatureUtils.getControllerPlayerId(creature);
Player controllerPlayer = Globals.playerManager.getPlayerFromId(playerId);
//tell the player they don't have the item anymore
controllerPlayer.addMessage(InventoryMessage.constructremoveItemFromInventoryMessage(item.getId()));
}
}
/**
@ -654,6 +653,23 @@ public class InventoryUtils {
//remove item from inventory
inventory.tryRemoveItem(item);
}
if(InventoryUtils.hasToolbarInventory(creature)){
RelationalInventoryState inventory = InventoryUtils.getToolbarInventory(creature);
inventory.tryRemoveItem(item);
if(ServerToolbarState.hasServerToolbarState(creature)){
ServerToolbarState serverToolbarState = ServerToolbarState.getServerToolbarState(creature);
serverToolbarState.update();
}
}
//
//tell player that the item is no longer in their inventory
if(CreatureUtils.hasControllerPlayerId(creature)){
//get player
int playerId = CreatureUtils.getControllerPlayerId(creature);
Player controllerPlayer = Globals.playerManager.getPlayerFromId(playerId);
//tell the player they don't have the item anymore
controllerPlayer.addMessage(InventoryMessage.constructremoveItemFromInventoryMessage(item.getId()));
}
ServerEntityUtils.destroyEntity(item);
}

View File

@ -4,16 +4,13 @@ package electrosphere.entity.state.item;
import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.equip.ServerToolbarState;
import electrosphere.entity.state.inventory.InventoryUtils;
import electrosphere.entity.state.inventory.RelationalInventoryState;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.ServerEntityUtils;
import electrosphere.net.synchronization.enums.FieldIdEnums;
import electrosphere.server.datacell.utils.DataCellSearchUtils;
import electrosphere.net.parser.net.message.InventoryMessage;
import electrosphere.net.parser.net.message.SynchronizationMessage;
import electrosphere.net.server.player.Player;
import electrosphere.net.synchronization.enums.BehaviorTreeIdEnums;
@ -70,21 +67,7 @@ public class ServerChargeState implements BehaviorTree {
if(inventoryItem != null){
ServerChargeState serverChargeState = ServerChargeState.getServerChargeState(inventoryItem);
if(serverChargeState != null){
if(serverChargeState.getCharges() - charges > 0){
serverChargeState.setCharges(serverChargeState.getCharges() - charges);
} else {
if(CreatureUtils.hasControllerPlayerId(parent)){
//get the player
int controllerPlayerID = CreatureUtils.getControllerPlayerId(parent);
Player controllerPlayer = Globals.playerManager.getPlayerFromId(controllerPlayerID);
//send message
controllerPlayer.addMessage(InventoryMessage.constructremoveItemFromInventoryMessage(inventoryItem.getId()));
}
RelationalInventoryState toolbarInventory = InventoryUtils.getToolbarInventory(parent);
toolbarInventory.tryRemoveItem(inventoryItem);
serverToolbarState.update();
ServerEntityUtils.destroyEntity(inventoryItem);
}
serverChargeState.attemptAddCharges(-charges);
}
}
}

View File

@ -41,8 +41,6 @@ import electrosphere.net.parser.net.message.NetworkMessage;
import electrosphere.net.server.player.Player;
import electrosphere.renderer.actor.Actor;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.utils.EntityLookupUtils;
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
import electrosphere.server.datacell.utils.ServerEntityTagUtils;
import electrosphere.server.entity.poseactor.PoseActor;
@ -162,13 +160,10 @@ public class ItemUtils {
//
//
if(item.getWeaponData() != null){
rVal.putData(EntityDataStrings.ITEM_IS_WEAPON, true);
WeaponData weaponData = item.getWeaponData();
if(weaponData.getHitboxes() != null){
HitboxCollectionState.attachHitboxState(realm.getHitboxManager(), true, rVal, weaponData.getHitboxes());
}
rVal.putData(EntityDataStrings.ITEM_WEAPON_CLASS,weaponData.getWeaponClass());
rVal.putData(EntityDataStrings.ITEM_WEAPON_DATA_RAW,weaponData);
}
//tokens
if(item.getTokens() != null){
@ -192,10 +187,48 @@ public class ItemUtils {
if(item.getIdleAnim() != null){
rVal.putData(EntityDataStrings.ANIM_IDLE,item.getIdleAnim());
}
//make all non-positional, non-physics data transform here
ItemUtils.serverApplyItemDataTransforms(item,rVal);
}
/**
* [SERVER ONLY] Applies transforms that we would expect to be applied to an entity that is an item inside an inventory
* @param item The item data
* @param itemEnt The item entity
*/
private static void serverApplyItemDataTransforms(Item item, Entity itemEnt){
if(item == null){
throw new Error("Item data is null");
}
if(itemEnt == null){
throw new Error("Item entity is null");
}
//
//
//Item specific transforms
//
//
if(item.getWeaponData() != null){
WeaponData weaponData = item.getWeaponData();
itemEnt.putData(EntityDataStrings.ITEM_IS_WEAPON, true);
itemEnt.putData(EntityDataStrings.ITEM_WEAPON_CLASS,weaponData.getWeaponClass());
itemEnt.putData(EntityDataStrings.ITEM_WEAPON_DATA_RAW,weaponData);
}
//tokens
if(item.getTokens() != null){
for(String token : item.getTokens()){
switch(token){
}
}
}
if(item.getIconPath() != null && !item.getIconPath().equals("")){
rVal.putData(EntityDataStrings.ITEM_ICON,item.getIconPath());
itemEnt.putData(EntityDataStrings.ITEM_ICON,item.getIconPath());
} else {
rVal.putData(EntityDataStrings.ITEM_ICON,AssetDataStrings.UI_TEXTURE_ITEM_ICON_GENERIC);
itemEnt.putData(EntityDataStrings.ITEM_ICON,AssetDataStrings.UI_TEXTURE_ITEM_ICON_GENERIC);
}
//
//
@ -205,28 +238,27 @@ public class ItemUtils {
if(item.getEquipData() != null){
EquipData equipData = item.getEquipData();
if(equipData.getEquipWhitelist() != null){
rVal.putData(EntityDataStrings.ITEM_EQUIP_WHITELIST, equipData.getEquipWhitelist());
itemEnt.putData(EntityDataStrings.ITEM_EQUIP_WHITELIST, equipData.getEquipWhitelist());
}
if(equipData.getEquipClass() != null){
rVal.putData(EntityDataStrings.ITEM_EQUIP_CLASS,equipData.getEquipClass());
itemEnt.putData(EntityDataStrings.ITEM_EQUIP_CLASS,equipData.getEquipClass());
}
}
rVal.putData(EntityDataStrings.ITEM_IS_IN_INVENTORY, false);
itemEnt.putData(EntityDataStrings.ITEM_IS_IN_INVENTORY, false);
//
// Fab data
//
if(item.getFabData() != null){
rVal.putData(EntityDataStrings.ITEM_FAB_DATA, item.getFabData());
itemEnt.putData(EntityDataStrings.ITEM_FAB_DATA, item.getFabData());
}
//
//stacking behavior
//
if(item.getMaxStack() != null){
ServerChargeState.attachTree(rVal, item.getMaxStack());
ServerChargeState.attachTree(itemEnt, item.getMaxStack());
}
}
/**
@ -491,6 +523,29 @@ public class ItemUtils {
}
}
/**
* [SERVER ONLY] Applies transforms that we would expect to be applied to an entity that is an item inside an inventory
* @param itemData The item data
* @param item The item entity
* @param containingParent The containing parent entity
*/
private static void serverApplyInInventoryItemTransforms(Item itemData, Entity itemEnt, Entity containingParent){
if(itemData == null){
throw new Error("Item data is null");
}
if(itemEnt == null){
throw new Error("Item entity is null");
}
if(containingParent == null){
throw new Error("Containing parent is null");
}
itemEnt.putData(EntityDataStrings.ITEM_IS_IN_INVENTORY, true);
ItemUtils.setContainingParent(itemEnt, containingParent);
CommonEntityUtils.setEntityType(itemEnt, EntityType.ITEM);
CommonEntityUtils.setEntitySubtype(itemEnt, itemData.getId());
CommonEntityUtils.setCommonData(itemEnt, itemData);
}
/**
* Emits an entity which represents the item inside a container
@ -500,30 +555,21 @@ public class ItemUtils {
public static Entity serverRecreateContainerItem(Entity item, Entity containingParent){
if(ItemUtils.isItem(item)){
Item itemData = Globals.gameConfigCurrent.getItemMap().getItem(ItemUtils.getType(item));
Entity rVal = EntityCreationUtils.createRealmlessServerEntity();
if(ItemUtils.getEquipWhitelist(item) != null){
rVal.putData(EntityDataStrings.ITEM_EQUIP_WHITELIST, getEquipWhitelist(item));
Realm realm = Globals.realmManager.getEntityRealm(containingParent);
Entity rVal = EntityCreationUtils.createServerInventoryEntity(realm);
//apply normal item transforms
ItemUtils.serverApplyItemDataTransforms(itemData, rVal);
//apply in-inventory transforms
ItemUtils.serverApplyInInventoryItemTransforms(itemData, rVal, containingParent);
//error checking
if(Globals.realmManager.getEntityRealm(rVal) == null){
LoggerInterface.loggerEngine.ERROR(new IllegalStateException("Created item without it being assigned to a realm!"));
}
rVal.putData(EntityDataStrings.ITEM_ICON,ItemUtils.getItemIcon(item));
rVal.putData(EntityDataStrings.ITEM_EQUIP_CLASS, item.getData(EntityDataStrings.ITEM_EQUIP_CLASS));
CommonEntityUtils.setEntityType(rVal, EntityType.ITEM);
rVal.putData(EntityDataStrings.ITEM_IS_IN_INVENTORY, true);
ItemUtils.setContainingParent(rVal, containingParent);
CommonEntityUtils.setEntitySubtype(rVal, CommonEntityUtils.getEntitySubtype(item));
//attach to server tracking
Realm realm = Globals.realmManager.getEntityRealm(item);
EntityLookupUtils.registerServerEntity(rVal);
ServerBehaviorTreeUtils.registerEntity(rVal);
Globals.realmManager.mapEntityToRealm(rVal, realm);
Globals.entityDataCellMapper.registerEntity(rVal, realm.getInventoryCell());
//
//stacking behavior
//
if(itemData.getMaxStack() != null){
ServerChargeState.attachTree(rVal, itemData.getMaxStack());
if(Globals.entityDataCellMapper.getEntityDataCell(rVal) == null){
throw new Error("Failed to get data cell or the entity");
}
return rVal;
@ -548,31 +594,28 @@ public class ItemUtils {
throw new Error("Trying to store an item in an entity with no inventories!");
}
Realm realm = Globals.realmManager.getEntityRealm(parent);
Vector3d parentPos = EntityUtils.getPosition(parent);
//must correct the position such that it spawns inside the realm
Entity rVal = EntityCreationUtils.createServerInventoryEntity(realm);
//apply normal item transforms
ItemUtils.serverApplyItemDataTransforms(itemData, rVal);
//apply item transforms to an entity
ItemUtils.serverApplyItemEntityTransforms(realm, parentPos, rVal, itemData);
ItemUtils.serverApplyInInventoryItemTransforms(itemData, rVal, parent);
//store the item in its actual inventory
naturalInventory.addItem(rVal);
//associate with parent and set other data
ItemUtils.setContainingParent(rVal, parent);
//destroy physics
if(realm.getCollisionEngine() != null){
realm.getCollisionEngine().destroyPhysics(rVal);
}
//error checking
if(Globals.realmManager.getEntityRealm(rVal) == null){
LoggerInterface.loggerEngine.ERROR(new IllegalStateException("Created item without it being assigned to a realm!"));
}
if(Globals.entityDataCellMapper.getEntityDataCell(rVal) == null){
throw new Error("Failed to get data cell or the entity");
}
//send entity to client
if(CreatureUtils.hasControllerPlayerId(parent)){

View File

@ -12,7 +12,9 @@ import electrosphere.entity.Entity;
*/
public class EntityLookupUtils {
//map of all entities by their ID
/**
* map of all entities by their ID
*/
static Map<Integer,Entity> idToEntityMap = new HashMap<Integer, Entity>();
/**