Skip to content

Commit 7cd3038

Browse files
committed
Refactor GuiStyle (old config) into the proper config, and streamline it
1 parent 3b8c751 commit 7cd3038

19 files changed

Lines changed: 892 additions & 1026 deletions

.github/ISSUE_TEMPLATE/bug_report.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ about: Create a report to help us improve
44
labels: bug
55
---
66

7+
## Checklist before submitting
8+
- [ ] I have checked the existing issues (including closed) to make sure this bug has not already been reported/fixed
9+
- [ ] I am using the latest version of Spellcaster's Archives
10+
- [ ] I can reproduce this issue consistently
11+
- [ ] I have isolated the issue to Spellcaster's Archives and X mod(s) (optional but recommended)
12+
713
## Describe the bug
814
A clear and concise description of what the bug is.
915

@@ -18,8 +24,7 @@ Steps to reproduce the behavior:
1824
A clear and concise description of what you expected to happen.
1925

2026
## Logs and crash reports
21-
- Attach `logs/latest.log` and any crash report from `crash-reports/`.
22-
- If relevant, include the OpenComputers program snippet you ran.
27+
- Attach `logs/latest.log` and any crash report from `crash-reports/` (anonymize any PII).
2328

2429
## Screenshots
2530
If applicable, add screenshots to help explain your problem.

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@ The format is based on Keep a Changelog and this project adheres to Semantic Ver
77
- Keep a Changelog: https://keepachangelog.com/en/1.1.0/
88
- Semantic Versioning: https://semver.org/spec/v2.0.0.html
99

10+
## [0.4.6] - 2025-11-19
11+
### Added
12+
- Add "Easy layout" toggle in config, that will try to automatically adjust the right panel width.
13+
- When enabled, the right panel width will be set to fit all spell content, up to a maximum of 65% of GUI width.
14+
- It will try to fit the name fully without ellipsis, up to 50% of GUI width.
15+
16+
### Fixed
17+
- Fix issue of books list not being shifted far enough on non-zero pages, causing a noticeable overlap of books between pages.
18+
1019
## [0.4.5] - 2025-11-17
1120
### Fixed
1221
- Fix Spell books from other mods using ebwizardry Spell books, resulting in broken books and not being able to extract them correctly.

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ buildscript {
1515

1616
apply plugin: 'net.minecraftforge.gradle.forge'
1717

18-
version = "0.4.5"
18+
version = "0.4.6"
1919
group = "com.spellarchives"
2020
archivesBaseName = "spellarchives"
2121

src/main/java/com/spellarchives/SpellArchives.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
public class SpellArchives {
2424
public static final String MODID = "spellarchives";
2525
public static final String NAME = "Spellcaster's Archives";
26-
public static final String VERSION = "0.4.5";
26+
public static final String VERSION = "0.4.6";
2727
public static final Log LOGGER = new Log();
2828

2929
@SidedProxy(clientSide = "com.spellarchives.client.ClientProxy", serverSide = "com.spellarchives.CommonProxy")

src/main/java/com/spellarchives/block/BlockSpellArchive.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public EnumBlockRenderType getRenderType(IBlockState state) {
9595
/**
9696
* Advertise that this block supports horizontal rotations via tools. Returning the four
9797
* horizontal faces allows wrenches to attempt rotation rather than remove/re-place.
98-
*
98+
*
9999
* @param world World containing the block (not used).
100100
* @param pos Position of the block (not used).
101101
*/

src/main/java/com/spellarchives/client/ClientConfig.java

Lines changed: 0 additions & 424 deletions
This file was deleted.

src/main/java/com/spellarchives/client/ClientConfigGuiFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import net.minecraftforge.fml.client.config.IConfigElement;
2121

2222
import com.spellarchives.SpellArchives;
23-
import com.spellarchives.gui.GuiStyle;
23+
import com.spellarchives.config.ClientConfig;
2424
import com.spellarchives.config.SpellArchivesConfig;
2525

2626

@@ -98,7 +98,7 @@ public void onGuiClosed() {
9898
Configuration guiCfg = ClientConfig.getConfiguration();
9999
if (guiCfg != null && guiCfg.hasChanged()) guiCfg.save();
100100

101-
net.minecraftforge.common.config.Configuration gameplayCfg = com.spellarchives.config.SpellArchivesConfig.getConfiguration();
101+
Configuration gameplayCfg = SpellArchivesConfig.getConfiguration();
102102
if (gameplayCfg != null && gameplayCfg.hasChanged()) gameplayCfg.save();
103103
}
104104
}

src/main/java/com/spellarchives/client/ClientProxy.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
import net.minecraftforge.common.MinecraftForge;
44

55
import com.spellarchives.CommonProxy;
6-
import com.spellarchives.client.ClientConfig;
7-
import com.spellarchives.gui.GuiStyle;
6+
import com.spellarchives.config.ClientConfig;
87
import com.spellarchives.registry.ClientModels;
98

109

@@ -22,6 +21,5 @@ public void preInit() {
2221

2322
// Initialize client-side config and apply GUI style overrides
2423
ClientConfig.init();
25-
GuiStyle.reloadFromConfig();
2624
}
2725
}

src/main/java/com/spellarchives/render/DynamicTextureFactory.java renamed to src/main/java/com/spellarchives/client/DynamicTextureFactory.java

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.spellarchives.render;
1+
package com.spellarchives.client;
22

33
import java.awt.image.BufferedImage;
44
import java.io.IOException;
@@ -15,13 +15,13 @@
1515
import net.minecraft.client.resources.IResourceManager;
1616
import net.minecraft.util.ResourceLocation;
1717

18-
import com.spellarchives.gui.GuiStyle;
18+
import com.spellarchives.config.ClientConfig;
1919
import com.spellarchives.util.TextUtils;
2020

2121

2222
/**
2323
* Centralized factory for dynamic textures used by the GUI. Caches textures and invalidates
24-
* them automatically when relevant configuration changes (tracked via GuiStyle.CONFIG_REVISION).
24+
* them automatically when relevant configuration changes (tracked via ClientConfig.CONFIG_REVISION).
2525
*/
2626
public final class DynamicTextureFactory {
2727
private DynamicTextureFactory() {}
@@ -31,15 +31,15 @@ private DynamicTextureFactory() {}
3131
private static int cacheRevision = -1;
3232

3333
private static void checkRevision() {
34-
if (cacheRevision != GuiStyle.CONFIG_REVISION) {
34+
if (cacheRevision != ClientConfig.CONFIG_REVISION) {
3535
// Attempt to delete previously registered dynamic textures from the texture manager
3636
TextureManager tm = Minecraft.getMinecraft().getTextureManager();
3737
for (ResourceLocation rl : spineCache.values()) tm.deleteTexture(rl);
3838
for (ResourceLocation rl : bgCache.values()) tm.deleteTexture(rl);
3939

4040
spineCache.clear();
4141
bgCache.clear();
42-
cacheRevision = GuiStyle.CONFIG_REVISION;
42+
cacheRevision = ClientConfig.CONFIG_REVISION;
4343
}
4444
}
4545

@@ -56,7 +56,7 @@ private static void checkRevision() {
5656
*/
5757
public static ResourceLocation getOrCreateSpineTexture(int baseRgb, int w, int h, ResourceLocation iconRl, int iconSize) {
5858
checkRevision();
59-
String key = baseRgb + "_" + w + "x" + h + (iconRl != null && GuiStyle.SPINE_EMBED_ICON ? ("|icon=" + iconRl.toString() + "|s=" + iconSize) : "");
59+
String key = baseRgb + "_" + w + "x" + h + (iconRl != null && ClientConfig.SPINE_EMBED_ICON ? ("|icon=" + iconRl.toString() + "|s=" + iconSize) : "");
6060
ResourceLocation existing = spineCache.get(key);
6161
if (existing != null) return existing;
6262
// Full generator: curvature, vertical shading, deterministic noise, optional bands and icon embedding
@@ -89,17 +89,17 @@ public static ResourceLocation getOrCreateSpineTexture(int baseRgb, int w, int h
8989
// Off-center bias for spine curvature
9090
float centerBias = 0.5f + (rf.apply(s1) - 0.5f) * 0.18f; // 0.32..0.68
9191
centerBias = Math.max(0.3f, Math.min(0.7f, centerBias));
92-
float asymTilt = GuiStyle.SPINE_ENABLE_TILT ? (rf.apply(s2) - 0.5f) * 0.12f : 0f; // -0.06..0.06
93-
float noiseAmp = GuiStyle.SPINE_ENABLE_NOISE ? GuiStyle.SPINE_NOISE_AMPLITUDE : 0f; // +/- percentage noise
92+
float asymTilt = ClientConfig.SPINE_ENABLE_TILT ? (rf.apply(s2) - 0.5f) * 0.12f : 0f; // -0.06..0.06
93+
float noiseAmp = ClientConfig.SPINE_ENABLE_NOISE ? ClientConfig.SPINE_NOISE_AMPLITUDE : 0f; // +/- percentage noise
9494

9595
// Two horizontal bands near the top of available area above icon reserve
96-
int iconReserve = GuiStyle.SPINE_ICON_SIZE + GuiStyle.SPINE_ICON_BOTTOM_MARGIN; // reserve for bottom icon area
96+
int iconReserve = ClientConfig.SPINE_ICON_SIZE + ClientConfig.SPINE_ICON_BOTTOM_MARGIN; // reserve for bottom icon area
9797
int available = Math.max(0, h - iconReserve);
98-
int bandThickness = GuiStyle.SPINE_BAND_THICKNESS;
99-
int bandGap = GuiStyle.SPINE_BAND_GAP;
98+
int bandThickness = ClientConfig.SPINE_BAND_THICKNESS;
99+
int bandGap = ClientConfig.SPINE_BAND_GAP;
100100

101101
// Place bands starting at top with a small top space
102-
int band1 = available > 0 ? Math.min(available - bandThickness, GuiStyle.SPINE_BAND_TOP_SPACE) : -1;
102+
int band1 = available > 0 ? Math.min(available - bandThickness, ClientConfig.SPINE_BAND_TOP_SPACE) : -1;
103103
int band2 = band1 >= 0 ? Math.min(available - bandThickness, band1 + bandThickness + bandGap) : -1;
104104

105105
for (int y = 0; y < h; y++) {
@@ -109,15 +109,15 @@ public static ResourceLocation getOrCreateSpineTexture(int baseRgb, int w, int h
109109
float dist = Math.abs(nx - centerBias) * 2f; // 0 center -> ~1 edges
110110
float side = Math.signum(nx - centerBias);
111111
dist *= (1f + asymTilt * side);
112-
float shade = GuiStyle.SPINE_ENABLE_CURVATURE
113-
? (GuiStyle.SPINE_CENTER_BRIGHTEN - GuiStyle.SPINE_EDGE_FACTOR * dist)
112+
float shade = ClientConfig.SPINE_ENABLE_CURVATURE
113+
? (ClientConfig.SPINE_CENTER_BRIGHTEN - ClientConfig.SPINE_EDGE_FACTOR * dist)
114114
: 1.0f;
115115
int rgb = TextUtils.darkenColor(baseRgb, shade);
116116

117117
// Subtle horizontal roll-off towards top/bottom
118118
float ny = (y + 0.5f) / h;
119119
float edgeY = Math.min(ny, 1f - ny) * 2f; // 0 at edges, 1 at center
120-
float vshade = GuiStyle.SPINE_VSHADE_BASE + GuiStyle.SPINE_VSHADE_RANGE * edgeY; // darker near top/bottom
120+
float vshade = ClientConfig.SPINE_VSHADE_BASE + ClientConfig.SPINE_VSHADE_RANGE * edgeY; // darker near top/bottom
121121
rgb = TextUtils.darkenColor(rgb, vshade);
122122

123123
// Per-pixel noise to break uniformity (deterministic)
@@ -131,36 +131,36 @@ public static ResourceLocation getOrCreateSpineTexture(int baseRgb, int w, int h
131131
}
132132

133133
// Apply horizontal bands post-pass for clean thin lines (darken slightly)
134-
if (GuiStyle.SPINE_ENABLE_BANDS && band1 >= 0) {
134+
if (ClientConfig.SPINE_ENABLE_BANDS && band1 >= 0) {
135135
for (int x = 0; x < w; x++) {
136136
for (int dy = 0; dy < bandThickness; dy++) { // 2px thickness
137137
int yy = band1 + dy;
138138
if (yy >= 0 && yy < h) {
139139
int idx = yy * w + x;
140140
int rgb = pixels[idx] & 0xFFFFFF;
141-
pixels[idx] = 0xFF000000 | (TextUtils.darkenColor(rgb, GuiStyle.SPINE_BAND1_DARKEN) & 0xFFFFFF);
141+
pixels[idx] = 0xFF000000 | (TextUtils.darkenColor(rgb, ClientConfig.SPINE_BAND1_DARKEN) & 0xFFFFFF);
142142
}
143143
}
144144
}
145145
}
146146

147-
if (GuiStyle.SPINE_ENABLE_BANDS && band2 >= 0) {
147+
if (ClientConfig.SPINE_ENABLE_BANDS && band2 >= 0) {
148148
for (int x = 0; x < w; x++) {
149149
for (int dy = 0; dy < bandThickness; dy++) {
150150
int yy = band2 + dy;
151151
if (yy >= 0 && yy < h) {
152152
int idx = yy * w + x;
153153
int rgb = pixels[idx] & 0xFFFFFF;
154-
pixels[idx] = 0xFF000000 | (TextUtils.darkenColor(rgb, GuiStyle.SPINE_BAND2_DARKEN) & 0xFFFFFF);
154+
pixels[idx] = 0xFF000000 | (TextUtils.darkenColor(rgb, ClientConfig.SPINE_BAND2_DARKEN) & 0xFFFFFF);
155155
}
156156
}
157157
}
158158
}
159159

160160
// Optionally embed the element icon into the spine texture (bottom-centered)
161-
if (GuiStyle.SPINE_EMBED_ICON && iconRl != null && iconSize > 0) {
161+
if (ClientConfig.SPINE_EMBED_ICON && iconRl != null && iconSize > 0) {
162162
int ix = (w - iconSize) / 2;
163-
int iy = (h - iconSize - GuiStyle.SPINE_ICON_BOTTOM_MARGIN) + GuiStyle.SPINE_ICON_Y_OFFSET;
163+
int iy = (h - iconSize - ClientConfig.SPINE_ICON_BOTTOM_MARGIN) + ClientConfig.SPINE_ICON_Y_OFFSET;
164164

165165
if (ix >= 0 && iy >= 0 && ix + iconSize <= w && iy + iconSize <= h) {
166166
try {
@@ -228,12 +228,12 @@ public static ResourceLocation getOrCreateSpineTexture(int baseRgb, int w, int h
228228
public static ResourceLocation getOrCreatePanelBg(int w, int h) {
229229
checkRevision();
230230

231-
String key = "bg_" + w + "x" + h + "_rev" + GuiStyle.CONFIG_REVISION;
231+
String key = "bg_" + w + "x" + h + "_rev" + ClientConfig.CONFIG_REVISION;
232232
ResourceLocation existing = bgCache.get(key);
233233
if (existing != null) return existing;
234234

235-
int topColor = GuiStyle.BACKGROUND_FILL;
236-
int bottomColor = GuiStyle.BACKGROUND_BORDER;
235+
int topColor = ClientConfig.BACKGROUND_FILL;
236+
int bottomColor = ClientConfig.BACKGROUND_BORDER;
237237
int[] pixels = new int[w * h];
238238
for (int y = 0; y < h; y++) {
239239
float t = y / (float)Math.max(1, h - 1);

src/main/java/com/spellarchives/client/SpellArchiveModelRetexture.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public static void onModelBake(ModelBakeEvent event) {
100100
try {
101101
// Build texture map with randomized corner textures and spell icons
102102
Map<String, String> textures = new HashMap<>();
103-
103+
104104
// Keep base textures
105105
textures.put("particle", "ebwizardry:blocks/dark_oak_bookshelf_top");
106106
textures.put("side", "ebwizardry:blocks/dark_oak_bookshelf_side");
@@ -110,7 +110,7 @@ public static void onModelBake(ModelBakeEvent event) {
110110
ResourceLocation leftIcon = WizardryTextureStitcher.getCoreSideSpellIcon(0);
111111
ResourceLocation rightIcon = WizardryTextureStitcher.getCoreSideSpellIcon(1);
112112
ResourceLocation backIcon = WizardryTextureStitcher.getCoreSideSpellIcon(2);
113-
113+
114114
// Convert spell icon paths: remove .png extension and adjust path
115115
String leftPath = convertResourcePath(leftIcon);
116116
String rightPath = convertResourcePath(rightIcon);
@@ -119,7 +119,7 @@ public static void onModelBake(ModelBakeEvent event) {
119119
textures.put("spell_left", leftPath);
120120
textures.put("spell_right", rightPath);
121121
textures.put("spell_back", backPath);
122-
122+
123123
// Randomized corner textures
124124
for (int corner = 0; corner < 8; corner++) {
125125
String element = WizardryTextureStitcher.getCornerElement(corner);
@@ -163,13 +163,13 @@ public static void onModelBake(ModelBakeEvent event) {
163163
DefaultVertexFormats.BLOCK,
164164
getter
165165
);
166-
166+
167167
// Register under the actual per-books path so blockstate resolves without reload
168168
event.getModelRegistry().putObject(modelLocation, bakedModel);
169169
// Also register under the canonical 'spell_archive' path for safety (books property included in variant)
170170
ModelResourceLocation canonicalLoc = new ModelResourceLocation(baseLoc, variant);
171171
event.getModelRegistry().putObject(canonicalLoc, bakedModel);
172-
172+
173173
} catch (Exception e) {
174174
SpellArchives.LOGGER.error("Failed to retexture spell archive model for " + variant, e);
175175
}

0 commit comments

Comments
 (0)