diff --git a/src/main/java/electrosphere/entity/state/lod/ClientLODComponent.java b/src/main/java/electrosphere/entity/state/lod/ClientLODComponent.java index 93cf2d00..babb48f1 100644 --- a/src/main/java/electrosphere/entity/state/lod/ClientLODComponent.java +++ b/src/main/java/electrosphere/entity/state/lod/ClientLODComponent.java @@ -45,8 +45,15 @@ public class ClientLODComponent implements BehaviorTree { if( commonData.getCollidable() != null && PhysicsEntityUtils.getCollidable(this.parent) == null && - Globals.clientState.playerEntity != null && - EntityUtils.getPosition(Globals.clientState.playerEntity).distance(EntityUtils.getPosition(this.parent)) < ServerLODComponent.LOD_RADIUS + ( + //IE actually running real game client + ( + Globals.clientState.playerEntity != null && + EntityUtils.getPosition(Globals.clientState.playerEntity).distance(EntityUtils.getPosition(this.parent)) < ServerLODComponent.LOD_RADIUS + ) || + //IE in viewport + Globals.clientState.playerEntity == null + ) ){ CollidableTemplate physicsTemplate = commonData.getCollidable(); PhysicsEntityUtils.clientAttachCollidableTemplate(this.parent, physicsTemplate); diff --git a/src/main/java/electrosphere/entity/state/movement/fall/ClientFallTree.java b/src/main/java/electrosphere/entity/state/movement/fall/ClientFallTree.java index 8f0bc2ce..8bb2bc00 100644 --- a/src/main/java/electrosphere/entity/state/movement/fall/ClientFallTree.java +++ b/src/main/java/electrosphere/entity/state/movement/fall/ClientFallTree.java @@ -29,19 +29,29 @@ public class ClientFallTree implements BehaviorTree { INACTIVE, } - //the raw data from disk + /** + * the raw data from disk + */ FallMovementSystem fallMovementSystem; - //current state + /** + * current state + */ FallState state = FallState.INACTIVE; - //the entity this is attached to + /** + * the entity this is attached to + */ Entity parent; - //the related jump tree + /** + * the related jump tree + */ ClientJumpTree jumpTree; - //The state transition util + /** + * The state transition util + */ StateTransitionUtil stateTransitionUtil; /** @@ -81,7 +91,6 @@ public class ClientFallTree implements BehaviorTree { case INACTIVE: { if(this.shouldStart()){ this.start(); - this.frameCurrent = 0; } frameCurrent++; } break; diff --git a/src/main/java/electrosphere/entity/state/movement/fall/ServerFallTree.java b/src/main/java/electrosphere/entity/state/movement/fall/ServerFallTree.java index 4dbda3ff..8f11a3af 100644 --- a/src/main/java/electrosphere/entity/state/movement/fall/ServerFallTree.java +++ b/src/main/java/electrosphere/entity/state/movement/fall/ServerFallTree.java @@ -39,7 +39,7 @@ public class ServerFallTree implements BehaviorTree { /** * The minimum frames to wait before scanning if it should activate due to gravity */ - public static final int MIN_FRAMES_BEFORE_ACTIVATION_SCAN = 60; + public static final int MIN_FRAMES_BEFORE_ACTIVATION_SCAN = 45; /** * The minimum frames to wait before playing landing animation on fall diff --git a/src/main/java/electrosphere/entity/state/movement/jump/ClientJumpTree.java b/src/main/java/electrosphere/entity/state/movement/jump/ClientJumpTree.java index 83a78440..5f682f5d 100644 --- a/src/main/java/electrosphere/entity/state/movement/jump/ClientJumpTree.java +++ b/src/main/java/electrosphere/entity/state/movement/jump/ClientJumpTree.java @@ -93,27 +93,27 @@ public class ClientJumpTree implements BehaviorTree { public void simulate(float deltaTime) { Actor entityActor = EntityUtils.getActor(parent); switch(state){ - case ACTIVE: - if(entityActor != null){ - if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(jumpData.getAnimationJump().getNameThirdPerson())){ - entityActor.playAnimation(jumpData.getAnimationJump().getNameThirdPerson(),AnimationPriorities.getValue(AnimationPriorities.MOVEMENT_MODIFIER)); - entityActor.incrementAnimationTime(0.0001); + case ACTIVE: { + if(entityActor != null){ + if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(jumpData.getAnimationJump().getNameThirdPerson())){ + entityActor.playAnimation(jumpData.getAnimationJump().getNameThirdPerson(),AnimationPriorities.getValue(AnimationPriorities.MOVEMENT_MODIFIER)); + entityActor.incrementAnimationTime(0.0001); + } + FirstPersonTree.conditionallyPlayAnimation(parent, jumpData.getAnimationJump()); } - FirstPersonTree.conditionallyPlayAnimation(parent, jumpData.getAnimationJump()); - } - //stop body falling if it is - DBody body = PhysicsEntityUtils.getDBody(parent); - if(body != null){ - DVector3C linearVelocity = body.getLinearVel(); - body.setLinearVel(linearVelocity.get0(), 0, linearVelocity.get2()); - //push parent up - body.addForce(0, currentJumpForce, 0); - body.enable(); - } - if(currentFrame >= jumpFrames){ - GravityUtils.clientAttemptActivateGravity(parent); - } - break; + //stop body falling if it is + DBody body = PhysicsEntityUtils.getDBody(parent); + if(body != null){ + DVector3C linearVelocity = body.getLinearVel(); + body.setLinearVel(linearVelocity.get0(), 0, linearVelocity.get2()); + //push parent up + body.addForce(0, currentJumpForce, 0); + body.enable(); + } + if(currentFrame >= jumpFrames){ + GravityUtils.clientAttemptActivateGravity(parent); + } + } break; case INACTIVE: break; case AWAITING_LAND: diff --git a/src/test/java/electrosphere/entity/state/gravity/ServerGravityTreeTests.java b/src/test/java/electrosphere/entity/state/gravity/ServerGravityTreeTests.java new file mode 100644 index 00000000..ccb5416c --- /dev/null +++ b/src/test/java/electrosphere/entity/state/gravity/ServerGravityTreeTests.java @@ -0,0 +1,81 @@ +package electrosphere.entity.state.gravity; + +import static electrosphere.test.testutils.Assertions.assertEventually; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.joml.Vector3d; + +import electrosphere.engine.Globals; +import electrosphere.entity.Entity; +import electrosphere.entity.state.movement.jump.ServerJumpTree; +import electrosphere.entity.types.EntityTypes.EntityType; +import electrosphere.entity.types.creature.CreatureUtils; +import electrosphere.entity.types.creature.ObjectTemplate; +import electrosphere.test.annotations.IntegrationTest; +import electrosphere.test.template.EntityTestTemplate; +import electrosphere.test.testutils.TestEngineUtils; + +/** + * Tests server gravity tree + */ +public class ServerGravityTreeTests extends EntityTestTemplate { + + @IntegrationTest + public void isActive_OnSpawn_false(){ + Entity serverEntity = CreatureUtils.serverSpawnBasicCreature(Globals.serverState.realmManager.first(), new Vector3d(), "human", ObjectTemplate.createDefault(EntityType.CREATURE, "human")); + + ServerGravityTree serverGravityTree = ServerGravityTree.getServerGravityTree(serverEntity); + assertTrue(serverGravityTree.isActive()); + } + + @IntegrationTest + public void isActive_AfterOneFrame_false(){ + Entity serverEntity = CreatureUtils.serverSpawnBasicCreature(Globals.serverState.realmManager.first(), new Vector3d(), "human", ObjectTemplate.createDefault(EntityType.CREATURE, "human")); + + //settle engine + TestEngineUtils.simulateFrames(1); + + ServerGravityTree serverGravityTree = ServerGravityTree.getServerGravityTree(serverEntity); + assertFalse(serverGravityTree.isActive()); + } + + @IntegrationTest + public void activates_on_jump(){ + Entity serverEntity = CreatureUtils.serverSpawnBasicCreature(Globals.serverState.realmManager.first(), new Vector3d(), "human", ObjectTemplate.createDefault(EntityType.CREATURE, "human")); + + //settle engine + TestEngineUtils.simulateFrames(1); + + ServerJumpTree serverJumpTree = ServerJumpTree.getServerJumpTree(serverEntity); + serverJumpTree.start(); + + ServerGravityTree serverGravityTree = ServerGravityTree.getServerGravityTree(serverEntity); + + assertEventually(() -> serverGravityTree.isActive()); + } + + @IntegrationTest + public void deactivates_on_collide_world_bound(){ + Entity serverEntity = CreatureUtils.serverSpawnBasicCreature(Globals.serverState.realmManager.first(), new Vector3d(), "human", ObjectTemplate.createDefault(EntityType.CREATURE, "human")); + + ServerGravityTree serverGravityTree = ServerGravityTree.getServerGravityTree(serverEntity); + + //wait for gravity to settle + assertTrue(serverGravityTree.isActive()); + TestEngineUtils.simulateFrames(1); + assertEventually(() -> !serverGravityTree.isActive()); + + //jump + ServerJumpTree serverJumpTree = ServerJumpTree.getServerJumpTree(serverEntity); + serverJumpTree.start(); + + //wait for jump to activate it + assertEventually(() -> serverGravityTree.isActive()); + + + //wait for it to settle after jump finishes + assertEventually(() -> !serverGravityTree.isActive()); + } + +} diff --git a/src/test/java/electrosphere/entity/state/movement/jump/ClientJumpTreeTests.java b/src/test/java/electrosphere/entity/state/movement/jump/ClientJumpTreeTests.java index a57f4c9e..11c6231d 100644 --- a/src/test/java/electrosphere/entity/state/movement/jump/ClientJumpTreeTests.java +++ b/src/test/java/electrosphere/entity/state/movement/jump/ClientJumpTreeTests.java @@ -5,6 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import org.joml.Vector3d; +import electrosphere.collision.PhysicsEntityUtils; import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.EntityUtils; @@ -63,5 +64,16 @@ public class ClientJumpTreeTests extends EntityTestTemplate { assertEventually(() -> EntityUtils.getPosition(clientEntity).y > 0.3); } + + @IntegrationTest + public void jumpEnablesBody_true(){ + Entity serverEntity = CreatureUtils.serverSpawnBasicCreature(Globals.serverState.realmManager.first(), new Vector3d(), "human", ObjectTemplate.createDefault(EntityType.CREATURE, "human")); + Entity clientEntity = TestEngineUtils.getClientEquivalent(serverEntity); + + ClientJumpTree clientJumpTree = ClientJumpTree.getClientJumpTree(clientEntity); + clientJumpTree.start(); + + assertEventually(() -> PhysicsEntityUtils.getDBody(clientEntity).isEnabled()); + } } diff --git a/src/test/java/electrosphere/entity/types/creature/CreatureUtilsTests.java b/src/test/java/electrosphere/entity/types/creature/CreatureUtilsTests.java new file mode 100644 index 00000000..1b9778d9 --- /dev/null +++ b/src/test/java/electrosphere/entity/types/creature/CreatureUtilsTests.java @@ -0,0 +1,27 @@ +package electrosphere.entity.types.creature; + +import static electrosphere.test.testutils.Assertions.assertEventually; + +import org.joml.Vector3d; + +import electrosphere.collision.PhysicsEntityUtils; +import electrosphere.engine.Globals; +import electrosphere.entity.Entity; +import electrosphere.entity.types.EntityTypes.EntityType; +import electrosphere.test.annotations.IntegrationTest; +import electrosphere.test.template.EntityTestTemplate; +import electrosphere.test.testutils.TestEngineUtils; + +/** + * Tests creature utils + */ +public class CreatureUtilsTests extends EntityTestTemplate { + + @IntegrationTest + public void isActive_OnSpawn_false(){ + Entity serverEntity = CreatureUtils.serverSpawnBasicCreature(Globals.serverState.realmManager.first(), new Vector3d(), "human", ObjectTemplate.createDefault(EntityType.CREATURE, "human")); + Entity clientEntity = TestEngineUtils.getClientEquivalent(serverEntity); + assertEventually(() -> PhysicsEntityUtils.containsDBody(clientEntity)); + } + +}