2424package aztech .modern_industrialization .api .energy ;
2525
2626import aztech .modern_industrialization .MI ;
27+ import aztech .modern_industrialization .config .MIServerConfig ;
2728import aztech .modern_industrialization .config .MIStartupConfig ;
28- import dev .technici4n .grandpower .api .DelegatingEnergyStorage ;
2929import dev .technici4n .grandpower .api .ILongEnergyStorage ;
30- import dev .technici4n .grandpower .api .LimitingEnergyStorage ;
3130import net .minecraft .core .Direction ;
3231import net .minecraft .world .item .Item ;
3332import net .minecraft .world .level .block .Block ;
3433import net .neoforged .neoforge .capabilities .BlockCapability ;
3534import net .neoforged .neoforge .capabilities .ItemCapability ;
3635import net .neoforged .neoforge .capabilities .RegisterCapabilitiesEvent ;
3736import org .jetbrains .annotations .ApiStatus ;
37+ import org .jetbrains .annotations .Nullable ;
3838
39+ /**
40+ * MI's energy API. It uses the same types as GrandPower (i.e. {@link ILongEnergyStorage},
41+ * however the conversion ratio between EU and GrandPower energy is configurable.
42+ * So don't mix them up!
43+ */
3944public class EnergyApi {
4045 public static final BlockCapability <MIEnergyStorage , Direction > SIDED = BlockCapability
4146 .createSided (MI .id ("sided_mi_energy_storage" ), MIEnergyStorage .class );
@@ -101,7 +106,7 @@ public static void init(RegisterCapabilitiesEvent event, Block[] allBlocks, Item
101106
102107 IN_COMPAT .set (true );
103108 try {
104- return world .getCapability (SIDED , pos , state , blockEntity , context );
109+ return WrappedMIStorage . of ( world .getCapability (SIDED , pos , state , blockEntity , context ) );
105110 } finally {
106111 IN_COMPAT .set (false );
107112 }
@@ -113,8 +118,7 @@ public static void init(RegisterCapabilitiesEvent event, Block[] allBlocks, Item
113118
114119 IN_COMPAT .set (true );
115120 try {
116- var trStorage = world .getCapability (ILongEnergyStorage .BLOCK , pos , state , blockEntity , context );
117- return trStorage == null ? null : new WrappedTrStorage (trStorage );
121+ return WrappedExternalStorage .of (world .getCapability (ILongEnergyStorage .BLOCK , pos , state , blockEntity , context ));
118122 } finally {
119123 IN_COMPAT .set (false );
120124 }
@@ -127,7 +131,7 @@ public static void init(RegisterCapabilitiesEvent event, Block[] allBlocks, Item
127131
128132 IN_COMPAT .set (true );
129133 try {
130- return stack .getCapability (ITEM );
134+ return WrappedMIStorage . of ( stack .getCapability (ITEM ) );
131135 } finally {
132136 IN_COMPAT .set (false );
133137 }
@@ -139,15 +143,14 @@ public static void init(RegisterCapabilitiesEvent event, Block[] allBlocks, Item
139143
140144 IN_COMPAT .set (true );
141145 try {
142- return stack .getCapability (ILongEnergyStorage .ITEM );
146+ return WrappedExternalStorage . of ( stack .getCapability (ILongEnergyStorage .ITEM ) );
143147 } finally {
144148 IN_COMPAT .set (false );
145149 }
146150 }, allItems );
147151 } else {
148152 event .registerBlock (SIDED , (world , pos , state , blockEntity , context ) -> {
149- var trStorage = world .getCapability (ILongEnergyStorage .BLOCK , pos , state , blockEntity , context );
150- return trStorage == null || !trStorage .canReceive () ? null : new InsertOnlyTrStorage (trStorage );
153+ return InsertOnlyExternalStorage .of (world .getCapability (ILongEnergyStorage .BLOCK , pos , state , blockEntity , context ));
151154 }, allBlocks );
152155 event .registerItem (ITEM , (stack , ctx ) -> {
153156 if (IN_COMPAT .get ()) {
@@ -156,8 +159,7 @@ public static void init(RegisterCapabilitiesEvent event, Block[] allBlocks, Item
156159
157160 IN_COMPAT .set (true );
158161 try {
159- var trStorage = stack .getCapability (ILongEnergyStorage .ITEM );
160- return trStorage == null || !trStorage .canReceive () ? null : new LimitingEnergyStorage (trStorage , Long .MAX_VALUE , 0 );
162+ return InsertOnlyExternalStorage .of (stack .getCapability (ILongEnergyStorage .ITEM ));
161163 } finally {
162164 IN_COMPAT .set (false );
163165 }
@@ -169,50 +171,168 @@ public static void init(RegisterCapabilitiesEvent event, Block[] allBlocks, Item
169171
170172 IN_COMPAT .set (true );
171173 try {
172- var miStorage = stack .getCapability (ITEM );
173- return miStorage == null || !miStorage .canExtract () ? null : new LimitingEnergyStorage (miStorage , 0 , Long .MAX_VALUE );
174+ return ExtractOnlyMIStorage .of (stack .getCapability (ITEM ));
174175 } finally {
175176 IN_COMPAT .set (false );
176177 }
177178 }, allItems );
178179 }
179180 }
180181
181- private record InsertOnlyTrStorage (ILongEnergyStorage trStorage ) implements MIEnergyStorage .NoExtract {
182+ private static long ratio () {
183+ return MIServerConfig .INSTANCE .forgeEnergyPerEu .getAsInt ();
184+ }
185+
186+ /**
187+ * An MI energy storage that wraps an external storage to apply the energy conversion ratio to it.
188+ */
189+ private static class WrappedExternalStorage implements MIEnergyStorage {
190+ @ Nullable
191+ private static WrappedExternalStorage of (@ Nullable ILongEnergyStorage externalStorage ) {
192+ return externalStorage == null ? null : new WrappedExternalStorage (externalStorage );
193+ }
194+
195+ private final ILongEnergyStorage externalStorage ;
196+
197+ private WrappedExternalStorage (ILongEnergyStorage externalStorage ) {
198+ this .externalStorage = externalStorage ;
199+ }
200+
182201 @ Override
183202 public boolean canConnect (CableTier cableTier ) {
184203 return true ;
185204 }
186205
187206 @ Override
188- public long receive (long maxAmount , boolean simulate ) {
189- return trStorage .receive (maxAmount , simulate );
207+ public long receive (long maxReceive , boolean simulate ) {
208+ long ratio = ratio ();
209+ maxReceive *= ratio ;
210+ if (ratio > 1 ) {
211+ // Do a simulate insertion to round down to a multiple of ratio that should be accepted.
212+ maxReceive = externalStorage .receive (maxReceive , true ) / ratio * ratio ;
213+ }
214+ return externalStorage .receive (maxReceive , simulate ) / ratio ;
215+ }
216+
217+ @ Override
218+ public long extract (long maxExtract , boolean simulate ) {
219+ long ratio = ratio ();
220+ maxExtract *= ratio ;
221+ if (ratio > 1 ) {
222+ // Do a simulate extraction to round down to a multiple of ratio that should be accepted.
223+ maxExtract = externalStorage .extract (maxExtract , true ) / ratio * ratio ;
224+ }
225+ return externalStorage .extract (maxExtract , simulate ) / ratio ;
226+ }
227+
228+ @ Override
229+ public long getAmount () {
230+ return externalStorage .getAmount () / ratio ();
231+ }
232+
233+ @ Override
234+ public long getCapacity () {
235+ return externalStorage .getCapacity () / ratio ();
236+ }
237+
238+ @ Override
239+ public boolean canExtract () {
240+ return externalStorage .canExtract ();
190241 }
191242
192243 @ Override
193244 public boolean canReceive () {
194- return trStorage .canReceive ();
245+ return externalStorage .canReceive ();
246+ }
247+ }
248+
249+ private static class InsertOnlyExternalStorage extends WrappedExternalStorage {
250+ @ Nullable
251+ private static InsertOnlyExternalStorage of (@ Nullable ILongEnergyStorage externalStorage ) {
252+ return externalStorage == null || !externalStorage .canReceive () ? null : new InsertOnlyExternalStorage (externalStorage );
253+ }
254+
255+ private InsertOnlyExternalStorage (ILongEnergyStorage externalStorage ) {
256+ super (externalStorage );
257+ }
258+
259+ @ Override
260+ public long extract (long maxExtract , boolean simulate ) {
261+ return 0 ;
262+ }
263+
264+ @ Override
265+ public boolean canExtract () {
266+ return false ;
267+ }
268+ }
269+
270+ /**
271+ * An external storage that wraps an MI storage to apply the energy conversion ratio to it.
272+ */
273+ private static class WrappedMIStorage implements ILongEnergyStorage {
274+ @ Nullable
275+ private static WrappedMIStorage of (@ Nullable ILongEnergyStorage miStorage ) {
276+ return miStorage == null ? null : new WrappedMIStorage (miStorage );
277+ }
278+
279+ private final ILongEnergyStorage miStorage ;
280+
281+ private WrappedMIStorage (ILongEnergyStorage miStorage ) {
282+ this .miStorage = miStorage ;
283+ }
284+
285+ @ Override
286+ public long receive (long maxReceive , boolean simulate ) {
287+ long ratio = ratio ();
288+ return miStorage .receive (maxReceive / ratio , simulate ) * ratio ;
289+ }
290+
291+ @ Override
292+ public long extract (long maxExtract , boolean simulate ) {
293+ long ratio = ratio ();
294+ return miStorage .extract (maxExtract / ratio , simulate ) * ratio ;
195295 }
196296
197297 @ Override
198298 public long getAmount () {
199- return trStorage .getAmount ();
299+ return miStorage .getAmount () * ratio ();
200300 }
201301
202302 @ Override
203303 public long getCapacity () {
204- return trStorage .getCapacity ();
304+ return miStorage .getCapacity () * ratio ();
305+ }
306+
307+ @ Override
308+ public boolean canExtract () {
309+ return miStorage .canExtract ();
310+ }
311+
312+ @ Override
313+ public boolean canReceive () {
314+ return miStorage .canReceive ();
205315 }
206316 }
207317
208- private static class WrappedTrStorage extends DelegatingEnergyStorage implements MIEnergyStorage {
209- public WrappedTrStorage (ILongEnergyStorage backingStorage ) {
210- super (backingStorage );
318+ private static class ExtractOnlyMIStorage extends WrappedMIStorage {
319+ @ Nullable
320+ private static EnergyApi .ExtractOnlyMIStorage of (@ Nullable ILongEnergyStorage miStorage ) {
321+ return miStorage == null || !miStorage .canExtract () ? null : new ExtractOnlyMIStorage (miStorage );
322+ }
323+
324+ private ExtractOnlyMIStorage (ILongEnergyStorage miStorage ) {
325+ super (miStorage );
211326 }
212327
213328 @ Override
214- public boolean canConnect (CableTier cableTier ) {
215- return true ;
329+ public long receive (long maxReceive , boolean simulate ) {
330+ return 0 ;
331+ }
332+
333+ @ Override
334+ public boolean canReceive () {
335+ return false ;
216336 }
217337 }
218338}
0 commit comments