work on moving hitboxes to ode4j handling
This commit is contained in:
parent
b1d79dbc16
commit
a30ac75573
@ -18,7 +18,8 @@
|
|||||||
"renderResolutionX": 1920,
|
"renderResolutionX": 1920,
|
||||||
"renderResolutionY": 1080,
|
"renderResolutionY": 1080,
|
||||||
|
|
||||||
"graphicsDebugDrawCollisionSpheres" : false,
|
"graphicsDebugDrawCollisionSpheresClient" : false,
|
||||||
|
"graphicsDebugDrawCollisionSpheresServer" : false,
|
||||||
"graphicsDebugDrawPhysicsObjects" : false,
|
"graphicsDebugDrawPhysicsObjects" : false,
|
||||||
"graphicsDebugDrawMovementVectors" : false,
|
"graphicsDebugDrawMovementVectors" : false,
|
||||||
"graphicsDebugDrawNavmesh" : false,
|
"graphicsDebugDrawNavmesh" : false,
|
||||||
|
|||||||
@ -5,32 +5,37 @@
|
|||||||
"hitboxes" : [
|
"hitboxes" : [
|
||||||
{
|
{
|
||||||
"type": "hurt",
|
"type": "hurt",
|
||||||
"bone": "Bone.031",
|
"bone": "Bicep.L",
|
||||||
"radius": 0.04
|
"radius": 0.04
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "hurt",
|
"type": "hurt",
|
||||||
"bone": "Bone.012",
|
"bone": "Bicep.R",
|
||||||
"radius": 0.04
|
"radius": 0.04
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "hurt",
|
"type": "hurt",
|
||||||
"bone": "Bone.003",
|
"bone": "Leg.L",
|
||||||
"radius": 0.04
|
"radius": 0.04
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "hurt",
|
"type": "hurt",
|
||||||
"bone": "Bone.010",
|
"bone": "Leg.R",
|
||||||
|
"radius": 0.04
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "hurt",
|
||||||
|
"bone": "Shoulder.L",
|
||||||
"radius": 0.06
|
"radius": 0.06
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "hurt",
|
"type": "hurt",
|
||||||
"bone": "Bone.001",
|
"bone": "Shoulder.R",
|
||||||
"radius": 0.06
|
"radius": 0.06
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "hurt",
|
"type": "hurt",
|
||||||
"bone": "Bone.014",
|
"bone": "Neck",
|
||||||
"radius": 0.06
|
"radius": 0.06
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -40,13 +45,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "hurt",
|
"type": "hurt",
|
||||||
"bone": "Bone.014",
|
"bone": "Head",
|
||||||
"radius": 0.06
|
"radius": 0.06
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "hurt",
|
|
||||||
"bone": "Bone.019",
|
|
||||||
"radius": 0.04
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"tokens" : [
|
"tokens" : [
|
||||||
|
|||||||
BIN
assets/Models/basic/geometry/unitsphere.glb
Normal file
BIN
assets/Models/basic/geometry/unitsphere.glb
Normal file
Binary file not shown.
@ -1,3 +1,3 @@
|
|||||||
#maven.buildNumber.plugin properties file
|
#maven.buildNumber.plugin properties file
|
||||||
#Sun May 19 19:34:37 EDT 2024
|
#Sat Jun 01 15:22:11 EDT 2024
|
||||||
buildNumber=132
|
buildNumber=134
|
||||||
|
|||||||
@ -310,14 +310,34 @@ Attaching items to hands in first person
|
|||||||
|
|
||||||
Fix grass placement
|
Fix grass placement
|
||||||
|
|
||||||
(05/25/2024)
|
(05/26/2024)
|
||||||
|
|
||||||
VERY rudimentary first person documentation to give basic navigation to relevant files.
|
VERY rudimentary first person documentation to give basic navigation to relevant files.
|
||||||
|
|
||||||
|
Fix attacking looping and freezing the character in place
|
||||||
|
- Was using delta real time (0.02ms) instead of delta frames in server and client attack trees (1 frame/simulate() call)
|
||||||
|
|
||||||
|
Document hitboxes
|
||||||
|
- Documented how it works currently and the architecture we want to move towards
|
||||||
|
|
||||||
|
Redo hitboxes to have capsules and also chaining between frames (but not between swinging the camera around)
|
||||||
|
- Need to have an object attached to creature that stores the rigid body
|
||||||
|
- When creating the creature, for each hitbox, create shapes for the rigid body
|
||||||
|
- Attach the overall object to the creature entity
|
||||||
|
|
||||||
|
(05/27/2024)
|
||||||
|
|
||||||
|
Redo hitboxes to have capsules and also chaining between frames (but not between swinging the camera around)
|
||||||
|
- Synchronize hitbox positions each frame
|
||||||
|
|
||||||
|
(05/31/2024)
|
||||||
|
Redo hitboxes to have capsules and also chaining between frames (but not between swinging the camera around)
|
||||||
|
- Write custom callback for the collision engine for just hitboxes
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
Redo hitboxes to have capsules and also chaining between frames (but not between swinging the camera around)
|
Redo hitboxes to have capsules and also chaining between frames (but not between swinging the camera around)
|
||||||
|
- Introduce block hitbox (blockbox) type
|
||||||
|
|
||||||
Fix being able to walk off far side of the world (ie in level editor)
|
Fix being able to walk off far side of the world (ie in level editor)
|
||||||
|
|
||||||
@ -349,6 +369,8 @@ More Debug menus
|
|||||||
- Screen that shows the overall status of fluid cell manager
|
- Screen that shows the overall status of fluid cell manager
|
||||||
- Screen that shows the overall status of realm 0
|
- Screen that shows the overall status of realm 0
|
||||||
- Screen that shows the overall status of realm manager
|
- Screen that shows the overall status of realm manager
|
||||||
|
- Particularly, want a view of all entities in the scene, and the ability to click on a single entity to get an overview of everything on the entity
|
||||||
|
- For each behavior tree, ability to click into the tree and view fine details about its state (both pure state variable as well as other relevant variables)
|
||||||
|
|
||||||
Revisit first attempt at instancing (its really laggy lol)
|
Revisit first attempt at instancing (its really laggy lol)
|
||||||
- Maybe have draw call happen on top level entity and immediately queue all children recursively
|
- Maybe have draw call happen on top level entity and immediately queue all children recursively
|
||||||
|
|||||||
@ -310,6 +310,17 @@
|
|||||||
"positionY",
|
"positionY",
|
||||||
"positionZ"
|
"positionZ"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"messageName" : "updateEntityViewDir",
|
||||||
|
"data" : [
|
||||||
|
"entityID",
|
||||||
|
"time",
|
||||||
|
"positionX",
|
||||||
|
"positionY",
|
||||||
|
"positionZ",
|
||||||
|
"propertyValueInt"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,19 +1,20 @@
|
|||||||
package electrosphere.client.scene;
|
package electrosphere.client.scene;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
|
import org.ode4j.ode.DContactGeom;
|
||||||
|
|
||||||
import electrosphere.collision.CollisionEngine;
|
import electrosphere.collision.CollisionEngine;
|
||||||
|
import electrosphere.collision.CollisionEngine.CollisionResolutionCallback;
|
||||||
|
import electrosphere.collision.collidable.Collidable;
|
||||||
|
import electrosphere.collision.hitbox.HitboxManager;
|
||||||
|
import electrosphere.collision.hitbox.HitboxUtils;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.ClientEntityUtils;
|
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityUtils;
|
|
||||||
import electrosphere.entity.Scene;
|
import electrosphere.entity.Scene;
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper around the scene object to provide lots of much needed client-specific utility
|
* Wrapper around the scene object to provide lots of much needed client-specific utility
|
||||||
@ -31,9 +32,18 @@ public class ClientSceneWrapper {
|
|||||||
//The engine used to back physics collision checks in client
|
//The engine used to back physics collision checks in client
|
||||||
CollisionEngine collisionEngine;
|
CollisionEngine collisionEngine;
|
||||||
|
|
||||||
|
//The hitbox manager
|
||||||
|
HitboxManager hitboxManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param scene The scene
|
||||||
|
* @param collisionEngine The collision engine
|
||||||
|
*/
|
||||||
public ClientSceneWrapper(Scene scene, CollisionEngine collisionEngine){
|
public ClientSceneWrapper(Scene scene, CollisionEngine collisionEngine){
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
this.collisionEngine = collisionEngine;
|
this.collisionEngine = collisionEngine;
|
||||||
|
this.hitboxManager = new HitboxManager(resolutionCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -110,6 +120,14 @@ public class ClientSceneWrapper {
|
|||||||
return collisionEngine;
|
return collisionEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hitbox manager for the client
|
||||||
|
* @return The hitbox manager
|
||||||
|
*/
|
||||||
|
public HitboxManager getHitboxManager(){
|
||||||
|
return hitboxManager;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys all entities outside simulation range
|
* Destroys all entities outside simulation range
|
||||||
*/
|
*/
|
||||||
@ -129,4 +147,15 @@ public class ClientSceneWrapper {
|
|||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The resolution callback that is invoked once a collision has occurred
|
||||||
|
*/
|
||||||
|
CollisionResolutionCallback resolutionCallback = new CollisionResolutionCallback() {
|
||||||
|
@Override
|
||||||
|
public void resolve(DContactGeom geom, Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude) {
|
||||||
|
HitboxUtils.clientDamageHitboxColision(impactor.getParent(), receiver.getParent());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,11 +6,7 @@ import electrosphere.client.fluid.manager.ClientFluidManager;
|
|||||||
import electrosphere.client.instancing.InstanceUpdater;
|
import electrosphere.client.instancing.InstanceUpdater;
|
||||||
import electrosphere.client.targeting.crosshair.Crosshair;
|
import electrosphere.client.targeting.crosshair.Crosshair;
|
||||||
import electrosphere.client.terrain.manager.ClientTerrainManager;
|
import electrosphere.client.terrain.manager.ClientTerrainManager;
|
||||||
import electrosphere.collision.PhysicsEntityUtils;
|
|
||||||
import electrosphere.collision.PhysicsUtils;
|
|
||||||
import electrosphere.collision.hitbox.HitboxUtils;
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.engine.Main;
|
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityTags;
|
import electrosphere.entity.EntityTags;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
@ -44,6 +40,7 @@ public class ClientSimulation {
|
|||||||
public void simulate(){
|
public void simulate(){
|
||||||
Globals.profiler.beginCpuSample("simulate");
|
Globals.profiler.beginCpuSample("simulate");
|
||||||
|
|
||||||
|
//
|
||||||
//load terrain
|
//load terrain
|
||||||
if(isLoadingTerrain()){
|
if(isLoadingTerrain()){
|
||||||
loadTerrain();
|
loadTerrain();
|
||||||
@ -53,10 +50,11 @@ public class ClientSimulation {
|
|||||||
Globals.profiler.beginCpuSample("clientSynchronizationManager.processMessages");
|
Globals.profiler.beginCpuSample("clientSynchronizationManager.processMessages");
|
||||||
Globals.clientSynchronizationManager.processMessages();
|
Globals.clientSynchronizationManager.processMessages();
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
|
//
|
||||||
//simulate bullet physics engine step
|
//simulate bullet physics engine step
|
||||||
Globals.clientSceneWrapper.getCollisionEngine().simulatePhysics((float)Globals.timekeeper.getSimFrameTime());
|
Globals.clientSceneWrapper.getCollisionEngine().simulatePhysics((float)Globals.timekeeper.getSimFrameTime());
|
||||||
Globals.clientSceneWrapper.getCollisionEngine().updateDynamicObjectTransforms();
|
Globals.clientSceneWrapper.getCollisionEngine().updateDynamicObjectTransforms();
|
||||||
|
//
|
||||||
//update actor animations
|
//update actor animations
|
||||||
Globals.profiler.beginCpuSample("update actor animations");
|
Globals.profiler.beginCpuSample("update actor animations");
|
||||||
for(Entity currentEntity : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.DRAWABLE)){
|
for(Entity currentEntity : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.DRAWABLE)){
|
||||||
@ -66,12 +64,14 @@ public class ClientSimulation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
|
//
|
||||||
//make items play idle animation
|
//make items play idle animation
|
||||||
Globals.profiler.beginCpuSample("item animations");
|
Globals.profiler.beginCpuSample("item animations");
|
||||||
for(Entity item : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.ITEM)){
|
for(Entity item : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.ITEM)){
|
||||||
ItemUtils.updateItemActorAnimation(item);
|
ItemUtils.updateItemActorAnimation(item);
|
||||||
}
|
}
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
|
//
|
||||||
//particle state updates
|
//particle state updates
|
||||||
Globals.profiler.beginCpuSample("particle state updates");
|
Globals.profiler.beginCpuSample("particle state updates");
|
||||||
for(Entity particle : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.PARTICLE)){
|
for(Entity particle : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.PARTICLE)){
|
||||||
@ -80,18 +80,12 @@ public class ClientSimulation {
|
|||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
//update attached entity positions
|
//update attached entity positions
|
||||||
AttachUtils.clientUpdateAttachedEntityPositions();
|
AttachUtils.clientUpdateAttachedEntityPositions();
|
||||||
//update hitbox positions
|
//
|
||||||
Globals.profiler.beginCpuSample("Hitbox updates");
|
//Hitbox stuff
|
||||||
for(Entity currentHitbox : Globals.clientHitboxManager.getAllHitboxes()){
|
Globals.profiler.beginCpuSample("update hitboxes");
|
||||||
HitboxUtils.clientUpdatePosition(currentHitbox);
|
Globals.clientSceneWrapper.getHitboxManager().simulate();
|
||||||
}
|
|
||||||
//collide hitboxes
|
|
||||||
for(Entity currentHitbox : Globals.clientHitboxManager.getAllHitboxes()){
|
|
||||||
if(isReady){
|
|
||||||
HitboxUtils.clientCollideEntities(currentHitbox);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
|
//
|
||||||
//update audio engine
|
//update audio engine
|
||||||
Globals.profiler.beginCpuSample("audio engine update");
|
Globals.profiler.beginCpuSample("audio engine update");
|
||||||
if(Globals.audioEngine!=null){
|
if(Globals.audioEngine!=null){
|
||||||
@ -99,31 +93,32 @@ public class ClientSimulation {
|
|||||||
Globals.virtualAudioSourceManager.update((float)Globals.timekeeper.getSimFrameTime());
|
Globals.virtualAudioSourceManager.update((float)Globals.timekeeper.getSimFrameTime());
|
||||||
}
|
}
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
|
//
|
||||||
//update foliage
|
//update foliage
|
||||||
if(Globals.clientFoliageManager != null){
|
if(Globals.clientFoliageManager != null){
|
||||||
Globals.clientFoliageManager.update();
|
Globals.clientFoliageManager.update();
|
||||||
}
|
}
|
||||||
//tally collidables and offset position accordingly
|
//
|
||||||
// for(Entity currentCollidable : Globals.entityManager.getEntitiesWithTag(EntityTags.COLLIDABLE)){
|
|
||||||
// CollidableTree tree = CollidableTree.getCollidableTree(currentCollidable);
|
|
||||||
// tree.simulate(Main.deltaFrames);
|
|
||||||
// }
|
|
||||||
//targeting crosshair
|
//targeting crosshair
|
||||||
Globals.profiler.beginCpuSample("crosshair update");
|
Globals.profiler.beginCpuSample("crosshair update");
|
||||||
Crosshair.checkTargetable();
|
Crosshair.checkTargetable();
|
||||||
Crosshair.updateTargetCrosshairPosition();
|
Crosshair.updateTargetCrosshairPosition();
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
|
//
|
||||||
//simulate behavior trees
|
//simulate behavior trees
|
||||||
Globals.clientSceneWrapper.getScene().simulateBehaviorTrees((float)Globals.timekeeper.getSimFrameTime());
|
Globals.clientSceneWrapper.getScene().simulateBehaviorTrees((float)Globals.timekeeper.getSimFrameTime());
|
||||||
|
//
|
||||||
//sum collidable impulses
|
//sum collidable impulses
|
||||||
Globals.profiler.beginCpuSample("collidable logic");
|
Globals.profiler.beginCpuSample("collidable logic");
|
||||||
for(Entity collidable : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.COLLIDABLE)){
|
for(Entity collidable : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.COLLIDABLE)){
|
||||||
ClientCollidableTree.getClientCollidableTree(collidable).simulate((float)Globals.timekeeper.getSimFrameTime());
|
ClientCollidableTree.getClientCollidableTree(collidable).simulate((float)Globals.timekeeper.getSimFrameTime());
|
||||||
}
|
}
|
||||||
|
//
|
||||||
//clear collidable impulse lists
|
//clear collidable impulse lists
|
||||||
Globals.clientSceneWrapper.getCollisionEngine().clearCollidableImpulseLists();
|
Globals.clientSceneWrapper.getCollisionEngine().clearCollidableImpulseLists();
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
|
|
||||||
|
//
|
||||||
//wrap up functions
|
//wrap up functions
|
||||||
runClientFunctions();
|
runClientFunctions();
|
||||||
|
|
||||||
|
|||||||
@ -12,9 +12,9 @@ import org.ode4j.math.DMatrix3;
|
|||||||
import org.ode4j.ode.DBody;
|
import org.ode4j.ode.DBody;
|
||||||
import org.ode4j.ode.DBox;
|
import org.ode4j.ode.DBox;
|
||||||
import org.ode4j.ode.DCylinder;
|
import org.ode4j.ode.DCylinder;
|
||||||
|
import org.ode4j.ode.DGeom;
|
||||||
import org.ode4j.ode.DSphere;
|
import org.ode4j.ode.DSphere;
|
||||||
import org.ode4j.ode.DTriMesh;
|
import org.ode4j.ode.DTriMesh;
|
||||||
import org.ode4j.ode.OdeHelper;
|
|
||||||
|
|
||||||
import electrosphere.entity.types.terrain.TerrainChunkData;
|
import electrosphere.entity.types.terrain.TerrainChunkData;
|
||||||
|
|
||||||
@ -81,6 +81,26 @@ public class CollisionBodyCreation {
|
|||||||
return collisionEngine.createDBody(geom);
|
return collisionEngine.createDBody(geom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a dbody with existing shapes that are provided
|
||||||
|
* @param collisionEngine the collision engine to create it in
|
||||||
|
* @param geoms the geometries to attach
|
||||||
|
* @return the dbody
|
||||||
|
*/
|
||||||
|
public static DBody createBodyWithShapes(CollisionEngine collisionEngine, DGeom ... geoms){
|
||||||
|
return collisionEngine.createDBody(geoms);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a sphere shape
|
||||||
|
* @param collisionEngine the collision engine
|
||||||
|
* @param radius the radius of the sphere
|
||||||
|
* @return the sphere shape
|
||||||
|
*/
|
||||||
|
public static DSphere createShapeSphere(CollisionEngine collisionEngine, double radius, long categoryBits){
|
||||||
|
return collisionEngine.createSphereGeom(radius, categoryBits);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the provided body to be a kinematic body (no gravity applied)
|
* Sets the provided body to be a kinematic body (no gravity applied)
|
||||||
* @param collisionEngine The collision engine
|
* @param collisionEngine The collision engine
|
||||||
@ -154,7 +174,7 @@ public class CollisionBodyCreation {
|
|||||||
*/
|
*/
|
||||||
public static DBody generateRigidBodyFromAIScene(CollisionEngine collisionEngine, AIScene scene, long categoryBits){
|
public static DBody generateRigidBodyFromAIScene(CollisionEngine collisionEngine, AIScene scene, long categoryBits){
|
||||||
|
|
||||||
DBody body = collisionEngine.createDBody(null);
|
DBody body = collisionEngine.createDBody((DGeom[])null);
|
||||||
|
|
||||||
PointerBuffer meshesBuffer = scene.mMeshes();
|
PointerBuffer meshesBuffer = scene.mMeshes();
|
||||||
while(meshesBuffer.hasRemaining()){
|
while(meshesBuffer.hasRemaining()){
|
||||||
|
|||||||
@ -31,6 +31,7 @@ import org.ode4j.ode.DBox;
|
|||||||
import org.ode4j.ode.DCapsule;
|
import org.ode4j.ode.DCapsule;
|
||||||
import org.ode4j.ode.DContact;
|
import org.ode4j.ode.DContact;
|
||||||
import org.ode4j.ode.DContactBuffer;
|
import org.ode4j.ode.DContactBuffer;
|
||||||
|
import org.ode4j.ode.DContactGeom;
|
||||||
import org.ode4j.ode.DContactJoint;
|
import org.ode4j.ode.DContactJoint;
|
||||||
import org.ode4j.ode.DCylinder;
|
import org.ode4j.ode.DCylinder;
|
||||||
import org.ode4j.ode.DGeom;
|
import org.ode4j.ode.DGeom;
|
||||||
@ -50,6 +51,7 @@ import org.ode4j.ode.OdeHelper;
|
|||||||
import electrosphere.collision.RayCastCallback.RayCastCallbackData;
|
import electrosphere.collision.RayCastCallback.RayCastCallbackData;
|
||||||
import electrosphere.collision.collidable.Collidable;
|
import electrosphere.collision.collidable.Collidable;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
|
import electrosphere.engine.time.Timekeeper;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
@ -63,9 +65,6 @@ import electrosphere.logger.LoggerInterface;
|
|||||||
*/
|
*/
|
||||||
public class CollisionEngine {
|
public class CollisionEngine {
|
||||||
|
|
||||||
//step interval time size
|
|
||||||
public static final float ENGINE_STEP_SIZE = 0.01f;
|
|
||||||
|
|
||||||
//gravity constant
|
//gravity constant
|
||||||
public static final float GRAVITY_MAGNITUDE = 9.8f * 2;
|
public static final float GRAVITY_MAGNITUDE = 9.8f * 2;
|
||||||
|
|
||||||
@ -91,16 +90,44 @@ public class CollisionEngine {
|
|||||||
|
|
||||||
//callbacks for collision check
|
//callbacks for collision check
|
||||||
RayCastCallback rayCastCallback = new RayCastCallback();
|
RayCastCallback rayCastCallback = new RayCastCallback();
|
||||||
|
|
||||||
|
//the collision resolution callback
|
||||||
|
CollisionResolutionCallback collisionResolutionCallback;
|
||||||
|
|
||||||
|
//buffer for collisions
|
||||||
|
DContactBuffer contacts = null;
|
||||||
|
|
||||||
|
// Callback for any near collisions in the broadphase of the collision check
|
||||||
|
private DNearCallback nearCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
public CollisionEngine(){
|
public CollisionEngine(){
|
||||||
world = OdeHelper.createWorld();
|
world = OdeHelper.createWorld();
|
||||||
space = OdeHelper.createBHVSpace(Collidable.TYPE_STATIC_BIT);
|
space = OdeHelper.createBHVSpace(Collidable.TYPE_STATIC_BIT);
|
||||||
world.setGravity(0,-GRAVITY_MAGNITUDE,0);
|
world.setGravity(0,-GRAVITY_MAGNITUDE,0);
|
||||||
contactgroup = OdeHelper.createJointGroup();
|
contactgroup = OdeHelper.createJointGroup();
|
||||||
|
this.nearCallback = new DNearCallback() {
|
||||||
|
@Override
|
||||||
|
public void call(Object data, DGeom o1, DGeom o2) {
|
||||||
|
nearCallback( data, o1, o2);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void resolveCollision(Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude){
|
/**
|
||||||
|
* Resolves collisions in the engine
|
||||||
|
* @param contactGeom the ode4j contact geometry
|
||||||
|
* @param impactor the instigator of the collision
|
||||||
|
* @param receiver the receiver of the collision
|
||||||
|
* @param normal the normal to the collision surface
|
||||||
|
* @param localPosition the local position of the collision
|
||||||
|
* @param worldPos the world position of the collision
|
||||||
|
* @param magnitude the magnitude of the collision
|
||||||
|
*/
|
||||||
|
public static void resolveCollision(DContactGeom contactGeom, Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude){
|
||||||
switch(receiver.getType()){
|
switch(receiver.getType()){
|
||||||
case Collidable.TYPE_CREATURE:
|
case Collidable.TYPE_CREATURE:
|
||||||
switch(impactor.getType()){
|
switch(impactor.getType()){
|
||||||
@ -223,7 +250,7 @@ public class CollisionEngine {
|
|||||||
|
|
||||||
//simulate physics
|
//simulate physics
|
||||||
Globals.profiler.beginCpuSample("step physics");
|
Globals.profiler.beginCpuSample("step physics");
|
||||||
world.quickStep(ENGINE_STEP_SIZE);
|
world.quickStep(Timekeeper.ENGINE_STEP_SIZE);
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
|
|
||||||
// remove all contact joints
|
// remove all contact joints
|
||||||
@ -233,27 +260,45 @@ public class CollisionEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for any near collisions in the broadphase of the collision check
|
* Runs a collision cycle on all bodies in the collision engine
|
||||||
*/
|
*/
|
||||||
private DNearCallback nearCallback = new DNearCallback() {
|
public void collide(){
|
||||||
@Override
|
Globals.profiler.beginCpuSample("physics");
|
||||||
public void call(Object data, DGeom o1, DGeom o2) {
|
spaceLock.acquireUninterruptibly();
|
||||||
nearCallback( data, o1, o2);
|
Globals.profiler.beginCpuSample("collide");
|
||||||
}
|
OdeHelper.spaceCollide(space, 0, nearCallback);
|
||||||
};
|
Globals.profiler.endCpuSample();
|
||||||
|
|
||||||
//buffer for collisions
|
// remove all contact joints
|
||||||
DContactBuffer contacts = null;
|
contactgroup.empty();
|
||||||
|
spaceLock.release();
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
|
}
|
||||||
|
|
||||||
// this is called by dSpaceCollide when two objects in space are
|
/**
|
||||||
// potentially colliding.
|
* Sets the near callback function for all collision calls.
|
||||||
|
* !!YOU LIKELY WANT TO INSTEAD OVERWRITE THE CollisionResolutionCallback!!
|
||||||
|
* @param callback the callback
|
||||||
|
*/
|
||||||
|
public void setNearCallback(DNearCallback callback){
|
||||||
|
this.nearCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is called by dSpaceCollide when two objects in space are potentially colliding.
|
||||||
|
* @param data The data
|
||||||
|
* @param o1 the first collision body
|
||||||
|
* @param o2 the second collision body
|
||||||
|
*/
|
||||||
private void nearCallback (Object data, DGeom o1, DGeom o2) {
|
private void nearCallback (Object data, DGeom o1, DGeom o2) {
|
||||||
// if (o1->body && o2->body) return;
|
// if (o1->body && o2->body) return;
|
||||||
|
|
||||||
// exit without doing anything if the two bodies are connected by a joint
|
// exit without doing anything if the two bodies are connected by a joint
|
||||||
DBody b1 = o1.getBody();
|
DBody b1 = o1.getBody();
|
||||||
DBody b2 = o2.getBody();
|
DBody b2 = o2.getBody();
|
||||||
if (b1!=null && b2!=null && areConnectedExcluding (b1,b2,DContactJoint.class)) return;
|
if (b1!=null && b2!=null && areConnectedExcluding (b1,b2,DContactJoint.class)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//creates a buffer to store potential collisions
|
//creates a buffer to store potential collisions
|
||||||
DContactBuffer contacts = new DContactBuffer(MAX_CONTACTS); // up to MAX_CONTACTS contacts per box-box
|
DContactBuffer contacts = new DContactBuffer(MAX_CONTACTS); // up to MAX_CONTACTS contacts per box-box
|
||||||
@ -284,33 +329,51 @@ public class CollisionEngine {
|
|||||||
DContact contact = contacts.get(i);
|
DContact contact = contacts.get(i);
|
||||||
//special code for ray casting
|
//special code for ray casting
|
||||||
if (o1 instanceof DRay || o2 instanceof DRay){
|
if (o1 instanceof DRay || o2 instanceof DRay){
|
||||||
DMatrix3 Rotation = new DMatrix3();
|
DVector3 end = new DVector3();
|
||||||
Rotation.setIdentity();
|
end.eqSum( contact.geom.pos, contact.geom.normal, contact.geom.depth );
|
||||||
// dsDrawSphere(contact.geom.pos, Rotation, (0.01));
|
|
||||||
|
|
||||||
DVector3 End = new DVector3();
|
|
||||||
End.eqSum( contact.geom.pos, contact.geom.normal, contact.geom.depth );
|
|
||||||
|
|
||||||
// dsDrawLine(contact.geom.pos, End);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// contact.geom.pos
|
// Use the default collision resolution
|
||||||
resolveCollision(
|
if(collisionResolutionCallback == null) {
|
||||||
bodyPointerMap.get(o1.getBody()),
|
resolveCollision(
|
||||||
bodyPointerMap.get(o2.getBody()),
|
contact.geom,
|
||||||
PhysicsUtils.odeVecToJomlVec(contact.geom.normal).mul(-1.0),
|
bodyPointerMap.get(o1.getBody()),
|
||||||
PhysicsUtils.odeVecToJomlVec(contact.fdir1).mul(-1.0),
|
bodyPointerMap.get(o2.getBody()),
|
||||||
PhysicsUtils.odeVecToJomlVec(contact.geom.pos),
|
PhysicsUtils.odeVecToJomlVec(contact.geom.normal).mul(-1.0),
|
||||||
(float)contact.geom.depth
|
PhysicsUtils.odeVecToJomlVec(contact.fdir1).mul(-1.0),
|
||||||
|
PhysicsUtils.odeVecToJomlVec(contact.geom.pos),
|
||||||
|
(float)contact.geom.depth
|
||||||
|
);
|
||||||
|
resolveCollision(
|
||||||
|
contact.geom,
|
||||||
|
bodyPointerMap.get(o2.getBody()),
|
||||||
|
bodyPointerMap.get(o1.getBody()),
|
||||||
|
PhysicsUtils.odeVecToJomlVec(contact.geom.normal),
|
||||||
|
PhysicsUtils.odeVecToJomlVec(contact.fdir1),
|
||||||
|
PhysicsUtils.odeVecToJomlVec(contact.geom.pos),
|
||||||
|
(float)contact.geom.depth
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
//use custom collision resolution
|
||||||
|
collisionResolutionCallback.resolve(
|
||||||
|
contact.geom,
|
||||||
|
bodyPointerMap.get(o1.getBody()),
|
||||||
|
bodyPointerMap.get(o2.getBody()),
|
||||||
|
PhysicsUtils.odeVecToJomlVec(contact.geom.normal).mul(-1.0),
|
||||||
|
PhysicsUtils.odeVecToJomlVec(contact.fdir1).mul(-1.0),
|
||||||
|
PhysicsUtils.odeVecToJomlVec(contact.geom.pos),
|
||||||
|
(float)contact.geom.depth
|
||||||
);
|
);
|
||||||
resolveCollision(
|
collisionResolutionCallback.resolve(
|
||||||
bodyPointerMap.get(o2.getBody()),
|
contact.geom,
|
||||||
bodyPointerMap.get(o1.getBody()),
|
bodyPointerMap.get(o2.getBody()),
|
||||||
PhysicsUtils.odeVecToJomlVec(contact.geom.normal),
|
bodyPointerMap.get(o1.getBody()),
|
||||||
PhysicsUtils.odeVecToJomlVec(contact.fdir1),
|
PhysicsUtils.odeVecToJomlVec(contact.geom.normal),
|
||||||
PhysicsUtils.odeVecToJomlVec(contact.geom.pos),
|
PhysicsUtils.odeVecToJomlVec(contact.fdir1),
|
||||||
(float)contact.geom.depth
|
PhysicsUtils.odeVecToJomlVec(contact.geom.pos),
|
||||||
|
(float)contact.geom.depth
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
//add contact to contact group
|
//add contact to contact group
|
||||||
DJoint c = OdeHelper.createContactJoint (world,contactgroup,contact );
|
DJoint c = OdeHelper.createContactJoint (world,contactgroup,contact );
|
||||||
@ -325,6 +388,14 @@ public class CollisionEngine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the function that is called once a collision has happened
|
||||||
|
* @param collisionResolutionCallback the function
|
||||||
|
*/
|
||||||
|
public void setCollisionResolutionCallback(CollisionResolutionCallback collisionResolutionCallback){
|
||||||
|
this.collisionResolutionCallback = collisionResolutionCallback;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -691,6 +762,19 @@ public class CollisionEngine {
|
|||||||
spaceLock.release();
|
spaceLock.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the transform of a geometry
|
||||||
|
* @param geom The geometry
|
||||||
|
* @param position The position
|
||||||
|
* @param rotation The rotation
|
||||||
|
*/
|
||||||
|
protected void setGeomTransform(DGeom geom, Vector3d position, Quaterniond rotation){
|
||||||
|
spaceLock.acquireUninterruptibly();
|
||||||
|
geom.setOffsetWorldPosition(position.x, position.y, position.z);
|
||||||
|
geom.setOffsetQuaternion(PhysicsUtils.jomlQuatToOdeQuat(rotation));
|
||||||
|
spaceLock.release();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Corrects the initial axis of eg cylinders or capsules
|
* Corrects the initial axis of eg cylinders or capsules
|
||||||
* @param geom the geometry to correct
|
* @param geom the geometry to correct
|
||||||
@ -759,4 +843,22 @@ public class CollisionEngine {
|
|||||||
spaceLock.release();
|
spaceLock.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A callback for resolving collisions between two entities
|
||||||
|
*/
|
||||||
|
public interface CollisionResolutionCallback {
|
||||||
|
/**
|
||||||
|
* Resolves a collision between two collidables in the engine
|
||||||
|
* @param contactGeom the ode4j contact geom
|
||||||
|
* @param impactor The collidable initiating the contact
|
||||||
|
* @param receiver The collidable recieving the contact
|
||||||
|
* @param normal The normal of the collision
|
||||||
|
* @param localPosition The local position of the collision
|
||||||
|
* @param worldPos The world position of the collision
|
||||||
|
* @param magnitude The magnitude of the collision
|
||||||
|
*/
|
||||||
|
public void resolve(DContactGeom contactGeom, Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,10 +2,12 @@ package electrosphere.collision;
|
|||||||
|
|
||||||
import org.joml.Matrix4d;
|
import org.joml.Matrix4d;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import org.ode4j.ode.DBody;
|
import org.ode4j.ode.DBody;
|
||||||
import org.ode4j.ode.DCylinder;
|
import org.ode4j.ode.DCylinder;
|
||||||
|
import org.ode4j.ode.DGeom;
|
||||||
import org.ode4j.ode.DTriMesh;
|
import org.ode4j.ode.DTriMesh;
|
||||||
|
|
||||||
import electrosphere.collision.collidable.Collidable;
|
import electrosphere.collision.collidable.Collidable;
|
||||||
@ -301,5 +303,14 @@ public class PhysicsEntityUtils {
|
|||||||
public static DBody getDBody(Entity entity){
|
public static DBody getDBody(Entity entity){
|
||||||
return (DBody)entity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
|
return (DBody)entity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the position of a DGeom
|
||||||
|
* @param collisionEngine the collision engine
|
||||||
|
* @param geom the geometry
|
||||||
|
*/
|
||||||
|
public static void setGeometryPosition(CollisionEngine collisionEngine, DGeom geom, Vector3d position, Quaterniond rotation){
|
||||||
|
collisionEngine.setGeomTransform(geom, position, rotation);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,7 +39,15 @@ public class PhysicsUtils {
|
|||||||
*/
|
*/
|
||||||
public static Vector3d odeVecToJomlVec(org.ode4j.math.DVector3C vector){
|
public static Vector3d odeVecToJomlVec(org.ode4j.math.DVector3C vector){
|
||||||
return new Vector3d(vector.get0(),vector.get1(),vector.get2());
|
return new Vector3d(vector.get0(),vector.get1(),vector.get2());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a joml vector to an Ode vector
|
||||||
|
* @param vector joml vector
|
||||||
|
* @return Ode vector
|
||||||
|
*/
|
||||||
|
public static org.ode4j.math.DVector3C jomlVecToOdeVec(Vector3d vector){
|
||||||
|
return new org.ode4j.math.DVector3(vector.x,vector.y,vector.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
package electrosphere.collision.hitbox;
|
package electrosphere.collision.hitbox;
|
||||||
|
|
||||||
import electrosphere.collision.CollisionEngine;
|
import electrosphere.collision.CollisionEngine;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.collision.CollisionEngine.CollisionResolutionCallback;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.engine.Globals;
|
||||||
|
import electrosphere.entity.state.hitbox.HitboxState;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11,7 +12,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||||||
public class HitboxManager {
|
public class HitboxManager {
|
||||||
|
|
||||||
//the list of all hitboxes
|
//the list of all hitboxes
|
||||||
CopyOnWriteArrayList<Entity> hitboxes = new CopyOnWriteArrayList<Entity>();
|
CopyOnWriteArrayList<HitboxState> hitboxes = new CopyOnWriteArrayList<HitboxState>();
|
||||||
|
|
||||||
//the collision engine for this hitbox manager
|
//the collision engine for this hitbox manager
|
||||||
CollisionEngine collisionEngine;
|
CollisionEngine collisionEngine;
|
||||||
@ -21,26 +22,27 @@ public class HitboxManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
* @param resolutionCallback The callback that fires when a collision occurs
|
||||||
*/
|
*/
|
||||||
public HitboxManager(){
|
public HitboxManager(CollisionResolutionCallback resolutionCallback){
|
||||||
collisionEngine = new CollisionEngine();
|
collisionEngine = new CollisionEngine();
|
||||||
|
collisionEngine.setCollisionResolutionCallback(resolutionCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a hitbox to the manager
|
* Registers a hitbox to the manager
|
||||||
* @param hitbox the hitbox to register
|
* @param hitbox the hitbox to register
|
||||||
*/
|
*/
|
||||||
public void registerHitbox(Entity hitbox){
|
public void registerHitbox(HitboxState hitbox){
|
||||||
hitboxes.add(hitbox);
|
hitboxes.add(hitbox);
|
||||||
idIncrementer++;
|
idIncrementer++;
|
||||||
hitbox.putData(EntityDataStrings.COLLISION_ENTITY_ID, idIncrementer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all hitboxes in the manager
|
* Gets all hitboxes in the manager
|
||||||
* @return all hitboxes in the manager
|
* @return all hitboxes in the manager
|
||||||
*/
|
*/
|
||||||
public CopyOnWriteArrayList<Entity> getAllHitboxes(){
|
public CopyOnWriteArrayList<HitboxState> getAllHitboxes(){
|
||||||
return hitboxes;
|
return hitboxes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +50,35 @@ public class HitboxManager {
|
|||||||
* Deregisters a hitbox from the manager
|
* Deregisters a hitbox from the manager
|
||||||
* @param hitbox the hitbox to deregister
|
* @param hitbox the hitbox to deregister
|
||||||
*/
|
*/
|
||||||
public void deregisterHitbox(Entity hitbox){
|
public void deregisterHitbox(HitboxState hitbox){
|
||||||
hitboxes.remove(hitbox);
|
hitboxes.remove(hitbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the collision engine associated with the hitbox manager
|
||||||
|
* @return The collision engine
|
||||||
|
*/
|
||||||
|
public CollisionEngine getCollisionEngine(){
|
||||||
|
return this.collisionEngine;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs all per frame functions of the hitbox manager
|
||||||
|
*/
|
||||||
|
public void simulate(){
|
||||||
|
//update all positions
|
||||||
|
Globals.profiler.beginCpuSample("Update hitbox positions");
|
||||||
|
for(HitboxState state : hitboxes){
|
||||||
|
state.updateHitboxPositions(this.collisionEngine);
|
||||||
|
}
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
|
//collide hitboxes
|
||||||
|
Globals.profiler.beginCpuSample("Collide hitboxes");
|
||||||
|
this.collisionEngine.collide();
|
||||||
|
this.collisionEngine.clearCollidableImpulseLists();
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,153 +26,153 @@ import org.joml.Vector3f;
|
|||||||
*/
|
*/
|
||||||
public class HitboxUtils {
|
public class HitboxUtils {
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Spawns a hitbox entity on the client
|
// * Spawns a hitbox entity on the client
|
||||||
* @param parent The parent entity to attach the hitbox to
|
// * @param parent The parent entity to attach the hitbox to
|
||||||
* @param bone The bone on the parent to attach to
|
// * @param bone The bone on the parent to attach to
|
||||||
* @param size The radius of the hitsphere
|
// * @param size The radius of the hitsphere
|
||||||
* @return The hitbox entity
|
// * @return The hitbox entity
|
||||||
*/
|
// */
|
||||||
public static Entity clientSpawnRegularHitbox(Entity parent, String bone, float size){
|
// public static Entity clientSpawnRegularHitbox(Entity parent, String bone, float size){
|
||||||
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
// Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
||||||
HitboxData data = new HitboxData();
|
// HitboxData data = new HitboxData();
|
||||||
data.setActive(false);
|
// data.setActive(false);
|
||||||
data.setBone(bone);
|
// data.setBone(bone);
|
||||||
data.setRadius(size);
|
// data.setRadius(size);
|
||||||
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT);
|
// data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT);
|
||||||
rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
// rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
||||||
rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
// rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
// rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
// rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||||
Globals.clientHitboxManager.registerHitbox(rVal);
|
// Globals.clientHitboxManager.registerHitbox(rVal);
|
||||||
return rVal;
|
// return rVal;
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Spawns a hitbox entity on the server
|
// * Spawns a hitbox entity on the server
|
||||||
* @param parent The parent entity to attach the hitbox to
|
// * @param parent The parent entity to attach the hitbox to
|
||||||
* @param bone The bone to attach to the hitbox to
|
// * @param bone The bone to attach to the hitbox to
|
||||||
* @param size The radius of the hitsphere
|
// * @param size The radius of the hitsphere
|
||||||
* @return The hitbox entity
|
// * @return The hitbox entity
|
||||||
*/
|
// */
|
||||||
public static Entity serverSpawnRegularHitbox(Entity parent, String bone, float size){
|
// public static Entity serverSpawnRegularHitbox(Entity parent, String bone, float size){
|
||||||
Entity rVal = EntityCreationUtils.createServerEntity(Globals.realmManager.getEntityRealm(parent), new Vector3d(0,0,0));
|
// Entity rVal = EntityCreationUtils.createServerEntity(Globals.realmManager.getEntityRealm(parent), new Vector3d(0,0,0));
|
||||||
HitboxData data = new HitboxData();
|
// HitboxData data = new HitboxData();
|
||||||
data.setActive(false);
|
// data.setActive(false);
|
||||||
data.setBone(bone);
|
// data.setBone(bone);
|
||||||
data.setRadius(size);
|
// data.setRadius(size);
|
||||||
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT);
|
// data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT);
|
||||||
rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
// rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
||||||
rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
// rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
// rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
// rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||||
Globals.realmManager.getEntityRealm(parent).getHitboxManager().registerHitbox(rVal);
|
// Globals.realmManager.getEntityRealm(parent).getHitboxManager().registerHitbox(rVal);
|
||||||
return rVal;
|
// return rVal;
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Spawns a hurtbox on the client
|
// * Spawns a hurtbox on the client
|
||||||
* @param parent The parent entity of the hurtbox
|
// * @param parent The parent entity of the hurtbox
|
||||||
* @param bone The bone on the parent to attach the hurtbox to
|
// * @param bone The bone on the parent to attach the hurtbox to
|
||||||
* @param size The radius of the hurtsphere
|
// * @param size The radius of the hurtsphere
|
||||||
* @return The hurtbox entity
|
// * @return The hurtbox entity
|
||||||
*/
|
// */
|
||||||
public static Entity clientSpawnRegularHurtbox(Entity parent, String bone, float size){
|
// public static Entity clientSpawnRegularHurtbox(Entity parent, String bone, float size){
|
||||||
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
// Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
||||||
HitboxData data = new HitboxData();
|
// HitboxData data = new HitboxData();
|
||||||
data.setActive(true);
|
// data.setActive(true);
|
||||||
data.setBone(bone);
|
// data.setBone(bone);
|
||||||
data.setRadius(size);
|
// data.setRadius(size);
|
||||||
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
|
// data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
|
||||||
rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
// rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
||||||
rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
// rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
// rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
// rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||||
Globals.clientHitboxManager.registerHitbox(rVal);
|
// Globals.clientHitboxManager.registerHitbox(rVal);
|
||||||
return rVal;
|
// return rVal;
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Spawns a hurtbox on the server
|
// * Spawns a hurtbox on the server
|
||||||
* @param parent The parent entity of the hurtbox
|
// * @param parent The parent entity of the hurtbox
|
||||||
* @param bone The bone on the parent to attach the hurtbox to
|
// * @param bone The bone on the parent to attach the hurtbox to
|
||||||
* @param size The radius of the hurtsphere
|
// * @param size The radius of the hurtsphere
|
||||||
* @return The hurtbox entity
|
// * @return The hurtbox entity
|
||||||
*/
|
// */
|
||||||
public static Entity serverSpawnRegularHurtbox(Entity parent, String bone, float size){
|
// public static Entity serverSpawnRegularHurtbox(Entity parent, String bone, float size){
|
||||||
Entity rVal = EntityCreationUtils.createServerEntity(Globals.realmManager.getEntityRealm(parent), new Vector3d(0,0,0));
|
// Entity rVal = EntityCreationUtils.createServerEntity(Globals.realmManager.getEntityRealm(parent), new Vector3d(0,0,0));
|
||||||
HitboxData data = new HitboxData();
|
// HitboxData data = new HitboxData();
|
||||||
data.setActive(true);
|
// data.setActive(true);
|
||||||
data.setBone(bone);
|
// data.setBone(bone);
|
||||||
data.setRadius(size);
|
// data.setRadius(size);
|
||||||
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
|
// data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
|
||||||
rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
// rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
||||||
rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
// rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
// rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
// rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||||
Globals.realmManager.getEntityRealm(parent).getHitboxManager().registerHitbox(rVal);
|
// Globals.realmManager.getEntityRealm(parent).getHitboxManager().registerHitbox(rVal);
|
||||||
return rVal;
|
// return rVal;
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* More sophisticated function for spawning in hitboxes. Takes a position callback so it's not tied to a bone
|
// * More sophisticated function for spawning in hitboxes. Takes a position callback so it's not tied to a bone
|
||||||
* @param parent The parent entity of the hitbox
|
// * @param parent The parent entity of the hitbox
|
||||||
* @param positionCallback The position callback for keeping hitbox entity position up to date
|
// * @param positionCallback The position callback for keeping hitbox entity position up to date
|
||||||
* @param size The size of the hitbox
|
// * @param size The size of the hitbox
|
||||||
* @param hurtbox If true, it will instead be a hurtbox
|
// * @param hurtbox If true, it will instead be a hurtbox
|
||||||
* @param filter an optional list of parent entities to not colide with
|
// * @param filter an optional list of parent entities to not colide with
|
||||||
* @return The hitbox entity
|
// * @return The hitbox entity
|
||||||
*/
|
// */
|
||||||
public static Entity clientSpawnRegularHitbox(Entity parent, HitboxPositionCallback positionCallback, float size, boolean hurtbox, List<Entity> filter){
|
// public static Entity clientSpawnRegularHitbox(Entity parent, HitboxPositionCallback positionCallback, float size, boolean hurtbox, List<Entity> filter){
|
||||||
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
// Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
||||||
HitboxData data = new HitboxData();
|
// HitboxData data = new HitboxData();
|
||||||
data.setActive(true);
|
// data.setActive(true);
|
||||||
data.setPositionCallback(positionCallback);
|
// data.setPositionCallback(positionCallback);
|
||||||
data.setRadius(size);
|
// data.setRadius(size);
|
||||||
data.setEntityFilter(filter);
|
// data.setEntityFilter(filter);
|
||||||
if(hurtbox){
|
// if(hurtbox){
|
||||||
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
|
// data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
|
||||||
} else {
|
// } else {
|
||||||
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT);
|
// data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT);
|
||||||
}
|
// }
|
||||||
rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
// rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
||||||
rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
// rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
// rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
// rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||||
Globals.clientHitboxManager.registerHitbox(rVal);
|
// Globals.clientHitboxManager.registerHitbox(rVal);
|
||||||
return rVal;
|
// return rVal;
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* More sophisticated function for spawning in hitboxes. Takes a position callback so it's not tied to a bone
|
// * More sophisticated function for spawning in hitboxes. Takes a position callback so it's not tied to a bone
|
||||||
* @param parent The parent entity of the hitbox
|
// * @param parent The parent entity of the hitbox
|
||||||
* @param positionCallback The position callback for keeping hitbox entity position up to date
|
// * @param positionCallback The position callback for keeping hitbox entity position up to date
|
||||||
* @param size The size of the hitbox
|
// * @param size The size of the hitbox
|
||||||
* @param hurtbox If true, it will instead be a hurtbox
|
// * @param hurtbox If true, it will instead be a hurtbox
|
||||||
* @param filter an optional list of parent entities to not colide with
|
// * @param filter an optional list of parent entities to not colide with
|
||||||
* @return The hitbox entity
|
// * @return The hitbox entity
|
||||||
*/
|
// */
|
||||||
public static Entity serverSpawnRegularHitbox(Entity parent, HitboxPositionCallback positionCallback, float size, boolean hurtbox, List<Entity> filter){
|
// public static Entity serverSpawnRegularHitbox(Entity parent, HitboxPositionCallback positionCallback, float size, boolean hurtbox, List<Entity> filter){
|
||||||
Entity rVal = EntityCreationUtils.createServerEntity(Globals.realmManager.getEntityRealm(parent), new Vector3d(0,0,0));
|
// Entity rVal = EntityCreationUtils.createServerEntity(Globals.realmManager.getEntityRealm(parent), new Vector3d(0,0,0));
|
||||||
HitboxData data = new HitboxData();
|
// HitboxData data = new HitboxData();
|
||||||
data.setActive(true);
|
// data.setActive(true);
|
||||||
data.setPositionCallback(positionCallback);
|
// data.setPositionCallback(positionCallback);
|
||||||
data.setRadius(size);
|
// data.setRadius(size);
|
||||||
data.setEntityFilter(filter);
|
// data.setEntityFilter(filter);
|
||||||
if(hurtbox){
|
// if(hurtbox){
|
||||||
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
|
// data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
|
||||||
} else {
|
// } else {
|
||||||
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT);
|
// data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT);
|
||||||
}
|
// }
|
||||||
rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
// rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
||||||
rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
// rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
// rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
// rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||||
Globals.realmManager.getEntityRealm(parent).getHitboxManager().registerHitbox(rVal);
|
// Globals.realmManager.getEntityRealm(parent).getHitboxManager().registerHitbox(rVal);
|
||||||
return rVal;
|
// return rVal;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public static void clientUpdatePosition(Entity hitbox){
|
public static void clientUpdatePosition(Entity hitbox){
|
||||||
Entity parent = ((Entity)hitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT));
|
Entity parent = ((Entity)hitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT));
|
||||||
@ -232,210 +232,48 @@ public class HitboxUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Collides entities on the client
|
|
||||||
* @param generatorHitbox the hitbox generating the collision
|
|
||||||
*/
|
|
||||||
public static void clientCollideEntities(Entity generatorHitbox){
|
|
||||||
// long generatorId = (Long)generatorHitbox.getData(EntityDataStrings.COLLISION_ENTITY_ID);
|
|
||||||
|
|
||||||
//This is the entity the hitbox is attached to
|
|
||||||
Entity generatorParent = (Entity)generatorHitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
|
||||||
|
|
||||||
for(Entity receiverHitbox : Globals.clientHitboxManager.getAllHitboxes()){
|
|
||||||
|
|
||||||
Entity receiverParent = (Entity)receiverHitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
|
||||||
|
|
||||||
HitboxData generatorData = getHitboxData(generatorHitbox);
|
|
||||||
HitboxData receiverData = getHitboxData(receiverHitbox);
|
|
||||||
|
|
||||||
//check projectile filters
|
|
||||||
List<Entity> generatorFilter = generatorData.getEntityFilter();
|
|
||||||
if(generatorFilter != null && generatorFilter.contains(receiverParent)){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Entity> receiverFilter = receiverData.getEntityFilter();
|
|
||||||
if(receiverFilter != null && receiverFilter.contains(generatorParent)){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if there is a collision
|
|
||||||
//and the collision isn't against itself
|
|
||||||
//and both hitboxes are active
|
|
||||||
if(
|
|
||||||
receiverParent != generatorParent &&
|
|
||||||
Globals.clientSceneWrapper.getCollisionEngine().collisionSphereCheck(generatorHitbox, generatorData, receiverHitbox, receiverData) &&
|
|
||||||
generatorData.isActive() &&
|
|
||||||
receiverData.isActive()){
|
|
||||||
//if two spheres collide, grab their hitbox types (eg hurt, hit, fire, etc)
|
|
||||||
String generatorType = generatorData.getType();
|
|
||||||
String receiverType = receiverData.getType();
|
|
||||||
|
|
||||||
if(generatorType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT) && receiverType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT)){
|
|
||||||
clientDamageHitboxColision(generatorHitbox, receiverHitbox);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(generatorType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT) && receiverType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT)){
|
|
||||||
clientDamageHitboxColision(receiverHitbox, generatorHitbox);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles collision between two hitboxes on the server
|
|
||||||
* @param generatorHitbox the hitbox generating the collision
|
|
||||||
*/
|
|
||||||
public static void serverCollideEntities(Entity generatorHitbox){
|
|
||||||
// long generatorId = (Long)generatorHitbox.getData(EntityDataStrings.COLLISION_ENTITY_ID);
|
|
||||||
|
|
||||||
//This is the entity the hitbox is attached to
|
|
||||||
Entity generatorParent = (Entity)generatorHitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
|
||||||
|
|
||||||
Realm generatorRealm = Globals.realmManager.getEntityRealm(generatorParent);
|
|
||||||
if(generatorRealm != null){
|
|
||||||
HitboxManager realmHitboxManager = generatorRealm.getHitboxManager();
|
|
||||||
|
|
||||||
for(Entity receiverHitbox : realmHitboxManager.getAllHitboxes()){
|
|
||||||
|
|
||||||
Entity receiverParent = (Entity)receiverHitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
|
||||||
|
|
||||||
HitboxData generatorData = getHitboxData(generatorHitbox);
|
|
||||||
HitboxData receiverData = getHitboxData(receiverHitbox);
|
|
||||||
|
|
||||||
//check projectile filters
|
|
||||||
List<Entity> generatorFilter = generatorData.getEntityFilter();
|
|
||||||
if(generatorFilter != null && generatorFilter.contains(receiverParent)){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Entity> receiverFilter = receiverData.getEntityFilter();
|
|
||||||
if(receiverFilter != null && receiverFilter.contains(generatorParent)){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if there is a collision
|
|
||||||
//and the collision isn't against itself
|
|
||||||
//and both hitboxes are active
|
|
||||||
if(
|
|
||||||
receiverParent != generatorParent &&
|
|
||||||
generatorRealm.getCollisionEngine().collisionSphereCheck(generatorHitbox, generatorData, receiverHitbox, receiverData) &&
|
|
||||||
generatorData.isActive() &&
|
|
||||||
receiverData.isActive()){
|
|
||||||
//if two spheres collide, grab their hitbox types (eg hurt, hit, fire, etc)
|
|
||||||
String generatorType = generatorData.getType();
|
|
||||||
String receiverType = receiverData.getType();
|
|
||||||
|
|
||||||
if(generatorType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT) && receiverType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT)){
|
|
||||||
serverDamageHitboxColision(generatorHitbox, receiverHitbox);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(generatorType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT) && receiverType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT)){
|
|
||||||
serverDamageHitboxColision(receiverHitbox, generatorHitbox);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a damage collision on the client
|
* Handles a damage collision on the client
|
||||||
* @param hitbox the hitbox
|
* @param impactor the entity initiating the collision
|
||||||
* @param hurtbox the hurtbox
|
* @param receiver the entity receiving the collision
|
||||||
*/
|
*/
|
||||||
public static void clientDamageHitboxColision(Entity hitbox, Entity hurtbox){
|
public static void clientDamageHitboxColision(Entity impactor, Entity receiver){
|
||||||
|
|
||||||
Entity hitboxParent = (Entity)hitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
// Entity hitboxParent = (Entity)impactor.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
||||||
Entity hurtboxParent = (Entity)hurtbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
// Entity hurtboxParent = (Entity)receiver.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
||||||
|
|
||||||
//if the entity is attached to is an item, we need to compare with the parent of the item
|
//if the entity is attached to is an item, we need to compare with the parent of the item
|
||||||
//to make sure you don't stab yourself for instance
|
//to make sure you don't stab yourself for instance
|
||||||
boolean isItem = ItemUtils.isItem(hitboxParent);//hitboxParent.containsKey(EntityDataStrings.ITEM_IS_ITEM);
|
// boolean isItem = ItemUtils.isItem(hitboxParent);//hitboxParent.containsKey(EntityDataStrings.ITEM_IS_ITEM);
|
||||||
Entity hitboxAttachParent = AttachUtils.getParent(hitboxParent);
|
// Entity hitboxAttachParent = AttachUtils.getParent(hitboxParent);
|
||||||
|
|
||||||
if(isItem){
|
// if(isItem){
|
||||||
if(hitboxAttachParent != hurtboxParent){
|
// if(hitboxAttachParent != hurtboxParent){
|
||||||
LifeState lifeState = LifeUtils.getLifeState(hurtboxParent);
|
// Vector3d hurtboxPos = EntityUtils.getPosition(receiver);
|
||||||
int currentHp = lifeState.getLifeCurrent();
|
// ParticleEffects.spawnBloodsplats(new Vector3f((float)hurtboxPos.x,(float)hurtboxPos.y,(float)hurtboxPos.z).add(0,0.1f,0), 20, 40);
|
||||||
int damage = ItemUtils.getWeaponDataRaw(hitboxParent).getDamage();
|
// }
|
||||||
LifeUtils.getLifeState(hurtboxParent).damage(damage);
|
// } else {
|
||||||
if(currentHp > lifeState.getLifeCurrent()){
|
|
||||||
Vector3d hurtboxPos = EntityUtils.getPosition(hurtbox);
|
|
||||||
ParticleEffects.spawnBloodsplats(new Vector3f((float)hurtboxPos.x,(float)hurtboxPos.y,(float)hurtboxPos.z).add(0,0.1f,0), 20, 40);
|
|
||||||
}
|
|
||||||
if(!LifeUtils.getLifeState(hurtboxParent).isIsAlive()){
|
|
||||||
EntityUtils.getPosition(hurtboxParent).set(Globals.spawnPoint);
|
|
||||||
LifeUtils.getLifeState(hurtboxParent).revive();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int damage = 0;
|
|
||||||
//for entities using attacktree
|
|
||||||
if(CreatureUtils.clientGetAttackTree(hitboxParent) != null){
|
|
||||||
damage = ItemUtils.getWeaponDataRaw(hitboxParent).getDamage();
|
|
||||||
} else {
|
|
||||||
//for entities using shooter tree
|
|
||||||
if(ProjectileTree.getProjectileTree(hitboxParent) != null){
|
|
||||||
damage = (int)ProjectileTree.getProjectileTree(hitboxParent).getDamage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LifeUtils.getLifeState(hurtboxParent).damage(damage);
|
|
||||||
if(!LifeUtils.getLifeState(hurtboxParent).isIsAlive()){
|
|
||||||
EntityUtils.getPosition(hurtboxParent).set(Globals.spawnPoint);
|
|
||||||
LifeUtils.getLifeState(hurtboxParent).revive();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
// //client no longer manages damage; however, keeping this code around for the moment to show how we
|
||||||
* Handles a damage hitbox collision on the server
|
// //might approach adding client-side effects as soon as impact occurs (ie play a sound, shoot sparks, etc)
|
||||||
* @param hitbox the hitbox
|
// //before the server responds with a valid collision event or not
|
||||||
* @param hurtbox the hurtbox
|
|
||||||
*/
|
// // int damage = 0;
|
||||||
public static void serverDamageHitboxColision(Entity hitbox, Entity hurtbox){
|
// // //for entities using attacktree
|
||||||
|
// // if(CreatureUtils.clientGetAttackTree(hitboxParent) != null){
|
||||||
Entity hitboxParent = (Entity)hitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
// // damage = ItemUtils.getWeaponDataRaw(hitboxParent).getDamage();
|
||||||
Entity hurtboxParent = (Entity)hurtbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
// // } else {
|
||||||
|
// // //for entities using shooter tree
|
||||||
//if the entity is attached to is an item, we need to compare with the parent of the item
|
// // if(ProjectileTree.getProjectileTree(hitboxParent) != null){
|
||||||
//to make sure you don't stab yourself for instance
|
// // damage = (int)ProjectileTree.getProjectileTree(hitboxParent).getDamage();
|
||||||
boolean isItem = ItemUtils.isItem(hitboxParent);//hitboxParent.containsKey(EntityDataStrings.ITEM_IS_ITEM);
|
// // }
|
||||||
Entity hitboxAttachParent = AttachUtils.getParent(hitboxParent);
|
// // }
|
||||||
|
// // LifeUtils.getLifeState(hurtboxParent).damage(damage);
|
||||||
if(isItem){
|
// // if(!LifeUtils.getLifeState(hurtboxParent).isIsAlive()){
|
||||||
if(hitboxAttachParent != hurtboxParent){
|
// // EntityUtils.getPosition(hurtboxParent).set(Globals.spawnPoint);
|
||||||
LifeState lifeState = LifeUtils.getLifeState(hurtboxParent);
|
// // LifeUtils.getLifeState(hurtboxParent).revive();
|
||||||
int currentHp = lifeState.getLifeCurrent();
|
// // }
|
||||||
int damage = ItemUtils.getWeaponDataRaw(hitboxParent).getDamage();
|
// }
|
||||||
LifeUtils.getLifeState(hurtboxParent).damage(damage);
|
|
||||||
if(currentHp > lifeState.getLifeCurrent()){
|
|
||||||
Vector3d hurtboxPos = EntityUtils.getPosition(hurtbox);
|
|
||||||
ParticleEffects.spawnBloodsplats(new Vector3f((float)hurtboxPos.x,(float)hurtboxPos.y,(float)hurtboxPos.z).add(0,0.1f,0), 20, 40);
|
|
||||||
}
|
|
||||||
if(!LifeUtils.getLifeState(hurtboxParent).isIsAlive()){
|
|
||||||
EntityUtils.getPosition(hurtboxParent).set(Globals.spawnPoint);
|
|
||||||
LifeUtils.getLifeState(hurtboxParent).revive();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int damage = 0;
|
|
||||||
//for entities using attacktree
|
|
||||||
if(CreatureUtils.serverGetAttackTree(hitboxParent) != null){
|
|
||||||
damage = ItemUtils.getWeaponDataRaw(hitboxParent).getDamage();
|
|
||||||
} else {
|
|
||||||
//for entities using shooter tree
|
|
||||||
if(ProjectileTree.getProjectileTree(hitboxParent) != null){
|
|
||||||
damage = (int)ProjectileTree.getProjectileTree(hitboxParent).getDamage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LifeUtils.getLifeState(hurtboxParent).damage(damage);
|
|
||||||
if(!LifeUtils.getLifeState(hurtboxParent).isIsAlive()){
|
|
||||||
EntityUtils.getPosition(hurtboxParent).set(Globals.spawnPoint);
|
|
||||||
LifeUtils.getLifeState(hurtboxParent).revive();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -447,24 +285,6 @@ public class HitboxUtils {
|
|||||||
return (HitboxData)e.getData(EntityDataStrings.HITBOX_DATA);
|
return (HitboxData)e.getData(EntityDataStrings.HITBOX_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the hitbox associated list
|
|
||||||
* @param e The entity that has hitboxes
|
|
||||||
* @return the list of hitboxes associated with the entity
|
|
||||||
*/
|
|
||||||
public static List<Entity> getHitboxAssociatedList(Entity e){
|
|
||||||
return (List<Entity>)e.getData(EntityDataStrings.HITBOX_ASSOCIATED_LIST);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the hurtbox associated list
|
|
||||||
* @param e the entity that has hurtboxes
|
|
||||||
* @return the list of hurtboxes associated with the entity
|
|
||||||
*/
|
|
||||||
public static List<Entity> getHurtboxAssociatedList(Entity e){
|
|
||||||
return (List<Entity>)e.getData(EntityDataStrings.HURTBOX_ASSOCIATED_LIST);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intended to be implemented as an anonoymous class when needed
|
* Intended to be implemented as an anonoymous class when needed
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import electrosphere.engine.Globals;
|
|||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.types.camera.CameraEntityUtils;
|
import electrosphere.entity.types.camera.CameraEntityUtils;
|
||||||
|
import electrosphere.net.parser.net.message.EntityMessage;
|
||||||
import electrosphere.renderer.ui.events.MouseEvent;
|
import electrosphere.renderer.ui.events.MouseEvent;
|
||||||
|
|
||||||
public class CameraHandler {
|
public class CameraHandler {
|
||||||
@ -107,8 +108,21 @@ public class CameraHandler {
|
|||||||
cameraRotationVector.mul(CameraEntityUtils.getOrbitalCameraDistance(Globals.playerCamera));
|
cameraRotationVector.mul(CameraEntityUtils.getOrbitalCameraDistance(Globals.playerCamera));
|
||||||
CameraEntityUtils.setCameraEye(Globals.playerCamera, cameraRotationVector);
|
CameraEntityUtils.setCameraEye(Globals.playerCamera, cameraRotationVector);
|
||||||
|
|
||||||
|
//tell the server that we changed where we're looking
|
||||||
|
Globals.clientConnection.queueOutgoingMessage(
|
||||||
|
EntityMessage.constructupdateEntityViewDirMessage(
|
||||||
|
Globals.clientSceneWrapper.mapClientToServerId(Globals.playerEntity.getId()),
|
||||||
|
Globals.timekeeper.getNumberOfSimFramesElapsed(),
|
||||||
|
cameraRotationVector.x,
|
||||||
|
cameraRotationVector.y,
|
||||||
|
cameraRotationVector.z
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
//the view matrix
|
||||||
Globals.viewMatrix = CameraEntityUtils.getCameraViewMatrix(Globals.playerCamera);
|
Globals.viewMatrix = CameraEntityUtils.getCameraViewMatrix(Globals.playerCamera);
|
||||||
|
|
||||||
|
//update the cursor on client side
|
||||||
updatePlayerCursor();
|
updatePlayerCursor();
|
||||||
}
|
}
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
|
|||||||
@ -84,6 +84,11 @@ import electrosphere.util.FileUtils;
|
|||||||
* @author amaterasu
|
* @author amaterasu
|
||||||
*/
|
*/
|
||||||
public class Globals {
|
public class Globals {
|
||||||
|
|
||||||
|
//
|
||||||
|
//Process data
|
||||||
|
//
|
||||||
|
public static String javaPID;
|
||||||
|
|
||||||
//
|
//
|
||||||
//Top level user settings object
|
//Top level user settings object
|
||||||
@ -302,9 +307,6 @@ public class Globals {
|
|||||||
//script engine
|
//script engine
|
||||||
public static ScriptEngine scriptEngine;
|
public static ScriptEngine scriptEngine;
|
||||||
|
|
||||||
//manages hitboxes
|
|
||||||
public static HitboxManager clientHitboxManager;
|
|
||||||
|
|
||||||
//client scene management
|
//client scene management
|
||||||
public static Scene clientScene;
|
public static Scene clientScene;
|
||||||
public static ClientSceneWrapper clientSceneWrapper;
|
public static ClientSceneWrapper clientSceneWrapper;
|
||||||
@ -442,8 +444,6 @@ public class Globals {
|
|||||||
//script engine
|
//script engine
|
||||||
scriptEngine = new ScriptEngine();
|
scriptEngine = new ScriptEngine();
|
||||||
scriptEngine.init();
|
scriptEngine.init();
|
||||||
//hitbox manager
|
|
||||||
clientHitboxManager = new HitboxManager();
|
|
||||||
//ai manager
|
//ai manager
|
||||||
aiManager = new AIManager();
|
aiManager = new AIManager();
|
||||||
//realm & data cell manager
|
//realm & data cell manager
|
||||||
@ -520,6 +520,7 @@ public class Globals {
|
|||||||
//init fluid shader program
|
//init fluid shader program
|
||||||
FluidChunkModelGeneration.fluidChunkShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/fluid2/fluid2.vs", "/Shaders/fluid2/fluid2.fs");
|
FluidChunkModelGeneration.fluidChunkShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/fluid2/fluid2.vs", "/Shaders/fluid2/fluid2.fs");
|
||||||
//init models
|
//init models
|
||||||
|
assetManager.addModelPathToQueue("Models/basic/geometry/unitsphere.glb");
|
||||||
assetManager.addModelPathToQueue("Models/basic/geometry/unitsphere.fbx");
|
assetManager.addModelPathToQueue("Models/basic/geometry/unitsphere.fbx");
|
||||||
assetManager.addModelPathToQueue("Models/basic/geometry/unitsphere_1.fbx");
|
assetManager.addModelPathToQueue("Models/basic/geometry/unitsphere_1.fbx");
|
||||||
assetManager.addModelPathToQueue("Models/basic/geometry/unitsphere_grey.fbx");
|
assetManager.addModelPathToQueue("Models/basic/geometry/unitsphere_grey.fbx");
|
||||||
|
|||||||
@ -63,8 +63,8 @@ public class Main {
|
|||||||
//initialize logging interfaces
|
//initialize logging interfaces
|
||||||
LoggerInterface.initLoggers();
|
LoggerInterface.initLoggers();
|
||||||
|
|
||||||
//gets pid of engine
|
//gets java pid of engine
|
||||||
System.out.println(ManagementFactory.getRuntimeMXBean().getName());
|
Globals.javaPID = ManagementFactory.getRuntimeMXBean().getName();
|
||||||
|
|
||||||
//load user settings
|
//load user settings
|
||||||
UserSettings.loadUserSettings();
|
UserSettings.loadUserSettings();
|
||||||
@ -221,6 +221,8 @@ public class Main {
|
|||||||
//main loop
|
//main loop
|
||||||
while (running) {
|
while (running) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
Globals.profiler.beginRootCpuSample("frame");
|
Globals.profiler.beginRootCpuSample("frame");
|
||||||
LoggerInterface.loggerEngine.DEBUG("Begin Main Loop Frame");
|
LoggerInterface.loggerEngine.DEBUG("Begin Main Loop Frame");
|
||||||
|
|
||||||
@ -396,6 +398,10 @@ public class Main {
|
|||||||
LoggerInterface.loggerEngine.DEBUG("End Main Loop Frame");
|
LoggerInterface.loggerEngine.DEBUG("End Main Loop Frame");
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
|
|
||||||
|
} catch (NullPointerException ex){
|
||||||
|
LoggerInterface.loggerEngine.ERROR("Main frame uncaught NPE", ex);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LoggerInterface.loggerEngine.WARNING("ENGINE SHUTDOWN");
|
LoggerInterface.loggerEngine.WARNING("ENGINE SHUTDOWN");
|
||||||
|
|||||||
@ -239,13 +239,21 @@ public class AssetManager {
|
|||||||
//
|
//
|
||||||
//Pose Models
|
//Pose Models
|
||||||
//
|
//
|
||||||
|
/**
|
||||||
|
* Adds a pose model to the list of pose models to load
|
||||||
|
* @param path The path to load
|
||||||
|
*/
|
||||||
public void addPoseModelPathToQueue(String path){
|
public void addPoseModelPathToQueue(String path){
|
||||||
if(!poseModelsInQueue.contains(path) && !poseModelsLoadedIntoMemory.containsKey(path)){
|
if(!poseModelsInQueue.contains(path) && !poseModelsLoadedIntoMemory.containsKey(path)){
|
||||||
poseModelsInQueue.add(path);
|
poseModelsInQueue.add(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a pose model
|
||||||
|
* @param path The path to fetch
|
||||||
|
* @return The pose model if it exists, null otherwise
|
||||||
|
*/
|
||||||
public PoseModel fetchPoseModel(String path){
|
public PoseModel fetchPoseModel(String path){
|
||||||
PoseModel rVal = null;
|
PoseModel rVal = null;
|
||||||
if(poseModelsLoadedIntoMemory.containsKey(path)){
|
if(poseModelsLoadedIntoMemory.containsKey(path)){
|
||||||
|
|||||||
@ -36,6 +36,9 @@ public class Timekeeper {
|
|||||||
//the maximum number of simulation frames that can happen in a row before the main loop immediately skips more
|
//the maximum number of simulation frames that can happen in a row before the main loop immediately skips more
|
||||||
public static final int SIM_FRAME_HARDCAP = 3;
|
public static final int SIM_FRAME_HARDCAP = 3;
|
||||||
|
|
||||||
|
//step interval time size (for physics)
|
||||||
|
public static final float ENGINE_STEP_SIZE = 0.01f;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -135,4 +138,13 @@ public class Timekeeper {
|
|||||||
return currentTime;
|
return currentTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of frames we're simulating this cycle
|
||||||
|
* @return The number of frames we're simulating this cycle
|
||||||
|
*/
|
||||||
|
public long getDeltaFrames(){
|
||||||
|
//this should always return 1. We're always simulating 1 frame per run of the loop in main
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,18 +1,16 @@
|
|||||||
package electrosphere.entity;
|
package electrosphere.entity;
|
||||||
|
|
||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Quaternionf;
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.renderer.actor.ActorUtils;
|
import electrosphere.renderer.actor.ActorUtils;
|
||||||
import electrosphere.renderer.actor.instance.InstancedActor;
|
|
||||||
import electrosphere.server.datacell.Realm;
|
import electrosphere.server.datacell.Realm;
|
||||||
import electrosphere.server.datacell.ServerDataCell;
|
import electrosphere.server.datacell.ServerDataCell;
|
||||||
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
||||||
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
|
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
|
||||||
import electrosphere.server.poseactor.PoseActor;
|
import electrosphere.server.poseactor.PoseActorUtils;
|
||||||
|
|
||||||
public class EntityCreationUtils {
|
public class EntityCreationUtils {
|
||||||
|
|
||||||
@ -82,7 +80,7 @@ public class EntityCreationUtils {
|
|||||||
* @param modelPath The model path for the model to back the pose actor
|
* @param modelPath The model path for the model to back the pose actor
|
||||||
*/
|
*/
|
||||||
public static void makeEntityPoseable(Entity entity, String modelPath){
|
public static void makeEntityPoseable(Entity entity, String modelPath){
|
||||||
entity.putData(EntityDataStrings.POSE_ACTOR, new PoseActor(modelPath));
|
entity.putData(EntityDataStrings.POSE_ACTOR, PoseActorUtils.createPoseActorFromModelPath(modelPath));
|
||||||
entity.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
entity.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||||
entity.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().identity());
|
entity.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().identity());
|
||||||
entity.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
|
entity.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
|
||||||
|
|||||||
@ -282,6 +282,11 @@ public class EntityDataStrings {
|
|||||||
* Pose actor
|
* Pose actor
|
||||||
*/
|
*/
|
||||||
public static final String POSE_ACTOR = "poseActor";
|
public static final String POSE_ACTOR = "poseActor";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server-specific btrees
|
||||||
|
*/
|
||||||
|
public static final String TREE_SERVERPLAYERVIEWDIR = "treeServerPlayerViewDir";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Entity categories
|
Entity categories
|
||||||
|
|||||||
@ -1,32 +1,20 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package electrosphere.entity;
|
package electrosphere.entity;
|
||||||
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree;
|
|
||||||
import electrosphere.entity.types.collision.CollisionObjUtils;
|
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
|
||||||
import electrosphere.entity.types.item.ItemUtils;
|
|
||||||
import electrosphere.renderer.actor.Actor;
|
import electrosphere.renderer.actor.Actor;
|
||||||
import electrosphere.renderer.actor.ActorUtils;
|
import electrosphere.renderer.actor.ActorUtils;
|
||||||
import electrosphere.renderer.model.Model;
|
|
||||||
import electrosphere.server.datacell.Realm;
|
import electrosphere.server.datacell.Realm;
|
||||||
import electrosphere.server.datacell.ServerDataCell;
|
import electrosphere.server.datacell.ServerDataCell;
|
||||||
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
|
||||||
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
||||||
import electrosphere.server.poseactor.PoseActor;
|
import electrosphere.server.poseactor.PoseActor;
|
||||||
|
import electrosphere.server.poseactor.PoseActorUtils;
|
||||||
|
|
||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Quaternionf;
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Utilties for dealing with entities
|
||||||
* @author amaterasu
|
|
||||||
*/
|
*/
|
||||||
public class EntityUtils {
|
public class EntityUtils {
|
||||||
|
|
||||||
@ -90,7 +78,7 @@ public class EntityUtils {
|
|||||||
*/
|
*/
|
||||||
protected static Entity spawnPoseableEntity(String modelPath){
|
protected static Entity spawnPoseableEntity(String modelPath){
|
||||||
Entity rVal = new Entity();
|
Entity rVal = new Entity();
|
||||||
rVal.putData(EntityDataStrings.POSE_ACTOR, new PoseActor(modelPath));
|
rVal.putData(EntityDataStrings.POSE_ACTOR, PoseActorUtils.createPoseActorFromModelPath(modelPath));
|
||||||
// rVal.putData(EntityDataStrings.DATA_STRING_MODEL_PATH, modelPath);
|
// rVal.putData(EntityDataStrings.DATA_STRING_MODEL_PATH, modelPath);
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().identity());
|
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().identity());
|
||||||
|
|||||||
@ -3,19 +3,15 @@ package electrosphere.entity.state.attack;
|
|||||||
|
|
||||||
import electrosphere.net.synchronization.BehaviorTreeIdEnums;
|
import electrosphere.net.synchronization.BehaviorTreeIdEnums;
|
||||||
|
|
||||||
import electrosphere.collision.collidable.Collidable;
|
|
||||||
import electrosphere.collision.hitbox.HitboxUtils;
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.engine.Main;
|
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.ServerEntityUtils;
|
|
||||||
import electrosphere.entity.btree.BehaviorTree;
|
import electrosphere.entity.btree.BehaviorTree;
|
||||||
import electrosphere.entity.state.client.firstPerson.FirstPersonTree;
|
import electrosphere.entity.state.client.firstPerson.FirstPersonTree;
|
||||||
import electrosphere.entity.state.collidable.Impulse;
|
import electrosphere.entity.state.collidable.Impulse;
|
||||||
import electrosphere.entity.state.equip.ClientEquipState;
|
import electrosphere.entity.state.equip.ClientEquipState;
|
||||||
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree;
|
import electrosphere.entity.state.hitbox.HitboxState;
|
||||||
import electrosphere.entity.state.rotator.RotatorTree;
|
import electrosphere.entity.state.rotator.RotatorTree;
|
||||||
import electrosphere.entity.types.attach.AttachUtils;
|
import electrosphere.entity.types.attach.AttachUtils;
|
||||||
import electrosphere.entity.types.collision.CollisionObjUtils;
|
import electrosphere.entity.types.collision.CollisionObjUtils;
|
||||||
@ -29,16 +25,11 @@ import electrosphere.net.synchronization.annotation.SyncedField;
|
|||||||
import electrosphere.net.synchronization.annotation.SynchronizableEnum;
|
import electrosphere.net.synchronization.annotation.SynchronizableEnum;
|
||||||
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
||||||
import electrosphere.renderer.actor.Actor;
|
import electrosphere.renderer.actor.Actor;
|
||||||
import electrosphere.renderer.anim.Animation;
|
|
||||||
import electrosphere.server.datacell.Realm;
|
|
||||||
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Quaternionf;
|
|
||||||
import org.joml.Quaternionfc;
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
@ -108,8 +99,8 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
String attackingPoint = null;
|
String attackingPoint = null;
|
||||||
|
|
||||||
public ClientAttackTree(Entity e){
|
public ClientAttackTree(Entity e){
|
||||||
state = AttackTreeState.IDLE;
|
setState(AttackTreeState.IDLE);
|
||||||
driftState = AttackTreeDriftState.NO_DRIFT;
|
setDriftState(AttackTreeDriftState.NO_DRIFT);
|
||||||
parent = e;
|
parent = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,6 +114,9 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts an attack
|
||||||
|
*/
|
||||||
public void start(){
|
public void start(){
|
||||||
currentMoveCanHold = false;
|
currentMoveCanHold = false;
|
||||||
currentMoveHasWindup = false;
|
currentMoveHasWindup = false;
|
||||||
@ -135,8 +129,8 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
String attackType = getAttackType();
|
String attackType = getAttackType();
|
||||||
//if we can attack, setup doing so
|
//if we can attack, setup doing so
|
||||||
if(canAttack(attackType)){
|
if(canAttack(attackType)){
|
||||||
parent.putData(EntityDataStrings.ATTACK_MOVE_TYPE_ACTIVE, attackType);
|
setAttackMoveTypeActive(attackType);
|
||||||
currentMoveset = (List<AttackMove>)parent.getData(attackType);
|
currentMoveset = getMoveset(attackType);
|
||||||
if(currentMoveset != null){
|
if(currentMoveset != null){
|
||||||
Globals.clientConnection.queueOutgoingMessage(EntityMessage.constructstartAttackMessage());
|
Globals.clientConnection.queueOutgoingMessage(EntityMessage.constructstartAttackMessage());
|
||||||
}
|
}
|
||||||
@ -148,23 +142,26 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void interrupt(){
|
public void interrupt(){
|
||||||
state = AttackTreeState.IDLE;
|
setState(AttackTreeState.IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void slowdown(){
|
public void slowdown(){
|
||||||
state = AttackTreeState.COOLDOWN;
|
setState(AttackTreeState.COOLDOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void simulate(float deltaTime){
|
public void simulate(float deltaTime){
|
||||||
frameCurrent = frameCurrent + (float)Globals.timekeeper.getSimFrameTime();
|
frameCurrent = frameCurrent + (float)Globals.timekeeper.getDeltaFrames();
|
||||||
float velocity = CreatureUtils.getVelocity(parent);
|
float velocity = CreatureUtils.getVelocity(parent);
|
||||||
Actor entityActor = EntityUtils.getActor(parent);
|
Actor entityActor = EntityUtils.getActor(parent);
|
||||||
Vector3d position = EntityUtils.getPosition(parent);
|
Vector3d position = EntityUtils.getPosition(parent);
|
||||||
Vector3d movementVector = CreatureUtils.getFacingVector(parent);
|
Vector3d movementVector = CreatureUtils.getFacingVector(parent);
|
||||||
|
|
||||||
//synchronize move from server
|
//synchronize move from server
|
||||||
if(this.currentMove == null && this.currentMoveId != null){
|
if(this.currentMoveset == null){
|
||||||
|
this.currentMoveset = getMoveset(getAttackType());
|
||||||
|
}
|
||||||
|
if(this.currentMove == null && this.currentMoveId != null && this.currentMoveset != null){
|
||||||
for(AttackMove move : currentMoveset){
|
for(AttackMove move : currentMoveset){
|
||||||
if(move.getAttackMoveId().equals(currentMoveId)){
|
if(move.getAttackMoveId().equals(currentMoveId)){
|
||||||
currentMove = move;
|
currentMove = move;
|
||||||
@ -183,23 +180,23 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
lastUpdateTime = updateTime;
|
lastUpdateTime = updateTime;
|
||||||
switch(message.gettreeState()){
|
switch(message.gettreeState()){
|
||||||
case 0:
|
case 0:
|
||||||
state = AttackTreeState.WINDUP;
|
setState(AttackTreeState.WINDUP);
|
||||||
frameCurrent = 0;
|
frameCurrent = 0;
|
||||||
// System.out.println("Set state STARTUP");
|
// System.out.println("Set state STARTUP");
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
frameCurrent = currentMove.getWindupFrames()+1;
|
frameCurrent = currentMove.getWindupFrames()+1;
|
||||||
state = AttackTreeState.ATTACK;
|
setState(AttackTreeState.ATTACK);
|
||||||
// System.out.println("Set state MOVE");
|
// System.out.println("Set state MOVE");
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
frameCurrent = currentMove.getWindupFrames()+currentMove.getAttackFrames()+1;
|
frameCurrent = currentMove.getWindupFrames()+currentMove.getAttackFrames()+1;
|
||||||
state = AttackTreeState.COOLDOWN;
|
setState(AttackTreeState.COOLDOWN);
|
||||||
// System.out.println("Set state SLOWDOWN");
|
// System.out.println("Set state SLOWDOWN");
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
frameCurrent = 60;
|
frameCurrent = 60;
|
||||||
state = AttackTreeState.IDLE;
|
setState(AttackTreeState.IDLE);
|
||||||
// System.out.println("Set state IDLE");
|
// System.out.println("Set state IDLE");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -230,26 +227,22 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
//calculate the vector of movement
|
//calculate the vector of movement
|
||||||
CollisionObjUtils.getCollidable(parent).addImpulse(new Impulse(new Vector3d(movementVector), new Vector3d(0,0,0), new Vector3d(0,0,0), currentMove.getDriftGoal() * Globals.timekeeper.getSimFrameTime(), "movement"));
|
CollisionObjUtils.getCollidable(parent).addImpulse(new Impulse(new Vector3d(movementVector), new Vector3d(0,0,0), new Vector3d(0,0,0), currentMove.getDriftGoal() * Globals.timekeeper.getSimFrameTime(), "movement"));
|
||||||
if(frameCurrent > currentMove.getDriftFrameEnd()){
|
if(frameCurrent > currentMove.getDriftFrameEnd()){
|
||||||
driftState = AttackTreeDriftState.NO_DRIFT;
|
setDriftState(AttackTreeDriftState.NO_DRIFT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NO_DRIFT:
|
case NO_DRIFT:
|
||||||
if(currentMove != null){
|
if(currentMove != null){
|
||||||
if(frameCurrent > currentMove.getDriftFrameStart() && frameCurrent < currentMove.getDriftFrameEnd()){
|
if(frameCurrent > currentMove.getDriftFrameStart() && frameCurrent < currentMove.getDriftFrameEnd()){
|
||||||
driftState = AttackTreeDriftState.DRIFT;
|
setDriftState(AttackTreeDriftState.DRIFT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if(state != AttackTreeState.IDLE){
|
|
||||||
// System.out.println(frameCurrent);
|
|
||||||
// }
|
|
||||||
|
|
||||||
//state machine
|
//state machine
|
||||||
switch(state){
|
switch(state){
|
||||||
case WINDUP:
|
case WINDUP: {
|
||||||
if(parent.containsKey(EntityDataStrings.CLIENT_ROTATOR_TREE)){
|
if(parent.containsKey(EntityDataStrings.CLIENT_ROTATOR_TREE)){
|
||||||
RotatorTree.getClientRotatorTree(parent).setActive(true);
|
RotatorTree.getClientRotatorTree(parent).setActive(true);
|
||||||
}
|
}
|
||||||
@ -261,35 +254,31 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonWindup().getName());
|
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonWindup().getName());
|
||||||
}
|
}
|
||||||
if(currentMoveCanHold && stillHold){
|
}
|
||||||
state = AttackTreeState.HOLD;
|
} break;
|
||||||
} else {
|
case HOLD: {
|
||||||
state = AttackTreeState.ATTACK;
|
if(entityActor != null){
|
||||||
|
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(currentMove.getHoldAnimationName())){
|
||||||
|
entityActor.playAnimation(currentMove.getHoldAnimationName(),1);
|
||||||
|
entityActor.incrementAnimationTime(0.0001);
|
||||||
}
|
}
|
||||||
|
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonHold().getName());
|
||||||
}
|
}
|
||||||
break;
|
} break;
|
||||||
case HOLD:
|
case ATTACK: {
|
||||||
if(entityActor != null){
|
if(entityActor != null && currentMove != null){
|
||||||
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationName)){
|
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(currentMove.getAttackAnimationName())){
|
||||||
entityActor.playAnimation(animationName,1);
|
entityActor.playAnimation(currentMove.getAttackAnimationName(),1);
|
||||||
entityActor.incrementAnimationTime(0.0001);
|
entityActor.incrementAnimationTime(0.0001);
|
||||||
|
}
|
||||||
|
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonAttack().getName());
|
||||||
}
|
}
|
||||||
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonHold().getName());
|
//activate hitboxes
|
||||||
}
|
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
||||||
if(!stillHold){
|
for(Entity currentAttached : attachedEntities){
|
||||||
state = AttackTreeState.ATTACK;
|
if(HitboxState.hasHitboxState(currentAttached)){
|
||||||
}
|
HitboxState currentState = HitboxState.getHitboxState(currentAttached);
|
||||||
break;
|
currentState.setActive(true);
|
||||||
case ATTACK:
|
|
||||||
if(parent.containsKey(EntityDataStrings.ATTACH_CHILDREN_LIST)){
|
|
||||||
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
|
||||||
for(Entity currentAttached : attachedEntities){
|
|
||||||
if(currentAttached.containsKey(EntityDataStrings.HITBOX_ASSOCIATED_LIST)){
|
|
||||||
List<Entity> hitboxes = HitboxUtils.getHitboxAssociatedList(currentAttached);
|
|
||||||
for(Entity hitbox : hitboxes){
|
|
||||||
HitboxUtils.getHitboxData(hitbox).setActive(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(firesProjectile && projectileToFire != null){
|
if(firesProjectile && projectileToFire != null){
|
||||||
@ -325,34 +314,27 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
ProjectileUtils.clientSpawnBasicProjectile(projectileToFire, spawnPosition, arrowRotation, 750, initialVector, 0.03f);
|
ProjectileUtils.clientSpawnBasicProjectile(projectileToFire, spawnPosition, arrowRotation, 750, initialVector, 0.03f);
|
||||||
projectileToFire = null;
|
projectileToFire = null;
|
||||||
}
|
}
|
||||||
if(currentMove != null && frameCurrent > currentMove.getWindupFrames() + currentMove.getAttackFrames()){
|
} break;
|
||||||
state = AttackTreeState.COOLDOWN;
|
case COOLDOWN: {
|
||||||
}
|
//deactive hitboxes
|
||||||
break;
|
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
||||||
case COOLDOWN:
|
for(Entity currentAttached : attachedEntities){
|
||||||
if(parent.containsKey(EntityDataStrings.ATTACH_CHILDREN_LIST)){
|
if(HitboxState.hasHitboxState(currentAttached)){
|
||||||
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
HitboxState currentState = HitboxState.getHitboxState(currentAttached);
|
||||||
for(Entity currentAttached : attachedEntities){
|
currentState.setActive(false);
|
||||||
if(currentAttached.containsKey(EntityDataStrings.HITBOX_ASSOCIATED_LIST)){
|
|
||||||
List<Entity> hitboxes = HitboxUtils.getHitboxAssociatedList(currentAttached);
|
|
||||||
for(Entity hitbox : hitboxes){
|
|
||||||
HitboxUtils.getHitboxData(hitbox).setActive(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(currentMove != null && frameCurrent > currentMove.getWindupFrames() + currentMove.getAttackFrames() + currentMove.getCooldownFrames()){
|
if(currentMove != null && frameCurrent > currentMove.getWindupFrames() + currentMove.getAttackFrames() + currentMove.getCooldownFrames()){
|
||||||
state = AttackTreeState.IDLE;
|
|
||||||
frameCurrent = 0;
|
frameCurrent = 0;
|
||||||
if(parent.containsKey(EntityDataStrings.CLIENT_ROTATOR_TREE)){
|
if(parent.containsKey(EntityDataStrings.CLIENT_ROTATOR_TREE)){
|
||||||
RotatorTree.getClientRotatorTree(parent).setActive(false);
|
RotatorTree.getClientRotatorTree(parent).setActive(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
} break;
|
||||||
case IDLE:
|
case IDLE: {
|
||||||
currentMove = null;
|
currentMove = null;
|
||||||
currentMoveset = null;
|
currentMoveset = null;
|
||||||
break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,6 +342,10 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
networkMessageQueue.add(networkMessage);
|
networkMessageQueue.add(networkMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current attack type
|
||||||
|
* @return The current attack type
|
||||||
|
*/
|
||||||
String getAttackType(){
|
String getAttackType(){
|
||||||
String rVal = null;
|
String rVal = null;
|
||||||
if(ClientEquipState.hasEquipState(parent)){
|
if(ClientEquipState.hasEquipState(parent)){
|
||||||
@ -433,6 +419,23 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current attack type of the entity
|
||||||
|
* @param attackType the current attack type
|
||||||
|
*/
|
||||||
|
public void setAttackMoveTypeActive(String attackType){
|
||||||
|
parent.putData(EntityDataStrings.ATTACK_MOVE_TYPE_ACTIVE, attackType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current moveset
|
||||||
|
* @param attackType the attack type
|
||||||
|
* @return The moveset if it exists
|
||||||
|
*/
|
||||||
|
public List<AttackMove> getMoveset(String attackType){
|
||||||
|
return (List<AttackMove>)parent.getData(attackType);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p> Automatically generated </p>
|
* <p> Automatically generated </p>
|
||||||
|
|||||||
@ -9,22 +9,19 @@ import electrosphere.net.parser.net.message.SynchronizationMessage;
|
|||||||
|
|
||||||
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
||||||
|
|
||||||
import electrosphere.collision.collidable.Collidable;
|
|
||||||
import electrosphere.collision.hitbox.HitboxUtils;
|
import electrosphere.collision.hitbox.HitboxUtils;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.engine.Main;
|
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.ServerEntityUtils;
|
|
||||||
import electrosphere.entity.btree.BehaviorTree;
|
import electrosphere.entity.btree.BehaviorTree;
|
||||||
import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeDriftState;
|
import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeDriftState;
|
||||||
import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeState;
|
import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeState;
|
||||||
|
import electrosphere.entity.state.client.firstPerson.FirstPersonTree;
|
||||||
import electrosphere.entity.state.collidable.Impulse;
|
import electrosphere.entity.state.collidable.Impulse;
|
||||||
import electrosphere.entity.state.equip.ServerEquipState;
|
import electrosphere.entity.state.equip.ServerEquipState;
|
||||||
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree;
|
import electrosphere.entity.state.hitbox.HitboxState;
|
||||||
import electrosphere.entity.state.movement.groundmove.ServerGroundMovementTree;
|
import electrosphere.entity.state.movement.groundmove.ServerGroundMovementTree;
|
||||||
import electrosphere.entity.state.rotator.RotatorTree;
|
|
||||||
import electrosphere.entity.state.rotator.ServerRotatorTree;
|
import electrosphere.entity.state.rotator.ServerRotatorTree;
|
||||||
import electrosphere.entity.types.attach.AttachUtils;
|
import electrosphere.entity.types.attach.AttachUtils;
|
||||||
import electrosphere.entity.types.collision.CollisionObjUtils;
|
import electrosphere.entity.types.collision.CollisionObjUtils;
|
||||||
@ -37,17 +34,13 @@ import electrosphere.net.parser.net.message.EntityMessage;
|
|||||||
import electrosphere.net.synchronization.annotation.SyncedField;
|
import electrosphere.net.synchronization.annotation.SyncedField;
|
||||||
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
||||||
import electrosphere.renderer.actor.Actor;
|
import electrosphere.renderer.actor.Actor;
|
||||||
import electrosphere.renderer.anim.Animation;
|
|
||||||
import electrosphere.server.datacell.Realm;
|
import electrosphere.server.datacell.Realm;
|
||||||
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
|
||||||
import electrosphere.server.poseactor.PoseActor;
|
import electrosphere.server.poseactor.PoseActor;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Quaternionf;
|
|
||||||
import org.joml.Quaternionfc;
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
@ -58,9 +51,11 @@ import org.joml.Vector3f;
|
|||||||
public class ServerAttackTree implements BehaviorTree {
|
public class ServerAttackTree implements BehaviorTree {
|
||||||
|
|
||||||
@SyncedField
|
@SyncedField
|
||||||
|
//the state of the attack tree
|
||||||
AttackTreeState state;
|
AttackTreeState state;
|
||||||
|
|
||||||
@SyncedField
|
@SyncedField
|
||||||
|
//the state of drifting caused by the attack animation
|
||||||
AttackTreeDriftState driftState;
|
AttackTreeDriftState driftState;
|
||||||
|
|
||||||
Entity parent;
|
Entity parent;
|
||||||
@ -115,8 +110,8 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
String attackType = getAttackType();
|
String attackType = getAttackType();
|
||||||
//if we can attack, setup doing so
|
//if we can attack, setup doing so
|
||||||
if(canAttack(attackType)){
|
if(canAttack(attackType)){
|
||||||
parent.putData(EntityDataStrings.ATTACK_MOVE_TYPE_ACTIVE, attackType);
|
setAttackMoveTypeActive(attackType);
|
||||||
currentMoveset = (List<AttackMove>)parent.getData(attackType);
|
currentMoveset = getMoveset(attackType);
|
||||||
if(currentMoveset != null){
|
if(currentMoveset != null){
|
||||||
if(currentMove == null){
|
if(currentMove == null){
|
||||||
currentMove = currentMoveset.get(0);
|
currentMove = currentMoveset.get(0);
|
||||||
@ -171,7 +166,7 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void simulate(float deltaTime){
|
public void simulate(float deltaTime){
|
||||||
frameCurrent = frameCurrent + (float)Globals.timekeeper.getSimFrameTime();
|
frameCurrent = frameCurrent + (float)Globals.timekeeper.getDeltaFrames();
|
||||||
float velocity = CreatureUtils.getVelocity(parent);
|
float velocity = CreatureUtils.getVelocity(parent);
|
||||||
PoseActor entityPoseActor = EntityUtils.getPoseActor(parent);
|
PoseActor entityPoseActor = EntityUtils.getPoseActor(parent);
|
||||||
Vector3d position = EntityUtils.getPosition(parent);
|
Vector3d position = EntityUtils.getPosition(parent);
|
||||||
@ -247,7 +242,7 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
|
|
||||||
//state machine
|
//state machine
|
||||||
switch(state){
|
switch(state){
|
||||||
case WINDUP:
|
case WINDUP: {
|
||||||
if(parent.containsKey(EntityDataStrings.SERVER_ROTATOR_TREE)){
|
if(parent.containsKey(EntityDataStrings.SERVER_ROTATOR_TREE)){
|
||||||
ServerRotatorTree.getServerRotatorTree(parent).setActive(true);
|
ServerRotatorTree.getServerRotatorTree(parent).setActive(true);
|
||||||
}
|
}
|
||||||
@ -278,28 +273,32 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
0
|
0
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
break;
|
} break;
|
||||||
case HOLD:
|
case HOLD: {
|
||||||
if(entityPoseActor != null){
|
if(entityPoseActor != null){
|
||||||
if(!entityPoseActor.isPlayingAnimation() || !entityPoseActor.isPlayingAnimation(animationName)){
|
if(!entityPoseActor.isPlayingAnimation() || !entityPoseActor.isPlayingAnimation(animationName)){
|
||||||
entityPoseActor.playAnimation(animationName,1);
|
entityPoseActor.playAnimation(animationName,1);
|
||||||
entityPoseActor.incrementAnimationTime(0.0001);
|
entityPoseActor.incrementAnimationTime(0.0001);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if(!stillHold){
|
||||||
if(!stillHold){
|
setState(AttackTreeState.ATTACK);
|
||||||
setState(AttackTreeState.ATTACK);
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
case ATTACK: {
|
||||||
case ATTACK:
|
if(entityPoseActor != null && currentMove != null){
|
||||||
if(parent.containsKey(EntityDataStrings.ATTACH_CHILDREN_LIST)){
|
if(!entityPoseActor.isPlayingAnimation() || !entityPoseActor.isPlayingAnimation(currentMove.getAttackAnimationName())){
|
||||||
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
entityPoseActor.playAnimation(currentMove.getAttackAnimationName(),1);
|
||||||
for(Entity currentAttached : attachedEntities){
|
entityPoseActor.incrementAnimationTime(0.0001);
|
||||||
if(currentAttached.containsKey(EntityDataStrings.HITBOX_ASSOCIATED_LIST)){
|
}
|
||||||
List<Entity> hitboxes = HitboxUtils.getHitboxAssociatedList(currentAttached);
|
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonAttack().getName());
|
||||||
for(Entity hitbox : hitboxes){
|
}
|
||||||
HitboxUtils.getHitboxData(hitbox).setActive(true);
|
//activate hitboxes
|
||||||
}
|
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
||||||
}
|
for(Entity currentAttached : attachedEntities){
|
||||||
|
if(HitboxState.hasHitboxState(currentAttached)){
|
||||||
|
HitboxState currentState = HitboxState.getHitboxState(currentAttached);
|
||||||
|
currentState.setActive(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(firesProjectile && projectileToFire != null){
|
if(firesProjectile && projectileToFire != null){
|
||||||
@ -353,17 +352,14 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
1
|
1
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
break;
|
} break;
|
||||||
case COOLDOWN:
|
case COOLDOWN: {
|
||||||
if(parent.containsKey(EntityDataStrings.ATTACH_CHILDREN_LIST)){
|
//deactive hitboxes
|
||||||
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
||||||
for(Entity currentAttached : attachedEntities){
|
for(Entity currentAttached : attachedEntities){
|
||||||
if(currentAttached.containsKey(EntityDataStrings.HITBOX_ASSOCIATED_LIST)){
|
if(HitboxState.hasHitboxState(currentAttached)){
|
||||||
List<Entity> hitboxes = HitboxUtils.getHitboxAssociatedList(currentAttached);
|
HitboxState currentState = HitboxState.getHitboxState(currentAttached);
|
||||||
for(Entity hitbox : hitboxes){
|
currentState.setActive(false);
|
||||||
HitboxUtils.getHitboxData(hitbox).setActive(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(frameCurrent > currentMove.getWindupFrames() + currentMove.getAttackFrames() + currentMove.getCooldownFrames()){
|
if(frameCurrent > currentMove.getWindupFrames() + currentMove.getAttackFrames() + currentMove.getCooldownFrames()){
|
||||||
@ -387,11 +383,11 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
2
|
2
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
break;
|
} break;
|
||||||
case IDLE:
|
case IDLE: {
|
||||||
currentMove = null;
|
currentMove = null;
|
||||||
currentMoveset = null;
|
currentMoveset = null;
|
||||||
break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,6 +467,23 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current attack type of the entity
|
||||||
|
* @param attackType the current attack type
|
||||||
|
*/
|
||||||
|
public void setAttackMoveTypeActive(String attackType){
|
||||||
|
parent.putData(EntityDataStrings.ATTACK_MOVE_TYPE_ACTIVE, attackType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current moveset
|
||||||
|
* @param attackType the attack type
|
||||||
|
* @return The moveset if it exists
|
||||||
|
*/
|
||||||
|
public List<AttackMove> getMoveset(String attackType){
|
||||||
|
return (List<AttackMove>)parent.getData(attackType);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p> Automatically generated </p>
|
* <p> Automatically generated </p>
|
||||||
|
|||||||
@ -115,7 +115,7 @@ public class FirstPersonTree implements BehaviorTree {
|
|||||||
* @param animationName the name of the animation
|
* @param animationName the name of the animation
|
||||||
*/
|
*/
|
||||||
public static void conditionallyPlayAnimation(Entity entity, String animationName){
|
public static void conditionallyPlayAnimation(Entity entity, String animationName){
|
||||||
if(hasTree(entity)){
|
if(entity != null && hasTree(entity)){
|
||||||
getTree(entity).playAnimation(animationName);
|
getTree(entity).playAnimation(animationName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,7 +72,6 @@ public class ClientEquipState implements BehaviorTree {
|
|||||||
boolean hasEquipped = hasEquippedAtPoint(point.getEquipPointId());
|
boolean hasEquipped = hasEquippedAtPoint(point.getEquipPointId());
|
||||||
boolean targetIsItem = ItemUtils.isItem(toEquip);
|
boolean targetIsItem = ItemUtils.isItem(toEquip);
|
||||||
boolean targetIsAttached = AttachUtils.isAttached(toEquip);
|
boolean targetIsAttached = AttachUtils.isAttached(toEquip);
|
||||||
boolean targetHasWhitelist = ItemUtils.hasEquipList(toEquip);
|
|
||||||
String equipItemClass = ItemUtils.getEquipClass(toEquip);
|
String equipItemClass = ItemUtils.getEquipClass(toEquip);
|
||||||
List<String> pointEquipClassList = point.getEquipClassWhitelist();
|
List<String> pointEquipClassList = point.getEquipClassWhitelist();
|
||||||
boolean itemIsInPointWhitelist = pointEquipClassList.contains(equipItemClass);
|
boolean itemIsInPointWhitelist = pointEquipClassList.contains(equipItemClass);
|
||||||
@ -90,7 +89,7 @@ public class ClientEquipState implements BehaviorTree {
|
|||||||
* @param toEquip The entity to equip
|
* @param toEquip The entity to equip
|
||||||
* @param point The equipment point to equip to
|
* @param point The equipment point to equip to
|
||||||
*/
|
*/
|
||||||
public void clientAttemptEquip(Entity toEquip, EquipPoint point){
|
public void attemptEquip(Entity toEquip, EquipPoint point){
|
||||||
boolean hasEquipped = hasEquippedAtPoint(point.getEquipPointId());
|
boolean hasEquipped = hasEquippedAtPoint(point.getEquipPointId());
|
||||||
boolean targetIsItem = ItemUtils.isItem(toEquip);
|
boolean targetIsItem = ItemUtils.isItem(toEquip);
|
||||||
boolean targetIsAttached = AttachUtils.isAttached(toEquip);
|
boolean targetIsAttached = AttachUtils.isAttached(toEquip);
|
||||||
|
|||||||
370
src/main/java/electrosphere/entity/state/hitbox/HitboxState.java
Normal file
370
src/main/java/electrosphere/entity/state/hitbox/HitboxState.java
Normal file
@ -0,0 +1,370 @@
|
|||||||
|
package electrosphere.entity.state.hitbox;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.joml.Quaterniond;
|
||||||
|
import org.joml.Vector3d;
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
import org.ode4j.ode.DBody;
|
||||||
|
import org.ode4j.ode.DGeom;
|
||||||
|
|
||||||
|
import electrosphere.collision.CollisionBodyCreation;
|
||||||
|
import electrosphere.collision.CollisionEngine;
|
||||||
|
import electrosphere.collision.PhysicsEntityUtils;
|
||||||
|
import electrosphere.collision.PhysicsUtils;
|
||||||
|
import electrosphere.collision.collidable.Collidable;
|
||||||
|
import electrosphere.collision.hitbox.HitboxManager;
|
||||||
|
import electrosphere.collision.hitbox.HitboxUtils.HitboxPositionCallback;
|
||||||
|
import electrosphere.entity.Entity;
|
||||||
|
import electrosphere.entity.EntityDataStrings;
|
||||||
|
import electrosphere.entity.EntityUtils;
|
||||||
|
import electrosphere.game.data.collidable.HitboxData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The hitbox state of this entity
|
||||||
|
*/
|
||||||
|
public class HitboxState {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Types of hitboxes
|
||||||
|
*/
|
||||||
|
public enum HitboxType {
|
||||||
|
HIT, // damages another entity
|
||||||
|
HURT, // receives damage from another entity
|
||||||
|
BLOCK, // blocks a hit from another entity
|
||||||
|
}
|
||||||
|
|
||||||
|
//the parent entity of the hitbox state
|
||||||
|
Entity parent;
|
||||||
|
|
||||||
|
//the body that contains all the hitbox shapes
|
||||||
|
DBody body;
|
||||||
|
|
||||||
|
//The collidable associated with the body
|
||||||
|
Collidable collidable;
|
||||||
|
|
||||||
|
//the map of bone -> hitbox shape in ode4j
|
||||||
|
Map<String,DGeom> hitboxGeomMap = new HashMap<String,DGeom>();
|
||||||
|
//the map of geometry -> hitbox shape status, useful for finding data about a given hitbox during collision
|
||||||
|
Map<DGeom,HitboxShapeStatus> geomBoneMap = new HashMap<DGeom,HitboxShapeStatus>();
|
||||||
|
|
||||||
|
//callback to provide a position for the hitbox each frame
|
||||||
|
HitboxPositionCallback positionCallback;
|
||||||
|
|
||||||
|
//controls whether the hitbox state is active or not
|
||||||
|
boolean active = true;
|
||||||
|
|
||||||
|
//the associated manager
|
||||||
|
HitboxManager manager;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create hitbox state for an entity
|
||||||
|
* @param collisionEngine the collision engine
|
||||||
|
* @param entity The entity to attach the state to
|
||||||
|
* @param hitboxListRaw The list of hitbox data to apply
|
||||||
|
* @return The hitbox state that has been attached to the entity
|
||||||
|
*/
|
||||||
|
public static HitboxState attachHitboxState(HitboxManager manager, Entity entity, List<HitboxData> hitboxListRaw){
|
||||||
|
HitboxState rVal = new HitboxState();
|
||||||
|
|
||||||
|
//create the shapes
|
||||||
|
for(HitboxData hitboxDataRaw : hitboxListRaw){
|
||||||
|
DGeom geom = CollisionBodyCreation.createShapeSphere(manager.getCollisionEngine(), hitboxDataRaw.getRadius(), Collidable.TYPE_OBJECT_BIT);
|
||||||
|
rVal.hitboxGeomMap.put(hitboxDataRaw.getBone(),geom);
|
||||||
|
HitboxType type = HitboxType.HIT;
|
||||||
|
switch(hitboxDataRaw.getType()){
|
||||||
|
case "HIT": {
|
||||||
|
type = HitboxType.HIT;
|
||||||
|
} break;
|
||||||
|
case "HURT": {
|
||||||
|
type = HitboxType.HURT;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
rVal.geomBoneMap.put(geom,new HitboxShapeStatus(hitboxDataRaw.getBone(), type, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
//create body with all the shapes
|
||||||
|
DGeom[] geomArray = rVal.hitboxGeomMap.values().toArray(new DGeom[rVal.hitboxGeomMap.values().size()]);
|
||||||
|
rVal.body = CollisionBodyCreation.createBodyWithShapes(manager.getCollisionEngine(), geomArray);
|
||||||
|
|
||||||
|
//register collidable with collision engine
|
||||||
|
Collidable collidable = new Collidable(entity, Collidable.TYPE_OBJECT);
|
||||||
|
manager.getCollisionEngine().registerCollisionObject(rVal.body, collidable);
|
||||||
|
|
||||||
|
//attach
|
||||||
|
entity.putData(EntityDataStrings.HITBOX_DATA, rVal);
|
||||||
|
rVal.parent = entity;
|
||||||
|
|
||||||
|
//register
|
||||||
|
manager.registerHitbox(rVal);
|
||||||
|
rVal.manager = manager;
|
||||||
|
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create hitbox state for an entity
|
||||||
|
* @param collisionEngine the collision engine
|
||||||
|
* @param entity The entity to attach the state to
|
||||||
|
* @param data The hitbox data to apply
|
||||||
|
* @param callback The callback that provides a position for the hitbox each frame
|
||||||
|
* @return The hitbox state that has been attached to the entity
|
||||||
|
*/
|
||||||
|
public static HitboxState attachHitboxStateWithCallback(HitboxManager manager, CollisionEngine collisionEngine, Entity entity, HitboxData data, HitboxPositionCallback callback){
|
||||||
|
HitboxState rVal = new HitboxState();
|
||||||
|
|
||||||
|
//create the shapes
|
||||||
|
rVal.hitboxGeomMap.put(data.getBone(),CollisionBodyCreation.createShapeSphere(collisionEngine, data.getRadius(), Collidable.TYPE_OBJECT_BIT));
|
||||||
|
|
||||||
|
//create body with all the shapes
|
||||||
|
DGeom[] geomArray = rVal.hitboxGeomMap.values().toArray(new DGeom[rVal.hitboxGeomMap.values().size()]);
|
||||||
|
rVal.body = CollisionBodyCreation.createBodyWithShapes(collisionEngine, geomArray);
|
||||||
|
|
||||||
|
//register collidable with collision engine
|
||||||
|
Collidable collidable = new Collidable(entity, Collidable.TYPE_OBJECT);
|
||||||
|
collisionEngine.registerCollisionObject(rVal.body, collidable);
|
||||||
|
|
||||||
|
//attach
|
||||||
|
entity.putData(EntityDataStrings.HITBOX_DATA, rVal);
|
||||||
|
rVal.parent = entity;
|
||||||
|
|
||||||
|
//register
|
||||||
|
manager.registerHitbox(rVal);
|
||||||
|
rVal.manager = manager;
|
||||||
|
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the positions of all hitboxes
|
||||||
|
*/
|
||||||
|
public void updateHitboxPositions(CollisionEngine collisionEngine){
|
||||||
|
if(parent != null && EntityUtils.getActor(parent) != null){
|
||||||
|
if(!this.hitboxGeomMap.isEmpty()){
|
||||||
|
Vector3d entityPosition = EntityUtils.getPosition(parent);
|
||||||
|
this.body.setPosition(PhysicsUtils.jomlVecToOdeVec(entityPosition));
|
||||||
|
for(String boneName : this.hitboxGeomMap.keySet()){
|
||||||
|
DGeom geom = this.hitboxGeomMap.get(boneName);
|
||||||
|
Quaterniond parentRotation = EntityUtils.getRotation(parent);
|
||||||
|
Vector3f positionScale = EntityUtils.getScale(parent);
|
||||||
|
Vector3d worldPosition = new Vector3d();
|
||||||
|
Vector3f bonePosition = EntityUtils.getActor(parent).getBonePosition(boneName);
|
||||||
|
Vector3d parentPos = EntityUtils.getPosition(parent);
|
||||||
|
worldPosition.set(bonePosition.x,bonePosition.y,bonePosition.z);
|
||||||
|
Quaterniond rotation = new Quaterniond(parentRotation);
|
||||||
|
|
||||||
|
worldPosition = worldPosition.mul(positionScale);
|
||||||
|
|
||||||
|
worldPosition = worldPosition.rotate(rotation);
|
||||||
|
|
||||||
|
|
||||||
|
worldPosition.add(new Vector3f((float)parentPos.x,(float)parentPos.y,(float)parentPos.z));
|
||||||
|
|
||||||
|
PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, worldPosition, rotation);
|
||||||
|
}
|
||||||
|
} else if(positionCallback != null){
|
||||||
|
DGeom geom = body.getGeomIterator().next();
|
||||||
|
Vector3d worldPosition = this.positionCallback.getPosition();
|
||||||
|
Quaterniond rotation = new Quaterniond().identity();
|
||||||
|
|
||||||
|
PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, worldPosition, rotation);
|
||||||
|
}
|
||||||
|
} else if(parent != null && EntityUtils.getPoseActor(parent) != null){
|
||||||
|
if(!this.hitboxGeomMap.isEmpty()){
|
||||||
|
Vector3d entityPosition = EntityUtils.getPosition(parent);
|
||||||
|
this.body.setPosition(PhysicsUtils.jomlVecToOdeVec(entityPosition));
|
||||||
|
for(String boneName : this.hitboxGeomMap.keySet()){
|
||||||
|
DGeom geom = this.hitboxGeomMap.get(boneName);
|
||||||
|
Quaterniond parentRotation = EntityUtils.getRotation(parent);
|
||||||
|
Vector3f positionScale = EntityUtils.getScale(parent);
|
||||||
|
Vector3d worldPosition = new Vector3d();
|
||||||
|
Vector3f bonePosition = EntityUtils.getPoseActor(parent).getBonePosition(boneName);
|
||||||
|
Vector3d parentPos = EntityUtils.getPosition(parent);
|
||||||
|
worldPosition.set(bonePosition.x,bonePosition.y,bonePosition.z);
|
||||||
|
Quaterniond rotation = new Quaterniond(parentRotation);
|
||||||
|
|
||||||
|
worldPosition = worldPosition.mul(positionScale);
|
||||||
|
|
||||||
|
worldPosition = worldPosition.rotate(rotation);
|
||||||
|
|
||||||
|
|
||||||
|
worldPosition.add(new Vector3f((float)parentPos.x,(float)parentPos.y,(float)parentPos.z));
|
||||||
|
|
||||||
|
PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, worldPosition, rotation);
|
||||||
|
}
|
||||||
|
} else if(positionCallback != null){
|
||||||
|
DGeom geom = body.getGeomIterator().next();
|
||||||
|
Vector3d worldPosition = this.positionCallback.getPosition();
|
||||||
|
Quaterniond rotation = new Quaterniond().identity();
|
||||||
|
|
||||||
|
PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, worldPosition, rotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the status of a shape in the hitbox object
|
||||||
|
* @param geom The geometry that is the shape within the hitbox data
|
||||||
|
* @return The status of the shape
|
||||||
|
*/
|
||||||
|
public HitboxShapeStatus getShapeStatus(DGeom geom){
|
||||||
|
return this.geomBoneMap.get(geom);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hitbox state of the entity
|
||||||
|
* @param entity the entity
|
||||||
|
* @return the hitbox state if it exists
|
||||||
|
*/
|
||||||
|
public static HitboxState getHitboxState(Entity entity){
|
||||||
|
return (HitboxState)entity.getData(EntityDataStrings.HITBOX_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the entity has hitbox state or not
|
||||||
|
* @param entity the entity to check
|
||||||
|
* @return true if there is hitbox state, false otherwise
|
||||||
|
*/
|
||||||
|
public static boolean hasHitboxState(Entity entity){
|
||||||
|
return entity.containsKey(EntityDataStrings.HITBOX_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the hitbox state and removes it from the entity
|
||||||
|
* @param entity the entity
|
||||||
|
* @return The hitbox state if it exists, null otherwise
|
||||||
|
*/
|
||||||
|
public static HitboxState destroyHitboxState(Entity entity){
|
||||||
|
HitboxState state = null;
|
||||||
|
if(hasHitboxState(entity)){
|
||||||
|
state = getHitboxState(entity);
|
||||||
|
state.manager.deregisterHitbox(state);
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the hitbox state is active or not
|
||||||
|
* @return true if active, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean isActive(){
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the active state of the hitbox
|
||||||
|
* @param state true to make it active, false otherwise
|
||||||
|
*/
|
||||||
|
public void setActive(boolean state){
|
||||||
|
this.active = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the collection of all DGeoms in the data
|
||||||
|
* @return the collection of all DGeoms
|
||||||
|
*/
|
||||||
|
public Collection<DGeom> getGeometries(){
|
||||||
|
return this.hitboxGeomMap.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the set of bone names in the state data
|
||||||
|
* @return The set of bone names in the state data
|
||||||
|
*/
|
||||||
|
public Set<String> getBones(){
|
||||||
|
return this.hitboxGeomMap.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets geometry on a single hitbox based on its bone name
|
||||||
|
* @param boneName the bone name
|
||||||
|
* @return the hitbox geometry
|
||||||
|
*/
|
||||||
|
public DGeom getGeometry(String boneName){
|
||||||
|
return this.hitboxGeomMap.get(boneName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The status of a single shape inside the overall hitbox data
|
||||||
|
* IE a single sphere on the overall body
|
||||||
|
*/
|
||||||
|
public static class HitboxShapeStatus {
|
||||||
|
|
||||||
|
//the name of the bone the hitbox is attached to
|
||||||
|
String boneName;
|
||||||
|
|
||||||
|
//the type of hitbox
|
||||||
|
HitboxType type;
|
||||||
|
|
||||||
|
//controls whether the hitbox is active
|
||||||
|
boolean isActive;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a status object for a hitbox
|
||||||
|
* @param boneName The name of the bone the hitbox is attached to, if any
|
||||||
|
* @param type The type of hitbox
|
||||||
|
* @param isActive if the hitbox is active or not
|
||||||
|
*/
|
||||||
|
public HitboxShapeStatus(String boneName, HitboxType type, boolean isActive){
|
||||||
|
this.boneName = boneName;
|
||||||
|
this.type = type;
|
||||||
|
this.isActive = isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the name of the bone the hitbox is attached to
|
||||||
|
* @return The name of the bone
|
||||||
|
*/
|
||||||
|
public String getBoneName(){
|
||||||
|
return boneName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the name of the bone the hitbox is attached to
|
||||||
|
* @param boneName The bone name
|
||||||
|
*/
|
||||||
|
public void setBoneName(String boneName){
|
||||||
|
this.boneName = boneName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the type of hitbox
|
||||||
|
* @return The type
|
||||||
|
*/
|
||||||
|
public HitboxType getType(){
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the type of hitbox
|
||||||
|
* @param type The type
|
||||||
|
*/
|
||||||
|
public void setType(HitboxType type){
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the hitbox is active or not
|
||||||
|
* @return true if active, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean isActive(){
|
||||||
|
return isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the hitbox is active or not
|
||||||
|
* @param active true for active, false otherwise
|
||||||
|
*/
|
||||||
|
public void setActive(boolean active){
|
||||||
|
this.isActive = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -3,20 +3,13 @@ package electrosphere.entity.state.movement.groundmove;
|
|||||||
|
|
||||||
import electrosphere.net.synchronization.BehaviorTreeIdEnums;
|
import electrosphere.net.synchronization.BehaviorTreeIdEnums;
|
||||||
|
|
||||||
import electrosphere.entity.state.collidable.Impulse;
|
|
||||||
import electrosphere.entity.state.gravity.ClientGravityTree;
|
|
||||||
import electrosphere.entity.state.gravity.GravityUtils;
|
import electrosphere.entity.state.gravity.GravityUtils;
|
||||||
import electrosphere.collision.CollisionEngine;
|
|
||||||
import electrosphere.collision.PhysicsEntityUtils;
|
import electrosphere.collision.PhysicsEntityUtils;
|
||||||
import electrosphere.collision.PhysicsUtils;
|
|
||||||
import electrosphere.collision.collidable.Collidable;
|
import electrosphere.collision.collidable.Collidable;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.engine.Main;
|
|
||||||
import electrosphere.entity.types.camera.CameraEntityUtils;
|
|
||||||
import electrosphere.entity.types.collision.CollisionObjUtils;
|
import electrosphere.entity.types.collision.CollisionObjUtils;
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
import electrosphere.game.data.creature.type.movement.GroundMovementSystem;
|
import electrosphere.game.data.creature.type.movement.GroundMovementSystem;
|
||||||
import electrosphere.entity.ClientEntityUtils;
|
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
@ -28,24 +21,17 @@ import electrosphere.entity.state.movement.FallTree;
|
|||||||
import electrosphere.entity.state.movement.JumpTree;
|
import electrosphere.entity.state.movement.JumpTree;
|
||||||
import electrosphere.entity.state.movement.SprintTree;
|
import electrosphere.entity.state.movement.SprintTree;
|
||||||
import electrosphere.entity.state.movement.SprintTree.SprintTreeState;
|
import electrosphere.entity.state.movement.SprintTree.SprintTreeState;
|
||||||
import electrosphere.net.NetUtils;
|
|
||||||
import electrosphere.net.parser.net.message.EntityMessage;
|
import electrosphere.net.parser.net.message.EntityMessage;
|
||||||
import electrosphere.net.synchronization.annotation.SyncedField;
|
import electrosphere.net.synchronization.annotation.SyncedField;
|
||||||
|
import electrosphere.net.synchronization.annotation.SynchronizableEnum;
|
||||||
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
||||||
import electrosphere.renderer.anim.Animation;
|
import electrosphere.renderer.anim.Animation;
|
||||||
import electrosphere.renderer.model.Model;
|
|
||||||
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
|
||||||
import electrosphere.renderer.actor.Actor;
|
import electrosphere.renderer.actor.Actor;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Quaternionf;
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
|
||||||
import org.ode4j.math.DVector3;
|
|
||||||
import org.ode4j.math.DVector3C;
|
import org.ode4j.math.DVector3C;
|
||||||
import org.ode4j.ode.DBody;
|
import org.ode4j.ode.DBody;
|
||||||
|
|
||||||
@ -69,6 +55,7 @@ public class ClientGroundMovementTree implements BehaviorTree {
|
|||||||
* The relative facing of the character to its rotation
|
* The relative facing of the character to its rotation
|
||||||
* (ie is it strafing, moveing straight forward, backpedaling, etc)
|
* (ie is it strafing, moveing straight forward, backpedaling, etc)
|
||||||
*/
|
*/
|
||||||
|
@SynchronizableEnum
|
||||||
public static enum MovementRelativeFacing {
|
public static enum MovementRelativeFacing {
|
||||||
FORWARD,
|
FORWARD,
|
||||||
LEFT,
|
LEFT,
|
||||||
@ -126,7 +113,6 @@ public class ClientGroundMovementTree implements BehaviorTree {
|
|||||||
//if we aren't the server, alert the server we intend to walk forward
|
//if we aren't the server, alert the server we intend to walk forward
|
||||||
Vector3d position = EntityUtils.getPosition(parent);
|
Vector3d position = EntityUtils.getPosition(parent);
|
||||||
Quaterniond rotation = EntityUtils.getRotation(parent);
|
Quaterniond rotation = EntityUtils.getRotation(parent);
|
||||||
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
|
|
||||||
float velocity = CreatureUtils.getVelocity(parent);
|
float velocity = CreatureUtils.getVelocity(parent);
|
||||||
Globals.clientConnection.queueOutgoingMessage(
|
Globals.clientConnection.queueOutgoingMessage(
|
||||||
EntityMessage.constructmoveUpdateMessage(
|
EntityMessage.constructmoveUpdateMessage(
|
||||||
@ -156,7 +142,6 @@ public class ClientGroundMovementTree implements BehaviorTree {
|
|||||||
//if we aren't the server, alert the server we intend to slow down
|
//if we aren't the server, alert the server we intend to slow down
|
||||||
Vector3d position = EntityUtils.getPosition(parent);
|
Vector3d position = EntityUtils.getPosition(parent);
|
||||||
Quaterniond rotation = EntityUtils.getRotation(parent);
|
Quaterniond rotation = EntityUtils.getRotation(parent);
|
||||||
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
|
|
||||||
float velocity = CreatureUtils.getVelocity(parent);
|
float velocity = CreatureUtils.getVelocity(parent);
|
||||||
Globals.clientConnection.queueOutgoingMessage(
|
Globals.clientConnection.queueOutgoingMessage(
|
||||||
EntityMessage.constructmoveUpdateMessage(
|
EntityMessage.constructmoveUpdateMessage(
|
||||||
|
|||||||
@ -3,15 +3,10 @@ package electrosphere.entity.state.movement.groundmove;
|
|||||||
|
|
||||||
import electrosphere.net.synchronization.BehaviorTreeIdEnums;
|
import electrosphere.net.synchronization.BehaviorTreeIdEnums;
|
||||||
|
|
||||||
import electrosphere.entity.state.collidable.Impulse;
|
|
||||||
import electrosphere.entity.state.gravity.GravityUtils;
|
import electrosphere.entity.state.gravity.GravityUtils;
|
||||||
import electrosphere.collision.CollisionEngine;
|
|
||||||
import electrosphere.collision.PhysicsEntityUtils;
|
import electrosphere.collision.PhysicsEntityUtils;
|
||||||
import electrosphere.collision.PhysicsUtils;
|
|
||||||
import electrosphere.collision.collidable.Collidable;
|
import electrosphere.collision.collidable.Collidable;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.engine.Main;
|
|
||||||
import electrosphere.entity.types.camera.CameraEntityUtils;
|
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
@ -25,28 +20,21 @@ import electrosphere.entity.state.movement.ServerSprintTree;
|
|||||||
import electrosphere.entity.state.movement.ServerSprintTree.SprintTreeState;
|
import electrosphere.entity.state.movement.ServerSprintTree.SprintTreeState;
|
||||||
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementRelativeFacing;
|
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementRelativeFacing;
|
||||||
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementTreeState;
|
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementTreeState;
|
||||||
import electrosphere.net.NetUtils;
|
|
||||||
import electrosphere.net.parser.net.message.EntityMessage;
|
import electrosphere.net.parser.net.message.EntityMessage;
|
||||||
import electrosphere.net.synchronization.annotation.SyncedField;
|
import electrosphere.net.synchronization.annotation.SyncedField;
|
||||||
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
||||||
import electrosphere.renderer.anim.Animation;
|
import electrosphere.renderer.anim.Animation;
|
||||||
import electrosphere.renderer.model.Model;
|
|
||||||
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
||||||
import electrosphere.server.poseactor.PoseActor;
|
import electrosphere.server.poseactor.PoseActor;
|
||||||
import electrosphere.renderer.actor.Actor;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Quaternionf;
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
|
||||||
import org.ode4j.math.DVector3C;
|
import org.ode4j.math.DVector3C;
|
||||||
import org.ode4j.ode.DBody;
|
import org.ode4j.ode.DBody;
|
||||||
|
|
||||||
@SynchronizedBehaviorTree(name = "serverGroundMovementTree", isServer = false, correspondingTree="clientGroundMovementTree")
|
@SynchronizedBehaviorTree(name = "serverGroundMovementTree", isServer = true, correspondingTree="clientGroundMovementTree")
|
||||||
/*
|
/*
|
||||||
Behavior tree for movement in an entity
|
Behavior tree for movement in an entity
|
||||||
*/
|
*/
|
||||||
@ -91,6 +79,10 @@ public class ServerGroundMovementTree implements BehaviorTree {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the server movement tree
|
||||||
|
* @param facing The facing dir to start with
|
||||||
|
*/
|
||||||
public void start(MovementRelativeFacing facing){
|
public void start(MovementRelativeFacing facing){
|
||||||
if(canStartMoving()){
|
if(canStartMoving()){
|
||||||
setFacing(facing);
|
setFacing(facing);
|
||||||
@ -98,7 +90,6 @@ public class ServerGroundMovementTree implements BehaviorTree {
|
|||||||
//if we aren't the server, alert the server we intend to walk forward
|
//if we aren't the server, alert the server we intend to walk forward
|
||||||
Vector3d position = EntityUtils.getPosition(parent);
|
Vector3d position = EntityUtils.getPosition(parent);
|
||||||
Quaterniond rotation = EntityUtils.getRotation(parent);
|
Quaterniond rotation = EntityUtils.getRotation(parent);
|
||||||
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
|
|
||||||
float velocity = CreatureUtils.getVelocity(parent);
|
float velocity = CreatureUtils.getVelocity(parent);
|
||||||
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
|
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
|
||||||
EntityMessage.constructmoveUpdateMessage(
|
EntityMessage.constructmoveUpdateMessage(
|
||||||
@ -128,7 +119,6 @@ public class ServerGroundMovementTree implements BehaviorTree {
|
|||||||
//if we aren't the server, alert the server we intend to slow down
|
//if we aren't the server, alert the server we intend to slow down
|
||||||
Vector3d position = EntityUtils.getPosition(parent);
|
Vector3d position = EntityUtils.getPosition(parent);
|
||||||
Quaterniond rotation = EntityUtils.getRotation(parent);
|
Quaterniond rotation = EntityUtils.getRotation(parent);
|
||||||
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
|
|
||||||
float velocity = CreatureUtils.getVelocity(parent);
|
float velocity = CreatureUtils.getVelocity(parent);
|
||||||
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
|
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
|
||||||
EntityMessage.constructmoveUpdateMessage(
|
EntityMessage.constructmoveUpdateMessage(
|
||||||
@ -213,9 +203,20 @@ public class ServerGroundMovementTree implements BehaviorTree {
|
|||||||
case MOVEUPDATE: {
|
case MOVEUPDATE: {
|
||||||
if(updateTime >= lastUpdateTime){
|
if(updateTime >= lastUpdateTime){
|
||||||
lastUpdateTime = updateTime;
|
lastUpdateTime = updateTime;
|
||||||
|
switch(message.gettreeState()){
|
||||||
|
//0 is startup
|
||||||
|
case 0: {
|
||||||
|
start(MovementRelativeFacing.FORWARD);
|
||||||
|
} break;
|
||||||
|
case 2: {
|
||||||
|
slowdown();
|
||||||
|
} break;
|
||||||
|
default: {
|
||||||
|
|
||||||
|
} break;
|
||||||
|
}
|
||||||
//we want to always update the server facing vector with where the client says they're facing
|
//we want to always update the server facing vector with where the client says they're facing
|
||||||
EntityUtils.getRotation(parent).set(message.getrotationX(),message.getrotationY(),message.getrotationZ(),message.getrotationW());
|
EntityUtils.getRotation(parent).set(message.getrotationX(),message.getrotationY(),message.getrotationZ(),message.getrotationW());
|
||||||
CreatureUtils.setFacingVector(parent, new Vector3d(0,0,1).rotate(EntityUtils.getRotation(parent)));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|||||||
@ -0,0 +1,85 @@
|
|||||||
|
package electrosphere.entity.state.server;
|
||||||
|
|
||||||
|
import org.joml.Vector3d;
|
||||||
|
|
||||||
|
import electrosphere.entity.Entity;
|
||||||
|
import electrosphere.entity.EntityDataStrings;
|
||||||
|
import electrosphere.entity.btree.BehaviorTree;
|
||||||
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the direction that the server thinks the player is looking
|
||||||
|
*/
|
||||||
|
public class ServerPlayerViewDirTree implements BehaviorTree {
|
||||||
|
|
||||||
|
//the direction of the view
|
||||||
|
Vector3d playerViewDir = new Vector3d();
|
||||||
|
|
||||||
|
//the last time this value was updated
|
||||||
|
long lastUpdateTime = 0;
|
||||||
|
|
||||||
|
//the parent entity
|
||||||
|
Entity parent;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void simulate(float deltaTime) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param parent
|
||||||
|
*/
|
||||||
|
private ServerPlayerViewDirTree(Entity parent){
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches a ServerPlayerViewDirTree to a given entity
|
||||||
|
* @param entity The entity to add to
|
||||||
|
*/
|
||||||
|
public static void attachServerPlayerViewDirTree(Entity entity){
|
||||||
|
ServerPlayerViewDirTree tree = new ServerPlayerViewDirTree(entity);
|
||||||
|
entity.putData(EntityDataStrings.TREE_SERVERPLAYERVIEWDIR, tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the server player view dir tree if it exists
|
||||||
|
* @param entity The entity to get from
|
||||||
|
* @return The ServerPlayerViewDirTree if it exists, null otherwise
|
||||||
|
*/
|
||||||
|
public static ServerPlayerViewDirTree getTree(Entity entity){
|
||||||
|
return (ServerPlayerViewDirTree)entity.getData(EntityDataStrings.TREE_SERVERPLAYERVIEWDIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the entity has a copy of this btree or not
|
||||||
|
* @param entity The entity
|
||||||
|
* @return true if the entity has the btree, false otherwise
|
||||||
|
*/
|
||||||
|
public static boolean hasTree(Entity entity){
|
||||||
|
return entity.containsKey(EntityDataStrings.TREE_SERVERPLAYERVIEWDIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the player view dir
|
||||||
|
* @return The player view dir
|
||||||
|
*/
|
||||||
|
public Vector3d getPlayerViewDir(){
|
||||||
|
return playerViewDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the player view dir vector
|
||||||
|
* @param playerViewDir The player view dir vector
|
||||||
|
*/
|
||||||
|
public void setPlayerViewDir(Vector3d playerViewDir, long time){
|
||||||
|
if(time > lastUpdateTime){
|
||||||
|
this.playerViewDir = playerViewDir;
|
||||||
|
this.lastUpdateTime = time;
|
||||||
|
CreatureUtils.setFacingVector(parent, new Vector3d(-playerViewDir.x,0,-playerViewDir.z));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -7,7 +7,6 @@ import electrosphere.entity.EntityTags;
|
|||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
import electrosphere.renderer.actor.Actor;
|
import electrosphere.renderer.actor.Actor;
|
||||||
import electrosphere.renderer.model.Model;
|
|
||||||
import electrosphere.server.datacell.ServerDataCell;
|
import electrosphere.server.datacell.ServerDataCell;
|
||||||
import electrosphere.server.datacell.utils.ServerEntityTagUtils;
|
import electrosphere.server.datacell.utils.ServerEntityTagUtils;
|
||||||
import electrosphere.server.poseactor.PoseActor;
|
import electrosphere.server.poseactor.PoseActor;
|
||||||
@ -18,10 +17,8 @@ import java.util.List;
|
|||||||
import org.joml.Matrix4d;
|
import org.joml.Matrix4d;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Quaternionf;
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import org.joml.Vector4d;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utilities for attaching entities to entities
|
* Utilities for attaching entities to entities
|
||||||
@ -39,7 +36,28 @@ public class AttachUtils {
|
|||||||
// FUNCTIONS TO UPDATE ATTACHMENTS FOR CURRENT FRAME
|
// FUNCTIONS TO UPDATE ATTACHMENTS FOR CURRENT FRAME
|
||||||
//
|
//
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// SERVER
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates positions of all attached entities in a data cell
|
||||||
|
* @param cell The data cell
|
||||||
|
*/
|
||||||
public static void serverUpdateAttachedEntityPositions(ServerDataCell cell){
|
public static void serverUpdateAttachedEntityPositions(ServerDataCell cell){
|
||||||
|
Globals.profiler.beginCpuSample("AttachUtils.serverUpdateAttachedEntityPositions");
|
||||||
|
serverUpdateBoneAttachedEntityPositions(cell);
|
||||||
|
serverUpdateNonBoneAttachments(cell);
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates entities attached to bones of actors in a data cell
|
||||||
|
* @param cell The data cell
|
||||||
|
*/
|
||||||
|
public static void serverUpdateBoneAttachedEntityPositions(ServerDataCell cell){
|
||||||
for(Entity currentEntity : cell.getScene().getEntitiesWithTag(EntityTags.BONE_ATTACHED)){
|
for(Entity currentEntity : cell.getScene().getEntitiesWithTag(EntityTags.BONE_ATTACHED)){
|
||||||
Entity parent;
|
Entity parent;
|
||||||
if((parent = (Entity)currentEntity.getData(EntityDataStrings.ATTACH_PARENT))!=null){
|
if((parent = (Entity)currentEntity.getData(EntityDataStrings.ATTACH_PARENT))!=null){
|
||||||
@ -68,25 +86,97 @@ public class AttachUtils {
|
|||||||
.mul(offsetRotation)
|
.mul(offsetRotation)
|
||||||
.normalize();
|
.normalize();
|
||||||
}
|
}
|
||||||
|
} else if(currentEntity.getData(EntityDataStrings.ATTACH_TARGET_BASE)!=null){
|
||||||
|
Vector3d positionOffset = getAttachPositionOffset(currentEntity);
|
||||||
|
Vector3d parentPosition = EntityUtils.getPosition(parent);
|
||||||
|
EntityUtils.getPosition(currentEntity).set(new Vector3d(parentPosition).add(positionOffset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates entities that aren't attached to a bone directly in a data cell
|
||||||
|
* @param cell the data cell
|
||||||
|
*/
|
||||||
|
private static void serverUpdateNonBoneAttachments(ServerDataCell cell){
|
||||||
|
Globals.profiler.beginCpuSample("AttachUtils.serverUpdateNonBoneAttachments");
|
||||||
|
Matrix4d parentTransform = new Matrix4d().identity();
|
||||||
|
Vector3d position = new Vector3d();
|
||||||
|
Quaterniond rotation = new Quaterniond();
|
||||||
|
Vector3d scaleRaw = new Vector3d();
|
||||||
|
Vector3f scale = new Vector3f();
|
||||||
|
Entity parent;
|
||||||
|
Matrix4f transform;
|
||||||
|
//update entities attached to centerpoint + transform of other entities
|
||||||
|
for(Entity currentEntity : cell.getScene().getEntitiesWithTag(EntityTags.TRANSFORM_ATTACHED)){
|
||||||
|
if((parent = (Entity)currentEntity.getData(EntityDataStrings.ATTACH_PARENT))!=null){
|
||||||
|
if((transform = getTransformOffset(currentEntity))!=null){
|
||||||
|
//parent objects
|
||||||
|
Vector3d parentPosition = EntityUtils.getPosition(parent);
|
||||||
|
Quaterniond parentRotation = EntityUtils.getRotation(parent);
|
||||||
|
Vector3f parentScale = EntityUtils.getScale(parent);
|
||||||
|
// calculate new transform for current entity
|
||||||
|
parentTransform.identity()
|
||||||
|
.translate(parentPosition)
|
||||||
|
.rotate(parentRotation)
|
||||||
|
.scale(parentScale.x,parentScale.y,parentScale.z)
|
||||||
|
.mul(transform);
|
||||||
|
//transform bone space
|
||||||
|
parentTransform.getTranslation(position);
|
||||||
|
parentTransform.getUnnormalizedRotation(rotation).normalize();
|
||||||
|
parentTransform.getScale(scaleRaw);
|
||||||
|
scale.set((float)scaleRaw.x,(float)scaleRaw.y,(float)scaleRaw.z);
|
||||||
|
//transform worldspace
|
||||||
|
// position.add(new Vector3d(EntityUtils.getPosition(parent)));
|
||||||
|
//set
|
||||||
|
EntityUtils.getPosition(currentEntity).set(position);
|
||||||
|
EntityUtils.getRotation(currentEntity).set(rotation);
|
||||||
|
EntityUtils.getScale(currentEntity).set(scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// CLIENT
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client version of attachment update functions
|
* Client version of attachment update functions
|
||||||
*/
|
*/
|
||||||
public static void clientUpdateAttachedEntityPositions(){
|
public static void clientUpdateAttachedEntityPositions(){
|
||||||
Globals.profiler.beginCpuSample("AttachUtils.clientUpdateAttachedEntityPositions");
|
Globals.profiler.beginCpuSample("AttachUtils.clientUpdateAttachedEntityPositions");
|
||||||
updateBoneAttachments();
|
clientUpdateBoneAttachments();
|
||||||
updateNonBoneAttachments();
|
clientUpdateNonBoneAttachments();
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates entities attached to bones
|
* Updates entities attached to bones
|
||||||
*/
|
*/
|
||||||
private static void updateBoneAttachments(){
|
private static void clientUpdateBoneAttachments(){
|
||||||
Globals.profiler.beginCpuSample("AttachUtils.updateBoneAttachments");
|
Globals.profiler.beginCpuSample("AttachUtils.clientUpdateBoneAttachments");
|
||||||
//update entities attached to bones of other entities
|
//update entities attached to bones of other entities
|
||||||
for(Entity currentEntity : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.BONE_ATTACHED)){
|
for(Entity currentEntity : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.BONE_ATTACHED)){
|
||||||
Entity parent;
|
Entity parent;
|
||||||
@ -128,7 +218,10 @@ public class AttachUtils {
|
|||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void updateNonBoneAttachments(){
|
/**
|
||||||
|
* Updates entities that aren't attached to a bone directly
|
||||||
|
*/
|
||||||
|
private static void clientUpdateNonBoneAttachments(){
|
||||||
Globals.profiler.beginCpuSample("AttachUtils.updateNonBoneAttachments");
|
Globals.profiler.beginCpuSample("AttachUtils.updateNonBoneAttachments");
|
||||||
Matrix4d parentTransform = new Matrix4d().identity();
|
Matrix4d parentTransform = new Matrix4d().identity();
|
||||||
Vector3d position = new Vector3d();
|
Vector3d position = new Vector3d();
|
||||||
@ -334,6 +427,11 @@ public class AttachUtils {
|
|||||||
// FUNCTIONS TO DETATCH AN ENTITY
|
// FUNCTIONS TO DETATCH AN ENTITY
|
||||||
//
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detatches an entity on the server
|
||||||
|
* @param parent The parent entity
|
||||||
|
* @param toAttach The attached entity
|
||||||
|
*/
|
||||||
public static void serverDetatchEntityFromEntityAtBone(Entity parent, Entity toAttach){
|
public static void serverDetatchEntityFromEntityAtBone(Entity parent, Entity toAttach){
|
||||||
ServerEntityTagUtils.removeTagFromEntity(toAttach, EntityTags.BONE_ATTACHED);
|
ServerEntityTagUtils.removeTagFromEntity(toAttach, EntityTags.BONE_ATTACHED);
|
||||||
toAttach.removeData(EntityDataStrings.ATTACH_ENTITY_IS_ATTACHED);
|
toAttach.removeData(EntityDataStrings.ATTACH_ENTITY_IS_ATTACHED);
|
||||||
@ -344,6 +442,11 @@ public class AttachUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detatches an entity on the client
|
||||||
|
* @param parent The parent entity
|
||||||
|
* @param toAttach The attached entity
|
||||||
|
*/
|
||||||
public static void clientDetatchEntityFromEntityAtBone(Entity parent, Entity toAttach){
|
public static void clientDetatchEntityFromEntityAtBone(Entity parent, Entity toAttach){
|
||||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(toAttach, EntityTags.BONE_ATTACHED);
|
Globals.clientSceneWrapper.getScene().removeEntityFromTag(toAttach, EntityTags.BONE_ATTACHED);
|
||||||
toAttach.removeData(EntityDataStrings.ATTACH_ENTITY_IS_ATTACHED);
|
toAttach.removeData(EntityDataStrings.ATTACH_ENTITY_IS_ATTACHED);
|
||||||
|
|||||||
@ -30,6 +30,7 @@ import electrosphere.entity.state.equip.ClientEquipState;
|
|||||||
import electrosphere.entity.state.equip.ServerEquipState;
|
import electrosphere.entity.state.equip.ServerEquipState;
|
||||||
import electrosphere.entity.state.gravity.ClientGravityTree;
|
import electrosphere.entity.state.gravity.ClientGravityTree;
|
||||||
import electrosphere.entity.state.gravity.ServerGravityTree;
|
import electrosphere.entity.state.gravity.ServerGravityTree;
|
||||||
|
import electrosphere.entity.state.hitbox.HitboxState;
|
||||||
import electrosphere.entity.state.idle.IdleTree;
|
import electrosphere.entity.state.idle.IdleTree;
|
||||||
import electrosphere.entity.state.idle.ServerIdleTree;
|
import electrosphere.entity.state.idle.ServerIdleTree;
|
||||||
import electrosphere.entity.state.inventory.ClientInventoryState;
|
import electrosphere.entity.state.inventory.ClientInventoryState;
|
||||||
@ -103,26 +104,26 @@ public class CreatureUtils {
|
|||||||
Actor creatureActor = EntityUtils.getActor(rVal);
|
Actor creatureActor = EntityUtils.getActor(rVal);
|
||||||
EntityUtils.setEntityType(rVal, ENTITY_TYPE_CREATURE);
|
EntityUtils.setEntityType(rVal, ENTITY_TYPE_CREATURE);
|
||||||
EntityUtils.setEntitySubtype(rVal, type);
|
EntityUtils.setEntitySubtype(rVal, type);
|
||||||
for(HitboxData hitboxdata : rawType.getHitboxes()){
|
|
||||||
List<Entity> hitboxList = new LinkedList<Entity>();
|
|
||||||
List<Entity> hurtboxList = new LinkedList<Entity>();
|
///
|
||||||
if(hitboxdata.getType().equals("hit")){
|
///
|
||||||
Entity hitbox = HitboxUtils.clientSpawnRegularHitbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius());
|
/// HITBOX DATA
|
||||||
Globals.clientHitboxManager.registerHitbox(hitbox);
|
///
|
||||||
hitboxList.add(hitbox);
|
///
|
||||||
} else if(hitboxdata.getType().equals("hurt")){
|
HitboxState.attachHitboxState(Globals.clientSceneWrapper.getHitboxManager(), rVal, rawType.getHitboxes());
|
||||||
Entity hurtbox = HitboxUtils.clientSpawnRegularHurtbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius());
|
|
||||||
Globals.clientHitboxManager.registerHitbox(hurtbox);
|
|
||||||
hurtboxList.add(hurtbox);
|
//
|
||||||
}
|
//
|
||||||
rVal.putData(EntityDataStrings.HITBOX_ASSOCIATED_LIST, hitboxList);
|
// PHYSICS
|
||||||
rVal.putData(EntityDataStrings.HURTBOX_ASSOCIATED_LIST, hurtboxList);
|
//
|
||||||
}
|
//
|
||||||
//Physics object
|
|
||||||
if(rawType.getCollidable() != null){
|
if(rawType.getCollidable() != null){
|
||||||
CollidableTemplate physicsTemplate = rawType.getCollidable();
|
CollidableTemplate physicsTemplate = rawType.getCollidable();
|
||||||
PhysicsEntityUtils.clientAttachCollidableTemplate(rVal, physicsTemplate);
|
PhysicsEntityUtils.clientAttachCollidableTemplate(rVal, physicsTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// MOVEMENT SYSTEMS
|
// MOVEMENT SYSTEMS
|
||||||
@ -390,21 +391,17 @@ public class CreatureUtils {
|
|||||||
EntityCreationUtils.makeEntityPoseable(rVal, rawType.getModelPath());
|
EntityCreationUtils.makeEntityPoseable(rVal, rawType.getModelPath());
|
||||||
|
|
||||||
PoseActor creatureActor = EntityUtils.getPoseActor(rVal);
|
PoseActor creatureActor = EntityUtils.getPoseActor(rVal);
|
||||||
for(HitboxData hitboxdata : rawType.getHitboxes()){
|
//
|
||||||
List<Entity> hitboxList = new LinkedList<Entity>();
|
//
|
||||||
List<Entity> hurtboxList = new LinkedList<Entity>();
|
// Hitbox stuff
|
||||||
if(hitboxdata.getType().equals("hit")){
|
//
|
||||||
Entity hitbox = HitboxUtils.serverSpawnRegularHitbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius());
|
//
|
||||||
realm.getHitboxManager().registerHitbox(hitbox);
|
HitboxState.attachHitboxState(realm.getHitboxManager(), rVal, rawType.getHitboxes());
|
||||||
hitboxList.add(hitbox);
|
//
|
||||||
} else if(hitboxdata.getType().equals("hurt")){
|
//
|
||||||
Entity hurtbox = HitboxUtils.serverSpawnRegularHurtbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius());
|
// Physics stuff
|
||||||
realm.getHitboxManager().registerHitbox(hurtbox);
|
//
|
||||||
hurtboxList.add(hurtbox);
|
//
|
||||||
}
|
|
||||||
rVal.putData(EntityDataStrings.HITBOX_ASSOCIATED_LIST, hitboxList);
|
|
||||||
rVal.putData(EntityDataStrings.HURTBOX_ASSOCIATED_LIST, hurtboxList);
|
|
||||||
}
|
|
||||||
if(rawType.getCollidable() != null){
|
if(rawType.getCollidable() != null){
|
||||||
CollidableTemplate physicsTemplate = rawType.getCollidable();
|
CollidableTemplate physicsTemplate = rawType.getCollidable();
|
||||||
PhysicsEntityUtils.serverAttachCollidableTemplate(realm, rVal, physicsTemplate);
|
PhysicsEntityUtils.serverAttachCollidableTemplate(realm, rVal, physicsTemplate);
|
||||||
|
|||||||
@ -26,6 +26,7 @@ import electrosphere.entity.state.collidable.ClientCollidableTree;
|
|||||||
import electrosphere.entity.state.collidable.ServerCollidableTree;
|
import electrosphere.entity.state.collidable.ServerCollidableTree;
|
||||||
import electrosphere.entity.state.gravity.ClientGravityTree;
|
import electrosphere.entity.state.gravity.ClientGravityTree;
|
||||||
import electrosphere.entity.state.gravity.ServerGravityTree;
|
import electrosphere.entity.state.gravity.ServerGravityTree;
|
||||||
|
import electrosphere.entity.state.hitbox.HitboxState;
|
||||||
import electrosphere.game.data.collidable.CollidableTemplate;
|
import electrosphere.game.data.collidable.CollidableTemplate;
|
||||||
import electrosphere.game.data.collidable.HitboxData;
|
import electrosphere.game.data.collidable.HitboxData;
|
||||||
import electrosphere.game.data.item.type.EquipWhitelist;
|
import electrosphere.game.data.item.type.EquipWhitelist;
|
||||||
@ -59,13 +60,7 @@ public class ItemUtils {
|
|||||||
rVal.putData(EntityDataStrings.ITEM_IS_WEAPON, true);
|
rVal.putData(EntityDataStrings.ITEM_IS_WEAPON, true);
|
||||||
WeaponData weaponData = item.getWeaponData();
|
WeaponData weaponData = item.getWeaponData();
|
||||||
if(weaponData.getHitboxes() != null){
|
if(weaponData.getHitboxes() != null){
|
||||||
List<Entity> hitboxList = new LinkedList<Entity>();
|
HitboxState.attachHitboxState(Globals.clientSceneWrapper.getHitboxManager(), rVal, weaponData.getHitboxes());
|
||||||
for(HitboxData hitboxdata : weaponData.getHitboxes()){
|
|
||||||
Entity hitbox = HitboxUtils.clientSpawnRegularHitbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius());
|
|
||||||
Globals.clientHitboxManager.registerHitbox(hitbox);
|
|
||||||
hitboxList.add(hitbox);
|
|
||||||
}
|
|
||||||
rVal.putData(EntityDataStrings.HITBOX_ASSOCIATED_LIST,hitboxList);
|
|
||||||
}
|
}
|
||||||
rVal.putData(EntityDataStrings.ITEM_WEAPON_CLASS,weaponData.getWeaponClass());
|
rVal.putData(EntityDataStrings.ITEM_WEAPON_CLASS,weaponData.getWeaponClass());
|
||||||
rVal.putData(EntityDataStrings.ITEM_WEAPON_DATA_RAW,weaponData);
|
rVal.putData(EntityDataStrings.ITEM_WEAPON_DATA_RAW,weaponData);
|
||||||
@ -138,13 +133,7 @@ public class ItemUtils {
|
|||||||
rVal.putData(EntityDataStrings.ITEM_IS_WEAPON, true);
|
rVal.putData(EntityDataStrings.ITEM_IS_WEAPON, true);
|
||||||
WeaponData weaponData = item.getWeaponData();
|
WeaponData weaponData = item.getWeaponData();
|
||||||
if(weaponData.getHitboxes() != null){
|
if(weaponData.getHitboxes() != null){
|
||||||
List<Entity> hitboxList = new LinkedList<Entity>();
|
HitboxState.attachHitboxState(realm.getHitboxManager(), rVal, weaponData.getHitboxes());
|
||||||
for(HitboxData hitboxdata : weaponData.getHitboxes()){
|
|
||||||
Entity hitbox = HitboxUtils.serverSpawnRegularHitbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius());
|
|
||||||
realm.getHitboxManager().registerHitbox(hitbox);
|
|
||||||
hitboxList.add(hitbox);
|
|
||||||
}
|
|
||||||
rVal.putData(EntityDataStrings.HITBOX_ASSOCIATED_LIST,hitboxList);
|
|
||||||
}
|
}
|
||||||
rVal.putData(EntityDataStrings.ITEM_WEAPON_CLASS,weaponData.getWeaponClass());
|
rVal.putData(EntityDataStrings.ITEM_WEAPON_CLASS,weaponData.getWeaponClass());
|
||||||
rVal.putData(EntityDataStrings.ITEM_WEAPON_DATA_RAW,weaponData);
|
rVal.putData(EntityDataStrings.ITEM_WEAPON_DATA_RAW,weaponData);
|
||||||
@ -378,13 +367,7 @@ public class ItemUtils {
|
|||||||
//this deregisters from all four & unhooks rigid bodies from the physics runtime
|
//this deregisters from all four & unhooks rigid bodies from the physics runtime
|
||||||
Globals.clientSceneWrapper.getCollisionEngine().destroyEntityThatHasPhysics(item);
|
Globals.clientSceneWrapper.getCollisionEngine().destroyEntityThatHasPhysics(item);
|
||||||
//destroy hitboxes
|
//destroy hitboxes
|
||||||
List<Entity> hitboxes = HitboxUtils.getHitboxAssociatedList(item);
|
HitboxState.destroyHitboxState(item);
|
||||||
if(hitboxes != null){
|
|
||||||
for(Entity hitbox : hitboxes){
|
|
||||||
Globals.clientHitboxManager.deregisterHitbox(hitbox);
|
|
||||||
HitboxUtils.getHitboxData(hitbox).setActive(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//destroy graphics
|
//destroy graphics
|
||||||
EntityUtils.cleanUpEntity(item);
|
EntityUtils.cleanUpEntity(item);
|
||||||
}
|
}
|
||||||
@ -401,13 +384,7 @@ public class ItemUtils {
|
|||||||
if(itemRealm != null){
|
if(itemRealm != null){
|
||||||
itemRealm.getCollisionEngine().destroyEntityThatHasPhysics(item);
|
itemRealm.getCollisionEngine().destroyEntityThatHasPhysics(item);
|
||||||
//destroy hitboxes
|
//destroy hitboxes
|
||||||
List<Entity> hitboxes = HitboxUtils.getHitboxAssociatedList(item);
|
HitboxState.destroyHitboxState(item);
|
||||||
if(hitboxes != null){
|
|
||||||
for(Entity hitbox : hitboxes){
|
|
||||||
itemRealm.getHitboxManager().deregisterHitbox(hitbox);
|
|
||||||
HitboxUtils.getHitboxData(hitbox).setActive(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//destroy graphics
|
//destroy graphics
|
||||||
EntityUtils.cleanUpEntity(item);
|
EntityUtils.cleanUpEntity(item);
|
||||||
|
|||||||
@ -16,7 +16,9 @@ import electrosphere.entity.Entity;
|
|||||||
import electrosphere.entity.EntityCreationUtils;
|
import electrosphere.entity.EntityCreationUtils;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.ServerEntityUtils;
|
import electrosphere.entity.ServerEntityUtils;
|
||||||
|
import electrosphere.entity.state.hitbox.HitboxState;
|
||||||
import electrosphere.entity.state.movement.ProjectileTree;
|
import electrosphere.entity.state.movement.ProjectileTree;
|
||||||
|
import electrosphere.game.data.collidable.HitboxData;
|
||||||
import electrosphere.game.data.projectile.ProjectileType;
|
import electrosphere.game.data.projectile.ProjectileType;
|
||||||
import electrosphere.server.datacell.Realm;
|
import electrosphere.server.datacell.Realm;
|
||||||
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
|
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
|
||||||
@ -92,11 +94,15 @@ public class ProjectileUtils {
|
|||||||
List<Entity> filter = new LinkedList<Entity>();
|
List<Entity> filter = new LinkedList<Entity>();
|
||||||
filter.add(parent);
|
filter.add(parent);
|
||||||
//collidable
|
//collidable
|
||||||
HitboxUtils.clientSpawnRegularHitbox(rVal, new HitboxPositionCallback() {
|
HitboxData hitboxData = new HitboxData();
|
||||||
public Vector3d getPosition(){
|
hitboxData.setRadius(rawType.getHitboxRadius());
|
||||||
return EntityUtils.getPosition(rVal);
|
HitboxState.attachHitboxStateWithCallback(Globals.clientSceneWrapper.getHitboxManager(), Globals.clientSceneWrapper.getCollisionEngine(), rVal, hitboxData,
|
||||||
|
new HitboxPositionCallback() {
|
||||||
|
public Vector3d getPosition(){
|
||||||
|
return EntityUtils.getPosition(rVal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, rawType.getHitboxRadius(), false, filter);
|
);
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,11 +129,15 @@ public class ProjectileUtils {
|
|||||||
List<Entity> filter = new LinkedList<Entity>();
|
List<Entity> filter = new LinkedList<Entity>();
|
||||||
filter.add(parent);
|
filter.add(parent);
|
||||||
//collidable
|
//collidable
|
||||||
HitboxUtils.serverSpawnRegularHitbox(rVal, new HitboxPositionCallback() {
|
HitboxData hitboxData = new HitboxData();
|
||||||
public Vector3d getPosition(){
|
hitboxData.setRadius(rawType.getHitboxRadius());
|
||||||
return EntityUtils.getPosition(rVal);
|
HitboxState.attachHitboxStateWithCallback(realm.getHitboxManager(), realm.getCollisionEngine(), rVal, hitboxData,
|
||||||
|
new HitboxPositionCallback() {
|
||||||
|
public Vector3d getPosition(){
|
||||||
|
return EntityUtils.getPosition(rVal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, rawType.getHitboxRadius(), false, filter);
|
);
|
||||||
|
|
||||||
|
|
||||||
//position entity
|
//position entity
|
||||||
|
|||||||
@ -5,8 +5,7 @@ import electrosphere.logger.LoggerInterface;
|
|||||||
import electrosphere.util.FileUtils;
|
import electrosphere.util.FileUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* User-defined settings
|
||||||
* @author amaterasu
|
|
||||||
*/
|
*/
|
||||||
public class UserSettings {
|
public class UserSettings {
|
||||||
|
|
||||||
@ -41,7 +40,8 @@ public class UserSettings {
|
|||||||
int renderResolutionY;
|
int renderResolutionY;
|
||||||
//debug
|
//debug
|
||||||
//debug visuals
|
//debug visuals
|
||||||
boolean graphicsDebugDrawCollisionSpheres;
|
boolean graphicsDebugDrawCollisionSpheresClient;
|
||||||
|
boolean graphicsDebugDrawCollisionSpheresServer;
|
||||||
boolean graphicsDebugDrawPhysicsObjects;
|
boolean graphicsDebugDrawPhysicsObjects;
|
||||||
boolean graphicsDebugDrawMovementVectors;
|
boolean graphicsDebugDrawMovementVectors;
|
||||||
boolean graphicsDebugDrawNavmesh;
|
boolean graphicsDebugDrawNavmesh;
|
||||||
@ -82,8 +82,12 @@ public class UserSettings {
|
|||||||
return graphicsPerformanceDrawShadows;
|
return graphicsPerformanceDrawShadows;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean graphicsDebugDrawCollisionSpheres() {
|
public boolean getGraphicsDebugDrawCollisionSpheresClient() {
|
||||||
return graphicsDebugDrawCollisionSpheres;
|
return graphicsDebugDrawCollisionSpheresClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getGraphicsDebugDrawCollisionSpheresServer() {
|
||||||
|
return graphicsDebugDrawCollisionSpheresServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean graphicsDebugDrawPhysicsObjects() {
|
public boolean graphicsDebugDrawPhysicsObjects() {
|
||||||
@ -131,8 +135,12 @@ public class UserSettings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setGraphicsDebugDrawCollisionSpheres(boolean draw){
|
public void setGraphicsDebugDrawCollisionSpheresClient(boolean draw){
|
||||||
this.graphicsDebugDrawCollisionSpheres = draw;
|
this.graphicsDebugDrawCollisionSpheresClient = draw;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGraphicsDebugDrawCollisionSpheresServer(boolean draw){
|
||||||
|
this.graphicsDebugDrawCollisionSpheresServer = draw;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGraphicsDebugDrawPhysicsObjects(boolean draw){
|
public void setGraphicsDebugDrawPhysicsObjects(boolean draw){
|
||||||
@ -178,7 +186,8 @@ public class UserSettings {
|
|||||||
rVal.gameplayPhysicsCellRadius = 2;
|
rVal.gameplayPhysicsCellRadius = 2;
|
||||||
|
|
||||||
//graphics settings
|
//graphics settings
|
||||||
rVal.graphicsDebugDrawCollisionSpheres = false;
|
rVal.graphicsDebugDrawCollisionSpheresClient = false;
|
||||||
|
rVal.graphicsDebugDrawCollisionSpheresServer = false;
|
||||||
rVal.graphicsDebugDrawMovementVectors = false;
|
rVal.graphicsDebugDrawMovementVectors = false;
|
||||||
rVal.graphicsDebugDrawPhysicsObjects = false;
|
rVal.graphicsDebugDrawPhysicsObjects = false;
|
||||||
rVal.graphicsDebugDrawNavmesh = false;
|
rVal.graphicsDebugDrawNavmesh = false;
|
||||||
|
|||||||
@ -4,25 +4,48 @@ import java.util.List;
|
|||||||
|
|
||||||
import electrosphere.game.data.collidable.HitboxData;
|
import electrosphere.game.data.collidable.HitboxData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data about a weapon
|
||||||
|
*/
|
||||||
public class WeaponData {
|
public class WeaponData {
|
||||||
|
|
||||||
|
//the class of weapon (ie sword, bow, etc)
|
||||||
String weaponClass;
|
String weaponClass;
|
||||||
|
//the hitboxes associated with the weapon
|
||||||
List<HitboxData> hitboxes;
|
List<HitboxData> hitboxes;
|
||||||
|
//the damage the weapon does
|
||||||
int damage;
|
int damage;
|
||||||
|
//the model for the projectile
|
||||||
String projectileModel;
|
String projectileModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the weapon class
|
||||||
|
* @return the weapon class
|
||||||
|
*/
|
||||||
public String getWeaponClass(){
|
public String getWeaponClass(){
|
||||||
return weaponClass;
|
return weaponClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of hitbox data
|
||||||
|
* @return the list of hitbox data
|
||||||
|
*/
|
||||||
public List<HitboxData> getHitboxes(){
|
public List<HitboxData> getHitboxes(){
|
||||||
return hitboxes;
|
return hitboxes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the projectile model
|
||||||
|
* @return the projectile model
|
||||||
|
*/
|
||||||
public String getProjectileModel(){
|
public String getProjectileModel(){
|
||||||
return projectileModel;
|
return projectileModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the damage dealt
|
||||||
|
* @return the damage dealt
|
||||||
|
*/
|
||||||
public int getDamage(){
|
public int getDamage(){
|
||||||
return damage;
|
return damage;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,8 @@ import electrosphere.collision.PhysicsEntityUtils;
|
|||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
|
import electrosphere.entity.state.attack.ClientAttackTree;
|
||||||
|
import electrosphere.entity.state.server.ServerPlayerViewDirTree;
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
import electrosphere.renderer.RenderingEngine;
|
import electrosphere.renderer.RenderingEngine;
|
||||||
import electrosphere.renderer.ui.imgui.ImGuiLinePlot;
|
import electrosphere.renderer.ui.imgui.ImGuiLinePlot;
|
||||||
@ -172,16 +174,35 @@ public class ImGuiWindowMacros {
|
|||||||
ImGui.text("Player Entity Details");
|
ImGui.text("Player Entity Details");
|
||||||
if(Globals.playerEntity != null){
|
if(Globals.playerEntity != null){
|
||||||
ImGui.text("Position: " + EntityUtils.getPosition(Globals.playerEntity));
|
ImGui.text("Position: " + EntityUtils.getPosition(Globals.playerEntity));
|
||||||
|
|
||||||
|
//server pos
|
||||||
|
int serverIdForClientEntity = Globals.clientSceneWrapper.mapClientToServerId(Globals.playerEntity.getId());
|
||||||
|
Entity serverPlayerEntity = EntityLookupUtils.getEntityById(serverIdForClientEntity);
|
||||||
|
ImGui.text("Position (Server): " + EntityUtils.getPosition(serverPlayerEntity));
|
||||||
|
|
||||||
|
//client-side tree stuff
|
||||||
DBody body = PhysicsEntityUtils.getDBody(Globals.playerEntity);
|
DBody body = PhysicsEntityUtils.getDBody(Globals.playerEntity);
|
||||||
|
ClientAttackTree attackTree = ClientAttackTree.getClientAttackTree(Globals.playerEntity);
|
||||||
if(body != null){
|
if(body != null){
|
||||||
ImGui.text("Velocity: " + body.getLinearVel());
|
ImGui.text("Velocity: " + body.getLinearVel());
|
||||||
ImGui.text("Force: " + body.getForce());
|
ImGui.text("Force: " + body.getForce());
|
||||||
ImGui.text("Angular Velocity: " + body.getAngularVel());
|
ImGui.text("Angular Velocity: " + body.getAngularVel());
|
||||||
ImGui.text("Torque: " + body.getTorque());
|
ImGui.text("Torque: " + body.getTorque());
|
||||||
ImGui.text("Move Vector: " + CreatureUtils.getFacingVector(Globals.playerEntity));
|
ImGui.text("Move Vector: " + CreatureUtils.getFacingVector(Globals.playerEntity));
|
||||||
Entity serverEntity = EntityLookupUtils.getEntityById(Globals.clientSceneWrapper.mapClientToServerId(Globals.playerEntity.getId()));
|
if(attackTree != null){
|
||||||
ImGui.text("Move Vector (Server): " + CreatureUtils.getFacingVector(serverEntity));
|
ImGui.text("Attack Tree State: " + attackTree.getState());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//server-side tree stuff
|
||||||
|
DBody serverBody = PhysicsEntityUtils.getDBody(serverPlayerEntity);
|
||||||
|
if(body != null){
|
||||||
|
ImGui.text("Velocity (Server): " + serverBody.getLinearVel());
|
||||||
|
ImGui.text("Force (Server): " + serverBody.getForce());
|
||||||
|
ImGui.text("Move Vector (Server): " + CreatureUtils.getFacingVector(serverPlayerEntity));
|
||||||
|
ImGui.text("Velocity (Server): " + CreatureUtils.getVelocity(serverPlayerEntity));
|
||||||
|
}
|
||||||
|
ImGui.text("View dir (Server): " + ServerPlayerViewDirTree.getTree(serverPlayerEntity).getPlayerViewDir());
|
||||||
}
|
}
|
||||||
if(ImGui.button("Toggle Player Camera Lock")){
|
if(ImGui.button("Toggle Player Camera Lock")){
|
||||||
Globals.cameraHandler.setTrackPlayerEntity(!Globals.cameraHandler.getTrackPlayerEntity());
|
Globals.cameraHandler.setTrackPlayerEntity(!Globals.cameraHandler.getTrackPlayerEntity());
|
||||||
|
|||||||
@ -273,15 +273,27 @@ public class MenuGeneratorsInGame {
|
|||||||
return false;
|
return false;
|
||||||
}});
|
}});
|
||||||
|
|
||||||
//label (toggle draw collision spheres)
|
//label (toggle draw client collision spheres)
|
||||||
Button toggleCollisionSpheresButton = new Button();
|
Button toggleClientCollisionSpheresButton = new Button();
|
||||||
Label toggleCollisionSpheresLabel = new Label(fontSize);
|
Label toggleClientCollisionSpheresLabel = new Label(fontSize);
|
||||||
toggleCollisionSpheresLabel.setText("Toggle draw collision spheres");
|
toggleClientCollisionSpheresLabel.setText("Toggle draw client collision spheres");
|
||||||
toggleCollisionSpheresButton.addChild(toggleCollisionSpheresLabel);
|
toggleClientCollisionSpheresButton.addChild(toggleClientCollisionSpheresLabel);
|
||||||
scrollable.addChild(toggleCollisionSpheresButton);
|
scrollable.addChild(toggleClientCollisionSpheresButton);
|
||||||
toggleCollisionSpheresButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
|
toggleClientCollisionSpheresButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
|
||||||
// Main.running = false;
|
// Main.running = false;
|
||||||
Globals.userSettings.setGraphicsDebugDrawCollisionSpheres(!Globals.userSettings.graphicsDebugDrawCollisionSpheres());
|
Globals.userSettings.setGraphicsDebugDrawCollisionSpheresClient(!Globals.userSettings.getGraphicsDebugDrawCollisionSpheresClient());
|
||||||
|
return false;
|
||||||
|
}});
|
||||||
|
|
||||||
|
//label (toggle draw server collision spheres)
|
||||||
|
Button toggleServerCollisionSpheresButton = new Button();
|
||||||
|
Label toggleServerCollisionSpheresLabel = new Label(fontSize);
|
||||||
|
toggleServerCollisionSpheresLabel.setText("Toggle draw server collision spheres");
|
||||||
|
toggleServerCollisionSpheresButton.addChild(toggleServerCollisionSpheresLabel);
|
||||||
|
scrollable.addChild(toggleServerCollisionSpheresButton);
|
||||||
|
toggleServerCollisionSpheresButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
|
||||||
|
// Main.running = false;
|
||||||
|
Globals.userSettings.setGraphicsDebugDrawCollisionSpheresServer(!Globals.userSettings.getGraphicsDebugDrawCollisionSpheresServer());
|
||||||
return false;
|
return false;
|
||||||
}});
|
}});
|
||||||
|
|
||||||
|
|||||||
@ -143,6 +143,7 @@ public class EntityProtocol {
|
|||||||
// TODO
|
// TODO
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
case UPDATEENTITYVIEWDIR:
|
||||||
case KILL:
|
case KILL:
|
||||||
case SETPOSITION:
|
case SETPOSITION:
|
||||||
case SETFACING:
|
case SETFACING:
|
||||||
|
|||||||
@ -38,7 +38,7 @@ public class InventoryProtocol {
|
|||||||
String equipPointName = message.getequipPointId();
|
String equipPointName = message.getequipPointId();
|
||||||
EquipPoint equipPoint = equipState.getEquipPoint(equipPointName);
|
EquipPoint equipPoint = equipState.getEquipPoint(equipPointName);
|
||||||
//attach
|
//attach
|
||||||
equipState.clientAttemptEquip(inWorldEntity, equipPoint);
|
equipState.attemptEquip(inWorldEntity, equipPoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -9,10 +9,13 @@ public class SynchronizationProtocol {
|
|||||||
Globals.profiler.beginCpuSample("SynchronizationProtocol.handleSynchronizationMessage");
|
Globals.profiler.beginCpuSample("SynchronizationProtocol.handleSynchronizationMessage");
|
||||||
switch(message.getMessageSubtype()){
|
switch(message.getMessageSubtype()){
|
||||||
case UPDATECLIENTSTATE:
|
case UPDATECLIENTSTATE:
|
||||||
|
case UPDATECLIENTSTRINGSTATE:
|
||||||
case ATTACHTREE:
|
case ATTACHTREE:
|
||||||
case DETATCHTREE:
|
case DETATCHTREE:
|
||||||
Globals.clientSynchronizationManager.pushMessage(message);
|
Globals.clientSynchronizationManager.pushMessage(message);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException("Received synchronization message on the client of unsupported type: " + message.getMessageSubtype());
|
||||||
}
|
}
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,6 +28,7 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
SETBTREEPROPERTYENUM,
|
SETBTREEPROPERTYENUM,
|
||||||
ATTACHENTITYTOENTITY,
|
ATTACHENTITYTOENTITY,
|
||||||
SPAWNFOLIAGESEED,
|
SPAWNFOLIAGESEED,
|
||||||
|
UPDATEENTITYVIEWDIR,
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityMessageType messageType;
|
EntityMessageType messageType;
|
||||||
@ -386,6 +387,12 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
return EntityMessage.canParseattachEntityToEntityMessage(byteBuffer);
|
return EntityMessage.canParseattachEntityToEntityMessage(byteBuffer);
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SPAWNFOLIAGESEED:
|
case TypeBytes.ENTITY_MESSAGE_TYPE_SPAWNFOLIAGESEED:
|
||||||
return EntityMessage.canParseSpawnFoliageSeedMessage(byteBuffer);
|
return EntityMessage.canParseSpawnFoliageSeedMessage(byteBuffer);
|
||||||
|
case TypeBytes.ENTITY_MESSAGE_TYPE_UPDATEENTITYVIEWDIR:
|
||||||
|
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_UPDATEENTITYVIEWDIR_SIZE){
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1010,6 +1017,28 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static EntityMessage parseupdateEntityViewDirMessage(CircularByteBuffer byteBuffer){
|
||||||
|
EntityMessage rVal = new EntityMessage(EntityMessageType.UPDATEENTITYVIEWDIR);
|
||||||
|
stripPacketHeader(byteBuffer);
|
||||||
|
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
|
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||||
|
rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||||
|
rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||||
|
rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EntityMessage constructupdateEntityViewDirMessage(int entityID,long time,double positionX,double positionY,double positionZ){
|
||||||
|
EntityMessage rVal = new EntityMessage(EntityMessageType.UPDATEENTITYVIEWDIR);
|
||||||
|
rVal.setentityID(entityID);
|
||||||
|
rVal.settime(time);
|
||||||
|
rVal.setpositionX(positionX);
|
||||||
|
rVal.setpositionY(positionY);
|
||||||
|
rVal.setpositionZ(positionZ);
|
||||||
|
rVal.serialize();
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void serialize(){
|
void serialize(){
|
||||||
byte[] intValues = new byte[8];
|
byte[] intValues = new byte[8];
|
||||||
@ -1566,6 +1595,33 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
rawBytes[34+creatureTemplate.length()+i] = intValues[i];
|
rawBytes[34+creatureTemplate.length()+i] = intValues[i];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case UPDATEENTITYVIEWDIR:
|
||||||
|
rawBytes = new byte[2+4+8+8+8+8];
|
||||||
|
//message header
|
||||||
|
rawBytes[0] = TypeBytes.MESSAGE_TYPE_ENTITY;
|
||||||
|
//entity messaage header
|
||||||
|
rawBytes[1] = TypeBytes.ENTITY_MESSAGE_TYPE_UPDATEENTITYVIEWDIR;
|
||||||
|
intValues = ByteStreamUtils.serializeIntToBytes(entityID);
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
rawBytes[2+i] = intValues[i];
|
||||||
|
}
|
||||||
|
intValues = ByteStreamUtils.serializeLongToBytes(time);
|
||||||
|
for(int i = 0; i < 8; i++){
|
||||||
|
rawBytes[6+i] = intValues[i];
|
||||||
|
}
|
||||||
|
intValues = ByteStreamUtils.serializeDoubleToBytes(positionX);
|
||||||
|
for(int i = 0; i < 8; i++){
|
||||||
|
rawBytes[14+i] = intValues[i];
|
||||||
|
}
|
||||||
|
intValues = ByteStreamUtils.serializeDoubleToBytes(positionY);
|
||||||
|
for(int i = 0; i < 8; i++){
|
||||||
|
rawBytes[22+i] = intValues[i];
|
||||||
|
}
|
||||||
|
intValues = ByteStreamUtils.serializeDoubleToBytes(positionZ);
|
||||||
|
for(int i = 0; i < 8; i++){
|
||||||
|
rawBytes[30+i] = intValues[i];
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
serialized = true;
|
serialized = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -141,6 +141,11 @@ SYNCHRONIZATION_MESSAGE,
|
|||||||
rVal = EntityMessage.parseSpawnFoliageSeedMessage(byteBuffer);
|
rVal = EntityMessage.parseSpawnFoliageSeedMessage(byteBuffer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case TypeBytes.ENTITY_MESSAGE_TYPE_UPDATEENTITYVIEWDIR:
|
||||||
|
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
|
rVal = EntityMessage.parseupdateEntityViewDirMessage(byteBuffer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.MESSAGE_TYPE_LORE:
|
case TypeBytes.MESSAGE_TYPE_LORE:
|
||||||
|
|||||||
@ -37,6 +37,7 @@ Message categories
|
|||||||
public static final byte ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYENUM = 17;
|
public static final byte ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYENUM = 17;
|
||||||
public static final byte ENTITY_MESSAGE_TYPE_ATTACHENTITYTOENTITY = 18;
|
public static final byte ENTITY_MESSAGE_TYPE_ATTACHENTITYTOENTITY = 18;
|
||||||
public static final byte ENTITY_MESSAGE_TYPE_SPAWNFOLIAGESEED = 19;
|
public static final byte ENTITY_MESSAGE_TYPE_SPAWNFOLIAGESEED = 19;
|
||||||
|
public static final byte ENTITY_MESSAGE_TYPE_UPDATEENTITYVIEWDIR = 20;
|
||||||
/*
|
/*
|
||||||
Entity packet sizes
|
Entity packet sizes
|
||||||
*/
|
*/
|
||||||
@ -54,6 +55,7 @@ Message categories
|
|||||||
public static final byte ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYFLOAT_SIZE = 26;
|
public static final byte ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYFLOAT_SIZE = 26;
|
||||||
public static final byte ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYDOUBLE_SIZE = 30;
|
public static final byte ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYDOUBLE_SIZE = 30;
|
||||||
public static final byte ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYENUM_SIZE = 26;
|
public static final byte ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYENUM_SIZE = 26;
|
||||||
|
public static final byte ENTITY_MESSAGE_TYPE_UPDATEENTITYVIEWDIR_SIZE = 38;
|
||||||
/*
|
/*
|
||||||
Lore subcategories
|
Lore subcategories
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,24 +1,12 @@
|
|||||||
package electrosphere.net.server.protocol;
|
package electrosphere.net.server.protocol;
|
||||||
|
|
||||||
import org.joml.Vector3d;
|
|
||||||
import org.joml.Vector3f;
|
|
||||||
import org.joml.Vector3i;
|
|
||||||
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.engine.Main;
|
|
||||||
import electrosphere.entity.Entity;
|
|
||||||
import electrosphere.entity.EntityUtils;
|
|
||||||
import electrosphere.entity.ServerEntityUtils;
|
|
||||||
import electrosphere.entity.state.ironsight.IronSightTree;
|
|
||||||
import electrosphere.entity.types.collision.CollisionObjUtils;
|
|
||||||
import electrosphere.entity.types.creature.CreatureTemplate;
|
import electrosphere.entity.types.creature.CreatureTemplate;
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
|
||||||
import electrosphere.net.parser.net.message.CharacterMessage;
|
import electrosphere.net.parser.net.message.CharacterMessage;
|
||||||
import electrosphere.net.parser.net.message.PlayerMessage;
|
import electrosphere.net.parser.net.message.PlayerMessage;
|
||||||
import electrosphere.net.parser.net.message.TerrainMessage;
|
import electrosphere.net.parser.net.message.TerrainMessage;
|
||||||
import electrosphere.net.server.ServerConnectionHandler;
|
import electrosphere.net.server.ServerConnectionHandler;
|
||||||
import electrosphere.net.server.player.Player;
|
import electrosphere.server.character.PlayerCharacterCreation;
|
||||||
import electrosphere.server.datacell.Realm;
|
|
||||||
import electrosphere.util.Utilities;
|
import electrosphere.util.Utilities;
|
||||||
|
|
||||||
public class CharacterProtocol {
|
public class CharacterProtocol {
|
||||||
@ -49,38 +37,12 @@ public class CharacterProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void spawnPlayerCharacter(ServerConnectionHandler connectionHandler){
|
/**
|
||||||
Player playerObject = Globals.playerManager.getPlayerFromId(connectionHandler.getPlayerId());
|
* Spawns the player's entity
|
||||||
//get template
|
* @param connectionHandler The connection handler for the player
|
||||||
CreatureTemplate template = connectionHandler.getCurrentCreatureTemplate();
|
*/
|
||||||
String raceName = template.getCreatureType();
|
|
||||||
//spawn player in world
|
|
||||||
Realm realm = Globals.realmManager.getRealms().iterator().next();
|
|
||||||
Entity newPlayerEntity = CreatureUtils.serverSpawnBasicCreature(realm,new Vector3d(Globals.spawnPoint.x,Globals.spawnPoint.y,Globals.spawnPoint.z),raceName,template);
|
|
||||||
int playerCharacterId = newPlayerEntity.getId();
|
|
||||||
connectionHandler.setPlayerCharacterId(playerCharacterId);
|
|
||||||
CreatureUtils.setControllerPlayerId(newPlayerEntity, connectionHandler.getPlayerId());
|
|
||||||
//attach player object to player character
|
|
||||||
playerObject.setPlayerEntity(newPlayerEntity);
|
|
||||||
playerObject.setWorldPos(new Vector3i(
|
|
||||||
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.x),
|
|
||||||
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.y),
|
|
||||||
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.z)
|
|
||||||
));
|
|
||||||
// System.out.println(EntityUtils.getRotation(newPlayerCharacter).set(0,1,0,1).normalize());
|
|
||||||
realm.getDataCellManager().addPlayerToRealm(playerObject);
|
|
||||||
// IronSightTree.attachIronSightTree(newPlayerEntity);
|
|
||||||
// //spawn player sword
|
|
||||||
// Entity sword = ItemUtils.spawnBasicItem("Katana");
|
|
||||||
// AttachUtils.attachEntityToEntityAtBone(newPlayerCharacter, sword, "Bone.031");
|
|
||||||
//set controller id
|
|
||||||
if(playerObject == Globals.clientPlayer){
|
|
||||||
Globals.playerEntity = newPlayerEntity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void spawnClientEntity(ServerConnectionHandler connectionHandler){
|
static void spawnClientEntity(ServerConnectionHandler connectionHandler){
|
||||||
spawnPlayerCharacter(connectionHandler);
|
PlayerCharacterCreation.spawnPlayerCharacter(connectionHandler);
|
||||||
//set client initial discrete position
|
//set client initial discrete position
|
||||||
connectionHandler.addMessagetoOutgoingQueue(
|
connectionHandler.addMessagetoOutgoingQueue(
|
||||||
PlayerMessage.constructSetInitialDiscretePositionMessage(
|
PlayerMessage.constructSetInitialDiscretePositionMessage(
|
||||||
@ -93,8 +55,6 @@ public class CharacterProtocol {
|
|||||||
connectionHandler.addMessagetoOutgoingQueue(
|
connectionHandler.addMessagetoOutgoingQueue(
|
||||||
TerrainMessage.constructSpawnPositionMessage(Globals.spawnPoint.x, Globals.spawnPoint.y, Globals.spawnPoint.z)
|
TerrainMessage.constructSpawnPositionMessage(Globals.spawnPoint.x, Globals.spawnPoint.y, Globals.spawnPoint.z)
|
||||||
);
|
);
|
||||||
//tell them what player stats they are
|
|
||||||
// connectionHandler.addMessagetoOutgoingQueue(PlayerMessage.constructSet_IDMessage(connectionHandler.getPlayerCharacterId()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,11 @@
|
|||||||
package electrosphere.net.server.protocol;
|
package electrosphere.net.server.protocol;
|
||||||
|
|
||||||
import electrosphere.engine.Globals;
|
import org.joml.Vector3d;
|
||||||
import electrosphere.engine.Main;
|
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityUtils;
|
|
||||||
import electrosphere.entity.state.attack.ServerAttackTree;
|
import electrosphere.entity.state.attack.ServerAttackTree;
|
||||||
import electrosphere.entity.types.attach.AttachUtils;
|
import electrosphere.entity.state.server.ServerPlayerViewDirTree;
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
import electrosphere.entity.types.item.ItemUtils;
|
|
||||||
import electrosphere.logger.LoggerInterface;
|
|
||||||
import electrosphere.net.NetUtils;
|
|
||||||
import electrosphere.net.parser.net.message.EntityMessage;
|
import electrosphere.net.parser.net.message.EntityMessage;
|
||||||
import electrosphere.net.server.ServerConnectionHandler;
|
import electrosphere.net.server.ServerConnectionHandler;
|
||||||
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
||||||
@ -45,6 +41,12 @@ public class EntityProtocol {
|
|||||||
ServerAttackTree.getServerAttackTree(targetEntity).addNetworkMessage(message);
|
ServerAttackTree.getServerAttackTree(targetEntity).addNetworkMessage(message);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
case UPDATEENTITYVIEWDIR: {
|
||||||
|
targetEntity = EntityLookupUtils.getEntityById(message.getentityID());
|
||||||
|
if(targetEntity != null && ServerPlayerViewDirTree.hasTree(targetEntity)){
|
||||||
|
ServerPlayerViewDirTree.getTree(targetEntity).setPlayerViewDir(new Vector3d(message.getpositionX(),message.getpositionY(),message.getpositionZ()),message.gettime());
|
||||||
|
}
|
||||||
|
} break;
|
||||||
//ignore stack
|
//ignore stack
|
||||||
case KILL:
|
case KILL:
|
||||||
case SPAWNCREATURE:
|
case SPAWNCREATURE:
|
||||||
@ -54,6 +56,13 @@ public class EntityProtocol {
|
|||||||
case SETFACING:
|
case SETFACING:
|
||||||
case SETPOSITION:
|
case SETPOSITION:
|
||||||
case SETPROPERTY:
|
case SETPROPERTY:
|
||||||
|
case SETBTREEPROPERTYDOUBLE:
|
||||||
|
case SETBTREEPROPERTYENUM:
|
||||||
|
case SETBTREEPROPERTYFLOAT:
|
||||||
|
case SETBTREEPROPERTYINT:
|
||||||
|
case SETBTREEPROPERTYSTRING:
|
||||||
|
case SPAWNFOLIAGESEED:
|
||||||
|
case SPAWNITEM:
|
||||||
//silently ignore
|
//silently ignore
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -92,7 +92,15 @@ public class Actor {
|
|||||||
return -1.0f;
|
return -1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if an animation is being played on any meshes
|
||||||
|
* @param animationName The animation name
|
||||||
|
* @return true if the animation is being played on any meshes, false if the provided animation name is null or the animation is not being played on any meshes
|
||||||
|
*/
|
||||||
public boolean isPlayingAnimation(String animationName){
|
public boolean isPlayingAnimation(String animationName){
|
||||||
|
if(animationName == null){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
for(ActorAnimationMask mask : animationQueue){
|
for(ActorAnimationMask mask : animationQueue){
|
||||||
if(mask.getAnimationName().contains(animationName)){
|
if(mask.getAnimationName().contains(animationName)){
|
||||||
return true;
|
return true;
|
||||||
@ -255,6 +263,12 @@ public class Actor {
|
|||||||
return modelPath;
|
return modelPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the position of a bone
|
||||||
|
* @param boneName The name of the bone
|
||||||
|
* @return The vector3f containing the position of the bone, or a vector of (0,0,0) if the model lookup fails
|
||||||
|
* //TODO: refactor to make failure more transparent (both for model not existing and bone not existing)
|
||||||
|
*/
|
||||||
public Vector3f getBonePosition(String boneName){
|
public Vector3f getBonePosition(String boneName){
|
||||||
Vector3f rVal = new Vector3f();
|
Vector3f rVal = new Vector3f();
|
||||||
Model model = Globals.assetManager.fetchModel(modelPath);
|
Model model = Globals.assetManager.fetchModel(modelPath);
|
||||||
|
|||||||
@ -5,12 +5,15 @@ import electrosphere.entity.Entity;
|
|||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Utils for dealing with actors
|
||||||
* @author amaterasu
|
|
||||||
*/
|
*/
|
||||||
public class ActorUtils {
|
public class ActorUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an actor object and queues the model path
|
||||||
|
* @param modelPath The model path
|
||||||
|
* @return The actor object
|
||||||
|
*/
|
||||||
public static Actor createActorFromModelPath(String modelPath){
|
public static Actor createActorFromModelPath(String modelPath){
|
||||||
Actor rVal = new Actor(modelPath);
|
Actor rVal = new Actor(modelPath);
|
||||||
Globals.assetManager.addModelPathToQueue(modelPath);
|
Globals.assetManager.addModelPathToQueue(modelPath);
|
||||||
@ -24,7 +27,7 @@ public class ActorUtils {
|
|||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static void applyBlenderTransformer(Entity actorEntity){
|
public static void applyBlenderTransformer(Entity actorEntity){
|
||||||
Actor entityActor = EntityUtils.getActor(actorEntity);
|
// Actor entityActor = EntityUtils.getActor(actorEntity);
|
||||||
// entityActor.setAnimationScalar(60f); //should be the value of the fps i think
|
// entityActor.setAnimationScalar(60f); //should be the value of the fps i think
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,20 +6,24 @@ import org.joml.Quaternionf;
|
|||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import org.lwjgl.opengl.GL40;
|
import org.lwjgl.opengl.GL40;
|
||||||
|
import org.ode4j.ode.DGeom;
|
||||||
|
import org.ode4j.ode.DSphere;
|
||||||
|
|
||||||
|
import electrosphere.collision.PhysicsUtils;
|
||||||
import electrosphere.collision.collidable.Collidable;
|
import electrosphere.collision.collidable.Collidable;
|
||||||
import electrosphere.collision.hitbox.HitboxUtils;
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
|
import electrosphere.entity.state.hitbox.HitboxState;
|
||||||
import electrosphere.entity.types.camera.CameraEntityUtils;
|
import electrosphere.entity.types.camera.CameraEntityUtils;
|
||||||
import electrosphere.game.data.collidable.CollidableTemplate;
|
import electrosphere.game.data.collidable.CollidableTemplate;
|
||||||
import electrosphere.game.data.collidable.HitboxData;
|
|
||||||
import electrosphere.renderer.OpenGLState;
|
import electrosphere.renderer.OpenGLState;
|
||||||
import electrosphere.renderer.RenderPipelineState;
|
import electrosphere.renderer.RenderPipelineState;
|
||||||
import electrosphere.renderer.RenderingEngine;
|
import electrosphere.renderer.RenderingEngine;
|
||||||
import electrosphere.renderer.model.Model;
|
import electrosphere.renderer.model.Model;
|
||||||
|
import electrosphere.server.datacell.Realm;
|
||||||
|
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
||||||
import electrosphere.server.pathfinding.navmesh.NavCube;
|
import electrosphere.server.pathfinding.navmesh.NavCube;
|
||||||
import electrosphere.server.pathfinding.navmesh.NavMesh;
|
import electrosphere.server.pathfinding.navmesh.NavMesh;
|
||||||
import electrosphere.server.pathfinding.navmesh.NavShape;
|
import electrosphere.server.pathfinding.navmesh.NavShape;
|
||||||
@ -56,44 +60,89 @@ public class DebugContentPipeline implements RenderPipeline {
|
|||||||
|
|
||||||
Matrix4d modelTransformMatrix = new Matrix4d();
|
Matrix4d modelTransformMatrix = new Matrix4d();
|
||||||
|
|
||||||
if(Globals.userSettings.graphicsDebugDrawCollisionSpheres()){
|
if(Globals.userSettings.getGraphicsDebugDrawCollisionSpheresClient()){
|
||||||
for(Entity currentHitbox : Globals.clientHitboxManager.getAllHitboxes()){
|
Model hitboxModel;
|
||||||
if((boolean)currentHitbox.getData(EntityDataStrings.DATA_STRING_DRAW)){
|
for(HitboxState hitboxState : Globals.clientSceneWrapper.getHitboxManager().getAllHitboxes()){
|
||||||
Model hitboxModel;
|
for(String boneName : hitboxState.getBones()){
|
||||||
HitboxData data = HitboxUtils.getHitboxData(currentHitbox);
|
DGeom geom = hitboxState.getGeometry(boneName);
|
||||||
if(data.isActive()){
|
if(geom instanceof DSphere){
|
||||||
if(data.getType().equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT)){
|
DSphere sphereView = (DSphere)geom;
|
||||||
if((hitboxModel = Globals.assetManager.fetchModel("Models/basic/geometry/unitsphere.fbx")) != null){
|
if((hitboxModel = Globals.assetManager.fetchModel("Models/basic/geometry/unitsphere.glb")) != null){
|
||||||
Vector3d position = EntityUtils.getPosition(currentHitbox);
|
Vector3d position = PhysicsUtils.odeVecToJomlVec(sphereView.getPosition());
|
||||||
//calculate camera-modified vector3f
|
//calculate camera-modified vector3f
|
||||||
Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
||||||
modelTransformMatrix.identity();
|
|
||||||
modelTransformMatrix.translate(cameraModifiedPosition);
|
|
||||||
// modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere
|
|
||||||
modelTransformMatrix.scale(data.getRadius() * 2);
|
|
||||||
hitboxModel.setModelMatrix(modelTransformMatrix);
|
|
||||||
hitboxModel.draw(renderPipelineState,openGLState);
|
|
||||||
}
|
|
||||||
} else if(data.getType().equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT)){
|
|
||||||
if((hitboxModel = Globals.assetManager.fetchModel("Models/basic/geometry/unitsphere_1.fbx")) != null){
|
|
||||||
Vector3d position = EntityUtils.getPosition(currentHitbox);
|
|
||||||
//calculate camera-modified vector3f
|
|
||||||
Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
|
||||||
modelTransformMatrix.identity();
|
|
||||||
modelTransformMatrix.translate(cameraModifiedPosition);
|
|
||||||
// modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere
|
|
||||||
modelTransformMatrix.scale(data.getRadius() * 2);
|
|
||||||
hitboxModel.setModelMatrix(modelTransformMatrix);
|
|
||||||
hitboxModel.draw(renderPipelineState,openGLState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if((hitboxModel = Globals.assetManager.fetchModel("Models/basic/geometry/unitsphere_grey.fbx")) != null){
|
|
||||||
Vector3d position = EntityUtils.getPosition(currentHitbox);
|
|
||||||
modelTransformMatrix.identity();
|
modelTransformMatrix.identity();
|
||||||
modelTransformMatrix.translate(new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)));
|
modelTransformMatrix.translate(cameraModifiedPosition);
|
||||||
// modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere
|
// modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere
|
||||||
modelTransformMatrix.scale(data.getRadius() * 2);
|
modelTransformMatrix.scale(sphereView.getRadius() * 2);
|
||||||
|
hitboxModel.setModelMatrix(modelTransformMatrix);
|
||||||
|
hitboxModel.draw(renderPipelineState,openGLState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// for(Entity currentHitbox : Globals.clientHitboxManager.getAllHitboxes()){
|
||||||
|
// if((boolean)currentHitbox.getData(EntityDataStrings.DATA_STRING_DRAW)){
|
||||||
|
// Model hitboxModel;
|
||||||
|
// HitboxData data = HitboxUtils.getHitboxData(currentHitbox);
|
||||||
|
// if(data.isActive()){
|
||||||
|
// if(data.getType().equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT)){
|
||||||
|
// if((hitboxModel = Globals.assetManager.fetchModel("Models/basic/geometry/unitsphere.fbx")) != null){
|
||||||
|
// Vector3d position = EntityUtils.getPosition(currentHitbox);
|
||||||
|
// //calculate camera-modified vector3f
|
||||||
|
// Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
||||||
|
// modelTransformMatrix.identity();
|
||||||
|
// modelTransformMatrix.translate(cameraModifiedPosition);
|
||||||
|
// // modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere
|
||||||
|
// modelTransformMatrix.scale(data.getRadius() * 2);
|
||||||
|
// hitboxModel.setModelMatrix(modelTransformMatrix);
|
||||||
|
// hitboxModel.draw(renderPipelineState,openGLState);
|
||||||
|
// }
|
||||||
|
// } else if(data.getType().equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT)){
|
||||||
|
// if((hitboxModel = Globals.assetManager.fetchModel("Models/basic/geometry/unitsphere_1.fbx")) != null){
|
||||||
|
// Vector3d position = EntityUtils.getPosition(currentHitbox);
|
||||||
|
// //calculate camera-modified vector3f
|
||||||
|
// Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
||||||
|
// modelTransformMatrix.identity();
|
||||||
|
// modelTransformMatrix.translate(cameraModifiedPosition);
|
||||||
|
// // modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere
|
||||||
|
// modelTransformMatrix.scale(data.getRadius() * 2);
|
||||||
|
// hitboxModel.setModelMatrix(modelTransformMatrix);
|
||||||
|
// hitboxModel.draw(renderPipelineState,openGLState);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// if((hitboxModel = Globals.assetManager.fetchModel("Models/basic/geometry/unitsphere_grey.fbx")) != null){
|
||||||
|
// Vector3d position = EntityUtils.getPosition(currentHitbox);
|
||||||
|
// modelTransformMatrix.identity();
|
||||||
|
// modelTransformMatrix.translate(new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)));
|
||||||
|
// // modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere
|
||||||
|
// modelTransformMatrix.scale(data.getRadius() * 2);
|
||||||
|
// hitboxModel.setModelMatrix(modelTransformMatrix);
|
||||||
|
// hitboxModel.draw(renderPipelineState,openGLState);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
if(Globals.userSettings.getGraphicsDebugDrawCollisionSpheresServer()){
|
||||||
|
Model hitboxModel;
|
||||||
|
int serverIdForClientEntity = Globals.clientSceneWrapper.mapClientToServerId(Globals.playerEntity.getId());
|
||||||
|
Entity serverPlayerEntity = EntityLookupUtils.getEntityById(serverIdForClientEntity);
|
||||||
|
Realm playerRealm = Globals.realmManager.getEntityRealm(serverPlayerEntity);
|
||||||
|
for(HitboxState hitboxState : playerRealm.getHitboxManager().getAllHitboxes()){
|
||||||
|
for(String boneName : hitboxState.getBones()){
|
||||||
|
DGeom geom = hitboxState.getGeometry(boneName);
|
||||||
|
if(geom instanceof DSphere){
|
||||||
|
DSphere sphereView = (DSphere)geom;
|
||||||
|
if((hitboxModel = Globals.assetManager.fetchModel("Models/basic/geometry/unitsphere.glb")) != null){
|
||||||
|
Vector3d position = PhysicsUtils.odeVecToJomlVec(sphereView.getPosition());
|
||||||
|
//calculate camera-modified vector3f
|
||||||
|
Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
||||||
|
modelTransformMatrix.identity();
|
||||||
|
modelTransformMatrix.translate(cameraModifiedPosition);
|
||||||
|
// modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere
|
||||||
|
modelTransformMatrix.scale(sphereView.getRadius() * 2);
|
||||||
hitboxModel.setModelMatrix(modelTransformMatrix);
|
hitboxModel.setModelMatrix(modelTransformMatrix);
|
||||||
hitboxModel.draw(renderPipelineState,openGLState);
|
hitboxModel.draw(renderPipelineState,openGLState);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,7 +43,9 @@ public class FirstPersonItemsPipeline implements RenderPipeline {
|
|||||||
public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) {
|
public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) {
|
||||||
|
|
||||||
//update logic
|
//update logic
|
||||||
updateFirstPersonModelPosition(Globals.firstPersonEntity);
|
if(Globals.firstPersonEntity != null){
|
||||||
|
updateFirstPersonModelPosition(Globals.firstPersonEntity);
|
||||||
|
}
|
||||||
|
|
||||||
//setup opengl state
|
//setup opengl state
|
||||||
this.firstPersonFramebuffer.bind();
|
this.firstPersonFramebuffer.bind();
|
||||||
|
|||||||
@ -0,0 +1,59 @@
|
|||||||
|
package electrosphere.server.character;
|
||||||
|
|
||||||
|
import org.joml.Vector3d;
|
||||||
|
import org.joml.Vector3i;
|
||||||
|
|
||||||
|
import electrosphere.engine.Globals;
|
||||||
|
import electrosphere.entity.Entity;
|
||||||
|
import electrosphere.entity.state.server.ServerPlayerViewDirTree;
|
||||||
|
import electrosphere.entity.types.creature.CreatureTemplate;
|
||||||
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
|
import electrosphere.net.server.ServerConnectionHandler;
|
||||||
|
import electrosphere.net.server.player.Player;
|
||||||
|
import electrosphere.server.datacell.Realm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deals with spawning player characters
|
||||||
|
*/
|
||||||
|
public class PlayerCharacterCreation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spawns the player's character
|
||||||
|
* @param connectionHandler The connection handler of the player
|
||||||
|
*/
|
||||||
|
public static void spawnPlayerCharacter(ServerConnectionHandler connectionHandler){
|
||||||
|
Player playerObject = Globals.playerManager.getPlayerFromId(connectionHandler.getPlayerId());
|
||||||
|
//get template
|
||||||
|
CreatureTemplate template = connectionHandler.getCurrentCreatureTemplate();
|
||||||
|
String raceName = template.getCreatureType();
|
||||||
|
//spawn entity in world
|
||||||
|
Realm realm = Globals.realmManager.getRealms().iterator().next();
|
||||||
|
Entity newPlayerEntity = CreatureUtils.serverSpawnBasicCreature(realm,new Vector3d(Globals.spawnPoint.x,Globals.spawnPoint.y,Globals.spawnPoint.z),raceName,template);
|
||||||
|
int playerCharacterId = newPlayerEntity.getId();
|
||||||
|
connectionHandler.setPlayerCharacterId(playerCharacterId);
|
||||||
|
CreatureUtils.setControllerPlayerId(newPlayerEntity, connectionHandler.getPlayerId());
|
||||||
|
//custom player btrees
|
||||||
|
addPlayerServerBTrees(newPlayerEntity);
|
||||||
|
//attach player object to player character
|
||||||
|
playerObject.setPlayerEntity(newPlayerEntity);
|
||||||
|
playerObject.setWorldPos(new Vector3i(
|
||||||
|
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.x),
|
||||||
|
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.y),
|
||||||
|
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.z)
|
||||||
|
));
|
||||||
|
realm.getDataCellManager().addPlayerToRealm(playerObject);
|
||||||
|
//set controller id
|
||||||
|
if(playerObject == Globals.clientPlayer){
|
||||||
|
Globals.playerEntity = newPlayerEntity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds behavior trees that are unique to players a given entity
|
||||||
|
* @param entity The entity to add to
|
||||||
|
*/
|
||||||
|
static void addPlayerServerBTrees(Entity entity){
|
||||||
|
ServerPlayerViewDirTree.attachServerPlayerViewDirTree(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -154,15 +154,22 @@ public class Realm {
|
|||||||
* Tells the data cell manager to simulate all loaded cells
|
* Tells the data cell manager to simulate all loaded cells
|
||||||
*/
|
*/
|
||||||
protected void simulate(){
|
protected void simulate(){
|
||||||
|
//
|
||||||
//simulate bullet physics engine step
|
//simulate bullet physics engine step
|
||||||
collisionEngine.simulatePhysics((float)Globals.timekeeper.getSimFrameTime());
|
collisionEngine.simulatePhysics((float)Globals.timekeeper.getSimFrameTime());
|
||||||
collisionEngine.updateDynamicObjectTransforms();
|
collisionEngine.updateDynamicObjectTransforms();
|
||||||
|
//
|
||||||
|
//hitbox sim
|
||||||
|
hitboxManager.simulate();
|
||||||
|
//
|
||||||
//main simulation
|
//main simulation
|
||||||
dataCellManager.simulate();
|
dataCellManager.simulate();
|
||||||
|
//
|
||||||
//data cell manager update misc variables (player positions, unload not-in-use cells)
|
//data cell manager update misc variables (player positions, unload not-in-use cells)
|
||||||
if(dataCellManager != null){
|
if(dataCellManager != null){
|
||||||
dataCellManager.unloadPlayerlessChunks();
|
dataCellManager.unloadPlayerlessChunks();
|
||||||
}
|
}
|
||||||
|
//
|
||||||
//clear collidable impulse lists
|
//clear collidable impulse lists
|
||||||
collisionEngine.clearCollidableImpulseLists();
|
collisionEngine.clearCollidableImpulseLists();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import electrosphere.engine.Globals;
|
|||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.game.server.world.ServerWorldData;
|
import electrosphere.game.server.world.ServerWorldData;
|
||||||
import electrosphere.net.server.player.Player;
|
import electrosphere.net.server.player.Player;
|
||||||
|
import electrosphere.server.datacell.physics.ServerHitboxResolutionCallback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages all realms for the engine. Should be a singleton
|
* Manages all realms for the engine. Should be a singleton
|
||||||
@ -39,7 +40,7 @@ public class RealmManager {
|
|||||||
* @return The realm
|
* @return The realm
|
||||||
*/
|
*/
|
||||||
public Realm createRealm(){
|
public Realm createRealm(){
|
||||||
return new Realm(new CollisionEngine(), new HitboxManager());
|
return new Realm(new CollisionEngine(), new HitboxManager(new ServerHitboxResolutionCallback()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,7 +52,7 @@ public class RealmManager {
|
|||||||
CollisionEngine collisionEngine = new CollisionEngine();
|
CollisionEngine collisionEngine = new CollisionEngine();
|
||||||
collisionEngine.setCollisionWorldData(new CollisionWorldData(serverWorldData));
|
collisionEngine.setCollisionWorldData(new CollisionWorldData(serverWorldData));
|
||||||
//create realm
|
//create realm
|
||||||
Realm realm = new Realm(collisionEngine, new HitboxManager());
|
Realm realm = new Realm(collisionEngine, new HitboxManager(new ServerHitboxResolutionCallback()));
|
||||||
//create function classes
|
//create function classes
|
||||||
GriddedDataCellManager griddedDataCellManager = new GriddedDataCellManager(realm,Globals.serverTerrainManager,Globals.serverFluidManager,Globals.serverContentManager);
|
GriddedDataCellManager griddedDataCellManager = new GriddedDataCellManager(realm,Globals.serverTerrainManager,Globals.serverFluidManager,Globals.serverContentManager);
|
||||||
EntityDataCellMapper entityDataCellMapper = new EntityDataCellMapper();
|
EntityDataCellMapper entityDataCellMapper = new EntityDataCellMapper();
|
||||||
|
|||||||
@ -0,0 +1,88 @@
|
|||||||
|
package electrosphere.server.datacell.physics;
|
||||||
|
|
||||||
|
import org.joml.Vector3d;
|
||||||
|
import org.ode4j.ode.DContactGeom;
|
||||||
|
import org.ode4j.ode.DGeom;
|
||||||
|
|
||||||
|
import electrosphere.collision.CollisionEngine.CollisionResolutionCallback;
|
||||||
|
import electrosphere.collision.collidable.Collidable;
|
||||||
|
import electrosphere.engine.Globals;
|
||||||
|
import electrosphere.entity.Entity;
|
||||||
|
import electrosphere.entity.EntityUtils;
|
||||||
|
import electrosphere.entity.state.hitbox.HitboxState;
|
||||||
|
import electrosphere.entity.state.hitbox.HitboxState.HitboxShapeStatus;
|
||||||
|
import electrosphere.entity.state.hitbox.HitboxState.HitboxType;
|
||||||
|
import electrosphere.entity.state.life.LifeUtils;
|
||||||
|
import electrosphere.entity.state.movement.ProjectileTree;
|
||||||
|
import electrosphere.entity.types.attach.AttachUtils;
|
||||||
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
|
import electrosphere.entity.types.item.ItemUtils;
|
||||||
|
import electrosphere.server.datacell.Realm;
|
||||||
|
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for managing collisions on the server
|
||||||
|
*/
|
||||||
|
public class ServerHitboxResolutionCallback implements CollisionResolutionCallback {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resolve(DContactGeom contactGeom, Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude) {
|
||||||
|
Entity impactorParent = impactor.getParent();
|
||||||
|
Entity receiverParent = receiver.getParent();
|
||||||
|
HitboxState impactorState = HitboxState.getHitboxState(impactorParent);
|
||||||
|
HitboxState receiverState = HitboxState.getHitboxState(receiverParent);
|
||||||
|
DGeom impactorGeom = contactGeom.g1;
|
||||||
|
DGeom receiverGeom = contactGeom.g2;
|
||||||
|
HitboxShapeStatus impactorShapeStatus = impactorState.getShapeStatus(impactorGeom);
|
||||||
|
HitboxShapeStatus receiverShapeStatus = receiverState.getShapeStatus(receiverGeom);
|
||||||
|
Realm receiverRealm = Globals.realmManager.getEntityRealm(receiverParent);
|
||||||
|
|
||||||
|
|
||||||
|
//currently, impactor needs to be an item, and the receiver must not be an item
|
||||||
|
boolean isDamageEvent =
|
||||||
|
impactorShapeStatus != null &&
|
||||||
|
receiverShapeStatus != null &&
|
||||||
|
impactorShapeStatus.isActive() &&
|
||||||
|
receiverShapeStatus.isActive() &&
|
||||||
|
impactorShapeStatus.getType() == HitboxType.HIT &&
|
||||||
|
receiverShapeStatus.getType() == HitboxType.HURT &&
|
||||||
|
AttachUtils.getParent(impactorParent) != receiverParent
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
if(isDamageEvent){
|
||||||
|
//if the entity is attached to is an item, we need to compare with the parent of the item
|
||||||
|
//to make sure you don't stab yourself for instance
|
||||||
|
boolean isItem = ItemUtils.isItem(impactorParent);//hitboxParent.containsKey(EntityDataStrings.ITEM_IS_ITEM);
|
||||||
|
Entity hitboxAttachParent = AttachUtils.getParent(impactorParent);
|
||||||
|
|
||||||
|
if(isItem){
|
||||||
|
if(hitboxAttachParent != receiverParent){
|
||||||
|
int damage = ItemUtils.getWeaponDataRaw(impactorParent).getDamage();
|
||||||
|
LifeUtils.getLifeState(receiverParent).damage(damage);
|
||||||
|
if(!LifeUtils.getLifeState(receiverParent).isIsAlive()){
|
||||||
|
EntityUtils.getPosition(receiverParent).set(Globals.spawnPoint);
|
||||||
|
LifeUtils.getLifeState(receiverParent).revive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int damage = 0;
|
||||||
|
//for entities using attacktree
|
||||||
|
if(CreatureUtils.serverGetAttackTree(impactorParent) != null){
|
||||||
|
damage = ItemUtils.getWeaponDataRaw(impactorParent).getDamage();
|
||||||
|
} else {
|
||||||
|
//for entities using shooter tree
|
||||||
|
if(ProjectileTree.getProjectileTree(impactorParent) != null){
|
||||||
|
damage = (int)ProjectileTree.getProjectileTree(impactorParent).getDamage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LifeUtils.getLifeState(receiverParent).damage(damage);
|
||||||
|
if(!LifeUtils.getLifeState(receiverParent).isIsAlive()){
|
||||||
|
EntityUtils.getPosition(receiverParent).set(Globals.spawnPoint);
|
||||||
|
LifeUtils.getLifeState(receiverParent).revive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -12,13 +12,11 @@ import org.joml.Matrix4f;
|
|||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import org.joml.Vector4d;
|
import org.joml.Vector4d;
|
||||||
import org.joml.Vector4f;
|
|
||||||
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.renderer.actor.ActorAnimationMask;
|
import electrosphere.renderer.actor.ActorAnimationMask;
|
||||||
import electrosphere.renderer.actor.ActorBoneRotator;
|
import electrosphere.renderer.actor.ActorBoneRotator;
|
||||||
import electrosphere.renderer.actor.ActorStaticMorph;
|
import electrosphere.renderer.actor.ActorStaticMorph;
|
||||||
import electrosphere.renderer.actor.ActorStaticMorph.StaticMorphTransforms;
|
|
||||||
import electrosphere.renderer.model.Bone;
|
import electrosphere.renderer.model.Bone;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,10 +1,21 @@
|
|||||||
package electrosphere.server.poseactor;
|
package electrosphere.server.poseactor;
|
||||||
|
|
||||||
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
|
|
||||||
public class PoseActorUtils {
|
public class PoseActorUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a pose actor object and queues the model path
|
||||||
|
* @param modelPath The model path
|
||||||
|
* @return The PoseActor object
|
||||||
|
*/
|
||||||
|
public static PoseActor createPoseActorFromModelPath(String modelPath){
|
||||||
|
PoseActor rVal = new PoseActor(modelPath);
|
||||||
|
Globals.assetManager.addPoseModelPathToQueue(modelPath);
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
public static void applyBlenderTransformer(Entity actorEntity){
|
public static void applyBlenderTransformer(Entity actorEntity){
|
||||||
PoseActor entityActor = EntityUtils.getPoseActor(actorEntity);
|
PoseActor entityActor = EntityUtils.getPoseActor(actorEntity);
|
||||||
|
|||||||
@ -1,41 +1,20 @@
|
|||||||
package electrosphere.server.simulation;
|
package electrosphere.server.simulation;
|
||||||
|
|
||||||
import electrosphere.entity.types.attach.AttachUtils;
|
import electrosphere.entity.types.attach.AttachUtils;
|
||||||
import electrosphere.client.targeting.crosshair.Crosshair;
|
|
||||||
import electrosphere.collision.hitbox.HitboxManager;
|
import electrosphere.collision.hitbox.HitboxManager;
|
||||||
import electrosphere.collision.hitbox.HitboxUtils;
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.engine.Main;
|
import electrosphere.engine.Main;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
|
||||||
import electrosphere.entity.EntityTags;
|
import electrosphere.entity.EntityTags;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.btree.BehaviorTree;
|
|
||||||
import electrosphere.entity.scene.EntityDescriptor;
|
|
||||||
import electrosphere.entity.state.ParticleTree;
|
|
||||||
import electrosphere.entity.state.attack.ClientAttackTree;
|
|
||||||
import electrosphere.entity.state.collidable.ClientCollidableTree;
|
|
||||||
import electrosphere.entity.state.collidable.ServerCollidableTree;
|
import electrosphere.entity.state.collidable.ServerCollidableTree;
|
||||||
import electrosphere.entity.state.idle.IdleTree;
|
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
|
||||||
import electrosphere.entity.types.item.ItemUtils;
|
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.state.movement.groundmove.ClientGroundMovementTree;
|
|
||||||
import electrosphere.entity.types.particle.ParticleUtils;
|
import electrosphere.entity.types.particle.ParticleUtils;
|
||||||
import electrosphere.net.parser.net.message.EntityMessage;
|
|
||||||
import electrosphere.renderer.actor.Actor;
|
import electrosphere.renderer.actor.Actor;
|
||||||
import electrosphere.server.datacell.ServerDataCell;
|
import electrosphere.server.datacell.ServerDataCell;
|
||||||
|
|
||||||
import java.sql.Time;
|
|
||||||
|
|
||||||
import org.joml.Vector3d;
|
|
||||||
import org.joml.Vector3f;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Server-side micro-scale simulation
|
||||||
* @author amaterasu
|
|
||||||
*/
|
*/
|
||||||
public class MicroSimulation {
|
public class MicroSimulation {
|
||||||
|
|
||||||
@ -79,16 +58,9 @@ public class MicroSimulation {
|
|||||||
}
|
}
|
||||||
//update attached entity positions
|
//update attached entity positions
|
||||||
AttachUtils.serverUpdateAttachedEntityPositions(dataCell);
|
AttachUtils.serverUpdateAttachedEntityPositions(dataCell);
|
||||||
//update hitbox positions
|
//
|
||||||
for(Entity currentHitbox : hitboxManager.getAllHitboxes()){
|
//hitbox updates
|
||||||
HitboxUtils.serverUpdatePosition(currentHitbox);
|
hitboxManager.simulate();
|
||||||
}
|
|
||||||
//collide hitboxes
|
|
||||||
for(Entity currentHitbox : hitboxManager.getAllHitboxes()){
|
|
||||||
if(isReady){
|
|
||||||
HitboxUtils.serverCollideEntities(currentHitbox);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//simulate behavior trees
|
//simulate behavior trees
|
||||||
dataCell.getScene().simulateBehaviorTrees((float)Globals.timekeeper.getSimFrameTime());
|
dataCell.getScene().simulateBehaviorTrees((float)Globals.timekeeper.getSimFrameTime());
|
||||||
//sum collidable impulses
|
//sum collidable impulses
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user