Skip to content

Commit fcd6390

Browse files
committed
refactor(UniverseGate): migrate to new Parabola block asset set; remove deprecated rotor model; add new block JSONs and textures; update languages and mod manifest to reflect asset changes
1 parent 4247334 commit fcd6390

33 files changed

+832
-390
lines changed

src/client/java/fr/geomtech/universegate/MeteorologicalControllerScreen.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ protected void renderLabels(GuiGraphics g, int mouseX, int mouseY) {
120120
infoText = Component.translatable("gui.universegate.weather_structure_missing");
121121
} else if (!menu.hasFlag(MeteorologicalControllerMenu.FLAG_CATALYST_HAS_CRYSTAL)) {
122122
infoText = Component.translatable("gui.universegate.weather_missing_crystal");
123+
} else if (!menu.hasFlag(MeteorologicalControllerMenu.FLAG_PARABOLA_POWERED)) {
124+
infoText = Component.translatable("gui.universegate.weather_parabola_unpowered");
123125
} else if (!menu.hasFlag(MeteorologicalControllerMenu.FLAG_FULLY_CHARGED)) {
124126
infoText = Component.translatable("gui.universegate.weather_waiting_energy");
125127
} else {

src/client/java/fr/geomtech/universegate/ParabolaDishRenderer.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,27 +35,29 @@ public void render(ParabolaBlockEntity blockEntity,
3535
return;
3636
}
3737

38-
BlockState rotorState = state.setValue(ParabolaBlock.PART, ParabolaBlock.Part.ROTOR);
38+
BlockState topState = state.setValue(ParabolaBlock.PART, ParabolaBlock.Part.DISH);
3939
float spinDegrees = 0.0F;
4040

41-
if (isPortalNetworkBlock(blockEntity.getLevel().getBlockState(blockEntity.getBlockPos().below()))) {
41+
if (blockEntity.isPowered()) {
4242
float time = blockEntity.getLevel().getGameTime() + partialTick;
4343
float phase = (blockEntity.getBlockPos().asLong() & 31L) * PHASE_DEGREES;
4444
spinDegrees = time * SPIN_DEGREES_PER_TICK + phase;
4545
}
4646

4747
poseStack.pushPose();
48-
poseStack.translate(0.5D, 0.0D, 0.5D);
48+
poseStack.translate(0.5D, 3.0D, 0.5D); // Translate to the TOP block (3 blocks above BASE)
4949
poseStack.mulPose(new Quaternionf().rotationY(spinDegrees * DEG_TO_RAD));
5050
poseStack.translate(-0.5D, 0.0D, -0.5D);
51-
blockRenderer.renderSingleBlock(rotorState, poseStack, buffer, packedLight, packedOverlay);
51+
blockRenderer.renderSingleBlock(topState, poseStack, buffer, packedLight, packedOverlay);
5252
poseStack.popPose();
5353
}
5454

55+
/*
5556
private static boolean isPortalNetworkBlock(BlockState state) {
5657
return state.is(ModBlocks.PORTAL_CORE)
5758
|| state.is(ModBlocks.PORTAL_FRAME)
5859
|| state.is(ModBlocks.PORTAL_FIELD)
5960
|| state.is(ModBlocks.PORTAL_KEYBOARD);
6061
}
62+
*/
6163
}

src/main/java/fr/geomtech/universegate/EnergyConduitBlock.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ private boolean canConnectTo(BlockGetter level, BlockPos pos, Direction directio
109109
|| state.is(ModBlocks.PORTAL_FIELD)
110110
|| state.is(ModBlocks.PORTAL_KEYBOARD)
111111
|| state.is(ModBlocks.CHARGED_LIGHTNING_ROD)
112-
|| state.is(ModBlocks.METEOROLOGICAL_CONTROLLER);
112+
|| state.is(ModBlocks.METEOROLOGICAL_CONTROLLER)
113+
|| state.is(ModBlocks.PARABOLA_BLOCK);
113114
}
114115

115116
private static VoxelShape[] buildShapeCache() {

src/main/java/fr/geomtech/universegate/EnergyNetworkHelper.java

Lines changed: 80 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,14 @@ public final class EnergyNetworkHelper {
3030

3131
private EnergyNetworkHelper() {}
3232

33-
public record CondenserNetwork(Set<BlockPos> condensers, Set<BlockPos> solarPanels) {}
33+
public record CondenserNetwork(Set<BlockPos> condensers, Set<BlockPos> solarPanels, Set<BlockPos> parabolas) {}
3434
public record EnergyNetworkSnapshot(int storedEnergy,
3535
int capacity,
3636
int condenserCount,
3737
int panelCount,
38-
int activePanelCount) {
39-
public static final EnergyNetworkSnapshot EMPTY = new EnergyNetworkSnapshot(0, 0, 0, 0, 0);
38+
int activePanelCount,
39+
int parabolaCount) {
40+
public static final EnergyNetworkSnapshot EMPTY = new EnergyNetworkSnapshot(0, 0, 0, 0, 0, 0);
4041

4142
public int chargePercent() {
4243
if (capacity <= 0) return 0;
@@ -54,12 +55,12 @@ public static CondenserNetwork scanCondenserNetwork(ServerLevel level, BlockPos
5455
}
5556

5657
if (startConduits.isEmpty()) {
57-
return new CondenserNetwork(condensers, Set.of());
58+
return new CondenserNetwork(condensers, Set.of(), Set.of());
5859
}
5960

6061
ConduitScanResult scan = scanConduits(level, startConduits);
6162
condensers.addAll(scan.condensers());
62-
return new CondenserNetwork(condensers, scan.solarPanels());
63+
return new CondenserNetwork(condensers, scan.solarPanels(), scan.parabolas());
6364
}
6465

6566
public static BlockPos findNetworkLeader(Set<BlockPos> condensers) {
@@ -110,10 +111,75 @@ public static EnergyNetworkSnapshot getNetworkSnapshot(ServerLevel level, BlockP
110111
capacity,
111112
condensers.size(),
112113
network.solarPanels().size(),
113-
activePanels
114+
activePanels,
115+
network.parabolas().size()
114116
);
115117
}
116118

119+
public static boolean isParabolaOnNetwork(ServerLevel level, BlockPos startNode) {
120+
Set<BlockPos> startConduits = new HashSet<>();
121+
collectAdjacentConduits(level, startNode, startConduits);
122+
if (startConduits.isEmpty()) return false;
123+
124+
ConduitScanResult scan = scanConduits(level, startConduits);
125+
return !scan.parabolas().isEmpty();
126+
}
127+
128+
public static boolean isPoweredParabolaOnNetwork(ServerLevel level, BlockPos startNode) {
129+
Set<BlockPos> startConduits = new HashSet<>();
130+
collectAdjacentConduits(level, startNode, startConduits);
131+
if (startConduits.isEmpty()) return false;
132+
133+
ConduitScanResult scan = scanConduits(level, startConduits);
134+
for (BlockPos pos : scan.parabolas()) {
135+
BlockEntity be = level.getBlockEntity(pos);
136+
if (be instanceof ParabolaBlockEntity parabola && parabola.isPowered()) {
137+
return true;
138+
}
139+
}
140+
return false;
141+
}
142+
143+
public static boolean consumeEnergyFromNetwork(ServerLevel level, BlockPos startNode, int amount) {
144+
Set<BlockPos> startConduits = new HashSet<>();
145+
collectAdjacentConduits(level, startNode, startConduits);
146+
147+
// Also check if startNode itself is a condenser (though usually we call this from a machine)
148+
if (level.getBlockState(startNode).is(ModBlocks.ENERGY_CONDENSER)) {
149+
// Logic if starting from a condenser, but usually machines connect TO conduits.
150+
}
151+
152+
if (startConduits.isEmpty()) return false;
153+
154+
ConduitScanResult scan = scanConduits(level, startConduits);
155+
return consumeFromCondensers(level, scan.condensers(), amount);
156+
}
157+
158+
private static boolean consumeFromCondensers(ServerLevel level, Set<BlockPos> condenserPositions, int amount) {
159+
if (condenserPositions.isEmpty()) return false;
160+
int totalStored = 0;
161+
List<EnergyCondenserBlockEntity> condensers = getCondensers(level, condenserPositions);
162+
163+
for (EnergyCondenserBlockEntity condenser : condensers) {
164+
totalStored += condenser.getStoredEnergy();
165+
}
166+
167+
if (totalStored < amount) return false;
168+
169+
condensers.sort(Comparator
170+
.comparingInt(EnergyCondenserBlockEntity::getStoredEnergy)
171+
.reversed()
172+
.thenComparing(be -> be.getBlockPos(), POS_COMPARATOR));
173+
174+
int remaining = amount;
175+
for (EnergyCondenserBlockEntity condenser : condensers) {
176+
if (remaining <= 0) break;
177+
remaining -= condenser.extractEnergy(remaining);
178+
}
179+
180+
return remaining <= 0;
181+
}
182+
117183
public static int distributeEnergy(ServerLevel level, Set<BlockPos> condenserPositions, int amount) {
118184
if (amount <= 0 || condenserPositions.isEmpty()) return 0;
119185

@@ -210,13 +276,14 @@ private static List<EnergyCondenserBlockEntity> getCondensers(ServerLevel level,
210276
return condensers;
211277
}
212278

213-
private record ConduitScanResult(Set<BlockPos> condensers, Set<BlockPos> solarPanels) {}
279+
private record ConduitScanResult(Set<BlockPos> condensers, Set<BlockPos> solarPanels, Set<BlockPos> parabolas) {}
214280

215281
private static ConduitScanResult scanConduits(ServerLevel level, Set<BlockPos> startConduits) {
216282
Set<BlockPos> visited = new HashSet<>();
217283
ArrayDeque<BlockPos> queue = new ArrayDeque<>();
218284
Set<BlockPos> condensers = new HashSet<>();
219285
Set<BlockPos> solarPanels = new HashSet<>();
286+
Set<BlockPos> parabolas = new HashSet<>();
220287

221288
for (BlockPos start : startConduits) {
222289
if (level.getBlockState(start).is(ModBlocks.ENERGY_CONDUIT) && visited.add(start.immutable())) {
@@ -245,14 +312,19 @@ private static ConduitScanResult scanConduits(ServerLevel level, Set<BlockPos> s
245312
condensers.add(neighborPos.immutable());
246313
continue;
247314
}
315+
316+
if (neighborState.is(ModBlocks.PARABOLA_BLOCK)) {
317+
parabolas.add(neighborPos.immutable());
318+
continue;
319+
}
248320

249321
if (isSolarPanelSocketConnection(neighborState, direction)) {
250322
solarPanels.add(neighborPos.immutable());
251323
}
252324
}
253325
}
254326

255-
return new ConduitScanResult(condensers, solarPanels);
327+
return new ConduitScanResult(condensers, solarPanels, parabolas);
256328
}
257329

258330
private static boolean isSolarPanelSocketConnection(BlockState panelState, Direction directionFromConduitToPanel) {

src/main/java/fr/geomtech/universegate/MeteorologicalControllerBlockEntity.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,17 @@ public boolean tryStartWeatherSequence(WeatherSelection weatherSelection) {
108108

109109
if (sequenceActive) return false;
110110
if (!machineStatus.structureReady()) return false;
111+
if (!machineStatus.parabolaPowered()) return false;
111112
if (!machineStatus.catalystHasCrystal()) return false;
112113
if (chargeTicks < CHARGE_FULL_TICKS) return false;
113114

114115
BlockPos catalystPos = machineStatus.catalystPos();
115116
if (catalystPos == null) return false;
116117

118+
if (!EnergyNetworkHelper.consumeEnergyFromNetwork(serverLevel, machineStatus.condenserBasePos(), 2500)) {
119+
return false;
120+
}
121+
117122
pendingWeather = weatherSelection;
118123
activeCatalystPos = catalystPos.immutable();
119124
sequenceActive = true;
@@ -217,6 +222,7 @@ private int buildStatusFlags() {
217222
if (machineStatus.catalystHasCrystal()) flags |= MeteorologicalControllerMenu.FLAG_CATALYST_HAS_CRYSTAL;
218223
if (machineStatus.structureReady()) flags |= MeteorologicalControllerMenu.FLAG_STRUCTURE_READY;
219224
if (machineStatus.energyLinked()) flags |= MeteorologicalControllerMenu.FLAG_ENERGY_LINKED;
225+
if (machineStatus.parabolaPowered()) flags |= MeteorologicalControllerMenu.FLAG_PARABOLA_POWERED;
220226
if (chargeTicks >= CHARGE_FULL_TICKS) flags |= MeteorologicalControllerMenu.FLAG_FULLY_CHARGED;
221227
if (sequenceActive) flags |= MeteorologicalControllerMenu.FLAG_SEQUENCE_ACTIVE;
222228
if (canTriggerWeatherChange()) flags |= MeteorologicalControllerMenu.FLAG_WEATHER_UNLOCKED;

src/main/java/fr/geomtech/universegate/MeteorologicalControllerMenu.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public class MeteorologicalControllerMenu extends AbstractContainerMenu {
2222
public static final int FLAG_FULLY_CHARGED = 1 << 6;
2323
public static final int FLAG_SEQUENCE_ACTIVE = 1 << 7;
2424
public static final int FLAG_WEATHER_UNLOCKED = 1 << 8;
25+
public static final int FLAG_PARABOLA_POWERED = 1 << 9;
2526

2627
private static final int DATA_CHARGE_TICKS = 0;
2728
private static final int DATA_MAX_CHARGE_TICKS = 1;

src/main/java/fr/geomtech/universegate/ModItemGroups.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,10 @@ public final class ModItemGroups {
4444
output.accept(ModItems.RIFT_MEAT);
4545
output.accept(ModItems.COOKED_RIFT_MEAT);
4646
output.accept(ModItems.ENERGY_CRYSTAL);
47+
output.accept(ModItems.RIFT_CRYSTAL);
4748
output.accept(ModItems.RIFT_SHADE_SPAWN_EGG);
4849
output.accept(ModItems.RIFT_BEAST_SPAWN_EGG);
50+
output.accept(ModItems.RIFT_CORE_FRAGMENT);
4951
})
5052
.build();
5153

src/main/java/fr/geomtech/universegate/ModItems.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,11 @@ public final class ModItems {
135135
new Item(new Item.Properties().stacksTo(64))
136136
);
137137

138+
public static final Item RIFT_CORE_FRAGMENT = register(
139+
"rift_core_fragment",
140+
new Item(new Item.Properties())
141+
);
142+
138143
private static Item register(String id, Item item) {
139144
return Registry.register(
140145
BuiltInRegistries.ITEM,

0 commit comments

Comments
 (0)