mirror of
https://github.com/XevianLight/Aphelion.git
synced 2026-05-11 01:50:56 +01:00
added gravity test block with gui and debug renderer
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<? extends BaseEntityBlock> 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -42,6 +42,8 @@ public class OxygenTestRenderer implements BlockEntityRenderer<OxygenTestBlockEn
|
||||
// If in debug mode, renders a model made from the blocks
|
||||
// that are currently returned by toBlockPositions(OxygenTestBlockEntity).
|
||||
public void render(OxygenTestBlockEntity be, float partialTick, PoseStack poseStack, MultiBufferSource buffer, int packedLight, int packedOverlay) {
|
||||
if (true) return; // i think this is all deprecated now
|
||||
|
||||
// This bit's debug only, folks!
|
||||
if (!Minecraft.getInstance().gui.getDebugOverlay().showDebugScreen()) return;
|
||||
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
package net.xevianlight.aphelion.client;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
public class DebugRenderUtils {
|
||||
|
||||
/// Utilities for dealing with longs instead of BlockPos
|
||||
/// I am not actually sure if this is faster or not. it probably is
|
||||
/// 99% sure that this breaks in edge cases
|
||||
public static class LongPos {
|
||||
private static final int PACKED_X_LENGTH = 26;
|
||||
private static final int PACKED_Y_LENGTH = 12;
|
||||
private static final int PACKED_Z_LENGTH = 26;
|
||||
private static final long PACKED_X_MASK = 67108863L;
|
||||
private static final long PACKED_Y_MASK = 4095L;
|
||||
private static final long PACKED_Z_MASK = 67108863L;
|
||||
private static final int Y_OFFSET = 0;
|
||||
private static final int Z_OFFSET = 12;
|
||||
private static final int X_OFFSET = 38;
|
||||
private static final long Y_MAGIC = PACKED_Y_MASK << Y_OFFSET;
|
||||
private static final long Z_MAGIC = PACKED_Z_MASK << Z_OFFSET;
|
||||
private static final long X_MAGIC = PACKED_X_MASK << X_OFFSET;
|
||||
|
||||
// no safeguard for the maximum values, but those are
|
||||
public static long above(long pos) {
|
||||
long y = (((pos & Y_MAGIC) >> 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<BlockEntityType<GravityTestBlockEntity>> GRAVITY_TEST_BLOCK_ENTITY =
|
||||
BLOCK_ENTITIES.register("gravity_test_block_entity", () -> BlockEntityType.Builder.of(
|
||||
GravityTestBlockEntity::new, ModBlocks.GRAVITY_TEST_BLOCK.get()).build(null)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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<Block> VAF_MULTIBLOCK_DUMMY_BLOCK = BLOCKS.register("vaf_dummy_block", () -> new VAFMultiblockDummyBlock(VAFMultiblockDummyBlock.getProperties()));
|
||||
public static final DeferredBlock<Block> OXYGEN_TEST_BLOCK = BLOCKS.register("oxygen_test_block", () -> new OxygenTestBlock(OxygenTestBlock.getProperties()));
|
||||
public static final DeferredBlock<Block> ROCKET_ASSEMBLER_BLOCK = BLOCKS.register("rocket_assemblerblock", () -> new RocketAssemblerBlock(RocketAssemblerBlock.getProperties()));
|
||||
public static final DeferredBlock<Block> GRAVITY_TEST_BLOCK = BLOCKS.register("gravity_test_block", () -> new GravityTestBlock(GravityTestBlock.getProperties()));
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ public static final DeferredItem<Item> MUSIC_DISC_BIT_SHIFT = ITEMS.register("mu
|
||||
public static final DeferredItem<BlockItem> ARC_FURNACE_CASING_BLOCK = ITEMS.register("arc_furnace_casing", () -> new BlockItem(ModBlocks.ARC_FURNACE_CASING_BLOCK.get(), ArcFurnaceCasingBlock.getItemProperties()));
|
||||
public static final DeferredItem<BlockItem> VACUUM_ARC_FURNACE_CONTROLLER = ITEMS.register("vacuum_arc_furnace_controller", () -> new BlockItem(ModBlocks.VACUUM_ARC_FURNACE_CONTROLLER.get(), VacuumArcFurnaceController.getItemProperties()));
|
||||
public static final DeferredItem<BlockItem> OXYGEN_TEST_BLOCK = ITEMS.register("oxygen_test_block", () -> new BlockItem(ModBlocks.OXYGEN_TEST_BLOCK.get(), new Item.Properties()));
|
||||
public static final DeferredItem<BlockItem> GRAVITY_TEST_BLOCK = ITEMS.register("gravity_test_block", () -> new BlockItem(ModBlocks.GRAVITY_TEST_BLOCK.get(), new Item.Properties()));
|
||||
public static final DeferredItem<BlockItem> LAUNCH_PAD = ITEMS.register("launch_pad", () -> new BlockItem(ModBlocks.LAUNCH_PAD.get(), LaunchPad.getItemProperties()));
|
||||
// public static final DeferredItem<BlockItem> VAF_MULTIBLOCK_DUMMY_BLOCK = ITEMS.register("vaf_multiblock_dummy_block", () -> new BlockItem(ModBlocks.VAF_MULTIBLOCK_DUMMY_BLOCK.get(), VAFMultiblockDummyBlock.getItemProperties()));
|
||||
}
|
||||
|
||||
@@ -94,6 +94,9 @@ public class GravitySavedData extends SavedData {
|
||||
gravityData.put(pos.asLong(), data.pack());
|
||||
}
|
||||
|
||||
public Long2IntOpenHashMap _debug_getGravityData() {
|
||||
return gravityData;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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<UpdateGravityTestBlockPacket> TYPE =
|
||||
new CustomPacketPayload.Type<>(ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "update_oxygen_test_block"));
|
||||
|
||||
public static final StreamCodec<ByteBuf, UpdateGravityTestBlockPacket> STREAM_CODEC = StreamCodec.composite(
|
||||
BlockPos.STREAM_CODEC,
|
||||
UpdateGravityTestBlockPacket::pos,
|
||||
ByteBufCodecs.FLOAT,
|
||||
UpdateGravityTestBlockPacket::radius,
|
||||
ByteBufCodecs.FLOAT,
|
||||
UpdateGravityTestBlockPacket::strength,
|
||||
UpdateGravityTestBlockPacket::new
|
||||
);
|
||||
|
||||
@Override
|
||||
public CustomPacketPayload.Type<? extends CustomPacketPayload> type() {
|
||||
return TYPE;
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<GravityTestBlockMenu> {
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -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<MenuType<?>> MENUS =
|
||||
DeferredRegister.create(Registries.MENU, Aphelion.MOD_ID);
|
||||
@@ -23,6 +25,9 @@ public class ModMenuTypes {
|
||||
public static DeferredHolder<MenuType<?>,MenuType<VacuumArcFurnaceMenu>> VACUUM_ARC_FURNACE_MENU =
|
||||
registerMenuType("vacuum_arc_furnace_menu", VacuumArcFurnaceMenu::new);
|
||||
|
||||
public static DeferredHolder<MenuType<?>,MenuType<GravityTestBlockMenu>> GRAVITY_TEST_BLOCK_MENU =
|
||||
registerMenuType("gravity_test_block_menu", GravityTestBlockMenu::new);
|
||||
|
||||
private static <T extends AbstractContainerMenu>DeferredHolder<MenuType<?>, MenuType<T>> registerMenuType(String name,
|
||||
IContainerFactory<T> factory) {
|
||||
return MENUS.register(name, () -> IMenuTypeExtension.create(factory));
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 280 B |
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 17 KiB |
Reference in New Issue
Block a user