Skip to content

Commit 71dcc51

Browse files
committed
Chore : Fix Prisma Can UX / UI
1 parent 09a8829 commit 71dcc51

File tree

9 files changed

+359
-63
lines changed

9 files changed

+359
-63
lines changed

src/generated/resources/assets/cosmiccore/lang/en_ud.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,10 @@
579579
"cosmiccore.gui.stellar.show_modules": "ןoɹʇuoƆ ǝןnpoW ʍoɥS",
580580
"cosmiccore.gui.stellar.show_star": "ʍǝıΛ ɹɐʇS ʍoɥS",
581581
"cosmiccore.item.linked_terminal.boundTo": "%s oʇ punoᗺ",
582+
"cosmiccore.item.spraycan.actionbar.color": "%s :ɹoןoƆ uɐƆ ʎɐɹdS",
583+
"cosmiccore.item.spraycan.gui.solvent": ")ɹoןoƆ dıɹʇS( ʇuǝʌןoS",
584+
"cosmiccore.item.spraycan.gui.title": "uɐƆ ʎɐɹdS ɔıʇɐɯsıɹԀ",
585+
"cosmiccore.item.spraycan.locked": "pǝʞɔoן sı uɐƆ ʎɐɹdS",
582586
"cosmiccore.item.spraycan.tooltip.current_color": "%s :ɹoןoƆ ʇuǝɹɹnƆ",
583587
"cosmiccore.item.spraycan.tooltip.lclick": "ɹoןoɔ ǝןɔʎƆ8§ :ʞɔıןƆ ʇɟǝꞀㄣ§",
584588
"cosmiccore.item.spraycan.tooltip.lclick_sneak": "ɹoןoɔ ǝןɔʎƆ8§ :ʞɐǝuS + ʞɔıןƆ ʇɟǝꞀㄣ§",
@@ -1305,7 +1309,7 @@
13051309
"item.cosmiccore.hydraulic_boots": "sʇooᗺ sɹǝʇʇoɹʇǝqoן⅁ ɔıןnɐɹpʎH",
13061310
"item.cosmiccore.industrial_drone": "ǝuoɹᗡ ןɐıɹʇsnpuI",
13071311
"item.cosmiccore.inert_fungal_spores": "sǝɹodS ןɐbunℲ ʇɹǝuI",
1308-
"item.cosmiccore.infinite_spray_can": "uɐƆ ʎɐɹdS ǝʇıuıɟuIן§",
1312+
"item.cosmiccore.infinite_spray_can": "uɐƆ ʎɐɹdS ɔıʇɐɯsıɹԀן§",
13091313
"item.cosmiccore.intermediate_gene_kit": "ʇıʞ ǝuǝ⅁ ǝʇɐıpǝɯɹǝʇuI",
13101314
"item.cosmiccore.iv_radio_module": "ǝןnpoW oıpɐᴚ ΛI",
13111315
"item.cosmiccore.iv_wildfire_core": "ǝɹoƆ ǝɹıɟpןıM ΛI",

src/generated/resources/assets/cosmiccore/lang/en_us.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,10 @@
579579
"cosmiccore.gui.stellar.show_modules": "Show Module Control",
580580
"cosmiccore.gui.stellar.show_star": "Show Star View",
581581
"cosmiccore.item.linked_terminal.boundTo": "Bound to %s",
582+
"cosmiccore.item.spraycan.actionbar.color": "Spray Can Color: %s",
583+
"cosmiccore.item.spraycan.gui.solvent": "Solvent (Strip Color)",
584+
"cosmiccore.item.spraycan.gui.title": "Prismatic Spray Can",
585+
"cosmiccore.item.spraycan.locked": "Spray Can is locked",
582586
"cosmiccore.item.spraycan.tooltip.current_color": "Current Color: %s",
583587
"cosmiccore.item.spraycan.tooltip.lclick": "§4Left Click: §8Cycle color",
584588
"cosmiccore.item.spraycan.tooltip.lclick_sneak": "§4Left Click + Sneak: §8Cycle color",
@@ -1305,7 +1309,7 @@
13051309
"item.cosmiccore.hydraulic_boots": "Hydraulic Globetrotters Boots",
13061310
"item.cosmiccore.industrial_drone": "Industrial Drone",
13071311
"item.cosmiccore.inert_fungal_spores": "Inert Fungal Spores",
1308-
"item.cosmiccore.infinite_spray_can": "§lInfinite Spray Can",
1312+
"item.cosmiccore.infinite_spray_can": "§lPrismatic Spray Can",
13091313
"item.cosmiccore.intermediate_gene_kit": "Intermediate Gene Kit",
13101314
"item.cosmiccore.iv_radio_module": "IV Radio Module",
13111315
"item.cosmiccore.iv_wildfire_core": "IV Wildfire Core",

src/generated/resources/assets/cosmiccore/sounds.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,15 @@
9898
],
9999
"subtitle": "cosmiccore.subtitle.orbital_forge"
100100
},
101+
"shake": {
102+
"sounds": [
103+
{
104+
"type": "file",
105+
"name": "cosmiccore:shake"
106+
}
107+
],
108+
"subtitle": "cosmiccore.subtitle.shake"
109+
},
101110
"vorax": {
102111
"sounds": [
103112
{
Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
package com.ghostipedia.cosmiccore.client.gui;
2+
3+
import com.ghostipedia.cosmiccore.common.data.CosmicSounds;
4+
import com.ghostipedia.cosmiccore.common.item.behavior.ExtendedDyeColor;
5+
import com.ghostipedia.cosmiccore.common.item.behavior.InfiniteSprayCanBehavior;
6+
7+
import net.minecraft.client.Minecraft;
8+
import net.minecraft.client.gui.GuiGraphics;
9+
import net.minecraft.client.gui.screens.Screen;
10+
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
11+
import net.minecraft.network.chat.Component;
12+
import net.minecraft.world.entity.player.Player;
13+
14+
public class SprayCanScreen extends Screen {
15+
16+
private static final int GUI_WIDTH = 176;
17+
private static final int GUI_HEIGHT = 90;
18+
private static final int BUTTON_SIZE = 18;
19+
private static final int GRID_COLS = 8;
20+
private static final int GRID_ROWS = 2;
21+
private static final int PADDING = 8;
22+
23+
private static final int BG_TOP = 0xFF080c14;
24+
private static final int BG_BOTTOM = 0xFF040608;
25+
private static final int GRID_COLOR = 0x0A4080FF;
26+
private static final int BORDER_COLOR = 0xFF304060;
27+
private static final int ACCENT_COLOR = 0xFF4080C0;
28+
private static final int BUTTON_BG = 0xC0101018;
29+
private static final int BUTTON_BORDER = 0xFF405070;
30+
private static final int BUTTON_HOVER = 0xFF6090D0;
31+
32+
private final Player player;
33+
private final InfiniteSprayCanBehavior behavior;
34+
35+
private int guiLeft;
36+
private int guiTop;
37+
private int hoveredColorIndex = -1;
38+
39+
public SprayCanScreen(Player player, InfiniteSprayCanBehavior behavior) {
40+
super(Component.translatable("cosmiccore.item.spraycan.gui.title"));
41+
this.player = player;
42+
this.behavior = behavior;
43+
}
44+
45+
@Override
46+
protected void init() {
47+
super.init();
48+
guiLeft = (width - GUI_WIDTH) / 2;
49+
guiTop = (height - GUI_HEIGHT) / 2;
50+
}
51+
52+
@Override
53+
public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) {
54+
renderBackground(graphics);
55+
drawBackground(graphics);
56+
drawColorGrid(graphics, mouseX, mouseY);
57+
drawSolventButton(graphics, mouseX, mouseY);
58+
drawCurrentColor(graphics);
59+
drawTooltip(graphics, mouseX, mouseY);
60+
super.render(graphics, mouseX, mouseY, partialTick);
61+
}
62+
63+
private void drawBackground(GuiGraphics graphics) {
64+
// Gradient background
65+
for (int row = 0; row < GUI_HEIGHT; row++) {
66+
float progress = (float) row / GUI_HEIGHT;
67+
int color = lerpColor(BG_TOP, BG_BOTTOM, progress);
68+
graphics.fill(guiLeft, guiTop + row, guiLeft + GUI_WIDTH, guiTop + row + 1, color);
69+
}
70+
71+
// Grid pattern
72+
int spacing = 10;
73+
for (int gx = guiLeft + spacing; gx < guiLeft + GUI_WIDTH; gx += spacing) {
74+
graphics.fill(gx, guiTop, gx + 1, guiTop + GUI_HEIGHT, GRID_COLOR);
75+
}
76+
for (int gy = guiTop + spacing; gy < guiTop + GUI_HEIGHT; gy += spacing) {
77+
graphics.fill(guiLeft, gy, guiLeft + GUI_WIDTH, gy + 1, GRID_COLOR);
78+
}
79+
80+
// Border
81+
drawBorder(graphics, guiLeft, guiTop, GUI_WIDTH, GUI_HEIGHT, BORDER_COLOR);
82+
83+
// Corner accents
84+
drawCornerAccents(graphics, guiLeft, guiTop, GUI_WIDTH, GUI_HEIGHT, ACCENT_COLOR);
85+
86+
// Title
87+
var font = Minecraft.getInstance().font;
88+
Component title = getTitle();
89+
int titleWidth = font.width(title);
90+
int titleX = guiLeft + (GUI_WIDTH - titleWidth) / 2;
91+
graphics.drawString(font, title, titleX, guiTop + 4, ACCENT_COLOR, true);
92+
}
93+
94+
private void drawColorGrid(GuiGraphics graphics, int mouseX, int mouseY) {
95+
hoveredColorIndex = -1;
96+
int startX = guiLeft + PADDING;
97+
int startY = guiTop + 18;
98+
99+
for (int i = 0; i < 16; i++) {
100+
ExtendedDyeColor dyeColor = ExtendedDyeColor.values()[i];
101+
int col = i % GRID_COLS;
102+
int row = i / GRID_COLS;
103+
int x = startX + col * BUTTON_SIZE + col * 2;
104+
int y = startY + row * BUTTON_SIZE + row * 2;
105+
106+
boolean hovered = mouseX >= x && mouseX < x + BUTTON_SIZE && mouseY >= y && mouseY < y + BUTTON_SIZE;
107+
boolean selected = behavior.getColor() == dyeColor;
108+
109+
if (hovered) {
110+
hoveredColorIndex = i;
111+
}
112+
113+
drawColorButton(graphics, x, y, dyeColor, hovered, selected);
114+
}
115+
}
116+
117+
private void drawColorButton(GuiGraphics graphics, int x, int y, ExtendedDyeColor color, boolean hovered,
118+
boolean selected) {
119+
// Button background
120+
graphics.fill(x, y, x + BUTTON_SIZE, y + BUTTON_SIZE, BUTTON_BG);
121+
122+
// Border
123+
int borderColor = selected ? ACCENT_COLOR : (hovered ? BUTTON_HOVER : BUTTON_BORDER);
124+
drawBorder(graphics, x, y, BUTTON_SIZE, BUTTON_SIZE, borderColor);
125+
126+
// Color fill (inner area)
127+
int innerPad = 2;
128+
int dyeRgb = color.getTextColor();
129+
int fillColor = 0xFF000000 | dyeRgb;
130+
graphics.fill(x + innerPad, y + innerPad, x + BUTTON_SIZE - innerPad, y + BUTTON_SIZE - innerPad, fillColor);
131+
}
132+
133+
private void drawSolventButton(GuiGraphics graphics, int mouseX, int mouseY) {
134+
// Align to rightmost column of the grid
135+
int gridWidth = GRID_COLS * BUTTON_SIZE + (GRID_COLS - 1) * 2;
136+
int x = guiLeft + PADDING + gridWidth - BUTTON_SIZE;
137+
int y = guiTop + GUI_HEIGHT - 28;
138+
139+
boolean hovered = mouseX >= x && mouseX < x + BUTTON_SIZE && mouseY >= y && mouseY < y + BUTTON_SIZE;
140+
boolean selected = behavior.getColor() == ExtendedDyeColor.SOLVENT;
141+
142+
if (hovered) {
143+
hoveredColorIndex = 16; // Solvent index
144+
}
145+
146+
// Button background
147+
graphics.fill(x, y, x + BUTTON_SIZE, y + BUTTON_SIZE, BUTTON_BG);
148+
149+
// Border
150+
int borderColor = selected ? ACCENT_COLOR : (hovered ? BUTTON_HOVER : BUTTON_BORDER);
151+
drawBorder(graphics, x, y, BUTTON_SIZE, BUTTON_SIZE, borderColor);
152+
153+
// X pattern for solvent
154+
int innerPad = 4;
155+
int lineColor = 0xFFCC4444;
156+
// Draw X
157+
for (int i = 0; i < BUTTON_SIZE - innerPad * 2; i++) {
158+
graphics.fill(x + innerPad + i, y + innerPad + i, x + innerPad + i + 1, y + innerPad + i + 2, lineColor);
159+
graphics.fill(x + BUTTON_SIZE - innerPad - i - 1, y + innerPad + i, x + BUTTON_SIZE - innerPad - i,
160+
y + innerPad + i + 2, lineColor);
161+
}
162+
}
163+
164+
private void drawCurrentColor(GuiGraphics graphics) {
165+
var font = Minecraft.getInstance().font;
166+
int y = guiTop + 18 + GRID_ROWS * (BUTTON_SIZE + 2) + 4;
167+
168+
ExtendedDyeColor current = behavior.getColor();
169+
String colorName = current != null ? current.name().replace('_', ' ') : "NONE";
170+
int textColor = getReadableTextColor(current);
171+
172+
String label = "Color: ";
173+
graphics.drawString(font, label, guiLeft + PADDING, y, 0xFFAAAAAA, false);
174+
graphics.drawString(font, colorName, guiLeft + PADDING + font.width(label), y, textColor, false);
175+
}
176+
177+
private int getReadableTextColor(ExtendedDyeColor color) {
178+
if (color == null || color == ExtendedDyeColor.SOLVENT) {
179+
return 0xFFFFFFFF;
180+
}
181+
// Black and other dark colors need a lighter display color
182+
if (color == ExtendedDyeColor.BLACK) {
183+
return 0xFF666666;
184+
}
185+
return 0xFF000000 | color.getTextColor();
186+
}
187+
188+
private void drawTooltip(GuiGraphics graphics, int mouseX, int mouseY) {
189+
if (hoveredColorIndex < 0) return;
190+
191+
Component tooltip;
192+
if (hoveredColorIndex == 16) {
193+
tooltip = Component.translatable("cosmiccore.item.spraycan.gui.solvent");
194+
} else {
195+
String colorName = ExtendedDyeColor.values()[hoveredColorIndex].name().replace('_', ' ');
196+
tooltip = Component.literal(colorName);
197+
}
198+
199+
graphics.renderTooltip(Minecraft.getInstance().font, tooltip, mouseX, mouseY);
200+
}
201+
202+
@Override
203+
public boolean mouseClicked(double mouseX, double mouseY, int button) {
204+
if (button == 0) {
205+
int clickedIndex = getColorIndexAt((int) mouseX, (int) mouseY);
206+
if (clickedIndex >= 0) {
207+
ExtendedDyeColor newColor;
208+
if (clickedIndex == 16) {
209+
newColor = ExtendedDyeColor.SOLVENT;
210+
} else {
211+
newColor = ExtendedDyeColor.values()[clickedIndex];
212+
}
213+
behavior.setColor(newColor);
214+
behavior.sendColorToTag(player, newColor);
215+
Minecraft.getInstance().getSoundManager().play(
216+
SimpleSoundInstance.forUI(CosmicSounds.SHAKE_CAN.getMainEvent(), 1.0f, 1.0f));
217+
return true;
218+
}
219+
}
220+
return super.mouseClicked(mouseX, mouseY, button);
221+
}
222+
223+
private int getColorIndexAt(int mouseX, int mouseY) {
224+
int startX = guiLeft + PADDING;
225+
int startY = guiTop + 18;
226+
227+
// Check color grid
228+
for (int i = 0; i < 16; i++) {
229+
int col = i % GRID_COLS;
230+
int row = i / GRID_COLS;
231+
int x = startX + col * BUTTON_SIZE + col * 2;
232+
int y = startY + row * BUTTON_SIZE + row * 2;
233+
234+
if (mouseX >= x && mouseX < x + BUTTON_SIZE && mouseY >= y && mouseY < y + BUTTON_SIZE) {
235+
return i;
236+
}
237+
}
238+
239+
// Check solvent button (aligned to rightmost column)
240+
int gridWidth = GRID_COLS * BUTTON_SIZE + (GRID_COLS - 1) * 2;
241+
int solventX = guiLeft + PADDING + gridWidth - BUTTON_SIZE;
242+
int solventY = guiTop + GUI_HEIGHT - 28;
243+
if (mouseX >= solventX && mouseX < solventX + BUTTON_SIZE && mouseY >= solventY &&
244+
mouseY < solventY + BUTTON_SIZE) {
245+
return 16;
246+
}
247+
248+
return -1;
249+
}
250+
251+
@Override
252+
public boolean isPauseScreen() {
253+
return false;
254+
}
255+
256+
private void drawBorder(GuiGraphics graphics, int x, int y, int w, int h, int color) {
257+
graphics.fill(x, y, x + w, y + 1, color); // Top
258+
graphics.fill(x, y + h - 1, x + w, y + h, color); // Bottom
259+
graphics.fill(x, y, x + 1, y + h, color); // Left
260+
graphics.fill(x + w - 1, y, x + w, y + h, color); // Right
261+
}
262+
263+
private void drawCornerAccents(GuiGraphics graphics, int x, int y, int w, int h, int color) {
264+
int len = 12;
265+
int thickness = 2;
266+
int accentAlpha = (color & 0x00FFFFFF) | 0x60000000;
267+
268+
// Top-left
269+
graphics.fill(x, y, x + len, y + thickness, accentAlpha);
270+
graphics.fill(x, y, x + thickness, y + len, accentAlpha);
271+
// Top-right
272+
graphics.fill(x + w - len, y, x + w, y + thickness, accentAlpha);
273+
graphics.fill(x + w - thickness, y, x + w, y + len, accentAlpha);
274+
// Bottom-left
275+
graphics.fill(x, y + h - thickness, x + len, y + h, accentAlpha);
276+
graphics.fill(x, y + h - len, x + thickness, y + h, accentAlpha);
277+
// Bottom-right
278+
graphics.fill(x + w - len, y + h - thickness, x + w, y + h, accentAlpha);
279+
graphics.fill(x + w - thickness, y + h - len, x + w, y + h, accentAlpha);
280+
}
281+
282+
private int lerpColor(int c1, int c2, float t) {
283+
int a1 = (c1 >> 24) & 0xFF, a2 = (c2 >> 24) & 0xFF;
284+
int r1 = (c1 >> 16) & 0xFF, r2 = (c2 >> 16) & 0xFF;
285+
int g1 = (c1 >> 8) & 0xFF, g2 = (c2 >> 8) & 0xFF;
286+
int b1 = c1 & 0xFF, b2 = c2 & 0xFF;
287+
288+
int a = (int) (a1 + (a2 - a1) * t);
289+
int r = (int) (r1 + (r2 - r1) * t);
290+
int g = (int) (g1 + (g2 - g1) * t);
291+
int b = (int) (b1 + (b2 - b1) * t);
292+
293+
return (a << 24) | (r << 16) | (g << 8) | b;
294+
}
295+
}

src/main/java/com/ghostipedia/cosmiccore/common/data/CosmicSounds.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public class CosmicSounds {
2020
public static final SoundEntry CHEMVAT = REGISTRATE.sound(CosmicCore.id("icv")).build();
2121
public static final SoundEntry VOARX = REGISTRATE.sound(CosmicCore.id("vorax")).build();
2222
public static final SoundEntry DAWN_FORGE_SFX = REGISTRATE.sound(CosmicCore.id("dawnforge")).build();
23+
public static final SoundEntry SHAKE_CAN = REGISTRATE.sound(CosmicCore.id("shake")).build();
2324

2425
public static void init() {}
2526
}

src/main/java/com/ghostipedia/cosmiccore/common/data/lang/CosmicLangHandler.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ public static void init(RegistrateLangProvider provider) {
415415
provider.add("cosmic.gui.wireless.energy.no.capacitor", "No Formed Capacitor");
416416
provider.add("cosmic.gui.wireless.energy.capacitor", " §bCapacitor Location:§b ");
417417

418-
replace(provider, "item.cosmiccore.infinite_spray_can", lInfinite Spray Can");
418+
replace(provider, "item.cosmiccore.infinite_spray_can", lPrismatic Spray Can");
419419

420420
// AE2 EU Display Mixin
421421
provider.add("gui.ae2.units.eu", "EU");
@@ -443,6 +443,12 @@ public static void init(RegistrateLangProvider provider) {
443443
provider.add("cosmiccore.item.spraycan.tooltip.locked", "Spraycan is locked");
444444
provider.add("cosmiccore.item.spraycan.tooltip.current_color", "Current Color: %s");
445445
provider.add("cosmiccore.item.spraycan.tooltip.solvent_mode", "Spraycan in SOLVENT mode");
446+
provider.add("cosmiccore.item.spraycan.gui.title", "Prismatic Spray Can");
447+
provider.add("cosmiccore.item.spraycan.gui.solvent", "Solvent (Strip Color)");
448+
provider.add("cosmiccore.item.spraycan.locked", "Spray Can is locked");
449+
provider.add("cosmiccore.item.spraycan.actionbar.color", "Spray Can Color: %s");
450+
provider.add("cosmiccore.item.spraycan.now_locked", "Spray Can locked");
451+
provider.add("cosmiccore.item.spraycan.now_unlocked", "Spray Can unlocked");
446452

447453
provider.add("cosmiccore.item.linked_terminal.boundTo", "Bound to %s");
448454
provider.add("allele.forestry.bee_species.cosmiccore.bee_oxygen", "Lofty Oxygen");

0 commit comments

Comments
 (0)