package zmaster587.advancedRocketry.tile.station; import io.netty.buffer.ByteBuf; import java.util.LinkedList; import java.util.List; import com.google.common.base.Predicate; import cpw.mods.fml.relauncher.Side; import zmaster587.advancedRocketry.AdvancedRocketry; import zmaster587.advancedRocketry.achievements.ARAchivements; import zmaster587.advancedRocketry.api.Configuration; import zmaster587.advancedRocketry.api.stations.ISpaceObject; import zmaster587.advancedRocketry.inventory.modules.ModulePlanetSelector; import zmaster587.advancedRocketry.inventory.TextureResources; import zmaster587.advancedRocketry.network.PacketSpaceStationInfo; import zmaster587.advancedRocketry.stations.SpaceObject; import zmaster587.advancedRocketry.stations.SpaceObjectManager; import zmaster587.advancedRocketry.tile.multiblock.TileWarpCore; import zmaster587.advancedRocketry.util.ITilePlanetSystemSelectable; import zmaster587.advancedRocketry.dimension.DimensionManager; import zmaster587.advancedRocketry.dimension.DimensionProperties; import zmaster587.libVulpes.LibVulpes; import zmaster587.libVulpes.client.util.IndicatorBarImage; import zmaster587.libVulpes.client.util.ProgressBarImage; import zmaster587.libVulpes.inventory.GuiHandler.guiId; import zmaster587.libVulpes.inventory.modules.IButtonInventory; import zmaster587.libVulpes.inventory.modules.IDataSync; import zmaster587.libVulpes.inventory.modules.IModularInventory; import zmaster587.libVulpes.inventory.modules.IProgressBar; import zmaster587.libVulpes.inventory.modules.ISelectionNotify; import zmaster587.libVulpes.inventory.modules.ModuleBase; import zmaster587.libVulpes.inventory.modules.ModuleButton; import zmaster587.libVulpes.inventory.modules.ModuleImage; import zmaster587.libVulpes.inventory.modules.ModuleProgress; import zmaster587.libVulpes.inventory.modules.ModuleScaledImage; import zmaster587.libVulpes.inventory.modules.ModuleSync; import zmaster587.libVulpes.inventory.modules.ModuleText; import zmaster587.libVulpes.network.PacketHandler; import zmaster587.libVulpes.network.PacketMachine; import zmaster587.libVulpes.util.BlockPosition; import zmaster587.libVulpes.util.INetworkMachine; import zmaster587.libVulpes.util.IconResource; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.Packet; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; import net.minecraftforge.common.util.ForgeDirection; public class TileWarpShipMonitor extends TileEntity implements IModularInventory, ISelectionNotify, INetworkMachine, IButtonInventory, IProgressBar, IDataSync { protected ModulePlanetSelector container; private ModuleText canWarp; DimensionProperties dimCache; private SpaceObject station; ModuleScaledImage srcPlanetImg, dstPlanetImg, srcAtmo, dstAtmo; ModuleSync sync1, sync2, sync3; ModuleText srcPlanetText, dstPlanetText, warpFuel, status; int warpCost = -1; int dstPlanet, srcPlanet; public TileWarpShipMonitor() { } private SpaceObject getSpaceObject() { if(station == null && worldObj.provider.dimensionId == Configuration.spaceDimId) { ISpaceObject object = SpaceObjectManager.getSpaceManager().getSpaceStationFromBlockCoords(xCoord, zCoord); if(object instanceof SpaceObject) station = (SpaceObject) object; } return station; } protected int getTravelCost() { if(getSpaceObject() != null) { DimensionProperties properties = getSpaceObject().getProperties().getParentProperties(); //properties.orbitalDist = 1; DimensionProperties destProperties = DimensionManager.getInstance().getDimensionProperties(getSpaceObject().getDestOrbitingBody()); if(properties == DimensionManager.defaultSpaceDimensionProperties) return Integer.MAX_VALUE; if(destProperties.getStar() != properties.getStar()) return 500; while(destProperties.getParentProperties() != null && destProperties.isMoon()) destProperties = destProperties.getParentProperties(); if((destProperties.isMoon() && destProperties.getParentPlanet() == properties.getId()) || (properties.isMoon() && properties.getParentPlanet() == destProperties.getId())) return 1; while(properties.isMoon()) properties = properties.getParentProperties(); //TODO: actual trig if(properties.getStar().getId() == destProperties.getStar().getId()) { double x1 = properties.orbitalDist*MathHelper.cos((float) properties.orbitTheta); double y1 = properties.orbitalDist*MathHelper.sin((float) properties.orbitTheta); double x2 = destProperties.orbitalDist*MathHelper.cos((float) destProperties.orbitTheta); double y2 = destProperties.orbitalDist*MathHelper.sin((float) destProperties.orbitTheta); return Math.max((int)Math.sqrt(Math.pow((x1 - x2),2) + Math.pow((y1 - y2),2)),1); //return Math.abs(properties.orbitalDist - destProperties.orbitalDist); } } return Integer.MAX_VALUE; } @Override public List<ModuleBase> getModules(int ID, EntityPlayer player) { List<ModuleBase> modules = new LinkedList<ModuleBase>(); if(ID == guiId.MODULARNOINV.ordinal()) { //Don't keep recreating it otherwise data is stale if(sync1 == null) { sync1 = new ModuleSync(0, this); sync2 = new ModuleSync(1, this); sync3 = new ModuleSync(2, this); } modules.add(sync1); modules.add(sync2); modules.add(sync3); ISpaceObject station = getSpaceObject(); boolean isOnStation = station != null; if(worldObj.isRemote) setPlanetModuleInfo(); //Source planet int baseX = 10; int baseY = 20; int sizeX = 70; int sizeY = 70; if(worldObj.isRemote) { modules.add(new ModuleScaledImage(baseX,baseY,sizeX,sizeY, zmaster587.libVulpes.inventory.TextureResources.starryBG)); modules.add(srcPlanetImg); modules.add(srcAtmo); modules.add(new ModuleText(baseX + 4, baseY + 4, "Orbiting:", 0xFFFFFF)); modules.add(srcPlanetText); //Border modules.add(new ModuleScaledImage(baseX - 3,baseY,3,sizeY, TextureResources.verticalBar)); modules.add(new ModuleScaledImage(baseX + sizeX, baseY, -3,sizeY, TextureResources.verticalBar)); modules.add(new ModuleScaledImage(baseX,baseY,70,3, TextureResources.horizontalBar)); modules.add(new ModuleScaledImage(baseX,baseY + sizeY - 3,70,-3, TextureResources.horizontalBar)); } modules.add(new ModuleButton(baseX - 3, baseY + sizeY, 0, "Select Planet", this, zmaster587.libVulpes.inventory.TextureResources.buttonBuild, sizeX + 6, 16)); //Status text modules.add(new ModuleText(baseX, baseY + sizeY + 20, "Core Status:", 0x1b1b1b)); boolean flag = isOnStation && getSpaceObject().getFuelAmount() >= getTravelCost() && getSpaceObject().hasUsableWarpCore(); flag = flag && !(isOnStation && (getSpaceObject().getDestOrbitingBody() == -1 || getSpaceObject().getOrbitingPlanetId() == getSpaceObject().getDestOrbitingBody())); canWarp = new ModuleText(baseX, baseY + sizeY + 30, (isOnStation && getSpaceObject().getOrbitingPlanetId() == getSpaceObject().getDestOrbitingBody()) ? "Nowhere to go" : flag ? "Ready!" : "Not ready", flag ? 0x1baa1b : 0xFF1b1b); modules.add(canWarp); modules.add(new ModuleProgress(baseX, baseY + sizeY + 40, 10, new IndicatorBarImage(70, 58, 53, 8, 122, 58, 5, 8, ForgeDirection.EAST, TextureResources.progressBars), this)); modules.add(new ModuleText(baseX + 82, baseY + sizeY + 20, "Fuel Cost:", 0x1b1b1b)); warpCost = getTravelCost(); //DEST planet baseX = 94; baseY = 20; sizeX = 70; sizeY = 70; ModuleButton warp = new ModuleButton(baseX - 3, baseY + sizeY,1, "Warp!", this , zmaster587.libVulpes.inventory.TextureResources.buttonBuild, sizeX + 6, 16); modules.add(warp); if(dimCache == null && isOnStation && station.getOrbitingPlanetId() != SpaceObjectManager.WARPDIMID ) dimCache = DimensionManager.getInstance().getDimensionProperties(station.getOrbitingPlanetId()); if(!worldObj.isRemote && isOnStation) { PacketHandler.sendToPlayer(new PacketSpaceStationInfo(getSpaceObject().getId(), getSpaceObject()), player); } if(worldObj.isRemote) { warpFuel.setText(flag ? String.valueOf(warpCost) : "N/A"); modules.add(warpFuel); modules.add(new ModuleScaledImage(baseX,baseY,sizeX,sizeY, zmaster587.libVulpes.inventory.TextureResources.starryBG)); if(dimCache != null) { if(worldObj.isRemote ) { modules.add(dstPlanetImg); modules.add(dstAtmo); } modules.add(new ModuleText(baseX + 4, baseY + 4, "Dest:", 0xFFFFFF)); modules.add(dstPlanetText); } else { modules.add(new ModuleText(baseX + 4, baseY + 4, "Dest:", 0xFFFFFF)); modules.add(dstPlanetText); } //Border modules.add(new ModuleScaledImage(baseX - 3,baseY,3,sizeY, TextureResources.verticalBar)); modules.add(new ModuleScaledImage(baseX + sizeX, baseY, -3,sizeY, TextureResources.verticalBar)); modules.add(new ModuleScaledImage(baseX,baseY,70,3, TextureResources.horizontalBar)); modules.add(new ModuleScaledImage(baseX,baseY + sizeY - 3,70,-3, TextureResources.horizontalBar)); } } else if (ID == guiId.MODULARFULLSCREEN.ordinal()) { //Open planet selector menu SpaceObject station = getSpaceObject(); int starId = 0; if(station != null) starId = station.getProperties().getParentProperties().getStar().getId(); container = new ModulePlanetSelector(starId, zmaster587.libVulpes.inventory.TextureResources.starryBG, this, true); container.setOffset(1000, 1000); modules.add(container); } return modules; } private void setPlanetModuleInfo() { ISpaceObject station = getSpaceObject(); boolean isOnStation = station != null; ResourceLocation location; boolean hasAtmo = true; String planetName; if(isOnStation) { DimensionProperties properties = DimensionManager.getInstance().getDimensionProperties(station.getOrbitingPlanetId()); location = properties.getPlanetIcon(); hasAtmo = properties.hasAtmosphere(); planetName = properties.getName(); } else { location = DimensionManager.getInstance().getDimensionProperties(worldObj.provider.dimensionId).getPlanetIcon(); planetName = DimensionManager.getInstance().getDimensionProperties(worldObj.provider.dimensionId).getName(); if(planetName.isEmpty()) planetName = "???"; } boolean flag = isOnStation && getSpaceObject().getFuelAmount() >= warpCost && getSpaceObject().hasUsableWarpCore(); if(canWarp != null) { flag = flag && !(isOnStation && (getSpaceObject().getDestOrbitingBody() == -1 || getSpaceObject().getOrbitingPlanetId() == getSpaceObject().getDestOrbitingBody())); canWarp.setText(isOnStation && srcPlanet == dstPlanet ? "Nowhere to go" : flag ? "Ready!" : "Not ready"); canWarp.setColor(flag ? 0x1baa1b : 0xFF1b1b); } if(worldObj.isRemote) { if(srcPlanetImg == null ) { //Source planet int baseX = 10; int baseY = 20; int sizeX = 70; int sizeY = 70; srcPlanetImg = new ModuleScaledImage(baseX + 10,baseY + 10,sizeX - 20, sizeY - 20, location); srcAtmo = new ModuleScaledImage(baseX + 10,baseY + 10,sizeX - 20, sizeY - 20,0.4f, DimensionProperties.getAtmosphereResource()); srcPlanetText = new ModuleText(baseX + 4, baseY + 16, "", 0xFFFFFF); warpFuel = new ModuleText(baseX + 82, baseY + sizeY + 30, "", 0x1b1b1b); //DEST planet baseX = 94; baseY = 20; sizeX = 70; sizeY = 70; dstPlanetImg = new ModuleScaledImage(baseX + 10,baseY + 10,sizeX - 20, sizeY - 20, location); dstAtmo = new ModuleScaledImage(baseX + 10,baseY + 10,sizeX - 20, sizeY - 20,0.4f, DimensionProperties.getAtmosphereResource()); dstPlanetText = new ModuleText(baseX + 4, baseY + 16, "", 0xFFFFFF); } srcPlanetImg.setResourceLocation(location); srcAtmo.setVisible(hasAtmo); srcPlanetText.setText(planetName); warpFuel.setText(warpCost < Integer.MAX_VALUE ? String.valueOf(warpCost) : "N/A"); DimensionProperties dstProps = null; if(isOnStation && station.getOrbitingPlanetId() != SpaceObjectManager.WARPDIMID ) dstProps = DimensionManager.getInstance().getDimensionProperties(dstPlanet); if(dstProps != null) { hasAtmo = dstProps.hasAtmosphere(); planetName = dstProps.getName(); location = dstProps.getPlanetIcon(); dstPlanetImg.setResourceLocation(location); dstAtmo.setVisible(hasAtmo); dstPlanetText.setText(planetName); dstPlanetImg.setVisible(true); dstAtmo.setVisible(true); } else { dstPlanetText.setText("???"); dstPlanetImg.setVisible(false); dstAtmo.setVisible(false); } } } @Override public String getModularInventoryName() { return "tile.stationmonitor.name"; } @Override public boolean canInteractWithContainer(EntityPlayer entity) { return true; } @Override public void onInventoryButtonPressed(int buttonId) { if(getSpaceObject() != null) { if(buttonId == 0) PacketHandler.sendToServer(new PacketMachine(this, (byte)0)); else if(buttonId == 1) { PacketHandler.sendToServer(new PacketMachine(this, (byte)2)); } } } @Override public void writeDataToNetwork(ByteBuf out, byte id) { if(id == 1 || id == 3) out.writeInt(container.getSelectedSystem()); } //TODO fix warp controller not sending @Override public void readDataFromNetwork(ByteBuf in, byte packetId, NBTTagCompound nbt) { if(packetId == 1 || packetId == 3) nbt.setInteger("id", in.readInt()); } @Override public void useNetworkData(EntityPlayer player, Side side, byte id, NBTTagCompound nbt) { if(id == 0) player.openGui(LibVulpes.instance, guiId.MODULARFULLSCREEN.ordinal(), worldObj, this.xCoord, this.yCoord, this.zCoord); else if(id == 1 || id == 3) { int dimId = nbt.getInteger("id"); container.setSelectedSystem(dimId); selectSystem(dimId); //Update known planets markDirty(); worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); if(id == 3) player.openGui(LibVulpes.instance, guiId.MODULARNOINV.ordinal(), worldObj, this.xCoord, this.yCoord, this.zCoord); } else if(id == 2) { SpaceObject station = getSpaceObject(); if(station != null && station.hasUsableWarpCore() && station.useFuel(getTravelCost()) != 0) { SpaceObjectManager.getSpaceManager().moveStationToBody(station, station.getDestOrbitingBody(), 200); for (Object plr : worldObj.playerEntities) { EntityPlayer player2 = (EntityPlayer)plr; if(SpaceObjectManager.getSpaceManager().getSpaceStationFromBlockCoords((int)player2.posX, (int)player2.posZ) == station) { player2.triggerAchievement(ARAchivements.givingItAllShesGot); if(!DimensionManager.hasReachedWarp) player2.triggerAchievement(ARAchivements.flightOfThePhoenix); } } DimensionManager.hasReachedWarp = true; for(BlockPosition vec : station.getWarpCoreLocations()) { TileEntity tile = worldObj.getTileEntity(vec.x, vec.y, vec.z); if(tile != null && tile instanceof TileWarpCore) { ((TileWarpCore)tile).onInventoryUpdated(); } } } } } @Override public void onSelectionConfirmed(Object sender) { //Container Cannot be null at this time onSelected(sender); PacketHandler.sendToServer(new PacketMachine(this, (byte)3)); } @Override public void onSelected(Object sender) { selectSystem(container.getSelectedSystem()); } private void selectSystem(int id) { if(getSpaceObject().getOrbitingPlanetId() == SpaceObjectManager.WARPDIMID) { dimCache = null; //return; } if(id == SpaceObjectManager.WARPDIMID) dimCache = null; else { dimCache = DimensionManager.getInstance().getDimensionProperties(container.getSelectedSystem()); ISpaceObject station = SpaceObjectManager.getSpaceManager().getSpaceStationFromBlockCoords(this.xCoord, this.zCoord); if(station != null) { station.setDestOrbitingBody(id); } } } @Override public void onSystemFocusChanged(Object sender) { PacketHandler.sendToServer(new PacketMachine(this, (byte)1)); } @Override public float getNormallizedProgress(int id) { //Screw it, the darn thing will stop updating inv in certain circumstances if(worldObj.isRemote) { setPlanetModuleInfo(); } return getProgress(id)/(float)getTotalProgress(id); } @Override public void setProgress(int id, int progress) { if(id == 10) if(getSpaceObject() != null) getSpaceObject().setFuelAmount(progress); } @Override public int getProgress(int id) { if(id == 10) { if(getSpaceObject() != null) return getSpaceObject().getFuelAmount(); } if(id == 0) return 30; else if(id == 1) return 30; else if(id == 2) return (int) 30; return 0; } @Override public int getTotalProgress(int id) { if(id == 10) { if(getSpaceObject() != null) return getSpaceObject().getMaxFuelAmount(); } if(dimCache == null) return 0; if(id == 0) return dimCache.getAtmosphereDensity()/2; else if(id == 1) return dimCache.orbitalDist/2; else if(id == 2) return (int) (dimCache.gravitationalMultiplier*50); return 0; } @Override public void setTotalProgress(int id, int progress) { } @Override public void setData(int id, int value) { //Id: 0, destination planet //Id: 1, source planet if(id == 2) { warpCost = value; } if(id == 1) srcPlanet = value; else if (id == 0) dstPlanet = value; setPlanetModuleInfo(); } @Override public int getData(int id) { if(id == 2) return getTravelCost(); ISpaceObject station = getSpaceObject(); boolean isOnStation = station != null; if(isOnStation) { if(id == 1) return station.getOrbitingPlanetId(); else //id == 1 return station.getDestOrbitingBody(); } return 0; } }