Walk tree

This commit is contained in:
austin 2024-08-15 13:03:41 -04:00
parent 89a0df81a5
commit 4db2de576a
18 changed files with 640 additions and 61 deletions

View File

@ -189,6 +189,10 @@
"priorityCategory" : "MOVEMENT_MODIFIER"
}
}
},
{
"type" : "WALK",
"modifier": 0.3
}
],
"rotatorSystem" : {

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -312,6 +312,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
*/

View File

@ -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

View File

@ -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);
}

View File

@ -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);

View File

@ -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();
}
/**
* <p> (initially) Automatically generated </p>
* <p>
* Attaches this tree to the entity.
* </p>
* @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;
}
/**
* <p> Automatically generated </p>
* <p>
* Detatches this tree from the entity.
* </p>
* @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);
}
/**
* <p> (initially) Automatically generated </p>
* <p> Private constructor to enforce using the attach methods </p>
* <p>
* Constructor
* </p>
* @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];
}
/**
* <p>
* Gets the ClientWalkTree of the entity
* </p>
* @param entity the entity
* @return The ClientWalkTree
*/
public static ClientWalkTree getClientWalkTree(Entity entity){
return (ClientWalkTree)entity.getData(EntityDataStrings.TREE_CLIENTWALKTREE);
}
/**
* <p> Automatically generated </p>
* <p>
* Requests that the server start this btree
* </p>
*/
public void start(){
Globals.clientConnection.queueOutgoingMessage(
SynchronizationMessage.constructClientRequestBTreeActionMessage(
Globals.clientSceneWrapper.mapClientToServerId(parent.getId()),
BehaviorTreeIdEnums.BTREE_CLIENTWALKTREE_ID,
ServerSynchronizationManager.SERVER_SYNC_START
)
);
}
/**
* <p> Automatically generated </p>
* <p>
* Requests that the server start this btree
* </p>
*/
public void interrupt(){
Globals.clientConnection.queueOutgoingMessage(
SynchronizationMessage.constructClientRequestBTreeActionMessage(
Globals.clientSceneWrapper.mapClientToServerId(parent.getId()),
BehaviorTreeIdEnums.BTREE_CLIENTWALKTREE_ID,
ServerSynchronizationManager.SERVER_SYNC_INTERRUPT
)
);
}
/**
* <p> Automatically generated </p>
* <p>
* Sets state and handles the synchronization logic for it.
* </p>
* @param state The value to set state to.
*/
public void setState(WalkState state){
this.state = state;
}
/**
* <p> Automatically generated </p>
* <p>
* Converts a short to the equivalent enum value
* </p>
* @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;
}
}
/**
* <p> Automatically generated </p>
* <p>
* Converts this enum type to an equivalent short value
* </p>
* @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;
}
}
}

View File

@ -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;
}
/**
* <p> (initially) Automatically generated </p>
* <p>
* Attaches this tree to the entity.
* </p>
* @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;
}
/**
* <p> Automatically generated </p>
* <p>
* Detatches this tree from the entity.
* </p>
* @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);
}
/**
* <p> (initially) Automatically generated </p>
* <p> Private constructor to enforce using the attach methods </p>
* <p>
* Constructor
* </p>
* @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];
}
/**
* <p>
* Gets the ServerWalkTree of the entity
* </p>
* @param entity the entity
* @return The ServerWalkTree
*/
public static ServerWalkTree getServerWalkTree(Entity entity){
return (ServerWalkTree)entity.getData(EntityDataStrings.TREE_SERVERWALKTREE);
}
/**
* <p> Automatically generated </p>
* <p>
* Sets state and handles the synchronization logic for it.
* </p>
* @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));
}
}

View File

@ -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;
}
}

View File

@ -21,6 +21,8 @@ public class MovementSystemSerializer implements JsonDeserializer<MovementSystem
return context.deserialize(json, FallMovementSystem.class);
case AirplaneMovementSystem.AIRPLANE_MOVEMENT_SYSTEM:
return context.deserialize(json, AirplaneMovementSystem.class);
case WalkMovementSystem.WALK_MOVEMENT_SYSTEM:
return context.deserialize(json, WalkMovementSystem.class);
}
return null;
}

View File

@ -0,0 +1,29 @@
package electrosphere.game.data.creature.type.movement;
/**
* A walk movement system
*/
public class WalkMovementSystem implements MovementSystem {
//move system type string
public static final String WALK_MOVEMENT_SYSTEM = "WALK";
@Override
public String getType() {
return WALK_MOVEMENT_SYSTEM;
}
/**
* The movespeed modifier applied when walking
*/
float modifier;
/**
* The movespeed modifier applied when walking
* @return The modifier
*/
public float getModifier(){
return modifier;
}
}

View File

@ -1,6 +1,7 @@
package electrosphere.net.synchronization.client;
import electrosphere.entity.state.movement.speed.ClientWalkTree;
import electrosphere.entity.state.equip.ClientEquipState;
import electrosphere.entity.state.movement.jump.ClientJumpTree;
import electrosphere.entity.state.life.ClientLifeTree;
@ -221,6 +222,14 @@ public class ClientSynchronizationManager {
} break;
}
} break;
case BehaviorTreeIdEnums.BTREE_SERVERWALKTREE_ID: {
switch(message.getfieldId()){
case FieldIdEnums.TREE_SERVERWALKTREE_SYNCEDFIELD_STATE_ID:{
ClientWalkTree tree = ClientWalkTree.getClientWalkTree(entity);
tree.setState(ClientWalkTree.getWalkStateShortAsEnum((short)message.getbTreeValue()));
} break;
}
} break;
}
}

View File

@ -21,5 +21,7 @@ public class BehaviorTreeIdEnums {
public static final int BTREE_SERVERGROUNDMOVEMENTTREE_ID = 11;
public static final int BTREE_CLIENTJUMPTREE_ID = 14;
public static final int BTREE_SERVERJUMPTREE_ID = 15;
public static final int BTREE_CLIENTWALKTREE_ID = 16;
public static final int BTREE_SERVERWALKTREE_ID = 17;
}

View File

@ -29,5 +29,7 @@ public class FieldIdEnums {
public static final int TREE_SERVERJUMPTREE_SYNCEDFIELD_STATE_ID = 19;
public static final int TREE_SERVERJUMPTREE_SYNCEDFIELD_CURRENTFRAME_ID = 20;
public static final int TREE_SERVERJUMPTREE_SYNCEDFIELD_CURRENTJUMPFORCE_ID = 21;
public static final int TREE_CLIENTWALKTREE_SYNCEDFIELD_STATE_ID = 24;
public static final int TREE_SERVERWALKTREE_SYNCEDFIELD_STATE_ID = 25;
}

View File

@ -1,6 +1,7 @@
package electrosphere.net.synchronization.server;
import electrosphere.entity.state.movement.speed.ServerWalkTree;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@ -83,7 +84,25 @@ public class ServerSynchronizationManager {
switch(bTreeId){
case BehaviorTreeIdEnums.BTREE_CLIENTJUMPTREE_ID: {
ServerJumpTree tree = ServerJumpTree.getServerJumpTree(entity);
tree.start();
switch(message.getbTreeValue()){
case ServerSynchronizationManager.SERVER_SYNC_START: {
tree.start();
} break;
case ServerSynchronizationManager.SERVER_SYNC_INTERRUPT: {
tree.interrupt();
} break;
}
} break;
case BehaviorTreeIdEnums.BTREE_CLIENTWALKTREE_ID: {
ServerWalkTree tree = ServerWalkTree.getServerWalkTree(entity);
switch(message.getbTreeValue()){
case ServerSynchronizationManager.SERVER_SYNC_START: {
tree.start();
} break;
case ServerSynchronizationManager.SERVER_SYNC_INTERRUPT: {
tree.interrupt();
} break;
}
} break;
}

View File

@ -1,6 +1,8 @@
package electrosphere.net.synchronization.transport;
import electrosphere.entity.state.movement.speed.ServerWalkTree;
import electrosphere.entity.state.movement.speed.ClientWalkTree;
import electrosphere.entity.state.equip.ClientEquipState;
import java.util.LinkedList;
import java.util.List;
@ -100,6 +102,10 @@ public class StateCollection {
collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERJUMPTREE_ID,FieldIdEnums.TREE_SERVERJUMPTREE_SYNCEDFIELD_CURRENTFRAME_ID,tree.getCurrentFrame()));
collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERJUMPTREE_ID,FieldIdEnums.TREE_SERVERJUMPTREE_SYNCEDFIELD_CURRENTJUMPFORCE_ID,tree.getCurrentJumpForce()));
} break;
case BehaviorTreeIdEnums.BTREE_SERVERWALKTREE_ID: {
ServerWalkTree tree = ServerWalkTree.getServerWalkTree(entity);
collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERWALKTREE_ID,FieldIdEnums.TREE_SERVERWALKTREE_SYNCEDFIELD_STATE_ID,ClientWalkTree.getWalkStateEnumAsShort(tree.getState())));
} break;
}
}
@ -193,6 +199,14 @@ public class StateCollection {
} break;
}
} break;
case BehaviorTreeIdEnums.BTREE_SERVERWALKTREE_ID: {
ClientWalkTree tree = ClientWalkTree.getClientWalkTree(entity);
switch(syncedValue.getFieldId()){
case(FieldIdEnums.TREE_SERVERWALKTREE_SYNCEDFIELD_STATE_ID): {
tree.setState(ClientWalkTree.getWalkStateShortAsEnum(((Double)syncedValue.getValue()).shortValue()));
} break;
}
} break;
}
}