- ignore 3rd party ChunkPrimer candidates for the fast chunk wrapper
- some tweaks to terrains stuff
This commit is contained in:
parent
f0d8cf3a76
commit
5142264bcf
@ -91,7 +91,7 @@ public class Main extends Applet {
|
|||||||
if (cell.tag == getCache().getTerrain().volcano) {
|
if (cell.tag == getCache().getTerrain().volcano) {
|
||||||
return 0F;
|
return 0F;
|
||||||
}
|
}
|
||||||
return 20 + (cell.tag.getId() / (float) Terrain.MAX_ID.get()) * 80;
|
return 20 + (cell.tag.getHue() * 80);
|
||||||
case ELEVATION:
|
case ELEVATION:
|
||||||
float value = (cell.value - 0.245F) / 0.65F;
|
float value = (cell.value - 0.245F) / 0.65F;
|
||||||
return (1 - value) * 30;
|
return (1 - value) * 30;
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
package com.terraforged.core.settings;
|
package com.terraforged.core.settings;
|
||||||
|
|
||||||
import com.terraforged.core.util.serialization.annotation.Comment;
|
import com.terraforged.core.util.serialization.annotation.Comment;
|
||||||
|
import com.terraforged.core.util.serialization.annotation.Name;
|
||||||
import com.terraforged.core.util.serialization.annotation.Range;
|
import com.terraforged.core.util.serialization.annotation.Range;
|
||||||
import com.terraforged.core.util.serialization.annotation.Serializable;
|
import com.terraforged.core.util.serialization.annotation.Serializable;
|
||||||
import me.dags.noise.Module;
|
import me.dags.noise.Module;
|
||||||
@ -77,6 +78,7 @@ public class GeneratorSettings {
|
|||||||
public int continentScale = 4000;
|
public int continentScale = 4000;
|
||||||
|
|
||||||
@Range(min = 250, max = 5000)
|
@Range(min = 250, max = 5000)
|
||||||
|
@Name("Mountain Range Scale")
|
||||||
@Comment("Controls the size of mountain ranges")
|
@Comment("Controls the size of mountain ranges")
|
||||||
public int mountainScale = 950;
|
public int mountainScale = 950;
|
||||||
|
|
||||||
|
@ -30,34 +30,30 @@ import com.terraforged.core.util.concurrent.batcher.Batcher;
|
|||||||
|
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.ForkJoinPool;
|
import java.util.concurrent.ForkJoinPool;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.ForkJoinTask;
|
||||||
|
|
||||||
public class ThreadPool implements Executor {
|
public class ThreadPool implements Executor {
|
||||||
|
|
||||||
private static final ThreadPool instance = new ThreadPool("TerraForged", defaultPoolSize());
|
private static final ThreadPool instance = new ThreadPool("TF", defaultPoolSize());
|
||||||
|
private static final Object lock = new Object();
|
||||||
|
|
||||||
private final ExecutorService service;
|
private final ForkJoinPool service;
|
||||||
|
|
||||||
private ThreadPool(String name, int size) {
|
private ThreadPool(String name, int size) {
|
||||||
this.service = ThreadPool.createPool(size, name);
|
this.service = ThreadPool.createPool(size, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void shutdown() {
|
|
||||||
service.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(Runnable command) {
|
public void execute(Runnable command) {
|
||||||
service.execute(command);
|
service.submit(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> Future<?> submit(Runnable runnable) {
|
public <T> ForkJoinTask<?> submit(Runnable runnable) {
|
||||||
return service.submit(runnable);
|
return service.submit(runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> Future<T> submit(Callable<T> callable) {
|
public <T> ForkJoinTask<T> submit(Callable<T> callable) {
|
||||||
return service.submit(callable);
|
return service.submit(callable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,16 +69,13 @@ public class ThreadPool implements Executor {
|
|||||||
return new ThreadPool("Pool", Math.max(1, size));
|
return new ThreadPool("Pool", Math.max(1, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void shutdownCurrent() {
|
|
||||||
instance.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int defaultPoolSize() {
|
private static int defaultPoolSize() {
|
||||||
int threads = Runtime.getRuntime().availableProcessors();
|
int threads = Runtime.getRuntime().availableProcessors();
|
||||||
return Math.max(1, (int) ((threads / 3F) * 2F));
|
return Math.max(1, (int) ((threads / 3F) * 2F));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ForkJoinPool createPool(int size, String name) {
|
public static ForkJoinPool createPool(int size, String name) {
|
||||||
|
|
||||||
return new ForkJoinPool(size, new WorkerFactory.ForkJoin(name), null, true);
|
return new ForkJoinPool(size, new WorkerFactory.ForkJoin(name), null, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ public class Cache<V extends ExpiringEntry> implements Runnable {
|
|||||||
private final long expireMS;
|
private final long expireMS;
|
||||||
private final long intervalMS;
|
private final long intervalMS;
|
||||||
private final SynchronizedLongMap<V> map;
|
private final SynchronizedLongMap<V> map;
|
||||||
|
private final ThreadPool threadPool = ThreadPool.getPool();
|
||||||
|
|
||||||
private volatile long timestamp = 0L;
|
private volatile long timestamp = 0L;
|
||||||
|
|
||||||
@ -33,7 +34,7 @@ public class Cache<V extends ExpiringEntry> implements Runnable {
|
|||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
if (now - timestamp > intervalMS) {
|
if (now - timestamp > intervalMS) {
|
||||||
timestamp = now;
|
timestamp = now;
|
||||||
ThreadPool.getPool().execute(this);
|
threadPool.submit(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
package com.terraforged.core.util.concurrent.cache;
|
package com.terraforged.core.util.concurrent.cache;
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
import com.terraforged.core.util.concurrent.ThreadPool;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
public class CacheEntry<T> implements Runnable, ExpiringEntry {
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ForkJoinTask;
|
||||||
|
|
||||||
|
public class CacheEntry<T> implements ExpiringEntry {
|
||||||
|
|
||||||
private volatile T result;
|
|
||||||
private volatile long timestamp;
|
private volatile long timestamp;
|
||||||
|
private final ForkJoinTask<T> task;
|
||||||
|
|
||||||
private final Supplier<T> supplier;
|
public CacheEntry(ForkJoinTask<T> task) {
|
||||||
|
this.task = task;
|
||||||
private CacheEntry(Supplier<T> supplier) {
|
|
||||||
this.supplier = supplier;
|
|
||||||
this.timestamp = System.currentTimeMillis();
|
this.timestamp = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,33 +20,15 @@ public class CacheEntry<T> implements Runnable, ExpiringEntry {
|
|||||||
return timestamp;
|
return timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
this.result = supplier.get();
|
|
||||||
this.timestamp = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDone() {
|
public boolean isDone() {
|
||||||
return result != null;
|
return task.isDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
public T get() {
|
public T get() {
|
||||||
T value = result;
|
return task.join();
|
||||||
if (value == null) {
|
|
||||||
value = getNow();
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private T getNow() {
|
public static <T> CacheEntry<T> supplyAsync(Callable<T> callable, ThreadPool executor) {
|
||||||
T result = supplier.get();
|
return new CacheEntry<>(executor.submit(callable));
|
||||||
this.result = result;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> CacheEntry<T> supplyAsync(Supplier<T> supplier, Executor executor) {
|
|
||||||
CacheEntry<T> entry = new CacheEntry<>(supplier);
|
|
||||||
executor.execute(entry);
|
|
||||||
return entry;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 TerraForged
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.terraforged.core.util.serialization.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface Name {
|
||||||
|
|
||||||
|
String value();
|
||||||
|
}
|
@ -26,6 +26,7 @@
|
|||||||
package com.terraforged.core.util.serialization.serializer;
|
package com.terraforged.core.util.serialization.serializer;
|
||||||
|
|
||||||
import com.terraforged.core.util.serialization.annotation.Comment;
|
import com.terraforged.core.util.serialization.annotation.Comment;
|
||||||
|
import com.terraforged.core.util.serialization.annotation.Name;
|
||||||
import com.terraforged.core.util.serialization.annotation.Range;
|
import com.terraforged.core.util.serialization.annotation.Range;
|
||||||
import com.terraforged.core.util.serialization.annotation.Serializable;
|
import com.terraforged.core.util.serialization.annotation.Serializable;
|
||||||
|
|
||||||
@ -163,7 +164,9 @@ public class Serializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static String getName(Field field) {
|
private static String getName(Field field) {
|
||||||
String name = field.getName();
|
Name nameMeta = field.getAnnotation(Name.class);
|
||||||
|
|
||||||
|
String name = nameMeta == null ? field.getName() : nameMeta.value();
|
||||||
StringBuilder sb = new StringBuilder(name.length() * 2);
|
StringBuilder sb = new StringBuilder(name.length() * 2);
|
||||||
for (int i = 0; i < name.length(); i++) {
|
for (int i = 0; i < name.length(); i++) {
|
||||||
char c = name.charAt(i);
|
char c = name.charAt(i);
|
||||||
|
@ -48,6 +48,7 @@ public class RiverMap {
|
|||||||
private final GeneratorContext context;
|
private final GeneratorContext context;
|
||||||
private final RiverMapConfig riverMapConfig;
|
private final RiverMapConfig riverMapConfig;
|
||||||
private final Cache<CacheEntry<RiverRegion>> cache;
|
private final Cache<CacheEntry<RiverRegion>> cache;
|
||||||
|
private final ThreadPool threadPool = ThreadPool.getPool();
|
||||||
|
|
||||||
public RiverMap(Heightmap heightmap, GeneratorContext context) {
|
public RiverMap(Heightmap heightmap, GeneratorContext context) {
|
||||||
RiverConfig primary = RiverConfig.builder(context.levels)
|
RiverConfig primary = RiverConfig.builder(context.levels)
|
||||||
@ -151,6 +152,6 @@ public class RiverMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private CacheEntry<RiverRegion> generateRegion(int rx, int rz) {
|
private CacheEntry<RiverRegion> generateRegion(int rx, int rz) {
|
||||||
return CacheEntry.supplyAsync(() -> new RiverRegion(rx, rz, heightmap, context, riverMapConfig), ThreadPool.getPool());
|
return CacheEntry.supplyAsync(() -> new RiverRegion(rx, rz, heightmap, context, riverMapConfig), threadPool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,17 +29,25 @@ import com.terraforged.core.cell.Tag;
|
|||||||
import com.terraforged.core.settings.Settings;
|
import com.terraforged.core.settings.Settings;
|
||||||
import com.terraforged.core.world.heightmap.Levels;
|
import com.terraforged.core.world.heightmap.Levels;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class Terrain implements Tag {
|
public class Terrain implements Tag {
|
||||||
|
|
||||||
public static final int ID_START = 9;
|
private static final AtomicInteger MAX_ID = new AtomicInteger(0);
|
||||||
public static final AtomicInteger MAX_ID = new AtomicInteger(0);
|
private static final Map<String, Terrain> register = Collections.synchronizedMap(new HashMap<>());
|
||||||
|
|
||||||
|
public static final int ID_START = 10;
|
||||||
public static final Terrain NONE = new Terrain("none", -1);
|
public static final Terrain NONE = new Terrain("none", -1);
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final int id;
|
private final int id;
|
||||||
private float weight;
|
private final float weight;
|
||||||
|
|
||||||
public Terrain(String name, int id) {
|
public Terrain(String name, int id) {
|
||||||
this(name, id, 1F);
|
this(name, id, 1F);
|
||||||
@ -49,6 +57,7 @@ public class Terrain implements Tag {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.weight = (float) weight;
|
this.weight = (float) weight;
|
||||||
|
register.put(name, this);
|
||||||
MAX_ID.set(Math.max(MAX_ID.get(), id));
|
MAX_ID.set(Math.max(MAX_ID.get(), id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,6 +78,10 @@ public class Terrain implements Tag {
|
|||||||
return weight;
|
return weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float getHue() {
|
||||||
|
return id / (float) MAX_ID.get();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getName();
|
return getName();
|
||||||
@ -177,4 +190,12 @@ public class Terrain implements Tag {
|
|||||||
public static Terrain volcanoPipe(Settings settings) {
|
public static Terrain volcanoPipe(Settings settings) {
|
||||||
return new Terrain("volcano_pipe", 15, settings.terrain.volcano.weight);
|
return new Terrain("volcano_pipe", 15, settings.terrain.volcano.weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Optional<Terrain> get(String name) {
|
||||||
|
return Optional.ofNullable(register.get(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Terrain> getRegistered() {
|
||||||
|
return new ArrayList<>(register.values());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,20 +26,17 @@
|
|||||||
package com.terraforged.mod;
|
package com.terraforged.mod;
|
||||||
|
|
||||||
import com.terraforged.api.material.WGTags;
|
import com.terraforged.api.material.WGTags;
|
||||||
import com.terraforged.core.util.concurrent.ThreadPool;
|
|
||||||
import com.terraforged.feature.FeatureManager;
|
import com.terraforged.feature.FeatureManager;
|
||||||
import com.terraforged.mod.data.DataGen;
|
import com.terraforged.mod.data.DataGen;
|
||||||
import com.terraforged.mod.feature.feature.DiskFeature;
|
import com.terraforged.mod.feature.feature.DiskFeature;
|
||||||
import com.terraforged.mod.feature.tree.SaplingManager;
|
import com.terraforged.mod.feature.tree.SaplingManager;
|
||||||
import com.terraforged.mod.util.Environment;
|
import com.terraforged.mod.util.Environment;
|
||||||
import net.minecraft.world.gen.feature.Feature;
|
import net.minecraft.world.gen.feature.Feature;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
|
||||||
import net.minecraftforge.event.RegistryEvent;
|
import net.minecraftforge.event.RegistryEvent;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||||
import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent;
|
import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent;
|
||||||
import net.minecraftforge.fml.event.server.FMLServerStoppingEvent;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Author <dags@dags.me>
|
* Author <dags@dags.me>
|
||||||
@ -51,7 +48,6 @@ public class TerraForgedMod {
|
|||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void setup(FMLCommonSetupEvent event) {
|
public static void setup(FMLCommonSetupEvent event) {
|
||||||
Log.info("Common setup");
|
Log.info("Common setup");
|
||||||
MinecraftForge.EVENT_BUS.addListener(TerraForgedMod::onShutdown);
|
|
||||||
WGTags.init();
|
WGTags.init();
|
||||||
TerraWorld.init();
|
TerraWorld.init();
|
||||||
SaplingManager.init();
|
SaplingManager.init();
|
||||||
@ -69,8 +65,4 @@ public class TerraForgedMod {
|
|||||||
FeatureManager.registerTemplates(event);
|
FeatureManager.registerTemplates(event);
|
||||||
event.getRegistry().register(DiskFeature.INSTANCE);
|
event.getRegistry().register(DiskFeature.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void onShutdown(FMLServerStoppingEvent event) {
|
|
||||||
ThreadPool.shutdownCurrent();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -9,12 +9,17 @@ import net.minecraft.world.chunk.ChunkPrimer;
|
|||||||
import net.minecraft.world.chunk.ChunkSection;
|
import net.minecraft.world.chunk.ChunkSection;
|
||||||
import net.minecraft.world.chunk.IChunk;
|
import net.minecraft.world.chunk.IChunk;
|
||||||
import net.minecraft.world.gen.Heightmap;
|
import net.minecraft.world.gen.Heightmap;
|
||||||
|
import org.apache.commons.lang3.Validate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A ChunkPrimer wrapper that handles setting BlockStates within the chunk & updating heightmaps accordingly
|
* A ChunkPrimer wrapper that handles setting BlockStates within the chunk & updating heightmaps accordingly
|
||||||
*/
|
*/
|
||||||
public class FastChunk implements ChunkDelegate {
|
public class FastChunk implements ChunkDelegate {
|
||||||
|
|
||||||
|
private static final int arraySize = 256;
|
||||||
|
private static final int bitsPerEntry = 9;
|
||||||
|
private static final long maxEntryValue = (1L << bitsPerEntry) - 1L;
|
||||||
|
|
||||||
private final int blockX;
|
private final int blockX;
|
||||||
private final int blockZ;
|
private final int blockZ;
|
||||||
private final ChunkPrimer primer;
|
private final ChunkPrimer primer;
|
||||||
@ -66,9 +71,56 @@ public class FastChunk implements ChunkDelegate {
|
|||||||
if (chunk instanceof FastChunk) {
|
if (chunk instanceof FastChunk) {
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
if (chunk instanceof ChunkPrimer) {
|
if (chunk.getClass() == ChunkPrimer.class) {
|
||||||
return new FastChunk((ChunkPrimer) chunk);
|
return new FastChunk((ChunkPrimer) chunk);
|
||||||
}
|
}
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void updateWGHeightmaps(IChunk chunk, BlockPos.Mutable pos) {
|
||||||
|
int topY = chunk.getTopFilledSegment() + 15;
|
||||||
|
long[] ocean = chunk.getHeightmap(Heightmap.Type.OCEAN_FLOOR_WG).getDataArray();
|
||||||
|
long[] surface = chunk.getHeightmap(Heightmap.Type.WORLD_SURFACE_WG).getDataArray();
|
||||||
|
for (int x = 0; x < 16; x++) {
|
||||||
|
for (int z = 0; z < 16; z++) {
|
||||||
|
boolean flag = false;
|
||||||
|
for (int y = topY; y >= 0; y--) {
|
||||||
|
BlockState state = chunk.getBlockState(pos.setPos(x, y, z));
|
||||||
|
if (state.getBlock() != Blocks.AIR) {
|
||||||
|
if (!flag) {
|
||||||
|
// WORLD_SURFACE_WG predicate is when block != air .: can set the height at this y value
|
||||||
|
setAt(surface, index(x, z), y + 1);
|
||||||
|
// flag = true means subsequent y values are ignored
|
||||||
|
flag = true;
|
||||||
|
}
|
||||||
|
if (Heightmap.Type.OCEAN_FLOOR_WG.getHeightLimitPredicate().test(state)) {
|
||||||
|
setAt(ocean, index(x, z), y + 1);
|
||||||
|
// no more heightmaps to update at this x/z so can exit the y loop here
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// from BitArray
|
||||||
|
private static void setAt(long[] longArray, int index, int value) {
|
||||||
|
Validate.inclusiveBetween(0L, (arraySize - 1), index);
|
||||||
|
Validate.inclusiveBetween(0L, maxEntryValue, value);
|
||||||
|
int i = index * bitsPerEntry;
|
||||||
|
int j = i >> 6;
|
||||||
|
int k = (index + 1) * bitsPerEntry - 1 >> 6;
|
||||||
|
int l = i ^ j << 6;
|
||||||
|
longArray[j] = longArray[j] & ~(maxEntryValue << l) | ((long) value & maxEntryValue) << l;
|
||||||
|
if (j != k) {
|
||||||
|
int i1 = 64 - l;
|
||||||
|
int j1 = bitsPerEntry - i1;
|
||||||
|
longArray[k] = longArray[k] >>> j1 << j1 | ((long) value & maxEntryValue) >> i1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int index(int x, int z) {
|
||||||
|
return x + (z << 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,6 +187,8 @@ public class TerraChunkGenerator extends ObfHelperChunkGenerator<GenerationSetti
|
|||||||
processor.decorate(ctx.buffer, ctx, px, py, pz);
|
processor.decorate(ctx.buffer, ctx, px, py, pz);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
FastChunk.updateWGHeightmaps(chunk, context.pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -32,20 +32,17 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
|||||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
||||||
import com.mojang.brigadier.suggestion.Suggestions;
|
import com.mojang.brigadier.suggestion.Suggestions;
|
||||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||||
import com.terraforged.core.settings.Settings;
|
|
||||||
import com.terraforged.core.world.terrain.Terrain;
|
import com.terraforged.core.world.terrain.Terrain;
|
||||||
import com.terraforged.core.world.terrain.Terrains;
|
|
||||||
import net.minecraft.command.ISuggestionProvider;
|
import net.minecraft.command.ISuggestionProvider;
|
||||||
import net.minecraft.util.text.StringTextComponent;
|
import net.minecraft.util.text.StringTextComponent;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class TerrainArgType implements ArgumentType<Terrain> {
|
public class TerrainArgType implements ArgumentType<Terrain> {
|
||||||
|
|
||||||
private final List<Terrain> terrains = getTerrains();
|
private final List<Terrain> terrains = Terrain.getRegistered();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Terrain parse(StringReader reader) throws CommandSyntaxException {
|
public Terrain parse(StringReader reader) throws CommandSyntaxException {
|
||||||
@ -79,39 +76,4 @@ public class TerrainArgType implements ArgumentType<Terrain> {
|
|||||||
new StringTextComponent(String.format(message, args))
|
new StringTextComponent(String.format(message, args))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<Terrain> getTerrains() {
|
|
||||||
Terrains terrains = Terrains.create(new Settings());
|
|
||||||
List<Terrain> result = new ArrayList<>();
|
|
||||||
|
|
||||||
for (int i = 0; i < terrains.index.size(); i++) {
|
|
||||||
Terrain terrain = terrains.index.get(i);
|
|
||||||
result.add(terrain);
|
|
||||||
if (dontMix(terrain, terrains)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (int j = i + 1; j < terrains.index.size(); j++) {
|
|
||||||
Terrain other = terrains.index.get(j);
|
|
||||||
if (dontMix(other, terrains)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Terrain mix = new Terrain(terrain.getName() + "-" + other.getName(), -1);
|
|
||||||
result.add(mix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean dontMix(Terrain terrain, Terrains terrains) {
|
|
||||||
return terrain == terrains.ocean
|
|
||||||
|| terrain == terrains.deepOcean
|
|
||||||
|| terrain == terrains.river
|
|
||||||
|| terrain == terrains.riverBanks
|
|
||||||
|| terrain == terrains.beach
|
|
||||||
|| terrain == terrains.coast
|
|
||||||
|| terrain == terrains.volcano
|
|
||||||
|| terrain == terrains.volcanoPipe
|
|
||||||
|| terrain == terrains.lake;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user