private static PilotDef GenerateCrew(StarSystem starSystem, string callsign, PilotDef pilotDef) { Mod.Log.Debug?.Write($"Generating support crew with callsign: {callsign}"); // Generate the lifepath we'll use LifePath lifePath = LifePathHelper.GetRandomLifePath(); int initialAge = ModState.SimGameState.Constants.Pilot.MinimumPilotAge + ModState.SimGameState.NetworkRandom.Int(1, ModState.SimGameState.Constants.Pilot.StartingAgeRange + 1); int currentAge = Mod.Random.Next(initialAge, 70); Mod.Log.Debug?.Write($" - currentAge: {currentAge}"); Gender newGender = RandomGender(); Gender voiceGender = newGender; if (voiceGender == Gender.NonBinary) { voiceGender = ((!(ModState.SimGameState.NetworkRandom.Float() < 0.5f)) ? Gender.Female : Gender.Male); } string voice = RandomUnusedVoice(voiceGender); string newFirstName = ModState.CrewCreateState.NameGenerator.GetFirstName(newGender); string newLastName = ModState.CrewCreateState.NameGenerator.GetLastName(); Mod.Log.Debug?.Write($" - gender: {newGender} voiceGender: {voiceGender} firstName: {newFirstName} lastName: {newLastName}"); pilotDef.SetVoice(voice); StringBuilder lifepathDescParagraphs = new StringBuilder(); string backgroundTitle = new Text(lifePath.Description.Title).ToString(); string backgroundDesc = new Text(lifePath.Description.Description).ToString(); // DETAILS string is EXTREMELY picky, see HumanDescriptionDef.GetLocalizedDetails. There format must be followed *exactly* string formattedBackground = $"{Environment.NewLine}<b>{backgroundTitle}:</b> {backgroundDesc}"; Mod.Log.Debug?.Write($" - Background: {formattedBackground}"); lifepathDescParagraphs.Append(formattedBackground); // Add tags from the lifepath TagSet tagSet = new TagSet(); tagSet.AddRange(lifePath.RequiredTags); foreach (string tag in lifePath.RandomTags) { double tagRoll = Mod.Random.NextDouble(); if (tagRoll <= Mod.Config.HiringHall.LifePath.RandomTagChance) { tagSet.Add(tag); } } Mod.Log.Debug?.Write($" - Tags: {String.Join(", ", tagSet)}"); // Add tags to the background foreach (string tagId in tagSet) { Tag_MDD tagIfExists = MetadataDatabase.Instance.GetTagIfExists(tagId); if (tagIfExists != null) { TagDataStruct tagStruct = new TagDataStruct(tagId, tagIfExists.PlayerVisible, tagIfExists.Important, tagIfExists.Name, tagIfExists.FriendlyName, tagIfExists.Description); string formattedTag = $"<b><color=#ff8c00>{tagStruct.FriendlyName}:</b> <color=#ffffff>{tagStruct.DescriptionTag}"; lifepathDescParagraphs.Append(formattedTag); } } string id = GenerateID(); HumanDescriptionDef descriptionDef = new HumanDescriptionDef(id, callsign, newFirstName, newLastName, callsign, newGender, FactionEnumeration.GetNoFactionValue(), currentAge, lifepathDescParagraphs.ToString(), null); StatCollection statCollection = pilotDef.GetStats(); int spentXPPilot = GetSpentXPPilot(statCollection); List <string> alreadyAssignedPortraits = new List <string>(); if (ModState.SimGameState.Commander != null && ModState.SimGameState.Commander.pilotDef.PortraitSettings != null) { alreadyAssignedPortraits.Add(ModState.SimGameState.Commander.pilotDef.PortraitSettings.Description.Id); } foreach (Pilot activePilot in ModState.SimGameState.PilotRoster) { if (activePilot.pilotDef.PortraitSettings != null) { alreadyAssignedPortraits.Add(activePilot.pilotDef.PortraitSettings.Description.Id); } } PilotDef pilotDef2 = new PilotDef(descriptionDef, pilotDef.BaseGunnery, pilotDef.BasePiloting, pilotDef.BaseGuts, pilotDef.BaseTactics, 0, ModState.SimGameState.CombatConstants.PilotingConstants.DefaultMaxInjuries, lethalInjury: false, 0, voice, pilotDef.abilityDefNames, AIPersonality.Undefined, 0, tagSet, spentXPPilot, 0) { DataManager = ModState.SimGameState.DataManager, PortraitSettings = GetPortraitForGenderAndAge(voiceGender, currentAge, alreadyAssignedPortraits) }; ModState.SimGameState.pilotGenCallsignDiscardPile.Add(pilotDef2.Description.Callsign); return(pilotDef2); }
public static void Init(string modDirectory, string settingsJSON) { ModDir = modDirectory; Exception settingsE = null; try { Mod.Config = JsonConvert.DeserializeObject <ModConfig>(settingsJSON); } catch (Exception e) { settingsE = e; Mod.Config = new ModConfig(); } Mod.Config.Init(); // Initialize color conversion & defaults Log = new DeferringLogger(modDirectory, LogName, "HR", Mod.Config.Debug, Mod.Config.Trace); DossierLog = new DeferringLogger(modDirectory, $"{LogName}.{LogSuffixDossier}", "HR", Mod.Config.Debug, Mod.Config.Trace); Assembly asm = Assembly.GetExecutingAssembly(); FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(asm.Location); Log.Info?.Write($"Assembly version: {fvi.ProductVersion}"); // Read config Log.Debug?.Write($"ModDir is:{modDirectory}"); Log.Debug?.Write($"mod.json settings are:({settingsJSON})"); Mod.Config.LogConfig(); if (settingsE != null) { Log.Info?.Write($"ERROR reading settings file! Error was: {settingsE}"); } else { Log.Info?.Write($"INFO: No errors reading settings file."); } // Read crew name dictionary string namesPath = Path.Combine(ModDir, "./mod_names.json"); try { string jsonS = File.ReadAllText(namesPath); Mod.CrewNames = JsonConvert.DeserializeObject <ModCrewNames>(jsonS); Log.Info?.Write($"Successfully read:" + $" {Mod.CrewNames.Aerospace?.Count} aerospace crew names" + $" {Mod.CrewNames.MechTech?.Count} mechtech crew names" + $" {Mod.CrewNames.MedTech?.Count} medtech crew names" + $" {Mod.CrewNames.Vehicle?.Count} vehicle crew names" ); } catch (Exception e) { Mod.CrewNames = new ModCrewNames(); Log.Error?.Write(e, $"Failed to read names from: {namesPath} due to error!"); } // Read localization string localizationPath = Path.Combine(ModDir, "./mod_localized_text.json"); try { string jsonS = File.ReadAllText(localizationPath); Mod.LocalizedText = JsonConvert.DeserializeObject <ModText>(jsonS); Log.Info?.Write("Successfully read mod localization files."); } catch (Exception e) { Mod.LocalizedText = new ModText(); Log.Error?.Write(e, $"Failed to read localizations from: {localizationPath} due to error!"); } // Read lifepaths string lifepathsPath = Path.Combine(ModDir, "./lifepaths.json"); try { string jsonS = File.ReadAllText(lifepathsPath); Mod.LifePathFamilies = JsonConvert.DeserializeObject <Dictionary <string, LifePathFamily> >(jsonS); Log.Info?.Write($"Successfully read {Mod.LifePaths?.Count} lifepath families."); LifePathHelper.InitAtModLoad(); } catch (Exception e) { Mod.LocalizedText = new ModText(); Log.Error?.Write(e, $"Failed to read lifepaths from: {lifepathsPath} due to error!"); } // Initialize harmony var harmony = HarmonyInstance.Create(HarmonyPackage); harmony.PatchAll(Assembly.GetExecutingAssembly()); }