diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index c6f547e9..ca69282d 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1524,6 +1524,12 @@ Fix jump trees not enabling physics body Priority based foliage content placement Hide cursor by default +(04/25/2025) +Macro data unloading/loading +Macro Character data serialization/deserialization +Macro character compression/decompression on chunk load/unload +ServerWorldData conversion methods are static now + diff --git a/src/main/java/electrosphere/client/ui/menu/debug/ImGuiPlayerEntity.java b/src/main/java/electrosphere/client/ui/menu/debug/ImGuiPlayerEntity.java index f3726c48..573bc6a0 100644 --- a/src/main/java/electrosphere/client/ui/menu/debug/ImGuiPlayerEntity.java +++ b/src/main/java/electrosphere/client/ui/menu/debug/ImGuiPlayerEntity.java @@ -1,5 +1,6 @@ package electrosphere.client.ui.menu.debug; +import org.joml.Vector3d; import org.ode4j.ode.DBody; import electrosphere.client.entity.camera.CameraEntityUtils; @@ -38,7 +39,8 @@ public class ImGuiPlayerEntity { //data about player entity if(Globals.playerEntity != null){ - ImGui.text("Position: " + EntityUtils.getPosition(Globals.playerEntity)); + Vector3d clientEntityPos = EntityUtils.getPosition(Globals.playerEntity); + ImGui.text("Position: " + String.format("%.2f",clientEntityPos.x) + " " + String.format("%.2f",clientEntityPos.y) + " " + String.format("%.2f",clientEntityPos.z)); ImGui.text("Rotation: " + EntityUtils.getRotation(Globals.playerEntity)); //physics on client diff --git a/src/main/java/electrosphere/entity/scene/SceneLoader.java b/src/main/java/electrosphere/entity/scene/SceneLoader.java index b6a832ef..af15fdec 100644 --- a/src/main/java/electrosphere/entity/scene/SceneLoader.java +++ b/src/main/java/electrosphere/entity/scene/SceneLoader.java @@ -12,6 +12,8 @@ import electrosphere.server.datacell.Realm; import electrosphere.server.datacell.ServerWorldData; import electrosphere.server.datacell.gridded.GriddedDataCellManager; import electrosphere.server.entity.ServerContentManager; +import electrosphere.server.macro.MacroData; +import electrosphere.server.macro.MacroDataLoader; import electrosphere.server.physics.terrain.generation.DefaultChunkGenerator; import electrosphere.server.physics.terrain.manager.ServerTerrainChunk; import electrosphere.util.FileUtils; @@ -30,8 +32,20 @@ public class SceneLoader { public static void serverInstantiateSaveSceneFile(String saveName, ServerWorldData serverWorldData, boolean isLevelEditor){ //load scene file SceneFile file = FileUtils.loadObjectFromSavePath(saveName, "/scene.json", SceneFile.class); + + // + //Load macro data + // + MacroData macroData = null; + if( + file.realmDescriptor.getType().matches(RealmDescriptor.REALM_DESCRIPTOR_PROCEDURAL) || + file.realmDescriptor.getType().matches(RealmDescriptor.REALM_DESCRIPTOR_GENERATION_TESTING) + ){ + macroData = MacroDataLoader.loadFromSave(saveName); + } + //instantiate scene data - serverInstantiateSceneFile(file,serverWorldData,isLevelEditor); + serverInstantiateSceneFile(file,macroData,serverWorldData,isLevelEditor); } /** @@ -45,7 +59,7 @@ public class SceneLoader { String sanitizedPath = FileUtils.sanitizeFilePath("/Scenes/" + sceneName + "/scene.json"); SceneFile file = FileUtils.loadObjectFromAssetPath(sanitizedPath, SceneFile.class); //instantiate scene data - serverInstantiateSceneFile(file,serverWorldData,isLevelEditor); + serverInstantiateSceneFile(file,null,serverWorldData,isLevelEditor); } /** @@ -53,7 +67,7 @@ public class SceneLoader { * @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, boolean isLevelEditor){ + private static void serverInstantiateSceneFile(SceneFile file, MacroData macroData, ServerWorldData serverWorldData, boolean isLevelEditor){ // //Content manager @@ -63,9 +77,9 @@ public class SceneLoader { file.realmDescriptor.getType().matches(RealmDescriptor.REALM_DESCRIPTOR_PROCEDURAL) || file.realmDescriptor.getType().matches(RealmDescriptor.REALM_DESCRIPTOR_GENERATION_TESTING) ){ - serverContentManager = ServerContentManager.createServerContentManager(true); + serverContentManager = ServerContentManager.createServerContentManager(true,macroData); } else { - serverContentManager = ServerContentManager.createServerContentManager(false); + serverContentManager = ServerContentManager.createServerContentManager(false,macroData); } // diff --git a/src/main/java/electrosphere/server/datacell/Realm.java b/src/main/java/electrosphere/server/datacell/Realm.java index 9701c0bb..33bdb768 100644 --- a/src/main/java/electrosphere/server/datacell/Realm.java +++ b/src/main/java/electrosphere/server/datacell/Realm.java @@ -260,6 +260,9 @@ public class Realm { protected void save(String saveName){ dataCellManager.save(saveName); serverWorldData.getServerTerrainManager().save(saveName); + if(serverContentManager.getMacroData() != null){ + serverContentManager.getMacroData().save(saveName); + } } /** diff --git a/src/main/java/electrosphere/server/datacell/RealmManager.java b/src/main/java/electrosphere/server/datacell/RealmManager.java index 92ac63bc..b25b8fdc 100644 --- a/src/main/java/electrosphere/server/datacell/RealmManager.java +++ b/src/main/java/electrosphere/server/datacell/RealmManager.java @@ -66,7 +66,7 @@ public class RealmManager { new CollisionEngine(), chemistryEngine, new HitboxManager(new ServerHitboxResolutionCallback()), - ServerContentManager.createServerContentManager(false) + ServerContentManager.createServerContentManager(false, null) ); } @@ -123,7 +123,7 @@ public class RealmManager { collisionEngine, chemistryEngine, new HitboxManager(new ServerHitboxResolutionCallback()), - ServerContentManager.createServerContentManager(false) + ServerContentManager.createServerContentManager(false, null) ); //add function classes to realm diff --git a/src/main/java/electrosphere/server/datacell/ServerWorldData.java b/src/main/java/electrosphere/server/datacell/ServerWorldData.java index fdb20af1..54623bd0 100644 --- a/src/main/java/electrosphere/server/datacell/ServerWorldData.java +++ b/src/main/java/electrosphere/server/datacell/ServerWorldData.java @@ -201,14 +201,27 @@ public class ServerWorldData { return dynamicInterpolationRatio; } - public int convertRealToChunkSpace(double real){ + public static int convertRealToChunkSpace(double real){ return (int)Math.floor(real / ServerTerrainChunk.CHUNK_DIMENSION); } - public float convertChunkToRealSpace(int chunk){ + public static float convertChunkToRealSpace(int chunk){ return chunk * ServerTerrainChunk.CHUNK_DIMENSION; } + /** + * Converts a chunk space position to a real space position + * @param chunk The chunk space position + * @return The real space position + */ + public static Vector3d convertChunkToRealSpace(Vector3i chunk){ + return new Vector3d( + ServerWorldData.convertChunkToRealSpace(chunk.x), + ServerWorldData.convertChunkToRealSpace(chunk.y), + ServerWorldData.convertChunkToRealSpace(chunk.z) + ); + } + /** * Converts a real position to a local block grid position * @param real The real position @@ -245,11 +258,11 @@ public class ServerWorldData { return convertChunkToRealSpace(world); } - public Vector3i convertRealToChunkSpace(Vector3d position){ + public static Vector3i convertRealToChunkSpace(Vector3d position){ return new Vector3i( - convertRealToChunkSpace(position.x), - convertRealToChunkSpace(position.y), - convertRealToChunkSpace(position.z) + ServerWorldData.convertRealToChunkSpace(position.x), + ServerWorldData.convertRealToChunkSpace(position.y), + ServerWorldData.convertRealToChunkSpace(position.z) ); } @@ -266,7 +279,7 @@ public class ServerWorldData { ); } - public Vector3i convertRealToVoxelSpace(Vector3d position){ + public static Vector3i convertRealToVoxelSpace(Vector3d position){ return new Vector3i( (int)Math.floor(position.x - convertChunkToRealSpace(convertRealToChunkSpace(position.x))), (int)Math.floor(position.y - convertChunkToRealSpace(convertRealToChunkSpace(position.y))), diff --git a/src/main/java/electrosphere/server/datacell/gridded/GriddedDataCellManager.java b/src/main/java/electrosphere/server/datacell/gridded/GriddedDataCellManager.java index a844aed5..df0a2e25 100644 --- a/src/main/java/electrosphere/server/datacell/gridded/GriddedDataCellManager.java +++ b/src/main/java/electrosphere/server/datacell/gridded/GriddedDataCellManager.java @@ -386,9 +386,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 = parent.getServerWorldData().convertRealToChunkSpace(position.x); - int currentWorldY = parent.getServerWorldData().convertRealToChunkSpace(position.y); - int currentWorldZ = parent.getServerWorldData().convertRealToChunkSpace(position.z); + int currentWorldX = ServerWorldData.convertRealToChunkSpace(position.x); + int currentWorldY = ServerWorldData.convertRealToChunkSpace(position.y); + int currentWorldZ = ServerWorldData.convertRealToChunkSpace(position.z); Vector3i newPosition = new Vector3i(currentWorldX,currentWorldY,currentWorldZ); player.setWorldPos(newPosition); @@ -583,9 +583,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager */ public ServerDataCell getDataCellAtPoint(Vector3d point){ ServerDataCell rVal = null; - int worldX = parent.getServerWorldData().convertRealToChunkSpace(point.x); - int worldY = parent.getServerWorldData().convertRealToChunkSpace(point.y); - int worldZ = parent.getServerWorldData().convertRealToChunkSpace(point.z); + int worldX = ServerWorldData.convertRealToChunkSpace(point.x); + int worldY = ServerWorldData.convertRealToChunkSpace(point.y); + int worldZ = ServerWorldData.convertRealToChunkSpace(point.z); Vector3i worldPos = new Vector3i(worldX,worldY,worldZ); if( //in bounds of array @@ -609,9 +609,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager * @return The data cell if created, null otherwise */ public ServerDataCell tryCreateCellAtPoint(Vector3d point){ - int worldX = parent.getServerWorldData().convertRealToChunkSpace(point.x); - int worldY = parent.getServerWorldData().convertRealToChunkSpace(point.y); - int worldZ = parent.getServerWorldData().convertRealToChunkSpace(point.z); + int worldX = ServerWorldData.convertRealToChunkSpace(point.x); + int worldY = ServerWorldData.convertRealToChunkSpace(point.y); + int worldZ = ServerWorldData.convertRealToChunkSpace(point.z); Vector3i worldPos = new Vector3i(worldX,worldY,worldZ); return tryCreateCellAtPoint(worldPos); } diff --git a/src/main/java/electrosphere/server/entity/ServerContentManager.java b/src/main/java/electrosphere/server/entity/ServerContentManager.java index 8434b041..1758dd06 100644 --- a/src/main/java/electrosphere/server/entity/ServerContentManager.java +++ b/src/main/java/electrosphere/server/entity/ServerContentManager.java @@ -7,33 +7,44 @@ import org.joml.Vector3i; import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.state.server.ServerCharacterData; +import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.server.character.CharacterService; import electrosphere.server.datacell.Realm; import electrosphere.server.datacell.ServerDataCell; import electrosphere.server.entity.serialization.ContentSerialization; +import electrosphere.server.macro.MacroData; import electrosphere.server.saves.SaveUtils; import electrosphere.util.FileUtils; import electrosphere.util.math.HashUtils; +import electrosphere.server.macro.character.Character; +import electrosphere.server.macro.race.Race; public class ServerContentManager { //controls whether the manager should generate content on loading a new scene boolean generateContent = false; + /** + * The macro data for the content manager + */ + MacroData macroData; + /** * Constructor */ - private ServerContentManager(boolean generateContent){ + private ServerContentManager(boolean generateContent, MacroData macroData){ this.generateContent = generateContent; + this.macroData = macroData; } /** * Creates a server content manager * @param generateContent if true, will generate content on loading a new scene, otherwise will not + * @param macroData The macro data * @return The server content manager */ - public static ServerContentManager createServerContentManager(boolean generateContent){ - return new ServerContentManager(generateContent); + public static ServerContentManager createServerContentManager(boolean generateContent, MacroData macroData){ + return new ServerContentManager(generateContent, macroData); } /** @@ -41,6 +52,7 @@ public class ServerContentManager { * @param realm The realm * @param worldPos The world position * @param cell The cell + * @param cellKey The key for this cell */ public void generateContentForDataCell(Realm realm, Vector3i worldPos, ServerDataCell cell, Long cellKey){ Globals.profiler.beginCpuSample("ServerContentManager.generateContentForDataCell"); @@ -62,15 +74,19 @@ public class ServerContentManager { contentRaw.hydrateRawContent(realm,cell); } } - //TODO: generate navmesh - // cell.setNavMesh( - // NavMeshUtils.createMeshFromChunk(Globals.serverTerrainManager.getChunk( - // worldPos.x, - // worldPos.y, - // worldPos.z - // ), - // Globals.navMeshManager.getBlockerCache().getBlocker(worldPos.x, worldPos.z)) - // ); + //checking for null because there are cases where we might not have macro data to instantiate from + //ie, if we load an asset-defined (not save-defined) scene that does not have save data + //ie, imagine a puzzle room or something like that + if(macroData != null){ + for(Character character : macroData.getCharacters(worldPos)){ + if(Race.hasRace(character)){ + Race race = Race.getRace(character); + String creatureName = race.getAssociatedCreature(); + //place macro object + CreatureUtils.serverSpawnBasicCreature(realm, character.getPos(), creatureName, null); + } + } + } Globals.profiler.endCpuSample(); } @@ -105,5 +121,13 @@ public class ServerContentManager { FileUtils.serializeObjectToFilePath(fullPath, serialization); } + /** + * Gets the macro data + * @return The macro data + */ + public MacroData getMacroData(){ + return macroData; + } + } diff --git a/src/main/java/electrosphere/server/macro/MacroData.java b/src/main/java/electrosphere/server/macro/MacroData.java index ab5b3f73..bfe42bb5 100644 --- a/src/main/java/electrosphere/server/macro/MacroData.java +++ b/src/main/java/electrosphere/server/macro/MacroData.java @@ -5,6 +5,7 @@ import java.util.List; import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; +import electrosphere.server.datacell.ServerWorldData; import electrosphere.server.macro.character.Character; import electrosphere.server.macro.character.CharacterDataStrings; import electrosphere.server.macro.character.CharacterUtils; @@ -15,9 +16,13 @@ import electrosphere.server.macro.race.RaceMap; import electrosphere.server.macro.structure.Structure; import electrosphere.server.macro.symbolism.Symbol; import electrosphere.server.macro.town.Town; +import electrosphere.util.FileUtils; import java.util.Random; +import org.joml.Vector3d; +import org.joml.Vector3i; + /** * Server macro level data */ @@ -97,6 +102,12 @@ public class MacroData { } } + //add a test character + Character testChar = new Character(); + testChar.setPos(new Vector3d(ServerWorldData.convertChunkToRealSpace(new Vector3i(32774, 3, 32769)))); + Race.setRace(testChar, Race.create("human", "human")); + rVal.characters.add(testChar); + //spawn initial characters in each race //find initial positions to place characters at per race //generate initial characters @@ -142,6 +153,14 @@ public class MacroData { return rVal; } + /** + * Saves this macro data to a save path + * @param saveName The name of the save + */ + public void save(String saveName){ + FileUtils.serializeObjectToSavePath(saveName, "./macro.json", this); + } + /** * Generates an initial diety * @param seed The seed @@ -224,7 +243,7 @@ public class MacroData { LoggerInterface.loggerEngine.WARNING("Diety"); Diety diety = CharacterUtils.getDiety(chara); for(Symbol symbol : diety.getSymbols()){ - System.out.print(symbol.getName() + " "); + LoggerInterface.loggerEngine.WARNING(symbol.getName() + " "); } LoggerInterface.loggerEngine.WARNING("\n"); } @@ -238,7 +257,7 @@ public class MacroData { //n*m complexity - yikes! - as long as we're not making a million chars at start this should be _ok_ for(Character chara : characters){ if(chara.containsKey(CharacterDataStrings.RACE)){ - if(CharacterUtils.getRace(chara).equals(race)){ + if(Race.getRace(chara).equals(race)){ numCharsOfRace++; } } @@ -248,5 +267,21 @@ public class MacroData { } LoggerInterface.loggerEngine.WARNING("=========================="); } + + + /** + * Gets the characters at a given world position + * @param worldPos The world position + * @return The list of characters occupying that world position + */ + public List getCharacters(Vector3i worldPos){ + List rVal = new LinkedList(); + for(Character character : this.characters){ + if(ServerWorldData.convertRealToChunkSpace(character.getPos()).equals(worldPos.x, worldPos.y, worldPos.z)){ + rVal.add(character); + } + } + return rVal; + } } diff --git a/src/main/java/electrosphere/server/macro/MacroDataLoader.java b/src/main/java/electrosphere/server/macro/MacroDataLoader.java new file mode 100644 index 00000000..ad40b5c6 --- /dev/null +++ b/src/main/java/electrosphere/server/macro/MacroDataLoader.java @@ -0,0 +1,20 @@ +package electrosphere.server.macro; + +import electrosphere.util.FileUtils; + +/** + * Loads macro data + */ +public class MacroDataLoader { + + /** + * Loads macro data from a save + * @param saveName The name of the save + * @return The macro data + */ + public static MacroData loadFromSave(String saveName){ + MacroData rVal = FileUtils.loadObjectFromSavePath(saveName, "macro.json", MacroData.class); + return rVal; + } + +} diff --git a/src/main/java/electrosphere/server/macro/character/Character.java b/src/main/java/electrosphere/server/macro/character/Character.java index 4118db4a..f67abaf2 100644 --- a/src/main/java/electrosphere/server/macro/character/Character.java +++ b/src/main/java/electrosphere/server/macro/character/Character.java @@ -3,12 +3,21 @@ package electrosphere.server.macro.character; import java.util.HashMap; import java.util.Map; -public class Character { +import org.joml.Vector3d; + +import electrosphere.server.macro.spatial.MacroObject; + +/** + * A character + */ +public class Character implements MacroObject { static int character_id_iterator = 0; int id; - Map data = new HashMap(); + Map data = new HashMap(); + + Vector3d pos = new Vector3d(); @@ -20,20 +29,30 @@ public class Character { this.id = id; } - public void putData(String key, Object o){ - data.put(key,o); + public void putData(String key, CharacterData item){ + data.put(key,item); } public boolean containsKey(String key){ return data.containsKey(key); } - public Object getData(String key){ + public CharacterData getData(String key){ return data.get(key); } public Character(){ } + + @Override + public Vector3d getPos() { + return this.pos; + } + + @Override + public void setPos(Vector3d pos) { + this.pos.set(pos); + } } diff --git a/src/main/java/electrosphere/server/macro/character/CharacterData.java b/src/main/java/electrosphere/server/macro/character/CharacterData.java new file mode 100644 index 00000000..0abee20d --- /dev/null +++ b/src/main/java/electrosphere/server/macro/character/CharacterData.java @@ -0,0 +1,29 @@ +package electrosphere.server.macro.character; + +/** + * A type of data for a character + */ +public abstract class CharacterData { + + /** + * The type of data + */ + String dataType; + + /** + * Constructor + * @param dataType The type of data + */ + public CharacterData(String dataType){ + this.dataType = dataType; + } + + /** + * Gets the type of the data + * @return The type of data + */ + public String getDataType(){ + return this.dataType; + } + +} diff --git a/src/main/java/electrosphere/server/macro/character/CharacterDataSerializer.java b/src/main/java/electrosphere/server/macro/character/CharacterDataSerializer.java new file mode 100644 index 00000000..9f9a8b36 --- /dev/null +++ b/src/main/java/electrosphere/server/macro/character/CharacterDataSerializer.java @@ -0,0 +1,47 @@ +package electrosphere.server.macro.character; + +import java.lang.reflect.Type; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; + +import electrosphere.server.macro.character.diety.Diety; +import electrosphere.server.macro.race.Race; +import electrosphere.server.macro.structure.Structure; +import electrosphere.server.macro.town.Town; + +/** + * Deserializes noise modules + */ +public class CharacterDataSerializer implements JsonDeserializer { + + @Override + public CharacterData deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + switch(json.getAsJsonObject().get("dataType").getAsString()){ + + //race + case CharacterDataStrings.RACE: { + return context.deserialize(json, Race.class); + } + + //diety data + case CharacterDataStrings.DIETY: { + return context.deserialize(json, Diety.class); + } + + //a structure + case CharacterDataStrings.STRUCTURE: { + return context.deserialize(json, Structure.class); + } + + //a town + case CharacterDataStrings.TOWN: { + return context.deserialize(json, Town.class); + } + } + return null; + } + +} diff --git a/src/main/java/electrosphere/server/macro/character/CharacterDataStrings.java b/src/main/java/electrosphere/server/macro/character/CharacterDataStrings.java index 937ac7c7..4b414905 100644 --- a/src/main/java/electrosphere/server/macro/character/CharacterDataStrings.java +++ b/src/main/java/electrosphere/server/macro/character/CharacterDataStrings.java @@ -11,6 +11,8 @@ public class CharacterDataStrings { public static final String PERSONALITY_ADVANCED = "personalityAdvanced"; public static final String RACE = "race"; public static final String SHELTER = "shelter"; + public static final String STRUCTURE = "structure"; public static final String HOMETOWN = "hometown"; + public static final String TOWN = "town"; } diff --git a/src/main/java/electrosphere/server/macro/character/CharacterUtils.java b/src/main/java/electrosphere/server/macro/character/CharacterUtils.java index 8dd08a0d..053175e4 100644 --- a/src/main/java/electrosphere/server/macro/character/CharacterUtils.java +++ b/src/main/java/electrosphere/server/macro/character/CharacterUtils.java @@ -1,41 +1,32 @@ package electrosphere.server.macro.character; import electrosphere.server.macro.character.diety.Diety; -import electrosphere.server.macro.race.Race; import electrosphere.server.macro.structure.Structure; import electrosphere.server.macro.town.Town; -import org.joml.Vector2i; - /** * Utility functions for dealing with characters */ public class CharacterUtils { - public static void addDiscretePosition(Character character, int posX, int posY){ - character.putData(CharacterDataStrings.POSITION_DISCRETE, new Vector2i(posX,posY)); - } - - public static Vector2i getDiscretePosition(Character character){ - return (Vector2i)character.getData(CharacterDataStrings.POSITION_DISCRETE); - } - + /** + * Adds diety data for the character + * @param character The character + * @param diety The diety data + */ public static void addDiety(Character character, Diety diety){ character.putData(CharacterDataStrings.DIETY, diety); } + /** + * Gets diety data for the character + * @param character The character + * @return The diety data + */ public static Diety getDiety(Character character){ return (Diety)character.getData(CharacterDataStrings.DIETY); } - public static void addRace(Character character, Race race){ - character.putData(CharacterDataStrings.RACE, race); - } - - public static Race getRace(Character character){ - return (Race)character.getData(CharacterDataStrings.RACE); - } - public static void addShelter(Character character, Structure shelter){ character.putData(CharacterDataStrings.SHELTER, shelter); } diff --git a/src/main/java/electrosphere/server/macro/character/diety/Diety.java b/src/main/java/electrosphere/server/macro/character/diety/Diety.java index f6e4f4c0..0117184a 100644 --- a/src/main/java/electrosphere/server/macro/character/diety/Diety.java +++ b/src/main/java/electrosphere/server/macro/character/diety/Diety.java @@ -1,6 +1,8 @@ package electrosphere.server.macro.character.diety; import electrosphere.engine.Globals; +import electrosphere.server.macro.character.CharacterData; +import electrosphere.server.macro.character.CharacterDataStrings; import electrosphere.server.macro.symbolism.Symbol; import electrosphere.server.macro.symbolism.SymbolMap; @@ -8,12 +10,22 @@ import java.util.LinkedList; import java.util.List; import java.util.Random; -public class Diety { +/** + * Data defining this character as a diety + */ +public class Diety extends CharacterData { List symbols = new LinkedList(); //TODO: eventually add function where we can pass intial symbol to seed rest of diety off of //this lets us create a "good" diety" and a "bad" diety to guarentee a more balanced pantheon + + /** + * Constructor + */ + private Diety(){ + super(CharacterDataStrings.DIETY); + } public static Diety generateDiety(long seed){ Random random = new Random(); diff --git a/src/main/java/electrosphere/server/macro/race/Race.java b/src/main/java/electrosphere/server/macro/race/Race.java index 3cf5f765..525d832e 100644 --- a/src/main/java/electrosphere/server/macro/race/Race.java +++ b/src/main/java/electrosphere/server/macro/race/Race.java @@ -1,21 +1,85 @@ package electrosphere.server.macro.race; +import electrosphere.server.macro.character.CharacterDataStrings; +import electrosphere.server.macro.character.Character; +import electrosphere.server.macro.character.CharacterData; + /** * The race of a creature */ -public class Race { +public class Race extends CharacterData { + /** + * The name of the race + */ String name; + + /** + * The associated creature for the race + */ String associatedCreature; + /** + * Constructor + */ + private Race(){ + super(CharacterDataStrings.RACE); + } + + /** + * Gets the name of the race + * @return The name of the race + */ public String getName() { return name; } + /** + * Gets the associated creature data for the race + * @return The associated creature data + */ public String getAssociatedCreature() { return associatedCreature; } + + /** + * Creates a race + * @param name The name of the race + * @param creatureName The name of the creature associated with the race + * @return The race + */ + public static Race create(String name, String creatureName){ + Race race = new Race(); + race.name = name; + race.associatedCreature = creatureName; + return race; + } + + /** + * Sets race data for the character + * @param character The character + * @param race The race data for the character + */ + public static void setRace(Character character, Race race){ + character.putData(CharacterDataStrings.RACE, race); + } - + /** + * Gets race data for the character + * @param character The character + * @return The race data + */ + public static Race getRace(Character character){ + return (Race)character.getData(CharacterDataStrings.RACE); + } + + /** + * Checks if a character has race data + * @param character The character + * @return true if it has race data, false otherwise + */ + public static boolean hasRace(Character character){ + return character.containsKey(CharacterDataStrings.RACE); + } } diff --git a/src/main/java/electrosphere/server/macro/spatial/MacroObject.java b/src/main/java/electrosphere/server/macro/spatial/MacroObject.java new file mode 100644 index 00000000..95da4f90 --- /dev/null +++ b/src/main/java/electrosphere/server/macro/spatial/MacroObject.java @@ -0,0 +1,22 @@ +package electrosphere.server.macro.spatial; + +import org.joml.Vector3d; + +/** + * Interface for a macro object that has a spatial position + */ +public interface MacroObject { + + /** + * Gets the position of this object + * @return The position of this object + */ + public Vector3d getPos(); + + /** + * Sets the position of this macro object + * @param pos The macro object + */ + public void setPos(Vector3d pos); + +} diff --git a/src/main/java/electrosphere/server/macro/structure/Structure.java b/src/main/java/electrosphere/server/macro/structure/Structure.java index 78af09c8..7353cda8 100644 --- a/src/main/java/electrosphere/server/macro/structure/Structure.java +++ b/src/main/java/electrosphere/server/macro/structure/Structure.java @@ -4,10 +4,13 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import electrosphere.server.macro.character.CharacterData; +import electrosphere.server.macro.character.CharacterDataStrings; + /** * Server representation of a structure */ -public class Structure { +public class Structure extends CharacterData { int worldX; int worldY; float locationX; @@ -19,6 +22,7 @@ public class Structure { LinkedList dataKeys = new LinkedList(); public Structure(int worldX, int worldY, float locationX, float locationY, String type) { + super(CharacterDataStrings.STRUCTURE); this.worldX = worldX; this.worldY = worldY; this.locationX = locationX; @@ -58,6 +62,11 @@ public class Structure { public String getType() { return type; } + + @Override + public String getDataType() { + return CharacterDataStrings.HOMETOWN; + } diff --git a/src/main/java/electrosphere/server/macro/town/Town.java b/src/main/java/electrosphere/server/macro/town/Town.java index 2a158c0a..b1eb12d7 100644 --- a/src/main/java/electrosphere/server/macro/town/Town.java +++ b/src/main/java/electrosphere/server/macro/town/Town.java @@ -2,6 +2,8 @@ package electrosphere.server.macro.town; import electrosphere.engine.Globals; import electrosphere.server.macro.character.Character; +import electrosphere.server.macro.character.CharacterData; +import electrosphere.server.macro.character.CharacterDataStrings; import electrosphere.server.macro.structure.Structure; import java.util.LinkedList; @@ -11,7 +13,7 @@ import org.joml.Vector2i; /** * Server representation of a town */ -public class Town { +public class Town extends CharacterData { int id; static int idIncrementer = 0; @@ -54,7 +56,8 @@ public class Town { return null; } - Town(){ + private Town(){ + super(CharacterDataStrings.HOMETOWN); this.id = idIncrementer; idIncrementer++; } @@ -118,5 +121,10 @@ public class Town { public List getResidents(){ return residents; } + + @Override + public String getDataType() { + return CharacterDataStrings.HOMETOWN; + } } diff --git a/src/main/java/electrosphere/server/saves/SaveUtils.java b/src/main/java/electrosphere/server/saves/SaveUtils.java index 1efb37c7..a887ae89 100644 --- a/src/main/java/electrosphere/server/saves/SaveUtils.java +++ b/src/main/java/electrosphere/server/saves/SaveUtils.java @@ -10,6 +10,7 @@ import electrosphere.logger.LoggerInterface; import electrosphere.server.datacell.ServerWorldData; import electrosphere.server.db.DatabaseController; import electrosphere.server.db.DatabaseUtils; +import electrosphere.server.macro.MacroData; import electrosphere.server.physics.fluid.generation.DefaultFluidGenerator; import electrosphere.server.physics.fluid.manager.ServerFluidManager; import electrosphere.server.physics.terrain.generation.DefaultChunkGenerator; @@ -122,6 +123,10 @@ public class SaveUtils { //fluid manager ServerFluidManager serverFluidManager = new ServerFluidManager(serverWorldData, serverTerrainManager, 0, new DefaultFluidGenerator()); serverFluidManager.save(saveName); + + //macro data + MacroData macroData = MacroData.generateWorld(sceneFile.getSeed()); + macroData.save(saveName); } else { //just save to disk // diff --git a/src/main/java/electrosphere/server/simulation/MacroSimulation.java b/src/main/java/electrosphere/server/simulation/MacroSimulation.java index 6f78bf89..7b2dc13e 100644 --- a/src/main/java/electrosphere/server/simulation/MacroSimulation.java +++ b/src/main/java/electrosphere/server/simulation/MacroSimulation.java @@ -64,44 +64,44 @@ public class MacroSimulation { fashion makeshift shelter */ if(!chara.containsKey(CharacterDataStrings.SHELTER)){ - Vector2i charPos = CharacterUtils.getDiscretePosition(chara); - Town nearbyTown = Town.getTownAtPosition(charPos.x,charPos.y); - if(nearbyTown != null){ - //if town has a place to stay - if(false){ + // Vector2i charPos = CharacterUtils.getDiscretePosition(chara); + // Town nearbyTown = Town.getTownAtPosition(charPos.x,charPos.y); + // if(nearbyTown != null){ + // //if town has a place to stay + // if(false){ - } else { - //try to find a place to put down a structure + // } else { + // //try to find a place to put down a structure - } - } else { - //cry - //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); - // } - } + // } + // } else { + // //cry + // //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); + // // } + // } } // } } @@ -158,7 +158,7 @@ public class MacroSimulation { static void checkInitCombat(){ for(Character chara : Globals.macroData.getAliveCharacters()){ - Vector2i position = CharacterUtils.getDiscretePosition(chara); + // Vector2i position = CharacterUtils.getDiscretePosition(chara); } } } diff --git a/src/main/java/electrosphere/util/FileUtils.java b/src/main/java/electrosphere/util/FileUtils.java index 0f285f3f..d912fbf8 100644 --- a/src/main/java/electrosphere/util/FileUtils.java +++ b/src/main/java/electrosphere/util/FileUtils.java @@ -8,6 +8,8 @@ import electrosphere.game.data.creature.type.ai.AITreeDataSerializer; import electrosphere.game.data.creature.type.movement.MovementSystem; import electrosphere.game.data.creature.type.movement.MovementSystemSerializer; import electrosphere.logger.LoggerInterface; +import electrosphere.server.macro.character.CharacterData; +import electrosphere.server.macro.character.CharacterDataSerializer; import electrosphere.server.physics.terrain.generation.noise.NoiseModuleSerializer; import electrosphere.server.physics.terrain.generation.noise.NoiseSampler; import electrosphere.util.annotation.AnnotationExclusionStrategy; @@ -50,6 +52,7 @@ public class FileUtils { gsonBuilder.registerTypeAdapter(MovementSystem.class, new MovementSystemSerializer()); gsonBuilder.registerTypeAdapter(AITreeData.class, new AITreeDataSerializer()); gsonBuilder.registerTypeAdapter(NoiseSampler.class, new NoiseModuleSerializer()); + gsonBuilder.registerTypeAdapter(CharacterData.class, new CharacterDataSerializer()); gsonBuilder.addDeserializationExclusionStrategy(new AnnotationExclusionStrategy()); gsonBuilder.addSerializationExclusionStrategy(new AnnotationExclusionStrategy()); gson = gsonBuilder.create();