예제 #1
0
        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;
        }
예제 #2
0
 IReadOnlyMutationData IReadOnlyAddedMutations.MutationsByPartAndLayer(BodyPartRecord part, MutationLayer layer)
 {
     return(MutationsByPartAndLayer(part, layer));
 }
예제 #3
0
 /// <summary>
 /// Finds and returns the first entry whose part and layer matches the provided part and layer.
 /// </summary>
 /// <param name="part">The part to match.</param>
 /// <param name="layer">The mutation layer to match.</param>
 /// <returns>The first entry whose part and layer matches the provied part and layer.</returns>
 public MutationData MutationsByPartAndLayer(BodyPartRecord part, MutationLayer layer)
 {
     return(mutationData.Where(m => m.part == part).FirstOrDefault());
 }
예제 #4
0
 /// <summary>
 /// Removes the first entry in the mutation data list whose part and layer matches the one provided.
 /// </summary>
 /// <param name="part">The body part record to filter out of the mutation data.</param>
 /// <param name="layer">The mutation layer to filter out of the mutation data.</param>
 public void RemoveByPartAndLayer(BodyPartRecord part, MutationLayer layer)
 {
     mutationData.Remove(mutationData.Where(m => m.part == part && m.mutation.RemoveComp.layer == layer).FirstOrDefault());
     //mutationData = mutationData.Where(m => m.part != part && m.mutation.RemoveComp.layer != layer).ToList();
 }
예제 #5
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();
                }
            }
        }
예제 #6
0
        private void DrawPartEntrySkinSyncMode(string label, List <BodyPartRecord> parts, ref float curPos, Rect rect, MutationLayer layer)
        {
            Rect labelRect = new Rect(rect.x, curPos, rect.width, Text.CalcHeight(label, rect.width));

            Widgets.Label(labelRect, label);
            curPos += labelRect.height;

            List <Hediff_AddedMutation> mutations = pawn.health.hediffSet.hediffs
                                                    .Where(m => m.def.GetType() == typeof(MutationDef))
                                                    .Cast <Hediff_AddedMutation>()
                                                    .Where(m => parts.Contains(m.Part) && m.TryGetComp <RemoveFromPartComp>().Layer == layer)
                                                    .ToList();

            string partButtonText = $"{(mutations.NullOrEmpty() ? NO_MUTATIONS_LOC_STRING.Translate().ToString() : string.Join(", ", mutations.Select(m => m.LabelCap).Distinct()))}";
            string editButtonText = EDIT_PARAMS_LOC_STRING.Translate();

            float editButtonWidth  = Text.CalcSize(editButtonText).x + BUTTON_HORIZONTAL_PADDING;
            float partButtonWidth  = rect.width - editButtonWidth;
            float partButtonHeight = Text.CalcHeight(partButtonText, partButtonWidth - BUTTON_HORIZONTAL_PADDING);

            Rect partButtonRect = new Rect(rect.x, curPos, partButtonWidth, partButtonHeight);
            Rect editButtonRect = new Rect(partButtonWidth, curPos, editButtonWidth, partButtonHeight);
            Rect descUpdateRect = new Rect(rect.x, curPos, rect.width, partButtonHeight);

            if (Widgets.ButtonText(partButtonRect, partButtonText))
            {
                List <FloatMenuOption> options = new List <FloatMenuOption>();
                void removeMutations()
                {
                    foreach (Hediff_AddedMutation mutation in mutations)
                    {
                        pawn.health.RemoveHediff(mutation);
                    }
                    recachePreview = true;
                }

                options.Add(new FloatMenuOption(NO_MUTATIONS_LOC_STRING.Translate(), removeMutations));
                foreach (MutationDef mutationDef in cachedMutationDefsByPart[parts.First().def].Where(m => m.CompProps <RemoveFromPartCompProperties>().layer == layer))
                {
                    void addMutation()
                    {
                        removeMutations();
                        foreach (BodyPartRecord part in parts)
                        {
                            MutationUtilities.AddMutation(pawn, mutationDef, part);
                        }
                    }

                    options.Add(new FloatMenuOption(mutationDef.LabelCap, addMutation));
                }
                Find.WindowStack.Add(new FloatMenu(options));
            }

            if (Widgets.ButtonText(editButtonRect, editButtonText))
            {
                // Pop open window to modify current stage, severity, halted status, etc.
            }

            if (Mouse.IsOver(descUpdateRect))
            {
                foreach (MutationDef mutation in mutations.Select(m => m.Def).Distinct().ToList())
                {
                    partDescBuilder.AppendLine($"{mutation.LabelCap}");
                    partDescBuilder.AppendLine($"{mutation.description}");
                    partDescBuilder.AppendLine();
                }
            }

            curPos += partButtonHeight;
        }
예제 #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MutationSite"/> struct.
 /// </summary>
 /// <param name="record">The record.</param>
 /// <param name="layer">The layer.</param>
 public MutationSite(BodyPartRecord record, MutationLayer layer)
 {
     Record = record;
     Layer  = layer;
 }