public void CheckOwnedItems(List <Thing> things)
        {
            for (int i = 0; i < things.Count; i++)
            {
                if (targetSettings.thingSettings != null)
                {
                    if (things[i].ThingIsValid(targetSettings.thingSettings))
                    {
                        if (!trackedThings.Contains(things[i]) && trackedThings.Count < targetSettings.thingSettings.minAmount)
                        {
                            trackedThings.Add(things[i]);
                        }
                    }
                }

                Thing thing = things[i];
                thing = thing.GetInnerIfMinified();
                ThingDef   def = thing.def;
                ThingValue tv  = TargetsDone.ThingValue(def);
                if (tv != null && TargetsDone[tv] < tv.value)
                {
                    int  value = 0;
                    bool flag  = CurrentlyOwnedTargets.TryGetValue(thing, out int lastStack);
                    value = flag ? thing.stackCount - lastStack : thing.stackCount;
                    int total = TargetsDone[tv] + value;
                    if (total > tv.value)
                    {
                        int excess = total - tv.value;
                        value = value - excess;
                    }
                    TargetsDone[tv] += value;
                    if (!flag)
                    {
                        CurrentlyOwnedTargets.Add(thing, thing.stackCount);
                    }
                    else
                    {
                        CurrentlyOwnedTargets[thing] = thing.stackCount;
                    }
                }
            }
            for (int i = 0; i < CurrentlyOwnedTargets.Count; i++)
            {
                Thing thing = CurrentlyOwnedTargets.ElementAt(i).Key;
                if (!things.Contains(thing))
                {
                    ThingValue tv    = TargetsDone.ThingValue(thing.def);
                    int        value = CurrentlyOwnedTargets[thing];
                    int        total = TargetsDone[tv] - value;
                    if (total < 0)
                    {
                        int excess = total;
                        value = value + excess;
                    }
                    TargetsDone[tv] -= GetCount(value, tv, CurrentlyOwnedTargets.Keys.ToList());
                    CurrentlyOwnedTargets.Remove(thing);
                }
            }
        }
        public int GetNeedCount(ThingDef def)
        {
            ThingValue thingvalue = targetSettings.targets.Find(tv => tv.ThingDef == def);

            if (thingvalue != null)
            {
                return(thingvalue.value);
            }
            return(0);
        }
Exemple #3
0
        private void DrawRewardContainer(Rect rect, string label, ref Vector2 pos, List <IncidentProperties> properties)
        {
            properties = properties.FindAll(p => p.type == IncidentType.Reward);
            Vector2 LabelSize = Text.CalcSize(label);
            Rect    LabelRect = new Rect(new Vector2(5f, rect.y), LabelSize);

            Widgets.Label(LabelRect, label);

            rect = new Rect(rect.x, rect.y + 22f, rect.width, rect.height);
            StoryUtils.DrawMenuSectionColor(new Rect(rect.x, rect.y + 24f, rect.width, rect.height), 1, new ColorInt(40, 40, 40), StoryMats.defaultBorder);

            List <ThingValue> things      = ThingsFromIncidents(properties);
            float             TotalHeight = things.Count * 34f;
            Rect UpperTab = new Rect(rect.x, rect.y, rect.width, 24f);

            StoryUtils.DrawMenuSectionColor(UpperTab, 1, new ColorInt(40, 40, 40), StoryMats.defaultBorder);
            float tenth = UpperTab.width * 0.1f;

            float itemPos = UpperTab.x += 5f;

            Widgets.Label(UpperTab, "Item_SMO".Translate());
            float ChancePos = UpperTab.x += tenth * 8.5f;

            Widgets.Label(UpperTab, "Chance_SMO".Translate());
            Rect ContainerRect = new Rect(rect.x, UpperTab.yMax, rect.width, rect.height + 2f).ContractedBy(1f);

            GUI.BeginGroup(ContainerRect);
            Widgets.BeginScrollView(new Rect(0f, 0f, ContainerRect.width, ContainerRect.height), ref pos, new Rect(0f, 0f, ContainerRect.width, TotalHeight), false);
            float CurY = 5f;

            for (int i = 0; i < things.Count; i++)
            {
                if (i % 2 == 0)
                {
                    GUI.color = new Color(1f, 1f, 1f, 0.5f);
                    Widgets.DrawHighlight(new Rect(0f, CurY - 5f, ContainerRect.width, 34f));
                    GUI.color = Color.white;
                }
                ThingValue thingValue = things[i];
                ThingDef   thingDef   = thingValue.ThingDef;
                WidgetRow  itemRow    = new WidgetRow(itemPos, CurY);
                GUI.color = ResolveColor(thingValue);
                itemRow.Icon(thingValue.ThingDef.uiIcon);
                GUI.color = Color.white;
                string qualityLabel = !thingDef.CountAsResource ? " (" + thingValue.QualityCategory.GetLabel() + ")" : "";
                float  LabelY       = itemRow.Label((thingValue.ResolvedStuff == null ? "" : thingValue.ResolvedStuff.LabelCap + " ") + thingDef.LabelCap + qualityLabel + " (x" + thingValue.value + ")").y;
                itemRow.Gap(ChancePos - itemRow.FinalX);
                itemRow.Label(thingValue.chance.ToStringPercent());
                CurY += 34f;
            }
            Widgets.EndScrollView();
            GUI.EndGroup();
        }
        public void ProcessTarget(ThingDef def, bool isColonist = false)
        {
            if (isColonist)
            {
                lostColonists++;
            }
            ThingValue thingValue = TargetsLost.ThingValue(def);

            if (thingValue != null && TargetsLost[thingValue] < thingValue.value)
            {
                TargetsLost[thingValue] += 1;
            }
        }
        private int GetCount(int value, ThingValue thingValue, List <Thing> things)
        {
            IEnumerable <Thing> listOfDef = things.Where(t => t.def == thingValue.ThingDef);

            if (listOfDef.Count() > 1)
            {
                int sum = CurrentlyOwnedTargets.Sum(t => t.Value);
                if (sum > thingValue.value && sum - value < thingValue.value)
                {
                    return(thingValue.value - (sum - value));
                }
            }
            return(value);
        }
Exemple #6
0
 public void ProcessTarget <T>(T t, IntVec3 cell, Map map, ObjectiveType type, Thing craftedThing = null, Pawn pawn = null)
 {
     if (this.type == type)
     {
         if (targetSettings.thingSettings != null)
         {
             if (craftedThing.ThingIsValid(targetSettings.thingSettings))
             {
                 if (type == ObjectiveType.Destroy)
                 {
                     count++;
                 }
                 else
                 if (!CurrentlyOwnedTargets.TryGetValue(craftedThing, out int value))
                 {
                     CurrentlyOwnedTargets.Add(craftedThing, craftedThing.stackCount);
                     LastTarget = craftedThing;
                 }
             }
         }
         else if (targetSettings.pawnSettings != null)
         {
             if (pawn != null)
             {
                 if (targetSettings.pawnSettings.PawnSatisfies(pawn))
                 {
                     if (type == ObjectiveType.Kill)
                     {
                         count++;
                     }
                     else
                     if (!trackedPawns.Contains(pawn))
                     {
                         trackedPawns.Add(pawn);
                         LastTarget = craftedThing;
                     }
                 }
             }
         }
         else
         {
             ThingValue tv = TargetsDone.ThingValue(t);
             if (tv != null && TargetsDone[tv] < tv.value && tv.ThingFits(craftedThing))
             {
                 TargetsDone[tv] += 1;
                 LastTarget       = new TargetInfo(cell, map, true);
             }
         }
     }
 }
        public void ProcessTarget <T>(T t, IntVec3 cell, Map map, ObjectiveType type, Thing thing = null, Pawn pawn = null, PawnInfo pawnInfo = null)
        {
            PawnInfo info = pawnInfo != null ? pawnInfo : new PawnInfo(pawn);

            if (this.type == type)
            {
                if (targetSettings.thingSettings != null)
                {
                    if (thing.ThingIsValid(targetSettings.thingSettings))
                    {
                        int min = targetSettings.thingSettings.minAmount;
                        if ((type == ObjectiveType.Destroy || type == ObjectiveType.ConstructOrCraft) && count < min)
                        {
                            count++;
                        }
                        else if (!trackedThings.Contains(thing) && trackedThings.Count < min)
                        {
                            trackedThings.Add(thing);
                            LastTarget = thing;
                        }
                    }
                }
                if (targetSettings.pawnSettings != null)
                {
                    if (info != null)
                    {
                        if (targetSettings.pawnSettings.PawnSatisfies(info))
                        {
                            int min = targetSettings.pawnSettings.minAmount;
                            if (pawn != null && !trackedPawns.Contains(pawn) && trackedPawns.Count < min)
                            {
                                trackedPawns.Add(pawn);
                                LastTarget = pawn;
                            }
                            else if (count < min)
                            {
                                count++;
                            }
                        }
                    }
                }
                ThingValue tv = TargetsDone.ThingValue(t);
                if (tv != null && TargetsDone[tv] < tv.value && tv.ThingFits(thing))
                {
                    TargetsDone[tv] += 1;
                    LastTarget       = new TargetInfo(cell, map, true);
                }
            }
        }
 private Color ResolveColor(ThingValue thingValue)
 {
     if (thingValue.ResolvedStuff != null)
     {
         return(thingValue.ResolvedStuff.stuffProps.color);
     }
     if (thingValue.IsPawnKindDef)
     {
         PawnKindDef pdef = thingValue.PawnKindDef;
         if (pdef.lifeStages.Last().bodyGraphicData.color != Color.white)
         {
             return(thingValue.ThingDef.race.leatherDef.graphicData.color);
         }
     }
     return(Color.white);
 }
Exemple #9
0
        private Color ResolveColor(ThingValue thingValue)
        {
            if (thingValue.ResolvedStuff != null)
            {
                return(thingValue.ResolvedStuff.stuffProps.color);
            }
            if (thingValue.IsPawnKindDef && !thingValue.ThingDef.race.Humanlike)
            {
                PawnKindDef pdef = thingValue.PawnKindDef;

                if (!pdef.lifeStages.NullOrEmpty() && pdef.lifeStages.Last().bodyGraphicData.color is Color color && color != Color.white)
                {
                    return(color);
                }
                return(thingValue.ThingDef.race.leatherDef?.graphicData.color ?? Color.white);
            }
            return(Color.white);
        }
Exemple #10
0
        private void ResolveBarInputs(Objective objective, out float pct, out string label, out Texture2D material)
        {
            ObjectiveDef  def           = objective.def;
            StringBuilder stringBuilder = new StringBuilder();

            pct      = 0f;
            label    = "";
            material = null;
            float l  = 0,
                  r  = 0;
            bool any = def.targetSettings?.any ?? false;

            if (def.type == ObjectiveType.Travel)
            {
                TravelSettings settings = def.travelSettings;
                if (settings.mode == TravelMode.Explore || settings.mode == TravelMode.Reach)
                {
                    return;
                }
                pct   = (float)(l = objective.travelTracker.CurrentCount) / (float)(r = settings.factionSettings.ValueForMode(settings.mode));
                label = l + "/" + r;
            }
            if (def.targetSettings != null)
            {
                foreach (ThingValue thingValue in def.targetSettings.targets)
                {
                    stringBuilder.AppendLine("       " + (thingValue.IsPawnKindDef ? thingValue.PawnKindDef.LabelCap : thingValue.ThingDef.LabelCap));
                }
                if (def.type == ObjectiveType.Research)
                {
                    pct   = objective.GetWorkPct;
                    label = Mathf.RoundToInt(objective.GetWorkDone) + "/" + def.workAmount;
                }
                else
                if (def.type == ObjectiveType.ConstructOrCraft || def.type == ObjectiveType.Own || def.type == ObjectiveType.PawnCheck || def.type == ObjectiveType.Recruit || def.type == ObjectiveType.Destroy || def.type == ObjectiveType.Kill)
                {
                    if (def.targetSettings.pawnSettings != null)
                    {
                        if (objective.CurrentState == MOState.Finished)
                        {
                            pct = 1f;
                            l   = r = def.targetSettings.pawnSettings.minAmount;
                        }
                        else
                        {
                            pct = (l = (float)objective.thingTracker.GetTargetCount) / (r = (float)def.targetSettings.pawnSettings.minAmount);
                        }
                    }
                    else
                    if (def.targetSettings.thingSettings != null)
                    {
                        if (objective.CurrentState == MOState.Finished)
                        {
                            pct = 1f;
                            l   = r = def.targetSettings.thingSettings.minAmount;
                        }
                        else
                        {
                            pct = (l = (float)objective.thingTracker.GetTargetCount) / (r = (float)def.targetSettings.thingSettings.minAmount);
                        }
                    }
                    else
                    if (!objective.thingTracker.TargetsDone.ToList().NullOrEmpty())
                    {
                        ThingValue maxValue = objective.thingTracker.TargetsDone.ToList().Find(tv => tv.Value == objective.thingTracker.TargetsDone.Values.Max()).Key;
                        pct = any ? (l = (float)objective.thingTracker.TargetsDone[maxValue]) / (r = (float)def.targetSettings.targets.Find(tv => tv == maxValue).value) :
                              (l = (float)objective.thingTracker.GetTargetCount) / (r = (float)def.targetSettings.targets.Sum(tv => tv.value));
                    }
                    label = l + "/" + r;
                }
            }
            if (def.customSettings.progressBarColor != null)
            {
                material = SolidColorMaterials.NewSolidColorTexture(def.customSettings.progressBarColor.ToColor);
            }
            switch (def.type)
            {
            case ObjectiveType.Custom:
                material = StoryMats.grey;
                break;

            case ObjectiveType.Research:
                material = StoryMats.blue;
                break;

            case ObjectiveType.ConstructOrCraft:
                material = StoryMats.orange;
                break;

            case ObjectiveType.Destroy:
            case ObjectiveType.Kill:
                material = StoryMats.red;
                break;

            case ObjectiveType.PawnCheck:
            case ObjectiveType.Recruit:
            case ObjectiveType.Own:
                material = StoryMats.green;
                break;

            case ObjectiveType.Travel:
                material = StoryMats.purple;
                break;
            }
        }
Exemple #11
0
        public override void DoWindowContents(Rect inRect)
        {
            float CurrentY = 0f;

            //Title
            Text.Font = GameFont.Medium;
            string  Title     = objective.def.LabelCap;
            Vector2 TitleSize = Text.CalcSize(Title);
            Rect    TitleRect = new Rect(new Vector2(0f, CurrentY), TitleSize);

            Widgets.Label(TitleRect, Title);
            Text.Font = GameFont.Small;
            CurrentY += TitleRect.height;

            Rect MainInfoBody = new Rect(0f, CurrentY, inRect.width, inRect.height - CurrentY);

            Widgets.DrawMenuSection(MainInfoBody);
            Rect MainInfoSub = MainInfoBody.ContractedBy(5f);

            CurrentY = 0f;
            GUI.BeginGroup(MainInfoSub);

            float tenth  = MainInfoSub.width * 0.1f;
            float middle = tenth * 5f;
            //Objective Type - State - Work - Time
            string  TypeLabel     = "OType_SMO".Translate() + ": " + (objective.def.type.ToString() + "_Label").Translate();
            Vector2 TypeLabelSize = Text.CalcSize(TypeLabel);
            Rect    TypeLabelRect = new Rect(new Vector2(5f, CurrentY), TypeLabelSize);

            string  StateLabel     = "OState_SMO".Translate() + ": " + (objective.CurrentState.ToString() + "_SMO").Translate();
            Vector2 StateLabelSize = Text.CalcSize(StateLabel);
            Rect    StateLabelRect = new Rect(new Vector2(middle, CurrentY), StateLabelSize);

            CurrentY += StateLabelRect.height + 5f;

            bool    workExists     = objective.def.workAmount > 0;
            string  WorkAmount     = "WorkAmount_SMO".Translate() + ": " + (workExists ? Math.Round(objective.GetWorkDone, 0) + "/" + objective.def.workAmount : "N/A");
            Vector2 WorkAmountSize = Text.CalcSize(WorkAmount);
            string  TimerLabel     = "Timer_SMO".Translate() + ": " + StoryUtils.GetTimerText(objective.GetTimer, objective.CurrentState);
            Vector2 TimerLabelSize = Text.CalcSize(TimerLabel);
            Rect    WorkAmountRect = new Rect(new Vector2(5f, CurrentY), WorkAmountSize);
            Rect    TimerLabelRect = new Rect(new Vector2(middle, CurrentY), TimerLabelSize);

            CurrentY += WorkAmountRect.height;

            Rect TSWTRect = new Rect(0f, TypeLabelRect.yMin, MainInfoSub.width, TypeLabelRect.height + WorkAmountRect.height + 5f);

            Widgets.DrawBoxSolid(TSWTRect, new ColorInt(33, 33, 33).ToColor);
            Widgets.Label(TypeLabelRect, TypeLabel);
            Widgets.Label(StateLabelRect, StateLabel);
            Widgets.Label(WorkAmountRect, WorkAmount);
            Widgets.Label(TimerLabelRect, TimerLabel);
            AddGap(MainInfoSub, ref CurrentY);

            //TravelSettings
            TravelSettings travelSettings = objective.def.travelSettings;
            float          width          = MainInfoSub.width - 10f;

            if (travelSettings != null)
            {
                TravelMode    mode            = travelSettings.mode;
                string        ModeLabel       = (mode.ToString() + "Travel_SMO").Translate();
                float         ModeLabelHeight = Text.CalcHeight(ModeLabel, width);
                Rect          ModeLabelRect   = new Rect(5f, CurrentY, width, ModeLabelHeight);
                Rect          BoxRect         = new Rect();
                List <string> factions        = new List <string>();
                List <string> factionCounts   = new List <string>();

                if (!travelSettings.factionSettings.factions.NullOrEmpty())
                {
                    foreach (FactionDef def in travelSettings.factionSettings.factions)
                    {
                        string label = def.LabelCap;
                        factions.Add(label);
                    }
                    foreach (FactionDef def in travelSettings.factionSettings.factions)
                    {
                        string label = def.LabelCap;
                        factionCounts.Add(label + ": " + objective.travelTracker.CountFor(def) + "/" + travelSettings.factionSettings.Value(mode));
                    }
                }

                if (mode == TravelMode.Reach || mode == TravelMode.Explore)
                {
                    float height = 4f * 25f;
                    BoxRect = new Rect(0f, CurrentY, MainInfoSub.width, height);
                    Widgets.DrawBoxSolid(BoxRect, new ColorInt(33, 33, 33).ToColor);
                    CurrentY += ModeLabelHeight + 5f;
                    var listing = new Listing_Standard(GameFont.Small);
                    listing.Begin(new Rect(5f, CurrentY, MainInfoSub.width - 10f, height));
                    listing.ColumnWidth = (MainInfoSub.width - 10f) * 0.5f;
                    //left side
                    string Distance = "TravelDistance_SMO".Translate(travelSettings.minDistance);
                    listing.Label(Distance, Text.CalcHeight(Distance, listing.ColumnWidth));
                    string Biome = "TileBiome_SMO".Translate() + ": " + (travelSettings.tileSettings.biome?.LabelCap ?? "N/A");
                    listing.Label(Biome, Text.CalcHeight(Biome, listing.ColumnWidth));
                    string River = "TileA_SMO".Translate() + " " + (travelSettings.tileSettings.river?.label ?? "N/A");
                    listing.Label(River, Text.CalcHeight(River, listing.ColumnWidth));
                    //right side
                    listing.NewColumn();
                    string Destination = "TravelDestination_SMO".Translate() + ": " + (travelSettings.destination?.label ?? "N/A");
                    listing.Label(Destination, Text.CalcHeight(Destination, listing.ColumnWidth));
                    string Road = "TileA_SMO".Translate() + " " + travelSettings.tileSettings.road?.label;
                    listing.Label(Road, Text.CalcHeight(Road, listing.ColumnWidth));
                    string Hilliness = "Tile_SMO".Translate() + " " + (travelSettings.tileSettings.hilliness.HasValue ? travelSettings.tileSettings.hilliness.Value.GetLabel() : "N/A");
                    listing.Label(Hilliness, Text.CalcHeight(Hilliness, listing.ColumnWidth));
                    listing.End();
                    CurrentY += (height - 23f);
                    Widgets.Label(ModeLabelRect, ModeLabel);
                }
                else if (mode == TravelMode.Trade)
                {
                    CurrentY += ModeLabelHeight;
                    Rect   ValueLabelRect = new Rect();
                    string ValueLabel     = "";
                    int    silver         = travelSettings.minSilver;
                    if (silver != 0)
                    {
                        ValueLabel = silver > 0 ? "TradeBuy_SMO".Translate(silver) : "TradeSell_SMO".Translate(-silver);
                        Vector2 ValueLabelSize = Text.CalcSize(ValueLabel);
                        ValueLabelRect = new Rect(new Vector2(5f, CurrentY), ValueLabelSize);
                        CurrentY      += ValueLabelSize.y;
                    }
                    BoxRect = new Rect(0f, ModeLabelRect.yMin, MainInfoSub.width, ModeLabelHeight + ValueLabelRect.height);
                    Widgets.DrawBoxSolid(BoxRect, new ColorInt(33, 33, 33).ToColor);
                    Widgets.Label(ModeLabelRect, ModeLabel);
                    Widgets.Label(ValueLabelRect, ValueLabel);
                    TryMakeTextList(MainInfoSub, ref CurrentY, "", factionCounts, false);
                }
                else
                {
                    TryMakeTextList(MainInfoSub, ref CurrentY, ModeLabel, factionCounts, false);
                }
                AddGap(MainInfoSub, ref CurrentY);
            }
            //ThingSettings
            ThingSettings thingSettings = objective.def.targetSettings?.thingSettings;

            if (thingSettings != null)
            {
                string ThingSettingLabel       = ResolveThingSettings();
                float  ThingSettingLabelHeight = Text.CalcHeight(ThingSettingLabel, width);
                Rect   ThingSettingLabelRect   = new Rect(5f, CurrentY, width, ThingSettingLabelHeight);
                CurrentY += ThingSettingLabelRect.height;

                string  stuff          = thingSettings.stuff?.LabelCap ?? "AnyStuff_SMO".Translate();
                string  StuffLabel     = "ThingSettingsStuff_SMO".Translate(stuff);
                Vector2 StuffLabelSize = Text.CalcSize(StuffLabel);
                Rect    StuffLabelRect = new Rect(new Vector2(5f, CurrentY), StuffLabelSize);

                string  qual             = thingSettings.minQuality?.GetLabel() ?? "Any_SMO".Translate();
                string  QualityLabel     = "ThingSettingsQuality_SMO".Translate(qual);
                Vector2 QualityLabelSize = Text.CalcSize(QualityLabel);
                Rect    QualityLabelRect = new Rect(new Vector2(middle, CurrentY), QualityLabelSize);
                CurrentY += QualityLabelRect.height;

                int     num          = objective.thingTracker?.GetThingCount >= thingSettings.minAmount ? thingSettings.minAmount : objective.thingTracker.GetThingCount;
                string  NumLabel     = "MapCheckCount_SMO".Translate(num + "/" + thingSettings.minAmount);
                Vector2 NumLabelSize = Text.CalcSize(NumLabel);
                Rect    NumLabelRect = new Rect(new Vector2(5f, CurrentY), NumLabelSize);
                CurrentY += NumLabelRect.height;

                Rect TSRect = new Rect(0f, ThingSettingLabelRect.yMin, width + 10f, ThingSettingLabelHeight + QualityLabelSize.y + NumLabelSize.y);
                Widgets.DrawBoxSolid(TSRect, new ColorInt(33, 33, 33).ToColor);
                Widgets.Label(ThingSettingLabelRect, ThingSettingLabel);
                Widgets.Label(StuffLabelRect, StuffLabel);
                Widgets.Label(QualityLabelRect, QualityLabel);
                Widgets.Label(NumLabelRect, NumLabel);

                AddGap(MainInfoSub, ref CurrentY);
            }

            //PawnSettings
            PawnSettings pawnSettings = objective.def.targetSettings?.pawnSettings;

            if (pawnSettings != null)
            {
                bool   humanlike          = pawnSettings.def?.race.Humanlike ?? false;
                string PawnDefLabel       = ResolvePawnSettings();
                float  PawnDefLabelHeight = Text.CalcHeight(PawnDefLabel, width);
                Rect   PawnDefLabelRect   = new Rect(5f, CurrentY, width, PawnDefLabelHeight);
                CurrentY += PawnDefLabelHeight;

                string  PawnKindDefLabel     = "PawnSettingsKind_SMO".Translate(pawnSettings.kindDef?.LabelCap ?? "N/A");
                Vector2 PawnKindDefLabelSize = Text.CalcSize(PawnKindDefLabel);
                Rect    PawnKindDefLabelRect = new Rect(new Vector2(5f, CurrentY), PawnKindDefLabelSize);

                string  FactionLabel     = "PawnSettingsFaction_SMO".Translate(pawnSettings.factionDef?.LabelCap ?? "N/A");
                Vector2 FactionLabelSize = Text.CalcSize(FactionLabel);
                Rect    FactionLabelRect = new Rect(new Vector2(middle, CurrentY), FactionLabelSize);
                CurrentY += PawnKindDefLabelSize.y;

                string  GenderLabel     = "PawnSettingsGender_SMO".Translate(pawnSettings.gender?.GetLabel(!humanlike) ?? "N/A");
                Vector2 GenderLabelSize = Text.CalcSize(GenderLabel);
                Rect    GenderLabelRect = new Rect(new Vector2(5f, CurrentY), GenderLabelSize);

                int     num          = objective.thingTracker?.GetPawnCount >= pawnSettings.minAmount ? pawnSettings.minAmount : objective.thingTracker.GetPawnCount;
                string  NumLabel     = "MapCheckCount_SMO".Translate(num + "/" + pawnSettings.minAmount);
                Vector2 NumLabelSize = Text.CalcSize(NumLabel);
                Rect    NumLabelRect = new Rect(new Vector2(middle, CurrentY), NumLabelSize);
                CurrentY += GenderLabelSize.y;

                Rect PawnSettingRect = new Rect(0f, PawnDefLabelRect.yMin, width + 10f, PawnDefLabelHeight + PawnKindDefLabelSize.y + GenderLabelSize.y);
                Widgets.DrawBoxSolid(PawnSettingRect, new ColorInt(33, 33, 33).ToColor);
                Widgets.Label(PawnDefLabelRect, PawnDefLabel);
                Widgets.Label(PawnKindDefLabelRect, PawnKindDefLabel);
                Widgets.Label(FactionLabelRect, FactionLabel);
                Widgets.Label(GenderLabelRect, GenderLabel);
                Widgets.Label(NumLabelRect, NumLabel);

                AddGap(MainInfoSub, ref CurrentY);
            }

            //Stations
            if (NeedsStation)
            {
                List <string> stations = new List <string>();
                foreach (ThingValue tv in objective.def.targetSettings?.targets)
                {
                    stations.Add(tv.ThingDef.LabelCap);
                }
                TryMakeTextList(MainInfoSub, ref CurrentY, "Stations_SMO".Translate(objective.def.BestPotentialStation.LabelCap), stations, true);
            }
            if (!objective.def.skillRequirements.NullOrEmpty())
            {
                List <string> skills = new List <string>();
                foreach (SkillRequirement sr in objective.def.skillRequirements)
                {
                    skills.Add(sr.Summary);
                }
                TryMakeTextList(MainInfoSub, ref CurrentY, "SkillRequirementsInfo_SMO".Translate(), skills, true);
            }

            float RestHeight     = MainInfoBody.ContractedBy(5f).height - CurrentY;
            float ContainerSplit = NeedsStation ? RestHeight * 0.5f : RestHeight / 3f;

            //Targets
            if (objective.def.targetSettings != null && objective.def.targetSettings.targets.Count > 0 && !NeedsStation)
            {
                float  TotalHeight     = objective.def.targetSettings.targets.Count * 34f;
                float  ContainerHeight = TotalHeight > ContainerSplit ? ContainerSplit : TotalHeight;
                Rect   ContainerRect   = new Rect(0f, CurrentY, MainInfoSub.width, ContainerHeight);
                string TargetDesc      = ResolveTargetText();
                if (!TargetDesc.NullOrEmpty())
                {
                    float TargetDescHeight = Text.CalcHeight(TargetDesc, MainInfoSub.width - 5f);
                    Rect  BoxRect          = new Rect(0f, CurrentY, MainInfoSub.width, TargetDescHeight + 10f);
                    Rect  TargetDescRect   = BoxRect.ContractedBy(5f);
                    ContainerRect.y += BoxRect.height + 5f;
                    CurrentY        += BoxRect.height + 5f;
                    if (TotalHeight > ContainerSplit)
                    {
                        ContainerRect.height -= BoxRect.height + 5f;
                    }
                    Widgets.DrawBoxSolid(BoxRect, new ColorInt(33, 33, 33).ToColor);
                    Widgets.Label(TargetDescRect, TargetDesc);
                }
                StoryUtils.DrawMenuSectionColor(ContainerRect, 1, new ColorInt(40, 40, 40), StoryMats.defaultBorder);
                GUI.BeginGroup(ContainerRect.ContractedBy(1));
                Widgets.BeginScrollView(new Rect(0f, 0f, ContainerRect.width, ContainerRect.height), ref TargetPos, new Rect(0f, 0f, ContainerRect.width, TotalHeight), false);
                float             CurY    = 5f;
                List <ThingValue> targets = objective.def.targetSettings.targets;
                for (int i = 0; i < targets.Count; i++)
                {
                    ThingValue   thingValue = targets[i];
                    ThingTracker tracker    = objective.thingTracker;
                    if (i % 2 == 0)
                    {
                        GUI.color = new Color(1f, 1f, 1f, 0.5f);
                        Widgets.DrawHighlight(new Rect(0f, CurY - 5f, ContainerRect.width, 34f));
                        GUI.color = Color.white;
                    }
                    string    label    = tracker.WorksWithPawns ? thingValue.PawnKindDef.LabelCap : thingValue.ThingDef.LabelCap;
                    WidgetRow itemRow  = new WidgetRow(5f, CurY);
                    WidgetRow infoRect = new WidgetRow(ContainerRect.width * 0.5f, CurY);
                    itemRow.Gap(10f);
                    GUI.color = ResolveColor(thingValue);
                    if ((thingValue.IsPawnKindDef && !thingValue.ThingDef.race.Humanlike) || thingValue.ThingDef != null)
                    {
                        if (thingValue.ThingDef.uiIcon != BaseContent.BadTex)
                        {
                            itemRow.Icon(thingValue.ThingDef.uiIcon);
                        }
                    }
                    GUI.color = Color.white;
                    itemRow.Label(label);
                    if (tracker.TargetsDone.TryGetValue(thingValue, out int value))
                    {
                        infoRect.Label(value.ToString() + "/" + thingValue.value);
                    }
                    CurY += 34f;
                }
                CurrentY += ContainerRect.height;
                Widgets.EndScrollView();
                GUI.EndGroup();
            }

            //Rewards
            float RewardContainerHeight     = ContainerSplit - 46f;
            List <IncidentProperties> props = new List <IncidentProperties>(objective.def.incidentsOnCompletion);

            if (objective.def.result != null)
            {
                props.Add(objective.def.result);
            }
            if (!props.NullOrEmpty())
            {
                if (props.Any(p => p.type == IncidentType.Reward))
                {
                    if (!props.NullOrEmpty() && props.Any(p => !p?.spawnSettings?.spawnList.NullOrEmpty() ?? false))
                    {
                        float TotalHeight          = props.Sum(s => s.spawnSettings.spawnList.Count) * 34f;
                        float height               = TotalHeight > ContainerSplit ? ContainerSplit : TotalHeight;
                        Rect  CompletedRewardsRect = new Rect(0f, CurrentY, MainInfoSub.width, height);
                        CurrentY += CompletedRewardsRect.height;
                        DrawRewardContainer(CompletedRewardsRect, "CompletedRewards_SMO".Translate(), ref RewardCompletedPos, props);
                    }
                }
                props = objective.def.incidentsOnFail;
                if (props.Any(p => p.type == IncidentType.Reward))
                {
                    if (!props.NullOrEmpty() && props.Any(p => !p?.spawnSettings?.spawnList.NullOrEmpty() ?? false))
                    {
                        float total             = props.Sum(s => s.spawnSettings.spawnList.Count) * 34f;
                        float height            = total > ContainerSplit ? ContainerSplit : total;
                        Rect  FailedRewardsRect = new Rect(0f, CurrentY, MainInfoSub.width, height);
                        CurrentY += FailedRewardsRect.height;
                        DrawRewardContainer(FailedRewardsRect, "FailedRewards_SMO".Translate(), ref RewardFailedPos, props);
                    }
                }
            }
            GUI.EndGroup();
        }