Skip to content

Commit c5a8f8a

Browse files
committed
Improved Datapack Handling
1 parent 8303467 commit c5a8f8a

File tree

7 files changed

+171
-13
lines changed

7 files changed

+171
-13
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ Change the datapack structure color scheme (applies immediately):
5757
- ```/sm:datapack colorscheme 2``` - secondary scheme
5858
- ```/sm:datapack colorscheme 3``` - third scheme
5959

60+
Change the datapack structure icon style (applies immediately):
61+
- ```/sm:datapack iconstyle 1``` - flat colored squares (default)
62+
- ```/sm:datapack iconstyle 2``` - colored potion bottle icons
63+
6064
Enable or disable auto-loading on join:
6165
- ```/sm:datapack autoload true```
6266
- ```/sm:datapack autoload false```

src/main/java/dev/xpple/seedmapper/command/commands/DatapackImportCommand.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ public static void register(com.mojang.brigadier.CommandDispatcher<FabricClientC
4343
.executes(DatapackImportCommand::read))
4444
.then(literal("colorscheme")
4545
.then(argument("scheme", IntegerArgumentType.integer(1, 3))
46-
.executes(DatapackImportCommand::setColorScheme))));
46+
.executes(DatapackImportCommand::setColorScheme)))
47+
.then(literal("iconstyle")
48+
.then(argument("style", IntegerArgumentType.integer(1, 2))
49+
.executes(DatapackImportCommand::setIconStyle))));
4750
}
4851

4952
@SuppressWarnings("unused")
@@ -121,6 +124,23 @@ private static int setColorScheme(CommandContext<FabricClientCommandSource> cont
121124
return Command.SINGLE_SUCCESS;
122125
}
123126

127+
private static int setIconStyle(CommandContext<FabricClientCommandSource> context) {
128+
CustomClientCommandSource source = CustomClientCommandSource.of(context.getSource());
129+
int style = IntegerArgumentType.getInteger(context, "style");
130+
Configs.DatapackIconStyle = style;
131+
Configs.save();
132+
source.sendFeedback(Component.translatable("seedMap.datapackImport.iconStyleSet", style));
133+
try {
134+
int generatorFlags = source.getGeneratorFlags();
135+
SeedMapScreen.reopenIfOpen(generatorFlags);
136+
SeedMapMinimapManager.refreshIfOpenWithGeneratorFlags(generatorFlags);
137+
} catch (CommandSyntaxException ignored) {
138+
SeedMapScreen.reopenIfOpen(0);
139+
SeedMapMinimapManager.refreshIfOpenWithGeneratorFlags(0);
140+
}
141+
return Command.SINGLE_SUCCESS;
142+
}
143+
124144
public static int importUrl(CustomClientCommandSource source, String url) {
125145
if (url.isBlank()) {
126146
source.sendError(Component.translatable("seedMap.datapackImport.status.invalidUrl"));

src/main/java/dev/xpple/seedmapper/config/Configs.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,13 @@ private static void setDatapackColorScheme(int scheme) {
101101
DatapackColorScheme = Math.clamp(scheme, 1, 3);
102102
}
103103

104+
@Config(setter = @Config.Setter("setDatapackIconStyle"))
105+
public static int DatapackIconStyle = 1;
106+
107+
private static void setDatapackIconStyle(int style) {
108+
DatapackIconStyle = Math.clamp(style, 1, 2);
109+
}
110+
104111
public static String getCurrentServerKey() {
105112
Minecraft minecraft = Minecraft.getInstance();
106113
if (minecraft == null || minecraft.getConnection() == null || minecraft.getConnection().getConnection() == null) {

src/main/java/dev/xpple/seedmapper/seedmap/CustomStructureToggleWidget.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@
22

33
import dev.xpple.seedmapper.config.Configs;
44
import dev.xpple.seedmapper.datapack.DatapackStructureManager;
5+
import dev.xpple.seedmapper.seedmap.SeedMapScreen;
56
import net.minecraft.client.gui.GuiGraphics;
67
import net.minecraft.client.gui.components.Button;
78
import net.minecraft.network.chat.Component;
9+
import net.minecraft.resources.Identifier;
810
import net.minecraft.util.ARGB;
911

1012
public class CustomStructureToggleWidget extends Button {
1113
private static final int ICON_SIZE = 16;
14+
private static final Identifier POTION_TEXTURE = Identifier.fromNamespaceAndPath("minecraft", "textures/item/potion.png");
15+
private static final Identifier POTION_OVERLAY_TEXTURE = Identifier.fromNamespaceAndPath("minecraft", "textures/item/potion_overlay.png");
1216

1317
private final String toggleKey;
1418
private final DatapackStructureManager.StructureSetEntry entry;
@@ -40,7 +44,11 @@ protected void renderContents(GuiGraphics guiGraphics, int mouseX, int mouseY, f
4044
if (!Configs.isDatapackStructureEnabled(this.toggleKey, this.entry.id())) {
4145
colour = ARGB.color(255 >> 1, colour);
4246
}
43-
drawSquare(guiGraphics, this.getX(), this.getY(), ICON_SIZE, colour);
47+
if (Configs.DatapackIconStyle == 2) {
48+
drawPotionIcon(guiGraphics, this.getX(), this.getY(), ICON_SIZE, colour);
49+
} else {
50+
drawSquare(guiGraphics, this.getX(), this.getY(), ICON_SIZE, colour);
51+
}
4452
}
4553

4654
private static void onButtonPress(Button button) {
@@ -81,4 +89,9 @@ private static void drawSquare(GuiGraphics guiGraphics, int x, int y, int size,
8189
guiGraphics.fill(x - 1, y - 1, x + size + 1, y + size + 1, border);
8290
guiGraphics.fill(x, y, x + size, y + size, colour);
8391
}
92+
93+
private static void drawPotionIcon(GuiGraphics guiGraphics, int x, int y, int size, int colour) {
94+
SeedMapScreen.drawIconStatic(guiGraphics, POTION_TEXTURE, x, y, size, size, 0xFF_FFFFFF);
95+
SeedMapScreen.drawIconStatic(guiGraphics, POTION_OVERLAY_TEXTURE, x, y, size, size, colour);
96+
}
8497
}

src/main/java/dev/xpple/seedmapper/seedmap/SeedMapMinimapScreen.java

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,66 @@ private void renderMinimapIcons(GuiGraphics guiGraphics, double translateX, doub
144144
double rotatedY = centerY + dx * sin + dy * cos;
145145
int drawX = (int) Math.round(rotatedX - scaledWidth / 2.0);
146146
int drawY = (int) Math.round(rotatedY - scaledHeight / 2.0);
147-
this.drawFeatureIcon(guiGraphics, texture, drawX, drawY, scaledWidth, scaledHeight, 0xFF_FFFFFF);
148-
this.drawCompletionOverlay(guiGraphics, widget, drawX, drawY, scaledWidth, scaledHeight);
147+
drawIconStatic(guiGraphics, texture.identifier(), drawX, drawY, scaledWidth, scaledHeight, 0xFF_FFFFFF);
148+
this.drawRotatedCompletionOverlay(guiGraphics, widget, drawX, drawY, scaledWidth, scaledHeight, rotationRadians);
149149
}
150150

151151
FeatureWidget marker = this.getMarkerWidget();
152152
if (marker != null && marker.withinBounds()) {
153153
this.renderSingleIcon(guiGraphics, marker, translateX, translateY, centerX, centerY, cos, sin, 0xFF_FFFFFF, iconScale);
154154
}
155+
this.renderMinimapCustomStructureIcons(guiGraphics, translateX, translateY, centerX, centerY, cos, sin, rotationRadians);
156+
}
157+
158+
private void renderMinimapCustomStructureIcons(GuiGraphics guiGraphics, double translateX, double translateY, double centerX, double centerY, double cos, double sin, float rotationRadians) {
159+
var widgets = this.getCustomStructureWidgets();
160+
if (widgets == null || widgets.isEmpty()) {
161+
return;
162+
}
163+
int iconSize = this.getDatapackIconSize();
164+
for (CustomStructureWidget widget : widgets) {
165+
if (!widget.withinBounds()) {
166+
continue;
167+
}
168+
double baseCenterX = widget.drawX() + iconSize / 2.0;
169+
double baseCenterY = widget.drawY() + iconSize / 2.0;
170+
double shiftedX = baseCenterX + translateX;
171+
double shiftedY = baseCenterY + translateY;
172+
double dx = shiftedX - centerX;
173+
double dy = shiftedY - centerY;
174+
double rotatedX = centerX + dx * cos - dy * sin;
175+
double rotatedY = centerY + dx * sin + dy * cos;
176+
int drawX = (int) Math.round(rotatedX - iconSize / 2.0);
177+
int drawY = (int) Math.round(rotatedY - iconSize / 2.0);
178+
this.drawCustomStructureIcon(guiGraphics, drawX, drawY, iconSize, widget.tint());
179+
if (this.isDatapackStructureCompleted(widget.entry().id(), widget.featureLocation())) {
180+
this.drawRotatedDatapackCompletion(guiGraphics, drawX, drawY, iconSize, rotationRadians);
181+
}
182+
}
183+
}
184+
185+
private void drawRotatedDatapackCompletion(GuiGraphics guiGraphics, int x, int y, int size, float rotationRadians) {
186+
this.drawCompletedTick(guiGraphics, x, y, size, size);
187+
}
188+
189+
private void drawRotatedCompletionOverlay(GuiGraphics guiGraphics, FeatureWidget widget, int x, int y, int width, int height, float rotationRadians) {
190+
this.drawCompletionOverlay(guiGraphics, widget, x, y, width, height);
191+
}
192+
193+
private void withIconRotation(GuiGraphics guiGraphics, int x, int y, int width, int height, float rotationRadians, Runnable drawAction) {
194+
if (rotationRadians == 0.0F) {
195+
drawAction.run();
196+
return;
197+
}
198+
var pose = guiGraphics.pose();
199+
pose.pushMatrix();
200+
float centerX = x + width / 2.0F;
201+
float centerY = y + height / 2.0F;
202+
pose.translate(centerX, centerY);
203+
pose.rotate(rotationRadians);
204+
pose.translate(-centerX, -centerY);
205+
drawAction.run();
206+
pose.popMatrix();
155207
}
156208

157209
private void renderWaypointLabels(GuiGraphics guiGraphics, double translateX, double translateY, double centerX, double centerY, float rotationRadians) {
@@ -261,6 +313,11 @@ protected void setPixelsPerBiome(double pixelsPerBiome) {
261313
}
262314
}
263315

316+
@Override
317+
protected boolean isMinimap() {
318+
return true;
319+
}
320+
264321
@Override
265322
protected boolean shouldRenderChestLootWidget() {
266323
return false;

src/main/java/dev/xpple/seedmapper/seedmap/SeedMapScreen.java

Lines changed: 65 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ public static void reopenIfOpen(int generatorFlags) {
343343
});
344344
private static final int CUSTOM_STRUCTURE_MAX_IN_FLIGHT = 2;
345345
private static final int CUSTOM_STRUCTURE_ENQUEUE_PER_TICK = 200;
346+
private static final int CUSTOM_STRUCTURE_MINIMAP_ENQUEUE_PER_TICK = 16;
346347
private final java.util.List<FeatureToggleWidget> featureToggleWidgets = new java.util.ArrayList<>();
347348
private final java.util.List<CustomStructureToggleWidget> customStructureToggleWidgets = new java.util.ArrayList<>();
348349

@@ -387,6 +388,8 @@ public static void reopenIfOpen(int generatorFlags) {
387388
private static final double DOUBLE_CLICK_DISTANCE_SQ = 16.0D;
388389

389390
private static final Identifier DIRECTION_ARROW_TEXTURE = Identifier.fromNamespaceAndPath(SeedMapper.MOD_ID, "textures/gui/arrow.png");
391+
private static final Identifier DATAPACK_POTION_TEXTURE = Identifier.fromNamespaceAndPath("minecraft", "textures/item/potion.png");
392+
private static final Identifier DATAPACK_POTION_OVERLAY_TEXTURE = Identifier.fromNamespaceAndPath("minecraft", "textures/item/potion_overlay.png");
390393
private static final MapFeature.Texture WURST_WAYPOINT_TEXTURE = new MapFeature.Texture(
391394
Identifier.fromNamespaceAndPath(SeedMapper.MOD_ID, "textures/feature_icons/waypoint_wurst.png"), 20, 20
392395
);
@@ -553,7 +556,22 @@ private void drawTile(GuiGraphics guiGraphics, Tile tile) {
553556
int drawMinY = (int) Math.round(minY);
554557
int drawMaxX = (int) Math.round(maxX);
555558
int drawMaxY = (int) Math.round(maxY);
556-
guiGraphics.submitBlit(RenderPipelines.GUI_TEXTURED, tile.texture().getTextureView(), tile.texture().getSampler(), drawMinX, drawMinY, drawMaxX, drawMaxY, u0, u1, v0, v1, tint);
559+
BlitRenderState renderState = new BlitRenderState(
560+
RenderPipelines.GUI_TEXTURED,
561+
TextureSetup.singleTexture(tile.texture().getTextureView(), tile.texture().getSampler()),
562+
new Matrix3x2f(guiGraphics.pose()),
563+
drawMinX,
564+
drawMinY,
565+
drawMaxX,
566+
drawMaxY,
567+
u0,
568+
u1,
569+
v0,
570+
v1,
571+
tint,
572+
guiGraphics.scissorStack.peek()
573+
);
574+
guiGraphics.guiRenderState.submitBlitToCurrentLayer(renderState);
557575
}
558576

559577
private Tile createBiomeTile(TilePos tilePos, int[] biomeData) {
@@ -646,6 +664,9 @@ private void drawCustomStructureIcons(GuiGraphics guiGraphics) {
646664
if ((this.customStructureWidgets == null) || this.customStructureWidgets.isEmpty()) {
647665
return;
648666
}
667+
if (!this.shouldDrawFeatureIcons()) {
668+
return;
669+
}
649670
for (CustomStructureWidget widget : this.customStructureWidgets) {
650671
if (!widget.withinBounds()) {
651672
continue;
@@ -657,10 +678,19 @@ private void drawCustomStructureIcons(GuiGraphics guiGraphics) {
657678
}
658679
}
659680

660-
private void drawCustomStructureIcon(GuiGraphics guiGraphics, int x, int y, int size, int colour) {
661-
int border = 0xFF000000;
662-
guiGraphics.fill(x - 1, y - 1, x + size + 1, y + size + 1, border);
663-
guiGraphics.fill(x, y, x + size, y + size, colour);
681+
protected void drawCustomStructureIcon(GuiGraphics guiGraphics, int x, int y, int size, int colour) {
682+
if (Configs.DatapackIconStyle == 2) {
683+
drawPotionIcon(guiGraphics, x, y, size, colour);
684+
} else {
685+
int border = 0xFF000000;
686+
guiGraphics.fill(x - 1, y - 1, x + size + 1, y + size + 1, border);
687+
guiGraphics.fill(x, y, x + size, y + size, colour);
688+
}
689+
}
690+
691+
private static void drawPotionIcon(GuiGraphics guiGraphics, int x, int y, int size, int colour) {
692+
drawIconStatic(guiGraphics, DATAPACK_POTION_TEXTURE, x, y, size, size, 0xFF_FFFFFF);
693+
drawIconStatic(guiGraphics, DATAPACK_POTION_OVERLAY_TEXTURE, x, y, size, size, colour);
664694
}
665695

666696
private void createFeatureToggles() {
@@ -2317,7 +2347,7 @@ private boolean isStructureCompleted(MapFeature feature, BlockPos pos) {
23172347
return this.completedStructures.contains(buildStructureCompletionEntry(feature, pos));
23182348
}
23192349

2320-
private boolean isDatapackStructureCompleted(String id, BlockPos pos) {
2350+
protected boolean isDatapackStructureCompleted(String id, BlockPos pos) {
23212351
return this.completedStructures.contains(buildDatapackStructureCompletionEntry(id, pos));
23222352
}
23232353

@@ -2345,6 +2375,10 @@ private void setDatapackStructureCompleted(String id, BlockPos pos, boolean comp
23452375
}
23462376
Configs.setSeedMapCompletedStructures(this.structureCompletionKey, this.completedStructures);
23472377
Configs.save();
2378+
try {
2379+
SeedMapMinimapManager.refreshCompletedStructuresIfOpen();
2380+
} catch (Throwable ignored) {
2381+
}
23482382
}
23492383

23502384
void refreshCompletedStructuresFromConfig() {
@@ -2362,7 +2396,7 @@ protected void drawCompletionOverlay(GuiGraphics guiGraphics, FeatureWidget widg
23622396
this.drawCompletedTick(guiGraphics, x, y, width, height);
23632397
}
23642398

2365-
private void drawCompletedTick(GuiGraphics guiGraphics, int x, int y, int width, int height) {
2399+
protected void drawCompletedTick(GuiGraphics guiGraphics, int x, int y, int width, int height) {
23662400
int size = Math.max(8, Math.min(width, height) - 4);
23672401
int baseX = x + (width - size) / 2;
23682402
int baseY = y + (height - size) / 2;
@@ -3125,7 +3159,7 @@ private void drawIcon(GuiGraphics guiGraphics, Identifier identifier, int minX,
31253159
pose.popMatrix();
31263160
}
31273161

3128-
private static void drawIconStatic(GuiGraphics guiGraphics, Identifier identifier, int minX, int minY, int iconWidth, int iconHeight, int colour) {
3162+
static void drawIconStatic(GuiGraphics guiGraphics, Identifier identifier, int minX, int minY, int iconWidth, int iconHeight, int colour) {
31293163
// Skip intersection checks (GuiRenderState.hasIntersection) you would otherwise get when calling
31303164
// GuiGraphics.blit as these checks incur a significant performance hit
31313165
AbstractTexture texture = Minecraft.getInstance().getTextureManager().getTexture(identifier);
@@ -3389,6 +3423,9 @@ protected void renderSeedMap(GuiGraphics guiGraphics, int mouseX, int mouseY, fl
33893423
protected boolean showFeatureIconTooltips() { return true; }
33903424

33913425
private void renderFeatureIconTooltip(GuiGraphics guiGraphics, int mouseX, int mouseY) {
3426+
if (this.isMouseOverToggleWidget(mouseX, mouseY)) {
3427+
return;
3428+
}
33923429
for (FeatureWidget widget : this.featureWidgets) {
33933430
if (!widget.withinBounds()) continue;
33943431
if (!Configs.ToggledFeatures.contains(widget.feature)) continue;
@@ -3403,6 +3440,9 @@ private void renderFeatureIconTooltip(GuiGraphics guiGraphics, int mouseX, int m
34033440
}
34043441

34053442
private void renderCustomStructureTooltip(GuiGraphics guiGraphics, int mouseX, int mouseY) {
3443+
if (this.isMouseOverToggleWidget(mouseX, mouseY)) {
3444+
return;
3445+
}
34063446
for (CustomStructureWidget widget : this.customStructureWidgets) {
34073447
if (!widget.withinBounds()) {
34083448
continue;
@@ -3418,6 +3458,20 @@ private void renderCustomStructureTooltip(GuiGraphics guiGraphics, int mouseX, i
34183458
}
34193459
}
34203460

3461+
private boolean isMouseOverToggleWidget(int mouseX, int mouseY) {
3462+
for (FeatureToggleWidget widget : this.featureToggleWidgets) {
3463+
if (widget.isMouseOver(mouseX, mouseY)) {
3464+
return true;
3465+
}
3466+
}
3467+
for (CustomStructureToggleWidget widget : this.customStructureToggleWidgets) {
3468+
if (widget.isMouseOver(mouseX, mouseY)) {
3469+
return true;
3470+
}
3471+
}
3472+
return false;
3473+
}
3474+
34213475
private void renderCustomStructureWidgets(GuiGraphics guiGraphics, int horChunkRadius, int verChunkRadius) {
34223476
DatapackStructureManager.DatapackWorldgen worldgen = DatapackStructureManager.getWorldgen(this.worldIdentifier);
34233477
if (worldgen == null) {
@@ -3729,7 +3783,7 @@ private void enqueueTilesSpiralIncremental(Object2ObjectMap<TilePos, java.util.L
37293783
if (this.customStructureSpiralCursor == null) {
37303784
return;
37313785
}
3732-
int budget = CUSTOM_STRUCTURE_ENQUEUE_PER_TICK;
3786+
int budget = this.isMinimap() ? CUSTOM_STRUCTURE_MINIMAP_ENQUEUE_PER_TICK : CUSTOM_STRUCTURE_ENQUEUE_PER_TICK;
37333787
while (budget > 0) {
37343788
TilePos tilePos = this.customStructureSpiralCursor.next();
37353789
if (tilePos == null) {
@@ -3983,9 +4037,11 @@ protected void drawCenteredPlayerDirectionArrow(GuiGraphics guiGraphics, double
39834037
protected int verticalPadding() { return VERTICAL_PADDING; }
39844038

39854039
protected ObjectSet<FeatureWidget> getFeatureWidgets() { return this.featureWidgets; }
4040+
protected ObjectSet<CustomStructureWidget> getCustomStructureWidgets() { return this.customStructureWidgets; }
39864041
protected FeatureWidget getMarkerWidget() { return this.markerWidget; }
39874042
protected QuartPos2f getCenterQuart() { return this.centerQuart; }
39884043
protected WorldIdentifier getWorldIdentifier() { return this.worldIdentifier; }
4044+
protected int getDatapackIconSize() { return DATAPACK_ICON_SIZE; }
39894045

39904046
protected void drawFeatureIcon(GuiGraphics guiGraphics, MapFeature.Texture texture, int x, int y, int width, int height, int colour) {
39914047
// Draw icon with requested width/height so minimap scaling works

src/main/resources/assets/seedmapper/lang/en_us.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,5 +137,6 @@
137137
"seedMap.datapackImport.read.none": "No datapack URL is available.",
138138
"seedMap.datapackImport.read.current": "Datapack URL: %s",
139139
"seedMap.datapackImport.colorschemeSet": "Datapack color scheme set to %d.",
140+
"seedMap.datapackImport.iconStyleSet": "Datapack icon style set to %d.",
140141
"config.showDatapackStructures.comment": "Render imported datapack structures on the SeedMap."
141142
}

0 commit comments

Comments
 (0)