package zmaster587.advancedRocketry.entity; import io.netty.buffer.ByteBuf; import java.util.Iterator; import java.util.List; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import zmaster587.advancedRocketry.AdvancedRocketry; import zmaster587.advancedRocketry.api.Configuration; import zmaster587.advancedRocketry.api.IInfrastructure; import zmaster587.advancedRocketry.api.RocketEvent; import zmaster587.advancedRocketry.api.StatsRocket; import zmaster587.advancedRocketry.api.RocketEvent.RocketLaunchEvent; import zmaster587.advancedRocketry.api.atmosphere.AtmosphereRegister; import zmaster587.advancedRocketry.api.stations.ISpaceObject; import zmaster587.advancedRocketry.dimension.DimensionManager; import zmaster587.advancedRocketry.dimension.DimensionProperties; import zmaster587.advancedRocketry.mission.MissionGasCollection; import zmaster587.advancedRocketry.network.PacketSatellite; import zmaster587.advancedRocketry.stations.SpaceObjectManager; import zmaster587.advancedRocketry.util.StorageChunk; import zmaster587.libVulpes.inventory.modules.ModuleBase; import zmaster587.libVulpes.inventory.modules.ModuleButton; import zmaster587.libVulpes.inventory.modules.ModuleText; import zmaster587.libVulpes.network.PacketEntity; import zmaster587.libVulpes.network.PacketHandler; import zmaster587.libVulpes.util.BlockPosition; import zmaster587.libVulpes.util.Vector3F; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.util.ForgeDirection; public class EntityStationDeployedRocket extends EntityRocket { public ForgeDirection launchDirection; public ForgeDirection forwardDirection; public BlockPosition launchLocation; private ModuleText atmText; private short gasId; boolean coastMode; public EntityStationDeployedRocket(World world) { super(world); launchDirection = ForgeDirection.DOWN; launchLocation = new BlockPosition(0,0,0); atmText = new ModuleText(182, 114, "", 0x2d2d2d); gasId = 0; } public EntityStationDeployedRocket(World world, StorageChunk storage, StatsRocket stats, double x, double y, double z) { super(world, storage, stats, x,y,z); launchLocation = new BlockPosition((int)x,(int)y,(int)z); launchDirection = ForgeDirection.DOWN; stats.setSeatLocation(-1, -1, -1); //No seats atmText = new ModuleText(182, 114, "", 0x2d2d2d); gasId = 0; } //Use as a way of checking when chunk is unloaded @Override public void setDead() { super.setDead(); } @Override public void launch() { if(isInFlight()) return; if(isInOrbit()) { setInFlight(true); return; } if(getFuelAmount() < getFuelCapacity()) return; ISpaceObject spaceObj; if( worldObj.provider.dimensionId == Configuration.spaceDimId && (spaceObj = SpaceObjectManager.getSpaceManager().getSpaceStationFromBlockCoords((int)posX, (int)posZ)) != null && ((DimensionProperties)spaceObj.getProperties().getParentProperties()).isGasGiant() ) { //Abort if destination is invalid setInFlight(true); launchLocation.x = (int) Math.floor(this.posX); launchLocation.y = (short) this.posY; launchLocation.z = (int) Math.floor(this.posZ); Iterator<IInfrastructure> connectedTiles = connectedInfrastructure.iterator(); MinecraftForge.EVENT_BUS.post(new RocketLaunchEvent(this)); //Disconnect things linked to the rocket on liftoff while(connectedTiles.hasNext()) { IInfrastructure i = connectedTiles.next(); if(i.disconnectOnLiftOff()) { disconnectInfrastructure(i); connectedTiles.remove(); } } } } @Override public void onUpdate() { lastWorldTickTicked = worldObj.getTotalWorldTime(); if(isInFlight()) { boolean burningFuel = isBurningFuel(); if(launchLocation == null || storage == null) return; boolean isCoasting = Math.abs(this.posX - launchLocation.x) < 4*storage.getSizeX() && Math.abs(this.posY - launchLocation.y) < 4*storage.getSizeY() && Math.abs(this.posZ - launchLocation.z) < 4*storage.getSizeZ(); if(!isCoasting) { //Burn the rocket fuel //Spawn in the particle effects for the engines if(worldObj.isRemote && Minecraft.getMinecraft().gameSettings.particleSetting < 2) { for(Vector3F<Float> vec : stats.getEngineLocations()) { float xMult = Math.abs(forwardDirection.offsetX); float zMult = Math.abs(forwardDirection.offsetZ); float xVel, zVel; for(int i = 0; i < 4; i++) { xVel = (1-xMult)*((this.rand.nextFloat() - 0.5f)/8f) + xMult*-.15f; zVel = (1-zMult)*((this.rand.nextFloat() - 0.5f)/8f) + zMult*-.15f; AdvancedRocketry.proxy.spawnParticle("rocketFlame", worldObj, this.posX + vec.x + motionX, this.posY + vec.y, this.posZ +vec.z, xVel,(this.rand.nextFloat() - 0.5f)/8f, zVel + motionZ); } } } } if(forwardDirection == null) return; //Returning if(isInOrbit()) { //For unmanned rockets ForgeDirection dir; isCoasting = Math.abs(this.posX - launchLocation.x - (storage.getSizeX() % 2 == 0 ? 0 : 0.5f)) < 0.01 && Math.abs(this.posZ - launchLocation.z - (storage.getSizeZ() % 2 == 0 ? 0 : 0.5f)) < .01; if(isCoasting) { dir = launchDirection.getOpposite(); float speed = 0.075f; motionX = speed*dir.offsetX; motionY = speed*dir.offsetY; motionZ = speed*dir.offsetZ; } else { dir = forwardDirection.getOpposite(); float acc = 0.01f; motionX = acc*(launchLocation.x - this.posX + (storage.getSizeX() % 2 == 0 ? 0 : 0.5f)) + 0.01*dir.offsetX; motionY = 0;//acc*(launchLocation.y - this.posY) + 0.01*dir.offsetY; motionZ = acc*(launchLocation.z - this.posZ + (storage.getSizeZ() % 2 == 0 ? 0 : 0.5f)) + 0.01*dir.offsetZ; } if(this.posY > launchLocation.y ) { if(!worldObj.isRemote) { this.setInFlight(false); this.setInOrbit(false); MinecraftForge.EVENT_BUS.post(new RocketEvent.RocketLandedEvent(this)); //PacketHandler.sendToNearby(new PacketEntity(this, (byte)PacketType.ROCKETLANDEVENT.ordinal()), worldObj.provider.dimensionId, (int)posX, (int)posY, (int)posZ, 64); //PacketHandler.sendToPlayersTrackingEntity(new PacketEntity(this, (byte)PacketType.ROCKETLANDEVENT.ordinal()), this); } this.motionY = 0; this.setPosition(launchLocation.x + (storage.getSizeX() % 2 == 0 ? 0 : 0.5f), launchLocation.y, launchLocation.z + (storage.getSizeZ() % 2 == 0 ? 0 : 0.5f)); } } else { //Move out 4x the size of the rocket //Coast away from the station if(isCoasting) { float speed = 0.01f;//(float)Math.min(0.2f, Math.abs(motionY) + 0.0001f); motionX = speed*launchDirection.offsetX * ( 2.1*storage.getSizeX() - Math.abs(2*storage.getSizeX() - Math.abs(this.posX - launchLocation.x)) + 0.05); motionY = speed*launchDirection.offsetY * ( 2.1*storage.getSizeY() - Math.abs(2*storage.getSizeY() - Math.abs(this.posY - launchLocation.y)) + 0.05); motionZ = speed*launchDirection.offsetZ * ( 2.1*storage.getSizeZ() - Math.abs(2*storage.getSizeZ() - Math.abs(this.posZ - launchLocation.z)) + 0.05); } else { float acc = 0.01f; motionX += acc*forwardDirection.offsetX; motionY += acc*forwardDirection.offsetY; motionZ += acc*forwardDirection.offsetZ; } if(!worldObj.isRemote && this.getDistance(launchLocation.x, launchLocation.y, launchLocation.z) > 128) { onOrbitReached(); return; } } this.moveEntity(motionX, motionY, motionZ); } } @Override public List<ModuleBase> getModules(int ID, EntityPlayer player) { List<ModuleBase> modules; //If the rocket is flight don't load the interface modules = super.getModules(ID, player); Iterator<ModuleBase> itr = modules.iterator(); while(itr.hasNext()) { ModuleBase module = itr.next(); if(module instanceof ModuleButton && ((ModuleButton)module).getText().equalsIgnoreCase("Select Dst")) { itr.remove(); break; } } atmText.setText(AtmosphereRegister.getInstance().getHarvestableGasses().get(gasId).getLocalizedName()); modules.add(new ModuleButton(170, 114, 1, "", this, zmaster587.libVulpes.inventory.TextureResources.buttonLeft, 5, 8)); modules.add(atmText); modules.add(new ModuleButton(240, 114, 2, "", this, zmaster587.libVulpes.inventory.TextureResources.buttonRight, 5, 8)); return modules; } @Override @SideOnly(Side.CLIENT) public void onInventoryButtonPressed(int buttonId) { switch(buttonId) { case 0: PacketHandler.sendToServer(new PacketEntity(this, (byte)EntityRocket.PacketType.DECONSTRUCT.ordinal())); break; case 1: gasId++; if(gasId < 0) gasId = (short)(AtmosphereRegister.getInstance().getHarvestableGasses().size() - 1); else if(gasId > AtmosphereRegister.getInstance().getHarvestableGasses().size() - 1) gasId = 0; PacketHandler.sendToServer(new PacketEntity(this, (byte)EntityRocket.PacketType.MENU_CHANGE.ordinal())); break; case 2: gasId--; if(gasId < 0) gasId = (short)(AtmosphereRegister.getInstance().getHarvestableGasses().size() - 1); else if(gasId > AtmosphereRegister.getInstance().getHarvestableGasses().size() - 1) gasId = 0; PacketHandler.sendToServer(new PacketEntity(this, (byte)EntityRocket.PacketType.MENU_CHANGE.ordinal())); break; default: super.onInventoryButtonPressed(buttonId); } } /** * Called when the rocket reaches orbit */ public void onOrbitReached() { //make it 30 minutes with one drill if(this.isDead) return; //Check again to make sure we are around a gas giant ISpaceObject spaceObj; if( worldObj.provider.dimensionId == Configuration.spaceDimId || ((spaceObj = SpaceObjectManager.getSpaceManager().getSpaceStationFromBlockCoords((int)posX, (int)posZ)) != null && !((DimensionProperties)spaceObj.getProperties().getParentProperties()).isGasGiant() )) { //Abort if destination is invalid setInOrbit(true); this.setPosition(forwardDirection.offsetX*64d + this.launchLocation.x + (storage.getSizeX() % 2 == 0 ? 0 : 0.5d), posY, forwardDirection.offsetZ*64d + this.launchLocation.z + (storage.getSizeZ() % 2 == 0 ? 0 : 0.5d)); } //one intake with a 1 bucket tank should take 100 seconds float intakePower = (Integer)stats.getStatTag("intakePower"); MissionGasCollection miningMission = new MissionGasCollection(intakePower == 0 ? 360 : (long)(2*((int)stats.getStatTag("liquidCapacity")/intakePower)), this, connectedInfrastructure, AtmosphereRegister.getInstance().getHarvestableGasses().get(gasId)); DimensionProperties properties = DimensionManager.getInstance().getDimensionProperties(worldObj.provider.dimensionId).getParentProperties(); miningMission.setDimensionId(properties.getId()); properties.addSatallite(miningMission); if(!worldObj.isRemote) PacketHandler.sendToAll(new PacketSatellite(miningMission)); for(IInfrastructure i : connectedInfrastructure) { i.linkMission(miningMission); } this.setDead(); } @Override protected void writeNetworkableNBT(NBTTagCompound nbt) { super.writeNetworkableNBT(nbt); } @Override protected void readEntityFromNBT(NBTTagCompound nbt) { super.readEntityFromNBT(nbt); } @Override public void writeDataToNetwork(ByteBuf out, byte id) { super.writeDataToNetwork(out, id); if(id == PacketType.MENU_CHANGE.ordinal()) { out.writeShort(gasId); } else super.writeDataToNetwork(out, id); } @Override public void readDataFromNetwork(ByteBuf in, byte packetId, NBTTagCompound nbt) { if(packetId == PacketType.MENU_CHANGE.ordinal()) { nbt.setShort("gas", in.readShort()); } else super.readDataFromNetwork(in, packetId, nbt); } @Override public void useNetworkData(EntityPlayer player, Side side, byte id, NBTTagCompound nbt) { if(id == PacketType.MENU_CHANGE.ordinal()) { gasId = nbt.getShort("gas"); if(gasId < 0) gasId = (short)(AtmosphereRegister.getInstance().getHarvestableGasses().size() - 1); else if(gasId > AtmosphereRegister.getInstance().getHarvestableGasses().size() - 1) gasId = 0; if(!worldObj.isRemote) PacketHandler.sendToNearby(new PacketEntity(this, (byte) PacketType.MENU_CHANGE.ordinal()), worldObj.provider.dimensionId, (int)posX, (int)posY, (int)posZ, 64d); else atmText.setText(AtmosphereRegister.getInstance().getHarvestableGasses().get(gasId).getLocalizedName()); } else super.useNetworkData(player, side, id, nbt); } @Override public void writeMissionPersistantNBT(NBTTagCompound nbt) { // TODO Auto-generated method stub super.writeMissionPersistantNBT(nbt); nbt.setInteger("fwd", forwardDirection.ordinal()); nbt.setInteger("launchX", launchLocation.x); nbt.setInteger("launchY", launchLocation.y); nbt.setInteger("launchZ", launchLocation.z); nbt.setShort("gas", gasId); } @Override public void readMissionPersistantNBT(NBTTagCompound nbt) { super.readMissionPersistantNBT(nbt); forwardDirection = ForgeDirection.values()[nbt.getInteger("fwd")]; launchLocation.x = nbt.getInteger("launchX"); launchLocation.y = (short)nbt.getInteger("launchY"); launchLocation.z = nbt.getInteger("launchZ"); gasId = nbt.getShort("gas"); } }