mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-12-28 03:29:06 +00:00
Hella nice goto
This commit is contained in:
@@ -47,7 +47,6 @@ 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;
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.gui.components.RenderType;
|
||||
import com.volmit.iris.core.gui.components.Renderer;
|
||||
import com.volmit.iris.core.loader.IrisData;
|
||||
import com.volmit.iris.core.loader.IrisRegistrant;
|
||||
import com.volmit.iris.engine.IrisComplex;
|
||||
import com.volmit.iris.engine.data.cache.Cache;
|
||||
import com.volmit.iris.engine.data.chunk.TerrainChunk;
|
||||
@@ -32,6 +33,7 @@ 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.IrisJigsawStructurePlacement;
|
||||
import com.volmit.iris.engine.object.IrisLootMode;
|
||||
import com.volmit.iris.engine.object.IrisLootReference;
|
||||
import com.volmit.iris.engine.object.IrisLootTable;
|
||||
@@ -46,8 +48,10 @@ import com.volmit.iris.util.collection.KMap;
|
||||
import com.volmit.iris.util.context.IrisContext;
|
||||
import com.volmit.iris.util.data.B;
|
||||
import com.volmit.iris.util.data.DataProvider;
|
||||
import com.volmit.iris.util.decree.handlers.JigsawStructureHandler;
|
||||
import com.volmit.iris.util.documentation.BlockCoordinates;
|
||||
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.function.Function2;
|
||||
import com.volmit.iris.util.hunk.Hunk;
|
||||
import com.volmit.iris.util.mantle.MantleFlag;
|
||||
@@ -72,6 +76,7 @@ import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
@@ -79,7 +84,6 @@ 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;
|
||||
@@ -87,6 +91,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdater, Renderer, Hotloadable {
|
||||
KList<EngineStage> getStages();
|
||||
@@ -780,4 +785,127 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
||||
default IrisBiome getBiomeOrMantle(Location l) {
|
||||
return getBiomeOrMantle(l.getBlockX(), l.getBlockY(), l.getBlockZ());
|
||||
}
|
||||
|
||||
default void gotoBiome(IrisBiome biome, Player player)
|
||||
{
|
||||
Set<String> regionKeys = getDimension()
|
||||
.getAllRegions(this).stream()
|
||||
.filter((i) -> i.getAllBiomes(this).contains(biome))
|
||||
.map(IrisRegistrant::getLoadKey)
|
||||
.collect(Collectors.toSet());
|
||||
Locator<IrisBiome> lb = Locator.surfaceBiome(biome.getLoadKey());
|
||||
Locator<IrisBiome> locator = (engine, chunk)
|
||||
-> regionKeys.contains(getRegion((chunk.getX()<< 4) + 8, (chunk.getZ() << 4) + 8).getLoadKey())
|
||||
&& lb.matches(engine, chunk);
|
||||
|
||||
if(!regionKeys.isEmpty())
|
||||
{
|
||||
locator.find(player);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
player.sendMessage(C.RED + biome.getName() + " is not in any defined regions!");
|
||||
}
|
||||
}
|
||||
|
||||
default void gotoJigsaw(IrisJigsawStructure s, Player player)
|
||||
{
|
||||
if(getDimension().getJigsawStructures().stream()
|
||||
.map(IrisJigsawStructurePlacement::getStructure)
|
||||
.collect(Collectors.toSet()).contains(s.getLoadKey()))
|
||||
{
|
||||
Locator.jigsawStructure(s.getLoadKey()).find(player);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
Set<String> biomeKeys = getDimension().getAllBiomes(this).stream()
|
||||
.filter((i) -> i.getJigsawStructures()
|
||||
.stream()
|
||||
.anyMatch((j) -> j.getStructure().equals(s.getLoadKey())))
|
||||
.map(IrisRegistrant::getLoadKey)
|
||||
.collect(Collectors.toSet());
|
||||
Set<String> regionKeys = getDimension().getAllRegions(this).stream()
|
||||
.filter((i) -> i.getAllBiomeIds().stream().anyMatch(biomeKeys::contains)
|
||||
|| i.getJigsawStructures()
|
||||
.stream()
|
||||
.anyMatch((j) -> j.getStructure().equals(s.getLoadKey())))
|
||||
.map(IrisRegistrant::getLoadKey)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
Locator<IrisJigsawStructure> sl = Locator.jigsawStructure(s.getLoadKey());
|
||||
Locator<IrisBiome> locator = (engine, chunk) -> {
|
||||
if(biomeKeys.contains(getSurfaceBiome((chunk.getX()<< 4) + 8, (chunk.getZ() << 4) + 8).getLoadKey()))
|
||||
{
|
||||
return sl.matches(engine, chunk);
|
||||
}
|
||||
|
||||
else if(regionKeys.contains(getRegion((chunk.getX()<< 4) + 8, (chunk.getZ() << 4) + 8).getLoadKey()))
|
||||
{
|
||||
return sl.matches(engine, chunk);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
if(!regionKeys.isEmpty())
|
||||
{
|
||||
locator.find(player);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
player.sendMessage(C.RED + s.getLoadKey() + " is not in any defined regions, biomes or dimensions!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
default void gotoObject(String s, Player player)
|
||||
{
|
||||
Set<String> biomeKeys = getDimension().getAllBiomes(this).stream()
|
||||
.filter((i) -> i.getObjects().stream().anyMatch((f) -> f.getPlace().contains(s)))
|
||||
.map(IrisRegistrant::getLoadKey)
|
||||
.collect(Collectors.toSet());
|
||||
Set<String> regionKeys = getDimension().getAllRegions(this).stream()
|
||||
.filter((i) -> i.getAllBiomeIds().stream().anyMatch(biomeKeys::contains)
|
||||
|| i.getObjects().stream().anyMatch((f) -> f.getPlace().contains(s)))
|
||||
.map(IrisRegistrant::getLoadKey)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
Locator<IrisObject> sl = Locator.object(s);
|
||||
Locator<IrisBiome> locator = (engine, chunk) -> {
|
||||
if(biomeKeys.contains(getSurfaceBiome((chunk.getX()<< 4) + 8, (chunk.getZ() << 4) + 8).getLoadKey()))
|
||||
{
|
||||
return sl.matches(engine, chunk);
|
||||
}
|
||||
|
||||
else if(regionKeys.contains(getRegion((chunk.getX()<< 4) + 8, (chunk.getZ() << 4) + 8).getLoadKey()))
|
||||
{
|
||||
return sl.matches(engine, chunk);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
if(!regionKeys.isEmpty())
|
||||
{
|
||||
locator.find(player);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
player.sendMessage(C.RED + s + " is not in any defined regions or biomes!");
|
||||
}
|
||||
}
|
||||
|
||||
default void gotoRegion(IrisRegion r, Player player)
|
||||
{
|
||||
if(!getDimension().getAllRegions(this).contains(r))
|
||||
{
|
||||
player.sendMessage(C.RED + r.getName() + " is not defined in the dimension!");
|
||||
return;
|
||||
}
|
||||
|
||||
Locator.region(r.getLoadKey()).find(player);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,52 +18,122 @@
|
||||
|
||||
package com.volmit.iris.engine.framework;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
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.engine.object.IrisObject;
|
||||
import com.volmit.iris.engine.object.IrisRegion;
|
||||
import com.volmit.iris.util.format.Form;
|
||||
import com.volmit.iris.util.math.M;
|
||||
import com.volmit.iris.util.math.Position2;
|
||||
import com.volmit.iris.util.math.Spiral;
|
||||
import com.volmit.iris.util.math.Spiraler;
|
||||
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.plugin.VolmitSender;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import com.volmit.iris.util.scheduling.jobs.SingleJob;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Locator<T> {
|
||||
boolean matches(Engine engine, Position2 chunk);
|
||||
|
||||
static void cancelSearch()
|
||||
{
|
||||
if(LocatorCanceller.cancel != null)
|
||||
{
|
||||
LocatorCanceller.cancel.run();
|
||||
LocatorCanceller.cancel = null;
|
||||
}
|
||||
}
|
||||
|
||||
default Future<Position2> find(Engine engine, Position2 pos, long timeout)
|
||||
default void find(Player player)
|
||||
{
|
||||
find(player, 30_000);
|
||||
}
|
||||
|
||||
default void find(Player player, long timeout)
|
||||
{
|
||||
AtomicLong checks = new AtomicLong();
|
||||
long ms = M.ms();
|
||||
new SingleJob("Searching", () -> {
|
||||
try {
|
||||
Position2 at = find(IrisToolbelt.access(player.getWorld()).getEngine(), new Position2(player.getLocation().getBlockX() >> 4, player.getLocation().getBlockZ() >> 4), timeout, checks::set).get();
|
||||
|
||||
if(at != null)
|
||||
{
|
||||
J.s(() -> player.teleport(new Location(player.getWorld(), (at.getX() << 4) + 8,
|
||||
IrisToolbelt.access(player.getWorld()).getEngine().getHeight(
|
||||
(at.getX() << 4) + 8,
|
||||
(at.getZ() << 4) + 8, false),
|
||||
(at.getZ() << 4) + 8)));
|
||||
}
|
||||
} catch (WrongEngineBroException | InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}){
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Searched " + Form.f(checks.get()) + " Chunks";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalWork() {
|
||||
return (int) timeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWorkCompleted() {
|
||||
return (int) Math.min(M.ms() - ms, timeout-1);
|
||||
}
|
||||
}.execute(new VolmitSender(player));
|
||||
}
|
||||
|
||||
default Future<Position2> find(Engine engine, Position2 pos, long timeout, Consumer<Integer> checks) throws WrongEngineBroException {
|
||||
if(engine.isClosed())
|
||||
{
|
||||
throw new WrongEngineBroException();
|
||||
}
|
||||
|
||||
cancelSearch();
|
||||
|
||||
return MultiBurst.burst.completeValue(() -> {
|
||||
int tc = IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getParallelism()) * 4;
|
||||
int tc = IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getParallelism()) * 17;
|
||||
MultiBurst burst = new MultiBurst("Iris Locator", Thread.MIN_PRIORITY);
|
||||
AtomicBoolean found = new AtomicBoolean(false);
|
||||
Position2 cursor = pos;
|
||||
AtomicInteger searched = new AtomicInteger();
|
||||
AtomicBoolean stop = new AtomicBoolean(false);
|
||||
AtomicReference<Position2> foundPos = new AtomicReference<>();
|
||||
PrecisionStopwatch px = PrecisionStopwatch.start();
|
||||
LocatorCanceller.cancel = () -> stop.set(true);
|
||||
|
||||
while(!found.get() || stop.get() || px.getMilliseconds() > timeout)
|
||||
AtomicReference<Position2> next = new AtomicReference<>(cursor);
|
||||
Spiraler s = new Spiraler(100000, 100000, (x, z) -> next.set(new Position2(x, z)));
|
||||
s.setOffset(cursor.getX(), cursor.getZ());
|
||||
s.next();
|
||||
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);
|
||||
|
||||
Position2 p = next.get();
|
||||
s.next();
|
||||
e.queue(() -> {
|
||||
if(matches(engine, p))
|
||||
{
|
||||
@@ -74,12 +144,15 @@ public interface Locator<T> {
|
||||
|
||||
found.set(true);
|
||||
}
|
||||
searched.incrementAndGet();
|
||||
});
|
||||
}
|
||||
|
||||
e.complete();
|
||||
checks.accept(searched.get());
|
||||
}
|
||||
|
||||
LocatorCanceller.cancel = null;
|
||||
burst.close();
|
||||
|
||||
if(found.get() && foundPos.get() != null)
|
||||
@@ -91,14 +164,12 @@ public interface Locator<T> {
|
||||
});
|
||||
}
|
||||
|
||||
boolean matches(Engine engine, Position2 chunk);
|
||||
|
||||
static Locator<IrisBiome> region(String loadKey)
|
||||
static Locator<IrisRegion> region(String loadKey)
|
||||
{
|
||||
return (e, c) -> e.getRegion((c.getX() << 4) + 8, (c.getZ() << 4) + 8).getLoadKey().equals(loadKey);
|
||||
}
|
||||
|
||||
static Locator<IrisBiome> jigsawStructure(String loadKey)
|
||||
static Locator<IrisJigsawStructure> jigsawStructure(String loadKey)
|
||||
{
|
||||
return (e, c) -> {
|
||||
IrisJigsawStructure s = e.getStructureAt(c.getX(), c.getZ());
|
||||
@@ -106,7 +177,7 @@ public interface Locator<T> {
|
||||
};
|
||||
}
|
||||
|
||||
static Locator<IrisBiome> object(String loadKey)
|
||||
static Locator<IrisObject> object(String loadKey)
|
||||
{
|
||||
return (e, c) -> e.getObjectsAt(c.getX(), c.getZ()).contains(loadKey);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user