diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b88623d..54993d3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -# [2006.1.0] +# [2100.1.1] + +### Fixed +* Fixed chapter and chapter group creation popups moving in and out with the chapter panel when it's not pinned. +* Fixed crash when creating Kill and Advancement tasks +* Fixed Fluid Tasks not loading correctly from older quest book data +* Any translatable text loaded from older quest book data is now automatically migrated into the new translation system + * A `lang/en_us.snbt` file will be auto-created under your `config/ftbquests/quests` folder when an older quest book is loaded +* Removed a misleading "Click to Submit" tooltip from fluid tasks in the quest view panel + * Fluid tasks can only be submitted via a Task Screen + +# [2100.1.0] ### Changed * Ported to Minecraft 1.21. Support for Fabric and NeoForge. diff --git a/common/src/main/java/dev/ftb/mods/ftbquests/client/gui/quests/ChapterPanel.java b/common/src/main/java/dev/ftb/mods/ftbquests/client/gui/quests/ChapterPanel.java index e34d6434..1fc0f285 100644 --- a/common/src/main/java/dev/ftb/mods/ftbquests/client/gui/quests/ChapterPanel.java +++ b/common/src/main/java/dev/ftb/mods/ftbquests/client/gui/quests/ChapterPanel.java @@ -196,7 +196,7 @@ public void onClicked(MouseButton button) { List contextMenu = new ArrayList<>(); contextMenu.add(new ContextMenuItem(Component.translatable("ftbquests.chapter"), ThemeProperties.ADD_ICON.get(), b -> { StringConfig c = new StringConfig(NON_EMPTY_PAT); - EditStringConfigOverlay overlay = new EditStringConfigOverlay<>(parent, c, accepted -> { + EditStringConfigOverlay overlay = new EditStringConfigOverlay<>(parent.getParent(), c, accepted -> { chapterPanel.questScreen.openGui(); if (accepted && !c.getValue().isEmpty()) { @@ -215,7 +215,7 @@ public void onClicked(MouseButton button) { contextMenu.add(new ContextMenuItem(Component.translatable("ftbquests.chapter_group"), ThemeProperties.ADD_ICON.get(), b -> { StringConfig c = new StringConfig(NON_EMPTY_PAT); - EditStringConfigOverlay overlay = new EditStringConfigOverlay<>(parent, c, accepted -> { + EditStringConfigOverlay overlay = new EditStringConfigOverlay<>(parent.getParent(), c, accepted -> { chapterPanel.questScreen.openGui(); if (accepted) { @@ -298,11 +298,11 @@ public void onClicked(MouseButton button) { playClickSound(); StringConfig c = new StringConfig(NON_EMPTY_PAT); - EditStringConfigOverlay overlay = new EditStringConfigOverlay<>(parent, c, accepted -> { + EditStringConfigOverlay overlay = new EditStringConfigOverlay<>(parent.getParent(), c, accepted -> { chapterPanel.questScreen.openGui(); if (accepted && !c.getValue().isEmpty()) { - Chapter chapter = new Chapter(0L, file, file.getDefaultChapterGroup()); + Chapter chapter = new Chapter(0L, file, file.getDefaultChapterGroup(), Chapter.titleToID( c.getValue()).orElse("")); CompoundTag extra = Util.make(new CompoundTag(), t -> t.putLong("group", group.id)); file.getTranslationManager().addInitialTranslation(extra, file.getLocale(), TranslationKey.TITLE, c.getValue()); NetworkManager.sendToServer(CreateObjectMessage.create(chapter, extra)); diff --git a/common/src/main/java/dev/ftb/mods/ftbquests/quest/BaseQuestFile.java b/common/src/main/java/dev/ftb/mods/ftbquests/quest/BaseQuestFile.java index f43e96ba..f18521bc 100644 --- a/common/src/main/java/dev/ftb/mods/ftbquests/quest/BaseQuestFile.java +++ b/common/src/main/java/dev/ftb/mods/ftbquests/quest/BaseQuestFile.java @@ -20,8 +20,10 @@ import dev.ftb.mods.ftbquests.quest.reward.*; import dev.ftb.mods.ftbquests.quest.task.*; import dev.ftb.mods.ftbquests.quest.theme.property.ThemeProperties; +import dev.ftb.mods.ftbquests.quest.translation.TranslationKey; import dev.ftb.mods.ftbquests.quest.translation.TranslationManager; import dev.ftb.mods.ftbquests.util.FileUtils; +import dev.ftb.mods.ftbquests.util.TextUtils; import dev.ftb.mods.ftbteams.api.FTBTeamsAPI; import dev.ftb.mods.ftbteams.api.Team; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; @@ -561,6 +563,7 @@ public final void readDataFull(Path folder, HolderLookup.Provider provider) { fileVersion = fileNBT.getInt("version"); questObjectMap.put(1, this); readData(fileNBT, provider); + handleLegacyFileNBT(fileNBT); } translationManager.loadFromNBT(folder.resolve("lang")); @@ -575,6 +578,9 @@ public final void readDataFull(Path folder, HolderLookup.Provider provider) { for (int i = 0; i < groupListTag.size(); i++) { CompoundTag groupNBT = groupListTag.getCompound(i); ChapterGroup chapterGroup = new ChapterGroup(readID(groupNBT.get("id")), this); + + handleLegacyChapterGroupNBT(groupNBT, chapterGroup); + questObjectMap.put(chapterGroup.id, chapterGroup); dataCache.put(chapterGroup.id, groupNBT); chapterGroups.add(chapterGroup); @@ -597,6 +603,9 @@ public final void readDataFull(Path folder, HolderLookup.Provider provider) { getChapterGroup(getID(chapterNBT.get("group"))), path.getFileName().toString().replace(".snbt", "") ); + + handleLegacyChapterNBT(chapterNBT, chapter); + objectOrderMap.put(chapter.id, chapterNBT.getInt("order_index")); questObjectMap.put(chapter.id, chapter); dataCache.put(chapter.id, chapterNBT); @@ -607,6 +616,9 @@ public final void readDataFull(Path folder, HolderLookup.Provider provider) { for (int i = 0; i < questList.size(); i++) { CompoundTag questNBT = questList.getCompound(i); Quest quest = new Quest(readID(questNBT.get("id")), chapter); + + handleLegacyQuestNBT(quest, questNBT); + questObjectMap.put(quest.id, quest); dataCache.put(quest.id, questNBT); chapter.addQuest(quest); @@ -617,6 +629,9 @@ public final void readDataFull(Path folder, HolderLookup.Provider provider) { CompoundTag taskNBT = taskList.getCompound(j); long taskId = readID(taskNBT.get("id")); Task task = TaskType.createTask(taskId, quest, taskNBT.getString("type")); + + handleLegacyTaskNBT(task, taskNBT); + if (task == null) { task = new CustomTask(taskId, quest); task.setRawTitle("Unknown type: " + taskNBT.getString("type")); @@ -728,6 +743,53 @@ public final void readDataFull(Path folder, HolderLookup.Provider provider) { FTBQuests.LOGGER.info("Loaded {} chapter groups, {} chapters, {} quests, {} reward tables", chapterGroups.size(), chapterCounter, questCounter, rewardTables.size()); } + private void handleLegacyFileNBT(CompoundTag fileNBT) { + if (fileNBT.contains("title", Tag.TAG_STRING)) { + translationManager.addTranslation(this, "en_us", TranslationKey.TITLE, fileNBT.getString("title")); + markDirty(); + } + } + + private void handleLegacyChapterGroupNBT(CompoundTag groupNBT, ChapterGroup chapterGroup) { + if (groupNBT.contains("title", Tag.TAG_STRING)) { + translationManager.addTranslation(chapterGroup, "en_us", TranslationKey.TITLE, groupNBT.getString("title")); + markDirty(); + } + } + + private void handleLegacyChapterNBT(CompoundTag chapterNBT, Chapter chapter) { + if (chapterNBT.contains("title", Tag.TAG_STRING)) { + translationManager.addTranslation(chapter, "en_us", TranslationKey.TITLE, chapterNBT.getString("title")); + markDirty(); + } + if (chapterNBT.contains("subtitle", Tag.TAG_LIST)) { + translationManager.addTranslation(chapter, "en_us", TranslationKey.CHAPTER_SUBTITLE, TextUtils.fromListTag(chapterNBT.getList("subtitle", Tag.TAG_STRING))); + markDirty(); + } + } + + private void handleLegacyQuestNBT(Quest quest, CompoundTag questNBT) { + if (questNBT.contains("title", Tag.TAG_STRING)) { + translationManager.addTranslation(quest, "en_us", TranslationKey.TITLE, questNBT.getString("title")); + markDirty(); + } + if (questNBT.contains("subtitle", Tag.TAG_STRING)) { + translationManager.addTranslation(quest, "en_us", TranslationKey.QUEST_SUBTITLE, questNBT.getString("subtitle")); + markDirty(); + } + if (questNBT.contains("description", Tag.TAG_LIST)) { + translationManager.addTranslation(quest, "en_us", TranslationKey.QUEST_DESC, TextUtils.fromListTag(questNBT.getList("description", Tag.TAG_STRING))); + markDirty(); + } + } + + private void handleLegacyTaskNBT(Task task, CompoundTag taskNBT) { + if (taskNBT.contains("title", Tag.TAG_STRING)) { + translationManager.addTranslation(task, "en_us", TranslationKey.TITLE, taskNBT.getString("title")); + markDirty(); + } + } + public void updateLootCrates() { Set prevCrateNames = new HashSet<>(LootCrate.LOOT_CRATES.keySet()); Collection oldStacks = LootCrate.allCrateStacks(); diff --git a/common/src/main/java/dev/ftb/mods/ftbquests/quest/Chapter.java b/common/src/main/java/dev/ftb/mods/ftbquests/quest/Chapter.java index da1fd729..8d014a58 100644 --- a/common/src/main/java/dev/ftb/mods/ftbquests/quest/Chapter.java +++ b/common/src/main/java/dev/ftb/mods/ftbquests/quest/Chapter.java @@ -364,16 +364,17 @@ public void deleteChildren() { @Override public void onCreated() { + // filename should have been suggested by the client and available here + // but in case not, fall back to the chapter's hex object id if (filename.isEmpty()) { - String basename = titleToID(getRawTitle()).orElse(toString()); - filename = basename; - - Set existingNames = new HashSet<>(); - getQuestFile().forAllChapters(ch -> existingNames.add(ch.filename)); + filename = getCodeString(); + } - for (int i = 2; existingNames.contains(filename); i++) { - filename = basename + "_" + i; - } + // ensure the filename is actually unique (same chapter name could appear in multiple groups...) + Set existingNames = new HashSet<>(); + getQuestFile().forAllChapters(ch -> existingNames.add(ch.filename)); + if (existingNames.contains(filename)) { + filename = filename + "_" + getCodeString(); } group.addChapter(this); diff --git a/common/src/main/java/dev/ftb/mods/ftbquests/quest/task/AdvancementTask.java b/common/src/main/java/dev/ftb/mods/ftbquests/quest/task/AdvancementTask.java index 9da1c861..f69f15c8 100644 --- a/common/src/main/java/dev/ftb/mods/ftbquests/quest/task/AdvancementTask.java +++ b/common/src/main/java/dev/ftb/mods/ftbquests/quest/task/AdvancementTask.java @@ -22,7 +22,7 @@ import net.minecraft.server.level.ServerPlayer; public class AdvancementTask extends AbstractBooleanTask { - private ResourceLocation advancement = ResourceLocation.withDefaultNamespace("minecraft:story/root"); + private ResourceLocation advancement = ResourceLocation.parse("minecraft:story/root"); private String criterion = ""; public AdvancementTask(long id, Quest quest) { diff --git a/common/src/main/java/dev/ftb/mods/ftbquests/quest/task/FluidTask.java b/common/src/main/java/dev/ftb/mods/ftbquests/quest/task/FluidTask.java index 5cd47e70..79a35237 100644 --- a/common/src/main/java/dev/ftb/mods/ftbquests/quest/task/FluidTask.java +++ b/common/src/main/java/dev/ftb/mods/ftbquests/quest/task/FluidTask.java @@ -14,12 +14,15 @@ import net.minecraft.core.HolderLookup; import net.minecraft.core.component.DataComponentMap; import net.minecraft.core.component.DataComponentPatch; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.Fluids; import org.jetbrains.annotations.Nullable; @@ -88,7 +91,17 @@ public void writeData(CompoundTag nbt, HolderLookup.Provider provider) { public void readData(CompoundTag nbt, HolderLookup.Provider provider) { super.readData(nbt, provider); - fluidStack = FluidStack.read(provider, nbt.getCompound("fluid")).orElse(FluidStack.empty()); + if (nbt.contains("fluid", Tag.TAG_STRING)) { + // legacy - fluid stored as string ID + ResourceLocation id = ResourceLocation.tryParse(nbt.getString("fluid")); + if (id == null) { + fluidStack = FluidStack.create(Fluids.WATER, 1000L); + } else { + fluidStack = FluidStack.create(BuiltInRegistries.FLUID.get(id), nbt.getLong("amount")); + } + } else { + fluidStack = FluidStack.read(provider, nbt.getCompound("fluid")).orElse(FluidStack.empty()); + } } @Override diff --git a/common/src/main/java/dev/ftb/mods/ftbquests/quest/task/KillTask.java b/common/src/main/java/dev/ftb/mods/ftbquests/quest/task/KillTask.java index 488c69a9..a4fb840b 100644 --- a/common/src/main/java/dev/ftb/mods/ftbquests/quest/task/KillTask.java +++ b/common/src/main/java/dev/ftb/mods/ftbquests/quest/task/KillTask.java @@ -26,7 +26,7 @@ import java.util.List; public class KillTask extends Task { - private static final ResourceLocation ZOMBIE = ResourceLocation.withDefaultNamespace("minecraft:zombie"); + private static final ResourceLocation ZOMBIE = ResourceLocation.parse("minecraft:zombie"); private ResourceLocation entity = ZOMBIE; private long value = 100L; diff --git a/common/src/main/java/dev/ftb/mods/ftbquests/quest/task/Task.java b/common/src/main/java/dev/ftb/mods/ftbquests/quest/task/Task.java index 69406a90..ec1c919a 100644 --- a/common/src/main/java/dev/ftb/mods/ftbquests/quest/task/Task.java +++ b/common/src/main/java/dev/ftb/mods/ftbquests/quest/task/Task.java @@ -233,10 +233,6 @@ public void addMouseOverHeader(TooltipList list, TeamData teamData, boolean adva */ @Environment(EnvType.CLIENT) public void addMouseOverText(TooltipList list, TeamData teamData) { - if (consumesResources()) { - list.blankLine(); - list.add(Component.translatable("ftbquests.task.click_to_submit").withStyle(ChatFormatting.YELLOW, ChatFormatting.UNDERLINE)); - } } @Environment(EnvType.CLIENT) diff --git a/common/src/main/java/dev/ftb/mods/ftbquests/util/TextUtils.java b/common/src/main/java/dev/ftb/mods/ftbquests/util/TextUtils.java index 9ba268f3..7c79585c 100644 --- a/common/src/main/java/dev/ftb/mods/ftbquests/util/TextUtils.java +++ b/common/src/main/java/dev/ftb/mods/ftbquests/util/TextUtils.java @@ -4,8 +4,13 @@ import dev.ftb.mods.ftblibrary.util.client.ClientTextComponentUtils; import net.minecraft.ChatFormatting; import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.Tag; +import net.minecraft.nbt.TagType; import net.minecraft.network.chat.Component; +import java.util.ArrayList; +import java.util.List; import java.util.regex.Pattern; public class TextUtils { @@ -31,4 +36,14 @@ private static Component deserializeRawJsonText(String raw, HolderLookup.Provide return Component.literal("ERROR: " + e.getMessage()).withStyle(ChatFormatting.RED); } } + + public static List fromListTag(ListTag tag) { + List res = new ArrayList<>(); + tag.forEach(el -> { + if (el.getId() == Tag.TAG_STRING) { + res.add(el.getAsString()); + } + }); + return res; + } } diff --git a/gradle.properties b/gradle.properties index 3e092d76..15d996bc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,21 +9,21 @@ maven_group=dev.ftb.mods mod_author=FTB Team # Build time -mod_version=2100.1.0 +mod_version=2100.1.1 minecraft_version=1.21 # Cross env #forge_version=50.0.9 #forge_loader_version=49 -neoforge_version=21.0.10-beta +neoforge_version=21.0.21-beta # https://maven.neoforged.net/#/releases/net/neoforged/fancymodloader/loader neoforge_loader_version=4 fabric_loader_version=0.15.11 fabric_api_version=0.100.1+1.21 architectury_api_version=13.0.1 -ftb_library_version=2100.1.0 +ftb_library_version=2100.1.1 ftb_teams_version=2100.1.0 # Optional deps