Skip to content

Commit

Permalink
Release 0.3.4
Browse files Browse the repository at this point in the history
- [feat] Hide/show unlocked only items
- [feat] Right click items to quick track
- [chore] Updated text colors on learned recipes screen
- [chore] Added hunting profession and updated parsing to handling future updates better
  • Loading branch information
blackjack26 committed Sep 4, 2024
1 parent 4a6530f commit 3386508
Show file tree
Hide file tree
Showing 17 changed files with 337 additions and 144 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ cloth_config_version=12.0.119
mod_menu_version=8.0.1

# Project Metadata
mod_version=0.3.3
mod_version=0.3.4
mod_name=Blockgame Journal
default_release_type=release
github_owner=blackjack26
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,6 @@ private ActionResult handleChatMessage(MinecraftClient client, String message) {

if (cleanedMessage.startsWith("[RECIPE]") && lastRecipeName != null) {
Journal.INSTANCE.getMetadata().setKnownRecipe("mmoitems:" + lastRecipeName, true);
LOGGER.info("[Blockgame Journal] Learned recipe: mmoitems:{}", lastRecipeName);
}

return ActionResult.PASS;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import dev.bnjc.blockgamejournal.util.NbtUtil;
import dev.bnjc.blockgamejournal.util.Profession;
import dev.bnjc.blockgamejournal.util.StringUtil;
import lombok.Getter;
import lombok.Setter;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtList;
import net.minecraft.network.packet.s2c.play.InventoryS2CPacket;
Expand All @@ -26,6 +24,7 @@
public class ProfileHandler {
private static final Logger LOGGER = BlockgameJournal.getLogger("Profile Handler");
private static final Pattern LEVEL_PATTERN = Pattern.compile("^Level: (\\d+)");
private static final Pattern IGNORED_PATTERN = Pattern.compile("^(Offense|Defense|Professions|Talents)$");

private final RecipeTrackerGameFeature gameFeature;
private int syncId = -1;
Expand Down Expand Up @@ -55,58 +54,66 @@ private ActionResult handleScreenInventory(InventoryS2CPacket packet) {
return ActionResult.PASS;
}

List<ItemStack> inv = packet.getContents();
parseProfessionLevel(inv, Profession.MINING);
parseProfessionLevel(inv, Profession.LOGGING);
parseProfessionLevel(inv, Profession.ARCHAEOLOGY);
parseProfessionLevel(inv, Profession.EINHERJAR);
parseProfessionLevel(inv, Profession.FISHING);
parseProfessionLevel(inv, Profession.HERBALISM);
parseProfessionLevel(inv, Profession.RUNECARVING);
parseProfessionLevel(inv, Profession.COOKING);
parseProfessionLevel(inv, Profession.ALCHEMY);

parseProfessions(packet.getContents());
return ActionResult.PASS;
}

private void parseProfessionLevel(List<ItemStack> inv, Profession profession) {
int slot = profession.getSlot();
ItemStack stack = inv.get(slot);
if (stack.isEmpty()) {
LOGGER.warn("[Blockgame Journal] Empty slot: {}", slot);
this.setProfessionLevel(profession, null);
return;
}
private void parseProfessions(List<ItemStack> inv) {
// Only look at items in 6x9 menu
for (int i = 0; i < Math.min(inv.size(), 54); i++) {
ItemStack itemStack = inv.get(i);
if (itemStack == null || itemStack.isEmpty()) {
continue;
}

NbtList lore = NbtUtil.getLore(stack);
if (lore == null) {
LOGGER.warn("[Blockgame Journal] No lore found in slot: {}", slot);
this.setProfessionLevel(profession, null);
return;
}
String name = itemStack.getName().getString();
if (IGNORED_PATTERN.matcher(name).find()) {
continue;
}

Profession profession = Profession.from(name);
String profName = "";
if (profession == null) {
LOGGER.warn("[Blockgame Journal] Unknown profession: {}", name);
profName = name;
} else {
profName = profession.getName();
}

for (int i = 0; i < lore.size(); i++) {
MutableText textLine = NbtUtil.parseLoreLine(lore.getString(i));
if (textLine == null) {
NbtList lore = NbtUtil.getLore(itemStack);
if (lore == null) {
LOGGER.warn("[Blockgame Journal] No lore found for profession: {}", profName);
this.setProfessionLevel(profName, null);
continue;
}

Matcher levelMatcher = LEVEL_PATTERN.matcher(StringUtil.removeFormatting(textLine.getString()));
if (levelMatcher.find()) {
this.setProfessionLevel(profession, Integer.parseInt(levelMatcher.group(1)));
return;
Integer foundLevel = null;
for (int t = 0; t < lore.size(); t++) {
MutableText textLine = NbtUtil.parseLoreLine(lore.getString(t));
if (textLine == null) {
continue;
}

Matcher levelMatcher = LEVEL_PATTERN.matcher(StringUtil.removeFormatting(textLine.getString()));
if (levelMatcher.find()) {
foundLevel = Integer.parseInt(levelMatcher.group(1));
break;
}
}
}

LOGGER.warn("[Blockgame Journal] No level found in lore");
this.setProfessionLevel(profession, null);
if (foundLevel == null) {
LOGGER.warn("[Blockgame Journal] No level found for profession: {}", profName);
}

this.setProfessionLevel(profName, foundLevel);
}
}

private void setProfessionLevel(Profession profession, @Nullable Integer level) {
private void setProfessionLevel(String name, @Nullable Integer level) {
if (Journal.INSTANCE == null) {
return;
}

Journal.INSTANCE.getMetadata().setProfessionLevel(profession.getName(), level);
Journal.INSTANCE.getMetadata().setProfessionLevel(name, level);
}
}
127 changes: 103 additions & 24 deletions src/main/java/dev/bnjc/blockgamejournal/gui/screen/JournalScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,13 @@
import net.minecraft.client.gui.widget.TexturedButtonWidget;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.nbt.NbtList;
import net.minecraft.nbt.NbtString;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
Expand All @@ -37,6 +43,8 @@ public class JournalScreen extends Screen {
private static final Identifier BACKGROUND_SPRITE = GuiUtil.sprite("background");

private static final int BUTTON_SIZE = 14;
private static final int BUTTON_SPACING = 2;

private static final int GRID_COLUMNS = 9;
private static final int GRID_ROWS = 6;
private static final int GRID_LEFT = 7;
Expand Down Expand Up @@ -87,6 +95,9 @@ public class JournalScreen extends Screen {
private ButtonWidget vendorSortButton;
private ButtonWidget inventoryToggleOnButton;
private ButtonWidget inventoryToggleOffButton;
@Nullable
private UnlockedButtonWidget unlockedToggleButton;

private NPCWidget npcWidget;

private List<JournalItemStack> items = Collections.emptyList();
Expand Down Expand Up @@ -179,9 +190,9 @@ protected void init() {

// Add warning if no journal
if (Journal.INSTANCE == null) {
this.search.setEditable(false);
this.search.setText(I18n.translate("blockgamejournal.recipe_journal.no_journal"));
this.search.setUneditableColor(0xFF4040);
this.search.setEditable(false);
this.search.setText(I18n.translate("blockgamejournal.recipe_journal.no_journal"));
this.search.setUneditableColor(0xFF4040);
}

// Close button
Expand Down Expand Up @@ -261,6 +272,17 @@ protected void init() {
this.inventoryToggleOffButton.visible = (this.currentMode == JournalMode.Type.ITEM_SEARCH || this.currentMode == JournalMode.Type.FAVORITES) && JournalScreen.useInventory;
this.addDrawableChild(this.inventoryToggleOffButton);

// Unlocked Toggle Button
this.unlockedToggleButton = new UnlockedButtonWidget(
this.left + MENU_WIDTH - 3 * (3 + BUTTON_SIZE),
this.top + 5,
button -> {
this.refreshItems();
}
);
this.refreshUnlockToggleButton();
this.addDrawableChild(this.unlockedToggleButton);

// Vendor sort button
this.vendorSortButton = new TexturedButtonWidget(
this.left + MENU_WIDTH - 2 * (3 + BUTTON_SIZE),
Expand Down Expand Up @@ -316,6 +338,7 @@ protected void init() {
this.setSelectedIngredient(null);

this.itemSortButton.visible = this.currentMode == JournalMode.Type.ITEM_SEARCH || this.currentMode == JournalMode.Type.FAVORITES;
this.refreshUnlockToggleButton();
this.inventoryToggleOnButton.visible = this.itemSortButton.visible && !JournalScreen.useInventory;
this.inventoryToggleOffButton.visible = this.itemSortButton.visible && JournalScreen.useInventory;
}
Expand Down Expand Up @@ -352,7 +375,7 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) {
titleText,
this.left + TITLE_LEFT,
this.top + TITLE_TOP,
MENU_WIDTH - (TITLE_LEFT * 2) - BUTTON_SIZE - 2,
MENU_WIDTH - (TITLE_LEFT * 2) - (2 * (BUTTON_SIZE - 2)),
0x404040
);
}
Expand Down Expand Up @@ -387,6 +410,7 @@ public void setSelectedNpc(String npc) {
this.updateItems(null);
this.closeButton.visible = npc != null;
this.vendorSortButton.visible = npc != null;
this.refreshUnlockToggleButton();
}

public void setSelectedIngredient(ItemStack ingredient) {
Expand All @@ -397,6 +421,7 @@ public void setSelectedIngredient(ItemStack ingredient) {

this.updateItems(null);
this.closeButton.visible = ingredient != null;
this.refreshUnlockToggleButton();
}

@Override
Expand Down Expand Up @@ -446,25 +471,21 @@ private void updateItems(String filter) {

if (this.currentMode == JournalMode.Type.ITEM_SEARCH) {
this.showAllItems();
}
else if (this.currentMode == JournalMode.Type.NPC_SEARCH) {
} else if (this.currentMode == JournalMode.Type.NPC_SEARCH) {
if (JournalScreen.selectedNpc == null) {
this.showVendors();
} else {
this.showVendorItems();
}
}
else if (this.currentMode == JournalMode.Type.FAVORITES) {
} else if (this.currentMode == JournalMode.Type.FAVORITES) {
this.showFavorites();
}
else if (this.currentMode == JournalMode.Type.INGREDIENT_SEARCH) {
} else if (this.currentMode == JournalMode.Type.INGREDIENT_SEARCH) {
if (JournalScreen.selectedIngredient == null) {
this.showIngredients();
} else {
this.showIngredientItems();
}
}
else {
} else {
this.items = Collections.emptyList();
}
filter(filter);
Expand All @@ -475,10 +496,10 @@ private void showFavorites() {

this.items = Journal.INSTANCE.getEntries().entrySet()
.stream()
.filter(entry -> entry.getValue().stream().anyMatch(e -> e.isFavorite() && this.inInventory(e)))
.filter(entry -> entry.getValue().stream().anyMatch(e -> e.isFavorite() && this.applyButtonFilters(e)))
.map(entry -> JournalItemStack.fromKnownItem(entry.getKey()))
.filter(Objects::nonNull)

.peek(this::adjustLoreNbt)
.sorted((a, b) -> {
if (JournalScreen.itemSort == ItemListWidget.ItemSort.A_TO_Z) {
return a.getStack().getName().getString().compareToIgnoreCase(b.getStack().getName().getString());
Expand All @@ -495,9 +516,10 @@ private void showAllItems() {

this.items = Journal.INSTANCE.getEntries().entrySet()
.stream()
.filter(entry -> entry.getValue().stream().anyMatch(this::inInventory))
.filter(entry -> entry.getValue().stream().anyMatch(this::applyButtonFilters))
.map(entry -> JournalItemStack.fromKnownItem(entry.getKey()))
.filter(Objects::nonNull)
.peek(this::adjustLoreNbt)
.sorted((a, b) -> {
if (JournalScreen.itemSort == ItemListWidget.ItemSort.A_TO_Z) {
return a.getStack().getName().getString().compareToIgnoreCase(b.getStack().getName().getString());
Expand Down Expand Up @@ -535,6 +557,7 @@ private void showVendorItems() {
if (JournalScreen.vendorItemSort == ItemListWidget.VendorSort.A_TO_Z) {
JournalItemStack stack = JournalItemStack.fromKnownItem(entry.getKey());
if (stack != null) {
this.adjustLoreNbt(stack);
return List.of(stack);
}

Expand All @@ -543,7 +566,14 @@ private void showVendorItems() {

return entry.getValue().stream()
.filter(this::isNpcNameMatching)
.filter(e -> {
if (UnlockedButtonWidget.isToggled()) {
return !e.isLocked();
}
return true;
})
.map((e) -> new JournalItemStack(e.getItem(), e.getSlot()))
.peek(this::adjustLoreNbt)
.toList();
})
.flatMap(List::stream)
Expand Down Expand Up @@ -580,7 +610,14 @@ private void showIngredientItems() {
.filter(journalEntries -> journalEntries.stream().anyMatch(this::hasIngredient))
.map(journalEntries -> journalEntries.stream()
.filter(this::hasIngredient)
.filter(e -> {
if (UnlockedButtonWidget.isToggled()) {
return !e.isLocked();
}
return true;
})
.map((e) -> new JournalItemStack(e.getItem(), e.getSlot()))
.peek(this::adjustLoreNbt)
.toList()
)
.flatMap(List::stream)
Expand Down Expand Up @@ -618,19 +655,61 @@ private boolean hasIngredient(JournalEntry entry) {
return entry.getIngredients().containsKey(ItemUtil.getKey(selectedIngredient));
}

private boolean inInventory(JournalEntry entry) {
private boolean applyButtonFilters(JournalEntry entry) {
if (UnlockedButtonWidget.isToggled() && entry.isLocked()) {
return false;
}

if (JournalScreen.useInventory) {
// If no ingredients, then it's not in inventory
if (entry.getIngredients().isEmpty()) {
return false;
}

boolean hasEnough = true;
for (ItemStack item : entry.getIngredientItems()) {
hasEnough &= this.inventory.neededCount(item) <= 0;
}
return hasEnough;
}

// If not filtering by inventory, then always return true
if (!JournalScreen.useInventory) return true;
return true;
}

// If no ingredients, then it's not in inventory
if (entry.getIngredients().isEmpty()) {
return false;
private void refreshUnlockToggleButton() {
if (this.unlockedToggleButton == null) {
return;
}

if (this.currentMode == JournalMode.Type.ITEM_SEARCH || this.currentMode == JournalMode.Type.FAVORITES) {
this.unlockedToggleButton.visible = true;
this.unlockedToggleButton.setX(this.left + MENU_WIDTH - 3 * (3 + BUTTON_SIZE));
} else if (this.currentMode == JournalMode.Type.NPC_SEARCH && JournalScreen.selectedNpc != null) {
this.unlockedToggleButton.visible = true;
this.unlockedToggleButton.setX(this.left + MENU_WIDTH - 3 * (3 + BUTTON_SIZE));
} else if (this.currentMode == JournalMode.Type.INGREDIENT_SEARCH && JournalScreen.selectedIngredient != null) {
this.unlockedToggleButton.visible = true;
this.unlockedToggleButton.setX(this.left + MENU_WIDTH - 2 * (3 + BUTTON_SIZE));
} else {
this.unlockedToggleButton.visible = false;
}
}

private void adjustLoreNbt(JournalItemStack jis) {
NbtCompound display = jis.getStack().getSubNbt(ItemStack.DISPLAY_KEY);
if (display != null) {
NbtList loreNbt = display.getList(ItemStack.LORE_KEY, NbtElement.STRING_TYPE);

loreNbt.add(NbtString.of(Text.Serializer.toJson(Text.literal(""))));

MutableText locateText = Text.literal(" ⚐ ").formatted(Formatting.GRAY)
.append(Text.literal("Right-click").formatted(Formatting.GREEN))
.append(Text.literal(" to toggle tracking").formatted(Formatting.GRAY));
locateText.setStyle(locateText.getStyle().withItalic(false));
loreNbt.add(NbtString.of(Text.Serializer.toJson(locateText)));

boolean hasEnough = true;
for (ItemStack item : entry.getIngredientItems()) {
hasEnough &= this.inventory.neededCount(item) <= 0;
jis.getStack().getOrCreateSubNbt(ItemStack.DISPLAY_KEY).put(ItemStack.LORE_KEY, loreNbt);
}
return hasEnough;
}
}
Loading

0 comments on commit 3386508

Please sign in to comment.