添加飞行器弹射装置的功能
This commit is contained in:
parent
ce4bf1fd78
commit
47ffcd5c01
4 changed files with 134 additions and 5 deletions
|
@ -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 <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level pLevel, @NotNull BlockState pState, @NotNull BlockEntityType<T> 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<Block, BlockState> builder) {
|
||||
builder.add(FACING).add(POWER);
|
||||
builder.add(FACING).add(POWER).add(UPDATING);
|
||||
}
|
||||
|
||||
public static final MapCodec<AircraftCatapultBlock> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -29,4 +29,6 @@ public class ModBlockEntities {
|
|||
public static final DeferredHolder<BlockEntityType<?>, BlockEntityType<VehicleDeployerBlockEntity>> VEHICLE_DEPLOYER = REGISTRY.register("vehicle_deployer",
|
||||
() -> BlockEntityType.Builder.of(VehicleDeployerBlockEntity::new, ModBlocks.VEHICLE_DEPLOYER.get()).build(null));
|
||||
|
||||
public static final DeferredHolder<BlockEntityType<?>, BlockEntityType<AircraftCatapultBlockEntity>> AIRCRAFT_CATAPULT = REGISTRY.register("aircraft_catapult",
|
||||
() -> BlockEntityType.Builder.of(AircraftCatapultBlockEntity::new, ModBlocks.AIRCRAFT_CATAPULT.get()).build(null));
|
||||
}
|
||||
|
|
|
@ -284,6 +284,7 @@ public class ModItems {
|
|||
public static final DeferredHolder<Item, ContainerBlockItem> CONTAINER = BLOCKS.register("container", ContainerBlockItem::new);
|
||||
public static final DeferredHolder<Item, SmallContainerBlockItem> SMALL_CONTAINER = BLOCKS.register("small_container", SmallContainerBlockItem::new);
|
||||
public static final DeferredHolder<Item, VehicleDeployerBlockItem> VEHICLE_DEPLOYER = BLOCKS.register("vehicle_deployer", VehicleDeployerBlockItem::new);
|
||||
public static final DeferredHolder<Item, BlockItem> AIRCRAFT_CATAPULT = block(ModBlocks.AIRCRAFT_CATAPULT);
|
||||
|
||||
/**
|
||||
* Perk Items
|
||||
|
|
Loading…
Add table
Reference in a new issue