private void SetFactionVars(Faction sourceFaction, Faction targetFaction, FactionMode mode, bool lateExecute)
        {
            targetFaction.leader = sourceFaction.leader;

            targetFaction.def = sourceFaction.def;

            targetFaction.loadID = sourceFaction.loadID;

            targetFaction.Name = sourceFaction.HasName ? sourceFaction.Name : null;

            targetFaction.randomKey         = sourceFaction.randomKey;
            targetFaction.colorFromSpectrum = sourceFaction.colorFromSpectrum;
            targetFaction.centralMelanin    = sourceFaction.centralMelanin;

            targetFaction.kidnapped = sourceFaction.kidnapped;

            PredatorThreatsField.SetValue(targetFaction, PredatorThreatsField.GetValue(sourceFaction));

            targetFaction.defeated = sourceFaction.defeated;
            targetFaction.lastTraderRequestTick      = sourceFaction.lastTraderRequestTick;
            targetFaction.lastMilitaryAidRequestTick = sourceFaction.lastMilitaryAidRequestTick;

            NaturalGoodwillTimerField.SetValue(targetFaction, NaturalGoodwillTimerField.GetValue(sourceFaction));

            if (lateExecute)
            {
                LongEventHandler.ExecuteWhenFinished(() => SetFactionRelationsVars(sourceFaction, targetFaction, mode));
            }
            else
            {
                SetFactionRelationsVars(sourceFaction, targetFaction, mode);
            }
        }
        private void SetFactionRelationsVars(Faction sourceFaction, Faction targetFaction, FactionMode mode)
        {
            var sourceFactionRelations = (List <FactionRelation>)RelationsField.GetValue(sourceFaction);
            var targetFactionRelations = (List <FactionRelation>)RelationsField.GetValue(targetFaction);

            var allFactions = this.WorldData.FactionManager.AllFactionsListForReading;

            switch (mode)
            {
            case FactionMode.Load:

                targetFactionRelations.Clear();

                foreach (var faction in allFactions)
                {
                    if (faction.IsPlayer)
                    {
                        continue;
                    }

                    var factionRelations = (List <FactionRelation>)RelationsField.GetValue(faction);

                    // Clear any previous relations that are player factions.
                    for (var i = 0; i < factionRelations.Count; i++)
                    {
                        var relation = factionRelations[i];

                        if (relation.other == null || relation.other.IsPlayer)
                        {
                            factionRelations.Remove(relation);
                        }
                    }

                    // Set relations.
                    var sourceRelation = sourceFaction.RelationWith(faction, true);

                    if (sourceRelation != null)
                    {
                        var goodwill = sourceRelation.goodwill;
                        var kind     = sourceRelation.kind;

                        targetFactionRelations.Add(new FactionRelation
                        {
                            other    = faction,
                            goodwill = goodwill,
                            kind     = kind
                        });

                        factionRelations.Add(new FactionRelation
                        {
                            other    = targetFaction,
                            goodwill = goodwill,
                            kind     = kind
                        });

                        sourceFactionRelations.Remove(sourceRelation);
                    }
                    else
                    {
                        targetFaction.TryMakeInitialRelationsWith(faction);
                    }
                }

                break;

            case FactionMode.Save:

                targetFactionRelations.Clear();

                foreach (var faction in allFactions)
                {
                    if (faction.IsPlayer)
                    {
                        continue;
                    }

                    var factionRelations = (List <FactionRelation>)RelationsField.GetValue(faction);

                    for (var i = 0; i < factionRelations.Count; i++)
                    {
                        var relation = factionRelations[i];

                        if (relation.other != null && relation.other.IsPlayer && relation.other != sourceFaction)
                        {
                            factionRelations.Remove(relation);
                        }
                    }

                    var sourceRelation = sourceFaction.RelationWith(faction, true);

                    if (sourceRelation != null)
                    {
                        var goodwill = sourceRelation.goodwill;
                        var kind     = sourceRelation.kind;

                        targetFactionRelations.Add(new FactionRelation
                        {
                            other    = faction,
                            goodwill = goodwill,
                            kind     = kind
                        });
                    }
                    else
                    {
                        targetFaction.TryMakeInitialRelationsWith(faction);
                    }
                }

                break;

            case FactionMode.Reset:

                RelationsField.SetValue(targetFaction, sourceFactionRelations);

                foreach (var faction in allFactions)
                {
                    if (faction.IsPlayer)
                    {
                        continue;
                    }

                    var factionRelations = (List <FactionRelation>)RelationsField.GetValue(faction);

                    for (var i = 0; i < factionRelations.Count; i++)
                    {
                        var relation = factionRelations[i];

                        if (relation.other != null && relation.other.IsPlayer)
                        {
                            factionRelations.Remove(relation);
                        }
                    }

                    var factionRelation = sourceFaction.RelationWith(faction, true);

                    if (factionRelation == null)
                    {
                        faction.TryMakeInitialRelationsWith(targetFaction);
                        continue;
                    }

                    factionRelations.Add(new FactionRelation
                    {
                        other    = targetFaction,
                        goodwill = factionRelation.goodwill,
                        kind     = factionRelation.kind
                    });
                }

                break;
            }
        }