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

116 lines
4.1 KiB
Java
Raw Normal View History

2019-03-19 17:21:06 +01:00
package de.ellpeck.naturesaura.blocks.tiles;
import de.ellpeck.naturesaura.ModConfig;
2019-03-19 17:21:06 +01:00
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
2021-12-06 14:38:12 +01:00
import net.minecraft.core.BlockPos;
2021-12-04 15:40:09 +01:00
import net.minecraft.nbt.CompoundTag;
2021-12-06 14:38:12 +01:00
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.block.state.BlockState;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
2019-03-19 17:21:06 +01:00
2021-12-04 15:40:09 +01:00
public class BlockEntityChunkLoader extends BlockEntityImpl implements ITickableBlockEntity {
private final List<ChunkPos> forcedChunks = new ArrayList<>();
private boolean firstTick = true;
2021-12-06 14:38:12 +01:00
public BlockEntityChunkLoader(BlockPos pos, BlockState state) {
super(ModTileEntities.CHUNK_LOADER, pos, state);
2020-01-21 21:04:44 +01:00
}
2019-03-19 17:21:06 +01:00
@Override
2021-12-06 14:38:12 +01:00
public void setRemoved() {
super.setRemoved();
this.loadChunks(true);
2019-03-19 17:21:06 +01:00
}
@Override
public void onRedstonePowerChange(int newPower) {
super.onRedstonePowerChange(newPower);
2021-12-04 15:40:09 +01:00
if (!this.level.isClientSide) {
this.loadChunks(false);
2019-03-19 17:21:06 +01:00
this.sendToClients();
}
}
2019-03-19 17:21:06 +01:00
public int range() {
return this.redstonePower * 2;
}
private void loadChunks(boolean unload) {
2021-12-04 15:40:09 +01:00
if (this.level.isClientSide || !ModConfig.instance.chunkLoader.get())
2019-03-19 17:21:06 +01:00
return;
2021-12-04 15:40:09 +01:00
ServerLevel level = (ServerLevel) this.level;
List<ChunkPos> shouldBeForced = new ArrayList<>();
if (!unload) {
int range = this.range();
if (range > 0) {
2021-12-04 15:40:09 +01:00
for (int x = (this.worldPosition.getX() - range) >> 4; x <= (this.worldPosition.getX() + range) >> 4; x++) {
for (int z = (this.worldPosition.getZ() - range) >> 4; z <= (this.worldPosition.getZ() + range) >> 4; z++) {
ChunkPos pos = new ChunkPos(x, z);
// Only force chunks that we're already forcing or that nobody else is forcing
2021-12-06 14:38:12 +01:00
if (this.forcedChunks.contains(pos) || !level.getForcedChunks().contains(pos.toLong()))
shouldBeForced.add(pos);
}
2019-03-19 17:21:06 +01:00
}
}
}
2021-12-06 14:38:12 +01:00
// Unforce all the chunks that shouldn't be forced anymore
for (ChunkPos pos : this.forcedChunks) {
if (!shouldBeForced.contains(pos))
2021-12-06 14:38:12 +01:00
level.setChunkForced(pos.x, pos.z, false);
}
this.forcedChunks.clear();
// Force all chunks that should be forced
for (ChunkPos pos : shouldBeForced) {
2021-12-06 14:38:12 +01:00
level.setChunkForced(pos.x, pos.z, true);
this.forcedChunks.add(pos);
}
}
2019-03-19 17:21:06 +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 && ModConfig.instance.chunkLoader.get()) {
// defer loading chunks on load to here since, otherwise, deadlocks happen oof
// since forced chunks are saved to disk by the game, this is only necessary for when the chunk loader config changes
if (this.firstTick) {
this.loadChunks(false);
this.firstTick = false;
}
2021-12-04 15:40:09 +01:00
if (this.level.getGameTime() % 20 != 0)
2019-03-19 17:21:06 +01:00
return;
2021-12-04 19:17:21 +01:00
int toUse = Mth.ceil(this.range() / 2F);
2019-03-19 17:21:06 +01:00
if (toUse > 0) {
2021-12-04 15:40:09 +01:00
BlockPos spot = IAuraChunk.getHighestSpot(this.level, this.worldPosition, 35, this.worldPosition);
IAuraChunk.getAuraChunk(this.level, spot).drainAura(spot, toUse);
2019-03-19 17:21:06 +01:00
}
}
}
@Override
2021-12-04 15:40:09 +01:00
public void writeNBT(CompoundTag compound, SaveType type) {
super.writeNBT(compound, type);
if (type == SaveType.TILE)
2021-12-06 14:38:12 +01:00
compound.putLongArray("forced_chunks", this.forcedChunks.stream().map(ChunkPos::toLong).collect(Collectors.toList()));
}
@Override
2021-12-04 15:40:09 +01:00
public void readNBT(CompoundTag compound, SaveType type) {
super.readNBT(compound, type);
if (type == SaveType.TILE) {
this.forcedChunks.clear();
Arrays.stream(compound.getLongArray("forced_chunks")).mapToObj(ChunkPos::new).forEach(this.forcedChunks::add);
}
}
2019-03-19 17:21:06 +01:00
}