diff --git a/assets/Data/entity/objects/furniture.json b/assets/Data/entity/objects/furniture.json index 7baae8e6..aa4ff8aa 100644 --- a/assets/Data/entity/objects/furniture.json +++ b/assets/Data/entity/objects/furniture.json @@ -98,6 +98,83 @@ "tokens": [ "FURNITURE" ] + }, + { + "id" : "Door1", + "collidable": { + "type" : "CUBE", + "dimension1" : 1.0, + "dimension2" : 1.0, + "dimension3" : 2.0, + "rotX": 0, + "rotY": 0, + "rotZ": 0, + "rotW": 1, + "offsetX" : 0.0, + "offsetY" : 0.5, + "offsetZ" : 0.0, + "kinematic" : true + }, + "spawnItem" : { + "graphicsTemplate" : { + "model": { + "path" : "Models/objects/furniture/door1.glb" + } + } + }, + "furnitureData" : { + "door" : { + "open" : { + "animation" : { + "nameThirdPerson": "Opend" + } + }, + "closed" : { + "animation" : { + "nameThirdPerson": "Closed" + } + }, + "opening" : { + "animation" : { + "nameThirdPerson": "Open" + } + }, + "closing" : { + "animation" : { + "nameThirdPerson": "Close" + } + } + } + }, + "buttonInteraction" : { + "onInteract" : "door", + "interactionShape" : { + "type" : "CUBE", + "dimension1" : 0.3, + "dimension2" : 0.3, + "dimension3" : 0.3, + "rotX": 0, + "rotY": 0, + "rotZ": 0, + "rotW": 1, + "offsetX" : 0.0, + "offsetY" : 0.1, + "offsetZ" : 0.0 + } + }, + "gridAlignedData" : { + "width" : 10, + "height" : 10, + "length" : 10 + }, + "graphicsTemplate": { + "model": { + "path" : "Models/objects/furniture/door1.glb" + } + }, + "tokens": [ + "FURNITURE" + ] } ], diff --git a/assets/Models/objects/furniture/door1.glb b/assets/Models/objects/furniture/door1.glb new file mode 100644 index 00000000..42558cd5 Binary files /dev/null and b/assets/Models/objects/furniture/door1.glb differ diff --git a/src/main/java/electrosphere/collision/PhysicsEntityUtils.java b/src/main/java/electrosphere/collision/PhysicsEntityUtils.java index c47788ec..92667215 100644 --- a/src/main/java/electrosphere/collision/PhysicsEntityUtils.java +++ b/src/main/java/electrosphere/collision/PhysicsEntityUtils.java @@ -583,13 +583,13 @@ public class PhysicsEntityUtils { ServerWorldData worldDat = realm.getServerWorldData(); for(Entity parent : toReposition){ Vector3d parentPos = EntityUtils.getPosition(parent); - if(worldDat.convertRealToChunkSpace(parentPos.x) >= worldDat.getWorldSizeDiscrete()){ + if(ServerWorldData.convertRealToChunkSpace(parentPos.x) >= worldDat.getWorldSizeDiscrete()){ parentPos.x = worldDat.convertWorldToReal(worldDat.getWorldSizeDiscrete()) - WORLD_MARGIN; } - if(worldDat.convertRealToChunkSpace(parentPos.y) >= worldDat.getWorldSizeDiscrete()){ + if(ServerWorldData.convertRealToChunkSpace(parentPos.y) >= worldDat.getWorldSizeDiscrete()){ parentPos.y = worldDat.convertWorldToReal(worldDat.getWorldSizeDiscrete()) - WORLD_MARGIN; } - if(worldDat.convertRealToChunkSpace(parentPos.z) >= worldDat.getWorldSizeDiscrete()){ + if(ServerWorldData.convertRealToChunkSpace(parentPos.z) >= worldDat.getWorldSizeDiscrete()){ parentPos.z = worldDat.convertWorldToReal(worldDat.getWorldSizeDiscrete()) - WORLD_MARGIN; } ServerEntityUtils.repositionEntity(parent,parentPos); @@ -652,5 +652,29 @@ public class PhysicsEntityUtils { public static Collidable getCollidable(Entity entity){ return (Collidable)entity.getData(EntityDataStrings.PHYSICS_COLLIDABLE); } + + /** + * Enables a body + * @param collisionEngine The collision engine + * @param entity The entity which contains the body to enable + */ + public static void enableBody(CollisionEngine collisionEngine, Entity entity){ + DBody body = PhysicsEntityUtils.getDBody(entity); + if(body != null){ + PhysicsUtils.enableBody(collisionEngine, body); + } + } + + /** + * Disables a body + * @param collisionEngine The collision engine + * @param entity The entity which contains the body to disable + */ + public static void disableBody(CollisionEngine collisionEngine, Entity entity){ + DBody body = PhysicsEntityUtils.getDBody(entity); + if(body != null){ + PhysicsUtils.disableBody(collisionEngine, body); + } + } } diff --git a/src/main/java/electrosphere/controls/categories/ControlCategoryMainGame.java b/src/main/java/electrosphere/controls/categories/ControlCategoryMainGame.java index 205da07c..05e19fd4 100644 --- a/src/main/java/electrosphere/controls/categories/ControlCategoryMainGame.java +++ b/src/main/java/electrosphere/controls/categories/ControlCategoryMainGame.java @@ -668,6 +668,10 @@ public class ControlCategoryMainGame { int serverEntityId = Globals.clientSceneWrapper.mapClientToServerId(target.getId()); Globals.clientConnection.queueOutgoingMessage(EntityMessage.constructinteractMessage(serverEntityId, InteractionData.ON_INTERACT_HARVEST)); } break; + case InteractionData.ON_INTERACT_DOOR: { + int serverEntityId = Globals.clientSceneWrapper.mapClientToServerId(target.getId()); + Globals.clientConnection.queueOutgoingMessage(EntityMessage.constructinteractMessage(serverEntityId, InteractionData.ON_INTERACT_DOOR)); + } break; default: { throw new Error("Unhandled interaction signal " + interactionData.getOnInteract()); } diff --git a/src/main/java/electrosphere/entity/EntityDataStrings.java b/src/main/java/electrosphere/entity/EntityDataStrings.java index 7aa7a94c..74a58509 100644 --- a/src/main/java/electrosphere/entity/EntityDataStrings.java +++ b/src/main/java/electrosphere/entity/EntityDataStrings.java @@ -351,6 +351,12 @@ public class EntityDataStrings { */ public static final String TREE_CLIENTSTANCECOMPONENT = "treeClientStanceComponent"; public static final String TREE_SERVERSTANCECOMPONENT = "treeServerStanceComponent"; + + /** + * Furniture + */ + public static final String TREE_SERVERDOOR = "treeServerDoor"; + public static final String TREE_CLIENTDOOR = "treeClientDoor"; /* Entity categories diff --git a/src/main/java/electrosphere/entity/btree/StateTransitionUtil.java b/src/main/java/electrosphere/entity/btree/StateTransitionUtil.java index b94b2986..20e770af 100644 --- a/src/main/java/electrosphere/entity/btree/StateTransitionUtil.java +++ b/src/main/java/electrosphere/entity/btree/StateTransitionUtil.java @@ -473,6 +473,7 @@ public class StateTransitionUtil { onComplete ); } else { + LoggerInterface.loggerEngine.WARNING("Creating state transition item with no tree data! " + stateEnum); rVal = new StateTransitionUtilItem( stateEnum, (TreeDataAnimation)null, @@ -504,6 +505,7 @@ public class StateTransitionUtil { loop ); } else { + LoggerInterface.loggerEngine.WARNING("Creating state transition item with no tree data! " + stateEnum); rVal = new StateTransitionUtilItem( stateEnum, (TreeDataAnimation)null, diff --git a/src/main/java/electrosphere/entity/state/furniture/ClientDoorState.java b/src/main/java/electrosphere/entity/state/furniture/ClientDoorState.java new file mode 100644 index 00000000..10265007 --- /dev/null +++ b/src/main/java/electrosphere/entity/state/furniture/ClientDoorState.java @@ -0,0 +1,234 @@ +package electrosphere.entity.state.furniture; + + +import electrosphere.collision.PhysicsEntityUtils; +import electrosphere.engine.Globals; +import electrosphere.entity.EntityDataStrings; +import electrosphere.net.synchronization.enums.BehaviorTreeIdEnums; +import electrosphere.entity.Entity; +import electrosphere.entity.btree.BehaviorTree; +import electrosphere.entity.btree.StateTransitionUtil; +import electrosphere.entity.btree.StateTransitionUtil.StateTransitionUtilItem; +import electrosphere.game.data.furniture.DoorData; +import electrosphere.net.synchronization.annotation.SyncedField; +import electrosphere.net.synchronization.annotation.SynchronizableEnum; +import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree; + +/** + * State for controlling door furniture behavior + */ +@SynchronizedBehaviorTree(name = "clientDoor", isServer = false, correspondingTree="serverDoor") +public class ClientDoorState implements BehaviorTree { + + /** + * Current state of the door + */ + @SynchronizableEnum + public static enum DoorState { + /** + * The door is already opened + */ + OPEN, + + /** + * The door is actively being opened + */ + OPENING, + + /** + * The door is already closed + */ + CLOSED, + + /** + * The door is actively closing + */ + CLOSING, + } + + /** + * The current state of the door + */ + @SyncedField + DoorState state; + + /** + * The parent entity + */ + Entity parent; + + /** + * The data for the door behavior + */ + DoorData doorData; + + /** + * The state transition util + */ + StateTransitionUtil stateTransitionUtil; + + /** + * Constructor + * @param e + * @param params + */ + private ClientDoorState(Entity e, Object ... params){ + parent = e; + this.state = DoorState.CLOSED; + this.doorData = (DoorData)params[0]; + this.stateTransitionUtil = StateTransitionUtil.create(parent, false, new StateTransitionUtilItem[]{ + StateTransitionUtilItem.create( + DoorState.OPEN, + doorData.getOpen(), + true + ), + StateTransitionUtilItem.create( + DoorState.OPENING, + doorData.getOpening(), + () -> { + this.setState(DoorState.OPEN); + PhysicsEntityUtils.disableBody(Globals.clientSceneWrapper.getCollisionEngine(), this.parent); + } + ), + StateTransitionUtilItem.create( + DoorState.CLOSED, + doorData.getClosed(), + true + ), + StateTransitionUtilItem.create( + DoorState.CLOSING, + doorData.getClosing(), + () -> { + this.setState(DoorState.CLOSED); + PhysicsEntityUtils.enableBody(Globals.clientSceneWrapper.getCollisionEngine(), this.parent); + } + ), + }); + } + + @Override + public void simulate(float deltaTime){ + this.stateTransitionUtil.simulate(this.state); + } + + /** + *

(initially) Automatically generated

+ *

+ * Attaches this tree to the entity. + *

+ * @param entity The entity to attach to + * @param tree The behavior tree to attach + * @param params Optional parameters that will be provided to the constructor + */ + public static ClientDoorState attachTree(Entity parent, Object ... params){ + ClientDoorState rVal = new ClientDoorState(parent,params); + //!!WARNING!! from here below should not be touched + //This was generated automatically to properly alert various systems that the btree exists and should be tracked + parent.putData(EntityDataStrings.TREE_CLIENTDOOR, rVal); + Globals.clientSceneWrapper.getScene().registerBehaviorTree(rVal); + Globals.entityValueTrackingService.attachTreeToEntity(parent, BehaviorTreeIdEnums.BTREE_CLIENTDOOR_ID); + return rVal; + } + + /** + *

Automatically generated

+ *

+ * Detatches this tree from the entity. + *

+ * @param entity The entity to detach to + * @param tree The behavior tree to detach + */ + public static void detachTree(Entity entity, BehaviorTree tree){ + Globals.entityValueTrackingService.detatchTreeFromEntity(entity, BehaviorTreeIdEnums.BTREE_CLIENTDOOR_ID); + } + + /** + *

+ * Gets the ClientDoorState of the entity + *

+ * @param entity the entity + * @return The ClientDoorState + */ + public static ClientDoorState getClientDoorState(Entity entity){ + return (ClientDoorState)entity.getData(EntityDataStrings.TREE_CLIENTDOOR); + } + + /** + *

+ * Checks if the entity has a ClientDoorState component + *

+ * @param entity the entity + * @return true if the entity contains the component, false otherwise + */ + public static boolean hasClientDoorState(Entity entity){ + return entity.containsKey(EntityDataStrings.TREE_CLIENTDOOR); + } + + /** + *

Automatically generated

+ *

+ * Sets state and handles the synchronization logic for it. + *

+ * @param state The value to set state to. + */ + public void setState(DoorState state){ + this.state = state; + } + + /** + *

Automatically generated

+ *

+ * Gets state. + *

+ */ + public DoorState getState(){ + return state; + } + + /** + *

Automatically generated

+ *

+ * Converts a short to the equivalent enum value + *

+ * @param shortVal The short value + * @return The enum value + */ + public static DoorState getDoorStateShortAsEnum(short shortVal){ + switch(shortVal){ + case 0: + return DoorState.OPEN; + case 1: + return DoorState.OPENING; + case 2: + return DoorState.CLOSED; + case 3: + return DoorState.CLOSING; + default: + return DoorState.OPEN; + } + } + + /** + *

Automatically generated

+ *

+ * Converts this enum type to an equivalent short value + *

+ * @param enumVal The enum value + * @return The short value + */ + public static short getDoorStateEnumAsShort(DoorState enumVal){ + switch(enumVal){ + case OPEN: + return 0; + case OPENING: + return 1; + case CLOSED: + return 2; + case CLOSING: + return 3; + default: + return 0; + } + } + +} diff --git a/src/main/java/electrosphere/entity/state/furniture/ServerDoorState.java b/src/main/java/electrosphere/entity/state/furniture/ServerDoorState.java new file mode 100644 index 00000000..aa8d8d49 --- /dev/null +++ b/src/main/java/electrosphere/entity/state/furniture/ServerDoorState.java @@ -0,0 +1,191 @@ +package electrosphere.entity.state.furniture; + + +import electrosphere.collision.PhysicsEntityUtils; +import electrosphere.engine.Globals; +import electrosphere.entity.EntityDataStrings; +import electrosphere.net.synchronization.enums.FieldIdEnums; +import electrosphere.server.datacell.Realm; +import electrosphere.server.datacell.utils.DataCellSearchUtils; +import electrosphere.net.parser.net.message.SynchronizationMessage; +import electrosphere.net.synchronization.enums.BehaviorTreeIdEnums; +import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils; +import electrosphere.entity.Entity; +import electrosphere.entity.btree.BehaviorTree; +import electrosphere.entity.btree.StateTransitionUtil; +import electrosphere.entity.btree.StateTransitionUtil.StateTransitionUtilItem; +import electrosphere.entity.state.furniture.ClientDoorState.DoorState; +import electrosphere.game.data.furniture.DoorData; +import electrosphere.net.synchronization.annotation.SyncedField; +import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree; + +/** + * State for controlling door furniture behavior + */ +@SynchronizedBehaviorTree(name = "serverDoor", isServer = true, correspondingTree="clientDoor") +public class ServerDoorState implements BehaviorTree { + + /** + * The current state of the door + */ + @SyncedField + DoorState state; + + /** + * The parent entity + */ + Entity parent; + + /** + * The data for the door behavior + */ + DoorData doorData; + + /** + * The state transition util + */ + StateTransitionUtil stateTransitionUtil; + + /** + * Constructor + * @param e + * @param params + */ + private ServerDoorState(Entity e, Object ... params){ + parent = e; + this.state = DoorState.CLOSED; + this.doorData = (DoorData)params[0]; + this.stateTransitionUtil = StateTransitionUtil.create(parent, true, new StateTransitionUtilItem[]{ + StateTransitionUtilItem.create( + DoorState.OPEN, + doorData.getOpen(), + true + ), + StateTransitionUtilItem.create( + DoorState.OPENING, + doorData.getOpening(), + () -> { + this.setState(DoorState.OPEN); + Realm parentRealm = Globals.realmManager.getEntityRealm(this.parent); + PhysicsEntityUtils.disableBody(parentRealm.getCollisionEngine(), this.parent); + } + ), + StateTransitionUtilItem.create( + DoorState.CLOSED, + doorData.getClosed(), + true + ), + StateTransitionUtilItem.create( + DoorState.CLOSING, + doorData.getClosing(), + () -> { + this.setState(DoorState.CLOSED); + Realm parentRealm = Globals.realmManager.getEntityRealm(this.parent); + PhysicsEntityUtils.enableBody(parentRealm.getCollisionEngine(), this.parent); + } + ), + }); + } + + @Override + public void simulate(float deltaTime){ + this.stateTransitionUtil.simulate(this.state); + } + + /** + * Tries interacting with the door + */ + public void interact(){ + switch(this.state){ + case OPEN: { + this.setState(DoorState.CLOSING); + } break; + case CLOSED: { + this.setState(DoorState.OPENING); + } break; + case OPENING: + case CLOSING: + //silently ignore + break; + } + } + + /** + *

(initially) Automatically generated

+ *

+ * Attaches this tree to the entity. + *

+ * @param entity The entity to attach to + * @param tree The behavior tree to attach + * @param params Optional parameters that will be provided to the constructor + */ + public static ServerDoorState attachTree(Entity parent, Object ... params){ + ServerDoorState rVal = new ServerDoorState(parent,params); + //!!WARNING!! from here below should not be touched + //This was generated automatically to properly alert various systems that the btree exists and should be tracked + ServerBehaviorTreeUtils.attachBTreeToEntity(parent, rVal); + parent.putData(EntityDataStrings.TREE_SERVERDOOR, rVal); + Globals.entityValueTrackingService.attachTreeToEntity(parent, BehaviorTreeIdEnums.BTREE_SERVERDOOR_ID); + return rVal; + } + + /** + *

Automatically generated

+ *

+ * Detatches this tree from the entity. + *

+ * @param entity The entity to detach to + * @param tree The behavior tree to detach + */ + public static void detachTree(Entity entity, BehaviorTree tree){ + Globals.entityValueTrackingService.detatchTreeFromEntity(entity, BehaviorTreeIdEnums.BTREE_SERVERDOOR_ID); + } + + /** + *

+ * Gets the ServerDoorState of the entity + *

+ * @param entity the entity + * @return The ServerDoorState + */ + public static ServerDoorState getServerDoorState(Entity entity){ + return (ServerDoorState)entity.getData(EntityDataStrings.TREE_SERVERDOOR); + } + + /** + *

+ * Checks if the entity has a ServerDoorState component + *

+ * @param entity the entity + * @return true if the entity contains the component, false otherwise + */ + public static boolean hasServerDoorState(Entity entity){ + return entity.containsKey(EntityDataStrings.TREE_SERVERDOOR); + } + + /** + *

Automatically generated

+ *

+ * Sets state and handles the synchronization logic for it. + *

+ * @param state The value to set state to. + */ + public void setState(DoorState state){ + this.state = state; + int value = ClientDoorState.getDoorStateEnumAsShort(state); + if(DataCellSearchUtils.getEntityDataCell(parent) != null){ + DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructUpdateClientStateMessage(parent.getId(), BehaviorTreeIdEnums.BTREE_SERVERDOOR_ID, FieldIdEnums.TREE_SERVERDOOR_SYNCEDFIELD_STATE_ID, value)); + } + } + + /** + *

Automatically generated

+ *

+ * Gets state. + *

+ */ + public DoorState getState(){ + return state; + } + +} diff --git a/src/main/java/electrosphere/entity/types/common/CommonEntityUtils.java b/src/main/java/electrosphere/entity/types/common/CommonEntityUtils.java index 2ef0aaab..d3def281 100644 --- a/src/main/java/electrosphere/entity/types/common/CommonEntityUtils.java +++ b/src/main/java/electrosphere/entity/types/common/CommonEntityUtils.java @@ -31,6 +31,8 @@ import electrosphere.entity.state.equip.ClientEquipState; import electrosphere.entity.state.equip.ClientToolbarState; import electrosphere.entity.state.equip.ServerEquipState; import electrosphere.entity.state.equip.ServerToolbarState; +import electrosphere.entity.state.furniture.ClientDoorState; +import electrosphere.entity.state.furniture.ServerDoorState; import electrosphere.entity.state.gravity.ClientGravityTree; import electrosphere.entity.state.gravity.ServerGravityTree; import electrosphere.entity.state.hitbox.HitboxCollectionState; @@ -421,6 +423,12 @@ public class CommonEntityUtils { if(rawType.getGridAlignedData() != null){ Globals.clientScene.registerEntityToTag(entity, EntityTags.BLOCK_OCCUPANT); } + //furniture data + if(rawType.getFurnitureData() != null){ + if(rawType.getFurnitureData().getDoor() != null){ + ClientDoorState.attachTree(entity, rawType.getFurnitureData().getDoor()); + } + } //add health system if(rawType.getHealthSystem() != null){ ClientLifeTree.attachTree(entity,rawType.getHealthSystem()); @@ -732,6 +740,13 @@ public class CommonEntityUtils { //TODO: must register with all nearby scenes as well because it could possibly occupy other chunks } + //furniture data + if(rawType.getFurnitureData() != null){ + if(rawType.getFurnitureData().getDoor() != null){ + ServerDoorState.attachTree(entity, rawType.getFurnitureData().getDoor()); + } + } + /// /// /// AI (This SHOULD only be applied on the server with the way AI architected currently) diff --git a/src/main/java/electrosphere/game/data/common/CommonEntityType.java b/src/main/java/electrosphere/game/data/common/CommonEntityType.java index 3b602ab2..59b05fca 100644 --- a/src/main/java/electrosphere/game/data/common/CommonEntityType.java +++ b/src/main/java/electrosphere/game/data/common/CommonEntityType.java @@ -22,6 +22,7 @@ import electrosphere.game.data.creature.type.movement.MovementSystem; import electrosphere.game.data.creature.type.rotator.RotatorSystem; import electrosphere.game.data.foliage.type.AmbientAudio; import electrosphere.game.data.foliage.type.GrowthModel; +import electrosphere.game.data.furniture.FurnitureData; import electrosphere.game.data.graphics.GraphicsTemplate; import electrosphere.game.data.grident.GridAlignedData; import electrosphere.game.data.particle.ParticleEmitter; @@ -156,6 +157,11 @@ public class CommonEntityType { */ GridAlignedData gridAlignedData; + /** + * Data for furniture behaviors + */ + FurnitureData furnitureData; + /** * Gets the id for this creature type * @return The id @@ -403,6 +409,14 @@ public class CommonEntityType { public GridAlignedData getGridAlignedData() { return gridAlignedData; } + + /** + * Gets the data for furniture behaviors + * @return The data for furniture behaviors + */ + public FurnitureData getFurnitureData() { + return furnitureData; + } } diff --git a/src/main/java/electrosphere/game/data/common/interact/InteractionData.java b/src/main/java/electrosphere/game/data/common/interact/InteractionData.java index a4be7052..d1d38370 100644 --- a/src/main/java/electrosphere/game/data/common/interact/InteractionData.java +++ b/src/main/java/electrosphere/game/data/common/interact/InteractionData.java @@ -16,6 +16,11 @@ public class InteractionData { * Try harvesting the entity on interaction */ public static final String ON_INTERACT_HARVEST = "harvest"; + + /** + * Try opening/closing a door + */ + public static final String ON_INTERACT_DOOR = "door"; /** * The function to run on interaction diff --git a/src/main/java/electrosphere/game/data/furniture/DoorData.java b/src/main/java/electrosphere/game/data/furniture/DoorData.java new file mode 100644 index 00000000..4e93f9db --- /dev/null +++ b/src/main/java/electrosphere/game/data/furniture/DoorData.java @@ -0,0 +1,64 @@ +package electrosphere.game.data.furniture; + +import electrosphere.game.data.common.treedata.TreeDataState; + +/** + * Data about how a door functions + */ +public class DoorData { + + /** + * Tree data for when the door is already open + */ + TreeDataState open; + + /** + * Tree data for when the door is already closed + */ + TreeDataState closed; + + /** + * Tree data for when the door is beginning to open + */ + TreeDataState opening; + + /** + * Tree data for when the door is beginning to close + */ + TreeDataState closing; + + /** + * Gets the Tree data for when the door is already open + * @return The Tree data for when the door is already open + */ + public TreeDataState getOpen() { + return open; + } + + /** + * Gets the Tree data for when the door is already closed + * @return The Tree data for when the door is already closed + */ + public TreeDataState getClosed() { + return closed; + } + + /** + * Gets the Tree data for when the door is beginning to open + * @return the Tree data for when the door is beginning to open + */ + public TreeDataState getOpening() { + return opening; + } + + /** + * Gets the Tree data for when the door is beginning to close + * @return the Tree data for when the door is beginning to close + */ + public TreeDataState getClosing() { + return closing; + } + + + +} diff --git a/src/main/java/electrosphere/game/data/furniture/FurnitureData.java b/src/main/java/electrosphere/game/data/furniture/FurnitureData.java new file mode 100644 index 00000000..ff53e55e --- /dev/null +++ b/src/main/java/electrosphere/game/data/furniture/FurnitureData.java @@ -0,0 +1,21 @@ +package electrosphere.game.data.furniture; + +/** + * Data controlling furniture behavior + */ +public class FurnitureData { + + /** + * Data for door functionality + */ + DoorData door; + + /** + * Gets the data for door functionality + * @return The data for door functionality + */ + public DoorData getDoor() { + return door; + } + +} diff --git a/src/main/java/electrosphere/net/synchronization/client/ClientSynchronizationManager.java b/src/main/java/electrosphere/net/synchronization/client/ClientSynchronizationManager.java index 36ff1355..76c1f4f2 100644 --- a/src/main/java/electrosphere/net/synchronization/client/ClientSynchronizationManager.java +++ b/src/main/java/electrosphere/net/synchronization/client/ClientSynchronizationManager.java @@ -1,6 +1,7 @@ package electrosphere.net.synchronization.client; +import electrosphere.entity.state.furniture.ClientDoorState; import electrosphere.util.Utilities; import electrosphere.entity.state.item.ClientChargeState; import electrosphere.entity.state.movement.editor.ClientEditorMovementTree; @@ -210,6 +211,16 @@ public class ClientSynchronizationManager { } break; } } break; + case BehaviorTreeIdEnums.BTREE_SERVERDOOR_ID: { + switch(message.getfieldId()){ + case FieldIdEnums.TREE_SERVERDOOR_SYNCEDFIELD_STATE_ID:{ + ClientDoorState tree = ClientDoorState.getClientDoorState(entity); + if(tree != null){ + tree.setState(ClientDoorState.getDoorStateShortAsEnum((short)message.getbTreeValue())); + } + } break; + } + } break; case BehaviorTreeIdEnums.BTREE_SERVERGRAVITY_ID: { switch(message.getfieldId()){ case FieldIdEnums.TREE_SERVERGRAVITY_SYNCEDFIELD_STATE_ID:{ diff --git a/src/main/java/electrosphere/net/synchronization/enums/BehaviorTreeIdEnums.java b/src/main/java/electrosphere/net/synchronization/enums/BehaviorTreeIdEnums.java index 277ac8b1..c4ef4e60 100644 --- a/src/main/java/electrosphere/net/synchronization/enums/BehaviorTreeIdEnums.java +++ b/src/main/java/electrosphere/net/synchronization/enums/BehaviorTreeIdEnums.java @@ -13,6 +13,8 @@ public class BehaviorTreeIdEnums { public static final int BTREE_CLIENTTOOLBARSTATE_ID = 22; public static final int BTREE_SERVEREQUIPSTATE_ID = 5; public static final int BTREE_SERVERTOOLBARSTATE_ID = 23; + public static final int BTREE_CLIENTDOOR_ID = 28; + public static final int BTREE_SERVERDOOR_ID = 29; public static final int BTREE_CLIENTGRAVITY_ID = 12; public static final int BTREE_SERVERGRAVITY_ID = 7; public static final int BTREE_IDLE_ID = 8; diff --git a/src/main/java/electrosphere/net/synchronization/enums/FieldIdEnums.java b/src/main/java/electrosphere/net/synchronization/enums/FieldIdEnums.java index c852d500..d720be08 100644 --- a/src/main/java/electrosphere/net/synchronization/enums/FieldIdEnums.java +++ b/src/main/java/electrosphere/net/synchronization/enums/FieldIdEnums.java @@ -17,6 +17,8 @@ public class FieldIdEnums { public static final int TREE_SERVERBLOCKTREE_SYNCEDFIELD_CURRENTBLOCKVARIANT_ID = 9; public static final int TREE_CLIENTTOOLBARSTATE_SYNCEDFIELD_SELECTEDSLOT_ID = 30; public static final int TREE_SERVERTOOLBARSTATE_SYNCEDFIELD_SELECTEDSLOT_ID = 31; + public static final int TREE_CLIENTDOOR_SYNCEDFIELD_STATE_ID = 36; + public static final int TREE_SERVERDOOR_SYNCEDFIELD_STATE_ID = 37; public static final int TREE_CLIENTGRAVITY_SYNCEDFIELD_STATE_ID = 16; public static final int TREE_SERVERGRAVITY_SYNCEDFIELD_STATE_ID = 11; public static final int TREE_IDLE_SYNCEDFIELD_STATE_ID = 12; diff --git a/src/main/java/electrosphere/net/synchronization/transport/StateCollection.java b/src/main/java/electrosphere/net/synchronization/transport/StateCollection.java index 327d16d4..c92a0b51 100644 --- a/src/main/java/electrosphere/net/synchronization/transport/StateCollection.java +++ b/src/main/java/electrosphere/net/synchronization/transport/StateCollection.java @@ -1,6 +1,8 @@ package electrosphere.net.synchronization.transport; +import electrosphere.entity.state.furniture.ServerDoorState; +import electrosphere.entity.state.furniture.ClientDoorState; import electrosphere.util.Utilities; import electrosphere.entity.state.item.ServerChargeState; import electrosphere.entity.state.item.ClientChargeState; @@ -90,6 +92,10 @@ public class StateCollection { ServerToolbarState tree = ServerToolbarState.getServerToolbarState(entity); collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERTOOLBARSTATE_ID,FieldIdEnums.TREE_SERVERTOOLBARSTATE_SYNCEDFIELD_SELECTEDSLOT_ID,tree.getSelectedSlot())); } break; + case BehaviorTreeIdEnums.BTREE_SERVERDOOR_ID: { + ServerDoorState tree = ServerDoorState.getServerDoorState(entity); + collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERDOOR_ID,FieldIdEnums.TREE_SERVERDOOR_SYNCEDFIELD_STATE_ID,ClientDoorState.getDoorStateEnumAsShort(tree.getState()))); + } break; case BehaviorTreeIdEnums.BTREE_SERVERGRAVITY_ID: { ServerGravityTree tree = ServerGravityTree.getServerGravityTree(entity); collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERGRAVITY_ID,FieldIdEnums.TREE_SERVERGRAVITY_SYNCEDFIELD_STATE_ID,ClientGravityTree.getGravityTreeStateEnumAsShort(tree.getState()))); @@ -182,6 +188,14 @@ public class StateCollection { } break; } } break; + case BehaviorTreeIdEnums.BTREE_SERVERDOOR_ID: { + ClientDoorState tree = ClientDoorState.getClientDoorState(entity); + switch(syncedValue.getFieldId()){ + case(FieldIdEnums.TREE_SERVERDOOR_SYNCEDFIELD_STATE_ID): { + tree.setState(ClientDoorState.getDoorStateShortAsEnum(((Double)syncedValue.getValue()).shortValue())); + } break; + } + } break; case BehaviorTreeIdEnums.BTREE_SERVERGRAVITY_ID: { ClientGravityTree tree = ClientGravityTree.getClientGravityTree(entity); switch(syncedValue.getFieldId()){ diff --git a/src/main/java/electrosphere/renderer/actor/Actor.java b/src/main/java/electrosphere/renderer/actor/Actor.java index 52efe6ab..7a4cea86 100644 --- a/src/main/java/electrosphere/renderer/actor/Actor.java +++ b/src/main/java/electrosphere/renderer/actor/Actor.java @@ -265,12 +265,20 @@ public class Actor { boneMask.addAll(group.getBoneNamesFirstPerson()); } } - } else if(this.boneGroups == null){ + } else if(animation.getBoneGroups() != null && this.boneGroups == null){ LoggerInterface.loggerRenderer.WARNING( "Trying to play animation on Actor that uses bone groups, but the Actor's bone group isn't defined!\n" + "Model path: " + modelPath + "\n" + "Animation name: " + animationName + "\n" ); + } else if(animation.getBoneGroups() == null){ + Model model = Globals.assetManager.fetchModel(this.modelPath); + if(model != null){ + boneMask = new LinkedList(); + for(Bone bone : model.getBones()){ + boneMask.add(bone.boneID); + } + } } diff --git a/src/main/java/electrosphere/server/entity/poseactor/PoseActor.java b/src/main/java/electrosphere/server/entity/poseactor/PoseActor.java index 0ba1b54a..bb66977a 100644 --- a/src/main/java/electrosphere/server/entity/poseactor/PoseActor.java +++ b/src/main/java/electrosphere/server/entity/poseactor/PoseActor.java @@ -231,12 +231,20 @@ public class PoseActor { boneMask.addAll(group.getBoneNamesThirdPerson()); } } - } else if(this.boneGroups == null){ + } else if(animation.getBoneGroups() != null && this.boneGroups == null){ LoggerInterface.loggerRenderer.WARNING( "Trying to play animation on PoseActor that uses bone groups, but the PoseActor's bone group isn't defined!\n" + "Model path: " + modelPath + "\n" + "Animation name: " + animationName + "\n" ); + } else if(animation.getBoneGroups() == null){ + PoseModel model = Globals.assetManager.fetchPoseModel(this.modelPath); + if(model != null){ + boneMask = new LinkedList(); + for(Bone bone : model.getBones()){ + boneMask.add(bone.boneID); + } + } } diff --git a/src/main/java/electrosphere/server/player/PlayerActions.java b/src/main/java/electrosphere/server/player/PlayerActions.java index 52d7e3e4..63dd0ada 100644 --- a/src/main/java/electrosphere/server/player/PlayerActions.java +++ b/src/main/java/electrosphere/server/player/PlayerActions.java @@ -8,6 +8,7 @@ import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.state.block.ServerBlockTree; import electrosphere.entity.state.equip.ServerToolbarState; +import electrosphere.entity.state.furniture.ServerDoorState; import electrosphere.entity.state.life.ServerLifeTree; import electrosphere.entity.types.common.CommonEntityUtils; import electrosphere.entity.types.creature.CreatureUtils; @@ -135,6 +136,13 @@ public class PlayerActions { } ServerScriptUtils.fireSignalOnEntity(playerEntity, "entityInteractHarvest", target); } break; + case InteractionData.ON_INTERACT_DOOR: { + if(ServerDoorState.hasServerDoorState(target)){ + ServerDoorState serverDoorState = ServerDoorState.getServerDoorState(target); + serverDoorState.interact(); + } + ServerScriptUtils.fireSignalOnEntity(playerEntity, "entityInteractHarvest", target); + } break; default: { throw new Error("Unsupported signal received! " + signal); }