private void DrawSeverityBar(ref float curY, ref Rect partListViewRect, MutationLayer layer, MutationDef mutationDef, List <Hediff_AddedMutation> mutationsOfDef)
        {
            // Draw the various labels for the severity bar (need to refine this later).
            string stageLabelText     = $"Stage {mutationsOfDef.FirstOrDefault().CurStageIndex}: {mutationsOfDef.FirstOrDefault().LabelCap}";
            Rect   severityLabelsRect = new Rect(partListViewRect.x, curY, partListViewRect.width, Text.CalcHeight(stageLabelText, partListViewRect.width));

            Text.Anchor = TextAnchor.MiddleLeft;
            Widgets.Label(severityLabelsRect, stageLabelText);
            Text.Anchor = TextAnchor.MiddleRight;
            Widgets.Label(severityLabelsRect, mutationsOfDef.FirstOrDefault().Severity.ToString("n2"));
            Text.Anchor = TextAnchor.UpperLeft;
            curY       += severityLabelsRect.height;

            // Draw the severity slider
            float curSeverity = mutationsOfDef.Select(n => n.Severity).Average();
            float newSeverity = Widgets.HorizontalSlider(new Rect(partListViewRect.x, curY, partListViewRect.width, SLIDER_HEIGHT), curSeverity, mutationDef.minSeverity, mutationDef.maxSeverity);

            if (curSeverity != newSeverity)
            {
                curSeverity = newSeverity;
                foreach (Hediff_AddedMutation mutationOfDef in mutationsOfDef)
                {
                    MutationData relevantEntry = addedMutations.MutationsByPartAndLayer(mutationOfDef.Part, layer);
                    if (relevantEntry != null)
                    {
                        relevantEntry.severity = newSeverity;
                    }
                    else
                    {
                        addedMutations.AddData(mutationOfDef.Def, mutationOfDef.Part, newSeverity, mutationOfDef.ProgressionHalted, false);
                    }
                    mutationOfDef.Severity = newSeverity;
                }
                recachePreview = true;
            }
            curY += SLIDER_HEIGHT;
        }
Example #2
0
        private void DrawPartButtons(ref float curY, Rect partListViewRect, List <Hediff_AddedMutation> mutations, List <BodyPartRecord> parts, MutationLayer layer, string label)
        {
            // Draw the main mutation selection button. It should take up the whole width if there are no mutations, otherwise it will leave a space for the edit button.
            float partButtonWidth = partListViewRect.width - (mutations.NullOrEmpty() ? 0 : editButtonWidth);
            Rect  partButtonRect  = new Rect(partListViewRect.x, curY, partButtonWidth, Text.CalcHeight(label, partButtonWidth - BUTTON_HORIZONTAL_PADDING));

            if (Widgets.ButtonText(partButtonRect, label))
            {
                List <FloatMenuOption> options = new List <FloatMenuOption>();
                void removeMutations()
                {
                    foreach (Hediff_AddedMutation mutation in mutations)
                    {
                        addedMutations.RemoveByPartAndLayer(mutation.Part, layer);
                        if (cachedInitialHediffs.Select(m => m.hediff).Contains(mutation))
                        {
                            addedMutations.AddData(mutation.Def, mutation.Part, mutation.Severity, mutation.ProgressionHalted, true);
                        }
                        pawn.health.RemoveHediff(mutation);
                    }
                    recachePreview = true;
                    RecachePawnMutations();
                }

                options.Add(new FloatMenuOption(NO_MUTATIONS_LOC_STRING.Translate(), removeMutations));


                List <MutationDef> mutationDefs = cachedMutationDefsByPartDef[parts.FirstOrDefault().def];
                foreach (MutationDef mutationDef in mutationDefs.Where(m => m.RemoveComp.layer == layer && (DebugSettings.godMode || m.IsTagged())))
                {
                    void addMutation()
                    {
                        foreach (Hediff_AddedMutation mutation in mutations)
                        {
                            pawn.health.RemoveHediff(mutation);
                        }
                        foreach (BodyPartRecord part in parts)
                        {
                            addedMutations.RemoveByPartAndLayer(part, layer);
                            addedMutations.AddData(mutationDef, part, mutationDef.initialSeverity, false, false);
                            MutationUtilities.AddMutation(pawn, mutationDef, part, ancillaryEffects: MutationUtilities.AncillaryMutationEffects.None); //don't give the green puffs
                        }
                        recachePreview = true;
                        RecachePawnMutations();
                    }

                    options.Add(new FloatMenuOption(mutationDef.LabelCap, addMutation));
                }
                Find.WindowStack.Add(new FloatMenu(options));
            }
            curY += partButtonRect.height;

            // If there are actually mutations, draw the edit button.
            if (!mutations.NullOrEmpty())
            {
                Rect editButtonRect = new Rect(partButtonWidth, partButtonRect.y, editButtonWidth, partButtonRect.height);
                if (Widgets.ButtonText(editButtonRect, editButtonText))
                {
                    detailPart = (detailPart.Item1 == parts.FirstOrDefault() && detailPart.Item2 == layer) ? new Tuple <BodyPartRecord, MutationLayer>(new BodyPartRecord(), 0) : new Tuple <BodyPartRecord, MutationLayer>(parts.FirstOrDefault(), layer);
                }
            }

            // If the currently selected part and layer match up with the part to give details for, draw the edit area below the buttons.
            if (detailPart.Item1 == parts.FirstOrDefault() && detailPart.Item2 == layer)
            {
                foreach (MutationDef mutationDef in mutations.Select(m => m.Def).Distinct())
                {
                    List <Hediff_AddedMutation> mutationsOfDef = mutations.Where(m => m.Def == mutationDef).ToList();

                    // Draw the LabelCap of the current Def if there is more than one type of mutation in the current list.
                    if (mutations.Select(m => m.Def).Distinct().Count() > 1)
                    {
                        Widgets.ListSeparator(ref curY, partListViewRect.width, mutationDef.LabelCap);
                    }

                    // Draw the various labels for the severity bar (need to refine this later).
                    string stageLabelText     = $"Stage {mutationsOfDef.FirstOrDefault().CurStageIndex}: {mutationsOfDef.FirstOrDefault().LabelCap}";
                    Rect   severityLabelsRect = new Rect(partListViewRect.x, curY, partListViewRect.width, Text.CalcHeight(stageLabelText, partListViewRect.width));
                    Text.Anchor = TextAnchor.MiddleLeft;
                    Widgets.Label(severityLabelsRect, stageLabelText);
                    Text.Anchor = TextAnchor.MiddleRight;
                    Widgets.Label(severityLabelsRect, mutationsOfDef.FirstOrDefault().Severity.ToString("n2"));
                    Text.Anchor = TextAnchor.UpperLeft;
                    curY       += severityLabelsRect.height;

                    // Draw the severity slider
                    float curSeverity = mutationsOfDef.Select(n => n.Severity).Average();
                    float newSeverity = Widgets.HorizontalSlider(new Rect(partListViewRect.x, curY, partListViewRect.width, SLIDER_HEIGHT), curSeverity, mutationDef.minSeverity, mutationDef.maxSeverity);
                    if (curSeverity != newSeverity)
                    {
                        curSeverity = newSeverity;
                        foreach (Hediff_AddedMutation mutationOfDef in mutationsOfDef)
                        {
                            MutationData relevantEntry = addedMutations.MutationsByPartAndLayer(mutationOfDef.Part, layer);
                            if (relevantEntry != null)
                            {
                                relevantEntry.severity = newSeverity;
                            }
                            else
                            {
                                addedMutations.AddData(mutationOfDef.Def, mutationOfDef.Part, newSeverity, mutationOfDef.ProgressionHalted, false);
                            }
                            mutationOfDef.Severity = newSeverity;
                        }
                        recachePreview = true;
                    }
                    curY += SLIDER_HEIGHT;

                    // If the mutation has the ability to be paused, show the toggle for it.
                    // This is a CheckboxMulti to handle edge cases, but likely could be replaced with a simple Checkbox.
                    if (mutationDef.CompProps <CompProperties_MutationSeverityAdjust>() != null)
                    {
                        float pauseLabelWidth           = partListViewRect.width - IS_PAUSED_CHECKBOX_SIZE.x;
                        Rect  pauseLabelRect            = new Rect(partListViewRect.x, curY, pauseLabelWidth, Text.CalcHeight(IS_PAUSED_LOC_STRING.Translate(), partListViewRect.width));
                        Rect  checkBoxRect              = new Rect(partListViewRect.x + pauseLabelWidth, curY, IS_PAUSED_CHECKBOX_SIZE.x, IS_PAUSED_CHECKBOX_SIZE.y);
                        MultiCheckboxState initialState = !mutationsOfDef.Select(n => n.ProgressionHalted).Contains(true) ? MultiCheckboxState.Off : !mutationsOfDef.Select(n => n.ProgressionHalted).Contains(false) ? MultiCheckboxState.On : MultiCheckboxState.Partial;
                        Widgets.Label(pauseLabelRect, IS_PAUSED_LOC_STRING.Translate());
                        MultiCheckboxState newState = Widgets.CheckboxMulti(checkBoxRect, initialState);
                        if (initialState != newState)
                        {
                            initialState = newState;
                            mutationsOfDef.FirstOrDefault().SeverityAdjust.Halted = !mutationsOfDef.FirstOrDefault().SeverityAdjust.Halted;
                            foreach (Hediff_AddedMutation mutationOfDef in mutationsOfDef)
                            {
                                MutationData relevantEntry = addedMutations.MutationsByPartAndLayer(mutationOfDef.Part, layer);
                                if (cachedInitialHediffs.Select(m => m.hediff).Contains(mutationOfDef))
                                {
                                    bool initialHediffIsHalted = cachedInitialHediffs.Where(m => m.hediff == mutationOfDef).FirstOrDefault().isHalted;
                                    if (newState == MultiCheckboxState.On == initialHediffIsHalted)
                                    {
                                        addedMutations.RemoveByPartAndLayer(mutationOfDef.Part, layer);
                                    }
                                }
                                if (relevantEntry != null)
                                {
                                    relevantEntry.isHalted = newState == MultiCheckboxState.On;
                                }
                                else
                                {
                                    addedMutations.AddData(mutationOfDef.Def, mutationOfDef.Part, mutationOfDef.Severity, newState == MultiCheckboxState.On, false);
                                }
                            }
                        }
                        curY += Math.Max(pauseLabelRect.height, checkBoxRect.height);
                    }
                }
            }

            // Create a zone for updating the lower description box (The one that shows details based on the currently hovered over mutation).
            Rect descriptionUpdateRect = new Rect(partListViewRect.x, partButtonRect.y, partListViewRect.width, curY - partButtonRect.y);

            if (Mouse.IsOver(descriptionUpdateRect))
            {
                foreach (MutationDef mutation in mutations.Select(m => m.def).Distinct())
                {
                    Hediff_AddedMutation firstMutationOfDef = mutations.Where(m => m.def == mutation).FirstOrDefault();
                    partDescBuilder.AppendLine(firstMutationOfDef.LabelCap);
                    partDescBuilder.AppendLine(firstMutationOfDef.Description);
                    partDescBuilder.AppendLine(firstMutationOfDef.TipStringExtra);
                    partDescBuilder.AppendLine();
                }
            }
        }