mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-04-09 17:26:22 +00:00
Forcefully shove stuff into other stuff
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.util.RNG;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
public interface BlockUpdater {
|
||||
|
||||
public void catchBlockUpdates(int x, int y, int z, BlockData data);
|
||||
|
||||
public void updateChunk(Chunk c);
|
||||
|
||||
public void update(int x, int y, int z, Chunk c, RNG rf);
|
||||
}
|
||||
308
src/main/java/com/volmit/iris/scaffold/engine/Engine.java
Normal file
308
src/main/java/com/volmit/iris/scaffold/engine/Engine.java
Normal file
@@ -0,0 +1,308 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.manager.IrisDataManager;
|
||||
import com.volmit.iris.object.*;
|
||||
import com.volmit.iris.scaffold.cache.Cache;
|
||||
import com.volmit.iris.scaffold.data.DataProvider;
|
||||
import com.volmit.iris.scaffold.hunk.Hunk;
|
||||
import com.volmit.iris.scaffold.parallax.ParallaxAccess;
|
||||
import com.volmit.iris.util.B;
|
||||
import com.volmit.iris.util.KList;
|
||||
import com.volmit.iris.util.RNG;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootProvider, BlockUpdater {
|
||||
public void close();
|
||||
|
||||
public boolean isClosed();
|
||||
|
||||
public EngineWorldManager getWorldManager();
|
||||
|
||||
public void setParallelism(int parallelism);
|
||||
|
||||
public int getParallelism();
|
||||
|
||||
public EngineTarget getTarget();
|
||||
|
||||
public EngineFramework getFramework();
|
||||
|
||||
public void setMinHeight(int min);
|
||||
|
||||
public int getIndex();
|
||||
|
||||
public int getMinHeight();
|
||||
|
||||
public double modifyX(double x);
|
||||
|
||||
public double modifyZ(double z);
|
||||
|
||||
public void generate(int x, int z, Hunk<BlockData> blocks, Hunk<Biome> biomes);
|
||||
|
||||
default void save()
|
||||
{
|
||||
getParallax().saveAll();
|
||||
}
|
||||
|
||||
default void saveNow()
|
||||
{
|
||||
getParallax().saveAllNOW();
|
||||
}
|
||||
|
||||
default String getName()
|
||||
{
|
||||
return getDimension().getName();
|
||||
}
|
||||
|
||||
public default int getHeight()
|
||||
{
|
||||
return getTarget().getHeight();
|
||||
}
|
||||
|
||||
public default IrisDataManager getData()
|
||||
{
|
||||
return getTarget().getData();
|
||||
}
|
||||
|
||||
public default World getWorld()
|
||||
{
|
||||
return getTarget().getWorld();
|
||||
}
|
||||
|
||||
public default IrisDimension getDimension()
|
||||
{
|
||||
return getTarget().getDimension();
|
||||
}
|
||||
|
||||
public default ParallaxAccess getParallax()
|
||||
{
|
||||
return getTarget().getParallaxWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public default IrisRegion getRegion(int x, int z) {
|
||||
return getFramework().getComplex().getRegionStream().get(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public default ParallaxAccess getParallaxAccess()
|
||||
{
|
||||
return getParallax();
|
||||
}
|
||||
|
||||
@Override
|
||||
public default IrisBiome getCaveBiome(int x, int z)
|
||||
{
|
||||
return getFramework().getComplex().getCaveBiomeStream().get(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public default IrisBiome getSurfaceBiome(int x, int z)
|
||||
{
|
||||
return getFramework().getComplex().getTrueBiomeStream().get(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public default int getHeight(int x, int z)
|
||||
{
|
||||
return getFramework().getEngineParallax().getHighest(x, z, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public default void catchBlockUpdates(int x, int y, int z, BlockData data) {
|
||||
if(data == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(B.isUpdatable(data))
|
||||
{
|
||||
getParallax().updateBlock(x,y,z);
|
||||
getParallax().getMetaRW(x>>4, z>>4).setUpdates(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public default void updateChunk(Chunk c)
|
||||
{
|
||||
if(getParallax().getMetaR(c.getX(), c.getZ()).isUpdates())
|
||||
{
|
||||
Hunk<Boolean> b = getParallax().getUpdatesR(c.getX(), c.getZ());
|
||||
|
||||
b.iterateSync((x,y,z,v) -> {
|
||||
if(v != null && v)
|
||||
{
|
||||
update(x,y,z, c, new RNG(Cache.key(c.getX(), c.getZ())));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public default void update(int x, int y, int z, Chunk c, RNG rf)
|
||||
{
|
||||
Block block = c.getBlock(x,y,z);
|
||||
BlockData data = block.getBlockData();
|
||||
|
||||
if(B.isStorage(data))
|
||||
{
|
||||
RNG rx = rf.nextParallelRNG(x).nextParallelRNG(z).nextParallelRNG(y);
|
||||
InventorySlotType slot = null;
|
||||
|
||||
if(B.isStorageChest(data))
|
||||
{
|
||||
slot = InventorySlotType.STORAGE;
|
||||
}
|
||||
|
||||
if(slot != null)
|
||||
{
|
||||
KList<IrisLootTable> tables = getLootTables(rx.nextParallelRNG(4568111), block);
|
||||
InventorySlotType slott = slot;
|
||||
|
||||
try
|
||||
{
|
||||
InventoryHolder m = (InventoryHolder) block.getState();
|
||||
addItems(false, m.getInventory(), rx, tables, slott, x, y, z, 15);
|
||||
}
|
||||
|
||||
catch(Throwable ignored)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if(B.isLit(data))
|
||||
{
|
||||
Iris.linkBK.updateBlock(block);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public default void scramble(Inventory inventory, RNG rng)
|
||||
{
|
||||
org.bukkit.inventory.ItemStack[] items = inventory.getContents();
|
||||
org.bukkit.inventory.ItemStack[] nitems = new org.bukkit.inventory.ItemStack[inventory.getSize()];
|
||||
System.arraycopy(items, 0, nitems, 0, items.length);
|
||||
boolean packedFull = false;
|
||||
|
||||
splitting: for(int i = 0; i < nitems.length; i++)
|
||||
{
|
||||
ItemStack is = nitems[i];
|
||||
|
||||
if(is != null && is.getAmount() > 1 && !packedFull)
|
||||
{
|
||||
for(int j = 0; j < nitems.length; j++)
|
||||
{
|
||||
if(nitems[j] == null)
|
||||
{
|
||||
int take = rng.nextInt(is.getAmount());
|
||||
take = take == 0 ? 1 : take;
|
||||
is.setAmount(is.getAmount() - take);
|
||||
nitems[j] = is.clone();
|
||||
nitems[j].setAmount(take);
|
||||
continue splitting;
|
||||
}
|
||||
}
|
||||
|
||||
packedFull = true;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
Arrays.parallelSort(nitems, (a, b) -> rng.nextInt());
|
||||
break;
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
inventory.setContents(nitems);
|
||||
}
|
||||
|
||||
@Override
|
||||
public default void injectTables(KList<IrisLootTable> list, IrisLootReference r)
|
||||
{
|
||||
if(r.getMode().equals(LootMode.CLEAR) || r.getMode().equals(LootMode.REPLACE))
|
||||
{
|
||||
list.clear();
|
||||
}
|
||||
|
||||
list.addAll(r.getLootTables(getFramework().getComplex()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public default KList<IrisLootTable> getLootTables(RNG rng, Block b)
|
||||
{
|
||||
int rx = b.getX();
|
||||
int rz = b.getZ();
|
||||
double he = getFramework().getComplex().getHeightStream().get(rx, rz);
|
||||
IrisRegion region = getFramework().getComplex().getRegionStream().get(rx, rz);
|
||||
IrisBiome biomeSurface = getFramework().getComplex().getTrueBiomeStream().get(rx, rz);
|
||||
IrisBiome biomeUnder = b.getY() < he ? getFramework().getComplex().getCaveBiomeStream().get(rx, rz) : biomeSurface;
|
||||
KList<IrisLootTable> tables = new KList<>();
|
||||
double multiplier = 1D * getDimension().getLoot().getMultiplier() * region.getLoot().getMultiplier() * biomeSurface.getLoot().getMultiplier() * biomeUnder.getLoot().getMultiplier();
|
||||
injectTables(tables, getDimension().getLoot());
|
||||
injectTables(tables, region.getLoot());
|
||||
injectTables(tables, biomeSurface.getLoot());
|
||||
injectTables(tables, biomeUnder.getLoot());
|
||||
|
||||
if(tables.isNotEmpty())
|
||||
{
|
||||
int target = (int) Math.round(tables.size() * multiplier);
|
||||
|
||||
while(tables.size() < target && tables.isNotEmpty())
|
||||
{
|
||||
tables.add(tables.get(rng.i(tables.size() - 1)));
|
||||
}
|
||||
|
||||
while(tables.size() > target && tables.isNotEmpty())
|
||||
{
|
||||
tables.remove(rng.i(tables.size() - 1));
|
||||
}
|
||||
}
|
||||
|
||||
return tables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public default void addItems(boolean debug, Inventory inv, RNG rng, KList<IrisLootTable> tables, InventorySlotType slot, int x, int y, int z, int mgf)
|
||||
{
|
||||
KList<ItemStack> items = new KList<>();
|
||||
|
||||
int b = 4;
|
||||
for(IrisLootTable i : tables)
|
||||
{
|
||||
b++;
|
||||
items.addAll(i.getLoot(debug, items.isEmpty(), rng.nextParallelRNG(345911), slot, x, y, z, b + b, mgf + b));
|
||||
}
|
||||
|
||||
for(ItemStack i : items)
|
||||
{
|
||||
inv.addItem(i);
|
||||
}
|
||||
|
||||
scramble(inv, rng);
|
||||
}
|
||||
|
||||
public default int getMaxHeight()
|
||||
{
|
||||
return getHeight() + getMinHeight();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.scaffold.hunk.Hunk;
|
||||
|
||||
public interface EngineActuator<O> extends EngineComponent
|
||||
{
|
||||
public void actuate(int x, int z, Hunk<O> output);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.scaffold.hunk.Hunk;
|
||||
|
||||
public abstract class EngineAssignedActuator<T> extends EngineAssignedComponent implements EngineActuator<T>
|
||||
{
|
||||
public EngineAssignedActuator(Engine engine, String name)
|
||||
{
|
||||
super(engine, name);
|
||||
}
|
||||
|
||||
public abstract void onActuate(int x, int z, Hunk<T> output);
|
||||
|
||||
@Override
|
||||
public void actuate(int x, int z, Hunk<T> output) {
|
||||
onActuate(x, z, output);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.scaffold.hunk.Hunk;
|
||||
|
||||
public abstract class EngineAssignedBiModifier<A, B> extends EngineAssignedComponent implements EngineBiModifier<A, B>
|
||||
{
|
||||
public EngineAssignedBiModifier(Engine engine, String name)
|
||||
{
|
||||
super(engine, name);
|
||||
}
|
||||
|
||||
public abstract void onModify(int x, int z, Hunk<A> a, Hunk<B> b);
|
||||
|
||||
@Override
|
||||
public void modify(int x, int z, Hunk<A> a, Hunk<B> b) {
|
||||
onModify(x, z, a, b);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.util.RollingSequence;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class EngineAssignedComponent implements EngineComponent {
|
||||
private final Engine engine;
|
||||
private final RollingSequence metrics;
|
||||
private final String name;
|
||||
|
||||
public EngineAssignedComponent(Engine engine, String name)
|
||||
{
|
||||
this.engine = engine;
|
||||
this.metrics = new RollingSequence(16);
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.scaffold.hunk.Hunk;
|
||||
|
||||
public abstract class EngineAssignedModifier<T> extends EngineAssignedComponent implements EngineModifier<T>
|
||||
{
|
||||
public EngineAssignedModifier(Engine engine, String name)
|
||||
{
|
||||
super(engine, name);
|
||||
}
|
||||
|
||||
public abstract void onModify(int x, int z, Hunk<T> output);
|
||||
|
||||
@Override
|
||||
public void modify(int x, int z, Hunk<T> output) {
|
||||
onModify(x, z, output);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
public abstract class EngineAssignedStructureManager extends EngineAssignedComponent implements EngineStructureManager {
|
||||
public EngineAssignedStructureManager(Engine engine) {
|
||||
super(engine, "Structure");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.entity.EntitySpawnEvent;
|
||||
import org.bukkit.event.world.WorldSaveEvent;
|
||||
import org.bukkit.event.world.WorldUnloadEvent;
|
||||
|
||||
public abstract class EngineAssignedWorldManager extends EngineAssignedComponent implements EngineWorldManager, Listener {
|
||||
private final int taskId;
|
||||
|
||||
public EngineAssignedWorldManager(Engine engine) {
|
||||
super(engine, "World");
|
||||
Iris.instance.registerListener(this);
|
||||
taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, this::onTick, 0, 0);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(WorldSaveEvent e)
|
||||
{
|
||||
if(e.getWorld().equals(getTarget().getWorld()))
|
||||
{
|
||||
onSave();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(WorldUnloadEvent e)
|
||||
{
|
||||
if(e.getWorld().equals(getTarget().getWorld()))
|
||||
{
|
||||
getEngine().close();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(EntitySpawnEvent e)
|
||||
{
|
||||
if(e.getEntity().getWorld().equals(getTarget().getWorld()))
|
||||
{
|
||||
onEntitySpawn(e);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(BlockBreakEvent e)
|
||||
{
|
||||
if(e.getPlayer().getWorld().equals(getTarget().getWorld()))
|
||||
{
|
||||
onBlockBreak(e);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(BlockPlaceEvent e)
|
||||
{
|
||||
if(e.getPlayer().getWorld().equals(getTarget().getWorld()))
|
||||
{
|
||||
onBlockPlace(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
super.close();
|
||||
Iris.instance.unregisterListener(this);
|
||||
Bukkit.getScheduler().cancelTask(taskId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.scaffold.hunk.Hunk;
|
||||
|
||||
public interface EngineBiModifier<A, B> extends EngineComponent {
|
||||
public void modify(int x, int z, Hunk<A> a, Hunk<B> b);
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.manager.IrisDataManager;
|
||||
import com.volmit.iris.object.IrisDimension;
|
||||
import com.volmit.iris.util.RollingSequence;
|
||||
import com.volmit.iris.generator.IrisComplex;
|
||||
import com.volmit.iris.scaffold.parallax.ParallaxAccess;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
public interface EngineComponent {
|
||||
public Engine getEngine();
|
||||
|
||||
public RollingSequence getMetrics();
|
||||
|
||||
public String getName();
|
||||
|
||||
default void close()
|
||||
{
|
||||
try
|
||||
{
|
||||
if(this instanceof Listener)
|
||||
{
|
||||
Iris.instance.unregisterListener((Listener) this);
|
||||
}
|
||||
}
|
||||
|
||||
catch(Throwable ignored)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
default double modX(double x)
|
||||
{
|
||||
return getEngine().modifyX(x);
|
||||
}
|
||||
|
||||
default double modZ(double z)
|
||||
{
|
||||
return getEngine().modifyZ(z);
|
||||
}
|
||||
|
||||
public default IrisDataManager getData()
|
||||
{
|
||||
return getEngine().getData();
|
||||
}
|
||||
|
||||
public default ParallaxAccess getParallax()
|
||||
{
|
||||
return getEngine().getParallax();
|
||||
}
|
||||
|
||||
public default EngineTarget getTarget()
|
||||
{
|
||||
return getEngine().getTarget();
|
||||
}
|
||||
|
||||
public default IrisDimension getDimension()
|
||||
{
|
||||
return getEngine().getDimension();
|
||||
}
|
||||
|
||||
public default long getSeed()
|
||||
{
|
||||
return getTarget().getWorld().getSeed();
|
||||
}
|
||||
|
||||
public default EngineFramework getFramework()
|
||||
{
|
||||
return getEngine().getFramework();
|
||||
}
|
||||
|
||||
public default int getParallelism()
|
||||
{
|
||||
return getEngine().getParallelism();
|
||||
}
|
||||
|
||||
public default IrisComplex getComplex()
|
||||
{
|
||||
return getFramework().getComplex();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.generator.IrisEngineCompound;
|
||||
import com.volmit.iris.generator.legacy.scaffold.TerrainChunk;
|
||||
import com.volmit.iris.manager.IrisDataManager;
|
||||
import com.volmit.iris.object.IrisBiome;
|
||||
import com.volmit.iris.object.IrisDimension;
|
||||
import com.volmit.iris.scaffold.hunk.Hunk;
|
||||
import com.volmit.iris.util.Form;
|
||||
import com.volmit.iris.util.KList;
|
||||
import com.volmit.iris.util.M;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class EngineCompositeGenerator extends ChunkGenerator implements IrisAccess {
|
||||
private EngineCompound compound;
|
||||
private final AtomicBoolean initialized;
|
||||
private final String dimensionHint;
|
||||
private final boolean production;
|
||||
private final KList<BlockPopulator> populators;
|
||||
private int generated = 0;
|
||||
|
||||
public EngineCompositeGenerator() {
|
||||
this(null, true);
|
||||
}
|
||||
|
||||
public EngineCompositeGenerator(String hint, boolean production) {
|
||||
super();
|
||||
this.production = production;
|
||||
this.dimensionHint = hint;
|
||||
initialized = new AtomicBoolean(false);
|
||||
populators = new KList<BlockPopulator>().qadd(new BlockPopulator() {
|
||||
@Override
|
||||
public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) {
|
||||
if(compound != null)
|
||||
{
|
||||
for(BlockPopulator i : compound.getPopulators())
|
||||
{
|
||||
i.populate(world, random, chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void hotload()
|
||||
{
|
||||
Iris.globaldata.dump();
|
||||
initialized.lazySet(false);
|
||||
}
|
||||
|
||||
private synchronized IrisDimension getDimension(World world) {
|
||||
String hint = dimensionHint;
|
||||
IrisDimension dim = null;
|
||||
|
||||
if (hint == null) {
|
||||
File iris = new File(world.getWorldFolder(), "iris");
|
||||
|
||||
searching:
|
||||
for (File i : iris.listFiles()) {
|
||||
// Look for v1 location
|
||||
if (i.isDirectory() && i.getName().equals("dimensions")) {
|
||||
for (File j : i.listFiles()) {
|
||||
if (j.isFile() && j.getName().endsWith(".json")) {
|
||||
hint = j.getName().replaceAll("\\Q.json\\E", "");
|
||||
break searching;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Look for v2 location
|
||||
else if (i.isFile() && i.getName().equals("engine-metadata.json")) {
|
||||
EngineData metadata = EngineData.load(i);
|
||||
hint = metadata.getDimension();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hint == null) {
|
||||
throw new RuntimeException("Cannot find iris dimension data for world: " + world.getName() + "! FAILED");
|
||||
}
|
||||
|
||||
dim = Iris.globaldata.preferFolder(hint).getDimensionLoader().load(hint);
|
||||
|
||||
if (dim == null) {
|
||||
throw new RuntimeException("Cannot find dimension: " + hint);
|
||||
}
|
||||
|
||||
if (production) {
|
||||
dim = new IrisDataManager(getDataFolder(world), true).preferFolder(dim.getLoadKey()).getDimensionLoader().load(dim.getLoadKey());
|
||||
|
||||
if (dim == null) {
|
||||
throw new RuntimeException("Cannot find dimension: " + hint);
|
||||
}
|
||||
}
|
||||
|
||||
return dim;
|
||||
}
|
||||
|
||||
private synchronized void initialize(World world) {
|
||||
if (initialized.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
IrisDataManager data = production ? new IrisDataManager(getDataFolder(world)) : Iris.globaldata.copy();
|
||||
IrisDimension dim = getDimension(world);
|
||||
data.preferFolder(dim.getLoadKey());
|
||||
compound = new IrisEngineCompound(world, dim, data, Iris.getThreadCount());
|
||||
initialized.set(true);
|
||||
populators.clear();
|
||||
populators.addAll(compound.getPopulators());
|
||||
}
|
||||
|
||||
private File getDataFolder(World world) {
|
||||
return new File(world.getWorldFolder(), "iris/pack");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ChunkData generateChunkData(@NotNull World world, @NotNull Random ignored, int x, int z, @NotNull BiomeGrid biome) {
|
||||
TerrainChunk tc = TerrainChunk.create(world, biome);
|
||||
generateChunkRawData(world, ignored, x, z, tc);
|
||||
return tc.getRaw();
|
||||
}
|
||||
|
||||
public void generateChunkRawData(World world, Random ignored, int x, int z, TerrainChunk tc)
|
||||
{
|
||||
initialize(world);
|
||||
Hunk<BlockData> blocks = Hunk.view((ChunkData) tc);
|
||||
Hunk<Biome> biomes = Hunk.view((BiomeGrid) tc);
|
||||
long m = M.ms();
|
||||
compound.generate(x * 16, z * 16, blocks, biomes);
|
||||
System.out.println("Generated " + x + "," + z + " in " + Form.duration(M.ms() - m, 0));
|
||||
generated++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSpawn(@NotNull World world, int x, int z) {
|
||||
return super.canSpawn(world, x, z);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<BlockPopulator> getDefaultPopulators(@NotNull World world) {
|
||||
return populators;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Location getFixedSpawnLocation(@NotNull World world, @NotNull Random random) {
|
||||
return super.getFixedSpawnLocation(world, random);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isParallelCapable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateCaves() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateDecorations() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateMobs() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateStructures() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static EngineCompositeGenerator newStudioWorld(String dimension) {
|
||||
return new EngineCompositeGenerator(dimension, false);
|
||||
}
|
||||
|
||||
public static EngineCompositeGenerator newProductionWorld(String dimension) {
|
||||
return new EngineCompositeGenerator(dimension, true);
|
||||
}
|
||||
|
||||
public static EngineCompositeGenerator newProductionWorld() {
|
||||
return new EngineCompositeGenerator(null, true);
|
||||
}
|
||||
|
||||
public EngineCompound getComposite() {
|
||||
return compound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IrisBiome getBiome(int x, int z) {
|
||||
return getBiome(x, 0, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IrisBiome getCaveBiome(int x, int z) {
|
||||
return getCaveBiome(x, 0, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGenerated() {
|
||||
return generated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IrisBiome getBiome(int x, int y, int z) {
|
||||
// TODO: REMOVE GET ABS BIOME OR THIS ONE
|
||||
return getEngineAccess(y).getBiome(x, y-getComposite().getEngineForHeight(y).getMinHeight(), z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IrisBiome getCaveBiome(int x, int y, int z) {
|
||||
return getEngineAccess(y).getCaveBiome(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GeneratorAccess getEngineAccess(int y) {
|
||||
return getComposite().getEngineForHeight(y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IrisDataManager getData() {
|
||||
return getComposite().getData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight(int x, int y, int z) {
|
||||
return getEngineAccess(y).getHeight(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IrisBiome getAbsoluteBiome(int x, int y, int z) {
|
||||
// TODO: REMOVE GET BIOME OR THIS ONE
|
||||
return getEngineAccess(y).getBiome(x, y-getComposite().getEngineForHeight(y).getMinHeight(), z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getThreadCount() {
|
||||
// TODO: NOT CORRECT
|
||||
return Iris.getThreadCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeThreadCount(int m) {
|
||||
// TODO: DO IT
|
||||
}
|
||||
|
||||
@Override
|
||||
public void regenerate(int x, int z) {
|
||||
// TODO: DO IT
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
getComposite().close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosed() {
|
||||
return getComposite().getEngine(0).isClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EngineTarget getTarget() {
|
||||
return getComposite().getEngine(0).getTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EngineCompound getCompound() {
|
||||
return getComposite();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.manager.IrisDataManager;
|
||||
import com.volmit.iris.object.IrisDimension;
|
||||
import com.volmit.iris.util.KList;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import com.volmit.iris.scaffold.hunk.Hunk;
|
||||
import com.volmit.iris.scaffold.parallel.MultiBurst;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
|
||||
public interface EngineCompound extends Listener
|
||||
{
|
||||
public IrisDimension getRootDimension();
|
||||
|
||||
public void generate(int x, int z, Hunk<BlockData> blocks, Hunk<Biome> biomes);
|
||||
|
||||
public World getWorld();
|
||||
|
||||
public int getSize();
|
||||
|
||||
public Engine getEngine(int index);
|
||||
|
||||
public MultiBurst getBurster();
|
||||
|
||||
public EngineData getEngineMetadata();
|
||||
|
||||
public void saveEngineMetadata();
|
||||
|
||||
public KList<BlockPopulator> getPopulators();
|
||||
|
||||
default Engine getEngineForHeight(int height)
|
||||
{
|
||||
if(getSize() == 1)
|
||||
{
|
||||
return getEngine(0);
|
||||
}
|
||||
|
||||
int buf = 0;
|
||||
|
||||
for(int i = 0; i < getSize(); i++)
|
||||
{
|
||||
Engine e = getEngine(i);
|
||||
buf += e.getHeight();
|
||||
|
||||
if(buf >= height)
|
||||
{
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
return getEngine(getSize() - 1);
|
||||
}
|
||||
|
||||
public default void save()
|
||||
{
|
||||
saveEngineMetadata();
|
||||
for(int i = 0; i < getSize(); i++)
|
||||
{
|
||||
getEngine(i).save();
|
||||
}
|
||||
}
|
||||
|
||||
public default void saveNOW()
|
||||
{
|
||||
saveEngineMetadata();
|
||||
for(int i = 0; i < getSize(); i++)
|
||||
{
|
||||
getEngine(i).saveNow();
|
||||
}
|
||||
}
|
||||
|
||||
public IrisDataManager getData(int height);
|
||||
|
||||
public default IrisDataManager getData()
|
||||
{
|
||||
return getData(0);
|
||||
}
|
||||
|
||||
public default void close()
|
||||
{
|
||||
for(int i = 0; i < getSize(); i++)
|
||||
{
|
||||
getEngine(i).close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.volmit.iris.util.IO;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
@Data
|
||||
public class EngineData {
|
||||
private String dimension;
|
||||
private String lastVersion;
|
||||
|
||||
public void save(File f)
|
||||
{
|
||||
try {
|
||||
f.getParentFile().mkdirs();
|
||||
IO.writeAll(f, new Gson().toJson(this));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static EngineData load(File f)
|
||||
{
|
||||
try
|
||||
{
|
||||
f.getParentFile().mkdirs();
|
||||
return new Gson().fromJson(IO.readAll(f), EngineData.class);
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return new EngineData();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.object.IrisBiome;
|
||||
import com.volmit.iris.util.B;
|
||||
import com.volmit.iris.scaffold.hunk.Hunk;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
public interface EngineDecorator extends EngineComponent {
|
||||
public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk<BlockData> data, IrisBiome biome, int height, int max);
|
||||
|
||||
default void decorate(int x, int z, int realX, int realZ, Hunk<BlockData> data, IrisBiome biome, int height, int max)
|
||||
{
|
||||
decorate(x, z, realX, realX, realX, realZ, realZ, realZ, data, biome, height, max);
|
||||
}
|
||||
|
||||
default boolean canGoOn(BlockData decorant, BlockData atop)
|
||||
{
|
||||
return B.canPlaceOnto(decorant.getMaterial(), atop.getMaterial());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.util.M;
|
||||
import com.volmit.iris.scaffold.parallel.MultiBurst;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
import com.volmit.iris.manager.IrisDataManager;
|
||||
import com.volmit.iris.generator.IrisComplex;
|
||||
import com.volmit.iris.scaffold.data.DataProvider;
|
||||
|
||||
public interface EngineFramework extends DataProvider
|
||||
{
|
||||
public Engine getEngine();
|
||||
|
||||
public IrisComplex getComplex();
|
||||
|
||||
public EngineParallaxManager getEngineParallax();
|
||||
|
||||
default IrisDataManager getData() {
|
||||
return getComplex().getData();
|
||||
}
|
||||
|
||||
default void recycle()
|
||||
{
|
||||
if(M.r(0.1))
|
||||
{
|
||||
MultiBurst.burst.lazy(() -> {
|
||||
getEngine().getParallax().cleanup();
|
||||
getData().getObjectLoader().clean();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public EngineActuator<BlockData> getTerrainActuator();
|
||||
|
||||
public EngineActuator<BlockData> getDecorantActuator();
|
||||
|
||||
public EngineActuator<Biome> getBiomeActuator();
|
||||
|
||||
public EngineModifier<BlockData> getCaveModifier();
|
||||
|
||||
public EngineModifier<BlockData> getRavineModifier();
|
||||
|
||||
public EngineModifier<BlockData> getDepositModifier();
|
||||
|
||||
public EngineModifier<BlockData> getPostModifier();
|
||||
|
||||
void close();
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.scaffold.hunk.Hunk;
|
||||
|
||||
public interface EngineModifier<T> extends EngineComponent {
|
||||
public void modify(int x, int z, Hunk<T> t);
|
||||
}
|
||||
@@ -0,0 +1,443 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.volmit.iris.object.*;
|
||||
import com.volmit.iris.util.*;
|
||||
import com.volmit.iris.generator.actuator.IrisTerrainActuator;
|
||||
import com.volmit.iris.generator.modifier.IrisCaveModifier;
|
||||
import com.volmit.iris.scaffold.parallax.ParallaxChunkMeta;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.util.BlockVector;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.manager.IrisDataManager;
|
||||
import com.volmit.iris.generator.IrisComplex;
|
||||
import com.volmit.iris.scaffold.cache.Cache;
|
||||
import com.volmit.iris.scaffold.data.DataProvider;
|
||||
import com.volmit.iris.scaffold.hunk.Hunk;
|
||||
import com.volmit.iris.scaffold.parallax.ParallaxAccess;
|
||||
import com.volmit.iris.scaffold.parallel.BurstExecutor;
|
||||
import com.volmit.iris.scaffold.parallel.MultiBurst;
|
||||
|
||||
public interface EngineParallaxManager extends DataProvider, IObjectPlacer
|
||||
{
|
||||
public static final BlockData AIR = B.get("AIR");
|
||||
|
||||
public Engine getEngine();
|
||||
|
||||
public int getParallaxSize();
|
||||
|
||||
public EngineStructureManager getStructureManager();
|
||||
|
||||
default EngineFramework getFramework()
|
||||
{
|
||||
return getEngine().getFramework();
|
||||
}
|
||||
|
||||
default ParallaxAccess getParallaxAccess()
|
||||
{
|
||||
return getEngine().getParallax();
|
||||
}
|
||||
|
||||
default IrisDataManager getData()
|
||||
{
|
||||
return getEngine().getData();
|
||||
}
|
||||
|
||||
default IrisComplex getComplex()
|
||||
{
|
||||
return getEngine().getFramework().getComplex();
|
||||
}
|
||||
|
||||
default KList<IrisRegion> getAllRegions()
|
||||
{
|
||||
KList<IrisRegion> r = new KList<>();
|
||||
|
||||
for(String i : getEngine().getDimension().getRegions())
|
||||
{
|
||||
r.add(getEngine().getData().getRegionLoader().load(i));
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
default KList<IrisBiome> getAllBiomes()
|
||||
{
|
||||
KList<IrisBiome> r = new KList<>();
|
||||
|
||||
for(IrisRegion i : getAllRegions())
|
||||
{
|
||||
r.addAll(i.getAllBiomes(this));
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
default void insertParallax(int x, int z, Hunk<BlockData> data)
|
||||
{
|
||||
ParallaxChunkMeta meta = getParallaxAccess().getMetaR(x>>4, z>>4);
|
||||
|
||||
if(!meta.isObjects()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(int i = x; i < x+ data.getWidth(); i++)
|
||||
{
|
||||
for(int j= z; j < z + data.getDepth(); j++)
|
||||
{
|
||||
for(int k = 0; k < data.getHeight(); k++)
|
||||
{
|
||||
BlockData d = getParallaxAccess().getBlock(i, k, j);
|
||||
|
||||
if(d != null)
|
||||
{
|
||||
data.set(i - x, k, j - z, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default void generateParallaxArea(int x, int z)
|
||||
{
|
||||
int s = (int) Math.ceil(getParallaxSize() / 2D);
|
||||
int j;
|
||||
BurstExecutor e = MultiBurst.burst.burst(getParallaxSize() * getParallaxSize());
|
||||
|
||||
for(int i = -s; i <= s; i++)
|
||||
{
|
||||
int ii = i;
|
||||
|
||||
for(j = -s; j <= s; j++)
|
||||
{
|
||||
int jj = j;
|
||||
e.queue(() -> generateParallaxLayer((ii*16)+x, (jj*16)+z));
|
||||
}
|
||||
}
|
||||
|
||||
e.complete();
|
||||
|
||||
getParallaxAccess().setChunkGenerated(x>>4, z>>4);
|
||||
}
|
||||
|
||||
default void generateParallaxLayer(int x, int z)
|
||||
{
|
||||
if(getParallaxAccess().isParallaxGenerated(x >> 4, z >> 4))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
getParallaxAccess().setParallaxGenerated(x>>4, z>>4);
|
||||
RNG rng = new RNG(Cache.key(x, z)).nextParallelRNG(getEngine().getTarget().getWorld().getSeed());
|
||||
IrisRegion region = getComplex().getRegionStream().get(x+8, z+8);
|
||||
IrisBiome biome = getComplex().getTrueBiomeStream().get(x+8, z+8);
|
||||
generateParallaxSurface(rng, x, z, biome);
|
||||
generateParallaxMutations(rng, x, z);
|
||||
generateStructures(rng, x>>4, z>>4, region, biome);
|
||||
}
|
||||
|
||||
default void generateStructures(RNG rng, int x, int z, IrisRegion region, IrisBiome biome)
|
||||
{
|
||||
int g = 30265;
|
||||
for(IrisStructurePlacement k : region.getStructures())
|
||||
{
|
||||
if(k == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
getStructureManager().placeStructure(k, rng.nextParallelRNG(2228 * 2 * g++), x, z);
|
||||
}
|
||||
|
||||
for(IrisStructurePlacement k : biome.getStructures())
|
||||
{
|
||||
if(k == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
getStructureManager().placeStructure(k, rng.nextParallelRNG(-22228 * 4 * g++), x, z);
|
||||
}
|
||||
}
|
||||
|
||||
default void generateParallaxSurface(RNG rng, int x, int z, IrisBiome biome) {
|
||||
for (IrisObjectPlacement i : biome.getSurfaceObjects())
|
||||
{
|
||||
if(rng.chance(i.getChance()))
|
||||
{
|
||||
place(rng, x, z, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default void generateParallaxMutations(RNG rng, int x, int z) {
|
||||
if(getEngine().getDimension().getMutations().isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
searching: for(IrisBiomeMutation k : getEngine().getDimension().getMutations())
|
||||
{
|
||||
for(int l = 0; l < k.getChecks(); l++)
|
||||
{
|
||||
IrisBiome sa = getComplex().getTrueBiomeStream().get(((x * 16) + rng.nextInt(16)) + rng.i(-k.getRadius(), k.getRadius()), ((z * 16) + rng.nextInt(16)) + rng.i(-k.getRadius(), k.getRadius()));
|
||||
IrisBiome sb = getComplex().getTrueBiomeStream().get(((x * 16) + rng.nextInt(16)) + rng.i(-k.getRadius(), k.getRadius()), ((z * 16) + rng.nextInt(16)) + rng.i(-k.getRadius(), k.getRadius()));
|
||||
|
||||
if(sa.getLoadKey().equals(sb.getLoadKey()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(k.getRealSideA(this).contains(sa.getLoadKey()) && k.getRealSideB(this).contains(sb.getLoadKey()))
|
||||
{
|
||||
for(IrisObjectPlacement m : k.getObjects())
|
||||
{
|
||||
place(rng.nextParallelRNG((34 * ((x * 30) + (z * 30)) * x * z) + x - z + 1569962), x, z, m);
|
||||
}
|
||||
|
||||
continue searching;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default void place(RNG rng, int x, int z, IrisObjectPlacement objectPlacement)
|
||||
{
|
||||
place(rng, x,-1, z, objectPlacement);
|
||||
}
|
||||
|
||||
default void place(RNG rng, int x, int forceY, int z, IrisObjectPlacement objectPlacement)
|
||||
{
|
||||
for(int i = 0; i < objectPlacement.getDensity(); i++)
|
||||
{
|
||||
IrisObject v = objectPlacement.getSchematic(getComplex(), rng);
|
||||
int xx = rng.i(x, x+16);
|
||||
int zz = rng.i(z, z+16);
|
||||
int id = rng.i(0, Integer.MAX_VALUE);
|
||||
v.place(xx, forceY, zz, this, objectPlacement, rng, (b) -> {
|
||||
getParallaxAccess().setObject(b.getX(), b.getY(), b.getZ(), v.getLoadKey() + "@" + id);
|
||||
ParallaxChunkMeta meta = getParallaxAccess().getMetaRW(b.getX() >> 4, b.getZ() >> 4);
|
||||
meta.setObjects(true);
|
||||
meta.setMaxObject(Math.max(b.getY(), meta.getMaxObject()));
|
||||
meta.setMinObject(Math.min(b.getY(), Math.max(meta.getMinObject(), 0)));
|
||||
}, null, getData());
|
||||
}
|
||||
}
|
||||
|
||||
default void updateParallaxChunkObjectData(int minY, int maxY, int x, int z, IrisObject v)
|
||||
{
|
||||
ParallaxChunkMeta meta = getParallaxAccess().getMetaRW(x >> 4, z >> 4);
|
||||
meta.setObjects(true);
|
||||
meta.setMaxObject(Math.max(maxY, meta.getMaxObject()));
|
||||
meta.setMinObject(Math.min(minY, Math.max(meta.getMinObject(), 0)));
|
||||
}
|
||||
|
||||
default int computeParallaxSize()
|
||||
{
|
||||
Iris.verbose("Calculating the Parallax Size in Parallel");
|
||||
AtomicInteger xg = new AtomicInteger(0);
|
||||
AtomicInteger zg = new AtomicInteger();
|
||||
xg.set(0);
|
||||
zg.set(0);
|
||||
|
||||
KSet<String> objects = new KSet<>();
|
||||
KList<IrisRegion> r = getAllRegions();
|
||||
KList<IrisBiome> b = getAllBiomes();
|
||||
|
||||
for(IrisBiome i : b)
|
||||
{
|
||||
for(IrisObjectPlacement j : i.getObjects())
|
||||
{
|
||||
objects.addAll(j.getPlace());
|
||||
}
|
||||
}
|
||||
|
||||
Iris.verbose("Checking sizes for " + Form.f(objects.size()) + " referenced objects.");
|
||||
BurstExecutor e = MultiBurst.burst.burst(objects.size());
|
||||
for(String i : objects)
|
||||
{
|
||||
e.queue(() -> {
|
||||
try
|
||||
{
|
||||
BlockVector bv = IrisObject.sampleSize(getData().getObjectLoader().findFile(i));
|
||||
synchronized (xg)
|
||||
{
|
||||
xg.getAndSet(Math.max(bv.getBlockX(), xg.get()));
|
||||
}
|
||||
|
||||
synchronized (zg)
|
||||
{
|
||||
zg.getAndSet(Math.max(bv.getBlockZ(), zg.get()));
|
||||
}
|
||||
}
|
||||
|
||||
catch(Throwable ignored)
|
||||
{
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
e.complete();
|
||||
|
||||
int x = xg.get();
|
||||
int z = zg.get();
|
||||
|
||||
for(IrisDepositGenerator i : getEngine().getDimension().getDeposits())
|
||||
{
|
||||
int max = i.getMaxDimension();
|
||||
x = Math.max(max, x);
|
||||
z = Math.max(max, z);
|
||||
}
|
||||
|
||||
for(IrisTextPlacement i : getEngine().getDimension().getText())
|
||||
{
|
||||
int max = i.maxDimension();
|
||||
x = Math.max(max, x);
|
||||
z = Math.max(max, z);
|
||||
}
|
||||
|
||||
for(IrisRegion v : r)
|
||||
{
|
||||
for(IrisDepositGenerator i : v.getDeposits())
|
||||
{
|
||||
int max = i.getMaxDimension();
|
||||
x = Math.max(max, x);
|
||||
z = Math.max(max, z);
|
||||
}
|
||||
|
||||
for(IrisTextPlacement i : v.getText())
|
||||
{
|
||||
int max = i.maxDimension();
|
||||
x = Math.max(max, x);
|
||||
z = Math.max(max, z);
|
||||
}
|
||||
}
|
||||
|
||||
for(IrisBiome v : b)
|
||||
{
|
||||
for(IrisDepositGenerator i : v.getDeposits())
|
||||
{
|
||||
int max = i.getMaxDimension();
|
||||
x = Math.max(max, x);
|
||||
z = Math.max(max, z);
|
||||
}
|
||||
|
||||
for(IrisTextPlacement i : v.getText())
|
||||
{
|
||||
int max = i.maxDimension();
|
||||
x = Math.max(max, x);
|
||||
z = Math.max(max, z);
|
||||
}
|
||||
}
|
||||
|
||||
x = (Math.max(x, 16) + 16) >> 4;
|
||||
z = (Math.max(z, 16) + 16) >> 4;
|
||||
x = x % 2 == 0 ? x + 1 : x;
|
||||
z = z % 2 == 0 ? z + 1 : z;
|
||||
x = Math.max(x, z);
|
||||
z = x;
|
||||
Iris.verbose(getEngine().getDimension().getName() + " Parallax Size: " + x + ", " + z);
|
||||
return x;
|
||||
}
|
||||
|
||||
@Override
|
||||
default int getHighest(int x, int z) {
|
||||
return getHighest(x,z,false);
|
||||
}
|
||||
|
||||
@Override
|
||||
default int getHighest(int x, int z, boolean ignoreFluid) {
|
||||
return ignoreFluid ? trueHeight(x, z) : Math.max(trueHeight(x, z), getEngine().getDimension().getFluidHeight());
|
||||
}
|
||||
|
||||
default int trueHeight(int x, int z)
|
||||
{
|
||||
int rx = (int) Math.round(getEngine().modifyX(x));
|
||||
int rz = (int) Math.round(getEngine().modifyZ(z));
|
||||
int height = (int) Math.round(getComplex().getHeightStream().get(rx, rz));
|
||||
int m = height;
|
||||
|
||||
if(getEngine().getDimension().isCarving())
|
||||
{
|
||||
if(getEngine().getDimension().isCarved(rx, m, rz, ((IrisTerrainActuator)getFramework().getTerrainActuator()).getRng(), height))
|
||||
{
|
||||
m--;
|
||||
|
||||
while(getEngine().getDimension().isCarved(rx, m, rz, ((IrisTerrainActuator)getFramework().getTerrainActuator()).getRng(), height))
|
||||
{
|
||||
m--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(getEngine().getDimension().isCaves())
|
||||
{
|
||||
KList<CaveResult> caves = ((IrisCaveModifier)getFramework().getCaveModifier()).genCaves(rx, rz, 0, 0, null);
|
||||
boolean again = true;
|
||||
|
||||
while(again)
|
||||
{
|
||||
again = false;
|
||||
for(CaveResult i : caves)
|
||||
{
|
||||
if(i.getCeiling() > m && i.getFloor() < m)
|
||||
{
|
||||
m = i.getFloor();
|
||||
again = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
@Override
|
||||
default void set(int x, int y, int z, BlockData d) {
|
||||
getParallaxAccess().setBlock(x,y,z,d);
|
||||
}
|
||||
|
||||
@Override
|
||||
default BlockData get(int x, int y, int z) {
|
||||
BlockData block = getParallaxAccess().getBlock(x,y,z);
|
||||
|
||||
if(block == null)
|
||||
{
|
||||
return AIR;
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isPreventingDecay() {
|
||||
return getEngine().getDimension().isPreventLeafDecay();
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isSolid(int x, int y, int z) {
|
||||
return B.isSolid(get(x,y,z));
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isUnderwater(int x, int z) {
|
||||
return getHighest(x, z, true) <= getFluidHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
default int getFluidHeight() {
|
||||
return getEngine().getDimension().getFluidHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isDebugSmartBore() {
|
||||
return getEngine().getDimension().isDebugSmartBore();
|
||||
}
|
||||
|
||||
default void close()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.object.IrisObject;
|
||||
import com.volmit.iris.object.IrisRareObject;
|
||||
import com.volmit.iris.object.IrisStructurePlacement;
|
||||
import com.volmit.iris.object.TileResult;
|
||||
import com.volmit.iris.util.ChunkPosition;
|
||||
import com.volmit.iris.util.KSet;
|
||||
import com.volmit.iris.util.RNG;
|
||||
import com.volmit.iris.scaffold.parallax.ParallaxChunkMeta;
|
||||
|
||||
public interface EngineStructureManager extends EngineComponent
|
||||
{
|
||||
default void placeStructure(IrisStructurePlacement structure, RNG rngno, int cx, int cz)
|
||||
{
|
||||
RNG rng = new RNG(getEngine().getWorld().getSeed()).nextParallelRNG(-88738456 + rngno.nextInt());
|
||||
RNG rnp = rng.nextParallelRNG(cx - (cz * cz << 3) + rngno.nextInt());
|
||||
int s = structure.gridSize(getEngine()) - (structure.getStructure(getEngine()).isMergeEdges() ? 1 : 0);
|
||||
int sh = structure.gridHeight(getEngine()) - (structure.getStructure(getEngine()).isMergeEdges() ? 1 : 0);
|
||||
KSet<ChunkPosition> m = new KSet<>();
|
||||
|
||||
for(int i = cx << 4; i <= (cx << 4) + 15; i += 1)
|
||||
{
|
||||
if(Math.floorDiv(i, s) * s >> 4 < cx)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for(int j = cz << 4; j <= (cz << 4) + 15; j += 1)
|
||||
{
|
||||
if(Math.floorDiv(j, s) * s >> 4 < cz)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ChunkPosition p = new ChunkPosition(Math.floorDiv(i, s) * s, Math.floorDiv(j, s) * s);
|
||||
|
||||
if(m.contains(p))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
m.add(p);
|
||||
|
||||
if(structure.getStructure(getEngine()).getMaxLayers() <= 1)
|
||||
{
|
||||
placeLayer(structure, rng, rnp, i, 0, j, s, sh);
|
||||
continue;
|
||||
}
|
||||
|
||||
for(int k = 0; k < s * structure.getStructure(getEngine()).getMaxLayers(); k += Math.max(sh, 1))
|
||||
{
|
||||
placeLayer(structure, rng, rnp, i, k, j, s, sh);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default void placeLayer(IrisStructurePlacement structure, RNG rng, RNG rnp, int i, int k, int j, int s, int sh)
|
||||
{
|
||||
if(!hasStructure(structure, rng, i, k, j))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int h = (structure.getHeight() == -1 ? 0 : structure.getHeight()) + (Math.floorDiv(k, sh) * sh);
|
||||
TileResult t = structure.getStructure(getEngine()).getTile(rng, Math.floorDiv(i, s) * s, h, Math.floorDiv(j, s) * s);
|
||||
|
||||
if(t != null)
|
||||
{
|
||||
IrisObject o = null;
|
||||
|
||||
for(IrisRareObject l : t.getTile().getRareObjects())
|
||||
{
|
||||
if(rnp.i(1, l.getRarity()) == 1)
|
||||
{
|
||||
o = structure.load(getEngine(), l.getObject());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
o = o != null ? o : structure.load(getEngine(), t.getTile().getObjects().get(rnp.nextInt(t.getTile().getObjects().size())));
|
||||
int id = rng.i(0, Integer.MAX_VALUE);
|
||||
IrisObject oo = o;
|
||||
o.place(
|
||||
Math.floorDiv(i, s) * s,
|
||||
structure.getHeight() == -1 ? -1 : h,
|
||||
Math.floorDiv(j, s) * s,
|
||||
getEngine().getFramework().getEngineParallax(),
|
||||
t.getPlacement(),
|
||||
rng,
|
||||
(b) -> {
|
||||
getEngine().getParallax().setObject(b.getX(), b.getY(), b.getZ(), oo.getLoadKey() + "@" + id);
|
||||
ParallaxChunkMeta meta = getEngine().getParallax().getMetaRW(b.getX() >> 4, b.getZ() >> 4);
|
||||
meta.setObjects(true);
|
||||
meta.setMaxObject(Math.max(b.getY(), meta.getMaxObject()));
|
||||
meta.setMinObject(Math.min(b.getY(), Math.max(meta.getMinObject(), 0)));
|
||||
},
|
||||
null,
|
||||
getData()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
default boolean hasStructure(IrisStructurePlacement structure, RNG random, double x, double y, double z)
|
||||
{
|
||||
if(structure.getChanceGenerator(new RNG(getEngine().getWorld().getSeed())).getIndex(x / structure.getZoom(), y / structure.getZoom(), z / structure.getZoom(), structure.getRarity()) == structure.getRarity() / 2)
|
||||
{
|
||||
return structure.getRatio() > 0 ? structure.getChanceGenerator(new RNG(getEngine().getWorld().getSeed())).getDistance(x / structure.getZoom(), z / structure.getZoom()) > structure.getRatio() : structure.getChanceGenerator(new RNG(getEngine().getWorld().getSeed())).getDistance(x / structure.getZoom(), z / structure.getZoom()) < Math.abs(structure.getRatio());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.scaffold.parallax.ParallaxWorld;
|
||||
import com.volmit.iris.manager.IrisDataManager;
|
||||
import com.volmit.iris.object.IrisDimension;
|
||||
import com.volmit.iris.scaffold.parallel.MultiBurst;
|
||||
import lombok.Data;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@Data
|
||||
public class EngineTarget
|
||||
{
|
||||
private final MultiBurst burster;
|
||||
private final IrisDimension dimension;
|
||||
private final World world;
|
||||
private final int height;
|
||||
private final IrisDataManager data;
|
||||
private final ParallaxWorld parallaxWorld;
|
||||
private final boolean inverted;
|
||||
|
||||
public EngineTarget(World world, IrisDimension dimension, IrisDataManager data, int height, boolean inverted, int threads)
|
||||
{
|
||||
this.world = world;
|
||||
this.height = height;
|
||||
this.dimension = dimension;
|
||||
this.data = data;
|
||||
this.parallaxWorld = new ParallaxWorld(256, new File(world.getWorldFolder(), "iris/" + dimension.getLoadKey() + "/parallax"));
|
||||
this.inverted = inverted;
|
||||
this.burster = new MultiBurst(threads);
|
||||
}
|
||||
|
||||
public EngineTarget(World world, IrisDimension dimension, IrisDataManager data, int height, int threads)
|
||||
{
|
||||
this(world, dimension, data, height, false, threads);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.entity.EntitySpawnEvent;
|
||||
|
||||
public interface EngineWorldManager
|
||||
{
|
||||
public void close();
|
||||
|
||||
public void onEntitySpawn(EntitySpawnEvent e);
|
||||
|
||||
public void onTick();
|
||||
|
||||
public void onSave();
|
||||
|
||||
public void spawnInitialEntities(Chunk chunk);
|
||||
|
||||
public void onBlockBreak(BlockBreakEvent e);
|
||||
|
||||
public void onBlockPlace(BlockPlaceEvent e);
|
||||
}
|
||||
26
src/main/java/com/volmit/iris/scaffold/engine/Fallible.java
Normal file
26
src/main/java/com/volmit/iris/scaffold/engine/Fallible.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
public interface Fallible
|
||||
{
|
||||
public default void fail(String error)
|
||||
{
|
||||
try
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
fail(error, e);
|
||||
}
|
||||
}
|
||||
|
||||
public default void fail(Throwable e)
|
||||
{
|
||||
fail("Failed to generate", e);
|
||||
}
|
||||
|
||||
public void fail(String error, Throwable e);
|
||||
|
||||
public boolean hasFailed();
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.manager.IrisDataManager;
|
||||
import com.volmit.iris.object.IrisBiome;
|
||||
import com.volmit.iris.object.IrisObjectPlacement;
|
||||
import com.volmit.iris.object.IrisRegion;
|
||||
import com.volmit.iris.scaffold.parallax.ParallaxAccess;
|
||||
|
||||
public interface GeneratorAccess
|
||||
{
|
||||
public IrisRegion getRegion(int x, int z);
|
||||
|
||||
public ParallaxAccess getParallaxAccess();
|
||||
|
||||
public IrisDataManager getData();
|
||||
|
||||
public IrisBiome getCaveBiome(int x, int z);
|
||||
|
||||
public IrisBiome getSurfaceBiome(int x, int z);
|
||||
|
||||
public int getHeight(int x, int z);
|
||||
|
||||
public default IrisBiome getBiome(int x, int y, int z)
|
||||
{
|
||||
if(y <= getHeight(x, z) - 2)
|
||||
{
|
||||
return getCaveBiome(x, z);
|
||||
}
|
||||
|
||||
return getSurfaceBiome(x, z);
|
||||
}
|
||||
public default PlacedObject getObjectPlacement(int x, int y, int z)
|
||||
{
|
||||
String objectAt = getParallaxAccess().getObject(x, y, z);
|
||||
|
||||
if(objectAt == null || objectAt.isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] v = objectAt.split("\\Q@\\E");
|
||||
String object = v[0];
|
||||
int id = Integer.parseInt(v[1]);
|
||||
IrisRegion region = getRegion(x, z);
|
||||
|
||||
for(IrisObjectPlacement i : region.getObjects())
|
||||
{
|
||||
if(i.getPlace().contains(object))
|
||||
{
|
||||
return new PlacedObject(i, getData().getObjectLoader().load(object), id);
|
||||
}
|
||||
}
|
||||
|
||||
IrisBiome biome = getBiome(x, y, z);
|
||||
|
||||
for(IrisObjectPlacement i : biome.getObjects())
|
||||
{
|
||||
if(i.getPlace().contains(object))
|
||||
{
|
||||
return new PlacedObject(i, getData().getObjectLoader().load(object), id);
|
||||
}
|
||||
}
|
||||
|
||||
return new PlacedObject(null, getData().getObjectLoader().load(object), id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
public interface Hotloadable {
|
||||
public void hotload();
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.manager.IrisDataManager;
|
||||
import com.volmit.iris.object.IrisBiome;
|
||||
|
||||
public interface IrisAccess extends Hotloadable {
|
||||
|
||||
public int getGenerated();
|
||||
|
||||
public IrisBiome getBiome(int x, int y, int z);
|
||||
|
||||
public IrisBiome getCaveBiome(int x, int y, int z);
|
||||
|
||||
public IrisBiome getBiome(int x, int z);
|
||||
|
||||
public IrisBiome getCaveBiome(int x, int z);
|
||||
|
||||
public GeneratorAccess getEngineAccess(int y);
|
||||
|
||||
public IrisDataManager getData();
|
||||
|
||||
public int getHeight(int x, int y, int z);
|
||||
|
||||
public IrisBiome getAbsoluteBiome(int x, int y, int z);
|
||||
|
||||
public int getThreadCount();
|
||||
|
||||
public void changeThreadCount(int m);
|
||||
|
||||
public void regenerate(int x, int z);
|
||||
|
||||
public void close();
|
||||
|
||||
public boolean isClosed();
|
||||
|
||||
public EngineTarget getTarget();
|
||||
|
||||
public EngineCompound getCompound();
|
||||
|
||||
public boolean isFailing();
|
||||
|
||||
public boolean isStudio();
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.object.InventorySlotType;
|
||||
import com.volmit.iris.object.IrisLootReference;
|
||||
import com.volmit.iris.object.IrisLootTable;
|
||||
import com.volmit.iris.util.KList;
|
||||
import com.volmit.iris.util.RNG;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
public interface LootProvider {
|
||||
public void scramble(Inventory inventory, RNG rng);
|
||||
|
||||
public void injectTables(KList<IrisLootTable> list, IrisLootReference r);
|
||||
|
||||
public KList<IrisLootTable> getLootTables(RNG rng, Block b);
|
||||
|
||||
public void addItems(boolean debug, Inventory inv, RNG rng, KList<IrisLootTable> tables, InventorySlotType slot, int x, int y, int z, int mgf);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.volmit.iris.scaffold.engine;
|
||||
|
||||
import com.volmit.iris.object.IrisObject;
|
||||
import com.volmit.iris.object.IrisObjectPlacement;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class PlacedObject {
|
||||
@Nullable
|
||||
private IrisObjectPlacement placement;
|
||||
@Nullable
|
||||
private IrisObject object;
|
||||
private int id;
|
||||
}
|
||||
Reference in New Issue
Block a user