diff --git a/assets/Config/keybinds.json b/assets/Config/keybinds.json index 61f3b7e9..10ef1272 100644 --- a/assets/Config/keybinds.json +++ b/assets/Config/keybinds.json @@ -121,6 +121,11 @@ "isKey": true, "isMouse": false, "keyValue": 256 + }, + "sprint" : { + "isKey": true, + "isMouse": false, + "keyValue": 340 } } } \ No newline at end of file diff --git a/assets/Data/creatures.json b/assets/Data/creatures.json index 46770e6c..569c30f8 100644 --- a/assets/Data/creatures.json +++ b/assets/Data/creatures.json @@ -230,7 +230,7 @@ { "type" : "GROUND", "acceleration" : 13.0, - "maxVelocity" : 2.8, + "maxVelocity" : 1.8, "animationStartup" : { "name" : "Walk", "length" : 1, @@ -245,6 +245,20 @@ "name" : "Armature|WalkForwardStart", "length" : 1, "loops" : false + }, + "sprintSystem" : { + "maxVelocity" : 3.8, + "staminaMax" : 500, + "animationStartUp" : { + "name" : "Run", + "length" : 1, + "loops" : false + }, + "animationMain" : { + "name" : "Run", + "length" : 1, + "loops" : false + } } } ], diff --git a/src/main/java/electrosphere/controls/ControlHandler.java b/src/main/java/electrosphere/controls/ControlHandler.java index be22766e..097214a3 100644 --- a/src/main/java/electrosphere/controls/ControlHandler.java +++ b/src/main/java/electrosphere/controls/ControlHandler.java @@ -8,6 +8,7 @@ import electrosphere.entity.EntityUtils; import electrosphere.entity.state.AttackTree; import electrosphere.entity.state.movement.GroundMovementTree; import electrosphere.entity.state.movement.GroundMovementTree.MovementTreeState; +import electrosphere.entity.state.movement.SprintTree; import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.types.item.ItemUtils; import electrosphere.game.client.targeting.crosshair.Crosshair; @@ -44,6 +45,7 @@ public class ControlHandler { public static final String DATA_STRING_INPUT_CODE_DEBUG_SPAWN_ITEM = "debugSpawnItem"; 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 DATA_STRING_INPUT_CODE_MENU_INCREMENT = "menuIncrement"; public static final String DATA_STRING_INPUT_CODE_MENU_DECREMENT = "menuDecrement"; @@ -128,6 +130,7 @@ public class ControlHandler { handler.addControl(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY, new Control(false,true,GLFW_MOUSE_BUTTON_LEFT)); handler.addControl(DATA_STRING_INPUT_CODE_IN_GAME_MAIN_MENU, new Control(true,false,GLFW_KEY_ESCAPE)); handler.addControl(DATA_STRING_INPUT_CODE_LOCK_CROSSHAIR, new Control(false,true,GLFW_MOUSE_BUTTON_RIGHT)); + handler.addControl(INPUT_CODE_SPRINT, new Control(true,false,GLFW_KEY_LEFT_SHIFT)); /* Map the menu navigation controls @@ -237,6 +240,7 @@ public class ControlHandler { public void pollMainGameControls(){ if(Globals.playerCharacter != null){ GroundMovementTree movementTree = CreatureUtils.getEntityMovementTree(Globals.playerCharacter); + SprintTree sprintTree = CreatureUtils.getSprintTree(Globals.playerCharacter); AttackTree attackTree = CreatureUtils.getAttackTree(Globals.playerCharacter); Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera); /* @@ -361,6 +365,25 @@ public class ControlHandler { if(controls.containsKey(DATA_STRING_INPUT_CODE_MOVEMENT_FALL) && glfwGetKey(Globals.window, controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_FALL).getKeyValue()) == GLFW_PRESS){ EntityUtils.getPosition(Globals.playerCharacter).add(new Vector3f(0,-0.6f,0).mul(1f)); } + /* + Sprint + */ + if(controls.containsKey(INPUT_CODE_SPRINT)){ + if(controls.get(INPUT_CODE_SPRINT).isIsKey() && glfwGetKey(Globals.window, controls.get(INPUT_CODE_SPRINT).getKeyValue()) == GLFW_PRESS){ + if(controls.get(INPUT_CODE_SPRINT).isState() == false){ + if(sprintTree != null){ + System.out.println("Sprint code"); + sprintTree.start(); + } + } + controls.get(INPUT_CODE_SPRINT).setState(true); + } else { + if(controls.get(INPUT_CODE_SPRINT).isState() == true){ + sprintTree.stop(); + } + controls.get(INPUT_CODE_SPRINT).setState(false); + } + } /* Attack diff --git a/src/main/java/electrosphere/entity/EntityDataStrings.java b/src/main/java/electrosphere/entity/EntityDataStrings.java index 7224e0a3..cdbcf211 100644 --- a/src/main/java/electrosphere/entity/EntityDataStrings.java +++ b/src/main/java/electrosphere/entity/EntityDataStrings.java @@ -32,6 +32,7 @@ public class EntityDataStrings { public static final String DATA_STRING_CREATURE_TYPE = "creatureType"; public static final String DATA_STRING_CREATURE_CONTROLLER_PLAYER_ID = "creaturePlayerId"; public static final String DATA_STRING_MOVEMENT_BT = "movementBT"; + public static final String SPRINT_TREE = "sprintBT"; public static final String DATA_STRING_MOVEMENT_VECTOR = "movementVector"; public static final String DATA_STRING_VELOCITY = "velocity"; public static final String DATA_STRING_ACCELERATION = "acceleration"; diff --git a/src/main/java/electrosphere/entity/EntityManager.java b/src/main/java/electrosphere/entity/EntityManager.java index 5026f64c..c4c05207 100644 --- a/src/main/java/electrosphere/entity/EntityManager.java +++ b/src/main/java/electrosphere/entity/EntityManager.java @@ -32,6 +32,7 @@ public class EntityManager { static CopyOnWriteArrayList gravityList = new CopyOnWriteArrayList(); static CopyOnWriteArrayList collidableList = new CopyOnWriteArrayList(); static CopyOnWriteArrayList targetableList = new CopyOnWriteArrayList(); + static CopyOnWriteArrayList sprintableList = new CopyOnWriteArrayList(); public EntityManager(){ @@ -146,6 +147,14 @@ public class EntityManager { return targetableList; } + public void registerSprintableEntity(Entity e){ + sprintableList.add(e); + } + + public CopyOnWriteArrayList getSprintables(){ + return sprintableList; + } + public void deregisterEntity(Entity e){ if(lightList.contains(e)){ lightList.remove(e); @@ -187,6 +196,9 @@ public class EntityManager { if(targetableList.contains(e)){ targetableList.remove(e); } + if(sprintableList.contains(e)){ + sprintableList.remove(e); + } } public void recursiveDeregister(Entity target){ diff --git a/src/main/java/electrosphere/entity/state/LookAtState.java b/src/main/java/electrosphere/entity/state/LookAtState.java new file mode 100644 index 00000000..ab4038bd --- /dev/null +++ b/src/main/java/electrosphere/entity/state/LookAtState.java @@ -0,0 +1,28 @@ +package electrosphere.entity.state; + +import electrosphere.entity.Entity; + +/** + * + * @author amaterasu + */ +public class LookAtState { + + Entity parent; + + float pitch; + + + public LookAtState(Entity parent){ + this.parent = parent; + } + + public void setPitch(float pitch){ + this.pitch = pitch; + } + + public float getPitch(){ + return pitch; + } + +} diff --git a/src/main/java/electrosphere/entity/state/movement/GroundMovementTree.java b/src/main/java/electrosphere/entity/state/movement/GroundMovementTree.java index 154c6a16..be9f7ea2 100644 --- a/src/main/java/electrosphere/entity/state/movement/GroundMovementTree.java +++ b/src/main/java/electrosphere/entity/state/movement/GroundMovementTree.java @@ -10,6 +10,7 @@ import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityUtils; import electrosphere.entity.state.GravityTree; import electrosphere.entity.state.GravityTree; +import electrosphere.entity.state.movement.SprintTree.SprintTreeState; import electrosphere.game.collision.CollisionEngine; import electrosphere.game.collision.PhysicsUtils; import electrosphere.game.collision.collidable.Collidable; @@ -46,9 +47,14 @@ public class GroundMovementTree { String animationStartUp = Animation.ANIMATION_MOVEMENT_STARTUP; String animationMain = Animation.ANIMATION_MOVEMENT_MOVE; String animationSlowDown = Animation.ANIMATION_MOVEMENT_MOVE; + String animationSprintStart = Animation.ANIMATION_SPRINT_STARTUP; + String animationSprint = Animation.ANIMATION_SPRINT; + String animationSprintWindDown = Animation.ANIMATION_SPRINT_WINDDOWN; MovementTreeState state; + SprintTree sprintTree; + Entity parent; Collidable collidable; @@ -84,7 +90,7 @@ public class GroundMovementTree { public void simulate(){ float velocity = CreatureUtils.getVelocity(parent); float acceleration = CreatureUtils.getAcceleration(parent); - float maxNaturalVelocity = CreatureUtils.getMaxNaturalVelocity(parent); + float maxNaturalVelocity = sprintTree != null && sprintTree.state == SprintTreeState.SPRINTING ? sprintTree.maxVelocity : CreatureUtils.getMaxNaturalVelocity(parent); Actor entityActor = EntityUtils.getActor(parent); // Model entityModel = Globals.assetManager.fetchModel(EntityUtils.getEntityModelPath(parent)); Vector3d position = EntityUtils.getPosition(parent); @@ -92,7 +98,6 @@ public class GroundMovementTree { // float movementYaw = CameraEntityUtils.getCameraYaw(Globals.playerCamera); Quaternionf movementQuaternion = new Quaternionf().rotationTo(new Vector3f(0,0,1), new Vector3f((float)movementVector.x,(float)movementVector.y,(float)movementVector.z)).normalize(); Quaternionf rotation = EntityUtils.getRotation(parent); - Vector3d newPosition; //parse attached network messages for(EntityMessage message : networkMessageQueue){ @@ -165,9 +170,16 @@ public class GroundMovementTree { velocity = velocity + acceleration * Main.deltaTime; CreatureUtils.setVelocity(parent, velocity); if(entityActor != null){ - if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationStartUp)){ - entityActor.playAnimation(animationStartUp); - entityActor.incrementAnimationTime(0.01); + if(sprintTree != null && sprintTree.state == SprintTreeState.SPRINTING){ + if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationSprintStart)){ + entityActor.playAnimation(animationSprintStart); + entityActor.incrementAnimationTime(0.01); + } + } else { + if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationStartUp)){ + entityActor.playAnimation(animationStartUp); + entityActor.incrementAnimationTime(0.01); + } } } //check if can transition state @@ -242,11 +254,21 @@ public class GroundMovementTree { //check if can restart animation //if yes, restart animation if(entityActor != null){ - if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationMain)){ - entityActor.playAnimation(animationMain); - entityActor.incrementAnimationTime(0.01); + if(sprintTree != null && sprintTree.state == SprintTreeState.SPRINTING){ + if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationSprint)){ + entityActor.playAnimation(animationSprint); + entityActor.incrementAnimationTime(0.01); + } + } else { + if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationMain)){ + entityActor.playAnimation(animationMain); + entityActor.incrementAnimationTime(0.01); + } } } + if(velocity != maxNaturalVelocity){ + velocity = maxNaturalVelocity; + } // body.applyCentralForce(PhysicsUtils.jomlToVecmathVector3f(force)); EntityUtils.getRotation(parent).set(movementQuaternion); //check if can move forward (collision engine) @@ -314,9 +336,16 @@ public class GroundMovementTree { velocity = velocity - acceleration * Main.deltaTime; CreatureUtils.setVelocity(parent, velocity); if(entityActor != null){ - if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationSlowDown)){ - entityActor.playAnimation(animationSlowDown); - entityActor.incrementAnimationTime(0.01); + if(sprintTree != null && sprintTree.state == SprintTreeState.SPRINTING){ + if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationSprintWindDown)){ + entityActor.playAnimation(animationSprintWindDown); + entityActor.incrementAnimationTime(0.01); + } + } else { + if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(animationSlowDown)){ + entityActor.playAnimation(animationSlowDown); + entityActor.incrementAnimationTime(0.01); + } } } //check if can transition state @@ -426,4 +455,20 @@ public class GroundMovementTree { this.animationSlowDown = animationSlowDown; } + public void setAnimationSprintStartUp(String animationSprintStartUp){ + this.animationSprintStart = animationSprintStartUp; + } + + public void setAnimationSprint(String animationSprint){ + this.animationSprint = animationSprint; + } + + public void setAnimationSprintWindDown(String animationSprintWindDown){ + this.animationSprintWindDown = animationSprintWindDown; + } + + public void setSprintTree(SprintTree sprintTree){ + this.sprintTree = sprintTree; + } + } diff --git a/src/main/java/electrosphere/entity/state/movement/SprintTree.java b/src/main/java/electrosphere/entity/state/movement/SprintTree.java new file mode 100644 index 00000000..8e908a57 --- /dev/null +++ b/src/main/java/electrosphere/entity/state/movement/SprintTree.java @@ -0,0 +1,73 @@ +package electrosphere.entity.state.movement; + +import electrosphere.entity.Entity; +import electrosphere.entity.state.movement.GroundMovementTree.MovementTreeState; + +/** + * + * @author amaterasu + */ +public class SprintTree { + + public static enum SprintTreeState { + SPRINTING, + NOT_SPRINTING, + } + + SprintTreeState state; + + GroundMovementTree groundMovementTree; + + Entity parent; + + int staminaCurrent = 0; + int staminaMax = 1; + + float maxVelocity; + + public SprintTree(Entity e, float maxVelocity, int staminaMax){ + state = SprintTreeState.NOT_SPRINTING; + parent = e; + this.maxVelocity = maxVelocity; + this.staminaMax = staminaMax; + } + + public SprintTreeState getState(){ + return state; + } + + public void start(){ + if(staminaCurrent > 0){ + System.out.println("Starting sprinting"); + state = SprintTreeState.SPRINTING; + } + } + + public void stop(){ + state = SprintTreeState.NOT_SPRINTING; + } + + public void simulate(){ + switch(state){ + case SPRINTING: + if(groundMovementTree != null && groundMovementTree.getState() != MovementTreeState.IDLE){ + staminaCurrent--; + if(staminaCurrent < 1){ + state = SprintTreeState.NOT_SPRINTING; + } + } + break; + case NOT_SPRINTING: + staminaCurrent++; + if(staminaCurrent > staminaMax){ + staminaCurrent = staminaMax; + } + break; + } + } + + public void setGroundMovementTree(GroundMovementTree groundMovementTree){ + this.groundMovementTree = groundMovementTree; + } + +} diff --git a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java index 6db8b4dc..11d976fc 100644 --- a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java +++ b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java @@ -16,10 +16,12 @@ import electrosphere.entity.state.IdleTree; import electrosphere.entity.state.collidable.CollidableTree; import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.state.life.LifeState; +import electrosphere.entity.state.movement.SprintTree; import electrosphere.game.collision.PhysicsUtils; import electrosphere.game.collision.collidable.Collidable; import electrosphere.game.data.creature.type.AttackMove; import electrosphere.game.data.creature.type.CollidableTemplate; +import electrosphere.game.data.creature.type.SprintSystem; import electrosphere.logger.LoggerInterface; import electrosphere.main.Globals; import electrosphere.main.Main; @@ -104,6 +106,23 @@ public class CreatureUtils { if(movementSystem.getAnimationWindDown()!= null){ moveTree.setAnimationSlowDown(movementSystem.getAnimationWindDown().getName()); } + if(movementSystem.getSprintSystem() != null){ + SprintSystem sprintSystem = movementSystem.getSprintSystem(); + SprintTree sprintTree = new SprintTree(rVal,sprintSystem.getMaxVelocity(),sprintSystem.getStaminaMax()); + if(sprintSystem.getAnimationStartUp()!= null){ + moveTree.setAnimationSprintStartUp(sprintSystem.getAnimationStartUp().getName()); + } + if(sprintSystem.getAnimationMain()!= null){ + moveTree.setAnimationSprint(sprintSystem.getAnimationMain().getName()); + } + if(sprintSystem.getAnimationWindDown()!= null){ + moveTree.setAnimationSprintWindDown(sprintSystem.getAnimationWindDown().getName()); + } + sprintTree.setGroundMovementTree(moveTree); + moveTree.setSprintTree(sprintTree); + rVal.putData(EntityDataStrings.SPRINT_TREE,sprintTree); + Globals.entityManager.registerSprintableEntity(rVal); + } rVal.putData(EntityDataStrings.DATA_STRING_MOVEMENT_BT, moveTree); rVal.putData(EntityDataStrings.DATA_STRING_MOVEMENT_VECTOR, new Vector3f(0,0,0)); rVal.putData(EntityDataStrings.DATA_STRING_MAX_NATURAL_VELOCITY, movementSystem.getMaxVelocity()); @@ -249,7 +268,9 @@ public class CreatureUtils { return (IdleTree)e.getData(EntityDataStrings.IDLE_TREE); } - + public static SprintTree getSprintTree(Entity e){ + return (SprintTree)e.getData(EntityDataStrings.SPRINT_TREE); + } } diff --git a/src/main/java/electrosphere/game/data/creature/type/MovementSystem.java b/src/main/java/electrosphere/game/data/creature/type/MovementSystem.java index baa601c6..fa33f606 100644 --- a/src/main/java/electrosphere/game/data/creature/type/MovementSystem.java +++ b/src/main/java/electrosphere/game/data/creature/type/MovementSystem.java @@ -7,6 +7,7 @@ public class MovementSystem { Animation animationStartup; Animation animationLoop; Animation animationWindDown; + SprintSystem sprintSystem; public String getType() { return type; @@ -31,6 +32,10 @@ public class MovementSystem { public Animation getAnimationWindDown() { return animationWindDown; } + + public SprintSystem getSprintSystem() { + return sprintSystem; + } } diff --git a/src/main/java/electrosphere/game/data/creature/type/SprintSystem.java b/src/main/java/electrosphere/game/data/creature/type/SprintSystem.java new file mode 100644 index 00000000..b276b5cc --- /dev/null +++ b/src/main/java/electrosphere/game/data/creature/type/SprintSystem.java @@ -0,0 +1,35 @@ +package electrosphere.game.data.creature.type; + +/** + * + * @author amaterasu + */ +public class SprintSystem { + Animation animationStartUp; + Animation animationMain; + Animation animationWindDown; + float maxVelocity; + int staminaMax; + + public Animation getAnimationStartUp() { + return animationStartUp; + } + + public Animation getAnimationMain() { + return animationMain; + } + + public Animation getAnimationWindDown() { + return animationWindDown; + } + + public float getMaxVelocity() { + return maxVelocity; + } + + public int getStaminaMax() { + return staminaMax; + } + + +} diff --git a/src/main/java/electrosphere/game/simulation/MicroSimulation.java b/src/main/java/electrosphere/game/simulation/MicroSimulation.java index decec7a1..3f032562 100644 --- a/src/main/java/electrosphere/game/simulation/MicroSimulation.java +++ b/src/main/java/electrosphere/game/simulation/MicroSimulation.java @@ -15,6 +15,7 @@ import electrosphere.entity.types.hitbox.HitboxUtils; import electrosphere.entity.types.item.ItemUtils; import electrosphere.entity.state.life.LifeState; import electrosphere.entity.state.life.LifeUtils; +import electrosphere.entity.state.movement.SprintTree; import electrosphere.entity.types.particle.ParticleUtils; import electrosphere.game.client.targeting.crosshair.Crosshair; import electrosphere.main.Globals; @@ -61,6 +62,11 @@ public class MicroSimulation { GroundMovementTree behaviorTree = CreatureUtils.getEntityMovementTree(currentMoveable); behaviorTree.simulate(); } + //sprint tree + for(Entity currentSprint : Globals.entityManager.getSprintables()){ + SprintTree sprintTree = CreatureUtils.getSprintTree(currentSprint); + sprintTree.simulate(); + } //simulate creature gravity trees for(Entity currentGravity : Globals.entityManager.getGravityEntities()){ GravityTree gravityTree = (GravityTree)currentGravity.getData(EntityDataStrings.GRAVITY_TREE); diff --git a/src/main/java/electrosphere/renderer/anim/Animation.java b/src/main/java/electrosphere/renderer/anim/Animation.java index 1a605c2c..35f6acf7 100644 --- a/src/main/java/electrosphere/renderer/anim/Animation.java +++ b/src/main/java/electrosphere/renderer/anim/Animation.java @@ -24,6 +24,9 @@ public class Animation { public static final String ANIMATION_MOVEMENT_MOVE = "Armature|Walk"; public static final String ANIMATION_IDLE_1 = "Armature|Idle1"; public static final String ANIMATION_SWING_PRIMARY = "Armature|SwingWeapon"; + public static final String ANIMATION_SPRINT_STARTUP = "Armature|RunStart"; + public static final String ANIMATION_SPRINT = "Armature|Run"; + public static final String ANIMATION_SPRINT_WINDDOWN = "Armature|RunStart";