NaturesAura/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityWoodStand.java

225 lines
10 KiB
Java
Raw Normal View History

2018-10-16 11:49:30 +02:00
package de.ellpeck.naturesaura.blocks.tiles;
2018-11-07 13:33:49 +01:00
import de.ellpeck.naturesaura.blocks.multi.Multiblocks;
2020-01-22 23:21:52 +01:00
import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticleStream;
import de.ellpeck.naturesaura.packet.PacketParticles;
2021-01-14 23:15:02 +01:00
import de.ellpeck.naturesaura.recipes.TreeRitualRecipe;
2020-01-21 21:04:44 +01:00
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
2019-10-20 22:30:49 +02:00
import net.minecraft.block.LeavesBlock;
import net.minecraft.entity.item.ItemEntity;
2018-10-16 11:49:30 +02:00
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.Ingredient;
2019-10-20 22:30:49 +02:00
import net.minecraft.nbt.CompoundNBT;
2020-09-22 03:17:02 +02:00
import net.minecraft.tags.BlockTags;
2020-01-21 21:04:44 +01:00
import net.minecraft.tileentity.ITickableTileEntity;
2018-10-16 18:07:03 +02:00
import net.minecraft.tileentity.TileEntity;
2018-11-07 13:33:49 +01:00
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundCategory;
2020-01-21 21:04:44 +01:00
import net.minecraft.util.SoundEvents;
2018-10-16 11:49:30 +02:00
import net.minecraft.util.math.BlockPos;
2020-05-13 17:57:31 +02:00
import net.minecraft.world.World;
2018-10-18 13:34:37 +02:00
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.ItemStackHandler;
2018-10-16 11:49:30 +02:00
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
2018-10-16 11:49:30 +02:00
2020-01-21 21:04:44 +01:00
public class TileEntityWoodStand extends TileEntityImpl implements ITickableTileEntity {
2018-10-16 11:49:30 +02:00
2018-10-18 13:34:37 +02:00
public final ItemStackHandler items = new ItemStackHandlerNA(1, this, true) {
@Override
public int getSlotLimit(int slot) {
return 1;
}
};
2018-10-16 11:49:30 +02:00
private TreeRitualRecipe recipe;
2018-10-16 11:49:30 +02:00
private BlockPos ritualPos;
private int timer;
2020-01-22 01:32:26 +01:00
public TileEntityWoodStand() {
super(ModTileEntities.WOOD_STAND);
2020-01-21 21:04:44 +01:00
}
public void setRitual(BlockPos pos, TreeRitualRecipe recipe) {
2018-10-16 11:49:30 +02:00
this.ritualPos = pos;
this.recipe = recipe;
2018-10-16 11:49:30 +02:00
}
@Override
2020-01-21 21:04:44 +01:00
public void tick() {
2018-10-16 11:49:30 +02:00
if (!this.world.isRemote) {
if (this.ritualPos != null && this.recipe != null) {
2020-01-21 21:04:44 +01:00
if (this.world.getGameTime() % 5 == 0) {
if (this.isRitualOkay()) {
boolean wasOverHalf = this.timer >= this.recipe.time / 2;
this.timer += 5;
boolean isOverHalf = this.timer >= this.recipe.time / 2;
if (!isOverHalf)
2018-11-07 13:33:49 +01:00
Multiblocks.TREE_RITUAL.forEach(this.ritualPos, 'W', (pos, matcher) -> {
TileEntity tile = this.world.getTileEntity(pos);
if (tile instanceof TileEntityWoodStand && !((TileEntityWoodStand) tile).items.getStackInSlot(0).isEmpty()) {
2020-01-22 23:21:52 +01:00
PacketHandler.sendToAllAround(this.world, this.pos, 32, new PacketParticleStream(
(float) pos.getX() + 0.2F + this.world.rand.nextFloat() * 0.6F,
(float) pos.getY() + 0.85F,
(float) pos.getZ() + 0.2F + this.world.rand.nextFloat() * 0.6F,
this.ritualPos.getX() + 0.5F, this.ritualPos.getY() + this.world.rand.nextFloat() * 3F + 2F, this.ritualPos.getZ() + 0.5F,
this.world.rand.nextFloat() * 0.04F + 0.04F, 0x89cc37, this.world.rand.nextFloat() * 1F + 1F
2020-01-22 23:21:52 +01:00
));
}
2018-11-07 13:33:49 +01:00
return true;
});
2020-01-22 23:21:52 +01:00
PacketHandler.sendToAllAround(this.world, this.ritualPos, 32,
2020-01-26 00:16:06 +01:00
new PacketParticles(this.ritualPos.getX(), this.ritualPos.getY(), this.ritualPos.getZ(), PacketParticles.Type.TR_GOLD_POWDER));
2018-10-16 11:49:30 +02:00
if (this.timer >= this.recipe.time) {
2020-05-13 17:57:31 +02:00
recurseTreeDestruction(this.world, this.ritualPos, this.ritualPos, true, false);
2018-11-07 13:33:49 +01:00
Multiblocks.TREE_RITUAL.forEach(this.ritualPos, 'G', (pos, matcher) -> {
2020-01-21 21:04:44 +01:00
this.world.setBlockState(pos, Blocks.AIR.getDefaultState());
2018-11-07 13:33:49 +01:00
return true;
});
2019-10-20 22:30:49 +02:00
ItemEntity item = new ItemEntity(this.world,
this.ritualPos.getX() + 0.5, this.ritualPos.getY() + 4.5, this.ritualPos.getZ() + 0.5,
this.recipe.result.copy());
2020-01-21 21:04:44 +01:00
this.world.addEntity(item);
2020-01-22 23:21:52 +01:00
PacketHandler.sendToAllAround(this.world, this.pos, 32,
2020-01-28 18:08:56 +01:00
new PacketParticles((float) item.getPosX(), (float) item.getPosY(), (float) item.getPosZ(), PacketParticles.Type.TR_SPAWN_RESULT));
this.world.playSound(null, this.pos.getX() + 0.5, this.pos.getY() + 0.5, this.pos.getZ() + 0.5,
2020-01-21 21:04:44 +01:00
SoundEvents.ENTITY_ENDERMAN_TELEPORT, SoundCategory.BLOCKS, 0.65F, 1F);
this.ritualPos = null;
this.recipe = null;
this.timer = 0;
} else if (isOverHalf && !wasOverHalf) {
2018-11-07 13:33:49 +01:00
Multiblocks.TREE_RITUAL.forEach(this.ritualPos, 'W', (pos, matcher) -> {
TileEntity tile = this.world.getTileEntity(pos);
if (tile instanceof TileEntityWoodStand) {
TileEntityWoodStand stand = (TileEntityWoodStand) tile;
if (!stand.items.getStackInSlot(0).isEmpty()) {
2020-01-22 23:21:52 +01:00
PacketHandler.sendToAllAround(this.world, this.pos, 32,
2020-01-26 00:16:06 +01:00
new PacketParticles(stand.pos.getX(), stand.pos.getY(), stand.pos.getZ(), PacketParticles.Type.TR_CONSUME_ITEM));
this.world.playSound(null, stand.pos.getX() + 0.5, stand.pos.getY() + 0.5, stand.pos.getZ() + 0.5,
SoundEvents.BLOCK_WOOD_STEP, SoundCategory.BLOCKS, 0.5F, 1F);
stand.items.setStackInSlot(0, ItemStack.EMPTY);
stand.sendToClients();
}
}
2018-11-07 13:33:49 +01:00
return true;
});
2018-10-16 17:48:36 +02:00
}
} else {
2018-10-16 11:49:30 +02:00
this.ritualPos = null;
this.recipe = null;
2018-10-16 11:49:30 +02:00
this.timer = 0;
}
}
}
}
2018-10-16 11:49:30 +02:00
}
2020-05-13 17:57:31 +02:00
public static void recurseTreeDestruction(World world, BlockPos pos, BlockPos start, boolean includeLeaves, boolean drop) {
2018-10-16 21:10:38 +02:00
if (Math.abs(pos.getX() - start.getX()) >= 6
|| Math.abs(pos.getZ() - start.getZ()) >= 6
2020-05-13 17:57:31 +02:00
|| Math.abs(pos.getY() - start.getY()) >= 32) {
2018-10-16 11:49:30 +02:00
return;
}
for (int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) {
for (int z = -1; z <= 1; z++) {
BlockPos offset = pos.add(x, y, z);
2020-05-13 17:57:31 +02:00
BlockState state = world.getBlockState(offset);
2020-09-22 03:17:02 +02:00
if (state.getBlock().getTags().contains(BlockTags.LOGS.getName()) || includeLeaves && state.getBlock() instanceof LeavesBlock) {
2020-05-13 17:57:31 +02:00
if (drop) {
world.destroyBlock(offset, true);
} else {
// in this case we don't want the particles, so we can't use destroyBlock
world.setBlockState(offset, Blocks.AIR.getDefaultState());
PacketHandler.sendToAllAround(world, pos, 32, new PacketParticles(offset.getX(), offset.getY(), offset.getZ(), PacketParticles.Type.TR_DISAPPEAR));
}
recurseTreeDestruction(world, offset, start, includeLeaves, drop);
}
}
2018-10-16 11:49:30 +02:00
}
}
}
2018-10-17 15:02:29 +02:00
private boolean isRitualOkay() {
2018-11-07 13:33:49 +01:00
if (!Multiblocks.TREE_RITUAL.isComplete(this.world, this.ritualPos)) {
return false;
2018-10-16 11:49:30 +02:00
}
for (int i = 0; i < 2; i++) {
2019-10-20 22:30:49 +02:00
BlockState state = this.world.getBlockState(this.ritualPos.up(i));
2020-09-22 03:17:02 +02:00
if (!(state.getBlock().getTags().contains(BlockTags.LOGS.getName())))
return false;
}
if (this.timer < this.recipe.time / 2) {
List<Ingredient> required = new ArrayList<>(Arrays.asList(this.recipe.ingredients));
2018-11-07 13:33:49 +01:00
boolean fine = Multiblocks.TREE_RITUAL.forEach(this.ritualPos, 'W', (pos, matcher) -> {
TileEntity tile = this.world.getTileEntity(pos);
if (tile instanceof TileEntityWoodStand) {
ItemStack stack = ((TileEntityWoodStand) tile).items.getStackInSlot(0);
if (!stack.isEmpty()) {
for (int i = required.size() - 1; i >= 0; i--) {
Ingredient req = required.get(i);
2020-01-21 21:04:44 +01:00
if (req.test(stack)) {
required.remove(i);
return true;
}
}
return false;
}
}
2018-11-07 13:33:49 +01:00
return true;
});
2018-11-07 13:33:49 +01:00
return fine && required.isEmpty();
} else
return true;
2018-10-16 11:49:30 +02:00
}
@Override
2019-10-20 22:30:49 +02:00
public void writeNBT(CompoundNBT compound, SaveType type) {
2018-11-04 16:38:09 +01:00
super.writeNBT(compound, type);
2018-11-05 16:36:10 +01:00
if (type != SaveType.BLOCK)
2020-01-21 21:04:44 +01:00
compound.put("items", this.items.serializeNBT());
2018-10-16 18:07:03 +02:00
2018-11-04 16:38:09 +01:00
if (type == SaveType.TILE) {
if (this.ritualPos != null && this.recipe != null) {
2020-01-21 21:04:44 +01:00
compound.putLong("ritual_pos", this.ritualPos.toLong());
compound.putInt("timer", this.timer);
compound.putString("recipe", this.recipe.name.toString());
2018-10-16 18:07:03 +02:00
}
}
2018-10-16 11:49:30 +02:00
}
@Override
2019-10-20 22:30:49 +02:00
public void readNBT(CompoundNBT compound, SaveType type) {
2018-11-04 16:38:09 +01:00
super.readNBT(compound, type);
2018-11-05 16:36:10 +01:00
if (type != SaveType.BLOCK)
2020-01-21 21:04:44 +01:00
this.items.deserializeNBT(compound.getCompound("items"));
2018-10-16 18:07:03 +02:00
2018-11-04 16:38:09 +01:00
if (type == SaveType.TILE) {
2020-01-21 21:04:44 +01:00
if (compound.contains("recipe")) {
2018-10-16 18:08:32 +02:00
this.ritualPos = BlockPos.fromLong(compound.getLong("ritual_pos"));
2020-01-21 21:04:44 +01:00
this.timer = compound.getInt("timer");
2020-04-29 16:38:50 +02:00
if (this.hasWorld())
this.recipe = (TreeRitualRecipe) this.world.getRecipeManager().getRecipe(new ResourceLocation(compound.getString("recipe"))).orElse(null);
2018-10-16 18:07:03 +02:00
}
}
2018-10-16 11:49:30 +02:00
}
2018-10-18 13:34:37 +02:00
@Override
2020-10-19 21:26:32 +02:00
public IItemHandlerModifiable getItemHandler() {
2018-10-18 13:34:37 +02:00
return this.items;
}
2018-10-16 11:49:30 +02:00
}