make implementing blocks that need world context possible

This commit is contained in:
CrazyDev22
2024-03-07 17:23:00 +01:00
parent 93c1265de9
commit 65e3fdd26c
10 changed files with 324 additions and 122 deletions
@@ -1,8 +1,10 @@
package com.volmit.iris.core.link; package com.volmit.iris.core.link;
import com.volmit.iris.engine.framework.Engine;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
@@ -28,6 +30,7 @@ public abstract class ExternalDataProvider {
public abstract BlockData getBlockData(Identifier blockId) throws MissingResourceException; public abstract BlockData getBlockData(Identifier blockId) throws MissingResourceException;
public abstract ItemStack getItemStack(Identifier itemId) throws MissingResourceException; public abstract ItemStack getItemStack(Identifier itemId) throws MissingResourceException;
public void processUpdate(Engine engine, Location location, Identifier blockId) {};
public abstract Identifier[] getBlockTypes(); public abstract Identifier[] getBlockTypes();
@@ -1,119 +1,130 @@
/* /*
* Iris is a World Generator for Minecraft Bukkit Servers * Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2022 Arcane Arts (Volmit Software) * Copyright (c) 2022 Arcane Arts (Volmit Software)
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.volmit.iris.core.service; package com.volmit.iris.core.service;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.link.*; import com.volmit.iris.core.link.*;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.util.plugin.IrisService; import com.volmit.iris.util.collection.KList;
import lombok.Data; import com.volmit.iris.util.plugin.IrisService;
import org.bukkit.Bukkit; import lombok.Data;
import org.bukkit.block.data.BlockData; import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler; import org.bukkit.Location;
import org.bukkit.event.server.PluginEnableEvent; import org.bukkit.block.data.BlockData;
import org.bukkit.inventory.ItemStack; import org.bukkit.event.EventHandler;
import org.bukkit.event.server.PluginEnableEvent;
import java.util.MissingResourceException; import org.bukkit.inventory.ItemStack;
import java.util.Optional;
import java.util.MissingResourceException;
@Data import java.util.Optional;
public class ExternalDataSVC implements IrisService {
@Data
private KList<ExternalDataProvider> providers = new KList<>(), activeProviders = new KList<>(); public class ExternalDataSVC implements IrisService {
@Override private KList<ExternalDataProvider> providers = new KList<>(), activeProviders = new KList<>();
public void onEnable() {
Iris.info("Loading ExternalDataProvider..."); @Override
Bukkit.getPluginManager().registerEvents(this, Iris.instance); public void onEnable() {
Iris.info("Loading ExternalDataProvider...");
providers.add(new OraxenDataProvider()); Bukkit.getPluginManager().registerEvents(this, Iris.instance);
if (Bukkit.getPluginManager().getPlugin("Oraxen") != null) {
Iris.info("Oraxen found, loading OraxenDataProvider..."); providers.add(new OraxenDataProvider());
} if (Bukkit.getPluginManager().getPlugin("Oraxen") != null) {
providers.add(new ItemAdderDataProvider()); Iris.info("Oraxen found, loading OraxenDataProvider...");
if (Bukkit.getPluginManager().getPlugin("ItemAdder") != null) { }
Iris.info("ItemAdder found, loading ItemAdderDataProvider..."); providers.add(new ItemAdderDataProvider());
} if (Bukkit.getPluginManager().getPlugin("ItemAdder") != null) {
providers.add(new ExecutableItemsDataProvider()); Iris.info("ItemAdder found, loading ItemAdderDataProvider...");
if (Bukkit.getPluginManager().getPlugin("ExecutableItems") != null) { }
Iris.info("ExecutableItems found, loading ExecutableItemsDataProvider..."); 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); for (ExternalDataProvider p : providers) {
p.init(); if (p.isReady()) {
Iris.info("Enabled ExternalDataProvider for %s.", p.getPluginId()); activeProviders.add(p);
} p.init();
} Iris.info("Enabled ExternalDataProvider for %s.", p.getPluginId());
} }
}
@Override }
public void onDisable() {
} @Override
public void onDisable() {
@EventHandler }
public void onPluginEnable(PluginEnableEvent e) {
if (activeProviders.stream().noneMatch(p -> p.getPlugin().equals(e.getPlugin()))) { @EventHandler
providers.stream().filter(p -> p.isReady() && p.getPlugin().equals(e.getPlugin())).findFirst().ifPresent(edp -> { public void onPluginEnable(PluginEnableEvent e) {
activeProviders.add(edp); if (activeProviders.stream().noneMatch(p -> p.getPlugin().equals(e.getPlugin()))) {
edp.init(); providers.stream().filter(p -> p.isReady() && p.getPlugin().equals(e.getPlugin())).findFirst().ifPresent(edp -> {
Iris.info("Enabled ExternalDataProvider for %s.", edp.getPluginId()); activeProviders.add(edp);
}); edp.init();
} Iris.info("Enabled ExternalDataProvider for %s.", edp.getPluginId());
} });
}
public Optional<BlockData> getBlockData(Identifier key) { }
Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(key, false)).findFirst();
if (provider.isEmpty()) public Optional<BlockData> getBlockData(Identifier key) {
return Optional.empty(); Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(key, false)).findFirst();
try { if (provider.isEmpty())
return Optional.of(provider.get().getBlockData(key)); return Optional.empty();
} catch (MissingResourceException e) { try {
Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]"); return Optional.of(provider.get().getBlockData(key));
return Optional.empty(); } catch (MissingResourceException e) {
} Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]");
} return Optional.empty();
}
public Optional<ItemStack> getItemStack(Identifier key) { }
Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(key, true)).findFirst();
if (provider.isEmpty()) { public Optional<ItemStack> getItemStack(Identifier key) {
Iris.warn("No matching Provider found for modded material \"%s\"!", key); Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(key, true)).findFirst();
return Optional.empty(); if (provider.isEmpty()) {
} Iris.warn("No matching Provider found for modded material \"%s\"!", key);
try { return Optional.empty();
return Optional.of(provider.get().getItemStack(key)); }
} catch (MissingResourceException e) { try {
Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]"); return Optional.of(provider.get().getItemStack(key));
return Optional.empty(); } catch (MissingResourceException e) {
} Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]");
} return Optional.empty();
}
public Identifier[] getAllBlockIdentifiers() { }
KList<Identifier> names = new KList<>();
activeProviders.forEach(p -> names.add(p.getBlockTypes())); public void processUpdate(Engine engine, Location location, Identifier blockId) {
return names.toArray(new Identifier[0]); Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(blockId, true)).findFirst();
} if (provider.isEmpty()) {
Iris.warn("No matching Provider found for modded material \"%s\"!", blockId);
public Identifier[] getAllItemIdentifiers() { return;
KList<Identifier> names = new KList<>(); }
activeProviders.forEach(p -> names.add(p.getItemTypes())); provider.get().processUpdate(engine, location, blockId);
return names.toArray(new Identifier[0]); }
}
} public Identifier[] getAllBlockIdentifiers() {
KList<Identifier> names = new KList<>();
activeProviders.forEach(p -> names.add(p.getBlockTypes()));
return names.toArray(new Identifier[0]);
}
public Identifier[] getAllItemIdentifiers() {
KList<Identifier> names = new KList<>();
activeProviders.forEach(p -> names.add(p.getItemTypes()));
return names.toArray(new Identifier[0]);
}
}
@@ -21,6 +21,7 @@ package com.volmit.iris.engine.data.chunk;
import com.volmit.iris.core.nms.BiomeBaseInjector; import com.volmit.iris.core.nms.BiomeBaseInjector;
import com.volmit.iris.core.nms.INMS; import com.volmit.iris.core.nms.INMS;
import com.volmit.iris.util.data.IrisBiomeStorage; import com.volmit.iris.util.data.IrisBiomeStorage;
import com.volmit.iris.util.data.IrisBlockData;
import lombok.Setter; import lombok.Setter;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
@@ -120,6 +121,8 @@ public class LinkedTerrainChunk implements TerrainChunk {
@Override @Override
public synchronized void setBlock(int x, int y, int z, BlockData blockData) { 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); rawChunkData.setBlock(x, y, z, blockData);
} }
@@ -20,6 +20,7 @@ package com.volmit.iris.engine.data.chunk;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.nms.BiomeBaseInjector; 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.Chunk;
import com.volmit.iris.util.nbt.mca.NBTWorld; import com.volmit.iris.util.nbt.mca.NBTWorld;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@@ -88,6 +89,8 @@ public class MCATerrainChunk implements TerrainChunk {
if (blockData == null) { if (blockData == null) {
Iris.error("NULL BD"); Iris.error("NULL BD");
} }
if (blockData instanceof IrisBlockData data)
blockData = data.getBase();
mcaChunk.setBlockStateAt(xx, y, zz, NBTWorld.getCompound(blockData), false); mcaChunk.setBlockStateAt(xx, y, zz, NBTWorld.getCompound(blockData), false);
} }
@@ -22,10 +22,12 @@ import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.gui.components.RenderType; import com.volmit.iris.core.gui.components.RenderType;
import com.volmit.iris.core.gui.components.Renderer; 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.IrisData;
import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.core.loader.IrisRegistrant;
import com.volmit.iris.core.nms.container.BlockPos; import com.volmit.iris.core.nms.container.BlockPos;
import com.volmit.iris.core.nms.container.Pair; 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.IrisComplex;
import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.engine.data.chunk.TerrainChunk; 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.context.IrisContext;
import com.volmit.iris.util.data.B; import com.volmit.iris.util.data.B;
import com.volmit.iris.util.data.DataProvider; 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.BlockCoordinates;
import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.documentation.ChunkCoordinates;
import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.C;
@@ -254,6 +257,9 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
if (B.isUpdatable(data)) { if (B.isUpdatable(data)) {
getMantle().updateBlock(x, y, z); getMantle().updateBlock(x, y, z);
} }
if (data instanceof IrisBlockData d) {
getMantle().getMantle().set(x, y, z, d.getCustom());
}
} }
void blockUpdatedMetric(); 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()); 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(() -> { getMantle().getMantle().raiseFlag(c.getX(), c.getZ(), MantleFlag.UPDATE, () -> J.s(() -> {
PrecisionStopwatch p = PrecisionStopwatch.start(); PrecisionStopwatch p = PrecisionStopwatch.start();
@@ -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();
}
}
@@ -19,6 +19,7 @@
package com.volmit.iris.util.hunk.view; package com.volmit.iris.util.hunk.view;
import com.volmit.iris.util.data.B; import com.volmit.iris.util.data.B;
import com.volmit.iris.util.data.IrisBlockData;
import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.hunk.Hunk;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.generator.ChunkGenerator.ChunkData; import org.bukkit.generator.ChunkGenerator.ChunkData;
@@ -72,7 +73,8 @@ public class ChunkDataHunkView implements Hunk<BlockData> {
} }
try { try {
if (t instanceof IrisBlockData d)
t = d.getBase();
chunk.setBlock(x, y + chunk.getMinHeight(), z, t); chunk.setBlock(x, y + chunk.getMinHeight(), z, t);
} catch (Throwable ignored) { } catch (Throwable ignored) {
@@ -33,7 +33,8 @@ public enum MantleFlag {
CLEANED, CLEANED,
PLANNED, PLANNED,
ETCHED, ETCHED,
TILE; TILE,
CUSTOM;
static StateList getStateList() { static StateList getStateList() {
return new StateList(MantleFlag.values()); return new StateList(MantleFlag.values());
@@ -18,6 +18,7 @@
package com.volmit.iris.util.matter.slices; 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.data.palette.Palette;
import com.volmit.iris.util.matter.Sliced; import com.volmit.iris.util.matter.Sliced;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@@ -39,7 +40,11 @@ public class BlockMatter extends RawMatter<BlockData> {
public BlockMatter(int width, int height, int depth) { public BlockMatter(int width, int height, int depth) {
super(width, height, depth, BlockData.class); 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) -> { registerReader(World.class, (w, x, y, z) -> {
BlockData d = w.getBlockAt(x, y, z).getBlockData(); BlockData d = w.getBlockAt(x, y, z).getBlockData();
return d.getMaterial().isAir() ? null : d; return d.getMaterial().isAir() ? null : d;
@@ -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<Identifier> {
public IdentifierMatter() {
this(1, 1, 1);
}
public IdentifierMatter(int width, int height, int depth) {
super(width, height, depth, Identifier.class);
}
@Override
public Palette<Identifier> 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());
}
}