void FromEVA(GameEvents.FromToAction <Part, Part> data) { String prop_name = Lib.EvaPropellantName(); // for each resource in the eva kerbal for (int i = 0; i < data.from.Resources.Count; ++i) { // get the resource PartResource res = data.from.Resources[i]; // add leftovers to the vessel data.to.RequestResource(res.resourceName, -res.amount); } // merge drives data Drive.Transfer(data.from.vessel, data.to.vessel, true); // forget vessel data DB.vessels.Remove(Lib.VesselID(data.from.vessel)); Drive.Purge(data.from.vessel); Cache.PurgeObjects(data.from.vessel); Cache.PurgeObjects(data.to.vessel); // execute script DB.Vessel(data.to.vessel).computer.Execute(data.to.vessel, ScriptType.eva_in); }
void FromEVA(GameEvents.FromToAction <Part, Part> data) { // contract configurator calls this event with both parts being the same when it adds a passenger if (data.from == data.to) { return; } String prop_name = Lib.EvaPropellantName(); // for each resource in the eva kerbal for (int i = 0; i < data.from.Resources.Count; ++i) { // get the resource PartResource res = data.from.Resources[i]; // add leftovers to the vessel data.to.RequestResource(res.resourceName, -res.amount); } // merge drives data Drive.Transfer(data.from.vessel, data.to.vessel, true); // forget EVA vessel data Cache.PurgeVesselCaches(data.from.vessel); //Drive.Purge(data.from.vessel); // update boarded vessel this.OnVesselModified(data.to.vessel); // execute script data.to.vessel.KerbalismData().computer.Execute(data.to.vessel, ScriptType.eva_in); }
public static void manageRescueMission(Vessel v) { // true if we detected this was a rescue mission vessel bool detected = false; // deal with rescue missions foreach (ProtoCrewMember c in Lib.CrewList(v)) { // get kerbal data KerbalData kd = DB.Kerbal(c.name); // flag the kerbal as not rescue at prelaunch if (v.situation == Vessel.Situations.PRELAUNCH) { kd.rescue = false; } // if the kerbal belong to a rescue mission if (kd.rescue) { // remember it detected = true; // flag the kerbal as non-rescue // note: enable life support mechanics for the kerbal kd.rescue = false; // show a message Message.Post(Lib.BuildString("We found <b>", c.name, "</b>"), Lib.BuildString((c.gender == ProtoCrewMember.Gender.Male ? "He" : "She"), "'s still alive!")); } } // gift resources if (detected) { var reslib = PartResourceLibrary.Instance.resourceDefinitions; var parts = Lib.GetPartsRecursively(v.rootPart); // give the vessel some propellant usable on eva string monoprop_name = Lib.EvaPropellantName(); double monoprop_amount = Lib.EvaPropellantCapacity(); foreach (var part in parts) { if (part.CrewCapacity > 0 || part.FindModuleImplementing <KerbalEVA>() != null) { if (Lib.Capacity(part, monoprop_name) <= double.Epsilon) { Lib.AddResource(part, monoprop_name, 0.0, monoprop_amount); } break; } } ResourceCache.Produce(v, monoprop_name, monoprop_amount); // give the vessel some supplies Profile.SetupRescue(v); } }
static bool Prefix() { if (Lib.EvaPropellantName() != "EVA Propellant") { return(false); } return(true); }
void ToEVA(GameEvents.FromToAction <Part, Part> data) { OnVesselModified(data.from.vessel); OnVesselModified(data.to.vessel); // get total crew in the origin vessel double tot_crew = Lib.CrewCount(data.from.vessel) + 1.0; // get vessel resources handler VesselResources resources = ResourceCache.Get(data.from.vessel); // setup supply resources capacity in the eva kerbal Profile.SetupEva(data.to); string evaPropName = Lib.EvaPropellantName(); // for each resource in the kerbal for (int i = 0; i < data.to.Resources.Count; ++i) { // get the resource PartResource res = data.to.Resources[i]; // eva prop is handled differently if (res.resourceName == evaPropName) { continue; } double quantity = Math.Min(resources.GetResource(data.from.vessel, res.resourceName).Amount / tot_crew, res.maxAmount); // remove resource from vessel quantity = data.from.RequestResource(res.resourceName, quantity); // add resource to eva kerbal data.to.RequestResource(res.resourceName, -quantity); } // Airlock loss resources.Consume(data.from.vessel, "Nitrogen", Settings.LifeSupportAtmoLoss, ResourceBroker.Generic); KerbalEVA kerbal = data.to.FindModuleImplementing <KerbalEVA>(); // turn off headlamp light, to avoid stock bug that show them for a split second when going on eva EVA.HeadLamps(kerbal, false); // execute script data.from.vessel.KerbalismData().computer.Execute(data.from.vessel, ScriptType.eva_out); // Start a coroutine for doing eva propellant resource transfers once the kerbal EVA is started (this is too early here) data.to.StartCoroutine(PostEVATweaks(data.from, data.to, evaPropName)); }
public static void Update(Vessel v) { // do nothing if not an eva kerbal if (!v.isEVA) return; // get KerbalEVA module KerbalEVA kerbal = Lib.FindModules<KerbalEVA>(v)[0]; Vessel_info vi = Cache.VesselInfo(v); // Stock KSP adds 5 units of monoprop to EVAs. We want to limit that amount // to whatever was available in the ship, so we don't magically create EVA prop out of nowhere if(Cache.HasVesselObjectsCache(v, "eva_prop")) { Lib.Log("### have eva_prop for " + v); var quantity = Cache.VesselObjectsCache<double>(v, "eva_prop"); Cache.RemoveVesselObjectsCache(v, "eva_prop"); Lib.Log("### adding " + quantity + " eva prop"); Lib.SetResource(kerbal.part, Lib.EvaPropellantName(), quantity, Lib.EvaPropellantCapacity()); } // get resource handler Resource_info ec = ResourceCache.Info(v, "ElectricCharge"); // determine if headlamps need ec // - not required if there is no EC capacity in eva kerbal (no ec supply in profile) // - not required if no EC cost for headlamps is specified (set by the user) bool need_ec = ec.capacity > double.Epsilon && Settings.HeadLampsCost > double.Epsilon; // consume EC for the headlamps if (need_ec && kerbal.lampOn) { ec.Consume(Settings.HeadLampsCost * Kerbalism.elapsed_s, "headlamp"); } // force the headlamps on/off HeadLamps(kerbal, kerbal.lampOn && (!need_ec || ec.amount > double.Epsilon)); // if dead if (IsDead(v)) { // enforce freezed state Freeze(kerbal); // disable modules DisableModules(kerbal); // remove plant flag action kerbal.flagItems = 0; } }
void ToEVA(GameEvents.FromToAction <Part, Part> data) { // get total crew in the origin vessel double tot_crew = (double)Lib.CrewCount(data.from.vessel) + 1.0; // get vessel resources handler Vessel_resources resources = ResourceCache.Get(data.from.vessel); // setup supply resources capacity in the eva kerbal Profile.SetupEva(data.to); // for each resource in the kerbal for (int i = 0; i < data.to.Resources.Count; ++i) { // get the resource PartResource res = data.to.Resources[i]; // determine quantity to take double quantity = Math.Min(resources.Info(data.from.vessel, res.resourceName).amount / tot_crew, res.maxAmount); // remove resource from vessel quantity = data.from.RequestResource(res.resourceName, quantity); // add resource to eva kerbal data.to.RequestResource(res.resourceName, -quantity); } // show warning if there isn't monoprop in the eva suit string prop_name = Lib.EvaPropellantName(); if (Lib.Amount(data.to, prop_name) <= double.Epsilon && !Lib.Landed(data.from.vessel)) { Message.Post(Severity.danger, Lib.BuildString("There isn't any <b>", prop_name, "</b> in the EVA suit"), "Don't let the ladder go!"); } // turn off headlamp light, to avoid stock bug that show them for a split second when going on eva KerbalEVA kerbal = data.to.FindModuleImplementing <KerbalEVA>(); EVA.HeadLamps(kerbal, false); // execute script DB.Vessel(data.from.vessel).computer.Execute(data.from.vessel, ScriptType.eva_out); }
void ToEVA(GameEvents.FromToAction <Part, Part> data) { OnVesselModified(data.from.vessel); OnVesselModified(data.to.vessel); // get total crew in the origin vessel double tot_crew = Lib.CrewCount(data.from.vessel) + 1.0; // get vessel resources handler VesselResources resources = ResourceCache.Get(data.from.vessel); // setup supply resources capacity in the eva kerbal Profile.SetupEva(data.to); String prop_name = Lib.EvaPropellantName(); // for each resource in the kerbal for (int i = 0; i < data.to.Resources.Count; ++i) { // get the resource PartResource res = data.to.Resources[i]; // eva prop is handled differently if (res.resourceName == prop_name) { continue; } double quantity = Math.Min(resources.GetResource(data.from.vessel, res.resourceName).Amount / tot_crew, res.maxAmount); // remove resource from vessel quantity = data.from.RequestResource(res.resourceName, quantity); // add resource to eva kerbal data.to.RequestResource(res.resourceName, -quantity); } // take as much of the propellant as possible. just imagine: there are 1.3 units left, and 12 occupants // in the ship. you want to send out an engineer to fix the chemical plant that produces monoprop, // and have to get from one end of the station to the other with just 0.1 units in the tank... // nope. double evaPropQuantity = data.from.RequestResource(prop_name, Lib.EvaPropellantCapacity()); // We can't just add the monoprop here, because that doesn't always work. It might be related // to the fact that stock KSP wants to add 5 units of monoprop to new EVAs. Instead of fighting KSP here, // we just let it do it's thing and set our amount later in EVA.cs - which seems to work just fine. // don't put that into Cache.VesselInfo because that can be deleted before we get there Cache.SetVesselObjectsCache(data.to.vessel, "eva_prop", evaPropQuantity); // Airlock loss resources.Consume(data.from.vessel, "Nitrogen", Settings.LifeSupportAtmoLoss, ResourceBroker.Generic); // show warning if there is little or no EVA propellant in the suit if (evaPropQuantity <= 0.05 && !Lib.Landed(data.from.vessel)) { Message.Post(Severity.danger, Local.CallBackMsg_EvaNoMP.Format("<b>" + prop_name + "</b>"), Local.CallBackMsg_EvaNoMP2); //Lib.BuildString("There isn't any <<1>> in the EVA suit")"Don't let the ladder go!" } // turn off headlamp light, to avoid stock bug that show them for a split second when going on eva KerbalEVA kerbal = data.to.FindModuleImplementing <KerbalEVA>(); EVA.HeadLamps(kerbal, false); // execute script data.from.vessel.KerbalismData().computer.Execute(data.from.vessel, ScriptType.eva_out); }
void FromEVA(GameEvents.FromToAction <Part, Part> data) { // contract configurator calls this event with both parts being the same when it adds a passenger if (data.from == data.to) { return; } // for each resource in the eva kerbal for (int i = 0; i < data.from.Resources.Count; ++i) { // get the resource PartResource res = data.from.Resources[i]; // add leftovers to the vessel data.to.RequestResource(res.resourceName, -res.amount); } #if !KSP15_16 && !KSP17 && !KSP18 && !KSP110 string evaPropName = Lib.EvaPropellantName(); if (evaPropName != "EVA Propellant") { KerbalEVA kerbalEVA = data.from.FindModuleImplementing <KerbalEVA>(); List <ProtoPartResourceSnapshot> propContainers = new List <ProtoPartResourceSnapshot>(); if (kerbalEVA.ModuleInventoryPartReference != null) { foreach (StoredPart storedPart in kerbalEVA.ModuleInventoryPartReference.storedParts.Values) { ProtoPartResourceSnapshot propContainer = storedPart.snapshot.resources.Find(p => p.resourceName == evaPropName); if (propContainer != null && propContainer.amount > 0.0) { propContainers.Add(propContainer); } } } if (propContainers.Count > 0) { // get vessel resources handler ResourceInfo evaPropOnVessel = ResourceCache.GetResource(data.to.vessel, evaPropName); double storageAvailable = evaPropOnVessel.Capacity - evaPropOnVessel.Amount; foreach (ProtoPartResourceSnapshot propContainer in propContainers) { double stored = Math.Min(propContainer.amount, storageAvailable); storageAvailable -= stored; evaPropOnVessel.Produce(stored, ResourceBroker.Generic); propContainer.amount = Math.Max(propContainer.amount - stored, 0.0); if (storageAvailable <= 0.0) { break; } } // Explaination : // - The ProtoCrewMember has already been removed from the EVA part and added to the vessel part // - It's inventory has already been saved // - The stock ModuleInventoryPart.RefillEVAPropellantOnBoarding() method has already been called // So to set the correct amount of EVA prop, we : // - Harmony patch ModuleInventoryPart.RefillEVAPropellantOnBoarding() so it doesn't refill anything // - Grab the ProtoCrewMember on the vessel part // - Call the SaveInventory() method again, with the modified amount on the inventory StoredPart data.to.protoModuleCrew[data.to.protoModuleCrew.Count - 1].SaveInventory(kerbalEVA.ModuleInventoryPartReference); } } #endif // merge drives data Drive.Transfer(data.from.vessel, data.to.vessel, true); // forget EVA vessel data Cache.PurgeVesselCaches(data.from.vessel); //Drive.Purge(data.from.vessel); // update boarded vessel this.OnVesselModified(data.to.vessel); // execute script data.to.vessel.KerbalismData().computer.Execute(data.to.vessel, ScriptType.eva_in); }