Fix SP debug mode
This commit is contained in:
parent
e225cac5cf
commit
8f61e3e00e
54
pom.xml
54
pom.xml
@ -255,7 +255,19 @@
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
|
||||
<configuration>
|
||||
<executable>java</executable>
|
||||
<includeProjectDependencies>false</includeProjectDependencies>
|
||||
<includePluginDependencies>true</includePluginDependencies>
|
||||
<mainClass>electrosphere.engine.Main</mainClass>
|
||||
<!-- <classpathScope>compile</classpathScope> -->
|
||||
<arguments>
|
||||
<argument>-cp</argument>
|
||||
<argument>target/classes;target/Renderer-0.1-jar-with-dependencies.jar</argument>
|
||||
<argument>electrosphere.engine.Main</argument>
|
||||
</arguments>
|
||||
<!-- <classesDirectory>${project.basedir}/target/classes</classesDirectory> -->
|
||||
</configuration>
|
||||
</execution>
|
||||
<!-- <execution>
|
||||
<id>Telephone</id>
|
||||
@ -272,28 +284,30 @@
|
||||
</configuration>
|
||||
</execution> -->
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>buildnumber-maven-plugin</artifactId>
|
||||
<version>1.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>buildnumber</id>
|
||||
<phase>validate</phase>
|
||||
<goals>
|
||||
<goal>create</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<executable>java</executable>
|
||||
<includeProjectDependencies>false</includeProjectDependencies>
|
||||
<includePluginDependencies>true</includePluginDependencies>
|
||||
<mainClass>electrosphere.engine.Main</mainClass>
|
||||
<!-- <classpathScope>compile</classpathScope> -->
|
||||
<arguments>
|
||||
<argument>-cp</argument>
|
||||
<argument>target/classes;target/Renderer-0.1-jar-with-dependencies.jar</argument>
|
||||
<argument>electrosphere.engine.Main</argument>
|
||||
</arguments>
|
||||
<!-- <classesDirectory>${project.basedir}/target/classes</classesDirectory> -->
|
||||
<format>{0,number}</format>
|
||||
<items>
|
||||
<item>buildNumber</item>
|
||||
</items>
|
||||
<doCheck>false</doCheck>
|
||||
<doUpdate>false</doUpdate>
|
||||
<revisionOnScmFailure>unknownbuild</revisionOnScmFailure>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- <plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.12.4</version>
|
||||
<configuration>
|
||||
<argLine>-XstartOnFirstThread</argLine>
|
||||
</configuration>
|
||||
</plugin> -->
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@ -60,7 +60,6 @@ public class FluidDrawCell {
|
||||
rVal.worldPos = worldPos;
|
||||
rVal.program = program;
|
||||
rVal.data = data;
|
||||
System.out.println("Create cell");
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ import electrosphere.renderer.ShaderProgram;
|
||||
*
|
||||
* @author satellite
|
||||
*/
|
||||
public class DrawCellManager {
|
||||
public class FluidDrawCellManager {
|
||||
|
||||
|
||||
//the center of this cell manager's array in cell space
|
||||
@ -78,7 +78,7 @@ public class DrawCellManager {
|
||||
* @param discreteX The initial discrete position X coordinate
|
||||
* @param discreteY The initial discrete position Y coordinate
|
||||
*/
|
||||
public DrawCellManager(ClientTerrainManager clientTerrainManager, int discreteX, int discreteY, int discreteZ){
|
||||
public FluidDrawCellManager(ClientTerrainManager clientTerrainManager, int discreteX, int discreteY, int discreteZ){
|
||||
worldBoundDiscreteMax = (int)(Globals.clientWorldData.getWorldBoundMin().x / Globals.clientWorldData.getDynamicInterpolationRatio() * 1.0f);
|
||||
cells = new HashSet<FluidDrawCell>();
|
||||
hasNotRequested = new HashSet<String>();
|
||||
@ -102,7 +102,7 @@ public class DrawCellManager {
|
||||
update = true;
|
||||
}
|
||||
|
||||
DrawCellManager(){
|
||||
FluidDrawCellManager(){
|
||||
|
||||
}
|
||||
|
||||
@ -61,7 +61,6 @@ public class DrawCell {
|
||||
rVal.worldPos = worldPos;
|
||||
rVal.program = program;
|
||||
rVal.data = data;
|
||||
System.out.println("Create cell");
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
@ -52,7 +52,7 @@ public class DrawCellManager {
|
||||
int drawStepdownInterval = 3;
|
||||
int drawStepdownValue = 25;
|
||||
|
||||
double drawRadius = 200;
|
||||
double drawRadius = 50;
|
||||
|
||||
int physicsRadius = 3;
|
||||
|
||||
@ -272,6 +272,7 @@ public class DrawCellManager {
|
||||
updateable.remove(key);
|
||||
keyCellMap.remove(key);
|
||||
hasRequested.remove(key);
|
||||
cell.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@ -324,14 +325,12 @@ public class DrawCellManager {
|
||||
* Updates cells that need updating in this manager
|
||||
*/
|
||||
public void update(){
|
||||
if(update){
|
||||
if(containsUnrequestedCell() && !containsUndrawableCell()){
|
||||
updateUnrequestedCell();
|
||||
} else if(containsUndrawableCell()){
|
||||
makeCellDrawable();
|
||||
} else if(containsUpdateableCell()){
|
||||
updateCellModel();
|
||||
}
|
||||
if(containsUnrequestedCell() && !containsUndrawableCell()){
|
||||
updateUnrequestedCell();
|
||||
} else if(containsUndrawableCell()){
|
||||
makeCellDrawable();
|
||||
} else if(containsUpdateableCell()){
|
||||
updateCellModel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -443,7 +443,7 @@ public class Globals {
|
||||
//init default shaderProgram
|
||||
defaultMeshShader = ShaderProgram.smart_assemble_shader(false,true);
|
||||
//init terrain shader program
|
||||
terrainShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/terrain2/terrain.vs", "/Shaders/terrain2/terrain.fs");
|
||||
terrainShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/terrain2/terrain2.vs", "/Shaders/terrain2/terrain2.fs");
|
||||
TerrainChunkModelGeneration.terrainChunkShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/terrain2/terrain2.vs", "/Shaders/terrain2/terrain2.fs");
|
||||
//init fluid shader program
|
||||
terrainShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/fluid1/fluid1.vs", "/Shaders/fluid1/fluid1.fs");
|
||||
|
||||
@ -238,7 +238,7 @@ public class Main {
|
||||
/// C L I E N T N E T W O R K I N G S T U F F
|
||||
///
|
||||
//Why is this its own function? Just to get the networking code out of main()
|
||||
if(Globals.RUN_CLIENT && Globals.clientConnection != null){
|
||||
if(Globals.clientConnection != null){
|
||||
Globals.clientConnection.parseMessages();
|
||||
}
|
||||
|
||||
|
||||
@ -119,6 +119,9 @@ public class ClientLoading {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Inits the client networking thread and socket
|
||||
*/
|
||||
private static void initClientThread(){
|
||||
//start client networking
|
||||
Thread clientThread = null;
|
||||
@ -253,6 +256,7 @@ public class ClientLoading {
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(10);
|
||||
} catch (InterruptedException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
// System.out.println("invalid cell");
|
||||
}
|
||||
@ -262,6 +266,7 @@ public class ClientLoading {
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(10);
|
||||
} catch (InterruptedException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
// System.out.println("undrawable");
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ import electrosphere.menu.MenuGenerators;
|
||||
import electrosphere.menu.WindowStrings;
|
||||
import electrosphere.menu.WindowUtils;
|
||||
import electrosphere.net.parser.net.message.TerrainMessage;
|
||||
import electrosphere.net.server.ServerConnectionHandler;
|
||||
import electrosphere.renderer.ui.Window;
|
||||
import electrosphere.server.saves.SaveUtils;
|
||||
import electrosphere.server.terrain.manager.ServerTerrainManager;
|
||||
@ -30,7 +31,7 @@ public class DebugSPWorldLoading {
|
||||
WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu());
|
||||
loadingWindow.setVisible(true);
|
||||
|
||||
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO,0.0f,0);
|
||||
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,0.0f,0);
|
||||
if(!SaveUtils.getSaves().contains("random_sp_world")){
|
||||
//
|
||||
//the juicy server GENERATION part
|
||||
@ -39,7 +40,7 @@ public class DebugSPWorldLoading {
|
||||
SaveUtils.createOrOverwriteSave("random_sp_world");
|
||||
//create terrain
|
||||
Globals.serverTerrainManager.generate();
|
||||
Globals.serverTerrainManager.save(SaveUtils.deriveSaveDirectoryPath("random_sp_world"));
|
||||
Globals.serverTerrainManager.save("random_sp_world");
|
||||
//create world.json
|
||||
Globals.serverWorldData = ServerWorldData.createGameWorld(Globals.serverTerrainManager);
|
||||
FileUtils.serializeObjectToSavePath("random_sp_world", "./world.json", Globals.serverWorldData);
|
||||
@ -59,7 +60,7 @@ public class DebugSPWorldLoading {
|
||||
//initialize the local connection
|
||||
Globals.clientUsername = "testuser";
|
||||
Globals.clientPassword = AuthenticationManager.getHashedString("testpass");
|
||||
LoadingUtils.initLocalConnection();
|
||||
ServerConnectionHandler serverPlayerConnection = LoadingUtils.initLocalConnection();
|
||||
//wait for player object creation
|
||||
while(Globals.playerManager.getPlayers().size() < 1){
|
||||
try {
|
||||
@ -85,7 +86,7 @@ public class DebugSPWorldLoading {
|
||||
}
|
||||
|
||||
//spawn player character
|
||||
LoadingUtils.spawnLocalPlayerTestEntity();
|
||||
LoadingUtils.spawnLocalPlayerTestEntity(serverPlayerConnection);
|
||||
|
||||
//request terrain data
|
||||
Globals.clientConnection.queueOutgoingMessage(TerrainMessage.constructRequestMetadataMessage());
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
package electrosphere.engine.loadingthreads;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PipedInputStream;
|
||||
import java.io.PipedOutputStream;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -28,7 +32,9 @@ import electrosphere.game.server.world.MacroData;
|
||||
import electrosphere.game.server.world.ServerWorldData;
|
||||
import electrosphere.net.NetUtils;
|
||||
import electrosphere.net.client.ClientNetworking;
|
||||
import electrosphere.net.parser.net.message.CharacterMessage;
|
||||
import electrosphere.net.server.Server;
|
||||
import electrosphere.net.server.ServerConnectionHandler;
|
||||
import electrosphere.net.server.player.Player;
|
||||
import electrosphere.server.datacell.GriddedDataCellManager;
|
||||
import electrosphere.server.datacell.Realm;
|
||||
@ -54,7 +60,7 @@ public class LoadingUtils {
|
||||
Actually initialize the terrain manager
|
||||
*/
|
||||
float randomDampener = 0.0f; //0.25f;
|
||||
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO,randomDampener,0);
|
||||
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,randomDampener,0);
|
||||
if(Globals.RUN_SERVER){
|
||||
if(Globals.userSettings.gameplayGenerateWorld()){
|
||||
Globals.serverTerrainManager.generate();
|
||||
@ -70,7 +76,6 @@ public class LoadingUtils {
|
||||
int playerStartX = 0;
|
||||
int playerStartY = 0;
|
||||
int discreteSize = Globals.serverTerrainManager.getWorldDiscreteSize();
|
||||
int chunkSize = Globals.serverTerrainManager.getChunkWidth();
|
||||
boolean found = false;
|
||||
for(int x = 0; x < discreteSize; x++){
|
||||
for(int y = 0; y < discreteSize; y++){
|
||||
@ -164,25 +169,30 @@ public class LoadingUtils {
|
||||
}
|
||||
}
|
||||
|
||||
static void initLocalConnection(){
|
||||
Globals.server = new Server(NetUtils.getPort());
|
||||
static final int STREAM_BUFFER_SIZE = 32 * 1024 * 1024;
|
||||
static ServerConnectionHandler initLocalConnection(){
|
||||
ServerConnectionHandler rVal = null;
|
||||
try {
|
||||
Globals.server = new Server(NetUtils.getPort());
|
||||
//client -> server pipe
|
||||
PipedInputStream clientInput = new PipedInputStream();
|
||||
PipedInputStream clientInput = new PipedInputStream(STREAM_BUFFER_SIZE);
|
||||
PipedOutputStream serverOutput = new PipedOutputStream(clientInput);
|
||||
//server -> client pipe
|
||||
PipedInputStream serverInput = new PipedInputStream();
|
||||
PipedOutputStream clientOutput = new PipedOutputStream(serverInput);
|
||||
PipedOutputStream clientOutput;
|
||||
clientOutput = new PipedOutputStream(serverInput);
|
||||
//start server communication thread
|
||||
Globals.server.addLocalPlayer(serverInput, serverOutput);
|
||||
rVal = Globals.server.addLocalPlayer(serverInput, serverOutput);
|
||||
//start client communication thread
|
||||
Globals.clientConnection = new ClientNetworking(clientInput,clientOutput);
|
||||
Thread clientThread = null;
|
||||
clientThread = new Thread(Globals.clientConnection);
|
||||
clientThread.start();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -219,7 +229,7 @@ public class LoadingUtils {
|
||||
/**
|
||||
* Spawns the character, and sets server side connection player object values to the appropriate chunk
|
||||
*/
|
||||
static void spawnLocalPlayerTestEntity(){
|
||||
static void spawnLocalPlayerTestEntity(ServerConnectionHandler serverPlayerConnection){
|
||||
//
|
||||
//Create entity
|
||||
//
|
||||
@ -238,11 +248,9 @@ public class LoadingUtils {
|
||||
template.putValue(attribute.getAttributeId(), attribute.getVariants().get(0).getId());
|
||||
}
|
||||
}
|
||||
Realm realm = Globals.realmManager.getRealms().iterator().next();
|
||||
//create player
|
||||
//spawn entity
|
||||
Entity newPlayerEntity = CreatureUtils.serverSpawnBasicCreature(realm,Globals.spawnPoint,template.getCreatureType(),template);
|
||||
Globals.playerEntity = newPlayerEntity;
|
||||
//set player character template
|
||||
serverPlayerConnection.setCreatureTemplate(template);
|
||||
Globals.clientConnection.queueOutgoingMessage(CharacterMessage.constructRequestSpawnCharacterMessage());
|
||||
|
||||
//set player world-space coordinates
|
||||
Player playerObject = Globals.playerManager.getPlayerFromId(0);
|
||||
@ -251,12 +259,6 @@ public class LoadingUtils {
|
||||
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.y),
|
||||
Globals.serverWorldData.convertRealToChunkSpace(Globals.spawnPoint.z)
|
||||
));
|
||||
//set client entity data
|
||||
Globals.clientPlayerData.setWorldPos(playerObject.getWorldPos());
|
||||
//initially position entity
|
||||
ServerEntityUtils.initiallyPositionEntity(realm, newPlayerEntity, new Vector3d(Globals.spawnPoint.x + 1,Globals.spawnPoint.y + 5,Globals.spawnPoint.z + 1));
|
||||
//add entity to correct cells
|
||||
realm.getDataCellManager().addPlayerToRealm(playerObject);
|
||||
}
|
||||
|
||||
static void initMacroSimulation(){
|
||||
|
||||
@ -15,7 +15,7 @@ public class ServerLoading {
|
||||
// }
|
||||
|
||||
//TODO: Globals.serverTerrainManager = new ServerTerrainManager(2000,50,100,randomDampener,0);
|
||||
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO,0.0f,0);
|
||||
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,0.0f,0);
|
||||
SaveUtils.loadSave(Globals.currentSaveName);
|
||||
// LoadingUtils.initTerrainDataCellManager();
|
||||
//TODO: set spawnpoint
|
||||
|
||||
@ -492,7 +492,6 @@ public class CreatureUtils {
|
||||
*/
|
||||
public static Entity serverSpawnBasicCreature(Realm realm, Vector3d position, String type, CreatureTemplate template){
|
||||
CreatureType rawType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(type);
|
||||
System.out.println("Creature");
|
||||
Entity rVal = EntityCreationUtils.createServerEntity(realm, position);
|
||||
EntityCreationUtils.makeEntityPoseable(rVal, rawType.getModelPath());
|
||||
|
||||
|
||||
@ -44,6 +44,9 @@ public class MacroData {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
static final int MAX_PLACEMENT_ATTEMPTS = 50;
|
||||
|
||||
public static MacroData generateWorld(long seed){
|
||||
Random random = new Random(seed);
|
||||
MacroData rVal = new MacroData();
|
||||
@ -80,6 +83,7 @@ public class MacroData {
|
||||
List<Vector2i> occupiedStartingPositions = new LinkedList<Vector2i>();
|
||||
for(Race race : rVal.races){
|
||||
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?
|
||||
@ -107,6 +111,10 @@ public class MacroData {
|
||||
}
|
||||
}
|
||||
}
|
||||
attempts++;
|
||||
if(attempts > MAX_PLACEMENT_ATTEMPTS){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package electrosphere.game.server.world;
|
||||
|
||||
import electrosphere.server.datacell.ServerDataCell;
|
||||
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||
import electrosphere.server.terrain.manager.ServerTerrainManager;
|
||||
|
||||
import java.util.List;
|
||||
@ -67,7 +68,7 @@ public class ServerWorldData {
|
||||
rVal.type = WorldType.GAME_WORLD;
|
||||
|
||||
rVal.worldMinPoint = new Vector3f(0,0,0);
|
||||
int worldDim = terrainManager.getWorldDiscreteSize() * terrainManager.getChunkWidth();
|
||||
int worldDim = terrainManager.getWorldDiscreteSize() * ServerTerrainChunk.CHUNK_DIMENSION;
|
||||
rVal.worldMaxPoint = new Vector3f(worldDim,0,worldDim);
|
||||
|
||||
rVal.dynamicInterpolationRatio = terrainManager.getDynamicInterpolationRatio();
|
||||
|
||||
@ -130,7 +130,7 @@ public class MenuGenerators {
|
||||
//create save dir
|
||||
SaveUtils.createOrOverwriteSave(saveName);
|
||||
//create and save terrain
|
||||
ServerTerrainManager terrainManager = new ServerTerrainManager(2000,50,100,0.0f,0);
|
||||
ServerTerrainManager terrainManager = new ServerTerrainManager(2000,50,0.0f,0);
|
||||
terrainManager.generate();
|
||||
terrainManager.save(SaveUtils.deriveSaveDirectoryPath(saveName));
|
||||
WindowUtils.replaceMainMenuContents(MenuGenerators.createWorldSelectMenu());
|
||||
|
||||
@ -164,7 +164,7 @@ public class ClientNetworking implements Runnable{
|
||||
//disconnected from the server
|
||||
LoggerInterface.loggerNetworking.WARNING("Disconnected from server");
|
||||
//close socket
|
||||
if(socket.isConnected()){
|
||||
if(socket != null && socket.isConnected()){
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
@ -205,13 +205,13 @@ public class ClientNetworking implements Runnable{
|
||||
(((ServerMessage)message).getMessageSubtype()) == ServerMessageType.PONG
|
||||
){
|
||||
if(this.echoPings == true){
|
||||
LoggerInterface.loggerNetworking.DEBUG("[Server] New message " + message.getType());
|
||||
LoggerInterface.loggerNetworking.DEBUG("[CLIENT] New message " + message.getType());
|
||||
}
|
||||
} else {
|
||||
LoggerInterface.loggerNetworking.DEBUG("[Server] New message " + message.getType());
|
||||
LoggerInterface.loggerNetworking.DEBUG("[CLIENT] New message " + message.getType());
|
||||
}
|
||||
} else {
|
||||
LoggerInterface.loggerNetworking.DEBUG("[Server] New message " + message.getType());
|
||||
LoggerInterface.loggerNetworking.DEBUG("[CLIENT] New message " + message.getType());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
package electrosphere.net.parser.net.raw;
|
||||
|
||||
import electrosphere.net.parser.net.message.NetworkMessage;
|
||||
package electrosphere.net.parser.net.raw;
|
||||
|
||||
import electrosphere.net.parser.net.message.NetworkMessage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
@ -15,7 +15,7 @@ public class NetworkParser {
|
||||
CopyOnWriteArrayList<NetworkMessage> incomingMessageQueue = new CopyOnWriteArrayList<NetworkMessage>();
|
||||
CopyOnWriteArrayList<NetworkMessage> outgoingMessageQueue = new CopyOnWriteArrayList<NetworkMessage>();
|
||||
|
||||
CircularByteBuffer incomingByteBuffer = new CircularByteBuffer(64 * 1024 * 124);
|
||||
CircularByteBuffer incomingByteBuffer = new CircularByteBuffer(64 * 1024 * 1024);
|
||||
CopyOnWriteArrayList<Byte> outgoingByteQueue = new CopyOnWriteArrayList<Byte>();
|
||||
|
||||
|
||||
|
||||
@ -90,9 +90,10 @@ public class Server implements Runnable{
|
||||
}
|
||||
}
|
||||
|
||||
public void addLocalPlayer(InputStream serverInputStream, OutputStream serverOutputStream){
|
||||
public ServerConnectionHandler addLocalPlayer(InputStream serverInputStream, OutputStream serverOutputStream){
|
||||
ServerConnectionHandler newClient = new ServerConnectionHandler(serverInputStream,serverOutputStream);
|
||||
clientMap.put("127.0.0.1", newClient);
|
||||
new Thread(newClient).start();
|
||||
return newClient;
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||
public class GriddedDataCellManager implements DataCellManager, VoxelCellManager {
|
||||
//these are going to be the natural ground grid of data cells, but we're going to have more than this
|
||||
Map<String,ServerDataCell> groundDataCells = new HashMap<String,ServerDataCell>();
|
||||
Map<ServerDataCell,Vector3i> cellPositionMap = new HashMap<ServerDataCell,Vector3i>();
|
||||
//loaded cells
|
||||
Semaphore loadedCellsLock = new Semaphore(1);
|
||||
Set<ServerDataCell> loadedCells;
|
||||
@ -211,6 +212,25 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
return playerChangedChunk;
|
||||
}
|
||||
|
||||
//Used for cleaning server data cells no longer in use from the realm
|
||||
Set<ServerDataCell> toCleanQueue = new HashSet<ServerDataCell>();
|
||||
/**
|
||||
* Unloads all chunks that haven't had players in them for a set amount of time
|
||||
*/
|
||||
public void unloadPlayerlessChunks(){
|
||||
//TODO: improve to make have less performance impact
|
||||
for(ServerDataCell cell : loadedCells){
|
||||
if(cell.getPlayers().size() < 1){
|
||||
System.out.println("Unload cell");
|
||||
toCleanQueue.add(cell);
|
||||
}
|
||||
}
|
||||
for(ServerDataCell cell : toCleanQueue){
|
||||
parent.deregisterCell(cell);
|
||||
}
|
||||
toCleanQueue.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data cell at a given real point in this realm
|
||||
* @param point The real point
|
||||
@ -341,6 +361,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
private ServerDataCell createServerDataCell(Vector3i worldPos){
|
||||
ServerDataCell rVal = parent.createNewCell();
|
||||
groundDataCells.put(getServerDataCellKey(worldPos),rVal);
|
||||
cellPositionMap.put(rVal,new Vector3i(worldPos));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -396,4 +417,14 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
terrainEditLock.release();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the world position of a given data cell
|
||||
* @param cell The data cell
|
||||
* @return The world position
|
||||
*/
|
||||
private Vector3i getCellWorldPosition(ServerDataCell cell){
|
||||
return cellPositionMap.get(cell);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -83,24 +83,6 @@ public class Realm {
|
||||
ServerDataCell cell = Globals.entityDataCellMapper.getEntityDataCell(e);
|
||||
cell.broadcastNetworkMessage(message);
|
||||
}
|
||||
|
||||
//Used for cleaning server data cells no longer in use from the realm
|
||||
Set<ServerDataCell> toCleanQueue = new HashSet<ServerDataCell>();
|
||||
/**
|
||||
* Unloads all chunks that haven't had players in them for a set amount of time
|
||||
*/
|
||||
public void unloadPlayerlessChunks(){
|
||||
//TODO: improve to make have less performance impact
|
||||
for(ServerDataCell cell : loadedDataCells){
|
||||
if(cell.getPlayers().size() < 1){
|
||||
toCleanQueue.add(cell);
|
||||
}
|
||||
}
|
||||
for(ServerDataCell cell : toCleanQueue){
|
||||
deregisterCell(cell);
|
||||
}
|
||||
toCleanQueue.clear();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@ -179,10 +161,7 @@ public class Realm {
|
||||
dataCellManager.simulate();
|
||||
//data cell manager update misc variables (player positions, unload not-in-use cells)
|
||||
if(dataCellManager != null){
|
||||
// boolean playerHasChangedChunk = dataCellManager.updatePlayerGroundCellPositions();
|
||||
// if(playerHasChangedChunk){
|
||||
// dataCellManager.unloadPlayerlessChunks();
|
||||
// }
|
||||
dataCellManager.unloadPlayerlessChunks();
|
||||
}
|
||||
//clear collidable impulse lists
|
||||
collisionEngine.clearCollidableImpulseLists();
|
||||
|
||||
@ -55,5 +55,10 @@ public interface DataCellManager {
|
||||
* Calls the simulate function on all loaded cells
|
||||
*/
|
||||
public void simulate();
|
||||
|
||||
/**
|
||||
* Unloads playerless chunks. Strategy for doing this is defined per data cell manager.
|
||||
*/
|
||||
public void unloadPlayerlessChunks();
|
||||
|
||||
}
|
||||
|
||||
@ -31,11 +31,11 @@ public class NavMeshUtils {
|
||||
float currentMax = 0;
|
||||
int startPos = 0;
|
||||
int endPos = 0;
|
||||
for(int x = 0; x < Globals.serverTerrainManager.getAugmentedChunkWidth() - 1; x++){
|
||||
for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION - 1; x++){
|
||||
numInCurrent = 0;
|
||||
currentMin = 0;
|
||||
currentMax = 0;
|
||||
for(int y = 0; y < Globals.serverTerrainManager.getAugmentedChunkWidth(); y++){
|
||||
for(int y = 0; y < ServerTerrainChunk.CHUNK_DIMENSION; y++){
|
||||
//create node
|
||||
if(navMeshGeneratorMask[x][y]){
|
||||
if(numInCurrent > 0){
|
||||
@ -183,12 +183,12 @@ public class NavMeshUtils {
|
||||
//why the -1? I think the array fiddling above is causing the bounds to be off normally
|
||||
//this fixes that
|
||||
NavCube cube = new NavCube(
|
||||
box.boundMinX + chunk.getWorldX() * Globals.serverTerrainManager.getChunkWidth(),
|
||||
box.boundMinX + chunk.getWorldX() * ServerTerrainChunk.CHUNK_DIMENSION,
|
||||
box.minHeight - 0.5f,
|
||||
box.boundMinY + chunk.getWorldY() * Globals.serverTerrainManager.getChunkWidth(),
|
||||
box.boundMaxX + chunk.getWorldX() * Globals.serverTerrainManager.getChunkWidth(),
|
||||
box.boundMinY + chunk.getWorldY() * ServerTerrainChunk.CHUNK_DIMENSION,
|
||||
box.boundMaxX + chunk.getWorldX() * ServerTerrainChunk.CHUNK_DIMENSION,
|
||||
box.maxHeight + 0.5f,
|
||||
box.boundMaxY + chunk.getWorldY() * Globals.serverTerrainManager.getChunkWidth()
|
||||
box.boundMaxY + chunk.getWorldY() * ServerTerrainChunk.CHUNK_DIMENSION
|
||||
);
|
||||
rVal.addNode(cube);
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package electrosphere.server.pathfinding.blocker;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -13,7 +14,7 @@ public class NavBlocker {
|
||||
boolean[][] heightfieldBlocker;
|
||||
|
||||
public NavBlocker(){
|
||||
heightfieldBlocker = new boolean[Globals.serverTerrainManager.getAugmentedChunkWidth()][Globals.serverTerrainManager.getAugmentedChunkWidth()];
|
||||
heightfieldBlocker = new boolean[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION];
|
||||
}
|
||||
|
||||
public NavBlocker(boolean[][] field){
|
||||
|
||||
@ -89,8 +89,8 @@ public class SaveUtils {
|
||||
String dbFilePath = FileUtils.sanitizeFilePath(dirPath) + "/central.db";
|
||||
Globals.dbController.connect(dbFilePath);
|
||||
if(!saveName.equals("arena")){
|
||||
Globals.serverTerrainManager.load(saveName);
|
||||
Globals.serverWorldData = FileUtils.loadObjectFromSavePath(saveName, "world.json", ServerWorldData.class);
|
||||
Globals.serverTerrainManager.load(saveName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -106,7 +106,7 @@ public class SaveUtils {
|
||||
}
|
||||
|
||||
public static boolean loadTerrainAndCreateWorldData(String currentSaveName){
|
||||
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO,0.0f,0);
|
||||
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,0.0f,0);
|
||||
SaveUtils.loadTerrainAndDB(currentSaveName);
|
||||
Globals.serverWorldData = ServerWorldData.createGameWorld(Globals.serverTerrainManager);
|
||||
Globals.realmManager.createGriddedRealm(Globals.serverWorldData);
|
||||
|
||||
@ -0,0 +1,92 @@
|
||||
package electrosphere.server.terrain.diskcache;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import electrosphere.net.server.Server;
|
||||
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||
import electrosphere.util.FileUtils;
|
||||
|
||||
/**
|
||||
* An interface for accessing the disk cache of chunk information
|
||||
*/
|
||||
public class ChunkDiskCache {
|
||||
|
||||
//The map of world position+chunk type to the file that actually houses that information
|
||||
Map<String,String> worldPosFileMap;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ChunkDiskCache(){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a key for a given chunk file based on a world coordinate
|
||||
* @param worldX The x component
|
||||
* @param worldY The y component
|
||||
* @param worldZ The z component
|
||||
* @return The key
|
||||
*/
|
||||
private static String getTerrainChunkKey(int worldX, int worldY, int worldZ){
|
||||
return worldX + "_" + worldY + "_" + worldZ + "t";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a key for a given chunk file based on a world coordinate
|
||||
* @param worldX The x component
|
||||
* @param worldY The y component
|
||||
* @param worldZ The z component
|
||||
* @return The key
|
||||
*/
|
||||
private static String getFluidChunkKey(int worldX, int worldY, int worldZ){
|
||||
return worldX + "_" + worldY + "_" + worldZ + "f";
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a diskcache based on a given save name
|
||||
* @param saveName The save name
|
||||
*/
|
||||
public void init(String saveName){
|
||||
worldPosFileMap = FileUtils.loadObjectFromSavePath(saveName, "ChunkCache.map", Map.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the cache contains a given chunk position
|
||||
* @param worldX The x component
|
||||
* @param worldY The y component
|
||||
* @param worldZ The z component
|
||||
* @return True if the cache contains the chunk, false otherwise
|
||||
*/
|
||||
public boolean containsTerrainAtPosition(int worldX, int worldY, int worldZ){
|
||||
return worldPosFileMap.containsKey(getTerrainChunkKey(worldX, worldY, worldZ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the cache contains a given chunk position
|
||||
* @param worldX The x component
|
||||
* @param worldY The y component
|
||||
* @param worldZ The z component
|
||||
* @return True if the cache contains the chunk, false otherwise
|
||||
*/
|
||||
public boolean containsFluidAtPosition(int worldX, int worldY, int worldZ){
|
||||
return worldPosFileMap.containsKey(getFluidChunkKey(worldX, worldY, worldZ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the server terrain chunk from disk if it exists, otherwise returns null
|
||||
* @param worldX The x coordinate
|
||||
* @param worldY The y coordinate
|
||||
* @param worldZ The z coordinate
|
||||
* @return The server terrain chunk if it exists, null otherwise
|
||||
*/
|
||||
public ServerTerrainChunk getTerrainChunk(int worldX, int worldY, int worldZ){
|
||||
ServerTerrainChunk rVal = null;
|
||||
if(containsTerrainAtPosition(worldX, worldY, worldZ)){
|
||||
String fileName = worldPosFileMap.get(getTerrainChunkKey(worldX, worldY, worldZ));
|
||||
//TODO: implement
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
|
||||
}
|
||||
@ -49,13 +49,16 @@ public class TerrainEditing {
|
||||
float distance = (float)new Vector3d(Math.floor(offsetPos.x),Math.floor(offsetPos.y),Math.floor(offsetPos.z)).distance(position);
|
||||
float currentPositionMagnitude = editMagnitude - distance;
|
||||
|
||||
ServerTerrainChunk data = voxelCellManager.getChunkAtPosition(chunkPos);
|
||||
ServerTerrainChunk data;
|
||||
if(
|
||||
voxelPos.x < ServerTerrainChunk.CHUNK_DIMENSION &&
|
||||
voxelPos.y < ServerTerrainChunk.CHUNK_DIMENSION &&
|
||||
voxelPos.z < ServerTerrainChunk.CHUNK_DIMENSION &&
|
||||
voxelPos.x > 0 &&
|
||||
voxelPos.y > 0 &&
|
||||
voxelPos.z > 0 &&
|
||||
currentPositionMagnitude > 0 &&
|
||||
data != null
|
||||
(data = voxelCellManager.getChunkAtPosition(chunkPos)) != null
|
||||
){
|
||||
float current = data.getWeights()[voxelPos.x][voxelPos.y][voxelPos.z];
|
||||
//hard clamp so it doesn't go over 1
|
||||
|
||||
@ -171,29 +171,29 @@ public class TerrainGenerator {
|
||||
|
||||
|
||||
//create internal renderer
|
||||
createRenderer();
|
||||
// createRenderer();
|
||||
|
||||
boolean test = true;
|
||||
while(test){
|
||||
if(brightnessIncreasing){
|
||||
if(brightness < 100){
|
||||
brightness++;
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
if(brightness > 0){
|
||||
brightness--;
|
||||
} else {
|
||||
brightnessIncreasing = true;
|
||||
displayToggle++;
|
||||
if(displayToggle > 1){
|
||||
displayToggle = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
frame.repaint();
|
||||
Utilities.sleep(10);
|
||||
}
|
||||
// boolean test = true;
|
||||
// while(test){
|
||||
// if(brightnessIncreasing){
|
||||
// if(brightness < 100){
|
||||
// brightness++;
|
||||
// } else {
|
||||
// }
|
||||
// } else {
|
||||
// if(brightness > 0){
|
||||
// brightness--;
|
||||
// } else {
|
||||
// brightnessIncreasing = true;
|
||||
// displayToggle++;
|
||||
// if(displayToggle > 1){
|
||||
// displayToggle = 0;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// frame.repaint();
|
||||
// Utilities.sleep(10);
|
||||
// }
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -1,20 +1,18 @@
|
||||
package electrosphere.server.terrain.manager;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.game.terrain.processing.TerrainInterpolator;
|
||||
import electrosphere.server.terrain.generation.TerrainGenerator;
|
||||
import electrosphere.server.terrain.models.ModificationList;
|
||||
import electrosphere.server.terrain.models.TerrainModel;
|
||||
import electrosphere.server.terrain.models.TerrainModification;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.util.FileUtils;
|
||||
import electrosphere.util.Utilities;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@ -36,8 +34,6 @@ public class ServerTerrainManager {
|
||||
//The vertical multiplier applied to the statically generated terrain
|
||||
int verticalInterpolationRatio;
|
||||
|
||||
int dynamicInterpolationRatio;
|
||||
|
||||
float interpolationRandomDampener;
|
||||
|
||||
long seed;
|
||||
@ -59,10 +55,9 @@ public class ServerTerrainManager {
|
||||
|
||||
|
||||
|
||||
public ServerTerrainManager(int worldSizeDiscrete, int verticalInterpolationRatio, int dynamicInterpolationRatio, float interpolationRandomDampener, long seed){
|
||||
public ServerTerrainManager(int worldSizeDiscrete, int verticalInterpolationRatio, float interpolationRandomDampener, long seed){
|
||||
this.worldSizeDiscrete = worldSizeDiscrete;
|
||||
this.verticalInterpolationRatio = verticalInterpolationRatio;
|
||||
this.dynamicInterpolationRatio = dynamicInterpolationRatio;
|
||||
this.chunkCache = new ConcurrentHashMap<String, ServerTerrainChunk>();
|
||||
this.chunkCacheContents = new CopyOnWriteArrayList<String>();
|
||||
this.interpolationRandomDampener = interpolationRandomDampener;
|
||||
@ -77,7 +72,6 @@ public class ServerTerrainManager {
|
||||
ServerTerrainManager rVal = new ServerTerrainManager();
|
||||
rVal.worldSizeDiscrete = 2;
|
||||
rVal.verticalInterpolationRatio = 0;
|
||||
rVal.dynamicInterpolationRatio = SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO;
|
||||
rVal.chunkCache = new ConcurrentHashMap<String, ServerTerrainChunk>();
|
||||
rVal.chunkCacheContents = new CopyOnWriteArrayList<String>();
|
||||
rVal.interpolationRandomDampener = 0.0f;
|
||||
@ -88,115 +82,47 @@ public class ServerTerrainManager {
|
||||
TerrainGenerator terrainGen = new TerrainGenerator();
|
||||
terrainGen.setInterpolationRatio(worldSizeDiscrete/200);
|
||||
terrainGen.setVerticalInterpolationRatio(verticalInterpolationRatio);
|
||||
terrainGen.setDynamicInterpolationRatio(dynamicInterpolationRatio);
|
||||
terrainGen.setRandomSeed(seed);
|
||||
model = terrainGen.generateModel();
|
||||
model.setInterpolationRandomDampener(interpolationRandomDampener);
|
||||
}
|
||||
|
||||
public void save(String path){
|
||||
Gson gson = new Gson();
|
||||
String terrainOutRaw = gson.toJson(model);
|
||||
try {
|
||||
Files.write(new File(path + "./terrain.json").toPath(), terrainOutRaw.getBytes());
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
/**
|
||||
* Saves the terrain model backing this manager to a save file
|
||||
* @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]);
|
||||
}
|
||||
floatView.flip();
|
||||
FileUtils.saveBinaryToSavePath(saveName, "./terrain.dat", buffer.array());
|
||||
FileUtils.serializeObjectToSavePath(saveName, "./terrain.json", model);
|
||||
}
|
||||
|
||||
public void load(String saveName){
|
||||
model = FileUtils.loadObjectFromSavePath(saveName, "./terrain.json", TerrainModel.class);
|
||||
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++){
|
||||
elevation[x][y] = floatView.get();
|
||||
}
|
||||
}
|
||||
model.setElevationArray(elevation);
|
||||
}
|
||||
|
||||
public float[][] getTerrainAtChunk(int x, int y){
|
||||
return model.getElevationForChunk(x, y);
|
||||
}
|
||||
|
||||
// public ServerTerrainChunk getAugmentedTerrainAtChunk(int x, int y){
|
||||
// //THIS FIRES IF THERE IS A MAIN GAME WORLD RUNNING
|
||||
// if(model != null){
|
||||
// String key = getKey(x,y);
|
||||
// ServerTerrainChunk returnedChunk;
|
||||
// if(elevationMapCache.containsKey(key)){
|
||||
// elevationMapCacheContents.remove(key);
|
||||
// elevationMapCacheContents.add(0, key);
|
||||
// returnedChunk = elevationMapCache.get(key);
|
||||
// return returnedChunk;
|
||||
// } else {
|
||||
// float[][] macroValues = model.getRad5MacroValuesAtPosition(x, y);
|
||||
// long[][] randomizer = model.getRad5RandomizerValuesAtPosition(x, y);
|
||||
// float[][] heightmap = TerrainInterpolator.getBicubicInterpolatedChunk(
|
||||
// macroValues,
|
||||
// randomizer,
|
||||
// model.getDynamicInterpolationRatio(),
|
||||
// model.getRandomDampener()
|
||||
// );
|
||||
// ModificationList modificationList = model.getModifications(x, y);
|
||||
// for(TerrainModification modification : modificationList.getModifications()){
|
||||
// modification.applyToHeightfield(heightmap);
|
||||
// }
|
||||
// if(elevationMapCacheContents.size() > cacheSize){
|
||||
// String oldChunk = elevationMapCacheContents.remove(elevationMapCacheContents.size() - 1);
|
||||
// elevationMapCache.remove(oldChunk);
|
||||
// }
|
||||
// returnedChunk = new ServerTerrainChunk(x, y, heightmap, macroValues, randomizer);
|
||||
// elevationMapCache.put(key, returnedChunk);
|
||||
// elevationMapCacheContents.add(key);
|
||||
// return returnedChunk;
|
||||
// }
|
||||
// } else {
|
||||
// //THIS FIRES IF THERE IS AN ARENA WORLD RUNNING
|
||||
// return ServerTerrainChunk.getArenaChunk(dynamicInterpolationRatio + 1);
|
||||
// }
|
||||
// }
|
||||
|
||||
public double getHeightAtPosition(double x, double y, double z){
|
||||
//get chunk coordinate space of input x,y
|
||||
// int chunkX = (int)Math.floor(x / dynamicInterpolationRatio);
|
||||
// int chunkY = (int)Math.floor(y / dynamicInterpolationRatio);
|
||||
// int chunkZ = (int)Math.floor(z / dynamicInterpolationRatio);
|
||||
// //get local coordinate space of input x,y
|
||||
// double localX = x - chunkX * dynamicInterpolationRatio;
|
||||
// double localY = y - chunkY * dynamicInterpolationRatio;
|
||||
// double localZ = z - chunkZ * dynamicInterpolationRatio;
|
||||
// //get chunk elevation map
|
||||
// float[][] chunkElevationMap = getChunk(chunkX,chunkY,chunkZ).heightMap;
|
||||
// //floored variants of local values
|
||||
// int localXf = (int)Math.floor(localX);
|
||||
// int localYf = (int)Math.floor(localY);
|
||||
// int localZf = (int)Math.floor(localZ);
|
||||
|
||||
// /*
|
||||
// Average some inner value.
|
||||
|
||||
// 01 11
|
||||
// 0.3 0.4 0.5
|
||||
// 0.1 0.2 0.3
|
||||
// 00 10
|
||||
// */
|
||||
// //interp elevation from map
|
||||
// float elevation00 = chunkElevationMap[(int)localX+0][(int)localY+0];
|
||||
// float elevation10 = chunkElevationMap[(int)localX+1][(int)localY+0];
|
||||
// float elevation01 = chunkElevationMap[(int)localX+0][(int)localY+1];
|
||||
// float elevation11 = chunkElevationMap[(int)localX+1][(int)localY+1];
|
||||
|
||||
// double rVal =
|
||||
// (1-(localX-localXf))*(1-(localY-localYf)) * elevation00 +
|
||||
// ( (localX-localXf))*(1-(localY-localYf)) * elevation10 +
|
||||
// (1-(localX-localXf))*( (localY-localYf)) * elevation01 +
|
||||
// ( (localX-localXf))*( (localY-localYf)) * elevation11
|
||||
// ;
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
public int getChunkWidth(){
|
||||
return dynamicInterpolationRatio;
|
||||
}
|
||||
|
||||
public int getAugmentedChunkWidth(){
|
||||
return dynamicInterpolationRatio + 1;
|
||||
}
|
||||
|
||||
public int getWorldDiscreteSize(){
|
||||
return worldSizeDiscrete;
|
||||
@ -229,36 +155,6 @@ public class ServerTerrainManager {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// public float[][] getMacroValues(int x, int y){
|
||||
// //THIS FIRES IF THERE IS A MAIN GAME WORLD RUNNING
|
||||
// if(model != null){
|
||||
// return model.getMacroValuesAtPosition(x, y);
|
||||
// } else {
|
||||
// //THIS FIRES IF THERE IS AN ARENA WORLD RUNNING
|
||||
// return new float[3][3];
|
||||
// }
|
||||
// }
|
||||
|
||||
// public float[][] getRad5MacroValues(int x, int y){
|
||||
// //THIS FIRES IF THERE IS A MAIN GAME WORLD RUNNING
|
||||
// if(model != null){
|
||||
// return model.getRad5MacroValuesAtPosition(x, y);
|
||||
// } else {
|
||||
// //THIS FIRES IF THERE IS AN ARENA WORLD RUNNING
|
||||
// return new float[5][5];
|
||||
// }
|
||||
// }
|
||||
|
||||
// public long[][] getRandomizer(int x, int y){
|
||||
// //THIS FIRES IF THERE IS A MAIN GAME WORLD RUNNING
|
||||
// if(model != null){
|
||||
// return model.getRad5RandomizerValuesAtPosition(x, y);
|
||||
// } else {
|
||||
// //THIS FIRES IF THERE IS AN ARENA WORLD RUNNING
|
||||
// return new long[5][5];
|
||||
// }
|
||||
// }
|
||||
|
||||
public TerrainModel getModel() {
|
||||
return model;
|
||||
@ -294,9 +190,13 @@ public class ServerTerrainManager {
|
||||
for(int weightX = 0; weightX < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; weightX++){
|
||||
for(int weightY = 0; weightY < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; weightY++){
|
||||
for(int weightZ = 0; weightZ < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; weightZ++){
|
||||
if(weightY < heightmap[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE * worldX + weightX][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE * worldZ + weightZ]){
|
||||
float height = heightmap[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE * worldX + weightX][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE * worldZ + weightZ];
|
||||
if(weightY < height){
|
||||
weights[weightX][weightY][weightZ] = 1;
|
||||
values[weightX][weightY][weightZ] = 1;
|
||||
} else if(height == 0 && weightY == 0 && worldY == 0) {
|
||||
weights[weightX][weightY][weightZ] = 0.1f;
|
||||
values[weightX][weightY][weightZ] = 1;
|
||||
} else {
|
||||
weights[weightX][weightY][weightZ] = -1;
|
||||
values[weightX][weightY][weightZ] = 0;
|
||||
@ -304,12 +204,6 @@ public class ServerTerrainManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
// ModificationList modificationList = model.getModifications(x, y);
|
||||
// if(modificationList != null){
|
||||
// for(TerrainModification modification : modificationList.getModifications()){
|
||||
// heightmap = modification.applyToHeightfield(heightmap);
|
||||
// }
|
||||
// }
|
||||
if(chunkCacheContents.size() > cacheSize){
|
||||
String oldChunk = chunkCacheContents.remove(chunkCacheContents.size() - 1);
|
||||
chunkCache.remove(oldChunk);
|
||||
|
||||
@ -6,13 +6,16 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import electrosphere.util.annotation.Exclude;
|
||||
|
||||
public class TerrainModel {
|
||||
|
||||
int dynamicInterpolationRatio;
|
||||
float interpolationRandomDampener = 0.4f;
|
||||
|
||||
int discreteArrayDimension;
|
||||
float[][] elevation;
|
||||
@Exclude
|
||||
private float[][] elevation;
|
||||
|
||||
float realMountainThreshold;
|
||||
float realOceanThreshold;
|
||||
@ -345,5 +348,13 @@ public class TerrainModel {
|
||||
// System.out.println("Got modifications at " + worldX + " " + worldY);
|
||||
return modifications.get(getModificationKey(worldX, worldY, worldZ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the elevation array (For instance when read from save file on loading a save)
|
||||
* @param elevation The elevation array to set to
|
||||
*/
|
||||
public void setElevationArray(float[][] elevation){
|
||||
this.elevation = elevation;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import com.google.gson.GsonBuilder;
|
||||
import electrosphere.engine.Main;
|
||||
import electrosphere.game.data.creature.type.movement.MovementSystem;
|
||||
import electrosphere.game.data.creature.type.movement.MovementSystemSerializer;
|
||||
import electrosphere.util.annotation.AnnotationExclusionStrategy;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
@ -26,6 +27,8 @@ public class FileUtils {
|
||||
static {
|
||||
GsonBuilder gsonBuilder = new GsonBuilder();
|
||||
gsonBuilder.registerTypeAdapter(MovementSystem.class, new MovementSystemSerializer());
|
||||
gsonBuilder.addDeserializationExclusionStrategy(new AnnotationExclusionStrategy());
|
||||
gsonBuilder.addSerializationExclusionStrategy(new AnnotationExclusionStrategy());
|
||||
gson = gsonBuilder.create();
|
||||
}
|
||||
|
||||
@ -209,6 +212,39 @@ public class FileUtils {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a binary file as an array of bytes
|
||||
* @param saveName The save name
|
||||
* @param pathName The path within the save folder
|
||||
* @return The array of bytes
|
||||
*/
|
||||
public static byte[] loadBinaryFromSavePath(String saveName, String pathName){
|
||||
byte[] rVal = null;
|
||||
String sanitizedFilePath = sanitizeFilePath(pathName);
|
||||
try {
|
||||
rVal = Files.readAllBytes(getSaveFile(saveName,sanitizedFilePath).toPath());
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a binary file to a save folder's file
|
||||
* @param saveName The name of the save
|
||||
* @param pathName The path within the save folder
|
||||
* @param data The data to write
|
||||
*/
|
||||
public static void saveBinaryToSavePath(String saveName, String pathName, byte[] data){
|
||||
String sanitizedFilePath = sanitizeFilePath(pathName);
|
||||
try {
|
||||
Files.write(getSaveFile(saveName,sanitizedFilePath).toPath(), data);
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a directory exists
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
package electrosphere.util.annotation;
|
||||
|
||||
import com.google.gson.ExclusionStrategy;
|
||||
import com.google.gson.FieldAttributes;
|
||||
|
||||
/**
|
||||
* Used to exclude single fields from a gson serialization in a black list manner.
|
||||
* Refer to https://stackoverflow.com/a/27986860/ for reference for why this works and what it is.
|
||||
*/
|
||||
public class AnnotationExclusionStrategy implements ExclusionStrategy {
|
||||
|
||||
@Override
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
return f.getAnnotation(Exclude.class) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
17
src/main/java/electrosphere/util/annotation/Exclude.java
Normal file
17
src/main/java/electrosphere/util/annotation/Exclude.java
Normal file
@ -0,0 +1,17 @@
|
||||
package electrosphere.util.annotation;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.annotation.ElementType;
|
||||
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
/**
|
||||
* Used to exclude single fields from a gson serialization in a black list manner.
|
||||
* Refer to https://stackoverflow.com/a/27986860/ for reference for why this works and what it is.
|
||||
*/
|
||||
public @interface Exclude {
|
||||
|
||||
}
|
||||
@ -19,7 +19,7 @@ public class TerrainViewer {
|
||||
|
||||
TerrainModel terrainModel;
|
||||
|
||||
ServerTerrainManager terrainManager = new ServerTerrainManager(2000, 1000, 100, 0.05f, new Random().nextLong());
|
||||
ServerTerrainManager terrainManager = new ServerTerrainManager(2000, 1000, 0.05f, new Random().nextLong());
|
||||
terrainManager.generate();
|
||||
terrainModel = terrainManager.getModel();
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user