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

257 lines
12 KiB
Java
Raw Normal View History

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;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
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.AltarRecipe;
2020-04-29 16:38:50 +02:00
import de.ellpeck.naturesaura.recipes.ModRecipes;
2021-12-08 00:31:29 +01:00
import net.minecraft.core.BlockPos;
2021-12-04 15:40:09 +01:00
import net.minecraft.nbt.CompoundTag;
2021-12-08 00:31:29 +01:00
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.level.block.state.BlockState;
2024-02-03 14:56:07 +01:00
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.neoforge.items.IItemHandlerModifiable;
import net.neoforged.neoforge.items.ItemStackHandler;
2018-10-14 14:27:18 +02:00
2021-12-04 15:40:09 +01:00
public class BlockEntityNatureAltar extends BlockEntityImpl implements ITickableBlockEntity {
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() {
2021-12-04 15:40:09 +01:00
return IAuraType.forLevel(BlockEntityNatureAltar.this.level).getColor();
2020-02-25 22:57:10 +01:00
}
};
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) {
2021-12-23 13:27:52 +01:00
return BlockEntityNatureAltar.this.getRecipeForInput(stack) != null || stack.getCapability(NaturesAuraAPI.CAP_AURA_CONTAINER, null).isPresent();
2018-10-18 13:34:37 +02:00
}
@Override
protected boolean canExtract(ItemStack stack, int slot, int amount) {
2021-12-23 13:27:52 +01:00
var cap = stack.getCapability(NaturesAuraAPI.CAP_AURA_CONTAINER, null).orElse(null);
if (cap != null) {
2020-01-21 21:04:44 +01:00
return cap.storeAura(1, true) <= 0;
} else {
2021-12-04 15:40:09 +01:00
return BlockEntityNatureAltar.this.getRecipeForInput(stack) == null;
}
2018-10-18 13:34:37 +02:00
}
};
2019-10-20 22:30:49 +02:00
@OnlyIn(Dist.CLIENT)
public int bobTimer;
public boolean isComplete;
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
2021-12-08 00:31:29 +01:00
public BlockEntityNatureAltar(BlockPos pos, BlockState state) {
2021-12-19 15:32:45 +01:00
super(ModBlockEntities.NATURE_ALTAR, pos, state);
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() {
2021-12-15 16:24:53 +01:00
var rand = this.level.random;
2018-10-14 14:27:18 +02:00
2021-12-04 15:40:09 +01:00
if (this.level.getGameTime() % 40 == 0) {
2021-12-15 16:24:53 +01:00
var index = 0;
for (var x = -2; x <= 2; x += 4) {
for (var z = -2; z <= 2; z += 4) {
var offset = this.worldPosition.offset(x, 1, z);
var state = this.level.getBlockState(offset);
2023-02-15 23:45:50 +01:00
this.catalysts[index] = new ItemStack(state.getBlock());
index++;
}
}
}
2021-12-04 15:40:09 +01:00
if (!this.level.isClientSide) {
if (this.level.getGameTime() % 40 == 0 || this.firstTick) {
var complete = Multiblocks.ALTAR.isComplete(this.level, this.worldPosition);
if (complete != this.isComplete) {
this.isComplete = complete;
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
}
if (this.isComplete) {
var type = IAuraType.forLevel(this.level);
2021-12-15 16:24:53 +01:00
var space = this.container.storeAura(300, true);
if (space > 0 && (type.isSimilar(NaturesAuraAPI.TYPE_OVERWORLD) || type.isSimilar(NaturesAuraAPI.TYPE_NETHER))) {
2021-12-15 16:24:53 +01:00
var toStore = Math.min(IAuraChunk.getAuraInArea(this.level, this.worldPosition, 20), space);
if (toStore > 0) {
2021-12-15 16:24:53 +01:00
var spot = IAuraChunk.getHighestSpot(this.level, this.worldPosition, 20, this.worldPosition);
var chunk = IAuraChunk.getAuraChunk(this.level, spot);
2018-10-14 14:27:18 +02:00
chunk.drainAura(spot, toStore);
this.container.storeAura(toStore, false);
2018-10-14 14:27:18 +02:00
2021-12-04 15:40:09 +01:00
if (this.level.getGameTime() % 3 == 0)
PacketHandler.sendToAllAround(this.level, this.worldPosition, 32, new PacketParticleStream(
this.worldPosition.getX() + (float) rand.nextGaussian() * 10F,
this.worldPosition.getY() + rand.nextFloat() * 10F,
this.worldPosition.getZ() + (float) rand.nextGaussian() * 10F,
this.worldPosition.getX() + 0.5F, this.worldPosition.getY() + 0.5F, this.worldPosition.getZ() + 0.5F,
2021-12-15 16:24:53 +01:00
rand.nextFloat() * 0.1F + 0.1F, this.container.getAuraColor(), rand.nextFloat() + 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
2021-12-15 16:24:53 +01:00
var stack = this.items.getStackInSlot(0);
2021-12-23 13:27:52 +01:00
var container = stack.getCapability(NaturesAuraAPI.CAP_AURA_CONTAINER, null).orElse(null);
2020-01-21 21:04:44 +01:00
if (!stack.isEmpty() && container != null) {
2021-12-15 16:24:53 +01:00
var theoreticalDrain = this.container.drainAura(1000, true);
2018-10-20 21:19:08 +02:00
if (theoreticalDrain > 0) {
2021-12-15 16:24:53 +01:00
var stored = container.storeAura(theoreticalDrain, false);
2018-10-20 21:19:08 +02:00
if (stored > 0) {
this.container.drainAura(stored, false);
2018-10-18 17:12:20 +02:00
2021-12-04 15:40:09 +01:00
if (this.level.getGameTime() % 4 == 0)
PacketHandler.sendToAllAround(this.level, this.worldPosition, 32, new PacketParticles(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ(), PacketParticles.Type.ALTAR_CONVERSION, this.container.getAuraColor()));
2018-10-20 21:19:08 +02:00
}
}
} else {
if (this.currentRecipe == null) {
if (!stack.isEmpty()) {
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;
} else {
2021-12-15 16:24:53 +01:00
var req = Mth.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)
2021-12-04 15:40:09 +01:00
PacketHandler.sendToAllAround(this.level, this.worldPosition, 32, new PacketParticles(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.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;
2021-12-08 00:31:29 +01:00
this.level.playSound(null, this.worldPosition.getX() + 0.5, this.worldPosition.getY() + 0.5, this.worldPosition.getZ() + 0.5, SoundEvents.ARROW_HIT_PLAYER, SoundSource.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
}
2021-12-04 15:40:09 +01:00
if (this.level.getGameTime() % 10 == 0 && this.lastAura != this.container.getStoredAura()) {
2018-10-14 14:27:18 +02:00
this.lastAura = this.container.getStoredAura();
this.sendToClients();
}
} else {
if (this.isComplete) {
2018-10-14 14:27:18 +02:00
if (rand.nextFloat() >= 0.7F) {
2021-12-15 16:24:53 +01:00
var fourths = this.container.getMaxAura() / 4;
2018-10-14 14:27:18 +02:00
if (this.container.getStoredAura() > 0) {
2018-11-13 00:36:47 +01:00
NaturesAuraAPI.instance().spawnMagicParticle(
2021-12-04 15:40:09 +01:00
this.worldPosition.getX() - 4F + rand.nextFloat(), this.worldPosition.getY() + 3F, this.worldPosition.getZ() + rand.nextFloat(),
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(
2021-12-04 15:40:09 +01:00
this.worldPosition.getX() + 4F + rand.nextFloat(), this.worldPosition.getY() + 3F, this.worldPosition.getZ() + rand.nextFloat(),
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(
2021-12-04 15:40:09 +01:00
this.worldPosition.getX() + rand.nextFloat(), this.worldPosition.getY() + 3F, this.worldPosition.getZ() - 4F + rand.nextFloat(),
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(
2021-12-04 15:40:09 +01:00
this.worldPosition.getX() + rand.nextFloat(), this.worldPosition.getY() + 3F, this.worldPosition.getZ() + 4F + rand.nextFloat(),
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
}
}
this.bobTimer++;
2018-10-14 14:27:18 +02:00
}
}
private AltarRecipe getRecipeForInput(ItemStack input) {
2023-07-25 14:12:29 +02:00
for (var recipe : this.level.getRecipeManager().getRecipesFor(ModRecipes.ALTAR_TYPE, null, this.level)) {
if (recipe.input.test(input)) {
if (recipe.catalyst == Ingredient.EMPTY)
return recipe;
for (var stack : this.catalysts) {
2020-01-21 21:04:44 +01:00
if (recipe.catalyst.test(stack))
return recipe;
}
2018-11-11 13:26:19 +01:00
}
}
return null;
}
2018-10-14 14:27:18 +02:00
@Override
2021-12-04 15:40:09 +01:00
public void writeNBT(CompoundTag 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());
compound.putBoolean("complete", this.isComplete);
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
2021-12-04 15:40:09 +01:00
public void readNBT(CompoundTag 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"));
this.isComplete = compound.getBoolean("complete");
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")) {
2021-12-04 15:40:09 +01:00
if (this.hasLevel())
2021-12-08 00:31:29 +01:00
this.currentRecipe = (AltarRecipe) this.level.getRecipeManager().byKey(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
2020-10-19 21:26:32 +02:00
public IAuraContainer getAuraContainer() {
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
2020-10-19 21:26:32 +02:00
public IItemHandlerModifiable getItemHandler() {
2018-10-18 13:34:37 +02:00
return this.items;
}
2018-10-14 14:27:18 +02:00
}