Skip to content

Add a History feature to the questbook#156

Open
Aedial wants to merge 3 commits into
CleanroomMC:1.12from
Aedial:1.12
Open

Add a History feature to the questbook#156
Aedial wants to merge 3 commits into
CleanroomMC:1.12from
Aedial:1.12

Conversation

@Aedial

@Aedial Aedial commented May 28, 2026

Copy link
Copy Markdown

The History is a list of quest entries (similar to Search, which it was adapted from), sorted by finish time in descending order. Only finished quests are indexed, and clicking on an entry opens the quest. The intent is allowing people to find/understand what they just unlocked in a big quest book and claim the rewards individually.
As it relies on already present data, all state is transient, re-indexed when the tab is opened. The position in the list (scroll bar) is restored when going back to the history (e.g., via the Back button), but this information only lasts as long as the client session.

The button to access it currently sits just above the search button, which may affect the muscle memory of people used to the edit button being at the same position, but it seemed weird to put it above edit if edit was on.

Aedial added 2 commits May 28, 2026 20:50
Sorted in descending order, from most recent.
Adding time ranges, later, may be a good addition

@WaitingIdly WaitingIdly left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how should repeatable quests be stored? currently, they go to the top of the list as soon as they completed and then are reset to the bottom with - when they reset. this seems suboptimal.

for the most part, bqu tends to combine something like

GuiTransform bgTransform = new GuiTransform(GuiAlign.FULL_BOX, new GuiPadding(0, 0, 0, 0), 0);
CanvasTextured cvBackground = new CanvasTextured(bgTransform, PresetTexture.PANEL_MAIN.getTexture());

into just

CanvasTextured cvBackground = new CanvasTextured(new GuiTransform(GuiAlign.FULL_BOX, new GuiPadding(0, 0, 0, 0), 0), PresetTexture.PANEL_MAIN.getTexture());

should change your code to match.

Comment thread src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasQuestHistory.java Outdated
Comment thread src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasQuestHistory.java Outdated
Comment thread src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasQuestHistory.java Outdated
Comment thread src/main/resources/assets/betterquesting/lang/en_us.lang Outdated
An additional key has been added for completion date
(defaults to timestamp if missing).
The History now has a setting to decide how to show repeatables.

@Aedial Aedial left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the separation of GuiTransform was to make things more readable, but I guess consistency trumps columns count.

The requested changes have been applied. Additionally, I tackled the Repeatable Quests issue by moving from "using the timestamp" to "adding a complete-at key to quests" (defaults to timestamp if missing).
The visibility of repeatable quests now depends on a cycling button (show all, show claimable, hide all) with a hidden, persistent config backing it up.
During the implementation, I also fixed a rendering issue with PresetTexture.BTN_ALT_*, which was producing a dark line (part of the border, I think) in the middle of the button. Looking at the texture, BTN_CLEAN_* suffers from the same issue, but I haven't touched it.

Comment on lines +187 to +190
public enum RepeatableFilter {
HIDE("betterquesting.gui.history.repeatable_filter.hide"),
SHOW_PENDING_REWARDS("betterquesting.gui.history.repeatable_filter.pending_rewards"),
SHOW_ALL("betterquesting.gui.history.repeatable_filter.all");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about expanding this to filter everything - mainly, i would like to filter by "pending rewards" for all quests.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So 2 buttons or drop hiding repeatables altogether?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think i would be fine with either, but would prefer two buttons

private void createRepeatableFilterButton(CanvasEmpty cvInner) {
repeatableFilterButton = new PanelButton(new GuiTransform(GuiAlign.TOP_EDGE, new GuiPadding(0, 16, 8, -32), 0), 1, "");
repeatableFilterButton.setClickAction(button -> cycleRepeatableFilter());
repeatableFilterButton.setTextures(PresetTexture.BTN_ALT_0.getTexture(), PresetTexture.BTN_ALT_1.getTexture(), PresetTexture.BTN_ALT_2.getTexture());

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i dont think i like BTN_ALT_\d here. feels odd.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you have in mind? I started with the same background as the quest entries, but it was awful for visibility, hence the button skin.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shrinking the size and offsetting it by a bit? perhaps converting the button into just an icon and having the mode be a tooltip.

this.addPanel(buttonContainer);

GuiRectangle questButtonRect = new GuiRectangle(2, 2, 28, 28);
PanelButtonQuest questButton = new PanelButtonQuest(questButtonRect, 0, "", entry.getQuest());

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to update this regularly to have the correct color - test a quest that resets, have it be completed when the gui opens and then reset while the gui remains open. color will not change, but should.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I avoided refreshing in real time, as it an be kinda expensive on big quest books. I guess I can updates every X seconds, with X configurable, but the user can just as much close and reopen.

* For quests completed before this was added, it will return the timestamp value (may be inaccurate for repeatable quests).
* For quests not completed, it will return 0.
*/
default long getLastCompletedAt(UUID uuid) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move this to QuestInstance

}

private void ensureLastCompletedAt(NBTTagCompound entry, long fallbackTimestamp) {
if (entry.hasKey(IQuest.LAST_COMPLETED_AT_TAG, Constants.NBT.TAG_LONG)) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checking if its been set already seems to make this a "first completed at" instead of a "last completed at" whenever this gets called. is there something im missing here?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is meant as a fallback if the normal path is not respected, see the comment at line 218. The "completed at" should reflect the completion time, not claiming, but I haven't found any clean way to ensure the key is updated here without also updating "completion time" to "claim time".

import java.util.UUID;

public interface IQuest extends INBTSaveLoad<NBTTagCompound>, INBTProgress<NBTTagCompound>, IPropertyContainer {
String LAST_COMPLETED_AT_TAG = "last_completed_at";

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as much as it would be beneficial to do this, we currently dont, and so shouldnt store the name in a field.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants