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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,7 +4,6 @@ import java.io.IOException;
import java.io.PipedInputStream; import java.io.PipedInputStream;
import java.io.PipedOutputStream; import java.io.PipedOutputStream;
import org.joml.Vector3d;
import org.joml.Vector3f; import org.joml.Vector3f;
import org.joml.Vector3i; import org.joml.Vector3i;
@ -14,7 +13,6 @@ import electrosphere.entity.types.creature.CreatureTemplate;
import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.creature.type.CreatureType;
import electrosphere.game.data.creature.type.visualattribute.VisualAttribute; import electrosphere.game.data.creature.type.visualattribute.VisualAttribute;
import electrosphere.game.server.world.MacroData; import electrosphere.game.server.world.MacroData;
import electrosphere.game.server.world.ServerWorldData;
import electrosphere.net.NetUtils; import electrosphere.net.NetUtils;
import electrosphere.net.client.ClientNetworking; import electrosphere.net.client.ClientNetworking;
import electrosphere.net.parser.net.message.CharacterMessage; 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.datacell.Realm;
import electrosphere.server.simulation.MacroSimulation; import electrosphere.server.simulation.MacroSimulation;
import electrosphere.server.simulation.MicroSimulation; import electrosphere.server.simulation.MicroSimulation;
import electrosphere.server.terrain.generation.OverworldChunkGenerator;
import electrosphere.server.terrain.manager.ServerTerrainManager;
/** /**
* Utilities for all loading thread types * Utilities for all loading thread types
@ -33,32 +29,6 @@ import electrosphere.server.terrain.manager.ServerTerrainManager;
public class LoadingUtils { 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){ // static void initCommonWorldData(boolean FLAG_INIT_SERVER){
// if(Globals.commonWorldData == null){ // if(Globals.commonWorldData == null){
// if(FLAG_INIT_SERVER){ // if(FLAG_INIT_SERVER){
@ -140,13 +110,6 @@ public class LoadingUtils {
} }
return rVal; 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 //set player world-space coordinates
Player playerObject = Globals.playerManager.getPlayerFromId(0); Player playerObject = Globals.playerManager.getPlayerFromId(0);
Realm realm = Globals.realmManager.getRealms().iterator().next();
playerObject.setWorldPos(new Vector3i( playerObject.setWorldPos(new Vector3i(
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.x), realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.x),
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.y), realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.y),
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.z) 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); //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); // SaveUtils.loadSave(Globals.currentSaveName);
// LoadingUtils.initTerrainDataCellManager(); // LoadingUtils.initTerrainDataCellManager();
//TODO: set spawnpoint //TODO: set spawnpoint

View File

@ -33,6 +33,10 @@ public class EntityCreationUtils {
//initialize server datacell tracking of this entity //initialize server datacell tracking of this entity
cell = realm.getDataCellManager().tryCreateCellAtPoint(position); 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 //register to entity data cell mapper
realm.getEntityDataCellMapper().registerEntity(rVal, cell); realm.getEntityDataCellMapper().registerEntity(rVal, cell);
//enable behavior tree tracking //enable behavior tree tracking

View File

@ -9,16 +9,17 @@ public class RealmDescriptor {
* A gridded realm * A gridded realm
*/ */
public static final String REALM_DESCRIPTOR_GRIDDED = "gridded"; public static final String REALM_DESCRIPTOR_GRIDDED = "gridded";
public static final String REALM_DESCRIPTOR_PROCEDURAL = "procedural";
/** /**
* The type of realm * 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 * Sets the type of realm
* @return The dimension * @param realmType The realm type
*/ */
public int getGriddedRealmDimension(){ public void setType(String realmType){
return griddedRealmDimension; 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; package electrosphere.entity.scene;
import java.util.LinkedList;
import java.util.List; import java.util.List;
/** /**
@ -27,6 +28,27 @@ public class SceneFile {
*/ */
RealmDescriptor realmDescriptor; 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 * Gets the paths of all scripts in this scene
* @return The list of all paths * @return The list of all paths
@ -51,4 +73,12 @@ public class SceneFile {
return initScriptPath; 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; 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) * 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 * Creates a scene file for the procedurally generated gamemode
* @param gridSize The size of the terrain grid of the scene
* @return The scene file * @return The scene file
*/ */
public static SceneFile createProceduralSceneFile(int gridDimension){ public static SceneFile createProceduralSceneFile(String saveName){
//base file stuff //base file stuff
SceneFile file = new SceneFile(); SceneFile file = SceneFile.createSceneFile();
file.entities = new LinkedList<EntityDescriptor>();
file.initScriptPath = null;
file.scriptPaths = new LinkedList<String>();
//realm descriptor stuff //realm descriptor stuff
file.realmDescriptor = new RealmDescriptor(); file.realmDescriptor.type = RealmDescriptor.REALM_DESCRIPTOR_PROCEDURAL;
file.realmDescriptor.type = RealmDescriptor.REALM_DESCRIPTOR_GRIDDED; file.realmDescriptor.griddedRealmSize = GriddedDataCellManager.MAX_GRID_SIZE;
file.realmDescriptor.griddedRealmDimension = gridDimension;
//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; return file;
} }

View File

@ -8,6 +8,8 @@ import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.item.ItemUtils; import electrosphere.entity.types.item.ItemUtils;
import electrosphere.entity.types.object.ObjectUtils; 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.Realm;
import electrosphere.server.datacell.ServerDataCell; import electrosphere.server.datacell.ServerDataCell;
import electrosphere.util.FileUtils; import electrosphere.util.FileUtils;
@ -19,12 +21,57 @@ public class SceneLoader {
/** /**
* Loads a scene file on the server * 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){ public static void serverInstantiateSaveSceneFile(String saveName, ServerWorldData serverWorldData){
Realm realm = Globals.realmManager.createRealm(); //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(); ServerDataCell rVal = realm.createNewCell();
SceneFile file = FileUtils.loadObjectFromAssetPath(path, SceneFile.class);
//spawn initial entities //spawn initial entities
for(EntityDescriptor descriptor : file.getEntities()){ for(EntityDescriptor descriptor : file.getEntities()){
//spawn entity somehow //spawn entity somehow
@ -62,9 +109,7 @@ public class SceneLoader {
// } // }
// Globals.scriptEngine.runScript(file.getInitScriptPath()); // Globals.scriptEngine.runScript(file.getInitScriptPath());
//instruct client to load the scene //TODO: instruct client to load the scene
return rVal;
} }
} }

View File

@ -69,14 +69,14 @@ public class ServerCollidableTree implements BehaviorTree {
} }
Realm realm = Globals.realmManager.getEntityRealm(parent); Realm realm = Globals.realmManager.getEntityRealm(parent);
//bound to world bounds //bound to world bounds
if(newPosition.x < Globals.serverWorldData.getWorldBoundMin().x){ if(newPosition.x < realm.getServerWorldData().getWorldBoundMin().x){
newPosition.x = Globals.serverWorldData.getWorldBoundMin().x; newPosition.x = realm.getServerWorldData().getWorldBoundMin().x;
} }
if(newPosition.y < Globals.serverWorldData.getWorldBoundMin().y){ if(newPosition.y < realm.getServerWorldData().getWorldBoundMin().y){
newPosition.y = Globals.serverWorldData.getWorldBoundMin().y; newPosition.y = realm.getServerWorldData().getWorldBoundMin().y;
} }
if(newPosition.z < Globals.serverWorldData.getWorldBoundMin().z){ if(newPosition.z < realm.getServerWorldData().getWorldBoundMin().z){
newPosition.z = Globals.serverWorldData.getWorldBoundMin().z; newPosition.z = realm.getServerWorldData().getWorldBoundMin().z;
} }
PhysicsUtils.setRigidBodyTransform(realm.getCollisionEngine(), newPosition, rotation, body); 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){ public static Structure placeStructureAtPoint(float posX, float posY, float posZ, String type){
int worldX = Globals.serverWorldData.convertRealToChunkSpace(posX); Realm realm = Globals.realmManager.getRealms().iterator().next();
int worldY = Globals.serverWorldData.convertRealToChunkSpace(posY); int worldX = realm.getServerWorldData().convertRealToChunkSpace(posX);
int worldY = realm.getServerWorldData().convertRealToChunkSpace(posY);
Structure rVal = new Structure(worldX,worldY,posX,posY,type); Structure rVal = new Structure(worldX,worldY,posX,posY,type);
Globals.macroData.addStructure(rVal); Globals.macroData.addStructure(rVal);
@ -35,7 +36,6 @@ public class VirtualStructureUtils {
// Globals.serverTerrainManager.deformTerrainAtLocationToValue(newWorldX, newWorldY, (int)(newLocationX), (int)(newLocationY), (float)centerHeight); // 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()); // StructureUtils.serverSpawnBasicStructure(type, realm, new Vector3d(posX,(float)centerHeight + 2.4f,posY), new Quaternionf());
return rVal; return rVal;
} }

View File

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

View File

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

View File

@ -1,7 +1,11 @@
package electrosphere.game.server.world; 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.ServerTerrainChunk;
import electrosphere.server.terrain.manager.ServerTerrainManager; import electrosphere.server.terrain.manager.ServerTerrainManager;
import electrosphere.util.FileUtils;
import org.joml.Vector3d; import org.joml.Vector3d;
import org.joml.Vector3f; import org.joml.Vector3f;
@ -15,6 +19,7 @@ public class ServerWorldData {
public static enum WorldType { public static enum WorldType {
GAME_WORLD, GAME_WORLD,
ARENA_WORLD, ARENA_WORLD,
LEVEL,
} }
WorldType type; WorldType type;
@ -45,34 +50,81 @@ public class ServerWorldData {
int dynamicInterpolationRatio; int dynamicInterpolationRatio;
float randomDampener; float randomDampener;
boolean isArena = false; 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(); 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.worldMinPoint = new Vector3f(0,0,0);
rVal.worldMaxPoint = new Vector3f(200,0,200); int worldDim = discreteWorldSize * ServerTerrainChunk.CHUNK_DIMENSION;
rVal.dynamicInterpolationRatio = 100; rVal.worldMaxPoint = new Vector3f(worldDim,worldDim, worldDim);
rVal.worldSizeDiscrete = 2;
rVal.worldSizeDiscreteVertical = 2; //misc values
rVal.randomDampener = 0.0f; rVal.dynamicInterpolationRatio = 1;
rVal.isArena = true; rVal.worldSizeDiscrete = discreteWorldSize;
rVal.worldSizeDiscreteVertical = discreteWorldSize;
rVal.randomDampener = ServerTerrainManager.SERVER_TERRAIN_MANAGER_DAMPENER;
return rVal; return rVal;
} }
public static ServerWorldData createGameWorld(ServerTerrainManager terrainManager){ // public static ServerWorldData createGameWorld(ServerTerrainManager terrainManager){
ServerWorldData rVal = new ServerWorldData(); // ServerWorldData rVal = new ServerWorldData();
rVal.type = WorldType.GAME_WORLD; // rVal.type = WorldType.GAME_WORLD;
rVal.worldMinPoint = new Vector3f(0,0,0); // rVal.worldMinPoint = new Vector3f(0,0,0);
int worldDim = terrainManager.getWorldDiscreteSize() * ServerTerrainChunk.CHUNK_DIMENSION; // int worldDim = terrainManager.getWorldDiscreteSize() * ServerTerrainChunk.CHUNK_DIMENSION;
rVal.worldMaxPoint = new Vector3f(worldDim,0,worldDim); // rVal.worldMaxPoint = new Vector3f(worldDim,0,worldDim);
rVal.dynamicInterpolationRatio = terrainManager.getDynamicInterpolationRatio(); // rVal.dynamicInterpolationRatio = terrainManager.getDynamicInterpolationRatio();
rVal.worldSizeDiscrete = terrainManager.getWorldDiscreteSize(); // rVal.worldSizeDiscrete = terrainManager.getWorldDiscreteSize();
rVal.worldSizeDiscreteVertical = 128; // rVal.worldSizeDiscreteVertical = 128;
rVal.randomDampener = terrainManager.getRandomDampener(); // 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); loggerFileIO = new Logger(LogLevel.WARNING);
loggerGameLogic = new Logger(LogLevel.WARNING); loggerGameLogic = new Logger(LogLevel.WARNING);
loggerRenderer = new Logger(LogLevel.WARNING); loggerRenderer = new Logger(LogLevel.WARNING);
loggerEngine = new Logger(LogLevel.WARNING); loggerEngine = new Logger(LogLevel.INFO);
loggerAuth = new Logger(LogLevel.WARNING); loggerAuth = new Logger(LogLevel.WARNING);
loggerDB = new Logger(LogLevel.WARNING); loggerDB = new Logger(LogLevel.WARNING);
loggerAudio = 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.auth.AuthenticationManager;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.engine.loadingthreads.LoadingThread; 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.MenuGeneratorsKeybind;
import electrosphere.menu.mainmenu.MenuGeneratorsTitleMenu; import electrosphere.menu.mainmenu.MenuGeneratorsTitleMenu;
import electrosphere.net.NetUtils; 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.Label;
import electrosphere.renderer.ui.elements.TextInput; import electrosphere.renderer.ui.elements.TextInput;
import electrosphere.renderer.ui.elementtypes.ClickableElement; import electrosphere.renderer.ui.elementtypes.ClickableElement;
import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback;
import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.elementtypes.Element;
import electrosphere.renderer.ui.events.ClickEvent; import electrosphere.renderer.ui.events.ClickEvent;
import electrosphere.server.saves.SaveUtils; import electrosphere.server.saves.SaveUtils;
import electrosphere.server.terrain.generation.OverworldChunkGenerator;
import electrosphere.server.terrain.manager.ServerTerrainManager;
/** /**
* Generator functions for creating menus * Generator functions for creating menus
@ -28,7 +27,7 @@ public class MenuGenerators {
//Used when we're displaying loading window to make main menu invisible //Used when we're displaying loading window to make main menu invisible
public static Element createEmptyMainMenu(){ public static Element createEmptyMainMenu(){
Div rVal = new Div(); Div rVal = Div.createDiv();
return rVal; return rVal;
} }
@ -51,9 +50,9 @@ public class MenuGenerators {
//need to log client in //need to log client in
Globals.clientUsername = "username"; Globals.clientUsername = "username";
Globals.clientPassword = AuthenticationManager.getHashedString("password"); Globals.clientPassword = AuthenticationManager.getHashedString("password");
LoadingThread clientThread = new LoadingThread(LoadingThread.LOAD_CHARACTER_SERVER); LoadingThread clientThread = new LoadingThread(LoadingThreadType.CHARACTER_SERVER);
Globals.loadingThreadsList.add(clientThread); Globals.loadingThreadsList.add(clientThread);
LoadingThread serverThread = new LoadingThread(LoadingThread.LOAD_MAIN_GAME); LoadingThread serverThread = new LoadingThread(LoadingThreadType.MAIN_GAME);
Globals.loadingThreadsList.add(serverThread); Globals.loadingThreadsList.add(serverThread);
Globals.RUN_CLIENT = true; Globals.RUN_CLIENT = true;
Globals.RUN_SERVER = true; Globals.RUN_SERVER = true;
@ -103,11 +102,7 @@ public class MenuGenerators {
createButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ createButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
String saveName = worldNameInput.getText(); String saveName = worldNameInput.getText();
//create save dir //create save dir
SaveUtils.createOrOverwriteSave(saveName); SaveUtils.createOrOverwriteSave(saveName, SceneGenerator.createProceduralSceneFile(saveName));
//create and save terrain
ServerTerrainManager terrainManager = new ServerTerrainManager(2000,50,0.0f,0,new OverworldChunkGenerator());
terrainManager.generate();
terrainManager.save(SaveUtils.deriveSaveDirectoryPath(saveName));
WindowUtils.replaceMainMenuContents(MenuGenerators.createWorldSelectMenu()); WindowUtils.replaceMainMenuContents(MenuGenerators.createWorldSelectMenu());
return false; return false;
}}); }});
@ -125,9 +120,10 @@ public class MenuGenerators {
saveButton.addChild(saveLabel); saveButton.addChild(saveLabel);
rVal.addChild(saveButton); rVal.addChild(saveButton);
saveButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ saveButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
SaveUtils.saveWorldData(Globals.currentSave.getName()); // SaveUtils.saveWorldData(Globals.currentSave.getName());
WindowUtils.replaceMainMenuContents(MenuGenerators.createWorldSelectMenu()); WindowUtils.replaceMainMenuContents(MenuGenerators.createWorldSelectMenu());
return false; throw new UnsupportedOperationException("Need to update to use new save flow");
// return false;
}}); }});
//button (cancel) //button (cancel)
@ -185,9 +181,9 @@ public class MenuGenerators {
hostButton.addChild(hostLabel); hostButton.addChild(hostLabel);
rVal.addChild(hostButton); rVal.addChild(hostButton);
hostButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ 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); Globals.loadingThreadsList.add(clientThread);
LoadingThread serverThread = new LoadingThread(LoadingThread.LOAD_MAIN_GAME); LoadingThread serverThread = new LoadingThread(LoadingThreadType.MAIN_GAME);
Globals.loadingThreadsList.add(serverThread); Globals.loadingThreadsList.add(serverThread);
Globals.RUN_CLIENT = true; Globals.RUN_CLIENT = true;
Globals.RUN_SERVER = true; Globals.RUN_SERVER = true;
@ -277,7 +273,7 @@ public class MenuGenerators {
NetUtils.setPort(Integer.parseInt(portInput.getText())); NetUtils.setPort(Integer.parseInt(portInput.getText()));
Globals.clientUsername = usernameInput.getText(); Globals.clientUsername = usernameInput.getText();
Globals.clientPassword = AuthenticationManager.getHashedString(passwordInput.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.loadingThreadsList.add(clientThread);
Globals.RUN_CLIENT = true; Globals.RUN_CLIENT = true;
Globals.RUN_SERVER = false; Globals.RUN_SERVER = false;
@ -319,10 +315,9 @@ public class MenuGenerators {
}}); }});
//button to open rebind controls window //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()); WindowUtils.replaceMainMenuContents(MenuGeneratorsKeybind.createControlsRebindMenu());
return false; });
}});
rVal.addChild(rebindControlsButton); rVal.addChild(rebindControlsButton);
return rVal; 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.ImGuiLinePlot.ImGuiLinePlotDataset;
import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback; import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback;
import electrosphere.server.datacell.utils.EntityLookupUtils; import electrosphere.server.datacell.utils.EntityLookupUtils;
import electrosphere.server.fluid.manager.ServerFluidManager;
import imgui.ImGui; import imgui.ImGui;
/** /**
@ -234,7 +235,8 @@ public class ImGuiWindowMacros {
//audio engine details //audio engine details
ImGui.text("Fluids Debug"); ImGui.text("Fluids Debug");
if(ImGui.button("Toggle Simulation")){ 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; int height = 500;
Window rVal = new Window(Globals.renderingEngine.getOpenGLState(),0,0,width,height,true); Window rVal = new Window(Globals.renderingEngine.getOpenGLState(),0,0,width,height,true);
// int screenLeft = (Globals.WINDOW_WIDTH - width)/2; // int screenLeft = (Globals.WINDOW_WIDTH - width)/2;
Div div = new Div(); Div div = Div.createDiv();
rVal.addChild(div); rVal.addChild(div);
div.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){ div.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN), false); 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()); WindowUtils.replaceWindow(WindowStrings.LEVEL_EDTIOR_SIDE_PANEL,MenuGeneratorsLevelEditor.createLevelEditorSidePanel());
return false; }));
}}));
rVal.applyYoga(0,0); rVal.applyYoga(0,0);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,19 +2,21 @@ package electrosphere.menu.mainmenu;
import java.util.List; import java.util.List;
import org.lwjgl.util.yoga.Yoga;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.engine.loadingthreads.LoadingThread; import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.engine.loadingthreads.LoadingThread.LoadingThreadType;
import electrosphere.entity.scene.SceneFile;
import electrosphere.menu.WindowUtils; import electrosphere.menu.WindowUtils;
import electrosphere.renderer.ui.elements.Button; import electrosphere.renderer.ui.elements.Button;
import electrosphere.renderer.ui.elements.Div; import electrosphere.renderer.ui.elements.Div;
import electrosphere.renderer.ui.elements.FormElement; import electrosphere.renderer.ui.elements.FormElement;
import electrosphere.renderer.ui.elements.Label; 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.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; import electrosphere.server.saves.SaveUtils;
/** /**
@ -22,84 +24,84 @@ import electrosphere.server.saves.SaveUtils;
*/ */
public class MenuGeneratorsLevelEditor { 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 * Creates the top level menu for the level editor
* @return The actual element containing the menu * @return The actual element containing the menu
*/ */
public static Element createLevelEditorTopMenu(){ public static Element createLevelEditorTopMenu(){
FormElement rVal = new FormElement(); 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) //
{ //title
Button backButton = new Button(); //
Label backLabel = new Label(1.0f); Div titleRow = Div.createRow(
backLabel.setText("Back"); Label.createLabel("Select Level"),
backButton.addChild(backLabel); Button.createButton("Back", () -> {
rVal.addChild(backButton);
backButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu()); WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu());
return false; })
}}); );
} titleRow.setMarginTop(30);
titleRow.setMarginBottom(30);
rVal.addChild(titleRow);
//
//button (create level) //button (create level)
{ //
Button createLevelButton = new Button(); Button createLevelButton = Button.createButton("Create Level", () -> {
Label createLevelLabel = new Label(1.0f); //go to create level flow
createLevelLabel.setText("Create Level"); WindowUtils.replaceMainMenuContents(MenuGeneratorsLevelEditor.createLevelEditorCreationMenu());
createLevelButton.addChild(createLevelLabel); });
rVal.addChild(createLevelButton); createLevelButton.setMarginBottom(30);
createLevelButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ rVal.addChild(createLevelButton);
//go to create level flow
WindowUtils.replaceMainMenuContents(MenuGeneratorsLevelEditor.createLevelEditorCreationMenu());
return false;
}});
}
//
//the buttons to load existing levels //the buttons to load existing levels
//
Div existingLevelColumn = Div.createCol();
existingLevelColumn.setAlignContent(YogaAlignment.Start);
rVal.addChild(existingLevelColumn);
List<String> saveNames = SaveUtils.getSaves(); List<String> saveNames = SaveUtils.getSaves();
for(String saveName : saveNames){ for(String saveName : saveNames){
//containing div
Div div = new Div();
div.setFlexDirection(Yoga.YGFlexDirectionRow);
div.setMaxHeight(30);
//delete level button //delete level button
Button deleteButton = new Button(); Button deleteButton = Button.createButton(" X ", () -> {
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){
SaveUtils.deleteSave(saveName); SaveUtils.deleteSave(saveName);
WindowUtils.replaceMainMenuContents(MenuGeneratorsLevelEditor.createLevelEditorTopMenu()); WindowUtils.replaceMainMenuContents(MenuGeneratorsLevelEditor.createLevelEditorTopMenu());
return false; });
}}); deleteButton.setMarginRight(10);
div.addChild(deleteButton);
//button (launch level) //button (launch level editor)
Button launchButton = new Button(); Button launchButton = Button.createButton(saveName, () -> {
Label launchLabel = new Label(1.0f);
launchLabel.setText(saveName);
launchButton.addChild(launchLabel);
launchButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
//launch level //launch level
LoadingThread loadingThread = new LoadingThread(LoadingThread.LOAD_LEVEL, saveName); LoadingThread loadingThread = new LoadingThread(LoadingThreadType.LEVEL, saveName);
Globals.loadingThreadsList.add(loadingThread); Globals.loadingThreadsList.add(loadingThread);
Globals.RUN_CLIENT = true; Globals.RUN_CLIENT = true;
Globals.RUN_SERVER = true; Globals.RUN_SERVER = true;
loadingThread.start(); 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; return rVal;
@ -111,34 +113,42 @@ public class MenuGeneratorsLevelEditor {
* @return The element containing the level creation menu * @return The element containing the level creation menu
*/ */
public static Element createLevelEditorCreationMenu(){ 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(); FormElement rVal = new FormElement();
int screenTop = 150; //top-bottom
rVal.setJustifyContent(YogaJustification.Start);
//label (address) //left-right
Label usernameLabel = new Label(1.0f); rVal.setAlignItems(YogaAlignment.Center);
usernameLabel.setText("Create Level"); rVal.setAlignContent(YogaAlignment.Start);
rVal.addChild(usernameLabel);
//button (back) //
{ //Title
Button backButton = new Button(); //
Label backLabel = new Label(1.0f); Div titleRow = Div.createRow(
backLabel.setText("Back"); Label.createLabel("Create Level"),
backButton.addChild(backLabel); Button.createButton("Back", () -> {
rVal.addChild(backButton);
backButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu()); 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 //generate default level name
List<String> saveNames = SaveUtils.getSaves(); List<String> saveNames = SaveUtils.getSaves();
int i = 0; int i = 0;
@ -147,32 +157,95 @@ public class MenuGeneratorsLevelEditor {
i++; i++;
defaultSaveName = "defaultLevel_" + 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); //Gridded realm controls
usernameInput.setText(defaultSaveName); //
rVal.addChild(usernameInput); Div griddedRealmControls = Div.createCol();
//button (create level)
{ {
Button createLevelButton = new Button(); griddedRealmControls.addChild(
Label createLevelLabel = new Label(1.0f); InputMacros.createSliderInput("Realm Size", (ValueChangeEvent event) -> {
createLevelLabel.setText("Create Level"); float value = event.getAsFloat() * GriddedDataCellManager.MAX_GRID_SIZE;
createLevelButton.addChild(createLevelLabel); sceneFile.getRealmDescriptor().setGriddedRealmSize((int)value);
rVal.addChild(createLevelButton); }, DEFAULT_GRID_SIZE / (float)GriddedDataCellManager.MAX_GRID_SIZE)
createLevelButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ );
//launch level editor sceneFile.getRealmDescriptor().setGriddedRealmSize(DEFAULT_GRID_SIZE);
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;
}});
} }
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; 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 java.util.List;
import org.joml.Vector3f; import org.joml.Vector3f;
import org.lwjgl.util.yoga.Yoga;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.types.camera.CameraEntityUtils; 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.Slider;
import electrosphere.renderer.ui.elements.StringCarousel; import electrosphere.renderer.ui.elements.StringCarousel;
import electrosphere.renderer.ui.elementtypes.ClickableElement; import electrosphere.renderer.ui.elementtypes.ClickableElement;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaFlexDirection;
import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.elementtypes.Element;
import electrosphere.renderer.ui.elementtypes.ValueElement.ValueChangeEventCallback; import electrosphere.renderer.ui.elementtypes.ValueElement.ValueChangeEventCallback;
import electrosphere.renderer.ui.events.ClickEvent; import electrosphere.renderer.ui.events.ClickEvent;
@ -203,8 +203,8 @@ public class MenuGeneratorsMultiplayer {
int width = 1800; int width = 1800;
int height = verticalPosition + 300; int height = verticalPosition + 300;
Div rVal = new Div(); Div rVal = Div.createDiv();
rVal.setFlexDirection(Yoga.YGFlexDirectionRow); rVal.setFlexDirection(YogaFlexDirection.Row);
ScrollableContainer scrollable = new ScrollableContainer(Globals.renderingEngine.getOpenGLState(), 0, 0, width, height); ScrollableContainer scrollable = new ScrollableContainer(Globals.renderingEngine.getOpenGLState(), 0, 0, width, height);
for(Element newControl : controlsToAdd){ for(Element newControl : controlsToAdd){

View File

@ -1,26 +1,36 @@
package electrosphere.menu.mainmenu; package electrosphere.menu.mainmenu;
import org.lwjgl.util.yoga.Yoga;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.engine.loadingthreads.LoadingThread; import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.engine.loadingthreads.LoadingThread.LoadingThreadType;
import electrosphere.menu.MenuGenerators; import electrosphere.menu.MenuGenerators;
import electrosphere.menu.WindowUtils; import electrosphere.menu.WindowUtils;
import electrosphere.renderer.ui.elements.Button; 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.elements.Label;
import electrosphere.renderer.ui.elementtypes.ClickableElement; 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.elementtypes.Element;
import electrosphere.renderer.ui.events.ClickEvent; import electrosphere.renderer.ui.events.ClickEvent;
/**
* Menu generators for the title menu
*/
public class MenuGeneratorsTitleMenu { public class MenuGeneratorsTitleMenu {
/**
* Creates the main title menu
* @return The menu element
*/
public static Element createTitleMenu(){ public static Element createTitleMenu(){
FormElement rVal = new FormElement(); Div rVal = Div.createDiv();
//top-bottom //top-bottom
rVal.setJustifyContent(Yoga.YGJustifyCenter); rVal.setJustifyContent(YogaJustification.Center);
//left-right //left-right
rVal.setAlignItems(Yoga.YGAlignCenter); rVal.setAlignItems(YogaAlignment.Center);
rVal.setAlignContent(Yoga.YGAlignFlexStart); rVal.setAlignContent(YogaAlignment.Center);
rVal.setFlexGrow(1.0f);
//label (title) //label (title)
Label titleLabel = new Label(1.0f); Label titleLabel = new Label(1.0f);
@ -78,7 +88,7 @@ public class MenuGeneratorsTitleMenu {
uiDebugSPQuickstartButton.addChild(uiDebugSPQuickstartLabel); uiDebugSPQuickstartButton.addChild(uiDebugSPQuickstartLabel);
rVal.addChild(uiDebugSPQuickstartButton); rVal.addChild(uiDebugSPQuickstartButton);
uiDebugSPQuickstartButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ 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.loadingThreadsList.add(loadingThread);
Globals.RUN_CLIENT = true; Globals.RUN_CLIENT = true;
Globals.RUN_SERVER = 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.Label;
import electrosphere.renderer.ui.elements.Slider; import electrosphere.renderer.ui.elements.Slider;
import electrosphere.renderer.ui.elements.VirtualScrollable; import electrosphere.renderer.ui.elements.VirtualScrollable;
import electrosphere.renderer.ui.elementtypes.ClickableElement;
import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.elementtypes.Element;
import electrosphere.renderer.ui.elementtypes.ValueElement; import electrosphere.renderer.ui.elementtypes.ValueElement;
import electrosphere.renderer.ui.events.ClickEvent;
import electrosphere.renderer.ui.events.ValueChangeEvent; import electrosphere.renderer.ui.events.ValueChangeEvent;
/** /**
@ -31,10 +29,9 @@ public class MenuGeneratorsUITesting {
FormElement rVal = new FormElement(); FormElement rVal = new FormElement();
//button (back) //button (back)
Button backButton = Button.createButton("Back", new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ Button backButton = Button.createButton("Back", () -> {
WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu()); WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu());
return false; });
}});
rVal.addChild(backButton); rVal.addChild(backButton);
ActorPanel actorPanel = new ActorPanel(Globals.renderingEngine.getOpenGLState(), 500, 100, 500, 500, ActorUtils.createActorFromModelPath("Models/deer1.fbx")); 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; package electrosphere.menu.tutorial;
import org.lwjgl.util.yoga.Yoga;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.game.data.tutorial.TutorialHint; import electrosphere.game.data.tutorial.TutorialHint;
import electrosphere.menu.WindowStrings; import electrosphere.menu.WindowStrings;
@ -9,8 +7,9 @@ import electrosphere.menu.WindowUtils;
import electrosphere.renderer.ui.elements.Button; import electrosphere.renderer.ui.elements.Button;
import electrosphere.renderer.ui.elements.Label; import electrosphere.renderer.ui.elements.Label;
import electrosphere.renderer.ui.elements.Window; import electrosphere.renderer.ui.elements.Window;
import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback; import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment;
import electrosphere.renderer.ui.events.ClickEvent; import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaFlexDirection;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification;
/** /**
* Generates in game tutorial windows * Generates in game tutorial windows
@ -30,9 +29,9 @@ public class TutorialMenus {
} else { } else {
//create the window //create the window
windowEl = new Window(Globals.renderingEngine.getOpenGLState(),50,50,500,500,true); windowEl = new Window(Globals.renderingEngine.getOpenGLState(),50,50,500,500,true);
windowEl.setParentAlignContent(Yoga.YGAlignCenter); windowEl.setParentAlignContent(YogaAlignment.Center);
windowEl.setParentJustifyContent(Yoga.YGJustifyCenter); windowEl.setParentJustifyContent(YogaJustification.Center);
windowEl.setFlexDirection(Yoga.YGFlexDirectionColumn); windowEl.setFlexDirection(YogaFlexDirection.Column);
Globals.elementManager.registerWindow(WindowStrings.TUTORIAL_POPUP, windowEl); Globals.elementManager.registerWindow(WindowStrings.TUTORIAL_POPUP, windowEl);
} }
@ -42,12 +41,8 @@ public class TutorialMenus {
//create tutorial elements //create tutorial elements
windowEl.addChild(Label.createLabel(hint.getTitleString())); windowEl.addChild(Label.createLabel(hint.getTitleString()));
windowEl.addChild(Label.createLabel(hint.getDescriptionString())); windowEl.addChild(Label.createLabel(hint.getDescriptionString()));
windowEl.addChild(Button.createButton("Close", new ClickEventCallback() { windowEl.addChild(Button.createButton("Close", () -> {
@Override WindowUtils.recursiveSetVisible(windowEl, true);
public boolean execute(ClickEvent event) {
WindowUtils.recursiveSetVisible(windowEl, true);
return false;
}
})); }));
//show the window //show the window

View File

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

View File

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

View File

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

View File

@ -5,6 +5,10 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.server.datacell.Realm;
/** /**
* Server player manager * Server player manager
*/ */
@ -27,5 +31,18 @@ public class PlayerManager {
public List<Player> getPlayers(){ public List<Player> getPlayers(){
return new LinkedList<Player>(idMap.values()); 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.parser.net.message.TerrainMessage;
import electrosphere.net.server.ServerConnectionHandler; import electrosphere.net.server.ServerConnectionHandler;
import electrosphere.server.character.PlayerCharacterCreation; import electrosphere.server.character.PlayerCharacterCreation;
import electrosphere.server.datacell.Realm;
import electrosphere.util.Utilities; import electrosphere.util.Utilities;
public class CharacterProtocol { public class CharacterProtocol {
@ -62,12 +63,13 @@ public class CharacterProtocol {
*/ */
static void spawnEntityForClient(ServerConnectionHandler connectionHandler){ static void spawnEntityForClient(ServerConnectionHandler connectionHandler){
PlayerCharacterCreation.spawnPlayerCharacter(connectionHandler); PlayerCharacterCreation.spawnPlayerCharacter(connectionHandler);
Realm realm = Globals.playerManager.getPlayerRealm(connectionHandler.getPlayer());
//set client initial discrete position //set client initial discrete position
connectionHandler.addMessagetoOutgoingQueue( connectionHandler.addMessagetoOutgoingQueue(
PlayerMessage.constructSetInitialDiscretePositionMessage( PlayerMessage.constructSetInitialDiscretePositionMessage(
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.x), realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.x),
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.y), realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.y),
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.z) realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.z)
) )
); );
//send spawn point //send spawn point

View File

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

View File

@ -58,6 +58,24 @@ public class Button extends StandardContainerElement implements DrawableElement,
return rVal; 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() { public boolean getVisible() {
return visible; 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); 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(); 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(){ public FormElement(){
super(); super();
Yoga.YGNodeStyleSetFlex(yogaNode, 1.0f); Yoga.YGNodeStyleSetDisplay(yogaNode, Yoga.YGDisplayFlex);
} }
public void draw( public void draw(

View File

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

View File

@ -1,5 +1,7 @@
package electrosphere.renderer.ui.elements; package electrosphere.renderer.ui.elements;
import java.util.function.Consumer;
import org.joml.Vector3f; import org.joml.Vector3f;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
@ -67,6 +69,19 @@ public class Slider extends StandardElement implements ClickableElement, Draggab
return slider; 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 * Private constructor
*/ */

View File

@ -163,8 +163,23 @@ public class StandardContainerElement extends StandardElement implements Contain
} }
@Override @Override
public void setFlexDirection(int layout){ public void setFlexDirection(YogaFlexDirection layout){
Yoga.YGNodeStyleSetFlexDirection(yogaNode, 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 @Override
@ -252,18 +267,93 @@ public class StandardContainerElement extends StandardElement implements Contain
} }
@Override @Override
public void setJustifyContent(int justification){ public void setJustifyContent(YogaJustification justification){
Yoga.YGNodeStyleSetJustifyContent(this.yogaNode, 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 @Override
public void setAlignItems(int alignment){ public void setAlignItems(YogaAlignment alignment){
Yoga.YGNodeStyleSetAlignItems(this.yogaNode, 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 @Override
public void setAlignContent(int alignment){ public void setAlignContent(YogaAlignment alignment){
Yoga.YGNodeStyleSetAlignContent(this.yogaNode, 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); 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.Element;
import electrosphere.renderer.ui.elementtypes.FocusableElement; import electrosphere.renderer.ui.elementtypes.FocusableElement;
import electrosphere.renderer.ui.elementtypes.KeyEventElement; import electrosphere.renderer.ui.elementtypes.KeyEventElement;
import electrosphere.renderer.ui.elementtypes.ValueElement;
import electrosphere.renderer.ui.events.ClickEvent; import electrosphere.renderer.ui.events.ClickEvent;
import electrosphere.renderer.ui.events.Event; import electrosphere.renderer.ui.events.Event;
import electrosphere.renderer.ui.events.FocusEvent; import electrosphere.renderer.ui.events.FocusEvent;
import electrosphere.renderer.ui.events.KeyboardEvent; import electrosphere.renderer.ui.events.KeyboardEvent;
import electrosphere.renderer.ui.events.ValueChangeEvent;
import electrosphere.renderer.ui.font.Font; import electrosphere.renderer.ui.font.Font;
import org.joml.Vector3f; import org.joml.Vector3f;
@ -27,7 +29,7 @@ import java.util.regex.Pattern;
/** /**
* A Text input * 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 boxPosition = new Vector3f();
Vector3f boxDimensions = new Vector3f(); Vector3f boxDimensions = new Vector3f();
@ -42,6 +44,7 @@ public class TextInput extends StandardContainerElement implements DrawableEleme
FocusEventCallback onLoseFocusCallback; FocusEventCallback onLoseFocusCallback;
KeyboardEventCallback onKeyPressCallback; KeyboardEventCallback onKeyPressCallback;
ClickEventCallback onClickCallback; ClickEventCallback onClickCallback;
ValueChangeEventCallback onValueChangeCallback;
Vector3f color; Vector3f color;
String text = ""; String text = "";
@ -53,12 +56,11 @@ public class TextInput extends StandardContainerElement implements DrawableEleme
Font font; Font font;
/** /**
* Creates a text input element * Creates a text input element using the default font size
* @param fontSize the size of the font in the text element
* @return The text input * @return The text input
*/ */
public static TextInput createTextInput(float fontSize){ public static TextInput createTextInput(){
return new TextInput(fontSize); return new TextInput(Label.DEFAULT_FONT_SIZE);
} }
/** /**
@ -230,6 +232,11 @@ public class TextInput extends StandardContainerElement implements DrawableEleme
Globals.elementManager.focusElement(this); Globals.elementManager.focusElement(this);
propagate = false; propagate = false;
} }
} else if(event instanceof ValueChangeEvent){
ValueChangeEvent valueEvent = (ValueChangeEvent)event;
if(this.onValueChangeCallback != null){
this.onValueChangeCallback.execute(valueEvent);
}
} }
return propagate; return propagate;
} }
@ -247,6 +254,8 @@ public class TextInput extends StandardContainerElement implements DrawableEleme
} else { } else {
this.setText(this.text + keyEvent.getKey()); this.setText(this.text + keyEvent.getKey());
} }
//fire value change event
Globals.elementManager.fireEventNoPosition(new ValueChangeEvent(text), this);
return false; return false;
} }
@ -274,5 +283,10 @@ public class TextInput extends StandardContainerElement implements DrawableEleme
public void setOnClick(ClickEventCallback callback) { public void setOnClick(ClickEventCallback callback) {
onClickCallback = 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 //yoga node for placement
this.parentWindowYogaNode = Yoga.YGNodeNew(); this.parentWindowYogaNode = Yoga.YGNodeNew();
Yoga.YGNodeInsertChild(this.parentWindowYogaNode, this.yogaNode, 0); Yoga.YGNodeInsertChild(this.parentWindowYogaNode, this.yogaNode, 0);
setParentAlignContent(Yoga.YGAlignFlexStart); setParentAlignContent(YogaAlignment.Start);
setParentAlignItem(Yoga.YGAlignFlexStart); setParentAlignItem(YogaAlignment.Start);
setParentJustifyContent(Yoga.YGJustifyFlexStart); setParentJustifyContent(YogaJustification.Start);
this.setWidth(width); this.setWidth(width);
this.setHeight(height); this.setHeight(height);
} }
@ -369,23 +369,113 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme
} }
@Override @Override
public void setFlexDirection(int layout){ public void setFlexDirection(YogaFlexDirection layout){
Yoga.YGNodeStyleSetFlexDirection(yogaNode, 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 @Override
public void setJustifyContent(int justification){ public void setJustifyContent(YogaJustification justification){
Yoga.YGNodeStyleSetJustifyContent(this.yogaNode, 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 @Override
public void setAlignItems(int alignment){ public void setAlignItems(YogaAlignment alignment){
Yoga.YGNodeStyleSetAlignItems(this.yogaNode, 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 @Override
public void setAlignContent(int alignment){ public void setAlignContent(YogaAlignment alignment){
Yoga.YGNodeStyleSetAlignContent(this.yogaNode, 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 @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 * Sets the alignment of items on the parent to the window yoga node
* @param alignment The alignment value * @param alignment The alignment value
*/ */
public void setParentAlignItem(int alignment){ public void setParentAlignItem(YogaAlignment alignment){
Yoga.YGNodeStyleSetAlignItems(this.parentWindowYogaNode, 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 * Sets the alignment of content on the parent to the window yoga node
* @param alignment The alignment * @param alignment The alignment
*/ */
public void setParentAlignContent(int alignment){ public void setParentAlignContent(YogaAlignment alignment){
Yoga.YGNodeStyleSetAlignContent(this.parentWindowYogaNode, 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 * Sets the justification of the parent yoga node containing this window
* @param justification The justification mode * @param justification The justification mode
*/ */
public void setParentJustifyContent(int justification){ public void setParentJustifyContent(YogaJustification justification){
Yoga.YGNodeStyleSetJustifyContent(this.parentWindowYogaNode, 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 @Override

View File

@ -7,6 +7,42 @@ import java.util.List;
*/ */
public interface ContainerElement extends Element { 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 * Add a child element to this element
* @param child The child element * @param child The child element
@ -49,24 +85,24 @@ public interface ContainerElement extends Element {
* Sets the flex direction * Sets the flex direction
* @param layout 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 * Sets the content justification of the container
* @param justification The spacing value * @param justification The spacing value
*/ */
public void setJustifyContent(int justification); public void setJustifyContent(YogaJustification justification);
/** /**
* Sets the item alignment * Sets the item alignment
* @param alignment The alignment style * @param alignment The alignment style
*/ */
public void setAlignItems(int alignment); public void setAlignItems(YogaAlignment alignment);
/** /**
* Sets the content alignment * Sets the content alignment
* @param alignment the alignment style * @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; 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 { public static enum ValueType {
STRING, STRING,
FLOAT, FLOAT,
} }
/**
* The string value
*/
String valueString; String valueString;
/**
* The float value
*/
float valueFloat; float valueFloat;
/**
* The type of this event
*/
ValueType valueType; ValueType valueType;
/**
* Constructor for string value changes
* @param value The string
*/
public ValueChangeEvent(String value){ public ValueChangeEvent(String value){
valueString = value; valueString = value;
valueType = ValueType.STRING; valueType = ValueType.STRING;
} }
/**
* Constructor for float value changes
* @param value The float
*/
public ValueChangeEvent(float value){ public ValueChangeEvent(float value){
valueFloat = value; valueFloat = value;
valueType = ValueType.FLOAT; valueType = ValueType.FLOAT;
} }
/**
* Gets the type of the value
* @return The type of the value
*/
public ValueType getType(){ public ValueType getType(){
return valueType; return valueType;
} }
/**
* Gets the value that changed as a float
* @return The float value
*/
public float getAsFloat(){ public float getAsFloat(){
return valueFloat; return valueFloat;
} }
/**
* Gets the value that changed as a string
* @return The string value
*/
public String getAsString(){ public String getAsString(){
return valueString; 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 //attach player object to player character
playerObject.setPlayerEntity(newPlayerEntity); playerObject.setPlayerEntity(newPlayerEntity);
playerObject.setWorldPos(new Vector3i( playerObject.setWorldPos(new Vector3i(
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.x), realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.x),
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.y), realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.y),
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.z) realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.z)
)); ));
realm.getDataCellManager().addPlayerToRealm(playerObject); realm.getDataCellManager().addPlayerToRealm(playerObject);
//set controller id //set controller id

View File

@ -1,6 +1,5 @@
package electrosphere.server.content; package electrosphere.server.content;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.types.foliage.FoliageUtils; import electrosphere.entity.types.foliage.FoliageUtils;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
@ -40,9 +39,9 @@ public class EnvironmentGenerator {
LoggerInterface.loggerGameLogic.DEBUG("generate forest"); LoggerInterface.loggerGameLogic.DEBUG("generate forest");
for(int i = 0; i < targetNum; i++){ for(int i = 0; i < targetNum; i++){
Vector3d position = new Vector3d( Vector3d position = new Vector3d(
Globals.serverWorldData.convertWorldToReal(worldPos.x) + rand.nextFloat() * 16, realm.getServerWorldData().convertWorldToReal(worldPos.x) + rand.nextFloat() * 16,
0, 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()); 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. * 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 { 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 //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<String,ServerDataCell> groundDataCells = new HashMap<String,ServerDataCell>();
Map<ServerDataCell,Vector3i> cellPositionMap = new HashMap<ServerDataCell,Vector3i>(); 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; static final int UNLOAD_FRAME_THRESHOLD = 100;
//loaded cells //loaded cells
Semaphore loadedCellsLock = new Semaphore(1); Semaphore loadedCellsLock = new Semaphore(1);
Set<ServerDataCell> loadedCells; Set<ServerDataCell> loadedCells = new CopyOnWriteArraySet<ServerDataCell>();
int discreteWorldSize;
//parent realm //parent realm
Realm parent; Realm parent;
//the world data of the parent
ServerWorldData serverWorldData;
//Manager for terrain for this particular cell manager //Manager for terrain for this particular cell manager
ServerTerrainManager serverTerrainManager; ServerTerrainManager serverTerrainManager;
//manager for fluids for this particular cell manager //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 * @param parent The gridded data cell manager's parent realm
*/ */
public GriddedDataCellManager( public GriddedDataCellManager(
Realm parent, Realm parent
ServerTerrainManager serverTerrainManager,
ServerFluidManager serverFluidManager,
ServerContentManager serverContentManager
) { ) {
this.parent = parent; this.parent = parent;
this.serverTerrainManager = serverTerrainManager; this.serverWorldData = this.parent.getServerWorldData();
this.serverFluidManager = serverFluidManager; this.serverTerrainManager = serverWorldData.getServerTerrainManager();
this.serverContentManager = serverContentManager; this.serverFluidManager = serverWorldData.getServerFluidManager();
} this.serverContentManager = this.parent.getServerContentManager();
/** //Assert the gridded data cell manager was given good data
* Initializes the gridded data cell manager if(
* @param data The server world data to back the manager with this.parent == null ||
*/ this.serverWorldData == null ||
public void init(ServerWorldData data){ this.serverTerrainManager == null ||
discreteWorldSize = data.getWorldSizeDiscrete(); this.serverFluidManager == null ||
loadedCells = new CopyOnWriteArraySet<ServerDataCell>(); 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 y = worldPos.y - playerSimulationRadius; y < worldPos.y + playerSimulationRadius + 1; y++){
for(int z = worldPos.z - playerSimulationRadius; z < worldPos.z + playerSimulationRadius + 1; z++){ for(int z = worldPos.z - playerSimulationRadius; z < worldPos.z + playerSimulationRadius + 1; z++){
if( if(
x >= 0 && x < discreteWorldSize && x >= 0 && x < this.serverWorldData.getWorldSizeDiscrete() &&
y >= 0 && y < discreteWorldSize && y >= 0 && y < this.serverWorldData.getWorldSizeDiscrete() &&
z >= 0 && z < discreteWorldSize z >= 0 && z < this.serverWorldData.getWorldSizeDiscrete()
){ ){
Vector3i targetPos = new Vector3i(x,y,z); Vector3i targetPos = new Vector3i(x,y,z);
LoggerInterface.loggerEngine.DEBUG("GriddedDataCellManager: Add player to " + 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 y = oldPosition.y - playerSimulationRadius; y < oldPosition.y + playerSimulationRadius + 1; y++){
for(int z = oldPosition.z - playerSimulationRadius; z < oldPosition.z + playerSimulationRadius + 1; z++){ for(int z = oldPosition.z - playerSimulationRadius; z < oldPosition.z + playerSimulationRadius + 1; z++){
if( if(
x >= 0 && x < discreteWorldSize && x >= 0 && x < this.serverWorldData.getWorldSizeDiscrete() &&
y >= 0 && y < discreteWorldSize && y >= 0 && y < this.serverWorldData.getWorldSizeDiscrete() &&
z >= 0 && z < discreteWorldSize && z >= 0 && z < this.serverWorldData.getWorldSizeDiscrete() &&
( (
x < newPosition.x - playerSimulationRadius || x < newPosition.x - playerSimulationRadius ||
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 y = newPosition.y - playerSimulationRadius; y < newPosition.y + playerSimulationRadius + 1; y++){
for(int z = newPosition.x - playerSimulationRadius; z < newPosition.z + playerSimulationRadius + 1; z++){ for(int z = newPosition.x - playerSimulationRadius; z < newPosition.z + playerSimulationRadius + 1; z++){
if( if(
x >= 0 && x < discreteWorldSize && x >= 0 && x < this.serverWorldData.getWorldSizeDiscrete() &&
y >= 0 && y < discreteWorldSize && y >= 0 && y < this.serverWorldData.getWorldSizeDiscrete() &&
z >= 0 && z < discreteWorldSize && z >= 0 && z < this.serverWorldData.getWorldSizeDiscrete() &&
( (
x < oldPosition.x - playerSimulationRadius || x < oldPosition.x - playerSimulationRadius ||
x > oldPosition.x + playerSimulationRadius || x > oldPosition.x + playerSimulationRadius ||
@ -221,9 +239,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
Entity playerEntity = player.getPlayerEntity(); Entity playerEntity = player.getPlayerEntity();
if(playerEntity != null && !parent.getLoadingDataCell().containsPlayer(player)){ if(playerEntity != null && !parent.getLoadingDataCell().containsPlayer(player)){
Vector3d position = EntityUtils.getPosition(playerEntity); Vector3d position = EntityUtils.getPosition(playerEntity);
int currentWorldX = Globals.serverWorldData.convertRealToChunkSpace(position.x); int currentWorldX = parent.getServerWorldData().convertRealToChunkSpace(position.x);
int currentWorldY = Globals.serverWorldData.convertRealToChunkSpace(position.y); int currentWorldY = parent.getServerWorldData().convertRealToChunkSpace(position.y);
int currentWorldZ = Globals.serverWorldData.convertRealToChunkSpace(position.z); int currentWorldZ = parent.getServerWorldData().convertRealToChunkSpace(position.z);
if(currentWorldX != player.getWorldPos().x || currentWorldY != player.getWorldPos().y || currentWorldZ != player.getWorldPos().z){ if(currentWorldX != player.getWorldPos().x || currentWorldY != player.getWorldPos().y || currentWorldZ != player.getWorldPos().z){
movePlayer(player,new Vector3i(currentWorldX,currentWorldY,currentWorldZ)); movePlayer(player,new Vector3i(currentWorldX,currentWorldY,currentWorldZ));
playerChangedChunk = true; playerChangedChunk = true;
@ -280,15 +298,15 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
*/ */
public ServerDataCell getDataCellAtPoint(Vector3d point){ public ServerDataCell getDataCellAtPoint(Vector3d point){
ServerDataCell rVal = null; ServerDataCell rVal = null;
int worldX = Globals.serverWorldData.convertRealToChunkSpace(point.x); int worldX = parent.getServerWorldData().convertRealToChunkSpace(point.x);
int worldY = Globals.serverWorldData.convertRealToChunkSpace(point.y); int worldY = parent.getServerWorldData().convertRealToChunkSpace(point.y);
int worldZ = Globals.serverWorldData.convertRealToChunkSpace(point.z); int worldZ = parent.getServerWorldData().convertRealToChunkSpace(point.z);
Vector3i worldPos = new Vector3i(worldX,worldY,worldZ); Vector3i worldPos = new Vector3i(worldX,worldY,worldZ);
if( if(
//in bounds of array //in bounds of array
worldX >= 0 && worldX < discreteWorldSize && worldX >= 0 && worldX < this.serverWorldData.getWorldSizeDiscrete() &&
worldY >= 0 && worldY < discreteWorldSize && worldY >= 0 && worldY < this.serverWorldData.getWorldSizeDiscrete() &&
worldZ >= 0 && worldZ < discreteWorldSize && worldZ >= 0 && worldZ < this.serverWorldData.getWorldSizeDiscrete() &&
//isn't null //isn't null
groundDataCells.get(getServerDataCellKey(worldPos)) != null groundDataCells.get(getServerDataCellKey(worldPos)) != null
){ ){
@ -304,15 +322,15 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
* @return The data cell if created, null otherwise * @return The data cell if created, null otherwise
*/ */
public ServerDataCell tryCreateCellAtPoint(Vector3d point){ public ServerDataCell tryCreateCellAtPoint(Vector3d point){
int worldX = Globals.serverWorldData.convertRealToChunkSpace(point.x); int worldX = parent.getServerWorldData().convertRealToChunkSpace(point.x);
int worldY = Globals.serverWorldData.convertRealToChunkSpace(point.y); int worldY = parent.getServerWorldData().convertRealToChunkSpace(point.y);
int worldZ = Globals.serverWorldData.convertRealToChunkSpace(point.z); int worldZ = parent.getServerWorldData().convertRealToChunkSpace(point.z);
Vector3i worldPos = new Vector3i(worldX,worldY,worldZ); Vector3i worldPos = new Vector3i(worldX,worldY,worldZ);
if( if(
//in bounds of array //in bounds of array
worldX >= 0 && worldX < discreteWorldSize && worldX >= 0 && worldX < this.serverWorldData.getWorldSizeDiscrete() &&
worldY >= 0 && worldY < discreteWorldSize && worldY >= 0 && worldY < this.serverWorldData.getWorldSizeDiscrete() &&
worldZ >= 0 && worldZ < discreteWorldSize && worldZ >= 0 && worldZ < this.serverWorldData.getWorldSizeDiscrete() &&
//isn't null //isn't null
groundDataCells.get(getServerDataCellKey(worldPos)) == null groundDataCells.get(getServerDataCellKey(worldPos)) == null
){ ){
@ -337,9 +355,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
public ServerDataCell getCellAtWorldPosition(Vector3i position){ public ServerDataCell getCellAtWorldPosition(Vector3i position){
if( if(
//in bounds of array //in bounds of array
position.x >= 0 && position.x < discreteWorldSize && position.x >= 0 && position.x < this.serverWorldData.getWorldSizeDiscrete() &&
position.y >= 0 && position.y < discreteWorldSize && position.y >= 0 && position.y < this.serverWorldData.getWorldSizeDiscrete() &&
position.z >= 0 && position.z < discreteWorldSize && position.z >= 0 && position.z < this.serverWorldData.getWorldSizeDiscrete() &&
//isn't null //isn't null
groundDataCells.get(getServerDataCellKey(position)) != null groundDataCells.get(getServerDataCellKey(position)) != null
){ ){
@ -528,20 +546,20 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
if(positionToTest.x < 0){ if(positionToTest.x < 0){
returnPos.x = 0; returnPos.x = 0;
} }
if(positionToTest.x >= Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete())){ if(positionToTest.x >= parent.getServerWorldData().convertChunkToRealSpace(parent.getServerWorldData().getWorldSizeDiscrete())){
returnPos.x = Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete()) - 1; returnPos.x = parent.getServerWorldData().convertChunkToRealSpace(parent.getServerWorldData().getWorldSizeDiscrete()) - 1;
} }
if(positionToTest.y < 0){ if(positionToTest.y < 0){
returnPos.y = 0; returnPos.y = 0;
} }
if(positionToTest.y >= Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete())){ if(positionToTest.y >= parent.getServerWorldData().convertChunkToRealSpace(parent.getServerWorldData().getWorldSizeDiscrete())){
returnPos.y = Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete()) - 1; returnPos.y = parent.getServerWorldData().convertChunkToRealSpace(parent.getServerWorldData().getWorldSizeDiscrete()) - 1;
} }
if(positionToTest.z < 0){ if(positionToTest.z < 0){
returnPos.z = 0; returnPos.z = 0;
} }
if(positionToTest.z >= Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete())){ if(positionToTest.z >= parent.getServerWorldData().convertChunkToRealSpace(parent.getServerWorldData().getWorldSizeDiscrete())){
returnPos.z = Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete()) - 1; returnPos.z = parent.getServerWorldData().convertChunkToRealSpace(parent.getServerWorldData().getWorldSizeDiscrete()) - 1;
} }
return returnPos; return returnPos;
} }

View File

@ -5,7 +5,9 @@ import electrosphere.collision.hitbox.HitboxManager;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.Scene; import electrosphere.entity.Scene;
import electrosphere.game.server.world.ServerWorldData;
import electrosphere.net.parser.net.message.NetworkMessage; import electrosphere.net.parser.net.message.NetworkMessage;
import electrosphere.server.content.ServerContentManager;
import electrosphere.server.datacell.interfaces.DataCellManager; import electrosphere.server.datacell.interfaces.DataCellManager;
import java.util.HashSet; import java.util.HashSet;
@ -34,15 +36,32 @@ public class Realm {
//Hitbox manager for the realm //Hitbox manager for the realm
HitboxManager hitboxManager; HitboxManager hitboxManager;
/**
* The world data about the server
*/
ServerWorldData serverWorldData;
/**
* The content manager
*/
ServerContentManager serverContentManager;
/** /**
* Realm constructor * Realm constructor
* @param collisionEngine The collision engine for the realm * @param collisionEngine The collision engine for the realm
* @param hitboxManager The hitbox manager 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.collisionEngine = collisionEngine;
this.hitboxManager = hitboxManager; this.hitboxManager = hitboxManager;
this.serverContentManager = serverContentManager;
} }
/** /**
@ -180,7 +199,23 @@ public class Realm {
*/ */
protected void save(String saveName){ protected void save(String saveName){
dataCellManager.save(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.collision.hitbox.HitboxManager;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.scene.RealmDescriptor;
import electrosphere.game.server.world.ServerWorldData; import electrosphere.game.server.world.ServerWorldData;
import electrosphere.net.server.player.Player; import electrosphere.net.server.player.Player;
import electrosphere.server.content.ServerContentManager;
import electrosphere.server.datacell.physics.ServerHitboxResolutionCallback; import electrosphere.server.datacell.physics.ServerHitboxResolutionCallback;
/** /**
@ -26,7 +28,6 @@ public class RealmManager {
//Map of player to the realm the player is in //Map of player to the realm the player is in
Map<Player,Realm> playerToRealmMap = new ConcurrentHashMap<Player,Realm>(); Map<Player,Realm> playerToRealmMap = new ConcurrentHashMap<Player,Realm>();
/** /**
* Constructor * Constructor
*/ */
@ -40,24 +41,22 @@ public class RealmManager {
* @return The realm * @return The realm
*/ */
public Realm createRealm(){ 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) * Creates a realm that uses a gridded layout (ie an array of cells in 3d space)
* @return The realm * @return The realm
*/ */
public Realm createGriddedRealm(ServerWorldData serverWorldData){ public Realm createGriddedRealm(ServerWorldData serverWorldData, ServerContentManager serverContentManager){
//create collision engine //create collision engine
CollisionEngine collisionEngine = new CollisionEngine(); CollisionEngine collisionEngine = new CollisionEngine();
collisionEngine.setCollisionWorldData(new CollisionWorldData(serverWorldData)); collisionEngine.setCollisionWorldData(new CollisionWorldData(serverWorldData));
//create realm //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 //create function classes
GriddedDataCellManager griddedDataCellManager = new GriddedDataCellManager(realm,Globals.serverTerrainManager,Globals.serverFluidManager,Globals.serverContentManager); GriddedDataCellManager griddedDataCellManager = new GriddedDataCellManager(realm);
EntityDataCellMapper entityDataCellMapper = new EntityDataCellMapper(); EntityDataCellMapper entityDataCellMapper = new EntityDataCellMapper();
//init gridded manager
griddedDataCellManager.init(serverWorldData);
//add function classes to realm //add function classes to realm
realm.setDataCellManager(griddedDataCellManager); realm.setDataCellManager(griddedDataCellManager);
realm.setEntityDataCellMapper(entityDataCellMapper); realm.setEntityDataCellMapper(entityDataCellMapper);

View File

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

View File

@ -1,13 +1,11 @@
package electrosphere.server.fluid.manager; 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.diskmap.FluidDiskMap;
import electrosphere.server.fluid.generation.DefaultFluidGenerator;
import electrosphere.server.fluid.generation.FluidGenerator; import electrosphere.server.fluid.generation.FluidGenerator;
import electrosphere.server.fluid.models.FluidModel; import electrosphere.server.fluid.models.FluidModel;
import electrosphere.server.fluid.simulator.ServerFluidSimulator; import electrosphere.server.fluid.simulator.ServerFluidSimulator;
import electrosphere.server.fluid.simulator.cellularautomata.FluidCellularAutomataSimulator;
import electrosphere.server.terrain.manager.ServerTerrainChunk; import electrosphere.server.terrain.manager.ServerTerrainChunk;
import electrosphere.server.terrain.manager.ServerTerrainManager; import electrosphere.server.terrain.manager.ServerTerrainManager;
import electrosphere.util.FileUtils; import electrosphere.util.FileUtils;
@ -25,14 +23,7 @@ import org.joml.Vector3i;
*/ */
public class ServerFluidManager { public class ServerFluidManager {
//The size of the world in discrete units * must be multiple of 200 //the seed for the water
int worldSizeDiscrete;
//The vertical multiplier applied to the statically generated fluid
int verticalInterpolationRatio;
float interpolationRandomDampener;
long seed; long seed;
//The model of the fluid this manager is managing //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 //controls whether fluid simulation should actually happen or not
boolean simulate = true; boolean simulate = true;
/**
* The parent world data
*/
ServerWorldData parent;
/** /**
* Constructor * Constructor
*/ */
public ServerFluidManager( public ServerFluidManager(
ServerWorldData parent,
ServerTerrainManager serverTerrainManager, ServerTerrainManager serverTerrainManager,
int worldSizeDiscrete,
int verticalInterpolationRatio,
float interpolationRandomDampener,
long seed, long seed,
FluidGenerator chunkGenerator FluidGenerator chunkGenerator
){ ){
this.parent = parent;
this.serverTerrainManager = serverTerrainManager; this.serverTerrainManager = serverTerrainManager;
this.worldSizeDiscrete = worldSizeDiscrete;
this.verticalInterpolationRatio = verticalInterpolationRatio;
this.chunkCache = new ConcurrentHashMap<String, ServerFluidChunk>(); this.chunkCache = new ConcurrentHashMap<String, ServerFluidChunk>();
this.chunkCacheContents = new CopyOnWriteArrayList<String>(); this.chunkCacheContents = new CopyOnWriteArrayList<String>();
this.interpolationRandomDampener = interpolationRandomDampener;
this.seed = seed; this.seed = seed;
this.chunkGenerator = chunkGenerator; 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 * Generates a fluid model for the manager
*/ */
@ -124,14 +99,16 @@ public class ServerFluidManager {
* @param saveName The name of the save * @param saveName The name of the save
*/ */
public void save(String saveName){ public void save(String saveName){
ByteBuffer buffer = ByteBuffer.allocate(model.getElevation().length * model.getElevation()[0].length * 4); if(model != null){
FloatBuffer floatView = buffer.asFloatBuffer(); ByteBuffer buffer = ByteBuffer.allocate(model.getElevation().length * model.getElevation()[0].length * 4);
for(int x = 0; x < model.getElevation().length; x++){ FloatBuffer floatView = buffer.asFloatBuffer();
floatView.put(model.getElevation()[x]); 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 each chunk, save via disk map
for(String chunkKey : chunkCacheContents){ for(String chunkKey : chunkCacheContents){
ServerFluidChunk chunk = chunkCache.get(chunkKey); ServerFluidChunk chunk = chunkCache.get(chunkKey);
@ -154,9 +131,9 @@ public class ServerFluidManager {
byte[] data = FileUtils.loadBinaryFromSavePath(saveName, "./fluid.dat"); byte[] data = FileUtils.loadBinaryFromSavePath(saveName, "./fluid.dat");
ByteBuffer buffer = ByteBuffer.wrap(data); ByteBuffer buffer = ByteBuffer.wrap(data);
FloatBuffer floatView = buffer.asFloatBuffer(); FloatBuffer floatView = buffer.asFloatBuffer();
float[][] elevation = new float[Globals.serverWorldData.getWorldSizeDiscrete()][Globals.serverWorldData.getWorldSizeDiscrete()]; float[][] elevation = new float[parent.getWorldSizeDiscrete()][parent.getWorldSizeDiscrete()];
for(int x = 0; x < Globals.serverWorldData.getWorldSizeDiscrete(); x++){ for(int x = 0; x < parent.getWorldSizeDiscrete(); x++){
for(int y = 0; y < Globals.serverWorldData.getWorldSizeDiscrete(); y++){ for(int y = 0; y < parent.getWorldSizeDiscrete(); y++){
elevation[x][y] = floatView.get(); elevation[x][y] = floatView.get();
} }
} }
@ -174,10 +151,6 @@ public class ServerFluidManager {
return y; return y;
} }
public int getWorldDiscreteSize(){
return worldSizeDiscrete;
}
public float getDiscreteValue(int x, int y){ public float getDiscreteValue(int x, int y){
if(model != null){ if(model != null){
return model.getElevation()[x][y]; return model.getElevation()[x][y];
@ -314,6 +287,14 @@ public class ServerFluidManager {
public void setSimulate(boolean simulate){ public void setSimulate(boolean simulate){
this.simulate = 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 java.util.List;
import electrosphere.engine.Globals; 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.game.server.world.ServerWorldData;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.server.content.ServerContentManager;
import electrosphere.server.db.DatabaseUtils; import electrosphere.server.db.DatabaseUtils;
import electrosphere.server.fluid.generation.DefaultFluidGenerator; import electrosphere.server.fluid.generation.DefaultFluidGenerator;
import electrosphere.server.fluid.manager.ServerFluidManager; import electrosphere.server.fluid.manager.ServerFluidManager;
@ -59,9 +61,10 @@ public class SaveUtils {
/** /**
* Initializes a save directory, overwrites if one is already there * Initializes a save directory, overwrites if one is already there
* @param saveName Name of the save * @param saveName Name of the save
* @param sceneFile The scene descriptor file
* @return true if initialized save, false if couldn't initialize * @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); String dirPath = deriveSaveDirectoryPath(saveName);
//check if exists //check if exists
if(FileUtils.checkFileExists(dirPath)){ if(FileUtils.checkFileExists(dirPath)){
@ -81,31 +84,53 @@ public class SaveUtils {
} }
} }
//create main save files //create main save files
createSave(saveName); createSave(saveName, sceneFile);
return true; return true;
} }
/** /**
* Creates a save * Creates a save
* @param saveName The name of the 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 * @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); String dirPath = deriveSaveDirectoryPath(saveName);
//create save file //create save file
Save save = new Save(saveName); Save save = new Save(saveName);
FileUtils.serializeObjectToSavePath(saveName, "/save.json", save); FileUtils.serializeObjectToSavePath(saveName, "/save.json", save);
//write scene file
FileUtils.serializeObjectToSavePath(saveName, "/scene.json", sceneFile);
//create server structures //create server structures
Globals.serverTerrainManager = new ServerTerrainManager(ServerTerrainManager.WORLD_SIZE_DISCRETE, ServerTerrainManager.VERTICAL_INTERPOLATION_RATIO, 0, 0, new OverworldChunkGenerator()); if(sceneFile.getRealmDescriptor().getType() == RealmDescriptor.REALM_DESCRIPTOR_PROCEDURAL){
Globals.serverWorldData = ServerWorldData.createGameWorld(Globals.serverTerrainManager); //generate terrain and save to disk
FileUtils.serializeObjectToSavePath(saveName, "./world.json", Globals.serverWorldData); //
Globals.serverFluidManager = new ServerFluidManager(Globals.serverTerrainManager, 3, 1, 0.0f, 0, new DefaultFluidGenerator()); //Server world data
if(Globals.serverTerrainManager != null){ ServerWorldData serverWorldData = ServerWorldData.createGriddedRealmWorldData(2000);
Globals.serverTerrainManager.save(saveName); 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 { } 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 //init db file
@ -127,10 +152,7 @@ public class SaveUtils {
FileUtils.serializeObjectToSavePath(saveName, "/save.json", Globals.currentSave); FileUtils.serializeObjectToSavePath(saveName, "/save.json", Globals.currentSave);
//write server structures //write server structures
if(Globals.serverTerrainManager != null){ Globals.realmManager.save(saveName);
Globals.serverTerrainManager.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 * Loads a save into the server
* @param saveName The name of the save * @param saveName The name of the save
@ -166,21 +178,40 @@ public class SaveUtils {
//load save file //load save file
Globals.currentSave = FileUtils.loadObjectFromSavePath(saveName, "/save.json", Save.class); 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 //load db
String dbFilePath = FileUtils.sanitizeFilePath(dirPath) + "/central.db"; String dbFilePath = FileUtils.sanitizeFilePath(dirPath) + "/central.db";
Globals.dbController.connect(dbFilePath); 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; return true;
} }
@ -208,34 +239,4 @@ public class SaveUtils {
return FileUtils.checkFileExists(dirPath); 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 //TODO: Get building type to place
String buildingTypeToPlace = "building1"; String buildingTypeToPlace = "building1";
//try to find a place to put down a structure //try to find a place to put down a structure
int dynamicInterpRatio = Globals.serverTerrainManager.getDynamicInterpolationRatio(); // int dynamicInterpRatio = Globals.serverTerrainManager.getDynamicInterpolationRatio();
Vector2f placementPos = new Vector2f( // Vector2f placementPos = new Vector2f(
(float)(charPos.x * dynamicInterpRatio + Math.random() * dynamicInterpRatio), // (float)(charPos.x * dynamicInterpRatio + Math.random() * dynamicInterpRatio),
(float)(charPos.y * dynamicInterpRatio + Math.random() * dynamicInterpRatio) // (float)(charPos.y * dynamicInterpRatio + Math.random() * dynamicInterpRatio)
); // );
int attempts = 0; // int attempts = 0;
while(!VirtualStructureUtils.validStructurePlacementPosition(placementPos.x, placementPos.y, buildingTypeToPlace)){ // while(!VirtualStructureUtils.validStructurePlacementPosition(placementPos.x, placementPos.y, buildingTypeToPlace)){
placementPos = new Vector2f( // placementPos = new Vector2f(
(float)(charPos.x * dynamicInterpRatio + Math.random() * dynamicInterpRatio), // (float)(charPos.x * dynamicInterpRatio + Math.random() * dynamicInterpRatio),
(float)(charPos.y * dynamicInterpRatio + Math.random() * dynamicInterpRatio) // (float)(charPos.y * dynamicInterpRatio + Math.random() * dynamicInterpRatio)
); // );
attempts++; // attempts++;
if(attempts > MAX_PLACE_ATTEMPTS){ // if(attempts > MAX_PLACE_ATTEMPTS){
placementPos = null; // placementPos = null;
break; // break;
} // }
} // }
if(placementPos != null){ // if(placementPos != null){
// Structure placedStructure = VirtualStructureUtils.placeStructureAtPoint(placementPos.x, placementPos.y, buildingTypeToPlace); // // Structure placedStructure = VirtualStructureUtils.placeStructureAtPoint(placementPos.x, placementPos.y, buildingTypeToPlace);
// CharacterUtils.addShelter(chara, placedStructure); // // CharacterUtils.addShelter(chara, placedStructure);
// VirtualStructureUtils.addResident(placedStructure, chara); // // VirtualStructureUtils.addResident(placedStructure, chara);
} // }
} }
} }
// } // }

View File

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

View File

@ -1,8 +1,7 @@
package electrosphere.server.terrain.manager; 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.diskmap.ChunkDiskMap;
import electrosphere.server.terrain.generation.DefaultChunkGenerator;
import electrosphere.server.terrain.generation.continentphase.TerrainGenerator; import electrosphere.server.terrain.generation.continentphase.TerrainGenerator;
import electrosphere.server.terrain.generation.interfaces.ChunkGenerator; import electrosphere.server.terrain.generation.interfaces.ChunkGenerator;
import electrosphere.server.terrain.models.TerrainModel; 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 //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; 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 parent world data
*/
//The vertical multiplier applied to the statically generated terrain ServerWorldData parent;
int verticalInterpolationRatio;
//the seed for terrain generation
float interpolationRandomDampener;
long seed; long seed;
//The model of the terrain this manager is managing //The model of the terrain this manager is managing
@ -68,17 +70,13 @@ public class ServerTerrainManager {
* Constructor * Constructor
*/ */
public ServerTerrainManager( public ServerTerrainManager(
int worldSizeDiscrete, ServerWorldData parent,
int verticalInterpolationRatio,
float interpolationRandomDampener,
long seed, long seed,
ChunkGenerator chunkGenerator ChunkGenerator chunkGenerator
){ ){
this.worldSizeDiscrete = worldSizeDiscrete; this.parent = parent;
this.verticalInterpolationRatio = verticalInterpolationRatio;
this.chunkCache = new ConcurrentHashMap<String, ServerTerrainChunk>(); this.chunkCache = new ConcurrentHashMap<String, ServerTerrainChunk>();
this.chunkCacheContents = new CopyOnWriteArrayList<String>(); this.chunkCacheContents = new CopyOnWriteArrayList<String>();
this.interpolationRandomDampener = interpolationRandomDampener;
this.seed = seed; this.seed = seed;
this.chunkGenerator = chunkGenerator; 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 * Generates a terrain model for the manager
*/ */
public void generate(){ public void generate(){
TerrainGenerator terrainGen = new TerrainGenerator(); TerrainGenerator terrainGen = new TerrainGenerator();
terrainGen.setInterpolationRatio(worldSizeDiscrete/200); terrainGen.setInterpolationRatio(parent.getWorldSizeDiscrete()/200);
terrainGen.setVerticalInterpolationRatio(verticalInterpolationRatio); terrainGen.setVerticalInterpolationRatio(parent.getWorldSizeDiscrete());
terrainGen.setRandomSeed(seed); terrainGen.setRandomSeed(seed);
model = terrainGen.generateModel(); model = terrainGen.generateModel();
this.chunkGenerator.setModel(model); this.chunkGenerator.setModel(model);
model.setInterpolationRandomDampener(interpolationRandomDampener); model.setInterpolationRandomDampener(SERVER_TERRAIN_MANAGER_DAMPENER);
this.chunkDiskMap = new ChunkDiskMap(); this.chunkDiskMap = new ChunkDiskMap();
} }
@ -154,9 +137,9 @@ public class ServerTerrainManager {
byte[] data = FileUtils.loadBinaryFromSavePath(saveName, "./terrain.dat"); byte[] data = FileUtils.loadBinaryFromSavePath(saveName, "./terrain.dat");
ByteBuffer buffer = ByteBuffer.wrap(data); ByteBuffer buffer = ByteBuffer.wrap(data);
FloatBuffer floatView = buffer.asFloatBuffer(); FloatBuffer floatView = buffer.asFloatBuffer();
float[][] elevation = new float[Globals.serverWorldData.getWorldSizeDiscrete()][Globals.serverWorldData.getWorldSizeDiscrete()]; float[][] elevation = new float[parent.getWorldSizeDiscrete()][parent.getWorldSizeDiscrete()];
for(int x = 0; x < Globals.serverWorldData.getWorldSizeDiscrete(); x++){ for(int x = 0; x < parent.getWorldSizeDiscrete(); x++){
for(int y = 0; y < Globals.serverWorldData.getWorldSizeDiscrete(); y++){ for(int y = 0; y < parent.getWorldSizeDiscrete(); y++){
elevation[x][y] = floatView.get(); elevation[x][y] = floatView.get();
} }
} }
@ -175,10 +158,6 @@ public class ServerTerrainManager {
return y; return y;
} }
public int getWorldDiscreteSize(){
return worldSizeDiscrete;
}
public float getDiscreteValue(int x, int y){ public float getDiscreteValue(int x, int y){
if(model != null){ if(model != null){
return model.getElevation()[x][y]; return model.getElevation()[x][y];
@ -293,5 +272,13 @@ public class ServerTerrainManager {
chunk.addModification(modification); 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; package electrosphere.util.worldviewer;
import electrosphere.game.server.world.ServerWorldData;
import electrosphere.server.simulation.MacroSimulation; import electrosphere.server.simulation.MacroSimulation;
import electrosphere.server.terrain.generation.OverworldChunkGenerator; import electrosphere.server.terrain.generation.OverworldChunkGenerator;
import electrosphere.server.terrain.manager.ServerTerrainManager; import electrosphere.server.terrain.manager.ServerTerrainManager;
@ -19,7 +20,8 @@ public class TerrainViewer {
TerrainModel terrainModel; 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(); terrainManager.generate();
terrainModel = terrainManager.getModel(); terrainModel = terrainManager.getModel();