protected override void OnLoad(ConfigNode configNode) { base.OnLoad(configNode); foreach (ConfigNode child in configNode.GetNodes("KERBAL_DETAIL")) { // Read all the orbit data KerbalData kd = new KerbalData(); kd.body = ConfigNodeUtil.ParseValue <CelestialBody>(child, "body"); kd.latitude = ConfigNodeUtil.ParseValue <double>(child, "lat"); kd.longitude = ConfigNodeUtil.ParseValue <double>(child, "lon"); kd.altitude = ConfigNodeUtil.ParseValue <double?>(child, "alt", (double?)null); kd.landed = ConfigNodeUtil.ParseValue <bool>(child, "landed"); kd.owned = ConfigNodeUtil.ParseValue <bool>(child, "owned"); kd.addToRoster = ConfigNodeUtil.ParseValue <bool>(child, "addToRoster"); if (child.HasNode("ORBIT")) { kd.orbit = new OrbitSnapshot(child.GetNode("ORBIT")).Load(); } // Load the kerbal kd.kerbal = Kerbal.Load(child); kerbals.Add(kd); } }
protected override void OnLoad(ConfigNode configNode) { base.OnLoad(configNode); foreach (ConfigNode child in configNode.GetNodes("KERBAL_DETAIL")) { // Read all the orbit data KerbalData kd = new KerbalData(); kd.name = child.GetValue("name"); kd.body = ConfigNodeUtil.ParseValue <CelestialBody>(child, "body"); kd.latitude = ConfigNodeUtil.ParseValue <double>(child, "lat"); kd.longitude = ConfigNodeUtil.ParseValue <double>(child, "lon"); kd.altitude = ConfigNodeUtil.ParseValue <double?>(child, "alt", (double?)null); kd.landed = ConfigNodeUtil.ParseValue <bool>(child, "landed"); kd.owned = ConfigNodeUtil.ParseValue <bool>(child, "owned"); kd.addToRoster = ConfigNodeUtil.ParseValue <bool>(child, "addToRoster"); if (child.HasNode("ORBIT")) { kd.orbit = new OrbitSnapshot(child.GetNode("ORBIT")).Load(); } // Find the ProtoCrewMember kd.crewMember = HighLogic.CurrentGame.CrewRoster.AllKerbals().Where(cm => cm.name == kd.name).First(); // Add to the global list kerbals.Add(kd); } }
public Suit getKerbalSuit(ProtoCrewMember kerbal, KerbalData kerbalData) { Suit suit = kerbalData.suit ?? getClassSuit(kerbal); if (suit != null) { return(suit); } List <Suit> genderSuits = kerbalSuits[0]; // Use female suits only if available, fall back to male suits otherwise. if (kerbalData.gender != 0 && kerbalSuits[1].Count != 0) { genderSuits = kerbalSuits[1]; } else if (genderSuits.Count == 0) { return(defaultSuit); } // We must use a different prime here to increase randomisation so that the same head is not always combined with // the same suit. int number = ((kerbalData.hash + kerbal.name.Length) * 2053) & 0x7fffffff; return(genderSuits[number % genderSuits.Count]); }
public KerbalData(KerbalData k) { name = k.name; crewMember = k.crewMember; body = k.body; orbit = k.orbit; latitude = k.latitude; longitude = k.longitude; altitude = k.altitude; landed = k.landed; owned = k.owned; }
public KerbalData(KerbalData k) { kerbal = new Kerbal(k.kerbal); body = k.body; orbit = k.orbit; latitude = k.latitude; longitude = k.longitude; altitude = k.altitude; landed = k.landed; owned = k.owned; addToRoster = k.addToRoster; pqsCity = k.pqsCity; pqsOffset = k.pqsOffset; heading = k.heading; }
public KerbalData(KerbalData k) { kerbal = new Kerbal(k.kerbal); body = k.body; orbit = k.orbit; latitude = k.latitude; longitude = k.longitude; altitude = k.altitude; landed = k.landed; owned = k.owned; addToRoster = k.addToRoster; pqsCity = k.pqsCity; pqsOffset = k.pqsOffset; heading = k.heading; }
public KerbalData(KerbalData k) { name = k.name; crewMember = k.crewMember; body = k.body; orbit = k.orbit; latitude = k.latitude; longitude = k.longitude; altitude = k.altitude; landed = k.landed; owned = k.owned; addToRoster = k.addToRoster; pqsCity = k.pqsCity; pqsOffset = k.pqsOffset; }
public void TestGameObject() { //var obj = KspData.LoadKspFile(@"C:\dev\KspData\src\KerbalData.Tests\bin\Debug\Data\Parts\dockingPort1\part.cfg"); //var vessel = obj["GAME"]["FLIGHTSTATE"]["VESSEL"].Where(v => v["pid"].ToString().Equals("f55d3f0601704035aa06e0a8174b723c")).FirstOrDefault(); //var parts = vessel["PART"].Where(p => p["uid"].ToString().Equals("2910085908")); //Console.WriteLine() var kd = KerbalData.Create(@"C:\games\KSP_win_test"); //var training = kd.TrainingScenarios["C_Orbit101"]; //var scenario = kd.Scenarios["Impending Impact"]; var save = kd.Saves["testing"]; //var craft = kd.Saves["testing"].CraftInSph["Goose Mk1_4"]; //var part = kd.Parts["fuelTank2-2"]; //var part2 = kd.Parts["liquidEngine1"]; //var craft2 = kd.CraftInVab["MechJeb Pod 2.0 Kit"]; //var settings = kd.KspSettings["settings"]; var props = save.Game.Parameters.Editor.ToArray(); //part.Cost = 43434343; //part.Save(); Console.WriteLine(); /* * var sf = kd.Saves["testing"]; * * * sf.Game.Title = "TESTINGTESTINGTESTINGTESTING"; * sf.Game.FlightState.ClearDebris(); * * var sat = sf.Game.FlightState.Vessels.Where(v => v.Name.Contains("Beta Geo-Sat")).FirstOrDefault(); * sat.Orbit.Change(Body.Kerbol); * * sf.Save();*/ /* * sf.Game.Title = "WHAT WHO WHAT?"; * sf.Game.FlightState.Vessels[0].Parts[0]["name"] = "SUPERCOREWOOO!"; * * sf.Save();*/ }
public static SpawnKerbal Create(ConfigNode configNode, CelestialBody defaultBody, SpawnKerbalFactory factory) { SpawnKerbal spawnKerbal = new SpawnKerbal(); bool valid = true; foreach (ConfigNode child in configNode.GetNodes("KERBAL")) { KerbalData kerbal = new KerbalData(); // Get name if (child.HasValue("name")) { kerbal.name = child.GetValue("name"); } // Get celestial body valid &= ConfigNodeUtil.ParseValue <CelestialBody>(child, "targetBody", ref kerbal.body, factory, defaultBody, Validation.NotNull); // Get orbit valid &= ConfigNodeUtil.ValidateMandatoryChild(child, "ORBIT", factory); kerbal.orbit = new OrbitSnapshot(child.GetNode("ORBIT")).Load(); kerbal.orbit.referenceBody = kerbal.body; // Get landed stuff if (child.HasValue("lat") && child.HasValue("lon") && child.HasValue("alt")) { valid &= ConfigNodeUtil.ParseValue <double>(child, "lat", ref kerbal.latitude, factory); valid &= ConfigNodeUtil.ParseValue <double>(child, "lon", ref kerbal.longitude, factory); valid &= ConfigNodeUtil.ParseValue <double>(child, "alt", ref kerbal.altitude, factory); kerbal.landed = true; } // Get owned flag if (child.HasValue("owned")) { valid &= ConfigNodeUtil.ParseValue <bool>(configNode, "owned", ref kerbal.owned, factory, false); } // Add to the list spawnKerbal.kerbals.Add(kerbal); } return(valid ? spawnKerbal : null); }
static void Main(string[] args) { if (args.Count() != 2) { Console.WriteLine("The ClearDebris command requires 2 parameters. The path of your KSP install, the name of your save game"); return; } var kspPath = args[0].Trim(); var gameName = args[1].Trim(); var kd = new KerbalData(kspPath); var save = kd.Saves[gameName]; Console.WriteLine("Removed " + save.Game.FlightState.ClearDebris() + " vessels."); save.Save(); }
/** * Load per-game custom kerbals mapping. */ void loadKerbals(ConfigNode node) { node = node ?? customKerbalsNode; KerbalRoster roster = HighLogic.CurrentGame.CrewRoster; foreach (ProtoCrewMember kerbal in roster.Crew.Concat(roster.Tourist).Concat(roster.Unowned)) { if (kerbal.rosterStatus == ProtoCrewMember.RosterStatus.Dead && kerbal.type != ProtoCrewMember.KerbalType.Unowned) { continue; } KerbalData kerbalData = getKerbalData(kerbal); string value = node.GetValue(kerbal.name); if (value != null) { string[] tokens = Util.splitConfigValue(value); string genderName = tokens.Length >= 1 ? tokens[0] : null; string headName = tokens.Length >= 2 ? tokens[1] : null; string suitName = tokens.Length >= 3 ? tokens[2] : null; if (genderName != null) { kerbalData.gender = genderName == "F" ? 1 : 0; } if (headName != null && headName != "GENERIC") { kerbalData.head = headName == "DEFAULT" ? defaultHead[(int)kerbal.gender] : heads.Find(h => h.name == headName); } if (suitName != null && suitName != "GENERIC") { kerbalData.suit = suitName == "DEFAULT" ? defaultSuit : suits.Find(s => s.name == suitName); } kerbal.gender = forceLegacyFemales ? ProtoCrewMember.Gender.Male : (ProtoCrewMember.Gender)kerbalData.gender; } } }
public KerbalData getKerbalData(ProtoCrewMember kerbal) { KerbalData kerbalData; if (!gameKerbals.TryGetValue(kerbal.name, out kerbalData)) { kerbalData = new KerbalData { hash = kerbal.name.GetHashCode(), gender = (int)kerbal.gender, isVeteran = VETERANS.Any(n => n == kerbal.name) }; gameKerbals.Add(kerbal.name, kerbalData); if (forceLegacyFemales) { kerbal.gender = ProtoCrewMember.Gender.Male; } } return(kerbalData); }
public Head getKerbalHead(ProtoCrewMember kerbal, KerbalData kerbalData) { if (kerbalData.head != null) { return(kerbalData.head); } List <Head> genderHeads = kerbalHeads[kerbalData.gender]; if (genderHeads.Count == 0) { return(defaultHead[(int)kerbal.gender]); } // Hash is multiplied with a large prime to increase randomisation, since hashes returned by `GetHashCode()` are // close together if strings only differ in the last (few) char(s). int number = (kerbalData.hash * 4099) & 0x7fffffff; return(genderHeads[number % genderHeads.Count]); }
/** * Save per-game custom Kerbals mapping. */ void saveKerbals(ConfigNode node) { KerbalRoster roster = HighLogic.CurrentGame.CrewRoster; foreach (ProtoCrewMember kerbal in roster.Crew.Concat(roster.Tourist).Concat(roster.Unowned)) { if (kerbal.rosterStatus == ProtoCrewMember.RosterStatus.Dead && kerbal.type != ProtoCrewMember.KerbalType.Unowned) { continue; } KerbalData kerbalData = getKerbalData(kerbal); string genderName = kerbalData.gender == 0 ? "M" : "F"; string headName = kerbalData.head == null ? "GENERIC" : kerbalData.head.name; string suitName = kerbalData.suit == null ? "GENERIC" : kerbalData.suit.name; node.AddValue(kerbal.name, genderName + " " + headName + " " + suitName); } }
static void Main(string[] args) { if (args.Count() < 4) { Console.WriteLine("The MakeOrbit command requires 3 parameters. The path of your save, the name of the flight you wish to orbit and the code of the reference body you wish to orbit"); return; } var kspPath = args[0].Trim(); var gameName = args[1].Trim(); var vesselName = args[2].Trim(); var body = (Body)Enum.Parse(typeof(Body), args[3].Trim()); var kd = new KerbalData(kspPath); var save = kd.Saves[gameName]; var vessel = save.Game.FlightState.Vessels.Where(v => v["name"].ToString() == vesselName).FirstOrDefault(); vessel.Orbit.Change(body); save.Save(); }
public static SpawnKerbal Create(ConfigNode configNode, CelestialBody defaultBody, SpawnKerbalFactory factory) { SpawnKerbal spawnKerbal = new SpawnKerbal(); bool valid = true; int index = 0; foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode, "KERBAL")) { DataNode dataNode = new DataNode("KERBAL_" + index++, factory.dataNode, factory); try { ConfigNodeUtil.SetCurrentDataNode(dataNode); KerbalData kerbal = new KerbalData(); // Get name if (child.HasValue("name")) { kerbal.name = child.GetValue("name"); } // Get celestial body valid &= ConfigNodeUtil.ParseValue <CelestialBody>(child, "targetBody", x => kerbal.body = x, factory, defaultBody, Validation.NotNull); // Get landed stuff if (child.HasValue("lat") && child.HasValue("lon") || child.HasValue("pqsCity")) { kerbal.landed = true; if (child.HasValue("pqsCity")) { string pqsCityStr = null; valid &= ConfigNodeUtil.ParseValue <string>(child, "pqsCity", x => pqsCityStr = x, factory); if (pqsCityStr != null) { try { kerbal.pqsCity = kerbal.body.GetComponentsInChildren <PQSCity>(true).Where(pqs => pqs.name == pqsCityStr).First(); } catch (Exception e) { LoggingUtil.LogError(typeof(WaypointGenerator), "Couldn't load PQSCity with name '" + pqsCityStr + "'"); LoggingUtil.LogException(e); valid = false; } } valid &= ConfigNodeUtil.ParseValue <Vector3d>(child, "pqsOffset", x => kerbal.pqsOffset = x, factory, new Vector3d()); } else { valid &= ConfigNodeUtil.ParseValue <double>(child, "lat", x => kerbal.latitude = x, factory); valid &= ConfigNodeUtil.ParseValue <double>(child, "lon", x => kerbal.longitude = x, factory); } } // Get orbit else if (child.HasNode("ORBIT")) { kerbal.orbit = new OrbitSnapshot(ConfigNodeUtil.GetChildNode(child, "ORBIT")).Load(); kerbal.orbit.referenceBody = kerbal.body; } else { // Will error valid &= ConfigNodeUtil.ValidateMandatoryChild(child, "ORBIT", factory); } valid &= ConfigNodeUtil.ParseValue <double?>(child, "alt", x => kerbal.altitude = x, factory, (double?)null); // Get additional flags valid &= ConfigNodeUtil.ParseValue <bool>(child, "owned", x => kerbal.owned = x, factory, false); valid &= ConfigNodeUtil.ParseValue <bool>(child, "addToRoster", x => kerbal.addToRoster = x, factory, true); // Add to the list spawnKerbal.kerbals.Add(kerbal); } finally { ConfigNodeUtil.SetCurrentDataNode(factory.dataNode); } } return(valid ? spawnKerbal : null); }
public static SpawnKerbal Create(ConfigNode configNode, SpawnKerbalFactory factory) { SpawnKerbal spawnKerbal = new SpawnKerbal(); bool valid = true; int index = 0; foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode, "KERBAL")) { DataNode dataNode = new DataNode("KERBAL_" + index++, factory.dataNode, factory); try { ConfigNodeUtil.SetCurrentDataNode(dataNode); KerbalData kd = new KerbalData(); // Use an expression to default - then it'll work for dynamic contracts if (!child.HasValue("targetBody")) { child.AddValue("targetBody", "@/targetBody"); } valid &= ConfigNodeUtil.ParseValue <CelestialBody>(child, "targetBody", x => kd.body = x, factory); // Get landed stuff if (child.HasValue("lat") && child.HasValue("lon") || child.HasValue("pqsCity")) { kd.landed = true; if (child.HasValue("pqsCity")) { string pqsCityStr = null; valid &= ConfigNodeUtil.ParseValue <string>(child, "pqsCity", x => pqsCityStr = x, factory); if (pqsCityStr != null) { try { kd.pqsCity = kd.body.GetComponentsInChildren <PQSCity>(true).Where(pqs => pqs.name == pqsCityStr).First(); } catch (Exception e) { LoggingUtil.LogError(typeof(WaypointGenerator), "Couldn't load PQSCity with name '" + pqsCityStr + "'"); LoggingUtil.LogException(e); valid = false; } } valid &= ConfigNodeUtil.ParseValue <Vector3d>(child, "pqsOffset", x => kd.pqsOffset = x, factory, new Vector3d()); // Don't expect these to load anything, but do it to mark as initialized valid &= ConfigNodeUtil.ParseValue <double>(child, "lat", x => kd.latitude = x, factory, 0.0); valid &= ConfigNodeUtil.ParseValue <double>(child, "lon", x => kd.longitude = x, factory, 0.0); } else { valid &= ConfigNodeUtil.ParseValue <double>(child, "lat", x => kd.latitude = x, factory); valid &= ConfigNodeUtil.ParseValue <double>(child, "lon", x => kd.longitude = x, factory); } valid &= ConfigNodeUtil.ParseValue <float>(child, "heading", x => kd.heading = x, factory, 0.0f); } // Get orbit else if (child.HasNode("ORBIT")) { // Don't expect these to load anything, but do it to mark as initialized valid &= ConfigNodeUtil.ParseValue <double>(child, "lat", x => kd.latitude = x, factory, 0.0); valid &= ConfigNodeUtil.ParseValue <double>(child, "lon", x => kd.longitude = x, factory, 0.0); valid &= ConfigNodeUtil.ParseValue <Orbit>(child, "ORBIT", x => kd.orbit = x, factory); } else { // Will error valid &= ConfigNodeUtil.ValidateMandatoryChild(child, "ORBIT", factory); } valid &= ConfigNodeUtil.ParseValue <double?>(child, "alt", x => kd.altitude = x, factory, (double?)null); if (child.HasValue("kerbal")) { valid &= ConfigNodeUtil.ParseValue <Kerbal>(child, "kerbal", x => kd.kerbal = x, factory); } else { // Default gender if (!child.HasValue("gender")) { child.AddValue("gender", "Random()"); } valid &= ConfigNodeUtil.ParseValue <ProtoCrewMember.Gender>(child, "gender", x => kd.kerbal.gender = x, factory); // Default name if (!child.HasValue("name")) { child.AddValue("name", "RandomKerbalName(@gender)"); } valid &= ConfigNodeUtil.ParseValue <string>(child, "name", x => { kd.kerbal.name = x; if (kd.kerbal.pcm != null) { kd.kerbal.pcm.ChangeName(x); } }, factory); } // Get additional stuff valid &= ConfigNodeUtil.ParseValue <bool>(child, "owned", x => kd.owned = x, factory, false); valid &= ConfigNodeUtil.ParseValue <bool>(child, "addToRoster", x => kd.addToRoster = x, factory, true); valid &= ConfigNodeUtil.ParseValue <ProtoCrewMember.KerbalType>(child, "kerbalType", x => kd.kerbal.kerbalType = x, factory, ProtoCrewMember.KerbalType.Unowned); // Check for unexpected values valid &= ConfigNodeUtil.ValidateUnexpectedValues(child, factory); // Add to the list spawnKerbal.kerbals.Add(kd); } finally { ConfigNodeUtil.SetCurrentDataNode(factory.dataNode); } } return(valid ? spawnKerbal : null); }
public Suit getKerbalSuit(ProtoCrewMember kerbal, KerbalData kerbalData) { Suit suit = kerbalData.suit ?? getClassSuit(kerbal); if (suit != null) return suit; List<Suit> genderSuits = kerbalSuits[0]; // Use female suits only if available, fall back to male suits otherwise. if (kerbalData.gender != 0 && kerbalSuits[1].Count != 0) genderSuits = kerbalSuits[1]; else if (genderSuits.Count == 0) return defaultSuit; // We must use a different prime here to increase randomisation so that the same head is not always combined with // the same suit. int number = ((kerbalData.hash + kerbal.name.Length) * 2053) & 0x7fffffff; return genderSuits[number % genderSuits.Count]; }
protected override void OnLoad(ConfigNode configNode) { base.OnLoad(configNode); foreach (ConfigNode child in configNode.GetNodes("KERBAL_DETAIL")) { // Read all the orbit data KerbalData kd = new KerbalData(); kd.body = ConfigNodeUtil.ParseValue<CelestialBody>(child, "body"); kd.latitude = ConfigNodeUtil.ParseValue<double>(child, "lat"); kd.longitude = ConfigNodeUtil.ParseValue<double>(child, "lon"); kd.altitude = ConfigNodeUtil.ParseValue<double?>(child, "alt", (double?)null); kd.landed = ConfigNodeUtil.ParseValue<bool>(child, "landed"); kd.owned = ConfigNodeUtil.ParseValue<bool>(child, "owned"); kd.addToRoster = ConfigNodeUtil.ParseValue<bool>(child, "addToRoster"); if (child.HasNode("ORBIT")) { kd.orbit = new OrbitSnapshot(child.GetNode("ORBIT")).Load(); } // Load the kerbal kd.kerbal = Kerbal.Load(child); kerbals.Add(kd); } }
public KerbalData(KerbalData k) { name = k.name; crewMember = k.crewMember; body = k.body; orbit = k.orbit; latitude = k.latitude; longitude = k.longitude; altitude = k.altitude; landed = k.landed; owned = k.owned; addToRoster = k.addToRoster; gender = k.gender; kerbalType = k.kerbalType; pqsCity = k.pqsCity; pqsOffset = k.pqsOffset; heading = k.heading; }
/** * Replace textures on a Kerbal model. */ void personaliseKerbal(Component component, ProtoCrewMember kerbal, Part cabin, bool needsSuit) { KerbalData kerbalData = getKerbalData(kerbal); bool isEva = cabin == null; Head head = getKerbalHead(kerbal, kerbalData); Suit suit = null; if (isEva || !cabinSuits.TryGetValue(cabin.partInfo.name, out kerbalData.cabinSuit)) { suit = getKerbalSuit(kerbal, kerbalData); } head = head == defaultHead[(int)kerbal.gender] ? null : head; suit = (isEva && needsSuit) || kerbalData.cabinSuit == null ? suit : kerbalData.cabinSuit; suit = suit == defaultSuit ? null : suit; Transform model = isEva ? component.transform.Find("model01") : component.transform.Find("kbIVA@idle/model01"); Transform flag = isEva ? component.transform.Find("model/kbEVA_flagDecals") : null; if (isEva) { flag.renderer.enabled = needsSuit; } // We must include hidden meshes, since flares are hidden when light is turned off. // All other meshes are always visible, so no performance hit here. foreach (Renderer renderer in model.GetComponentsInChildren <Renderer>(true)) { var smr = renderer as SkinnedMeshRenderer; // Thruster jets, flag decals and headlight flares. if (smr == null) { if (renderer.name != "screenMessage") { renderer.enabled = needsSuit; } } else { Material material = renderer.material; Texture2D newTexture = null; Texture2D newNormalMap = null; switch (smr.name) { case "eyeballLeft": case "eyeballRight": case "pupilLeft": case "pupilRight": case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_eyeballLeft": case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_eyeballRight": case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_pupilLeft": case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_pupilRight": if (head != null && head.isEyeless) { smr.sharedMesh = null; } break; case "headMesh01": case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_pCube1": case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_polySurface51": case "headMesh": case "ponytail": if (head != null) { newTexture = head.head; newNormalMap = head.headNRM; } break; case "tongue": case "upTeeth01": case "upTeeth02": case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_upTeeth01": case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_downTeeth01": case "downTeeth01": break; case "body01": case "mesh_female_kerbalAstronaut01_body01": bool isEvaSuit = isEva && needsSuit; if (suit != null) { newTexture = isEvaSuit ? suit.getEvaSuit(kerbal.experienceLevel) : suit.getSuit(kerbal.experienceLevel); newNormalMap = isEvaSuit ? suit.evaSuitNRM : suit.suitNRM; } if (newTexture == null) { // This required for two reasons: to fix IVA suits after KSP resetting them to the stock ones all the // time and to fix the switch from non-default to default texture during EVA suit toggle. newTexture = isEvaSuit ? defaultSuit.evaSuit : kerbalData.isVeteran ? defaultSuit.suitVeteran : defaultSuit.suit; } if (newNormalMap == null) { newNormalMap = isEvaSuit ? defaultSuit.evaSuitNRM : defaultSuit.suitNRM; } // Update textures in Kerbal IVA object since KSP resets them to these values a few frames later. if (!isEva) { Kerbal kerbalIVA = (Kerbal)component; kerbalIVA.textureStandard = newTexture; kerbalIVA.textureVeteran = newTexture; } break; case "helmet": case "mesh_female_kerbalAstronaut01_helmet": if (isEva) { smr.enabled = needsSuit; } else { smr.sharedMesh = needsSuit ? helmetMesh[(int)kerbal.gender] : null; } // Textures have to be replaced even when hidden since it may become visible later on situation change. if (suit != null) { newTexture = isEva ? suit.getEvaHelmet(kerbal.experienceLevel) : suit.getHelmet(kerbal.experienceLevel); newNormalMap = suit.helmetNRM; } break; case "visor": case "mesh_female_kerbalAstronaut01_visor": if (isEva) { smr.enabled = needsSuit; } else { smr.sharedMesh = needsSuit ? visorMesh[(int)kerbal.gender] : null; } // Textures have to be replaced even when hidden since it may become visible later on situation change. if (suit != null) { newTexture = isEva ? suit.evaVisor : suit.visor; if (newTexture != null) { material.color = Color.white; } } break; default: // Jetpack. if (isEva) { smr.enabled = needsSuit; if (needsSuit && suit != null) { newTexture = suit.evaJetpack; newNormalMap = suit.evaJetpackNRM; } } break; } if (newTexture != null) { material.mainTexture = newTexture; } if (newNormalMap != null) { material.SetTexture(Util.BUMPMAP_PROPERTY, newNormalMap); } } } }
protected override void TestInit() { Data = null; ResetTempData(); Data = KerbalData.Create(TestHelpers.BaseDataTempPath()); }
// execute the recipe public bool Execute(Vessel v, Vessel_resources resources) { // determine worst input ratio // - pure input recipes can just underflow double worst_input = left; if (outputs.Count > 0) { for (int i = 0; i < inputs.Count; ++i) { Entry e = inputs[i]; Resource_info_view res = GetResourceInfoView(v, resources, e.name); // handle combined inputs if (e.combined != null) { // is combined resource the primary if (e.combined != "") { Entry sec_e = inputs.Find(x => x.name.Contains(e.combined)); Resource_info_view sec = GetResourceInfoView(v, resources, sec_e.name); double pri_worst = Lib.Clamp((res.amount + res.deferred) * e.inv_quantity, 0.0, worst_input); if (pri_worst > 0.0) { worst_input = pri_worst; } else { worst_input = Lib.Clamp((sec.amount + sec.deferred) * sec_e.inv_quantity, 0.0, worst_input); } } } else { worst_input = Lib.Clamp((res.amount + res.deferred) * e.inv_quantity, 0.0, worst_input); } } } // determine worst output ratio // - pure output recipes can just overflow double worst_output = left; if (inputs.Count > 0) { for (int i = 0; i < outputs.Count; ++i) { Entry e = outputs[i]; if (!e.dump) // ignore outputs that can dump overboard { Resource_info_view res = GetResourceInfoView(v, resources, e.name); worst_output = Lib.Clamp((res.capacity - (res.amount + res.deferred)) * e.inv_quantity, 0.0, worst_output); } } } // determine worst-io double worst_io = Math.Min(worst_input, worst_output); // consume inputs for (int i = 0; i < inputs.Count; ++i) { Entry e = inputs[i]; Resource_info_view res = GetResourceInfoView(v, resources, e.name); // handle combined inputs if (e.combined != null) { // is combined resource the primary if (e.combined != "") { Entry sec_e = inputs.Find(x => x.name.Contains(e.combined)); Resource_info_view sec = GetResourceInfoView(v, resources, sec_e.name); double need = (e.quantity * worst_io) + (sec_e.quantity * worst_io); // do we have enough primary to satisfy needs, if so don't consume secondary if (res.amount + res.deferred >= need) { resources.Consume(v, e.name, need, name); } // consume primary if any available and secondary else { need -= res.amount + res.deferred; res.Consume(res.amount + res.deferred, name); sec.Consume(need, name); } } } else { res.Consume(e.quantity * worst_io, name); } } // produce outputs for (int i = 0; i < outputs.Count; ++i) { Entry e = outputs[i]; Resource_info_view res = GetResourceInfoView(v, resources, e.name); res.Produce(e.quantity * worst_io, name); } // produce cures for (int i = 0; i < cures.Count; ++i) { Entry entry = cures[i]; List <RuleData> curingRules = new List <RuleData>(); foreach (ProtoCrewMember crew in v.GetVesselCrew()) { KerbalData kd = DB.Kerbal(crew.name); if (kd.sickbay.IndexOf(entry.combined + ",", StringComparison.Ordinal) >= 0) { curingRules.Add(kd.Rule(entry.name)); } } foreach (RuleData rd in curingRules) { rd.problem -= entry.quantity * worst_io / curingRules.Count; rd.problem = Math.Max(rd.problem, 0); } } // update amount left to execute left -= worst_io; // the recipe was executed, at least partially return(worst_io > double.Epsilon); }
public KerbalData getKerbalData(ProtoCrewMember kerbal) { KerbalData kerbalData; if (!gameKerbals.TryGetValue(kerbal.name, out kerbalData)) { kerbalData = new KerbalData { hash = kerbal.name.GetHashCode(), gender = (int) kerbal.gender, isVeteran = VETERANS.Any(n => n == kerbal.name) }; gameKerbals.Add(kerbal.name, kerbalData); if (forceLegacyFemales) kerbal.gender = ProtoCrewMember.Gender.Male; } return kerbalData; }
protected override void OnLoad(ConfigNode configNode) { base.OnLoad(configNode); foreach (ConfigNode child in configNode.GetNodes("KERBAL_DETAIL")) { // Read all the orbit data KerbalData kd = new KerbalData(); kd.name = child.GetValue("name"); kd.body = ConfigNodeUtil.ParseValue<CelestialBody>(child, "body"); kd.latitude = ConfigNodeUtil.ParseValue<double>(child, "lat"); kd.longitude = ConfigNodeUtil.ParseValue<double>(child, "lon"); kd.altitude = ConfigNodeUtil.ParseValue<double?>(child, "alt", (double?)null); kd.landed = ConfigNodeUtil.ParseValue<bool>(child, "landed"); kd.owned = ConfigNodeUtil.ParseValue<bool>(child, "owned"); kd.addToRoster = ConfigNodeUtil.ParseValue<bool>(child, "addToRoster"); if (child.HasNode("ORBIT")) { kd.orbit = new OrbitSnapshot(child.GetNode("ORBIT")).Load(); } // Find the ProtoCrewMember kd.crewMember = HighLogic.CurrentGame.CrewRoster.AllKerbals().Where(cm => cm != null && cm.name == kd.name).FirstOrDefault(); // Add to the global list if (kd.crewMember != null) { kerbals.Add(kd); } } }
public Head getKerbalHead(ProtoCrewMember kerbal, KerbalData kerbalData) { if (kerbalData.head != null) return kerbalData.head; List<Head> genderHeads = kerbalHeads[kerbalData.gender]; if (genderHeads.Count == 0) return defaultHead[(int) kerbal.gender]; // Hash is multiplied with a large prime to increase randomisation, since hashes returned by `GetHashCode()` are // close together if strings only differ in the last (few) char(s). int number = (kerbalData.hash * 4099) & 0x7fffffff; return genderHeads[number % genderHeads.Count]; }
public static SpawnKerbal Create(ConfigNode configNode, SpawnKerbalFactory factory) { SpawnKerbal spawnKerbal = new SpawnKerbal(); bool valid = true; int index = 0; foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode, "KERBAL")) { DataNode dataNode = new DataNode("KERBAL_" + index++, factory.dataNode, factory); try { ConfigNodeUtil.SetCurrentDataNode(dataNode); KerbalData kerbal = new KerbalData(); // Get name valid &= ConfigNodeUtil.ParseValue<string>(child, "name", x => { kerbal.name = x; if (kerbal.crewMember != null) kerbal.crewMember.name = x; }, factory, (string)null); // Use an expression to default - then it'll work for dynamic contracts if (!child.HasValue("targetBody")) { child.AddValue("targetBody", "@/targetBody"); } valid &= ConfigNodeUtil.ParseValue<CelestialBody>(child, "targetBody", x => kerbal.body = x, factory); // Get landed stuff if (child.HasValue("lat") && child.HasValue("lon") || child.HasValue("pqsCity")) { kerbal.landed = true; if (child.HasValue("pqsCity")) { string pqsCityStr = null; valid &= ConfigNodeUtil.ParseValue<string>(child, "pqsCity", x => pqsCityStr = x, factory); if (pqsCityStr != null) { try { kerbal.pqsCity = kerbal.body.GetComponentsInChildren<PQSCity>(true).Where(pqs => pqs.name == pqsCityStr).First(); } catch (Exception e) { LoggingUtil.LogError(typeof(WaypointGenerator), "Couldn't load PQSCity with name '" + pqsCityStr + "'"); LoggingUtil.LogException(e); valid = false; } } valid &= ConfigNodeUtil.ParseValue<Vector3d>(child, "pqsOffset", x => kerbal.pqsOffset = x, factory, new Vector3d()); // Don't expect these to load anything, but do it to mark as initialized valid &= ConfigNodeUtil.ParseValue<double>(child, "lat", x => kerbal.latitude = x, factory, 0.0); valid &= ConfigNodeUtil.ParseValue<double>(child, "lon", x => kerbal.longitude = x, factory, 0.0); } else { valid &= ConfigNodeUtil.ParseValue<double>(child, "lat", x => kerbal.latitude = x, factory); valid &= ConfigNodeUtil.ParseValue<double>(child, "lon", x => kerbal.longitude = x, factory); } valid &= ConfigNodeUtil.ParseValue<float>(child, "heading", x => kerbal.heading = x, factory, 0.0f); } // Get orbit else if (child.HasNode("ORBIT")) { // Don't expect these to load anything, but do it to mark as initialized valid &= ConfigNodeUtil.ParseValue<double>(child, "lat", x => kerbal.latitude = x, factory, 0.0); valid &= ConfigNodeUtil.ParseValue<double>(child, "lon", x => kerbal.longitude = x, factory, 0.0); valid &= ConfigNodeUtil.ParseValue<Orbit>(child, "ORBIT", x => kerbal.orbit = x, factory); } else { // Will error valid &= ConfigNodeUtil.ValidateMandatoryChild(child, "ORBIT", factory); } valid &= ConfigNodeUtil.ParseValue<double?>(child, "alt", x => kerbal.altitude = x, factory, (double?)null); // Get additional stuff valid &= ConfigNodeUtil.ParseValue<bool>(child, "owned", x => kerbal.owned = x, factory, false); valid &= ConfigNodeUtil.ParseValue<bool>(child, "addToRoster", x => kerbal.addToRoster = x, factory, true); valid &= ConfigNodeUtil.ParseValue<ProtoCrewMember.Gender?>(child, "gender", x => kerbal.gender = x, factory, (ProtoCrewMember.Gender?)null); valid &= ConfigNodeUtil.ParseValue<ProtoCrewMember.KerbalType>(child, "kerbalType", x => kerbal.kerbalType = x, factory, ProtoCrewMember.KerbalType.Unowned); // Check for unexpected values valid &= ConfigNodeUtil.ValidateUnexpectedValues(child, factory); // Add to the list spawnKerbal.kerbals.Add(kerbal); } finally { ConfigNodeUtil.SetCurrentDataNode(factory.dataNode); } } return valid ? spawnKerbal : null; }
private void UpdateInstallPath() { KerbalData = null; KerbalData = KerbalData.Create(installPath); }