From 4db2de576a742dd3bc6af54fb39ec7f120a6f333 Mon Sep 17 00:00:00 2001 From: austin Date: Thu, 15 Aug 2024 13:03:41 -0400 Subject: [PATCH] Walk tree --- assets/Data/creatures/human.json | 4 + docs/src/progress/currenttarget.md | 2 + docs/src/progress/renderertodo.md | 51 ++-- .../controls/ControlHandler.java | 21 ++ .../entity/EntityDataStrings.java | 6 + .../groundmove/ClientGroundMovementTree.java | 63 ++++- .../groundmove/ServerGroundMovementTree.java | 75 ++++-- .../state/movement/jump/ServerJumpTree.java | 6 + .../state/movement/speed/ClientWalkTree.java | 220 ++++++++++++++++++ .../state/movement/speed/ServerWalkTree.java | 165 +++++++++++++ .../entity/types/creature/CreatureUtils.java | 9 + .../movement/MovementSystemSerializer.java | 2 + .../type/movement/WalkMovementSystem.java | 29 +++ .../client/ClientSynchronizationManager.java | 9 + .../enums/BehaviorTreeIdEnums.java | 2 + .../synchronization/enums/FieldIdEnums.java | 2 + .../server/ServerSynchronizationManager.java | 21 +- .../transport/StateCollection.java | 14 ++ 18 files changed, 640 insertions(+), 61 deletions(-) create mode 100644 src/main/java/electrosphere/entity/state/movement/speed/ClientWalkTree.java create mode 100644 src/main/java/electrosphere/entity/state/movement/speed/ServerWalkTree.java create mode 100644 src/main/java/electrosphere/game/data/creature/type/movement/WalkMovementSystem.java diff --git a/assets/Data/creatures/human.json b/assets/Data/creatures/human.json index 77b5ec96..ae1a693c 100644 --- a/assets/Data/creatures/human.json +++ b/assets/Data/creatures/human.json @@ -189,6 +189,10 @@ "priorityCategory" : "MOVEMENT_MODIFIER" } } + }, + { + "type" : "WALK", + "modifier": 0.3 } ], "rotatorSystem" : { diff --git a/docs/src/progress/currenttarget.md b/docs/src/progress/currenttarget.md index 4ff9d469..f9efc675 100644 --- a/docs/src/progress/currenttarget.md +++ b/docs/src/progress/currenttarget.md @@ -13,9 +13,11 @@ + fix the vibes Stability + Recoil State on attack Movement penalty while swinging weapon Ticketed randomizer node for BTs to more heavily weight attacking and waiting Slow down strafe movement somehow + bug fixes Fix grass rendering distance + Fix hitbox audio not playing spatially diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 484557d0..11703381 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -576,15 +576,14 @@ True behavior trees Melee ai using BT framework Server block nullchecks Melee AI tweaks +Walk tree # TODO -BIG BIG BIG BIG IMMEDIATE TO DO: -always enforce opengl interface across all opengl calls jesus christ the bone uniform bug was impossible - -Rename "BehaviorTree" to be "Component" (what it actually is) +IMMEDIATE SCALING ISSUES + - Always enforce opengl interface across all opengl calls jesus christ the bone uniform bug was impossible Ability to fully reload game engine state without exiting client - Back out to main menu and load a new level without any values persisting @@ -595,6 +594,23 @@ Unit Testing - Ability to click through the ui via scripts - Add ui tests +Bug Fixes + - Fix hitbox placement does not scale with entity scale on server + - Fix not all grass tiles update when updating a nearby voxel (ie it doesn't go into negative coordinates to scan for foliage updates) + - Fix typescript load error + +Startup Performance + - Cache loaded typescript + - Allow texture map to bind multiple model paths to a single set of mesh->textures + - Cache texture atlas for terrain + +Code Generation + - Generate static "hasXComponent", "getXComponent" functions on sync'd components + +Code cleanup + - Rename "BehaviorTree" to be "Component" (what it actually is) + - Refactor ground movement components + - Refactor menu clases under electrosphere.client package Goof off today requirements: Transvoxel implementation @@ -607,26 +623,13 @@ Transvoxel implementation Terrain Interface Positional Access Interface - Ability to get terrain at point for interactions with game world eg placing grass/water collision -Fix hitbox placement does not scale with entity scale on server - -Fix not all grass tiles update when updating a nearby voxel (ie it doesn't go into negative coordinates to scan for foliage updates) - -Fix typescript load error - -Refactor menu clases under electrosphere.client package - -Allow texture map to bind multiple model paths to a single set of mesh->textures - -Cache texture atlas for terrain - Rework how chunks are written to disk to make them more cache friendly - IE, write consecutively higher LOD levels the further into the file, so that you can read just the first few bytes if its a far away chunk - -Fix voxel type selection menu not showing textures - - The quads are off screen because the calculation for ndcX/ndcY are putting it wayyy to the right -- will need to revisit calcs for all that - -Fix being able to walk off far side of the world (ie in level editor) +Bug fixes + - Fix voxel type selection menu not showing textures + - The quads are off screen because the calculation for ndcX/ndcY are putting it wayyy to the right -- will need to revisit calcs for all that + - Fix being able to walk off far side of the world (ie in level editor) Grass System properly LOD - Have foliage dynamically time out cells to be reconsidered based on distance from player (if close, short cooldown, if far long cooldown) @@ -641,8 +644,6 @@ Refactor render flags Data Cleanup - Clean up creatures - Remove unused ones - - Fix values for movement now that physics has changed - - Fix characters bouncing when landing from a fall - Clean up unused models - Clean up textures - Move model textures into models @@ -690,10 +691,10 @@ Light Manager - Point shadows ??? gltf Support - - Fix bad data with human mesh textures not mapping - Texture loading from gltf file -FileUtils sanitation function check if requested file is in game root dir +Security + - FileUtils sanitation function check if requested file is in game root dir Cellular Automata Fluid Dynamics System - Advect force diff --git a/src/main/java/electrosphere/controls/ControlHandler.java b/src/main/java/electrosphere/controls/ControlHandler.java index 24e797da..18a3831e 100644 --- a/src/main/java/electrosphere/controls/ControlHandler.java +++ b/src/main/java/electrosphere/controls/ControlHandler.java @@ -34,6 +34,7 @@ import static org.lwjgl.glfw.GLFW.GLFW_KEY_J; import static org.lwjgl.glfw.GLFW.GLFW_KEY_K; import static org.lwjgl.glfw.GLFW.GLFW_KEY_L; import static org.lwjgl.glfw.GLFW.GLFW_KEY_LEFT; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_LEFT_ALT; import static org.lwjgl.glfw.GLFW.GLFW_KEY_LEFT_CONTROL; import static org.lwjgl.glfw.GLFW.GLFW_KEY_LEFT_SHIFT; import static org.lwjgl.glfw.GLFW.GLFW_KEY_M; @@ -92,6 +93,7 @@ import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree; import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementRelativeFacing; import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementTreeState; import electrosphere.entity.state.movement.jump.ClientJumpTree; +import electrosphere.entity.state.movement.speed.ClientWalkTree; import electrosphere.entity.types.camera.CameraEntityUtils; import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.logger.LoggerInterface; @@ -130,6 +132,7 @@ public class ControlHandler { public static final String DATA_STRING_INPUT_CODE_IN_GAME_MAIN_MENU = "inGameMainMenu"; public static final String DATA_STRING_INPUT_CODE_LOCK_CROSSHAIR = "crosshairLock"; public static final String INPUT_CODE_SPRINT = "sprint"; + public static final String INPUT_CODE_WALK = "walk"; public static final String INPUT_CODE_INTERACT = "interact"; public static final String INPUT_CODE_DROP = "drop"; public static final String INPUT_CODE_INVENTORY_OPEN = "inventoryOpen"; @@ -318,6 +321,7 @@ public class ControlHandler { handler.addControl(DATA_STRING_INPUT_CODE_IN_GAME_MAIN_MENU, new Control(ControlType.KEY,GLFW_KEY_ESCAPE,false,"Main Menu","Opens the main menu while in game")); handler.addControl(DATA_STRING_INPUT_CODE_LOCK_CROSSHAIR, new Control(ControlType.KEY,GLFW_KEY_CAPS_LOCK,false,"Lock On","Locks the camera onto the target")); handler.addControl(INPUT_CODE_SPRINT, new Control(ControlType.KEY,GLFW_KEY_LEFT_SHIFT,false,"Sprint (hold)","Causes the player to sprint")); + handler.addControl(INPUT_CODE_WALK, new Control(ControlType.KEY,GLFW_KEY_LEFT_ALT,false,"Walk (hold)","Causes the player to walk")); handler.addControl(INPUT_CODE_INTERACT, new Control(ControlType.KEY,GLFW_KEY_E,false,"Interact","Interacts with whatever is targeted currently")); handler.addControl(INPUT_CODE_DROP, new Control(ControlType.KEY,GLFW_KEY_Y,false,"Drop","Drops the currently equipped item")); handler.addControl(INPUT_CODE_INVENTORY_OPEN, new Control(ControlType.KEY,GLFW_KEY_I,false,"Inventory","Opens the player's inventory")); @@ -836,6 +840,23 @@ public class ControlHandler { } }}); + /** + * Walk + */ + mainGameControlList.add(controls.get(INPUT_CODE_WALK)); + controls.get(INPUT_CODE_WALK).setOnPress(new ControlMethod(){public void execute(){ + if(Globals.playerEntity != null && ClientWalkTree.getClientWalkTree(Globals.playerEntity) != null){ + ClientWalkTree clientWalkTree = ClientWalkTree.getClientWalkTree(Globals.playerEntity); + clientWalkTree.start(); + } + }}); + controls.get(INPUT_CODE_WALK).setOnRelease(new ControlMethod(){public void execute(){ + if(Globals.playerEntity != null && ClientWalkTree.getClientWalkTree(Globals.playerEntity) != null){ + ClientWalkTree clientWalkTree = ClientWalkTree.getClientWalkTree(Globals.playerEntity); + clientWalkTree.interrupt(); + } + }}); + mainGameControlList.add(controls.get(ITEM_SECONDARY)); controls.get(ITEM_SECONDARY).setOnPress(new ControlMethod() {public void execute() { ItemActions.attemptSecondaryItemAction(); diff --git a/src/main/java/electrosphere/entity/EntityDataStrings.java b/src/main/java/electrosphere/entity/EntityDataStrings.java index 8f0933c1..02c52a8a 100644 --- a/src/main/java/electrosphere/entity/EntityDataStrings.java +++ b/src/main/java/electrosphere/entity/EntityDataStrings.java @@ -311,6 +311,12 @@ public class EntityDataStrings { */ public static final String TREE_CLIENTALWAYSUPRIGHTTREE = "treeClientAlwaysUprightTree"; public static final String TREE_SERVERALWAYSUPRIGHTTREE = "treeServerAlwaysUprightTree"; + + /** + * Walk tree + */ + public static final String TREE_CLIENTWALKTREE = "treeClientWalkTree"; + public static final String TREE_SERVERWALKTREE = "treeServerWalkTree"; /* Entity categories diff --git a/src/main/java/electrosphere/entity/state/movement/groundmove/ClientGroundMovementTree.java b/src/main/java/electrosphere/entity/state/movement/groundmove/ClientGroundMovementTree.java index 010187fc..078e1461 100644 --- a/src/main/java/electrosphere/entity/state/movement/groundmove/ClientGroundMovementTree.java +++ b/src/main/java/electrosphere/entity/state/movement/groundmove/ClientGroundMovementTree.java @@ -21,6 +21,7 @@ import electrosphere.entity.state.movement.FallTree; import electrosphere.entity.state.movement.SprintTree; import electrosphere.entity.state.movement.jump.ClientJumpTree; import electrosphere.entity.state.movement.jump.ClientJumpTree.JumpState; +import electrosphere.entity.state.movement.speed.ClientWalkTree; import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.net.synchronization.annotation.SyncedField; import electrosphere.net.synchronization.annotation.SynchronizableEnum; @@ -193,12 +194,10 @@ public class ClientGroundMovementTree implements BehaviorTree { @Override public void simulate(float deltaTime){ - float velocity = CreatureUtils.getVelocity(parent); - float acceleration = CreatureUtils.getAcceleration(parent); - float maxNaturalVelocity = ServerGroundMovementTree.getMaximumVelocity(parent, this.groundMovementData, facing); Actor entityActor = EntityUtils.getActor(parent); Vector3d position = EntityUtils.getPosition(parent); Vector3d facingVector = CreatureUtils.getFacingVector(parent); + float maxNaturalVelocity = ServerGroundMovementTree.getMaximumVelocity(parent, this.groundMovementData, facing); DBody body = PhysicsEntityUtils.getDBody(parent); DVector3C linearVelocity = body.getLinearVel(); @@ -309,8 +308,8 @@ public class ClientGroundMovementTree implements BehaviorTree { //conditionally play footstep audio this.playFootstepAudio(0,entityActor.getAnimationTime(animationToPlay),position); - //run startup code - velocity = velocity + acceleration * (float)Globals.timekeeper.getSimFrameTime(); + this.updateVelocity(); + float velocity = this.getModifiedVelocity(); //check if can transition state if(velocity >= maxNaturalVelocity){ velocity = maxNaturalVelocity; @@ -347,10 +346,8 @@ public class ClientGroundMovementTree implements BehaviorTree { //conditionally play footstep audio this.playFootstepAudio(0,entityActor.getAnimationTime(animationToPlay),position); - if(velocity != maxNaturalVelocity){ - velocity = maxNaturalVelocity; - CreatureUtils.setVelocity(parent, velocity); - } + this.updateVelocity(); + float velocity = this.getModifiedVelocity(); body.setLinearVel( movementVector.x * velocity * Globals.timekeeper.getSimFrameTime(), linearVelocity.get1(), @@ -384,7 +381,8 @@ public class ClientGroundMovementTree implements BehaviorTree { this.playFootstepAudio(0,entityActor.getAnimationTime(animationToPlay),position); //velocity stuff - velocity = velocity - acceleration * (float)Globals.timekeeper.getSimFrameTime(); + this.updateVelocity(); + float velocity = this.getModifiedVelocity(); //check if can transition state if(velocity <= 0){ velocity = 0; @@ -395,8 +393,8 @@ public class ClientGroundMovementTree implements BehaviorTree { entityActor.stopAnimation(animationToPlay); } } + CreatureUtils.setVelocity(parent, velocity); } - CreatureUtils.setVelocity(parent, velocity); body.setLinearVel( movementVector.x * velocity * Globals.timekeeper.getSimFrameTime(), linearVelocity.get1(), @@ -461,6 +459,49 @@ public class ClientGroundMovementTree implements BehaviorTree { this.fallTree = fallTree; } + /** + * Updates the velocity and acceleration + */ + private void updateVelocity(){ + float velocity = CreatureUtils.getVelocity(parent); + float acceleration = CreatureUtils.getAcceleration(parent); + float maxNaturalVelocity = ServerGroundMovementTree.getMaximumVelocity(parent, this.groundMovementData, facing); + switch(this.state){ + case IDLE: { + } break; + case STARTUP: { + //run startup code + velocity = velocity + acceleration * (float)Globals.timekeeper.getSimFrameTime(); + CreatureUtils.setVelocity(parent, velocity); + } break; + case MOVE: { + if(velocity != maxNaturalVelocity){ + velocity = maxNaturalVelocity; + CreatureUtils.setVelocity(parent, velocity); + } + } break; + case SLOWDOWN: { + //velocity stuff + velocity = velocity - acceleration * (float)Globals.timekeeper.getSimFrameTime(); + CreatureUtils.setVelocity(parent, velocity); + } break; + } + } + + /** + * Gets the velocity to move at + * @return The velocity + */ + private float getModifiedVelocity(){ + float velocity = CreatureUtils.getVelocity(parent); + float sprintModifier = 1.0f; + float walkModifier = 1.0f; + if(ClientWalkTree.getClientWalkTree(parent) != null && ClientWalkTree.getClientWalkTree(parent).isWalking()){ + walkModifier = ClientWalkTree.getClientWalkTree(parent).getModifier(); + } + return velocity * sprintModifier * walkModifier; + } + /** * Conditionally plays audio for footsteps * @param voxelType The voxel type diff --git a/src/main/java/electrosphere/entity/state/movement/groundmove/ServerGroundMovementTree.java b/src/main/java/electrosphere/entity/state/movement/groundmove/ServerGroundMovementTree.java index ef9e37d9..bf9a6869 100644 --- a/src/main/java/electrosphere/entity/state/movement/groundmove/ServerGroundMovementTree.java +++ b/src/main/java/electrosphere/entity/state/movement/groundmove/ServerGroundMovementTree.java @@ -20,6 +20,7 @@ import electrosphere.entity.state.movement.ServerSprintTree; import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementRelativeFacing; import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementTreeState; import electrosphere.entity.state.movement.jump.ServerJumpTree; +import electrosphere.entity.state.movement.speed.ServerWalkTree; import electrosphere.entity.state.server.ServerPlayerViewDirTree; import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.net.synchronization.annotation.SyncedField; @@ -158,12 +159,8 @@ public class ServerGroundMovementTree implements BehaviorTree { @Override public void simulate(float deltaTime){ - float velocity = 0; - float acceleration = 0; float maxNaturalVelocity = 0; if(CreatureUtils.hasVelocity(parent)){ - velocity = CreatureUtils.getVelocity(parent); - acceleration = CreatureUtils.getAcceleration(parent); maxNaturalVelocity = ServerGroundMovementTree.getMaximumVelocity(parent, this.groundMovementSystem, facing); } if(ServerPlayerViewDirTree.hasTree(parent)){ @@ -265,19 +262,14 @@ public class ServerGroundMovementTree implements BehaviorTree { } } //run startup code - velocity = velocity + acceleration * (float)Globals.timekeeper.getSimFrameTime(); + this.updateVelocity(); + float velocity = this.getModifiedVelocity(); //check if can transition state if(velocity >= maxNaturalVelocity){ velocity = maxNaturalVelocity; state = MovementTreeState.MOVE; + CreatureUtils.setVelocity(parent, velocity); } - CreatureUtils.setVelocity(parent, velocity); -// //actually update - // PhysicsEntityUtils.getDBody(parent).addForce( - // movementVector.x * velocity * Globals.timekeeper.getSimFrameTime(), - // linearVelocity.get1(), - // movementVector.z * velocity * Globals.timekeeper.getSimFrameTime() - // ); PhysicsEntityUtils.getDBody(parent).setLinearVel( movementVector.x * velocity * Globals.timekeeper.getSimFrameTime(), linearVelocity.get1(), @@ -320,22 +312,14 @@ public class ServerGroundMovementTree implements BehaviorTree { poseActor.incrementAnimationTime(0.0001); } } - if(velocity != maxNaturalVelocity){ - velocity = maxNaturalVelocity; - CreatureUtils.setVelocity(parent, velocity); - } - // PhysicsEntityUtils.getDBody(parent).addForce( - // movementVector.x * velocity * Globals.timekeeper.getSimFrameTime(), - // linearVelocity.get1(), - // movementVector.z * velocity * Globals.timekeeper.getSimFrameTime() - // ); + this.updateVelocity(); + float velocity = this.getModifiedVelocity(); PhysicsEntityUtils.getDBody(parent).setLinearVel( movementVector.x * velocity * Globals.timekeeper.getSimFrameTime(), linearVelocity.get1(), movementVector.z * velocity * Globals.timekeeper.getSimFrameTime() ); body.setAngularVel(0, 0, 0); -// position.set(newPosition); GravityUtils.serverAttemptActivateGravity(parent); @@ -377,7 +361,8 @@ public class ServerGroundMovementTree implements BehaviorTree { } } //velocity stuff - velocity = velocity - acceleration * (float)Globals.timekeeper.getSimFrameTime(); + this.updateVelocity(); + float velocity = this.getModifiedVelocity(); //check if can transition state if(velocity <= 0){ velocity = 0; @@ -389,7 +374,6 @@ public class ServerGroundMovementTree implements BehaviorTree { } } } - CreatureUtils.setVelocity(parent, velocity); // PhysicsEntityUtils.getDBody(parent).addForce( // movementVector.x * velocity * Globals.timekeeper.getSimFrameTime(), // linearVelocity.get1(), @@ -427,6 +411,49 @@ public class ServerGroundMovementTree implements BehaviorTree { } } + /** + * Updates the velocity and acceleration + */ + private void updateVelocity(){ + float velocity = CreatureUtils.getVelocity(parent); + float acceleration = CreatureUtils.getAcceleration(parent); + float maxNaturalVelocity = ServerGroundMovementTree.getMaximumVelocity(parent, this.groundMovementSystem, facing); + switch(this.state){ + case IDLE: { + } break; + case STARTUP: { + //run startup code + velocity = velocity + acceleration * (float)Globals.timekeeper.getSimFrameTime(); + CreatureUtils.setVelocity(parent, velocity); + } break; + case MOVE: { + if(velocity != maxNaturalVelocity){ + velocity = maxNaturalVelocity; + CreatureUtils.setVelocity(parent, velocity); + } + } break; + case SLOWDOWN: { + //velocity stuff + velocity = velocity - acceleration * (float)Globals.timekeeper.getSimFrameTime(); + CreatureUtils.setVelocity(parent, velocity); + } break; + } + } + + /** + * Gets the velocity to move at + * @return The velocity + */ + private float getModifiedVelocity(){ + float velocity = CreatureUtils.getVelocity(parent); + float sprintModifier = 1.0f; + float walkModifier = 1.0f; + if(ServerWalkTree.getServerWalkTree(parent) != null && ServerWalkTree.getServerWalkTree(parent).isWalking()){ + walkModifier = ServerWalkTree.getServerWalkTree(parent).getModifier(); + } + return velocity * sprintModifier * walkModifier; + } + public void addNetworkMessage(EntityMessage networkMessage) { networkMessageQueue.add(networkMessage); } diff --git a/src/main/java/electrosphere/entity/state/movement/jump/ServerJumpTree.java b/src/main/java/electrosphere/entity/state/movement/jump/ServerJumpTree.java index 19008a74..a4b5fdd4 100644 --- a/src/main/java/electrosphere/entity/state/movement/jump/ServerJumpTree.java +++ b/src/main/java/electrosphere/entity/state/movement/jump/ServerJumpTree.java @@ -64,6 +64,12 @@ public class ServerJumpTree implements BehaviorTree { } } + /** + * Interrupts the tree + */ + public void interrupt(){ + } + @Override public void simulate(float deltaTime) { PoseActor poseActor = EntityUtils.getPoseActor(parent); diff --git a/src/main/java/electrosphere/entity/state/movement/speed/ClientWalkTree.java b/src/main/java/electrosphere/entity/state/movement/speed/ClientWalkTree.java new file mode 100644 index 00000000..46a45ad0 --- /dev/null +++ b/src/main/java/electrosphere/entity/state/movement/speed/ClientWalkTree.java @@ -0,0 +1,220 @@ +package electrosphere.entity.state.movement.speed; + + +import electrosphere.net.synchronization.server.ServerSynchronizationManager; +import electrosphere.net.parser.net.message.SynchronizationMessage; +import electrosphere.net.synchronization.enums.BehaviorTreeIdEnums; +import electrosphere.engine.Globals; +import electrosphere.entity.Entity; +import electrosphere.entity.EntityDataStrings; +import electrosphere.entity.btree.BehaviorTree; +import electrosphere.game.data.creature.type.movement.WalkMovementSystem; +import electrosphere.net.synchronization.annotation.SyncedField; +import electrosphere.net.synchronization.annotation.SynchronizableEnum; +import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree; + +@SynchronizedBehaviorTree( + name = "clientWalkTree", + isServer = false, + correspondingTree = "serverWalkTree", + genStartInt = true +) +/* +Behavior tree for walking +*/ +public class ClientWalkTree implements BehaviorTree { + + /** + * States for the walk tree + */ + @SynchronizableEnum + public static enum WalkState { + /** + * Is not walking + */ + INACTIVE, + /** + * Is walking + */ + ACTIVE, + } + + /** + * The state of the tree + */ + @SyncedField + WalkState state = WalkState.INACTIVE; + + /** + * The parent entity + */ + Entity parent; + + /** + * The data for the walking system + */ + WalkMovementSystem walkMovementSystem; + + + @Override + public void simulate(float deltaTime){ + } + + /** + * Checks if the tree is walking + * @return True if is walking, false otherwise + */ + public boolean isWalking(){ + return this.state == WalkState.ACTIVE; + } + + /** + * Gets the movement modifier to apply while walking + * @return The modifier + */ + public float getModifier(){ + return this.walkMovementSystem.getModifier(); + } + + + /** + *

(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 ClientWalkTree attachTree(Entity parent, Object ... params){ + ClientWalkTree rVal = new ClientWalkTree(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_CLIENTWALKTREE, rVal); + Globals.clientSceneWrapper.getScene().registerBehaviorTree(rVal); + Globals.entityValueTrackingService.attachTreeToEntity(parent, BehaviorTreeIdEnums.BTREE_CLIENTWALKTREE_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_CLIENTWALKTREE_ID); + } + + /** + *

(initially) Automatically generated

+ *

Private constructor to enforce using the attach methods

+ *

+ * Constructor + *

+ * @param parent The parent entity of this tree + * @param params Optional parameters that can be provided when attaching the tree. All custom data required for creating this tree should be passed in this varargs. + */ + public ClientWalkTree(Entity parent, Object ... params){ + if(params.length < 1 || (params[0] instanceof WalkMovementSystem) == false){ + throw new IllegalArgumentException("Trying to create client walk tree with invalid arguments!"); + } + this.parent = parent; + this.walkMovementSystem = (WalkMovementSystem)params[0]; + } + + /** + *

+ * Gets the ClientWalkTree of the entity + *

+ * @param entity the entity + * @return The ClientWalkTree + */ + public static ClientWalkTree getClientWalkTree(Entity entity){ + return (ClientWalkTree)entity.getData(EntityDataStrings.TREE_CLIENTWALKTREE); + } + + /** + *

Automatically generated

+ *

+ * Requests that the server start this btree + *

+ */ + public void start(){ + Globals.clientConnection.queueOutgoingMessage( + SynchronizationMessage.constructClientRequestBTreeActionMessage( + Globals.clientSceneWrapper.mapClientToServerId(parent.getId()), + BehaviorTreeIdEnums.BTREE_CLIENTWALKTREE_ID, + ServerSynchronizationManager.SERVER_SYNC_START + ) + ); + } + + /** + *

Automatically generated

+ *

+ * Requests that the server start this btree + *

+ */ + public void interrupt(){ + Globals.clientConnection.queueOutgoingMessage( + SynchronizationMessage.constructClientRequestBTreeActionMessage( + Globals.clientSceneWrapper.mapClientToServerId(parent.getId()), + BehaviorTreeIdEnums.BTREE_CLIENTWALKTREE_ID, + ServerSynchronizationManager.SERVER_SYNC_INTERRUPT + ) + ); + } + + /** + *

Automatically generated

+ *

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

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

Automatically generated

+ *

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

+ * @param shortVal The short value + * @return The enum value + */ + public static WalkState getWalkStateShortAsEnum(short shortVal){ + switch(shortVal){ + case 0: + return WalkState.INACTIVE; + case 1: + return WalkState.ACTIVE; + default: + return WalkState.INACTIVE; + } + } + + /** + *

Automatically generated

+ *

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

+ * @param enumVal The enum value + * @return The short value + */ + public static short getWalkStateEnumAsShort(WalkState enumVal){ + switch(enumVal){ + case INACTIVE: + return 0; + case ACTIVE: + return 1; + default: + return 0; + } + } + +} diff --git a/src/main/java/electrosphere/entity/state/movement/speed/ServerWalkTree.java b/src/main/java/electrosphere/entity/state/movement/speed/ServerWalkTree.java new file mode 100644 index 00000000..77f0fc0f --- /dev/null +++ b/src/main/java/electrosphere/entity/state/movement/speed/ServerWalkTree.java @@ -0,0 +1,165 @@ +package electrosphere.entity.state.movement.speed; + + +import electrosphere.engine.Globals; +import electrosphere.entity.EntityDataStrings; +import electrosphere.net.synchronization.enums.FieldIdEnums; +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.state.movement.speed.ClientWalkTree.WalkState; +import electrosphere.game.data.creature.type.movement.WalkMovementSystem; +import electrosphere.net.synchronization.annotation.SyncedField; +import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree; + +@SynchronizedBehaviorTree( + name = "serverWalkTree", + isServer = true, + correspondingTree = "clientWalkTree" +) +/* +Behavior tree for walking +*/ +public class ServerWalkTree implements BehaviorTree { + + /** + * The state of the tree + */ + @SyncedField + WalkState state = WalkState.INACTIVE; + + /** + * The parent entity + */ + Entity parent; + + /** + * The data for the walking system + */ + WalkMovementSystem walkMovementSystem; + + @Override + public void simulate(float deltaTime) { + } + + /** + * Gets the movement modifier to apply while walking + * @return The modifier + */ + public float getModifier(){ + return this.walkMovementSystem.getModifier(); + } + + /** + * Starts the tree + */ + public void start(){ + this.setState(WalkState.ACTIVE); + } + + /** + * Stops the tree + */ + public void stop(){ + this.setState(WalkState.INACTIVE); + } + + /** + * Interrupts the tree + */ + public void interrupt(){ + this.setState(WalkState.INACTIVE); + } + + /** + * Checks if the tree is walking + * @return True if is walking, false otherwise + */ + public boolean isWalking(){ + return this.state == WalkState.ACTIVE; + } + + /** + * Gets the state + * @return The state + */ + public WalkState getState(){ + return 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 ServerWalkTree attachTree(Entity parent, Object ... params){ + ServerWalkTree rVal = new ServerWalkTree(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_SERVERWALKTREE, rVal); + Globals.entityValueTrackingService.attachTreeToEntity(parent, BehaviorTreeIdEnums.BTREE_SERVERWALKTREE_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_SERVERWALKTREE_ID); + } + + /** + *

(initially) Automatically generated

+ *

Private constructor to enforce using the attach methods

+ *

+ * Constructor + *

+ * @param parent The parent entity of this tree + * @param params Optional parameters that can be provided when attaching the tree. All custom data required for creating this tree should be passed in this varargs. + */ + public ServerWalkTree(Entity parent, Object ... params){ + if(params.length < 1 || (params[0] instanceof WalkMovementSystem) == false){ + throw new IllegalArgumentException("Trying to create client walk tree with invalid arguments!"); + } + this.parent = parent; + this.walkMovementSystem = (WalkMovementSystem)params[0]; + } + + /** + *

+ * Gets the ServerWalkTree of the entity + *

+ * @param entity the entity + * @return The ServerWalkTree + */ + public static ServerWalkTree getServerWalkTree(Entity entity){ + return (ServerWalkTree)entity.getData(EntityDataStrings.TREE_SERVERWALKTREE); + } + + /** + *

Automatically generated

+ *

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

+ * @param state The value to set state to. + */ + public void setState(WalkState state){ + this.state = state; + int value = ClientWalkTree.getWalkStateEnumAsShort(state); + DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructUpdateClientStateMessage(parent.getId(), BehaviorTreeIdEnums.BTREE_SERVERWALKTREE_ID, FieldIdEnums.TREE_SERVERWALKTREE_SYNCEDFIELD_STATE_ID, value)); + } + +} diff --git a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java index ce121496..8801c454 100644 --- a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java +++ b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java @@ -41,6 +41,8 @@ import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree; import electrosphere.entity.state.movement.groundmove.ServerGroundMovementTree; import electrosphere.entity.state.movement.jump.ClientJumpTree; import electrosphere.entity.state.movement.jump.ServerJumpTree; +import electrosphere.entity.state.movement.speed.ClientWalkTree; +import electrosphere.entity.state.movement.speed.ServerWalkTree; import electrosphere.entity.state.physicssync.upright.ClientAlwaysUprightTree; import electrosphere.entity.state.physicssync.upright.ServerAlwaysUprightTree; import electrosphere.entity.state.rotator.RotatorHierarchyNode; @@ -57,6 +59,7 @@ import electrosphere.game.data.creature.type.movement.FallMovementSystem; import electrosphere.game.data.creature.type.movement.GroundMovementSystem; import electrosphere.game.data.creature.type.movement.JumpMovementSystem; import electrosphere.game.data.creature.type.movement.MovementSystem; +import electrosphere.game.data.creature.type.movement.WalkMovementSystem; import electrosphere.game.data.creature.type.rotator.RotatorConstraint; import electrosphere.game.data.creature.type.rotator.RotatorItem; import electrosphere.game.data.creature.type.rotator.RotatorSystem; @@ -198,6 +201,9 @@ public class CreatureUtils { rVal.putData(EntityDataStrings.FALL_TREE, fallTree); Globals.clientScene.registerBehaviorTree(fallTree); break; + case WalkMovementSystem.WALK_MOVEMENT_SYSTEM: { + ClientWalkTree.attachTree(rVal, (WalkMovementSystem)movementSystem); + } break; } } if(rawType.getEquipPoints() != null && rawType.getEquipPoints().size() > 0){ @@ -467,6 +473,9 @@ public class CreatureUtils { rVal.putData(EntityDataStrings.FALL_TREE, fallTree); ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, fallTree); break; + case WalkMovementSystem.WALK_MOVEMENT_SYSTEM: { + ServerWalkTree.attachTree(rVal, (WalkMovementSystem)movementSystem); + } break; } } diff --git a/src/main/java/electrosphere/game/data/creature/type/movement/MovementSystemSerializer.java b/src/main/java/electrosphere/game/data/creature/type/movement/MovementSystemSerializer.java index 0c68a96a..f5500563 100644 --- a/src/main/java/electrosphere/game/data/creature/type/movement/MovementSystemSerializer.java +++ b/src/main/java/electrosphere/game/data/creature/type/movement/MovementSystemSerializer.java @@ -21,6 +21,8 @@ public class MovementSystemSerializer implements JsonDeserializer