Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.evandev.fieldguide.client.data;

import net.minecraft.resources.ResourceLocation;

public class CategoryVisual {
public static final CategoryVisual DEFAULT = new CategoryVisual();

public String color = "#FFFFFF";
public ResourceLocation icon = new ResourceLocation("minecraft:book");

public int getColorInt() {
try {
String hex = color.startsWith("#") ? color.substring(1) : color;
return Integer.parseInt(hex, 16);
} catch (Exception e) {
return 0xFFFFFF;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.evandev.fieldguide.client.data;

public class EntryVisual {
// Global defaults
public float scale = 1.0f;
public float yOffset = 0.0f;
public float xOffset = 0.0f;

// Grid Overrides
public Float gridScale = null;
public Float gridYOffset = null;
public Float gridXOffset = null;

// Page Overrides
public Float pageScale = null;
public Float pageYOffset = null;
public Float pageXOffset = null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,12 @@ public void render(@NotNull GuiGraphics guiGraphics, int mouseX, int mouseY, flo

if (entry instanceof EntityType && renderedEntity instanceof LivingEntity living) {
if (unlocked) {
EntryRenderHelper.renderEntityNormalized(guiGraphics, living, xPos, yPos, 100, 100, 80, false);
EntryRenderHelper.renderEntityNormalized(guiGraphics, living, xPos, yPos, 100, 100, 80, false, 0, true);
} else {
EntryRenderHelper.renderEntityNormalized(guiGraphics, living, xPos, yPos, 100, 100, 80, true, Constants.DETAILS_SILHOUETTE_COLOR);
EntryRenderHelper.renderEntityNormalized(guiGraphics, living, xPos, yPos, 100, 100, 80, true, Constants.DETAILS_SILHOUETTE_COLOR, true);
}
} else if (entry instanceof Block block) {
EntryRenderHelper.renderBlock(guiGraphics, block, xPos, yPos, 30.0F, !unlocked);
EntryRenderHelper.renderBlock(guiGraphics, block, xPos, yPos, 30.0F, !unlocked, true);
}

// Description
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ public FieldGuideScreen(Category initialCategory, String searchQuery) {
}

public static int getPageForEntry(Category category, Object entry) {
int index = category.getEntries().indexOf(entry);
List<Object> entries = FieldGuideDataManager.getInstance().getEntriesForCategory(category);
int index = entries.indexOf(entry);
if (index < 0) return 0;
if (index < ITEMS_PER_PAGE) return 0;
return 1 + (index - ITEMS_PER_PAGE) / ITEMS_PER_VIEW;
Expand All @@ -97,8 +98,13 @@ protected void init() {
super.init();

this.sortedCategories.clear();
this.sortedCategories.addAll(FieldGuideDataManager.getCategories().values());
this.sortedCategories.sort(Comparator.comparingInt(Category::getTabIndex)
for (Category cat : FieldGuideDataManager.getCategories().values()) {
List<Object> entries = FieldGuideDataManager.getInstance().getEntriesForCategory(cat);
if (entries != null && !entries.isEmpty()) {
this.sortedCategories.add(cat);
}
}
this.sortedCategories.sort(Comparator.comparingInt(Category::getSortIndex)
.thenComparing(c -> c.getId().getPath()));

if (this.selectedCategory == null) {
Expand All @@ -112,7 +118,7 @@ protected void init() {
}

if (this.selectedCategory != null) {
this.currentEntries = this.selectedCategory.getEntries();
this.currentEntries = FieldGuideDataManager.getInstance().getEntriesForCategory(this.selectedCategory);
lastOpenedCategory = this.selectedCategory.getId();

int totalSpreads = getTotalSpreads();
Expand Down Expand Up @@ -158,7 +164,7 @@ private void onSearchChanged(String query) {

if (!isSearching) {
if (this.selectedCategory != null) {
this.currentEntries = this.selectedCategory.getEntries();
this.currentEntries = FieldGuideDataManager.getInstance().getEntriesForCategory(this.selectedCategory);
}
} else {
this.currentPage = 0;
Expand Down Expand Up @@ -197,7 +203,7 @@ public void selectCategory(Category category) {
if (this.selectedCategory == category) return;
this.selectedCategory = category;
this.currentPage = 0;
this.currentEntries = category.getEntries();
this.currentEntries = FieldGuideDataManager.getInstance().getEntriesForCategory(category);
lastOpenedCategory = this.selectedCategory.getId();
lastOpenedPage = this.currentPage;

Expand Down Expand Up @@ -245,23 +251,16 @@ private void nextPage() {

@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (this.searchBox != null) {
this.searchBox.setFocused(this.searchBox.isMouseOver(mouseX, mouseY));
}

if (super.mouseClicked(mouseX, mouseY, button)) {
return true;
}
if (this.searchBox != null) this.searchBox.setFocused(this.searchBox.isMouseOver(mouseX, mouseY));
if (super.mouseClicked(mouseX, mouseY, button)) return true;

for (int i = 0; i < ITEMS_PER_VIEW; i++) {
int globalSlotIndex = currentPage * ITEMS_PER_VIEW + i;
if (getGridCellBounds(globalSlotIndex).contains((int) mouseX, (int) mouseY)) {
int itemIndex = getItemIndexForSlot(i);
if (itemIndex >= 0 && itemIndex < currentEntries.size()) {
Object entry = currentEntries.get(itemIndex);
if (FieldGuideDataManager.isNew(entry)) {
FieldGuideDataManager.markAsSeen(entry);
}
if (FieldGuideDataManager.isNew(entry)) FieldGuideDataManager.markAsSeen(entry);
Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
Minecraft.getInstance().setScreen(new FieldGuideEntryScreen(this, entry));
return true;
Expand All @@ -274,27 +273,18 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) {
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
if (this.searchBox.isFocused()) {
if (keyCode == GLFW.GLFW_KEY_ESCAPE) {
return super.keyPressed(keyCode, scanCode, modifiers);
}

if (this.searchBox.keyPressed(keyCode, scanCode, modifiers)) {
return true;
}

if (keyCode == GLFW.GLFW_KEY_ESCAPE) return super.keyPressed(keyCode, scanCode, modifiers);
if (this.searchBox.keyPressed(keyCode, scanCode, modifiers)) return true;
return true;
}

return super.keyPressed(keyCode, scanCode, modifiers);
}

@Override
public void render(@NotNull GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
this.renderBackground(guiGraphics);

RenderSystem.setShaderTexture(0, Constants.BOOK_TEXTURE);
guiGraphics.blit(Constants.BOOK_TEXTURE, this.bounds.left(), this.bounds.top(), 0, 0, this.bounds.width(), this.bounds.height(), this.bounds.width(), this.bounds.height());

super.render(guiGraphics, mouseX, mouseY, partialTick);

if (!isSearching && selectedCategory != null && currentPage == 0) {
Expand All @@ -303,9 +293,7 @@ public void render(@NotNull GuiGraphics guiGraphics, int mouseX, int mouseY, flo
renderSearchTab(guiGraphics);
if (currentEntries.isEmpty()) {
Component noResults = Component.translatable("gui.fieldguide.no_results");
int textX = this.leftPageBounds.x_center() - this.font.width(noResults) / 2;
int textY = this.leftPageBounds.y_center();
guiGraphics.drawString(this.font, noResults, textX, textY, Constants.TEXT_MUTED_COLOR, false);
guiGraphics.drawString(this.font, noResults, this.leftPageBounds.x_center() - this.font.width(noResults) / 2, this.leftPageBounds.y_center(), Constants.TEXT_MUTED_COLOR, false);
}
}

Expand Down Expand Up @@ -367,9 +355,7 @@ private void renderCategoryInfo(GuiGraphics guiGraphics) {
}

private int getItemIndexForSlot(int slotIndex) {
if (isSearching) {
return (currentPage * ITEMS_PER_VIEW) + slotIndex;
}
if (isSearching) return (currentPage * ITEMS_PER_VIEW) + slotIndex;
if (currentPage == 0) {
if (slotIndex < ITEMS_PER_PAGE) return -1;
return slotIndex - ITEMS_PER_PAGE;
Expand Down Expand Up @@ -482,11 +468,11 @@ private void renderEntryInGrid(GuiGraphics guiGraphics, Object entry, int x, int
}

if (entity instanceof LivingEntity living) {
EntryRenderHelper.renderEntityNormalized(guiGraphics, living, x, y, CELL_SIZE - 8, CELL_SIZE - 8, scale, !unlocked);
EntryRenderHelper.renderEntityNormalized(guiGraphics, living, x, y, CELL_SIZE - 8, CELL_SIZE - 8, scale, !unlocked, Constants.LIST_SILHOUETTE_COLOR, false);
}
}
} else if (entry instanceof Block block) {
EntryRenderHelper.renderBlock(guiGraphics, block, x, y, 15.0F, !unlocked);
EntryRenderHelper.renderBlock(guiGraphics, block, x, y, 15.0F, !unlocked, false);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.evandev.fieldguide.client.gui.util;

import com.evandev.fieldguide.Constants;
import com.evandev.fieldguide.client.data.EntryVisual;
import com.evandev.fieldguide.data.FieldGuideDataManager;
import com.mojang.blaze3d.platform.Lighting;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
Expand Down Expand Up @@ -32,15 +34,17 @@

public class EntryRenderHelper {

private static final Map<Object, Optional<ResourceLocation>> OVERRIDE_CACHE = new HashMap<>();
private static final Map<String, Optional<ResourceLocation>> OVERRIDE_CACHE = new HashMap<>();

public static void clearCache() {
OVERRIDE_CACHE.clear();
}

private static Optional<ResourceLocation> getOverride(Object entry) {
if (OVERRIDE_CACHE.containsKey(entry)) {
return OVERRIDE_CACHE.get(entry);
private static Optional<ResourceLocation> getOverride(Object entry, boolean isPage) {
String key = entry.toString() + (isPage ? "_page" : "_grid");

if (OVERRIDE_CACHE.containsKey(key)) {
return OVERRIDE_CACHE.get(key);
}

ResourceLocation id = null;
Expand All @@ -51,19 +55,30 @@ private static Optional<ResourceLocation> getOverride(Object entry) {
}

if (id != null) {
ResourceLocation texture = new ResourceLocation(id.getNamespace(), "textures/fieldguide/entries/" + id.getPath() + ".png");
if (Minecraft.getInstance().getResourceManager().getResource(texture).isPresent()) {
OVERRIDE_CACHE.put(entry, Optional.of(texture));
return Optional.of(texture);
// Define paths to check
ResourceLocation specificLoc = new ResourceLocation(id.getNamespace(),
"textures/fieldguide/entries/" + id.getPath() + (isPage ? "_page.png" : "_grid.png"));

ResourceLocation defaultLoc = new ResourceLocation(id.getNamespace(),
"textures/fieldguide/entries/" + id.getPath() + ".png");

// Check specific first (e.g., pig_page.png), then default (pig.png)
if (Minecraft.getInstance().getResourceManager().getResource(specificLoc).isPresent()) {
OVERRIDE_CACHE.put(key, Optional.of(specificLoc));
return Optional.of(specificLoc);
} else if (Minecraft.getInstance().getResourceManager().getResource(defaultLoc).isPresent()) {
OVERRIDE_CACHE.put(key, Optional.of(defaultLoc));
return Optional.of(defaultLoc);
}
}

OVERRIDE_CACHE.put(entry, Optional.empty());
OVERRIDE_CACHE.put(key, Optional.empty());
return Optional.empty();
}

private static boolean tryRenderOverride(GuiGraphics guiGraphics, Object entry, int x, int y, int width, int height, boolean silhouette, int color) {
Optional<ResourceLocation> override = getOverride(entry);
private static boolean tryRenderOverride(GuiGraphics guiGraphics, Object entry, int x, int y, int width, int height, boolean silhouette, int color, boolean isPage) {
Optional<ResourceLocation> override = getOverride(entry, isPage);

if (override.isPresent()) {
ResourceLocation texture = override.get();
int drawX = x - width / 2;
Expand Down Expand Up @@ -163,32 +178,40 @@ private static float getScaleFactorForEntity(LivingEntity entity) {
}
}

/**
* Renders an entity normalized to fit within a standard widget box.
* Defaults to the standard sepia silhouette color.
*/
public static void renderEntityNormalized(GuiGraphics guiGraphics, LivingEntity entity, int x, int y, int maxWidth, int maxHeight, float baseScale, boolean silhouette) {
renderEntityNormalized(guiGraphics, entity, x, y, maxWidth, maxHeight, baseScale, silhouette, Constants.LIST_SILHOUETTE_COLOR);
}

/**
* Renders an entity normalized to fit within a standard widget box with a specific silhouette color.
*/
public static void renderEntityNormalized(GuiGraphics guiGraphics, LivingEntity entity, int x, int y, int maxWidth, int maxHeight, float baseScale, boolean silhouette, int color) {
if (tryRenderOverride(guiGraphics, entity.getType(), x, y, maxWidth, maxHeight, silhouette, color)) {
public static void renderEntityNormalized(GuiGraphics guiGraphics, LivingEntity entity, int x, int y, int maxWidth, int maxHeight, float baseScale, boolean silhouette, int color, boolean isPage) {
if (tryRenderOverride(guiGraphics, entity.getType(), x, y, maxWidth, maxHeight, silhouette, color, isPage)) {
return;
}

ResourceLocation id = FieldGuideDataManager.getEntryId(entity.getType());
EntryVisual visual = FieldGuideDataManager.getInstance().getEntryVisual(id);

float visualScale = visual.scale;
float yOff = visual.yOffset;
if (isPage) {
if (visual.pageScale != null) visualScale = visual.pageScale;
if (visual.pageYOffset != null) yOff = visual.pageYOffset;
} else {
if (visual.gridScale != null) visualScale = visual.gridScale;
if (visual.gridYOffset != null) yOff = visual.gridYOffset;
}

float dynamicFactor = getScaleFactorForEntity(entity);
float finalScale = (baseScale * 0.32F) * dynamicFactor;
float finalScale;

if (visualScale == 1.0f && visual.gridScale == null && visual.pageScale == null) {
finalScale = (baseScale * 0.32F) * dynamicFactor;
} else {
finalScale = baseScale * visualScale;
}

float entityHeight = entity.getBbHeight();
if (entityHeight * finalScale > maxHeight * 0.9f) {
finalScale = (maxHeight * 0.9f) / entityHeight;
}

// Standardize Y offset
int feetY = (int) (y + (entityHeight * finalScale / 2.0f));
int feetY = (int) (y + (entityHeight * finalScale / 2.0f) + yOff);

int minX = x - maxWidth / 2;
int minY = y - maxHeight / 2;
int maxX = x + maxWidth / 2;
Expand Down Expand Up @@ -216,7 +239,6 @@ public static void renderEntityStatic(GuiGraphics guiGraphics, LivingEntity enti
float bodyYAngle = 30;

Quaternionf cameraOrientation = Axis.XP.rotationDegrees(cameraXAngle);
Quaternionf bodyOrientation = Axis.YP.rotationDegrees(-bodyYAngle);

pose.mulPose(cameraOrientation);

Expand Down Expand Up @@ -268,9 +290,10 @@ public static void renderEntityStatic(GuiGraphics guiGraphics, LivingEntity enti
Lighting.setupForFlatItems();
}

public static void renderBlock(GuiGraphics guiGraphics, Block block, int x, int y, float scale, boolean silhouette) {
public static void renderBlock(GuiGraphics guiGraphics, Block block, int x, int y, float scale, boolean silhouette, boolean isPage) {
int estimatedSize = (int) (scale * 2);
if (tryRenderOverride(guiGraphics, block, x, y, estimatedSize, estimatedSize, silhouette, Constants.LIST_SILHOUETTE_COLOR)) {

if (tryRenderOverride(guiGraphics, block, x, y, estimatedSize, estimatedSize, silhouette, Constants.LIST_SILHOUETTE_COLOR, isPage)) {
return;
}

Expand All @@ -288,7 +311,6 @@ public static void renderBlock(GuiGraphics guiGraphics, Block block, int x, int
state = stateWithMaxPropertyValue(state, "flower_amount");
state = stateWithMaxPropertyValue(state, "pickles");

// Rendering
float cameraXAngle = 30;
float cameraYAngle = 210;

Expand Down Expand Up @@ -320,8 +342,6 @@ public static void renderBlock(GuiGraphics guiGraphics, Block block, int x, int
} else {
// Render multiple blocks vertically
Collection<?> values = verticalProp.getPossibleValues();

// Sort values in correct order from bottom -> top
if (!values.isEmpty() && values.iterator().next() instanceof Comparable) {
@SuppressWarnings("unchecked")
Collection<Comparable<?>> sorted = (Collection<Comparable<?>>) values;
Expand Down
Loading
Loading