From ad4141ed2fde33ec1557cce47bb73267548e91ae Mon Sep 17 00:00:00 2001 From: Albazavr Date: Wed, 24 Jun 2026 15:50:28 +0300 Subject: [PATCH 01/10] Items port --- .../item/CustomDamageSwordItem.java | 8 - .../twilightforest/item/EmptyMazeMapItem.java | 2 +- .../twilightforest/item/MagicMapItem.java | 5 +- .../java/twilightforest/item/MazeMapItem.java | 4 +- .../twilightforest/item/MoonDialItem.java | 16 +- .../twilightforest/item/food/TFFoods.java | 1 - .../item/mapdata/TFMagicMapData.java | 153 ++++++++---------- .../item/mapdata/TFMazeMapData.java | 81 ++++------ .../travellers_gear/TravellersArmorItem.java | 6 +- .../travellers_gear/TravellersGearLogic.java | 6 +- .../TransferableComponentModifier.java | 19 ++- .../modifiers/TravellersEntryModifier.java | 5 +- 12 files changed, 135 insertions(+), 171 deletions(-) diff --git a/src/main/java/twilightforest/item/CustomDamageSwordItem.java b/src/main/java/twilightforest/item/CustomDamageSwordItem.java index edd0660c24..860e284988 100644 --- a/src/main/java/twilightforest/item/CustomDamageSwordItem.java +++ b/src/main/java/twilightforest/item/CustomDamageSwordItem.java @@ -5,12 +5,9 @@ import net.minecraft.world.damagesource.DamageType; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.Item; -import net.minecraft.world.item.Tier; -import net.minecraft.world.item.component.Tool; //TODO data component-itize this public class CustomDamageSwordItem extends Item implements CustomDamageProvider { - private final ResourceKey damageType; public CustomDamageSwordItem(ResourceKey damageType, Properties properties) { @@ -18,11 +15,6 @@ public CustomDamageSwordItem(ResourceKey damageType, Properties prop this.damageType = damageType; } - public CustomDamageSwordItem(ResourceKey damageType, Tier tier, Properties properties, Tool toolComponentData) { - super(tier, properties, toolComponentData); - this.damageType = damageType; - } - @Override public DamageSource getDamageSource(LivingEntity attacker) { return attacker.damageSources().source(this.damageType, attacker); diff --git a/src/main/java/twilightforest/item/EmptyMazeMapItem.java b/src/main/java/twilightforest/item/EmptyMazeMapItem.java index 1f80e67c1d..d9345dafd2 100644 --- a/src/main/java/twilightforest/item/EmptyMazeMapItem.java +++ b/src/main/java/twilightforest/item/EmptyMazeMapItem.java @@ -27,7 +27,7 @@ public InteractionResult use(Level level, Player player, InteractionHand hand) { itemStack.consume(1, player); player.awardStat(Stats.ITEM_USED.get(this)); serverLevel.playSound(null, player, SoundEvents.UI_CARTOGRAPHY_TABLE_TAKE_RESULT, player.getSoundSource(), 1.0F, 1.0F); - ItemStack map = MazeMapItem.setupNewMap(level, Mth.floor(player.getX()), Mth.floor(player.getZ()), (byte) 0, true, false, Mth.floor(player.getY()), this.mapOres); + ItemStack map = MazeMapItem.setupNewMap(serverLevel, Mth.floor(player.getX()), Mth.floor(player.getZ()), (byte) 0, true, false, Mth.floor(player.getY()), this.mapOres); if (itemStack.isEmpty()) { return InteractionResult.SUCCESS.heldItemTransformedTo(map); } else { diff --git a/src/main/java/twilightforest/item/MagicMapItem.java b/src/main/java/twilightforest/item/MagicMapItem.java index f54218a59b..5e449053b1 100644 --- a/src/main/java/twilightforest/item/MagicMapItem.java +++ b/src/main/java/twilightforest/item/MagicMapItem.java @@ -37,7 +37,6 @@ // [VanillaCopy] super everything, but with appropriate redirections to our own datastructures. finer details noted public class MagicMapItem extends MapItem { - public static final String STR_ID = "magicmap"; public MagicMapItem(Properties properties) { @@ -53,7 +52,7 @@ public static ItemStack setupNewMap(ServerLevel level, int worldX, int worldZ, b @Nullable public static TFMagicMapData getData(ItemStack stack, Level level) { MapId mapid = stack.get(DataComponents.MAP_ID); - return mapid == null ? null : TFMagicMapData.getMagicMapData(level, getMapName(mapid.id())); + return mapid == null ? null : TFMagicMapData.getMagicMapData(level, mapid); } @Nullable @@ -89,7 +88,7 @@ private static TFMagicMapData createMapData(ItemStack stack, ServerLevel level, ColumnPos pos = getMagicMapCenter(x, z); TFMagicMapData mapdata = new TFMagicMapData(pos.x(), pos.z(), (byte) scale, trackingPosition, unlimitedTracking, false, dimension); - TFMagicMapData.registerMagicMapData(level, mapdata, getMapName(freeMapId.id())); // call our own register method + TFMagicMapData.registerMagicMapData(level, mapdata, new MapId(freeMapId.id())); // call our own register method stack.set(DataComponents.MAP_ID, freeMapId); return mapdata; } diff --git a/src/main/java/twilightforest/item/MazeMapItem.java b/src/main/java/twilightforest/item/MazeMapItem.java index d23a3a21e3..9f90453c9b 100644 --- a/src/main/java/twilightforest/item/MazeMapItem.java +++ b/src/main/java/twilightforest/item/MazeMapItem.java @@ -54,7 +54,7 @@ public static ItemStack setupNewMap(ServerLevel level, int worldX, int worldZ, b @Nullable public static TFMazeMapData getData(ItemStack stack, Level level) { MapId id = stack.get(DataComponents.MAP_ID); - return id == null ? null : TFMazeMapData.getMazeMapData(level, getMapName(id.id())); + return id == null ? null : TFMazeMapData.getMazeMapData(level, id); } @Nullable @@ -81,7 +81,7 @@ private static TFMazeMapData createMapData(ItemStack stack, ServerLevel level, i TFMazeMapData mapdata = new TFMazeMapData(scaledX, scaledZ, (byte) scale, trackingPosition, unlimitedTracking, false, dimension); mapdata.calculateMapCenter(level, x, y, z); // call our own map center calculation mapdata.ore = ore; - TFMazeMapData.registerMazeMapData(level, mapdata, getMapName(i.id())); // call our own register method + TFMazeMapData.registerMazeMapData(level, mapdata, i); // call our own register method stack.set(DataComponents.MAP_ID, i); return mapdata; } diff --git a/src/main/java/twilightforest/item/MoonDialItem.java b/src/main/java/twilightforest/item/MoonDialItem.java index 6e2530493f..32b8706a89 100644 --- a/src/main/java/twilightforest/item/MoonDialItem.java +++ b/src/main/java/twilightforest/item/MoonDialItem.java @@ -1,6 +1,8 @@ package twilightforest.item; import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.world.attribute.EnvironmentAttributes; @@ -9,11 +11,10 @@ import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.component.TooltipDisplay; import net.minecraft.world.level.Level; -import net.minecraft.world.level.MoonPhase; -import org.jspecify.annotations.Nullable; - import java.time.LocalDate; import java.util.function.Consumer; +import org.jetbrains.annotations.Nullable; +import twilightforest.util.MoonPhaseConverter; public class MoonDialItem extends Item { public MoonDialItem(Properties properties) { @@ -22,18 +23,19 @@ public MoonDialItem(Properties properties) { @Override public void appendHoverText(ItemStack stack, TooltipContext context, TooltipDisplay display, Consumer builder, TooltipFlag flag) { - builder.accept(getMoonPhase(context.level()).withStyle(ChatFormatting.GRAY)); + BlockPos pos = Minecraft.getInstance().player != null ? Minecraft.getInstance().player.blockPosition() : BlockPos.ZERO; + builder.accept(getMoonPhase(context.level(), pos).withStyle(ChatFormatting.GRAY)); } - public static MutableComponent getMoonPhase(@Nullable Level level) { + public static MutableComponent getMoonPhase(@Nullable Level level, BlockPos pos) { String phaseType; if (level != null && !level.dimensionType().hasFixedTime()) { - MoonPhase phase = level.environmentAttributes().getDimensionValue(EnvironmentAttributes.MOON_PHASE); + var phase = level.environmentAttributes().getValue(EnvironmentAttributes.MOON_PHASE, pos); phaseType = phase.getSerializedName(); } else { boolean aprilFools = LocalDate.of(LocalDate.now().getYear(), 4, 1).equals(LocalDate.now()); phaseType = aprilFools ? "unknown_fools" : "unknown"; } - return Component.translatable("item.twilightforest.moon_dial.phase_" + phaseType); + return Component.translatable("item.twilightforest.moon_dial.phase_" + MoonPhaseConverter.convertPhaseToIndex(phaseType)); } } \ No newline at end of file diff --git a/src/main/java/twilightforest/item/food/TFFoods.java b/src/main/java/twilightforest/item/food/TFFoods.java index c00456fdb0..8745237008 100644 --- a/src/main/java/twilightforest/item/food/TFFoods.java +++ b/src/main/java/twilightforest/item/food/TFFoods.java @@ -4,7 +4,6 @@ import net.minecraft.world.food.Foods; public class TFFoods extends Foods { - public static final FoodProperties TORCHBERRIES = new FoodProperties.Builder().alwaysEdible().build(); public static final FoodProperties RAW_VENISON = new FoodProperties.Builder().nutrition(3).saturationModifier(0.3F).build(); public static final FoodProperties VENISON_STEAK = new FoodProperties.Builder().nutrition(8).saturationModifier(0.8F).build(); diff --git a/src/main/java/twilightforest/item/mapdata/TFMagicMapData.java b/src/main/java/twilightforest/item/mapdata/TFMagicMapData.java index b8f9040ed7..bd81d79f09 100644 --- a/src/main/java/twilightforest/item/mapdata/TFMagicMapData.java +++ b/src/main/java/twilightforest/item/mapdata/TFMagicMapData.java @@ -3,126 +3,109 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.Holder; -import net.minecraft.core.HolderLookup; -import net.minecraft.nbt.*; +import net.minecraft.core.registries.Registries; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.ClientboundMapItemDataPacket; import net.minecraft.resources.ResourceKey; import net.minecraft.server.level.ServerLevel; -import net.minecraft.util.datafix.DataFixTypes; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.saveddata.SavedData; import net.minecraft.world.level.saveddata.maps.MapDecoration; import net.minecraft.world.level.saveddata.maps.MapDecorationType; import net.minecraft.world.level.saveddata.maps.MapId; import net.minecraft.world.level.saveddata.maps.MapItemSavedData; import org.jetbrains.annotations.Nullable; -import twilightforest.TwilightForestMod; import twilightforest.item.MagicMapItem; import twilightforest.network.MagicMapPacket; import twilightforest.util.Codecs; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public class TFMagicMapData extends MapItemSavedData { - private static final Map CLIENT_DATA = new HashMap<>(); - public final List conqueredStructures = new ArrayList<>(); - - public TFMagicMapData(int x, int z, byte scale, boolean trackpos, boolean unlimited, boolean locked, ResourceKey dim) { - super(x, z, scale, trackpos, unlimited, locked, dim); - } - - public static TFMagicMapData load(CompoundTag nbt, HolderLookup.Provider provider) { - MapItemSavedData data = MapItemSavedData.load(nbt, provider); - final boolean trackingPosition = !nbt.contains("trackingPosition", 1) || nbt.getBoolean("trackingPosition"); - final boolean unlimitedTracking = nbt.getBoolean("unlimitedTracking"); - final boolean locked = nbt.getBoolean("locked"); - TFMagicMapData tfdata = new TFMagicMapData(data.centerX, data.centerZ, data.scale, trackingPosition, unlimitedTracking, locked, data.dimension); - - tfdata.colors = data.colors; - tfdata.bannerMarkers.putAll(data.bannerMarkers); - tfdata.frameMarkers.putAll(data.frameMarkers); - - for (DecorationHolder decoration : DecorationHolder.CODEC.listOf() - .parse(provider.createSerializationContext(NbtOps.INSTANCE), nbt.get("decorations")) - .resultOrPartial(error -> TwilightForestMod.LOGGER.warn("Failed to parse map decoration: '{}'", error)) - .orElse(List.of())) { - MapDecoration mapdecoration1 = decoration.decoration(); - MapDecoration mapdecoration = tfdata.decorations.put(decoration.id(), mapdecoration1); - if (!mapdecoration1.equals(mapdecoration)) { - if (mapdecoration != null && mapdecoration.type().value().trackCount()) { - tfdata.trackedDecorationCount--; - } + private static final Codec COLORS_CODEC = Codec.BYTE.listOf() + .xmap(list -> { + byte[] arr = new byte[list.size()]; + for (int i = 0; i < list.size(); i++) arr[i] = list.get(i); + return arr; + }, array -> { + List list = new ArrayList<>(array.length); + for (byte b : array) list.add(b); + return list; + }); - if (decoration.decoration().type().value().trackCount()) { - tfdata.trackedDecorationCount++; + public static final Codec CODEC = RecordCodecBuilder.create(instance -> + instance.group( + Codec.INT.fieldOf("xCenter").forGetter(data -> data.centerX), + Codec.INT.fieldOf("zCenter").forGetter(data -> data.centerZ), + Codec.BYTE.fieldOf("scale").forGetter(data -> data.scale), + Codec.BOOL.optionalFieldOf("trackingPosition", true).forGetter(data -> data.trackingPosition), + Codec.BOOL.optionalFieldOf("unlimitedTracking", false).forGetter(data -> data.unlimitedTracking), + Codec.BOOL.optionalFieldOf("locked", false).forGetter(data -> data.locked), + ResourceKey.codec(Registries.DIMENSION).fieldOf("dimension").forGetter(data -> data.dimension), + COLORS_CODEC.fieldOf("colors").forGetter(data -> data.colors), + DecorationHolder.CODEC.listOf().optionalFieldOf("decorations", List.of()).forGetter(data -> { + List holders = new ArrayList<>(); + data.decorations.forEach((s, decoration) -> { + if (decoration.type().value().showOnItemFrame()) { + holders.add(new DecorationHolder(s, decoration)); + } + }); + return holders; + }), + Codec.STRING.listOf().optionalFieldOf("conquered_structures", List.of()).forGetter(data -> data.conqueredStructures) + ).apply(instance, (centerX, centerZ, scale, trackingPosition, unlimitedTracking, locked, dimension, colorsArray, decorationsList, conqueredList) -> { + TFMagicMapData tfdata = new TFMagicMapData(centerX, centerZ, scale, trackingPosition, unlimitedTracking, locked, dimension); + if (colorsArray.length == tfdata.colors.length) { + System.arraycopy(colorsArray, 0, tfdata.colors, 0, colorsArray.length); + } + for (DecorationHolder decoration : decorationsList) { + MapDecoration mapdecoration1 = decoration.decoration(); + MapDecoration mapdecoration = tfdata.decorations.put(decoration.id(), mapdecoration1); + if (!mapdecoration1.equals(mapdecoration)) { + if (mapdecoration != null && mapdecoration.type().value().trackCount()) { + tfdata.trackedDecorationCount--; + } + if (decoration.decoration().type().value().trackCount()) { + tfdata.trackedDecorationCount++; + } + tfdata.setDecorationsDirty(); } - tfdata.setDecorationsDirty(); } - } - - if (nbt.contains("conquered_structures", Tag.TAG_LIST)) { tfdata.conqueredStructures.clear(); - ListTag tag = nbt.getList("conquered_structures", Tag.TAG_STRING); - tag.forEach(tag1 -> tfdata.conqueredStructures.add(tag1.getAsString())); - } - - return tfdata; - } + tfdata.conqueredStructures.addAll(conqueredList); + return tfdata; + }) + ); - @Override - public CompoundTag save(CompoundTag tag, HolderLookup.Provider provider) { - tag = super.save(tag, provider); - - List holders = new ArrayList<>(); - this.decorations.forEach((s, decoration) -> { - if (decoration.type().value().showOnItemFrame()) { - holders.add(new DecorationHolder(s, decoration)); - } - }); - tag.put("decorations", DecorationHolder.CODEC.listOf().encodeStart(NbtOps.INSTANCE, holders).getOrThrow()); - - if (!this.conqueredStructures.isEmpty()) { - ListTag conqueredTag = new ListTag(); - for (String structure : this.conqueredStructures) { - conqueredTag.add(StringTag.valueOf(structure)); - } - tag.put("conquered_structures", conqueredTag); - } + private static final Map CLIENT_DATA = new HashMap<>(); + public final List conqueredStructures = new ArrayList<>(); - return tag; + public TFMagicMapData(int x, int z, byte scale, boolean trackpos, boolean unlimited, boolean locked, ResourceKey dim) { + super(x, z, scale, trackpos, unlimited, locked, dim); } // [VanillaCopy] Adapted from World.getMapData @Nullable - public static TFMagicMapData getMagicMapData(Level level, String name) { - if (level instanceof ServerLevel serverLevel) return (TFMagicMapData) serverLevel.getServer().overworld().getDataStorage().get(TFMagicMapData.factory(), name); - else return CLIENT_DATA.get(name); + public static TFMagicMapData getMagicMapData(Level level, MapId mapId) { + if (level instanceof ServerLevel serverLevel) { + MapItemSavedData baseData = serverLevel.getServer().overworld().getMapData(mapId); + if (baseData instanceof TFMagicMapData tfData) { + return tfData; + } + return null; + } else { + return CLIENT_DATA.get(mapId); + } } - // Like the method above, but if we know we're on client - @Nullable - public static TFMagicMapData getClientMagicMapData(String name) { - return CLIENT_DATA.get(name); - } // [VanillaCopy] Adapted from World.registerMapData - public static void registerMagicMapData(Level level, TFMagicMapData data, String id) { - if (level instanceof ServerLevel serverLevel) serverLevel.getServer().overworld().getDataStorage().set(id, data); + public static void registerMagicMapData(Level level, TFMagicMapData data, MapId id) { + if (level instanceof ServerLevel serverLevel) serverLevel.getServer().overworld().getDataStorage().set(type(id), data); else CLIENT_DATA.put(id, data); } - public static Factory factory() { - return new SavedData.Factory<>(() -> { - throw new IllegalStateException("Should never create an empty map saved data"); - }, TFMagicMapData::load, DataFixTypes.SAVED_DATA_MAP_DATA); - } - @Nullable @Override public Packet getUpdatePacket(MapId mapId, Player player) { diff --git a/src/main/java/twilightforest/item/mapdata/TFMazeMapData.java b/src/main/java/twilightforest/item/mapdata/TFMazeMapData.java index 5c40cbf91a..c689bc4ac0 100644 --- a/src/main/java/twilightforest/item/mapdata/TFMazeMapData.java +++ b/src/main/java/twilightforest/item/mapdata/TFMazeMapData.java @@ -1,16 +1,15 @@ package twilightforest.item.mapdata; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.BlockPos; -import net.minecraft.core.HolderLookup; -import net.minecraft.nbt.CompoundTag; +import net.minecraft.core.registries.Registries; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.ClientboundMapItemDataPacket; import net.minecraft.resources.ResourceKey; import net.minecraft.server.level.ServerLevel; -import net.minecraft.util.datafix.DataFixTypes; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; -import net.minecraft.world.level.saveddata.SavedData; import net.minecraft.world.level.saveddata.maps.MapId; import net.minecraft.world.level.saveddata.maps.MapItemSavedData; import org.jetbrains.annotations.Nullable; @@ -22,7 +21,23 @@ import java.util.Map; public class TFMazeMapData extends MapItemSavedData { - private static final Map CLIENT_DATA = new HashMap<>(); + private static final Map CLIENT_DATA = new HashMap<>(); + + public static final Codec CODEC = RecordCodecBuilder.create(instance -> + instance.group( + Codec.INT.fieldOf("xCenter").forGetter(data -> data.centerX), + Codec.INT.fieldOf("zCenter").forGetter(data -> data.centerZ), + Codec.BYTE.fieldOf("scale").forGetter(data -> data.scale), + Codec.BOOL.optionalFieldOf("trackingPosition", true).forGetter(data -> true), + Codec.BOOL.optionalFieldOf("unlimitedTracking", false).forGetter(data -> false), + Codec.BOOL.optionalFieldOf("locked", false).forGetter(data -> data.locked), + ResourceKey.codec(Registries.DIMENSION).fieldOf("dimension").forGetter(data -> data.dimension) + ).apply(instance, (centerX, centerZ, scale, trackingPosition, unlimitedTracking, locked, dimension) -> { + TFMazeMapData mazeData = new TFMazeMapData(centerX, centerZ, scale, trackingPosition, unlimitedTracking, locked, dimension); + return mazeData; + }) + ); + public int yCenter; public boolean ore; @@ -31,33 +46,6 @@ public TFMazeMapData(int x, int z, byte scale, boolean trackpos, boolean unlimit super(x, z, scale, trackpos, unlimited, locked, dim); } - public static TFMazeMapData load(CompoundTag nbt, HolderLookup.Provider provider) { - MapItemSavedData data = MapItemSavedData.load(nbt, provider); - final boolean trackingPosition = !nbt.contains("trackingPosition", 1) || nbt.getBoolean("trackingPosition"); - final boolean unlimitedTracking = nbt.getBoolean("unlimitedTracking"); - final boolean locked = nbt.getBoolean("locked"); - TFMazeMapData tfdata = new TFMazeMapData(data.centerX, data.centerZ, data.scale, trackingPosition, unlimitedTracking, locked, data.dimension); - - tfdata.colors = data.colors; - tfdata.bannerMarkers.putAll(data.bannerMarkers); - tfdata.decorations.putAll(data.decorations); - tfdata.frameMarkers.putAll(data.frameMarkers); - tfdata.trackedDecorationCount = data.trackedDecorationCount; - - tfdata.yCenter = nbt.getInt("yCenter"); - tfdata.ore = nbt.getBoolean("mapOres"); - - return tfdata; - } - - @Override - public CompoundTag save(CompoundTag nbt, HolderLookup.Provider provider) { - CompoundTag ret = super.save(nbt, provider); - ret.putInt("yCenter", this.yCenter); - ret.putBoolean("mapOres", this.ore); - return ret; - } - public void calculateMapCenter(Level world, int x, int y, int z) { this.yCenter = y; @@ -73,27 +61,22 @@ public void calculateMapCenter(Level world, int x, int y, int z) { // [VanillaCopy] Adapted from World.getMapData @Nullable - public static TFMazeMapData getMazeMapData(Level level, String name) { - if (level.isClientSide()) return CLIENT_DATA.get(name); - else return (TFMazeMapData) ((ServerLevel) level).getServer().overworld().getDataStorage().get(TFMazeMapData.factory(), name); - } - - // Like the method above, but if we know we're on client - @Nullable - public static TFMazeMapData getClientMagicMapData(String name) { - return CLIENT_DATA.get(name); - } - - public static SavedData.Factory factory() { - return new SavedData.Factory<>(() -> { - throw new IllegalStateException("Should never create an empty map saved data"); - }, TFMazeMapData::load, DataFixTypes.SAVED_DATA_MAP_DATA); + public static TFMazeMapData getMazeMapData(Level level, MapId mapId) { + if (level instanceof ServerLevel serverLevel) { + MapItemSavedData baseData = serverLevel.getServer().overworld().getMapData(mapId); + if (baseData instanceof TFMazeMapData tfData) { + return tfData; + } + return null; + } else { + return CLIENT_DATA.get(mapId); + } } // [VanillaCopy] Adapted from World.registerMapData - public static void registerMazeMapData(Level level, TFMazeMapData data, String id) { + public static void registerMazeMapData(Level level, TFMazeMapData data, MapId id) { if (level.isClientSide()) CLIENT_DATA.put(id, data); - else ((ServerLevel) level).getServer().overworld().getDataStorage().set(id, data); + else ((ServerLevel) level).getServer().overworld().getDataStorage().set(type(id), data); } @Nullable diff --git a/src/main/java/twilightforest/item/travellers_gear/TravellersArmorItem.java b/src/main/java/twilightforest/item/travellers_gear/TravellersArmorItem.java index 115bc339e8..9fc02143fb 100644 --- a/src/main/java/twilightforest/item/travellers_gear/TravellersArmorItem.java +++ b/src/main/java/twilightforest/item/travellers_gear/TravellersArmorItem.java @@ -2,9 +2,11 @@ import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; +import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.model.Model; import net.minecraft.client.model.geom.ModelPart; import net.minecraft.client.model.player.PlayerModel; +import net.minecraft.client.renderer.entity.state.HumanoidRenderState; import net.minecraft.client.resources.model.EquipmentClientInfo; import net.minecraft.core.Holder; import net.minecraft.core.HolderLookup; @@ -187,7 +189,7 @@ public ArmorRender() { @Nullable @Override public Identifier getArmorTexture(ItemStack stack, EquipmentClientInfo.LayerType type, EquipmentClientInfo.Layer layer, Identifier def) { - return type != EquipmentClientInfo.LayerType.HUMANOID_LEGGINGS && entity.getData(TFDataAttachments.IS_USING_GOGGLES_ZOOM_MODIFIER) ? + return type != EquipmentClientInfo.LayerType.HUMANOID_LEGGINGS ? TwilightForestMod.prefix("textures/models/armor/travellers_layer_1_down.png") : super.getArmorTexture(stack, type, layer, def); } @@ -236,7 +238,7 @@ public Model getHumanoidArmorModel(ItemStack stack, EquipmentClientInfo.Layer @Override public void setupModelAnimations(LivingEntity livingEntity, ItemStack itemStack, EquipmentSlot equipmentSlot, Model model, float limbSwing, float limbSwingAmount, float partialTick, float ageInTicks, float netHeadYaw, float headPitch) { if (model instanceof TravellersWingsModel wingsModel) - wingsModel.setupModelAnimations(livingEntity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch); + wingsModel.setupModelAnimations(livingEntity, ageInTicks); } private boolean isModelSlim(Model model) { diff --git a/src/main/java/twilightforest/item/travellers_gear/TravellersGearLogic.java b/src/main/java/twilightforest/item/travellers_gear/TravellersGearLogic.java index 3c2628cfc9..5fd368d7e8 100644 --- a/src/main/java/twilightforest/item/travellers_gear/TravellersGearLogic.java +++ b/src/main/java/twilightforest/item/travellers_gear/TravellersGearLogic.java @@ -11,6 +11,7 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvents; +import net.minecraft.tags.FluidTags; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.EquipmentSlot; @@ -26,7 +27,6 @@ import net.minecraft.world.level.block.Blocks; import net.minecraft.world.phys.Vec3; import net.neoforged.neoforge.attachment.AttachmentType; -import net.neoforged.neoforge.common.NeoForgeMod; import net.neoforged.neoforge.network.PacketDistributor; import net.neoforged.neoforge.registries.DeferredHolder; import net.neoforged.neoforge.server.ServerLifecycleHooks; @@ -88,7 +88,7 @@ public static void waterWalkingSplashEffect(LivingEntity livingEntity) { } public static boolean isBelowMaxWaterWalkingSubmergedHeight(LivingEntity livingEntity) { - double waterHeight = livingEntity.getFluidTypeHeight(NeoForgeMod.WATER_TYPE.value()); + double waterHeight = livingEntity.getFluidHeight(FluidTags.WATER); return waterHeight < WATER_WALKING_MAX_SUBMERGED_HEIGHT; } @@ -195,7 +195,7 @@ public static void travellersVestHaste(LivingEntity livingEntity) { public static void travellersBootsUnrestrained(LivingEntity livingEntity) { if (TravellersModifiersManager.isModifierActive(livingEntity, TravellersModifiersManager.UNRESTRAINED_MODIFIER)) - livingEntity.stuckSpeedMultiplier = Vec3.ZERO; + livingEntity.makeStuckInBlock(Blocks.AIR.defaultBlockState(), new Vec3(1.0D, 1.0D, 1.0D)); } public static boolean tryPerformSidestep(Player player, boolean isLeftSidestep) { diff --git a/src/main/java/twilightforest/item/travellers_gear/modifiers/TransferableComponentModifier.java b/src/main/java/twilightforest/item/travellers_gear/modifiers/TransferableComponentModifier.java index be1d043d63..a7b8bbcec5 100644 --- a/src/main/java/twilightforest/item/travellers_gear/modifiers/TransferableComponentModifier.java +++ b/src/main/java/twilightforest/item/travellers_gear/modifiers/TransferableComponentModifier.java @@ -11,9 +11,9 @@ import net.minecraft.world.entity.EquipmentSlotGroup; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; +import org.jetbrains.annotations.NotNull; import twilightforest.TwilightForestMod; -import java.util.Arrays; import java.util.List; @SuppressWarnings("unchecked") @@ -26,12 +26,12 @@ public record TransferableComponentModifier( public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( EquipmentSlotGroup.CODEC.fieldOf("equipment_slots").validate(TravellersModifier::validateEquipment).forGetter(TransferableComponentModifier::group), DataComponentType.CODEC.fieldOf("component").forGetter(o -> o.markerComponent), - DataComponentMap.CODEC.fieldOf("transferable_components").forGetter(o -> DataComponentMap.builder().set((DataComponentType) o.transferableComponent().type(), o.transferableComponent().value()).build()), + DataComponentMap.CODEC.fieldOf("transferable_components").forGetter(o -> DataComponentMap.builder().set((DataComponentType<@NotNull Object>) o.transferableComponent().type(), o.transferableComponent().value()).build()), ComponentSerialization.CODEC.listOf().optionalFieldOf("description", List.of()).forGetter(TransferableComponentModifier::description) ).apply(instance, (group, markerComponentMap, transferableComponentsMap, description) -> { if (transferableComponentsMap.size() != 1) throw new IllegalArgumentException(String.format("Expected exactly one entry in this data component maps: %s", transferableComponentsMap)); - DataComponentType marker = (DataComponentType) markerComponentMap; + DataComponentType marker = (DataComponentType<@NotNull Unit>) markerComponentMap; TypedDataComponent transferable = transferableComponentsMap.stream().findFirst().orElseThrow(); return new TransferableComponentModifier(group, marker, transferable, description); })); @@ -53,7 +53,7 @@ public boolean isAbility() { @Override public boolean addModifier(ItemStack stack) { stack.set(markerComponent, Unit.INSTANCE); - stack.set((DataComponentType) transferableComponent.type(), transferableComponent.value()); + stack.set((DataComponentType<@NotNull Object>) transferableComponent.type(), transferableComponent.value()); return true; } @@ -74,18 +74,21 @@ public boolean transfer(ItemStack output, List input) { if (dataComponentProviders.isEmpty()) return false; if (dataComponentProviders.size() > 1) { - TwilightForestMod.LOGGER.error(String.format("A recipe with more than 2 dataComponentProviders was matched: %s. Please report to https://github.com/TeamTwilight/twilightforest/issues", input)); + TwilightForestMod.LOGGER.error("A recipe with more than 2 dataComponentProviders was matched: {}. Please report to https://github.com/TeamTwilight/twilightforest/issues", input); return false; } ItemStack dataComponentProvider = dataComponentProviders.getFirst()[0]; output.set(this.markerComponent, Unit.INSTANCE); - output.set((DataComponentType) this.transferableComponent.type(), dataComponentProvider.get(transferableComponent.type())); + output.set((DataComponentType<@NotNull Object>) this.transferableComponent.type(), dataComponentProvider.get(transferableComponent.type())); return true; } public List findDataComponentProviders(List input) { - return input.stream().map(Ingredient::getItems) - .filter(itemStacks -> Arrays.stream(itemStacks) + return input.stream() + .map(ingredient -> ingredient.getValues().stream() + .map(itemHolder -> new ItemStack(itemHolder.value())) + .toArray(ItemStack[]::new)) + .filter(itemStacks -> java.util.Arrays.stream(itemStacks) .anyMatch(itemStack -> itemStack.has(transferableComponent.type()))) .toList(); } diff --git a/src/main/java/twilightforest/item/travellers_gear/modifiers/TravellersEntryModifier.java b/src/main/java/twilightforest/item/travellers_gear/modifiers/TravellersEntryModifier.java index 7aff3d5de4..f34930bc84 100644 --- a/src/main/java/twilightforest/item/travellers_gear/modifiers/TravellersEntryModifier.java +++ b/src/main/java/twilightforest/item/travellers_gear/modifiers/TravellersEntryModifier.java @@ -11,6 +11,7 @@ import net.minecraft.world.entity.EquipmentSlotGroup; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.component.ItemAttributeModifiers; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -22,7 +23,7 @@ public record TravellersEntryModifier(EquipmentSlotGroup group, List CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( EquipmentSlotGroup.CODEC.fieldOf("equipment_slots").validate(TravellersModifier::validateEquipment).forGetter(TravellersEntryModifier::group), ItemAttributeModifiers.Entry.CODEC.listOf().fieldOf("attribute_modifiers").forGetter(TravellersEntryModifier::modifiers), - DataComponentType.CODEC.fieldOf("component").xmap(component -> (DataComponentType) component, object -> object).forGetter(TravellersEntryModifier::markerComponent), + DataComponentType.CODEC.fieldOf("component").xmap(component -> (DataComponentType<@NotNull Unit>) component, object -> object).forGetter(TravellersEntryModifier::markerComponent), ComponentSerialization.CODEC.listOf().optionalFieldOf("description", List.of()).forGetter(TravellersEntryModifier::description), Codec.BOOL.fieldOf("builtin_modifier").orElse(false).forGetter(TravellersEntryModifier::builtin) ).apply(instance, TravellersEntryModifier::new)); @@ -63,7 +64,7 @@ public void removeModifier(ItemStack stack) { newEntries.add(entry); } }); - stack.set(DataComponents.ATTRIBUTE_MODIFIERS, new ItemAttributeModifiers(newEntries, modifiers.showInTooltip())); + stack.set(DataComponents.ATTRIBUTE_MODIFIERS, new ItemAttributeModifiers(newEntries)); stack.remove(this.markerComponent()); } } From 7ae2c291349b29716acbac653690ab965752df48 Mon Sep 17 00:00:00 2001 From: Albazavr <110563872+albazavr-alba@users.noreply.github.com> Date: Wed, 24 Jun 2026 23:20:32 +0300 Subject: [PATCH 02/10] fix review comments for TravellersGearLogic.java --- .../item/travellers_gear/TravellersGearLogic.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/twilightforest/item/travellers_gear/TravellersGearLogic.java b/src/main/java/twilightforest/item/travellers_gear/TravellersGearLogic.java index 5fd368d7e8..46abffe6dd 100644 --- a/src/main/java/twilightforest/item/travellers_gear/TravellersGearLogic.java +++ b/src/main/java/twilightforest/item/travellers_gear/TravellersGearLogic.java @@ -195,7 +195,7 @@ public static void travellersVestHaste(LivingEntity livingEntity) { public static void travellersBootsUnrestrained(LivingEntity livingEntity) { if (TravellersModifiersManager.isModifierActive(livingEntity, TravellersModifiersManager.UNRESTRAINED_MODIFIER)) - livingEntity.makeStuckInBlock(Blocks.AIR.defaultBlockState(), new Vec3(1.0D, 1.0D, 1.0D)); + livingEntity.makeStuckInBlock(Blocks.AIR.defaultBlockState(), Vec3.ZERO); } public static boolean tryPerformSidestep(Player player, boolean isLeftSidestep) { From a308f9bb6ef67c62a68dd1ff6bd0c0f20b8747da Mon Sep 17 00:00:00 2001 From: Albazavr Date: Sun, 5 Jul 2026 01:55:27 +0300 Subject: [PATCH 03/10] MoonPhaseConverter.java was moved to here --- .../util/MoonPhaseConverter.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/main/java/twilightforest/util/MoonPhaseConverter.java diff --git a/src/main/java/twilightforest/util/MoonPhaseConverter.java b/src/main/java/twilightforest/util/MoonPhaseConverter.java new file mode 100644 index 0000000000..90e9fc66f8 --- /dev/null +++ b/src/main/java/twilightforest/util/MoonPhaseConverter.java @@ -0,0 +1,20 @@ +package twilightforest.util; + +public class MoonPhaseConverter { + private static final String[] moonPhases = new String[]{ + "full", "waning_gibbous", "third_quarter", "waning_crescent", + "new", "waxing_crescent", "first_quarter", "waxing_gibbous" + }; + + + public static int convertPhaseToIndex(String phaseType) { + for (int i = 0; i < moonPhases.length; i++) { + if (moonPhases[i].equals(phaseType)) return i; + } + return 0; + } + + public static String convertIndexToPhase(int index) { + return moonPhases[index]; + } +} From 5e64c53123a0b1fe6acbe1dfcc84ae678fbff69b Mon Sep 17 00:00:00 2001 From: Albazavr Date: Sun, 5 Jul 2026 03:39:06 +0300 Subject: [PATCH 04/10] Removed every @NotNull and unnecessary line change --- .../java/twilightforest/item/CustomDamageSwordItem.java | 1 + src/main/java/twilightforest/item/MagicMapItem.java | 1 + src/main/java/twilightforest/item/food/TFFoods.java | 1 + .../java/twilightforest/item/mapdata/TFMagicMapData.java | 1 - .../modifiers/TransferableComponentModifier.java | 9 ++++----- .../modifiers/TravellersEntryModifier.java | 3 +-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/twilightforest/item/CustomDamageSwordItem.java b/src/main/java/twilightforest/item/CustomDamageSwordItem.java index 860e284988..69d4d17136 100644 --- a/src/main/java/twilightforest/item/CustomDamageSwordItem.java +++ b/src/main/java/twilightforest/item/CustomDamageSwordItem.java @@ -8,6 +8,7 @@ //TODO data component-itize this public class CustomDamageSwordItem extends Item implements CustomDamageProvider { + private final ResourceKey damageType; public CustomDamageSwordItem(ResourceKey damageType, Properties properties) { diff --git a/src/main/java/twilightforest/item/MagicMapItem.java b/src/main/java/twilightforest/item/MagicMapItem.java index 5e449053b1..05f44ab1e9 100644 --- a/src/main/java/twilightforest/item/MagicMapItem.java +++ b/src/main/java/twilightforest/item/MagicMapItem.java @@ -37,6 +37,7 @@ // [VanillaCopy] super everything, but with appropriate redirections to our own datastructures. finer details noted public class MagicMapItem extends MapItem { + public static final String STR_ID = "magicmap"; public MagicMapItem(Properties properties) { diff --git a/src/main/java/twilightforest/item/food/TFFoods.java b/src/main/java/twilightforest/item/food/TFFoods.java index 8745237008..c00456fdb0 100644 --- a/src/main/java/twilightforest/item/food/TFFoods.java +++ b/src/main/java/twilightforest/item/food/TFFoods.java @@ -4,6 +4,7 @@ import net.minecraft.world.food.Foods; public class TFFoods extends Foods { + public static final FoodProperties TORCHBERRIES = new FoodProperties.Builder().alwaysEdible().build(); public static final FoodProperties RAW_VENISON = new FoodProperties.Builder().nutrition(3).saturationModifier(0.3F).build(); public static final FoodProperties VENISON_STEAK = new FoodProperties.Builder().nutrition(8).saturationModifier(0.8F).build(); diff --git a/src/main/java/twilightforest/item/mapdata/TFMagicMapData.java b/src/main/java/twilightforest/item/mapdata/TFMagicMapData.java index bd81d79f09..65d45676c8 100644 --- a/src/main/java/twilightforest/item/mapdata/TFMagicMapData.java +++ b/src/main/java/twilightforest/item/mapdata/TFMagicMapData.java @@ -99,7 +99,6 @@ public static TFMagicMapData getMagicMapData(Level level, MapId mapId) { } } - // [VanillaCopy] Adapted from World.registerMapData public static void registerMagicMapData(Level level, TFMagicMapData data, MapId id) { if (level instanceof ServerLevel serverLevel) serverLevel.getServer().overworld().getDataStorage().set(type(id), data); diff --git a/src/main/java/twilightforest/item/travellers_gear/modifiers/TransferableComponentModifier.java b/src/main/java/twilightforest/item/travellers_gear/modifiers/TransferableComponentModifier.java index a7b8bbcec5..04670e8c38 100644 --- a/src/main/java/twilightforest/item/travellers_gear/modifiers/TransferableComponentModifier.java +++ b/src/main/java/twilightforest/item/travellers_gear/modifiers/TransferableComponentModifier.java @@ -11,7 +11,6 @@ import net.minecraft.world.entity.EquipmentSlotGroup; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; -import org.jetbrains.annotations.NotNull; import twilightforest.TwilightForestMod; import java.util.List; @@ -26,12 +25,12 @@ public record TransferableComponentModifier( public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( EquipmentSlotGroup.CODEC.fieldOf("equipment_slots").validate(TravellersModifier::validateEquipment).forGetter(TransferableComponentModifier::group), DataComponentType.CODEC.fieldOf("component").forGetter(o -> o.markerComponent), - DataComponentMap.CODEC.fieldOf("transferable_components").forGetter(o -> DataComponentMap.builder().set((DataComponentType<@NotNull Object>) o.transferableComponent().type(), o.transferableComponent().value()).build()), + DataComponentMap.CODEC.fieldOf("transferable_components").forGetter(o -> DataComponentMap.builder().set((DataComponentType) o.transferableComponent().type(), o.transferableComponent().value()).build()), ComponentSerialization.CODEC.listOf().optionalFieldOf("description", List.of()).forGetter(TransferableComponentModifier::description) ).apply(instance, (group, markerComponentMap, transferableComponentsMap, description) -> { if (transferableComponentsMap.size() != 1) throw new IllegalArgumentException(String.format("Expected exactly one entry in this data component maps: %s", transferableComponentsMap)); - DataComponentType marker = (DataComponentType<@NotNull Unit>) markerComponentMap; + DataComponentType marker = (DataComponentType) markerComponentMap; TypedDataComponent transferable = transferableComponentsMap.stream().findFirst().orElseThrow(); return new TransferableComponentModifier(group, marker, transferable, description); })); @@ -53,7 +52,7 @@ public boolean isAbility() { @Override public boolean addModifier(ItemStack stack) { stack.set(markerComponent, Unit.INSTANCE); - stack.set((DataComponentType<@NotNull Object>) transferableComponent.type(), transferableComponent.value()); + stack.set((DataComponentType) transferableComponent.type(), transferableComponent.value()); return true; } @@ -79,7 +78,7 @@ public boolean transfer(ItemStack output, List input) { } ItemStack dataComponentProvider = dataComponentProviders.getFirst()[0]; output.set(this.markerComponent, Unit.INSTANCE); - output.set((DataComponentType<@NotNull Object>) this.transferableComponent.type(), dataComponentProvider.get(transferableComponent.type())); + output.set((DataComponentType) this.transferableComponent.type(), dataComponentProvider.get(transferableComponent.type())); return true; } diff --git a/src/main/java/twilightforest/item/travellers_gear/modifiers/TravellersEntryModifier.java b/src/main/java/twilightforest/item/travellers_gear/modifiers/TravellersEntryModifier.java index f34930bc84..fa6620ce5d 100644 --- a/src/main/java/twilightforest/item/travellers_gear/modifiers/TravellersEntryModifier.java +++ b/src/main/java/twilightforest/item/travellers_gear/modifiers/TravellersEntryModifier.java @@ -11,7 +11,6 @@ import net.minecraft.world.entity.EquipmentSlotGroup; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.component.ItemAttributeModifiers; -import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -23,7 +22,7 @@ public record TravellersEntryModifier(EquipmentSlotGroup group, List CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( EquipmentSlotGroup.CODEC.fieldOf("equipment_slots").validate(TravellersModifier::validateEquipment).forGetter(TravellersEntryModifier::group), ItemAttributeModifiers.Entry.CODEC.listOf().fieldOf("attribute_modifiers").forGetter(TravellersEntryModifier::modifiers), - DataComponentType.CODEC.fieldOf("component").xmap(component -> (DataComponentType<@NotNull Unit>) component, object -> object).forGetter(TravellersEntryModifier::markerComponent), + DataComponentType.CODEC.fieldOf("component").xmap(component -> (DataComponentType) component, object -> object).forGetter(TravellersEntryModifier::markerComponent), ComponentSerialization.CODEC.listOf().optionalFieldOf("description", List.of()).forGetter(TravellersEntryModifier::description), Codec.BOOL.fieldOf("builtin_modifier").orElse(false).forGetter(TravellersEntryModifier::builtin) ).apply(instance, TravellersEntryModifier::new)); From 4fc383c97f65eaf61b94c8d776bd4a2fd1abb50c Mon Sep 17 00:00:00 2001 From: Albazavr Date: Mon, 20 Jul 2026 03:27:15 +0300 Subject: [PATCH 05/10] Reverted back modifier check --- .../item/travellers_gear/TravellersArmorItem.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/twilightforest/item/travellers_gear/TravellersArmorItem.java b/src/main/java/twilightforest/item/travellers_gear/TravellersArmorItem.java index 9fc02143fb..5f5f61726b 100644 --- a/src/main/java/twilightforest/item/travellers_gear/TravellersArmorItem.java +++ b/src/main/java/twilightforest/item/travellers_gear/TravellersArmorItem.java @@ -2,11 +2,9 @@ import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; -import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.model.Model; import net.minecraft.client.model.geom.ModelPart; import net.minecraft.client.model.player.PlayerModel; -import net.minecraft.client.renderer.entity.state.HumanoidRenderState; import net.minecraft.client.resources.model.EquipmentClientInfo; import net.minecraft.core.Holder; import net.minecraft.core.HolderLookup; @@ -189,7 +187,7 @@ public ArmorRender() { @Nullable @Override public Identifier getArmorTexture(ItemStack stack, EquipmentClientInfo.LayerType type, EquipmentClientInfo.Layer layer, Identifier def) { - return type != EquipmentClientInfo.LayerType.HUMANOID_LEGGINGS ? + return type != EquipmentClientInfo.LayerType.HUMANOID_LEGGINGS && entity.getData(TFDataAttachments.IS_USING_GOGGLES_ZOOM_MODIFIER) ? TwilightForestMod.prefix("textures/models/armor/travellers_layer_1_down.png") : super.getArmorTexture(stack, type, layer, def); } From 2e931f166f4d80ad9bfbba6769ca383477cb7e65 Mon Sep 17 00:00:00 2001 From: Albazavr Date: Mon, 20 Jul 2026 21:13:01 +0300 Subject: [PATCH 06/10] Excluded map's files from PR and added FIXME --- .../twilightforest/item/MagicMapItem.java | 6 +- .../java/twilightforest/item/MazeMapItem.java | 6 +- .../item/mapdata/TFMagicMapData.java | 155 ++++++++++-------- .../item/mapdata/TFMazeMapData.java | 82 +++++---- 4 files changed, 145 insertions(+), 104 deletions(-) diff --git a/src/main/java/twilightforest/item/MagicMapItem.java b/src/main/java/twilightforest/item/MagicMapItem.java index 05f44ab1e9..59ea73c47a 100644 --- a/src/main/java/twilightforest/item/MagicMapItem.java +++ b/src/main/java/twilightforest/item/MagicMapItem.java @@ -53,7 +53,8 @@ public static ItemStack setupNewMap(ServerLevel level, int worldX, int worldZ, b @Nullable public static TFMagicMapData getData(ItemStack stack, Level level) { MapId mapid = stack.get(DataComponents.MAP_ID); - return mapid == null ? null : TFMagicMapData.getMagicMapData(level, mapid); + // FIXME fix this after fixing TFMagicMapData + return mapid == null ? null : TFMagicMapData.getMagicMapData(level, getMapName(mapid.id())); } @Nullable @@ -89,7 +90,8 @@ private static TFMagicMapData createMapData(ItemStack stack, ServerLevel level, ColumnPos pos = getMagicMapCenter(x, z); TFMagicMapData mapdata = new TFMagicMapData(pos.x(), pos.z(), (byte) scale, trackingPosition, unlimitedTracking, false, dimension); - TFMagicMapData.registerMagicMapData(level, mapdata, new MapId(freeMapId.id())); // call our own register method + // FIXME fix this after fixing TFMagicMapData + TFMagicMapData.registerMagicMapData(level, mapdata, getMapName(freeMapId.id())); // call our own register method stack.set(DataComponents.MAP_ID, freeMapId); return mapdata; } diff --git a/src/main/java/twilightforest/item/MazeMapItem.java b/src/main/java/twilightforest/item/MazeMapItem.java index 9f90453c9b..42c224e89d 100644 --- a/src/main/java/twilightforest/item/MazeMapItem.java +++ b/src/main/java/twilightforest/item/MazeMapItem.java @@ -54,7 +54,8 @@ public static ItemStack setupNewMap(ServerLevel level, int worldX, int worldZ, b @Nullable public static TFMazeMapData getData(ItemStack stack, Level level) { MapId id = stack.get(DataComponents.MAP_ID); - return id == null ? null : TFMazeMapData.getMazeMapData(level, id); + // FIXME fix this after fixing TFMazeMapData + return id == null ? null : TFMazeMapData.getMazeMapData(level, getMapName(id.id())); } @Nullable @@ -81,7 +82,8 @@ private static TFMazeMapData createMapData(ItemStack stack, ServerLevel level, i TFMazeMapData mapdata = new TFMazeMapData(scaledX, scaledZ, (byte) scale, trackingPosition, unlimitedTracking, false, dimension); mapdata.calculateMapCenter(level, x, y, z); // call our own map center calculation mapdata.ore = ore; - TFMazeMapData.registerMazeMapData(level, mapdata, i); // call our own register method + // FIXME fix this after fixing TFMazeMapData + TFMazeMapData.registerMazeMapData(level, mapdata, getMapName(i.id())); // call our own register method stack.set(DataComponents.MAP_ID, i); return mapdata; } diff --git a/src/main/java/twilightforest/item/mapdata/TFMagicMapData.java b/src/main/java/twilightforest/item/mapdata/TFMagicMapData.java index 65d45676c8..6f6058f4ba 100644 --- a/src/main/java/twilightforest/item/mapdata/TFMagicMapData.java +++ b/src/main/java/twilightforest/item/mapdata/TFMagicMapData.java @@ -3,108 +3,127 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.Holder; -import net.minecraft.core.registries.Registries; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.*; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.ClientboundMapItemDataPacket; import net.minecraft.resources.ResourceKey; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.datafix.DataFixTypes; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.saveddata.SavedData; import net.minecraft.world.level.saveddata.maps.MapDecoration; import net.minecraft.world.level.saveddata.maps.MapDecorationType; import net.minecraft.world.level.saveddata.maps.MapId; import net.minecraft.world.level.saveddata.maps.MapItemSavedData; import org.jetbrains.annotations.Nullable; +import twilightforest.TwilightForestMod; import twilightforest.item.MagicMapItem; import twilightforest.network.MagicMapPacket; import twilightforest.util.Codecs; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +// FIXME this class should be totally fixed public class TFMagicMapData extends MapItemSavedData { - private static final Codec COLORS_CODEC = Codec.BYTE.listOf() - .xmap(list -> { - byte[] arr = new byte[list.size()]; - for (int i = 0; i < list.size(); i++) arr[i] = list.get(i); - return arr; - }, array -> { - List list = new ArrayList<>(array.length); - for (byte b : array) list.add(b); - return list; - }); + private static final Map CLIENT_DATA = new HashMap<>(); + public final List conqueredStructures = new ArrayList<>(); - public static final Codec CODEC = RecordCodecBuilder.create(instance -> - instance.group( - Codec.INT.fieldOf("xCenter").forGetter(data -> data.centerX), - Codec.INT.fieldOf("zCenter").forGetter(data -> data.centerZ), - Codec.BYTE.fieldOf("scale").forGetter(data -> data.scale), - Codec.BOOL.optionalFieldOf("trackingPosition", true).forGetter(data -> data.trackingPosition), - Codec.BOOL.optionalFieldOf("unlimitedTracking", false).forGetter(data -> data.unlimitedTracking), - Codec.BOOL.optionalFieldOf("locked", false).forGetter(data -> data.locked), - ResourceKey.codec(Registries.DIMENSION).fieldOf("dimension").forGetter(data -> data.dimension), - COLORS_CODEC.fieldOf("colors").forGetter(data -> data.colors), - DecorationHolder.CODEC.listOf().optionalFieldOf("decorations", List.of()).forGetter(data -> { - List holders = new ArrayList<>(); - data.decorations.forEach((s, decoration) -> { - if (decoration.type().value().showOnItemFrame()) { - holders.add(new DecorationHolder(s, decoration)); - } - }); - return holders; - }), - Codec.STRING.listOf().optionalFieldOf("conquered_structures", List.of()).forGetter(data -> data.conqueredStructures) - ).apply(instance, (centerX, centerZ, scale, trackingPosition, unlimitedTracking, locked, dimension, colorsArray, decorationsList, conqueredList) -> { - TFMagicMapData tfdata = new TFMagicMapData(centerX, centerZ, scale, trackingPosition, unlimitedTracking, locked, dimension); - if (colorsArray.length == tfdata.colors.length) { - System.arraycopy(colorsArray, 0, tfdata.colors, 0, colorsArray.length); - } - for (DecorationHolder decoration : decorationsList) { - MapDecoration mapdecoration1 = decoration.decoration(); - MapDecoration mapdecoration = tfdata.decorations.put(decoration.id(), mapdecoration1); - if (!mapdecoration1.equals(mapdecoration)) { - if (mapdecoration != null && mapdecoration.type().value().trackCount()) { - tfdata.trackedDecorationCount--; - } - if (decoration.decoration().type().value().trackCount()) { - tfdata.trackedDecorationCount++; - } - tfdata.setDecorationsDirty(); + public TFMagicMapData(int x, int z, byte scale, boolean trackpos, boolean unlimited, boolean locked, ResourceKey dim) { + super(x, z, scale, trackpos, unlimited, locked, dim); + } + + public static TFMagicMapData load(CompoundTag nbt, HolderLookup.Provider provider) { + MapItemSavedData data = MapItemSavedData.load(nbt, provider); + final boolean trackingPosition = !nbt.contains("trackingPosition", 1) || nbt.getBoolean("trackingPosition"); + final boolean unlimitedTracking = nbt.getBoolean("unlimitedTracking"); + final boolean locked = nbt.getBoolean("locked"); + TFMagicMapData tfdata = new TFMagicMapData(data.centerX, data.centerZ, data.scale, trackingPosition, unlimitedTracking, locked, data.dimension); + + tfdata.colors = data.colors; + tfdata.bannerMarkers.putAll(data.bannerMarkers); + tfdata.frameMarkers.putAll(data.frameMarkers); + + for (DecorationHolder decoration : DecorationHolder.CODEC.listOf() + .parse(provider.createSerializationContext(NbtOps.INSTANCE), nbt.get("decorations")) + .resultOrPartial(error -> TwilightForestMod.LOGGER.warn("Failed to parse map decoration: '{}'", error)) + .orElse(List.of())) { + MapDecoration mapdecoration1 = decoration.decoration(); + MapDecoration mapdecoration = tfdata.decorations.put(decoration.id(), mapdecoration1); + if (!mapdecoration1.equals(mapdecoration)) { + if (mapdecoration != null && mapdecoration.type().value().trackCount()) { + tfdata.trackedDecorationCount--; } + + if (decoration.decoration().type().value().trackCount()) { + tfdata.trackedDecorationCount++; + } + tfdata.setDecorationsDirty(); } + } + + if (nbt.contains("conquered_structures", Tag.TAG_LIST)) { tfdata.conqueredStructures.clear(); - tfdata.conqueredStructures.addAll(conqueredList); - return tfdata; - }) - ); + ListTag tag = nbt.getList("conquered_structures", Tag.TAG_STRING); + tag.forEach(tag1 -> tfdata.conqueredStructures.add(tag1.getAsString())); + } - private static final Map CLIENT_DATA = new HashMap<>(); - public final List conqueredStructures = new ArrayList<>(); + return tfdata; + } - public TFMagicMapData(int x, int z, byte scale, boolean trackpos, boolean unlimited, boolean locked, ResourceKey dim) { - super(x, z, scale, trackpos, unlimited, locked, dim); + @Override + public CompoundTag save(CompoundTag tag, HolderLookup.Provider provider) { + tag = super.save(tag, provider); + + List holders = new ArrayList<>(); + this.decorations.forEach((s, decoration) -> { + if (decoration.type().value().showOnItemFrame()) { + holders.add(new DecorationHolder(s, decoration)); + } + }); + tag.put("decorations", DecorationHolder.CODEC.listOf().encodeStart(NbtOps.INSTANCE, holders).getOrThrow()); + + if (!this.conqueredStructures.isEmpty()) { + ListTag conqueredTag = new ListTag(); + for (String structure : this.conqueredStructures) { + conqueredTag.add(StringTag.valueOf(structure)); + } + tag.put("conquered_structures", conqueredTag); + } + + return tag; } // [VanillaCopy] Adapted from World.getMapData @Nullable - public static TFMagicMapData getMagicMapData(Level level, MapId mapId) { - if (level instanceof ServerLevel serverLevel) { - MapItemSavedData baseData = serverLevel.getServer().overworld().getMapData(mapId); - if (baseData instanceof TFMagicMapData tfData) { - return tfData; - } - return null; - } else { - return CLIENT_DATA.get(mapId); - } + public static TFMagicMapData getMagicMapData(Level level, String name) { + if (level instanceof ServerLevel serverLevel) return (TFMagicMapData) serverLevel.getServer().overworld().getDataStorage().get(TFMagicMapData.factory(), name); + else return CLIENT_DATA.get(name); + } + + // Like the method above, but if we know we're on client + @Nullable + public static TFMagicMapData getClientMagicMapData(String name) { + return CLIENT_DATA.get(name); } // [VanillaCopy] Adapted from World.registerMapData - public static void registerMagicMapData(Level level, TFMagicMapData data, MapId id) { - if (level instanceof ServerLevel serverLevel) serverLevel.getServer().overworld().getDataStorage().set(type(id), data); + public static void registerMagicMapData(Level level, TFMagicMapData data, String id) { + if (level instanceof ServerLevel serverLevel) serverLevel.getServer().overworld().getDataStorage().set(id, data); else CLIENT_DATA.put(id, data); } + public static Factory factory() { + return new SavedData.Factory<>(() -> { + throw new IllegalStateException("Should never create an empty map saved data"); + }, TFMagicMapData::load, DataFixTypes.SAVED_DATA_MAP_DATA); + } + @Nullable @Override public Packet getUpdatePacket(MapId mapId, Player player) { diff --git a/src/main/java/twilightforest/item/mapdata/TFMazeMapData.java b/src/main/java/twilightforest/item/mapdata/TFMazeMapData.java index c689bc4ac0..c563b69725 100644 --- a/src/main/java/twilightforest/item/mapdata/TFMazeMapData.java +++ b/src/main/java/twilightforest/item/mapdata/TFMazeMapData.java @@ -1,15 +1,16 @@ package twilightforest.item.mapdata; -import com.mojang.serialization.Codec; -import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.BlockPos; -import net.minecraft.core.registries.Registries; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.ClientboundMapItemDataPacket; import net.minecraft.resources.ResourceKey; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.datafix.DataFixTypes; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; +import net.minecraft.world.level.saveddata.SavedData; import net.minecraft.world.level.saveddata.maps.MapId; import net.minecraft.world.level.saveddata.maps.MapItemSavedData; import org.jetbrains.annotations.Nullable; @@ -20,24 +21,9 @@ import java.util.HashMap; import java.util.Map; +// FIXME this class should be totally fixed public class TFMazeMapData extends MapItemSavedData { - private static final Map CLIENT_DATA = new HashMap<>(); - - public static final Codec CODEC = RecordCodecBuilder.create(instance -> - instance.group( - Codec.INT.fieldOf("xCenter").forGetter(data -> data.centerX), - Codec.INT.fieldOf("zCenter").forGetter(data -> data.centerZ), - Codec.BYTE.fieldOf("scale").forGetter(data -> data.scale), - Codec.BOOL.optionalFieldOf("trackingPosition", true).forGetter(data -> true), - Codec.BOOL.optionalFieldOf("unlimitedTracking", false).forGetter(data -> false), - Codec.BOOL.optionalFieldOf("locked", false).forGetter(data -> data.locked), - ResourceKey.codec(Registries.DIMENSION).fieldOf("dimension").forGetter(data -> data.dimension) - ).apply(instance, (centerX, centerZ, scale, trackingPosition, unlimitedTracking, locked, dimension) -> { - TFMazeMapData mazeData = new TFMazeMapData(centerX, centerZ, scale, trackingPosition, unlimitedTracking, locked, dimension); - return mazeData; - }) - ); - + private static final Map CLIENT_DATA = new HashMap<>(); public int yCenter; public boolean ore; @@ -46,6 +32,33 @@ public TFMazeMapData(int x, int z, byte scale, boolean trackpos, boolean unlimit super(x, z, scale, trackpos, unlimited, locked, dim); } + public static TFMazeMapData load(CompoundTag nbt, HolderLookup.Provider provider) { + MapItemSavedData data = MapItemSavedData.load(nbt, provider); + final boolean trackingPosition = !nbt.contains("trackingPosition", 1) || nbt.getBoolean("trackingPosition"); + final boolean unlimitedTracking = nbt.getBoolean("unlimitedTracking"); + final boolean locked = nbt.getBoolean("locked"); + TFMazeMapData tfdata = new TFMazeMapData(data.centerX, data.centerZ, data.scale, trackingPosition, unlimitedTracking, locked, data.dimension); + + tfdata.colors = data.colors; + tfdata.bannerMarkers.putAll(data.bannerMarkers); + tfdata.decorations.putAll(data.decorations); + tfdata.frameMarkers.putAll(data.frameMarkers); + tfdata.trackedDecorationCount = data.trackedDecorationCount; + + tfdata.yCenter = nbt.getInt("yCenter"); + tfdata.ore = nbt.getBoolean("mapOres"); + + return tfdata; + } + + @Override + public CompoundTag save(CompoundTag nbt, HolderLookup.Provider provider) { + CompoundTag ret = super.save(nbt, provider); + ret.putInt("yCenter", this.yCenter); + ret.putBoolean("mapOres", this.ore); + return ret; + } + public void calculateMapCenter(Level world, int x, int y, int z) { this.yCenter = y; @@ -61,22 +74,27 @@ public void calculateMapCenter(Level world, int x, int y, int z) { // [VanillaCopy] Adapted from World.getMapData @Nullable - public static TFMazeMapData getMazeMapData(Level level, MapId mapId) { - if (level instanceof ServerLevel serverLevel) { - MapItemSavedData baseData = serverLevel.getServer().overworld().getMapData(mapId); - if (baseData instanceof TFMazeMapData tfData) { - return tfData; - } - return null; - } else { - return CLIENT_DATA.get(mapId); - } + public static TFMazeMapData getMazeMapData(Level level, String name) { + if (level.isClientSide()) return CLIENT_DATA.get(name); + else return (TFMazeMapData) ((ServerLevel) level).getServer().overworld().getDataStorage().get(TFMazeMapData.factory(), name); + } + + // Like the method above, but if we know we're on client + @Nullable + public static TFMazeMapData getClientMagicMapData(String name) { + return CLIENT_DATA.get(name); + } + + public static SavedData.Factory factory() { + return new SavedData.Factory<>(() -> { + throw new IllegalStateException("Should never create an empty map saved data"); + }, TFMazeMapData::load, DataFixTypes.SAVED_DATA_MAP_DATA); } // [VanillaCopy] Adapted from World.registerMapData - public static void registerMazeMapData(Level level, TFMazeMapData data, MapId id) { + public static void registerMazeMapData(Level level, TFMazeMapData data, String id) { if (level.isClientSide()) CLIENT_DATA.put(id, data); - else ((ServerLevel) level).getServer().overworld().getDataStorage().set(type(id), data); + else ((ServerLevel) level).getServer().overworld().getDataStorage().set(id, data); } @Nullable From ce9bc0b9872e48fc624dd1548bb7cab848336787 Mon Sep 17 00:00:00 2001 From: Albazavr Date: Wed, 22 Jul 2026 17:04:55 +0300 Subject: [PATCH 07/10] Fixed MoonDialItem --- .../twilightforest/item/MoonDialItem.java | 16 +++++++-------- .../util/MoonPhaseConverter.java | 20 ------------------- 2 files changed, 7 insertions(+), 29 deletions(-) delete mode 100644 src/main/java/twilightforest/util/MoonPhaseConverter.java diff --git a/src/main/java/twilightforest/item/MoonDialItem.java b/src/main/java/twilightforest/item/MoonDialItem.java index 32b8706a89..b67d84e0db 100644 --- a/src/main/java/twilightforest/item/MoonDialItem.java +++ b/src/main/java/twilightforest/item/MoonDialItem.java @@ -1,8 +1,6 @@ package twilightforest.item; import net.minecraft.ChatFormatting; -import net.minecraft.client.Minecraft; -import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.world.attribute.EnvironmentAttributes; @@ -13,8 +11,9 @@ import net.minecraft.world.level.Level; import java.time.LocalDate; import java.util.function.Consumer; + +import net.minecraft.world.level.MoonPhase; import org.jetbrains.annotations.Nullable; -import twilightforest.util.MoonPhaseConverter; public class MoonDialItem extends Item { public MoonDialItem(Properties properties) { @@ -23,19 +22,18 @@ public MoonDialItem(Properties properties) { @Override public void appendHoverText(ItemStack stack, TooltipContext context, TooltipDisplay display, Consumer builder, TooltipFlag flag) { - BlockPos pos = Minecraft.getInstance().player != null ? Minecraft.getInstance().player.blockPosition() : BlockPos.ZERO; - builder.accept(getMoonPhase(context.level(), pos).withStyle(ChatFormatting.GRAY)); + builder.accept(getMoonPhase(context.level()).withStyle(ChatFormatting.GRAY)); } - public static MutableComponent getMoonPhase(@Nullable Level level, BlockPos pos) { + public static MutableComponent getMoonPhase(@Nullable Level level) { String phaseType; if (level != null && !level.dimensionType().hasFixedTime()) { - var phase = level.environmentAttributes().getValue(EnvironmentAttributes.MOON_PHASE, pos); - phaseType = phase.getSerializedName(); + MoonPhase phase = level.environmentAttributes().getDimensionValue(EnvironmentAttributes.MOON_PHASE); + phaseType = String.valueOf(phase.index()); } else { boolean aprilFools = LocalDate.of(LocalDate.now().getYear(), 4, 1).equals(LocalDate.now()); phaseType = aprilFools ? "unknown_fools" : "unknown"; } - return Component.translatable("item.twilightforest.moon_dial.phase_" + MoonPhaseConverter.convertPhaseToIndex(phaseType)); + return Component.translatable("item.twilightforest.moon_dial.phase_" + phaseType); } } \ No newline at end of file diff --git a/src/main/java/twilightforest/util/MoonPhaseConverter.java b/src/main/java/twilightforest/util/MoonPhaseConverter.java deleted file mode 100644 index 90e9fc66f8..0000000000 --- a/src/main/java/twilightforest/util/MoonPhaseConverter.java +++ /dev/null @@ -1,20 +0,0 @@ -package twilightforest.util; - -public class MoonPhaseConverter { - private static final String[] moonPhases = new String[]{ - "full", "waning_gibbous", "third_quarter", "waning_crescent", - "new", "waxing_crescent", "first_quarter", "waxing_gibbous" - }; - - - public static int convertPhaseToIndex(String phaseType) { - for (int i = 0; i < moonPhases.length; i++) { - if (moonPhases[i].equals(phaseType)) return i; - } - return 0; - } - - public static String convertIndexToPhase(int index) { - return moonPhases[index]; - } -} From eb0574ddc74f16aaae9e0251aef86d251b638c4d Mon Sep 17 00:00:00 2001 From: Albazavr Date: Thu, 23 Jul 2026 02:42:11 +0300 Subject: [PATCH 08/10] Fixed MoonDialItem --- src/main/java/twilightforest/item/MoonDialItem.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/twilightforest/item/MoonDialItem.java b/src/main/java/twilightforest/item/MoonDialItem.java index b67d84e0db..cfebcb253e 100644 --- a/src/main/java/twilightforest/item/MoonDialItem.java +++ b/src/main/java/twilightforest/item/MoonDialItem.java @@ -1,6 +1,8 @@ package twilightforest.item; import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.world.attribute.EnvironmentAttributes; @@ -11,8 +13,6 @@ import net.minecraft.world.level.Level; import java.time.LocalDate; import java.util.function.Consumer; - -import net.minecraft.world.level.MoonPhase; import org.jetbrains.annotations.Nullable; public class MoonDialItem extends Item { @@ -22,13 +22,14 @@ public MoonDialItem(Properties properties) { @Override public void appendHoverText(ItemStack stack, TooltipContext context, TooltipDisplay display, Consumer builder, TooltipFlag flag) { - builder.accept(getMoonPhase(context.level()).withStyle(ChatFormatting.GRAY)); + BlockPos pos = Minecraft.getInstance().player != null ? Minecraft.getInstance().player.blockPosition() : BlockPos.ZERO; + builder.accept(getMoonPhase(context.level(), pos).withStyle(ChatFormatting.GRAY)); } - public static MutableComponent getMoonPhase(@Nullable Level level) { + public static MutableComponent getMoonPhase(@Nullable Level level, BlockPos pos) { String phaseType; if (level != null && !level.dimensionType().hasFixedTime()) { - MoonPhase phase = level.environmentAttributes().getDimensionValue(EnvironmentAttributes.MOON_PHASE); + var phase = level.environmentAttributes().getValue(EnvironmentAttributes.MOON_PHASE, pos); phaseType = String.valueOf(phase.index()); } else { boolean aprilFools = LocalDate.of(LocalDate.now().getYear(), 4, 1).equals(LocalDate.now()); From f7f5c0fd0cfd02544b17d528920464a14cec935f Mon Sep 17 00:00:00 2001 From: Albazavr Date: Thu, 23 Jul 2026 03:04:08 +0300 Subject: [PATCH 09/10] Fixed annotation --- src/main/java/twilightforest/item/MoonDialItem.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/twilightforest/item/MoonDialItem.java b/src/main/java/twilightforest/item/MoonDialItem.java index cfebcb253e..bbc6496998 100644 --- a/src/main/java/twilightforest/item/MoonDialItem.java +++ b/src/main/java/twilightforest/item/MoonDialItem.java @@ -11,9 +11,10 @@ import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.component.TooltipDisplay; import net.minecraft.world.level.Level; +import org.jspecify.annotations.Nullable; + import java.time.LocalDate; import java.util.function.Consumer; -import org.jetbrains.annotations.Nullable; public class MoonDialItem extends Item { public MoonDialItem(Properties properties) { From 2eb95cd65c09963bef78656c247aa69200e31b4a Mon Sep 17 00:00:00 2001 From: Albazavr Date: Thu, 23 Jul 2026 20:03:25 +0300 Subject: [PATCH 10/10] Fixed MoonDialItem --- src/main/java/twilightforest/item/MoonDialItem.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/twilightforest/item/MoonDialItem.java b/src/main/java/twilightforest/item/MoonDialItem.java index bbc6496998..11dc1fb953 100644 --- a/src/main/java/twilightforest/item/MoonDialItem.java +++ b/src/main/java/twilightforest/item/MoonDialItem.java @@ -11,6 +11,7 @@ import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.component.TooltipDisplay; import net.minecraft.world.level.Level; +import net.minecraft.world.level.MoonPhase; import org.jspecify.annotations.Nullable; import java.time.LocalDate; @@ -30,7 +31,7 @@ public void appendHoverText(ItemStack stack, TooltipContext context, TooltipDisp public static MutableComponent getMoonPhase(@Nullable Level level, BlockPos pos) { String phaseType; if (level != null && !level.dimensionType().hasFixedTime()) { - var phase = level.environmentAttributes().getValue(EnvironmentAttributes.MOON_PHASE, pos); + MoonPhase phase = level.environmentAttributes().getValue(EnvironmentAttributes.MOON_PHASE, pos); phaseType = String.valueOf(phase.index()); } else { boolean aprilFools = LocalDate.of(LocalDate.now().getYear(), 4, 1).equals(LocalDate.now());