package mcjty.deepresonance.blocks.gencontroller;
import elec332.core.world.WorldHelper;
import mcjty.deepresonance.blocks.generator.GeneratorConfiguration;
import mcjty.deepresonance.blocks.generator.GeneratorSetup;
import mcjty.deepresonance.blocks.generator.GeneratorTileEntity;
import mcjty.deepresonance.client.sound.GeneratorSoundController;
import mcjty.deepresonance.generatornetwork.DRGeneratorNetwork;
import mcjty.lib.entity.GenericTileEntity;
import mcjty.lib.varia.Broadcaster;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.util.HashSet;
import java.util.Set;
public class GeneratorControllerTileEntity extends GenericTileEntity implements ITickable {
private int startup = 0;
private int shutdown = 0;
private boolean active = false;
private int powered;
public GeneratorControllerTileEntity() {
super();
}
@Override
public void setPowered(int powered) {
this.powered = powered;
markDirtyClient();
}
public boolean isPowered() {
return powered > 0;
}
@Override
public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity packet) {
boolean working = isPowered();
super.onDataPacket(net, packet);
if (worldObj.isRemote) {
// If needed send a render update.
if (isPowered() != working) {
worldObj.markBlockRangeForRenderUpdate(getPos(), getPos());
}
}
}
@Override
public void invalidate() {
super.invalidate();
if (worldObj.isRemote) {
stopSounds();
}
}
@SideOnly(Side.CLIENT)
private void stopSounds() {
GeneratorSoundController.stopSound(worldObj, getPos());
}
@Override
public void update() {
if (!worldObj.isRemote){
checkStateServer();
} else {
checkStateClient();
}
}
@SideOnly(Side.CLIENT)
protected void checkStateClient() {
if (GeneratorConfiguration.baseGeneratorVolume < 0.01f) {
// No sounds.
return;
}
if (startup != 0) {
if (!GeneratorSoundController.isStartupPlaying(worldObj, pos)) {
GeneratorSoundController.playStartup(worldObj, pos);
}
} else if (shutdown != 0) {
if (!GeneratorSoundController.isShutdownPlaying(worldObj, pos)) {
GeneratorSoundController.playShutdown(worldObj, pos);
}
} else if (active) {
if (!GeneratorSoundController.isLoopPlaying(worldObj, pos)) {
GeneratorSoundController.playLoop(worldObj, pos);
}
} else {
stopSounds();
}
}
protected void checkStateServer() {
boolean active = powered > 0;
// @todo optimize this?
boolean dirty = false;
Set<Integer> networks = new HashSet<Integer>();
for (EnumFacing direction : EnumFacing.VALUES) {
BlockPos newC = getPos().offset(direction);
Block b = WorldHelper.getBlockAt(worldObj, newC);
if (b == GeneratorSetup.generatorBlock) {
GeneratorTileEntity generatorTileEntity = (GeneratorTileEntity) WorldHelper.getTileAt(worldObj, newC);
int networkId = generatorTileEntity.getNetworkId();
if (networkId != -1 && !networks.contains(networkId)) {
networks.add(networkId);
if (active) {
// Only activate with sufficient energy collectors.
int countCollectors = generatorTileEntity.getNetwork().getCollectorBlocks();
if (countCollectors == 1) {
if (handleActivate(networkId, newC)) {
dirty = true;
}
} else {
if (countCollectors < 1) {
Broadcaster.broadcast(worldObj, getPos().getX(), getPos().getY(), getPos().getZ(), "There is no energy collector on this generator!", 100);
} else {
Broadcaster.broadcast(worldObj, getPos().getX(), getPos().getY(), getPos().getZ(), "There are too many energy collectors on this generator!!", 100);
}
if (handleDeactivate(networkId, newC)) {
dirty = true;
}
}
} else {
if (handleDeactivate(networkId, newC)) {
dirty = true;
}
}
}
}
}
if (dirty) {
DRGeneratorNetwork generatorNetwork = DRGeneratorNetwork.getChannels(worldObj);
generatorNetwork.save(worldObj);
}
}
private boolean handleActivate(int id, BlockPos coordinate) {
DRGeneratorNetwork generatorNetwork = DRGeneratorNetwork.getChannels(worldObj);
DRGeneratorNetwork.Network network = generatorNetwork.getOrCreateNetwork(id);
if (network.isActive() && network.getShutdownCounter() == 0) {
return false; // Nothing to do.
}
startup = network.getStartupCounter();
if (startup == 0) {
startup = GeneratorConfiguration.startupTime;
}
startup--;
if (startup <= 0) {
startup = 0;
GeneratorTileEntity generatorTileEntity = (GeneratorTileEntity) WorldHelper.getTileAt(worldObj, coordinate);
generatorTileEntity.activate(true);
}
active = network.isActive();
shutdown = 0;
network.setShutdownCounter(0);
network.setStartupCounter(startup);
markDirty();
IBlockState state = worldObj.getBlockState(pos);
worldObj.notifyBlockUpdate(pos, state, state, 3);
return true;
}
private boolean handleDeactivate(int id, BlockPos coordinate) {
IBlockState state = worldObj.getBlockState(getPos());
DRGeneratorNetwork generatorNetwork = DRGeneratorNetwork.getChannels(worldObj);
DRGeneratorNetwork.Network network = generatorNetwork.getOrCreateNetwork(id);
if ((!network.isActive()) && network.getShutdownCounter() == 0 && network.getStartupCounter() == 0) {
if (network.getShutdownCounter() != shutdown || network.getStartupCounter() != startup || (network.isActive() != active)) {
shutdown = network.getShutdownCounter();
startup = network.getStartupCounter();
active = network.isActive();
markDirty();
worldObj.notifyBlockUpdate(getPos(), state, state, 3);
}
return false; // Nothing to do.
}
shutdown = network.getShutdownCounter();
if (network.isActive() || network.getStartupCounter() != 0) {
shutdown = GeneratorConfiguration.shutdownTime;
GeneratorTileEntity generatorTileEntity = (GeneratorTileEntity) WorldHelper.getTileAt(worldObj, coordinate);
generatorTileEntity.activate(false);
}
shutdown--;
if (shutdown <= 0) {
shutdown = 0;
}
startup = 0;
active = network.isActive();
network.setStartupCounter(0);
network.setShutdownCounter(shutdown);
markDirty();
worldObj.notifyBlockUpdate(getPos(), state, state, 3);
return true;
}
@Override
public void readFromNBT(NBTTagCompound tagCompound) {
super.readFromNBT(tagCompound);
startup = tagCompound.getInteger("startup");
shutdown = tagCompound.getInteger("shutdown");
active = tagCompound.getBoolean("active");
powered = tagCompound.getInteger("powered");
}
@Override
public void writeToNBT(NBTTagCompound tagCompound) {
super.writeToNBT(tagCompound);
tagCompound.setInteger("startup", startup);
tagCompound.setInteger("shutdown", shutdown);
tagCompound.setBoolean("active", active);
tagCompound.setInteger("powered", powered);
}
}