/// <summary> /// create the main log text /// </summary> /// <param name="pov">The pov.</param> /// <param name="forceLog">if set to <c>true</c> [force log].</param> /// <returns></returns> protected override string ToGameStringFromPOV_Worker(Thing pov, bool forceLog) { Assert(pov == _pawn, "pov == _pawn"); Rand.PushState(logID); // Does not need a MP-safe seed. try { GrammarRequest grammarRequest = GenerateGrammarRequest(); RulePackDef mutationRulePack = (_mutationDef as MutationDef)?.mutationLogRulePack; if (mutationRulePack != null) { grammarRequest.Includes.Add(mutationRulePack); } else { grammarRequest.Includes.Add(PMRulePackDefOf.GetDefaultPackForMutation(_mutationDef)); grammarRequest.Rules.Add(new Rule_String("DATE", GenDate.DateFullStringAt(ticksAbs, Vector2.zero))); } AddCustomRules(grammarRequest.Rules); IEnumerable <Rule> pawnR = GrammarUtility.RulesForPawn(PAWN_IDENTIFIER, _pawn, grammarRequest.Constants); BodyPartRecord partR = BodyDefOf.Human.AllParts.Where(r => _mutatedRecords.Contains(r.def)).RandomElement(); IEnumerable <Rule> partRules = GrammarUtility.RulesForBodyPartRecord(PART_LABEL, partR); IEnumerable <Rule> mutR = GrammarUtility.RulesForHediffDef(MUTATION_IDENTIFIER, _mutationDef, partR); // Add the rules. grammarRequest.Rules.AddRange(pawnR); grammarRequest.Rules.AddRange(mutR); grammarRequest.Rules.AddRange(partRules); return(GrammarResolver.Resolve(RP_ROOT_RULE, grammarRequest, "mutation log", forceLog)); } catch (Exception exception) { Log.Error($"encountered {exception.GetType().Name} exception while generating string for mutation log\n\t{exception}"); } finally { Rand.PopState(); // Make sure to always pop rand. } return(_mutationDef.LabelCap); //TODO generate string }
public void Put(string actionName, float value) { string color = value > 0 ? "red" : "cyan"; string date; if (pawn.Map != null || Find.CurrentMap != null) { int longitude = pawn.Map != null ? pawn.Map.Tile : Find.CurrentMap.Tile; date = GenDate.DateFullStringAt(Find.TickManager.TicksAbs, Find.WorldGrid.LongLatOf(longitude)); } else { date = "Uknown date"; } string entry = $"<color={color}><b>{date}:</b> <i>{actionName} ({value.ToStringPercent()})</i></color>"; log.Insert(0, entry); if (EnableLogging) { Log.Message($"Bad People: {pawn.Name} got entry '{entry}'"); } }
private void DoArchivableRow(Rect rect, IArchivable archivable, int index) { if (index % 2 == 1) { Widgets.DrawLightHighlight(rect); } Widgets.DrawHighlightIfMouseover(rect); Text.Font = GameFont.Small; Text.Anchor = TextAnchor.MiddleLeft; Text.WordWrap = false; Rect rect2 = rect; Rect rect3 = rect2; rect3.width = 30f; rect2.xMin += 40f; float num = Find.Archive.IsPinned(archivable) ? 1f : ((!Mouse.IsOver(rect3)) ? 0f : 0.25f); if (num > 0f) { GUI.color = new Color(1f, 1f, 1f, num); GUI.DrawTexture(new Rect(rect3.x + (rect3.width - 22f) / 2f, rect3.y + (rect3.height - 22f) / 2f, 22f, 22f).Rounded(), PinTex); GUI.color = Color.white; } Rect rect4 = rect2; Rect outerRect = rect2; outerRect.width = 30f; rect2.xMin += 40f; Texture archivedIcon = archivable.ArchivedIcon; if (archivedIcon != null) { GUI.color = archivable.ArchivedIconColor; Widgets.DrawTextureFitted(outerRect, archivedIcon, 0.8f); GUI.color = Color.white; } Rect rect5 = rect2; rect5.width = 200f; rect2.xMin += 210f; Vector2 location = (Find.CurrentMap == null) ? default(Vector2) : Find.WorldGrid.LongLatOf(Find.CurrentMap.Tile); GUI.color = new Color(0.75f, 0.75f, 0.75f); int num2 = GenDate.TickGameToAbs(archivable.CreatedTicksGame); string str = GenDate.DateFullStringAt(num2, location) + ", " + GenDate.HourInteger(num2, location.x) + "LetterHour".Translate(); Widgets.Label(rect5, str.Truncate(rect5.width)); GUI.color = Color.white; Rect rect6 = rect2; Widgets.Label(rect6, archivable.ArchivedLabel.Truncate(rect6.width)); GenUI.ResetLabelAlign(); Text.WordWrap = true; TooltipHandler.TipRegion(rect3, "PinArchivableTip".Translate(200)); if (Mouse.IsOver(rect4)) { TooltipHandler.TipRegion(rect4, archivable.ArchivedTooltip); } if (Widgets.ButtonInvisible(rect3)) { if (Find.Archive.IsPinned(archivable)) { Find.Archive.Unpin(archivable); SoundDefOf.Checkbox_TurnedOff.PlayOneShotOnCamera(); } else { Find.Archive.Pin(archivable); SoundDefOf.Checkbox_TurnedOn.PlayOneShotOnCamera(); } } if (Widgets.ButtonInvisible(rect4)) { if (Event.current.button == 1) { LookTargets lookTargets = archivable.LookTargets; if (CameraJumper.CanJump(lookTargets.TryGetPrimaryTarget())) { CameraJumper.TryJumpAndSelect(lookTargets.TryGetPrimaryTarget()); Find.MainTabsRoot.EscapeCurrentTab(); } } else { archivable.OpenArchived(); } } }
public override void Interacted(Pawn initiator, Pawn recipient, List <RulePackDef> extraSentencePacks) { PsychologyPawn realRecipient = recipient as PsychologyPawn; PsychologyPawn realInitiator = initiator as PsychologyPawn; //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 - realInitiator.psyche.GetPersonalityRating(d)), 2) / (1.3f - realInitiator.psyche.GetPersonalityRating(PersonalityNodeDefOf.Aggressive)) + Mathf.Pow(Mathf.Abs(0.5f - realRecipient.psyche.GetPersonalityRating(d)), 2) / (1.3f - realRecipient.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.TicksGame + Mathf.RoundToInt(GenDate.TicksPerDay * 5 * (((1f - realInitiator.psyche.GetPersonalityRating(PersonalityNodeDefOf.Spontaneous)) + (1f - realRecipient.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); realInitiator.psyche.lastDateTick = day; realRecipient.psyche.lastDateTick = day; if (Prefs.DevMode && Prefs.LogVerbose) { Log.Message(initiator.LabelShort + " planned date with " + recipient.LabelShort + " for hour " + hour + " on date " + GenDate.DateFullStringAt(GenDate.TickGameToAbs(day), Find.WorldGrid.LongLatOf(initiator.Map.Tile))); } }
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(); }
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); } }
protected override IEnumerable <Toil> MakeNewToils() { Passion passion = Passion.None; const float skillGainPerTick = 0.15f; float skillGainFactor = 0f; int studyDuration = 0; float statValue = this.pawn.GetStatValue(StatDefOf.ResearchSpeed, true); studyDuration = (int)Math.Round((double)(1200f / statValue)); yield return(Toils_Reserve.Reserve(terraformerIndex)); yield return(Toils_Goto.GotoCell(terraformerIndex, PathEndMode.InteractionCell).FailOnDestroyed(terraformerIndex)); Toil studyToil = new Toil() { initAction = () => { passion = this.pawn.skills.MaxPassionOfRelevantSkillsFor(WorkTypeDefOf.Research); if (passion == Passion.None) { skillGainFactor = 0.3f; } else if (passion == Passion.Minor) { skillGainFactor = 1f; } else { skillGainFactor = 1.5f; } }, tickAction = () => { this.pawn.skills.Learn(SkillDefOf.Research, skillGainPerTick * skillGainFactor); }, defaultCompleteMode = ToilCompleteMode.Delay, defaultDuration = studyDuration }; yield return(studyToil); Toil incrementStudyCounterToil = new Toil() { initAction = () => { Building_MechanoidTerraformer terraformer = this.TargetThingA as Building_MechanoidTerraformer; terraformer.studyCounter++; if (terraformer.studyCounter >= Building_MechanoidTerraformer.studyCounterTargetValue) { string herHisOrIts = "its"; if (pawn.gender == Gender.Female) { herHisOrIts = "her"; } else if (pawn.gender == Gender.Male) { herHisOrIts = "his"; } string studyReportHeader = " " + pawn.Name.ToStringShort + " has finished the study of the strange artifact. " + herHisOrIts.CapitalizeFirst() + " report is quite alarming!\n\n\n" + "### Study references ###\n\n" + "Date: " + GenDate.DateFullStringAt(Find.TickManager.TicksAbs) + "\n" + "Researcher: " + pawn.Name.ToStringFull + "\n\n"; terraformer.DisplayStudyReport(studyReportHeader); terraformer.def.label = "Mechanoid terraformer"; terraformer.reverseEngineeringState = Building_MechanoidTerraformer.ReverseEngineeringState.StudyCompleted; Building_MechanoidTerraformer.studyIsCompleted = true; } }, defaultCompleteMode = ToilCompleteMode.Instant }; yield return(incrementStudyCounterToil); yield return(Toils_Reserve.Release(terraformerIndex)); }