mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-29 11:59:11 +00:00
Merge remote-tracking branch 'upstream/dev' into dev
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id("com.gradleup.shadow") version "9.0.0-beta13"
|
||||
id("com.gradleup.shadow") version "9.0.0-rc2"
|
||||
id("maven-publish")
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.momirealms.craftengine.core.attribute;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -72,7 +73,7 @@ public class AttributeModifier {
|
||||
}
|
||||
}
|
||||
|
||||
public record Display(AttributeModifier.Display.Type type, String value) {
|
||||
public record Display(AttributeModifier.Display.Type type, Component value) {
|
||||
|
||||
public enum Type {
|
||||
DEFAULT, HIDDEN, OVERRIDE
|
||||
|
||||
@@ -41,7 +41,25 @@ public final class BlockKeys {
|
||||
public static final Key COMMAND_BLOCK = Key.of("minecraft:command_block");
|
||||
public static final Key CHAIN_COMMAND_BLOCK = Key.of("minecraft:chain_command_block");
|
||||
public static final Key REPEATING_COMMAND_BLOCK = Key.of("minecraft:repeating_command_block");
|
||||
public static final Key JIGSAW = Key.of("minecraft:jigsaw");
|
||||
public static final Key STRUCTURE_BLOCK = Key.of("minecraft:structure_block");
|
||||
public static final Key TEST_INSTANCE_BLOCK = Key.of("minecraft:test_instance_block");
|
||||
public static final Key TEST_BLOCK = Key.of("minecraft:test_block");
|
||||
public static final Key LIGHT = Key.of("minecraft:light");
|
||||
public static final Key DECORATED_POT = Key.of("minecraft:decorated_pot");
|
||||
public static final Key FLOWER_POT = Key.of("minecraft:flower_pot");
|
||||
public static final Key CHISELED_BOOKSHELF = Key.of("minecraft:chiseled_bookshelf");
|
||||
public static final Key REDSTONE_ORE = Key.of("minecraft:redstone_ore");
|
||||
public static final Key DEEPSLATE_REDSTONE_ORE = Key.of("minecraft:deepslate_redstone_ore");
|
||||
public static final Key BEE_NEST = Key.of("minecraft:bee_nest");
|
||||
public static final Key BEEHIVE = Key.of("minecraft:beehive");
|
||||
public static final Key POWDER_SNOW = Key.of("minecraft:powder_snow");
|
||||
public static final Key COMPOSTER = Key.of("minecraft:composter");
|
||||
public static final Key CAULDRON = Key.of("minecraft:cauldron");
|
||||
public static final Key WATER_CAULDRON = Key.of("minecraft:water_cauldron");
|
||||
public static final Key LAVA_CAULDRON = Key.of("minecraft:lava_cauldron");
|
||||
public static final Key RESPAWN_ANCHOR = Key.of("minecraft:respawn_anchor");
|
||||
public static final Key LODESTONE = Key.of("minecraft:lodestone");
|
||||
|
||||
public static final Key CAKE = Key.of("minecraft:cake");
|
||||
public static final Key CANDLE_CAKE = Key.of("minecraft:candle_cake");
|
||||
@@ -158,6 +176,8 @@ public final class BlockKeys {
|
||||
public static final Key WAXED_OXIDIZED_COPPER_TRAPDOOR = Key.of("minecraft:waxed_oxidized_copper_trapdoor");
|
||||
public static final Key WAXED_WEATHERED_COPPER_TRAPDOOR = Key.of("minecraft:waxed_weathered_copper_trapdoor");
|
||||
|
||||
|
||||
|
||||
public static final Key OAK_FENCE_GATE = Key.of("minecraft:oak_fence_gate");
|
||||
public static final Key SPRUCE_FENCE_GATE = Key.of("minecraft:spruce_fence_gate");
|
||||
public static final Key BIRCH_FENCE_GATE = Key.of("minecraft:birch_fence_gate");
|
||||
|
||||
@@ -464,7 +464,7 @@ public class BlockSettings {
|
||||
LazyReference<Set<Key>> correctTools = LazyReference.lazyReference(() -> {
|
||||
Set<Key> ids = new HashSet<>();
|
||||
for (String tool : tools) {
|
||||
if (tool.charAt(0) == '#') ids.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(tool.substring(1))).stream().map(UniqueKey::key).toList());
|
||||
if (tool.charAt(0) == '#') ids.addAll(CraftEngine.instance().itemManager().itemIdsByTag(Key.of(tool.substring(1))).stream().map(UniqueKey::key).toList());
|
||||
else ids.add(Key.of(tool));
|
||||
}
|
||||
return ids;
|
||||
|
||||
@@ -9,7 +9,7 @@ import net.momirealms.craftengine.core.util.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class Properties {
|
||||
public final class Properties {
|
||||
public static final Key BOOLEAN = Key.of("craftengine:boolean");
|
||||
public static final Key INT = Key.of("craftengine:int");
|
||||
public static final Key STRING = Key.of("craftengine:string");
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
package net.momirealms.craftengine.core.entity;
|
||||
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
public class EntityTypeKeys {
|
||||
private EntityTypeKeys() {}
|
||||
|
||||
public static final Key BEE = Key.of("minecraft:bee");
|
||||
public static final Key FOX = Key.of("minecraft:fox");
|
||||
public static final Key FROG = Key.of("minecraft:frog");
|
||||
public static final Key PANDA = Key.of("minecraft:panda");
|
||||
public static final Key SHEEP = Key.of("minecraft:sheep");
|
||||
public static final Key BOGGED = Key.of("minecraft:bogged");
|
||||
public static final Key SNOW_GOLEM = Key.of("minecraft:snow_golem");
|
||||
public static final Key HOGLIN = Key.of("minecraft:hoglin");
|
||||
public static final Key OCELOT = Key.of("minecraft:ocelot");
|
||||
public static final Key RABBIT = Key.of("minecraft:rabbit");
|
||||
public static final Key TURTLE = Key.of("minecraft:turtle");
|
||||
public static final Key AXOLOTL = Key.of("minecraft:axolotl");
|
||||
public static final Key CHICKEN = Key.of("minecraft:chicken");
|
||||
public static final Key SNIFFER = Key.of("minecraft:sniffer");
|
||||
public static final Key ARMADILLO = Key.of("minecraft:armadillo");
|
||||
public static final Key COD = Key.of("minecraft:cod");
|
||||
public static final Key SALMON = Key.of("minecraft:salmon");
|
||||
public static final Key TROPICAL_FISH = Key.of("minecraft:tropical_fish");
|
||||
public static final Key PUFFERFISH = Key.of("minecraft:pufferfish");
|
||||
public static final Key TADPOLE = Key.of("minecraft:tadpole");
|
||||
public static final Key COW = Key.of("minecraft:cow");
|
||||
public static final Key MOOSHROOM = Key.of("minecraft:mooshroom");
|
||||
public static final Key GOAT = Key.of("minecraft:goat");
|
||||
public static final Key PIG = Key.of("minecraft:pig");
|
||||
public static final Key STRIDER = Key.of("minecraft:strider");
|
||||
public static final Key WOLF = Key.of("minecraft:wolf");
|
||||
public static final Key CAT = Key.of("minecraft:cat");
|
||||
public static final Key PARROT = Key.of("minecraft:parrot");
|
||||
|
||||
public static final Key HAPPY_GHAST = Key.of("minecraft:happy_ghast");
|
||||
public static final Key PIGLIN = Key.of("minecraft:piglin");
|
||||
public static final Key CREEPER = Key.of("minecraft:creeper");
|
||||
public static final Key ALLAY = Key.of("minecraft:allay");
|
||||
public static final Key HORSE = Key.of("minecraft:horse");
|
||||
public static final Key ZOMBIE_HORSE = Key.of("minecraft:zombie_horse");
|
||||
public static final Key SKELETON_HORSE = Key.of("minecraft:skeleton_horse");
|
||||
public static final Key DONKEY = Key.of("minecraft:donkey");
|
||||
public static final Key MULE = Key.of("minecraft:mule");
|
||||
public static final Key VILLAGER = Key.of("minecraft:villager");
|
||||
public static final Key WANDERING_TRADER = Key.of("minecraft:wandering_trader");
|
||||
public static final Key LLAMA = Key.of("minecraft:llama");
|
||||
public static final Key TRADER_LLAMA = Key.of("minecraft:trader_llama");
|
||||
public static final Key CAMEL = Key.of("minecraft:camel");
|
||||
public static final Key ITEM_FRAME = Key.of("minecraft:item_frame");
|
||||
public static final Key GLOW_ITEM_FRAME = Key.of("minecraft:glow_item_frame");
|
||||
public static final Key INTERACTION = Key.of("minecraft:interaction");
|
||||
|
||||
public static final Key BOAT = Key.of("minecraft:boat");
|
||||
public static final Key OAK_BOAT = Key.of("minecraft:oak_boat");
|
||||
public static final Key SPRUCE_BOAT = Key.of("minecraft:spruce_boat");
|
||||
public static final Key BIRCH_BOAT = Key.of("minecraft:birch_boat");
|
||||
public static final Key JUNGLE_BOAT = Key.of("minecraft:jungle_boat");
|
||||
public static final Key ACACIA_BOAT = Key.of("minecraft:acacia_boat");
|
||||
public static final Key DARK_OAK_BOAT = Key.of("minecraft:dark_oak_boat");
|
||||
public static final Key MANGROVE_BOAT = Key.of("minecraft:mangrove_boat");
|
||||
public static final Key CHERRY_BOAT = Key.of("minecraft:cherry_boat");
|
||||
public static final Key PALE_OAK_BOAT = Key.of("minecraft:pale_oak_boat");
|
||||
public static final Key BAMBOO_RAFT = Key.of("minecraft:bamboo_raft");
|
||||
|
||||
public static final Key CHEST_BOAT = Key.of("minecraft:chest_boat");
|
||||
public static final Key OAK_CHEST_BOAT = Key.of("minecraft:oak_chest_boat");
|
||||
public static final Key SPRUCE_CHEST_BOAT = Key.of("minecraft:spruce_chest_boat");
|
||||
public static final Key BIRCH_CHEST_BOAT = Key.of("minecraft:birch_chest_boat");
|
||||
public static final Key JUNGLE_CHEST_BOAT = Key.of("minecraft:jungle_chest_boat");
|
||||
public static final Key ACACIA_CHEST_BOAT = Key.of("minecraft:acacia_chest_boat");
|
||||
public static final Key DARK_OAK_CHEST_BOAT = Key.of("minecraft:dark_oak_chest_boat");
|
||||
public static final Key MANGROVE_CHEST_BOAT = Key.of("minecraft:mangrove_chest_boat");
|
||||
public static final Key CHERRY_CHEST_BOAT = Key.of("minecraft:cherry_chest_boat");
|
||||
public static final Key PALE_OAK_CHEST_BOAT = Key.of("minecraft:pale_oak_chest_boat");
|
||||
public static final Key BAMBOO_CHEST_RAFT = Key.of("minecraft:bamboo_chest_raft");
|
||||
|
||||
public static final Key MINECART = Key.of("minecraft:minecart");
|
||||
public static final Key CHEST_MINECART = Key.of("minecraft:chest_minecart");
|
||||
public static final Key FURNACE_MINECART = Key.of("minecraft:furnace_minecart");
|
||||
public static final Key HOPPER_MINECART = Key.of("minecraft:hopper_minecart");
|
||||
public static final Key COMMAND_BLOCK_MINECART = Key.of("minecraft:command_block_minecart");
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package net.momirealms.craftengine.core.entity.furniture;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.logger.Debugger;
|
||||
import net.momirealms.craftengine.core.util.Color;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.NBT;
|
||||
|
||||
@@ -49,8 +50,8 @@ public class FurnitureExtraData {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public Optional<Integer> dyedColor() {
|
||||
if (this.data.containsKey(DYED_COLOR)) return Optional.of(this.data.getInt(DYED_COLOR));
|
||||
public Optional<Color> dyedColor() {
|
||||
if (this.data.containsKey(DYED_COLOR)) return Optional.of(Color.fromDecimal(this.data.getInt(DYED_COLOR)));
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@@ -92,9 +93,9 @@ public class FurnitureExtraData {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder dyedColor(Integer color) {
|
||||
public Builder dyedColor(Color color) {
|
||||
if (color == null) return this;
|
||||
this.data.putInt(DYED_COLOR, color);
|
||||
this.data.putInt(DYED_COLOR, color.color());
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ public abstract class Player extends AbstractEntity implements NetWorkUser {
|
||||
|
||||
public abstract void sendPackets(List<Object> packet, boolean immediately);
|
||||
|
||||
public abstract void sendPackets(List<Object> packet, boolean immediately, Runnable sendListener);
|
||||
|
||||
public abstract float getDestroyProgress(Object blockState, BlockPos pos);
|
||||
|
||||
public abstract void setClientSideCanBreakBlock(boolean canBreak);
|
||||
@@ -68,6 +70,10 @@ public abstract class Player extends AbstractEntity implements NetWorkUser {
|
||||
|
||||
public abstract int lastSuccessfulInteractionTick();
|
||||
|
||||
public abstract void updateLastInteractEntityTick(@NotNull InteractionHand hand);
|
||||
|
||||
public abstract boolean lastInteractEntityCheck(@NotNull InteractionHand hand);
|
||||
|
||||
public abstract int gameTicks();
|
||||
|
||||
public abstract void swingHand(InteractionHand hand);
|
||||
|
||||
@@ -368,7 +368,13 @@ public abstract class AbstractFontManager implements FontManager {
|
||||
if (keywords.isEmpty()) {
|
||||
throw new LocalizedResourceConfigException("warning.config.emoji.missing_keywords", path, id);
|
||||
}
|
||||
String content = section.getOrDefault("content", "<arg:emoji>").toString();
|
||||
Object rawContent = section.getOrDefault("content", "<white><arg:emoji></white>");
|
||||
String content;
|
||||
if (rawContent instanceof List<?> list) {
|
||||
content = list.stream().map(Object::toString).collect(Collectors.joining());
|
||||
} else {
|
||||
content = rawContent.toString();
|
||||
}
|
||||
String image = null;
|
||||
if (section.containsKey("image")) {
|
||||
String rawImage = section.get("image").toString();
|
||||
|
||||
@@ -15,6 +15,7 @@ import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public abstract class AbstractCustomItem<I> implements CustomItem<I> {
|
||||
protected final boolean isVanillaItem;
|
||||
protected final UniqueKey id;
|
||||
protected final Key material;
|
||||
protected final Key clientBoundMaterial;
|
||||
@@ -25,12 +26,13 @@ public abstract class AbstractCustomItem<I> implements CustomItem<I> {
|
||||
protected final Map<EventTrigger, List<Function<PlayerOptionalContext>>> events;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public AbstractCustomItem(UniqueKey id, Key material, Key clientBoundMaterial,
|
||||
public AbstractCustomItem(boolean isVanillaItem, UniqueKey id, Key material, Key clientBoundMaterial,
|
||||
List<ItemBehavior> behaviors,
|
||||
List<ItemDataModifier<I>> modifiers,
|
||||
List<ItemDataModifier<I>> clientBoundModifiers,
|
||||
ItemSettings settings,
|
||||
Map<EventTrigger, List<Function<PlayerOptionalContext>>> events) {
|
||||
this.isVanillaItem = isVanillaItem;
|
||||
this.id = id;
|
||||
this.material = material;
|
||||
this.clientBoundMaterial = clientBoundMaterial;
|
||||
@@ -75,6 +77,11 @@ public abstract class AbstractCustomItem<I> implements CustomItem<I> {
|
||||
return this.modifiers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVanillaItem() {
|
||||
return isVanillaItem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasClientBoundDataModifier() {
|
||||
return this.clientBoundModifiers.length != 0;
|
||||
|
||||
@@ -2,15 +2,19 @@ package net.momirealms.craftengine.core.item;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.momirealms.craftengine.core.attribute.AttributeModifier;
|
||||
import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
|
||||
import net.momirealms.craftengine.core.item.data.Enchantment;
|
||||
import net.momirealms.craftengine.core.item.data.FireworkExplosion;
|
||||
import net.momirealms.craftengine.core.item.data.JukeboxPlayable;
|
||||
import net.momirealms.craftengine.core.item.data.Trim;
|
||||
import net.momirealms.craftengine.core.item.setting.EquipmentData;
|
||||
import net.momirealms.craftengine.core.util.Color;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -107,13 +111,13 @@ public class AbstractItem<W extends ItemWrapper<I>, I> implements Item<I> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> dyedColor(Integer data) {
|
||||
public Item<I> dyedColor(Color data) {
|
||||
this.factory.dyedColor(this.item, data);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> dyedColor() {
|
||||
public Optional<Color> dyedColor() {
|
||||
return this.factory.dyedColor(this.item);
|
||||
}
|
||||
|
||||
@@ -150,17 +154,17 @@ public class AbstractItem<W extends ItemWrapper<I>, I> implements Item<I> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key id() {
|
||||
public @NotNull Key id() {
|
||||
return this.factory.id(this.item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key vanillaId() {
|
||||
public @NotNull Key vanillaId() {
|
||||
return this.factory.vanillaId(this.item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UniqueKey recipeIngredientId() {
|
||||
public @Nullable UniqueKey recipeIngredientId() {
|
||||
return this.factory.recipeIngredientID(this.item);
|
||||
}
|
||||
|
||||
@@ -252,6 +256,12 @@ public class AbstractItem<W extends ItemWrapper<I>, I> implements Item<I> {
|
||||
return this.factory.loreComponent(this.item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> attributeModifiers(List<AttributeModifier> modifiers) {
|
||||
this.factory.attributeModifiers(this.item, modifiers);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> unbreakable(boolean unbreakable) {
|
||||
this.factory.unbreakable(this.item, unbreakable);
|
||||
@@ -433,8 +443,8 @@ public class AbstractItem<W extends ItemWrapper<I>, I> implements Item<I> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is(Key itemTag) {
|
||||
return this.factory.is(this.item, itemTag);
|
||||
public boolean hasItemTag(Key itemTag) {
|
||||
return this.factory.hasItemTag(this.item, itemTag);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,14 +2,10 @@ package net.momirealms.craftengine.core.item;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import net.momirealms.craftengine.core.attribute.AttributeModifier;
|
||||
import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
|
||||
import net.momirealms.craftengine.core.item.behavior.ItemBehaviors;
|
||||
import net.momirealms.craftengine.core.item.data.Enchantment;
|
||||
import net.momirealms.craftengine.core.item.data.JukeboxPlayable;
|
||||
import net.momirealms.craftengine.core.item.equipment.*;
|
||||
import net.momirealms.craftengine.core.item.modifier.*;
|
||||
import net.momirealms.craftengine.core.item.setting.EquipmentData;
|
||||
import net.momirealms.craftengine.core.pack.AbstractPackManager;
|
||||
import net.momirealms.craftengine.core.pack.LoadingSequence;
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
@@ -22,20 +18,18 @@ import net.momirealms.craftengine.core.pack.model.select.TrimMaterialSelectPrope
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||
import net.momirealms.craftengine.core.plugin.context.event.EventFunctions;
|
||||
import net.momirealms.craftengine.core.plugin.context.text.TextProvider;
|
||||
import net.momirealms.craftengine.core.plugin.context.text.TextProviders;
|
||||
import net.momirealms.craftengine.core.plugin.context.event.EventTrigger;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.plugin.locale.TranslationManager;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.incendo.cloud.type.Either;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public abstract class AbstractItemManager<I> extends AbstractModelGenerator implements ItemManager<I> {
|
||||
@@ -46,7 +40,6 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
||||
private final ItemParser itemParser;
|
||||
private final EquipmentParser equipmentParser;
|
||||
protected final Map<String, ExternalItemSource<I>> externalItemSources = new HashMap<>();
|
||||
protected final Map<String, Function<Object, ItemDataModifier<I>>> dataFunctions = new HashMap<>();
|
||||
protected final Map<Key, CustomItem<I>> customItems = new HashMap<>();
|
||||
protected final Map<Key, List<UniqueKey>> customItemTags = new HashMap<>();
|
||||
protected final Map<Key, Map<Integer, Key>> cmdConflictChecker = new HashMap<>();
|
||||
@@ -63,14 +56,7 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
||||
super(plugin);
|
||||
this.itemParser = new ItemParser();
|
||||
this.equipmentParser = new EquipmentParser();
|
||||
this.registerFunctions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerDataType(Function<Object, ItemDataModifier<I>> factory, String... alias) {
|
||||
for (String a : alias) {
|
||||
this.dataFunctions.put(a, factory);
|
||||
}
|
||||
ItemDataModifiers.init();
|
||||
}
|
||||
|
||||
protected static void registerVanillaItemExtraBehavior(ItemBehavior behavior, Key... items) {
|
||||
@@ -79,23 +65,23 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
||||
}
|
||||
}
|
||||
|
||||
protected void applyDataFunctions(Map<String, Object> dataSection, Consumer<ItemDataModifier<I>> consumer) {
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void applyDataModifiers(Map<String, Object> dataSection, Consumer<ItemDataModifier<I>> callback) {
|
||||
ExceptionCollector<LocalizedResourceConfigException> errorCollector = new ExceptionCollector<>();
|
||||
if (dataSection != null) {
|
||||
for (Map.Entry<String, Object> dataEntry : dataSection.entrySet()) {
|
||||
Optional.ofNullable(this.dataFunctions.get(dataEntry.getKey())).ifPresent(function -> {
|
||||
Object value = dataEntry.getValue();
|
||||
if (value == null) continue;
|
||||
Optional.ofNullable(BuiltInRegistries.ITEM_DATA_MODIFIER_FACTORY.getValue(Key.withDefaultNamespace(dataEntry.getKey(), Key.DEFAULT_NAMESPACE))).ifPresent(factory -> {
|
||||
try {
|
||||
consumer.accept(function.apply(dataEntry.getValue()));
|
||||
} catch (IllegalArgumentException e) {
|
||||
this.plugin.logger().warn("Invalid data format", e);
|
||||
callback.accept((ItemDataModifier<I>) factory.create(value));
|
||||
} catch (LocalizedResourceConfigException e) {
|
||||
errorCollector.add(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function<Object, ItemDataModifier<I>> getDataType(String key) {
|
||||
return this.dataFunctions.get(key);
|
||||
errorCollector.throwIfPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -151,43 +137,31 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
||||
Key id = customItem.id();
|
||||
if (this.customItems.containsKey(id)) return false;
|
||||
this.customItems.put(id, customItem);
|
||||
// cache command suggestions
|
||||
this.cachedSuggestions.add(Suggestion.suggestion(id.toString()));
|
||||
// totem animations
|
||||
if (VersionHelper.isOrAbove1_21_2()) {
|
||||
this.cachedTotemSuggestions.add(Suggestion.suggestion(id.toString()));
|
||||
} else if (customItem.material().equals(ItemKeys.TOTEM_OF_UNDYING)) {
|
||||
this.cachedTotemSuggestions.add(Suggestion.suggestion(id.toString()));
|
||||
}
|
||||
// tags
|
||||
Set<Key> tags = customItem.settings().tags();
|
||||
for (Key tag : tags) {
|
||||
this.customItemTags.computeIfAbsent(tag, k -> new ArrayList<>()).add(customItem.uniqueId());
|
||||
if (!customItem.isVanillaItem()) {
|
||||
// cache command suggestions
|
||||
this.cachedSuggestions.add(Suggestion.suggestion(id.toString()));
|
||||
// totem animations
|
||||
if (VersionHelper.isOrAbove1_21_2()) {
|
||||
this.cachedTotemSuggestions.add(Suggestion.suggestion(id.toString()));
|
||||
} else if (customItem.material().equals(ItemKeys.TOTEM_OF_UNDYING)) {
|
||||
this.cachedTotemSuggestions.add(Suggestion.suggestion(id.toString()));
|
||||
}
|
||||
// tags
|
||||
Set<Key> tags = customItem.settings().tags();
|
||||
for (Key tag : tags) {
|
||||
this.customItemTags.computeIfAbsent(tag, k -> new ArrayList<>()).add(customItem.uniqueId());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UniqueKey> tagToItems(Key tag) {
|
||||
List<UniqueKey> items = new ArrayList<>();
|
||||
List<UniqueKey> holders = VANILLA_ITEM_TAGS.get(tag);
|
||||
if (holders != null) {
|
||||
items.addAll(holders);
|
||||
}
|
||||
List<UniqueKey> customItems = this.customItemTags.get(tag);
|
||||
if (customItems != null) {
|
||||
items.addAll(customItems);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UniqueKey> tagToVanillaItems(Key tag) {
|
||||
public List<UniqueKey> vanillaItemIdsByTag(Key tag) {
|
||||
return Collections.unmodifiableList(VANILLA_ITEM_TAGS.getOrDefault(tag, List.of()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UniqueKey> tagToCustomItems(Key tag) {
|
||||
public List<UniqueKey> customItemIdsByTag(Key tag) {
|
||||
return Collections.unmodifiableList(this.customItemTags.getOrDefault(tag, List.of()));
|
||||
}
|
||||
|
||||
@@ -378,23 +352,63 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
||||
else itemBuilder.dataModifier(new ItemModelModifier<>(itemModelKey));
|
||||
}
|
||||
|
||||
// 对于不重要的配置,可以仅警告,不返回
|
||||
ExceptionCollector<LocalizedResourceConfigException> collector = new ExceptionCollector<>();
|
||||
|
||||
// 应用物品数据
|
||||
applyDataFunctions(MiscUtils.castToMap(section.get("data"), true), itemBuilder::dataModifier);
|
||||
applyDataFunctions(MiscUtils.castToMap(section.get("client-bound-data"), true), itemBuilder::clientBoundDataModifier);
|
||||
try {
|
||||
applyDataModifiers(MiscUtils.castToMap(section.get("data"), true), itemBuilder::dataModifier);
|
||||
} catch (LocalizedResourceConfigException e) {
|
||||
collector.add(e);
|
||||
}
|
||||
try {
|
||||
applyDataModifiers(MiscUtils.castToMap(section.get("client-bound-data"), true), itemBuilder::clientBoundDataModifier);
|
||||
} catch (LocalizedResourceConfigException e) {
|
||||
collector.add(e);
|
||||
}
|
||||
|
||||
// 如果不是原版物品,那么加入ce的标识符
|
||||
if (!isVanillaItem)
|
||||
itemBuilder.dataModifier(new IdModifier<>(id));
|
||||
|
||||
// 事件
|
||||
Map<EventTrigger, List<net.momirealms.craftengine.core.plugin.context.function.Function<PlayerOptionalContext>>> eventTriggerListMap;
|
||||
try {
|
||||
eventTriggerListMap = EventFunctions.parseEvents(ResourceConfigUtils.get(section, "events", "event"));
|
||||
} catch (LocalizedResourceConfigException e) {
|
||||
collector.add(e);
|
||||
eventTriggerListMap = Map.of();
|
||||
}
|
||||
|
||||
// 设置
|
||||
ItemSettings settings;
|
||||
try {
|
||||
settings = Optional.ofNullable(ResourceConfigUtils.get(section, "settings"))
|
||||
.map(map -> ItemSettings.fromMap(MiscUtils.castToMap(map, true)))
|
||||
.map(it -> isVanillaItem ? it.canPlaceRelatedVanillaBlock(true) : it)
|
||||
.orElse(ItemSettings.of().canPlaceRelatedVanillaBlock(isVanillaItem));
|
||||
} catch (LocalizedResourceConfigException e) {
|
||||
collector.add(e);
|
||||
settings = ItemSettings.of().canPlaceRelatedVanillaBlock(isVanillaItem);
|
||||
}
|
||||
|
||||
// 行为
|
||||
List<ItemBehavior> behaviors;
|
||||
try {
|
||||
behaviors = ItemBehaviors.fromObj(pack, path, id, ResourceConfigUtils.get(section, "behavior", "behaviors"));
|
||||
} catch (LocalizedResourceConfigException e) {
|
||||
collector.add(e);
|
||||
behaviors = Collections.emptyList();
|
||||
}
|
||||
|
||||
// 构建自定义物品
|
||||
CustomItem<I> customItem = itemBuilder
|
||||
.behaviors(ItemBehaviors.fromObj(pack, path, id, ResourceConfigUtils.get(section, "behavior", "behaviors")))
|
||||
.settings(Optional.ofNullable(ResourceConfigUtils.get(section, "settings"))
|
||||
.map(map -> ItemSettings.fromMap(MiscUtils.castToMap(map, true)))
|
||||
.map(it -> isVanillaItem ? it.canPlaceRelatedVanillaBlock(true) : it)
|
||||
.orElse(ItemSettings.of().canPlaceRelatedVanillaBlock(isVanillaItem)))
|
||||
.events(EventFunctions.parseEvents(ResourceConfigUtils.get(section, "events", "event")))
|
||||
.isVanillaItem(isVanillaItem)
|
||||
.behaviors(behaviors)
|
||||
.settings(settings)
|
||||
.events(eventTriggerListMap)
|
||||
.build();
|
||||
|
||||
// 添加到缓存
|
||||
addCustomItem(customItem);
|
||||
|
||||
@@ -407,6 +421,7 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
||||
Map<String, Object> modelSection = MiscUtils.castToMap(section.get("model"), true);
|
||||
Map<String, Object> legacyModelSection = MiscUtils.castToMap(section.get("legacy-model"), true);
|
||||
if (modelSection == null && legacyModelSection == null) {
|
||||
collector.throwIfPresent();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -415,39 +430,47 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
||||
if (!isVanillaItem) {
|
||||
// 既没有模型值也没有item-model
|
||||
if (customModelData == 0 && itemModelKey == null) {
|
||||
throw new LocalizedResourceConfigException("warning.config.item.missing_model_id");
|
||||
collector.addAndThrow(new LocalizedResourceConfigException("warning.config.item.missing_model_id"));
|
||||
}
|
||||
}
|
||||
|
||||
// 1.21.4+必须要配置model区域,如果不需要高版本兼容,则可以只写legacy-model
|
||||
if (needsModelSection && modelSection == null) {
|
||||
throw new LocalizedResourceConfigException("warning.config.item.missing_model");
|
||||
}
|
||||
|
||||
// 新版格式
|
||||
ItemModel modernModel = null;
|
||||
// 旧版格式
|
||||
TreeSet<LegacyOverridesModel> legacyOverridesModels = null;
|
||||
// 如果需要支持新版item model 或者用户需要旧版本兼容,但是没配置legacy-model
|
||||
if (needsModelSection) {
|
||||
modernModel = ItemModels.fromMap(modelSection);
|
||||
for (ModelGeneration generation : modernModel.modelsToGenerate()) {
|
||||
prepareModelGeneration(generation);
|
||||
// 1.21.4+必须要配置model区域,如果不需要高版本兼容,则可以只写legacy-model
|
||||
if (modelSection == null) {
|
||||
collector.addAndThrow(new LocalizedResourceConfigException("warning.config.item.missing_model"));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
modernModel = ItemModels.fromMap(modelSection);
|
||||
for (ModelGeneration generation : modernModel.modelsToGenerate()) {
|
||||
prepareModelGeneration(generation);
|
||||
}
|
||||
} catch (LocalizedResourceConfigException e) {
|
||||
collector.addAndThrow(e);
|
||||
}
|
||||
}
|
||||
// 如果需要旧版本兼容
|
||||
if (needsLegacyCompatibility()) {
|
||||
if (legacyModelSection != null) {
|
||||
LegacyItemModel legacyItemModel = LegacyItemModel.fromMap(legacyModelSection, customModelData);
|
||||
for (ModelGeneration generation : legacyItemModel.modelsToGenerate()) {
|
||||
prepareModelGeneration(generation);
|
||||
try {
|
||||
LegacyItemModel legacyItemModel = LegacyItemModel.fromMap(legacyModelSection, customModelData);
|
||||
for (ModelGeneration generation : legacyItemModel.modelsToGenerate()) {
|
||||
prepareModelGeneration(generation);
|
||||
}
|
||||
legacyOverridesModels = new TreeSet<>(legacyItemModel.overrides());
|
||||
} catch (LocalizedResourceConfigException e) {
|
||||
collector.addAndThrow(e);
|
||||
}
|
||||
legacyOverridesModels = new TreeSet<>(legacyItemModel.overrides());
|
||||
} else {
|
||||
legacyOverridesModels = new TreeSet<>();
|
||||
processModelRecursively(modernModel, new LinkedHashMap<>(), legacyOverridesModels, clientBoundMaterial, customModelData);
|
||||
if (legacyOverridesModels.isEmpty()) {
|
||||
TranslationManager.instance().log("warning.config.item.legacy_model.cannot_convert", path.toString(), id.asString());
|
||||
collector.add(new LocalizedResourceConfigException("warning.config.item.legacy_model.cannot_convert", path.toString(), id.asString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -463,7 +486,7 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
||||
// 检查cmd冲突
|
||||
Map<Integer, Key> conflict = AbstractItemManager.this.cmdConflictChecker.computeIfAbsent(finalBaseModel, k -> new HashMap<>());
|
||||
if (conflict.containsKey(customModelData)) {
|
||||
throw new LocalizedResourceConfigException("warning.config.item.custom_model_data_conflict", String.valueOf(customModelData), conflict.get(customModelData).toString());
|
||||
collector.addAndThrow(new LocalizedResourceConfigException("warning.config.item.custom_model_data_conflict", String.valueOf(customModelData), conflict.get(customModelData).toString()));
|
||||
}
|
||||
conflict.put(customModelData, id);
|
||||
// 添加新版item model
|
||||
@@ -481,7 +504,7 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
||||
lom.addAll(legacyOverridesModels);
|
||||
}
|
||||
} else if (isVanillaItemModel) {
|
||||
throw new LocalizedResourceConfigException("warning.config.item.item_model.conflict", itemModelKey.asString());
|
||||
collector.addAndThrow(new LocalizedResourceConfigException("warning.config.item.item_model.conflict", itemModelKey.asString()));
|
||||
}
|
||||
|
||||
// 使用了item-model组件,且不是原版物品的
|
||||
@@ -508,162 +531,9 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerFunctions() {
|
||||
registerDataType((obj) -> {
|
||||
Map<String, Object> data = MiscUtils.castToMap(obj, false);
|
||||
String plugin = data.get("plugin").toString();
|
||||
String id = data.get("id").toString();
|
||||
ExternalItemSource<I> provider = AbstractItemManager.this.getExternalItemSource(plugin.toLowerCase(Locale.ENGLISH));
|
||||
return new ExternalModifier<>(id, Objects.requireNonNull(provider, "Item provider " + plugin + " not found"));
|
||||
}, "external");
|
||||
if (VersionHelper.isOrAbove1_20_5()) {
|
||||
registerDataType((obj) -> {
|
||||
String name = obj.toString();
|
||||
return new CustomNameModifier<>(name);
|
||||
}, "custom-name");
|
||||
registerDataType((obj) -> {
|
||||
String name = obj.toString();
|
||||
return new ItemNameModifier<>(name);
|
||||
}, "item-name", "display-name");
|
||||
} else {
|
||||
registerDataType((obj) -> {
|
||||
String name = obj.toString();
|
||||
return new CustomNameModifier<>(name);
|
||||
}, "custom-name", "item-name", "display-name");
|
||||
}
|
||||
registerDataType((obj) -> {
|
||||
List<String> lore = MiscUtils.getAsStringList(obj);
|
||||
return new LoreModifier<>(lore);
|
||||
}, "lore", "display-lore", "description");
|
||||
registerDataType((obj) -> {
|
||||
Map<String, List<String>> dynamicLore = new LinkedHashMap<>();
|
||||
if (obj instanceof Map<?, ?> map) {
|
||||
for (Map.Entry<?, ?> entry : map.entrySet()) {
|
||||
dynamicLore.put(entry.getKey().toString(), MiscUtils.getAsStringList(entry.getValue()));
|
||||
}
|
||||
}
|
||||
return new DynamicLoreModifier<>(dynamicLore);
|
||||
}, "dynamic-lore");
|
||||
registerDataType((obj) -> {
|
||||
if (obj instanceof Integer integer) {
|
||||
return new DyedColorModifier<>(integer);
|
||||
} else {
|
||||
Vector3f vector3f = MiscUtils.getAsVector3f(obj, "dyed-color");
|
||||
return new DyedColorModifier<>(0 << 24 /*不可省略*/ | MCUtils.fastFloor(vector3f.x) << 16 | MCUtils.fastFloor(vector3f.y) << 8 | MCUtils.fastFloor(vector3f.z));
|
||||
}
|
||||
}, "dyed-color");
|
||||
if (!VersionHelper.isOrAbove1_21_5()) {
|
||||
registerDataType((obj) -> {
|
||||
Map<String, Object> data = MiscUtils.castToMap(obj, false);
|
||||
return new TagsModifier<>(data);
|
||||
}, "tags", "tag", "nbt");
|
||||
}
|
||||
registerDataType((object -> {
|
||||
MutableInt mutableInt = new MutableInt(0);
|
||||
List<AttributeModifier> attributeModifiers = ResourceConfigUtils.parseConfigAsList(object, (map) -> {
|
||||
String type = ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("type"), "warning.config.item.data.attribute_modifiers.missing_type");
|
||||
Key nativeType = AttributeModifiersModifier.getNativeAttributeName(Key.of(type));
|
||||
AttributeModifier.Slot slot = AttributeModifier.Slot.valueOf(map.getOrDefault("slot", "any").toString().toUpperCase(Locale.ENGLISH));
|
||||
Key id = Optional.ofNullable(map.get("id")).map(String::valueOf).map(Key::of).orElseGet(() -> {
|
||||
mutableInt.add(1);
|
||||
return Key.of("craftengine", "modifier_" + mutableInt.intValue());
|
||||
});
|
||||
double amount = ResourceConfigUtils.getAsDouble(
|
||||
ResourceConfigUtils.requireNonNullOrThrow(map.get("amount"), "warning.config.item.data.attribute_modifiers.missing_amount"), "amount"
|
||||
);
|
||||
AttributeModifier.Operation operation = AttributeModifier.Operation.valueOf(
|
||||
ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("operation"), "warning.config.item.data.attribute_modifiers.missing_operation").toUpperCase(Locale.ENGLISH)
|
||||
);
|
||||
AttributeModifier.Display display = null;
|
||||
if (VersionHelper.isOrAbove1_21_6() && map.containsKey("display")) {
|
||||
Map<String, Object> displayMap = MiscUtils.castToMap(map.get("display"), false);
|
||||
AttributeModifier.Display.Type displayType = AttributeModifier.Display.Type.valueOf(ResourceConfigUtils.requireNonEmptyStringOrThrow(displayMap.get("type"), "warning.config.item.data.attribute_modifiers.display.missing_type").toUpperCase(Locale.ENGLISH));
|
||||
if (displayType == AttributeModifier.Display.Type.OVERRIDE) {
|
||||
String miniMessageValue = ResourceConfigUtils.requireNonEmptyStringOrThrow(displayMap.get("value"), "warning.config.item.data.attribute_modifiers.display.missing_value");
|
||||
display = new AttributeModifier.Display(displayType, miniMessageValue);
|
||||
} else {
|
||||
display = new AttributeModifier.Display(displayType, null);
|
||||
}
|
||||
}
|
||||
return new AttributeModifier(nativeType.value(), slot, id,
|
||||
amount, operation, display);
|
||||
});
|
||||
return new AttributeModifiersModifier<>(attributeModifiers);
|
||||
}), "attributes", "attribute-modifiers", "attribute-modifier");
|
||||
registerDataType((obj) -> {
|
||||
boolean value = TypeUtils.checkType(obj, Boolean.class);
|
||||
return new UnbreakableModifier<>(value);
|
||||
}, "unbreakable");
|
||||
registerDataType((obj) -> {
|
||||
int customModelData = ResourceConfigUtils.getAsInt(obj, "custom-model-data");
|
||||
return new CustomModelDataModifier<>(customModelData);
|
||||
}, "custom-model-data");
|
||||
registerDataType((obj) -> {
|
||||
Map<String, Object> data = MiscUtils.castToMap(obj, false);
|
||||
List<Enchantment> enchantments = new ArrayList<>();
|
||||
for (Map.Entry<String, Object> e : data.entrySet()) {
|
||||
if (e.getValue() instanceof Number number) {
|
||||
enchantments.add(new Enchantment(Key.of(e.getKey()), number.intValue()));
|
||||
}
|
||||
}
|
||||
return new EnchantmentModifier<>(enchantments);
|
||||
}, "enchantment", "enchantments", "enchant");
|
||||
registerDataType((obj) -> {
|
||||
Map<String, Object> data = MiscUtils.castToMap(obj, false);
|
||||
String material = data.get("material").toString().toLowerCase(Locale.ENGLISH);
|
||||
String pattern = data.get("pattern").toString().toLowerCase(Locale.ENGLISH);
|
||||
return new TrimModifier<>(Key.of(material), Key.of(pattern));
|
||||
}, "trim");
|
||||
registerDataType((obj) -> {
|
||||
List<Key> components = MiscUtils.getAsStringList(obj).stream().map(Key::of).toList();
|
||||
return new HideTooltipModifier<>(components);
|
||||
}, "hide-tooltip", "hide-flags");
|
||||
registerDataType((obj) -> {
|
||||
Map<String, Object> data = MiscUtils.castToMap(obj, false);
|
||||
Map<String, TextProvider> arguments = new HashMap<>();
|
||||
for (Map.Entry<String, Object> entry : data.entrySet()) {
|
||||
arguments.put(entry.getKey(), TextProviders.fromString(entry.getValue().toString()));
|
||||
}
|
||||
return new ArgumentModifier<>(arguments);
|
||||
}, "args", "argument", "arguments");
|
||||
if (VersionHelper.isOrAbove1_20_5()) {
|
||||
registerDataType((obj) -> {
|
||||
Map<String, Object> data = MiscUtils.castToMap(obj, false);
|
||||
return new ComponentModifier<>(data);
|
||||
}, "components", "component");
|
||||
registerDataType((obj) -> {
|
||||
List<String> data = MiscUtils.getAsStringList(obj);
|
||||
return new RemoveComponentModifier<>(data);
|
||||
}, "remove-components", "remove-component");
|
||||
registerDataType((obj) -> {
|
||||
Map<String, Object> data = MiscUtils.castToMap(obj, false);
|
||||
int nutrition = ResourceConfigUtils.getAsInt(data.get("nutrition"), "nutrition");
|
||||
float saturation = ResourceConfigUtils.getAsFloat(data.get("saturation"), "saturation");
|
||||
return new FoodModifier<>(nutrition, saturation, ResourceConfigUtils.getAsBoolean(data.getOrDefault("can-always-eat", false), "can-always-eat"));
|
||||
}, "food");
|
||||
}
|
||||
if (VersionHelper.isOrAbove1_21()) {
|
||||
registerDataType((obj) -> {
|
||||
String song = obj.toString();
|
||||
return new JukeboxSongModifier<>(new JukeboxPlayable(song, true));
|
||||
}, "jukebox-playable");
|
||||
}
|
||||
if (VersionHelper.isOrAbove1_21_2()) {
|
||||
registerDataType((obj) -> {
|
||||
String id = obj.toString();
|
||||
return new TooltipStyleModifier<>(Key.of(id));
|
||||
}, "tooltip-style");
|
||||
registerDataType((obj) -> {
|
||||
Map<String, Object> data = MiscUtils.castToMap(obj, false);
|
||||
return new EquippableModifier<>(EquipmentData.fromMap(data));
|
||||
}, "equippable");
|
||||
registerDataType((obj) -> {
|
||||
String id = obj.toString();
|
||||
return new ItemModelModifier<>(Key.of(id));
|
||||
}, "item-model");
|
||||
// 抛出异常
|
||||
collector.throwIfPresent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package net.momirealms.craftengine.core.item;
|
||||
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
public class CloneableConstantItem<I> implements BuildableItem<I> {
|
||||
private final Item<I> item;
|
||||
|
||||
private CloneableConstantItem(Item<I> item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
public static <I> CloneableConstantItem<I> of(Item<I> item) {
|
||||
return new CloneableConstantItem<>(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key id() {
|
||||
return this.item.id();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> buildItem(ItemBuildContext context, int count) {
|
||||
return this.item.copyWithCount(count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public I buildItemStack(ItemBuildContext context, int count) {
|
||||
return this.item.copyWithCount(count).getItem();
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,8 @@ import java.util.Map;
|
||||
|
||||
public interface CustomItem<I> extends BuildableItem<I> {
|
||||
|
||||
boolean isVanillaItem();
|
||||
|
||||
Key id();
|
||||
|
||||
UniqueKey uniqueId();
|
||||
@@ -40,6 +42,8 @@ public interface CustomItem<I> extends BuildableItem<I> {
|
||||
List<ItemBehavior> behaviors();
|
||||
|
||||
interface Builder<I> {
|
||||
Builder<I> isVanillaItem(boolean isVanillaItem);
|
||||
|
||||
Builder<I> id(UniqueKey id);
|
||||
|
||||
Builder<I> clientBoundMaterial(Key clientBoundMaterialKey);
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.momirealms.craftengine.core.item;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.momirealms.craftengine.core.attribute.AttributeModifier;
|
||||
import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
|
||||
import net.momirealms.craftengine.core.item.data.Enchantment;
|
||||
import net.momirealms.craftengine.core.item.data.FireworkExplosion;
|
||||
@@ -9,9 +10,12 @@ import net.momirealms.craftengine.core.item.data.JukeboxPlayable;
|
||||
import net.momirealms.craftengine.core.item.data.Trim;
|
||||
import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
|
||||
import net.momirealms.craftengine.core.item.setting.EquipmentData;
|
||||
import net.momirealms.craftengine.core.util.Color;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -35,10 +39,13 @@ public interface Item<I> {
|
||||
|
||||
boolean isBlockItem();
|
||||
|
||||
@NotNull
|
||||
Key id();
|
||||
|
||||
@NotNull
|
||||
Key vanillaId();
|
||||
|
||||
@Nullable
|
||||
UniqueKey recipeIngredientId();
|
||||
|
||||
Optional<Key> customId();
|
||||
@@ -69,9 +76,10 @@ public interface Item<I> {
|
||||
|
||||
int maxDamage();
|
||||
|
||||
Item<I> dyedColor(Integer data);
|
||||
// todo 考虑部分版本的show in tooltip保留
|
||||
Item<I> dyedColor(Color data);
|
||||
|
||||
Optional<Integer> dyedColor();
|
||||
Optional<Color> dyedColor();
|
||||
|
||||
Item<I> fireworkExplosion(FireworkExplosion explosion);
|
||||
|
||||
@@ -117,6 +125,8 @@ public interface Item<I> {
|
||||
|
||||
Optional<List<Component>> loreComponent();
|
||||
|
||||
Item<I> attributeModifiers(List<AttributeModifier> modifiers);
|
||||
|
||||
Optional<JukeboxPlayable> jukeboxSong();
|
||||
|
||||
Item<I> jukeboxSong(JukeboxPlayable song);
|
||||
@@ -185,7 +195,7 @@ public interface Item<I> {
|
||||
|
||||
Item<I> copyWithCount(int count);
|
||||
|
||||
boolean is(Key itemTag);
|
||||
boolean hasItemTag(Key itemTag);
|
||||
|
||||
Object getLiteralObject();
|
||||
|
||||
@@ -208,4 +218,34 @@ public interface Item<I> {
|
||||
}
|
||||
|
||||
byte[] toByteArray();
|
||||
|
||||
default Item<I> applyDyedColors(List<Color> colors) {
|
||||
int totalRed = 0;
|
||||
int totalGreen = 0;
|
||||
int totalBlue = 0;
|
||||
int totalMaxComponent = 0;
|
||||
int colorCount = 0;
|
||||
Optional<Color> existingColor = dyedColor();
|
||||
existingColor.ifPresent(colors::add);
|
||||
for (Color color : colors) {
|
||||
int dyeRed = color.r();
|
||||
int dyeGreen = color.g();
|
||||
int dyeBlue = color.b();
|
||||
totalMaxComponent += Math.max(dyeRed, Math.max(dyeGreen, dyeBlue));
|
||||
totalRed += dyeRed;
|
||||
totalGreen += dyeGreen;
|
||||
totalBlue += dyeBlue;
|
||||
++colorCount;
|
||||
}
|
||||
int avgRed = totalRed / colorCount;
|
||||
int avgGreen = totalGreen / colorCount;
|
||||
int avgBlue = totalBlue / colorCount;
|
||||
float avgMaxComponent = (float) totalMaxComponent / (float)colorCount;
|
||||
float currentMaxComponent = (float) Math.max(avgRed, Math.max(avgGreen, avgBlue));
|
||||
avgRed = (int) ((float) avgRed * avgMaxComponent / currentMaxComponent);
|
||||
avgGreen = (int) ((float) avgGreen * avgMaxComponent / currentMaxComponent);
|
||||
avgBlue = (int) ((float) avgBlue * avgMaxComponent / currentMaxComponent);
|
||||
Color finalColor = new Color(0, avgRed, avgGreen, avgBlue);
|
||||
return dyedColor(finalColor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package net.momirealms.craftengine.core.item;
|
||||
|
||||
import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
|
||||
|
||||
public interface ItemDataModifierFactory<I> {
|
||||
|
||||
ItemDataModifier<I> create(Object arg);
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package net.momirealms.craftengine.core.item;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.momirealms.craftengine.core.attribute.AttributeModifier;
|
||||
import net.momirealms.craftengine.core.item.data.Enchantment;
|
||||
import net.momirealms.craftengine.core.item.data.FireworkExplosion;
|
||||
import net.momirealms.craftengine.core.item.data.JukeboxPlayable;
|
||||
@@ -9,6 +10,7 @@ import net.momirealms.craftengine.core.item.data.Trim;
|
||||
import net.momirealms.craftengine.core.item.setting.EquipmentData;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.util.AdventureHelper;
|
||||
import net.momirealms.craftengine.core.util.Color;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
@@ -16,7 +18,6 @@ import net.momirealms.sparrow.nbt.Tag;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public abstract class ItemFactory<W extends ItemWrapper<I>, I> {
|
||||
protected final CraftEngine plugin;
|
||||
@@ -112,7 +113,7 @@ public abstract class ItemFactory<W extends ItemWrapper<I>, I> {
|
||||
|
||||
protected void loreComponent(W item, List<Component> component) {
|
||||
if (component != null && !component.isEmpty()) {
|
||||
loreJson(item, component.stream().map(AdventureHelper::componentToJson).collect(Collectors.toList()));
|
||||
loreJson(item, component.stream().map(AdventureHelper::componentToJson).toList());
|
||||
} else {
|
||||
loreJson(item, null);
|
||||
}
|
||||
@@ -136,9 +137,9 @@ public abstract class ItemFactory<W extends ItemWrapper<I>, I> {
|
||||
|
||||
protected abstract void damage(W item, Integer damage);
|
||||
|
||||
protected abstract Optional<Integer> dyedColor(W item);
|
||||
protected abstract Optional<Color> dyedColor(W item);
|
||||
|
||||
protected abstract void dyedColor(W item, Integer color);
|
||||
protected abstract void dyedColor(W item, Color color);
|
||||
|
||||
protected abstract int maxDamage(W item);
|
||||
|
||||
@@ -164,7 +165,7 @@ public abstract class ItemFactory<W extends ItemWrapper<I>, I> {
|
||||
|
||||
protected abstract void maxStackSize(W item, Integer maxStackSize);
|
||||
|
||||
protected abstract boolean is(W item, Key itemTag);
|
||||
protected abstract boolean hasItemTag(W item, Key itemTag);
|
||||
|
||||
protected abstract boolean isBlockItem(W item);
|
||||
|
||||
@@ -211,4 +212,6 @@ public abstract class ItemFactory<W extends ItemWrapper<I>, I> {
|
||||
protected abstract boolean isEmpty(W item);
|
||||
|
||||
protected abstract UniqueKey recipeIngredientID(W item);
|
||||
|
||||
protected abstract void attributeModifiers(W item, List<AttributeModifier> modifiers);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package net.momirealms.craftengine.core.item;
|
||||
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
public class ItemKeys {
|
||||
public final class ItemKeys {
|
||||
public static final Key AIR = Key.of("minecraft:air");
|
||||
public static final Key FLINT_AND_STEEL = Key.of("minecraft:flint_and_steel");
|
||||
public static final Key STONE = Key.of("minecraft:stone");
|
||||
@@ -26,6 +26,7 @@ public class ItemKeys {
|
||||
public static final Key TROPICAL_FISH_BUCKET = Key.of("minecraft:tropical_fish_bucket");
|
||||
public static final Key PUFFERFISH_BUCKET = Key.of("minecraft:pufferfish_bucket");
|
||||
public static final Key AXOLOTL_BUCKET = Key.of("minecraft:axolotl_bucket");
|
||||
public static final Key LAVA_BUCKET = Key.of("minecraft:lava_bucket");
|
||||
public static final Key BUCKET = Key.of("minecraft:bucket");
|
||||
public static final Key BONE_MEAL = Key.of("minecraft:bone_meal");
|
||||
public static final Key ENCHANTED_BOOK = Key.of("minecraft:enchanted_book");
|
||||
@@ -33,6 +34,33 @@ public class ItemKeys {
|
||||
public static final Key BARRIER = Key.of("minecraft:barrier");
|
||||
public static final Key CACTUS = Key.of("minecraft:cactus");
|
||||
public static final Key REDSTONE = Key.of("minecraft:redstone");
|
||||
public static final Key GOLD_INGOT = Key.of("minecraft:gold_ingot");
|
||||
public static final Key SHEARS = Key.of("minecraft:shears");
|
||||
public static final Key BRUSH = Key.of("minecraft:brush");
|
||||
public static final Key BOWL = Key.of("minecraft:bowl");
|
||||
public static final Key COMPASS = Key.of("minecraft:compass");
|
||||
public static final Key GLASS_BOTTLE = Key.of("minecraft:glass_bottle");
|
||||
public static final Key LIGHT = Key.of("minecraft:light");
|
||||
public static final Key GLOWSTONE = Key.of("minecraft:glowstone");
|
||||
public static final Key SADDLE = Key.of("minecraft:saddle");
|
||||
public static final Key HARNESS = Key.of("minecraft:harness");
|
||||
public static final Key WHITE_DYE = Key.of("minecraft:white_dye");
|
||||
public static final Key ORANGE_DYE = Key.of("minecraft:orange_dye");
|
||||
public static final Key MAGENTA_DYE = Key.of("minecraft:magenta_dye");
|
||||
public static final Key LIGHT_BLUE_DYE = Key.of("minecraft:light_blue_dye");
|
||||
public static final Key YELLOW_DYE = Key.of("minecraft:yellow_dye");
|
||||
public static final Key LIME_DYE = Key.of("minecraft:lime_dye");
|
||||
public static final Key PINK_DYE = Key.of("minecraft:pink_dye");
|
||||
public static final Key GRAY_DYE = Key.of("minecraft:gray_dye");
|
||||
public static final Key LIGHT_GRAY_DYE = Key.of("minecraft:light_gray_dye");
|
||||
public static final Key CYAN_DYE = Key.of("minecraft:cyan_dye");
|
||||
public static final Key PURPLE_DYE = Key.of("minecraft:purple_dye");
|
||||
public static final Key BLUE_DYE = Key.of("minecraft:blue_dye");
|
||||
public static final Key BROWN_DYE = Key.of("minecraft:brown_dye");
|
||||
public static final Key GREEN_DYE = Key.of("minecraft:green_dye");
|
||||
public static final Key RED_DYE = Key.of("minecraft:red_dye");
|
||||
public static final Key BLACK_DYE = Key.of("minecraft:black_dye");
|
||||
public static final Key FIREWORK_STAR = Key.of("minecraft:firework_star");
|
||||
|
||||
public static final Key[] AXES = new Key[] {
|
||||
WOODEN_AXE, STONE_AXE, IRON_AXE, GOLDEN_AXE, DIAMOND_AXE, NETHERITE_AXE
|
||||
|
||||
@@ -3,7 +3,7 @@ package net.momirealms.craftengine.core.item;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
|
||||
import net.momirealms.craftengine.core.item.equipment.Equipment;
|
||||
import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
|
||||
import net.momirealms.craftengine.core.item.recipe.DatapackRecipeResult;
|
||||
import net.momirealms.craftengine.core.item.recipe.UniqueIdItem;
|
||||
import net.momirealms.craftengine.core.pack.model.LegacyOverridesModel;
|
||||
import net.momirealms.craftengine.core.pack.model.ModernItemModel;
|
||||
@@ -18,14 +18,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
public interface ItemManager<T> extends Manageable, ModelGenerator {
|
||||
|
||||
void registerDataType(Function<Object, ItemDataModifier<T>> factory, String... alias);
|
||||
|
||||
Function<Object, ItemDataModifier<T>> getDataType(String key);
|
||||
|
||||
Map<Key, Equipment> equipments();
|
||||
|
||||
ConfigParser[] parsers();
|
||||
@@ -59,10 +54,6 @@ public interface ItemManager<T> extends Manageable, ModelGenerator {
|
||||
|
||||
Collection<Key> items();
|
||||
|
||||
Key itemId(T itemStack);
|
||||
|
||||
Key customItemId(T itemStack);
|
||||
|
||||
ExternalItemSource<T> getExternalItemSource(String name);
|
||||
|
||||
boolean registerExternalItemSource(ExternalItemSource<T> externalItemSource);
|
||||
@@ -87,11 +78,16 @@ public interface ItemManager<T> extends Manageable, ModelGenerator {
|
||||
|
||||
boolean addCustomItem(CustomItem<T> customItem);
|
||||
|
||||
List<UniqueKey> tagToItems(Key tag);
|
||||
default List<UniqueKey> itemIdsByTag(Key tag) {
|
||||
List<UniqueKey> items = new ArrayList<>();
|
||||
items.addAll(vanillaItemIdsByTag(tag));
|
||||
items.addAll(customItemIdsByTag(tag));
|
||||
return items;
|
||||
}
|
||||
|
||||
List<UniqueKey> tagToVanillaItems(Key tag);
|
||||
List<UniqueKey> vanillaItemIdsByTag(Key tag);
|
||||
|
||||
List<UniqueKey> tagToCustomItems(Key tag);
|
||||
List<UniqueKey> customItemIdsByTag(Key tag);
|
||||
|
||||
int fuelTime(T itemStack);
|
||||
|
||||
@@ -114,4 +110,6 @@ public interface ItemManager<T> extends Manageable, ModelGenerator {
|
||||
UniqueIdItem<T> uniqueEmptyItem();
|
||||
|
||||
Item<T> applyTrim(Item<T> base, Item<T> addition, Item<T> template, Key pattern);
|
||||
|
||||
Item<T> build(DatapackRecipeResult result);
|
||||
}
|
||||
@@ -25,12 +25,12 @@ import java.util.stream.Collectors;
|
||||
public class ItemSettings {
|
||||
int fuelTime;
|
||||
Set<Key> tags = Set.of();
|
||||
boolean canRepair = true;
|
||||
Tristate canRepair = Tristate.UNDEFINED;
|
||||
List<AnvilRepairItem> anvilRepairItems = List.of();
|
||||
boolean renameable = true;
|
||||
boolean canPlaceRelatedVanillaBlock = false;
|
||||
ProjectileMeta projectileMeta;
|
||||
boolean dyeable = true;
|
||||
Tristate dyeable = Tristate.UNDEFINED;
|
||||
Helmet helmet = null;
|
||||
FoodData foodData = null;
|
||||
Key consumeReplacement = null;
|
||||
@@ -41,6 +41,10 @@ public class ItemSettings {
|
||||
boolean respectRepairableComponent = false;
|
||||
@Nullable
|
||||
ItemEquipment equipment;
|
||||
@Nullable
|
||||
Color dyeColor;
|
||||
@Nullable
|
||||
Color fireworkColor;
|
||||
|
||||
private ItemSettings() {}
|
||||
|
||||
@@ -99,6 +103,8 @@ public class ItemSettings {
|
||||
newSettings.canEnchant = settings.canEnchant;
|
||||
newSettings.compostProbability = settings.compostProbability;
|
||||
newSettings.respectRepairableComponent = settings.respectRepairableComponent;
|
||||
newSettings.dyeColor = settings.dyeColor;
|
||||
newSettings.fireworkColor = settings.fireworkColor;
|
||||
return newSettings;
|
||||
}
|
||||
|
||||
@@ -122,7 +128,7 @@ public class ItemSettings {
|
||||
return canPlaceRelatedVanillaBlock;
|
||||
}
|
||||
|
||||
public boolean canRepair() {
|
||||
public Tristate canRepair() {
|
||||
return canRepair;
|
||||
}
|
||||
|
||||
@@ -138,7 +144,7 @@ public class ItemSettings {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public boolean dyeable() {
|
||||
public Tristate dyeable() {
|
||||
return dyeable;
|
||||
}
|
||||
|
||||
@@ -179,6 +185,16 @@ public class ItemSettings {
|
||||
return equipment;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Color dyeColor() {
|
||||
return this.dyeColor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Color fireworkColor() {
|
||||
return this.fireworkColor;
|
||||
}
|
||||
|
||||
public List<DamageSource> invulnerable() {
|
||||
return invulnerable;
|
||||
}
|
||||
@@ -187,6 +203,16 @@ public class ItemSettings {
|
||||
return compostProbability;
|
||||
}
|
||||
|
||||
public ItemSettings fireworkColor(Color color) {
|
||||
this.fireworkColor = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemSettings dyeColor(Color color) {
|
||||
this.dyeColor = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemSettings repairItems(List<AnvilRepairItem> items) {
|
||||
this.anvilRepairItems = items;
|
||||
return this;
|
||||
@@ -207,7 +233,7 @@ public class ItemSettings {
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemSettings canRepair(boolean canRepair) {
|
||||
public ItemSettings canRepair(Tristate canRepair) {
|
||||
this.canRepair = canRepair;
|
||||
return this;
|
||||
}
|
||||
@@ -252,7 +278,7 @@ public class ItemSettings {
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemSettings dyeable(boolean bool) {
|
||||
public ItemSettings dyeable(Tristate bool) {
|
||||
this.dyeable = bool;
|
||||
return this;
|
||||
}
|
||||
@@ -290,7 +316,7 @@ public class ItemSettings {
|
||||
static {
|
||||
registerFactory("repairable", (value -> {
|
||||
boolean bool = ResourceConfigUtils.getAsBoolean(value, "repairable");
|
||||
return settings -> settings.canRepair(bool);
|
||||
return settings -> settings.canRepair(bool ? Tristate.TRUE : Tristate.FALSE);
|
||||
}));
|
||||
registerFactory("enchantable", (value -> {
|
||||
boolean bool = ResourceConfigUtils.getAsBoolean(value, "enchantable");
|
||||
@@ -325,7 +351,13 @@ public class ItemSettings {
|
||||
}));
|
||||
registerFactory("tags", (value -> {
|
||||
List<String> tags = MiscUtils.getAsStringList(value);
|
||||
return settings -> settings.tags(tags.stream().map(Key::of).collect(Collectors.toSet()));
|
||||
return settings -> settings.tags(tags.stream().map(it -> {
|
||||
if (it.charAt(0) == '#') {
|
||||
return Key.of(it.substring(1));
|
||||
} else {
|
||||
return Key.of(it);
|
||||
}
|
||||
}).collect(Collectors.toSet()));
|
||||
}));
|
||||
registerFactory("equippable", (value -> {
|
||||
Map<String, Object> args = MiscUtils.castToMap(value, false);
|
||||
@@ -384,12 +416,26 @@ public class ItemSettings {
|
||||
}));
|
||||
registerFactory("dyeable", (value -> {
|
||||
boolean bool = ResourceConfigUtils.getAsBoolean(value, "dyeable");
|
||||
return settings -> settings.dyeable(bool);
|
||||
return settings -> settings.dyeable(bool ? Tristate.TRUE : Tristate.FALSE);
|
||||
}));
|
||||
registerFactory("respect-repairable-component", (value -> {
|
||||
boolean bool = ResourceConfigUtils.getAsBoolean(value, "respect-repairable-component");
|
||||
return settings -> settings.respectRepairableComponent(bool);
|
||||
}));
|
||||
registerFactory("dye-color", (value -> {
|
||||
if (value instanceof Integer i) {
|
||||
return settings -> settings.dyeColor(Color.fromDecimal(i));
|
||||
} else {
|
||||
return settings -> settings.dyeColor(Color.fromVector3f(MiscUtils.getAsVector3f(value, "dye-color")));
|
||||
}
|
||||
}));
|
||||
registerFactory("firework-color", (value -> {
|
||||
if (value instanceof Integer i) {
|
||||
return settings -> settings.fireworkColor(Color.fromDecimal(i));
|
||||
} else {
|
||||
return settings -> settings.fireworkColor(Color.fromVector3f(MiscUtils.getAsVector3f(value, "firework-color")));
|
||||
}
|
||||
}));
|
||||
registerFactory("food", (value -> {
|
||||
Map<String, Object> args = MiscUtils.castToMap(value, false);
|
||||
FoodData data = new FoodData(
|
||||
|
||||
@@ -8,6 +8,12 @@ import java.util.Map;
|
||||
|
||||
public record FireworkExplosion(Shape shape, IntList colors, IntList fadeColors, boolean hasTrail, boolean hasTwinkle) {
|
||||
|
||||
public static final FireworkExplosion DEFAULT = new FireworkExplosion(Shape.SMALL_BALL, IntList.of(), IntList.of(), false, false);
|
||||
|
||||
public FireworkExplosion withFadeColors(@NotNull final IntList fadeColors) {
|
||||
return new FireworkExplosion(this.shape, this.colors, fadeColors, this.hasTrail, this.hasTwinkle);
|
||||
}
|
||||
|
||||
public enum Shape {
|
||||
SMALL_BALL(0, "small_ball"),
|
||||
LARGE_BALL(1, "large_ball"),
|
||||
|
||||
@@ -3,7 +3,11 @@ package net.momirealms.craftengine.core.item.modifier;
|
||||
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.ItemDataModifierFactory;
|
||||
import net.momirealms.craftengine.core.plugin.context.text.TextProvider;
|
||||
import net.momirealms.craftengine.core.plugin.context.text.TextProviders;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.StringTag;
|
||||
@@ -12,17 +16,22 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ArgumentModifier<I> implements ItemDataModifier<I> {
|
||||
public class ArgumentsModifier<I> implements ItemDataModifier<I> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
public static final String ARGUMENTS_TAG = "craftengine:arguments";
|
||||
private final Map<String, TextProvider> arguments;
|
||||
|
||||
public ArgumentModifier(Map<String, TextProvider> arguments) {
|
||||
public ArgumentsModifier(Map<String, TextProvider> arguments) {
|
||||
this.arguments = arguments;
|
||||
}
|
||||
|
||||
public Map<String, TextProvider> arguments() {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "arguments";
|
||||
public Key type() {
|
||||
return ItemDataModifiers.ARGUMENTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -44,4 +53,17 @@ public class ArgumentModifier<I> implements ItemDataModifier<I> {
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
public static class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
Map<String, Object> data = ResourceConfigUtils.getAsMap(arg, "arguments");
|
||||
Map<String, TextProvider> arguments = new HashMap<>();
|
||||
for (Map.Entry<String, Object> entry : data.entrySet()) {
|
||||
arguments.put(entry.getKey(), TextProviders.fromString(entry.getValue().toString()));
|
||||
}
|
||||
return new ArgumentsModifier<>(arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,19 +6,16 @@ import net.momirealms.craftengine.core.attribute.Attributes1_21;
|
||||
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||
import net.momirealms.craftengine.core.util.AdventureHelper;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.UUIDUtils;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.ListTag;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
import net.momirealms.craftengine.core.item.ItemDataModifierFactory;
|
||||
import net.momirealms.craftengine.core.plugin.context.number.NumberProvider;
|
||||
import net.momirealms.craftengine.core.plugin.context.number.NumberProviders;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
public class AttributeModifiersModifier<I> implements ItemDataModifier<I> {
|
||||
public class AttributeModifiersModifier<I> implements SimpleNetworkItemDataModifier<I> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
public static final Map<Key, Key> CONVERTOR = new HashMap<>();
|
||||
|
||||
static {
|
||||
@@ -91,100 +88,101 @@ public class AttributeModifiersModifier<I> implements ItemDataModifier<I> {
|
||||
return CONVERTOR.getOrDefault(attributeName, attributeName);
|
||||
}
|
||||
|
||||
private final List<AttributeModifier> modifiers;
|
||||
private final List<PreModifier> modifiers;
|
||||
|
||||
public AttributeModifiersModifier(List<AttributeModifier> modifiers) {
|
||||
public AttributeModifiersModifier(List<PreModifier> modifiers) {
|
||||
this.modifiers = modifiers;
|
||||
}
|
||||
|
||||
public List<AttributeModifier> modifiers() {
|
||||
public List<PreModifier> modifiers() {
|
||||
return this.modifiers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "attribute-modifiers";
|
||||
public Key type() {
|
||||
return ItemDataModifiers.ATTRIBUTE_MODIFIERS;
|
||||
}
|
||||
|
||||
private static Object previous;
|
||||
|
||||
@Override
|
||||
public Item<I> apply(Item<I> item, ItemBuildContext context) {
|
||||
if (VersionHelper.isOrAbove1_21_5()) {
|
||||
ListTag modifiers = new ListTag();
|
||||
for (AttributeModifier modifier : this.modifiers) {
|
||||
CompoundTag modifierTag = new CompoundTag();
|
||||
modifierTag.putString("type", modifier.type());
|
||||
modifierTag.putString("slot", modifier.slot().name().toLowerCase(Locale.ENGLISH));
|
||||
modifierTag.putString("id", modifier.id().toString());
|
||||
modifierTag.putDouble("amount", modifier.amount());
|
||||
modifierTag.putString("operation", modifier.operation().id());
|
||||
AttributeModifier.Display display = modifier.display();
|
||||
if (VersionHelper.isOrAbove1_21_6() && display != null) {
|
||||
CompoundTag displayTag = new CompoundTag();
|
||||
AttributeModifier.Display.Type displayType = display.type();
|
||||
displayTag.putString("type", displayType.name().toLowerCase(Locale.ENGLISH));
|
||||
if (displayType == AttributeModifier.Display.Type.OVERRIDE) {
|
||||
displayTag.put("value", AdventureHelper.componentToTag(AdventureHelper.miniMessage().deserialize(display.value(), context.tagResolvers())));
|
||||
}
|
||||
modifierTag.put("display", displayTag);
|
||||
}
|
||||
modifiers.add(modifierTag);
|
||||
}
|
||||
item.setNBTComponent(ComponentKeys.ATTRIBUTE_MODIFIERS, modifiers);
|
||||
} else if (VersionHelper.isOrAbove1_20_5()) {
|
||||
CompoundTag compoundTag = (CompoundTag) Optional.ofNullable(item.getSparrowNBTComponent(ComponentKeys.ATTRIBUTE_MODIFIERS)).orElseGet(CompoundTag::new);
|
||||
ListTag modifiers = new ListTag();
|
||||
compoundTag.put("modifiers", modifiers);
|
||||
for (AttributeModifier modifier : this.modifiers) {
|
||||
CompoundTag modifierTag = new CompoundTag();
|
||||
modifierTag.putString("type", modifier.type());
|
||||
modifierTag.putString("slot", modifier.slot().name().toLowerCase(Locale.ENGLISH));
|
||||
if (VersionHelper.isOrAbove1_21()) {
|
||||
modifierTag.putString("id", modifier.id().toString());
|
||||
} else {
|
||||
modifierTag.putIntArray("uuid", UUIDUtils.uuidToIntArray(UUID.nameUUIDFromBytes(modifier.id().toString().getBytes(StandardCharsets.UTF_8))));
|
||||
modifierTag.putString("name", modifier.id().toString());
|
||||
}
|
||||
modifierTag.putDouble("amount", modifier.amount());
|
||||
modifierTag.putString("operation", modifier.operation().id());
|
||||
modifiers.add(modifierTag);
|
||||
}
|
||||
item.setNBTComponent(ComponentKeys.ATTRIBUTE_MODIFIERS, compoundTag);
|
||||
} else {
|
||||
ListTag listTag = new ListTag();
|
||||
for (AttributeModifier modifier : this.modifiers) {
|
||||
CompoundTag modifierTag = new CompoundTag();
|
||||
modifierTag.putString("AttributeName", modifier.type());
|
||||
modifierTag.putString("Name", modifier.id().toString());
|
||||
modifierTag.putString("Slot", modifier.slot().name().toLowerCase(Locale.ENGLISH));
|
||||
modifierTag.putInt("Operation", modifier.operation().ordinal());
|
||||
modifierTag.putDouble("Amount", modifier.amount());
|
||||
modifierTag.putIntArray("UUID", UUIDUtils.uuidToIntArray(UUID.nameUUIDFromBytes(modifier.id().toString().getBytes(StandardCharsets.UTF_8))));
|
||||
listTag.add(modifierTag);
|
||||
}
|
||||
item.setTag(listTag, "AttributeModifiers");
|
||||
}
|
||||
return item;
|
||||
return item.attributeModifiers(this.modifiers.stream().map(it -> it.toAttributeModifier(context)).toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> prepareNetworkItem(Item<I> item, ItemBuildContext context, CompoundTag networkData) {
|
||||
if (VersionHelper.isOrAbove1_20_5()) {
|
||||
Tag previous = item.getSparrowNBTComponent(ComponentKeys.ATTRIBUTE_MODIFIERS);
|
||||
if (previous != null) {
|
||||
networkData.put(ComponentKeys.ATTRIBUTE_MODIFIERS.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put(ComponentKeys.ATTRIBUTE_MODIFIERS.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getTag("AttributeModifiers");
|
||||
if (previous != null) {
|
||||
networkData.put("AttributeModifiers", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put("AttributeModifiers", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
public @Nullable Key componentType(Item<I> item, ItemBuildContext context) {
|
||||
return ComponentKeys.ATTRIBUTE_MODIFIERS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object[] nbtPath(Item<I> item, ItemBuildContext context) {
|
||||
return new Object[]{"AttributeModifiers"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nbtPathString(Item<I> item, ItemBuildContext context) {
|
||||
return "AttributeModifiers";
|
||||
}
|
||||
|
||||
public record PreModifier(String type,
|
||||
AttributeModifier.Slot slot,
|
||||
Key id,
|
||||
NumberProvider amount,
|
||||
AttributeModifier.Operation operation,
|
||||
AttributeModifiersModifier.PreModifier.@Nullable PreDisplay display) {
|
||||
|
||||
public PreModifier(String type, AttributeModifier.Slot slot, Key id, NumberProvider amount, AttributeModifier.Operation operation, @Nullable PreDisplay display) {
|
||||
this.amount = amount;
|
||||
this.type = type;
|
||||
this.slot = slot;
|
||||
this.id = id;
|
||||
this.operation = operation;
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
public AttributeModifier toAttributeModifier(ItemBuildContext context) {
|
||||
return new AttributeModifier(type, slot, id, amount.getDouble(context), operation, display == null ? null : display.toDisplay(context));
|
||||
}
|
||||
|
||||
public record PreDisplay(AttributeModifier.Display.Type type, String value) {
|
||||
|
||||
public AttributeModifier.Display toDisplay(ItemBuildContext context) {
|
||||
return new AttributeModifier.Display(type, AdventureHelper.miniMessage().deserialize(value, context.tagResolvers()));
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
public static class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
MutableInt mutableInt = new MutableInt(0);
|
||||
List<PreModifier> attributeModifiers = ResourceConfigUtils.parseConfigAsList(arg, (map) -> {
|
||||
String type = ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("type"), "warning.config.item.data.attribute_modifiers.missing_type");
|
||||
Key nativeType = AttributeModifiersModifier.getNativeAttributeName(Key.of(type));
|
||||
AttributeModifier.Slot slot = AttributeModifier.Slot.valueOf(map.getOrDefault("slot", "any").toString().toUpperCase(Locale.ENGLISH));
|
||||
Key id = Optional.ofNullable(map.get("id")).map(String::valueOf).map(Key::of).orElseGet(() -> {
|
||||
mutableInt.add(1);
|
||||
return Key.of("craftengine", "modifier_" + mutableInt.intValue());
|
||||
});
|
||||
NumberProvider amount = NumberProviders.fromObject(ResourceConfigUtils.requireNonNullOrThrow(map.get("amount"), "warning.config.item.data.attribute_modifiers.missing_amount"));
|
||||
AttributeModifier.Operation operation = AttributeModifier.Operation.valueOf(
|
||||
ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("operation"), "warning.config.item.data.attribute_modifiers.missing_operation").toUpperCase(Locale.ENGLISH)
|
||||
);
|
||||
PreModifier.PreDisplay display = null;
|
||||
if (VersionHelper.isOrAbove1_21_6() && map.containsKey("display")) {
|
||||
Map<String, Object> displayMap = MiscUtils.castToMap(map.get("display"), false);
|
||||
AttributeModifier.Display.Type displayType = AttributeModifier.Display.Type.valueOf(ResourceConfigUtils.requireNonEmptyStringOrThrow(displayMap.get("type"), "warning.config.item.data.attribute_modifiers.display.missing_type").toUpperCase(Locale.ENGLISH));
|
||||
if (displayType == AttributeModifier.Display.Type.OVERRIDE) {
|
||||
String miniMessageValue = ResourceConfigUtils.requireNonEmptyStringOrThrow(displayMap.get("value"), "warning.config.item.data.attribute_modifiers.display.missing_value");
|
||||
display = new PreModifier.PreDisplay(displayType, miniMessageValue);
|
||||
} else {
|
||||
display = new PreModifier.PreDisplay(displayType, null);
|
||||
}
|
||||
}
|
||||
return new PreModifier(nativeType.value(), slot, id,
|
||||
amount, operation, display);
|
||||
});
|
||||
return new AttributeModifiersModifier<>(attributeModifiers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
package net.momirealms.craftengine.core.item.modifier;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||
import net.momirealms.craftengine.core.item.*;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.util.GsonHelper;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.Pair;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
|
||||
@@ -16,11 +14,12 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ComponentModifier<I> implements ItemDataModifier<I> {
|
||||
public class ComponentsModifier<I> implements ItemDataModifier<I> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
private final List<Pair<Key, Tag>> arguments;
|
||||
private CompoundTag customData = null;
|
||||
|
||||
public ComponentModifier(Map<String, Object> arguments) {
|
||||
public ComponentsModifier(Map<String, Object> arguments) {
|
||||
List<Pair<Key, Tag>> pairs = new ArrayList<>(arguments.size());
|
||||
for (Map.Entry<String, Object> entry : arguments.entrySet()) {
|
||||
Key key = Key.of(entry.getKey());
|
||||
@@ -33,7 +32,7 @@ public class ComponentModifier<I> implements ItemDataModifier<I> {
|
||||
this.arguments = pairs;
|
||||
}
|
||||
|
||||
public List<Pair<Key, Tag>> arguments() {
|
||||
public List<Pair<Key, Tag>> components() {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
@@ -49,8 +48,8 @@ public class ComponentModifier<I> implements ItemDataModifier<I> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "components";
|
||||
public Key type() {
|
||||
return ItemDataModifiers.COMPONENTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -84,4 +83,13 @@ public class ComponentModifier<I> implements ItemDataModifier<I> {
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
public static class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
Map<String, Object> data = ResourceConfigUtils.getAsMap(arg, "components");
|
||||
return new ComponentsModifier<>(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,21 +3,26 @@ package net.momirealms.craftengine.core.item.modifier;
|
||||
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
import net.momirealms.craftengine.core.item.ItemDataModifierFactory;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class CustomModelDataModifier<I> implements ItemDataModifier<I> {
|
||||
public class CustomModelDataModifier<I> implements SimpleNetworkItemDataModifier<I> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
private final int argument;
|
||||
|
||||
public CustomModelDataModifier(int argument) {
|
||||
this.argument = argument;
|
||||
}
|
||||
|
||||
public int customModelData() {
|
||||
return this.argument;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "custom-model-data";
|
||||
public Key type() {
|
||||
return ItemDataModifiers.CUSTOM_MODEL_DATA;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -27,22 +32,26 @@ public class CustomModelDataModifier<I> implements ItemDataModifier<I> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> prepareNetworkItem(Item<I> item, ItemBuildContext context, CompoundTag networkData) {
|
||||
if (VersionHelper.isOrAbove1_20_5()) {
|
||||
Tag previous = item.getSparrowNBTComponent(ComponentKeys.CUSTOM_MODEL_DATA);
|
||||
if (previous != null) {
|
||||
networkData.put(ComponentKeys.CUSTOM_MODEL_DATA.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put(ComponentKeys.CUSTOM_MODEL_DATA.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getTag("CustomModelData");
|
||||
if (previous != null) {
|
||||
networkData.put("CustomModelData", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put("CustomModelData", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
public @Nullable Key componentType(Item<I> item, ItemBuildContext context) {
|
||||
return ComponentKeys.CUSTOM_MODEL_DATA;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object[] nbtPath(Item<I> item, ItemBuildContext context) {
|
||||
return new Object[]{"CustomModelData"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nbtPathString(Item<I> item, ItemBuildContext context) {
|
||||
return "CustomModelData";
|
||||
}
|
||||
|
||||
public static class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
int customModelData = ResourceConfigUtils.getAsInt(arg, "custom-model-data");
|
||||
return new CustomModelDataModifier<>(customModelData);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,14 @@ package net.momirealms.craftengine.core.item.modifier;
|
||||
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||
import net.momirealms.craftengine.core.item.ItemDataModifierFactory;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.util.AdventureHelper;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class CustomNameModifier<I> implements ItemDataModifier<I> {
|
||||
public class CustomNameModifier<I> implements SimpleNetworkItemDataModifier<I> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
private final String argument;
|
||||
|
||||
public CustomNameModifier(String argument) {
|
||||
@@ -25,9 +25,13 @@ public class CustomNameModifier<I> implements ItemDataModifier<I> {
|
||||
}
|
||||
}
|
||||
|
||||
public String customName() {
|
||||
return argument;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "custom-name";
|
||||
public Key type() {
|
||||
return ItemDataModifiers.CUSTOM_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -37,22 +41,26 @@ public class CustomNameModifier<I> implements ItemDataModifier<I> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> prepareNetworkItem(Item<I> item, ItemBuildContext context, CompoundTag networkData) {
|
||||
if (VersionHelper.isOrAbove1_20_5()) {
|
||||
Tag previous = item.getSparrowNBTComponent(ComponentKeys.CUSTOM_NAME);
|
||||
if (previous != null) {
|
||||
networkData.put(ComponentKeys.CUSTOM_NAME.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put(ComponentKeys.CUSTOM_NAME.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getTag("display", "Name");
|
||||
if (previous != null) {
|
||||
networkData.put("display.Name", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put("display.Name", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
public @Nullable Key componentType(Item<I> item, ItemBuildContext context) {
|
||||
return ComponentKeys.CUSTOM_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object[] nbtPath(Item<I> item, ItemBuildContext context) {
|
||||
return new Object[]{"display", "Name"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nbtPathString(Item<I> item, ItemBuildContext context) {
|
||||
return "display.Name";
|
||||
}
|
||||
|
||||
public static class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
String name = arg.toString();
|
||||
return new CustomNameModifier<>(name);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,46 +3,60 @@ package net.momirealms.craftengine.core.item.modifier;
|
||||
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
import net.momirealms.craftengine.core.item.ItemDataModifierFactory;
|
||||
import net.momirealms.craftengine.core.util.Color;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public class DyedColorModifier<I> implements ItemDataModifier<I> {
|
||||
private final int color;
|
||||
public class DyedColorModifier<I> implements SimpleNetworkItemDataModifier<I> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
private final Color color;
|
||||
|
||||
public DyedColorModifier(int color) {
|
||||
public DyedColorModifier(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public Color dyedColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "dyed-color";
|
||||
public Key type() {
|
||||
return ItemDataModifiers.DYED_COLOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> apply(Item<I> item, ItemBuildContext context) {
|
||||
item.dyedColor(this.color);
|
||||
return item;
|
||||
return item.dyedColor(this.color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> prepareNetworkItem(Item<I> item, ItemBuildContext context, CompoundTag networkData) {
|
||||
if (VersionHelper.isOrAbove1_20_5()) {
|
||||
Tag previous = item.getSparrowNBTComponent(ComponentKeys.DYED_COLOR);
|
||||
if (previous != null) {
|
||||
networkData.put(ComponentKeys.DYED_COLOR.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
public @Nullable Key componentType(Item<I> item, ItemBuildContext context) {
|
||||
return ComponentKeys.DYED_COLOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object[] nbtPath(Item<I> item, ItemBuildContext context) {
|
||||
return new Object[]{"display", "color"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nbtPathString(Item<I> item, ItemBuildContext context) {
|
||||
return "display.color";
|
||||
}
|
||||
|
||||
public static class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
if (arg instanceof Integer integer) {
|
||||
return new DyedColorModifier<>(Color.fromDecimal(integer));
|
||||
} else {
|
||||
networkData.put(ComponentKeys.DYED_COLOR.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getTag("display", "color");
|
||||
if (previous != null) {
|
||||
networkData.put("display.color", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put("display.color", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
Vector3f vector3f = MiscUtils.getAsVector3f(arg, "dyed-color");
|
||||
return new DyedColorModifier<>(Color.fromVector3f(vector3f));
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
package net.momirealms.craftengine.core.item.modifier;
|
||||
|
||||
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||
import net.momirealms.craftengine.core.util.AdventureHelper;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class DynamicLoreModifier<I> implements ItemDataModifier<I> {
|
||||
public static final String CONTEXT_TAG_KEY = "craftengine:display_context";
|
||||
private final Map<String, List<String>> displayContexts;
|
||||
private final String defaultContext;
|
||||
|
||||
public DynamicLoreModifier(Map<String, List<String>> displayContexts) {
|
||||
this.defaultContext = displayContexts.keySet().iterator().next();
|
||||
this.displayContexts = displayContexts;
|
||||
}
|
||||
|
||||
public Map<String, List<String>> displayContexts() {
|
||||
return Collections.unmodifiableMap(this.displayContexts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "dynamic-lore";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> apply(Item<I> item, ItemBuildContext context) {
|
||||
String displayContext = Optional.ofNullable(item.getJavaTag(CONTEXT_TAG_KEY)).orElse(this.defaultContext).toString();
|
||||
List<String> lore = this.displayContexts.get(displayContext);
|
||||
if (lore == null) {
|
||||
lore = this.displayContexts.get(this.defaultContext);
|
||||
}
|
||||
item.loreComponent(lore.stream().map(it -> AdventureHelper.miniMessage().deserialize(it, context.tagResolvers())).toList());
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> prepareNetworkItem(Item<I> item, ItemBuildContext context, CompoundTag networkData) {
|
||||
if (VersionHelper.isOrAbove1_20_5()) {
|
||||
Tag previous = item.getSparrowNBTComponent(ComponentKeys.LORE);
|
||||
if (previous != null) {
|
||||
networkData.put(ComponentKeys.LORE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put(ComponentKeys.LORE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getTag("display", "Lore");
|
||||
if (previous != null) {
|
||||
networkData.put("display.Lore", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put("display.Lore", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
package net.momirealms.craftengine.core.item.modifier;
|
||||
|
||||
import net.momirealms.craftengine.core.item.*;
|
||||
import net.momirealms.craftengine.core.item.data.Enchantment;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EnchantmentModifier<I> implements ItemDataModifier<I> {
|
||||
private final List<Enchantment> enchantments;
|
||||
|
||||
public EnchantmentModifier(List<Enchantment> enchantments) {
|
||||
this.enchantments = enchantments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "enchantment";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> apply(Item<I> item, ItemBuildContext context) {
|
||||
if (item.vanillaId().equals(ItemKeys.ENCHANTED_BOOK)) {
|
||||
item.setStoredEnchantments(this.enchantments);
|
||||
} else {
|
||||
item.setEnchantments(this.enchantments);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> prepareNetworkItem(Item<I> item, ItemBuildContext context, CompoundTag networkData) {
|
||||
if (item.vanillaId().equals(ItemKeys.ENCHANTED_BOOK)) {
|
||||
if (VersionHelper.isOrAbove1_20_5()) {
|
||||
Tag previous = item.getSparrowNBTComponent(ComponentKeys.STORED_ENCHANTMENTS);
|
||||
if (previous != null) {
|
||||
networkData.put(ComponentKeys.STORED_ENCHANTMENTS.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put(ComponentKeys.STORED_ENCHANTMENTS.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getTag("StoredEnchantments");
|
||||
if (previous != null) {
|
||||
networkData.put("StoredEnchantments", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put("StoredEnchantments", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (VersionHelper.isOrAbove1_20_5()) {
|
||||
Tag previous = item.getSparrowNBTComponent(ComponentKeys.ENCHANTMENTS);
|
||||
if (previous != null) {
|
||||
networkData.put(ComponentKeys.ENCHANTMENTS.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put(ComponentKeys.ENCHANTMENTS.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getTag("Enchantments");
|
||||
if (previous != null) {
|
||||
networkData.put("Enchantments", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put("Enchantments", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package net.momirealms.craftengine.core.item.modifier;
|
||||
|
||||
import net.momirealms.craftengine.core.item.*;
|
||||
import net.momirealms.craftengine.core.item.data.Enchantment;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class EnchantmentsModifier<I> implements SimpleNetworkItemDataModifier<I> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
private final List<Enchantment> enchantments;
|
||||
|
||||
public EnchantmentsModifier(List<Enchantment> enchantments) {
|
||||
this.enchantments = enchantments;
|
||||
}
|
||||
|
||||
public List<Enchantment> enchantments() {
|
||||
return enchantments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
return ItemDataModifiers.ENCHANTMENTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> apply(Item<I> item, ItemBuildContext context) {
|
||||
if (item.vanillaId().equals(ItemKeys.ENCHANTED_BOOK)) {
|
||||
return item.setStoredEnchantments(this.enchantments);
|
||||
} else {
|
||||
return item.setEnchantments(this.enchantments);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Key componentType(Item<I> item, ItemBuildContext context) {
|
||||
return item.vanillaId().equals(ItemKeys.ENCHANTED_BOOK) ? ComponentKeys.STORED_ENCHANTMENTS : ComponentKeys.ENCHANTMENTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object[] nbtPath(Item<I> item, ItemBuildContext context) {
|
||||
return item.vanillaId().equals(ItemKeys.ENCHANTED_BOOK) ? new Object[]{"StoredEnchantments"} : new Object[]{"Enchantments"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nbtPathString(Item<I> item, ItemBuildContext context) {
|
||||
return item.vanillaId().equals(ItemKeys.ENCHANTED_BOOK) ? "StoredEnchantments" : "Enchantments";
|
||||
}
|
||||
|
||||
public static class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
Map<String, Object> data = ResourceConfigUtils.getAsMap(arg, "enchantments");
|
||||
List<Enchantment> enchantments = new ArrayList<>();
|
||||
for (Map.Entry<String, Object> e : data.entrySet()) {
|
||||
if (e.getValue() instanceof Number number) {
|
||||
enchantments.add(new Enchantment(Key.of(e.getKey()), number.intValue()));
|
||||
}
|
||||
}
|
||||
return new EnchantmentsModifier<>(enchantments);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,24 +3,26 @@ package net.momirealms.craftengine.core.item.modifier;
|
||||
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||
import net.momirealms.craftengine.core.item.setting.EquipmentData;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class EquippableAssetIdModifier<I> implements ItemDataModifier<I> {
|
||||
public class EquippableAssetIdModifier<I> implements SimpleNetworkItemDataModifier<I> {
|
||||
private final Key assetId;
|
||||
|
||||
public EquippableAssetIdModifier(Key assetsId) {
|
||||
this.assetId = assetsId;
|
||||
}
|
||||
|
||||
public Key assetId() {
|
||||
return assetId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "equippable-asset-id";
|
||||
public Key type() {
|
||||
return ItemDataModifiers.EQUIPPABLE_ASSET_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -39,13 +41,7 @@ public class EquippableAssetIdModifier<I> implements ItemDataModifier<I> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> prepareNetworkItem(Item<I> item, ItemBuildContext context, CompoundTag networkData) {
|
||||
Tag previous = item.getSparrowNBTComponent(ComponentKeys.EQUIPPABLE);
|
||||
if (previous != null) {
|
||||
networkData.put(ComponentKeys.EQUIPPABLE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put(ComponentKeys.EQUIPPABLE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
return item;
|
||||
public @Nullable Key componentType(Item<I> item, ItemBuildContext context) {
|
||||
return ComponentKeys.EQUIPPABLE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,49 @@
|
||||
package net.momirealms.craftengine.core.item.modifier;
|
||||
|
||||
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.ItemDataModifierFactory;
|
||||
import net.momirealms.craftengine.core.item.setting.EquipmentData;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class EquippableModifier<I> implements ItemDataModifier<I> {
|
||||
import java.util.Map;
|
||||
|
||||
public class EquippableModifier<I> implements SimpleNetworkItemDataModifier<I> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
private final EquipmentData data;
|
||||
|
||||
public EquippableModifier(EquipmentData data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public EquipmentData data() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "equippable";
|
||||
public Key type() {
|
||||
return ItemDataModifiers.EQUIPPABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> apply(Item<I> item, ItemBuildContext context) {
|
||||
item.equippable(this.data);
|
||||
return item;
|
||||
return item.equippable(this.data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Key componentType(Item<I> item, ItemBuildContext context) {
|
||||
return ComponentKeys.EQUIPPABLE;
|
||||
}
|
||||
|
||||
public static class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
Map<String, Object> data = ResourceConfigUtils.getAsMap(arg, "equippable");
|
||||
return new EquippableModifier<>(EquipmentData.fromMap(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,17 @@ package net.momirealms.craftengine.core.item.modifier;
|
||||
import net.momirealms.craftengine.core.item.ExternalItemSource;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.ItemDataModifierFactory;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public class ExternalModifier<I> implements ItemDataModifier<I> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
private final String id;
|
||||
private final ExternalItemSource<I> provider;
|
||||
|
||||
@@ -14,9 +22,17 @@ public class ExternalModifier<I> implements ItemDataModifier<I> {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
public String id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public ExternalItemSource<I> source() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "external";
|
||||
public Key type() {
|
||||
return ItemDataModifiers.EXTERNAL;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -31,4 +47,17 @@ public class ExternalModifier<I> implements ItemDataModifier<I> {
|
||||
item.merge(anotherWrapped);
|
||||
return item;
|
||||
}
|
||||
|
||||
public static class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
Map<String, Object> data = ResourceConfigUtils.getAsMap(arg, "external");
|
||||
String plugin = ResourceConfigUtils.requireNonEmptyStringOrThrow(ResourceConfigUtils.get(data, "plugin", "source"), "warning.config.item.data.external.missing_source");
|
||||
String id = ResourceConfigUtils.requireNonEmptyStringOrThrow(data.get("id"), "warning.config.item.data.external.missing_id");
|
||||
ExternalItemSource<I> provider = (ExternalItemSource<I>) CraftEngine.instance().itemManager().getExternalItemSource(plugin.toLowerCase(Locale.ENGLISH));
|
||||
return new ExternalModifier<>(id, ResourceConfigUtils.requireNonNullOrThrow(provider, () -> new LocalizedResourceConfigException("warning.config.item.data.external.invalid_source", plugin)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,13 +3,15 @@ package net.momirealms.craftengine.core.item.modifier;
|
||||
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
import net.momirealms.craftengine.core.item.ItemDataModifierFactory;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class FoodModifier<I> implements ItemDataModifier<I> {
|
||||
public class FoodModifier<I> implements SimpleNetworkItemDataModifier<I> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
private final int nutrition;
|
||||
private final float saturation;
|
||||
private final boolean canAlwaysEat;
|
||||
@@ -20,9 +22,21 @@ public class FoodModifier<I> implements ItemDataModifier<I> {
|
||||
this.saturation = saturation;
|
||||
}
|
||||
|
||||
public boolean canAlwaysEat() {
|
||||
return canAlwaysEat;
|
||||
}
|
||||
|
||||
public int nutrition() {
|
||||
return nutrition;
|
||||
}
|
||||
|
||||
public float saturation() {
|
||||
return saturation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "food";
|
||||
public Key type() {
|
||||
return ItemDataModifiers.FOOD;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -36,13 +50,18 @@ public class FoodModifier<I> implements ItemDataModifier<I> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> prepareNetworkItem(Item<I> item, ItemBuildContext context, CompoundTag networkData) {
|
||||
Tag previous = item.getSparrowNBTComponent(ComponentKeys.FOOD);
|
||||
if (previous != null) {
|
||||
networkData.put(ComponentKeys.FOOD.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put(ComponentKeys.FOOD.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
public @Nullable Key componentType(Item<I> item, ItemBuildContext context) {
|
||||
return ComponentKeys.FOOD;
|
||||
}
|
||||
|
||||
public static class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
Map<String, Object> data = ResourceConfigUtils.getAsMap(arg, "food");
|
||||
int nutrition = ResourceConfigUtils.getAsInt(data.get("nutrition"), "nutrition");
|
||||
float saturation = ResourceConfigUtils.getAsFloat(data.get("saturation"), "saturation");
|
||||
return new FoodModifier<>(nutrition, saturation, ResourceConfigUtils.getAsBoolean(data.getOrDefault("can-always-eat", false), "can-always-eat"));
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
package net.momirealms.craftengine.core.item.modifier;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||
import net.momirealms.craftengine.core.item.*;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
@@ -19,7 +16,19 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class HideTooltipModifier<I> implements ItemDataModifier<I> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
public static final Map<Key, Integer> TO_LEGACY;
|
||||
public static final List<Key> COMPONENTS = List.of(
|
||||
ComponentKeys.UNBREAKABLE,
|
||||
ComponentKeys.ENCHANTMENTS,
|
||||
ComponentKeys.STORED_ENCHANTMENTS,
|
||||
ComponentKeys.CAN_PLACE_ON,
|
||||
ComponentKeys.CAN_BREAK,
|
||||
ComponentKeys.ATTRIBUTE_MODIFIERS,
|
||||
ComponentKeys.DYED_COLOR,
|
||||
ComponentKeys.TRIM,
|
||||
ComponentKeys.JUKEBOX_PLAYABLE
|
||||
);
|
||||
static {
|
||||
ImmutableMap.Builder<Key, Integer> builder = ImmutableMap.builder();
|
||||
builder.put(ComponentKeys.ENCHANTMENTS, 1);
|
||||
@@ -52,13 +61,24 @@ public class HideTooltipModifier<I> implements ItemDataModifier<I> {
|
||||
if (components.isEmpty()) {
|
||||
this.applier = new DummyApplier<>();
|
||||
} else if (components.size() == 1) {
|
||||
this.applier = new SemiModernApplier<>(components.getFirst());
|
||||
if (COMPONENTS.contains(components.getFirst())) {
|
||||
this.applier = new SemiModernApplier<>(components.getFirst());
|
||||
} else {
|
||||
this.applier = new DummyApplier<>();
|
||||
}
|
||||
} else {
|
||||
List<Applier<I>> appliers = new ArrayList<>();
|
||||
for (Key key : components) {
|
||||
if (!COMPONENTS.contains(key)) continue;
|
||||
appliers.add(new SemiModernApplier<>(key));
|
||||
}
|
||||
this.applier = new CompoundApplier<>(appliers);
|
||||
if (appliers.isEmpty()) {
|
||||
this.applier = new DummyApplier<>();
|
||||
} else if (appliers.size() == 1) {
|
||||
this.applier = appliers.getFirst();
|
||||
} else {
|
||||
this.applier = new CompoundApplier<>(appliers);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.applier = new LegacyApplier<>(components);
|
||||
@@ -66,7 +86,7 @@ public class HideTooltipModifier<I> implements ItemDataModifier<I> {
|
||||
}
|
||||
|
||||
public List<Key> components() {
|
||||
return components;
|
||||
return this.components;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -105,8 +125,8 @@ public class HideTooltipModifier<I> implements ItemDataModifier<I> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "hide-tooltip";
|
||||
public Key type() {
|
||||
return ItemDataModifiers.HIDE_TOOLTIP;
|
||||
}
|
||||
|
||||
public interface Applier<I> {
|
||||
@@ -134,10 +154,6 @@ public class HideTooltipModifier<I> implements ItemDataModifier<I> {
|
||||
if (previous instanceof CompoundTag compoundTag) {
|
||||
compoundTag.putBoolean("show_in_tooltip", false);
|
||||
item.setNBTComponent(this.component, compoundTag);
|
||||
} else {
|
||||
CompoundTag compoundTag = new CompoundTag();
|
||||
compoundTag.putBoolean("show_in_tooltip", false);
|
||||
item.setNBTComponent(this.component, compoundTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -215,4 +231,13 @@ public class HideTooltipModifier<I> implements ItemDataModifier<I> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
List<Key> components = MiscUtils.getAsStringList(arg).stream().map(Key::of).toList();
|
||||
return new HideTooltipModifier<>(components);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,13 @@ public class IdModifier<I> implements ItemDataModifier<I> {
|
||||
this.argument = argument;
|
||||
}
|
||||
|
||||
public Key identifier() {
|
||||
return argument;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "id";
|
||||
public Key type() {
|
||||
return ItemDataModifiers.ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,11 +2,12 @@ package net.momirealms.craftengine.core.item.modifier;
|
||||
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
|
||||
public interface ItemDataModifier<I> {
|
||||
|
||||
String name();
|
||||
Key type();
|
||||
|
||||
Item<I> apply(Item<I> item, ItemBuildContext context);
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
package net.momirealms.craftengine.core.item.modifier;
|
||||
|
||||
import net.momirealms.craftengine.core.item.ItemDataModifierFactory;
|
||||
import net.momirealms.craftengine.core.item.modifier.lore.DynamicLoreModifier;
|
||||
import net.momirealms.craftengine.core.item.modifier.lore.LoreModifier;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.registry.Registries;
|
||||
import net.momirealms.craftengine.core.registry.WritableRegistry;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceKey;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
|
||||
public final class ItemDataModifiers {
|
||||
private ItemDataModifiers() {}
|
||||
|
||||
public static final Key ITEM_MODEL = Key.of("craftengine:item-model");
|
||||
public static final Key ID = Key.of("craftengine:id");
|
||||
public static final Key HIDE_TOOLTIP = Key.of("craftengine:hide-tooltip");
|
||||
public static final Key FOOD = Key.of("craftengine:food");
|
||||
public static final Key EXTERNAL = Key.of("craftengine:external");
|
||||
public static final Key EQUIPPABLE = Key.of("craftengine:equippable");
|
||||
public static final Key EQUIPPABLE_ASSET_ID = Key.of("craftengine:equippable-asset-id");
|
||||
public static final Key ENCHANTMENT = Key.of("craftengine:enchantment");
|
||||
public static final Key ENCHANTMENTS = Key.of("craftengine:enchantments");
|
||||
public static final Key DYED_COLOR = Key.of("craftengine:dyed-color");
|
||||
public static final Key DISPLAY_NAME = Key.of("craftengine:display-name");
|
||||
public static final Key CUSTOM_NAME = Key.of("craftengine:custom-name");
|
||||
public static final Key CUSTOM_MODEL_DATA = Key.of("craftengine:custom-model-data");
|
||||
public static final Key COMPONENTS = Key.of("craftengine:components");
|
||||
public static final Key ATTRIBUTE_MODIFIERS = Key.of("craftengine:attribute-modifiers");
|
||||
public static final Key ATTRIBUTES = Key.of("craftengine:attributes");
|
||||
public static final Key ARGUMENTS = Key.of("craftengine:arguments");
|
||||
public static final Key ITEM_NAME = Key.of("craftengine:item-name");
|
||||
public static final Key JUKEBOX_PLAYABLE = Key.of("craftengine:jukebox-playable");
|
||||
public static final Key REMOVE_COMPONENTS = Key.of("craftengine:remove-components");
|
||||
public static final Key TAGS = Key.of("craftengine:tags");
|
||||
public static final Key NBT = Key.of("craftengine:nbt");
|
||||
public static final Key TOOLTIP_STYLE = Key.of("craftengine:tooltip-style");
|
||||
public static final Key TRIM = Key.of("craftengine:trim");
|
||||
public static final Key LORE = Key.of("craftengine:lore");
|
||||
public static final Key UNBREAKABLE = Key.of("craftengine:unbreakable");
|
||||
public static final Key DYNAMIC_LORE = Key.of("craftengine:dynamic-lore");
|
||||
|
||||
public static <T> void register(Key key, ItemDataModifierFactory<T> factory) {
|
||||
((WritableRegistry<ItemDataModifierFactory<?>>) BuiltInRegistries.ITEM_DATA_MODIFIER_FACTORY)
|
||||
.register(ResourceKey.create(Registries.ITEM_DATA_MODIFIER_FACTORY.location(), key), factory);
|
||||
}
|
||||
|
||||
public static void init() {}
|
||||
|
||||
static {
|
||||
register(EXTERNAL, ExternalModifier.FACTORY);
|
||||
register(LORE, LoreModifier.FACTORY);
|
||||
register(DYNAMIC_LORE, DynamicLoreModifier.FACTORY);
|
||||
register(DYED_COLOR, DyedColorModifier.FACTORY);
|
||||
register(TAGS, TagsModifier.FACTORY);
|
||||
register(NBT, TagsModifier.FACTORY);
|
||||
register(ATTRIBUTE_MODIFIERS, AttributeModifiersModifier.FACTORY);
|
||||
register(ATTRIBUTES, AttributeModifiersModifier.FACTORY);
|
||||
register(CUSTOM_MODEL_DATA, CustomModelDataModifier.FACTORY);
|
||||
register(UNBREAKABLE, UnbreakableModifier.FACTORY);
|
||||
register(ENCHANTMENT, EnchantmentsModifier.FACTORY);
|
||||
register(ENCHANTMENTS, EnchantmentsModifier.FACTORY);
|
||||
register(TRIM, TrimModifier.FACTORY);
|
||||
register(HIDE_TOOLTIP, HideTooltipModifier.FACTORY);
|
||||
register(ARGUMENTS, ArgumentsModifier.FACTORY);
|
||||
if (VersionHelper.isOrAbove1_20_5()) {
|
||||
register(CUSTOM_NAME, CustomNameModifier.FACTORY);
|
||||
register(ITEM_NAME, ItemNameModifier.FACTORY);
|
||||
register(DISPLAY_NAME, ItemNameModifier.FACTORY);
|
||||
register(COMPONENTS, ComponentsModifier.FACTORY);
|
||||
register(REMOVE_COMPONENTS, RemoveComponentModifier.FACTORY);
|
||||
register(FOOD, FoodModifier.FACTORY);
|
||||
} else {
|
||||
register(CUSTOM_NAME, CustomNameModifier.FACTORY);
|
||||
register(ITEM_NAME, CustomNameModifier.FACTORY);
|
||||
register(DISPLAY_NAME, CustomNameModifier.FACTORY);
|
||||
}
|
||||
if (VersionHelper.isOrAbove1_21()) {
|
||||
register(JUKEBOX_PLAYABLE, JukeboxSongModifier.FACTORY);
|
||||
}
|
||||
if (VersionHelper.isOrAbove1_21_2()) {
|
||||
register(TOOLTIP_STYLE, TooltipStyleModifier.FACTORY);
|
||||
register(ITEM_MODEL, ItemModelModifier.FACTORY);
|
||||
register(EQUIPPABLE, EquippableModifier.FACTORY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,37 +3,43 @@ package net.momirealms.craftengine.core.item.modifier;
|
||||
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||
import net.momirealms.craftengine.core.item.ItemDataModifierFactory;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ItemModelModifier<I> implements ItemDataModifier<I> {
|
||||
public class ItemModelModifier<I> implements SimpleNetworkItemDataModifier<I> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
private final Key data;
|
||||
|
||||
public ItemModelModifier(Key data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public Key data() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "item-model";
|
||||
public Key type() {
|
||||
return ItemDataModifiers.ITEM_MODEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> apply(Item<I> item, ItemBuildContext context) {
|
||||
item.itemModel(this.data.toString());
|
||||
return item;
|
||||
return item.itemModel(this.data.asString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> prepareNetworkItem(Item<I> item, ItemBuildContext context, CompoundTag networkData) {
|
||||
Tag previous = item.getSparrowNBTComponent(ComponentKeys.ITEM_MODEL);
|
||||
if (previous != null) {
|
||||
networkData.put(ComponentKeys.ITEM_MODEL.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put(ComponentKeys.ITEM_MODEL.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
public @Nullable Key componentType(Item<I> item, ItemBuildContext context) {
|
||||
return ComponentKeys.ITEM_MODEL;
|
||||
}
|
||||
|
||||
public static class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
String id = arg.toString();
|
||||
return new ItemModelModifier<>(Key.of(id));
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,22 +3,26 @@ package net.momirealms.craftengine.core.item.modifier;
|
||||
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||
import net.momirealms.craftengine.core.item.ItemDataModifierFactory;
|
||||
import net.momirealms.craftengine.core.util.AdventureHelper;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ItemNameModifier<I> implements ItemDataModifier<I> {
|
||||
public class ItemNameModifier<I> implements SimpleNetworkItemDataModifier<I> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
private final String argument;
|
||||
|
||||
public ItemNameModifier(String argument) {
|
||||
this.argument = argument;
|
||||
}
|
||||
|
||||
public String itemName() {
|
||||
return argument;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "item-name";
|
||||
public Key type() {
|
||||
return ItemDataModifiers.ITEM_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -28,22 +32,26 @@ public class ItemNameModifier<I> implements ItemDataModifier<I> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> prepareNetworkItem(Item<I> item, ItemBuildContext context, CompoundTag networkData) {
|
||||
if (VersionHelper.isOrAbove1_20_5()) {
|
||||
Tag previous = item.getSparrowNBTComponent(ComponentKeys.ITEM_NAME);
|
||||
if (previous != null) {
|
||||
networkData.put(ComponentKeys.ITEM_NAME.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put(ComponentKeys.ITEM_NAME.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getTag("display", "Name");
|
||||
if (previous != null) {
|
||||
networkData.put("display.Name", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put("display.Name", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
public @Nullable Key componentType(Item<I> item, ItemBuildContext context) {
|
||||
return ComponentKeys.ITEM_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object[] nbtPath(Item<I> item, ItemBuildContext context) {
|
||||
return new Object[]{"display", "Name"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nbtPathString(Item<I> item, ItemBuildContext context) {
|
||||
return "display.Name";
|
||||
}
|
||||
|
||||
public static class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
String name = arg.toString();
|
||||
return new ItemNameModifier<>(name);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,18 +2,25 @@ package net.momirealms.craftengine.core.item.modifier;
|
||||
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.ItemDataModifierFactory;
|
||||
import net.momirealms.craftengine.core.item.data.JukeboxPlayable;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
public class JukeboxSongModifier<I> implements ItemDataModifier<I> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
private final JukeboxPlayable song;
|
||||
|
||||
public JukeboxSongModifier(JukeboxPlayable song) {
|
||||
this.song = song;
|
||||
}
|
||||
|
||||
public JukeboxPlayable song() {
|
||||
return song;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "jukebox-playable";
|
||||
public Key type() {
|
||||
return ItemDataModifiers.JUKEBOX_PLAYABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -21,4 +28,13 @@ public class JukeboxSongModifier<I> implements ItemDataModifier<I> {
|
||||
item.jukeboxSong(this.song);
|
||||
return item;
|
||||
}
|
||||
|
||||
public static class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
String song = arg.toString();
|
||||
return new JukeboxSongModifier<>(new JukeboxPlayable(song, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
package net.momirealms.craftengine.core.item.modifier;
|
||||
|
||||
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.util.AdventureHelper;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class LoreModifier<I> implements ItemDataModifier<I> {
|
||||
private final List<String> argument;
|
||||
|
||||
public LoreModifier(List<String> argument) {
|
||||
if (Config.addNonItalicTag()) {
|
||||
List<String> processed = new ArrayList<>(argument.size());
|
||||
for (String arg : argument) {
|
||||
if (arg.startsWith("<!i>")) {
|
||||
processed.add(arg);
|
||||
} else {
|
||||
processed.add("<!i>" + arg);
|
||||
}
|
||||
}
|
||||
this.argument = processed;
|
||||
} else {
|
||||
this.argument = argument;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "lore";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> apply(Item<I> item, ItemBuildContext context) {
|
||||
item.loreComponent(this.argument.stream().map(it -> AdventureHelper.miniMessage().deserialize(it, context.tagResolvers())).toList());
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> prepareNetworkItem(Item<I> item, ItemBuildContext context, CompoundTag networkData) {
|
||||
if (VersionHelper.isOrAbove1_20_5()) {
|
||||
Tag previous = item.getSparrowNBTComponent(ComponentKeys.LORE);
|
||||
if (previous != null) {
|
||||
networkData.put(ComponentKeys.LORE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put(ComponentKeys.LORE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getTag("display", "Lore");
|
||||
if (previous != null) {
|
||||
networkData.put("display.Lore", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put("display.Lore", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,10 @@ package net.momirealms.craftengine.core.item.modifier;
|
||||
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.ItemDataModifierFactory;
|
||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
|
||||
@@ -10,19 +13,20 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class RemoveComponentModifier<I> implements ItemDataModifier<I> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
private final List<String> arguments;
|
||||
|
||||
public RemoveComponentModifier(List<String> arguments) {
|
||||
this.arguments = arguments;
|
||||
}
|
||||
|
||||
public List<String> arguments() {
|
||||
public List<String> components() {
|
||||
return Collections.unmodifiableList(this.arguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "remove-components";
|
||||
public Key type() {
|
||||
return ItemDataModifiers.REMOVE_COMPONENTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -43,4 +47,13 @@ public class RemoveComponentModifier<I> implements ItemDataModifier<I> {
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
public static class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
List<String> data = MiscUtils.getAsStringList(arg);
|
||||
return new RemoveComponentModifier<>(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package net.momirealms.craftengine.core.item.modifier;
|
||||
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface SimpleNetworkItemDataModifier<I> extends ItemDataModifier<I> {
|
||||
|
||||
@Override
|
||||
default Item<I> prepareNetworkItem(Item<I> item, ItemBuildContext context, CompoundTag networkData) {
|
||||
if (VersionHelper.COMPONENT_RELEASE) {
|
||||
Key componentType= componentType(item, context);
|
||||
if (componentType != null) {
|
||||
Tag previous = item.getSparrowNBTComponent(componentType);
|
||||
if (previous != null) {
|
||||
networkData.put(componentType.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put(componentType.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Object[] path = nbtPath(item, context);
|
||||
if (path != null) {
|
||||
Tag previous = item.getTag(path);
|
||||
if (previous != null) {
|
||||
networkData.put(nbtPathString(item, context), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put(nbtPathString(item, context), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
default Key componentType(Item<I> item, ItemBuildContext context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
default Object[] nbtPath(Item<I> item, ItemBuildContext context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
default String nbtPathString(Item<I> item, ItemBuildContext context) {
|
||||
Object[] path = nbtPath(item, context);
|
||||
if (path != null && path.length > 0) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (Object object : path) {
|
||||
builder.append(object.toString());
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,7 @@
|
||||
package net.momirealms.craftengine.core.item.modifier;
|
||||
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.TypeUtils;
|
||||
import net.momirealms.craftengine.core.item.*;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
|
||||
@@ -12,19 +9,20 @@ import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class TagsModifier<I> implements ItemDataModifier<I> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
private final Map<String, Object> arguments;
|
||||
|
||||
public TagsModifier(Map<String, Object> arguments) {
|
||||
this.arguments = mapToMap(arguments);
|
||||
}
|
||||
|
||||
public Map<String, Object> arguments() {
|
||||
public Map<String, Object> tags() {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "tags";
|
||||
public Key type() {
|
||||
return ItemDataModifiers.TAGS;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -40,12 +38,21 @@ public class TagsModifier<I> implements ItemDataModifier<I> {
|
||||
// TODO NOT PERFECT
|
||||
@Override
|
||||
public Item<I> prepareNetworkItem(Item<I> item, ItemBuildContext context, CompoundTag networkData) {
|
||||
for (Map.Entry<String, Object> entry : this.arguments.entrySet()) {
|
||||
Tag previous = item.getTag(entry.getKey());
|
||||
if (VersionHelper.isOrAbove1_20_5()) {
|
||||
Tag previous = item.getSparrowNBTComponent(ComponentKeys.CUSTOM_DATA);
|
||||
if (previous != null) {
|
||||
networkData.put(entry.getKey(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
networkData.put(ComponentKeys.CUSTOM_DATA.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put(entry.getKey(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
networkData.put(ComponentKeys.CUSTOM_DATA.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
for (Map.Entry<String, Object> entry : this.arguments.entrySet()) {
|
||||
Tag previous = item.getTag(entry.getKey());
|
||||
if (previous != null) {
|
||||
networkData.put(entry.getKey(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put(entry.getKey(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
}
|
||||
}
|
||||
return item;
|
||||
@@ -124,4 +131,12 @@ public class TagsModifier<I> implements ItemDataModifier<I> {
|
||||
private record ParsedValue(boolean success, Object result) {
|
||||
static final ParsedValue FAILURE = new ParsedValue(false, null);
|
||||
}
|
||||
|
||||
public static class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
Map<String, Object> data = ResourceConfigUtils.getAsMap(arg, "nbt");
|
||||
return new TagsModifier<>(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,21 +3,25 @@ package net.momirealms.craftengine.core.item.modifier;
|
||||
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||
import net.momirealms.craftengine.core.item.ItemDataModifierFactory;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class TooltipStyleModifier<I> implements ItemDataModifier<I> {
|
||||
public class TooltipStyleModifier<I> implements SimpleNetworkItemDataModifier<I> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
private final Key argument;
|
||||
|
||||
public TooltipStyleModifier(Key argument) {
|
||||
this.argument = argument;
|
||||
}
|
||||
|
||||
public Key tooltipStyle() {
|
||||
return this.argument;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "tooltip-style";
|
||||
public Key type() {
|
||||
return ItemDataModifiers.TOOLTIP_STYLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -27,13 +31,16 @@ public class TooltipStyleModifier<I> implements ItemDataModifier<I> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> prepareNetworkItem(Item<I> item, ItemBuildContext context, CompoundTag networkData) {
|
||||
Tag previous = item.getSparrowNBTComponent(ComponentKeys.TOOLTIP_STYLE);
|
||||
if (previous != null) {
|
||||
networkData.put(ComponentKeys.TOOLTIP_STYLE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put(ComponentKeys.TOOLTIP_STYLE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
public @Nullable Key componentType(Item<I> item, ItemBuildContext context) {
|
||||
return ComponentKeys.TOOLTIP_STYLE;
|
||||
}
|
||||
|
||||
public static class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
String id = arg.toString();
|
||||
return new TooltipStyleModifier<>(Key.of(id));
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,17 @@ package net.momirealms.craftengine.core.item.modifier;
|
||||
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||
import net.momirealms.craftengine.core.item.ItemDataModifierFactory;
|
||||
import net.momirealms.craftengine.core.item.data.Trim;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class TrimModifier<I> implements ItemDataModifier<I> {
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public class TrimModifier<I> implements SimpleNetworkItemDataModifier<I> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
private final Key material;
|
||||
private final Key pattern;
|
||||
|
||||
@@ -19,34 +22,47 @@ public class TrimModifier<I> implements ItemDataModifier<I> {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
public Key material() {
|
||||
return material;
|
||||
}
|
||||
|
||||
public Key pattern() {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "trim";
|
||||
public Key type() {
|
||||
return ItemDataModifiers.TRIM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> apply(Item<I> item, ItemBuildContext context) {
|
||||
item.trim(new Trim(this.pattern, this.material));
|
||||
return item;
|
||||
return item.trim(new Trim(this.pattern, this.material));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> prepareNetworkItem(Item<I> item, ItemBuildContext context, CompoundTag networkData) {
|
||||
if (VersionHelper.isOrAbove1_20_5()) {
|
||||
Tag previous = item.getSparrowNBTComponent(ComponentKeys.TRIM);
|
||||
if (previous != null) {
|
||||
networkData.put(ComponentKeys.TRIM.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put(ComponentKeys.TRIM.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getTag("Trim");
|
||||
if (previous != null) {
|
||||
networkData.put("Trim", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put("Trim", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
public @Nullable Key componentType(Item<I> item, ItemBuildContext context) {
|
||||
return ComponentKeys.TRIM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object[] nbtPath(Item<I> item, ItemBuildContext context) {
|
||||
return new Object[]{"Trim"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nbtPathString(Item<I> item, ItemBuildContext context) {
|
||||
return "Trim";
|
||||
}
|
||||
|
||||
public static class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
Map<String, Object> data = ResourceConfigUtils.getAsMap(arg, "trim");
|
||||
String material = data.get("material").toString().toLowerCase(Locale.ENGLISH);
|
||||
String pattern = data.get("pattern").toString().toLowerCase(Locale.ENGLISH);
|
||||
return new TrimModifier<>(Key.of(material), Key.of(pattern));
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,21 +3,26 @@ package net.momirealms.craftengine.core.item.modifier;
|
||||
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.NetworkItemHandler;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
import net.momirealms.craftengine.core.item.ItemDataModifierFactory;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class UnbreakableModifier<I> implements ItemDataModifier<I> {
|
||||
public class UnbreakableModifier<I> implements SimpleNetworkItemDataModifier<I> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
private final boolean argument;
|
||||
|
||||
public UnbreakableModifier(boolean argument) {
|
||||
this.argument = argument;
|
||||
}
|
||||
|
||||
public boolean unbreakable() {
|
||||
return argument;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "unbreakable";
|
||||
public Key type() {
|
||||
return ItemDataModifiers.UNBREAKABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -27,22 +32,26 @@ public class UnbreakableModifier<I> implements ItemDataModifier<I> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> prepareNetworkItem(Item<I> item, ItemBuildContext context, CompoundTag networkData) {
|
||||
if (VersionHelper.isOrAbove1_20_5()) {
|
||||
Tag previous = item.getSparrowNBTComponent(ComponentKeys.UNBREAKABLE);
|
||||
if (previous != null) {
|
||||
networkData.put(ComponentKeys.UNBREAKABLE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put(ComponentKeys.UNBREAKABLE.asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
} else {
|
||||
Tag previous = item.getTag("Unbreakable");
|
||||
if (previous != null) {
|
||||
networkData.put("Unbreakable", NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous));
|
||||
} else {
|
||||
networkData.put("Unbreakable", NetworkItemHandler.pack(NetworkItemHandler.Operation.REMOVE));
|
||||
}
|
||||
public @Nullable Key componentType(Item<I> item, ItemBuildContext context) {
|
||||
return ComponentKeys.UNBREAKABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object[] nbtPath(Item<I> item, ItemBuildContext context) {
|
||||
return new Object[]{"Unbreakable"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nbtPathString(Item<I> item, ItemBuildContext context) {
|
||||
return "Unbreakable";
|
||||
}
|
||||
|
||||
public static class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
boolean value = ResourceConfigUtils.getAsBoolean(arg, "unbreakable");
|
||||
return new UnbreakableModifier<>(value);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package net.momirealms.craftengine.core.item.modifier.lore;
|
||||
|
||||
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.ItemDataModifierFactory;
|
||||
import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
|
||||
import net.momirealms.craftengine.core.item.modifier.ItemDataModifiers;
|
||||
import net.momirealms.craftengine.core.item.modifier.SimpleNetworkItemDataModifier;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class DynamicLoreModifier<I> implements SimpleNetworkItemDataModifier<I> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
public static final String CONTEXT_TAG_KEY = "craftengine:display_context";
|
||||
private final Map<String, LoreModifier<I>> displayContexts;
|
||||
private final LoreModifier<I> defaultModifier;
|
||||
|
||||
public DynamicLoreModifier(Map<String, LoreModifier<I>> displayContexts) {
|
||||
this.displayContexts = displayContexts;
|
||||
this.defaultModifier = displayContexts.values().iterator().next();
|
||||
}
|
||||
|
||||
public Map<String, LoreModifier<I>> displayContexts() {
|
||||
return displayContexts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
return ItemDataModifiers.DYNAMIC_LORE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> apply(Item<I> item, ItemBuildContext context) {
|
||||
String displayContext = Optional.ofNullable(item.getJavaTag(CONTEXT_TAG_KEY)).orElse(this.defaultModifier).toString();
|
||||
LoreModifier<I> lore = this.displayContexts.get(displayContext);
|
||||
if (lore == null) {
|
||||
lore = this.defaultModifier;
|
||||
}
|
||||
return lore.apply(item, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key componentType(Item<I> item, ItemBuildContext context) {
|
||||
return ComponentKeys.LORE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] nbtPath(Item<I> item, ItemBuildContext context) {
|
||||
return new Object[]{"display", "Lore"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nbtPathString(Item<I> item, ItemBuildContext context) {
|
||||
return "display.Lore";
|
||||
}
|
||||
|
||||
public static class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
Map<String, LoreModifier<I>> dynamicLore = new LinkedHashMap<>();
|
||||
if (arg instanceof Map<?, ?> map) {
|
||||
for (Map.Entry<?, ?> entry : map.entrySet()) {
|
||||
dynamicLore.put(entry.getKey().toString(), LoreModifier.createLoreModifier(entry.getValue()));
|
||||
}
|
||||
}
|
||||
return new DynamicLoreModifier<>(dynamicLore);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package net.momirealms.craftengine.core.item.modifier.lore;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.util.AdventureHelper;
|
||||
import net.momirealms.craftengine.core.util.TriFunction;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
// todo 可以考虑未来添加条件系统
|
||||
public record LoreModification(Operation operation, boolean split, String[] content) {
|
||||
|
||||
public Stream<Component> apply(Stream<Component> lore, ItemBuildContext context) {
|
||||
return this.operation.function.apply(lore, context, this);
|
||||
}
|
||||
|
||||
public Stream<Component> parseAsStream(ItemBuildContext context) {
|
||||
Stream<Component> parsed = Arrays.stream(this.content).map(string -> AdventureHelper.miniMessage().deserialize(string, context.tagResolvers()));
|
||||
return this.split ? parsed.map(AdventureHelper::splitLines).flatMap(List::stream) : parsed;
|
||||
}
|
||||
|
||||
public List<Component> parseAsList(ItemBuildContext context) {
|
||||
return this.parseAsStream(context).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public enum Operation {
|
||||
APPEND((s, c, modification) -> Stream.concat(s, modification.parseAsStream(c))),
|
||||
PREPEND((s, c, modification) -> Stream.concat(modification.parseAsStream(c), s));
|
||||
|
||||
private final TriFunction<Stream<Component>, ItemBuildContext, LoreModification, Stream<Component>> function;
|
||||
|
||||
Operation(TriFunction<Stream<Component>, ItemBuildContext, LoreModification, Stream<Component>> function) {
|
||||
this.function = function;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package net.momirealms.craftengine.core.item.modifier.lore;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public record LoreModificationHolder(LoreModification modification, int priority) implements Comparable<LoreModificationHolder> {
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull LoreModificationHolder o) {
|
||||
return Integer.compare(priority, o.priority);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
package net.momirealms.craftengine.core.item.modifier.lore;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.ItemDataModifierFactory;
|
||||
import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
|
||||
import net.momirealms.craftengine.core.item.modifier.ItemDataModifiers;
|
||||
import net.momirealms.craftengine.core.item.modifier.SimpleNetworkItemDataModifier;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public sealed interface LoreModifier<I> extends SimpleNetworkItemDataModifier<I>
|
||||
permits LoreModifier.EmptyLoreModifier, LoreModifier.CompositeLoreModifier, LoreModifier.DoubleLoreModifier, LoreModifier.SingleLoreModifier {
|
||||
Factory<?> FACTORY = new Factory<>();
|
||||
|
||||
@Override
|
||||
default Key type() {
|
||||
return ItemDataModifiers.LORE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
default Key componentType(Item<I> item, ItemBuildContext context) {
|
||||
return ComponentKeys.LORE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
default Object[] nbtPath(Item<I> item, ItemBuildContext context) {
|
||||
return new Object[]{"display", "Lore"};
|
||||
}
|
||||
|
||||
@Override
|
||||
default String nbtPathString(Item<I> item, ItemBuildContext context) {
|
||||
return "display.Lore";
|
||||
}
|
||||
|
||||
List<LoreModification> lore();
|
||||
|
||||
class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
return createLoreModifier(arg);
|
||||
}
|
||||
}
|
||||
|
||||
static <I> LoreModifier<I> createLoreModifier(Object arg) {
|
||||
List<Object> rawLoreData = MiscUtils.getAsList(arg, Object.class);
|
||||
String[] rawLore = new String[rawLoreData.size()];
|
||||
label_all_string_check: {
|
||||
for (int i = 0; i < rawLore.length; i++) {
|
||||
Object o = rawLoreData.get(i);
|
||||
if (o instanceof Map<?,?>) {
|
||||
break label_all_string_check;
|
||||
} else {
|
||||
rawLore[i] = o.toString();
|
||||
}
|
||||
}
|
||||
return new SingleLoreModifier<>(new LoreModification(LoreModification.Operation.APPEND, false, rawLore));
|
||||
}
|
||||
|
||||
List<LoreModificationHolder> modifications = new ArrayList<>(rawLoreData.size() + 1);
|
||||
int lastPriority = 0;
|
||||
for (Object o : rawLoreData) {
|
||||
if (o instanceof Map<?,?> complexLore) {
|
||||
String[] content = MiscUtils.getAsStringArray(complexLore.get("content"));
|
||||
LoreModification.Operation operation = ResourceConfigUtils.getAsEnum(Optional.ofNullable(complexLore.get("operation")).map(String::valueOf).orElse(null), LoreModification.Operation.class, LoreModification.Operation.APPEND);
|
||||
lastPriority = Optional.ofNullable(complexLore.get("priority")).map(it -> ResourceConfigUtils.getAsInt(it, "priority")).orElse(lastPriority);
|
||||
boolean split = ResourceConfigUtils.getAsBoolean(complexLore.get("split-lines"), "split-lines");
|
||||
modifications.add(new LoreModificationHolder(new LoreModification(operation, split, content), lastPriority));
|
||||
}
|
||||
}
|
||||
modifications.sort(LoreModificationHolder::compareTo);
|
||||
return switch (modifications.size()) {
|
||||
case 0 -> new EmptyLoreModifier<>();
|
||||
case 1 -> new SingleLoreModifier<>(modifications.get(0).modification());
|
||||
case 2 -> new DoubleLoreModifier<>(modifications.get(0).modification(), modifications.get(1).modification());
|
||||
default -> new CompositeLoreModifier<>(modifications.stream().map(LoreModificationHolder::modification).toArray(LoreModification[]::new));
|
||||
};
|
||||
}
|
||||
|
||||
non-sealed class EmptyLoreModifier<I> implements LoreModifier<I> {
|
||||
|
||||
@Override
|
||||
public Item<I> apply(Item<I> item, ItemBuildContext context) {
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LoreModification> lore() {
|
||||
return List.of();
|
||||
}
|
||||
}
|
||||
|
||||
non-sealed class SingleLoreModifier<I> implements LoreModifier<I> {
|
||||
private final LoreModification modification;
|
||||
|
||||
public SingleLoreModifier(LoreModification modification) {
|
||||
this.modification = modification;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> apply(Item<I> item, ItemBuildContext context) {
|
||||
item.loreComponent(this.modification.parseAsList(context));
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LoreModification> lore() {
|
||||
return List.of(modification);
|
||||
}
|
||||
}
|
||||
|
||||
non-sealed class DoubleLoreModifier<I> implements LoreModifier<I> {
|
||||
private final LoreModification modification1;
|
||||
private final LoreModification modification2;
|
||||
|
||||
public DoubleLoreModifier(LoreModification m1, LoreModification m2) {
|
||||
this.modification1 = m1;
|
||||
this.modification2 = m2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> apply(Item<I> item, ItemBuildContext context) {
|
||||
item.loreComponent(this.modification2.apply(this.modification1.apply(Stream.empty(), context), context).toList());
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LoreModification> lore() {
|
||||
return List.of(modification1, modification2);
|
||||
}
|
||||
}
|
||||
|
||||
non-sealed class CompositeLoreModifier<I> implements LoreModifier<I> {
|
||||
private final LoreModification[] modifications;
|
||||
|
||||
public CompositeLoreModifier(LoreModification... modifications) {
|
||||
this.modifications = modifications;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<I> apply(Item<I> item, ItemBuildContext context) {
|
||||
item.loreComponent(Arrays.stream(this.modifications).reduce(Stream.<Component>empty(), (stream, modification) -> modification.apply(stream, context), Stream::concat).toList());
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LoreModification> lore() {
|
||||
return Arrays.asList(modifications);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.recipe.result.CustomRecipeResult;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -10,7 +11,7 @@ public abstract class AbstractGroupedRecipe<T> implements FixedResultRecipe<T> {
|
||||
protected final CustomRecipeResult<T> result;
|
||||
|
||||
protected AbstractGroupedRecipe(Key id, String group, CustomRecipeResult<T> result) {
|
||||
this.group = group;
|
||||
this.group = group == null ? "" : group;
|
||||
this.id = id;
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public abstract class AbstractRecipeFactory<T> implements RecipeFactory<T> {
|
||||
|
||||
protected List<String> ingredients(Map<String, Object> arguments) {
|
||||
return MiscUtils.getAsStringList(getIngredientOrThrow(arguments));
|
||||
}
|
||||
|
||||
protected Map<String, Object> ingredientMap(Map<String, Object> arguments) {
|
||||
return MiscUtils.castToMap(getIngredientOrThrow(arguments), true);
|
||||
}
|
||||
|
||||
protected Set<UniqueKey> ingredientHolders(Map<String, Object> arguments) {
|
||||
Set<UniqueKey> holders = new HashSet<>();
|
||||
for (String item : ingredients(arguments)) {
|
||||
if (item.charAt(0) == '#') {
|
||||
holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1))));
|
||||
} else {
|
||||
holders.add(UniqueKey.create(Key.of(item)));
|
||||
}
|
||||
}
|
||||
return holders;
|
||||
}
|
||||
|
||||
protected Object getIngredientOrThrow(Map<String, Object> arguments) {
|
||||
Object ingredient = ResourceConfigUtils.get(arguments, "ingredient", "ingredients");
|
||||
if (ingredient == null) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.missing_ingredient");
|
||||
}
|
||||
return ingredient;
|
||||
}
|
||||
|
||||
protected CookingRecipeCategory cookingRecipeCategory(Map<String, Object> arguments) {
|
||||
CookingRecipeCategory recipeCategory;
|
||||
try {
|
||||
recipeCategory = arguments.containsKey("category") ? CookingRecipeCategory.valueOf(arguments.get("category").toString().toUpperCase(Locale.ENGLISH)) : null;
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.cooking.invalid_category", e, arguments.get("category").toString(), EnumUtils.toString(CookingRecipeCategory.values()));
|
||||
}
|
||||
return recipeCategory;
|
||||
}
|
||||
|
||||
protected CraftingRecipeCategory craftingRecipeCategory(Map<String, Object> arguments) {
|
||||
CraftingRecipeCategory recipeCategory;
|
||||
try {
|
||||
recipeCategory = arguments.containsKey("category") ? CraftingRecipeCategory.valueOf(arguments.get("category").toString().toUpperCase(Locale.ENGLISH)) : null;
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.crafting.invalid_category", e, arguments.get("category").toString(), EnumUtils.toString(CraftingRecipeCategory.values()));
|
||||
}
|
||||
return recipeCategory;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,6 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.item.recipe.input.RecipeInput;
|
||||
import net.momirealms.craftengine.core.item.recipe.vanilla.VanillaRecipeReader;
|
||||
import net.momirealms.craftengine.core.item.recipe.vanilla.reader.VanillaRecipeReader1_20;
|
||||
import net.momirealms.craftengine.core.item.recipe.vanilla.reader.VanillaRecipeReader1_20_5;
|
||||
import net.momirealms.craftengine.core.item.recipe.vanilla.reader.VanillaRecipeReader1_21_2;
|
||||
import net.momirealms.craftengine.core.item.recipe.vanilla.reader.VanillaRecipeReader1_21_5;
|
||||
import net.momirealms.craftengine.core.pack.LoadingSequence;
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
@@ -14,24 +9,20 @@ import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
public abstract class AbstractRecipeManager<T> implements RecipeManager<T> {
|
||||
protected final VanillaRecipeReader recipeReader;
|
||||
protected final Map<Key, List<Recipe<T>>> byType = new HashMap<>();
|
||||
protected final Map<RecipeType, List<Recipe<T>>> byType = new HashMap<>();
|
||||
protected final Map<Key, Recipe<T>> byId = new HashMap<>();
|
||||
protected final Map<Key, List<Recipe<T>>> byResult = new HashMap<>();
|
||||
protected final Map<Key, List<Recipe<T>>> byIngredient = new HashMap<>();
|
||||
protected final Set<Key> dataPackRecipes = new HashSet<>();
|
||||
protected final RecipeParser recipeParser;
|
||||
protected boolean isReloading;
|
||||
|
||||
public AbstractRecipeManager() {
|
||||
this.recipeReader = initVanillaRecipeReader();
|
||||
this.recipeParser = new RecipeParser();
|
||||
}
|
||||
|
||||
@@ -40,18 +31,6 @@ public abstract class AbstractRecipeManager<T> implements RecipeManager<T> {
|
||||
return this.recipeParser;
|
||||
}
|
||||
|
||||
private VanillaRecipeReader initVanillaRecipeReader() {
|
||||
if (VersionHelper.isOrAbove1_21_5()) {
|
||||
return new VanillaRecipeReader1_21_5();
|
||||
} else if (VersionHelper.isOrAbove1_21_2()) {
|
||||
return new VanillaRecipeReader1_21_2();
|
||||
} else if (VersionHelper.isOrAbove1_20_5()) {
|
||||
return new VanillaRecipeReader1_20_5();
|
||||
} else {
|
||||
return new VanillaRecipeReader1_20();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload() {
|
||||
this.dataPackRecipes.clear();
|
||||
@@ -67,44 +46,37 @@ public abstract class AbstractRecipeManager<T> implements RecipeManager<T> {
|
||||
|
||||
@Override
|
||||
public boolean isDataPackRecipe(Key key) {
|
||||
if (this.isReloading) return false;
|
||||
return this.dataPackRecipes.contains(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCustomRecipe(Key key) {
|
||||
if (this.isReloading) return false;
|
||||
return this.byId.containsKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Recipe<T>> recipeById(Key key) {
|
||||
if (this.isReloading) return Optional.empty();
|
||||
return Optional.ofNullable(this.byId.get(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Recipe<T>> recipesByType(Key type) {
|
||||
if (this.isReloading) return List.of();
|
||||
public List<Recipe<T>> recipesByType(RecipeType type) {
|
||||
return this.byType.getOrDefault(type, List.of());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Recipe<T>> recipeByResult(Key result) {
|
||||
if (this.isReloading) return List.of();
|
||||
return this.byResult.getOrDefault(result, List.of());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Recipe<T>> recipeByIngredient(Key ingredient) {
|
||||
if (this.isReloading) return List.of();
|
||||
return this.byIngredient.getOrDefault(ingredient, List.of());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Recipe<T> recipeByInput(Key type, RecipeInput input) {
|
||||
if (this.isReloading) return null;
|
||||
public Recipe<T> recipeByInput(RecipeType type, RecipeInput input) {
|
||||
List<Recipe<T>> recipes = this.byType.get(type);
|
||||
if (recipes == null) return null;
|
||||
for (Recipe<T> recipe : recipes) {
|
||||
@@ -117,8 +89,7 @@ public abstract class AbstractRecipeManager<T> implements RecipeManager<T> {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Recipe<T> recipeByInput(Key type, RecipeInput input, Key lastRecipe) {
|
||||
if (this.isReloading) return null;
|
||||
public Recipe<T> recipeByInput(RecipeType type, RecipeInput input, Key lastRecipe) {
|
||||
if (lastRecipe != null) {
|
||||
Recipe<T> last = this.byId.get(lastRecipe);
|
||||
if (last != null && last.matches(input)) {
|
||||
@@ -128,7 +99,8 @@ public abstract class AbstractRecipeManager<T> implements RecipeManager<T> {
|
||||
return recipeByInput(type, input);
|
||||
}
|
||||
|
||||
protected void registerInternalRecipe(Key id, Recipe<T> recipe) {
|
||||
protected boolean registerInternalRecipe(Key id, Recipe<T> recipe) {
|
||||
if (this.byId.containsKey(id)) return false;
|
||||
this.byType.computeIfAbsent(recipe.type(), k -> new ArrayList<>()).add(recipe);
|
||||
this.byId.put(id, recipe);
|
||||
if (recipe instanceof FixedResultRecipe<?> fixedResult) {
|
||||
@@ -143,6 +115,7 @@ public abstract class AbstractRecipeManager<T> implements RecipeManager<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public class RecipeParser implements ConfigParser {
|
||||
@@ -164,10 +137,9 @@ public abstract class AbstractRecipeManager<T> implements RecipeManager<T> {
|
||||
if (AbstractRecipeManager.this.byId.containsKey(id)) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.duplicate", path, id);
|
||||
}
|
||||
Recipe<T> recipe = RecipeTypes.fromMap(id, section);
|
||||
Recipe<T> recipe = RecipeSerializers.fromMap(id, section);
|
||||
try {
|
||||
registerInternalRecipe(id, recipe);
|
||||
registerPlatformRecipe(id, recipe);
|
||||
} catch (LocalizedResourceConfigException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
@@ -176,7 +148,7 @@ public abstract class AbstractRecipeManager<T> implements RecipeManager<T> {
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void unregisterPlatformRecipe(Key key, boolean isBrewingRecipe);
|
||||
protected abstract void unregisterPlatformRecipeMainThread(Key key, boolean isBrewingRecipe);
|
||||
|
||||
protected abstract void registerPlatformRecipe(Key key, Recipe<T> recipe);
|
||||
protected abstract void registerPlatformRecipeMainThread(Recipe<T> recipe);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.item.CloneableConstantItem;
|
||||
import net.momirealms.craftengine.core.item.CustomItem;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemManager;
|
||||
import net.momirealms.craftengine.core.item.recipe.reader.VanillaRecipeReader;
|
||||
import net.momirealms.craftengine.core.item.recipe.reader.VanillaRecipeReader1_20;
|
||||
import net.momirealms.craftengine.core.item.recipe.reader.VanillaRecipeReader1_20_5;
|
||||
import net.momirealms.craftengine.core.item.recipe.reader.VanillaRecipeReader1_21_2;
|
||||
import net.momirealms.craftengine.core.item.recipe.result.CustomRecipeResult;
|
||||
import net.momirealms.craftengine.core.item.recipe.result.PostProcessor;
|
||||
import net.momirealms.craftengine.core.item.recipe.result.PostProcessors;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public abstract class AbstractRecipeSerializer<T, R extends Recipe<T>> implements RecipeSerializer<T, R> {
|
||||
protected static final VanillaRecipeReader VANILLA_RECIPE_HELPER =
|
||||
VersionHelper.isOrAbove1_21_2() ?
|
||||
new VanillaRecipeReader1_21_2() :
|
||||
VersionHelper.isOrAbove1_20_5() ?
|
||||
new VanillaRecipeReader1_20_5() :
|
||||
new VanillaRecipeReader1_20();
|
||||
|
||||
protected Ingredient<T> singleInputIngredient(Map<String, Object> arguments) {
|
||||
List<String> ingredients = MiscUtils.getAsStringList(getIngredientOrThrow(arguments));
|
||||
return toIngredient(ingredients);
|
||||
}
|
||||
|
||||
// 不确定的类型
|
||||
protected Object getIngredientOrThrow(Map<String, Object> arguments) {
|
||||
Object ingredient = ResourceConfigUtils.get(arguments, "ingredient", "ingredients");
|
||||
if (ingredient == null) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.missing_ingredient");
|
||||
}
|
||||
return ingredient;
|
||||
}
|
||||
|
||||
protected CookingRecipeCategory cookingRecipeCategory(Map<String, Object> arguments) {
|
||||
CookingRecipeCategory recipeCategory;
|
||||
try {
|
||||
recipeCategory = arguments.containsKey("category") ? CookingRecipeCategory.valueOf(arguments.get("category").toString().toUpperCase(Locale.ENGLISH)) : null;
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.cooking.invalid_category", e, arguments.get("category").toString(), EnumUtils.toString(CookingRecipeCategory.values()));
|
||||
}
|
||||
return recipeCategory;
|
||||
}
|
||||
|
||||
protected CraftingRecipeCategory craftingRecipeCategory(Map<String, Object> arguments) {
|
||||
CraftingRecipeCategory recipeCategory;
|
||||
try {
|
||||
recipeCategory = arguments.containsKey("category") ? CraftingRecipeCategory.valueOf(arguments.get("category").toString().toUpperCase(Locale.ENGLISH)) : null;
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.crafting.invalid_category", e, arguments.get("category").toString(), EnumUtils.toString(CraftingRecipeCategory.values()));
|
||||
}
|
||||
return recipeCategory;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
protected CustomRecipeResult<T> parseResult(Map<String, Object> arguments) {
|
||||
Map<String, Object> resultMap = MiscUtils.castToMap(arguments.get("result"), true);
|
||||
if (resultMap == null) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.missing_result");
|
||||
}
|
||||
String id = ResourceConfigUtils.requireNonEmptyStringOrThrow(resultMap.get("id"), "warning.config.recipe.result.missing_id");
|
||||
int count = ResourceConfigUtils.getAsInt(resultMap.getOrDefault("count", 1), "count");
|
||||
List<PostProcessor<T>> processors = ResourceConfigUtils.parseConfigAsList(resultMap.get("post-processors"), PostProcessors::fromMap);
|
||||
return (CustomRecipeResult<T>) new CustomRecipeResult<>(
|
||||
CraftEngine.instance().itemManager().getBuildableItem(Key.of(id)).orElseThrow(() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_result", id)),
|
||||
count,
|
||||
processors.isEmpty() ? null : processors.toArray(new PostProcessor[0])
|
||||
);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected CustomRecipeResult<T> parseResult(DatapackRecipeResult recipeResult) {
|
||||
Item<T> result = (Item<T>) CraftEngine.instance().itemManager().build(recipeResult);
|
||||
return new CustomRecipeResult<>(CloneableConstantItem.of(result), recipeResult.count(), null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected Ingredient<T> toIngredient(String item) {
|
||||
return toIngredient(List.of(item));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected Ingredient<T> toIngredient(List<String> items) {
|
||||
Set<UniqueKey> itemIds = new HashSet<>();
|
||||
Set<UniqueKey> minecraftItemIds = new HashSet<>();
|
||||
ItemManager<T> itemManager = CraftEngine.instance().itemManager();
|
||||
for (String item : items) {
|
||||
if (item.charAt(0) == '#') itemIds.addAll(itemManager.itemIdsByTag(Key.of(item.substring(1))));
|
||||
else {
|
||||
Key itemId = Key.of(item);
|
||||
if (itemManager.getBuildableItem(itemId).isEmpty()) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.invalid_ingredient", item);
|
||||
}
|
||||
itemIds.add(UniqueKey.create(itemId));
|
||||
}
|
||||
}
|
||||
boolean hasCustomItem = false;
|
||||
for (UniqueKey holder : itemIds) {
|
||||
Optional<CustomItem<T>> optionalCustomItem = itemManager.getCustomItem(holder.key());
|
||||
if (optionalCustomItem.isPresent()) {
|
||||
CustomItem<T> customItem = optionalCustomItem.get();
|
||||
if (customItem.isVanillaItem()) {
|
||||
minecraftItemIds.add(holder);
|
||||
} else {
|
||||
minecraftItemIds.add(UniqueKey.create(customItem.material()));
|
||||
hasCustomItem = true;
|
||||
}
|
||||
} else {
|
||||
minecraftItemIds.add(holder);
|
||||
}
|
||||
}
|
||||
return itemIds.isEmpty() ? null : Ingredient.of(itemIds, minecraftItemIds, hasCustomItem);
|
||||
}
|
||||
}
|
||||
@@ -1,35 +1,55 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.item.recipe.result.CustomRecipeResult;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class CustomBlastingRecipe<T> extends CustomCookingRecipe<T> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
public static final Serializer<?> SERIALIZER = new Serializer<>();
|
||||
|
||||
public CustomBlastingRecipe(Key id, CookingRecipeCategory category, String group, Ingredient<T> ingredient, int cookingTime, float experience, CustomRecipeResult<T> result) {
|
||||
super(id, category, group, ingredient, cookingTime, experience, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Key type() {
|
||||
return RecipeTypes.BLASTING;
|
||||
public @NotNull Key serializerType() {
|
||||
return RecipeSerializers.BLASTING;
|
||||
}
|
||||
|
||||
public static class Factory<A> extends AbstractRecipeFactory<A> {
|
||||
@Override
|
||||
public RecipeType type() {
|
||||
return RecipeType.BLASTING;
|
||||
}
|
||||
|
||||
public static class Serializer<A> extends AbstractRecipeSerializer<A, CustomBlastingRecipe<A>> {
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"})
|
||||
@Override
|
||||
public Recipe<A> create(Key id, Map<String, Object> arguments) {
|
||||
String group = arguments.containsKey("group") ? arguments.get("group").toString() : null;
|
||||
int cookingTime = ResourceConfigUtils.getAsInt(arguments.getOrDefault("time", 80), "time");
|
||||
float experience = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("experience", 0.0f), "experience");
|
||||
Set<UniqueKey> holders = ingredientHolders(arguments);
|
||||
return new CustomBlastingRecipe(id, cookingRecipeCategory(arguments), group, Ingredient.of(holders), cookingTime, experience, parseResult(arguments));
|
||||
public CustomBlastingRecipe<A> readMap(Key id, Map<String, Object> arguments) {
|
||||
return new CustomBlastingRecipe(id,
|
||||
cookingRecipeCategory(arguments),
|
||||
arguments.containsKey("group") ? arguments.get("group").toString() : null,
|
||||
singleInputIngredient(arguments),
|
||||
ResourceConfigUtils.getAsInt(arguments.getOrDefault("time", 80), "time"),
|
||||
ResourceConfigUtils.getAsFloat(arguments.getOrDefault("experience", 0.0f), "experience"),
|
||||
parseResult(arguments)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomBlastingRecipe<A> readJson(Key id, JsonObject json) {
|
||||
return new CustomBlastingRecipe<>(id,
|
||||
VANILLA_RECIPE_HELPER.cookingCategory(json),
|
||||
VANILLA_RECIPE_HELPER.readGroup(json),
|
||||
toIngredient(VANILLA_RECIPE_HELPER.singleIngredient(json.get("ingredient"))),
|
||||
VANILLA_RECIPE_HELPER.cookingTime(json),
|
||||
VANILLA_RECIPE_HELPER.cookingExperience(json),
|
||||
parseResult(VANILLA_RECIPE_HELPER.cookingResult(json.get("result")))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.BrewingInput;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.RecipeInput;
|
||||
import net.momirealms.craftengine.core.item.recipe.result.CustomRecipeResult;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
@@ -14,7 +16,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CustomBrewingRecipe<T> implements FixedResultRecipe<T> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
public static final Serializer<?> SERIALIZER = new Serializer<>();
|
||||
private final Key id;
|
||||
private final Ingredient<T> container;
|
||||
private final Ingredient<T> ingredient;
|
||||
@@ -56,8 +58,13 @@ public class CustomBrewingRecipe<T> implements FixedResultRecipe<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Key type() {
|
||||
return RecipeTypes.BREWING;
|
||||
public @NotNull Key serializerType() {
|
||||
return RecipeSerializers.BREWING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeType type() {
|
||||
return RecipeType.BREWING;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -76,10 +83,10 @@ public class CustomBrewingRecipe<T> implements FixedResultRecipe<T> {
|
||||
}
|
||||
|
||||
@SuppressWarnings({"DuplicatedCode"})
|
||||
public static class Factory<A> implements RecipeFactory<A> {
|
||||
public static class Serializer<A> extends AbstractRecipeSerializer<A, CustomBrewingRecipe<A>> {
|
||||
|
||||
@Override
|
||||
public Recipe<A> create(Key id, Map<String, Object> arguments) {
|
||||
public CustomBrewingRecipe<A> readMap(Key id, Map<String, Object> arguments) {
|
||||
List<String> container = MiscUtils.getAsStringList(arguments.get("container"));
|
||||
if (container.isEmpty()) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.brewing.missing_container");
|
||||
@@ -93,5 +100,10 @@ public class CustomBrewingRecipe<T> implements FixedResultRecipe<T> {
|
||||
ResourceConfigUtils.requireNonNullOrThrow(toIngredient(ingredient), "warning.config.recipe.brewing.missing_ingredient"),
|
||||
parseResult(arguments));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomBrewingRecipe<A> readJson(Key id, JsonObject json) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,55 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.item.recipe.result.CustomRecipeResult;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class CustomCampfireRecipe<T> extends CustomCookingRecipe<T> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
public static final Serializer<?> SERIALIZER = new Serializer<>();
|
||||
|
||||
public CustomCampfireRecipe(Key id, CookingRecipeCategory category, String group, Ingredient<T> ingredient, int cookingTime, float experience, CustomRecipeResult<T> result) {
|
||||
super(id, category, group, ingredient, cookingTime, experience, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Key type() {
|
||||
return RecipeTypes.CAMPFIRE_COOKING;
|
||||
public @NotNull Key serializerType() {
|
||||
return RecipeSerializers.CAMPFIRE_COOKING;
|
||||
}
|
||||
|
||||
public static class Factory<A> extends AbstractRecipeFactory<A> {
|
||||
@Override
|
||||
public RecipeType type() {
|
||||
return RecipeType.CAMPFIRE_COOKING;
|
||||
}
|
||||
|
||||
public static class Serializer<A> extends AbstractRecipeSerializer<A, CustomCampfireRecipe<A>> {
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"})
|
||||
@Override
|
||||
public Recipe<A> create(Key id, Map<String, Object> arguments) {
|
||||
String group = arguments.containsKey("group") ? arguments.get("group").toString() : null;
|
||||
int cookingTime = ResourceConfigUtils.getAsInt(arguments.getOrDefault("time", 80), "time");
|
||||
float experience = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("experience", 0.0f), "experience");
|
||||
Set<UniqueKey> holders = ingredientHolders(arguments);
|
||||
return new CustomCampfireRecipe(id, cookingRecipeCategory(arguments), group, Ingredient.of(holders), cookingTime, experience, parseResult(arguments));
|
||||
public CustomCampfireRecipe<A> readMap(Key id, Map<String, Object> arguments) {
|
||||
return new CustomCampfireRecipe(id,
|
||||
cookingRecipeCategory(arguments),
|
||||
arguments.containsKey("group") ? arguments.get("group").toString() : null,
|
||||
singleInputIngredient(arguments),
|
||||
ResourceConfigUtils.getAsInt(arguments.getOrDefault("time", 80), "time"),
|
||||
ResourceConfigUtils.getAsFloat(arguments.getOrDefault("experience", 0.0f), "experience"),
|
||||
parseResult(arguments)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomCampfireRecipe<A> readJson(Key id, JsonObject json) {
|
||||
return new CustomCampfireRecipe<>(id,
|
||||
VANILLA_RECIPE_HELPER.cookingCategory(json),
|
||||
VANILLA_RECIPE_HELPER.readGroup(json),
|
||||
toIngredient(VANILLA_RECIPE_HELPER.singleIngredient(json.get("ingredient"))),
|
||||
VANILLA_RECIPE_HELPER.cookingTime(json),
|
||||
VANILLA_RECIPE_HELPER.cookingExperience(json),
|
||||
parseResult(VANILLA_RECIPE_HELPER.cookingResult(json.get("result")))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.item.recipe.input.RecipeInput;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.SingleItemInput;
|
||||
import net.momirealms.craftengine.core.item.recipe.result.CustomRecipeResult;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
import java.util.List;
|
||||
@@ -20,7 +21,7 @@ public abstract class CustomCookingRecipe<T> extends AbstractGroupedRecipe<T> {
|
||||
float experience,
|
||||
CustomRecipeResult<T> result) {
|
||||
super(id, group, result);
|
||||
this.category = category;
|
||||
this.category = category == null ? CookingRecipeCategory.MISC : category;
|
||||
this.ingredient = ingredient;
|
||||
this.experience = experience;
|
||||
this.cookingTime = cookingTime;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.item.recipe.result.CustomRecipeResult;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
public abstract class CustomCraftingTableRecipe<T> extends AbstractGroupedRecipe<T> {
|
||||
@@ -7,10 +8,15 @@ public abstract class CustomCraftingTableRecipe<T> extends AbstractGroupedRecipe
|
||||
|
||||
protected CustomCraftingTableRecipe(Key id, CraftingRecipeCategory category, String group, CustomRecipeResult<T> result) {
|
||||
super(id, group, result);
|
||||
this.category = category;
|
||||
this.category = category == null ? CraftingRecipeCategory.MISC : category;
|
||||
}
|
||||
|
||||
public CraftingRecipeCategory category() {
|
||||
return category;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeType type() {
|
||||
return RecipeType.CRAFTING;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.item.BuildableItem;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.registry.Registries;
|
||||
import net.momirealms.craftengine.core.registry.WritableRegistry;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceKey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public record CustomRecipeResult<T>(BuildableItem<T> item, int count, PostProcessor<T>[] postProcessors) {
|
||||
|
||||
public T buildItemStack(ItemBuildContext context) {
|
||||
Item<T> builtItem = this.item.buildItem(context, count);
|
||||
if (this.postProcessors != null) {
|
||||
for (PostProcessor<T> postProcessor : this.postProcessors) {
|
||||
builtItem = postProcessor.process(builtItem, context);
|
||||
}
|
||||
}
|
||||
return builtItem.getItem();
|
||||
}
|
||||
|
||||
static {
|
||||
registerPostProcessorType(Key.of("apply_data"), args -> {
|
||||
List<ItemDataModifier<?>> modifiers = new ArrayList<>();
|
||||
for (Map.Entry<String, Object> entry : args.entrySet()) {
|
||||
Optional.ofNullable(CraftEngine.instance().itemManager().getDataType(entry.getKey())).ifPresent(it -> {
|
||||
modifiers.add(it.apply(entry.getValue()));
|
||||
});
|
||||
}
|
||||
return new ApplyItemDataProcessor<>(modifiers.toArray(new ItemDataModifier[0]));
|
||||
});
|
||||
}
|
||||
|
||||
public static void registerPostProcessorType(Key id, PostProcessor.Type<?> type) {
|
||||
((WritableRegistry<PostProcessor.Type<?>>) BuiltInRegistries.RECIPE_POST_PROCESSOR_TYPE).register(ResourceKey.create(Registries.RECIPE_POST_PROCESSOR_TYPE.location(), id), type);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface PostProcessor<T> {
|
||||
|
||||
Item<T> process(Item<T> item, ItemBuildContext context);
|
||||
|
||||
interface Type<T> {
|
||||
|
||||
PostProcessor<T> create(Map<String, Object> args);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ApplyItemDataProcessor<T> implements PostProcessor<T> {
|
||||
private final ItemDataModifier<T>[] modifiers;
|
||||
|
||||
public ApplyItemDataProcessor(ItemDataModifier<T>[] modifiers) {
|
||||
this.modifiers = modifiers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<T> process(Item<T> item, ItemBuildContext context) {
|
||||
for (ItemDataModifier<T> modifier : this.modifiers) {
|
||||
item.apply(modifier, context);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,20 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.CraftingInput;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.RecipeInput;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.item.recipe.result.CustomRecipeResult;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class CustomShapedRecipe<T> extends CustomCraftingTableRecipe<T> {
|
||||
public static final Factory<?> FACTORY = new Factory<CustomShapedRecipe<?>>();
|
||||
public static final Serializer<?> SERIALIZER = new Serializer<CustomShapedRecipe<?>>();
|
||||
private final ParsedPattern<T> parsedPattern;
|
||||
private final Pattern<T> pattern;
|
||||
|
||||
@@ -38,8 +40,8 @@ public class CustomShapedRecipe<T> extends CustomCraftingTableRecipe<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Key type() {
|
||||
return RecipeTypes.SHAPED;
|
||||
public @NotNull Key serializerType() {
|
||||
return RecipeSerializers.SHAPED;
|
||||
}
|
||||
|
||||
public Pattern<T> pattern() {
|
||||
@@ -133,11 +135,11 @@ public class CustomShapedRecipe<T> extends CustomCraftingTableRecipe<T> {
|
||||
}
|
||||
}
|
||||
|
||||
public static class Factory<A> extends AbstractRecipeFactory<A> {
|
||||
public static class Serializer<A> extends AbstractRecipeSerializer<A, CustomShapedRecipe<A>> {
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"})
|
||||
@Override
|
||||
public Recipe<A> create(Key id, Map<String, Object> arguments) {
|
||||
public CustomShapedRecipe<A> readMap(Key id, Map<String, Object> arguments) {
|
||||
List<String> pattern = MiscUtils.getAsStringList(arguments.get("pattern"));
|
||||
if (pattern.isEmpty()) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.shaped.missing_pattern");
|
||||
@@ -146,30 +148,37 @@ public class CustomShapedRecipe<T> extends CustomCraftingTableRecipe<T> {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.shaped.invalid_pattern", pattern.toString());
|
||||
}
|
||||
Object ingredientObj = getIngredientOrThrow(arguments);
|
||||
String group = arguments.containsKey("group") ? arguments.get("group").toString() : null;
|
||||
Map<Character, Ingredient<A>> ingredients = new HashMap<>();
|
||||
for (Map.Entry<String, Object> entry : MiscUtils.castToMap(ingredientObj, false).entrySet()) {
|
||||
for (Map.Entry<String, Object> entry : ResourceConfigUtils.getAsMap(ingredientObj, "ingredient").entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (key.length() != 1) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.shaped.invalid_symbol", key);
|
||||
}
|
||||
char ch = key.charAt(0);
|
||||
List<String> items = MiscUtils.getAsStringList(entry.getValue());
|
||||
Set<UniqueKey> holders = new HashSet<>();
|
||||
for (String item : items) {
|
||||
if (item.charAt(0) == '#') {
|
||||
holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1))));
|
||||
} else {
|
||||
holders.add(UniqueKey.create(Key.of(item)));
|
||||
}
|
||||
}
|
||||
ingredients.put(ch, Ingredient.of(holders));
|
||||
ingredients.put(ch, toIngredient(items));
|
||||
}
|
||||
return new CustomShapedRecipe(id, craftingRecipeCategory(arguments), group, new Pattern<>(pattern.toArray(new String[0]), ingredients), parseResult(arguments));
|
||||
return new CustomShapedRecipe(id,
|
||||
craftingRecipeCategory(arguments),
|
||||
arguments.containsKey("group") ? arguments.get("group").toString() : null,
|
||||
new Pattern<>(pattern.toArray(new String[0]), ingredients),
|
||||
parseResult(arguments)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomShapedRecipe<A> readJson(Key id, JsonObject json) {
|
||||
Map<Character, Ingredient<A>> ingredients = Maps.transformValues(VANILLA_RECIPE_HELPER.shapedIngredientMap(json.getAsJsonObject("key")), this::toIngredient);
|
||||
return new CustomShapedRecipe<>(id,
|
||||
VANILLA_RECIPE_HELPER.craftingCategory(json),
|
||||
VANILLA_RECIPE_HELPER.readGroup(json),
|
||||
new Pattern<>(VANILLA_RECIPE_HELPER.craftingShapedPattern(json), ingredients),
|
||||
parseResult(VANILLA_RECIPE_HELPER.craftingResult(json.getAsJsonObject("result")))
|
||||
);
|
||||
}
|
||||
|
||||
private boolean validatePattern(List<String> pattern) {
|
||||
String first = pattern.get(0);
|
||||
String first = pattern.getFirst();
|
||||
int length = first.length();
|
||||
for (String s : pattern) {
|
||||
if (s.length() != length) {
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.CraftingInput;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.RecipeInput;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.item.recipe.result.CustomRecipeResult;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CustomShapelessRecipe<T> extends CustomCraftingTableRecipe<T> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
public static final Serializer<?> SERIALIZER = new Serializer<>();
|
||||
private final List<Ingredient<T>> ingredients;
|
||||
private final PlacementInfo<T> placementInfo;
|
||||
|
||||
@@ -47,65 +49,49 @@ public class CustomShapelessRecipe<T> extends CustomCraftingTableRecipe<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Key type() {
|
||||
return RecipeTypes.SHAPELESS;
|
||||
public @NotNull Key serializerType() {
|
||||
return RecipeSerializers.SHAPELESS;
|
||||
}
|
||||
|
||||
public static class Factory<A> extends AbstractRecipeFactory<A> {
|
||||
public static class Serializer<A> extends AbstractRecipeSerializer<A, CustomShapelessRecipe<A>> {
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"})
|
||||
@Override
|
||||
public Recipe<A> create(Key id, Map<String, Object> arguments) {
|
||||
String group = arguments.containsKey("group") ? arguments.get("group").toString() : null;
|
||||
public CustomShapelessRecipe<A> readMap(Key id, Map<String, Object> arguments) {
|
||||
List<Ingredient<A>> ingredients = new ArrayList<>();
|
||||
Object ingredientsObject = getIngredientOrThrow(arguments);
|
||||
if (ingredientsObject instanceof Map<?,?> map) {
|
||||
for (Map.Entry<String, Object> entry : (MiscUtils.castToMap(map, false)).entrySet()) {
|
||||
List<String> items = MiscUtils.getAsStringList(entry.getValue());
|
||||
Set<UniqueKey> holders = new HashSet<>();
|
||||
for (String item : items) {
|
||||
if (item.charAt(0) == '#') {
|
||||
holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1))));
|
||||
} else {
|
||||
holders.add(UniqueKey.create(Key.of(item)));
|
||||
}
|
||||
}
|
||||
ingredients.add(Ingredient.of(holders));
|
||||
if (entry.getValue() == null) continue;
|
||||
ingredients.add(toIngredient(MiscUtils.getAsStringList(entry.getValue())));
|
||||
}
|
||||
} else if (ingredientsObject instanceof List<?> list) {
|
||||
for (Object obj : list) {
|
||||
if (obj instanceof List<?> inner) {
|
||||
Set<UniqueKey> holders = new HashSet<>();
|
||||
for (String item : MiscUtils.getAsStringList(inner)) {
|
||||
if (item.charAt(0) == '#') {
|
||||
holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1))));
|
||||
} else {
|
||||
holders.add(UniqueKey.create(Key.of(item)));
|
||||
}
|
||||
}
|
||||
ingredients.add(Ingredient.of(holders));
|
||||
ingredients.add(toIngredient(MiscUtils.getAsStringList(inner)));
|
||||
} else {
|
||||
String item = obj.toString();
|
||||
Set<UniqueKey> holders = new HashSet<>();
|
||||
if (item.charAt(0) == '#') {
|
||||
holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1))));
|
||||
} else {
|
||||
holders.add(UniqueKey.create(Key.of(item)));
|
||||
}
|
||||
ingredients.add(Ingredient.of(holders));
|
||||
ingredients.add(toIngredient(item));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String item = ingredientsObject.toString();
|
||||
Set<UniqueKey> holders = new HashSet<>();
|
||||
if (item.charAt(0) == '#') {
|
||||
holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1))));
|
||||
} else {
|
||||
holders.add(UniqueKey.create(Key.of(item)));
|
||||
}
|
||||
ingredients.add(Ingredient.of(holders));
|
||||
ingredients.add(toIngredient(ingredientsObject.toString()));
|
||||
}
|
||||
return new CustomShapelessRecipe(id, craftingRecipeCategory(arguments), group, ingredients, parseResult(arguments));
|
||||
return new CustomShapelessRecipe(id,
|
||||
craftingRecipeCategory(arguments),
|
||||
arguments.containsKey("group") ? arguments.get("group").toString() : null,
|
||||
ingredients,
|
||||
parseResult(arguments));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomShapelessRecipe<A> readJson(Key id, JsonObject json) {
|
||||
return new CustomShapelessRecipe<>(id,
|
||||
VANILLA_RECIPE_HELPER.craftingCategory(json),
|
||||
VANILLA_RECIPE_HELPER.readGroup(json),
|
||||
VANILLA_RECIPE_HELPER.shapelessIngredients(json.getAsJsonArray("ingredients")).stream().map(this::toIngredient).toList(),
|
||||
parseResult(VANILLA_RECIPE_HELPER.craftingResult(json.getAsJsonObject("result")))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,55 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.item.recipe.result.CustomRecipeResult;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class CustomSmeltingRecipe<T> extends CustomCookingRecipe<T> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
public static final Serializer<?> SERIALIZER = new Serializer<>();
|
||||
|
||||
public CustomSmeltingRecipe(Key id, CookingRecipeCategory category, String group, Ingredient<T> ingredient, int cookingTime, float experience, CustomRecipeResult<T> result) {
|
||||
super(id, category, group, ingredient, cookingTime, experience, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Key type() {
|
||||
return RecipeTypes.SMELTING;
|
||||
public @NotNull Key serializerType() {
|
||||
return RecipeSerializers.SMELTING;
|
||||
}
|
||||
|
||||
public static class Factory<A> extends AbstractRecipeFactory<A> {
|
||||
@Override
|
||||
public RecipeType type() {
|
||||
return RecipeType.SMELTING;
|
||||
}
|
||||
|
||||
public static class Serializer<A> extends AbstractRecipeSerializer<A, CustomSmeltingRecipe<A>> {
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"})
|
||||
@Override
|
||||
public Recipe<A> create(Key id, Map<String, Object> arguments) {
|
||||
String group = arguments.containsKey("group") ? arguments.get("group").toString() : null;
|
||||
int cookingTime = ResourceConfigUtils.getAsInt(arguments.getOrDefault("time", 80), "time");
|
||||
float experience = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("experience", 0.0f), "experience");
|
||||
Set<UniqueKey> holders = ingredientHolders(arguments);
|
||||
return new CustomSmeltingRecipe(id, cookingRecipeCategory(arguments), group, Ingredient.of(holders), cookingTime, experience, parseResult(arguments));
|
||||
public CustomSmeltingRecipe<A> readMap(Key id, Map<String, Object> arguments) {
|
||||
return new CustomSmeltingRecipe(id,
|
||||
cookingRecipeCategory(arguments),
|
||||
arguments.containsKey("group") ? arguments.get("group").toString() : null,
|
||||
singleInputIngredient(arguments),
|
||||
ResourceConfigUtils.getAsInt(arguments.getOrDefault("time", 80), "time"),
|
||||
ResourceConfigUtils.getAsFloat(arguments.getOrDefault("experience", 0.0f), "experience"),
|
||||
parseResult(arguments)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomSmeltingRecipe<A> readJson(Key id, JsonObject json) {
|
||||
return new CustomSmeltingRecipe<>(id,
|
||||
VANILLA_RECIPE_HELPER.cookingCategory(json),
|
||||
VANILLA_RECIPE_HELPER.readGroup(json),
|
||||
toIngredient(VANILLA_RECIPE_HELPER.singleIngredient(json.get("ingredient"))),
|
||||
VANILLA_RECIPE_HELPER.cookingTime(json),
|
||||
VANILLA_RECIPE_HELPER.cookingExperience(json),
|
||||
parseResult(VANILLA_RECIPE_HELPER.cookingResult(json.get("result")))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.RecipeInput;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.SmithingInput;
|
||||
import net.momirealms.craftengine.core.item.recipe.result.CustomRecipeResult;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
@@ -16,9 +18,10 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class CustomSmithingTransformRecipe<T> implements FixedResultRecipe<T> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
public static final Serializer<?> SERIALIZER = new Serializer<>();
|
||||
private final Key id;
|
||||
private final CustomRecipeResult<T> result;
|
||||
private final Ingredient<T> base;
|
||||
@@ -28,7 +31,7 @@ public class CustomSmithingTransformRecipe<T> implements FixedResultRecipe<T> {
|
||||
private final List<ItemDataProcessor> processors;
|
||||
|
||||
public CustomSmithingTransformRecipe(Key id,
|
||||
@Nullable Ingredient<T> base,
|
||||
@NotNull Ingredient<T> base,
|
||||
@Nullable Ingredient<T> template,
|
||||
@Nullable Ingredient<T> addition,
|
||||
CustomRecipeResult<T> result,
|
||||
@@ -78,8 +81,13 @@ public class CustomSmithingTransformRecipe<T> implements FixedResultRecipe<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Key type() {
|
||||
return RecipeTypes.SMITHING_TRANSFORM;
|
||||
public @NotNull Key serializerType() {
|
||||
return RecipeSerializers.SMITHING_TRANSFORM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeType type() {
|
||||
return RecipeType.SMITHING;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -113,7 +121,7 @@ public class CustomSmithingTransformRecipe<T> implements FixedResultRecipe<T> {
|
||||
return this.result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
public Ingredient<T> base() {
|
||||
return this.base;
|
||||
}
|
||||
@@ -129,26 +137,37 @@ public class CustomSmithingTransformRecipe<T> implements FixedResultRecipe<T> {
|
||||
}
|
||||
|
||||
@SuppressWarnings({"DuplicatedCode"})
|
||||
public static class Factory<A> implements RecipeFactory<A> {
|
||||
public static class Serializer<A> extends AbstractRecipeSerializer<A, CustomSmithingTransformRecipe<A>> {
|
||||
|
||||
@Override
|
||||
public Recipe<A> create(Key id, Map<String, Object> arguments) {
|
||||
public CustomSmithingTransformRecipe<A> readMap(Key id, Map<String, Object> arguments) {
|
||||
List<String> base = MiscUtils.getAsStringList(arguments.get("base"));
|
||||
if (base.isEmpty()) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.smithing_transform.missing_base");
|
||||
}
|
||||
List<String> addition = MiscUtils.getAsStringList(arguments.get("addition"));
|
||||
List<String> template = MiscUtils.getAsStringList(arguments.get("template-type"));
|
||||
List<String> addition = MiscUtils.getAsStringList(arguments.get("addition"));
|
||||
boolean mergeComponents = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("merge-components", true), "merge-components");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> processors = (List<Map<String, Object>>) arguments.getOrDefault("post-processors", List.of());
|
||||
return new CustomSmithingTransformRecipe<>(
|
||||
id,
|
||||
toIngredient(base), toIngredient(template),toIngredient(addition), parseResult(arguments),
|
||||
return new CustomSmithingTransformRecipe<>(id,
|
||||
ResourceConfigUtils.requireNonNullOrThrow(toIngredient(base), "warning.config.recipe.smithing_transform.missing_base"),
|
||||
toIngredient(template),
|
||||
toIngredient(addition),
|
||||
parseResult(arguments),
|
||||
mergeComponents,
|
||||
ItemDataProcessors.fromMapList(processors)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomSmithingTransformRecipe<A> readJson(Key id, JsonObject json) {
|
||||
return new CustomSmithingTransformRecipe<>(id,
|
||||
Objects.requireNonNull(toIngredient(VANILLA_RECIPE_HELPER.singleIngredient(json.get("base")))),
|
||||
toIngredient(VANILLA_RECIPE_HELPER.singleIngredient(json.get("template"))),
|
||||
toIngredient(VANILLA_RECIPE_HELPER.singleIngredient(json.get("addition"))),
|
||||
parseResult(VANILLA_RECIPE_HELPER.smithingResult(json.getAsJsonObject("result"))),
|
||||
true,
|
||||
null
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ItemDataProcessors {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.RecipeInput;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.SmithingInput;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
@@ -16,9 +16,10 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class CustomSmithingTrimRecipe<T> implements Recipe<T> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
public static final Serializer<?> SERIALIZER = new Serializer<>();
|
||||
private final Key id;
|
||||
private final Ingredient<T> base;
|
||||
private final Ingredient<T> template;
|
||||
@@ -60,14 +61,7 @@ public class CustomSmithingTrimRecipe<T> implements Recipe<T> {
|
||||
}
|
||||
|
||||
private boolean checkIngredient(Ingredient<T> ingredient, UniqueIdItem<T> item) {
|
||||
if (ingredient != null) {
|
||||
if (item == null || item.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return ingredient.test(item);
|
||||
} else {
|
||||
return item == null || item.isEmpty();
|
||||
}
|
||||
return ingredient.test(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -80,8 +74,13 @@ public class CustomSmithingTrimRecipe<T> implements Recipe<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Key type() {
|
||||
return RecipeTypes.SMITHING_TRIM;
|
||||
public @NotNull Key serializerType() {
|
||||
return RecipeSerializers.SMITHING_TRIM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeType type() {
|
||||
return RecipeType.SMITHING;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -89,17 +88,17 @@ public class CustomSmithingTrimRecipe<T> implements Recipe<T> {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
public Ingredient<T> base() {
|
||||
return this.base;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
public Ingredient<T> template() {
|
||||
return template;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
public Ingredient<T> addition() {
|
||||
return addition;
|
||||
}
|
||||
@@ -110,22 +109,13 @@ public class CustomSmithingTrimRecipe<T> implements Recipe<T> {
|
||||
}
|
||||
|
||||
@SuppressWarnings({"DuplicatedCode"})
|
||||
public static class Factory<A> implements RecipeFactory<A> {
|
||||
public static class Serializer<A> extends AbstractRecipeSerializer<A, CustomSmithingTrimRecipe<A>> {
|
||||
|
||||
@Override
|
||||
public Recipe<A> create(Key id, Map<String, Object> arguments) {
|
||||
public CustomSmithingTrimRecipe<A> readMap(Key id, Map<String, Object> arguments) {
|
||||
List<String> base = MiscUtils.getAsStringList(arguments.get("base"));
|
||||
if (base.isEmpty()) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.smithing_trim.missing_base");
|
||||
}
|
||||
List<String> addition = MiscUtils.getAsStringList(arguments.get("addition"));
|
||||
if (addition.isEmpty()) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.smithing_trim.missing_addition");
|
||||
}
|
||||
List<String> template = MiscUtils.getAsStringList(arguments.get("template-type"));
|
||||
if (template.isEmpty()) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.smithing_trim.missing_template_type");
|
||||
}
|
||||
List<String> addition = MiscUtils.getAsStringList(arguments.get("addition"));
|
||||
Key pattern = VersionHelper.isOrAbove1_21_5() ? Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("pattern"), "warning.config.recipe.smithing_trim.missing_pattern")) : null;
|
||||
return new CustomSmithingTrimRecipe<>(id,
|
||||
ResourceConfigUtils.requireNonNullOrThrow(toIngredient(base), "warning.config.recipe.smithing_trim.missing_base"),
|
||||
@@ -133,5 +123,15 @@ public class CustomSmithingTrimRecipe<T> implements Recipe<T> {
|
||||
ResourceConfigUtils.requireNonNullOrThrow(toIngredient(addition), "warning.config.recipe.smithing_trim.missing_addition"),
|
||||
pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomSmithingTrimRecipe<A> readJson(Key id, JsonObject json) {
|
||||
return new CustomSmithingTrimRecipe<>(id,
|
||||
Objects.requireNonNull(toIngredient(VANILLA_RECIPE_HELPER.singleIngredient(json.get("base")))),
|
||||
Objects.requireNonNull(toIngredient(VANILLA_RECIPE_HELPER.singleIngredient(json.get("template")))),
|
||||
Objects.requireNonNull(toIngredient(VANILLA_RECIPE_HELPER.singleIngredient(json.get("addition")))),
|
||||
VersionHelper.isOrAbove1_21_5() ? Key.of(json.get("pattern").getAsString()) : null
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,55 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.item.recipe.result.CustomRecipeResult;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class CustomSmokingRecipe<T> extends CustomCookingRecipe<T> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
public static final Serializer<?> SERIALIZER = new Serializer<>();
|
||||
|
||||
public CustomSmokingRecipe(Key id, CookingRecipeCategory category, String group, Ingredient<T> ingredient, int cookingTime, float experience, CustomRecipeResult<T> result) {
|
||||
super(id, category, group, ingredient, cookingTime, experience, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Key type() {
|
||||
return RecipeTypes.SMOKING;
|
||||
public @NotNull Key serializerType() {
|
||||
return RecipeSerializers.SMOKING;
|
||||
}
|
||||
|
||||
public static class Factory<A> extends AbstractRecipeFactory<A> {
|
||||
@Override
|
||||
public RecipeType type() {
|
||||
return RecipeType.SMOKING;
|
||||
}
|
||||
|
||||
public static class Serializer<A> extends AbstractRecipeSerializer<A, CustomSmokingRecipe<A>> {
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes", "DuplicatedCode"})
|
||||
@Override
|
||||
public Recipe<A> create(Key id, Map<String, Object> arguments) {
|
||||
String group = arguments.containsKey("group") ? arguments.get("group").toString() : null;
|
||||
int cookingTime = ResourceConfigUtils.getAsInt(arguments.getOrDefault("time", 80), "time");
|
||||
float experience = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("experience", 0.0f), "experience");
|
||||
Set<UniqueKey> holders = ingredientHolders(arguments);
|
||||
return new CustomSmokingRecipe(id, cookingRecipeCategory(arguments), group, Ingredient.of(holders), cookingTime, experience, parseResult(arguments));
|
||||
public CustomSmokingRecipe<A> readMap(Key id, Map<String, Object> arguments) {
|
||||
return new CustomSmokingRecipe(id,
|
||||
cookingRecipeCategory(arguments),
|
||||
arguments.containsKey("group") ? arguments.get("group").toString() : null,
|
||||
singleInputIngredient(arguments),
|
||||
ResourceConfigUtils.getAsInt(arguments.getOrDefault("time", 80), "time"),
|
||||
ResourceConfigUtils.getAsFloat(arguments.getOrDefault("experience", 0.0f), "experience"),
|
||||
parseResult(arguments)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomSmokingRecipe<A> readJson(Key id, JsonObject json) {
|
||||
return new CustomSmokingRecipe<>(id,
|
||||
VANILLA_RECIPE_HELPER.cookingCategory(json),
|
||||
VANILLA_RECIPE_HELPER.readGroup(json),
|
||||
toIngredient(VANILLA_RECIPE_HELPER.singleIngredient(json.get("ingredient"))),
|
||||
VANILLA_RECIPE_HELPER.cookingTime(json),
|
||||
VANILLA_RECIPE_HELPER.cookingExperience(json),
|
||||
parseResult(VANILLA_RECIPE_HELPER.cookingResult(json.get("result")))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.RecipeInput;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.SingleItemInput;
|
||||
import net.momirealms.craftengine.core.item.recipe.result.CustomRecipeResult;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class CustomStoneCuttingRecipe<T> extends AbstractGroupedRecipe<T> {
|
||||
public static final Factory<?> FACTORY = new Factory<>();
|
||||
public static final Serializer<?> SERIALIZER = new Serializer<>();
|
||||
protected final Ingredient<T> ingredient;
|
||||
|
||||
public CustomStoneCuttingRecipe(Key id, String group, Ingredient<T> ingredient, CustomRecipeResult<T> result) {
|
||||
@@ -27,26 +27,36 @@ public class CustomStoneCuttingRecipe<T> extends AbstractGroupedRecipe<T> {
|
||||
|
||||
@Override
|
||||
public List<Ingredient<T>> ingredientsInUse() {
|
||||
return List.of(ingredient);
|
||||
return List.of(this.ingredient);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Key type() {
|
||||
return RecipeTypes.STONECUTTING;
|
||||
public @NotNull Key serializerType() {
|
||||
return RecipeSerializers.STONECUTTING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeType type() {
|
||||
return RecipeType.STONECUTTING;
|
||||
}
|
||||
|
||||
public Ingredient<T> ingredient() {
|
||||
return ingredient;
|
||||
return this.ingredient;
|
||||
}
|
||||
|
||||
public static class Factory<A> extends AbstractRecipeFactory<A> {
|
||||
public static class Serializer<A> extends AbstractRecipeSerializer<A, CustomStoneCuttingRecipe<A>> {
|
||||
|
||||
@SuppressWarnings({"DuplicatedCode"})
|
||||
@Override
|
||||
public Recipe<A> create(Key id, Map<String, Object> arguments) {
|
||||
public CustomStoneCuttingRecipe<A> readMap(Key id, Map<String, Object> arguments) {
|
||||
String group = arguments.containsKey("group") ? arguments.get("group").toString() : null;
|
||||
Set<UniqueKey> holders = ingredientHolders(arguments);
|
||||
return new CustomStoneCuttingRecipe<>(id, group, Ingredient.of(holders), parseResult(arguments));
|
||||
return new CustomStoneCuttingRecipe<>(id, group, singleInputIngredient(arguments), parseResult(arguments));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomStoneCuttingRecipe<A> readJson(Key id, JsonObject json) {
|
||||
String group = VANILLA_RECIPE_HELPER.readGroup(json);
|
||||
return new CustomStoneCuttingRecipe<>(id, group, toIngredient(VANILLA_RECIPE_HELPER.singleIngredient(json.get("ingredient"))), parseResult(VANILLA_RECIPE_HELPER.stoneCuttingResult(json)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public record DatapackRecipeResult(String id, int count, JsonObject components) {
|
||||
|
||||
public boolean isCustom() {
|
||||
return components != null;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.recipe.input.RecipeInput;
|
||||
import net.momirealms.craftengine.core.item.recipe.result.CustomRecipeResult;
|
||||
|
||||
public interface FixedResultRecipe<T> extends Recipe<T> {
|
||||
|
||||
@@ -9,6 +10,8 @@ public interface FixedResultRecipe<T> extends Recipe<T> {
|
||||
|
||||
CustomRecipeResult<T> result();
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
default T assemble(RecipeInput input, ItemBuildContext context) {
|
||||
return this.result(context);
|
||||
|
||||
@@ -6,10 +6,17 @@ import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class Ingredient<T> implements Predicate<UniqueIdItem<T>>, StackedContents.IngredientInfo<UniqueKey> {
|
||||
// 自定义物品与原版物品混合的列表
|
||||
private final List<UniqueKey> items;
|
||||
// 自定义物品原版材质与原版物品混合的列表
|
||||
private final List<UniqueKey> vanillaItems;
|
||||
// ingredient里是否含有自定义物品
|
||||
private final boolean hasCustomItem;
|
||||
|
||||
public Ingredient(List<UniqueKey> items) {
|
||||
this.items = items;
|
||||
private Ingredient(List<UniqueKey> items, List<UniqueKey> vanillaItems, boolean hasCustomItem) {
|
||||
this.items = List.copyOf(items);
|
||||
this.vanillaItems = List.copyOf(vanillaItems);
|
||||
this.hasCustomItem = hasCustomItem;
|
||||
}
|
||||
|
||||
public static <T> boolean isInstance(Optional<Ingredient<T>> optionalIngredient, UniqueIdItem<T> stack) {
|
||||
@@ -17,12 +24,12 @@ public class Ingredient<T> implements Predicate<UniqueIdItem<T>>, StackedContent
|
||||
.orElseGet(stack::isEmpty);
|
||||
}
|
||||
|
||||
public static <T> Ingredient<T> of(List<UniqueKey> items) {
|
||||
return new Ingredient<>(items);
|
||||
public static <T> Ingredient<T> of(Set<UniqueKey> items, Set<UniqueKey> minecraftItems, boolean hasCustomItem) {
|
||||
return new Ingredient<>(new ArrayList<>(items), new ArrayList<>(minecraftItems), hasCustomItem);
|
||||
}
|
||||
|
||||
public static <T> Ingredient<T> of(Set<UniqueKey> items) {
|
||||
return new Ingredient<>(new ArrayList<>(items));
|
||||
public boolean hasCustomItem() {
|
||||
return hasCustomItem;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -39,6 +46,10 @@ public class Ingredient<T> implements Predicate<UniqueIdItem<T>>, StackedContent
|
||||
return this.items;
|
||||
}
|
||||
|
||||
public List<UniqueKey> minecraftItems() {
|
||||
return vanillaItems;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringJoiner joiner = new StringJoiner(", ");
|
||||
|
||||
@@ -16,7 +16,13 @@ public interface Recipe<T> {
|
||||
List<Ingredient<T>> ingredientsInUse();
|
||||
|
||||
@NotNull
|
||||
Key type();
|
||||
Key serializerType();
|
||||
|
||||
RecipeType type();
|
||||
|
||||
Key id();
|
||||
|
||||
default boolean showNotification() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.craftengine.core.util.UniqueKey;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public interface RecipeFactory<T> {
|
||||
|
||||
Recipe<T> create(Key id, Map<String, Object> arguments);
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
default CustomRecipeResult<T> parseResult(Map<String, Object> arguments) {
|
||||
Map<String, Object> resultMap = MiscUtils.castToMap(arguments.get("result"), true);
|
||||
if (resultMap == null) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.missing_result");
|
||||
}
|
||||
String id = ResourceConfigUtils.requireNonEmptyStringOrThrow(resultMap.get("id"), "warning.config.recipe.result.missing_id");
|
||||
int count = ResourceConfigUtils.getAsInt(resultMap.getOrDefault("count", 1), "count");
|
||||
return new CustomRecipeResult(
|
||||
CraftEngine.instance().itemManager().getBuildableItem(Key.of(id)).orElseThrow(
|
||||
() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_result", id)),
|
||||
count,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
default Ingredient<T> toIngredient(List<String> items) {
|
||||
Set<UniqueKey> holders = new HashSet<>();
|
||||
for (String item : items) {
|
||||
if (item.charAt(0) == '#') {
|
||||
holders.addAll(CraftEngine.instance().itemManager().tagToItems(Key.of(item.substring(1))));
|
||||
} else {
|
||||
holders.add(UniqueKey.create(Key.of(item)));
|
||||
}
|
||||
}
|
||||
return holders.isEmpty() ? null : Ingredient.of(holders);
|
||||
}
|
||||
}
|
||||
@@ -19,15 +19,15 @@ public interface RecipeManager<T> extends Manageable {
|
||||
|
||||
Optional<Recipe<T>> recipeById(Key id);
|
||||
|
||||
List<Recipe<T>> recipesByType(Key type);
|
||||
List<Recipe<T>> recipesByType(RecipeType type);
|
||||
|
||||
List<Recipe<T>> recipeByResult(Key result);
|
||||
|
||||
List<Recipe<T>> recipeByIngredient(Key ingredient);
|
||||
|
||||
@Nullable
|
||||
Recipe<T> recipeByInput(Key type, RecipeInput input);
|
||||
Recipe<T> recipeByInput(RecipeType type, RecipeInput input);
|
||||
|
||||
@Nullable
|
||||
Recipe<T> recipeByInput(Key type, RecipeInput input, @Nullable Key lastRecipe);
|
||||
Recipe<T> recipeByInput(RecipeType type, RecipeInput input, @Nullable Key lastRecipe);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface RecipeSerializer<T, R extends Recipe<T>> {
|
||||
|
||||
R readMap(Key id, Map<String, Object> arguments);
|
||||
|
||||
R readJson(Key id, JsonObject json);
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import net.momirealms.craftengine.core.util.ResourceKey;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class RecipeTypes {
|
||||
public final class RecipeSerializers {
|
||||
public static final Key SHAPED = Key.of("minecraft:shaped");
|
||||
public static final Key SHAPELESS = Key.of("minecraft:shapeless");
|
||||
public static final Key SMELTING = Key.of("minecraft:smelting");
|
||||
@@ -23,31 +23,34 @@ public class RecipeTypes {
|
||||
public static final Key BREWING = Key.of("minecraft:brewing");
|
||||
|
||||
static {
|
||||
register(SHAPED, CustomShapedRecipe.FACTORY);
|
||||
register(SHAPELESS, CustomShapelessRecipe.FACTORY);
|
||||
register(SMELTING, CustomSmeltingRecipe.FACTORY);
|
||||
register(SMOKING, CustomSmokingRecipe.FACTORY);
|
||||
register(BLASTING, CustomBlastingRecipe.FACTORY);
|
||||
register(CAMPFIRE_COOKING, CustomCampfireRecipe.FACTORY);
|
||||
register(STONECUTTING, CustomStoneCuttingRecipe.FACTORY);
|
||||
register(SMITHING_TRANSFORM, CustomSmithingTransformRecipe.FACTORY);
|
||||
register(SMITHING_TRIM, CustomSmithingTrimRecipe.FACTORY);
|
||||
register(BREWING, CustomBrewingRecipe.FACTORY);
|
||||
register(SHAPED, CustomShapedRecipe.SERIALIZER);
|
||||
register(Key.of("crafting_shaped"), CustomShapedRecipe.SERIALIZER);
|
||||
register(SHAPELESS, CustomShapelessRecipe.SERIALIZER);
|
||||
register(Key.of("crafting_shapeless"), CustomShapelessRecipe.SERIALIZER);
|
||||
register(SMELTING, CustomSmeltingRecipe.SERIALIZER);
|
||||
register(SMOKING, CustomSmokingRecipe.SERIALIZER);
|
||||
register(BLASTING, CustomBlastingRecipe.SERIALIZER);
|
||||
register(CAMPFIRE_COOKING, CustomCampfireRecipe.SERIALIZER);
|
||||
register(STONECUTTING, CustomStoneCuttingRecipe.SERIALIZER);
|
||||
register(SMITHING_TRANSFORM, CustomSmithingTransformRecipe.SERIALIZER);
|
||||
register(SMITHING_TRIM, CustomSmithingTrimRecipe.SERIALIZER);
|
||||
register(BREWING, CustomBrewingRecipe.SERIALIZER);
|
||||
}
|
||||
|
||||
public static <T> void register(Key key, RecipeFactory<T> factory) {
|
||||
((WritableRegistry<RecipeFactory<?>>) BuiltInRegistries.RECIPE_FACTORY)
|
||||
.register(ResourceKey.create(Registries.RECIPE_FACTORY.location(), key), factory);
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public static <T, R extends Recipe<T>> void register(Key key, RecipeSerializer<T, R> serializer) {
|
||||
WritableRegistry<RecipeSerializer<T, R>> registry = (WritableRegistry) BuiltInRegistries.RECIPE_SERIALIZER;
|
||||
registry.register(ResourceKey.create(Registries.RECIPE_FACTORY.location(), key), serializer);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Recipe<T> fromMap(Key id, Map<String, Object> map) {
|
||||
public static <T, R extends Recipe<T>> Recipe<T> fromMap(Key id, Map<String, Object> map) {
|
||||
String type = ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("type"), "warning.config.recipe.missing_type");
|
||||
Key key = Key.withDefaultNamespace(type, "minecraft");
|
||||
RecipeFactory<T> factory = (RecipeFactory<T>) BuiltInRegistries.RECIPE_FACTORY.getValue(key);
|
||||
RecipeSerializer<T, R> factory = (RecipeSerializer<T, R>) BuiltInRegistries.RECIPE_SERIALIZER.getValue(key);
|
||||
if (factory == null) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.invalid_type", type);
|
||||
}
|
||||
return factory.create(id, map);
|
||||
return factory.readMap(id, map);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package net.momirealms.craftengine.core.item.recipe;
|
||||
|
||||
public enum RecipeType {
|
||||
CRAFTING("crafting"),
|
||||
SMELTING("smelting"),
|
||||
BLASTING("blasting"),
|
||||
SMOKING("smoking"),
|
||||
CAMPFIRE_COOKING("campfire_cooking"),
|
||||
STONECUTTING("stonecutting"),
|
||||
BREWING("brewing"),
|
||||
SMITHING("smithing");
|
||||
|
||||
private final String id;
|
||||
|
||||
RecipeType(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String id() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,13 @@ public class UniqueIdItem<T> {
|
||||
private final Item<T> rawItem;
|
||||
private final UniqueKey uniqueId;
|
||||
|
||||
public UniqueIdItem(@NotNull UniqueKey uniqueId, @NotNull Item<T> rawItem) {
|
||||
this.uniqueId = uniqueId;
|
||||
private UniqueIdItem(@NotNull Item<T> rawItem) {
|
||||
this.rawItem = rawItem;
|
||||
this.uniqueId = rawItem.recipeIngredientId();
|
||||
}
|
||||
|
||||
public static <T> UniqueIdItem<T> of(Item<T> rawItem) {
|
||||
return new UniqueIdItem<>(rawItem);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -28,7 +32,7 @@ public class UniqueIdItem<T> {
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.uniqueId == UniqueKey.AIR;
|
||||
return this.uniqueId == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,12 +2,14 @@ package net.momirealms.craftengine.core.item.recipe.input;
|
||||
|
||||
import net.momirealms.craftengine.core.item.recipe.RecipeFinder;
|
||||
import net.momirealms.craftengine.core.item.recipe.UniqueIdItem;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public final class CraftingInput<T> implements RecipeInput {
|
||||
public final class CraftingInput<T> implements RecipeInput, Iterable<UniqueIdItem<T>> {
|
||||
private final int width;
|
||||
private final int height;
|
||||
private final List<UniqueIdItem<T>> items;
|
||||
@@ -99,4 +101,9 @@ public final class CraftingInput<T> implements RecipeInput {
|
||||
public UniqueIdItem<T> getItem(int index) {
|
||||
return this.items.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Iterator<UniqueIdItem<T>> iterator() {
|
||||
return this.items.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package net.momirealms.craftengine.core.item.recipe.input;
|
||||
|
||||
import net.momirealms.craftengine.core.item.recipe.UniqueIdItem;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class SmithingInput<T> implements RecipeInput {
|
||||
private final UniqueIdItem<T> base;
|
||||
@@ -10,8 +9,8 @@ public final class SmithingInput<T> implements RecipeInput {
|
||||
private final UniqueIdItem<T> addition;
|
||||
|
||||
public SmithingInput(@NotNull UniqueIdItem<T> base,
|
||||
@Nullable UniqueIdItem<T> template,
|
||||
@Nullable UniqueIdItem<T> addition) {
|
||||
@NotNull UniqueIdItem<T> template,
|
||||
@NotNull UniqueIdItem<T> addition) {
|
||||
this.base = base;
|
||||
this.template = template;
|
||||
this.addition = addition;
|
||||
@@ -22,12 +21,12 @@ public final class SmithingInput<T> implements RecipeInput {
|
||||
return base;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
public UniqueIdItem<T> template() {
|
||||
return template;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
public UniqueIdItem<T> addition() {
|
||||
return addition;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.reader;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.item.recipe.CookingRecipeCategory;
|
||||
import net.momirealms.craftengine.core.item.recipe.CraftingRecipeCategory;
|
||||
import net.momirealms.craftengine.core.item.recipe.DatapackRecipeResult;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface VanillaRecipeReader {
|
||||
|
||||
@NotNull DatapackRecipeResult cookingResult(JsonElement object);
|
||||
|
||||
@NotNull DatapackRecipeResult craftingResult(JsonObject object);
|
||||
|
||||
@NotNull DatapackRecipeResult smithingResult(JsonObject object);
|
||||
|
||||
List<List<String>> shapelessIngredients(JsonArray json);
|
||||
|
||||
Map<Character, List<String>> shapedIngredientMap(JsonObject json);
|
||||
|
||||
@NotNull List<String> ingredientList(JsonArray array);
|
||||
|
||||
String[] craftingShapedPattern(JsonObject object);
|
||||
|
||||
@Nullable
|
||||
String readGroup(JsonObject object);
|
||||
|
||||
@NotNull
|
||||
CraftingRecipeCategory craftingCategory(JsonObject object);
|
||||
|
||||
@NotNull
|
||||
CookingRecipeCategory cookingCategory(JsonObject object);
|
||||
|
||||
float cookingExperience(JsonObject object);
|
||||
|
||||
int cookingTime(JsonObject object);
|
||||
|
||||
@NotNull DatapackRecipeResult stoneCuttingResult(JsonObject json);
|
||||
|
||||
List<String> singleIngredient(JsonElement json);
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.reader;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.item.recipe.CookingRecipeCategory;
|
||||
import net.momirealms.craftengine.core.item.recipe.CraftingRecipeCategory;
|
||||
import net.momirealms.craftengine.core.item.recipe.DatapackRecipeResult;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class VanillaRecipeReader1_20 implements VanillaRecipeReader {
|
||||
|
||||
@Override
|
||||
public @NotNull DatapackRecipeResult cookingResult(JsonElement object) {
|
||||
return new DatapackRecipeResult(object.getAsString(), 1, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull DatapackRecipeResult craftingResult(JsonObject object) {
|
||||
String item = object.get("item").getAsString();
|
||||
int count = object.has("count") ? object.get("count").getAsInt() : 1;
|
||||
return new DatapackRecipeResult(item, count, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull DatapackRecipeResult smithingResult(JsonObject object) {
|
||||
String item = object.get("item").getAsString();
|
||||
return new DatapackRecipeResult(item, 1, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<List<String>> shapelessIngredients(JsonArray json) {
|
||||
List<List<String>> ingredients = new ArrayList<>();
|
||||
for (JsonElement element : json) {
|
||||
if (element.isJsonObject()) {
|
||||
JsonObject jsonObject = element.getAsJsonObject();
|
||||
if (jsonObject.has("item")) {
|
||||
ingredients.add(List.of(jsonObject.get("item").getAsString()));
|
||||
} else if (jsonObject.has("tag")) {
|
||||
ingredients.add(List.of("#" + jsonObject.get("tag").getAsString()));
|
||||
}
|
||||
} else if (element.isJsonArray()) {
|
||||
List<String> ingredient = ingredientList((JsonArray) element);
|
||||
ingredients.add(ingredient);
|
||||
}
|
||||
}
|
||||
return ingredients;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Character, List<String>> shapedIngredientMap(JsonObject json) {
|
||||
Map<Character, List<String>> ingredients = new HashMap<>();
|
||||
for (Map.Entry<String, JsonElement> entry : json.entrySet()) {
|
||||
char c = entry.getKey().charAt(0);
|
||||
if (entry.getValue().isJsonObject()) {
|
||||
JsonObject argument = entry.getValue().getAsJsonObject();
|
||||
if (argument.has("item")) {
|
||||
ingredients.put(c, List.of(argument.get("item").getAsString()));
|
||||
} else if (argument.has("tag")) {
|
||||
ingredients.put(c, List.of("#" + argument.get("tag").getAsString()));
|
||||
}
|
||||
} else if (entry.getValue().isJsonArray()) {
|
||||
List<String> items = ingredientList((JsonArray) entry.getValue());
|
||||
ingredients.put(c, items);
|
||||
}
|
||||
}
|
||||
return ingredients;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<String> ingredientList(JsonArray array) {
|
||||
List<String> items = new ArrayList<>();
|
||||
for (JsonElement element : array) {
|
||||
if (element.isJsonObject()) {
|
||||
JsonObject argument = element.getAsJsonObject();
|
||||
if (argument.has("item")) {
|
||||
items.add(argument.get("item").getAsString());
|
||||
} else if (argument.has("tag")) {
|
||||
items.add("#" + argument.get("tag").getAsString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] craftingShapedPattern(JsonObject object) {
|
||||
JsonArray pattern = object.getAsJsonArray("pattern");
|
||||
List<String> patternList = new ArrayList<>();
|
||||
for (JsonElement element : pattern) {
|
||||
patternList.add(element.getAsString());
|
||||
}
|
||||
return patternList.toArray(new String[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String readGroup(JsonObject object) {
|
||||
return object.has("group") ? object.get("group").getAsString() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull CraftingRecipeCategory craftingCategory(JsonObject object) {
|
||||
return object.has("category") ? CraftingRecipeCategory.valueOf(object.get("category").getAsString().toUpperCase(Locale.ENGLISH)) : CraftingRecipeCategory.MISC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull CookingRecipeCategory cookingCategory(JsonObject object) {
|
||||
return object.has("category") ? CookingRecipeCategory.valueOf(object.get("category").getAsString().toUpperCase(Locale.ENGLISH)) : CookingRecipeCategory.MISC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float cookingExperience(JsonObject object) {
|
||||
return object.has("experience") ? object.get("experience").getAsFloat() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int cookingTime(JsonObject object) {
|
||||
return object.has("cookingtime") ? object.get("cookingtime").getAsInt() : 200;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull DatapackRecipeResult stoneCuttingResult(JsonObject json) {
|
||||
int count = json.has("count") ? json.get("count").getAsInt() : 1;
|
||||
String result = json.get("result").getAsString();
|
||||
return new DatapackRecipeResult(result, count, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> singleIngredient(JsonElement json) {
|
||||
List<String> ingredients = new ArrayList<>();
|
||||
if (json.isJsonObject()) {
|
||||
JsonObject argument = json.getAsJsonObject();
|
||||
if (argument.has("item")) {
|
||||
ingredients.add(argument.get("item").getAsString());
|
||||
} else if (argument.has("tag")) {
|
||||
ingredients.add("#" + argument.get("tag").getAsString());
|
||||
}
|
||||
} else if (json.isJsonArray()) {
|
||||
List<String> items = ingredientList((JsonArray) json);
|
||||
ingredients.addAll(items);
|
||||
}
|
||||
return ingredients;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.reader;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.momirealms.craftengine.core.item.recipe.DatapackRecipeResult;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class VanillaRecipeReader1_20_5 extends VanillaRecipeReader1_20 {
|
||||
|
||||
@Override
|
||||
public @NotNull DatapackRecipeResult craftingResult(JsonObject object) {
|
||||
String item = object.get("id").getAsString();
|
||||
JsonObject components = object.has("components") ? object.getAsJsonObject("components") : null;
|
||||
int count = object.has("count") ? object.get("count").getAsInt() : 1;
|
||||
return new DatapackRecipeResult(item, count, components);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DatapackRecipeResult cookingResult(JsonElement object) {
|
||||
return craftingResult(object.getAsJsonObject());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DatapackRecipeResult stoneCuttingResult(JsonObject json) {
|
||||
return craftingResult(json.getAsJsonObject("result"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull DatapackRecipeResult smithingResult(JsonObject object) {
|
||||
return craftingResult(object.getAsJsonObject());
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.vanilla.reader;
|
||||
package net.momirealms.craftengine.core.item.recipe.reader;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
@@ -12,7 +12,7 @@ import java.util.Map;
|
||||
public class VanillaRecipeReader1_21_2 extends VanillaRecipeReader1_20_5 {
|
||||
|
||||
@Override
|
||||
protected List<String> readSingleIngredient(JsonElement json) {
|
||||
public List<String> singleIngredient(JsonElement json) {
|
||||
if (json.isJsonPrimitive()) {
|
||||
return List.of(json.getAsString());
|
||||
} else {
|
||||
@@ -26,7 +26,7 @@ public class VanillaRecipeReader1_21_2 extends VanillaRecipeReader1_20_5 {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<Character, List<String>> readShapedIngredientMap(JsonObject json) {
|
||||
public Map<Character, List<String>> shapedIngredientMap(JsonObject json) {
|
||||
Map<Character, List<String>> ingredients = new HashMap<>();
|
||||
for (Map.Entry<String, JsonElement> entry : json.entrySet()) {
|
||||
char c = entry.getKey().charAt(0);
|
||||
@@ -44,7 +44,7 @@ public class VanillaRecipeReader1_21_2 extends VanillaRecipeReader1_20_5 {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<List<String>> readShapelessIngredients(JsonArray json) {
|
||||
public List<List<String>> shapelessIngredients(JsonArray json) {
|
||||
List<List<String>> ingredients = new ArrayList<>();
|
||||
for (JsonElement element : json) {
|
||||
if (element.isJsonPrimitive()) {
|
||||
@@ -0,0 +1,21 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.result;
|
||||
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
|
||||
|
||||
public class ApplyItemDataPostProcessor<T> implements PostProcessor<T> {
|
||||
private final ItemDataModifier<T>[] modifiers;
|
||||
|
||||
public ApplyItemDataPostProcessor(ItemDataModifier<T>[] modifiers) {
|
||||
this.modifiers = modifiers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item<T> process(Item<T> item, ItemBuildContext context) {
|
||||
for (ItemDataModifier<T> modifier : this.modifiers) {
|
||||
item.apply(modifier, context);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.result;
|
||||
|
||||
import net.momirealms.craftengine.core.item.BuildableItem;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
|
||||
public record CustomRecipeResult<T>(BuildableItem<T> item, int count, PostProcessor<T>[] postProcessors) {
|
||||
|
||||
public T buildItemStack(ItemBuildContext context) {
|
||||
return buildItem(context).getItem();
|
||||
}
|
||||
|
||||
public Item<T> buildItem(ItemBuildContext context) {
|
||||
Item<T> builtItem = this.item.buildItem(context, this.count);
|
||||
if (this.postProcessors != null) {
|
||||
for (PostProcessor<T> postProcessor : this.postProcessors) {
|
||||
builtItem = postProcessor.process(builtItem, context);
|
||||
}
|
||||
}
|
||||
return builtItem;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.result;
|
||||
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface PostProcessor<T> {
|
||||
|
||||
Item<T> process(Item<T> item, ItemBuildContext context);
|
||||
|
||||
interface Type<T> {
|
||||
|
||||
PostProcessor<T> create(Map<String, Object> args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.result;
|
||||
|
||||
import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
|
||||
import net.momirealms.craftengine.core.registry.Registries;
|
||||
import net.momirealms.craftengine.core.registry.WritableRegistry;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.craftengine.core.util.ResourceKey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class PostProcessors {
|
||||
public static final Key APPLY_DATA = Key.of("craftengine:apply_data");
|
||||
|
||||
static {
|
||||
registerPostProcessorType(APPLY_DATA, args -> {
|
||||
List<ItemDataModifier<?>> modifiers = new ArrayList<>();
|
||||
Map<String, Object> data = ResourceConfigUtils.getAsMap(args.get("data"), "data");
|
||||
for (Map.Entry<String, Object> entry : data.entrySet()) {
|
||||
Optional.ofNullable(BuiltInRegistries.ITEM_DATA_MODIFIER_FACTORY.getValue(Key.withDefaultNamespace(entry.getKey(), Key.DEFAULT_NAMESPACE)))
|
||||
.ifPresent(factory -> modifiers.add(factory.create(entry.getValue())));
|
||||
}
|
||||
return new ApplyItemDataPostProcessor<>(modifiers.toArray(new ItemDataModifier[0]));
|
||||
});
|
||||
}
|
||||
|
||||
public static <T> PostProcessor<T> fromMap(Map<String, Object> map) {
|
||||
String type = ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("type"), "warning.config.recipe.result.post_processor.missing_type");
|
||||
Key key = Key.withDefaultNamespace(type, Key.DEFAULT_NAMESPACE);
|
||||
PostProcessor.Type<T> processor = (PostProcessor.Type<T>) BuiltInRegistries.RECIPE_POST_PROCESSOR_TYPE.getValue(key);
|
||||
if (processor == null) {
|
||||
throw new LocalizedResourceConfigException("warning.config.recipe.result.post_processor.invalid_type", type);
|
||||
}
|
||||
return processor.create(map);
|
||||
}
|
||||
|
||||
public static void registerPostProcessorType(Key id, PostProcessor.Type<?> type) {
|
||||
((WritableRegistry<PostProcessor.Type<?>>) BuiltInRegistries.RECIPE_POST_PROCESSOR_TYPE)
|
||||
.register(ResourceKey.create(Registries.RECIPE_POST_PROCESSOR_TYPE.location(), id), type);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.vanilla;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public record RecipeResult(String id, int count, JsonObject components) {
|
||||
|
||||
public boolean isCustom() {
|
||||
return components != null;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.vanilla;
|
||||
|
||||
import net.momirealms.craftengine.core.item.recipe.CookingRecipeCategory;
|
||||
import net.momirealms.craftengine.core.item.recipe.RecipeTypes;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class VanillaBlastingRecipe extends VanillaCookingRecipe {
|
||||
|
||||
public VanillaBlastingRecipe(CookingRecipeCategory category, String group, RecipeResult result, List<String> ingredient, float experience, int cookingTime) {
|
||||
super(category, group, result, ingredient, experience, cookingTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
return RecipeTypes.BLASTING;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.vanilla;
|
||||
|
||||
import net.momirealms.craftengine.core.item.recipe.CookingRecipeCategory;
|
||||
import net.momirealms.craftengine.core.item.recipe.RecipeTypes;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class VanillaCampfireRecipe extends VanillaCookingRecipe {
|
||||
|
||||
public VanillaCampfireRecipe(CookingRecipeCategory category, String group, RecipeResult result, List<String> ingredient, float experience, int cookingTime) {
|
||||
super(category, group, result, ingredient, experience, cookingTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
return RecipeTypes.CAMPFIRE_COOKING;
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.vanilla;
|
||||
|
||||
import net.momirealms.craftengine.core.item.recipe.CookingRecipeCategory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class VanillaCookingRecipe extends VanillaGroupedRecipe {
|
||||
protected final List<String> ingredient;
|
||||
protected final CookingRecipeCategory category;
|
||||
protected final float experience;
|
||||
protected final int cookingTime;
|
||||
|
||||
protected VanillaCookingRecipe(CookingRecipeCategory category, String group, RecipeResult result, List<String> ingredient, float experience, int cookingTime) {
|
||||
super(group, result);
|
||||
this.ingredient = ingredient;
|
||||
this.experience = experience;
|
||||
this.cookingTime = cookingTime;
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public CookingRecipeCategory category() {
|
||||
return category;
|
||||
}
|
||||
|
||||
public List<String> ingredient() {
|
||||
return ingredient;
|
||||
}
|
||||
|
||||
public float experience() {
|
||||
return experience;
|
||||
}
|
||||
|
||||
public int cookingTime() {
|
||||
return cookingTime;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.vanilla;
|
||||
|
||||
import net.momirealms.craftengine.core.item.recipe.CraftingRecipeCategory;
|
||||
|
||||
public abstract class VanillaCraftingRecipe extends VanillaGroupedRecipe {
|
||||
protected final CraftingRecipeCategory category;
|
||||
|
||||
protected VanillaCraftingRecipe(CraftingRecipeCategory category, String group, RecipeResult result) {
|
||||
super(group, result);
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public CraftingRecipeCategory category() {
|
||||
return category;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.vanilla;
|
||||
|
||||
public abstract class VanillaGroupedRecipe implements VanillaRecipe {
|
||||
protected final String group;
|
||||
protected final RecipeResult result;
|
||||
|
||||
protected VanillaGroupedRecipe(String group, RecipeResult result) {
|
||||
this.group = group;
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public String group() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public RecipeResult result() {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.vanilla;
|
||||
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
public interface VanillaRecipe {
|
||||
|
||||
Key type();
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.vanilla;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public interface VanillaRecipeReader {
|
||||
|
||||
VanillaShapedRecipe readShaped(JsonObject json);
|
||||
|
||||
VanillaShapelessRecipe readShapeless(JsonObject json);
|
||||
|
||||
VanillaBlastingRecipe readBlasting(JsonObject json);
|
||||
|
||||
VanillaSmeltingRecipe readSmelting(JsonObject json);
|
||||
|
||||
VanillaSmokingRecipe readSmoking(JsonObject json);
|
||||
|
||||
VanillaCampfireRecipe readCampfire(JsonObject json);
|
||||
|
||||
VanillaStoneCuttingRecipe readStoneCutting(JsonObject json);
|
||||
|
||||
VanillaSmithingTransformRecipe readSmithingTransform(JsonObject json);
|
||||
|
||||
VanillaSmithingTrimRecipe readSmithingTrim(JsonObject json);
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.vanilla;
|
||||
|
||||
import net.momirealms.craftengine.core.item.recipe.CraftingRecipeCategory;
|
||||
import net.momirealms.craftengine.core.item.recipe.RecipeTypes;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class VanillaShapedRecipe extends VanillaCraftingRecipe {
|
||||
private final String[] pattern;
|
||||
private final Map<Character, List<String>> key;
|
||||
|
||||
public VanillaShapedRecipe(CraftingRecipeCategory category,
|
||||
String group,
|
||||
Map<Character, List<String>> key,
|
||||
String[] pattern,
|
||||
RecipeResult result) {
|
||||
super(category, group, result);
|
||||
this.key = key;
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
public Map<Character, List<String>> ingredients() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public String[] pattern() {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
return RecipeTypes.SHAPED;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.vanilla;
|
||||
|
||||
import net.momirealms.craftengine.core.item.recipe.CraftingRecipeCategory;
|
||||
import net.momirealms.craftengine.core.item.recipe.RecipeTypes;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class VanillaShapelessRecipe extends VanillaCraftingRecipe {
|
||||
private final List<List<String>> ingredients;
|
||||
|
||||
public VanillaShapelessRecipe(CraftingRecipeCategory category, String group, List<List<String>> ingredients, RecipeResult result) {
|
||||
super(category, group, result);
|
||||
this.ingredients = ingredients;
|
||||
}
|
||||
|
||||
public List<List<String>> ingredients() {
|
||||
return ingredients;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
return RecipeTypes.SHAPELESS;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package net.momirealms.craftengine.core.item.recipe.vanilla;
|
||||
|
||||
import net.momirealms.craftengine.core.item.recipe.CookingRecipeCategory;
|
||||
import net.momirealms.craftengine.core.item.recipe.RecipeTypes;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class VanillaSmeltingRecipe extends VanillaCookingRecipe {
|
||||
|
||||
public VanillaSmeltingRecipe(CookingRecipeCategory category, String group, RecipeResult result, List<String> ingredient, float experience, int cookingTime) {
|
||||
super(category, group, result, ingredient, experience, cookingTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key type() {
|
||||
return RecipeTypes.SMELTING;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user