2018-11-05 16:36:10 +01:00
|
|
|
package de.ellpeck.naturesaura.blocks.tiles;
|
|
|
|
|
|
|
|
import de.ellpeck.naturesaura.Helper;
|
2018-11-11 13:26:19 +01:00
|
|
|
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
|
2018-11-09 12:42:08 +01:00
|
|
|
import de.ellpeck.naturesaura.items.ModItems;
|
2020-01-22 23:21:52 +01:00
|
|
|
import de.ellpeck.naturesaura.packet.PacketHandler;
|
|
|
|
import de.ellpeck.naturesaura.packet.PacketParticles;
|
2021-12-08 00:31:29 +01:00
|
|
|
import net.minecraft.core.BlockPos;
|
|
|
|
import net.minecraft.core.Direction;
|
|
|
|
import net.minecraft.server.level.ServerLevel;
|
|
|
|
import net.minecraft.world.InteractionHand;
|
|
|
|
import net.minecraft.world.entity.decoration.ItemFrame;
|
|
|
|
import net.minecraft.world.item.ItemStack;
|
|
|
|
import net.minecraft.world.item.context.UseOnContext;
|
|
|
|
import net.minecraft.world.level.block.Blocks;
|
|
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
|
|
import net.minecraft.world.phys.BlockHitResult;
|
|
|
|
import net.minecraft.world.phys.Vec3;
|
2020-01-23 20:57:56 +01:00
|
|
|
import net.minecraftforge.common.ForgeHooks;
|
2018-11-05 16:36:10 +01:00
|
|
|
import net.minecraftforge.common.util.FakePlayerFactory;
|
|
|
|
import net.minecraftforge.items.CapabilityItemHandler;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.List;
|
|
|
|
|
2021-12-04 15:40:09 +01:00
|
|
|
public class BlockEntityPlacer extends BlockEntityImpl implements ITickableBlockEntity {
|
2020-01-21 21:04:44 +01:00
|
|
|
|
2021-12-08 00:31:29 +01:00
|
|
|
public BlockEntityPlacer(BlockPos pos, BlockState state) {
|
2021-12-19 15:32:45 +01:00
|
|
|
super(ModBlockEntities.PLACER, pos, state);
|
2020-01-21 21:04:44 +01:00
|
|
|
}
|
2018-11-05 16:36:10 +01:00
|
|
|
|
|
|
|
@Override
|
2020-01-21 21:04:44 +01:00
|
|
|
public void tick() {
|
2021-12-04 15:40:09 +01:00
|
|
|
if (!this.level.isClientSide && this.level.getGameTime() % 15 == 0) {
|
2018-11-28 13:18:21 +01:00
|
|
|
if (this.redstonePower > 0)
|
|
|
|
return;
|
2021-12-15 16:30:22 +01:00
|
|
|
var tileUp = this.level.getBlockEntity(this.worldPosition.above());
|
2020-01-21 21:04:44 +01:00
|
|
|
if (tileUp == null)
|
2018-11-05 16:36:10 +01:00
|
|
|
return;
|
2021-12-15 16:30:22 +01:00
|
|
|
var handler = tileUp.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, Direction.DOWN).orElse(null);
|
2018-11-05 16:36:10 +01:00
|
|
|
if (handler == null)
|
|
|
|
return;
|
2021-12-15 16:30:22 +01:00
|
|
|
var frames = Helper.getAttachedItemFrames(this.level, this.worldPosition);
|
2018-11-05 16:36:10 +01:00
|
|
|
if (frames.isEmpty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
List<BlockPos> validPositions = new ArrayList<>();
|
2021-12-15 16:30:22 +01:00
|
|
|
var range = 5;
|
|
|
|
for (var x = -range; x <= range; x++)
|
|
|
|
for (var y = -range; y <= range; y++)
|
|
|
|
for (var z = -range; z <= range; z++) {
|
|
|
|
var pos = this.worldPosition.offset(x, y, z);
|
2021-12-04 15:40:09 +01:00
|
|
|
if (!this.framesContain(frames, pos, this.level.getBlockState(pos)))
|
2018-11-05 16:36:10 +01:00
|
|
|
continue;
|
|
|
|
|
2021-12-15 16:30:22 +01:00
|
|
|
var up = pos.above();
|
|
|
|
var state = this.level.getBlockState(up);
|
2020-01-23 22:40:03 +01:00
|
|
|
if (state.getMaterial().isReplaceable())
|
2018-11-05 16:36:10 +01:00
|
|
|
validPositions.add(up);
|
|
|
|
}
|
|
|
|
if (validPositions.isEmpty())
|
|
|
|
return;
|
|
|
|
|
2021-12-15 16:30:22 +01:00
|
|
|
for (var i = 0; i < handler.getSlots(); i++) {
|
|
|
|
var stack = handler.extractItem(i, 1, true);
|
2018-11-05 16:36:10 +01:00
|
|
|
if (stack.isEmpty())
|
|
|
|
continue;
|
|
|
|
|
2021-12-15 16:30:22 +01:00
|
|
|
var pos = validPositions.get(this.level.random.nextInt(validPositions.size()));
|
|
|
|
var left = this.tryPlace(stack.copy(), pos);
|
2021-12-19 15:40:53 +01:00
|
|
|
if (ItemStack.matches(stack, left))
|
2018-11-05 16:36:10 +01:00
|
|
|
continue;
|
|
|
|
|
|
|
|
handler.extractItem(i, 1, false);
|
2021-12-15 16:30:22 +01:00
|
|
|
var spot = IAuraChunk.getHighestSpot(this.level, this.worldPosition, 10, this.worldPosition);
|
2021-12-04 15:40:09 +01:00
|
|
|
IAuraChunk.getAuraChunk(this.level, spot).drainAura(spot, 1000);
|
2018-11-05 18:03:07 +01:00
|
|
|
|
2021-12-04 15:40:09 +01:00
|
|
|
PacketHandler.sendToAllAround(this.level, this.worldPosition, 32, new PacketParticles(pos.getX(), pos.getY(), pos.getZ(), PacketParticles.Type.PLACER_PLACING));
|
2018-11-05 18:03:07 +01:00
|
|
|
|
2018-11-05 16:36:10 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-08 00:31:29 +01:00
|
|
|
private boolean framesContain(List<ItemFrame> frames, BlockPos pos, BlockState state) {
|
2021-12-15 16:30:22 +01:00
|
|
|
var stack = state.getBlock().getCloneItemStack(this.level, pos, state);
|
2018-11-05 16:36:10 +01:00
|
|
|
if (stack.isEmpty())
|
|
|
|
return false;
|
|
|
|
|
2021-12-15 16:30:22 +01:00
|
|
|
for (var frame : frames) {
|
|
|
|
var frameStack = frame.getItem();
|
2018-11-09 12:42:08 +01:00
|
|
|
if (frameStack.isEmpty())
|
|
|
|
continue;
|
2018-11-20 11:48:45 +01:00
|
|
|
if (Helper.areItemsEqual(stack, frameStack, false))
|
2018-11-09 12:42:08 +01:00
|
|
|
return true;
|
|
|
|
|
2018-11-20 11:48:45 +01:00
|
|
|
if (state.getBlock() == Blocks.FARMLAND && frameStack.getItem() == ModItems.FARMING_STENCIL)
|
2018-11-05 16:36:10 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private ItemStack tryPlace(ItemStack stack, BlockPos pos) {
|
2021-12-04 15:40:09 +01:00
|
|
|
if (!(this.level instanceof ServerLevel))
|
2018-11-05 16:36:10 +01:00
|
|
|
return stack;
|
2021-12-15 16:30:22 +01:00
|
|
|
var fake = FakePlayerFactory.getMinecraft((ServerLevel) this.level);
|
2021-12-08 00:31:29 +01:00
|
|
|
fake.getInventory().items.set(fake.getInventory().selected, stack);
|
2021-12-15 16:30:22 +01:00
|
|
|
var ray = new BlockHitResult(Vec3.atCenterOf(pos), Direction.UP, pos, false);
|
2021-12-08 00:31:29 +01:00
|
|
|
ForgeHooks.onPlaceItemIntoWorld(new UseOnContext(fake, InteractionHand.MAIN_HAND, ray));
|
|
|
|
return fake.getMainHandItem().copy();
|
2018-11-05 16:36:10 +01:00
|
|
|
}
|
|
|
|
}
|