From 65e3fdd26cf4067781d0a93d10fc2002f7aacf3b Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Thu, 7 Mar 2024 17:23:00 +0100 Subject: [PATCH] make implementing blocks that need world context possible --- .../iris/core/link/ExternalDataProvider.java | 3 + .../iris/core/service/ExternalDataSVC.java | 249 +++++++++--------- .../engine/data/chunk/LinkedTerrainChunk.java | 3 + .../engine/data/chunk/MCATerrainChunk.java | 3 + .../volmit/iris/engine/framework/Engine.java | 11 + .../volmit/iris/util/data/IrisBlockData.java | 127 +++++++++ .../util/hunk/view/ChunkDataHunkView.java | 4 +- .../volmit/iris/util/mantle/MantleFlag.java | 3 +- .../iris/util/matter/slices/BlockMatter.java | 7 +- .../util/matter/slices/IdentifierMatter.java | 36 +++ 10 files changed, 324 insertions(+), 122 deletions(-) create mode 100644 core/src/main/java/com/volmit/iris/util/data/IrisBlockData.java create mode 100644 core/src/main/java/com/volmit/iris/util/matter/slices/IdentifierMatter.java diff --git a/core/src/main/java/com/volmit/iris/core/link/ExternalDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/ExternalDataProvider.java index ee4d46bfc..b3104d2e5 100644 --- a/core/src/main/java/com/volmit/iris/core/link/ExternalDataProvider.java +++ b/core/src/main/java/com/volmit/iris/core/link/ExternalDataProvider.java @@ -1,8 +1,10 @@ package com.volmit.iris.core.link; +import com.volmit.iris.engine.framework.Engine; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.block.data.BlockData; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; @@ -28,6 +30,7 @@ public abstract class ExternalDataProvider { public abstract BlockData getBlockData(Identifier blockId) throws MissingResourceException; public abstract ItemStack getItemStack(Identifier itemId) throws MissingResourceException; + public void processUpdate(Engine engine, Location location, Identifier blockId) {}; public abstract Identifier[] getBlockTypes(); diff --git a/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java b/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java index de6d2ac81..a7136fe51 100644 --- a/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java @@ -1,119 +1,130 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2022 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.core.service; - -import com.volmit.iris.Iris; -import com.volmit.iris.core.link.*; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.plugin.IrisService; -import lombok.Data; -import org.bukkit.Bukkit; -import org.bukkit.block.data.BlockData; -import org.bukkit.event.EventHandler; -import org.bukkit.event.server.PluginEnableEvent; -import org.bukkit.inventory.ItemStack; - -import java.util.MissingResourceException; -import java.util.Optional; - -@Data -public class ExternalDataSVC implements IrisService { - - private KList providers = new KList<>(), activeProviders = new KList<>(); - - @Override - public void onEnable() { - Iris.info("Loading ExternalDataProvider..."); - Bukkit.getPluginManager().registerEvents(this, Iris.instance); - - providers.add(new OraxenDataProvider()); - if (Bukkit.getPluginManager().getPlugin("Oraxen") != null) { - Iris.info("Oraxen found, loading OraxenDataProvider..."); - } - providers.add(new ItemAdderDataProvider()); - if (Bukkit.getPluginManager().getPlugin("ItemAdder") != null) { - Iris.info("ItemAdder found, loading ItemAdderDataProvider..."); - } - providers.add(new ExecutableItemsDataProvider()); - if (Bukkit.getPluginManager().getPlugin("ExecutableItems") != null) { - Iris.info("ExecutableItems found, loading ExecutableItemsDataProvider..."); - } - - for (ExternalDataProvider p : providers) { - if (p.isReady()) { - activeProviders.add(p); - p.init(); - Iris.info("Enabled ExternalDataProvider for %s.", p.getPluginId()); - } - } - } - - @Override - public void onDisable() { - } - - @EventHandler - public void onPluginEnable(PluginEnableEvent e) { - if (activeProviders.stream().noneMatch(p -> p.getPlugin().equals(e.getPlugin()))) { - providers.stream().filter(p -> p.isReady() && p.getPlugin().equals(e.getPlugin())).findFirst().ifPresent(edp -> { - activeProviders.add(edp); - edp.init(); - Iris.info("Enabled ExternalDataProvider for %s.", edp.getPluginId()); - }); - } - } - - public Optional getBlockData(Identifier key) { - Optional provider = activeProviders.stream().filter(p -> p.isValidProvider(key, false)).findFirst(); - if (provider.isEmpty()) - return Optional.empty(); - try { - return Optional.of(provider.get().getBlockData(key)); - } catch (MissingResourceException e) { - Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]"); - return Optional.empty(); - } - } - - public Optional getItemStack(Identifier key) { - Optional provider = activeProviders.stream().filter(p -> p.isValidProvider(key, true)).findFirst(); - if (provider.isEmpty()) { - Iris.warn("No matching Provider found for modded material \"%s\"!", key); - return Optional.empty(); - } - try { - return Optional.of(provider.get().getItemStack(key)); - } catch (MissingResourceException e) { - Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]"); - return Optional.empty(); - } - } - - public Identifier[] getAllBlockIdentifiers() { - KList names = new KList<>(); - activeProviders.forEach(p -> names.add(p.getBlockTypes())); - return names.toArray(new Identifier[0]); - } - - public Identifier[] getAllItemIdentifiers() { - KList names = new KList<>(); - activeProviders.forEach(p -> names.add(p.getItemTypes())); - return names.toArray(new Identifier[0]); - } -} +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2022 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.core.service; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.link.*; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.plugin.IrisService; +import lombok.Data; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.block.data.BlockData; +import org.bukkit.event.EventHandler; +import org.bukkit.event.server.PluginEnableEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.MissingResourceException; +import java.util.Optional; + +@Data +public class ExternalDataSVC implements IrisService { + + private KList providers = new KList<>(), activeProviders = new KList<>(); + + @Override + public void onEnable() { + Iris.info("Loading ExternalDataProvider..."); + Bukkit.getPluginManager().registerEvents(this, Iris.instance); + + providers.add(new OraxenDataProvider()); + if (Bukkit.getPluginManager().getPlugin("Oraxen") != null) { + Iris.info("Oraxen found, loading OraxenDataProvider..."); + } + providers.add(new ItemAdderDataProvider()); + if (Bukkit.getPluginManager().getPlugin("ItemAdder") != null) { + Iris.info("ItemAdder found, loading ItemAdderDataProvider..."); + } + providers.add(new ExecutableItemsDataProvider()); + if (Bukkit.getPluginManager().getPlugin("ExecutableItems") != null) { + Iris.info("ExecutableItems found, loading ExecutableItemsDataProvider..."); + } + + for (ExternalDataProvider p : providers) { + if (p.isReady()) { + activeProviders.add(p); + p.init(); + Iris.info("Enabled ExternalDataProvider for %s.", p.getPluginId()); + } + } + } + + @Override + public void onDisable() { + } + + @EventHandler + public void onPluginEnable(PluginEnableEvent e) { + if (activeProviders.stream().noneMatch(p -> p.getPlugin().equals(e.getPlugin()))) { + providers.stream().filter(p -> p.isReady() && p.getPlugin().equals(e.getPlugin())).findFirst().ifPresent(edp -> { + activeProviders.add(edp); + edp.init(); + Iris.info("Enabled ExternalDataProvider for %s.", edp.getPluginId()); + }); + } + } + + public Optional getBlockData(Identifier key) { + Optional provider = activeProviders.stream().filter(p -> p.isValidProvider(key, false)).findFirst(); + if (provider.isEmpty()) + return Optional.empty(); + try { + return Optional.of(provider.get().getBlockData(key)); + } catch (MissingResourceException e) { + Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]"); + return Optional.empty(); + } + } + + public Optional getItemStack(Identifier key) { + Optional provider = activeProviders.stream().filter(p -> p.isValidProvider(key, true)).findFirst(); + if (provider.isEmpty()) { + Iris.warn("No matching Provider found for modded material \"%s\"!", key); + return Optional.empty(); + } + try { + return Optional.of(provider.get().getItemStack(key)); + } catch (MissingResourceException e) { + Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]"); + return Optional.empty(); + } + } + + public void processUpdate(Engine engine, Location location, Identifier blockId) { + Optional provider = activeProviders.stream().filter(p -> p.isValidProvider(blockId, true)).findFirst(); + if (provider.isEmpty()) { + Iris.warn("No matching Provider found for modded material \"%s\"!", blockId); + return; + } + provider.get().processUpdate(engine, location, blockId); + } + + public Identifier[] getAllBlockIdentifiers() { + KList names = new KList<>(); + activeProviders.forEach(p -> names.add(p.getBlockTypes())); + return names.toArray(new Identifier[0]); + } + + public Identifier[] getAllItemIdentifiers() { + KList names = new KList<>(); + activeProviders.forEach(p -> names.add(p.getItemTypes())); + return names.toArray(new Identifier[0]); + } +} diff --git a/core/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java b/core/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java index cbf18c1e6..015efd0e9 100644 --- a/core/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java +++ b/core/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java @@ -21,6 +21,7 @@ package com.volmit.iris.engine.data.chunk; import com.volmit.iris.core.nms.BiomeBaseInjector; import com.volmit.iris.core.nms.INMS; import com.volmit.iris.util.data.IrisBiomeStorage; +import com.volmit.iris.util.data.IrisBlockData; import lombok.Setter; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -120,6 +121,8 @@ public class LinkedTerrainChunk implements TerrainChunk { @Override public synchronized void setBlock(int x, int y, int z, BlockData blockData) { + if (blockData instanceof IrisBlockData d) + blockData = d.getBase(); rawChunkData.setBlock(x, y, z, blockData); } diff --git a/core/src/main/java/com/volmit/iris/engine/data/chunk/MCATerrainChunk.java b/core/src/main/java/com/volmit/iris/engine/data/chunk/MCATerrainChunk.java index 31b24a665..2da3db43a 100644 --- a/core/src/main/java/com/volmit/iris/engine/data/chunk/MCATerrainChunk.java +++ b/core/src/main/java/com/volmit/iris/engine/data/chunk/MCATerrainChunk.java @@ -20,6 +20,7 @@ package com.volmit.iris.engine.data.chunk; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.BiomeBaseInjector; +import com.volmit.iris.util.data.IrisBlockData; import com.volmit.iris.util.nbt.mca.Chunk; import com.volmit.iris.util.nbt.mca.NBTWorld; import lombok.AllArgsConstructor; @@ -88,6 +89,8 @@ public class MCATerrainChunk implements TerrainChunk { if (blockData == null) { Iris.error("NULL BD"); } + if (blockData instanceof IrisBlockData data) + blockData = data.getBase(); mcaChunk.setBlockStateAt(xx, y, zz, NBTWorld.getCompound(blockData), false); } diff --git a/core/src/main/java/com/volmit/iris/engine/framework/Engine.java b/core/src/main/java/com/volmit/iris/engine/framework/Engine.java index 4d57cdf83..d80b23d1b 100644 --- a/core/src/main/java/com/volmit/iris/engine/framework/Engine.java +++ b/core/src/main/java/com/volmit/iris/engine/framework/Engine.java @@ -22,10 +22,12 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.gui.components.RenderType; import com.volmit.iris.core.gui.components.Renderer; +import com.volmit.iris.core.link.Identifier; import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.core.nms.container.BlockPos; import com.volmit.iris.core.nms.container.Pair; +import com.volmit.iris.core.service.ExternalDataSVC; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.engine.data.chunk.TerrainChunk; @@ -38,6 +40,7 @@ import com.volmit.iris.util.context.ChunkContext; 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.data.IrisBlockData; import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.format.C; @@ -254,6 +257,9 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat if (B.isUpdatable(data)) { getMantle().updateBlock(x, y, z); } + if (data instanceof IrisBlockData d) { + getMantle().getMantle().set(x, y, z, d.getCustom()); + } } void blockUpdatedMetric(); @@ -277,6 +283,11 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat Iris.warn("Failed to set tile entity data at [%d %d %d | %s] for tile %s!", x, betterY, z, c.getBlock(x, betterY, z).getBlockData().getMaterial().getKey(), tile.getData().getTileId()); }); })); + getMantle().getMantle().raiseFlag(c.getX(), c.getZ(), MantleFlag.CUSTOM, () -> J.s(() -> { + getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), Identifier.class, (x, y, z, v) -> { + Iris.service(ExternalDataSVC.class).processUpdate(this, new Location(c.getWorld(), x, y + getWorld().minHeight(), z), v); + }); + })); getMantle().getMantle().raiseFlag(c.getX(), c.getZ(), MantleFlag.UPDATE, () -> J.s(() -> { PrecisionStopwatch p = PrecisionStopwatch.start(); diff --git a/core/src/main/java/com/volmit/iris/util/data/IrisBlockData.java b/core/src/main/java/com/volmit/iris/util/data/IrisBlockData.java new file mode 100644 index 000000000..dce36cd17 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/util/data/IrisBlockData.java @@ -0,0 +1,127 @@ +package com.volmit.iris.util.data; + +import com.volmit.iris.core.link.Identifier; +import lombok.Data; +import lombok.NonNull; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.SoundGroup; +import org.bukkit.block.*; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.structure.Mirror; +import org.bukkit.block.structure.StructureRotation; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Data +public class IrisBlockData implements BlockData{ + private final @NonNull BlockData base; + private final @NotNull Identifier custom; + + @NotNull + @Override + public Material getMaterial() { + return base.getMaterial(); + } + + @NotNull + @Override + public String getAsString() { + return base.getAsString(); + } + + @NotNull + @Override + public String getAsString(boolean b) { + return base.getAsString(b); + } + + @NotNull + @Override + public BlockData merge(@NotNull BlockData blockData) { + return new IrisBlockData(base.merge(blockData), custom); + } + + @Override + public boolean matches(@Nullable BlockData blockData) { + if (blockData instanceof IrisBlockData b) + return custom.equals(b.custom) && base.matches(b.base); + return base.matches(blockData); + } + + @NotNull + @Override + public BlockData clone() { + return new IrisBlockData(base.clone(), custom); + } + + @NotNull + @Override + public SoundGroup getSoundGroup() { + return base.getSoundGroup(); + } + + @Override + public int getLightEmission() { + return base.getLightEmission(); + } + + @Override + public boolean isOccluding() { + return base.isOccluding(); + } + + @Override + public boolean requiresCorrectToolForDrops() { + return base.requiresCorrectToolForDrops(); + } + + @Override + public boolean isPreferredTool(@NotNull ItemStack itemStack) { + return base.isPreferredTool(itemStack); + } + + @NotNull + @Override + public PistonMoveReaction getPistonMoveReaction() { + return base.getPistonMoveReaction(); + } + + @Override + public boolean isSupported(@NotNull Block block) { + return base.isSupported(block); + } + + @Override + public boolean isSupported(@NotNull Location location) { + return base.isSupported(location); + } + + @Override + public boolean isFaceSturdy(@NotNull BlockFace blockFace, @NotNull BlockSupport blockSupport) { + return base.isFaceSturdy(blockFace, blockSupport); + } + + @NotNull + @Override + public Material getPlacementMaterial() { + return base.getPlacementMaterial(); + } + + @Override + public void rotate(@NotNull StructureRotation structureRotation) { + base.rotate(structureRotation); + } + + @Override + public void mirror(@NotNull Mirror mirror) { + base.mirror(mirror); + } + + @NotNull + @Override + public BlockState createBlockState() { + return base.createBlockState(); + } +} diff --git a/core/src/main/java/com/volmit/iris/util/hunk/view/ChunkDataHunkView.java b/core/src/main/java/com/volmit/iris/util/hunk/view/ChunkDataHunkView.java index a9267f3fc..62cb7fc61 100644 --- a/core/src/main/java/com/volmit/iris/util/hunk/view/ChunkDataHunkView.java +++ b/core/src/main/java/com/volmit/iris/util/hunk/view/ChunkDataHunkView.java @@ -19,6 +19,7 @@ package com.volmit.iris.util.hunk.view; import com.volmit.iris.util.data.B; +import com.volmit.iris.util.data.IrisBlockData; import com.volmit.iris.util.hunk.Hunk; import org.bukkit.block.data.BlockData; import org.bukkit.generator.ChunkGenerator.ChunkData; @@ -72,7 +73,8 @@ public class ChunkDataHunkView implements Hunk { } try { - + if (t instanceof IrisBlockData d) + t = d.getBase(); chunk.setBlock(x, y + chunk.getMinHeight(), z, t); } catch (Throwable ignored) { diff --git a/core/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java b/core/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java index 03d98dee6..6bb5f1e6f 100644 --- a/core/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java +++ b/core/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java @@ -33,7 +33,8 @@ public enum MantleFlag { CLEANED, PLANNED, ETCHED, - TILE; + TILE, + CUSTOM; static StateList getStateList() { return new StateList(MantleFlag.values()); diff --git a/core/src/main/java/com/volmit/iris/util/matter/slices/BlockMatter.java b/core/src/main/java/com/volmit/iris/util/matter/slices/BlockMatter.java index 9a0de90ba..cf6eef776 100644 --- a/core/src/main/java/com/volmit/iris/util/matter/slices/BlockMatter.java +++ b/core/src/main/java/com/volmit/iris/util/matter/slices/BlockMatter.java @@ -18,6 +18,7 @@ package com.volmit.iris.util.matter.slices; +import com.volmit.iris.util.data.IrisBlockData; import com.volmit.iris.util.data.palette.Palette; import com.volmit.iris.util.matter.Sliced; import org.bukkit.Bukkit; @@ -39,7 +40,11 @@ public class BlockMatter extends RawMatter { public BlockMatter(int width, int height, int depth) { super(width, height, depth, BlockData.class); - registerWriter(World.class, ((w, d, x, y, z) -> w.getBlockAt(x, y, z).setBlockData(d))); + registerWriter(World.class, ((w, d, x, y, z) -> { + if (d instanceof IrisBlockData c) + w.getBlockAt(x, y, z).setBlockData(c.getBase()); + else w.getBlockAt(x, y, z).setBlockData(d); + })); registerReader(World.class, (w, x, y, z) -> { BlockData d = w.getBlockAt(x, y, z).getBlockData(); return d.getMaterial().isAir() ? null : d; diff --git a/core/src/main/java/com/volmit/iris/util/matter/slices/IdentifierMatter.java b/core/src/main/java/com/volmit/iris/util/matter/slices/IdentifierMatter.java new file mode 100644 index 000000000..5777c6320 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/util/matter/slices/IdentifierMatter.java @@ -0,0 +1,36 @@ +package com.volmit.iris.util.matter.slices; + +import com.volmit.iris.core.link.Identifier; +import com.volmit.iris.util.data.palette.Palette; +import com.volmit.iris.util.matter.Sliced; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +@Sliced +public class IdentifierMatter extends RawMatter { + + public IdentifierMatter() { + this(1, 1, 1); + } + + public IdentifierMatter(int width, int height, int depth) { + super(width, height, depth, Identifier.class); + } + + @Override + public Palette getGlobalPalette() { + return null; + } + + @Override + public void writeNode(Identifier b, DataOutputStream dos) throws IOException { + dos.writeUTF(b.toString()); + } + + @Override + public Identifier readNode(DataInputStream din) throws IOException { + return Identifier.fromString(din.readUTF()); + } +}