public override void RunCommand([NotNull] ITwitchMessage message) { string code = CommandFilter.Parse(message.Message).Skip(1).FirstOrDefault(); if (code.NullOrEmpty()) { return; } if (!Data.ColorIndex.TryGetValue(code !.ToLowerInvariant(), out Color color) && !ColorUtility.TryParseHtmlString(code, out color)) { MessageHelper.ReplyToUser(message.Username, "TKUtils.NotAColor".LocalizeKeyed(code)); return; } if (!PurchaseHelper.TryGetPawn(message.Username, out Pawn pawn)) { MessageHelper.ReplyToUser(message.Username, "TKUtils.NoPawn".Localize()); return; } pawn.story.favoriteColor = new Color(color.r, color.g, color.b, 1f); message.Reply("TKUtils.FavoriteColor.Complete".Localize()); }
public override void RunCommand([NotNull] ITwitchMessage twitchMessage) { if (!PurchaseHelper.TryGetPawn(twitchMessage.Username, out Pawn pawn)) { twitchMessage.Reply("TKUtils.NoPawn".Localize()); return; } if (pawn !.IsCaravanMember()) { twitchMessage.Reply("TKUtils.Leave.Caravan".Localize()); return; } var component = Current.Game.GetComponent <GameComponentPawns>(); if (CompatRegistry.Magic?.IsUndead(pawn) ?? false) { twitchMessage.Reply("TKUtils.Leave.Undead".Localize()); component?.pawnHistory.Remove(twitchMessage.Username); if (pawn.Name is NameTriple name) { pawn.Name = new NameTriple(name.First ?? "", name.Last ?? "", name.Last ?? ""); } return; } ForceLeave(twitchMessage, pawn); component.pawnHistory.Remove(twitchMessage.Username); }
public override bool CanHappen(string msg, [NotNull] Viewer viewer) { if (!PurchaseHelper.TryGetPawn(viewer.username, out _pawn)) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.NoPawn".Localize()); return(false); } var worker = ArgWorker.CreateInstance(CommandFilter.Parse(msg).Skip(2)); if (!worker.TryGetNextAsItem(out _item) || !_item.IsValid()) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.InvalidItemQuery".LocalizeKeyed(worker.GetLast())); return(false); } if (_item.TryGetError(out string error)) { MessageHelper.ReplyToUser(viewer.username, error); return(false); } if (!(_item.Thing.Thing is { IsWeapon : true }) || _item.Thing.ItemData?.IsEquippable != true)
public override bool CanHappen(string msg, [NotNull] Viewer viewer) { if (!PurchaseHelper.TryGetPawn(viewer.username, out _pawn)) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.NoPawn".Localize()); return(false); } if (IncidentSettings.HealMe.FairFights && _pawn !.mindState.lastAttackTargetTick > 0 && Find.TickManager.TicksGame < _pawn.mindState.lastAttackTargetTick + 1800) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.InCombat".Localize()); return(false); } object result = HealHelper.GetPawnHealable(_pawn !); switch (result) { case Hediff hediff: _toHeal = hediff; break; case BodyPartRecord record: _toRestore = record; break; } return(_toHeal != null || _toRestore != null); }
public override void RunCommand([NotNull] ITwitchMessage twitchMessage) { if (!PurchaseHelper.TryGetPawn(twitchMessage.Username, out Pawn pawn)) { twitchMessage.Reply("TKUtils.NoPawn".Localize()); return; } var parts = new List <string>(); List <SkillRecord> skills = pawn !.skills.skills; foreach (SkillRecord skill in skills) { var container = ""; container += ResponseHelper.JoinPair(skill.def.LabelCap, skill.TotallyDisabled ? ResponseHelper.ForbiddenGlyph.AltText("-") : skill.levelInt.ToString()); container += !Interests.Active ? string.Concat(Enumerable.Repeat(ResponseHelper.FireGlyph.AltText("+"), (int)skill.passion)) : Interests.GetIconForPassion(skill); parts.Add(container); } twitchMessage.Reply(parts.SectionJoin().WithHeader("StatsReport_Skills".Localize())); }
public override void RunCommand([NotNull] ITwitchMessage twitchMessage) { if (!PurchaseHelper.TryGetPawn(twitchMessage.Username, out Pawn pawn)) { twitchMessage.Reply("TKUtils.NoPawn".Localize()); return; } List <string> queries = CommandFilter.Parse(twitchMessage.Message).Skip(1).Select(PurchaseHelper.ToToolkit).ToList(); if (queries.Count <= 0) { queries.AddRange(DefaultStats); } List <StatDef> container = queries.Select(FindStat).Where(s => s != null).ToList(); if (container.Count <= 0) { return; } CommandRouter.MainThreadCommands.Enqueue( () => { MessageHelper.ReplyToUser(twitchMessage.Username, container.Select(s => FormatStat(pawn, s)).SectionJoin()); } ); }
public override bool CanHappen(string msg, [NotNull] Viewer viewer) { if (!PurchaseHelper.TryGetPawn(viewer.username, out _pawn)) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.NoPawn".Localize()); return(false); } if (IncidentSettings.FullHeal.FairFights && _pawn !.mindState.lastAttackTargetTick > 0 && Find.TickManager.TicksGame < _pawn.mindState.lastAttackTargetTick + 1800) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.InCombat".Localize()); return(false); } if (HealHelper.GetPawnHealable(_pawn !) != null) { return(true); } MessageHelper.ReplyToUser(viewer.username, "TKUtils.NotInjured".Localize()); return(false); }
public override void RunCommand([NotNull] ITwitchMessage twitchMessage) { if (!PurchaseHelper.TryGetPawn(twitchMessage.Username, out Pawn pawn)) { twitchMessage.Reply("TKUtils.NoPawn".Localize()); return; } int totalKills = pawn !.records.GetAsInt(RecordDefOf.Kills); int animalKills = pawn.records.GetAsInt(RecordDefOf.KillsAnimals); int humanLikeKills = pawn.records.GetAsInt(RecordDefOf.KillsHumanlikes); int mechanoidKills = pawn.records.GetAsInt(RecordDefOf.KillsMechanoids); string container = ResponseHelper.JoinPair("TKUtils.PawnKills.Total".Localize().CapitalizeFirst(), totalKills.ToString("N0")); container += ResponseHelper.OuterGroupSeparator; container += string.Join( ", ", ResponseHelper.JoinPair("TKUtils.PawnKills.Humanlike".Localize().CapitalizeFirst(), humanLikeKills.ToString("N0")), ResponseHelper.JoinPair("TKUtils.PawnKills.Animals".Localize().CapitalizeFirst(), animalKills.ToString("N0")), ResponseHelper.JoinPair("TKUtils.PawnKills.Mechanoids".Localize().CapitalizeFirst(), mechanoidKills.ToString("N0")) ); twitchMessage.Reply(container); }
/// <inheritdoc/> protected override void ProcessAcceptInternal(string asker, string askee) { if (!PurchaseHelper.TryGetPawn(asker, out Pawn askerPawn)) { MessageHelper.ReplyToUser(asker, "TKUtils.NoPawn".LocalizeKeyed(asker)); return; } if (!PurchaseHelper.TryGetPawn(askee, out Pawn askeePawn)) { MessageHelper.ReplyToUser(asker, "TKUtils.PawnNotFound".LocalizeKeyed(askee)); return; } if (!GameHelper.CanPawnsMarry(askerPawn, askeePawn)) { MessageHelper.ReplyToUser(asker, "TKUtils.Marriage.NoSlots".Localize()); return; } TkUtils.Context.Post(c => PerformMarriage(askerPawn, askeePawn), null); }
public override bool CanHappen(string msg, [NotNull] Viewer viewer) { if (!PurchaseHelper.TryGetPawn(viewer.username, out _pawn)) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.NoPawn".Localize()); return(false); } var worker = ArgWorker.CreateInstance(CommandFilter.Parse(msg).Skip(2)); if (!worker.TryGetNextAsSkill(out SkillDef skillDef)) { return(false); } _target = _pawn !.skills.skills.Where(s => !s.TotallyDisabled).FirstOrDefault(s => s.def.Equals(skillDef)); if (_target == null) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.InvalidSkillQuery".LocalizeKeyed(worker.GetLast())); return(false); } if ((int)_target.passion < 3) { return(true); } MessageHelper.ReplyToUser(viewer.username, "TKUtils.Passion.Full".Localize()); return(false); }
public override bool CanHappen(string msg, [NotNull] Viewer viewer) { if (!PurchaseHelper.TryGetPawn(viewer.username, out _pawn)) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.NoPawn".Localize()); return(false); } var worker = ArgWorker.CreateInstance(CommandFilter.Parse(msg).Skip(2)); if (!worker.TryGetNextAsTrait(out _thisShop) || !worker.TryGetNextAsTrait(out _thatShop)) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.InvalidTraitQuery".LocalizeKeyed(worker.GetLast())); return(false); } if (!IsUsable(_thisShop, _thatShop)) { MessageHelper.ReplyToUser( viewer.username, $"TKUtils.{(_thisShop.CanRemove ? "" : "Remove")}Trait.Disabled".LocalizeKeyed((_thisShop.CanRemove ? _thatShop : _thisShop).Name.CapitalizeFirst()) ); return(false); } if (TraitHelper.GetTotalTraits(_pawn) >= AddTraitSettings.maxTraits && WouldExceedLimit()) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.ReplaceTrait.Violation".LocalizeKeyed(_thisShop.Name, _thatShop.Name)); return(false); } if (!viewer.CanAfford(TotalPrice)) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.InsufficientBalance".LocalizeKeyed(TotalPrice.ToString("N0"), viewer.GetViewerCoins().ToString("N0"))); return(false); } if (!PassesCharacterCheck(viewer)) { return(false); } if (!PassesModCheck(viewer)) { return(false); } if (!PassesValidationCheck(viewer)) { return(false); } return(true); }
public string GetSkillDescription(string invoker, string query) { if (!PurchaseHelper.TryGetPawn(invoker, out Pawn pawn)) { return("TKUtils.NoPawn".Localize()); } var builder = new StringBuilder(); var userMagic = pawn.TryGetComp <CompAbilityUserMagic>(); if (userMagic is { IsMagicUser : true } && TryGetMagicDescription(userMagic, query.ToToolkit(), out string description))
public override void RunCommand([NotNull] ITwitchMessage twitchMessage) { if (!PurchaseHelper.TryGetPawn(twitchMessage.Username, out Pawn pawn)) { twitchMessage.Reply("TKUtils.NoPawn".Localize().WithHeader("TabGear".Localize())); return; } twitchMessage.Reply(GetPawnGear(pawn).WithHeader("TabGear".Localize())); }
public override bool CanHappen(string msg, [NotNull] Viewer viewer) { if (!PurchaseHelper.TryGetPawn(viewer.username, out _pawn)) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.NoPawn".Localize()); return(false); } _backstory = BackstoryDatabase.allBackstories.Values.Where(b => b.slot == BackstorySlot.Adulthood) .Where(b => !WouldBeViolation(b)) .InRandomOrder() .FirstOrDefault(); return(_backstory != null); }
public override bool CanHappen(string msg, [NotNull] Viewer viewer) { if (!PurchaseHelper.TryGetPawn(viewer.username, out _pawn)) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.NoPawn".Localize()); return(false); } if (!Immortals.Active) { return(false); } return(!_pawn !.health.hediffSet.HasHediff(Immortals.ImmortalHediffDef)); }
public override void RunCommand([NotNull] ITwitchMessage twitchMessage) { if (!PurchaseHelper.TryGetPawn(twitchMessage.Username, out Pawn pawn)) { twitchMessage.Reply("TKUtils.NoPawn".Localize().WithHeader("TKUtils.PawnWork.Header".Localize())); return; } if (pawn !.workSettings?.EverWork == false) { twitchMessage.Reply("TKUtils.PawnWork.None".Localize().WithHeader("TKUtils.PawnWork.Header".Localize())); return; } List <KeyValuePair <string, string> > newPriorities = CommandParser.ParseKeyed(twitchMessage.Message); if (!newPriorities.NullOrEmpty()) { var builder = new StringBuilder(); foreach (string change in ProcessChangeRequests(pawn, newPriorities)) { builder.Append(change); builder.Append(", "); } if (builder.Length > 0) { builder.Remove(builder.Length - 2, 2); twitchMessage.Reply("TKUtils.PawnWork.Changed".LocalizeKeyed(builder.ToString())); return; } } string summary = GetWorkPrioritySummary(pawn); if (summary.NullOrEmpty()) { return; } twitchMessage.Reply(summary.WithHeader("TKUtils.PawnWork.Header".Localize())); }
public override bool CanHappen(string msg, [NotNull] Viewer viewer) { if (!PurchaseHelper.TryGetPawn(viewer.username, out _pawn)) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.NoPawn".Localize()); return(false); } if (_pawn.kindDef?.RaceProps?.hasGenders == true || _pawn.gender == Gender.None) { return(true); } MessageHelper.ReplyToUser(viewer.username, "TKUtils.GenderSwap.None".Localize()); return(false); }
public override bool CanHappen([NotNull] string msg, [NotNull] Viewer viewer) { if (!viewer.mod || !viewer.username.EqualsIgnoreCase(ToolkitCoreSettings.channel_username)) { return(false); } string target = msg.Split(' ').Skip(2).FirstOrDefault(); if (PurchaseHelper.TryGetPawn(target, out _pawn)) { return(_pawn?.Spawned == true && _pawn?.Map != null); } MessageHelper.ReplyToUser(viewer.username, "TKUtils.PawnNotFound".LocalizeKeyed(target)); return(false); }
public override bool CanHappen(string msg, [NotNull] Viewer viewer) { if (!PurchaseHelper.TryGetPawn(viewer.username, out _pawn)) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.NoPawn".Localize()); return(false); } if (PawnTracker.pawnsToRevive.Contains(_pawn)) { return(false); } PawnTracker.pawnsToRevive.Add(_pawn); return(true); }
public override void RunCommand([NotNull] ITwitchMessage twitchMessage) { if (!PurchaseHelper.TryGetPawn(twitchMessage.Username, out Pawn pawn)) { twitchMessage.Reply("TKUtils.NoPawn".Localize()); return; } var name = pawn !.Name as NameTriple; if (name?.Nick != twitchMessage.Username) { pawn.Name = new NameTriple(name?.First ?? "", twitchMessage.Username, name?.Last ?? ""); } twitchMessage.Reply("TKUtils.PawnFix".Localize()); }
public override bool CanHappen(string msg, [NotNull] Viewer viewer) { if (!PurchaseHelper.TryGetPawn(viewer.username, out _pawn)) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.NoPawn".Localize()); return(false); } var worker = ArgWorker.CreateInstance(CommandFilter.Parse(msg).Skip(2)); if (!worker.TryGetNextAsTrait(out _buyableTrait) || !_buyableTrait.CanAdd || _buyableTrait.TraitDef == null) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.InvalidTraitQuery".LocalizeKeyed(worker.GetLast())); return(false); } if (!viewer.CanAfford(_buyableTrait !.CostToAdd)) { MessageHelper.ReplyToUser( viewer.username, "TKUtils.InsufficientBalance".LocalizeKeyed(_buyableTrait.CostToAdd.ToString("N0"), viewer.GetViewerCoins().ToString("N0")) ); return(false); } if (TraitHelper.GetTotalTraits(_pawn) >= AddTraitSettings.maxTraits && _buyableTrait.TraitData?.CanBypassLimit != true) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.Trait.LimitReached".LocalizeKeyed(AddTraitSettings.maxTraits)); return(false); } if (!PassesCharacterChecks(viewer, worker)) { return(false); } _trait = new Trait(_buyableTrait.TraitDef, _buyableTrait.Degree); return(PassesValidationChecks(viewer) && PassesModChecks(viewer)); }
public override void RunCommand([NotNull] ITwitchMessage twitchMessage) { foreach (Viewer viewer in Viewers.All) { if (!PurchaseHelper.TryGetPawn(viewer.username, out Pawn pawn)) { continue; } var name = pawn !.Name as NameTriple; if (name?.Nick != viewer.username) { pawn.Name = new NameTriple(name?.First ?? "", viewer.username, name?.Last ?? ""); } } twitchMessage.Reply("TKUtils.FixAll".Localize()); }
/// <inheritdoc/> public override void RunCommand([NotNull] ITwitchMessage twitchMessage) { if (!PurchaseHelper.TryGetPawn(twitchMessage.Username, out Pawn pawn)) { MessageHelper.ReplyToUser(twitchMessage.Username, "TKUtils.NoPawn".Localize()); return; } var worker = ArgWorker.CreateInstance(CommandFilter.Parse(twitchMessage.Message).Skip(1)); if (!worker.TryGetNextAsViewer(out Viewer viewer) || !PurchaseHelper.TryGetPawn(viewer.username, out Pawn target)) { MessageHelper.ReplyToUser(twitchMessage.Username, "TKUtils.PawnNotFound".LocalizeKeyed(worker.GetLast())); return; } TkUtils.Context.Post(c => PerformDivorce(pawn, target), null); }
public override void RunCommand([NotNull] ITwitchMessage twitchMessage) { if (!PurchaseHelper.TryGetPawn(twitchMessage.Username, out Pawn pawn)) { twitchMessage.Reply("TKUtils.NoPawn".Localize()); return; } if (pawn !.needs?.AllNeeds == null) { twitchMessage.Reply("TKUtils.PawnNeeds.None".Localize().WithHeader("TabNeeds".Localize())); return; } twitchMessage.Reply( pawn.needs.AllNeeds.Select(n => ResponseHelper.JoinPair(n.LabelCap, n.CurLevelPercentage.ToStringPercent())).SectionJoin().WithHeader("TabNeeds".Localize()) ); }
public override void RunCommand([NotNull] ITwitchMessage twitchMessage) { if (!PurchaseHelper.TryGetPawn(twitchMessage.Username, out Pawn pawn)) { twitchMessage.Reply("TKUtils.NoPawn".Localize()); return; } var component = Current.Game.GetComponent <GameComponentPawns>(); if (component == null) { return; } string viewer = CommandFilter.Parse(twitchMessage.Message).Skip(1).FirstOrFallback(); if (!viewer.NullOrEmpty() && component.pawnHistory.TryGetValue(viewer.ToLowerInvariant(), out Pawn viewerPawn)) { int theirOpinion = viewerPawn.relations.OpinionOf(pawn); int myOpinion = pawn !.relations.OpinionOf(viewerPawn); string relationship = GetSocialString(pawn, viewerPawn, myOpinion, true); if (relationship.NullOrEmpty()) { return; } var container = new List <string> { $"{myOpinion.ToStringWithSign()} ({twitchMessage.Username!.ToLowerInvariant()})", $"{theirOpinion.ToStringWithSign()} ({viewer.ToLowerInvariant()})" }; twitchMessage.Reply(new[] { relationship, container.SectionJoin() }.GroupedJoin()); return; } ShowRelationshipOverview(twitchMessage, component, pawn); }
public override bool CanHappen(string msg, [NotNull] Viewer viewer) { if (!PurchaseHelper.TryGetPawn(viewer.username, out _pawn)) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.NoPawn".Localize()); return(false); } int passions = _pawn !.skills.skills.Sum(skill => (int)skill.passion); if (passions <= 0) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.PassionShuffle.None".Localize()); return(false); } string query = CommandFilter.Parse(msg).Skip(2).FirstOrDefault(); if (query.NullOrEmpty()) { return(_pawn.skills.skills.Any(s => (int)s.passion > (int)Passion.None)); } _target = _pawn.skills.skills.FirstOrDefault( s => s.def.defName.EqualsIgnoreCase(query !.ToToolkit()) || (s.def.skillLabel?.ToToolkit().EqualsIgnoreCase(query.ToToolkit()) ?? false) || (s.def.label?.ToToolkit().EqualsIgnoreCase(query.ToToolkit()) ?? false) ) ?.def; if (_target != null) { return(_pawn.skills.skills.Any(s => (int)s.passion > (int)Passion.None)); } MessageHelper.ReplyToUser(viewer.username, "TKUtils.InvalidSkillQuery".LocalizeKeyed(query)); return(false); }
public static KidnapReport KidnapReportFor(string username) { if (PurchaseHelper.TryGetPawn(username, out Pawn linkedPawn)) { return(new KidnapReport { Viewer = username, PawnIds = new List <string> { linkedPawn.ThingID } }); } if (Find.FactionManager?.AllFactions.Any() != true) { return(null); } var report = new KidnapReport { Viewer = username, PawnIds = new List <string>() }; foreach (Pawn pawn in Find.FactionManager.AllFactions.SelectMany(f => f.kidnapped.KidnappedPawnsListForReading)) { if (!(pawn.Name is NameTriple name) || !name.Nick.EqualsIgnoreCase(username)) { continue; } report.PawnIds.Add(pawn.ThingID); } foreach (Pawn pawn in Find.WorldPawns.AllPawnsAlive) { if (pawn.GuestStatus == GuestStatus.Prisoner && pawn.HomeFaction == Faction.OfPlayer) { report.PawnIds.Add(pawn.ThingID); } } return(report); }
public override void RunCommand([NotNull] ITwitchMessage message) { _invoker = message.Username; if (!PurchaseHelper.TryGetPawn(message.Username, out _pawn)) { message.Reply("TKUtils.NoPawn".Localize()); return; } string hexcode = CommandFilter.Parse(message.Message).Skip(1).FirstOrDefault(); List <KeyValuePair <string, string> > apparelPairs = CommandParser.ParseKeyed(message.Message); if (!apparelPairs.NullOrEmpty()) { CommandRouter.MainThreadCommands.Enqueue(() => DyeApparel(apparelPairs)); return; } if (hexcode.NullOrEmpty()) { CommandRouter.MainThreadCommands.Enqueue(() => DyeAll(null)); return; } string s = hexcode !.ToToolkit(); if (!Data.ColorIndex.TryGetValue(s, out Color color) && !ColorUtility.TryParseHtmlString(s, out color)) { message.Reply("TKUtils.NotAColor".LocalizeKeyed(s)); return; } CommandRouter.MainThreadCommands.Enqueue(() => DyeAll(new Color(color.r, color.g, color.b, 1f))); }
public override bool CanHappen(string msg, [NotNull] Viewer viewer) { if (!PurchaseHelper.TryGetPawn(viewer.username, out _pawn)) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.NoPawn".Localize()); return(false); } string query = CommandFilter.Parse(msg).Skip(2).FirstOrDefault(); if (query.NullOrEmpty()) { return(false); } _target = _pawn !.skills.skills.Where(s => !s.TotallyDisabled) .FirstOrDefault( s => s.def.defName.EqualsIgnoreCase(query !.ToToolkit()) || (s.def.skillLabel?.ToToolkit().EqualsIgnoreCase(query.ToToolkit()) ?? false) || (s.def.label?.ToToolkit().EqualsIgnoreCase(query.ToToolkit()) ?? false) ); if (_target == null) { MessageHelper.ReplyToUser(viewer.username, "TKUtils.InvalidSkillQuery".LocalizeKeyed(query)); return(false); } if ((int)_target.passion is { } passion&& passion > 0 && passion < 3) { return(true); } MessageHelper.ReplyToUser(viewer.username, "TKUtils.RemovePassion.None".LocalizeKeyed(query)); return(false); }
public override void RunCommand([NotNull] ITwitchMessage twitchMessage) { if (!PurchaseHelper.TryGetPawn(twitchMessage.Username, out Pawn pawn)) { twitchMessage.Reply("TKUtils.NoPawn".Localize()); return; } var magic = pawn.TryGetComp <CompAbilityUserMagic>(); var might = pawn.TryGetComp <CompAbilityUserMight>(); bool isMightUser = might is { IsMightUser : true }; bool isMagicUser = magic is { IsMagicUser : true }; if (!isMightUser && !isMagicUser) { twitchMessage.Reply("TKUtils.PawnClass.None".Localize()); return; } var container = new List <string>(); if (isMightUser) { container.Add(ExtractMightData(pawn, might)); } if (isMagicUser) { container.Add(ExtractMagicData(pawn, magic)); } string className = ExtractClassName(pawn); string joined = container.GroupedJoin(); twitchMessage.Reply(className.NullOrEmpty() ? joined : joined.WithHeader(className)); }