Exemplo n.º 1
0
        public string UWP(Planet.WorldType type = Planet.WorldType.NORMAL, double diameter = 0)
        {
            var builder = new StringBuilder();

            switch (type)
            {
            case Planet.WorldType.LGG:
                builder.AppendFormat("LGG - diameter {0} km", diameter.ToString("F"));
                break;

            case Planet.WorldType.SGG:
                builder.AppendFormat("SGG - diameter {0} km", diameter.ToString("F"));
                break;

            case Planet.WorldType.SMALL:
                builder.AppendFormat("{0}-S{1}{2}{3}-{4}", Starport, Atmosphere.ToString(), Hydro.ToString(), SocialUWP(), TechLevel.ToString());
                break;

            case Planet.WorldType.RING:
                builder.AppendFormat("{0}-R00{1}-{2}", Starport, SocialUWP(), TechLevel.ToString());
                break;

            case Planet.WorldType.NORMAL:
            case Planet.WorldType.PLANETOID:
                builder.AppendFormat("{0}-{1}{2}-{3}", Starport, PhysicalUWP(), SocialUWP(), TechLevel.ToString());
                break;

            case Planet.WorldType.STAR:
                builder.Append(Languages.CompanionStar);
                break;
            }
            return(builder.ToString());
        }
        public override void DefsLoaded()
        {
            //1. Preparing settings
            UpdateSettings();

            //2. Adding Tech Tab to Pawns
            //ThingDef injection stolen from the work of notfood for Psychology
            var zombieThinkTree = DefDatabase <ThinkTreeDef> .GetNamedSilentFail("Zombie");

            IEnumerable <ThingDef> things = (from def in DefDatabase <ThingDef> .AllDefs
                                             where def.race?.intelligence == Intelligence.Humanlike && (zombieThinkTree == null || def.race.thinkTreeMain != zombieThinkTree)
                                             select def);
            List <string> registered = new List <string>();

            foreach (ThingDef t in things)
            {
                if (t.inspectorTabsResolved == null)
                {
                    t.inspectorTabsResolved = new List <InspectTabBase>(1);
                }
                t.inspectorTabsResolved.Add(InspectTabManager.GetSharedInstance(typeof(ITab_PawnKnowledge)));
                if (t.comps == null)
                {
                    t.comps = new List <CompProperties>(1);
                }
                t.comps.Add(new CompProperties_Knowledge());
                registered.Add(t.defName);
            }
            InspectPaneUtility.Reset();

            //3. Preparing knowledge support infrastructure

            //a. Things everyone knows
            UniversalWeapons.AddRange(DefDatabase <ThingDef> .AllDefs.Where(x => x.IsWeapon));
            UniversalCrops.AddRange(DefDatabase <ThingDef> .AllDefs.Where(x => x.plant != null && x.plant.Sowable));

            //b. Minus things unlocked on research
            ThingFilter lateFilter = new ThingFilter();

            foreach (ResearchProjectDef tech in DefDatabase <ResearchProjectDef> .AllDefs)
            {
                tech.InferSkillBias();
                tech.CreateStuff(lateFilter, unlocked);
                foreach (ThingDef weapon in tech.UnlockedWeapons())
                {
                    UniversalWeapons.Remove(weapon);
                }
                foreach (ThingDef plant in tech.UnlockedPlants())
                {
                    UniversalCrops.Remove(plant);
                }
            }
            ;

            //c. Also removing atipical weapons
            List <string> ForbiddenWeaponTags = TechDefOf.WeaponsNotBasic.weaponTags;

            UniversalWeapons.RemoveAll(x => SplitSimpleWeapons(x, ForbiddenWeaponTags));
            List <ThingDef> garbage = new List <ThingDef>();

            garbage.Add(TechDefOf.WeaponsNotBasic);

            //d. Classifying pawn backstories
            PawnBackgroundUtility.BuildCache();

            //e. Telling humans what's going on
            ThingCategoryDef       knowledgeCat = TechDefOf.Knowledge;
            IEnumerable <ThingDef> codifiedTech = DefDatabase <ThingDef> .AllDefs.Where(x => x.IsWithinCategory(knowledgeCat));

            if (Prefs.LogVerbose || FullStartupReport)
            {
                Log.Message($"[HumanResources] Codified technologies: {codifiedTech.Select(x => x.label).ToStringSafeEnumerable()}");
                Log.Message($"[HumanResources] Basic crops: {UniversalCrops.ToStringSafeEnumerable()}");
                Log.Message($"[HumanResources] Basic weapons: {UniversalWeapons.ToStringSafeEnumerable()}");
                Log.Message($"[HumanResources] Basic weapons that require training: {SimpleWeapons.ToStringSafeEnumerable()}");
                Log.Warning($"[HumanResources] Basic weapons tags: {SimpleWeapons.Where(x => !x.weaponTags.NullOrEmpty()).SelectMany(x => x.weaponTags).Distinct().ToStringSafeEnumerable()}");
                if (FullStartupReport)
                {
                    Log.Warning("[HumanResources] Backstories classified by TechLevel:");
                    for (int i = 0; i < 8; i++)
                    {
                        TechLevel            level = (TechLevel)i;
                        IEnumerable <string> found = PawnBackgroundUtility.TechLevelByBackstory.Where(e => e.Value == level).Select(e => e.Key);
                        if (!found.EnumerableNullOrEmpty())
                        {
                            Log.Message($"- {level.ToString().CapitalizeFirst()} ({found.EnumerableCount()}): {found.ToStringSafeEnumerable()}");
                        }
                    }
                    Log.Warning("[HumanResources] Techs classified by associated skill:");
                    var skills = DefDatabase <SkillDef> .AllDefsListForReading.GetEnumerator();

                    while (skills.MoveNext())
                    {
                        SkillDef             skill = skills.Current;
                        IEnumerable <string> found = TechTracker.FindTechs(skill).Select(x => x.Tech.label);
                        Log.Message($"- {skill.LabelCap} ({found.EnumerableCount()}): {found.ToStringSafeEnumerable()}");
                    }
                }
            }
            else
            {
                Log.Message($"[HumanResources] This is what we know: {codifiedTech.EnumerableCount()} technologies processed, {UniversalCrops.Count()} basic crops, {UniversalWeapons.Count()} basic weapons + {SimpleWeapons.Count()} that require training.");
            }

            //4. Filling gaps on the database

            //a. TechBook dirty trick, but only now this is possible!
            TechDefOf.TechBook.stuffCategories  = TechDefOf.UnfinishedTechBook.stuffCategories = TechDefOf.LowTechCategories.stuffCategories;
            TechDefOf.TechDrive.stuffCategories = TechDefOf.HiTechCategories.stuffCategories;
            garbage.Add(TechDefOf.LowTechCategories);
            garbage.Add(TechDefOf.HiTechCategories);

            //b. Filling main tech category with subcategories
            foreach (ThingDef t in lateFilter.AllowedThingDefs.Where(t => !t.thingCategories.NullOrEmpty()))
            {
                foreach (ThingCategoryDef c in t.thingCategories)
                {
                    c.childThingDefs.Add(t);
                    if (!knowledgeCat.childCategories.NullOrEmpty() && !knowledgeCat.childCategories.Contains(c))
                    {
                        knowledgeCat.childCategories.Add(c);
                    }
                }
            }

            //c. Populating knowledge recipes and book shelves
            foreach (RecipeDef r in DefDatabase <RecipeDef> .AllDefs.Where(x => x.ingredients.Count == 1 && x.fixedIngredientFilter.AnyAllowedDef == null))
            {
                r.fixedIngredientFilter.ResolveReferences();
                r.defaultIngredientFilter.ResolveReferences();
            }
            foreach (ThingDef t in DefDatabase <ThingDef> .AllDefs.Where(x => x.thingClass == typeof(Building_BookStore)))
            {
                t.building.fixedStorageSettings.filter.ResolveReferences();
                t.building.defaultStorageSettings.filter.ResolveReferences();
            }

            //d. Removing temporary defs from database.
            foreach (ThingDef def in garbage)
            {
                AccessTools.Method(typeof(DefDatabase <ThingDef>), "Remove").Invoke(this, new object[] { def });
            }
        }
Exemplo n.º 3
0
        internal static void _ReapplyAllMods(this ResearchManager _this)                                                     //new ReapplyAllMods Method
        {
            if (Faction.OfPlayerSilentFail?.def?.techLevel == null || Faction.OfPlayer.def.techLevel == TechLevel.Undefined) // if some mod does something funky again....
            {
                return;
            }


            if (firstpass || facName != Faction.OfPlayer.def.defName)
            {
                startedAt = DateTime.Now;
                facName   = Faction.OfPlayer.def.defName;
                try
                {
                    GetAndReloadTL();        //store the default value for the techlevel because we will modify it later and we need the one from right now

                    isTribe = factionDefault == TechLevel.Neolithic;
                    LoadCfgValues();
                    firstpass = false;

                    //Debug
                    LogOutput.WriteLogMessage(Errorlevel.Debug, "Con A val= " + TechAdvancing_Config_Tab.Conditionvalue_A + "|||Con B Val= " + TechAdvancing_Config_Tab.Conditionvalue_B);
                }
                catch (Exception ex)
                {
                    LogOutput.WriteLogMessage(Errorlevel.Error, "Caught error in Reapply All Mods: " + ex.ToString());
                }
            }

            var researchProjectStoreTotal    = new Dictionary <TechLevel, int>();
            var researchProjectStoreFinished = new Dictionary <TechLevel, int>();

            for (int i = 0; i < Enum.GetValues(typeof(TechLevel)).Length; i++)
            {
                researchProjectStoreTotal.Add((TechLevel)i, 0);
                researchProjectStoreFinished.Add((TechLevel)i, 0);
            }

            foreach (var researchProjectDef in DefDatabase <ResearchProjectDef> .AllDefs)
            {
                //skip the research if it contains the disabled-tag:
                #region tagDesc

                /*
                 *  <ResearchProjectDef>
                 *      <defName>Firefoam</defName>
                 *      <label>firefoam</label>
                 *      <description>Allows the construction of firefoam poppers; fire-safety buildings which spread fire-retardant foam in response to encroaching flames.</description>
                 *      <baseCost>800</baseCost>
                 *      <techLevel>Industrial</techLevel>
                 *      <prerequisites>
                 *          <li>MicroelectronicsBasics</li>
                 *      </prerequisites>
                 * !    <tags>
                 * Important  !        <li>ta-ignore</li>
                 * !    </tags>
                 *      <requiredResearchBuilding>HiTechResearchBench</requiredResearchBuilding>
                 *      <researchViewX>7</researchViewX>
                 *      <researchViewY>4</researchViewY>
                 *  </ResearchProjectDef>
                 *
                 */
                #endregion

                if (researchProjectDef.tags?.Any(x => x.defName == "ta-ignore") != true)
                {
                    researchProjectStoreTotal[researchProjectDef.techLevel]++;        //total projects for techlevel
                    if (researchProjectDef.IsFinished)
                    {                                                                 // TODO filter out undefined later
                        researchProjectStoreFinished[researchProjectDef.techLevel]++; //finished projects for techlevel
                        researchProjectDef.ReapplyAllMods();                          // TODO always run it?
                    }
                }
                else
                {
                    LogOutput.WriteLogMessage(Errorlevel.Debug, "Found ta-ignore tag in:" + researchProjectDef.defName);
                }
            }

            TechAdvancing.Rules.researchProjectStoreTotal    = researchProjectStoreTotal;
            TechAdvancing.Rules.researchProjectStoreFinished = researchProjectStoreFinished;

            TechLevel newLevel = TechAdvancing.Rules.GetNewTechLevel();

            if (newLevel != TechLevel.Undefined)
            {
                if (firstNotificationHidden && DateTime.Now.Subtract(TimeSpan.FromSeconds(5)) > startedAt) //hiding the notification on world start
                {
                    if (Faction.OfPlayer.def.techLevel < newLevel)
                    {
                        Find.LetterStack.ReceiveLetter("newTechLevelLetterTitle".Translate(), "newTechLevelLetterContents".Translate(isTribe ? "configTribe".Translate() : "configColony".Translate()) + " " + newLevel.ToString() + ".", LetterDefOf.PositiveEvent);
                    }
                }
                else
                {
                    firstNotificationHidden = true;
                }

                Faction.OfPlayer.def.techLevel = newLevel;
            }

            /***
             * how techlevel increases:
             * player researched all techs of techlevel X and below. the techlevel rises to X+1
             *
             * player researched more than 50% of the techlevel Y then the techlevel rises to Y
             **/
            RecalculateTechlevel(false);
        }
Exemplo n.º 4
0
        static RemoveModernStuff()
        {
            DebugString.AppendLine("Lord of the Rings - The Third Age - Start Removal Log");
            DebugString.AppendLine("Tech Limiter Active: Max Level = " + MAX_TECHLEVEL.ToString());
            giveApproppriateTechLevels();

            removedDefs = 0;

            IEnumerable <ResearchProjectDef> projects =
                DefDatabase <ResearchProjectDef> .AllDefs.Where(rpd => rpd.techLevel > MAX_TECHLEVEL);

            things = new HashSet <ThingDef>(DefDatabase <ThingDef> .AllDefs.Where(td =>
                                                                                  td.techLevel > MAX_TECHLEVEL ||
                                                                                  (td.researchPrerequisites?.Any(rpd => projects.Contains(rpd)) ?? false) || new[]
            {
                "Gun_Revolver", "VanometricPowerCell", "PsychicEmanator", "InfiniteChemreactor", "Joywire",
                "Painstopper"
            }.Contains(td.defName)));

            DebugString.AppendLine("RecipeDef Removal List");
            var recipeDefsToRemove = DefDatabase <RecipeDef> .AllDefs.Where(rd =>
                                                                            rd.products.Any(tcc => things.Contains(tcc.thingDef)) ||
                                                                            rd.AllRecipeUsers.All(td => things.Contains(td)) ||
                                                                            projects.Contains(rd.researchPrerequisite)).Cast <Def>().ToList();

            recipeDefsToRemove?.RemoveAll(x =>
                                          x.defName == "ExtractMetalFromSlag" ||
                                          x.defName == "SmeltWeapon" ||
                                          x.defName == "DestroyWeapon" ||
                                          x.defName == "OfferingOfPlants_Meagre" ||
                                          x.defName == "OfferingOfPlants_Decent" ||
                                          x.defName == "OfferingOfPlants_Sizable" ||
                                          x.defName == "OfferingOfPlants_Worthy" ||
                                          x.defName == "OfferingOfPlants_Impressive" ||
                                          x.defName == "OfferingOfMeat_Meagre" ||
                                          x.defName == "OfferingOfMeat_Decent" ||
                                          x.defName == "OfferingOfMeat_Sizable" ||
                                          x.defName == "OfferingOfMeat_Worthy" ||
                                          x.defName == "OfferingOfMeat_Impressive" ||
                                          x.defName == "OfferingOfMeals_Meagre" ||
                                          x.defName == "OfferingOfMeals_Decent" ||
                                          x.defName == "OfferingOfMeals_Sizable" ||
                                          x.defName == "OfferingOfMeals_Worthy" ||
                                          x.defName == "OfferingOfMeals_Impressive" ||
                                          x.defName == "ROMV_ExtractBloodVial" ||
                                          x.defName == "ROMV_ExtractBloodPack"
                                          );
            RemoveStuffFromDatabase(typeof(DefDatabase <RecipeDef>), recipeDefsToRemove);

            DebugString.AppendLine("ResearchProjectDef Removal List");
            RemoveStuffFromDatabase(typeof(DefDatabase <ResearchProjectDef>), projects.Cast <Def>());


            DebugString.AppendLine("Scenario Part Removal List");
            FieldInfo getThingInfo =
                typeof(ScenPart_ThingCount).GetField("thingDef", BindingFlags.NonPublic | BindingFlags.Instance);

            foreach (ScenarioDef def in DefDatabase <ScenarioDef> .AllDefs)
            {
                foreach (ScenPart sp in def.scenario.AllParts)
                {
                    if (sp is ScenPart_ThingCount && things.Contains((ThingDef)getThingInfo?.GetValue(sp)))
                    {
                        def.scenario.RemovePart(sp);
                        DebugString.AppendLine("- " + sp.Label + " " + ((ThingDef)getThingInfo?.GetValue(sp)).label +
                                               " from " + def.label);
                    }
                }
            }

            foreach (ThingCategoryDef thingCategoryDef in DefDatabase <ThingCategoryDef> .AllDefs)
            {
                thingCategoryDef.childThingDefs.RemoveAll(things.Contains);
            }

            DebugString.AppendLine("Stock Generator Part Cleanup");
            foreach (TraderKindDef tkd in DefDatabase <TraderKindDef> .AllDefs)
            {
                for (int i = tkd.stockGenerators.Count - 1; i >= 0; i--)
                {
                    StockGenerator stockGenerator = tkd.stockGenerators[i];

                    switch (stockGenerator)
                    {
                    case StockGenerator_SingleDef sd when things.Contains(Traverse.Create(sd).Field("thingDef")
                                                                          .GetValue <ThingDef>()):
                        ThingDef def = Traverse.Create(sd).Field("thingDef")
                                       .GetValue <ThingDef>();

                        tkd.stockGenerators.Remove(stockGenerator);
                        DebugString.AppendLine("- " + def.label + " from " + tkd.label +
                                               "'s StockGenerator_SingleDef");
                        break;

                    case StockGenerator_MultiDef md:
                        Traverse        thingListTraverse = Traverse.Create(md).Field("thingDefs");
                        List <ThingDef> thingList         = thingListTraverse.GetValue <List <ThingDef> >();
                        var             removeList        = thingList.FindAll(things.Contains);
                        removeList?.ForEach(x =>
                                            DebugString.AppendLine("- " + x.label + " from " + tkd.label +
                                                                   "'s StockGenerator_MultiDef"));
                        thingList.RemoveAll(things.Contains);

                        if (thingList.NullOrEmpty())
                        {
                            tkd.stockGenerators.Remove(stockGenerator);
                        }
                        else
                        {
                            thingListTraverse.SetValue(thingList);
                        }
                        break;
                    }
                }
            }


            DebugString.AppendLine("IncidentDef Removal List");



            IEnumerable <IncidentDef> incidents = DefDatabase <IncidentDef> .AllDefs
                                                  .Where(id => new[]
            {
                typeof
                (IncidentWorker_ShipChunkDrop
                ),
                AccessTools
                .TypeByName(
                    "IncidentWorker_ShipPartCrash"),
                typeof
                (IncidentWorker_QuestJourneyOffer
                ),
                typeof
                (IncidentWorker_ResourcePodCrash
                ),
                //typeof(IncidentWorker_RefugeePodCrash),
                typeof(IncidentWorker_TransportPodCrash),
                typeof
                (IncidentWorker_PsychicDrone
                ),
                typeof
                (IncidentWorker_RansomDemand
                ),
                typeof
                (IncidentWorker_ShortCircuit
                ),
                typeof
                (IncidentWorker_OrbitalTraderArrival
                ),
                typeof
                (IncidentWorker_PsychicSoothe
                )
            }.SelectMany(
                                                             it =>
                                                             it
                                                             .AllSubclassesNonAbstract()
                                                             .Concat(
                                                                 it))
                                                         .ToArray()
                                                         .Contains(
                                                             id
                                                             .workerClass) ||
                                                         new[]
            {
                "Disease_FibrousMechanites",
                "Disease_SensoryMechanites",
                "RaidEnemyEscapeShip",
                "StrangerInBlackJoin"
            }.Contains(
                                                             id
                                                             .defName)).ToList();


            foreach (IncidentDef incident in incidents)
            {
                incident.targetTags?.Clear();
                incident.baseChance = 0f;
                incident.allowedBiomes?.Clear();
                incident.earliestDay = int.MaxValue;
            }

            RemoveStuffFromDatabase(typeof(DefDatabase <IncidentDef>), incidents.Cast <Def>());



            DebugString.AppendLine("Replaced Ancient Asphalt Road / Ancient Asphalt Highway with Stone Road");
            RoadDef[] targetRoads  = { RoadDefOf.AncientAsphaltRoad, RoadDefOf.AncientAsphaltHighway };
            RoadDef   originalRoad = DefDatabase <RoadDef> .GetNamed("StoneRoad");

            List <string> fieldNames = AccessTools.GetFieldNames(typeof(RoadDef));

            fieldNames.Remove("defName");
            foreach (FieldInfo fi in fieldNames.Select(name => AccessTools.Field(typeof(RoadDef), name)))
            {
                object fieldValue = fi.GetValue(originalRoad);
                foreach (RoadDef targetRoad in targetRoads)
                {
                    fi.SetValue(targetRoad, fieldValue);
                }
            }

            DebugString.AppendLine("Special Hediff Removal List");
            RemoveStuffFromDatabase(typeof(DefDatabase <HediffDef>), (hediffs = new[] { HediffDefOf.Gunshot }).Cast <Def>());

            DebugString.AppendLine("RaidStrategyDef Removal List");
            RemoveStuffFromDatabase(typeof(DefDatabase <RaidStrategyDef>),
                                    DefDatabase <RaidStrategyDef> .AllDefs
                                    .Where(rs => typeof(ScenPart_ThingCount).IsAssignableFrom(rs.workerClass)).Cast <Def>());

            //            ItemCollectionGeneratorUtility.allGeneratableItems.RemoveAll(match: things.Contains);
            //
            //            foreach (Type type in typeof(ItemCollectionGenerator_Standard).AllSubclassesNonAbstract())
            //                type.GetMethod(name: "Reset")?.Invoke(obj: null, parameters: null);

            DebugString.AppendLine("ThingDef Removal List");
            RemoveStuffFromDatabase(typeof(DefDatabase <ThingDef>), things.ToArray());

            DebugString.AppendLine("ThingSetMaker Reset");
            ThingSetMakerUtility.Reset();

            DebugString.AppendLine("TraitDef Removal List");
            RemoveStuffFromDatabase(typeof(DefDatabase <TraitDef>),
                                    //                                                                   { nameof(TraitDefOf.Prosthophobe), "Prosthophile" } ?
                                    DefDatabase <TraitDef> .AllDefs
                                    .Where(td => new[] { nameof(TraitDefOf.BodyPurist), "Transhumanist" }.Contains(td.defName))
                                    .Cast <Def>());

            DebugString.AppendLine("Designators Resolved Again");
            MethodInfo resolveDesignatorsAgain = typeof(DesignationCategoryDef).GetMethod("ResolveDesignators",
                                                                                          BindingFlags.NonPublic | BindingFlags.Instance);

            foreach (DesignationCategoryDef dcd in DefDatabase <DesignationCategoryDef> .AllDefs)
            {
                resolveDesignatorsAgain?.Invoke(dcd, null);
            }

            DebugString.AppendLine("PawnKindDef Removal List");
            RemoveStuffFromDatabase(typeof(DefDatabase <PawnKindDef>),
                                    DefDatabase <PawnKindDef> .AllDefs
                                    .Where(pkd =>
                                           (!pkd.defaultFactionType?.isPlayer ?? false) &&
                                           (pkd.race.techLevel > MAX_TECHLEVEL || pkd.defaultFactionType?.techLevel > MAX_TECHLEVEL) &&
                                           !pkd.defName.EqualsIgnoreCase("Villager") && !pkd.defName.EqualsIgnoreCase("SpaceRefugee"))
                                    .Cast <Def>());

            DebugString.AppendLine("FactionDef Removal List");
            RemoveStuffFromDatabase(typeof(DefDatabase <FactionDef>),
                                    DefDatabase <FactionDef> .AllDefs.Where(fd => !fd.isPlayer && fd.techLevel > MAX_TECHLEVEL).Cast <Def>());

            DebugString.AppendLine("BackstoryDef Removal List");
            BackstoryHandler.RemoveIncompatibleBackstories(DebugString);

            DebugString.AppendLine("MapGeneratorDef Removal List");
            DebugString.AppendLine("- GenStep_SleepingMechanoids");
            DebugString.AppendLine("- GenStep_Turrets");
            DebugString.AppendLine("- GenStep_Power");
            foreach (MapGeneratorDef mgd in DefDatabase <MapGeneratorDef> .AllDefs)
            {
                mgd.genSteps.RemoveAll(gs =>
                                       gs.genStep is GenStep_SleepingMechanoids || gs.genStep is GenStep_Turrets ||
                                       gs.genStep is GenStep_Power);
            }

            DebugString.AppendLine("RuleDef Removal List");
            DebugString.AppendLine("- SymbolResolver_AncientCryptosleepCasket");
            DebugString.AppendLine("- SymbolResolver_ChargeBatteries");
            DebugString.AppendLine("- SymbolResolver_EdgeMannedMortor");
            DebugString.AppendLine("- SymbolResolver_FirefoamPopper");
            DebugString.AppendLine("- SymbolResolver_MannedMortar");
            DebugString.AppendLine("- SymbolResolver_");
            foreach (RuleDef rd in DefDatabase <RuleDef> .AllDefs)
            {
                rd.resolvers.RemoveAll(sr =>
                                       sr is SymbolResolver_AncientCryptosleepCasket || sr is SymbolResolver_ChargeBatteries ||
                                       sr is SymbolResolver_EdgeMannedMortar || sr is SymbolResolver_FirefoamPopper ||
                                       sr is SymbolResolver_MannedMortar || sr is SymbolResolver_OutdoorLighting);
                if (rd.resolvers.Count == 0)
                {
                    rd.resolvers.Add(new SymbolResolver_AddWortToFermentingBarrels());
                }
            }

            Log.Message("Removed " + removedDefs + " modern defs");

            PawnWeaponGenerator.Reset();
            PawnApparelGenerator.Reset();

            Debug.Log(DebugString.ToString());
            DebugString = new StringBuilder();
        }
Exemplo n.º 5
0
        static void Postfix()
        {
            if (Faction.OfPlayerSilentFail?.def?.techLevel == null || Faction.OfPlayer.def.techLevel == TechLevel.Undefined) // abort if our techlevel is undefined for some reason
            {
                LogOutput.WriteLogMessage(Errorlevel.Debug, "Aborted reasearch manager postfix!");
                return;
            }

            LogOutput.WriteLogMessage(Errorlevel.Debug, "Research Manager called");

            if (Find.CurrentMap == null)
            {
                //LogOutput.WriteLogMessage(Errorlevel.Information, "Research Manager called while loading a new map. Flushing old values.");
                FlushCfg();
            }

            if (firstpass || facName != Faction.OfPlayer.def.defName)
            {
                startedAt = DateTime.Now;
                LogOutput.WriteLogMessage(Errorlevel.Debug, "Research Manager restarted");
                facName = Faction.OfPlayer.def.defName;
                try
                {
                    GetAndReloadTL();        //store the default value for the techlevel because we will modify it later and we need the one from right now

                    isTribe = factionDefault == TechLevel.Neolithic;
                    //LoadCfgValues();
                    firstpass = false;
                }
                catch (Exception ex)
                {
                    LogOutput.WriteLogMessage(Errorlevel.Error, "Caught error in Reapply All Mods: " + ex.ToString());
                }
            }

            UpdateFinishedProjectCounts();

            TechLevel newLevel = TechAdvancing.Rules.GetNewTechLevel();

            if (newLevel != TechLevel.Undefined)
            {
                if (firstNotificationHidden && DateTime.Now.Subtract(TimeSpan.FromSeconds(5)) > startedAt) //hiding the notification on world start
                {
                    if (Faction.OfPlayer.def.techLevel < newLevel)
                    {
                        Find.LetterStack.ReceiveLetter("newTechLevelLetterTitle".Translate(), "newTechLevelLetterContents".Translate(isTribe ? "configTribe".Translate() : "configColony".Translate()) + " " + newLevel.ToString() + ".", LetterDefOf.PositiveEvent);
                    }
                }
                else
                {
                    firstNotificationHidden = true;
                }

                LogOutput.WriteLogMessage(Errorlevel.Debug, $"Factiondeflevel was changed from {Faction.OfPlayer.def.techLevel} to {newLevel} via call #1.");
                Faction.OfPlayer.def.techLevel = newLevel;
            }

            /***
             * how techlevel increases:
             * player researched all techs of techlevel X and below. the techlevel rises to X+1
             *
             * player researched more than 50% of the techlevel Y then the techlevel rises to Y
             **/
            RecalculateTechlevel(false);
        }
Exemplo n.º 6
0
        public IEnumerable <ResearchProjectDef> GetExpertiseDefsFor(Pawn pawn, FactionDef faction)
        {
            //1. Gather info on that pawn

            //a. tech level
            TechLevel factionTechLevel = faction?.techLevel ?? 0;
            TechLevel childhoodLevel   = 0;
            SkillDef  childhoodSkill   = null;
            bool      isPlayer         = pawn.Faction?.IsPlayer ?? false;

            techLevel = TechPoolIncludesBackground || !isPlayer?FindBGTechLevel(pawn, out childhoodLevel, out childhoodSkill) : factionTechLevel;

            TechLevel workingTechLevel = startingTechLevel = techLevel;

            //b. higest skills
            SkillRecord highestSkillRecord             = pawn.skills.skills.Aggregate(AccessHighestSkill);
            SkillDef    highestSkill                   = highestSkillRecord.def;
            IEnumerable <SkillRecord> secondCandidates = pawn.skills.skills.Except(highestSkillRecord).Where(x => SkillIsRelevant(x.def, techLevel));
            SkillDef secondSkill = secondCandidates.Aggregate(AccessHighestSkill).def;

            //c. age
            float middleAge    = pawn.RaceProps.lifeExpectancy / 2;
            int   matureAge    = pawn.RaceProps.lifeStageAges.FindLastIndex(x => x.minAge < middleAge); //not always the last possible age because there are mods with an "eldery" stage
            int   growthAdjust = 0;
            int   oldBonus     = 0;

            if (pawn.ageTracker.CurLifeStageIndex < matureAge)
            {
                growthAdjust = matureAge - pawn.ageTracker.CurLifeStageIndex;
            }
            else if (pawn.ageTracker.AgeBiologicalYears > middleAge)
            {
                oldBonus = 1;
            }

            //d. special cases
            isFighter = highestSkill == SkillDefOf.Melee;
            isShooter = highestSkill == SkillDefOf.Shooting;
            int  fighterHandicap = (isFighter | isShooter) ? 1 : 0;
            bool guru            = techLevel < TechLevel.Archotech && highestSkill == SkillDefOf.Intellectual && highestSkillRecord.Level >= Rand.Range(7, 10);

            //2. Calculate how many techs he should know
            int minSlots = techLevel > TechLevel.Medieval ? 1 : oldBonus;
            int slots    = Mathf.Max(minSlots, FactionExpertiseRange(techLevel) - growthAdjust + oldBonus - fighterHandicap);

            if (slots == 0)
            {
                if (Prefs.LogVerbose)
                {
                    Log.Warning($"... No slots for {pawn.gender.GetObjective()}, returning null. (StartingTechLevel is {techLevel}, CurLifeStageIndex is {pawn.ageTracker.CurLifeStageIndex}, fighterHandicap is {fighterHandicap})");
                }
                return(null);
            }

            //3. Info for debugging.

            if (Prefs.LogVerbose)
            {
                StringBuilder stringBuilder = new StringBuilder();
                string        factionName   = faction.label.ToLower() ?? pawn.Possessive().ToLower() + faction;
                if (TechPoolIncludesStarting)
                {
                    stringBuilder.Append($"default for {factionName}");
                }
                if (TechPoolIncludesTechLevel)
                {
                    stringBuilder.AppendWithComma($"{factionTechLevel.ToString().ToLower()} age");
                }
                if (TechPoolIncludesScenario)
                {
                    stringBuilder.AppendWithComma($"{Find.Scenario.name.ToLower()} scenario");
                }
                if (TechPoolIncludesBackground)
                {
                    stringBuilder.AppendWithComma($"{childhoodLevel.ToString().ToLower()} childhood & {techLevel.ToString().ToLower()} background");
                }
                Log.Message($"... Including technologies from: " + stringBuilder.ToString() + ".");
                stringBuilder.Clear();
                string guruText = guru ? " (allowing advanced knowledge)" : "";
                stringBuilder.Append($"... As {pawn.ageTracker.CurLifeStage.label}, {pawn.ProSubj()} gets {slots} slots. {pawn.Possessive().CapitalizeFirst()} highest relevant skills are {highestSkill.label}{guruText} & {secondSkill.label}.");
                Log.Message(stringBuilder.ToString());
            }

            //4. Finally, Distribute knowledge
            bool strict       = false;
            bool useChildhood = childhoodSkill != null && TechPoolIncludesBackground && SkillIsRelevant(childhoodSkill, childhoodLevel) && slots > 1;
            var  filtered     = TechTracker.FindTechs(x => TechPool(isPlayer, x, workingTechLevel, strict));
            int  pass         = 0;
            List <ResearchProjectDef> result = new List <ResearchProjectDef>();

            if (guru)
            {
                workingTechLevel++;
            }
            while (result.Count() < slots)
            {
                pass++;
                filtered.ExecuteEnumerable();
                if (filtered.EnumerableNullOrEmpty())
                {
                    Log.Warning("[HumanResources] Empty technology pool!");
                }
                var remaining = filtered.Where(x => !result.Contains(x));
                if (remaining.EnumerableNullOrEmpty())
                {
                    break;
                }
                SkillDef skill = null;
                if (pass == 1 && remaining.Any(x => x.Skills.Contains(highestSkill)))
                {
                    skill = highestSkill;
                }
                else if (pass == 2 && remaining.Any(x => x.Skills.Contains(secondSkill)))
                {
                    skill = useChildhood ? childhoodSkill : secondSkill;
                }
                ResearchProjectDef selected = remaining.RandomElementByWeightWithDefault(x => TechLikelihoodForSkill(pawn, x.Skills, slots, pass, skill), 1f) ?? remaining.RandomElement();
                result.Add(selected);

                //prepare next pass:
                strict = false;
                if ((guru && pass == 1) | result.NullOrEmpty())
                {
                    workingTechLevel--;
                }
                if (useChildhood)
                {
                    if (pass == 1)
                    {
                        strict           = true;
                        workingTechLevel = childhoodLevel;
                    }
                    if (pass == 2)
                    {
                        workingTechLevel = techLevel;
                    }
                }
                if (workingTechLevel == 0)
                {
                    break;
                }
            }
            if (!result.NullOrEmpty())
            {
                return(result);
            }
            Log.Error($"[HumanResources] Couldn't calculate any expertise for {pawn}");
            return(null);
        }
Exemplo n.º 7
0
        public override void DoWindowContents(Rect canvas)
        {
            // zooming in seems to cause Text.Font to start at Tiny, make sure it's set to Small for our panels.
            Text.Font = GameFont.Small;
            float drawpos = 0;

            DrawText(canvas, description, ref drawpos);
            AddSpace(ref drawpos, 10f);
            if (Widgets.RadioButtonLabeled(new Rect(canvas.x + 20, drawpos, 100f, 60f), "configRadioBtnNeolithic".Translate(), baseTechlvlCfg == 0)) //translation default: Neolithic / Tribal
            {
                baseTechlvlCfg = 0;
            }
            if (Widgets.RadioButtonLabeled(new Rect(canvas.x + 200f, drawpos, 100f, 60f), "configRadioBtnAutoDetect".Translate(), baseTechlvlCfg == 1)) //translation default: Auto-Detect (default)
            {
                baseTechlvlCfg = 1;
            }

            if (Widgets.RadioButtonLabeled(new Rect(canvas.x + 400f, drawpos, 100f, 60f), "configRadioBtnIndustrial".Translate(), baseTechlvlCfg == 2)) //translation default: Industrial / Colony
            {
                baseTechlvlCfg = 2;
            }
            AddSpace(ref drawpos, 70f);
            DrawText(canvas, "configBaseTechLvl".Translate() + " (" + ((baseTechlvlCfg == 1) ? ((_ResearchManager.isTribe) ? "configTribe".Translate() : "configColony".Translate()) : ((baseTechlvlCfg == 0) ? "configSetToTribe".Translate() : "configSetToColony".Translate())) + "): " + ((baseTechlvlCfg == 1) ? _ResearchManager.factionDefault.ToString().TranslateOrDefault(null, "TA_TL_") : ((baseTechlvlCfg == 0) ? "configNeolithic".Translate() : "configIndustrial".Translate())), ref drawpos);
            AddSpace(ref drawpos, 20f);
            baseFactionTechLevel = _ResearchManager.factionDefault;
            if (baseTechlvlCfg != 1)
            {
                baseFactionTechLevel = (baseTechlvlCfg == 0) ? TechLevel.Neolithic : TechLevel.Industrial;
            }
            DrawText(canvas, descriptionA2 + " (" + "configWordDefault".Translate() + Conditionvalue_A_Default + ")", ref drawpos);
            string bufferA = null;
            string bufferB = null;

            Widgets.TextFieldNumeric(new Rect(canvas.x + Verse.Text.CalcSize(descriptionA2_calc + " (" + "configWordDefault".Translate() + Conditionvalue_A_Default + ")").x - 25f, canvas.y + drawpos - 22f, 50f, Verse.Text.CalcSize("Text").y), ref Conditionvalue_A, ref bufferA, -100, 100);
            AddSpace(ref drawpos, 10f);
            DrawText(canvas, "configExpectedTechLvl".Translate() + " " + ((TechLevel)Math.Min((int)TechLevel.Archotech, (int)previewTechLevels[0])).ToString().TranslateOrDefault(null, "TA_TL_"), ref drawpos);

            AddSpace(ref drawpos, 20f);
            DrawText(canvas, descriptionB2.Replace("50", Conditionvalue_B_s.ToString()) + " (" + "configWordDefault".Translate() + Conditionvalue_B_Default + ")", ref drawpos);
            Widgets.TextFieldNumeric(new Rect(canvas.x + Verse.Text.CalcSize(descriptionB2_calc + " (" + "configWordDefault".Translate() + Conditionvalue_B_Default + ")").x - 25f, canvas.y + drawpos - 22f, 50f, Verse.Text.CalcSize("Text").y), ref Conditionvalue_B, ref bufferB, -100, 100);

            AddSpace(ref drawpos, 10f);
            DrawText(canvas, "configExpectedTechLvl".Translate() + " " + ((TechLevel)Math.Min((int)TechLevel.Archotech, (int)previewTechLevels[1])).ToString().TranslateOrDefault(null, "TA_TL_"), ref drawpos);
            AddSpace(ref drawpos, 20f);


            DrawText(canvas, descriptionB2_s + " (" + "configWordDefault".Translate() + Conditionvalue_B_s_Default + ")", ref drawpos);
            AddSpace(ref drawpos, 10f);
            Conditionvalue_B_s = (int)Widgets.HorizontalSlider(new Rect(canvas.x, canvas.y + drawpos, 500, 15), Conditionvalue_B_s, 1, 100, true, "50%", "1%", "100%", 1);
            DrawText(new Rect(canvas.x + 530, canvas.y - 5, canvas.width, canvas.height), $"{Conditionvalue_B_s}%", ref drawpos);

            AddSpace(ref drawpos, 20f);

            //if (b_configCheckboxNeedTechColonists != (configCheckboxNeedTechColonists == 1))
            //{
            //    previewTechLevels[2] = (Util.ColonyHasHiTechPeople()) ? TechLevel.Archotech : TechAdvancing_Config_Tab.maxTechLevelForTribals;
            //}

            b_configCheckboxNeedTechColonists = configCheckboxNeedTechColonists == 1;

            Widgets.CheckboxLabeled(new Rect(canvas.x, drawpos, Verse.Text.CalcSize("configCheckboxNeedTechColonists".Translate(maxTechLevelForTribals.ToString().TranslateOrDefault(null, "TA_TL_"))).x + 40f, 40f), "configCheckboxNeedTechColonists".Translate(maxTechLevelForTribals.ToString().TranslateOrDefault(null, "TA_TL_")), ref b_configCheckboxNeedTechColonists, false);
            configCheckboxNeedTechColonists = (b_configCheckboxNeedTechColonists) ? 1 : 0;
            AddSpace(ref drawpos, 32f);

            if (previewTechLevels[2] == maxTechLevelForTribals && b_configCheckboxNeedTechColonists)
            {
                DrawText(canvas, "configCheckboxNeedTechColonists_CappedAt".Translate(maxTechLevelForTribals.ToString().TranslateOrDefault(null, "TA_TL_")), ref drawpos, false, Color.red);
            }



            AddSpace(ref drawpos, 50f);
            DrawText(canvas, "configResultingTechLvl".Translate() + " " + Rules.GetNewTechLevel().ToString().TranslateOrDefault(null, "TA_TL_"), ref drawpos);

            AddSpace(ref drawpos, 30f);
            DrawText(canvas, "availableTechLvls".Translate(), ref drawpos);

            AddSpace(ref drawpos, 10f);
            string[] techLevels = Enum.GetNames(typeof(TechLevel));
            for (int i = 0; i < techLevels.Length; i++)
            {
                DrawText(canvas, techLevels[i].ToString().TranslateOrDefault(null, "TA_TL_") + " = " + i, ref drawpos);
            }
        }
Exemplo n.º 8
0
        static void Postfix()
        {
            if (Settings.AllowTechAdvance == true)
            {
                TechLevel currentTechLevel = Faction.OfPlayer.def.techLevel;
#if DEBUG
                Log.Warning("Tech Level: " + currentTechLevel);
#endif
                int totalCurrentAndPast = 0;
                int finishedResearch    = 0;

                foreach (ResearchProjectDef def in DefDatabase <ResearchProjectDef> .AllDefs)
                {
                    if (def.IsFinished)
                    {
                        ++finishedResearch;
                        //if (def.techLevel <= currentTechLevel)
                        //    ++finishedCurrentAndPast;
                        //else
                        //    ++finishedFuture;
                    }


                    if (def.techLevel <= currentTechLevel)
                    {
                        ++totalCurrentAndPast;
                    }
                }

                int  neededTechsToAdvance = 0;
                bool useStatisPerTier     = Settings.StaticNumberResearchPerTier;
                if (useStatisPerTier)
                {
                    switch (Faction.OfPlayer.def.techLevel)
                    {
                    case TechLevel.Neolithic:
                        neededTechsToAdvance = Settings.NeolithicNeeded;
                        break;

                    case TechLevel.Medieval:
                        neededTechsToAdvance = Settings.MedievalNeeded;
                        break;

                    case TechLevel.Industrial:
                        neededTechsToAdvance = Settings.IndustrialNeeded;
                        break;

                    case TechLevel.Spacer:
                        neededTechsToAdvance = Settings.SpacerNeeded;
                        break;
                    }
                }

#if DEBUG
                Log.Warning("Current Tech Level: " + Faction.OfPlayer.def.techLevel);
                Log.Warning("neededTechsToAdvance: " + neededTechsToAdvance);
                Log.Warning("totalCurrentAndPast: " + totalCurrentAndPast);
                Log.Warning("finishedResearch: " + finishedResearch);
#endif

                if ((useStatisPerTier && neededTechsToAdvance < finishedResearch) ||
                    (!useStatisPerTier && totalCurrentAndPast + 1 < finishedResearch))
                {
                    if (Faction.OfPlayer.def.techLevel < TechLevel.Spacer)
                    {
                        if (Scribe.mode == LoadSaveMode.Inactive)
                        {
                            // Only display this message is not loading
                            Messages.Message(
                                "Advancing Tech Level from [" + currentTechLevel.ToString() + "] to [" + (currentTechLevel + 1).ToString() + "].",
                                MessageTypeDefOf.PositiveEvent);
                        }

                        Faction.OfPlayer.def.techLevel = currentTechLevel + 1;
                    }
                }
                else
                {
                    int needed = (useStatisPerTier) ? neededTechsToAdvance - finishedResearch : totalCurrentAndPast + 1 - finishedResearch;
                    Log.Message("Tech Advance: Need to research [" + needed + "] more technologies");
                }
            }
            if (Settings.ChangeBaseCosts)
            {
                foreach (var cost in Settings.ResearchBaseCosts)
                {
                    var techDef = ResearchTimeUtil.GetResearchDef(cost.Key);
                    if (techDef != null)
                    {
                        techDef.baseCost = cost.Value;
                    }
                }
            }
        }