private void RetireWanderers()   // TODO ideally this should be outright "delete", but a safe one, of course
        // heroes are naturally ordered by creation time
        // take first wanderer who is not already "retired", and who is not currently accompanying us and do the job
        {
            foreach (var hero in Hero.All.Where(hero => HeroIsAvailableWanderer(hero))
                     .Take(wanderersToSpawn))
            {
#if !RETIRE_BY_KILLING
                hero.ChangeState(Hero.CharacterStates.Disabled);
#else
                // KillCharacterAction -> MakeDead() will change state
                // LeaveSettlementAction is still required because it removes a guy from the actual tavern
#endif
                // apparently a wanderer may get so unlucky (recall that a random wanderer with culture preference is settled only when
                // MainHero enters an eligible town) that she's still in limbo by the time of retirement
                if (hero.StayingInSettlementOfNotable != null)
                {
                    LeaveSettlementAction.ApplyForCharacterOnly(hero);
                }
#if !RETIRE_BY_KILLING
                var urbanRemoved = urbanCharsBhvCompanions.Remove(hero);
                InformationManager.DisplayMessage(new InformationMessage($"\"Retired\" wanderer {hero} (urbanRemoved={urbanRemoved})"));
#else
                KillCharacterAction.ApplyByRemove(hero); // UrbanCharactersCampaignBehavior.OnHeroKilled() will Remove() from urbanCharsBhvCompanions
                // superfluous since Native v1.2.0:
                //InformationManager.DisplayMessage(new InformationMessage($"\"Retired\" wanderer {hero}"));
#endif
            }
        }
示例#2
0
 public void CharacterChangeLocation(Hero hero, Settlement startLocation, Settlement endLocation)
 {
     if (startLocation != null)
     {
         LeaveSettlementAction.ApplyForCharacterOnly(hero);
     }
     EnterSettlementAction.ApplyForCharacterOnly(hero, endLocation);
     if (hero != null)
     {
         hero.SpcDaysInLocation = 0;
     }
 }
示例#3
0
        private static void OnHourlyTickParty(MobileParty mobileParty)
        {
            if (mobileParty.IsCaravan || mobileParty.IsVillager)
            {
                if (mobileParty.CurrentSettlement != null &&
                    mobileParty.CurrentSettlement.IsCastle &&
                    !mobileParty.CurrentSettlement.IsUnderSiege &&
                    MBRandom.RandomFloat < 0.5f)
                {
                    Settlement currentSettlement = mobileParty.CurrentSettlement;
                    LeaveSettlementAction.ApplyForParty(mobileParty);
                    mobileParty.SetMoveGoToPoint(currentSettlement.GatePosition);
                    return;
                }

                if (mobileParty.DefaultBehavior == AiBehavior.GoToSettlement &&
                    mobileParty.ShortTermBehavior != AiBehavior.FleeToPoint &&
                    mobileParty.TargetSettlement != null &&
                    mobileParty.TargetSettlement.IsUnderSiege &&
                    mobileParty.CurrentSettlement == null)
                {
                    mobileParty.SetMoveGoToPoint(mobileParty.Position2D);
                    return;
                }
            }

            if (mobileParty.IsLordParty || mobileParty.IsCaravan || mobileParty.IsVillager)
            {
                if (mobileParty.ShortTermBehavior == AiBehavior.FleeToPoint && mobileParty.ShortTermTargetParty != null)
                {
                    // find nearest safe settlement
                    Settlement settlementToFlee = SettlementHelper.FindNearestSettlementToMapPoint(mobileParty,
                                                                                                   s => s.IsFortification &&
                                                                                                   (s.MapFaction == mobileParty.MapFaction ||
                                                                                                    (s.MapFaction.IsKingdomFaction && !s.MapFaction.IsAtWarWith(mobileParty.MapFaction))));

                    if (settlementToFlee == null || settlementToFlee.IsUnderSiege || settlementToFlee.Party.MapEvent != null)
                    {
                        return;
                    }

                    float dist = mobileParty.Position2D.DistanceSquared(settlementToFlee.GatePosition);

                    if (dist < magnetDistance && dist < mobileParty.ShortTermTargetParty.Position2D.DistanceSquared(settlementToFlee.GatePosition))
                    {
                        mobileParty.SetMoveGoToSettlement(settlementToFlee);
                        mobileParty.RecalculateShortTermAi();
                    }
                }
            }
        }
示例#4
0
 private static void FlushHideoutsOfMilitias()
 {
     foreach (var hideout in Settlement.All.Where(x => x.IsHideout()).ToList())
     {
         for (var index = 0; index < hideout.Parties.Count; index++)
         {
             var party = hideout.Parties[index];
             if (IsBM(party))
             {
                 Mod.Log(">>> FLUSH Hideout.");
                 LeaveSettlementAction.ApplyForParty(party);
                 party.SetMovePatrolAroundSettlement(hideout);
             }
         }
     }
 }
示例#5
0
        private void ConsequenceChangeClanLeader()
        {
            newLeader = Hero.OneToOneConversationHero;
            leader    = Hero.MainHero;

            if (newLeader.PartyBelongedTo == null || newLeader != newLeader.PartyBelongedTo.LeaderHero)
            {
                MobilePartyHelper.CreateNewClanMobileParty(newLeader, leader.Clan, out _);
            }

            if (leader.PartyBelongedTo != null && leader.PartyBelongedTo.CurrentSettlement != null)
            {
                EnterSettlementAction.ApplyForParty(newLeader.PartyBelongedTo, leader.PartyBelongedTo.CurrentSettlement);
                LeaveSettlementAction.ApplyForParty(leader.PartyBelongedTo);
            }

            CampaignEvents.TickEvent.AddNonSerializedListener(this, OnChangeClanLeader);
        }
        static bool Prefix(Clan clan, Kingdom kingdom, int detail, int awardMultiplier, bool byRebellion, bool showNotification)
        {
            //MessageBox.Show($"Detail: {detail}");
            //MessageBox.Show(SharedObjects.Instance.RebellionRelationsChange.ToString());

            var  onClanChangedKingdom          = typeof(CampaignEventDispatcher).GetMethod("OnClanChangedKingdom", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            var  onMercenaryClanChangedKingdom = typeof(CampaignEventDispatcher).GetMethod("OnMercenaryClanChangedKingdom", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            Type type = typeof(ChangeKingdomAction).Assembly.GetType("TaleWorlds.CampaignSystem.Actions.ChangeKingdomAction+ChangeKingdomActionDetail");

            int joinMerc       = (int)Enum.ToObject(type, 0);
            int joinKingdom    = (int)Enum.ToObject(type, 1);
            int leaveKingdom   = (int)Enum.ToObject(type, 2);
            int leaveRebellion = (int)Enum.ToObject(type, 3);
            int leaveMerc      = (int)Enum.ToObject(type, 4);

            Kingdom oldKingdom = clan.Kingdom;

            if (kingdom != null)
            {
                foreach (Kingdom kingdom3 in Kingdom.All)
                {
                    if (object.ReferenceEquals(kingdom3, kingdom) || !kingdom.IsAtWarWith(kingdom3))
                    {
                        FactionHelper.FinishAllRelatedHostileActionsOfFactionToFaction(clan, kingdom3);
                        FactionHelper.FinishAllRelatedHostileActionsOfFactionToFaction(kingdom3, clan);
                    }
                }
                foreach (Clan clan2 in Clan.All)
                {
                    if (!object.ReferenceEquals(clan2, clan) && ((clan2.Kingdom == null) && !kingdom.IsAtWarWith(clan2)))
                    {
                        FactionHelper.FinishAllRelatedHostileActions(clan, clan2);
                    }
                }
            }
            if (detail == joinKingdom)   //ChangeKingdomActionDetail.JoinKingdom
            {
                object[] additionalArgs = new object[] { clan, oldKingdom, kingdom, false };
                StatisticsDataLogHelper.AddLog(StatisticsDataLogHelper.LogAction.ChangeKingdomAction, additionalArgs);
                clan.IsUnderMercenaryService = false;
                if (oldKingdom != null)
                {
                    clan.ClanLeaveKingdom(!byRebellion);
                }
                clan.ClanJoinFaction(kingdom);
                onClanChangedKingdom.Invoke(CampaignEventDispatcher.Instance, new object[] { clan, oldKingdom, clan.Kingdom, byRebellion, showNotification });
            }
            else if (detail == joinMerc)   //ChangeKingdomActionDetail.JoinAsMercenary
            {
                object[] additionalArgs = new object[] { clan, oldKingdom, kingdom, false };
                StatisticsDataLogHelper.AddLog(StatisticsDataLogHelper.LogAction.ChangeKingdomAction, additionalArgs);
                if (clan.IsUnderMercenaryService)
                {
                    clan.ClanLeaveKingdom(false);
                }
                clan.MercenaryAwardMultiplier = MathF.Round((float)awardMultiplier);
                clan.IsUnderMercenaryService  = true;
                clan.ClanJoinFaction(kingdom);
                //CampaignEventDispatcher.Instance.OnMercenaryClanChangedKingdom(clan, null, kingdom);
                onMercenaryClanChangedKingdom.Invoke(CampaignEventDispatcher.Instance, new object[] { clan, null, kingdom });
            }
            else if (detail == leaveRebellion || detail == leaveKingdom || detail == leaveMerc)   //ChangeKingdomActionDetail.LeaveAsMercenary = 4
            {
                object[] additionalArgs = new object[] { clan, oldKingdom, kingdom, true };
                StatisticsDataLogHelper.AddLog(StatisticsDataLogHelper.LogAction.ChangeKingdomAction, additionalArgs);
                clan.ClanLeaveKingdom(false);
                if (detail == leaveMerc)   //ChangeKingdomActionDetail.LeaveAsMercenary
                {
                    onMercenaryClanChangedKingdom.Invoke(CampaignEventDispatcher.Instance, new object[] { clan, kingdom, null });
                    clan.IsUnderMercenaryService = false;
                }
                if (detail == leaveRebellion)   //ChangeKingdomActionDetail.LeaveWithRebellion
                {
                    if (object.ReferenceEquals(clan, Clan.PlayerClan))
                    {
                        foreach (Clan clan3 in oldKingdom.Clans)
                        {
                            ChangeRelationAction.ApplyRelationChangeBetweenHeroes(clan.Leader, clan3.Leader, SharedObjects.Instance.RebellionRelationsChange, true);
                        }
                        if (SharedObjects.Instance.DeclareWarOnRebellion)
                        {
                            DeclareWarAction.Apply(oldKingdom, clan);
                        }
                    }
                    onClanChangedKingdom.Invoke(CampaignEventDispatcher.Instance, new object[] { clan, oldKingdom, null, true, true });
                }
                else if (detail == leaveKingdom)   //ChangeKingdomActionDetail.LeaveKingdom
                {
                    if (object.ReferenceEquals(clan, Clan.PlayerClan))
                    {
                        foreach (Clan clan4 in oldKingdom.Clans)
                        {
                            ChangeRelationAction.ApplyRelationChangeBetweenHeroes(clan.Leader, clan4.Leader, SharedObjects.Instance.ForfeitSettlementsRelationsChange, true);
                        }
                    }
                    foreach (Settlement settlement in new List <Settlement>(clan.Settlements))
                    {
                        ChangeOwnerOfSettlementAction.ApplyByLeaveFaction(oldKingdom.Leader, settlement);
                        foreach (Hero hero in new List <Hero>((IEnumerable <Hero>)settlement.HeroesWithoutParty))
                        {
                            if ((hero.CurrentSettlement != null) && object.ReferenceEquals(hero.Clan, clan))
                            {
                                if (hero.PartyBelongedTo != null)
                                {
                                    LeaveSettlementAction.ApplyForParty(hero.PartyBelongedTo);
                                    EnterSettlementAction.ApplyForParty(hero.PartyBelongedTo, clan.Leader.HomeSettlement);
                                    continue;
                                }
                                LeaveSettlementAction.ApplyForCharacterOnly(hero);
                                EnterSettlementAction.ApplyForCharacterOnly(hero, clan.Leader.HomeSettlement);
                            }
                        }
                    }
                    onClanChangedKingdom.Invoke(CampaignEventDispatcher.Instance, new object[] { clan, oldKingdom, null, false, false });
                }
            }
            if (object.ReferenceEquals(clan, Clan.PlayerClan))
            {
                Campaign.Current.UpdateDecisions();
            }
            typeof(ChangeKingdomAction).GetMethod("CheckIfPartyIconIsDirty", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
            .Invoke(null, new object[] { clan, kingdom });
            return(false);
        }