Skip to content

Commit aa7bf66

Browse files
authored
Make the ratio between EU and FE configurable. Default: 1 EU = 10 FE (#1067)
1 parent 4eeb199 commit aa7bf66

File tree

3 files changed

+151
-27
lines changed

3 files changed

+151
-27
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1119,6 +1119,8 @@
11191119
"modern_industrialization.configuration.defaultIndustrialistTrades.tooltip": "Enable the default trades from the Industrialist villager provided by MI. Disable this to provide your own set of trades.",
11201120
"modern_industrialization.configuration.defaultOreGenTooltips": "Ore generation tooltips",
11211121
"modern_industrialization.configuration.defaultOreGenTooltips.tooltip": "Enable the default ore generation tooltips. These tooltips show how each MI ore generates, based on the default ore generation settings in MI. Set this to false if you change the ore features in a datapack.",
1122+
"modern_industrialization.configuration.forgeEnergyPerEu": "FE per EU",
1123+
"modern_industrialization.configuration.forgeEnergyPerEu.tooltip": "How many Forge Energy units a single EU from MI is worth.",
11221124
"modern_industrialization.configuration.ftbQuestsIntegration": "FTB Quests integration",
11231125
"modern_industrialization.configuration.ftbQuestsIntegration.tooltip": "Enable the FTB Quests integration, if present.",
11241126
"modern_industrialization.configuration.fuelTooltips": "Fuel tooltips",
@@ -1134,7 +1136,6 @@
11341136
"modern_industrialization.configuration.maxDistillationTowerHeight": "Max distillation tower height",
11351137
"modern_industrialization.configuration.maxDistillationTowerHeight.tooltip": "Maximum height of the distillation tower multiblock.",
11361138
"modern_industrialization.configuration.messages": "Messages",
1137-
"modern_industrialization.configuration.misc": "Miscellaneous",
11381139
"modern_industrialization.configuration.missingRecipeViewerMessage": "Missing recipe viewer message",
11391140
"modern_industrialization.configuration.missingRecipeViewerMessage.tooltip": "Enable login message when EMI, JEI and REI are all missing.",
11401141
"modern_industrialization.configuration.newVersionMessage": "New version message",

src/main/java/aztech/modern_industrialization/api/energy/EnergyApi.java

Lines changed: 144 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,23 @@
2424
package aztech.modern_industrialization.api.energy;
2525

2626
import aztech.modern_industrialization.MI;
27+
import aztech.modern_industrialization.config.MIServerConfig;
2728
import aztech.modern_industrialization.config.MIStartupConfig;
28-
import dev.technici4n.grandpower.api.DelegatingEnergyStorage;
2929
import dev.technici4n.grandpower.api.ILongEnergyStorage;
30-
import dev.technici4n.grandpower.api.LimitingEnergyStorage;
3130
import net.minecraft.core.Direction;
3231
import net.minecraft.world.item.Item;
3332
import net.minecraft.world.level.block.Block;
3433
import net.neoforged.neoforge.capabilities.BlockCapability;
3534
import net.neoforged.neoforge.capabilities.ItemCapability;
3635
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
3736
import 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+
*/
3944
public 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
}

src/main/java/aztech/modern_industrialization/config/MIServerConfig.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public final class MIServerConfig {
3535
SPEC = builder.build();
3636
}
3737

38+
public final ModConfigSpec.IntValue forgeEnergyPerEu;
3839
public final ModConfigSpec.IntValue baseItemPipeTransfer;
3940
public final ModConfigSpec.BooleanValue spawnWithGuideBook;
4041
public final ModConfigSpec.BooleanValue respawnWithGuideBook;
@@ -43,7 +44,10 @@ public final class MIServerConfig {
4344
public final ModConfigSpec.BooleanValue stonecutterToCuttingMachine;
4445

4546
private MIServerConfig(MIConfigBuilder builder) {
46-
builder.pushSection("misc", "Miscellaneous");
47+
this.forgeEnergyPerEu = builder.start("forgeEnergyPerEu",
48+
"FE per EU",
49+
"How many Forge Energy units a single EU from MI is worth.")
50+
.defineInRange("forgeEnergyPerEu", 10, 1, 1000);
4751
this.baseItemPipeTransfer = builder.start("baseItemPipeTransfer",
4852
"Base item pipe transfer",
4953
"Base amount of items transferred by item pipes every 3 seconds.")
@@ -56,7 +60,6 @@ private MIServerConfig(MIConfigBuilder builder) {
5660
"Respawn with guidebook",
5761
"Grant guidebook when a player respawns after death.")
5862
.define("respawnWithGuideBook", true);
59-
builder.popSection();
6063

6164
builder.pushSection("recipes", "Recipes");
6265
this.compostableToPlantOil = builder.start("compostableToPlantOil",

0 commit comments

Comments
 (0)