Skip to content

Commit 02c8e1b

Browse files
committed
Release v1.2: Fix unknown schematic persistence & streamline mobile preview UX
1 parent f7bbae5 commit 02c8e1b

6 files changed

Lines changed: 89 additions & 24 deletions

File tree

‎README.md‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,19 @@ A Mindustry Java mod that introduces a customizable, floating **Quick Access HUD
3636

3737
---
3838

39+
## 🆕 What's New in v1.2
40+
41+
### 🐛 Bug Fixes:
42+
- **Unknown/Unnamed Schematic Persistence**: Fixed an issue where schematics with default `"unknown"` names, missing tags, or in-game copied selections were lost when closing and re-opening the game. Schematics without library files are now serialized cleanly using Base64.
43+
- **Duplicate Collision Fix for Unnamed Schematics**: Improved schematic slot comparison (`isSameSchematic`) to perform deep tile structure checks, preventing unnamed or copied schematics of the same size from falsely colliding as duplicates.
44+
45+
### ✨ New Features & UX Enhancements:
46+
- **Instant 1-Step Mobile Preview**: Long-pressing a slot on Mobile (or right-clicking on PC) now opens the **Schematic Preview Dialog** directly in 1 single step, displaying a full visual layout, tile counts, and item build costs.
47+
- **All-in-One Preview & Slot Management**: Added a `🔄 Replace` button directly inside the Schematic Preview Dialog alongside `⚡ Select & Use`, `🎨 Icon`, and `❌ Clear`.
48+
- **Improved Mobile Picker UX**: Enlarged info button touch targets (34px) and added long-press gesture support on schematic library cards to instantly preview any schematic before assigning it.
49+
50+
---
51+
3952
## 🛠️ Building & Installation
4053

4154
### Building for Desktop Testing

‎mod.hjson‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: "quick-schema"
33
author: "Seven"
44
main: "quickschema.QuickSchemaMod"
55
description: "Quick Access Favorites Bar for Mindustry Schematics! Works seamlessly on both PC and Mobile. If there an issue leave it on github."
6-
version: "1.1"
6+
version: "1.2"
77
minGameVersion: 158
88
java: true
99
hidden: true

‎src/quickschema/QuickSlotManager.java‎

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public static void load() {
3838
String b64 = data.substring(4);
3939
s = Vars.schematics.readBase64(b64);
4040
}
41-
if (s != null && !contains(s)) {
41+
if (s != null) {
4242
slots.add(s);
4343
slotIcons.add(iconKey);
4444
}
@@ -55,18 +55,26 @@ public static void save() {
5555
if (i < slots.size) {
5656
Schematic s = slots.get(i);
5757
String iconKey = i < slotIcons.size ? slotIcons.get(i) : "";
58-
if (s.file != null) {
59-
Core.settings.put("quickschema_slot_" + i, "file:" + s.file.name());
60-
} else if (s.name() != null && !s.name().isEmpty()) {
61-
Core.settings.put("quickschema_slot_" + i, "name:" + s.name());
62-
} else {
63-
try {
64-
String b64 = Vars.schematics.writeBase64(s);
65-
Core.settings.put("quickschema_slot_" + i, "b64:" + b64);
66-
} catch (Throwable t) {
67-
Core.settings.put("quickschema_slot_" + i, "");
58+
String saveData = "";
59+
if (s != null) {
60+
if (s.file != null && Vars.schematics.all().find(sc -> sc.file != null && sc.file.name().equals(s.file.name())) != null) {
61+
saveData = "file:" + s.file.name();
62+
} else if (s.name() != null && !s.name().isEmpty()
63+
&& !s.name().equalsIgnoreCase("unknown")
64+
&& !s.name().startsWith("Copied ")
65+
&& Vars.schematics.all().find(sc -> sc.name().equals(s.name())) != null) {
66+
saveData = "name:" + s.name();
67+
} else {
68+
try {
69+
String b64 = Vars.schematics.writeBase64(s);
70+
saveData = "b64:" + b64;
71+
} catch (Throwable t) {
72+
Log.err("Failed to write base64 for QuickSchema slot " + i, t);
73+
saveData = "";
74+
}
6875
}
6976
}
77+
Core.settings.put("quickschema_slot_" + i, saveData);
7078
Core.settings.put("quickschema_slot_icon_" + i, iconKey);
7179
} else {
7280
Core.settings.put("quickschema_slot_" + i, "");
@@ -154,14 +162,46 @@ public static boolean addSchematic(Schematic schematic) {
154162
return true;
155163
}
156164

165+
public static boolean isSameSchematic(Schematic a, Schematic b) {
166+
if (a == b) return true;
167+
if (a == null || b == null) return false;
168+
169+
if (a.file != null && b.file != null) {
170+
return a.file.name().equals(b.file.name());
171+
}
172+
173+
String nameA = a.name();
174+
String nameB = b.name();
175+
boolean validNameA = nameA != null && !nameA.isEmpty() && !nameA.equalsIgnoreCase("unknown") && !nameA.startsWith("Copied ");
176+
boolean validNameB = nameB != null && !nameB.isEmpty() && !nameB.equalsIgnoreCase("unknown") && !nameB.startsWith("Copied ");
177+
178+
if (validNameA && validNameB) {
179+
return nameA.equals(nameB) && a.width == b.width && a.height == b.height;
180+
}
181+
182+
if (a.width != b.width || a.height != b.height) return false;
183+
if (a.tiles == null || b.tiles == null) return a.tiles == b.tiles;
184+
if (a.tiles.size != b.tiles.size) return false;
185+
186+
for (int i = 0; i < a.tiles.size; i++) {
187+
Schematic.Stile t1 = a.tiles.get(i);
188+
Schematic.Stile t2 = b.tiles.get(i);
189+
if (t1.block != t2.block || t1.x != t2.x || t1.y != t2.y || t1.rotation != t2.rotation) {
190+
return false;
191+
}
192+
if (t1.config != null ? !t1.config.equals(t2.config) : t2.config != null) {
193+
return false;
194+
}
195+
}
196+
197+
return true;
198+
}
199+
157200
public static int findSlot(Schematic schematic) {
158201
if (schematic == null) return -1;
159202
for (int i = 0; i < slots.size; i++) {
160203
Schematic s = slots.get(i);
161-
if (s == null) continue;
162-
if (s == schematic) return i;
163-
if (s.file != null && schematic.file != null && s.file.name().equals(schematic.file.name())) return i;
164-
if (s.name() != null && s.name().equals(schematic.name()) && s.width == schematic.width && s.height == schematic.height) return i;
204+
if (isSameSchematic(s, schematic)) return i;
165205
}
166206
return -1;
167207
}

‎src/quickschema/ui/QuickBarUI.java‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,13 @@ private void setup() {
116116
.color(arc.graphics.Color.lightGray).fontScale(0.85f);
117117
}));
118118

119-
// Mouse Right Click (PC)
120-
btn.clicked(KeyCode.mouseRight, () -> showSlotMenu(index, s));
119+
// Mouse Right Click (PC) & Touch Long Press (Mobile) directly opens visual preview & slot controls
120+
btn.clicked(KeyCode.mouseRight, () -> new SchematicPreviewDialog(s, index, this::setup).show());
121121

122-
// Touch Long Press / Hold Gesture (Mobile)
123122
btn.addListener(new ElementGestureListener() {
124123
@Override
125124
public boolean longPress(Element element, float x, float y) {
126-
showSlotMenu(index, s);
125+
new SchematicPreviewDialog(s, index, QuickBarUI.this::setup).show();
127126
return true;
128127
}
129128
});

‎src/quickschema/ui/SchematicPickerDialog.java‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ private void rebuildList(Table listTable) {
106106

107107
header.button(Icon.info, Styles.clearNonei, () -> {
108108
new SchematicPreviewDialog(s, -1, onSelect).show();
109-
}).size(26f).padRight(4f);
109+
}).size(34f).padRight(4f);
110110

111111
String displayName = s.name();
112112
if (displayName.length() > 12) {
@@ -151,15 +151,23 @@ private void rebuildList(Table listTable) {
151151
.color(Color.lightGray).fontScale(0.75f).center();
152152
card.add(footer).pad(2f).row();
153153

154-
// Click card button (proper dynamic sizing to avoid card overlapping)
155-
listTable.button(btn -> btn.add(card).growX(), Styles.cleart, () -> {
154+
// Click card to assign, long-press card to preview directly on Mobile
155+
var cardBtn = listTable.button(btn -> btn.add(card).growX(), Styles.cleart, () -> {
156156
boolean success = QuickSlotManager.setSlot(targetSlot, s);
157157
if (success) {
158158
Vars.ui.showInfoToast("Assigned [" + s.name() + "] to Quick Slot " + (targetSlot + 1), 2f);
159159
hide();
160160
if (onSelect != null) onSelect.run();
161161
}
162-
}).pad(3f).growX();
162+
}).pad(3f).growX().get();
163+
164+
cardBtn.addListener(new arc.scene.event.ElementGestureListener() {
165+
@Override
166+
public boolean longPress(arc.scene.Element element, float x, float y) {
167+
new SchematicPreviewDialog(s, -1, onSelect).show();
168+
return true;
169+
}
170+
});
163171

164172
colCount++;
165173
if (colCount % cols == 0) {

‎src/quickschema/ui/SchematicPreviewDialog.java‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ private void setup() {
134134
}).show();
135135
}).size(110f, 50f).pad(4f);
136136

137+
buttons.button("🔄 Replace", Icon.refresh, Styles.cleart, () -> {
138+
hide();
139+
new SchematicPickerDialog(slotIndex, onUpdate).show();
140+
}).size(110f, 50f).pad(4f);
141+
137142
buttons.button("❌ Clear", Icon.cancel, Styles.cleart, () -> {
138143
QuickSlotManager.clearSlot(slotIndex);
139144
if (onUpdate != null) onUpdate.run();

0 commit comments

Comments
 (0)