Skip to content

Commit

Permalink
Merge pull request #752 from FTBTeam/1.20.1/dev
Browse files Browse the repository at this point in the history
1.20.1/dev
  • Loading branch information
desht authored Oct 16, 2024
2 parents 6a3dc8f + 52c9d57 commit 9718dcf
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 48 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@ 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).

## [2001.4.9]

### Added
* A few new template substitutions are available in command rewards
* `{team_id}` - the short team name, e.g. "Dev#380df991"
* `{long_team_id}` - the full team UUID, e.g. "380df991-f603-344c-a090-369bad2a924a"
* `{member_count}` - the number of players in the team
* `{online_member_count}` - the number of currently-online players in the team

### Fixed
* Fixed "Hide Quests until Dependencies Visible" setting actually checking for dependencies being _complete_
* Added new "Hide Quests until Dependencies Complete" setting
* So there are now two independent setting for hiding quests based on dependency visibility and/or completion

## [2001.4.8]

### Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ public interface FTBQuestsClientConfig {
SNBTConfig UI = CONFIG.addGroup("ui", 0);
BooleanValue OLD_SCROLL_WHEEL = UI.addBoolean("old_scroll_wheel", false);
EnumValue<PanelPositioning> PINNED_QUESTS_POS = UI.addEnum("pinned_quests_pos", PanelPositioning.NAME_MAP, PanelPositioning.RIGHT);
IntValue PINNED_QUESTS_INSET_X = UI.addInt("pinned_quests_inset_x", 2);
IntValue PINNED_QUESTS_INSET_Y = UI.addInt("pinned_quests_inset_y", 2);
IntValue PINNED_QUESTS_INSET_X = UI.addInt("pinned_quests_inset_x", 4);
IntValue PINNED_QUESTS_INSET_Y = UI.addInt("pinned_quests_inset_y", 4);

// TODO migrate chapter-pinned and pinned-quests data out of per-player team data into here

Expand Down
17 changes: 14 additions & 3 deletions common/src/main/java/dev/ftb/mods/ftbquests/quest/Chapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public final class Chapter extends QuestObject {
private int defaultMinWidth = 0;
private ProgressionMode progressionMode;
private boolean hideQuestDetailsUntilStartable;
private boolean hideQuestUntilDepsComplete;
private boolean hideQuestUntilDepsVisible;
private boolean defaultRepeatable;
private Tristate consumeItems;
Expand All @@ -68,6 +69,7 @@ public Chapter(long id, BaseQuestFile file, ChapterGroup group, String filename)
defaultHideDependencyLines = false;
progressionMode = ProgressionMode.DEFAULT;
hideQuestUntilDepsVisible = false;
hideQuestUntilDepsComplete = false;
hideQuestDetailsUntilStartable = false;
defaultRepeatable = false;
consumeItems = Tristate.DEFAULT;
Expand Down Expand Up @@ -187,6 +189,7 @@ public void writeData(CompoundTag nbt) {

if (hideQuestDetailsUntilStartable) nbt.putBoolean("hide_quest_details_until_startable", true);
if (hideQuestUntilDepsVisible) nbt.putBoolean("hide_quest_until_deps_visible", true);
if (hideQuestUntilDepsComplete) nbt.putBoolean("hide_quest_until_deps_complete", true);
if (defaultRepeatable) nbt.putBoolean("default_repeatable_quest", true);
if (requireSequentialTasks) nbt.putBoolean("require_sequential_tasks", true);

Expand Down Expand Up @@ -233,6 +236,7 @@ public void readData(CompoundTag nbt) {
consumeItems = Tristate.read(nbt, "consume_items");
hideQuestDetailsUntilStartable = nbt.getBoolean("hide_quest_details_until_startable");
hideQuestUntilDepsVisible = nbt.getBoolean("hide_quest_until_deps_visible");
hideQuestUntilDepsComplete = nbt.getBoolean("hide_quest_until_deps_complete");
defaultRepeatable = nbt.getBoolean("default_repeatable_quest");
requireSequentialTasks = nbt.getBoolean("require_sequential_tasks");
autoFocusId = nbt.getString("autofocus_id");
Expand All @@ -253,12 +257,13 @@ public void writeNetData(FriendlyByteBuf buffer) {
flags = Bits.setFlag(flags, 0x01, alwaysInvisible);
flags = Bits.setFlag(flags, 0x02, defaultHideDependencyLines);
flags = Bits.setFlag(flags, 0x04, hideQuestDetailsUntilStartable);
flags = Bits.setFlag(flags, 0x08, hideQuestUntilDepsVisible);
flags = Bits.setFlag(flags, 0x08, hideQuestUntilDepsComplete);
flags = Bits.setFlag(flags, 0x10, defaultRepeatable);
flags = Bits.setFlag(flags, 0x20, consumeItems != Tristate.DEFAULT);
flags = Bits.setFlag(flags, 0x40, consumeItems == Tristate.TRUE);
flags = Bits.setFlag(flags, 0x80, requireSequentialTasks);
flags = Bits.setFlag(flags, 0x100, !autoFocusId.isEmpty());
flags = Bits.setFlag(flags, 0x200, hideQuestUntilDepsVisible);
buffer.writeVarInt(flags);

if (!autoFocusId.isEmpty()) buffer.writeLong(QuestObjectBase.parseHexId(autoFocusId).orElse(0L));
Expand All @@ -283,10 +288,11 @@ public void readNetData(FriendlyByteBuf buffer) {
alwaysInvisible = Bits.getFlag(flags, 0x01);
defaultHideDependencyLines = Bits.getFlag(flags, 0x02);
hideQuestDetailsUntilStartable = Bits.getFlag(flags, 0x04);
hideQuestUntilDepsVisible = Bits.getFlag(flags, 0x08);
hideQuestUntilDepsComplete = Bits.getFlag(flags, 0x08);
defaultRepeatable = Bits.getFlag(flags, 0x10);
consumeItems = Bits.getFlag(flags, 0x20) ? Bits.getFlag(flags, 0x40) ? Tristate.TRUE : Tristate.FALSE : Tristate.DEFAULT;
requireSequentialTasks = Bits.getFlag(flags, 0x80);
hideQuestUntilDepsVisible = Bits.getFlag(flags, 0x200);

autoFocusId = Bits.getFlag(flags, 0x100) ? QuestObjectBase.getCodeString(buffer.readLong()) : "";
}
Expand Down Expand Up @@ -441,6 +447,7 @@ public void fillConfigGroup(ConfigGroup config) {
visibility.addBool("default_hide_dependency_lines", defaultHideDependencyLines, v -> defaultHideDependencyLines = v, false);
visibility.addBool("hide_quest_details_until_startable", hideQuestDetailsUntilStartable, v -> hideQuestDetailsUntilStartable = v, false);
visibility.addBool("hide_quest_until_deps_visible", hideQuestUntilDepsVisible, v -> hideQuestUntilDepsVisible = v, false);
visibility.addBool("hide_quest_until_deps_complete", hideQuestUntilDepsComplete, v -> hideQuestUntilDepsComplete = v, false);

ConfigGroup misc = config.getOrCreateSubgroup("misc").setNameKey("ftbquests.quest.misc");
misc.addString("autofocus_id", autoFocusId, v -> autoFocusId = v, "", HEX_STRING);
Expand Down Expand Up @@ -513,7 +520,11 @@ public boolean hideQuestDetailsUntilStartable() {
return hideQuestDetailsUntilStartable;
}

public boolean hideQuestUntilDepsVisible() {
public boolean hideQuestUntilDepsComplete() {
return hideQuestUntilDepsComplete;
}

public boolean isHideQuestUntilDepsVisible() {
return hideQuestUntilDepsVisible;
}

Expand Down
49 changes: 39 additions & 10 deletions common/src/main/java/dev/ftb/mods/ftbquests/quest/Quest.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public final class Quest extends QuestObject implements Movable {
private String rawSubtitle;
private double x, y;
private Tristate hideUntilDepsVisible;
private Tristate hideUntilDepsComplete;
private String shape;
private final List<String> rawDescription;
private final List<QuestObject> dependencies;
Expand Down Expand Up @@ -94,6 +95,7 @@ public Quest(long id, Chapter chapter) {
hideDependencyLines = Tristate.DEFAULT;
hideDependentLines = false;
hideUntilDepsVisible = Tristate.DEFAULT;
hideUntilDepsComplete = Tristate.DEFAULT;
dependencyRequirement = DependencyRequirement.ALL_COMPLETED;
minRequiredDependencies = 0;
hideTextUntilComplete = Tristate.DEFAULT;
Expand Down Expand Up @@ -265,7 +267,8 @@ public void writeData(CompoundTag nbt) {
nbt.put("dependencies", deps);
}

hideUntilDepsVisible.write(nbt, "hide");
hideUntilDepsVisible.write(nbt, "hide_until_deps_visible");
hideUntilDepsComplete.write(nbt, "hide_until_deps_complete");

if (dependencyRequirement != DependencyRequirement.ALL_COMPLETED) {
nbt.putString("dependency_requirement", dependencyRequirement.getId());
Expand Down Expand Up @@ -357,7 +360,14 @@ public void readData(CompoundTag nbt) {
}
}

hideUntilDepsVisible = Tristate.read(nbt, "hide");
if (nbt.contains("hide", Tag.TAG_BYTE)) {
// TODO legacy; remove in 1.22
hideUntilDepsVisible = Tristate.read(nbt, "hide");
} else {
hideUntilDepsVisible = Tristate.read(nbt, "hide_until_deps_visible");
}
hideUntilDepsComplete = Tristate.read(nbt, "hide_until_deps_complete");

dependencyRequirement = DependencyRequirement.NAME_MAP.get(nbt.getString("dependency_requirement"));
hideTextUntilComplete = Tristate.read(nbt, "hide_text_until_complete");
size = nbt.getDouble("size");
Expand Down Expand Up @@ -398,6 +408,7 @@ public void writeNetData(FriendlyByteBuf buffer) {
flags = Bits.setFlag(flags, 0x20000, iconScale != 1f);
buffer.writeVarInt(flags);

hideUntilDepsComplete.write(buffer);
hideUntilDepsVisible.write(buffer);
hideDependencyLines.write(buffer);
hideTextUntilComplete.write(buffer);
Expand Down Expand Up @@ -449,6 +460,7 @@ public void writeNetData(FriendlyByteBuf buffer) {
public void readNetData(FriendlyByteBuf buffer) {
super.readNetData(buffer);
int flags = buffer.readVarInt();
hideUntilDepsComplete = Tristate.read(buffer);
hideUntilDepsVisible = Tristate.read(buffer);
hideDependencyLines = Tristate.read(buffer);
hideTextUntilComplete = Tristate.read(buffer);
Expand Down Expand Up @@ -668,7 +680,8 @@ public void onClicked(Widget clicked, MouseButton button, ConfigCallback callbac
appearance.addDouble("icon_scale", iconScale, v -> iconScale = v, 1f, 0.1, 2.0);

ConfigGroup visibility = config.getOrCreateSubgroup("visibility");
visibility.addTristate("hide", hideUntilDepsVisible, v -> hideUntilDepsVisible = v);
visibility.addTristate("hide_until_deps_complete", hideUntilDepsComplete, v -> hideUntilDepsComplete = v);
visibility.addTristate("hide_until_deps_visible", hideUntilDepsVisible, v -> hideUntilDepsVisible = v);
visibility.addBool("invisible", invisible, v -> invisible = v, false);
visibility.addInt("invisible_until_tasks", invisibleUntilTasks, v -> invisibleUntilTasks = v, 0, 0, Integer.MAX_VALUE).setCanEdit(invisible);
visibility.addTristate("hide_details_until_startable", hideDetailsUntilStartable, v -> hideDetailsUntilStartable = v);
Expand Down Expand Up @@ -750,8 +763,10 @@ public boolean isVisible(TeamData data) {
return true;
}

if (hideUntilDepsVisible.get(chapter.hideQuestUntilDepsVisible())) {
if (hideUntilDepsComplete.get(chapter.hideQuestUntilDepsComplete())) {
return data.areDependenciesComplete(this);
} else if (hideUntilDepsVisible.get(chapter.isHideQuestUntilDepsVisible())) {
return data.areDependenciesVisible(this);
}

return streamDependencies().anyMatch(object -> object.isVisible(data));
Expand Down Expand Up @@ -1051,21 +1066,35 @@ public void removeReward(Reward reward) {
rewards.remove(reward);
}

public boolean areDependenciesComplete(TeamData teamData) {
@FunctionalInterface
private interface DependencyChecker {
default boolean check(QuestObject questObject) {
return !questObject.invalid && check0(questObject);
}
boolean check0(QuestObject questObject);
}

private boolean checkDependencies(DependencyChecker checker) {
if (minRequiredDependencies > 0) {
return streamDependencies()
.filter(dep -> teamData.isCompleted(dep) && !dep.invalid)
.filter(checker::check)
.limit(minRequiredDependencies)
.count() == minRequiredDependencies;
} else if (dependencyRequirement.needOnlyOne()) {
return streamDependencies()
.anyMatch(dep -> !dep.invalid && (dependencyRequirement.needCompletion() ? teamData.isCompleted(dep) : teamData.isStarted(dep)));
return streamDependencies().anyMatch(checker::check);
} else {
return streamDependencies()
.allMatch(dep -> !dep.invalid && (dependencyRequirement.needCompletion() ? teamData.isCompleted(dep) : teamData.isStarted(dep)));
return streamDependencies().allMatch(checker::check);
}
}

public boolean areDependenciesComplete(TeamData teamData) {
return checkDependencies(dep -> dependencyRequirement.needCompletion() ? teamData.isCompleted(dep) : teamData.isStarted(dep));
}

public boolean areDependenciesVisible(TeamData teamData) {
return checkDependencies(dep -> dep.isVisible(teamData));
}

public List<Pair<Integer,Integer>> buildDescriptionIndex() {
List<Pair<Integer,Integer>> index = new ArrayList<>();

Expand Down
43 changes: 23 additions & 20 deletions common/src/main/java/dev/ftb/mods/ftbquests/quest/TeamData.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import org.apache.commons.lang3.function.ToBooleanBiFunction;
import org.jetbrains.annotations.Nullable;

import java.nio.file.Path;
Expand Down Expand Up @@ -59,8 +60,9 @@ public class TeamData {
private final Long2LongOpenHashMap completed;
private final Object2ObjectOpenHashMap<UUID,PerPlayerData> perPlayerData;

private Long2ByteOpenHashMap areDependenciesCompleteCache;
private Object2ByteOpenHashMap<QuestKey> unclaimedRewardsCache;
private final Long2ByteOpenHashMap areDependenciesCompleteCache;
private final Long2ByteOpenHashMap areDependenciesVisibleCache;
private final Object2ByteOpenHashMap<QuestKey> unclaimedRewardsCache;

public TeamData(UUID teamId, BaseQuestFile file) {
this(teamId, file, "");
Expand All @@ -82,6 +84,9 @@ public TeamData(UUID teamId, BaseQuestFile file, String name) {
completed = new Long2LongOpenHashMap();
completed.defaultReturnValue(0L);
perPlayerData = new Object2ObjectOpenHashMap<>();
areDependenciesCompleteCache = new Long2ByteOpenHashMap();
areDependenciesVisibleCache = new Long2ByteOpenHashMap();
unclaimedRewardsCache = new Object2ByteOpenHashMap<>();
}

public UUID getTeamId() {
Expand Down Expand Up @@ -238,14 +243,8 @@ public boolean isRewardClaimed(UUID player, Reward reward) {
}

public boolean hasUnclaimedRewards(UUID player, QuestObject object) {
if (unclaimedRewardsCache == null) {
unclaimedRewardsCache = new Object2ByteOpenHashMap<>();
unclaimedRewardsCache.defaultReturnValue(BOOL_UNKNOWN);
}

QuestKey key = QuestKey.create(player, object.id);
byte b = unclaimedRewardsCache.getByte(key);

byte b = unclaimedRewardsCache.getOrDefault(key, BOOL_UNKNOWN);
if (b == BOOL_UNKNOWN) {
b = object.hasUnclaimedRewardsRaw(this, player) ? BOOL_TRUE : BOOL_FALSE;
unclaimedRewardsCache.put(key, b);
Expand Down Expand Up @@ -301,8 +300,9 @@ public boolean resetReward(UUID player, Reward reward) {
}

public void clearCachedProgress() {
areDependenciesCompleteCache = null;
unclaimedRewardsCache = null;
areDependenciesCompleteCache.clear();
areDependenciesVisibleCache.clear();
unclaimedRewardsCache.clear();
}

public SNBTCompoundTag serializeNBT() {
Expand Down Expand Up @@ -510,25 +510,28 @@ public boolean isCompleted(QuestObject object) {
return completed.containsKey(object.id);
}

public boolean areDependenciesComplete(Quest quest) {
private boolean checkDepsCached(Quest quest, Long2ByteOpenHashMap cache, ToBooleanBiFunction<Quest,TeamData> checker) {
if (!quest.hasDependencies()) {
return true;
}

if (areDependenciesCompleteCache == null) {
areDependenciesCompleteCache = new Long2ByteOpenHashMap();
areDependenciesCompleteCache.defaultReturnValue(BOOL_UNKNOWN);
}

byte res = areDependenciesCompleteCache.get(quest.id);
byte res = cache.getOrDefault(quest.id, BOOL_UNKNOWN);
if (res == BOOL_UNKNOWN) {
res = quest.areDependenciesComplete(this) ? BOOL_TRUE : BOOL_FALSE;
areDependenciesCompleteCache.put(quest.id, res);
res = checker.applyAsBoolean(quest, this) ? BOOL_TRUE : BOOL_FALSE;
cache.put(quest.id, res);
}

return res == BOOL_TRUE;
}

public boolean areDependenciesComplete(Quest quest) {
return checkDepsCached(quest, areDependenciesCompleteCache, Quest::areDependenciesComplete);
}

public boolean areDependenciesVisible(Quest quest) {
return checkDepsCached(quest, areDependenciesVisibleCache, Quest::areDependenciesVisible);
}

public boolean canStartTasks(Quest quest) {
return quest.getProgressionMode() == ProgressionMode.FLEXIBLE || areDependenciesComplete(quest);
}
Expand Down
Loading

0 comments on commit 9718dcf

Please sign in to comment.