scene/save refactor

This commit is contained in:
austin 2024-07-13 21:11:46 -04:00
parent 4e0459e460
commit 2b68231789
63 changed files with 1611 additions and 820 deletions

Binary file not shown.

View File

@ -190,7 +190,6 @@ public class Globals {
//
//Server scene management
//
public static ServerWorldData serverWorldData;
public static RealmManager realmManager;
public static EntityDataCellMapper entityDataCellMapper;
@ -277,20 +276,9 @@ public class Globals {
//
//Engine - Main managers/variables
//
//terrain manager
// public static boolean LOAD_TERRAIN = true;
public static ServerTerrainManager serverTerrainManager;
//fluid manager
public static ServerFluidManager serverFluidManager;
//spawn point
public static Vector3d spawnPoint = new Vector3d(0,0,0);
//content manager
public static ServerContentManager serverContentManager;
//manages all models loaded into memory
public static AssetManager assetManager;

View File

@ -14,6 +14,7 @@ import electrosphere.controls.ControlHandler;
import electrosphere.controls.ControlHandler.ControlsState;
import electrosphere.engine.cli.CLIParser;
import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.engine.loadingthreads.LoadingThread.LoadingThreadType;
import electrosphere.engine.time.Timekeeper;
import electrosphere.game.config.UserSettings;
import electrosphere.game.server.world.MacroData;
@ -198,11 +199,11 @@ public class Main {
//fire off a loading thread for the title menus/screen
LoggerInterface.loggerStartup.INFO("Fire off loading thread");
if(Globals.RUN_DEMO){
LoadingThread serverThread = new LoadingThread(LoadingThread.LOAD_DEMO_MENU);
LoadingThread serverThread = new LoadingThread(LoadingThreadType.DEMO_MENU);
Globals.loadingThreadsList.add(serverThread);
serverThread.start();
} else if(Globals.RUN_CLIENT){
LoadingThread serverThread = new LoadingThread(LoadingThread.LOAD_TITLE_MENU);
LoadingThread serverThread = new LoadingThread(LoadingThreadType.TITLE_MENU);
Globals.loadingThreadsList.add(serverThread);
serverThread.start();
} else {

View File

@ -4,7 +4,7 @@ import java.util.concurrent.TimeUnit;
import electrosphere.auth.AuthenticationManager;
import electrosphere.engine.Globals;
import electrosphere.game.server.world.ServerWorldData;
import electrosphere.entity.scene.SceneGenerator;
import electrosphere.logger.LoggerInterface;
import electrosphere.menu.MenuGenerators;
import electrosphere.menu.WindowStrings;
@ -12,13 +12,7 @@ import electrosphere.menu.WindowUtils;
import electrosphere.net.parser.net.message.TerrainMessage;
import electrosphere.net.server.ServerConnectionHandler;
import electrosphere.renderer.ui.elements.Window;
import electrosphere.server.content.ServerContentManager;
import electrosphere.server.fluid.generation.DefaultFluidGenerator;
import electrosphere.server.fluid.manager.ServerFluidManager;
import electrosphere.server.saves.SaveUtils;
import electrosphere.server.terrain.generation.OverworldChunkGenerator;
import electrosphere.server.terrain.manager.ServerTerrainManager;
import electrosphere.util.FileUtils;
public class DebugSPWorldLoading {
@ -30,34 +24,19 @@ public class DebugSPWorldLoading {
WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu());
loadingWindow.setVisible(true);
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,0.0f,0, new OverworldChunkGenerator());
String saveName = "random_sp_world";
if(!SaveUtils.getSaves().contains(saveName)){
//
//the juicy server GENERATION part
//
//init save structure
SaveUtils.createOrOverwriteSave(saveName);
//create terrain
Globals.serverTerrainManager.generate();
Globals.serverTerrainManager.save(saveName);
//create world.json
Globals.serverWorldData = ServerWorldData.createGameWorld(Globals.serverTerrainManager);
FileUtils.serializeObjectToSavePath(saveName, "./world.json", Globals.serverWorldData);
//create mock fluid sim manager
Globals.serverFluidManager = new ServerFluidManager(Globals.serverTerrainManager, 2000, 50, 0.0f, 0, new DefaultFluidGenerator());
SaveUtils.createOrOverwriteSave(saveName, SceneGenerator.createProceduralSceneFile(saveName));
}
//load just-created save
SaveUtils.loadSave(saveName);
//start initializing game datastructures
// Globals.griddedDataCellManager.init(Globals.serverWorldData);
//initialize the "virtual" objects simulation
LoadingUtils.initMacroSimulation();
Globals.serverContentManager = ServerContentManager.createServerContentManager(true);
LoadingUtils.initGriddedRealm();
LoggerInterface.loggerEngine.INFO("run server: " + Globals.RUN_SERVER + " run client: " + Globals.RUN_CLIENT);
//init authentication

View File

@ -4,14 +4,15 @@ import java.util.concurrent.TimeUnit;
import electrosphere.auth.AuthenticationManager;
import electrosphere.engine.Globals;
import electrosphere.entity.scene.SceneFile;
import electrosphere.logger.LoggerInterface;
import electrosphere.menu.MenuGenerators;
import electrosphere.menu.WindowStrings;
import electrosphere.menu.WindowUtils;
import electrosphere.menu.mainmenu.MenuGeneratorsLevelEditor.LevelDescription;
import electrosphere.net.parser.net.message.TerrainMessage;
import electrosphere.net.server.ServerConnectionHandler;
import electrosphere.renderer.ui.elements.Window;
import electrosphere.server.content.ServerContentManager;
import electrosphere.server.saves.SaveUtils;
/**
@ -23,10 +24,22 @@ public class LevelEditorLoading {
* Loads the level editor
*/
protected static void loadLevelEditor(Object[] params){
//
// Get params to create the level with
//
if(params.length < 1){
throw new IllegalStateException("Trying to load level editor with insufficient params");
}
String saveName = (String)params[0];
LevelDescription description = (LevelDescription)params[0];
String saveName = description.getName();
SceneFile sceneFile = description.getSceneFile();
//
//Set params we would expect to run with this thread
//
Globals.RUN_CLIENT = true;
Globals.RUN_SERVER = true;
Window loadingWindow = (Window)Globals.elementManager.getWindow(WindowStrings.WINDOW_LOADING);
@ -37,18 +50,11 @@ public class LevelEditorLoading {
if(!SaveUtils.getSaves().contains(saveName)){
//init save structure
SaveUtils.createOrOverwriteSave(saveName);
SaveUtils.createOrOverwriteSave(saveName,sceneFile);
}
//load just-created save
SaveUtils.loadSave(saveName);
//init server content manager
Globals.serverContentManager = ServerContentManager.createServerContentManager(false);
//creates a gridded realm
LoadingUtils.initGriddedRealm();
LoggerInterface.loggerEngine.INFO("run server: " + Globals.RUN_SERVER + " run client: " + Globals.RUN_CLIENT);
//init authentication
LoadingUtils.initAuthenticationManager();

View File

@ -11,7 +11,6 @@ import electrosphere.menu.WindowUtils;
import electrosphere.net.parser.net.message.TerrainMessage;
import electrosphere.net.server.ServerConnectionHandler;
import electrosphere.renderer.ui.elements.Window;
import electrosphere.server.content.ServerContentManager;
import electrosphere.server.saves.SaveUtils;
/**
@ -34,16 +33,9 @@ public class LevelLoading {
WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu());
loadingWindow.setVisible(true);
//load just-created save
//load save
SaveUtils.loadSave(saveName);
//init server content manager
Globals.serverContentManager = ServerContentManager.createServerContentManager(false);
//creates a gridded realm
LoadingUtils.initGriddedRealm();
LoggerInterface.loggerEngine.INFO("run server: " + Globals.RUN_SERVER + " run client: " + Globals.RUN_CLIENT);
//init authentication
LoadingUtils.initAuthenticationManager();
@ -59,7 +51,6 @@ public class LevelLoading {
e.printStackTrace();
}
}
//load level on server
//initialize the "real" objects simulation
LoadingUtils.initMicroSimulation();

View File

@ -7,17 +7,57 @@ import java.util.concurrent.Semaphore;
*/
public class LoadingThread extends Thread {
public static final int LOAD_TITLE_MENU = 0; //loads the main game title menu
public static final int LOAD_MAIN_GAME = 1; //loads the main game
public static final int LOAD_CHARACTER_SERVER = 3; //loads the character creation menus on the client
public static final int LOAD_CLIENT_WORLD = 4; //loads the client world
public static final int LOAD_DEBUG_RANDOM_SP_WORLD = 5; //loads a random singleplayer debug world
public static final int LOAD_LEVEL_EDITOR = 6; //loads the level editor
public static final int LOAD_LEVEL = 7; //loads a level
public static final int LOAD_DEMO_MENU = 8; //loads the main menu ui for the demo version of the client
/**
* The types of threads available
*/
public static enum LoadingThreadType {
/**
* Loads the main game title menu
*/
TITLE_MENU,
/**
* Loads the main game
*/
MAIN_GAME,
/**
* Loads the character creation menus on the client
*/
CHARACTER_SERVER,
/**
* Loads the client world
*/
CLIENT_WORLD,
/**
* Loads a random singleplayer debug world
*/
DEBUG_RANDOM_SP_WORLD,
/**
* Loads the level editor
*/
LEVEL_EDITOR,
/**
* Loads a level
*/
LEVEL,
/**
* Loads the main menu ui for the demo version of the client
*/
DEMO_MENU,
}
//the type of loading to do
int threadType;
/**
* The type of loading to run
*/
LoadingThreadType threadType;
//the params provided to this thread in particular
Object[] params;
@ -30,7 +70,7 @@ public class LoadingThread extends Thread {
* @param type The type of thread
* @param params The params provided to the thread
*/
public LoadingThread(int type, Object ... params){
public LoadingThread(LoadingThreadType type, Object ... params){
threadType = type;
this.params = params;
lock = new Semaphore(1);
@ -41,40 +81,40 @@ public class LoadingThread extends Thread {
lock.acquireUninterruptibly();
switch(threadType){
case LOAD_TITLE_MENU: {
case TITLE_MENU: {
ClientLoading.loadMainMenu(this.params);
} break;
case LOAD_MAIN_GAME: {
case MAIN_GAME: {
ServerLoading.loadMainGameServer(this.params);
} break;
case LOAD_CHARACTER_SERVER: {
case CHARACTER_SERVER: {
ClientLoading.loadCharacterServer(this.params);
} break;
case LOAD_CLIENT_WORLD: {
case CLIENT_WORLD: {
ClientLoading.loadClientWorld(this.params);
} break;
//intended to act like you went through the steps of setting up a vanilla settings SP world
case LOAD_DEBUG_RANDOM_SP_WORLD: {
case DEBUG_RANDOM_SP_WORLD: {
DebugSPWorldLoading.loadDebugSPWorld(this.params);
} break;
//loads the level editor
case LOAD_LEVEL_EDITOR: {
case LEVEL_EDITOR: {
LevelEditorLoading.loadLevelEditor(this.params);
} break;
//loads the save in Globals.currentSave as a level
case LOAD_LEVEL: {
case LEVEL: {
LevelLoading.loadLevel(this.params);
} break;
//the demo menu ui
case LOAD_DEMO_MENU: {
case DEMO_MENU: {
DemoLoading.loadDemoMenu(this.params);
} break;

View File

@ -4,7 +4,6 @@ import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.joml.Vector3i;
@ -14,7 +13,6 @@ import electrosphere.entity.types.creature.CreatureTemplate;
import electrosphere.game.data.creature.type.CreatureType;
import electrosphere.game.data.creature.type.visualattribute.VisualAttribute;
import electrosphere.game.server.world.MacroData;
import electrosphere.game.server.world.ServerWorldData;
import electrosphere.net.NetUtils;
import electrosphere.net.client.ClientNetworking;
import electrosphere.net.parser.net.message.CharacterMessage;
@ -24,8 +22,6 @@ import electrosphere.net.server.player.Player;
import electrosphere.server.datacell.Realm;
import electrosphere.server.simulation.MacroSimulation;
import electrosphere.server.simulation.MicroSimulation;
import electrosphere.server.terrain.generation.OverworldChunkGenerator;
import electrosphere.server.terrain.manager.ServerTerrainManager;
/**
* Utilities for all loading thread types
@ -33,32 +29,6 @@ import electrosphere.server.terrain.manager.ServerTerrainManager;
public class LoadingUtils {
static void initServerGameTerrainManager(){
/*
Actually initialize the terrain manager
*/
float randomDampener = 0.0f; //0.25f;
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,randomDampener,0,new OverworldChunkGenerator());
}
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){
@ -140,13 +110,6 @@ public class LoadingUtils {
}
return rVal;
}
/**
* Spins up the gridded data cell manager
*/
protected static void initGriddedRealm(){
Realm griddedRealm = Globals.realmManager.createGriddedRealm(Globals.serverWorldData);
}
/**
@ -207,10 +170,11 @@ public class LoadingUtils {
//set player world-space coordinates
Player playerObject = Globals.playerManager.getPlayerFromId(0);
Realm realm = Globals.realmManager.getRealms().iterator().next();
playerObject.setWorldPos(new Vector3i(
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.x),
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.y),
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.z)
realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.x),
realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.y),
realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.z)
));
}

View File

@ -15,7 +15,7 @@ public class ServerLoading {
// }
//TODO: Globals.serverTerrainManager = new ServerTerrainManager(2000,50,100,randomDampener,0);
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,0.0f,0, new OverworldChunkGenerator());
// Globals.serverTerrainManager = new ServerTerrainManager(2000,50,0.0f,0, new OverworldChunkGenerator());
// SaveUtils.loadSave(Globals.currentSaveName);
// LoadingUtils.initTerrainDataCellManager();
//TODO: set spawnpoint

View File

@ -33,6 +33,10 @@ public class EntityCreationUtils {
//initialize server datacell tracking of this entity
cell = realm.getDataCellManager().tryCreateCellAtPoint(position);
}
//If a server data cell was not created, this is considered illegal state
if(cell == null){
throw new IllegalStateException("Failed to create a server data cell");
}
//register to entity data cell mapper
realm.getEntityDataCellMapper().registerEntity(rVal, cell);
//enable behavior tree tracking

View File

@ -9,16 +9,17 @@ public class RealmDescriptor {
* A gridded realm
*/
public static final String REALM_DESCRIPTOR_GRIDDED = "gridded";
public static final String REALM_DESCRIPTOR_PROCEDURAL = "procedural";
/**
* The type of realm
*/
String type;
String type = REALM_DESCRIPTOR_GRIDDED;
/**
* If this is a gridded realm, what is the dimension of the realm
* If this is a gridded realm, what is the size of the realm
*/
int griddedRealmDimension;
int griddedRealmSize;
/**
@ -30,11 +31,27 @@ public class RealmDescriptor {
}
/**
* Gets the dimensions of the gridded realm
* @return The dimension
* Sets the type of realm
* @param realmType The realm type
*/
public int getGriddedRealmDimension(){
return griddedRealmDimension;
public void setType(String realmType){
this.type = realmType;
}
/**
* Gets the size of the gridded realm
* @return The size
*/
public int getGriddedRealmSize(){
return griddedRealmSize;
}
/**
* Sets the size of the gridded realm
* @param size The size
*/
public void setGriddedRealmSize(int size){
this.griddedRealmSize = size;
}
}

View File

@ -1,5 +1,6 @@
package electrosphere.entity.scene;
import java.util.LinkedList;
import java.util.List;
/**
@ -27,6 +28,27 @@ public class SceneFile {
*/
RealmDescriptor realmDescriptor;
/**
* Private constructor
*/
private SceneFile(){
}
/**
* Creates a scene file
* @return The scene file
*/
public static SceneFile createSceneFile(){
SceneFile rVal = new SceneFile();
rVal.entities = new LinkedList<EntityDescriptor>();
rVal.scriptPaths = new LinkedList<String>();
rVal.initScriptPath = null;
rVal.realmDescriptor = new RealmDescriptor();
return rVal;
}
/**
* Gets the paths of all scripts in this scene
* @return The list of all paths
@ -51,4 +73,12 @@ public class SceneFile {
return initScriptPath;
}
/**
* Gets the realm descriptor
* @return The realm descriptor
*/
public RealmDescriptor getRealmDescriptor(){
return realmDescriptor;
}
}

View File

@ -1,6 +1,12 @@
package electrosphere.entity.scene;
import java.util.LinkedList;
import electrosphere.game.server.world.ServerWorldData;
import electrosphere.server.datacell.GriddedDataCellManager;
import electrosphere.server.fluid.generation.DefaultFluidGenerator;
import electrosphere.server.fluid.manager.ServerFluidManager;
import electrosphere.server.terrain.generation.OverworldChunkGenerator;
import electrosphere.server.terrain.manager.ServerTerrainManager;
import electrosphere.util.FileUtils;
/**
* Generates scene files where appropriate (ie, if playing the procedurally generated level)
@ -9,19 +15,26 @@ public class SceneGenerator {
/**
* Creates a scene file for the procedurally generated gamemode
* @param gridSize The size of the terrain grid of the scene
* @return The scene file
*/
public static SceneFile createProceduralSceneFile(int gridDimension){
public static SceneFile createProceduralSceneFile(String saveName){
//base file stuff
SceneFile file = new SceneFile();
file.entities = new LinkedList<EntityDescriptor>();
file.initScriptPath = null;
file.scriptPaths = new LinkedList<String>();
SceneFile file = SceneFile.createSceneFile();
//realm descriptor stuff
file.realmDescriptor = new RealmDescriptor();
file.realmDescriptor.type = RealmDescriptor.REALM_DESCRIPTOR_GRIDDED;
file.realmDescriptor.griddedRealmDimension = gridDimension;
file.realmDescriptor.type = RealmDescriptor.REALM_DESCRIPTOR_PROCEDURAL;
file.realmDescriptor.griddedRealmSize = GriddedDataCellManager.MAX_GRID_SIZE;
//create terrain
ServerWorldData serverWorldData = ServerWorldData.createGriddedRealmWorldData(2000);
ServerTerrainManager serverTerrainManager = new ServerTerrainManager(serverWorldData, 0, new OverworldChunkGenerator());
serverTerrainManager.generate();
serverTerrainManager.save(saveName);
//create world.json
FileUtils.serializeObjectToSavePath(saveName, "./world.json", serverWorldData);
//create mock fluid sim manager
ServerFluidManager serverFluidManager = new ServerFluidManager(serverWorldData, serverTerrainManager, 0, new DefaultFluidGenerator());
serverFluidManager.save(saveName);
return file;
}

View File

@ -8,6 +8,8 @@ import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.entity.types.object.ObjectUtils;
import electrosphere.game.server.world.ServerWorldData;
import electrosphere.server.content.ServerContentManager;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.ServerDataCell;
import electrosphere.util.FileUtils;
@ -19,12 +21,57 @@ public class SceneLoader {
/**
* Loads a scene file on the server
* @param path The path in the assets directory to a scene file
* @param path The name of the save to look for a scene file within
*/
public ServerDataCell serverInstantiateSceneFile(String path){
Realm realm = Globals.realmManager.createRealm();
public static void serverInstantiateSaveSceneFile(String saveName, ServerWorldData serverWorldData){
//load scene file
SceneFile file = FileUtils.loadObjectFromSavePath(saveName, "/scene.json", SceneFile.class);
//instantiate scene data
serverInstantiateSceneFile(file,serverWorldData);
}
/**
* Loads a scene file on the server
* @param path The name of the scene in the assets/scenes folder
*/
public static void serverInstantiateAssetSceneFile(String sceneName, ServerWorldData serverWorldData){
//load scene file
String sanitizedPath = FileUtils.sanitizeFilePath("/Scenes/" + sceneName + "/scene.json");
SceneFile file = FileUtils.loadObjectFromAssetPath(sanitizedPath, SceneFile.class);
//instantiate scene data
serverInstantiateSceneFile(file,serverWorldData);
}
/**
* Loads a scene file on the server
* @param path The path in the assets directory to a scene file
* @param isSave if true, will try to load scene from save file instead of asset file
*/
private static void serverInstantiateSceneFile(SceneFile file, ServerWorldData serverWorldData){
//
//Content manager
//
ServerContentManager serverContentManager = null;
if(file.realmDescriptor.getType() == RealmDescriptor.REALM_DESCRIPTOR_PROCEDURAL){
serverContentManager = ServerContentManager.createServerContentManager(true);
} else {
serverContentManager = ServerContentManager.createServerContentManager(false);
}
//
//Init the realm
//
Realm realm = null;
switch(file.realmDescriptor.getType()){
case RealmDescriptor.REALM_DESCRIPTOR_GRIDDED: {
realm = Globals.realmManager.createGriddedRealm(serverWorldData,serverContentManager);
} break;
case RealmDescriptor.REALM_DESCRIPTOR_PROCEDURAL: {
realm = Globals.realmManager.createRealm();
} break;
}
ServerDataCell rVal = realm.createNewCell();
SceneFile file = FileUtils.loadObjectFromAssetPath(path, SceneFile.class);
//spawn initial entities
for(EntityDescriptor descriptor : file.getEntities()){
//spawn entity somehow
@ -62,9 +109,7 @@ public class SceneLoader {
// }
// Globals.scriptEngine.runScript(file.getInitScriptPath());
//instruct client to load the scene
return rVal;
//TODO: instruct client to load the scene
}
}

View File

@ -69,14 +69,14 @@ public class ServerCollidableTree implements BehaviorTree {
}
Realm realm = Globals.realmManager.getEntityRealm(parent);
//bound to world bounds
if(newPosition.x < Globals.serverWorldData.getWorldBoundMin().x){
newPosition.x = Globals.serverWorldData.getWorldBoundMin().x;
if(newPosition.x < realm.getServerWorldData().getWorldBoundMin().x){
newPosition.x = realm.getServerWorldData().getWorldBoundMin().x;
}
if(newPosition.y < Globals.serverWorldData.getWorldBoundMin().y){
newPosition.y = Globals.serverWorldData.getWorldBoundMin().y;
if(newPosition.y < realm.getServerWorldData().getWorldBoundMin().y){
newPosition.y = realm.getServerWorldData().getWorldBoundMin().y;
}
if(newPosition.z < Globals.serverWorldData.getWorldBoundMin().z){
newPosition.z = Globals.serverWorldData.getWorldBoundMin().z;
if(newPosition.z < realm.getServerWorldData().getWorldBoundMin().z){
newPosition.z = realm.getServerWorldData().getWorldBoundMin().z;
}
PhysicsUtils.setRigidBodyTransform(realm.getCollisionEngine(), newPosition, rotation, body);
}

View File

@ -16,8 +16,9 @@ public class VirtualStructureUtils {
public static Structure placeStructureAtPoint(float posX, float posY, float posZ, String type){
int worldX = Globals.serverWorldData.convertRealToChunkSpace(posX);
int worldY = Globals.serverWorldData.convertRealToChunkSpace(posY);
Realm realm = Globals.realmManager.getRealms().iterator().next();
int worldX = realm.getServerWorldData().convertRealToChunkSpace(posX);
int worldY = realm.getServerWorldData().convertRealToChunkSpace(posY);
Structure rVal = new Structure(worldX,worldY,posX,posY,type);
Globals.macroData.addStructure(rVal);
@ -35,7 +36,6 @@ public class VirtualStructureUtils {
// Globals.serverTerrainManager.deformTerrainAtLocationToValue(newWorldX, newWorldY, (int)(newLocationX), (int)(newLocationY), (float)centerHeight);
// }
// }
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

@ -24,33 +24,33 @@ public class Town {
final static int avgDiffThreshold = 10;
public static Vector2i findValidTownLocation(){
for(int x = 0; x < Globals.serverTerrainManager.getWorldDiscreteSize(); x++){
for(int y = 0; y < Globals.serverTerrainManager.getWorldDiscreteSize(); y++){
// ServerTerrainChunk chunk = Globals.serverTerrainManager.getChunk(x, y);
// float[][] macroValues = chunk.getMacroValues();
// float sum = 0;
// int count = 0;
// for(int i = 0; i < 5; i++){
// for(int j = 0; j < 5; j++){
// sum = sum + macroValues[i][j];
// count++;
// }
// }
// float average = sum / (float)count;
// if(average > 1000){
// float diffSum = 0;
// for(int i = 0; i < 5; i++){
// for(int j = 0; j < 5; j++){
// diffSum = diffSum + (float)Math.abs(average - macroValues[i][j]);
// }
// }
// float averageDiff = diffSum / (float)count;
// if(averageDiff < avgDiffThreshold){
// return new Vector2i(x,y);
// }
// }
}
}
// for(int x = 0; x < Globals.serverTerrainManager.getWorldDiscreteSize(); x++){
// for(int y = 0; y < Globals.serverTerrainManager.getWorldDiscreteSize(); y++){
// // ServerTerrainChunk chunk = Globals.serverTerrainManager.getChunk(x, y);
// // float[][] macroValues = chunk.getMacroValues();
// // float sum = 0;
// // int count = 0;
// // for(int i = 0; i < 5; i++){
// // for(int j = 0; j < 5; j++){
// // sum = sum + macroValues[i][j];
// // count++;
// // }
// // }
// // float average = sum / (float)count;
// // if(average > 1000){
// // float diffSum = 0;
// // for(int i = 0; i < 5; i++){
// // for(int j = 0; j < 5; j++){
// // diffSum = diffSum + (float)Math.abs(average - macroValues[i][j]);
// // }
// // }
// // float averageDiff = diffSum / (float)count;
// // if(averageDiff < avgDiffThreshold){
// // return new Vector2i(x,y);
// // }
// // }
// }
// }
return null;
}

View File

@ -84,36 +84,36 @@ public class MacroData {
boolean foundPlacementLocation = false;
int attempts = 0;
while(!foundPlacementLocation){
Vector2i start = new Vector2i(random.nextInt(Globals.serverTerrainManager.getWorldDiscreteSize()),random.nextInt(Globals.serverTerrainManager.getWorldDiscreteSize()));
//are we above sea level?
if(Globals.serverTerrainManager.getDiscreteValue(start.x, start.y) > 25){ //TODO: Set to actual sea level value
//is this position already occupied?
boolean match = false;
for(Vector2i known : occupiedStartingPositions){
if(known.x == start.x && known.y == start.y){
match = true;
break;
}
}
if(!match){
//occupy position
occupiedStartingPositions.add(start);
foundPlacementLocation = true;
//make characters
int numCharactersToMake = 5 + random.nextInt(20);
for(int i = 0; i < numCharactersToMake; i++){
Character character = new Character();
CharacterUtils.addDiscretePosition(character, start.x, start.y);
CharacterUtils.addRace(character, race);
rVal.characters.add(character);
rVal.aliveCharacters.add(character);
}
}
}
attempts++;
if(attempts > MAX_PLACEMENT_ATTEMPTS){
break;
}
// Vector2i start = new Vector2i(random.nextInt(Globals.serverTerrainManager.getWorldDiscreteSize()),random.nextInt(Globals.serverTerrainManager.getWorldDiscreteSize()));
// //are we above sea level?
// if(Globals.serverTerrainManager.getDiscreteValue(start.x, start.y) > 25){ //TODO: Set to actual sea level value
// //is this position already occupied?
// boolean match = false;
// for(Vector2i known : occupiedStartingPositions){
// if(known.x == start.x && known.y == start.y){
// match = true;
// break;
// }
// }
// if(!match){
// //occupy position
// occupiedStartingPositions.add(start);
// foundPlacementLocation = true;
// //make characters
// int numCharactersToMake = 5 + random.nextInt(20);
// for(int i = 0; i < numCharactersToMake; i++){
// Character character = new Character();
// CharacterUtils.addDiscretePosition(character, start.x, start.y);
// CharacterUtils.addRace(character, race);
// rVal.characters.add(character);
// rVal.aliveCharacters.add(character);
// }
// }
// }
// attempts++;
// if(attempts > MAX_PLACEMENT_ATTEMPTS){
// break;
// }
}
}

View File

@ -1,7 +1,11 @@
package electrosphere.game.server.world;
import electrosphere.server.fluid.generation.DefaultFluidGenerator;
import electrosphere.server.fluid.manager.ServerFluidManager;
import electrosphere.server.terrain.generation.DefaultChunkGenerator;
import electrosphere.server.terrain.manager.ServerTerrainChunk;
import electrosphere.server.terrain.manager.ServerTerrainManager;
import electrosphere.util.FileUtils;
import org.joml.Vector3d;
import org.joml.Vector3f;
@ -15,6 +19,7 @@ public class ServerWorldData {
public static enum WorldType {
GAME_WORLD,
ARENA_WORLD,
LEVEL,
}
WorldType type;
@ -45,34 +50,81 @@ public class ServerWorldData {
int dynamicInterpolationRatio;
float randomDampener;
boolean isArena = false;
public static ServerWorldData createArenaWorld(){
//terrain data
private ServerTerrainManager serverTerrainManager;
//fluid data
private ServerFluidManager serverFluidManager;
/**
* Creates a server world data object based on a discrete world size
* @param discreteWorldSize The discrete world size
* @return The server world data object
*/
public static ServerWorldData createGriddedRealmWorldData(int discreteWorldSize){
ServerWorldData rVal = new ServerWorldData();
rVal.type = WorldType.ARENA_WORLD;
rVal.type = WorldType.LEVEL;
//min and max real points
rVal.worldMinPoint = new Vector3f(0,0,0);
rVal.worldMaxPoint = new Vector3f(200,0,200);
rVal.dynamicInterpolationRatio = 100;
rVal.worldSizeDiscrete = 2;
rVal.worldSizeDiscreteVertical = 2;
rVal.randomDampener = 0.0f;
rVal.isArena = true;
int worldDim = discreteWorldSize * ServerTerrainChunk.CHUNK_DIMENSION;
rVal.worldMaxPoint = new Vector3f(worldDim,worldDim, worldDim);
//misc values
rVal.dynamicInterpolationRatio = 1;
rVal.worldSizeDiscrete = discreteWorldSize;
rVal.worldSizeDiscreteVertical = discreteWorldSize;
rVal.randomDampener = ServerTerrainManager.SERVER_TERRAIN_MANAGER_DAMPENER;
return rVal;
}
public static ServerWorldData createGameWorld(ServerTerrainManager terrainManager){
ServerWorldData rVal = new ServerWorldData();
rVal.type = WorldType.GAME_WORLD;
// public static ServerWorldData createGameWorld(ServerTerrainManager terrainManager){
// ServerWorldData rVal = new ServerWorldData();
// rVal.type = WorldType.GAME_WORLD;
rVal.worldMinPoint = new Vector3f(0,0,0);
int worldDim = terrainManager.getWorldDiscreteSize() * ServerTerrainChunk.CHUNK_DIMENSION;
rVal.worldMaxPoint = new Vector3f(worldDim,0,worldDim);
// rVal.worldMinPoint = new Vector3f(0,0,0);
// int worldDim = terrainManager.getWorldDiscreteSize() * ServerTerrainChunk.CHUNK_DIMENSION;
// rVal.worldMaxPoint = new Vector3f(worldDim,0,worldDim);
rVal.dynamicInterpolationRatio = terrainManager.getDynamicInterpolationRatio();
rVal.worldSizeDiscrete = terrainManager.getWorldDiscreteSize();
rVal.worldSizeDiscreteVertical = 128;
rVal.randomDampener = terrainManager.getRandomDampener();
// rVal.dynamicInterpolationRatio = terrainManager.getDynamicInterpolationRatio();
// rVal.worldSizeDiscrete = terrainManager.getWorldDiscreteSize();
// rVal.worldSizeDiscreteVertical = 128;
// rVal.randomDampener = terrainManager.getRandomDampener();
return rVal;
// return rVal;
// }
/**
* Loads world data from a scene or a save
* @param sceneOrSaveName The name of the scene or save
* @param isScene true if loading from a scene, false if loading from a save
* @return The server world data
*/
public static ServerWorldData loadWorldData(String sceneOrSaveName, boolean isScene){
//
//Read world data if it exists
//
ServerWorldData serverWorldData = null;
ServerTerrainManager serverTerrainManager = null;
ServerFluidManager serverFluidManager = null;
if(isScene){
serverWorldData = FileUtils.loadObjectFromSavePath(sceneOrSaveName, "world.json", ServerWorldData.class);
serverTerrainManager = new ServerTerrainManager(serverWorldData, 0, new DefaultChunkGenerator());
serverTerrainManager.load(sceneOrSaveName);
serverFluidManager = new ServerFluidManager(serverWorldData, serverTerrainManager, 0, new DefaultFluidGenerator());
} else {
//TODO: Allow loading procedurally generated terrain from disk (the chunk generator is always default currently)
serverWorldData = FileUtils.loadObjectFromSavePath(sceneOrSaveName, "world.json", ServerWorldData.class);
serverTerrainManager = new ServerTerrainManager(serverWorldData, 0, new DefaultChunkGenerator());
serverTerrainManager.load(sceneOrSaveName);
serverFluidManager = new ServerFluidManager(serverWorldData, serverTerrainManager, 0, new DefaultFluidGenerator());
}
serverWorldData.setManagers(serverTerrainManager, serverFluidManager);
return serverWorldData;
}
@ -163,4 +215,35 @@ public class ServerWorldData {
);
}
/**
* Gets the terrain manager for this world
* @return The terrain manager if it exists, null otherwise
*/
public ServerTerrainManager getServerTerrainManager(){
return this.serverTerrainManager;
}
/**
* Gets the fluid manager for this world
* @return The fluid manager if it exists, null otherwise
*/
public ServerFluidManager getServerFluidManager(){
return this.serverFluidManager;
}
/**
* Sets the chunk managers
* @param serverTerrainManager The terrain manager
* @param serverFluidManager The fluid manager
*/
public void setManagers(ServerTerrainManager serverTerrainManager, ServerFluidManager serverFluidManager){
this.serverTerrainManager = serverTerrainManager;
this.serverFluidManager = serverFluidManager;
this.serverTerrainManager.setParent(this);
this.serverFluidManager.setParent(this);
if(this.serverTerrainManager == null || this.serverFluidManager == null){
throw new IllegalStateException("Setting world data managers to a null manager " + this.serverTerrainManager + " " + this.serverFluidManager);
}
}
}

View File

@ -30,7 +30,7 @@ public class LoggerInterface {
loggerFileIO = new Logger(LogLevel.WARNING);
loggerGameLogic = new Logger(LogLevel.WARNING);
loggerRenderer = new Logger(LogLevel.WARNING);
loggerEngine = new Logger(LogLevel.WARNING);
loggerEngine = new Logger(LogLevel.INFO);
loggerAuth = new Logger(LogLevel.WARNING);
loggerDB = new Logger(LogLevel.WARNING);
loggerAudio = new Logger(LogLevel.WARNING);

View File

@ -5,6 +5,8 @@ import java.util.List;
import electrosphere.auth.AuthenticationManager;
import electrosphere.engine.Globals;
import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.engine.loadingthreads.LoadingThread.LoadingThreadType;
import electrosphere.entity.scene.SceneGenerator;
import electrosphere.menu.mainmenu.MenuGeneratorsKeybind;
import electrosphere.menu.mainmenu.MenuGeneratorsTitleMenu;
import electrosphere.net.NetUtils;
@ -14,12 +16,9 @@ import electrosphere.renderer.ui.elements.FormElement;
import electrosphere.renderer.ui.elements.Label;
import electrosphere.renderer.ui.elements.TextInput;
import electrosphere.renderer.ui.elementtypes.ClickableElement;
import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback;
import electrosphere.renderer.ui.elementtypes.Element;
import electrosphere.renderer.ui.events.ClickEvent;
import electrosphere.server.saves.SaveUtils;
import electrosphere.server.terrain.generation.OverworldChunkGenerator;
import electrosphere.server.terrain.manager.ServerTerrainManager;
/**
* Generator functions for creating menus
@ -28,7 +27,7 @@ public class MenuGenerators {
//Used when we're displaying loading window to make main menu invisible
public static Element createEmptyMainMenu(){
Div rVal = new Div();
Div rVal = Div.createDiv();
return rVal;
}
@ -51,9 +50,9 @@ public class MenuGenerators {
//need to log client in
Globals.clientUsername = "username";
Globals.clientPassword = AuthenticationManager.getHashedString("password");
LoadingThread clientThread = new LoadingThread(LoadingThread.LOAD_CHARACTER_SERVER);
LoadingThread clientThread = new LoadingThread(LoadingThreadType.CHARACTER_SERVER);
Globals.loadingThreadsList.add(clientThread);
LoadingThread serverThread = new LoadingThread(LoadingThread.LOAD_MAIN_GAME);
LoadingThread serverThread = new LoadingThread(LoadingThreadType.MAIN_GAME);
Globals.loadingThreadsList.add(serverThread);
Globals.RUN_CLIENT = true;
Globals.RUN_SERVER = true;
@ -103,11 +102,7 @@ public class MenuGenerators {
createButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
String saveName = worldNameInput.getText();
//create save dir
SaveUtils.createOrOverwriteSave(saveName);
//create and save terrain
ServerTerrainManager terrainManager = new ServerTerrainManager(2000,50,0.0f,0,new OverworldChunkGenerator());
terrainManager.generate();
terrainManager.save(SaveUtils.deriveSaveDirectoryPath(saveName));
SaveUtils.createOrOverwriteSave(saveName, SceneGenerator.createProceduralSceneFile(saveName));
WindowUtils.replaceMainMenuContents(MenuGenerators.createWorldSelectMenu());
return false;
}});
@ -125,9 +120,10 @@ public class MenuGenerators {
saveButton.addChild(saveLabel);
rVal.addChild(saveButton);
saveButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
SaveUtils.saveWorldData(Globals.currentSave.getName());
// SaveUtils.saveWorldData(Globals.currentSave.getName());
WindowUtils.replaceMainMenuContents(MenuGenerators.createWorldSelectMenu());
return false;
throw new UnsupportedOperationException("Need to update to use new save flow");
// return false;
}});
//button (cancel)
@ -185,9 +181,9 @@ public class MenuGenerators {
hostButton.addChild(hostLabel);
rVal.addChild(hostButton);
hostButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
LoadingThread clientThread = new LoadingThread(LoadingThread.LOAD_CHARACTER_SERVER);
LoadingThread clientThread = new LoadingThread(LoadingThreadType.CHARACTER_SERVER);
Globals.loadingThreadsList.add(clientThread);
LoadingThread serverThread = new LoadingThread(LoadingThread.LOAD_MAIN_GAME);
LoadingThread serverThread = new LoadingThread(LoadingThreadType.MAIN_GAME);
Globals.loadingThreadsList.add(serverThread);
Globals.RUN_CLIENT = true;
Globals.RUN_SERVER = true;
@ -277,7 +273,7 @@ public class MenuGenerators {
NetUtils.setPort(Integer.parseInt(portInput.getText()));
Globals.clientUsername = usernameInput.getText();
Globals.clientPassword = AuthenticationManager.getHashedString(passwordInput.getText());
LoadingThread clientThread = new LoadingThread(LoadingThread.LOAD_CHARACTER_SERVER);
LoadingThread clientThread = new LoadingThread(LoadingThreadType.CHARACTER_SERVER);
Globals.loadingThreadsList.add(clientThread);
Globals.RUN_CLIENT = true;
Globals.RUN_SERVER = false;
@ -319,10 +315,9 @@ public class MenuGenerators {
}});
//button to open rebind controls window
Button rebindControlsButton = Button.createButton("Controls", new ClickEventCallback() {public boolean execute(ClickEvent event) {
Button rebindControlsButton = Button.createButton("Controls", () -> {
WindowUtils.replaceMainMenuContents(MenuGeneratorsKeybind.createControlsRebindMenu());
return false;
}});
});
rVal.addChild(rebindControlsButton);
return rVal;

View File

@ -19,6 +19,7 @@ import electrosphere.renderer.ui.imgui.ImGuiWindow;
import electrosphere.renderer.ui.imgui.ImGuiLinePlot.ImGuiLinePlotDataset;
import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback;
import electrosphere.server.datacell.utils.EntityLookupUtils;
import electrosphere.server.fluid.manager.ServerFluidManager;
import imgui.ImGui;
/**
@ -234,7 +235,8 @@ public class ImGuiWindowMacros {
//audio engine details
ImGui.text("Fluids Debug");
if(ImGui.button("Toggle Simulation")){
Globals.serverFluidManager.setSimulate(!Globals.serverFluidManager.getSimulate());;
ServerFluidManager fluidManager = Globals.playerManager.getPlayerRealm(Globals.clientPlayer).getServerWorldData().getServerFluidManager();
fluidManager.setSimulate(!fluidManager.getSimulate());
}
}
});

View File

@ -46,7 +46,7 @@ public class MenuGeneratorsInGame {
int height = 500;
Window rVal = new Window(Globals.renderingEngine.getOpenGLState(),0,0,width,height,true);
// int screenLeft = (Globals.WINDOW_WIDTH - width)/2;
Div div = new Div();
Div div = Div.createDiv();
rVal.addChild(div);
div.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN), false);
@ -122,10 +122,9 @@ public class MenuGeneratorsInGame {
}});
// }
div.addChild(Button.createButton("Open Level Editor Tools", new ClickableElement.ClickEventCallback() {public boolean execute(ClickEvent event){
div.addChild(Button.createButton("Open Level Editor Tools", () -> {
WindowUtils.replaceWindow(WindowStrings.LEVEL_EDTIOR_SIDE_PANEL,MenuGeneratorsLevelEditor.createLevelEditorSidePanel());
return false;
}}));
}));
rVal.applyYoga(0,0);

View File

@ -2,8 +2,6 @@ package electrosphere.menu.ingame;
import java.util.List;
import org.lwjgl.util.yoga.Yoga;
import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType;
import electrosphere.controls.ControlHandler.ControlsState;
import electrosphere.engine.Globals;
@ -21,6 +19,8 @@ import electrosphere.renderer.ui.elements.Label;
import electrosphere.renderer.ui.elements.Window;
import electrosphere.renderer.ui.elementtypes.Element;
import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification;
import electrosphere.renderer.ui.elementtypes.ContainerElement;
import electrosphere.renderer.ui.elementtypes.DraggableElement.DragEventCallback;
import electrosphere.renderer.ui.elementtypes.NavigableElement.NavigationEventCallback;
@ -35,13 +35,13 @@ public class MenuGeneratorsInventory {
int height = 500;
Window rVal = new Window(Globals.renderingEngine.getOpenGLState(),0,0,width,height,true);
rVal.setParentAlignItem(Yoga.YGAlignCenter);
rVal.setParentJustifyContent(Yoga.YGJustifyCenter);
rVal.setParentAlignItem(YogaAlignment.Center);
rVal.setParentJustifyContent(YogaJustification.Center);
//apply yoga so that the screenspace position of the window can be calculated, that allows proper placement of the absolute elements
rVal.applyYoga(0, 0);
Div div = new Div();
Div div = Div.createDiv();
rVal.addChild(div);
rVal.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){
@ -219,7 +219,7 @@ public class MenuGeneratorsInventory {
// int screenLeft = (Globals.WINDOW_WIDTH - width)/2;
Window rVal = new Window(Globals.renderingEngine.getOpenGLState(),0,0,width,height,true);
Div div = new Div();
Div div = Div.createDiv();
rVal.addChild(div);
rVal.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){
@ -404,7 +404,7 @@ public class MenuGeneratorsInventory {
public static Element worldItemDropCaptureWindow(){
Window rVal = new Window(Globals.renderingEngine.getOpenGLState(),0,0,Globals.WINDOW_WIDTH,Globals.WINDOW_HEIGHT,true);
Div div = new Div();
Div div = Div.createDiv();
div.setOnDragRelease(new DragEventCallback() {public boolean execute(DragEvent event){
if(Globals.draggedItem != null){
if(Globals.dragSourceInventory instanceof UnrelationalInventoryState){

View File

@ -4,7 +4,6 @@ import java.util.Random;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.lwjgl.util.yoga.Yoga;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
@ -29,10 +28,11 @@ import electrosphere.renderer.ui.elements.Label;
import electrosphere.renderer.ui.elements.Slider;
import electrosphere.renderer.ui.elements.VirtualScrollable;
import electrosphere.renderer.ui.elements.Window;
import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback;
import electrosphere.renderer.ui.elementtypes.NavigableElement.NavigationEventCallback;
import electrosphere.renderer.ui.elementtypes.ValueElement;
import electrosphere.renderer.ui.events.ClickEvent;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaFlexDirection;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification;
import electrosphere.renderer.ui.events.NavigationEvent;
import electrosphere.renderer.ui.events.ValueChangeEvent;
import electrosphere.server.datacell.Realm;
@ -63,12 +63,12 @@ public class MenuGeneratorsLevelEditor {
public static Window createLevelEditorSidePanel(){
//setup window
mainSidePanel = new Window(Globals.renderingEngine.getOpenGLState(),0,0,SIDE_PANEL_WIDTH,Globals.WINDOW_HEIGHT,true);
mainSidePanel.setParentAlignContent(Yoga.YGAlignFlexEnd);
mainSidePanel.setParentJustifyContent(Yoga.YGJustifyFlexEnd);
mainSidePanel.setParentAlignItem(Yoga.YGAlignFlexEnd);
mainSidePanel.setAlignContent(Yoga.YGAlignFlexStart);
mainSidePanel.setAlignItems(Yoga.YGAlignFlexStart);
mainSidePanel.setJustifyContent(Yoga.YGJustifyFlexStart);
mainSidePanel.setParentAlignContent(YogaAlignment.End);
mainSidePanel.setParentJustifyContent(YogaJustification.End);
mainSidePanel.setParentAlignItem(YogaAlignment.End);
mainSidePanel.setAlignContent(YogaAlignment.Start);
mainSidePanel.setAlignItems(YogaAlignment.Start);
mainSidePanel.setJustifyContent(YogaJustification.Start);
//scrollable
VirtualScrollable scrollable = new VirtualScrollable(SIDE_PANEL_WIDTH, Globals.WINDOW_HEIGHT);
@ -95,37 +95,32 @@ public class MenuGeneratorsLevelEditor {
scrollable.clearChildren();
//close button
scrollable.addChild(Button.createButton("Close", new ClickEventCallback() {public boolean execute(ClickEvent event){
scrollable.addChild(Button.createButton("Close", () -> {
WindowUtils.closeWindow(WindowStrings.LEVEL_EDTIOR_SIDE_PANEL);
return false;
}}));
}));
//spawn creature button
scrollable.addChild(Button.createButton("Spawn Creature", new ClickEventCallback() {public boolean execute(ClickEvent event){
scrollable.addChild(Button.createButton("Spawn Creature", () -> {
fillInSpawnCreatureContent(scrollable);
return false;
}}));
}));
//spawn foliage button
scrollable.addChild(Button.createButton("Spawn Foliage", new ClickEventCallback() {public boolean execute(ClickEvent event){
scrollable.addChild(Button.createButton("Spawn Foliage", () -> {
fillInSpawnFoliageContent(scrollable);
return false;
}}));
}));
//spawn foliage button
scrollable.addChild(Button.createButton("Spawn Item", new ClickEventCallback() {public boolean execute(ClickEvent event){
scrollable.addChild(Button.createButton("Spawn Item", () -> {
fillInSpawnItemContent(scrollable);
return false;
}}));
}));
//spawn object button
scrollable.addChild(Button.createButton("Spawn Object", new ClickEventCallback() {public boolean execute(ClickEvent event){
scrollable.addChild(Button.createButton("Spawn Object", () -> {
fillInSpawnObjectContent(scrollable);
return false;
}}));
}));
//select voxel button
scrollable.addChild(Button.createButton("Select Voxel Type", new ClickEventCallback() {public boolean execute(ClickEvent event){
scrollable.addChild(Button.createButton("Select Voxel Type", () -> {
if(voxelWindowOpen){
voxelWindowOpen = false;
WindowUtils.closeWindow(WindowStrings.VOXEL_TYPE_SELECTION);
@ -133,21 +128,18 @@ public class MenuGeneratorsLevelEditor {
voxelWindowOpen = true;
WindowUtils.replaceWindow(WindowStrings.VOXEL_TYPE_SELECTION,MenuGeneratorsTerrainEditing.createVoxelTypeSelectionPanel());
}
return false;
}}));
}));
//entity tree view
scrollable.addChild(Button.createButton("View Entity Tree", new ClickEventCallback() {public boolean execute(ClickEvent event){
scrollable.addChild(Button.createButton("View Entity Tree", () -> {
fillInEntityTreeContent(scrollable);
return false;
}}));
}));
//entity tree view
scrollable.addChild(Button.createButton("Atmospheric Control", new ClickEventCallback() {public boolean execute(ClickEvent event){
scrollable.addChild(Button.createButton("Atmospheric Control", () -> {
fillInAtmosphericControlContent(scrollable);
return false;
}}));
}));
mainSidePanel.applyYoga(0,0);
@ -162,23 +154,21 @@ public class MenuGeneratorsLevelEditor {
scrollable.clearChildren();
//back button
scrollable.addChild(Button.createButton("Back", new ClickEventCallback() {public boolean execute(ClickEvent event){
scrollable.addChild(Button.createButton("Back", () -> {
fillInDefaultContent(scrollable);
return false;
}}));
}));
//button for spawning all creatures
for(CreatureType data : Globals.gameConfigCurrent.getCreatureTypeLoader().getCreatures()){
//spawn creature button
scrollable.addChild(Button.createButton("Spawn " + data.getCreatureId(), new ClickEventCallback() {public boolean execute(ClickEvent event){
scrollable.addChild(Button.createButton("Spawn " + data.getCreatureId(), () -> {
LoggerInterface.loggerEngine.INFO("spawn " + data.getCreatureId() + "!");
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera));
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
Realm realm = Globals.realmManager.getRealms().iterator().next();
Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0).add(cursorVerticalOffset);
CreatureUtils.serverSpawnBasicCreature(realm, cursorPos, data.getCreatureId(), null);
return false;
}}));
}));
}
mainSidePanel.applyYoga(0,0);
@ -192,23 +182,21 @@ public class MenuGeneratorsLevelEditor {
scrollable.clearChildren();
//back button
scrollable.addChild(Button.createButton("Back", new ClickEventCallback() {public boolean execute(ClickEvent event){
scrollable.addChild(Button.createButton("Back", () -> {
fillInDefaultContent(scrollable);
return false;
}}));
}));
//button for spawning all foliage types
for(FoliageType data : Globals.gameConfigCurrent.getFoliageMap().getFoliageList()){
//spawn foliage button
scrollable.addChild(Button.createButton("Spawn " + data.getName(), new ClickEventCallback() {public boolean execute(ClickEvent event){
scrollable.addChild(Button.createButton("Spawn " + data.getName(), () -> {
LoggerInterface.loggerEngine.INFO("spawn " + data.getName() + "!");
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera));
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
Realm realm = Globals.realmManager.getRealms().iterator().next();
Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0).add(cursorVerticalOffset);
FoliageUtils.serverSpawnTreeFoliage(realm, cursorPos, data.getName(), new Random().nextLong());
return false;
}}));
}));
}
mainSidePanel.applyYoga(0,0);
@ -222,23 +210,21 @@ public class MenuGeneratorsLevelEditor {
scrollable.clearChildren();
//back button
scrollable.addChild(Button.createButton("Back", new ClickEventCallback() {public boolean execute(ClickEvent event){
scrollable.addChild(Button.createButton("Back", () -> {
fillInDefaultContent(scrollable);
return false;
}}));
}));
//button for spawning all foliage types
for(Item item : Globals.gameConfigCurrent.getItemMap().getItems()){
//spawn foliage button
scrollable.addChild(Button.createButton("Spawn " + item.getItemId(), new ClickEventCallback() {public boolean execute(ClickEvent event){
scrollable.addChild(Button.createButton("Spawn " + item.getItemId(), () -> {
LoggerInterface.loggerEngine.INFO("spawn " + item.getItemId() + "!");
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera));
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
Realm realm = Globals.realmManager.getRealms().iterator().next();
Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0).add(cursorVerticalOffset);
ItemUtils.serverSpawnBasicItem(realm, cursorPos, item.getItemId());
return false;
}}));
}));
}
mainSidePanel.applyYoga(0,0);
@ -253,23 +239,21 @@ public class MenuGeneratorsLevelEditor {
scrollable.clearChildren();
//back button
scrollable.addChild(Button.createButton("Back", new ClickEventCallback() {public boolean execute(ClickEvent event){
scrollable.addChild(Button.createButton("Back", () -> {
fillInDefaultContent(scrollable);
return false;
}}));
}));
//button for spawning all foliage types
for(ObjectData object : Globals.gameConfigCurrent.getObjectTypeLoader().getAllObjectTypes()){
//spawn foliage button
scrollable.addChild(Button.createButton("Spawn " + object.getObjectId(), new ClickEventCallback() {public boolean execute(ClickEvent event){
scrollable.addChild(Button.createButton("Spawn " + object.getObjectId(), () -> {
LoggerInterface.loggerEngine.INFO("spawn " + object.getObjectId() + "!");
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera));
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
Realm realm = Globals.realmManager.getRealms().iterator().next();
Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0).add(cursorVerticalOffset);
ObjectUtils.serverSpawnBasicObject(realm, cursorPos, object.getObjectId());
return false;
}}));
}));
}
mainSidePanel.applyYoga(0,0);
@ -284,10 +268,9 @@ public class MenuGeneratorsLevelEditor {
scrollable.clearChildren();
//back button
scrollable.addChild(Button.createButton("Close", new ClickEventCallback() {public boolean execute(ClickEvent event){
scrollable.addChild(Button.createButton("Close", () -> {
fillInDefaultContent(scrollable);
return false;
}}));
}));
//elements for the entity
for(Entity entity : EntityLookupUtils.getAllEntities()){
@ -297,8 +280,8 @@ public class MenuGeneratorsLevelEditor {
ObjectUtils.isObject(entity) ||
FoliageUtils.isFoliage(entity)
){
Div div = new Div();
div.setFlexDirection(Yoga.YGFlexDirectionRow);
Div div = Div.createDiv();
div.setFlexDirection(YogaFlexDirection.Row);
div.setMaxHeight(30);
div.setMarginBottom(5);
div.setMarginLeft(5);
@ -306,11 +289,10 @@ public class MenuGeneratorsLevelEditor {
div.setMarginTop(5);
//delete button
Button deleteButton = Button.createButton("X", new ClickEventCallback() {public boolean execute(ClickEvent event){
Button deleteButton = Button.createButton("X", () -> {
LoggerInterface.loggerEngine.INFO("Delete " + entity.getId());
ServerEntityUtils.destroyEntity(entity);
return false;
}});
});
deleteButton.setMarginRight(5);
deleteButton.setMarginLeft(5);
div.addChild(deleteButton);
@ -356,16 +338,15 @@ public class MenuGeneratorsLevelEditor {
scrollable.clearChildren();
//back button
scrollable.addChild(Button.createButton("Close", new ClickEventCallback() {public boolean execute(ClickEvent event){
scrollable.addChild(Button.createButton("Close", () -> {
fillInDefaultContent(scrollable);
return false;
}}));
}));
//global light direction
scrollable.addChild(Label.createLabel("Global Light Direction"));
Div xDiv = new Div();
Div xDiv = Div.createDiv();
xDiv.setMaxHeight(50);
xDiv.setFlexDirection(Yoga.YGFlexDirectionRow);
xDiv.setFlexDirection(YogaFlexDirection.Row);
xDiv.addChild(Label.createLabel("X: "));
xDiv.addChild(Slider.createSlider(new ValueElement.ValueChangeEventCallback() {public void execute(ValueChangeEvent event) {
LightManager lightManager = Globals.renderingEngine.getLightManager();
@ -376,9 +357,9 @@ public class MenuGeneratorsLevelEditor {
}}));
scrollable.addChild(xDiv);
Div yDiv = new Div();
Div yDiv = Div.createDiv();
yDiv.setMaxHeight(50);
yDiv.setFlexDirection(Yoga.YGFlexDirectionRow);
yDiv.setFlexDirection(YogaFlexDirection.Row);
yDiv.addChild(Label.createLabel("Y: "));
yDiv.addChild(Slider.createSlider(new ValueElement.ValueChangeEventCallback() {public void execute(ValueChangeEvent event) {
LightManager lightManager = Globals.renderingEngine.getLightManager();
@ -389,9 +370,9 @@ public class MenuGeneratorsLevelEditor {
}}));
scrollable.addChild(yDiv);
Div zDiv = new Div();
Div zDiv = Div.createDiv();
zDiv.setMaxHeight(50);
zDiv.setFlexDirection(Yoga.YGFlexDirectionRow);
zDiv.setFlexDirection(YogaFlexDirection.Row);
zDiv.addChild(Label.createLabel("Z: "));
zDiv.addChild(Slider.createSlider(new ValueElement.ValueChangeEventCallback() {public void execute(ValueChangeEvent event) {
LightManager lightManager = Globals.renderingEngine.getLightManager();

View File

@ -2,8 +2,6 @@ package electrosphere.menu.ingame;
import java.util.List;
import org.lwjgl.util.yoga.Yoga;
import electrosphere.engine.Globals;
import electrosphere.game.data.voxel.VoxelData;
import electrosphere.game.data.voxel.VoxelType;
@ -16,6 +14,9 @@ import electrosphere.renderer.ui.elements.TextInput;
import electrosphere.renderer.ui.elements.VirtualScrollable;
import electrosphere.renderer.ui.elements.Window;
import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaFlexDirection;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification;
import electrosphere.renderer.ui.elementtypes.KeyEventElement.KeyboardEventCallback;
import electrosphere.renderer.ui.elementtypes.NavigableElement.NavigationEventCallback;
import electrosphere.renderer.ui.events.ClickEvent;
@ -55,25 +56,25 @@ public class MenuGeneratorsTerrainEditing {
public static Window createVoxelTypeSelectionPanel(){
//setup window
rVal = new Window(Globals.renderingEngine.getOpenGLState(),0,0,WINDOW_WIDTH,WINDOW_HEIGHT,true);
rVal.setParentAlignContent(Yoga.YGAlignCenter);
rVal.setParentJustifyContent(Yoga.YGJustifyCenter);
rVal.setParentAlignItem(Yoga.YGAlignCenter);
rVal.setAlignContent(Yoga.YGAlignCenter);
rVal.setAlignItems(Yoga.YGAlignCenter);
rVal.setJustifyContent(Yoga.YGJustifyCenter);
rVal.setFlexDirection(Yoga.YGFlexDirectionColumn);
rVal.setParentAlignContent(YogaAlignment.Center);
rVal.setParentJustifyContent(YogaJustification.Center);
rVal.setParentAlignItem(YogaAlignment.Center);
rVal.setAlignContent(YogaAlignment.Center);
rVal.setAlignItems(YogaAlignment.Center);
rVal.setJustifyContent(YogaJustification.Center);
rVal.setFlexDirection(YogaFlexDirection.Column);
//scrollable that contains all the voxel types
VirtualScrollable scrollable = new VirtualScrollable(VOXEL_SCROLLABLE_WIDTH, VOXEL_SCROLLABLE_HEIGHT);
scrollable.setFlexDirection(Yoga.YGFlexDirectionRow);
scrollable.setAlignItems(Yoga.YGAlignFlexStart);
scrollable.setFlexDirection(YogaFlexDirection.Row);
scrollable.setAlignItems(YogaAlignment.Start);
rVal.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){
WindowUtils.closeWindow(WindowStrings.LEVEL_EDTIOR_SIDE_PANEL);
return false;
}});
//search input
TextInput searchInput = TextInput.createTextInput(1.0f);
TextInput searchInput = TextInput.createTextInput();
searchInput.setWidth(TEXT_INPUT_WIDTH);
searchInput.setMinWidth(TEXT_INPUT_WIDTH);
searchInput.setMinHeight(20);
@ -109,7 +110,7 @@ public class MenuGeneratorsTerrainEditing {
//generate voxel buttons
for(VoxelType type : matchingVoxels){
Button newButton = new Button();
newButton.setAlignItems(Yoga.YGAlignCenter);
newButton.setAlignItems(YogaAlignment.Center);
//dimensions
newButton.setWidth(VOXEL_BUTTON_WIDTH);
newButton.setMinWidth(VOXEL_BUTTON_WIDTH);

View File

@ -1,9 +1,9 @@
package electrosphere.menu.mainmenu;
import org.lwjgl.util.yoga.Yoga;
import electrosphere.renderer.ui.elements.FormElement;
import electrosphere.renderer.ui.elements.Label;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification;
import electrosphere.renderer.ui.elementtypes.Element;
/**
@ -18,10 +18,10 @@ public class MenuGeneratorsDemo {
public static Element createTitleMenu(){
FormElement rVal = new FormElement();
//top-bottom
rVal.setJustifyContent(Yoga.YGJustifyCenter);
rVal.setJustifyContent(YogaJustification.Center);
//left-right
rVal.setAlignItems(Yoga.YGAlignCenter);
rVal.setAlignContent(Yoga.YGAlignFlexStart);
rVal.setAlignItems(YogaAlignment.Center);
rVal.setAlignContent(YogaAlignment.Start);
//label (title)
Label titleLabel = new Label(1.0f);

View File

@ -1,7 +1,5 @@
package electrosphere.menu.mainmenu;
import org.lwjgl.util.yoga.Yoga;
import electrosphere.controls.Control;
import electrosphere.engine.Globals;
import electrosphere.menu.WindowUtils;
@ -10,10 +8,9 @@ import electrosphere.renderer.ui.elements.Div;
import electrosphere.renderer.ui.elements.FormElement;
import electrosphere.renderer.ui.elements.Label;
import electrosphere.renderer.ui.elements.VirtualScrollable;
import electrosphere.renderer.ui.elementtypes.ClickableElement;
import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaFlexDirection;
import electrosphere.renderer.ui.elementtypes.Element;
import electrosphere.renderer.ui.events.ClickEvent;
/**
* A menu for rebinding controls
@ -29,28 +26,25 @@ public class MenuGeneratorsKeybind {
*/
public static Element createControlsRebindMenu(){
FormElement rVal = new FormElement();
rVal.setAlignItems(Yoga.YGAlignCenter);
rVal.setAlignItems(YogaAlignment.Center);
//header buttons
Div headerButtons = new Div();
headerButtons.setFlexDirection(Yoga.YGFlexDirectionRow);
Button backButton = Button.createButton("Back", new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
Div headerButtons = Div.createDiv();
headerButtons.setFlexDirection(YogaFlexDirection.Row);
Button backButton = Button.createButton("Back", () -> {
WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu());
return false;
}});
});
headerButtons.addChild(backButton);
Button saveButton = Button.createButton("Save", new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
Button saveButton = Button.createButton("Save", () -> {
WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu());
return false;
}});
});
saveButton.setVisible(false);
headerButtons.addChild(saveButton);
Button cancelButton = Button.createButton("Cancel", new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
Button cancelButton = Button.createButton("Cancel", () -> {
WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu());
return false;
}});
});
cancelButton.setVisible(false);
headerButtons.addChild(cancelButton);
@ -60,20 +54,19 @@ public class MenuGeneratorsKeybind {
//
//Generate keybind controls
VirtualScrollable virtualScrollable = new VirtualScrollable(300, 700);
virtualScrollable.setAlignItems(Yoga.YGAlignFlexStart);
virtualScrollable.setAlignItems(YogaAlignment.Start);
//add a ton of children
for(Control control : Globals.controlHandler.getMainControlsList()){
if(control.isRebindable()){
Div rebindItem = new Div();
rebindItem.setFlexDirection(Yoga.YGFlexDirectionRow);
Div rebindItem = Div.createDiv();
rebindItem.setFlexDirection(YogaFlexDirection.Row);
Label controlNameLabel = Label.createLabel(control.getName());
rebindItem.addChild(controlNameLabel);
Button testButton = Button.createButton(control.getKeyValue() + "", new ClickEventCallback() {public boolean execute(ClickEvent event) {
Button testButton = Button.createButton(control.getKeyValue() + "", () -> {
System.out.println("Start rebind");
return false;
}});
});
rebindItem.addChild(testButton);
virtualScrollable.addChild(rebindItem);

View File

@ -2,19 +2,21 @@ package electrosphere.menu.mainmenu;
import java.util.List;
import org.lwjgl.util.yoga.Yoga;
import electrosphere.engine.Globals;
import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.engine.loadingthreads.LoadingThread.LoadingThreadType;
import electrosphere.entity.scene.SceneFile;
import electrosphere.menu.WindowUtils;
import electrosphere.renderer.ui.elements.Button;
import electrosphere.renderer.ui.elements.Div;
import electrosphere.renderer.ui.elements.FormElement;
import electrosphere.renderer.ui.elements.Label;
import electrosphere.renderer.ui.elements.TextInput;
import electrosphere.renderer.ui.elementtypes.ClickableElement;
import electrosphere.renderer.ui.elementtypes.Element;
import electrosphere.renderer.ui.events.ClickEvent;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification;
import electrosphere.renderer.ui.events.ValueChangeEvent;
import electrosphere.renderer.ui.macros.InputMacros;
import electrosphere.server.datacell.GriddedDataCellManager;
import electrosphere.server.saves.SaveUtils;
/**
@ -22,84 +24,84 @@ import electrosphere.server.saves.SaveUtils;
*/
public class MenuGeneratorsLevelEditor {
/**
* The default grid size when creating a level
*/
static final int DEFAULT_GRID_SIZE = 2;
/**
* Creates the top level menu for the level editor
* @return The actual element containing the menu
*/
public static Element createLevelEditorTopMenu(){
FormElement rVal = new FormElement();
//top-bottom
rVal.setJustifyContent(YogaJustification.Start);
//left-right
rVal.setAlignItems(YogaAlignment.Center);
rVal.setAlignContent(YogaAlignment.Start);
//label (address)
Label usernameLabel = new Label(1.0f);
usernameLabel.setText("Select Level");
rVal.addChild(usernameLabel);
//button (back)
{
Button backButton = new Button();
Label backLabel = new Label(1.0f);
backLabel.setText("Back");
backButton.addChild(backLabel);
rVal.addChild(backButton);
backButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
//
//title
//
Div titleRow = Div.createRow(
Label.createLabel("Select Level"),
Button.createButton("Back", () -> {
WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu());
return false;
}});
}
})
);
titleRow.setMarginTop(30);
titleRow.setMarginBottom(30);
rVal.addChild(titleRow);
//
//button (create level)
{
Button createLevelButton = new Button();
Label createLevelLabel = new Label(1.0f);
createLevelLabel.setText("Create Level");
createLevelButton.addChild(createLevelLabel);
rVal.addChild(createLevelButton);
createLevelButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
//go to create level flow
WindowUtils.replaceMainMenuContents(MenuGeneratorsLevelEditor.createLevelEditorCreationMenu());
return false;
}});
}
//
Button createLevelButton = Button.createButton("Create Level", () -> {
//go to create level flow
WindowUtils.replaceMainMenuContents(MenuGeneratorsLevelEditor.createLevelEditorCreationMenu());
});
createLevelButton.setMarginBottom(30);
rVal.addChild(createLevelButton);
//
//the buttons to load existing levels
//
Div existingLevelColumn = Div.createCol();
existingLevelColumn.setAlignContent(YogaAlignment.Start);
rVal.addChild(existingLevelColumn);
List<String> saveNames = SaveUtils.getSaves();
for(String saveName : saveNames){
//containing div
Div div = new Div();
div.setFlexDirection(Yoga.YGFlexDirectionRow);
div.setMaxHeight(30);
//delete level button
Button deleteButton = new Button();
Label deleteLabel = new Label(1.0f);
deleteLabel.setText(" X ");
deleteButton.addChild(deleteLabel);
deleteButton.setMarginRight(10);
deleteButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
Button deleteButton = Button.createButton(" X ", () -> {
SaveUtils.deleteSave(saveName);
WindowUtils.replaceMainMenuContents(MenuGeneratorsLevelEditor.createLevelEditorTopMenu());
return false;
}});
div.addChild(deleteButton);
});
deleteButton.setMarginRight(10);
//button (launch level)
Button launchButton = new Button();
Label launchLabel = new Label(1.0f);
launchLabel.setText(saveName);
launchButton.addChild(launchLabel);
launchButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
//button (launch level editor)
Button launchButton = Button.createButton(saveName, () -> {
//launch level
LoadingThread loadingThread = new LoadingThread(LoadingThread.LOAD_LEVEL, saveName);
LoadingThread loadingThread = new LoadingThread(LoadingThreadType.LEVEL, saveName);
Globals.loadingThreadsList.add(loadingThread);
Globals.RUN_CLIENT = true;
Globals.RUN_SERVER = true;
loadingThread.start();
return false;
}});
div.addChild(launchButton);
});
rVal.addChild(div);
//create row
Div row = Div.createRow(
deleteButton,
launchButton
);
row.setMaxHeight(30);
existingLevelColumn.addChild(row);
}
return rVal;
@ -111,34 +113,42 @@ public class MenuGeneratorsLevelEditor {
* @return The element containing the level creation menu
*/
public static Element createLevelEditorCreationMenu(){
//values to creat the level with
LevelDescription inFlightLevel = new LevelDescription();
SceneFile sceneFile = SceneFile.createSceneFile();
inFlightLevel.setSceneFile(sceneFile);
//
//Top level element
//
FormElement rVal = new FormElement();
int screenTop = 150;
//label (address)
Label usernameLabel = new Label(1.0f);
usernameLabel.setText("Create Level");
rVal.addChild(usernameLabel);
//top-bottom
rVal.setJustifyContent(YogaJustification.Start);
//left-right
rVal.setAlignItems(YogaAlignment.Center);
rVal.setAlignContent(YogaAlignment.Start);
//button (back)
{
Button backButton = new Button();
Label backLabel = new Label(1.0f);
backLabel.setText("Back");
backButton.addChild(backLabel);
rVal.addChild(backButton);
backButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
//
//Title
//
Div titleRow = Div.createRow(
Label.createLabel("Create Level"),
Button.createButton("Back", () -> {
WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu());
return false;
}});
}
})
);
titleRow.setMarginTop(30);
titleRow.setMarginBottom(30);
rVal.addChild(titleRow);
//label for text input for level name
{
Label levelNameLabel = new Label(1.0f);
levelNameLabel.setText("Level Name:");
rVal.addChild(levelNameLabel);
}
//
//Level name input
//
//generate default level name
List<String> saveNames = SaveUtils.getSaves();
int i = 0;
@ -147,32 +157,95 @@ public class MenuGeneratorsLevelEditor {
i++;
defaultSaveName = "defaultLevel_" + i;
}
inFlightLevel.setName(defaultSaveName);
//input for the name of the save
Div levelNameInput = InputMacros.createTextInput("Level Name:", defaultSaveName, (ValueChangeEvent event) -> {
inFlightLevel.setName(event.getAsString());
});
levelNameInput.setMaxWidth(400);
levelNameInput.setMarginBottom(30);
rVal.addChild(levelNameInput);
//get level name
TextInput usernameInput = new TextInput(100,screenTop + 300,1.0f);
usernameInput.setText(defaultSaveName);
rVal.addChild(usernameInput);
//button (create level)
//
//Gridded realm controls
//
Div griddedRealmControls = Div.createCol();
{
Button createLevelButton = new Button();
Label createLevelLabel = new Label(1.0f);
createLevelLabel.setText("Create Level");
createLevelButton.addChild(createLevelLabel);
rVal.addChild(createLevelButton);
createLevelButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
//launch level editor
LoadingThread loadingThread = new LoadingThread(LoadingThread.LOAD_LEVEL_EDITOR, usernameInput.getText());
Globals.loadingThreadsList.add(loadingThread);
Globals.RUN_CLIENT = true;
Globals.RUN_SERVER = true;
loadingThread.start();
return false;
}});
griddedRealmControls.addChild(
InputMacros.createSliderInput("Realm Size", (ValueChangeEvent event) -> {
float value = event.getAsFloat() * GriddedDataCellManager.MAX_GRID_SIZE;
sceneFile.getRealmDescriptor().setGriddedRealmSize((int)value);
}, DEFAULT_GRID_SIZE / (float)GriddedDataCellManager.MAX_GRID_SIZE)
);
sceneFile.getRealmDescriptor().setGriddedRealmSize(DEFAULT_GRID_SIZE);
}
rVal.addChild(griddedRealmControls);
//
//Create level button
//
rVal.addChild(Button.createButton("Create Level", () -> {
//launch level editor
LoadingThread loadingThread = new LoadingThread(LoadingThreadType.LEVEL_EDITOR, inFlightLevel);
Globals.loadingThreadsList.add(loadingThread);
loadingThread.start();
}));
return rVal;
}
/**
* A level that is currently having its parameters defined
*/
public static class LevelDescription {
/**
* The name of the new level
*/
String name;
/**
* The scene file
*/
SceneFile sceneFile;
/**
* Sets the name of the level
* @param name The name
*/
public void setName(String name){
this.name = name;
}
/**
* Sets the scene file
* @param sceneFile The scene file
*/
public void setSceneFile(SceneFile sceneFile){
this.sceneFile = sceneFile;
}
/**
* Gets the name of the level
* @return The level name
*/
public String getName(){
return name;
}
/**
* Gets the scene file
* @return The scene file
*/
public SceneFile getSceneFile(){
return sceneFile;
}
}
}

View File

@ -4,7 +4,6 @@ import java.util.LinkedList;
import java.util.List;
import org.joml.Vector3f;
import org.lwjgl.util.yoga.Yoga;
import electrosphere.engine.Globals;
import electrosphere.entity.types.camera.CameraEntityUtils;
@ -28,6 +27,7 @@ import electrosphere.renderer.ui.elements.ScrollableContainer;
import electrosphere.renderer.ui.elements.Slider;
import electrosphere.renderer.ui.elements.StringCarousel;
import electrosphere.renderer.ui.elementtypes.ClickableElement;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaFlexDirection;
import electrosphere.renderer.ui.elementtypes.Element;
import electrosphere.renderer.ui.elementtypes.ValueElement.ValueChangeEventCallback;
import electrosphere.renderer.ui.events.ClickEvent;
@ -203,8 +203,8 @@ public class MenuGeneratorsMultiplayer {
int width = 1800;
int height = verticalPosition + 300;
Div rVal = new Div();
rVal.setFlexDirection(Yoga.YGFlexDirectionRow);
Div rVal = Div.createDiv();
rVal.setFlexDirection(YogaFlexDirection.Row);
ScrollableContainer scrollable = new ScrollableContainer(Globals.renderingEngine.getOpenGLState(), 0, 0, width, height);
for(Element newControl : controlsToAdd){

View File

@ -1,26 +1,36 @@
package electrosphere.menu.mainmenu;
import org.lwjgl.util.yoga.Yoga;
import electrosphere.engine.Globals;
import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.engine.loadingthreads.LoadingThread.LoadingThreadType;
import electrosphere.menu.MenuGenerators;
import electrosphere.menu.WindowUtils;
import electrosphere.renderer.ui.elements.Button;
import electrosphere.renderer.ui.elements.FormElement;
import electrosphere.renderer.ui.elements.Div;
import electrosphere.renderer.ui.elements.Label;
import electrosphere.renderer.ui.elementtypes.ClickableElement;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification;
import electrosphere.renderer.ui.elementtypes.Element;
import electrosphere.renderer.ui.events.ClickEvent;
/**
* Menu generators for the title menu
*/
public class MenuGeneratorsTitleMenu {
/**
* Creates the main title menu
* @return The menu element
*/
public static Element createTitleMenu(){
FormElement rVal = new FormElement();
Div rVal = Div.createDiv();
//top-bottom
rVal.setJustifyContent(Yoga.YGJustifyCenter);
rVal.setJustifyContent(YogaJustification.Center);
//left-right
rVal.setAlignItems(Yoga.YGAlignCenter);
rVal.setAlignContent(Yoga.YGAlignFlexStart);
rVal.setAlignItems(YogaAlignment.Center);
rVal.setAlignContent(YogaAlignment.Center);
rVal.setFlexGrow(1.0f);
//label (title)
Label titleLabel = new Label(1.0f);
@ -78,7 +88,7 @@ public class MenuGeneratorsTitleMenu {
uiDebugSPQuickstartButton.addChild(uiDebugSPQuickstartLabel);
rVal.addChild(uiDebugSPQuickstartButton);
uiDebugSPQuickstartButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
LoadingThread loadingThread = new LoadingThread(LoadingThread.LOAD_DEBUG_RANDOM_SP_WORLD);
LoadingThread loadingThread = new LoadingThread(LoadingThreadType.DEBUG_RANDOM_SP_WORLD);
Globals.loadingThreadsList.add(loadingThread);
Globals.RUN_CLIENT = true;
Globals.RUN_SERVER = true;

View File

@ -12,10 +12,8 @@ import electrosphere.renderer.ui.elements.FormElement;
import electrosphere.renderer.ui.elements.Label;
import electrosphere.renderer.ui.elements.Slider;
import electrosphere.renderer.ui.elements.VirtualScrollable;
import electrosphere.renderer.ui.elementtypes.ClickableElement;
import electrosphere.renderer.ui.elementtypes.Element;
import electrosphere.renderer.ui.elementtypes.ValueElement;
import electrosphere.renderer.ui.events.ClickEvent;
import electrosphere.renderer.ui.events.ValueChangeEvent;
/**
@ -31,10 +29,9 @@ public class MenuGeneratorsUITesting {
FormElement rVal = new FormElement();
//button (back)
Button backButton = Button.createButton("Back", new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
Button backButton = Button.createButton("Back", () -> {
WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu());
return false;
}});
});
rVal.addChild(backButton);
ActorPanel actorPanel = new ActorPanel(Globals.renderingEngine.getOpenGLState(), 500, 100, 500, 500, ActorUtils.createActorFromModelPath("Models/deer1.fbx"));

View File

@ -1,7 +1,5 @@
package electrosphere.menu.tutorial;
import org.lwjgl.util.yoga.Yoga;
import electrosphere.engine.Globals;
import electrosphere.game.data.tutorial.TutorialHint;
import electrosphere.menu.WindowStrings;
@ -9,8 +7,9 @@ import electrosphere.menu.WindowUtils;
import electrosphere.renderer.ui.elements.Button;
import electrosphere.renderer.ui.elements.Label;
import electrosphere.renderer.ui.elements.Window;
import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback;
import electrosphere.renderer.ui.events.ClickEvent;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaFlexDirection;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification;
/**
* Generates in game tutorial windows
@ -30,9 +29,9 @@ public class TutorialMenus {
} else {
//create the window
windowEl = new Window(Globals.renderingEngine.getOpenGLState(),50,50,500,500,true);
windowEl.setParentAlignContent(Yoga.YGAlignCenter);
windowEl.setParentJustifyContent(Yoga.YGJustifyCenter);
windowEl.setFlexDirection(Yoga.YGFlexDirectionColumn);
windowEl.setParentAlignContent(YogaAlignment.Center);
windowEl.setParentJustifyContent(YogaJustification.Center);
windowEl.setFlexDirection(YogaFlexDirection.Column);
Globals.elementManager.registerWindow(WindowStrings.TUTORIAL_POPUP, windowEl);
}
@ -42,12 +41,8 @@ public class TutorialMenus {
//create tutorial elements
windowEl.addChild(Label.createLabel(hint.getTitleString()));
windowEl.addChild(Label.createLabel(hint.getDescriptionString()));
windowEl.addChild(Button.createButton("Close", new ClickEventCallback() {
@Override
public boolean execute(ClickEvent event) {
WindowUtils.recursiveSetVisible(windowEl, true);
return false;
}
windowEl.addChild(Button.createButton("Close", () -> {
WindowUtils.recursiveSetVisible(windowEl, true);
}));
//show the window

View File

@ -2,6 +2,7 @@ package electrosphere.net.client.protocol;
import electrosphere.engine.Globals;
import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.engine.loadingthreads.LoadingThread.LoadingThreadType;
import electrosphere.net.parser.net.message.CharacterMessage;
import electrosphere.net.parser.net.message.TerrainMessage;
@ -13,7 +14,7 @@ public class CharacterProtocol {
//trigger request to spawn character
Globals.clientConnection.queueOutgoingMessage(CharacterMessage.constructRequestSpawnCharacterMessage());
Globals.clientConnection.queueOutgoingMessage(TerrainMessage.constructRequestMetadataMessage());
LoadingThread clientThread = new LoadingThread(LoadingThread.LOAD_CLIENT_WORLD);
LoadingThread clientThread = new LoadingThread(LoadingThreadType.CLIENT_WORLD);
Globals.loadingThreadsList.add(clientThread);
clientThread.start();
break;

View File

@ -281,6 +281,14 @@ public class ServerConnectionHandler implements Runnable {
return playerEntityID;
}
/**
* Gets the player associated with this connection
* @return The player object
*/
public Player getPlayer(){
return Globals.playerManager.getPlayerFromId(playerID);
}
public String getIPAddress(){
if(local){
return "127.0.0.1";

View File

@ -10,8 +10,7 @@ import java.util.concurrent.Semaphore;
import org.joml.Vector3i;
/**
*
* @author satellite
* A client logged into the server
*/
public class Player {

View File

@ -5,6 +5,10 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.server.datacell.Realm;
/**
* Server player manager
*/
@ -27,5 +31,18 @@ public class PlayerManager {
public List<Player> getPlayers(){
return new LinkedList<Player>(idMap.values());
}
/**
* Gets the realm a player is within
* @param player The player
* @return The realm if it exists, null otherwise
*/
public Realm getPlayerRealm(Player player){
Entity playerEntity = player.getPlayerEntity();
if(playerEntity == null){
throw new IllegalStateException("Trying to get realm of player who does not have an entity assigned!");
}
return Globals.realmManager.getEntityRealm(playerEntity);
}
}

View File

@ -7,6 +7,7 @@ import electrosphere.net.parser.net.message.PlayerMessage;
import electrosphere.net.parser.net.message.TerrainMessage;
import electrosphere.net.server.ServerConnectionHandler;
import electrosphere.server.character.PlayerCharacterCreation;
import electrosphere.server.datacell.Realm;
import electrosphere.util.Utilities;
public class CharacterProtocol {
@ -62,12 +63,13 @@ public class CharacterProtocol {
*/
static void spawnEntityForClient(ServerConnectionHandler connectionHandler){
PlayerCharacterCreation.spawnPlayerCharacter(connectionHandler);
Realm realm = Globals.playerManager.getPlayerRealm(connectionHandler.getPlayer());
//set client initial discrete position
connectionHandler.addMessagetoOutgoingQueue(
PlayerMessage.constructSetInitialDiscretePositionMessage(
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.x),
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.y),
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.z)
realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.x),
realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.y),
realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.z)
)
);
//send spawn point

View File

@ -113,8 +113,8 @@ public class TerrainProtocol {
*/
// System.out.println("Received request for chunk " + message.getworldX() + " " + message.getworldY());
ServerTerrainChunk chunk = Globals.serverTerrainManager.getChunk(worldX, worldY, worldZ);
Realm realm = Globals.playerManager.getPlayerRealm(connectionHandler.getPlayer());
ServerTerrainChunk chunk = realm.getServerWorldData().getServerTerrainManager().getChunk(worldX, worldY, worldZ);
// float[][] macroValues = chunk.getMacroValues();//Globals.serverTerrainManager.getRad5MacroValues(message.getworldX(), message.getworldY());
@ -243,10 +243,11 @@ public class TerrainProtocol {
* @param worldZ the world z
*/
static void sendWorldFluidSubChunk(ServerConnectionHandler connectionHandler, int worldX, int worldY, int worldZ){
Realm realm = Globals.playerManager.getPlayerRealm(connectionHandler.getPlayer());
// System.out.println("Received request for chunk " + message.getworldX() + " " + message.getworldY());
ServerFluidChunk chunk = Globals.serverFluidManager.getChunk(worldX, worldY, worldZ);
ServerFluidChunk chunk = realm.getServerWorldData().getServerFluidManager().getChunk(worldX, worldY, worldZ);
ByteBuffer buffer = constructFluidByteBuffer(chunk);
@ -260,16 +261,17 @@ public class TerrainProtocol {
* @param connectionHandler The connection handler
*/
static void sendWorldMetadata(ServerConnectionHandler connectionHandler){
Realm realm = Globals.playerManager.getPlayerRealm(connectionHandler.getPlayer());
//world metadata
connectionHandler.addMessagetoOutgoingQueue(
TerrainMessage.constructResponseMetadataMessage(
Globals.serverWorldData.getWorldSizeDiscrete(),
Globals.serverWorldData.getDynamicInterpolationRatio(),
Globals.serverWorldData.getRandomDampener(),
(int)Globals.serverWorldData.getWorldBoundMin().x,
(int)Globals.serverWorldData.getWorldBoundMin().z,
(int)Globals.serverWorldData.getWorldBoundMax().x,
(int)Globals.serverWorldData.getWorldBoundMax().z
realm.getServerWorldData().getWorldSizeDiscrete(),
realm.getServerWorldData().getDynamicInterpolationRatio(),
realm.getServerWorldData().getRandomDampener(),
(int)realm.getServerWorldData().getWorldBoundMin().x,
(int)realm.getServerWorldData().getWorldBoundMin().z,
(int)realm.getServerWorldData().getWorldBoundMax().x,
(int)realm.getServerWorldData().getWorldBoundMax().z
)
);
}

View File

@ -58,6 +58,24 @@ public class Button extends StandardContainerElement implements DrawableElement,
return rVal;
}
/**
* Creates a button that fires a callback when clicked
* @param text The text for the button label
* @param callback The callback
* @return The button
*/
public static Button createButton(String text, Runnable callback){
Button rVal = new Button();
Label rValLabel = new Label(1.0f);
rValLabel.setText(text);
rVal.addChild(rValLabel);
rVal.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
callback.run();
return false;
}});
return rVal;
}
public boolean getVisible() {
return visible;
}

View File

@ -32,9 +32,52 @@ public class Div extends StandardContainerElement implements ClickableElement,Dr
static final Vector3f windowDrawDebugColor = new Vector3f(1.0f,1.0f,1.0f);
public Div(){
/**
* Creates a new div
* @return The div
*/
public static Div createDiv(){
return new Div();
}
/**
* Creates a div that will behave like a row
* @param children The elements to include within the row
* @return The div
*/
public static Div createRow(Element ... children){
Div rVal = new Div();
rVal.setFlexDirection(YogaFlexDirection.Row);
if(children != null && children.length > 0){
for(Element child : children){
rVal.addChild(child);
}
}
return rVal;
}
/**
* Creates a div that will behave like a column
* @param children the elements to include within the column
* @return The div
*/
public static Div createCol(Element ... children){
Div rVal = new Div();
rVal.setFlexDirection(YogaFlexDirection.Column);
if(children != null && children.length > 0){
for(Element child : children){
rVal.addChild(child);
}
}
return rVal;
}
/**
* Constructor
*/
private Div(){
super();
Yoga.YGNodeStyleSetFlex(yogaNode, 1.0f);
Yoga.YGNodeStyleSetDisplay(yogaNode, Yoga.YGDisplayFlex);
}

View File

@ -16,7 +16,7 @@ public class FormElement extends StandardContainerElement implements DrawableEle
public FormElement(){
super();
Yoga.YGNodeStyleSetFlex(yogaNode, 1.0f);
Yoga.YGNodeStyleSetDisplay(yogaNode, Yoga.YGDisplayFlex);
}
public void draw(

View File

@ -17,6 +17,11 @@ import electrosphere.renderer.ui.font.Font;
*/
public class Label extends StandardContainerElement implements DrawableElement {
/**
* The default font size
*/
public static final float DEFAULT_FONT_SIZE = 1.0f;
public boolean visible = false;

View File

@ -1,5 +1,7 @@
package electrosphere.renderer.ui.elements;
import java.util.function.Consumer;
import org.joml.Vector3f;
import electrosphere.engine.Globals;
@ -67,6 +69,19 @@ public class Slider extends StandardElement implements ClickableElement, Draggab
return slider;
}
/**
* Creates a slider element
* @param callback the Logic to fire when the slider changes value
* @return the slider element
*/
public static Slider createSlider(Consumer<ValueChangeEvent> callback){
Slider slider = new Slider();
slider.setOnValueChangeCallback(new ValueChangeEventCallback() {public void execute(ValueChangeEvent event) {
callback.accept(event);
}});
return slider;
}
/**
* Private constructor
*/

View File

@ -163,8 +163,23 @@ public class StandardContainerElement extends StandardElement implements Contain
}
@Override
public void setFlexDirection(int layout){
Yoga.YGNodeStyleSetFlexDirection(yogaNode, layout);
public void setFlexDirection(YogaFlexDirection layout){
int directionInteger = Yoga.YGFlexDirectionColumn;
switch(layout){
case Column:
directionInteger = Yoga.YGFlexDirectionColumn;
break;
case Column_Reverse:
directionInteger = Yoga.YGFlexDirectionColumnReverse;
break;
case Row:
directionInteger = Yoga.YGFlexDirectionRow;
break;
case Row_Reverse:
directionInteger = Yoga.YGFlexDirectionRowReverse;
break;
}
Yoga.YGNodeStyleSetFlexDirection(yogaNode, directionInteger);
}
@Override
@ -252,18 +267,93 @@ public class StandardContainerElement extends StandardElement implements Contain
}
@Override
public void setJustifyContent(int justification){
Yoga.YGNodeStyleSetJustifyContent(this.yogaNode, justification);
public void setJustifyContent(YogaJustification justification){
int justificationInteger = Yoga.YGJustifyFlexStart;
switch(justification){
case Center:
justificationInteger = Yoga.YGJustifyCenter;
break;
case Start:
justificationInteger = Yoga.YGJustifyFlexStart;
break;
case End:
justificationInteger = Yoga.YGJustifyFlexEnd;
break;
case Around:
justificationInteger = Yoga.YGJustifySpaceAround;
break;
case Between:
justificationInteger = Yoga.YGJustifySpaceBetween;
break;
case Evenly:
justificationInteger = Yoga.YGJustifySpaceEvenly;
break;
}
Yoga.YGNodeStyleSetJustifyContent(this.yogaNode, justificationInteger);
}
@Override
public void setAlignItems(int alignment){
Yoga.YGNodeStyleSetAlignItems(this.yogaNode, alignment);
public void setAlignItems(YogaAlignment alignment){
int alignmentInteger = Yoga.YGAlignAuto;
switch(alignment){
case Auto:
alignmentInteger = Yoga.YGAlignAuto;
break;
case Start:
alignmentInteger = Yoga.YGAlignFlexStart;
break;
case End:
alignmentInteger = Yoga.YGAlignFlexEnd;
break;
case Around:
alignmentInteger = Yoga.YGAlignSpaceAround;
break;
case Between:
alignmentInteger = Yoga.YGAlignSpaceBetween;
break;
case Stretch:
alignmentInteger = Yoga.YGAlignStretch;
break;
case Baseline:
alignmentInteger = Yoga.YGAlignBaseline;
break;
case Center:
alignmentInteger = Yoga.YGAlignCenter;
break;
}
Yoga.YGNodeStyleSetAlignItems(this.yogaNode, alignmentInteger);
}
@Override
public void setAlignContent(int alignment){
Yoga.YGNodeStyleSetAlignContent(this.yogaNode, alignment);
public void setAlignContent(YogaAlignment alignment){
int alignmentInteger = Yoga.YGAlignAuto;
switch(alignment){
case Auto:
alignmentInteger = Yoga.YGAlignAuto;
break;
case Start:
alignmentInteger = Yoga.YGAlignFlexStart;
break;
case End:
alignmentInteger = Yoga.YGAlignFlexEnd;
break;
case Around:
alignmentInteger = Yoga.YGAlignSpaceAround;
break;
case Between:
alignmentInteger = Yoga.YGAlignSpaceBetween;
break;
case Stretch:
alignmentInteger = Yoga.YGAlignStretch;
break;
case Baseline:
alignmentInteger = Yoga.YGAlignBaseline;
break;
case Center:
alignmentInteger = Yoga.YGAlignCenter;
break;
}
Yoga.YGNodeStyleSetAlignContent(this.yogaNode, alignmentInteger);
}

View File

@ -214,4 +214,12 @@ public class StandardElement implements Element {
Yoga.YGNodeStyleSetMinHeight(yogaNode, height);
}
/**
* The value of the grow property
* @param grow The grow value
*/
public void setFlexGrow(float grow){
Yoga.YGNodeStyleSetFlexGrow(yogaNode, grow);
}
}

View File

@ -12,10 +12,12 @@ import electrosphere.renderer.ui.elementtypes.DrawableElement;
import electrosphere.renderer.ui.elementtypes.Element;
import electrosphere.renderer.ui.elementtypes.FocusableElement;
import electrosphere.renderer.ui.elementtypes.KeyEventElement;
import electrosphere.renderer.ui.elementtypes.ValueElement;
import electrosphere.renderer.ui.events.ClickEvent;
import electrosphere.renderer.ui.events.Event;
import electrosphere.renderer.ui.events.FocusEvent;
import electrosphere.renderer.ui.events.KeyboardEvent;
import electrosphere.renderer.ui.events.ValueChangeEvent;
import electrosphere.renderer.ui.font.Font;
import org.joml.Vector3f;
@ -27,7 +29,7 @@ import java.util.regex.Pattern;
/**
* A Text input
*/
public class TextInput extends StandardContainerElement implements DrawableElement, FocusableElement, KeyEventElement, ClickableElement {
public class TextInput extends StandardContainerElement implements DrawableElement, FocusableElement, KeyEventElement, ClickableElement, ValueElement {
Vector3f boxPosition = new Vector3f();
Vector3f boxDimensions = new Vector3f();
@ -42,6 +44,7 @@ public class TextInput extends StandardContainerElement implements DrawableEleme
FocusEventCallback onLoseFocusCallback;
KeyboardEventCallback onKeyPressCallback;
ClickEventCallback onClickCallback;
ValueChangeEventCallback onValueChangeCallback;
Vector3f color;
String text = "";
@ -53,12 +56,11 @@ public class TextInput extends StandardContainerElement implements DrawableEleme
Font font;
/**
* Creates a text input element
* @param fontSize the size of the font in the text element
* Creates a text input element using the default font size
* @return The text input
*/
public static TextInput createTextInput(float fontSize){
return new TextInput(fontSize);
public static TextInput createTextInput(){
return new TextInput(Label.DEFAULT_FONT_SIZE);
}
/**
@ -230,6 +232,11 @@ public class TextInput extends StandardContainerElement implements DrawableEleme
Globals.elementManager.focusElement(this);
propagate = false;
}
} else if(event instanceof ValueChangeEvent){
ValueChangeEvent valueEvent = (ValueChangeEvent)event;
if(this.onValueChangeCallback != null){
this.onValueChangeCallback.execute(valueEvent);
}
}
return propagate;
}
@ -247,6 +254,8 @@ public class TextInput extends StandardContainerElement implements DrawableEleme
} else {
this.setText(this.text + keyEvent.getKey());
}
//fire value change event
Globals.elementManager.fireEventNoPosition(new ValueChangeEvent(text), this);
return false;
}
@ -274,5 +283,10 @@ public class TextInput extends StandardContainerElement implements DrawableEleme
public void setOnClick(ClickEventCallback callback) {
onClickCallback = callback;
}
@Override
public void setOnValueChangeCallback(ValueChangeEventCallback callback) {
this.onValueChangeCallback = callback;
}
}

View File

@ -82,9 +82,9 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme
//yoga node for placement
this.parentWindowYogaNode = Yoga.YGNodeNew();
Yoga.YGNodeInsertChild(this.parentWindowYogaNode, this.yogaNode, 0);
setParentAlignContent(Yoga.YGAlignFlexStart);
setParentAlignItem(Yoga.YGAlignFlexStart);
setParentJustifyContent(Yoga.YGJustifyFlexStart);
setParentAlignContent(YogaAlignment.Start);
setParentAlignItem(YogaAlignment.Start);
setParentJustifyContent(YogaJustification.Start);
this.setWidth(width);
this.setHeight(height);
}
@ -369,23 +369,113 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme
}
@Override
public void setFlexDirection(int layout){
Yoga.YGNodeStyleSetFlexDirection(yogaNode, layout);
public void setFlexDirection(YogaFlexDirection layout){
int directionInteger = Yoga.YGFlexDirectionColumn;
switch(layout){
case Column:
directionInteger = Yoga.YGFlexDirectionColumn;
break;
case Column_Reverse:
directionInteger = Yoga.YGFlexDirectionColumnReverse;
break;
case Row:
directionInteger = Yoga.YGFlexDirectionRow;
break;
case Row_Reverse:
directionInteger = Yoga.YGFlexDirectionRowReverse;
break;
}
Yoga.YGNodeStyleSetFlexDirection(yogaNode, directionInteger);
}
@Override
public void setJustifyContent(int justification){
Yoga.YGNodeStyleSetJustifyContent(this.yogaNode, justification);
public void setJustifyContent(YogaJustification justification){
int justificationInteger = Yoga.YGJustifyFlexStart;
switch(justification){
case Center:
justificationInteger = Yoga.YGJustifyCenter;
break;
case Start:
justificationInteger = Yoga.YGJustifyFlexStart;
break;
case End:
justificationInteger = Yoga.YGJustifyFlexEnd;
break;
case Around:
justificationInteger = Yoga.YGJustifySpaceAround;
break;
case Between:
justificationInteger = Yoga.YGJustifySpaceBetween;
break;
case Evenly:
justificationInteger = Yoga.YGJustifySpaceEvenly;
break;
}
Yoga.YGNodeStyleSetJustifyContent(this.yogaNode, justificationInteger);
}
@Override
public void setAlignItems(int alignment){
Yoga.YGNodeStyleSetAlignItems(this.yogaNode, alignment);
public void setAlignItems(YogaAlignment alignment){
int alignmentInteger = Yoga.YGAlignAuto;
switch(alignment){
case Auto:
alignmentInteger = Yoga.YGAlignAuto;
break;
case Start:
alignmentInteger = Yoga.YGAlignFlexStart;
break;
case End:
alignmentInteger = Yoga.YGAlignFlexEnd;
break;
case Around:
alignmentInteger = Yoga.YGAlignSpaceAround;
break;
case Between:
alignmentInteger = Yoga.YGAlignSpaceBetween;
break;
case Stretch:
alignmentInteger = Yoga.YGAlignStretch;
break;
case Baseline:
alignmentInteger = Yoga.YGAlignBaseline;
break;
case Center:
alignmentInteger = Yoga.YGAlignCenter;
break;
}
Yoga.YGNodeStyleSetAlignItems(this.yogaNode, alignmentInteger);
}
@Override
public void setAlignContent(int alignment){
Yoga.YGNodeStyleSetAlignContent(this.yogaNode, alignment);
public void setAlignContent(YogaAlignment alignment){
int alignmentInteger = Yoga.YGAlignAuto;
switch(alignment){
case Auto:
alignmentInteger = Yoga.YGAlignAuto;
break;
case Start:
alignmentInteger = Yoga.YGAlignFlexStart;
break;
case End:
alignmentInteger = Yoga.YGAlignFlexEnd;
break;
case Around:
alignmentInteger = Yoga.YGAlignSpaceAround;
break;
case Between:
alignmentInteger = Yoga.YGAlignSpaceBetween;
break;
case Stretch:
alignmentInteger = Yoga.YGAlignStretch;
break;
case Baseline:
alignmentInteger = Yoga.YGAlignBaseline;
break;
case Center:
alignmentInteger = Yoga.YGAlignCenter;
break;
}
Yoga.YGNodeStyleSetAlignContent(this.yogaNode, alignmentInteger);
}
@Override
@ -482,24 +572,99 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme
* Sets the alignment of items on the parent to the window yoga node
* @param alignment The alignment value
*/
public void setParentAlignItem(int alignment){
Yoga.YGNodeStyleSetAlignItems(this.parentWindowYogaNode, alignment);
public void setParentAlignItem(YogaAlignment alignment){
int alignmentInteger = Yoga.YGAlignAuto;
switch(alignment){
case Auto:
alignmentInteger = Yoga.YGAlignAuto;
break;
case Start:
alignmentInteger = Yoga.YGAlignFlexStart;
break;
case End:
alignmentInteger = Yoga.YGAlignFlexEnd;
break;
case Around:
alignmentInteger = Yoga.YGAlignSpaceAround;
break;
case Between:
alignmentInteger = Yoga.YGAlignSpaceBetween;
break;
case Stretch:
alignmentInteger = Yoga.YGAlignStretch;
break;
case Baseline:
alignmentInteger = Yoga.YGAlignBaseline;
break;
case Center:
alignmentInteger = Yoga.YGAlignCenter;
break;
}
Yoga.YGNodeStyleSetAlignItems(this.parentWindowYogaNode, alignmentInteger);
}
/**
* Sets the alignment of content on the parent to the window yoga node
* @param alignment The alignment
*/
public void setParentAlignContent(int alignment){
Yoga.YGNodeStyleSetAlignContent(this.parentWindowYogaNode, alignment);
public void setParentAlignContent(YogaAlignment alignment){
int alignmentInteger = Yoga.YGAlignAuto;
switch(alignment){
case Auto:
alignmentInteger = Yoga.YGAlignAuto;
break;
case Start:
alignmentInteger = Yoga.YGAlignFlexStart;
break;
case End:
alignmentInteger = Yoga.YGAlignFlexEnd;
break;
case Around:
alignmentInteger = Yoga.YGAlignSpaceAround;
break;
case Between:
alignmentInteger = Yoga.YGAlignSpaceBetween;
break;
case Stretch:
alignmentInteger = Yoga.YGAlignStretch;
break;
case Baseline:
alignmentInteger = Yoga.YGAlignBaseline;
break;
case Center:
alignmentInteger = Yoga.YGAlignCenter;
break;
}
Yoga.YGNodeStyleSetAlignContent(this.parentWindowYogaNode, alignmentInteger);
}
/**
* Sets the justification of the parent yoga node containing this window
* @param justification The justification mode
*/
public void setParentJustifyContent(int justification){
Yoga.YGNodeStyleSetJustifyContent(this.parentWindowYogaNode, justification);
public void setParentJustifyContent(YogaJustification justification){
int justificationInteger = Yoga.YGJustifyFlexStart;
switch(justification){
case Center:
justificationInteger = Yoga.YGJustifyCenter;
break;
case Start:
justificationInteger = Yoga.YGJustifyFlexStart;
break;
case End:
justificationInteger = Yoga.YGJustifyFlexEnd;
break;
case Around:
justificationInteger = Yoga.YGJustifySpaceAround;
break;
case Between:
justificationInteger = Yoga.YGJustifySpaceBetween;
break;
case Evenly:
justificationInteger = Yoga.YGJustifySpaceEvenly;
break;
}
Yoga.YGNodeStyleSetJustifyContent(this.parentWindowYogaNode, justificationInteger);
}
@Override

View File

@ -7,6 +7,42 @@ import java.util.List;
*/
public interface ContainerElement extends Element {
/**
* Options for flex directions
*/
public static enum YogaFlexDirection {
Column,
Column_Reverse,
Row,
Row_Reverse,
};
/**
* Options for aligning items in containers
*/
public static enum YogaAlignment {
Auto,
Baseline,
Center,
End,
Start,
Around,
Between,
Stretch,
};
/**
* Options for justifying items in containers
*/
public static enum YogaJustification {
Center,
End,
Start,
Around,
Between,
Evenly,
}
/**
* Add a child element to this element
* @param child The child element
@ -49,24 +85,24 @@ public interface ContainerElement extends Element {
* Sets the flex direction
* @param layout the flex direction
*/
public void setFlexDirection(int layout);
public void setFlexDirection(YogaFlexDirection layout);
/**
* Sets the content justification of the container
* @param justification The spacing value
*/
public void setJustifyContent(int justification);
public void setJustifyContent(YogaJustification justification);
/**
* Sets the item alignment
* @param alignment The alignment style
*/
public void setAlignItems(int alignment);
public void setAlignItems(YogaAlignment alignment);
/**
* Sets the content alignment
* @param alignment the alignment style
*/
public void setAlignContent(int alignment);
public void setAlignContent(YogaAlignment alignment);
}

View File

@ -1,34 +1,71 @@
package electrosphere.renderer.ui.events;
public class ValueChangeEvent {
/**
* An event raised when an element changes an internal value
*/
public class ValueChangeEvent implements Event {
/**
* The type of the value changed
*/
public static enum ValueType {
STRING,
FLOAT,
}
/**
* The string value
*/
String valueString;
/**
* The float value
*/
float valueFloat;
/**
* The type of this event
*/
ValueType valueType;
/**
* Constructor for string value changes
* @param value The string
*/
public ValueChangeEvent(String value){
valueString = value;
valueType = ValueType.STRING;
}
/**
* Constructor for float value changes
* @param value The float
*/
public ValueChangeEvent(float value){
valueFloat = value;
valueType = ValueType.FLOAT;
}
/**
* Gets the type of the value
* @return The type of the value
*/
public ValueType getType(){
return valueType;
}
/**
* Gets the value that changed as a float
* @return The float value
*/
public float getAsFloat(){
return valueFloat;
}
/**
* Gets the value that changed as a string
* @return The string value
*/
public String getAsString(){
return valueString;
}

View File

@ -0,0 +1,100 @@
package electrosphere.renderer.ui.macros;
import java.util.function.Consumer;
import electrosphere.renderer.ui.elements.Div;
import electrosphere.renderer.ui.elements.Label;
import electrosphere.renderer.ui.elements.Slider;
import electrosphere.renderer.ui.elements.TextInput;
import electrosphere.renderer.ui.events.ValueChangeEvent;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaFlexDirection;
import electrosphere.renderer.ui.elementtypes.ValueElement.ValueChangeEventCallback;
/**
* Macros for creating rich ui elements (ie an input with an included label)
*/
public class InputMacros {
/**
* Default margin for a label in a labeled input
*/
static final int LABEL_MARGIN = 10;
/**
* Creates a text input that has a label and optional placeholder
* @param label The label for the text input
* @param placeholder The placeholder (can be null if no placeholder desired)
* @return The div encapsulating all the individual elements
*/
public static Div createTextInput(String label, String placeholder){
Div rVal = Div.createDiv();
rVal.setFlexDirection(YogaFlexDirection.Row);
//the label
Label labelEl = Label.createLabel(label);
labelEl.setMarginRight(LABEL_MARGIN);
rVal.addChild(labelEl);
//the actual input
TextInput inputControl = TextInput.createTextInput();
if(placeholder != null){
inputControl.setText(placeholder);
}
rVal.addChild(inputControl);
return rVal;
}
/**
* Creates a text input that has a label and optional placeholder
* @param label The label for the text input
* @param placeholder The placeholder (can be null if no placeholder desired)
* @param callback A callback fired when the text input changes value
* @return The div encapsulating all the individual elements
*/
public static Div createTextInput(String label, String placeholder, Consumer<ValueChangeEvent> callback){
Div rVal = Div.createDiv();
rVal.setFlexDirection(YogaFlexDirection.Row);
//the label
Label labelEl = Label.createLabel(label);
labelEl.setMarginRight(LABEL_MARGIN);
rVal.addChild(labelEl);
//the actual input
TextInput inputControl = TextInput.createTextInput();
if(placeholder != null){
inputControl.setText(placeholder);
}
inputControl.setOnValueChangeCallback(new ValueChangeEventCallback() {public void execute(ValueChangeEvent event) {
callback.accept(event);
}});
rVal.addChild(inputControl);
return rVal;
}
/**
* Creates a labeled slider input
* @param label The label
* @param defaultValue The default value for the slider (between 0.0 and 1.0)
* @return The slider element
*/
public static Div createSliderInput(String label, Consumer<ValueChangeEvent> onChange, float defaultValue){
Div rVal = Div.createDiv();
rVal.setFlexDirection(YogaFlexDirection.Row);
//the label
Label labelEl = Label.createLabel(label);
labelEl.setMarginRight(LABEL_MARGIN);
rVal.addChild(labelEl);
//the actual input
Slider sliderControl = Slider.createSlider(onChange);
sliderControl.setValue(defaultValue);
rVal.addChild(sliderControl);
return rVal;
}
}

View File

@ -37,9 +37,9 @@ public class PlayerCharacterCreation {
//attach player object to player character
playerObject.setPlayerEntity(newPlayerEntity);
playerObject.setWorldPos(new Vector3i(
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.x),
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.y),
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.z)
realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.x),
realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.y),
realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.z)
));
realm.getDataCellManager().addPlayerToRealm(playerObject);
//set controller id

View File

@ -1,6 +1,5 @@
package electrosphere.server.content;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.types.foliage.FoliageUtils;
import electrosphere.logger.LoggerInterface;
@ -40,9 +39,9 @@ public class EnvironmentGenerator {
LoggerInterface.loggerGameLogic.DEBUG("generate forest");
for(int i = 0; i < targetNum; i++){
Vector3d position = new Vector3d(
Globals.serverWorldData.convertWorldToReal(worldPos.x) + rand.nextFloat() * 16,
realm.getServerWorldData().convertWorldToReal(worldPos.x) + rand.nextFloat() * 16,
0,
Globals.serverWorldData.convertWorldToReal(worldPos.z) + rand.nextFloat() * 16
realm.getServerWorldData().convertWorldToReal(worldPos.z) + rand.nextFloat() * 16
);
Entity tree = FoliageUtils.serverSpawnTreeFoliage(realm, position, "oak", rand.nextLong());
}

View File

@ -31,6 +31,17 @@ import electrosphere.server.terrain.manager.ServerTerrainChunk;
* Implementation of DataCellManager that lays out cells in a logical grid (array). Useful for eg 3d terrain gridded world.
*/
public class GriddedDataCellManager implements DataCellManager, VoxelCellManager {
/**
* The minimum grid size allowed
*/
public static final int MIN_GRID_SIZE = 1;
/**
* The max grid size allowed
*/
public static final int MAX_GRID_SIZE = 10;
//these are going to be the natural ground grid of data cells, but we're going to have more than this
Map<String,ServerDataCell> groundDataCells = new HashMap<String,ServerDataCell>();
Map<ServerDataCell,Vector3i> cellPositionMap = new HashMap<ServerDataCell,Vector3i>();
@ -40,10 +51,11 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
static final int UNLOAD_FRAME_THRESHOLD = 100;
//loaded cells
Semaphore loadedCellsLock = new Semaphore(1);
Set<ServerDataCell> loadedCells;
int discreteWorldSize;
Set<ServerDataCell> loadedCells = new CopyOnWriteArraySet<ServerDataCell>();
//parent realm
Realm parent;
//the world data of the parent
ServerWorldData serverWorldData;
//Manager for terrain for this particular cell manager
ServerTerrainManager serverTerrainManager;
//manager for fluids for this particular cell manager
@ -58,24 +70,30 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
* @param parent The gridded data cell manager's parent realm
*/
public GriddedDataCellManager(
Realm parent,
ServerTerrainManager serverTerrainManager,
ServerFluidManager serverFluidManager,
ServerContentManager serverContentManager
Realm parent
) {
this.parent = parent;
this.serverTerrainManager = serverTerrainManager;
this.serverFluidManager = serverFluidManager;
this.serverContentManager = serverContentManager;
}
this.serverWorldData = this.parent.getServerWorldData();
this.serverTerrainManager = serverWorldData.getServerTerrainManager();
this.serverFluidManager = serverWorldData.getServerFluidManager();
this.serverContentManager = this.parent.getServerContentManager();
/**
* Initializes the gridded data cell manager
* @param data The server world data to back the manager with
*/
public void init(ServerWorldData data){
discreteWorldSize = data.getWorldSizeDiscrete();
loadedCells = new CopyOnWriteArraySet<ServerDataCell>();
//Assert the gridded data cell manager was given good data
if(
this.parent == null ||
this.serverWorldData == null ||
this.serverTerrainManager == null ||
this.serverFluidManager == null ||
this.serverContentManager == null
){
throw new IllegalStateException("Tried to create a GriddedDataCellManager with invalid parameters " +
this.parent + " " +
this.serverWorldData + " " +
this.serverTerrainManager + " " +
this.serverFluidManager + " " +
this.serverContentManager + " "
);
}
}
/**
@ -90,9 +108,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
for(int y = worldPos.y - playerSimulationRadius; y < worldPos.y + playerSimulationRadius + 1; y++){
for(int z = worldPos.z - playerSimulationRadius; z < worldPos.z + playerSimulationRadius + 1; z++){
if(
x >= 0 && x < discreteWorldSize &&
y >= 0 && y < discreteWorldSize &&
z >= 0 && z < discreteWorldSize
x >= 0 && x < this.serverWorldData.getWorldSizeDiscrete() &&
y >= 0 && y < this.serverWorldData.getWorldSizeDiscrete() &&
z >= 0 && z < this.serverWorldData.getWorldSizeDiscrete()
){
Vector3i targetPos = new Vector3i(x,y,z);
LoggerInterface.loggerEngine.DEBUG("GriddedDataCellManager: Add player to " + x + " " + y + " " + z);
@ -136,9 +154,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
for(int y = oldPosition.y - playerSimulationRadius; y < oldPosition.y + playerSimulationRadius + 1; y++){
for(int z = oldPosition.z - playerSimulationRadius; z < oldPosition.z + playerSimulationRadius + 1; z++){
if(
x >= 0 && x < discreteWorldSize &&
y >= 0 && y < discreteWorldSize &&
z >= 0 && z < discreteWorldSize &&
x >= 0 && x < this.serverWorldData.getWorldSizeDiscrete() &&
y >= 0 && y < this.serverWorldData.getWorldSizeDiscrete() &&
z >= 0 && z < this.serverWorldData.getWorldSizeDiscrete() &&
(
x < newPosition.x - playerSimulationRadius ||
x > newPosition.x + playerSimulationRadius ||
@ -163,9 +181,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
for(int y = newPosition.y - playerSimulationRadius; y < newPosition.y + playerSimulationRadius + 1; y++){
for(int z = newPosition.x - playerSimulationRadius; z < newPosition.z + playerSimulationRadius + 1; z++){
if(
x >= 0 && x < discreteWorldSize &&
y >= 0 && y < discreteWorldSize &&
z >= 0 && z < discreteWorldSize &&
x >= 0 && x < this.serverWorldData.getWorldSizeDiscrete() &&
y >= 0 && y < this.serverWorldData.getWorldSizeDiscrete() &&
z >= 0 && z < this.serverWorldData.getWorldSizeDiscrete() &&
(
x < oldPosition.x - playerSimulationRadius ||
x > oldPosition.x + playerSimulationRadius ||
@ -221,9 +239,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
Entity playerEntity = player.getPlayerEntity();
if(playerEntity != null && !parent.getLoadingDataCell().containsPlayer(player)){
Vector3d position = EntityUtils.getPosition(playerEntity);
int currentWorldX = Globals.serverWorldData.convertRealToChunkSpace(position.x);
int currentWorldY = Globals.serverWorldData.convertRealToChunkSpace(position.y);
int currentWorldZ = Globals.serverWorldData.convertRealToChunkSpace(position.z);
int currentWorldX = parent.getServerWorldData().convertRealToChunkSpace(position.x);
int currentWorldY = parent.getServerWorldData().convertRealToChunkSpace(position.y);
int currentWorldZ = parent.getServerWorldData().convertRealToChunkSpace(position.z);
if(currentWorldX != player.getWorldPos().x || currentWorldY != player.getWorldPos().y || currentWorldZ != player.getWorldPos().z){
movePlayer(player,new Vector3i(currentWorldX,currentWorldY,currentWorldZ));
playerChangedChunk = true;
@ -280,15 +298,15 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
*/
public ServerDataCell getDataCellAtPoint(Vector3d point){
ServerDataCell rVal = null;
int worldX = Globals.serverWorldData.convertRealToChunkSpace(point.x);
int worldY = Globals.serverWorldData.convertRealToChunkSpace(point.y);
int worldZ = Globals.serverWorldData.convertRealToChunkSpace(point.z);
int worldX = parent.getServerWorldData().convertRealToChunkSpace(point.x);
int worldY = parent.getServerWorldData().convertRealToChunkSpace(point.y);
int worldZ = parent.getServerWorldData().convertRealToChunkSpace(point.z);
Vector3i worldPos = new Vector3i(worldX,worldY,worldZ);
if(
//in bounds of array
worldX >= 0 && worldX < discreteWorldSize &&
worldY >= 0 && worldY < discreteWorldSize &&
worldZ >= 0 && worldZ < discreteWorldSize &&
worldX >= 0 && worldX < this.serverWorldData.getWorldSizeDiscrete() &&
worldY >= 0 && worldY < this.serverWorldData.getWorldSizeDiscrete() &&
worldZ >= 0 && worldZ < this.serverWorldData.getWorldSizeDiscrete() &&
//isn't null
groundDataCells.get(getServerDataCellKey(worldPos)) != null
){
@ -304,15 +322,15 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
* @return The data cell if created, null otherwise
*/
public ServerDataCell tryCreateCellAtPoint(Vector3d point){
int worldX = Globals.serverWorldData.convertRealToChunkSpace(point.x);
int worldY = Globals.serverWorldData.convertRealToChunkSpace(point.y);
int worldZ = Globals.serverWorldData.convertRealToChunkSpace(point.z);
int worldX = parent.getServerWorldData().convertRealToChunkSpace(point.x);
int worldY = parent.getServerWorldData().convertRealToChunkSpace(point.y);
int worldZ = parent.getServerWorldData().convertRealToChunkSpace(point.z);
Vector3i worldPos = new Vector3i(worldX,worldY,worldZ);
if(
//in bounds of array
worldX >= 0 && worldX < discreteWorldSize &&
worldY >= 0 && worldY < discreteWorldSize &&
worldZ >= 0 && worldZ < discreteWorldSize &&
worldX >= 0 && worldX < this.serverWorldData.getWorldSizeDiscrete() &&
worldY >= 0 && worldY < this.serverWorldData.getWorldSizeDiscrete() &&
worldZ >= 0 && worldZ < this.serverWorldData.getWorldSizeDiscrete() &&
//isn't null
groundDataCells.get(getServerDataCellKey(worldPos)) == null
){
@ -337,9 +355,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
public ServerDataCell getCellAtWorldPosition(Vector3i position){
if(
//in bounds of array
position.x >= 0 && position.x < discreteWorldSize &&
position.y >= 0 && position.y < discreteWorldSize &&
position.z >= 0 && position.z < discreteWorldSize &&
position.x >= 0 && position.x < this.serverWorldData.getWorldSizeDiscrete() &&
position.y >= 0 && position.y < this.serverWorldData.getWorldSizeDiscrete() &&
position.z >= 0 && position.z < this.serverWorldData.getWorldSizeDiscrete() &&
//isn't null
groundDataCells.get(getServerDataCellKey(position)) != null
){
@ -528,20 +546,20 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
if(positionToTest.x < 0){
returnPos.x = 0;
}
if(positionToTest.x >= Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete())){
returnPos.x = Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete()) - 1;
if(positionToTest.x >= parent.getServerWorldData().convertChunkToRealSpace(parent.getServerWorldData().getWorldSizeDiscrete())){
returnPos.x = parent.getServerWorldData().convertChunkToRealSpace(parent.getServerWorldData().getWorldSizeDiscrete()) - 1;
}
if(positionToTest.y < 0){
returnPos.y = 0;
}
if(positionToTest.y >= Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete())){
returnPos.y = Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete()) - 1;
if(positionToTest.y >= parent.getServerWorldData().convertChunkToRealSpace(parent.getServerWorldData().getWorldSizeDiscrete())){
returnPos.y = parent.getServerWorldData().convertChunkToRealSpace(parent.getServerWorldData().getWorldSizeDiscrete()) - 1;
}
if(positionToTest.z < 0){
returnPos.z = 0;
}
if(positionToTest.z >= Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete())){
returnPos.z = Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete()) - 1;
if(positionToTest.z >= parent.getServerWorldData().convertChunkToRealSpace(parent.getServerWorldData().getWorldSizeDiscrete())){
returnPos.z = parent.getServerWorldData().convertChunkToRealSpace(parent.getServerWorldData().getWorldSizeDiscrete()) - 1;
}
return returnPos;
}

View File

@ -5,7 +5,9 @@ import electrosphere.collision.hitbox.HitboxManager;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.Scene;
import electrosphere.game.server.world.ServerWorldData;
import electrosphere.net.parser.net.message.NetworkMessage;
import electrosphere.server.content.ServerContentManager;
import electrosphere.server.datacell.interfaces.DataCellManager;
import java.util.HashSet;
@ -34,15 +36,32 @@ public class Realm {
//Hitbox manager for the realm
HitboxManager hitboxManager;
/**
* The world data about the server
*/
ServerWorldData serverWorldData;
/**
* The content manager
*/
ServerContentManager serverContentManager;
/**
* Realm constructor
* @param collisionEngine The collision engine for the realm
* @param hitboxManager The hitbox manager for the realm
*/
protected Realm(CollisionEngine collisionEngine, HitboxManager hitboxManager){
protected Realm(
ServerWorldData serverWorldData,
CollisionEngine collisionEngine,
HitboxManager hitboxManager,
ServerContentManager serverContentManager
){
this.serverWorldData = serverWorldData;
this.collisionEngine = collisionEngine;
this.hitboxManager = hitboxManager;
this.serverContentManager = serverContentManager;
}
/**
@ -180,7 +199,23 @@ public class Realm {
*/
protected void save(String saveName){
dataCellManager.save(saveName);
serverWorldData.getServerTerrainManager().save(saveName);
}
/**
* Gets the server world data for this realm
* @return The server world data
*/
public ServerWorldData getServerWorldData(){
return this.serverWorldData;
}
/**
* Gets the content manager for this realm
* @return The content manager
*/
public ServerContentManager getServerContentManager(){
return this.serverContentManager;
}
}

View File

@ -10,8 +10,10 @@ import electrosphere.collision.CollisionWorldData;
import electrosphere.collision.hitbox.HitboxManager;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.scene.RealmDescriptor;
import electrosphere.game.server.world.ServerWorldData;
import electrosphere.net.server.player.Player;
import electrosphere.server.content.ServerContentManager;
import electrosphere.server.datacell.physics.ServerHitboxResolutionCallback;
/**
@ -26,7 +28,6 @@ public class RealmManager {
//Map of player to the realm the player is in
Map<Player,Realm> playerToRealmMap = new ConcurrentHashMap<Player,Realm>();
/**
* Constructor
*/
@ -40,24 +41,22 @@ public class RealmManager {
* @return The realm
*/
public Realm createRealm(){
return new Realm(new CollisionEngine(), new HitboxManager(new ServerHitboxResolutionCallback()));
return new Realm(new ServerWorldData(), new CollisionEngine(), new HitboxManager(new ServerHitboxResolutionCallback()), ServerContentManager.createServerContentManager(false));
}
/**
* Creates a realm that uses a gridded layout (ie an array of cells in 3d space)
* @return The realm
*/
public Realm createGriddedRealm(ServerWorldData serverWorldData){
public Realm createGriddedRealm(ServerWorldData serverWorldData, ServerContentManager serverContentManager){
//create collision engine
CollisionEngine collisionEngine = new CollisionEngine();
collisionEngine.setCollisionWorldData(new CollisionWorldData(serverWorldData));
//create realm
Realm realm = new Realm(collisionEngine, new HitboxManager(new ServerHitboxResolutionCallback()));
Realm realm = new Realm(serverWorldData, collisionEngine, new HitboxManager(new ServerHitboxResolutionCallback()), serverContentManager);
//create function classes
GriddedDataCellManager griddedDataCellManager = new GriddedDataCellManager(realm,Globals.serverTerrainManager,Globals.serverFluidManager,Globals.serverContentManager);
GriddedDataCellManager griddedDataCellManager = new GriddedDataCellManager(realm);
EntityDataCellMapper entityDataCellMapper = new EntityDataCellMapper();
//init gridded manager
griddedDataCellManager.init(serverWorldData);
//add function classes to realm
realm.setDataCellManager(griddedDataCellManager);
realm.setEntityDataCellMapper(entityDataCellMapper);

View File

@ -8,6 +8,7 @@ import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.terrain.TerrainChunk;
import electrosphere.server.datacell.Realm;
import electrosphere.server.terrain.manager.ServerTerrainChunk;
import electrosphere.server.terrain.manager.ServerTerrainManager;
import org.joml.Vector3d;
import org.joml.Vector3i;
@ -25,6 +26,7 @@ public class PhysicsDataCell {
DBody physicsObject;
Realm realm;
ServerTerrainManager serverTerrainManager;
float[][][] weights = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
int[][][] types = new int[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
@ -46,6 +48,7 @@ public class PhysicsDataCell {
){
PhysicsDataCell rVal = new PhysicsDataCell();
rVal.realm = realm;
rVal.serverTerrainManager = realm.getServerWorldData().getServerTerrainManager();
rVal.worldPos = worldPos;
return rVal;
}
@ -99,7 +102,7 @@ public class PhysicsDataCell {
//fill in data
//
//main chunk
ServerTerrainChunk currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x, worldPos.y, worldPos.z);
ServerTerrainChunk currentChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y, worldPos.z);
for(int x = 0; x < ChunkData.CHUNK_SIZE; x++){
for(int y = 0; y < ChunkData.CHUNK_SIZE; y++){
for(int z = 0; z < ChunkData.CHUNK_SIZE; z++){
@ -109,8 +112,8 @@ public class PhysicsDataCell {
}
}
//face X
if(worldPos.x + 1 < Globals.serverTerrainManager.getWorldDiscreteSize()){
currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y, worldPos.z);
if(worldPos.x + 1 < realm.getServerWorldData().getWorldSizeDiscrete()){
currentChunk = serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y, worldPos.z);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
weights[ChunkData.CHUNK_SIZE][i][j] = currentChunk.getWeight(0, i, j);
@ -126,8 +129,8 @@ public class PhysicsDataCell {
}
}
//face Y
if(worldPos.y + 1 < Globals.serverTerrainManager.getWorldDiscreteSize()){
currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x, worldPos.y + 1, worldPos.z);
if(worldPos.y + 1 < realm.getServerWorldData().getWorldSizeDiscrete()){
currentChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y + 1, worldPos.z);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
weights[i][ChunkData.CHUNK_SIZE][j] = currentChunk.getWeight(i, 0, j);
@ -143,8 +146,8 @@ public class PhysicsDataCell {
}
}
//face Z
if(worldPos.z + 1 < Globals.serverTerrainManager.getWorldDiscreteSize()){
currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x, worldPos.y, worldPos.z + 1);
if(worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete()){
currentChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y, worldPos.z + 1);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
weights[i][j][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(i, j, 0);
@ -161,10 +164,10 @@ public class PhysicsDataCell {
}
//edge X-Y
if(
worldPos.x + 1 < Globals.serverTerrainManager.getWorldDiscreteSize() &&
worldPos.y + 1 < Globals.serverTerrainManager.getWorldDiscreteSize()
worldPos.x + 1 < realm.getServerWorldData().getWorldSizeDiscrete() &&
worldPos.y + 1 < realm.getServerWorldData().getWorldSizeDiscrete()
){
currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y + 1, worldPos.z);
currentChunk = serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y + 1, worldPos.z);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = currentChunk.getWeight(0, 0, i);
types [ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = currentChunk.getType(0, 0, i);
@ -177,10 +180,10 @@ public class PhysicsDataCell {
}
//edge X-Z
if(
worldPos.x + 1 < Globals.serverTerrainManager.getWorldDiscreteSize() &&
worldPos.z + 1 < Globals.serverTerrainManager.getWorldDiscreteSize()
worldPos.x + 1 < realm.getServerWorldData().getWorldSizeDiscrete() &&
worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete()
){
currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y, worldPos.z + 1);
currentChunk = serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y, worldPos.z + 1);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
weights[ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(0, i, 0);
types [ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = currentChunk.getType(0, i, 0);
@ -193,10 +196,10 @@ public class PhysicsDataCell {
}
//edge Y-Z
if(
worldPos.y + 1 < Globals.serverTerrainManager.getWorldDiscreteSize() &&
worldPos.z + 1 < Globals.serverTerrainManager.getWorldDiscreteSize()
worldPos.y + 1 < realm.getServerWorldData().getWorldSizeDiscrete() &&
worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete()
){
currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x, worldPos.y + 1, worldPos.z + 1);
currentChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y + 1, worldPos.z + 1);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
weights[i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(i, 0, 0);
types [i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getType(i, 0, 0);
@ -208,11 +211,11 @@ public class PhysicsDataCell {
}
}
if(
worldPos.z + 1 < Globals.serverTerrainManager.getWorldDiscreteSize() &&
worldPos.y + 1 < Globals.serverTerrainManager.getWorldDiscreteSize() &&
worldPos.z + 1 < Globals.serverTerrainManager.getWorldDiscreteSize()
worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete() &&
worldPos.y + 1 < realm.getServerWorldData().getWorldSizeDiscrete() &&
worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete()
){
currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y + 1, worldPos.z + 1);
currentChunk = serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y + 1, worldPos.z + 1);
weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(0, 0, 0);
types[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getType(0, 0, 0);
} else {

View File

@ -1,13 +1,11 @@
package electrosphere.server.fluid.manager;
import electrosphere.engine.Globals;
import electrosphere.game.server.world.ServerWorldData;
import electrosphere.server.fluid.diskmap.FluidDiskMap;
import electrosphere.server.fluid.generation.DefaultFluidGenerator;
import electrosphere.server.fluid.generation.FluidGenerator;
import electrosphere.server.fluid.models.FluidModel;
import electrosphere.server.fluid.simulator.ServerFluidSimulator;
import electrosphere.server.fluid.simulator.cellularautomata.FluidCellularAutomataSimulator;
import electrosphere.server.terrain.manager.ServerTerrainChunk;
import electrosphere.server.terrain.manager.ServerTerrainManager;
import electrosphere.util.FileUtils;
@ -25,14 +23,7 @@ import org.joml.Vector3i;
*/
public class ServerFluidManager {
//The size of the world in discrete units * must be multiple of 200
int worldSizeDiscrete;
//The vertical multiplier applied to the statically generated fluid
int verticalInterpolationRatio;
float interpolationRandomDampener;
//the seed for the water
long seed;
//The model of the fluid this manager is managing
@ -61,25 +52,26 @@ public class ServerFluidManager {
//controls whether fluid simulation should actually happen or not
boolean simulate = true;
/**
* The parent world data
*/
ServerWorldData parent;
/**
* Constructor
*/
public ServerFluidManager(
ServerWorldData parent,
ServerTerrainManager serverTerrainManager,
int worldSizeDiscrete,
int verticalInterpolationRatio,
float interpolationRandomDampener,
long seed,
FluidGenerator chunkGenerator
){
this.parent = parent;
this.serverTerrainManager = serverTerrainManager;
this.worldSizeDiscrete = worldSizeDiscrete;
this.verticalInterpolationRatio = verticalInterpolationRatio;
this.chunkCache = new ConcurrentHashMap<String, ServerFluidChunk>();
this.chunkCacheContents = new CopyOnWriteArrayList<String>();
this.interpolationRandomDampener = interpolationRandomDampener;
this.seed = seed;
this.chunkGenerator = chunkGenerator;
}
@ -88,23 +80,6 @@ public class ServerFluidManager {
}
/**
* Constructs an arena fluid manager
* @return The arena fluid manager
*/
public static ServerFluidManager constructArenaFluidManager(ServerTerrainManager serverTerrainManager){
ServerFluidManager rVal = new ServerFluidManager();
rVal.serverTerrainManager = serverTerrainManager;
rVal.worldSizeDiscrete = 2;
rVal.verticalInterpolationRatio = 0;
rVal.chunkCache = new ConcurrentHashMap<String, ServerFluidChunk>();
rVal.chunkCacheContents = new CopyOnWriteArrayList<String>();
rVal.interpolationRandomDampener = 0.0f;
rVal.chunkGenerator = new DefaultFluidGenerator();
rVal.serverFluidSimulator = new FluidCellularAutomataSimulator();
return rVal;
}
/**
* Generates a fluid model for the manager
*/
@ -124,14 +99,16 @@ public class ServerFluidManager {
* @param saveName The name of the save
*/
public void save(String saveName){
ByteBuffer buffer = ByteBuffer.allocate(model.getElevation().length * model.getElevation()[0].length * 4);
FloatBuffer floatView = buffer.asFloatBuffer();
for(int x = 0; x < model.getElevation().length; x++){
floatView.put(model.getElevation()[x]);
if(model != null){
ByteBuffer buffer = ByteBuffer.allocate(model.getElevation().length * model.getElevation()[0].length * 4);
FloatBuffer floatView = buffer.asFloatBuffer();
for(int x = 0; x < model.getElevation().length; x++){
floatView.put(model.getElevation()[x]);
}
floatView.flip();
FileUtils.saveBinaryToSavePath(saveName, "./fluid.dat", buffer.array());
FileUtils.serializeObjectToSavePath(saveName, "./fluid.json", model);
}
floatView.flip();
FileUtils.saveBinaryToSavePath(saveName, "./fluid.dat", buffer.array());
FileUtils.serializeObjectToSavePath(saveName, "./fluid.json", model);
//for each chunk, save via disk map
for(String chunkKey : chunkCacheContents){
ServerFluidChunk chunk = chunkCache.get(chunkKey);
@ -154,9 +131,9 @@ public class ServerFluidManager {
byte[] data = FileUtils.loadBinaryFromSavePath(saveName, "./fluid.dat");
ByteBuffer buffer = ByteBuffer.wrap(data);
FloatBuffer floatView = buffer.asFloatBuffer();
float[][] elevation = new float[Globals.serverWorldData.getWorldSizeDiscrete()][Globals.serverWorldData.getWorldSizeDiscrete()];
for(int x = 0; x < Globals.serverWorldData.getWorldSizeDiscrete(); x++){
for(int y = 0; y < Globals.serverWorldData.getWorldSizeDiscrete(); y++){
float[][] elevation = new float[parent.getWorldSizeDiscrete()][parent.getWorldSizeDiscrete()];
for(int x = 0; x < parent.getWorldSizeDiscrete(); x++){
for(int y = 0; y < parent.getWorldSizeDiscrete(); y++){
elevation[x][y] = floatView.get();
}
}
@ -174,10 +151,6 @@ public class ServerFluidManager {
return y;
}
public int getWorldDiscreteSize(){
return worldSizeDiscrete;
}
public float getDiscreteValue(int x, int y){
if(model != null){
return model.getElevation()[x][y];
@ -314,6 +287,14 @@ public class ServerFluidManager {
public void setSimulate(boolean simulate){
this.simulate = simulate;
}
/**
* Sets the parent world data of this manager
* @param serverWorldData The parent world data
*/
public void setParent(ServerWorldData serverWorldData){
this.parent = serverWorldData;
}

View File

@ -3,9 +3,11 @@ package electrosphere.server.saves;
import java.util.List;
import electrosphere.engine.Globals;
import electrosphere.entity.scene.RealmDescriptor;
import electrosphere.entity.scene.SceneFile;
import electrosphere.entity.scene.SceneLoader;
import electrosphere.game.server.world.ServerWorldData;
import electrosphere.logger.LoggerInterface;
import electrosphere.server.content.ServerContentManager;
import electrosphere.server.db.DatabaseUtils;
import electrosphere.server.fluid.generation.DefaultFluidGenerator;
import electrosphere.server.fluid.manager.ServerFluidManager;
@ -59,9 +61,10 @@ public class SaveUtils {
/**
* Initializes a save directory, overwrites if one is already there
* @param saveName Name of the save
* @param sceneFile The scene descriptor file
* @return true if initialized save, false if couldn't initialize
*/
public static boolean createOrOverwriteSave(String saveName){
public static boolean createOrOverwriteSave(String saveName, SceneFile sceneFile){
String dirPath = deriveSaveDirectoryPath(saveName);
//check if exists
if(FileUtils.checkFileExists(dirPath)){
@ -81,31 +84,53 @@ public class SaveUtils {
}
}
//create main save files
createSave(saveName);
createSave(saveName, sceneFile);
return true;
}
/**
* Creates a save
* @param saveName The name of the save
* @param sceneFile The scene descriptor file
* @return Returns true if the save was created successfully, returns false if the save was not created successfully
*/
public static boolean createSave(String saveName){
public static boolean createSave(String saveName, SceneFile sceneFile){
String dirPath = deriveSaveDirectoryPath(saveName);
//create save file
Save save = new Save(saveName);
FileUtils.serializeObjectToSavePath(saveName, "/save.json", save);
//write scene file
FileUtils.serializeObjectToSavePath(saveName, "/scene.json", sceneFile);
//create server structures
Globals.serverTerrainManager = new ServerTerrainManager(ServerTerrainManager.WORLD_SIZE_DISCRETE, ServerTerrainManager.VERTICAL_INTERPOLATION_RATIO, 0, 0, new OverworldChunkGenerator());
Globals.serverWorldData = ServerWorldData.createGameWorld(Globals.serverTerrainManager);
FileUtils.serializeObjectToSavePath(saveName, "./world.json", Globals.serverWorldData);
Globals.serverFluidManager = new ServerFluidManager(Globals.serverTerrainManager, 3, 1, 0.0f, 0, new DefaultFluidGenerator());
if(Globals.serverTerrainManager != null){
Globals.serverTerrainManager.save(saveName);
if(sceneFile.getRealmDescriptor().getType() == RealmDescriptor.REALM_DESCRIPTOR_PROCEDURAL){
//generate terrain and save to disk
//
//Server world data
ServerWorldData serverWorldData = ServerWorldData.createGriddedRealmWorldData(2000);
FileUtils.serializeObjectToSavePath(saveName, "./world.json", serverWorldData);
//terrain manager
ServerTerrainManager serverTerrainManager = new ServerTerrainManager(serverWorldData, 0, new OverworldChunkGenerator());
serverTerrainManager.generate();
serverTerrainManager.save(saveName);
//fluid manager
ServerFluidManager serverFluidManager = new ServerFluidManager(serverWorldData, serverTerrainManager, 0, new DefaultFluidGenerator());
serverFluidManager.generate();
serverFluidManager.save(saveName);
} else {
LoggerInterface.loggerEngine.ERROR(new IllegalStateException("Trying to create save file and server terrain manager is null!"));
//just save to disk
//
//Server world data
ServerWorldData serverWorldData = ServerWorldData.createGriddedRealmWorldData(sceneFile.getRealmDescriptor().getGriddedRealmSize());
FileUtils.serializeObjectToSavePath(saveName, "./world.json", serverWorldData);
//terrain manager
ServerTerrainManager serverTerrainManager = new ServerTerrainManager(serverWorldData, 0, new DefaultChunkGenerator());
serverTerrainManager.save(saveName);
//fluid manager
ServerFluidManager serverFluidManager = new ServerFluidManager(serverWorldData, serverTerrainManager, 0, new DefaultFluidGenerator());
serverFluidManager.save(saveName);
}
//init db file
@ -127,10 +152,7 @@ public class SaveUtils {
FileUtils.serializeObjectToSavePath(saveName, "/save.json", Globals.currentSave);
//write server structures
if(Globals.serverTerrainManager != null){
Globals.serverTerrainManager.save(saveName);
Globals.realmManager.save(saveName);
}
Globals.realmManager.save(saveName);
}
/**
@ -145,16 +167,6 @@ public class SaveUtils {
}
}
@Deprecated
public static boolean loadTerrainAndDB(String saveName){
String dirPath = deriveSaveDirectoryPath(saveName);
String dbFilePath = FileUtils.sanitizeFilePath(dirPath) + "/central.db";
Globals.dbController.connect(dbFilePath);
Globals.serverTerrainManager.load(saveName);
return true;
}
/**
* Loads a save into the server
* @param saveName The name of the save
@ -166,21 +178,40 @@ public class SaveUtils {
//load save file
Globals.currentSave = FileUtils.loadObjectFromSavePath(saveName, "/save.json", Save.class);
//load world data
ServerWorldData serverWorldData = null;
if(FileUtils.checkSavePathExists(saveName, "/world.json")){
//load from save itself
LoggerInterface.loggerEngine.INFO("Load world data from save " + saveName);
serverWorldData = ServerWorldData.loadWorldData(saveName, false);
} else if(FileUtils.checkFileExists("/Scenes/" + saveName + "/world.json")){
//load from defined scene
LoggerInterface.loggerEngine.INFO("Load world data from scene " + saveName);
serverWorldData = ServerWorldData.loadWorldData(saveName, true);
} else {
//The scene is neither defined in the save itself nor in the assets scene files
throw new IllegalStateException("Trying to load a save that does not contain a scene!");
}
//load scene file
if(FileUtils.checkSavePathExists(saveName, "/scene.json")){
//load from save itself
LoggerInterface.loggerEngine.INFO("Load scene data from save " + saveName);
SceneLoader.serverInstantiateSaveSceneFile(saveName, serverWorldData);
} else if(FileUtils.checkFileExists("/Scenes/" + saveName)){
//load from defined scene
LoggerInterface.loggerEngine.INFO("Load scene data from scene " + saveName);
SceneLoader.serverInstantiateAssetSceneFile(saveName, serverWorldData);
} else {
//The scene is neither defined in the save itself nor in the assets scene files
throw new IllegalStateException("Trying to load a save that does not contain a scene!");
}
//load db
String dbFilePath = FileUtils.sanitizeFilePath(dirPath) + "/central.db";
Globals.dbController.connect(dbFilePath);
//create server structures
if(!saveName.equals("arena")){
Globals.serverWorldData = FileUtils.loadObjectFromSavePath(saveName, "world.json", ServerWorldData.class);
Globals.serverTerrainManager = new ServerTerrainManager(Globals.serverWorldData.getWorldSizeDiscrete(), 1, 0, 0, new DefaultChunkGenerator());
Globals.serverTerrainManager.load(saveName);
Globals.serverFluidManager = new ServerFluidManager(Globals.serverTerrainManager, 2000, 50, 0, 0, new DefaultFluidGenerator());
}
//if the scene file exists, load it
if(FileUtils.checkFileExists("assets/Scenes/" + saveName)){
//TODO: load scene
}
return true;
}
@ -208,34 +239,4 @@ public class SaveUtils {
return FileUtils.checkFileExists(dirPath);
}
/**
* Loads terrain and creates world data object
* @param currentSaveName The save name
* @return true always
*/
public static boolean loadTerrainAndCreateWorldData(String currentSaveName){
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,0.0f,0,new OverworldChunkGenerator());
Globals.serverFluidManager = new ServerFluidManager(Globals.serverTerrainManager, 2000, 50, 0.0f, 0, new DefaultFluidGenerator());
SaveUtils.loadTerrainAndDB(currentSaveName);
Globals.serverWorldData = ServerWorldData.createGameWorld(Globals.serverTerrainManager);
Globals.serverContentManager = ServerContentManager.createServerContentManager(true);
Globals.realmManager.createGriddedRealm(Globals.serverWorldData);
return true;
}
/**
* Saves world data file
* @param saveName The name of the save
* @return true always
*/
public static boolean saveWorldData(String saveName){
/*
Globals.serverWorldData = ServerWorldData.createGameWorld(Globals.serverTerrainManager);
//TODO: Globals.dataCellManager = new DataCellManager(Globals.serverWorldData);
*/
String dirPath = deriveSaveDirectoryPath(saveName);
FileUtils.serializeObjectToFilePath(dirPath + "/world.json", Globals.serverWorldData);
return true;
}
}

View File

@ -78,28 +78,28 @@ public class MacroSimulation {
//TODO: Get building type to place
String buildingTypeToPlace = "building1";
//try to find a place to put down a structure
int dynamicInterpRatio = Globals.serverTerrainManager.getDynamicInterpolationRatio();
Vector2f placementPos = new Vector2f(
(float)(charPos.x * dynamicInterpRatio + Math.random() * dynamicInterpRatio),
(float)(charPos.y * dynamicInterpRatio + Math.random() * dynamicInterpRatio)
);
int attempts = 0;
while(!VirtualStructureUtils.validStructurePlacementPosition(placementPos.x, placementPos.y, buildingTypeToPlace)){
placementPos = new Vector2f(
(float)(charPos.x * dynamicInterpRatio + Math.random() * dynamicInterpRatio),
(float)(charPos.y * dynamicInterpRatio + Math.random() * dynamicInterpRatio)
);
attempts++;
if(attempts > MAX_PLACE_ATTEMPTS){
placementPos = null;
break;
}
}
if(placementPos != null){
// Structure placedStructure = VirtualStructureUtils.placeStructureAtPoint(placementPos.x, placementPos.y, buildingTypeToPlace);
// CharacterUtils.addShelter(chara, placedStructure);
// VirtualStructureUtils.addResident(placedStructure, chara);
}
// int dynamicInterpRatio = Globals.serverTerrainManager.getDynamicInterpolationRatio();
// Vector2f placementPos = new Vector2f(
// (float)(charPos.x * dynamicInterpRatio + Math.random() * dynamicInterpRatio),
// (float)(charPos.y * dynamicInterpRatio + Math.random() * dynamicInterpRatio)
// );
// int attempts = 0;
// while(!VirtualStructureUtils.validStructurePlacementPosition(placementPos.x, placementPos.y, buildingTypeToPlace)){
// placementPos = new Vector2f(
// (float)(charPos.x * dynamicInterpRatio + Math.random() * dynamicInterpRatio),
// (float)(charPos.y * dynamicInterpRatio + Math.random() * dynamicInterpRatio)
// );
// attempts++;
// if(attempts > MAX_PLACE_ATTEMPTS){
// placementPos = null;
// break;
// }
// }
// if(placementPos != null){
// // Structure placedStructure = VirtualStructureUtils.placeStructureAtPoint(placementPos.x, placementPos.y, buildingTypeToPlace);
// // CharacterUtils.addShelter(chara, placedStructure);
// // VirtualStructureUtils.addResident(placedStructure, chara);
// }
}
}
// }

View File

@ -3,7 +3,6 @@ package electrosphere.server.terrain.editing;
import org.joml.Vector3d;
import org.joml.Vector3i;
import electrosphere.engine.Globals;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.interfaces.VoxelCellManager;
import electrosphere.server.terrain.manager.ServerTerrainChunk;
@ -46,8 +45,8 @@ public class TerrainEditing {
for(i = 0; i < numPlacesToCheck; i++){
//calculate position of edit
Vector3d offsetPos = new Vector3d(position).add(xOffsetSet[i],yOffsetSet[i],zOffsetSet[i]);
Vector3i chunkPos = Globals.serverWorldData.convertRealToWorldSpace(offsetPos);
Vector3i voxelPos = Globals.serverWorldData.convertRealToVoxelSpace(offsetPos);
Vector3i chunkPos = realm.getServerWorldData().convertRealToWorldSpace(offsetPos);
Vector3i voxelPos = realm.getServerWorldData().convertRealToVoxelSpace(offsetPos);
//get distance from true center point of sphere to current voxel position in world space
float distance = (float)new Vector3d(Math.floor(offsetPos.x),Math.floor(offsetPos.y),Math.floor(offsetPos.z)).distance(position);
float currentPositionMagnitude = editMagnitude - distance;

View File

@ -1,8 +1,7 @@
package electrosphere.server.terrain.manager;
import electrosphere.engine.Globals;
import electrosphere.game.server.world.ServerWorldData;
import electrosphere.server.terrain.diskmap.ChunkDiskMap;
import electrosphere.server.terrain.generation.DefaultChunkGenerator;
import electrosphere.server.terrain.generation.continentphase.TerrainGenerator;
import electrosphere.server.terrain.generation.interfaces.ChunkGenerator;
import electrosphere.server.terrain.models.TerrainModel;
@ -34,15 +33,18 @@ public class ServerTerrainManager {
//the interpolation width of a server terrain manager is hard coded at the moment to make sure it's divisible by the sub chunk calculations
public static final int SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO = 128;
/**
* The dampening ratio for ground noise
*/
public static final float SERVER_TERRAIN_MANAGER_DAMPENER = 1.0f;
//The size of the world in discrete units * must be multiple of 200
int worldSizeDiscrete;
//The vertical multiplier applied to the statically generated terrain
int verticalInterpolationRatio;
float interpolationRandomDampener;
/**
* The parent world data
*/
ServerWorldData parent;
//the seed for terrain generation
long seed;
//The model of the terrain this manager is managing
@ -68,17 +70,13 @@ public class ServerTerrainManager {
* Constructor
*/
public ServerTerrainManager(
int worldSizeDiscrete,
int verticalInterpolationRatio,
float interpolationRandomDampener,
ServerWorldData parent,
long seed,
ChunkGenerator chunkGenerator
){
this.worldSizeDiscrete = worldSizeDiscrete;
this.verticalInterpolationRatio = verticalInterpolationRatio;
this.parent = parent;
this.chunkCache = new ConcurrentHashMap<String, ServerTerrainChunk>();
this.chunkCacheContents = new CopyOnWriteArrayList<String>();
this.interpolationRandomDampener = interpolationRandomDampener;
this.seed = seed;
this.chunkGenerator = chunkGenerator;
}
@ -87,32 +85,17 @@ public class ServerTerrainManager {
}
/**
* Constructs an arena terrain manager
* @return The arena terrain manager
*/
public static ServerTerrainManager constructArenaTerrainManager(){
ServerTerrainManager rVal = new ServerTerrainManager();
rVal.worldSizeDiscrete = 2;
rVal.verticalInterpolationRatio = 0;
rVal.chunkCache = new ConcurrentHashMap<String, ServerTerrainChunk>();
rVal.chunkCacheContents = new CopyOnWriteArrayList<String>();
rVal.interpolationRandomDampener = 0.0f;
rVal.chunkGenerator = new DefaultChunkGenerator();
return rVal;
}
/**
* Generates a terrain model for the manager
*/
public void generate(){
TerrainGenerator terrainGen = new TerrainGenerator();
terrainGen.setInterpolationRatio(worldSizeDiscrete/200);
terrainGen.setVerticalInterpolationRatio(verticalInterpolationRatio);
terrainGen.setInterpolationRatio(parent.getWorldSizeDiscrete()/200);
terrainGen.setVerticalInterpolationRatio(parent.getWorldSizeDiscrete());
terrainGen.setRandomSeed(seed);
model = terrainGen.generateModel();
this.chunkGenerator.setModel(model);
model.setInterpolationRandomDampener(interpolationRandomDampener);
model.setInterpolationRandomDampener(SERVER_TERRAIN_MANAGER_DAMPENER);
this.chunkDiskMap = new ChunkDiskMap();
}
@ -154,9 +137,9 @@ public class ServerTerrainManager {
byte[] data = FileUtils.loadBinaryFromSavePath(saveName, "./terrain.dat");
ByteBuffer buffer = ByteBuffer.wrap(data);
FloatBuffer floatView = buffer.asFloatBuffer();
float[][] elevation = new float[Globals.serverWorldData.getWorldSizeDiscrete()][Globals.serverWorldData.getWorldSizeDiscrete()];
for(int x = 0; x < Globals.serverWorldData.getWorldSizeDiscrete(); x++){
for(int y = 0; y < Globals.serverWorldData.getWorldSizeDiscrete(); y++){
float[][] elevation = new float[parent.getWorldSizeDiscrete()][parent.getWorldSizeDiscrete()];
for(int x = 0; x < parent.getWorldSizeDiscrete(); x++){
for(int y = 0; y < parent.getWorldSizeDiscrete(); y++){
elevation[x][y] = floatView.get();
}
}
@ -175,10 +158,6 @@ public class ServerTerrainManager {
return y;
}
public int getWorldDiscreteSize(){
return worldSizeDiscrete;
}
public float getDiscreteValue(int x, int y){
if(model != null){
return model.getElevation()[x][y];
@ -293,5 +272,13 @@ public class ServerTerrainManager {
chunk.addModification(modification);
}
}
/**
* Sets the parent world data of this manager
* @param serverWorldData The parent world data
*/
public void setParent(ServerWorldData serverWorldData){
this.parent = serverWorldData;
}
}

View File

@ -1,5 +1,6 @@
package electrosphere.util.worldviewer;
import electrosphere.game.server.world.ServerWorldData;
import electrosphere.server.simulation.MacroSimulation;
import electrosphere.server.terrain.generation.OverworldChunkGenerator;
import electrosphere.server.terrain.manager.ServerTerrainManager;
@ -19,7 +20,8 @@ public class TerrainViewer {
TerrainModel terrainModel;
ServerTerrainManager terrainManager = new ServerTerrainManager(2000, 1000, 0.05f, new Random().nextLong(), new OverworldChunkGenerator());
ServerWorldData worldData = ServerWorldData.createGriddedRealmWorldData(2000);
ServerTerrainManager terrainManager = new ServerTerrainManager(worldData, new Random().nextLong(), new OverworldChunkGenerator());
terrainManager.generate();
terrainModel = terrainManager.getModel();