// main merge method private static void Postfix() { if (Campaign.Current.TimeControlMode == CampaignTimeControlMode.Stop || Campaign.Current.TimeControlMode == CampaignTimeControlMode.UnstoppableFastForwardForPartyWaitTime || Campaign.Current.TimeControlMode == CampaignTimeControlMode.FastForwardStop || Campaign.Current.TimeControlMode == CampaignTimeControlMode.StoppableFastForward) { return; } if (Campaign.CurrentTime - lastChecked < 1f) { return; } lastChecked = Campaign.CurrentTime; var hideouts = Settlement.All.Where(s => s.IsHideout).ToList(); var parties = MobileParty.All.Where(m => m.Party.IsMobile && m.CurrentSettlement is null && !m.IsUsedByAQuest() && m.IsBandit && m.MemberRoster.TotalManCount >= Globals.Settings.MinPartySizeToConsiderMerge) .ToListQ(); for (var index = 0; index < parties.Count; index++) { //T.Restart(); var mobileParty = parties[index]; if (hideouts.AnyQ(s => s.Position2D.Distance(mobileParty.Position2D) < MinDistanceFromHideout)) { continue; } if (mobileParty.IsTooBusyToMerge()) { continue; } var nearbyParties = MobileParty.FindPartiesAroundPosition(mobileParty.Position2D, FindRadius) .Intersect(parties) .Except(new[] { mobileParty }) .ToListQ(); if (!nearbyParties.Any()) { continue; } if (mobileParty.ToString().Contains("manhunter")) // Calradia Expanded Kingdoms { continue; } CampaignTime?lastChangeDate = null; if (mobileParty.IsBM()) { lastChangeDate = PartyMilitiaMap[mobileParty].LastMergedOrSplitDate; } if (CampaignTime.Now < lastChangeDate + CampaignTime.Hours(Globals.Settings.CooldownHours)) { continue; } var targetParty = nearbyParties.Where(m => IsAvailableBanditParty(m) && m.MemberRoster.TotalManCount + mobileParty.MemberRoster.TotalManCount >= Globals.Settings.MinPartySize) .ToListQ().GetRandomElement()?.Party; //Mod.Log($">T targetParty {T.ElapsedTicks / 10000F:F3}ms."); // "nobody" is a valid answer if (targetParty is null) { continue; } CampaignTime?targetLastChangeDate = null; if (targetParty.MobileParty.IsBM()) { targetLastChangeDate = PartyMilitiaMap[targetParty.MobileParty].LastMergedOrSplitDate; } if (CampaignTime.Now < targetLastChangeDate + CampaignTime.Hours(Globals.Settings.CooldownHours)) { continue; } var militiaTotalCount = mobileParty.MemberRoster.TotalManCount + targetParty.MemberRoster.TotalManCount; if (MilitiaPowerPercent > Globals.Settings.GlobalPowerPercent || militiaTotalCount < Globals.Settings.MinPartySize || militiaTotalCount > CalculatedMaxPartySize || NumMountedTroops(mobileParty.MemberRoster) + NumMountedTroops(targetParty.MemberRoster) > militiaTotalCount / 2) { continue; } //Mod.Log($"==> counted {T.ElapsedTicks / 10000F:F3}ms."); if (mobileParty != targetParty.MobileParty.MoveTargetParty && Campaign.Current.Models.MapDistanceModel.GetDistance(targetParty.MobileParty, mobileParty) > MergeDistance) { //Mod.Log($"{mobileParty} seeking > {targetParty.MobileParty}"); mobileParty.SetMoveEscortParty(targetParty.MobileParty); //Mod.Log($"SetNavigationModeParty ==> {T.ElapsedTicks / 10000F:F3}ms"); if (targetParty.MobileParty.MoveTargetParty != mobileParty) { //Mod.Log($"{targetParty.MobileParty} seeking back > {mobileParty}"); targetParty.MobileParty.SetMoveEscortParty(mobileParty); //Mod.Log($"SetNavigationModeTargetParty ==> {T.ElapsedTicks / 10000F:F3}ms"); } continue; } //Mod.Log($"==> found settlement {T.ElapsedTicks / 10000F:F3}ms."); // create a new party merged from the two var rosters = MergeRosters(mobileParty, targetParty); var militia = new Militia(mobileParty.Position2D, rosters[0], rosters[1]); // teleport new militias near the player if (Globals.Settings.TestingMode) { // in case a prisoner var party = Hero.MainHero.PartyBelongedTo ?? Hero.MainHero.PartyBelongedToAsPrisoner.MobileParty; militia.MobileParty.Position2D = party.Position2D; } militia.MobileParty.Party.Visuals.SetMapIconAsDirty(); try { // can throw if Clan is null Trash(mobileParty); Trash(targetParty.MobileParty); } catch (Exception ex) { Mod.Log(ex); } DoPowerCalculations(); //Mod.Log($"==> Finished all work: {T.ElapsedTicks / 10000F:F3}ms."); } //Mod.Log($"Looped ==> {T.ElapsedTicks / 10000F:F3}ms"); }
private static void Postfix() { try { if (Campaign.Current.TimeControlMode == CampaignTimeControlMode.Stop || Campaign.Current.TimeControlMode == CampaignTimeControlMode.UnstoppableFastForwardForPartyWaitTime || Campaign.Current.TimeControlMode == CampaignTimeControlMode.FastForwardStop || Campaign.Current.TimeControlMode == CampaignTimeControlMode.StoppableFastForward || GlobalMilitiaPower > CalculatedGlobalPowerLimit) { return; } var parties = MobileParty.All.Where(x => x.Party.IsMobile && x.CurrentSettlement == null && !x.IsCurrentlyUsedByAQuest && x.IsBandit).ToList(); //T.Restart(); for (var index = 0; index < parties.Count; index++) { var mobileParty = parties[index]; if (mobileParty.MoveTargetParty != null && mobileParty.MoveTargetParty.IsBandit || // Calradia Expanded Kingdoms mobileParty.ToString().Contains("manhunter") || mobileParty.IsTooBusyToMerge()) { continue; } CampaignTime?lastChangeDate = null; if (PartyMilitiaMap.ContainsKey(mobileParty)) { lastChangeDate = PartyMilitiaMap[mobileParty].LastMergedOrSplitDate; } if (CampaignTime.Now < lastChangeDate + CampaignTime.Hours(Globals.Settings.CooldownHours)) { continue; } var targetParty = MobileParty.FindPartiesAroundPosition(mobileParty.Position2D, FindRadius, x => x != mobileParty && IsValidParty(x) && x.MemberRoster.TotalManCount + mobileParty.MemberRoster.TotalManCount >= Globals.Settings.MinPartySize) .ToList().GetRandomElement()?.Party; // "nobody" is a valid answer if (targetParty == null) { continue; } CampaignTime?targetLastChangeDate = null; if (PartyMilitiaMap.ContainsKey(targetParty.MobileParty)) { targetLastChangeDate = PartyMilitiaMap[mobileParty].LastMergedOrSplitDate; } if (CampaignTime.Now < targetLastChangeDate + CampaignTime.Hours(Globals.Settings.CooldownHours)) { continue; } var militiaTotalCount = mobileParty.MemberRoster.TotalManCount + targetParty.MemberRoster.TotalManCount; if (militiaTotalCount < Globals.Settings.MinPartySize || militiaTotalCount > CalculatedMaxPartySize || mobileParty.Party.TotalStrength > CalculatedMaxPartyStrength || NumMountedTroops(mobileParty.MemberRoster) + NumMountedTroops(targetParty.MemberRoster) > militiaTotalCount / 2) { continue; } if (Campaign.Current.Models.MapDistanceModel.GetDistance(targetParty.MobileParty, mobileParty) > MergeDistance) { Mod.Log($"{mobileParty} seeking > {targetParty.MobileParty}"); mobileParty.SetMoveEscortParty(targetParty.MobileParty); //Mod.Log($"SetNavigationModeParty ==> {T.ElapsedTicks / 10000F:F3}ms"); if (targetParty.MobileParty.MoveTargetParty != mobileParty) { Mod.Log($"{targetParty.MobileParty} seeking back > {mobileParty}"); targetParty.MobileParty.SetMoveEscortParty(mobileParty); //Mod.Log($"SetNavigationModeTargetParty ==> {T.ElapsedTicks / 10000F:F3}ms"); } continue; } if (Settlement.FindSettlementsAroundPosition(mobileParty.Position2D, MinDistanceFromHideout, x => x.IsHideout()).Any()) { continue; } // create a new party merged from the two var rosters = MergeRosters(mobileParty, targetParty); var militia = new Militia(mobileParty, rosters[0], rosters[1]); militia.MobileParty.SetMovePatrolAroundPoint(militia.MobileParty.Position2D); // teleport new militias near the player if (TestingMode) { // in case a prisoner var party = Hero.MainHero.PartyBelongedTo ?? Hero.MainHero.PartyBelongedToAsPrisoner.MobileParty; militia.MobileParty.Position2D = party.Position2D; } militia.MobileParty.Party.Visuals.SetMapIconAsDirty(); Trash(mobileParty); Trash(targetParty.MobileParty); //Mod.Log($">>> Finished all work: {T.ElapsedTicks / 10000F:F3}ms."); } //Mod.Log($"Looped ==> {T.ElapsedTicks / 10000F:F3}ms"); } catch (Exception ex) { Mod.Log(ex); } }