Beispiel #1
0
 public void prepareResourceList(StoredVessel sv)
 {
     if (resourceTransferList.Count > 0)
     {
         return;
     }
     foreach (var r in sv.resources.resourcesNames)
     {
         if (hangarResources.ResourceCapacity(r) == 0)
         {
             continue;
         }
         ResourceManifest rm = new ResourceManifest();
         rm.name          = r;
         rm.amount        = sv.resources.ResourceAmount(r);
         rm.capacity      = sv.resources.ResourceCapacity(r);
         rm.offset        = rm.amount;
         rm.host_amount   = hangarResources.ResourceAmount(r);
         rm.host_capacity = hangarResources.ResourceCapacity(r);
         rm.pool          = rm.host_amount + rm.offset;
         rm.minAmount     = Math.Max(0, rm.pool - rm.host_capacity);
         rm.maxAmount     = Math.Min(rm.pool, rm.capacity);
         resourceTransferList.Add(rm);
     }
 }
Beispiel #2
0
 public void transferResources(StoredVessel sv)
 {
     if (resourceTransferList.Count == 0)
     {
         return;
     }
     foreach (var r in resourceTransferList)
     {
         //transfer resource between hangar and protovessel
         var a = hangarResources.TransferResource(r.name, r.offset - r.amount);
         a = r.amount - r.offset + a;
         var b = sv.resources.TransferResource(r.name, a);
         hangarResources.TransferResource(r.name, b);
         //update masses
         PartResourceDefinition res_def = PartResourceLibrary.Instance.GetDefinition(r.name);
         if (res_def.density == 0)
         {
             continue;
         }
         float dM = (float)a * res_def.density;
         float dC = (float)a * res_def.unitCost;
         vessels_mass += dM;
         vessels_cost += dC;
         sv.mass      += dM;
         sv.cost      += dC;
         set_part_params();
     }
     resourceTransferList.Clear();
 }
Beispiel #3
0
        public void TryRestoreVessel(StoredVessel stored_vessel)
        {
            if (!can_restore())
            {
                return;
            }
            ScreenMessager.showMessage(string.Format("Launching {0}...", stored_vessel.vessel.vesselName), 3);
            //clean up
            stored_vessels.Remove(stored_vessel.vessel.vesselID);
            //switch hangar state
            hangar_state = HangarState.Inactive;
            //transfer resources
            transferResources(stored_vessel);
            //set restored vessel orbit
            GetLaunchTransform();
            position_vessel(stored_vessel);
            //restore vessel
            stored_vessel.Load();
            //get restored vessel from the world
            launched_vessel = stored_vessel.vessel.vesselRef;
            //transfer crew back to the launched vessel
            List <ProtoCrewMember> crew_to_transfer = CrewTransfer.delCrew(vessel, stored_vessel.crew);

            //change volume and mass
            change_part_params(stored_vessel.metric, -1f);
            //switch to restored vessel
            FlightGlobals.ForceSetActiveVessel(launched_vessel);
            SetupVessel(new LaunchedVessel(stored_vessel, launched_vessel, crew_to_transfer, part.flightID));
        }
Beispiel #4
0
 //build dropdown list of stored vessels
 void BuildVesselList(Hangar hangar)
 {
     //reset stat
     vessels.Clear();
     vessel_list.Items = new List <string>();
     selected_vessel   = null;
     //check hangar
     if (hangar == null)
     {
         return;
     }
     //build new list
     vessels = hangar.GetVessels();
     if (vessels.Count > 0)
     {
         selected_vessel = vessels.Find(v => v.vessel.vesselID == vessel_id);
         if (selected_vessel == null)
         {
             selected_vessel = vessels[0];
         }
         var vessel_names = new List <string>();
         for (int i = 0; i < vessels.Count; i++)
         {
             vessel_names.Add(string.Format("{0} {1}", i + 1, vessels[i].vessel.vesselName));
         }
         vessel_list.Items = vessel_names;
         vessel_list.SelectItem(vessels.IndexOf(selected_vessel));
     }
 }
Beispiel #5
0
 public LaunchedVessel(StoredVessel sv, Vessel vsl, List<ProtoCrewMember> crew, uint hangar_id)
     : base(vsl)
 {
     this.sv = sv;
     this.crew = crew;
     this.hangar_id = hangar_id;
 }
Beispiel #6
0
 public LaunchedVessel(StoredVessel sv, Vessel vsl, List <ProtoCrewMember> crew, uint hangar_id)
     : base(vsl)
 {
     this.sv        = sv;
     this.crew      = crew;
     this.hangar_id = hangar_id;
 }
Beispiel #7
0
 void Select_Vessel(StoredVessel vsl)
 {
     vessel_id = vsl.vessel.vesselID;
     vessel_list.SelectItem(vessels.IndexOf(vsl));
     if (vsl != selected_vessel)
     {
         selected_hangar.resourceTransferList.Clear();
     }
     selected_vessel = vsl;
 }
Beispiel #8
0
        //store vessel
        void store_vessel(Vessel vsl, bool perform_checks = true)
        {
            StoredVessel stored_vessel = new StoredVessel();

            if (perform_checks)            //for normal operation
            {
                //check momentary states
                if (!can_store(vsl))
                {
                    return;
                }
                //check if the vessel can be stored, if unknown, try to store
                bool storable;
                if (!probed_ids.TryGetValue(vsl.id, out storable))
                {
                    stored_vessel = try_store(vsl);
                    storable      = stored_vessel != null;
                    probed_ids.Add(vsl.id, storable);
                }
                if (!storable)
                {
                    return;
                }
            }
            else             //for storing packed constructs upon hangar launch
            {
                stored_vessel = new StoredVessel(vsl);
                stored_vessels.ForceAdd(stored_vessel);
            }
            //get vessel crew on board
            List <ProtoCrewMember> _crew = new List <ProtoCrewMember>(stored_vessel.crew);

            CrewTransfer.delCrew(vsl, _crew);
            vsl.DespawnCrew();
            //first of, add crew to the hangar if there's a place
            CrewTransfer.addCrew(part, _crew);
            //then add to other vessel parts if needed
            CrewTransfer.addCrew(vessel, _crew);
            //recalculate volume and mass
            change_part_params(stored_vessel.metric);
            //switch to hangar vessel before storing
            if (FlightGlobals.ActiveVessel.id == vsl.id)
            {
                FlightGlobals.ForceSetActiveVessel(vessel);
            }
            //destroy vessel
            vsl.Die();
            ScreenMessager.showMessage("Vessel has been docked inside the hangar", 3);
        }
Beispiel #9
0
        /// <summary>
        /// Set vessel orbit, transform, coordinates.
        /// </summary>
        /// <param name="sv">Stored vessel</param>
        void position_vessel(StoredVessel sv)
        {
            ProtoVessel pv = sv.vessel;

            //state
            pv.splashed = vessel.Landed;
            pv.landed   = vessel.Splashed;
            //rotation
            //it is essential to use BackupVessel() instead of vessel.protoVessel,
            //because in general the latter does not store the current flight state of the vessel
            ProtoVessel hpv        = vessel.BackupVessel();
            Quaternion  proto_rot  = hpv.rotation;
            Quaternion  hangar_rot = vessel.vesselTransform.rotation;

            //rotate launchTransform.rotation to protovessel's reference frame
            pv.rotation = proto_rot * hangar_rot.Inverse() * launchTransform.rotation;
            //calculate launch offset from vessel bounds
            Vector3 bounds_offset = launchTransform.TransformDirection(sv.CoM - sv.CoG);
            //set vessel's orbit
            Orbit    horb  = vessel.orbit;
            Orbit    vorb  = new Orbit();
            Vector3  d_pos = launchTransform.position - vessel.findWorldCenterOfMass() + bounds_offset;
            Vector3d vpos  = horb.pos + new Vector3d(d_pos.x, d_pos.z, d_pos.y);

            vorb.UpdateFromStateVectors(vpos, horb.vel, horb.referenceBody, Planetarium.GetUniversalTime());
            pv.orbitSnapShot = new OrbitSnapshot(vorb);
            //position on a surface
            if (vessel.LandedOrSplashed)
            {
                //calculate launch offset from vessel bounds
                bounds_offset = launchTransform.TransformDirection(-sv.CoG);
                //set vessel's position
                vpos         = Vector3d.zero + launchTransform.position + bounds_offset;
                pv.longitude = vessel.mainBody.GetLongitude(vpos);
                pv.latitude  = vessel.mainBody.GetLatitude(vpos);
                pv.altitude  = vessel.mainBody.GetAltitude(vpos);
            }
        }
Beispiel #10
0
        StoredVessel try_store(Vessel vsl)
        {
            //check vessel crew
            if (vsl.GetCrewCount() > vessel.GetCrewCapacity() - vessel.GetCrewCount())
            {
                ScreenMessager.showMessage("Not enough space for the crew of a docking vessel", 3);
                return(null);
            }
            //check vessel metrics
            GetLaunchTransform();
            StoredVessel sv = new StoredVessel(vsl);

            if (!sv.metric.FitsAligned(launchTransform, part.partTransform, hangar_metric))
            {
                ScreenMessager.showMessage("The vessel does not fit into this hangar", 3);
                return(null);
            }
            if (!stored_vessels.Add(sv))
            {
                ScreenMessager.showMessage("There's no room in the hangar for this vessel", 3);
                return(null);
            }
            return(sv);
        }
Beispiel #11
0
 protected abstract Vector3 get_vessel_offset(Transform launch_transform, StoredVessel sv);
Beispiel #12
0
 protected virtual void on_vessel_launch(StoredVessel sv)
 {
 }
Beispiel #13
0
 void load_vessel(StoredVessel sv)
 {
     sv.proto_vessel.Load(HighLogic.CurrentGame.flightState);
     StartCoroutine(wait_for_launched_vessel(sv.vessel));
 }
Beispiel #14
0
 StoredVessel try_store(Vessel vsl)
 {
     //check vessel crew
     if(vsl.GetCrewCount() > vessel.GetCrewCapacity()-vessel.GetCrewCount())
     {
         ScreenMessager.showMessage("Not enough space for the crew of a docking vessel", 3);
         return null;
     }
     //check vessel metrics
     GetLaunchTransform();
     StoredVessel sv = new StoredVessel(vsl);
     if(!sv.metric.FitsAligned(launchTransform, part.partTransform, hangar_metric))
     {
         ScreenMessager.showMessage("The vessel does not fit into this hangar", 3);
         return null;
     }
     if(!stored_vessels.Add(sv))
     {
         ScreenMessager.showMessage("There's no room in the hangar for this vessel", 3);
         return null;
     }
     return sv;
 }
Beispiel #15
0
 StoredVessel try_store_vessel(Vessel vsl)
 {
     //check vessel crew
     var vsl_crew = vsl.GetCrewCount();
     if(NoCrewTransfers && vsl_crew > 0)
     {
         ScreenMessager.showMessage("Crew cannot enter through this hangar. Leave your ship before docking.");
         return null;
     }
     if(vsl_crew > vessel.GetCrewCapacity()-vessel.GetCrewCount())
     {
         ScreenMessager.showMessage("Not enough space for the crew of a docking vessel");
         return null;
     }
     //check vessel metrics
     var sv = new StoredVessel(vsl, Storage.ComputeHull);
     return try_store_vessel(sv) ? sv : null;
 }
Beispiel #16
0
 public static void SelectVessel(StoredVessel vsl)
 {
     instance.Select_Vessel(vsl);
 }
Beispiel #17
0
 void onVesselGoOffRails(Vessel vsl)
 {
     if(launched_vessel == null) return;
     if(launched_vessel.vessel != vsl) return;
     launched_vessel = null;
     FlightGlobals.ForceSetActiveVessel(vsl);
 }
Beispiel #18
0
 public void TryRestoreVessel(StoredVessel stored_vessel)
 {
     if(!can_restore()) return;
     ScreenMessager.showMessage(string.Format("Launching {0}...", stored_vessel.vessel.vesselName), 3);
     //clean up
     stored_vessels.Remove(stored_vessel.vessel.vesselID);
     //switch hangar state
     hangar_state = HangarState.Inactive;
     //transfer resources
     transferResources(stored_vessel);
     //set restored vessel orbit
     GetLaunchTransform();
     position_vessel(stored_vessel);
     //restore vessel
     stored_vessel.Load();
     //get restored vessel from the world
     launched_vessel = stored_vessel.vessel.vesselRef;
     //transfer crew back to the launched vessel
     List<ProtoCrewMember> crew_to_transfer = CrewTransfer.delCrew(vessel, stored_vessel.crew);
     //change volume and mass
     change_part_params(stored_vessel.metric, -1f);
     //switch to restored vessel
     FlightGlobals.ForceSetActiveVessel(launched_vessel);
     SetupVessel(new LaunchedVessel(stored_vessel, launched_vessel, crew_to_transfer, part.flightID));
 }
Beispiel #19
0
 public void transferResources(StoredVessel sv)
 {
     if(resourceTransferList.Count == 0) return;
     foreach(var r in resourceTransferList)
     {
         //transfer resource between hangar and protovessel
         var a = hangarResources.TransferResource(r.name, r.offset-r.amount);
         a = r.amount-r.offset + a;
         var b = sv.resources.TransferResource(r.name, a);
         hangarResources.TransferResource(r.name, b);
         //update masses
         PartResourceDefinition res_def = PartResourceLibrary.Instance.GetDefinition(r.name);
         if(res_def.density == 0) continue;
         float dM = (float)a*res_def.density;
         float dC = (float)a*res_def.unitCost;
         vessels_mass += dM;
         vessels_cost += dC;
         sv.mass += dM;
         sv.cost += dC;
         set_part_params();
     }
     resourceTransferList.Clear();
 }
Beispiel #20
0
 public void prepareResourceList(StoredVessel sv)
 {
     if(resourceTransferList.Count > 0) return;
     foreach(var r in sv.resources.resourcesNames)
     {
         if(hangarResources.ResourceCapacity(r) == 0) continue;
         ResourceManifest rm = new ResourceManifest();
         rm.name          = r;
         rm.amount        = sv.resources.ResourceAmount(r);
         rm.capacity      = sv.resources.ResourceCapacity(r);
         rm.offset        = rm.amount;
         rm.host_amount   = hangarResources.ResourceAmount(r);
         rm.host_capacity = hangarResources.ResourceCapacity(r);
         rm.pool          = rm.host_amount + rm.offset;
         rm.minAmount     = Math.Max(0, rm.pool-rm.host_capacity);
         rm.maxAmount     = Math.Min(rm.pool, rm.capacity);
         resourceTransferList.Add(rm);
     }
 }
Beispiel #21
0
 public void TryRestoreVessel(StoredVessel stored_vessel)
 {
     if(!can_restore(stored_vessel)) return;
     //clean up
     if(!Storage.RemoveVessel(stored_vessel))
     {
         ScreenMessager.showMessage("WARNING: restored vessel is not found in the Stored Vessels: {0}\n" +
             "This should never happen!", stored_vessel.id);
         return;
     }
     ScreenMessager.showMessage("Launching \"{0}\"...", stored_vessel.name);
     //switch hangar state
     Deactivate();
     //transfer resources
     transferResources(stored_vessel);
     //set restored vessel orbit
     position_vessel(stored_vessel);
     //let child classes make their modifications
     on_vessel_launch(stored_vessel);
     //transfer crew back to the launched vessel
     List<ProtoCrewMember> crew_to_transfer = CrewTransfer.delCrew(vessel, stored_vessel.crew);
     CrewTransfer.addCrew(stored_vessel.proto_vessel, crew_to_transfer);
     //restore vessel
     launched_vessel = stored_vessel;
     load_vessel(stored_vessel);
 }
Beispiel #22
0
 protected override Vector3 get_vessel_offset(Transform launch_transform, StoredVessel sv)
 {
     return vessel.LandedOrSplashed ?
         launch_transform.TransformDirection(-sv.CoG + Vector3.up*sv.size.y/2) :
         launch_transform.TransformDirection(sv.CoM - sv.CoG + Vector3.up*sv.size.y/2);
 }
Beispiel #23
0
 /// <summary>
 /// Set vessel orbit, transform, coordinates.
 /// </summary>
 /// <param name="sv">Stored vessel</param>
 void position_vessel(StoredVessel sv)
 {
     ProtoVessel pv = sv.vessel;
     //state
     pv.splashed = vessel.Landed;
     pv.landed   = vessel.Splashed;
     //rotation
     //it is essential to use BackupVessel() instead of vessel.protoVessel,
     //because in general the latter does not store the current flight state of the vessel
     ProtoVessel hpv = vessel.BackupVessel();
     Quaternion proto_rot  = hpv.rotation;
     Quaternion hangar_rot = vessel.vesselTransform.rotation;
     //rotate launchTransform.rotation to protovessel's reference frame
     pv.rotation = proto_rot*hangar_rot.Inverse()*launchTransform.rotation;
     //calculate launch offset from vessel bounds
     Vector3 bounds_offset = launchTransform.TransformDirection(sv.CoM - sv.CoG);
     //set vessel's orbit
     Orbit horb = vessel.orbit;
     Orbit vorb = new Orbit();
     Vector3 d_pos = launchTransform.position-vessel.findWorldCenterOfMass()+bounds_offset;
     Vector3d vpos = horb.pos+new Vector3d(d_pos.x, d_pos.z, d_pos.y);
     vorb.UpdateFromStateVectors(vpos, horb.vel, horb.referenceBody, Planetarium.GetUniversalTime());
     pv.orbitSnapShot = new OrbitSnapshot(vorb);
     //position on a surface
     if(vessel.LandedOrSplashed)
     {
         //calculate launch offset from vessel bounds
         bounds_offset = launchTransform.TransformDirection(-sv.CoG);
         //set vessel's position
         vpos = Vector3d.zero+launchTransform.position+bounds_offset;
         pv.longitude  = vessel.mainBody.GetLongitude(vpos);
         pv.latitude   = vessel.mainBody.GetLatitude(vpos);
         pv.altitude   = vessel.mainBody.GetAltitude(vpos);
     }
 }
Beispiel #24
0
 /// <summary>
 /// Set vessel orbit, transform, coordinates.
 /// </summary>
 /// <param name="sv">Stored vessel</param>
 void position_vessel(StoredVessel sv)
 {
     var pv = sv.proto_vessel;
     //state
     pv.splashed = vessel.Splashed;
     pv.landed   = vessel.Landed;
     pv.landedAt = vessel.landedAt;
     //rotation
     //rotate spawn_transform.rotation to protovessel's reference frame
     var spawn_transform = get_spawn_transform(sv);
     pv.rotation = vessel.mainBody.bodyTransform.rotation.Inverse() * spawn_transform.rotation;
     //set vessel's orbit
     var UT    = Planetarium.GetUniversalTime();
     var horb  = vessel.orbitDriver.orbit;
     var vorb  = new Orbit();
     var d_pos = spawn_transform.position-vessel.CurrentCoM+get_vessel_offset(spawn_transform, sv);
     var vpos  = horb.pos - horb.GetRotFrameVel(horb.referenceBody)*TimeWarp.fixedDeltaTime + new Vector3d(d_pos.x, d_pos.z, d_pos.y);
     var vvel  = horb.vel;
     if(LaunchWithPunch && LaunchVelocity != Vector3.zero)
     {
         //honor the momentum conservation law
         //:calculate launched vessel velocity
         var hM = vessel.GetTotalMass();
         var tM = hM + sv.mass;
         var d_vel = part.transform.TransformDirection(LaunchVelocity);
         vvel += (Vector3d.zero + d_vel*hM/tM).xzy;
         //:calculate hangar's vessel velocity
         deltaV = d_vel*(-sv.mass)/tM;
         change_velocity = true;
     }
     vorb.UpdateFromStateVectors(vpos, vvel, horb.referenceBody, UT);
     pv.orbitSnapShot = new OrbitSnapshot(vorb);
     //position on a surface
     if(vessel.LandedOrSplashed)
     {
         vpos = spawn_transform.position+get_vessel_offset(spawn_transform, sv);
         pv.longitude = vessel.mainBody.GetLongitude(vpos);
         pv.latitude  = vessel.mainBody.GetLatitude(vpos);
         pv.altitude  = vessel.mainBody.GetAltitude(vpos);
     }
 }
Beispiel #25
0
 //store vessel
 void store_vessel(Vessel vsl, bool perform_checks = true)
 {
     StoredVessel stored_vessel = new StoredVessel();
     if(perform_checks) //for normal operation
     {
         //check momentary states
         if(!can_store(vsl))
             return;
         //check if the vessel can be stored, if unknown, try to store
         bool storable;
         if(!probed_ids.TryGetValue(vsl.id, out storable))
         {
             stored_vessel = try_store(vsl);
             storable = stored_vessel != null;
             probed_ids.Add(vsl.id, storable);
         }
         if(!storable) return;
     }
     else //for storing packed constructs upon hangar launch
     {
         stored_vessel = new StoredVessel(vsl);
         stored_vessels.ForceAdd(stored_vessel);
     }
     //get vessel crew on board
     List<ProtoCrewMember> _crew = new List<ProtoCrewMember>(stored_vessel.crew);
     CrewTransfer.delCrew(vsl, _crew);
     vsl.DespawnCrew();
     //first of, add crew to the hangar if there's a place
     CrewTransfer.addCrew(part, _crew);
     //then add to other vessel parts if needed
     CrewTransfer.addCrew(vessel, _crew);
     //recalculate volume and mass
     change_part_params(stored_vessel.metric);
     //switch to hangar vessel before storing
     if(FlightGlobals.ActiveVessel.id == vsl.id)
         FlightGlobals.ForceSetActiveVessel(vessel);
     //destroy vessel
     vsl.Die();
     ScreenMessager.showMessage("Vessel has been docked inside the hangar", 3);
 }
Beispiel #26
0
 protected override void on_vessel_launch(StoredVessel sv)
 {
     sv.crew.Clear();
     sv.crew.AddRange(part.protoModuleCrew);
     //transfer the target and controls
     var this_vsl = vessel.BackupVessel();
     sv.proto_vessel.targetInfo   = this_vsl.targetInfo;
     sv.proto_vessel.ctrlState    = this_vsl.ctrlState;
     sv.proto_vessel.actionGroups = this_vsl.actionGroups;
     //transfer the flight plan
     if(vessel.patchedConicSolver != null &&
         vessel.patchedConicSolver.maneuverNodes.Count > 0)
     {
         var nearest_node = vessel.patchedConicSolver.maneuverNodes[0];
         var new_orbit = sv.proto_vessel.orbitSnapShot.Load();
         var vvel = new_orbit.getOrbitalVelocityAtUT(nearest_node.UT).xzy;
         var vpos = new_orbit.getPositionAtUT(nearest_node.UT).xzy;
         nearest_node.nodeRotation = Quaternion.LookRotation(vvel, Vector3d.Cross(-vpos, vvel));
         nearest_node.DeltaV = nearest_node.nodeRotation.Inverse() * (nearest_node.nextPatch.getOrbitalVelocityAtUT(nearest_node.UT).xzy-vvel);
         sv.proto_vessel.flightPlan.ClearData();
         vessel.patchedConicSolver.Save(sv.proto_vessel.flightPlan);
         vessel.patchedConicSolver.maneuverNodes.Clear();
         vessel.patchedConicSolver.flightPlan.Clear();
     }
     jettison_fairings();
     //turn everything off
     Storage.enabled = Storage.isEnabled = false;
     Events["LaunchVessel"].active = Actions["LaunchVesselAction"].active = false;
     //this event is catched by FlightLogger
     GameEvents.onStageSeparation.Fire(new EventReport(FlightEvents.STAGESEPARATION, part, null, null, Staging.CurrentStage, string.Empty));
 }