Renderer/src/main/java/electrosphere/entity/ServerEntityUtils.java
austin cdd44bd362
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
bugfixes
2024-09-12 19:13:34 -04:00

140 lines
5.4 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.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){
//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);
//initialize server datacell tracking of this entity
realm.initializeServerSideEntity(entity, cell);
}
}
/**
* 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
ServerDataCell oldDataCell = realm.getDataCellManager().getDataCellAtPoint(EntityUtils.getPosition(entity));
ServerDataCell newDataCell = realm.getDataCellManager().getDataCellAtPoint(position);
if(oldDataCell != newDataCell){
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);
}
}
}
//reposition entity
CollisionObjUtils.serverPositionCharacter(entity, 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!");
}
//
//destroy the child entities, too
if(AttachUtils.hasChildren(entity)){
List<Entity> children = AttachUtils.getChildrenList(entity);
for(Entity child : children){
ServerEntityUtils.destroyEntity(child);
}
}
//
//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);
Globals.realmManager.removeEntity(entity);
EntityLookupUtils.removeEntity(entity);
if(Globals.aiManager != null){
Globals.aiManager.removeAI(entity);
}
//
//deregister all behavior trees
EntityUtils.cleanUpEntity(entity);
}
/**
* 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);
}
}