diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java index ba2dc721a..d3c6ec44d 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -46,6 +46,8 @@ import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisBiomePaletteLayer; import com.volmit.iris.engine.object.IrisDecorator; import com.volmit.iris.engine.object.IrisEngineData; +import com.volmit.iris.engine.object.IrisJigsawStructure; +import com.volmit.iris.engine.object.IrisObject; import com.volmit.iris.engine.object.IrisObjectPlacement; import com.volmit.iris.engine.scripting.EngineExecutionEnvironment; import com.volmit.iris.util.atomics.AtomicRollingSequence; @@ -71,6 +73,7 @@ import org.bukkit.command.CommandSender; import java.io.File; import java.io.IOException; +import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; @@ -198,7 +201,7 @@ public class IrisEngine implements Engine { var perfection = new IrisPerfectionModifier(this); registerStage((x, z, k, p, m) -> warmupChunk(x>>4, z>>4)); - registerStage((x, z, k, p, m) -> getMantle().generateMatter(x >> 4, z >> 4, m)); + registerStage((x, z, k, p, m) -> generateMatter(x >> 4, z >> 4, m)); registerStage((x, z, k, p, m) -> terrain.actuate(x, z, k, m)); registerStage((x, z, k, p, m) -> biome.actuate(x, z, p, m)); registerStage((x, z, k, p, m) -> cave.modify(x >> 4, z >> 4, k, m)); @@ -210,6 +213,21 @@ public class IrisEngine implements Engine { registerStage((x, z, k, p, m) -> perfection.modify(x, z, k, m)); } + @Override + public void generateMatter(int x, int z, boolean multicore) { + getMantle().generateMatter(x, z, multicore); + } + + @Override + public Set getObjectsAt(int x, int z) { + return getMantle().getObjectComponent().guess(x, z); + } + + @Override + public IrisJigsawStructure getStructureAt(int x, int z) { + return getMantle().getJigsawComponent().guess(x, z); + } + private void warmupChunk(int x, int z) { for(int i = 0; i < 16; i++) { diff --git a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java index 5d83ed71d..2f5bbee11 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java @@ -29,6 +29,7 @@ import com.volmit.iris.engine.mantle.components.MantleJigsawComponent; import com.volmit.iris.engine.mantle.components.MantleObjectComponent; import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisDepositGenerator; +import com.volmit.iris.engine.object.IrisJigsawStructure; import com.volmit.iris.engine.object.IrisJigsawStructurePlacement; import com.volmit.iris.engine.object.IrisObject; import com.volmit.iris.engine.object.IrisObjectPlacement; @@ -55,6 +56,8 @@ public class IrisEngineMantle implements EngineMantle { private final KList components; private final int radius; private final AtomicCache radCache = new AtomicCache<>(); + private final MantleObjectComponent object; + private final MantleJigsawComponent jigsaw; public IrisEngineMantle(Engine engine) { this.engine = engine; @@ -63,8 +66,10 @@ public class IrisEngineMantle implements EngineMantle { components = new KList<>(); registerComponent(new MantleCarvingComponent(this)); registerComponent(new MantleFluidBodyComponent(this)); - registerComponent(new MantleJigsawComponent(this)); - registerComponent(new MantleObjectComponent(this)); + jigsaw = new MantleJigsawComponent(this); + registerComponent(jigsaw); + object = new MantleObjectComponent(this); + registerComponent(object); } @Override @@ -72,6 +77,16 @@ public class IrisEngineMantle implements EngineMantle { components.add(c); } + @Override + public MantleJigsawComponent getJigsawComponent() { + return jigsaw; + } + + @Override + public MantleObjectComponent getObjectComponent() { + return object; + } + private KList getAllRegions() { KList r = new KList<>(); diff --git a/src/main/java/com/volmit/iris/engine/framework/Engine.java b/src/main/java/com/volmit/iris/engine/framework/Engine.java index 22415e09d..a631c2ced 100644 --- a/src/main/java/com/volmit/iris/engine/framework/Engine.java +++ b/src/main/java/com/volmit/iris/engine/framework/Engine.java @@ -31,9 +31,11 @@ import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisColor; import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.engine.object.IrisEngineData; +import com.volmit.iris.engine.object.IrisJigsawStructure; import com.volmit.iris.engine.object.IrisLootMode; import com.volmit.iris.engine.object.IrisLootReference; import com.volmit.iris.engine.object.IrisLootTable; +import com.volmit.iris.engine.object.IrisObject; import com.volmit.iris.engine.object.IrisObjectPlacement; import com.volmit.iris.engine.object.IrisPosition; import com.volmit.iris.engine.object.IrisRegion; @@ -77,6 +79,8 @@ import org.bukkit.inventory.ItemStack; import java.awt.Color; import java.util.Arrays; +import java.util.List; +import java.util.Set; import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -196,6 +200,8 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat return getComplex().getRegionStream().get(x, z); } + void generateMatter(int x, int z, boolean multicore); + @BlockCoordinates default IrisBiome getCaveOrMantleBiome(int x, int y, int z) { MatterCavern m = getMantle().getMantle().get(x, y, z, MatterCavern.class); @@ -211,6 +217,12 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat return getCaveBiome(x, z); } + @ChunkCoordinates + Set getObjectsAt(int x, int z); + + @ChunkCoordinates + IrisJigsawStructure getStructureAt(int x, int z); + @BlockCoordinates default IrisBiome getCaveBiome(int x, int z) { return getComplex().getCaveBiomeStream().get(x, z); diff --git a/src/main/java/com/volmit/iris/engine/framework/Locator.java b/src/main/java/com/volmit/iris/engine/framework/Locator.java new file mode 100644 index 000000000..f285fccf6 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/framework/Locator.java @@ -0,0 +1,144 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.framework; + +import com.volmit.iris.core.IrisSettings; +import com.volmit.iris.engine.data.cache.AtomicCache; +import com.volmit.iris.engine.object.IrisBiome; +import com.volmit.iris.engine.object.IrisJigsawStructure; +import com.volmit.iris.util.math.Position2; +import com.volmit.iris.util.math.Spiral; +import com.volmit.iris.util.matter.MatterCavern; +import com.volmit.iris.util.parallel.BurstExecutor; +import com.volmit.iris.util.parallel.MultiBurst; +import com.volmit.iris.util.scheduling.PrecisionStopwatch; + +import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + +@FunctionalInterface +public interface Locator { + static void cancelSearch() + { + if(LocatorCanceller.cancel != null) + { + LocatorCanceller.cancel.run(); + } + } + + default Future find(Engine engine, Position2 pos, long timeout) + { + return MultiBurst.burst.completeValue(() -> { + int tc = IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getParallelism()) * 4; + MultiBurst burst = new MultiBurst("Iris Locator", Thread.MIN_PRIORITY); + AtomicBoolean found = new AtomicBoolean(false); + Position2 cursor = pos; + AtomicBoolean stop = new AtomicBoolean(false); + AtomicReference foundPos = new AtomicReference<>(); + PrecisionStopwatch px = PrecisionStopwatch.start(); + LocatorCanceller.cancel = () -> stop.set(true); + + while(!found.get() || stop.get() || px.getMilliseconds() > timeout) + { + BurstExecutor e = burst.burst(tc); + + for(int i = 0; i < tc; i++) + { + Position2 p = cursor; + cursor = Spiral.next(cursor); + + e.queue(() -> { + if(matches(engine, p)) + { + if(foundPos.get() == null) + { + foundPos.set(p); + } + + found.set(true); + } + }); + } + + e.complete(); + } + + burst.close(); + + if(found.get() && foundPos.get() != null) + { + return foundPos.get(); + } + + return null; + }); + } + + boolean matches(Engine engine, Position2 chunk); + + static Locator region(String loadKey) + { + return (e, c) -> e.getRegion((c.getX() << 4) + 8, (c.getZ() << 4) + 8).getLoadKey().equals(loadKey); + } + + static Locator jigsawStructure(String loadKey) + { + return (e, c) -> { + IrisJigsawStructure s = e.getStructureAt(c.getX(), c.getZ()); + return s != null && s.getLoadKey().equals(loadKey); + }; + } + + static Locator object(String loadKey) + { + return (e, c) -> e.getObjectsAt(c.getX(), c.getZ()).contains(loadKey); + } + + static Locator surfaceBiome(String loadKey) + { + return (e, c) -> e.getSurfaceBiome((c.getX() << 4) + 8, (c.getZ() << 4) + 8).getLoadKey().equals(loadKey); + } + + static Locator caveBiome(String loadKey) + { + return (e, c) -> e.getCaveBiome((c.getX() << 4) + 8, (c.getZ() << 4) + 8).getLoadKey().equals(loadKey); + } + + static Locator caveOrMantleBiome(String loadKey) + { + return (e, c) -> { + AtomicBoolean found = new AtomicBoolean(false); + e.generateMatter(c.getX(), c.getZ(), true); + e.getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), MatterCavern.class, (x,y,z,t) ->{ + if(found.get()) + { + return; + } + + if(t != null && t.getCustomBiome().equals(loadKey)) + { + found.set(true); + } + }); + + return found.get(); + }; + } +} diff --git a/src/main/java/com/volmit/iris/engine/framework/LocatorCanceller.java b/src/main/java/com/volmit/iris/engine/framework/LocatorCanceller.java new file mode 100644 index 000000000..b1a522d4c --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/framework/LocatorCanceller.java @@ -0,0 +1,23 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.framework; + +public class LocatorCanceller { + protected static Runnable cancel = null; +}