diff --git a/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java b/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java index 904853a9..5de07cae 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java @@ -1,6 +1,7 @@ package at.petrak.hexcasting.api.item; import at.petrak.hexcasting.api.spell.iota.Iota; +import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.api.utils.NBTHelper; import at.petrak.hexcasting.common.lib.HexIotaTypes; import net.minecraft.ChatFormatting; @@ -23,6 +24,12 @@ import java.util.List; * and the appropriate cap/CC will be attached. */ public interface IotaHolderItem { + /** + * If this key is set on the item, we ignore the rest of the item and render this as if it were of the + * {@link at.petrak.hexcasting.api.spell.iota.IotaType IotaType} given by the resource location. + *

+ * This is not useful to the player at all. + */ String TAG_OVERRIDE_VISUALLY = "VisualOverride"; @Nullable CompoundTag readIotaTag(ItemStack stack); @@ -47,6 +54,15 @@ public interface IotaHolderItem { return null; } + default int getColor(ItemStack stack) { + var tag = stack.getTag(); + if (tag == null) { + return HexUtils.ERROR_COLOR; + } + + return HexIotaTypes.getColor(tag); + } + boolean canWrite(ItemStack stack, @Nullable Iota iota); void writeDatum(ItemStack stack, @Nullable Iota iota); diff --git a/Common/src/main/java/at/petrak/hexcasting/api/utils/HexUtils.kt b/Common/src/main/java/at/petrak/hexcasting/api/utils/HexUtils.kt index d51d53d6..601514ff 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/utils/HexUtils.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/utils/HexUtils.kt @@ -2,9 +2,11 @@ package at.petrak.hexcasting.api.utils -import at.petrak.hexcasting.api.spell.LegacySpellDatum import at.petrak.hexcasting.api.spell.SpellList +import at.petrak.hexcasting.api.spell.iota.Iota +import at.petrak.hexcasting.api.spell.iota.ListIota import at.petrak.hexcasting.api.spell.math.HexCoord +import at.petrak.hexcasting.common.lib.HexIotaTypes import net.minecraft.ChatFormatting import net.minecraft.nbt.* import net.minecraft.network.chat.* @@ -85,7 +87,7 @@ fun pxToCoord(px: Vec2, size: Float, offset: Vec2): HexCoord { else HexCoord(q, r + (rf + 0.5 * qf).roundToInt()) } -s + fun String.withStyle(op: (Style) -> Style): MutableComponent = asTextComponent.withStyle(op) fun String.withStyle(style: Style): MutableComponent = asTextComponent.withStyle(style) fun String.withStyle(formatting: ChatFormatting): MutableComponent = asTextComponent.withStyle(formatting) @@ -231,13 +233,11 @@ inline operator fun WeakValue.setValue(thisRef: Any?, property: KProperty /** * Returns an empty list if it's too complicated. */ -fun Iterable>.serializeToNBT(): ListTag { - val out = LegacySpellDatum.make(SpellList.LList(0, this.toList())).serializeToNBT() - return if (out.contains(LegacySpellDatum.TAG_WIDGET)) +fun Iterable.serializeToNBT() = + if (HexIotaTypes.isTooLargeToSerialize(this)) ListTag() else - out.getList(LegacySpellDatum.TAG_LIST, Tag.TAG_COMPOUND) -} + ListIota(SpellList.LList(this.toList())).serialize() // Copy the impl from forge fun ItemStack.serializeToNBT(): CompoundTag { @@ -247,7 +247,7 @@ fun ItemStack.serializeToNBT(): CompoundTag { } @Throws(IllegalArgumentException::class) -fun Tag.downcast(type: TagType) : T { +fun Tag.downcast(type: TagType): T { if (this.type == type) { return this as T } else { @@ -256,3 +256,5 @@ fun Tag.downcast(type: TagType) : T { ) } } + +const val ERROR_COLOR = 0xff_f800f8.toInt() diff --git a/Common/src/main/java/at/petrak/hexcasting/client/RegisterClientStuff.java b/Common/src/main/java/at/petrak/hexcasting/client/RegisterClientStuff.java index dde3b323..c7bead1b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/RegisterClientStuff.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/RegisterClientStuff.java @@ -3,11 +3,8 @@ package at.petrak.hexcasting.client; import at.petrak.hexcasting.api.block.circle.BlockAbstractImpetus; import at.petrak.hexcasting.api.block.circle.BlockEntityAbstractImpetus; import at.petrak.hexcasting.api.client.ScryingLensOverlayRegistry; -import at.petrak.hexcasting.api.item.IotaHolderItem; import at.petrak.hexcasting.api.item.MediaHolderItem; import at.petrak.hexcasting.api.misc.ManaConstants; -import at.petrak.hexcasting.api.spell.LegacySpellDatum; -import at.petrak.hexcasting.api.spell.Widget; import at.petrak.hexcasting.api.utils.NBTHelper; import at.petrak.hexcasting.client.be.BlockEntityAkashicBookshelfRenderer; import at.petrak.hexcasting.client.be.BlockEntitySlateRenderer; @@ -16,10 +13,7 @@ import at.petrak.hexcasting.client.particles.ConjureParticle; import at.petrak.hexcasting.common.blocks.akashic.BlockEntityAkashicBookshelf; import at.petrak.hexcasting.common.blocks.akashic.BlockEntityAkashicRecord; import at.petrak.hexcasting.common.entities.HexEntities; -import at.petrak.hexcasting.common.items.ItemFocus; -import at.petrak.hexcasting.common.items.ItemScroll; -import at.petrak.hexcasting.common.items.ItemSlate; -import at.petrak.hexcasting.common.items.ItemWand; +import at.petrak.hexcasting.common.items.*; import at.petrak.hexcasting.common.items.magic.ItemMediaBattery; import at.petrak.hexcasting.common.items.magic.ItemPackagedHex; import at.petrak.hexcasting.common.lib.HexBlockEntities; @@ -29,6 +23,7 @@ import at.petrak.hexcasting.common.lib.HexParticles; import at.petrak.hexcasting.xplat.IClientXplatAbstractions; import com.mojang.datafixers.util.Pair; import net.minecraft.ChatFormatting; +import net.minecraft.client.color.item.ItemColor; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.core.Direction; @@ -49,13 +44,13 @@ import net.minecraft.world.level.material.MaterialColor; import org.jetbrains.annotations.NotNull; import java.util.Locale; +import java.util.function.BiConsumer; +import java.util.function.Predicate; +import java.util.function.ToIntFunction; import java.util.function.UnaryOperator; public class RegisterClientStuff { public static void init() { - registerDataHolderOverrides(HexItems.FOCUS); - registerDataHolderOverrides(HexItems.SPELLBOOK); - registerPackagedSpellOverrides(HexItems.CYPHER); registerPackagedSpellOverrides(HexItems.TRINKET); registerPackagedSpellOverrides(HexItems.ARTIFACT); @@ -107,6 +102,43 @@ public class RegisterClientStuff { addScryingLensStuff(); } + public static void registerColorProviders(BiConsumer colorProviderRegistry) { + colorProviderRegistry.accept(makeIotaStorageColorer( + stack -> HexItems.FOCUS.readIotaTag(stack) != null, + ItemFocus::isSealed, + HexItems.FOCUS::getColor), + HexItems.FOCUS); + colorProviderRegistry.accept(makeIotaStorageColorer( + stack -> HexItems.SPELLBOOK.readIotaTag(stack) != null, + ItemSpellbook::isSealed, + HexItems.SPELLBOOK::getColor), + HexItems.SPELLBOOK); + } + + /** + * Helper function to colorize the layers of an item that stores an iota, in the manner of foci and spellbooks. + *
+ * 0 = base; 1 = unsealed overlay; 2 = sealed overlay. + */ + public static ItemColor makeIotaStorageColorer(Predicate hasIota, Predicate isSealed, + ToIntFunction getColor) { + return (stack, idx) -> { + if (idx == 0) { + return 0xff_000000; + } + if (!hasIota.test(stack)) { + return 0; // no higher overlays + } + + var sealed = isSealed.test(stack); + if (!sealed && idx == 1 || sealed && idx == 2) { + return getColor.applyAsInt(stack); + } else { + return 0; // this layer is invisible + } + }; + } + private static void addScryingLensStuff() { ScryingLensOverlayRegistry.addPredicateDisplayer( (state, pos, observer, world, direction, lensHand) -> state.getBlock() instanceof BlockAbstractImpetus, @@ -253,32 +285,6 @@ public class RegisterClientStuff { (stack, level, holder, holderID) -> NBTHelper.hasString(stack, ItemScroll.TAG_OP_ID) ? 1f : 0f); } - private static void registerDataHolderOverrides(IotaHolderItem item) { - IClientXplatAbstractions.INSTANCE.registerItemProperty((Item) item, ItemFocus.DATATYPE_PRED, - (stack, level, holder, holderID) -> { - var datum = item.readIotaTag(stack); - String override = NBTHelper.getString(stack, IotaHolderItem.TAG_OVERRIDE_VISUALLY); - String typename = null; - if (override != null) { - typename = override; - } else if (datum != null) { - typename = datum.getAllKeys().iterator().next(); - } - - return typename == null ? 0f : switch (typename) { - case LegacySpellDatum.TAG_ENTITY -> 1f; - case LegacySpellDatum.TAG_DOUBLE -> 2f; - case LegacySpellDatum.TAG_VEC3 -> 3f; - case LegacySpellDatum.TAG_WIDGET -> 4f; - case LegacySpellDatum.TAG_LIST -> 5f; - case LegacySpellDatum.TAG_PATTERN -> 6f; - default -> 0f; // uh oh - }; - }); - IClientXplatAbstractions.INSTANCE.registerItemProperty((Item) item, ItemFocus.SEALED_PRED, - (stack, level, holder, holderID) -> item.canWrite(stack, LegacySpellDatum.make(Widget.NULL)) ? 0f : 1f); - } - private static void registerPackagedSpellOverrides(ItemPackagedHex item) { IClientXplatAbstractions.INSTANCE.registerItemProperty(item, ItemPackagedHex.HAS_PATTERNS_PRED, (stack, level, holder, holderID) -> diff --git a/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockStoredPlayerImpetus.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockStoredPlayerImpetus.java index e07c9117..86882450 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockStoredPlayerImpetus.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockStoredPlayerImpetus.java @@ -1,7 +1,7 @@ package at.petrak.hexcasting.common.blocks.circles.impetuses; import at.petrak.hexcasting.api.block.circle.BlockAbstractImpetus; -import at.petrak.hexcasting.api.spell.DatumType; +import at.petrak.hexcasting.api.spell.iota.EntityIota; import at.petrak.hexcasting.common.blocks.entity.BlockEntityStoredPlayerImpetus; import at.petrak.hexcasting.common.lib.HexSounds; import at.petrak.hexcasting.xplat.IXplatAbstractions; @@ -11,7 +11,6 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; @@ -53,15 +52,15 @@ public class BlockStoredPlayerImpetus extends BlockAbstractImpetus { if (datumContainer != null) { if (pLevel instanceof ServerLevel level) { var stored = datumContainer.readIota(level); - if (stored != null && stored.getType() == DatumType.ENTITY) { - var entity = (Entity) stored.getPayload(); + if (stored instanceof EntityIota eieio) { + var entity = eieio.getEntity(); if (entity instanceof Player player) { // phew, we got something tile.setPlayer(player.getGameProfile(), entity.getUUID()); level.sendBlockUpdated(pPos, pState, pState, Block.UPDATE_CLIENTS); - pLevel.playSound(null, pPos, HexSounds.IMPETUS_STOREDPLAYER_DING, SoundSource.BLOCKS, - 1f, 1f); + pLevel.playSound(pPlayer, pPos, HexSounds.IMPETUS_STOREDPLAYER_DING, + SoundSource.BLOCKS, 1f, 1f); } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/ItemFocus.java b/Common/src/main/java/at/petrak/hexcasting/common/items/ItemFocus.java index a1bc751b..8917c155 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/ItemFocus.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/ItemFocus.java @@ -1,9 +1,10 @@ package at.petrak.hexcasting.common.items; import at.petrak.hexcasting.api.item.IotaHolderItem; -import at.petrak.hexcasting.api.spell.LegacySpellDatum; -import at.petrak.hexcasting.api.spell.Widget; +import at.petrak.hexcasting.api.spell.iota.Iota; +import at.petrak.hexcasting.api.spell.iota.NullIota; import at.petrak.hexcasting.api.utils.NBTHelper; +import at.petrak.hexcasting.common.lib.HexIotaTypes; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; @@ -39,22 +40,22 @@ public class ItemFocus extends Item implements IotaHolderItem { } @Override - public @Nullable LegacySpellDatum emptyIota(ItemStack stack) { - return LegacySpellDatum.make(Widget.NULL); + public @Nullable Iota emptyIota(ItemStack stack) { + return new NullIota(); } @Override - public boolean canWrite(ItemStack stack, LegacySpellDatum datum) { + public boolean canWrite(ItemStack stack, Iota datum) { return datum == null || !NBTHelper.getBoolean(stack, TAG_SEALED); } @Override - public void writeDatum(ItemStack stack, LegacySpellDatum datum) { + public void writeDatum(ItemStack stack, Iota datum) { if (datum == null) { stack.removeTagKey(TAG_DATA); stack.removeTagKey(TAG_SEALED); - } else if (!NBTHelper.getBoolean(stack, TAG_SEALED)) { - NBTHelper.put(stack, TAG_DATA, datum.serializeToNBT()); + } else if (!isSealed(stack)) { + NBTHelper.put(stack, TAG_DATA, HexIotaTypes.serialize(datum)); } } @@ -63,4 +64,8 @@ public class ItemFocus extends Item implements IotaHolderItem { TooltipFlag pIsAdvanced) { IotaHolderItem.appendHoverText(this, pStack, pTooltipComponents, pIsAdvanced); } + + public static boolean isSealed(ItemStack stack) { + return NBTHelper.getBoolean(stack, TAG_SEALED); + } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/ItemSpellbook.java b/Common/src/main/java/at/petrak/hexcasting/common/items/ItemSpellbook.java index 8d2e7f8e..ee1cb77b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/ItemSpellbook.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/ItemSpellbook.java @@ -1,9 +1,10 @@ package at.petrak.hexcasting.common.items; import at.petrak.hexcasting.api.item.IotaHolderItem; -import at.petrak.hexcasting.api.spell.LegacySpellDatum; -import at.petrak.hexcasting.api.spell.Widget; +import at.petrak.hexcasting.api.spell.iota.Iota; +import at.petrak.hexcasting.api.spell.iota.NullIota; import at.petrak.hexcasting.api.utils.NBTHelper; +import at.petrak.hexcasting.common.lib.HexIotaTypes; import net.minecraft.ChatFormatting; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; @@ -44,11 +45,11 @@ public class ItemSpellbook extends Item implements IotaHolderItem { @Override public void appendHoverText(ItemStack stack, @Nullable Level level, List tooltip, TooltipFlag isAdvanced) { - boolean sealed = IsSealed(stack); + boolean sealed = isSealed(stack); boolean empty = false; if (NBTHelper.hasNumber(stack, TAG_SELECTED_PAGE)) { var pageIdx = NBTHelper.getInt(stack, TAG_SELECTED_PAGE); - int highest = HighestPage(stack); + int highest = highestPage(stack); if (highest != 0) { if (sealed) { tooltip.add(new TranslatableComponent("hexcasting.tooltip.spellbook.page.sealed", @@ -93,7 +94,7 @@ public class ItemSpellbook extends Item implements IotaHolderItem { @Override public void inventoryTick(ItemStack stack, Level pLevel, Entity pEntity, int pSlotId, boolean pIsSelected) { - int index = GetPage(stack, 0); + int index = getPage(stack, 0); NBTHelper.putInt(stack, TAG_SELECTED_PAGE, index); int shiftedIdx = Math.max(1, index); @@ -106,14 +107,14 @@ public class ItemSpellbook extends Item implements IotaHolderItem { } } - public static boolean ArePagesEmpty(ItemStack stack) { + public static boolean arePagesEmpty(ItemStack stack) { CompoundTag tag = NBTHelper.getCompound(stack, TAG_PAGES); return tag == null || tag.isEmpty(); } @Override public @Nullable CompoundTag readIotaTag(ItemStack stack) { - int idx = GetPage(stack, 1); + int idx = getPage(stack, 1); var key = String.valueOf(idx); var tag = NBTHelper.getCompound(stack, TAG_PAGES); if (tag != null && tag.contains(key, Tag.TAG_COMPOUND)) { @@ -124,22 +125,22 @@ public class ItemSpellbook extends Item implements IotaHolderItem { } @Override - public @Nullable LegacySpellDatum emptyIota(ItemStack stack) { - return LegacySpellDatum.make(Widget.NULL); + public @Nullable Iota emptyIota(ItemStack stack) { + return new NullIota(); } @Override - public boolean canWrite(ItemStack stack, LegacySpellDatum datum) { - return datum == null || !IsSealed(stack); + public boolean canWrite(ItemStack stack, Iota datum) { + return datum == null || !isSealed(stack); } @Override - public void writeDatum(ItemStack stack, LegacySpellDatum datum) { - if (datum != null && IsSealed(stack)) { + public void writeDatum(ItemStack stack, Iota datum) { + if (datum != null && isSealed(stack)) { return; } - int idx = GetPage(stack, 1); + int idx = getPage(stack, 1); var key = String.valueOf(idx); CompoundTag pages = NBTHelper.getCompound(stack, TAG_PAGES); if (pages != null) { @@ -147,21 +148,21 @@ public class ItemSpellbook extends Item implements IotaHolderItem { pages.remove(key); NBTHelper.remove(NBTHelper.getCompound(stack, TAG_SEALED), key); } else { - pages.put(key, datum.serializeToNBT()); + pages.put(key, HexIotaTypes.serialize(datum)); } if (pages.isEmpty()) { NBTHelper.remove(stack, TAG_PAGES); } } else if (datum != null) { - NBTHelper.getOrCreateCompound(stack, TAG_PAGES).put(key, datum.serializeToNBT()); + NBTHelper.getOrCreateCompound(stack, TAG_PAGES).put(key, HexIotaTypes.serialize(datum)); } else { NBTHelper.remove(NBTHelper.getCompound(stack, TAG_SEALED), key); } } - public static int GetPage(ItemStack stack, int ifEmpty) { - if (ArePagesEmpty(stack)) { + public static int getPage(ItemStack stack, int ifEmpty) { + if (arePagesEmpty(stack)) { return ifEmpty; } else if (NBTHelper.hasNumber(stack, TAG_SELECTED_PAGE)) { int index = NBTHelper.getInt(stack, TAG_SELECTED_PAGE); @@ -174,8 +175,8 @@ public class ItemSpellbook extends Item implements IotaHolderItem { } } - public static void SetSealed(ItemStack stack, boolean sealed) { - int index = GetPage(stack, 1); + public static void setSealed(ItemStack stack, boolean sealed) { + int index = getPage(stack, 1); String nameKey = String.valueOf(index); CompoundTag names = NBTHelper.getOrCreateCompound(stack, TAG_SEALED); @@ -194,15 +195,15 @@ public class ItemSpellbook extends Item implements IotaHolderItem { } - public static boolean IsSealed(ItemStack stack) { - int index = GetPage(stack, 1); + public static boolean isSealed(ItemStack stack) { + int index = getPage(stack, 1); String nameKey = String.valueOf(index); CompoundTag names = NBTHelper.getCompound(stack, TAG_SEALED); return NBTHelper.getBoolean(names, nameKey); } - public static int HighestPage(ItemStack stack) { + public static int highestPage(ItemStack stack) { CompoundTag tag = NBTHelper.getCompound(stack, TAG_PAGES); if (tag == null) { return 0; @@ -216,8 +217,8 @@ public class ItemSpellbook extends Item implements IotaHolderItem { }).max(Integer::compare).orElse(0); } - public static int RotatePageIdx(ItemStack stack, boolean increase) { - int idx = GetPage(stack, 0); + public static int rotatePageIdx(ItemStack stack, boolean increase) { + int idx = getPage(stack, 0); if (idx != 0) { idx += increase ? 1 : -1; idx = Math.max(1, idx); diff --git a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexIotaTypes.java b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexIotaTypes.java index f188e602..4415293c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexIotaTypes.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexIotaTypes.java @@ -2,7 +2,9 @@ package at.petrak.hexcasting.common.lib; import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.spell.iota.*; +import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.xplat.IXplatAbstractions; +import com.mojang.datafixers.util.Pair; import net.minecraft.core.Registry; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; @@ -12,6 +14,8 @@ import net.minecraft.server.level.ServerLevel; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; +import java.util.ArrayDeque; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; import java.util.function.BiConsumer; @@ -26,6 +30,8 @@ public class HexIotaTypes { public static final String KEY_TYPE = HexAPI.MOD_ID + ":type", KEY_DATA = HexAPI.MOD_ID + ":data"; + public static final int MAX_SERIALIZATION_DEPTH = 256; + public static final int MAX_SERIALIZATION_TOTAL = 1024; public static CompoundTag serialize(Iota iota) { var type = iota.getType(); @@ -35,6 +41,12 @@ public class HexIotaTypes { "Tried to serialize an unregistered iota type. Iota: " + iota + " ; Type" + type.getClass().getTypeName()); } + + // We check if it's too big on serialization; if it is we just return a garbage. + if (iota instanceof ListIota listIota && isTooLargeToSerialize(listIota.getList())) { + // Garbage will never be too large so we just recurse + return serialize(new GarbageIota()); + } var dataTag = iota.serialize(); var out = new CompoundTag(); out.putString(KEY_TYPE, typeId.toString()); @@ -42,6 +54,34 @@ public class HexIotaTypes { return out; } + public static boolean isTooLargeToSerialize(Iterable examinee) { + // We don't recurse here, just a work queue (or work stack, if we liked.) + // Each element is a found sub-iota, and how deep it is. + // + // TODO: is it worth trying to cache the depth and size statically on a SpellList. + var listsToExamine = new ArrayDeque<>(Collections.singleton(new Pair<>(examinee, 0))); + int totalEltsFound = 1; // count the first list + while (!listsToExamine.isEmpty()) { + var iotaPair = listsToExamine.removeFirst(); + var sublist = iotaPair.getFirst(); + int depth = iotaPair.getSecond(); + for (var iota : sublist) { + totalEltsFound++; + if (totalEltsFound >= MAX_SERIALIZATION_TOTAL) { + return true; // too bad + } + if (iota instanceof ListIota subsublist) { + if (depth + 1 >= MAX_SERIALIZATION_DEPTH) { + return true; + } + listsToExamine.addLast(new Pair<>(subsublist.getList(), depth + 1)); + } + } + } + // we made it! + return false; + } + /** * This method attempts to find the type from the {@code type} key. * See {@link HexIotaTypes#getTypeFromTag} for the storage format. @@ -98,6 +138,14 @@ public class HexIotaTypes { return type.display(tag); } + public static int getColor(CompoundTag tag) { + var type = getTypeFromTag(tag); + if (type == null) { + return HexUtils.ERROR_COLOR; + } + return type.color(); + } + @ApiStatus.Internal public static void registerTypes() { BiConsumer, ResourceLocation> r = (type, id) -> Registry.register(REGISTRY, id, type); diff --git a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgShiftScrollSyn.java b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgShiftScrollSyn.java index bff44706..75f1cdaa 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgShiftScrollSyn.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgShiftScrollSyn.java @@ -60,11 +60,11 @@ public record MsgShiftScrollSyn(InteractionHand hand, double scrollDelta, boolea } private void spellbook(ServerPlayer sender, ItemStack stack) { - var newIdx = ItemSpellbook.RotatePageIdx(stack, this.scrollDelta < 0.0); + var newIdx = ItemSpellbook.rotatePageIdx(stack, this.scrollDelta < 0.0); - var len = ItemSpellbook.HighestPage(stack); + var len = ItemSpellbook.highestPage(stack); - var sealed = ItemSpellbook.IsSealed(stack); + var sealed = ItemSpellbook.isSealed(stack); MutableComponent component; if (hand == InteractionHand.OFF_HAND && stack.hasCustomHoverName()) { diff --git a/Common/src/main/java/at/petrak/hexcasting/common/recipe/SealSpellbookRecipe.java b/Common/src/main/java/at/petrak/hexcasting/common/recipe/SealSpellbookRecipe.java index 3a18cb98..49156f35 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/recipe/SealSpellbookRecipe.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/recipe/SealSpellbookRecipe.java @@ -22,7 +22,7 @@ public class SealSpellbookRecipe extends ShapelessRecipe { private static ItemStack getSealedStack() { ItemStack output = new ItemStack(HexItems.SPELLBOOK); - ItemSpellbook.SetSealed(output, true); + ItemSpellbook.setSealed(output, true); NBTHelper.putString(output, IotaHolderItem.TAG_OVERRIDE_VISUALLY, "any"); return output; } @@ -51,7 +51,7 @@ public class SealSpellbookRecipe extends ShapelessRecipe { } if (!out.isEmpty()) { - ItemSpellbook.SetSealed(out, true); + ItemSpellbook.setSealed(out, true); out.setCount(1); } diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/focus/empty.png b/Common/src/main/resources/assets/hexcasting/textures/item/focus.png similarity index 100% rename from Common/src/main/resources/assets/hexcasting/textures/item/focus/empty.png rename to Common/src/main/resources/assets/hexcasting/textures/item/focus.png diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/focus/double.png b/Common/src/main/resources/assets/hexcasting/textures/item/focus/double.png deleted file mode 100644 index 8fcfc814..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/focus/double.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/focus/double_sealed.png b/Common/src/main/resources/assets/hexcasting/textures/item/focus/double_sealed.png deleted file mode 100644 index 55924d2f..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/focus/double_sealed.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/focus/empty_sealed.png b/Common/src/main/resources/assets/hexcasting/textures/item/focus/empty_sealed.png deleted file mode 100644 index 67cbfaad..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/focus/empty_sealed.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/focus/entity.png b/Common/src/main/resources/assets/hexcasting/textures/item/focus/entity.png deleted file mode 100644 index 7dedb90e..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/focus/entity.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/focus/entity_sealed.png b/Common/src/main/resources/assets/hexcasting/textures/item/focus/entity_sealed.png deleted file mode 100644 index ed126ecc..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/focus/entity_sealed.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/focus/list.png b/Common/src/main/resources/assets/hexcasting/textures/item/focus/list.png deleted file mode 100644 index a9f1a03f..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/focus/list.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/focus/list_sealed.png b/Common/src/main/resources/assets/hexcasting/textures/item/focus/list_sealed.png deleted file mode 100644 index 9701fe2c..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/focus/list_sealed.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/focus/pattern.png b/Common/src/main/resources/assets/hexcasting/textures/item/focus/pattern.png deleted file mode 100644 index 0ecb01d3..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/focus/pattern.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/focus/pattern_sealed.png b/Common/src/main/resources/assets/hexcasting/textures/item/focus/pattern_sealed.png deleted file mode 100644 index 65e1aa60..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/focus/pattern_sealed.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/focus/vec3.png b/Common/src/main/resources/assets/hexcasting/textures/item/focus/vec3.png deleted file mode 100644 index 1435f013..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/focus/vec3.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/focus/vec3_sealed.png b/Common/src/main/resources/assets/hexcasting/textures/item/focus/vec3_sealed.png deleted file mode 100644 index 6da7da3b..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/focus/vec3_sealed.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/focus/widget.png b/Common/src/main/resources/assets/hexcasting/textures/item/focus/widget.png deleted file mode 100644 index 0910c9b4..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/focus/widget.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/focus/widget_sealed.png b/Common/src/main/resources/assets/hexcasting/textures/item/focus/widget_sealed.png deleted file mode 100644 index 6c356b7a..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/focus/widget_sealed.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/focus_overlay.png b/Common/src/main/resources/assets/hexcasting/textures/item/focus_overlay.png new file mode 100644 index 00000000..77083e21 Binary files /dev/null and b/Common/src/main/resources/assets/hexcasting/textures/item/focus_overlay.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/focus_overlay_sealed.png b/Common/src/main/resources/assets/hexcasting/textures/item/focus_overlay_sealed.png new file mode 100644 index 00000000..5f4fb69a Binary files /dev/null and b/Common/src/main/resources/assets/hexcasting/textures/item/focus_overlay_sealed.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook.png b/Common/src/main/resources/assets/hexcasting/textures/item/spellbook.png new file mode 100644 index 00000000..f6532ab6 Binary files /dev/null and b/Common/src/main/resources/assets/hexcasting/textures/item/spellbook.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/double.png b/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/double.png deleted file mode 100644 index 9241b159..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/double.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/double_sealed.png b/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/double_sealed.png deleted file mode 100644 index b66ced29..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/double_sealed.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/empty.png b/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/empty.png deleted file mode 100644 index 0b919d27..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/empty.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/empty_sealed.png b/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/empty_sealed.png deleted file mode 100644 index c5a5c642..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/empty_sealed.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/entity.png b/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/entity.png deleted file mode 100644 index 1332ae6d..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/entity.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/entity_sealed.png b/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/entity_sealed.png deleted file mode 100644 index fec01c29..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/entity_sealed.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/list.png b/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/list.png deleted file mode 100644 index b8872f7a..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/list.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/list_sealed.png b/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/list_sealed.png deleted file mode 100644 index 02553f38..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/list_sealed.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/pattern.png b/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/pattern.png deleted file mode 100644 index 65ca7d05..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/pattern.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/pattern_sealed.png b/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/pattern_sealed.png deleted file mode 100644 index 8c458496..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/pattern_sealed.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/vec3.png b/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/vec3.png deleted file mode 100644 index a4886c82..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/vec3.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/vec3_sealed.png b/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/vec3_sealed.png deleted file mode 100644 index 766704e9..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/vec3_sealed.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/widget.png b/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/widget.png deleted file mode 100644 index 8adec2af..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/widget.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/widget_sealed.png b/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/widget_sealed.png deleted file mode 100644 index 5feb35dd..00000000 Binary files a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook/widget_sealed.png and /dev/null differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook_overlay.png b/Common/src/main/resources/assets/hexcasting/textures/item/spellbook_overlay.png new file mode 100644 index 00000000..e6f266d1 Binary files /dev/null and b/Common/src/main/resources/assets/hexcasting/textures/item/spellbook_overlay.png differ diff --git a/Common/src/main/resources/assets/hexcasting/textures/item/spellbook_overlay_sealed.png b/Common/src/main/resources/assets/hexcasting/textures/item/spellbook_overlay_sealed.png new file mode 100644 index 00000000..08dbe6f0 Binary files /dev/null and b/Common/src/main/resources/assets/hexcasting/textures/item/spellbook_overlay_sealed.png differ diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/FabricHexClientInitializer.kt b/Fabric/src/main/java/at/petrak/hexcasting/fabric/FabricHexClientInitializer.kt index 36fcecda..244cad32 100644 --- a/Fabric/src/main/java/at/petrak/hexcasting/fabric/FabricHexClientInitializer.kt +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/FabricHexClientInitializer.kt @@ -9,6 +9,7 @@ import at.petrak.hexcasting.fabric.network.FabricPacketHandler import net.fabricmc.api.ClientModInitializer import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents import net.fabricmc.fabric.api.client.rendering.v1.BlockEntityRendererRegistry +import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider @@ -47,5 +48,8 @@ object FabricHexClientInitializer : ClientModInitializer { BlockEntityRendererRegistry.register(type, berp) } }) + RegisterClientStuff.registerColorProviders { colorizer, item -> + ColorProviderRegistry.ITEM.register(colorizer, item) + } } } diff --git a/Forge/src/main/java/at/petrak/hexcasting/forge/ForgeHexClientInitializer.java b/Forge/src/main/java/at/petrak/hexcasting/forge/ForgeHexClientInitializer.java index 2bf43a09..04d3759d 100644 --- a/Forge/src/main/java/at/petrak/hexcasting/forge/ForgeHexClientInitializer.java +++ b/Forge/src/main/java/at/petrak/hexcasting/forge/ForgeHexClientInitializer.java @@ -5,6 +5,7 @@ import at.petrak.hexcasting.client.HexAdditionalRenderers; import at.petrak.hexcasting.client.RegisterClientStuff; import at.petrak.hexcasting.client.ShiftScrollListener; import at.petrak.hexcasting.client.shader.HexShaders; +import net.minecraft.client.color.item.ItemColors; import net.minecraftforge.client.event.*; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.TickEvent; @@ -16,9 +17,18 @@ import java.io.IOException; // This is Java because I can't kotlin-fu some of the consumers public class ForgeHexClientInitializer { + // We copy Fabric's example; it mixes in on the return of the initializer and sticks it in a global variable. + // So here's our global. + public static ItemColors GLOBAL_ITEM_COLORS; + @SubscribeEvent public static void clientInit(FMLClientSetupEvent evt) { - evt.enqueueWork(RegisterClientStuff::init); + evt.enqueueWork(() -> { + RegisterClientStuff.init(); + RegisterClientStuff.registerColorProviders((colorizer, item) -> { + GLOBAL_ITEM_COLORS.register(colorizer, item); + }); + }); var evBus = MinecraftForge.EVENT_BUS; diff --git a/Forge/src/main/java/at/petrak/hexcasting/forge/mixin/ForgeMixinItemColors.java b/Forge/src/main/java/at/petrak/hexcasting/forge/mixin/ForgeMixinItemColors.java new file mode 100644 index 00000000..2ef14ac4 --- /dev/null +++ b/Forge/src/main/java/at/petrak/hexcasting/forge/mixin/ForgeMixinItemColors.java @@ -0,0 +1,17 @@ +package at.petrak.hexcasting.forge.mixin; + +import at.petrak.hexcasting.forge.ForgeHexClientInitializer; +import net.minecraft.client.color.block.BlockColors; +import net.minecraft.client.color.item.ItemColors; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(ItemColors.class) +public class ForgeMixinItemColors { + @Inject(method = "createDefault", at = @At("RETURN")) + private static void hex$onCreateDefault(BlockColors blockColors, CallbackInfoReturnable info) { + ForgeHexClientInitializer.GLOBAL_ITEM_COLORS = info.getReturnValue(); + } +} diff --git a/Forge/src/main/java/at/petrak/hexcasting/forge/recipe/ForgeUnsealedIngredient.java b/Forge/src/main/java/at/petrak/hexcasting/forge/recipe/ForgeUnsealedIngredient.java index b34ea5b3..dfd28d7d 100644 --- a/Forge/src/main/java/at/petrak/hexcasting/forge/recipe/ForgeUnsealedIngredient.java +++ b/Forge/src/main/java/at/petrak/hexcasting/forge/recipe/ForgeUnsealedIngredient.java @@ -2,10 +2,9 @@ package at.petrak.hexcasting.forge.recipe; import at.petrak.hexcasting.api.addldata.ADIotaHolder; import at.petrak.hexcasting.api.item.IotaHolderItem; -import at.petrak.hexcasting.api.spell.DatumType; -import at.petrak.hexcasting.api.spell.LegacySpellDatum; -import at.petrak.hexcasting.api.spell.Widget; +import at.petrak.hexcasting.api.spell.iota.NullIota; import at.petrak.hexcasting.api.utils.NBTHelper; +import at.petrak.hexcasting.common.lib.HexIotaTypes; import at.petrak.hexcasting.xplat.IXplatAbstractions; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -19,18 +18,16 @@ import net.minecraftforge.common.crafting.NBTIngredient; import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; -import java.util.Arrays; import java.util.Objects; public class ForgeUnsealedIngredient extends AbstractIngredient { private final ItemStack stack; protected ForgeUnsealedIngredient(ItemStack stack) { - super(Arrays.stream(DatumType.values()) - .filter((it) -> it != DatumType.EMPTY && it != DatumType.OTHER) - .map((type) -> { + super(HexIotaTypes.REGISTRY.keySet().stream() + .map(it -> { ItemStack newStack = stack.copy(); - NBTHelper.putString(newStack, IotaHolderItem.TAG_OVERRIDE_VISUALLY, LegacySpellDatum.tagForType(type)); + NBTHelper.putString(newStack, IotaHolderItem.TAG_OVERRIDE_VISUALLY, it.toString()); return new Ingredient.ItemValue(newStack); })); this.stack = stack; @@ -51,7 +48,7 @@ public class ForgeUnsealedIngredient extends AbstractIngredient { if (this.stack.getItem() == input.getItem() && this.stack.getDamageValue() == input.getDamageValue()) { ADIotaHolder holder = IXplatAbstractions.INSTANCE.findDataHolder(this.stack); if (holder != null) { - return holder.readIotaTag() != null && holder.writeIota(LegacySpellDatum.make(Widget.NULL), true); + return holder.readIotaTag() != null && holder.writeIota(new NullIota(), true); } } diff --git a/Forge/src/main/resources/hexcasting_forge.mixins.json b/Forge/src/main/resources/hexcasting_forge.mixins.json index fcd07e72..769314d2 100644 --- a/Forge/src/main/resources/hexcasting_forge.mixins.json +++ b/Forge/src/main/resources/hexcasting_forge.mixins.json @@ -4,5 +4,5 @@ "compatibilityLevel": "JAVA_17", "refmap": "hexcasting.mixins.refmap.json", "package": "at.petrak.hexcasting.forge.mixin", - "mixins": ["ForgeAccessorRegistry", "ForgeMixinCursedRecipeSerializerBase"] + "mixins": ["ForgeAccessorRegistry", "ForgeMixinCursedRecipeSerializerBase"], "client": ["ForgeMixinItemColors"] }