diff --git a/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d b/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d index 1fa8913..e864cb9 100644 --- a/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d +++ b/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d @@ -1,11 +1,12 @@ -// 1.21.1 2026-01-28T08:47:15.3186366 Loot Tables -// 1.21.1 2026-01-26T19:04:46.4976369 Loot Tables +// 1.21.1 2026-02-06T10:36:07.5023829 Loot Tables 69d8318ddba171526d1fabb87d9d93548ed8598e data/aphelion/loot_table/blocks/arc_furnace_casing.json 05f08985e601d30116f67e2f07b48b03b40cdca6 data/aphelion/loot_table/blocks/block_steel.json ff43a9c3741faf10b1e156a7a74d5cfb035cc118 data/aphelion/loot_table/blocks/dimension_changer.json b63130d9c10485676303d729807b6fcaac080294 data/aphelion/loot_table/blocks/electric_arc_furnace.json -afb6519a03415b8e0d5bafc9fadb70905a398046 data/aphelion/loot_table/blocks/oxygen_test_block.json +086c97543700ccc2f815da4e6c29f11159766889 data/aphelion/loot_table/blocks/gravity_test_block.json b9cfe672ead8e2673a7b2f5c4cec831e7e8e7040 data/aphelion/loot_table/blocks/launch_pad.json +afb6519a03415b8e0d5bafc9fadb70905a398046 data/aphelion/loot_table/blocks/oxygen_test_block.json +2c6748b2cfb5b78e0cc95a2f3583d4e50cb4c964 data/aphelion/loot_table/blocks/rocket_assemblerblock.json 1ab50c99e9f478840b9d003fd56ebdcab12fbbce data/aphelion/loot_table/blocks/test_block.json 7d8eeb99a1bc942a6e2cf292b21fd4534062b5ab data/aphelion/loot_table/blocks/vacuum_arc_furnace_controller.json 797bf9839d79e08b4832c9eaf3cb303b0471ed0c data/aphelion/loot_table/blocks/vaf_dummy_block.json diff --git a/src/generated/resources/.cache/a8139181fab9cfd94e67697230cbaca839a05e1f b/src/generated/resources/.cache/a8139181fab9cfd94e67697230cbaca839a05e1f index c021feb..bbe8db5 100644 --- a/src/generated/resources/.cache/a8139181fab9cfd94e67697230cbaca839a05e1f +++ b/src/generated/resources/.cache/a8139181fab9cfd94e67697230cbaca839a05e1f @@ -1,19 +1,21 @@ -// 1.21.1 2026-01-28T08:47:15.3176368 Block States: aphelion -// 1.21.1 2026-01-26T20:40:43.8251623 Block States: aphelion +// 1.21.1 2026-02-06T10:36:07.5013847 Block States: aphelion 851ff42f7b21dec86107c8e0cefb3934ae4ebc08 assets/aphelion/blockstates/block_steel.json 30b9c0efd7aaadb5412d98e4568f98b3632adbb9 assets/aphelion/blockstates/dimension_changer.json cb4287104006c80c8396b290ab5258df65d62cef assets/aphelion/blockstates/electric_arc_furnace.json +1975ab6c73f76642f8b6cfed00e0739b4ea5775f assets/aphelion/blockstates/gravity_test_block.json 28131a570d3666b7f323de4ad8a69e52ceec92e2 assets/aphelion/blockstates/oxygen_test_block.json b86c50fddcf6c8c6c19cb748529239d5962a3ede assets/aphelion/blockstates/test_block.json a810b97f4dace35d026f28d96cb9c47c93600d75 assets/aphelion/models/block/block_steel.json 2d3592b7ab7132908709243e97540151e0fb762e assets/aphelion/models/block/dimension_changer.json 5f7e8674070f31a63875b5d6147153bfa0eef61a assets/aphelion/models/block/electric_arc_furnace.json +ad49034f318c6bc14a4844cf598c6999296aa8a0 assets/aphelion/models/block/gravity_test_block.json 746f23f150a01524ad03cbd1eb822bfbb7cf453b assets/aphelion/models/block/oxygen_test_block.json e0971228b4a1c4bc9dbab58a7dacdc3ae6037e02 assets/aphelion/models/block/test_block.json cdc831b0f1c462be64825fd34bd446e5b95afac6 assets/aphelion/models/item/arc_furnace_casing.json 3599f9037eb2f66de1765318b97ab564c3eae92f assets/aphelion/models/item/block_steel.json db0ec473a016ce05c258cde18a217d47a9ea8324 assets/aphelion/models/item/dimension_changer.json 279080c06ada87f54fd0a7b885b256dbe25a946a assets/aphelion/models/item/electric_arc_furnace.json +8de1f7597e1fa82c5603a88040ad935aa1cb9b29 assets/aphelion/models/item/gravity_test_block.json 24cf60e70f7d9450b0e70cf017662e80971bae17 assets/aphelion/models/item/oxygen_test_block.json 74418ef1cf678e72e7534924274688ef5a68af0e assets/aphelion/models/item/test_block.json 88ca3602517e99f7feaed57eddfc96965a25761c assets/aphelion/models/item/vacuum_arc_furnace_controller.json diff --git a/src/main/java/net/xevianlight/aphelion/Aphelion.java b/src/main/java/net/xevianlight/aphelion/Aphelion.java index 4101621..dc2eef1 100644 --- a/src/main/java/net/xevianlight/aphelion/Aphelion.java +++ b/src/main/java/net/xevianlight/aphelion/Aphelion.java @@ -24,10 +24,7 @@ import net.xevianlight.aphelion.fluid.BaseFluidType; import net.xevianlight.aphelion.fluid.ModFluidTypes; import net.xevianlight.aphelion.fluid.ModFluids; import net.xevianlight.aphelion.recipe.ModRecipes; -import net.xevianlight.aphelion.screen.ElectricArcFurnaceScreen; -import net.xevianlight.aphelion.screen.ModMenuTypes; -import net.xevianlight.aphelion.screen.TestBlockScreen; -import net.xevianlight.aphelion.screen.VacuumArcFurnaceScreen; +import net.xevianlight.aphelion.screen.*; import org.slf4j.Logger; import net.xevianlight.aphelion.entites.vehicles.RocketRenderer; @@ -147,6 +144,7 @@ public class Aphelion { event.register(ModMenuTypes.TEST_BLOCK_MENU.get(), TestBlockScreen::new); event.register(ModMenuTypes.ELECTRIC_ARC_FURNACE_MENU.get(), ElectricArcFurnaceScreen::new); event.register(ModMenuTypes.VACUUM_ARC_FURNACE_MENU.get(), VacuumArcFurnaceScreen::new); + event.register(ModMenuTypes.GRAVITY_TEST_BLOCK_MENU.get(), GravityTestBlockScreen::new); } @SubscribeEvent diff --git a/src/main/java/net/xevianlight/aphelion/block/custom/GravityTestBlock.java b/src/main/java/net/xevianlight/aphelion/block/custom/GravityTestBlock.java new file mode 100644 index 0000000..6a2af5b --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/block/custom/GravityTestBlock.java @@ -0,0 +1,57 @@ +package net.xevianlight.aphelion.block.custom; + +import com.mojang.serialization.MapCodec; +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.SimpleMenuProvider; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import net.xevianlight.aphelion.block.custom.base.BasicEntityBlock; +import net.xevianlight.aphelion.block.entity.custom.GravityTestBlockEntity; +import net.xevianlight.aphelion.block.entity.custom.OxygenTestBlockEntity; +import net.xevianlight.aphelion.block.entity.custom.TestBlockEntity; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class GravityTestBlock extends BasicEntityBlock { + + public GravityTestBlock(Properties properties) {super(properties, true);} + + @Override + protected MapCodec codec() {return null;} + + @Override + public @Nullable BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) { + return new GravityTestBlockEntity(blockPos, blockState); + } + + public static Properties getProperties() {return Properties.of();} + + @Override + protected void onRemove(BlockState state, @NotNull Level level, @NotNull BlockPos pos, BlockState newState, boolean movedByPiston) { + if (state.getBlock() != newState.getBlock()) { + BlockEntity blockEntity = level.getBlockEntity(pos); + if (blockEntity instanceof GravityTestBlockEntity BE) { + BE.removeGravityArea(); + } + } + super.onRemove(state, level, pos, newState, movedByPiston); + } + + @Override + public InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult result) { + + if (!level.isClientSide && player instanceof ServerPlayer serverPlayer && level.getBlockEntity(pos) instanceof GravityTestBlockEntity testBlockEntity) { + serverPlayer.openMenu(new SimpleMenuProvider(testBlockEntity, Component.literal("Gravity Test Block")), pos); + } + return InteractionResult.sidedSuccess(level.isClientSide); + } +} diff --git a/src/main/java/net/xevianlight/aphelion/block/entity/custom/GravityTestBlockEntity.java b/src/main/java/net/xevianlight/aphelion/block/entity/custom/GravityTestBlockEntity.java new file mode 100644 index 0000000..e23f399 --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/block/entity/custom/GravityTestBlockEntity.java @@ -0,0 +1,119 @@ +package net.xevianlight.aphelion.block.entity.custom; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.MenuProvider; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.neoforge.items.ItemStackHandler; +import net.xevianlight.aphelion.block.custom.base.TickableBlockEntity; +import net.xevianlight.aphelion.core.init.ModBlockEntities; +import net.xevianlight.aphelion.core.init.ModBlocks; +import net.xevianlight.aphelion.core.saveddata.GravitySavedData; +import net.xevianlight.aphelion.screen.ElectricArcFurnaceMenu; +import net.xevianlight.aphelion.screen.GravityTestBlockMenu; +import net.xevianlight.aphelion.systems.GravityService; +import org.jetbrains.annotations.Nullable; + +public class GravityTestBlockEntity extends BlockEntity implements TickableBlockEntity, MenuProvider { + + public GravityTestBlockEntity(BlockPos pos, BlockState blockState) {super(ModBlockEntities.GRAVITY_TEST_BLOCK_ENTITY.get(), pos, blockState);} + + public int areaSize = 5; + public float gravityStrength = 5f; + private boolean isInitialized = false; + public final ItemStackHandler inventory = new ItemStackHandler(0); + + @Override + protected void saveAdditional(CompoundTag pTag, HolderLookup.Provider pRegistries) { + pTag.putInt("areaSize", areaSize); + pTag.putFloat("gravityStrength", gravityStrength); + super.saveAdditional(pTag, pRegistries); + } + + @Override + protected void loadAdditional(CompoundTag pTag, HolderLookup.Provider pRegistries) { + areaSize = pTag.getInt("areaSize"); + gravityStrength = pTag.getFloat("gravityStrength"); + super.loadAdditional(pTag, pRegistries); + } + + public void setRadius(float r) { + areaSize = (int) r; + } + + public void setStrength(float s) { + gravityStrength = s; + } + + public void addGravityArea() { + Level level = getLevel(); + if (level != null && level.isClientSide()) return; + + BlockPos pos = this.getBlockPos(); + + GravityService.setGravityArea((ServerLevel) level, pos, gravityStrength, areaSize); + } + + public void removeGravityArea() { + Level level = getLevel(); + if (level != null && level.isClientSide()) return; + + BlockPos pos = this.getBlockPos(); + + GravityService.removeGravityArea((ServerLevel) level, pos); + } + + @Override + public void tick(Level entityLevel, long time, BlockState blockState, BlockPos pos) {} + + @Override + public void clientTick(ClientLevel level, long time, BlockState state, BlockPos pos) {} + + @Override + public void serverTick(ServerLevel level, long time, BlockState state, BlockPos pos) {} + + @Override + public boolean isInitialized() { + return isInitialized; + } + + @Override + public void firstTick(Level level, BlockState state, BlockPos pos) { addGravityArea(); isInitialized = true; } + + @Override + public @Nullable AbstractContainerMenu createMenu(int i, Inventory inventory, Player player) { + return new GravityTestBlockMenu(i, inventory, this); + } + + @Override + public Component getDisplayName() { + return null; + } + + public void sendUpdate() { + removeGravityArea(); + addGravityArea(); + } + + @Override + public ClientboundBlockEntityDataPacket getUpdatePacket() { + return ClientboundBlockEntityDataPacket.create(this); + } + + + @Override + public CompoundTag getUpdateTag(HolderLookup.Provider registries) { + return this.saveCustomOnly(registries); + } +} diff --git a/src/main/java/net/xevianlight/aphelion/block/entity/custom/renderer/OxygenTestRenderer.java b/src/main/java/net/xevianlight/aphelion/block/entity/custom/renderer/OxygenTestRenderer.java index 604c52d..28cf257 100644 --- a/src/main/java/net/xevianlight/aphelion/block/entity/custom/renderer/OxygenTestRenderer.java +++ b/src/main/java/net/xevianlight/aphelion/block/entity/custom/renderer/OxygenTestRenderer.java @@ -42,6 +42,8 @@ public class OxygenTestRenderer implements BlockEntityRenderer> Y_OFFSET) + 1) << Y_OFFSET; + return (pos & (~Y_MAGIC)) | (y & Y_MAGIC); + } + + public static long below(long pos) { + long y = (((pos & Y_MAGIC) >> Y_OFFSET) - 1) << Y_OFFSET; + return (pos & (~Y_MAGIC)) | (y & Y_MAGIC); + } + + public static long north(long pos) { + long z = (((pos & Z_MAGIC) >> Z_OFFSET) - 1) << Z_OFFSET; + return (pos & (~Z_MAGIC)) | (z & Z_MAGIC); + } + + public static long south(long pos) { + long z = (((pos & Z_MAGIC) >> Z_OFFSET) + 1) << Z_OFFSET; + return (pos & (~Z_MAGIC)) | (z & Z_MAGIC); + } + + public static long east(long pos) { + long x = (((pos & X_MAGIC) >> X_OFFSET) + 1) << X_OFFSET; + return (pos & (~X_MAGIC)) | (x & X_MAGIC); + } + + public static long west(long pos) { + long x = (((pos & X_MAGIC) >> X_OFFSET) - 1) << X_OFFSET; + return (pos & (~X_MAGIC)) | (x & X_MAGIC); + } + + public static int getX(long pos) { + return BlockPos.getX(pos); + } + + public static int getY(long pos) { + return BlockPos.getY(pos); + } + + public static int getZ(long pos) { + return BlockPos.getZ(pos); + } + } + + public static void drawSphere(PoseStack poseStack, VertexConsumer vc, Vector3f center, float radius) { + + Matrix4f mat = poseStack.last().pose(); + + final int Y_SEGMENT_COUNT = 20; + for (int segmentY=0; segmentY < Y_SEGMENT_COUNT; segmentY++) { + double bottomAngle = (((double) segmentY / Y_SEGMENT_COUNT) - 0.5) * Math.PI; + double topAngle = (((double) (segmentY+1) / Y_SEGMENT_COUNT) - 0.5) * Math.PI; + float y0 = (float) Math.sin(bottomAngle) * radius + center.y(); + float y1 = (float) Math.sin(topAngle) * radius + center.y(); + float bottomRadius = (float) Math.cos(bottomAngle) * radius; + float topRadius = (float) Math.cos(topAngle) * radius; + + final int POLAR_SEGMENT_COUNT = 20; + for (int segmentP = 0; segmentP < POLAR_SEGMENT_COUNT; segmentP++) { + // "left" and "right" As viewed from outside the sphere + double leftAngle = (((double) segmentP / POLAR_SEGMENT_COUNT) - 1) * 2 * Math.PI; + double rightAngle = (((double) (segmentP+1) / POLAR_SEGMENT_COUNT) - 1) * 2 * Math.PI; + // Points have to wind CCW, so 0->1->2->3 is CCW. + // 0 and 1 use y0, 2 and 3 use y1. + float x0, x1, x2, x3, z0, z1, z2, z3; + + x0 = (float) Math.cos(leftAngle) * bottomRadius + center.x(); + x1 = (float) Math.cos(rightAngle) * bottomRadius + center.x(); + x2 = (float) Math.cos(rightAngle) * topRadius + center.x(); + x3 = (float) Math.cos(leftAngle) * topRadius + center.x(); + z0 = (float) Math.sin(leftAngle) * bottomRadius + center.z(); + z1 = (float) Math.sin(rightAngle) * bottomRadius + center.z(); + z2 = (float) Math.sin(rightAngle) * topRadius + center.z(); + z3 = (float) Math.sin(leftAngle) * topRadius + center.z(); + + // Draw the sphere quad + quad(mat, vc, + x0, y0, z0, + x1, y0, z1, + x2, y1, z2, + x3, y1, z3, + 0.7f, 0.2f, 0.2f, 0.5f); + } + } + } + + // Sorry LOSERS, we only let FAST data structures in HERE. + public static void drawBlockArea(PoseStack poseStack, VertexConsumer vc, LongOpenHashSet blocks) { + + for (long p : blocks) { + + + // Neighbor checks: only render faces exposed to non-oxygen + boolean up = blocks.contains(LongPos.above(p)); + boolean down = blocks.contains(LongPos.below(p)); + boolean north = blocks.contains(LongPos.north(p)); + boolean south = blocks.contains(LongPos.south(p)); + boolean east = blocks.contains(LongPos.east(p)); + boolean west = blocks.contains(LongPos.west(p)); + + if (up && down && north && south && east && west) continue; + + drawBlockFaces(poseStack, vc, p, up, down, north, south, east, west); + } + } + + public static void drawBlockFaces( + PoseStack poseStack, VertexConsumer vc, long posAsLong, + boolean up, boolean down, boolean north, boolean south, boolean east, boolean west) { + final float eps = 0.0025f; + float x0 = LongPos.getX(posAsLong) + eps; + float y0 = LongPos.getY(posAsLong) + eps; + float z0 = LongPos.getZ(posAsLong) + eps; + float x1 = LongPos.getX(posAsLong) + 1 - eps; + float y1 = LongPos.getY(posAsLong) + 1 - eps; + float z1 = LongPos.getZ(posAsLong) + 1 - eps; + + // Color (ARGB-ish but as floats) + float r = 0.2f, g = 0.8f, b = 1.0f, a = 0.18f; + + Matrix4f mat = poseStack.last().pose(); + + // IMPORTANT: vertex winding should be consistent (counter-clockwise) + if (!up) quad(mat, vc, x0,y1,z0, x1,y1,z0, x1,y1,z1, x0,y1,z1, r,g,b,a); + if (!down) quad(mat, vc, x0,y0,z1, x1,y0,z1, x1,y0,z0, x0,y0,z0, r,g,b,a); + + if (!north) quad(mat, vc, x1,y0,z0, x0,y0,z0, x0,y1,z0, x1,y1,z0, r,g,b,a); + if (!south) quad(mat, vc, x0,y0,z1, x1,y0,z1, x1,y1,z1, x0,y1,z1, r,g,b,a); + + if (!east) quad(mat, vc, x1,y0,z1, x1,y0,z0, x1,y1,z0, x1,y1,z1, r,g,b,a); + if (!west) quad(mat, vc, x0,y0,z0, x0,y0,z1, x0,y1,z1, x0,y1,z0, r,g,b,a); + } + + public static void quad( + Matrix4f mat, VertexConsumer vc, + float x0, float y0, float z0, + float x1, float y1, float z1, + float x2, float y2, float z2, + float x3, float y3, float z3, + float r, float g, float b, float a + ) { + // POSITION_COLOR format: ONLY position + color. + vc.addVertex(mat, x0, y0, z0).setColor(r, g, b, a); + vc.addVertex(mat, x1, y1, z1).setColor(r, g, b, a); + vc.addVertex(mat, x2, y2, z2).setColor(r, g, b, a); + vc.addVertex(mat, x3, y3, z3).setColor(r, g, b, a); + } +} diff --git a/src/main/java/net/xevianlight/aphelion/client/GravityDebugRender.java b/src/main/java/net/xevianlight/aphelion/client/GravityDebugRender.java new file mode 100644 index 0000000..dc1586c --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/client/GravityDebugRender.java @@ -0,0 +1,74 @@ +package net.xevianlight.aphelion.client; + +import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.blaze3d.vertex.VertexFormat; +import it.unimi.dsi.fastutil.longs.Long2IntMap; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderStateShard; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.server.IntegratedServer; +import net.minecraft.core.BlockPos; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.client.event.RenderLevelStageEvent; +import net.xevianlight.aphelion.Aphelion; +import net.xevianlight.aphelion.core.saveddata.GravitySavedData; +import net.xevianlight.aphelion.core.saveddata.types.GravityData; + +@EventBusSubscriber(modid = Aphelion.MOD_ID, value = Dist.CLIENT) +public class GravityDebugRender { + // Untextured translucent quads (POSITION_COLOR only) + private static final RenderType GRAVITY_FILL = RenderType.create( + "aphelion_gravity_fill", + DefaultVertexFormat.POSITION_COLOR, + VertexFormat.Mode.QUADS, + 256, + false, + true, + RenderType.CompositeState.builder() + .setShaderState(RenderStateShard.POSITION_COLOR_SHADER) + .setTransparencyState(RenderStateShard.TRANSLUCENT_TRANSPARENCY) + .setCullState(RenderStateShard.NO_CULL) + .setDepthTestState(RenderStateShard.LEQUAL_DEPTH_TEST) + .setWriteMaskState(RenderStateShard.COLOR_DEPTH_WRITE) + .createCompositeState(true) + ); + + @SubscribeEvent + public static void onRenderLevel(RenderLevelStageEvent event) { + // One stage only (pick one that exists and looks good) + if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_TRANSLUCENT_BLOCKS) return; + + Minecraft mc = Minecraft.getInstance(); + if (mc.level == null || mc.player == null) return; + if (!mc.gui.getDebugOverlay().showDebugScreen()) return; + + PoseStack poseStack = event.getPoseStack(); + var cam = mc.gameRenderer.getMainCamera(); + var camPos = cam.getPosition(); + + poseStack.pushPose(); + poseStack.translate(-camPos.x, -camPos.y, -camPos.z); + + // I'm lazy, so i'm just gonna make this work on a singleplayer server and call it a day :P + IntegratedServer singleplayer = mc.getSingleplayerServer(); + if (singleplayer == null) return; + + MultiBufferSource.BufferSource bufferSource = mc.renderBuffers().bufferSource(); + VertexConsumer vc = bufferSource.getBuffer(GRAVITY_FILL); + + for (Long2IntMap.Entry gravityEntry : GravitySavedData.get(singleplayer.getLevel(mc.level.dimension()))._debug_getGravityData().long2IntEntrySet()) { + GravityData d = GravityData.unpack(gravityEntry.getIntValue()); + BlockPos p = BlockPos.of(gravityEntry.getLongKey()); + + DebugRenderUtils.drawSphere(poseStack, vc, p.getCenter().toVector3f(), d.getRadius()); + } + + poseStack.popPose(); + bufferSource.endBatch(GRAVITY_FILL); + } +} diff --git a/src/main/java/net/xevianlight/aphelion/client/OxygenDebugRender.java b/src/main/java/net/xevianlight/aphelion/client/OxygenDebugRender.java index f9e9423..87bf01a 100644 --- a/src/main/java/net/xevianlight/aphelion/client/OxygenDebugRender.java +++ b/src/main/java/net/xevianlight/aphelion/client/OxygenDebugRender.java @@ -17,6 +17,8 @@ import net.neoforged.neoforge.client.event.RenderLevelStageEvent; import net.xevianlight.aphelion.Aphelion; import org.joml.Matrix4f; +import java.util.Collection; + @EventBusSubscriber(modid = Aphelion.MOD_ID, value = Dist.CLIENT) public final class OxygenDebugRender { @@ -56,63 +58,9 @@ public final class OxygenDebugRender { MultiBufferSource.BufferSource bufferSource = mc.renderBuffers().bufferSource(); VertexConsumer vc = bufferSource.getBuffer(OXYGEN_FILL); - // Render surface faces only (fast + pretty) - for (long l : ClientOxygenCache.OXYGEN) { - BlockPos p = BlockPos.of(l); - drawSurfaceFaces(poseStack, vc, p); - } + DebugRenderUtils.drawBlockArea(poseStack, vc, ClientOxygenCache.OXYGEN); poseStack.popPose(); bufferSource.endBatch(OXYGEN_FILL); } - - private static void drawSurfaceFaces(PoseStack poseStack, VertexConsumer vc, BlockPos p) { - // Neighbor checks: only render faces exposed to non-oxygen - boolean up = ClientOxygenCache.OXYGEN.contains(p.above().asLong()); - boolean down = ClientOxygenCache.OXYGEN.contains(p.below().asLong()); - boolean north = ClientOxygenCache.OXYGEN.contains(p.north().asLong()); - boolean south = ClientOxygenCache.OXYGEN.contains(p.south().asLong()); - boolean east = ClientOxygenCache.OXYGEN.contains(p.east().asLong()); - boolean west = ClientOxygenCache.OXYGEN.contains(p.west().asLong()); - - if (up && down && north && south && east && west) return; - - final float eps = 0.0025f; - float x0 = p.getX() + eps; - float y0 = p.getY() + eps; - float z0 = p.getZ() + eps; - float x1 = p.getX() + 1 - eps; - float y1 = p.getY() + 1 - eps; - float z1 = p.getZ() + 1 - eps; - - // Color (ARGB-ish but as floats) - float r = 0.2f, g = 0.8f, b = 1.0f, a = 0.18f; - - Matrix4f mat = poseStack.last().pose(); - - // IMPORTANT: vertex winding should be consistent (counter-clockwise) - if (!up) quad(mat, vc, x0,y1,z0, x1,y1,z0, x1,y1,z1, x0,y1,z1, r,g,b,a); - if (!down) quad(mat, vc, x0,y0,z1, x1,y0,z1, x1,y0,z0, x0,y0,z0, r,g,b,a); - - if (!north) quad(mat, vc, x1,y0,z0, x0,y0,z0, x0,y1,z0, x1,y1,z0, r,g,b,a); - if (!south) quad(mat, vc, x0,y0,z1, x1,y0,z1, x1,y1,z1, x0,y1,z1, r,g,b,a); - - if (!east) quad(mat, vc, x1,y0,z1, x1,y0,z0, x1,y1,z0, x1,y1,z1, r,g,b,a); - if (!west) quad(mat, vc, x0,y0,z0, x0,y0,z1, x0,y1,z1, x0,y1,z0, r,g,b,a); - } - - private static void quad( - Matrix4f mat, VertexConsumer vc, - float x0, float y0, float z0, - float x1, float y1, float z1, - float x2, float y2, float z2, - float x3, float y3, float z3, - float r, float g, float b, float a - ) { - // POSITION_COLOR format: ONLY position + color. - vc.addVertex(mat, x0, y0, z0).setColor(r, g, b, a); - vc.addVertex(mat, x1, y1, z1).setColor(r, g, b, a); - vc.addVertex(mat, x2, y2, z2).setColor(r, g, b, a); - vc.addVertex(mat, x3, y3, z3).setColor(r, g, b, a); - } } diff --git a/src/main/java/net/xevianlight/aphelion/core/init/ModBlockEntities.java b/src/main/java/net/xevianlight/aphelion/core/init/ModBlockEntities.java index 600035d..e8824f1 100644 --- a/src/main/java/net/xevianlight/aphelion/core/init/ModBlockEntities.java +++ b/src/main/java/net/xevianlight/aphelion/core/init/ModBlockEntities.java @@ -51,4 +51,9 @@ public class ModBlockEntities { BLOCK_ENTITIES.register("rocket_assembler_block_entity", () -> BlockEntityType.Builder.of( RocketAssemblerBlockEntity::new, ModBlocks.ROCKET_ASSEMBLER_BLOCK.get()).build(null) ); + + public static final Supplier> GRAVITY_TEST_BLOCK_ENTITY = + BLOCK_ENTITIES.register("gravity_test_block_entity", () -> BlockEntityType.Builder.of( + GravityTestBlockEntity::new, ModBlocks.GRAVITY_TEST_BLOCK.get()).build(null) + ); } diff --git a/src/main/java/net/xevianlight/aphelion/core/init/ModBlocks.java b/src/main/java/net/xevianlight/aphelion/core/init/ModBlocks.java index ff032a1..a237fbb 100644 --- a/src/main/java/net/xevianlight/aphelion/core/init/ModBlocks.java +++ b/src/main/java/net/xevianlight/aphelion/core/init/ModBlocks.java @@ -6,6 +6,7 @@ import net.neoforged.neoforge.registries.DeferredRegister; import net.xevianlight.aphelion.Aphelion; import net.xevianlight.aphelion.block.custom.*; import net.xevianlight.aphelion.block.dummy.VAFMultiblockDummyBlock; +import net.xevianlight.aphelion.block.entity.custom.GravityTestBlockEntity; public class ModBlocks { public static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(Aphelion.MOD_ID); @@ -20,4 +21,5 @@ public class ModBlocks { public static final DeferredBlock VAF_MULTIBLOCK_DUMMY_BLOCK = BLOCKS.register("vaf_dummy_block", () -> new VAFMultiblockDummyBlock(VAFMultiblockDummyBlock.getProperties())); public static final DeferredBlock OXYGEN_TEST_BLOCK = BLOCKS.register("oxygen_test_block", () -> new OxygenTestBlock(OxygenTestBlock.getProperties())); public static final DeferredBlock ROCKET_ASSEMBLER_BLOCK = BLOCKS.register("rocket_assemblerblock", () -> new RocketAssemblerBlock(RocketAssemblerBlock.getProperties())); + public static final DeferredBlock GRAVITY_TEST_BLOCK = BLOCKS.register("gravity_test_block", () -> new GravityTestBlock(GravityTestBlock.getProperties())); } diff --git a/src/main/java/net/xevianlight/aphelion/core/init/ModItems.java b/src/main/java/net/xevianlight/aphelion/core/init/ModItems.java index 3edecd6..3dd3db1 100644 --- a/src/main/java/net/xevianlight/aphelion/core/init/ModItems.java +++ b/src/main/java/net/xevianlight/aphelion/core/init/ModItems.java @@ -36,6 +36,7 @@ public static final DeferredItem MUSIC_DISC_BIT_SHIFT = ITEMS.register("mu public static final DeferredItem ARC_FURNACE_CASING_BLOCK = ITEMS.register("arc_furnace_casing", () -> new BlockItem(ModBlocks.ARC_FURNACE_CASING_BLOCK.get(), ArcFurnaceCasingBlock.getItemProperties())); public static final DeferredItem VACUUM_ARC_FURNACE_CONTROLLER = ITEMS.register("vacuum_arc_furnace_controller", () -> new BlockItem(ModBlocks.VACUUM_ARC_FURNACE_CONTROLLER.get(), VacuumArcFurnaceController.getItemProperties())); public static final DeferredItem OXYGEN_TEST_BLOCK = ITEMS.register("oxygen_test_block", () -> new BlockItem(ModBlocks.OXYGEN_TEST_BLOCK.get(), new Item.Properties())); + public static final DeferredItem GRAVITY_TEST_BLOCK = ITEMS.register("gravity_test_block", () -> new BlockItem(ModBlocks.GRAVITY_TEST_BLOCK.get(), new Item.Properties())); public static final DeferredItem LAUNCH_PAD = ITEMS.register("launch_pad", () -> new BlockItem(ModBlocks.LAUNCH_PAD.get(), LaunchPad.getItemProperties())); // public static final DeferredItem VAF_MULTIBLOCK_DUMMY_BLOCK = ITEMS.register("vaf_multiblock_dummy_block", () -> new BlockItem(ModBlocks.VAF_MULTIBLOCK_DUMMY_BLOCK.get(), VAFMultiblockDummyBlock.getItemProperties())); } diff --git a/src/main/java/net/xevianlight/aphelion/core/saveddata/GravitySavedData.java b/src/main/java/net/xevianlight/aphelion/core/saveddata/GravitySavedData.java index 435cb33..bb888e5 100644 --- a/src/main/java/net/xevianlight/aphelion/core/saveddata/GravitySavedData.java +++ b/src/main/java/net/xevianlight/aphelion/core/saveddata/GravitySavedData.java @@ -94,6 +94,9 @@ public class GravitySavedData extends SavedData { gravityData.put(pos.asLong(), data.pack()); } + public Long2IntOpenHashMap _debug_getGravityData() { + return gravityData; + } /** diff --git a/src/main/java/net/xevianlight/aphelion/datagen/ModBlockLootTableProvider.java b/src/main/java/net/xevianlight/aphelion/datagen/ModBlockLootTableProvider.java index 7471d65..9c7c521 100644 --- a/src/main/java/net/xevianlight/aphelion/datagen/ModBlockLootTableProvider.java +++ b/src/main/java/net/xevianlight/aphelion/datagen/ModBlockLootTableProvider.java @@ -26,6 +26,8 @@ public class ModBlockLootTableProvider extends BlockLootSubProvider { dropSelf(ModBlocks.OXYGEN_TEST_BLOCK.get()); dropOther(ModBlocks.VAF_MULTIBLOCK_DUMMY_BLOCK.get(), ItemStack.EMPTY.getItem()); dropSelf(ModBlocks.LAUNCH_PAD.get()); + dropSelf(ModBlocks.GRAVITY_TEST_BLOCK.get()); + dropSelf(ModBlocks.ROCKET_ASSEMBLER_BLOCK.get()); } @Override diff --git a/src/main/java/net/xevianlight/aphelion/datagen/ModBlockStateProvider.java b/src/main/java/net/xevianlight/aphelion/datagen/ModBlockStateProvider.java index 04b15a2..95fdb28 100644 --- a/src/main/java/net/xevianlight/aphelion/datagen/ModBlockStateProvider.java +++ b/src/main/java/net/xevianlight/aphelion/datagen/ModBlockStateProvider.java @@ -32,7 +32,9 @@ public class ModBlockStateProvider extends BlockStateProvider { // blockItem(ModBlocks.LAUNCH_PAD); blockItem(ModBlocks.ARC_FURNACE_CASING_BLOCK); + blockWithItem(ModBlocks.OXYGEN_TEST_BLOCK); + blockWithItem(ModBlocks.GRAVITY_TEST_BLOCK); } private void blockWithItem(DeferredBlock deferredBlock) { diff --git a/src/main/java/net/xevianlight/aphelion/event/ModBusEvents.java b/src/main/java/net/xevianlight/aphelion/event/ModBusEvents.java index 938ea7f..6ec3e2c 100644 --- a/src/main/java/net/xevianlight/aphelion/event/ModBusEvents.java +++ b/src/main/java/net/xevianlight/aphelion/event/ModBusEvents.java @@ -16,9 +16,11 @@ import net.xevianlight.aphelion.core.init.ModBlockEntities; import net.xevianlight.aphelion.network.ClientPlayerStateUpdateHandler; import net.xevianlight.aphelion.network.RocketPayloadHandlers; import net.xevianlight.aphelion.network.PartitionPayloadHandler; +import net.xevianlight.aphelion.network.UpdateGravityTestBlockHandler; import net.xevianlight.aphelion.network.packet.ClientPlayerStateUpdatePacket; import net.xevianlight.aphelion.network.packet.PartitionPayload; import net.xevianlight.aphelion.network.packet.RocketLaunchPayload; +import net.xevianlight.aphelion.network.packet.UpdateGravityTestBlockPacket; @EventBusSubscriber(modid = Aphelion.MOD_ID) public class ModBusEvents { @@ -57,5 +59,10 @@ public class ModBusEvents { ClientPlayerStateUpdateHandler::handleDataOnMain ); + registrar.playToServer( + UpdateGravityTestBlockPacket.TYPE, + UpdateGravityTestBlockPacket.STREAM_CODEC, + UpdateGravityTestBlockHandler::handleDataOnMain + ); } } diff --git a/src/main/java/net/xevianlight/aphelion/network/UpdateGravityTestBlockHandler.java b/src/main/java/net/xevianlight/aphelion/network/UpdateGravityTestBlockHandler.java new file mode 100644 index 0000000..d2934b6 --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/network/UpdateGravityTestBlockHandler.java @@ -0,0 +1,27 @@ +package net.xevianlight.aphelion.network; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import net.xevianlight.aphelion.block.entity.custom.GravityTestBlockEntity; +import net.xevianlight.aphelion.network.packet.UpdateGravityTestBlockPacket; + +public class UpdateGravityTestBlockHandler { + public static void handleDataOnMain(UpdateGravityTestBlockPacket packet, IPayloadContext context) { + context.enqueueWork(() -> { + BlockPos pos = packet.pos(); + float radius = packet.radius(); + float strength = packet.strength(); + + Level level = context.player().level(); + if (level.getBlockEntity(pos) instanceof GravityTestBlockEntity blockEntity) { + blockEntity.setRadius(radius); + blockEntity.setStrength(strength); + blockEntity.sendUpdate(); + level.sendBlockUpdated(pos, level.getBlockState(pos), level.getBlockState(pos), Block.UPDATE_ALL); + } + }); + } +} diff --git a/src/main/java/net/xevianlight/aphelion/network/packet/UpdateGravityTestBlockPacket.java b/src/main/java/net/xevianlight/aphelion/network/packet/UpdateGravityTestBlockPacket.java new file mode 100644 index 0000000..7467817 --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/network/packet/UpdateGravityTestBlockPacket.java @@ -0,0 +1,30 @@ +package net.xevianlight.aphelion.network.packet; + +import io.netty.buffer.ByteBuf; +import net.minecraft.core.BlockPos; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import net.xevianlight.aphelion.Aphelion; + +public record UpdateGravityTestBlockPacket(BlockPos pos, float radius, float strength) implements CustomPacketPayload { + + public static final CustomPacketPayload.Type TYPE = + new CustomPacketPayload.Type<>(ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "update_oxygen_test_block")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, + UpdateGravityTestBlockPacket::pos, + ByteBufCodecs.FLOAT, + UpdateGravityTestBlockPacket::radius, + ByteBufCodecs.FLOAT, + UpdateGravityTestBlockPacket::strength, + UpdateGravityTestBlockPacket::new + ); + + @Override + public CustomPacketPayload.Type type() { + return TYPE; + } +} diff --git a/src/main/java/net/xevianlight/aphelion/screen/GravityTestBlockMenu.java b/src/main/java/net/xevianlight/aphelion/screen/GravityTestBlockMenu.java new file mode 100644 index 0000000..3999fca --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/screen/GravityTestBlockMenu.java @@ -0,0 +1,110 @@ +package net.xevianlight.aphelion.screen; + +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.BrewingStandMenu; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.neoforged.neoforge.items.SlotItemHandler; +import net.xevianlight.aphelion.block.entity.custom.GravityTestBlockEntity; +import net.xevianlight.aphelion.block.entity.custom.TestBlockEntity; +import org.jetbrains.annotations.NotNull; + +public class GravityTestBlockMenu extends AbstractContainerMenu { + public final GravityTestBlockEntity blockEntity; + private final Level level; + + public GravityTestBlockMenu(int i, Inventory inventory, FriendlyByteBuf extraData) { + this(i, inventory, inventory.player.level().getBlockEntity(extraData.readBlockPos())); + } + + public GravityTestBlockMenu(int i, Inventory inventory, BlockEntity blockEntity) { + super(ModMenuTypes.GRAVITY_TEST_BLOCK_MENU.get(), i); + this.blockEntity = ((GravityTestBlockEntity) blockEntity); + this.level = inventory.player.level(); + + // Init stuff + addPlayerInventory(inventory); + addPlayerHotbar(inventory); + + + } + + @Override + public boolean stillValid(Player player) { + return true; + } + + // CREDIT GOES TO: diesieben07 | https://github.com/diesieben07/SevenCommons + // must assign a slot number to each of the slots used by the GUI. + // For this container, we can see both the tile inventory's slots as well as the player inventory slots and the hotbar. + // Each time we add a Slot to the container, it automatically increases the slotIndex, which means + // 0 - 8 = hotbar slots (which will map to the InventoryPlayer slot numbers 0 - 8) + // 9 - 35 = player inventory slots (which map to the InventoryPlayer slot numbers 9 - 35) + // 36 - 44 = TileInventory slots, which map to our TileEntity slot numbers 0 - 8) + private static final int HOTBAR_SLOT_COUNT = 9; + private static final int PLAYER_INVENTORY_ROW_COUNT = 3; + private static final int PLAYER_INVENTORY_COLUMN_COUNT = 9; + private static final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT; + private static final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT; + private static final int VANILLA_FIRST_SLOT_INDEX = 0; + private static final int TE_INVENTORY_FIRST_SLOT_INDEX = VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT; + + // THIS YOU HAVE TO DEFINE! + private static final int TE_INVENTORY_SLOT_COUNT = 0; // must be the number of slots you have! + @Override + public @NotNull ItemStack quickMoveStack(Player playerIn, int pIndex) { + Slot sourceSlot = slots.get(pIndex); + if (sourceSlot == null || !sourceSlot.hasItem()) return ItemStack.EMPTY; //EMPTY_ITEM + ItemStack sourceStack = sourceSlot.getItem(); + ItemStack copyOfSourceStack = sourceStack.copy(); + + // Check if the slot clicked is one of the vanilla container slots + if (pIndex < VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT) { + // This is a vanilla container slot so merge the stack into the tile inventory + if (!moveItemStackTo(sourceStack, TE_INVENTORY_FIRST_SLOT_INDEX, TE_INVENTORY_FIRST_SLOT_INDEX + + TE_INVENTORY_SLOT_COUNT, false)) { + blockEntity.sendUpdate(); + return ItemStack.EMPTY; // EMPTY_ITEM + } + } else if (pIndex < TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT) { + // This is a TE slot so merge the stack into the players inventory + if (!moveItemStackTo(sourceStack, VANILLA_FIRST_SLOT_INDEX, VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT, false)) { + blockEntity.sendUpdate(); + return ItemStack.EMPTY; + } + } else { + System.out.println("Invalid slotIndex:" + pIndex); + return ItemStack.EMPTY; + } + // If stack size == 0 (the entire stack was moved) set slot contents to null + if (sourceStack.getCount() == 0) { + sourceSlot.set(ItemStack.EMPTY); + blockEntity.sendUpdate(); + } else { + blockEntity.sendUpdate(); + sourceSlot.setChanged(); + } + sourceSlot.onTake(playerIn, sourceStack); + blockEntity.sendUpdate(); + return copyOfSourceStack; + } + + private void addPlayerInventory(Inventory playerInventory) { + for (int i = 0; i < 3; ++i) { + for (int l = 0; l < 9; ++l) { + this.addSlot(new Slot(playerInventory, l + i * 9 + 9, 8 + l * 18, 84 + i * 18)); + } + } + } + + private void addPlayerHotbar(Inventory playerInventory) { + for (int i = 0; i < 9; ++i) { + this.addSlot(new Slot(playerInventory, i, 8 + i * 18, 142)); + } + } +} diff --git a/src/main/java/net/xevianlight/aphelion/screen/GravityTestBlockScreen.java b/src/main/java/net/xevianlight/aphelion/screen/GravityTestBlockScreen.java new file mode 100644 index 0000000..b38c3df --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/screen/GravityTestBlockScreen.java @@ -0,0 +1,94 @@ +package net.xevianlight.aphelion.screen; + +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.StringWidget; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.client.gui.screens.inventory.FurnaceScreen; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; +import net.neoforged.neoforge.network.PacketDistributor; +import net.xevianlight.aphelion.Aphelion; +import net.xevianlight.aphelion.network.packet.UpdateGravityTestBlockPacket; + +public class GravityTestBlockScreen extends AbstractContainerScreen { + + private static final ResourceLocation GUI_TEXTURE = + ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "textures/gui/gravity_test_block/gui.png"); + + public GravityTestBlockScreen(GravityTestBlockMenu menu, Inventory playerInventory, Component title) { + super(menu, playerInventory, title); + } + + private StringWidget gravityWidget; + private StringWidget rangeWidget; + + @Override + protected void init() { + super.init(); + + // Gets rid of labels + this.inventoryLabelY = 73; + this.titleLabelY = 5; + + // Increase Gravity + this.addRenderableWidget(Button.builder(Component.literal("+"), (button) -> { + PacketDistributor.sendToServer(new UpdateGravityTestBlockPacket(menu.blockEntity.getBlockPos(), menu.blockEntity.areaSize, menu.blockEntity.gravityStrength + 0.1f)); + }).bounds(this.leftPos + 7, this.topPos + 30, 9, 9).build()); + // Decrease Gravity + this.addRenderableWidget(Button.builder(Component.literal("-"), (button) -> { + PacketDistributor.sendToServer(new UpdateGravityTestBlockPacket(menu.blockEntity.getBlockPos(), menu.blockEntity.areaSize, menu.blockEntity.gravityStrength - 0.1f)); + }).bounds(this.leftPos + 19, this.topPos + 30, 9, 9).build()); + // Increase Radius + this.addRenderableWidget(Button.builder(Component.literal("+"), (button) -> { + PacketDistributor.sendToServer(new UpdateGravityTestBlockPacket(menu.blockEntity.getBlockPos(), menu.blockEntity.areaSize + 1, menu.blockEntity.gravityStrength)); + }).bounds(this.leftPos + 135, this.topPos + 32, 9, 9).build()); + // Decrease Radius + this.addRenderableWidget(Button.builder(Component.literal("-"), (button) -> { + PacketDistributor.sendToServer(new UpdateGravityTestBlockPacket(menu.blockEntity.getBlockPos(), menu.blockEntity.areaSize - 1, menu.blockEntity.gravityStrength)); + }).bounds(this.leftPos + 147, this.topPos + 32, 9, 9).build()); + + // Current Gravity + gravityWidget = new StringWidget( + this.leftPos + 11, + this.topPos+46, + 26, + 9, + Component.literal("" + menu.blockEntity.gravityStrength), + this.font); + this.addRenderableWidget(gravityWidget); + + // Current Radius + rangeWidget = new StringWidget( + this.leftPos + 139, + this.topPos+46, + 26, + 9, + Component.literal("" + menu.blockEntity.areaSize), + this.font); + this.addRenderableWidget(rangeWidget); + } + + @Override + protected void renderBg(GuiGraphics pGuiGraphics, float pPartialTick, int pMouseX, int pMouseY) { + RenderSystem.setShader(GameRenderer::getPositionTexShader); + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + RenderSystem.setShaderTexture(0, GUI_TEXTURE); + int x = (width - imageWidth) / 2; + int y = (height - imageHeight) / 2; + + pGuiGraphics.blit(GUI_TEXTURE, x, y, 0, 0, imageWidth, imageHeight); + } + + @Override + public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float delta) { + renderBackground(guiGraphics, mouseX, mouseY, delta); + super.render(guiGraphics, mouseX, mouseY, delta); + renderTooltip(guiGraphics, mouseX, mouseY); + gravityWidget.setMessage(Component.literal(String.format("%.1f", menu.blockEntity.gravityStrength))); + rangeWidget.setMessage(Component.literal("" + menu.blockEntity.areaSize)); + } +} diff --git a/src/main/java/net/xevianlight/aphelion/screen/ModMenuTypes.java b/src/main/java/net/xevianlight/aphelion/screen/ModMenuTypes.java index 635e168..c9afa6d 100644 --- a/src/main/java/net/xevianlight/aphelion/screen/ModMenuTypes.java +++ b/src/main/java/net/xevianlight/aphelion/screen/ModMenuTypes.java @@ -10,6 +10,8 @@ import net.neoforged.neoforge.registries.DeferredHolder; import net.neoforged.neoforge.registries.DeferredRegister; import net.xevianlight.aphelion.Aphelion; +import java.awt.*; + public class ModMenuTypes { public static final DeferredRegister> MENUS = DeferredRegister.create(Registries.MENU, Aphelion.MOD_ID); @@ -23,6 +25,9 @@ public class ModMenuTypes { public static DeferredHolder,MenuType> VACUUM_ARC_FURNACE_MENU = registerMenuType("vacuum_arc_furnace_menu", VacuumArcFurnaceMenu::new); + public static DeferredHolder,MenuType> GRAVITY_TEST_BLOCK_MENU = + registerMenuType("gravity_test_block_menu", GravityTestBlockMenu::new); + private static DeferredHolder, MenuType> registerMenuType(String name, IContainerFactory factory) { return MENUS.register(name, () -> IMenuTypeExtension.create(factory)); diff --git a/src/main/java/net/xevianlight/aphelion/systems/GravityService.java b/src/main/java/net/xevianlight/aphelion/systems/GravityService.java index 89fcae1..3804947 100644 --- a/src/main/java/net/xevianlight/aphelion/systems/GravityService.java +++ b/src/main/java/net/xevianlight/aphelion/systems/GravityService.java @@ -13,9 +13,13 @@ import net.xevianlight.aphelion.core.saveddata.types.GravityData; public class GravityService { - /// If i did this right, there SHOULDN'T be a way to break client/server separation with this... - /// you shouldn't be able to get the "ServerLevel" object from the Client side unless you're already - /// breaking that rule, in which case, go for it lmfao + public static void setGravityArea(ServerLevel level, BlockPos pos, float accel, int radius) { + GravitySavedData.get(level).setGravityRegion(pos, new GravityData(accel, radius)); + } + + public static void removeGravityArea(ServerLevel level, BlockPos pos) { + GravitySavedData.get(level).removeGravityRegion(pos); + } public static float getGravityAccel(Level level, BlockPos pos) { if (level.isClientSide) { diff --git a/src/main/resources/assets/aphelion/textures/block/gravity_test_block.png b/src/main/resources/assets/aphelion/textures/block/gravity_test_block.png new file mode 100644 index 0000000..8a8f174 Binary files /dev/null and b/src/main/resources/assets/aphelion/textures/block/gravity_test_block.png differ diff --git a/src/main/resources/assets/aphelion/textures/gui/gravity_test_block/gui.png b/src/main/resources/assets/aphelion/textures/gui/gravity_test_block/gui.png new file mode 100644 index 0000000..f567b2a Binary files /dev/null and b/src/main/resources/assets/aphelion/textures/gui/gravity_test_block/gui.png differ diff --git a/src/main/resources/assets/aphelion/textures/gui/test_block/gui.png b/src/main/resources/assets/aphelion/textures/gui/test_block/gui.png index 9f70154..f567b2a 100644 Binary files a/src/main/resources/assets/aphelion/textures/gui/test_block/gui.png and b/src/main/resources/assets/aphelion/textures/gui/test_block/gui.png differ