Terrain generation improvements

This commit is contained in:
austin 2023-05-28 13:07:29 -04:00
parent 0273bc54c8
commit fda4a9584b
10 changed files with 1106 additions and 726 deletions

View File

@ -15,6 +15,7 @@ import electrosphere.game.config.UserSettings;
import electrosphere.logger.LoggerInterface;
import electrosphere.renderer.Model;
import electrosphere.renderer.RenderingEngine;
import electrosphere.util.worldviewer.TerrainViewer;
@ -127,7 +128,7 @@ public class Main {
//debug: create terrain/world viewer
// TerrainViewer.runViewer();
// TerrainViewer.runViewer();
//create the drawing context
if(Globals.RUN_CLIENT && !Globals.HEADLESS){

View File

@ -1,10 +1,10 @@
package electrosphere.game.server.terrain.generation;
/**
*
* @author satellite
* Contains information about a continent
*/
class Continent {
//dimensions of the condinent
public int dim_x;
public int dim_y;
public int size = 0;

View File

@ -15,7 +15,7 @@ class Hotspot {
TerrainGenerator parent;
public Hotspot(int x, int y, int life_max, int magnitude, TerrainGenerator parent) {
protected Hotspot(int x, int y, int life_max, int magnitude, TerrainGenerator parent) {
this.x = x;
this.y = y;
this.life_current = 0;
@ -25,7 +25,7 @@ class Hotspot {
this.parent = parent;
}
public void simulate() {
protected void simulate() {
if ((1.0f - (Math.abs((life_max / 2) - life_current) / (life_max / 2))) > 0.8f) {
magnitude_current = magnitude_max;
} else if ((1.0f - (Math.abs((life_max / 2) - life_current) / (life_max / 2))) > 0.6f) {
@ -39,103 +39,104 @@ class Hotspot {
}
//affect asthenosphere heat
if (magnitude_current == 1) {
parent.asthenosphere_Heat[x][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
} else if (magnitude_current == 2) {
parent.asthenosphere_Heat[x][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
if (x + 1 < parent.DIMENSION) {
parent.asthenosphere_Heat[x + 1][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x + 1][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
if (x - 1 >= 0) {
parent.asthenosphere_Heat[x - 1][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x - 1][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
if (y + 1 < parent.DIMENSION) {
parent.asthenosphere_Heat[x][y + 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x][y + 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
if (y - 1 >= 0) {
parent.asthenosphere_Heat[x][y - 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x][y - 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
} else if (magnitude_current == 3) {
parent.asthenosphere_Heat[x][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
if (x + 1 < parent.DIMENSION) {
parent.asthenosphere_Heat[x + 1][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x + 1][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
if (x - 1 >= 0) {
parent.asthenosphere_Heat[x - 1][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x - 1][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
if (y + 1 < parent.DIMENSION) {
parent.asthenosphere_Heat[x][y + 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x][y + 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
if (x + 1 < parent.DIMENSION) {
parent.asthenosphere_Heat[x + 1][y + 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x + 1][y + 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
if (x - 1 >= 0) {
parent.asthenosphere_Heat[x - 1][y + 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x - 1][y + 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
}
if (y - 1 >= 0) {
parent.asthenosphere_Heat[x][y - 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x][y - 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
if (x + 1 < parent.DIMENSION) {
parent.asthenosphere_Heat[x + 1][y - 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x + 1][y - 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
if (x - 1 >= 0) {
parent.asthenosphere_Heat[x - 1][y - 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x - 1][y - 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
}
} else if (magnitude_current == 4) {
parent.asthenosphere_Heat[x][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
if (x + 1 < parent.DIMENSION) {
parent.asthenosphere_Heat[x + 1][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x + 1][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
if (x - 1 >= 0) {
parent.asthenosphere_Heat[x - 1][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x - 1][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
if (y + 1 < parent.DIMENSION) {
parent.asthenosphere_Heat[x][y + 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x][y + 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
if (x + 1 < parent.DIMENSION) {
parent.asthenosphere_Heat[x + 1][y + 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x + 1][y + 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
if (x - 1 >= 0) {
parent.asthenosphere_Heat[x - 1][y + 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x - 1][y + 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
}
if (y - 1 >= 0) {
parent.asthenosphere_Heat[x][y - 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x][y - 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
if (x + 1 < parent.DIMENSION) {
parent.asthenosphere_Heat[x + 1][y - 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x + 1][y - 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
if (x - 1 >= 0) {
parent.asthenosphere_Heat[x - 1][y - 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x - 1][y - 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
}
} else if (magnitude_current == 5) {
parent.asthenosphere_Heat[x][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
if (x + 1 < parent.DIMENSION) {
parent.asthenosphere_Heat[x + 1][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x + 1][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
if (x - 1 >= 0) {
parent.asthenosphere_Heat[x - 1][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x - 1][y] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
if (y + 1 < parent.DIMENSION) {
parent.asthenosphere_Heat[x][y + 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x][y + 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
if (x + 1 < parent.DIMENSION) {
parent.asthenosphere_Heat[x + 1][y + 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x + 1][y + 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
if (x - 1 >= 0) {
parent.asthenosphere_Heat[x - 1][y + 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x - 1][y + 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
}
if (y - 1 >= 0) {
parent.asthenosphere_Heat[x][y - 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x][y - 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
if (x + 1 < parent.DIMENSION) {
parent.asthenosphere_Heat[x + 1][y - 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x + 1][y - 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
if (x - 1 >= 0) {
parent.asthenosphere_Heat[x - 1][y - 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
parent.asthenosphereHeat[x - 1][y - 1] = (int) (100.0f - Math.abs((life_max / 2) - life_current) * 100 / (life_max / 2));
}
}
}
life_current++;
}
public void add_to_elevation(int x, int y, int magnitude){
protected void add_to_elevation(int x, int y, int magnitude){
parent.elevation[x][y] = parent.elevation[x][y] + magnitude;
if(parent.elevation[x][y] > 100){
parent.elevation[x][y] = 100;

View File

@ -9,52 +9,60 @@ import javax.swing.JPanel;
* @author satellite
*/
class InterpolationDisplay extends JPanel{
TerrainGen parent;
protected InterpolationDisplay(TerrainGen parent){
this.parent = parent;
}
@Override
public void paint(Graphics g) {
if(TerrainGen.display_toggle == 0) {
for (int x = 0; x < TerrainGen.DIMENSION; x++) {
for (int y = 0; y < TerrainGen.DIMENSION; y++) {
if (TerrainGen.mountainParsed[x][y] > TerrainGen.MOUNTAIN_THRESHOLD - 1) {
g.setColor(new Color((int) (TerrainGen.elevation[x][y] / 100.0 * 254 * (TerrainGen.brightness / 100.0)), 1, 1));
} else if (TerrainGen.oceanParsed[x][y] > TerrainGen.OCEAN_THRESHOLD - 1) {
int width = parent.continentPhaseDimension;
if(parent.displayToggle == 0) {
for (int x = 0; x < width; x++) {
for (int y = 0; y < width; y++) {
if (parent.mountainParsed[x][y] > TerrainGen.MOUNTAIN_THRESHOLD - 1) {
g.setColor(new Color((int) (parent.elevation[x][y] / 100.0 * 254 * (parent.brightness / 100.0)), 1, 1));
} else if (parent.oceanParsed[x][y] > TerrainGen.OCEAN_THRESHOLD - 1) {
g.setColor(
new Color(
1,
(int) ((TerrainGen.elevation[x][y] + 50) / 100.0 * 254 * (TerrainGen.brightness / 100.0)),
(int) ((TerrainGen.elevation[x][y] + 50) / 100.0 * 254 * (TerrainGen.brightness / 100.0))
(int) ((parent.elevation[x][y] + 50) / 100.0 * 254 * (parent.brightness / 100.0)),
(int) ((parent.elevation[x][y] + 50) / 100.0 * 254 * (parent.brightness / 100.0))
)
);
} else {
g.setColor(new Color(1, (int) (TerrainGen.elevation[x][y] / 100.0 * 254 * (TerrainGen.brightness / 100.0)), 1));
g.setColor(new Color(1, (int) (parent.elevation[x][y] / 100.0 * 254 * (parent.brightness / 100.0)), 1));
}
g.fillRect(x * 2 + 25, y * 2 + 25, 2, 2);
}
}
} else if(TerrainGen.display_toggle == 1){
for (int x = 0; x < TerrainGen.DIMENSION; x++) {
for (int y = 0; y < TerrainGen.DIMENSION; y++) {
if (TerrainGen.precipitationChart[x][y] > 0) {
} else if(parent.displayToggle == 1){
for (int x = 0; x < width; x++) {
for (int y = 0; y < width; y++) {
if (parent.precipitationChart[x][y] > 0) {
g.setColor(
new Color(
1,
(int) ((TerrainGen.elevation[x][y]) / 100.0 * 254 * (TerrainGen.brightness / 100.0)),
(int) ((TerrainGen.elevation[x][y]) / 100.0 * 254 * (TerrainGen.brightness / 100.0))
(int) ((parent.elevation[x][y]) / 100.0 * 254 * (parent.brightness / 100.0)),
(int) ((parent.elevation[x][y]) / 100.0 * 254 * (parent.brightness / 100.0))
)
);
} else {
g.setColor(new Color((int) (TerrainGen.elevation[x][y] / 100.0 * 254 * (TerrainGen.brightness / 100.0)), 1, 1));
g.setColor(new Color((int) (parent.elevation[x][y] / 100.0 * 254 * (parent.brightness / 100.0)), 1, 1));
}
g.fillRect(x * 2 + 25, y * 2 + 25, 2, 2);
}
}
} else if(TerrainGen.display_toggle == 2){
for (int x = 0; x < TerrainGen.DIMENSION; x++) {
for (int y = 0; y < TerrainGen.DIMENSION; y++) {
} else if(parent.displayToggle == 2){
for (int x = 0; x < width; x++) {
for (int y = 0; y < width; y++) {
// if (TerrainInterpolator.precipitation_Chart[x][y] > 0) {
g.setColor(
new Color(
(int) ((TerrainGen.temperatureChart[x][y]) / 100.0 * 254 * (TerrainGen.brightness / 100.0)),
(int) ((TerrainGen.elevation[x][y]) / 100.0 * 254 * (TerrainGen.brightness / 100.0)),
(int) ((parent.temperatureChart[x][y]) / 100.0 * 254 * (parent.brightness / 100.0)),
(int) ((parent.elevation[x][y]) / 100.0 * 254 * (parent.brightness / 100.0)),
1
)
);
@ -64,10 +72,10 @@ class InterpolationDisplay extends JPanel{
g.fillRect(x * 2 + 25, y * 2 + 25, 2, 2);
}
}
} else if(TerrainGen.display_toggle == 3){
for (int x = 0; x < TerrainGen.DIMENSION; x++) {
for (int y = 0; y < TerrainGen.DIMENSION; y++) {
if (TerrainGen.climateCategory[x][y] == 0) {
} else if(parent.displayToggle == 3){
for (int x = 0; x < width; x++) {
for (int y = 0; y < width; y++) {
if (parent.climateCategory[x][y] == 0) {
g.setColor(Color.BLUE);
// g.setColor(
// new Color(
@ -76,7 +84,7 @@ class InterpolationDisplay extends JPanel{
// (int) ((TerrainInterpolator.elevation[x][y]) / 100.0 * 254 * (TerrainInterpolator.brightness / 100.0))
// )
// );
} else if(TerrainGen.climateCategory[x][y] == 1){
} else if(parent.climateCategory[x][y] == 1){
g.setColor(Color.RED);
// g.setColor(
// new Color(
@ -85,7 +93,7 @@ class InterpolationDisplay extends JPanel{
// 1
// )
// );
} else if(TerrainGen.climateCategory[x][y] == 2){
} else if(parent.climateCategory[x][y] == 2){
g.setColor(Color.GREEN);
// g.setColor(
// new Color(
@ -94,7 +102,7 @@ class InterpolationDisplay extends JPanel{
// 1
// )
// );
} else if(TerrainGen.climateCategory[x][y] == 3){
} else if(parent.climateCategory[x][y] == 3){
g.setColor(Color.YELLOW);
// g.setColor(
// new Color(
@ -103,58 +111,58 @@ class InterpolationDisplay extends JPanel{
// (int) ((TerrainInterpolator.elevation[x][y]) / 100.0 * 254 * (TerrainInterpolator.brightness / 100.0))
// )
// );
} else if(TerrainGen.climateCategory[x][y] == 4){
} else if(parent.climateCategory[x][y] == 4){
g.setColor(
new Color(
(int) ((TerrainGen.elevation[x][y]) / 100.0 * 254 * (TerrainGen.brightness / 100.0)),
(int) ((TerrainGen.elevation[x][y]) / 100.0 * 254 * (TerrainGen.brightness / 100.0)),
(int) ((parent.elevation[x][y]) / 100.0 * 254 * (parent.brightness / 100.0)),
(int) ((parent.elevation[x][y]) / 100.0 * 254 * (parent.brightness / 100.0)),
1
)
);
g.setColor(Color.ORANGE);
} else if(TerrainGen.climateCategory[x][y] == 5){
} else if(parent.climateCategory[x][y] == 5){
g.setColor(
new Color(
(int) ((TerrainGen.elevation[x][y]) / 100.0 * 254 * (TerrainGen.brightness / 100.0)),
(int) ((parent.elevation[x][y]) / 100.0 * 254 * (parent.brightness / 100.0)),
1,
(int) ((TerrainGen.elevation[x][y]) / 100.0 * 254 * (TerrainGen.brightness / 100.0))
(int) ((parent.elevation[x][y]) / 100.0 * 254 * (parent.brightness / 100.0))
)
);
g.setColor(Color.BLACK);
} else if(TerrainGen.climateCategory[x][y] == 6){
} else if(parent.climateCategory[x][y] == 6){
g.setColor(
new Color(
(int) ((TerrainGen.elevation[x][y]) / 100.0 * 254 * (TerrainGen.brightness / 100.0)),
(int) ((TerrainGen.elevation[x][y]) / 100.0 * 254 * (TerrainGen.brightness / 100.0)),
(int) ((TerrainGen.elevation[x][y]) / 100.0 * 254 * (TerrainGen.brightness / 100.0))
(int) ((parent.elevation[x][y]) / 100.0 * 254 * (parent.brightness / 100.0)),
(int) ((parent.elevation[x][y]) / 100.0 * 254 * (parent.brightness / 100.0)),
(int) ((parent.elevation[x][y]) / 100.0 * 254 * (parent.brightness / 100.0))
)
);
} else {
g.setColor(new Color((int) (TerrainGen.elevation[x][y] / 100.0 * 254 * (TerrainGen.brightness / 100.0)), 1, 1));
g.setColor(new Color((int) (parent.elevation[x][y] / 100.0 * 254 * (parent.brightness / 100.0)), 1, 1));
}
g.fillRect(x * 2 + 25, y * 2 + 25, 2, 2);
}
}
} else if(TerrainGen.display_toggle == 4){
for (int x = 0; x < TerrainGen.DIMENSION; x++) {
for (int y = 0; y < TerrainGen.DIMENSION; y++) {
if (TerrainGen.continentIdField[x][y] > 8) {
} else if(parent.displayToggle == 4){
for (int x = 0; x < width; x++) {
for (int y = 0; y < width; y++) {
if (parent.continentIdField[x][y] > 8) {
g.setColor(Color.PINK);
} else if (TerrainGen.continentIdField[x][y] > 7) {
} else if (parent.continentIdField[x][y] > 7) {
g.setColor(Color.DARK_GRAY);
} else if (TerrainGen.continentIdField[x][y] > 6) {
} else if (parent.continentIdField[x][y] > 6) {
g.setColor(Color.CYAN);
} else if (TerrainGen.continentIdField[x][y] > 5) {
} else if (parent.continentIdField[x][y] > 5) {
g.setColor(Color.GRAY);
} else if (TerrainGen.continentIdField[x][y] > 4) {
} else if (parent.continentIdField[x][y] > 4) {
g.setColor(Color.orange);
} else if (TerrainGen.continentIdField[x][y] > 3) {
} else if (parent.continentIdField[x][y] > 3) {
g.setColor(Color.green);
} else if (TerrainGen.continentIdField[x][y] > 2) {
} else if (parent.continentIdField[x][y] > 2) {
g.setColor(Color.yellow);
} else if (TerrainGen.continentIdField[x][y] > 1) {
} else if (parent.continentIdField[x][y] > 1) {
g.setColor(Color.blue);
} else if (TerrainGen.continentIdField[x][y] > 0) {
} else if (parent.continentIdField[x][y] > 0) {
g.setColor(Color.red);
} else {
g.setColor(Color.BLACK);
@ -162,30 +170,30 @@ class InterpolationDisplay extends JPanel{
g.fillRect(x * 2 + 25, y * 2 + 25, 2, 2);
}
}
} else if (TerrainGen.display_toggle == 5) {
Continent current = TerrainGen.continents.get(TerrainGen.current_Continent);
} else if (parent.displayToggle == 5) {
Continent current = parent.continents.get(parent.current_Continent);
g.drawString("dim_x: " + current.dim_x, 20, 20);
g.drawString("dim_y: " + current.dim_y, 20, 30);
for (int x = 0; x < current.dim_x; x++) {
for (int y = 0; y < current.dim_y; y++) {
if (current.elevation[x][y] > 10) {
g.setColor(new Color(1, (int) (current.elevation[x][y] / 100.0 * 254 * (TerrainGen.brightness / 100.0)), 1));
g.setColor(new Color(1, (int) (current.elevation[x][y] / 100.0 * 254 * (parent.brightness / 100.0)), 1));
g.fillRect(50 + x * 2, 50 + y * 2, 2, 2);
}
}
}
} else if (TerrainGen.display_toggle == 6){
Continent current = TerrainGen.continents.get(TerrainGen.current_Continent);
for(int x = 0; x < Region.REGION_DIMENSION; x++){
for(int y = 0; y < Region.REGION_DIMENSION; y++){
if(current.regions[TerrainGen.current_Region_X][TerrainGen.current_Region_Y].chart_Drainage[x][y] > 0){
g.setColor(Color.BLUE);
} else {
g.setColor(Color.BLACK);
}
g.fillRect(50 + x * 2, 50 + y * 2, 2, 2);
}
}
} else if (parent.displayToggle == 6){
// Continent current = parent.continents.get(parent.current_Continent);
// for(int x = 0; x < Region.REGION_DIMENSION; x++){
// for(int y = 0; y < Region.REGION_DIMENSION; y++){
// if(current.regions[parent.current_Region_X][parent.current_Region_Y].chart_Drainage[x][y] > 0){
// g.setColor(Color.BLUE);
// } else {
// g.setColor(Color.BLACK);
// }
// g.fillRect(50 + x * 2, 50 + y * 2, 2, 2);
// }
// }
}
// if(TerrainInterpolator.display_toggle == 0) {
// g.drawString("Elevation Raws", 10, 10);

View File

@ -5,6 +5,7 @@ package electrosphere.game.server.terrain.generation;
* @author satellite
*/
class Region {
public static int REGION_DIMENSION = 100;
int chart_Elevation[][];
int chart_Drainage[][];
@ -12,8 +13,10 @@ class Region {
int elevation_Goal;
Region neighbors[][];
public boolean finished_Drainage_Simulation = false;
public Region(){
protected Region(){
neighbors = new Region[3][3];
neighbors[1][1] = null;
}
}

View File

@ -4,126 +4,157 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
/**
*
* @author satellite
* Core continent phase terrain generator
*/
class TerrainGenerator {
static int DIMENSION = 200;
static int[][] asthenosphere_Heat;
static int[][] rock_Hardness;
static int[][] elevation;
static int[][] smoothed_elevation;
static int new_Elevation[][];
static Vector[][] currents;
static List<Hotspot> spots = new ArrayList<Hotspot>();
static int Time = 0;
static final int ELEVATION_DATA_LENGTH = 50;
static int[] elevation_Data;
static int current_Max_Elevation_Data = 1;
static int lifespan = 75000;
public TerrainGenerator(){
//size of a parallelized chunk
static final int PARALLEL_CHUNK_SIZE = 32;
//number of threads for threadpool
static final int THREAD_POOL_COUNT = 16;
//the dimensions of the map
int DIMENSION = 200;
int[][] asthenosphereHeat;
int[][] rockHardness;
int[][] elevation;
int[][] smoothedElevation;
int currentElev[][];
int newElevation[][];
//currents used for pushing terrain elevation around the map
Vector[][] currents;
//hotspots that thrust rock up from the ocean floor
List<Hotspot> spots = new ArrayList<Hotspot>();
int time = 0;
int lifespan = 75000;
Random rand;
//thread pool for parallelized force calculation
ThreadPoolExecutor threadPool;
/**
* Constructor
* @param seed Seed for random
*/
protected TerrainGenerator(long seed){
this.rand = new Random(seed);
threadPool = (ThreadPoolExecutor)Executors.newFixedThreadPool(THREAD_POOL_COUNT);
}
public void set_Dimension(int new_Dim){
DIMENSION = new_Dim;
/**
* Sets the data width
* @param newDim The dimension of the data
*/
protected void setDimension(int newDim){
DIMENSION = newDim;
if(DIMENSION % PARALLEL_CHUNK_SIZE != 0){
//this requirement is for parallelization purposes
throw new Error("DIMENSION MUST BE A MULTIPLE OF 16!");
}
}
public void set_Lifespan(int new_Lifespan){
lifespan = new_Lifespan;
/**
* Sets the simulation lifespan for the Continent Phase
* @param newLifespan The lifespan in units of simulation frames
*/
protected void setLifespan(int newLifespan){
lifespan = newLifespan;
}
/**
* Runs the continent phase simulation. Blocks until completed
*/
protected void run(){
allocateData();
long lastTime = System.currentTimeMillis();
//construct convection cells prior to simulation
constructConvectionCells();
//main simulation
while(true){
time++;
simulateHotspots();
heatToElevation();
applyVectorsToElevationParallel();
calculateSmoothedElevations();
// try {
// TimeUnit.MILLISECONDS.sleep(1);
// } catch (InterruptedException ex) {
// }
if(time % 500 == 0) {
long new_Time = System.currentTimeMillis();
long time_Delta = new_Time - lastTime;
lastTime = new_Time;
System.out.println("Progress: " + time + "/" + lifespan + " ETA: " + (time_Delta * (lifespan - time) / 1000 / 500) + "S");
}
if(time > lifespan){
break;
}
}
//TODO:
//next subphase is to find large areas without continents and place ones there
//the terrain added in this next phase will be made with a more quick and dirty implementation
//shutdown threadpool
threadPool.shutdown();
}
/**
* Gets the raw terrain
* @return The raw terrain
*/
protected int[][] getTerrain(){
return elevation;
}
/**
* Gets the terrain smoothed
* @return The terrain smoothed
*/
protected int[][] getTerrainSmoothed(){
return smoothedElevation;
}
public void run(){
asthenosphere_Heat = new int[DIMENSION][DIMENSION];
/**
* Allocates all arrays generated based on the dimension provided
*/
private void allocateData(){
asthenosphereHeat = new int[DIMENSION][DIMENSION];
elevation = new int[DIMENSION][DIMENSION];
smoothed_elevation = new int[DIMENSION][DIMENSION];
new_Elevation = new int[DIMENSION][DIMENSION];
smoothedElevation = new int[DIMENSION][DIMENSION];
newElevation = new int[DIMENSION][DIMENSION];
currents = new Vector[DIMENSION][DIMENSION];
currentElev = new int[DIMENSION][DIMENSION];
for(int x = 0; x < DIMENSION; x++){
for(int y = 0; y < DIMENSION; y++){
currents[x][y] = new Vector();
}
}
elevation_Data = new int[ELEVATION_DATA_LENGTH];
for(int x = 0; x < ELEVATION_DATA_LENGTH; x++){
elevation_Data[x] = 0;
}
long last_Time = System.currentTimeMillis();
while(true){
Time++;
if(spots.size() >= 1){
List<Hotspot> to_Remove = new ArrayList<Hotspot>();
Iterator<Hotspot> spot_Iterator = spots.iterator();
while(spot_Iterator.hasNext()){
Hotspot current_Spot = spot_Iterator.next();
if(current_Spot.life_current >= current_Spot.life_max){
to_Remove.add(current_Spot);
}
}
spot_Iterator = to_Remove.iterator();
while(spot_Iterator.hasNext()){
Hotspot current_Spot = spot_Iterator.next();
spots.remove(current_Spot);
}
}
if(spots.size() < 5){
spots.add(new Hotspot(electrosphere.game.server.terrain.generation.Utilities.random_Integer(0, DIMENSION - 1),electrosphere.game.server.terrain.generation.Utilities.random_Integer(0, DIMENSION - 1),electrosphere.game.server.terrain.generation.Utilities.random_Integer(6000, 10000), electrosphere.game.server.terrain.generation.Utilities.random_Integer(3, 5), this));
}
for(int x = 0; x < DIMENSION; x++){
for(int y = 0; y < DIMENSION; y++){
asthenosphere_Heat[x][y] = 0;
}
}
if(spots.size() >= 1){
Iterator<Hotspot> spot_Iterator = spots.iterator();
while(spot_Iterator.hasNext()){
Hotspot current_Spot = spot_Iterator.next();
current_Spot.simulate();
}
}
// try {
// TimeUnit.MILLISECONDS.sleep(1);
// } catch (InterruptedException ex) {
// }
heat_To_Elevation();
construct_Convection_Cells();
apply_Vectors_To_Elevation();
calculate_Smoothed_Elevations();
if(Time % 500 == 0) {
long new_Time = System.currentTimeMillis();
long time_Delta = new_Time - last_Time;
last_Time = new_Time;
System.out.println("Progress: " + Time + "/" + lifespan + " ETA: " + (time_Delta * (lifespan - Time) / 1000 / 500) + "S");
}
if(Time > lifespan){
break;
}
}
}
public int[][] get_Terrain(){
return elevation;
}
public int[][] get_Terrain_Smoothed(){
return smoothed_elevation;
}
static void heat_To_Elevation(){
/**
* If the asthenosphere is sufficiently hot, increases elevation of position
*/
private void heatToElevation(){
for(int x = 0; x < DIMENSION; x++){
for(int y = 0; y < DIMENSION; y++){
if(asthenosphere_Heat[x][y] > 25){
if(electrosphere.game.server.terrain.generation.Utilities.random_Integer(1, 10) == 10){
if(asthenosphereHeat[x][y] > 25){
if(electrosphere.game.server.terrain.generation.Utilities.random_Integer(1, 10, rand) == 10){
elevation[x][y] = elevation[x][y] + 1;
if(elevation[x][y] > 100){
elevation[x][y] = 100;
@ -134,160 +165,172 @@ class TerrainGenerator {
}
}
static void construct_Convection_Cells(){
boolean is_cell_type_1 = false;
/**
* Constructs convection cells in the force vector field
*/
private void constructConvectionCells(){
//controls whether the cell rotates clockwise or couterclockwise
boolean isCellType1 = false;
//one fourth of the width of the data set
int fourth = DIMENSION / 4;
for(int x = 0; x < DIMENSION; x++){
for(int y = 0; y < DIMENSION; y++){
int normalized_x = x;
int normalized_y = y;
//the current position RELATIVE to the center point of the current convection cell center
int normalizedX = x;
int normalizedY = y;
//determine relative position and whether convection cell type one or two
if(y < fourth || (y < fourth * 3 && y > (fourth * 2) - 1)){
is_cell_type_1 = true;
if(normalized_y > fourth){
normalized_y = normalized_y - fourth * 2;
isCellType1 = true;
if(normalizedY > fourth){
normalizedY = normalizedY - fourth * 2;
}
} else {
is_cell_type_1 = false;
if(normalized_y > fourth * 2 + 1){
normalized_y = normalized_y - fourth * 3;
isCellType1 = false;
if(normalizedY > fourth * 2 + 1){
normalizedY = normalizedY - fourth * 3;
} else {
normalized_y = normalized_y - fourth;
normalizedY = normalizedY - fourth;
}
}
while(normalized_x > fourth){
normalized_x = normalized_x - fourth;
while(normalizedX > fourth){
normalizedX = normalizedX - fourth;
}
if(normalized_x < 0){
normalized_x = 0;
if(normalizedX < 0){
normalizedX = 0;
}
if(normalized_y < 0){
normalized_y = 0;
if(normalizedY < 0){
normalizedY = 0;
}
//one eighth of the width of the data set
int eigth = fourth / 2;
normalized_y = normalized_y - eigth;
normalized_x = normalized_x - eigth;
float magnitude = (float)Math.sqrt(Math.pow(normalized_y, 2) + Math.pow(normalized_x, 2));
//Moves the relative position to be in its correct eighth
normalizedY = normalizedY - eigth;
normalizedX = normalizedX - eigth;
//calculates the distance from convection cell center to the relative position
float magnitude = (float)Math.sqrt(Math.pow(normalizedY, 2) + Math.pow(normalizedX, 2));
//If the distance is small enough we stretch it along the X axis ... ?
if(magnitude < fourth / 10){
normalized_x = normalized_x + fourth / 10;
magnitude = (float)Math.sqrt(Math.pow(normalized_y, 2) + Math.pow(normalized_x, 2));
normalizedX = normalizedX + fourth / 10;
magnitude = (float)Math.sqrt(Math.pow(normalizedY, 2) + Math.pow(normalizedX, 2));
}
double offset_angle = Math.atan2(normalized_y / magnitude, normalized_x / magnitude);
if(offset_angle < 0){
offset_angle = offset_angle + Math.PI * 2;
//calculates the angle of the point relative to convection cell center
double offsetAngle = Math.atan2(normalizedY / magnitude, normalizedX / magnitude);
if(offsetAngle < 0){
offsetAngle = offsetAngle + Math.PI * 2;
}
double vector_angle = offset_angle;
if(is_cell_type_1){
offset_angle = offset_angle + Math.PI / 2;
//rotate based on cell type
if(isCellType1){
offsetAngle = offsetAngle + Math.PI / 2;
} else {
offset_angle = offset_angle - Math.PI / 2;
offsetAngle = offsetAngle - Math.PI / 2;
}
while(offset_angle > Math.PI * 2){
offset_angle = offset_angle - Math.PI * 2;
//normalize
while(offsetAngle > Math.PI * 2){
offsetAngle = offsetAngle - Math.PI * 2;
}
while(offset_angle < 0){
offset_angle = offset_angle + Math.PI * 2;
while(offsetAngle < 0){
offsetAngle = offsetAngle + Math.PI * 2;
}
currents[x][y].x = (int)(99 * Math.cos(offset_angle));
currents[x][y].y = (int)(99 * Math.sin(offset_angle));
//Lastly, actually set the force vector
currents[x][y].x = (int)(99 * Math.cos(offsetAngle));
currents[x][y].y = (int)(99 * Math.sin(offsetAngle));
}
}
}
static void apply_Vectors_To_Elevation(){
int current_Elev[][] = new int[DIMENSION][DIMENSION];
/**
* Moves the terrain around based on the vector field
*/
private void applyVectorsToElevation(){
//allocate new elevation array
for(int x = 0; x < DIMENSION; x++){
for(int y = 0; y < DIMENSION; y++){
new_Elevation[x][y] = 0;
current_Elev[x][y] = elevation[x][y];
newElevation[x][y] = 0;
currentElev[x][y] = elevation[x][y];
}
}
//transfer terrain
for(int x = 0; x < DIMENSION; x++){
for(int y = 0; y < DIMENSION; y++){
boolean transfer = false;
if (electrosphere.game.server.terrain.generation.Utilities.random_Integer(1, 50) == 1) {
transfer = true;
}
int transfer_goal;
if(electrosphere.game.server.terrain.generation.Utilities.random_Integer(1, 2)==1){
transfer_goal = electrosphere.game.server.terrain.generation.Utilities.random_Integer(20, 60);
} else {
transfer_goal = electrosphere.game.server.terrain.generation.Utilities.random_Integer(0, 60);
}
if(electrosphere.game.server.terrain.generation.Utilities.random_Integer(1, 2)==1){
if (currents[x][y].x >= 0) {
if (transfer) {
if (x + 1 < DIMENSION) {
while(new_Elevation[x + 1][y] + current_Elev[x + 1][y] < 99 && current_Elev[x][y] > transfer_goal){
new_Elevation[x + 1][y]++;
current_Elev[x][y]--;
}
} else {
}
}
} else {
if (transfer) {
if (x - 1 >= 0) {
while(new_Elevation[x - 1][y] + current_Elev[x - 1][y] < 99 && current_Elev[x][y] > transfer_goal){
new_Elevation[x - 1][y]++;
current_Elev[x][y]--;
}
} else {
boolean transfer = false;
if (Utilities.random_Integer(1, 50, rand) == 1) {
transfer = true;
}
int transfer_goal;
if(Utilities.random_Integer(1, 2, rand)==1){
transfer_goal = Utilities.random_Integer(20, 60, rand);
} else {
transfer_goal = Utilities.random_Integer(0, 60, rand);
}
if(Utilities.random_Integer(1, 2, rand)==1){
if (currents[x][y].x >= 0) {
if (transfer) {
if (x + 1 < DIMENSION) {
while(newElevation[x + 1][y] + currentElev[x + 1][y] < 99 && currentElev[x][y] > transfer_goal){
newElevation[x + 1][y]++;
currentElev[x][y]--;
}
} else {
}
}
} else {
if (currents[x][y].y >= 0) {
if (transfer) {
if (y + 1 < DIMENSION) { // V REPLACE THIS WITH GOAL
while(new_Elevation[x][y + 1] + current_Elev[x][y + 1] < 99 && current_Elev[x][y] > transfer_goal){
new_Elevation[x][y + 1]++;
current_Elev[x][y]--;
}
} else {
}
}
} else {
if (transfer) {
if (y - 1 >= 0) {
while(new_Elevation[x][y - 1] + current_Elev[x][y - 1] < 99 && current_Elev[x][y] > transfer_goal){
new_Elevation[x][y - 1]++;
current_Elev[x][y]--;
}
} else {
if (transfer) {
if (x - 1 >= 0) {
while(newElevation[x - 1][y] + currentElev[x - 1][y] < 99 && currentElev[x][y] > transfer_goal){
newElevation[x - 1][y]++;
currentElev[x][y]--;
}
} else {
}
}
}
} else {
if (currents[x][y].y >= 0) {
if (transfer) {
if (y + 1 < DIMENSION) { // V REPLACE THIS WITH GOAL
while(newElevation[x][y + 1] + currentElev[x][y + 1] < 99 && currentElev[x][y] > transfer_goal){
newElevation[x][y + 1]++;
currentElev[x][y]--;
}
} else {
}
}
} else {
if (transfer) {
if (y - 1 >= 0) {
while(newElevation[x][y - 1] + currentElev[x][y - 1] < 99 && currentElev[x][y] > transfer_goal){
newElevation[x][y - 1]++;
currentElev[x][y]--;
}
} else {
}
}
}
}
}
for(int x = 0; x < DIMENSION; x++){
for(int y = 0; y < DIMENSION; y++){
new_Elevation[x][y] = new_Elevation[x][y] + current_Elev[x][y];
while(new_Elevation[x][y] > 99){
new_Elevation[x][y] = 99;
}
elevation[x][y] = new_Elevation[x][y];
}
}
}
static void grab_Elevation_Data(){
int new_Elevation_Data_Val = 0;
//move data from temporary array to main array
for(int x = 0; x < DIMENSION; x++){
for(int y = 0; y < DIMENSION; y++){
new_Elevation_Data_Val = new_Elevation_Data_Val + elevation[x][y];
newElevation[x][y] = newElevation[x][y] + currentElev[x][y];
while(newElevation[x][y] > 99){
newElevation[x][y] = 99;
}
elevation[x][y] = newElevation[x][y];
}
}
for(int x = 1; x < ELEVATION_DATA_LENGTH; x++){
elevation_Data[x-1] = elevation_Data[x];
}
elevation_Data[ELEVATION_DATA_LENGTH - 1] = new_Elevation_Data_Val;
if(new_Elevation_Data_Val > current_Max_Elevation_Data){
current_Max_Elevation_Data = new_Elevation_Data_Val;
}
}
static void calculate_Smoothed_Elevations(){
/**
* Applies a smooth kernel to the terrain data
*/
private void calculateSmoothedElevations(){
int[][] buffer = new int[DIMENSION][DIMENSION];
for(int x = 1; x < DIMENSION - 2; x++){
for(int y = 1; y < DIMENSION - 2; y++){
@ -297,19 +340,306 @@ class TerrainGenerator {
while(buffer[x][y] > 100){
buffer[x][y] = buffer[x][y]/2;
}
smoothed_elevation[x][y] = buffer[x][y];
smoothedElevation[x][y] = buffer[x][y];
}
}
for(int x = 1; x < DIMENSION - 2; x++){
for(int y = 1; y < DIMENSION - 2; y++){
buffer[x][y] = smoothed_elevation[x][y] * 4 * smoothed_elevation[x+1][y] * 2 + smoothed_elevation[x-1][y] * 2 + smoothed_elevation[x][y+1] * 2 +
smoothed_elevation[x][y-1] * 2 + smoothed_elevation[x+1][y+1] + smoothed_elevation[x+1][y-1] + smoothed_elevation[x-1][y+1] + smoothed_elevation[x-1][y-1];
buffer[x][y] = smoothedElevation[x][y] * 4 * smoothedElevation[x+1][y] * 2 + smoothedElevation[x-1][y] * 2 + smoothedElevation[x][y+1] * 2 +
smoothedElevation[x][y-1] * 2 + smoothedElevation[x+1][y+1] + smoothedElevation[x+1][y-1] + smoothedElevation[x-1][y+1] + smoothedElevation[x-1][y-1];
buffer[x][y] = (int)(buffer[x][y] / 16.0);
while(buffer[x][y] > 100){
buffer[x][y] = buffer[x][y]/2;
}
smoothed_elevation[x][y] = buffer[x][y];
smoothedElevation[x][y] = buffer[x][y];
}
}
}
/**
* simulates the hotspot logic
*/
private void simulateHotspots(){
if(spots.size() >= 1){
List<Hotspot> to_Remove = new ArrayList<Hotspot>();
Iterator<Hotspot> spot_Iterator = spots.iterator();
while(spot_Iterator.hasNext()){
Hotspot current_Spot = spot_Iterator.next();
if(current_Spot.life_current >= current_Spot.life_max){
to_Remove.add(current_Spot);
}
}
spot_Iterator = to_Remove.iterator();
while(spot_Iterator.hasNext()){
Hotspot current_Spot = spot_Iterator.next();
spots.remove(current_Spot);
}
}
if(spots.size() < 5){
spots.add(new Hotspot(
Utilities.random_Integer(0, DIMENSION - 1, rand),
Utilities.random_Integer(0, DIMENSION - 1, rand),
Utilities.random_Integer(6000, 10000, rand),
Utilities.random_Integer(3, 5, rand),
this));
}
for(int x = 0; x < DIMENSION; x++){
for(int y = 0; y < DIMENSION; y++){
asthenosphereHeat[x][y] = 0;
}
}
if(spots.size() >= 1){
Iterator<Hotspot> spot_Iterator = spots.iterator();
while(spot_Iterator.hasNext()){
Hotspot current_Spot = spot_Iterator.next();
current_Spot.simulate();
}
}
}
/**
* Fills in the gaps not covered by the main chunks
*/
private void applyVectorToElevationGaps(){
for(int x = 0; x < DIMENSION; x++){
for(int y = 0; y < DIMENSION; y++){
if(x % 16 == 0 || x % 16 == 1 || y % 16 == 0 || y % 16 == 1){
boolean transfer = false;
if (Utilities.random_Integer(1, 50, rand) == 1) {
transfer = true;
}
int transfer_goal;
if(Utilities.random_Integer(1, 2, rand)==1){
transfer_goal = Utilities.random_Integer(20, 60, rand);
} else {
transfer_goal = Utilities.random_Integer(0, 60, rand);
}
if(Utilities.random_Integer(1, 2, rand)==1){
if (currents[x][y].x >= 0) {
if (transfer) {
if (x + 1 < DIMENSION) {
while(newElevation[x + 1][y] + currentElev[x + 1][y] < 99 && currentElev[x][y] > transfer_goal){
newElevation[x + 1][y]++;
currentElev[x][y]--;
}
} else {
}
}
} else {
if (transfer) {
if (x - 1 >= 0) {
while(newElevation[x - 1][y] + currentElev[x - 1][y] < 99 && currentElev[x][y] > transfer_goal){
newElevation[x - 1][y]++;
currentElev[x][y]--;
}
} else {
}
}
}
} else {
if (currents[x][y].y >= 0) {
if (transfer) {
if (y + 1 < DIMENSION) { // V REPLACE THIS WITH GOAL
while(newElevation[x][y + 1] + currentElev[x][y + 1] < 99 && currentElev[x][y] > transfer_goal){
newElevation[x][y + 1]++;
currentElev[x][y]--;
}
} else {
}
}
} else {
if (transfer) {
if (y - 1 >= 0) {
while(newElevation[x][y - 1] + currentElev[x][y - 1] < 99 && currentElev[x][y] > transfer_goal){
newElevation[x][y - 1]++;
currentElev[x][y]--;
}
} else {
}
}
}
}
}
}
}
}
//latch for synchronizing parallel force vector computation
CountDownLatch latch;
/**
* Moves the terrain around based on the vector field, parallelized
*/
private void applyVectorsToElevationParallel(){
//allocate new elevation array
for(int x = 0; x < DIMENSION; x++){
for(int y = 0; y < DIMENSION; y++){
newElevation[x][y] = 0;
currentElev[x][y] = elevation[x][y];
}
}
latch = new CountDownLatch(DIMENSION / PARALLEL_CHUNK_SIZE * DIMENSION / PARALLEL_CHUNK_SIZE);
//transfer terrain in main chunks
for(int x = 0; x < DIMENSION / PARALLEL_CHUNK_SIZE; x++){
for(int y = 0; y < DIMENSION / PARALLEL_CHUNK_SIZE; y++){
threadPool.execute(new TerrainMovementWorker(
DIMENSION,
x,
y,
new Random(rand.nextLong()),
currents,
newElevation,
currentElev,
latch
));
}
}
//await main chunks
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
//fill in gaps
applyVectorToElevationGaps();
//move data from temporary array to main array
for(int x = 0; x < DIMENSION; x++){
for(int y = 0; y < DIMENSION; y++){
newElevation[x][y] = newElevation[x][y] + currentElev[x][y];
while(newElevation[x][y] > 99){
newElevation[x][y] = 99;
}
elevation[x][y] = newElevation[x][y];
}
}
}
/**
* A worker thread for simulating terrain moving due to force vector field
*/
static class TerrainMovementWorker implements Runnable {
//size of data map
int continentPhaseDimension;
//The offsets into the data array
int offsetX;
int offsetY;
//random
Random rand;
//force vector field
Vector[][] currents;
//new elevation map to fill in
int[][] newElevation;
//reference elevation map to pull from
int[][] referenceElevation;
//latch to resynchronize threads
CountDownLatch latch;
protected TerrainMovementWorker(
int continentPhaseDimension,
int offsetX,
int offsetY,
Random rand,
Vector[][] currents,
int[][] newElevation,
int[][] referenceElevation,
CountDownLatch latch
){
this.continentPhaseDimension = continentPhaseDimension;
this.offsetX = offsetX;
this.offsetY = offsetY;
this.rand = rand;
this.currents = currents;
this.newElevation = newElevation;
this.referenceElevation = referenceElevation;
this.latch = latch;
}
/**
* Runs the terrain movement simulation for this worker
*/
@Override
public void run() {
for(int x = 0; x < PARALLEL_CHUNK_SIZE; x++){
for(int y = 0; y < PARALLEL_CHUNK_SIZE; y++){
if(x % PARALLEL_CHUNK_SIZE != 0 && x % PARALLEL_CHUNK_SIZE != 1 && y % PARALLEL_CHUNK_SIZE != 0 && y % PARALLEL_CHUNK_SIZE != 1){
//current absolute position in data arrays
int currentX = x + offsetX * PARALLEL_CHUNK_SIZE;
int currentY = y + offsetY * PARALLEL_CHUNK_SIZE;
//roll whether should transfer terrain or not
boolean transfer = false;
if (Utilities.random_Integer(1, 50, rand) == 1) {
transfer = true;
}
//sets the goal of how much elevation to transfer to neighbors
int transferGoal;
if(Utilities.random_Integer(1, 2, rand)==1){
transferGoal = Utilities.random_Integer(20, 60, rand);
} else {
transferGoal = Utilities.random_Integer(0, 60, rand);
}
//roll whether to transfer horizontally or vertically
if(Utilities.random_Integer(1, 2, rand)==1){
//transfers horizontally
if (currents[currentX][currentY].x >= 0) {
if (transfer) {
if (currentX + 1 < continentPhaseDimension) {
while(
newElevation[currentX + 1][currentY] + referenceElevation[currentX + 1][currentY] < 99 &&
referenceElevation[currentX][currentY] > transferGoal){
newElevation[currentX + 1][currentY]++;
referenceElevation[currentX][currentY]--;
}
}
}
} else {
if (transfer) {
if (currentX - 1 >= 0) {
while(
newElevation[currentX - 1][currentY] + referenceElevation[currentX - 1][currentY] < 99 &&
referenceElevation[currentX][currentY] > transferGoal){
newElevation[currentX - 1][currentY]++;
referenceElevation[currentX][currentY]--;
}
}
}
}
} else {
//transfer vertically
if (currents[currentX][currentY].y >= 0) {
if (transfer) {
if (currentY + 1 < continentPhaseDimension) { // V REPLACE THIS WITH GOAL
while(
newElevation[currentX][currentY + 1] + referenceElevation[currentX][currentY + 1] < 99 &&
referenceElevation[currentX][currentY] > transferGoal){
newElevation[currentX][currentY + 1]++;
referenceElevation[currentX][currentY]--;
}
}
}
} else {
if (transfer) {
if (currentY - 1 >= 0) {
while(
newElevation[currentX][currentY - 1] + referenceElevation[currentX][currentY - 1] < 99 &&
referenceElevation[currentX][currentY] > transferGoal){
newElevation[currentX][currentY - 1]++;
referenceElevation[currentX][currentY]--;
}
}
}
}
}
}
}
}
latch.countDown();
}
}
}

View File

@ -43,10 +43,10 @@ class Utilities {
System.out.println("Sleep failed lol.");
}
}
public static int random_Integer(int Min, int Max){
public static int random_Integer(int Min, int Max, Random rand){
return Min + (int)(rand.nextDouble() * ((Max - Min) + 1));
}
public static int random_Range_Distribution_Even(int ... range){
public static int random_Range_Distribution_Even(Random rand, int ... range){
if(range.length % 2 != 0){
System.out.println("Invalid number of parameters for range in a function call to \"random_Range_Distribution_Even\"!");
return -1;
@ -57,7 +57,7 @@ class Utilities {
total = total + range[i+1] - range[i] + 1;
i=i+2;
}
int temp = random_Integer(1,total);
int temp = random_Integer(1,total,rand);
int incrementer = 0;
i = 0;
while(incrementer + range[i+1] - range[i] + 1 < temp){
@ -113,7 +113,7 @@ class Utilities {
String rVal = "";
int line_To_Go_To;
try (BufferedReader reader = new BufferedReader(new FileReader(source));){
line_To_Go_To = random_Integer(1,Integer.parseInt(reader.readLine()));
line_To_Go_To = random_Integer(1,Integer.parseInt(reader.readLine()),rand);
int i = 0;
while(i<line_To_Go_To - 1){
reader.readLine();

View File

@ -1,8 +1,7 @@
package electrosphere.game.server.terrain.generation;
/**
*
* @author satellite
* Int based 2 dimension vector
*/
class Vector {
public int x;

View File

@ -1,27 +1,10 @@
package electrosphere.util.worldviewer;
import com.google.gson.Gson;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.game.server.terrain.manager.ServerTerrainManager;
import electrosphere.game.server.terrain.models.TerrainModel;
import electrosphere.server.simulation.MacroSimulation;
import electrosphere.util.FileUtils;
import electrosphere.util.Utilities;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JComponent;
import javax.swing.JFrame;
/**