Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
181 lines
7.1 KiB
Java
181 lines
7.1 KiB
Java
package electrosphere.entity;
|
|
|
|
import java.util.List;
|
|
|
|
import org.joml.Vector3d;
|
|
|
|
import electrosphere.engine.Globals;
|
|
import electrosphere.entity.state.attach.AttachUtils;
|
|
import electrosphere.entity.state.hitbox.HitboxCollectionState;
|
|
import electrosphere.entity.types.collision.CollisionObjUtils;
|
|
import electrosphere.logger.LoggerInterface;
|
|
import electrosphere.net.parser.net.message.EntityMessage;
|
|
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;
|
|
|
|
/**
|
|
* 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.
|
|
* <p>
|
|
* !!NOTE!!: This function must be called after the entity has fully been created.
|
|
* The initializeServerSideEntity logic requires knowing the type of entity (creature, foliage, etc)
|
|
* which is typically set further in the function than the initial "spawnServerEntity" that returns
|
|
* the actual Entity() object.
|
|
* </p>
|
|
* @param entity
|
|
* @param position
|
|
*/
|
|
public static void initiallyPositionEntity(Realm realm, Entity entity, Vector3d position){
|
|
if(position == null){
|
|
throw new Error("Trying to set server entity position to null!");
|
|
}
|
|
//reposition entity, if the position isn't correct then it will spawn at 0,0,0 when the synchronization part is called
|
|
CollisionObjUtils.serverPositionCharacter(entity, position);
|
|
//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);
|
|
if(cell == null){
|
|
throw new Error("Trying to initially position entity to position that cannot generate a data cell! " + position);
|
|
}
|
|
//initialize server datacell tracking of this entity
|
|
realm.initializeServerSideEntity(entity, cell);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Called to reposition the entity
|
|
* @param entity
|
|
* @param position
|
|
*/
|
|
public static void repositionEntity(Entity entity, Vector3d position){
|
|
if(position == null){
|
|
throw new Error("Trying to set server entity position to null!");
|
|
}
|
|
if(AttachUtils.getParent(entity) != null){
|
|
throw new Error("Trying to reposition attached entity!");
|
|
}
|
|
Realm realm = Globals.realmManager.getEntityRealm(entity);
|
|
if(position.x < 0 || position.y < 0 || position.z < 0){
|
|
throw new Error("Providing invalid location to reposition! " + position);
|
|
}
|
|
ServerEntityUtils.repositionEntityRecursive(realm, entity, position);
|
|
//reposition entity
|
|
CollisionObjUtils.serverPositionCharacter(entity, position);
|
|
}
|
|
|
|
/**
|
|
* Called to reposition the entity
|
|
* @param realm The realm containing the entity
|
|
* @param entity The entity
|
|
* @param position The new position for the entity
|
|
*/
|
|
protected static void repositionEntityRecursive(Realm realm, Entity entity, Vector3d position){
|
|
//if server, get current server data cell
|
|
ServerDataCell oldDataCell = Globals.entityDataCellMapper.getEntityDataCell(entity);
|
|
ServerDataCell newDataCell = realm.getDataCellManager().getDataCellAtPoint(position);
|
|
if(oldDataCell == null){
|
|
LoggerInterface.loggerEngine.WARNING(
|
|
"Trying to reposition entity on server when it's former cell is null!\n" +
|
|
"Entity original position: " + EntityUtils.getPosition(entity) + "\n"
|
|
);
|
|
}
|
|
if(oldDataCell != newDataCell){
|
|
if(newDataCell == null){
|
|
newDataCell = realm.getDataCellManager().tryCreateCellAtPoint(position);
|
|
if(newDataCell == null){
|
|
LoggerInterface.loggerEngine.WARNING(
|
|
"Trying to reposition entity on server when it's new cell is null!\n" +
|
|
"Entity new position: " + position + "\n"
|
|
);
|
|
}
|
|
}
|
|
ServerDataCell.moveEntityFromCellToCell(entity, oldDataCell, newDataCell);
|
|
ServerBehaviorTreeUtils.updateCell(entity, oldDataCell);
|
|
if(oldDataCell.getScene().containsEntity(entity)){
|
|
throw new Error("Entity not removed from scene!");
|
|
}
|
|
}
|
|
if(AttachUtils.hasChildren(entity)){
|
|
List<Entity> children = AttachUtils.getChildrenList(entity);
|
|
for(Entity child : children){
|
|
repositionEntityRecursive(realm, child, position);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Destroys an entity on the server
|
|
* @param entity the entity to destroy
|
|
*/
|
|
public static void destroyEntity(Entity entity){
|
|
if(entity == null){
|
|
throw new IllegalArgumentException("Trying to destroy null!");
|
|
}
|
|
|
|
//
|
|
//get info required to destroy
|
|
Realm realm = Globals.realmManager.getEntityRealm(entity);
|
|
ServerDataCell cell = null;
|
|
|
|
//
|
|
//realm specific logic
|
|
if(realm != null){
|
|
realm.getCollisionEngine().destroyPhysics(entity);
|
|
cell = DataCellSearchUtils.getEntityDataCell(entity);
|
|
}
|
|
|
|
//
|
|
//cell specific logic
|
|
if(cell != null){
|
|
cell.broadcastNetworkMessage(EntityMessage.constructDestroyMessage(entity.getId()));
|
|
ServerBehaviorTreeUtils.deregisterEntity(entity);
|
|
cell.getScene().deregisterEntity(entity);
|
|
}
|
|
|
|
//
|
|
//detatch from all global tracking
|
|
HitboxCollectionState.destroyHitboxState(entity,true);
|
|
Globals.realmManager.removeEntity(entity);
|
|
EntityLookupUtils.removeEntity(entity);
|
|
if(Globals.aiManager != null){
|
|
Globals.aiManager.removeAI(entity);
|
|
}
|
|
|
|
//
|
|
//deregister all behavior trees
|
|
EntityUtils.cleanUpEntity(entity);
|
|
|
|
//
|
|
//destroy the child entities, too
|
|
if(AttachUtils.hasChildren(entity)){
|
|
List<Entity> children = AttachUtils.getChildrenList(entity);
|
|
for(Entity child : children){
|
|
ServerEntityUtils.destroyEntity(child);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Guarantees that the returned position is in bounds of the server realm
|
|
* @param realm The realm to test
|
|
* @param position the position
|
|
* @return Either the position if it is in bounds, or the closest position that is in bounds
|
|
*/
|
|
public static Vector3d guaranteePositionIsInBounds(Realm realm, Vector3d position){
|
|
return realm.getDataCellManager().guaranteePositionIsInBounds(position);
|
|
}
|
|
|
|
}
|