From 90a88bbd8b3a99f376354cbe1ff8dc43d205b195 Mon Sep 17 00:00:00 2001 From: austin Date: Thu, 3 Apr 2025 16:35:01 -0400 Subject: [PATCH] break out interaction into dedicated collision eng --- assets/Data/entity/foliage/bushes.json | 16 ++ assets/Data/entity/items/tools.json | 12 +- assets/Data/entity/objects/furniture.json | 2 +- docs/src/progress/renderertodo.md | 1 + .../interact/ClientInteractionEngine.java | 213 ++++++++++++++++++ .../client/scene/ClientSceneWrapper.java | 23 +- .../categories/ControlCategoryMainGame.java | 13 +- .../java/electrosphere/engine/Globals.java | 4 +- .../entity/ClientEntityUtils.java | 2 + .../entity/EntityDataStrings.java | 8 + .../types/common/CommonEntityUtils.java | 10 +- .../game/data/common/CommonEntityType.java | 20 +- .../data/common/interact/InteractionData.java | 22 +- 13 files changed, 315 insertions(+), 31 deletions(-) create mode 100644 src/main/java/electrosphere/client/interact/ClientInteractionEngine.java diff --git a/assets/Data/entity/foliage/bushes.json b/assets/Data/entity/foliage/bushes.json index f1a6acca..1143ec26 100644 --- a/assets/Data/entity/foliage/bushes.json +++ b/assets/Data/entity/foliage/bushes.json @@ -5,6 +5,22 @@ "tokens" : [ "FLAMMABLE" ], + "buttonInteraction" : { + "onInteract" : "harvest", + "interactionShape" : { + "type" : "CUBE", + "dimension1" : 1.0, + "dimension2" : 1.0, + "dimension3" : 1.0, + "rotX": 0, + "rotY": 0, + "rotZ": 0, + "rotW": 1, + "offsetX" : 0.0, + "offsetY" : 0.5, + "offsetZ" : 0.0 + } + }, "graphicsTemplate": { "model": { "path" : "Models/foliage/bush4.glb" diff --git a/assets/Data/entity/items/tools.json b/assets/Data/entity/items/tools.json index 1c4b424d..9dee6e9b 100644 --- a/assets/Data/entity/items/tools.json +++ b/assets/Data/entity/items/tools.json @@ -4,7 +4,8 @@ "id" : "terrainTool", "tokens" : [ "GRAVITY", - "TARGETABLE" + "TARGETABLE", + "CURSOR" ], "equipData": { "equipClass" : "tool" @@ -36,7 +37,8 @@ "id" : "spawningPalette", "tokens" : [ "GRAVITY", - "TARGETABLE" + "TARGETABLE", + "CURSOR" ], "equipData": { "equipClass" : "tool" @@ -67,7 +69,8 @@ "id" : "entityinspector", "tokens" : [ "GRAVITY", - "TARGETABLE" + "TARGETABLE", + "CURSOR" ], "equipData": { "equipClass" : "tool" @@ -97,7 +100,8 @@ "id" : "waterSpawner", "tokens" : [ "GRAVITY", - "TARGETABLE" + "TARGETABLE", + "CURSOR" ], "equipData": { "equipClass" : "tool" diff --git a/assets/Data/entity/objects/furniture.json b/assets/Data/entity/objects/furniture.json index 0f4e935b..cb7da1c2 100644 --- a/assets/Data/entity/objects/furniture.json +++ b/assets/Data/entity/objects/furniture.json @@ -73,7 +73,7 @@ "offsetZ" : 0.0, "kinematic" : true }, - "interaction" : { + "buttonInteraction" : { "onInteract" : "menu", "windowTarget" : "crafting" }, diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 1b1493ca..8f129319 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1425,6 +1425,7 @@ Add bush entity Add bushes to forest biome Make foliage data files recursive Fix bug with toolbar not unequipping items when moving to empty slot +Break out interaction ray casting into dedicated collision engine object diff --git a/src/main/java/electrosphere/client/interact/ClientInteractionEngine.java b/src/main/java/electrosphere/client/interact/ClientInteractionEngine.java new file mode 100644 index 00000000..82580525 --- /dev/null +++ b/src/main/java/electrosphere/client/interact/ClientInteractionEngine.java @@ -0,0 +1,213 @@ +package electrosphere.client.interact; + +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.locks.ReentrantLock; + +import org.joml.Matrix4d; +import org.joml.Quaterniond; +import org.joml.Vector3d; +import org.ode4j.ode.DBody; + +import electrosphere.collision.CollisionBodyCreation; +import electrosphere.collision.CollisionEngine; +import electrosphere.collision.PhysicsUtils; +import electrosphere.collision.collidable.Collidable; +import electrosphere.engine.Globals; +import electrosphere.entity.Entity; +import electrosphere.entity.EntityDataStrings; +import electrosphere.entity.EntityUtils; +import electrosphere.game.data.collidable.CollidableTemplate; + +/** + * Manages the interaction state + */ +public class ClientInteractionEngine { + + /** + * The lock used for thread-safe-ing the engine + */ + private static ReentrantLock lock = new ReentrantLock(); + + /** + * The list of entities that are currently registered for interaction + */ + private static List interactables = new LinkedList(); + + /** + * Attaches a collidable template to a given entity + * @param rVal The entity + * @param physicsTemplate The collidable template + */ + public static void attachCollidableTemplate(Entity rVal, CollidableTemplate physicsTemplate){ + DBody rigidBody = null; + Collidable collidable; + long categoryBit = Collidable.TYPE_OBJECT_BIT; + lock.lock(); + interactables.add(rVal); + switch(physicsTemplate.getType()){ + case "CYLINDER": { + + // + //create dbody + rigidBody = CollisionBodyCreation.createCylinderBody( + Globals.clientSceneWrapper.getInteractionEngine(), + physicsTemplate.getDimension1(), + physicsTemplate.getDimension2(), + categoryBit + ); + + // + //set offset from center of entity position + CollisionBodyCreation.setOffsetPosition( + Globals.clientSceneWrapper.getInteractionEngine(), + rigidBody, + new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ()) + ); + + // + //create collidable and link to structures + collidable = new Collidable(rVal, Collidable.TYPE_OBJECT, true); + + // + //store values + Matrix4d offsetTransform = new Matrix4d().translationRotate( + physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ(), //translate + physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW() //rotate + ); + rVal.putData(EntityDataStrings.INTERACTION_OFFSET_TRANSFORM, offsetTransform); + rVal.putData(EntityDataStrings.INTERACTION_TEMPLATE, physicsTemplate); + rVal.putData(EntityDataStrings.INTERACTION_COLLIDABLE, collidable); + rVal.putData(EntityDataStrings.INTERACTION_BODY, rigidBody); + + Globals.clientSceneWrapper.getInteractionEngine().registerCollisionObject(rigidBody, collidable); + } break; + case "CUBE": { + // + //create dbody + rigidBody = CollisionBodyCreation.createCubeBody( + Globals.clientSceneWrapper.getInteractionEngine(), + new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()), + categoryBit + ); + + // + //set offset from center of entity position + CollisionBodyCreation.setOffsetPosition( + Globals.clientSceneWrapper.getInteractionEngine(), + rigidBody, + new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ()) + ); + + // + //create collidable and link to structures + collidable = new Collidable(rVal, Collidable.TYPE_OBJECT, true); + + // + //store values + Matrix4d offsetTransform = new Matrix4d().translationRotateScale( + physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ(), //translate + physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW(), //rotate + 1, 1, 1 //scale + ); + rVal.putData(EntityDataStrings.INTERACTION_OFFSET_TRANSFORM, offsetTransform); + rVal.putData(EntityDataStrings.INTERACTION_TEMPLATE, physicsTemplate); + rVal.putData(EntityDataStrings.INTERACTION_COLLIDABLE, collidable); + rVal.putData(EntityDataStrings.INTERACTION_BODY, rigidBody); + + Globals.clientSceneWrapper.getInteractionEngine().registerCollisionObject(rigidBody, collidable); + } break; + case "CAPSULE": { + // + //create dbody + rigidBody = CollisionBodyCreation.createCapsuleBody( + Globals.clientSceneWrapper.getInteractionEngine(), + physicsTemplate.getDimension2(), + physicsTemplate.getDimension2() - physicsTemplate.getDimension1() - physicsTemplate.getDimension1(), + categoryBit + ); + + // + //set offset from center of entity position + CollisionBodyCreation.setOffsetPosition( + Globals.clientSceneWrapper.getInteractionEngine(), + rigidBody, + new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ()) + ); + + // + //create collidable and link to structures + collidable = new Collidable(rVal, Collidable.TYPE_OBJECT, true); + + // + //store values + Matrix4d offsetTransform = new Matrix4d().translationRotateScale( + physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ(), //translate + physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW(), //rotate + 1, 1, 1 //scale + ); + rVal.putData(EntityDataStrings.INTERACTION_OFFSET_TRANSFORM, offsetTransform); + rVal.putData(EntityDataStrings.INTERACTION_TEMPLATE, physicsTemplate); + rVal.putData(EntityDataStrings.INTERACTION_COLLIDABLE, collidable); + rVal.putData(EntityDataStrings.INTERACTION_BODY, rigidBody); + + Globals.clientSceneWrapper.getInteractionEngine().registerCollisionObject(rigidBody, collidable); + } break; + default: { + throw new Error("Unsupported shape type! " + physicsTemplate.getType()); + } + } + lock.unlock(); + } + + /** + * Destroys the interaction collidable attached to this entity + * @param rVal The entity + */ + public static void destroyCollidableTemplate(Entity rVal){ + lock.lock(); + CollisionEngine interactionEngine = Globals.clientSceneWrapper.getInteractionEngine(); + Collidable collidable = (Collidable)rVal.getData(EntityDataStrings.INTERACTION_COLLIDABLE); + DBody body = (DBody)rVal.getData(EntityDataStrings.INTERACTION_BODY); + if(body != null){ + PhysicsUtils.destroyBody(interactionEngine, body); + if(collidable != null){ + interactionEngine.deregisterCollisionObject(body, collidable); + } + } + lock.unlock(); + } + + /** + * Updates the positions of all hitboxes + */ + private static void updateInteractableTransforms(){ + lock.lock(); + CollisionEngine interactionEngine = Globals.clientSceneWrapper.getInteractionEngine(); + for(Entity entity : interactables){ + if(entity != null){ + Vector3d entityPosition = EntityUtils.getPosition(entity); + Quaterniond entityRotation = EntityUtils.getRotation(entity); + DBody body = (DBody)entity.getData(EntityDataStrings.INTERACTION_BODY); + PhysicsUtils.setRigidBodyTransform(interactionEngine, new Vector3d(entityPosition), new Quaterniond(entityRotation), body); + } + } + lock.unlock(); + } + + /** + * Ray cast to pick the current interaction target + * @return The current interaction target if it exists, null otherwise + */ + public static Entity rayCast(Vector3d centerPos, Vector3d eyePos){ + lock.lock(); + CollisionEngine interactionEngine = Globals.clientSceneWrapper.getInteractionEngine(); + //update position of all interactables + ClientInteractionEngine.updateInteractableTransforms(); + //ray cast + Entity target = interactionEngine.rayCast(centerPos, eyePos, CollisionEngine.DEFAULT_INTERACT_DISTANCE, Collidable.MASK_NO_TERRAIN); + lock.unlock(); + return target; + } + +} diff --git a/src/main/java/electrosphere/client/scene/ClientSceneWrapper.java b/src/main/java/electrosphere/client/scene/ClientSceneWrapper.java index 8602a3b9..c7b6ece5 100644 --- a/src/main/java/electrosphere/client/scene/ClientSceneWrapper.java +++ b/src/main/java/electrosphere/client/scene/ClientSceneWrapper.java @@ -41,6 +41,11 @@ public class ClientSceneWrapper { */ CollisionEngine chemistryEngine; + /** + * The interaction engine + */ + CollisionEngine interactionEngine; + //The hitbox manager HitboxManager hitboxManager; @@ -48,12 +53,14 @@ public class ClientSceneWrapper { * Constructor * @param scene The scene * @param collisionEngine The collision engine - * @param chemistryEngine the chemsitry engine + * @param chemistryEngine The chemsitry engine + * @param interactionEngine The interaction engine */ - public ClientSceneWrapper(Scene scene, CollisionEngine collisionEngine, CollisionEngine chemistryEngine){ + public ClientSceneWrapper(Scene scene, CollisionEngine collisionEngine, CollisionEngine chemistryEngine, CollisionEngine interactionEngine){ this.scene = scene; this.collisionEngine = collisionEngine; this.chemistryEngine = chemistryEngine; + this.interactionEngine = interactionEngine; this.hitboxManager = new HitboxManager(resolutionCallback); } @@ -192,7 +199,7 @@ public class ClientSceneWrapper { /** * Gets the collision engine backing the wrapper - * @return + * @return The collision engine used for the physics system */ public CollisionEngine getCollisionEngine(){ return collisionEngine; @@ -200,12 +207,20 @@ public class ClientSceneWrapper { /** * Gets the chemistry engine backing the wrapper - * @return + * @return The collision engine used for the chemistry system */ public CollisionEngine getChemistryEngine(){ return collisionEngine; } + /** + * Gets the interaction-based collision engine backing the wrapper + * @return The collision engine used for interaction ray casting + */ + public CollisionEngine getInteractionEngine(){ + return interactionEngine; + } + /** * Gets the hitbox manager for the client * @return The hitbox manager diff --git a/src/main/java/electrosphere/controls/categories/ControlCategoryMainGame.java b/src/main/java/electrosphere/controls/categories/ControlCategoryMainGame.java index 0fff9279..2b212869 100644 --- a/src/main/java/electrosphere/controls/categories/ControlCategoryMainGame.java +++ b/src/main/java/electrosphere/controls/categories/ControlCategoryMainGame.java @@ -9,13 +9,12 @@ import org.lwjgl.glfw.GLFW; import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType; import electrosphere.client.entity.camera.CameraEntityUtils; import electrosphere.client.entity.crosshair.Crosshair; +import electrosphere.client.interact.ClientInteractionEngine; import electrosphere.client.item.ItemActions; import electrosphere.client.ui.components.PlayerInventoryWindow; import electrosphere.client.ui.menu.WindowStrings; import electrosphere.client.ui.menu.WindowUtils; import electrosphere.client.ui.menu.ingame.MenuGeneratorsInGame; -import electrosphere.collision.CollisionEngine; -import electrosphere.collision.collidable.Collidable; import electrosphere.controls.Control; import electrosphere.controls.Control.ControlMethod; import electrosphere.controls.Control.ControlType; @@ -613,17 +612,19 @@ public class ControlCategoryMainGame { controlMap.get(INPUT_CODE_INTERACT).setOnPress(new ControlMethod(){public void execute(MouseState mouseState){ if(Globals.playerEntity != null && Globals.playerCamera != null){ Entity camera = Globals.playerCamera; - CollisionEngine collisionEngine = Globals.clientSceneWrapper.getCollisionEngine(); Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(camera)).mul(-1.0); Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(camera)); - Entity target = collisionEngine.rayCast(centerPos, eyePos, CollisionEngine.DEFAULT_INTERACT_DISTANCE, Collidable.MASK_NO_TERRAIN); + Entity target = ClientInteractionEngine.rayCast(centerPos, eyePos); if(target != null && CommonEntityFlags.isInteractable(target)){ Globals.interactionTarget = target; - InteractionData interactionData = CommonEntityUtils.getCommonData(target).getInteraction(); + InteractionData interactionData = CommonEntityUtils.getCommonData(target).getButtonInteraction(); switch(interactionData.getOnInteract()){ - case InteractionData.ON_INTERACT_TARGET: { + case InteractionData.ON_INTERACT_MENU: { WindowUtils.openInteractionMenu(interactionData.getWindowTarget()); } break; + case InteractionData.ON_INTERACT_HARVEST: { + System.out.println("Harvest me! :D"); + } break; default: { throw new Error("Unhandled interaction signal " + interactionData.getOnInteract()); } diff --git a/src/main/java/electrosphere/engine/Globals.java b/src/main/java/electrosphere/engine/Globals.java index d5e54860..82cf3145 100644 --- a/src/main/java/electrosphere/engine/Globals.java +++ b/src/main/java/electrosphere/engine/Globals.java @@ -505,7 +505,7 @@ public class Globals { shaderOptionMap.debug(); //client scene wrapper clientScene = new Scene(); - clientSceneWrapper = new ClientSceneWrapper(clientScene, new CollisionEngine(), CollisionEngine.create(new ClientChemistryCollisionCallback())); + clientSceneWrapper = new ClientSceneWrapper(clientScene, new CollisionEngine(), CollisionEngine.create(new ClientChemistryCollisionCallback()), new CollisionEngine()); //temporary hold for skybox colors skyboxColors = new ArrayList(); //load asset manager @@ -728,7 +728,7 @@ public class Globals { Globals.clientPlayer = null; Globals.playerManager = new PlayerManager(); Globals.clientScene = new Scene(); - Globals.clientSceneWrapper = new ClientSceneWrapper(Globals.clientScene, new CollisionEngine(), CollisionEngine.create(new ClientChemistryCollisionCallback())); + Globals.clientSceneWrapper = new ClientSceneWrapper(Globals.clientScene, new CollisionEngine(), CollisionEngine.create(new ClientChemistryCollisionCallback()), new CollisionEngine()); Globals.clientSynchronizationManager = new ClientSynchronizationManager(); Globals.server = null; Globals.serverSynchronizationManager = new ServerSynchronizationManager(); diff --git a/src/main/java/electrosphere/entity/ClientEntityUtils.java b/src/main/java/electrosphere/entity/ClientEntityUtils.java index 3e045672..58145e70 100644 --- a/src/main/java/electrosphere/entity/ClientEntityUtils.java +++ b/src/main/java/electrosphere/entity/ClientEntityUtils.java @@ -5,6 +5,7 @@ import java.util.List; import org.joml.Quaterniond; import org.joml.Vector3d; +import electrosphere.client.interact.ClientInteractionEngine; import electrosphere.engine.Globals; import electrosphere.entity.state.attach.AttachUtils; import electrosphere.entity.state.hitbox.HitboxCollectionState; @@ -73,6 +74,7 @@ public class ClientEntityUtils { Globals.clientScene.deregisterEntity(entity); } HitboxCollectionState.destroyHitboxState(entity,false); + ClientInteractionEngine.destroyCollidableTemplate(entity); if(entity == Globals.playerEntity && Globals.firstPersonEntity != null){ ClientEntityUtils.destroyEntity(Globals.firstPersonEntity); } diff --git a/src/main/java/electrosphere/entity/EntityDataStrings.java b/src/main/java/electrosphere/entity/EntityDataStrings.java index 0681a2dc..c7c3027f 100644 --- a/src/main/java/electrosphere/entity/EntityDataStrings.java +++ b/src/main/java/electrosphere/entity/EntityDataStrings.java @@ -138,6 +138,14 @@ public class EntityDataStrings { public static final String PHYSICS_MODEL_TEMPLATE = "physicsModelTemplate"; public static final String PHYSICS_MASS = "physicsMass"; public static final String PHYSICS_ENGINE_AUTHORITATIVE_TRANSFORM = "physicsEngineAuthoritativeTransform"; // The physics engine is authoritative abound transforms of object (eg position, rotation) + + /* + * Interaction + */ + public static final String INTERACTION_OFFSET_TRANSFORM = "interactionOffsetTransform"; + public static final String INTERACTION_TEMPLATE = "interactionTemplate"; + public static final String INTERACTION_COLLIDABLE = "interactionCollidable"; + public static final String INTERACTION_BODY = "interactionBody"; /* Gravity Entity diff --git a/src/main/java/electrosphere/entity/types/common/CommonEntityUtils.java b/src/main/java/electrosphere/entity/types/common/CommonEntityUtils.java index 77522876..99fc94d8 100644 --- a/src/main/java/electrosphere/entity/types/common/CommonEntityUtils.java +++ b/src/main/java/electrosphere/entity/types/common/CommonEntityUtils.java @@ -7,6 +7,7 @@ import org.joml.Quaterniond; import org.joml.Vector3d; import org.ode4j.ode.DBody; +import electrosphere.client.interact.ClientInteractionEngine; import electrosphere.collision.PhysicsEntityUtils; import electrosphere.collision.collidable.Collidable; import electrosphere.engine.Globals; @@ -290,8 +291,13 @@ public class CommonEntityUtils { // Interaction Logic // // - if(rawType.getInteraction() != null){ + if(rawType.getButtonInteraction() != null){ CommonEntityFlags.setIsInteractable(entity, true); + if(rawType.getButtonInteraction().getInteractionShape() != null){ + ClientInteractionEngine.attachCollidableTemplate(entity, rawType.getButtonInteraction().getInteractionShape()); + } else if(rawType.getCollidable() != null){ + ClientInteractionEngine.attachCollidableTemplate(entity, rawType.getCollidable()); + } } // @@ -592,7 +598,7 @@ public class CommonEntityUtils { // Interaction Logic // // - if(rawType.getInteraction() != null){ + if(rawType.getButtonInteraction() != null){ CommonEntityFlags.setIsInteractable(entity, true); } diff --git a/src/main/java/electrosphere/game/data/common/CommonEntityType.java b/src/main/java/electrosphere/game/data/common/CommonEntityType.java index 27ee5d34..33670628 100644 --- a/src/main/java/electrosphere/game/data/common/CommonEntityType.java +++ b/src/main/java/electrosphere/game/data/common/CommonEntityType.java @@ -146,9 +146,9 @@ public class CommonEntityType { SpawnItemDescription spawnItem; /** - * The behavior when this entity is interacted with + * The behavior when this entity is interacted with via the button interaction */ - InteractionData interaction; + InteractionData buttonInteraction; /** * Gets the id for this creature type @@ -375,19 +375,19 @@ public class CommonEntityType { } /** - * Gets the behavior when this entity is interacted with - * @return The behavior when this entity is interacted with + * Gets the behavior when this entity is interacted with via the button interaction + * @return The behavior when this entity is interacted with via the button interaction */ - public InteractionData getInteraction() { - return interaction; + public InteractionData getButtonInteraction() { + return buttonInteraction; } /** - * Sets the behavior when this entity is interacted with - * @return The behavior when this entity is interacted with + * Sets the behavior when this entity is interacted with via the button interaction + * @return The behavior when this entity is interacted with via the button interaction */ - public void setInteraction(InteractionData interaction) { - this.interaction = interaction; + public void setButtonInteraction(InteractionData interaction) { + this.buttonInteraction = interaction; } 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 7a87d03e..56eed0bd 100644 --- a/src/main/java/electrosphere/game/data/common/interact/InteractionData.java +++ b/src/main/java/electrosphere/game/data/common/interact/InteractionData.java @@ -1,5 +1,7 @@ package electrosphere.game.data.common.interact; +import electrosphere.game.data.collidable.CollidableTemplate; + /** * Controls handling when interacting with this entity */ @@ -8,7 +10,12 @@ public class InteractionData { /** * Pulls up a menu on interaction */ - public static final String ON_INTERACT_TARGET = "menu"; + public static final String ON_INTERACT_MENU = "menu"; + + /** + * Try harvesting the entity on interaction + */ + public static final String ON_INTERACT_HARVEST = "harvest"; /** * The function to run on interaction @@ -20,6 +27,11 @@ public class InteractionData { */ String windowTarget; + /** + * The collidable shape used for ray casting to pick entities to interact with + */ + CollidableTemplate interactionShape; + /** * Gets the function to run on interaction * @return The function to run on interaction @@ -36,6 +48,12 @@ public class InteractionData { return windowTarget; } - + /** + * Gets the template for the shape used to ray cast for interaction targets + * @return The collidable template + */ + public CollidableTemplate getInteractionShape(){ + return interactionShape; + } }