From 2b68231789f14268b9ac3e48a5976fc20a7dacae Mon Sep 17 00:00:00 2001 From: austin Date: Sat, 13 Jul 2024 21:11:46 -0400 Subject: [PATCH] scene/save refactor --- saves/arena/central.db | Bin 81920 -> 0 bytes .../java/electrosphere/engine/Globals.java | 12 - src/main/java/electrosphere/engine/Main.java | 5 +- .../loadingthreads/DebugSPWorldLoading.java | 25 +- .../loadingthreads/LevelEditorLoading.java | 26 +- .../engine/loadingthreads/LevelLoading.java | 11 +- .../engine/loadingthreads/LoadingThread.java | 78 +++-- .../engine/loadingthreads/LoadingUtils.java | 44 +-- .../engine/loadingthreads/ServerLoading.java | 2 +- .../entity/EntityCreationUtils.java | 4 + .../entity/scene/RealmDescriptor.java | 31 +- .../electrosphere/entity/scene/SceneFile.java | 30 ++ .../entity/scene/SceneGenerator.java | 33 ++- .../entity/scene/SceneLoader.java | 59 +++- .../collidable/ServerCollidableTree.java | 12 +- .../virtual/VirtualStructureUtils.java | 6 +- .../electrosphere/game/server/town/Town.java | 54 ++-- .../game/server/world/MacroData.java | 60 ++-- .../game/server/world/ServerWorldData.java | 121 ++++++-- .../electrosphere/logger/LoggerInterface.java | 2 +- .../electrosphere/menu/MenuGenerators.java | 33 +-- .../menu/debug/ImGuiWindowMacros.java | 4 +- .../menu/ingame/MenuGeneratorsInGame.java | 7 +- .../menu/ingame/MenuGeneratorsInventory.java | 14 +- .../ingame/MenuGeneratorsLevelEditor.java | 129 ++++----- .../ingame/MenuGeneratorsTerrainEditing.java | 27 +- .../menu/mainmenu/MenuGeneratorsDemo.java | 10 +- .../menu/mainmenu/MenuGeneratorsKeybind.java | 39 ++- .../mainmenu/MenuGeneratorsLevelEditor.java | 271 +++++++++++------- .../mainmenu/MenuGeneratorsMultiplayer.java | 6 +- .../mainmenu/MenuGeneratorsTitleMenu.java | 26 +- .../mainmenu/MenuGeneratorsUITesting.java | 7 +- .../menu/tutorial/TutorialMenus.java | 21 +- .../client/protocol/CharacterProtocol.java | 3 +- .../net/server/ServerConnectionHandler.java | 8 + .../net/server/player/Player.java | 3 +- .../net/server/player/PlayerManager.java | 17 ++ .../server/protocol/CharacterProtocol.java | 8 +- .../net/server/protocol/TerrainProtocol.java | 22 +- .../renderer/ui/elements/Button.java | 18 ++ .../renderer/ui/elements/Div.java | 47 ++- .../renderer/ui/elements/FormElement.java | 2 +- .../renderer/ui/elements/Label.java | 5 + .../renderer/ui/elements/Slider.java | 15 + .../ui/elements/StandardContainerElement.java | 106 ++++++- .../renderer/ui/elements/StandardElement.java | 8 + .../renderer/ui/elements/TextInput.java | 24 +- .../renderer/ui/elements/Window.java | 199 +++++++++++-- .../ui/elementtypes/ContainerElement.java | 44 ++- .../renderer/ui/events/ValueChangeEvent.java | 39 ++- .../renderer/ui/macros/InputMacros.java | 100 +++++++ .../character/PlayerCharacterCreation.java | 6 +- .../server/content/EnvironmentGenerator.java | 5 +- .../datacell/GriddedDataCellManager.java | 118 ++++---- .../electrosphere/server/datacell/Realm.java | 37 ++- .../server/datacell/RealmManager.java | 13 +- .../datacell/physics/PhysicsDataCell.java | 43 +-- .../fluid/manager/ServerFluidManager.java | 77 ++--- .../electrosphere/server/saves/SaveUtils.java | 133 ++++----- .../server/simulation/MacroSimulation.java | 44 +-- .../terrain/editing/TerrainEditing.java | 5 +- .../terrain/manager/ServerTerrainManager.java | 69 ++--- .../util/worldviewer/TerrainViewer.java | 4 +- 63 files changed, 1611 insertions(+), 820 deletions(-) delete mode 100644 saves/arena/central.db create mode 100644 src/main/java/electrosphere/renderer/ui/macros/InputMacros.java diff --git a/saves/arena/central.db b/saves/arena/central.db deleted file mode 100644 index 3ff7910a698f8b56833431be2c9294608c4e04d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 81920 zcmeI)T~FIq7{GCxmzV${&~&pj31Ku%N(38Yh<03{Erp0>OGAJ_q1(#5;6i9f$Xi1@ zO_RS#_gSW0?RH;c+GQ`g-R(Guog9*s_G+s2w+M00@v)!hcOGI~r|j*d@-@qNT&i4{ zHDg7YR#a8_(l8W7iHOH-@o<+Ju`=Sm5YKAY`k>W_^2y#0q3}OSM2jfl@4~-N{Wet& z{TbSy{A2QPa%kdw{O@rq_$v5oP#tS%e`!^*84CgkAbNeZ@od6KrZ*FZM$d-EcDk$4h_*IJZpLc2G<|+vwO4B9j|HnU zuCo?t?>QU4mr6)G$)AYBWfNP8T_dxbydU2^GQLS1Ew;BwZo0jT#)$~|z$_RC@!gHD z;=3_>Vn)*wtEwIA%IiU?QaH(!s`*;JRIG}Xt`z0ITYZw1w{S;y@|OFJ=w+#TxM+y) zM=@KQ*7OY#&4&Y{k-X(y&Dai|)&?-UCnc%!54Q&1d9w1r`kGAJ3^z znku<7vto8tnD=^IGVq$aQuo@NsAA6q~n)h>pv~$(dO_liNeFQ?>OoFx!ml z!ps-5&KciZ8ImINngw*FbeVPz)INE4MR>t1(kc_^SK=2WFwZfz&CUTd8* zj=dcpFMF%Q;uoti=a;LHc&Oo5iuhtd009ILKmY**5I_I{1Q0*~0e=Z->To3d)T%6x zi@enEzl!)`K>z^+5I_I{1Q0*~0R#|000F-V1coC)@ecs4`~NSL@C&~sNInQ4fB*sr zAb+7xS|CdVm<-21-qzE8@00IagfB*srAbZ{^%bI0tg_0 z00IagfB*srAb4jQ`Tzf1|ND4?Neux65I_I{1Q0*~0R#|000AMu^*?2R00Iag zfB*srAb009ILKmY** i5I_I{1Q6i(); + rVal.scriptPaths = new LinkedList(); + rVal.initScriptPath = null; + rVal.realmDescriptor = new RealmDescriptor(); + return rVal; + } + /** * Gets the paths of all scripts in this scene * @return The list of all paths @@ -51,4 +73,12 @@ public class SceneFile { return initScriptPath; } + /** + * Gets the realm descriptor + * @return The realm descriptor + */ + public RealmDescriptor getRealmDescriptor(){ + return realmDescriptor; + } + } diff --git a/src/main/java/electrosphere/entity/scene/SceneGenerator.java b/src/main/java/electrosphere/entity/scene/SceneGenerator.java index f72133be..5bae2d39 100644 --- a/src/main/java/electrosphere/entity/scene/SceneGenerator.java +++ b/src/main/java/electrosphere/entity/scene/SceneGenerator.java @@ -1,6 +1,12 @@ package electrosphere.entity.scene; -import java.util.LinkedList; +import electrosphere.game.server.world.ServerWorldData; +import electrosphere.server.datacell.GriddedDataCellManager; +import electrosphere.server.fluid.generation.DefaultFluidGenerator; +import electrosphere.server.fluid.manager.ServerFluidManager; +import electrosphere.server.terrain.generation.OverworldChunkGenerator; +import electrosphere.server.terrain.manager.ServerTerrainManager; +import electrosphere.util.FileUtils; /** * Generates scene files where appropriate (ie, if playing the procedurally generated level) @@ -9,19 +15,26 @@ public class SceneGenerator { /** * Creates a scene file for the procedurally generated gamemode + * @param gridSize The size of the terrain grid of the scene * @return The scene file */ - public static SceneFile createProceduralSceneFile(int gridDimension){ + public static SceneFile createProceduralSceneFile(String saveName){ //base file stuff - SceneFile file = new SceneFile(); - file.entities = new LinkedList(); - file.initScriptPath = null; - file.scriptPaths = new LinkedList(); - + SceneFile file = SceneFile.createSceneFile(); //realm descriptor stuff - file.realmDescriptor = new RealmDescriptor(); - file.realmDescriptor.type = RealmDescriptor.REALM_DESCRIPTOR_GRIDDED; - file.realmDescriptor.griddedRealmDimension = gridDimension; + file.realmDescriptor.type = RealmDescriptor.REALM_DESCRIPTOR_PROCEDURAL; + file.realmDescriptor.griddedRealmSize = GriddedDataCellManager.MAX_GRID_SIZE; + + //create terrain + ServerWorldData serverWorldData = ServerWorldData.createGriddedRealmWorldData(2000); + ServerTerrainManager serverTerrainManager = new ServerTerrainManager(serverWorldData, 0, new OverworldChunkGenerator()); + serverTerrainManager.generate(); + serverTerrainManager.save(saveName); + //create world.json + FileUtils.serializeObjectToSavePath(saveName, "./world.json", serverWorldData); + //create mock fluid sim manager + ServerFluidManager serverFluidManager = new ServerFluidManager(serverWorldData, serverTerrainManager, 0, new DefaultFluidGenerator()); + serverFluidManager.save(saveName); return file; } diff --git a/src/main/java/electrosphere/entity/scene/SceneLoader.java b/src/main/java/electrosphere/entity/scene/SceneLoader.java index affa138f..4817071b 100644 --- a/src/main/java/electrosphere/entity/scene/SceneLoader.java +++ b/src/main/java/electrosphere/entity/scene/SceneLoader.java @@ -8,6 +8,8 @@ import electrosphere.entity.EntityUtils; import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.item.ItemUtils; import electrosphere.entity.types.object.ObjectUtils; +import electrosphere.game.server.world.ServerWorldData; +import electrosphere.server.content.ServerContentManager; import electrosphere.server.datacell.Realm; import electrosphere.server.datacell.ServerDataCell; import electrosphere.util.FileUtils; @@ -19,12 +21,57 @@ public class SceneLoader { /** * Loads a scene file on the server - * @param path The path in the assets directory to a scene file + * @param path The name of the save to look for a scene file within */ - public ServerDataCell serverInstantiateSceneFile(String path){ - Realm realm = Globals.realmManager.createRealm(); + public static void serverInstantiateSaveSceneFile(String saveName, ServerWorldData serverWorldData){ + //load scene file + SceneFile file = FileUtils.loadObjectFromSavePath(saveName, "/scene.json", SceneFile.class); + //instantiate scene data + serverInstantiateSceneFile(file,serverWorldData); + } + + /** + * Loads a scene file on the server + * @param path The name of the scene in the assets/scenes folder + */ + public static void serverInstantiateAssetSceneFile(String sceneName, ServerWorldData serverWorldData){ + //load scene file + String sanitizedPath = FileUtils.sanitizeFilePath("/Scenes/" + sceneName + "/scene.json"); + SceneFile file = FileUtils.loadObjectFromAssetPath(sanitizedPath, SceneFile.class); + //instantiate scene data + serverInstantiateSceneFile(file,serverWorldData); + } + + /** + * Loads a scene file on the server + * @param path The path in the assets directory to a scene file + * @param isSave if true, will try to load scene from save file instead of asset file + */ + private static void serverInstantiateSceneFile(SceneFile file, ServerWorldData serverWorldData){ + + // + //Content manager + // + ServerContentManager serverContentManager = null; + if(file.realmDescriptor.getType() == RealmDescriptor.REALM_DESCRIPTOR_PROCEDURAL){ + serverContentManager = ServerContentManager.createServerContentManager(true); + } else { + serverContentManager = ServerContentManager.createServerContentManager(false); + } + + // + //Init the realm + // + Realm realm = null; + switch(file.realmDescriptor.getType()){ + case RealmDescriptor.REALM_DESCRIPTOR_GRIDDED: { + realm = Globals.realmManager.createGriddedRealm(serverWorldData,serverContentManager); + } break; + case RealmDescriptor.REALM_DESCRIPTOR_PROCEDURAL: { + realm = Globals.realmManager.createRealm(); + } break; + } ServerDataCell rVal = realm.createNewCell(); - SceneFile file = FileUtils.loadObjectFromAssetPath(path, SceneFile.class); //spawn initial entities for(EntityDescriptor descriptor : file.getEntities()){ //spawn entity somehow @@ -62,9 +109,7 @@ public class SceneLoader { // } // Globals.scriptEngine.runScript(file.getInitScriptPath()); - //instruct client to load the scene - - return rVal; + //TODO: instruct client to load the scene } } diff --git a/src/main/java/electrosphere/entity/state/collidable/ServerCollidableTree.java b/src/main/java/electrosphere/entity/state/collidable/ServerCollidableTree.java index e996f9fb..5c9df4d3 100644 --- a/src/main/java/electrosphere/entity/state/collidable/ServerCollidableTree.java +++ b/src/main/java/electrosphere/entity/state/collidable/ServerCollidableTree.java @@ -69,14 +69,14 @@ public class ServerCollidableTree implements BehaviorTree { } Realm realm = Globals.realmManager.getEntityRealm(parent); //bound to world bounds - if(newPosition.x < Globals.serverWorldData.getWorldBoundMin().x){ - newPosition.x = Globals.serverWorldData.getWorldBoundMin().x; + if(newPosition.x < realm.getServerWorldData().getWorldBoundMin().x){ + newPosition.x = realm.getServerWorldData().getWorldBoundMin().x; } - if(newPosition.y < Globals.serverWorldData.getWorldBoundMin().y){ - newPosition.y = Globals.serverWorldData.getWorldBoundMin().y; + if(newPosition.y < realm.getServerWorldData().getWorldBoundMin().y){ + newPosition.y = realm.getServerWorldData().getWorldBoundMin().y; } - if(newPosition.z < Globals.serverWorldData.getWorldBoundMin().z){ - newPosition.z = Globals.serverWorldData.getWorldBoundMin().z; + if(newPosition.z < realm.getServerWorldData().getWorldBoundMin().z){ + newPosition.z = realm.getServerWorldData().getWorldBoundMin().z; } PhysicsUtils.setRigidBodyTransform(realm.getCollisionEngine(), newPosition, rotation, body); } diff --git a/src/main/java/electrosphere/game/server/structure/virtual/VirtualStructureUtils.java b/src/main/java/electrosphere/game/server/structure/virtual/VirtualStructureUtils.java index 3fcc64e5..a25093f7 100644 --- a/src/main/java/electrosphere/game/server/structure/virtual/VirtualStructureUtils.java +++ b/src/main/java/electrosphere/game/server/structure/virtual/VirtualStructureUtils.java @@ -16,8 +16,9 @@ public class VirtualStructureUtils { public static Structure placeStructureAtPoint(float posX, float posY, float posZ, String type){ - int worldX = Globals.serverWorldData.convertRealToChunkSpace(posX); - int worldY = Globals.serverWorldData.convertRealToChunkSpace(posY); + Realm realm = Globals.realmManager.getRealms().iterator().next(); + int worldX = realm.getServerWorldData().convertRealToChunkSpace(posX); + int worldY = realm.getServerWorldData().convertRealToChunkSpace(posY); Structure rVal = new Structure(worldX,worldY,posX,posY,type); Globals.macroData.addStructure(rVal); @@ -35,7 +36,6 @@ public class VirtualStructureUtils { // Globals.serverTerrainManager.deformTerrainAtLocationToValue(newWorldX, newWorldY, (int)(newLocationX), (int)(newLocationY), (float)centerHeight); // } // } - Realm realm = Globals.realmManager.getRealms().iterator().next(); // StructureUtils.serverSpawnBasicStructure(type, realm, new Vector3d(posX,(float)centerHeight + 2.4f,posY), new Quaternionf()); return rVal; } diff --git a/src/main/java/electrosphere/game/server/town/Town.java b/src/main/java/electrosphere/game/server/town/Town.java index 1e8e2baf..58ba8f5b 100644 --- a/src/main/java/electrosphere/game/server/town/Town.java +++ b/src/main/java/electrosphere/game/server/town/Town.java @@ -24,33 +24,33 @@ public class Town { final static int avgDiffThreshold = 10; public static Vector2i findValidTownLocation(){ - for(int x = 0; x < Globals.serverTerrainManager.getWorldDiscreteSize(); x++){ - for(int y = 0; y < Globals.serverTerrainManager.getWorldDiscreteSize(); y++){ - // ServerTerrainChunk chunk = Globals.serverTerrainManager.getChunk(x, y); - // float[][] macroValues = chunk.getMacroValues(); - // float sum = 0; - // int count = 0; - // for(int i = 0; i < 5; i++){ - // for(int j = 0; j < 5; j++){ - // sum = sum + macroValues[i][j]; - // count++; - // } - // } - // float average = sum / (float)count; - // if(average > 1000){ - // float diffSum = 0; - // for(int i = 0; i < 5; i++){ - // for(int j = 0; j < 5; j++){ - // diffSum = diffSum + (float)Math.abs(average - macroValues[i][j]); - // } - // } - // float averageDiff = diffSum / (float)count; - // if(averageDiff < avgDiffThreshold){ - // return new Vector2i(x,y); - // } - // } - } - } + // for(int x = 0; x < Globals.serverTerrainManager.getWorldDiscreteSize(); x++){ + // for(int y = 0; y < Globals.serverTerrainManager.getWorldDiscreteSize(); y++){ + // // ServerTerrainChunk chunk = Globals.serverTerrainManager.getChunk(x, y); + // // float[][] macroValues = chunk.getMacroValues(); + // // float sum = 0; + // // int count = 0; + // // for(int i = 0; i < 5; i++){ + // // for(int j = 0; j < 5; j++){ + // // sum = sum + macroValues[i][j]; + // // count++; + // // } + // // } + // // float average = sum / (float)count; + // // if(average > 1000){ + // // float diffSum = 0; + // // for(int i = 0; i < 5; i++){ + // // for(int j = 0; j < 5; j++){ + // // diffSum = diffSum + (float)Math.abs(average - macroValues[i][j]); + // // } + // // } + // // float averageDiff = diffSum / (float)count; + // // if(averageDiff < avgDiffThreshold){ + // // return new Vector2i(x,y); + // // } + // // } + // } + // } return null; } diff --git a/src/main/java/electrosphere/game/server/world/MacroData.java b/src/main/java/electrosphere/game/server/world/MacroData.java index d68e33e4..0d0dd7ca 100644 --- a/src/main/java/electrosphere/game/server/world/MacroData.java +++ b/src/main/java/electrosphere/game/server/world/MacroData.java @@ -84,36 +84,36 @@ public class MacroData { boolean foundPlacementLocation = false; int attempts = 0; while(!foundPlacementLocation){ - Vector2i start = new Vector2i(random.nextInt(Globals.serverTerrainManager.getWorldDiscreteSize()),random.nextInt(Globals.serverTerrainManager.getWorldDiscreteSize())); - //are we above sea level? - if(Globals.serverTerrainManager.getDiscreteValue(start.x, start.y) > 25){ //TODO: Set to actual sea level value - //is this position already occupied? - boolean match = false; - for(Vector2i known : occupiedStartingPositions){ - if(known.x == start.x && known.y == start.y){ - match = true; - break; - } - } - if(!match){ - //occupy position - occupiedStartingPositions.add(start); - foundPlacementLocation = true; - //make characters - int numCharactersToMake = 5 + random.nextInt(20); - for(int i = 0; i < numCharactersToMake; i++){ - Character character = new Character(); - CharacterUtils.addDiscretePosition(character, start.x, start.y); - CharacterUtils.addRace(character, race); - rVal.characters.add(character); - rVal.aliveCharacters.add(character); - } - } - } - attempts++; - if(attempts > MAX_PLACEMENT_ATTEMPTS){ - break; - } + // Vector2i start = new Vector2i(random.nextInt(Globals.serverTerrainManager.getWorldDiscreteSize()),random.nextInt(Globals.serverTerrainManager.getWorldDiscreteSize())); + // //are we above sea level? + // if(Globals.serverTerrainManager.getDiscreteValue(start.x, start.y) > 25){ //TODO: Set to actual sea level value + // //is this position already occupied? + // boolean match = false; + // for(Vector2i known : occupiedStartingPositions){ + // if(known.x == start.x && known.y == start.y){ + // match = true; + // break; + // } + // } + // if(!match){ + // //occupy position + // occupiedStartingPositions.add(start); + // foundPlacementLocation = true; + // //make characters + // int numCharactersToMake = 5 + random.nextInt(20); + // for(int i = 0; i < numCharactersToMake; i++){ + // Character character = new Character(); + // CharacterUtils.addDiscretePosition(character, start.x, start.y); + // CharacterUtils.addRace(character, race); + // rVal.characters.add(character); + // rVal.aliveCharacters.add(character); + // } + // } + // } + // attempts++; + // if(attempts > MAX_PLACEMENT_ATTEMPTS){ + // break; + // } } } diff --git a/src/main/java/electrosphere/game/server/world/ServerWorldData.java b/src/main/java/electrosphere/game/server/world/ServerWorldData.java index 0aaa3b8e..03bd04b4 100644 --- a/src/main/java/electrosphere/game/server/world/ServerWorldData.java +++ b/src/main/java/electrosphere/game/server/world/ServerWorldData.java @@ -1,7 +1,11 @@ package electrosphere.game.server.world; +import electrosphere.server.fluid.generation.DefaultFluidGenerator; +import electrosphere.server.fluid.manager.ServerFluidManager; +import electrosphere.server.terrain.generation.DefaultChunkGenerator; import electrosphere.server.terrain.manager.ServerTerrainChunk; import electrosphere.server.terrain.manager.ServerTerrainManager; +import electrosphere.util.FileUtils; import org.joml.Vector3d; import org.joml.Vector3f; @@ -15,6 +19,7 @@ public class ServerWorldData { public static enum WorldType { GAME_WORLD, ARENA_WORLD, + LEVEL, } WorldType type; @@ -45,34 +50,81 @@ public class ServerWorldData { int dynamicInterpolationRatio; float randomDampener; boolean isArena = false; + - public static ServerWorldData createArenaWorld(){ + //terrain data + private ServerTerrainManager serverTerrainManager; + + //fluid data + private ServerFluidManager serverFluidManager; + + + /** + * Creates a server world data object based on a discrete world size + * @param discreteWorldSize The discrete world size + * @return The server world data object + */ + public static ServerWorldData createGriddedRealmWorldData(int discreteWorldSize){ ServerWorldData rVal = new ServerWorldData(); - rVal.type = WorldType.ARENA_WORLD; + rVal.type = WorldType.LEVEL; + + //min and max real points rVal.worldMinPoint = new Vector3f(0,0,0); - rVal.worldMaxPoint = new Vector3f(200,0,200); - rVal.dynamicInterpolationRatio = 100; - rVal.worldSizeDiscrete = 2; - rVal.worldSizeDiscreteVertical = 2; - rVal.randomDampener = 0.0f; - rVal.isArena = true; + int worldDim = discreteWorldSize * ServerTerrainChunk.CHUNK_DIMENSION; + rVal.worldMaxPoint = new Vector3f(worldDim,worldDim, worldDim); + + //misc values + rVal.dynamicInterpolationRatio = 1; + rVal.worldSizeDiscrete = discreteWorldSize; + rVal.worldSizeDiscreteVertical = discreteWorldSize; + rVal.randomDampener = ServerTerrainManager.SERVER_TERRAIN_MANAGER_DAMPENER; + return rVal; } - public static ServerWorldData createGameWorld(ServerTerrainManager terrainManager){ - ServerWorldData rVal = new ServerWorldData(); - rVal.type = WorldType.GAME_WORLD; + // public static ServerWorldData createGameWorld(ServerTerrainManager terrainManager){ + // ServerWorldData rVal = new ServerWorldData(); + // rVal.type = WorldType.GAME_WORLD; - rVal.worldMinPoint = new Vector3f(0,0,0); - int worldDim = terrainManager.getWorldDiscreteSize() * ServerTerrainChunk.CHUNK_DIMENSION; - rVal.worldMaxPoint = new Vector3f(worldDim,0,worldDim); + // rVal.worldMinPoint = new Vector3f(0,0,0); + // int worldDim = terrainManager.getWorldDiscreteSize() * ServerTerrainChunk.CHUNK_DIMENSION; + // rVal.worldMaxPoint = new Vector3f(worldDim,0,worldDim); - rVal.dynamicInterpolationRatio = terrainManager.getDynamicInterpolationRatio(); - rVal.worldSizeDiscrete = terrainManager.getWorldDiscreteSize(); - rVal.worldSizeDiscreteVertical = 128; - rVal.randomDampener = terrainManager.getRandomDampener(); + // rVal.dynamicInterpolationRatio = terrainManager.getDynamicInterpolationRatio(); + // rVal.worldSizeDiscrete = terrainManager.getWorldDiscreteSize(); + // rVal.worldSizeDiscreteVertical = 128; + // rVal.randomDampener = terrainManager.getRandomDampener(); - return rVal; + // return rVal; + // } + + /** + * Loads world data from a scene or a save + * @param sceneOrSaveName The name of the scene or save + * @param isScene true if loading from a scene, false if loading from a save + * @return The server world data + */ + public static ServerWorldData loadWorldData(String sceneOrSaveName, boolean isScene){ + // + //Read world data if it exists + // + ServerWorldData serverWorldData = null; + ServerTerrainManager serverTerrainManager = null; + ServerFluidManager serverFluidManager = null; + if(isScene){ + serverWorldData = FileUtils.loadObjectFromSavePath(sceneOrSaveName, "world.json", ServerWorldData.class); + serverTerrainManager = new ServerTerrainManager(serverWorldData, 0, new DefaultChunkGenerator()); + serverTerrainManager.load(sceneOrSaveName); + serverFluidManager = new ServerFluidManager(serverWorldData, serverTerrainManager, 0, new DefaultFluidGenerator()); + } else { + //TODO: Allow loading procedurally generated terrain from disk (the chunk generator is always default currently) + serverWorldData = FileUtils.loadObjectFromSavePath(sceneOrSaveName, "world.json", ServerWorldData.class); + serverTerrainManager = new ServerTerrainManager(serverWorldData, 0, new DefaultChunkGenerator()); + serverTerrainManager.load(sceneOrSaveName); + serverFluidManager = new ServerFluidManager(serverWorldData, serverTerrainManager, 0, new DefaultFluidGenerator()); + } + serverWorldData.setManagers(serverTerrainManager, serverFluidManager); + return serverWorldData; } @@ -163,4 +215,35 @@ public class ServerWorldData { ); } + /** + * Gets the terrain manager for this world + * @return The terrain manager if it exists, null otherwise + */ + public ServerTerrainManager getServerTerrainManager(){ + return this.serverTerrainManager; + } + + /** + * Gets the fluid manager for this world + * @return The fluid manager if it exists, null otherwise + */ + public ServerFluidManager getServerFluidManager(){ + return this.serverFluidManager; + } + + /** + * Sets the chunk managers + * @param serverTerrainManager The terrain manager + * @param serverFluidManager The fluid manager + */ + public void setManagers(ServerTerrainManager serverTerrainManager, ServerFluidManager serverFluidManager){ + this.serverTerrainManager = serverTerrainManager; + this.serverFluidManager = serverFluidManager; + this.serverTerrainManager.setParent(this); + this.serverFluidManager.setParent(this); + if(this.serverTerrainManager == null || this.serverFluidManager == null){ + throw new IllegalStateException("Setting world data managers to a null manager " + this.serverTerrainManager + " " + this.serverFluidManager); + } + } + } diff --git a/src/main/java/electrosphere/logger/LoggerInterface.java b/src/main/java/electrosphere/logger/LoggerInterface.java index dd801b63..5b8ff5c5 100644 --- a/src/main/java/electrosphere/logger/LoggerInterface.java +++ b/src/main/java/electrosphere/logger/LoggerInterface.java @@ -30,7 +30,7 @@ public class LoggerInterface { loggerFileIO = new Logger(LogLevel.WARNING); loggerGameLogic = new Logger(LogLevel.WARNING); loggerRenderer = new Logger(LogLevel.WARNING); - loggerEngine = new Logger(LogLevel.WARNING); + loggerEngine = new Logger(LogLevel.INFO); loggerAuth = new Logger(LogLevel.WARNING); loggerDB = new Logger(LogLevel.WARNING); loggerAudio = new Logger(LogLevel.WARNING); diff --git a/src/main/java/electrosphere/menu/MenuGenerators.java b/src/main/java/electrosphere/menu/MenuGenerators.java index 1ea647ef..0fd428e9 100644 --- a/src/main/java/electrosphere/menu/MenuGenerators.java +++ b/src/main/java/electrosphere/menu/MenuGenerators.java @@ -5,6 +5,8 @@ import java.util.List; import electrosphere.auth.AuthenticationManager; import electrosphere.engine.Globals; import electrosphere.engine.loadingthreads.LoadingThread; +import electrosphere.engine.loadingthreads.LoadingThread.LoadingThreadType; +import electrosphere.entity.scene.SceneGenerator; import electrosphere.menu.mainmenu.MenuGeneratorsKeybind; import electrosphere.menu.mainmenu.MenuGeneratorsTitleMenu; import electrosphere.net.NetUtils; @@ -14,12 +16,9 @@ import electrosphere.renderer.ui.elements.FormElement; import electrosphere.renderer.ui.elements.Label; import electrosphere.renderer.ui.elements.TextInput; import electrosphere.renderer.ui.elementtypes.ClickableElement; -import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.events.ClickEvent; import electrosphere.server.saves.SaveUtils; -import electrosphere.server.terrain.generation.OverworldChunkGenerator; -import electrosphere.server.terrain.manager.ServerTerrainManager; /** * Generator functions for creating menus @@ -28,7 +27,7 @@ public class MenuGenerators { //Used when we're displaying loading window to make main menu invisible public static Element createEmptyMainMenu(){ - Div rVal = new Div(); + Div rVal = Div.createDiv(); return rVal; } @@ -51,9 +50,9 @@ public class MenuGenerators { //need to log client in Globals.clientUsername = "username"; Globals.clientPassword = AuthenticationManager.getHashedString("password"); - LoadingThread clientThread = new LoadingThread(LoadingThread.LOAD_CHARACTER_SERVER); + LoadingThread clientThread = new LoadingThread(LoadingThreadType.CHARACTER_SERVER); Globals.loadingThreadsList.add(clientThread); - LoadingThread serverThread = new LoadingThread(LoadingThread.LOAD_MAIN_GAME); + LoadingThread serverThread = new LoadingThread(LoadingThreadType.MAIN_GAME); Globals.loadingThreadsList.add(serverThread); Globals.RUN_CLIENT = true; Globals.RUN_SERVER = true; @@ -103,11 +102,7 @@ public class MenuGenerators { createButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ String saveName = worldNameInput.getText(); //create save dir - SaveUtils.createOrOverwriteSave(saveName); - //create and save terrain - ServerTerrainManager terrainManager = new ServerTerrainManager(2000,50,0.0f,0,new OverworldChunkGenerator()); - terrainManager.generate(); - terrainManager.save(SaveUtils.deriveSaveDirectoryPath(saveName)); + SaveUtils.createOrOverwriteSave(saveName, SceneGenerator.createProceduralSceneFile(saveName)); WindowUtils.replaceMainMenuContents(MenuGenerators.createWorldSelectMenu()); return false; }}); @@ -125,9 +120,10 @@ public class MenuGenerators { saveButton.addChild(saveLabel); rVal.addChild(saveButton); saveButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ - SaveUtils.saveWorldData(Globals.currentSave.getName()); + // SaveUtils.saveWorldData(Globals.currentSave.getName()); WindowUtils.replaceMainMenuContents(MenuGenerators.createWorldSelectMenu()); - return false; + throw new UnsupportedOperationException("Need to update to use new save flow"); + // return false; }}); //button (cancel) @@ -185,9 +181,9 @@ public class MenuGenerators { hostButton.addChild(hostLabel); rVal.addChild(hostButton); hostButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ - LoadingThread clientThread = new LoadingThread(LoadingThread.LOAD_CHARACTER_SERVER); + LoadingThread clientThread = new LoadingThread(LoadingThreadType.CHARACTER_SERVER); Globals.loadingThreadsList.add(clientThread); - LoadingThread serverThread = new LoadingThread(LoadingThread.LOAD_MAIN_GAME); + LoadingThread serverThread = new LoadingThread(LoadingThreadType.MAIN_GAME); Globals.loadingThreadsList.add(serverThread); Globals.RUN_CLIENT = true; Globals.RUN_SERVER = true; @@ -277,7 +273,7 @@ public class MenuGenerators { NetUtils.setPort(Integer.parseInt(portInput.getText())); Globals.clientUsername = usernameInput.getText(); Globals.clientPassword = AuthenticationManager.getHashedString(passwordInput.getText()); - LoadingThread clientThread = new LoadingThread(LoadingThread.LOAD_CHARACTER_SERVER); + LoadingThread clientThread = new LoadingThread(LoadingThreadType.CHARACTER_SERVER); Globals.loadingThreadsList.add(clientThread); Globals.RUN_CLIENT = true; Globals.RUN_SERVER = false; @@ -319,10 +315,9 @@ public class MenuGenerators { }}); //button to open rebind controls window - Button rebindControlsButton = Button.createButton("Controls", new ClickEventCallback() {public boolean execute(ClickEvent event) { + Button rebindControlsButton = Button.createButton("Controls", () -> { WindowUtils.replaceMainMenuContents(MenuGeneratorsKeybind.createControlsRebindMenu()); - return false; - }}); + }); rVal.addChild(rebindControlsButton); return rVal; diff --git a/src/main/java/electrosphere/menu/debug/ImGuiWindowMacros.java b/src/main/java/electrosphere/menu/debug/ImGuiWindowMacros.java index 7811df92..cc2c7a0c 100644 --- a/src/main/java/electrosphere/menu/debug/ImGuiWindowMacros.java +++ b/src/main/java/electrosphere/menu/debug/ImGuiWindowMacros.java @@ -19,6 +19,7 @@ import electrosphere.renderer.ui.imgui.ImGuiWindow; import electrosphere.renderer.ui.imgui.ImGuiLinePlot.ImGuiLinePlotDataset; import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback; import electrosphere.server.datacell.utils.EntityLookupUtils; +import electrosphere.server.fluid.manager.ServerFluidManager; import imgui.ImGui; /** @@ -234,7 +235,8 @@ public class ImGuiWindowMacros { //audio engine details ImGui.text("Fluids Debug"); if(ImGui.button("Toggle Simulation")){ - Globals.serverFluidManager.setSimulate(!Globals.serverFluidManager.getSimulate());; + ServerFluidManager fluidManager = Globals.playerManager.getPlayerRealm(Globals.clientPlayer).getServerWorldData().getServerFluidManager(); + fluidManager.setSimulate(!fluidManager.getSimulate()); } } }); diff --git a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInGame.java b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInGame.java index 212c20d5..50e3a5b2 100644 --- a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInGame.java +++ b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInGame.java @@ -46,7 +46,7 @@ public class MenuGeneratorsInGame { int height = 500; Window rVal = new Window(Globals.renderingEngine.getOpenGLState(),0,0,width,height,true); // int screenLeft = (Globals.WINDOW_WIDTH - width)/2; - Div div = new Div(); + Div div = Div.createDiv(); rVal.addChild(div); div.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){ WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN), false); @@ -122,10 +122,9 @@ public class MenuGeneratorsInGame { }}); // } - div.addChild(Button.createButton("Open Level Editor Tools", new ClickableElement.ClickEventCallback() {public boolean execute(ClickEvent event){ + div.addChild(Button.createButton("Open Level Editor Tools", () -> { WindowUtils.replaceWindow(WindowStrings.LEVEL_EDTIOR_SIDE_PANEL,MenuGeneratorsLevelEditor.createLevelEditorSidePanel()); - return false; - }})); + })); rVal.applyYoga(0,0); diff --git a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInventory.java b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInventory.java index d647b096..fb514545 100644 --- a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInventory.java +++ b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInventory.java @@ -2,8 +2,6 @@ package electrosphere.menu.ingame; import java.util.List; -import org.lwjgl.util.yoga.Yoga; - import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType; import electrosphere.controls.ControlHandler.ControlsState; import electrosphere.engine.Globals; @@ -21,6 +19,8 @@ import electrosphere.renderer.ui.elements.Label; import electrosphere.renderer.ui.elements.Window; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification; import electrosphere.renderer.ui.elementtypes.ContainerElement; import electrosphere.renderer.ui.elementtypes.DraggableElement.DragEventCallback; import electrosphere.renderer.ui.elementtypes.NavigableElement.NavigationEventCallback; @@ -35,13 +35,13 @@ public class MenuGeneratorsInventory { int height = 500; Window rVal = new Window(Globals.renderingEngine.getOpenGLState(),0,0,width,height,true); - rVal.setParentAlignItem(Yoga.YGAlignCenter); - rVal.setParentJustifyContent(Yoga.YGJustifyCenter); + rVal.setParentAlignItem(YogaAlignment.Center); + rVal.setParentJustifyContent(YogaJustification.Center); //apply yoga so that the screenspace position of the window can be calculated, that allows proper placement of the absolute elements rVal.applyYoga(0, 0); - Div div = new Div(); + Div div = Div.createDiv(); rVal.addChild(div); rVal.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){ @@ -219,7 +219,7 @@ public class MenuGeneratorsInventory { // int screenLeft = (Globals.WINDOW_WIDTH - width)/2; Window rVal = new Window(Globals.renderingEngine.getOpenGLState(),0,0,width,height,true); - Div div = new Div(); + Div div = Div.createDiv(); rVal.addChild(div); rVal.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){ @@ -404,7 +404,7 @@ public class MenuGeneratorsInventory { public static Element worldItemDropCaptureWindow(){ Window rVal = new Window(Globals.renderingEngine.getOpenGLState(),0,0,Globals.WINDOW_WIDTH,Globals.WINDOW_HEIGHT,true); - Div div = new Div(); + Div div = Div.createDiv(); div.setOnDragRelease(new DragEventCallback() {public boolean execute(DragEvent event){ if(Globals.draggedItem != null){ if(Globals.dragSourceInventory instanceof UnrelationalInventoryState){ diff --git a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsLevelEditor.java b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsLevelEditor.java index b37ca7b6..979509f0 100644 --- a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsLevelEditor.java +++ b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsLevelEditor.java @@ -4,7 +4,6 @@ import java.util.Random; import org.joml.Vector3d; import org.joml.Vector3f; -import org.lwjgl.util.yoga.Yoga; import electrosphere.engine.Globals; import electrosphere.entity.Entity; @@ -29,10 +28,11 @@ import electrosphere.renderer.ui.elements.Label; import electrosphere.renderer.ui.elements.Slider; import electrosphere.renderer.ui.elements.VirtualScrollable; import electrosphere.renderer.ui.elements.Window; -import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback; import electrosphere.renderer.ui.elementtypes.NavigableElement.NavigationEventCallback; import electrosphere.renderer.ui.elementtypes.ValueElement; -import electrosphere.renderer.ui.events.ClickEvent; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaFlexDirection; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification; import electrosphere.renderer.ui.events.NavigationEvent; import electrosphere.renderer.ui.events.ValueChangeEvent; import electrosphere.server.datacell.Realm; @@ -63,12 +63,12 @@ public class MenuGeneratorsLevelEditor { public static Window createLevelEditorSidePanel(){ //setup window mainSidePanel = new Window(Globals.renderingEngine.getOpenGLState(),0,0,SIDE_PANEL_WIDTH,Globals.WINDOW_HEIGHT,true); - mainSidePanel.setParentAlignContent(Yoga.YGAlignFlexEnd); - mainSidePanel.setParentJustifyContent(Yoga.YGJustifyFlexEnd); - mainSidePanel.setParentAlignItem(Yoga.YGAlignFlexEnd); - mainSidePanel.setAlignContent(Yoga.YGAlignFlexStart); - mainSidePanel.setAlignItems(Yoga.YGAlignFlexStart); - mainSidePanel.setJustifyContent(Yoga.YGJustifyFlexStart); + mainSidePanel.setParentAlignContent(YogaAlignment.End); + mainSidePanel.setParentJustifyContent(YogaJustification.End); + mainSidePanel.setParentAlignItem(YogaAlignment.End); + mainSidePanel.setAlignContent(YogaAlignment.Start); + mainSidePanel.setAlignItems(YogaAlignment.Start); + mainSidePanel.setJustifyContent(YogaJustification.Start); //scrollable VirtualScrollable scrollable = new VirtualScrollable(SIDE_PANEL_WIDTH, Globals.WINDOW_HEIGHT); @@ -95,37 +95,32 @@ public class MenuGeneratorsLevelEditor { scrollable.clearChildren(); //close button - scrollable.addChild(Button.createButton("Close", new ClickEventCallback() {public boolean execute(ClickEvent event){ + scrollable.addChild(Button.createButton("Close", () -> { WindowUtils.closeWindow(WindowStrings.LEVEL_EDTIOR_SIDE_PANEL); - return false; - }})); + })); //spawn creature button - scrollable.addChild(Button.createButton("Spawn Creature", new ClickEventCallback() {public boolean execute(ClickEvent event){ + scrollable.addChild(Button.createButton("Spawn Creature", () -> { fillInSpawnCreatureContent(scrollable); - return false; - }})); + })); //spawn foliage button - scrollable.addChild(Button.createButton("Spawn Foliage", new ClickEventCallback() {public boolean execute(ClickEvent event){ + scrollable.addChild(Button.createButton("Spawn Foliage", () -> { fillInSpawnFoliageContent(scrollable); - return false; - }})); + })); //spawn foliage button - scrollable.addChild(Button.createButton("Spawn Item", new ClickEventCallback() {public boolean execute(ClickEvent event){ + scrollable.addChild(Button.createButton("Spawn Item", () -> { fillInSpawnItemContent(scrollable); - return false; - }})); + })); //spawn object button - scrollable.addChild(Button.createButton("Spawn Object", new ClickEventCallback() {public boolean execute(ClickEvent event){ + scrollable.addChild(Button.createButton("Spawn Object", () -> { fillInSpawnObjectContent(scrollable); - return false; - }})); + })); //select voxel button - scrollable.addChild(Button.createButton("Select Voxel Type", new ClickEventCallback() {public boolean execute(ClickEvent event){ + scrollable.addChild(Button.createButton("Select Voxel Type", () -> { if(voxelWindowOpen){ voxelWindowOpen = false; WindowUtils.closeWindow(WindowStrings.VOXEL_TYPE_SELECTION); @@ -133,21 +128,18 @@ public class MenuGeneratorsLevelEditor { voxelWindowOpen = true; WindowUtils.replaceWindow(WindowStrings.VOXEL_TYPE_SELECTION,MenuGeneratorsTerrainEditing.createVoxelTypeSelectionPanel()); } - return false; - }})); + })); //entity tree view - scrollable.addChild(Button.createButton("View Entity Tree", new ClickEventCallback() {public boolean execute(ClickEvent event){ + scrollable.addChild(Button.createButton("View Entity Tree", () -> { fillInEntityTreeContent(scrollable); - return false; - }})); + })); //entity tree view - scrollable.addChild(Button.createButton("Atmospheric Control", new ClickEventCallback() {public boolean execute(ClickEvent event){ + scrollable.addChild(Button.createButton("Atmospheric Control", () -> { fillInAtmosphericControlContent(scrollable); - return false; - }})); + })); mainSidePanel.applyYoga(0,0); @@ -162,23 +154,21 @@ public class MenuGeneratorsLevelEditor { scrollable.clearChildren(); //back button - scrollable.addChild(Button.createButton("Back", new ClickEventCallback() {public boolean execute(ClickEvent event){ + scrollable.addChild(Button.createButton("Back", () -> { fillInDefaultContent(scrollable); - return false; - }})); + })); //button for spawning all creatures for(CreatureType data : Globals.gameConfigCurrent.getCreatureTypeLoader().getCreatures()){ //spawn creature button - scrollable.addChild(Button.createButton("Spawn " + data.getCreatureId(), new ClickEventCallback() {public boolean execute(ClickEvent event){ + scrollable.addChild(Button.createButton("Spawn " + data.getCreatureId(), () -> { LoggerInterface.loggerEngine.INFO("spawn " + data.getCreatureId() + "!"); Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera)); Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); Realm realm = Globals.realmManager.getRealms().iterator().next(); Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0).add(cursorVerticalOffset); CreatureUtils.serverSpawnBasicCreature(realm, cursorPos, data.getCreatureId(), null); - return false; - }})); + })); } mainSidePanel.applyYoga(0,0); @@ -192,23 +182,21 @@ public class MenuGeneratorsLevelEditor { scrollable.clearChildren(); //back button - scrollable.addChild(Button.createButton("Back", new ClickEventCallback() {public boolean execute(ClickEvent event){ + scrollable.addChild(Button.createButton("Back", () -> { fillInDefaultContent(scrollable); - return false; - }})); + })); //button for spawning all foliage types for(FoliageType data : Globals.gameConfigCurrent.getFoliageMap().getFoliageList()){ //spawn foliage button - scrollable.addChild(Button.createButton("Spawn " + data.getName(), new ClickEventCallback() {public boolean execute(ClickEvent event){ + scrollable.addChild(Button.createButton("Spawn " + data.getName(), () -> { LoggerInterface.loggerEngine.INFO("spawn " + data.getName() + "!"); Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera)); Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); Realm realm = Globals.realmManager.getRealms().iterator().next(); Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0).add(cursorVerticalOffset); FoliageUtils.serverSpawnTreeFoliage(realm, cursorPos, data.getName(), new Random().nextLong()); - return false; - }})); + })); } mainSidePanel.applyYoga(0,0); @@ -222,23 +210,21 @@ public class MenuGeneratorsLevelEditor { scrollable.clearChildren(); //back button - scrollable.addChild(Button.createButton("Back", new ClickEventCallback() {public boolean execute(ClickEvent event){ + scrollable.addChild(Button.createButton("Back", () -> { fillInDefaultContent(scrollable); - return false; - }})); + })); //button for spawning all foliage types for(Item item : Globals.gameConfigCurrent.getItemMap().getItems()){ //spawn foliage button - scrollable.addChild(Button.createButton("Spawn " + item.getItemId(), new ClickEventCallback() {public boolean execute(ClickEvent event){ + scrollable.addChild(Button.createButton("Spawn " + item.getItemId(), () -> { LoggerInterface.loggerEngine.INFO("spawn " + item.getItemId() + "!"); Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera)); Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); Realm realm = Globals.realmManager.getRealms().iterator().next(); Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0).add(cursorVerticalOffset); ItemUtils.serverSpawnBasicItem(realm, cursorPos, item.getItemId()); - return false; - }})); + })); } mainSidePanel.applyYoga(0,0); @@ -253,23 +239,21 @@ public class MenuGeneratorsLevelEditor { scrollable.clearChildren(); //back button - scrollable.addChild(Button.createButton("Back", new ClickEventCallback() {public boolean execute(ClickEvent event){ + scrollable.addChild(Button.createButton("Back", () -> { fillInDefaultContent(scrollable); - return false; - }})); + })); //button for spawning all foliage types for(ObjectData object : Globals.gameConfigCurrent.getObjectTypeLoader().getAllObjectTypes()){ //spawn foliage button - scrollable.addChild(Button.createButton("Spawn " + object.getObjectId(), new ClickEventCallback() {public boolean execute(ClickEvent event){ + scrollable.addChild(Button.createButton("Spawn " + object.getObjectId(), () -> { LoggerInterface.loggerEngine.INFO("spawn " + object.getObjectId() + "!"); Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera)); Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); Realm realm = Globals.realmManager.getRealms().iterator().next(); Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0).add(cursorVerticalOffset); ObjectUtils.serverSpawnBasicObject(realm, cursorPos, object.getObjectId()); - return false; - }})); + })); } mainSidePanel.applyYoga(0,0); @@ -284,10 +268,9 @@ public class MenuGeneratorsLevelEditor { scrollable.clearChildren(); //back button - scrollable.addChild(Button.createButton("Close", new ClickEventCallback() {public boolean execute(ClickEvent event){ + scrollable.addChild(Button.createButton("Close", () -> { fillInDefaultContent(scrollable); - return false; - }})); + })); //elements for the entity for(Entity entity : EntityLookupUtils.getAllEntities()){ @@ -297,8 +280,8 @@ public class MenuGeneratorsLevelEditor { ObjectUtils.isObject(entity) || FoliageUtils.isFoliage(entity) ){ - Div div = new Div(); - div.setFlexDirection(Yoga.YGFlexDirectionRow); + Div div = Div.createDiv(); + div.setFlexDirection(YogaFlexDirection.Row); div.setMaxHeight(30); div.setMarginBottom(5); div.setMarginLeft(5); @@ -306,11 +289,10 @@ public class MenuGeneratorsLevelEditor { div.setMarginTop(5); //delete button - Button deleteButton = Button.createButton("X", new ClickEventCallback() {public boolean execute(ClickEvent event){ + Button deleteButton = Button.createButton("X", () -> { LoggerInterface.loggerEngine.INFO("Delete " + entity.getId()); ServerEntityUtils.destroyEntity(entity); - return false; - }}); + }); deleteButton.setMarginRight(5); deleteButton.setMarginLeft(5); div.addChild(deleteButton); @@ -356,16 +338,15 @@ public class MenuGeneratorsLevelEditor { scrollable.clearChildren(); //back button - scrollable.addChild(Button.createButton("Close", new ClickEventCallback() {public boolean execute(ClickEvent event){ + scrollable.addChild(Button.createButton("Close", () -> { fillInDefaultContent(scrollable); - return false; - }})); + })); //global light direction scrollable.addChild(Label.createLabel("Global Light Direction")); - Div xDiv = new Div(); + Div xDiv = Div.createDiv(); xDiv.setMaxHeight(50); - xDiv.setFlexDirection(Yoga.YGFlexDirectionRow); + xDiv.setFlexDirection(YogaFlexDirection.Row); xDiv.addChild(Label.createLabel("X: ")); xDiv.addChild(Slider.createSlider(new ValueElement.ValueChangeEventCallback() {public void execute(ValueChangeEvent event) { LightManager lightManager = Globals.renderingEngine.getLightManager(); @@ -376,9 +357,9 @@ public class MenuGeneratorsLevelEditor { }})); scrollable.addChild(xDiv); - Div yDiv = new Div(); + Div yDiv = Div.createDiv(); yDiv.setMaxHeight(50); - yDiv.setFlexDirection(Yoga.YGFlexDirectionRow); + yDiv.setFlexDirection(YogaFlexDirection.Row); yDiv.addChild(Label.createLabel("Y: ")); yDiv.addChild(Slider.createSlider(new ValueElement.ValueChangeEventCallback() {public void execute(ValueChangeEvent event) { LightManager lightManager = Globals.renderingEngine.getLightManager(); @@ -389,9 +370,9 @@ public class MenuGeneratorsLevelEditor { }})); scrollable.addChild(yDiv); - Div zDiv = new Div(); + Div zDiv = Div.createDiv(); zDiv.setMaxHeight(50); - zDiv.setFlexDirection(Yoga.YGFlexDirectionRow); + zDiv.setFlexDirection(YogaFlexDirection.Row); zDiv.addChild(Label.createLabel("Z: ")); zDiv.addChild(Slider.createSlider(new ValueElement.ValueChangeEventCallback() {public void execute(ValueChangeEvent event) { LightManager lightManager = Globals.renderingEngine.getLightManager(); diff --git a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsTerrainEditing.java b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsTerrainEditing.java index 0e09d99b..4b515332 100644 --- a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsTerrainEditing.java +++ b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsTerrainEditing.java @@ -2,8 +2,6 @@ package electrosphere.menu.ingame; import java.util.List; -import org.lwjgl.util.yoga.Yoga; - import electrosphere.engine.Globals; import electrosphere.game.data.voxel.VoxelData; import electrosphere.game.data.voxel.VoxelType; @@ -16,6 +14,9 @@ import electrosphere.renderer.ui.elements.TextInput; import electrosphere.renderer.ui.elements.VirtualScrollable; import electrosphere.renderer.ui.elements.Window; import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaFlexDirection; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification; import electrosphere.renderer.ui.elementtypes.KeyEventElement.KeyboardEventCallback; import electrosphere.renderer.ui.elementtypes.NavigableElement.NavigationEventCallback; import electrosphere.renderer.ui.events.ClickEvent; @@ -55,25 +56,25 @@ public class MenuGeneratorsTerrainEditing { public static Window createVoxelTypeSelectionPanel(){ //setup window rVal = new Window(Globals.renderingEngine.getOpenGLState(),0,0,WINDOW_WIDTH,WINDOW_HEIGHT,true); - rVal.setParentAlignContent(Yoga.YGAlignCenter); - rVal.setParentJustifyContent(Yoga.YGJustifyCenter); - rVal.setParentAlignItem(Yoga.YGAlignCenter); - rVal.setAlignContent(Yoga.YGAlignCenter); - rVal.setAlignItems(Yoga.YGAlignCenter); - rVal.setJustifyContent(Yoga.YGJustifyCenter); - rVal.setFlexDirection(Yoga.YGFlexDirectionColumn); + rVal.setParentAlignContent(YogaAlignment.Center); + rVal.setParentJustifyContent(YogaJustification.Center); + rVal.setParentAlignItem(YogaAlignment.Center); + rVal.setAlignContent(YogaAlignment.Center); + rVal.setAlignItems(YogaAlignment.Center); + rVal.setJustifyContent(YogaJustification.Center); + rVal.setFlexDirection(YogaFlexDirection.Column); //scrollable that contains all the voxel types VirtualScrollable scrollable = new VirtualScrollable(VOXEL_SCROLLABLE_WIDTH, VOXEL_SCROLLABLE_HEIGHT); - scrollable.setFlexDirection(Yoga.YGFlexDirectionRow); - scrollable.setAlignItems(Yoga.YGAlignFlexStart); + scrollable.setFlexDirection(YogaFlexDirection.Row); + scrollable.setAlignItems(YogaAlignment.Start); rVal.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){ WindowUtils.closeWindow(WindowStrings.LEVEL_EDTIOR_SIDE_PANEL); return false; }}); //search input - TextInput searchInput = TextInput.createTextInput(1.0f); + TextInput searchInput = TextInput.createTextInput(); searchInput.setWidth(TEXT_INPUT_WIDTH); searchInput.setMinWidth(TEXT_INPUT_WIDTH); searchInput.setMinHeight(20); @@ -109,7 +110,7 @@ public class MenuGeneratorsTerrainEditing { //generate voxel buttons for(VoxelType type : matchingVoxels){ Button newButton = new Button(); - newButton.setAlignItems(Yoga.YGAlignCenter); + newButton.setAlignItems(YogaAlignment.Center); //dimensions newButton.setWidth(VOXEL_BUTTON_WIDTH); newButton.setMinWidth(VOXEL_BUTTON_WIDTH); diff --git a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsDemo.java b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsDemo.java index 22dbb71d..f07ae41f 100644 --- a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsDemo.java +++ b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsDemo.java @@ -1,9 +1,9 @@ package electrosphere.menu.mainmenu; -import org.lwjgl.util.yoga.Yoga; - import electrosphere.renderer.ui.elements.FormElement; import electrosphere.renderer.ui.elements.Label; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification; import electrosphere.renderer.ui.elementtypes.Element; /** @@ -18,10 +18,10 @@ public class MenuGeneratorsDemo { public static Element createTitleMenu(){ FormElement rVal = new FormElement(); //top-bottom - rVal.setJustifyContent(Yoga.YGJustifyCenter); + rVal.setJustifyContent(YogaJustification.Center); //left-right - rVal.setAlignItems(Yoga.YGAlignCenter); - rVal.setAlignContent(Yoga.YGAlignFlexStart); + rVal.setAlignItems(YogaAlignment.Center); + rVal.setAlignContent(YogaAlignment.Start); //label (title) Label titleLabel = new Label(1.0f); diff --git a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsKeybind.java b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsKeybind.java index 823d088b..0301702d 100644 --- a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsKeybind.java +++ b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsKeybind.java @@ -1,7 +1,5 @@ package electrosphere.menu.mainmenu; -import org.lwjgl.util.yoga.Yoga; - import electrosphere.controls.Control; import electrosphere.engine.Globals; import electrosphere.menu.WindowUtils; @@ -10,10 +8,9 @@ import electrosphere.renderer.ui.elements.Div; import electrosphere.renderer.ui.elements.FormElement; import electrosphere.renderer.ui.elements.Label; import electrosphere.renderer.ui.elements.VirtualScrollable; -import electrosphere.renderer.ui.elementtypes.ClickableElement; -import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaFlexDirection; import electrosphere.renderer.ui.elementtypes.Element; -import electrosphere.renderer.ui.events.ClickEvent; /** * A menu for rebinding controls @@ -29,28 +26,25 @@ public class MenuGeneratorsKeybind { */ public static Element createControlsRebindMenu(){ FormElement rVal = new FormElement(); - rVal.setAlignItems(Yoga.YGAlignCenter); + rVal.setAlignItems(YogaAlignment.Center); //header buttons - Div headerButtons = new Div(); - headerButtons.setFlexDirection(Yoga.YGFlexDirectionRow); - Button backButton = Button.createButton("Back", new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ + Div headerButtons = Div.createDiv(); + headerButtons.setFlexDirection(YogaFlexDirection.Row); + Button backButton = Button.createButton("Back", () -> { WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu()); - return false; - }}); + }); headerButtons.addChild(backButton); - Button saveButton = Button.createButton("Save", new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ + Button saveButton = Button.createButton("Save", () -> { WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu()); - return false; - }}); + }); saveButton.setVisible(false); headerButtons.addChild(saveButton); - Button cancelButton = Button.createButton("Cancel", new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ + Button cancelButton = Button.createButton("Cancel", () -> { WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu()); - return false; - }}); + }); cancelButton.setVisible(false); headerButtons.addChild(cancelButton); @@ -60,20 +54,19 @@ public class MenuGeneratorsKeybind { // //Generate keybind controls VirtualScrollable virtualScrollable = new VirtualScrollable(300, 700); - virtualScrollable.setAlignItems(Yoga.YGAlignFlexStart); + virtualScrollable.setAlignItems(YogaAlignment.Start); //add a ton of children for(Control control : Globals.controlHandler.getMainControlsList()){ if(control.isRebindable()){ - Div rebindItem = new Div(); - rebindItem.setFlexDirection(Yoga.YGFlexDirectionRow); + Div rebindItem = Div.createDiv(); + rebindItem.setFlexDirection(YogaFlexDirection.Row); Label controlNameLabel = Label.createLabel(control.getName()); rebindItem.addChild(controlNameLabel); - Button testButton = Button.createButton(control.getKeyValue() + "", new ClickEventCallback() {public boolean execute(ClickEvent event) { + Button testButton = Button.createButton(control.getKeyValue() + "", () -> { System.out.println("Start rebind"); - return false; - }}); + }); rebindItem.addChild(testButton); virtualScrollable.addChild(rebindItem); diff --git a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsLevelEditor.java b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsLevelEditor.java index 4710fc85..097c69e3 100644 --- a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsLevelEditor.java +++ b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsLevelEditor.java @@ -2,19 +2,21 @@ package electrosphere.menu.mainmenu; import java.util.List; -import org.lwjgl.util.yoga.Yoga; - import electrosphere.engine.Globals; import electrosphere.engine.loadingthreads.LoadingThread; +import electrosphere.engine.loadingthreads.LoadingThread.LoadingThreadType; +import electrosphere.entity.scene.SceneFile; import electrosphere.menu.WindowUtils; import electrosphere.renderer.ui.elements.Button; import electrosphere.renderer.ui.elements.Div; import electrosphere.renderer.ui.elements.FormElement; import electrosphere.renderer.ui.elements.Label; -import electrosphere.renderer.ui.elements.TextInput; -import electrosphere.renderer.ui.elementtypes.ClickableElement; import electrosphere.renderer.ui.elementtypes.Element; -import electrosphere.renderer.ui.events.ClickEvent; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification; +import electrosphere.renderer.ui.events.ValueChangeEvent; +import electrosphere.renderer.ui.macros.InputMacros; +import electrosphere.server.datacell.GriddedDataCellManager; import electrosphere.server.saves.SaveUtils; /** @@ -22,84 +24,84 @@ import electrosphere.server.saves.SaveUtils; */ public class MenuGeneratorsLevelEditor { + /** + * The default grid size when creating a level + */ + static final int DEFAULT_GRID_SIZE = 2; + /** * Creates the top level menu for the level editor * @return The actual element containing the menu */ public static Element createLevelEditorTopMenu(){ FormElement rVal = new FormElement(); + //top-bottom + rVal.setJustifyContent(YogaJustification.Start); + //left-right + rVal.setAlignItems(YogaAlignment.Center); + rVal.setAlignContent(YogaAlignment.Start); - //label (address) - Label usernameLabel = new Label(1.0f); - usernameLabel.setText("Select Level"); - rVal.addChild(usernameLabel); - //button (back) - { - Button backButton = new Button(); - Label backLabel = new Label(1.0f); - backLabel.setText("Back"); - backButton.addChild(backLabel); - rVal.addChild(backButton); - backButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ + // + //title + // + Div titleRow = Div.createRow( + Label.createLabel("Select Level"), + Button.createButton("Back", () -> { WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu()); - return false; - }}); - } + }) + ); + titleRow.setMarginTop(30); + titleRow.setMarginBottom(30); + rVal.addChild(titleRow); + + // //button (create level) - { - Button createLevelButton = new Button(); - Label createLevelLabel = new Label(1.0f); - createLevelLabel.setText("Create Level"); - createLevelButton.addChild(createLevelLabel); - rVal.addChild(createLevelButton); - createLevelButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ - //go to create level flow - WindowUtils.replaceMainMenuContents(MenuGeneratorsLevelEditor.createLevelEditorCreationMenu()); - return false; - }}); - } + // + Button createLevelButton = Button.createButton("Create Level", () -> { + //go to create level flow + WindowUtils.replaceMainMenuContents(MenuGeneratorsLevelEditor.createLevelEditorCreationMenu()); + }); + createLevelButton.setMarginBottom(30); + rVal.addChild(createLevelButton); + + // //the buttons to load existing levels + // + Div existingLevelColumn = Div.createCol(); + existingLevelColumn.setAlignContent(YogaAlignment.Start); + rVal.addChild(existingLevelColumn); + List saveNames = SaveUtils.getSaves(); for(String saveName : saveNames){ - //containing div - Div div = new Div(); - div.setFlexDirection(Yoga.YGFlexDirectionRow); - div.setMaxHeight(30); //delete level button - Button deleteButton = new Button(); - Label deleteLabel = new Label(1.0f); - deleteLabel.setText(" X "); - deleteButton.addChild(deleteLabel); - deleteButton.setMarginRight(10); - deleteButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ + Button deleteButton = Button.createButton(" X ", () -> { SaveUtils.deleteSave(saveName); WindowUtils.replaceMainMenuContents(MenuGeneratorsLevelEditor.createLevelEditorTopMenu()); - return false; - }}); - div.addChild(deleteButton); + }); + deleteButton.setMarginRight(10); - //button (launch level) - Button launchButton = new Button(); - Label launchLabel = new Label(1.0f); - launchLabel.setText(saveName); - launchButton.addChild(launchLabel); - launchButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ + //button (launch level editor) + Button launchButton = Button.createButton(saveName, () -> { //launch level - LoadingThread loadingThread = new LoadingThread(LoadingThread.LOAD_LEVEL, saveName); + LoadingThread loadingThread = new LoadingThread(LoadingThreadType.LEVEL, saveName); Globals.loadingThreadsList.add(loadingThread); Globals.RUN_CLIENT = true; Globals.RUN_SERVER = true; loadingThread.start(); - return false; - }}); - div.addChild(launchButton); + }); - rVal.addChild(div); + //create row + Div row = Div.createRow( + deleteButton, + launchButton + ); + row.setMaxHeight(30); + existingLevelColumn.addChild(row); } return rVal; @@ -111,34 +113,42 @@ public class MenuGeneratorsLevelEditor { * @return The element containing the level creation menu */ public static Element createLevelEditorCreationMenu(){ + + //values to creat the level with + LevelDescription inFlightLevel = new LevelDescription(); + SceneFile sceneFile = SceneFile.createSceneFile(); + inFlightLevel.setSceneFile(sceneFile); + + + // + //Top level element + // FormElement rVal = new FormElement(); - int screenTop = 150; - - //label (address) - Label usernameLabel = new Label(1.0f); - usernameLabel.setText("Create Level"); - rVal.addChild(usernameLabel); + //top-bottom + rVal.setJustifyContent(YogaJustification.Start); + //left-right + rVal.setAlignItems(YogaAlignment.Center); + rVal.setAlignContent(YogaAlignment.Start); - //button (back) - { - Button backButton = new Button(); - Label backLabel = new Label(1.0f); - backLabel.setText("Back"); - backButton.addChild(backLabel); - rVal.addChild(backButton); - backButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ + // + //Title + // + Div titleRow = Div.createRow( + Label.createLabel("Create Level"), + Button.createButton("Back", () -> { WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu()); - return false; - }}); - } + }) + ); + titleRow.setMarginTop(30); + titleRow.setMarginBottom(30); + rVal.addChild(titleRow); - //label for text input for level name - { - Label levelNameLabel = new Label(1.0f); - levelNameLabel.setText("Level Name:"); - rVal.addChild(levelNameLabel); - } + + + // + //Level name input + // //generate default level name List saveNames = SaveUtils.getSaves(); int i = 0; @@ -147,32 +157,95 @@ public class MenuGeneratorsLevelEditor { i++; defaultSaveName = "defaultLevel_" + i; } + inFlightLevel.setName(defaultSaveName); + //input for the name of the save + Div levelNameInput = InputMacros.createTextInput("Level Name:", defaultSaveName, (ValueChangeEvent event) -> { + inFlightLevel.setName(event.getAsString()); + }); + levelNameInput.setMaxWidth(400); + levelNameInput.setMarginBottom(30); + rVal.addChild(levelNameInput); + - //get level name - TextInput usernameInput = new TextInput(100,screenTop + 300,1.0f); - usernameInput.setText(defaultSaveName); - rVal.addChild(usernameInput); - - //button (create level) + // + //Gridded realm controls + // + Div griddedRealmControls = Div.createCol(); { - Button createLevelButton = new Button(); - Label createLevelLabel = new Label(1.0f); - createLevelLabel.setText("Create Level"); - createLevelButton.addChild(createLevelLabel); - rVal.addChild(createLevelButton); - createLevelButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ - //launch level editor - LoadingThread loadingThread = new LoadingThread(LoadingThread.LOAD_LEVEL_EDITOR, usernameInput.getText()); - Globals.loadingThreadsList.add(loadingThread); - Globals.RUN_CLIENT = true; - Globals.RUN_SERVER = true; - loadingThread.start(); - return false; - }}); + griddedRealmControls.addChild( + InputMacros.createSliderInput("Realm Size", (ValueChangeEvent event) -> { + float value = event.getAsFloat() * GriddedDataCellManager.MAX_GRID_SIZE; + sceneFile.getRealmDescriptor().setGriddedRealmSize((int)value); + }, DEFAULT_GRID_SIZE / (float)GriddedDataCellManager.MAX_GRID_SIZE) + ); + sceneFile.getRealmDescriptor().setGriddedRealmSize(DEFAULT_GRID_SIZE); } + rVal.addChild(griddedRealmControls); + + + + // + //Create level button + // + rVal.addChild(Button.createButton("Create Level", () -> { + //launch level editor + LoadingThread loadingThread = new LoadingThread(LoadingThreadType.LEVEL_EDITOR, inFlightLevel); + Globals.loadingThreadsList.add(loadingThread); + loadingThread.start(); + })); return rVal; } + + + /** + * A level that is currently having its parameters defined + */ + public static class LevelDescription { + + /** + * The name of the new level + */ + String name; + + /** + * The scene file + */ + SceneFile sceneFile; + + /** + * Sets the name of the level + * @param name The name + */ + public void setName(String name){ + this.name = name; + } + + /** + * Sets the scene file + * @param sceneFile The scene file + */ + public void setSceneFile(SceneFile sceneFile){ + this.sceneFile = sceneFile; + } + + /** + * Gets the name of the level + * @return The level name + */ + public String getName(){ + return name; + } + + /** + * Gets the scene file + * @return The scene file + */ + public SceneFile getSceneFile(){ + return sceneFile; + } + + } } diff --git a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsMultiplayer.java b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsMultiplayer.java index fd09dbc4..98975de0 100644 --- a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsMultiplayer.java +++ b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsMultiplayer.java @@ -4,7 +4,6 @@ import java.util.LinkedList; import java.util.List; import org.joml.Vector3f; -import org.lwjgl.util.yoga.Yoga; import electrosphere.engine.Globals; import electrosphere.entity.types.camera.CameraEntityUtils; @@ -28,6 +27,7 @@ import electrosphere.renderer.ui.elements.ScrollableContainer; import electrosphere.renderer.ui.elements.Slider; import electrosphere.renderer.ui.elements.StringCarousel; import electrosphere.renderer.ui.elementtypes.ClickableElement; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaFlexDirection; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.elementtypes.ValueElement.ValueChangeEventCallback; import electrosphere.renderer.ui.events.ClickEvent; @@ -203,8 +203,8 @@ public class MenuGeneratorsMultiplayer { int width = 1800; int height = verticalPosition + 300; - Div rVal = new Div(); - rVal.setFlexDirection(Yoga.YGFlexDirectionRow); + Div rVal = Div.createDiv(); + rVal.setFlexDirection(YogaFlexDirection.Row); ScrollableContainer scrollable = new ScrollableContainer(Globals.renderingEngine.getOpenGLState(), 0, 0, width, height); for(Element newControl : controlsToAdd){ diff --git a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsTitleMenu.java b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsTitleMenu.java index c154e8d6..6873587d 100644 --- a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsTitleMenu.java +++ b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsTitleMenu.java @@ -1,26 +1,36 @@ package electrosphere.menu.mainmenu; -import org.lwjgl.util.yoga.Yoga; - import electrosphere.engine.Globals; import electrosphere.engine.loadingthreads.LoadingThread; +import electrosphere.engine.loadingthreads.LoadingThread.LoadingThreadType; import electrosphere.menu.MenuGenerators; import electrosphere.menu.WindowUtils; import electrosphere.renderer.ui.elements.Button; -import electrosphere.renderer.ui.elements.FormElement; +import electrosphere.renderer.ui.elements.Div; import electrosphere.renderer.ui.elements.Label; import electrosphere.renderer.ui.elementtypes.ClickableElement; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.events.ClickEvent; +/** + * Menu generators for the title menu + */ public class MenuGeneratorsTitleMenu { + + /** + * Creates the main title menu + * @return The menu element + */ public static Element createTitleMenu(){ - FormElement rVal = new FormElement(); + Div rVal = Div.createDiv(); //top-bottom - rVal.setJustifyContent(Yoga.YGJustifyCenter); + rVal.setJustifyContent(YogaJustification.Center); //left-right - rVal.setAlignItems(Yoga.YGAlignCenter); - rVal.setAlignContent(Yoga.YGAlignFlexStart); + rVal.setAlignItems(YogaAlignment.Center); + rVal.setAlignContent(YogaAlignment.Center); + rVal.setFlexGrow(1.0f); //label (title) Label titleLabel = new Label(1.0f); @@ -78,7 +88,7 @@ public class MenuGeneratorsTitleMenu { uiDebugSPQuickstartButton.addChild(uiDebugSPQuickstartLabel); rVal.addChild(uiDebugSPQuickstartButton); uiDebugSPQuickstartButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ - LoadingThread loadingThread = new LoadingThread(LoadingThread.LOAD_DEBUG_RANDOM_SP_WORLD); + LoadingThread loadingThread = new LoadingThread(LoadingThreadType.DEBUG_RANDOM_SP_WORLD); Globals.loadingThreadsList.add(loadingThread); Globals.RUN_CLIENT = true; Globals.RUN_SERVER = true; diff --git a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsUITesting.java b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsUITesting.java index 96c6d0f0..f6a7ac9b 100644 --- a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsUITesting.java +++ b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsUITesting.java @@ -12,10 +12,8 @@ import electrosphere.renderer.ui.elements.FormElement; import electrosphere.renderer.ui.elements.Label; import electrosphere.renderer.ui.elements.Slider; import electrosphere.renderer.ui.elements.VirtualScrollable; -import electrosphere.renderer.ui.elementtypes.ClickableElement; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.elementtypes.ValueElement; -import electrosphere.renderer.ui.events.ClickEvent; import electrosphere.renderer.ui.events.ValueChangeEvent; /** @@ -31,10 +29,9 @@ public class MenuGeneratorsUITesting { FormElement rVal = new FormElement(); //button (back) - Button backButton = Button.createButton("Back", new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ + Button backButton = Button.createButton("Back", () -> { WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu()); - return false; - }}); + }); rVal.addChild(backButton); ActorPanel actorPanel = new ActorPanel(Globals.renderingEngine.getOpenGLState(), 500, 100, 500, 500, ActorUtils.createActorFromModelPath("Models/deer1.fbx")); diff --git a/src/main/java/electrosphere/menu/tutorial/TutorialMenus.java b/src/main/java/electrosphere/menu/tutorial/TutorialMenus.java index 82c97d78..80c69968 100644 --- a/src/main/java/electrosphere/menu/tutorial/TutorialMenus.java +++ b/src/main/java/electrosphere/menu/tutorial/TutorialMenus.java @@ -1,7 +1,5 @@ package electrosphere.menu.tutorial; -import org.lwjgl.util.yoga.Yoga; - import electrosphere.engine.Globals; import electrosphere.game.data.tutorial.TutorialHint; import electrosphere.menu.WindowStrings; @@ -9,8 +7,9 @@ import electrosphere.menu.WindowUtils; import electrosphere.renderer.ui.elements.Button; import electrosphere.renderer.ui.elements.Label; import electrosphere.renderer.ui.elements.Window; -import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback; -import electrosphere.renderer.ui.events.ClickEvent; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaFlexDirection; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification; /** * Generates in game tutorial windows @@ -30,9 +29,9 @@ public class TutorialMenus { } else { //create the window windowEl = new Window(Globals.renderingEngine.getOpenGLState(),50,50,500,500,true); - windowEl.setParentAlignContent(Yoga.YGAlignCenter); - windowEl.setParentJustifyContent(Yoga.YGJustifyCenter); - windowEl.setFlexDirection(Yoga.YGFlexDirectionColumn); + windowEl.setParentAlignContent(YogaAlignment.Center); + windowEl.setParentJustifyContent(YogaJustification.Center); + windowEl.setFlexDirection(YogaFlexDirection.Column); Globals.elementManager.registerWindow(WindowStrings.TUTORIAL_POPUP, windowEl); } @@ -42,12 +41,8 @@ public class TutorialMenus { //create tutorial elements windowEl.addChild(Label.createLabel(hint.getTitleString())); windowEl.addChild(Label.createLabel(hint.getDescriptionString())); - windowEl.addChild(Button.createButton("Close", new ClickEventCallback() { - @Override - public boolean execute(ClickEvent event) { - WindowUtils.recursiveSetVisible(windowEl, true); - return false; - } + windowEl.addChild(Button.createButton("Close", () -> { + WindowUtils.recursiveSetVisible(windowEl, true); })); //show the window diff --git a/src/main/java/electrosphere/net/client/protocol/CharacterProtocol.java b/src/main/java/electrosphere/net/client/protocol/CharacterProtocol.java index 056425bf..d9756e73 100644 --- a/src/main/java/electrosphere/net/client/protocol/CharacterProtocol.java +++ b/src/main/java/electrosphere/net/client/protocol/CharacterProtocol.java @@ -2,6 +2,7 @@ package electrosphere.net.client.protocol; import electrosphere.engine.Globals; import electrosphere.engine.loadingthreads.LoadingThread; +import electrosphere.engine.loadingthreads.LoadingThread.LoadingThreadType; import electrosphere.net.parser.net.message.CharacterMessage; import electrosphere.net.parser.net.message.TerrainMessage; @@ -13,7 +14,7 @@ public class CharacterProtocol { //trigger request to spawn character Globals.clientConnection.queueOutgoingMessage(CharacterMessage.constructRequestSpawnCharacterMessage()); Globals.clientConnection.queueOutgoingMessage(TerrainMessage.constructRequestMetadataMessage()); - LoadingThread clientThread = new LoadingThread(LoadingThread.LOAD_CLIENT_WORLD); + LoadingThread clientThread = new LoadingThread(LoadingThreadType.CLIENT_WORLD); Globals.loadingThreadsList.add(clientThread); clientThread.start(); break; diff --git a/src/main/java/electrosphere/net/server/ServerConnectionHandler.java b/src/main/java/electrosphere/net/server/ServerConnectionHandler.java index 1a6d3087..1c10eca9 100644 --- a/src/main/java/electrosphere/net/server/ServerConnectionHandler.java +++ b/src/main/java/electrosphere/net/server/ServerConnectionHandler.java @@ -281,6 +281,14 @@ public class ServerConnectionHandler implements Runnable { return playerEntityID; } + /** + * Gets the player associated with this connection + * @return The player object + */ + public Player getPlayer(){ + return Globals.playerManager.getPlayerFromId(playerID); + } + public String getIPAddress(){ if(local){ return "127.0.0.1"; diff --git a/src/main/java/electrosphere/net/server/player/Player.java b/src/main/java/electrosphere/net/server/player/Player.java index 3e92ff9e..1b0efdcc 100644 --- a/src/main/java/electrosphere/net/server/player/Player.java +++ b/src/main/java/electrosphere/net/server/player/Player.java @@ -10,8 +10,7 @@ import java.util.concurrent.Semaphore; import org.joml.Vector3i; /** - * - * @author satellite + * A client logged into the server */ public class Player { diff --git a/src/main/java/electrosphere/net/server/player/PlayerManager.java b/src/main/java/electrosphere/net/server/player/PlayerManager.java index e80b188b..89258bca 100644 --- a/src/main/java/electrosphere/net/server/player/PlayerManager.java +++ b/src/main/java/electrosphere/net/server/player/PlayerManager.java @@ -5,6 +5,10 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import electrosphere.engine.Globals; +import electrosphere.entity.Entity; +import electrosphere.server.datacell.Realm; + /** * Server player manager */ @@ -27,5 +31,18 @@ public class PlayerManager { public List getPlayers(){ return new LinkedList(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); + } } diff --git a/src/main/java/electrosphere/net/server/protocol/CharacterProtocol.java b/src/main/java/electrosphere/net/server/protocol/CharacterProtocol.java index 5bfc7d57..4e255f9c 100644 --- a/src/main/java/electrosphere/net/server/protocol/CharacterProtocol.java +++ b/src/main/java/electrosphere/net/server/protocol/CharacterProtocol.java @@ -7,6 +7,7 @@ import electrosphere.net.parser.net.message.PlayerMessage; import electrosphere.net.parser.net.message.TerrainMessage; import electrosphere.net.server.ServerConnectionHandler; import electrosphere.server.character.PlayerCharacterCreation; +import electrosphere.server.datacell.Realm; import electrosphere.util.Utilities; public class CharacterProtocol { @@ -62,12 +63,13 @@ public class CharacterProtocol { */ static void spawnEntityForClient(ServerConnectionHandler connectionHandler){ PlayerCharacterCreation.spawnPlayerCharacter(connectionHandler); + Realm realm = Globals.playerManager.getPlayerRealm(connectionHandler.getPlayer()); //set client initial discrete position connectionHandler.addMessagetoOutgoingQueue( PlayerMessage.constructSetInitialDiscretePositionMessage( - Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.x), - Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.y), - Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.z) + realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.x), + realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.y), + realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.z) ) ); //send spawn point diff --git a/src/main/java/electrosphere/net/server/protocol/TerrainProtocol.java b/src/main/java/electrosphere/net/server/protocol/TerrainProtocol.java index efd5b45f..4c5b3392 100644 --- a/src/main/java/electrosphere/net/server/protocol/TerrainProtocol.java +++ b/src/main/java/electrosphere/net/server/protocol/TerrainProtocol.java @@ -113,8 +113,8 @@ public class TerrainProtocol { */ // System.out.println("Received request for chunk " + message.getworldX() + " " + message.getworldY()); - - ServerTerrainChunk chunk = Globals.serverTerrainManager.getChunk(worldX, worldY, worldZ); + Realm realm = Globals.playerManager.getPlayerRealm(connectionHandler.getPlayer()); + ServerTerrainChunk chunk = realm.getServerWorldData().getServerTerrainManager().getChunk(worldX, worldY, worldZ); // float[][] macroValues = chunk.getMacroValues();//Globals.serverTerrainManager.getRad5MacroValues(message.getworldX(), message.getworldY()); @@ -243,10 +243,11 @@ public class TerrainProtocol { * @param worldZ the world z */ static void sendWorldFluidSubChunk(ServerConnectionHandler connectionHandler, int worldX, int worldY, int worldZ){ + Realm realm = Globals.playerManager.getPlayerRealm(connectionHandler.getPlayer()); // System.out.println("Received request for chunk " + message.getworldX() + " " + message.getworldY()); - ServerFluidChunk chunk = Globals.serverFluidManager.getChunk(worldX, worldY, worldZ); + ServerFluidChunk chunk = realm.getServerWorldData().getServerFluidManager().getChunk(worldX, worldY, worldZ); ByteBuffer buffer = constructFluidByteBuffer(chunk); @@ -260,16 +261,17 @@ public class TerrainProtocol { * @param connectionHandler The connection handler */ static void sendWorldMetadata(ServerConnectionHandler connectionHandler){ + Realm realm = Globals.playerManager.getPlayerRealm(connectionHandler.getPlayer()); //world metadata connectionHandler.addMessagetoOutgoingQueue( TerrainMessage.constructResponseMetadataMessage( - Globals.serverWorldData.getWorldSizeDiscrete(), - Globals.serverWorldData.getDynamicInterpolationRatio(), - Globals.serverWorldData.getRandomDampener(), - (int)Globals.serverWorldData.getWorldBoundMin().x, - (int)Globals.serverWorldData.getWorldBoundMin().z, - (int)Globals.serverWorldData.getWorldBoundMax().x, - (int)Globals.serverWorldData.getWorldBoundMax().z + realm.getServerWorldData().getWorldSizeDiscrete(), + realm.getServerWorldData().getDynamicInterpolationRatio(), + realm.getServerWorldData().getRandomDampener(), + (int)realm.getServerWorldData().getWorldBoundMin().x, + (int)realm.getServerWorldData().getWorldBoundMin().z, + (int)realm.getServerWorldData().getWorldBoundMax().x, + (int)realm.getServerWorldData().getWorldBoundMax().z ) ); } diff --git a/src/main/java/electrosphere/renderer/ui/elements/Button.java b/src/main/java/electrosphere/renderer/ui/elements/Button.java index a471c653..9c9e9116 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Button.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Button.java @@ -58,6 +58,24 @@ public class Button extends StandardContainerElement implements DrawableElement, return rVal; } + /** + * Creates a button that fires a callback when clicked + * @param text The text for the button label + * @param callback The callback + * @return The button + */ + public static Button createButton(String text, Runnable callback){ + Button rVal = new Button(); + Label rValLabel = new Label(1.0f); + rValLabel.setText(text); + rVal.addChild(rValLabel); + rVal.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ + callback.run(); + return false; + }}); + return rVal; + } + public boolean getVisible() { return visible; } diff --git a/src/main/java/electrosphere/renderer/ui/elements/Div.java b/src/main/java/electrosphere/renderer/ui/elements/Div.java index ad9a7c1b..32cc5d97 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Div.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Div.java @@ -32,9 +32,52 @@ public class Div extends StandardContainerElement implements ClickableElement,Dr static final Vector3f windowDrawDebugColor = new Vector3f(1.0f,1.0f,1.0f); - public Div(){ + /** + * Creates a new div + * @return The div + */ + public static Div createDiv(){ + return new Div(); + } + + /** + * Creates a div that will behave like a row + * @param children The elements to include within the row + * @return The div + */ + public static Div createRow(Element ... children){ + Div rVal = new Div(); + rVal.setFlexDirection(YogaFlexDirection.Row); + if(children != null && children.length > 0){ + for(Element child : children){ + rVal.addChild(child); + } + } + return rVal; + } + + /** + * Creates a div that will behave like a column + * @param children the elements to include within the column + * @return The div + */ + public static Div createCol(Element ... children){ + Div rVal = new Div(); + rVal.setFlexDirection(YogaFlexDirection.Column); + if(children != null && children.length > 0){ + for(Element child : children){ + rVal.addChild(child); + } + } + return rVal; + } + + /** + * Constructor + */ + private Div(){ super(); - Yoga.YGNodeStyleSetFlex(yogaNode, 1.0f); + Yoga.YGNodeStyleSetDisplay(yogaNode, Yoga.YGDisplayFlex); } diff --git a/src/main/java/electrosphere/renderer/ui/elements/FormElement.java b/src/main/java/electrosphere/renderer/ui/elements/FormElement.java index ed6f4557..b1115440 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/FormElement.java +++ b/src/main/java/electrosphere/renderer/ui/elements/FormElement.java @@ -16,7 +16,7 @@ public class FormElement extends StandardContainerElement implements DrawableEle public FormElement(){ super(); - Yoga.YGNodeStyleSetFlex(yogaNode, 1.0f); + Yoga.YGNodeStyleSetDisplay(yogaNode, Yoga.YGDisplayFlex); } public void draw( diff --git a/src/main/java/electrosphere/renderer/ui/elements/Label.java b/src/main/java/electrosphere/renderer/ui/elements/Label.java index b8351c42..23660759 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Label.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Label.java @@ -17,6 +17,11 @@ import electrosphere.renderer.ui.font.Font; */ public class Label extends StandardContainerElement implements DrawableElement { + /** + * The default font size + */ + public static final float DEFAULT_FONT_SIZE = 1.0f; + public boolean visible = false; diff --git a/src/main/java/electrosphere/renderer/ui/elements/Slider.java b/src/main/java/electrosphere/renderer/ui/elements/Slider.java index a60b4f57..336cd168 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Slider.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Slider.java @@ -1,5 +1,7 @@ package electrosphere.renderer.ui.elements; +import java.util.function.Consumer; + import org.joml.Vector3f; import electrosphere.engine.Globals; @@ -67,6 +69,19 @@ public class Slider extends StandardElement implements ClickableElement, Draggab return slider; } + /** + * Creates a slider element + * @param callback the Logic to fire when the slider changes value + * @return the slider element + */ + public static Slider createSlider(Consumer callback){ + Slider slider = new Slider(); + slider.setOnValueChangeCallback(new ValueChangeEventCallback() {public void execute(ValueChangeEvent event) { + callback.accept(event); + }}); + return slider; + } + /** * Private constructor */ diff --git a/src/main/java/electrosphere/renderer/ui/elements/StandardContainerElement.java b/src/main/java/electrosphere/renderer/ui/elements/StandardContainerElement.java index 3c76cc1b..872323fb 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/StandardContainerElement.java +++ b/src/main/java/electrosphere/renderer/ui/elements/StandardContainerElement.java @@ -163,8 +163,23 @@ public class StandardContainerElement extends StandardElement implements Contain } @Override - public void setFlexDirection(int layout){ - Yoga.YGNodeStyleSetFlexDirection(yogaNode, layout); + public void setFlexDirection(YogaFlexDirection layout){ + int directionInteger = Yoga.YGFlexDirectionColumn; + switch(layout){ + case Column: + directionInteger = Yoga.YGFlexDirectionColumn; + break; + case Column_Reverse: + directionInteger = Yoga.YGFlexDirectionColumnReverse; + break; + case Row: + directionInteger = Yoga.YGFlexDirectionRow; + break; + case Row_Reverse: + directionInteger = Yoga.YGFlexDirectionRowReverse; + break; + } + Yoga.YGNodeStyleSetFlexDirection(yogaNode, directionInteger); } @Override @@ -252,18 +267,93 @@ public class StandardContainerElement extends StandardElement implements Contain } @Override - public void setJustifyContent(int justification){ - Yoga.YGNodeStyleSetJustifyContent(this.yogaNode, justification); + public void setJustifyContent(YogaJustification justification){ + int justificationInteger = Yoga.YGJustifyFlexStart; + switch(justification){ + case Center: + justificationInteger = Yoga.YGJustifyCenter; + break; + case Start: + justificationInteger = Yoga.YGJustifyFlexStart; + break; + case End: + justificationInteger = Yoga.YGJustifyFlexEnd; + break; + case Around: + justificationInteger = Yoga.YGJustifySpaceAround; + break; + case Between: + justificationInteger = Yoga.YGJustifySpaceBetween; + break; + case Evenly: + justificationInteger = Yoga.YGJustifySpaceEvenly; + break; + } + Yoga.YGNodeStyleSetJustifyContent(this.yogaNode, justificationInteger); } @Override - public void setAlignItems(int alignment){ - Yoga.YGNodeStyleSetAlignItems(this.yogaNode, alignment); + public void setAlignItems(YogaAlignment alignment){ + int alignmentInteger = Yoga.YGAlignAuto; + switch(alignment){ + case Auto: + alignmentInteger = Yoga.YGAlignAuto; + break; + case Start: + alignmentInteger = Yoga.YGAlignFlexStart; + break; + case End: + alignmentInteger = Yoga.YGAlignFlexEnd; + break; + case Around: + alignmentInteger = Yoga.YGAlignSpaceAround; + break; + case Between: + alignmentInteger = Yoga.YGAlignSpaceBetween; + break; + case Stretch: + alignmentInteger = Yoga.YGAlignStretch; + break; + case Baseline: + alignmentInteger = Yoga.YGAlignBaseline; + break; + case Center: + alignmentInteger = Yoga.YGAlignCenter; + break; + } + Yoga.YGNodeStyleSetAlignItems(this.yogaNode, alignmentInteger); } @Override - public void setAlignContent(int alignment){ - Yoga.YGNodeStyleSetAlignContent(this.yogaNode, alignment); + public void setAlignContent(YogaAlignment alignment){ + int alignmentInteger = Yoga.YGAlignAuto; + switch(alignment){ + case Auto: + alignmentInteger = Yoga.YGAlignAuto; + break; + case Start: + alignmentInteger = Yoga.YGAlignFlexStart; + break; + case End: + alignmentInteger = Yoga.YGAlignFlexEnd; + break; + case Around: + alignmentInteger = Yoga.YGAlignSpaceAround; + break; + case Between: + alignmentInteger = Yoga.YGAlignSpaceBetween; + break; + case Stretch: + alignmentInteger = Yoga.YGAlignStretch; + break; + case Baseline: + alignmentInteger = Yoga.YGAlignBaseline; + break; + case Center: + alignmentInteger = Yoga.YGAlignCenter; + break; + } + Yoga.YGNodeStyleSetAlignContent(this.yogaNode, alignmentInteger); } diff --git a/src/main/java/electrosphere/renderer/ui/elements/StandardElement.java b/src/main/java/electrosphere/renderer/ui/elements/StandardElement.java index 49bacd74..cf01def3 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/StandardElement.java +++ b/src/main/java/electrosphere/renderer/ui/elements/StandardElement.java @@ -214,4 +214,12 @@ public class StandardElement implements Element { Yoga.YGNodeStyleSetMinHeight(yogaNode, height); } + /** + * The value of the grow property + * @param grow The grow value + */ + public void setFlexGrow(float grow){ + Yoga.YGNodeStyleSetFlexGrow(yogaNode, grow); + } + } diff --git a/src/main/java/electrosphere/renderer/ui/elements/TextInput.java b/src/main/java/electrosphere/renderer/ui/elements/TextInput.java index 01245fe0..e47f98b0 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/TextInput.java +++ b/src/main/java/electrosphere/renderer/ui/elements/TextInput.java @@ -12,10 +12,12 @@ import electrosphere.renderer.ui.elementtypes.DrawableElement; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.elementtypes.FocusableElement; import electrosphere.renderer.ui.elementtypes.KeyEventElement; +import electrosphere.renderer.ui.elementtypes.ValueElement; import electrosphere.renderer.ui.events.ClickEvent; import electrosphere.renderer.ui.events.Event; import electrosphere.renderer.ui.events.FocusEvent; import electrosphere.renderer.ui.events.KeyboardEvent; +import electrosphere.renderer.ui.events.ValueChangeEvent; import electrosphere.renderer.ui.font.Font; import org.joml.Vector3f; @@ -27,7 +29,7 @@ import java.util.regex.Pattern; /** * A Text input */ -public class TextInput extends StandardContainerElement implements DrawableElement, FocusableElement, KeyEventElement, ClickableElement { +public class TextInput extends StandardContainerElement implements DrawableElement, FocusableElement, KeyEventElement, ClickableElement, ValueElement { Vector3f boxPosition = new Vector3f(); Vector3f boxDimensions = new Vector3f(); @@ -42,6 +44,7 @@ public class TextInput extends StandardContainerElement implements DrawableEleme FocusEventCallback onLoseFocusCallback; KeyboardEventCallback onKeyPressCallback; ClickEventCallback onClickCallback; + ValueChangeEventCallback onValueChangeCallback; Vector3f color; String text = ""; @@ -53,12 +56,11 @@ public class TextInput extends StandardContainerElement implements DrawableEleme Font font; /** - * Creates a text input element - * @param fontSize the size of the font in the text element + * Creates a text input element using the default font size * @return The text input */ - public static TextInput createTextInput(float fontSize){ - return new TextInput(fontSize); + public static TextInput createTextInput(){ + return new TextInput(Label.DEFAULT_FONT_SIZE); } /** @@ -230,6 +232,11 @@ public class TextInput extends StandardContainerElement implements DrawableEleme Globals.elementManager.focusElement(this); propagate = false; } + } else if(event instanceof ValueChangeEvent){ + ValueChangeEvent valueEvent = (ValueChangeEvent)event; + if(this.onValueChangeCallback != null){ + this.onValueChangeCallback.execute(valueEvent); + } } return propagate; } @@ -247,6 +254,8 @@ public class TextInput extends StandardContainerElement implements DrawableEleme } else { this.setText(this.text + keyEvent.getKey()); } + //fire value change event + Globals.elementManager.fireEventNoPosition(new ValueChangeEvent(text), this); return false; } @@ -274,5 +283,10 @@ public class TextInput extends StandardContainerElement implements DrawableEleme public void setOnClick(ClickEventCallback callback) { onClickCallback = callback; } + + @Override + public void setOnValueChangeCallback(ValueChangeEventCallback callback) { + this.onValueChangeCallback = callback; + } } diff --git a/src/main/java/electrosphere/renderer/ui/elements/Window.java b/src/main/java/electrosphere/renderer/ui/elements/Window.java index f6ccd36a..61eae6a9 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Window.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Window.java @@ -82,9 +82,9 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme //yoga node for placement this.parentWindowYogaNode = Yoga.YGNodeNew(); Yoga.YGNodeInsertChild(this.parentWindowYogaNode, this.yogaNode, 0); - setParentAlignContent(Yoga.YGAlignFlexStart); - setParentAlignItem(Yoga.YGAlignFlexStart); - setParentJustifyContent(Yoga.YGJustifyFlexStart); + setParentAlignContent(YogaAlignment.Start); + setParentAlignItem(YogaAlignment.Start); + setParentJustifyContent(YogaJustification.Start); this.setWidth(width); this.setHeight(height); } @@ -369,23 +369,113 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme } @Override - public void setFlexDirection(int layout){ - Yoga.YGNodeStyleSetFlexDirection(yogaNode, layout); + public void setFlexDirection(YogaFlexDirection layout){ + int directionInteger = Yoga.YGFlexDirectionColumn; + switch(layout){ + case Column: + directionInteger = Yoga.YGFlexDirectionColumn; + break; + case Column_Reverse: + directionInteger = Yoga.YGFlexDirectionColumnReverse; + break; + case Row: + directionInteger = Yoga.YGFlexDirectionRow; + break; + case Row_Reverse: + directionInteger = Yoga.YGFlexDirectionRowReverse; + break; + } + Yoga.YGNodeStyleSetFlexDirection(yogaNode, directionInteger); } @Override - public void setJustifyContent(int justification){ - Yoga.YGNodeStyleSetJustifyContent(this.yogaNode, justification); + public void setJustifyContent(YogaJustification justification){ + int justificationInteger = Yoga.YGJustifyFlexStart; + switch(justification){ + case Center: + justificationInteger = Yoga.YGJustifyCenter; + break; + case Start: + justificationInteger = Yoga.YGJustifyFlexStart; + break; + case End: + justificationInteger = Yoga.YGJustifyFlexEnd; + break; + case Around: + justificationInteger = Yoga.YGJustifySpaceAround; + break; + case Between: + justificationInteger = Yoga.YGJustifySpaceBetween; + break; + case Evenly: + justificationInteger = Yoga.YGJustifySpaceEvenly; + break; + } + Yoga.YGNodeStyleSetJustifyContent(this.yogaNode, justificationInteger); } @Override - public void setAlignItems(int alignment){ - Yoga.YGNodeStyleSetAlignItems(this.yogaNode, alignment); + public void setAlignItems(YogaAlignment alignment){ + int alignmentInteger = Yoga.YGAlignAuto; + switch(alignment){ + case Auto: + alignmentInteger = Yoga.YGAlignAuto; + break; + case Start: + alignmentInteger = Yoga.YGAlignFlexStart; + break; + case End: + alignmentInteger = Yoga.YGAlignFlexEnd; + break; + case Around: + alignmentInteger = Yoga.YGAlignSpaceAround; + break; + case Between: + alignmentInteger = Yoga.YGAlignSpaceBetween; + break; + case Stretch: + alignmentInteger = Yoga.YGAlignStretch; + break; + case Baseline: + alignmentInteger = Yoga.YGAlignBaseline; + break; + case Center: + alignmentInteger = Yoga.YGAlignCenter; + break; + } + Yoga.YGNodeStyleSetAlignItems(this.yogaNode, alignmentInteger); } @Override - public void setAlignContent(int alignment){ - Yoga.YGNodeStyleSetAlignContent(this.yogaNode, alignment); + public void setAlignContent(YogaAlignment alignment){ + int alignmentInteger = Yoga.YGAlignAuto; + switch(alignment){ + case Auto: + alignmentInteger = Yoga.YGAlignAuto; + break; + case Start: + alignmentInteger = Yoga.YGAlignFlexStart; + break; + case End: + alignmentInteger = Yoga.YGAlignFlexEnd; + break; + case Around: + alignmentInteger = Yoga.YGAlignSpaceAround; + break; + case Between: + alignmentInteger = Yoga.YGAlignSpaceBetween; + break; + case Stretch: + alignmentInteger = Yoga.YGAlignStretch; + break; + case Baseline: + alignmentInteger = Yoga.YGAlignBaseline; + break; + case Center: + alignmentInteger = Yoga.YGAlignCenter; + break; + } + Yoga.YGNodeStyleSetAlignContent(this.yogaNode, alignmentInteger); } @Override @@ -482,24 +572,99 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme * Sets the alignment of items on the parent to the window yoga node * @param alignment The alignment value */ - public void setParentAlignItem(int alignment){ - Yoga.YGNodeStyleSetAlignItems(this.parentWindowYogaNode, alignment); + public void setParentAlignItem(YogaAlignment alignment){ + int alignmentInteger = Yoga.YGAlignAuto; + switch(alignment){ + case Auto: + alignmentInteger = Yoga.YGAlignAuto; + break; + case Start: + alignmentInteger = Yoga.YGAlignFlexStart; + break; + case End: + alignmentInteger = Yoga.YGAlignFlexEnd; + break; + case Around: + alignmentInteger = Yoga.YGAlignSpaceAround; + break; + case Between: + alignmentInteger = Yoga.YGAlignSpaceBetween; + break; + case Stretch: + alignmentInteger = Yoga.YGAlignStretch; + break; + case Baseline: + alignmentInteger = Yoga.YGAlignBaseline; + break; + case Center: + alignmentInteger = Yoga.YGAlignCenter; + break; + } + Yoga.YGNodeStyleSetAlignItems(this.parentWindowYogaNode, alignmentInteger); } /** * Sets the alignment of content on the parent to the window yoga node * @param alignment The alignment */ - public void setParentAlignContent(int alignment){ - Yoga.YGNodeStyleSetAlignContent(this.parentWindowYogaNode, alignment); + public void setParentAlignContent(YogaAlignment alignment){ + int alignmentInteger = Yoga.YGAlignAuto; + switch(alignment){ + case Auto: + alignmentInteger = Yoga.YGAlignAuto; + break; + case Start: + alignmentInteger = Yoga.YGAlignFlexStart; + break; + case End: + alignmentInteger = Yoga.YGAlignFlexEnd; + break; + case Around: + alignmentInteger = Yoga.YGAlignSpaceAround; + break; + case Between: + alignmentInteger = Yoga.YGAlignSpaceBetween; + break; + case Stretch: + alignmentInteger = Yoga.YGAlignStretch; + break; + case Baseline: + alignmentInteger = Yoga.YGAlignBaseline; + break; + case Center: + alignmentInteger = Yoga.YGAlignCenter; + break; + } + Yoga.YGNodeStyleSetAlignContent(this.parentWindowYogaNode, alignmentInteger); } /** * Sets the justification of the parent yoga node containing this window * @param justification The justification mode */ - public void setParentJustifyContent(int justification){ - Yoga.YGNodeStyleSetJustifyContent(this.parentWindowYogaNode, justification); + public void setParentJustifyContent(YogaJustification justification){ + int justificationInteger = Yoga.YGJustifyFlexStart; + switch(justification){ + case Center: + justificationInteger = Yoga.YGJustifyCenter; + break; + case Start: + justificationInteger = Yoga.YGJustifyFlexStart; + break; + case End: + justificationInteger = Yoga.YGJustifyFlexEnd; + break; + case Around: + justificationInteger = Yoga.YGJustifySpaceAround; + break; + case Between: + justificationInteger = Yoga.YGJustifySpaceBetween; + break; + case Evenly: + justificationInteger = Yoga.YGJustifySpaceEvenly; + break; + } + Yoga.YGNodeStyleSetJustifyContent(this.parentWindowYogaNode, justificationInteger); } @Override diff --git a/src/main/java/electrosphere/renderer/ui/elementtypes/ContainerElement.java b/src/main/java/electrosphere/renderer/ui/elementtypes/ContainerElement.java index fa1c5147..522252dd 100644 --- a/src/main/java/electrosphere/renderer/ui/elementtypes/ContainerElement.java +++ b/src/main/java/electrosphere/renderer/ui/elementtypes/ContainerElement.java @@ -7,6 +7,42 @@ import java.util.List; */ public interface ContainerElement extends Element { + /** + * Options for flex directions + */ + public static enum YogaFlexDirection { + Column, + Column_Reverse, + Row, + Row_Reverse, + }; + + /** + * Options for aligning items in containers + */ + public static enum YogaAlignment { + Auto, + Baseline, + Center, + End, + Start, + Around, + Between, + Stretch, + }; + + /** + * Options for justifying items in containers + */ + public static enum YogaJustification { + Center, + End, + Start, + Around, + Between, + Evenly, + } + /** * Add a child element to this element * @param child The child element @@ -49,24 +85,24 @@ public interface ContainerElement extends Element { * Sets the flex direction * @param layout the flex direction */ - public void setFlexDirection(int layout); + public void setFlexDirection(YogaFlexDirection layout); /** * Sets the content justification of the container * @param justification The spacing value */ - public void setJustifyContent(int justification); + public void setJustifyContent(YogaJustification justification); /** * Sets the item alignment * @param alignment The alignment style */ - public void setAlignItems(int alignment); + public void setAlignItems(YogaAlignment alignment); /** * Sets the content alignment * @param alignment the alignment style */ - public void setAlignContent(int alignment); + public void setAlignContent(YogaAlignment alignment); } diff --git a/src/main/java/electrosphere/renderer/ui/events/ValueChangeEvent.java b/src/main/java/electrosphere/renderer/ui/events/ValueChangeEvent.java index 85580588..31aa15ab 100644 --- a/src/main/java/electrosphere/renderer/ui/events/ValueChangeEvent.java +++ b/src/main/java/electrosphere/renderer/ui/events/ValueChangeEvent.java @@ -1,34 +1,71 @@ package electrosphere.renderer.ui.events; -public class ValueChangeEvent { +/** + * An event raised when an element changes an internal value + */ +public class ValueChangeEvent implements Event { + /** + * The type of the value changed + */ public static enum ValueType { STRING, FLOAT, } + /** + * The string value + */ String valueString; + + /** + * The float value + */ float valueFloat; + + /** + * The type of this event + */ ValueType valueType; + /** + * Constructor for string value changes + * @param value The string + */ public ValueChangeEvent(String value){ valueString = value; valueType = ValueType.STRING; } + /** + * Constructor for float value changes + * @param value The float + */ public ValueChangeEvent(float value){ valueFloat = value; valueType = ValueType.FLOAT; } + /** + * Gets the type of the value + * @return The type of the value + */ public ValueType getType(){ return valueType; } + /** + * Gets the value that changed as a float + * @return The float value + */ public float getAsFloat(){ return valueFloat; } + /** + * Gets the value that changed as a string + * @return The string value + */ public String getAsString(){ return valueString; } diff --git a/src/main/java/electrosphere/renderer/ui/macros/InputMacros.java b/src/main/java/electrosphere/renderer/ui/macros/InputMacros.java new file mode 100644 index 00000000..7812d2da --- /dev/null +++ b/src/main/java/electrosphere/renderer/ui/macros/InputMacros.java @@ -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 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 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; + } + +} diff --git a/src/main/java/electrosphere/server/character/PlayerCharacterCreation.java b/src/main/java/electrosphere/server/character/PlayerCharacterCreation.java index 969f07b1..0d00d1c1 100644 --- a/src/main/java/electrosphere/server/character/PlayerCharacterCreation.java +++ b/src/main/java/electrosphere/server/character/PlayerCharacterCreation.java @@ -37,9 +37,9 @@ public class PlayerCharacterCreation { //attach player object to player character playerObject.setPlayerEntity(newPlayerEntity); playerObject.setWorldPos(new Vector3i( - Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.x), - Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.y), - Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.z) + realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.x), + realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.y), + realm.getServerWorldData().convertRealToChunkSpace(Globals.spawnPoint.z) )); realm.getDataCellManager().addPlayerToRealm(playerObject); //set controller id diff --git a/src/main/java/electrosphere/server/content/EnvironmentGenerator.java b/src/main/java/electrosphere/server/content/EnvironmentGenerator.java index 2d4d9452..a6381a03 100644 --- a/src/main/java/electrosphere/server/content/EnvironmentGenerator.java +++ b/src/main/java/electrosphere/server/content/EnvironmentGenerator.java @@ -1,6 +1,5 @@ package electrosphere.server.content; -import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.types.foliage.FoliageUtils; import electrosphere.logger.LoggerInterface; @@ -40,9 +39,9 @@ public class EnvironmentGenerator { LoggerInterface.loggerGameLogic.DEBUG("generate forest"); for(int i = 0; i < targetNum; i++){ Vector3d position = new Vector3d( - Globals.serverWorldData.convertWorldToReal(worldPos.x) + rand.nextFloat() * 16, + realm.getServerWorldData().convertWorldToReal(worldPos.x) + rand.nextFloat() * 16, 0, - Globals.serverWorldData.convertWorldToReal(worldPos.z) + rand.nextFloat() * 16 + realm.getServerWorldData().convertWorldToReal(worldPos.z) + rand.nextFloat() * 16 ); Entity tree = FoliageUtils.serverSpawnTreeFoliage(realm, position, "oak", rand.nextLong()); } diff --git a/src/main/java/electrosphere/server/datacell/GriddedDataCellManager.java b/src/main/java/electrosphere/server/datacell/GriddedDataCellManager.java index 937a959a..c2e46a8e 100644 --- a/src/main/java/electrosphere/server/datacell/GriddedDataCellManager.java +++ b/src/main/java/electrosphere/server/datacell/GriddedDataCellManager.java @@ -31,6 +31,17 @@ import electrosphere.server.terrain.manager.ServerTerrainChunk; * Implementation of DataCellManager that lays out cells in a logical grid (array). Useful for eg 3d terrain gridded world. */ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager { + + /** + * The minimum grid size allowed + */ + public static final int MIN_GRID_SIZE = 1; + + /** + * The max grid size allowed + */ + public static final int MAX_GRID_SIZE = 10; + //these are going to be the natural ground grid of data cells, but we're going to have more than this Map groundDataCells = new HashMap(); Map cellPositionMap = new HashMap(); @@ -40,10 +51,11 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager static final int UNLOAD_FRAME_THRESHOLD = 100; //loaded cells Semaphore loadedCellsLock = new Semaphore(1); - Set loadedCells; - int discreteWorldSize; + Set loadedCells = new CopyOnWriteArraySet(); //parent realm Realm parent; + //the world data of the parent + ServerWorldData serverWorldData; //Manager for terrain for this particular cell manager ServerTerrainManager serverTerrainManager; //manager for fluids for this particular cell manager @@ -58,24 +70,30 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager * @param parent The gridded data cell manager's parent realm */ public GriddedDataCellManager( - Realm parent, - ServerTerrainManager serverTerrainManager, - ServerFluidManager serverFluidManager, - ServerContentManager serverContentManager + Realm parent ) { this.parent = parent; - this.serverTerrainManager = serverTerrainManager; - this.serverFluidManager = serverFluidManager; - this.serverContentManager = serverContentManager; - } + this.serverWorldData = this.parent.getServerWorldData(); + this.serverTerrainManager = serverWorldData.getServerTerrainManager(); + this.serverFluidManager = serverWorldData.getServerFluidManager(); + this.serverContentManager = this.parent.getServerContentManager(); - /** - * Initializes the gridded data cell manager - * @param data The server world data to back the manager with - */ - public void init(ServerWorldData data){ - discreteWorldSize = data.getWorldSizeDiscrete(); - loadedCells = new CopyOnWriteArraySet(); + //Assert the gridded data cell manager was given good data + if( + this.parent == null || + this.serverWorldData == null || + this.serverTerrainManager == null || + this.serverFluidManager == null || + this.serverContentManager == null + ){ + throw new IllegalStateException("Tried to create a GriddedDataCellManager with invalid parameters " + + this.parent + " " + + this.serverWorldData + " " + + this.serverTerrainManager + " " + + this.serverFluidManager + " " + + this.serverContentManager + " " + ); + } } /** @@ -90,9 +108,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager for(int y = worldPos.y - playerSimulationRadius; y < worldPos.y + playerSimulationRadius + 1; y++){ for(int z = worldPos.z - playerSimulationRadius; z < worldPos.z + playerSimulationRadius + 1; z++){ if( - x >= 0 && x < discreteWorldSize && - y >= 0 && y < discreteWorldSize && - z >= 0 && z < discreteWorldSize + x >= 0 && x < this.serverWorldData.getWorldSizeDiscrete() && + y >= 0 && y < this.serverWorldData.getWorldSizeDiscrete() && + z >= 0 && z < this.serverWorldData.getWorldSizeDiscrete() ){ Vector3i targetPos = new Vector3i(x,y,z); LoggerInterface.loggerEngine.DEBUG("GriddedDataCellManager: Add player to " + x + " " + y + " " + z); @@ -136,9 +154,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager for(int y = oldPosition.y - playerSimulationRadius; y < oldPosition.y + playerSimulationRadius + 1; y++){ for(int z = oldPosition.z - playerSimulationRadius; z < oldPosition.z + playerSimulationRadius + 1; z++){ if( - x >= 0 && x < discreteWorldSize && - y >= 0 && y < discreteWorldSize && - z >= 0 && z < discreteWorldSize && + x >= 0 && x < this.serverWorldData.getWorldSizeDiscrete() && + y >= 0 && y < this.serverWorldData.getWorldSizeDiscrete() && + z >= 0 && z < this.serverWorldData.getWorldSizeDiscrete() && ( x < newPosition.x - playerSimulationRadius || x > newPosition.x + playerSimulationRadius || @@ -163,9 +181,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager for(int y = newPosition.y - playerSimulationRadius; y < newPosition.y + playerSimulationRadius + 1; y++){ for(int z = newPosition.x - playerSimulationRadius; z < newPosition.z + playerSimulationRadius + 1; z++){ if( - x >= 0 && x < discreteWorldSize && - y >= 0 && y < discreteWorldSize && - z >= 0 && z < discreteWorldSize && + x >= 0 && x < this.serverWorldData.getWorldSizeDiscrete() && + y >= 0 && y < this.serverWorldData.getWorldSizeDiscrete() && + z >= 0 && z < this.serverWorldData.getWorldSizeDiscrete() && ( x < oldPosition.x - playerSimulationRadius || x > oldPosition.x + playerSimulationRadius || @@ -221,9 +239,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager Entity playerEntity = player.getPlayerEntity(); if(playerEntity != null && !parent.getLoadingDataCell().containsPlayer(player)){ Vector3d position = EntityUtils.getPosition(playerEntity); - int currentWorldX = Globals.serverWorldData.convertRealToChunkSpace(position.x); - int currentWorldY = Globals.serverWorldData.convertRealToChunkSpace(position.y); - int currentWorldZ = Globals.serverWorldData.convertRealToChunkSpace(position.z); + int currentWorldX = parent.getServerWorldData().convertRealToChunkSpace(position.x); + int currentWorldY = parent.getServerWorldData().convertRealToChunkSpace(position.y); + int currentWorldZ = parent.getServerWorldData().convertRealToChunkSpace(position.z); if(currentWorldX != player.getWorldPos().x || currentWorldY != player.getWorldPos().y || currentWorldZ != player.getWorldPos().z){ movePlayer(player,new Vector3i(currentWorldX,currentWorldY,currentWorldZ)); playerChangedChunk = true; @@ -280,15 +298,15 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager */ public ServerDataCell getDataCellAtPoint(Vector3d point){ ServerDataCell rVal = null; - int worldX = Globals.serverWorldData.convertRealToChunkSpace(point.x); - int worldY = Globals.serverWorldData.convertRealToChunkSpace(point.y); - int worldZ = Globals.serverWorldData.convertRealToChunkSpace(point.z); + int worldX = parent.getServerWorldData().convertRealToChunkSpace(point.x); + int worldY = parent.getServerWorldData().convertRealToChunkSpace(point.y); + int worldZ = parent.getServerWorldData().convertRealToChunkSpace(point.z); Vector3i worldPos = new Vector3i(worldX,worldY,worldZ); if( //in bounds of array - worldX >= 0 && worldX < discreteWorldSize && - worldY >= 0 && worldY < discreteWorldSize && - worldZ >= 0 && worldZ < discreteWorldSize && + worldX >= 0 && worldX < this.serverWorldData.getWorldSizeDiscrete() && + worldY >= 0 && worldY < this.serverWorldData.getWorldSizeDiscrete() && + worldZ >= 0 && worldZ < this.serverWorldData.getWorldSizeDiscrete() && //isn't null groundDataCells.get(getServerDataCellKey(worldPos)) != null ){ @@ -304,15 +322,15 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager * @return The data cell if created, null otherwise */ public ServerDataCell tryCreateCellAtPoint(Vector3d point){ - int worldX = Globals.serverWorldData.convertRealToChunkSpace(point.x); - int worldY = Globals.serverWorldData.convertRealToChunkSpace(point.y); - int worldZ = Globals.serverWorldData.convertRealToChunkSpace(point.z); + int worldX = parent.getServerWorldData().convertRealToChunkSpace(point.x); + int worldY = parent.getServerWorldData().convertRealToChunkSpace(point.y); + int worldZ = parent.getServerWorldData().convertRealToChunkSpace(point.z); Vector3i worldPos = new Vector3i(worldX,worldY,worldZ); if( //in bounds of array - worldX >= 0 && worldX < discreteWorldSize && - worldY >= 0 && worldY < discreteWorldSize && - worldZ >= 0 && worldZ < discreteWorldSize && + worldX >= 0 && worldX < this.serverWorldData.getWorldSizeDiscrete() && + worldY >= 0 && worldY < this.serverWorldData.getWorldSizeDiscrete() && + worldZ >= 0 && worldZ < this.serverWorldData.getWorldSizeDiscrete() && //isn't null groundDataCells.get(getServerDataCellKey(worldPos)) == null ){ @@ -337,9 +355,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager public ServerDataCell getCellAtWorldPosition(Vector3i position){ if( //in bounds of array - position.x >= 0 && position.x < discreteWorldSize && - position.y >= 0 && position.y < discreteWorldSize && - position.z >= 0 && position.z < discreteWorldSize && + position.x >= 0 && position.x < this.serverWorldData.getWorldSizeDiscrete() && + position.y >= 0 && position.y < this.serverWorldData.getWorldSizeDiscrete() && + position.z >= 0 && position.z < this.serverWorldData.getWorldSizeDiscrete() && //isn't null groundDataCells.get(getServerDataCellKey(position)) != null ){ @@ -528,20 +546,20 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager if(positionToTest.x < 0){ returnPos.x = 0; } - if(positionToTest.x >= Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete())){ - returnPos.x = Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete()) - 1; + if(positionToTest.x >= parent.getServerWorldData().convertChunkToRealSpace(parent.getServerWorldData().getWorldSizeDiscrete())){ + returnPos.x = parent.getServerWorldData().convertChunkToRealSpace(parent.getServerWorldData().getWorldSizeDiscrete()) - 1; } if(positionToTest.y < 0){ returnPos.y = 0; } - if(positionToTest.y >= Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete())){ - returnPos.y = Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete()) - 1; + if(positionToTest.y >= parent.getServerWorldData().convertChunkToRealSpace(parent.getServerWorldData().getWorldSizeDiscrete())){ + returnPos.y = parent.getServerWorldData().convertChunkToRealSpace(parent.getServerWorldData().getWorldSizeDiscrete()) - 1; } if(positionToTest.z < 0){ returnPos.z = 0; } - if(positionToTest.z >= Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete())){ - returnPos.z = Globals.serverWorldData.convertChunkToRealSpace(Globals.serverWorldData.getWorldSizeDiscrete()) - 1; + if(positionToTest.z >= parent.getServerWorldData().convertChunkToRealSpace(parent.getServerWorldData().getWorldSizeDiscrete())){ + returnPos.z = parent.getServerWorldData().convertChunkToRealSpace(parent.getServerWorldData().getWorldSizeDiscrete()) - 1; } return returnPos; } diff --git a/src/main/java/electrosphere/server/datacell/Realm.java b/src/main/java/electrosphere/server/datacell/Realm.java index a1e5b51f..f1915cdc 100644 --- a/src/main/java/electrosphere/server/datacell/Realm.java +++ b/src/main/java/electrosphere/server/datacell/Realm.java @@ -5,7 +5,9 @@ import electrosphere.collision.hitbox.HitboxManager; import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.Scene; +import electrosphere.game.server.world.ServerWorldData; import electrosphere.net.parser.net.message.NetworkMessage; +import electrosphere.server.content.ServerContentManager; import electrosphere.server.datacell.interfaces.DataCellManager; import java.util.HashSet; @@ -34,15 +36,32 @@ public class Realm { //Hitbox manager for the realm HitboxManager hitboxManager; + + /** + * The world data about the server + */ + ServerWorldData serverWorldData; + + /** + * The content manager + */ + ServerContentManager serverContentManager; /** * Realm constructor * @param collisionEngine The collision engine for the realm * @param hitboxManager The hitbox manager for the realm */ - protected Realm(CollisionEngine collisionEngine, HitboxManager hitboxManager){ + protected Realm( + ServerWorldData serverWorldData, + CollisionEngine collisionEngine, + HitboxManager hitboxManager, + ServerContentManager serverContentManager + ){ + this.serverWorldData = serverWorldData; this.collisionEngine = collisionEngine; this.hitboxManager = hitboxManager; + this.serverContentManager = serverContentManager; } /** @@ -180,7 +199,23 @@ public class Realm { */ protected void save(String saveName){ dataCellManager.save(saveName); + serverWorldData.getServerTerrainManager().save(saveName); } + /** + * Gets the server world data for this realm + * @return The server world data + */ + public ServerWorldData getServerWorldData(){ + return this.serverWorldData; + } + + /** + * Gets the content manager for this realm + * @return The content manager + */ + public ServerContentManager getServerContentManager(){ + return this.serverContentManager; + } } diff --git a/src/main/java/electrosphere/server/datacell/RealmManager.java b/src/main/java/electrosphere/server/datacell/RealmManager.java index 2b002657..13960cb5 100644 --- a/src/main/java/electrosphere/server/datacell/RealmManager.java +++ b/src/main/java/electrosphere/server/datacell/RealmManager.java @@ -10,8 +10,10 @@ import electrosphere.collision.CollisionWorldData; import electrosphere.collision.hitbox.HitboxManager; import electrosphere.engine.Globals; import electrosphere.entity.Entity; +import electrosphere.entity.scene.RealmDescriptor; import electrosphere.game.server.world.ServerWorldData; import electrosphere.net.server.player.Player; +import electrosphere.server.content.ServerContentManager; import electrosphere.server.datacell.physics.ServerHitboxResolutionCallback; /** @@ -26,7 +28,6 @@ public class RealmManager { //Map of player to the realm the player is in Map playerToRealmMap = new ConcurrentHashMap(); - /** * Constructor */ @@ -40,24 +41,22 @@ public class RealmManager { * @return The realm */ public Realm createRealm(){ - return new Realm(new CollisionEngine(), new HitboxManager(new ServerHitboxResolutionCallback())); + return new Realm(new ServerWorldData(), new CollisionEngine(), new HitboxManager(new ServerHitboxResolutionCallback()), ServerContentManager.createServerContentManager(false)); } /** * Creates a realm that uses a gridded layout (ie an array of cells in 3d space) * @return The realm */ - public Realm createGriddedRealm(ServerWorldData serverWorldData){ + public Realm createGriddedRealm(ServerWorldData serverWorldData, ServerContentManager serverContentManager){ //create collision engine CollisionEngine collisionEngine = new CollisionEngine(); collisionEngine.setCollisionWorldData(new CollisionWorldData(serverWorldData)); //create realm - Realm realm = new Realm(collisionEngine, new HitboxManager(new ServerHitboxResolutionCallback())); + Realm realm = new Realm(serverWorldData, collisionEngine, new HitboxManager(new ServerHitboxResolutionCallback()), serverContentManager); //create function classes - GriddedDataCellManager griddedDataCellManager = new GriddedDataCellManager(realm,Globals.serverTerrainManager,Globals.serverFluidManager,Globals.serverContentManager); + GriddedDataCellManager griddedDataCellManager = new GriddedDataCellManager(realm); EntityDataCellMapper entityDataCellMapper = new EntityDataCellMapper(); - //init gridded manager - griddedDataCellManager.init(serverWorldData); //add function classes to realm realm.setDataCellManager(griddedDataCellManager); realm.setEntityDataCellMapper(entityDataCellMapper); diff --git a/src/main/java/electrosphere/server/datacell/physics/PhysicsDataCell.java b/src/main/java/electrosphere/server/datacell/physics/PhysicsDataCell.java index cb5a6791..21be474f 100644 --- a/src/main/java/electrosphere/server/datacell/physics/PhysicsDataCell.java +++ b/src/main/java/electrosphere/server/datacell/physics/PhysicsDataCell.java @@ -8,6 +8,7 @@ import electrosphere.entity.EntityUtils; import electrosphere.entity.types.terrain.TerrainChunk; import electrosphere.server.datacell.Realm; import electrosphere.server.terrain.manager.ServerTerrainChunk; +import electrosphere.server.terrain.manager.ServerTerrainManager; import org.joml.Vector3d; import org.joml.Vector3i; @@ -25,6 +26,7 @@ public class PhysicsDataCell { DBody physicsObject; Realm realm; + ServerTerrainManager serverTerrainManager; float[][][] weights = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE]; int[][][] types = new int[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE]; @@ -46,6 +48,7 @@ public class PhysicsDataCell { ){ PhysicsDataCell rVal = new PhysicsDataCell(); rVal.realm = realm; + rVal.serverTerrainManager = realm.getServerWorldData().getServerTerrainManager(); rVal.worldPos = worldPos; return rVal; } @@ -99,7 +102,7 @@ public class PhysicsDataCell { //fill in data // //main chunk - ServerTerrainChunk currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x, worldPos.y, worldPos.z); + ServerTerrainChunk currentChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y, worldPos.z); for(int x = 0; x < ChunkData.CHUNK_SIZE; x++){ for(int y = 0; y < ChunkData.CHUNK_SIZE; y++){ for(int z = 0; z < ChunkData.CHUNK_SIZE; z++){ @@ -109,8 +112,8 @@ public class PhysicsDataCell { } } //face X - if(worldPos.x + 1 < Globals.serverTerrainManager.getWorldDiscreteSize()){ - currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y, worldPos.z); + if(worldPos.x + 1 < realm.getServerWorldData().getWorldSizeDiscrete()){ + currentChunk = serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y, worldPos.z); for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){ for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){ weights[ChunkData.CHUNK_SIZE][i][j] = currentChunk.getWeight(0, i, j); @@ -126,8 +129,8 @@ public class PhysicsDataCell { } } //face Y - if(worldPos.y + 1 < Globals.serverTerrainManager.getWorldDiscreteSize()){ - currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x, worldPos.y + 1, worldPos.z); + if(worldPos.y + 1 < realm.getServerWorldData().getWorldSizeDiscrete()){ + currentChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y + 1, worldPos.z); for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){ for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){ weights[i][ChunkData.CHUNK_SIZE][j] = currentChunk.getWeight(i, 0, j); @@ -143,8 +146,8 @@ public class PhysicsDataCell { } } //face Z - if(worldPos.z + 1 < Globals.serverTerrainManager.getWorldDiscreteSize()){ - currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x, worldPos.y, worldPos.z + 1); + if(worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete()){ + currentChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y, worldPos.z + 1); for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){ for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){ weights[i][j][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(i, j, 0); @@ -161,10 +164,10 @@ public class PhysicsDataCell { } //edge X-Y if( - worldPos.x + 1 < Globals.serverTerrainManager.getWorldDiscreteSize() && - worldPos.y + 1 < Globals.serverTerrainManager.getWorldDiscreteSize() + worldPos.x + 1 < realm.getServerWorldData().getWorldSizeDiscrete() && + worldPos.y + 1 < realm.getServerWorldData().getWorldSizeDiscrete() ){ - currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y + 1, worldPos.z); + currentChunk = serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y + 1, worldPos.z); for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){ weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = currentChunk.getWeight(0, 0, i); types [ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = currentChunk.getType(0, 0, i); @@ -177,10 +180,10 @@ public class PhysicsDataCell { } //edge X-Z if( - worldPos.x + 1 < Globals.serverTerrainManager.getWorldDiscreteSize() && - worldPos.z + 1 < Globals.serverTerrainManager.getWorldDiscreteSize() + worldPos.x + 1 < realm.getServerWorldData().getWorldSizeDiscrete() && + worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete() ){ - currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y, worldPos.z + 1); + currentChunk = serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y, worldPos.z + 1); for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){ weights[ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(0, i, 0); types [ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = currentChunk.getType(0, i, 0); @@ -193,10 +196,10 @@ public class PhysicsDataCell { } //edge Y-Z if( - worldPos.y + 1 < Globals.serverTerrainManager.getWorldDiscreteSize() && - worldPos.z + 1 < Globals.serverTerrainManager.getWorldDiscreteSize() + worldPos.y + 1 < realm.getServerWorldData().getWorldSizeDiscrete() && + worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete() ){ - currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x, worldPos.y + 1, worldPos.z + 1); + currentChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y + 1, worldPos.z + 1); for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){ weights[i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(i, 0, 0); types [i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getType(i, 0, 0); @@ -208,11 +211,11 @@ public class PhysicsDataCell { } } if( - worldPos.z + 1 < Globals.serverTerrainManager.getWorldDiscreteSize() && - worldPos.y + 1 < Globals.serverTerrainManager.getWorldDiscreteSize() && - worldPos.z + 1 < Globals.serverTerrainManager.getWorldDiscreteSize() + worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete() && + worldPos.y + 1 < realm.getServerWorldData().getWorldSizeDiscrete() && + worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete() ){ - currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y + 1, worldPos.z + 1); + currentChunk = serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y + 1, worldPos.z + 1); weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(0, 0, 0); types[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getType(0, 0, 0); } else { diff --git a/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java b/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java index 87040348..73870c3d 100644 --- a/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java +++ b/src/main/java/electrosphere/server/fluid/manager/ServerFluidManager.java @@ -1,13 +1,11 @@ package electrosphere.server.fluid.manager; -import electrosphere.engine.Globals; +import electrosphere.game.server.world.ServerWorldData; import electrosphere.server.fluid.diskmap.FluidDiskMap; -import electrosphere.server.fluid.generation.DefaultFluidGenerator; import electrosphere.server.fluid.generation.FluidGenerator; import electrosphere.server.fluid.models.FluidModel; import electrosphere.server.fluid.simulator.ServerFluidSimulator; -import electrosphere.server.fluid.simulator.cellularautomata.FluidCellularAutomataSimulator; import electrosphere.server.terrain.manager.ServerTerrainChunk; import electrosphere.server.terrain.manager.ServerTerrainManager; import electrosphere.util.FileUtils; @@ -25,14 +23,7 @@ import org.joml.Vector3i; */ public class ServerFluidManager { - //The size of the world in discrete units * must be multiple of 200 - int worldSizeDiscrete; - - //The vertical multiplier applied to the statically generated fluid - int verticalInterpolationRatio; - - float interpolationRandomDampener; - + //the seed for the water long seed; //The model of the fluid this manager is managing @@ -61,25 +52,26 @@ public class ServerFluidManager { //controls whether fluid simulation should actually happen or not boolean simulate = true; + + /** + * The parent world data + */ + ServerWorldData parent; /** * Constructor */ public ServerFluidManager( + ServerWorldData parent, ServerTerrainManager serverTerrainManager, - int worldSizeDiscrete, - int verticalInterpolationRatio, - float interpolationRandomDampener, long seed, FluidGenerator chunkGenerator ){ + this.parent = parent; this.serverTerrainManager = serverTerrainManager; - this.worldSizeDiscrete = worldSizeDiscrete; - this.verticalInterpolationRatio = verticalInterpolationRatio; this.chunkCache = new ConcurrentHashMap(); this.chunkCacheContents = new CopyOnWriteArrayList(); - this.interpolationRandomDampener = interpolationRandomDampener; this.seed = seed; this.chunkGenerator = chunkGenerator; } @@ -88,23 +80,6 @@ public class ServerFluidManager { } - /** - * Constructs an arena fluid manager - * @return The arena fluid manager - */ - public static ServerFluidManager constructArenaFluidManager(ServerTerrainManager serverTerrainManager){ - ServerFluidManager rVal = new ServerFluidManager(); - rVal.serverTerrainManager = serverTerrainManager; - rVal.worldSizeDiscrete = 2; - rVal.verticalInterpolationRatio = 0; - rVal.chunkCache = new ConcurrentHashMap(); - rVal.chunkCacheContents = new CopyOnWriteArrayList(); - rVal.interpolationRandomDampener = 0.0f; - rVal.chunkGenerator = new DefaultFluidGenerator(); - rVal.serverFluidSimulator = new FluidCellularAutomataSimulator(); - return rVal; - } - /** * Generates a fluid model for the manager */ @@ -124,14 +99,16 @@ public class ServerFluidManager { * @param saveName The name of the save */ public void save(String saveName){ - ByteBuffer buffer = ByteBuffer.allocate(model.getElevation().length * model.getElevation()[0].length * 4); - FloatBuffer floatView = buffer.asFloatBuffer(); - for(int x = 0; x < model.getElevation().length; x++){ - floatView.put(model.getElevation()[x]); + if(model != null){ + ByteBuffer buffer = ByteBuffer.allocate(model.getElevation().length * model.getElevation()[0].length * 4); + FloatBuffer floatView = buffer.asFloatBuffer(); + for(int x = 0; x < model.getElevation().length; x++){ + floatView.put(model.getElevation()[x]); + } + floatView.flip(); + FileUtils.saveBinaryToSavePath(saveName, "./fluid.dat", buffer.array()); + FileUtils.serializeObjectToSavePath(saveName, "./fluid.json", model); } - floatView.flip(); - FileUtils.saveBinaryToSavePath(saveName, "./fluid.dat", buffer.array()); - FileUtils.serializeObjectToSavePath(saveName, "./fluid.json", model); //for each chunk, save via disk map for(String chunkKey : chunkCacheContents){ ServerFluidChunk chunk = chunkCache.get(chunkKey); @@ -154,9 +131,9 @@ public class ServerFluidManager { byte[] data = FileUtils.loadBinaryFromSavePath(saveName, "./fluid.dat"); ByteBuffer buffer = ByteBuffer.wrap(data); FloatBuffer floatView = buffer.asFloatBuffer(); - float[][] elevation = new float[Globals.serverWorldData.getWorldSizeDiscrete()][Globals.serverWorldData.getWorldSizeDiscrete()]; - for(int x = 0; x < Globals.serverWorldData.getWorldSizeDiscrete(); x++){ - for(int y = 0; y < Globals.serverWorldData.getWorldSizeDiscrete(); y++){ + float[][] elevation = new float[parent.getWorldSizeDiscrete()][parent.getWorldSizeDiscrete()]; + for(int x = 0; x < parent.getWorldSizeDiscrete(); x++){ + for(int y = 0; y < parent.getWorldSizeDiscrete(); y++){ elevation[x][y] = floatView.get(); } } @@ -174,10 +151,6 @@ public class ServerFluidManager { return y; } - public int getWorldDiscreteSize(){ - return worldSizeDiscrete; - } - public float getDiscreteValue(int x, int y){ if(model != null){ return model.getElevation()[x][y]; @@ -314,6 +287,14 @@ public class ServerFluidManager { public void setSimulate(boolean simulate){ this.simulate = simulate; } + + /** + * Sets the parent world data of this manager + * @param serverWorldData The parent world data + */ + public void setParent(ServerWorldData serverWorldData){ + this.parent = serverWorldData; + } diff --git a/src/main/java/electrosphere/server/saves/SaveUtils.java b/src/main/java/electrosphere/server/saves/SaveUtils.java index 160284d8..997a3ebf 100644 --- a/src/main/java/electrosphere/server/saves/SaveUtils.java +++ b/src/main/java/electrosphere/server/saves/SaveUtils.java @@ -3,9 +3,11 @@ package electrosphere.server.saves; import java.util.List; import electrosphere.engine.Globals; +import electrosphere.entity.scene.RealmDescriptor; +import electrosphere.entity.scene.SceneFile; +import electrosphere.entity.scene.SceneLoader; import electrosphere.game.server.world.ServerWorldData; import electrosphere.logger.LoggerInterface; -import electrosphere.server.content.ServerContentManager; import electrosphere.server.db.DatabaseUtils; import electrosphere.server.fluid.generation.DefaultFluidGenerator; import electrosphere.server.fluid.manager.ServerFluidManager; @@ -59,9 +61,10 @@ public class SaveUtils { /** * Initializes a save directory, overwrites if one is already there * @param saveName Name of the save + * @param sceneFile The scene descriptor file * @return true if initialized save, false if couldn't initialize */ - public static boolean createOrOverwriteSave(String saveName){ + public static boolean createOrOverwriteSave(String saveName, SceneFile sceneFile){ String dirPath = deriveSaveDirectoryPath(saveName); //check if exists if(FileUtils.checkFileExists(dirPath)){ @@ -81,31 +84,53 @@ public class SaveUtils { } } //create main save files - createSave(saveName); + createSave(saveName, sceneFile); return true; } /** * Creates a save * @param saveName The name of the save + * @param sceneFile The scene descriptor file * @return Returns true if the save was created successfully, returns false if the save was not created successfully */ - public static boolean createSave(String saveName){ + public static boolean createSave(String saveName, SceneFile sceneFile){ String dirPath = deriveSaveDirectoryPath(saveName); //create save file Save save = new Save(saveName); FileUtils.serializeObjectToSavePath(saveName, "/save.json", save); + //write scene file + FileUtils.serializeObjectToSavePath(saveName, "/scene.json", sceneFile); + //create server structures - Globals.serverTerrainManager = new ServerTerrainManager(ServerTerrainManager.WORLD_SIZE_DISCRETE, ServerTerrainManager.VERTICAL_INTERPOLATION_RATIO, 0, 0, new OverworldChunkGenerator()); - Globals.serverWorldData = ServerWorldData.createGameWorld(Globals.serverTerrainManager); - FileUtils.serializeObjectToSavePath(saveName, "./world.json", Globals.serverWorldData); - Globals.serverFluidManager = new ServerFluidManager(Globals.serverTerrainManager, 3, 1, 0.0f, 0, new DefaultFluidGenerator()); - if(Globals.serverTerrainManager != null){ - Globals.serverTerrainManager.save(saveName); + if(sceneFile.getRealmDescriptor().getType() == RealmDescriptor.REALM_DESCRIPTOR_PROCEDURAL){ + //generate terrain and save to disk + // + //Server world data + ServerWorldData serverWorldData = ServerWorldData.createGriddedRealmWorldData(2000); + FileUtils.serializeObjectToSavePath(saveName, "./world.json", serverWorldData); + //terrain manager + ServerTerrainManager serverTerrainManager = new ServerTerrainManager(serverWorldData, 0, new OverworldChunkGenerator()); + serverTerrainManager.generate(); + serverTerrainManager.save(saveName); + //fluid manager + ServerFluidManager serverFluidManager = new ServerFluidManager(serverWorldData, serverTerrainManager, 0, new DefaultFluidGenerator()); + serverFluidManager.generate(); + serverFluidManager.save(saveName); } else { - LoggerInterface.loggerEngine.ERROR(new IllegalStateException("Trying to create save file and server terrain manager is null!")); + //just save to disk + // + //Server world data + ServerWorldData serverWorldData = ServerWorldData.createGriddedRealmWorldData(sceneFile.getRealmDescriptor().getGriddedRealmSize()); + FileUtils.serializeObjectToSavePath(saveName, "./world.json", serverWorldData); + //terrain manager + ServerTerrainManager serverTerrainManager = new ServerTerrainManager(serverWorldData, 0, new DefaultChunkGenerator()); + serverTerrainManager.save(saveName); + //fluid manager + ServerFluidManager serverFluidManager = new ServerFluidManager(serverWorldData, serverTerrainManager, 0, new DefaultFluidGenerator()); + serverFluidManager.save(saveName); } //init db file @@ -127,10 +152,7 @@ public class SaveUtils { FileUtils.serializeObjectToSavePath(saveName, "/save.json", Globals.currentSave); //write server structures - if(Globals.serverTerrainManager != null){ - Globals.serverTerrainManager.save(saveName); - Globals.realmManager.save(saveName); - } + Globals.realmManager.save(saveName); } /** @@ -145,16 +167,6 @@ public class SaveUtils { } } - - @Deprecated - public static boolean loadTerrainAndDB(String saveName){ - String dirPath = deriveSaveDirectoryPath(saveName); - String dbFilePath = FileUtils.sanitizeFilePath(dirPath) + "/central.db"; - Globals.dbController.connect(dbFilePath); - Globals.serverTerrainManager.load(saveName); - return true; - } - /** * Loads a save into the server * @param saveName The name of the save @@ -166,21 +178,40 @@ public class SaveUtils { //load save file Globals.currentSave = FileUtils.loadObjectFromSavePath(saveName, "/save.json", Save.class); + + //load world data + ServerWorldData serverWorldData = null; + if(FileUtils.checkSavePathExists(saveName, "/world.json")){ + //load from save itself + LoggerInterface.loggerEngine.INFO("Load world data from save " + saveName); + serverWorldData = ServerWorldData.loadWorldData(saveName, false); + } else if(FileUtils.checkFileExists("/Scenes/" + saveName + "/world.json")){ + //load from defined scene + LoggerInterface.loggerEngine.INFO("Load world data from scene " + saveName); + serverWorldData = ServerWorldData.loadWorldData(saveName, true); + } else { + //The scene is neither defined in the save itself nor in the assets scene files + throw new IllegalStateException("Trying to load a save that does not contain a scene!"); + } + + //load scene file + if(FileUtils.checkSavePathExists(saveName, "/scene.json")){ + //load from save itself + LoggerInterface.loggerEngine.INFO("Load scene data from save " + saveName); + SceneLoader.serverInstantiateSaveSceneFile(saveName, serverWorldData); + } else if(FileUtils.checkFileExists("/Scenes/" + saveName)){ + //load from defined scene + LoggerInterface.loggerEngine.INFO("Load scene data from scene " + saveName); + SceneLoader.serverInstantiateAssetSceneFile(saveName, serverWorldData); + } else { + //The scene is neither defined in the save itself nor in the assets scene files + throw new IllegalStateException("Trying to load a save that does not contain a scene!"); + } + //load db String dbFilePath = FileUtils.sanitizeFilePath(dirPath) + "/central.db"; Globals.dbController.connect(dbFilePath); - //create server structures - if(!saveName.equals("arena")){ - Globals.serverWorldData = FileUtils.loadObjectFromSavePath(saveName, "world.json", ServerWorldData.class); - Globals.serverTerrainManager = new ServerTerrainManager(Globals.serverWorldData.getWorldSizeDiscrete(), 1, 0, 0, new DefaultChunkGenerator()); - Globals.serverTerrainManager.load(saveName); - Globals.serverFluidManager = new ServerFluidManager(Globals.serverTerrainManager, 2000, 50, 0, 0, new DefaultFluidGenerator()); - } - //if the scene file exists, load it - if(FileUtils.checkFileExists("assets/Scenes/" + saveName)){ - //TODO: load scene - } return true; } @@ -208,34 +239,4 @@ public class SaveUtils { return FileUtils.checkFileExists(dirPath); } - /** - * Loads terrain and creates world data object - * @param currentSaveName The save name - * @return true always - */ - public static boolean loadTerrainAndCreateWorldData(String currentSaveName){ - Globals.serverTerrainManager = new ServerTerrainManager(2000,50,0.0f,0,new OverworldChunkGenerator()); - Globals.serverFluidManager = new ServerFluidManager(Globals.serverTerrainManager, 2000, 50, 0.0f, 0, new DefaultFluidGenerator()); - SaveUtils.loadTerrainAndDB(currentSaveName); - Globals.serverWorldData = ServerWorldData.createGameWorld(Globals.serverTerrainManager); - Globals.serverContentManager = ServerContentManager.createServerContentManager(true); - Globals.realmManager.createGriddedRealm(Globals.serverWorldData); - return true; - } - - /** - * Saves world data file - * @param saveName The name of the save - * @return true always - */ - public static boolean saveWorldData(String saveName){ - /* - Globals.serverWorldData = ServerWorldData.createGameWorld(Globals.serverTerrainManager); - //TODO: Globals.dataCellManager = new DataCellManager(Globals.serverWorldData); - */ - String dirPath = deriveSaveDirectoryPath(saveName); - FileUtils.serializeObjectToFilePath(dirPath + "/world.json", Globals.serverWorldData); - return true; - } - } diff --git a/src/main/java/electrosphere/server/simulation/MacroSimulation.java b/src/main/java/electrosphere/server/simulation/MacroSimulation.java index 62395cd6..93f191b2 100644 --- a/src/main/java/electrosphere/server/simulation/MacroSimulation.java +++ b/src/main/java/electrosphere/server/simulation/MacroSimulation.java @@ -78,28 +78,28 @@ public class MacroSimulation { //TODO: Get building type to place String buildingTypeToPlace = "building1"; //try to find a place to put down a structure - int dynamicInterpRatio = Globals.serverTerrainManager.getDynamicInterpolationRatio(); - Vector2f placementPos = new Vector2f( - (float)(charPos.x * dynamicInterpRatio + Math.random() * dynamicInterpRatio), - (float)(charPos.y * dynamicInterpRatio + Math.random() * dynamicInterpRatio) - ); - int attempts = 0; - while(!VirtualStructureUtils.validStructurePlacementPosition(placementPos.x, placementPos.y, buildingTypeToPlace)){ - placementPos = new Vector2f( - (float)(charPos.x * dynamicInterpRatio + Math.random() * dynamicInterpRatio), - (float)(charPos.y * dynamicInterpRatio + Math.random() * dynamicInterpRatio) - ); - attempts++; - if(attempts > MAX_PLACE_ATTEMPTS){ - placementPos = null; - break; - } - } - if(placementPos != null){ - // Structure placedStructure = VirtualStructureUtils.placeStructureAtPoint(placementPos.x, placementPos.y, buildingTypeToPlace); - // CharacterUtils.addShelter(chara, placedStructure); - // VirtualStructureUtils.addResident(placedStructure, chara); - } + // int dynamicInterpRatio = Globals.serverTerrainManager.getDynamicInterpolationRatio(); + // Vector2f placementPos = new Vector2f( + // (float)(charPos.x * dynamicInterpRatio + Math.random() * dynamicInterpRatio), + // (float)(charPos.y * dynamicInterpRatio + Math.random() * dynamicInterpRatio) + // ); + // int attempts = 0; + // while(!VirtualStructureUtils.validStructurePlacementPosition(placementPos.x, placementPos.y, buildingTypeToPlace)){ + // placementPos = new Vector2f( + // (float)(charPos.x * dynamicInterpRatio + Math.random() * dynamicInterpRatio), + // (float)(charPos.y * dynamicInterpRatio + Math.random() * dynamicInterpRatio) + // ); + // attempts++; + // if(attempts > MAX_PLACE_ATTEMPTS){ + // placementPos = null; + // break; + // } + // } + // if(placementPos != null){ + // // Structure placedStructure = VirtualStructureUtils.placeStructureAtPoint(placementPos.x, placementPos.y, buildingTypeToPlace); + // // CharacterUtils.addShelter(chara, placedStructure); + // // VirtualStructureUtils.addResident(placedStructure, chara); + // } } } // } diff --git a/src/main/java/electrosphere/server/terrain/editing/TerrainEditing.java b/src/main/java/electrosphere/server/terrain/editing/TerrainEditing.java index 1632bbf8..bfc31ef6 100644 --- a/src/main/java/electrosphere/server/terrain/editing/TerrainEditing.java +++ b/src/main/java/electrosphere/server/terrain/editing/TerrainEditing.java @@ -3,7 +3,6 @@ package electrosphere.server.terrain.editing; import org.joml.Vector3d; import org.joml.Vector3i; -import electrosphere.engine.Globals; import electrosphere.server.datacell.Realm; import electrosphere.server.datacell.interfaces.VoxelCellManager; import electrosphere.server.terrain.manager.ServerTerrainChunk; @@ -46,8 +45,8 @@ public class TerrainEditing { for(i = 0; i < numPlacesToCheck; i++){ //calculate position of edit Vector3d offsetPos = new Vector3d(position).add(xOffsetSet[i],yOffsetSet[i],zOffsetSet[i]); - Vector3i chunkPos = Globals.serverWorldData.convertRealToWorldSpace(offsetPos); - Vector3i voxelPos = Globals.serverWorldData.convertRealToVoxelSpace(offsetPos); + Vector3i chunkPos = realm.getServerWorldData().convertRealToWorldSpace(offsetPos); + Vector3i voxelPos = realm.getServerWorldData().convertRealToVoxelSpace(offsetPos); //get distance from true center point of sphere to current voxel position in world space float distance = (float)new Vector3d(Math.floor(offsetPos.x),Math.floor(offsetPos.y),Math.floor(offsetPos.z)).distance(position); float currentPositionMagnitude = editMagnitude - distance; diff --git a/src/main/java/electrosphere/server/terrain/manager/ServerTerrainManager.java b/src/main/java/electrosphere/server/terrain/manager/ServerTerrainManager.java index 749cddf9..20ef9d8a 100644 --- a/src/main/java/electrosphere/server/terrain/manager/ServerTerrainManager.java +++ b/src/main/java/electrosphere/server/terrain/manager/ServerTerrainManager.java @@ -1,8 +1,7 @@ package electrosphere.server.terrain.manager; -import electrosphere.engine.Globals; +import electrosphere.game.server.world.ServerWorldData; import electrosphere.server.terrain.diskmap.ChunkDiskMap; -import electrosphere.server.terrain.generation.DefaultChunkGenerator; import electrosphere.server.terrain.generation.continentphase.TerrainGenerator; import electrosphere.server.terrain.generation.interfaces.ChunkGenerator; import electrosphere.server.terrain.models.TerrainModel; @@ -34,15 +33,18 @@ public class ServerTerrainManager { //the interpolation width of a server terrain manager is hard coded at the moment to make sure it's divisible by the sub chunk calculations public static final int SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO = 128; + + /** + * The dampening ratio for ground noise + */ + public static final float SERVER_TERRAIN_MANAGER_DAMPENER = 1.0f; - //The size of the world in discrete units * must be multiple of 200 - int worldSizeDiscrete; - - //The vertical multiplier applied to the statically generated terrain - int verticalInterpolationRatio; - - float interpolationRandomDampener; - + /** + * The parent world data + */ + ServerWorldData parent; + + //the seed for terrain generation long seed; //The model of the terrain this manager is managing @@ -68,17 +70,13 @@ public class ServerTerrainManager { * Constructor */ public ServerTerrainManager( - int worldSizeDiscrete, - int verticalInterpolationRatio, - float interpolationRandomDampener, + ServerWorldData parent, long seed, ChunkGenerator chunkGenerator ){ - this.worldSizeDiscrete = worldSizeDiscrete; - this.verticalInterpolationRatio = verticalInterpolationRatio; + this.parent = parent; this.chunkCache = new ConcurrentHashMap(); this.chunkCacheContents = new CopyOnWriteArrayList(); - this.interpolationRandomDampener = interpolationRandomDampener; this.seed = seed; this.chunkGenerator = chunkGenerator; } @@ -87,32 +85,17 @@ public class ServerTerrainManager { } - /** - * Constructs an arena terrain manager - * @return The arena terrain manager - */ - public static ServerTerrainManager constructArenaTerrainManager(){ - ServerTerrainManager rVal = new ServerTerrainManager(); - rVal.worldSizeDiscrete = 2; - rVal.verticalInterpolationRatio = 0; - rVal.chunkCache = new ConcurrentHashMap(); - rVal.chunkCacheContents = new CopyOnWriteArrayList(); - rVal.interpolationRandomDampener = 0.0f; - rVal.chunkGenerator = new DefaultChunkGenerator(); - return rVal; - } - /** * Generates a terrain model for the manager */ public void generate(){ TerrainGenerator terrainGen = new TerrainGenerator(); - terrainGen.setInterpolationRatio(worldSizeDiscrete/200); - terrainGen.setVerticalInterpolationRatio(verticalInterpolationRatio); + terrainGen.setInterpolationRatio(parent.getWorldSizeDiscrete()/200); + terrainGen.setVerticalInterpolationRatio(parent.getWorldSizeDiscrete()); terrainGen.setRandomSeed(seed); model = terrainGen.generateModel(); this.chunkGenerator.setModel(model); - model.setInterpolationRandomDampener(interpolationRandomDampener); + model.setInterpolationRandomDampener(SERVER_TERRAIN_MANAGER_DAMPENER); this.chunkDiskMap = new ChunkDiskMap(); } @@ -154,9 +137,9 @@ public class ServerTerrainManager { byte[] data = FileUtils.loadBinaryFromSavePath(saveName, "./terrain.dat"); ByteBuffer buffer = ByteBuffer.wrap(data); FloatBuffer floatView = buffer.asFloatBuffer(); - float[][] elevation = new float[Globals.serverWorldData.getWorldSizeDiscrete()][Globals.serverWorldData.getWorldSizeDiscrete()]; - for(int x = 0; x < Globals.serverWorldData.getWorldSizeDiscrete(); x++){ - for(int y = 0; y < Globals.serverWorldData.getWorldSizeDiscrete(); y++){ + float[][] elevation = new float[parent.getWorldSizeDiscrete()][parent.getWorldSizeDiscrete()]; + for(int x = 0; x < parent.getWorldSizeDiscrete(); x++){ + for(int y = 0; y < parent.getWorldSizeDiscrete(); y++){ elevation[x][y] = floatView.get(); } } @@ -175,10 +158,6 @@ public class ServerTerrainManager { return y; } - public int getWorldDiscreteSize(){ - return worldSizeDiscrete; - } - public float getDiscreteValue(int x, int y){ if(model != null){ return model.getElevation()[x][y]; @@ -293,5 +272,13 @@ public class ServerTerrainManager { chunk.addModification(modification); } } + + /** + * Sets the parent world data of this manager + * @param serverWorldData The parent world data + */ + public void setParent(ServerWorldData serverWorldData){ + this.parent = serverWorldData; + } } diff --git a/src/main/java/electrosphere/util/worldviewer/TerrainViewer.java b/src/main/java/electrosphere/util/worldviewer/TerrainViewer.java index 7f103a1c..50990203 100644 --- a/src/main/java/electrosphere/util/worldviewer/TerrainViewer.java +++ b/src/main/java/electrosphere/util/worldviewer/TerrainViewer.java @@ -1,5 +1,6 @@ package electrosphere.util.worldviewer; +import electrosphere.game.server.world.ServerWorldData; import electrosphere.server.simulation.MacroSimulation; import electrosphere.server.terrain.generation.OverworldChunkGenerator; import electrosphere.server.terrain.manager.ServerTerrainManager; @@ -19,7 +20,8 @@ public class TerrainViewer { TerrainModel terrainModel; - ServerTerrainManager terrainManager = new ServerTerrainManager(2000, 1000, 0.05f, new Random().nextLong(), new OverworldChunkGenerator()); + ServerWorldData worldData = ServerWorldData.createGriddedRealmWorldData(2000); + ServerTerrainManager terrainManager = new ServerTerrainManager(worldData, new Random().nextLong(), new OverworldChunkGenerator()); terrainManager.generate(); terrainModel = terrainManager.getModel();