diff --git a/src/main/java/com/atsuishio/superbwarfare/block/VehicleDeployerBlock.java b/src/main/java/com/atsuishio/superbwarfare/block/VehicleDeployerBlock.java new file mode 100644 index 000000000..95eac7a4c --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/block/VehicleDeployerBlock.java @@ -0,0 +1,92 @@ +package com.atsuishio.superbwarfare.block; + +import com.atsuishio.superbwarfare.block.entity.VehicleDeployerBlockEntity; +import com.atsuishio.superbwarfare.init.ModItems; +import com.mojang.serialization.MapCodec; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.ItemInteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +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.SoundType; +import net.minecraft.world.level.block.entity.BlockEntity; +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.phys.BlockHitResult; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.annotation.ParametersAreNonnullByDefault; + +// TODO 渲染 +public class VehicleDeployerBlock extends BaseEntityBlock { + public static final BooleanProperty TRIGGERED = BlockStateProperties.TRIGGERED; + + public VehicleDeployerBlock() { + super(Properties.of().sound(SoundType.METAL).strength(3.0f).requiresCorrectToolForDrops()); + this.registerDefaultState(this.stateDefinition.any().setValue(TRIGGERED, false)); + } + + private VehicleDeployerBlock(BlockBehaviour.Properties properties) { + this(); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.@NotNull Builder builder) { + builder.add(TRIGGERED); + } + + @Override + @ParametersAreNonnullByDefault + protected @NotNull ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult) { + if (level.isClientSide + || !(level.getBlockEntity(pos) instanceof VehicleDeployerBlockEntity blockEntity) + ) return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + + if (stack.getItem() != ModItems.CONTAINER.get()) { + player.displayClientMessage(Component.translatable("des.superbwarfare.vehicle_deployer.fail").withStyle(ChatFormatting.RED), true); + return ItemInteractionResult.FAIL; + } + + blockEntity.writeEntityInfo(stack); + player.displayClientMessage(Component.translatable("des.superbwarfare.vehicle_deployer.success").withStyle(ChatFormatting.GREEN), true); + + // TODO 取消原本的放置动作 + return ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION; + } + + @Override + @ParametersAreNonnullByDefault + public void neighborChanged(BlockState state, Level level, BlockPos pos, Block neighborBlock, BlockPos neighborPos, boolean pMovedByPiston) { + boolean charged = level.hasNeighborSignal(pos) || level.hasNeighborSignal(pos.above()); + boolean triggered = state.getValue(TRIGGERED); + + if (charged && !triggered) { + level.setBlock(pos, state.setValue(TRIGGERED, Boolean.TRUE), 4); + if (level.getBlockEntity(pos) instanceof VehicleDeployerBlockEntity blockEntity) { + blockEntity.deploy(); + } + } else if (!charged && triggered) { + level.setBlock(pos, state.setValue(TRIGGERED, Boolean.FALSE), 4); + } + } + + @Nullable + @Override + public BlockEntity newBlockEntity(@NotNull BlockPos pos, @NotNull BlockState state) { + return new VehicleDeployerBlockEntity(pos, state); + } + + @Override + protected @NotNull MapCodec codec() { + return simpleCodec(VehicleDeployerBlock::new); + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/block/entity/VehicleDeployerBlockEntity.java b/src/main/java/com/atsuishio/superbwarfare/block/entity/VehicleDeployerBlockEntity.java new file mode 100644 index 000000000..bb47d88b8 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/block/entity/VehicleDeployerBlockEntity.java @@ -0,0 +1,75 @@ +package com.atsuishio.superbwarfare.block.entity; + +import com.atsuishio.superbwarfare.init.ModBlockEntities; +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.component.DataComponents; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.joml.Math; + +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.UUID; + +public class VehicleDeployerBlockEntity extends BlockEntity { + + public CompoundTag entityData = new CompoundTag(); + + public VehicleDeployerBlockEntity(BlockPos pPos, BlockState pBlockState) { + super(ModBlockEntities.VEHICLE_DEPLOYER.get(), pPos, pBlockState); + } + + @Override + @ParametersAreNonnullByDefault + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.saveAdditional(tag, registries); + + if (this.entityData.contains("EntityType")) { + tag.putString("EntityType", this.entityData.getString("EntityType")); + } + if (this.entityData.contains("Entity")) { + tag.put("Entity", this.entityData.getCompound("Entity")); + } + } + + @Override + @ParametersAreNonnullByDefault + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.loadAdditional(tag, registries); + + this.entityData = tag.copy(); + } + + public void deploy() { + if (this.level == null) return; + + if (this.entityData.contains("EntityType")) { + var entityType = EntityType.byString(entityData.getString("EntityType")).orElse(null); + if (entityType == null) return; + + var entity = entityType.create(this.level); + if (entity == null) return; + + if (entityData.contains("Entity")) { + var entityTag = entityData.getCompound("Entity").copy(); + entityTag.remove("UUID"); + entity.load(entityTag); + } + + entity.setUUID(UUID.randomUUID()); + entity.setPos(this.getBlockPos().getX() + 0.5 + (2 * Math.random() - 1) * 0.1f, this.getBlockPos().getY() + 1.5 + (2 * Math.random() - 1) * 0.1f, this.getBlockPos().getZ() + 0.5 + (2 * Math.random() - 1) * 0.1f); + this.level.addFreshEntity(entity); + } + } + + public void writeEntityInfo(ItemStack stack) { + var tag = stack.get(DataComponents.BLOCK_ENTITY_DATA); + if (tag == null) return; + + this.entityData = tag.copyTag(); + } + +} diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModBlockEntities.java b/src/main/java/com/atsuishio/superbwarfare/init/ModBlockEntities.java index d75fbfd4f..37e58be78 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModBlockEntities.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModBlockEntities.java @@ -26,4 +26,7 @@ public class ModBlockEntities { public static final DeferredHolder, BlockEntityType> FUMO_25 = REGISTRY.register("fumo_25", () -> BlockEntityType.Builder.of(FuMO25BlockEntity::new, ModBlocks.FUMO_25.get()).build(null)); + public static final DeferredHolder, BlockEntityType> VEHICLE_DEPLOYER = REGISTRY.register("vehicle_deployer", + () -> BlockEntityType.Builder.of(VehicleDeployerBlockEntity::new, ModBlocks.VEHICLE_DEPLOYER.get()).build(null)); + } diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModBlocks.java b/src/main/java/com/atsuishio/superbwarfare/init/ModBlocks.java index e34f37f9b..d68f52229 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModBlocks.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModBlocks.java @@ -48,4 +48,5 @@ public class ModBlocks { public static final DeferredHolder CHARGING_STATION = REGISTRY.register("charging_station", ChargingStationBlock::new); public static final DeferredHolder CREATIVE_CHARGING_STATION = REGISTRY.register("creative_charging_station", () -> new CreativeChargingStationBlock()); public static final DeferredHolder FUMO_25 = REGISTRY.register("fumo_25", FuMO25Block::new); + public static final DeferredHolder VEHICLE_DEPLOYER = REGISTRY.register("vehicle_deployer", VehicleDeployerBlock::new); } diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModItems.java b/src/main/java/com/atsuishio/superbwarfare/init/ModItems.java index 6e0f8bb06..e583317c2 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModItems.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModItems.java @@ -280,6 +280,7 @@ public class ModItems { public static final DeferredHolder FUMO_25 = block(ModBlocks.FUMO_25); 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); /** * Perk Items diff --git a/src/main/java/com/atsuishio/superbwarfare/item/VehicleDeployerBlockItem.java b/src/main/java/com/atsuishio/superbwarfare/item/VehicleDeployerBlockItem.java new file mode 100644 index 000000000..509f958b0 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/item/VehicleDeployerBlockItem.java @@ -0,0 +1,23 @@ +package com.atsuishio.superbwarfare.item; + +import com.atsuishio.superbwarfare.init.ModBlocks; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; + +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.List; + +// TODO 图标和简介等 +public class VehicleDeployerBlockItem extends BlockItem { + public VehicleDeployerBlockItem() { + super(ModBlocks.VEHICLE_DEPLOYER.get(), new Properties().stacksTo(1)); + } + + @Override + @ParametersAreNonnullByDefault + public void appendHoverText(ItemStack stack, TooltipContext context, List tooltipComponents, TooltipFlag tooltipFlag) { + tooltipComponents.add(Component.literal("test")); + } +} diff --git a/src/main/resources/assets/superbwarfare/lang/en_us.json b/src/main/resources/assets/superbwarfare/lang/en_us.json index bfacf6318..57ff3ab16 100644 --- a/src/main/resources/assets/superbwarfare/lang/en_us.json +++ b/src/main/resources/assets/superbwarfare/lang/en_us.json @@ -618,5 +618,8 @@ "superbwarfare.advancement.main.boomstick_melee.des": "Who said RPGs can't be baseball bats?", "warning.title.example": "[SuperbWarfare Mod Warning]", "warning.content.example": "This mod is Free And Open-Source, No Commercial Use\nCode: GPL-3.0 License; Asserts: Private (No Commercialization)\nBan on paid downloads or EULA-breaking purchases\nReport violations by submitting an issue in the mod's repository", - "warning.check.example": "I have read and agreed to the content. Do not show this message again" + "warning.check.example": "I have read and agreed to the content. Do not show this message again", + "block.superbwarfare.vehicle_deployer": "Vehicle Deployer", + "des.superbwarfare.vehicle_deployer.success": "Vehicle info set successfully!", + "des.superbwarfare.vehicle_deployer.fail": "Please click with a container!" } \ No newline at end of file diff --git a/src/main/resources/assets/superbwarfare/lang/zh_cn.json b/src/main/resources/assets/superbwarfare/lang/zh_cn.json index 543dbda79..2e0af6089 100644 --- a/src/main/resources/assets/superbwarfare/lang/zh_cn.json +++ b/src/main/resources/assets/superbwarfare/lang/zh_cn.json @@ -619,5 +619,8 @@ "superbwarfare.advancement.main.boomstick_melee.des": "谁说RPG不能当棒球棒用?", "warning.title.example": "【卓越前线 警示声明】", "warning.content.example": "== 本模组完全免费开源,禁止用于任何商业行为 ==\n本模组代码采用GPL-3协议开源,美术资源私有禁止商用\n禁止付费下载、充值获取道具等违反协议和Mojang EULA的行为\n如遇以上行为,请到本模组仓库处提交Issue进行举报", - "warning.check.example": "我已阅读并同意,不再显示此警告" + "warning.check.example": "我已阅读并同意,不再显示此警告", + "block.superbwarfare.vehicle_deployer": "载具部署器", + "des.superbwarfare.vehicle_deployer.success": "成功设置载具信息!", + "des.superbwarfare.vehicle_deployer.fail": "请使用集装箱点击!" } \ No newline at end of file