Skip to content

Commit 8f089f8

Browse files
committed
Latest update
1 parent a579eaf commit 8f089f8

52 files changed

Lines changed: 1602 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package fr.geomtech.universegate;
2+
3+
import com.mojang.blaze3d.systems.RenderSystem;
4+
import net.minecraft.client.gui.GuiGraphics;
5+
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
6+
import net.minecraft.client.renderer.GameRenderer;
7+
import net.minecraft.network.chat.Component;
8+
import net.minecraft.resources.ResourceLocation;
9+
import net.minecraft.world.entity.player.Inventory;
10+
11+
public class RiftRefinerScreen extends AbstractContainerScreen<RiftRefinerMenu> {
12+
private static final ResourceLocation TEXTURE = ResourceLocation.fromNamespaceAndPath(UniverseGate.MOD_ID, "textures/gui/rift_refiner.png");
13+
14+
public RiftRefinerScreen(RiftRefinerMenu menu, Inventory inventory, Component title) {
15+
super(menu, inventory, title);
16+
}
17+
18+
@Override
19+
protected void init() {
20+
super.init();
21+
this.titleLabelX = (this.imageWidth - this.font.width(this.title)) / 2;
22+
}
23+
24+
@Override
25+
public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
26+
this.renderBackground(guiGraphics, mouseX, mouseY, partialTick);
27+
super.render(guiGraphics, mouseX, mouseY, partialTick);
28+
this.renderTooltip(guiGraphics, mouseX, mouseY);
29+
}
30+
31+
@Override
32+
protected void renderBg(GuiGraphics guiGraphics, float partialTick, int mouseX, int mouseY) {
33+
RenderSystem.setShader(GameRenderer::getPositionTexShader);
34+
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
35+
RenderSystem.setShaderTexture(0, TEXTURE);
36+
int x = (this.width - this.imageWidth) / 2;
37+
int y = (this.height - this.imageHeight) / 2;
38+
guiGraphics.blit(TEXTURE, x, y, 0, 0, this.imageWidth, this.imageHeight);
39+
40+
if (menu.isCrafting()) {
41+
guiGraphics.blit(TEXTURE, x + 79, y + 34, 176, 14, menu.getScaledProgress(), 16);
42+
}
43+
}
44+
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package fr.geomtech.universegate;
2+
3+
import net.minecraft.core.BlockPos;
4+
import net.minecraft.core.Direction;
5+
import net.minecraft.world.item.context.BlockPlaceContext;
6+
import net.minecraft.world.level.BlockGetter;
7+
import net.minecraft.world.level.LevelAccessor;
8+
import net.minecraft.world.level.block.Block;
9+
import net.minecraft.world.level.block.state.BlockState;
10+
import net.minecraft.world.level.block.state.StateDefinition;
11+
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
12+
import net.minecraft.world.level.block.state.properties.BooleanProperty;
13+
import net.minecraft.world.phys.shapes.CollisionContext;
14+
import net.minecraft.world.phys.shapes.Shapes;
15+
import net.minecraft.world.phys.shapes.VoxelShape;
16+
17+
import java.util.Map;
18+
19+
import net.minecraft.core.registries.BuiltInRegistries;
20+
21+
public class DarkEnergyConduitBlock extends Block {
22+
23+
public static final BooleanProperty NORTH = BlockStateProperties.NORTH;
24+
public static final BooleanProperty EAST = BlockStateProperties.EAST;
25+
public static final BooleanProperty SOUTH = BlockStateProperties.SOUTH;
26+
public static final BooleanProperty WEST = BlockStateProperties.WEST;
27+
public static final BooleanProperty UP = BlockStateProperties.UP;
28+
public static final BooleanProperty DOWN = BlockStateProperties.DOWN;
29+
30+
private static final Map<Direction, BooleanProperty> PROPERTY_BY_DIRECTION = Map.of(
31+
Direction.NORTH, NORTH,
32+
Direction.EAST, EAST,
33+
Direction.SOUTH, SOUTH,
34+
Direction.WEST, WEST,
35+
Direction.UP, UP,
36+
Direction.DOWN, DOWN
37+
);
38+
39+
private static final VoxelShape CENTER_SHAPE = Block.box(6.0D, 6.0D, 6.0D, 10.0D, 10.0D, 10.0D);
40+
private static final VoxelShape NORTH_SHAPE = Block.box(6.0D, 6.0D, 0.0D, 10.0D, 10.0D, 6.0D);
41+
private static final VoxelShape SOUTH_SHAPE = Block.box(6.0D, 6.0D, 10.0D, 10.0D, 10.0D, 16.0D);
42+
private static final VoxelShape WEST_SHAPE = Block.box(0.0D, 6.0D, 6.0D, 6.0D, 10.0D, 10.0D);
43+
private static final VoxelShape EAST_SHAPE = Block.box(10.0D, 6.0D, 6.0D, 16.0D, 10.0D, 10.0D);
44+
private static final VoxelShape UP_SHAPE = Block.box(6.0D, 10.0D, 6.0D, 10.0D, 16.0D, 10.0D);
45+
private static final VoxelShape DOWN_SHAPE = Block.box(6.0D, 0.0D, 6.0D, 10.0D, 6.0D, 10.0D);
46+
private static final VoxelShape[] SHAPE_CACHE = buildShapeCache();
47+
48+
public DarkEnergyConduitBlock(Properties properties) {
49+
super(properties);
50+
this.registerDefaultState(this.stateDefinition.any()
51+
.setValue(NORTH, false)
52+
.setValue(EAST, false)
53+
.setValue(SOUTH, false)
54+
.setValue(WEST, false)
55+
.setValue(UP, false)
56+
.setValue(DOWN, false));
57+
}
58+
59+
@Override
60+
public BlockState getStateForPlacement(BlockPlaceContext context) {
61+
return updateConnections(context.getLevel(), context.getClickedPos(), this.defaultBlockState());
62+
}
63+
64+
@Override
65+
protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor level, BlockPos currentPos, BlockPos neighborPos) {
66+
BooleanProperty property = PROPERTY_BY_DIRECTION.get(direction);
67+
if (property == null) return state;
68+
return state.setValue(property, canConnectTo(level, neighborPos, direction));
69+
}
70+
71+
@Override
72+
protected VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
73+
return SHAPE_CACHE[shapeIndex(state)];
74+
}
75+
76+
@Override
77+
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
78+
builder.add(NORTH, EAST, SOUTH, WEST, UP, DOWN);
79+
}
80+
81+
private BlockState updateConnections(BlockGetter level, BlockPos pos, BlockState state) {
82+
return state
83+
.setValue(NORTH, canConnectTo(level, pos.north(), Direction.NORTH))
84+
.setValue(EAST, canConnectTo(level, pos.east(), Direction.EAST))
85+
.setValue(SOUTH, canConnectTo(level, pos.south(), Direction.SOUTH))
86+
.setValue(WEST, canConnectTo(level, pos.west(), Direction.WEST))
87+
.setValue(UP, canConnectTo(level, pos.above(), Direction.UP))
88+
.setValue(DOWN, canConnectTo(level, pos.below(), Direction.DOWN));
89+
}
90+
91+
private boolean canConnectTo(BlockGetter level, BlockPos pos, Direction direction) {
92+
BlockState state = level.getBlockState(pos);
93+
Block block = state.getBlock();
94+
if (block instanceof DarkEnergyConduitBlock || block instanceof DarkEnergyGeneratorBlock) return true;
95+
96+
net.minecraft.resources.ResourceLocation key = BuiltInRegistries.BLOCK.getKey(state.getBlock());
97+
return key.getPath().startsWith("portal_");
98+
}
99+
100+
private static VoxelShape[] buildShapeCache() {
101+
VoxelShape[] shapes = new VoxelShape[64];
102+
for (int i = 0; i < shapes.length; i++) {
103+
VoxelShape shape = CENTER_SHAPE;
104+
if ((i & 1) != 0) shape = Shapes.or(shape, NORTH_SHAPE);
105+
if ((i & 2) != 0) shape = Shapes.or(shape, EAST_SHAPE);
106+
if ((i & 4) != 0) shape = Shapes.or(shape, SOUTH_SHAPE);
107+
if ((i & 8) != 0) shape = Shapes.or(shape, WEST_SHAPE);
108+
if ((i & 16) != 0) shape = Shapes.or(shape, UP_SHAPE);
109+
if ((i & 32) != 0) shape = Shapes.or(shape, DOWN_SHAPE);
110+
shapes[i] = shape;
111+
}
112+
return shapes;
113+
}
114+
115+
private static int shapeIndex(BlockState state) {
116+
int index = 0;
117+
if (state.getValue(NORTH)) index |= 1;
118+
if (state.getValue(EAST)) index |= 2;
119+
if (state.getValue(SOUTH)) index |= 4;
120+
if (state.getValue(WEST)) index |= 8;
121+
if (state.getValue(UP)) index |= 16;
122+
if (state.getValue(DOWN)) index |= 32;
123+
return index;
124+
}
125+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package fr.geomtech.universegate;
2+
3+
import net.minecraft.core.BlockPos;
4+
import net.minecraft.server.level.ServerPlayer;
5+
import net.minecraft.world.InteractionHand;
6+
import net.minecraft.world.InteractionResult;
7+
import net.minecraft.world.entity.player.Player;
8+
import net.minecraft.world.level.Level;
9+
import net.minecraft.world.level.block.BaseEntityBlock;
10+
import net.minecraft.world.level.block.RenderShape;
11+
import net.minecraft.world.level.block.entity.BlockEntity;
12+
import net.minecraft.world.level.block.entity.BlockEntityTicker;
13+
import net.minecraft.world.level.block.entity.BlockEntityType;
14+
import net.minecraft.world.level.block.state.BlockState;
15+
import net.minecraft.world.phys.BlockHitResult;
16+
import org.jetbrains.annotations.Nullable;
17+
18+
public class DarkEnergyGeneratorBlock extends BaseEntityBlock {
19+
20+
public DarkEnergyGeneratorBlock(Properties properties) {
21+
super(properties);
22+
}
23+
24+
@Override
25+
protected com.mojang.serialization.MapCodec<? extends BaseEntityBlock> codec() {
26+
return simpleCodec(DarkEnergyGeneratorBlock::new);
27+
}
28+
29+
@Nullable
30+
@Override
31+
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
32+
return new DarkEnergyGeneratorBlockEntity(pos, state);
33+
}
34+
35+
@Override
36+
public RenderShape getRenderShape(BlockState state) {
37+
return RenderShape.MODEL;
38+
}
39+
40+
@Override
41+
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hit) {
42+
if (!level.isClientSide) {
43+
// Open GUI if we have one, otherwise just return success
44+
// For now, no GUI requested for Generator specifically, but likely needed for inputting fluid manually if pipes don't work yet.
45+
// But the prompt implies using pipes.
46+
}
47+
return InteractionResult.SUCCESS;
48+
}
49+
50+
@Nullable
51+
@Override
52+
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> blockEntityType) {
53+
return createTickerHelper(blockEntityType, ModBlockEntities.DARK_ENERGY_GENERATOR, DarkEnergyGeneratorBlockEntity::tick);
54+
}
55+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package fr.geomtech.universegate;
2+
3+
import net.minecraft.core.BlockPos;
4+
import net.minecraft.core.HolderLookup;
5+
import net.minecraft.core.HolderLookup;
6+
import net.minecraft.nbt.CompoundTag;
7+
import net.minecraft.world.level.Level;
8+
import net.minecraft.world.level.block.entity.BlockEntity;
9+
import net.minecraft.world.level.block.state.BlockState;
10+
11+
public class DarkEnergyGeneratorBlockEntity extends BlockEntity {
12+
13+
private int darkMatterAmount = 0;
14+
private int energyAmount = 0;
15+
public static final int MAX_DARK_MATTER = 10000; // mB
16+
public static final int MAX_ENERGY = 50000;
17+
18+
// Production rate
19+
public static final int DARK_MATTER_CONSUMPTION = 5; // per tick
20+
public static final int ENERGY_CONSUMPTION = 100; // per tick
21+
22+
private boolean isRunning = false;
23+
24+
public DarkEnergyGeneratorBlockEntity(BlockPos pos, BlockState state) {
25+
super(ModBlockEntities.DARK_ENERGY_GENERATOR, pos, state);
26+
}
27+
28+
public static void tick(Level level, BlockPos pos, BlockState state, DarkEnergyGeneratorBlockEntity entity) {
29+
if (level.isClientSide) return;
30+
31+
// Logic: If has fuel + energy, run.
32+
if (entity.darkMatterAmount >= DARK_MATTER_CONSUMPTION && entity.energyAmount >= ENERGY_CONSUMPTION) {
33+
entity.darkMatterAmount -= DARK_MATTER_CONSUMPTION;
34+
entity.energyAmount -= ENERGY_CONSUMPTION;
35+
entity.isRunning = true;
36+
} else {
37+
entity.isRunning = false;
38+
}
39+
}
40+
41+
public boolean isGenerating() {
42+
return isRunning;
43+
}
44+
45+
// Simplistic Fluid/Energy insertion methods for now
46+
public int fillDarkMatter(int amount) {
47+
int space = MAX_DARK_MATTER - darkMatterAmount;
48+
int toFill = Math.min(amount, space);
49+
darkMatterAmount += toFill;
50+
return toFill;
51+
}
52+
53+
public int receiveEnergy(int amount) {
54+
int space = MAX_ENERGY - energyAmount;
55+
int toReceive = Math.min(amount, space);
56+
energyAmount += toReceive;
57+
return toReceive;
58+
}
59+
60+
@Override
61+
protected void saveAdditional(CompoundTag tag, net.minecraft.core.HolderLookup.Provider registries) {
62+
super.saveAdditional(tag, registries);
63+
tag.putInt("DarkMatter", darkMatterAmount);
64+
tag.putInt("Energy", energyAmount);
65+
tag.putBoolean("Running", isRunning);
66+
}
67+
68+
@Override
69+
protected void loadAdditional(CompoundTag tag, net.minecraft.core.HolderLookup.Provider registries) {
70+
super.loadAdditional(tag, registries);
71+
darkMatterAmount = tag.getInt("DarkMatter");
72+
energyAmount = tag.getInt("Energy");
73+
isRunning = tag.getBoolean("Running");
74+
}
75+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package fr.geomtech.universegate;
2+
3+
import net.minecraft.core.BlockPos;
4+
import net.minecraft.core.Direction;
5+
import net.minecraft.server.level.ServerLevel;
6+
import net.minecraft.world.level.block.entity.BlockEntity;
7+
import net.minecraft.world.level.block.state.BlockState;
8+
9+
import fr.geomtech.universegate.PortalFrameHelper;
10+
import fr.geomtech.universegate.PortalFrameDetector;
11+
12+
import java.util.HashSet;
13+
import java.util.Set;
14+
import java.util.ArrayDeque;
15+
16+
public final class DarkEnergyNetworkHelper {
17+
18+
private static final int MAX_SEARCH_DEPTH = 64;
19+
20+
private DarkEnergyNetworkHelper() {}
21+
22+
public static boolean isPortalPowered(ServerLevel level, BlockPos corePos) {
23+
// Find the full frame to check all adjacent blocks
24+
var match = PortalFrameDetector.find(level, corePos);
25+
if (match.isEmpty()) return false;
26+
27+
// Collect all relevant positions: Core + Frames
28+
Set<BlockPos> framePositions = new HashSet<>();
29+
framePositions.add(corePos);
30+
framePositions.addAll(PortalFrameHelper.collectFrame(match.get(), corePos));
31+
32+
// Search for connected Dark Energy Generators via Dark Energy Conduits
33+
Set<BlockPos> visited = new HashSet<>();
34+
ArrayDeque<BlockPos> queue = new ArrayDeque<>();
35+
36+
// Add initial adjacent conduits from ANY portal part
37+
for (BlockPos partPos : framePositions) {
38+
for (Direction dir : Direction.values()) {
39+
BlockPos neighbor = partPos.relative(dir);
40+
if (isValidConduit(level, neighbor)) {
41+
queue.add(neighbor);
42+
visited.add(neighbor);
43+
}
44+
}
45+
}
46+
47+
int steps = 0;
48+
while (!queue.isEmpty() && steps < MAX_SEARCH_DEPTH) {
49+
BlockPos current = queue.poll();
50+
steps++;
51+
52+
// Check neighbors of current conduit
53+
for (Direction dir : Direction.values()) {
54+
BlockPos neighbor = current.relative(dir);
55+
if (visited.contains(neighbor)) continue;
56+
57+
BlockState state = level.getBlockState(neighbor);
58+
59+
if (state.is(ModBlocks.DARK_ENERGY_GENERATOR)) {
60+
BlockEntity be = level.getBlockEntity(neighbor);
61+
if (be instanceof DarkEnergyGeneratorBlockEntity generator && generator.isGenerating()) {
62+
return true;
63+
}
64+
} else if (isValidConduit(level, neighbor)) {
65+
visited.add(neighbor);
66+
queue.add(neighbor);
67+
}
68+
}
69+
}
70+
71+
return false;
72+
}
73+
74+
private static boolean isValidConduit(ServerLevel level, BlockPos pos) {
75+
return level.getBlockState(pos).is(ModBlocks.DARK_ENERGY_CONDUIT);
76+
}
77+
}

0 commit comments

Comments
 (0)