同步更新内容

This commit is contained in:
Light_Quanta 2025-03-27 22:36:46 +08:00
parent 8c1fed9923
commit b2c48cde0e
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
31 changed files with 1169 additions and 32 deletions

View file

@ -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

View file

@ -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

View file

@ -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
}
}
}

View file

@ -11,7 +11,7 @@
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:air"
"name": "superbwarfare:container"
}
],
"functions": [

View file

@ -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"
}

View file

@ -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 <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, @NotNull BlockState state, @NotNull BlockEntityType<T> 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<Component> 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<SmallContainerBlock> CODEC = BlockBehaviour.simpleCodec(SmallContainerBlock::new);
@Override
protected @NotNull MapCodec<? extends BaseEntityBlock> 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<Block, BlockState> 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;
}
}

View file

@ -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<SmallContainerBlockEntity> 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<ItemStack> 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;
}
}

View file

@ -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());
}
}

View file

@ -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<ContainerBlockEntity> {
@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");
}
}

View file

@ -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<FuMO25BlockEntity> {
@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");
}
}

View file

@ -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<SmallContainerBlockEntity> {
@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");
}
}

View file

@ -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<ContainerBlockItem> {
@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");
}
}

View file

@ -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<SmallContainerBlockItem> {
@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");
}
}

View file

@ -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));
}

View file

@ -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<ChargingStationBlockEntity> {
@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;
}
}

View file

@ -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<ContainerBlockEntity> {
public ContainerBlockEntityRenderer() {
super(new ContainerBlockModel());
}
@Override
public RenderType getRenderType(ContainerBlockEntity animatable, ResourceLocation texture, MultiBufferSource bufferSource, float partialTick) {
return RenderType.entityTranslucent(getTextureLocation(animatable));
}
}

View file

@ -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<FuMO25BlockEntity> {
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);
}
}

View file

@ -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<SmallContainerBlockEntity> {
public SmallContainerBlockEntityRenderer() {
super(new SmallContainerBlockModel());
}
@Override
public RenderType getRenderType(SmallContainerBlockEntity animatable, ResourceLocation texture, MultiBufferSource bufferSource, float partialTick) {
return RenderType.entityTranslucent(getTextureLocation(animatable));
}
}

View file

@ -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<ContainerBlockItem> {
public ContainerBlockItemRenderer() {
super(new ContainerItemModel());
}
@Override
public RenderType getRenderType(ContainerBlockItem animatable, ResourceLocation texture, MultiBufferSource bufferSource, float partialTick) {
return RenderType.entityTranslucent(getTextureLocation(animatable));
}
}

View file

@ -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<SmallContainerBlockItem> {
public SmallContainerBlockItemRenderer() {
super(new SmallContainerItemModel());
}
@Override
public RenderType getRenderType(SmallContainerBlockItem animatable, ResourceLocation texture, MultiBufferSource bufferSource, float partialTick) {
return RenderType.entityTranslucent(getTextureLocation(animatable));
}
}

View file

@ -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

View file

@ -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")));

View file

@ -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<ResourceKey<LootTable>, 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) {
}
}

View file

@ -12,7 +12,8 @@ import java.util.concurrent.CompletableFuture;
public class ModLootTableProvider {
public static LootTableProvider create(PackOutput output, CompletableFuture<HolderLookup.Provider> 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);
}
}

View file

@ -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<?>, BlockEntityType<ContainerBlockEntity>> CONTAINER = REGISTRY.register("container",
() -> BlockEntityType.Builder.of(ContainerBlockEntity::new, ModBlocks.CONTAINER.get()).build(null));
public static final DeferredHolder<BlockEntityType<?>, BlockEntityType<SmallContainerBlockEntity>> SMALL_CONTAINER = REGISTRY.register("small_container",
() -> BlockEntityType.Builder.of(SmallContainerBlockEntity::new, ModBlocks.SMALL_CONTAINER.get()).build(null));
public static final DeferredHolder<BlockEntityType<?>, BlockEntityType<ChargingStationBlockEntity>> CHARGING_STATION = REGISTRY.register("charging_station",
() -> BlockEntityType.Builder.of(ChargingStationBlockEntity::new, ModBlocks.CHARGING_STATION.get()).build(null));
public static final DeferredHolder<BlockEntityType<?>, BlockEntityType<CreativeChargingStationBlockEntity>> 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<?>, BlockEntityType<FuMO25BlockEntity>> FUMO_25 = REGISTRY.register("fumo_25",
() -> BlockEntityType.Builder.of(FuMO25BlockEntity::new, ModBlocks.FUMO_25.get()).build(null));

View file

@ -44,8 +44,7 @@ public class ModBlocks {
public static final DeferredHolder<Block, Block> 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<Block, Block> CONTAINER = REGISTRY.register("container", ContainerBlock::new);
// TODO small container
// public static final DeferredHolder<Block,Block> SMALL_CONTAINER = REGISTRY.register("small_container", SmallContainerBlock::new);
public static final DeferredHolder<Block, Block> SMALL_CONTAINER = REGISTRY.register("small_container", () -> new SmallContainerBlock());
public static final DeferredHolder<Block, Block> CHARGING_STATION = REGISTRY.register("charging_station", ChargingStationBlock::new);
public static final DeferredHolder<Block, Block> CREATIVE_CHARGING_STATION = REGISTRY.register("creative_charging_station", () -> new CreativeChargingStationBlock());
public static final DeferredHolder<Block, Block> FUMO_25 = REGISTRY.register("fumo_25", FuMO25Block::new);

View file

@ -120,7 +120,8 @@ public class ModItems {
*/
public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(Registries.ITEM, ModUtils.MODID);
// public static final DeferredHolder<Item, Item> CONTAINER = ITEMS.register("container", ContainerBlockItem::new);
public static final DeferredHolder<Item, Item> CONTAINER = ITEMS.register("container", ContainerBlockItem::new);
public static final DeferredHolder<Item, Item> SMALL_CONTAINER = ITEMS.register("small_container", SmallContainerBlockItem::new);
// public static final DeferredHolder<Item, Item> SENPAI_SPAWN_EGG = ITEMS.register("senpai_spawn_egg", () -> new ForgeSpawnEggItem(ModEntities.SENPAI, -11584987, -14014413, new Item.Properties()));
public static final DeferredHolder<Item, Item> ANCIENT_CPU = ITEMS.register("ancient_cpu", () -> new Item(new Item.Properties().rarity(Rarity.RARE)));
public static final DeferredHolder<Item, Item> PROPELLER = ITEMS.register("propeller", () -> new Item(new Item.Properties()));

View file

@ -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<Potion> potions, Item potionItem) {
// potions.listElements().filter(potion -> !potion.is(Potions.EMPTY_ID))
// .map(potion -> PotionUtils.setPotion(new ItemStack(potionItem), potion.value()))

View file

@ -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<Supplier<ItemStack>> 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<ItemStack> 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<ContainerBlockItem> 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;
}
}

View file

@ -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<Supplier<ItemStack>> 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<SmallContainerBlockItem> 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;
}
}

View file

@ -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);