Skip to content

Commit 0fd9083

Browse files
committed
"texture missing"
1 parent 68db8e6 commit 0fd9083

17 files changed

+294
-17
lines changed

src/main/java/net/hellomouse/ae2dn/AE2DistributedNetworks.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import net.hellomouse.ae2dn.definitions.DNBlockEntities;
66
import net.hellomouse.ae2dn.definitions.DNBlocks;
77
import net.hellomouse.ae2dn.definitions.DNItems;
8-
import net.neoforged.bus.api.SubscribeEvent;
98
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
109
import org.slf4j.Logger;
1110

src/main/java/net/hellomouse/ae2dn/Config.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,28 @@ public class Config {
1414
.define("enable", true);
1515

1616
private static final ModConfigSpec.BooleanValue REQUIRE_ROUTE_DISTRIBUTOR = BUILDER
17-
.comment("Whether the Subnet Manager is required to allow multiple controllers on a network")
18-
.define("enable", true);
17+
.comment("Whether the route distributor is required to allow multiple controllers on a network")
18+
.define("requireRouteDistributor", true);
19+
20+
private static final ModConfigSpec.ConfigValue<Integer> ROUTE_CONTROLLER_PASSIVE_ENERGY_COST = BUILDER
21+
.comment("Passive energy consumption of the route distributor block")
22+
.define("routeDistributorPassiveEnergyCost", 25);
23+
private static final ModConfigSpec.ConfigValue<Integer> ROUTE_DISTRIBUTOR_PER_CONTROLLER_ENERGY_COST = BUILDER
24+
.comment("How much energy the route distributor consumes per controller structure in the network beyond the first")
25+
.define("routeDistributorPerControllerEnergyCost", 100);
1926

2027
static final ModConfigSpec SPEC = BUILDER.build();
2128

2229
public static boolean globalEnable;
2330
public static boolean requireRouteDistributor;
31+
public static int rdPerControllerEnergyCost;
32+
public static int rdPassiveEnergyCost;
2433

2534
@SubscribeEvent
2635
static void onLoad(final ModConfigEvent event) {
2736
globalEnable = GLOBAL_ENABLE.get();
2837
requireRouteDistributor = REQUIRE_ROUTE_DISTRIBUTOR.get();
38+
rdPerControllerEnergyCost = ROUTE_DISTRIBUTOR_PER_CONTROLLER_ENERGY_COST.get();
39+
rdPassiveEnergyCost = ROUTE_CONTROLLER_PASSIVE_ENERGY_COST.get();
2940
}
3041
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,48 @@
11
package net.hellomouse.ae2dn;
22

33
import appeng.block.AEBaseEntityBlock;
4+
import net.minecraft.util.StringRepresentable;
5+
import net.minecraft.world.level.block.Block;
6+
import net.minecraft.world.level.block.state.BlockState;
7+
import net.minecraft.world.level.block.state.StateDefinition;
8+
import net.minecraft.world.level.block.state.properties.EnumProperty;
9+
import org.jetbrains.annotations.NotNull;
410

511
public class RouteDistributorBlock extends AEBaseEntityBlock<RouteDistributorBlockEntity> {
12+
public enum OperationalState implements StringRepresentable {
13+
/** No power */
14+
unpowered,
15+
/** Powered but no channel */
16+
missing_channel,
17+
/** Powered and has channel, currently standby */
18+
standby,
19+
/** Powered and has channel, currently active */
20+
active;
21+
22+
@Override
23+
public @NotNull String getSerializedName() {
24+
return name();
25+
}
26+
}
27+
28+
public static final EnumProperty<OperationalState> OPERATIONAL_STATE = EnumProperty.create("operational_state", OperationalState.class);
29+
630
public RouteDistributorBlock() {
731
super(metalProps());
32+
registerDefaultState(defaultBlockState().setValue(OPERATIONAL_STATE, OperationalState.unpowered));
33+
}
34+
35+
@Override
36+
protected BlockState updateBlockStateFromBlockEntity(
37+
BlockState currentState,
38+
RouteDistributorBlockEntity be
39+
) {
40+
return currentState.setValue(OPERATIONAL_STATE, be.getOperationalState());
41+
}
42+
43+
@Override
44+
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
45+
super.createBlockStateDefinition(builder);
46+
builder.add(OPERATIONAL_STATE);
847
}
948
}
Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,80 @@
11
package net.hellomouse.ae2dn;
22

3-
import appeng.api.inventories.InternalInventory;
43
import appeng.api.networking.GridFlags;
4+
import appeng.api.networking.IGridNodeListener;
55
import appeng.blockentity.grid.AENetworkedBlockEntity;
6+
import appeng.core.AELog;
7+
import net.hellomouse.ae2dn.extension.PathingServiceExt;
8+
import net.hellomouse.ae2dn.RouteDistributorBlock.OperationalState;
69
import net.minecraft.core.BlockPos;
710
import net.minecraft.world.level.block.entity.BlockEntityType;
811
import net.minecraft.world.level.block.state.BlockState;
912

1013
public class RouteDistributorBlockEntity extends AENetworkedBlockEntity {
14+
private boolean isPrimary = false;
15+
1116
public RouteDistributorBlockEntity(BlockEntityType<?> blockEntityType, BlockPos pos, BlockState blockState) {
1217
super(blockEntityType, pos, blockState);
13-
this.getMainNode().setIdlePowerUsage(100);
14-
this.getMainNode().setFlags(GridFlags.REQUIRE_CHANNEL);
18+
getMainNode().setIdlePowerUsage(Config.rdPassiveEnergyCost);
19+
getMainNode().setFlags(GridFlags.REQUIRE_CHANNEL);
20+
}
21+
22+
public boolean isPrimary() {
23+
return isPrimary;
24+
}
25+
26+
public void setPrimary(boolean value) {
27+
isPrimary = value;
28+
}
29+
30+
@Override
31+
public void onMainNodeStateChanged(IGridNodeListener.State reason) {
32+
if (reason == IGridNodeListener.State.GRID_BOOT) {
33+
if (!getMainNode().hasGridBooted()) {
34+
// grid rebooted, no longer primary
35+
setPrimary(false);
36+
}
37+
updateEnergyUsage();
38+
}
39+
markForUpdate();
40+
}
41+
42+
/** Recalculate energy cost */
43+
private void updateEnergyUsage() {
44+
var node = getMainNode();
45+
if (node.isActive()) {
46+
var grid = getMainNode().getGrid();
47+
assert grid != null;
48+
var pathingServiceExt = ((PathingServiceExt) grid.getPathingService());
49+
if (isPrimary()) {
50+
var controllerStructures = pathingServiceExt.ae2dn$getControllerStructureCount();
51+
int multiplier;
52+
if (controllerStructures <= 1) {
53+
// this ought not to happen
54+
AELog.warn("RouteDistributor primary but controllers <= 1");
55+
multiplier = 0;
56+
} else {
57+
multiplier = controllerStructures - 1;
58+
}
59+
node.setIdlePowerUsage(Config.rdPassiveEnergyCost + multiplier * Config.rdPerControllerEnergyCost);
60+
return;
61+
}
62+
}
63+
// not active
64+
node.setIdlePowerUsage(Config.rdPassiveEnergyCost);
65+
}
66+
67+
public OperationalState getOperationalState() {
68+
var node = getMainNode();
69+
if (!node.isPowered()) {
70+
return OperationalState.unpowered;
71+
}
72+
if (!node.isActive()) {
73+
return OperationalState.missing_channel;
74+
}
75+
if (!isPrimary()) {
76+
return OperationalState.standby;
77+
}
78+
return OperationalState.active;
1579
}
1680
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package net.hellomouse.ae2dn;
2+
3+
import appeng.api.integrations.igtooltip.TooltipBuilder;
4+
import appeng.api.integrations.igtooltip.TooltipContext;
5+
import appeng.api.integrations.igtooltip.providers.BodyProvider;
6+
import appeng.api.integrations.igtooltip.providers.ServerDataProvider;
7+
import appeng.core.localization.GuiText;
8+
import appeng.util.Platform;
9+
import net.hellomouse.ae2dn.RouteDistributorBlock.OperationalState;
10+
import net.hellomouse.ae2dn.extension.PathingServiceExt;
11+
import net.minecraft.nbt.CompoundTag;
12+
import net.minecraft.nbt.Tag;
13+
import net.minecraft.network.chat.Component;
14+
import net.minecraft.world.entity.player.Player;
15+
16+
@SuppressWarnings("UnstableApiUsage")
17+
public class RouteDistributorDataProvider
18+
implements BodyProvider<RouteDistributorBlockEntity>, ServerDataProvider<RouteDistributorBlockEntity>
19+
{
20+
private static final String TAG_ENERGY_USAGE = "rdEnergyConsumption";
21+
private static final String TAG_CONTROLLER_COUNT = "rdControllerCount";
22+
23+
@Override
24+
public void buildTooltip(RouteDistributorBlockEntity object, TooltipContext context, TooltipBuilder tooltip) {
25+
var serverData = context.serverData();
26+
var blockState = object.getBlockState();
27+
var state = blockState.getValue(RouteDistributorBlock.OPERATIONAL_STATE);
28+
// the GridNodeStateDataProvider will handle unpowered and missing_channel cases
29+
if (state == OperationalState.standby) {
30+
tooltip.addLine(
31+
Component.translatable("waila.ae2dn.RouteDistributorStatus")
32+
.append(Component.translatable("waila.ae2dn.RouteDistributorStatusStandby"))
33+
);
34+
} else if (state == OperationalState.active) {
35+
tooltip.addLine(
36+
Component.translatable("waila.ae2dn.RouteDistributorStatus")
37+
.append(Component.translatable("waila.ae2dn.RouteDistributorStatusActive"))
38+
);
39+
}
40+
if (serverData.contains(TAG_CONTROLLER_COUNT, Tag.TAG_INT)) {
41+
var count = serverData.getInt(TAG_CONTROLLER_COUNT);
42+
tooltip.addLine(
43+
Component.translatable("waila.ae2dn.ControllerStructureCount", count)
44+
);
45+
}
46+
if (serverData.contains(TAG_ENERGY_USAGE, Tag.TAG_DOUBLE)) {
47+
var usage = serverData.getDouble(TAG_ENERGY_USAGE);
48+
tooltip.addLine(GuiText.PowerUsageRate.text(Platform.formatPower(usage, true)));
49+
}
50+
}
51+
52+
@Override
53+
public void provideServerData(Player player, RouteDistributorBlockEntity object, CompoundTag serverData) {
54+
var node = object.getMainNode();
55+
var blockState = object.getBlockState();
56+
var state = blockState.getValue(RouteDistributorBlock.OPERATIONAL_STATE);
57+
if (node.isReady()) {
58+
if (state != OperationalState.unpowered) {
59+
//noinspection DataFlowIssue: node.isReady() checked
60+
serverData.putDouble(TAG_ENERGY_USAGE, node.getNode().getIdlePowerUsage());
61+
}
62+
if (state == OperationalState.standby || state == OperationalState.active) {
63+
//noinspection DataFlowIssue: node.isReady() checked
64+
var pathingServiceExt = (PathingServiceExt) node.getGrid().getPathingService();
65+
serverData.putInt(TAG_CONTROLLER_COUNT, pathingServiceExt.ae2dn$getControllerStructureCount());
66+
}
67+
}
68+
}
69+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package net.hellomouse.ae2dn.definitions;
2+
3+
import appeng.api.integrations.igtooltip.ClientRegistration;
4+
import appeng.api.integrations.igtooltip.CommonRegistration;
5+
import appeng.api.integrations.igtooltip.TooltipProvider;
6+
import net.hellomouse.ae2dn.AE2DistributedNetworks;
7+
import net.hellomouse.ae2dn.RouteDistributorBlock;
8+
import net.hellomouse.ae2dn.RouteDistributorBlockEntity;
9+
import net.hellomouse.ae2dn.RouteDistributorDataProvider;
10+
import net.minecraft.resources.ResourceLocation;
11+
12+
public class DNTooltipProviders implements TooltipProvider {
13+
@Override
14+
public void registerCommon(CommonRegistration registration) {
15+
registration.addBlockEntityData(
16+
ResourceLocation.fromNamespaceAndPath(AE2DistributedNetworks.MOD_ID, "route_distributor"),
17+
RouteDistributorBlockEntity.class,
18+
new RouteDistributorDataProvider()
19+
);
20+
}
21+
22+
@Override
23+
public void registerClient(ClientRegistration registration) {
24+
registration.addBlockEntityBody(
25+
RouteDistributorBlockEntity.class,
26+
RouteDistributorBlock.class,
27+
ResourceLocation.fromNamespaceAndPath(AE2DistributedNetworks.MOD_ID, "route_distributor"),
28+
new RouteDistributorDataProvider()
29+
);
30+
}
31+
}

src/main/java/net/hellomouse/ae2dn/extension/PathingServiceExt.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,9 @@
44

55
public interface PathingServiceExt {
66
TrunkIssue ae2dn$getTrunkIssue();
7-
boolean ae2dn$hasMultipleControllers();
7+
int ae2dn$getControllerStructureCount();
8+
9+
default boolean ae2dn$hasMultipleControllers() {
10+
return ae2dn$getControllerStructureCount() > 1;
11+
}
812
}

src/main/java/net/hellomouse/ae2dn/mixin/PathingCalculationMixin.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public abstract class PathingCalculationMixin implements PathingCalculationExt {
5656
@Shadow @Final private Set<GridNode> channelNodes;
5757
@Shadow @Final private Set<IPathItem> visited;
5858
@Shadow protected abstract void enqueue(IPathItem pathItem, int queueIndex);
59+
@Shadow private int channelsByBlocks;
5960

6061
@Unique
6162
@Override
@@ -117,6 +118,9 @@ public abstract class PathingCalculationMixin implements PathingCalculationExt {
117118
} else if (sideA instanceof GridNode gn) {
118119
gn.incrementChannelCount(maxChannels);
119120
}
121+
// PathingCalculation counts GridConnections as well for some reason, so replicate that behavior
122+
// this is probably a documentation issue?
123+
channelsByBlocks += maxChannels;
120124
sideA = sideA.getControllerRoute();
121125
}
122126
var sideB = other;
@@ -126,6 +130,7 @@ public abstract class PathingCalculationMixin implements PathingCalculationExt {
126130
} else if (sideB instanceof GridNode gn) {
127131
gn.incrementChannelCount(maxChannels);
128132
}
133+
channelsByBlocks += maxChannels;
129134
sideB = sideB.getControllerRoute();
130135
}
131136
// setControllerRoute sets usedChannels to 0 so we don't need to clear the rest
@@ -341,6 +346,7 @@ private void postCompute(CallbackInfo ci) {
341346
for (var node : grid.getMachineNodes(RouteDistributorBlockEntity.class)) {
342347
// require at least one subnet manager to have a channel
343348
if (channelNodes.contains((GridNode) node)) {
349+
((RouteDistributorBlockEntity) ((GridNode) node).getOwner()).setPrimary(true);
344350
break smCheck;
345351
}
346352
}

src/main/java/net/hellomouse/ae2dn/mixin/PathingServiceMixin.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
public class PathingServiceMixin implements PathingServiceExt {
3232
@Unique private TrunkIssue ae2dn$trunkIssue = TrunkIssue.NONE;
3333
@Unique private TrunkIssue ae2dn$oldTrunkIssue = TrunkIssue.NONE;
34-
/** Whether multiple distinct controller structures exist */
35-
@Unique private boolean ae2dn$hasMultipleControllers = false;
34+
/** How many distinct controller structures exist */
35+
@Unique private int ae2dn$controllerStructureCount;
3636
@Unique private ControllerState ae2dn$oldControllerState = null;
3737

3838
@Shadow private boolean recalculateControllerNextTick;
@@ -48,8 +48,8 @@ public class PathingServiceMixin implements PathingServiceExt {
4848

4949
@Unique
5050
@Override
51-
public boolean ae2dn$hasMultipleControllers() {
52-
return ae2dn$hasMultipleControllers;
51+
public int ae2dn$getControllerStructureCount() {
52+
return ae2dn$controllerStructureCount;
5353
}
5454

5555
@Inject(
@@ -97,10 +97,13 @@ private void afterPathingCalculation(CallbackInfo ci, @Local PathingCalculation
9797
private void updateControllerState() {
9898
// why overwrite? because we pretty much replace the whole method anyway
9999
recalculateControllerNextTick = false;
100-
ae2dn$hasMultipleControllers = false;
100+
ae2dn$controllerStructureCount = 0;
101101

102102
if (!Config.globalEnable) {
103103
controllerState = ControllerValidator.calculateState(controllers);
104+
if (controllerState == ControllerState.CONTROLLER_ONLINE) {
105+
ae2dn$controllerStructureCount = 1;
106+
}
104107
return;
105108
}
106109

@@ -114,7 +117,6 @@ private void updateControllerState() {
114117
return;
115118
}
116119

117-
int distinctControllers = 0;
118120
var unvisited = new HashSet<>(controllers);
119121

120122
while (!unvisited.isEmpty()) {
@@ -135,12 +137,9 @@ private void updateControllerState() {
135137
return;
136138
}
137139

138-
distinctControllers++;
140+
ae2dn$controllerStructureCount++;
139141
}
140142

141-
if (distinctControllers > 1) {
142-
ae2dn$hasMultipleControllers = true;
143-
}
144143
controllerState = ControllerState.CONTROLLER_ONLINE;
145144
}
146145
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
net.hellomouse.ae2dn.definitions.DNTooltipProviders

0 commit comments

Comments
 (0)