Separation of client and server logic
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2023-05-20 19:18:09 -04:00
parent a27f9f8991
commit ebec7a373e
127 changed files with 8633 additions and 2804 deletions

View File

@ -16,6 +16,10 @@
{
"name" : "initialDiscretePositionY",
"type" : "FIXED_INT"
},
{
"name" : "initialDiscretePositionZ",
"type" : "FIXED_INT"
}
],
"messageTypes" : [
@ -29,7 +33,8 @@
"messageName" : "SetInitialDiscretePosition",
"data" : [
"initialDiscretePositionX",
"initialDiscretePositionY"
"initialDiscretePositionY",
"initialDiscretePositionZ"
]
}
]

View File

@ -41,6 +41,10 @@
"name" : "worldY",
"type" : "FIXED_INT"
},
{
"name" : "worldZ",
"type" : "FIXED_INT"
},
{
"name" : "value",
"type" : "FIXED_FLOAT"
@ -57,6 +61,10 @@
"name" : "locationY",
"type" : "FIXED_INT"
},
{
"name" : "locationZ",
"type" : "FIXED_INT"
},
{
@ -67,6 +75,10 @@
"name" : "realLocationY",
"type" : "FIXED_DOUBLE"
},
{
"name" : "realLocationZ",
"type" : "FIXED_DOUBLE"
},
@ -305,7 +317,8 @@
"messageName" : "Update",
"data" : [
"locationX",
"locationY"
"locationY",
"locationZ"
]
},
{
@ -379,15 +392,18 @@
"value",
"worldX",
"worldY",
"worldZ",
"locationX",
"locationY"
"locationY",
"locationZ"
]
},
{
"messageName" : "SpawnPosition",
"data" : [
"realLocationX",
"realLocationY"
"realLocationY",
"realLocationZ"
]
}
]

View File

@ -0,0 +1,85 @@
package electrosphere.client.culling;
import java.util.List;
import org.joml.Vector3d;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.Scene;
import electrosphere.entity.types.attach.AttachUtils;
public class ClientEntityCullingManager {
Scene scene;
public ClientEntityCullingManager(Scene scene){
this.scene = scene;
}
public void recursiveHide(Entity target){
if(AttachUtils.hasChildren(target)){
List<Entity> childrenList = AttachUtils.getChildrenList(target);
for(Entity currentChild : childrenList){
recursiveHide(currentChild);
}
}
target.putData(EntityDataStrings.DATA_STRING_DRAW, false);
}
public void recursiveShow(Entity target){
if(AttachUtils.hasChildren(target)){
List<Entity> childrenList = AttachUtils.getChildrenList(target);
for(Entity currentChild : childrenList){
recursiveShow(currentChild);
}
}
target.putData(EntityDataStrings.DATA_STRING_DRAW, true);
}
public void clearOutOfBoundsEntities(){
if(Globals.commonWorldData != null && Globals.playerEntity != null && Globals.clientPlayerData != null){
Vector3d playerCharacterPos = EntityUtils.getPosition(Globals.playerEntity);
int playerCharacterWorldX = Globals.commonWorldData.convertRealToWorld(playerCharacterPos.x);
int playerCharacterWorldY = Globals.commonWorldData.convertRealToWorld(playerCharacterPos.y);
int playerCharacterWorldZ = Globals.commonWorldData.convertRealToWorld(playerCharacterPos.z);
if(
playerCharacterWorldX != Globals.clientPlayerData.getWorldPos().x||
playerCharacterWorldY != Globals.clientPlayerData.getWorldPos().y ||
playerCharacterWorldZ != Globals.clientPlayerData.getWorldPos().z
){
for(Entity entity : scene.getEntityList()){
if(entity.containsKey(EntityDataStrings.TERRAIN_IS_TERRAIN) || entity.containsKey(EntityDataStrings.ATTACH_PARENT) || entity.containsKey(EntityDataStrings.COLLISION_ENTITY_PARENT)){
} else {
Vector3d position = EntityUtils.getPosition(entity);
//common world data is initialized with the collision data
//if this is null then the engine hasn't fully started up yet
if(position != null){
int worldX = Globals.commonWorldData.convertRealToWorld(position.x);
int worldY = Globals.commonWorldData.convertRealToWorld(position.z);
if(!Globals.drawCellManager.coordsInPhysicsSpace(worldX, worldY)){
//if we're running the server we need to just hide the entity
//otherwise delete it
if(Globals.RUN_SERVER && Globals.RUN_CLIENT){
recursiveHide(entity);
} else {
scene.recursiveDeregister(entity);
}
} else {
//if the entity is within range, we're running server,
//and it's not set to visible, make it visible
if(Globals.RUN_SERVER && Globals.RUN_CLIENT){
recursiveShow(entity);
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,98 @@
package electrosphere.client.scene;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.Scene;
import electrosphere.game.collision.CollisionEngine;
import electrosphere.logger.LoggerInterface;
/**
* Wrapper around the scene object to provide lots of much needed client-specific utility
* Does all the server<->client id translation and provides utilities to map between the two
*/
public class ClientSceneWrapper {
//entity id translation between server/client
Map<Integer,Integer> clientToServerIdMap = new ConcurrentHashMap<Integer,Integer>();
Map<Integer,Integer> serverToClientIdMap = new ConcurrentHashMap<Integer,Integer>();
//The scene backing the wrapper
Scene scene;
//The engine used to back physics collision checks in client
CollisionEngine collisionEngine;
public ClientSceneWrapper(Scene scene, CollisionEngine collisionEngine){
this.scene = scene;
this.collisionEngine = collisionEngine;
}
/**
* Registers a server provided ID as a mapping to a given ID on the client
* @param clientId The client's generated ID
* @param serverId The server's provided ID
*/
public void mapIdToId(int clientId, int serverId){
LoggerInterface.loggerEngine.DEBUG("MapID: " + clientId + " <===> " + serverId);
clientToServerIdMap.put(clientId, serverId);
serverToClientIdMap.put(serverId, clientId);
}
/**
* Resolves a client ID to the equivalent ID on the server
* @param clientId The id provided by the client
* @return The equivalent id on the server
*/
public int mapClientToServerId(int clientId){
return clientToServerIdMap.get(clientId);
}
/**
* Translates the id provided by the server into the equivalent id on the client
* @param serverId The id provided by the server
* @return The equivalent id on the client
*/
public int mapServerToClientId(int serverId){
return serverToClientIdMap.get(serverId);
}
/**
* Returns true if the server->client map contains a given id
* @param id The id to search for
* @return True if the server->client map contains the provided id
*/
public boolean serverToClientMapContainsId(int id){
return serverToClientIdMap.containsKey(id);
}
/**
* Gets the entity provided a server-provided id
* @param id The server-provided ID
* @return The entity in question
*/
public Entity getEntityFromServerId(int id){
return scene.getEntityFromId(mapServerToClientId(id));
}
/**
* Gets the scene backing this client scene wrapper
* @return The scene
*/
public Scene getScene(){
return this.scene;
}
/**
* Gets the collision engine backing the wrapper
* @return
*/
public CollisionEngine getCollisionEngine(){
return collisionEngine;
}
}

View File

@ -0,0 +1,127 @@
package electrosphere.client.sim;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityTags;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.collidable.ClientCollidableTree;
import electrosphere.entity.types.attach.AttachUtils;
import electrosphere.entity.types.hitbox.HitboxUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.entity.types.particle.ParticleUtils;
import electrosphere.game.client.targeting.crosshair.Crosshair;
import electrosphere.renderer.actor.Actor;
public class ClientSimulation {
boolean isReady = false;
boolean loadTerrain = false;
public ClientSimulation(){
isReady = false;
}
public void simulate(){
//simulate bullet physics engine step
Globals.clientSceneWrapper.getCollisionEngine().simulatePhysics(Main.deltaFrames);
//update actor animations
for(Entity currentEntity : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.DRAWABLE)){
//fetch actor
Actor currentActor = EntityUtils.getActor(currentEntity);
//increment animations
if(currentActor.isPlayingAnimation()){
currentActor.incrementAnimationTime(Main.deltaFrames / Main.targetFrameRate);
}
}
//make items play idle animation
for(Entity item : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.ITEM)){
ItemUtils.updateItemActorAnimation(item);
}
//particle state updates
for(Entity particle : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.PARTICLE)){
// ParticleTree tree = ParticleUtils.getParticleTree(particle);
// tree.simulate(Main.deltaFrames);
ParticleUtils.makeParticleBillboardFaceCamera(particle);
}
//update attached entity positions
AttachUtils.clientUpdateAttachedEntityPositions();
//update hitbox positions
for(Entity currentHitbox : Globals.clientHitboxManager.getAllHitboxes()){
HitboxUtils.clientUpdatePosition(currentHitbox);
}
//collide hitboxes
for(Entity currentHitbox : Globals.clientHitboxManager.getAllHitboxes()){
if(isReady){
HitboxUtils.clientCollideEntities(currentHitbox);
}
}
//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
Crosshair.checkTargetable();
Crosshair.updateTargetCrosshairPosition();
//simulate behavior trees
Globals.clientSceneWrapper.getScene().simulateBehaviorTrees(Main.deltaFrames);
//sum collidable impulses
for(Entity collidable : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.COLLIDABLE)){
ClientCollidableTree.getClientCollidableTree(collidable).simulate(Main.deltaFrames);
}
//clear collidable impulse lists
Globals.clientSceneWrapper.getCollisionEngine().clearCollidableImpulseLists();
//delete all client side entities that aren't in visible chunks
if(Globals.clientEntityCullingManager != null){
Globals.clientEntityCullingManager.clearOutOfBoundsEntities();
}
}
/**
* Gets whether the client simulation is ready to execute
* @return True if ready to execute, false otherwise
*/
public boolean isReady(){
return isReady;
}
/**
* Sets the ready status of the client simulation
* @param ready True if ready to simulate, false otherwise
*/
public void setReady(boolean ready){
isReady = ready;
}
/**
* Freezes simulation (sets ready to false)
*/
public void freeze(){
isReady = false;
}
/**
* Unfreezes simulation (sets ready to true)
*/
public void unfreeze(){
isReady = true;
}
/**
* Gets whether the client simulation is loading terrain
* @return True if loading terrain, false otherwise
*/
public boolean isLoadingTerrain(){
return this.loadTerrain;
}
/**
* Sets whether the client should load terrain or not
* @param loadTerrain True if should load terrain, false otherwise
*/
public void setLoadingTerrain(boolean loadTerrain){
this.loadTerrain = loadTerrain;
}
}

View File

@ -420,7 +420,7 @@ public class ControlHandler {
mainGameControlList.add(controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_FORWARD));
controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_FORWARD).setOnPress(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
BehaviorTree movementTree = CreatureUtils.getEntityMovementTree(Globals.playerEntity);
BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity);
if(movementTree instanceof GroundMovementTree){
GroundMovementTree groundTree = (GroundMovementTree) movementTree;
Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera);
@ -442,7 +442,7 @@ public class ControlHandler {
}});
controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_FORWARD).setOnRepeat(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
BehaviorTree movementTree = CreatureUtils.getEntityMovementTree(Globals.playerEntity);
BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity);
if(movementTree instanceof GroundMovementTree){
GroundMovementTree groundTree = (GroundMovementTree) movementTree;
Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera);
@ -464,7 +464,7 @@ public class ControlHandler {
}});
controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_FORWARD).setOnRelease(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
BehaviorTree movementTree = CreatureUtils.getEntityMovementTree(Globals.playerEntity);
BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity);
if(movementTree instanceof GroundMovementTree){
GroundMovementTree groundTree = (GroundMovementTree) movementTree;
groundTree.slowdown();
@ -477,7 +477,7 @@ public class ControlHandler {
mainGameControlList.add(controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_BACKWARD));
controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_BACKWARD).setOnPress(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
BehaviorTree movementTree = CreatureUtils.getEntityMovementTree(Globals.playerEntity);
BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity);
if(movementTree instanceof GroundMovementTree){
GroundMovementTree groundTree = (GroundMovementTree) movementTree;
Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera);
@ -496,7 +496,7 @@ public class ControlHandler {
}});
controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_BACKWARD).setOnRepeat(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
BehaviorTree movementTree = CreatureUtils.getEntityMovementTree(Globals.playerEntity);
BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity);
if(movementTree instanceof GroundMovementTree){
GroundMovementTree groundTree = (GroundMovementTree) movementTree;
Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera);
@ -515,7 +515,7 @@ public class ControlHandler {
}});
controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_BACKWARD).setOnRelease(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
BehaviorTree movementTree = CreatureUtils.getEntityMovementTree(Globals.playerEntity);
BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity);
if(movementTree instanceof GroundMovementTree){
GroundMovementTree groundTree = (GroundMovementTree) movementTree;
groundTree.slowdown();
@ -528,7 +528,7 @@ public class ControlHandler {
mainGameControlList.add(controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_LEFT));
controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_LEFT).setOnPress(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
BehaviorTree movementTree = CreatureUtils.getEntityMovementTree(Globals.playerEntity);
BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity);
if(movementTree instanceof GroundMovementTree){
GroundMovementTree groundTree = (GroundMovementTree) movementTree;
Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera);
@ -544,7 +544,7 @@ public class ControlHandler {
}});
controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_LEFT).setOnRepeat(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
BehaviorTree movementTree = CreatureUtils.getEntityMovementTree(Globals.playerEntity);
BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity);
if(movementTree instanceof GroundMovementTree){
GroundMovementTree groundTree = (GroundMovementTree) movementTree;
Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera);
@ -560,7 +560,7 @@ public class ControlHandler {
}});
controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_LEFT).setOnRelease(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
BehaviorTree movementTree = CreatureUtils.getEntityMovementTree(Globals.playerEntity);
BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity);
if(movementTree instanceof GroundMovementTree){
GroundMovementTree groundTree = (GroundMovementTree) movementTree;
groundTree.slowdown();
@ -573,7 +573,7 @@ public class ControlHandler {
mainGameControlList.add(controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_RIGHT));
controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_RIGHT).setOnPress(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
BehaviorTree movementTree = CreatureUtils.getEntityMovementTree(Globals.playerEntity);
BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity);
if(movementTree instanceof GroundMovementTree){
GroundMovementTree groundTree = (GroundMovementTree) movementTree;
Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera);
@ -589,7 +589,7 @@ public class ControlHandler {
}});
controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_RIGHT).setOnRepeat(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
BehaviorTree movementTree = CreatureUtils.getEntityMovementTree(Globals.playerEntity);
BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity);
if(movementTree instanceof GroundMovementTree){
GroundMovementTree groundTree = (GroundMovementTree) movementTree;
Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera);
@ -605,7 +605,7 @@ public class ControlHandler {
}});
controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_RIGHT).setOnRelease(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
BehaviorTree movementTree = CreatureUtils.getEntityMovementTree(Globals.playerEntity);
BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity);
if(movementTree instanceof GroundMovementTree){
GroundMovementTree groundTree = (GroundMovementTree) movementTree;
groundTree.slowdown();
@ -627,7 +627,7 @@ public class ControlHandler {
mainGameControlList.add(controls.get(DATA_STRING_INPUT_CODE_STRAFE_LEFT));
controls.get(DATA_STRING_INPUT_CODE_STRAFE_LEFT).setOnPress(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
BehaviorTree movementTree = CreatureUtils.getEntityMovementTree(Globals.playerEntity);
BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity);
if(movementTree instanceof GroundMovementTree){
GroundMovementTree groundTree = (GroundMovementTree) movementTree;
Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera);
@ -644,7 +644,7 @@ public class ControlHandler {
}});
controls.get(DATA_STRING_INPUT_CODE_STRAFE_LEFT).setOnRepeat(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
BehaviorTree movementTree = CreatureUtils.getEntityMovementTree(Globals.playerEntity);
BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity);
if(movementTree instanceof GroundMovementTree){
GroundMovementTree groundTree = (GroundMovementTree) movementTree;
Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera);
@ -661,7 +661,7 @@ public class ControlHandler {
}});
controls.get(DATA_STRING_INPUT_CODE_STRAFE_LEFT).setOnRelease(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
BehaviorTree movementTree = CreatureUtils.getEntityMovementTree(Globals.playerEntity);
BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity);
if(movementTree instanceof GroundMovementTree){
GroundMovementTree groundTree = (GroundMovementTree) movementTree;
groundTree.slowdown();
@ -674,7 +674,7 @@ public class ControlHandler {
mainGameControlList.add(controls.get(DATA_STRING_INPUT_CODE_STRAFE_RIGHT));
controls.get(DATA_STRING_INPUT_CODE_STRAFE_RIGHT).setOnPress(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
BehaviorTree movementTree = CreatureUtils.getEntityMovementTree(Globals.playerEntity);
BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity);
if(movementTree instanceof GroundMovementTree){
GroundMovementTree groundTree = (GroundMovementTree) movementTree;
Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera);
@ -691,7 +691,7 @@ public class ControlHandler {
}});
controls.get(DATA_STRING_INPUT_CODE_STRAFE_RIGHT).setOnRepeat(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
BehaviorTree movementTree = CreatureUtils.getEntityMovementTree(Globals.playerEntity);
BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity);
if(movementTree instanceof GroundMovementTree){
GroundMovementTree groundTree = (GroundMovementTree) movementTree;
Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera);
@ -708,7 +708,7 @@ public class ControlHandler {
}});
controls.get(DATA_STRING_INPUT_CODE_STRAFE_RIGHT).setOnRelease(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
BehaviorTree movementTree = CreatureUtils.getEntityMovementTree(Globals.playerEntity);
BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity);
if(movementTree instanceof GroundMovementTree){
GroundMovementTree groundTree = (GroundMovementTree) movementTree;
groundTree.slowdown();
@ -722,7 +722,7 @@ public class ControlHandler {
mainGameControlList.add(controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_JUMP));
controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_JUMP).setOnPress(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
JumpTree jumpTree = JumpTree.getJumpTree(Globals.playerEntity);
JumpTree jumpTree = JumpTree.getClientJumpTree(Globals.playerEntity);
if(jumpTree != null){
jumpTree.start();
}
@ -734,7 +734,7 @@ public class ControlHandler {
mainGameControlList.add(controls.get(INPUT_CODE_SPRINT));
controls.get(INPUT_CODE_SPRINT).setOnPress(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
SprintTree sprintTree = CreatureUtils.getSprintTree(Globals.playerEntity);
SprintTree sprintTree = CreatureUtils.clientGetSprintTree(Globals.playerEntity);
if(sprintTree != null){
sprintTree.start();
}
@ -742,7 +742,7 @@ public class ControlHandler {
}});
controls.get(INPUT_CODE_SPRINT).setOnRelease(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
SprintTree sprintTree = CreatureUtils.getSprintTree(Globals.playerEntity);
SprintTree sprintTree = CreatureUtils.clientGetSprintTree(Globals.playerEntity);
if(sprintTree != null){
sprintTree.stop();
}
@ -804,7 +804,7 @@ public class ControlHandler {
controls.get(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY).setOnPress(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
// Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera);
AttackTree attackTree = CreatureUtils.getAttackTree(Globals.playerEntity);
AttackTree attackTree = CreatureUtils.clientGetAttackTree(Globals.playerEntity);
if(attackTree != null){
// CreatureUtils.setFacingVector(Globals.playerCharacter, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).normalize());
attackTree.start();
@ -826,7 +826,7 @@ public class ControlHandler {
controls.get(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY).setOnRelease(new ControlMethod(){public void execute(){
if(Globals.playerEntity != null){
// Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera);
AttackTree attackTree = CreatureUtils.getAttackTree(Globals.playerEntity);
AttackTree attackTree = CreatureUtils.clientGetAttackTree(Globals.playerEntity);
if(attackTree != null){
// CreatureUtils.setFacingVector(Globals.playerCharacter, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).normalize());
attackTree.release();

View File

@ -11,6 +11,9 @@ import org.lwjgl.glfw.GLFWErrorCallback;
import electrosphere.audio.AudioEngine;
import electrosphere.auth.AuthenticationManager;
import electrosphere.client.culling.ClientEntityCullingManager;
import electrosphere.client.scene.ClientSceneWrapper;
import electrosphere.client.sim.ClientSimulation;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.controls.CameraHandler;
import electrosphere.controls.ControlCallback;
@ -18,6 +21,7 @@ import electrosphere.controls.ControlHandler;
import electrosphere.controls.MouseCallback;
import electrosphere.engine.assetmanager.AssetDataStrings;
import electrosphere.engine.assetmanager.AssetManager;
import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.entity.Entity;
import electrosphere.entity.Scene;
import electrosphere.entity.types.hitbox.HitboxManager;
@ -56,7 +60,10 @@ import electrosphere.renderer.ui.font.FontUtils;
import electrosphere.renderer.ui.font.RawFontMap;
import electrosphere.script.ScriptEngine;
import electrosphere.server.ai.AIManager;
import electrosphere.server.datacell.DataCellManager;
import electrosphere.server.datacell.EntityDataCellMapper;
import electrosphere.server.datacell.GriddedDataCellManager;
import electrosphere.server.datacell.RealmManager;
import electrosphere.server.datacell.physics.DataCellPhysicsManager;
import electrosphere.server.db.DatabaseController;
import electrosphere.server.pathfinding.NavMeshManager;
import electrosphere.server.simulation.MacroSimulation;
@ -120,12 +127,6 @@ public class Globals {
public static MouseCallback mouseCallback = new MouseCallback();
//
// Collision engine
//
public static CollisionEngine collisionEngine;
//
// Game Save stuff
//
@ -149,10 +150,12 @@ public class Globals {
public static CameraHandler cameraHandler = new CameraHandler();
//
//current world
//Server scene management
//
public static ServerWorldData serverWorldData;
public static DataCellManager dataCellManager;
public static RealmManager realmManager;
public static EntityDataCellMapper entityDataCellMapper;
public static DataCellPhysicsManager dataCellPhysicsManager;
//
//Player manager
@ -231,9 +234,6 @@ public class Globals {
//
//Engine - Main managers/variables
//
//keeps track of all entities in game
public static Scene entityManager;
public static Scene clientScene;
//terrain manager
// public static boolean LOAD_TERRAIN = true;
@ -254,8 +254,14 @@ public class Globals {
public static ScriptEngine scriptEngine;
//manages hitboxes
public static HitboxManager hitboxManager;
public static HitboxManager clientHitboxManager;
//client scene management
public static Scene clientScene;
public static ClientSceneWrapper clientSceneWrapper;
public static ClientEntityCullingManager clientEntityCullingManager;
public static ClientSimulation clientSimulation;
//client world data
public static ClientWorldData clientWorldData;
@ -350,8 +356,9 @@ public class Globals {
//load in shader options map
shaderOptionMap = FileUtils.loadObjectFromAssetPath("Shaders/shaderoptions.json", ShaderOptionMap.class);
shaderOptionMap.debug();
//create entity manager
entityManager = new Scene();
//client scene wrapper
clientScene = new Scene();
clientSceneWrapper = new ClientSceneWrapper(clientScene, new CollisionEngine());
//temporary hold for skybox colors
skyboxColors = new ArrayList<Vector3f>();
//load asset manager
@ -362,13 +369,19 @@ public class Globals {
scriptEngine = new ScriptEngine();
scriptEngine.init();
//hitbox manager
hitboxManager = new HitboxManager();
clientHitboxManager = new HitboxManager();
//ai manager
aiManager = new AIManager();
//collision engine
collisionEngine = new CollisionEngine();
//data cell manager
realmManager = new RealmManager();
// dataCellManager = new DataCellManager();
// griddedDataCellManager = new GriddedDataCellManager();
entityDataCellMapper = new EntityDataCellMapper();
// dataCellLocationResolver = new DataCellLocationResolver();
//nav mesh manager
navMeshManager = new NavMeshManager();
//terrain
Globals.clientTerrainManager = new ClientTerrainManager();
//game config
gameConfigDefault = electrosphere.game.data.Config.loadDefaultConfig();
gameConfigCurrent = gameConfigDefault;

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,7 @@ import java.util.concurrent.TimeUnit;
import electrosphere.audio.AudioEngine;
import electrosphere.controls.ControlHandler;
import electrosphere.engine.cli.CLIParser;
import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.game.client.ClientFunctions;
import electrosphere.game.config.UserSettings;
import electrosphere.logger.LoggerInterface;
@ -189,10 +190,17 @@ public class Main {
// RenderUtils.recaptureScreen();
}
/**
* Runs the main loop indefinitely. Blocks the thread this is called in.
*/
public static void mainLoop(){
mainLoop(0);
}
/**
* Runs the main loop for a specified number of frames.
* @param maxFrames The number of frames to run for. If 0, will run indefinitely.
*/
public static void mainLoop(long maxFrames){
//main loop
@ -246,15 +254,25 @@ public class Main {
///
/// C L I E N T S I M U L A T I O N S T U F F
///
if(Globals.RUN_CLIENT && framestep > 0){
if(Globals.clientSimulation != null && Globals.clientSimulation.isReady() && framestep > 0){
ClientFunctions.runBeforeSimulationFunctions();
}
if(Globals.microSimulation != null && Globals.microSimulation.isReady() && framestep > 0){
Globals.microSimulation.simulate();
if(Globals.clientSimulation != null && Globals.clientSimulation.isLoadingTerrain() && framestep > 0){
ClientFunctions.loadTerrain();
}
if(Globals.RUN_CLIENT && framestep > 0){
if(Globals.clientSimulation != null && Globals.clientSimulation.isReady() && framestep > 0){
Globals.clientSimulation.simulate();
}
if(Globals.clientSimulation != null && Globals.clientSimulation.isReady() && framestep > 0){
ClientFunctions.runClientFunctions();
}
///
/// S E R V E R M I C R O S I M U L A T I O N
///
if(Globals.realmManager != null){
Globals.realmManager.simulate();
}
///
/// M A C R O S I M U L A T I O N S T U F F

View File

@ -9,6 +9,7 @@ import electrosphere.renderer.ShaderProgram;
import electrosphere.renderer.actor.ActorShaderMask;
import electrosphere.renderer.loading.ModelLoader;
import electrosphere.renderer.texture.Texture;
import electrosphere.server.poseactor.PoseModel;
import java.util.LinkedList;
import java.util.List;
@ -40,6 +41,9 @@ public class AssetManager {
Map<String,CollisionObject> physicsMeshesLoadedIntoMemory = new ConcurrentHashMap<String,CollisionObject>();
List<String> physicsMeshesToLoad = new CopyOnWriteArrayList<String>();
Map<String,PoseModel> poseModelsLoadedIntoMemory = new ConcurrentHashMap<String,PoseModel>();
List<String> poseModelsInQueue = new CopyOnWriteArrayList<String>();
@ -82,6 +86,11 @@ public class AssetManager {
);
}
}
for(String currentPath: poseModelsInQueue){
poseModelsInQueue.remove(currentPath);
AIScene scene = ModelLoader.loadAIScene(currentPath);
poseModelsLoadedIntoMemory.put(currentPath, new PoseModel(currentPath, scene));
}
performMeshOverrides();
}
@ -178,6 +187,26 @@ public class AssetManager {
//
//Pose Models
//
public void addPoseModelPathToQueue(String path){
if(!poseModelsInQueue.contains(path) && !poseModelsLoadedIntoMemory.containsKey(path)){
poseModelsInQueue.add(path);
}
}
public PoseModel fetchPoseModel(String path){
PoseModel rVal = null;
if(poseModelsLoadedIntoMemory.containsKey(path)){
rVal = poseModelsLoadedIntoMemory.get(path);
}
return rVal;
}

View File

@ -0,0 +1,376 @@
package electrosphere.engine.loadingthreads;
import java.util.Random;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import electrosphere.engine.Globals;
import electrosphere.engine.assetmanager.AssetDataStrings;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.ServerEntityUtils;
import electrosphere.game.server.terrain.manager.ServerTerrainManager;
import electrosphere.game.server.world.ServerWorldData;
import electrosphere.logger.LoggerInterface;
import electrosphere.server.saves.SaveUtils;
import electrosphere.util.FileUtils;
public class ArenaLoading {
protected static void loadArenaGameServer(){
//init server arena terrain manager separately
initServerArenaTerrainManager();
//init the data of the world
initServerArenaWorldData();
//init data cell manager
// LoadingUtils.initTerrainDataCellManager();
//for testing purposes
FileUtils.recursivelyDelete("/Users/satellite/temp/saves/arena");
//init database connection
SaveUtils.initSave("arena");
//connect to database
SaveUtils.loadSave("arena");
//init authentication
LoadingUtils.initAuthenticationManager();
//initialize the server thread (server only)
LoadingUtils.initServerThread();
//collision engine
LoadingUtils.initCommonWorldData(Globals.RUN_SERVER);
//init gridded datacell manager
LoadingUtils.initGriddedRealm();
//initialize the "virtual" objects simulation
//not really relevant in arena mode
// initMacroSimulation();
//initialize the "real" objects simulation
LoadingUtils.initMicroSimulation();
//create arena entities
creatingRandomEntities();
//set simulations to ready if they exist
LoadingUtils.setSimulationsToReady();
LoggerInterface.loggerEngine.INFO("[Server]Finished loading arena world");
}
private static void initServerArenaTerrainManager(){
Globals.serverTerrainManager = ServerTerrainManager.constructArenaTerrainManager();
}
private static void initServerArenaWorldData(){
Globals.serverWorldData = ServerWorldData.createArenaWorld();
Globals.spawnPoint = new Vector3d(1,0.1,1);
// Globals.serverTerrainManager.getChunk(0, 0).addModification(new TerrainModification(0,0,5,5,5));
}
private static void creatingRandomEntities(){
// String unitCubeModelPath = Globals.assetManager.registerModel(ModelUtils.createUnitCube());
// Entity unitCube = EntityUtils.spawnDrawableEntity(unitCubeModelPath);
// EntityUtils.getEntityPosition(unitCube).set(10,2,10);
// String goundPlaneModelPath = "Models/groundplanemassiveuv.fbx";
// Entity groundPlane = EntityUtils.spawnDrawableEntity(goundPlaneModelPath);
// EntityUtils.getEntityPosition(groundPlane).set(10f,2f,10f);
// EntityUtils.getEntityRotation(groundPlane).rotateAxis((float)Math.PI/2, new Vector3f(1,0,0));
// EntityUtils.getEntityScale(groundPlane).set(5);
// String unitsphereModelPath = "Models/unitsphere.fbx";
// Entity unitsphere = EntityUtils.spawnDrawableEntity(unitsphereModelPath);
// EntityUtils.getEntityPosition(unitsphere).set(10f,2f,10f);
// EntityUtils.getEntityScale(unitsphere).set(1);
// String smallCubePath = "Models/SmallCube.fbx";
// Entity originCube = EntityUtils.spawnDrawableEntity(smallCubePath);
// EntityUtils.getEntityPosition(originCube).set(0, 0, 0);
//
// originCube = EntityUtils.spawnDrawableEntity(smallCubePath);
// EntityUtils.getEntityPosition(originCube).set(1, 0, 0);
//
// originCube = EntityUtils.spawnDrawableEntity(smallCubePath);
// EntityUtils.getEntityPosition(originCube).set(0, 0, 1);
// Entity font = FontUtils.makeFont(7, 1);
// EntityUtils.getEntityPosition(font).set(new Vector3f(0.2f,0.2f,0.0f));
// for(int i = 0; i < 10; i++){
// Random rand = new Random();
// Entity creature = CreatureUtils.spawnBasicCreature(0, 0.01f, 0.01f);
// EntityUtils.getEntityPosition(creature).set(rand.nextFloat() * 10, rand.nextFloat() * 10, rand.nextFloat() * 10);
// EntityUtils.getEntityScale(creature).set(0.01f);
// }
//trees \:D/
// for(int i = 0; i < 10; i++){
// Random rand = new Random();
// String treePath = "Models/tree1.fbx";
// Entity tree = EntityUtils.spawnDrawableEntity(treePath);
// EntityUtils.getPosition(tree).set(rand.nextFloat() * 150 + 10, 0, rand.nextFloat() * 150 + 10);
//// EntityUtils.getEntityRotation(tree).rotateAxis((float)-Math.PI/2.0f, new Vector3f(1,0,0));
// }
// for(int i = 0; i < 250; i++){
// Random rand = new Random();
// String treePath = "Models/falloak1.fbx";
// Entity tree = EntityUtils.spawnDrawableEntity(treePath);
// EntityUtils.getPosition(tree).set(rand.nextFloat() * 105 + 1, 0, rand.nextFloat() * 105 + 1);
// EntityUtils.getRotation(tree).rotateLocalX(-(float)Math.PI/2.0f).rotateZ(rand.nextFloat());
// // EntityUtils.getEntityRotation(tree).rotateAxis((float)-Math.PI/2.0f, new Vector3f(1,0,0));
// }
// Random rand = new Random();
// for(int i = 0; i < 1000; i++){
// String wheatPath = "Models/wheat2.fbx";
// Entity wheatStalk = EntityUtils.spawnDrawableEntity(wheatPath);
// EntityUtils.getPosition(wheatStalk).set(rand.nextFloat() * 20, 0, rand.nextFloat() * 20);
// EntityUtils.getRotation(wheatStalk).rotateLocalX(-(float)Math.PI/2.0f);
// EntityUtils.getScale(wheatStalk).set(1, 1, 2);
// }
// String buildingPath = "Models/building1.fbx";
// Entity building = EntityUtils.spawnDrawableEntity(buildingPath);
// EntityUtils.getPosition(building).set(5,1.2f,5);
// EntityUtils.getScale(building).set(0.5f);
// EntityUtils.getRotation(building).rotateLocalY((float)(Math.PI));
// ActorUtils.applyBlenderTransformer(building);
//spawn evil goblin
// Entity goblin = CreatureUtils.spawnBasicCreature("goblin");
// CollisionObjUtils.positionCharacter(goblin, new Vector3f(4, 0, 4));
// EntityUtils.getScale(goblin).set(0.005f);
// //give evil goblin sword
// Entity goblinSword = ItemUtils.spawnBasicItem("Katana");
// AttachUtils.attachEntityToEntityAtBone(goblin, goblinSword, "Bone.031");
// // attach ai to evil goblin
// MindlessAttacker.attachToCreature(goblin);
// OpportunisticAttacker.attachToCreature(goblin);
//sword
// Entity sword = ItemUtils.spawnBasicItem("Katana");
// EntityUtils.initiallyPositionEntity(sword, new Vector3d(1,0.4f,2));
// EntityUtils.getRotation(sword).set(new Quaternionf().rotationY((float)(Math.PI/2.0)));
//floating island 1
// Entity island1 = ObjectUtils.spawnBasicObject("floatingisland1");
// EntityUtils.getRotation(island1).set(new Quaternionf().rotationX(-(float)(Math.PI/2.0)));
// EntityUtils.getScale(island1).set(0.3f);
// EntityUtils.initiallyPositionEntity(island1, new Vector3d(5,0.5,5));
//work on ez volumetrics shader
// Entity myCube = EntityUtils.spawnDrawableEntity("Models/unitcube.fbx");
// EntityUtils.getActor(myCube).maskShader("Cube", "Shaders/clouds1/clouds1.vs", "Shaders/clouds1/clouds1.fs");
// Globals.assetManager.addShaderToQueue("Shaders/clouds1/clouds1.vs", "Shaders/clouds1/clouds1.fs");
// myCube.putData(EntityDataStrings.DRAW_TRANSPARENT_PASS, true);
// EntityUtils.getPosition(myCube).set(3,1,3);
//work on smoke shader
// Entity myCube = EntityUtils.spawnDrawableEntity("Models/unitcube.fbx");
// EntityUtils.getActor(myCube).maskShader("Cube", "Shaders/smoke1/smoke1.vs", "Shaders/smoke1/smoke1.fs");
// Globals.assetManager.addShaderToQueue("Shaders/smoke1/smoke1.vs", "Shaders/smoke1/smoke1.fs");
// myCube.putData(EntityDataStrings.DRAW_TRANSPARENT_PASS, true);
// EntityUtils.getPosition(myCube).set(3,1,3);
// SceneLoader loader = new SceneLoader();
// loader.serverInstantiateSceneFile("Scenes/testscene1/testscene1.json");
// Entity chunk = TerrainChunk.createTerrainChunkEntity();
// Random rand = new Random();
// for(int i = 0; i < 100; i++){
// Entity leaves = EntityUtils.spawnDrawableEntity(AssetDataStrings.LEAVES_MODEL);
// float rad = rand.nextFloat();
// float angle = (float)(rand.nextFloat() * 2.0 * Math.PI);
// Vector3d position = new Vector3d(Math.cos(angle) * rad + 4,1 + (rand.nextFloat() - 0.5),Math.sin(angle) * rad + 4);
// Quaternionf rotation = new Quaternionf(rand.nextFloat(), rand.nextFloat(), rand.nextFloat(), rand.nextFloat()).normalize();
// ServerEntityUtils.repositionEntity(leaves, position);
// EntityUtils.getPosition(leaves).set(position);
// EntityUtils.getRotation(leaves).slerp(rotation, 0.3f);
// leaves.removeData(EntityDataStrings.DRAW_SOLID_PASS);
// leaves.putData(EntityDataStrings.DRAW_TRANSPARENT_PASS, true);
// }
// Globals.entityManager.registerBehaviorTree(new BehaviorTree() {
// int i = 0;
// public void simulate(){
// if(i < 100){
// i++;
// CollisionObjUtils.getCollidable(sword).addImpulse(new Impulse(new Vector3d(0,0,1), new Vector3d(-1,0,0), 0.001, Collidable.TYPE_CREATURE));
// EntityUtils.getPosition(sword).set(1,0.2f,2);
// }
// }});
// Globals.entityManager.registerBehaviorTree(new BehaviorTree() {
// int i = 0;
// public void simulate(){
// if(i < 10000){
// i++;
// if(i % 100 == 0){
// Entity sword = ItemUtils.spawnBasicItem("Katana");
// EntityUtils.getPosition(sword).set(new Vector3f(1,1.4f,2));
// EntityUtils.getRotation(sword).set(new Quaternionf().rotationY((float)(Math.PI/2.0)));
// }
// }
// }});
// DebugVisualizerUtils.spawnVectorVisualizer(new Vector3d(0,0,0), new Vector3d(-1,-1,-1));
// Entity shorts = ItemUtils.spawnBasicItem("boots1");
// EntityUtils.getPosition(shorts).set(new Vector3f(2,0.1f,2));
// // Entity hair = ItemUtils.spawnBasicItem("hairshort1");
// // EntityUtils.getPosition(hair).set(new Vector3f(2,0.1f,1));
// Entity bow = ItemUtils.spawnBasicItem("bow1");
// EntityUtils.getPosition(bow).set(new Vector3f(2,0.1f,1));
//crate
// Entity crate = EntityUtils.spawnDrawableEntity("Models/crate2.fbx");
// EntityUtils.getPosition(crate).set(5,0.5,5);
// EntityUtils.getScale(crate).set(new Vector3f(0.5f));
// //center flame
// Entity fire = ParticleUtils.spawnStaticBillboardParticle();
// EntityUtils.getPosition(fire).set(new Vector3f(1,0.2f,1));
// EntityUtils.getScale(fire).set(0.6f);
// Actor fireActor = EntityUtils.getActor(fire);
// fireActor.maskShader("particleBillboard", "Shaders/flame1/flame.vs", "Shaders/flame1/flame.fs");
// Globals.assetManager.addShaderToQueue("Shaders/flame1/flame.vs", "Shaders/flame1/flame.fs");
// // //campfire
// Entity campfire = EntityUtils.spawnDrawableEntity("Models/campfire1.fbx");
// EntityUtils.getPosition(campfire).set(1,0,1);
// EntityUtils.getRotation(campfire).rotationX(-(float)Math.PI/2.0f);
// campfire.putData(EntityDataStrings.DRAW_OUTLINE, true);
// //flame
// Entity cube = EntityUtils.spawnDrawableEntity("Models/flame1.fbx");
// //shader mask
// EntityUtils.getActor(cube).maskShader("Sphere", "Shaders/flame2/flame.vs", "Shaders/flame2/flame.fs");
// Globals.assetManager.addShaderToQueue("Shaders/flame2/flame.vs", "Shaders/flame2/flame.fs");
// EntityUtils.getScale(cube).set(0.8f);
// EntityUtils.getPosition(cube).set(1,0.08f,1);
// EntityUtils.getRotation(cube).rotationX(-(float)Math.PI/2.0f);
// //texture mask
// EntityUtils.getActor(cube).addTextureMask(RenderUtils.generateVolumetricTextureMask("Sphere"));
// //set draw volumetric
// cube.putData(EntityDataStrings.DRAW_VOLUMETRIC, true);
// Globals.assetManager.addShaderToQueue("Shaders/grass1/grass1.vs", "Shaders/grass1/grass1.gs", "Shaders/grass1/grass1.fs");
// Entity grass = EntityUtils.spawnDrawableEntity("Models/grass1.fbx");
// //shader mask
// EntityUtils.getActor(grass).maskShader("Cube", "Shaders/grass1/grass1.vs", "Shaders/grass1/grass1.gs", "Shaders/grass1/grass1.fs");
// EntityUtils.getPosition(grass).set(3,0,1);
// queue grass shader
// Globals.assetManager.addShaderToQueue("Shaders/grass1/grass1.vs", "Shaders/grass1/grass1.gs", "Shaders/grass1/grass1.fs");
// for(int x = 0; x < 10; x++){
// for(int y = 0; y < 10; y++){
// Entity grass = EntityUtils.spawnDrawableEntity("Models/grass1.fbx");
// //shader mask
// EntityUtils.getActor(grass).maskShader("Cube", "Shaders/grass1/grass1.vs", "Shaders/grass1/grass1.gs", "Shaders/grass1/grass1.fs");
// EntityUtils.getPosition(grass).set(3 + x / 5.0f,0.0,1 + y / 5.0f);
// }
// }
// //water cube
// Entity water = EntityUtils.spawnDrawableEntity("Models/watercube1.fbx");
// EntityUtils.getActor(water).maskShader("Cube", "Shaders/water1/water.vs", "Shaders/water1/water.fs");
// Globals.assetManager.addShaderToQueue("Shaders/water1/water.vs", "Shaders/water1/water.fs");
// // EntityUtils.getPosition(water).set(5,0.51,5);
// // EntityUtils.getRotation(water).rotationX((float)Math.PI/4.0f);
// EntityUtils.getPosition(water).set(5,-0.1,5);
// EntityUtils.getScale(water).set(1,1,1);
// //texture mask
// EntityUtils.getActor(water).addTextureMask(RenderUtils.generateVolumetricTextureMask("Cube"));
// //set draw volumetric
// water.putData(EntityDataStrings.DRAW_VOLUMETRIC, true);
// water.removeData(EntityDataStrings.DRAW_SOLID_PASS);
// water.putData(EntityDataStrings.DRAW_TRANSPARENT_PASS, true);
// //shrine 2
// Entity shrine = EntityUtils.spawnDrawableEntity("Models/shrine2.fbx");
// EntityUtils.getPosition(shrine).set(15,0,15);
// EntityUtils.getRotation(shrine).rotationX((float)-Math.PI/2.0f);
// shrine.putData(EntityDataStrings.DRAW_OUTLINE, true);
// goblin = CreatureUtils.spawnBasicCreature("Goblin");
// CollisionObjUtils.positionCharacter(goblin, new Vector3f(3, 0, 4));
// EntityUtils.getScale(goblin).set(0.005f);
//
// goblin = CreatureUtils.spawnBasicCreature("Goblin");
// CollisionObjUtils.positionCharacter(goblin, new Vector3f(4, 0, 3));
// EntityUtils.getScale(goblin).set(0.005f);
//
// goblin = CreatureUtils.spawnBasicCreature("Goblin");
// CollisionObjUtils.positionCharacter(goblin, new Vector3f(3, 0, 3));
// EntityUtils.getScale(goblin).set(0.005f);
// UnitUtils.spawnTextGoblin(10, 0, 10);
// StructureUtils.spawnBasicStructure("building1", new Vector3f(5,2.4f,5), new Quaternionf());
// Entity bow = ItemUtils.spawnBasicItem("Bow");
// EntityUtils.getPosition(bow).set(1, 1, 2);
// NavMeshPathfinder.navigatePointToPointInMesh(G*lobals.navMeshManager.getMeshes().get(0), new Vector3d(10,0,5), new Vector3d(5,0,10));
// NavMesh mesh = new NavMesh();
// NavCube cube = new NavCube(5,0,0,10,5,5);
// mesh.addNode(cube);
// Globals.navMeshManager.addMesh(mesh);
// Entity fallOak = FoliageUtils.spawnBasicFoliage("FallOak1");
// EntityUtils.getPosition(fallOak).set(1,0,3);
//
// Entity spark = ParticleUtils.spawnBillboardParticle("Textures/animetree1leaves1.png", 150000, new Vector3f(0,0,0), 0, 0);
// EntityUtils.getPosition(spark).set(new Vector3f(3,3,3));
// EntityUtils.getScale(spark).mul(1f);
// System.out.println(Globals.drawCellManager.)
// Entity deer = CreatureUtils.spawnBasicCreature("Deer");
// EntityUtils.getPosition(deer).set(5, 0.25f, 3);
// Model deerModel = Globals.assetManager.fetchModel("Models/deer1.fbx");
// deerModel.describeHighLevel();
// CollisionObjUtils.positionCharacter(fallOak, new Vector3f(1, 0, 3));
//
//
// Entity testHomie = CreatureUtils.spawnBasicCreature("Human");
// EntityUtils.getScale(testHomie).set(0.005f);
// CreatureUtils.positionCharacter(testHomie, new Vector3f(10,1,10));
//
// Entity sword = ItemUtils.spawnBasicItem("Katana");
// AttachUtils.attachEntityToEntityAtBone(testHomie, sword, "Bone.020");
// CollisionObjUtils.spawnCollisionPlane(new Vector3f(1,1,1), new Vector3f(8,2,10), new Quaternionf()); // .rotateLocalX(0.75f)
// CollisionObjUtils.spawnCollisionCube(new Vector3f(1,1,1), new Vector3f(10,1,10), new Quaternionf());
// CreatureUtils.positionCharacter(Globals.playerCharacter, new Vector3f(10,3,10));
// StructureUtils.spawnBasicStructure("building1", new Vector3f(10,2.4f,15), new Quaternionf().rotateLocalY((float)Math.PI));
}
}

View File

@ -0,0 +1,253 @@
package electrosphere.engine.loadingthreads;
import java.util.concurrent.TimeUnit;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.movement.ApplyRotationTree;
import electrosphere.entity.types.camera.CameraEntityUtils;
import electrosphere.game.client.cells.DrawCellManager;
import electrosphere.game.client.targeting.crosshair.Crosshair;
import electrosphere.logger.LoggerInterface;
import electrosphere.menu.MenuGenerators;
import electrosphere.menu.MenuGeneratorsMultiplayer;
import electrosphere.menu.WindowStrings;
import electrosphere.menu.WindowUtils;
import electrosphere.net.NetUtils;
import electrosphere.net.client.ClientNetworking;
import electrosphere.renderer.ui.Window;
import electrosphere.client.culling.ClientEntityCullingManager;
import electrosphere.client.sim.ClientSimulation;
import electrosphere.controls.ControlHandler;
public class ClientLoading {
protected static void loadMainMenu(){
Window loadingWindow = (Window)Globals.elementManager.getWindow(WindowStrings.WINDOW_LOADING);
WindowUtils.recursiveSetVisible(loadingWindow,false);
WindowUtils.focusWindow(WindowStrings.WINDOW_MENU_MAIN);
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_MAIN), true);
}
protected static void loadCharacterServer(){
Window loadingWindow = (Window)Globals.elementManager.getWindow(WindowStrings.WINDOW_LOADING);
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_MAIN), false);
WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu());
loadingWindow.setVisible(true);
//disable menu input
Globals.controlHandler.setHandlerState(ControlHandler.ControlsState.NO_INPUT);
//initialize the client thread (client)
initClientThread();
//while we don't know what races are playable, wait
while(Globals.gameConfigCurrent.getCreatureTypeLoader().getPlayableRaces().size() == 0){
try {
TimeUnit.MILLISECONDS.sleep(5);
} catch (InterruptedException ex) {}
}
//once we have them, bring up the character creation interface
//init character creation window
//eventually should replace with at ui to select an already created character or create a new one
WindowUtils.replaceMainMenuContents(MenuGeneratorsMultiplayer.createMultiplayerCharacterCreationWindow());
//make loading dialog disappear
loadingWindow.setVisible(false);
//make character creation window visible
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_MAIN), true);
//recapture window
Globals.controlHandler.setShouldRecapture(true);
//log
LoggerInterface.loggerEngine.INFO("[Client]Finished loading character creation menu");
//set menu controls again
Globals.controlHandler.setHandlerState(ControlHandler.ControlsState.TITLE_MENU);
}
protected static void loadClientWorld(){
Window loadingWindow = (Window)Globals.elementManager.getWindow(WindowStrings.WINDOW_LOADING);
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_MAIN), false);
WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu());
loadingWindow.setVisible(true);
//disable menu input
Globals.controlHandler.setHandlerState(ControlHandler.ControlsState.NO_INPUT);
//collision engine
if(!Globals.RUN_SERVER){
LoadingUtils.initCommonWorldData(Globals.RUN_SERVER);
}
//initialize the "real" objects simulation
initClientSimulation();
//initialize the cell manager (client)
initDrawCellManager();
//initialize the basic graphical entities of the world (skybox, camera)
initWorldBaseGraphicalEntities();
//init arena specific stuff (ie different skybox colors)
initArenaGraphicalEntities();
//sets micro and macro sims to ready if they exist
setSimulationsToReady();
//init culling manager and other graphics-focused non-simulation items
initEntitycullingManager();
//hide cursor
Globals.controlHandler.hideMouse();
//make loading window disappear
loadingWindow.setVisible(false);
//recapture screen
Globals.controlHandler.setShouldRecapture(true);
//set rendering flags to main game mode
Globals.RENDER_FLAG_RENDER_SHADOW_MAP = true;
Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT = true;
Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER = true;
Globals.RENDER_FLAG_RENDER_UI = true;
Globals.RENDER_FLAG_RENDER_BLACK_BACKGROUND = false;
Globals.RENDER_FLAG_RENDER_WHITE_BACKGROUND = false;
LoggerInterface.loggerEngine.INFO("[Client]Finished loading main game");
//set controls state
Globals.controlHandler.setHandlerState(ControlHandler.ControlsState.MAIN_GAME);
}
private static void initClientThread(){
//start client networking
Thread clientThread = null;
if(Globals.RUN_CLIENT){
Globals.clientConnection = new ClientNetworking(NetUtils.getAddress(),NetUtils.getPort());
clientThread = new Thread(Globals.clientConnection);
clientThread.start();
}
}
/**
* Creates client simulation object
*/
private static void initClientSimulation(){
if(Globals.clientSimulation == null){
Globals.clientSimulation = new ClientSimulation();
}
}
/**
* Sets client simulation object state to ready
*/
private static void setSimulationsToReady(){
Globals.clientSimulation.setReady(true);
}
private static void initWorldBaseGraphicalEntities(){
/*
Skybox
*/
// Model skyboxModel = Globals.assetManager.fetchModel(AssetDataStrings.ASSET_STRING_SKYBOX_BASIC);
// Globals.skybox = EntityUtils.spawnDrawableEntity(AssetDataStrings.ASSET_STRING_SKYBOX_BASIC);
/*
Player Camera
*/
Globals.playerCamera = CameraEntityUtils.spawnPlayerEntityTrackingCameraEntity(new Vector3f(1,0,1), new Vector3f(0,0,1));
// Globals.playerCamera = CameraEntityUtils.spawnPlayerEntityAirplaneTrackingCameraEntity(new Vector3f(1,0,1), new Vector3f(0,0,1));
/*
Targeting crosshair
*/
Crosshair.initCrossHairEntity();
}
static void initArenaGraphicalEntities(){
float skyR = 150;
float skyG = 200;
float skyB = 250;
float groundR = 20;
float groundG = 20;
float groundB = 20;
Globals.skyboxColors.add(new Vector3f(skyR,skyG,skyB));
Globals.skyboxColors.add(new Vector3f(skyR,skyG,skyB));
Globals.skyboxColors.add(new Vector3f(groundR,groundG,groundB));
Globals.skyboxColors.add(new Vector3f(groundR,groundG,groundB));
Globals.skyboxColors.add(new Vector3f(skyR,skyG,skyB));
Globals.skyboxColors.add(new Vector3f(skyR,skyG,skyB));
Globals.skyboxColors.add(new Vector3f(groundR,groundG,groundB));
Globals.skyboxColors.add(new Vector3f(groundR,groundG,groundB));
//starry sky true skybox
Entity skybox = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(skybox, "Models/skyboxSphere.fbx");
EntityUtils.getRotation(skybox).rotateX((float)(-Math.PI/2.0f));
EntityUtils.getScale(skybox).mul(2000.0f);
Globals.assetManager.queueOverrideMeshShader("Models/skyboxSphere.fbx", "Sphere", "Shaders/skysphere/skysphere.vs", "Shaders/skysphere/skysphere.fs");
//cloud ring pseudo skybox
Entity cloudRing = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(cloudRing, "Models/cloudRing.fbx");
EntityUtils.getRotation(cloudRing).rotateX((float)(-Math.PI/2.0f));
EntityUtils.getScale(cloudRing).mul(1000.0f);
Globals.clientScene.registerBehaviorTree(new ApplyRotationTree(cloudRing,new Quaternionf().rotationZ(0.0001f)));
Globals.assetManager.queueOverrideMeshShader("Models/cloudRing.fbx", "Sphere", "Shaders/skysphere/skysphere.vs", "Shaders/skysphere/skysphere.fs");
}
static void initDrawCellManager(){
//initialize draw cell manager
Globals.drawCellManager = new DrawCellManager(Globals.commonWorldData, Globals.clientTerrainManager, 0, 0);
//set our draw cell manager to actually generate drawable chunks
Globals.drawCellManager.setGenerateDrawables(true);
//Alerts the client simulation that it should start loading terrain
Globals.clientSimulation.setLoadingTerrain(true);
//wait for all the terrain data to arrive
while(Globals.drawCellManager.containsInvalidCell()){
// Globals.drawCellManager.updateInvalidCell();
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException ex) {
}
// System.out.println("invalid cell");
}
while(Globals.drawCellManager.containsUndrawableCell()){
// Globals.drawCellManager.makeCellDrawable();
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException ex) {
}
// System.out.println("undrawable");
}
while(Globals.drawCellManager.containsPhysicsNeedingCell()){
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException ex) {
}
}
// System.out.println("Draw Cell Manager ready");
}
private static void initEntitycullingManager(){
Globals.clientEntityCullingManager = new ClientEntityCullingManager(Globals.clientScene);
}
}

View File

@ -0,0 +1,135 @@
package electrosphere.engine.loadingthreads;
import java.util.concurrent.TimeUnit;
import org.joml.Vector3f;
import electrosphere.auth.AuthenticationManager;
import electrosphere.engine.Globals;
import electrosphere.entity.types.camera.CameraEntityUtils;
import electrosphere.game.client.targeting.crosshair.Crosshair;
import electrosphere.game.server.terrain.manager.ServerTerrainManager;
import electrosphere.game.server.world.ServerWorldData;
import electrosphere.logger.LoggerInterface;
import electrosphere.menu.MenuGenerators;
import electrosphere.menu.WindowStrings;
import electrosphere.menu.WindowUtils;
import electrosphere.renderer.ui.Window;
import electrosphere.server.saves.SaveUtils;
import electrosphere.util.FileUtils;
import electrosphere.controls.ControlHandler;
public class DebugSPWorldLoading {
protected static void loadDebugSPWorld(){
Window loadingWindow = (Window)Globals.elementManager.getWindow(WindowStrings.WINDOW_LOADING);
//show loading
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_MAIN), false);
WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu());
loadingWindow.setVisible(true);
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,100,0.0f,0);
if(!SaveUtils.getSaves().contains("random_sp_world")){
//
//the juicy server GENERATION part
//
//init save structure
SaveUtils.createOrOverwriteSave("random_sp_world");
//create terrain
Globals.serverTerrainManager.generate();
Globals.serverTerrainManager.save(SaveUtils.deriveSaveDirectoryPath("random_sp_world"));
//create world.json
Globals.serverWorldData = ServerWorldData.createGameWorld(Globals.serverTerrainManager);
FileUtils.serializeObjectToSavePath("random_sp_world", "./world.json", Globals.serverWorldData);
}
//load just-created save
SaveUtils.loadSave("random_sp_world");
//start initializing game datastructures
// Globals.griddedDataCellManager.init(Globals.serverWorldData);
LoadingUtils.initGriddedRealm();
//initialize the "virtual" objects simulation
LoadingUtils.initMacroSimulation();
LoggerInterface.loggerEngine.INFO("run server: " + Globals.RUN_SERVER + " run client: " + Globals.RUN_CLIENT);
//init the data of the world
// LoadingUtils.initTerrainDataCellManager();
//init authentication
LoadingUtils.initAuthenticationManager();
//initialize the local connection
Globals.clientUsername = "testuser";
Globals.clientPassword = AuthenticationManager.getHashedString("testpass");
LoadingUtils.initLocalConnection();
//initialize the "real" objects simulation
LoadingUtils.initMicroSimulation();
//collision engine
LoadingUtils.initCommonWorldData(Globals.RUN_SERVER);
//init game specific stuff (ie different skybox colors)
LoadingUtils.initGameGraphicalEntities();
//set simulations to ready if they exist
LoadingUtils.setSimulationsToReady();
//log
LoggerInterface.loggerEngine.INFO("[Server]Finished loading main world");
//the less juicy client setup part
while(Globals.gameConfigCurrent.getCreatureTypeLoader().getPlayableRaces().size() == 0){
try {
TimeUnit.MILLISECONDS.sleep(5);
} catch (InterruptedException ex) {}
}
LoadingUtils.spawnLocalPlayerTestEntity();
initWorldBaseGraphicalEntities();
// SeekTown.attachToCreature(Globals.playerEntity);
//hide cursor
Globals.controlHandler.hideMouse();
//make loading window disappear
loadingWindow.setVisible(false);
//recapture screen
Globals.controlHandler.setShouldRecapture(true);
//set rendering flags to main game mode
Globals.RENDER_FLAG_RENDER_SHADOW_MAP = true;
Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT = true;
Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER = true;
Globals.RENDER_FLAG_RENDER_UI = true;
Globals.RENDER_FLAG_RENDER_BLACK_BACKGROUND = false;
Globals.RENDER_FLAG_RENDER_WHITE_BACKGROUND = false;
LoggerInterface.loggerEngine.INFO("[Client]Finished loading main game");
//set controls state
Globals.controlHandler.setHandlerState(ControlHandler.ControlsState.MAIN_GAME);
}
private static void initWorldBaseGraphicalEntities(){
/*
Skybox
*/
// Model skyboxModel = Globals.assetManager.fetchModel(AssetDataStrings.ASSET_STRING_SKYBOX_BASIC);
// Globals.skybox = EntityUtils.spawnDrawableEntity(AssetDataStrings.ASSET_STRING_SKYBOX_BASIC);
/*
Player Camera
*/
Globals.playerCamera = CameraEntityUtils.spawnPlayerEntityTrackingCameraEntity(new Vector3f(1,0,1), new Vector3f(0,0,1));
// Globals.playerCamera = CameraEntityUtils.spawnPlayerEntityAirplaneTrackingCameraEntity(new Vector3f(1,0,1), new Vector3f(0,0,1));
/*
Targeting crosshair
*/
Crosshair.initCrossHairEntity();
}
}

View File

@ -0,0 +1,71 @@
package electrosphere.engine.loadingthreads;
import java.util.concurrent.Semaphore;
/**
*
* @author amaterasu
*/
public class LoadingThread extends Thread {
public static final int LOAD_TITLE_MENU = 0;
public static final int LOAD_MAIN_GAME = 1;
public static final int LOAD_ARENA = 2;
public static final int LOAD_CHARACTER_SERVER = 3;
public static final int LOAD_CLIENT_WORLD = 4;
public static final int LOAD_DEBUG_RANDOM_SP_WORLD = 5;
int threadType;
Semaphore lock;
public LoadingThread(int type){
threadType = type;
lock = new Semaphore(1);
}
@Override
public void run(){
lock.acquireUninterruptibly();
switch(threadType){
case LOAD_TITLE_MENU: {
ClientLoading.loadMainMenu();
} break;
case LOAD_MAIN_GAME: {
ServerLoading.loadMainGameServer();
} break;
case LOAD_ARENA: {
ArenaLoading.loadArenaGameServer();
} break;
case LOAD_CHARACTER_SERVER: {
ClientLoading.loadCharacterServer();
} break;
case LOAD_CLIENT_WORLD: {
ClientLoading.loadClientWorld();
} break;
//intended to act like you went through the steps of setting up a vanilla settings SP world
case LOAD_DEBUG_RANDOM_SP_WORLD: {
DebugSPWorldLoading.loadDebugSPWorld();
} break;
}
lock.release();
}
public boolean isDone(){
boolean rVal = lock.tryAcquire();
if(rVal == true){
lock.release();
}
return rVal;
}
}

View File

@ -0,0 +1,287 @@
package electrosphere.engine.loadingthreads;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.concurrent.TimeUnit;
import org.joml.Quaternionf;
import org.joml.Vector2i;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.joml.Vector3i;
import electrosphere.auth.AuthenticationManager;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.ServerEntityUtils;
import electrosphere.entity.state.movement.ApplyRotationTree;
import electrosphere.entity.types.creature.CreatureTemplate;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.game.client.cells.DrawCellManager;
import electrosphere.game.collision.CommonWorldData;
import electrosphere.game.data.creature.type.CreatureType;
import electrosphere.game.data.creature.type.visualattribute.VisualAttribute;
import electrosphere.game.server.terrain.manager.ServerTerrainManager;
import electrosphere.game.server.town.Town;
import electrosphere.game.server.world.MacroData;
import electrosphere.game.server.world.ServerWorldData;
import electrosphere.net.NetUtils;
import electrosphere.net.client.ClientNetworking;
import electrosphere.net.server.Server;
import electrosphere.net.server.player.Player;
import electrosphere.server.datacell.GriddedDataCellManager;
import electrosphere.server.datacell.Realm;
import electrosphere.server.saves.SaveUtils;
import electrosphere.server.simulation.MacroSimulation;
import electrosphere.server.simulation.MicroSimulation;
/**
* Utilities for all loading thread types
*/
public class LoadingUtils {
// static void initTerrainDataCellManager(){
// Globals.griddedDataCellManager.init(Globals.serverWorldData);
// }
static void initServerGameTerrainManager(){
/*
Actually initialize the terrain manager
*/
float randomDampener = 0.0f; //0.25f;
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,100,randomDampener,0);
if(Globals.RUN_SERVER){
if(Globals.userSettings.gameplayGenerateWorld()){
Globals.serverTerrainManager.generate();
Globals.serverTerrainManager.save("./terrain.json");
} else {
SaveUtils.loadSave(Globals.currentSaveName);
}
}
/*
Set spawn point
*/
int playerStartX = 0;
int playerStartY = 0;
int discreteSize = Globals.serverTerrainManager.getWorldDiscreteSize();
int chunkSize = Globals.serverTerrainManager.getChunkWidth();
boolean found = false;
for(int x = 0; x < discreteSize; x++){
for(int y = 0; y < discreteSize; y++){
if(Globals.serverTerrainManager.getDiscreteValue(x, y)>1800){
playerStartX = x;
playerStartY = y;
found = true;
}
if(found){
break;
}
}
if(found){
break;
}
}
// Globals.spawnPoint = new Vector3f(playerStartX * chunkSize, Globals.serverTerrainManager.getHeightAtPosition(playerStartX * chunkSize,playerStartY * chunkSize), playerStartY * chunkSize);
}
static void initServerArenaTerrainManager(){
Globals.serverTerrainManager = ServerTerrainManager.constructArenaTerrainManager();
}
static void initServerArenaWorldData(){
Globals.serverWorldData = ServerWorldData.createArenaWorld();
Globals.spawnPoint = new Vector3d(1,0.1,1);
// Globals.serverTerrainManager.getChunk(0, 0).addModification(new TerrainModification(0,0,5,5,5));
}
static void initServerGameWorldData(){
Globals.serverWorldData = ServerWorldData.createGameWorld(Globals.serverTerrainManager);
}
static void initCommonWorldData(boolean FLAG_INIT_SERVER){
if(Globals.commonWorldData == null){
if(FLAG_INIT_SERVER){
Globals.commonWorldData = new CommonWorldData(Globals.serverWorldData, Globals.serverTerrainManager);
if(Globals.macroSimulation != null){
Town startTown = Globals.macroData.getTowns().get(0);
Vector2i firstPos = startTown.getPositions().get(0);
// double startX = firstPos.x * Globals.serverTerrainManager.getChunkWidth();
// double startZ = firstPos.y * Globals.serverTerrainManager.getChunkWidth();
double startX = Globals.commonWorldData.convertWorldToReal(firstPos.x);
double startZ = Globals.commonWorldData.convertWorldToReal(firstPos.y);
Globals.spawnPoint.set((float)startX,(float)Globals.commonWorldData.getElevationAtPoint(new Vector3d(startX,0,startZ)),(float)startZ);
}
} else {
//basically wait for the client to receive the world metadata
while(!Globals.clientConnection.getClientProtocol().hasReceivedWorld()){
try {
TimeUnit.MILLISECONDS.sleep(5);
} catch (InterruptedException ex) {
}
}
//then create common world data
Globals.commonWorldData = new CommonWorldData(Globals.clientWorldData, Globals.clientTerrainManager);
}
}
}
static void initServerThread(){
//start server networking
if(Globals.RUN_SERVER){
Globals.server = new Server(NetUtils.getPort());
Globals.serverThread = new Thread(Globals.server);
Globals.serverThread.start();
}
}
static void initAuthenticationManager(){
if(Globals.RUN_SERVER){
Globals.authenticationManager = new AuthenticationManager();
}
}
static void initClientThread(){
//start client networking
Thread clientThread = null;
if(Globals.RUN_CLIENT){
Globals.clientConnection = new ClientNetworking(NetUtils.getAddress(),NetUtils.getPort());
clientThread = new Thread(Globals.clientConnection);
clientThread.start();
}
}
static void initLocalConnection(){
Globals.server = new Server(NetUtils.getPort());
try {
//client -> server pipe
PipedInputStream clientInput = new PipedInputStream();
PipedOutputStream serverOutput = new PipedOutputStream(clientInput);
//server -> client pipe
PipedInputStream serverInput = new PipedInputStream();
PipedOutputStream clientOutput = new PipedOutputStream(serverInput);
//start server communication thread
Globals.server.addLocalPlayer(serverInput, serverOutput);
//start client communication thread
Globals.clientConnection = new ClientNetworking(clientInput,clientOutput);
Thread clientThread = null;
clientThread = new Thread(Globals.clientConnection);
clientThread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Spins up the gridded data cell manager
*/
protected static void initGriddedRealm(){
Realm griddedRealm = Globals.realmManager.createGriddedRealm(Globals.serverWorldData);
}
static void initGameGraphicalEntities(){
float skyR = 100;
float skyG = 150;
float skyB = 200;
float groundR = 50;
float groundG = 100;
float groundB = 150;
Globals.skyboxColors.add(new Vector3f(skyR,skyG,skyB));
Globals.skyboxColors.add(new Vector3f(skyR,skyG,skyB));
Globals.skyboxColors.add(new Vector3f(groundR,groundG,groundB));
Globals.skyboxColors.add(new Vector3f(groundR,groundG,groundB));
Globals.skyboxColors.add(new Vector3f(skyR,skyG,skyB));
Globals.skyboxColors.add(new Vector3f(skyR,skyG,skyB));
Globals.skyboxColors.add(new Vector3f(groundR,groundG,groundB));
Globals.skyboxColors.add(new Vector3f(groundR,groundG,groundB));
}
/**
* Spawns the character, and sets server side connection player object values to the appropriate chunk
*/
static void spawnLocalPlayerTestEntity(){
//
//Create entity
//
//send default template back
String race = Globals.gameConfigCurrent.getCreatureTypeLoader().getPlayableRaces().get(0);
CreatureType type = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(race);
CreatureTemplate template = new CreatureTemplate(race);
for(VisualAttribute attribute : type.getVisualAttributes()){
if(attribute.getType().equals(VisualAttribute.TYPE_BONE)){
float min = attribute.getMinValue();
float max = attribute.getMaxValue();
float defaultValue = min + (max - min)/2.0f;
//add attribute to creature template
template.putValue(attribute.getAttributeId(), defaultValue);
} else if(attribute.getType().equals(VisualAttribute.TYPE_REMESH)){
template.putValue(attribute.getAttributeId(), attribute.getVariants().get(0).getId());
}
}
Realm realm = Globals.realmManager.getRealms().iterator().next();
//spawn entity
Entity newPlayerEntity = CreatureUtils.serverSpawnBasicCreature(realm,Globals.spawnPoint,template.getCreatureType(),template);
Globals.playerEntity = newPlayerEntity;
//set player world-space coordinates
Player playerObject = Globals.playerManager.getPlayerFromId(0);
playerObject.setWorldPos(new Vector3i(
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.x),
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.y),
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.z)
));
//set client entity data
Globals.clientPlayerData.setWorldPos(playerObject.getWorldPos());
//initially position entity
ServerEntityUtils.initiallyPositionEntity(realm, newPlayerEntity, new Vector3d(Globals.spawnPoint.x + 1,Globals.spawnPoint.y + 5,Globals.spawnPoint.z + 1));
//add entity to correct cells
realm.getDataCellManager().addPlayerToRealm(playerObject);
}
static void initMacroSimulation(){
Globals.macroData = MacroData.generateWorld(0);
// Globals.macroData.describeWorld();
Globals.macroSimulation = new MacroSimulation();
Globals.macroSimulation.simulate();
// Town startTown = Globals.macroData.getTowns().get(0);
// Vector2i firstPos = startTown.getPositions().get(0);
// double startX = firstPos.x * Globals.serverTerrainManager.getChunkWidth();
// double startZ = firstPos.y * Globals.serverTerrainManager.getChunkWidth();
// Globals.spawnPoint.set((float)startX,(float)Globals.commonWorldData.getElevationAtPoint(new Vector3d(startX,0,startZ)),(float)startZ);
// Globals.macroSimulation.setReady(true);
}
static void initMicroSimulation(){
if(Globals.microSimulation == null){
Globals.microSimulation = new MicroSimulation();
}
}
static void setSimulationsToReady(){
Globals.microSimulation.setReady(true);
if(Globals.macroSimulation != null){
Globals.macroSimulation.setReady(true);
}
}
}

View File

@ -0,0 +1,45 @@
package electrosphere.engine.loadingthreads;
import electrosphere.engine.Globals;
import electrosphere.game.server.terrain.manager.ServerTerrainManager;
import electrosphere.logger.LoggerInterface;
import electrosphere.server.saves.SaveUtils;
public class ServerLoading {
protected static void loadMainGameServer(){
//initialize the terrain manager (server only)
// if(Globals.RUN_SERVER){
// initServerGameTerrainManager();
// }
//TODO: Globals.serverTerrainManager = new ServerTerrainManager(2000,50,100,randomDampener,0);
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,100,0.0f,0);
SaveUtils.loadSave(Globals.currentSaveName);
// LoadingUtils.initTerrainDataCellManager();
//TODO: set spawnpoint
//TODO: Globals.serverWorldData = ServerWorldData.createGameWorld(Globals.serverTerrainManager);
//TODO: Globals.dataCellManager = new DataCellManager(Globals.serverWorldData);
// Globals.serverWorldData = ServerWorldData.createGameWorld(Globals.serverTerrainManager);
// Globals.dataCellManager = new DataCellManager(Globals.serverWorldData);
LoggerInterface.loggerEngine.INFO("run server: " + Globals.RUN_SERVER + " run client: " + Globals.RUN_CLIENT);
//init authentication
LoadingUtils.initAuthenticationManager();
//initialize the server thread (server only)
LoadingUtils.initServerThread();
//initialize the "virtual" objects simulation
LoadingUtils.initMacroSimulation();
//initialize the "real" objects simulation
LoadingUtils.initMicroSimulation();
//collision engine
LoadingUtils.initCommonWorldData(Globals.RUN_SERVER);
//init game specific stuff (ie different skybox colors)
LoadingUtils.initGameGraphicalEntities();
//set simulations to ready if they exist
LoadingUtils.setSimulationsToReady();
//log
LoggerInterface.loggerEngine.INFO("[Server]Finished loading main world");
}
}

View File

@ -0,0 +1,25 @@
package electrosphere.entity;
import org.joml.Vector3d;
import electrosphere.entity.types.collision.CollisionObjUtils;
/**
* Client only entity utility functions
*/
public class ClientEntityUtils {
/**
* Called when the creature is first spawned to serialize to all people in its initial chunk
* @param entity
* @param position
*/
public static void initiallyPositionEntity(Entity entity, Vector3d position){
//reposition entity
CollisionObjUtils.positionCharacter(entity, position);
}
}

View File

@ -46,11 +46,8 @@ public class Entity {
return data.get(key);
}
public Entity(){
protected Entity(){
data = new HashMap<String,Object>();
while(Globals.entityManager.getEntityFromId(entity_id_iterator)!=null){
entity_id_iterator++;
}
id = entity_id_iterator;
entity_id_iterator++;
}

View File

@ -0,0 +1,105 @@
package electrosphere.entity;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
import electrosphere.engine.Globals;
import electrosphere.renderer.actor.ActorUtils;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.ServerDataCell;
import electrosphere.server.datacell.utils.EntityLookupUtils;
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
import electrosphere.server.poseactor.PoseActor;
public class EntityCreationUtils {
/**
* Creates a server entity in the given realm and position. This uses spatial entity as a server entity can't (currently) exist outside of a realm.
* @param realm The realm to attach the entity to
* @param position The position to place the entity at
* @return The entity
*/
public static Entity createServerEntity(Realm realm, Vector3d position){
Entity rVal = EntityUtils.spawnSpatialEntity();
//register to global entity id lookup table
EntityLookupUtils.registerServerEntity(rVal);
//register to data cell
ServerDataCell entityDataCell = realm.getDataCellManager().tryCreateCellAtPoint(position);
entityDataCell.getScene().registerEntity(rVal);
//maps this entity to its realm
Globals.realmManager.mapEntityToRealm(rVal, realm);
//enable behavior tree tracking
ServerBehaviorTreeUtils.registerEntity(rVal);
//register to entity data cell mapper
realm.getEntityDataCellMapper().registerEntity(rVal, entityDataCell);
return rVal;
}
/**
* Spawns an entity that is not attached to a realm (for instance an item in an inventory)
* @return The entity
*/
public static Entity createRealmlessServerEntity(){
Entity rVal = new Entity();
//register to global entity id lookup table
EntityLookupUtils.registerServerEntity(rVal);
//enable behavior tree tracking
ServerBehaviorTreeUtils.registerEntity(rVal);
return rVal;
}
/**
* Creates an entity for the client
* @return The entity
*/
public static Entity createClientSpatialEntity(){
Entity rVal = EntityUtils.spawnSpatialEntity();
Globals.clientSceneWrapper.getScene().registerEntity(rVal);
return rVal;
}
/**
* Creates a non-spatial entity for the client
* @return The entity
*/
public static Entity createClientNonSpatialEntity(){
Entity rVal = new Entity();
Globals.clientSceneWrapper.getScene().registerEntity(rVal);
return rVal;
}
/**
* Makes an already created entity a poseable entity by backing it with a PoseActor
* @param entity The entity
* @param modelPath The model path for the model to back the pose actor
*/
public static void makeEntityPoseable(Entity entity, String modelPath){
entity.putData(EntityDataStrings.POSE_ACTOR, new PoseActor(modelPath));
entity.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
entity.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().identity());
entity.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
entity.putData(EntityDataStrings.DATA_STRING_DRAW, true);
entity.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
}
/**
* MAkes an already created entity a drawable entity (client only) by backing it with an Actor
* @param entity The entity
* @param modelPath The model path for the model to back the actor
*/
public static void makeEntityDrawable(Entity entity, String modelPath){
entity.putData(EntityDataStrings.DATA_STRING_ACTOR, ActorUtils.createActorFromModelPath(modelPath));
entity.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
entity.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().identity());
entity.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
entity.putData(EntityDataStrings.DATA_STRING_DRAW, true);
entity.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
Globals.clientScene.registerEntity(entity);
Globals.clientScene.registerEntityToTag(entity, EntityTags.DRAWABLE);
}
}

View File

@ -35,15 +35,19 @@ public class EntityDataStrings {
public static final String DATA_STRING_CREATURE_IS_CREATURE = "isCreature";
public static final String DATA_STRING_CREATURE_TYPE = "creatureType";
public static final String DATA_STRING_CREATURE_CONTROLLER_PLAYER_ID = "creaturePlayerId";
public static final String DATA_STRING_MOVEMENT_BT = "movementBT";
public static final String SPRINT_TREE = "sprintBT";
public static final String CLIENT_MOVEMENT_BT = "clientMovementBT";
public static final String SERVER_MOVEMENT_BT = "serverMovementBT";
public static final String CLIENT_SPRINT_TREE = "clientSprintBT";
public static final String SERVER_SPRINT_TREE = "serverSprintBT";
public static final String DATA_STRING_FACING_VECTOR = "facingVector";
public static final String DATA_STRING_VELOCITY = "velocity";
public static final String DATA_STRING_ACCELERATION = "acceleration";
public static final String DATA_STRING_MAX_NATURAL_VELOCITY = "velocityMaxNatural";
public static final String CREATURE_ATTRIBUTE_VARIANT = "creatureAttributeVariant";
public static final String ROTATOR_TREE = "rotatorTree";
public static final String JUMP_TREE = "jumpTree";
public static final String CLIENT_ROTATOR_TREE = "clientRotatorTree";
public static final String SERVER_ROTATOR_TREE = "serverRotatorTree";
public static final String CLIENT_JUMP_TREE = "clientJumpTree";
public static final String SERVER_JUMP_TREE = "serverJumpTree";
public static final String FALL_TREE = "fallTree";
public static final String CREATURE_TEMPLATE = "creatureTemplate";
@ -110,7 +114,8 @@ public class EntityDataStrings {
Gravity Entity
*/
public static final String GRAVITY_ENTITY = "gravityEntity";
public static final String GRAVITY_TREE = "gravityTree";
public static final String CLIENT_GRAVITY_TREE = "clientGravityTree";
public static final String SERVER_GRAVITY_TREE = "serverGravityTree";
/*
Collision Entity
@ -134,7 +139,8 @@ public class EntityDataStrings {
public static final String COLLISION_ENTITY_DATA_PARENT = "collisionDataParent";
public static final String COLLIDABLE_TREE = "collidableTree";
public static final String SERVER_COLLIDABLE_TREE = "serverCollidableTree";
public static final String CLIENT_COLLIDABLE_TREE = "clientCollidableTree";
public static final String HITBOX_DATA = "hitboxData";
public static final String HITBOX_ASSOCIATED_LIST = "hitboxAssociatedList";
@ -170,7 +176,8 @@ public class EntityDataStrings {
/*
Attack behavior tree
*/
public static final String ATTACK_TREE = "attackTree";
public static final String CLIENT_ATTACK_TREE = "clientAttackTree";
public static final String SERVER_ATTACK_TREE = "serverAttackTree";
public static final String ATTACK_MOVE_TYPE_ACTIVE = "attackMoveTypeActive";
public static final String ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND = "MELEE_WEAPON_SWING_ONE_HAND";
@ -225,7 +232,8 @@ public class EntityDataStrings {
Inventory in general
*/
public static final String NATURAL_INVENTORY = "inventoryNatural";
public static final String INVENTORY_STATE = "inventoryState";
public static final String CLIENT_INVENTORY_STATE = "clientInventoryState";
public static final String SERVER_INVENTORY_STATE = "serverInventoryState";
/*
Iron sight
@ -236,6 +244,11 @@ public class EntityDataStrings {
AI stuff
*/
public static final String VIEW_PITCH = "aiViewPitch";
/**
* Pose actor
*/
public static final String POSE_ACTOR = "poseActor";
/*
Entity categories

View File

@ -6,7 +6,6 @@
package electrosphere.entity;
import electrosphere.engine.Globals;
import electrosphere.entity.state.collidable.CollidableTree;
import electrosphere.entity.state.movement.GroundMovementTree;
import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.entity.types.creature.CreatureUtils;
@ -14,7 +13,11 @@ import electrosphere.entity.types.item.ItemUtils;
import electrosphere.renderer.Model;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.actor.ActorUtils;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.ServerDataCell;
import electrosphere.server.datacell.utils.DataCellSearchUtils;
import electrosphere.server.datacell.utils.EntityLookupUtils;
import electrosphere.server.poseactor.PoseActor;
import org.joml.Quaternionf;
import org.joml.Vector3d;
@ -42,7 +45,12 @@ public class EntityUtils {
return (String)e.getData(EntityDataStrings.DATA_STRING_MODEL_PATH);
}
public static Entity spawnDrawableEntity(String modelPath){
/**
* Creates an entity with an associated actor
* @param modelPath The model path of the model for the actor
* @return The entity
*/
protected static Entity spawnDrawableEntity(String modelPath){
Entity rVal = new Entity();
rVal.putData(EntityDataStrings.DATA_STRING_ACTOR, ActorUtils.createActorFromModelPath(modelPath));
// rVal.putData(EntityDataStrings.DATA_STRING_MODEL_PATH, modelPath);
@ -51,12 +59,17 @@ public class EntityUtils {
rVal.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
rVal.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
Globals.entityManager.registerEntity(rVal);
Globals.entityManager.registerEntityToTag(rVal, EntityTags.DRAWABLE);
Globals.clientScene.registerEntity(rVal);
Globals.clientScene.registerEntityToTag(rVal, EntityTags.DRAWABLE);
return rVal;
}
public static Entity spawnDrawableEntityWithPreexistingModel(String modelPath){
/**
* Creates an entity with an actor based on a model that already exists or is actively being loaded, not sure
* @param modelPath The path to the model in asset manager
* @return The entity
*/
protected static Entity spawnDrawableEntityWithPreexistingModel(String modelPath){
Entity rVal = new Entity();
rVal.putData(EntityDataStrings.DATA_STRING_ACTOR, ActorUtils.createActorOfLoadingModel(modelPath));
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
@ -64,20 +77,37 @@ public class EntityUtils {
rVal.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
rVal.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
Globals.entityManager.registerEntity(rVal);
Globals.entityManager.registerEntityToTag(rVal, EntityTags.DRAWABLE);
Globals.clientScene.registerEntity(rVal);
Globals.clientScene.registerEntityToTag(rVal, EntityTags.DRAWABLE);
return rVal;
}
/**
* Spawns an entity with a backing pose actor (server side presumably)
* @param modelPath The model path to back the pose actor
* @return The entity
*/
protected static Entity spawnPoseableEntity(String modelPath){
Entity rVal = new Entity();
rVal.putData(EntityDataStrings.POSE_ACTOR, new PoseActor(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_ROTATION, new Quaternionf().identity());
rVal.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
rVal.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
return rVal;
}
public static Entity spawnUIEntity(String modelPath){
protected static Entity spawnUIEntity(String modelPath){
Entity rVal = new Entity();
rVal.putData(EntityDataStrings.DATA_STRING_ACTOR, ActorUtils.createActorFromModelPath(modelPath));
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().rotateAxis((float)0, new Vector3f(1,0,0)));
rVal.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
rVal.putData(EntityDataStrings.DATA_STRING_UI_ELEMENT, true);
Globals.entityManager.registerEntity(rVal);
Globals.entityManager.registerEntityToTag(rVal, EntityTags.UI);
Globals.clientScene.registerEntity(rVal);
Globals.clientScene.registerEntityToTag(rVal, EntityTags.UI);
return rVal;
}
@ -85,21 +115,32 @@ public class EntityUtils {
* Spawns an entity that has a position in the world, but isn't necessarily drawable
* @return the entity
*/
public static Entity spawnSpatialEntity(){
protected static Entity spawnSpatialEntity(){
Entity rVal = new Entity();
// rVal.putData(EntityDataStrings.DATA_STRING_MODEL_PATH, modelPath);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().identity());
rVal.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
Globals.entityManager.registerEntity(rVal);
EntityLookupUtils.registerServerEntity(rVal);
return rVal;
}
public static void cleanUpDrawableEntity(Entity e){
if(e != null){
Globals.entityManager.deregisterEntity(e);
// getEntityModelPath(e).free();
/**
* Cleans up the entity and deregisters it from all tracking datastructures
* @param e The entity to clean up
*/
public static void cleanUpEntity(Entity e){
//remove from client
Globals.clientSceneWrapper.getScene().deregisterEntity(e);
//remove from all server classes
if(Globals.realmManager != null){
Realm realm = Globals.realmManager.getEntityRealm(e);
if(realm != null){
realm.getEntityDataCellMapper().ejectEntity(e);
}
Globals.realmManager.removeEntity(e);
}
EntityLookupUtils.removeEntity(e);
}
// public static void setEntityID(Entity e, int id){
@ -109,6 +150,10 @@ public class EntityUtils {
public static Actor getActor(Entity e){
return (Actor)e.getData(EntityDataStrings.DATA_STRING_ACTOR);
}
public static PoseActor getPoseActor(Entity e){
return (PoseActor)e.getData(EntityDataStrings.POSE_ACTOR);
}
public static void setVisible(Entity entity, boolean visible){
entity.putData(EntityDataStrings.DATA_STRING_DRAW, visible);
@ -121,65 +166,5 @@ public class EntityUtils {
public static boolean getDraw(Entity entity){
return (boolean)entity.getData(EntityDataStrings.DATA_STRING_DRAW);
}
/**
* Called when the creature is first spawned to serialize to all people in its initial chunk
* @param entity
* @param position
*/
public static void initiallyPositionEntity(Entity entity, Vector3d position){
//if server, get current server data cell
if(Globals.RUN_SERVER){
ServerDataCell oldDataCell = Globals.dataCellManager.getDataCellAtPoint(EntityUtils.getPosition(entity));
ServerDataCell newDataCell = Globals.dataCellManager.getDataCellAtPoint(position);
if(newDataCell != null){
//initialize server datacell tracking of this entity
Globals.dataCellManager.initializeServerSideEntity(entity, newDataCell);
} else {
//if it doesn't already exist, try creating it and if successfull move creature
newDataCell = Globals.dataCellManager.tryCreateGroundDataCell(EntityUtils.getPosition(entity));
//initialize server datacell tracking of this entity
Globals.dataCellManager.initializeServerSideEntity(entity, newDataCell);
}
//if the server is also a client, update the drawcell manager to know to pull new chunks
if(Globals.RUN_CLIENT){
Globals.drawCellManager.invalidateAllCells();
Globals.drawCellManager.setCellX(Globals.clientPlayerData.getWorldPositionX());
Globals.drawCellManager.setCellY(Globals.clientPlayerData.getWorldPositionY());
}
}
//reposition entity
CollisionObjUtils.positionCharacter(entity, position);
}
/**
* Called to reposition the creature
* @param entity
* @param position
*/
public static void repositionEntity(Entity entity, Vector3d position){
//if server, get current server data cell
if(Globals.RUN_SERVER){
ServerDataCell oldDataCell = Globals.dataCellManager.getDataCellAtPoint(EntityUtils.getPosition(entity));
ServerDataCell newDataCell = Globals.dataCellManager.getDataCellAtPoint(position);
if(newDataCell != null){
ServerDataCell.moveEntityFromCellToCell(entity, oldDataCell, newDataCell);
} else {
//if it doesn't already exist, try creating it and if successfull move creature
newDataCell = Globals.dataCellManager.tryCreateGroundDataCell(EntityUtils.getPosition(entity));
if(newDataCell != null){
ServerDataCell.moveEntityFromCellToCell(entity, oldDataCell, newDataCell);
}
}
//if the server is also a client, update the drawcell manager to know to pull new chunks
if(Globals.RUN_CLIENT){
Globals.drawCellManager.invalidateAllCells();
Globals.drawCellManager.setCellX(Globals.clientPlayerData.getWorldPositionX());
Globals.drawCellManager.setCellY(Globals.clientPlayerData.getWorldPositionY());
}
}
//reposition entity
CollisionObjUtils.positionCharacter(entity, Globals.spawnPoint);
}
}

View File

@ -6,10 +6,12 @@ import electrosphere.entity.types.attach.AttachUtils;
import electrosphere.logger.LoggerInterface;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import org.joml.Vector3d;
@ -23,30 +25,32 @@ public class Scene {
Map<Integer,Entity> entityIdMap = new ConcurrentHashMap<Integer,Entity>();
Map<Integer,Integer> clientToServerIdMap = new ConcurrentHashMap<Integer,Integer>();
Map<Integer,Integer> serverToClientIdMap = new ConcurrentHashMap<Integer,Integer>();
Map<String,List<Entity>> tagEntityMap = new ConcurrentHashMap<String,List<Entity>>();
Map<String,Set<Entity>> tagEntityMap = new ConcurrentHashMap<String,Set<Entity>>();
List<Entity> entityList = new CopyOnWriteArrayList<Entity>();
List<BehaviorTree> behaviorTreeList = new CopyOnWriteArrayList<BehaviorTree>();
public Scene(){
tagEntityMap.put(EntityTags.BONE_ATTACHED, new LinkedList<Entity>());
tagEntityMap.put(EntityTags.COLLIDABLE, new LinkedList<Entity>());
tagEntityMap.put(EntityTags.SPRINTABLE, new LinkedList<Entity>());
tagEntityMap.put(EntityTags.MOVEABLE, new LinkedList<Entity>());
tagEntityMap.put(EntityTags.ATTACKER, new LinkedList<Entity>());
tagEntityMap.put(EntityTags.TARGETABLE, new LinkedList<Entity>());
tagEntityMap.put(EntityTags.LIFE_STATE, new LinkedList<Entity>());
tagEntityMap.put(EntityTags.CREATURE, new LinkedList<Entity>());
tagEntityMap.put(EntityTags.UI, new LinkedList<Entity>());
tagEntityMap.put(EntityTags.DRAWABLE, new LinkedList<Entity>());
tagEntityMap.put(EntityTags.LIGHT, new LinkedList<Entity>());
tagEntityMap.put(EntityTags.ITEM, new LinkedList<Entity>());
tagEntityMap.put(EntityTags.GRAVITY, new LinkedList<Entity>());
tagEntityMap.put(EntityTags.PARTICLE, new LinkedList<Entity>());
tagEntityMap.put(EntityTags.BONE_ATTACHED, new HashSet<Entity>());
tagEntityMap.put(EntityTags.COLLIDABLE, new HashSet<Entity>());
tagEntityMap.put(EntityTags.SPRINTABLE, new HashSet<Entity>());
tagEntityMap.put(EntityTags.MOVEABLE, new HashSet<Entity>());
tagEntityMap.put(EntityTags.ATTACKER, new HashSet<Entity>());
tagEntityMap.put(EntityTags.TARGETABLE, new HashSet<Entity>());
tagEntityMap.put(EntityTags.LIFE_STATE, new HashSet<Entity>());
tagEntityMap.put(EntityTags.CREATURE, new HashSet<Entity>());
tagEntityMap.put(EntityTags.UI, new HashSet<Entity>());
tagEntityMap.put(EntityTags.DRAWABLE, new HashSet<Entity>());
tagEntityMap.put(EntityTags.LIGHT, new HashSet<Entity>());
tagEntityMap.put(EntityTags.ITEM, new HashSet<Entity>());
tagEntityMap.put(EntityTags.GRAVITY, new HashSet<Entity>());
tagEntityMap.put(EntityTags.PARTICLE, new HashSet<Entity>());
}
/**
* Registers an entity to the scene
* @param e The entity to register
*/
public void registerEntity(Entity e){
entityIdMap.put(e.getId(), e);
entityList.add(e);
@ -61,7 +65,7 @@ public class Scene {
if(tagEntityMap.containsKey(tag)){
tagEntityMap.get(tag).add(e);
} else {
List<Entity> newEntityList = new LinkedList<Entity>();
Set<Entity> newEntityList = new HashSet<Entity>();
newEntityList.add(e);
tagEntityMap.put(tag,newEntityList);
}
@ -72,7 +76,7 @@ public class Scene {
* @param tag The tag
* @return A list of all entities with the tag, or null if no entities have been added to the tag yet
*/
public List<Entity> getEntitiesWithTag(String tag){
public Set<Entity> getEntitiesWithTag(String tag){
return tagEntityMap.get(tag);
}
@ -93,8 +97,14 @@ public class Scene {
for(String key : tagEntityMap.keySet()){
tagEntityMap.get(key).remove(e);
}
entityIdMap.remove(e.getId());
entityList.remove(e);
}
/**
* Recursively deregisters an entity and all entities attached via AttachUtils
* @param target The top level entity to deregister
*/
public void recursiveDeregister(Entity target){
if(AttachUtils.hasChildren(target)){
List<Entity> childrenList = AttachUtils.getChildrenList(target);
@ -105,123 +115,27 @@ public class Scene {
deregisterEntity(target);
}
public void recursiveHide(Entity target){
if(AttachUtils.hasChildren(target)){
List<Entity> childrenList = AttachUtils.getChildrenList(target);
for(Entity currentChild : childrenList){
recursiveHide(currentChild);
}
}
target.putData(EntityDataStrings.DATA_STRING_DRAW, false);
}
public void recursiveShow(Entity target){
if(AttachUtils.hasChildren(target)){
List<Entity> childrenList = AttachUtils.getChildrenList(target);
for(Entity currentChild : childrenList){
recursiveShow(currentChild);
}
}
target.putData(EntityDataStrings.DATA_STRING_DRAW, true);
}
// public void overrideEntityId(Entity e, int id){
// LoggerInterface.loggerGameLogic.DEBUG("Overriding entity ID " + e.getId() + " => " + id);
// if(entityIdMap.containsKey(e.getId())){
// entityIdMap.remove(e.getId());
// }
// e.setId(id);
// entityIdMap.put(e.getId(), e);
// }
/**
* Registers a server provided ID as a mapping to a given ID on the client
* @param clientId The client's generated ID
* @param serverId The server's provided ID
* Gets an entity via its ID
* @param id The id to search for
* @return The entity with that ID
*/
public void mapIdToId(int clientId, int serverId){
LoggerInterface.loggerEngine.DEBUG("MapID: " + clientId + " <===> " + serverId);
clientToServerIdMap.put(clientId, serverId);
serverToClientIdMap.put(serverId, clientId);
}
/**
* Resolves a client ID to the equivalent ID on the server
* @param clientId The id provided by the client
* @return The equivalent id on the server
*/
public int mapClientToServerId(int clientId){
return clientToServerIdMap.get(clientId);
}
/**
* Translates the id provided by the server into the equivalent id on the client
* @param serverId The id provided by the server
* @return The equivalent id on the client
*/
public int mapServerToClientId(int serverId){
return serverToClientIdMap.get(serverId);
}
public Entity getEntityFromId(int id){
return (Entity)entityIdMap.get(id);
}
/**
* [CLIENT ONLY] Gets the entity provided a server-provided id
* @param id The server-provided ID
* @return The entity in question
* Registers a behavior tree to simulate each scene simulation frame
* @param tree The behavior tree to register
*/
public Entity getEntityFromServerId(int id){
if(Globals.RUN_SERVER){
return (Entity)entityIdMap.get(id);
} else {
return (Entity)entityIdMap.get(mapServerToClientId(id));
}
}
public void clearOutOfBoundsEntities(){
if(Globals.commonWorldData != null && Globals.playerEntity != null && Globals.clientPlayerData != null){
Vector3d playerCharacterPos = EntityUtils.getPosition(Globals.playerEntity);
int playerCharacterWorldX = Globals.commonWorldData.convertRealToWorld(playerCharacterPos.x);
int playerCharacterWorldY = Globals.commonWorldData.convertRealToWorld(playerCharacterPos.z);
if(playerCharacterWorldX != Globals.clientPlayerData.getWorldPositionX() || playerCharacterWorldY != Globals.clientPlayerData.getWorldPositionY()){
for(Entity entity : entityList){
if(entity.containsKey(EntityDataStrings.TERRAIN_IS_TERRAIN) || entity.containsKey(EntityDataStrings.ATTACH_PARENT) || entity.containsKey(EntityDataStrings.COLLISION_ENTITY_PARENT)){
} else {
Vector3d position = EntityUtils.getPosition(entity);
//common world data is initialized with the collision data
//if this is null then the engine hasn't fully started up yet
if(position != null){
int worldX = Globals.commonWorldData.convertRealToWorld(position.x);
int worldY = Globals.commonWorldData.convertRealToWorld(position.z);
if(!Globals.drawCellManager.coordsInPhysicsSpace(worldX, worldY)){
//if we're running the server we need to just hide the entity
//otherwise delete it
if(Globals.RUN_SERVER && Globals.RUN_CLIENT){
recursiveHide(entity);
} else {
recursiveDeregister(entity);
}
} else {
//if the entity is within range, we're running server,
//and it's not set to visible, make it visible
if(Globals.RUN_SERVER && Globals.RUN_CLIENT){
recursiveShow(entity);
}
}
}
}
}
}
}
}
public void registerBehaviorTree(BehaviorTree tree){
behaviorTreeList.add(tree);
}
/**
* Deregisters a behavior tree from the scene
* @param tree The behavior tree to deregister
*/
public void deregisterBehaviorTree(BehaviorTree tree){
behaviorTreeList.remove(tree);
}

View File

@ -0,0 +1,72 @@
package electrosphere.entity;
import org.joml.Vector3d;
import electrosphere.engine.Globals;
import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.ServerDataCell;
import electrosphere.server.datacell.utils.DataCellSearchUtils;
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
/**
* Entity utilities specifically for the server side
*/
public class ServerEntityUtils {
/**
* Called when the creature is first spawned to serialize to all people in its initial chunk
* @param entity
* @param position
*/
public static void initiallyPositionEntity(Realm realm, Entity entity, Vector3d position){
Globals.realmManager.mapEntityToRealm(entity, realm);
//get current server data cell
ServerDataCell cell = realm.getDataCellManager().getDataCellAtPoint(position);
if(cell != null){
//initialize server datacell tracking of this entity
realm.initializeServerSideEntity(entity, cell);
} else {
//if it doesn't already exist, try creating it and if successfull move creature
cell = realm.getDataCellManager().tryCreateCellAtPoint(position);
//initialize server datacell tracking of this entity
realm.initializeServerSideEntity(entity, cell);
}
//reposition entity
CollisionObjUtils.positionCharacter(entity, position);
}
/**
* Called to reposition the creature
* @param entity
* @param position
*/
public static void repositionEntity(Entity entity, Vector3d position){
Realm realm = Globals.realmManager.getEntityRealm(entity);
//if server, get current server data cell
if(Globals.RUN_SERVER){
ServerDataCell oldDataCell = realm.getDataCellManager().getDataCellAtPoint(EntityUtils.getPosition(entity));
ServerDataCell newDataCell = realm.getDataCellManager().getDataCellAtPoint(position);
if(newDataCell != null){
ServerDataCell.moveEntityFromCellToCell(entity, oldDataCell, newDataCell);
ServerBehaviorTreeUtils.updateCell(entity, oldDataCell);
} else {
//if it doesn't already exist, try creating it and if successfull move creature
newDataCell = realm.getDataCellManager().tryCreateCellAtPoint(EntityUtils.getPosition(entity));
if(newDataCell != null){
ServerDataCell.moveEntityFromCellToCell(entity, oldDataCell, newDataCell);
ServerBehaviorTreeUtils.updateCell(entity, oldDataCell);
}
}
// //if the server is also a client, update the drawcell manager to know to pull new chunks
// if(Globals.RUN_CLIENT){
// Globals.drawCellManager.invalidateAllCells();
// Globals.drawCellManager.setCellX(Globals.clientPlayerData.getWorldPos().x);
// Globals.drawCellManager.setCellY(Globals.clientPlayerData.getWorldPos().z);
// }
}
//reposition entity
CollisionObjUtils.positionCharacter(entity, Globals.spawnPoint);
}
}

View File

@ -1,12 +0,0 @@
package electrosphere.entity;
import java.util.LinkedList;
import java.util.List;
public class ServerSceneManager {
List<Scene> scenes = new LinkedList<Scene>();
}

View File

@ -1,11 +1,14 @@
package electrosphere.entity.scene;
import org.joml.Vector3d;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.entity.types.object.ObjectUtils;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.ServerDataCell;
import electrosphere.util.FileUtils;
@ -19,7 +22,8 @@ public class SceneLoader {
* @param path The path in the assets directory to a scene file
*/
public ServerDataCell serverInstantiateSceneFile(String path){
ServerDataCell rVal = Globals.dataCellManager.createNewCell();
Realm realm = Globals.realmManager.createRealm();
ServerDataCell rVal = realm.createNewCell();
SceneFile file = FileUtils.loadObjectFromAssetPath(path, SceneFile.class);
//spawn initial entities
for(EntityDescriptor descriptor : file.getEntities()){
@ -27,21 +31,22 @@ public class SceneLoader {
switch(descriptor.getType()){
case EntityDescriptor.TYPE_CREATURE: {
Entity newEntity = CreatureUtils.spawnBasicCreature(descriptor.subtype, null);
EntityUtils.getPosition(newEntity).set(descriptor.posX,descriptor.posY,descriptor.posZ);
Vector3d position = new Vector3d(descriptor.posX,descriptor.posY,descriptor.posZ);
Entity newEntity = CreatureUtils.serverSpawnBasicCreature(realm, position, descriptor.subtype, null);
EntityUtils.getRotation(newEntity).set((float)descriptor.rotX, (float)descriptor.rotY, (float)descriptor.rotZ, (float)descriptor.rotW);
rVal.initializeEntityForNewPlayers(newEntity, rVal);
} break;
case EntityDescriptor.TYPE_ITEM: {
Entity newEntity = ItemUtils.spawnBasicItem(descriptor.subtype);
EntityUtils.getPosition(newEntity).set(descriptor.posX,descriptor.posY,descriptor.posZ);
Vector3d position = new Vector3d(descriptor.posX,descriptor.posY,descriptor.posZ);
Entity newEntity = ItemUtils.serverSpawnBasicItem(realm, position, descriptor.subtype);
EntityUtils.getRotation(newEntity).set((float)descriptor.rotX, (float)descriptor.rotY, (float)descriptor.rotZ, (float)descriptor.rotW);
rVal.initializeEntityForNewPlayers(newEntity, rVal);
} break;
case EntityDescriptor.TYPE_OBJECT: {
Entity newEntity = ObjectUtils.spawnBasicObject(descriptor.subtype);
Vector3d position = new Vector3d(descriptor.posX,descriptor.posY,descriptor.posZ);
Entity newEntity = ObjectUtils.serverSpawnBasicObject(realm, position, descriptor.subtype);
EntityUtils.getPosition(newEntity).set(descriptor.posX,descriptor.posY,descriptor.posZ);
EntityUtils.getRotation(newEntity).set((float)descriptor.rotX, (float)descriptor.rotY, (float)descriptor.rotZ, (float)descriptor.rotW);
rVal.initializeEntityForNewPlayers(newEntity, rVal);

View File

@ -61,7 +61,7 @@ public class ParticleTree implements BehaviorTree {
if(hasLife){
lifeCurrent--;
if(lifeCurrent <= 0){
Globals.entityManager.deregisterEntity(parent);
EntityUtils.cleanUpEntity(parent);
}
}
}

View File

@ -5,6 +5,7 @@ import electrosphere.engine.Main;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.ServerEntityUtils;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.collidable.Impulse;
import electrosphere.entity.state.equip.EquipState;
@ -22,6 +23,9 @@ import electrosphere.game.data.creature.type.equip.EquipPoint;
import electrosphere.net.parser.net.message.EntityMessage;
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.concurrent.CopyOnWriteArrayList;
@ -117,8 +121,8 @@ public class AttackTree implements BehaviorTree {
//intuit can hold from presence of windup anim
currentMoveCanHold = currentMove.getHoldAnimationName() != null;
//stop movement tree
if(parent.containsKey(EntityDataStrings.DATA_STRING_MOVEMENT_BT)){
BehaviorTree movementTree = CreatureUtils.getEntityMovementTree(parent);
if(parent.containsKey(EntityDataStrings.CLIENT_MOVEMENT_BT)){
BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(parent);
if(movementTree instanceof GroundMovementTree){
((GroundMovementTree)movementTree).interrupt();
}
@ -233,8 +237,8 @@ public class AttackTree implements BehaviorTree {
//state machine
switch(state){
case WINDUP:
if(parent.containsKey(EntityDataStrings.ROTATOR_TREE)){
RotatorTree.getRotatorTree(parent).setActive(true);
if(parent.containsKey(EntityDataStrings.CLIENT_ROTATOR_TREE)){
RotatorTree.getClientRotatorTree(parent).setActive(true);
}
if(entityActor != null){
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationName)){
@ -249,25 +253,10 @@ public class AttackTree implements BehaviorTree {
state = AttackTreeState.ATTACK;
}
}
if(Globals.RUN_SERVER){
Globals.server.broadcastMessage(
EntityMessage.constructattackUpdateMessage(
parent.getId(),
System.currentTimeMillis(),
(float)position.x,
(float)position.y,
(float)position.z,
movementVector.x,
movementVector.y,
movementVector.z,
velocity,
0
)
);
} else if(Globals.RUN_CLIENT && parent.getId() == Globals.clientCharacterID){
if(parent.getId() == Globals.clientCharacterID){
Globals.clientConnection.queueOutgoingMessage(
EntityMessage.constructattackUpdateMessage(
Globals.entityManager.mapClientToServerId(parent.getId()),
Globals.clientSceneWrapper.mapClientToServerId(parent.getId()),
System.currentTimeMillis(),
(float)position.x,
(float)position.y,
@ -291,37 +280,6 @@ public class AttackTree implements BehaviorTree {
if(!stillHold){
state = AttackTreeState.ATTACK;
}
// if(Globals.RUN_SERVER){
// Globals.server.broadcastMessage(
// EntityMessage.constructattackUpdateMessage(
// parent.getId(),
// System.currentTimeMillis(),
// (float)position.x,
// (float)position.y,
// (float)position.z,
// movementVector.x,
// movementVector.y,
// movementVector.z,
// velocity,
// 0
// )
// );
// } else if(Globals.RUN_CLIENT && parent.getId() == Globals.clientCharacterID){
// Globals.clientConnection.queueOutgoingMessage(
// EntityMessage.constructattackUpdateMessage(
// parent.getId(),
// System.currentTimeMillis(),
// (float)position.x,
// (float)position.y,
// (float)position.z,
// movementVector.x,
// movementVector.y,
// movementVector.z,
// velocity,
// 0
// )
// );
// }
break;
case ATTACK:
if(parent.containsKey(EntityDataStrings.ATTACH_CHILDREN_LIST)){
@ -365,31 +323,16 @@ public class AttackTree implements BehaviorTree {
// EntityUtils.getRotation(currentEntity).rotationTo(new Vector3f(0,0,1), new Vector3f((float)facingAngle.x,(float)facingAngle.y,(float)facingAngle.z)).mul(parentActor.getBoneRotation(targetBone)).normalize();
}
Vector3f initialVector = new Vector3f((float)movementVector.x,(float)movementVector.y,(float)movementVector.z).normalize();
ProjectileUtils.spawnBasicProjectile(projectileToFire, spawnPosition, arrowRotation, 750, initialVector, 0.03f);
ProjectileUtils.clientSpawnBasicProjectile(projectileToFire, spawnPosition, arrowRotation, 750, initialVector, 0.03f);
projectileToFire = null;
}
if(frameCurrent > currentMove.getWindupFrames() + currentMove.getAttackFrames()){
state = AttackTreeState.COOLDOWN;
}
if(Globals.RUN_SERVER){
Globals.server.broadcastMessage(
EntityMessage.constructattackUpdateMessage(
parent.getId(),
System.currentTimeMillis(),
(float)position.x,
(float)position.y,
(float)position.z,
movementVector.x,
movementVector.y,
movementVector.z,
velocity,
1
)
);
} else if(Globals.RUN_CLIENT && parent.getId() == Globals.clientCharacterID){
if(parent.getId() == Globals.clientCharacterID){
Globals.clientConnection.queueOutgoingMessage(
EntityMessage.constructattackUpdateMessage(
Globals.entityManager.mapClientToServerId(parent.getId()),
Globals.clientSceneWrapper.mapClientToServerId(parent.getId()),
System.currentTimeMillis(),
(float)position.x,
(float)position.y,
@ -418,29 +361,14 @@ public class AttackTree implements BehaviorTree {
if(frameCurrent > currentMove.getWindupFrames() + currentMove.getAttackFrames() + currentMove.getCooldownFrames()){
state = AttackTreeState.IDLE;
frameCurrent = 0;
if(parent.containsKey(EntityDataStrings.ROTATOR_TREE)){
RotatorTree.getRotatorTree(parent).setActive(false);
if(parent.containsKey(EntityDataStrings.CLIENT_ROTATOR_TREE)){
RotatorTree.getClientRotatorTree(parent).setActive(false);
}
}
if(Globals.RUN_SERVER){
Globals.server.broadcastMessage(
EntityMessage.constructattackUpdateMessage(
parent.getId(),
System.currentTimeMillis(),
(float)position.x,
(float)position.y,
(float)position.z,
movementVector.x,
movementVector.y,
movementVector.z,
velocity,
2
)
);
} else if(Globals.RUN_CLIENT && parent.getId() == Globals.clientCharacterID){
if(parent.getId() == Globals.clientCharacterID){
Globals.clientConnection.queueOutgoingMessage(
EntityMessage.constructattackUpdateMessage(
Globals.entityManager.mapClientToServerId(parent.getId()),
Globals.clientSceneWrapper.mapClientToServerId(parent.getId()),
System.currentTimeMillis(),
(float)position.x,
(float)position.y,

View File

@ -0,0 +1,467 @@
package electrosphere.entity.state.attack;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.ServerEntityUtils;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.collidable.Impulse;
import electrosphere.entity.state.equip.EquipState;
import electrosphere.entity.state.movement.GroundMovementTree;
import electrosphere.entity.state.movement.ServerGroundMovementTree;
import electrosphere.entity.state.rotator.RotatorTree;
import electrosphere.entity.state.rotator.ServerRotatorTree;
import electrosphere.entity.types.attach.AttachUtils;
import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.hitbox.HitboxUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.entity.types.projectile.ProjectileUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.data.creature.type.attack.AttackMove;
import electrosphere.game.data.creature.type.equip.EquipPoint;
import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.anim.Animation;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.utils.EntityLookupUtils;
import electrosphere.server.poseactor.PoseActor;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Quaternionfc;
import org.joml.Vector3d;
import org.joml.Vector3f;
public class ServerAttackTree implements BehaviorTree {
public static enum AttackTreeState {
WINDUP,
HOLD,
ATTACK,
COOLDOWN,
IDLE,
}
//the state of drifting forward during the attack
public static enum AttackTreeDriftState {
DRIFT,
NO_DRIFT,
}
AttackTreeState state;
AttackTreeDriftState driftState;
Entity parent;
CopyOnWriteArrayList<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList<EntityMessage>();
long lastUpdateTime = 0;
float frameCurrent;
String animationName = "SwingWeapon";
int maxFrame = 60;
List<AttackMove> currentMoveset = null;
AttackMove currentMove = null;
Entity currentWeapon = null;
boolean currentMoveHasWindup;
boolean currentMoveCanHold;
boolean stillHold = true;
boolean firesProjectile = false;
String projectileToFire = null;
String attackingPoint = null;
public ServerAttackTree(Entity e){
state = AttackTreeState.IDLE;
driftState = AttackTreeDriftState.NO_DRIFT;
parent = e;
}
public AttackTreeState getState(){
return state;
}
public void start(){
currentMoveCanHold = false;
currentMoveHasWindup = false;
stillHold = true;
firesProjectile = false;
projectileToFire = null;
currentWeapon = null;
attackingPoint = null;
//figure out attack type we should be doing
String attackType = getAttackType();
//if we can attack, setup doing so
if(canAttack(attackType)){
parent.putData(EntityDataStrings.ATTACK_MOVE_TYPE_ACTIVE, attackType);
currentMoveset = (List<AttackMove>)parent.getData(attackType);
if(currentMoveset != null){
if(currentMove == null){
currentMove = currentMoveset.get(0);
} else {
currentMove = getNextMove(currentMoveset,currentMove.getNextMoveId());
}
if(currentMove != null){
firesProjectile = currentMove.getFiresProjectile();
if(firesProjectile){
projectileToFire = ItemUtils.getWeaponDataRaw(currentWeapon).getProjectileModel();
}
animationName = currentMove.getAttackAnimationName();
//intuit windup from presence of windup anim
currentMoveHasWindup = currentMove.getWindupAnimationName() != null;
if(currentMoveHasWindup){
animationName = currentMove.getWindupAnimationName();
}
//intuit can hold from presence of windup anim
currentMoveCanHold = currentMove.getHoldAnimationName() != null;
//stop movement tree
if(parent.containsKey(EntityDataStrings.SERVER_MOVEMENT_BT)){
BehaviorTree movementTree = CreatureUtils.serverGetEntityMovementTree(parent);
if(movementTree instanceof ServerGroundMovementTree){
((ServerGroundMovementTree)movementTree).interrupt();
}
}
Vector3d movementVector = CreatureUtils.getFacingVector(parent);
EntityUtils.getRotation(parent).rotationTo(new Vector3f(0,0,1), new Vector3f((float)movementVector.x,(float)movementVector.y,(float)movementVector.z));
//set initial stuff
state = AttackTreeState.WINDUP;
frameCurrent = 0;
} else {
state = AttackTreeState.IDLE;
}
}
}
}
public void release(){
stillHold = false;
}
public void interrupt(){
state = AttackTreeState.IDLE;
}
public void slowdown(){
state = AttackTreeState.COOLDOWN;
}
@Override
public void simulate(float deltaTime){
frameCurrent = frameCurrent + Main.deltaFrames;
float velocity = CreatureUtils.getVelocity(parent);
PoseActor entityPoseActor = EntityUtils.getPoseActor(parent);
Vector3d position = EntityUtils.getPosition(parent);
Vector3d movementVector = CreatureUtils.getFacingVector(parent);
//parse attached network messages
for(EntityMessage message : networkMessageQueue){
networkMessageQueue.remove(message);
// System.out.println("MOVE to " + message.getX() + " " + message.getY() + " " + message.getZ());
long updateTime = message.gettime();
switch(message.getMessageSubtype()){
case ATTACKUPDATE:
if(updateTime > lastUpdateTime){
lastUpdateTime = updateTime;
switch(message.gettreeState()){
case 0:
state = AttackTreeState.WINDUP;
frameCurrent = 0;
// System.out.println("Set state STARTUP");
break;
case 1:
frameCurrent = currentMove.getWindupFrames()+1;
state = AttackTreeState.ATTACK;
// System.out.println("Set state MOVE");
break;
case 2:
frameCurrent = currentMove.getWindupFrames()+currentMove.getAttackFrames()+1;
state = AttackTreeState.COOLDOWN;
// System.out.println("Set state SLOWDOWN");
break;
case 3:
frameCurrent = 60;
state = AttackTreeState.IDLE;
// System.out.println("Set state IDLE");
break;
}
}
EntityUtils.getPosition(parent).set(message.getpositionX(),message.getpositionY(),message.getpositionZ());
CreatureUtils.setFacingVector(parent, new Vector3d(message.getrotationX(),message.getrotationY(),message.getrotationZ()));
break;
case ATTACHENTITYTOENTITY:
case CREATE:
case DESTROY:
case MOVE:
case MOVEUPDATE:
case SETBEHAVIORTREE:
case SETFACING:
case SETPOSITION:
case SETPROPERTY:
case KILL:
case SPAWNCREATURE:
//silently ignore
break;
}
}
//handle the drifting if we're supposed to currently
switch(driftState){
case DRIFT:
if(currentMove != null){
//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() * Main.deltaFrames, "movement"));
if(frameCurrent > currentMove.getDriftFrameEnd()){
driftState = AttackTreeDriftState.NO_DRIFT;
}
}
break;
case NO_DRIFT:
if(currentMove != null){
if(frameCurrent > currentMove.getDriftFrameStart() && frameCurrent < currentMove.getDriftFrameEnd()){
driftState = AttackTreeDriftState.DRIFT;
}
}
break;
}
// if(state != AttackTreeState.IDLE){
// System.out.println(frameCurrent);
// }
//state machine
switch(state){
case WINDUP:
if(parent.containsKey(EntityDataStrings.SERVER_ROTATOR_TREE)){
ServerRotatorTree.getServerRotatorTree(parent).setActive(true);
}
if(entityPoseActor != null){
if(!entityPoseActor.isPlayingAnimation() || !entityPoseActor.isPlayingAnimation(animationName)){
entityPoseActor.playAnimation(animationName,1);
entityPoseActor.incrementAnimationTime(0.0001);
}
}
if(frameCurrent > currentMove.getWindupFrames()){
if(currentMoveCanHold && stillHold){
state = AttackTreeState.HOLD;
} else {
state = AttackTreeState.ATTACK;
}
}
Globals.server.broadcastMessage(
EntityMessage.constructattackUpdateMessage(
parent.getId(),
System.currentTimeMillis(),
(float)position.x,
(float)position.y,
(float)position.z,
movementVector.x,
movementVector.y,
movementVector.z,
velocity,
0
)
);
break;
case HOLD:
if(entityPoseActor != null){
if(!entityPoseActor.isPlayingAnimation() || !entityPoseActor.isPlayingAnimation(animationName)){
entityPoseActor.playAnimation(animationName,1);
entityPoseActor.incrementAnimationTime(0.0001);
}
}
if(!stillHold){
state = AttackTreeState.ATTACK;
}
break;
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){
//spawn projectile
//TODO: solve spawnPosition, initialVector
Vector3d spawnPosition = new Vector3d(0,0,0);
Quaternionf arrowRotation = new Quaternionf();
String targetBone = null;
EquipState equipState = EquipState.getEquipState(parent);
EquipPoint weaponPoint = null;
if((weaponPoint = equipState.getEquipPoint(attackingPoint)) != null){
targetBone = weaponPoint.getBone();
}
if(targetBone != null){
Actor parentActor = EntityUtils.getActor(parent);
//transform bone space
spawnPosition = new Vector3d(parentActor.getBonePosition(targetBone));
spawnPosition = spawnPosition.mul(((Vector3f)EntityUtils.getScale(parent)));
Quaternionf rotation = EntityUtils.getRotation(parent);
spawnPosition = spawnPosition.rotate(new Quaterniond(rotation.x,rotation.y,rotation.z,rotation.w));
//transform worldspace
spawnPosition.add(new Vector3d(EntityUtils.getPosition(parent)));
//set
// EntityUtils.getPosition(currentEntity).set(position);
//set rotation
// Quaternionf rotation = parentActor.getBoneRotation(targetBone);
// EntityUtils.getRotation(currentEntity).set(rotation).normalize();
// Vector3d facingAngle = CreatureUtils.getFacingVector(parent);
arrowRotation = parentActor.getBoneRotation(targetBone);
// EntityUtils.getRotation(currentEntity).rotationTo(new Vector3f(0,0,1), new Vector3f((float)facingAngle.x,(float)facingAngle.y,(float)facingAngle.z)).mul(parentActor.getBoneRotation(targetBone)).normalize();
}
Vector3f initialVector = new Vector3f((float)movementVector.x,(float)movementVector.y,(float)movementVector.z).normalize();
Realm parentRealm = Globals.realmManager.getEntityRealm(parent);
ProjectileUtils.serverSpawnBasicProjectile(parentRealm, projectileToFire, spawnPosition, arrowRotation, 750, initialVector, 0.03f);
projectileToFire = null;
}
if(frameCurrent > currentMove.getWindupFrames() + currentMove.getAttackFrames()){
state = AttackTreeState.COOLDOWN;
}
Globals.server.broadcastMessage(
EntityMessage.constructattackUpdateMessage(
parent.getId(),
System.currentTimeMillis(),
(float)position.x,
(float)position.y,
(float)position.z,
movementVector.x,
movementVector.y,
movementVector.z,
velocity,
1
)
);
break;
case COOLDOWN:
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(false);
}
}
}
}
if(frameCurrent > currentMove.getWindupFrames() + currentMove.getAttackFrames() + currentMove.getCooldownFrames()){
state = AttackTreeState.IDLE;
frameCurrent = 0;
if(parent.containsKey(EntityDataStrings.SERVER_ROTATOR_TREE)){
ServerRotatorTree.getServerRotatorTree(parent).setActive(false);
}
}
Globals.server.broadcastMessage(
EntityMessage.constructattackUpdateMessage(
parent.getId(),
System.currentTimeMillis(),
(float)position.x,
(float)position.y,
(float)position.z,
movementVector.x,
movementVector.y,
movementVector.z,
velocity,
2
)
);
break;
case IDLE:
currentMove = null;
currentMoveset = null;
break;
}
}
public void addNetworkMessage(EntityMessage networkMessage) {
networkMessageQueue.add(networkMessage);
}
String getAttackType(){
String rVal = null;
if(EquipState.hasEquipState(parent)){
EquipState equipState = EquipState.getEquipState(parent);
for(String point : equipState.equippedPoints()){
Entity item = equipState.getEquippedItemAtPoint(point);
if(ItemUtils.isWeapon(item)){
attackingPoint = point;
currentWeapon = item;
switch(ItemUtils.getWeaponClass(item)){
case "sword1h":
rVal = EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND;
break;
case "bow2h":
rVal = EntityDataStrings.ATTACK_MOVE_TYPE_BOW_TWO_HAND;
break;
}
}
}
}
return rVal;
}
boolean canAttack(String attackType){
boolean rVal = true;
if(attackType == null){
return false;
} else if(state != AttackTreeState.IDLE){
//checks if we have a next move and if we're in the specified range of frames when we're allowed to chain into it
if(
currentMove.getNextMoveId() != null &&
!currentMove.getNextMoveId().equals("") &&
frameCurrent >= currentMove.getMoveChainWindowStart() && frameCurrent <= currentMove.getMoveChainWindowEnd()
){
rVal = true;
}
} else {
if(EquipState.hasEquipState(parent)){
EquipState equipState = EquipState.getEquipState(parent);
// if(equipState.hasEquipPrimary()){
// switch(attackType){
// case EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND:
// break;
// default:
// rVal = false;
// break;
// }
// } else {
// switch(attackType){
// case EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND:
// rVal = false;
// break;
// default:
// rVal = false;
// break;
// }
// }
}
}
return rVal;
}
AttackMove getNextMove(List<AttackMove> moveset, String nextMoveId){
AttackMove rVal = null;
for(AttackMove move : moveset){
if(move.getAttackMoveId().equals(nextMoveId)){
rVal = move;
break;
}
}
return rVal;
}
}

View File

@ -2,12 +2,15 @@ package electrosphere.entity.state.attack;
import org.joml.Vector3d;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.projectile.ProjectileUtils;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.utils.EntityLookupUtils;
public class ShooterTree implements BehaviorTree {
@ -40,7 +43,12 @@ public class ShooterTree implements BehaviorTree {
//
Vector3d parentPosition = EntityUtils.getPosition(parent);
Vector3d movementDir = CreatureUtils.getFacingVector(parent);
ProjectileUtils.spawnProjectile("missile1", parentPosition, new Vector3d(movementDir),parent);
if(EntityLookupUtils.isServerEntity(parent)){
Realm parentRealm = Globals.realmManager.getEntityRealm(parent);
ProjectileUtils.serverSpawnProjectile(parentRealm, "missile1", parentPosition, new Vector3d(movementDir),parent);
} else {
ProjectileUtils.clientSpawnProjectile("missile1", parentPosition, new Vector3d(movementDir),parent);
}
this.state = ShooterTreeState.COOLDOWN;
cooldownCurrent = cooldownMax;
} break;

View File

@ -27,7 +27,7 @@ import org.joml.Vector4f;
*
* @author amaterasu
*/
public class CollidableTree implements BehaviorTree {
public class ClientCollidableTree implements BehaviorTree {
Entity parent;
CollisionObject body;
@ -39,13 +39,13 @@ public class CollidableTree implements BehaviorTree {
static final float DELTA_T = 0.01f;
public CollidableTree(Entity e, Collidable collidable, CollisionObject body){
public ClientCollidableTree(Entity e, Collidable collidable, CollisionObject body){
parent = e;
this.collidable = collidable;
this.body = body;
}
public CollidableTree(Entity e, Collidable collidable, CollisionObject body, boolean applyImpulses){
public ClientCollidableTree(Entity e, Collidable collidable, CollisionObject body, boolean applyImpulses){
parent = e;
this.collidable = collidable;
this.body = body;
@ -73,14 +73,14 @@ public class CollidableTree implements BehaviorTree {
// System.out.println("Position: " + position);
}
if(impulse.type.matches(Collidable.TYPE_ITEM)){
if(parent.containsKey(EntityDataStrings.GRAVITY_TREE)){
((GravityTree)parent.getData(EntityDataStrings.GRAVITY_TREE)).start();
if(parent.containsKey(EntityDataStrings.CLIENT_GRAVITY_TREE)){
((GravityTree)parent.getData(EntityDataStrings.CLIENT_GRAVITY_TREE)).start();
}
}
if(impulse.type.matches(Collidable.TYPE_CREATURE)){
// System.out.println(System.currentTimeMillis() + " creature hit!");
if(parent.containsKey(EntityDataStrings.GRAVITY_TREE)){
((GravityTree)parent.getData(EntityDataStrings.GRAVITY_TREE)).start();
if(parent.containsKey(EntityDataStrings.CLIENT_GRAVITY_TREE)){
((GravityTree)parent.getData(EntityDataStrings.CLIENT_GRAVITY_TREE)).start();
}
}
if(
@ -199,8 +199,8 @@ public class CollidableTree implements BehaviorTree {
if(applyImpulses){
newPosition.add(offsetVector);
}
if(!Globals.collisionEngine.checkCanOccupyPosition(Globals.commonWorldData, parent, newPosition)){
newPosition = Globals.collisionEngine.suggestMovementPosition(Globals.commonWorldData, parent, newPosition);
if(!Globals.clientSceneWrapper.getCollisionEngine().checkCanOccupyPosition(Globals.commonWorldData, parent, newPosition)){
newPosition = Globals.clientSceneWrapper.getCollisionEngine().suggestMovementPosition(Globals.commonWorldData, parent, newPosition);
}
position.set(newPosition);
@ -224,12 +224,12 @@ public class CollidableTree implements BehaviorTree {
return angularVelocity.lengthSquared();
}
public static boolean hasCollidableTree(Entity e){
return e.containsKey(EntityDataStrings.COLLIDABLE_TREE);
public static boolean hasClientCollidableTree(Entity e){
return e.containsKey(EntityDataStrings.CLIENT_COLLIDABLE_TREE);
}
public static CollidableTree getCollidableTree(Entity e){
return (CollidableTree)e.getData(EntityDataStrings.COLLIDABLE_TREE);
public static ClientCollidableTree getClientCollidableTree(Entity e){
return (ClientCollidableTree)e.getData(EntityDataStrings.CLIENT_COLLIDABLE_TREE);
}

View File

@ -0,0 +1,239 @@
package electrosphere.entity.state.collidable;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.gravity.GravityTree;
import electrosphere.entity.state.gravity.ServerGravityTree;
import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.debug.DebugVisualizerUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.game.collision.PhysicsUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.data.creature.type.CollidableTemplate;
import electrosphere.server.datacell.Realm;
import org.joml.Matrix4f;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.joml.Vector4d;
import org.joml.Vector4f;
/**
*
* @author amaterasu
*/
public class ServerCollidableTree implements BehaviorTree {
Entity parent;
CollisionObject body;
Collidable collidable;
Quaternionf angularVelocity = new Quaternionf(0,0,0,0);
Vector4d cumulativeTorque = new Vector4d(0,0,0,0);
boolean applyImpulses = true;
static final float DELTA_T = 0.01f;
public ServerCollidableTree(Entity e, Collidable collidable, CollisionObject body){
parent = e;
this.collidable = collidable;
this.body = body;
}
public ServerCollidableTree(Entity e, Collidable collidable, CollisionObject body, boolean applyImpulses){
parent = e;
this.collidable = collidable;
this.body = body;
this.applyImpulses = applyImpulses;
}
static int incrementer = 0;
public void simulate(float deltaTime){
Vector3d position = EntityUtils.getPosition(parent);
Quaternionf rotation = EntityUtils.getRotation(parent);
Matrix4f inverseInertiaTensor = CollisionObjUtils.getInverseInertiaTensor(parent);
Vector3d offsetVector = new Vector3d();
Vector3d newPosition = new Vector3d(position);
javax.vecmath.Matrix4f bodyTransformMatrix;
//have we hit a terrain impulse?
boolean hitTerrain = false;
//handle impulses
for(Impulse impulse : collidable.getImpulses()){
// collidable.getImpulses().remove(impulse);
Vector3d impulseForce = new Vector3d(impulse.getDirection()).mul(impulse.getForce());
if(impulse.type.matches(Collidable.TYPE_TERRAIN)){
hitTerrain = true;
// System.out.println("Impulse force: " + impulseForce);
// System.out.println("Position: " + position);
}
if(impulse.type.matches(Collidable.TYPE_ITEM)){
if(parent.containsKey(EntityDataStrings.SERVER_GRAVITY_TREE)){
((ServerGravityTree)parent.getData(EntityDataStrings.SERVER_GRAVITY_TREE)).start();
}
}
if(impulse.type.matches(Collidable.TYPE_CREATURE)){
// System.out.println(System.currentTimeMillis() + " creature hit!");
if(parent.containsKey(EntityDataStrings.SERVER_GRAVITY_TREE)){
((ServerGravityTree)parent.getData(EntityDataStrings.SERVER_GRAVITY_TREE)).start();
}
}
if(
impulse.getCollisionPoint().length() > 0 &&
!Double.isNaN(impulse.getCollisionPoint().x) &&
!Double.isNaN(impulse.getCollisionPoint().y) &&
!Double.isNaN(impulse.getCollisionPoint().z) &&
!Double.isNaN(impulse.getDirection().x) &&
!Double.isNaN(impulse.getDirection().y) &&
!Double.isNaN(impulse.getDirection().z) &&
ItemUtils.isItem(parent)
){
// Vector3d collisionPoint = new Vector3d(impulse.getCollisionPoint()).normalize();
Vector3d collisionPoint = new Vector3d(impulse.getWorldPoint()).sub(position);
Vector3d forceDir = new Vector3d(impulse.getDirection()).normalize();
Vector3d torqueVec = new Vector3d(collisionPoint).cross(forceDir).normalize();
// double torqueMag = Math.abs(impulse.force);
double torqueMag = Math.sqrt(impulse.getCollisionPoint().length()) * impulse.getForce();
if(impulse.getType().equals(Collidable.TYPE_TERRAIN)){
torqueMag = torqueMag * 3;
}
torqueMag = torqueMag * 10;
// } else {
// torqueMag = 0;
// }
// if(impulse.type.matches(Collidable.TYPE_ITEM) && ItemUtils.isItem(parent)){
// // System.out.println(rotation);
// if(impulse.collisionPoint.x < 0){
// // System.out.println("Impulse collision point: " + impulse.getCollisionPoint() + " direction: " + impulse.getDirection() + " => " + new Vector3d(impulse.getCollisionPoint()).cross(impulse.getDirection()));
// cumulativeTorque.add(new Vector3d(impulse.getCollisionPoint()).cross(impulse.getDirection()));
// }
// } else {
// // angularVelocity.add(new Vector3d(impulse.getCollisionPoint()).cross(impulse.getDirection()),1.0);
// cumulativeTorque.add(new Vector3d(impulse.getCollisionPoint()).cross(impulse.getDirection()));
// }
if(impulse.type.matches(Collidable.TYPE_CREATURE)){
// System.out.println("Impulse: " + impulse.getCollisionPoint() + " x " + impulse.getDirection() + " ->f " + impulse.force);
// incrementer++;
// if(incrementer > 5){
// Globals.microSimulation.freeze();
// } else if(incrementer <= 5){
// // Globals.controlHandler.showMouse();
// Vector3d pos = impulse.getWorldPoint();
// // pos = new Vector3d(position).add(impulse.getCollisionPoint()).mul(1,0,1);
// DebugVisualizerUtils.spawnVectorVisualizer(impulse.getWorldPoint(), new Vector3d(torqueVec));
// }
// System.out.println("Impulse: " + torqueVec + " " + torqueMag);
}
// if(CreatureUtils.isCreature(parent) && forceDir.y < 0.5){
// System.out.println(collisionPoint + " x " + forceDir + " => " + torqueVec + " " + torqueMag);
// }
Quaternionf impulseRotation = new Quaternionf().rotationAxis((float)torqueMag * DELTA_T,new Vector3f((float)torqueVec.x,(float)torqueVec.y,(float)torqueVec.z));
if(angularVelocity.lengthSquared() > 0.001){
angularVelocity.mul(impulseRotation);
} else {
angularVelocity.set(impulseRotation);
}
// angularVelocity.add(new Vector4d((float)torqueVec.x,(float)torqueVec.y,(float)torqueVec.z,(float)torqueMag));
// cumulativeTorque.add(new Vector4d((float)torqueVec.x,(float)torqueVec.y,(float)torqueVec.z,(float)torqueMag));
}
offsetVector.add(impulseForce);
}
// if(ItemUtils.isItem(parent) && cumulativeTorque.w > 0.001){
// System.out.println(cumulativeTorque);
// }
//friction
if(angularVelocity.lengthSquared() > 0.001){
angularVelocity.slerp(new Quaternionf(0,0,0,1), 0.03f);
// angularVelocity.scale((float)(Math.sqrt(angularVelocity.lengthSquared()) * 0.9));
// System.out.println(angularVelocity);
}
// if(cumulativeTorque.w > 0.001){
// Vector4f holder = inverseInertiaTensor.transform(new Vector4f((float)cumulativeTorque.x,(float)cumulativeTorque.y,(float)cumulativeTorque.z,(float)cumulativeTorque.w));
// cumulativeTorque = new Vector4d(holder.x,holder.y,holder.z,holder.w);
// angularVelocity = angularVelocity.add(cumulativeTorque).normalize();
// cumulativeTorque.set(0,0,0,0);
// // Vector3d normalizedTorqueDir = new Vector3d(cumulativeTorque.x,cumulativeTorque.y,cumulativeTorque.z).normalize();
// // double newMag = cumulativeTorque.w * 0.9;
// // cumulativeTorque.set(normalizedTorqueDir.x,normalizedTorqueDir.y,normalizedTorqueDir.z,newMag);
// }
if(angularVelocity.lengthSquared() > 0.001){
// System.out.println("-" + rotation);
Quaternionf newRotation = new Quaternionf(rotation).mul(angularVelocity).normalize();
// if(new Quaternionf(newRotation).add(new Quaternionf(rotation).conjugate()).lengthSquared() > 0.2){
// newRotation.w = Math.copySign(newRotation.w, rotation.w);
// newRotation.x = Math.copySign(newRotation.x, rotation.x);
// newRotation.y = Math.copySign(newRotation.y, rotation.y);
// newRotation.z = Math.copySign(newRotation.z, rotation.z);
// }
rotation.set(newRotation);
// System.out.println("=" + rotation);
}
// if(inverseInertiaTensor != null && angularVelocity.w > 0.01){
// // Vector4f angularMomentum = inverseInertiaTensor.transform(new Vector4f((float)cumulativeTorque.x,(float)cumulativeTorque.x,(float)cumulativeTorque.x,(float)cumulativeTorque.w));
// // Quaternionf nextRotation = new Quaternionf(rotation).mul(new Quaternionf(angularMomentum.x,angularMomentum.y,angularMomentum.z,angularMomentum.w).scale(0.001f)).normalize();
// // rotation = nextRotation;
// // rotation.mul(new Quaternionf((float)angularMomentum.x,(float)angularMomentum.y,(float)angularMomentum.z,(float)angularMomentum.w / 0.01f));
// // if(ItemUtils.isItem(parent)){
// // System.out.println("cumulative quat: " + cumulativeTorque);
// // }
// rotation.x = rotation.x + rotation.x * (float)(angularVelocity.x * angularVelocity.w) * 0.01f;
// rotation.y = rotation.y + rotation.y * (float)(angularVelocity.y * angularVelocity.w) * 0.01f;
// rotation.z = rotation.z + rotation.z * (float)(angularVelocity.z * angularVelocity.w) * 0.01f;
// rotation.w = 1;
// // rotation.w = rotation.w + rotation.w * (float)cumulativeTorque.w * 0.001f;
// rotation.normalize();
// }
//the reasoning here is that if we have something above something else and it's pushing it into the terrain,
//we should instead just not push into terrain and push along terrain
if(hitTerrain && offsetVector.y < 0){
offsetVector.y = 0;
}
//make sure we're in a valid (World bounds) position
if(applyImpulses){
newPosition.add(offsetVector);
}
Realm parentRealm = Globals.realmManager.getEntityRealm(parent);
if(!parentRealm.getCollisionEngine().checkCanOccupyPosition(Globals.commonWorldData, parent, newPosition)){
newPosition = parentRealm.getCollisionEngine().suggestMovementPosition(Globals.commonWorldData, parent, newPosition);
}
position.set(newPosition);
//update collision engine of this thing's position
CollidableTemplate template = (CollidableTemplate)parent.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE);
bodyTransformMatrix = new javax.vecmath.Matrix4f(PhysicsUtils.jomlToVecmathQuaternionf(rotation),PhysicsUtils.jomlToVecmathVector3f(new Vector3f((float)position.x + template.getOffsetX(),(float)position.y + template.getOffsetY(),(float)position.z + template.getOffsetZ())),1.0f);
body.setWorldTransform(new electrosphere.linearmath.Transform(bodyTransformMatrix));
// bodyTransformMatrix = new javax.vecmath.Matrix4f(PhysicsUtils.jomlToVecmathQuaternionf(rotation),PhysicsUtils.jomlToVecmathVector3f(new Vector3f((float)newPosition.x,(float)newPosition.y,(float)newPosition.z)),1.0f);
// body.setWorldTransform(new electrosphere.linearmath.Transform(bodyTransformMatrix));
}
public void setCollisionObject(CollisionObject body, Collidable collidable){
this.body = body;
this.collidable = collidable;
}
public float getAngularVelocityMagnitude(){
return angularVelocity.lengthSquared();
}
public static boolean hasServerCollidableTree(Entity e){
return e.containsKey(EntityDataStrings.SERVER_COLLIDABLE_TREE);
}
public static ServerCollidableTree getServerCollidableTree(Entity e){
return (ServerCollidableTree)e.getData(EntityDataStrings.SERVER_COLLIDABLE_TREE);
}
}

View File

@ -31,7 +31,10 @@ import electrosphere.net.server.player.Player;
import electrosphere.net.server.protocol.InventoryProtocol;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.actor.ActorMeshMask;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.ServerDataCell;
import electrosphere.server.datacell.utils.DataCellSearchUtils;
import electrosphere.server.datacell.utils.ServerEntityTagUtils;
/**
*
@ -69,7 +72,7 @@ public class EquipState {
serverAttemptEquip(toEquip, point);
} else {
String pointName = point.getEquipPointId();
int serverSideID = Globals.entityManager.mapClientToServerId(toEquip.getId());
int serverSideID = Globals.clientSceneWrapper.mapClientToServerId(toEquip.getId());
NetworkMessage requestPickupMessage = InventoryMessage.constructclientRequestEquipItemMessage(pointName, serverSideID);
Globals.clientConnection.queueOutgoingMessage(requestPickupMessage);
}
@ -86,7 +89,8 @@ public class EquipState {
if(!hasEquipped && targetIsItem && itemIsInPointWhitelist){
//hydrate inventory item
String itemType = ItemUtils.getType(inInventoryEntity);
Entity inWorldItem = ItemUtils.spawnBasicItem(itemType);
Realm realm = Globals.realmManager.getEntityRealm(parent);
Entity inWorldItem = ItemUtils.serverSpawnBasicItem(realm,new Vector3d(0,0,0),itemType);
//bind in world with in inventory
ItemUtils.setRealWorldEntity(inInventoryEntity, inWorldItem);
@ -110,29 +114,31 @@ public class EquipState {
meshMask.queueMesh(modelName, toDraw);
}
//attach to parent bone
AttachUtils.attachEntityToEntityAtBone(parent, inWorldItem, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation()));
AttachUtils.serverAttachEntityToEntityAtBone(parent, inWorldItem, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation()));
//make uncollidable
if(inWorldItem.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY) && inWorldItem.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){
CollisionObject rigidBody = (CollisionObject)inWorldItem.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
Globals.collisionEngine.deregisterPhysicsObject(rigidBody);
Realm inWorldRealm = Globals.realmManager.getEntityRealm(inWorldItem);
inWorldRealm.getCollisionEngine().deregisterPhysicsObject(rigidBody);
}
//hide toEquip actor
EntityUtils.setDraw(inWorldItem, false);
//make untargetable
Globals.entityManager.removeEntityFromTag(inWorldItem, EntityTags.TARGETABLE);
ServerEntityTagUtils.removeTagFromEntity(inWorldItem, EntityTags.TARGETABLE);
break;
}
}
} else {
//since we're not replacing meshes we must be attaching to a bone
equipMap.put(point.getEquipPointId(),inWorldItem);
AttachUtils.attachEntityToEntityAtBone(parent, inWorldItem, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation()));
AttachUtils.serverAttachEntityToEntityAtBone(parent, inWorldItem, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation()));
if(inWorldItem.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY) && inWorldItem.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){
CollisionObject rigidBody = (CollisionObject)inWorldItem.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
Globals.collisionEngine.deregisterPhysicsObject(rigidBody);
Realm inWorldRealm = Globals.realmManager.getEntityRealm(inWorldItem);
inWorldRealm.getCollisionEngine().deregisterPhysicsObject(rigidBody);
}
Globals.entityManager.removeEntityFromTag(inWorldItem, EntityTags.TARGETABLE);
GravityUtils.attemptDeactivateGravity(inWorldItem);
ServerEntityTagUtils.removeTagFromEntity(inWorldItem, EntityTags.TARGETABLE);
GravityUtils.serverAttemptDeactivateGravity(inWorldItem);
}
//we need to send two packets
//1) Remove item from original inventory
@ -166,7 +172,7 @@ public class EquipState {
}
//get the chunk the equipper is in, and broadcast to that chunk that they equipped the item
//get datacell
ServerDataCell dataCell = Globals.dataCellManager.getDataCellAtPoint(EntityUtils.getPosition(parent));
ServerDataCell dataCell = DataCellSearchUtils.getEntityDataCell(parent);
//broadcast attach entity
int equipperId = parent.getId();
String equipPointId = point.getEquipPointId();
@ -206,29 +212,29 @@ public class EquipState {
meshMask.queueMesh(modelName, toDraw);
}
//attach to parent bone
AttachUtils.attachEntityToEntityAtBone(parent, toEquip, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation()));
AttachUtils.clientAttachEntityToEntityAtBone(parent, toEquip, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation()));
//make uncollidable
if(toEquip.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY) && toEquip.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){
CollisionObject rigidBody = (CollisionObject)toEquip.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
Globals.collisionEngine.deregisterPhysicsObject(rigidBody);
Globals.clientSceneWrapper.getCollisionEngine().deregisterPhysicsObject(rigidBody);
}
//hide toEquip actor
EntityUtils.setDraw(toEquip, false);
//make untargetable
Globals.entityManager.removeEntityFromTag(toEquip, EntityTags.TARGETABLE);
Globals.clientSceneWrapper.getScene().removeEntityFromTag(toEquip, EntityTags.TARGETABLE);
break;
}
}
} else {
//since we're not replacing meshes we must be attaching to a bone
equipMap.put(point.getEquipPointId(),toEquip);
AttachUtils.attachEntityToEntityAtBone(parent, toEquip, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation()));
AttachUtils.clientAttachEntityToEntityAtBone(parent, toEquip, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation()));
if(toEquip.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY) && toEquip.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){
CollisionObject rigidBody = (CollisionObject)toEquip.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
Globals.collisionEngine.deregisterPhysicsObject(rigidBody);
Globals.clientSceneWrapper.getCollisionEngine().deregisterPhysicsObject(rigidBody);
}
Globals.entityManager.removeEntityFromTag(toEquip, EntityTags.TARGETABLE);
GravityUtils.attemptDeactivateGravity(toEquip);
Globals.clientSceneWrapper.getScene().removeEntityFromTag(toEquip, EntityTags.TARGETABLE);
GravityUtils.clientAttemptDeactivateGravity(toEquip);
}
}
@ -356,10 +362,10 @@ public class EquipState {
equipInventory.removeItemSlot(pointId);
naturalInventory.addItem(ejectedItem);
//destroy in world item
transformUnequipPoint(pointId);
serverTransformUnequipPoint(pointId);
//tell all clients to unequip the world item
//get datacell
ServerDataCell dataCell = Globals.dataCellManager.getDataCellAtPoint(EntityUtils.getPosition(parent));
ServerDataCell dataCell = DataCellSearchUtils.getEntityDataCell(parent);
//broadcast attach entity
NetworkMessage unequipMessage = InventoryMessage.constructserverCommandUnequipItemMessage(parent.getId(), pointId);
//actually send the packet
@ -388,7 +394,19 @@ public class EquipState {
// inventory.addItem(item);
}
public void transformUnequipPoint(String pointId){
public void clientTransformUnequipPoint(String pointId){
Entity equipped = equipMap.remove(pointId);
if(equipped != null){
boolean targetHasWhitelist = ItemUtils.hasEquipList(equipped);
if(targetHasWhitelist){
} else {
AttachUtils.clientDetatchEntityFromEntityAtBone(parent, equipped);
EntityUtils.cleanUpEntity(equipped);
}
}
}
public void serverTransformUnequipPoint(String pointId){
Entity equipped = equipMap.remove(pointId);
if(equipped != null){
boolean targetHasWhitelist = ItemUtils.hasEquipList(equipped);
@ -426,8 +444,8 @@ public class EquipState {
// }
// }
} else {
AttachUtils.detatchEntityFromEntityAtBone(parent, equipped);
EntityUtils.cleanUpDrawableEntity(equipped);
AttachUtils.serverDetatchEntityFromEntityAtBone(parent, equipped);
EntityUtils.cleanUpEntity(equipped);
}
}
}

View File

@ -12,7 +12,7 @@ import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.collidable.CollidableTree;
import electrosphere.entity.state.collidable.ClientCollidableTree;
import electrosphere.entity.state.collidable.Impulse;
import electrosphere.entity.state.movement.FallTree;
import electrosphere.entity.state.movement.JumpTree;
@ -91,9 +91,9 @@ public class GravityTree implements BehaviorTree {
Quaternionf rotation = EntityUtils.getRotation(parent);
Vector3f newPosition;
javax.vecmath.Matrix4f bodyTransformMatrix;
CollidableTree collidableTree = null;
if(CollidableTree.hasCollidableTree(parent)){
collidableTree = CollidableTree.getCollidableTree(parent);
ClientCollidableTree collidableTree = null;
if(ClientCollidableTree.hasClientCollidableTree(parent)){
collidableTree = ClientCollidableTree.getClientCollidableTree(parent);
}
//parse attached network messages
@ -134,7 +134,7 @@ public class GravityTree implements BehaviorTree {
// position.set(new Vector3d(position.x,Globals.commonWorldData.getElevationAtPoint(position) + 0.0001f,position.z));
}
JumpTree jumpTree;
if((jumpTree = JumpTree.getJumpTree(parent))!=null){
if((jumpTree = JumpTree.getClientJumpTree(parent))!=null){
jumpTree.land();
}
FallTree fallTree;
@ -162,7 +162,7 @@ public class GravityTree implements BehaviorTree {
}
float gravityDif = gravityVelocity * (float)Math.pow(1.0f - linearDamping,deltaTime * 2);
Vector3d newGravityPos = new Vector3d(position.x,position.y - gravityDif,position.z);
float hitFraction = Globals.collisionEngine.sweepTest(body, new Vector3f((float)position.x,(float)position.y,(float)position.z), new Vector3f((float)newGravityPos.x,(float)newGravityPos.y,(float)newGravityPos.z));
float hitFraction = Globals.clientSceneWrapper.getCollisionEngine().sweepTest(body, new Vector3f((float)position.x,(float)position.y,(float)position.z), new Vector3f((float)newGravityPos.x,(float)newGravityPos.y,(float)newGravityPos.z));
// if(hitFraction >= 0){
// collidable.addImpulse(new Impulse(new Vector3d(0,-1,0),gravityDif * hitFraction,"gravity"));
// position.set(new Vector3d(position.x,position.y - gravityDif * hitFraction,position.z));

View File

@ -5,16 +5,30 @@ import electrosphere.entity.EntityDataStrings;
public class GravityUtils {
public static void attemptActivateGravity(Entity target){
public static void clientAttemptActivateGravity(Entity target){
if(target.containsKey(EntityDataStrings.GRAVITY_ENTITY)){
GravityTree tree = (GravityTree)target.getData(EntityDataStrings.GRAVITY_TREE);
GravityTree tree = (GravityTree)target.getData(EntityDataStrings.CLIENT_GRAVITY_TREE);
tree.start();
}
}
public static void attemptDeactivateGravity(Entity target){
public static void serverAttemptActivateGravity(Entity target){
if(target.containsKey(EntityDataStrings.GRAVITY_ENTITY)){
GravityTree tree = (GravityTree)target.getData(EntityDataStrings.GRAVITY_TREE);
ServerGravityTree tree = (ServerGravityTree)target.getData(EntityDataStrings.SERVER_GRAVITY_TREE);
tree.start();
}
}
public static void clientAttemptDeactivateGravity(Entity target){
if(target.containsKey(EntityDataStrings.GRAVITY_ENTITY)){
GravityTree tree = (GravityTree)target.getData(EntityDataStrings.CLIENT_GRAVITY_TREE);
tree.stop();
}
}
public static void serverAttemptDeactivateGravity(Entity target){
if(target.containsKey(EntityDataStrings.GRAVITY_ENTITY)){
ServerGravityTree tree = (ServerGravityTree)target.getData(EntityDataStrings.SERVER_GRAVITY_TREE);
tree.stop();
}
}

View File

@ -0,0 +1,238 @@
package electrosphere.entity.state.gravity;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.collidable.ClientCollidableTree;
import electrosphere.entity.state.collidable.Impulse;
import electrosphere.entity.state.collidable.ServerCollidableTree;
import electrosphere.entity.state.movement.FallTree;
import electrosphere.entity.state.movement.JumpTree;
import electrosphere.entity.state.movement.ServerFallTree;
import electrosphere.entity.state.movement.ServerJumpTree;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.server.datacell.Realm;
/**
*
* @author amaterasu
*/
public class ServerGravityTree implements BehaviorTree {
public static enum GravityTreeState {
ACTIVE,
NOT_ACTIVE,
}
GravityTreeState state;
Entity parent;
int frameCurrent = 0;
int fallFrame = 1;
float gravityVelocity = 0;
float gravityAccel = 0.0007f;
CollisionObject body;
Collidable collidable;
List<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList<EntityMessage>();
public ServerGravityTree(Entity e, Collidable collidable, CollisionObject body, int fallFrame){
state = GravityTreeState.ACTIVE;
parent = e;
this.body = body;
this.collidable = collidable;
this.fallFrame = fallFrame;
}
// public void setCollisionObject(CollisionObject body, Collidable collidable){
// this.body = body;
// this.collidable = collidable;
// }
public GravityTreeState getState(){
return state;
}
public void start(){
//TODO: check if can start moving
state = GravityTreeState.ACTIVE;
if(state == GravityTreeState.NOT_ACTIVE){
frameCurrent = 0;
}
}
public void interrupt(){
state = GravityTreeState.NOT_ACTIVE;
}
public void stop(){
state = GravityTreeState.NOT_ACTIVE;
}
static final float gravityConstant = 0.2f;
static final float linearDamping = 0.1f;
public void simulate(float deltaTime){
// float velocity = CreatureUtils.getVelocity(parent);
// float acceleration = CreatureUtils.getAcceleration(parent);
// float maxNaturalVelocity = CreatureUtils.getMaxNaturalVelocity(parent);
// Actor entityActor = EntityUtils.getActor(parent);
Vector3d position = EntityUtils.getPosition(parent);
// Vector3f movementVector = CreatureUtils.getMovementVector(parent);
Quaternionf rotation = EntityUtils.getRotation(parent);
Vector3f newPosition;
javax.vecmath.Matrix4f bodyTransformMatrix;
ServerCollidableTree collidableTree = null;
if(ServerCollidableTree.hasServerCollidableTree(parent)){
collidableTree = ServerCollidableTree.getServerCollidableTree(parent);
}
//parse attached network messages
// for(EntityMessage message : networkMessageQueue){
// networkMessageQueue.remove(message);
//// System.out.println("MOVE to " + message.getX() + " " + message.getY() + " " + message.getZ());
// switch(message.getMessageSubtype()){
// case ATTACKUPDATE:
// switch(message.gettreeState()){
// case 0:
// state = IdleTreeState.IDLE;
// break;
// case 1:
// state = IdleTreeState.NOT_IDLE;
// break;
// }
// EntityUtils.getPosition(parent).set(message.getpositionX(),message.getpositionY(),message.getpositionZ());
// CreatureUtils.setMovementVector(parent, new Vector3f(message.getrotationX(),message.getrotationY(),message.getrotationZ()));
// break;
// }
// }
//Basically if we're still spinning keep applying gravity
boolean angularVelocityLow = true;
if(collidableTree != null){
if(collidableTree.getAngularVelocityMagnitude() > 0.0001){
angularVelocityLow = false;
}
}
//state machine
switch(state){
case ACTIVE:
if(hadGroundCollision()){
state = GravityTreeState.NOT_ACTIVE;
if(!hadStructureCollision()){
// position.set(new Vector3d(position.x,Globals.commonWorldData.getElevationAtPoint(position) + 0.0001f,position.z));
}
ServerJumpTree jumpTree;
if((jumpTree = ServerJumpTree.getServerJumpTree(parent))!=null){
jumpTree.land();
}
ServerFallTree fallTree;
if((fallTree = ServerFallTree.getFallTree(parent))!=null){
fallTree.land();
}
frameCurrent = 0;
gravityVelocity = 0;
} else {
//animation nonsense
frameCurrent++;
if(frameCurrent == fallFrame){
ServerFallTree fallTree;
if((fallTree = ServerFallTree.getFallTree(parent))!=null){
fallTree.start();
}
}
//actual gravity calculations
if(gravityVelocity < gravityConstant){
gravityVelocity = gravityVelocity + gravityAccel;
}
if(gravityVelocity > gravityConstant){
gravityVelocity = gravityConstant;
}
float gravityDif = gravityVelocity * (float)Math.pow(1.0f - linearDamping,deltaTime * 2);
Vector3d newGravityPos = new Vector3d(position.x,position.y - gravityDif,position.z);
Realm parentRealm = Globals.realmManager.getEntityRealm(parent);
float hitFraction = parentRealm.getCollisionEngine().sweepTest(body, new Vector3f((float)position.x,(float)position.y,(float)position.z), new Vector3f((float)newGravityPos.x,(float)newGravityPos.y,(float)newGravityPos.z));
// if(hitFraction >= 0){
// collidable.addImpulse(new Impulse(new Vector3d(0,-1,0),gravityDif * hitFraction,"gravity"));
// position.set(new Vector3d(position.x,position.y - gravityDif * hitFraction,position.z));
// } else {
// position.set(new Vector3d(position.x,position.y - gravityDif,position.z));
// }
if(hitFraction < 0){
hitFraction = 1;
}
collidable.addImpulse(new Impulse(new Vector3d(0,-1,0), new Vector3d(0,0,0), new Vector3d(position), gravityDif * hitFraction,"gravity"));
// System.out.println(hitFraction);
// bodyTransformMatrix = new javax.vecmath.Matrix4f(PhysicsUtils.jomlToVecmathQuaternionf(rotation),PhysicsUtils.jomlToVecmathVector3f(new Vector3f((float)position.x,(float)position.y,(float)position.z)),1.0f);
// body.setWorldTransform(new electrosphere.linearmath.Transform(bodyTransformMatrix));
}
break;
case NOT_ACTIVE:
if(hadEntityCollision()){
start();
}
//nothing here atm
//eventually want to check if need to re-activate somehow
break;
}
}
public void addNetworkMessage(EntityMessage networkMessage) {
networkMessageQueue.add(networkMessage);
}
public boolean hadStructureCollision(){
boolean rVal = false;
for(Impulse impulse : collidable.getImpulses()){
if(impulse.getType().equals(Collidable.TYPE_STRUCTURE)){
rVal = true;
break;
}
}
return rVal;
}
public boolean hadGroundCollision(){
boolean rVal = false;
for(Impulse impulse : collidable.getImpulses()){
if(impulse.getType().equals(Collidable.TYPE_TERRAIN)){
rVal = true;
break;
} else if(
impulse.getType().equals(Collidable.TYPE_STRUCTURE) &&
new Vector3d(impulse.getDirection()).normalize().y > 0.7
){
rVal = true;
}
}
return rVal;
}
public boolean hadEntityCollision(){
boolean rVal = false;
for(Impulse impulse : collidable.getImpulses()){
if(impulse.getType().equals(Collidable.TYPE_CREATURE)){
rVal = true;
break;
}
}
return rVal;
}
}

View File

@ -1,5 +1,8 @@
package electrosphere.entity.state;
package electrosphere.entity.state.idle;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.BehaviorTreeAnnotation;
import electrosphere.entity.state.SyncedField;
import electrosphere.entity.state.attack.AttackTree;
import electrosphere.entity.state.attack.AttackTree.AttackTreeState;
import electrosphere.entity.state.movement.AirplaneMovementTree;
@ -64,10 +67,10 @@ public class IdleTree {
boolean movementTreeIsIdle = movementTreeIsIdle();
boolean hasAttackTree = parent.containsKey(EntityDataStrings.ATTACK_TREE);
boolean hasAttackTree = parent.containsKey(EntityDataStrings.CLIENT_ATTACK_TREE);
AttackTree attackTree = null;
if(hasAttackTree){
attackTree = CreatureUtils.getAttackTree(parent);
attackTree = CreatureUtils.clientGetAttackTree(parent);
}
//parse attached network messages
@ -151,9 +154,9 @@ public class IdleTree {
boolean movementTreeIsIdle(){
boolean rVal = false;
boolean hasMovementTree = parent.containsKey(EntityDataStrings.DATA_STRING_MOVEMENT_BT);
boolean hasMovementTree = parent.containsKey(EntityDataStrings.CLIENT_MOVEMENT_BT);
if(hasMovementTree){
BehaviorTree movementTree = CreatureUtils.getEntityMovementTree(parent);
BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(parent);
if(movementTree instanceof GroundMovementTree){
if(((GroundMovementTree)movementTree).getState() == MovementTreeState.IDLE){
rVal = true;

View File

@ -0,0 +1,175 @@
package electrosphere.entity.state.idle;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.BehaviorTreeAnnotation;
import electrosphere.entity.state.SyncedField;
import electrosphere.entity.state.attack.ServerAttackTree;
import electrosphere.entity.state.attack.ServerAttackTree.AttackTreeState;
import electrosphere.entity.state.movement.AirplaneMovementTree;
import electrosphere.entity.state.movement.ServerGroundMovementTree;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.movement.ServerGroundMovementTree.MovementTreeState;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.anim.Animation;
import java.util.concurrent.CopyOnWriteArrayList;
import org.joml.Vector3d;
@BehaviorTreeAnnotation(name="idle")
public class ServerIdleTree {
public static enum IdleTreeState {
IDLE,
NOT_IDLE,
}
@SyncedField(isEnum = true)
IdleTreeState state;
Entity parent;
CopyOnWriteArrayList<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList<EntityMessage>();
int frameCurrent;
int maxFrame = 60;
public ServerIdleTree(Entity e){
state = IdleTreeState.IDLE;
parent = e;
}
public IdleTreeState getState(){
return state;
}
public void start(){
//TODO: check if can start moving
state = IdleTreeState.IDLE;
frameCurrent = 0;
}
public void interrupt(){
state = IdleTreeState.NOT_IDLE;
}
public void stop(){
state = IdleTreeState.NOT_IDLE;
}
public void simulate(float deltaTime){
Actor entityActor = EntityUtils.getActor(parent);
boolean movementTreeIsIdle = movementTreeIsIdle();
boolean hasAttackTree = parent.containsKey(EntityDataStrings.SERVER_ATTACK_TREE);
ServerAttackTree attackTree = null;
if(hasAttackTree){
attackTree = CreatureUtils.serverGetAttackTree(parent);
}
//parse attached network messages
for(EntityMessage message : networkMessageQueue){
networkMessageQueue.remove(message);
// System.out.println("MOVE to " + message.getX() + " " + message.getY() + " " + message.getZ());
switch(message.getMessageSubtype()){
case ATTACKUPDATE:
switch(message.gettreeState()){
case 0:
state = IdleTreeState.IDLE;
break;
case 1:
state = IdleTreeState.NOT_IDLE;
break;
}
EntityUtils.getPosition(parent).set(message.getpositionX(),message.getpositionY(),message.getpositionZ());
CreatureUtils.setFacingVector(parent, new Vector3d(message.getrotationX(),message.getrotationY(),message.getrotationZ()));
break;
case ATTACHENTITYTOENTITY:
case CREATE:
case DESTROY:
case MOVE:
case MOVEUPDATE:
case SETBEHAVIORTREE:
case SETFACING:
case SETPOSITION:
case SETPROPERTY:
case SPAWNCREATURE:
case SPAWNITEM:
case KILL:
//silently ignore
break;
}
}
boolean isIdle;
//state machine
switch(state){
case IDLE:
if(entityActor != null){
if(
(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(Animation.ANIMATION_IDLE_1)) &&
(Globals.assetManager.fetchModel(entityActor.getModelPath()) != null && Globals.assetManager.fetchModel(entityActor.getModelPath()).getAnimation(Animation.ANIMATION_IDLE_1) != null)
){
entityActor.playAnimation(Animation.ANIMATION_IDLE_1,3);
entityActor.incrementAnimationTime(0.0001);
}
}
isIdle = true;
if(!movementTreeIsIdle){
isIdle = false;
}
if(hasAttackTree){
if(attackTree.getState() != AttackTreeState.IDLE){
isIdle = false;
}
}
if(!isIdle){
state = IdleTreeState.NOT_IDLE;
}
break;
case NOT_IDLE:
isIdle = true;
if(!movementTreeIsIdle){
isIdle = false;
}
if(hasAttackTree){
if(attackTree.getState() != AttackTreeState.IDLE){
isIdle = false;
}
}
if(isIdle){
state = IdleTreeState.IDLE;
}
break;
}
}
boolean movementTreeIsIdle(){
boolean rVal = false;
boolean hasMovementTree = parent.containsKey(EntityDataStrings.SERVER_MOVEMENT_BT);
if(hasMovementTree){
BehaviorTree movementTree = CreatureUtils.serverGetEntityMovementTree(parent);
if(movementTree instanceof ServerGroundMovementTree){
if(((ServerGroundMovementTree)movementTree).getState() == MovementTreeState.IDLE){
rVal = true;
}
} else if(movementTree instanceof AirplaneMovementTree){
rVal = false;
}
}
return rVal;
}
public void addNetworkMessage(EntityMessage networkMessage) {
networkMessageQueue.add(networkMessage);
}
}

View File

@ -4,6 +4,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.equip.EquipState;
import electrosphere.entity.types.item.ItemUtils;
@ -12,6 +13,8 @@ import electrosphere.menu.WindowStrings;
import electrosphere.menu.WindowUtils;
import electrosphere.net.parser.net.message.InventoryMessage;
import electrosphere.net.server.protocol.InventoryProtocol;
import electrosphere.server.datacell.utils.EntityLookupUtils;
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
/**
* Principally used to handle network messages related to inventory and thread synchronization
@ -26,127 +29,86 @@ public class InventoryState implements BehaviorTree {
}
public static InventoryState createInventoryState(Entity parent){
public static InventoryState clientCreateInventoryState(Entity parent){
InventoryState rVal = new InventoryState();
rVal.parent = parent;
Globals.entityManager.registerBehaviorTree(rVal);
Globals.clientSceneWrapper.getScene().registerBehaviorTree(rVal);
return rVal;
}
@Override
public void simulate(float deltaTime) {
if(Globals.RUN_SERVER){
for(InventoryMessage message : networkMessageQueue){
networkMessageQueue.remove(message);
switch(message.getMessageSubtype()){
case ADDITEMTOINVENTORY:
InventoryUtils.attemptStoreItem(parent, Globals.entityManager.getEntityFromId(message.getentityId()));
break;
case REMOVEITEMFROMINVENTORY:
InventoryUtils.attemptEjectItem(parent, Globals.entityManager.getEntityFromId(message.getentityId()));
break;
case CLIENTREQUESTEQUIPITEM:{
//item to equip
Entity target = Globals.entityManager.getEntityFromId(message.getentityId());
//perform transform if it makes sense
if(InventoryUtils.hasEquipInventory(parent) && InventoryUtils.hasNaturalInventory(parent) && EquipState.hasEquipState(parent)){
EquipState equipState = EquipState.getEquipState(parent);
EquipPoint point = equipState.getEquipPoint(message.getequipPointId());
equipState.commandAttemptEquip(target, point);
}
for(InventoryMessage message : networkMessageQueue){
networkMessageQueue.remove(message);
switch(message.getMessageSubtype()){
case ADDITEMTOINVENTORY:
//the ID we get is of the in-inventory item
Entity inInventorySpawnedItem = InventoryUtils.clientConstructInInventoryItem(parent,message.getitemTemplate());
//map id
if(inInventorySpawnedItem != null){
Globals.clientSceneWrapper.mapIdToId(inInventorySpawnedItem.getId(), message.getentityId());
}
//attempt re-render ui
WindowUtils.attemptRedrawInventoryWindows();
break;
case CLIENTREQUESTUNEQUIPITEM:{
//make sure can unequip
if(InventoryUtils.hasEquipInventory(parent) && InventoryUtils.hasNaturalInventory(parent) && EquipState.hasEquipState(parent)){
EquipState equipState = EquipState.getEquipState(parent);
EquipPoint point = equipState.getEquipPoint(message.getequipPointId());
if(equipState.hasEquippedAtPoint(message.getequipPointId())){
equipState.commandAttemptUnequip(message.getequipPointId());
//tell player
}
case REMOVEITEMFROMINVENTORY:
InventoryUtils.removeItemFromInventories(parent, Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId()));
//attempt re-render ui
WindowUtils.attemptRedrawInventoryWindows();
break;
case SERVERCOMMANDMOVEITEMCONTAINER: {
//this is a command to switch an item from one inventory to another (ie equip->natural or vice-versa)
switch(message.getcontainerType()){
case InventoryProtocol.INVENTORY_TYPE_EQUIP:
Entity target = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId());
boolean isInventoryItem = ItemUtils.itemIsInInventory(target);
boolean parentHasNaturalInventory = InventoryUtils.hasNaturalInventory(parent);
boolean parentHasEquipInventory = InventoryUtils.hasEquipInventory(parent);
String equipPointId = message.getequipPointId();
//check that we can do the transform
if(isInventoryItem && parentHasEquipInventory && parentHasNaturalInventory){
//switch containers
UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(parent);
RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(parent);
naturalInventory.removeItem(target);
equipInventory.addItem(equipPointId, target);
}
break;
case InventoryProtocol.INVENTORY_TYPE_NATURAL:
target = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId());
isInventoryItem = ItemUtils.itemIsInInventory(target);
parentHasNaturalInventory = InventoryUtils.hasNaturalInventory(parent);
parentHasEquipInventory = InventoryUtils.hasEquipInventory(parent);
equipPointId = message.getequipPointId();
//check that we can do the transform
if(isInventoryItem && parentHasEquipInventory && parentHasNaturalInventory){
//switch containers
UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(parent);
RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(parent);
naturalInventory.addItem(target);
equipInventory.removeItemSlot(equipPointId);
}
break;
}
break;
case SERVERCOMMANDUNEQUIPITEM:
case SERVERCOMMANDEQUIPITEM:
case SERVERCOMMANDMOVEITEMCONTAINER:
break;
//once we've switched the items around, redraw the inventory to reflect the updated contents
WindowUtils.attemptRedrawInventoryWindows();
}
}
} else {
for(InventoryMessage message : networkMessageQueue){
networkMessageQueue.remove(message);
switch(message.getMessageSubtype()){
case ADDITEMTOINVENTORY:
//the ID we get is of the in-inventory item
Entity inInventorySpawnedItem = InventoryUtils.constructInInventoryItem(parent,message.getitemTemplate());
//map id
if(inInventorySpawnedItem != null){
Globals.entityManager.mapIdToId(inInventorySpawnedItem.getId(), message.getentityId());
}
//attempt re-render ui
WindowUtils.attemptRedrawInventoryWindows();
break;
case REMOVEITEMFROMINVENTORY:
InventoryUtils.removeItemFromInventories(parent, Globals.entityManager.getEntityFromServerId(message.getentityId()));
//attempt re-render ui
WindowUtils.attemptRedrawInventoryWindows();
break;
case SERVERCOMMANDMOVEITEMCONTAINER: {
//this is a command to switch an item from one inventory to another (ie equip->natural or vice-versa)
switch(message.getcontainerType()){
case InventoryProtocol.INVENTORY_TYPE_EQUIP:
Entity target = Globals.entityManager.getEntityFromId(Globals.entityManager.mapServerToClientId(message.getentityId()));
boolean isInventoryItem = ItemUtils.itemIsInInventory(target);
boolean parentHasNaturalInventory = InventoryUtils.hasNaturalInventory(parent);
boolean parentHasEquipInventory = InventoryUtils.hasEquipInventory(parent);
String equipPointId = message.getequipPointId();
//check that we can do the transform
if(isInventoryItem && parentHasEquipInventory && parentHasNaturalInventory){
//switch containers
UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(parent);
RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(parent);
naturalInventory.removeItem(target);
equipInventory.addItem(equipPointId, target);
}
break;
case InventoryProtocol.INVENTORY_TYPE_NATURAL:
target = Globals.entityManager.getEntityFromId(Globals.entityManager.mapServerToClientId(message.getentityId()));
isInventoryItem = ItemUtils.itemIsInInventory(target);
parentHasNaturalInventory = InventoryUtils.hasNaturalInventory(parent);
parentHasEquipInventory = InventoryUtils.hasEquipInventory(parent);
equipPointId = message.getequipPointId();
//check that we can do the transform
if(isInventoryItem && parentHasEquipInventory && parentHasNaturalInventory){
//switch containers
UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(parent);
RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(parent);
naturalInventory.addItem(target);
equipInventory.removeItemSlot(equipPointId);
}
break;
}
//once we've switched the items around, redraw the inventory to reflect the updated contents
WindowUtils.attemptRedrawInventoryWindows();
break;
case SERVERCOMMANDUNEQUIPITEM: {
if(Globals.playerEntity != null && EquipState.hasEquipState(Globals.playerEntity)){
//unequip the item
EquipState equipState = EquipState.getEquipState(Globals.playerEntity);
Entity entityInSlot = equipState.getEquippedItemAtPoint(message.getequipPointId());
equipState.clientTransformUnequipPoint(message.getequipPointId());
//destroy the in-world manifestation of said item
EntityUtils.cleanUpEntity(entityInSlot);
}
break;
case SERVERCOMMANDUNEQUIPITEM: {
if(Globals.playerEntity != null && EquipState.hasEquipState(Globals.playerEntity)){
//unequip the item
EquipState equipState = EquipState.getEquipState(Globals.playerEntity);
Entity entityInSlot = equipState.getEquippedItemAtPoint(message.getequipPointId());
equipState.transformUnequipPoint(message.getequipPointId());
//destroy the in-world manifestation of said item
Globals.entityManager.deregisterEntity(entityInSlot);
}
}
break;
case CLIENTREQUESTEQUIPITEM:
case CLIENTREQUESTUNEQUIPITEM:
case SERVERCOMMANDEQUIPITEM:
break;
}
break;
case CLIENTREQUESTEQUIPITEM:
case CLIENTREQUESTUNEQUIPITEM:
case SERVERCOMMANDEQUIPITEM:
break;
}
}
}

View File

@ -15,7 +15,11 @@ import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.net.parser.net.message.InventoryMessage;
import electrosphere.net.parser.net.message.NetworkMessage;
import electrosphere.net.server.player.Player;
import electrosphere.server.datacell.EntityDataCellMapper;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.ServerDataCell;
import electrosphere.server.datacell.utils.DataCellSearchUtils;
import electrosphere.server.datacell.utils.EntityLookupUtils;
import electrosphere.util.Utilities;
public class InventoryUtils {
@ -42,8 +46,17 @@ public class InventoryUtils {
* @param target the entity to get inventory state from
* @return The inventory state behavior tree or null
*/
public static InventoryState getInventoryState(Entity target){
return (InventoryState)target.getData(EntityDataStrings.INVENTORY_STATE);
public static InventoryState clientGetInventoryState(Entity target){
return (InventoryState)target.getData(EntityDataStrings.CLIENT_INVENTORY_STATE);
}
/**
* Gets the current inventory state
* @param target the entity to get inventory state from
* @return The inventory state behavior tree or null
*/
public static ServerInventoryState serverGetInventoryState(Entity target){
return (ServerInventoryState)target.getData(EntityDataStrings.SERVER_INVENTORY_STATE);
}
/**
@ -51,8 +64,17 @@ public class InventoryUtils {
* @param target The entity to attach inventory state to
* @param state The inventory state to attach
*/
public static void setInventoryState(Entity target, InventoryState state){
target.putData(EntityDataStrings.INVENTORY_STATE, state);
public static void clientSetInventoryState(Entity target, InventoryState state){
target.putData(EntityDataStrings.CLIENT_INVENTORY_STATE, state);
}
/**
* Sets the current inventory state
* @param target The entity to attach inventory state to
* @param state The inventory state to attach
*/
public static void serverSetInventoryState(Entity target, ServerInventoryState state){
target.putData(EntityDataStrings.SERVER_INVENTORY_STATE, state);
}
/**
@ -60,7 +82,7 @@ public class InventoryUtils {
* @param creature The creature to store the item in
* @param item The item to store
*/
public static void attemptStoreItemTransform(Entity creature, Entity item){
public static void serverAttemptStoreItemTransform(Entity creature, Entity item){
boolean creatureIsCreature = CreatureUtils.isCreature(creature);
boolean itemIsItem = ItemUtils.isItem(item);
boolean hasInventory = hasNaturalInventory(creature);
@ -73,17 +95,18 @@ public class InventoryUtils {
UnrelationalInventoryState inventory = getNaturalInventory(creature);
//destroy in-world entity and create in-inventory item
//we're doing this so that we're not constantly sending networking messages for invisible entities attached to the player
Entity inventoryItem = ItemUtils.recreateContainerItem(item, creature);
Entity inventoryItem = ItemUtils.serverRecreateContainerItem(item, creature);
//destroy the item that was left over
ItemUtils.destroyInWorldItem(item);
ItemUtils.serverDestroyInWorldItem(item);
//store item in inventory
inventory.addItem(inventoryItem);
//set item containing parent
ItemUtils.setContainingParent(inventoryItem, creature);
//if we are the server, immediately send required packets
if(Globals.RUN_SERVER){
ServerDataCell dataCell = Globals.dataCellManager.getDataCellAtPoint(EntityUtils.getPosition(item));
dataCell.removeEntity(item);
ServerDataCell dataCell = Globals.realmManager.getEntityRealm(item).getEntityDataCellMapper().getEntityDataCell(item);
// ServerDataCell dataCell = Globals.dataCellLocationResolver.getDataCellAtPoint(EntityUtils.getPosition(item),item);
dataCell.getScene().deregisterEntity(item);
//broadcast destroy entity
dataCell.broadcastNetworkMessage(EntityMessage.constructDestroyMessage(item.getId()));
//tell controlling player that they have an item in their inventory
@ -106,11 +129,11 @@ public class InventoryUtils {
public static void attemptStoreItem(Entity creature, Entity item){
if(Globals.RUN_SERVER){
//if we're the server, immediately attempt the transform
attemptStoreItemTransform(creature,item);
serverAttemptStoreItemTransform(creature,item);
} else {
//if we're the client, tell the server we want to try the transform
NetworkMessage requestPickupMessage = InventoryMessage.constructaddItemToInventoryMessage(
Globals.entityManager.mapClientToServerId(item.getId()),
Globals.clientSceneWrapper.mapClientToServerId(item.getId()),
ItemUtils.getType(item)
);
Globals.clientConnection.queueOutgoingMessage(requestPickupMessage);
@ -118,12 +141,12 @@ public class InventoryUtils {
}
/**
* [CLIENT ONLY] Places an item of provided type in the parent container's natural inventory
* Places an item of provided type in the parent container's natural inventory
* @param parentContainer The entity (typically a creature) which will receive the item in their natural inventory
* @param type The type of item to place in the inventory
* @return The in-inventory item entity
*/
public static Entity constructInInventoryItem(Entity parentContainer, String type){
public static Entity clientConstructInInventoryItem(Entity parentContainer, String type){
//sanity checks
boolean creatureIsCreature = CreatureUtils.isCreature(parentContainer);
boolean hasInventory = hasNaturalInventory(parentContainer);
@ -135,11 +158,11 @@ public class InventoryUtils {
UnrelationalInventoryState inventory = getNaturalInventory(parentContainer);
//create item
//TODO: optimize by directly creating the container item instead of first spawning regular item
Entity spawnedItem = ItemUtils.spawnBasicItem(type);
Entity spawnedItem = ItemUtils.clientSpawnBasicItem(type);
//convert to in-inventory
Entity inventoryItem = ItemUtils.recreateContainerItem(spawnedItem, parentContainer);
Entity inventoryItem = ItemUtils.clientRecreateContainerItem(spawnedItem, parentContainer);
//destroy the item that was left over
ItemUtils.destroyInWorldItem(spawnedItem);
ItemUtils.clientDestroyInWorldItem(spawnedItem);
//store item in inventory
inventory.addItem(inventoryItem);
//set item containing parent
@ -153,7 +176,7 @@ public class InventoryUtils {
/**
* [SERVER ONLY] Attempts the transform to eject an item from an inventory, if this is the server it has added side effect of sending packets on success
* Attempts the transform to eject an item from an inventory, if this is the server it has added side effect of sending packets on success
* @param creature The creature to eject the item from
* @param item The item to eject
*/
@ -184,13 +207,14 @@ public class InventoryUtils {
if(realWorldItem != null){
//drop item
EquipState equipState = EquipState.getEquipState(creature);
equipState.transformUnequipPoint(inventorySlot);
equipState.serverTransformUnequipPoint(inventorySlot);
// equipState.serverAttemptUnequip(inventory.getItemSlot(item));
//
//Tell clients to destroy the attached item
Vector3d oldItemPos = EntityUtils.getPosition(realWorldItem);
//get closest chunk
ServerDataCell dataCell = Globals.dataCellManager.getDataCellAtPoint(oldItemPos);
// ServerDataCell dataCell = Globals.dataCellLocationResolver.getDataCellAtPoint(oldItemPos,realWorldItem);
ServerDataCell dataCell = Globals.realmManager.getEntityRealm(realWorldItem).getEntityDataCellMapper().getEntityDataCell(realWorldItem);
//broadcast destroy item
NetworkMessage destroyMessage = InventoryMessage.constructserverCommandUnequipItemMessage(creature.getId(), inventorySlot);
dataCell.broadcastNetworkMessage(destroyMessage);
@ -206,23 +230,17 @@ public class InventoryUtils {
//tell the player they don't have the item anymore
controllerPlayer.addMessage(InventoryMessage.constructremoveItemFromInventoryMessage(item.getId()));
}
//
//compose item into in-world entity
Entity inWorldItem = ItemUtils.spawnBasicItem(ItemUtils.getType(item));
//delete in container item
ItemUtils.destroyInInventoryItem(item);
//get parent realm
Realm realm = Globals.realmManager.getEntityRealm(creature);
//find "in front of creature"
Vector3d dropSpot = new Vector3d(EntityUtils.getPosition(creature)).add(CreatureUtils.getFacingVector(creature));
//move in-world entity to in front of creature
EntityUtils.getPosition(inWorldItem).set(dropSpot);
//activate gravity
GravityUtils.attemptActivateGravity(inWorldItem);
//
//add the item to closest data cell
//get closest chunk
ServerDataCell dataCell = Globals.dataCellManager.getDataCellAtPoint(dropSpot);
//add item
Globals.dataCellManager.initializeServerSideEntity(inWorldItem, dataCell);
//compose item into in-world entity
Entity inWorldItem = ItemUtils.serverSpawnBasicItem(realm,dropSpot,ItemUtils.getType(item));
//delete in container item
ItemUtils.destroyInInventoryItem(item);
//activate gravity
GravityUtils.serverAttemptActivateGravity(inWorldItem);
}
}
@ -233,7 +251,7 @@ public class InventoryUtils {
serverAttemptEjectItemTransform(creature,item);
} else {
//if we're the client, tell the server we want to try the transform
NetworkMessage requestPickupMessage = InventoryMessage.constructremoveItemFromInventoryMessage(Globals.entityManager.mapClientToServerId(item.getId()));
NetworkMessage requestPickupMessage = InventoryMessage.constructremoveItemFromInventoryMessage(Globals.clientSceneWrapper.mapClientToServerId(item.getId()));
Globals.clientConnection.queueOutgoingMessage(requestPickupMessage);
}
}
@ -267,7 +285,7 @@ public class InventoryUtils {
if(realWorldItem != null){
//drop item
EquipState equipState = EquipState.getEquipState(creature);
equipState.transformUnequipPoint(inventory.getItemSlot(item));
equipState.clientTransformUnequipPoint(inventory.getItemSlot(item));
}
//remove item from inventory
inventory.tryRemoveItem(item);

View File

@ -0,0 +1,85 @@
package electrosphere.entity.state.inventory;
import java.util.concurrent.CopyOnWriteArrayList;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.equip.EquipState;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.game.data.creature.type.equip.EquipPoint;
import electrosphere.menu.WindowStrings;
import electrosphere.menu.WindowUtils;
import electrosphere.net.parser.net.message.InventoryMessage;
import electrosphere.net.server.protocol.InventoryProtocol;
import electrosphere.server.datacell.utils.EntityLookupUtils;
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
/**
* Principally used to handle network messages related to inventory and thread synchronization
*/
public class ServerInventoryState implements BehaviorTree {
CopyOnWriteArrayList<InventoryMessage> networkMessageQueue = new CopyOnWriteArrayList<InventoryMessage>();
Entity parent;
ServerInventoryState() {
}
public static ServerInventoryState serverCreateInventoryState(Entity parent){
ServerInventoryState rVal = new ServerInventoryState();
rVal.parent = parent;
ServerBehaviorTreeUtils.attachBTreeToEntity(parent, rVal);
return rVal;
}
@Override
public void simulate(float deltaTime) {
for(InventoryMessage message : networkMessageQueue){
networkMessageQueue.remove(message);
switch(message.getMessageSubtype()){
case ADDITEMTOINVENTORY:
InventoryUtils.attemptStoreItem(parent, EntityLookupUtils.getEntityById(message.getentityId()));
break;
case REMOVEITEMFROMINVENTORY:
InventoryUtils.attemptEjectItem(parent, EntityLookupUtils.getEntityById(message.getentityId()));
break;
case CLIENTREQUESTEQUIPITEM:{
//item to equip
Entity target = EntityLookupUtils.getEntityById(message.getentityId());
//perform transform if it makes sense
if(InventoryUtils.hasEquipInventory(parent) && InventoryUtils.hasNaturalInventory(parent) && EquipState.hasEquipState(parent)){
EquipState equipState = EquipState.getEquipState(parent);
EquipPoint point = equipState.getEquipPoint(message.getequipPointId());
equipState.commandAttemptEquip(target, point);
}
}
break;
case CLIENTREQUESTUNEQUIPITEM:{
//make sure can unequip
if(InventoryUtils.hasEquipInventory(parent) && InventoryUtils.hasNaturalInventory(parent) && EquipState.hasEquipState(parent)){
EquipState equipState = EquipState.getEquipState(parent);
EquipPoint point = equipState.getEquipPoint(message.getequipPointId());
if(equipState.hasEquippedAtPoint(message.getequipPointId())){
equipState.commandAttemptUnequip(message.getequipPointId());
//tell player
}
}
}
break;
case SERVERCOMMANDUNEQUIPITEM:
case SERVERCOMMANDEQUIPITEM:
case SERVERCOMMANDMOVEITEMCONTAINER:
break;
}
}
}
public void addNetworkMessage(InventoryMessage networkMessage) {
networkMessageQueue.add(networkMessage);
}
}

View File

@ -64,7 +64,7 @@ public class IronSightTree implements BehaviorTree {
public static void attachIronSightTree(Entity player){
IronSightTree ironSightTree = new IronSightTree();
player.putData(EntityDataStrings.IRON_SIGHT_TREE, ironSightTree);
Globals.entityManager.registerBehaviorTree(ironSightTree);
Globals.clientSceneWrapper.getScene().registerBehaviorTree(ironSightTree);
}
}

View File

@ -15,6 +15,7 @@ import electrosphere.game.data.creature.type.HealthSystem;
import electrosphere.net.parser.net.message.CharacterMessage;
import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.renderer.actor.Actor;
import electrosphere.server.datacell.utils.DataCellSearchUtils;
public class LifeState implements BehaviorTree {
@ -114,13 +115,11 @@ public class LifeState implements BehaviorTree {
if(Globals.RUN_SERVER){
state = LifeStateEnum.DYING;
Vector3d position = EntityUtils.getPosition(parent);
Globals.dataCellManager.sendNetworkMessageToChunk(
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
EntityMessage.constructKillMessage(
Main.getCurrentFrame(),
parent.getId()
),
Globals.serverWorldData.convertRealToChunkSpace(position.x),
Globals.serverWorldData.convertRealToChunkSpace(position.z)
)
);
}
} else {

View File

@ -18,6 +18,7 @@ import electrosphere.game.collision.collidable.Collidable;
import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.anim.Animation;
import electrosphere.server.datacell.utils.DataCellSearchUtils;
public class AirplaneMovementTree implements BehaviorTree {
@ -243,7 +244,7 @@ public class AirplaneMovementTree implements BehaviorTree {
stateNumber = 1;
break;
}
Globals.dataCellManager.sendNetworkMessageToChunk(
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
EntityMessage.constructmoveUpdateMessage(
parent.getId(),
Main.getCurrentFrame(),
@ -256,9 +257,7 @@ public class AirplaneMovementTree implements BehaviorTree {
rotation.w,
velocity,
stateNumber
),
Globals.serverWorldData.convertRealToChunkSpace(position.x),
Globals.serverWorldData.convertRealToChunkSpace(position.z)
)
);
}
}

View File

@ -22,6 +22,7 @@ import electrosphere.game.collision.collidable.Collidable;
import electrosphere.net.NetUtils;
import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.renderer.anim.Animation;
import electrosphere.server.datacell.utils.DataCellSearchUtils;
import electrosphere.renderer.Model;
import electrosphere.renderer.actor.Actor;
@ -201,9 +202,7 @@ public class GroundMovementTree implements BehaviorTree {
// System.out.println("MOVE to " + message.getX() + " " + message.getY() + " " + message.getZ());
switch(message.getMessageSubtype()){
case MOVE:
if(Globals.RUN_CLIENT){
position.set(message.getpositionX(), message.getpositionY(), message.getpositionZ());
}
position.set(message.getpositionX(), message.getpositionY(), message.getpositionZ());
break;
case SETFACING:
break;
@ -214,17 +213,17 @@ public class GroundMovementTree implements BehaviorTree {
case 0:
state = MovementTreeState.STARTUP;
// System.out.println("Set state STARTUP");
GravityUtils.attemptActivateGravity(parent);
GravityUtils.clientAttemptActivateGravity(parent);
break;
case 1:
state = MovementTreeState.MOVE;
// System.out.println("Set state MOVE");
GravityUtils.attemptActivateGravity(parent);
GravityUtils.clientAttemptActivateGravity(parent);
break;
case 2:
state = MovementTreeState.SLOWDOWN;
// System.out.println("Set state SLOWDOWN");
GravityUtils.attemptActivateGravity(parent);
GravityUtils.clientAttemptActivateGravity(parent);
break;
case 3:
state = MovementTreeState.IDLE;
@ -288,27 +287,8 @@ public class GroundMovementTree implements BehaviorTree {
// position.set(newPosition);
rotation.set(movementQuaternion);
GravityUtils.attemptActivateGravity(parent);
GravityUtils.clientAttemptActivateGravity(parent);
if(Globals.RUN_SERVER){
Globals.dataCellManager.sendNetworkMessageToChunk(
EntityMessage.constructmoveUpdateMessage(
parent.getId(),
Main.getCurrentFrame(),
position.x,
position.y,
position.z,
rotation.x,
rotation.y,
rotation.z,
rotation.w,
velocity,
0
),
Globals.serverWorldData.convertRealToChunkSpace(position.x),
Globals.serverWorldData.convertRealToChunkSpace(position.z)
);
}
break;
case MOVE:
//check if can restart animation
@ -340,27 +320,8 @@ public class GroundMovementTree implements BehaviorTree {
// position.set(newPosition);
rotation.set(movementQuaternion);
GravityUtils.attemptActivateGravity(parent);
GravityUtils.clientAttemptActivateGravity(parent);
if(Globals.RUN_SERVER){
Globals.dataCellManager.sendNetworkMessageToChunk(
EntityMessage.constructmoveUpdateMessage(
parent.getId(),
Main.getCurrentFrame(),
position.x,
position.y,
position.z,
rotation.x,
rotation.y,
rotation.z,
rotation.w,
velocity,
1
),
Globals.serverWorldData.convertRealToChunkSpace(position.x),
Globals.serverWorldData.convertRealToChunkSpace(position.z)
);
}
break;
case SLOWDOWN:
//run slowdown code
@ -400,27 +361,8 @@ public class GroundMovementTree implements BehaviorTree {
// position.set(newPosition);
rotation.set(movementQuaternion);
GravityUtils.attemptActivateGravity(parent);
GravityUtils.clientAttemptActivateGravity(parent);
if(Globals.RUN_SERVER){
Globals.dataCellManager.sendNetworkMessageToChunk(
EntityMessage.constructmoveUpdateMessage(
parent.getId(),
Main.getCurrentFrame(),
position.x,
position.y,
position.z,
rotation.x,
rotation.y,
rotation.z,
rotation.w,
velocity,
2
),
Globals.serverWorldData.convertRealToChunkSpace(position.x),
Globals.serverWorldData.convertRealToChunkSpace(position.z)
);
}
break;
case IDLE:
// body.clearForces();
@ -441,7 +383,7 @@ public class GroundMovementTree implements BehaviorTree {
public boolean canStartMoving(){
boolean rVal = true;
if(parent.containsKey(EntityDataStrings.ATTACK_TREE) && ((AttackTree)parent.getData(EntityDataStrings.ATTACK_TREE)).getState() != AttackTreeState.IDLE){
if(parent.containsKey(EntityDataStrings.CLIENT_ATTACK_TREE) && ((AttackTree)parent.getData(EntityDataStrings.CLIENT_ATTACK_TREE)).getState() != AttackTreeState.IDLE){
rVal = false;
}
return rVal;
@ -475,11 +417,11 @@ public class GroundMovementTree implements BehaviorTree {
this.sprintTree = sprintTree;
}
public void setJumpTree(JumpTree jumpTree){
public void setClientJumpTree(JumpTree jumpTree){
this.jumpTree = jumpTree;
}
public void setFallTree(FallTree fallTree){
public void setClientFallTree(FallTree fallTree){
this.fallTree = fallTree;
}

View File

@ -44,7 +44,7 @@ public class JumpTree implements BehaviorTree {
state = JumpState.ACTIVE;
currentFrame = 0;
currentJumpForce = jumpForce;
GravityUtils.attemptActivateGravity(parent);
GravityUtils.clientAttemptActivateGravity(parent);
}
}
@ -67,7 +67,7 @@ public class JumpTree implements BehaviorTree {
//potentially disable
if(currentFrame >= jumpFrames){
state = JumpState.AWAITING_LAND;
GravityUtils.attemptActivateGravity(parent);
GravityUtils.clientAttemptActivateGravity(parent);
}
break;
case INACTIVE:
@ -77,8 +77,8 @@ public class JumpTree implements BehaviorTree {
}
}
public static JumpTree getJumpTree(Entity parent){
return (JumpTree)parent.getData(EntityDataStrings.JUMP_TREE);
public static JumpTree getClientJumpTree(Entity parent){
return (JumpTree)parent.getData(EntityDataStrings.CLIENT_JUMP_TREE);
}
public void land(){

View File

@ -8,6 +8,7 @@ import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
public class ProjectileTree implements BehaviorTree {
@ -44,8 +45,8 @@ public class ProjectileTree implements BehaviorTree {
lifeCurrent++;
if(lifeCurrent >= maxLife){
Globals.entityManager.deregisterEntity(parent);
Globals.entityManager.deregisterBehaviorTree(this);
EntityUtils.cleanUpEntity(parent);
ServerBehaviorTreeUtils.detatchBTreeFromEntity(parent,this);
}
Vector3d positionCurrent = EntityUtils.getPosition(parent);

View File

@ -0,0 +1,101 @@
package electrosphere.entity.state.movement;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.renderer.actor.Actor;
public class ServerFallTree implements BehaviorTree {
static enum FallState {
ACTIVE,
INACTIVE,
}
FallState state = FallState.INACTIVE;
String animationFall = "Armature|Fall";
String animationLand = "Armature|Land";
Entity parent;
ServerJumpTree jumpTree;
public ServerFallTree(Entity parent){
this.parent = parent;
}
@Override
public void simulate(float deltaTime) {
Actor entityActor = EntityUtils.getActor(parent);
switch(state){
case ACTIVE:
if(entityActor != null){
String animationToPlay = determineCorrectAnimation();
if(
!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationToPlay) &&
(jumpTree == null || !jumpTree.isJumping())
){
entityActor.playAnimation(animationToPlay,1);
entityActor.incrementAnimationTime(0.0001);
}
}
break;
case INACTIVE:
break;
}
}
public void start(){
state = FallState.ACTIVE;
}
public boolean isFalling(){
return state == FallState.ACTIVE;
}
public void land(){
if(state != FallState.INACTIVE){
state = FallState.INACTIVE;
Actor entityActor = EntityUtils.getActor(parent);
if(entityActor != null){
String animationToPlay = determineCorrectAnimation();
if(
!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationToPlay)
){
entityActor.playAnimation(animationToPlay,1);
entityActor.incrementAnimationTime(0.0001);
}
}
}
}
public static ServerFallTree getFallTree(Entity parent){
return (ServerFallTree)parent.getData(EntityDataStrings.FALL_TREE);
}
String determineCorrectAnimation(){
switch(state){
case ACTIVE:
return animationFall;
case INACTIVE:
return animationLand;
default:
return animationLand;
}
}
public void setServerJumpTree(ServerJumpTree jumpTree){
this.jumpTree = jumpTree;
}
public void setAnimationFall(String animationName){
animationFall = animationName;
}
public void setAnimationLand(String animationName){
animationLand = animationName;
}
}

View File

@ -0,0 +1,672 @@
package electrosphere.entity.state.movement;
import electrosphere.entity.state.collidable.Impulse;
import electrosphere.entity.state.gravity.GravityTree;
import electrosphere.entity.state.gravity.GravityUtils;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.dynamics.RigidBody;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.entity.types.camera.CameraEntityUtils;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.attack.ServerAttackTree;
import electrosphere.entity.state.attack.ServerAttackTree.AttackTreeState;
import electrosphere.entity.state.movement.ServerSprintTree.SprintTreeState;
import electrosphere.game.collision.CollisionEngine;
import electrosphere.game.collision.PhysicsUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.net.NetUtils;
import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.renderer.anim.Animation;
import electrosphere.server.datacell.utils.DataCellSearchUtils;
import electrosphere.server.poseactor.PoseActor;
import electrosphere.renderer.Model;
import electrosphere.renderer.actor.Actor;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
/*
Behavior tree for movement in an entity
*/
public class ServerGroundMovementTree implements BehaviorTree {
public static enum MovementTreeState {
STARTUP,
MOVE,
SLOWDOWN,
IDLE,
}
public static enum MovementRelativeFacing {
FORWARD,
LEFT,
RIGHT,
BACKWARD,
FORWARD_LEFT,
FORWARD_RIGHT,
BACKWARD_LEFT,
BACKWARD_RIGHT,
}
static final double STATE_DIFFERENCE_HARD_UPDATE_THRESHOLD = 1.0;
static final double STATE_DIFFERENCE_SOFT_UPDATE_THRESHOLD = 0.2;
static final double SOFT_UPDATE_MULTIPLIER = 0.1;
String animationStartUp = Animation.ANIMATION_MOVEMENT_STARTUP;
String animationMain = Animation.ANIMATION_MOVEMENT_MOVE;
String animationSlowDown = Animation.ANIMATION_MOVEMENT_MOVE;
String animationSprintStart = Animation.ANIMATION_SPRINT_STARTUP;
String animationSprint = Animation.ANIMATION_SPRINT;
String animationSprintWindDown = Animation.ANIMATION_SPRINT_WINDDOWN;
MovementTreeState state;
MovementRelativeFacing facing;
ServerSprintTree sprintTree;
ServerJumpTree jumpTree;
ServerFallTree fallTree;
Entity parent;
Collidable collidable;
CopyOnWriteArrayList<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList<EntityMessage>();
long lastUpdateTime = 0;
public ServerGroundMovementTree(Entity e, Collidable collidable){
state = MovementTreeState.IDLE;
facing = MovementRelativeFacing.FORWARD;
parent = e;
this.collidable = collidable;
}
public MovementTreeState getState(){
return state;
}
public void start(MovementRelativeFacing facing){
if(canStartMoving()){
this.facing = facing;
state = MovementTreeState.STARTUP;
//if we aren't the server, alert the server we intend to walk forward
if(!Globals.RUN_SERVER){
Vector3d position = EntityUtils.getPosition(parent);
Quaternionf rotation = EntityUtils.getRotation(parent);
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
float velocity = CreatureUtils.getVelocity(parent);
Globals.clientConnection.queueOutgoingMessage(
EntityMessage.constructmoveUpdateMessage(
parent.getId(),
Main.getCurrentFrame(),
position.x,
position.y,
position.z,
rotation.x,
rotation.y,
rotation.z,
rotation.w,
velocity,
0 //magic number corresponding to state startup
)
);
}
}
}
public void interrupt(){
state = MovementTreeState.IDLE;
CreatureUtils.setVelocity(parent, 0);
}
public void slowdown(){
state = MovementTreeState.SLOWDOWN;
//if we aren't the server, alert the server we intend to slow down
if(!Globals.RUN_SERVER){
Vector3d position = EntityUtils.getPosition(parent);
Quaternionf rotation = EntityUtils.getRotation(parent);
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
float velocity = CreatureUtils.getVelocity(parent);
Globals.clientConnection.queueOutgoingMessage(
EntityMessage.constructmoveUpdateMessage(
parent.getId(),
Main.getCurrentFrame(),
position.x,
position.y,
position.z,
rotation.x,
rotation.y,
rotation.z,
rotation.w,
velocity,
2 //magic number corresponding to state slowdown
)
);
}
}
public void simulate(float deltaTime){
float velocity = CreatureUtils.getVelocity(parent);
float acceleration = CreatureUtils.getAcceleration(parent);
float maxNaturalVelocity = sprintTree != null && sprintTree.state == SprintTreeState.SPRINTING ? sprintTree.maxVelocity : CreatureUtils.getMaxNaturalVelocity(parent);
PoseActor entityPoseActor = EntityUtils.getPoseActor(parent);
// Model entityModel = Globals.assetManager.fetchModel(EntityUtils.getEntityModelPath(parent));
Vector3d position = EntityUtils.getPosition(parent);
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
Vector3d movementVector = new Vector3d(facingVector);
switch(facing){
case FORWARD:
movementVector.normalize();
break;
case LEFT:
movementVector.rotateY((float)(90 * Math.PI / 180)).normalize();
break;
case RIGHT:
movementVector.rotateY((float)(-90 * Math.PI / 180)).normalize();
break;
case BACKWARD:
movementVector.x = -movementVector.x;
movementVector.z = -movementVector.z;
movementVector.normalize();
break;
case FORWARD_LEFT:
movementVector.rotateY((float)(45 * Math.PI / 180)).normalize();
break;
case FORWARD_RIGHT:
movementVector.rotateY((float)(-45 * Math.PI / 180)).normalize();
break;
case BACKWARD_LEFT:
movementVector.rotateY((float)(135 * Math.PI / 180)).normalize();
break;
case BACKWARD_RIGHT:
movementVector.rotateY((float)(-135 * Math.PI / 180)).normalize();
break;
}
// float movementYaw = CameraEntityUtils.getCameraYaw(Globals.playerCamera);
Quaternionf movementQuaternion = new Quaternionf().rotationTo(new Vector3f(0,0,1), new Vector3f((float)facingVector.x,0,(float)facingVector.z)).normalize();
Quaternionf rotation = EntityUtils.getRotation(parent);
//parse attached network messages
for(EntityMessage message : networkMessageQueue){
networkMessageQueue.remove(message);
long updateTime = message.gettime();
// System.out.println("MOVE to " + message.getX() + " " + message.getY() + " " + message.getZ());
switch(message.getMessageSubtype()){
case MOVE:
break;
case SETFACING:
break;
case MOVEUPDATE:
if(updateTime > lastUpdateTime){
lastUpdateTime = updateTime;
switch(message.gettreeState()){
case 0:
state = MovementTreeState.STARTUP;
// System.out.println("Set state STARTUP");
GravityUtils.serverAttemptActivateGravity(parent);
break;
case 1:
state = MovementTreeState.MOVE;
// System.out.println("Set state MOVE");
GravityUtils.serverAttemptActivateGravity(parent);
break;
case 2:
state = MovementTreeState.SLOWDOWN;
// System.out.println("Set state SLOWDOWN");
GravityUtils.serverAttemptActivateGravity(parent);
break;
case 3:
state = MovementTreeState.IDLE;
// System.out.println("Set state IDLE");
break;
}
//we want to always update the server facing vector with where the client says they're facing
CreatureUtils.setFacingVector(parent, new Vector3d(message.getrotationX(),message.getrotationY(),message.getrotationZ()));
break;
}
break;
default:
break;
}
}
// System.out.println(movementVector + " " + velocity * Main.deltaTime);
//state machine
switch(state){
case STARTUP:
if(entityPoseActor != null){
String animationToPlay = determineCorrectAnimation();
if(
!entityPoseActor.isPlayingAnimation() || !entityPoseActor.isPlayingAnimation(animationToPlay) &&
(jumpTree == null || !jumpTree.isJumping()) &&
(fallTree == null || !fallTree.isFalling())
){
entityPoseActor.playAnimation(animationToPlay,1);
entityPoseActor.incrementAnimationTime(0.0001);
}
}
//run startup code
velocity = velocity + acceleration * Main.deltaFrames;
//check if can transition state
if(velocity >= maxNaturalVelocity){
velocity = maxNaturalVelocity;
state = MovementTreeState.MOVE;
}
CreatureUtils.setVelocity(parent, velocity);
// body.applyCentralForce(PhysicsUtils.jomlToVecmathVector3f(new Vector3f(movementVector.x,0,movementVector.z).normalize().mul(velocity)));
// EntityUtils.getRotation(parent).set(movementQuaternion);
// //move the entity
// newPosition = new Vector3d(position).add(new Vector3d(movementVector).mul(velocity).mul(Main.deltaTime));
// //check/update if collision
// if(!Globals.collisionEngine.checkCanOccupyPosition(Globals.commonWorldData, parent, newPosition)){
// newPosition = Globals.collisionEngine.suggestMovementPosition(Globals.commonWorldData, parent, newPosition);
// }
// //actually update
collidable.addImpulse(new Impulse(new Vector3d(movementVector), new Vector3d(0,0,0), new Vector3d(0,0,0), velocity * Main.deltaFrames, "movement"));
// position.set(newPosition);
rotation.set(movementQuaternion);
GravityUtils.serverAttemptActivateGravity(parent);
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
EntityMessage.constructmoveUpdateMessage(
parent.getId(),
Main.getCurrentFrame(),
position.x,
position.y,
position.z,
rotation.x,
rotation.y,
rotation.z,
rotation.w,
velocity,
0
)
);
break;
case MOVE:
//check if can restart animation
//if yes, restart animation
if(entityPoseActor != null){
String animationToPlay = determineCorrectAnimation();
if(
!entityPoseActor.isPlayingAnimation() || !entityPoseActor.isPlayingAnimation(animationToPlay) &&
(jumpTree == null || !jumpTree.isJumping()) &&
(fallTree == null || !fallTree.isFalling())
){
entityPoseActor.playAnimation(animationToPlay,1);
entityPoseActor.incrementAnimationTime(0.0001);
}
}
if(velocity != maxNaturalVelocity){
velocity = maxNaturalVelocity;
CreatureUtils.setVelocity(parent, velocity);
}
// body.applyCentralForce(PhysicsUtils.jomlToVecmathVector3f(force));
// EntityUtils.getRotation(parent).set(movementQuaternion);
//check if can move forward (collision engine)
//if can, move forward by entity movement stats
// newPosition = new Vector3d(position).add(new Vector3d(movementVector).mul(velocity).mul(Main.deltaTime));
// if(!Globals.collisionEngine.checkCanOccupyPosition(Globals.commonWorldData, parent, newPosition)){
// newPosition = Globals.collisionEngine.suggestMovementPosition(Globals.commonWorldData, parent, newPosition);
// }
collidable.addImpulse(new Impulse(new Vector3d(movementVector), new Vector3d(0,0,0), new Vector3d(0,0,0), velocity * Main.deltaFrames, "movement"));
// position.set(newPosition);
rotation.set(movementQuaternion);
GravityUtils.serverAttemptActivateGravity(parent);
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
EntityMessage.constructmoveUpdateMessage(
parent.getId(),
Main.getCurrentFrame(),
position.x,
position.y,
position.z,
rotation.x,
rotation.y,
rotation.z,
rotation.w,
velocity,
1
)
);
break;
case SLOWDOWN:
//run slowdown code
if(entityPoseActor != null){
String animationToPlay = determineCorrectAnimation();
if(
!entityPoseActor.isPlayingAnimation() || !entityPoseActor.isPlayingAnimation(animationToPlay) &&
(jumpTree == null || !jumpTree.isJumping()) &&
(fallTree == null || !fallTree.isFalling())
){
entityPoseActor.playAnimation(animationToPlay,1);
entityPoseActor.incrementAnimationTime(0.0001);
}
}
//velocity stuff
velocity = velocity - acceleration * Main.deltaFrames;
//check if can transition state
if(velocity <= 0){
velocity = 0;
state = MovementTreeState.IDLE;
if(entityPoseActor != null){
String animationToPlay = determineCorrectAnimation();
if(entityPoseActor.isPlayingAnimation() && entityPoseActor.isPlayingAnimation(animationToPlay)){
entityPoseActor.stopAnimation(animationToPlay);
}
}
}
CreatureUtils.setVelocity(parent, velocity);
// body.applyCentralForce(PhysicsUtils.jomlToVecmathVector3f(new Vector3f(movementVector).mul(-1.0f).normalize().mul(velocity)));
// EntityUtils.getRotation(parent).rotationTo(new Vector3f(0,0,1), new Vector3f((float)movementVector.x,(float)movementVector.y,(float)movementVector.z));
//move the entity
// newPosition = new Vector3d(position).add(new Vector3d(movementVector).mul(velocity).mul(Main.deltaTime));
// if(!Globals.collisionEngine.checkCanOccupyPosition(Globals.commonWorldData, parent, newPosition)){
// newPosition = Globals.collisionEngine.suggestMovementPosition(Globals.commonWorldData, parent, newPosition);
// }
collidable.addImpulse(new Impulse(new Vector3d(movementVector), new Vector3d(0,0,0), new Vector3d(0,0,0), velocity * Main.deltaFrames, "movement"));
// position.set(newPosition);
rotation.set(movementQuaternion);
GravityUtils.serverAttemptActivateGravity(parent);
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
EntityMessage.constructmoveUpdateMessage(
parent.getId(),
Main.getCurrentFrame(),
position.x,
position.y,
position.z,
rotation.x,
rotation.y,
rotation.z,
rotation.w,
velocity,
2
)
);
break;
case IDLE:
// body.clearForces();
// if(Globals.collisionEngine.gravityCheck(Globals.commonWorldData, parent)){
// position.set(Globals.collisionEngine.suggestMovementPosition(Globals.commonWorldData,parent,new Vector3f(position.x,position.y - 9.8f,position.z)));
// }
// position.set(new Vector3f(position.x,position.y - 0.08f,position.z));
// bodyTransformMatrix = new javax.vecmath.Matrix4f(PhysicsUtils.jomlToVecmathQuaternionf(rotation),PhysicsUtils.jomlToVecmathVector3f(position),1.0f);
// body.setWorldTransform(new com.bulletphysics.linearmath.Transform(bodyTransformMatrix));
break;
}
}
public void addNetworkMessage(EntityMessage networkMessage) {
networkMessageQueue.add(networkMessage);
}
public boolean canStartMoving(){
boolean rVal = true;
if(parent.containsKey(EntityDataStrings.SERVER_ATTACK_TREE) && ((ServerAttackTree)parent.getData(EntityDataStrings.SERVER_ATTACK_TREE)).getState() != AttackTreeState.IDLE){
rVal = false;
}
return rVal;
}
public void setAnimationStartUp(String animationStartUp) {
this.animationStartUp = animationStartUp;
}
public void setAnimationMain(String animationMain) {
this.animationMain = animationMain;
}
public void setAnimationSlowDown(String animationSlowDown) {
this.animationSlowDown = animationSlowDown;
}
public void setAnimationSprintStartUp(String animationSprintStartUp){
this.animationSprintStart = animationSprintStartUp;
}
public void setAnimationSprint(String animationSprint){
this.animationSprint = animationSprint;
}
public void setAnimationSprintWindDown(String animationSprintWindDown){
this.animationSprintWindDown = animationSprintWindDown;
}
public void setServerSprintTree(ServerSprintTree sprintTree){
this.sprintTree = sprintTree;
}
public void setServerJumpTree(ServerJumpTree jumpTree){
this.jumpTree = jumpTree;
}
public void setServerFallTree(ServerFallTree fallTree){
this.fallTree = fallTree;
}
public MovementRelativeFacing getFacing(){
return facing;
}
public String determineCorrectAnimation(){
String rVal = "";
if(sprintTree != null){
switch(sprintTree.state){
case SPRINTING:
switch(state){
case IDLE:
break;
case STARTUP:
rVal = animationSprintStart;
break;
case MOVE:
rVal = animationSprint;
break;
case SLOWDOWN:
rVal = animationSprintWindDown;
break;
}
break;
case NOT_SPRINTING:
switch(state){
case IDLE:
break;
case STARTUP:
switch(facing){
case FORWARD:
rVal = animationStartUp;
break;
case BACKWARD:
rVal = animationStartUp;
break;
case LEFT:
rVal = Animation.ANIMATION_WALK_LEFT;
break;
case RIGHT:
rVal = Animation.ANIMATION_WALK_RIGHT;
break;
case FORWARD_LEFT:
rVal = Animation.ANIMATION_WALK_LEFT;
break;
case FORWARD_RIGHT:
rVal = Animation.ANIMATION_WALK_RIGHT;
break;
case BACKWARD_LEFT:
rVal = Animation.ANIMATION_WALK_LEFT;
break;
case BACKWARD_RIGHT:
rVal = Animation.ANIMATION_WALK_RIGHT;
break;
}
break;
case MOVE:
switch(facing){
case FORWARD:
rVal = animationMain;
break;
case BACKWARD:
rVal = animationMain;
break;
case LEFT:
rVal = Animation.ANIMATION_WALK_LEFT;
break;
case RIGHT:
rVal = Animation.ANIMATION_WALK_RIGHT;
break;
case FORWARD_LEFT:
rVal = Animation.ANIMATION_WALK_LEFT;
break;
case FORWARD_RIGHT:
rVal = Animation.ANIMATION_WALK_RIGHT;
break;
case BACKWARD_LEFT:
rVal = Animation.ANIMATION_WALK_LEFT;
break;
case BACKWARD_RIGHT:
rVal = Animation.ANIMATION_WALK_RIGHT;
break;
}
break;
case SLOWDOWN:
switch(facing){
case FORWARD:
rVal = animationSlowDown;
break;
case BACKWARD:
rVal = animationSlowDown;
break;
case LEFT:
rVal = Animation.ANIMATION_WALK_LEFT;
break;
case RIGHT:
rVal = Animation.ANIMATION_WALK_RIGHT;
break;
case FORWARD_LEFT:
rVal = Animation.ANIMATION_WALK_LEFT;
break;
case FORWARD_RIGHT:
rVal = Animation.ANIMATION_WALK_RIGHT;
break;
case BACKWARD_LEFT:
rVal = Animation.ANIMATION_WALK_LEFT;
break;
case BACKWARD_RIGHT:
rVal = Animation.ANIMATION_WALK_RIGHT;
break;
}
break;
}
break;
}
} else {
switch(state){
case IDLE:
break;
case STARTUP:
switch(facing){
case FORWARD:
rVal = animationStartUp;
break;
case BACKWARD:
rVal = animationStartUp;
break;
case LEFT:
rVal = Animation.ANIMATION_WALK_LEFT;
break;
case RIGHT:
rVal = Animation.ANIMATION_WALK_RIGHT;
break;
case FORWARD_LEFT:
rVal = Animation.ANIMATION_WALK_LEFT;
break;
case FORWARD_RIGHT:
rVal = Animation.ANIMATION_WALK_RIGHT;
break;
case BACKWARD_LEFT:
rVal = Animation.ANIMATION_WALK_LEFT;
break;
case BACKWARD_RIGHT:
rVal = Animation.ANIMATION_WALK_RIGHT;
break;
}
break;
case MOVE:
switch(facing){
case FORWARD:
rVal = animationMain;
break;
case BACKWARD:
rVal = animationMain;
break;
case LEFT:
rVal = Animation.ANIMATION_WALK_LEFT;
break;
case RIGHT:
rVal = Animation.ANIMATION_WALK_RIGHT;
break;
case FORWARD_LEFT:
rVal = Animation.ANIMATION_WALK_LEFT;
break;
case FORWARD_RIGHT:
rVal = Animation.ANIMATION_WALK_RIGHT;
break;
case BACKWARD_LEFT:
rVal = Animation.ANIMATION_WALK_LEFT;
break;
case BACKWARD_RIGHT:
rVal = Animation.ANIMATION_WALK_RIGHT;
break;
}
break;
case SLOWDOWN:
switch(facing){
case FORWARD:
rVal = animationSlowDown;
break;
case BACKWARD:
rVal = animationSlowDown;
break;
case LEFT:
rVal = Animation.ANIMATION_WALK_LEFT;
break;
case RIGHT:
rVal = Animation.ANIMATION_WALK_RIGHT;
break;
case FORWARD_LEFT:
rVal = Animation.ANIMATION_WALK_LEFT;
break;
case FORWARD_RIGHT:
rVal = Animation.ANIMATION_WALK_RIGHT;
break;
case BACKWARD_LEFT:
rVal = Animation.ANIMATION_WALK_LEFT;
break;
case BACKWARD_RIGHT:
rVal = Animation.ANIMATION_WALK_RIGHT;
break;
}
break;
}
}
return rVal;
}
}

View File

@ -0,0 +1,102 @@
package electrosphere.entity.state.movement;
import org.joml.Vector3d;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.collidable.Impulse;
import electrosphere.entity.state.gravity.GravityUtils;
import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.renderer.actor.Actor;
public class ServerJumpTree implements BehaviorTree {
static enum JumpState {
INACTIVE,
ACTIVE,
AWAITING_LAND,
}
JumpState state = JumpState.INACTIVE;
String animationJump = "Armature|Jump";
Entity parent;
int jumpFrames = 0;
int currentFrame = 0;
float jumpForce = 10.0f;
float currentJumpForce = jumpForce;
static final float jumpFalloff = 0.99f;
public ServerJumpTree(Entity parent, int jumpFrames, float jumpForce){
this.parent = parent;
this.jumpFrames = jumpFrames;
this.jumpForce = jumpForce;
}
public void start(){
if(state == JumpState.INACTIVE){
state = JumpState.ACTIVE;
currentFrame = 0;
currentJumpForce = jumpForce;
GravityUtils.serverAttemptActivateGravity(parent);
}
}
@Override
public void simulate(float deltaTime) {
Actor entityActor = EntityUtils.getActor(parent);
switch(state){
case ACTIVE:
if(entityActor != null){
String animationToPlay = determineCorrectAnimation();
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationToPlay)){
entityActor.playAnimation(animationToPlay,1);
entityActor.incrementAnimationTime(0.0001);
}
}
currentFrame++;
currentJumpForce = currentJumpForce * jumpFalloff;
//push parent up
CollisionObjUtils.getCollidable(parent).addImpulse(new Impulse(new Vector3d(0,1,0), new Vector3d(0,0,0), new Vector3d(EntityUtils.getPosition(parent)), currentJumpForce, Collidable.TYPE_FORCE));
//potentially disable
if(currentFrame >= jumpFrames){
state = JumpState.AWAITING_LAND;
GravityUtils.serverAttemptActivateGravity(parent);
}
break;
case INACTIVE:
break;
case AWAITING_LAND:
break;
}
}
public static ServerJumpTree getServerJumpTree(Entity parent){
return (ServerJumpTree)parent.getData(EntityDataStrings.SERVER_JUMP_TREE);
}
public void land(){
if(state != JumpState.INACTIVE && currentFrame > 2){
state = JumpState.INACTIVE;
}
}
public boolean isJumping(){
return state == JumpState.ACTIVE;
}
String determineCorrectAnimation(){
return animationJump;
}
public void setAnimationJump(String animationName){
animationJump = animationName;
}
}

View File

@ -0,0 +1,76 @@
package electrosphere.entity.state.movement;
import electrosphere.engine.Main;
import electrosphere.entity.Entity;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.movement.ServerGroundMovementTree.MovementTreeState;
/**
*
* @author amaterasu
*/
public class ServerSprintTree implements BehaviorTree {
public static enum SprintTreeState {
SPRINTING,
NOT_SPRINTING,
}
SprintTreeState state;
ServerGroundMovementTree groundMovementTree;
Entity parent;
int staminaCurrent = 0;
int staminaMax = 1;
float maxVelocity;
public ServerSprintTree(Entity e, float maxVelocity, int staminaMax){
state = SprintTreeState.NOT_SPRINTING;
parent = e;
this.maxVelocity = maxVelocity;
this.staminaMax = staminaMax;
}
public SprintTreeState getState(){
return state;
}
public void start(){
if(staminaCurrent > 0){
// System.out.println("Starting sprinting");
state = SprintTreeState.SPRINTING;
}
}
public void stop(){
state = SprintTreeState.NOT_SPRINTING;
}
@Override
public void simulate(float deltaTime){
switch(state){
case SPRINTING:
if(groundMovementTree != null && groundMovementTree.getState() != MovementTreeState.IDLE){
staminaCurrent--;
if(staminaCurrent < 1){
state = SprintTreeState.NOT_SPRINTING;
}
}
break;
case NOT_SPRINTING:
staminaCurrent++;
if(staminaCurrent > staminaMax){
staminaCurrent = staminaMax;
}
break;
}
}
public void setServerGroundMovementTree(ServerGroundMovementTree groundMovementTree){
this.groundMovementTree = groundMovementTree;
}
}

View File

@ -109,8 +109,8 @@ public class RotatorTree implements BehaviorTree{
return (float)Math.asin(-2.0*(quat.x*quat.z - quat.w*quat.y));
}
public static RotatorTree getRotatorTree(Entity parent){
return (RotatorTree)parent.getData(EntityDataStrings.ROTATOR_TREE);
public static RotatorTree getClientRotatorTree(Entity parent){
return (RotatorTree)parent.getData(EntityDataStrings.CLIENT_ROTATOR_TREE);
}
}

View File

@ -0,0 +1,117 @@
package electrosphere.entity.state.rotator;
import java.util.LinkedList;
import java.util.List;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.view.ViewUtils;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.actor.ActorBoneRotator;
import electrosphere.server.poseactor.PoseActor;
public class ServerRotatorTree implements BehaviorTree{
public static enum RotatorTreeState {
ACTIVE,
INACTIVE,
}
RotatorTreeState state;
Entity parent;
PoseActor entityPoseActor;
List<RotatorHierarchyNode> nodes = new LinkedList<RotatorHierarchyNode>();
public ServerRotatorTree(Entity parent){
this.parent = parent;
entityPoseActor = EntityUtils.getPoseActor(parent);
state = RotatorTreeState.INACTIVE;
}
public void setActive(boolean isActive){
if(isActive){
state = RotatorTreeState.ACTIVE;
} else {
state = RotatorTreeState.INACTIVE;
//clear all modifications we've made up to this point
for(RotatorHierarchyNode node : nodes){
entityPoseActor.getBoneRotator(node.getBone()).getRotation().identity();
}
}
}
public void simulate(float deltaTime){
if(entityPoseActor.modelIsLoaded() && this.state == RotatorTreeState.ACTIVE){
for(RotatorHierarchyNode node : nodes){
applyRotatorNode(node);
}
}
}
public void applyRotatorNode(RotatorHierarchyNode node){
//apply
String nodeBoneName = node.getBone();
Quaternionf currentRotation = entityPoseActor.getBoneRotation(nodeBoneName);
for(RotatorConstraint constraint : node.getRotatorContraints()){
float allowedMarginPitch = constraint.getAllowedMarginPitch();
float allowedMarginYaw = constraint.getAllowedMarginYaw();
boolean followsBone = constraint.getFollowsBone();
boolean followsView = constraint.getFollowsView();
if(followsBone){
String parentBone = constraint.getParentBone();
Quaternionf parentBoneRotation = entityPoseActor.getBoneRotation(parentBone);
// currentRotation.
}
if(followsView){
ActorBoneRotator currentRotator = entityPoseActor.getBoneRotator(node.getBone());
//apparently this isn't needed?
//not sure I understand the math on this one
// Vector3d facingVector = CreatureUtils.getFacingVector(parent);
// Vector3f rotationAxis = new Vector3f((float)facingVector.x,(float)facingVector.y,(float)facingVector.z).rotateY((float)Math.PI/2.0f).normalize();
Vector3f rotationAxis = new Vector3f(1,0,0);
float rotationRaw = 0.0f;
if(parent == Globals.playerEntity){
rotationRaw = Globals.cameraHandler.getPitch();
} else {
rotationRaw = ViewUtils.getPitch(parent);
}
float rotation = (float)(rotationRaw * Math.PI / 180.0f);
if(Math.abs(rotation) > constraint.getAllowedMarginPitch()){
rotation = (float)Math.copySign(constraint.allowedMarginPitch, rotation);
}
currentRotator.getRotation().identity().rotationAxis(rotation, rotationAxis);
}
}
//recurse to children
// for(RotatorHierarchyNode child : node.getChildren()){
// applyRotatorNode(child);
// }
}
public void addRotatorNode(RotatorHierarchyNode node){
nodes.add(node);
}
public float calculateYawOfQuat(Quaternionf quat){
return (float)Math.atan2(2.0*(quat.y*quat.z + quat.w*quat.x), quat.w*quat.w - quat.x*quat.x - quat.y*quat.y + quat.z*quat.z);
}
public float calculatePitchOfQuat(Quaternionf quat){
return (float)Math.asin(-2.0*(quat.x*quat.z - quat.w*quat.y));
}
public static ServerRotatorTree getServerRotatorTree(Entity parent){
return (ServerRotatorTree)parent.getData(EntityDataStrings.SERVER_ROTATOR_TREE);
}
}

View File

@ -8,6 +8,8 @@ import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.renderer.Model;
import electrosphere.renderer.actor.Actor;
import electrosphere.server.datacell.ServerDataCell;
import electrosphere.server.datacell.utils.ServerEntityTagUtils;
import java.util.LinkedList;
import java.util.List;
@ -24,8 +26,24 @@ import org.joml.Vector3f;
public class AttachUtils {
public static void attachEntityToEntityAtBone(Entity parent, Entity toAttach, String boneName, Quaternionf rotation){
Globals.entityManager.registerEntityToTag(toAttach, EntityTags.BONE_ATTACHED);
public static void serverAttachEntityToEntityAtBone(Entity parent, Entity toAttach, String boneName, Quaternionf rotation){
ServerEntityTagUtils.attachTagToEntity(toAttach, EntityTags.BONE_ATTACHED);
toAttach.putData(EntityDataStrings.ATTACH_ENTITY_IS_ATTACHED, true);
toAttach.putData(EntityDataStrings.ATTACH_PARENT, parent);
toAttach.putData(EntityDataStrings.ATTACH_TARGET_BONE, boneName);
toAttach.putData(EntityDataStrings.ATTACH_ROTATION_OFFSET, rotation);
if(parent.containsKey(EntityDataStrings.ATTACH_CHILDREN_LIST)){
getChildrenList(parent).add(toAttach);
} else {
LinkedList<Entity> childrenEntities = new LinkedList<Entity> ();
childrenEntities.add(toAttach);
parent.putData(EntityDataStrings.ATTACH_CHILDREN_LIST, childrenEntities);
}
}
public static void clientAttachEntityToEntityAtBone(Entity parent, Entity toAttach, String boneName, Quaternionf rotation){
Globals.clientSceneWrapper.getScene().registerEntityToTag(toAttach, EntityTags.BONE_ATTACHED);
toAttach.putData(EntityDataStrings.ATTACH_ENTITY_IS_ATTACHED, true);
toAttach.putData(EntityDataStrings.ATTACH_PARENT, parent);
toAttach.putData(EntityDataStrings.ATTACH_TARGET_BONE, boneName);
@ -39,8 +57,41 @@ public class AttachUtils {
}
}
public static void updateAttachedEntityPositions(){
for(Entity currentEntity : Globals.entityManager.getEntitiesWithTag(EntityTags.BONE_ATTACHED)){
public static void serverUpdateAttachedEntityPositions(ServerDataCell cell){
for(Entity currentEntity : cell.getScene().getEntitiesWithTag(EntityTags.BONE_ATTACHED)){
Entity parent;
if((parent = (Entity)currentEntity.getData(EntityDataStrings.ATTACH_PARENT))!=null){
String targetBone;
if((targetBone = (String)currentEntity.getData(EntityDataStrings.ATTACH_TARGET_BONE))!=null){
Actor parentActor = EntityUtils.getActor(parent);
//get offset rotation
Quaternionf offsetRotation = getRotationOffset(currentEntity);
//transform bone space
Vector3d position = new Vector3d(parentActor.getBonePosition(targetBone));
position = position.mul(((Vector3f)EntityUtils.getScale(parent)));
Quaternionf rotation = EntityUtils.getRotation(parent);
position = position.rotate(new Quaterniond(rotation.x,rotation.y,rotation.z,rotation.w));
//transform worldspace
position.add(new Vector3d(EntityUtils.getPosition(parent)));
//set
EntityUtils.getPosition(currentEntity).set(position);
//set rotation
// Quaternionf rotation = parentActor.getBoneRotation(targetBone);
// EntityUtils.getRotation(currentEntity).set(rotation).normalize();
Vector3d facingAngle = CreatureUtils.getFacingVector(parent);
//calculate rotation of model
EntityUtils.getRotation(currentEntity)
.rotationTo(new Vector3f(0,0,1), new Vector3f((float)facingAngle.x,(float)facingAngle.y,(float)facingAngle.z))
.mul(parentActor.getBoneRotation(targetBone))
.mul(offsetRotation)
.normalize();
}
}
}
}
public static void clientUpdateAttachedEntityPositions(){
for(Entity currentEntity : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.BONE_ATTACHED)){
Entity parent;
if((parent = (Entity)currentEntity.getData(EntityDataStrings.ATTACH_PARENT))!=null){
String targetBone;
@ -72,8 +123,18 @@ public class AttachUtils {
}
}
public static void detatchEntityFromEntityAtBone(Entity parent, Entity toAttach){
Globals.entityManager.registerEntityToTag(toAttach, EntityTags.BONE_ATTACHED);
public static void serverDetatchEntityFromEntityAtBone(Entity parent, Entity toAttach){
ServerEntityTagUtils.removeTagFromEntity(toAttach, EntityTags.BONE_ATTACHED);
toAttach.removeData(EntityDataStrings.ATTACH_ENTITY_IS_ATTACHED);
toAttach.removeData(EntityDataStrings.ATTACH_PARENT);
toAttach.removeData(EntityDataStrings.ATTACH_TARGET_BONE);
if(parent.containsKey(EntityDataStrings.ATTACH_CHILDREN_LIST)){
getChildrenList(parent).remove(toAttach);
}
}
public static void clientDetatchEntityFromEntityAtBone(Entity parent, Entity toAttach){
Globals.clientSceneWrapper.getScene().removeEntityFromTag(toAttach, EntityTags.BONE_ATTACHED);
toAttach.removeData(EntityDataStrings.ATTACH_ENTITY_IS_ATTACHED);
toAttach.removeData(EntityDataStrings.ATTACH_PARENT);
toAttach.removeData(EntityDataStrings.ATTACH_TARGET_BONE);

View File

@ -2,6 +2,7 @@ package electrosphere.entity.types.camera;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.BehaviorTree;
@ -19,8 +20,7 @@ public class CameraEntityUtils {
public static Entity spawnBasicCameraEntity(Vector3f center, Vector3f eye){
Entity rVal = new Entity();
Globals.entityManager.registerEntity(rVal);
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
rVal.putData(EntityDataStrings.DATA_STRING_CAMERA_TYPE, EntityDataStrings.DATA_STRING_CAMERA_TYPE_BASIC);
rVal.putData(EntityDataStrings.DATA_STRING_CAMERA_CENTER, center);
rVal.putData(EntityDataStrings .DATA_STRING_CAMERA_EYE, eye);
@ -32,8 +32,7 @@ public class CameraEntityUtils {
}
public static Entity spawnEntityTrackingCameraEntity(Vector3f center, Vector3f eye, Entity toTrack){
Entity rVal = new Entity();
Globals.entityManager.registerEntity(rVal);
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
rVal.putData(EntityDataStrings.DATA_STRING_CAMERA_TYPE, EntityDataStrings.DATA_STRING_CAMERA_TYPE_ORBIT);
rVal.putData(EntityDataStrings.DATA_STRING_CAMERA_CENTER, center);
rVal.putData(EntityDataStrings.DATA_STRING_CAMERA_EYE, eye);
@ -50,13 +49,12 @@ public class CameraEntityUtils {
}
}
};
Globals.entityManager.registerBehaviorTree(entityTrackingTree);
Globals.clientScene.registerBehaviorTree(entityTrackingTree);
return rVal;
}
public static Entity spawnPlayerEntityTrackingCameraEntity(Vector3f center, Vector3f eye){
Entity rVal = new Entity();
Globals.entityManager.registerEntity(rVal);
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
rVal.putData(EntityDataStrings.DATA_STRING_CAMERA_TYPE, EntityDataStrings.DATA_STRING_CAMERA_TYPE_ORBIT);
rVal.putData(EntityDataStrings.DATA_STRING_CAMERA_CENTER, center);
rVal.putData(EntityDataStrings.DATA_STRING_CAMERA_EYE, eye);
@ -73,13 +71,12 @@ public class CameraEntityUtils {
}
}
};
Globals.entityManager.registerBehaviorTree(entityTrackingTree);
Globals.clientScene.registerBehaviorTree(entityTrackingTree);
return rVal;
}
public static Entity spawnPlayerEntityAirplaneTrackingCameraEntity(Vector3f center, Vector3f eye){
Entity rVal = new Entity();
Globals.entityManager.registerEntity(rVal);
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
rVal.putData(EntityDataStrings.DATA_STRING_CAMERA_TYPE, EntityDataStrings.DATA_STRING_CAMERA_TYPE_ORBIT);
rVal.putData(EntityDataStrings.DATA_STRING_CAMERA_CENTER, center);
rVal.putData(EntityDataStrings.DATA_STRING_CAMERA_EYE, eye);
@ -96,7 +93,7 @@ public class CameraEntityUtils {
}
}
};
Globals.entityManager.registerBehaviorTree(entityTrackingTree);
Globals.clientScene.registerBehaviorTree(entityTrackingTree);
return rVal;
}
@ -154,7 +151,7 @@ public class CameraEntityUtils {
public static void destroyCameraEntity(Entity e){
if(e != null){
Globals.entityManager.deregisterEntity(e);
Globals.clientScene.deregisterEntity(e);
}
}

View File

@ -4,11 +4,13 @@ import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.collision.shapes.CylinderShape;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.attach.AttachUtils;
import electrosphere.game.collision.PhysicsUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.server.datacell.Realm;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
@ -21,8 +23,8 @@ import org.joml.Vector3f;
*/
public class CollisionObjUtils {
public static Entity spawnCollisionPlane(Vector3f scale, Vector3f position, Quaternionf rotation){
Entity rVal = new Entity();
public static Entity clientSpawnCollisionPlane(Vector3f scale, Vector3f position, Quaternionf rotation){
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
float mass = 1.0f;
@ -33,8 +35,39 @@ public class CollisionObjUtils {
1.0f);
planeObject.setWorldTransform(new electrosphere.linearmath.Transform(planeTransform));
Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
Globals.collisionEngine.registerCollisionObject(planeObject, collidable);
Globals.collisionEngine.registerStructurePhysicsEntity(rVal);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(planeObject, collidable);
Globals.clientSceneWrapper.getCollisionEngine().registerStructurePhysicsEntity(rVal);
rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_PLANE, true);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z));
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, rotation);
rVal.putData(EntityDataStrings.DATA_STRING_SCALE, scale);
rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLISION_OBJECT, planeObject);
rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLIDABLE, collidable);
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
//inertia tensor
//https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html
Matrix4f inertiaTensor = new Matrix4f().zero();
rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor);
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
return rVal;
}
public static Entity serverSpawnCollisionPlane(Realm realm, Vector3f scale, Vector3f position, Quaternionf rotation){
Entity rVal = EntityCreationUtils.createServerEntity(realm, new Vector3d(position));
float mass = 1.0f;
CollisionObject planeObject = PhysicsUtils.getPlaneObject(scale);
javax.vecmath.Matrix4f planeTransform = new javax.vecmath.Matrix4f(
PhysicsUtils.jomlToVecmathQuaternionf(rotation),
PhysicsUtils.jomlToVecmathVector3f(position),
1.0f);
planeObject.setWorldTransform(new electrosphere.linearmath.Transform(planeTransform));
Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
realm.getCollisionEngine().registerCollisionObject(planeObject, collidable);
realm.getCollisionEngine().registerStructurePhysicsEntity(rVal);
rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_PLANE, true);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z));
@ -49,13 +82,12 @@ public class CollisionObjUtils {
rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor);
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
Globals.entityManager.registerEntity(rVal);
return rVal;
}
public static Entity spawnCollisionCube(Vector3f scale, Vector3f position, Quaternionf rotation){
Entity rVal = new Entity();
public static Entity clientSpawnCollisionCube(Vector3f scale, Vector3f position, Quaternionf rotation){
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
float mass = 1.0f;
@ -66,8 +98,39 @@ public class CollisionObjUtils {
1.0f);
cubeObject.setWorldTransform(new electrosphere.linearmath.Transform(planeTransform));
Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
Globals.collisionEngine.registerCollisionObject(cubeObject, collidable);
Globals.collisionEngine.registerStructurePhysicsEntity(rVal);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(cubeObject, collidable);
Globals.clientSceneWrapper.getCollisionEngine().registerStructurePhysicsEntity(rVal);
rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_CUBE, true);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z));
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, rotation);
rVal.putData(EntityDataStrings.DATA_STRING_SCALE, scale);
rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLISION_OBJECT, cubeObject);
rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLIDABLE, collidable);
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
//inertia tensor
//https://hepweb.ucsd.edu/ph110b/110b_notes/node26.html
Matrix4f inertiaTensor = new Matrix4f().identity().scale(mass * scale.x * scale.x / 6.0f).m33(1);
rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert());
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
return rVal;
}
public static Entity serverSpawnCollisionCube(Realm realm, Vector3f scale, Vector3f position, Quaternionf rotation){
Entity rVal = EntityCreationUtils.createServerEntity(realm, new Vector3d(position));
float mass = 1.0f;
CollisionObject cubeObject = PhysicsUtils.getCubeObject(scale);
javax.vecmath.Matrix4f planeTransform = new javax.vecmath.Matrix4f(
PhysicsUtils.jomlToVecmathQuaternionf(rotation),
PhysicsUtils.jomlToVecmathVector3f(position),
1.0f);
cubeObject.setWorldTransform(new electrosphere.linearmath.Transform(planeTransform));
Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
realm.getCollisionEngine().registerCollisionObject(cubeObject, collidable);
realm.getCollisionEngine().registerStructurePhysicsEntity(rVal);
rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_CUBE, true);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z));
@ -82,12 +145,11 @@ public class CollisionObjUtils {
rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert());
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
Globals.entityManager.registerEntity(rVal);
return rVal;
}
public static Entity spawnCollisionCylinder(Vector3f scale, Vector3f position, Quaternionf rotation){
Entity rVal = new Entity();
public static Entity clientSpawnCollisionCylinder(Vector3f scale, Vector3f position, Quaternionf rotation){
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
float mass = 1.0f;
@ -98,8 +160,42 @@ public class CollisionObjUtils {
1.0f);
cubeObject.setWorldTransform(new electrosphere.linearmath.Transform(planeTransform));
Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
Globals.collisionEngine.registerCollisionObject(cubeObject, collidable);
Globals.collisionEngine.registerStructurePhysicsEntity(rVal);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(cubeObject, collidable);
Globals.clientSceneWrapper.getCollisionEngine().registerStructurePhysicsEntity(rVal);
rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_CYLINDER, true);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z));
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, rotation);
rVal.putData(EntityDataStrings.DATA_STRING_SCALE, scale);
rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLISION_OBJECT, cubeObject);
rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLIDABLE, collidable);
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
//inertia tensor
//https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html
Matrix4f inertiaTensor = new Matrix4f();
inertiaTensor.m00(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f);
inertiaTensor.m11(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f);
inertiaTensor.m22(mass * scale.x * scale.x / 2.0f);
rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert());
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
return rVal;
}
public static Entity serverSpawnCollisionCylinder(Realm realm, Vector3f scale, Vector3f position, Quaternionf rotation){
Entity rVal = EntityCreationUtils.createServerEntity(realm, new Vector3d(position));
float mass = 1.0f;
CollisionObject cubeObject = PhysicsUtils.getCylinderObject(scale);
javax.vecmath.Matrix4f planeTransform = new javax.vecmath.Matrix4f(
PhysicsUtils.jomlToVecmathQuaternionf(rotation),
PhysicsUtils.jomlToVecmathVector3f(position),
1.0f);
cubeObject.setWorldTransform(new electrosphere.linearmath.Transform(planeTransform));
Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
realm.getCollisionEngine().registerCollisionObject(cubeObject, collidable);
realm.getCollisionEngine().registerStructurePhysicsEntity(rVal);
rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_CYLINDER, true);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z));
@ -117,13 +213,28 @@ public class CollisionObjUtils {
rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert());
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
Globals.entityManager.registerEntity(rVal);
return rVal;
}
public static Entity attachCollisionPlane(Vector3f scale, Vector3f position, Quaternionf rotation, Entity parent){
Entity rVal = spawnCollisionPlane(scale, position, rotation);
public static Entity clientAttachCollisionPlane(Vector3f scale, Vector3f position, Quaternionf rotation, Entity parent){
Entity rVal = clientSpawnCollisionPlane(scale, position, rotation);
AttachUtils.attachEntityToEntity(parent, rVal);
float mass = 1.0f;
parent.putData(EntityDataStrings.PHYSICS_MASS, mass);
//inertia tensor
//https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html
Matrix4f inertiaTensor = new Matrix4f().zero();
parent.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor);
return rVal;
}
public static Entity serverAttachCollisionPlane(Vector3f scale, Vector3f position, Quaternionf rotation, Entity parent){
Realm parentRealm = Globals.realmManager.getEntityRealm(parent);
Entity rVal = serverSpawnCollisionPlane(parentRealm, scale, position, rotation);
AttachUtils.attachEntityToEntity(parent, rVal);
@ -137,8 +248,24 @@ public class CollisionObjUtils {
return rVal;
}
public static Entity attachCollisionCube(Vector3f scale, Vector3f position, Quaternionf rotation, Entity parent){
Entity rVal = spawnCollisionCube(scale, position, rotation);
public static Entity clientAttachCollisionCube(Vector3f scale, Vector3f position, Quaternionf rotation, Entity parent){
Entity rVal = clientSpawnCollisionCube(scale, position, rotation);
AttachUtils.attachEntityToEntity(parent, rVal);
float mass = 1.0f;
parent.putData(EntityDataStrings.PHYSICS_MASS, mass);
//inertia tensor
//https://hepweb.ucsd.edu/ph110b/110b_notes/node26.html
Matrix4f inertiaTensor = new Matrix4f().identity().scale(mass * scale.x * scale.x / 6.0f).m33(1);
parent.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert());
return rVal;
}
public static Entity serverAttachCollisionCube(Vector3f scale, Vector3f position, Quaternionf rotation, Entity parent){
Realm parentRealm = Globals.realmManager.getEntityRealm(parent);
Entity rVal = serverSpawnCollisionCube(parentRealm, scale, position, rotation);
AttachUtils.attachEntityToEntity(parent, rVal);
@ -152,8 +279,27 @@ public class CollisionObjUtils {
return rVal;
}
public static Entity attachCollisionCylinder(Vector3f scale, Vector3f position, Quaternionf rotation, Entity parent){
Entity rVal = spawnCollisionCylinder(scale, position, rotation);
public static Entity clientAttachCollisionCylinder(Vector3f scale, Vector3f position, Quaternionf rotation, Entity parent){
Entity rVal = clientSpawnCollisionCylinder(scale, position, rotation);
AttachUtils.attachEntityToEntity(parent, rVal);
float mass = 1.0f;
parent.putData(EntityDataStrings.PHYSICS_MASS, mass);
//inertia tensor
//https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html
Matrix4f inertiaTensor = new Matrix4f();
inertiaTensor.m00(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f);
inertiaTensor.m11(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f);
inertiaTensor.m22(mass * scale.x * scale.x / 2.0f);
parent.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert());
return rVal;
}
public static Entity serverAttachCollisionCylinder(Vector3f scale, Vector3f position, Quaternionf rotation, Entity parent){
Realm parentRealm = Globals.realmManager.getEntityRealm(parent);
Entity rVal = serverSpawnCollisionCylinder(parentRealm, scale, position, rotation);
AttachUtils.attachEntityToEntity(parent, rVal);
@ -177,13 +323,45 @@ public class CollisionObjUtils {
* @param mass The mass of the collidable
* @param collidableType The type of collidable we are attaching. For instance, "Terrain", "Creature", "Item", etc. Refer to Collidable class for options.
*/
public static void attachCollisionObjectToEntity(Entity entity, CollisionObject collisionObject, float mass, String collidableType){
public static void clientAttachCollisionObjectToEntity(Entity entity, CollisionObject collisionObject, float mass, String collidableType){
Vector3d position = EntityUtils.getPosition(entity);
Vector3f scale = EntityUtils.getScale(entity);
Collidable collidable = new Collidable(entity, collidableType);
Globals.collisionEngine.registerCollisionObject(collisionObject, collidable);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(collisionObject, collidable);
Globals.collisionEngine.registerPhysicsEntity(entity);
Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(entity);
entity.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, collisionObject);
//update world transform of collision object
positionCharacter(entity,position);
entity.putData(EntityDataStrings.COLLISION_ENTITY_COLLISION_OBJECT, collisionObject);
entity.putData(EntityDataStrings.COLLISION_ENTITY_COLLIDABLE, collidable);
entity.putData(EntityDataStrings.PHYSICS_MASS, mass);
//inertia tensor
//https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html
Matrix4f inertiaTensor = new Matrix4f();
inertiaTensor.m00(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f);
inertiaTensor.m11(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f);
inertiaTensor.m22(mass * scale.x * scale.x / 2.0f);
entity.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert());
}
/**
* Attach a collision object to a provided entity
* @param entity The entity to attach a collision object to
* @param collisionObject The jBulletF collision object to attach to the entity
* @param mass The mass of the collidable
* @param collidableType The type of collidable we are attaching. For instance, "Terrain", "Creature", "Item", etc. Refer to Collidable class for options.
*/
public static void serverAttachCollisionObjectToEntity(Entity entity, CollisionObject collisionObject, float mass, String collidableType){
Vector3d position = EntityUtils.getPosition(entity);
Vector3f scale = EntityUtils.getScale(entity);
Collidable collidable = new Collidable(entity, collidableType);
Realm realm = Globals.realmManager.getEntityRealm(entity);
realm.getCollisionEngine().registerCollisionObject(collisionObject, collidable);
realm.getCollisionEngine().registerPhysicsEntity(entity);
entity.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, collisionObject);
//update world transform of collision object

View File

@ -5,32 +5,43 @@ import electrosphere.dynamics.RigidBody;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityTags;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.Scene;
import electrosphere.entity.state.movement.AirplaneMovementTree;
import electrosphere.entity.state.movement.FallTree;
import electrosphere.entity.state.movement.GroundMovementTree;
import electrosphere.entity.state.movement.ServerGroundMovementTree;
import electrosphere.entity.state.movement.JumpTree;
import electrosphere.entity.state.movement.ServerFallTree;
import electrosphere.entity.state.movement.ServerJumpTree;
import electrosphere.entity.state.movement.ServerSprintTree;
import electrosphere.entity.types.hitbox.HitboxData;
import electrosphere.entity.types.hitbox.HitboxUtils;
import electrosphere.game.data.creature.type.CreatureType;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.IdleTree;
import electrosphere.entity.state.attack.AttackTree;
import electrosphere.entity.state.attack.ServerAttackTree;
import electrosphere.entity.state.attack.ShooterTree;
import electrosphere.entity.state.collidable.CollidableTree;
import electrosphere.entity.state.collidable.ClientCollidableTree;
import electrosphere.entity.state.collidable.ServerCollidableTree;
import electrosphere.entity.state.equip.EquipState;
import electrosphere.entity.state.gravity.GravityTree;
import electrosphere.entity.state.gravity.ServerGravityTree;
import electrosphere.entity.state.idle.IdleTree;
import electrosphere.entity.state.inventory.InventoryState;
import electrosphere.entity.state.inventory.InventoryUtils;
import electrosphere.entity.state.inventory.RelationalInventoryState;
import electrosphere.entity.state.inventory.ServerInventoryState;
import electrosphere.entity.state.inventory.UnrelationalInventoryState;
import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.entity.state.life.LifeState;
import electrosphere.entity.state.movement.SprintTree;
import electrosphere.entity.state.rotator.RotatorHierarchyNode;
import electrosphere.entity.state.rotator.RotatorTree;
import electrosphere.entity.state.rotator.ServerRotatorTree;
import electrosphere.game.collision.PhysicsUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.data.creature.type.CollidableTemplate;
@ -59,7 +70,14 @@ import electrosphere.renderer.actor.ActorStaticMorph;
import electrosphere.renderer.actor.ActorUtils;
import electrosphere.renderer.light.PointLight;
import electrosphere.renderer.loading.ModelLoader;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.ServerDataCell;
import electrosphere.server.datacell.utils.DataCellSearchUtils;
import electrosphere.server.datacell.utils.EntityLookupUtils;
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
import electrosphere.server.datacell.utils.ServerEntityTagUtils;
import electrosphere.server.poseactor.PoseActor;
import electrosphere.server.poseactor.PoseActorUtils;
import electrosphere.util.Utilities;
import java.util.LinkedList;
@ -94,21 +112,54 @@ public class CreatureUtils {
// Globals.entityManager.registerMoveableEntity(rVal);
// return rVal;
// }
// /**
// * Spawns a server-side creature entity
// * @param type The type of creature
// * @param template The creature template if applicable
// * @param realm The realm to spawn the creature in
// * @param position The position to place the creature at
// * @return The creature entity
// */
// public static Entity serverSpawnCreature(String type, CreatureTemplate template, Realm realm, Vector3d position){
// Entity rVal = EntityCreationUtils.createServerEntity(realm, position);
// spawnBasicCreature(rVal, type, template, true);
// return rVal;
// }
// /**
// * Spawns a client-side creature entity
// * @param type The type of creature
// * @param template The creature template if applicable
// * @return The creature entity
// */
// public static Entity clientSpawnCreature(String type, CreatureTemplate template){
// Entity rVal = EntityCreationUtils.createClientEntity();
// spawnBasicCreature(rVal, type, template, false);
// return rVal;
// }
public static Entity spawnBasicCreature(String type, CreatureTemplate template){
/**
* Spawns a client-side creature entity
* @param type The type of creature
* @param template The creature template if applicable
* @return The creature entity
*/
public static Entity clientSpawnBasicCreature(String type, CreatureTemplate template){
CreatureType rawType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(type);
Entity rVal = EntityUtils.spawnDrawableEntity(rawType.getModelPath());
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(rVal, rawType.getModelPath());
Actor creatureActor = EntityUtils.getActor(rVal);
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.spawnRegularHitbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius());
Globals.hitboxManager.registerHitbox(hitbox);
Entity hitbox = HitboxUtils.clientSpawnRegularHitbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius());
Globals.clientHitboxManager.registerHitbox(hitbox);
hitboxList.add(hitbox);
} else if(hitboxdata.getType().equals("hurt")){
Entity hurtbox = HitboxUtils.spawnRegularHurtbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius());
Globals.hitboxManager.registerHitbox(hurtbox);
Entity hurtbox = HitboxUtils.clientSpawnRegularHurtbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius());
Globals.clientHitboxManager.registerHitbox(hurtbox);
hurtboxList.add(hurtbox);
}
rVal.putData(EntityDataStrings.HITBOX_ASSOCIATED_LIST, hitboxList);
@ -125,12 +176,12 @@ public class CreatureUtils {
case "CYLINDER": {
rigidBody = PhysicsUtils.getCylinderObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE);
CollidableTree tree = new CollidableTree(rVal,collidable,rigidBody);
ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
rVal.putData(EntityDataStrings.COLLIDABLE_TREE, tree);
rVal.putData(EntityDataStrings.CLIENT_COLLIDABLE_TREE, tree);
scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3());
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
@ -142,20 +193,20 @@ public class CreatureUtils {
inertiaTensor.m22(mass * scale.x * scale.x / 2.0f);
rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert());
Globals.collisionEngine.registerPhysicsEntity(rVal);
Globals.collisionEngine.registerDynamicPhysicsEntity(rVal);
Globals.collisionEngine.registerCollisionObject(rigidBody, collidable);
Globals.entityManager.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(rVal);
Globals.clientSceneWrapper.getCollisionEngine().registerDynamicPhysicsEntity(rVal);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
Globals.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
} break;
case "CUBE": {
rigidBody = PhysicsUtils.getCubeObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE);
CollidableTree tree = new CollidableTree(rVal,collidable,rigidBody);
ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
rVal.putData(EntityDataStrings.COLLIDABLE_TREE, tree);
rVal.putData(EntityDataStrings.CLIENT_COLLIDABLE_TREE, tree);
scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3());
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
@ -164,10 +215,10 @@ public class CreatureUtils {
inertiaTensor = new Matrix4f().identity().scale(mass * scale.x * scale.x / 6.0f).m33(1);
rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert());
Globals.collisionEngine.registerPhysicsEntity(rVal);
Globals.collisionEngine.registerDynamicPhysicsEntity(rVal);
Globals.collisionEngine.registerCollisionObject(rigidBody, collidable);
Globals.entityManager.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(rVal);
Globals.clientSceneWrapper.getCollisionEngine().registerDynamicPhysicsEntity(rVal);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
Globals.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
} break;
}
}
@ -207,18 +258,18 @@ public class CreatureUtils {
}
sprintTree.setGroundMovementTree(moveTree);
moveTree.setSprintTree(sprintTree);
rVal.putData(EntityDataStrings.SPRINT_TREE,sprintTree);
Globals.entityManager.registerBehaviorTree(sprintTree);
Globals.entityManager.registerEntityToTag(rVal, EntityTags.SPRINTABLE);
rVal.putData(EntityDataStrings.CLIENT_SPRINT_TREE,sprintTree);
Globals.clientScene.registerBehaviorTree(sprintTree);
Globals.clientScene.registerEntityToTag(rVal, EntityTags.SPRINTABLE);
}
//round out end of move system
rVal.putData(EntityDataStrings.DATA_STRING_MOVEMENT_BT, moveTree);
rVal.putData(EntityDataStrings.CLIENT_MOVEMENT_BT, moveTree);
CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,0));
rVal.putData(EntityDataStrings.DATA_STRING_MAX_NATURAL_VELOCITY, groundMovementSystem.getMaxVelocity());
rVal.putData(EntityDataStrings.DATA_STRING_ACCELERATION, groundMovementSystem.getAcceleration());
rVal.putData(EntityDataStrings.DATA_STRING_VELOCITY, 0f);
Globals.entityManager.registerBehaviorTree(moveTree);
Globals.entityManager.registerEntityToTag(rVal, EntityTags.MOVEABLE);
Globals.clientScene.registerBehaviorTree(moveTree);
Globals.clientScene.registerEntityToTag(rVal, EntityTags.MOVEABLE);
break;
//
// Jump
@ -228,14 +279,14 @@ public class CreatureUtils {
if(jumpMovementSystem.getAnimationJump() != null){
jumpTree.setAnimationJump(jumpMovementSystem.getAnimationJump().getName());
}
if(CreatureUtils.getEntityMovementTree(rVal) != null && CreatureUtils.getEntityMovementTree(rVal) instanceof GroundMovementTree){
((GroundMovementTree)CreatureUtils.getEntityMovementTree(rVal)).setJumpTree(jumpTree);
if(CreatureUtils.clientGetEntityMovementTree(rVal) != null && CreatureUtils.clientGetEntityMovementTree(rVal) instanceof GroundMovementTree){
((GroundMovementTree)CreatureUtils.clientGetEntityMovementTree(rVal)).setClientJumpTree(jumpTree);
}
if(FallTree.getFallTree(rVal)!=null){
FallTree.getFallTree(rVal).setJumpTree(jumpTree);
}
rVal.putData(EntityDataStrings.JUMP_TREE, jumpTree);
Globals.entityManager.registerBehaviorTree(jumpTree);
rVal.putData(EntityDataStrings.CLIENT_JUMP_TREE, jumpTree);
Globals.clientScene.registerBehaviorTree(jumpTree);
break;
//
// Falling
@ -248,14 +299,14 @@ public class CreatureUtils {
if(fallMovementSystem.getAnimationLand()!=null){
fallTree.setAnimationLand(fallMovementSystem.getAnimationLand().getName());
}
if(CreatureUtils.getEntityMovementTree(rVal) != null && CreatureUtils.getEntityMovementTree(rVal) instanceof GroundMovementTree){
((GroundMovementTree)CreatureUtils.getEntityMovementTree(rVal)).setFallTree(fallTree);
if(CreatureUtils.clientGetEntityMovementTree(rVal) != null && CreatureUtils.clientGetEntityMovementTree(rVal) instanceof GroundMovementTree){
((GroundMovementTree)CreatureUtils.clientGetEntityMovementTree(rVal)).setClientFallTree(fallTree);
}
if(JumpTree.getJumpTree(rVal)!=null){
fallTree.setJumpTree(JumpTree.getJumpTree(rVal));
if(JumpTree.getClientJumpTree(rVal)!=null){
fallTree.setJumpTree(JumpTree.getClientJumpTree(rVal));
}
rVal.putData(EntityDataStrings.FALL_TREE, fallTree);
Globals.entityManager.registerBehaviorTree(fallTree);
Globals.clientScene.registerBehaviorTree(fallTree);
break;
//
// Airplane
@ -270,10 +321,10 @@ public class CreatureUtils {
airplaneMovementTree.setMinimumVelocity(airplaneMovementSystem.getMinVelocity());
airplaneMovementTree.setMaxRotationSpeed(airplaneMovementSystem.getMaxRotationSpeed());
//register misc stuff
rVal.putData(EntityDataStrings.DATA_STRING_MOVEMENT_BT, airplaneMovementTree);
rVal.putData(EntityDataStrings.CLIENT_MOVEMENT_BT, airplaneMovementTree);
CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,0));
Globals.entityManager.registerBehaviorTree(airplaneMovementTree);
Globals.entityManager.registerEntityToTag(rVal, EntityTags.MOVEABLE);
Globals.clientScene.registerBehaviorTree(airplaneMovementTree);
Globals.clientScene.registerEntityToTag(rVal, EntityTags.MOVEABLE);
} break;
}
}
@ -288,10 +339,10 @@ public class CreatureUtils {
break;
case "ATTACKER":
AttackTree attackTree = new AttackTree(rVal);
rVal.putData(EntityDataStrings.ATTACK_TREE, attackTree);
rVal.putData(EntityDataStrings.CLIENT_ATTACK_TREE, attackTree);
rVal.putData(EntityDataStrings.ATTACK_MOVE_TYPE_ACTIVE, null);
Globals.entityManager.registerBehaviorTree(attackTree);
Globals.entityManager.registerEntityToTag(rVal, EntityTags.ATTACKER);
Globals.clientScene.registerBehaviorTree(attackTree);
Globals.clientScene.registerEntityToTag(rVal, EntityTags.ATTACKER);
//add all attack moves
if(rawType.getAttackMoves() != null && rawType.getAttackMoves().size() > 0){
for(AttackMove attackMove : rawType.getAttackMoves()){
@ -310,23 +361,23 @@ public class CreatureUtils {
case "SHOOTER": {
ShooterTree shooterTree = new ShooterTree(rVal);
ShooterTree.setShooterTree(rVal, shooterTree);
Globals.entityManager.registerBehaviorTree(shooterTree);
Globals.clientScene.registerBehaviorTree(shooterTree);
} break;
case "GRAVITY":
Collidable collidable = (Collidable)rVal.getData(EntityDataStrings.PHYSICS_COLLIDABLE);
CollisionObject collisionObject = (CollisionObject)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
GravityTree gravityTree = new GravityTree(rVal,collidable,collisionObject,30);
// gravityTree.setCollisionObject(collisionObject, collidable);
// gravityTree.setCollisionObject(collisionObject, collidable);
rVal.putData(EntityDataStrings.GRAVITY_ENTITY, true);
rVal.putData(EntityDataStrings.GRAVITY_TREE, gravityTree);
Globals.entityManager.registerBehaviorTree(gravityTree);
rVal.putData(EntityDataStrings.CLIENT_GRAVITY_TREE, gravityTree);
Globals.clientScene.registerBehaviorTree(gravityTree);
break;
case "TARGETABLE":
Globals.entityManager.registerEntityToTag(rVal, EntityTags.TARGETABLE);
Globals.clientScene.registerEntityToTag(rVal, EntityTags.TARGETABLE);
break;
case "INVENTORY":
rVal.putData(EntityDataStrings.NATURAL_INVENTORY,UnrelationalInventoryState.createUnrelationalInventory(10));
InventoryUtils.setInventoryState(rVal, InventoryState.createInventoryState(rVal));
InventoryUtils.clientSetInventoryState(rVal, InventoryState.clientCreateInventoryState(rVal));
break;
case "OUTLINE":
rVal.putData(EntityDataStrings.DRAW_OUTLINE, true);
@ -418,15 +469,366 @@ public class CreatureUtils {
}
rotatorTree.addRotatorNode(hierarchyNode);
}
rVal.putData(EntityDataStrings.ROTATOR_TREE, rotatorTree);
Globals.entityManager.registerBehaviorTree(rotatorTree);
rVal.putData(EntityDataStrings.CLIENT_ROTATOR_TREE, rotatorTree);
Globals.clientScene.registerBehaviorTree(rotatorTree);
}
//add health system
rVal.putData(EntityDataStrings.LIFE_STATE, new LifeState(rVal, rawType.getHealthSystem()));
Globals.entityManager.registerEntityToTag(rVal, EntityTags.LIFE_STATE);
Globals.clientScene.registerEntityToTag(rVal, EntityTags.LIFE_STATE);
//idle tree & generic stuff all creatures have
rVal.putData(EntityDataStrings.IDLE_TREE, new IdleTree(rVal));
Globals.entityManager.registerEntityToTag(rVal, EntityTags.CREATURE);
Globals.clientScene.registerEntityToTag(rVal, EntityTags.CREATURE);
rVal.putData(EntityDataStrings.DATA_STRING_CREATURE_IS_CREATURE, true);
rVal.putData(EntityDataStrings.DATA_STRING_CREATURE_TYPE, type);
CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,1));
rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
return rVal;
}
/**
* Spawns a server-side creature
* @param realm The realm to spawn the creature in
* @param position The position of the creature in that realm
* @param type The type of creature
* @param template The creature template to use
* @return The creature entity
*/
public static Entity serverSpawnBasicCreature(Realm realm, Vector3d position, String type, CreatureTemplate template){
CreatureType rawType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(type);
Entity rVal = EntityCreationUtils.createServerEntity(realm, position);
EntityCreationUtils.makeEntityPoseable(rVal, rawType.getModelPath());
PoseActor creatureActor = EntityUtils.getPoseActor(rVal);
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.serverSpawnRegularHitbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius());
realm.getHitboxManager().registerHitbox(hitbox);
hitboxList.add(hitbox);
} else if(hitboxdata.getType().equals("hurt")){
Entity hurtbox = HitboxUtils.serverSpawnRegularHurtbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius());
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){
CollidableTemplate physicsTemplate = rawType.getCollidable();
CollisionObject rigidBody;
Collidable collidable;
float mass = 1.0f;
Matrix4f inertiaTensor;
Vector3f scale;
switch(physicsTemplate.getType()){
case "CYLINDER": {
rigidBody = PhysicsUtils.getCylinderObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE);
ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, tree);
scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3());
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
//inertia tensor
//https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html
inertiaTensor = new Matrix4f();
inertiaTensor.m00(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f);
inertiaTensor.m11(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f);
inertiaTensor.m22(mass * scale.x * scale.x / 2.0f);
rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert());
realm.getCollisionEngine().registerPhysicsEntity(rVal);
realm.getCollisionEngine().registerDynamicPhysicsEntity(rVal);
realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
} break;
case "CUBE": {
rigidBody = PhysicsUtils.getCubeObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE);
ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, tree);
scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3());
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
//inertia tensor
//https://hepweb.ucsd.edu/ph110b/110b_notes/node26.html
inertiaTensor = new Matrix4f().identity().scale(mass * scale.x * scale.x / 6.0f).m33(1);
rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert());
realm.getCollisionEngine().registerPhysicsEntity(rVal);
realm.getCollisionEngine().registerDynamicPhysicsEntity(rVal);
realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
} break;
}
}
//
//
// MOVEMENT SYSTEMS
//
//
for(MovementSystem movementSystem : rawType.getMovementSystems()){
switch(movementSystem.getType()){
//
// Generic ground
case GroundMovementSystem.GROUND_MOVEMENT_SYSTEM:
GroundMovementSystem groundMovementSystem = (GroundMovementSystem)movementSystem;
ServerGroundMovementTree moveTree = new ServerGroundMovementTree(rVal,CollisionObjUtils.getCollidable(rVal));
if(groundMovementSystem.getAnimationStartup() != null){
moveTree.setAnimationStartUp(groundMovementSystem.getAnimationStartup().getName());
}
if(groundMovementSystem.getAnimationLoop() != null){
moveTree.setAnimationMain(groundMovementSystem.getAnimationLoop().getName());
}
if(groundMovementSystem.getAnimationWindDown()!= null){
moveTree.setAnimationSlowDown(groundMovementSystem.getAnimationWindDown().getName());
}
//sprint system
if(groundMovementSystem.getSprintSystem() != null){
SprintSystem sprintSystem = groundMovementSystem.getSprintSystem();
ServerSprintTree sprintTree = new ServerSprintTree(rVal,sprintSystem.getMaxVelocity(),sprintSystem.getStaminaMax());
if(sprintSystem.getAnimationStartUp()!= null){
moveTree.setAnimationSprintStartUp(sprintSystem.getAnimationStartUp().getName());
}
if(sprintSystem.getAnimationMain()!= null){
moveTree.setAnimationSprint(sprintSystem.getAnimationMain().getName());
}
if(sprintSystem.getAnimationWindDown()!= null){
moveTree.setAnimationSprintWindDown(sprintSystem.getAnimationWindDown().getName());
}
sprintTree.setServerGroundMovementTree(moveTree);
moveTree.setServerSprintTree(sprintTree);
rVal.putData(EntityDataStrings.SERVER_SPRINT_TREE,sprintTree);
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, sprintTree);
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.SPRINTABLE);
}
//round out end of move system
rVal.putData(EntityDataStrings.SERVER_MOVEMENT_BT, moveTree);
CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,0));
rVal.putData(EntityDataStrings.DATA_STRING_MAX_NATURAL_VELOCITY, groundMovementSystem.getMaxVelocity());
rVal.putData(EntityDataStrings.DATA_STRING_ACCELERATION, groundMovementSystem.getAcceleration());
rVal.putData(EntityDataStrings.DATA_STRING_VELOCITY, 0f);
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, moveTree);
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.MOVEABLE);
break;
//
// Jump
case JumpMovementSystem.JUMP_MOVEMENT_SYSTEM:
JumpMovementSystem jumpMovementSystem = (JumpMovementSystem)movementSystem;
ServerJumpTree jumpTree = new ServerJumpTree(rVal, jumpMovementSystem.getJumpFrames(), jumpMovementSystem.getJumpForce());
if(jumpMovementSystem.getAnimationJump() != null){
jumpTree.setAnimationJump(jumpMovementSystem.getAnimationJump().getName());
}
if(CreatureUtils.serverGetEntityMovementTree(rVal) != null && CreatureUtils.serverGetEntityMovementTree(rVal) instanceof GroundMovementTree){
((ServerGroundMovementTree)CreatureUtils.serverGetEntityMovementTree(rVal)).setServerJumpTree(jumpTree);
}
if(ServerFallTree.getFallTree(rVal)!=null){
ServerFallTree.getFallTree(rVal).setServerJumpTree(jumpTree);
}
rVal.putData(EntityDataStrings.SERVER_JUMP_TREE, jumpTree);
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, jumpTree);
break;
//
// Falling
case FallMovementSystem.FALL_MOVEMENT_SYSTEM:
FallMovementSystem fallMovementSystem = (FallMovementSystem)movementSystem;
ServerFallTree fallTree = new ServerFallTree(rVal);
if(fallMovementSystem.getAnimationFall()!=null){
fallTree.setAnimationFall(fallMovementSystem.getAnimationFall().getName());
}
if(fallMovementSystem.getAnimationLand()!=null){
fallTree.setAnimationLand(fallMovementSystem.getAnimationLand().getName());
}
if(CreatureUtils.serverGetEntityMovementTree(rVal) != null && CreatureUtils.serverGetEntityMovementTree(rVal) instanceof GroundMovementTree){
((ServerGroundMovementTree)CreatureUtils.serverGetEntityMovementTree(rVal)).setServerFallTree(fallTree);
}
if(ServerJumpTree.getServerJumpTree(rVal)!=null){
fallTree.setServerJumpTree(ServerJumpTree.getServerJumpTree(rVal));
}
rVal.putData(EntityDataStrings.FALL_TREE, fallTree);
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, fallTree);
break;
//
// Airplane
case AirplaneMovementSystem.AIRPLANE_MOVEMENT_SYSTEM: {
//construct tree
AirplaneMovementSystem airplaneMovementSystem = (AirplaneMovementSystem) movementSystem;
AirplaneMovementTree airplaneMovementTree = new AirplaneMovementTree(rVal, CollisionObjUtils.getCollidable(rVal));
//set properties
rVal.putData(EntityDataStrings.DATA_STRING_MAX_NATURAL_VELOCITY, airplaneMovementSystem.getMaxVelocity());
rVal.putData(EntityDataStrings.DATA_STRING_ACCELERATION, airplaneMovementSystem.getAcceleration());
rVal.putData(EntityDataStrings.DATA_STRING_VELOCITY, 0f);
airplaneMovementTree.setMinimumVelocity(airplaneMovementSystem.getMinVelocity());
airplaneMovementTree.setMaxRotationSpeed(airplaneMovementSystem.getMaxRotationSpeed());
//register misc stuff
rVal.putData(EntityDataStrings.SERVER_MOVEMENT_BT, airplaneMovementTree);
CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,0));
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, airplaneMovementTree);
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.MOVEABLE);
} break;
}
}
if(rawType.getEquipPoints() != null && rawType.getEquipPoints().size() > 0){
EquipState.setEquipState(rVal, new EquipState(rVal,rawType.getEquipPoints()));
rVal.putData(EntityDataStrings.EQUIP_INVENTORY, RelationalInventoryState.buildRelationalInventoryStateFromEquipList(rawType.getEquipPoints()));
}
for(String token : rawType.getTokens()){
switch(token){
case "BLENDER_TRANSFORM": {
PoseActorUtils.applyBlenderTransformer(rVal);
} break;
case "ATTACKER": {
ServerAttackTree attackTree = new ServerAttackTree(rVal);
rVal.putData(EntityDataStrings.SERVER_ATTACK_TREE, attackTree);
rVal.putData(EntityDataStrings.ATTACK_MOVE_TYPE_ACTIVE, null);
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, attackTree);
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.ATTACKER);
//add all attack moves
if(rawType.getAttackMoves() != null && rawType.getAttackMoves().size() > 0){
for(AttackMove attackMove : rawType.getAttackMoves()){
rVal.putData(attackMove.getType(), rawType.getAttackMoveResolver().getMoveset(attackMove.getType()));
// switch(attackMove.getType()){
// case EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND:
// rVal.putData(EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND, rawType.getAttackMoveResolver().getMoveset(EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND));
// break;
// case EntityDataStrings.ATTACK_MOVE_TYPE_BOW_TWO_HAND:
// rVal.putData(EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND, rawType.getAttackMoveResolver().getMoveset(EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND));
// break;
// }
}
}
} break;
case "SHOOTER": {
ShooterTree shooterTree = new ShooterTree(rVal);
ShooterTree.setShooterTree(rVal, shooterTree);
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, shooterTree);
} break;
case "GRAVITY": {
Collidable collidable = (Collidable)rVal.getData(EntityDataStrings.PHYSICS_COLLIDABLE);
CollisionObject collisionObject = (CollisionObject)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
ServerGravityTree gravityTree = new ServerGravityTree(rVal,collidable,collisionObject,30);
// gravityTree.setCollisionObject(collisionObject, collidable);
rVal.putData(EntityDataStrings.GRAVITY_ENTITY, true);
rVal.putData(EntityDataStrings.SERVER_GRAVITY_TREE, gravityTree);
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, gravityTree);
} break;
case "TARGETABLE": {
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.TARGETABLE);
} break;
case "INVENTORY": {
rVal.putData(EntityDataStrings.NATURAL_INVENTORY,UnrelationalInventoryState.createUnrelationalInventory(10));
InventoryUtils.serverSetInventoryState(rVal, ServerInventoryState.serverCreateInventoryState(rVal));
} break;
case "OUTLINE": {
rVal.putData(EntityDataStrings.DRAW_OUTLINE, true);
} break;
}
}
//variants
if(rawType.getVisualAttributes() != null){
ActorStaticMorph staticMorph = null;
CreatureTemplate storedTemplate = new CreatureTemplate(rawType.getCreatureId());
for(VisualAttribute attributeType : rawType.getVisualAttributes()){
if(attributeType.getType().equals("remesh")){
if(attributeType.getVariants() != null && attributeType.getVariants().size() > 0){
AttributeVariant variant = attributeType.getVariants().get(0);
//if the template isn't null, try to find the variant from the template in the variant list
//if the variant is found, set the variable "variant" to the searched for variant
if(template != null && template.getValue(attributeType.getAttributeId()) != null){
String variantId = template.getValue(attributeType.getAttributeId()).getVariantId();
for(AttributeVariant searchVariant : attributeType.getVariants()){
if(searchVariant.getId().equals(variantId)){
variant = searchVariant;
//if we find the variant, store in on-creature template as well
storedTemplate.putValue(attributeType.getAttributeId(), variantId);
break;
}
}
}
//make sure stored template contains creature data
if(storedTemplate.getValue(attributeType.getAttributeId())==null){
storedTemplate.putValue(attributeType.getAttributeId(), attributeType.getVariants().get(0).getId());
}
//TODO: determine if this should be relevant to pose actor
//pretty certain it shouldn't be but you never know
// rVal.putData(EntityDataStrings.CREATURE_ATTRIBUTE_VARIANT + attributeType.getAttributeId(), variant.getId());
// Globals.assetManager.addModelPathToQueue(variant.getModel());
// for(String mesh : variant.getMeshes()){
// creatureActor.getMeshMask().queueMesh(variant.getModel(), mesh);
// }
}
}
if(attributeType.getType().equals("bone")){
if(staticMorph == null){
staticMorph = new ActorStaticMorph();
creatureActor.setStaticMorph(staticMorph);
}
if(attributeType.getPrimaryBone() != null && staticMorph.getBoneTransforms(attributeType.getPrimaryBone()) == null){
staticMorph.initBoneTransforms(attributeType.getPrimaryBone());
//if the template isn't null, set the value of the morph
if(template != null && template.getValue(attributeType.getAttributeId()) != null){
float templateValue = template.getValue(attributeType.getAttributeId()).getValue();
staticMorph.updateValue(attributeType.getSubtype(), attributeType.getPrimaryBone(), templateValue);
}
}
if(attributeType.getMirrorBone() != null && staticMorph.getBoneTransforms(attributeType.getMirrorBone()) == null){
staticMorph.initBoneTransforms(attributeType.getMirrorBone());
//if the template isn't null, set the value of the morph
if(template != null && template.getValue(attributeType.getAttributeId()) != null){
float templateValue = template.getValue(attributeType.getAttributeId()).getValue();
staticMorph.updateValue(attributeType.getSubtype(), attributeType.getMirrorBone(), templateValue);
}
}
//make sure stored template contains creature data
if(template != null && template.getValue(attributeType.getAttributeId()) != null) {
storedTemplate.putValue(attributeType.getAttributeId(), template.getValue(attributeType.getAttributeId()).getValue());
} else {
float midpoint = (attributeType.getMaxValue() - attributeType.getMinValue())/2.0f + attributeType.getMinValue();
storedTemplate.putValue(attributeType.getAttributeId(), midpoint);
}
}
}
//set race
storedTemplate.creatureType = rawType.getCreatureId();
//store template on creature
CreatureUtils.setCreatureTemplate(rVal, storedTemplate);
}
//rotator system
if(rawType.getRotatorSystem() != null){
RotatorSystem system = rawType.getRotatorSystem();
ServerRotatorTree rotatorTree = new ServerRotatorTree(rVal);
for(RotatorItem item : system.getRotatorItems()){
//put actor rotator
ActorBoneRotator newRotator = new ActorBoneRotator();
creatureActor.addBoneRotator(item.getBoneName(), newRotator);
//construct node for tree
RotatorHierarchyNode hierarchyNode = new RotatorHierarchyNode();
hierarchyNode.setBone(item.getBoneName());
for(RotatorConstraint constraint : item.getConstraints()){
hierarchyNode.addRotatorConstraint(new electrosphere.entity.state.rotator.RotatorConstraint(constraint));
}
rotatorTree.addRotatorNode(hierarchyNode);
}
rVal.putData(EntityDataStrings.SERVER_ROTATOR_TREE, rotatorTree);
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, rotatorTree);
}
//add health system
rVal.putData(EntityDataStrings.LIFE_STATE, new LifeState(rVal, rawType.getHealthSystem()));
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.LIFE_STATE);
//idle tree & generic stuff all creatures have
rVal.putData(EntityDataStrings.IDLE_TREE, new IdleTree(rVal));
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.CREATURE);
rVal.putData(EntityDataStrings.DATA_STRING_CREATURE_IS_CREATURE, true);
rVal.putData(EntityDataStrings.DATA_STRING_CREATURE_TYPE, type);
CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,1));
@ -485,25 +887,34 @@ public class CreatureUtils {
e.putData(EntityDataStrings.DATA_STRING_MAX_NATURAL_VELOCITY, scalar);
}
public static BehaviorTree getEntityMovementTree(Entity e){
return (BehaviorTree)e.getData(EntityDataStrings.DATA_STRING_MOVEMENT_BT);
public static BehaviorTree clientGetEntityMovementTree(Entity e){
return (BehaviorTree)e.getData(EntityDataStrings.CLIENT_MOVEMENT_BT);
}
public static BehaviorTree serverGetEntityMovementTree(Entity e){
return (BehaviorTree)e.getData(EntityDataStrings.SERVER_MOVEMENT_BT);
}
public static void attachEntityMessageToMovementTree(Entity e, EntityMessage em){
BehaviorTree movementTree = getEntityMovementTree(e);
public static void clientAttachEntityMessageToMovementTree(Entity e, EntityMessage em){
BehaviorTree movementTree = clientGetEntityMovementTree(e);
if(movementTree instanceof GroundMovementTree){
((GroundMovementTree)movementTree).addNetworkMessage(em);
} else if(movementTree instanceof AirplaneMovementTree){
((AirplaneMovementTree)movementTree).addNetworkMessage(em);
}
}
public static AttackTree getEntityAttackTree(Entity e){
return (AttackTree)e.getData(EntityDataStrings.ATTACK_TREE);
public static void serverAttachEntityMessageToMovementTree(Entity e, EntityMessage em){
BehaviorTree movementTree = serverGetEntityMovementTree(e);
if(movementTree instanceof ServerGroundMovementTree){
((ServerGroundMovementTree)movementTree).addNetworkMessage(em);
} else if(movementTree instanceof AirplaneMovementTree){
((AirplaneMovementTree)movementTree).addNetworkMessage(em);
}
}
public static void attachEntityMessageToAttackTree(Entity e, EntityMessage em){
getEntityAttackTree(e).addNetworkMessage(em);
clientGetAttackTree(e).addNetworkMessage(em);
}
public static String getType(Entity e){
@ -526,16 +937,24 @@ public class CreatureUtils {
return e.containsKey(EntityDataStrings.DATA_STRING_CREATURE_IS_CREATURE);
}
public static AttackTree getAttackTree(Entity e){
return (AttackTree)e.getData(EntityDataStrings.ATTACK_TREE);
public static AttackTree clientGetAttackTree(Entity e){
return (AttackTree)e.getData(EntityDataStrings.CLIENT_ATTACK_TREE);
}
public static ServerAttackTree serverGetAttackTree(Entity e){
return (ServerAttackTree)e.getData(EntityDataStrings.SERVER_ATTACK_TREE);
}
public static IdleTree getIdleTree(Entity e){
return (IdleTree)e.getData(EntityDataStrings.IDLE_TREE);
}
public static SprintTree getSprintTree(Entity e){
return (SprintTree)e.getData(EntityDataStrings.SPRINT_TREE);
public static SprintTree clientGetSprintTree(Entity e){
return (SprintTree)e.getData(EntityDataStrings.CLIENT_SPRINT_TREE);
}
public static ServerSprintTree serverGetSprintTree(Entity e){
return (ServerSprintTree)e.getData(EntityDataStrings.SERVER_SPRINT_TREE);
}
public static void setCreatureTemplate(Entity e, CreatureTemplate template){

View File

@ -4,13 +4,15 @@ import org.joml.Vector3d;
import org.joml.Vector3f;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityUtils;
public class DebugVisualizerUtils {
public static Entity spawnVectorVisualizer(Vector3d position, Vector3d direction){
Entity rVal = EntityUtils.spawnDrawableEntity("Models/unitcube.fbx");
public static Entity clientSpawnVectorVisualizer(Vector3d position, Vector3d direction){
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(rVal, "Models/unitcube.fbx");
Vector3d pos = new Vector3d(position).add(new Vector3d(direction).normalize().mul(0.3));
EntityUtils.getPosition(rVal).set(pos);
EntityUtils.getScale(rVal).set(0.05f,0.3f,0.05f);
@ -18,8 +20,9 @@ public class DebugVisualizerUtils {
return rVal;
}
public static Entity spawnUpdatingVectorVisualizer(Vector3d position, Vector3d direction){
Entity rVal = EntityUtils.spawnDrawableEntity("Models/unitcube.fbx");
public static Entity clientSpawnUpdatingVectorVisualizer(Vector3d position, Vector3d direction){
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(rVal, "Models/unitcube.fbx");
Vector3d pos = new Vector3d(position).add(new Vector3d(direction).normalize().mul(0.3));
EntityUtils.getPosition(rVal).set(pos);
EntityUtils.getScale(rVal).set(0.05f,0.3f,0.05f);

View File

@ -3,9 +3,10 @@ package electrosphere.entity.types.foliage;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.IdleTree;
import electrosphere.entity.state.idle.IdleTree;
import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.game.collision.PhysicsUtils;
import electrosphere.game.collision.collidable.Collidable;
@ -28,7 +29,8 @@ public class FoliageUtils {
public static Entity spawnBasicFoliage(String type){
FoliageType rawType = Globals.gameConfigCurrent.getFoliageMap().getFoliage(type);
Entity rVal = EntityUtils.spawnDrawableEntity(rawType.getModelPath());
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(rVal, rawType.getModelPath());
// if(rawType.getPhysicsObjects() != null){
// List<PhysicsObject> physicsObjects = rawType.getPhysicsObjects();
// for(PhysicsObject physicsTemplate : physicsObjects){

View File

@ -2,6 +2,7 @@ package electrosphere.entity.types.hitbox;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.attach.AttachUtils;
@ -12,6 +13,7 @@ import electrosphere.entity.state.life.LifeState;
import electrosphere.entity.state.life.LifeUtils;
import electrosphere.entity.state.movement.ProjectileTree;
import electrosphere.game.server.effects.ParticleEffects;
import electrosphere.server.datacell.Realm;
import java.util.List;
@ -27,9 +29,15 @@ import org.joml.Vector4f;
*/
public class HitboxUtils {
public static Entity spawnRegularHitbox(Entity parent, String bone, float size){
Entity rVal = new Entity();
/**
* Spawns a hitbox entity on the client
* @param parent The parent entity to attach the hitbox to
* @param bone The bone on the parent to attach to
* @param size The radius of the hitsphere
* @return The hitbox entity
*/
public static Entity clientSpawnRegularHitbox(Entity parent, String bone, float size){
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
HitboxData data = new HitboxData();
data.setActive(false);
data.setBone(bone);
@ -39,12 +47,42 @@ public class HitboxUtils {
rVal.putData(EntityDataStrings.HITBOX_DATA, data);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
Globals.hitboxManager.registerHitbox(rVal);
Globals.clientHitboxManager.registerHitbox(rVal);
return rVal;
}
public static Entity spawnRegularHurtbox(Entity parent, String bone, float size){
Entity rVal = new Entity();
/**
* Spawns a hitbox entity on the server
* @param parent The parent entity to attach the hitbox to
* @param bone The bone to attach to the hitbox to
* @param size The radius of the hitsphere
* @return The hitbox entity
*/
public static Entity serverSpawnRegularHitbox(Entity parent, String bone, float size){
Entity rVal = EntityCreationUtils.createServerEntity(Globals.realmManager.getEntityRealm(parent), new Vector3d(0,0,0));
HitboxData data = new HitboxData();
data.setActive(false);
data.setBone(bone);
data.setRadius(size);
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT);
rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
rVal.putData(EntityDataStrings.HITBOX_DATA, data);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
Globals.realmManager.getEntityRealm(parent).getHitboxManager().registerHitbox(rVal);
return rVal;
}
/**
* Spawns a hurtbox on the client
* @param parent The parent entity of the hurtbox
* @param bone The bone on the parent to attach the hurtbox to
* @param size The radius of the hurtsphere
* @return The hurtbox entity
*/
public static Entity clientSpawnRegularHurtbox(Entity parent, String bone, float size){
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
HitboxData data = new HitboxData();
data.setActive(true);
data.setBone(bone);
@ -54,7 +92,29 @@ public class HitboxUtils {
rVal.putData(EntityDataStrings.HITBOX_DATA, data);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
Globals.hitboxManager.registerHitbox(rVal);
Globals.clientHitboxManager.registerHitbox(rVal);
return rVal;
}
/**
* Spawns a hurtbox on the server
* @param parent The parent entity of the hurtbox
* @param bone The bone on the parent to attach the hurtbox to
* @param size The radius of the hurtsphere
* @return The hurtbox entity
*/
public static Entity serverSpawnRegularHurtbox(Entity parent, String bone, float size){
Entity rVal = EntityCreationUtils.createServerEntity(Globals.realmManager.getEntityRealm(parent), new Vector3d(0,0,0));
HitboxData data = new HitboxData();
data.setActive(true);
data.setBone(bone);
data.setRadius(size);
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
rVal.putData(EntityDataStrings.HITBOX_DATA, data);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
Globals.realmManager.getEntityRealm(parent).getHitboxManager().registerHitbox(rVal);
return rVal;
}
@ -67,8 +127,8 @@ public class HitboxUtils {
* @param filter an optional list of parent entities to not colide with
* @return The hitbox entity
*/
public static Entity spawnRegularHitbox(Entity parent, HitboxPositionCallback positionCallback, float size, boolean hurtbox, List<Entity> filter){
Entity rVal = new Entity();
public static Entity clientSpawnRegularHitbox(Entity parent, HitboxPositionCallback positionCallback, float size, boolean hurtbox, List<Entity> filter){
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
HitboxData data = new HitboxData();
data.setActive(true);
data.setPositionCallback(positionCallback);
@ -83,11 +143,41 @@ public class HitboxUtils {
rVal.putData(EntityDataStrings.HITBOX_DATA, data);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
Globals.hitboxManager.registerHitbox(rVal);
Globals.clientHitboxManager.registerHitbox(rVal);
return rVal;
}
/**
* 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 positionCallback The position callback for keeping hitbox entity position up to date
* @param size The size of the hitbox
* @param hurtbox If true, it will instead be a hurtbox
* @param filter an optional list of parent entities to not colide with
* @return The hitbox entity
*/
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));
HitboxData data = new HitboxData();
data.setActive(true);
data.setPositionCallback(positionCallback);
data.setRadius(size);
data.setEntityFilter(filter);
if(hurtbox){
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
} else {
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT);
}
rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
rVal.putData(EntityDataStrings.HITBOX_DATA, data);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
Globals.realmManager.getEntityRealm(parent).getHitboxManager().registerHitbox(rVal);
return rVal;
}
public static void updatePosition(Entity hitbox){
public static void clientUpdatePosition(Entity hitbox){
Entity parent = ((Entity)hitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT));
HitboxData hitboxData = getHitboxData(hitbox);
String boneName = hitboxData.getBone();
@ -105,6 +195,33 @@ public class HitboxUtils {
worldPosition = worldPosition.rotate(rotation);
worldPosition.add(new Vector3f((float)parentPos.x,(float)parentPos.y,(float)parentPos.z));
EntityUtils.getPosition(hitbox).set(worldPosition);
} else {
HitboxPositionCallback positionCallback = hitboxData.getPositionCallback();
EntityUtils.getPosition(hitbox).set(positionCallback.getPosition());
}
}
public static void serverUpdatePosition(Entity hitbox){
Entity parent = ((Entity)hitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT));
HitboxData hitboxData = getHitboxData(hitbox);
String boneName = hitboxData.getBone();
if(boneName != null){
Quaternionf parentRotation = EntityUtils.getRotation(parent);
Vector3f positionScale = EntityUtils.getScale(parent);
Vector3f worldPosition = new Vector3f();
Vector3f bonePosition = EntityUtils.getPoseActor(parent).getBonePosition(boneName);
Vector3d parentPos = EntityUtils.getPosition(parent);
worldPosition.set(bonePosition.x,bonePosition.y,bonePosition.z);
Quaternionf rotation = new Quaternionf(parentRotation);
worldPosition = worldPosition.mul(positionScale);
worldPosition = worldPosition.rotate(rotation);
worldPosition.add(new Vector3f((float)parentPos.x,(float)parentPos.y,(float)parentPos.z));
EntityUtils.getPosition(hitbox).set(worldPosition);
@ -114,13 +231,13 @@ public class HitboxUtils {
}
}
public static void collideEntities(Entity generatorHitbox){
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.hitboxManager.getAllHitboxes()){
for(Entity receiverHitbox : Globals.clientHitboxManager.getAllHitboxes()){
Entity receiverParent = (Entity)receiverHitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
@ -143,7 +260,7 @@ public class HitboxUtils {
//and both hitboxes are active
if(
receiverParent != generatorParent &&
Globals.collisionEngine.collisionSphereCheck(generatorHitbox, generatorData, receiverHitbox, receiverData) &&
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)
@ -151,17 +268,67 @@ public class HitboxUtils {
String receiverType = receiverData.getType();
if(generatorType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT) && receiverType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT)){
damageHitboxColision(generatorHitbox, receiverHitbox);
clientDamageHitboxColision(generatorHitbox, receiverHitbox);
}
if(generatorType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT) && receiverType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT)){
damageHitboxColision(receiverHitbox, generatorHitbox);
clientDamageHitboxColision(receiverHitbox, generatorHitbox);
}
}
}
}
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);
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);
}
}
}
}
public static void damageHitboxColision(Entity hitbox, Entity hurtbox){
public static void clientDamageHitboxColision(Entity hitbox, Entity hurtbox){
Entity hitboxParent = (Entity)hitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
Entity hurtboxParent = (Entity)hurtbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
@ -189,7 +356,51 @@ public class HitboxUtils {
} else {
int damage = 0;
//for entities using attacktree
if(CreatureUtils.getAttackTree(hitboxParent) != null){
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();
}
}
}
public static void serverDamageHitboxColision(Entity hitbox, Entity hurtbox){
Entity hitboxParent = (Entity)hitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
Entity hurtboxParent = (Entity)hurtbox.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
//to make sure you don't stab yourself for instance
boolean isItem = ItemUtils.isItem(hitboxParent);//hitboxParent.containsKey(EntityDataStrings.ITEM_IS_ITEM);
Entity hitboxAttachParent = AttachUtils.getParent(hitboxParent);
if(isItem){
if(hitboxAttachParent != hurtboxParent){
LifeState lifeState = LifeUtils.getLifeState(hurtboxParent);
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

View File

@ -3,11 +3,14 @@ package electrosphere.entity.types.item;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityTags;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.collidable.CollidableTree;
import electrosphere.entity.state.collidable.ClientCollidableTree;
import electrosphere.entity.state.collidable.ServerCollidableTree;
import electrosphere.entity.state.gravity.GravityTree;
import electrosphere.entity.state.gravity.ServerGravityTree;
import electrosphere.entity.state.movement.GroundMovementTree;
import electrosphere.entity.types.attach.AttachUtils;
import electrosphere.entity.types.collision.CollisionObjUtils;
@ -26,6 +29,9 @@ import electrosphere.net.server.player.Player;
import electrosphere.renderer.Model;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.actor.ActorUtils;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
import electrosphere.server.datacell.utils.ServerEntityTagUtils;
import java.util.LinkedList;
import java.util.List;
@ -43,17 +49,18 @@ public class ItemUtils {
static final String genericItemIconPath = "Textures/icons/itemIconItemGeneric.png";
public static Entity spawnBasicItem(String name){
public static Entity clientSpawnBasicItem(String name){
Item item = Globals.gameConfigCurrent.getItemMap().getItem(name);
Entity rVal = EntityUtils.spawnDrawableEntity(item.getModelPath());
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(rVal, item.getModelPath());
if(item.getWeaponData() != null){
rVal.putData(EntityDataStrings.ITEM_IS_WEAPON, true);
WeaponData weaponData = item.getWeaponData();
if(weaponData.getHitboxes() != null){
List<Entity> hitboxList = new LinkedList<Entity>();
for(HitboxData hitboxdata : weaponData.getHitboxes()){
Entity hitbox = HitboxUtils.spawnRegularHitbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius());
Globals.hitboxManager.registerHitbox(hitbox);
Entity hitbox = HitboxUtils.clientSpawnRegularHitbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius());
Globals.clientHitboxManager.registerHitbox(hitbox);
hitboxList.add(hitbox);
}
rVal.putData(EntityDataStrings.HITBOX_ASSOCIATED_LIST,hitboxList);
@ -76,7 +83,7 @@ public class ItemUtils {
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
rVal.putData(EntityDataStrings.COLLIDABLE_TREE, new CollidableTree(rVal,collidable,rigidBody));
rVal.putData(EntityDataStrings.CLIENT_COLLIDABLE_TREE, new ClientCollidableTree(rVal,collidable,rigidBody));
scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3());
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
@ -88,10 +95,10 @@ public class ItemUtils {
inertiaTensor.m22(mass * scale.x * scale.x / 2.0f);
rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert());
Globals.collisionEngine.registerPhysicsEntity(rVal);
Globals.collisionEngine.registerDynamicPhysicsEntity(rVal);
Globals.collisionEngine.registerCollisionObject(rigidBody, collidable);
Globals.entityManager.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(rVal);
Globals.clientSceneWrapper.getCollisionEngine().registerDynamicPhysicsEntity(rVal);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
Globals.clientSceneWrapper.getScene().registerEntityToTag(rVal, EntityTags.COLLIDABLE);
break;
case "CUBE":
rigidBody = PhysicsUtils.getCubeObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
@ -100,7 +107,7 @@ public class ItemUtils {
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
rVal.putData(EntityDataStrings.COLLIDABLE_TREE, new CollidableTree(rVal,collidable,rigidBody));
rVal.putData(EntityDataStrings.CLIENT_COLLIDABLE_TREE, new ClientCollidableTree(rVal,collidable,rigidBody));
scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3());
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
@ -109,10 +116,10 @@ public class ItemUtils {
inertiaTensor = new Matrix4f().identity().scale(mass * scale.x * scale.x / 6.0f).m33(1);
rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert());
Globals.collisionEngine.registerPhysicsEntity(rVal);
Globals.collisionEngine.registerDynamicPhysicsEntity(rVal);
Globals.collisionEngine.registerCollisionObject(rigidBody, collidable);
Globals.entityManager.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(rVal);
Globals.clientSceneWrapper.getCollisionEngine().registerDynamicPhysicsEntity(rVal);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
Globals.clientSceneWrapper.getScene().registerEntityToTag(rVal, EntityTags.COLLIDABLE);
break;
}
}
@ -127,11 +134,11 @@ public class ItemUtils {
GravityTree gravityTree = new GravityTree(rVal,collidable,collisionObject,30);
// gravityTree.setCollisionObject(collisionObject, collidable);
rVal.putData(EntityDataStrings.GRAVITY_ENTITY, true);
rVal.putData(EntityDataStrings.GRAVITY_TREE, gravityTree);
Globals.entityManager.registerBehaviorTree(gravityTree);
rVal.putData(EntityDataStrings.CLIENT_GRAVITY_TREE, gravityTree);
Globals.clientSceneWrapper.getScene().registerBehaviorTree(gravityTree);
break;
case "TARGETABLE":
Globals.entityManager.registerEntityToTag(rVal, EntityTags.TARGETABLE);
Globals.clientSceneWrapper.getScene().registerEntityToTag(rVal, EntityTags.TARGETABLE);
break;
case "OUTLINE":
rVal.putData(EntityDataStrings.DRAW_OUTLINE, true);
@ -158,7 +165,129 @@ public class ItemUtils {
rVal.putData(EntityDataStrings.ITEM_TYPE, name);
// rVal.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(0.005f,0.005f,0.005f));
// rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().identity().rotateY((float)(-Math.PI/2)).rotateZ(-(float)(Math.PI/2)));
Globals.entityManager.registerEntityToTag(rVal, EntityTags.ITEM);
Globals.clientSceneWrapper.getScene().registerEntityToTag(rVal, EntityTags.ITEM);
return rVal;
}
public static Entity serverSpawnBasicItem(Realm realm, Vector3d position, String name){
Item item = Globals.gameConfigCurrent.getItemMap().getItem(name);
Entity rVal = EntityCreationUtils.createServerEntity(realm, position);// EntityUtils.spawnDrawableEntity(item.getModelPath());
EntityCreationUtils.makeEntityPoseable(rVal, item.getModelPath());
if(item.getWeaponData() != null){
rVal.putData(EntityDataStrings.ITEM_IS_WEAPON, true);
WeaponData weaponData = item.getWeaponData();
if(weaponData.getHitboxes() != null){
List<Entity> hitboxList = new LinkedList<Entity>();
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_DATA_RAW,weaponData);
}
if(item.getCollidable() != null){
CollidableTemplate physicsTemplate = item.getCollidable();
CollisionObject rigidBody;
Collidable collidable;
float mass = 1.0f;
Matrix4f inertiaTensor;
Vector3f scale;
switch(physicsTemplate.getType()){
case "CYLINDER":
rigidBody = PhysicsUtils.getCylinderObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
collidable = new Collidable(rVal, Collidable.TYPE_ITEM);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, new ServerCollidableTree(rVal,collidable,rigidBody));
scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3());
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
//inertia tensor
//https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html
inertiaTensor = new Matrix4f();
inertiaTensor.m00(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f);
inertiaTensor.m11(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f);
inertiaTensor.m22(mass * scale.x * scale.x / 2.0f);
rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert());
realm.getCollisionEngine().registerPhysicsEntity(rVal);
realm.getCollisionEngine().registerDynamicPhysicsEntity(rVal);
realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
break;
case "CUBE":
rigidBody = PhysicsUtils.getCubeObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
collidable = new Collidable(rVal, Collidable.TYPE_ITEM);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, new ServerCollidableTree(rVal,collidable,rigidBody));
scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3());
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
//inertia tensor
//https://hepweb.ucsd.edu/ph110b/110b_notes/node26.html
inertiaTensor = new Matrix4f().identity().scale(mass * scale.x * scale.x / 6.0f).m33(1);
rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert());
realm.getCollisionEngine().registerPhysicsEntity(rVal);
realm.getCollisionEngine().registerDynamicPhysicsEntity(rVal);
realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
break;
}
}
for(String token : item.getTokens()){
switch(token){
case "BLENDER_TRANSFORM":
ActorUtils.applyBlenderTransformer(rVal);
break;
case "GRAVITY":
Collidable collidable = (Collidable)rVal.getData(EntityDataStrings.PHYSICS_COLLIDABLE);
CollisionObject collisionObject = (CollisionObject)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
ServerGravityTree gravityTree = new ServerGravityTree(rVal,collidable,collisionObject,30);
// gravityTree.setCollisionObject(collisionObject, collidable);
rVal.putData(EntityDataStrings.GRAVITY_ENTITY, true);
rVal.putData(EntityDataStrings.SERVER_GRAVITY_TREE, gravityTree);
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, gravityTree);
break;
case "TARGETABLE":
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.TARGETABLE);
break;
case "OUTLINE":
rVal.putData(EntityDataStrings.DRAW_OUTLINE, true);
break;
}
}
if(item.getEquipWhitelist() != null){
rVal.putData(EntityDataStrings.ITEM_EQUIP_WHITELIST, item.getEquipWhitelist());
}
if(item.getIdleAnim() != null){
rVal.putData(EntityDataStrings.ANIM_IDLE,item.getIdleAnim());
}
if(item.getIconPath() != null && !item.getIconPath().equals("")){
rVal.putData(EntityDataStrings.ITEM_ICON,item.getIconPath());
} else {
rVal.putData(EntityDataStrings.ITEM_ICON,genericItemIconPath);
}
if(item.getEquipClass() != null){
rVal.putData(EntityDataStrings.ITEM_EQUIP_CLASS,item.getEquipClass());
}
rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
rVal.putData(EntityDataStrings.ITEM_IS_ITEM, true);
rVal.putData(EntityDataStrings.ITEM_IS_IN_INVENTORY, false);
rVal.putData(EntityDataStrings.ITEM_TYPE, name);
// rVal.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(0.005f,0.005f,0.005f));
// rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().identity().rotateY((float)(-Math.PI/2)).rotateZ(-(float)(Math.PI/2)));
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.ITEM);
return rVal;
}
@ -182,8 +311,11 @@ public class ItemUtils {
if(item.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){
item.removeData(EntityDataStrings.PHYSICS_COLLIDABLE);
}
if(item.containsKey(EntityDataStrings.COLLIDABLE_TREE)){
item.removeData(EntityDataStrings.COLLIDABLE_TREE);
if(item.containsKey(EntityDataStrings.SERVER_COLLIDABLE_TREE)){
item.removeData(EntityDataStrings.SERVER_COLLIDABLE_TREE);
}
if(item.containsKey(EntityDataStrings.CLIENT_COLLIDABLE_TREE)){
item.removeData(EntityDataStrings.CLIENT_COLLIDABLE_TREE);
}
}
@ -267,9 +399,9 @@ public class ItemUtils {
* @param item The item to recreate
* @param containingParent The parent that contains the item
*/
public static Entity recreateContainerItem(Entity item, Entity containingParent){
public static Entity clientRecreateContainerItem(Entity item, Entity containingParent){
if(isItem(item)){
Entity rVal = new Entity();
Entity rVal = EntityCreationUtils.createClientNonSpatialEntity();
if(getEquipWhitelist(item) != null){
rVal.putData(EntityDataStrings.ITEM_EQUIP_WHITELIST, getEquipWhitelist(item));
}
@ -279,30 +411,76 @@ public class ItemUtils {
rVal.putData(EntityDataStrings.ITEM_IS_IN_INVENTORY, true);
ItemUtils.setContainingParent(rVal, containingParent);
rVal.putData(EntityDataStrings.ITEM_TYPE, item.getData(EntityDataStrings.ITEM_TYPE));
Globals.entityManager.registerEntity(rVal);
Globals.clientSceneWrapper.getScene().registerEntity(rVal);
return rVal;
} else {
return null;
}
}
public static void destroyInWorldItem(Entity item){
/**
* Emits an entity which represents the item inside a container
* @param item The item to recreate
* @param containingParent The parent that contains the item
*/
public static Entity serverRecreateContainerItem(Entity item, Entity containingParent){
if(isItem(item)){
Entity rVal = EntityCreationUtils.createRealmlessServerEntity();
if(getEquipWhitelist(item) != null){
rVal.putData(EntityDataStrings.ITEM_EQUIP_WHITELIST, getEquipWhitelist(item));
}
rVal.putData(EntityDataStrings.ITEM_ICON,ItemUtils.getItemIcon(item));
rVal.putData(EntityDataStrings.ITEM_EQUIP_CLASS, item.getData(EntityDataStrings.ITEM_EQUIP_CLASS));
rVal.putData(EntityDataStrings.ITEM_IS_ITEM, true);
rVal.putData(EntityDataStrings.ITEM_IS_IN_INVENTORY, true);
ItemUtils.setContainingParent(rVal, containingParent);
rVal.putData(EntityDataStrings.ITEM_TYPE, item.getData(EntityDataStrings.ITEM_TYPE));
return rVal;
} else {
return null;
}
}
public static void clientDestroyInWorldItem(Entity item){
if(isItem(item)){
//destroy physics
if(item.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY) && item.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){
//destroy physics
//this deregisters from all four & unhooks rigid bodies from the physics runtime
Globals.collisionEngine.destroyEntityThatHasPhysics(item);
Globals.clientSceneWrapper.getCollisionEngine().destroyEntityThatHasPhysics(item);
//destroy hitboxes
List<Entity> hitboxes = HitboxUtils.getHitboxAssociatedList(item);
if(hitboxes != null){
for(Entity hitbox : hitboxes){
Globals.hitboxManager.deregisterHitbox(hitbox);
Globals.clientHitboxManager.deregisterHitbox(hitbox);
HitboxUtils.getHitboxData(hitbox).setActive(false);
}
}
//destroy graphics
EntityUtils.cleanUpDrawableEntity(item);
EntityUtils.cleanUpEntity(item);
}
}
}
public static void serverDestroyInWorldItem(Entity item){
if(isItem(item)){
//destroy physics
if(item.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY) && item.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){
Realm itemRealm = Globals.realmManager.getEntityRealm(item);
//destroy physics
//this deregisters from all four & unhooks rigid bodies from the physics runtime
itemRealm.getCollisionEngine().destroyEntityThatHasPhysics(item);
//destroy hitboxes
List<Entity> hitboxes = HitboxUtils.getHitboxAssociatedList(item);
if(hitboxes != null){
for(Entity hitbox : hitboxes){
itemRealm.getHitboxManager().deregisterHitbox(hitbox);
HitboxUtils.getHitboxData(hitbox).setActive(false);
}
}
//destroy graphics
EntityUtils.cleanUpEntity(item);
}
}
}
@ -312,7 +490,7 @@ public class ItemUtils {
}
public static void destroyInInventoryItem(Entity item){
Globals.entityManager.deregisterEntity(item);
EntityUtils.cleanUpEntity(item);
}
public static String getItemIcon(Entity item){

View File

@ -1,20 +1,25 @@
package electrosphere.entity.types.object;
import org.joml.Matrix4f;
import org.joml.Vector3d;
import org.joml.Vector3f;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityTags;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.IdleTree;
import electrosphere.entity.state.collidable.CollidableTree;
import electrosphere.entity.state.collidable.ClientCollidableTree;
import electrosphere.entity.state.collidable.ServerCollidableTree;
import electrosphere.entity.state.gravity.GravityTree;
import electrosphere.entity.state.gravity.ServerGravityTree;
import electrosphere.entity.state.idle.IdleTree;
import electrosphere.entity.state.inventory.InventoryState;
import electrosphere.entity.state.inventory.InventoryUtils;
import electrosphere.entity.state.inventory.ServerInventoryState;
import electrosphere.entity.state.inventory.UnrelationalInventoryState;
import electrosphere.entity.state.life.LifeState;
import electrosphere.entity.types.collision.CollisionObjUtils;
@ -24,12 +29,19 @@ import electrosphere.game.data.creature.type.CollidableTemplate;
import electrosphere.game.data.object.type.ObjectData;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.actor.ActorUtils;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.ServerDataCell;
import electrosphere.server.datacell.utils.EntityLookupUtils;
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
import electrosphere.server.datacell.utils.ServerEntityTagUtils;
import electrosphere.server.poseactor.PoseActor;
public class ObjectUtils {
public static Entity spawnBasicObject(String type){
public static Entity clientSpawnBasicObject(String type){
ObjectData rawType = Globals.gameConfigCurrent.getObjectTypeLoader().getObject(type);
Entity rVal = EntityUtils.spawnDrawableEntity(rawType.getModelPath());
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityPoseable(rVal, rawType.getModelPath());
Actor creatureActor = EntityUtils.getActor(rVal);
//forward-searching tokens
boolean collisionMakeDynamic = true;
@ -40,21 +52,21 @@ public class ObjectUtils {
} break;
case "GENERATE_COLLISION_OBJECT": {
Globals.assetManager.addCollisionMeshToQueue(rawType.getModelPath());
Globals.entityManager.registerBehaviorTree(new BehaviorTree() {public void simulate(float deltaTime) {
Globals.clientSceneWrapper.getScene().registerBehaviorTree(new BehaviorTree() {public void simulate(float deltaTime) {
CollisionObject collisionObject = Globals.assetManager.fetchCollisionObject(rawType.getModelPath());
if(collisionObject != null){
Globals.entityManager.deregisterBehaviorTree(this);
CollisionObjUtils.attachCollisionObjectToEntity(rVal, collisionObject, 0, Collidable.TYPE_OBJECT);
Globals.clientSceneWrapper.getScene().deregisterBehaviorTree(this);
CollisionObjUtils.clientAttachCollisionObjectToEntity(rVal, collisionObject, 0, Collidable.TYPE_OBJECT);
}
}});
} break;
case "GENERATE_COLLISION_TERRAIN": {
Globals.assetManager.addCollisionMeshToQueue(rawType.getModelPath());
Globals.entityManager.registerBehaviorTree(new BehaviorTree() {public void simulate(float deltaTime) {
Globals.clientSceneWrapper.getScene().registerBehaviorTree(new BehaviorTree() {public void simulate(float deltaTime) {
CollisionObject collisionObject = Globals.assetManager.fetchCollisionObject(rawType.getModelPath());
if(collisionObject != null){
Globals.entityManager.deregisterBehaviorTree(this);
CollisionObjUtils.attachCollisionObjectToEntity(rVal, collisionObject, 0, Collidable.TYPE_TERRAIN);
Globals.clientSceneWrapper.getScene().deregisterBehaviorTree(this);
CollisionObjUtils.clientAttachCollisionObjectToEntity(rVal, collisionObject, 0, Collidable.TYPE_TERRAIN);
}
}});
} break;
@ -76,8 +88,8 @@ public class ObjectUtils {
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
CollidableTree tree = new CollidableTree(rVal,collidable,rigidBody, collisionMakeDynamic);
rVal.putData(EntityDataStrings.COLLIDABLE_TREE, tree);
ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody, collisionMakeDynamic);
rVal.putData(EntityDataStrings.CLIENT_COLLIDABLE_TREE, tree);
scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3());
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
@ -89,9 +101,9 @@ public class ObjectUtils {
inertiaTensor.m22(mass * scale.x * scale.x / 2.0f);
rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert());
Globals.collisionEngine.registerPhysicsEntity(rVal);
Globals.entityManager.registerBehaviorTree(tree);
Globals.collisionEngine.registerCollisionObject(rigidBody, collidable);
Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(rVal);
Globals.clientSceneWrapper.getScene().registerBehaviorTree(tree);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
} break;
case "CUBE": {
rigidBody = PhysicsUtils.getCubeObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
@ -100,8 +112,8 @@ public class ObjectUtils {
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
CollidableTree tree = new CollidableTree(rVal,collidable,rigidBody, collisionMakeDynamic);
rVal.putData(EntityDataStrings.COLLIDABLE_TREE, tree);
ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody, collisionMakeDynamic);
rVal.putData(EntityDataStrings.CLIENT_COLLIDABLE_TREE, tree);
scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3());
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
@ -110,13 +122,13 @@ public class ObjectUtils {
inertiaTensor = new Matrix4f().identity().scale(mass * scale.x * scale.x / 6.0f).m33(1);
rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert());
Globals.collisionEngine.registerPhysicsEntity(rVal);
Globals.entityManager.registerBehaviorTree(tree);
Globals.collisionEngine.registerCollisionObject(rigidBody, collidable);
Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(rVal);
Globals.clientSceneWrapper.getScene().registerBehaviorTree(tree);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
} break;
}
Globals.collisionEngine.registerDynamicPhysicsEntity(rVal);
Globals.entityManager.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
Globals.clientSceneWrapper.getCollisionEngine().registerDynamicPhysicsEntity(rVal);
Globals.clientSceneWrapper.getScene().registerEntityToTag(rVal, EntityTags.COLLIDABLE);
}
for(String token : rawType.getTokens()){
switch(token){
@ -129,15 +141,163 @@ public class ObjectUtils {
GravityTree gravityTree = new GravityTree(rVal,collidable,collisionObject,30);
// gravityTree.setCollisionObject(collisionObject, collidable);
rVal.putData(EntityDataStrings.GRAVITY_ENTITY, true);
rVal.putData(EntityDataStrings.GRAVITY_TREE, gravityTree);
Globals.entityManager.registerBehaviorTree(gravityTree);
rVal.putData(EntityDataStrings.CLIENT_GRAVITY_TREE, gravityTree);
Globals.clientSceneWrapper.getScene().registerBehaviorTree(gravityTree);
break;
case "TARGETABLE":
Globals.entityManager.registerEntityToTag(rVal, EntityTags.TARGETABLE);
Globals.clientSceneWrapper.getScene().registerEntityToTag(rVal, EntityTags.TARGETABLE);
break;
case "INVENTORY":
rVal.putData(EntityDataStrings.NATURAL_INVENTORY,UnrelationalInventoryState.createUnrelationalInventory(10));
InventoryUtils.setInventoryState(rVal, InventoryState.createInventoryState(rVal));
InventoryUtils.clientSetInventoryState(rVal, InventoryState.clientCreateInventoryState(rVal));
break;
case "OUTLINE":
rVal.putData(EntityDataStrings.DRAW_OUTLINE, true);
break;
case "TERRAIN_COLLISION": {
CollisionObjUtils.getCollidable(rVal).overrideType(Collidable.TYPE_TERRAIN);
} break;
}
}
//add health system
// rVal.putData(EntityDataStrings.LIFE_STATE, new LifeState(rVal, rawType.getHealthSystem()));
// Globals.entityManager.registerLifeStateEntity(rVal);
//idle tree & generic stuff all objects have
rVal.putData(EntityDataStrings.IDLE_TREE, new IdleTree(rVal));
rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
return rVal;
}
/**
* Spawns a server-side object
* @param type The type of object to spawn
* @return The object
*/
public static Entity serverSpawnBasicObject(Realm realm, Vector3d position, String type){
ObjectData rawType = Globals.gameConfigCurrent.getObjectTypeLoader().getObject(type);
Entity rVal = EntityCreationUtils.createServerEntity(realm, position);
EntityCreationUtils.makeEntityPoseable(rVal, rawType.getModelPath());
//register to global entity id lookup table
EntityLookupUtils.registerServerEntity(rVal);
//register to data cell
ServerDataCell entityDataCell = realm.getDataCellManager().tryCreateCellAtPoint(position);
entityDataCell.getScene().registerEntity(rVal);
//maps this entity to its realm
Globals.realmManager.mapEntityToRealm(rVal, realm);
//enable behavior tree tracking
ServerBehaviorTreeUtils.registerEntity(rVal);
PoseActor creatureActor = EntityUtils.getPoseActor(rVal);
//forward-searching tokens
boolean collisionMakeDynamic = true;
for(String token : rawType.getTokens()){
switch(token){
case "DISABLE_COLLISION_REACTION": {
collisionMakeDynamic = false;
} break;
case "GENERATE_COLLISION_OBJECT": {
Globals.assetManager.addCollisionMeshToQueue(rawType.getModelPath());
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, new BehaviorTree() {public void simulate(float deltaTime) {
CollisionObject collisionObject = Globals.assetManager.fetchCollisionObject(rawType.getModelPath());
if(collisionObject != null){
ServerBehaviorTreeUtils.detatchBTreeFromEntity(rVal, this);
CollisionObjUtils.serverAttachCollisionObjectToEntity(rVal, collisionObject, 0, Collidable.TYPE_OBJECT);
}
}});
} break;
case "GENERATE_COLLISION_TERRAIN": {
Globals.assetManager.addCollisionMeshToQueue(rawType.getModelPath());
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, new BehaviorTree() {public void simulate(float deltaTime) {
CollisionObject collisionObject = Globals.assetManager.fetchCollisionObject(rawType.getModelPath());
if(collisionObject != null){
ServerBehaviorTreeUtils.detatchBTreeFromEntity(rVal, this);
CollisionObjUtils.serverAttachCollisionObjectToEntity(rVal, collisionObject, 0, Collidable.TYPE_TERRAIN);
}
}});
} break;
}
}
//main entity construction
if(rawType.getCollidable() != null){
CollidableTemplate physicsTemplate = rawType.getCollidable();
CollisionObject rigidBody;
Collidable collidable;
float mass = 1.0f;
Matrix4f inertiaTensor;
Vector3f scale;
switch(physicsTemplate.getType()){
case "CYLINDER": {
rigidBody = PhysicsUtils.getCylinderObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
collidable = new Collidable(rVal, Collidable.TYPE_OBJECT);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody, collisionMakeDynamic);
rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, tree);
scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3());
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
//inertia tensor
//https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html
inertiaTensor = new Matrix4f();
inertiaTensor.m00(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f);
inertiaTensor.m11(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f);
inertiaTensor.m22(mass * scale.x * scale.x / 2.0f);
rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert());
realm.getCollisionEngine().registerPhysicsEntity(rVal);
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, tree);
realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
} break;
case "CUBE": {
rigidBody = PhysicsUtils.getCubeObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
collidable = new Collidable(rVal, Collidable.TYPE_OBJECT);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody, collisionMakeDynamic);
rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, tree);
scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3());
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
//inertia tensor
//https://hepweb.ucsd.edu/ph110b/110b_notes/node26.html
inertiaTensor = new Matrix4f().identity().scale(mass * scale.x * scale.x / 6.0f).m33(1);
rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert());
realm.getCollisionEngine().registerPhysicsEntity(rVal);
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, tree);
realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
} break;
}
realm.getCollisionEngine().registerDynamicPhysicsEntity(rVal);
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
}
for(String token : rawType.getTokens()){
switch(token){
case "BLENDER_TRANSFORM":
ActorUtils.applyBlenderTransformer(rVal);
break;
case "GRAVITY":
Collidable collidable = (Collidable)rVal.getData(EntityDataStrings.PHYSICS_COLLIDABLE);
CollisionObject collisionObject = (CollisionObject)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
ServerGravityTree gravityTree = new ServerGravityTree(rVal,collidable,collisionObject,30);
// gravityTree.setCollisionObject(collisionObject, collidable);
rVal.putData(EntityDataStrings.GRAVITY_ENTITY, true);
rVal.putData(EntityDataStrings.SERVER_GRAVITY_TREE, gravityTree);
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, gravityTree);
break;
case "TARGETABLE":
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.TARGETABLE);
break;
case "INVENTORY":
rVal.putData(EntityDataStrings.NATURAL_INVENTORY,UnrelationalInventoryState.createUnrelationalInventory(10));
InventoryUtils.serverSetInventoryState(rVal, ServerInventoryState.serverCreateInventoryState(rVal));
break;
case "OUTLINE":
rVal.putData(EntityDataStrings.DRAW_OUTLINE, true);

View File

@ -2,6 +2,7 @@ package electrosphere.entity.types.particle;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityTags;
import electrosphere.entity.EntityUtils;
@ -22,23 +23,25 @@ public class ParticleUtils {
public static Entity spawnBillboardProjectileParticle(String texture, int maxLife, Vector3f destination, float velocity, float acceleration){
Entity rVal = EntityUtils.spawnDrawableEntity(Globals.particleBillboardModel);
public static Entity clientSpawnBillboardProjectileParticle(String texture, int maxLife, Vector3f destination, float velocity, float acceleration){
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(rVal, Globals.particleBillboardModel);
EntityUtils.getActor(rVal).setTextureOverride(texture);
Globals.assetManager.addTexturePathtoQueue(texture);
ParticleTree particleTree = new ParticleTree(rVal, maxLife, destination, velocity, acceleration, true);
rVal.putData(EntityDataStrings.PARTICLE_TREE, particleTree);
rVal.putData(EntityDataStrings.IS_PARTICLE, true);
Globals.entityManager.registerEntityToTag(rVal, EntityTags.PARTICLE);
Globals.clientSceneWrapper.getScene().registerEntityToTag(rVal, EntityTags.PARTICLE);
return rVal;
}
public static Entity spawnStaticBillboardParticle(){
Entity rVal = EntityUtils.spawnDrawableEntity(Globals.particleBillboardModel);
public static Entity clientSpawnStaticBillboardParticle(){
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(rVal, Globals.particleBillboardModel);
ParticleTree particleTree = new ParticleTree(rVal, 10, new Vector3f(0,0,0), 0, 0, false);
rVal.putData(EntityDataStrings.PARTICLE_TREE, particleTree);
rVal.putData(EntityDataStrings.IS_PARTICLE, true);
Globals.entityManager.registerEntityToTag(rVal, EntityTags.PARTICLE);
Globals.clientSceneWrapper.getScene().registerEntityToTag(rVal, EntityTags.PARTICLE);
return rVal;
}

View File

@ -11,16 +11,50 @@ import org.joml.Vector3f;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.movement.ProjectileTree;
import electrosphere.entity.types.hitbox.HitboxUtils;
import electrosphere.entity.types.hitbox.HitboxUtils.HitboxPositionCallback;
import electrosphere.game.data.projectile.ProjectileType;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
public class ProjectileUtils {
public static Entity spawnBasicProjectile(String model, Vector3d initialPosition, Quaternionf rotation, int maxLife, Vector3f initialVector, float velocity){
Entity rVal = EntityUtils.spawnDrawableEntity(model);
/**
* Spawns a basic projectile entity on the client
* @param model The model
* @param initialPosition The initial position
* @param rotation The rotation
* @param maxLife The maximum life
* @param initialVector The initial vector
* @param velocity The velocity
* @return The projectile entity
*/
public static Entity clientSpawnBasicProjectile(String model, Vector3d initialPosition, Quaternionf rotation, int maxLife, Vector3f initialVector, float velocity){
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(rVal, model);
Globals.assetManager.addModelPathToQueue(model);
ProjectileTree tree = new ProjectileTree(rVal,maxLife,new Vector3d(initialVector),velocity);
EntityUtils.getPosition(rVal).set(initialPosition);
EntityUtils.getRotation(rVal).rotationTo(new Vector3f(0,0,1), new Vector3f((float)initialVector.x,(float)initialVector.y,(float)initialVector.z)).normalize();
Globals.clientSceneWrapper.getScene().registerBehaviorTree(tree);
return rVal;
}
/**
* Spawns a basic projectile entity on the server
* @param model The model
* @param initialPosition The initial position
* @param rotation The rotation
* @param maxLife The maximum life
* @param initialVector The initial vector
* @param velocity The velocity
* @return The projectile entity
*/
public static Entity serverSpawnBasicProjectile(Realm realm, String model, Vector3d initialPosition, Quaternionf rotation, int maxLife, Vector3f initialVector, float velocity){
Entity rVal = EntityCreationUtils.createServerEntity(realm, initialPosition);
Globals.assetManager.addModelPathToQueue(model);
ProjectileTree tree = new ProjectileTree(rVal,maxLife,new Vector3d(initialVector),velocity);
EntityUtils.getPosition(rVal).set(initialPosition);
@ -29,7 +63,7 @@ public class ProjectileUtils {
// ParticleTree particleTree = new ParticleTree(rVal, maxLife, destination, velocity, acceleration, true);
// rVal.putData(EntityDataStrings.PARTICLE_TREE, particleTree);
// rVal.putData(EntityDataStrings.IS_PARTICLE, true);
Globals.entityManager.registerBehaviorTree(tree);
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, tree);
return rVal;
}
@ -42,21 +76,53 @@ public class ProjectileUtils {
* @param parent The parent that fired said projectile
* @return The projectile entity
*/
public static Entity spawnProjectile(String projectileType, Vector3d initialPosition, Vector3d initialVector, Entity parent){
public static Entity clientSpawnProjectile(String projectileType, Vector3d initialPosition, Vector3d initialVector, Entity parent){
ProjectileType rawType = Globals.gameConfigCurrent.getProjectileMap().getType(projectileType);
Entity rVal = EntityUtils.spawnDrawableEntity(rawType.getModelPath());
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(rVal, rawType.getModelPath());
//initial coordinates
EntityUtils.getRotation(rVal).rotationTo(new Vector3f(0,0,1), new Vector3f((float)initialVector.x,(float)initialVector.y,(float)initialVector.z)).normalize();
EntityUtils.getPosition(rVal).set(initialPosition);
//projectile behavior tree
ProjectileTree tree = new ProjectileTree(rVal,rawType.getMaxLife(),initialVector,rawType.getVelocity(), rawType.getDamage());
Globals.entityManager.registerBehaviorTree(tree);
Globals.clientSceneWrapper.getScene().registerBehaviorTree(tree);
ProjectileTree.setProjectileTree(rVal, tree);
//filter construction
List<Entity> filter = new LinkedList<Entity>();
filter.add(parent);
//collidable
HitboxUtils.spawnRegularHitbox(rVal, new HitboxPositionCallback() {
HitboxUtils.clientSpawnRegularHitbox(rVal, new HitboxPositionCallback() {
public Vector3d getPosition(){
return EntityUtils.getPosition(rVal);
}
}, rawType.getHitboxRadius(), false, filter);
return rVal;
}
/**
* More sophisticated function for spawning projectiles. Uses the projectiles.json file to store data about types to spawn.
* Also filters the parent from being hit by their own projectiles.
* @param projectileType The type in projectiles.json to spawn
* @param initialPosition The initial position of the projectile
* @param initialVector The initial velocity of the projectile
* @param parent The parent that fired said projectile
* @return The projectile entity
*/
public static Entity serverSpawnProjectile(Realm realm, String projectileType, Vector3d initialPosition, Vector3d initialVector, Entity parent){
ProjectileType rawType = Globals.gameConfigCurrent.getProjectileMap().getType(projectileType);
Entity rVal = EntityCreationUtils.createServerEntity(realm, initialPosition);
//initial coordinates
EntityUtils.getRotation(rVal).rotationTo(new Vector3f(0,0,1), new Vector3f((float)initialVector.x,(float)initialVector.y,(float)initialVector.z)).normalize();
EntityUtils.getPosition(rVal).set(initialPosition);
//projectile behavior tree
ProjectileTree tree = new ProjectileTree(rVal,rawType.getMaxLife(),initialVector,rawType.getVelocity(), rawType.getDamage());
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, tree);
ProjectileTree.setProjectileTree(rVal, tree);
//filter construction
List<Entity> filter = new LinkedList<Entity>();
filter.add(parent);
//collidable
HitboxUtils.serverSpawnRegularHitbox(rVal, new HitboxPositionCallback() {
public Vector3d getPosition(){
return EntityUtils.getPosition(rVal);
}

View File

@ -2,6 +2,7 @@ package electrosphere.entity.types.structure;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.collision.CollisionObjUtils;
@ -11,6 +12,7 @@ import electrosphere.game.data.structure.type.model.StructureType;
import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.net.parser.net.message.NetworkMessage;
import electrosphere.net.server.player.Player;
import electrosphere.server.datacell.Realm;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
@ -25,9 +27,10 @@ import org.joml.Vector4f;
public class StructureUtils {
public static Entity spawnBasicStructure(String type, Vector3f position, Quaternionf rotation){
public static Entity clientSpawnBasicStructure(String type, Vector3f position, Quaternionf rotation){
StructureType rawType = Globals.gameConfigCurrent.getStructureTypeMap().getType(type);
Entity rVal = EntityUtils.spawnDrawableEntity(rawType.getModelPath());
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(rVal, rawType.getModelPath());
EntityUtils.getPosition(rVal).set(position);
EntityUtils.getRotation(rVal).set(rotation);
for(CollisionObjectTemplate template : rawType.getCollision()){
@ -37,7 +40,34 @@ public class StructureUtils {
Vector4f rotatedPosition = rotationTransform.transform(new Vector4f(template.getPositionX(),template.getPositionY(),template.getPositionZ(),1.0f));
Vector3f cubePosition = new Vector3f(position).add(rotatedPosition.x,rotatedPosition.y,rotatedPosition.z);
Quaternionf cubeRotation = new Quaternionf(rotation).mul(new Quaternionf(template.getRotationX(),template.getRotationY(),template.getRotationZ(),template.getRotationW())).normalize();
CollisionObjUtils.attachCollisionCube(new Vector3f(template.getScaleX(),template.getScaleY(),template.getScaleZ()), cubePosition, cubeRotation, rVal);
CollisionObjUtils.clientAttachCollisionCube(new Vector3f(template.getScaleX(),template.getScaleY(),template.getScaleZ()), cubePosition, cubeRotation, rVal);
// Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
// Globals.collisionEngine.registerPhysicsEntity(rVal);
// Globals.collisionEngine.registerCollisionObject(rigidBody, collidable);
break;
case CollisionObjectTemplate.TYPE_PLANE:
throw new UnsupportedOperationException("Haven't implemented plane collision on structures");
}
}
rVal.putData(EntityDataStrings.STRUCTURE_IS_STRUCTURE,true);
rVal.putData(EntityDataStrings.STRUCTURE_TYPE,type);
return rVal;
}
public static Entity serverSpawnBasicStructure(String type, Realm realm, Vector3d position, Quaternionf rotation){
StructureType rawType = Globals.gameConfigCurrent.getStructureTypeMap().getType(type);
Entity rVal = EntityCreationUtils.createServerEntity(realm, position);
EntityCreationUtils.makeEntityPoseable(rVal, rawType.getModelPath());
EntityUtils.getPosition(rVal).set(position);
EntityUtils.getRotation(rVal).set(rotation);
for(CollisionObjectTemplate template : rawType.getCollision()){
switch(template.getType()){
case CollisionObjectTemplate.TYPE_CUBE:
Matrix4f rotationTransform = new Matrix4f().rotate(rotation);
Vector4f rotatedPosition = rotationTransform.transform(new Vector4f(template.getPositionX(),template.getPositionY(),template.getPositionZ(),1.0f));
Vector3f cubePosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).add(rotatedPosition.x,rotatedPosition.y,rotatedPosition.z);
Quaternionf cubeRotation = new Quaternionf(rotation).mul(new Quaternionf(template.getRotationX(),template.getRotationY(),template.getRotationZ(),template.getRotationW())).normalize();
CollisionObjUtils.serverAttachCollisionCube(new Vector3f(template.getScaleX(),template.getScaleY(),template.getScaleZ()), cubePosition, cubeRotation, rVal);
// Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
// Globals.collisionEngine.registerPhysicsEntity(rVal);
// Globals.collisionEngine.registerCollisionObject(rigidBody, collidable);

View File

@ -5,8 +5,10 @@ import org.joml.Vector3f;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.ServerEntityUtils;
import electrosphere.game.client.terrain.manager.ClientTerrainManager;
import electrosphere.game.collision.PhysicsUtils;
import electrosphere.renderer.Model;
@ -156,12 +158,14 @@ public class TerrainChunk {
TerrainChunkData data = TerrainChunkModelGeneration.generateTerrainChunkData(terrainGrid, textureGrid);
String modelPath = ClientTerrainManager.queueTerrainGridGeneration(data);
Entity rVal = EntityUtils.spawnDrawableEntityWithPreexistingModel(modelPath);
PhysicsUtils.attachTerrainChunkRigidBody(rVal, data);
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(rVal, modelPath);
// Entity rVal = EntityUtils.spawnDrawableEntityWithPreexistingModel(modelPath);
PhysicsUtils.clientAttachTerrainChunkRigidBody(rVal, data);
rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
EntityUtils.repositionEntity(rVal, new Vector3d(1,-1,1));
ServerEntityUtils.repositionEntity(rVal, new Vector3d(1,-1,1));
return rVal;
}

View File

@ -19,21 +19,15 @@ public class ClientFunctions {
public static void runBeforeSimulationFunctions(){
//cell tracking values
if(Globals.RUN_CLIENT){
if(Globals.playerEntity != null){
oldPlayerCharacterPosition = new Vector3d(EntityUtils.getPosition(Globals.playerEntity));
}
if(Globals.playerEntity != null){
oldPlayerCharacterPosition = new Vector3d(EntityUtils.getPosition(Globals.playerEntity));
}
}
public static void runClientFunctions(){
if(Globals.clientTerrainManager != null){
Globals.clientTerrainManager.handleMessages();
Globals.clientTerrainManager.ejectLoadedChunks();
}
ClientTerrainManager.generateTerrainChunkGeometry();
updateSkyboxPos();
updateCellManager();
// updateCellManager();
}
static void updateSkyboxPos(){
@ -48,11 +42,19 @@ public class ClientFunctions {
}
}
public static void loadTerrain(){
if(Globals.clientTerrainManager != null){
Globals.clientTerrainManager.handleMessages();
Globals.clientTerrainManager.ejectLoadedChunks();
updateCellManager();
}
}
static void updateCellManager(){
///
/// C L I E N T C E L L M A N A G E R
///
if(Globals.drawCellManager != null){
if(Globals.drawCellManager != null && Globals.clientWorldData != null){
if(Globals.playerEntity != null){
newPlayerCharacterPosition = EntityUtils.getPosition(Globals.playerEntity);
}

View File

@ -4,6 +4,7 @@ import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.dynamics.RigidBody;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.game.collision.PhysicsUtils;
@ -97,7 +98,7 @@ public class DrawCell {
*/
public void generateDrawableEntity(int stride){
if(modelEntity != null){
Globals.entityManager.deregisterEntity(modelEntity);
Globals.clientScene.deregisterEntity(modelEntity);
}
Model terrainModel = RenderUtils.createMinimizedTerrainModelPrecomputedShader(heightmap, texturemap, program, stride);
Mesh terrainMesh = terrainModel.meshes.get(0);
@ -112,7 +113,8 @@ public class DrawCell {
uniformList.add("groundTextures[2]");
uniformList.add("groundTextures[3]");
String terrainModelPath = Globals.assetManager.registerModel(terrainModel);
modelEntity = EntityUtils.spawnDrawableEntity(terrainModelPath);
modelEntity = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(modelEntity, terrainModelPath);
EntityUtils.getActor(modelEntity).addTextureMask(new ActorTextureMask("terrain",textureList,uniformList));
modelEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
modelEntity.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
@ -121,25 +123,25 @@ public class DrawCell {
}
public void retireCell(){
EntityUtils.cleanUpDrawableEntity(modelEntity);
EntityUtils.cleanUpEntity(modelEntity);
}
public void generatePhysics(){
//if we're in no-graphics mode, need to generate the entity
if(modelEntity == null){
modelEntity = EntityUtils.spawnSpatialEntity();
modelEntity = EntityCreationUtils.createClientSpatialEntity();
modelEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
EntityUtils.getPosition(modelEntity).set(new Vector3f(cellX * dynamicInterpolationRatio, 0.0f, cellY * dynamicInterpolationRatio));
}
//then actually perform the attach
physicsObject = PhysicsUtils.attachTerrainRigidBody(modelEntity,heightmap);
Globals.collisionEngine.registerPhysicsEntity(modelEntity);
physicsObject = PhysicsUtils.attachTerrainRigidBody(modelEntity,heightmap,false);
Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(modelEntity);
// System.out.println("generate physics");
}
public void destroyPhysics(){
Globals.collisionEngine.deregisterCollidableEntity(modelEntity);
Globals.collisionEngine.deregisterRigidBody((RigidBody)physicsObject);
Globals.clientSceneWrapper.getCollisionEngine().deregisterCollidableEntity(modelEntity);
Globals.clientSceneWrapper.getCollisionEngine().deregisterRigidBody((RigidBody)physicsObject);
}
}

View File

@ -72,7 +72,13 @@ public class DrawCellManager {
boolean generateDrawables = false;
/**
* DrawCellManager constructor
* @param commonWorldData The common world data
* @param clientTerrainManager The client terrain manager
* @param discreteX The initial discrete position X coordinate
* @param discreteY The initial discrete position Y coordinate
*/
public DrawCellManager(CommonWorldData commonWorldData, ClientTerrainManager clientTerrainManager, int discreteX, int discreteY){
this.commonWorldData = commonWorldData;
worldBoundDiscreteMax = (int)(commonWorldData.getWorldBoundMin().x / commonWorldData.getDynamicInterpolationRatio() * 1.0f);

View File

@ -1,10 +1,11 @@
package electrosphere.game.client.player;
import org.joml.Vector3i;
import electrosphere.logger.LoggerInterface;
public class ClientPlayerData {
int worldPositionX;
int worldPositionY;
Vector3i worldPos;
int simulationRadius = 3;
boolean loaded = false;
@ -16,19 +17,14 @@ public class ClientPlayerData {
return loaded;
}
public void setWorldPosition(int x, int y){
worldPositionX = x;
worldPositionY = y;
public void setWorldPos(Vector3i worldPos){
this.worldPos = worldPos;
LoggerInterface.loggerGameLogic.INFO("Loaded client data");
loaded = true;
}
public int getWorldPositionX() {
return worldPositionX;
}
public int getWorldPositionY() {
return worldPositionY;
public Vector3i getWorldPos() {
return worldPos;
}

View File

@ -2,6 +2,7 @@ package electrosphere.game.client.targeting.crosshair;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityTags;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.camera.CameraEntityUtils;
@ -23,7 +24,8 @@ public class Crosshair {
static boolean crosshairActive = false;
public static void initCrossHairEntity(){
crossHairEntity = EntityUtils.spawnDrawableEntity("/Models/lockoncrosshair1.fbx");
crossHairEntity = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(crossHairEntity, "/Models/lockoncrosshair1.fbx");
EntityUtils.setVisible(crossHairEntity, false);
}
@ -36,7 +38,7 @@ public class Crosshair {
if(!crosshairActive){
Entity target = null;
double dist = 100;
for(Entity entity : Globals.entityManager.getEntitiesWithTag(EntityTags.TARGETABLE)){
for(Entity entity : Globals.clientScene.getEntitiesWithTag(EntityTags.TARGETABLE)){
Vector3d entityPos = EntityUtils.getPosition(entity);
double currentDist = parentPos.distance(entityPos);
double currentAngleDiff = new Vector3d(entityPos).sub(parentPos).normalize().dot(new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera)));

View File

@ -27,9 +27,8 @@ public class ClientTerrainCache {
List<String> cacheList = new CopyOnWriteArrayList<String>();
public ClientTerrainCache(int cacheSize, ClientWorldData clientWorldData){
public ClientTerrainCache(int cacheSize){
this.cacheSize = cacheSize;
this.clientWorldData = clientWorldData;
}
// TerrainChunkValues getChunkValuesAtPoint(int x, int y){
@ -50,7 +49,7 @@ public class ClientTerrainCache {
//USED TO ADD macro values
public void addChunkValuesToCache(int x, int y, float[][] macroValues, long[][] randomizer){
// TerrainChunkValues chunk = new TerrainChunkValues(macroValues, randomizer);
assert clientWorldData != null;
float[][] heightmap = TerrainInterpolator.getBicubicInterpolatedChunk(
macroValues,
@ -93,4 +92,11 @@ public class ClientTerrainCache {
public float[][] getHeightmapAtChunkPoint(int x, int y){
return cacheMap.get(getKey(x,y));
}
public void setClientWorldData(ClientWorldData clientWorldData){
this.clientWorldData = clientWorldData;
}
}

View File

@ -38,9 +38,8 @@ public class ClientTerrainManager {
static List<TerrainChunkGenQueueItem> terrainChunkGenerationQueue = new CopyOnWriteArrayList<TerrainChunkGenQueueItem>();
public ClientTerrainManager(ClientWorldData clientWorldData){
this.clientWorldData = clientWorldData;
terrainCache = new ClientTerrainCache(CACHE_SIZE,clientWorldData);
public ClientTerrainManager(){
terrainCache = new ClientTerrainCache(CACHE_SIZE);
loadingChunkCache = new LoadingChunkCache();
}
@ -116,14 +115,18 @@ public class ClientTerrainManager {
}
break;
case CHUNKLOADSTART:
LoadingChunk newChunk = new LoadingChunk(message.getworldX(),message.getworldY(),(int)message.getvalue(),clientWorldData);
loadingChunkCache.addLoadingChunkToCache(newChunk);
newChunk.incrementMessageCount();
if(clientWorldData != null){
LoadingChunk newChunk = new LoadingChunk(message.getworldX(),message.getworldY(),(int)message.getvalue(),clientWorldData);
loadingChunkCache.addLoadingChunkToCache(newChunk);
newChunk.incrementMessageCount();
} else {
bouncedMessages.add(message);
}
break;
case HEIGHTMAPMODIFICATION:
if(loadingChunkCache.containsKey(loadingChunkCache.getKey(message.getworldX(), message.getworldY()))){
LoadingChunk inProgressChunk = loadingChunkCache.fetch(loadingChunkCache.getKey(message.getworldX(), message.getworldY()));
inProgressChunk.addModification(message.getworldX(), message.getworldY(), message.getlocationX(), message.getlocationY(), message.getvalue());
inProgressChunk.addModification(message.getworldX(), message.getworldZ(), message.getlocationX(), message.getlocationZ(), message.getvalue());
inProgressChunk.incrementMessageCount();
} else {
bouncedMessages.add(message);
@ -148,6 +151,7 @@ public class ClientTerrainManager {
}
public boolean containsHeightmapAtRealPoint(double x, double z){
assert clientWorldData != null;
return terrainCache.containsHeightmapAtChunkPoint(clientWorldData.convertRealToChunkSpace(x), clientWorldData.convertRealToChunkSpace(z));
}
@ -157,6 +161,7 @@ public class ClientTerrainManager {
public double getHeightAtPosition(double x, double y){
assert clientWorldData != null;
//get chunk coordinate space of input x,y
int chunkX = (int)Math.floor(x / clientWorldData.getDynamicInterpolationRatio());
int chunkY = (int)Math.floor(y / clientWorldData.getDynamicInterpolationRatio());
@ -194,6 +199,7 @@ public class ClientTerrainManager {
}
public float[][] getTextureMapAtPoint(int x, int y){
assert clientWorldData != null;
float[][] rVal = new float[clientWorldData.getDynamicInterpolationRatio()][clientWorldData.getDynamicInterpolationRatio()];
rVal[1][1] = 1;
rVal[2][1] = 1;
@ -207,16 +213,18 @@ public class ClientTerrainManager {
}
public void ejectLoadedChunks(){
List<LoadingChunk> chunksToEject = new LinkedList<LoadingChunk>();
for(LoadingChunk chunk : loadingChunkCache.getChunks()){
if(chunk.isComplete() && chunk.getClientWorldData() != null){
float[][] heightMap = chunk.exportFloats();
terrainCache.addFloatsToCache(chunk.getWorldX(), chunk.getWorldY(), heightMap);
chunksToEject.add(chunk);
if(clientWorldData != null){
List<LoadingChunk> chunksToEject = new LinkedList<LoadingChunk>();
for(LoadingChunk chunk : loadingChunkCache.getChunks()){
if(chunk.isComplete() && chunk.getClientWorldData() != null){
float[][] heightMap = chunk.exportFloats();
terrainCache.addFloatsToCache(chunk.getWorldX(), chunk.getWorldY(), heightMap);
chunksToEject.add(chunk);
}
}
for(LoadingChunk loadedChunk : chunksToEject){
loadingChunkCache.remove(loadedChunk);
}
}
for(LoadingChunk loadedChunk : chunksToEject){
loadingChunkCache.remove(loadedChunk);
}
}
@ -236,5 +244,14 @@ public class ClientTerrainManager {
}
terrainChunkGenerationQueue.clear();
}
/**
* Sets the client world data that this terrain manager references
* @param clientWorldData The client world data
*/
public void setClientWorldData(ClientWorldData clientWorldData){
this.clientWorldData = clientWorldData;
this.terrainCache.setClientWorldData(clientWorldData);
}
}

View File

@ -359,11 +359,11 @@ public class CollisionEngine {
/*
Check if the entity is being accelerated by gravity
*/
public boolean gravityCheck(CommonWorldData w, Entity e){
double worldHeight = w.getElevationAtPoint(EntityUtils.getPosition(e));
double entityHeight = EntityUtils.getPosition(e).y;
return entityHeight > worldHeight + 0.1f;
}
// public boolean gravityCheck(CommonWorldData w, Entity e){
// double worldHeight = w.getElevationAtPoint(EntityUtils.getPosition(e));
// double entityHeight = EntityUtils.getPosition(e).y;
// return entityHeight > worldHeight + 0.1f;
// }
public float sweepTest(CollisionObject object, Vector3f startPos, Vector3f endPos){
SphereShape sphere = new SphereShape(0.1f);

View File

@ -11,6 +11,7 @@ import electrosphere.dynamics.RigidBodyConstructionInfo;
import electrosphere.engine.Globals;
import electrosphere.linearmath.DefaultMotionState;
import electrosphere.linearmath.Transform;
import electrosphere.server.datacell.Realm;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
@ -49,7 +50,7 @@ public class PhysicsUtils {
}
public static RigidBody attachTerrainRigidBody(Entity terrain, float[][] heightfield){
public static RigidBody attachTerrainRigidBody(Entity terrain, float[][] heightfield, boolean isServer){
Vector3d position = EntityUtils.getPosition(terrain);
@ -165,8 +166,12 @@ public class PhysicsUtils {
// terrainRigidBody.setFriction(1f);
Globals.collisionEngine.registerCollisionObject(terrainRigidBody, new Collidable(terrain,Collidable.TYPE_TERRAIN));
if(isServer){
Realm terrainRealm = Globals.realmManager.getEntityRealm(terrain);
terrainRealm.getCollisionEngine().registerCollisionObject(terrainRigidBody, new Collidable(terrain,Collidable.TYPE_TERRAIN));
} else {
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainRigidBody, new Collidable(terrain,Collidable.TYPE_TERRAIN));
}
// terrainRigidBody.getAabb(aabbMin, aabbMax);
//
@ -180,7 +185,7 @@ public class PhysicsUtils {
}
public static RigidBody attachTerrainChunkRigidBody(Entity terrain, TerrainChunkData data){
public static RigidBody clientAttachTerrainChunkRigidBody(Entity terrain, TerrainChunkData data){
Vector3d position = EntityUtils.getPosition(terrain);
@ -270,7 +275,111 @@ public class PhysicsUtils {
// terrainRigidBody.setFriction(1f);
Globals.collisionEngine.registerCollisionObject(terrainRigidBody, new Collidable(terrain,Collidable.TYPE_TERRAIN));
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainRigidBody, new Collidable(terrain,Collidable.TYPE_TERRAIN));
// terrainRigidBody.getAabb(aabbMin, aabbMax);
//
// System.out.println("aabbMin: " + aabbMin + " aabbMax: " + aabbMax);
terrain.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, terrainRigidBody);
return terrainRigidBody;
}
public static RigidBody serverAttachTerrainChunkRigidBody(Entity terrain, TerrainChunkData data){
Vector3d position = EntityUtils.getPosition(terrain);
float collisionMargin = 0.08f;
/*
Traditional buffer code not working for some reason
the approach of
https://stackoverflow.com/questions/40855945/lwjgl-mesh-to-jbullet-collider
works much better
IDK why
*/
int numberTriangles = data.getFaceElements().size() / 3;
int triangleStride = 0;
int numberVertices = data.getVertices().size() / 3;
int vertexStride = 0;
float[] vertices = new float[numberVertices * 3];
int vertexInserterPos = 0;
int[] indices = new int[numberTriangles * 3];
int indexInserterPos = 0;
for(float vertexValue : data.getVertices()){
vertices[vertexInserterPos] = vertexValue;
vertexInserterPos++;
}
for(int element : data.getFaceElements()){
indices[indexInserterPos] = element;
indexInserterPos++;
}
javax.vecmath.Vector3f aabbMin = new javax.vecmath.Vector3f();
javax.vecmath.Vector3f aabbMax = new javax.vecmath.Vector3f();
//http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/IndexedMesh.html
electrosphere.collision.shapes.IndexedMesh indexedMesh = new electrosphere.collision.shapes.IndexedMesh();
indexedMesh.numTriangles = indices.length / 3;
indexedMesh.triangleIndexBase = ByteBuffer.allocateDirect(indices.length*Float.BYTES).order(ByteOrder.nativeOrder());
indexedMesh.triangleIndexBase.asIntBuffer().put(indices);
indexedMesh.triangleIndexStride = 3 * Float.BYTES;
indexedMesh.numVertices = vertices.length / 3;
indexedMesh.vertexBase = ByteBuffer.allocateDirect(vertices.length*Float.BYTES).order(ByteOrder.nativeOrder());
indexedMesh.vertexBase.asFloatBuffer().put(vertices);
indexedMesh.vertexStride = 3 * Float.BYTES;
//http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shpaes/TriangleIndexVertexArray.html
electrosphere.collision.shapes.TriangleIndexVertexArray triangleIndexArray = new electrosphere.collision.shapes.TriangleIndexVertexArray();
triangleIndexArray.addIndexedMesh(indexedMesh); //this assumes the scalar type is integer (assumes bytebuffer is actually integer
// triangleIndexArray.calculateAabbBruteForce(aabbMin, aabbMax);
//http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/BvhTriangleMeshShape.html
electrosphere.collision.shapes.BvhTriangleMeshShape terrainShape = new electrosphere.collision.shapes.BvhTriangleMeshShape(
triangleIndexArray,
true // "useQuantizedAabbCompression" -- apparently means better memory usage ( http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/BvhTriangleMeshShape.html )
);
//uncomment if we start falling through things again
terrainShape.setMargin(collisionMargin);
// terrainShape.localGetSupportingVertex(new javax.vecmath.Vector3f(1,0,0), aabbMin);
// terrainShape.recalcLocalAabb();
// terrainShape.getLocalAabbMin(aabbMin);
// terrainShape.getLocalAabbMax(aabbMax);
DefaultMotionState defaultMotionState = new DefaultMotionState(new Transform(new javax.vecmath.Matrix4f(new javax.vecmath.Quat4f(0,0,0,1),new javax.vecmath.Vector3f((float)position.x,(float)position.y,(float)position.z),1.0f)));
RigidBodyConstructionInfo terrainRigidBodyCI = new RigidBodyConstructionInfo(0, defaultMotionState, terrainShape);
RigidBody terrainRigidBody = new RigidBody(terrainRigidBodyCI);
// terrainRigidBody.setFriction(1f);
Realm terrainRealm = Globals.realmManager.getEntityRealm(terrain);
terrainRealm.getCollisionEngine().registerCollisionObject(terrainRigidBody, new Collidable(terrain,Collidable.TYPE_TERRAIN));
// terrainRigidBody.getAabb(aabbMin, aabbMax);
//

View File

@ -20,7 +20,7 @@ public class ParticleEffects {
Vector3f direction = new Vector3f(rand.nextFloat() - 0.5f,rand.nextFloat() - 0.5f,rand.nextFloat() - 0.5f).normalize();
float velocity = rand.nextFloat() * 0.01f;
float acceleration = 0.005f;
Entity spark = ParticleUtils.spawnBillboardProjectileParticle("Textures/spark1.png", 15, direction, velocity, acceleration);
Entity spark = ParticleUtils.clientSpawnBillboardProjectileParticle("Textures/spark1.png", 15, direction, velocity, acceleration);
EntityUtils.getPosition(spark).set(position);
EntityUtils.getScale(spark).mul(0.03f);
}
@ -33,7 +33,7 @@ public class ParticleEffects {
Vector3f direction = new Vector3f(rand.nextFloat() - 0.5f,rand.nextFloat() - 0.5f,rand.nextFloat() - 0.5f).normalize();
float velocity = rand.nextFloat() * 0.001f;
float acceleration = 0.000005f;
Entity spark = ParticleUtils.spawnBillboardProjectileParticle("Textures/bloodsplat1.png", 90, direction, velocity, acceleration);
Entity spark = ParticleUtils.clientSpawnBillboardProjectileParticle("Textures/bloodsplat1.png", 90, direction, velocity, acceleration);
EntityUtils.getPosition(spark).set(position);
EntityUtils.getScale(spark).mul(0.1f);
}

View File

@ -4,10 +4,13 @@ import electrosphere.engine.Globals;
import electrosphere.entity.types.structure.StructureUtils;
import electrosphere.game.data.structure.type.model.StructureType;
import electrosphere.game.server.character.Character;
import electrosphere.server.datacell.Realm;
import java.util.LinkedList;
import java.util.List;
import org.joml.Quaternionf;
import org.joml.Vector2f;
import org.joml.Vector3d;
import org.joml.Vector3f;
/**
@ -37,7 +40,8 @@ public class VirtualStructureUtils {
Globals.serverTerrainManager.deformTerrainAtLocationToValue(newWorldX, newWorldY, (int)(newLocationX), (int)(newLocationY), (float)centerHeight);
}
}
StructureUtils.spawnBasicStructure(type, new Vector3f(posX,(float)centerHeight + 2.4f,posY), new Quaternionf());
Realm realm = Globals.realmManager.getRealms().iterator().next();
StructureUtils.serverSpawnBasicStructure(type, realm, new Vector3d(posX,(float)centerHeight + 2.4f,posY), new Quaternionf());
return rVal;
}

View File

@ -1,34 +0,0 @@
package electrosphere.game.server.unit;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.attach.AttachUtils;
import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.server.ai.creature.MillAbout;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
/**
*
* @author amaterasu
*/
public class UnitUtils {
public static void spawnTextGoblin(float posX, float posY, float posZ){
Entity goblin = CreatureUtils.spawnBasicCreature("Goblin",null);
CollisionObjUtils.positionCharacter(goblin, new Vector3d(posX, posY, posZ));
EntityUtils.getScale(goblin).set(0.005f);
//give evil goblin sword
Entity goblinSword = ItemUtils.spawnBasicItem("Katana");
AttachUtils.attachEntityToEntityAtBone(goblin, goblinSword, "Bone.031", new Quaternionf());
//attach ai to evil goblin
MillAbout.attachToCreature(goblin);
// MindlessAttacker.attachToCreature(goblin);
}
}

View File

@ -41,6 +41,7 @@ public class ServerWorldData {
Vector3f worldMaxPoint;
int worldSizeDiscrete;
int worldSizeDiscreteVertical;
int dynamicInterpolationRatio;
float randomDampener;
boolean isArena = false;
@ -52,6 +53,7 @@ public class ServerWorldData {
rVal.worldMaxPoint = new Vector3f(200,0,200);
rVal.dynamicInterpolationRatio = 100;
rVal.worldSizeDiscrete = 2;
rVal.worldSizeDiscreteVertical = 1;
rVal.randomDampener = 0.0f;
rVal.isArena = true;
return rVal;
@ -67,6 +69,7 @@ public class ServerWorldData {
rVal.dynamicInterpolationRatio = terrainManager.getDynamicInterpolationRatio();
rVal.worldSizeDiscrete = terrainManager.getWorldDiscreteSize();
rVal.worldSizeDiscreteVertical = 128;
rVal.randomDampener = terrainManager.getRandomDampener();
return rVal;

View File

@ -21,11 +21,11 @@ public class LoggerInterface {
public static void initLoggers(){
loggerStartup = new Logger(LogLevel.WARNING);
loggerNetworking = new Logger(LogLevel.WARNING);
loggerNetworking = new Logger(LogLevel.DEBUG);
loggerFileIO = new Logger(LogLevel.WARNING);
loggerGameLogic = new Logger(LogLevel.WARNING);
loggerRenderer = new Logger(LogLevel.WARNING);
loggerEngine = new Logger(LogLevel.WARNING);
loggerEngine = new Logger(LogLevel.DEBUG);
loggerAuth = new Logger(LogLevel.WARNING);
loggerDB = new Logger(LogLevel.WARNING);
loggerStartup.INFO("Initialized loggers");

View File

@ -1,357 +0,0 @@
package electrosphere.menu;
import electrosphere.audio.AudioSource;
import electrosphere.audio.AudioUtils;
import electrosphere.controls.ControlHandler;
import electrosphere.controls.ControlHandler.ControlsState;
import electrosphere.engine.Globals;
import electrosphere.engine.LoadingThread;
import electrosphere.engine.Main;
import electrosphere.net.NetUtils;
import electrosphere.net.client.ClientNetworking;
import electrosphere.renderer.ui.DrawableElement;
import electrosphere.renderer.ui.elements.Label;
import electrosphere.server.saves.SaveUtils;
import org.joml.Vector3f;
/**
*
* @author amaterasu
*/
public class MenuCallbacks {
// public static void selectOption(Menu m){
// switch(m.getType()){
// case TITLE_MENU:
// switch(((TextBox)m.getCurrentOption()).getText()){
// //single player
// case "SINGLEPLAYER":
// // m.dispose();
// // Globals.loadingThread = new LoadingThread(LoadingThread.LOAD_MAIN_GAME);
// // Globals.RUN_CLIENT = true;
// // Globals.RUN_SERVER = true;
// // Globals.loadingThread.start();
// m.dispose();
// Globals.currentMenu = MenuGenerators.createWorldSelectMenu();
// break;
// //multi player
// case "MULTIPLAYER":
// m.dispose();
// Globals.currentMenu = MenuGenerators.createMultiplayerMenu();
// break;
// //arena
// case "ARENA":
// m.dispose();
// Globals.loadingThread = new LoadingThread(LoadingThread.LOAD_ARENA);
// Globals.RUN_CLIENT = true;
// Globals.RUN_SERVER = true;
// Globals.loadingThread.start();
// break;
// //options
// case "OPTIONS":
// m.dispose();
// Globals.currentMenu = MenuGenerators.createOptionsMainMenu();
// break;
// //test
// case "UI TESTING":
// m.dispose();
// Globals.currentMenu = MenuGenerators.createTestMainMenu();
// break;
// }
// break;
// case WORLD_SELECT_MENU:
// switch(((TextBox)m.getCurrentOption()).getText()){
// case "CREATE WORLD":
// m.dispose();
// Globals.currentMenu = MenuGenerators.createWorldCreationMenu();
// break;
// default:
// String worldName = ((TextBox)m.getCurrentOption()).getText();
// m.dispose();
// //check if has save or not
// if(SaveUtils.worldHasSave(worldName.toLowerCase())){
// Globals.loadingThread = new LoadingThread(LoadingThread.LOAD_MAIN_GAME);
// Globals.RUN_CLIENT = true;
// Globals.RUN_SERVER = true;
// Globals.loadingThread.start();
// } else {
// Globals.currentSaveName = worldName.toLowerCase();
// SaveUtils.loadTerrainAndCreateWorldData();
// Globals.currentMenu = MenuGenerators.createSaveCreationMenu();
// }
// break;
// }
// break;
// case WORLD_CREATE_MENU:
// break;
// case SAVE_CREATE_MENU:
// switch(((TextBox)m.getCurrentOption()).getText()){
// case "SAVE":
// m.dispose();
// SaveUtils.saveWorldDataToSave(Globals.currentSaveName);
// Globals.currentMenu = MenuGenerators.createWorldSelectMenu();
// break;
// case "CANCEL":
// m.dispose();
// Globals.currentMenu = MenuGenerators.createWorldSelectMenu();
// break;
// }
// break;
// case CHARACTER_CREATE_MENU:
// break;
// case FINALIZE_SAVE_CREATION_MENU:
// break;
// case MULTIPLAYER_MENU:
// switch(((TextBox)m.getCurrentOption()).getText()){
// //HOST
// case "HOST":
// m.dispose();
// Globals.loadingThread = new LoadingThread(LoadingThread.LOAD_MAIN_GAME);
// Globals.RUN_CLIENT = true;
// Globals.RUN_SERVER = true;
// Globals.loadingThread.start();
// break;
// //JOIN
// case "JOIN":
// m.dispose();
// Globals.currentMenu = MenuGenerators.createIPMenu();
// break;
// //back
// case "BACK":
// backout(m);
// break;
// }
// break;
// case IP_MENU:
// switch(((TextBox)m.getCurrentOption()).getText()){
// //connect
// case "CONNECT":
// NetUtils.setAddress( ( (TextBox)m.getOptions().get(0) ).getText() );
// NetUtils.setPort( Integer.parseInt( ( (TextBox)m.getOptions().get(1) ).getText() ) );
// m.dispose();
// Globals.loadingThread = new LoadingThread(LoadingThread.LOAD_MAIN_GAME);
// Globals.RUN_CLIENT = true;
// Globals.RUN_SERVER = false;
// Globals.loadingThread.start();
// break;
// //back
// case "BACK":
// backout(m);
// break;
// }
// break;
// case IN_GAME_MAIN_MENU:
// switch(((Label)m.getCurrentOption()).getText()){
// //connect
// case "QUIT":
// //TODO: actually shut down program
// Globals.ENGINE_SHUTDOWN_FLAG = true;
// break;
// //back
// case "BACK":
// MenuGenerators.makeMenuUndrawable(Globals.currentMenu);
// Globals.currentMenu.dispose();
// Globals.controlHandler.setHandlerState(ControlsState.MAIN_GAME);
// break;
// }
// break;
// }
// }
// public static void backout(Menu m){
// AudioSource startupSound = AudioUtils.playAudioAtLocation("/Audio/MenuBackspace.ogg", new Vector3f(0,0,0));
// switch(m.getType()){
// case TITLE_MENU:
// Main.running = false;
// break;
// case WORLD_SELECT_MENU:
// m.dispose();
// Globals.currentMenu = MenuGenerators.createTitleMenu();
// break;
// case WORLD_CREATE_MENU:
// m.dispose();
// Globals.currentMenu = MenuGenerators.createWorldSelectMenu();
// break;
// case SAVE_CREATE_MENU:
// m.dispose();
// Globals.currentMenu = MenuGenerators.createWorldSelectMenu();
// break;
// case CHARACTER_CREATE_MENU:
// m.dispose();
// Globals.currentMenu = MenuGenerators.createSaveCreationMenu();
// break;
// case FINALIZE_SAVE_CREATION_MENU:
// m.dispose();
// Globals.currentMenu = MenuGenerators.createCharacterCreationMenu();
// break;
// case MULTIPLAYER_MENU:
// m.dispose();
// Globals.currentMenu = MenuGenerators.createTitleMenu();
// break;
// case IP_MENU:
// m.dispose();
// Globals.currentMenu = MenuGenerators.createMultiplayerMenu();
// break;
// case OPTIONS_MAIN_MENU:
// m.dispose();
// Globals.currentMenu = MenuGenerators.createTitleMenu();
// break;
// case TEST:
// m.dispose();
// Globals.currentMenu = MenuGenerators.createTitleMenu();
// break;
// case IN_GAME_MAIN_MENU:
// MenuGenerators.makeMenuUndrawable(Globals.currentMenu);
// Globals.currentMenu.dispose();
// Globals.controlHandler.setHandlerState(ControlsState.MAIN_GAME);
// break;
// case INVENTORY_NATURAL:
// MenuGenerators.makeMenuUndrawable(Globals.currentMenu);
// Globals.currentMenu.dispose();
// Globals.controlHandler.setHandlerState(ControlsState.MAIN_GAME);
// Globals.controlHandler.hideMouse();
// break;
// }
// }
// public static void menuHandleKeypress(Menu m, String keycode){
// char toWrite = ' ';
// DrawableElement currentOption = m.getCurrentOption();
// boolean backspace = false;
// switch(keycode){
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_BACKSPACE:
// if(currentOption instanceof TextBox){
// TextBox currentTextBox = (TextBox)currentOption;
// String currentText = currentTextBox.getText();
// if(currentText.length() > 0){
// currentTextBox.setText(currentText.substring(0, currentText.length() - 1));
// AudioSource startupSound = AudioUtils.playAudioAtLocation("/Audio/MenuBackspace.ogg", new Vector3f(0,0,0));
// }
// }
// backspace = true;
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_0:
// toWrite = '0';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_1:
// toWrite = '1';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_2:
// toWrite = '2';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_3:
// toWrite = '3';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_4:
// toWrite = '4';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_5:
// toWrite = '5';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_6:
// toWrite = '6';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_7:
// toWrite = '7';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_8:
// toWrite = '8';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_9:
// toWrite = '9';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_A:
// toWrite = 'A';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_B:
// toWrite = 'B';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_C:
// toWrite = 'C';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_D:
// toWrite = 'D';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_E:
// toWrite = 'E';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_F:
// toWrite = 'F';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_G:
// toWrite = 'G';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_H:
// toWrite = 'H';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_I:
// toWrite = 'I';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_J:
// toWrite = 'J';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_K:
// toWrite = 'K';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_L:
// toWrite = 'L';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_M:
// toWrite = 'M';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_N:
// toWrite = 'N';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_O:
// toWrite = 'O';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_P:
// toWrite = 'P';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_Q:
// toWrite = 'Q';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_R:
// toWrite = 'R';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_S:
// toWrite = 'S';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_T:
// toWrite = 'T';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_U:
// toWrite = 'U';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_V:
// toWrite = 'V';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_W:
// toWrite = 'W';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_X:
// toWrite = 'X';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_Y:
// toWrite = 'Y';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_Z:
// toWrite = 'Z';
// break;
// case ControlHandler.DATA_STRING_INPUT_CODE_MENU_TYPE_PERIOD:
// toWrite = '.';
// break;
// }
// if(!backspace){
// if(currentOption instanceof TextBox){
// TextBox currentTextBox = (TextBox)currentOption;
// String currentText = currentTextBox.getText();
// if(currentText.length() < currentTextBox.getCols()){
// currentTextBox.setText(currentText + toWrite);
// AudioSource startupSound = AudioUtils.playAudioAtLocation("/Audio/MenuType.ogg", new Vector3f(0,0,0));
// }
// }
// }
// }
}

View File

@ -7,8 +7,8 @@ import org.joml.Vector3f;
import electrosphere.auth.AuthenticationManager;
import electrosphere.controls.ControlHandler.ControlsState;
import electrosphere.engine.Globals;
import electrosphere.engine.LoadingThread;
import electrosphere.engine.Main;
import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
@ -83,7 +83,7 @@ public class MenuGenerators {
clientThread.start();
} else {
Globals.currentSaveName = saveName.toLowerCase();
SaveUtils.loadTerrainAndCreateWorldData();
SaveUtils.loadTerrainAndCreateWorldData(saveName.toLowerCase());
WindowUtils.replaceMainMenuContents(MenuGenerators.createSaveCreationMenu());
}
return false;

View File

@ -2,7 +2,7 @@ package electrosphere.menu;
import electrosphere.auth.AuthenticationManager;
import electrosphere.engine.Globals;
import electrosphere.engine.LoadingThread;
import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.net.NetUtils;
import electrosphere.renderer.ui.ClickableElement;
import electrosphere.renderer.ui.Element;

View File

@ -1,7 +1,7 @@
package electrosphere.menu;
import electrosphere.engine.Globals;
import electrosphere.engine.LoadingThread;
import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.renderer.ui.ClickableElement;
import electrosphere.renderer.ui.Element;
import electrosphere.renderer.ui.elements.Button;

View File

@ -1,7 +1,7 @@
package electrosphere.net.client.protocol;
import electrosphere.engine.Globals;
import electrosphere.engine.LoadingThread;
import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.net.parser.net.message.CharacterMessage;
import electrosphere.net.parser.net.message.TerrainMessage;

View File

@ -6,6 +6,7 @@ import org.joml.Vector3d;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.entity.ClientEntityUtils;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.attach.AttachUtils;
@ -32,44 +33,42 @@ public class EntityProtocol {
// EntityUtils.setEntityID(newlySpawnedEntity, message.getentityID());
break;
case 1:
newlySpawnedEntity = ItemUtils.spawnBasicItem(message.getentitySubtype());
newlySpawnedEntity = ItemUtils.clientSpawnBasicItem(message.getentitySubtype());
EntityUtils.getScale(newlySpawnedEntity).set(0.005f);
EntityUtils.getPosition(newlySpawnedEntity).set(message.getpositionX(),message.getpositionY(),message.getpositionZ());
Globals.entityManager.mapIdToId(newlySpawnedEntity.getId(), message.getentityID());
Globals.clientSceneWrapper.mapIdToId(newlySpawnedEntity.getId(), message.getentityID());
break;
}
break;
case SPAWNCREATURE:
if(!Globals.RUN_SERVER){
LoggerInterface.loggerNetworking.DEBUG("Spawn Creature " + message.getentityID() + " at " + message.getpositionX() + " " + message.getpositionY() + " " + message.getpositionZ());
CreatureTemplate template = Utilities.deserialize(message.getcreatureTemplate(), CreatureTemplate.class);
newlySpawnedEntity = CreatureUtils.spawnBasicCreature(template.getCreatureType(),template);
EntityUtils.getScale(newlySpawnedEntity).set(0.005f);
EntityUtils.getPosition(newlySpawnedEntity).set(message.getpositionX(),message.getpositionY(),message.getpositionZ());
Globals.entityManager.mapIdToId(newlySpawnedEntity.getId(), message.getentityID());
}
LoggerInterface.loggerNetworking.DEBUG("Spawn Creature " + message.getentityID() + " at " + message.getpositionX() + " " + message.getpositionY() + " " + message.getpositionZ());
CreatureTemplate template = Utilities.deserialize(message.getcreatureTemplate(), CreatureTemplate.class);
newlySpawnedEntity = CreatureUtils.clientSpawnBasicCreature(template.getCreatureType(),template);
EntityUtils.getScale(newlySpawnedEntity).set(0.005f);
EntityUtils.getPosition(newlySpawnedEntity).set(message.getpositionX(),message.getpositionY(),message.getpositionZ());
Globals.clientSceneWrapper.mapIdToId(newlySpawnedEntity.getId(), message.getentityID());
break;
case SPAWNITEM:
if(!Globals.RUN_SERVER){
LoggerInterface.loggerNetworking.DEBUG("Spawn Item " + message.getentityID() + " at " + message.getpositionX() + " " + message.getpositionY() + " " + message.getpositionZ());
//spawn item
String itemType = message.getcreatureTemplate();
newlySpawnedEntity = ItemUtils.spawnBasicItem(itemType);
newlySpawnedEntity = ItemUtils.clientSpawnBasicItem(itemType);
//position
EntityUtils.initiallyPositionEntity(newlySpawnedEntity, new Vector3d(message.getpositionX(),message.getpositionY(),message.getpositionZ()));
Globals.entityManager.mapIdToId(newlySpawnedEntity.getId(), message.getentityID());
ClientEntityUtils.initiallyPositionEntity(newlySpawnedEntity, new Vector3d(message.getpositionX(),message.getpositionY(),message.getpositionZ()));
Globals.clientSceneWrapper.mapIdToId(newlySpawnedEntity.getId(), message.getentityID());
}
break;
case DESTROY:
//only obey if we're not also the server
if(!Globals.RUN_SERVER){
Globals.entityManager.deregisterEntity(Globals.entityManager.getEntityFromServerId(message.getentityID()));
EntityUtils.cleanUpEntity(Globals.clientSceneWrapper.getEntityFromServerId(message.getentityID()));
}
break;
case MOVE:
//literally just adding this to scope so I can use `` Entity target; `` again
if(message.getentityID() != -1){
Entity target = Globals.entityManager.getEntityFromServerId(message.getentityID());
Entity target = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityID());
LoggerInterface.loggerNetworking.DEBUG("ID: " + message.getentityID());
if(target != null){
EntityUtils.getPosition(target).set(message.getpositionX(),message.getpositionY(),message.getpositionZ());
@ -79,31 +78,35 @@ public class EntityProtocol {
break;
case SETBEHAVIORTREE:
break;
case SETPROPERTY:
if(message.getpropertyType()== 0){
Entity target = Globals.entityManager.getEntityFromServerId(message.getentityID());
if(target != null){
CreatureUtils.setControllerPlayerId(target, message.getpropertyValue());
if(Globals.clientPlayer != null && message.getpropertyValue() == Globals.clientPlayer.getId()){
Globals.clientCharacterID = message.getentityID();
Globals.playerEntity = target;
case SETPROPERTY: {
if(Globals.clientSceneWrapper.serverToClientMapContainsId(message.getentityID())){
if(message.getpropertyType() == 0){
Entity target = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityID());
if(target != null){
CreatureUtils.setControllerPlayerId(target, message.getpropertyValue());
if(Globals.clientPlayer != null && message.getpropertyValue() == Globals.clientPlayer.getId()){
Globals.clientCharacterID = message.getentityID();
Globals.playerEntity = target;
}
}
}
} else {
//TODO: bounce message
}
break;
} break;
case ATTACHENTITYTOENTITY:
Entity child = Globals.entityManager.getEntityFromServerId(message.getentityID());
Entity parent = Globals.entityManager.getEntityFromServerId(message.gettargetID());
Entity child = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityID());
Entity parent = Globals.clientSceneWrapper.getEntityFromServerId(message.gettargetID());
LoggerInterface.loggerNetworking.DEBUG("Attach " + message.getentityID() + " to " + message.gettargetID() + " on bone " + message.getbone());
if(child != null && parent != null){
AttachUtils.attachEntityToEntityAtBone(parent, child, message.getbone(), new Quaternionf());
AttachUtils.clientAttachEntityToEntityAtBone(parent, child, message.getbone(), new Quaternionf());
}
break;
case MOVEUPDATE:
CreatureUtils.attachEntityMessageToMovementTree(Globals.entityManager.getEntityFromServerId(message.getentityID()),message);
CreatureUtils.clientAttachEntityMessageToMovementTree(Globals.clientSceneWrapper.getEntityFromServerId(message.getentityID()),message);
break;
case ATTACKUPDATE:
CreatureUtils.attachEntityMessageToAttackTree(Globals.entityManager.getEntityFromServerId(message.getentityID()),message);
CreatureUtils.attachEntityMessageToAttackTree(Globals.clientSceneWrapper.getEntityFromServerId(message.getentityID()),message);
break;
case KILL:
break;

View File

@ -17,7 +17,7 @@ public class InventoryProtocol {
LoggerInterface.loggerNetworking.DEBUG("[CLIENT] ADD ITEM TO INVENTORY " + message.getentityId());
if(Globals.playerEntity != null){
InventoryState inventoryState;
if((inventoryState = InventoryUtils.getInventoryState(Globals.playerEntity))!=null){
if((inventoryState = InventoryUtils.clientGetInventoryState(Globals.playerEntity))!=null){
inventoryState.addNetworkMessage(message);
}
}
@ -25,12 +25,12 @@ public class InventoryProtocol {
case SERVERCOMMANDEQUIPITEM: {
LoggerInterface.loggerNetworking.DEBUG("[CLIENT] EQUIP ITEM " + message.getentityId());
//translate equipper id
Entity equipper = Globals.entityManager.getEntityFromId(Globals.entityManager.mapServerToClientId(message.getequipperId()));
Entity equipper = Globals.clientSceneWrapper.getEntityFromServerId(message.getequipperId());
//spawn in world id
Entity inWorldEntity = ItemUtils.spawnBasicItem(message.getitemTemplate());
Entity inWorldEntity = ItemUtils.clientSpawnBasicItem(message.getitemTemplate());
if(inWorldEntity != null){
//translate id
Globals.entityManager.mapIdToId(inWorldEntity.getId(), message.getentityId());
Globals.clientSceneWrapper.mapIdToId(inWorldEntity.getId(), message.getentityId());
//grab equip state
EquipState equipState = EquipState.getEquipState(equipper);
//create entity from template in message
@ -46,7 +46,7 @@ public class InventoryProtocol {
LoggerInterface.loggerNetworking.DEBUG("[CLIENT] REMOVE ITEM FROM INVENTORY " + message.getentityId());
if(Globals.playerEntity != null){
InventoryState inventoryState;
if((inventoryState = InventoryUtils.getInventoryState(Globals.playerEntity))!=null){
if((inventoryState = InventoryUtils.clientGetInventoryState(Globals.playerEntity))!=null){
inventoryState.addNetworkMessage(message);
}
}
@ -55,7 +55,7 @@ public class InventoryProtocol {
LoggerInterface.loggerNetworking.DEBUG("[CLIENT] MOVE ITEM INVENTORY " + message.getentityId());
if(Globals.playerEntity != null){
InventoryState inventoryState;
if((inventoryState = InventoryUtils.getInventoryState(Globals.playerEntity))!=null){
if((inventoryState = InventoryUtils.clientGetInventoryState(Globals.playerEntity))!=null){
inventoryState.addNetworkMessage(message);
}
}
@ -64,7 +64,7 @@ public class InventoryProtocol {
LoggerInterface.loggerNetworking.DEBUG("[CLIENT] UNEQUIP ITEM " + message.getentityId());
if(Globals.playerEntity != null){
InventoryState inventoryState;
if((inventoryState = InventoryUtils.getInventoryState(Globals.playerEntity))!=null){
if((inventoryState = InventoryUtils.clientGetInventoryState(Globals.playerEntity))!=null){
inventoryState.addNetworkMessage(message);
}
}

View File

@ -1,5 +1,7 @@
package electrosphere.net.client.protocol;
import org.joml.Vector3i;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.logger.LoggerInterface;
@ -15,7 +17,7 @@ public class PlayerProtocol {
LoggerInterface.loggerNetworking.DEBUG("Player ID is " + Globals.clientPlayer.getId());
break;
case SETINITIALDISCRETEPOSITION:
Globals.clientPlayerData.setWorldPosition(message.getinitialDiscretePositionX(), message.getinitialDiscretePositionY());
Globals.clientPlayerData.setWorldPos(new Vector3i(message.getinitialDiscretePositionX(), message.getinitialDiscretePositionY(), message.getinitialDiscretePositionZ()));
break;
}
}

View File

@ -22,13 +22,14 @@ public class TerrainProtocol {
message.getrandomDampener(),
message.getworldSizeDiscrete()
);
Globals.clientTerrainManager.setClientWorldData(Globals.clientWorldData);
Globals.clientConnection.getClientProtocol().setHasReceivedWorld(true);
break;
case MACROVALUE:
Globals.clientTerrainManager.attachTerrainMessage(message);
break;
case SPAWNPOSITION:
Globals.spawnPoint.set(message.getrealLocationX(),0.25,message.getrealLocationY());
Globals.spawnPoint.set(message.getrealLocationX(),0.25,message.getrealLocationZ());
break;
case CHUNKLOADSTART:
Globals.clientTerrainManager.attachTerrainMessage(message);

View File

@ -15,6 +15,7 @@ public class PlayerMessage extends NetworkMessage {
int playerID;
int initialDiscretePositionX;
int initialDiscretePositionY;
int initialDiscretePositionZ;
PlayerMessage(PlayerMessageType messageType){
this.type = MessageType.PLAYER_MESSAGE;
@ -49,6 +50,14 @@ public class PlayerMessage extends NetworkMessage {
this.initialDiscretePositionY = initialDiscretePositionY;
}
public int getinitialDiscretePositionZ() {
return initialDiscretePositionZ;
}
public void setinitialDiscretePositionZ(int initialDiscretePositionZ) {
this.initialDiscretePositionZ = initialDiscretePositionZ;
}
static void stripPacketHeader(List<Byte> byteStream){
byteStream.remove(0);
byteStream.remove(0);
@ -91,13 +100,15 @@ public class PlayerMessage extends NetworkMessage {
stripPacketHeader(byteStream);
rVal.setinitialDiscretePositionX(ByteStreamUtils.popIntFromByteQueue(byteStream));
rVal.setinitialDiscretePositionY(ByteStreamUtils.popIntFromByteQueue(byteStream));
rVal.setinitialDiscretePositionZ(ByteStreamUtils.popIntFromByteQueue(byteStream));
return rVal;
}
public static PlayerMessage constructSetInitialDiscretePositionMessage(int initialDiscretePositionX,int initialDiscretePositionY){
public static PlayerMessage constructSetInitialDiscretePositionMessage(int initialDiscretePositionX,int initialDiscretePositionY,int initialDiscretePositionZ){
PlayerMessage rVal = new PlayerMessage(PlayerMessageType.SETINITIALDISCRETEPOSITION);
rVal.setinitialDiscretePositionX(initialDiscretePositionX);
rVal.setinitialDiscretePositionY(initialDiscretePositionY);
rVal.setinitialDiscretePositionZ(initialDiscretePositionZ);
rVal.serialize();
return rVal;
}
@ -119,7 +130,7 @@ public class PlayerMessage extends NetworkMessage {
}
break;
case SETINITIALDISCRETEPOSITION:
rawBytes = new byte[2+4+4];
rawBytes = new byte[2+4+4+4];
//message header
rawBytes[0] = TypeBytes.MESSAGE_TYPE_PLAYER;
//entity messaage header
@ -132,6 +143,10 @@ public class PlayerMessage extends NetworkMessage {
for(int i = 0; i < 4; i++){
rawBytes[6+i] = intValues[i];
}
intValues = ByteStreamUtils.serializeIntToBytes(initialDiscretePositionZ);
for(int i = 0; i < 4; i++){
rawBytes[10+i] = intValues[i];
}
break;
}
serialized = true;

View File

@ -27,11 +27,14 @@ public class TerrainMessage extends NetworkMessage {
int worldMaxY;
int worldX;
int worldY;
int worldZ;
float value;
int locationX;
int locationY;
int locationZ;
double realLocationX;
double realLocationY;
double realLocationZ;
float macroValue00;
float macroValue01;
float macroValue02;
@ -164,6 +167,14 @@ public class TerrainMessage extends NetworkMessage {
this.worldY = worldY;
}
public int getworldZ() {
return worldZ;
}
public void setworldZ(int worldZ) {
this.worldZ = worldZ;
}
public float getvalue() {
return value;
}
@ -188,6 +199,14 @@ public class TerrainMessage extends NetworkMessage {
this.locationY = locationY;
}
public int getlocationZ() {
return locationZ;
}
public void setlocationZ(int locationZ) {
this.locationZ = locationZ;
}
public double getrealLocationX() {
return realLocationX;
}
@ -204,6 +223,14 @@ public class TerrainMessage extends NetworkMessage {
this.realLocationY = realLocationY;
}
public double getrealLocationZ() {
return realLocationZ;
}
public void setrealLocationZ(double realLocationZ) {
this.realLocationZ = realLocationZ;
}
public float getmacroValue00() {
return macroValue00;
}
@ -722,13 +749,15 @@ public class TerrainMessage extends NetworkMessage {
stripPacketHeader(byteStream);
rVal.setlocationX(ByteStreamUtils.popIntFromByteQueue(byteStream));
rVal.setlocationY(ByteStreamUtils.popIntFromByteQueue(byteStream));
rVal.setlocationZ(ByteStreamUtils.popIntFromByteQueue(byteStream));
return rVal;
}
public static TerrainMessage constructUpdateMessage(int locationX,int locationY){
public static TerrainMessage constructUpdateMessage(int locationX,int locationY,int locationZ){
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.UPDATE);
rVal.setlocationX(locationX);
rVal.setlocationY(locationY);
rVal.setlocationZ(locationZ);
rVal.serialize();
return rVal;
}
@ -873,18 +902,22 @@ public class TerrainMessage extends NetworkMessage {
rVal.setvalue(ByteStreamUtils.popFloatFromByteQueue(byteStream));
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteStream));
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteStream));
rVal.setworldZ(ByteStreamUtils.popIntFromByteQueue(byteStream));
rVal.setlocationX(ByteStreamUtils.popIntFromByteQueue(byteStream));
rVal.setlocationY(ByteStreamUtils.popIntFromByteQueue(byteStream));
rVal.setlocationZ(ByteStreamUtils.popIntFromByteQueue(byteStream));
return rVal;
}
public static TerrainMessage constructheightMapModificationMessage(float value,int worldX,int worldY,int locationX,int locationY){
public static TerrainMessage constructheightMapModificationMessage(float value,int worldX,int worldY,int worldZ,int locationX,int locationY,int locationZ){
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.HEIGHTMAPMODIFICATION);
rVal.setvalue(value);
rVal.setworldX(worldX);
rVal.setworldY(worldY);
rVal.setworldZ(worldZ);
rVal.setlocationX(locationX);
rVal.setlocationY(locationY);
rVal.setlocationZ(locationZ);
rVal.serialize();
return rVal;
}
@ -894,13 +927,15 @@ public class TerrainMessage extends NetworkMessage {
stripPacketHeader(byteStream);
rVal.setrealLocationX(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
rVal.setrealLocationY(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
rVal.setrealLocationZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
return rVal;
}
public static TerrainMessage constructSpawnPositionMessage(double realLocationX,double realLocationY){
public static TerrainMessage constructSpawnPositionMessage(double realLocationX,double realLocationY,double realLocationZ){
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.SPAWNPOSITION);
rVal.setrealLocationX(realLocationX);
rVal.setrealLocationY(realLocationY);
rVal.setrealLocationZ(realLocationZ);
rVal.serialize();
return rVal;
}
@ -967,7 +1002,7 @@ public class TerrainMessage extends NetworkMessage {
}
break;
case UPDATE:
rawBytes = new byte[2+4+4];
rawBytes = new byte[2+4+4+4];
//message header
rawBytes[0] = TypeBytes.MESSAGE_TYPE_TERRAIN;
//entity messaage header
@ -980,6 +1015,10 @@ public class TerrainMessage extends NetworkMessage {
for(int i = 0; i < 4; i++){
rawBytes[6+i] = intValues[i];
}
intValues = ByteStreamUtils.serializeIntToBytes(locationZ);
for(int i = 0; i < 4; i++){
rawBytes[10+i] = intValues[i];
}
break;
case CHUNKLOADSTART:
rawBytes = new byte[2+4+4+4];
@ -1190,7 +1229,7 @@ public class TerrainMessage extends NetworkMessage {
}
break;
case HEIGHTMAPMODIFICATION:
rawBytes = new byte[2+4+4+4+4+4];
rawBytes = new byte[2+4+4+4+4+4+4+4];
//message header
rawBytes[0] = TypeBytes.MESSAGE_TYPE_TERRAIN;
//entity messaage header
@ -1206,17 +1245,25 @@ public class TerrainMessage extends NetworkMessage {
for(int i = 0; i < 4; i++){
rawBytes[10+i] = intValues[i];
}
intValues = ByteStreamUtils.serializeIntToBytes(locationX);
intValues = ByteStreamUtils.serializeIntToBytes(worldZ);
for(int i = 0; i < 4; i++){
rawBytes[14+i] = intValues[i];
}
intValues = ByteStreamUtils.serializeIntToBytes(locationY);
intValues = ByteStreamUtils.serializeIntToBytes(locationX);
for(int i = 0; i < 4; i++){
rawBytes[18+i] = intValues[i];
}
intValues = ByteStreamUtils.serializeIntToBytes(locationY);
for(int i = 0; i < 4; i++){
rawBytes[22+i] = intValues[i];
}
intValues = ByteStreamUtils.serializeIntToBytes(locationZ);
for(int i = 0; i < 4; i++){
rawBytes[26+i] = intValues[i];
}
break;
case SPAWNPOSITION:
rawBytes = new byte[2+8+8];
rawBytes = new byte[2+8+8+8];
//message header
rawBytes[0] = TypeBytes.MESSAGE_TYPE_TERRAIN;
//entity messaage header
@ -1229,6 +1276,10 @@ public class TerrainMessage extends NetworkMessage {
for(int i = 0; i < 8; i++){
rawBytes[10+i] = intValues[i];
}
intValues = ByteStreamUtils.serializeDoubleToBytes(realLocationZ);
for(int i = 0; i < 8; i++){
rawBytes[18+i] = intValues[i];
}
break;
}
serialized = true;

View File

@ -73,7 +73,7 @@ Message categories
Player packet sizes
*/
public static final byte PLAYER_MESSAGE_TYPE_SET_ID_SIZE = 6;
public static final byte PLAYER_MESSAGE_TYPE_SETINITIALDISCRETEPOSITION_SIZE = 10;
public static final byte PLAYER_MESSAGE_TYPE_SETINITIALDISCRETEPOSITION_SIZE = 14;
/*
Terrain subcategories
*/
@ -91,11 +91,11 @@ Message categories
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTMETADATA_SIZE = 2;
public static final byte TERRAIN_MESSAGE_TYPE_RESPONSEMETADATA_SIZE = 30;
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTCHUNK_SIZE = 10;
public static final byte TERRAIN_MESSAGE_TYPE_UPDATE_SIZE = 10;
public static final byte TERRAIN_MESSAGE_TYPE_UPDATE_SIZE = 14;
public static final byte TERRAIN_MESSAGE_TYPE_CHUNKLOADSTART_SIZE = 14;
public static final short TERRAIN_MESSAGE_TYPE_MACROVALUE_SIZE = 310;
public static final byte TERRAIN_MESSAGE_TYPE_HEIGHTMAPMODIFICATION_SIZE = 22;
public static final byte TERRAIN_MESSAGE_TYPE_SPAWNPOSITION_SIZE = 18;
public static final byte TERRAIN_MESSAGE_TYPE_HEIGHTMAPMODIFICATION_SIZE = 30;
public static final byte TERRAIN_MESSAGE_TYPE_SPAWNPOSITION_SIZE = 26;
/*
Server subcategories
*/

View File

@ -262,38 +262,7 @@ public class ServerConnectionHandler implements Runnable {
}
public void addMessagetoOutgoingQueue(NetworkMessage message){
switch(message.getType()){
case ENTITY_MESSAGE:
switch(((EntityMessage)message).getMessageSubtype()){
case MOVEUPDATE:
//we don't want this to fire if it's the server client because other people will keep running indefinitely
//as the server broadcasts to itself that they're moving
case ATTACKUPDATE:
//we don't want this to fire if it's the server client because other people will keep running indefinitely
//as the server broadcasts to itself that they're moving
case SPAWNCREATURE:
if(isServerClient()){
//basically don't send the message if this is the player that is also hosting the game
} else {
networkParser.addOutgoingMessage(message);
}
break;
default:
networkParser.addOutgoingMessage(message);
break;
}
break;
case INVENTORY_MESSAGE:
if(isServerClient()){
//basically don't send the message if this is the player that is also hosting the game
} else {
networkParser.addOutgoingMessage(message);
}
break;
default:
networkParser.addOutgoingMessage(message);
break;
}
networkParser.addOutgoingMessage(message);
}
boolean isConnectionPlayerEntity(int id){
@ -338,9 +307,9 @@ public class ServerConnectionHandler implements Runnable {
Entity playerEntity = playerObject.getPlayerEntity();
Vector3d position = EntityUtils.getPosition(playerEntity);
//deregister entity
Globals.entityManager.deregisterEntity(playerObject.getPlayerEntity());
//tell all clients to destroy the entity
Globals.dataCellManager.getDataCellAtPoint(position).broadcastNetworkMessage(EntityMessage.constructDestroyMessage(playerEntity.getId()));
EntityUtils.cleanUpEntity(playerObject.getPlayerEntity());
//TODO: tell all clients to destroy the entity
EntityUtils.cleanUpEntity(playerEntity);
}
}

View File

@ -7,6 +7,8 @@ import electrosphere.net.server.ServerConnectionHandler;
import java.util.concurrent.Semaphore;
import org.joml.Vector3i;
/**
*
* @author satellite
@ -17,8 +19,7 @@ public class Player {
int id;
static Semaphore idIncrementerLock = new Semaphore(1);
static int idIncrementer = 0;
int worldX;
int worldY;
Vector3i worldPos;
int simulationRadius = 3;
Entity playerEntity;
@ -45,20 +46,12 @@ public class Player {
connectionHandler.addMessagetoOutgoingQueue(message);
}
public int getWorldX() {
return worldX;
public Vector3i getWorldPos() {
return worldPos;
}
public int getWorldY() {
return worldY;
}
public void setWorldX(int worldX) {
this.worldX = worldX;
}
public void setWorldY(int worldY) {
this.worldY = worldY;
public void setWorldPos(Vector3i worldPos) {
this.worldPos = worldPos;
}
public int getSimulationRadius() {

View File

@ -2,11 +2,13 @@ package electrosphere.net.server.protocol;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.joml.Vector3i;
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;
@ -16,6 +18,7 @@ import electrosphere.net.parser.net.message.PlayerMessage;
import electrosphere.net.parser.net.message.TerrainMessage;
import electrosphere.net.server.ServerConnectionHandler;
import electrosphere.net.server.player.Player;
import electrosphere.server.datacell.Realm;
import electrosphere.util.Utilities;
public class CharacterProtocol {
@ -52,18 +55,20 @@ public class CharacterProtocol {
CreatureTemplate template = connectionHandler.getCurrentCreatureTemplate();
String raceName = template.getCreatureType();
//spawn player in world
Entity newPlayerEntity = CreatureUtils.spawnBasicCreature(raceName,template);
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);
EntityUtils.initiallyPositionEntity(newPlayerEntity, new Vector3d(Globals.spawnPoint.x,Globals.spawnPoint.y,Globals.spawnPoint.z));
CreatureUtils.setControllerPlayerId(newPlayerEntity, connectionHandler.getPlayerId());
//attach player object to player character
playerObject.setPlayerEntity(newPlayerEntity);
playerObject.setWorldX(Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.x));
playerObject.setWorldY(Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.z));
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());
Globals.dataCellManager.addPlayerToGroundCells(playerObject);
Globals.dataCellManager.movePlayerGroundCells(playerObject, Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.x), Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.z));
realm.getDataCellManager().addPlayerToRealm(playerObject);
// IronSightTree.attachIronSightTree(newPlayerEntity);
// //spawn player sword
// Entity sword = ItemUtils.spawnBasicItem("Katana");
@ -77,15 +82,16 @@ public class CharacterProtocol {
static void spawnClientEntity(ServerConnectionHandler connectionHandler){
spawnPlayerCharacter(connectionHandler);
//set client initial discrete position
// connectionHandler.addMessagetoOutgoingQueue(
// PlayerMessage.constructSetInitialDiscretePositionMessage(
// Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.x),
// Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.z)
// )
// );
connectionHandler.addMessagetoOutgoingQueue(
PlayerMessage.constructSetInitialDiscretePositionMessage(
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.x),
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.y),
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.z)
)
);
//send spawn point
connectionHandler.addMessagetoOutgoingQueue(
TerrainMessage.constructSpawnPositionMessage(Globals.spawnPoint.x, 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()));

View File

@ -11,6 +11,7 @@ import electrosphere.logger.LoggerInterface;
import electrosphere.net.NetUtils;
import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.net.server.ServerConnectionHandler;
import electrosphere.server.datacell.utils.EntityLookupUtils;
public class EntityProtocol {
@ -18,21 +19,21 @@ public class EntityProtocol {
Entity targetEntity;
switch(message.getMessageSubtype()){
case MOVE:
targetEntity = Globals.entityManager.getEntityFromId(message.getentityID());
targetEntity = EntityLookupUtils.getEntityById(message.getentityID());
if(targetEntity != null){
CreatureUtils.attachEntityMessageToMovementTree(targetEntity,message);
CreatureUtils.serverAttachEntityMessageToMovementTree(targetEntity,message);
}
break;
case SETBEHAVIORTREE:
break;
case MOVEUPDATE:
targetEntity = Globals.entityManager.getEntityFromId(message.getentityID());
targetEntity = EntityLookupUtils.getEntityById(message.getentityID());
if(targetEntity != null){
CreatureUtils.attachEntityMessageToMovementTree(targetEntity,message);
CreatureUtils.serverAttachEntityMessageToMovementTree(targetEntity,message);
}
break;
case ATTACKUPDATE:
targetEntity = Globals.entityManager.getEntityFromId(message.getentityID());
targetEntity = EntityLookupUtils.getEntityById(message.getentityID());
if(targetEntity != null){
CreatureUtils.attachEntityMessageToAttackTree(targetEntity,message);
}

View File

@ -10,6 +10,7 @@ import electrosphere.game.data.creature.type.equip.EquipPoint;
import electrosphere.logger.LoggerInterface;
import electrosphere.net.parser.net.message.InventoryMessage;
import electrosphere.net.server.ServerConnectionHandler;
import electrosphere.server.datacell.utils.EntityLookupUtils;
public class InventoryProtocol {
@ -22,30 +23,30 @@ public class InventoryProtocol {
switch(message.getMessageSubtype()){
case ADDITEMTOINVENTORY:
LoggerInterface.loggerNetworking.DEBUG("[SERVER] ADD ITEM TO INVENTORY " + message.getentityId());
target = Globals.entityManager.getEntityFromId(connectionHandler.getPlayerCharacterId());
target = EntityLookupUtils.getEntityById(connectionHandler.getPlayerCharacterId());
if(InventoryUtils.hasNaturalInventory(target)){
InventoryUtils.getInventoryState(target).addNetworkMessage(message);
InventoryUtils.serverGetInventoryState(target).addNetworkMessage(message);
}
break;
case REMOVEITEMFROMINVENTORY:
LoggerInterface.loggerNetworking.DEBUG("[SERVER] REMOVE ITEM FROM INVENTORY " + message.getentityId());
target = Globals.entityManager.getEntityFromId(connectionHandler.getPlayerCharacterId());
target = EntityLookupUtils.getEntityById(connectionHandler.getPlayerCharacterId());
if(InventoryUtils.hasNaturalInventory(target)){
InventoryUtils.getInventoryState(target).addNetworkMessage(message);
InventoryUtils.serverGetInventoryState(target).addNetworkMessage(message);
}
break;
case CLIENTREQUESTEQUIPITEM:
LoggerInterface.loggerNetworking.DEBUG("[SERVER] REQUEST EQUIP ITEM " + message.getentityId());
target = Globals.entityManager.getEntityFromId(connectionHandler.getPlayerCharacterId());
target = EntityLookupUtils.getEntityById(connectionHandler.getPlayerCharacterId());
if(InventoryUtils.hasNaturalInventory(target)){
InventoryUtils.getInventoryState(target).addNetworkMessage(message);
InventoryUtils.serverGetInventoryState(target).addNetworkMessage(message);
}
break;
case CLIENTREQUESTUNEQUIPITEM:
LoggerInterface.loggerNetworking.DEBUG("[SERVER] REQUEST UNEQUIP ITEM " + message.getentityId());
target = Globals.entityManager.getEntityFromId(connectionHandler.getPlayerCharacterId());
target = EntityLookupUtils.getEntityById(connectionHandler.getPlayerCharacterId());
if(InventoryUtils.hasNaturalInventory(target)){
InventoryUtils.getInventoryState(target).addNetworkMessage(message);
InventoryUtils.serverGetInventoryState(target).addNetworkMessage(message);
}
break;
case SERVERCOMMANDUNEQUIPITEM:

View File

@ -134,8 +134,10 @@ public class TerrainProtocol {
TerrainMessage.constructheightMapModificationMessage(
modification.getValue(),
modification.getWorldX(),
0,
modification.getWorldY(),
modification.getLocationX(),
0,
modification.getLocationY()
)
);

View File

@ -569,7 +569,7 @@ public class RenderingEngine {
//
Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
modelTransformMatrix = new Matrix4f();
for(Entity currentEntity : Globals.entityManager.getEntitiesWithTag(EntityTags.DRAWABLE)){
for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){
Vector3d position = EntityUtils.getPosition(currentEntity);
if(
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
@ -647,7 +647,7 @@ public class RenderingEngine {
//
Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
modelTransformMatrix = new Matrix4f();
for(Entity currentEntity : Globals.entityManager.getEntitiesWithTag(EntityTags.DRAWABLE)){
for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){
Vector3d position = EntityUtils.getPosition(currentEntity);
if(
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
@ -700,7 +700,7 @@ public class RenderingEngine {
//
for(Entity currentEntity : Globals.entityManager.getEntitiesWithTag(EntityTags.DRAWABLE)){
for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){
Vector3d position = EntityUtils.getPosition(currentEntity);
if(
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
@ -773,7 +773,7 @@ public class RenderingEngine {
//
Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
modelTransformMatrix = new Matrix4f();
for(Entity currentEntity : Globals.entityManager.getEntitiesWithTag(EntityTags.DRAWABLE)){
for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){
Vector3d position = EntityUtils.getPosition(currentEntity);
if(
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
@ -824,7 +824,7 @@ public class RenderingEngine {
Matrix4f modelTransformMatrix = new Matrix4f();
if(Globals.userSettings.graphicsDebugDrawCollisionSpheres()){
for(Entity currentHitbox : Globals.hitboxManager.getAllHitboxes()){
for(Entity currentHitbox : Globals.clientHitboxManager.getAllHitboxes()){
if((boolean)currentHitbox.getData(EntityDataStrings.DATA_STRING_DRAW)){
Model hitboxModel;
HitboxData data = HitboxUtils.getHitboxData(currentHitbox);
@ -871,7 +871,7 @@ public class RenderingEngine {
if(Globals.userSettings.graphicsDebugDrawPhysicsObjects()){
Model physicsGraphicsModel;
for(Entity physicsEntity : Globals.collisionEngine.getDynamicPhysicsEntities()){
for(Entity physicsEntity : Globals.clientSceneWrapper.getCollisionEngine().getDynamicPhysicsEntities()){
if((boolean)physicsEntity.getData(EntityDataStrings.DATA_STRING_DRAW)){
CollidableTemplate template = (CollidableTemplate)physicsEntity.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE);
switch(template.getType()){
@ -908,7 +908,7 @@ public class RenderingEngine {
}
}
}
for(Entity physicsEntity : Globals.collisionEngine.getStructurePhysicsEntities()){
for(Entity physicsEntity : Globals.clientSceneWrapper.getCollisionEngine().getStructurePhysicsEntities()){
if((boolean)physicsEntity.getData(EntityDataStrings.DATA_STRING_DRAW)){
if(physicsEntity.containsKey(EntityDataStrings.COLLISION_ENTITY_TYPE_PLANE)){
if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitplane.fbx")) != null){
@ -1017,7 +1017,7 @@ public class RenderingEngine {
Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
modelTransformMatrix = new Matrix4f();
for(Entity currentEntity : Globals.entityManager.getEntitiesWithTag(EntityTags.DRAWABLE)){
for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){
Vector3d position = EntityUtils.getPosition(currentEntity);
if(
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
@ -1272,7 +1272,7 @@ public class RenderingEngine {
// D R A W A L L E N T I T I E S
//
Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
for(Entity currentEntity : Globals.entityManager.getEntitiesWithTag(EntityTags.DRAWABLE)){
for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){
Vector3d position = EntityUtils.getPosition(currentEntity);
if(
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
@ -1310,7 +1310,7 @@ public class RenderingEngine {
//Draw front faces of all non-volumetrics
//
cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
for(Entity currentEntity : Globals.entityManager.getEntitiesWithTag(EntityTags.DRAWABLE)){
for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){
Vector3d position = EntityUtils.getPosition(currentEntity);
if(
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
@ -1359,7 +1359,7 @@ public class RenderingEngine {
//
// D R A W A L L E N T I T I E S
//
for(Entity currentEntity : Globals.entityManager.getEntitiesWithTag(EntityTags.DRAWABLE)){
for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){
Vector3d position = EntityUtils.getPosition(currentEntity);
if(
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&

View File

@ -2,6 +2,7 @@ package electrosphere.renderer.light;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityTags;
@ -15,9 +16,8 @@ import org.joml.Vector3f;
public class LightEntityUtils {
public static Entity createDirectionalLight(Vector3f position, Vector3f ambient, Vector3f diffuse, Vector3f specular){
Entity rVal = new Entity();
Globals.entityManager.registerEntity(rVal);
Globals.entityManager.registerEntityToTag(rVal, EntityTags.LIGHT);
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
Globals.clientScene.registerEntityToTag(rVal, EntityTags.LIGHT);
rVal.putData(EntityDataStrings.DATA_STRING_LIGHT_TYPE, EntityDataStrings.DATA_STRING_LIGHT_TYPE_DIRECTIONAL);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z));
rVal.putData(EntityDataStrings.DATA_STRING_LIGHT_AMBIENT, ambient);
@ -27,9 +27,8 @@ public class LightEntityUtils {
}
public static Entity createPointLight(Vector3f position, Vector3f ambient, Vector3f diffuse, Vector3f specular, float constant, float linear, float quadratic){
Entity rVal = new Entity();
Globals.entityManager.registerEntity(rVal);
Globals.entityManager.registerEntityToTag(rVal, EntityTags.LIGHT);
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
Globals.clientScene.registerEntityToTag(rVal, EntityTags.LIGHT);
rVal.putData(EntityDataStrings.DATA_STRING_LIGHT_TYPE, EntityDataStrings.DATA_STRING_LIGHT_TYPE_POINT);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z));
rVal.putData(EntityDataStrings.DATA_STRING_LIGHT_AMBIENT, ambient);

View File

@ -79,12 +79,12 @@ public class MillAbout extends AI {
if(moveTargetPosition.distance(position) > 0.4){
Vector3d moveVector = new Vector3d(moveTargetPosition).sub(position).normalize();
CreatureUtils.setFacingVector(character, new Vector3d((float)moveVector.x,(float)moveVector.y,(float)moveVector.z));
GroundMovementTree characterMoveTree = (GroundMovementTree)CreatureUtils.getEntityMovementTree(character);
GroundMovementTree characterMoveTree = (GroundMovementTree)CreatureUtils.serverGetEntityMovementTree(character);
if(characterMoveTree.getState()==GroundMovementTree.MovementTreeState.IDLE || characterMoveTree.getState()==GroundMovementTree.MovementTreeState.SLOWDOWN){
characterMoveTree.start(MovementRelativeFacing.FORWARD);
}
} else {
GroundMovementTree characterMoveTree = (GroundMovementTree)CreatureUtils.getEntityMovementTree(character);
GroundMovementTree characterMoveTree = (GroundMovementTree)CreatureUtils.serverGetEntityMovementTree(character);
characterMoveTree.slowdown();
// System.out.println("Made it to destination");
moveToTarget = false;

Some files were not shown because too many files have changed in this diff Show More