/// <summary> /// Harmony Postfix patch to stop historical buildings from abandoning. /// </summary> /// <param name="__instance">Instance reference</param> /// <param name="buildingID">Building instance ID</param /// <param name="buildingData">Building instance data reference</param> public static void Postfix(PrivateBuildingAI __instance, ushort buildingID, ref Building buildingData) { // Check to see if we have no abandonement for any building set, or no abandonment historical and this is an historical building. if (ModSettings.noAbandonAny || (ModSettings.noAbandonHistorical && __instance.IsHistorical(buildingID, ref buildingData, out bool _))) { // It is - simply reset the major problem timer to avoid the 'abandonment' timeout. buildingData.m_majorProblemTimer = 0; } }
/// <summary> /// Upgrades/downgrades the selected building to the given level, if possible. /// </summary> /// <param name="buildingID">Building instance ID</param> /// <param name="targetLevel">Level to upgrade/downgrade to</param> internal static void ForceLevel(ushort buildingID, byte targetLevel) { // BuildingInfo to change to, if this building isn't historical. BuildingInfo targetInfo = null; // References. BuildingManager buildingManager = Singleton <BuildingManager> .instance; Building[] buildingBuffer = buildingManager.m_buildings.m_buffer; BuildingInfo buildingInfo = buildingBuffer[buildingID].Info; PrivateBuildingAI buildingAI = buildingInfo?.GetAI() as PrivateBuildingAI; if (buildingInfo == null || buildingAI == null) { // If something went wrong, abort. Logging.Error("couldn't get existing building info"); return; } // Check to see if this is historical or not, or is a RICO ploppable. bool isHistorical = buildingAI.IsHistorical(buildingID, ref Singleton <BuildingManager> .instance.m_buildings.m_buffer[buildingID], out bool _) || ModUtils.CheckRICOPloppable(buildingInfo); // Get target prefab (if needed, i.e. not historical or RICO ploppable). if (!isHistorical) { // Get upgrade/downgrade building target. targetInfo = GetTargetInfo(buildingID, targetLevel); if (targetInfo == null) { // If we failed, don't do anything more. return; } } // If we have a valid upgrade/downgrade target, proceed. if (isHistorical || targetInfo != null) { // Apply target level to our building and cancel all level-up progress. buildingBuffer[buildingID].m_level = targetLevel; buildingBuffer[buildingID].m_levelUpProgress = 0; // Apply our upgrade/downgrade target if not historical if (!isHistorical) { buildingManager.UpdateBuildingInfo(buildingID, targetInfo); } // Post-downgrade processing to update instance values - call game method if new level is equal to or greater than info base level, otherwise use custom method. BuildingInfo newInfo = targetInfo ?? buildingInfo; if (newInfo.GetAI() is PrivateBuildingAI newAI) { if (targetLevel < (byte)newInfo.GetClassLevel()) { // New level is less than info base level; call custom method. CustomBuildingUpgraded(newAI, buildingID, ref buildingBuffer[buildingID]); } else { // New level is equal to or greater than info base level; call game method. newAI.BuildingUpgraded(buildingID, ref buildingBuffer[buildingID]); } } } }