Renderer/src/main/java/electrosphere/server/entity/ServerContentGenerator.java
austin a7ef1db485
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
macro structure data definitions
2025-04-29 13:41:52 -04:00

111 lines
5.2 KiB
Java

package electrosphere.server.entity;
import java.util.List;
import java.util.Random;
import org.joml.Vector3d;
import org.joml.Vector3i;
import electrosphere.entity.types.foliage.FoliageUtils;
import electrosphere.game.data.biome.BiomeData;
import electrosphere.game.data.biome.BiomeFoliageDescription;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.ServerDataCell;
import electrosphere.server.macro.MacroData;
import electrosphere.server.physics.terrain.manager.ServerTerrainChunk;
import io.github.studiorailgun.NoiseUtils;
/**
* Generates content for a given datacell
*/
public class ServerContentGenerator {
/**
* The seed of the foliage
*/
public static final int FOLIAGE_SEED = 0;
/**
* Adjustment applied to generated height value to approximate the height of the actual terrain.
* The voxels don't generate QUITE to the height of the heightmap, so this is applied to make the value line up better for entity placement.
*/
public static final float HEIGHT_MANUAL_ADJUSTMENT = -0.35f;
/**
* Generates content for a given data cell
* @param realm The realm
* @param macroData The macro data
* @param cell The cell
* @param worldPos The world position of the cell
* @param randomizer The randomizer
*/
public static void generateContent(Realm realm, MacroData macroData, ServerDataCell cell, Vector3i worldPos, long randomizer){
//verify we have everything for chunk content gen
if(realm.getServerWorldData() == null && realm.getServerWorldData().getServerTerrainManager() == null && realm.getServerWorldData().getServerTerrainManager().getModel() == null){
throw new Error(
"Trying to generate content for a realm that does not have a terrain model defined!\n" +
realm.getServerWorldData() + "\n" +
realm.getServerWorldData().getServerTerrainManager() + "\n" +
realm.getServerWorldData().getServerTerrainManager().getModel()
);
}
//setup
Random random = new Random(randomizer);
//generate foliage
BiomeData biome = null;
if(realm.getServerWorldData() != null && realm.getServerWorldData().getServerTerrainManager() != null && realm.getServerWorldData().getServerTerrainManager().getModel() != null){
biome = realm.getServerWorldData().getServerTerrainManager().getModel().getClosestSurfaceBiome(worldPos.x, worldPos.z);
}
List<BiomeFoliageDescription> foliageDescriptions = biome.getSurfaceGenerationParams().getFoliageDescriptions();
if(foliageDescriptions != null){
for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION; x++){
for(int z = 0; z < ServerTerrainChunk.CHUNK_DIMENSION; z++){
double height = realm.getServerWorldData().getServerTerrainManager().getElevation(worldPos.x, worldPos.z, x, z) + HEIGHT_MANUAL_ADJUSTMENT;
if(
realm.getServerWorldData().convertVoxelToRealSpace(0, worldPos.y) < height &&
realm.getServerWorldData().convertVoxelToRealSpace(ServerTerrainChunk.CHUNK_DIMENSION, worldPos.y) > height
){
BiomeFoliageDescription toPlace = null;
double foundPriority = -1;
double realX = realm.getServerWorldData().convertVoxelToRealSpace(x, worldPos.x);
double realZ = realm.getServerWorldData().convertVoxelToRealSpace(z, worldPos.z);
for(BiomeFoliageDescription foliageDescription : foliageDescriptions){
double scale = foliageDescription.getScale();
double regularity = foliageDescription.getRegularity();
double threshold = foliageDescription.getThreshold();
double value = NoiseUtils.relaxedPointGen(realX * scale, realZ * scale, regularity, threshold);
if(value > 0){
if(toPlace == null){
foundPriority = foliageDescription.getPriority();
toPlace = foliageDescription;
} else if(foliageDescription.getPriority() > foundPriority) {
foundPriority = foliageDescription.getPriority();
toPlace = foliageDescription;
}
}
}
if(toPlace != null){
String type = toPlace.getEntityIDs().get(random.nextInt(0,toPlace.getEntityIDs().size()));
FoliageUtils.serverSpawnTreeFoliage(
realm,
new Vector3d(
realX,
height,
realZ
),
type,
random.nextLong()
);
}
}
}
}
}
}
}