public override void ExposeData() { base.ExposeData(); Scribe_Collections.Look(ref Configvalues, "TA_Expose_Numbers", LookMode.Value, LookMode.Value); int isPplDictSaved = 1; LogOutput.WriteLogMessage(Errorlevel.Information, "isPplDictSaved:" + isPplDictSaved.ToString()); Scribe_Values.Look(ref isPplDictSaved, "TA_Expose_People_isSaved", -1, true); LogOutput.WriteLogMessage(Errorlevel.Information, "isPplDictSaved:" + isPplDictSaved.ToString()); if (ColonyPeople != null) { ColonyPeople.RemoveAll(x => x.Key == null); if (isPplDictSaved == 1 && ColonyPeople.Count > 0) { LogOutput.WriteLogMessage(Errorlevel.Information, "ColonyPeople: " + ColonyPeople.ToStringFullContents()); Scribe_Collections.Look(ref ColonyPeople, "TA_Expose_People", LookMode.Reference, LookMode.Reference); LogOutput.WriteLogMessage(Errorlevel.Information, "Read TA_ExposePeople"); } } TechAdvancing_Config_Tab.ExposeData(TA_Expose_Mode.Load); if (ColonyPeople == null) { ColonyPeople = new Dictionary <Pawn, Faction>(); } LogOutput.WriteLogMessage(Errorlevel.Information, "Loading finished."); }
public static void TA_ExposeData(string key, ref int value, TA_Expose_Mode mode = TA_Expose_Mode.Load) { bool accessWasValid = false; if (mode == TA_Expose_Mode.Save) { LogOutput.WriteLogMessage(Errorlevel.Debug, "Adding " + key + " : " + value + "to save dictionary"); if (Configvalues.ContainsKey(GetInt(key))) { Configvalues.Remove(GetInt(key)); } Configvalues.Add(GetInt(key), value); } else if (mode == TA_Expose_Mode.Load) { accessWasValid = Configvalues.TryGetValue(GetInt(key), out int tempval); if (accessWasValid) { value = tempval; } else { //TA_Expose_Numbers.Add(getInt(key),) LogOutput.WriteLogMessage(Errorlevel.Information, "Value " + GetInt(key) + " could not be loaded. This usually happens when updating to the new config-system. Try saving and reloading the map."); } LogOutput.WriteLogMessage(Errorlevel.Debug, "Loaded " + key + " : " + value + "from save dictionary. Success: " + accessWasValid); } }
internal static void RecalculateTechlevel(bool showIncreaseMsg = true) { if (Faction.OfPlayerSilentFail?.def?.techLevel == null || Faction.OfPlayer.def.techLevel == TechLevel.Undefined) // if some mod does something funky again.... { return; } GetAndReloadTL(); TechLevel baseNewTL = Rules.GetNewTechLevel(); if (TechAdvancing_Config_Tab.ConfigCheckboxNeedTechColonists == 1 && !Util.ColonyHasHiTechPeople()) { var newTl = (TechLevel)Util.Clamp((int)TechLevel.Undefined, (int)baseNewTL, (int)TechAdvancing_Config_Tab.maxTechLevelForTribals); LogOutput.WriteLogMessage(Errorlevel.Debug, $"Factiondeflevel was changed from {Faction.OfPlayer.def.techLevel} to {newTl} via call #2."); Faction.OfPlayer.def.techLevel = newTl; } else { LogOutput.WriteLogMessage(Errorlevel.Debug, $"Factiondeflevel was changed from {Faction.OfPlayer.def.techLevel} to {baseNewTL} via call #3."); Faction.OfPlayer.def.techLevel = baseNewTL; } if (showIncreaseMsg) //used to supress the first update message| Treat as always false { Messages.Message("ConfigEditTechlevelChange".Translate() + " " + (TechLevel)Faction.OfPlayer.def.techLevel + ".", MessageTypeDefOf.PositiveEvent); } }
public static void DoSettingsWindowContents(Rect rect) { Rect TA_Cfgrect = new Rect(0f, 0f, 180f, 20f); TA_Cfgrect.x = (rect.width - TA_Cfgrect.width) / 4f; TA_Cfgrect.y = 40f; float drawpos = 10f + rect.position.y; Color defaultGuiColor = GUI.contentColor; if (Current.ProgramState == ProgramState.Playing) { if (Widgets.ButtonText(TA_Cfgrect, "TAcfgmenulabel".Translate(), true, false, true)) { Find.WindowStack.Add(new TechAdvancing_Config_Tab()); } } else { if (settingsText == null) { settingsText = string.Join("\n", ConfigTabValueSavedAttribute.attributeDefaultValues.Select(x => $"{x.Key}:{x.Value}")); } GUI.Label(new Rect(rect.position.x, drawpos, rect.width, 20), "TAcfgDefaultsHeader".Translate()); AddSpace(ref drawpos, 10 + 20); var r = new Rect(rect.position.x, drawpos, rect.width, rect.height - drawpos - 50); settingsText = GUI.TextArea(r, settingsText); AddSpace(ref drawpos, r.height + 10); var lbl = "TAcfgSetDefaults".Translate(); if (GUI.Button(GetButtonRectVert(0, ref drawpos, 20, lbl), lbl)) { var newDict = settingsText.Replace("\r\n", "\n").Replace("\r", "\n") .Split('\n') .Select(x => x.Split(':').Select(y => y.Trim()).ToArray()) .ToDictionary(x => x[0], x => int.Parse(x[1])); foreach (var kv in newDict) { if (ConfigTabValueSavedAttribute.attributeDefaultValues.ContainsKey(kv.Key)) // overwrite default attribute values if they exist { ConfigTabValueSavedAttribute.attributeDefaultValues[kv.Key] = kv.Value; } else { LogOutput.WriteLogMessage(Errorlevel.Warning, $"Not saving value with key '{kv.Key}' as that key does not exist."); } } SoundDef.Named("Click").PlayOneShot(new SoundInfo() { pitchFactor = 1, volumeFactor = 1 }); } GUI.contentColor = defaultGuiColor; } }
static void Postfix() { LogOutput.WriteLogMessage(Errorlevel.Information, "Detected new world. Creating fresh config..."); MapCompSaveHandler.ColonyPeople.Clear(); // TODO cleanup. This was added on 05.Mar.2020 MapCompSaveHandler.Configvalues.Clear(); TA_PostOnMapLoad_Event.LoadOrCreateCfg(); }
internal static void LoadCfgValues() { if (TechAdvancing_Config_Tab.worldCompSaveHandler.world != Find.World) { LogOutput.WriteLogMessage(Errorlevel.Warning, "wcsh not referencing the current world!!!"); } TechAdvancing_Config_Tab.ExposeData(TA_Expose_Mode.Load); }
internal static void FlushCfg() { LogOutput.WriteLogMessage(Errorlevel.Information, "Flushing old Research Manager values."); TA_ResearchManager.factionDefault = TechLevel.Undefined; firstpass = true; facName = ""; firstNotificationHidden = false; startedAt = DateTime.Now; }
public override void PostClose() { base.PostClose(); if (settingsChanged) { TechAdvancing._ResearchManager.RecalculateTechlevel(); LogOutput.WriteLogMessage(Errorlevel.Information, "Saving data."); ExposeData(TA_Expose_Mode.Save); } this.forcePause = false; }
public void FixedUpdate() { if (Current.ProgramState != ProgramState.Playing) { return; } foreach (var map in Find.Maps.Where(m => m.GetComponent <MapCompSaveHandler>() == null)) { map.components.Add(new MapCompSaveHandler(map)); //for saving data associated with a map LogOutput.WriteLogMessage(Errorlevel.Information, "Added a MapComponent to store some information."); } Destroy(this); }
internal static TechLevel GetAndReloadTL() { if (Faction.OfPlayer.def.techLevel > TechLevel.Undefined && _ResearchManager.factionDefault == TechLevel.Undefined) { _ResearchManager.factionDefault = Faction.OfPlayer.def.techLevel; TechAdvancing_Config_Tab.baseFactionTechLevel = Faction.OfPlayer.def.techLevel; } if (Faction.OfPlayer.def.techLevel == TechLevel.Undefined) { LogOutput.WriteLogMessage(Errorlevel.Warning, "Called without valid TL"); #if DEBUG throw new InvalidOperationException("If you see this message please report it immediately. Thanks! (0x1)"); #endif } return(Faction.OfPlayer.def.techLevel); }
public static void ExposeData(TA_Expose_Mode mode) { MapCompSaveHandler.TA_ExposeData("Conditionvalue_A", ref Conditionvalue_A, mode); MapCompSaveHandler.TA_ExposeData("Conditionvalue_B", ref Conditionvalue_B, mode); MapCompSaveHandler.TA_ExposeData("Conditionvalue_B_s", ref Conditionvalue_B_s, mode); MapCompSaveHandler.TA_ExposeData("baseTechlvlCfg", ref baseTechlvlCfg, mode); MapCompSaveHandler.TA_ExposeData("configCheckboxNeedTechColonists", ref configCheckboxNeedTechColonists, mode); MapCompSaveHandler.TA_ExposeData("configCheckboxDisableCostMultiplicatorCap", ref configCheckboxDisableCostMultiplicatorCap, mode); if (!MapCompSaveHandler.IsValueSaved("Conditionvalue_A")) { MapCompSaveHandler.TA_ExposeData("Conditionvalue_A", ref Conditionvalue_A, TA_Expose_Mode.Save); LogOutput.WriteLogMessage(Errorlevel.Information, "Value 'Conditionvalue_A' was added to the save file. This message shouldn't appear more than once per value and world."); } if (!MapCompSaveHandler.IsValueSaved("Conditionvalue_B")) { MapCompSaveHandler.TA_ExposeData("Conditionvalue_B", ref Conditionvalue_B, TA_Expose_Mode.Save); LogOutput.WriteLogMessage(Errorlevel.Information, "Value 'Conditionvalue_B' was added to the save file. This message shouldn't appear more than once per value and world."); } if (!MapCompSaveHandler.IsValueSaved("Conditionvalue_B_s")) { MapCompSaveHandler.TA_ExposeData("Conditionvalue_B_s", ref Conditionvalue_B_s, TA_Expose_Mode.Save); LogOutput.WriteLogMessage(Errorlevel.Information, "Value 'Conditionvalue_B_s' was added to the save file. This message shouldn't appear more than once per value and world."); } if (!MapCompSaveHandler.IsValueSaved("baseTechlvlCfg")) { MapCompSaveHandler.TA_ExposeData("baseTechlvlCfg", ref baseTechlvlCfg, TA_Expose_Mode.Save); LogOutput.WriteLogMessage(Errorlevel.Information, "Value 'baseTechlvlCfg' was added to the save file. This message shouldn't appear more than once per value and world."); } if (!MapCompSaveHandler.IsValueSaved("configCheckboxNeedTechColonists")) { MapCompSaveHandler.TA_ExposeData("configCheckboxNeedTechColonists", ref configCheckboxNeedTechColonists, TA_Expose_Mode.Save); LogOutput.WriteLogMessage(Errorlevel.Information, "Value 'configCheckboxNeedTechColonists' was added to the save file. This message shouldn't appear more than once per value and world."); } if (!MapCompSaveHandler.IsValueSaved("configCheckboxDisableCostMultiplicatorCap")) { MapCompSaveHandler.TA_ExposeData("configCheckboxDisableCostMultiplicatorCap", ref configCheckboxNeedTechColonists, TA_Expose_Mode.Save); LogOutput.WriteLogMessage(Errorlevel.Information, "Value 'configCheckboxDisableCostMultiplicatorCap' was added to the save file. This message shouldn't appear more than once per value and world."); } last_Conditionvalue_A = Conditionvalue_A; last_Conditionvalue_B = Conditionvalue_B; last_Conditionvalue_B_s = Conditionvalue_B_s; last_baseTechlvlCfg = baseTechlvlCfg; last_configCheckboxNeedTechColonists = configCheckboxNeedTechColonists; last_configCheckboxDisableCostMultiplicatorCap = configCheckboxDisableCostMultiplicatorCap; }
public override void WindowUpdate() { base.WindowUpdate(); if ((last_Conditionvalue_A != Conditionvalue_A) || (last_Conditionvalue_B != Conditionvalue_B) || (last_baseTechlvlCfg != baseTechlvlCfg) || (last_configCheckboxNeedTechColonists != configCheckboxNeedTechColonists) || last_Conditionvalue_B_s != Conditionvalue_B_s ) { last_Conditionvalue_A = Conditionvalue_A; last_Conditionvalue_B = Conditionvalue_B; last_Conditionvalue_B_s = Conditionvalue_B_s; last_baseTechlvlCfg = baseTechlvlCfg; last_configCheckboxNeedTechColonists = configCheckboxNeedTechColonists; settingsChanged = true; LogOutput.WriteLogMessage(Errorlevel.Information, "Settings changed."); previewTechLevels = GetTechlevelPreview(); } }
public override void ExposeData() { LogOutput.WriteLogMessage(Errorlevel.Debug, $"Loading begun. Factiondef techlevel: {Find.FactionManager.OfPlayer.def.techLevel}"); if (Scribe.mode == LoadSaveMode.LoadingVars) { if (TA_ResearchManager.originalTechlevelCache.ContainsKey(Find.FactionManager.OfPlayer.Name)) { var correctTl = TA_ResearchManager.originalTechlevelCache[Find.FactionManager.OfPlayer.Name]; LogOutput.WriteLogMessage(Errorlevel.Information, $"The playerfaction is the same as one which was previously loaded. " + $"Resetting the techlevel to what it was before we changed it. Current faction techlevel: {Find.FactionManager.OfPlayer.def.techLevel} New (correct) techlevel: {correctTl}"); Find.FactionManager.OfPlayer.def.techLevel = correctTl; } else { LogOutput.WriteLogMessage(Errorlevel.Debug, $"Scribe mode is LoadingVars. The playerfaction is new, adding it to cache, with techlevel {Find.FactionManager.OfPlayer.def.techLevel}."); TA_ResearchManager.originalTechlevelCache.Add(Find.FactionManager.OfPlayer.Name, Find.FactionManager.OfPlayer.def.techLevel); } } TechAdvancing_Config_Tab.worldCompSaveHandler = this; base.ExposeData(); Scribe_Collections.Look(ref this.ConfigValues, "TA_Expose_Numbers", LookMode.Value, LookMode.Value); int isPplDictSaved = 1; //LogOutput.WriteLogMessage(Errorlevel.Information, "val:" + isPplDictSaved.ToString()); Scribe_Values.Look(ref isPplDictSaved, "TA_Expose_People_isSaved", -1, true); //LogOutput.WriteLogMessage(Errorlevel.Information, "val:" + isPplDictSaved.ToString()); if (this.ColonyPeople != null) { this.ColonyPeople.RemoveAll(x => x.Key == null); } if (isPplDictSaved == 1) { Scribe_Collections.Look(ref this.ColonyPeople, "TA_Expose_People", LookMode.Reference, LookMode.Reference); //LogOutput.WriteLogMessage(Errorlevel.Information, "Read TA_ExposePeople"); } TechAdvancing_Config_Tab.ExposeData(TA_Expose_Mode.Load); if (this.ColonyPeople == null) { this.ColonyPeople = new Dictionary <Pawn, Faction>(); } LogOutput.WriteLogMessage(Errorlevel.Information, "Loading finished."); TA_ResearchManager.FlushCfg(); }
internal static TechLevel GetAndReloadTL() { if (Faction.OfPlayer.def.techLevel > TechLevel.Undefined && TA_ResearchManager.factionDefault == TechLevel.Undefined) { LogOutput.WriteLogMessage(Errorlevel.Debug, "Set default techlevel to: " + Faction.OfPlayer.def.techLevel); TA_ResearchManager.factionDefault = Faction.OfPlayer.def.techLevel; } else { LogOutput.WriteLogMessage(Errorlevel.Debug, "Techlevel was not set. Techlevel currently is " + Faction.OfPlayer.def.techLevel.ToString()); } if (Faction.OfPlayer.def.techLevel == TechLevel.Undefined) { LogOutput.WriteLogMessage(Errorlevel.Warning, "Called without valid TL"); } return(Faction.OfPlayer.def.techLevel); }
public override void ExposeData() { if (Current.ProgramState == ProgramState.Entry) { if (Scribe.mode == LoadSaveMode.LoadingVars) { ConfigTabValueSavedAttribute.BuildDefaultValueCache(); LogOutput.WriteLogMessage(Errorlevel.Debug, "Loading default vars"); var dict = new Dictionary <string, int>(); Scribe_Collections.Look(ref dict, "TA_Expose_Default_Numbers", LookMode.Value, LookMode.Value); //LogOutput.WriteLogMessage(Errorlevel.Debug, $"DefaultDict: {string.Join(";", ConfigTabValueSavedAttribute.attributeDefaultValues.Select(x => $"{x.Key}={x.Value}"))}"); if (dict != null) { //LogOutput.WriteLogMessage(Errorlevel.Debug, $"SavedDict: {string.Join(";", dict.Select(x => $"{x.Key}={x.Value}"))}"); foreach (var kv in dict) { if (ConfigTabValueSavedAttribute.attributeDefaultValues.ContainsKey(kv.Key)) // load existing keys { ConfigTabValueSavedAttribute.attributeDefaultValues[kv.Key] = kv.Value; } else { LogOutput.WriteLogMessage(Errorlevel.Debug, $"Wiped old value with key {kv.Key}"); } } } } else if (Scribe.mode == LoadSaveMode.Saving) { LogOutput.WriteLogMessage(Errorlevel.Debug, "Saving default vars"); var dict = ConfigTabValueSavedAttribute.attributeDefaultValues.ToDictionary(x => x.Key, x => x.Value); Scribe_Collections.Look(ref dict, "TA_Expose_Default_Numbers", LookMode.Value, LookMode.Value); settingsText = null; } } else { this.tempdict = ConfigTabValueSavedAttribute.attributeDefaultValues.ToDictionary(x => x.Key, x => x.Value); Scribe_Collections.Look(ref this.tempdict, "TA_Expose_Default_Numbers", LookMode.Value, LookMode.Value); // because rimworld thinks its a great idea to clear configs otherwise... } base.ExposeData(); }
public void TA_ExposeData(ConfigTabValueSavedAttribute attrib, ref int value, TA_Expose_Mode mode = TA_Expose_Mode.Load) { string saveName = attrib.SaveName; object defaultValue = attrib.DefaultValue; if (mode == TA_Expose_Mode.Save) { LogOutput.WriteLogMessage(Errorlevel.Debug, "Adding " + saveName + " : " + value + " to save dictionary"); if (this.ConfigValues.ContainsKey(saveName)) { this.ConfigValues.Remove(saveName); } this.ConfigValues.Add(saveName, value); } else if (mode == TA_Expose_Mode.Load) { if (this.ConfigValues.TryGetValue(saveName, out int tempval)) { value = tempval; } else if (this.ConfigValues.TryGetValue(Enum.GetNames(typeof(TA_Expose_Name)).Contains(saveName) ? ((int)Enum.Parse(typeof(TA_Expose_Name), saveName)).ToString() : saveName, out tempval)) // TODO remove backwards compatability fallback { value = tempval; LogOutput.WriteLogMessage(Errorlevel.Information, "Value " + saveName + " was loaded via fallback. (A new save system is in place. But this message shouldnt appear anymore after saving)"); } else { LogOutput.WriteLogMessage(Errorlevel.Information, "Value " + saveName + " is not present. Using default value."); if (defaultValue == null) { LogOutput.WriteLogMessage(Errorlevel.Error, $"Default value of {saveName} is null!"); } else { value = (int)defaultValue; } } LogOutput.WriteLogMessage(Errorlevel.Debug, "Successfully loaded " + saveName + " : " + value + " from save dictionary."); } }
static void Postfix() { LogOutput.WriteLogMessage(Errorlevel.Information, "Detected existing world. Loading existing config..."); LoadOrCreateCfg(); }
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); }
public static void DoDetour(MethodInfo source, MethodInfo target) { if (LogOutput.DebugMode_TA_enabled) { LogOutput.WriteLogMessage(Errorlevel.Warning, "DEBUG MODE ACTIVATED"); } MethodInfo methodToReplace = target; MethodInfo methodToInject = source; RuntimeHelpers.PrepareMethod(methodToReplace.MethodHandle); RuntimeHelpers.PrepareMethod(methodToInject.MethodHandle); unsafe { if (IntPtr.Size == sizeof(Int64)) { // 64-bit systems use 64-bit absolute address and jumps // 12 byte destructive // Get function pointers long Source_Base = source.MethodHandle.GetFunctionPointer().ToInt64(); long Destination_Base = target.MethodHandle.GetFunctionPointer().ToInt64(); // Native source address byte *Pointer_Raw_Source = (byte *)Source_Base; // Pointer to insert jump address into native code long *Pointer_Raw_Address = (long *)(Pointer_Raw_Source + 0x02); // Insert 64-bit absolute jump into native code (address in rax) // mov rax, immediate64 // jmp [rax] *(Pointer_Raw_Source + 0x00) = 0x48; *(Pointer_Raw_Source + 0x01) = 0xB8; *Pointer_Raw_Address = Destination_Base; // ( Pointer_Raw_Source + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 ) *(Pointer_Raw_Source + 0x0A) = 0xFF; *(Pointer_Raw_Source + 0x0B) = 0xE0; } else { // 32-bit systems use 32-bit relative offset and jump // 5 byte destructive // Get function pointers int Source_Base = source.MethodHandle.GetFunctionPointer().ToInt32(); int Destination_Base = target.MethodHandle.GetFunctionPointer().ToInt32(); // Native source address byte *Pointer_Raw_Source = (byte *)Source_Base; // Pointer to insert jump address into native code int *Pointer_Raw_Address = (int *)(Pointer_Raw_Source + 1); // Jump offset (less instruction size) int offset = (Destination_Base - Source_Base) - 5; // Insert 32-bit relative jump into native code *Pointer_Raw_Source = 0xE9; *Pointer_Raw_Address = offset; } } }
/// <summary> /// Gets the max techlevel that was generated by any rule. Also takes the faction-min techlevel into account. /// </summary> /// <returns></returns> internal static TechLevel GetRuleTechlevel() { LogOutput.WriteLogMessage(Errorlevel.Debug, $"A: {RuleA().ToString()} | B:{RuleB().ToString()}"); return(Util.GetHighestTechlevel(TechAdvancing_Config_Tab.baseFactionTechLevel, RuleA(), RuleB())); }
internal static void UpdateFinishedProjectCounts() { var researchProjectStoreTotal = new Dictionary <TechLevel, int>(); var researchProjectStoreFinished = new Dictionary <TechLevel, int>(); var nonIgnoredTechs = new List <ResearchProjectDef>(); 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 var seenResearchProjDefNames = new List <string>(); bool projectHasTechprintsRecursive(ResearchProjectDef p) { if (seenResearchProjDefNames.Contains(p.defName)) { return(false); // if the lookup was already done, then it must have been false. So return false again. } seenResearchProjDefNames.Add(p.defName); if (p.techprintCount > 0) { return(true); } if (p.prerequisites?.Any(x => projectHasTechprintsRecursive(x)) == true) { return(true); } if (p.hiddenPrerequisites?.Any(x => projectHasTechprintsRecursive(x)) == true) { return(true); } return(false); } if (researchProjectDef.tags?.Any(x => x.defName == "ta-ignore") == true) { LogOutput.WriteLogMessage(Errorlevel.Debug, $"Found ta-ignore tag in: {researchProjectDef.defName}"); } else if (TechAdvancing_Config_Tab.b_configCheckboxIgnoreNonMainTreeTechs && researchProjectDef.tab != ResearchTabDefOf.Main) { LogOutput.WriteLogMessage(Errorlevel.Debug, $"Ignoring project '{researchProjectDef.defName}' from nonMainTab: '{researchProjectDef.tab.defName}'"); } else if (TechAdvancing_Config_Tab.b_configCheckboxIgnoreResearchNeedingTechprints && projectHasTechprintsRecursive(researchProjectDef)) // if it requires techprints, ignore it if the cfg wants it { LogOutput.WriteLogMessage(Errorlevel.Debug, $"Ignoring project '{researchProjectDef.defName}' because it requires '{researchProjectDef.techprintCount}' techprint(s)."); } else { nonIgnoredTechs.Add(researchProjectDef); researchProjectStoreTotal[researchProjectDef.techLevel]++; //total projects for techlevel if (researchProjectDef.IsFinished) { researchProjectStoreFinished[researchProjectDef.techLevel]++; //finished projects for techlevel researchProjectDef.ReapplyAllMods(); } } if (researchProjectDef.IsFinished) { researchProjectDef.ReapplyAllMods(); } } TechAdvancing.Rules.researchProjectStoreTotal = researchProjectStoreTotal; TechAdvancing.Rules.researchProjectStoreFinished = researchProjectStoreFinished; TechAdvancing.Rules.nonIgnoredTechs = nonIgnoredTechs; }
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); }
internal static void LoadOrCreateCfg() { LogOutput.WriteLogMessage(Errorlevel.Information, "Loading config..."); var TA_currentWorld = Find.World; if (TA_currentWorld.components.Any(x => x is WorldCompSaveHandler wcshObj && wcshObj.isInitialized)) { LogOutput.WriteLogMessage(Errorlevel.Warning, "Found an already existing and initialized worldcomponent!!!"); } var wcsh = TA_currentWorld.GetComponent <WorldCompSaveHandler>(); var wcshHasData = wcsh?.GetConfigValueNames?.Any() ?? false; if (wcsh?.isInitialized != true) { if (wcsh == null) { wcsh = new WorldCompSaveHandler(TA_currentWorld); TA_currentWorld.components.Add(wcsh); LogOutput.WriteLogMessage(Errorlevel.Information, "Adding a WorldComponent to store some information."); } bool needUpgrade = wcsh.GetConfigValueNames.Count == 0 && Find.Maps.Any(x => x.GetComponent <MapCompSaveHandler>() is MapCompSaveHandler && MapCompSaveHandler.GetConfigValueNames.Count > 0); // TODO cleanup. This was added on 28.Feb.2020 if (needUpgrade) { LogOutput.WriteLogMessage(Errorlevel.Warning, "Detected legacy save system! Upgrading..."); wcsh.LoadValuesForUpgrade(MapCompSaveHandler.Configvalues, MapCompSaveHandler.ColonyPeople); int removalCount = 0; foreach (var map in Find.Maps) { while (true) { var comp = map.GetComponent <MapCompSaveHandler>(); if (comp == null) { break; } else { if (map.components.Remove(comp)) { removalCount++; } else { LogOutput.WriteLogMessage(Errorlevel.Error, "Cleaning up 1 element failed."); } } } } LogOutput.WriteLogMessage(Errorlevel.Warning, $"Removed {removalCount} old dataset(s)."); } wcsh.isInitialized = true; } TechAdvancing_Config_Tab.worldCompSaveHandler = wcsh; //wcsh.ExposeData(); LoadCfgValues(); }