player character movement triggers layoutTown
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2025-05-18 15:12:57 -04:00
parent 7a8405230a
commit 139a5a11d3
7 changed files with 155 additions and 7 deletions

View File

@ -179,6 +179,20 @@ public class MacroData {
public List<Civilization> getCivilizations(){
return civilizations;
}
/**
* Gets a civilization by its id
* @param id The id
* @return The civilization if it exists, null otherwise
*/
public Civilization getCivilization(int id){
for(Civilization civ : this.civilizations){
if(civ.getId() == id){
return civ;
}
}
return null;
}
/**
* Adds a civilization
@ -203,9 +217,10 @@ public class MacroData {
* Adds a town
* @param center The center point of the town
* @param radius The radius of the town
* @param parentCivId The id of the parent civilization
*/
public Town addTown(Vector3d center, double radius){
Town rVal = Town.createTown(center, radius);
public Town addTown(Vector3d center, double radius, int parentCivId){
Town rVal = Town.createTown(center, radius, parentCivId);
rVal.setId(towns.size());
towns.add(rVal);
return rVal;

View File

@ -2,10 +2,18 @@ package electrosphere.server.macro;
import org.joml.Vector3d;
import electrosphere.server.macro.town.Town;
import electrosphere.server.macro.town.TownLayout;
/**
* Updates macro data as a player comes into range of it
*/
public class MacroDataUpdater {
/**
* Generate all towns within 5 km of a player
*/
private static final int TOWN_GENERATION_DIST = 5 * 1000;
/**
* Updates the macro data
@ -13,8 +21,17 @@ public class MacroDataUpdater {
* @param playerPos The player's position
*/
public static void update(MacroData macroData, Vector3d playerPos){
//scan for all objects within update range
//update them
//scan for all towns within update range
for(Town town : macroData.getTowns()){
//only generate data for towns that aren't already full resolution
if(town.getResolution() == Town.TOWN_RES_MAX){
continue;
}
Vector3d townPos = town.getPos();
if(townPos.distance(playerPos) < TOWN_GENERATION_DIST){
TownLayout.layoutTown(macroData, town);
}
}
}
}

View File

@ -8,6 +8,7 @@ import electrosphere.engine.Globals;
import electrosphere.server.macro.MacroData;
import electrosphere.server.macro.town.Town;
import electrosphere.server.macro.character.Character;
import electrosphere.server.macro.race.Race;
/**
* A civilization
@ -34,6 +35,11 @@ public class Civilization {
*/
private List<Integer> citizens = new LinkedList<Integer>();
/**
* The races that are a part of this civilization
*/
private List<String> races = new LinkedList<String>();
/**
* Gets the id of the civilization
* @return The id
@ -98,4 +104,20 @@ public class Civilization {
this.citizens.add(chara.getId());
}
/**
* Adds a race to the civilization
* @param race The race
*/
public void addRace(Race race){
this.races.add(race.getId());
}
/**
* Gets the list of race ids of this civilization
* @return The list of race ids
*/
public List<String> getRaceIds(){
return this.races;
}
}

View File

@ -28,9 +28,11 @@ public class CivilizationGenerator {
public static void generate(ServerWorldData serverWorldData, MacroData macroData, Config config){
//TODO: spread out and don't just put at global spawn point
Vector3d spawnPoint = new Vector3d(serverWorldData.getWorldSizeDiscrete() * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET / 2);
spawnPoint.y = serverWorldData.getServerTerrainManager().getElevation(spawnPoint);
for(Race race : config.getRaceMap().getRaces()){
Civilization newCiv = macroData.addCivilization(race);
Town startingTown = macroData.addTown(spawnPoint, INITIAL_TOWN_RADIUS);
newCiv.addRace(race);
Town startingTown = macroData.addTown(spawnPoint, INITIAL_TOWN_RADIUS, newCiv.getId());
newCiv.addTown(startingTown);
}
}

View File

@ -3,6 +3,7 @@ package electrosphere.server.macro.town;
import electrosphere.engine.Globals;
import electrosphere.server.macro.MacroData;
import electrosphere.server.macro.character.Character;
import electrosphere.server.macro.civilization.Civilization;
import electrosphere.server.macro.spatial.MacroAreaObject;
import electrosphere.server.macro.structure.VirtualStructure;
@ -18,6 +19,16 @@ import org.joml.Vector3d;
*/
public class Town implements MacroAreaObject {
/**
* Minimum data resolution town (ie hasn't generated structures or residents)
*/
public static final int TOWN_RES_MIN = 0;
/**
* Maximim data resolution town (has fully generated all default structures and residents)
*/
public static final int TOWN_RES_MAX = 1;
/**
* The id of the town
*/
@ -27,6 +38,11 @@ public class Town implements MacroAreaObject {
* Incrementer for IDs
*/
static int idIncrementer = 0;
/**
* The resolution of data that has been generated for this town
*/
private int resolution = TOWN_RES_MIN;
/**
* The position of the town
@ -53,6 +69,11 @@ public class Town implements MacroAreaObject {
*/
private List<TownJob> jobs = new LinkedList<TownJob>();
/**
* The id of the parent civilization
*/
private int parentCivId;
/**
* Constructor
*/
@ -65,12 +86,14 @@ public class Town implements MacroAreaObject {
* Creates a town
* @param position The position of the town
* @param radius The radius of the town
* @param parentCiv The id of the parent civilization
* @return The town
*/
public static Town createTown(Vector3d position, double radius){
public static Town createTown(Vector3d position, double radius, int parentCiv){
Town rVal = new Town();
rVal.position = position;
rVal.radius = radius;
rVal.parentCivId = parentCiv;
return rVal;
}
@ -170,5 +193,30 @@ public class Town implements MacroAreaObject {
public int getId(){
return this.id;
}
/**
* Gets the resolution of the data that has been generated for this town
* @return The resolution of the data
*/
public int getResolution() {
return resolution;
}
/**
* Sets the resolution of the data that has been generated for this town
* @param resolution The resolution of the data
*/
public void setResolution(int resolution) {
this.resolution = resolution;
}
/**
* Gets the parent civilization
* @param macroData The macro data
* @return The parent civilization
*/
public Civilization getParent(MacroData macroData){
return macroData.getCivilization(this.parentCivId);
}
}

View File

@ -1,18 +1,47 @@
package electrosphere.server.macro.town;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import electrosphere.data.struct.StructureData;
import electrosphere.engine.Globals;
import electrosphere.logger.LoggerInterface;
import electrosphere.server.macro.MacroData;
import electrosphere.server.macro.civilization.Civilization;
import electrosphere.server.macro.race.Race;
/**
* Lays out town objects
*/
public class TownLayout {
/**
* Lays out structures for a town
* @param macroData The macro data
* @param town The town
*/
public static void layoutTown(MacroData macroData, Town town){
Civilization parentCiv = town.getParent(macroData);
List<String> raceIds = parentCiv.getRaceIds();
List<Race> races = raceIds.stream().map((String raceId) -> Globals.gameConfigCurrent.getRaceMap().getRace(raceId)).filter((Race race) -> race != null).collect(Collectors.toList());
if(races.size() == 0){
throw new Error("No races found! " + raceIds);
}
List<StructureData> allowedStructures = new LinkedList<StructureData>();
for(Race race : races){
for(String structureId : race.getStructureIds()){
StructureData structData = Globals.gameConfigCurrent.getStructureData().getType(structureId);
if(!allowedStructures.contains(structData)){
allowedStructures.add(structData);
}
}
}
if(allowedStructures.size() < 1){
throw new Error("No structures found! " + raceIds);
}
LoggerInterface.loggerEngine.DEBUG("Allowed structure count: " + allowedStructures.size());
town.setResolution(Town.TOWN_RES_MAX);
}
}

View File

@ -22,6 +22,7 @@ import java.nio.ShortBuffer;
import java.util.concurrent.ExecutorService;
import java.util.function.Consumer;
import org.joml.Vector3d;
import org.joml.Vector3i;
/**
@ -311,6 +312,20 @@ public class ServerTerrainManager {
return elevation;
}
/**
* Gets the elevation at a real x and z (ignores y component)
* @param realPos The real position
* @return The elevation
*/
public double getElevation(Vector3d realPos){
Globals.profiler.beginAggregateCpuSample("ServerTerrainManager.getChunk");
Vector3i chunkPos = ServerWorldData.convertRealToChunkSpace(realPos);
Vector3i voxelPos = ServerWorldData.convertRealToVoxelSpace(realPos);
double elevation = chunkGenerator.getElevation(chunkPos.x, chunkPos.z, voxelPos.x, voxelPos.z);
Globals.profiler.endCpuSample();
return elevation;
}
/**
* Performs logic once a server chunk is available
* @param worldX The world x position