package micdoodle8.mods.galacticraft.planets.mars.tile; import micdoodle8.mods.galacticraft.api.entity.IDockable; import micdoodle8.mods.galacticraft.api.prefab.entity.EntityAutoRocket; import micdoodle8.mods.galacticraft.api.tile.IFuelDock; import micdoodle8.mods.galacticraft.api.tile.ILandingPadAttachable; import micdoodle8.mods.galacticraft.core.GCBlocks; import micdoodle8.mods.galacticraft.core.GalacticraftCore; import micdoodle8.mods.galacticraft.core.blocks.BlockLandingPadFull; import micdoodle8.mods.galacticraft.core.energy.item.ItemElectricBase; import micdoodle8.mods.galacticraft.core.energy.tile.TileBaseElectricBlockWithInventory; import micdoodle8.mods.galacticraft.core.tile.TileEntityLandingPad; // import micdoodle8.mods.galacticraft.core.util.ConfigManagerCore; import micdoodle8.mods.galacticraft.core.util.GCCoreUtil; // import micdoodle8.mods.galacticraft.core.util.GCLog; import micdoodle8.mods.galacticraft.core.world.ChunkLoadingCallback; import micdoodle8.mods.galacticraft.core.world.IChunkLoader; import micdoodle8.mods.galacticraft.planets.mars.ConfigManagerMars; import micdoodle8.mods.galacticraft.planets.mars.blocks.BlockMachineMars; import micdoodle8.mods.galacticraft.planets.mars.network.PacketSimpleMars; import micdoodle8.mods.galacticraft.planets.mars.network.PacketSimpleMars.EnumSimplePacketMars; import micdoodle8.mods.miccore.Annotations.NetworkedField; import net.minecraft.block.Block; import net.minecraft.inventory.ISidedInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockPos; import net.minecraft.util.EnumFacing; import net.minecraft.util.IChatComponent; import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.IBlockAccess; import net.minecraft.world.WorldServer; import net.minecraftforge.common.ForgeChunkManager; import net.minecraftforge.common.ForgeChunkManager.Ticket; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.relauncher.Side; import java.util.ArrayList; // import java.util.HashMap; import java.util.List; // import java.util.Map; public class TileEntityLaunchController extends TileBaseElectricBlockWithInventory implements IChunkLoader, ISidedInventory, ILandingPadAttachable { public static final int WATTS_PER_TICK = 1; private ItemStack[] containingItems = new ItemStack[1]; @NetworkedField(targetSide = Side.CLIENT) public boolean launchPadRemovalDisabled = true; private Ticket chunkLoadTicket; private List<BlockPos> connectedPads = new ArrayList<BlockPos>(); @NetworkedField(targetSide = Side.CLIENT) public int frequency = -1; @NetworkedField(targetSide = Side.CLIENT) public int destFrequency = -1; @NetworkedField(targetSide = Side.CLIENT) public String ownerName = ""; @NetworkedField(targetSide = Side.CLIENT) public boolean frequencyValid; @NetworkedField(targetSide = Side.CLIENT) public boolean destFrequencyValid; @NetworkedField(targetSide = Side.CLIENT) public int launchDropdownSelection; @NetworkedField(targetSide = Side.CLIENT) public boolean launchSchedulingEnabled; @NetworkedField(targetSide = Side.CLIENT) public boolean controlEnabled; public boolean hideTargetDestination = true; public boolean requiresClientUpdate; public Object attachedDock = null; private boolean frequencyCheckNeeded = false; // private static Map<Integer, Long> tickCounts = new HashMap(); // private static Map<Integer, Integer> instanceCounts = new HashMap(); public TileEntityLaunchController() { this.storage.setMaxExtract(10); this.noRedstoneControl = true; } @Override public void update() { super.update(); if (!this.worldObj.isRemote) { this.controlEnabled = this.launchSchedulingEnabled && this.hasEnoughEnergyToRun && !this.getDisabled(0); if (this.frequencyCheckNeeded) { this.checkDestFrequencyValid(); this.frequencyCheckNeeded = false; } if (this.requiresClientUpdate) { // PacketDispatcher.sendPacketToAllPlayers(this.getPacket()); // TODO this.requiresClientUpdate = false; } if (this.ticks % 40 == 0) { this.setFrequency(this.frequency); this.setDestinationFrequency(this.destFrequency); } if (this.ticks % 20 == 0) { if (this.chunkLoadTicket != null) { for (int i = 0; i < this.connectedPads.size(); i++) { BlockPos coords = this.connectedPads.get(i); Block block = this.worldObj.getBlockState(coords).getBlock(); if (block != GCBlocks.landingPadFull) { this.connectedPads.remove(i); ForgeChunkManager.unforceChunk(this.chunkLoadTicket, new ChunkCoordIntPair(coords.getX() >> 4, coords.getZ() >> 4)); } } } } } else { if (this.frequency == -1 && this.destFrequency == -1) { GalacticraftCore.packetPipeline.sendToServer(new PacketSimpleMars(EnumSimplePacketMars.S_UPDATE_ADVANCED_GUI, GCCoreUtil.getDimensionID(this.worldObj), new Object[] { 5, this.getPos(), 0 })); } } } @Override public String getOwnerName() { return this.ownerName; } @Override public void setOwnerName(String ownerName) { this.ownerName = ownerName; } @Override public void invalidate() { super.invalidate(); if (this.chunkLoadTicket != null) { ForgeChunkManager.releaseTicket(this.chunkLoadTicket); } } @Override public void onTicketLoaded(Ticket ticket, boolean placed) { if (!this.worldObj.isRemote && ConfigManagerMars.launchControllerChunkLoad) { if (ticket == null) { return; } if (this.chunkLoadTicket == null) { this.chunkLoadTicket = ticket; } NBTTagCompound nbt = this.chunkLoadTicket.getModData(); nbt.setInteger("ChunkLoaderTileX", this.getPos().getX()); nbt.setInteger("ChunkLoaderTileY", this.getPos().getY()); nbt.setInteger("ChunkLoaderTileZ", this.getPos().getZ()); for (int x = -2; x <= 2; x++) { for (int z = -2; z <= 2; z++) { Block blockID = this.worldObj.getBlockState(this.getPos().add(x, 0, z)).getBlock(); if (blockID instanceof BlockLandingPadFull) { if (this.getPos().getX() + x >> 4 != this.getPos().getX() >> 4 || this.getPos().getZ() + z >> 4 != this.getPos().getZ() >> 4) { this.connectedPads.add(new BlockPos(this.getPos().getX() + x, this.getPos().getY(), this.getPos().getZ() + z)); if (placed) { ChunkLoadingCallback.forceChunk(this.chunkLoadTicket, this.worldObj, this.getPos().getX() + x, this.getPos().getY(), this.getPos().getZ() + z, this.getOwnerName()); } else { ChunkLoadingCallback.addToList(this.worldObj, this.getPos().getX(), this.getPos().getY(), this.getPos().getZ(), this.getOwnerName()); } } } } } ChunkLoadingCallback.forceChunk(this.chunkLoadTicket, this.worldObj, this.getPos().getX(), this.getPos().getY(), this.getPos().getZ(), this.getOwnerName()); } } @Override public Ticket getTicket() { return this.chunkLoadTicket; } @Override public BlockPos getCoords() { return new BlockPos(this.getPos().getX(), this.getPos().getY(), this.getPos().getZ()); } @Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); this.containingItems = this.readStandardItemsFromNBT(nbt); this.ownerName = nbt.getString("OwnerName"); this.launchDropdownSelection = nbt.getInteger("LaunchSelection"); this.frequency = nbt.getInteger("ControllerFrequency"); this.destFrequency = nbt.getInteger("TargetFrequency"); this.frequencyCheckNeeded = true; this.launchPadRemovalDisabled = nbt.getBoolean("LaunchPadRemovalDisabled"); this.launchSchedulingEnabled = nbt.getBoolean("LaunchPadSchedulingEnabled"); this.hideTargetDestination = nbt.getBoolean("HideTargetDestination"); this.requiresClientUpdate = true; } @Override public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); this.writeStandardItemsToNBT(nbt); nbt.setString("OwnerName", this.ownerName); nbt.setInteger("LaunchSelection", this.launchDropdownSelection); nbt.setInteger("ControllerFrequency", this.frequency); nbt.setInteger("TargetFrequency", this.destFrequency); nbt.setBoolean("LaunchPadRemovalDisabled", this.launchPadRemovalDisabled); nbt.setBoolean("LaunchPadSchedulingEnabled", this.launchSchedulingEnabled); nbt.setBoolean("HideTargetDestination", this.hideTargetDestination); } @Override public ItemStack[] getContainingItems() { return this.containingItems; } @Override public String getName() { return GCCoreUtil.translate("container.launchcontroller.name"); } @Override public boolean hasCustomName() { return true; } @Override public boolean isItemValidForSlot(int slotID, ItemStack itemStack) { return slotID == 0 && ItemElectricBase.isElectricItem(itemStack.getItem()); } @Override public int[] getSlotsForFace(EnumFacing side) { return new int[] { 0 }; } @Override public boolean canInsertItem(int slotID, ItemStack par2ItemStack, EnumFacing par3) { return this.isItemValidForSlot(slotID, par2ItemStack); } @Override public boolean canExtractItem(int slotID, ItemStack par2ItemStack, EnumFacing par3) { return slotID == 0; } @Override public boolean shouldUseEnergy() { return !this.getDisabled(0); } @Override public void setDisabled(int index, boolean disabled) { if (this.disableCooldown == 0) { switch (index) { case 0: this.disabled = disabled; this.disableCooldown = 10; break; case 1: this.launchSchedulingEnabled = disabled; break; case 2: this.hideTargetDestination = disabled; this.disableCooldown = 10; break; } } } @Override public boolean getDisabled(int index) { switch (index) { case 0: return this.disabled; case 1: return this.launchSchedulingEnabled; case 2: return this.hideTargetDestination; } return true; } @Override public boolean canAttachToLandingPad(IBlockAccess world, BlockPos pos) { TileEntity tile = world.getTileEntity(pos); return tile instanceof TileEntityLandingPad; } public void setFrequency(int frequency) { this.frequency = frequency; if (this.frequency >= 0 && FMLCommonHandler.instance().getMinecraftServerInstance() != null) { this.frequencyValid = true; WorldServer[] servers = FMLCommonHandler.instance().getMinecraftServerInstance().worldServers; worldLoop: for (int i = 0; i < servers.length; i++) { WorldServer world = servers[i]; for (TileEntity tile2 : new ArrayList<TileEntity>(world.loadedTileEntityList)) { if (this != tile2) { tile2 = world.getTileEntity(tile2.getPos()); if (tile2 == null) { continue; } if (tile2 instanceof TileEntityLaunchController) { TileEntityLaunchController launchController2 = (TileEntityLaunchController) tile2; if (launchController2.frequency == this.frequency) { this.frequencyValid = false; break worldLoop; } } } } } } else { this.frequencyValid = false; } } public void setDestinationFrequency(int frequency) { if (frequency != this.destFrequency) { this.destFrequency = frequency; this.checkDestFrequencyValid(); this.updateRocketOnDockSettings(); } } public void checkDestFrequencyValid() { if (!this.worldObj.isRemote && FMLCommonHandler.instance().getMinecraftServerInstance() != null) { this.destFrequencyValid = false; if (this.destFrequency >= 0) { WorldServer[] servers = FMLCommonHandler.instance().getMinecraftServerInstance().worldServers; for (int i = 0; i < servers.length; i++) { WorldServer world = servers[i]; for (TileEntity tile2 : new ArrayList<TileEntity>(world.loadedTileEntityList)) { if (this != tile2) { tile2 = world.getTileEntity(tile2.getPos()); if (tile2 == null) { continue; } if (tile2 instanceof TileEntityLaunchController) { TileEntityLaunchController launchController2 = (TileEntityLaunchController) tile2; if (launchController2.frequency == this.destFrequency) { this.destFrequencyValid = true; return; } } } } } } } } public boolean validFrequency() { this.checkDestFrequencyValid(); return !this.getDisabled(0) && this.hasEnoughEnergyToRun && this.frequencyValid && this.destFrequencyValid; } public void setLaunchDropdownSelection(int newvalue) { if (newvalue != this.launchDropdownSelection) { this.launchDropdownSelection = newvalue; this.checkDestFrequencyValid(); this.updateRocketOnDockSettings(); } } public void setLaunchSchedulingEnabled(boolean newvalue) { if (newvalue != this.launchSchedulingEnabled) { this.launchSchedulingEnabled = newvalue; this.checkDestFrequencyValid(); this.updateRocketOnDockSettings(); } } public void updateRocketOnDockSettings() { if (this.attachedDock instanceof TileEntityLandingPad) { TileEntityLandingPad pad = ((TileEntityLandingPad) this.attachedDock); IDockable rocket = pad.getDockedEntity(); if (rocket instanceof EntityAutoRocket) { ((EntityAutoRocket) rocket).updateControllerSettings(pad); } } } @Override public IChatComponent getDisplayName() { return null; } public void setAttachedPad(IFuelDock pad) { this.attachedDock = pad; } @Override public EnumFacing getFront() { return this.worldObj.getBlockState(getPos()).getValue(BlockMachineMars.FACING); } @Override public EnumFacing getElectricInputDirection() { return getFront().rotateY(); } }