macro data work
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2025-04-25 15:32:23 -04:00
parent 4e6a0d0145
commit 80924671de
23 changed files with 433 additions and 105 deletions

View File

@ -1524,6 +1524,12 @@ Fix jump trees not enabling physics body
Priority based foliage content placement Priority based foliage content placement
Hide cursor by default 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

View File

@ -1,5 +1,6 @@
package electrosphere.client.ui.menu.debug; package electrosphere.client.ui.menu.debug;
import org.joml.Vector3d;
import org.ode4j.ode.DBody; import org.ode4j.ode.DBody;
import electrosphere.client.entity.camera.CameraEntityUtils; import electrosphere.client.entity.camera.CameraEntityUtils;
@ -38,7 +39,8 @@ public class ImGuiPlayerEntity {
//data about player entity //data about player entity
if(Globals.playerEntity != null){ 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)); ImGui.text("Rotation: " + EntityUtils.getRotation(Globals.playerEntity));
//physics on client //physics on client

View File

@ -12,6 +12,8 @@ import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.ServerWorldData; import electrosphere.server.datacell.ServerWorldData;
import electrosphere.server.datacell.gridded.GriddedDataCellManager; import electrosphere.server.datacell.gridded.GriddedDataCellManager;
import electrosphere.server.entity.ServerContentManager; 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.generation.DefaultChunkGenerator;
import electrosphere.server.physics.terrain.manager.ServerTerrainChunk; import electrosphere.server.physics.terrain.manager.ServerTerrainChunk;
import electrosphere.util.FileUtils; import electrosphere.util.FileUtils;
@ -30,8 +32,20 @@ public class SceneLoader {
public static void serverInstantiateSaveSceneFile(String saveName, ServerWorldData serverWorldData, boolean isLevelEditor){ public static void serverInstantiateSaveSceneFile(String saveName, ServerWorldData serverWorldData, boolean isLevelEditor){
//load scene file //load scene file
SceneFile file = FileUtils.loadObjectFromSavePath(saveName, "/scene.json", SceneFile.class); 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 //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"); String sanitizedPath = FileUtils.sanitizeFilePath("/Scenes/" + sceneName + "/scene.json");
SceneFile file = FileUtils.loadObjectFromAssetPath(sanitizedPath, SceneFile.class); SceneFile file = FileUtils.loadObjectFromAssetPath(sanitizedPath, SceneFile.class);
//instantiate scene data //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 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 * @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 //Content manager
@ -63,9 +77,9 @@ public class SceneLoader {
file.realmDescriptor.getType().matches(RealmDescriptor.REALM_DESCRIPTOR_PROCEDURAL) || file.realmDescriptor.getType().matches(RealmDescriptor.REALM_DESCRIPTOR_PROCEDURAL) ||
file.realmDescriptor.getType().matches(RealmDescriptor.REALM_DESCRIPTOR_GENERATION_TESTING) file.realmDescriptor.getType().matches(RealmDescriptor.REALM_DESCRIPTOR_GENERATION_TESTING)
){ ){
serverContentManager = ServerContentManager.createServerContentManager(true); serverContentManager = ServerContentManager.createServerContentManager(true,macroData);
} else { } else {
serverContentManager = ServerContentManager.createServerContentManager(false); serverContentManager = ServerContentManager.createServerContentManager(false,macroData);
} }
// //

View File

@ -260,6 +260,9 @@ public class Realm {
protected void save(String saveName){ protected void save(String saveName){
dataCellManager.save(saveName); dataCellManager.save(saveName);
serverWorldData.getServerTerrainManager().save(saveName); serverWorldData.getServerTerrainManager().save(saveName);
if(serverContentManager.getMacroData() != null){
serverContentManager.getMacroData().save(saveName);
}
} }
/** /**

View File

@ -66,7 +66,7 @@ public class RealmManager {
new CollisionEngine(), new CollisionEngine(),
chemistryEngine, chemistryEngine,
new HitboxManager(new ServerHitboxResolutionCallback()), new HitboxManager(new ServerHitboxResolutionCallback()),
ServerContentManager.createServerContentManager(false) ServerContentManager.createServerContentManager(false, null)
); );
} }
@ -123,7 +123,7 @@ public class RealmManager {
collisionEngine, collisionEngine,
chemistryEngine, chemistryEngine,
new HitboxManager(new ServerHitboxResolutionCallback()), new HitboxManager(new ServerHitboxResolutionCallback()),
ServerContentManager.createServerContentManager(false) ServerContentManager.createServerContentManager(false, null)
); );
//add function classes to realm //add function classes to realm

View File

@ -201,14 +201,27 @@ public class ServerWorldData {
return dynamicInterpolationRatio; return dynamicInterpolationRatio;
} }
public int convertRealToChunkSpace(double real){ public static int convertRealToChunkSpace(double real){
return (int)Math.floor(real / ServerTerrainChunk.CHUNK_DIMENSION); return (int)Math.floor(real / ServerTerrainChunk.CHUNK_DIMENSION);
} }
public float convertChunkToRealSpace(int chunk){ public static float convertChunkToRealSpace(int chunk){
return chunk * ServerTerrainChunk.CHUNK_DIMENSION; 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 * Converts a real position to a local block grid position
* @param real The real position * @param real The real position
@ -245,11 +258,11 @@ public class ServerWorldData {
return convertChunkToRealSpace(world); return convertChunkToRealSpace(world);
} }
public Vector3i convertRealToChunkSpace(Vector3d position){ public static Vector3i convertRealToChunkSpace(Vector3d position){
return new Vector3i( return new Vector3i(
convertRealToChunkSpace(position.x), ServerWorldData.convertRealToChunkSpace(position.x),
convertRealToChunkSpace(position.y), ServerWorldData.convertRealToChunkSpace(position.y),
convertRealToChunkSpace(position.z) 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( return new Vector3i(
(int)Math.floor(position.x - convertChunkToRealSpace(convertRealToChunkSpace(position.x))), (int)Math.floor(position.x - convertChunkToRealSpace(convertRealToChunkSpace(position.x))),
(int)Math.floor(position.y - convertChunkToRealSpace(convertRealToChunkSpace(position.y))), (int)Math.floor(position.y - convertChunkToRealSpace(convertRealToChunkSpace(position.y))),

View File

@ -386,9 +386,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
Entity playerEntity = player.getPlayerEntity(); Entity playerEntity = player.getPlayerEntity();
if(playerEntity != null && !parent.getLoadingDataCell().containsPlayer(player)){ if(playerEntity != null && !parent.getLoadingDataCell().containsPlayer(player)){
Vector3d position = EntityUtils.getPosition(playerEntity); Vector3d position = EntityUtils.getPosition(playerEntity);
int currentWorldX = parent.getServerWorldData().convertRealToChunkSpace(position.x); int currentWorldX = ServerWorldData.convertRealToChunkSpace(position.x);
int currentWorldY = parent.getServerWorldData().convertRealToChunkSpace(position.y); int currentWorldY = ServerWorldData.convertRealToChunkSpace(position.y);
int currentWorldZ = parent.getServerWorldData().convertRealToChunkSpace(position.z); int currentWorldZ = ServerWorldData.convertRealToChunkSpace(position.z);
Vector3i newPosition = new Vector3i(currentWorldX,currentWorldY,currentWorldZ); Vector3i newPosition = new Vector3i(currentWorldX,currentWorldY,currentWorldZ);
player.setWorldPos(newPosition); player.setWorldPos(newPosition);
@ -583,9 +583,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
*/ */
public ServerDataCell getDataCellAtPoint(Vector3d point){ public ServerDataCell getDataCellAtPoint(Vector3d point){
ServerDataCell rVal = null; ServerDataCell rVal = null;
int worldX = parent.getServerWorldData().convertRealToChunkSpace(point.x); int worldX = ServerWorldData.convertRealToChunkSpace(point.x);
int worldY = parent.getServerWorldData().convertRealToChunkSpace(point.y); int worldY = ServerWorldData.convertRealToChunkSpace(point.y);
int worldZ = parent.getServerWorldData().convertRealToChunkSpace(point.z); int worldZ = ServerWorldData.convertRealToChunkSpace(point.z);
Vector3i worldPos = new Vector3i(worldX,worldY,worldZ); Vector3i worldPos = new Vector3i(worldX,worldY,worldZ);
if( if(
//in bounds of array //in bounds of array
@ -609,9 +609,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
* @return The data cell if created, null otherwise * @return The data cell if created, null otherwise
*/ */
public ServerDataCell tryCreateCellAtPoint(Vector3d point){ public ServerDataCell tryCreateCellAtPoint(Vector3d point){
int worldX = parent.getServerWorldData().convertRealToChunkSpace(point.x); int worldX = ServerWorldData.convertRealToChunkSpace(point.x);
int worldY = parent.getServerWorldData().convertRealToChunkSpace(point.y); int worldY = ServerWorldData.convertRealToChunkSpace(point.y);
int worldZ = parent.getServerWorldData().convertRealToChunkSpace(point.z); int worldZ = ServerWorldData.convertRealToChunkSpace(point.z);
Vector3i worldPos = new Vector3i(worldX,worldY,worldZ); Vector3i worldPos = new Vector3i(worldX,worldY,worldZ);
return tryCreateCellAtPoint(worldPos); return tryCreateCellAtPoint(worldPos);
} }

View File

@ -7,33 +7,44 @@ import org.joml.Vector3i;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.state.server.ServerCharacterData; import electrosphere.entity.state.server.ServerCharacterData;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.server.character.CharacterService; import electrosphere.server.character.CharacterService;
import electrosphere.server.datacell.Realm; import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.ServerDataCell; import electrosphere.server.datacell.ServerDataCell;
import electrosphere.server.entity.serialization.ContentSerialization; import electrosphere.server.entity.serialization.ContentSerialization;
import electrosphere.server.macro.MacroData;
import electrosphere.server.saves.SaveUtils; import electrosphere.server.saves.SaveUtils;
import electrosphere.util.FileUtils; import electrosphere.util.FileUtils;
import electrosphere.util.math.HashUtils; import electrosphere.util.math.HashUtils;
import electrosphere.server.macro.character.Character;
import electrosphere.server.macro.race.Race;
public class ServerContentManager { public class ServerContentManager {
//controls whether the manager should generate content on loading a new scene //controls whether the manager should generate content on loading a new scene
boolean generateContent = false; boolean generateContent = false;
/**
* The macro data for the content manager
*/
MacroData macroData;
/** /**
* Constructor * Constructor
*/ */
private ServerContentManager(boolean generateContent){ private ServerContentManager(boolean generateContent, MacroData macroData){
this.generateContent = generateContent; this.generateContent = generateContent;
this.macroData = macroData;
} }
/** /**
* Creates a server content manager * Creates a server content manager
* @param generateContent if true, will generate content on loading a new scene, otherwise will not * @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 * @return The server content manager
*/ */
public static ServerContentManager createServerContentManager(boolean generateContent){ public static ServerContentManager createServerContentManager(boolean generateContent, MacroData macroData){
return new ServerContentManager(generateContent); return new ServerContentManager(generateContent, macroData);
} }
/** /**
@ -41,6 +52,7 @@ public class ServerContentManager {
* @param realm The realm * @param realm The realm
* @param worldPos The world position * @param worldPos The world position
* @param cell The cell * @param cell The cell
* @param cellKey The key for this cell
*/ */
public void generateContentForDataCell(Realm realm, Vector3i worldPos, ServerDataCell cell, Long cellKey){ public void generateContentForDataCell(Realm realm, Vector3i worldPos, ServerDataCell cell, Long cellKey){
Globals.profiler.beginCpuSample("ServerContentManager.generateContentForDataCell"); Globals.profiler.beginCpuSample("ServerContentManager.generateContentForDataCell");
@ -62,15 +74,19 @@ public class ServerContentManager {
contentRaw.hydrateRawContent(realm,cell); contentRaw.hydrateRawContent(realm,cell);
} }
} }
//TODO: generate navmesh //checking for null because there are cases where we might not have macro data to instantiate from
// cell.setNavMesh( //ie, if we load an asset-defined (not save-defined) scene that does not have save data
// NavMeshUtils.createMeshFromChunk(Globals.serverTerrainManager.getChunk( //ie, imagine a puzzle room or something like that
// worldPos.x, if(macroData != null){
// worldPos.y, for(Character character : macroData.getCharacters(worldPos)){
// worldPos.z if(Race.hasRace(character)){
// ), Race race = Race.getRace(character);
// Globals.navMeshManager.getBlockerCache().getBlocker(worldPos.x, worldPos.z)) String creatureName = race.getAssociatedCreature();
// ); //place macro object
CreatureUtils.serverSpawnBasicCreature(realm, character.getPos(), creatureName, null);
}
}
}
Globals.profiler.endCpuSample(); Globals.profiler.endCpuSample();
} }
@ -105,5 +121,13 @@ public class ServerContentManager {
FileUtils.serializeObjectToFilePath(fullPath, serialization); FileUtils.serializeObjectToFilePath(fullPath, serialization);
} }
/**
* Gets the macro data
* @return The macro data
*/
public MacroData getMacroData(){
return macroData;
}
} }

View File

@ -5,6 +5,7 @@ import java.util.List;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.server.datacell.ServerWorldData;
import electrosphere.server.macro.character.Character; import electrosphere.server.macro.character.Character;
import electrosphere.server.macro.character.CharacterDataStrings; import electrosphere.server.macro.character.CharacterDataStrings;
import electrosphere.server.macro.character.CharacterUtils; 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.structure.Structure;
import electrosphere.server.macro.symbolism.Symbol; import electrosphere.server.macro.symbolism.Symbol;
import electrosphere.server.macro.town.Town; import electrosphere.server.macro.town.Town;
import electrosphere.util.FileUtils;
import java.util.Random; import java.util.Random;
import org.joml.Vector3d;
import org.joml.Vector3i;
/** /**
* Server macro level data * 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 //spawn initial characters in each race
//find initial positions to place characters at per race //find initial positions to place characters at per race
//generate initial characters //generate initial characters
@ -142,6 +153,14 @@ public class MacroData {
return rVal; 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 * Generates an initial diety
* @param seed The seed * @param seed The seed
@ -224,7 +243,7 @@ public class MacroData {
LoggerInterface.loggerEngine.WARNING("Diety"); LoggerInterface.loggerEngine.WARNING("Diety");
Diety diety = CharacterUtils.getDiety(chara); Diety diety = CharacterUtils.getDiety(chara);
for(Symbol symbol : diety.getSymbols()){ for(Symbol symbol : diety.getSymbols()){
System.out.print(symbol.getName() + " "); LoggerInterface.loggerEngine.WARNING(symbol.getName() + " ");
} }
LoggerInterface.loggerEngine.WARNING("\n"); 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_ //n*m complexity - yikes! - as long as we're not making a million chars at start this should be _ok_
for(Character chara : characters){ for(Character chara : characters){
if(chara.containsKey(CharacterDataStrings.RACE)){ if(chara.containsKey(CharacterDataStrings.RACE)){
if(CharacterUtils.getRace(chara).equals(race)){ if(Race.getRace(chara).equals(race)){
numCharsOfRace++; numCharsOfRace++;
} }
} }
@ -248,5 +267,21 @@ public class MacroData {
} }
LoggerInterface.loggerEngine.WARNING("=========================="); 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<Character> getCharacters(Vector3i worldPos){
List<Character> rVal = new LinkedList<Character>();
for(Character character : this.characters){
if(ServerWorldData.convertRealToChunkSpace(character.getPos()).equals(worldPos.x, worldPos.y, worldPos.z)){
rVal.add(character);
}
}
return rVal;
}
} }

View File

@ -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;
}
}

View File

@ -3,12 +3,21 @@ package electrosphere.server.macro.character;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; 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; static int character_id_iterator = 0;
int id; int id;
Map<String,Object> data = new HashMap<String,Object>(); Map<String,CharacterData> data = new HashMap<String,CharacterData>();
Vector3d pos = new Vector3d();
@ -20,20 +29,30 @@ public class Character {
this.id = id; this.id = id;
} }
public void putData(String key, Object o){ public void putData(String key, CharacterData item){
data.put(key,o); data.put(key,item);
} }
public boolean containsKey(String key){ public boolean containsKey(String key){
return data.containsKey(key); return data.containsKey(key);
} }
public Object getData(String key){ public CharacterData getData(String key){
return data.get(key); return data.get(key);
} }
public Character(){ public Character(){
} }
@Override
public Vector3d getPos() {
return this.pos;
}
@Override
public void setPos(Vector3d pos) {
this.pos.set(pos);
}
} }

View File

@ -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;
}
}

View File

@ -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<CharacterData> {
@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;
}
}

View File

@ -11,6 +11,8 @@ public class CharacterDataStrings {
public static final String PERSONALITY_ADVANCED = "personalityAdvanced"; public static final String PERSONALITY_ADVANCED = "personalityAdvanced";
public static final String RACE = "race"; public static final String RACE = "race";
public static final String SHELTER = "shelter"; public static final String SHELTER = "shelter";
public static final String STRUCTURE = "structure";
public static final String HOMETOWN = "hometown"; public static final String HOMETOWN = "hometown";
public static final String TOWN = "town";
} }

View File

@ -1,41 +1,32 @@
package electrosphere.server.macro.character; package electrosphere.server.macro.character;
import electrosphere.server.macro.character.diety.Diety; import electrosphere.server.macro.character.diety.Diety;
import electrosphere.server.macro.race.Race;
import electrosphere.server.macro.structure.Structure; import electrosphere.server.macro.structure.Structure;
import electrosphere.server.macro.town.Town; import electrosphere.server.macro.town.Town;
import org.joml.Vector2i;
/** /**
* Utility functions for dealing with characters * Utility functions for dealing with characters
*/ */
public class CharacterUtils { public class CharacterUtils {
public static void addDiscretePosition(Character character, int posX, int posY){ /**
character.putData(CharacterDataStrings.POSITION_DISCRETE, new Vector2i(posX,posY)); * Adds diety data for the character
} * @param character The character
* @param diety The diety data
public static Vector2i getDiscretePosition(Character character){ */
return (Vector2i)character.getData(CharacterDataStrings.POSITION_DISCRETE);
}
public static void addDiety(Character character, Diety diety){ public static void addDiety(Character character, Diety diety){
character.putData(CharacterDataStrings.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){ public static Diety getDiety(Character character){
return (Diety)character.getData(CharacterDataStrings.DIETY); 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){ public static void addShelter(Character character, Structure shelter){
character.putData(CharacterDataStrings.SHELTER, shelter); character.putData(CharacterDataStrings.SHELTER, shelter);
} }

View File

@ -1,6 +1,8 @@
package electrosphere.server.macro.character.diety; package electrosphere.server.macro.character.diety;
import electrosphere.engine.Globals; 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.Symbol;
import electrosphere.server.macro.symbolism.SymbolMap; import electrosphere.server.macro.symbolism.SymbolMap;
@ -8,12 +10,22 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
public class Diety { /**
* Data defining this character as a diety
*/
public class Diety extends CharacterData {
List<Symbol> symbols = new LinkedList<Symbol>(); List<Symbol> symbols = new LinkedList<Symbol>();
//TODO: eventually add function where we can pass intial symbol to seed rest of diety off of //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 //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){ public static Diety generateDiety(long seed){
Random random = new Random(); Random random = new Random();

View File

@ -1,21 +1,85 @@
package electrosphere.server.macro.race; 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 * The race of a creature
*/ */
public class Race { public class Race extends CharacterData {
/**
* The name of the race
*/
String name; String name;
/**
* The associated creature for the race
*/
String associatedCreature; String associatedCreature;
/**
* Constructor
*/
private Race(){
super(CharacterDataStrings.RACE);
}
/**
* Gets the name of the race
* @return The name of the race
*/
public String getName() { public String getName() {
return name; return name;
} }
/**
* Gets the associated creature data for the race
* @return The associated creature data
*/
public String getAssociatedCreature() { public String getAssociatedCreature() {
return associatedCreature; 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);
}
} }

View File

@ -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);
}

View File

@ -4,10 +4,13 @@ import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import electrosphere.server.macro.character.CharacterData;
import electrosphere.server.macro.character.CharacterDataStrings;
/** /**
* Server representation of a structure * Server representation of a structure
*/ */
public class Structure { public class Structure extends CharacterData {
int worldX; int worldX;
int worldY; int worldY;
float locationX; float locationX;
@ -19,6 +22,7 @@ public class Structure {
LinkedList<String> dataKeys = new LinkedList<String>(); LinkedList<String> dataKeys = new LinkedList<String>();
public Structure(int worldX, int worldY, float locationX, float locationY, String type) { public Structure(int worldX, int worldY, float locationX, float locationY, String type) {
super(CharacterDataStrings.STRUCTURE);
this.worldX = worldX; this.worldX = worldX;
this.worldY = worldY; this.worldY = worldY;
this.locationX = locationX; this.locationX = locationX;
@ -58,6 +62,11 @@ public class Structure {
public String getType() { public String getType() {
return type; return type;
} }
@Override
public String getDataType() {
return CharacterDataStrings.HOMETOWN;
}

View File

@ -2,6 +2,8 @@ package electrosphere.server.macro.town;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.server.macro.character.Character; 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 electrosphere.server.macro.structure.Structure;
import java.util.LinkedList; import java.util.LinkedList;
@ -11,7 +13,7 @@ import org.joml.Vector2i;
/** /**
* Server representation of a town * Server representation of a town
*/ */
public class Town { public class Town extends CharacterData {
int id; int id;
static int idIncrementer = 0; static int idIncrementer = 0;
@ -54,7 +56,8 @@ public class Town {
return null; return null;
} }
Town(){ private Town(){
super(CharacterDataStrings.HOMETOWN);
this.id = idIncrementer; this.id = idIncrementer;
idIncrementer++; idIncrementer++;
} }
@ -118,5 +121,10 @@ public class Town {
public List<Character> getResidents(){ public List<Character> getResidents(){
return residents; return residents;
} }
@Override
public String getDataType() {
return CharacterDataStrings.HOMETOWN;
}
} }

View File

@ -10,6 +10,7 @@ import electrosphere.logger.LoggerInterface;
import electrosphere.server.datacell.ServerWorldData; import electrosphere.server.datacell.ServerWorldData;
import electrosphere.server.db.DatabaseController; import electrosphere.server.db.DatabaseController;
import electrosphere.server.db.DatabaseUtils; import electrosphere.server.db.DatabaseUtils;
import electrosphere.server.macro.MacroData;
import electrosphere.server.physics.fluid.generation.DefaultFluidGenerator; import electrosphere.server.physics.fluid.generation.DefaultFluidGenerator;
import electrosphere.server.physics.fluid.manager.ServerFluidManager; import electrosphere.server.physics.fluid.manager.ServerFluidManager;
import electrosphere.server.physics.terrain.generation.DefaultChunkGenerator; import electrosphere.server.physics.terrain.generation.DefaultChunkGenerator;
@ -122,6 +123,10 @@ public class SaveUtils {
//fluid manager //fluid manager
ServerFluidManager serverFluidManager = new ServerFluidManager(serverWorldData, serverTerrainManager, 0, new DefaultFluidGenerator()); ServerFluidManager serverFluidManager = new ServerFluidManager(serverWorldData, serverTerrainManager, 0, new DefaultFluidGenerator());
serverFluidManager.save(saveName); serverFluidManager.save(saveName);
//macro data
MacroData macroData = MacroData.generateWorld(sceneFile.getSeed());
macroData.save(saveName);
} else { } else {
//just save to disk //just save to disk
// //

View File

@ -64,44 +64,44 @@ public class MacroSimulation {
fashion makeshift shelter fashion makeshift shelter
*/ */
if(!chara.containsKey(CharacterDataStrings.SHELTER)){ if(!chara.containsKey(CharacterDataStrings.SHELTER)){
Vector2i charPos = CharacterUtils.getDiscretePosition(chara); // Vector2i charPos = CharacterUtils.getDiscretePosition(chara);
Town nearbyTown = Town.getTownAtPosition(charPos.x,charPos.y); // Town nearbyTown = Town.getTownAtPosition(charPos.x,charPos.y);
if(nearbyTown != null){ // if(nearbyTown != null){
//if town has a place to stay // //if town has a place to stay
if(false){ // if(false){
} else { // } else {
//try to find a place to put down a structure // //try to find a place to put down a structure
} // }
} else { // } else {
//cry // //cry
//TODO: Get building type to place // //TODO: Get building type to place
String buildingTypeToPlace = "building1"; // String buildingTypeToPlace = "building1";
//try to find a place to put down a structure // //try to find a place to put down a structure
// int dynamicInterpRatio = Globals.serverTerrainManager.getDynamicInterpolationRatio(); // // int dynamicInterpRatio = Globals.serverTerrainManager.getDynamicInterpolationRatio();
// Vector2f placementPos = new Vector2f( // // Vector2f placementPos = new Vector2f(
// (float)(charPos.x * dynamicInterpRatio + Math.random() * dynamicInterpRatio), // // (float)(charPos.x * dynamicInterpRatio + Math.random() * dynamicInterpRatio),
// (float)(charPos.y * dynamicInterpRatio + Math.random() * dynamicInterpRatio) // // (float)(charPos.y * dynamicInterpRatio + Math.random() * dynamicInterpRatio)
// ); // // );
// int attempts = 0; // // int attempts = 0;
// while(!VirtualStructureUtils.validStructurePlacementPosition(placementPos.x, placementPos.y, buildingTypeToPlace)){ // // while(!VirtualStructureUtils.validStructurePlacementPosition(placementPos.x, placementPos.y, buildingTypeToPlace)){
// placementPos = new Vector2f( // // placementPos = new Vector2f(
// (float)(charPos.x * dynamicInterpRatio + Math.random() * dynamicInterpRatio), // // (float)(charPos.x * dynamicInterpRatio + Math.random() * dynamicInterpRatio),
// (float)(charPos.y * dynamicInterpRatio + Math.random() * dynamicInterpRatio) // // (float)(charPos.y * dynamicInterpRatio + Math.random() * dynamicInterpRatio)
// ); // // );
// attempts++; // // attempts++;
// if(attempts > MAX_PLACE_ATTEMPTS){ // // if(attempts > MAX_PLACE_ATTEMPTS){
// placementPos = null; // // placementPos = null;
// break; // // break;
// } // // }
// } // // }
// if(placementPos != null){ // // if(placementPos != null){
// // Structure placedStructure = VirtualStructureUtils.placeStructureAtPoint(placementPos.x, placementPos.y, buildingTypeToPlace); // // // Structure placedStructure = VirtualStructureUtils.placeStructureAtPoint(placementPos.x, placementPos.y, buildingTypeToPlace);
// // CharacterUtils.addShelter(chara, placedStructure); // // // CharacterUtils.addShelter(chara, placedStructure);
// // VirtualStructureUtils.addResident(placedStructure, chara); // // // VirtualStructureUtils.addResident(placedStructure, chara);
// } // // }
} // }
} }
// } // }
} }
@ -158,7 +158,7 @@ public class MacroSimulation {
static void checkInitCombat(){ static void checkInitCombat(){
for(Character chara : Globals.macroData.getAliveCharacters()){ for(Character chara : Globals.macroData.getAliveCharacters()){
Vector2i position = CharacterUtils.getDiscretePosition(chara); // Vector2i position = CharacterUtils.getDiscretePosition(chara);
} }
} }
} }

View File

@ -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.MovementSystem;
import electrosphere.game.data.creature.type.movement.MovementSystemSerializer; import electrosphere.game.data.creature.type.movement.MovementSystemSerializer;
import electrosphere.logger.LoggerInterface; 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.NoiseModuleSerializer;
import electrosphere.server.physics.terrain.generation.noise.NoiseSampler; import electrosphere.server.physics.terrain.generation.noise.NoiseSampler;
import electrosphere.util.annotation.AnnotationExclusionStrategy; import electrosphere.util.annotation.AnnotationExclusionStrategy;
@ -50,6 +52,7 @@ public class FileUtils {
gsonBuilder.registerTypeAdapter(MovementSystem.class, new MovementSystemSerializer()); gsonBuilder.registerTypeAdapter(MovementSystem.class, new MovementSystemSerializer());
gsonBuilder.registerTypeAdapter(AITreeData.class, new AITreeDataSerializer()); gsonBuilder.registerTypeAdapter(AITreeData.class, new AITreeDataSerializer());
gsonBuilder.registerTypeAdapter(NoiseSampler.class, new NoiseModuleSerializer()); gsonBuilder.registerTypeAdapter(NoiseSampler.class, new NoiseModuleSerializer());
gsonBuilder.registerTypeAdapter(CharacterData.class, new CharacterDataSerializer());
gsonBuilder.addDeserializationExclusionStrategy(new AnnotationExclusionStrategy()); gsonBuilder.addDeserializationExclusionStrategy(new AnnotationExclusionStrategy());
gsonBuilder.addSerializationExclusionStrategy(new AnnotationExclusionStrategy()); gsonBuilder.addSerializationExclusionStrategy(new AnnotationExclusionStrategy());
gson = gsonBuilder.create(); gson = gsonBuilder.create();