Exemplo n.º 1
0
        public static void PushState(Map map)
        {
            var world = Current.Game != null ? Current.Game.World : null;

            if (world == null)
            {
                RimRPC.prsnc.details = "Main Menu";
            }
            else
            {
                float latitude  = (map == null) ? 0f : Find.WorldGrid.LongLatOf(map.Tile).y;
                float longitude = (map == null) ? 0f : Find.WorldGrid.LongLatOf(map.Tile).x;
                colonyname     = GetColonyName();
                years          = days / 60;
                colonistnumber = (float)PawnsFinder.AllMapsCaravansAndTravelingTransportPods_Alive_FreeColonists.Count <Pawn>();
                days           = GenDate.DaysPassed;
                dayhour        = GenDate.HourOfDay(Find.TickManager.TicksAbs, longitude);
                quadrum        = GenDate.Quadrum(Find.TickManager.TicksAbs, longitude);

                BiomeDef biome = Find.WorldGrid[map.uniqueID].biome;
                RimRPC.prsnc.state          = BuildString("state");
                RimRPC.prsnc.details        = BuildString("details");
                RimRPC.prsnc.largeImageText = "RimWorld";
                RimRPC.prsnc.smallImageKey  = "inmap";
                RimRPC.prsnc.smallImageText = "Playing!";
                if (RWRPCMod.settings.RPC_Time)
                {
                    RimRPC.prsnc.startTimestamp = RimRPC.started;
                }
            }
            DiscordRPC.UpdatePresence(ref RimRPC.prsnc);
        }
Exemplo n.º 2
0
        public static void PushState(Map map)
        {
            var world = Current.Game != null ? Current.Game.World : null;

            if (world == null)
            {
                RimRPC.prsnc.details = "Main Menu";
            }
            else
            {
                float latitude  = (map == null) ? 0f : Find.WorldGrid.LongLatOf(map.Tile).y;
                float longitude = (map == null) ? 0f : Find.WorldGrid.LongLatOf(map.Tile).x;
                colonyname     = GetColonyName();
                years          = days / 60;
                days           = GenDate.DaysPassed;
                dayhour        = GenDate.HourOfDay(Find.TickManager.TicksAbs, longitude);
                colonistnumber = (float)PawnsFinder.AllMapsCaravansAndTravelingTransportPods_Alive_FreeColonists.Count <Pawn>();
                //Season season = GenDate.Season(Find.TickManager.TicksAbs, latitude, longitude);
                //Quadrum updates seem enough.
                Quadrum quadrum = GenDate.Quadrum(Find.TickManager.TicksAbs, longitude);

                BiomeDef biome = Find.WorldGrid[map.uniqueID].biome;
                RimRPC.prsnc.state          = "Year " + years + " Day " + days + " (" + dayhour + "h) | " + quadrum;
                RimRPC.prsnc.details        = colonyname + ", " + colonistnumber + " Colonists";
                RimRPC.prsnc.largeImageText = "RimWorld";
                RimRPC.prsnc.smallImageKey  = "inmap";
                RimRPC.prsnc.smallImageText = "Playing!";
            }
            DiscordRPC.UpdatePresence(ref RimRPC.prsnc);
            //Log.Message("[RichPressence] Pushed presence update to RPC."); commented to remove log spam
        }
Exemplo n.º 3
0
        public static void PushState(Map map)
        {
            var world = Current.Game != null ? Current.Game.World : null;

            if (world == null)
            {
                RimRPC.prsnc.details = "Main Menu";
            }
            else
            {
                float latitude  = (map == null) ? 0f : Find.WorldGrid.LongLatOf(map.Tile).y;
                float longitude = (map == null) ? 0f : Find.WorldGrid.LongLatOf(map.Tile).x;
                colonyname = GetColonyName();
                days       = GenDate.DaysPassed;
                dayhour    = GenDate.HourOfDay(Find.TickManager.TicksAbs, longitude);
                //Season season = GenDate.Season(Find.TickManager.TicksAbs, latitude, longitude);
                //Quadrum updates seem enough.
                Quadrum quadrum = GenDate.Quadrum(Find.TickManager.TicksAbs, longitude);

                BiomeDef biome = Find.WorldGrid[map.uniqueID].biome;
                RimRPC.prsnc.state          = "Day " + days + " (" + dayhour + "h) | " + quadrum;
                RimRPC.prsnc.details        = colonyname;
                RimRPC.prsnc.largeImageText = "RimWorld";
                RimRPC.prsnc.smallImageKey  = "inmap";
                RimRPC.prsnc.smallImageText = "Playing!";
            }
            DiscordRPC.UpdatePresence(ref RimRPC.prsnc);
            Log.Message("[RichPressence] Pushed presence update to RPC.");
        }
Exemplo n.º 4
0
        private void UpdateAbsoluteFieldsFromTicks(int ticksToUse)
        {
            var tileCoords = RemindersGameComponent.VectorForTime;

            if (!tileCoords.HasValue)
            {
                return;
            }
            var absTicks = GenDate.TickGameToAbs(ticksToUse);
            var coords   = tileCoords.Value;

            yearValue  = GenDate.Year(absTicks, coords.x);
            yearBuffer = yearValue.ToString();

            quadrumValue = GenDate.Quadrum(absTicks, coords.x);

            dayValue  = GenDate.DayOfQuadrum(absTicks, coords.x) + 1;
            dayBuffer = dayValue.ToString();

            hourValue  = GenDate.HourOfDay(absTicks, coords.x);
            hourBuffer = hourValue.ToString();

            Log.Debug($"Set defaults to {dayBuffer} {quadrumValue}, {yearBuffer} at {hourBuffer}.");
            Log.Debug($"Should have set to {GenDate.DateFullStringWithHourAt(absTicks, coords)}.");
        }
Exemplo n.º 5
0
        private void CalculateNextRunTickAdvanced(int ticksNowAbs)
        {
            //If Settings have not been parsed do that now.
            if (this.m_ScreenshotHours == null || this.m_ScreenshotDays == null)
            {
                this.CalculateDaysAndHoursToRunOn();
            }

            int _CurrentHour = GenDate.HourOfDay(ticksNowAbs, this.SettingAdvancedTimeZoneLongitude);
            int _CurrentDay  = GenDate.DayOfSeason(ticksNowAbs, this.SettingAdvancedTimeZoneLongitude) + 1; //Convert from 0-14 to 1-15 as seen by user.

            Log.Message("CalculateNextRunTick Day:" + _CurrentDay.ToString() + " Hour " + _CurrentHour.ToString());

            int _NextHour = this.m_ScreenshotHours.Where(item => item > _CurrentHour).FirstOrDefault();
            int _NextDay  = this.m_ScreenshotDays.Where(item => item > _CurrentDay).FirstOrDefault();

            Log.Message("Next Hour is: " + _NextHour.ToString() + " Next Day: " + _NextDay.ToString());

            int _TicksThroughDay   = (int)((ticksNowAbs + this.LocalTicksOffsetFromLongitude((int)this.SettingAdvancedTimeZoneLongitude)) % 60000L);
            int _TicksAtStartOfDay = ticksNowAbs - _TicksThroughDay;

            Log.Message("_TicksAtStartOfDay: " + _TicksAtStartOfDay.ToString() + " _TicksThroughDay: " + _TicksThroughDay.ToString());

            int _DayOffset = 0;

            if (int.Equals(0, _NextHour))
            {
                _NextHour  = this.m_ScreenshotHours.FirstOrDefault();
                _DayOffset = _NextDay - _CurrentDay;
                Log.Message("Day offset: " + _DayOffset.ToString());
            }

            this.m_NextRunTicks = _TicksAtStartOfDay + _NextHour * GenDate.TicksPerHour + _DayOffset * GenDate.TicksPerDay;
            Log.Message("Running at: " + this.m_NextRunTicks);
        }
Exemplo n.º 6
0
        public void ReloadEvents()
        {
            events.Clear();
            int currentTick = this.game.tickManager.TicksAbs;

            Utils.LogDebug("Loading scheduled events...");
            foreach (ScheduledEvent e in ScheduledEventsSettings.events)
            {
                int nextEventTick = e.GetNextEventTick(currentTick);
                if (nextEventTick <= 0)
                {
                    Utils.LogDebug(e.incidentName + " event has invalid next tick");
                    continue;
                }
                Utils.LogDebug($"Event {e.incidentName} will happen on {GenDate.HourOfDay(nextEventTick, 0)}h, {GenDate.DateFullStringAt(nextEventTick, Vector2.zero)}");
                TickEvent.AddToList(events, nextEventTick, e);
            }
        }
        public override void Interacted(Pawn initiator, Pawn recipient, List <RulePackDef> extraSentencePacks, out string letterText, out string letterLabel, out LetterDef letterDef)
        {
            letterText  = null;
            letterLabel = null;
            letterDef   = null;
            //Choose a time that works with their schedule, based on their personality
            Dictionary <int, float> possibleHours = new Dictionary <int, float>();

            for (int i = 0; i < GenDate.HoursPerDay; i++)
            {
                possibleHours.Add(i, 0f);
            }
            foreach (PersonalityNodeDef d in DefDatabase <PersonalityNodeDef> .AllDefsListForReading)
            {
                if (d.preferredDateHours != null)
                {
                    foreach (int h in d.preferredDateHours)
                    {
                        possibleHours[h] += (Mathf.Pow(Mathf.Abs(0.5f - PsycheHelper.Comp(initiator).Psyche.GetPersonalityRating(d)), 2) / (1.3f - PsycheHelper.Comp(initiator).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Aggressive)) + Mathf.Pow(Mathf.Abs(0.5f - PsycheHelper.Comp(recipient).Psyche.GetPersonalityRating(d)), 2) / (1.3f - PsycheHelper.Comp(recipient).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Aggressive)) / 2f);
                    }
                }
            }
            int hour = possibleHours.Keys.RandomElementByWeight(h => possibleHours[h] * RendezvousUtility.TimeAssignmentFactor(initiator, h) * RendezvousUtility.TimeAssignmentFactor(recipient, h));
            //More Spontaneous couples will plan their dates sooner; possibly even immediately!
            int day = Find.TickManager.TicksAbs + Mathf.RoundToInt(GenDate.TicksPerDay * 5 * (((1f - PsycheHelper.Comp(initiator).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Spontaneous)) + (1f - PsycheHelper.Comp(recipient).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Spontaneous))) / 2f));
            Hediff_PlannedDate plannedDate = HediffMaker.MakeHediff(HediffDefOfPsychology.PlannedDate, initiator) as Hediff_PlannedDate;

            plannedDate.partner = recipient;
            plannedDate.day     = day;
            plannedDate.hour    = hour;
            initiator.health.AddHediff(plannedDate);
            PsycheHelper.Comp(initiator).Psyche.lastDateTick = day;
            PsycheHelper.Comp(recipient).Psyche.lastDateTick = day;
            if (PsychologyBase.SendDateLetters())
            {
                int    hourDiscrepancy = GenDate.HourOfDay(day, Find.WorldGrid.LongLatOf(initiator.Map.Tile).x) - hour;
                int    accurateTime    = day + (Math.Abs(hourDiscrepancy) * GenDate.TicksPerHour);
                String dateTime        = GenDate.QuadrumDateStringAt(accurateTime, Find.WorldGrid.LongLatOf(initiator.Map.Tile).x);
                Letter dateLetter      = LetterMaker.MakeLetter("LetterLabelDatePlanned".Translate(), "LetterDatePlanned".Translate(initiator, recipient, dateTime, hour), LetterDefOf.PositiveEvent);
                Find.LetterStack.ReceiveLetter(dateLetter);
            }
        }
Exemplo n.º 8
0
        public override void GameComponentTick()
        {
            int       currentTick = this.game.tickManager.TicksAbs;
            TickEvent nextEvent   = events.FirstOrDefault();

            if (nextEvent != null && nextEvent.tick <= currentTick)
            {
                Utils.LogDebug($"Firing scheduled {nextEvent.e.incidentName} event!");
                // Remove from list
                events.Remove(nextEvent);
                int nextEventTick = nextEvent.e.GetNextEventTick(currentTick);

                IncidentDef incident = nextEvent.e.GetIncident();
                if (incident != null)
                {
                    IEnumerable <IIncidentTarget> targets = nextEvent.e.incidentTarget.GetCurrentTarget(nextEvent.e);
                    if (targets.Count() > 0)
                    {
                        nextEvent.e.targetSelector.RunOn(targets, (target) => this.nextEvents.Add(new NextEvent(incident, target)));
                    }
                    else
                    {
                        Utils.LogDebugWarning($"Event found 0 targets");
                    }
                }
                else
                {
                    Utils.LogWarning($"Could not fire event, since it could not find an IncidentDef");
                }
                Utils.LogDebug($"Next event will happen on {GenDate.HourOfDay(nextEventTick, 0)}h, {GenDate.DateFullStringAt(nextEventTick, Vector2.zero)}");
                //Utils.LogDebug($"Hours until: {(nextEventTick - currentTick) / GenDate.TicksPerHour}");
                TickEvent.AddToList(events, nextEventTick, nextEvent.e);
            }
            if (nextEvents.Count > 0)
            {
                nextEvents.First().Execute();
                nextEvents.RemoveAt(0);
            }
            //Current.Game.storyteller.TryFire()
            base.GameComponentTick();
        }
Exemplo n.º 9
0
        private void ExecureOperation(int ticksNowAbs)
        {
            if (this.SettingAutoPause)
            {
                if (!Find.TickManager.Paused)
                {
                    Find.TickManager.TogglePaused();
                }
            }

            if (this.SettingDisplayMessage)
            {
                Letter _Letter = new Letter(this.SettingMessageLabel, this.SettingMessageContent, LetterType.Good);
                Find.LetterStack.ReceiveLetter(_Letter, "PhotoDay Letter");
            }

            if (this.SettingAutoScreenshot)
            {
                string _ScreenshotFolderPath = GenFilePaths.ScreenshotFolderPath;

                string _FullFilePath = _ScreenshotFolderPath;
                // _FullFilePath = _FullFilePath + (object)Path.DirectorySeparatorChar + GenDate.DaysPassedFloat.ToString() + ".jpg";
                if (this.SettingAdvancedMode)
                {
                    _FullFilePath = _FullFilePath + (object)Path.DirectorySeparatorChar +
                                    GenDate.Year(ticksNowAbs, this.SettingAdvancedTimeZoneLongitude) + "-" +
                                    GenDate.Season(ticksNowAbs, this.SettingAdvancedTimeZoneLongitude) + "-" +
                                    (GenDate.DayOfSeason(ticksNowAbs, this.SettingAdvancedTimeZoneLongitude) + 1).ToString().PadLeft(2, '0') + "-" +
                                    GenDate.HourOfDay(ticksNowAbs, this.SettingAdvancedTimeZoneLongitude).ToString().PadLeft(2, '0') + ".jpg";
                }
                else
                {
                    _FullFilePath = _FullFilePath + (object)Path.DirectorySeparatorChar +
                                    "Screenshot" + "-" +
                                    ticksNowAbs.ToString() + ".jpg";
                }

                Log.Message(_FullFilePath);
                Application.CaptureScreenshot(_FullFilePath);
            }
        }
Exemplo n.º 10
0
        public static void PlanFuneral(Building_Grave __instance, Pawn worker)
        {
            Pawn planner;

            (from c in worker.Map.mapPawns.FreeColonistsSpawned
             where c.relations.OpinionOf(__instance.Corpse.InnerPawn) >= 20
             select c).TryRandomElementByWeight((c) => Mathf.Max(0f, c.relations.OpinionOf(__instance.Corpse.InnerPawn) - (PsycheHelper.PsychologyEnabled(c) ? 100f * (1f - PsycheHelper.Comp(c).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Nostalgic)) : 0f)), out planner);
            if (planner != null && PsycheHelper.PsychologyEnabled(__instance.Corpse.InnerPawn) && !PsycheHelper.Comp(__instance.Corpse.InnerPawn).AlreadyBuried)
            {
                Func <int, float> timeAssignmentFactor = delegate(int h)
                {
                    if (planner.timetable.GetAssignment(h) == TimeAssignmentDefOf.Joy)
                    {
                        return(1.25f);
                    }
                    if (planner.timetable.GetAssignment(h) == TimeAssignmentDefOf.Anything)
                    {
                        return(0.9f);
                    }
                    return(0f);
                };
                int hour = -1;
                if (Enumerable.Range(0, GenDate.HoursPerDay).TryRandomElementByWeight(h => timeAssignmentFactor(h), out hour))
                {
                    int date       = Find.TickManager.TicksGame + Mathf.RoundToInt(GenDate.TicksPerDay * (2f + (PsycheHelper.PsychologyEnabled(planner) ? 3f - (5f * PsycheHelper.Comp(planner).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Spontaneous)) : 0f)));
                    int currentDay = GenDate.DayOfYear(GenDate.TickGameToAbs(date), Find.WorldGrid.LongLatOf(planner.Map.Tile).x);
                    if (currentDay <= GenLocalDate.DayOfYear(planner.Map) && GenDate.HourOfDay(GenDate.TickGameToAbs(date), Find.WorldGrid.LongLatOf(planner.Map.Tile).x) > hour)
                    {
                        date += GenDate.TicksPerDay * (currentDay - GenLocalDate.DayOfYear(planner.Map));
                    }
                    Hediff_Funeral planFuneral = HediffMaker.MakeHediff(HediffDefOfPsychology.PlannedFuneral, planner) as Hediff_Funeral;
                    planFuneral.date  = date;
                    planFuneral.hour  = hour;
                    planFuneral.day   = GenDate.DayOfYear(GenDate.TickGameToAbs(date), Find.WorldGrid.LongLatOf(planner.Map.Tile).x);
                    planFuneral.grave = __instance;
                    planFuneral.spot  = __instance.Position;
                    planner.health.AddHediff(planFuneral);
                    PsycheHelper.Comp(__instance.Corpse.InnerPawn).AlreadyBuried = true;
                }
            }
        }
Exemplo n.º 11
0
        public static int CurrentHour()
        {
            Vector2 vector;

            if (WorldRendererUtility.WorldRenderedNow && Find.WorldSelector.selectedTile >= 0)
            {
                vector = Find.WorldGrid.LongLatOf(Find.WorldSelector.selectedTile);
            }
            else if (WorldRendererUtility.WorldRenderedNow && Find.WorldSelector.NumSelectedObjects > 0)
            {
                vector = Find.WorldGrid.LongLatOf(Find.WorldSelector.FirstSelectedObject.Tile);
            }
            else
            {
                if (Find.CurrentMap == null)
                {
                    return(0);
                }
                vector = Find.WorldGrid.LongLatOf(Find.CurrentMap.Tile);
            }
            int num = (Find.TickManager.gameStartAbsTick == 0) ? Find.TickManager.TicksGame : Find.TickManager.TicksAbs;

            return(GenDate.HourOfDay((long)num, vector.x) + 1);
        }
Exemplo n.º 12
0
        public override void Init()
        {
            base.Init();
            //Make sure the election occurs during the day if possible.
            int plannedStart = GenDate.HourOfDay(this.Duration + Find.TickManager.TicksAbs, Find.WorldGrid.LongLatOf(this.SingleMap.Tile).x);

            if (plannedStart < 7)
            {
                this.Duration += (7 - plannedStart) * GenDate.TicksPerHour;
            }
            else if (plannedStart > 18)
            {
                this.Duration -= (plannedStart - 18) * GenDate.TicksPerHour;
            }
            IEnumerable <Pawn> psychologyColonists = (from p in this.SingleMap.mapPawns.FreeColonistsSpawned
                                                      where PsycheHelper.PsychologyEnabled(p)
                                                      select p);
            int   maxCandidatesThisColonySupports = Mathf.RoundToInt(psychologyColonists.Count() * 0.3f);
            float totalOutspoken = 0f;

            foreach (Pawn p in psychologyColonists)
            {
                totalOutspoken += PsycheHelper.Comp(p).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Outspoken);
            }
            int numCandidates = Rand.RangeInclusive(Mathf.Min(maxCandidatesThisColonySupports, 1 + Mathf.RoundToInt(totalOutspoken * 0.1f)), maxCandidatesThisColonySupports);
            int tries         = 0;

            while (this.candidates.Count < numCandidates && tries < 500)
            {
                Pawn candidate = psychologyColonists.RandomElementByWeight(p => (p.ageTracker.CurLifeStageIndex >= 3) ? PsycheHelper.Comp(p).Psyche.GetPersonalityRating(PersonalityNodeDefOf.Outspoken) * 2 + (p.health.hediffSet.HasHediff(HediffDefOfPsychology.Mayor) ? p.needs.mood.CurLevel - 0.5f : 0f) : 0f);
                List <PersonalityNodeDef> issues = new List <PersonalityNodeDef>();
                int tries2 = 0;
                while (issues.Count < 5 && tries2 < 500)
                {
                    PersonalityNodeDef issue = (from node in PsycheHelper.Comp(candidate).Psyche.PersonalityNodes
                                                where !node.Core
                                                select node.def).RandomElementByWeight(n => Mathf.Pow(Mathf.Abs(0.5f - PsycheHelper.Comp(candidate).Psyche.GetPersonalityRating(n)), 4) * Mathf.Pow(2, n.controversiality));
                    if (!issues.Contains(issue))
                    {
                        issues.Add(issue);
                    }
                    else
                    {
                        tries2++;
                    }
                }
                if (issues.Count >= 5 && this.candidates.Find(c => c.pawn == candidate) == null)
                {
                    this.candidates.Add(new Candidate(candidate, issues));
                }
                else
                {
                    if (issues.Count < 5)
                    {
                        Log.Error("[Psychology] Could not find five unique issues for " + candidate.LabelShort + "'s platform.");
                    }
                    tries++;
                }
            }
            if (candidates.Count == 0)
            {
                this.End();
                Log.Error("[Psychology] Tried to start election but could not find anyone to run.");
                return;
            }
            foreach (Candidate candidate in candidates)
            {
                StringBuilder issuesString = new StringBuilder();
                for (int i = 0; i < candidate.nodes.Count; i++)
                {
                    issuesString.AppendFormat("{0}) {1}{2}", i + 1, PsycheHelper.Comp(candidate.pawn).Psyche.GetPersonalityNodeOfDef(candidate.nodes[i]).PlatformIssue, (i != candidate.nodes.Count - 1 ? "\n" : ""));
                }
                Find.LetterStack.ReceiveLetter("LetterLabelElectionCandidate".Translate(candidate.pawn.LabelShort), "LetterElectionCandidate".Translate(candidate.pawn.LabelShort, Find.WorldObjects.ObjectsAt(candidate.pawn.Map.Tile).OfType <SettlementBase>().First().Label, issuesString.ToString()).AdjustedFor(candidate.pawn), LetterDefOf.NeutralEvent, candidate.pawn, null);
            }
        }
Exemplo n.º 13
0
        public override void Tick(int currentTick)
        {
            base.Tick(currentTick);

            int ticks = Find.TickManager.TicksAbs;

            if (ticks % GenDate.TicksPerHour != 0 || Find.CurrentMap == null || _store == null)
            {
                return;
            }

            Vector2 location     = Find.WorldGrid.LongLatOf(Find.CurrentMap.Tile);
            Quadrum quadrum      = GenDate.Quadrum(ticks, location.x);
            int     dayOfQuadrum = GenDate.DayOfQuadrum(ticks, location.x); // zero based
            int     hour         = GenDate.HourOfDay(ticks, location.x);

            // check settlement
            int     startTicks        = Find.TickManager.gameStartAbsTick;
            Quadrum settlementQuadrum = GenDate.Quadrum(startTicks, 0);
            int     settlementDay     = GenDate.DayOfQuadrum(startTicks, 0); // zero based
            int     settlementYears   = Mathf.RoundToInt(GenDate.YearsPassedFloat);

            if ((hour == 0 || _store.Settlement.Start() == hour) && settlementQuadrum == quadrum && settlementDay == dayOfQuadrum)
            {
                if (hour == 0)
                {
                    Messages.Message("DM.Message.TodaySettlement".Translate(settlementYears), MessageTypeDefOf.PositiveEvent);
                }
                else
                {
                    StartParty("DM.Letter.SettlementParty".Translate(), new List <Pawn>(), _store.Settlement == Duration.AllDay);
                }
            }

            // check built in days
            if (hour == 0 || _store.Birthdays.Start() == hour || _store.MarriageAnniversaries.Start() == hour || _store.LoversAnniversaries.Start() == hour)
            {
                Dictionary <Pawn, DirectPawnRelation> handledRelations = new Dictionary <Pawn, DirectPawnRelation>();

                var colonists = Find.CurrentMap.mapPawns.PawnsInFaction(Faction.OfPlayer);
                foreach (var colonist in colonists)
                {
                    if (colonist.Dead || !colonist.RaceProps.Humanlike)
                    {
                        continue;
                    }

                    // check marriage
                    List <DirectPawnRelation> marriageRelations = colonist.relations.DirectRelations.FindAll(x => x.def == PawnRelationDefOf.Spouse);
                    foreach (DirectPawnRelation relation in marriageRelations)
                    {
                        if (handledRelations.ContainsKey(colonist) || handledRelations.ContainsKey(relation.otherPawn))
                        {
                            continue;
                        }
                        handledRelations.Add(colonist, relation);
                        int     startTick    = relation.startTicks + startTicks;
                        int     startDay     = GenDate.DayOfQuadrum(startTick, location.x);
                        Quadrum startQuadrum = GenDate.Quadrum(startTick, location.x);
                        if (startDay == dayOfQuadrum && startQuadrum == quadrum)
                        {
                            if (hour == 0)
                            {
                                Messages.Message("DM.Message.TodayMarriageAnniversary".Translate(colonist.Name.ToStringShort, relation.otherPawn.Name.ToStringShort), MessageTypeDefOf.PositiveEvent);
                            }
                            else if (_store.MarriageAnniversaries.Start() == hour)
                            {
                                StartParty("DM.Letter.MarriageAnniversaryParty".Translate(colonist.Name.ToStringShort, relation.otherPawn.Name.ToStringShort), new List <Pawn> {
                                    colonist, relation.otherPawn
                                }, _store.MarriageAnniversaries == Duration.AllDay, colonist);
                            }
                        }
                    }

                    // check relationship
                    List <DirectPawnRelation> loverRelations = colonist.relations.DirectRelations.FindAll(x => x.def == PawnRelationDefOf.Lover);
                    foreach (DirectPawnRelation relation in loverRelations)
                    {
                        if (handledRelations.ContainsKey(colonist) || handledRelations.ContainsKey(relation.otherPawn))
                        {
                            continue;
                        }
                        handledRelations.Add(colonist, relation);
                        int     startTick    = relation.startTicks + startTicks;
                        int     startDay     = GenDate.DayOfQuadrum(startTick, location.x);
                        Quadrum startQuadrum = GenDate.Quadrum(startTick, location.x);
                        if (startDay == dayOfQuadrum && startQuadrum == quadrum)
                        {
                            if (hour == 0)
                            {
                                Messages.Message("DM.Message.TodayRelationshipAnniversary".Translate(colonist.Name.ToStringShort, relation.otherPawn.Name.ToStringShort), MessageTypeDefOf.PositiveEvent);
                            }
                            else if (_store.LoversAnniversaries.Start() == hour)
                            {
                                StartParty("DM.Letter.RelationshipAnniversaryParty".Translate(colonist.Name.ToStringShort, relation.otherPawn.Name.ToStringShort), new List <Pawn> {
                                    colonist, relation.otherPawn
                                }, _store.LoversAnniversaries == Duration.AllDay, colonist);
                            }
                        }
                    }

                    // check birthday
                    long    birthdayTick = colonist.ageTracker.BirthAbsTicks;
                    int     birthDate    = GenDate.DayOfQuadrum(birthdayTick, location.x); // zero based
                    Quadrum birthQuadrum = GenDate.Quadrum(birthdayTick, location.x);
                    int     colonistAge  = Mathf.RoundToInt(colonist.ageTracker.AgeChronologicalYearsFloat);
                    if (birthDate == dayOfQuadrum && birthQuadrum == quadrum)
                    {
                        if (hour == 0)
                        {
                            Messages.Message("DM.Message.TodayBirthday".Translate(colonist.Name.ToStringShort, colonistAge), MessageTypeDefOf.PositiveEvent);
                        }
                        else if (_store.Birthdays.Start() == hour)
                        {
                            StartParty("DM.Letter.BirthdayParty".Translate(colonist.Name.ToStringShort), new List <Pawn>(), _store.Birthdays == Duration.AllDay);
                        }
                    }
                }
            }

            // check custom days
            var matchedEvents = _store.MatteredDays.FindAll(x => x.DayOfQuadrum - 1 == dayOfQuadrum && x.Quadrum == quadrum);

            if (matchedEvents.Count == 0)
            {
                return;
            }

            foreach (MatteredDay day in matchedEvents)
            {
                if (hour == 0)
                {
                    Messages.Message("DM.Message.TodayCustomDay".Translate(day.Name), MessageTypeDefOf.PositiveEvent);
                }
                else if (day.Duration.Start() == hour)
                {
                    StartParty("DM.Letter.CustomDayParty".Translate(day.Name), new List <Pawn>(), day.Duration == Duration.AllDay);
                }
            }
        }