Skip to content

Commit ed1f633

Browse files
committed
fix
1 parent 7b4b381 commit ed1f633

4 files changed

Lines changed: 297 additions & 9 deletions

File tree

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
package com.github.gtexpert.gtbm.integration.forestry.util;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.function.IntSupplier;
6+
7+
import net.bdew.gendustry.api.ApiaryModifiers;
8+
import net.minecraft.client.Minecraft;
9+
import net.minecraft.client.renderer.BufferBuilder;
10+
import net.minecraft.client.renderer.GlStateManager;
11+
import net.minecraft.client.renderer.Tessellator;
12+
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
13+
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
14+
import net.minecraft.client.resources.I18n;
15+
import net.minecraft.item.ItemStack;
16+
import net.minecraft.network.PacketBuffer;
17+
import net.minecraft.util.text.TextFormatting;
18+
import net.minecraftforge.fml.relauncher.Side;
19+
import net.minecraftforge.fml.relauncher.SideOnly;
20+
21+
import gregtech.api.gui.IRenderContext;
22+
import gregtech.api.gui.Widget;
23+
import gregtech.api.util.Position;
24+
import gregtech.api.util.Size;
25+
26+
import forestry.api.apiculture.*;
27+
import forestry.api.core.*;
28+
29+
/**
30+
* Gendustry-style bee status widget.
31+
* Displays Forestry error icons (cycled) and shows climate/bee stats on hover.
32+
*/
33+
public class WidgetBeeStatus extends Widget {
34+
35+
private static final int SYNC_TOOLTIP = 0;
36+
private static final int SYNC_ERRORS = 1;
37+
38+
private final IBeeHousing housing;
39+
private final IBeeRoot beeRoot;
40+
private final ApiaryModifiers modifiers;
41+
private final IntSupplier euPerTickSupplier;
42+
43+
// Client-side synced data
44+
private List<String> clientTooltip = new ArrayList<>();
45+
private List<Short> clientErrorIds = new ArrayList<>();
46+
47+
// Server-side change tracking
48+
private int lastTooltipHash = Integer.MIN_VALUE;
49+
private int lastErrorHash = Integer.MIN_VALUE;
50+
51+
public WidgetBeeStatus(int x, int y, IBeeHousing housing, IBeeRoot beeRoot, ApiaryModifiers modifiers,
52+
IntSupplier euPerTickSupplier) {
53+
super(new Position(x, y), new Size(16, 16));
54+
this.housing = housing;
55+
this.beeRoot = beeRoot;
56+
this.modifiers = modifiers;
57+
this.euPerTickSupplier = euPerTickSupplier;
58+
}
59+
60+
// ---- Server-side: sync ----
61+
62+
@Override
63+
public void detectAndSendChanges() {
64+
if (housing.getWorldObj() == null) return;
65+
66+
// Sync error IDs (for icon display)
67+
IErrorLogic errorLogic = housing.getErrorLogic();
68+
List<Short> errorIds = new ArrayList<>();
69+
for (IErrorState error : errorLogic.getErrorStates()) {
70+
errorIds.add(error.getID());
71+
}
72+
int errorHash = errorIds.hashCode();
73+
if (errorHash != lastErrorHash) {
74+
lastErrorHash = errorHash;
75+
writeUpdateInfo(SYNC_ERRORS, buf -> {
76+
buf.writeVarInt(errorIds.size());
77+
for (short id : errorIds) {
78+
buf.writeShort(id);
79+
}
80+
});
81+
}
82+
83+
// Sync tooltip lines
84+
List<String> tooltip = buildTooltipLines();
85+
int tooltipHash = tooltip.hashCode();
86+
if (tooltipHash != lastTooltipHash) {
87+
lastTooltipHash = tooltipHash;
88+
writeUpdateInfo(SYNC_TOOLTIP, buf -> {
89+
buf.writeVarInt(tooltip.size());
90+
for (String line : tooltip) {
91+
buf.writeString(line);
92+
}
93+
});
94+
}
95+
}
96+
97+
private List<String> buildTooltipLines() {
98+
List<String> lines = new ArrayList<>();
99+
100+
// Error descriptions (red)
101+
IErrorLogic errorLogic = housing.getErrorLogic();
102+
for (IErrorState error : errorLogic.getErrorStates()) {
103+
lines.add(TextFormatting.RED + error.getUnlocalizedDescription());
104+
}
105+
106+
// Energy
107+
lines.add("gtbm.bee.label.energy\t" + euPerTickSupplier.getAsInt());
108+
109+
// Temperature & Humidity (send enum name for client-side localization)
110+
EnumTemperature temp = housing.getTemperature();
111+
EnumHumidity hum = housing.getHumidity();
112+
lines.add("gtbm.bee.label.temperature\t" + temp.getName().toLowerCase());
113+
lines.add("gtbm.bee.label.humidity\t" + hum.getName().toLowerCase());
114+
115+
// Bee stats
116+
IBeeHousingInventory inv = housing.getBeeInventory();
117+
if (beeRoot != null && !inv.getQueen().isEmpty()) {
118+
IBee bee = beeRoot.getMember(inv.getQueen());
119+
if (bee != null && bee.isAnalyzed()) {
120+
IBeeGenome genome = bee.getGenome();
121+
lines.add("gtbm.bee.label.production\t" +
122+
String.format("%.0f%%", 100F * modifiers.production * genome.getSpeed()));
123+
lines.add("gtbm.bee.label.flowering\t" +
124+
String.format("%.0f%%", modifiers.flowering * genome.getFlowering()));
125+
lines.add("gtbm.bee.label.lifespan\t" +
126+
String.format("%.0f%%", 100F * modifiers.lifespan * genome.getLifespan()));
127+
var t = genome.getTerritory();
128+
lines.add("gtbm.bee.label.territory\t" + String.format("%.0f x %.0f x %.0f",
129+
t.getX() * modifiers.territory, t.getY() * modifiers.territory,
130+
t.getZ() * modifiers.territory));
131+
}
132+
}
133+
134+
return lines;
135+
}
136+
137+
// ---- Client-side: receive ----
138+
139+
@Override
140+
public void readUpdateInfo(int id, PacketBuffer buf) {
141+
if (id == SYNC_ERRORS) {
142+
int count = buf.readVarInt();
143+
clientErrorIds = new ArrayList<>();
144+
for (int i = 0; i < count; i++) {
145+
clientErrorIds.add(buf.readShort());
146+
}
147+
} else if (id == SYNC_TOOLTIP) {
148+
int count = buf.readVarInt();
149+
clientTooltip = new ArrayList<>();
150+
for (int i = 0; i < count; i++) {
151+
clientTooltip.add(buf.readString(512));
152+
}
153+
}
154+
}
155+
156+
// ---- Client-side: render icon ----
157+
158+
@Override
159+
@SideOnly(Side.CLIENT)
160+
public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) {
161+
if (clientErrorIds.isEmpty()) return;
162+
163+
Position pos = getPosition();
164+
Minecraft mc = Minecraft.getMinecraft();
165+
mc.getTextureManager().bindTexture(ForestryAPI.textureManager.getGuiTextureMap());
166+
GlStateManager.color(1, 1, 1, 1);
167+
GlStateManager.enableBlend();
168+
GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
169+
170+
// Cycle through error icons (same as Gendustry: 40 tick interval)
171+
int index = (int) ((mc.world.getTotalWorldTime() / 40) % clientErrorIds.size());
172+
short errorId = clientErrorIds.get(index);
173+
IErrorState errorState = ForestryAPI.errorStateRegistry.getErrorState(errorId);
174+
if (errorState != null) {
175+
TextureAtlasSprite sprite = errorState.getSprite();
176+
if (sprite != null) {
177+
drawAtlasSprite(pos.x, pos.y, 16, 16, sprite);
178+
}
179+
}
180+
}
181+
182+
@SideOnly(Side.CLIENT)
183+
private static void drawAtlasSprite(int x, int y, int width, int height, TextureAtlasSprite sprite) {
184+
Tessellator tessellator = Tessellator.getInstance();
185+
BufferBuilder buffer = tessellator.getBuffer();
186+
buffer.begin(7, DefaultVertexFormats.POSITION_TEX);
187+
buffer.pos(x, y + height, 0).tex(sprite.getMinU(), sprite.getMaxV()).endVertex();
188+
buffer.pos(x + width, y + height, 0).tex(sprite.getMaxU(), sprite.getMaxV()).endVertex();
189+
buffer.pos(x + width, y, 0).tex(sprite.getMaxU(), sprite.getMinV()).endVertex();
190+
buffer.pos(x, y, 0).tex(sprite.getMinU(), sprite.getMinV()).endVertex();
191+
tessellator.draw();
192+
}
193+
194+
// ---- Client-side: render tooltip ----
195+
196+
@Override
197+
@SideOnly(Side.CLIENT)
198+
public void drawInForeground(int mouseX, int mouseY) {
199+
if (!isMouseOverElement(mouseX, mouseY)) return;
200+
if (clientTooltip.isEmpty()) return;
201+
202+
List<String> tooltip = new ArrayList<>();
203+
for (String line : clientTooltip) {
204+
// Lines with \t are "key\tvalue" pairs for localization
205+
int tab = line.indexOf('\t');
206+
if (tab >= 0) {
207+
String key = line.substring(0, tab);
208+
String value = line.substring(tab + 1);
209+
// Temperature/humidity values need for.gui.* localization
210+
if (key.contains("temperature") || key.contains("humidity")) {
211+
tooltip.add(I18n.format(key, I18n.format("for.gui." + value)));
212+
} else {
213+
tooltip.add(I18n.format(key, value));
214+
}
215+
} else {
216+
// Error lines (already have TextFormatting.RED + unlocalized key)
217+
if (line.startsWith(TextFormatting.RED.toString())) {
218+
String errorKey = line.substring(TextFormatting.RED.toString().length());
219+
tooltip.add(TextFormatting.RED + I18n.format(errorKey));
220+
} else {
221+
tooltip.add(line);
222+
}
223+
}
224+
}
225+
226+
if (!tooltip.isEmpty()) {
227+
drawHoveringText(ItemStack.EMPTY, tooltip, 200, mouseX, mouseY);
228+
}
229+
}
230+
}

src/main/java/com/github/gtexpert/gtbm/integration/gendustry/metatileentities/MetaTileEntityIndustrialApiary.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,9 @@ public void readFromNBT(NBTTagCompound data) {
164164

165165
// ---- GUI ----
166166
// Based on Gendustry Industrial Apiary layout, adapted for GT controls.
167-
// 176x180: Content(y=18-54) | Controls(y=76) | PlayerInv(y=98)
167+
// 176x179: Content(y=18-66) | Controls(y=75) | PlayerInv(y=97)
168168

169-
private static final int Y_OFFSET = 14;
169+
private static final int Y_OFFSET = 13;
170170

171171
@Override
172172
protected ModularUI createUI(EntityPlayer player) {
@@ -179,23 +179,27 @@ protected ModularUI createUI(EntityPlayer player) {
179179
// Title
180180
builder.widget(new LabelWidget(5, 5, getMetaFullName()));
181181

182-
// Queen slot (x=7, aligned with AutoOutput button)
183-
builder.widget(new SlotWidget(importItems, 0, 7, 18, true, true, false)
182+
// Queen slot (x=7, aligned with AutoOutput button, shift-clickable)
183+
builder.widget(new SlotWidget(importItems, 0, 7, 18, true, true, true)
184184
.setBackgroundTexture(GuiTextures.SLOT));
185185
builder.widget(new ImageWidget(8, 19, 16, 16, GTBMGuiTextures.QUEEN_OVERLAY));
186186

187-
// Drone slot (y=36, aligned with upgrade and output middle row)
188-
builder.widget(new SlotWidget(importItems, 1, 7, 36, true, true, false)
187+
// Drone slot (y=36, aligned with upgrade and output middle row, shift-clickable)
188+
builder.widget(new SlotWidget(importItems, 1, 7, 36, true, true, true)
189189
.setBackgroundTexture(GuiTextures.SLOT));
190190
builder.widget(new ImageWidget(8, 37, 16, 16, GTBMGuiTextures.DRONE_OVERLAY));
191191

192+
// Bee status indicator (below bee slots, Gendustry-style error icon + stats tooltip)
193+
builder.widget(new com.github.gtexpert.gtbm.integration.forestry.util.WidgetBeeStatus(
194+
8, 56, this, getLogic().getBeeRoot(), getModifiers(), getLogic()::getEUPerTick));
195+
192196
// Progress bar (centered above upgrade slots)
193197
builder.widget(new ProgressWidget(getLogic()::getBeeProgress, 60, 18, 20, 20,
194198
GuiTextures.PROGRESS_BAR_ARROW, ProgressWidget.MoveType.HORIZONTAL));
195199

196-
// Upgrade slots 1x4 (y=36, same row as drone and output middle)
200+
// Upgrade slots 1x4 (y=36, same row as drone and output middle, shift-clickable)
197201
for (int i = 0; i < UPGRADE_SLOT_COUNT; i++) {
198-
builder.widget(new SlotWidget(upgradeInventory, i, 34 + i * 18, 36, true, true, false)
202+
builder.widget(new SlotWidget(upgradeInventory, i, 34 + i * 18, 36, true, true, true)
199203
.setBackgroundTexture(GuiTextures.SLOT));
200204
builder.widget(new ImageWidget(35 + i * 18, 37, 16, 16, GTBMGuiTextures.UPGRADE_OVERLAY));
201205
}
@@ -228,7 +232,7 @@ protected ModularUI createUI(EntityPlayer player) {
228232
.setButtonTexture(GuiTextures.BUTTON_OVERCLOCK));
229233

230234
// Charger slot
231-
builder.widget(new SlotWidget(chargerInventory, 0, 79, 62 + Y_OFFSET, true, true, false)
235+
builder.widget(new SlotWidget(chargerInventory, 0, 79, 62 + Y_OFFSET, true, true, true)
232236
.setBackgroundTexture(GuiTextures.SLOT, GuiTextures.CHARGER_OVERLAY)
233237
.setTooltipText("gregtech.gui.charger_slot.tooltip",
234238
GTValues.VNF[getTier()], GTValues.VNF[getTier()]));
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,28 @@
11
gtbm.tooltip.warn.disabled_item=§l§dThis item is disabled!!
2+
3+
# Industrial Apiary
4+
gtbm.machine.industrial_apiary.lv.name=Basic Industrial Apiary
5+
gtbm.machine.industrial_apiary.lv.tooltip=BEES GOES BRRRR/n§dAuthor:§f @tier940
6+
gtbm.machine.industrial_apiary.mv.name=Advanced Industrial Apiary
7+
gtbm.machine.industrial_apiary.mv.tooltip=BEES GOES BRRRR/n§dAuthor:§f @tier940
8+
gtbm.machine.industrial_apiary.hv.name=Advanced Industrial Apiary II
9+
gtbm.machine.industrial_apiary.hv.tooltip=BEES GOES BRRRR/n§dAuthor:§f @tier940
10+
gtbm.machine.industrial_apiary.ev.name=Advanced Industrial Apiary III
11+
gtbm.machine.industrial_apiary.ev.tooltip=BEES GOES BRRRR/n§dAuthor:§f @tier940
12+
gtbm.machine.industrial_apiary.iv.name=Elite Industrial Apiary
13+
gtbm.machine.industrial_apiary.iv.tooltip=BEES GOES BRRRR/n§dAuthor:§f @tier940
14+
gtbm.machine.industrial_apiary.luv.name=Elite Industrial Apiary II
15+
gtbm.machine.industrial_apiary.luv.tooltip=BEES GOES BRRRR/n§dAuthor:§f @tier940
16+
gtbm.machine.industrial_apiary.zpm.name=Elite Industrial Apiary III
17+
gtbm.machine.industrial_apiary.zpm.tooltip=BEES GOES BRRRR/n§dAuthor:§f @tier940
18+
gtbm.machine.industrial_apiary.uv.name=Ultimate Industrial Apiary
19+
gtbm.machine.industrial_apiary.uv.tooltip=BEES GOES BRRRR/n§dAuthor:§f @tier940
20+
21+
# Bee Status Widget
22+
gtbm.bee.label.energy=Energy Required: %s EU/t
23+
gtbm.bee.label.temperature=Temperature: %s
24+
gtbm.bee.label.humidity=Humidity: %s
25+
gtbm.bee.label.production=Production Modifier: %s
26+
gtbm.bee.label.flowering=Flowering Chance: %s
27+
gtbm.bee.label.lifespan=Lifespan Modifier: %s
28+
gtbm.bee.label.territory=Territory: %s
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,28 @@
11
gtbm.tooltip.warn.disabled_item=§l§dこのアイテムは無効化されています!!
2+
3+
# Industrial Apiary
4+
gtbm.machine.industrial_apiary.lv.name=基本型工業用養蜂箱
5+
gtbm.machine.industrial_apiary.lv.tooltip=ミツバチ殿様のおな~り~/n§d作者:§f @tier940
6+
gtbm.machine.industrial_apiary.mv.name=発展型工業用養蜂箱
7+
gtbm.machine.industrial_apiary.mv.tooltip=ミツバチ殿様のおな~り~/n§d作者:§f @tier940
8+
gtbm.machine.industrial_apiary.hv.name=発展型工業用養蜂箱 II
9+
gtbm.machine.industrial_apiary.hv.tooltip=ミツバチ殿様のおな~り~/n§d作者:§f @tier940
10+
gtbm.machine.industrial_apiary.ev.name=発展型工業用養蜂箱 III
11+
gtbm.machine.industrial_apiary.ev.tooltip=ミツバチ殿様のおな~り~/n§d作者:§f @tier940
12+
gtbm.machine.industrial_apiary.iv.name=精鋭型工業用養蜂箱
13+
gtbm.machine.industrial_apiary.iv.tooltip=ミツバチ殿様のおな~り~/n§d作者:§f @tier940
14+
gtbm.machine.industrial_apiary.luv.name=精鋭型工業用養蜂箱 II
15+
gtbm.machine.industrial_apiary.luv.tooltip=ミツバチ殿様のおな~り~/n§d作者:§f @tier940
16+
gtbm.machine.industrial_apiary.zpm.name=精鋭型工業用養蜂箱 III
17+
gtbm.machine.industrial_apiary.zpm.tooltip=ミツバチ殿様のおな~り~/n§d作者:§f @tier940
18+
gtbm.machine.industrial_apiary.uv.name=究極型工業用養蜂箱
19+
gtbm.machine.industrial_apiary.uv.tooltip=ミツバチ殿様のおな~り~/n§d作者:§f @tier940
20+
21+
# Bee Status Widget
22+
gtbm.bee.label.energy=消費電力: %s EU/t
23+
gtbm.bee.label.temperature=気温: %s
24+
gtbm.bee.label.humidity=湿度: %s
25+
gtbm.bee.label.production=生産速度: %s
26+
gtbm.bee.label.flowering=受粉確率: %s
27+
gtbm.bee.label.lifespan=寿命補正: %s
28+
gtbm.bee.label.territory=活動範囲: %s

0 commit comments

Comments
 (0)