Skip to content

Commit 67879bd

Browse files
authored
Merge pull request #776 from FTBTeam/dev
Dev
2 parents 1a91dab + dae5765 commit 67879bd

27 files changed

+1442
-184
lines changed

CHANGELOG.md

+18
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,24 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [2101.1.7]
8+
9+
### Added
10+
* Added exclusive quest branching, where starting one quest makes certain other quests unavailable
11+
* New "Max Completable Dependents" integer property for quests
12+
* When that number of dependent quests is completed, other uncompleted dependents of that quest become unavailable to the player/team
13+
* Improved importing of legacy quest data (from quest book data in 1.20.1 and earlier)
14+
* Item SNBT data is now imported, other than custom NBT data, which can't reliably be auto-converted to 1.21 item component data
15+
* Added ja_jp translation (thanks @twister716)
16+
* Added de_de translation (thanks @FlyonDE)
17+
* Task Screens now show related quest names along with task names (and can search on those)
18+
* New hotkeys when hovering chapters (same as 2101.1.6 changes made to quests):
19+
* Left-Alt & Left-Mouse opens directly to chapter properties
20+
* Right-Alt & Left-Mouse copies the chapter ID
21+
22+
### Fixed
23+
* Add extra defensive null-checking to avoid crashes by mods incorrectly calling `Entity#die` with a null damage source
24+
725
## [2101.1.6]
826

927
### Added

common/src/main/java/dev/ftb/mods/ftbquests/FTBQuestsEventHandler.java

+5
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ private void playerChangedTeam(PlayerChangedTeamEvent event) {
114114
}
115115

116116
private EventResult playerKill(LivingEntity entity, DamageSource source) {
117+
// `source` should never be null, this is a defensive check against badly behaved mods.
118+
if (source == null) {
119+
return EventResult.pass();
120+
}
121+
117122
if (source.getEntity() instanceof ServerPlayer player && !PlayerHooks.isFake(player)) {
118123
if (killTasks == null) {
119124
killTasks = ServerQuestFile.INSTANCE.collect(KillTask.class);

common/src/main/java/dev/ftb/mods/ftbquests/block/entity/TaskScreenBlockEntity.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import dev.ftb.mods.ftbquests.registry.ModBlocks;
1919
import dev.ftb.mods.ftbquests.registry.ModDataComponents;
2020
import dev.ftb.mods.ftbquests.util.ConfigQuestObject;
21+
import net.minecraft.ChatFormatting;
2122
import net.minecraft.Util;
2223
import net.minecraft.core.BlockPos;
2324
import net.minecraft.core.Direction;
@@ -26,6 +27,7 @@
2627
import net.minecraft.nbt.CompoundTag;
2728
import net.minecraft.nbt.NbtOps;
2829
import net.minecraft.network.RegistryFriendlyByteBuf;
30+
import net.minecraft.network.chat.Component;
2931
import net.minecraft.network.codec.ByteBufCodecs;
3032
import net.minecraft.network.codec.StreamCodec;
3133
import net.minecraft.network.protocol.Packet;
@@ -223,7 +225,7 @@ public ConfigGroup fillConfigGroup(TeamData data) {
223225

224226
cg0.setNameKey(getBlockState().getBlock().getDescriptionId());
225227
ConfigGroup cg = cg0.getOrCreateSubgroup("screen");
226-
cg.add("task", new ConfigQuestObject<>(o -> isSuitableTask(data, o)), getTask(), this::setTask, null).setNameKey("ftbquests.task");
228+
cg.add("task", new ConfigQuestObject<>(o -> isSuitableTask(data, o), this::formatLine), getTask(), this::setTask, null).setNameKey("ftbquests.task");
227229
cg.add("skin", new ItemStackConfig(true, true), getSkin(), this::setSkin, ItemStack.EMPTY).setNameKey("block.ftbquests.screen.skin");
228230
cg.add("text_shadow", new BooleanConfig(), isTextShadow(), this::setTextShadow, false).setNameKey("block.ftbquests.screen.text_shadow");
229231
cg.add("indestructible", new BooleanConfig(), isIndestructible(), this::setIndestructible, false).setNameKey("block.ftbquests.screen.indestructible");
@@ -233,6 +235,13 @@ public ConfigGroup fillConfigGroup(TeamData data) {
233235
return cg0;
234236
}
235237

238+
private Component formatLine(Task task) {
239+
if (this.task == null) return Component.empty();
240+
241+
Component questTxt = Component.literal(" [").append(task.getQuest().getTitle()).append("]").withStyle(ChatFormatting.GREEN);
242+
return ConfigQuestObject.formatEntry(task).copy().append(questTxt);
243+
}
244+
236245
private boolean isSuitableTask(TeamData data, QuestObjectBase o) {
237246
return o instanceof Task t && (data.getCanEdit(FTBQuestsClient.getClientPlayer()) || data.canStartTasks(t.getQuest())) && t.consumesResources();
238247
}

common/src/main/java/dev/ftb/mods/ftbquests/client/FTBQuestsClientConfig.java

+8
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public interface FTBQuestsClientConfig {
1818
IntValue PINNED_QUESTS_INSET_Y = UI.addInt("pinned_quests_inset_y", 2);
1919
BooleanValue SHOW_LOCK_ICON = UI.addBoolean("show_lock_icon", true);
2020
BooleanValue BACKSPACE_HISTORY = UI.addBoolean("backspace_history", true);
21+
BooleanValue CHAPTER_PANEL_PINNED = UI.addBoolean("chapter_panel_pinned", false);
2122

2223
SNBTConfig XLATE = CONFIG.addGroup("xlate", 1);
2324
StringValue EDITING_LOCALE = XLATE.add(new LocaleValue(XLATE,"editing_locale", ""));
@@ -29,4 +30,11 @@ static void openSettings(boolean pauseGame) {
2930
ConfigManager.getInstance().createConfigGroup(KEY)
3031
.ifPresent(group -> new QuestsClientConfigScreen(group, pauseGame).openGui());
3132
}
33+
34+
static void setChapterPanelPinned(boolean pinned) {
35+
if (pinned != CHAPTER_PANEL_PINNED.get()) {
36+
CHAPTER_PANEL_PINNED.set(pinned);
37+
ConfigManager.getInstance().save(KEY);
38+
}
39+
}
3240
}

common/src/main/java/dev/ftb/mods/ftbquests/client/FTBQuestsNetClient.java

-5
Original file line numberDiff line numberDiff line change
@@ -259,11 +259,6 @@ private static void refreshQuestScreenIfOpen() {
259259
}
260260
}
261261

262-
public static void toggleChapterPinned(boolean pinned) {
263-
ClientQuestFile.INSTANCE.selfTeamData.setChapterPinned(FTBQuestsClient.getClientPlayer(), pinned);
264-
ClientQuestFile.INSTANCE.getQuestScreen().ifPresent(QuestScreen::refreshChapterPanel);
265-
}
266-
267262
public static void syncRewardBlocking(UUID teamId, boolean rewardsBlocked) {
268263
if (ClientQuestFile.INSTANCE.getOrCreateTeamData(teamId).setRewardsBlocked(rewardsBlocked)) {
269264
ClientQuestFile.INSTANCE.refreshGui();

common/src/main/java/dev/ftb/mods/ftbquests/client/gui/SelectQuestObjectScreen.java

+59-33
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22

33
import dev.ftb.mods.ftblibrary.config.ConfigCallback;
44
import dev.ftb.mods.ftblibrary.icon.Color4I;
5-
import dev.ftb.mods.ftblibrary.ui.GuiHelper;
6-
import dev.ftb.mods.ftblibrary.ui.Panel;
7-
import dev.ftb.mods.ftblibrary.ui.SimpleTextButton;
8-
import dev.ftb.mods.ftblibrary.ui.Theme;
5+
import dev.ftb.mods.ftblibrary.ui.*;
96
import dev.ftb.mods.ftblibrary.ui.input.Key;
107
import dev.ftb.mods.ftblibrary.ui.input.MouseButton;
118
import dev.ftb.mods.ftblibrary.ui.misc.AbstractButtonListScreen;
@@ -23,10 +20,13 @@
2320

2421
import java.util.ArrayList;
2522
import java.util.List;
23+
import java.util.Objects;
24+
import java.util.function.Function;
2625

2726
public class SelectQuestObjectScreen<T extends QuestObjectBase> extends AbstractButtonListScreen {
2827
private final ConfigQuestObject<T> config;
2928
private final ConfigCallback callback;
29+
private Function<T,Component> formatter = ConfigQuestObject::formatEntry;
3030

3131
public SelectQuestObjectScreen(ConfigQuestObject<T> config, ConfigCallback callback) {
3232
setTitle(Component.translatable("ftbquests.gui.select_quest_object"));
@@ -40,6 +40,11 @@ public SelectQuestObjectScreen(ConfigQuestObject<T> config, ConfigCallback callb
4040
this.callback = callback;
4141
}
4242

43+
public SelectQuestObjectScreen<T> withFormatter(@Nullable Function<T,Component> formatter) {
44+
this.formatter = Objects.requireNonNullElse(formatter, ConfigQuestObject::formatEntry);
45+
return this;
46+
}
47+
4348
@Override
4449
public boolean onClosedByKey(Key key) {
4550
if (super.onClosedByKey(key)) {
@@ -82,6 +87,15 @@ public void addButtons(Panel panel) {
8287
for (T objectBase : list) {
8388
panel.add(new QuestObjectButton(panel, objectBase));
8489
}
90+
91+
int width = panel.getWidgets().stream().map(Widget::getWidth).max(Integer::compare).orElse(200);
92+
panel.getWidgets().forEach(w -> w.setWidth(width));
93+
}
94+
95+
@Override
96+
public boolean onInit() {
97+
setWidth(mainPanel.getWidgets().isEmpty() ? 200 : mainPanel.getWidgets().getFirst().width + 20);
98+
return super.onInit();
8599
}
86100

87101
@Override
@@ -97,14 +111,20 @@ protected void doAccept() {
97111
private class QuestObjectButton extends SimpleTextButton {
98112
public final T object;
99113

100-
public QuestObjectButton(Panel panel, @Nullable T o) {
101-
super(panel, o == null ? Component.translatable("ftbquests.null") : o.getMutableTitle().withStyle(o.getObjectType().getColor()), o == null ? Color4I.empty() : o.getIcon());
102-
object = o;
103-
setSize(200, 14);
114+
public QuestObjectButton(Panel panel, @Nullable T questObject) {
115+
super(panel,
116+
questObject == null ? Component.translatable("ftbquests.null") : formatter.apply(questObject),
117+
questObject == null ? Color4I.empty() : questObject.getIcon()
118+
);
119+
object = questObject;
120+
setHeight(getTheme().getFontHeight() + 4);
104121
}
105122

106123
private void addObject(TooltipList list, QuestObjectBase o) {
107-
list.add(QuestObjectType.NAME_MAP.getDisplayName(o.getObjectType()).copy().withStyle(ChatFormatting.GRAY).append(": ").append(o.getMutableTitle().withStyle(o.getObjectType().getColor())));
124+
list.add(QuestObjectType.NAME_MAP.getDisplayName(o.getObjectType()).copy().withStyle(ChatFormatting.GRAY)
125+
.append(": ")
126+
.append(o.getMutableTitle().withStyle(o.getObjectType().getColor()))
127+
);
108128
}
109129

110130
@Override
@@ -114,30 +134,36 @@ public void addMouseOverText(TooltipList list) {
114134
}
115135

116136
list.add(object.getTitle());
117-
list.add(Component.literal("ID: ").withStyle(ChatFormatting.GRAY).append(Component.literal(object.toString()).withStyle(ChatFormatting.DARK_GRAY)));
118-
list.add(Component.literal("Type: ").withStyle(ChatFormatting.GRAY).append(QuestObjectType.NAME_MAP.getDisplayName(object.getObjectType()).copy().withStyle(object.getObjectType().getColor())));
119-
120-
if (object instanceof Quest quest) {
121-
addObject(list, quest.getChapter());
122-
addRewardTooltip(list, quest);
123-
} else if (object instanceof QuestLink link) {
124-
link.getQuest().ifPresent(quest -> {
125-
addObject(list, link.getChapter());
126-
list.add(Component.translatable("ftbquests.gui.linked_quest_id", Component.literal(quest.getCodeString()).withStyle(ChatFormatting.DARK_GRAY)).withStyle(ChatFormatting.GRAY));
127-
addObject(list, quest.getChapter());
128-
});
129-
} else if (object instanceof Task task) {
130-
Quest quest = task.getQuest();
131-
addObject(list, quest.getChapter());
132-
addObject(list, quest);
133-
addRewardTooltip(list, quest);
134-
} else if (object instanceof Reward reward) {
135-
Quest quest = reward.getQuest();
136-
addObject(list, quest.getChapter());
137-
addObject(list, quest);
138-
} else if (object instanceof RewardTable rewardTable) {
139-
rewardTable.addMouseOverText(list, true, true);
140-
}
137+
list.add(Component.literal("ID: ").withStyle(ChatFormatting.GRAY)
138+
.append(Component.literal(object.toString()).withStyle(ChatFormatting.DARK_GRAY)));
139+
list.add(Component.literal("Type: ").withStyle(ChatFormatting.GRAY)
140+
.append(QuestObjectType.NAME_MAP.getDisplayName(object.getObjectType()).copy().withStyle(object.getObjectType().getColor())));
141+
142+
switch (object) {
143+
case Quest quest -> {
144+
addObject(list, quest.getChapter());
145+
addRewardTooltip(list, quest);
146+
}
147+
case QuestLink link -> link.getQuest().ifPresent(quest -> {
148+
addObject(list, link.getChapter());
149+
list.add(Component.translatable("ftbquests.gui.linked_quest_id", Component.literal(quest.getCodeString()).withStyle(ChatFormatting.DARK_GRAY)).withStyle(ChatFormatting.GRAY));
150+
addObject(list, quest.getChapter());
151+
});
152+
case Task task -> {
153+
Quest quest = task.getQuest();
154+
addObject(list, quest.getChapter());
155+
addObject(list, quest);
156+
addRewardTooltip(list, quest);
157+
}
158+
case Reward reward -> {
159+
Quest quest = reward.getQuest();
160+
addObject(list, quest.getChapter());
161+
addObject(list, quest);
162+
}
163+
case RewardTable rewardTable -> rewardTable.addMouseOverText(list, true, true);
164+
default -> {
165+
}
166+
}
141167
}
142168

143169
private void addRewardTooltip(TooltipList list, Quest quest) {

common/src/main/java/dev/ftb/mods/ftbquests/client/gui/quests/ChapterPanel.java

+21-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dev.ftb.mods.ftbquests.client.gui.quests;
22

3+
import com.mojang.blaze3d.platform.InputConstants;
34
import com.mojang.blaze3d.systems.RenderSystem;
45
import dev.architectury.networking.NetworkManager;
56
import dev.ftb.mods.ftblibrary.config.StringConfig;
@@ -12,13 +13,14 @@
1213
import dev.ftb.mods.ftblibrary.util.TooltipList;
1314
import dev.ftb.mods.ftblibrary.util.client.PositionedIngredient;
1415
import dev.ftb.mods.ftbquests.client.ClientQuestFile;
16+
import dev.ftb.mods.ftbquests.client.FTBQuestsClient;
1517
import dev.ftb.mods.ftbquests.client.FTBQuestsClientConfig;
1618
import dev.ftb.mods.ftbquests.client.gui.ChangeChapterGroupScreen;
1719
import dev.ftb.mods.ftbquests.client.gui.ContextMenuBuilder;
20+
import dev.ftb.mods.ftbquests.client.gui.CustomToast;
1821
import dev.ftb.mods.ftbquests.net.CreateObjectMessage;
1922
import dev.ftb.mods.ftbquests.net.MoveChapterGroupMessage;
2023
import dev.ftb.mods.ftbquests.net.MoveChapterMessage;
21-
import dev.ftb.mods.ftbquests.net.ToggleChapterPinnedMessage;
2224
import dev.ftb.mods.ftbquests.quest.Chapter;
2325
import dev.ftb.mods.ftbquests.quest.ChapterGroup;
2426
import dev.ftb.mods.ftbquests.quest.theme.property.ThemeProperties;
@@ -160,7 +162,7 @@ public void setExpanded(boolean b) {
160162
}
161163

162164
boolean isPinned() {
163-
return ClientQuestFile.INSTANCE.selfTeamData.isChapterPinned(Minecraft.getInstance().player);
165+
return FTBQuestsClientConfig.CHAPTER_PANEL_PINNED.get();
164166
}
165167

166168
public static abstract class ListButton extends Button {
@@ -195,7 +197,7 @@ public ModpackButton(ChapterPanel panel, ClientQuestFile f) {
195197
public void onClicked(MouseButton button) {
196198
if (getMouseX() > getX() + width - 18) {
197199
playClickSound();
198-
NetworkManager.sendToServer(ToggleChapterPinnedMessage.INSTANCE);
200+
FTBQuestsClientConfig.setChapterPanelPinned(!FTBQuestsClientConfig.CHAPTER_PANEL_PINNED.get());
199201
} else {
200202
ClientQuestFile file = chapterPanel.questScreen.file;
201203
if (file.canEdit() && getMouseX() > getX() + width - 34) {
@@ -277,9 +279,7 @@ public int getActualWidth(QuestScreen screen) {
277279
public void addMouseOverText(TooltipList list) {
278280
chapterPanel.questScreen.addInfoTooltip(list, chapterPanel.questScreen.file);
279281

280-
if (getMouseX() > getX() + width - 18) {
281-
list.translate(chapterPanel.isPinned() ? "ftbquests.gui.stays_open" : "ftbquests.gui.does_not_stay_open");
282-
} else if (chapterPanel.questScreen.file.canEdit() && getMouseX() > getX() + width - 34) {
282+
if (chapterPanel.questScreen.file.canEdit() && getMouseX() > getX() + width - 34) {
283283
list.translate("gui.add");
284284
}
285285
}
@@ -406,10 +406,21 @@ public void onClicked(MouseButton button) {
406406
if (chapterPanel.questScreen.file.canEdit() || chapter.hasAnyVisibleChildren()) {
407407
playClickSound();
408408

409-
if (chapterPanel.questScreen.selectedChapter != chapter) {
410-
chapterPanel.questScreen.open(chapter, false);
411-
chapter.getAutofocus().ifPresent(chapterPanel.questScreen::scrollTo);
412-
}
409+
if (chapterPanel.questScreen.file.canEdit() && button.isLeft()) {
410+
if (isKeyDown(InputConstants.KEY_LALT)) {
411+
chapter.onEditButtonClicked(chapterPanel.questScreen);
412+
} else if (isKeyDown(InputConstants.KEY_RALT)) {
413+
FTBQuestsClient.copyToClipboard(chapter);
414+
Minecraft.getInstance().getToasts().addToast(new CustomToast(Component.translatable("ftbquests.quest.copied"),
415+
Icons.INFO, Component.literal(chapter.getTitle().getString())));
416+
} else if (chapterPanel.questScreen.selectedChapter != chapter) {
417+
chapterPanel.questScreen.open(chapter, false);
418+
chapter.getAutofocus().ifPresent(chapterPanel.questScreen::scrollTo);
419+
}
420+
} else if (chapterPanel.questScreen.selectedChapter != chapter) {
421+
chapterPanel.questScreen.open(chapter, false);
422+
chapter.getAutofocus().ifPresent(chapterPanel.questScreen::scrollTo);
423+
}
413424
}
414425

415426
if (chapterPanel.questScreen.file.canEdit() && button.isRight()) {

common/src/main/java/dev/ftb/mods/ftbquests/client/gui/quests/QuestButton.java

+4
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,10 @@ public void addMouseOverText(TooltipList list) {
328328
if (!questScreen.file.selfTeamData.canStartTasks(quest)) {
329329
list.add(Component.literal("[").withStyle(ChatFormatting.DARK_GRAY).append(Component.translatable("ftbquests.quest.locked")).append("]"));
330330
}
331+
if (quest.isExclusiveQuest()) {
332+
list.add(Component.translatable("ftbquests.quest.misc.exclusive").withStyle(ChatFormatting.GOLD));
333+
list.add(Component.translatable("ftbquests.quest.misc.exclusive.desc").withColor(0xFFC08000));
334+
}
331335
}
332336

333337
@Override

common/src/main/java/dev/ftb/mods/ftbquests/net/FTBQuestsNetHandler.java

-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ public static void init() {
2828
NetworkHelper.registerC2S(SyncStructuresRequestMessage.TYPE, SyncStructuresRequestMessage.STREAM_CODEC, SyncStructuresRequestMessage::handle);
2929
NetworkHelper.registerC2S(SyncTranslationMessageToServer.TYPE, SyncTranslationMessageToServer.STREAM_CODEC, SyncTranslationMessageToServer::handle);
3030
NetworkHelper.registerC2S(TaskScreenConfigResponseMessage.TYPE, TaskScreenConfigResponseMessage.STREAM_CODEC, TaskScreenConfigResponseMessage::handle);
31-
NetworkHelper.registerC2S(ToggleChapterPinnedMessage.TYPE, ToggleChapterPinnedMessage.STREAM_CODEC, ToggleChapterPinnedMessage::handle);
3231
NetworkHelper.registerC2S(ToggleEditingModeMessage.TYPE, ToggleEditingModeMessage.STREAM_CODEC, ToggleEditingModeMessage::handle);
3332
NetworkHelper.registerC2S(TogglePinnedMessage.TYPE, TogglePinnedMessage.STREAM_CODEC, TogglePinnedMessage::handle);
3433

@@ -62,7 +61,6 @@ public static void init() {
6261
NetworkHelper.registerS2C(SyncTranslationTableMessage.TYPE, SyncTranslationTableMessage.STREAM_CODEC, SyncTranslationTableMessage::handle);
6362
NetworkHelper.registerS2C(TaskScreenConfigRequestMessage.TYPE, TaskScreenConfigRequestMessage.STREAM_CODEC, TaskScreenConfigRequestMessage::handle);
6463
NetworkHelper.registerS2C(TeamDataChangedMessage.TYPE, TeamDataChangedMessage.STREAM_CODEC, TeamDataChangedMessage::handle);
65-
NetworkHelper.registerS2C(ToggleChapterPinnedResponseMessage.TYPE, ToggleChapterPinnedResponseMessage.STREAM_CODEC, ToggleChapterPinnedResponseMessage::handle);
6664
NetworkHelper.registerS2C(TogglePinnedResponseMessage.TYPE, TogglePinnedResponseMessage.STREAM_CODEC, TogglePinnedResponseMessage::handle);
6765
NetworkHelper.registerS2C(UpdateTaskProgressMessage.TYPE, UpdateTaskProgressMessage.STREAM_CODEC, UpdateTaskProgressMessage::handle);
6866
NetworkHelper.registerS2C(UpdateTeamDataMessage.TYPE, UpdateTeamDataMessage.STREAM_CODEC, UpdateTeamDataMessage::handle);

common/src/main/java/dev/ftb/mods/ftbquests/net/ToggleChapterPinnedMessage.java

-33
This file was deleted.

0 commit comments

Comments
 (0)