From e56b9131ab1d61cb95ec3a8599d45bdaf7365663 Mon Sep 17 00:00:00 2001 From: Han Programer <30620423+Hanprogramer@users.noreply.github.com> Date: Wed, 22 Oct 2025 07:06:18 +0700 Subject: [PATCH 1/7] Bring back power requirement --- .../client/screen/android/InventoryTab.java | 14 +++++++------- .../java/com/hanprogramer/androids/ModItems.java | 8 ++++---- .../androids/entities/android/AndroidEntity.java | 2 +- .../android/AndroidInventoryScreenHandler.java | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/client/java/com/hanprogramer/androids/client/screen/android/InventoryTab.java b/src/client/java/com/hanprogramer/androids/client/screen/android/InventoryTab.java index 2dffdda..a205b15 100644 --- a/src/client/java/com/hanprogramer/androids/client/screen/android/InventoryTab.java +++ b/src/client/java/com/hanprogramer/androids/client/screen/android/InventoryTab.java @@ -21,7 +21,7 @@ class InventoryTab extends BaseScreenTab { private static final Identifier TEXTURE = Identifier.of("androids", "textures/gui/android_inventory.png"); -// protected VerticalProgressBar progressBar; + protected VerticalProgressBar progressBar; protected SwitchWidget switchWidget; public InventoryTab(AndroidInventoryHandledScreen parent, Text title, @Nullable ItemStack iconStack, @Nullable Identifier texture) { @@ -33,7 +33,7 @@ public void build(List elements) { int i = (parent.width - parent.backgroundWidth) / 2; int j = (parent.height - parent.backgroundHeight) / 2; -// elements.add((progressBar = new VerticalProgressBar(i + 141, j + 7, 8, 72, (int) parent.entity.getTotalPower(), (int) parent.entity.getTotalCapacity()))); + elements.add((progressBar = new VerticalProgressBar(i + 141, j + 7, 8, 72, (int) parent.entity.getTotalPower(), (int) parent.entity.getTotalCapacity()))); if (parent.entity != null) { var mc = MinecraftClient.getInstance(); elements.add((switchWidget = new SwitchWidget(i + 108, j + 18, 24, 24, parent.entity.isOn(), (widget, value) -> { @@ -62,11 +62,11 @@ public void handledScreenTick() { super.handledScreenTick(); parent.resyncEntity(); if (parent.entity.age % 4 == 0) { -// if (progressBar != null) { -// progressBar.value = (int) parent.entity.getTotalPower(); -// progressBar.maxValue = (int) parent.entity.getTotalCapacity(); -// progressBar.update(); -// } + if (progressBar != null) { + progressBar.value = (int) parent.entity.getTotalPower(); + progressBar.maxValue = (int) parent.entity.getTotalCapacity(); + progressBar.update(); + } if (switchWidget != null) switchWidget.isActive = parent.entity.isOn(); } diff --git a/src/main/java/com/hanprogramer/androids/ModItems.java b/src/main/java/com/hanprogramer/androids/ModItems.java index 2b8ec87..515dad7 100644 --- a/src/main/java/com/hanprogramer/androids/ModItems.java +++ b/src/main/java/com/hanprogramer/androids/ModItems.java @@ -38,10 +38,10 @@ public static void initialize() { // entries.add(HEADSET); NOT IMPLEMENTED YET // entries.add(CABLE); // entries.add(ModBlocks.CONNECTOR_BLOCK.getRight()); -// entries.add(BATTERY_0.createFullyCharged()); -// entries.add(BATTERY_1.createFullyCharged()); -// entries.add(BATTERY_2.createFullyCharged()); -// entries.add(BATTERY_3.createFullyCharged()); + entries.add(BATTERY_0.createFullyCharged()); + entries.add(BATTERY_1.createFullyCharged()); + entries.add(BATTERY_2.createFullyCharged()); + entries.add(BATTERY_3.createFullyCharged()); // entries.add(REMOTE); entries.add(ANDROID_SPAWNER.create(AndroidMaterial.WOOD)); entries.add(ANDROID_SPAWNER.create(AndroidMaterial.STONE)); diff --git a/src/main/java/com/hanprogramer/androids/entities/android/AndroidEntity.java b/src/main/java/com/hanprogramer/androids/entities/android/AndroidEntity.java index bb5560b..15e9d0d 100644 --- a/src/main/java/com/hanprogramer/androids/entities/android/AndroidEntity.java +++ b/src/main/java/com/hanprogramer/androids/entities/android/AndroidEntity.java @@ -412,7 +412,7 @@ public boolean isOn() { public void setOn(boolean value) { if (getWorld().isClient) return; -// if (dataTracker.get(totalPower) <= 0) value = false; + if (dataTracker.get(totalPower) <= 0) value = false; // Cancel any running tick and clear state if (tickFnFuture != null) { diff --git a/src/main/java/com/hanprogramer/androids/entities/android/AndroidInventoryScreenHandler.java b/src/main/java/com/hanprogramer/androids/entities/android/AndroidInventoryScreenHandler.java index 9c06fe6..ec38859 100644 --- a/src/main/java/com/hanprogramer/androids/entities/android/AndroidInventoryScreenHandler.java +++ b/src/main/java/com/hanprogramer/androids/entities/android/AndroidInventoryScreenHandler.java @@ -185,7 +185,7 @@ public void createInventoryTabSlots() { // Battery slots for (m = 0; m < 4; m++) { -// inventoryScreenSlots.add(new BatterySlot(inventory, m + 11, 152, 8 + (18 * m))); + inventoryScreenSlots.add(new BatterySlot(inventory, m + 11, 152, 8 + (18 * m))); } } From e7527b1c946923537fbdea2b445c9e3a239dfecb Mon Sep 17 00:00:00 2001 From: Han Programer <30620423+Hanprogramer@users.noreply.github.com> Date: Wed, 22 Oct 2025 08:41:38 +0700 Subject: [PATCH 2/7] Chargepad, Battery, Energy implementation --- .../androids/blockstates/chargepad.json | 25 +++ .../resources/assets/androids/lang/en_us.json | 5 +- .../androids/models/block/chargepad.bbmodel | 1 + .../androids/models/block/chargepad.json | 89 ++++++++++ .../assets/androids/models/block/empty.json | 4 + .../androids/textures/block/cragepad.png | Bin 0 -> 1541 bytes .../textures/gui/android_inventory.ase | Bin 1516 -> 1518 bytes .../textures/gui/android_inventory.png | Bin 1236 -> 1280 bytes .../com/hanprogramer/androids/ModBlocks.java | 49 +++++- .../com/hanprogramer/androids/ModItems.java | 7 +- .../blocks/chargepad/ChargepadBlock.java | 148 +++++++++++++++++ .../chargepad/ChargepadBlockEntity.java | 153 ++++++++++++++++++ .../entities/android/AndroidEntity.java | 5 +- .../androids/items/BatteryItem.java | 78 ++++++++- .../data/androids/recipe/battery_0.json | 19 +++ .../data/androids/recipe/battery_1.json | 19 +++ .../data/androids/recipe/battery_2.json | 19 +++ .../data/androids/recipe/chargepad.json | 19 +++ .../data/androids/recipe/solar_panel.json | 19 +++ 19 files changed, 649 insertions(+), 10 deletions(-) create mode 100644 src/client/resources/assets/androids/blockstates/chargepad.json create mode 100644 src/client/resources/assets/androids/models/block/chargepad.bbmodel create mode 100644 src/client/resources/assets/androids/models/block/chargepad.json create mode 100644 src/client/resources/assets/androids/models/block/empty.json create mode 100644 src/client/resources/assets/androids/textures/block/cragepad.png create mode 100644 src/main/java/com/hanprogramer/androids/blocks/chargepad/ChargepadBlock.java create mode 100644 src/main/java/com/hanprogramer/androids/blocks/chargepad/ChargepadBlockEntity.java create mode 100644 src/main/resources/data/androids/recipe/battery_0.json create mode 100644 src/main/resources/data/androids/recipe/battery_1.json create mode 100644 src/main/resources/data/androids/recipe/battery_2.json create mode 100644 src/main/resources/data/androids/recipe/chargepad.json create mode 100644 src/main/resources/data/androids/recipe/solar_panel.json diff --git a/src/client/resources/assets/androids/blockstates/chargepad.json b/src/client/resources/assets/androids/blockstates/chargepad.json new file mode 100644 index 0000000..0f0311d --- /dev/null +++ b/src/client/resources/assets/androids/blockstates/chargepad.json @@ -0,0 +1,25 @@ +{ + "variants": { + "facing=north,half=lower": { + "model": "androids:block/chargepad", + "y": 90 + }, + "facing=east,half=lower": { + "model": "androids:block/chargepad", + "y": 180 + }, + "facing=south,half=lower": { + "model": "androids:block/chargepad", + "y": 270 + }, + "facing=west,half=lower": { + "model": "androids:block/chargepad", + "y": 0 + }, + + "facing=north,half=upper": { "model": "androids:block/empty" }, + "facing=south,half=upper": { "model": "androids:block/empty" }, + "facing=west,half=upper": { "model": "androids:block/empty" }, + "facing=east,half=upper": { "model": "androids:block/empty" } + } +} \ No newline at end of file diff --git a/src/client/resources/assets/androids/lang/en_us.json b/src/client/resources/assets/androids/lang/en_us.json index c841432..c60b265 100644 --- a/src/client/resources/assets/androids/lang/en_us.json +++ b/src/client/resources/assets/androids/lang/en_us.json @@ -15,5 +15,8 @@ "item.androids.battery_3": "Creative Battery", "item.androids.remote": "Remote", "item.androids.android_spawner": "Android", - "item.androids.block_name_tag": "Block Name Tag" + "item.androids.block_name_tag": "Block Name Tag", + + "tooltip.androids.energy": "Energy: %s / %s (%s%%)", + "block.androids.chargepad": "Charging Pad" } \ No newline at end of file diff --git a/src/client/resources/assets/androids/models/block/chargepad.bbmodel b/src/client/resources/assets/androids/models/block/chargepad.bbmodel new file mode 100644 index 0000000..0ff5784 --- /dev/null +++ b/src/client/resources/assets/androids/models/block/chargepad.bbmodel @@ -0,0 +1 @@ +{"meta":{"format_version":"5.0","model_format":"java_block","box_uv":false},"name":"chargepad","parent":"chargepad","java_block_version":"1.21.6","ambientocclusion":true,"front_gui_light":false,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"unhandled_root_fields":{},"resolution":{"width":64,"height":64},"elements":[{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[0,0,0],"to":[16,2,16],"autouv":0,"color":6,"origin":[8,1,9],"faces":{"north":{"uv":[36,36,52,38],"texture":0},"east":{"uv":[36,28,54,30],"texture":0},"south":{"uv":[38,0,54,2],"texture":0},"west":{"uv":[36,30,54,32],"texture":0},"up":{"uv":[16,18,0,0],"texture":0},"down":{"uv":[32,0,16,18],"texture":0}},"type":"cube","uuid":"5c843a3a-75d6-0290-db05-72bd25fcd9ba"},{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[0,2,0],"to":[2,30,2],"autouv":0,"color":6,"origin":[0,0,0],"faces":{"north":{"uv":[32,0,34,28],"texture":0},"east":{"uv":[32,28,34,56],"texture":0},"south":{"uv":[34,0,36,28],"texture":0},"west":{"uv":[34,28,36,56],"texture":0},"up":{"uv":[24,38,22,36],"texture":0},"down":{"uv":[26,36,24,38],"texture":0}},"type":"cube","uuid":"46f4aee4-322d-7d11-d243-b6011f334412"},{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[14,2,0],"to":[16,30,2],"autouv":0,"color":6,"origin":[14,0,0],"faces":{"north":{"uv":[0,36,2,64],"texture":0},"east":{"uv":[36,0,38,28],"texture":0},"south":{"uv":[2,36,4,64],"texture":0},"west":{"uv":[4,36,6,64],"texture":0},"up":{"uv":[28,38,26,36],"texture":0},"down":{"uv":[30,36,28,38],"texture":0}},"type":"cube","uuid":"1e4ddad7-ef31-0857-a758-4971fc4f806d"},{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[0,2,14],"to":[2,30,16],"autouv":0,"color":6,"origin":[0,0,14],"faces":{"north":{"uv":[6,36,8,64],"texture":0},"east":{"uv":[8,36,10,64],"texture":0},"south":{"uv":[10,36,12,64],"texture":0},"west":{"uv":[12,36,14,64],"texture":0},"up":{"uv":[32,38,30,36],"texture":0},"down":{"uv":[40,6,38,8],"texture":0}},"type":"cube","uuid":"006c8bde-51f6-1619-b76c-820b954b3e7d"},{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[14,2,14],"to":[16,30,16],"autouv":0,"color":6,"origin":[14,0,14],"faces":{"north":{"uv":[14,36,16,64],"texture":0},"east":{"uv":[16,36,18,64],"texture":0},"south":{"uv":[18,36,20,64],"texture":0},"west":{"uv":[20,36,22,64],"texture":0},"up":{"uv":[40,10,38,8],"texture":0},"down":{"uv":[40,10,38,12],"texture":0}},"type":"cube","uuid":"220a651b-60f8-b807-a968-da138c7947e1"},{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[0,30,0],"to":[16,32,16],"autouv":0,"color":6,"origin":[8,31,9],"faces":{"north":{"uv":[38,2,54,4],"texture":0},"east":{"uv":[36,32,54,34],"texture":0},"south":{"uv":[38,4,54,6],"texture":0},"west":{"uv":[36,34,54,36],"texture":0},"up":{"uv":[16,36,0,18],"texture":0},"down":{"uv":[32,18,16,36],"texture":0}},"type":"cube","uuid":"1521bb86-dfb8-05cc-1a4b-cf631f62e77b"}],"groups":[],"outliner":["5c843a3a-75d6-0290-db05-72bd25fcd9ba","1521bb86-dfb8-05cc-1a4b-cf631f62e77b","46f4aee4-322d-7d11-d243-b6011f334412","1e4ddad7-ef31-0857-a758-4971fc4f806d","220a651b-60f8-b807-a968-da138c7947e1","006c8bde-51f6-1619-b76c-820b954b3e7d"],"textures":[{"name":"cragepad.png","relative_path":"../../textures/block/cragepad.png","folder":"block","namespace":"androids","id":"0","group":"","width":64,"height":64,"uv_width":64,"uv_height":64,"particle":true,"use_as_default":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","pbr_channel":"color","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"ac201deb-9d22-cd27-2034-6bf0aaf41611","source":"data:image/png;base64,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"}]} \ No newline at end of file diff --git a/src/client/resources/assets/androids/models/block/chargepad.json b/src/client/resources/assets/androids/models/block/chargepad.json new file mode 100644 index 0000000..f6130b8 --- /dev/null +++ b/src/client/resources/assets/androids/models/block/chargepad.json @@ -0,0 +1,89 @@ +{ + "format_version": "1.21.6", + "credit": "Made with Blockbench", + "parent": "chargepad", + "texture_size": [64, 64], + "textures": { + "0": "androids:block/cragepad", + "particle": "androids:block/cragepad" + }, + "elements": [ + { + "from": [0, 0, 0], + "to": [16, 2, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 1, 9]}, + "faces": { + "north": {"uv": [9, 9, 13, 9.5], "texture": "#0"}, + "east": {"uv": [9, 7, 13.5, 7.5], "texture": "#0"}, + "south": {"uv": [9.5, 0, 13.5, 0.5], "texture": "#0"}, + "west": {"uv": [9, 7.5, 13.5, 8], "texture": "#0"}, + "up": {"uv": [4, 4.5, 0, 0], "texture": "#0"}, + "down": {"uv": [8, 0, 4, 4.5], "texture": "#0"} + } + }, + { + "from": [0, 30, 0], + "to": [16, 32, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 31, 9]}, + "faces": { + "north": {"uv": [9.5, 0.5, 13.5, 1], "texture": "#0"}, + "east": {"uv": [9, 8, 13.5, 8.5], "texture": "#0"}, + "south": {"uv": [9.5, 1, 13.5, 1.5], "texture": "#0"}, + "west": {"uv": [9, 8.5, 13.5, 9], "texture": "#0"}, + "up": {"uv": [4, 9, 0, 4.5], "texture": "#0"}, + "down": {"uv": [8, 4.5, 4, 9], "texture": "#0"} + } + }, + { + "from": [0, 2, 0], + "to": [2, 30, 2], + "faces": { + "north": {"uv": [8, 0, 8.5, 7], "texture": "#0"}, + "east": {"uv": [8, 7, 8.5, 14], "texture": "#0"}, + "south": {"uv": [8.5, 0, 9, 7], "texture": "#0"}, + "west": {"uv": [8.5, 7, 9, 14], "texture": "#0"}, + "up": {"uv": [6, 9.5, 5.5, 9], "texture": "#0"}, + "down": {"uv": [6.5, 9, 6, 9.5], "texture": "#0"} + } + }, + { + "from": [14, 2, 0], + "to": [16, 30, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [14, 0, 0]}, + "faces": { + "north": {"uv": [0, 9, 0.5, 16], "texture": "#0"}, + "east": {"uv": [9, 0, 9.5, 7], "texture": "#0"}, + "south": {"uv": [0.5, 9, 1, 16], "texture": "#0"}, + "west": {"uv": [1, 9, 1.5, 16], "texture": "#0"}, + "up": {"uv": [7, 9.5, 6.5, 9], "texture": "#0"}, + "down": {"uv": [7.5, 9, 7, 9.5], "texture": "#0"} + } + }, + { + "from": [14, 2, 14], + "to": [16, 30, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [14, 0, 14]}, + "faces": { + "north": {"uv": [3.5, 9, 4, 16], "texture": "#0"}, + "east": {"uv": [4, 9, 4.5, 16], "texture": "#0"}, + "south": {"uv": [4.5, 9, 5, 16], "texture": "#0"}, + "west": {"uv": [5, 9, 5.5, 16], "texture": "#0"}, + "up": {"uv": [10, 2.5, 9.5, 2], "texture": "#0"}, + "down": {"uv": [10, 2.5, 9.5, 3], "texture": "#0"} + } + }, + { + "from": [0, 2, 14], + "to": [2, 30, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 0, 14]}, + "faces": { + "north": {"uv": [1.5, 9, 2, 16], "texture": "#0"}, + "east": {"uv": [2, 9, 2.5, 16], "texture": "#0"}, + "south": {"uv": [2.5, 9, 3, 16], "texture": "#0"}, + "west": {"uv": [3, 9, 3.5, 16], "texture": "#0"}, + "up": {"uv": [8, 9.5, 7.5, 9], "texture": "#0"}, + "down": {"uv": [10, 1.5, 9.5, 2], "texture": "#0"} + } + } + ] +} \ No newline at end of file diff --git a/src/client/resources/assets/androids/models/block/empty.json b/src/client/resources/assets/androids/models/block/empty.json new file mode 100644 index 0000000..786ad42 --- /dev/null +++ b/src/client/resources/assets/androids/models/block/empty.json @@ -0,0 +1,4 @@ +{ + "ambientocclusion": false, + "elements": [] +} \ No newline at end of file diff --git a/src/client/resources/assets/androids/textures/block/cragepad.png b/src/client/resources/assets/androids/textures/block/cragepad.png new file mode 100644 index 0000000000000000000000000000000000000000..e652a1ed8c1a95b224fd20b7958af45f52a8a7c8 GIT binary patch literal 1541 zcmV+g2KxDlP)hjX;9rVoO@IFx(xtb{mprOsidZjUVD6eboV>cVL?m5CoCY;q#-zd3(5#3u>hETC@6b< zbussh<1>WNvXxnYb9fP+9A&#XW4J84ySwi5`1m-;n-|3?AjWGFT}L~;EPQ3z!`j0y z8*5esId1dJeUYq;0thUC4zUWt-Q|*i!02&U0RCJI(X6gn&H`cr2cqjB&K$we2FLWjtO(U*>i2TaHsZQR*0+#LlNz!Qub3^f!jq%>TvUpbY3;>)0nBc@v zq|Pdm%mPSo7~}hrA(%aT9%X$n#t%t`2u)r_hfIyDpn>&(GU+fVn+_w3YY2tmeW$0V zmH2?hsx62xIXXK#t3(0z`uaM_xIzU%gW1r%y**PD`M#KBYLQq7zky6@8hzbGL|~{h z)ttNj^1C0*KZ9qdxZU0{?aoJYfI_5FP>1PjomjV~H|zP$S&#aV4Tb50qGR9pn{~thU?KAjOulFx z20)EQB|h&3E0Yb<8e&&;%91D`CIi!DwZjXcNS$SnX#vdmimVug!t9Se0Pm{OF{Ua2 z!vFg2oxA?#?c1d)p-yV|0Z=T)JQZAZR+y>)GzdM<>t(`l7@t@U>vTFshv;ca@eP;g zy}>lxp=~Bxrss;r-YCw051)7J~}Eym>cWWQO5_Yz!zXi!3nN?Z7#Gk zv?|nQ0cAjv6KerXjHCdJ2;m2qo$8)XQwVp5F?+>Cm6nGQfYe-GG6ZBEUxYNr#@OIi zEVSrVBUw(CiA}I9G=|g`*MvRB<*a`F*n_LU(rh{r*Jyg3t(VQPjRU3gLM~rjF$?Hwz#ck;`FOOI12q;eDE! zhQOWSItY5J4nAHJK|X-Jta~2Fp2webTA{z~yRHh0c~s89bVymASI)f@T9*lhD?k_m zRqhFrraYM;y)k@)ixOwgsU$X5S_Gb?pY>nT9iX$ooLGO?>nrJcAVw4U}@S}LcQiV zATq1a>ExVVB_>M&pY_Dk% zB7J~d*NdU5Gr?)t5bgV>Ds2g|)8DGll&P=}Em-XRs$*p+4CFq&MDN4t>oQAXb&~1> zvP?Yf+E;JYv2uC?J^@1J|8=#1T(|8DjN~S&_91mnX+^O5UsJW0*C8*S%O!MOf87pK r{SN>D|Np{8i=_Yn00v1!K~w_(B&h>gb^(uj00000NkvXXu0mjfa@OBJ literal 0 HcmV?d00001 diff --git a/src/client/resources/assets/androids/textures/gui/android_inventory.ase b/src/client/resources/assets/androids/textures/gui/android_inventory.ase index dcbc7a29d7d3be6fef26ec5387a162a3656ef0a2..5d727392ab5cad7b8dba411497a7bac7a261c18d 100644 GIT binary patch delta 727 zcmaFE{f?XQ-9*NE#=MD*?-}n*E@afLw{+>~*q^KQ^2%FF*87v6B;9iM?-$s!yV_bm zZDOsBeqXSqJkR{UZ!ONvKll0b=jy}r_obPAmXnu{-(EK_;kwu3>!*Nd_m%gD4tKm{~de(_WX!lCx5eO+PVDiF?Xu+tM|C=|7rWW zHt!10d%^X*`~Q48t-t@zw8?SIdfM;r)Lnn=eqQ(Y-PfkOT=%>0HA}atFWk0O`F{QS zkAGY*u79ro>|RyAoqf&w$x+OP(dD}PU!Q;7^YQfi758r*d!O5Lf9KzI*Zb#1f7^XM zyJXu*6P7z4zXdto{G>&(S@*r`_LtZ~ou^z43KF=aydo^7?!F zpRm8@%r7> zHxc9#tfmrgs5N%m5vHz=-z<52{Zt5g{xf-QQ2LSgKKtD-{wfd~53`k9=JUy3tcw5vg|M{% delta 629 zcmaFI{f3+I%|ym}#+-?b?-_4RE@afL*A!HGl<%+g^2%FF*87v6B;9iM?-$s!yV_nq zZDOsReqXTVe4hD#-&&lrpZomz^ZvH|HD`04+1lCd%l&I}aNX2n>!%)HKec@2{r2|u zhqku1Z!gU(tiF5u($BZgOP~FG`+L{^{r}6Ve@lMc9b>=gsm|Q_@3!vwdhc6B@4rvg z*M8qw!FyjhPP*>r)9LYbKXv;jCo=15-{1Ln-Sz%?(cgAo&o1e%>#xc^SMl#rPPY5L z|8b9hb}x!QAAe@=*LyW}KWFPrFuEssUjFrqoVPtc z?!Nw>Ze34jWaF@L&AL_t(|obB9AZsJN9hS74=n@W(f3M+eHh{Qe^vIxA23<#5~ zi96}&_T>gA9ox9@d(JF>6?X+c!X@?Blz*KI+=piF3s{PejXa;v?tkt>(=FvdHC}KH-A55dHBZn01G7m5bRgq z7dM;D;9t)+P4ZCR~WSHJ%F_&E4?{M2WUh0o8=y+8B%`dZ3}ub;lX zVVK?kl;3}VA-3CX>AJ4GzrPP!r$(pKsdQa8${u}n{xZk;%xTn01!+7 zAeaCw+em~9t{>|LPrMmA5TbTt?a>ma-q@S^ z-E1Pzl9_sQoxQ1>Gm~)wB~BB8?!e2-%iNd1LJ7bf*lad)Ujhr|5deaj2sDsAy3XFz z&qSbsR;$%y11rXO>)*ERC<9r3GMUFjp!%5zRJpPCf3C?qCIZ#X82|(mlW_toFH8ig z*jW2N*Wc0Wr+y{^4K&u&p3kP}f zSi8wYptfzx>2w;rPK~CVdSfCGQ)@~o=kxhoN+|{}a2IyFT`8rM!{JbVzlQlCj{p!% z03etEK(O9Jz_BLYjxiL}I=SnZ3Ot>gO$D}&b$+^z!|CaG1e1{iEhN~@rUF~XI@G6k zDzJ$_)~R8g%ZWgy0*}W;AnR1Wj)_3iaR!rt0v?kP1P~n)fvi*gI!wnzAnR1Wj)_3i zF%if*)vseB&~%&ulTZUBlMn<6G|WUG>r}rE)9IZE1T``dXgnSPAeaC^FadyIy@!CN z0$ZnsbuOm@GagfctyBFv4yUK%5tASSD3dP&21TX9#@vD^5G);3p9*;H`!hE~~Xr7*)X1)~oJ_mr~xZJ?=OxFQ_%gqmyaRf_~ ffCLQ~zykdPPfwntq78L*00000NkvXXu0mjf%bBg| delta 851 zcmZqRy23fZu)fdJ#WAE}&f7a@b8kmTv|aR8_Pv?aT)-d26(AqAien>Rr1bS8H(h4* z99t&)IY{Z}yv?Wi?TmZg3r}>|x9rbq{S7>47waeJt~1~CzWVw6)QnlnIviyE`Ru)m z?dEs;uPHUz&R9`hUHyXfU^rj9v*yw%mtTg|2uVDDd0yV)&xEJ-FQxahM`$uOB?yPco8II4czw%pTcn}2?}K7amv_xj%XpCWeTH8X1L-*0*R#{2I} zU+?<#@1I@PIhk0!>6c1lr&fQt>R5fm(MEGhZjj_aFcN=g-&UN(bh%B(&!7{|~qK*JF&ZY@esd z#BdNOw1?%%ZkB{pyXu?YZ=QDCRQt1@F=F21j}hB$zx}WD;6t%DL)fXr=hjdQoBJ7n ze)wBgzkhY4!uJkUX`rHjq)^~6pyEZ_R>;srN_8K>@=F|EC6YsSiSP-GADWCdmw z=goo{jB)Yt^0l06rZDIn$lG51MRh}v9HYXFUI*o!?m9DpRIb_VlhZ1%{CIJHTkh0W zoo!-kC-*uShrj-JJL-r#*c@FgpmO7|*Z+Q3KQT6A>J7=xKJR|JEbH$7sNx)!D0%5d ztrJna-hC`K-{WAX zC;*MT$&qsI&2s};>BciN|H?==E=yLPV7YmIvhsxzi1$o@-g|bYj_PS8rJ1vq+0Q?pr`NKxjwvH9E>5mS^FwVM!?nU{=HKkG?0gTe~DWM4fyrqNi diff --git a/src/main/java/com/hanprogramer/androids/ModBlocks.java b/src/main/java/com/hanprogramer/androids/ModBlocks.java index c8e56f8..f48fb9a 100644 --- a/src/main/java/com/hanprogramer/androids/ModBlocks.java +++ b/src/main/java/com/hanprogramer/androids/ModBlocks.java @@ -1,5 +1,7 @@ package com.hanprogramer.androids; +import com.hanprogramer.androids.blocks.chargepad.ChargepadBlock; +import com.hanprogramer.androids.blocks.chargepad.ChargepadBlockEntity; import com.hanprogramer.androids.blocks.computer.ComputerBlock; import com.hanprogramer.androids.blocks.computer.ComputerBlockEntity; import com.hanprogramer.androids.blocks.connector.ConnectorBlock; @@ -8,12 +10,18 @@ import com.hanprogramer.androids.blocks.solar.SolarPanelBlockEntity; import com.hanprogramer.androids.util.RegistryHelper; import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder; +import net.minecraft.block.AbstractBlock; +import net.minecraft.block.Block; import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.block.enums.DoubleBlockHalf; import net.minecraft.item.BlockItem; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; +import net.minecraft.sound.BlockSoundGroup; import net.minecraft.util.Identifier; import net.minecraft.util.Pair; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; import team.reborn.energy.api.EnergyStorage; public class ModBlocks { @@ -22,21 +30,50 @@ public class ModBlocks { // Solar Panel block + entity public static final Pair SOLAR_PANEL = RegistryHelper.registerBlockWithItem("solar_panel", SolarPanelBlock::new); + public static final Pair CHARGEPAD = RegistryHelper.registerBlockWithItem( + "chargepad", + ChargepadBlock::new, + AbstractBlock.Settings.create().strength(3.0f).sounds(BlockSoundGroup.METAL) + ); + + public static final BlockEntityType CHARGEPAD_BLOCK_ENTITY = + Registry.register( + Registries.BLOCK_ENTITY_TYPE, + Identifier.of(AndroidsCraft.MOD_ID, "chargepad"), + FabricBlockEntityTypeBuilder.create(ChargepadBlockEntity::new, ModBlocks.CHARGEPAD.getLeft()).build() + ); + public static void initialize() { - } - public static void initEnergyLookups() { + // Attach sided energy to the BlockEntity (LOWER half) EnergyStorage.SIDED.registerForBlockEntity( - (be, side) -> be.getEnergyStorage(side), + (ChargepadBlockEntity be, Direction side) -> be.externalEnergyView, + CHARGEPAD_BLOCK_ENTITY + ); + // Optional: if you want upper connections to also work, redirect upper queries to the lower BE. + // This uses the Block API lookup (EnergyStorage.SIDED is a BlockApiLookup). + EnergyStorage.SIDED.registerForBlocks((world, pos, state, be, side) -> { + if (state.isOf(ModBlocks.CHARGEPAD.getLeft()) && state.get(ChargepadBlock.HALF) == DoubleBlockHalf.UPPER) { + BlockPos below = pos.down(); + if (world.getBlockEntity(below) instanceof ChargepadBlockEntity lower) { + return lower.externalEnergyView; + } + } + return null; + }, ModBlocks.CHARGEPAD.getLeft()); + + + EnergyStorage.SIDED.registerForBlockEntity( + SolarPanelBlockEntity::getEnergyStorage, SOLAR_PANEL_BLOCK_ENTITY ); - } public static final BlockEntityType COMPUTER_BLOCK_ENTITY = + } + + public static final BlockEntityType COMPUTER_BLOCK_ENTITY = Registry.register(Registries.BLOCK_ENTITY_TYPE, Identifier.of(AndroidsCraft.MOD_ID, "computer_block_entity"), FabricBlockEntityTypeBuilder.create(ComputerBlockEntity::new, COMPUTER_BLOCK.getLeft()).build()); - - public static final BlockEntityType CONNECTOR_BLOCK_ENTITY_BLOCK_ENTITY_TYPE = Registry.register(Registries.BLOCK_ENTITY_TYPE, Identifier.of(AndroidsCraft.MOD_ID, "connector_block_entity"), FabricBlockEntityTypeBuilder.create(ConnectorBlockEntity::new, CONNECTOR_BLOCK.getLeft()).build()); diff --git a/src/main/java/com/hanprogramer/androids/ModItems.java b/src/main/java/com/hanprogramer/androids/ModItems.java index 515dad7..d344813 100644 --- a/src/main/java/com/hanprogramer/androids/ModItems.java +++ b/src/main/java/com/hanprogramer/androids/ModItems.java @@ -38,6 +38,10 @@ public static void initialize() { // entries.add(HEADSET); NOT IMPLEMENTED YET // entries.add(CABLE); // entries.add(ModBlocks.CONNECTOR_BLOCK.getRight()); + entries.add(BATTERY_0.createEmptyCharged()); + entries.add(BATTERY_1.createEmptyCharged()); + entries.add(BATTERY_2.createEmptyCharged()); + entries.add(BATTERY_3.createEmptyCharged()); entries.add(BATTERY_0.createFullyCharged()); entries.add(BATTERY_1.createFullyCharged()); entries.add(BATTERY_2.createFullyCharged()); @@ -52,7 +56,8 @@ public static void initialize() { entries.add(ANDROID_SPAWNER.create(AndroidMaterial.OBSIDIAN)); entries.add(ANDROID_SPAWNER.create(AndroidMaterial.NETHERITE)); -// entries.add(ModBlocks.SOLAR_PANEL.getRight()); + entries.add(ModBlocks.SOLAR_PANEL.getRight()); + entries.add(ModBlocks.CHARGEPAD.getRight()); entries.add(BLOCK_NAME_TAG); }) .build(); diff --git a/src/main/java/com/hanprogramer/androids/blocks/chargepad/ChargepadBlock.java b/src/main/java/com/hanprogramer/androids/blocks/chargepad/ChargepadBlock.java new file mode 100644 index 0000000..333d69d --- /dev/null +++ b/src/main/java/com/hanprogramer/androids/blocks/chargepad/ChargepadBlock.java @@ -0,0 +1,148 @@ +package com.hanprogramer.androids.blocks.chargepad; + +import com.mojang.serialization.MapCodec; +import net.minecraft.block.*; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.BlockEntityTicker; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.block.enums.DoubleBlockHalf; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.item.ItemStack; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.state.StateManager; +import net.minecraft.state.property.EnumProperty; +import net.minecraft.state.property.Properties; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.random.Random; +import net.minecraft.world.World; +import net.minecraft.world.WorldView; +import net.minecraft.world.tick.ScheduledTickView; +import org.jetbrains.annotations.Nullable; + +public class ChargepadBlock extends BlockWithEntity { + public static final EnumProperty FACING = Properties.HORIZONTAL_FACING; + public static final EnumProperty HALF = Properties.DOUBLE_BLOCK_HALF; + + public ChargepadBlock(Settings settings) { + super(settings.noCollision()); + setDefaultState(getDefaultState().with(FACING, Direction.NORTH).with(HALF, DoubleBlockHalf.LOWER)); + } + + @Override + protected MapCodec getCodec() { + return createCodec(ChargepadBlock::new); + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + builder.add(FACING, HALF); + } + + @Override + public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) { + BlockPos pos = ctx.getBlockPos(); + World world = ctx.getWorld(); + // Ensure there is space above + if (pos.getY() < world.getTopYInclusive() - 1 && world.getBlockState(pos.up()).canReplace(ctx)) { + return getDefaultState() + .with(FACING, ctx.getHorizontalPlayerFacing().getOpposite()) + .with(HALF, DoubleBlockHalf.LOWER); + } + return null; + } + + @Override + public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack item) { + // Place the UPPER half + world.setBlockState(pos.up(), state.with(HALF, DoubleBlockHalf.UPPER), Block.NOTIFY_ALL); + } + // Remove the other half when a player breaks one half. + @Override + public BlockState onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) { + DoubleBlockHalf half = state.get(HALF); + BlockPos otherPos = (half == DoubleBlockHalf.LOWER) ? pos.up() : pos.down(); + BlockState other = world.getBlockState(otherPos); + + // Only read HALF after verifying it's your block + if (other.isOf(this)) { + world.setBlockState(otherPos, Blocks.AIR.getDefaultState(), Block.NOTIFY_ALL | Block.SKIP_DROPS); + } + + return super.onBreak(world, pos, state, player); + } + + // Keep the two halves consistent regardless of how the block is removed. + + + @Override + protected BlockState getStateForNeighborUpdate(BlockState state, + WorldView world, + ScheduledTickView tickView, + BlockPos pos, + Direction direction, + BlockPos neighborPos, + BlockState neighborState, + Random random) { + var half = state.get(HALF); + + if (half == DoubleBlockHalf.LOWER && direction == Direction.UP) { + // Lower requires an upper directly above + if (!neighborState.isOf(this) || neighborState.get(HALF) != DoubleBlockHalf.UPPER) { + return Blocks.AIR.getDefaultState(); + } + } else if (half == DoubleBlockHalf.UPPER && direction == Direction.DOWN) { + // Upper requires a lower directly below + if (!neighborState.isOf(this) || neighborState.get(HALF) != DoubleBlockHalf.LOWER) { + return Blocks.AIR.getDefaultState(); + } + } + + return super.getStateForNeighborUpdate(state, world, tickView, pos, direction, neighborPos, neighborState, random); + } + + @Override + public BlockRenderType getRenderType(BlockState state) { + return BlockRenderType.MODEL; // render using block model JSON + } + + @Override + public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) { + if (state.get(HALF) == DoubleBlockHalf.LOWER) { + // lower just needs to be placeable; upper will be validated when it’s set + return super.canPlaceAt(state, world, pos); + } else { + // upper must sit above its lower + BlockState below = world.getBlockState(pos.down()); + return below.isOf(this) && below.get(HALF) == DoubleBlockHalf.LOWER; + } + } + + + @Override + protected void onStateReplaced(BlockState newState, ServerWorld world, BlockPos pos, boolean moved) { + // Lower half is the one that owns a BE in our design; removing at pos is safe regardless: + world.removeBlockEntity(pos); // NOP if there isn't one (e.g., upper half) + super.onStateReplaced(newState, world, pos, moved); + } + + // Only the LOWER half has a BlockEntity + @Override + public @Nullable BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + if (state.get(HALF) == DoubleBlockHalf.LOWER) { + return new ChargepadBlockEntity(pos, state); + } + return null; + } + + @Override + public @Nullable BlockEntityTicker getTicker(World world, BlockState state, BlockEntityType type) { + return (w, p, s, be) -> { + if (!w.isClient && be instanceof ChargepadBlockEntity machine) { + machine.serverTick(); + } + }; + } +} \ No newline at end of file diff --git a/src/main/java/com/hanprogramer/androids/blocks/chargepad/ChargepadBlockEntity.java b/src/main/java/com/hanprogramer/androids/blocks/chargepad/ChargepadBlockEntity.java new file mode 100644 index 0000000..0adc556 --- /dev/null +++ b/src/main/java/com/hanprogramer/androids/blocks/chargepad/ChargepadBlockEntity.java @@ -0,0 +1,153 @@ +package com.hanprogramer.androids.blocks.chargepad; + +import com.hanprogramer.androids.ModBlocks; +import net.fabricmc.fabric.api.transfer.v1.context.ContainerItemContext; +import net.fabricmc.fabric.api.transfer.v1.item.InventoryStorage; +import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant; +import net.fabricmc.fabric.api.transfer.v1.storage.base.SingleSlotStorage; +import net.fabricmc.fabric.api.transfer.v1.transaction.Transaction; +import net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.entity.InventoryOwner; +import net.minecraft.inventory.Inventory; +import net.minecraft.item.ItemStack; +import net.minecraft.storage.ReadView; +import net.minecraft.storage.WriteView; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; +import team.reborn.energy.api.EnergyStorage; +import team.reborn.energy.api.base.SimpleEnergyStorage; + +public class ChargepadBlockEntity extends BlockEntity { + + // Tune these + public static final long CAPACITY = 100_000; + public static final long MAX_INSERT_FROM_GRID = 4000; // incoming from cables/generators + public static final long INTERNAL_CHARGE_RATE = 2000; // per tick to items + + // Internal storage supports extract so we can feed items + private final SimpleEnergyStorage internalEnergy = new SimpleEnergyStorage( + CAPACITY, MAX_INSERT_FROM_GRID, INTERNAL_CHARGE_RATE + ) { + @Override + protected void onFinalCommit() { + markDirty(); + } + }; + + // External view shown to the world: sink-only (no extraction) + public final EnergyStorage externalEnergyView = new EnergyStorage() { + @Override + public boolean supportsInsertion() { + return true; + } + + @Override + public boolean supportsExtraction() { + return false; + } + + @Override + public long insert(long maxAmount, TransactionContext tx) { + return internalEnergy.insert(maxAmount, tx); + } + + @Override + public long extract(long maxAmount, TransactionContext tx) { + return 0; + } + + @Override + public long getAmount() { + return internalEnergy.getAmount(); + } + + @Override + public long getCapacity() { + return internalEnergy.getCapacity(); + } + }; + + public ChargepadBlockEntity(BlockPos pos, BlockState state) { + super(ModBlocks.CHARGEPAD_BLOCK_ENTITY, pos, state); + } + + public void serverTick() { + if (this.world == null || this.world.isClient) return; + if (internalEnergy.getAmount() <= 0) return; + + // Run every 4 ticks to cut cost; tweak as you like + if ((world.getTime() & 3L) != 0) return; + + // 1x2 axis-aligned box covering the block’s footprint + Box area = new Box(pos.getX(), pos.getY(), pos.getZ(), + pos.getX() + 1, pos.getY() + 2, pos.getZ() + 1); + + boolean chargedSomething = false; + + for (var entity : world.getOtherEntities(null, area, e -> e instanceof InventoryOwner)) { + Inventory inv = ((InventoryOwner) entity).getInventory(); + if (inv == null || inv.size() == 0) continue; + + // Fabric Transfer view over the inventory (lets us get per-slot contexts) + var invStorage = InventoryStorage.of(inv, null); + + // Simple policy: scan slots in order and charge the first compatible item + for (int i = 0; i < inv.size(); i++) { + SingleSlotStorage slot = invStorage.getSlot(i); + if (slot.isResourceBlank() || slot.getAmount() <= 0) continue; + + // Context that can mutate the slot’s stack + ContainerItemContext itemCtx = ContainerItemContext.ofSingleSlot(slot); + // A lightweight stack with correct variant/nbt is enough for the lookup + ItemStack probe = slot.getResource().toStack(1); + + // Ask TR Energy for the item storage + EnergyStorage itemEnergy = EnergyStorage.ITEM.find(probe, itemCtx); + if (itemEnergy == null) continue; + + long toSend = Math.min(INTERNAL_CHARGE_RATE, internalEnergy.getAmount()); + if (toSend <= 0) break; + + try (Transaction tx = Transaction.openOuter()) { + // Insert into the item first to learn how much it accepts this tick + long accepted = itemEnergy.insert(toSend, tx); + if (accepted <= 0) { + // Nothing accepted; try next slot + tx.abort(); + continue; + } + // Extract that exact amount from our internal store + long extracted = internalEnergy.extract(accepted, tx); + if (extracted > 0) { + tx.commit(); + chargedSomething = true; + } else { + tx.abort(); + } + } + + if (chargedSomething) break; + } + + if (chargedSomething) break; // one item per tick batch + } + } + + // Helper to avoid building massive ItemStacks from large slots (visual only) + private int stackLimitForDisplay() { + return 64; + } + + // Persist energy with 1.21.8 custom data views + @Override + public void writeData(WriteView out) { + out.putLong("energy", internalEnergy.getAmount()); + } + + @Override + public void readData(ReadView in) { + internalEnergy.amount = Math.min(in.getLong("energy", 0L), CAPACITY); + } +} \ No newline at end of file diff --git a/src/main/java/com/hanprogramer/androids/entities/android/AndroidEntity.java b/src/main/java/com/hanprogramer/androids/entities/android/AndroidEntity.java index 15e9d0d..02a3ea4 100644 --- a/src/main/java/com/hanprogramer/androids/entities/android/AndroidEntity.java +++ b/src/main/java/com/hanprogramer/androids/entities/android/AndroidEntity.java @@ -493,7 +493,10 @@ public void setOn(boolean value) { public void tick() { super.tick(); if (!getWorld().isClient()) { - if (isOn()) { + if (dataTracker.get(totalPower) <= 0) { + setOn(false); + } + else if (isOn()) { ensureJs(); if (isWaitingStart) return; diff --git a/src/main/java/com/hanprogramer/androids/items/BatteryItem.java b/src/main/java/com/hanprogramer/androids/items/BatteryItem.java index 5f9152b..2a18c3b 100644 --- a/src/main/java/com/hanprogramer/androids/items/BatteryItem.java +++ b/src/main/java/com/hanprogramer/androids/items/BatteryItem.java @@ -1,16 +1,29 @@ package com.hanprogramer.androids.items; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.transfer.v1.context.ContainerItemContext; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.LoreComponent; +import net.minecraft.component.type.TooltipDisplayComponent; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.item.tooltip.TooltipData; +import net.minecraft.item.tooltip.TooltipType; +import net.minecraft.text.Style; import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.minecraft.util.math.MathHelper; +import team.reborn.energy.api.EnergyStorage; import team.reborn.energy.api.base.SimpleEnergyItem; import java.util.List; +import java.util.Locale; +import java.util.Optional; +import java.util.function.Consumer; public class BatteryItem extends Item implements SimpleEnergyItem { - public int capacity, maxInput, maxOutput; + public long capacity, maxInput, maxOutput; public BatteryItem(Item.Settings settings, int capacity, int maxInput, int maxOutput) { super(settings @@ -45,4 +58,67 @@ public ItemStack createFullyCharged() { setStoredEnergy(stack, this.capacity); return stack; } + public ItemStack createEmptyCharged() { + var stack = new ItemStack(this); + setStoredEnergy(stack, 0); + return stack; + } + + @Override + public Optional getTooltipData(ItemStack stack) { + var result = super.getTooltipData(stack); + + return result; + } + + @Override + @Environment(EnvType.CLIENT) + public void appendTooltip(ItemStack stack, + TooltipContext context, + TooltipDisplayComponent displayComponent, + Consumer textConsumer, + TooltipType type) { + var itemCtx = ContainerItemContext.withConstant(stack); // read-only context + var storage = EnergyStorage.ITEM.find(stack, itemCtx); + if (storage != null) { + long amount = storage.getAmount(); + long cap = Math.max(1, storage.getCapacity()); + int pct = (int) ((amount * 100L) / cap); + + textConsumer.accept(Text.translatable( + "tooltip.androids.energy", + formatEnergy(amount), formatEnergy(cap), pct + ).styled(s -> s.withColor(Formatting.AQUA))); + } + } + + private static String formatEnergy(long value) { + // Simple formatting; customize as you like (k, M, etc.) + return String.format(Locale.ROOT, "%,d E", value); + } + + @Override + public boolean isItemBarVisible(ItemStack stack) { + var ctx = ContainerItemContext.withConstant(stack); + var s = EnergyStorage.ITEM.find(stack, ctx); + return s != null;// && s.getAmount() < s.getCapacity(); + } + + @Override + public int getItemBarStep(ItemStack stack) { + var ctx = ContainerItemContext.withConstant(stack); + var s = EnergyStorage.ITEM.find(stack, ctx); + if (s == null || s.getCapacity() == 0) return 0; + double pct = (double) s.getAmount() / (double) s.getCapacity(); + return MathHelper.floor(pct * 13.0); + } + + @Override + public int getItemBarColor(ItemStack stack) { + var ctx = ContainerItemContext.withConstant(stack); + var s = EnergyStorage.ITEM.find(stack, ctx); + if (s == null || s.getCapacity() == 0) return 0x00FFFF; + float pct = (float) ((double) s.getAmount() / (double) s.getCapacity()); + return MathHelper.hsvToRgb(pct / 3.0F, 1.0F, 1.0F); + } } diff --git a/src/main/resources/data/androids/recipe/battery_0.json b/src/main/resources/data/androids/recipe/battery_0.json new file mode 100644 index 0000000..79f3ca1 --- /dev/null +++ b/src/main/resources/data/androids/recipe/battery_0.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "#g#", + "iRi", + "#g#" + ], + "key": { + "#": "minecraft:coal", + "g": "minecraft:gold_ingot", + "i": "minecraft:iron_ingot", + "R": "minecraft:redstone" + }, + "result": { + "id": "androids:battery_0", + "count": 1 + }, + "group": "battery" +} \ No newline at end of file diff --git a/src/main/resources/data/androids/recipe/battery_1.json b/src/main/resources/data/androids/recipe/battery_1.json new file mode 100644 index 0000000..1c301ea --- /dev/null +++ b/src/main/resources/data/androids/recipe/battery_1.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "#g#", + "iRi", + "#g#" + ], + "key": { + "#": "androids:battery_0", + "g": "minecraft:gold_ingot", + "i": "minecraft:iron_ingot", + "R": "minecraft:redstone" + }, + "result": { + "id": "androids:battery_1", + "count": 1 + }, + "group": "battery" +} \ No newline at end of file diff --git a/src/main/resources/data/androids/recipe/battery_2.json b/src/main/resources/data/androids/recipe/battery_2.json new file mode 100644 index 0000000..ca1cad8 --- /dev/null +++ b/src/main/resources/data/androids/recipe/battery_2.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "#g#", + "iRi", + "#g#" + ], + "key": { + "#": "androids:battery_1", + "g": "minecraft:gold_ingot", + "i": "minecraft:iron_ingot", + "R": "minecraft:redstone" + }, + "result": { + "id": "androids:battery_2", + "count": 1 + }, + "group": "battery" +} \ No newline at end of file diff --git a/src/main/resources/data/androids/recipe/chargepad.json b/src/main/resources/data/androids/recipe/chargepad.json new file mode 100644 index 0000000..db09773 --- /dev/null +++ b/src/main/resources/data/androids/recipe/chargepad.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "#H#", + "gRg", + "#H#" + ], + "key": { + "#": "minecraft:iron_block", + "H": "minecraft:heavy_weighted_pressure_plate", + "g": "minecraft:gold_ingot", + "R": "minecraft:redstone" + }, + "result": { + "id": "androids:chargepad", + "count": 1 + }, + "group": "chargepad" +} \ No newline at end of file diff --git a/src/main/resources/data/androids/recipe/solar_panel.json b/src/main/resources/data/androids/recipe/solar_panel.json new file mode 100644 index 0000000..06045ac --- /dev/null +++ b/src/main/resources/data/androids/recipe/solar_panel.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "###", + "gRg", + "IgI" + ], + "key": { + "#": "minecraft:lapis_lazuli", + "g": "minecraft:gold_ingot", + "R": "minecraft:redstone", + "I": "minecraft:iron_block" + }, + "result": { + "id": "androids:solar_panel", + "count": 1 + }, + "group": "androids_spawner" +} \ No newline at end of file From 618d59ed0ad7217e9c9a8dfdcb2b60a2bd9c92d6 Mon Sep 17 00:00:00 2001 From: Han Programer <30620423+Hanprogramer@users.noreply.github.com> Date: Wed, 22 Oct 2025 08:46:19 +0700 Subject: [PATCH 3/7] Fixed bugs with android inventory not syncing --- src/client/resources/assets/androids/lang/en_us.json | 3 ++- .../resources/assets/androids/models/item/chargepad.json | 3 +++ .../entities/android/AndroidInventoryScreenHandler.java | 1 - 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 src/client/resources/assets/androids/models/item/chargepad.json diff --git a/src/client/resources/assets/androids/lang/en_us.json b/src/client/resources/assets/androids/lang/en_us.json index c60b265..34a56d4 100644 --- a/src/client/resources/assets/androids/lang/en_us.json +++ b/src/client/resources/assets/androids/lang/en_us.json @@ -18,5 +18,6 @@ "item.androids.block_name_tag": "Block Name Tag", "tooltip.androids.energy": "Energy: %s / %s (%s%%)", - "block.androids.chargepad": "Charging Pad" + "block.androids.chargepad": "Charging Pad", + "item.androids.chargepad": "Charging Pad" } \ No newline at end of file diff --git a/src/client/resources/assets/androids/models/item/chargepad.json b/src/client/resources/assets/androids/models/item/chargepad.json new file mode 100644 index 0000000..5fe5dd6 --- /dev/null +++ b/src/client/resources/assets/androids/models/item/chargepad.json @@ -0,0 +1,3 @@ +{ + "parent": "androids:block/computer_block" +} \ No newline at end of file diff --git a/src/main/java/com/hanprogramer/androids/entities/android/AndroidInventoryScreenHandler.java b/src/main/java/com/hanprogramer/androids/entities/android/AndroidInventoryScreenHandler.java index ec38859..e72d6cb 100644 --- a/src/main/java/com/hanprogramer/androids/entities/android/AndroidInventoryScreenHandler.java +++ b/src/main/java/com/hanprogramer/androids/entities/android/AndroidInventoryScreenHandler.java @@ -105,7 +105,6 @@ public boolean onButtonClick(PlayerEntity player, int id) { assert entity != null; if (id == SWITCH_BUTTON_ON) { entity.setOn(true); - slots.clear(); } else if (id == SWITCH_BUTTON_OFF) { entity.setOn(false); } else if (id == LOGS_CLEAR_BUTTON) { From 045879b1e6cceab1ab628ca9d6e0ca5a6b0a0084 Mon Sep 17 00:00:00 2001 From: Han Programer <30620423+Hanprogramer@users.noreply.github.com> Date: Wed, 22 Oct 2025 10:02:38 +0700 Subject: [PATCH 4/7] Solar panel & chargepad impleemntation --- .../screen/widgets/VerticalProgressBar.java | 4 +- .../assets/androids/items/chargepad.json | 6 +++ .../androids/models/block/chargepad.bbmodel | 2 +- .../androids/models/block/chargepad.json | 32 +++++++++++++- .../androids/models/item/chargepad.json | 2 +- .../com/hanprogramer/androids/ModBlocks.java | 44 ++++++++++++++----- .../blocks/chargepad/ChargepadBlock.java | 8 ++++ .../chargepad/ChargepadBlockEntity.java | 4 +- .../blocks/solar/SolarPanelBlockEntity.java | 8 ++-- 9 files changed, 88 insertions(+), 22 deletions(-) create mode 100644 src/client/resources/assets/androids/items/chargepad.json diff --git a/src/client/java/com/hanprogramer/androids/client/screen/widgets/VerticalProgressBar.java b/src/client/java/com/hanprogramer/androids/client/screen/widgets/VerticalProgressBar.java index ed3f7e2..4aa2b2c 100644 --- a/src/client/java/com/hanprogramer/androids/client/screen/widgets/VerticalProgressBar.java +++ b/src/client/java/com/hanprogramer/androids/client/screen/widgets/VerticalProgressBar.java @@ -46,8 +46,8 @@ protected void renderWidget(DrawContext context, int mouseX, int mouseY, float d if (maxValue > 0 && value > 0) { var ph = (int) (this.height * percentage); context.fill(RenderPipelines.GUI, - this.getX() + 1, this.getY() + ph - 1, - this.getX() + this.width - 1, this.getY() + this.height - ph + 1, + this.getX() + 1, this.getY() + this.height - ph + 1, + this.getX() + this.width - 1, this.getY() + this.height - 1, 0xAAAAFF00); } } diff --git a/src/client/resources/assets/androids/items/chargepad.json b/src/client/resources/assets/androids/items/chargepad.json new file mode 100644 index 0000000..176badf --- /dev/null +++ b/src/client/resources/assets/androids/items/chargepad.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "androids:item/chargepad" + } +} \ No newline at end of file diff --git a/src/client/resources/assets/androids/models/block/chargepad.bbmodel b/src/client/resources/assets/androids/models/block/chargepad.bbmodel index 0ff5784..dc57125 100644 --- a/src/client/resources/assets/androids/models/block/chargepad.bbmodel +++ b/src/client/resources/assets/androids/models/block/chargepad.bbmodel @@ -1 +1 @@ -{"meta":{"format_version":"5.0","model_format":"java_block","box_uv":false},"name":"chargepad","parent":"chargepad","java_block_version":"1.21.6","ambientocclusion":true,"front_gui_light":false,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"unhandled_root_fields":{},"resolution":{"width":64,"height":64},"elements":[{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[0,0,0],"to":[16,2,16],"autouv":0,"color":6,"origin":[8,1,9],"faces":{"north":{"uv":[36,36,52,38],"texture":0},"east":{"uv":[36,28,54,30],"texture":0},"south":{"uv":[38,0,54,2],"texture":0},"west":{"uv":[36,30,54,32],"texture":0},"up":{"uv":[16,18,0,0],"texture":0},"down":{"uv":[32,0,16,18],"texture":0}},"type":"cube","uuid":"5c843a3a-75d6-0290-db05-72bd25fcd9ba"},{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[0,2,0],"to":[2,30,2],"autouv":0,"color":6,"origin":[0,0,0],"faces":{"north":{"uv":[32,0,34,28],"texture":0},"east":{"uv":[32,28,34,56],"texture":0},"south":{"uv":[34,0,36,28],"texture":0},"west":{"uv":[34,28,36,56],"texture":0},"up":{"uv":[24,38,22,36],"texture":0},"down":{"uv":[26,36,24,38],"texture":0}},"type":"cube","uuid":"46f4aee4-322d-7d11-d243-b6011f334412"},{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[14,2,0],"to":[16,30,2],"autouv":0,"color":6,"origin":[14,0,0],"faces":{"north":{"uv":[0,36,2,64],"texture":0},"east":{"uv":[36,0,38,28],"texture":0},"south":{"uv":[2,36,4,64],"texture":0},"west":{"uv":[4,36,6,64],"texture":0},"up":{"uv":[28,38,26,36],"texture":0},"down":{"uv":[30,36,28,38],"texture":0}},"type":"cube","uuid":"1e4ddad7-ef31-0857-a758-4971fc4f806d"},{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[0,2,14],"to":[2,30,16],"autouv":0,"color":6,"origin":[0,0,14],"faces":{"north":{"uv":[6,36,8,64],"texture":0},"east":{"uv":[8,36,10,64],"texture":0},"south":{"uv":[10,36,12,64],"texture":0},"west":{"uv":[12,36,14,64],"texture":0},"up":{"uv":[32,38,30,36],"texture":0},"down":{"uv":[40,6,38,8],"texture":0}},"type":"cube","uuid":"006c8bde-51f6-1619-b76c-820b954b3e7d"},{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[14,2,14],"to":[16,30,16],"autouv":0,"color":6,"origin":[14,0,14],"faces":{"north":{"uv":[14,36,16,64],"texture":0},"east":{"uv":[16,36,18,64],"texture":0},"south":{"uv":[18,36,20,64],"texture":0},"west":{"uv":[20,36,22,64],"texture":0},"up":{"uv":[40,10,38,8],"texture":0},"down":{"uv":[40,10,38,12],"texture":0}},"type":"cube","uuid":"220a651b-60f8-b807-a968-da138c7947e1"},{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[0,30,0],"to":[16,32,16],"autouv":0,"color":6,"origin":[8,31,9],"faces":{"north":{"uv":[38,2,54,4],"texture":0},"east":{"uv":[36,32,54,34],"texture":0},"south":{"uv":[38,4,54,6],"texture":0},"west":{"uv":[36,34,54,36],"texture":0},"up":{"uv":[16,36,0,18],"texture":0},"down":{"uv":[32,18,16,36],"texture":0}},"type":"cube","uuid":"1521bb86-dfb8-05cc-1a4b-cf631f62e77b"}],"groups":[],"outliner":["5c843a3a-75d6-0290-db05-72bd25fcd9ba","1521bb86-dfb8-05cc-1a4b-cf631f62e77b","46f4aee4-322d-7d11-d243-b6011f334412","1e4ddad7-ef31-0857-a758-4971fc4f806d","220a651b-60f8-b807-a968-da138c7947e1","006c8bde-51f6-1619-b76c-820b954b3e7d"],"textures":[{"name":"cragepad.png","relative_path":"../../textures/block/cragepad.png","folder":"block","namespace":"androids","id":"0","group":"","width":64,"height":64,"uv_width":64,"uv_height":64,"particle":true,"use_as_default":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","pbr_channel":"color","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"ac201deb-9d22-cd27-2034-6bf0aaf41611","source":"data:image/png;base64,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"}]} \ No newline at end of file +{"meta":{"format_version":"5.0","model_format":"java_block","box_uv":false},"name":"chargepad","parent":"chargepad","java_block_version":"1.21.6","ambientocclusion":true,"front_gui_light":false,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"unhandled_root_fields":{},"resolution":{"width":64,"height":64},"elements":[{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[0,0,0],"to":[16,2,16],"autouv":0,"color":6,"origin":[8,1,9],"faces":{"north":{"uv":[36,36,52,38],"texture":0},"east":{"uv":[36,28,54,30],"texture":0},"south":{"uv":[38,0,54,2],"texture":0},"west":{"uv":[36,30,54,32],"texture":0},"up":{"uv":[16,18,0,0],"texture":0},"down":{"uv":[32,0,16,18],"texture":0}},"type":"cube","uuid":"5c843a3a-75d6-0290-db05-72bd25fcd9ba"},{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[0,2,0],"to":[2,30,2],"autouv":0,"color":6,"origin":[0,0,0],"faces":{"north":{"uv":[32,0,34,28],"texture":0},"east":{"uv":[32,28,34,56],"texture":0},"south":{"uv":[34,0,36,28],"texture":0},"west":{"uv":[34,28,36,56],"texture":0},"up":{"uv":[24,38,22,36],"texture":0},"down":{"uv":[26,36,24,38],"texture":0}},"type":"cube","uuid":"46f4aee4-322d-7d11-d243-b6011f334412"},{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[14,2,0],"to":[16,30,2],"autouv":0,"color":6,"origin":[14,0,0],"faces":{"north":{"uv":[0,36,2,64],"texture":0},"east":{"uv":[36,0,38,28],"texture":0},"south":{"uv":[2,36,4,64],"texture":0},"west":{"uv":[4,36,6,64],"texture":0},"up":{"uv":[28,38,26,36],"texture":0},"down":{"uv":[30,36,28,38],"texture":0}},"type":"cube","uuid":"1e4ddad7-ef31-0857-a758-4971fc4f806d"},{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[0,2,14],"to":[2,30,16],"autouv":0,"color":6,"origin":[0,0,14],"faces":{"north":{"uv":[6,36,8,64],"texture":0},"east":{"uv":[8,36,10,64],"texture":0},"south":{"uv":[10,36,12,64],"texture":0},"west":{"uv":[12,36,14,64],"texture":0},"up":{"uv":[32,38,30,36],"texture":0},"down":{"uv":[40,6,38,8],"texture":0}},"type":"cube","uuid":"006c8bde-51f6-1619-b76c-820b954b3e7d"},{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[14,2,14],"to":[16,30,16],"autouv":0,"color":6,"origin":[14,0,14],"faces":{"north":{"uv":[14,36,16,64],"texture":0},"east":{"uv":[16,36,18,64],"texture":0},"south":{"uv":[18,36,20,64],"texture":0},"west":{"uv":[20,36,22,64],"texture":0},"up":{"uv":[40,10,38,8],"texture":0},"down":{"uv":[40,10,38,12],"texture":0}},"type":"cube","uuid":"220a651b-60f8-b807-a968-da138c7947e1"},{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[0,30,0],"to":[16,32,16],"autouv":0,"color":6,"origin":[8,31,9],"faces":{"north":{"uv":[38,2,54,4],"texture":0},"east":{"uv":[36,32,54,34],"texture":0},"south":{"uv":[38,4,54,6],"texture":0},"west":{"uv":[36,34,54,36],"texture":0},"up":{"uv":[16,36,0,18],"texture":0},"down":{"uv":[32,18,16,36],"texture":0}},"type":"cube","uuid":"1521bb86-dfb8-05cc-1a4b-cf631f62e77b"}],"groups":[],"outliner":["5c843a3a-75d6-0290-db05-72bd25fcd9ba","1521bb86-dfb8-05cc-1a4b-cf631f62e77b","46f4aee4-322d-7d11-d243-b6011f334412","1e4ddad7-ef31-0857-a758-4971fc4f806d","220a651b-60f8-b807-a968-da138c7947e1","006c8bde-51f6-1619-b76c-820b954b3e7d"],"textures":[{"name":"cragepad.png","relative_path":"../../textures/block/cragepad.png","folder":"block","namespace":"androids","id":"0","group":"","width":64,"height":64,"uv_width":64,"uv_height":64,"particle":true,"use_as_default":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","pbr_channel":"color","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"ac201deb-9d22-cd27-2034-6bf0aaf41611","source":"data:image/png;base64,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"}],"display":{"thirdperson_righthand":{"scale":[0.3,0.3,0.3]},"thirdperson_lefthand":{"scale":[0.3,0.3,0.3]},"firstperson_righthand":{"scale":[0.3,0.3,0.3]},"firstperson_lefthand":{"scale":[0.3,0.3,0.3]},"ground":{"scale":[0.3,0.3,0.3]},"gui":{"rotation":[33.25,-29,0],"translation":[0,-1.75,0],"scale":[0.3,0.3,0.3]},"fixed":{"translation":[0,-1.75,0],"scale":[0.3,0.3,0.3]},"on_shelf":{"translation":[0,-1.75,0],"scale":[0.3,0.3,0.3]}}} \ No newline at end of file diff --git a/src/client/resources/assets/androids/models/block/chargepad.json b/src/client/resources/assets/androids/models/block/chargepad.json index f6130b8..b52e04f 100644 --- a/src/client/resources/assets/androids/models/block/chargepad.json +++ b/src/client/resources/assets/androids/models/block/chargepad.json @@ -85,5 +85,35 @@ "down": {"uv": [10, 1.5, 9.5, 2], "texture": "#0"} } } - ] + ], + "display": { + "thirdperson_righthand": { + "scale": [0.3, 0.3, 0.3] + }, + "thirdperson_lefthand": { + "scale": [0.3, 0.3, 0.3] + }, + "firstperson_righthand": { + "scale": [0.3, 0.3, 0.3] + }, + "firstperson_lefthand": { + "scale": [0.3, 0.3, 0.3] + }, + "ground": { + "scale": [0.3, 0.3, 0.3] + }, + "gui": { + "rotation": [33.25, -29, 0], + "translation": [0, -1.75, 0], + "scale": [0.3, 0.3, 0.3] + }, + "fixed": { + "translation": [0, -1.75, 0], + "scale": [0.3, 0.3, 0.3] + }, + "on_shelf": { + "translation": [0, -1.75, 0], + "scale": [0.3, 0.3, 0.3] + } + } } \ No newline at end of file diff --git a/src/client/resources/assets/androids/models/item/chargepad.json b/src/client/resources/assets/androids/models/item/chargepad.json index 5fe5dd6..c89365b 100644 --- a/src/client/resources/assets/androids/models/item/chargepad.json +++ b/src/client/resources/assets/androids/models/item/chargepad.json @@ -1,3 +1,3 @@ { - "parent": "androids:block/computer_block" + "parent": "androids:block/chargepad" } \ No newline at end of file diff --git a/src/main/java/com/hanprogramer/androids/ModBlocks.java b/src/main/java/com/hanprogramer/androids/ModBlocks.java index f48fb9a..de44089 100644 --- a/src/main/java/com/hanprogramer/androids/ModBlocks.java +++ b/src/main/java/com/hanprogramer/androids/ModBlocks.java @@ -20,7 +20,6 @@ import net.minecraft.sound.BlockSoundGroup; import net.minecraft.util.Identifier; import net.minecraft.util.Pair; -import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import team.reborn.energy.api.EnergyStorage; @@ -50,23 +49,48 @@ public static void initialize() { (ChargepadBlockEntity be, Direction side) -> be.externalEnergyView, CHARGEPAD_BLOCK_ENTITY ); + + + EnergyStorage.SIDED.registerForBlockEntity( + SolarPanelBlockEntity::getEnergyStorage, + SOLAR_PANEL_BLOCK_ENTITY + ); + // Optional: if you want upper connections to also work, redirect upper queries to the lower BE. // This uses the Block API lookup (EnergyStorage.SIDED is a BlockApiLookup). +// EnergyStorage.SIDED.registerForBlocks((world, pos, state, be, side) -> { +// if (state.isOf(ModBlocks.CHARGEPAD.getLeft()) && state.get(ChargepadBlock.HALF) == DoubleBlockHalf.UPPER) { +// BlockPos below = pos.down(); +// if (world.getBlockEntity(below) instanceof ChargepadBlockEntity lower) { +// return lower.externalEnergyView; +// } +// } +// return null; +// }, ModBlocks.CHARGEPAD.getLeft()); + + // UPPER-half bridge via per-block provider (be may be null — that’s OK) EnergyStorage.SIDED.registerForBlocks((world, pos, state, be, side) -> { - if (state.isOf(ModBlocks.CHARGEPAD.getLeft()) && state.get(ChargepadBlock.HALF) == DoubleBlockHalf.UPPER) { - BlockPos below = pos.down(); - if (world.getBlockEntity(below) instanceof ChargepadBlockEntity lower) { - return lower.externalEnergyView; + if (state.isOf(ModBlocks.CHARGEPAD.getLeft()) + && state.get(ChargepadBlock.HALF) == net.minecraft.block.enums.DoubleBlockHalf.UPPER) { + var belowBe = world.getBlockEntity(pos.down()); + if (belowBe instanceof ChargepadBlockEntity pad) { + return pad.externalEnergyView; // insertion-only sink } } return null; }, ModBlocks.CHARGEPAD.getLeft()); - - EnergyStorage.SIDED.registerForBlockEntity( - SolarPanelBlockEntity::getEnergyStorage, - SOLAR_PANEL_BLOCK_ENTITY - ); +// Last-resort safety: if the block provider somehow doesn’t run, bridge here + EnergyStorage.SIDED.registerFallback((world, pos, state, be, side) -> { + if (state.isOf(ModBlocks.CHARGEPAD.getLeft()) + && state.get(ChargepadBlock.HALF) == net.minecraft.block.enums.DoubleBlockHalf.UPPER) { + var belowBe = world.getBlockEntity(pos.down()); + if (belowBe instanceof ChargepadBlockEntity pad) { + return pad.externalEnergyView; + } + } + return null; + }); } public static final BlockEntityType COMPUTER_BLOCK_ENTITY = diff --git a/src/main/java/com/hanprogramer/androids/blocks/chargepad/ChargepadBlock.java b/src/main/java/com/hanprogramer/androids/blocks/chargepad/ChargepadBlock.java index 333d69d..3b6cde1 100644 --- a/src/main/java/com/hanprogramer/androids/blocks/chargepad/ChargepadBlock.java +++ b/src/main/java/com/hanprogramer/androids/blocks/chargepad/ChargepadBlock.java @@ -17,6 +17,9 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.random.Random; +import net.minecraft.util.shape.VoxelSet; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.world.BlockView; import net.minecraft.world.World; import net.minecraft.world.WorldView; import net.minecraft.world.tick.ScheduledTickView; @@ -41,6 +44,11 @@ protected void appendProperties(StateManager.Builder builder) builder.add(FACING, HALF); } + @Override + protected VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return Block.createCuboidShape(0, 0, 0, 16, 8, 16); + } + @Override public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) { BlockPos pos = ctx.getBlockPos(); diff --git a/src/main/java/com/hanprogramer/androids/blocks/chargepad/ChargepadBlockEntity.java b/src/main/java/com/hanprogramer/androids/blocks/chargepad/ChargepadBlockEntity.java index 0adc556..7e992dc 100644 --- a/src/main/java/com/hanprogramer/androids/blocks/chargepad/ChargepadBlockEntity.java +++ b/src/main/java/com/hanprogramer/androids/blocks/chargepad/ChargepadBlockEntity.java @@ -88,8 +88,7 @@ public void serverTick() { for (var entity : world.getOtherEntities(null, area, e -> e instanceof InventoryOwner)) { Inventory inv = ((InventoryOwner) entity).getInventory(); - if (inv == null || inv.size() == 0) continue; - + if (inv == null || inv.isEmpty()) continue; // Fabric Transfer view over the inventory (lets us get per-slot contexts) var invStorage = InventoryStorage.of(inv, null); @@ -109,7 +108,6 @@ public void serverTick() { long toSend = Math.min(INTERNAL_CHARGE_RATE, internalEnergy.getAmount()); if (toSend <= 0) break; - try (Transaction tx = Transaction.openOuter()) { // Insert into the item first to learn how much it accepts this tick long accepted = itemEnergy.insert(toSend, tx); diff --git a/src/main/java/com/hanprogramer/androids/blocks/solar/SolarPanelBlockEntity.java b/src/main/java/com/hanprogramer/androids/blocks/solar/SolarPanelBlockEntity.java index eb82373..2551a15 100644 --- a/src/main/java/com/hanprogramer/androids/blocks/solar/SolarPanelBlockEntity.java +++ b/src/main/java/com/hanprogramer/androids/blocks/solar/SolarPanelBlockEntity.java @@ -29,11 +29,11 @@ public class SolarPanelBlockEntity extends BlockEntity implements NamedScreenHandlerFactory { // ---- Configurable numbers (tweak freely) ---- - public static final long CAPACITY = 10_000L; // previous 10k - public static final long MAX_INSERT = 1_024L; // allow merging from neighbors - public static final long MAX_EXTRACT = 1_024L; // "default" output limit + public static final long CAPACITY = 1000L; // previous 10k + public static final long MAX_INSERT = 512L; // allow merging from neighbors + public static final long MAX_EXTRACT = 512L; // "default" output limit public static final long PUSH_PER_TICK = MAX_EXTRACT; - public static final int MAX_GEN_PER_TICK = 15; // light level 0..15 (experiment) + public static final int MAX_GEN_PER_TICK = 1; // light level 0..15 (experiment) private final Inventory machineInv = new SimpleInventory(0); private final PropertyDelegate props = new ArrayPropertyDelegate(MachineProps.SIZE); private final ExtEnergyStorage energy = new ExtEnergyStorage(CAPACITY, MAX_INSERT, MAX_EXTRACT) { From a294082a1aca6378cb8de8d9152ef8da6bada232 Mon Sep 17 00:00:00 2001 From: Han Programer <30620423+Hanprogramer@users.noreply.github.com> Date: Wed, 22 Oct 2025 10:23:53 +0700 Subject: [PATCH 5/7] Finished SolarPanel Implementation --- .../client/screen/base/BaseMachineScreen.java | 65 +++++++++--------- .../client/screen/solar/SolarPanelScreen.java | 7 +- .../androids/textures/gui/machine_ui_base.png | Bin 1109 -> 1064 bytes .../textures/gui/machine_ui_base_2ndtab.png | Bin 1244 -> 1202 bytes .../androids/textures/gui/solar_panel.png | Bin 1653 -> 1471 bytes .../chargepad/ChargepadBlockEntity.java | 2 +- .../blocks/solar/SolarPanelBlockEntity.java | 42 +++++++++-- 7 files changed, 76 insertions(+), 40 deletions(-) diff --git a/src/client/java/com/hanprogramer/androids/client/screen/base/BaseMachineScreen.java b/src/client/java/com/hanprogramer/androids/client/screen/base/BaseMachineScreen.java index cb09318..5c7cde1 100644 --- a/src/client/java/com/hanprogramer/androids/client/screen/base/BaseMachineScreen.java +++ b/src/client/java/com/hanprogramer/androids/client/screen/base/BaseMachineScreen.java @@ -32,7 +32,7 @@ public class BaseMachineScreen extends Handl private static final int TAB_FIRST_W = 25; // default base creative tab width private static final int TAB_OTHER_W = 25; // scaled wider version protected final PlayerInventory playerInventory; - protected Tab currentTab = Tab.FIRST; + protected Tab currentTab = Tab.THIRD; private boolean productionTabTexturesAvailable = false; // tab_on/tab_off public BaseMachineScreen(T handler, PlayerInventory inv, Text title) { @@ -123,9 +123,9 @@ protected void drawBackground(DrawContext ctx, float delta, int mouseX, int mous int secondY = firstY + TAB_BAR_HEIGHT + TAB_GAP; int thirdY = secondY + TAB_BAR_HEIGHT + TAB_GAP; - drawTab(ctx, Tab.FIRST, tabX, firstY, TAB_FIRST_W, TAB_BAR_HEIGHT); - drawTab(ctx, Tab.SECOND, tabX, secondY, TAB_OTHER_W, TAB_BAR_HEIGHT); - drawTab(ctx, Tab.THIRD, tabX, thirdY, TAB_OTHER_W, TAB_BAR_HEIGHT); +// drawTab(ctx, Tab.FIRST, tabX, firstY, TAB_FIRST_W, TAB_BAR_HEIGHT); +// drawTab(ctx, Tab.SECOND, tabX, secondY, TAB_OTHER_W, TAB_BAR_HEIGHT); +// drawTab(ctx, Tab.THIRD, tabX, thirdY, TAB_OTHER_W, TAB_BAR_HEIGHT); drawTabContent(ctx, currentTab, x, y); @@ -377,34 +377,34 @@ protected void drawVerticalBar(DrawContext ctx, int x, int topY, int w, int h, d } // Interaction ----------------------------------------- - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - int x = (this.width - this.backgroundWidth) / 2; - int y = (this.height - this.backgroundHeight) / 2; - // 与渲染逻辑保持一致:不再减去 TAB_OTHER_W - int tabX = x + this.backgroundWidth + getTabBaseOffsetX(); - int firstY = y + 8; - int secondY = firstY + TAB_BAR_HEIGHT + TAB_GAP; - int thirdY = secondY + TAB_BAR_HEIGHT + TAB_GAP; - // 命中区域与绘制位置一致:激活标签有水平偏移 - int firstX = tabX + ((currentTab == Tab.FIRST) ? getActiveTabShiftX() : 0); - int secondX = tabX + ((currentTab == Tab.SECOND) ? getActiveTabShiftX() : 0); - int thirdX = tabX + ((currentTab == Tab.THIRD) ? getActiveTabShiftX() : 0); - - if (isInside(mouseX, mouseY, firstX, firstY, TAB_FIRST_W, TAB_BAR_HEIGHT)) { - currentTab = Tab.FIRST; - return true; - } - if (isInside(mouseX, mouseY, secondX, secondY, TAB_OTHER_W, TAB_BAR_HEIGHT)) { - currentTab = Tab.SECOND; - return true; - } - if (isInside(mouseX, mouseY, thirdX, thirdY, TAB_OTHER_W, TAB_BAR_HEIGHT)) { - currentTab = Tab.THIRD; - return true; - } - return super.mouseClicked(mouseX, mouseY, button); - } +// @Override +// public boolean mouseClicked(double mouseX, double mouseY, int button) { +// int x = (this.width - this.backgroundWidth) / 2; +// int y = (this.height - this.backgroundHeight) / 2; +// // 与渲染逻辑保持一致:不再减去 TAB_OTHER_W +// int tabX = x + this.backgroundWidth + getTabBaseOffsetX(); +// int firstY = y + 8; +// int secondY = firstY + TAB_BAR_HEIGHT + TAB_GAP; +// int thirdY = secondY + TAB_BAR_HEIGHT + TAB_GAP; +// // 命中区域与绘制位置一致:激活标签有水平偏移 +// int firstX = tabX + ((currentTab == Tab.FIRST) ? getActiveTabShiftX() : 0); +// int secondX = tabX + ((currentTab == Tab.SECOND) ? getActiveTabShiftX() : 0); +// int thirdX = tabX + ((currentTab == Tab.THIRD) ? getActiveTabShiftX() : 0); +// +// if (isInside(mouseX, mouseY, firstX, firstY, TAB_FIRST_W, TAB_BAR_HEIGHT)) { +// currentTab = Tab.FIRST; +// return true; +// } +// if (isInside(mouseX, mouseY, secondX, secondY, TAB_OTHER_W, TAB_BAR_HEIGHT)) { +// currentTab = Tab.SECOND; +// return true; +// } +// if (isInside(mouseX, mouseY, thirdX, thirdY, TAB_OTHER_W, TAB_BAR_HEIGHT)) { +// currentTab = Tab.THIRD; +// return true; +// } +// return super.mouseClicked(mouseX, mouseY, button); +// } protected boolean isInside(double mx, double my, int x, int y, int w, int h) { return mx >= x && mx < x + w && my >= y && my < y + h; @@ -415,6 +415,7 @@ protected boolean isInside(double mx, double my, int x, int y, int w, int h) { protected void drawForeground(DrawContext ctx, int mouseX, int mouseY) { ctx.drawTextWithShadow(this.textRenderer, this.title, 8, 6, 0xFFFFFF); ctx.drawTextWithShadow(this.textRenderer, this.playerInventory.getDisplayName(), 8, this.backgroundHeight - 96 + 2, 0xFFFFFF); + drawMouseoverTooltip(ctx, mouseX, mouseY); } // Hook: allow subclasses to request an overlay over the machine (top) portion before content is drawn. diff --git a/src/client/java/com/hanprogramer/androids/client/screen/solar/SolarPanelScreen.java b/src/client/java/com/hanprogramer/androids/client/screen/solar/SolarPanelScreen.java index a0a4672..e27ff97 100644 --- a/src/client/java/com/hanprogramer/androids/client/screen/solar/SolarPanelScreen.java +++ b/src/client/java/com/hanprogramer/androids/client/screen/solar/SolarPanelScreen.java @@ -1,9 +1,12 @@ package com.hanprogramer.androids.client.screen.solar; +import com.hanprogramer.androids.ModBlocks; +import com.hanprogramer.androids.ModItems; import com.hanprogramer.androids.client.screen.base.BaseMachineScreen; import com.hanprogramer.androids.screen.solar.SolarPanelScreenHandler; import net.minecraft.client.gui.DrawContext; import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.item.ItemStack; import net.minecraft.text.Text; /** @@ -21,6 +24,8 @@ protected boolean shouldDrawMachineOverlay() { } @Override - protected void drawMachineOverlay(DrawContext ctx, int x, int y) { + protected void drawForeground(DrawContext ctx, int mouseX, int mouseY) { + ctx.drawItem(new ItemStack(ModBlocks.SOLAR_PANEL.getRight()), -22, 20); + super.drawForeground(ctx, mouseX, mouseY); } } diff --git a/src/client/resources/assets/androids/textures/gui/machine_ui_base.png b/src/client/resources/assets/androids/textures/gui/machine_ui_base.png index 604b820e289a632cc63834b7ac0bca36f97a9847..249426b9b3b798ef803d9ad1e998e6537350db4e 100644 GIT binary patch literal 1064 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|G!U;i$lZxy-8q?;3=GVVJY5_^ zD(1YsdocHQgowk%^9Mpt=B^NAe&yWiQRn`t|(v4LYZ1JlXYAdtdIKUwU=>rrdsO_O0ajuF{ir zoCp5a-Tz|nq5jYA&-dRM;^#7{Jhm>GS{XnLR(3 zY5r%q24A}gpC1Q@9&p?D(?qUhZ_OWe`4f$O@p4SNek?rd(TKuz@K>HPbb_O97} zJ9p0c=WEY1+g$uDd!Wcd#>|fELyrCbst-?#cCL}0$6B#zI)8oqyg$F1n591n2pnQz zpdX6cW_RHIp1pf*Z5~(H^u7L?)n{36^Ze`AuMaJaXPYrRK3;!7*>Cyf9dYZQ&G>x0 z_}%y4&c) zl-SKbE|DCgH{I~y*UuX=-!ruJIz00+IPRv9u$}nuSaz4);C7ls@vP!+d9Qob%$Q~x zf0dDLG&8vj7R+H`D)S~figRw&GHlLmGhA+&{(jrNj8C_F9Sj!l&1Lx{28*9%wHz7R z8!U~_{M;d0k-v=hzy{G9b2y*9`TKCob_M}8qLJBKyM~+F4$rzgXLEUUzUfxc8Tv=V z5)#b89=Ch>_glUHwmOa-I;S_?%iA7XSDaX8e1}n|{cz%I;{(gzK4p9`<4t$Ob~}ce jOFq|mf!UHaVD~54!aawQW-i~q9%O;1tDnm{r-UW|*E4Rk literal 1109 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|G!U;i$lZxy-8q?;3=Ay%o-U3d z6?5L+4a}SEAkubm;ipw+%x-k3emm&&!Ro`N7tWKl3Pp}`O-wiXZ|NT@zs^(3j?rzq zbLQc=-wY2No!>J5@YMZd@Oz*2|DUpLi5k6g%GSHG+hJ9^lGes7?{F(fN|7!+nOAnAtNjgW|c$2?=% z$}^w;%vsDh@6~CBp2rz8*-K98!dwYddE@2%|Cemv+}<`dH8M+{|AWi=aE8M_Yu43h z9N4_~uT(+A_0shfItM1--Op}d^Yb$+yVfTG0favhc0s&=#SzqyxUupZW6iUooig(b zeS>$#t$#M-^IOZu7IO10Z%Shhi2KLbH{fB*a5DM5BRaT^3r%n^HbC!Zy1+R`aOr*^Gd+W7hThP3qz zUA+#^Obm{@DJ+O4!IKf2e=|hg=1KN@Hs{{edl^Z}6D)ntZxmdyXqwsK8Ivt3H15+& zH-(JAeCbAn|7X>5WN2@&)IGEFKG&Vu!0^gpHCx_jxz~P988T2AKg*s)rY-Tt_T1N>rgN{&e#n(zG5`G5 yenz=#r>Foi2cbe*?zt>N%D9J$O2DSKbLh*2~7akl50%> diff --git a/src/client/resources/assets/androids/textures/gui/machine_ui_base_2ndtab.png b/src/client/resources/assets/androids/textures/gui/machine_ui_base_2ndtab.png index d2c01449f5a668e7f7ea4b1fe5a68d1b364e3272..0bc784944eb2f45f0cba26fcb6232d8906cf4fe5 100644 GIT binary patch delta 838 zcmcb^xruXvVSSFLi(^Q|oVR!H=HB*@XuFvBV42R=g>F12N>>Q1Od1m`u>%`IYo1F4Jb$<#qa%W`QGwiq+@SCw_so1`mmGff%+q5N0cqv~$JN-x4 z&)2(uRBAl7m^ROE%~tPk-VDn!SN%$OknguVSaa!=&p%_NcGSHKtN+dNp}AXr+jSp? zhPRvyEW!*NY77EC3<@_c``5pFw%7N8nLOi)PmOb4FJIN*weP2i+>@$bf5h!3Fk9Af zHgwDXn{L{FZnlm6zqc$5cb@&~c3geqZP{lr!4GB%CK;>mTa_?1wBEaSZ(q%`y8Zt@ z&8&aK!oVA;tW~cBwqypwWJ4yE$u>;F_1l;ZJ54{Gy7lJz_3Mw;GAdjM6R$61YIu6@ z{{8DxdvE4$p1<$@(&`z<3w4%X&Ro5o+qUAz@7wh@tP*9rW1qG&<-C2qoZ;}#nz+Al zDHkTLT{r!zpVa(#<{Q5}lr3!5RNi~G|Gfdv>bsgZb~9Yqk)08?vbUTuVPWR1u(|*L z{MqyB4>!+Zea$Ua=ZE4 ze;BR4x7M2>VQ1buJ{}gK$qr1SR*=xU_Qt(2J}&Ovyh00^Q%{QwkIy+;{O$MOyTwu0 zau`m1m46_2{PD&ZJ@Mi*kv8eGmhDd4axNI89cZDXz3FcL2L%>W9)HZ}vkZOyW!<;4 zyw5A=d22r1ew5pcY3AiabIwaQf+Fz$J;@#4z7}s!^Jh5frcf+3BUxGCg6`z|Ofr-G znb;=hFmkG_xmnAwHn+`Cz1Z)4R=&wb!4q?qJ-@*b66ifU@yy9N7#i%+H2gf@>u_Pw zJu{|CE{20F3{61qWq)&Zh;BTanRxE`+5>wt%@~e`B>?Td{JZ<|JSK2V0xkA|nA2_w zvDkF0=#2IxZG#KEj137)4CcQq{(WEat-Il{0ncZPzSw^S3rlt9Ftpvx3;%6+;A~YT z;|7y&zGt?|Gu&CR^flY$LYCmk4J@n@4eS0e+cv+N!n?O^4g(N)y85}Sb4q9e0Mng| A$N&HU delta 881 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 Date: Wed, 22 Oct 2025 10:46:38 +0700 Subject: [PATCH 6/7] Android drain energy when doing stuffs --- .../entities/android/AndroidEntity.java | 25 ++++++++++++++++--- .../android/scripting/SelfBridge.java | 6 +++++ .../androids/items/BatteryItem.java | 6 +++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/hanprogramer/androids/entities/android/AndroidEntity.java b/src/main/java/com/hanprogramer/androids/entities/android/AndroidEntity.java index 02a3ea4..6f66ed4 100644 --- a/src/main/java/com/hanprogramer/androids/entities/android/AndroidEntity.java +++ b/src/main/java/com/hanprogramer/androids/entities/android/AndroidEntity.java @@ -92,6 +92,8 @@ public void encode(ByteBuf byteBuf, AndroidMaterial material) { private Sleeper sleeper; private String _log = ""; private boolean hasChip = false; + private int energyDrainTick = 0; // if reached 20 reduce energy + private int energyDrainTickTime = 20; // 20 ticks = 1s public AndroidEntity(EntityType entityType, World world) { @@ -495,8 +497,7 @@ public void tick() { if (!getWorld().isClient()) { if (dataTracker.get(totalPower) <= 0) { setOn(false); - } - else if (isOn()) { + } else if (isOn()) { ensureJs(); if (isWaitingStart) return; @@ -533,9 +534,14 @@ else if (isOn()) { } } - // Light throttle: 4x per second is plenty for passive pickup - if ((this.age & 4) != 0) return; + energyDrainTick++; + if (energyDrainTick > energyDrainTickTime) {// Passive energy drain 1/s + decreaseEnergy(1); + energyDrainTick = 0; + } + // Light throttle: 6x per second is plenty for passive pickup + if ((this.age & 6) != 0) return; recalculateTotalPower(); Box reach = this.getBoundingBox().expand(0.75, 0.25, 0.75); @@ -614,6 +620,17 @@ public long getTotalCapacity() { return dataTracker.get(totalCapacity); } + public boolean decreaseEnergy(long toPull) { + for (var i : BATTERY_SLOTS) { + var stack = inventory.getStack(i); + if (stack != null && stack.getItem() instanceof BatteryItem batteryItem) { + if (batteryItem.tryUseEnergy(stack, toPull)) + return true; + } + } + return false; + } + public void updateProperties() { var appliedProps = new ArrayList(); var unusedProps = new ArrayList(); diff --git a/src/main/java/com/hanprogramer/androids/entities/android/scripting/SelfBridge.java b/src/main/java/com/hanprogramer/androids/entities/android/scripting/SelfBridge.java index 70bc202..572d770 100644 --- a/src/main/java/com/hanprogramer/androids/entities/android/scripting/SelfBridge.java +++ b/src/main/java/com/hanprogramer/androids/entities/android/scripting/SelfBridge.java @@ -157,6 +157,7 @@ public void say(String msg) { if (name == null) name = e.getName(); e.getServer().getPlayerManager().broadcast(Text.literal("[" + name.getLiteralString() + "] " + msg), false); + e.decreaseEnergy(5); } } @@ -191,6 +192,7 @@ public void navigateTo(int @Nullable [] pos) throws Exception { if (e != null) { if (pos == null) throw new Exception("Can't navigate to 'pos' because pos is null"); e.getNavigation().startMovingAlong(e.getNavigation().findPathTo(pos[0] + 0.5, pos[1], pos[2] + 0.5, 0), 0.5F); + e.decreaseEnergy(2); } } @@ -202,6 +204,7 @@ public Value navigateToAsync(int[] pos, int timeoutTicks, double acceptDistance) } var jsCtx = e.getJsCtx(); + e.decreaseEnergy(2); MinecraftServer server = ((ServerWorld) e.getWorld()).getServer(); // call your original CF-returning method CompletableFuture cf = navigateToAsyncCF(pos, timeoutTicks, acceptDistance); @@ -428,6 +431,7 @@ public boolean dumpInventoryToContainer(int[] _targetPos, String itemIdString) { if (tryMoveStackToInventory(stack, targetInv)) { entity.getInventory().setStack(i, ItemStack.EMPTY); + entity.decreaseEnergy(1); movedAny = true; } } @@ -463,6 +467,7 @@ public boolean destroyBlock(int[] _targetPos) throws Exception { if (world instanceof ServerWorld serverWorld) { // ServerWorld.breakBlock handles dropping, dropping experience, block removed events, block entity handling, and notifies clients + entity.decreaseEnergy(4); return serverWorld.breakBlock(targetPos, true, entity); } else throw new Exception("not a server world"); } @@ -472,6 +477,7 @@ public boolean plantSeed(int[] targetPos, String seedId) { var entity = get(); if (entity == null) return false; var pos = new BlockPos(targetPos[0], targetPos[1], targetPos[2]); + entity.decreaseEnergy(1); return Seeder.plantSeedById(entity, entity.getWorld(), pos, seedId); } diff --git a/src/main/java/com/hanprogramer/androids/items/BatteryItem.java b/src/main/java/com/hanprogramer/androids/items/BatteryItem.java index 2a18c3b..79a0e5b 100644 --- a/src/main/java/com/hanprogramer/androids/items/BatteryItem.java +++ b/src/main/java/com/hanprogramer/androids/items/BatteryItem.java @@ -43,6 +43,10 @@ public long getEnergyCapacity(ItemStack itemStack) { return capacity; } + public void decreasePower(ItemStack itemStack) { + + } + @Override public long getEnergyMaxInput(ItemStack itemStack) { return maxInput; @@ -121,4 +125,6 @@ public int getItemBarColor(ItemStack stack) { float pct = (float) ((double) s.getAmount() / (double) s.getCapacity()); return MathHelper.hsvToRgb(pct / 3.0F, 1.0F, 1.0F); } + + } From aa4b414f66374f7dd910b75abfd0eaf22bbaf7a4 Mon Sep 17 00:00:00 2001 From: Han Programer <30620423+Hanprogramer@users.noreply.github.com> Date: Wed, 22 Oct 2025 10:52:40 +0700 Subject: [PATCH 7/7] Rebalanced energy usage + fix nav bug --- .../androids/entities/android/AndroidEntity.java | 2 +- .../entities/android/scripting/SelfBridge.java | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/hanprogramer/androids/entities/android/AndroidEntity.java b/src/main/java/com/hanprogramer/androids/entities/android/AndroidEntity.java index 6f66ed4..cb8e529 100644 --- a/src/main/java/com/hanprogramer/androids/entities/android/AndroidEntity.java +++ b/src/main/java/com/hanprogramer/androids/entities/android/AndroidEntity.java @@ -93,7 +93,7 @@ public void encode(ByteBuf byteBuf, AndroidMaterial material) { private String _log = ""; private boolean hasChip = false; private int energyDrainTick = 0; // if reached 20 reduce energy - private int energyDrainTickTime = 20; // 20 ticks = 1s + private int energyDrainTickTime = 40; // 20 ticks = 1s public AndroidEntity(EntityType entityType, World world) { diff --git a/src/main/java/com/hanprogramer/androids/entities/android/scripting/SelfBridge.java b/src/main/java/com/hanprogramer/androids/entities/android/scripting/SelfBridge.java index 572d770..23f3731 100644 --- a/src/main/java/com/hanprogramer/androids/entities/android/scripting/SelfBridge.java +++ b/src/main/java/com/hanprogramer/androids/entities/android/scripting/SelfBridge.java @@ -192,7 +192,7 @@ public void navigateTo(int @Nullable [] pos) throws Exception { if (e != null) { if (pos == null) throw new Exception("Can't navigate to 'pos' because pos is null"); e.getNavigation().startMovingAlong(e.getNavigation().findPathTo(pos[0] + 0.5, pos[1], pos[2] + 0.5, 0), 0.5F); - e.decreaseEnergy(2); + e.decreaseEnergy(1); } } @@ -204,7 +204,6 @@ public Value navigateToAsync(int[] pos, int timeoutTicks, double acceptDistance) } var jsCtx = e.getJsCtx(); - e.decreaseEnergy(2); MinecraftServer server = ((ServerWorld) e.getWorld()).getServer(); // call your original CF-returning method CompletableFuture cf = navigateToAsyncCF(pos, timeoutTicks, acceptDistance); @@ -278,6 +277,11 @@ public CompletableFuture navigateToAsyncCF(int[] pos, int timeoutTicks, } if (!navIdle) { + if (!e.isOn()) { + e.logMessage("Android turned off, cancelled navigation"); + result.complete(false); + return; + } if (ticksLeft.decrementAndGet() <= 0) { e.logMessage("Can't reach target block, timeout"); result.complete(false); @@ -467,7 +471,7 @@ public boolean destroyBlock(int[] _targetPos) throws Exception { if (world instanceof ServerWorld serverWorld) { // ServerWorld.breakBlock handles dropping, dropping experience, block removed events, block entity handling, and notifies clients - entity.decreaseEnergy(4); + entity.decreaseEnergy(2); return serverWorld.breakBlock(targetPos, true, entity); } else throw new Exception("not a server world"); }