2018-10-14 14:27:18 +02:00
|
|
|
package de.ellpeck.naturesaura.blocks.tiles;
|
|
|
|
|
2018-11-11 13:26:19 +01:00
|
|
|
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
|
|
|
|
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
|
|
|
|
import de.ellpeck.naturesaura.api.aura.container.BasicAuraContainer;
|
|
|
|
import de.ellpeck.naturesaura.api.aura.container.IAuraContainer;
|
2018-11-12 01:29:33 +01:00
|
|
|
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
|
2020-04-29 16:38:50 +02:00
|
|
|
import de.ellpeck.naturesaura.recipes.AltarRecipe;
|
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;
|
2020-04-29 16:38:50 +02:00
|
|
|
import de.ellpeck.naturesaura.recipes.ModRecipes;
|
2019-10-20 22:30:49 +02:00
|
|
|
import net.minecraft.block.BlockState;
|
2018-10-18 13:34:37 +02:00
|
|
|
import net.minecraft.item.ItemStack;
|
2018-11-20 11:44:07 +01:00
|
|
|
import net.minecraft.item.crafting.Ingredient;
|
2019-10-20 22:30:49 +02:00
|
|
|
import net.minecraft.nbt.CompoundNBT;
|
2020-01-21 21:04:44 +01:00
|
|
|
import net.minecraft.tileentity.ITickableTileEntity;
|
2019-10-20 22:30:49 +02:00
|
|
|
import net.minecraft.util.Direction;
|
2018-10-22 00:14:52 +02:00
|
|
|
import net.minecraft.util.ResourceLocation;
|
2018-10-24 12:42:04 +02:00
|
|
|
import net.minecraft.util.SoundCategory;
|
2020-01-21 21:04:44 +01:00
|
|
|
import net.minecraft.util.SoundEvents;
|
2018-10-14 14:27:18 +02:00
|
|
|
import net.minecraft.util.math.BlockPos;
|
2018-11-22 18:56:01 +01:00
|
|
|
import net.minecraft.util.math.MathHelper;
|
2019-10-20 22:30:49 +02:00
|
|
|
import net.minecraftforge.api.distmarker.Dist;
|
|
|
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
2018-10-18 13:34:37 +02:00
|
|
|
import net.minecraftforge.items.IItemHandlerModifiable;
|
|
|
|
import net.minecraftforge.items.ItemStackHandler;
|
2018-10-14 14:27:18 +02:00
|
|
|
|
|
|
|
import java.util.Random;
|
|
|
|
|
2020-01-21 21:04:44 +01:00
|
|
|
public class TileEntityNatureAltar extends TileEntityImpl implements ITickableTileEntity {
|
2018-10-14 14:27:18 +02:00
|
|
|
|
2020-02-25 22:57:10 +01:00
|
|
|
private final BasicAuraContainer container = new BasicAuraContainer(null, 500000) {
|
|
|
|
@Override
|
|
|
|
public int getAuraColor() {
|
|
|
|
return IAuraType.forWorld(TileEntityNatureAltar.this.world).getColor();
|
|
|
|
}
|
|
|
|
};
|
2020-02-07 15:22:30 +01:00
|
|
|
private final ItemStack[] catalysts = new ItemStack[4];
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected boolean canInsert(ItemStack stack, int slot) {
|
2020-01-21 21:04:44 +01:00
|
|
|
return TileEntityNatureAltar.this.getRecipeForInput(stack) != null || stack.getCapability(NaturesAuraAPI.capAuraContainer, null).isPresent();
|
2018-10-18 13:34:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected boolean canExtract(ItemStack stack, int slot, int amount) {
|
2020-01-21 21:04:44 +01:00
|
|
|
IAuraContainer cap = stack.getCapability(NaturesAuraAPI.capAuraContainer, null).orElse(null);
|
|
|
|
if (cap != null)
|
|
|
|
return cap.storeAura(1, true) <= 0;
|
2018-11-02 20:56:46 +01:00
|
|
|
else
|
2019-02-08 20:10:25 +01:00
|
|
|
return TileEntityNatureAltar.this.getRecipeForInput(stack) == null;
|
2018-10-18 13:34:37 +02:00
|
|
|
}
|
|
|
|
};
|
2019-10-20 22:30:49 +02:00
|
|
|
@OnlyIn(Dist.CLIENT)
|
2018-11-08 22:15:25 +01:00
|
|
|
public int bobTimer;
|
2020-02-25 22:57:10 +01:00
|
|
|
public StructureState structureState = StructureState.INVALID;
|
2018-10-14 14:27:18 +02:00
|
|
|
|
2018-10-18 17:12:20 +02:00
|
|
|
private AltarRecipe currentRecipe;
|
|
|
|
private int timer;
|
|
|
|
|
2018-10-14 14:27:18 +02:00
|
|
|
private int lastAura;
|
2020-02-25 22:57:10 +01:00
|
|
|
private boolean firstTick = true;
|
2018-10-14 14:27:18 +02:00
|
|
|
|
2020-01-22 01:32:26 +01:00
|
|
|
public TileEntityNatureAltar() {
|
|
|
|
super(ModTileEntities.NATURE_ALTAR);
|
2020-01-21 21:04:44 +01:00
|
|
|
}
|
|
|
|
|
2018-10-14 14:27:18 +02:00
|
|
|
@Override
|
2020-01-21 21:04:44 +01:00
|
|
|
public void tick() {
|
2018-10-14 14:27:18 +02:00
|
|
|
Random rand = this.world.rand;
|
|
|
|
|
2020-01-21 21:04:44 +01:00
|
|
|
if (this.world.getGameTime() % 40 == 0) {
|
2019-02-13 11:11:21 +01:00
|
|
|
int index = 0;
|
|
|
|
for (int x = -2; x <= 2; x += 4) {
|
|
|
|
for (int z = -2; z <= 2; z += 4) {
|
|
|
|
BlockPos offset = this.pos.add(x, 1, z);
|
2019-10-20 22:30:49 +02:00
|
|
|
BlockState state = this.world.getBlockState(offset);
|
2019-02-13 11:11:21 +01:00
|
|
|
this.catalysts[index] = state.getBlock().getItem(this.world, offset, state);
|
|
|
|
index++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-14 14:27:18 +02:00
|
|
|
if (!this.world.isRemote) {
|
2020-02-25 22:57:10 +01:00
|
|
|
if (this.world.getGameTime() % 40 == 0 || this.firstTick) {
|
|
|
|
StructureState newState = this.getNewState();
|
|
|
|
if (newState != this.structureState) {
|
|
|
|
this.structureState = newState;
|
2018-10-14 14:27:18 +02:00
|
|
|
this.sendToClients();
|
|
|
|
}
|
2020-02-25 22:57:10 +01:00
|
|
|
this.firstTick = false;
|
2018-10-14 14:27:18 +02:00
|
|
|
}
|
|
|
|
|
2020-02-25 22:57:10 +01:00
|
|
|
if (this.structureState != StructureState.INVALID) {
|
2019-01-29 11:46:38 +01:00
|
|
|
int space = this.container.storeAura(300, true);
|
2020-02-25 22:57:10 +01:00
|
|
|
IAuraType expectedType = this.structureState == StructureState.NETHER ? NaturesAuraAPI.TYPE_NETHER : NaturesAuraAPI.TYPE_OVERWORLD;
|
2020-02-25 23:14:19 +01:00
|
|
|
if (space > 0 && IAuraType.forWorld(this.world).isSimilar(expectedType)) {
|
2018-11-11 13:26:19 +01:00
|
|
|
int toStore = Math.min(IAuraChunk.getAuraInArea(this.world, this.pos, 20), space);
|
2018-10-21 12:51:13 +02:00
|
|
|
if (toStore > 0) {
|
2018-11-11 13:26:19 +01:00
|
|
|
BlockPos spot = IAuraChunk.getHighestSpot(this.world, this.pos, 20, this.pos);
|
|
|
|
IAuraChunk chunk = IAuraChunk.getAuraChunk(this.world, spot);
|
2018-10-14 14:27:18 +02:00
|
|
|
|
2018-10-21 12:51:13 +02:00
|
|
|
chunk.drainAura(spot, toStore);
|
|
|
|
this.container.storeAura(toStore, false);
|
2018-10-14 14:27:18 +02:00
|
|
|
|
2020-01-22 23:21:52 +01:00
|
|
|
if (this.world.getGameTime() % 3 == 0)
|
2018-10-16 01:36:30 +02:00
|
|
|
PacketHandler.sendToAllAround(this.world, this.pos, 32, new PacketParticleStream(
|
2018-10-21 12:51:13 +02:00
|
|
|
this.pos.getX() + (float) rand.nextGaussian() * 10F,
|
|
|
|
this.pos.getY() + rand.nextFloat() * 10F,
|
|
|
|
this.pos.getZ() + (float) rand.nextGaussian() * 10F,
|
2018-10-14 14:27:18 +02:00
|
|
|
this.pos.getX() + 0.5F, this.pos.getY() + 0.5F, this.pos.getZ() + 0.5F,
|
2020-02-25 22:57:10 +01:00
|
|
|
rand.nextFloat() * 0.1F + 0.1F, this.container.getAuraColor(), rand.nextFloat() * 1F + 1F
|
2020-01-22 23:21:52 +01:00
|
|
|
));
|
2018-10-14 14:27:18 +02:00
|
|
|
}
|
|
|
|
}
|
2018-10-18 17:12:20 +02:00
|
|
|
|
|
|
|
ItemStack stack = this.items.getStackInSlot(0);
|
2020-01-21 21:04:44 +01:00
|
|
|
IAuraContainer container = stack.getCapability(NaturesAuraAPI.capAuraContainer, null).orElse(null);
|
|
|
|
if (!stack.isEmpty() && container != null) {
|
2019-01-29 16:01:10 +01:00
|
|
|
int theoreticalDrain = this.container.drainAura(1000, true);
|
2018-10-20 21:19:08 +02:00
|
|
|
if (theoreticalDrain > 0) {
|
|
|
|
int stored = container.storeAura(theoreticalDrain, false);
|
|
|
|
if (stored > 0) {
|
|
|
|
this.container.drainAura(stored, false);
|
2018-10-18 17:12:20 +02:00
|
|
|
|
2020-01-22 23:21:52 +01:00
|
|
|
if (this.world.getGameTime() % 4 == 0)
|
2020-02-25 22:57:10 +01:00
|
|
|
PacketHandler.sendToAllAround(this.world, this.pos, 32, new PacketParticles(this.pos.getX(), this.pos.getY(), this.pos.getZ(), PacketParticles.Type.ALTAR_CONVERSION, this.container.getAuraColor()));
|
2018-10-20 21:19:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (this.currentRecipe == null) {
|
|
|
|
if (!stack.isEmpty()) {
|
2019-02-08 20:10:25 +01:00
|
|
|
this.currentRecipe = this.getRecipeForInput(stack);
|
2018-10-20 21:19:08 +02:00
|
|
|
}
|
|
|
|
} else {
|
2020-01-21 21:04:44 +01:00
|
|
|
if (stack.isEmpty() || !this.currentRecipe.input.test(stack)) {
|
2018-10-20 21:19:08 +02:00
|
|
|
this.currentRecipe = null;
|
2018-10-22 11:23:48 +02:00
|
|
|
this.timer = 0;
|
2019-02-08 20:10:25 +01:00
|
|
|
} else {
|
2018-11-22 18:56:01 +01:00
|
|
|
int req = MathHelper.ceil(this.currentRecipe.aura / (double) this.currentRecipe.time);
|
2018-10-20 21:19:08 +02:00
|
|
|
if (this.container.getStoredAura() >= req) {
|
|
|
|
this.container.drainAura(req, false);
|
|
|
|
|
2020-01-22 23:21:52 +01:00
|
|
|
if (this.timer % 4 == 0)
|
2020-02-25 22:57:10 +01:00
|
|
|
PacketHandler.sendToAllAround(this.world, this.pos, 32, new PacketParticles(this.pos.getX(), this.pos.getY(), this.pos.getZ(), PacketParticles.Type.ALTAR_CONVERSION, this.container.getAuraColor()));
|
2018-10-20 21:19:08 +02:00
|
|
|
|
|
|
|
this.timer++;
|
|
|
|
if (this.timer >= this.currentRecipe.time) {
|
|
|
|
this.items.setStackInSlot(0, this.currentRecipe.output.copy());
|
|
|
|
this.currentRecipe = null;
|
|
|
|
this.timer = 0;
|
2018-10-24 12:42:04 +02:00
|
|
|
|
|
|
|
this.world.playSound(null, this.pos.getX() + 0.5, this.pos.getY() + 0.5, this.pos.getZ() + 0.5,
|
|
|
|
SoundEvents.ENTITY_ARROW_HIT_PLAYER, SoundCategory.BLOCKS, 0.65F, 1F);
|
2018-10-20 21:19:08 +02:00
|
|
|
}
|
2018-10-18 17:12:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-10-14 14:27:18 +02:00
|
|
|
}
|
|
|
|
|
2020-01-21 21:04:44 +01:00
|
|
|
if (this.world.getGameTime() % 10 == 0 && this.lastAura != this.container.getStoredAura()) {
|
2018-10-14 14:27:18 +02:00
|
|
|
this.lastAura = this.container.getStoredAura();
|
|
|
|
this.sendToClients();
|
|
|
|
}
|
|
|
|
} else {
|
2020-02-25 22:57:10 +01:00
|
|
|
if (this.structureState != StructureState.INVALID) {
|
2018-10-14 14:27:18 +02:00
|
|
|
if (rand.nextFloat() >= 0.7F) {
|
|
|
|
int fourths = this.container.getMaxAura() / 4;
|
|
|
|
if (this.container.getStoredAura() > 0) {
|
2018-11-13 00:36:47 +01:00
|
|
|
NaturesAuraAPI.instance().spawnMagicParticle(
|
2018-10-14 14:27:18 +02:00
|
|
|
this.pos.getX() - 4F + rand.nextFloat(), this.pos.getY() + 3F, this.pos.getZ() + rand.nextFloat(),
|
2018-11-04 18:42:35 +01:00
|
|
|
0F, 0F, 0F, this.container.getAuraColor(), rand.nextFloat() * 3F + 1F, rand.nextInt(100) + 50, -0.05F, true, true);
|
2018-10-14 14:27:18 +02:00
|
|
|
}
|
|
|
|
if (this.container.getStoredAura() >= fourths) {
|
2018-11-13 00:36:47 +01:00
|
|
|
NaturesAuraAPI.instance().spawnMagicParticle(
|
2018-10-14 14:27:18 +02:00
|
|
|
this.pos.getX() + 4F + rand.nextFloat(), this.pos.getY() + 3F, this.pos.getZ() + rand.nextFloat(),
|
2018-11-04 18:42:35 +01:00
|
|
|
0F, 0F, 0F, this.container.getAuraColor(), rand.nextFloat() * 3F + 1F, rand.nextInt(100) + 50, -0.05F, true, true);
|
2018-10-14 14:27:18 +02:00
|
|
|
}
|
|
|
|
if (this.container.getStoredAura() >= fourths * 2) {
|
2018-11-13 00:36:47 +01:00
|
|
|
NaturesAuraAPI.instance().spawnMagicParticle(
|
2018-10-14 14:27:18 +02:00
|
|
|
this.pos.getX() + rand.nextFloat(), this.pos.getY() + 3F, this.pos.getZ() - 4F + rand.nextFloat(),
|
2018-11-04 18:42:35 +01:00
|
|
|
0F, 0F, 0F, this.container.getAuraColor(), rand.nextFloat() * 3F + 1F, rand.nextInt(100) + 50, -0.05F, true, true);
|
2018-10-14 14:27:18 +02:00
|
|
|
}
|
|
|
|
if (this.container.getStoredAura() >= fourths * 3) {
|
2018-11-13 00:36:47 +01:00
|
|
|
NaturesAuraAPI.instance().spawnMagicParticle(
|
2018-10-14 14:27:18 +02:00
|
|
|
this.pos.getX() + rand.nextFloat(), this.pos.getY() + 3F, this.pos.getZ() + 4F + rand.nextFloat(),
|
2018-11-04 18:42:35 +01:00
|
|
|
0F, 0F, 0F, this.container.getAuraColor(), rand.nextFloat() * 3F + 1F, rand.nextInt(100) + 50, -0.05F, true, true);
|
2018-10-14 14:27:18 +02:00
|
|
|
}
|
2018-10-14 16:12:33 +02:00
|
|
|
|
2018-10-14 14:27:18 +02:00
|
|
|
}
|
|
|
|
}
|
2018-11-08 22:15:25 +01:00
|
|
|
|
|
|
|
this.bobTimer++;
|
2018-10-14 14:27:18 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-08 20:10:25 +01:00
|
|
|
private AltarRecipe getRecipeForInput(ItemStack input) {
|
2020-02-25 23:14:19 +01:00
|
|
|
IAuraType type = IAuraType.forWorld(this.world);
|
2020-04-29 16:38:50 +02:00
|
|
|
for (AltarRecipe recipe : this.world.getRecipeManager().getRecipes(ModRecipes.ALTAR_TYPE, null, null)) {
|
2020-02-25 23:14:19 +01:00
|
|
|
if (recipe.input.test(input) && (recipe.requiredType == null || type.isSimilar(recipe.requiredType))) {
|
2019-02-08 20:10:25 +01:00
|
|
|
if (recipe.catalyst == Ingredient.EMPTY)
|
|
|
|
return recipe;
|
|
|
|
for (ItemStack stack : this.catalysts)
|
2020-01-21 21:04:44 +01:00
|
|
|
if (recipe.catalyst.test(stack))
|
2019-02-08 20:10:25 +01:00
|
|
|
return recipe;
|
2018-11-11 13:26:19 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2020-02-25 22:57:10 +01:00
|
|
|
private StructureState getNewState() {
|
|
|
|
if (Multiblocks.ALTAR.isComplete(this.world, this.pos))
|
|
|
|
return StructureState.OVERWORLD;
|
|
|
|
if (Multiblocks.NETHER_ALTAR.isComplete(this.world, this.pos))
|
|
|
|
return StructureState.NETHER;
|
|
|
|
return StructureState.INVALID;
|
|
|
|
}
|
|
|
|
|
2018-10-14 14:27:18 +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());
|
2020-02-25 22:57:10 +01:00
|
|
|
compound.putString("state", this.structureState.name());
|
2018-11-05 16:36:10 +01:00
|
|
|
this.container.writeNBT(compound);
|
|
|
|
}
|
2018-11-04 16:38:09 +01:00
|
|
|
if (type == SaveType.TILE) {
|
2018-10-18 17:12:20 +02:00
|
|
|
if (this.currentRecipe != null) {
|
2020-01-21 21:04:44 +01:00
|
|
|
compound.putString("recipe", this.currentRecipe.name.toString());
|
|
|
|
compound.putInt("timer", this.timer);
|
2018-10-18 17:12:20 +02:00
|
|
|
}
|
|
|
|
}
|
2018-10-14 14:27:18 +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"));
|
2020-02-25 22:57:10 +01:00
|
|
|
if (compound.contains("state"))
|
|
|
|
this.structureState = StructureState.valueOf(compound.getString("state"));
|
2018-11-05 16:36:10 +01:00
|
|
|
this.container.readNBT(compound);
|
|
|
|
}
|
2018-11-04 16:38:09 +01:00
|
|
|
if (type == SaveType.TILE) {
|
2020-01-21 21:04:44 +01:00
|
|
|
if (compound.contains("recipe")) {
|
2020-04-29 16:38:50 +02:00
|
|
|
if (this.hasWorld())
|
|
|
|
this.currentRecipe = (AltarRecipe) this.world.getRecipeManager().getRecipe(new ResourceLocation(compound.getString("recipe"))).orElse(null);
|
2020-01-21 21:04:44 +01:00
|
|
|
this.timer = compound.getInt("timer");
|
2018-10-18 17:12:20 +02:00
|
|
|
}
|
|
|
|
}
|
2018-10-14 14:27:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2019-10-20 22:30:49 +02:00
|
|
|
public IAuraContainer getAuraContainer(Direction facing) {
|
2018-10-14 14:27:18 +02:00
|
|
|
return this.container;
|
|
|
|
}
|
2018-10-14 17:46:00 +02:00
|
|
|
|
2018-10-18 13:34:37 +02:00
|
|
|
@Override
|
2019-10-20 22:30:49 +02:00
|
|
|
public IItemHandlerModifiable getItemHandler(Direction facing) {
|
2018-10-18 13:34:37 +02:00
|
|
|
return this.items;
|
|
|
|
}
|
2020-02-25 22:57:10 +01:00
|
|
|
|
|
|
|
public enum StructureState {
|
|
|
|
INVALID,
|
|
|
|
NETHER,
|
|
|
|
OVERWORLD
|
|
|
|
}
|
2018-10-14 14:27:18 +02:00
|
|
|
}
|