Skip to content

Commit

Permalink
Enable live reset of schools to vanilla calcs.
Browse files Browse the repository at this point in the history
  • Loading branch information
algernon-A committed Feb 27, 2022
1 parent 70f05dc commit e310a9e
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Code/Patches/StudentCount.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static bool Prefix(SchoolAI __instance, ref int __result)
{
// We are - set the result to our realistic population lookup.
BuildingInfo thisInfo = __instance.m_info;
__result = (int)(PopData.instance.Population(thisInfo, (int)__instance.m_info.GetClassLevel(), Multipliers.instance.ActiveMultiplier(thisInfo)));
__result = PopData.instance.Students(thisInfo);

// Don't continue on to original method.
return false;
Expand Down
20 changes: 20 additions & 0 deletions Code/Patches/VanillaPopMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,5 +182,25 @@ public static void OfficeWorkplaceCount(object instance, ItemClass.Level level,
Logging.Error(message, instance, level, r, width, length);
throw new NotImplementedException(message);
}


/// <summary>
/// Reverse patch for SchoolAI.StudentCount to access original game method without any Harmony patches (including ours).
/// </summary>
/// <param name="instance">Object instance</param>
/// <param name="level">Building level</param>
/// <param name="r">Randomizer</param>
/// <param name="width">Building lot width (in cells)</param>
/// <param name="length">Building lot depth (in cells)</param>
/// <exception cref="NotImplementedException">Harmony reverse patch wasn't applied</exception>
[HarmonyReversePatch]
[HarmonyPatch((typeof(SchoolAI)), nameof(SchoolAI.StudentCount), MethodType.Getter)]
[MethodImpl(MethodImplOptions.NoInlining)]
public static int StudentCount(object instance)
{
string message = "SchoolAI.StudentCount reverse Harmony patch wasn't applied";
Logging.Error(message, instance);
throw new NotImplementedException(message);
}
}
}
29 changes: 28 additions & 1 deletion Code/VolumetricData/CalcPacks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,19 @@ public class PopDataPack : DataPack
/// <param name="level">Building level</param>
/// <returns>Workplace breakdowns and visitor count </returns>
public virtual WorkplaceLevels Workplaces(BuildingInfo buildingPrefab, int level) => new WorkplaceLevels { level0 = 1, level1 = 0, level2 = 0, level3 = 0};


/// <summary>
/// Returns the student count for the given building prefab and level.
/// </summary>
/// <param name="buildingPrefab">Building prefab record</param>
/// <returns>Student count (0 if not a school building)</returns>
public virtual int Students(BuildingInfo buildingPrefab) => buildingPrefab.m_buildingAI is SchoolAI ? Population(buildingPrefab, (int)buildingPrefab.m_class.m_level, Multipliers.instance.ActiveMultiplier(buildingPrefab)) : 0;
}


/// <summary>
/// Population clculation data pack - provides parameters for calculating building populations.
/// Population calculation data pack - provides parameters for calculating building populations.
/// </summary>
public class SchoolDataPack : DataPack
{
Expand Down Expand Up @@ -308,5 +316,24 @@ public override WorkplaceLevels Workplaces(BuildingInfo buildingPrefab, int leve
level3 = (ushort)workLevel3
};
}


/// <summary>
/// Returns the vanilla student count for the given building prefab and level.
/// </summary>
/// <param name="buildingPrefab">Building prefab record</param>
/// <returns>Workplace breakdown</returns>
public override int Students(BuildingInfo buildingPrefab)
{
// Set m_studentCount to original value.
if (buildingPrefab.m_buildingAI is SchoolAI schoolAI)
{
schoolAI.m_studentCount = SchoolData.instance.OriginalStudentCount(buildingPrefab);
return VanillaPopMethods.StudentCount(schoolAI);
}

// If we got here, no valid vanilla settings were found; return 0.
return 0;
}
}
}
8 changes: 8 additions & 0 deletions Code/VolumetricData/PopData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ internal class PopData : CalcData
internal WorkplaceLevels Workplaces(BuildingInfo buildingPrefab, int level) => ((PopDataPack)ActivePack(buildingPrefab)).Workplaces(buildingPrefab, level);


/// <summary>
/// Returns the student count for the given building prefab.
/// </summary>
/// <param name="prefab">Building prefab</param>
/// <returns>Student count</returns>
internal int Students(BuildingInfo buildingPrefab) => ((PopDataPack)ActivePack(buildingPrefab)).Students(buildingPrefab);


/// <summary>
/// Adds or updates cached housholds for the specified building prefab and level.
/// </summary>
Expand Down
36 changes: 35 additions & 1 deletion Code/VolumetricData/SchoolData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace RealPop2
/// </summary>
public class OriginalSchoolStats
{
public int students;
public int jobs0, jobs1, jobs2, jobs3;
public int cost, maintenance;
}
Expand Down Expand Up @@ -103,6 +104,30 @@ public SchoolData()
}


/// <summary>
/// Returns the original student count for the given school prefab.
/// </summary>
/// <param name="building">Building prefab</param>
/// <returns>Original student count, if available (300 if no record available)</returns>
internal int OriginalStudentCount(BuildingInfo prefab)
{
if (originalStats == null)
{
if (prefab.m_buildingAI is SchoolAI schoolAI)
{
return schoolAI.m_studentCount;
}
}
else if (originalStats.ContainsKey(prefab.name))
{
return originalStats[prefab.name].students;
}

// If we got here, no record was found; return 300 (vanilla elementary).
return 300;
}


/// <summary>
/// Updates our building setting dictionary for the selected building prefab to the indicated calculation pack.
/// IMPORTANT: make sure student count is called before calling this.
Expand Down Expand Up @@ -255,6 +280,7 @@ internal void OnLoad()
// Found a school; add it to our dictionary.
originalStats.Add(building.name, new OriginalSchoolStats
{
students = schoolAI.m_studentCount,
jobs0 = schoolAI.m_workPlaceCount0,
jobs1 = schoolAI.m_workPlaceCount1,
jobs2 = schoolAI.m_workPlaceCount2,
Expand All @@ -263,6 +289,8 @@ internal void OnLoad()
maintenance = schoolAI.m_maintenanceCost
});

Logging.KeyMessage("found school prefab ", building.name, " with student count ", schoolAI.m_studentCount);

// If setting is set, get currently active pack and apply it.
if (ModSettings.enableSchoolProperties)
{
Expand Down Expand Up @@ -305,6 +333,7 @@ internal void UpdateSchools()
if (thisInfo?.m_buildingAI is SchoolAI schoolAI && thisInfo.m_class.m_level <= ItemClass.Level.Level2)
{
// Found a school - set local references for passing to SimulationManager.
Logging.KeyMessage("updating school building ", i, ": ", thisInfo.name, " to student count of ", schoolAI.StudentCount);
SchoolAI thisAI = schoolAI;
ushort buildingID = (ushort)i;

Expand Down Expand Up @@ -406,7 +435,7 @@ private void ApplyPack(BuildingInfo prefab, SchoolDataPack schoolPack)
schoolAI.m_constructionCost = CalcCost(schoolPack, schoolAI.StudentCount);
schoolAI.m_maintenanceCost = CalcMaint(schoolPack, schoolAI.StudentCount);

// Force update of m_studentCount.
// Update prefab population record.
schoolAI.m_studentCount = schoolAI.StudentCount;

// Update prefab and tooltip.
Expand Down Expand Up @@ -435,9 +464,14 @@ private void UpdateSchoolPrefab(BuildingInfo prefab, SchoolAI schoolAI)
return;
}

Logging.KeyMessage("updating school prefab ", prefab.name, " with studentCount ", schoolAI.m_studentCount);
Logging.KeyMessage("applying calculation pack ", PopData.instance.ActivePack(prefab).DisplayName, " with multiplier ", Multipliers.instance.ActiveMultiplier(prefab));

// Update prefab population record.
schoolAI.m_studentCount = schoolAI.StudentCount;

Logging.KeyMessage("new student count is ", schoolAI.m_studentCount);

// Update tooltip.
UpdateSchoolTooltip(prefab);
}
Expand Down

0 comments on commit e310a9e

Please sign in to comment.