예제 #1
0
        /* Good news! Looking at HAR's code, this seems to have been made redundant.
         * This will be commented out in case it is needed ever again.
         * private static void StyleFixProcedure(PawnKindDef pawnkindDef)
         * {
         *  //HAR does not handle hair generation for pawnkinds, therefore I will fix this myself.
         *  //  To revert to default behavior that HAR already does with factions, I can temporarily set
         *  //  the pawnkind hairtags to null in order to stop forced hair generation.
         *  //Pawns that are allowed to have forced hair are pawns that already do spawn with hair (will change this later).
         *  //  However, pawns that are not supposed to spawn with hair should not have forced pawnkind hair gen.
         *  if (pawnkindDef?.styleItemTags != null)
         *  {
         *      Dictionary<Type, StyleSettings> loadedStyleSettings = raceStyleData.TryGetValue(pawnkindDef.race.defName);
         *      if (loadedStyleSettings != null)
         *      {
         *          List<StyleItemTagWeighted> insertedStyleItemTags = new List<StyleItemTagWeighted>();
         *          List<StyleItemTagWeighted> overriddenStyleItemTags = new List<StyleItemTagWeighted>();
         *          bool foundOverrides = false;
         *          prevPawnkindItemSettings = pawnkindDef.styleItemTags;
         *          //Start finding tag overrides first
         *          foreach (KeyValuePair<Type, StyleSettings> ts in loadedStyleSettings)
         *          {
         *              if (ts.Value != null
         *                  && ts.Value.hasStyle
         *                  && (ts.Key == typeof(TattooDef) && ModLister.IdeologyInstalled)
         *                  && ((ts.Value.styleTags?.Count > 0) || (ts.Value.styleTagsOverride?.Count > 0)))
         *              {
         *                  if (ts.Value.styleTags != null)
         *                      foreach (string s in ts.Value.styleTags)
         *                      {
         *                          insertedStyleItemTags.Add(new StyleItemTagWeighted(s, 1.0f));
         *                          overriddenStyleItemTags.Add(new StyleItemTagWeighted(s, 1.0f));
         *                      }
         *                  if (ts.Value.styleTagsOverride != null)
         *                      foreach (string s in ts.Value.styleTagsOverride)
         *                      {
         *                          overriddenStyleItemTags.Add(new StyleItemTagWeighted(s, 1.0f));
         *                          foundOverrides = true;
         *                      }
         *              }
         *          }
         *          if (foundOverrides)
         *              pawnkindDef.styleItemTags = overriddenStyleItemTags;
         *          else if (insertedStyleItemTags.Count > 0)
         *              pawnkindDef.styleItemTags?.AddRange(insertedStyleItemTags);
         *      }
         *  }
         * }
         */

        private static void BackstoryInjectionProcedure(PawnKindDef pawnkindDef, FactionDef factionDef)
        {
            /*  Backstory precedences (first-to-last):
             *      1.) Pawnkind backstories
             *      2.) Faction backstories
             *      3.) General backstories
             */
            string race = pawnkindDef.race.defName; //Because the race should've been assigned to already

            if (racesDiversified.ContainsKey(race))
            {
                if (ModSettingsHandler.DebugMode)
                {
                    PawnkindRaceDiversification.Logger.Message("Correcting backstory information for " + race + "... ");
                }

                //Extension data
                RaceDiversificationPool raceExtensionData = racesDiversified[race];
                FactionWeight           factionWeightData = null;
                if (factionDef != null)
                {
                    factionWeightData = raceExtensionData.factionWeights?.FirstOrFallback(w => w.factionDef == factionDef.defName);
                }
                PawnkindWeight pawnkindWeightData = raceExtensionData.pawnKindWeights?.FirstOrFallback(w => w.pawnKindDef == pawnkindDef.defName);

                //Handled backstory data
                List <string> backstoryCategories = new List <string>();
                List <BackstoryCategoryFilter> backstoryPawnkindFilters = new List <BackstoryCategoryFilter>();
                List <BackstoryCategoryFilter> backstoryFactionFilters  = new List <BackstoryCategoryFilter>();
                bool pawnkindBackstoryOverride = false;
                bool factionBackstoryOverride  = false;

                //Procedure
                backstoryCategories.AddRange(pawnkindWeightData?.backstoryCategories ?? new List <string>());
                backstoryPawnkindFilters.AddRange(pawnkindWeightData?.backstoryFilters ?? new List <BackstoryCategoryFilter>());
                pawnkindBackstoryOverride = pawnkindWeightData != null ? pawnkindWeightData.overrideBackstories : false;
                if (!pawnkindBackstoryOverride &&
                    !(raceExtensionData.overrideBackstories))
                {
                    backstoryCategories.AddRange(pawnkindDef.backstoryCategories ?? new List <string>());
                    backstoryPawnkindFilters.AddRange(pawnkindDef.backstoryFilters ?? new List <BackstoryCategoryFilter>());
                }
                if (!pawnkindBackstoryOverride)
                {
                    backstoryCategories.AddRange(factionWeightData?.backstoryCategories ?? new List <string>());
                    backstoryFactionFilters.AddRange(factionWeightData?.backstoryFilters ?? new List <BackstoryCategoryFilter>());
                    factionBackstoryOverride = factionWeightData != null ? factionWeightData.overrideBackstories : false;
                    if (!factionBackstoryOverride &&
                        !(raceExtensionData.overrideBackstories))
                    {
                        backstoryFactionFilters.AddRange(factionDef?.backstoryFilters ?? new List <BackstoryCategoryFilter>());
                    }
                }
                if (!pawnkindBackstoryOverride &&
                    !factionBackstoryOverride)
                {
                    backstoryCategories.AddRange(raceExtensionData.backstoryCategories ?? new List <string>());
                    backstoryFactionFilters.AddRange(raceExtensionData.backstoryFilters ?? new List <BackstoryCategoryFilter>());
                }

                //Failsafe
                if (backstoryFactionFilters.Count == 0 &&
                    backstoryPawnkindFilters.Count == 0 &&
                    backstoryCategories.Count == 0)
                {
                    //Nothing happened here.
                    if (ModSettingsHandler.DebugMode)
                    {
                        PawnkindRaceDiversification.Logger.Warning("Race did not get any backstories!");
                    }
                    return;
                }

                //Assignment
                if (factionDef != null)
                {
                    factionDef.backstoryFilters = backstoryFactionFilters;
                }
                pawnkindDef.backstoryCategories = backstoryCategories;
                pawnkindDef.backstoryFilters    = backstoryPawnkindFilters;

                if (ModSettingsHandler.DebugMode)
                {
                    PawnkindRaceDiversification.Logger.Message("Backstories selected successfully.");
                }
            }
            else
            if (ModSettingsHandler.DebugMode)
            {
                PawnkindRaceDiversification.Logger.Message(race + " does not have any extension data, therefore it cannot override backstories.");
            }
        }
예제 #2
0
        public static ThingDef WeightedRaceSelectionProcedure(PawnKindDef pawnKind, Faction faction)
        {
            /*      Precedences for weights (first-to-last):
             *          1.) Flat weight (user settings per-save)
             *              ~ World Load
             *          2.) Flat weight (user settings global)
             *          *3.) Flat weight (set by AlienRace XML)
             *              + **Pawnkind weight
             *              + **Faction weight
             *      *Weight chance increases from these conditions, but flat weight in settings overrides these
             *      **If either of these weights are negative, then this pawn cannot spawn in these conditions
             * */
            Dictionary <string, float> determinedWeights = new Dictionary <string, float>();
            string dbgstrList = "";

            foreach (KeyValuePair <string, RaceDiversificationPool> data in racesDiversified)
            {
                //Faction weight
                FactionWeight factionWeight = null;
                if (faction != null)
                {
                    factionWeight = data.Value.factionWeights?.Find(f => f.factionDef == faction.def.defName);
                }
                float fw = factionWeight != null ? factionWeight.weight : 0.0f;
                //Negative value would mean that this pawn shouldn't generate with this faction.
                //  Skip this race.
                if (fw < 0.0f)
                {
                    determinedWeights.Remove(data.Key);
                    continue;
                }
                determinedWeights.SetOrAdd(data.Key, fw);

                //Pawnkind weight
                PawnkindWeight pawnkindWeight = data.Value.pawnKindWeights?.Find(p => p.pawnKindDef == pawnKind.defName);
                float          pw             = pawnkindWeight != null ? pawnkindWeight.weight : 0.0f;
                //Negative value would mean that this pawn shouldn't generate as this pawnkind.
                //  Skip this race.
                if (pw < 0.0f)
                {
                    determinedWeights.Remove(data.Key);
                    continue;
                }
                determinedWeights.SetOrAdd(data.Key, pw + fw);

                //Flat generation weight
                float w = data.Value.flatGenerationWeight;
                //Negative value means that this is not modifiable in the mod options, but this race wants
                //  to add weights on its own.
                if (w < 0.0f)
                {
                    determinedWeights.SetOrAdd(data.Key, pw + fw);
                }
                else
                {
                    determinedWeights.SetOrAdd(data.Key, w + pw + fw);
                }
            }
            //Flat generation weight, determined by user settings (applied generally)
            //  Overrides previous weight calculations.
            //  Prevented if race has a negative flat weight.
            foreach (KeyValuePair <string, float> kv in ModSettingsHandler.setFlatWeights)
            {
                if (kv.Value >= 0.0f)
                {
                    determinedWeights.SetOrAdd(kv.Key, kv.Value);
                    if (ModSettingsHandler.DebugMode)
                    {
                        dbgstrList += kv.Key + ": " + kv.Value + "\n";
                    }
                }
            }
            if (ModSettingsHandler.DebugMode)
            {
                PawnkindRaceDiversification.Logger.Message("Flat weights found: \n" + dbgstrList);
                dbgstrList = "";
            }

            //Flat generation weight, determined by user settings (applied locally)
            //  Overrides previous weight calculations.
            //  Prevented if race has a negative flat weight.
            foreach (KeyValuePair <string, float> kv in ModSettingsHandler.setLocalFlatWeights)
            {
                if (kv.Value >= 0.0f)
                {
                    determinedWeights.SetOrAdd(kv.Key, kv.Value);
                    if (ModSettingsHandler.DebugMode)
                    {
                        dbgstrList += kv.Key + ": " + kv.Value + "\n";
                    }
                }
            }
            if (ModSettingsHandler.DebugMode)
            {
                PawnkindRaceDiversification.Logger.Message("Local save weights found: \n" + dbgstrList);
                dbgstrList = "";
            }

            //Flat generation weight, determined by user settings (applied for starting pawns - any pawn that is of player faction)
            //  Overrides previous weight calculations.
            //  Prevented if race has a negative flat weight.
            if (faction != null && faction.def.isPlayer)
            {
                foreach (KeyValuePair <string, float> kv in ModSettingsHandler.setLocalStartingPawnWeights)
                {
                    if (kv.Value >= 0.0f)
                    {
                        determinedWeights.SetOrAdd(kv.Key, kv.Value);
                        if (ModSettingsHandler.DebugMode)
                        {
                            dbgstrList += kv.Key + ": " + kv.Value + "\n";
                        }
                    }
                }
            }
            else
            {
                if (ModSettingsHandler.DebugMode)
                {
                    PawnkindRaceDiversification.Logger.Warning("This pawn wasn't a part of the player faction (of " + faction.ToStringSafe() + ", " + (faction?.def?.isPlayer).ToStringSafe() + ") ");
                }
            }
            if (ModSettingsHandler.DebugMode)
            {
                PawnkindRaceDiversification.Logger.Message("Starting pawn weights found: \n" + dbgstrList);
                dbgstrList = "";
                foreach (KeyValuePair <string, float> w in determinedWeights)
                {
                    dbgstrList += w.Key + ": " + w.Value + "\n";
                }
                PawnkindRaceDiversification.Logger.Message("Final determined weights: \n" + dbgstrList);
                dbgstrList = "";
            }

            //Calculate race selection with a weighting procedure
            float sumOfWeights = 0.0f;

            foreach (KeyValuePair <string, float> w in determinedWeights)
            {
                sumOfWeights += w.Value;
            }
            float rnd = Rand.Value * sumOfWeights;

            try
            {
                foreach (KeyValuePair <string, float> w in determinedWeights)
                {
                    if (rnd < w.Value)
                    {
                        return(racesLoaded[w.Key]);
                    }
                    rnd -= w.Value;
                }
            } catch (Exception)
            {
                //If you see this, contact me about this.
                PawnkindRaceDiversification.Logger.Warning("Failed to assign weighted race! Defaulting to the original race from the pawnkind instead.");
            }

            //Return the original pawnkind race if no race selected
            return(pawnKind.race);
        }