public override void OnDelayedWorldLoadFinished() { Overwatch.Log("CleanupTimers"); Dictionary <DateAndTime, Dictionary <MethodInfo, Dictionary <ReferenceWrapper, bool> > > lookup = new Dictionary <DateAndTime, Dictionary <MethodInfo, Dictionary <ReferenceWrapper, bool> > >(); Dictionary <AlarmHandle, AlarmManager> remove = new Dictionary <AlarmHandle, AlarmManager>(); Dictionary <AlarmManager, bool> managers = new Dictionary <AlarmManager, bool>(); managers.Add(AlarmManager.Global, true); foreach (Lot lot in LotManager.AllLots) { if (lot.mSavedData.mAlarmManager == null) { continue; } if (managers.ContainsKey(lot.AlarmManager)) { continue; } managers.Add(lot.AlarmManager, true); } Dictionary <ulong, SimDescription> sims = SimListing.GetResidents(true); foreach (AlarmManager manager in managers.Keys) { foreach (KeyValuePair <AlarmHandle, List <AlarmManager.Timer> > list in manager.mTimers) { foreach (AlarmManager.Timer timer in list.Value) { bool removed = false; SimDescription sim = timer.ObjectRef as SimDescription; if (sim != null) { if (!sim.IsValidDescription) { remove[list.Key] = manager; Overwatch.Log(" Invalid Sim " + sim.FullName); removed = true; } } else { GameObject gameObject = timer.ObjectRef as GameObject; if (gameObject != null) { if (gameObject.HasBeenDestroyed) { remove[list.Key] = manager; Overwatch.Log(" Destroyed Object " + gameObject.GetType()); removed = true; } } } AlarmTimerCallback callback = timer.CallBack; if (callback == null) { remove[list.Key] = manager; Overwatch.Log(" Removed Empty Alarm"); removed = true; } else { Writing.RoyaltyAlarm royaltyAlarm = callback.Target as Writing.RoyaltyAlarm; if (royaltyAlarm != null) { string reason = null; if ((royaltyAlarm.mSkill == null) || (royaltyAlarm.mSkill.SkillOwner == null)) { reason = "No Skill"; } else if (!royaltyAlarm.mSkill.SkillOwner.IsValidDescription) { reason = "Bad Sim"; } else if (royaltyAlarm.mSkill.SkillOwner.SkillManager == null) { reason = "No Manager"; } else { Writing skill = royaltyAlarm.mSkill.SkillOwner.SkillManager.GetSkill <Writing>(SkillNames.Writing); if (skill != royaltyAlarm.mSkill) { reason = "Not Royalty Skill"; } else if (skill.mRoyaltyAlarm != royaltyAlarm) { reason = "Not Royalty Alarm"; } } if (reason != null) { remove[list.Key] = manager; Overwatch.Log(" Invalid Royalty Alarm: " + reason); removed = true; } } else { MethodInfo info = typeof(LunarCycleManager).GetMethod("PossiblySpawnZombie", BindingFlags.Static | BindingFlags.NonPublic); if (callback.Method == info) { if (LunarCycleManager.mZombieAlarm != timer.Handle) { remove[list.Key] = manager; Overwatch.Log(" Invalid Zombie Alarm"); removed = true; } } else { info = typeof(MeteorShower).GetMethod("RandomMeteorShowerCallback", BindingFlags.Static | BindingFlags.Public); if (callback.Method == info) { if (MeteorShower.RandomMeteorShowerAlarmHandler != timer.Handle) { remove[list.Key] = manager; Overwatch.Log(" Invalid Meteor Shower Alarm"); removed = true; } } } } if (!removed) { Dictionary <MethodInfo, Dictionary <ReferenceWrapper, bool> > methods; if (!lookup.TryGetValue(timer.AlarmDateAndTime, out methods)) { methods = new Dictionary <MethodInfo, Dictionary <ReferenceWrapper, bool> >(); lookup[timer.AlarmDateAndTime] = methods; } Dictionary <ReferenceWrapper, bool> objects; if (!methods.TryGetValue(callback.Method, out objects)) { objects = new Dictionary <ReferenceWrapper, bool>(); methods[callback.Method] = objects; } ReferenceWrapper reference = new ReferenceWrapper(callback.Target); if (objects.ContainsKey(reference)) { remove[list.Key] = manager; Overwatch.Log(" Removed Duplicate Alarm: " + timer.AlarmDateAndTime + " " + callback.Method + " (" + callback.Target + ")"); } else { objects[reference] = true; } } } } } } foreach (KeyValuePair <AlarmHandle, AlarmManager> handle in remove) { handle.Value.RemoveAlarm(handle.Key); } // cleanup trick or treating fail HolidayManager instance = HolidayManager.Instance; if (instance != null && AlarmManager.Global != null) { if (!instance.IsFallHoliday && TrickOrTreatSituation.NPCTrickOrTreatAlarm != AlarmHandle.kInvalidHandle) { Overwatch.Log("Cleaned up run away trick or treat alarm"); AlarmManager.Global.RemoveAlarm(TrickOrTreatSituation.NPCTrickOrTreatAlarm); TrickOrTreatSituation.NPCTrickOrTreatAlarm = AlarmHandle.kInvalidHandle; } } }
protected override bool PrivateUpdate(ScenarioFrame frame) { Household house = Sim.Household; Sim sim = Sim.CreatedSim; Dictionary <SimDescription, float> inheritors = Deaths.GetInheritors(Sim, GetValue <InheritCashScenario.InheritorsOption, ManagerDeath.Inheritors>(), false); List <Sim> choices = new List <Sim>(); foreach (SimDescription other in inheritors.Keys) { if (other.CreatedSim == null) { continue; } if (!other.ChildOrAbove) { continue; } choices.Add(other.CreatedSim); } if (choices.Count == 0) { foreach (Sim other in HouseholdsEx.AllHumans(house)) { if (other == sim) { continue; } choices.Add(other); } if (choices.Count == 0) { IncStat("No Choices"); return(false); } } bool found = false; if (HouseholdsEx.NumHumans(house) == 1) { if (house.RealEstateManager.AllProperties.Count > 0) { Dictionary <Household, Sim> houses = new Dictionary <Household, Sim>(); foreach (Sim choice in choices) { if (choice.Household == null) { continue; } houses[choice.Household] = choice; } if (houses.Count > 0) { List <KeyValuePair <Household, Sim> > houseChoices = new List <KeyValuePair <Household, Sim> >(houses); foreach (PropertyData data in house.RealEstateManager.AllProperties) { KeyValuePair <Household, Sim> choice = RandomUtil.GetRandomObjectFromList(houseChoices); ManagerMoney.TransferProperty(house, choice.Key, data); mInheritors[choice.Value.SimDescription] = true; IncStat("Property Transferred"); found = true; } } } } if (!SimTypes.IsSelectable(Sim)) { Lots.PackupVehicles(sim, (HouseholdsEx.NumHumans(house) > 1)); foreach (GameObject obj in Inventories.QuickFind <GameObject>(sim.Inventory)) { Sim choice = RandomUtil.GetRandomObjectFromList(choices); if ((obj is INotTransferableOnDeath) || (obj is IHiddenInInventory) || (obj is DeathFlower) || (obj is Diploma)) { IncStat("NonTrans " + obj.GetLocalizedName()); continue; } found = true; if (Inventories.TryToMove(obj, choice)) { IncStat("Transferred " + obj.GetLocalizedName()); mInheritors[choice.SimDescription] = true; } else { IncStat("Unremovable " + obj.GetLocalizedName()); } } } Writing oldSkill = Sim.SkillManager.GetSkill <Writing>(SkillNames.Writing); if (oldSkill != null) { Writing.RoyaltyAlarm alarm = oldSkill.mRoyaltyAlarm; if (alarm != null) { List <Sim> royaltyChoices = new List <Sim>(choices); while (royaltyChoices.Count > 0) { Sim choice = RandomUtil.GetRandomObjectFromList(royaltyChoices); royaltyChoices.Remove(choice); Writing newSkill = choice.SkillManager.GetSkill <Writing>(SkillNames.Writing); if ((newSkill != null) && (newSkill.mRoyaltyAlarm != null)) { continue; } newSkill = choice.SkillManager.AddElement(SkillNames.Writing) as Writing; if (newSkill != null) { alarm.RemoveRoyaltyAlarm(); alarm.mAlarmHandle = AlarmManager.Global.AddAlarmDay(Writing.kRoyaltyPayHour, DaysOfTheWeek.Sunday, new AlarmTimerCallback(alarm.AlarmCallBack), "Royalty Alarm", AlarmType.AlwaysPersisted, newSkill.SkillOwner); alarm.mSkill = newSkill; newSkill.mRoyaltyAlarm = alarm; IncStat("Transferred Royalties"); mInheritors[choice.SimDescription] = true; found = true; } break; } } } if (!found) { return(false); } return(mInheritors.Count > 0); }