Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Portable storage piston/dispenser behaviors #60

Merged
merged 3 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"type": "minecraft:block",
"pools": [
{
"bonus_rolls": 0.0,
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
],
"entries": [
{
"type": "minecraft:item",
"functions": [
{
"function": "oritech:nbt_block_loot_function"
}
],
"name": "oritech:small_storage_block"
}
],
"rolls": 1.0
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"type": "minecraft:block",
"pools": [
{
"bonus_rolls": 0.0,
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
],
"entries": [
{
"type": "minecraft:item",
"functions": [
{
"function": "oritech:nbt_block_loot_function"
}
],
"name": "oritech:small_tank_block"
}
],
"rolls": 1.0
}
]
}
1 change: 1 addition & 0 deletions src/main/java/rearth/oritech/Oritech.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public void onInitialize() {
NetworkContent.registerChannels();
ParticleContent.registerParticles();
FeatureContent.initialize();
LootContent.init();

ServerLifecycleEvents.SERVER_STARTED.register(this::onServerStarted);
PlayerBlockBreakEvents.BEFORE.register(PromethiumPickaxeItem::preMine);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,24 @@
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.NbtComponent;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.loot.context.LootContextParameterSet;
import net.minecraft.loot.context.LootContextParameters;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.WorldView;

import java.util.List;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import rearth.oritech.block.entity.machines.storage.SmallFluidTankEntity;
import rearth.oritech.init.BlockContent;

Expand Down Expand Up @@ -65,30 +70,17 @@ public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEnt

return ActionResult.SUCCESS;
}

@Override
public BlockState onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) {

if (!world.isClient) {
var stack = getStackWithData(world, pos);
var tankEntity = (SmallFluidTankEntity) world.getBlockEntity(pos);

if (!player.isCreative())
Block.dropStack(world, pos, stack);

var stacks = tankEntity.inventory.heldStacks;
for (var heldStack : stacks) {
if (!heldStack.isEmpty()) {
var itemEntity = new ItemEntity(world, pos.getX(), pos.getY(), pos.getZ(), heldStack);
world.spawnEntity(itemEntity);
}
}

}

return super.onBreak(world, pos, state, player);

protected List<ItemStack> getDroppedStacks(BlockState state, LootContextParameterSet.Builder builder) {
var droppedStacks = super.getDroppedStacks(state, builder);

var blockEntity = (BlockEntity)builder.getOptional(LootContextParameters.BLOCK_ENTITY);
if (blockEntity instanceof SmallFluidTankEntity tankEntity)
droppedStacks.addAll(tankEntity.inventory.getHeldStacks());

return droppedStacks;
}

@Override
public ItemStack getPickStack(WorldView world, BlockPos pos, BlockState state) {
return getStackWithData(world, pos);
Expand All @@ -102,7 +94,6 @@ private static ItemStack getStackWithData(WorldView world, BlockPos pos) {
if (tankEntity.getForDirectFluidAccess().amount > 0) {
var nbt = new NbtCompound();
tankEntity.writeNbt(nbt, world.getRegistryManager());
nbt.remove("Items");
stack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(nbt));
var fluidName = FluidVariantAttributes.getName(tankEntity.getForDirectFluidAccess().variant);
stack.set(DataComponentTypes.CUSTOM_NAME, fluidName.copy().append(" ").append(Text.translatable("block.oritech.small_tank_block")));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package rearth.oritech.block.blocks.machines.storage;

import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariantAttributes;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockRenderType;
Expand All @@ -10,13 +11,14 @@
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.NbtComponent;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemStack;
import net.minecraft.item.tooltip.TooltipType;
import net.minecraft.loot.context.LootContextParameterSet;
import net.minecraft.loot.context.LootContextParameters;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.DirectionProperty;
Expand All @@ -27,14 +29,19 @@
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
import net.minecraft.world.WorldView;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import rearth.oritech.block.base.entity.ExpandableEnergyStorageBlockEntity;
import rearth.oritech.block.entity.machines.storage.SmallFluidTankEntity;
import rearth.oritech.block.entity.machines.storage.SmallStorageBlockEntity;
import rearth.oritech.init.BlockContent;
import rearth.oritech.util.MachineAddonController;

import java.util.List;
import java.util.Objects;
import java.util.UUID;

import static rearth.oritech.util.TooltipHelper.addMachineTooltip;

Expand Down Expand Up @@ -106,43 +113,34 @@ public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEnt

return ActionResult.SUCCESS;
}


protected List<ItemStack> getDroppedStacks(BlockState state, LootContextParameterSet.Builder builder) {
var droppedStacks = super.getDroppedStacks(state, builder);

var blockEntity = (BlockEntity)builder.getOptional(LootContextParameters.BLOCK_ENTITY);
if (blockEntity instanceof SmallStorageBlockEntity storageEntity)
droppedStacks.addAll(storageEntity.inventory.getHeldStacks());

return droppedStacks;
}

@Override
public BlockState onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) {
public ItemStack getPickStack(WorldView world, BlockPos pos, BlockState state) {
return getStackWithData(world, pos);
}

@NotNull
private static ItemStack getStackWithData(WorldView world, BlockPos pos) {
var stack = new ItemStack(BlockContent.SMALL_STORAGE_BLOCK.asItem());
var storageEntity = (SmallStorageBlockEntity) world.getBlockEntity(pos);

if (!world.isClient()) {

var entity = world.getBlockEntity(pos);
if (entity instanceof MachineAddonController machineEntity) {
machineEntity.resetAddons();
}

if (entity instanceof ExpandableEnergyStorageBlockEntity storageBlock) {
var stacks = storageBlock.inventory.heldStacks;
for (var heldStack : stacks) {
if (!heldStack.isEmpty()) {
var itemEntity = new ItemEntity(world, pos.getX(), pos.getY(), pos.getZ(), heldStack);
world.spawnEntity(itemEntity);
}
}

// drop block with nbt
if (state.getBlock().equals(BlockContent.SMALL_STORAGE_BLOCK)) {
var stack = new ItemStack(BlockContent.SMALL_STORAGE_BLOCK.asItem());
var storedAmount = storageBlock.getStorageForAddon().amount;
if (storedAmount > 0) {
var nbt = new NbtCompound();
storageBlock.writeNbt(nbt, world.getRegistryManager());
stack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(nbt));
}

if (!player.isCreative())
Block.dropStack(world, pos, stack);
}
}
if (storageEntity.getStorage(null).getAmount() > 0) {
var nbt = new NbtCompound();
storageEntity.writeNbt(nbt, world.getRegistryManager());
stack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(nbt));
}

return super.onBreak(world, pos, state, player);
return stack;
}

@Override
Expand Down
17 changes: 15 additions & 2 deletions src/main/java/rearth/oritech/init/BlockContent.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import io.wispforest.owo.registration.reflect.BlockRegistryContainer;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.*;
import net.minecraft.block.dispenser.BlockPlacementDispenserBehavior;
import net.minecraft.block.piston.PistonBehavior;
import net.minecraft.fluid.FlowableFluid;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
Expand Down Expand Up @@ -104,10 +106,12 @@ public class BlockContent implements BlockRegistryContainer {
public static final Block DRONE_PORT_BLOCK = new DronePortBlock(FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).nonOpaque());

@NoAutoDrop
public static final Block SMALL_STORAGE_BLOCK = new SmallStorageBlock(FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).nonOpaque());
@DispenserPlace
public static final Block SMALL_STORAGE_BLOCK = new SmallStorageBlock(FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).nonOpaque().pistonBehavior(PistonBehavior.DESTROY));
public static final Block LARGE_STORAGE_BLOCK = new LargeStorageBlock(FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).nonOpaque());
@NoAutoDrop
public static final Block SMALL_TANK_BLOCK = new SmallFluidTank(FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).nonOpaque());
@DispenserPlace
public static final Block SMALL_TANK_BLOCK = new SmallFluidTank(FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).nonOpaque().pistonBehavior(PistonBehavior.DESTROY));

public static final Block PLACER_BLOCK = new PlacerBlock(FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).nonOpaque());
public static final Block DESTROYER_BLOCK = new DestroyerBlock(FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).nonOpaque());
Expand Down Expand Up @@ -241,6 +245,10 @@ public void postProcessField(String namespace, Block value, String identifier, F
if (!field.isAnnotationPresent(NoAutoDrop.class)) {
BlockLootGenerator.autoRegisteredDrops.add(value);
}

if (field.isAnnotationPresent(DispenserPlace.class)) {
DispenserBlock.registerBehavior(value, new BlockPlacementDispenserBehavior());
}

ItemGroups.add(targetGroup, value);
}
Expand All @@ -260,5 +268,10 @@ private BlockItem getGeoBlockItem(Block block, String identifier, float scale) {
@Target({ElementType.FIELD})
public @interface NoAutoDrop {
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface DispenserPlace {
}

}
15 changes: 15 additions & 0 deletions src/main/java/rearth/oritech/init/LootContent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package rearth.oritech.init;

import net.minecraft.loot.function.LootFunctionType;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import rearth.oritech.Oritech;
import rearth.oritech.init.datagen.loot.NbtBlockLootFunction;

public class LootContent {
public static final LootFunctionType<NbtBlockLootFunction> NBT_BLOCK_LOOT_FUNCTION = new LootFunctionType<>(NbtBlockLootFunction.CODEC);

public static void init() {
Registry.register(Registries.LOOT_FUNCTION_TYPE, Oritech.id("nbt_block_loot_function"), NBT_BLOCK_LOOT_FUNCTION);
}
}
19 changes: 19 additions & 0 deletions src/main/java/rearth/oritech/init/datagen/BlockLootGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,18 @@
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricBlockLootTableProvider;
import net.minecraft.block.Block;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.item.Item;
import net.minecraft.loot.LootPool;
import net.minecraft.loot.LootTable;
import net.minecraft.loot.entry.ItemEntry;
import net.minecraft.loot.function.CopyComponentsLootFunction;
import net.minecraft.loot.function.CopyComponentsLootFunction.Source;
import net.minecraft.loot.provider.number.ConstantLootNumberProvider;
import net.minecraft.registry.RegistryWrapper;
import rearth.oritech.init.BlockContent;
import rearth.oritech.init.ItemContent;
import rearth.oritech.init.datagen.loot.NbtBlockLootFunction;

import java.util.HashSet;
import java.util.Set;
Expand Down Expand Up @@ -34,9 +42,20 @@ public void generate() {
addDrop(BlockContent.ITEM_PIPE_CONNECTION, BlockContent.ITEM_PIPE);
addDrop(BlockContent.FLUID_PIPE_CONNECTION, BlockContent.FLUID_PIPE);
addDrop(BlockContent.ENERGY_PIPE_CONNECTION, BlockContent.ENERGY_PIPE);

addCustomDataDrop(BlockContent.SMALL_TANK_BLOCK);
addCustomDataDrop(BlockContent.SMALL_STORAGE_BLOCK);
}

private void addOreDrop(Block block, Item item) {
addDrop(block, oreDrops(block, item));
}

private void addCustomDataDrop(Block block) {
// similar to shulkerBoxDrops
addDrop(block, LootTable.builder().pool(
(LootPool.Builder)this.addSurvivesExplosionCondition(block, LootPool.builder()
.rolls(ConstantLootNumberProvider.create(1.0F))
.with(ItemEntry.builder(block).apply(NbtBlockLootFunction.builder())))));
}
}
Loading
Loading