diff --git a/src/main/java/net/xevianlight/aphelion/Aphelion.java b/src/main/java/net/xevianlight/aphelion/Aphelion.java index 4510d86..4101621 100644 --- a/src/main/java/net/xevianlight/aphelion/Aphelion.java +++ b/src/main/java/net/xevianlight/aphelion/Aphelion.java @@ -156,7 +156,8 @@ public class Aphelion { @SubscribeEvent public static void onClientTick(ClientTickEvent.Post e) { - EnvironmentSavedData.refreshFromIntegratedServerIfNeeded(Minecraft.getInstance(), 64, 10000); + if (!Minecraft.getInstance().gui.getDebugOverlay().showDebugScreen()) return; + EnvironmentSavedData.refreshFromIntegratedServerIfNeeded(Minecraft.getInstance(), 64, 50000); } } } diff --git a/src/main/java/net/xevianlight/aphelion/block/custom/OxygenTestBlock.java b/src/main/java/net/xevianlight/aphelion/block/custom/OxygenTestBlock.java index 5c615ae..180da0e 100644 --- a/src/main/java/net/xevianlight/aphelion/block/custom/OxygenTestBlock.java +++ b/src/main/java/net/xevianlight/aphelion/block/custom/OxygenTestBlock.java @@ -4,33 +4,29 @@ import com.mojang.serialization.MapCodec; import net.minecraft.core.BlockPos; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.BaseEntityBlock; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityTicker; -import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; +import net.xevianlight.aphelion.block.custom.base.BasicEntityBlock; import net.xevianlight.aphelion.block.entity.custom.OxygenTestBlockEntity; -import net.xevianlight.aphelion.block.entity.custom.TestBlockEntity; -import net.xevianlight.aphelion.core.init.ModBlockEntities; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class OxygenTestBlock extends BaseEntityBlock { +public class OxygenTestBlock extends BasicEntityBlock { public OxygenTestBlock(Properties properties) { - super(properties); + super(properties, true); } public static final MapCodec CODEC = simpleCodec(OxygenTestBlock::new); @Override - protected MapCodec codec() { + protected @NotNull MapCodec codec() { return CODEC; } @Override - public @Nullable BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) { + public @Nullable BlockEntity newBlockEntity(@NotNull BlockPos blockPos, @NotNull BlockState blockState) { return new OxygenTestBlockEntity(blockPos, blockState); } @@ -39,21 +35,13 @@ public class OxygenTestBlock extends BaseEntityBlock { } @Override - public @Nullable BlockEntityTicker getTicker(Level level, BlockState state, BlockEntityType blockEntityType) { - if (level.isClientSide) { - return null; - } - return createTickerHelper(blockEntityType, ModBlockEntities.OXYGEN_TEST_BLOCK_ENTITY.get(), (level1, blockPos, blockState, oxygenTestBlockEntity) -> oxygenTestBlockEntity.tick(level1, blockPos, blockState)); - - } - - @Override - public RenderShape getRenderShape(BlockState pState) { + @NotNull + public RenderShape getRenderShape(@NotNull BlockState pState) { return RenderShape.MODEL; } @Override - protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) { + 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 OxygenTestBlockEntity oxygenTestBlockEntity) { diff --git a/src/main/java/net/xevianlight/aphelion/block/custom/RocketAssemblerBlock.java b/src/main/java/net/xevianlight/aphelion/block/custom/RocketAssemblerBlock.java new file mode 100644 index 0000000..3a68912 --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/block/custom/RocketAssemblerBlock.java @@ -0,0 +1,44 @@ +package net.xevianlight.aphelion.block.custom; + +import com.mojang.serialization.MapCodec; +import net.minecraft.core.BlockPos; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.xevianlight.aphelion.block.custom.base.BasicHorizontalEntityBlock; +import net.xevianlight.aphelion.block.entity.custom.RocketAssemblerBlockEntity; +import org.jetbrains.annotations.Nullable; + +public class RocketAssemblerBlock extends BasicHorizontalEntityBlock { + + public RocketAssemblerBlock(Properties properties) { + super(properties, true); + } + + public static final MapCodec CODEC = simpleCodec(RocketAssemblerBlock::new); + + @Override + protected MapCodec codec() { + return CODEC; + } + + public static Properties getProperties() { + return Properties + .of() + .sound(SoundType.METAL) + .destroyTime(2f) + .explosionResistance(10f) + .requiresCorrectToolForDrops(); + } + + @Override + public @Nullable BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) { + return new RocketAssemblerBlockEntity(blockPos, blockState); + } +} diff --git a/src/main/java/net/xevianlight/aphelion/block/custom/base/BasicEntityBlock.java b/src/main/java/net/xevianlight/aphelion/block/custom/base/BasicEntityBlock.java new file mode 100644 index 0000000..4d6823d --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/block/custom/base/BasicEntityBlock.java @@ -0,0 +1,61 @@ +package net.xevianlight.aphelion.block.custom.base; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; +import net.minecraft.world.level.block.RenderShape; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityTicker; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public abstract class BasicEntityBlock extends BaseEntityBlock { + + private final boolean shouldTick; + private BlockEntityType entity; + + protected BasicEntityBlock(Properties properties, boolean shouldTick) { + super(properties); + this.shouldTick = shouldTick; + } + + @Override + protected @NotNull RenderShape getRenderShape(@NotNull BlockState state) { + return RenderShape.MODEL; + } + + public static Item.Properties getItemProperties() { + return new Item.Properties(); + } + + @Override + public @Nullable BlockEntityTicker getTicker(@NotNull Level level, @NotNull BlockState state, @NotNull BlockEntityType blockEntityType) { + return !shouldTick ? null : (entityLevel, pos, blockState, blockEntity) -> { + if (blockEntity instanceof TickableBlockEntity tickable) { + long time = level.getGameTime() - pos.hashCode(); + tickable.tick(entityLevel, time, blockState, pos); + if (level.isClientSide()) { + tickable.clientTick((ClientLevel) level, time, state, pos); + } else { + tickable.serverTick((ServerLevel) level, time, state, pos); + } + if (!tickable.isInitialized()) tickable.firstTick(level, state, pos); + } + }; + } + + @Override + protected void onRemove(BlockState state, @NotNull Level level, @NotNull BlockPos pos, BlockState newState, boolean movedByPiston) { + if (state.getBlock() != newState.getBlock()) { + if (level.getBlockEntity(pos) instanceof TickableBlockEntity tickable) { + tickable.onRemoved(); + } + } + super.onRemove(state, level, pos, newState, movedByPiston); + } +} diff --git a/src/main/java/net/xevianlight/aphelion/block/custom/base/BasicHorizontalEntityBlock.java b/src/main/java/net/xevianlight/aphelion/block/custom/base/BasicHorizontalEntityBlock.java new file mode 100644 index 0000000..1583d6d --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/block/custom/base/BasicHorizontalEntityBlock.java @@ -0,0 +1,42 @@ +package net.xevianlight.aphelion.block.custom.base; + +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public abstract class BasicHorizontalEntityBlock extends BasicEntityBlock { + + protected BasicHorizontalEntityBlock(Properties properties, boolean shouldTick) { + super(properties, shouldTick); + this.registerDefaultState(this.getStateDefinition().any()); + } + + public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; + + @Override + protected @NotNull BlockState rotate(BlockState state, Rotation rotation) { + return state.setValue(FACING, rotation.rotate(state.getValue(FACING))); + } + + @Override + protected @NotNull BlockState mirror(BlockState state, Mirror mirror) { + return state.rotate(mirror.getRotation(state.getValue(FACING))); + } + + @Override + public @Nullable BlockState getStateForPlacement(BlockPlaceContext context) { + return this.defaultBlockState().setValue(FACING, context.getHorizontalDirection().getOpposite()); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(FACING); + } +} diff --git a/src/main/java/net/xevianlight/aphelion/block/custom/base/TickableBlockEntity.java b/src/main/java/net/xevianlight/aphelion/block/custom/base/TickableBlockEntity.java new file mode 100644 index 0000000..5f15832 --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/block/custom/base/TickableBlockEntity.java @@ -0,0 +1,23 @@ +package net.xevianlight.aphelion.block.custom.base; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; + +public interface TickableBlockEntity { + void tick(Level entityLevel, long time, BlockState blockState, BlockPos pos); + + void clientTick(ClientLevel level, long time, BlockState state, BlockPos pos); + + void serverTick(ServerLevel level, long time, BlockState state, BlockPos pos); + + default boolean isInitialized() { + return true; + }; + + void firstTick(Level level, BlockState state, BlockPos pos); + + default void onRemoved() {} +} diff --git a/src/main/java/net/xevianlight/aphelion/block/entity/custom/OxygenTestBlockEntity.java b/src/main/java/net/xevianlight/aphelion/block/entity/custom/OxygenTestBlockEntity.java index 79bbe22..f3b5148 100644 --- a/src/main/java/net/xevianlight/aphelion/block/entity/custom/OxygenTestBlockEntity.java +++ b/src/main/java/net/xevianlight/aphelion/block/entity/custom/OxygenTestBlockEntity.java @@ -2,13 +2,16 @@ package net.xevianlight.aphelion.block.entity.custom; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import static net.xevianlight.aphelion.Aphelion.LOGGER; import net.minecraft.world.level.chunk.LevelChunk; +import net.xevianlight.aphelion.block.custom.base.TickableBlockEntity; import net.xevianlight.aphelion.core.init.ModBlockEntities; import net.xevianlight.aphelion.core.saveddata.EnvironmentSavedData; import net.xevianlight.aphelion.util.FloodFill3D; @@ -16,13 +19,20 @@ import org.openjdk.nashorn.internal.runtime.regexp.joni.exception.ValueException import java.util.*; -public class OxygenTestBlockEntity extends BlockEntity { +public class OxygenTestBlockEntity extends BlockEntity implements TickableBlockEntity { public OxygenTestBlockEntity(BlockPos pos, BlockState blockState) { super(ModBlockEntities.OXYGEN_TEST_BLOCK_ENTITY.get(), pos, blockState); } + public boolean isInitialized; + + @Override + public boolean isInitialized() { + return this.isInitialized; + } + private LevelChunk lastChunk; private int lastChunkX = Integer.MIN_VALUE, lastChunkZ = Integer.MIN_VALUE; @@ -231,9 +241,8 @@ public class OxygenTestBlockEntity extends BlockEntity { int refreshAfter = 20; - - public void tick(Level level, BlockPos pos, BlockState blockState) { - if (level.isClientSide) return; + @Override + public void serverTick(ServerLevel level, long time, BlockState blockState, BlockPos pos) { ticks++; if (ticks >= refreshAfter) { getEnclosedBlocks(); @@ -244,4 +253,18 @@ public class OxygenTestBlockEntity extends BlockEntity { } } + @Override + public void clientTick(ClientLevel level, long time, BlockState state, BlockPos pos) { + + } + + @Override + public void tick(Level entityLevel, long time, BlockState blockState, BlockPos pos) { + + } + + @Override + public void firstTick(Level level, BlockState state, BlockPos pos) { + this.isInitialized = true; + } } diff --git a/src/main/java/net/xevianlight/aphelion/block/entity/custom/RocketAssemblerBlockEntity.java b/src/main/java/net/xevianlight/aphelion/block/entity/custom/RocketAssemblerBlockEntity.java new file mode 100644 index 0000000..3166246 --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/block/entity/custom/RocketAssemblerBlockEntity.java @@ -0,0 +1,60 @@ +package net.xevianlight.aphelion.block.entity.custom; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +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.xevianlight.aphelion.block.custom.base.TickableBlockEntity; +import net.xevianlight.aphelion.core.init.ModBlockEntities; +import net.xevianlight.aphelion.util.RocketStructure; +import org.apache.commons.lang3.NotImplementedException; + +public class RocketAssemblerBlockEntity extends BlockEntity implements TickableBlockEntity { + + public boolean isInitialized; + @Override + public boolean isInitialized() { + return isInitialized; + } + + public RocketAssemblerBlockEntity(BlockPos pos, BlockState blockState) { + super(ModBlockEntities.ROCKET_ASSEMBLER_BLOCK_ENTITY.get(), pos, blockState); + } + + public void tick(Level level1, BlockPos blockPos, BlockState blockState) { + + } + + public boolean getPlatform() { + // TODO + throw new NotImplementedException(); + } + + public RocketStructure scan() { + // TODO + throw new NotImplementedException(); + } + + @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 void firstTick(Level level, BlockState state, BlockPos pos) { + this.isInitialized = true; + } +} diff --git a/src/main/java/net/xevianlight/aphelion/client/AphelionDebugOverlay.java b/src/main/java/net/xevianlight/aphelion/client/AphelionDebugOverlay.java index 7a5b604..8530c51 100644 --- a/src/main/java/net/xevianlight/aphelion/client/AphelionDebugOverlay.java +++ b/src/main/java/net/xevianlight/aphelion/client/AphelionDebugOverlay.java @@ -59,7 +59,7 @@ public class AphelionDebugOverlay { if (server != null) { singlePlayerLevel = server.getLevel(mc.level.dimension()); if (singlePlayerLevel != null) - event.getLeft().add(" Oxygen: " + EnvironmentSavedData.get(singlePlayerLevel).hasOxygen(singlePlayerLevel, mc.player.blockPosition())); + event.getLeft().add(" Oxygen: " + EnvironmentSavedData.get(singlePlayerLevel).hasOxygen(singlePlayerLevel, mc.player.blockPosition().mutable().above())); } } } \ No newline at end of file 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 e61a735..600035d 100644 --- a/src/main/java/net/xevianlight/aphelion/core/init/ModBlockEntities.java +++ b/src/main/java/net/xevianlight/aphelion/core/init/ModBlockEntities.java @@ -46,4 +46,9 @@ public class ModBlockEntities { BLOCK_ENTITIES.register("oxygen_test_block_entity", () -> BlockEntityType.Builder.of( OxygenTestBlockEntity::new, ModBlocks.OXYGEN_TEST_BLOCK.get()).build(null) ); + + public static final Supplier> ROCKET_ASSEMBLER_BLOCK_ENTITY = + BLOCK_ENTITIES.register("rocket_assembler_block_entity", () -> BlockEntityType.Builder.of( + RocketAssemblerBlockEntity::new, ModBlocks.ROCKET_ASSEMBLER_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 5b7e11e..ff032a1 100644 --- a/src/main/java/net/xevianlight/aphelion/core/init/ModBlocks.java +++ b/src/main/java/net/xevianlight/aphelion/core/init/ModBlocks.java @@ -19,4 +19,5 @@ public class ModBlocks { public static final DeferredBlock VACUUM_ARC_FURNACE_CONTROLLER = BLOCKS.register("vacuum_arc_furnace_controller", () -> new VacuumArcFurnaceController(VacuumArcFurnaceController.getProperties())); 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())); }