From b2c48cde0e41053fd5eda74426d1bc322c67fd64 Mon Sep 17 00:00:00 2001 From: Light_Quanta Date: Thu, 27 Mar 2025 22:36:46 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E6=9B=B4=E6=96=B0=E5=86=85?= =?UTF-8?q?=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../59eb3dbb5f86130e09b3c62d89b9525ee01cf52d | 5 +- .../f93f628a3b0902e77de76541bcff68d1e5e3578f | 3 +- .../blockstates/small_container.json | 34 ++++ .../loot_table/blocks/container.json | 2 +- .../loot_table/blocks/small_container.json | 39 ++++ .../block/SmallContainerBlock.java | 153 +++++++++++++++ .../entity/SmallContainerBlockEntity.java | 179 +++++++++++++++++ ...Registry.java => ClientRenderHandler.java} | 18 +- .../model/block/ContainerBlockModel.java | 24 +++ .../client/model/block/FuMO25Model.java | 23 +++ .../model/block/SmallContainerBlockModel.java | 27 +++ .../client/model/item/ContainerItemModel.java | 24 +++ .../model/item/SmallContainerItemModel.java | 24 +++ .../client/renderer/CustomRenderType.java | 24 +++ .../ChargingStationBlockEntityRenderer.java | 96 +++++++++ .../block/ContainerBlockEntityRenderer.java | 20 ++ .../block/FuMO25BlockEntityRenderer.java | 45 +++++ .../SmallContainerBlockEntityRenderer.java | 20 ++ .../item/ContainerBlockItemRenderer.java | 20 ++ .../item/SmallContainerBlockItemRenderer.java | 20 ++ .../datagen/ModBlockLootProvider.java | 9 +- .../datagen/ModBlockStateProvider.java | 3 +- .../datagen/ModContainerLootProvider.java | 81 ++++++++ .../datagen/ModLootTableProvider.java | 3 +- .../superbwarfare/init/ModBlockEntities.java | 11 +- .../superbwarfare/init/ModBlocks.java | 3 +- .../superbwarfare/init/ModItems.java | 3 +- .../atsuishio/superbwarfare/init/ModTabs.java | 20 +- .../item/ContainerBlockItem.java | 183 ++++++++++++++++++ .../item/SmallContainerBlockItem.java | 84 ++++++++ .../superbwarfare/tools/NBTTool.java | 1 + 31 files changed, 1169 insertions(+), 32 deletions(-) create mode 100644 src/generated/resources/assets/superbwarfare/blockstates/small_container.json create mode 100644 src/generated/resources/data/superbwarfare/loot_table/blocks/small_container.json create mode 100644 src/main/java/com/atsuishio/superbwarfare/block/SmallContainerBlock.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/block/entity/SmallContainerBlockEntity.java rename src/main/java/com/atsuishio/superbwarfare/client/{tooltip/TooltipRegistry.java => ClientRenderHandler.java} (57%) create mode 100644 src/main/java/com/atsuishio/superbwarfare/client/model/block/ContainerBlockModel.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/client/model/block/FuMO25Model.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/client/model/block/SmallContainerBlockModel.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/client/model/item/ContainerItemModel.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/client/model/item/SmallContainerItemModel.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/client/renderer/CustomRenderType.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/client/renderer/block/ChargingStationBlockEntityRenderer.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/client/renderer/block/ContainerBlockEntityRenderer.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/client/renderer/block/FuMO25BlockEntityRenderer.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/client/renderer/block/SmallContainerBlockEntityRenderer.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/client/renderer/item/ContainerBlockItemRenderer.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/client/renderer/item/SmallContainerBlockItemRenderer.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/datagen/ModContainerLootProvider.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/item/ContainerBlockItem.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/item/SmallContainerBlockItem.java diff --git a/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d b/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d index 9ed2640db..467ae58e6 100644 --- a/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d +++ b/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d @@ -1,8 +1,8 @@ -// 1.21.1 2025-03-27T19:46:28.646366 Loot Tables +// 1.21.1 2025-03-27T22:36:38.8875256 Loot Tables 98386b2e65b2afb7cf5b0cabf6a7b0f062c1e640 data/superbwarfare/loot_table/blocks/barbed_wire.json 811e69929a14e6736015849c220100bb58d914c9 data/superbwarfare/loot_table/blocks/cemented_carbide_block.json 1f482bc1f0a1026d0e1b75ee28c6f541b56747a5 data/superbwarfare/loot_table/blocks/charging_station.json -e3d65cec9cd578df0c357c534ba64e2336ea05b7 data/superbwarfare/loot_table/blocks/container.json +088850d9af31c14153b1e837d14d78ea46682ba4 data/superbwarfare/loot_table/blocks/container.json c7b613c897b0eeca4dbade5eb65f718015dcb853 data/superbwarfare/loot_table/blocks/creative_charging_station.json f75afc8822e651ec7106271385813e2c6a810866 data/superbwarfare/loot_table/blocks/deepslate_galena_ore.json 7e0186c30d572478bebcb62171c1c126801258c2 data/superbwarfare/loot_table/blocks/deepslate_scheelite_ore.json @@ -17,5 +17,6 @@ ff3548e151685da812f1d5df1dff9fe365b5e0f9 data/superbwarfare/loot_table/blocks/ga e2fa2e6ba85ec27b3fbb6ad12a731a7ecff1c509 data/superbwarfare/loot_table/blocks/scheelite_ore.json a223f61202cf9937e8be5b90791925bba09d17b9 data/superbwarfare/loot_table/blocks/silver_block.json fb31a40f6a04000f317823cbb80eda8588ba9c69 data/superbwarfare/loot_table/blocks/silver_ore.json +073b9c242ea372f7b34883835c0b02a9ca8d94e5 data/superbwarfare/loot_table/blocks/small_container.json 83112ebff477e322bd3d23ed4653c7c02b230473 data/superbwarfare/loot_table/blocks/steel_block.json 71fc892124b5343e10688cabc2fb7c87d83cfef8 data/superbwarfare/loot_table/blocks/tungsten_block.json diff --git a/src/generated/resources/.cache/f93f628a3b0902e77de76541bcff68d1e5e3578f b/src/generated/resources/.cache/f93f628a3b0902e77de76541bcff68d1e5e3578f index b96be85b2..e11fbdcf7 100644 --- a/src/generated/resources/.cache/f93f628a3b0902e77de76541bcff68d1e5e3578f +++ b/src/generated/resources/.cache/f93f628a3b0902e77de76541bcff68d1e5e3578f @@ -1,4 +1,4 @@ -// 1.21.1 2025-03-27T19:46:28.6444106 Block States: superbwarfare +// 1.21.1 2025-03-27T21:38:30.5594453 Block States: superbwarfare f3b778ca36ca78c3d80f1b778078897f59bdb0c5 assets/superbwarfare/blockstates/barbed_wire.json 0cfad4f53a8047c402edf978d0c8cf6269f063cb assets/superbwarfare/blockstates/cemented_carbide_block.json 472c06e6b43ad09925edaa88e9376bfd27ab267f assets/superbwarfare/blockstates/charging_station.json @@ -15,6 +15,7 @@ d765539a643378e4f8ce56dc42bcff579d666e8a assets/superbwarfare/blockstates/reforg 123574c25d10de6d915514af34f0a878c93a07ea assets/superbwarfare/blockstates/scheelite_ore.json 0ea636a9080f56b6cda500a6943e17c7b5443878 assets/superbwarfare/blockstates/silver_block.json cf801445ce7cec678d5e811b5985506472e6ba4c assets/superbwarfare/blockstates/silver_ore.json +2a91b72f2d7974e100ae502006a2384bd66b29e5 assets/superbwarfare/blockstates/small_container.json a175c908c9aabee3a073844cd58ec9dfe6498bf0 assets/superbwarfare/blockstates/steel_block.json d4bbef5040ef43c362b28ea12ea73fb4a3db9adc assets/superbwarfare/blockstates/tungsten_block.json 5f1c22b64ff3ca4db9987f91a7179c9e705c7601 assets/superbwarfare/models/block/cemented_carbide_block.json diff --git a/src/generated/resources/assets/superbwarfare/blockstates/small_container.json b/src/generated/resources/assets/superbwarfare/blockstates/small_container.json new file mode 100644 index 000000000..c998fd25f --- /dev/null +++ b/src/generated/resources/assets/superbwarfare/blockstates/small_container.json @@ -0,0 +1,34 @@ +{ + "variants": { + "facing=east,opened=false": { + "model": "superbwarfare:block/small_container", + "y": 90 + }, + "facing=east,opened=true": { + "model": "superbwarfare:block/small_container", + "y": 90 + }, + "facing=north,opened=false": { + "model": "superbwarfare:block/small_container" + }, + "facing=north,opened=true": { + "model": "superbwarfare:block/small_container" + }, + "facing=south,opened=false": { + "model": "superbwarfare:block/small_container", + "y": 180 + }, + "facing=south,opened=true": { + "model": "superbwarfare:block/small_container", + "y": 180 + }, + "facing=west,opened=false": { + "model": "superbwarfare:block/small_container", + "y": 270 + }, + "facing=west,opened=true": { + "model": "superbwarfare:block/small_container", + "y": 270 + } + } +} \ No newline at end of file diff --git a/src/generated/resources/data/superbwarfare/loot_table/blocks/container.json b/src/generated/resources/data/superbwarfare/loot_table/blocks/container.json index b176097cd..8dd44560e 100644 --- a/src/generated/resources/data/superbwarfare/loot_table/blocks/container.json +++ b/src/generated/resources/data/superbwarfare/loot_table/blocks/container.json @@ -11,7 +11,7 @@ "entries": [ { "type": "minecraft:item", - "name": "minecraft:air" + "name": "superbwarfare:container" } ], "functions": [ diff --git a/src/generated/resources/data/superbwarfare/loot_table/blocks/small_container.json b/src/generated/resources/data/superbwarfare/loot_table/blocks/small_container.json new file mode 100644 index 000000000..f920d5774 --- /dev/null +++ b/src/generated/resources/data/superbwarfare/loot_table/blocks/small_container.json @@ -0,0 +1,39 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "superbwarfare:small_container" + } + ], + "functions": [ + { + "function": "minecraft:copy_custom_data", + "ops": [ + { + "op": "replace", + "source": "LootTable", + "target": "BlockEntityTag.LootTable" + }, + { + "op": "replace", + "source": "LootTableSeed", + "target": "BlockEntityTag.LootTableSeed" + } + ], + "source": "block_entity" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "superbwarfare:blocks/small_container" +} \ No newline at end of file diff --git a/src/main/java/com/atsuishio/superbwarfare/block/SmallContainerBlock.java b/src/main/java/com/atsuishio/superbwarfare/block/SmallContainerBlock.java new file mode 100644 index 000000000..611cf64b8 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/block/SmallContainerBlock.java @@ -0,0 +1,153 @@ +package com.atsuishio.superbwarfare.block; + +import com.atsuishio.superbwarfare.block.entity.SmallContainerBlockEntity; +import com.atsuishio.superbwarfare.init.ModBlockEntities; +import com.atsuishio.superbwarfare.init.ModItems; +import com.atsuishio.superbwarfare.init.ModSounds; +import com.mojang.serialization.MapCodec; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.component.DataComponents; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelReader; +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.BooleanProperty; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.HitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.List; + +@SuppressWarnings("deprecation") +public class SmallContainerBlock extends BaseEntityBlock { + + public static final DirectionProperty FACING = HorizontalDirectionalBlock.FACING; + public static final BooleanProperty OPENED = BooleanProperty.create("opened"); + + public SmallContainerBlock() { + this(Properties.of().sound(SoundType.METAL).strength(3.0f).noOcclusion().requiresCorrectToolForDrops()); + } + + public SmallContainerBlock(BlockBehaviour.Properties properties) { + super(properties); + this.registerDefaultState(this.stateDefinition.any().setValue(FACING, Direction.NORTH)); + } + + @Override + @ParametersAreNonnullByDefault + protected @NotNull InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + if (level.isClientSide || state.getValue(OPENED) || !(level.getBlockEntity(pos) instanceof SmallContainerBlockEntity blockEntity)) { + return InteractionResult.PASS; + } + + ItemStack stack = player.getItemInHand(player.getUsedItemHand()); + if (!stack.is(ModItems.CROWBAR.get())) { + player.displayClientMessage(Component.translatable("des.superbwarfare.container.fail.crowbar"), true); + return InteractionResult.PASS; + } + + blockEntity.setPlayer(player); + + level.setBlockAndUpdate(pos, state.setValue(OPENED, true)); + level.playSound(null, BlockPos.containing(pos.getX(), pos.getY(), pos.getZ()), ModSounds.OPEN.get(), SoundSource.BLOCKS, 1, 1); + + return InteractionResult.SUCCESS; + } + + @Nullable + @Override + public BlockEntityTicker getTicker(Level level, @NotNull BlockState state, @NotNull BlockEntityType pBlockEntityType) { + if (!level.isClientSide) { + return createTickerHelper(pBlockEntityType, ModBlockEntities.SMALL_CONTAINER.get(), SmallContainerBlockEntity::serverTick); + } + return null; + } + + @Override + @ParametersAreNonnullByDefault + public void appendHoverText(ItemStack stack, Item.TooltipContext context, List tooltipComponents, TooltipFlag tooltipFlag) { + super.appendHoverText(stack, context, tooltipComponents, tooltipFlag); + + var data = stack.get(DataComponents.BLOCK_ENTITY_DATA); + CompoundTag tag = data != null ? data.copyTag() : null; + if (tag != null) { + long seed = tag.getLong("LootTableSeed"); + if (seed != 0 && seed % 205 == 0) { + tooltipComponents.add(Component.translatable("des.superbwarfare.small_container.special").withStyle(ChatFormatting.GRAY)); + } else { + tooltipComponents.add(Component.translatable("des.superbwarfare.small_container.random").withStyle(ChatFormatting.GRAY)); + } + } else { + tooltipComponents.add(Component.translatable("des.superbwarfare.small_container").withStyle(ChatFormatting.GRAY)); + } + } + + @Override + @ParametersAreNonnullByDefault + public @NotNull VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { + if (state.getValue(FACING) == Direction.NORTH || state.getValue(FACING) == Direction.SOUTH) { + return state.getValue(OPENED) ? box(1, 0, 2, 15, 12, 14) : box(0, 0, 1, 16, 13.5, 15); + } else return state.getValue(OPENED) ? box(2, 0, 1, 14, 12, 15) : box(1, 0, 0, 15, 13.5, 16); + } + + private static final MapCodec CODEC = BlockBehaviour.simpleCodec(SmallContainerBlock::new); + + @Override + protected @NotNull MapCodec codec() { + return CODEC; + } + + @Override + public @NotNull RenderShape getRenderShape(@NotNull BlockState state) { + return RenderShape.ENTITYBLOCK_ANIMATED; + } + + @Nullable + @Override + public BlockEntity newBlockEntity(@NotNull BlockPos blockPos, @NotNull BlockState blockState) { + return new SmallContainerBlockEntity(blockPos, blockState); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(FACING).add(OPENED); + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { + return this.defaultBlockState().setValue(FACING, context.getHorizontalDirection().getOpposite()).setValue(OPENED, false); + } + + @Override + @ParametersAreNonnullByDefault + public @NotNull ItemStack getCloneItemStack(BlockState state, HitResult target, LevelReader level, BlockPos pos, Player player) { + var stack = super.getCloneItemStack(state, target, level, pos, player); + + level.getBlockEntity(pos, ModBlockEntities.SMALL_CONTAINER.get()).ifPresent((blockEntity) -> blockEntity.saveToItem(stack, level.registryAccess())); + return stack; + } + +} + diff --git a/src/main/java/com/atsuishio/superbwarfare/block/entity/SmallContainerBlockEntity.java b/src/main/java/com/atsuishio/superbwarfare/block/entity/SmallContainerBlockEntity.java new file mode 100644 index 000000000..5c0ae051c --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/block/entity/SmallContainerBlockEntity.java @@ -0,0 +1,179 @@ +package com.atsuishio.superbwarfare.block.entity; + +import com.atsuishio.superbwarfare.block.SmallContainerBlock; +import com.atsuishio.superbwarfare.init.ModBlockEntities; +import com.atsuishio.superbwarfare.tools.ParticleTool; +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.loot.LootParams; +import net.minecraft.world.level.storage.loot.parameters.LootContextParams; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.NotNull; +import software.bernie.geckolib.animatable.GeoBlockEntity; +import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; +import software.bernie.geckolib.animation.*; +import software.bernie.geckolib.util.GeckoLibUtil; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.Collections; +import java.util.List; + +public class SmallContainerBlockEntity extends BlockEntity implements GeoBlockEntity { + + @Nullable + public ResourceLocation lootTable; + public long lootTableSeed; + public int tick = 0; + @Nullable + private Player player; + + private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); + + public SmallContainerBlockEntity(BlockPos pos, BlockState state) { + super(ModBlockEntities.SMALL_CONTAINER.get(), pos, state); + } + + public static void serverTick(Level pLevel, BlockPos pPos, BlockState pState, SmallContainerBlockEntity blockEntity) { + if (!pState.getValue(SmallContainerBlock.OPENED)) { + return; + } + + if (blockEntity.tick < 20) { + blockEntity.tick++; + blockEntity.setChanged(); + + if (blockEntity.tick == 18) { + ParticleTool.sendParticle((ServerLevel) pLevel, ParticleTypes.EXPLOSION, pPos.getX(), pPos.getY() + 1, pPos.getZ(), 40, 1.5, 1.5, 1.5, 1, false); + pLevel.playSound(null, pPos, SoundEvents.GENERIC_EXPLODE.value(), SoundSource.BLOCKS, 4.0F, (1.0F + (pLevel.random.nextFloat() - pLevel.random.nextFloat()) * 0.2F) * 0.7F); + } + } else { + var items = blockEntity.unpackLootTable(blockEntity.player); + if (!items.isEmpty()) { + for (var item : items) { + ItemEntity entity = new ItemEntity(pLevel, pPos.getX(), pPos.getY() + 0.85, pPos.getZ(), item); + entity.setDeltaMovement(new Vec3(pLevel.random.nextDouble() * 0.2, 0.1, pLevel.random.nextDouble() * 0.2)); + pLevel.addFreshEntity(entity); + } + } + pLevel.setBlockAndUpdate(pPos, Blocks.AIR.defaultBlockState()); + } + } + + private PlayState predicate(AnimationState event) { + if (this.getBlockState().getValue(SmallContainerBlock.OPENED)) { + return event.setAndContinue(RawAnimation.begin().thenPlay("animation.container.open")); + } + return PlayState.STOP; + } + + @Override + public void registerControllers(AnimatableManager.ControllerRegistrar data) { + data.add(new AnimationController<>(this, "controller", 0, this::predicate)); + } + + @Override + public AnimatableInstanceCache getAnimatableInstanceCache() { + return this.cache; + } + + @Override + @ParametersAreNonnullByDefault + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.loadAdditional(tag, registries); + + if (tag.contains("LootTable", 8)) { + this.lootTable = ResourceLocation.bySeparator(tag.getString("LootTable"), ':'); + this.lootTableSeed = tag.getLong("LootTableSeed"); + } + this.tick = tag.getInt("Tick"); + } + + @Override + @ParametersAreNonnullByDefault + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.saveAdditional(tag, registries); + + if (this.lootTable != null) { + tag.putString("LootTable", this.lootTable.toString()); + if (this.lootTableSeed != 0L) { + tag.putLong("LootTableSeed", this.lootTableSeed); + } + } + tag.putInt("Tick", this.tick); + } + + @Override + public ClientboundBlockEntityDataPacket getUpdatePacket() { + return ClientboundBlockEntityDataPacket.create(this); + } + + @Override + public @NotNull CompoundTag getUpdateTag(HolderLookup.@NotNull Provider registries) { + return this.saveWithFullMetadata(registries); + } + + @Override + @ParametersAreNonnullByDefault + public void saveToItem(ItemStack stack, HolderLookup.Provider registries) { + CompoundTag tag = new CompoundTag(); + if (this.lootTable != null) { + tag.putString("LootTable", this.lootTable.toString()); + if (this.lootTableSeed != 0L) { + tag.putLong("LootTableSeed", this.lootTableSeed); + } + } + BlockItem.setBlockEntityData(stack, this.getType(), tag); + } + + public void setLootTable(ResourceLocation pLootTable, long pLootTableSeed) { + this.lootTable = pLootTable; + this.lootTableSeed = pLootTableSeed; + } + + public List unpackLootTable(@Nullable Player pPlayer) { + if (this.lootTable != null && this.level != null && this.level.getServer() != null) { + + // TODO loot table resource key? +// LootTable loottable = this.level.getServer().reloadableRegistries().getLootTable(this.lootTable); + if (pPlayer instanceof ServerPlayer) { +// CriteriaTriggers.GENERATE_LOOT.trigger((ServerPlayer) pPlayer, this.lootTable); + } + + this.lootTable = null; + LootParams.Builder builder = (new LootParams.Builder((ServerLevel) this.level)) + .withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(this.worldPosition)); + if (pPlayer != null) { + builder.withLuck(pPlayer.getLuck()).withParameter(LootContextParams.THIS_ENTITY, pPlayer); + } + +// return loottable.getRandomItems(builder.create(LootContextParamSets.CHEST), this.lootTableSeed).stream().toList(); + } + return Collections.emptyList(); + } + + @Nullable + public Player getPlayer() { + return player; + } + + public void setPlayer(@Nullable Player player) { + this.player = player; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/client/tooltip/TooltipRegistry.java b/src/main/java/com/atsuishio/superbwarfare/client/ClientRenderHandler.java similarity index 57% rename from src/main/java/com/atsuishio/superbwarfare/client/tooltip/TooltipRegistry.java rename to src/main/java/com/atsuishio/superbwarfare/client/ClientRenderHandler.java index 6f5535589..804d60a3e 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/tooltip/TooltipRegistry.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/ClientRenderHandler.java @@ -1,6 +1,12 @@ -package com.atsuishio.superbwarfare.client.tooltip; +package com.atsuishio.superbwarfare.client; +import com.atsuishio.superbwarfare.client.renderer.block.ChargingStationBlockEntityRenderer; +import com.atsuishio.superbwarfare.client.renderer.block.ContainerBlockEntityRenderer; +import com.atsuishio.superbwarfare.client.renderer.block.FuMO25BlockEntityRenderer; +import com.atsuishio.superbwarfare.client.renderer.block.SmallContainerBlockEntityRenderer; +import com.atsuishio.superbwarfare.client.tooltip.*; import com.atsuishio.superbwarfare.client.tooltip.component.*; +import com.atsuishio.superbwarfare.init.ModBlockEntities; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; @@ -8,7 +14,7 @@ import net.neoforged.neoforge.client.event.EntityRenderersEvent; import net.neoforged.neoforge.client.event.RegisterClientTooltipComponentFactoriesEvent; @EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) -public class TooltipRegistry { +public class ClientRenderHandler { @SubscribeEvent public static void registerTooltip(RegisterClientTooltipComponentFactoriesEvent event) { @@ -25,9 +31,9 @@ public class TooltipRegistry { @SubscribeEvent public static void registerRenderers(EntityRenderersEvent.RegisterRenderers event) { - // TODO block entity renderer -// event.registerBlockEntityRenderer(ModBlockEntities.CONTAINER.get(), context -> new ContainerBlockEntityRenderer()); -// event.registerBlockEntityRenderer(ModBlockEntities.FUMO_25.get(), context -> new FuMO25BlockEntityRenderer()); -// event.registerBlockEntityRenderer(ModBlockEntities.CHARGING_STATION.get(), context -> new ChargingStationBlockEntityRenderer()); + event.registerBlockEntityRenderer(ModBlockEntities.CONTAINER.get(), context -> new ContainerBlockEntityRenderer()); + event.registerBlockEntityRenderer(ModBlockEntities.FUMO_25.get(), context -> new FuMO25BlockEntityRenderer()); + event.registerBlockEntityRenderer(ModBlockEntities.CHARGING_STATION.get(), context -> new ChargingStationBlockEntityRenderer()); + event.registerBlockEntityRenderer(ModBlockEntities.SMALL_CONTAINER.get(), context -> new SmallContainerBlockEntityRenderer()); } } diff --git a/src/main/java/com/atsuishio/superbwarfare/client/model/block/ContainerBlockModel.java b/src/main/java/com/atsuishio/superbwarfare/client/model/block/ContainerBlockModel.java new file mode 100644 index 000000000..a97b81e9e --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/client/model/block/ContainerBlockModel.java @@ -0,0 +1,24 @@ +package com.atsuishio.superbwarfare.client.model.block; + +import com.atsuishio.superbwarfare.ModUtils; +import com.atsuishio.superbwarfare.block.entity.ContainerBlockEntity; +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib.model.GeoModel; + +public class ContainerBlockModel extends GeoModel { + + @Override + public ResourceLocation getAnimationResource(ContainerBlockEntity animatable) { + return ModUtils.loc("animations/container.animation.json"); + } + + @Override + public ResourceLocation getModelResource(ContainerBlockEntity animatable) { + return ModUtils.loc("geo/container.geo.json"); + } + + @Override + public ResourceLocation getTextureResource(ContainerBlockEntity animatable) { + return ModUtils.loc("textures/block/container.png"); + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/client/model/block/FuMO25Model.java b/src/main/java/com/atsuishio/superbwarfare/client/model/block/FuMO25Model.java new file mode 100644 index 000000000..dc6fa2b9c --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/client/model/block/FuMO25Model.java @@ -0,0 +1,23 @@ +package com.atsuishio.superbwarfare.client.model.block; + +import com.atsuishio.superbwarfare.ModUtils; +import com.atsuishio.superbwarfare.block.entity.FuMO25BlockEntity; +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib.model.GeoModel; + +public class FuMO25Model extends GeoModel { + @Override + public ResourceLocation getAnimationResource(FuMO25BlockEntity animatable) { + return null; + } + + @Override + public ResourceLocation getModelResource(FuMO25BlockEntity animatable) { + return ModUtils.loc("geo/fumo_25.geo.json"); + } + + @Override + public ResourceLocation getTextureResource(FuMO25BlockEntity animatable) { + return ModUtils.loc("textures/block/fumo_25.png"); + } +} \ No newline at end of file diff --git a/src/main/java/com/atsuishio/superbwarfare/client/model/block/SmallContainerBlockModel.java b/src/main/java/com/atsuishio/superbwarfare/client/model/block/SmallContainerBlockModel.java new file mode 100644 index 000000000..b84033d88 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/client/model/block/SmallContainerBlockModel.java @@ -0,0 +1,27 @@ +package com.atsuishio.superbwarfare.client.model.block; + +import com.atsuishio.superbwarfare.ModUtils; +import com.atsuishio.superbwarfare.block.entity.SmallContainerBlockEntity; +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib.model.GeoModel; + +public class SmallContainerBlockModel extends GeoModel { + + @Override + public ResourceLocation getAnimationResource(SmallContainerBlockEntity animatable) { + return ModUtils.loc("animations/small_container.animation.json"); + } + + @Override + public ResourceLocation getModelResource(SmallContainerBlockEntity animatable) { + return ModUtils.loc("geo/small_container.geo.json"); + } + + @Override + public ResourceLocation getTextureResource(SmallContainerBlockEntity animatable) { + if (animatable.lootTableSeed != 0L && animatable.lootTableSeed % 205 == 0) { + return ModUtils.loc("textures/block/small_container_sui.png"); + } + return ModUtils.loc("textures/block/small_container.png"); + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/client/model/item/ContainerItemModel.java b/src/main/java/com/atsuishio/superbwarfare/client/model/item/ContainerItemModel.java new file mode 100644 index 000000000..79c210fbb --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/client/model/item/ContainerItemModel.java @@ -0,0 +1,24 @@ +package com.atsuishio.superbwarfare.client.model.item; + +import com.atsuishio.superbwarfare.ModUtils; +import com.atsuishio.superbwarfare.item.ContainerBlockItem; +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib.model.GeoModel; + +public class ContainerItemModel extends GeoModel { + + @Override + public ResourceLocation getAnimationResource(ContainerBlockItem animatable) { + return ModUtils.loc("animations/container.animation.json"); + } + + @Override + public ResourceLocation getModelResource(ContainerBlockItem animatable) { + return ModUtils.loc("geo/container.geo.json"); + } + + @Override + public ResourceLocation getTextureResource(ContainerBlockItem animatable) { + return ModUtils.loc("textures/block/container.png"); + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/client/model/item/SmallContainerItemModel.java b/src/main/java/com/atsuishio/superbwarfare/client/model/item/SmallContainerItemModel.java new file mode 100644 index 000000000..e083c7f5a --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/client/model/item/SmallContainerItemModel.java @@ -0,0 +1,24 @@ +package com.atsuishio.superbwarfare.client.model.item; + +import com.atsuishio.superbwarfare.ModUtils; +import com.atsuishio.superbwarfare.item.SmallContainerBlockItem; +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib.model.GeoModel; + +public class SmallContainerItemModel extends GeoModel { + + @Override + public ResourceLocation getAnimationResource(SmallContainerBlockItem animatable) { + return ModUtils.loc("animations/small_container.animation.json"); + } + + @Override + public ResourceLocation getModelResource(SmallContainerBlockItem animatable) { + return ModUtils.loc("geo/small_container.geo.json"); + } + + @Override + public ResourceLocation getTextureResource(SmallContainerBlockItem animatable) { + return ModUtils.loc("textures/block/small_container.png"); + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/client/renderer/CustomRenderType.java b/src/main/java/com/atsuishio/superbwarfare/client/renderer/CustomRenderType.java new file mode 100644 index 000000000..e352d3e62 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/client/renderer/CustomRenderType.java @@ -0,0 +1,24 @@ +package com.atsuishio.superbwarfare.client.renderer; + +import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.VertexFormat; +import net.minecraft.client.renderer.RenderType; + +public class CustomRenderType extends RenderType { + public CustomRenderType(String pName, VertexFormat pFormat, VertexFormat.Mode pMode, int pBufferSize, boolean pAffectsCrumbling, boolean pSortOnUpload, Runnable pSetupState, Runnable pClearState) { + super(pName, pFormat, pMode, pBufferSize, pAffectsCrumbling, pSortOnUpload, pSetupState, pClearState); + } + + public static final RenderType BLOCK_OVERLAY = create("block_overlay", + DefaultVertexFormat.POSITION_COLOR, VertexFormat.Mode.QUADS, 256, false, false, + CompositeState.builder() + .setShaderState(ShaderStateShard.POSITION_COLOR_SHADER) + .setLayeringState(NO_LAYERING) + .setTransparencyState(TRANSLUCENT_TRANSPARENCY) + .setTextureState(NO_TEXTURE) + .setDepthTestState(LEQUAL_DEPTH_TEST) + .setCullState(NO_CULL) + .setLightmapState(NO_LIGHTMAP) + .setWriteMaskState(COLOR_WRITE) + .createCompositeState(false)); +} diff --git a/src/main/java/com/atsuishio/superbwarfare/client/renderer/block/ChargingStationBlockEntityRenderer.java b/src/main/java/com/atsuishio/superbwarfare/client/renderer/block/ChargingStationBlockEntityRenderer.java new file mode 100644 index 000000000..efe99a013 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/client/renderer/block/ChargingStationBlockEntityRenderer.java @@ -0,0 +1,96 @@ +package com.atsuishio.superbwarfare.client.renderer.block; + +import com.atsuishio.superbwarfare.block.ChargingStationBlock; +import com.atsuishio.superbwarfare.block.entity.ChargingStationBlockEntity; +import com.atsuishio.superbwarfare.client.renderer.CustomRenderType; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.ParametersAreNonnullByDefault; + +@OnlyIn(Dist.CLIENT) +public class ChargingStationBlockEntityRenderer implements BlockEntityRenderer { + + @Override + public void render(ChargingStationBlockEntity blockEntity, float partialTick, @NotNull PoseStack poseStack, MultiBufferSource bufferSource, int packedLight, int packedOverlay) { + if (!blockEntity.getBlockState().getValue(ChargingStationBlock.SHOW_RANGE)) return; + + poseStack.pushPose(); + var pos = blockEntity.getBlockPos(); + poseStack.translate(-pos.getX(), -pos.getY(), -pos.getZ()); + + var aabb = new AABB(pos).inflate(ChargingStationBlockEntity.CHARGE_RADIUS); + + float startX = (float) aabb.minX - 0.001f; + float startY = (float) aabb.minY - 0.001f; + float startZ = (float) aabb.minZ - 0.001f; + float endX = (float) aabb.maxX + 0.001f; + float endY = (float) aabb.maxY + 0.001f; + float endZ = (float) aabb.maxZ + 0.001f; + + var red = 0.0f; + var green = 1.0f; + var blue = 0.0f; + var alpha = 0.2f; + + + var builder = bufferSource.getBuffer(CustomRenderType.BLOCK_OVERLAY); + var m4f = poseStack.last().pose(); + + // east + builder.addVertex(m4f, startX, startY, startZ).setColor(red, green, blue, alpha); + builder.addVertex(m4f, startX, endY, startZ).setColor(red, green, blue, alpha); + builder.addVertex(m4f, endX, endY, startZ).setColor(red, green, blue, alpha); + builder.addVertex(m4f, endX, startY, startZ).setColor(red, green, blue, alpha); + + // west + builder.addVertex(m4f, startX, startY, endZ).setColor(red, green, blue, alpha); + builder.addVertex(m4f, endX, startY, endZ).setColor(red, green, blue, alpha); + builder.addVertex(m4f, endX, endY, endZ).setColor(red, green, blue, alpha); + builder.addVertex(m4f, startX, endY, endZ).setColor(red, green, blue, alpha); + + // south + builder.addVertex(m4f, endX, startY, startZ).setColor(red, green, blue, alpha); + builder.addVertex(m4f, endX, endY, startZ).setColor(red, green, blue, alpha); + builder.addVertex(m4f, endX, endY, endZ).setColor(red, green, blue, alpha); + builder.addVertex(m4f, endX, startY, endZ).setColor(red, green, blue, alpha); + + // north + builder.addVertex(m4f, startX, startY, startZ).setColor(red, green, blue, alpha); + builder.addVertex(m4f, startX, startY, endZ).setColor(red, green, blue, alpha); + builder.addVertex(m4f, startX, endY, endZ).setColor(red, green, blue, alpha); + builder.addVertex(m4f, startX, endY, startZ).setColor(red, green, blue, alpha); + + // top + builder.addVertex(m4f, startX, endY, startZ).setColor(red, green, blue, alpha); + builder.addVertex(m4f, endX, endY, startZ).setColor(red, green, blue, alpha); + builder.addVertex(m4f, endX, endY, endZ).setColor(red, green, blue, alpha); + builder.addVertex(m4f, startX, endY, endZ).setColor(red, green, blue, alpha); + + // bottom + builder.addVertex(m4f, startX, startY, startZ).setColor(red, green, blue, alpha); + builder.addVertex(m4f, endX, startY, startZ).setColor(red, green, blue, alpha); + builder.addVertex(m4f, endX, startY, endZ).setColor(red, green, blue, alpha); + builder.addVertex(m4f, startX, startY, endZ).setColor(red, green, blue, alpha); + + poseStack.popPose(); + } + + @Override + public boolean shouldRenderOffScreen(@NotNull ChargingStationBlockEntity blockEntity) { + return true; + } + + @Override + @ParametersAreNonnullByDefault + public boolean shouldRender(ChargingStationBlockEntity blockEntity, Vec3 pCameraPos) { + return true; + } + +} diff --git a/src/main/java/com/atsuishio/superbwarfare/client/renderer/block/ContainerBlockEntityRenderer.java b/src/main/java/com/atsuishio/superbwarfare/client/renderer/block/ContainerBlockEntityRenderer.java new file mode 100644 index 000000000..e77275de2 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/client/renderer/block/ContainerBlockEntityRenderer.java @@ -0,0 +1,20 @@ +package com.atsuishio.superbwarfare.client.renderer.block; + +import com.atsuishio.superbwarfare.block.entity.ContainerBlockEntity; +import com.atsuishio.superbwarfare.client.model.block.ContainerBlockModel; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib.renderer.GeoBlockRenderer; + +public class ContainerBlockEntityRenderer extends GeoBlockRenderer { + + public ContainerBlockEntityRenderer() { + super(new ContainerBlockModel()); + } + + @Override + public RenderType getRenderType(ContainerBlockEntity animatable, ResourceLocation texture, MultiBufferSource bufferSource, float partialTick) { + return RenderType.entityTranslucent(getTextureLocation(animatable)); + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/client/renderer/block/FuMO25BlockEntityRenderer.java b/src/main/java/com/atsuishio/superbwarfare/client/renderer/block/FuMO25BlockEntityRenderer.java new file mode 100644 index 000000000..090d1792f --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/client/renderer/block/FuMO25BlockEntityRenderer.java @@ -0,0 +1,45 @@ +package com.atsuishio.superbwarfare.client.renderer.block; + +import com.atsuishio.superbwarfare.block.FuMO25Block; +import com.atsuishio.superbwarfare.block.entity.FuMO25BlockEntity; +import com.atsuishio.superbwarfare.client.model.block.FuMO25Model; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.NotNull; +import software.bernie.geckolib.cache.object.GeoBone; +import software.bernie.geckolib.renderer.GeoBlockRenderer; + + +public class FuMO25BlockEntityRenderer extends GeoBlockRenderer { + public FuMO25BlockEntityRenderer() { + super(new FuMO25Model()); + } + + @Override + public RenderType getRenderType(FuMO25BlockEntity animatable, ResourceLocation texture, MultiBufferSource bufferSource, float partialTick) { + return RenderType.entityTranslucent(getTextureLocation(animatable)); + } + + @Override + public boolean shouldRenderOffScreen(@NotNull FuMO25BlockEntity pBlockEntity) { + return true; + } + + @Override + public int getViewDistance() { + return 512; + } + + @Override + public void renderRecursively(PoseStack poseStack, FuMO25BlockEntity animatable, GeoBone bone, RenderType renderType, MultiBufferSource bufferSource, VertexConsumer buffer, boolean isReRender, float partialTick, int packedLight, int packedOverlay, int colour) { + String name = bone.getName(); + if (name.equals("mian") && animatable.getBlockState().getValue(FuMO25Block.POWERED)) { + bone.setRotY((System.currentTimeMillis() % 36000000) / 1200f); + } + + super.renderRecursively(poseStack, animatable, bone, renderType, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay, colour); + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/client/renderer/block/SmallContainerBlockEntityRenderer.java b/src/main/java/com/atsuishio/superbwarfare/client/renderer/block/SmallContainerBlockEntityRenderer.java new file mode 100644 index 000000000..2cb5b0875 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/client/renderer/block/SmallContainerBlockEntityRenderer.java @@ -0,0 +1,20 @@ +package com.atsuishio.superbwarfare.client.renderer.block; + +import com.atsuishio.superbwarfare.block.entity.SmallContainerBlockEntity; +import com.atsuishio.superbwarfare.client.model.block.SmallContainerBlockModel; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib.renderer.GeoBlockRenderer; + +public class SmallContainerBlockEntityRenderer extends GeoBlockRenderer { + + public SmallContainerBlockEntityRenderer() { + super(new SmallContainerBlockModel()); + } + + @Override + public RenderType getRenderType(SmallContainerBlockEntity animatable, ResourceLocation texture, MultiBufferSource bufferSource, float partialTick) { + return RenderType.entityTranslucent(getTextureLocation(animatable)); + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/client/renderer/item/ContainerBlockItemRenderer.java b/src/main/java/com/atsuishio/superbwarfare/client/renderer/item/ContainerBlockItemRenderer.java new file mode 100644 index 000000000..e3bea4df9 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/client/renderer/item/ContainerBlockItemRenderer.java @@ -0,0 +1,20 @@ +package com.atsuishio.superbwarfare.client.renderer.item; + +import com.atsuishio.superbwarfare.client.model.item.ContainerItemModel; +import com.atsuishio.superbwarfare.item.ContainerBlockItem; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib.renderer.GeoItemRenderer; + +public class ContainerBlockItemRenderer extends GeoItemRenderer { + + public ContainerBlockItemRenderer() { + super(new ContainerItemModel()); + } + + @Override + public RenderType getRenderType(ContainerBlockItem animatable, ResourceLocation texture, MultiBufferSource bufferSource, float partialTick) { + return RenderType.entityTranslucent(getTextureLocation(animatable)); + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/client/renderer/item/SmallContainerBlockItemRenderer.java b/src/main/java/com/atsuishio/superbwarfare/client/renderer/item/SmallContainerBlockItemRenderer.java new file mode 100644 index 000000000..1b96504c5 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/client/renderer/item/SmallContainerBlockItemRenderer.java @@ -0,0 +1,20 @@ +package com.atsuishio.superbwarfare.client.renderer.item; + +import com.atsuishio.superbwarfare.client.model.item.SmallContainerItemModel; +import com.atsuishio.superbwarfare.item.SmallContainerBlockItem; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib.renderer.GeoItemRenderer; + +public class SmallContainerBlockItemRenderer extends GeoItemRenderer { + + public SmallContainerBlockItemRenderer() { + super(new SmallContainerItemModel()); + } + + @Override + public RenderType getRenderType(SmallContainerBlockItem animatable, ResourceLocation texture, MultiBufferSource bufferSource, float partialTick) { + return RenderType.entityTranslucent(getTextureLocation(animatable)); + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/datagen/ModBlockLootProvider.java b/src/main/java/com/atsuishio/superbwarfare/datagen/ModBlockLootProvider.java index 4af0e65da..6ba439fc6 100644 --- a/src/main/java/com/atsuishio/superbwarfare/datagen/ModBlockLootProvider.java +++ b/src/main/java/com/atsuishio/superbwarfare/datagen/ModBlockLootProvider.java @@ -54,11 +54,10 @@ public class ModBlockLootProvider extends BlockLootSubProvider { LootPool.lootPool().setRolls(ConstantValue.exactly(1.0F)).add(LootItem.lootTableItem(ModBlocks.CONTAINER.get())) .apply(CopyCustomDataFunction.copyData(ContextNbtProvider.BLOCK_ENTITY).copy("Entity", "BlockEntityTag.Entity") .copy("EntityType", "BlockEntityTag.EntityType"))))); - // TODO small container -// this.add(ModBlocks.SMALL_CONTAINER.get(), LootTable.lootTable().withPool(this.applyExplosionCondition(ModBlocks.SMALL_CONTAINER.get(), -// LootPool.lootPool().setRolls(ConstantValue.exactly(1.0F)).add(LootItem.lootTableItem(ModBlocks.SMALL_CONTAINER.get())) -// .apply(CopyNbtFunction.copyData(ContextNbtProvider.BLOCK_ENTITY).copy("LootTable", "BlockEntityTag.LootTable") -// .copy("LootTableSeed", "BlockEntityTag.LootTableSeed"))))); + this.add(ModBlocks.SMALL_CONTAINER.get(), LootTable.lootTable().withPool(this.applyExplosionCondition(ModBlocks.SMALL_CONTAINER.get(), + LootPool.lootPool().setRolls(ConstantValue.exactly(1.0F)).add(LootItem.lootTableItem(ModBlocks.SMALL_CONTAINER.get())) + .apply(CopyCustomDataFunction.copyData(ContextNbtProvider.BLOCK_ENTITY).copy("LootTable", "BlockEntityTag.LootTable") + .copy("LootTableSeed", "BlockEntityTag.LootTableSeed"))))); } @Override diff --git a/src/main/java/com/atsuishio/superbwarfare/datagen/ModBlockStateProvider.java b/src/main/java/com/atsuishio/superbwarfare/datagen/ModBlockStateProvider.java index e1a9a0240..ed6121644 100644 --- a/src/main/java/com/atsuishio/superbwarfare/datagen/ModBlockStateProvider.java +++ b/src/main/java/com/atsuishio/superbwarfare/datagen/ModBlockStateProvider.java @@ -24,8 +24,7 @@ public class ModBlockStateProvider extends BlockStateProvider { horizontalBlock(ModBlocks.JUMP_PAD.get(), new ModelFile.UncheckedModelFile(modLoc("block/jump_pad"))); horizontalBlock(ModBlocks.REFORGING_TABLE.get(), new ModelFile.UncheckedModelFile(modLoc("block/reforging_table"))); horizontalBlock(ModBlocks.CONTAINER.get(), new ModelFile.UncheckedModelFile(modLoc("block/container"))); - // TODO small container - // horizontalBlock(ModBlocks.SMALL_CONTAINER.get(), new ModelFile.UncheckedModelFile(modLoc("block/small_container"))); + horizontalBlock(ModBlocks.SMALL_CONTAINER.get(), new ModelFile.UncheckedModelFile(modLoc("block/small_container"))); horizontalBlock(ModBlocks.CHARGING_STATION.get(), new ModelFile.UncheckedModelFile(modLoc("block/charging_station"))); horizontalBlock(ModBlocks.CREATIVE_CHARGING_STATION.get(), new ModelFile.UncheckedModelFile(modLoc("block/creative_charging_station"))); diff --git a/src/main/java/com/atsuishio/superbwarfare/datagen/ModContainerLootProvider.java b/src/main/java/com/atsuishio/superbwarfare/datagen/ModContainerLootProvider.java new file mode 100644 index 000000000..72b7d975e --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/datagen/ModContainerLootProvider.java @@ -0,0 +1,81 @@ +package com.atsuishio.superbwarfare.datagen; + +import net.minecraft.core.HolderLookup; +import net.minecraft.data.loot.LootTableSubProvider; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.level.ItemLike; +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.LootTable; +import net.minecraft.world.level.storage.loot.entries.LootItem; +import net.minecraft.world.level.storage.loot.providers.number.ConstantValue; +import org.jetbrains.annotations.NotNull; + +import java.util.function.BiConsumer; + +public class ModContainerLootProvider implements LootTableSubProvider { + + public ModContainerLootProvider(HolderLookup.Provider provider) { + super(); + } + + @Override + public void generate(@NotNull BiConsumer, LootTable.Builder> output) { + // TODO resource key +// output.accept(ModUtils.loc("containers/blueprints"), +// LootTable.lootTable().withPool(multiItems(1, 0, +// new PoolTriple(ModItems.GLOCK_17_BLUEPRINT.get(), 60, 0), +// new PoolTriple(ModItems.MP_443_BLUEPRINT.get(), 60, 0), +// new PoolTriple(ModItems.TASER_BLUEPRINT.get(), 60, 0), +// new PoolTriple(ModItems.MARLIN_BLUEPRINT.get(), 60, 0), +// new PoolTriple(ModItems.M_1911_BLUEPRINT.get(), 60, 0), +// new PoolTriple(ModItems.GLOCK_18_BLUEPRINT.get(), 62, 0), +// new PoolTriple(ModItems.M_79_BLUEPRINT.get(), 62, 0), +// new PoolTriple(ModItems.M_4_BLUEPRINT.get(), 62, 0), +// new PoolTriple(ModItems.SKS_BLUEPRINT.get(), 62, 0), +// new PoolTriple(ModItems.M_870_BLUEPRINT.get(), 62, 0), +// new PoolTriple(ModItems.AK_47_BLUEPRINT.get(), 62, 0), +// new PoolTriple(ModItems.K_98_BLUEPRINT.get(), 62, 0), +// new PoolTriple(ModItems.MOSIN_NAGANT_BLUEPRINT.get(), 62, 0), +// new PoolTriple(ModItems.TRACHELIUM_BLUEPRINT.get(), 12, 0), +// new PoolTriple(ModItems.HUNTING_RIFLE_BLUEPRINT.get(), 12, 0), +// new PoolTriple(ModItems.RPG_BLUEPRINT.get(), 12, 0), +// new PoolTriple(ModItems.BOCEK_BLUEPRINT.get(), 12, 0), +// new PoolTriple(ModItems.HK_416_BLUEPRINT.get(), 12, 0), +// new PoolTriple(ModItems.RPK_BLUEPRINT.get(), 12, 0), +// new PoolTriple(ModItems.VECTOR_BLUEPRINT.get(), 12, 0), +// new PoolTriple(ModItems.MK_14_BLUEPRINT.get(), 12, 0), +// new PoolTriple(ModItems.M_60_BLUEPRINT.get(), 12, 0), +// new PoolTriple(ModItems.SVD_BLUEPRINT.get(), 12, 0), +// new PoolTriple(ModItems.M_98B_BLUEPRINT.get(), 12, 0), +// new PoolTriple(ModItems.AK_12_BLUEPRINT.get(), 12, 0), +// new PoolTriple(ModItems.DEVOTION_BLUEPRINT.get(), 12, 0), +// new PoolTriple(ModItems.QBZ_95_BLUEPRINT.get(), 12, 0), +// new PoolTriple(ModItems.AA_12_BLUEPRINT.get(), 5, 0), +// new PoolTriple(ModItems.NTW_20_BLUEPRINT.get(), 5, 0), +// new PoolTriple(ModItems.MINIGUN_BLUEPRINT.get(), 5, 0), +// new PoolTriple(ModItems.SENTINEL_BLUEPRINT.get(), 5, 0), +// new PoolTriple(ModItems.JAVELIN_BLUEPRINT.get(), 5, 0), +// new PoolTriple(ModItems.SECONDARY_CATACLYSM_BLUEPRINT.get(), 5, 0) +// ))); + } + + public LootPool.Builder singleItem(ItemLike item, int weight) { + return singleItem(item, 1, 0, weight, 0); + } + + public LootPool.Builder singleItem(ItemLike item, float rolls, float bonus, int weight, int quality) { + return LootPool.lootPool().setRolls(ConstantValue.exactly(rolls)).setBonusRolls(ConstantValue.exactly(bonus)) + .add(LootItem.lootTableItem(item).setWeight(weight).setQuality(quality)); + } + + public final LootPool.Builder multiItems(float rolls, float bonus, PoolTriple... triplet) { + var builder = LootPool.lootPool().setRolls(ConstantValue.exactly(rolls)).setBonusRolls(ConstantValue.exactly(bonus)); + for (var t : triplet) { + builder.add(LootItem.lootTableItem(t.item()).setWeight(t.weight()).setQuality(t.quality())); + } + return builder; + } + + public record PoolTriple(ItemLike item, int weight, int quality) { + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/datagen/ModLootTableProvider.java b/src/main/java/com/atsuishio/superbwarfare/datagen/ModLootTableProvider.java index fb8c673fe..3eef10b88 100644 --- a/src/main/java/com/atsuishio/superbwarfare/datagen/ModLootTableProvider.java +++ b/src/main/java/com/atsuishio/superbwarfare/datagen/ModLootTableProvider.java @@ -12,7 +12,8 @@ import java.util.concurrent.CompletableFuture; public class ModLootTableProvider { public static LootTableProvider create(PackOutput output, CompletableFuture registries) { return new LootTableProvider(output, Set.of(), List.of( - new LootTableProvider.SubProviderEntry(ModBlockLootProvider::new, LootContextParamSets.BLOCK) + new LootTableProvider.SubProviderEntry(ModBlockLootProvider::new, LootContextParamSets.BLOCK), + new LootTableProvider.SubProviderEntry(ModContainerLootProvider::new, LootContextParamSets.CHEST) ), registries); } } diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModBlockEntities.java b/src/main/java/com/atsuishio/superbwarfare/init/ModBlockEntities.java index 05a2a5f32..cc8d6319d 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModBlockEntities.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModBlockEntities.java @@ -1,10 +1,7 @@ package com.atsuishio.superbwarfare.init; import com.atsuishio.superbwarfare.ModUtils; -import com.atsuishio.superbwarfare.block.entity.ChargingStationBlockEntity; -import com.atsuishio.superbwarfare.block.entity.ContainerBlockEntity; -import com.atsuishio.superbwarfare.block.entity.CreativeChargingStationBlockEntity; -import com.atsuishio.superbwarfare.block.entity.FuMO25BlockEntity; +import com.atsuishio.superbwarfare.block.entity.*; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.world.level.block.entity.BlockEntityType; import net.neoforged.neoforge.registries.DeferredHolder; @@ -16,10 +13,16 @@ public class ModBlockEntities { public static final DeferredHolder, BlockEntityType> CONTAINER = REGISTRY.register("container", () -> BlockEntityType.Builder.of(ContainerBlockEntity::new, ModBlocks.CONTAINER.get()).build(null)); + + public static final DeferredHolder, BlockEntityType> SMALL_CONTAINER = REGISTRY.register("small_container", + () -> BlockEntityType.Builder.of(SmallContainerBlockEntity::new, ModBlocks.SMALL_CONTAINER.get()).build(null)); + public static final DeferredHolder, BlockEntityType> CHARGING_STATION = REGISTRY.register("charging_station", () -> BlockEntityType.Builder.of(ChargingStationBlockEntity::new, ModBlocks.CHARGING_STATION.get()).build(null)); + public static final DeferredHolder, BlockEntityType> CREATIVE_CHARGING_STATION = REGISTRY.register("creative_charging_station", () -> BlockEntityType.Builder.of(CreativeChargingStationBlockEntity::new, ModBlocks.CREATIVE_CHARGING_STATION.get()).build(null)); + public static final DeferredHolder, BlockEntityType> FUMO_25 = REGISTRY.register("fumo_25", () -> BlockEntityType.Builder.of(FuMO25BlockEntity::new, ModBlocks.FUMO_25.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 2626fc4ba..ad2300e60 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModBlocks.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModBlocks.java @@ -44,8 +44,7 @@ public class ModBlocks { public static final DeferredHolder CEMENTED_CARBIDE_BLOCK = REGISTRY.register("cemented_carbide_block", () -> new Block(BlockBehaviour.Properties.of().instrument(NoteBlockInstrument.BASEDRUM).sound(SoundType.METAL).strength(5f, 6f).requiresCorrectToolForDrops())); public static final DeferredHolder CONTAINER = REGISTRY.register("container", ContainerBlock::new); - // TODO small container -// public static final DeferredHolder SMALL_CONTAINER = REGISTRY.register("small_container", SmallContainerBlock::new); + public static final DeferredHolder SMALL_CONTAINER = REGISTRY.register("small_container", () -> new SmallContainerBlock()); 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); diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModItems.java b/src/main/java/com/atsuishio/superbwarfare/init/ModItems.java index 032e5793b..e133e8f76 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModItems.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModItems.java @@ -120,7 +120,8 @@ public class ModItems { */ public static final DeferredRegister ITEMS = DeferredRegister.create(Registries.ITEM, ModUtils.MODID); - // public static final DeferredHolder CONTAINER = ITEMS.register("container", ContainerBlockItem::new); + public static final DeferredHolder CONTAINER = ITEMS.register("container", ContainerBlockItem::new); + public static final DeferredHolder SMALL_CONTAINER = ITEMS.register("small_container", SmallContainerBlockItem::new); // public static final DeferredHolder SENPAI_SPAWN_EGG = ITEMS.register("senpai_spawn_egg", () -> new ForgeSpawnEggItem(ModEntities.SENPAI, -11584987, -14014413, new Item.Properties())); public static final DeferredHolder ANCIENT_CPU = ITEMS.register("ancient_cpu", () -> new Item(new Item.Properties().rarity(Rarity.RARE))); public static final DeferredHolder PROPELLER = ITEMS.register("propeller", () -> new Item(new Item.Properties())); diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModTabs.java b/src/main/java/com/atsuishio/superbwarfare/init/ModTabs.java index 3a4cdac4c..160f967f3 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModTabs.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModTabs.java @@ -1,6 +1,7 @@ package com.atsuishio.superbwarfare.init; import com.atsuishio.superbwarfare.ModUtils; +import com.atsuishio.superbwarfare.item.ArmorPlate; import com.atsuishio.superbwarfare.item.BatteryItem; import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; @@ -12,6 +13,10 @@ import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; import net.neoforged.neoforge.registries.DeferredHolder; import net.neoforged.neoforge.registries.DeferredRegister; +import java.util.function.Supplier; + +import static com.atsuishio.superbwarfare.item.ContainerBlockItem.CONTAINER_ENTITIES; + @EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD) @SuppressWarnings("unused") public class ModTabs { @@ -49,6 +54,7 @@ public class ModTabs { } }); + // TODO c4, potion // param.holders().lookup(Registries.POTION) // .ifPresent(potion -> generatePotionEffectTypes(output, potion, ModItems.POTION_MORTAR_SHELL.get())); }) @@ -59,15 +65,13 @@ public class ModTabs { .title(Component.translatable("item_group.superbwarfare.item")) .icon(() -> new ItemStack(ModItems.FIRING_PARAMETERS.get())) .displayItems((param, output) -> ModItems.ITEMS.getEntries().forEach(registryObject -> { - // TODO container, armor plate -// if (registryObject.get() == ModItems.CONTAINER.get()) { - if (false) { -// CONTAINER_ENTITIES.stream().map(Supplier::get).forEach(output::accept); + if (registryObject.get() == ModItems.CONTAINER.get()) { + CONTAINER_ENTITIES.stream().map(Supplier::get).forEach(output::accept); } else { output.accept(registryObject.get()); -// if (registryObject.get() == ModItems.ARMOR_PLATE.get()) { -// output.accept(ArmorPlate.getInfiniteInstance()); -// } + if (registryObject.get() == ModItems.ARMOR_PLATE.get()) { + output.accept(ArmorPlate.getInfiniteInstance()); + } if (registryObject.get() instanceof BatteryItem batteryItem) { output.accept(batteryItem.makeFullEnergyStack()); } @@ -85,11 +89,13 @@ public class ModTabs { @SubscribeEvent public static void buildTabContentsVanilla(BuildCreativeModeTabContentsEvent tabData) { + // TODO senpai // if (tabData.getTabKey() == CreativeModeTabs.SPAWN_EGGS) { // tabData.accept(ModItems.SENPAI_SPAWN_EGG.get()); // } } + // TODO potion shell // private static void generatePotionEffectTypes(CreativeModeTab.Output output, HolderLookup potions, Item potionItem) { // potions.listElements().filter(potion -> !potion.is(Potions.EMPTY_ID)) // .map(potion -> PotionUtils.setPotion(new ItemStack(potionItem), potion.value())) diff --git a/src/main/java/com/atsuishio/superbwarfare/item/ContainerBlockItem.java b/src/main/java/com/atsuishio/superbwarfare/item/ContainerBlockItem.java new file mode 100644 index 000000000..bcd6f24ea --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/item/ContainerBlockItem.java @@ -0,0 +1,183 @@ +package com.atsuishio.superbwarfare.item; + +import com.atsuishio.superbwarfare.ModUtils; +import com.atsuishio.superbwarfare.client.renderer.item.ContainerBlockItemRenderer; +import com.atsuishio.superbwarfare.init.ModBlockEntities; +import com.atsuishio.superbwarfare.init.ModBlocks; +import com.atsuishio.superbwarfare.init.ModEntities; +import com.atsuishio.superbwarfare.init.ModItems; +import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer; +import net.minecraft.core.component.DataComponents; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.CustomData; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.ClipContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.HitResult; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions; +import net.neoforged.neoforge.client.extensions.common.RegisterClientExtensionsEvent; +import org.jetbrains.annotations.NotNull; +import software.bernie.geckolib.animatable.GeoItem; +import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; +import software.bernie.geckolib.animation.AnimatableManager; +import software.bernie.geckolib.animation.AnimationController; +import software.bernie.geckolib.animation.AnimationState; +import software.bernie.geckolib.animation.PlayState; +import software.bernie.geckolib.util.GeckoLibUtil; + +import java.util.List; +import java.util.function.Supplier; + +@EventBusSubscriber(modid = ModUtils.MODID, bus = EventBusSubscriber.Bus.MOD) +public class ContainerBlockItem extends BlockItem implements GeoItem { + + /** + * 集装箱可用实体列表 + */ + // TODO 正确生成可用列表 + public static final List> CONTAINER_ENTITIES = List.of( + () -> ContainerBlockItem.createInstance(ModEntities.TARGET.get()) +// () -> ContainerBlockItem.createInstance(ModEntities.MK_42.get()), +// () -> ContainerBlockItem.createInstance(ModEntities.MLE_1934.get()), +// () -> ContainerBlockItem.createInstance(ModEntities.ANNIHILATOR.get()), +// () -> ContainerBlockItem.createInstance(ModEntities.LASER_TOWER.get()), +// () -> ContainerBlockItem.createInstance(ModEntities.SPEEDBOAT.get(), true), +// () -> ContainerBlockItem.createInstance(ModEntities.AH_6.get()), +// () -> ContainerBlockItem.createInstance(ModEntities.LAV_150.get(), true), +// () -> ContainerBlockItem.createInstance(ModEntities.BMP_2.get(), true), +// () -> ContainerBlockItem.createInstance(ModEntities.YX_100.get()), +// () -> ContainerBlockItem.createInstance(ModEntities.WHEEL_CHAIR.get()), +// () -> ContainerBlockItem.createInstance(ModEntities.TOM_6.get()) + ); + + private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); + + public ContainerBlockItem() { + super(ModBlocks.CONTAINER.get(), new Properties().stacksTo(1)); + } + + @Override + public @NotNull InteractionResult useOn(UseOnContext context) { + ItemStack stack = context.getItemInHand(); + var data = stack.get(DataComponents.CUSTOM_DATA); + + if (data != null && data.copyTag().getBoolean("CanPlacedAboveWater")) { + return InteractionResult.PASS; + } + return super.useOn(context); + } + + @Override + public @NotNull InteractionResultHolder use(@NotNull Level level, Player player, @NotNull InteractionHand hand) { + ItemStack stack = player.getItemInHand(hand); + var data = stack.get(DataComponents.CUSTOM_DATA); + + if (data != null && data.copyTag().getBoolean("CanPlacedAboveWater")) { + BlockHitResult playerPOVHitResult = getPlayerPOVHitResult(level, player, ClipContext.Fluid.WATER); + if (playerPOVHitResult.getType() == HitResult.Type.MISS) { + return super.use(level, player, hand); + } + BlockHitResult blockHitResult = playerPOVHitResult.withPosition(playerPOVHitResult.getBlockPos().above()); + InteractionResult interactionresult = super.useOn(new UseOnContext(player, hand, blockHitResult)); + return new InteractionResultHolder<>(interactionresult, player.getItemInHand(hand)); + } + return super.use(level, player, hand); + } + + @Override + public @NotNull InteractionResult place(BlockPlaceContext pContext) { + ItemStack stack = pContext.getItemInHand(); + Player player = pContext.getPlayer(); + var res = super.place(pContext); + + if (player != null) { + var tag = stack.get(DataComponents.BLOCK_ENTITY_DATA); + if (tag != null && tag.copyTag().get("Entity") != null) { + if (player.level().isClientSide && res == InteractionResult.SUCCESS) { + player.getInventory().removeItem(stack); + } + if (!player.level().isClientSide && res == InteractionResult.CONSUME) { + player.getInventory().removeItem(stack); + } + } + } + return res; + } + + private PlayState predicate(AnimationState event) { + return PlayState.CONTINUE; + } + + + @SubscribeEvent + private static void registerArmorExtensions(RegisterClientExtensionsEvent event) { + event.registerItem(new IClientItemExtensions() { + + private final BlockEntityWithoutLevelRenderer renderer = new ContainerBlockItemRenderer(); + + @Override + public @NotNull BlockEntityWithoutLevelRenderer getCustomRenderer() { + return renderer; + } + + }, ModItems.CONTAINER); + } + + @Override + public void registerControllers(AnimatableManager.ControllerRegistrar data) { + data.add(new AnimationController<>(this, "controller", 0, this::predicate)); + } + + @Override + public AnimatableInstanceCache getAnimatableInstanceCache() { + return this.cache; + } + + public static ItemStack createInstance(Entity entity) { + return createInstance(entity, false); + } + + public static ItemStack createInstance(EntityType entityType) { + return createInstance(entityType, false); + } + + public static ItemStack createInstance(Entity entity, boolean canPlacedAboveWater) { + ItemStack stack = new ItemStack(ModBlocks.CONTAINER.get()); + + var data = stack.get(DataComponents.CUSTOM_DATA); + var tag = data != null ? data.copyTag() : new CompoundTag(); + + tag.put("Entity", entity.serializeNBT(entity.level().registryAccess())); + tag.putString("EntityType", EntityType.getKey(entity.getType()).toString()); + BlockItem.setBlockEntityData(stack, ModBlockEntities.CONTAINER.get(), tag); + tag.putBoolean("CanPlacedAboveWater", canPlacedAboveWater); + stack.set(DataComponents.CUSTOM_DATA, CustomData.of(tag)); + + return stack; + } + + public static ItemStack createInstance(EntityType entityType, boolean canPlacedAboveWater) { + ItemStack stack = new ItemStack(ModBlocks.CONTAINER.get()); + var data = stack.get(DataComponents.CUSTOM_DATA); + var tag = data != null ? data.copyTag() : new CompoundTag(); + + tag.putString("EntityType", EntityType.getKey(entityType).toString()); + BlockItem.setBlockEntityData(stack, ModBlockEntities.CONTAINER.get(), tag); + tag.putBoolean("CanPlacedAboveWater", canPlacedAboveWater); + stack.set(DataComponents.CUSTOM_DATA, CustomData.of(tag)); + + return stack; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/item/SmallContainerBlockItem.java b/src/main/java/com/atsuishio/superbwarfare/item/SmallContainerBlockItem.java new file mode 100644 index 000000000..3abc767c4 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/item/SmallContainerBlockItem.java @@ -0,0 +1,84 @@ +package com.atsuishio.superbwarfare.item; + +import com.atsuishio.superbwarfare.ModUtils; +import com.atsuishio.superbwarfare.client.renderer.item.SmallContainerBlockItemRenderer; +import com.atsuishio.superbwarfare.init.ModBlockEntities; +import com.atsuishio.superbwarfare.init.ModBlocks; +import com.atsuishio.superbwarfare.init.ModItems; +import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions; +import net.neoforged.neoforge.client.extensions.common.RegisterClientExtensionsEvent; +import org.jetbrains.annotations.NotNull; +import software.bernie.geckolib.animatable.GeoItem; +import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; +import software.bernie.geckolib.animation.AnimatableManager; +import software.bernie.geckolib.animation.AnimationController; +import software.bernie.geckolib.animation.AnimationState; +import software.bernie.geckolib.animation.PlayState; +import software.bernie.geckolib.util.GeckoLibUtil; + +import java.util.List; +import java.util.function.Supplier; + +@EventBusSubscriber(modid = ModUtils.MODID, bus = EventBusSubscriber.Bus.MOD) +public class SmallContainerBlockItem extends BlockItem implements GeoItem { + + public static final List> SMALL_CONTAINER_LOOT_TABLES = List.of( + () -> SmallContainerBlockItem.createInstance(ModUtils.loc("containers/blueprints")) + ); + + private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); + + public SmallContainerBlockItem() { + super(ModBlocks.SMALL_CONTAINER.get(), new Properties().stacksTo(1)); + } + + private PlayState predicate(AnimationState event) { + return PlayState.CONTINUE; + } + + @SubscribeEvent + private static void registerArmorExtensions(RegisterClientExtensionsEvent event) { + event.registerItem(new IClientItemExtensions() { + + private final BlockEntityWithoutLevelRenderer renderer = new SmallContainerBlockItemRenderer(); + + @Override + public @NotNull BlockEntityWithoutLevelRenderer getCustomRenderer() { + return renderer; + } + + }, ModItems.SMALL_CONTAINER); + } + + @Override + public void registerControllers(AnimatableManager.ControllerRegistrar data) { + data.add(new AnimationController<>(this, "controller", 0, this::predicate)); + } + + @Override + public AnimatableInstanceCache getAnimatableInstanceCache() { + return this.cache; + } + + public static ItemStack createInstance(ResourceLocation lootTable) { + return createInstance(lootTable, 0L); + } + + public static ItemStack createInstance(ResourceLocation lootTable, long lootTableSeed) { + ItemStack stack = new ItemStack(ModBlocks.SMALL_CONTAINER.get()); + CompoundTag tag = new CompoundTag(); + tag.putString("LootTable", lootTable.toString()); + if (lootTableSeed != 0L) { + tag.putLong("LootTableSeed", lootTableSeed); + } + BlockItem.setBlockEntityData(stack, ModBlockEntities.SMALL_CONTAINER.get(), tag); + return stack; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/NBTTool.java b/src/main/java/com/atsuishio/superbwarfare/tools/NBTTool.java index e14af944e..8a9955ef8 100644 --- a/src/main/java/com/atsuishio/superbwarfare/tools/NBTTool.java +++ b/src/main/java/com/atsuishio/superbwarfare/tools/NBTTool.java @@ -5,6 +5,7 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.world.item.ItemStack; // From Botania +// TODO 修改为使用DataComponents.CUSTOM_DATA public final class NBTTool { public static boolean verifyExistence(ItemStack stack, String tag) { var data = stack.get(ModDataComponents.GUN_DATA);