synchronizing object entities
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2024-07-27 00:15:50 -04:00
parent 1df8a89b3e
commit 161f40ee04
25 changed files with 311 additions and 85 deletions

View File

@ -27,6 +27,7 @@
"files" : [ "files" : [
"Data/objects/floatingisland.json", "Data/objects/floatingisland.json",
"Data/objects/testscene1objects.json", "Data/objects/testscene1objects.json",
"Data/objects/debug_objects.json" "Data/objects/debug_objects.json",
"Data/objects/game_objects.json"
] ]
} }

View File

@ -0,0 +1,14 @@
{
"objects" : [
{
"objectId" : "spawnPoint",
"modelPath" : "Models/basic/geometry/unitcylinder.fbx",
"tokens": [
"SPAWNPOINT"
]
}
],
"files" : []
}

View File

@ -454,11 +454,11 @@ Devtools for updating first person attachment rotations
(07/26/2024) (07/26/2024)
Viewmodel equipped item rotates inverted to bone rotation Viewmodel equipped item rotates inverted to bone rotation
Visually block
Utility object for reducing boilerplate when writing btree transitions that just play an animation then transition Utility object for reducing boilerplate when writing btree transitions that just play an animation then transition
First animations flickering in first person (enforce animation priority requirement) First animations flickering in first person (enforce animation priority requirement)
Debug third person animations flickering (attachments not reflecting animations that were played that frame) Debug third person animations flickering (attachments not reflecting animations that were played that frame)
Small data fix
Refactor spawn point to not be global
# TODO # TODO

View File

@ -149,6 +149,17 @@
"positionZ" "positionZ"
] ]
}, },
{
"messageName" : "SpawnObject",
"description" : "Spawns a generic object",
"data" : [
"entityID",
"creatureTemplate",
"positionX",
"positionY",
"positionZ"
]
},
{ {
"messageName" : "moveUpdate", "messageName" : "moveUpdate",
"description" : "Updates a client on the move state of an entity", "description" : "Updates a client on the move state of an entity",

View File

@ -101,7 +101,12 @@ public class ClientSceneWrapper {
* @return The entity in question * @return The entity in question
*/ */
public Entity getEntityFromServerId(int id){ public Entity getEntityFromServerId(int id){
return scene.getEntityFromId(mapServerToClientId(id)); if(serverToClientIdMap.containsKey(id)){
int clientId = mapServerToClientId(id);
return scene.getEntityFromId(clientId);
} else {
return null;
}
} }
/** /**
@ -119,6 +124,7 @@ public class ClientSceneWrapper {
* @param id The id * @param id The id
*/ */
public void dumpIdData(int id){ public void dumpIdData(int id){
LoggerInterface.loggerNetworking.WARNING("Offending ID " + id);
LoggerInterface.loggerNetworking.WARNING("Client->Server Map contains? " + clientToServerIdMap.containsKey(id)); LoggerInterface.loggerNetworking.WARNING("Client->Server Map contains? " + clientToServerIdMap.containsKey(id));
LoggerInterface.loggerNetworking.WARNING("Server->Client Map contains? " + serverToClientIdMap.containsKey(id)); LoggerInterface.loggerNetworking.WARNING("Server->Client Map contains? " + serverToClientIdMap.containsKey(id));
if(clientToServerIdMap.containsKey(id)){ if(clientToServerIdMap.containsKey(id)){

View File

@ -5,7 +5,6 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import org.joml.Matrix4f; import org.joml.Matrix4f;
import org.joml.Vector3d;
import org.joml.Vector3f; import org.joml.Vector3f;
import electrosphere.audio.AudioEngine; import electrosphere.audio.AudioEngine;
@ -273,9 +272,6 @@ public class Globals {
//Engine - Main managers/variables //Engine - Main managers/variables
// //
//spawn point
public static Vector3d spawnPoint = new Vector3d(0,0,0);
//manages all models loaded into memory //manages all models loaded into memory
public static AssetManager assetManager; public static AssetManager assetManager;

View File

@ -4,6 +4,7 @@ import java.io.IOException;
import java.io.PipedInputStream; import java.io.PipedInputStream;
import java.io.PipedOutputStream; import java.io.PipedOutputStream;
import org.joml.Vector3d;
import org.joml.Vector3f; import org.joml.Vector3f;
import org.joml.Vector3i; import org.joml.Vector3i;
@ -171,10 +172,11 @@ public class LoadingUtils {
//set player world-space coordinates //set player world-space coordinates
Player playerObject = Globals.playerManager.getPlayerFromId(0); Player playerObject = Globals.playerManager.getPlayerFromId(0);
Realm realm = Globals.realmManager.getRealms().iterator().next(); Realm realm = Globals.realmManager.getRealms().iterator().next();
Vector3d spawnPoint = realm.getSpawnPoint();
playerObject.setWorldPos(new Vector3i( playerObject.setWorldPos(new Vector3i(
realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.x), realm.getServerWorldData().convertRealToChunkSpace(spawnPoint.x),
realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.y), realm.getServerWorldData().convertRealToChunkSpace(spawnPoint.y),
realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.z) realm.getServerWorldData().convertRealToChunkSpace(spawnPoint.z)
)); ));
} }

View File

@ -22,6 +22,7 @@ public class EntityTags {
public static final String POSEABLE = "poseable"; //is it poseable on server public static final String POSEABLE = "poseable"; //is it poseable on server
public static final String LIGHT = "light"; public static final String LIGHT = "light";
public static final String ITEM = "item"; public static final String ITEM = "item";
public static final String OBJECT = "object";
public static final String GRAVITY = "gravity"; public static final String GRAVITY = "gravity";
public static final String PARTICLE = "particle"; public static final String PARTICLE = "particle";

View File

@ -665,12 +665,13 @@ public class CreatureUtils {
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.LIFE_STATE); ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.LIFE_STATE);
//idle tree & generic stuff all creatures have //idle tree & generic stuff all creatures have
ServerIdleTree.attachTree(rVal); ServerIdleTree.attachTree(rVal);
CreatureUtils.setFacingVector(rVal, MathUtils.getOriginVector());
rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
//required for synchronization manager
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.CREATURE); ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.CREATURE);
EntityUtils.setEntityType(rVal, ENTITY_TYPE_CREATURE); EntityUtils.setEntityType(rVal, ENTITY_TYPE_CREATURE);
EntityUtils.setEntitySubtype(rVal, type); EntityUtils.setEntitySubtype(rVal, type);
CreatureUtils.setFacingVector(rVal, MathUtils.getOriginVector());
rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
//position entity //position entity
//this needs to be called at the end of this function. //this needs to be called at the end of this function.

View File

@ -186,14 +186,16 @@ public class ItemUtils {
} }
} }
rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true); rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
EntityUtils.setEntityType(rVal, ENTITY_TYPE_ITEM);
rVal.putData(EntityDataStrings.ITEM_IS_IN_INVENTORY, false); rVal.putData(EntityDataStrings.ITEM_IS_IN_INVENTORY, false);
EntityUtils.setEntitySubtype(rVal, name);
// rVal.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(0.005f,0.005f,0.005f)); // 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))); // rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().identity().rotateY((float)(-Math.PI/2)).rotateZ(-(float)(Math.PI/2)));
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.ITEM);
//required for synchronization manager
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.ITEM);
EntityUtils.setEntityType(rVal, ENTITY_TYPE_ITEM);
EntityUtils.setEntitySubtype(rVal, name);
//position entity //position entity
//this needs to be called at the end of this function. //this needs to be called at the end of this function.

View File

@ -26,7 +26,9 @@ import electrosphere.entity.state.inventory.UnrelationalInventoryState;
import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.game.data.collidable.CollidableTemplate; import electrosphere.game.data.collidable.CollidableTemplate;
import electrosphere.game.data.object.type.ObjectData; import electrosphere.game.data.object.type.ObjectData;
import electrosphere.renderer.actor.ActorUtils; 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 electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils; import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
import electrosphere.server.datacell.utils.ServerEntityTagUtils; import electrosphere.server.datacell.utils.ServerEntityTagUtils;
@ -48,12 +50,8 @@ public class ObjectUtils {
EntityCreationUtils.makeEntityDrawable(rVal, rawType.getModelPath()); EntityCreationUtils.makeEntityDrawable(rVal, rawType.getModelPath());
} }
//forward-searching tokens //forward-searching tokens
boolean collisionMakeDynamic = true;
for(String token : rawType.getTokens()){ for(String token : rawType.getTokens()){
switch(token){ switch(token){
case "DISABLE_COLLISION_REACTION": {
collisionMakeDynamic = false;
} break;
case "GENERATE_COLLISION_OBJECT": { case "GENERATE_COLLISION_OBJECT": {
Globals.assetManager.addCollisionMeshToQueue(new PhysicsMeshQueueItem(Globals.clientSceneWrapper.getCollisionEngine(),rawType.getModelPath())); Globals.assetManager.addCollisionMeshToQueue(new PhysicsMeshQueueItem(Globals.clientSceneWrapper.getCollisionEngine(),rawType.getModelPath()));
Globals.clientSceneWrapper.getScene().registerBehaviorTree(new BehaviorTree() {public void simulate(float deltaTime) { Globals.clientSceneWrapper.getScene().registerBehaviorTree(new BehaviorTree() {public void simulate(float deltaTime) {
@ -86,9 +84,6 @@ public class ObjectUtils {
//tokens //tokens
for(String token : rawType.getTokens()){ for(String token : rawType.getTokens()){
switch(token){ switch(token){
case "BLENDER_TRANSFORM":
ActorUtils.applyBlenderTransformer(rVal);
break;
case "GRAVITY": case "GRAVITY":
Collidable collidable = (Collidable)rVal.getData(EntityDataStrings.PHYSICS_COLLIDABLE); Collidable collidable = (Collidable)rVal.getData(EntityDataStrings.PHYSICS_COLLIDABLE);
DBody collisionObject = (DBody)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); DBody collisionObject = (DBody)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
@ -108,6 +103,9 @@ public class ObjectUtils {
case "TERRAIN_COLLISION": { case "TERRAIN_COLLISION": {
CollisionObjUtils.getCollidable(rVal).overrideType(Collidable.TYPE_TERRAIN); CollisionObjUtils.getCollidable(rVal).overrideType(Collidable.TYPE_TERRAIN);
} break; } break;
case "SPAWNPOINT": {
//ignore on client
} break;
} }
} }
if(rawType.getHitboxData() != null){ if(rawType.getHitboxData() != null){
@ -139,12 +137,8 @@ public class ObjectUtils {
EntityCreationUtils.makeEntityPoseable(rVal, rawType.getModelPath()); EntityCreationUtils.makeEntityPoseable(rVal, rawType.getModelPath());
} }
//forward-searching tokens //forward-searching tokens
boolean collisionMakeDynamic = true;
for(String token : rawType.getTokens()){ for(String token : rawType.getTokens()){
switch(token){ switch(token){
case "DISABLE_COLLISION_REACTION": {
collisionMakeDynamic = false;
} break;
case "GENERATE_COLLISION_OBJECT": { case "GENERATE_COLLISION_OBJECT": {
Globals.assetManager.addCollisionMeshToQueue(new PhysicsMeshQueueItem(realm.getCollisionEngine(),rawType.getModelPath())); Globals.assetManager.addCollisionMeshToQueue(new PhysicsMeshQueueItem(realm.getCollisionEngine(),rawType.getModelPath()));
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, new BehaviorTree() {public void simulate(float deltaTime) { ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, new BehaviorTree() {public void simulate(float deltaTime) {
@ -177,9 +171,6 @@ public class ObjectUtils {
//tokens //tokens
for(String token : rawType.getTokens()){ for(String token : rawType.getTokens()){
switch(token){ switch(token){
case "BLENDER_TRANSFORM":
ActorUtils.applyBlenderTransformer(rVal);
break;
case "GRAVITY": case "GRAVITY":
Collidable collidable = (Collidable)rVal.getData(EntityDataStrings.PHYSICS_COLLIDABLE); Collidable collidable = (Collidable)rVal.getData(EntityDataStrings.PHYSICS_COLLIDABLE);
DBody collisionObject = (DBody)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); DBody collisionObject = (DBody)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
@ -199,6 +190,9 @@ public class ObjectUtils {
case "TERRAIN_COLLISION": { case "TERRAIN_COLLISION": {
CollisionObjUtils.getCollidable(rVal).overrideType(Collidable.TYPE_TERRAIN); CollisionObjUtils.getCollidable(rVal).overrideType(Collidable.TYPE_TERRAIN);
} break; } break;
case "SPAWNPOINT": {
realm.registerSpawnPoint(position);
} break;
} }
} }
if(rawType.getHitboxData() != null){ if(rawType.getHitboxData() != null){
@ -208,6 +202,12 @@ public class ObjectUtils {
ServerIdleTree.attachTree(rVal); ServerIdleTree.attachTree(rVal);
//required for synchronization manager
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.OBJECT);
EntityUtils.setEntityType(rVal, ENTITY_TYPE_OBJECT);
EntityUtils.setEntitySubtype(rVal, type);
//position entity //position entity
//this needs to be called at the end of this function. //this needs to be called at the end of this function.
//Burried underneath this is function call to initialize a server side entity. //Burried underneath this is function call to initialize a server side entity.
@ -239,4 +239,24 @@ public class ObjectUtils {
return (String)EntityUtils.getEntitySubtype(e); return (String)EntityUtils.getEntitySubtype(e);
} }
/**
* Sets the object to a given player
* @param player The player
* @param item The object entity
*/
public static void sendEntityToPlayer(Player player, Entity object){
int id = object.getId();
String type = ObjectUtils.getType(object);
Vector3d position = EntityUtils.getPosition(object);
//construct the spawn message and attach to player
NetworkMessage message = EntityMessage.constructSpawnObjectMessage(
id,
type,
position.x,
position.y,
position.z
);
player.addMessage(message);
}
} }

View File

@ -7,7 +7,6 @@ import electrosphere.engine.Globals;
import electrosphere.entity.ClientEntityUtils; import electrosphere.entity.ClientEntityUtils;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils; import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils; import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.attack.ClientAttackTree; import electrosphere.entity.state.attack.ClientAttackTree;
import electrosphere.entity.state.client.firstPerson.FirstPersonTree; import electrosphere.entity.state.client.firstPerson.FirstPersonTree;
@ -16,6 +15,7 @@ import electrosphere.entity.types.creature.CreatureTemplate;
import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.foliage.FoliageUtils; import electrosphere.entity.types.foliage.FoliageUtils;
import electrosphere.entity.types.item.ItemUtils; import electrosphere.entity.types.item.ItemUtils;
import electrosphere.entity.types.object.ObjectUtils;
import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.creature.type.CreatureType;
import electrosphere.game.data.creature.type.ViewModelData; import electrosphere.game.data.creature.type.ViewModelData;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
@ -86,6 +86,15 @@ public class EntityProtocol {
ClientEntityUtils.initiallyPositionEntity(newlySpawnedEntity, new Vector3d(message.getpositionX(),message.getpositionY(),message.getpositionZ())); ClientEntityUtils.initiallyPositionEntity(newlySpawnedEntity, new Vector3d(message.getpositionX(),message.getpositionY(),message.getpositionZ()));
Globals.clientSceneWrapper.mapIdToId(newlySpawnedEntity.getId(), message.getentityID()); Globals.clientSceneWrapper.mapIdToId(newlySpawnedEntity.getId(), message.getentityID());
} break; } break;
case SPAWNOBJECT: {
LoggerInterface.loggerNetworking.DEBUG("Spawn object " + message.getentityID() + " at " + message.getpositionX() + " " + message.getpositionY() + " " + message.getpositionZ());
//spawn item
String objectType = message.getcreatureTemplate();
newlySpawnedEntity = ObjectUtils.clientSpawnBasicObject(objectType);
//position
ClientEntityUtils.initiallyPositionEntity(newlySpawnedEntity, new Vector3d(message.getpositionX(),message.getpositionY(),message.getpositionZ()));
Globals.clientSceneWrapper.mapIdToId(newlySpawnedEntity.getId(), message.getentityID());
} break;

View File

@ -28,7 +28,7 @@ public class TerrainProtocol {
Globals.clientConnection.getClientProtocol().setHasReceivedWorld(true); Globals.clientConnection.getClientProtocol().setHasReceivedWorld(true);
break; break;
case SPAWNPOSITION: case SPAWNPOSITION:
Globals.spawnPoint.set(message.getrealLocationX(),0.25,message.getrealLocationZ()); LoggerInterface.loggerNetworking.WARNING("Received spawnPosition packet on client. This is deprecated!");
break; break;
case SENDCHUNKDATA: case SENDCHUNKDATA:
Globals.clientTerrainManager.attachTerrainMessage(message); Globals.clientTerrainManager.attachTerrainMessage(message);

View File

@ -11,6 +11,7 @@ public class EntityMessage extends NetworkMessage {
CREATE, CREATE,
SPAWNCREATURE, SPAWNCREATURE,
SPAWNITEM, SPAWNITEM,
SPAWNOBJECT,
MOVEUPDATE, MOVEUPDATE,
ATTACKUPDATE, ATTACKUPDATE,
STARTATTACK, STARTATTACK,
@ -288,6 +289,8 @@ public class EntityMessage extends NetworkMessage {
return EntityMessage.canParseSpawnCreatureMessage(byteBuffer); return EntityMessage.canParseSpawnCreatureMessage(byteBuffer);
case TypeBytes.ENTITY_MESSAGE_TYPE_SPAWNITEM: case TypeBytes.ENTITY_MESSAGE_TYPE_SPAWNITEM:
return EntityMessage.canParseSpawnItemMessage(byteBuffer); return EntityMessage.canParseSpawnItemMessage(byteBuffer);
case TypeBytes.ENTITY_MESSAGE_TYPE_SPAWNOBJECT:
return EntityMessage.canParseSpawnObjectMessage(byteBuffer);
case TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE: case TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE:
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE_SIZE){ if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE_SIZE){
return true; return true;
@ -502,6 +505,59 @@ public class EntityMessage extends NetworkMessage {
return rVal; return rVal;
} }
public static boolean canParseSpawnObjectMessage(CircularByteBuffer byteBuffer){
int currentStreamLength = byteBuffer.getRemaining();
List<Byte> temporaryByteQueue = new LinkedList();
if(currentStreamLength < 6){
return false;
}
int creatureTemplateSize = 0;
if(currentStreamLength < 10){
return false;
} else {
temporaryByteQueue.add(byteBuffer.peek(6 + 0));
temporaryByteQueue.add(byteBuffer.peek(6 + 1));
temporaryByteQueue.add(byteBuffer.peek(6 + 2));
temporaryByteQueue.add(byteBuffer.peek(6 + 3));
creatureTemplateSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
}
if(currentStreamLength < 10 + creatureTemplateSize){
return false;
}
if(currentStreamLength < 18 + creatureTemplateSize){
return false;
}
if(currentStreamLength < 26 + creatureTemplateSize){
return false;
}
if(currentStreamLength < 34 + creatureTemplateSize){
return false;
}
return true;
}
public static EntityMessage parseSpawnObjectMessage(CircularByteBuffer byteBuffer){
EntityMessage rVal = new EntityMessage(EntityMessageType.SPAWNOBJECT);
stripPacketHeader(byteBuffer);
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
rVal.setcreatureTemplate(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
return rVal;
}
public static EntityMessage constructSpawnObjectMessage(int entityID,String creatureTemplate,double positionX,double positionY,double positionZ){
EntityMessage rVal = new EntityMessage(EntityMessageType.SPAWNOBJECT);
rVal.setentityID(entityID);
rVal.setcreatureTemplate(creatureTemplate);
rVal.setpositionX(positionX);
rVal.setpositionY(positionY);
rVal.setpositionZ(positionZ);
rVal.serialize();
return rVal;
}
public static EntityMessage parsemoveUpdateMessage(CircularByteBuffer byteBuffer){ public static EntityMessage parsemoveUpdateMessage(CircularByteBuffer byteBuffer){
EntityMessage rVal = new EntityMessage(EntityMessageType.MOVEUPDATE); EntityMessage rVal = new EntityMessage(EntityMessageType.MOVEUPDATE);
stripPacketHeader(byteBuffer); stripPacketHeader(byteBuffer);
@ -857,6 +913,37 @@ public class EntityMessage extends NetworkMessage {
rawBytes[26+creatureTemplate.length()+i] = intValues[i]; rawBytes[26+creatureTemplate.length()+i] = intValues[i];
} }
break; break;
case SPAWNOBJECT:
rawBytes = new byte[2+4+4+creatureTemplate.length()+8+8+8];
//message header
rawBytes[0] = TypeBytes.MESSAGE_TYPE_ENTITY;
//entity messaage header
rawBytes[1] = TypeBytes.ENTITY_MESSAGE_TYPE_SPAWNOBJECT;
intValues = ByteStreamUtils.serializeIntToBytes(entityID);
for(int i = 0; i < 4; i++){
rawBytes[2+i] = intValues[i];
}
intValues = ByteStreamUtils.serializeIntToBytes(creatureTemplate.length());
for(int i = 0; i < 4; i++){
rawBytes[6+i] = intValues[i];
}
stringBytes = creatureTemplate.getBytes();
for(int i = 0; i < creatureTemplate.length(); i++){
rawBytes[10+i] = stringBytes[i];
}
intValues = ByteStreamUtils.serializeDoubleToBytes(positionX);
for(int i = 0; i < 8; i++){
rawBytes[10+creatureTemplate.length()+i] = intValues[i];
}
intValues = ByteStreamUtils.serializeDoubleToBytes(positionY);
for(int i = 0; i < 8; i++){
rawBytes[18+creatureTemplate.length()+i] = intValues[i];
}
intValues = ByteStreamUtils.serializeDoubleToBytes(positionZ);
for(int i = 0; i < 8; i++){
rawBytes[26+creatureTemplate.length()+i] = intValues[i];
}
break;
case MOVEUPDATE: case MOVEUPDATE:
rawBytes = new byte[2+4+8+8+8+8+8+8+8+8+8+4+4]; rawBytes = new byte[2+4+8+8+8+8+8+8+8+8+8+4+4];
//message header //message header

View File

@ -56,6 +56,11 @@ SYNCHRONIZATION_MESSAGE,
rVal = EntityMessage.parseSpawnItemMessage(byteBuffer); rVal = EntityMessage.parseSpawnItemMessage(byteBuffer);
} }
break; break;
case TypeBytes.ENTITY_MESSAGE_TYPE_SPAWNOBJECT:
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
rVal = EntityMessage.parseSpawnObjectMessage(byteBuffer);
}
break;
case TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE: case TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE:
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){ if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
rVal = EntityMessage.parsemoveUpdateMessage(byteBuffer); rVal = EntityMessage.parsemoveUpdateMessage(byteBuffer);

View File

@ -20,15 +20,16 @@ Message categories
public static final byte ENTITY_MESSAGE_TYPE_CREATE = 0; public static final byte ENTITY_MESSAGE_TYPE_CREATE = 0;
public static final byte ENTITY_MESSAGE_TYPE_SPAWNCREATURE = 1; public static final byte ENTITY_MESSAGE_TYPE_SPAWNCREATURE = 1;
public static final byte ENTITY_MESSAGE_TYPE_SPAWNITEM = 2; public static final byte ENTITY_MESSAGE_TYPE_SPAWNITEM = 2;
public static final byte ENTITY_MESSAGE_TYPE_MOVEUPDATE = 3; public static final byte ENTITY_MESSAGE_TYPE_SPAWNOBJECT = 3;
public static final byte ENTITY_MESSAGE_TYPE_ATTACKUPDATE = 4; public static final byte ENTITY_MESSAGE_TYPE_MOVEUPDATE = 4;
public static final byte ENTITY_MESSAGE_TYPE_STARTATTACK = 5; public static final byte ENTITY_MESSAGE_TYPE_ATTACKUPDATE = 5;
public static final byte ENTITY_MESSAGE_TYPE_KILL = 6; public static final byte ENTITY_MESSAGE_TYPE_STARTATTACK = 6;
public static final byte ENTITY_MESSAGE_TYPE_DESTROY = 7; public static final byte ENTITY_MESSAGE_TYPE_KILL = 7;
public static final byte ENTITY_MESSAGE_TYPE_SETPROPERTY = 8; public static final byte ENTITY_MESSAGE_TYPE_DESTROY = 8;
public static final byte ENTITY_MESSAGE_TYPE_ATTACHENTITYTOENTITY = 9; public static final byte ENTITY_MESSAGE_TYPE_SETPROPERTY = 9;
public static final byte ENTITY_MESSAGE_TYPE_SPAWNFOLIAGESEED = 10; public static final byte ENTITY_MESSAGE_TYPE_ATTACHENTITYTOENTITY = 10;
public static final byte ENTITY_MESSAGE_TYPE_UPDATEENTITYVIEWDIR = 11; public static final byte ENTITY_MESSAGE_TYPE_SPAWNFOLIAGESEED = 11;
public static final byte ENTITY_MESSAGE_TYPE_UPDATEENTITYVIEWDIR = 12;
/* /*
Entity packet sizes Entity packet sizes
*/ */

View File

@ -1,5 +1,7 @@
package electrosphere.net.server.protocol; package electrosphere.net.server.protocol;
import org.joml.Vector3d;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.types.creature.CreatureTemplate; import electrosphere.entity.types.creature.CreatureTemplate;
import electrosphere.net.parser.net.message.CharacterMessage; import electrosphere.net.parser.net.message.CharacterMessage;
@ -64,17 +66,18 @@ public class CharacterProtocol {
static void spawnEntityForClient(ServerConnectionHandler connectionHandler){ static void spawnEntityForClient(ServerConnectionHandler connectionHandler){
PlayerCharacterCreation.spawnPlayerCharacter(connectionHandler); PlayerCharacterCreation.spawnPlayerCharacter(connectionHandler);
Realm realm = Globals.playerManager.getPlayerRealm(connectionHandler.getPlayer()); Realm realm = Globals.playerManager.getPlayerRealm(connectionHandler.getPlayer());
Vector3d spawnPoint = realm.getSpawnPoint();
//set client initial discrete position //set client initial discrete position
connectionHandler.addMessagetoOutgoingQueue( connectionHandler.addMessagetoOutgoingQueue(
PlayerMessage.constructSetInitialDiscretePositionMessage( PlayerMessage.constructSetInitialDiscretePositionMessage(
realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.x), realm.getServerWorldData().convertRealToChunkSpace(spawnPoint.x),
realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.y), realm.getServerWorldData().convertRealToChunkSpace(spawnPoint.y),
realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.z) realm.getServerWorldData().convertRealToChunkSpace(spawnPoint.z)
) )
); );
//send spawn point //send spawn point
connectionHandler.addMessagetoOutgoingQueue( connectionHandler.addMessagetoOutgoingQueue(
TerrainMessage.constructSpawnPositionMessage(Globals.spawnPoint.x, Globals.spawnPoint.y, Globals.spawnPoint.z) TerrainMessage.constructSpawnPositionMessage(spawnPoint.x, spawnPoint.y, spawnPoint.z)
); );
} }

View File

@ -48,6 +48,7 @@ public class EntityProtocol {
case SETPROPERTY: case SETPROPERTY:
case SPAWNFOLIAGESEED: case SPAWNFOLIAGESEED:
case SPAWNITEM: case SPAWNITEM:
case SPAWNOBJECT:
//silently ignore //silently ignore
break; break;
} }
@ -72,6 +73,7 @@ public class EntityProtocol {
case SETPROPERTY: case SETPROPERTY:
case SPAWNFOLIAGESEED: case SPAWNFOLIAGESEED:
case SPAWNITEM: case SPAWNITEM:
case SPAWNOBJECT:
//silently ignore //silently ignore
break; break;
} }

View File

@ -3,21 +3,17 @@ package electrosphere.net.synchronization;
import electrosphere.net.synchronization.FieldIdEnums; import electrosphere.net.synchronization.FieldIdEnums;
import electrosphere.entity.state.block.ClientBlockTree; import electrosphere.entity.state.block.ClientBlockTree;
import electrosphere.entity.state.block.ServerBlockTree;
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree; import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree;
import electrosphere.entity.state.movement.groundmove.ServerGroundMovementTree;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.entity.state.equip.ClientEquipState; import electrosphere.entity.state.equip.ClientEquipState;
import electrosphere.entity.state.attack.ClientAttackTree; import electrosphere.entity.state.attack.ClientAttackTree;
import electrosphere.entity.state.attack.ServerAttackTree;
import electrosphere.entity.state.equip.ServerEquipState;
import electrosphere.entity.state.gravity.ClientGravityTree; import electrosphere.entity.state.gravity.ClientGravityTree;
import electrosphere.entity.state.gravity.ServerGravityTree;
import electrosphere.entity.state.idle.ServerIdleTree;
import electrosphere.entity.state.idle.ClientIdleTree; import electrosphere.entity.state.idle.ClientIdleTree;
import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
@ -32,6 +28,12 @@ public class ClientSynchronizationManager {
//The list of messages to loop through //The list of messages to loop through
List<SynchronizationMessage> messages = new CopyOnWriteArrayList<SynchronizationMessage>(); List<SynchronizationMessage> messages = new CopyOnWriteArrayList<SynchronizationMessage>();
//Map that tracks the number of times a network message bounces
Map<SynchronizationMessage,Integer> messageBounceCount = new HashMap<SynchronizationMessage,Integer>();
//the count at which to warn about a message bouncing
static final int MESSAGE_BOUNCE_WARNING_COUNT = 10;
/** /**
* Pushes a message into the queue to be processed * Pushes a message into the queue to be processed
* @param message The message * @param message The message
@ -46,8 +48,18 @@ public class ClientSynchronizationManager {
public void processMessages(){ public void processMessages(){
List<SynchronizationMessage> messagesToClear = new LinkedList<SynchronizationMessage>(); List<SynchronizationMessage> messagesToClear = new LinkedList<SynchronizationMessage>();
for(SynchronizationMessage message : messages){ for(SynchronizationMessage message : messages){
//track number of times this message has bounced
if(messageBounceCount.containsKey(message)){
messageBounceCount.put(message, messageBounceCount.get(message) + 1);
} else {
messageBounceCount.put(message, 0);
}
//attempt to handle the message
if(Globals.clientSceneWrapper.containsServerId(message.getentityId()) && Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId()) != null){ if(Globals.clientSceneWrapper.containsServerId(message.getentityId()) && Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId()) != null){
messagesToClear.add(message); messagesToClear.add(message);
messageBounceCount.remove(message);
switch(message.getMessageSubtype()){ switch(message.getMessageSubtype()){
case UPDATECLIENTSTATE:{ case UPDATECLIENTSTATE:{
int bTreeId = message.getbTreeId(); int bTreeId = message.getbTreeId();
@ -71,15 +83,23 @@ public class ClientSynchronizationManager {
int entityId = message.getentityId(); int entityId = message.getentityId();
} break; } break;
} }
} else if(Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId()) == null){ } else if(Globals.clientSceneWrapper.containsServerId(message.getentityId()) && Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId()) == null){
String errorMessage = String errorMessage =
"Client received synchronization packet for entity that does not exists on client!\n" + "Client received synchronization packet for entity that does not exists on client!\n" +
"Specifically, the synchronization manager thinks this id is registered, but there is no entity at that key\n" +
"Entity id in network message: " + message.getentityId() "Entity id in network message: " + message.getentityId()
; ;
Globals.clientSceneWrapper.dumpTranslationLayerStatus(); Globals.clientSceneWrapper.dumpTranslationLayerStatus();
Globals.clientSceneWrapper.dumpIdData(message.getentityId()); Globals.clientSceneWrapper.dumpIdData(message.getentityId());
throw new IllegalStateException(errorMessage); throw new IllegalStateException(errorMessage);
} }
//warn if a message has bounced a certain number of times
if(messageBounceCount.containsKey(message) && messageBounceCount.get(message) > MESSAGE_BOUNCE_WARNING_COUNT){
String warningMessage =
"A synchronization message has bounced at least " + MESSAGE_BOUNCE_WARNING_COUNT + "times!";
LoggerInterface.loggerNetworking.WARNING(warningMessage);
}
} }
for(SynchronizationMessage message : messagesToClear){ for(SynchronizationMessage message : messagesToClear){
messages.remove(message); messages.remove(message);

View File

@ -28,7 +28,8 @@ public class PlayerCharacterCreation {
String raceName = template.getCreatureType(); String raceName = template.getCreatureType();
//spawn entity in world //spawn entity in world
Realm realm = Globals.realmManager.getRealms().iterator().next(); 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); Vector3d spawnPoint = realm.getSpawnPoint();
Entity newPlayerEntity = CreatureUtils.serverSpawnBasicCreature(realm,new Vector3d(spawnPoint.x,spawnPoint.y,spawnPoint.z),raceName,template);
int playerCharacterId = newPlayerEntity.getId(); int playerCharacterId = newPlayerEntity.getId();
connectionHandler.setPlayerEntityId(playerCharacterId); connectionHandler.setPlayerEntityId(playerCharacterId);
CreatureUtils.setControllerPlayerId(newPlayerEntity, connectionHandler.getPlayerId()); CreatureUtils.setControllerPlayerId(newPlayerEntity, connectionHandler.getPlayerId());
@ -37,9 +38,9 @@ public class PlayerCharacterCreation {
//attach player object to player character //attach player object to player character
playerObject.setPlayerEntity(newPlayerEntity); playerObject.setPlayerEntity(newPlayerEntity);
playerObject.setWorldPos(new Vector3i( playerObject.setWorldPos(new Vector3i(
realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.x), realm.getServerWorldData().convertRealToChunkSpace(spawnPoint.x),
realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.y), realm.getServerWorldData().convertRealToChunkSpace(spawnPoint.y),
realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.z) realm.getServerWorldData().convertRealToChunkSpace(spawnPoint.z)
)); ));
realm.getDataCellManager().addPlayerToRealm(playerObject); realm.getDataCellManager().addPlayerToRealm(playerObject);
//parse network messages on client if running //parse network messages on client if running

View File

@ -6,11 +6,7 @@ import org.joml.Vector3i;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.server.content.serialization.ContentSerialization; import electrosphere.server.content.serialization.ContentSerialization;
import electrosphere.server.content.serialization.EntitySerialization;
import electrosphere.server.datacell.Realm; import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.ServerDataCell; import electrosphere.server.datacell.ServerDataCell;
import electrosphere.server.saves.SaveUtils; import electrosphere.server.saves.SaveUtils;
@ -49,7 +45,7 @@ public class ServerContentManager {
if(FileUtils.checkSavePathExists(Globals.currentSave.getName(), fullPath)){ if(FileUtils.checkSavePathExists(Globals.currentSave.getName(), fullPath)){
//if on disk (has already been generated) //if on disk (has already been generated)
ContentSerialization contentRaw = FileUtils.loadObjectFromSavePath(Globals.currentSave.getName(), fullPath, ContentSerialization.class); ContentSerialization contentRaw = FileUtils.loadObjectFromSavePath(Globals.currentSave.getName(), fullPath, ContentSerialization.class);
hydrateRawContent(realm,cell,contentRaw); contentRaw.hydrateRawContent(realm,cell);
} else { } else {
//else create from scratch //else create from scratch
//UNCOMMENT THIS WHEN YOU WANT CONTENT GENERATED FOR WORLDS AGAIN //UNCOMMENT THIS WHEN YOU WANT CONTENT GENERATED FOR WORLDS AGAIN
@ -60,7 +56,7 @@ public class ServerContentManager {
if(FileUtils.checkSavePathExists(Globals.currentSave.getName(), fullPath)){ if(FileUtils.checkSavePathExists(Globals.currentSave.getName(), fullPath)){
//if on disk (has already been generated) //if on disk (has already been generated)
ContentSerialization contentRaw = FileUtils.loadObjectFromSavePath(Globals.currentSave.getName(), fullPath, ContentSerialization.class); ContentSerialization contentRaw = FileUtils.loadObjectFromSavePath(Globals.currentSave.getName(), fullPath, ContentSerialization.class);
hydrateRawContent(realm,cell,contentRaw); contentRaw.hydrateRawContent(realm,cell);
} }
} }
//TODO: generate navmesh //TODO: generate navmesh
@ -86,24 +82,5 @@ public class ServerContentManager {
FileUtils.serializeObjectToFilePath(fullPath, serialization); FileUtils.serializeObjectToFilePath(fullPath, serialization);
} }
/**
* Actually creates the entities from a content serialization
* @param contentRaw The content serialization
*/
public void hydrateRawContent(Realm realm, ServerDataCell serverDataCell, ContentSerialization contentRaw){
List<EntitySerialization> serializedEntities = contentRaw.getSerializedEntities();
for(EntitySerialization serializedEntity : serializedEntities){
switch(serializedEntity.getType()){
case CreatureUtils.ENTITY_TYPE_CREATURE: {
Entity creature = CreatureUtils.serverSpawnBasicCreature(realm, serializedEntity.getPosition(), serializedEntity.getSubtype(), null);
EntityUtils.getRotation(creature).set(serializedEntity.getRotation());
} break;
case ItemUtils.ENTITY_TYPE_ITEM: {
Entity item = ItemUtils.serverSpawnBasicItem(realm, serializedEntity.getPosition(), serializedEntity.getSubtype());
} break;
}
}
}
} }

View File

@ -10,6 +10,8 @@ import electrosphere.entity.types.foliage.FoliageUtils;
import electrosphere.entity.types.item.ItemUtils; import electrosphere.entity.types.item.ItemUtils;
import electrosphere.entity.types.object.ObjectUtils; import electrosphere.entity.types.object.ObjectUtils;
import electrosphere.entity.types.structure.StructureUtils; import electrosphere.entity.types.structure.StructureUtils;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.ServerDataCell;
/** /**
* Contains all content for a given cell * Contains all content for a given cell
@ -46,7 +48,12 @@ public class ContentSerialization {
rVal.serializedEntities.add(serializedEntity); rVal.serializedEntities.add(serializedEntity);
} }
if(ObjectUtils.isObject(entity)){ if(ObjectUtils.isObject(entity)){
throw new UnsupportedOperationException(); EntitySerialization serializedEntity = new EntitySerialization();
serializedEntity.setPosition(EntityUtils.getPosition(entity));
serializedEntity.setRotation(EntityUtils.getRotation(entity));
serializedEntity.setType(ObjectUtils.ENTITY_TYPE_OBJECT);
serializedEntity.setSubtype(ObjectUtils.getType(entity));
rVal.serializedEntities.add(serializedEntity);
} }
if(StructureUtils.isStructure(entity)){ if(StructureUtils.isStructure(entity)){
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
@ -59,6 +66,30 @@ public class ContentSerialization {
return rVal; return rVal;
} }
/**
* Actually creates the entities from a content serialization
* @param contentRaw The content serialization
*/
public void hydrateRawContent(Realm realm, ServerDataCell serverDataCell){
List<EntitySerialization> serializedEntities = this.getSerializedEntities();
for(EntitySerialization serializedEntity : serializedEntities){
switch(serializedEntity.getType()){
case CreatureUtils.ENTITY_TYPE_CREATURE: {
Entity creature = CreatureUtils.serverSpawnBasicCreature(realm, serializedEntity.getPosition(), serializedEntity.getSubtype(), null);
EntityUtils.getRotation(creature).set(serializedEntity.getRotation());
} break;
case ItemUtils.ENTITY_TYPE_ITEM: {
Entity item = ItemUtils.serverSpawnBasicItem(realm, serializedEntity.getPosition(), serializedEntity.getSubtype());
EntityUtils.getRotation(item).set(serializedEntity.getRotation());
} break;
case ObjectUtils.ENTITY_TYPE_OBJECT: {
Entity object = ObjectUtils.serverSpawnBasicObject(realm, serializedEntity.getPosition(), serializedEntity.getSubtype());
EntityUtils.getRotation(object).set(serializedEntity.getRotation());
} break;
}
}
}
/** /**
* Gets all serialized entities * Gets all serialized entities
* @return the list of serialized entities * @return the list of serialized entities

View File

@ -12,8 +12,12 @@ import electrosphere.server.content.ServerContentManager;
import electrosphere.server.datacell.interfaces.DataCellManager; import electrosphere.server.datacell.interfaces.DataCellManager;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set; import java.util.Set;
import org.joml.Vector3d;
/** /**
* Manages data cells on the server side * Manages data cells on the server side
@ -58,6 +62,11 @@ public class Realm {
*/ */
int sceneInstanceId = NO_SCENE_INSTANCE; int sceneInstanceId = NO_SCENE_INSTANCE;
/**
* The list of available spawnpoints
*/
List<Vector3d> spawnPoints = new LinkedList<Vector3d>();
/** /**
* Realm constructor * Realm constructor
* @param collisionEngine The collision engine for the realm * @param collisionEngine The collision engine for the realm
@ -229,6 +238,26 @@ public class Realm {
return this.serverContentManager; return this.serverContentManager;
} }
/**
* Gets the spawn point for the realm
* @return The spawn point
*/
public Vector3d getSpawnPoint(){
if(this.spawnPoints.size() > 0){
return this.spawnPoints.get(0);
} else {
return new Vector3d(0,0,0);
}
}
/**
* Registers a spawn point
* @param point The spawn point location
*/
public void registerSpawnPoint(Vector3d point){
this.spawnPoints.add(point);
}
/** /**
* Sets the script-engine side instance id for the scene that was loaded with this realm * Sets the script-engine side instance id for the scene that was loaded with this realm
* @param sceneInstanceId The instance id * @param sceneInstanceId The instance id

View File

@ -6,6 +6,7 @@ import electrosphere.entity.Scene;
import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.foliage.FoliageUtils; import electrosphere.entity.types.foliage.FoliageUtils;
import electrosphere.entity.types.item.ItemUtils; import electrosphere.entity.types.item.ItemUtils;
import electrosphere.entity.types.object.ObjectUtils;
import electrosphere.entity.types.structure.StructureUtils; import electrosphere.entity.types.structure.StructureUtils;
import electrosphere.game.server.character.Character; import electrosphere.game.server.character.Character;
import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.net.parser.net.message.EntityMessage;
@ -149,6 +150,9 @@ public class ServerDataCell {
if(ItemUtils.isItem(entity)){ if(ItemUtils.isItem(entity)){
ItemUtils.sendEntityToPlayer(player, entity); ItemUtils.sendEntityToPlayer(player, entity);
} }
if(ObjectUtils.isObject(entity)){
ObjectUtils.sendEntityToPlayer(player,entity);
}
if(StructureUtils.isStructure(entity)){ if(StructureUtils.isStructure(entity)){
StructureUtils.sendStructureToPlayer(player, entity); StructureUtils.sendStructureToPlayer(player, entity);
} }

View File

@ -17,6 +17,7 @@ import electrosphere.entity.state.movement.ProjectileTree;
import electrosphere.entity.types.attach.AttachUtils; import electrosphere.entity.types.attach.AttachUtils;
import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.item.ItemUtils; import electrosphere.entity.types.item.ItemUtils;
import electrosphere.server.datacell.Realm;
/** /**
* Callback for managing collisions on the server * Callback for managing collisions on the server
@ -64,7 +65,8 @@ public class ServerHitboxResolutionCallback implements CollisionResolutionCallba
LifeUtils.getLifeState(receiverParent).damage(damage); LifeUtils.getLifeState(receiverParent).damage(damage);
if(!LifeUtils.getLifeState(receiverParent).isIsAlive()){ if(!LifeUtils.getLifeState(receiverParent).isIsAlive()){
System.out.println("ServerHitboxResolutionCallback - Unimplemented!!"); System.out.println("ServerHitboxResolutionCallback - Unimplemented!!");
EntityUtils.getPosition(receiverParent).set(Globals.spawnPoint); Realm entityRealm = Globals.realmManager.getEntityRealm(receiverParent);
EntityUtils.getPosition(receiverParent).set(entityRealm.getSpawnPoint());
LifeUtils.getLifeState(receiverParent).revive(); LifeUtils.getLifeState(receiverParent).revive();
} }
} }
@ -82,7 +84,8 @@ public class ServerHitboxResolutionCallback implements CollisionResolutionCallba
LifeUtils.getLifeState(receiverParent).damage(damage); LifeUtils.getLifeState(receiverParent).damage(damage);
if(!LifeUtils.getLifeState(receiverParent).isIsAlive()){ if(!LifeUtils.getLifeState(receiverParent).isIsAlive()){
System.out.println("ServerHitboxResolutionCallback - Unimplemented!!"); System.out.println("ServerHitboxResolutionCallback - Unimplemented!!");
EntityUtils.getPosition(receiverParent).set(Globals.spawnPoint); Realm entityRealm = Globals.realmManager.getEntityRealm(receiverParent);
EntityUtils.getPosition(receiverParent).set(entityRealm.getSpawnPoint());
LifeUtils.getLifeState(receiverParent).revive(); LifeUtils.getLifeState(receiverParent).revive();
} }
} }