using HarmonyLib; namespace IdleSpectator; /// Era + meta genesis patches from mutation discovery. [HarmonyPatch] public static class MetaEventPatches { [HarmonyPatch(typeof(WorldAgeManager), nameof(WorldAgeManager.startNextAge))] [HarmonyPostfix] public static void PostfixStartNextAge() { MetaInterestFeed.EmitEra(ReadCurrentEraId()); } [HarmonyPatch(typeof(CultureManager), nameof(CultureManager.newCulture))] [HarmonyPostfix] public static void PostfixNewCulture(Culture __result) { EmitNew("new_culture", "Culture", 68f, InterestOwnership.Signal, __result, "New culture: {a}"); } [HarmonyPatch(typeof(ReligionManager), nameof(ReligionManager.newReligion))] [HarmonyPostfix] public static void PostfixNewReligion(Religion __result) { EmitNew("new_religion", "Culture", 72f, InterestOwnership.Signal, __result, "New religion: {a}"); } [HarmonyPatch(typeof(LanguageManager), nameof(LanguageManager.newLanguage))] [HarmonyPostfix] public static void PostfixNewLanguage(Language __result) { EmitNew("new_language", "Culture", 60f, InterestOwnership.Ambient, __result, "New language: {a}"); } [HarmonyPatch(typeof(ClanManager), nameof(ClanManager.newClan))] [HarmonyPostfix] public static void PostfixNewClan(Clan __result) { EmitNew("new_clan", "Politics", 70f, InterestOwnership.Signal, __result, "New clan: {a}"); } [HarmonyPatch(typeof(ArmyManager), nameof(ArmyManager.newArmy))] [HarmonyPostfix] public static void PostfixNewArmy(Army __result) { EmitNew("new_army", "Politics", 66f, InterestOwnership.Ambient, __result, "New army: {a}"); } [HarmonyPatch(typeof(AllianceManager), nameof(AllianceManager.newAlliance))] [HarmonyPostfix] public static void PostfixNewAlliance(Alliance __result) { EmitNew("new_alliance", "Politics", 78f, InterestOwnership.Signal, __result, "New alliance: {a}"); } [HarmonyPatch(typeof(CityManager), nameof(CityManager.newCity))] [HarmonyPostfix] public static void PostfixNewCity(City __result) { EmitNew("new_city", "Politics", 74f, InterestOwnership.Signal, __result, "New city: {a}"); } private static void EmitNew( string eventId, string category, float strength, InterestOwnership owns, object meta, string labelTemplate) { Actor anchor = TryReadActor(meta); string name = EventFeedUtil.SafeName(anchor); if (string.IsNullOrEmpty(name) && meta != null) { try { name = meta.GetType().GetMethod("getName")?.Invoke(meta, null) as string ?? meta.GetType().GetProperty("name")?.GetValue(meta, null) as string ?? ""; } catch { name = ""; } } if (anchor == null) { // Meta without a living founder/leader: skip (no stranger subject). return; } string label = (labelTemplate ?? "{a}") .Replace("{a}", name ?? "") .Replace("{id}", eventId); MetaInterestFeed.EmitMeta(eventId, category, strength, owns, anchor, label); } private static Actor TryReadActor(object meta) { if (meta == null) { return null; } try { foreach (string name in new[] { "founder", "creator", "leader", "king", "actor", "unit" }) { object value = meta.GetType().GetField(name)?.GetValue(meta) ?? meta.GetType().GetProperty(name)?.GetValue(meta, null); if (value is Actor actor && actor.isAlive()) { return actor; } } } catch { // ignore } return null; } private static string ReadCurrentEraId() { try { object world = World.world; object ageManager = world?.GetType().GetField("era_manager")?.GetValue(world) ?? world?.GetType().GetProperty("era_manager")?.GetValue(world, null) ?? world?.GetType().GetField("age_manager")?.GetValue(world) ?? MapBox.instance?.GetType().GetField("era_manager")?.GetValue(MapBox.instance); if (ageManager == null) { return "age_unknown"; } object asset = ageManager.GetType().GetMethod("getCurrentAge")?.Invoke(ageManager, null) ?? ageManager.GetType().GetProperty("current_age")?.GetValue(ageManager, null) ?? ageManager.GetType().GetField("current_age")?.GetValue(ageManager); if (asset != null) { object id = asset.GetType().GetField("id")?.GetValue(asset) ?? asset.GetType().GetProperty("id")?.GetValue(asset, null); if (id != null) { return id.ToString(); } } } catch { // ignore } return "age_unknown"; } }