This commit is contained in:
RePixelatedMC
2024-07-29 20:41:25 +02:00
42 changed files with 1525 additions and 316 deletions

View File

@@ -76,6 +76,7 @@ import java.util.zip.GZIPOutputStream;
@Decree(name = "Developer", origin = DecreeOrigin.BOTH, description = "Iris World Manager", aliases = {"dev"})
public class CommandDeveloper implements DecreeExecutor {
private CommandTurboPregen turboPregen;
private CommandUpdater updater;
@Decree(description = "Get Loaded TectonicPlates Count", origin = DecreeOrigin.BOTH, sync = true)
public void EngineStatus() {
@@ -164,18 +165,6 @@ public class CommandDeveloper implements DecreeExecutor {
}
@Decree(description = "Test")
public void updater(
@Param(description = "Updater for chunks")
World world
) {
Iris.info("test");
ChunkUpdater updater = new ChunkUpdater(world);
updater.start();
}
@Decree(description = "test")
public void mca (
@Param(description = "String") World world) {

View File

@@ -30,13 +30,13 @@ import com.volmit.iris.util.decree.annotations.Param;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form;
@Decree(name = "Updater", origin = DecreeOrigin.BOTH, description = "Iris World Updater")
@Decree(name = "updater", origin = DecreeOrigin.BOTH, description = "Iris World Updater")
public class CommandUpdater implements DecreeExecutor {
private ChunkUpdater chunkUpdater;
@Decree(description = "Updates all chunk in the specified world")
public void start(
@Param(description = "World to update chunks at")
@Param(description = "World to update chunks at", contextual = true)
World world
) {
if (!IrisToolbelt.isIrisWorld(world)) {

View File

@@ -2,6 +2,7 @@ package com.volmit.iris.core.link;
import com.volmit.iris.Iris;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.reflect.WrappedField;
import com.willfp.ecoitems.items.EcoItem;
import com.willfp.ecoitems.items.EcoItems;
@@ -33,12 +34,12 @@ public class EcoItemsDataProvider extends ExternalDataProvider {
}
@Override
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
public BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException {
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
}
@Override
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
public ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException {
EcoItem item = EcoItems.INSTANCE.getByID(itemId.key());
if (item == null) throw new MissingResourceException("Failed to find Item!", itemId.namespace(), itemId.key());
return itemStack.get(item).clone();

View File

@@ -3,6 +3,7 @@ package com.volmit.iris.core.link;
import com.ssomar.score.api.executableitems.ExecutableItemsAPI;
import com.volmit.iris.Iris;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import org.bukkit.block.data.BlockData;
import org.bukkit.inventory.ItemStack;
@@ -20,12 +21,12 @@ public class ExecutableItemsDataProvider extends ExternalDataProvider {
}
@Override
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
public BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException {
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
}
@Override
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
public ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException {
return ExecutableItemsAPI.getExecutableItemsManager().getExecutableItem(itemId.key())
.map(item -> item.buildItem(1, Optional.empty()))
.orElseThrow(() -> new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key()));

View File

@@ -1,6 +1,7 @@
package com.volmit.iris.core.link;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.util.collection.KMap;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.bukkit.Bukkit;
@@ -27,10 +28,19 @@ public abstract class ExternalDataProvider {
public abstract void init();
public abstract BlockData getBlockData(Identifier blockId) throws MissingResourceException;
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
return getBlockData(blockId, new KMap<>());
}
public abstract ItemStack getItemStack(Identifier itemId) throws MissingResourceException;
public void processUpdate(Engine engine, Block block, Identifier blockId) {};
public abstract BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException;
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
return getItemStack(itemId, new KMap<>());
}
public abstract ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException;
public void processUpdate(Engine engine, Block block, Identifier blockId) {}
public abstract Identifier[] getBlockTypes();

View File

@@ -2,8 +2,10 @@ package com.volmit.iris.core.link;
import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.service.ExternalDataSVC;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.data.IrisBlockData;
import com.volmit.iris.util.reflect.WrappedField;
import com.volmit.iris.util.reflect.WrappedReturningMethod;
@@ -50,7 +52,7 @@ public class HMCLeavesDataProvider extends ExternalDataProvider {
}
@Override
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
public BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException {
Object o = blockDataMap.get(blockId.key());
if (o == null)
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
@@ -60,11 +62,11 @@ public class HMCLeavesDataProvider extends ExternalDataProvider {
BlockData blockData = Bukkit.createBlockData(material);
if (IrisSettings.get().getGenerator().preventLeafDecay && blockData instanceof Leaves leaves)
leaves.setPersistent(true);
return new IrisBlockData(blockData, blockId);
return new IrisBlockData(blockData, ExternalDataSVC.buildState(blockId, state));
}
@Override
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
public ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException {
if (!itemDataField.containsKey(itemId.key()))
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
return itemDataField.get(itemId.key()).get();
@@ -72,6 +74,8 @@ public class HMCLeavesDataProvider extends ExternalDataProvider {
@Override
public void processUpdate(Engine engine, Block block, Identifier blockId) {
var pair = ExternalDataSVC.parseState(blockId);
blockId = pair.getA();
Boolean result = setCustomBlock.invoke(apiInstance, new Object[]{block.getLocation(), blockId.key(), false});
if (result == null || !result)
Iris.warn("Failed to set custom block! " + blockId.key() + " " + block.getX() + " " + block.getY() + " " + block.getZ());

View File

@@ -2,6 +2,7 @@ package com.volmit.iris.core.link;
import com.volmit.iris.Iris;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import dev.lone.itemsadder.api.CustomBlock;
import dev.lone.itemsadder.api.CustomStack;
import org.bukkit.block.data.BlockData;
@@ -32,12 +33,12 @@ public class ItemAdderDataProvider extends ExternalDataProvider {
}
@Override
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
public BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException {
return CustomBlock.getBaseBlockData(blockId.toString());
}
@Override
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
public ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException {
CustomStack stack = CustomStack.getInstance(itemId.toString());
if (stack == null) {
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());

View File

@@ -2,6 +2,7 @@ package com.volmit.iris.core.link;
import com.volmit.iris.Iris;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.scheduling.J;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.Type;
@@ -26,7 +27,7 @@ public class MMOItemsDataProvider extends ExternalDataProvider {
}
@Override
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
public BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException {
int id = -1;
try {
id = Integer.parseInt(blockId.key());
@@ -37,12 +38,33 @@ public class MMOItemsDataProvider extends ExternalDataProvider {
}
@Override
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
public ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException {
String[] parts = itemId.namespace().split("_", 2);
if (parts.length != 2)
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
CompletableFuture<ItemStack> future = new CompletableFuture<>();
Runnable run = () -> future.complete(api().getItem(parts[1], itemId.key()));
Runnable run = () -> {
try {
var type = api().getTypes().get(parts[1]);
int level = customNbt.containsKey("level") ? (int) customNbt.get("level") : -1;
var tier = api().getTiers().get(String.valueOf(customNbt.get("tier")));
ItemStack itemStack;
if (type == null) {
future.complete(null);
return;
}
if (level != -1 && tier != null) {
itemStack = api().getItem(type, itemId.key(), level, tier);
} else {
itemStack = api().getItem(type, itemId.key());
}
future.complete(itemStack);
} catch (Throwable e) {
future.completeExceptionally(e);
}
};
if (Bukkit.isPrimaryThread()) run.run();
else J.s(run);
ItemStack item = null;

View File

@@ -19,10 +19,16 @@
package com.volmit.iris.core.link;
import com.volmit.iris.Iris;
import com.volmit.iris.core.nms.INMS;
import com.volmit.iris.core.nms.container.BiomeColor;
import com.volmit.iris.core.service.ExternalDataSVC;
import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.data.B;
import com.volmit.iris.util.data.IrisBlockData;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.reflect.WrappedField;
import io.th0rgal.oraxen.api.OraxenItems;
import io.th0rgal.oraxen.items.ItemBuilder;
@@ -36,15 +42,22 @@ import io.th0rgal.oraxen.mechanics.provided.gameplay.furniture.FurnitureMechanic
import io.th0rgal.oraxen.mechanics.provided.gameplay.noteblock.NoteBlockMechanicFactory;
import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanicFactory;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.MultipleFacing;
import org.bukkit.entity.Entity;
import org.bukkit.entity.ItemDisplay;
import org.bukkit.entity.ItemFrame;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.PotionMeta;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Optional;
import java.util.function.Consumer;
public class OraxenDataProvider extends ExternalDataProvider {
@@ -66,7 +79,7 @@ public class OraxenDataProvider extends ExternalDataProvider {
}
@Override
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
public BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException {
MechanicFactory factory = getFactory(blockId);
if (factory instanceof NoteBlockMechanicFactory f)
return f.createNoteBlockData(blockId.key());
@@ -77,22 +90,71 @@ public class OraxenDataProvider extends ExternalDataProvider {
} else if (factory instanceof StringBlockMechanicFactory f) {
return f.createTripwireData(blockId.key());
} else if (factory instanceof FurnitureFactory) {
return new IrisBlockData(B.getAir(), blockId);
return new IrisBlockData(B.getAir(), ExternalDataSVC.buildState(blockId, state));
} else
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
}
@Override
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
public ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException {
Optional<ItemBuilder> opt = OraxenItems.getOptionalItemById(itemId.key());
return opt.orElseThrow(() -> new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key())).build();
}
@Override
public void processUpdate(Engine engine, Block block, Identifier blockId) {
var pair = ExternalDataSVC.parseState(blockId);
var state = pair.getB();
blockId = pair.getA();
Mechanic mechanic = getFactory(blockId).getMechanic(blockId.key());
if (mechanic instanceof FurnitureMechanic f) {
f.place(block.getLocation());
float yaw = 0;
BlockFace face = BlockFace.NORTH;
long seed = engine.getSeedManager().getSeed() + Cache.key(block.getX(), block.getZ()) + block.getY();
RNG rng = new RNG(seed);
if ("true".equals(state.get("randomYaw"))) {
yaw = rng.f(0, 360);
} else if (state.containsKey("yaw")) {
yaw = Float.parseFloat(state.get("yaw"));
}
if ("true".equals(state.get("randomFace"))) {
BlockFace[] faces = BlockFace.values();
face = faces[rng.i(0, faces.length - 1)];
} else if (state.containsKey("face")) {
face = BlockFace.valueOf(state.get("face").toUpperCase());
}
if (face == BlockFace.SELF) {
face = BlockFace.NORTH;
}
ItemStack itemStack = OraxenItems.getItemById(f.getItemID()).build();
Entity entity = f.place(block.getLocation(), itemStack, yaw, face, false);
Consumer<ItemStack> setter = null;
if (entity instanceof ItemFrame frame) {
itemStack = frame.getItem();
setter = frame::setItem;
} else if (entity instanceof ItemDisplay display) {
itemStack = display.getItemStack();
setter = display::setItemStack;
}
if (setter == null || itemStack == null) return;
BiomeColor type = null;
try {
type = BiomeColor.valueOf(state.get("matchBiome").toUpperCase());
} catch (NullPointerException | IllegalArgumentException ignored) {}
if (type != null) {
var biomeColor = INMS.get().getBiomeColor(block.getLocation(), type);
if (biomeColor == null) return;
var potionColor = Color.fromARGB(biomeColor.getAlpha(), biomeColor.getRed(), biomeColor.getGreen(), biomeColor.getBlue());
if (itemStack.getItemMeta() instanceof PotionMeta meta) {
meta.setColor(potionColor);
itemStack.setItemMeta(meta);
}
}
setter.accept(itemStack);
}
}

View File

@@ -1,12 +1,19 @@
package com.volmit.iris.core.link;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.util.data.Cuboid;
import com.volmit.iris.util.data.KCache;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.lang.reflect.InvocationTargetException;
import java.time.Duration;
import java.util.UUID;
public class WorldEditLink {
private static Boolean enabled = null;
private static final AtomicCache<Boolean> active = new AtomicCache<>();
public static Cuboid getSelection(Player p) {
if (!hasWorldEdit())
@@ -15,29 +22,38 @@ public class WorldEditLink {
try {
Object instance = Class.forName("com.sk89q.worldedit.WorldEdit").getDeclaredMethod("getInstance").invoke(null);
Object sessionManager = instance.getClass().getDeclaredMethod("getSessionManager").invoke(instance);
Object player = Class.forName("com.sk89q.worldedit.bukkit.BukkitAdapter").getDeclaredMethod("adapt", Player.class).invoke(null, p);
Class<?> bukkitAdapter = Class.forName("com.sk89q.worldedit.bukkit.BukkitAdapter");
Object world = bukkitAdapter.getDeclaredMethod("adapt", World.class).invoke(null, p.getWorld());
Object player = bukkitAdapter.getDeclaredMethod("adapt", Player.class).invoke(null, p);
Object localSession = sessionManager.getClass().getDeclaredMethod("getIfPresent", Class.forName("com.sk89q.worldedit.session.SessionOwner")).invoke(sessionManager, player);
Object world = Class.forName("com.sk89q.worldedit.bukkit.BukkitAdapter").getDeclaredMethod("adapt", World.class).invoke(null, p.getWorld());
Object region = localSession.getClass().getDeclaredMethod("getSelection", world.getClass()).invoke(localSession, world);
if (localSession == null) return null;
Object region = null;
try {
region = localSession.getClass().getDeclaredMethod("getSelection", Class.forName("com.sk89q.worldedit.world.World")).invoke(localSession, world);
} catch (InvocationTargetException ignored) {}
if (region == null) return null;
Object min = region.getClass().getDeclaredMethod("getMinimumPoint").invoke(region);
Object max = region.getClass().getDeclaredMethod("getMaximumPoint").invoke(region);
return new Cuboid(p.getWorld(),
(int) min.getClass().getDeclaredMethod("getX").invoke(min),
(int) min.getClass().getDeclaredMethod("getY").invoke(min),
(int) min.getClass().getDeclaredMethod("getZ").invoke(min),
(int) min.getClass().getDeclaredMethod("getX").invoke(max),
(int) min.getClass().getDeclaredMethod("getY").invoke(max),
(int) min.getClass().getDeclaredMethod("getZ").invoke(max)
(int) min.getClass().getDeclaredMethod("x").invoke(min),
(int) min.getClass().getDeclaredMethod("y").invoke(min),
(int) min.getClass().getDeclaredMethod("z").invoke(min),
(int) min.getClass().getDeclaredMethod("x").invoke(max),
(int) min.getClass().getDeclaredMethod("y").invoke(max),
(int) min.getClass().getDeclaredMethod("z").invoke(max)
);
} catch (Throwable ignored) {
} catch (Throwable e) {
Iris.error("Could not get selection");
e.printStackTrace();
active.reset();
active.aquire(() -> false);
}
return null;
}
public static boolean hasWorldEdit() {
if (enabled == null)
enabled = Bukkit.getPluginManager().isPluginEnabled("WorldEdit");
return enabled;
return active.aquire(() -> Bukkit.getPluginManager().isPluginEnabled("WorldEdit"));
}
}

View File

@@ -362,7 +362,12 @@ public class ResourceLoader<T extends IrisRegistrant> implements MeteredCache {
if (folderCache.get() == null) {
KList<File> fc = new KList<>();
for (File i : root.listFiles()) {
File[] files = root.listFiles();
if (files == null) {
throw new IllegalStateException("Failed to list files in " + root);
}
for (File i : files) {
if (i.isDirectory()) {
if (i.getName().equals(folderName)) {
fc.add(i);

View File

@@ -28,7 +28,8 @@ import java.util.Map;
public class INMS {
private static final Map<String, String> REVISION = Map.of(
"1.20.5", "v1_20_R4",
"1.20.6", "v1_20_R4"
"1.20.6", "v1_20_R4",
"1.21", "v1_21_R1"
);
//@done
private static final INMSBinding binding = bind();

View File

@@ -18,6 +18,7 @@
package com.volmit.iris.core.nms;
import com.volmit.iris.core.nms.container.BiomeColor;
import com.volmit.iris.core.nms.datapack.DataVersion;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.object.IrisBiomeCustom;
@@ -41,6 +42,8 @@ import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.inventory.ItemStack;
import java.awt.*;
public interface INMSBinding {
boolean hasTile(Location l);
@@ -114,6 +117,8 @@ public interface INMSBinding {
Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason);
Color getBiomeColor(Location location, BiomeColor type);
default DataVersion getDataVersion() {
return DataVersion.V1192;
}

View File

@@ -0,0 +1,10 @@
package com.volmit.iris.core.nms.container;
public enum BiomeColor {
FOG,
WATER,
WATER_FOG,
SKY,
FOLIAGE,
GRASS
}

View File

@@ -21,6 +21,7 @@ package com.volmit.iris.core.nms.v1X;
import com.google.common.base.Preconditions;
import com.volmit.iris.Iris;
import com.volmit.iris.core.nms.INMSBinding;
import com.volmit.iris.core.nms.container.BiomeColor;
import com.volmit.iris.core.nms.container.BlockPos;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.object.IrisBiomeCustom;
@@ -49,6 +50,8 @@ import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.inventory.ItemStack;
import java.awt.*;
import java.io.File;
public class NMSBinding1X implements INMSBinding {
@@ -118,6 +121,11 @@ public class NMSBinding1X implements INMSBinding {
return false;
}
@Override
public Color getBiomeColor(Location location, BiomeColor type) {
return Color.GREEN;
}
@Override
public void deserializeTile(CompoundTag s, Location newPosition) {

View File

@@ -20,8 +20,10 @@ package com.volmit.iris.core.service;
import com.volmit.iris.Iris;
import com.volmit.iris.core.link.*;
import com.volmit.iris.core.nms.container.Pair;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.plugin.IrisService;
import lombok.Data;
import org.bukkit.Bukkit;
@@ -31,8 +33,8 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.server.PluginEnableEvent;
import org.bukkit.inventory.ItemStack;
import java.util.MissingResourceException;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;
@Data
public class ExternalDataSVC implements IrisService {
@@ -93,26 +95,29 @@ public class ExternalDataSVC implements IrisService {
}
}
public Optional<BlockData> getBlockData(Identifier key) {
Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(key, false)).findFirst();
public Optional<BlockData> getBlockData(final Identifier key) {
var pair = parseState(key);
Identifier mod = pair.getA();
Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(mod, false)).findFirst();
if (provider.isEmpty())
return Optional.empty();
try {
return Optional.of(provider.get().getBlockData(key));
return Optional.of(provider.get().getBlockData(mod, pair.getB()));
} catch (MissingResourceException e) {
Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]");
return Optional.empty();
}
}
public Optional<ItemStack> getItemStack(Identifier key) {
public Optional<ItemStack> getItemStack(Identifier key, KMap<String, Object> customNbt) {
Optional<ExternalDataProvider> 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));
return Optional.of(provider.get().getItemStack(key, customNbt));
} catch (MissingResourceException e) {
Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]");
return Optional.empty();
@@ -139,4 +144,27 @@ public class ExternalDataSVC implements IrisService {
activeProviders.forEach(p -> names.add(p.getItemTypes()));
return names.toArray(new Identifier[0]);
}
public static Pair<Identifier, KMap<String, String>> parseState(Identifier key) {
if (!key.key().contains("[") || !key.key().contains("]")) {
return new Pair<>(key, new KMap<>());
}
String state = key.key().split("\\Q[\\E")[1].split("\\Q]\\E")[0];
KMap<String, String> stateMap = new KMap<>();
if (!state.isEmpty()) {
Arrays.stream(state.split(",")).forEach(s -> stateMap.put(s.split("=")[0], s.split("=")[1]));
}
return new Pair<>(new Identifier(key.namespace(), key.key().split("\\Q[\\E")[0]), stateMap);
}
public static Identifier buildState(Identifier key, KMap<String, String> state) {
if (state.isEmpty()) {
return key;
}
String path = state.entrySet()
.stream()
.map(e -> e.getKey() + "=" + e.getValue())
.collect(Collectors.joining(",", key.key() + "[", "]"));
return new Identifier(key.namespace(), path);
}
}

View File

@@ -240,7 +240,7 @@ public class TreeSVC implements IrisService {
boolean isUseAll = worldAccess.getEngine().getDimension().getTreeSettings().getMode().equals(IrisTreeModes.ALL);
// Retrieve objectPlacements of type `species` from biome
IrisBiome biome = worldAccess.getEngine().getBiome(location.getBlockX(), location.getBlockY(), location.getBlockZ());
IrisBiome biome = worldAccess.getEngine().getBiome(location.getBlockX(), location.getBlockY()-worldAccess.getTarget().getWorld().minHeight(), location.getBlockZ());
placements.addAll(matchObjectPlacements(biome.getObjects(), size, type));
// Add more or find any in the region

View File

@@ -318,7 +318,7 @@ public class WandSVC implements IrisService {
Vector gx = Vector.getRandom().subtract(Vector.getRandom()).normalize().clone().multiply(0.65);
d[0].getWorld().spawnParticle(CRIT_MAGIC, d[0], 1, 0.5 + gx.getX(), 0.5 + gx.getY(), 0.5 + gx.getZ(), 0, null, false);
Vector gxx = Vector.getRandom().subtract(Vector.getRandom()).normalize().clone().multiply(0.65);
d[1].getWorld().spawnParticle(Particle.CRIT, d[1], 1, 0.5 + gxx.getX(), 0.5 + gxx.getY(), 0.5 + gxx.getZ(), 0, null, false);
d[1].getWorld().spawnParticle(CRIT_MAGIC, d[1], 1, 0.5 + gxx.getX(), 0.5 + gxx.getY(), 0.5 + gxx.getZ(), 0, null, false);
if (!d[0].getWorld().equals(d[1].getWorld())) {
return;
@@ -388,7 +388,7 @@ public class WandSVC implements IrisService {
if (e.getHand() != EquipmentSlot.HAND)
return;
try {
if (isHoldingWand(e.getPlayer())) {
if (isHoldingIrisWand(e.getPlayer())) {
if (e.getAction().equals(Action.LEFT_CLICK_BLOCK)) {
e.setCancelled(true);
e.getPlayer().getInventory().setItemInMainHand(update(true, Objects.requireNonNull(e.getClickedBlock()).getLocation(), e.getPlayer().getInventory().getItemInMainHand()));

View File

@@ -124,6 +124,7 @@ public class IrisComplex implements DataProvider {
ProceduralStream.of((x, z) -> focusRegion,
Interpolated.of(a -> 0D, a -> focusRegion))
: regionStyleStream
.zoom(engine.getDimension().getRegionZoom())
.selectRarity(data.getRegionLoader().loadAll(engine.getDimension().getRegions()))
.cache2D("regionStream", engine, cacheSize).waste("Region Stream");
regionIDStream = regionIdentityStream.convertCached((i) -> new UUID(Double.doubleToLongBits(i),
@@ -131,6 +132,7 @@ public class IrisComplex implements DataProvider {
caveBiomeStream = regionStream.contextInjecting((c, x, z) -> IrisContext.getOr(engine).getChunkContext().getRegion().get(x, z))
.convert((r)
-> engine.getDimension().getCaveBiomeStyle().create(rng.nextParallelRNG(InferredType.CAVE.ordinal()), getData()).stream()
.zoom(engine.getDimension().getBiomeZoom())
.zoom(r.getCaveBiomeZoom())
.selectRarity(data.getBiomeLoader().loadAll(r.getCaveBiomes()))
.onNull(emptyBiome)
@@ -139,6 +141,8 @@ public class IrisComplex implements DataProvider {
landBiomeStream = regionStream.contextInjecting((c, x, z) -> IrisContext.getOr(engine).getChunkContext().getRegion().get(x, z))
.convert((r)
-> engine.getDimension().getLandBiomeStyle().create(rng.nextParallelRNG(InferredType.LAND.ordinal()), getData()).stream()
.zoom(engine.getDimension().getBiomeZoom())
.zoom(engine.getDimension().getLandZoom())
.zoom(r.getLandBiomeZoom())
.selectRarity(data.getBiomeLoader().loadAll(r.getLandBiomes(), (t) -> t.setInferredType(InferredType.LAND)))
).convertAware2D(ProceduralStream::get)
@@ -147,6 +151,8 @@ public class IrisComplex implements DataProvider {
seaBiomeStream = regionStream.contextInjecting((c, x, z) -> IrisContext.getOr(engine).getChunkContext().getRegion().get(x, z))
.convert((r)
-> engine.getDimension().getSeaBiomeStyle().create(rng.nextParallelRNG(InferredType.SEA.ordinal()), getData()).stream()
.zoom(engine.getDimension().getBiomeZoom())
.zoom(engine.getDimension().getSeaZoom())
.zoom(r.getSeaBiomeZoom())
.selectRarity(data.getBiomeLoader().loadAll(r.getSeaBiomes(), (t) -> t.setInferredType(InferredType.SEA)))
).convertAware2D(ProceduralStream::get)
@@ -155,6 +161,7 @@ public class IrisComplex implements DataProvider {
shoreBiomeStream = regionStream.contextInjecting((c, x, z) -> IrisContext.getOr(engine).getChunkContext().getRegion().get(x, z))
.convert((r)
-> engine.getDimension().getShoreBiomeStyle().create(rng.nextParallelRNG(InferredType.SHORE.ordinal()), getData()).stream()
.zoom(engine.getDimension().getBiomeZoom())
.zoom(r.getShoreBiomeZoom())
.selectRarity(data.getBiomeLoader().loadAll(r.getShoreBiomes(), (t) -> t.setInferredType(InferredType.SHORE)))
).convertAware2D(ProceduralStream::get).cache2D("shoreBiomeStream", engine, cacheSize).waste("Shore Biome Stream");

View File

@@ -39,6 +39,10 @@ public class IrisSeaFloorDecorator extends IrisEngineDecorator {
if (decorator != null) {
if (!decorator.isStacking()) {
if (!decorator.isForcePlace() && !decorator.getSlopeCondition().isDefault()
&& !decorator.getSlopeCondition().isValid(getComplex().getSlopeStream().get(realX, realZ))) {
return;
}
if (height >= 0 || height < getEngine().getHeight()) {
if (null != decorator.getBlockDataForTop(biome, getRng(), realX, height, realZ, getData())) {
if (height == getDimension().getFluidHeight() - 1) {

View File

@@ -45,6 +45,11 @@ public class IrisShoreLineDecorator extends IrisEngineDecorator {
IrisDecorator decorator = getDecorator(biome, realX, realZ);
if (decorator != null) {
if (!decorator.isForcePlace() && !decorator.getSlopeCondition().isDefault()
&& !decorator.getSlopeCondition().isValid(getComplex().getSlopeStream().get(realX, realZ))) {
return;
}
if (!decorator.isStacking()) {
if (null != decorator.getBlockDataForTop(biome, getRng(), realX, height, realZ, getData())) {
data.set(x, height, z, decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData()));

View File

@@ -53,6 +53,11 @@ public class IrisSurfaceDecorator extends IrisEngineDecorator {
boolean underwater = height < getDimension().getFluidHeight();
if (decorator != null) {
if (!decorator.isForcePlace() && !decorator.getSlopeCondition().isDefault()
&& !decorator.getSlopeCondition().isValid(getComplex().getSlopeStream().get(realX, realZ))) {
return;
}
if (!decorator.isStacking()) {
bd = decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData());

View File

@@ -269,77 +269,80 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
@ChunkCoordinates
@Override
default void updateChunk(Chunk c) {
if (c.getWorld().isChunkLoaded(c.getX() + 1, c.getZ() + 1)
&& c.getWorld().isChunkLoaded(c.getX(), c.getZ() + 1)
&& c.getWorld().isChunkLoaded(c.getX() + 1, c.getZ())
&& c.getWorld().isChunkLoaded(c.getX() - 1, c.getZ() - 1)
&& c.getWorld().isChunkLoaded(c.getX(), c.getZ() - 1)
&& c.getWorld().isChunkLoaded(c.getX() - 1, c.getZ())
&& c.getWorld().isChunkLoaded(c.getX() + 1, c.getZ() - 1)
&& c.getWorld().isChunkLoaded(c.getX() - 1, c.getZ() + 1) && getMantle().getMantle().isLoaded(c)) {
getMantle().getMantle().raiseFlag(c.getX(), c.getZ(), MantleFlag.TILE, () -> J.s(() -> {
getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), TileWrapper.class, (x, y, z, tile) -> {
int betterY = y + getWorld().minHeight();
if (!TileData.setTileState(c.getBlock(x, betterY, z), tile.getData()))
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, c.getBlock(x & 15, y + getWorld().minHeight(), z & 15), v);
});
}));
getMantle().getMantle().raiseFlag(c.getX(), c.getZ(), MantleFlag.UPDATE, () -> J.s(() -> {
PrecisionStopwatch p = PrecisionStopwatch.start();
KMap<Long, Integer> updates = new KMap<>();
RNG r = new RNG(Cache.key(c.getX(), c.getZ()));
getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), MatterCavern.class, (x, yf, z, v) -> {
int y = yf + getWorld().minHeight();
if (!B.isFluid(c.getBlock(x & 15, y, z & 15).getBlockData())) {
return;
}
boolean u = false;
if (B.isAir(c.getBlock(x & 15, y, z & 15).getRelative(BlockFace.DOWN).getBlockData())) {
u = true;
} else if (B.isAir(c.getBlock(x & 15, y, z & 15).getRelative(BlockFace.WEST).getBlockData())) {
u = true;
} else if (B.isAir(c.getBlock(x & 15, y, z & 15).getRelative(BlockFace.EAST).getBlockData())) {
u = true;
} else if (B.isAir(c.getBlock(x & 15, y, z & 15).getRelative(BlockFace.SOUTH).getBlockData())) {
u = true;
} else if (B.isAir(c.getBlock(x & 15, y, z & 15).getRelative(BlockFace.NORTH).getBlockData())) {
u = true;
}
if (u) {
updates.compute(Cache.key(x & 15, z & 15), (k, vv) -> {
if (vv != null) {
return Math.max(vv, y);
}
return y;
});
}
});
updates.forEach((k, v) -> update(Cache.keyX(k), v, Cache.keyZ(k), c, r));
getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), MatterUpdate.class, (x, yf, z, v) -> {
int y = yf + getWorld().minHeight();
if (v != null && v.isUpdate()) {
int vx = x & 15;
int vz = z & 15;
update(x, y, z, c, new RNG(Cache.key(c.getX(), c.getZ())));
if (vx > 0 && vx < 15 && vz > 0 && vz < 15) {
updateLighting(x, y, z, c);
}
}
});
getMantle().getMantle().deleteChunkSlice(c.getX(), c.getZ(), MatterUpdate.class);
getMetrics().getUpdates().put(p.getMilliseconds());
}, RNG.r.i(0, 20)));
for (int x = -1; x <= 1; x++) {
for (int z = -1; z <= 1; z++) {
if (c.getWorld().isChunkLoaded(c.getX() + x, c.getZ() + z))
continue;
Iris.debug("Chunk %s, %s [%s, %s] is not loaded".formatted(c.getX() + x, c.getZ() + z, x, z));
return;
}
}
if (!getMantle().getMantle().isLoaded(c)) {
Iris.debug("Mantle Chunk " + c.getX() + c.getX() + " is not loaded");
return;
}
getMantle().getMantle().raiseFlag(c.getX(), c.getZ(), MantleFlag.TILE, () -> J.s(() -> {
getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), TileWrapper.class, (x, y, z, tile) -> {
int betterY = y + getWorld().minHeight();
if (!TileData.setTileState(c.getBlock(x, betterY, z), tile.getData()))
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, c.getBlock(x & 15, y + getWorld().minHeight(), z & 15), v);
});
}));
getMantle().getMantle().raiseFlag(c.getX(), c.getZ(), MantleFlag.UPDATE, () -> J.s(() -> {
PrecisionStopwatch p = PrecisionStopwatch.start();
KMap<Long, Integer> updates = new KMap<>();
RNG r = new RNG(Cache.key(c.getX(), c.getZ()));
getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), MatterCavern.class, (x, yf, z, v) -> {
int y = yf + getWorld().minHeight();
if (!B.isFluid(c.getBlock(x & 15, y, z & 15).getBlockData())) {
return;
}
boolean u = false;
if (B.isAir(c.getBlock(x & 15, y, z & 15).getRelative(BlockFace.DOWN).getBlockData())) {
u = true;
} else if (B.isAir(c.getBlock(x & 15, y, z & 15).getRelative(BlockFace.WEST).getBlockData())) {
u = true;
} else if (B.isAir(c.getBlock(x & 15, y, z & 15).getRelative(BlockFace.EAST).getBlockData())) {
u = true;
} else if (B.isAir(c.getBlock(x & 15, y, z & 15).getRelative(BlockFace.SOUTH).getBlockData())) {
u = true;
} else if (B.isAir(c.getBlock(x & 15, y, z & 15).getRelative(BlockFace.NORTH).getBlockData())) {
u = true;
}
if (u) {
updates.compute(Cache.key(x & 15, z & 15), (k, vv) -> {
if (vv != null) {
return Math.max(vv, y);
}
return y;
});
}
});
updates.forEach((k, v) -> update(Cache.keyX(k), v, Cache.keyZ(k), c, r));
getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), MatterUpdate.class, (x, yf, z, v) -> {
int y = yf + getWorld().minHeight();
if (v != null && v.isUpdate()) {
int vx = x & 15;
int vz = z & 15;
update(x, y, z, c, new RNG(Cache.key(c.getX(), c.getZ())));
if (vx > 0 && vx < 15 && vz > 0 && vz < 15) {
updateLighting(x, y, z, c);
}
}
});
getMantle().getMantle().deleteChunkSlice(c.getX(), c.getZ(), MatterUpdate.class);
getMetrics().getUpdates().put(p.getMilliseconds());
}, RNG.r.i(0, 20)));
}
@BlockCoordinates

View File

@@ -25,6 +25,7 @@ import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.placer.WorldObjectPlacer;
import com.volmit.iris.engine.object.*;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.data.IrisBlockData;
import com.volmit.iris.util.mantle.Mantle;
import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.math.RNG;
@@ -149,6 +150,9 @@ public class PlannedStructure {
return v.place(xx, height, zz, placer, options, rng, (b, data) -> {
e.set(b.getX(), b.getY(), b.getZ(), v.getLoadKey() + "@" + id);
e.set(b.getX(), b.getY(), b.getZ(), container);
if (data instanceof IrisBlockData d) {
e.set(b.getX(), b.getY(), b.getZ(), d.getCustom());
}
}, null, getData().getEngine() != null ? getData() : eng.getData()) != -1;
}

View File

@@ -27,6 +27,7 @@ import com.volmit.iris.engine.object.*;
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.data.IrisBlockData;
import com.volmit.iris.util.documentation.BlockCoordinates;
import com.volmit.iris.util.documentation.ChunkCoordinates;
import com.volmit.iris.util.mantle.MantleFlag;
@@ -103,6 +104,9 @@ public class MantleObjectComponent extends IrisMantleComponent {
if (objectPlacement.isDolphinTarget() && objectPlacement.isUnderwater() && B.isStorageChest(data)) {
writer.setData(b.getX(), b.getY(), b.getZ(), MatterStructurePOI.BURIED_TREASURE);
}
if (data instanceof IrisBlockData d) {
writer.setData(b.getX(), b.getY(), b.getZ(), d.getCustom());
}
}, null, getData());
}
}

View File

@@ -55,6 +55,8 @@ public class IrisDecorator {
@ArrayType(min = 1, type = IrisBlockData.class)
@Desc("When set, the decorator will never place onto any of these blocks.")
private KList<IrisBlockData> blacklist;
@Desc("The slope at which this decorator can be placed. Range from 0 to 10 by default. Calculated from a 3-block radius from the center of the decorator placement.")
private IrisSlopeClip slopeCondition = new IrisSlopeClip();
@DependsOn({"scaleStack", "stackMin", "stackMax"})
@Desc("If stackMax is set to true, use this to limit its max height for large caverns")
private int absoluteMaxStack = 30;

View File

@@ -163,7 +163,7 @@ public class IrisDimension extends IrisRegistrant {
@MinNumber(0.0001)
@MaxNumber(512)
@Desc("Zoom in or out the biome size. Higher = bigger biomes")
private double biomeZoom = 5D;
private double biomeZoom = 1D;
@MinNumber(0)
@MaxNumber(360)
@Desc("You can rotate the input coordinates by an angle. This can make terrain appear more natural (less sharp corners and lines). This literally rotates the entire dimension by an angle. Hint: Try 12 degrees or something not on a 90 or 45 degree angle.")

View File

@@ -29,7 +29,6 @@ import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.data.B;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.json.JSONObject;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.noise.CNG;
import lombok.AllArgsConstructor;
@@ -146,7 +145,7 @@ public class IrisLoot {
// TODO Better Third Party Item Acquisition
private ItemStack getItemStack(RNG rng) {
if (!type.startsWith("minecraft:") && type.contains(":")) {
Optional<ItemStack> opt = Iris.service(ExternalDataSVC.class).getItemStack(Identifier.fromString(type));
Optional<ItemStack> opt = Iris.service(ExternalDataSVC.class).getItemStack(Identifier.fromString(type), customNbt);
if (opt.isEmpty()) {
Iris.warn("Unknown Material: " + type);
return new ItemStack(Material.AIR);

View File

@@ -59,6 +59,10 @@ public class IrisLootTable extends IrisRegistrant {
@Desc("The minimum amount of loot that can be picked in this table at a time.")
private int minPicked = 1;
@MinNumber(1)
@Desc("The maximum amount of tries to generate loot")
private int maxTries = 10;
@Desc("The loot in this table")
@ArrayType(min = 1, type = IrisLoot.class)
private KList<IrisLoot> loot = new KList<>();
@@ -67,9 +71,10 @@ public class IrisLootTable extends IrisRegistrant {
KList<ItemStack> lootf = new KList<>();
int m = 0;
int c = 0;
int mx = rng.i(getMinPicked(), getMaxPicked());
while (m < mx) {
while (m < mx && c++ < getMaxTries()) {
int num = rng.i(loot.size());
IrisLoot l = loot.get(num);