예제 #1
0
        public override void Tick()
        {
            base.Tick();
            tickerInternal++;

            if (safetyValve_ShouldConductImportanceUpdate)
            {
                try
                {
                    // 8 calculations per day, should be enough -> 3 in-game hours
                    // 60000 / 8 = 7500
                    while (tickerInternal > 7500)
                    {
                        ImportanceUpdateCycle_DoOnce();
                        tickerInternal -= 7500;
                    }
                }
                catch (Exception ex)
                {
                    DesynchronizedMain.LogError("A critical error has occured while attempting to update news importance scores. This periodical process has been terminated. Please also include the full log (using HugsLib's log-sharing) when reporting this error.");
                    DesynchronizedMain.LogError(ex.ToString());
                    safetyValve_ShouldConductImportanceUpdate = false;
                }
            }
        }
예제 #2
0
        public static void ManipulateInteractionTargetsList(List <Pawn> original, Pawn self)
        {
            var caravan = self.GetCaravan();

            if (caravan == null)
            {
                // No caravan, no modification needed
                return;
            }

            DesynchronizedMain.LogWarning("Hi hi! Processing " + self.Name);
            var possibleCandidates = caravan.PawnsListForReading;
            var selfFaction        = self.Faction;

            for (var i = possibleCandidates.Count; i >= 0; i++)
            {
                if (possibleCandidates[i].Faction != selfFaction)
                {
                    possibleCandidates.RemoveAt(i);
                }
            }

            original.Clear();
            original.AddRange(possibleCandidates);
        }
예제 #3
0
 public TaleNews(LocationInfo info)
 {
     locationInfo = info;
     if (DesynchronizedMain.TaleNewsDatabaseSystem == null)
     {
         DesynchronizedMain.LogError("The TNDBS is unexpectedly null, cancelling creation of TaleNews. This may happen because the map is still being set up (or, alternatively, you are using Prepare Carefully), but otherwise, this is a bug.");
         return;
     }
     DesynchronizedMain.TaleNewsDatabaseSystem.RegisterNewTaleNews(this);
 }
예제 #4
0
        private static void SendOutNotificationLetter(Pawn victim)
        {
            DesynchronizedMain.LogError("Called SendOutNotificationLetter(Pawn) to give out \"Pawn Kidnapped\" letters, which should not happen due to v1.1's own letters.");

            string letterLabel   = "Kidnapped".Translate() + ": " + victim.LabelShortCap;
            string letterContent = string.Empty;

            letterContent += "PawnKidnapped".Translate(victim.LabelShort.CapitalizeFirst(), kidnappingFaction.def.pawnsPlural, kidnappingFaction.Name, victim.Named("PAWN"));

            Find.LetterStack.ReceiveLetter(letterLabel, letterContent, LetterDefOf.NegativeEvent, LookTargets.Invalid);
        }
 public TaleNewsPawnKidnapped(Pawn victim, Pawn kidnapper) : base(victim, InstigationInfo.NoInstigator)
 {
     if (kidnapper == null)
     {
         DesynchronizedMain.LogError("Kidnapper cannot be null! Fake News!\n" + Environment.StackTrace);
     }
     else
     {
         InstigationDetails = (InstigationInfo)kidnapper;
         kidnapperFaction   = kidnapper.Faction;
     }
 }
예제 #6
0
 public TaleNewsPawnKidnapped(Pawn victim, Faction kidnappingFaction) : base(victim, InstigatorInfo.NoInstigator)
 {
     if (kidnappingFaction == null)
     {
         DesynchronizedMain.LogError("Kidnapping faction cannot be null! Fake news!\n" + Environment.StackTrace);
     }
     else
     {
         InstigatorInfo   = (InstigatorInfo)kidnappingFaction;
         kidnapperFaction = kidnappingFaction;
     }
 }
예제 #7
0
        /// <summary>
        /// Registers a TaleNews object by giving it a valid UID, then adding it to the List.
        /// <para/>
        /// In current implementation, the constructor of TaleNews will also register itself to here.
        /// </summary>
        /// <param name="news"></param>
        public void RegisterNewTaleNews(TaleNews news)
        {
            if (news == null)
            {
                DesynchronizedMain.LogError("An unexpected null TaleNews was received. Report this to Desynchronized.\n" + Environment.StackTrace);
                return;
            }

            if (!news.IsRegistered)
            {
                news.ReceiveRegistrationID(GetNextUID());
                talesOfImportance.Add(news);
            }
        }
예제 #8
0
        public static bool PreFix(Pawn_RelationsTracker __instance, Pawn playerNegotiator)
        {
            // Find out the underlying pawn of this tracker exhausively
            foreach (Pawn potential in Find.WorldPawns.AllPawnsAlive)
            {
                if (potential.relations == __instance)
                {
                    Handler_PawnSold.HandlePawnSold_ByTrade(potential, playerNegotiator);
                    return(false);
                }
            }

            DesynchronizedMain.LogError("Failed to determine owner of Pawn_RelationsTracker. Falling back to vanilla behavior.");
            return(true);
        }
예제 #9
0
 /// <summary>
 /// Wrapper method to let the recipient react to the news.
 /// </summary>
 /// <param name="recipient"></param>
 public void ActivateForReceipient(Pawn recipient)
 {
     if (isPermanentlyForgotten)
     {
         DesynchronizedMain.LogError("Illegal state. This tale-news should be permanently forgotten. Tale-news: " + ToString());
     }
     try
     {
         GiveThoughtsToReceipient(recipient);
     }
     catch (Exception ex)
     {
         DesynchronizedMain.LogError("Cannot give thought(s). Something went wrong.\n" + ex.ToString());
     }
 }
예제 #10
0
        public int GetNextUID()
        {
            int result = nextUID;

            try
            {
                nextUID = checked (nextUID + 1);
            }
            catch (OverflowException ex)
            {
                Find.LetterStack.ReceiveLetter(DesynchronizedMain.MODPREFIX + "Overflow Occured", "Report this situation to Desynchronized; it is time for an upgrade.", LetterDefOf.ThreatBig);
                DesynchronizedMain.LogError("Greetings, Ancient One. You have sucessfully broken this mod without exploiting any bug.\n" + ex.StackTrace);
                nextUID = 0;
            }

            return(result);
        }
예제 #11
0
        public void Notify_UpdateNewsImportance()
        {
            if (IsLocallyForgotten || ReferencedTaleNews.PermanentlyForgotten)
            {
                // Just to be safe. Do nothing and return.
                DesynchronizedMain.LogWarning("Someone attempted to update importance score of a forgotten tale-news reference. This is unsafe behavior, and has been prevented.\n" + Environment.StackTrace);
                return;
            }

            cachedImportance = ReferencedTaleNews.CalculateNewsImportanceForPawn(CachedSubject, this);

            if (cachedImportance < 1)
            {
                Forget();
            }
            // CachedNewsImportance can already return 0 when IsLocallyForgotten
        }
        public static bool PreventVanillaThoughts()
        {
            StackFrame investigateFrame = new StackFrame(2);
            string     namespaceString  = investigateFrame.GetMethod().ReflectedType.Namespace;

            if (namespaceString == "RimWorld" || namespaceString == "Verse")
            {
                return(false);
            }
            if (!reportedNamespaces.Contains(namespaceString))
            {
                reportedNamespaces.Add(namespaceString);
                DesynchronizedMain.LogError("Mod incompatibility detected. " +
                                            "There are some other mods calling the vanilla GenGuest.AddPrisonerSoldThoughts() function.\n" +
                                            "This detected mod comes from " + namespaceString + ".\n" + Environment.StackTrace);
            }
            return(true);
        }
예제 #13
0
        public static bool SignalRelevantHandlers(Pawn_RelationsTracker __instance, Pawn playerNegotiator)
        {
            foreach (Pawn potential in Find.WorldPawns.AllPawnsAlive)
            {
                /*
                 * Reversed method for finding the victim.
                 * If RelationsTracker -> pawn does not work, then let's do pawn -> RelationsTracker
                 */
                if (potential.relations == __instance)
                {
                    Handler_PawnSold.HandlePawnSold_ByTrade(potential, playerNegotiator);
                    return(false);
                }
            }

            DesynchronizedMain.LogError("Failed to determine owner of Pawn_RelationsTracker. Falling back to vanilla behavior.");
            return(true);
        }
예제 #14
0
        /// <summary>
        /// Extension method. A Social Proxomity Score is given for the other pawn. The "socially closer" the other pawn is w.r.t self (e.g. close family), the higher the score.
        /// </summary>
        /// <param name="subject"></param>
        /// <param name="other"></param>
        /// <returns></returns>
        public static int GetSocialProximityScoreForOther(this Pawn subject, Pawn other)
        {
            if (subject == null)
            {
                DesynchronizedMain.LogError("This shit be null bruh!");
                return(0);
            }

            PawnRelationDef relation = subject.GetMostImportantRelation(other);

            // Score is given by the "differential pattern" of subject.
            if (relation == PawnRelationDefOf.Lover || relation == PawnRelationDefOf.Fiance || relation == PawnRelationDefOf.Spouse)
            {
                return(5);
            }
            if (relation == PawnRelationDefOf.Parent || relation == PawnRelationDefOf.Child || relation == PawnRelationDefOf.Bond)
            {
                return(4);
            }
            if (relation == PawnRelationDefOf.Sibling || relation == PawnRelationDefOf.HalfSibling || relation == PawnRelationDefOf.Cousin)
            {
                return(4);
            }
            if (relation == PawnRelationDefOf.Grandparent || relation == PawnRelationDefOf.Grandchild)
            {
                return(3);
            }
            if (relation == PawnRelationDefOf.UncleOrAunt || relation == PawnRelationDefOf.NephewOrNiece)
            {
                return(3);
            }
            if (relation == PawnRelationDefOf.ExLover || relation == PawnRelationDefOf.ExSpouse)
            {
                return(3);
            }

            // Determine score by factions
            Faction subjectFaction = subject.Faction;
            Faction otherFaction   = other.Faction;

            if (subjectFaction != null)
            {
                if (subjectFaction == otherFaction)
                {
                    return(2);
                }
                if (subjectFaction.AlliedTo(otherFaction))
                {
                    return(1);
                }
                else
                {
                    return(0);
                }
            }
            if (otherFaction != null)
            {
                if (otherFaction.AlliedTo(subjectFaction))
                {
                    return(1);
                }
                else
                {
                    return(0);
                }
            }
            else
            {
                return(0);
            }
        }
예제 #15
0
 protected override void GiveThoughtsToReceipient(Pawn recipient)
 {
     DesynchronizedMain.LogError("Somebody tried to trigger a thought-giving process using a default TaleNews. Nothing was done.\n" + Environment.StackTrace);
 }