private void OnDailyTickClan(Clan clan) { var kingdom = clan.Kingdom; if (kingdom == null || clan == Clan.PlayerClan || clan.IsUnderMercenaryService || !clan.Leader.IsAlive || clan.Leader.IsPrisoner || clan.Fortifications.Any(x => x.IsUnderSiege) || clan.Parties.Any(x => x.MapEvent != null)) { return; } var ruler = kingdom.Ruler; if (clan.Leader != ruler) { if (!SeparatismConfig.Settings.LordRebellionsEnabled) { return; } var hasReason = !clan.Leader.HasGoodRelationWith(ruler); var kingdomFiefs = kingdom.GetFiefsAmount(); var kingdomClans = kingdom.Clans.Count(x => !x.IsUnderMercenaryService); var clanFiefs = clan.GetFiefsAmount(); var hasEnoughFiefs = (kingdomFiefs > 0 && ((SeparatismConfig.Settings.AverageAmountOfKingdomFiefsIsEnoughToRebel && clanFiefs >= (float)kingdomFiefs / kingdomClans) || SeparatismConfig.Settings.MinimalAmountOfKingdomFiefsToRebel <= clanFiefs)); var rebelRightNow = SeparatismConfig.Settings.DailyLordRebellionChance >= 1 || (MBRandom.RandomFloat <= SeparatismConfig.Settings.DailyLordRebellionChance); if (hasReason && hasEnoughFiefs && rebelRightNow) { var rebelKingdom = GoRebelKingdom(clan); var textObject = new TextObject("{=Separatism_Clan_Rebel}The {ClanName} have broken from {Kingdom} to found the {RebelKingdom}.", null); textObject.SetTextVariable("ClanName", clan.Name); textObject.SetTextVariable("Kingdom", kingdom.Name); textObject.SetTextVariable("RebelKingdom", rebelKingdom.Name); GameLog.Warn(textObject.ToString()); } } else { if (kingdom.Clans.Where(x => x.Leader.IsAlive).Count() == 1) // kingdom has the only one ruler clan { if (clan.Settlements.Count() == 0) // no any fiefs { clan.ChangeKingdom(null, false); var textObject = new TextObject("{=Separatism_Kingdom_Abandoned}The {Kingdom} has been destroyed and the {ClanName} are in search of a new sovereign.", null); textObject.SetTextVariable("Kingdom", kingdom.Name); textObject.SetTextVariable("ClanName", clan.Name); GameLog.Warn(textObject.ToString()); } else // look for ally { var enemies = FactionManager.GetEnemyKingdoms(kingdom).ToArray(); var potentialAllies = enemies .SelectMany(x => FactionManager.GetEnemyKingdoms(x)) .Distinct() .Except(enemies) .Intersect(clan.CloseKingdoms()) .Where(x => x != kingdom && x.Settlements.Count() > 0) .ToArray(); foreach (var pa in potentialAllies) { if (kingdom.Leader.HasGoodRelationWith(pa.Leader) && pa.Leader.Clan.Tier >= clan.Tier) { var commonEnemies = FactionManager.GetEnemyKingdoms(pa) .Intersect(enemies) .Where(x => x.Settlements.Count() > 0) .ToArray(); foreach (var enemy in commonEnemies) { var kingdomDistance = enemy.FactionMidPoint.Distance(kingdom.FactionMidPoint); var paDistance = enemy.FactionMidPoint.Distance(pa.FactionMidPoint); var allianceDistance = kingdom.FactionMidPoint.Distance(pa.FactionMidPoint); if (allianceDistance <= Math.Sqrt(kingdomDistance * kingdomDistance + paDistance * paDistance) || (kingdom.IsInsideKingdomTeritory(enemy) && pa.IsInsideKingdomTeritory(enemy))) { clan.ChangeKingdom(pa, false); var textObject = new TextObject("{=Separatism_Kingdom_Union}The {Kingdom} has joined to the {Ally} to fight against common enemy the {Enemy}.", null); textObject.SetTextVariable("Kingdom", kingdom.Name); textObject.SetTextVariable("Ally", pa.Name); textObject.SetTextVariable("Enemy", enemy.Name); GameLog.Warn(textObject.ToString()); return; } } } } // no ally kingdoms found, so look for friendly clans at least var allyClan = Clan.All.ReadyToGo().Where(c => c.Tier <= clan.Tier && c.Leader.HasGoodRelationWith(clan.Leader)) .OrderByDescending(c => c.TotalStrength) .FirstOrDefault(); if (allyClan != null) { allyClan.ChangeKingdom(kingdom, false); int relationChange = SeparatismConfig.Settings.RelationChangeRulerWithSupporter; if (relationChange != 0) { ChangeRelationAction.ApplyRelationChangeBetweenHeroes(clan.Leader, allyClan.Leader, relationChange, true); } var textObject = new TextObject("{=Separatism_Clan_Support}The {ClanName} have joined the {Kingdom} to support {Ruler}.", null); textObject.SetTextVariable("ClanName", allyClan.Name); textObject.SetTextVariable("Kingdom", kingdom.Name); textObject.SetTextVariable("Ruler", kingdom.Ruler.Name); GameLog.Warn(textObject.ToString()); } } } } }
private void OnDailyTickClan(Clan clan) { if (!SeparatismConfig.Settings.AnarchyRebellionsEnabled) { return; } var clanFiefsAmount = clan.GetFiefsAmount(); if (clanFiefsAmount < SeparatismConfig.Settings.CriticalAmountOfFiefsPerSingleClan) { return; } var anarchySettlements = clan.Settlements.Where(x => x.IsTown && CampaignTime.Hours(x.LastVisitTimeOfOwner) + CampaignTime.Days(SeparatismConfig.Settings.NumberOfDaysAfterOwnerVisitToKeepOrder) < CampaignTime.Now).ToArray(); if (anarchySettlements.Length == 0) { return; } var availableClans = Clan.All.ReadyToGo().ToArray(); foreach (var settlement in anarchySettlements.OrderByDescending(x => x.Position2D.Distance(clan.FactionMidPoint))) { var newRulerClan = availableClans .Where(x => x.Culture == settlement.Culture) .OrderByDescending(x => x.TotalStrength) .FirstOrDefault(); var rebelRightNow = SeparatismConfig.Settings.DailyAnarchyRebellionChance >= 1 || (MBRandom.RandomFloat <= SeparatismConfig.Settings.DailyAnarchyRebellionChance); if (newRulerClan != null && rebelRightNow) { var rebelSettlements = new List <Settlement>(); rebelSettlements.Add(settlement); int bonusSettlements = (SeparatismConfig.Settings.BonusRebelFiefForHighTierClan && newRulerClan.Tier > 4) ? 1 : 0; if (bonusSettlements > 0) { var neighborClanFiefs = new Queue <Settlement>(Settlement .FindSettlementsAroundPosition(settlement.Position2D, 50, x => x.OwnerClan == clan) .Where(x => x.IsCastle) .Except(rebelSettlements) .OrderBy(x => x.Position2D.Distance(settlement.Position2D))); while (bonusSettlements > 0 && neighborClanFiefs.Count > 0) { var nextFief = neighborClanFiefs.Dequeue(); if (nextFief.Culture == settlement.Culture) { rebelSettlements.Add(nextFief); bonusSettlements--; } } } var rebelKingdom = GoRebelKingdom(newRulerClan, rebelSettlements); var textObject = new TextObject("{=Separatism_Anarchy_Rebel}People of {Settlement} have broken from {Kingdom} to call {Ruler} on rulership and found the {RebelKingdom}.", null); textObject.SetTextVariable("Settlement", settlement.Name); textObject.SetTextVariable("Kingdom", clan.Kingdom.Name); textObject.SetTextVariable("Ruler", newRulerClan.Leader.Name); textObject.SetTextVariable("RebelKingdom", rebelKingdom.Name); GameLog.Warn(textObject.ToString()); return; } } }