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

210 lines
8.2 KiB
Java
Raw Normal View History

2018-11-13 00:36:47 +01:00
package de.ellpeck.naturesaura.blocks.tiles;
2019-01-31 18:58:31 +01:00
import de.ellpeck.naturesaura.Helper;
2018-11-13 00:36:47 +01:00
import de.ellpeck.naturesaura.ModConfig;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
2020-01-22 23:21:52 +01:00
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticleStream;
2018-11-13 00:36:47 +01:00
import net.minecraft.block.Block;
2019-10-20 22:30:49 +02:00
import net.minecraft.block.BlockState;
import net.minecraft.entity.item.ItemFrameEntity;
2018-11-13 00:36:47 +01:00
import net.minecraft.item.ItemStack;
2020-01-23 20:57:56 +01:00
import net.minecraft.item.Items;
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;
2018-11-13 00:36:47 +01:00
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
2020-01-21 21:04:44 +01:00
import net.minecraft.world.server.ServerWorld;
import net.minecraft.world.storage.loot.LootContext;
import net.minecraft.world.storage.loot.LootParameters;
2018-11-13 00:36:47 +01:00
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.common.util.FakePlayerFactory;
import net.minecraftforge.event.world.BlockEvent;
2019-01-31 18:58:31 +01:00
import java.util.List;
2020-01-21 21:04:44 +01:00
public class TileEntityFieldCreator extends TileEntityImpl implements ITickableTileEntity {
2018-11-13 00:36:47 +01:00
public BlockPos connectionOffset;
public boolean isMain;
public boolean isCharged;
private int chargeTimer;
2020-01-22 01:32:26 +01:00
public TileEntityFieldCreator() {
super(ModTileEntities.FIELD_CREATOR);
2020-01-21 21:04:44 +01:00
}
2018-11-13 00:36:47 +01:00
@Override
2020-01-21 21:04:44 +01:00
public void tick() {
if (this.world.isRemote || this.world.getGameTime() % 10 != 0)
2018-11-13 00:36:47 +01:00
return;
BlockPos connectedPos = this.getConnectedPos();
2018-11-13 01:27:47 +01:00
if (connectedPos == null || !this.world.isBlockLoaded(connectedPos))
2018-11-13 00:36:47 +01:00
return;
TileEntity other = this.world.getTileEntity(connectedPos);
if (!this.isCloseEnough(connectedPos)
|| !(other instanceof TileEntityFieldCreator)
|| !this.pos.equals(((TileEntityFieldCreator) other).getConnectedPos())) {
this.connectionOffset = null;
this.chargeTimer = 0;
this.isCharged = false;
this.isMain = false;
this.sendToClients();
return;
}
if (!this.isMain)
return;
TileEntityFieldCreator creator = (TileEntityFieldCreator) other;
if (this.redstonePower <= 0 && creator.redstonePower <= 0) {
2018-11-13 00:36:47 +01:00
this.chargeTimer = 0;
if (this.isCharged) {
this.isCharged = false;
this.sendToClients();
creator.isCharged = false;
creator.sendToClients();
}
return;
}
BlockPos spot = IAuraChunk.getHighestSpot(this.world, this.pos, 32, this.pos);
IAuraChunk chunk = IAuraChunk.getAuraChunk(this.world, spot);
if (!this.isCharged) {
this.chargeTimer += 10;
if (this.chargeTimer >= 150) {
this.chargeTimer = 0;
this.isCharged = true;
this.sendToClients();
creator.isCharged = true;
creator.sendToClients();
}
chunk.drainAura(spot, 300);
2018-11-13 00:36:47 +01:00
this.sendParticles();
} else {
2020-01-21 21:04:44 +01:00
if (this.world.getGameTime() % 40 == 0)
chunk.drainAura(spot, 100);
2018-11-13 00:36:47 +01:00
2020-01-23 20:57:56 +01:00
ItemStack tool = this.getToolUsed(creator);
2018-11-13 00:36:47 +01:00
Vec3d dist = new Vec3d(
this.pos.getX() - connectedPos.getX(),
this.pos.getY() - connectedPos.getY(),
this.pos.getZ() - connectedPos.getZ()
);
double length = dist.length();
Vec3d normal = new Vec3d(dist.x / length, dist.y / length, dist.z / length);
2020-01-23 20:57:56 +01:00
for (float i = MathHelper.floor(length); i > 0; i -= 0.5F) {
2018-11-13 00:36:47 +01:00
Vec3d scaled = normal.scale(i);
BlockPos pos = connectedPos.add(
MathHelper.floor(scaled.x + 0.5F),
MathHelper.floor(scaled.y + 0.5F),
MathHelper.floor(scaled.z + 0.5F));
if (pos.equals(this.pos) || pos.equals(connectedPos))
continue;
2019-10-20 22:30:49 +02:00
BlockState state = this.world.getBlockState(pos);
2018-11-13 00:36:47 +01:00
Block block = state.getBlock();
2020-01-21 21:04:44 +01:00
if (!block.isAir(state, this.world, pos) && state.getBlockHardness(this.world, pos) >= 0F) {
2019-10-20 22:30:49 +02:00
FakePlayer fake = FakePlayerFactory.getMinecraft((ServerWorld) this.world);
2018-11-13 00:36:47 +01:00
if (!MinecraftForge.EVENT_BUS.post(new BlockEvent.BreakEvent(this.world, pos, state, fake))) {
2020-01-23 20:57:56 +01:00
List<ItemStack> drops = state.getDrops(new LootContext.Builder((ServerWorld) this.world)
.withParameter(LootParameters.POSITION, pos)
.withParameter(LootParameters.BLOCK_STATE, state)
.withParameter(LootParameters.TOOL, tool == null ? new ItemStack(Items.DIAMOND_PICKAXE) : tool)
.withNullableParameter(LootParameters.BLOCK_ENTITY, this.world.getTileEntity(pos)));
this.world.destroyBlock(pos, false);
for (ItemStack stack : drops)
Block.spawnAsEntity(this.world, pos, stack);
chunk.drainAura(spot, tool != null ? 1000 : 300);
this.sendParticles();
2018-11-13 00:36:47 +01:00
}
}
}
}
}
2020-01-23 20:57:56 +01:00
private ItemStack getToolUsed(TileEntityFieldCreator other) {
ItemStack myTool = this.getMyTool();
ItemStack otherTool = other.getMyTool();
if (myTool != null && otherTool != null)
return this.world.rand.nextBoolean() ? myTool : otherTool;
return myTool;
}
private ItemStack getMyTool() {
2019-10-20 22:30:49 +02:00
List<ItemFrameEntity> frames = Helper.getAttachedItemFrames(this.world, this.pos);
for (ItemFrameEntity frame : frames) {
2019-01-31 18:58:31 +01:00
ItemStack stack = frame.getDisplayedItem();
2020-01-23 20:57:56 +01:00
if (!stack.isEmpty())
return stack;
2019-01-31 18:58:31 +01:00
}
2020-01-23 20:57:56 +01:00
return null;
2019-01-31 18:58:31 +01:00
}
2018-11-13 00:36:47 +01:00
private void sendParticles() {
for (int j = 0; j < 2; j++) {
BlockPos p = j == 0 ? this.pos : this.getConnectedPos();
2020-01-22 23:21:52 +01:00
PacketHandler.sendToAllAround(this.world, p, 32, new PacketParticleStream(
2018-11-13 00:36:47 +01:00
p.getX() + (float) this.world.rand.nextGaussian() * 3F,
p.getY() + 1 + this.world.rand.nextFloat() * 3F,
p.getZ() + (float) this.world.rand.nextGaussian() * 3F,
2018-11-13 01:27:47 +01:00
p.getX() + 0.5F,
p.getY() + 0.5F,
p.getZ() + 0.5F,
2018-11-13 00:36:47 +01:00
this.world.rand.nextFloat() * 0.07F + 0.07F, IAuraType.forWorld(this.world).getColor(), this.world.rand.nextFloat() + 0.5F
2020-01-22 23:21:52 +01:00
));
2018-11-13 00:36:47 +01:00
}
}
public boolean isCloseEnough(BlockPos pos) {
2020-01-24 17:05:41 +01:00
int range = ModConfig.instance.fieldCreatorRange.get() + 1;
2018-11-13 00:36:47 +01:00
return this.pos.distanceSq(pos) <= range * range;
}
public BlockPos getConnectedPos() {
if (this.connectionOffset == null)
return null;
return this.pos.add(this.connectionOffset);
}
@Override
2019-10-20 22:30:49 +02:00
public void writeNBT(CompoundNBT compound, SaveType type) {
2018-11-13 00:36:47 +01:00
super.writeNBT(compound, type);
if (type != SaveType.BLOCK) {
if (this.connectionOffset != null)
2020-01-21 21:04:44 +01:00
compound.putLong("connection", this.connectionOffset.toLong());
compound.putBoolean("main", this.isMain);
compound.putBoolean("charged", this.isCharged);
2018-11-13 00:36:47 +01:00
if (type == SaveType.TILE)
2020-01-21 21:04:44 +01:00
compound.putInt("timer", this.chargeTimer);
2018-11-13 00:36:47 +01:00
}
}
@Override
2019-10-20 22:30:49 +02:00
public void readNBT(CompoundNBT compound, SaveType type) {
2018-11-13 00:36:47 +01:00
super.readNBT(compound, type);
if (type != SaveType.BLOCK) {
2020-01-21 21:04:44 +01:00
if (compound.contains("connection"))
2018-11-13 00:36:47 +01:00
this.connectionOffset = BlockPos.fromLong(compound.getLong("connection"));
else
this.connectionOffset = null;
this.isMain = compound.getBoolean("main");
this.isCharged = compound.getBoolean("charged");
if (type == SaveType.TILE)
2020-01-21 21:04:44 +01:00
this.chargeTimer = compound.getInt("timer");
2018-11-13 00:36:47 +01:00
}
}
}