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

212 lines
8.3 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;
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.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
2023-07-08 12:32:27 +02:00
import net.minecraft.world.level.storage.loot.LootParams;
2021-12-08 00:31:29 +01:00
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.phys.Vec3;
2024-02-03 14:56:07 +01:00
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.common.util.FakePlayerFactory;
import net.neoforged.neoforge.event.level.BlockEvent;
2018-11-13 00:36:47 +01:00
2021-12-04 15:40:09 +01:00
public class BlockEntityFieldCreator extends BlockEntityImpl implements ITickableBlockEntity {
2018-11-13 00:36:47 +01:00
public BlockPos connectionOffset;
public boolean isMain;
public boolean isCharged;
private int chargeTimer;
2021-12-08 00:31:29 +01:00
public BlockEntityFieldCreator(BlockPos pos, BlockState state) {
2021-12-19 15:32:45 +01:00
super(ModBlockEntities.FIELD_CREATOR, pos, state);
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() {
2021-12-04 15:40:09 +01:00
if (this.level.isClientSide || this.level.getGameTime() % 10 != 0)
2018-11-13 00:36:47 +01:00
return;
2021-12-15 16:30:22 +01:00
var connectedPos = this.getConnectedPos();
2021-12-08 00:31:29 +01:00
if (connectedPos == null || !this.level.isLoaded(connectedPos))
2018-11-13 00:36:47 +01:00
return;
2021-12-15 16:30:22 +01:00
var other = this.level.getBlockEntity(connectedPos);
2018-11-13 00:36:47 +01:00
if (!this.isCloseEnough(connectedPos)
2022-09-03 12:06:41 +02:00
|| !(other instanceof BlockEntityFieldCreator creator)
2021-12-04 15:40:09 +01:00
|| !this.worldPosition.equals(((BlockEntityFieldCreator) other).getConnectedPos())) {
2018-11-13 00:36:47 +01:00
this.connectionOffset = null;
this.chargeTimer = 0;
this.isCharged = false;
this.isMain = false;
this.sendToClients();
return;
}
if (!this.isMain)
return;
2023-02-16 19:03:26 +01:00
if (this.redstonePower <= 0 && creator.redstonePower <= 0 || !this.canUseRightNow(20)) {
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;
}
2021-12-15 16:30:22 +01:00
var spot = IAuraChunk.getHighestSpot(this.level, this.worldPosition, 32, this.worldPosition);
var chunk = IAuraChunk.getAuraChunk(this.level, spot);
2018-11-13 00:36:47 +01:00
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 {
2021-12-04 15:40:09 +01:00
if (this.level.getGameTime() % 40 == 0)
chunk.drainAura(spot, 20);
2018-11-13 00:36:47 +01:00
2021-12-15 16:30:22 +01:00
var tool = this.getToolUsed(creator);
var dist = new Vec3(
2021-12-04 15:40:09 +01:00
this.worldPosition.getX() - connectedPos.getX(),
this.worldPosition.getY() - connectedPos.getY(),
this.worldPosition.getZ() - connectedPos.getZ()
2018-11-13 00:36:47 +01:00
);
2021-12-15 16:30:22 +01:00
var length = dist.length();
var normal = new Vec3(dist.x / length, dist.y / length, dist.z / length);
2021-12-04 19:17:21 +01:00
for (float i = Mth.floor(length); i > 0; i -= 0.5F) {
2021-12-15 16:30:22 +01:00
var scaled = normal.scale(i);
var pos = connectedPos.offset(
2021-12-04 19:17:21 +01:00
Mth.floor(scaled.x + 0.5F),
Mth.floor(scaled.y + 0.5F),
Mth.floor(scaled.z + 0.5F));
2018-11-13 00:36:47 +01:00
2021-12-04 15:40:09 +01:00
if (pos.equals(this.worldPosition) || pos.equals(connectedPos))
2018-11-13 00:36:47 +01:00
continue;
2021-12-15 16:30:22 +01:00
var state = this.level.getBlockState(pos);
2021-12-08 00:31:29 +01:00
if (!state.isAir() && state.getDestroySpeed(this.level, pos) >= 0F) {
2021-12-15 16:30:22 +01:00
var fake = FakePlayerFactory.getMinecraft((ServerLevel) this.level);
2024-02-03 14:56:07 +01:00
if (!NeoForge.EVENT_BUS.post(new BlockEvent.BreakEvent(this.level, pos, state, fake))) {
2023-07-08 12:32:27 +02:00
var drops = state.getDrops(new LootParams.Builder((ServerLevel) this.level)
2021-12-08 00:31:29 +01:00
.withParameter(LootContextParams.THIS_ENTITY, fake)
.withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(pos))
.withParameter(LootContextParams.BLOCK_STATE, state)
.withParameter(LootContextParams.TOOL, tool.isEmpty() ? new ItemStack(Items.DIAMOND_PICKAXE) : tool)
.withOptionalParameter(LootContextParams.BLOCK_ENTITY, this.level.getBlockEntity(pos)));
2021-12-04 15:40:09 +01:00
this.level.destroyBlock(pos, false);
2021-12-15 16:30:22 +01:00
for (var stack : drops)
2021-12-08 00:31:29 +01:00
Block.popResource(this.level, pos, stack);
2020-10-18 15:30:51 +02:00
chunk.drainAura(spot, !tool.isEmpty() ? 300 : 100);
2020-01-23 20:57:56 +01:00
this.sendParticles();
2018-11-13 00:36:47 +01:00
}
}
}
}
}
2021-12-04 15:40:09 +01:00
private ItemStack getToolUsed(BlockEntityFieldCreator other) {
2021-12-15 16:30:22 +01:00
var myTool = this.getMyTool();
var otherTool = other.getMyTool();
if (!myTool.isEmpty()) {
// if both have tools, choose randomly
if (!otherTool.isEmpty())
2021-12-08 00:31:29 +01:00
return this.level.random.nextBoolean() ? myTool : otherTool;
return myTool;
}
return otherTool;
2020-01-23 20:57:56 +01:00
}
private ItemStack getMyTool() {
2021-12-15 16:30:22 +01:00
var frames = Helper.getAttachedItemFrames(this.level, this.worldPosition);
for (var frame : frames) {
var stack = frame.getItem();
2020-01-23 20:57:56 +01:00
if (!stack.isEmpty())
return stack;
2019-01-31 18:58:31 +01:00
}
return ItemStack.EMPTY;
2019-01-31 18:58:31 +01:00
}
2018-11-13 00:36:47 +01:00
private void sendParticles() {
2021-12-15 16:30:22 +01:00
for (var j = 0; j < 2; j++) {
var p = j == 0 ? this.worldPosition : this.getConnectedPos();
2021-12-04 15:40:09 +01:00
PacketHandler.sendToAllAround(this.level, p, 32, new PacketParticleStream(
2021-12-08 00:31:29 +01:00
p.getX() + (float) this.level.random.nextGaussian() * 3F,
p.getY() + 1 + this.level.random.nextFloat() * 3F,
p.getZ() + (float) this.level.random.nextGaussian() * 3F,
2018-11-13 01:27:47 +01:00
p.getX() + 0.5F,
p.getY() + 0.5F,
p.getZ() + 0.5F,
2021-12-08 00:31:29 +01:00
this.level.random.nextFloat() * 0.07F + 0.07F, IAuraType.forLevel(this.level).getColor(), this.level.random.nextFloat() + 0.5F
2020-01-22 23:21:52 +01:00
));
2018-11-13 00:36:47 +01:00
}
}
public boolean isCloseEnough(BlockPos pos) {
2021-12-15 16:30:22 +01:00
var range = ModConfig.instance.fieldCreatorRange.get() + 1;
2021-12-08 00:31:29 +01:00
return this.worldPosition.distSqr(pos) <= range * range;
2018-11-13 00:36:47 +01:00
}
public BlockPos getConnectedPos() {
if (this.connectionOffset == null)
return null;
2021-12-08 00:31:29 +01:00
return this.worldPosition.offset(this.connectionOffset);
2018-11-13 00:36:47 +01:00
}
@Override
2021-12-04 15:40:09 +01:00
public void writeNBT(CompoundTag compound, SaveType type) {
2018-11-13 00:36:47 +01:00
super.writeNBT(compound, type);
if (type != SaveType.BLOCK) {
if (this.connectionOffset != null)
2021-12-08 00:31:29 +01:00
compound.putLong("connection", this.connectionOffset.asLong());
2020-01-21 21:04:44 +01:00
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
2021-12-04 15:40:09 +01:00
public void readNBT(CompoundTag 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"))
2021-12-08 00:31:29 +01:00
this.connectionOffset = BlockPos.of(compound.getLong("connection"));
2018-11-13 00:36:47 +01:00
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
}
}
2023-02-16 19:03:26 +01:00
@Override
public boolean allowsLowerLimiter() {
return true;
}
2018-11-13 00:36:47 +01:00
}