Skip to content

Commit

Permalink
Version 1.6.5.1 hotfix; rework OutsideConnectionAI patch for greater …
Browse files Browse the repository at this point in the history
…robustness and fix transpiler argument indexation.
  • Loading branch information
algernon-A committed Dec 16, 2022
1 parent c91d17e commit ae0bb36
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 48 deletions.
7 changes: 6 additions & 1 deletion Changelog.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
Version 1.6.5
Version 1.6.6

- Rework OutsideConnectionAI patch for greater robustness


Version 1.6.5

- Add support for wall-to-wall residential buildings as separate transport mode probability category
- Mod conflict detection now takes place on enabling the mod (so you don't have to load a city to find out if there's a conflict)
Expand Down
2 changes: 2 additions & 0 deletions Code/Loading.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ protected override void LoadedActions(LoadMode mode)
// Prime Threading.counter to continue from frame index.
int temp = (int)(Singleton<SimulationManager>.instance.m_currentFrameIndex / 4096u);
Threading.Counter = temp % DataStore.LifeSpanMultiplier;

PatcherManager<Patcher>.Instance.ListMethods();
}
}
}
97 changes: 51 additions & 46 deletions Code/Patches/OutsideConnectionAIPatches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace LifecycleRebalance
using System.Reflection.Emit;
using AlgernonCommons;
using ColossalFramework;
using ColossalFramework.Math;
using HarmonyLib;

/// <summary>
Expand All @@ -31,15 +32,12 @@ public static class OutsideConnectionAIPatches
public static IEnumerable<CodeInstruction> Transpiler(MethodBase original, IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
// Local variable ILCode indexes (original method).
const int EducationVarIndex = 3;
const int EducationVarIndex = 2;
const int NumVarIndex = 3;
const int ILoopVarIndex = 17;
const int AgeVarIndex = 21;
const int Education2VarIndex = 22;

// Not used in patch - for determining patch location.
const int flag4VarIndex = 23;

Logging.Message("starting StartConnectionTransferImpl transpiler");

// Local variables used by the patch.
Expand Down Expand Up @@ -100,7 +98,7 @@ public static IEnumerable<CodeInstruction> Transpiler(MethodBase original, IEnum
{
instruction = instructionsEnumerator.Current;
}
while ((instruction.opcode != OpCodes.Stloc_S || !(instruction.operand is LocalBuilder builder && builder.LocalIndex == flag4VarIndex)) && instructionsEnumerator.MoveNext());
while ((instruction.opcode != OpCodes.Stloc_S || !(instruction.operand is LocalBuilder builder && builder.LocalIndex == Education2VarIndex)) && instructionsEnumerator.MoveNext());

// Load required variables for patch method onto stack.
yield return new CodeInstruction(OpCodes.Ldloc_S, ILoopVarIndex) { labels = startForLabels };
Expand Down Expand Up @@ -179,59 +177,66 @@ public static void RandomizeImmigrants(int i, Citizen.Education education, int[]
// Set default eductation output to what the game has already determined.
resultEducation = education;

// Apply education level randomisation if that option is selected.
if (ModSettings.Settings.RandomImmigrantEd)
if (education < Citizen.Education.Uneducated || resultEducation > Citizen.Education.ThreeSchools)
{
Logging.Error("invalid starting education level ", education);
}

// Calculate education levels.
if (i < 2)
{
if (i < 2)
// Adults (set education levels).
// Local references.
ref Randomizer simulationRandomizer = ref Singleton<SimulationManager>.instance.m_randomizer;
ModSettings settings = ModSettings.Settings;

// 24% different education levels.
int eduModifier = settings.RandomImmigrantEd ? simulationRandomizer.Int32(-12, 12) / 10 : 0;

if (settings.ImmiEduBoost)
{
// Adults.
// 24% different education levels
int eduModifier = Singleton<SimulationManager>.instance.m_randomizer.Int32(-12, 12) / 10;
resultEducation += eduModifier;
if (resultEducation < Citizen.Education.Uneducated)
{
resultEducation = Citizen.Education.Uneducated;
}
else if (resultEducation > Citizen.Education.ThreeSchools)
{
resultEducation = Citizen.Education.ThreeSchools;
}

// Apply education boost, if enabled, and if we're not already at the max.
if (ModSettings.Settings.ImmiEduBoost && resultEducation < Citizen.Education.ThreeSchools)
{
++resultEducation;
}
// Education boost - 50% chance.
eduModifier += simulationRandomizer.Int32(0, 1);
}
else
else if (settings.ImmiEduDrag)
{
// Children.
switch (Citizen.GetAgeGroup(resultAge))
{
case Citizen.AgeGroup.Child:
resultEducation = Citizen.Education.Uneducated;
break;
case Citizen.AgeGroup.Teen:
resultEducation = Citizen.Education.OneSchool;
break;
default:
// Make it that 80% graduate from high school
resultEducation = (Singleton<SimulationManager>.instance.m_randomizer.Int32(0, 100) < 80) ? Citizen.Education.TwoSchools : Citizen.Education.OneSchool;
break;
}
// Education drag - 50% chance.
eduModifier -= simulationRandomizer.Int32(0, 1);
}
}

// Apply education suppression, if enabled, and if we're not already at the min.
if (ModSettings.Settings.ImmiEduDrag && resultEducation > Citizen.Education.Uneducated)
// Apply education modifier and clamp bounds.
resultEducation += eduModifier;
if (resultEducation < Citizen.Education.Uneducated)
{
resultEducation = Citizen.Education.Uneducated;
}
else if (resultEducation > Citizen.Education.ThreeSchools)
{
resultEducation = Citizen.Education.ThreeSchools;
}
}
else
{
--resultEducation;
// Children (set education levels).
switch (Citizen.GetAgeGroup(resultAge))
{
case Citizen.AgeGroup.Child:
resultEducation = Citizen.Education.Uneducated;
break;
case Citizen.AgeGroup.Teen:
resultEducation = Citizen.Education.OneSchool;
break;
default:
// Make it that 80% graduate from high school
resultEducation = (Singleton<SimulationManager>.instance.m_randomizer.Int32(0, 100) < 80) ? Citizen.Education.TwoSchools : Citizen.Education.OneSchool;
break;
}
}

// Write to immigration log if that option is selected.
if (LifecycleLogging.UseImmigrationLog)
{
LifecycleLogging.WriteToLog(LifecycleLogging.ImmigrationLogName, "Family member ", i, " immigrating with age ", resultAge, " (" + (int)(resultAge / ModSettings.AgePerYear), " years old) and education level ", education);
LifecycleLogging.WriteToLog(LifecycleLogging.ImmigrationLogName, "Family member ", i, " immigrating with age ", resultAge, " (" + (int)(resultAge / ModSettings.AgePerYear), " years old) and education level ", resultEducation, " from original education level ", education);
}
}

Expand Down
2 changes: 1 addition & 1 deletion Lifecycle Rebalance Revisited.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<Authors>algernon</Authors>
<Copyright>Copyright © 2022 algernon</Copyright>
<Product>$(Title)</Product>
<Version>1.6.5</Version>
<Version>1.6.5.1</Version>
<ManagedDLLPath>$(MSBuildProgramFiles32)/Steam/steamapps/common/Cities_Skylines/Cities_Data/Managed</ManagedDLLPath>
<AssemblySearchPaths>
$(AssemblySearchPaths);
Expand Down

0 comments on commit ae0bb36

Please sign in to comment.