diff --git a/src/main/java/com/volmit/iris/core/commands/CommandFind.java b/src/main/java/com/volmit/iris/core/commands/CommandFind.java index fd1b146d3..1a461b8d4 100644 --- a/src/main/java/com/volmit/iris/core/commands/CommandFind.java +++ b/src/main/java/com/volmit/iris/core/commands/CommandFind.java @@ -28,6 +28,7 @@ import com.volmit.iris.util.decree.annotations.Decree; import com.volmit.iris.util.decree.annotations.Param; import com.volmit.iris.util.decree.specialhandlers.ObjectHandler; import com.volmit.iris.util.format.C; +import org.bukkit.generator.structure.StructureType; @Decree(name = "find", origin = DecreeOrigin.PLAYER, description = "Iris Find commands", aliases = "goto") public class CommandFind implements DecreeExecutor { @@ -76,6 +77,20 @@ public class CommandFind implements DecreeExecutor { e.gotoJigsaw(structure, player()); } + @Decree(description = "Find a point of interest.") + public void poi( + @Param(description = "The type of PoI to look for.") + String type + ) { + Engine e = engine(); + if(e == null) { + sender().sendMessage(C.GOLD + "Not in an Iris World!"); + return; + } + + e.gotoPOI(type, player()); + } + @Decree(description = "Find an object") public void object( @Param(description = "The object to look for", customHandler = ObjectHandler.class) diff --git a/src/main/java/com/volmit/iris/core/service/DolphinSVC.java b/src/main/java/com/volmit/iris/core/service/DolphinSVC.java index 093e410b2..ba5b625ca 100644 --- a/src/main/java/com/volmit/iris/core/service/DolphinSVC.java +++ b/src/main/java/com/volmit/iris/core/service/DolphinSVC.java @@ -18,14 +18,31 @@ package com.volmit.iris.core.service; +import com.volmit.iris.Iris; import com.volmit.iris.core.tools.IrisToolbelt; +import com.volmit.iris.engine.IrisEngine; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.util.documentation.ChunkCoordinates; +import com.volmit.iris.util.function.Consumer4; +import com.volmit.iris.util.math.Spiraler; +import com.volmit.iris.util.matter.MatterStructurePOI; import com.volmit.iris.util.plugin.IrisService; +import net.minecraft.core.BlockPos; import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.SoundCategory; +import org.bukkit.craftbukkit.v1_19_R1.entity.CraftDolphin; +import org.bukkit.entity.Dolphin; import org.bukkit.entity.EntityType; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.generator.structure.StructureType; + +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; public class DolphinSVC implements IrisService { + @Override public void onEnable() { @@ -36,10 +53,6 @@ public class DolphinSVC implements IrisService { } - /** - * Prevents dolphins from being fed, to locate a treasure map. - * Note: This results in odd dolphin behaviour, but it's the best we can do. - */ @EventHandler public void on(PlayerInteractEntityEvent event) { if(!IrisToolbelt.isIrisWorld(event.getPlayer().getWorld())) { @@ -48,7 +61,36 @@ public class DolphinSVC implements IrisService { Material hand = event.getPlayer().getInventory().getItem(event.getHand()).getType(); if(event.getRightClicked().getType().equals(EntityType.DOLPHIN) && (hand.equals(Material.TROPICAL_FISH) || hand.equals(Material.PUFFERFISH) || hand.equals(Material.COD) || hand.equals(Material.SALMON))) { - event.setCancelled(true); + Engine e = IrisToolbelt.access(event.getPlayer().getWorld()).getEngine(); + searchNearestTreasure(e, event.getPlayer().getLocation().getBlockX() >> 4, event.getPlayer().getLocation().getBlockZ() >> 4, e.getMantle().getRadius() - 1, StructureType.BURIED_TREASURE, (x, y, z, p) -> { + event.setCancelled(true); + Dolphin d = (Dolphin)event.getRightClicked(); + CraftDolphin cd = (CraftDolphin)d; + d.getWorld().playSound(d, Sound.ENTITY_DOLPHIN_EAT, SoundCategory.NEUTRAL, 1, 1); + cd.getHandle().setTreasurePos(new BlockPos(x, y, z)); + cd.getHandle().setGotFish(true); + }); + } } + + @ChunkCoordinates + public void findTreasure(Engine engine, int chunkX, int chunkY, StructureType type, Consumer4 consumer) { + AtomicReference ref = new AtomicReference<>(); + engine.getMantle().getMantle().iterateChunk(chunkX, chunkY, MatterStructurePOI.class, ref.get() == null ? (x, y, z, d) -> { + if(d.getType().equals(type.getKey().getKey())) { + ref.set(d); + consumer.accept(x, y, z, d); + } + } : (x, y, z, d) -> { }); + } + + @ChunkCoordinates + public void searchNearestTreasure(Engine engine, int chunkX, int chunkY, int radius, StructureType type, Consumer4 consumer) { + AtomicReference ref = new AtomicReference<>(); + new Spiraler(radius * 2, radius * 2, (x, z) -> findTreasure(engine, x, z, type, ref.get() == null ? (i, d, g, a) -> { + ref.set(a); + consumer.accept(i, d, g, a); + } : (i, d, g, a) -> { })).setOffset(chunkX, chunkY).drain(); + } } diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java index 9a2d78fba..97f1a71f2 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -25,6 +25,7 @@ import com.volmit.iris.core.ServerConfigurator; import com.volmit.iris.core.events.IrisEngineHotloadEvent; import com.volmit.iris.core.gui.PregeneratorJob; import com.volmit.iris.core.project.IrisProject; +import com.volmit.iris.core.service.DolphinSVC; import com.volmit.iris.core.service.PreservationSVC; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.*; @@ -43,22 +44,27 @@ import com.volmit.iris.util.io.IO; import com.volmit.iris.util.mantle.MantleFlag; import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.matter.MatterStructurePOI; import com.volmit.iris.util.scheduling.ChronoLatch; import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.PrecisionStopwatch; import lombok.Data; +import net.minecraft.core.BlockPos; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; import org.bukkit.command.CommandSender; +import oshi.util.tuples.Pair; import java.io.File; import java.io.IOException; +import java.util.HashSet; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; @Data public class IrisEngine implements Engine { @@ -191,6 +197,13 @@ public class IrisEngine implements Engine { return getMantle().getObjectComponent().guess(x, z); } + @Override + public Set> getPOIsAt(int chunkX, int chunkY) { + Set> pois = new HashSet<>(); + getMantle().getMantle().iterateChunk(chunkX, chunkY, MatterStructurePOI.class, (x, y, z, d) -> pois.add(new Pair<>(d.getType(), new BlockPos(x, y, z)))); + return pois; + } + @Override public IrisJigsawStructure getStructureAt(int x, int z) { return getMantle().getJigsawComponent().guess(x, z); 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 f2db7517f..e82ea5b6c 100644 --- a/src/main/java/com/volmit/iris/engine/framework/Engine.java +++ b/src/main/java/com/volmit/iris/engine/framework/Engine.java @@ -24,6 +24,7 @@ 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.core.service.DolphinSVC; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.engine.data.chunk.TerrainChunk; @@ -56,6 +57,7 @@ import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.PrecisionStopwatch; import com.volmit.iris.util.stream.ProceduralStream; import io.papermc.lib.PaperLib; +import net.minecraft.core.BlockPos; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.Location; @@ -66,9 +68,11 @@ 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.structure.StructureType; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; +import oshi.util.tuples.Pair; import java.awt.*; import java.util.Arrays; @@ -215,6 +219,9 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat @ChunkCoordinates Set getObjectsAt(int x, int z); + @ChunkCoordinates + Set> getPOIsAt(int x, int z); + @ChunkCoordinates IrisJigsawStructure getStructureAt(int x, int z); @@ -907,6 +914,10 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat Locator.region(r.getLoadKey()).find(player); } + default void gotoPOI(String type, Player p) { + Locator.poi(type).find(p); + } + default void cleanupMantleChunk(int x, int z) { if(IrisSettings.get().getPerformance().isTrimMantleInStudio() || !isStudio()) { J.a(() -> getMantle().cleanupChunk(x, z)); diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java index 36e9d9b1a..5ddb2d903 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java @@ -100,14 +100,17 @@ public abstract class EngineAssignedWorldManager extends EngineAssignedComponent @EventHandler public void onItemUse(PlayerInteractEvent e) { - if(e.getItem() == null || e.getHand() != EquipmentSlot.HAND) + if(e.getItem() == null || e.getHand() != EquipmentSlot.HAND) { return; - if(e.getAction() == Action.LEFT_CLICK_BLOCK || e.getAction() == Action.LEFT_CLICK_AIR) + } + if(e.getAction() == Action.LEFT_CLICK_BLOCK || e.getAction() == Action.LEFT_CLICK_AIR) { return; + } if(e.getPlayer().getWorld().equals(getTarget().getWorld().realWorld()) && e.getItem().getType() == Material.ENDER_EYE) { KList positions = getEngine().getDimension().getStrongholds(getEngine().getSeedManager().getSpawn()); - if(positions.isEmpty()) + if(positions.isEmpty()) { return; + } Position2 playerPos = new Position2(e.getPlayer().getLocation().getBlockX(), e.getPlayer().getLocation().getBlockZ()); Position2 pr = positions.get(0); diff --git a/src/main/java/com/volmit/iris/engine/framework/Locator.java b/src/main/java/com/volmit/iris/engine/framework/Locator.java index 339adc689..e023d6f01 100644 --- a/src/main/java/com/volmit/iris/engine/framework/Locator.java +++ b/src/main/java/com/volmit/iris/engine/framework/Locator.java @@ -36,9 +36,12 @@ 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 net.minecraft.core.BlockPos; import org.bukkit.Location; import org.bukkit.entity.Player; +import oshi.util.tuples.Pair; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; @@ -169,6 +172,13 @@ public interface Locator { return (e, c) -> e.getSurfaceBiome((c.getX() << 4) + 8, (c.getZ() << 4) + 8).getLoadKey().equals(loadKey); } + static Locator poi(String type) { + return (e, c) -> { + Set> pos = e.getPOIsAt((c.getX() << 4) + 8, (c.getZ() << 4) + 8); + return pos.stream().anyMatch(p -> p.getA().equals(type)); + }; + } + static Locator caveBiome(String loadKey) { return (e, c) -> e.getCaveBiome((c.getX() << 4) + 8, (c.getZ() << 4) + 8).getLoadKey().equals(loadKey); } diff --git a/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java b/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java index f58a48480..42f14af78 100644 --- a/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java +++ b/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java @@ -117,7 +117,7 @@ public class PlannedStructure { } int id = rng.i(0, Integer.MAX_VALUE); - vo.place(xx, height, zz, placer, options, rng, (b) -> e.set(b.getX(), b.getY(), b.getZ(), v.getLoadKey() + "@" + id), null, getData()); + vo.place(xx, height, zz, placer, options, rng, (b, data) -> e.set(b.getX(), b.getY(), b.getZ(), v.getLoadKey() + "@" + id), null, getData()); } public void place(World world) { @@ -210,10 +210,7 @@ public class PlannedStructure { return generateRotatedPiece(piece, pieceConnector, idea, IrisObjectRotation.of(x, y, z)); } - private boolean generatePositionedPiece(PlannedPiece piece, - IrisJigsawPieceConnector pieceConnector, - PlannedPiece test, - IrisJigsawPieceConnector testConnector) { + private boolean generatePositionedPiece(PlannedPiece piece, IrisJigsawPieceConnector pieceConnector, PlannedPiece test, IrisJigsawPieceConnector testConnector) { test.setPosition(new IrisPosition(0, 0, 0)); IrisPosition connector = piece.getWorldPosition(pieceConnector); IrisDirection desiredDirection = pieceConnector.getDirection().reverse(); diff --git a/src/main/java/com/volmit/iris/engine/mantle/components/MantleObjectComponent.java b/src/main/java/com/volmit/iris/engine/mantle/components/MantleObjectComponent.java index 851baca75..7e42f4fba 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/components/MantleObjectComponent.java +++ b/src/main/java/com/volmit/iris/engine/mantle/components/MantleObjectComponent.java @@ -29,10 +29,13 @@ import com.volmit.iris.engine.object.IrisObjectPlacement; import com.volmit.iris.engine.object.IrisRegion; import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.context.ChunkContext; +import com.volmit.iris.util.data.B; import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.mantle.MantleFlag; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.matter.MatterStructurePOI; +import com.volmit.iris.util.matter.slices.StructurePOIMatter; import java.util.Set; @@ -96,7 +99,12 @@ public class MantleObjectComponent extends IrisMantleComponent { int xx = rng.i(x, x + 15); int zz = rng.i(z, z + 15); int id = rng.i(0, Integer.MAX_VALUE); - v.place(xx, -1, zz, writer, objectPlacement, rng, (b) -> writer.setData(b.getX(), b.getY(), b.getZ(), v.getLoadKey() + "@" + id), null, getData()); + v.place(xx, -1, zz, writer, objectPlacement, rng, (b, data) -> { + writer.setData(b.getX(), b.getY(), b.getZ(), v.getLoadKey() + "@" + id); + if(objectPlacement.isDolphinTarget() && objectPlacement.isUnderwater() && B.isStorageChest(data)) { + writer.setData(b.getX(), b.getY(), b.getZ(), MatterStructurePOI.BURIED_TREASURE); + } + }, null, getData()); } } diff --git a/src/main/java/com/volmit/iris/engine/object/IrisObject.java b/src/main/java/com/volmit/iris/engine/object/IrisObject.java index d3c5c0b93..b206f3b94 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisObject.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisObject.java @@ -60,6 +60,7 @@ import org.bukkit.util.Vector; import java.io.*; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BiConsumer; import java.util.function.Consumer; @Accessors(chain = true) @@ -493,7 +494,7 @@ public class IrisObject extends IrisRegistrant { return place(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), placer, config, rng, rdata); } - public int place(int x, int yv, int z, IObjectPlacer oplacer, IrisObjectPlacement config, RNG rng, Consumer listener, CarveResult c, IrisData rdata) { + public int place(int x, int yv, int z, IObjectPlacer oplacer, IrisObjectPlacement config, RNG rng, BiConsumer listener, CarveResult c, IrisData rdata) { IObjectPlacer placer = (config.getHeightmap() != null) ? new HeightmapObjectPlacer(oplacer.getEngine() == null ? IrisContext.get().getEngine() : oplacer.getEngine(), rng, x, yv, z, config, oplacer) : oplacer; if(config.isSmartBore()) { @@ -795,6 +796,7 @@ public class IrisObject extends IrisRegistrant { } if((config.isWaterloggable() || config.isUnderwater()) && yy <= placer.getFluidHeight() && data instanceof Waterlogged) { + // TODO Here ((Waterlogged) data).setWaterlogged(true); } @@ -809,7 +811,7 @@ public class IrisObject extends IrisRegistrant { } if(listener != null) { - listener.accept(new BlockPosition(xx, yy, zz)); + listener.accept(new BlockPosition(xx, yy, zz), data); } if(markers != null && markers.containsKey(g)) { diff --git a/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java b/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java index 130cfd18f..547580103 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java @@ -60,6 +60,8 @@ public class IrisObjectPlacement { @MaxNumber(1) @Desc("The maximum layer level of a snow filter overtop of this placement. Set to 0 to disable. Max of 1.") private double snow = 0; + @Desc("Whether or not this object can be targeted by a dolphin.") + private boolean isDolphinTarget = false; @MinNumber(0) @MaxNumber(1) @Desc("The chance for this to place in a chunk. If you need multiple per chunk, set this to 1 and use density.") diff --git a/src/main/java/com/volmit/iris/util/matter/MatterStructurePOI.java b/src/main/java/com/volmit/iris/util/matter/MatterStructurePOI.java new file mode 100644 index 000000000..8c69d3f65 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/matter/MatterStructurePOI.java @@ -0,0 +1,24 @@ +package com.volmit.iris.util.matter; + +import lombok.Data; +import org.bukkit.generator.structure.StructureType; + +import java.util.Map; + +@Data +public class MatterStructurePOI { + + public static final MatterStructurePOI BURIED_TREASURE = new MatterStructurePOI("buried_treasure"); + + private static final MatterStructurePOI UNKNOWN = new MatterStructurePOI("unknown"); + private static final Map VALUES = Map.of( + "buried_treasure", BURIED_TREASURE + ); + + private final String type; + + public static MatterStructurePOI get(String id) { + MatterStructurePOI poi = VALUES.get(id); + return poi != null ? poi : new MatterStructurePOI(id); + } +} diff --git a/src/main/java/com/volmit/iris/util/matter/slices/StructurePOIMatter.java b/src/main/java/com/volmit/iris/util/matter/slices/StructurePOIMatter.java new file mode 100644 index 000000000..a91dc172d --- /dev/null +++ b/src/main/java/com/volmit/iris/util/matter/slices/StructurePOIMatter.java @@ -0,0 +1,30 @@ +package com.volmit.iris.util.matter.slices; + +import com.volmit.iris.util.data.palette.Palette; +import com.volmit.iris.util.matter.MatterStructurePOI; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class StructurePOIMatter extends RawMatter { + + public StructurePOIMatter() { + super(1, 1, 1, MatterStructurePOI.class); + } + + @Override + public Palette getGlobalPalette() { + return null; + } + + @Override + public void writeNode(MatterStructurePOI b, DataOutputStream dos) throws IOException { + dos.writeUTF(b.getType()); + } + + @Override + public MatterStructurePOI readNode(DataInputStream din) throws IOException { + return MatterStructurePOI.get(din.readUTF()); + } +}