Block Updates (not yet working)

This commit is contained in:
Daniel Mills 2020-11-02 12:29:55 -05:00
parent 8b720e103f
commit 44358c122f
8 changed files with 298 additions and 14 deletions

View File

@ -9,6 +9,7 @@ import com.volmit.iris.util.KList;
import com.volmit.iris.util.MinNumber;
import com.volmit.iris.util.RegistryListLoot;
import com.volmit.iris.v2.scaffold.data.DataProvider;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -39,7 +40,7 @@ public class IrisLootReference
private final transient AtomicCache<KList<IrisLootTable>> tt = new AtomicCache<>();
public KList<IrisLootTable> getLootTables(DimensionalTerrainProvider g)
public KList<IrisLootTable> getLootTables(DataProvider g)
{
return tt.aquire(() ->
{

View File

@ -1,22 +1,35 @@
package com.volmit.iris.v2.generator;
import com.volmit.iris.Iris;
import com.volmit.iris.util.J;
import com.volmit.iris.util.M;
import com.volmit.iris.object.*;
import com.volmit.iris.util.*;
import com.volmit.iris.v2.scaffold.cache.Cache;
import com.volmit.iris.v2.scaffold.engine.Engine;
import com.volmit.iris.v2.scaffold.engine.EngineFramework;
import com.volmit.iris.v2.scaffold.engine.EngineTarget;
import com.volmit.iris.v2.scaffold.hunk.Hunk;
import com.volmit.iris.v2.scaffold.parallel.MultiBurst;
import io.papermc.lib.PaperLib;
import lombok.Getter;
import lombok.Setter;
import net.minecraft.server.v1_16_R2.*;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.generator.BlockPopulator;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Random;
public class IrisEngine implements Engine
public class IrisEngine extends BlockPopulator implements Engine
{
@Getter
private final EngineTarget target;
@ -28,15 +41,21 @@ public class IrisEngine implements Engine
@Getter
private volatile int parallelism;
@Setter
@Getter
private volatile int minHeight;
public IrisEngine(EngineTarget target)
{
Iris.info("Initializing Engine: " + target.getWorld().getName() + "/" + target.getDimension().getLoadKey() + " (" + target.getHeight() + " height)");
this.target = target;
this.framework = new IrisEngineFramework(this);
minHeight = 0;
}
@Override
public void generate(int x, int z, Hunk<BlockData> blocks, Hunk<Biome> biomes) {
public void generate(int x, int z, Hunk<BlockData> vblocks, Hunk<Biome> biomes) {
Hunk<BlockData> blocks = vblocks.listen(this::catchBlockUpdates);
getFramework().getEngineParallax().generateParallaxArea(x, z);
getFramework().getBiomeActuator().actuate(x, z, biomes);
getFramework().getTerrainActuator().actuate(x, z, blocks);
@ -47,4 +66,172 @@ public class IrisEngine implements Engine
getFramework().getEngineParallax().insertParallax(x, z, blocks);
getFramework().recycle();
}
private void catchBlockUpdates(int x, int y, int z, BlockData data) {
if(B.isUpdatable(data))
{
getParallax().updateBlock(x,y,z);
}
}
@Override
public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk c)
{
RNG rx = new RNG(Cache.key(c.getX(), c.getZ()));
getParallax().getUpdatesR(c.getX(), c.getZ()).iterate(0, (x,y,z) -> update(x, getMinHeight() + y, z, c, rx));
}
private 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);
block.setType(Material.AIR, false);
block.setBlockData(data, true);
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))
{
block.setType(Material.AIR, false);
block.setBlockData(data, true);
}
}
public 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);
}
public 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()));
}
public 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;
}
public 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);
}
}

View File

@ -20,6 +20,7 @@ import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.v1_16_R2.generator.CraftChunkData;
import org.bukkit.event.EventHandler;
import org.bukkit.event.world.WorldSaveEvent;
import org.bukkit.generator.BlockPopulator;
import java.io.File;
import java.util.concurrent.atomic.AtomicInteger;
@ -37,15 +38,20 @@ public class IrisEngineCompound implements EngineCompound {
@Getter
private final MultiBurst burster;
private IrisDimension root;
@Getter
private final KList<BlockPopulator> populators;
@Getter
private final IrisDimension rootDimension;
public IrisEngineCompound(World world, IrisDimension rootDimension, IrisDataManager data, int maximumThreads)
{
this.root = rootDimension;
this.rootDimension = rootDimension;
Iris.info("Initializing Engine Composite for " + world.getName());
this.world = world;
engineMetadata = EngineData.load(getEngineMetadataFile());
saveEngineMetadata();
populators = new KList<>();
if(rootDimension.getDimensionalComposite().isEmpty())
{
@ -70,11 +76,23 @@ public class IrisEngineCompound implements EngineCompound {
totalWeight += i.getWeight();
}
int buf = 0;
for(int i = 0; i < engines.length; i++)
{
IrisDimensionIndex index = rootDimension.getDimensionalComposite().get(i);
IrisDimension dimension = data.getDimensionLoader().load(index.getDimension());
engines[i] = new IrisEngine(new EngineTarget(world, dimension, data.copy().preferFolder(rootDimension.getLoadKey()), (int)Math.floor(256D * (index.getWeight() / totalWeight)), index.isInverted(), threadDist));
engines[i].setMinHeight(buf);
buf += engines[i].getHeight();
}
}
for(Engine i : engines)
{
if(i instanceof BlockPopulator)
{
populators.add((BlockPopulator) i);
}
}
@ -94,11 +112,6 @@ public class IrisEngineCompound implements EngineCompound {
return new File(world.getWorldFolder(), "iris/engine-metadata.json");
}
@Override
public IrisDimension getRootDimension() {
return root;
}
@Override
public void generate(int x, int z, Hunk<BlockData> blocks, Hunk<Biome> biomes)
{

View File

@ -19,6 +19,10 @@ public interface Engine
public EngineFramework getFramework();
public void setMinHeight(int min);
public int getMinHeight();
default void save()
{
getParallax().saveAll();

View File

@ -6,9 +6,10 @@ import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
import com.volmit.iris.gen.scaffold.TerrainChunk;
import com.volmit.iris.util.KList;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.WorldCreator;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData;
import org.bukkit.generator.BlockPopulator;
@ -29,6 +30,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements Hotloada
private final AtomicBoolean initialized;
private final String dimensionHint;
private final boolean production;
private final KList<BlockPopulator> populators;
public EngineCompositeGenerator() {
this(null, true);
@ -39,6 +41,18 @@ public class EngineCompositeGenerator extends ChunkGenerator implements Hotloada
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()
@ -106,6 +120,8 @@ public class EngineCompositeGenerator extends ChunkGenerator implements Hotloada
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) {
@ -138,7 +154,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements Hotloada
@NotNull
@Override
public List<BlockPopulator> getDefaultPopulators(@NotNull World world) {
return super.getDefaultPopulators(world);
return populators;
}
@Nullable

View File

@ -1,6 +1,7 @@
package com.volmit.iris.v2.scaffold.engine;
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;
@ -8,6 +9,7 @@ import org.bukkit.event.Listener;
import com.volmit.iris.v2.scaffold.hunk.Hunk;
import com.volmit.iris.v2.scaffold.parallel.MultiBurst;
import org.bukkit.generator.BlockPopulator;
public interface EngineCompound extends Listener
{
@ -27,6 +29,8 @@ public interface EngineCompound extends Listener
public void saveEngineMetadata();
public KList<BlockPopulator> getPopulators();
default Engine getEngineForHeight(int height)
{
if(getSize() == 1)

View File

@ -68,6 +68,11 @@ public interface Hunk<T>
return newCombinedArrayHunk(hunks);
}
default Hunk<T> listen(Consumer4<Integer, Integer, Integer, T> l)
{
return new ListeningHunk<>(this, l);
}
public static <T> Hunk<T> newArrayHunk(int w, int h, int d)
{
return new ArrayHunk<>(w, h, d);

View File

@ -0,0 +1,54 @@
package com.volmit.iris.v2.scaffold.hunk.view;
import com.volmit.iris.util.B;
import com.volmit.iris.util.Consumer4;
import com.volmit.iris.v2.scaffold.hunk.Hunk;
import org.checkerframework.checker.units.qual.A;
public class ListeningHunk<T> implements Hunk<T> {
private final Hunk<T> src;
private final Consumer4<Integer, Integer, Integer, T> listener;
public ListeningHunk(Hunk<T> src, Consumer4<Integer, Integer, Integer, T> listener)
{
this.src = src;
this.listener = listener;
}
@Override
public void setRaw(int x, int y, int z, T t)
{
listener.accept(x,y,z,t);
src.setRaw(x,y,z,t);
}
@Override
public T getRaw(int x, int y, int z)
{
return src.getRaw(x, y, z);
}
@Override
public int getWidth()
{
return src.getWidth();
}
@Override
public int getHeight()
{
return src.getHeight();
}
@Override
public int getDepth()
{
return src.getDepth();
}
@Override
public Hunk<T> getSource()
{
return src;
}
}