Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #759

Merged
merged 25 commits into from
Jan 10, 2025
Merged

Dev #759

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
4e3e715
fix: changelog versions should be level 2 headings! [ciskip]
desht Nov 7, 2024
36b5e9e
Merge remote-tracking branch 'origin/dev' into dev
desht Nov 7, 2024
0f9f4b8
fix: QuestFile#getOrCreateTeamData(Player) safety
desht Nov 8, 2024
655dbaf
build: version -> 2101.1.2, changelog updated
desht Nov 8, 2024
507cd83
fix: allow clickthrough for images when left-clicking & no action con…
desht Nov 11, 2024
8f408ef
fix: don't do Quest#onCompleted work twice
desht Nov 19, 2024
282aa8d
chore: changelog updated
desht Nov 19, 2024
c88c3b0
fix: rework some commands to not use QuestObjectArgument
desht Dec 18, 2024
448565e
chore: only write reward feedback message if not empty
desht Jan 2, 2025
6b078bd
build: bump ftb library dep version
desht Jan 2, 2025
15ab70f
chore: changelog updated [ciskip]
desht Jan 3, 2025
edc82d8
fix: include lang/ translation data in "Save Locally"
desht Jan 6, 2025
1bd1f42
feat: new "All Table" reward type
desht Jan 6, 2025
e5c6dcf
chore: update URL for "open wiki" link
desht Jan 6, 2025
98b385e
feat: add new "none" quest shape and lock icon
desht Jan 7, 2025
55b3403
fix: recipes/loot tables/tag naming for 1.21
desht Jan 8, 2025
9ae01de
fix: rewards in reward tables must have unique IDs
desht Jan 6, 2025
b854cf2
fix: tooltips appearing behind context menus
desht Jan 9, 2025
3f03c67
chore: changelog updated
desht Jan 9, 2025
920eaae
fix: fix to last reward table commit
desht Jan 9, 2025
a8922a9
feat: added "Grab Copy of Item" to item task context menus
desht Jan 10, 2025
f61d7a2
chore: changelog updated
desht Jan 10, 2025
5adb844
chore: tiny changelog fix [ciskip]
desht Jan 10, 2025
774552d
fix: fixes from PR feedback
desht Jan 10, 2025
bc22e96
chore: changelog update [ciskip]
desht Jan 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 39 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,35 @@ 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).

# [2101.1.1]
## [2101.1.2]

### Added
* Added a new "None" quest shape, which simply means to not draw any border around the quest icon
* This doesn't affect the icon itself, which is still rendered as normal
* Locked quests (i.e. which can't be started due to dependencies) now show a small padlock icon
* This can be disabled in player preferences if preferred - "Show Icon for Locked Quests"
* Added a new "All Table" reward type
* This works on an existing reward table, and rewards the player with one of every reward in the table
* Added a new "Grab Copy of Item" context menu entry for item tasks in the quest view panel
* This is intended to allow getting copies of items with custom components (e.g. FTB Filter System filters) if you don't have a copy of the item to hand

### Fixed
* Fixed a rare server-side crash which can occur when new (as in, never on this server before) players join the server
* Timing issue with FTB Teams initialising their team data for the first time
* Fixed quest completion toasts appearing more than once if a quest has multiple optional tasks
* Image objects with no click action can now be clicked-through, allowing the background to be scrolled/panned
* Fixed issue with several ftbquests subcommands meaning they could not be used in MC functions
* Commands are `/ftbquests change_progress`, `/ftbquests open_book`, and `/ftbquests export_reward_table_to_chest`
* Fixed tooltips sometimes rendering underneath context menus
* Fixed rewards in reward tables not being able to have a custom title set
* Technical detail: rewards in reward tables (unlike rewards in quests) have historically not had a unique ID, but this ID is necessary for titles to work with the new translation system which the mod uses.
* Fixed recipes for craftable items (task screens etc.) not working
* Fixed loot tables for task screens not working
* The "Open Wiki" entry in the Settings context menu now opens the new FTB Quests docs at https://go.ftb.team/docs-quests
* The "Download Quest Files" entry in the Settings menu now also saves the `lang/` folder
* Caveat: only translations which the client knows about are included in this download (translations on the server that the client has not used won't be included)

## [2101.1.1]

### Added
* The pinned quests panel now has a "Pinned Quests" title for clarity
Expand All @@ -18,7 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Fixed context menu tooltips sometimes appearing behind the context menu
* Fixed some issues with the reward table editor GUI (changes not getting correctly sync'd to server in some cases)

# [2101.1.0]
## [2101.1.0]

### Changed
* Minecraft 1.21.1 is now required; this no longer supports Minecraft 1.21
Expand All @@ -36,7 +64,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* 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

# [2100.1.5]
## [2100.1.5]

### Changed
* FTB Quests items are now registered to the `FTB Suite` creative tab instead of FTB Quests own tab
Expand All @@ -47,7 +75,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* In addition, rotated images with a non-default aspect ratio now preview correctly during rotation
* Fixed copy/pasting images

# [2100.1.4]
## [2100.1.4]

### Fixed
* Fixed coloured text in quest titles & subtitles not showing in the quest view panel
Expand All @@ -57,21 +85,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Pre-existing chapter files may be named after the hex chapter id; they will still work fine, but you can rename them if you wish
* If you choose to rename them, also update the `filename` field in the file correspondingly

# [2100.1.3]
## [2100.1.3]

### Fixed
* Fixed adding tasks to existing quests sometimes losing the task type (leading to a '?' button appearing)
* Fixed images in the quest book not sync'ing to the client
* Fixed issue where using FTB Filter System filters would sometimes fail to find matching items for GUI display

# [2100.1.2]
## [2100.1.2]

### Fixed
* Fixed raw json text in quest descriptions not always being recognised
* Fixed a packet sync error related to translation system when on dedicated server
* Chapter filenames are now again named after the chapter title (at the time of creation), as they used to be in 1.20 and earlier

# [2100.1.1]
## [2100.1.1]

### Fixed
* Fixed chapter and chapter group creation popups moving in and out with the chapter panel when it's not pinned.
Expand All @@ -82,7 +110,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* 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]
## [2100.1.0]

### Changed
* Ported to Minecraft 1.21. Support for Fabric and NeoForge.
Expand All @@ -94,19 +122,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Text which doesn't have a translation in the current locale (but does in the `en_us` locale) is highlighted when in edit mode.
* Changes do not affect the player experience

# [2004.2.1]
## [2004.2.1]

### Added
* The pinned quests panel positioned can now be adjusted in client config (use "Player Preferences" button in lower right of screen)
* A couple of other minor GUI fixes and improvements (mainly via FTB Library)

# [2004.2.0]
## [2004.2.0]

### Changed
* Ported to Minecraft 1.20.4. Supported on Forge, NeoForge and Fabric.
* Some GUI enhancements in a few places.

# [2001.3.4]
## [2001.3.4]

### Added
* The color of dependency lines for uncompleted quests is now themable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import dev.ftb.mods.ftbquests.events.ClearFileCacheEvent;
import dev.ftb.mods.ftbquests.quest.BaseQuestFile;
import dev.ftb.mods.ftbquests.quest.ServerQuestFile;
import dev.ftb.mods.ftbquests.quest.TeamData;
import dev.ftb.mods.ftbquests.quest.task.DimensionTask;
import dev.ftb.mods.ftbquests.quest.task.KillTask;
import dev.ftb.mods.ftbquests.quest.task.Task;
Expand Down Expand Up @@ -124,13 +123,13 @@ private EventResult playerKill(LivingEntity entity, DamageSource source) {
return EventResult.pass();
}

TeamData data = ServerQuestFile.INSTANCE.getOrCreateTeamData(player);

for (KillTask task : killTasks) {
if (data.getProgress(task) < task.getMaxProgress() && data.canStartTasks(task.getQuest())) {
task.kill(data, entity);
ServerQuestFile.INSTANCE.getTeamData(player).ifPresent(data -> {
for (KillTask task : killTasks) {
if (data.getProgress(task) < task.getMaxProgress() && data.canStartTasks(task.getQuest())) {
task.kill(data, entity);
}
}
}
});
}

return EventResult.pass();
Expand All @@ -139,34 +138,29 @@ private EventResult playerKill(LivingEntity entity, DamageSource source) {
private void playerTick(Player player) {
ServerQuestFile file = ServerQuestFile.INSTANCE;

if (player instanceof ServerPlayer && file != null && !PlayerHooks.isFake(player)) {
if (player instanceof ServerPlayer serverPlayer && file != null && !PlayerHooks.isFake(player)) {
if (autoSubmitTasks == null) {
autoSubmitTasks = file.collect(o -> o instanceof Task && ((Task) o).autoSubmitOnPlayerTick() > 0);
autoSubmitTasks = file.collect(o -> o instanceof Task t && t.autoSubmitOnPlayerTick() > 0);
}

// Don't be deceived, its somehow possible to be null here
// Don't be deceived, it's somehow possible to be null here
if (autoSubmitTasks == null || autoSubmitTasks.isEmpty()) {
return;
}

TeamData data = file.getOrCreateTeamData(player);

if (data.isLocked()) {
return;
}

long t = player.level().getGameTime();
file.getTeamData(player).ifPresent(data -> {
long now = player.level().getGameTime();

file.withPlayerContext((ServerPlayer) player, () -> {
for (Task task : autoSubmitTasks) {
long d = task.autoSubmitOnPlayerTick();

if (d > 0L && t % d == 0L) {
if (!data.isCompleted(task) && data.canStartTasks(task.getQuest())) {
task.submitTask(data, (ServerPlayer) player);
file.withPlayerContext(serverPlayer, () -> {
for (Task task : autoSubmitTasks) {
long interval = task.autoSubmitOnPlayerTick();
if (interval > 0L && now % interval == 0L) {
if (!data.isCompleted(task) && data.canStartTasks(task.getQuest())) {
task.submitTask(data, serverPlayer);
}
}
}
}
});
});
}
}
Expand Down Expand Up @@ -206,17 +200,15 @@ private void cloned(ServerPlayer oldPlayer, ServerPlayer newPlayer, boolean wonG
private void changedDimension(ServerPlayer player, ResourceKey<Level> oldLevel, ResourceKey<Level> newLevel) {
if (!PlayerHooks.isFake(player)) {
ServerQuestFile file = ServerQuestFile.INSTANCE;
TeamData data = file.getOrCreateTeamData(player);

if (data.isLocked()) {
return;
}

file.withPlayerContext(player, () -> {
for (DimensionTask task : file.collect(DimensionTask.class)) {
if (data.canStartTasks(task.getQuest())) {
task.submitTask(data, player);
}
file.getTeamData(player).ifPresent(data -> {
if (!data.isLocked()) {
file.withPlayerContext(player, () -> {
for (DimensionTask task : file.collect(DimensionTask.class)) {
if (data.canStartTasks(task.getQuest())) {
task.submitTask(data, player);
}
}
});
}
});
}
Expand Down
39 changes: 39 additions & 0 deletions common/src/main/java/dev/ftb/mods/ftbquests/api/QuestFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,64 @@
import dev.ftb.mods.ftbquests.quest.TeamData;
import dev.ftb.mods.ftbteams.api.Team;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.Optional;
import java.util.UUID;
import java.util.function.Consumer;

public interface QuestFile {
/**
* {@return true if this quest file is on the server, false if on the client}
*/
boolean isServerSide();

/**
* Check if this quest file is editable. This will always return false on the server;
* use {@link TeamData#getCanEdit(Player)} there.
* @return true if the file can be edited (clientside), false otherwise
*/
boolean canEdit();

/**
* {@return FTB Quests progress data for the given FTB Teams team UUID, or null if there is no data for this team ID}
* @param id the team ID to check
*/
@Nullable TeamData getNullableTeamData(UUID id);

/**
* {@return FTB Quests progress data for the given FTB Teams team UUID, creating new progress data if necessary}
* @param teamId the team ID to check
*/
TeamData getOrCreateTeamData(UUID teamId);

/**
* {@return FTB Quests progress data for the given FTB Teams team, creating new progress data if necessary}
* @param team the team to check
*/
TeamData getOrCreateTeamData(Team team);

/**
* {@return quest team data for the player, creating new progress data if necessary}
* @param player the player
* @deprecated not recommended since it can return null if player's team data isn't ready. Use {@link #getTeamData(Player)}.
*/
@Nullable
@Deprecated(forRemoval = true)
TeamData getOrCreateTeamData(Entity player);

/**
* Get the FTB Quests team progress data for the given player, creating new progress data if necessary.
* @param player the player to check
* @return the team data, or {@code Optional.empty()} if the player isn't yet known by FTB Teams (rare, but possible, particularly for players joining the server for the first time)
*/
Optional<TeamData> getTeamData(Player player);

/**
* {@return collection of progress data for all known teams}
*/
Collection<TeamData> getAllTeamData();

void forAllChapters(Consumer<Chapter> consumer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public void setPlacedBy(Level level, BlockPos blockPos, BlockState blockState, @

if (level.getBlockEntity(blockPos) instanceof TaskScreenBlockEntity coreScreen) {
if (livingEntity instanceof ServerPlayer sp) {
coreScreen.setTeamId(ServerQuestFile.INSTANCE.getOrCreateTeamData(sp).getTeamId());
ServerQuestFile.INSTANCE.getTeamData(sp).ifPresent(d -> coreScreen.setTeamId(d.getTeamId()));
}

Direction facing = blockState.getValue(FACING);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import dev.architectury.hooks.level.entity.PlayerHooks;
import dev.ftb.mods.ftbquests.quest.QuestObjectBase;
import dev.ftb.mods.ftbquests.quest.ServerQuestFile;
import dev.ftb.mods.ftbquests.quest.TeamData;
import dev.ftb.mods.ftbquests.registry.ModBlockEntityTypes;
import dev.ftb.mods.ftbquests.util.ProgressChange;
import net.minecraft.core.BlockPos;
Expand Down Expand Up @@ -50,8 +49,8 @@ public void onPowered(Level level, BlockPos pos) {
if (qo != null) {
AABB box = new AABB(pos).inflate(radius);
for (ServerPlayer player : level.getEntitiesOfClass(ServerPlayer.class, box, DetectorBlockEntity::isRealPlayer)) {
TeamData data = ServerQuestFile.INSTANCE.getOrCreateTeamData(player);
qo.forceProgressRaw(data, new ProgressChange(qo, player.getUUID()).setReset(false).withNotifications());
ServerQuestFile.INSTANCE.getTeamData(player).ifPresent(data ->
qo.forceProgressRaw(data, new ProgressChange(qo, player.getUUID()).setReset(false).withNotifications()));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ public void update(String s) {
public boolean isOpen(Player player) {
BaseQuestFile file = FTBQuestsAPI.api().getQuestFile(player.level().isClientSide());
QuestObject qo = file.get(objId);
return qo != null && file.getOrCreateTeamData(player).isCompleted(qo);
return qo != null && file.getTeamData(player)
.map(d -> d.isCompleted(qo))
.orElse(false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public interface FTBQuestsClientConfig {
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);
BooleanValue SHOW_LOCK_ICON = UI.addBoolean("show_lock_icon", true);

SNBTConfig XLATE = CONFIG.addGroup("xlate", 1);
StringValue EDITING_LOCALE = XLATE.add(new LocaleValue(XLATE,"editing_locale", ""));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public static RewardType.GuiProvider defaultRewardGuiProvider(RewardType.Provide
}
gui.run();
});
group.setNameKey(reward.getType().getTypeId().toLanguageKey("ftbquests.reward"));
reward.fillConfigGroup(reward.createSubGroup(group));
new EditConfigScreen(group).openGui();
}
Expand Down Expand Up @@ -160,6 +161,7 @@ private static void openSetupGui(Runnable gui, BiConsumer<Task, CompoundTag> cal
callback.accept(task, task.getType().makeExtraNBT());
}
});
group.setNameKey(task.getType().getTypeId().toLanguageKey("ftbquests.task"));
task.fillConfigGroup(task.createSubGroup(group));

new EditConfigScreen(group).openGui();
Expand Down Expand Up @@ -206,5 +208,17 @@ public static void setRewardGuiProviders() {
}, RewardTypes.XP_LEVELS.getDisplayName()).atMousePosition();
panel.getGui().pushModalPanel(overlay);
});

RewardTypes.STAGE.setGuiProvider((panel, quest, callback) -> {
StringConfig c = new StringConfig();

EditStringConfigOverlay<String> overlay = new EditStringConfigOverlay<>(panel.getGui(), c, accepted -> {
if (accepted) {
callback.accept(new StageReward(0L, quest, c.getValue()));
}
panel.run();
}, RewardTypes.STAGE.getDisplayName()).atMousePosition();
panel.getGui().pushModalPanel(overlay);
});
}
}
Loading