From 47ffcd5c012ddd4f8f1ab6032317771dd17add72 Mon Sep 17 00:00:00 2001 From: 17146 <1714673995@qq.com> Date: Tue, 13 May 2025 00:29:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=A3=9E=E8=A1=8C=E5=99=A8?= =?UTF-8?q?=E5=BC=B9=E5=B0=84=E8=A3=85=E7=BD=AE=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../block/AircraftCatapultBlock.java | 89 +++++++++++++++++-- .../entity/AircraftCatapultBlockEntity.java | 47 ++++++++++ .../superbwarfare/init/ModBlockEntities.java | 2 + .../superbwarfare/init/ModItems.java | 1 + 4 files changed, 134 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/atsuishio/superbwarfare/block/entity/AircraftCatapultBlockEntity.java diff --git a/src/main/java/com/atsuishio/superbwarfare/block/AircraftCatapultBlock.java b/src/main/java/com/atsuishio/superbwarfare/block/AircraftCatapultBlock.java index 66798ffc4..b9b01f51a 100644 --- a/src/main/java/com/atsuishio/superbwarfare/block/AircraftCatapultBlock.java +++ b/src/main/java/com/atsuishio/superbwarfare/block/AircraftCatapultBlock.java @@ -1,38 +1,71 @@ package com.atsuishio.superbwarfare.block; +import com.atsuishio.superbwarfare.block.entity.AircraftCatapultBlockEntity; +import com.atsuishio.superbwarfare.init.ModBlockEntities; import com.mojang.serialization.MapCodec; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; 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.entity.BlockEntityTicker; +import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockBehaviour; 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.BooleanProperty; import net.minecraft.world.level.block.state.properties.DirectionProperty; import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + public class AircraftCatapultBlock extends BaseEntityBlock { public static final DirectionProperty FACING = HorizontalDirectionalBlock.FACING; - public static final IntegerProperty POWER = IntegerProperty.create("power", 0, 15); + public static final IntegerProperty POWER = BlockStateProperties.POWER; + public static final BooleanProperty UPDATING = BooleanProperty.create("updating"); public AircraftCatapultBlock() { super(BlockBehaviour.Properties.of().sound(SoundType.METAL).strength(3.0f).requiresCorrectToolForDrops()); - this.registerDefaultState(this.stateDefinition.any().setValue(FACING, Direction.NORTH).setValue(POWER, 0)); + this.registerDefaultState(this.stateDefinition.any().setValue(FACING, Direction.NORTH).setValue(POWER, 0).setValue(UPDATING, false)); } @Nullable @Override public BlockEntity newBlockEntity(@NotNull BlockPos pPos, @NotNull BlockState pState) { - return null; + return new AircraftCatapultBlockEntity(pPos, pState); + } + + @Nullable + @Override + public BlockEntityTicker getTicker(Level pLevel, @NotNull BlockState pState, @NotNull BlockEntityType pBlockEntityType) { + if (!pLevel.isClientSide) { + return createTickerHelper(pBlockEntityType, ModBlockEntities.AIRCRAFT_CATAPULT.get(), AircraftCatapultBlockEntity::serverTick); + } else { + return createTickerHelper(pBlockEntityType, ModBlockEntities.AIRCRAFT_CATAPULT.get(), AircraftCatapultBlockEntity::clientTick); + } + } + + @Override + @ParametersAreNonnullByDefault + public void onPlace(@NotNull BlockState state, Level level, BlockPos pos, @NotNull BlockState pOldState, boolean pMovedByPiston) { + if (level instanceof ServerLevel) { + int receivedPower = level.getBestNeighborSignal(pos); + int maxNeighborPower = this.getFacingPower(level, pos, state); + int newPower = Math.max(receivedPower, maxNeighborPower); + level.setBlock(pos, state.setValue(POWER, newPower), 3); + } } @Override protected void createBlockStateDefinition(StateDefinition.@NotNull Builder builder) { - builder.add(FACING).add(POWER); + builder.add(FACING).add(POWER).add(UPDATING); } public static final MapCodec CODEC = simpleCodec((prop) -> new AircraftCatapultBlock()); @@ -49,6 +82,52 @@ public class AircraftCatapultBlock extends BaseEntityBlock { @Override public BlockState getStateForPlacement(BlockPlaceContext context) { - return this.defaultBlockState().setValue(FACING, context.getHorizontalDirection().getOpposite()); + return this.defaultBlockState().setValue(FACING, context.getHorizontalDirection()); + } + + @Override + @ParametersAreNonnullByDefault + public void neighborChanged(BlockState pState, Level pLevel, BlockPos pPos, Block pBlock, BlockPos pFromPos, boolean pIsMoving) { + if (!pLevel.isClientSide && !pState.getValue(UPDATING)) { + pLevel.scheduleTick(pPos, this, 1); + } + } + + @Override + @ParametersAreNonnullByDefault + public void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource pRandom) { + this.updateSignal(state, level, pos); + } + + private void updateSignal(BlockState state, ServerLevel level, BlockPos pos) { + if (state.getValue(UPDATING)) return; // 防止重入 + + // 标记正在更新 + level.setBlock(pos, state.setValue(UPDATING, true), 2); + + // 计算新能量 + int receivedPower = level.getBestNeighborSignal(pos); + int maxNeighborPower = this.getFacingPower(level, pos, state); + int newPower = Math.max(receivedPower, maxNeighborPower); + + // 仅当能量变化时更新 + if (newPower != state.getValue(POWER)) { + var newState = level.getBlockState(pos); + level.setBlock(pos, newState.setValue(POWER, newPower), 3); + } + + // 清除更新标记 + var newState = level.getBlockState(pos); + level.setBlock(pos, newState.setValue(UPDATING, false), 2); + } + + private int getFacingPower(Level level, BlockPos pos, BlockState state) { + int max = 0; + BlockPos relative = pos.relative(state.getValue(FACING)); + BlockState blockState = level.getBlockState(relative); + if (blockState.getBlock() instanceof AircraftCatapultBlock) { + max = Math.max(max, blockState.getValue(POWER)); + } + return max; } } diff --git a/src/main/java/com/atsuishio/superbwarfare/block/entity/AircraftCatapultBlockEntity.java b/src/main/java/com/atsuishio/superbwarfare/block/entity/AircraftCatapultBlockEntity.java new file mode 100644 index 000000000..05581a689 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/block/entity/AircraftCatapultBlockEntity.java @@ -0,0 +1,47 @@ +package com.atsuishio.superbwarfare.block.entity; + +import com.atsuishio.superbwarfare.block.AircraftCatapultBlock; +import com.atsuishio.superbwarfare.init.ModBlockEntities; +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; + +public class AircraftCatapultBlockEntity extends BlockEntity { + + public AircraftCatapultBlockEntity(BlockPos pPos, BlockState pBlockState) { + super(ModBlockEntities.AIRCRAFT_CATAPULT.get(), pPos, pBlockState); + } + + public static void serverTick(Level pLevel, BlockPos pPos, BlockState pState, AircraftCatapultBlockEntity blockEntity) { + var direction = pState.getValue(AircraftCatapultBlock.FACING); + int power = pState.getValue(AircraftCatapultBlock.POWER); + if (power == 0) return; + + var list = pLevel.getEntitiesOfClass(Entity.class, new AABB(pPos.above())); + list.forEach(entity -> { + float rate = power / 800f; + if (entity instanceof LivingEntity) { + rate = power / 100f; + } + entity.addDeltaMovement(new Vec3(direction.getStepX() * rate, 0, direction.getStepZ() * rate)); + }); + } + + public static void clientTick(Level pLevel, BlockPos pPos, BlockState pState, AircraftCatapultBlockEntity blockEntity) { + var direction = pState.getValue(AircraftCatapultBlock.FACING); + int power = pState.getValue(AircraftCatapultBlock.POWER); + if (power == 0) return; + + var list = pLevel.getEntitiesOfClass(Player.class, new AABB(pPos.above())); + list.forEach(entity -> { + if (entity.getAbilities().flying) return; + entity.addDeltaMovement(new Vec3(direction.getStepX() * power / 100f, 0, direction.getStepZ() * power / 100f)); + }); + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModBlockEntities.java b/src/main/java/com/atsuishio/superbwarfare/init/ModBlockEntities.java index 37e58be78..444e154dd 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModBlockEntities.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModBlockEntities.java @@ -29,4 +29,6 @@ public class ModBlockEntities { public static final DeferredHolder, BlockEntityType> VEHICLE_DEPLOYER = REGISTRY.register("vehicle_deployer", () -> BlockEntityType.Builder.of(VehicleDeployerBlockEntity::new, ModBlocks.VEHICLE_DEPLOYER.get()).build(null)); + public static final DeferredHolder, BlockEntityType> AIRCRAFT_CATAPULT = REGISTRY.register("aircraft_catapult", + () -> BlockEntityType.Builder.of(AircraftCatapultBlockEntity::new, ModBlocks.AIRCRAFT_CATAPULT.get()).build(null)); } diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModItems.java b/src/main/java/com/atsuishio/superbwarfare/init/ModItems.java index c58173250..7cf5c6766 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModItems.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModItems.java @@ -284,6 +284,7 @@ public class ModItems { public static final DeferredHolder CONTAINER = BLOCKS.register("container", ContainerBlockItem::new); public static final DeferredHolder SMALL_CONTAINER = BLOCKS.register("small_container", SmallContainerBlockItem::new); public static final DeferredHolder VEHICLE_DEPLOYER = BLOCKS.register("vehicle_deployer", VehicleDeployerBlockItem::new); + public static final DeferredHolder AIRCRAFT_CATAPULT = block(ModBlocks.AIRCRAFT_CATAPULT); /** * Perk Items