package de.ellpeck.naturesaura.blocks.tiles; import de.ellpeck.naturesaura.Helper; import de.ellpeck.naturesaura.blocks.multi.Multiblocks; import de.ellpeck.naturesaura.packet.PacketHandler; import de.ellpeck.naturesaura.packet.PacketParticles; import de.ellpeck.naturesaura.recipes.ModRecipes; import de.ellpeck.naturesaura.recipes.OfferingRecipe; import net.minecraft.block.Blocks; import net.minecraft.entity.EntityType; import net.minecraft.entity.effect.LightningBoltEntity; import net.minecraft.entity.item.ItemEntity; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.INBT; import net.minecraft.nbt.ListNBT; import net.minecraft.tileentity.ITickableBlockEntity; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.vector.Vector3d; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemStackHandler; import java.util.ArrayDeque; import java.util.List; import java.util.Queue; public class BlockEntityOfferingTable extends BlockEntityImpl implements ITickableBlockEntity { public final ItemStackHandler items = new ItemStackHandlerNA(1, this, true) { @Override public int getSlotLimit(int slot) { return 16; } }; private final Queue itemsToSpawn = new ArrayDeque<>(); public BlockEntityOfferingTable() { super(ModTileEntities.OFFERING_TABLE); } private OfferingRecipe getRecipe(ItemStack input) { for (OfferingRecipe recipe : this.level.getRecipeManager().getRecipes(ModRecipes.OFFERING_TYPE, null, null)) if (recipe.input.test(input)) return recipe; return null; } @Override public void tick() { if (!this.level.isClientSide) { if (this.level.getGameTime() % 20 == 0) { if (!Multiblocks.OFFERING_TABLE.isComplete(this.level, this.worldPosition)) return; ItemStack stack = this.items.getStackInSlot(0); if (stack.isEmpty()) return; List items = this.level.getEntitiesWithinAABB(ItemEntity.class, new AxisAlignedBB(this.worldPosition).grow(1)); if (items.isEmpty()) return; OfferingRecipe recipe = this.getRecipe(stack); if (recipe == null) return; for (ItemEntity item : items) { if (!item.isAlive() || item.cannotPickup()) continue; ItemStack itemStack = item.getItem(); if (itemStack.isEmpty() || itemStack.getCount() != 1) continue; if (!recipe.startItem.test(itemStack)) continue; int amount = Helper.getIngredientAmount(recipe.input); int recipeCount = stack.getCount() / amount; stack.shrink(recipeCount * amount); item.remove(); this.sendToClients(); for (int i = 0; i < recipeCount; i++) this.itemsToSpawn.add(recipe.output.copy()); if (Multiblocks.OFFERING_TABLE.forEach(this.worldPosition, 'R', (pos, m) -> this.level.getBlockState(pos).getBlock() == Blocks.WITHER_ROSE)) { for (int i = this.level.rand.nextInt(5) + 3; i >= 0; i--) this.itemsToSpawn.add(new ItemStack(Items.BLACK_DYE)); } LightningBoltEntity lightningboltentity = EntityType.LIGHTNING_BOLT.create(this.level); lightningboltentity.setEffectOnly(true); lightningboltentity.moveForced(Vector3d.copyCenteredHorizontally(this.worldPosition)); this.level.addEntity(lightningboltentity); PacketHandler.sendToAllAround(this.level, this.worldPosition, 32, new PacketParticles( (float) item.getPosX(), (float) item.getPosY(), (float) item.getPosZ(), PacketParticles.Type.OFFERING_TABLE, this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ())); break; } } else if (this.level.getGameTime() % 3 == 0) { if (!this.itemsToSpawn.isEmpty()) this.level.addEntity(new ItemEntity( this.level, this.worldPosition.getX() + 0.5F, 256, this.worldPosition.getZ() + 0.5F, this.itemsToSpawn.remove())); } } } @Override public void writeNBT(CompoundTag compound, SaveType type) { super.writeNBT(compound, type); if (type != SaveType.BLOCK) { compound.put("items", this.items.serializeNBT()); if (type != SaveType.SYNC) { ListNBT list = new ListNBT(); for (ItemStack stack : this.itemsToSpawn) { list.add(stack.serializeNBT()); } compound.put("items_to_spawn", list); } } } @Override public void readNBT(CompoundTag compound, SaveType type) { super.readNBT(compound, type); if (type != SaveType.BLOCK) { this.items.deserializeNBT(compound.getCompound("items")); if (type != SaveType.SYNC) { this.itemsToSpawn.clear(); ListNBT list = compound.getList("items_to_spawn", 10); for (INBT base : list) { this.itemsToSpawn.add(ItemStack.read((CompoundTag) base)); } } } } @Override public IItemHandlerModifiable getItemHandler() { return this.items; } }