private void AsyncCalculateBreedingScoresAndDisplayPairs(BreedingMode breedingMode, bool updateBreedingData = false)
        {
            SuspendLayout();
            this.SuspendDrawing();
            Cursor.Current = Cursors.WaitCursor;
            ClearControls();

            // chosen Creature (only consider this one for its sex)
            bool considerChosenCreature = chosenCreature != null;

            // filter by tags
            int             crCountF = females.Count;
            int             crCountM = males.Count;
            List <Creature> chosenF, chosenM;

            if (considerChosenCreature && chosenCreature.sex == Sex.Female)
            {
                chosenF = new List <Creature>();
            }
            else
            {
                chosenF = FilterByTags(females);
            }
            if (considerChosenCreature && chosenCreature.sex == Sex.Male)
            {
                chosenM = new List <Creature>();
            }
            else
            {
                chosenM = FilterByTags(males);
            }

            // filter by servers
            if (cbServerFilterLibrary.Checked)
            {
                chosenF = chosenF.Where(c => (c.server == "" && !creatureCollection.hiddenServers.Contains("n/a")) ||
                                        (c.server != "" && !creatureCollection.hiddenServers.Contains(c.server))).ToList();
                chosenM = chosenM.Where(c => (c.server == "" && !creatureCollection.hiddenServers.Contains("n/a")) ||
                                        (c.server != "" && !creatureCollection.hiddenServers.Contains(c.server))).ToList();
            }
            // filter by owner
            if (cbOwnerFilterLibrary.Checked)
            {
                chosenF = chosenF.Where(c => (c.owner == "" && !creatureCollection.hiddenOwners.Contains("n/a")) ||
                                        (c.owner != "" && !creatureCollection.hiddenOwners.Contains(c.owner))).ToList();
                chosenM = chosenM.Where(c => (c.owner == "" && !creatureCollection.hiddenOwners.Contains("n/a")) ||
                                        (c.owner != "" && !creatureCollection.hiddenOwners.Contains(c.owner))).ToList();
            }

            bool creaturesTagFilteredOut = (crCountF != chosenF.Count) ||
                                           (crCountM != chosenM.Count);

            crCountF = chosenF.Count;
            crCountM = chosenM.Count;
            if (nudBPMutationLimit.Value >= 0)
            {
                chosenF = chosenF.Where(c => c.Mutations <= nudBPMutationLimit.Value).ToList();
                chosenM = chosenM.Where(c => c.Mutations <= nudBPMutationLimit.Value).ToList();
            }
            bool creaturesMutationsFilteredOut = (crCountF != chosenF.Count) ||
                                                 (crCountM != chosenM.Count);

            if (considerChosenCreature)
            {
                if (chosenCreature.sex == Sex.Female)
                {
                    chosenF.Add(chosenCreature);
                }
                if (chosenCreature.sex == Sex.Male)
                {
                    chosenM.Add(chosenCreature);
                }
            }

            lbBreedingPlanHeader.Text = currentSpecies.DescriptiveNameAndMod + (considerChosenCreature ? " (" + string.Format(Loc.s("onlyPairingsWith"), chosenCreature.name) + ")" : "");
            if (considerChosenCreature && (chosenCreature.flags.HasFlag(CreatureFlags.Neutered) || chosenCreature.status != CreatureStatus.Available))
            {
                lbBreedingPlanHeader.Text += $"{Loc.s("BreedingNotPossible")} ! ({(chosenCreature.flags.HasFlag(CreatureFlags.Neutered) ? Loc.s("Neutered") : Loc.s("notAvailable"))})";
            }

            string warningText = "";

            if (creaturesTagFilteredOut)
            {
                warningText = Loc.s("BPsomeCreaturesAreFilteredOutTags");
            }
            if (creaturesMutationsFilteredOut)
            {
                warningText += (warningText.Length > 0 ? " " + Loc.s("BPorMutations") : Loc.s("BPsomeCreaturesAreFilteredOutMutations"));
            }
            if (warningText.Length > 0)
            {
                SetMessageLabelText(warningText + ".\n" + Loc.s("BPTopStatsShownMightNotTotalTopStats"), MessageBoxIcon.Warning);
            }

            var combinedCreatures = new List <Creature>(chosenF);

            combinedCreatures.AddRange(chosenM);
            // determine top-stats for choosen creatures.
            int[] topStats = new int[Values.STATS_COUNT];
            foreach (Creature c in combinedCreatures)
            {
                for (int s = 0; s < Values.STATS_COUNT; s++)
                {
                    if (topStats[s] < c.levelsWild[s])
                    {
                        topStats[s] = c.levelsWild[s];
                    }
                }
            }

            if (Properties.Settings.Default.IgnoreSexInBreedingPlan)
            {
                chosenF = new List <Creature>(combinedCreatures);
                chosenM = new List <Creature>(combinedCreatures);
            }

            if (chosenF.Count > 0 && chosenM.Count > 0)
            {
                pedigreeCreature1.Show();
                pedigreeCreature2.Show();
                lbBPBreedingScore.Show();

                breedingPairs.Clear();
                short[] bestPossLevels = new short[Values.STATS_COUNT]; // best possible levels

                foreach (Creature female in chosenF)
                {
                    foreach (Creature male in chosenM)
                    {
                        if (male == female || // happens if Properties.Settings.Default.IgnoreSexInBreedingPlan (when using S+ mutator)
                            (nudBPMutationLimit.Value >= 0 && female.Mutations > nudBPMutationLimit.Value && male.Mutations > nudBPMutationLimit.Value)    // if one pair is below the limit, show this pair
                            )
                        {
                            continue;
                        }
                        double t    = 0;
                        int    nrTS = 0;
                        double eTS  = 0;

                        int topfemale = 0;
                        int topmale   = 0;

                        for (int s = 0; s < Values.STATS_COUNT; s++)
                        {
                            if (s == (int)StatNames.Torpidity)
                            {
                                continue;
                            }
                            bestPossLevels[s] = 0;
                            int higherLevel = Math.Max(female.levelsWild[s], male.levelsWild[s]);
                            int lowerlevel  = Math.Min(female.levelsWild[s], male.levelsWild[s]);
                            if (higherLevel < 0)
                            {
                                higherLevel = 0;
                            }
                            if (lowerlevel < 0)
                            {
                                lowerlevel = 0;
                            }

                            double tt = statWeights[s] * (probabilityHigherLevel * higherLevel + probabilityLowerLevel * lowerlevel) / 40;
                            if (tt > 0)
                            {
                                if (breedingMode == BreedingMode.TopStatsLucky)
                                {
                                    if (female.levelsWild[s] == topStats[s] || male.levelsWild[s] == topStats[s])
                                    {
                                        if (female.levelsWild[s] == topStats[s] && male.levelsWild[s] == topStats[s])
                                        {
                                            tt *= 1.142;
                                        }
                                    }
                                    else if (bestLevels[s] > 0)
                                    {
                                        tt *= .01;
                                    }
                                }
                                else if (breedingMode == BreedingMode.TopStatsConservative && bestLevels[s] > 0)
                                {
                                    bestPossLevels[s] = (short)Math.Max(female.levelsWild[s], male.levelsWild[s]);
                                    tt *= .01;
                                    if (female.levelsWild[s] == topStats[s] || male.levelsWild[s] == topStats[s])
                                    {
                                        nrTS++;
                                        eTS += female.levelsWild[s] == topStats[s] && male.levelsWild[s] == topStats[s] ? 1 : probabilityHigherLevel;
                                        if (female.levelsWild[s] == topStats[s])
                                        {
                                            topfemale++;
                                        }
                                        if (male.levelsWild[s] == topStats[s])
                                        {
                                            topmale++;
                                        }
                                    }
                                }
                            }
                            t += tt;
                        }

                        if (breedingMode == BreedingMode.TopStatsConservative)
                        {
                            if (topfemale < nrTS && topmale < nrTS)
                            {
                                t += eTS;
                            }
                            else
                            {
                                t += .1 * eTS;
                            }
                            // check if the best possible stat outcome already exists in a male
                            bool maleExists = false;

                            foreach (Creature cr in chosenM)
                            {
                                maleExists = true;
                                for (int s = 0; s < Values.STATS_COUNT; s++)
                                {
                                    if (s == (int)StatNames.Torpidity || cr.valuesDom[s] == 0)
                                    {
                                        continue;                                                        // TODO check if stat is used with cr.species.statsUsed[s]
                                    }
                                    if (cr.levelsWild[s] != bestPossLevels[s])
                                    {
                                        maleExists = false;
                                        break;
                                    }
                                }
                                if (maleExists)
                                {
                                    break;
                                }
                            }
                            if (maleExists)
                            {
                                t *= .4; // another male with the same stats is not worth much, the mating-cooldown of males is short.
                            }
                            else
                            {
                                // check if the best possible stat outcome already exists in a female
                                bool femaleExists = false;
                                foreach (Creature cr in chosenF)
                                {
                                    femaleExists = true;
                                    for (int s = 0; s < Values.STATS_COUNT; s++)
                                    {
                                        if (s == (int)StatNames.Torpidity || cr.valuesDom[s] == 0)
                                        {
                                            continue;                                                        // TODO check if stat is used with cr.species.statsUsed[s]
                                        }
                                        if (cr.levelsWild[s] != bestPossLevels[s])
                                        {
                                            femaleExists = false;
                                            break;
                                        }
                                    }
                                    if (femaleExists)
                                    {
                                        break;
                                    }
                                }
                                if (femaleExists)
                                {
                                    t *= .8; // another female with the same stats may be useful, but not so much in conservative breeding
                                }
                            }
                            //t *= 2; // scale conservative mode as it rather displays improvement, but only scarcely
                        }

                        breedingPairs.Add(new BreedingPair(female, male, t * 1.25));
                    }
                }

                breedingPairs = breedingPairs.OrderByDescending(p => p.BreedingScore).ToList();
                double minScore = (breedingPairs.Count > 0 ? breedingPairs[breedingPairs.Count - 1].BreedingScore : 0);
                if (minScore < 0)
                {
                    foreach (BreedingPair bp in breedingPairs)
                    {
                        bp.BreedingScore -= minScore;
                    }
                }

                // draw best parents
                int row = 0;
                // scrolloffsets
                int xS = AutoScrollPosition.X;
                int yS = AutoScrollPosition.Y;

                for (int i = 0; i < breedingPairs.Count && i < creatureCollection.maxBreedingSuggestions; i++)
                {
                    PedigreeCreature pc;
                    if (2 * i < pcs.Count)
                    {
                        pcs[2 * i].Creature            = breedingPairs[i].Female;
                        pcs[2 * i].enabledColorRegions = enabledColorRegions;
                        pcs[2 * i].comboId             = i;
                        pcs[2 * i].Show();
                    }
                    else
                    {
                        pc = new PedigreeCreature(breedingPairs[i].Female, enabledColorRegions, i);
                        //pc.Location = new Point(10 + xS, 5 + 35 * row + yS);
                        pc.CreatureClicked      += CreatureClicked;
                        pc.CreatureEdit         += CreatureEdit;
                        pc.BPRecalc             += RecalculateBreedingPlan;
                        pc.BestBreedingPartners += BestBreedingPartners;
                        pc.exportToClipboard    += ExportToClipboard;
                        flowLayoutPanelPairs.Controls.Add(pc);
                        pcs.Add(pc);
                    }

                    // draw score
                    PictureBox pb;
                    if (i < pbs.Count)
                    {
                        pb = pbs[i];
                        pbs[i].Show();
                    }
                    else
                    {
                        pb = new PictureBox
                        {
                            Size = new Size(87, 35)
                        };
                        //pb.Location = new Point(308 + xS, 19 + 35 * row + yS);
                        pbs.Add(pb);
                        flowLayoutPanelPairs.Controls.Add(pb);
                    }

                    if (2 * i + 1 < pcs.Count)
                    {
                        pcs[2 * i + 1].Creature            = breedingPairs[i].Male;
                        pcs[2 * i + 1].enabledColorRegions = enabledColorRegions;
                        pcs[2 * i + 1].comboId             = i;
                        pcs[2 * i + 1].Show();
                    }
                    else
                    {
                        pc = new PedigreeCreature(breedingPairs[i].Male, enabledColorRegions, i);
                        //pc.Location = new Point(397 + xS, 5 + 35 * row + yS);
                        pc.CreatureClicked      += CreatureClicked;
                        pc.CreatureEdit         += CreatureEdit;
                        pc.BPRecalc             += RecalculateBreedingPlan;
                        pc.BestBreedingPartners += BestBreedingPartners;
                        pc.exportToClipboard    += ExportToClipboard;
                        flowLayoutPanelPairs.Controls.Add(pc);
                        flowLayoutPanelPairs.SetFlowBreak(pc, true);
                        pcs.Add(pc);
                    }

                    Bitmap   bm = new Bitmap(pb.Width, pb.Height);
                    Graphics g;
                    using (g = Graphics.FromImage(bm))
                    {
                        g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
                        Brush br  = new SolidBrush(Utils.getColorFromPercent((int)(breedingPairs[i].BreedingScore * 12.5), 0.5));
                        Brush brd = new SolidBrush(Utils.getColorFromPercent((int)(breedingPairs[i].BreedingScore * 12.5), -.2));
                        g.FillRectangle(brd, 0, 15, 87, 5);
                        g.FillRectangle(brd, 20, 10, 47, 15);
                        g.FillRectangle(br, 1, 16, 85, 3);
                        g.FillRectangle(br, 21, 11, 45, 13);
                        g.DrawString(breedingPairs[i].BreedingScore.ToString("N4"), new Font("Microsoft Sans Serif", 8.25f), new SolidBrush(Color.Black), 24, 12);
                        pb.Image = bm;
                    }

                    row++;
                }
                // hide unused controls
                for (int i = breedingPairs.Count; i < creatureCollection.maxBreedingSuggestions && 2 * i + 1 < pcs.Count && i < pbs.Count; i++)
                {
                    pcs[2 * i].Hide();
                    pcs[2 * i + 1].Hide();
                    pbs[i].Hide();
                }

                if (updateBreedingData)
                {
                    SetBreedingData(currentSpecies);
                }
                if (breedingPairs.Count > 0)
                {
                    SetParents(0);

                    // if breeding mode is conservative and a creature with top-stats already exists, the scoring might seem off
                    if (breedingMode == BreedingMode.TopStatsConservative)
                    {
                        bool            bestCreatureAlreadyAvailable = true;
                        Creature        bestCreature           = null;
                        List <Creature> choosenFemalesAndMales = chosenF.Concat(chosenM).ToList();
                        foreach (Creature cr in choosenFemalesAndMales)
                        {
                            bestCreatureAlreadyAvailable = true;
                            for (int s = 0; s < Values.STATS_COUNT; s++)
                            {
                                // if the stat is not a top stat and the stat is leveled in wild creatures
                                if (!cr.topBreedingStats[s] && cr.Species.stats[s].IncPerWildLevel != 0)
                                {
                                    bestCreatureAlreadyAvailable = false;
                                    break;
                                }
                            }
                            if (bestCreatureAlreadyAvailable)
                            {
                                bestCreature = cr;
                                break;
                            }
                        }

                        if (bestCreatureAlreadyAvailable)
                        {
                            SetMessageLabelText(string.Format(Loc.s("AlreadyCreatureWithTopStats"), bestCreature.name, Utils.sexSymbol(bestCreature.sex)), MessageBoxIcon.Warning);
                        }
                    }
                }
                else
                {
                    SetParents(-1);
                }
            }
            else
            {
                // hide unused controls
                pedigreeCreature1.Hide();
                pedigreeCreature2.Hide();
                lbBPBreedingScore.Hide();
                for (int i = 0; i < creatureCollection.maxBreedingSuggestions && 2 * i + 1 < pcs.Count && i < pbs.Count; i++)
                {
                    pcs[2 * i].Hide();
                    pcs[2 * i + 1].Hide();
                    pbs[i].Hide();
                }
                lbBreedingPlanInfo.Text    = string.Format(Loc.s("NoPossiblePairingForSpeciesFound"), currentSpecies);
                lbBreedingPlanInfo.Visible = true;
                if (updateBreedingData)
                {
                    SetBreedingData(currentSpecies);
                }
            }
            Cursor.Current = Cursors.Default;
            this.ResumeDrawing();

            if (considerChosenCreature)
            {
                btShowAllCreatures.Text = "Unset Restriction to " + chosenCreature.name;
            }
            btShowAllCreatures.Visible = considerChosenCreature;
            ResumeLayout();
        }
        /// <summary>
        /// call this function to create the pedigreeCreature-Elements
        /// </summary>
        public void createPedigree()
        {
            // clear old pedigreeCreatures
            ClearControls();
            if (creature != null)
            {
                SuspendLayout();

                bool isGlowSpecies = Values.V.IsGlowSpecies(creature.Species?.name);
                pedigreeCreature1.IsGlowSpecies = isGlowSpecies;

                int leftBorder           = 40;
                int pedigreeElementWidth = 325;
                int margin = 10;

                lbPedigreeEmpty.Visible = false;

                // create ancestors
                createParentsChild(creature, leftBorder + pedigreeElementWidth + margin, 60, true, true);
                if (creature.Mother != null)
                {
                    if (createParentsChild(creature.Mother, leftBorder, 20))
                    {
                        lines[1].Add(new[] { leftBorder + pedigreeElementWidth, 79, leftBorder + pedigreeElementWidth + margin, 79 });
                    }
                }
                if (creature.Father != null)
                {
                    if (createParentsChild(creature.Father, leftBorder + 2 * (pedigreeElementWidth + margin), 20))
                    {
                        lines[1].Add(new[] { leftBorder + 2 * pedigreeElementWidth + 2 * margin, 79, leftBorder + 2 * pedigreeElementWidth + margin, 159 });
                    }
                }

                // create descendants
                int row = 0;
                // scrolloffsets
                int xS = AutoScrollPosition.X;
                int yS = AutoScrollPosition.Y;
                foreach (Creature c in children)
                {
                    PedigreeCreature pc = new PedigreeCreature(c, enabledColorRegions)
                    {
                        Location = new Point(leftBorder + xS, 200 + 35 * row + yS)
                    };
                    for (int s = 0; s < PedigreeCreature.displayedStats.Length; s++)
                    {
                        int si = PedigreeCreature.displayedStats[s];
                        if (creature.valuesDom[si] > 0 && creature.levelsWild[si] >= 0 && creature.levelsWild[si] == c.levelsWild[si])
                        {
                            lines[0].Add(new[] { leftBorder + 38 + 29 * s, 200 + 35 * row + 6, leftBorder + 38 + 29 * s, 200 + 35 * row + 15, 0, 0 });
                        }
                    }
                    pc.CreatureClicked      += CreatureClicked;
                    pc.CreatureEdit         += CreatureEdit;
                    pc.BestBreedingPartners += BestBreedingPartners;
                    pc.exportToClipboard    += exportToClipboard;
                    splitContainer1.Panel2.Controls.Add(pc);
                    pcs.Add(pc);
                    row++;
                }

                pictureBox.Image = CreatureColored.getColoredCreature(creature.colors, creature.Species, enabledColorRegions, 256);

                Invalidate();
                ResumeLayout();
            }
            else
            {
                noCreatureSelected();
            }
        }
 private bool createParentsChild(Creature creature, int x, int y, bool drawWithNoParents = false, bool highlightCreature = false)
 {
     if (creature != null && (drawWithNoParents || creature.Mother != null || creature.Father != null))
     {
         // scrolloffset for control-locations (not for lines)
         int xS = AutoScrollPosition.X;
         int yS = AutoScrollPosition.Y;
         // creature
         PedigreeCreature pc = new PedigreeCreature(creature, enabledColorRegions);
         if (highlightCreature)
         {
             pc.highlight = true;
         }
         pc.Location = new Point(x + xS, y + yS + 40);
         splitContainer1.Panel2.Controls.Add(pc);
         pc.CreatureClicked      += CreatureClicked;
         pc.CreatureEdit         += CreatureEdit;
         pc.BestBreedingPartners += BestBreedingPartners;
         pc.exportToClipboard    += exportToClipboard;
         pcs.Add(pc);
         // mother
         if (creature.Mother != null)
         {
             pc = new PedigreeCreature(creature.Mother, enabledColorRegions)
             {
                 Location = new Point(x + xS, y + yS)
             };
             splitContainer1.Panel2.Controls.Add(pc);
             pc.CreatureClicked      += CreatureClicked;
             pc.CreatureEdit         += CreatureEdit;
             pc.BestBreedingPartners += BestBreedingPartners;
             pc.exportToClipboard    += exportToClipboard;
             pcs.Add(pc);
         }
         // father
         if (creature.Father != null)
         {
             pc = new PedigreeCreature(creature.Father, enabledColorRegions)
             {
                 Location = new Point(x + xS, y + yS + 80)
             };
             splitContainer1.Panel2.Controls.Add(pc);
             pc.CreatureClicked      += CreatureClicked;
             pc.CreatureEdit         += CreatureEdit;
             pc.BestBreedingPartners += BestBreedingPartners;
             pc.exportToClipboard    += exportToClipboard;
             pcs.Add(pc);
         }
         // gene-inheritance-lines
         // better: if father < mother: 1, if mother < father: -1
         for (int s = 0; s < PedigreeCreature.displayedStats.Length; s++)
         {
             int si = PedigreeCreature.displayedStats[s];
             if (creature.valuesDom[si] <= 0)
             {
                 continue;                              // don't display arrows for non used stats
             }
             int better = 0;
             if (creature.Mother != null && creature.Father != null)
             {
                 if (creature.Mother.levelsWild[si] < creature.Father.levelsWild[si])
                 {
                     better = -1;
                 }
                 else if (creature.Mother.levelsWild[si] > creature.Father.levelsWild[si])
                 {
                     better = 1;
                 }
             }
             // offspring can have stats that are up to 2 levels higher due to mutations. currently there are no decreasing levels due to mutations
             if (creature.Mother != null && creature.levelsWild[si] >= 0 && (creature.levelsWild[si] == creature.Mother.levelsWild[si] || creature.levelsWild[si] == creature.Mother.levelsWild[si] + 2))
             {
                 lines[0].Add(new[] { 38 + x + 29 * s, y + 33, 38 + x + 29 * s, y + 42, (better == -1 ? 1 : 2), (creature.levelsWild[si] > creature.Mother.levelsWild[si] ? 1 : 0) });
             }
             if (creature.Father != null && creature.levelsWild[si] >= 0 && (creature.levelsWild[si] == creature.Father.levelsWild[si] || creature.levelsWild[si] == creature.Father.levelsWild[si] + 2))
             {
                 lines[0].Add(new[] { 38 + x + 29 * s, y + 83, 38 + x + 29 * s, y + 74, (better == 1 ? 1 : 2), (creature.levelsWild[si] > creature.Father.levelsWild[si] ? 1 : 0) });
             }
         }
         return(true);
     }
     return(false);
 }
        public void drawBestParents(BreedingMode breedingMode, bool updateBreedingData = false)
        {
            SuspendLayout();
            Cursor.Current = Cursors.WaitCursor;
            ClearControls();

            // chosen Creature (only consider this one for its gender)
            bool considerChosenCreature = chosenCreature != null;
            Sex  chosenCS = (considerChosenCreature ? chosenCreature.gender : Sex.Unknown);

            labelTitle.Text = currentSpecies + (considerChosenCreature ? " (only pairings with \"" + chosenCreature.name + "\")" : "");
            if (considerChosenCreature && (chosenCreature.neutered || chosenCreature.status != CreatureStatus.Available))
            {
                labelTitle.Text += "! Breeding not possible ! (" + (chosenCreature.neutered ? "neutered" : "not available") + ")";
            }

            // filter by tags
            List <Creature> choosenF = filterByTags(females);
            List <Creature> choosenM = filterByTags(males);

            if (choosenF != null && choosenM != null && choosenF.Count > 0 && choosenM.Count > 0)
            {
                pedigreeCreature1.Show();
                pedigreeCreature2.Show();
                labelBreedingScore.Show();

                combinedTops[0].Clear();
                combinedTops[1].Clear();
                comboScore.Clear();
                comboOrder.Clear();
                double  t = 0, tt = 0, eTS;
                int     o = 0, nrTS;
                Int16[] bestPossLevels = new Int16[7]; // best possible levels

                for (int f = 0; f < choosenF.Count; f++)
                {
                    if (considerChosenCreature && chosenCS == Sex.Female && choosenF[f] != chosenCreature)
                    {
                        continue;
                    }
                    for (int m = 0; m < choosenM.Count; m++)
                    {
                        if (considerChosenCreature && chosenCS == Sex.Male && choosenM[m] != chosenCreature)
                        {
                            continue;
                        }

                        combinedTops[0].Add(f);
                        combinedTops[1].Add(m);
                        t    = 0;
                        nrTS = 0; // number of possible top-stats
                        eTS  = 0; // expected number of top stats

                        for (int s = 0; s < 7; s++)
                        {
                            bestPossLevels[s] = 0;
                            int higherLevel = Math.Max(choosenF[f].levelsWild[s], choosenM[m].levelsWild[s]);
                            int lowerlevel  = Math.Min(choosenF[f].levelsWild[s], choosenM[m].levelsWild[s]);
                            if (higherLevel < 0)
                            {
                                higherLevel = 0;
                            }
                            if (lowerlevel < 0)
                            {
                                lowerlevel = 0;
                            }

                            tt = statWeights[s] * (0.7 * higherLevel + 0.3 * lowerlevel) / 40;
                            if (tt > 0)
                            {
                                if (breedingMode == BreedingMode.TopStatsLucky)
                                {
                                    if (choosenF[f].topBreedingStats[s] || choosenM[m].topBreedingStats[s])
                                    {
                                        if (choosenF[f].topBreedingStats[s] && choosenM[m].topBreedingStats[s])
                                        {
                                            tt *= 1.142;
                                        }
                                    }
                                    else if (bestLevels[s] > 0)
                                    {
                                        tt *= .01;
                                    }
                                }
                                else if (breedingMode == BreedingMode.TopStatsConservative && bestLevels[s] > 0)
                                {
                                    bestPossLevels[s] = (Int16)Math.Max(choosenF[f].levelsWild[s], choosenM[m].levelsWild[s]);
                                    tt *= .01;
                                    if (choosenF[f].topBreedingStats[s] || choosenM[m].topBreedingStats[s])
                                    {
                                        nrTS++;
                                        eTS += ((choosenF[f].topBreedingStats[s] && choosenM[m].topBreedingStats[s]) ? 1 : 0.7);
                                    }
                                }
                            }
                            t += tt;
                        }

                        if (breedingMode == BreedingMode.TopStatsConservative)
                        {
                            if (choosenF[f].topStatsCountBP < nrTS && choosenM[m].topStatsCountBP < nrTS)
                            {
                                t += eTS;
                            }
                            else
                            {
                                t += .1 * eTS;
                            }
                            // check if the best possible stat outcome already exists in a male
                            bool maleExists = false;

                            foreach (Creature cr in choosenM)
                            {
                                maleExists = true;
                                for (int s = 0; s < 7; s++)
                                {
                                    if (cr.levelsWild[s] != bestPossLevels[s])
                                    {
                                        maleExists = false;
                                        break;
                                    }
                                }
                                if (maleExists)
                                {
                                    break;
                                }
                            }
                            if (maleExists)
                            {
                                t *= .4; // another male with the same stats is not worth much, the mating-cooldown of males is short.
                            }
                            else
                            {
                                // check if the best possible stat outcome already exists in a female
                                bool femaleExists = false;
                                foreach (Creature cr in choosenF)
                                {
                                    femaleExists = true;
                                    for (int s = 0; s < 7; s++)
                                    {
                                        if (cr.levelsWild[s] != bestPossLevels[s])
                                        {
                                            femaleExists = false;
                                            break;
                                        }
                                    }
                                    if (femaleExists)
                                    {
                                        break;
                                    }
                                }
                                if (femaleExists)
                                {
                                    t *= .8; // another female with the same stats may be useful, but not so much in conservative breeding
                                }
                            }
                            //t *= 2; // scale conservative mode as it rather displays improvement, but only scarcely
                        }

                        comboScore.Add(t * 1.25);
                        comboOrder.Add(o++);
                    }
                }
                comboOrder = comboOrder.OrderByDescending(c => comboScore[c]).ToList();
                double minCombo        = comboScore.Min();
                if (minCombo < 0)
                {
                    for (int i = 0; i < comboScore.Count; i++)
                    {
                        comboScore[i] -= minCombo;
                    }
                }

                // draw best parents
                int row = 0;
                // scrolloffsets
                int xS = AutoScrollPosition.X;
                int yS = AutoScrollPosition.Y;
                PedigreeCreature pc;
                Bitmap           bm;
                Graphics         g;
                PictureBox       pb;

                for (int i = 0; i < creatureCollection.maxBreedingSuggestions && i < comboOrder.Count; i++)
                {
                    if (2 * i < pcs.Count)
                    {
                        pcs[2 * i].Creature            = choosenF[combinedTops[0][comboOrder[i]]];
                        pcs[2 * i].enabledColorRegions = enabledColorRegions;
                        pcs[2 * i].comboId             = comboOrder[i];
                        pcs[2 * i].Show();
                    }
                    else
                    {
                        pc                       = new PedigreeCreature(choosenF[combinedTops[0][comboOrder[i]]], enabledColorRegions, comboOrder[i]);
                        pc.Location              = new Point(10 + xS, 5 + 35 * row + yS);
                        pc.CreatureClicked      += new PedigreeCreature.CreatureChangedEventHandler(CreatureClicked);
                        pc.CreatureEdit         += new PedigreeCreature.CreatureEditEventHandler(CreatureEdit);
                        pc.BPRecalc             += new PedigreeCreature.BPRecalcEventHandler(recalculateBreedingPlan);
                        pc.BestBreedingPartners += new PedigreeCreature.CreaturePartnerEventHandler(BestBreedingPartners);
                        pc.exportToClipboard    += new PedigreeCreature.ExportToClipboardEventHandler(exportToClipboard);
                        panelCombinations.Controls.Add(pc);
                        pcs.Add(pc);
                    }
                    if (2 * i + 1 < pcs.Count)
                    {
                        pcs[2 * i + 1].Creature            = choosenM[combinedTops[1][comboOrder[i]]];
                        pcs[2 * i + 1].enabledColorRegions = enabledColorRegions;
                        pcs[2 * i + 1].comboId             = comboOrder[i];
                        pcs[2 * i + 1].Show();
                    }
                    else
                    {
                        pc                       = new PedigreeCreature(choosenM[combinedTops[1][comboOrder[i]]], enabledColorRegions, comboOrder[i]);
                        pc.Location              = new Point(397 + xS, 5 + 35 * row + yS);
                        pc.CreatureClicked      += new PedigreeCreature.CreatureChangedEventHandler(CreatureClicked);
                        pc.CreatureEdit         += new PedigreeCreature.CreatureEditEventHandler(CreatureEdit);
                        pc.BPRecalc             += new PedigreeCreature.BPRecalcEventHandler(recalculateBreedingPlan);
                        pc.BestBreedingPartners += new PedigreeCreature.CreaturePartnerEventHandler(BestBreedingPartners);
                        pc.exportToClipboard    += new PedigreeCreature.ExportToClipboardEventHandler(exportToClipboard);
                        panelCombinations.Controls.Add(pc);
                        pcs.Add(pc);
                    }

                    // draw score
                    if (i < pbs.Count)
                    {
                        pb = pbs[i];
                        pbs[i].Show();
                    }
                    else
                    {
                        pb          = new PictureBox();
                        pb.Size     = new Size(87, 15);
                        pb.Location = new Point(308 + xS, 19 + 35 * row + yS);
                        pbs.Add(pb);
                        panelCombinations.Controls.Add(pb);
                    }
                    bm = new Bitmap(pb.Width, pb.Height);
                    g  = Graphics.FromImage(bm);
                    g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
                    Brush br  = new SolidBrush(Utils.getColorFromPercent((int)(comboScore[comboOrder[i]] * 12.5), 0.5));
                    Brush brd = new SolidBrush(Utils.getColorFromPercent((int)(comboScore[comboOrder[i]] * 12.5), -.2));
                    g.FillRectangle(brd, 0, 5, 87, 5);
                    g.FillRectangle(brd, 20, 0, 47, 15);
                    g.FillRectangle(br, 1, 6, 85, 3);
                    g.FillRectangle(br, 21, 1, 45, 13);
                    g.DrawString(comboScore[comboOrder[i]].ToString("N4"), new System.Drawing.Font("Microsoft Sans Serif", 8.25f), new System.Drawing.SolidBrush(System.Drawing.Color.Black), 24, 2);
                    pb.Image = bm;
                    g.Dispose();

                    row++;
                }
                // hide unused controls
                for (int i = comboOrder.Count; i < creatureCollection.maxBreedingSuggestions && 2 * i + 1 < pcs.Count && i < pbs.Count; i++)
                {
                    pcs[2 * i].Hide();
                    pcs[2 * i + 1].Hide();
                    pbs[i].Hide();
                }

                if (updateBreedingData)
                {
                    setBreedingData(currentSpecies);
                }
                if (comboOrder.Count > 0)
                {
                    setParents(comboOrder[0]);

                    // if breeding mode is conservative and a creature with top-stats already exists, the scoring might seem off
                    if (breedingMode == BreedingMode.TopStatsConservative)
                    {
                        bool            bestCreatureAlreadyAvailable = true;
                        Creature        bestCreature           = null;
                        List <Creature> choosenFemalesAndMales = choosenF.Concat(choosenM).ToList();
                        bool            noWildSpeedLevels      = Values.V.species[speciesIndex].NoImprintingForSpeed == true;
                        foreach (Creature cr in choosenFemalesAndMales)
                        {
                            bestCreatureAlreadyAvailable = true;
                            for (int s = 0; s < 7; s++)
                            {
                                if (!cr.topBreedingStats[s] && !(s == 6 && noWildSpeedLevels))
                                {
                                    bestCreatureAlreadyAvailable = false;
                                    break;
                                }
                            }
                            if (bestCreatureAlreadyAvailable)
                            {
                                bestCreature = cr;
                                break;
                            }
                        }

                        if (bestCreatureAlreadyAvailable)
                        {
                            if (MessageBox.Show("There is already a creature in your library that has all the available top-stats ("
                                                + bestCreature.name + " " + Utils.sexSymbol(bestCreature.gender) + ")."
                                                + "\nThe currently selected conservative-breeding-mode might show some suggestions that may seem non-optimal.\n\n"
                                                + "Change the breeding-mode to \"High Stats\" for better suggestions.\nDo you want to change the breeding-mode to \"High Stats\"?",
                                                "Top-creature already available", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
                            {
                                radioButtonBPHighStats.Checked = true;
                            }
                        }
                    }
                }
                else
                {
                    setParents(-1);
                }
            }
            else
            {
                // hide unused controls
                pedigreeCreature1.Hide();
                pedigreeCreature2.Hide();
                labelBreedingScore.Hide();
                for (int i = 0; i < creatureCollection.maxBreedingSuggestions && 2 * i + 1 < pcs.Count && i < pbs.Count; i++)
                {
                    pcs[2 * i].Hide();
                    pcs[2 * i + 1].Hide();
                    pbs[i].Hide();
                }
                labelInfo.Text    = "No possible pairings found for " + currentSpecies + ". Make sure at least one female and male are available in your library and that you didn't exclude all possible creatures via the tag-selector.";
                labelInfo.Visible = true;
                if (updateBreedingData)
                {
                    setBreedingData(currentSpecies);
                }
            }
            Cursor.Current = Cursors.Default;
            ResumeLayout();
        }
        public void drawBestParents(BreedingMode breedingMode, bool updateBreedingData = false)
        {
            SuspendLayout();
            Cursor.Current = Cursors.WaitCursor;
            ClearControls();

            // chosen Creature (only consider this one for its gender)
            bool considerChosenCreature = chosenCreature != null;
            Gender chosenCG = (considerChosenCreature ? chosenCreature.gender : Gender.Unknown);

            labelTitle.Text = currentSpecies + (considerChosenCreature ? " (only pairings with \"" + chosenCreature.name + "\")" : "");
            if (females != null && males != null && females.Count > 0 && males.Count > 0)
            {
                combinedTops[0].Clear();
                combinedTops[1].Clear();
                comboScore.Clear();
                comboOrder.Clear();
                double t = 0, tt = 0, pTS = 1;
                int o = 0, nrTS = 0;
                Int16[] bestPossLevels = new Int16[7]; // best possible levels

                for (int f = 0; f < females.Count; f++)
                {
                    if (considerChosenCreature && chosenCG == Gender.Female && females[f] != chosenCreature)
                        continue;
                    for (int m = 0; m < males.Count; m++)
                    {
                        if (considerChosenCreature && chosenCG == Gender.Male && males[m] != chosenCreature)
                            continue;

                        combinedTops[0].Add(f);
                        combinedTops[1].Add(m);
                        t = 0;
                        nrTS = 0; // number of possible top-stats
                        pTS = 1;
                        for (int s = 0; s < 7; s++)
                        {
                            bestPossLevels[s] = 0;
                            tt = statWeights[s] * (0.7 * Math.Max(females[f].levelsWild[s], males[m].levelsWild[s]) + 0.3 * Math.Min(females[f].levelsWild[s], males[m].levelsWild[s])) / 40;
                            if (tt <= 0) { tt = 0; }
                            else if (breedingMode == BreedingMode.TopStatsLucky)
                            {
                                if (females[f].topBreedingStats[s] || males[m].topBreedingStats[s])
                                {
                                    if (females[f].topBreedingStats[s] && males[m].topBreedingStats[s])
                                        tt *= 1.142;
                                }
                                else if (bestLevels[s] > 0)
                                    tt *= .01;
                            }
                            else if (breedingMode == BreedingMode.TopStatsConservative && bestLevels[s] > 0)
                            {
                                bestPossLevels[s] = (Int16)Math.Max(females[f].levelsWild[s], males[m].levelsWild[s]);
                                tt *= .01;
                                if (females[f].topBreedingStats[s] || males[m].topBreedingStats[s])
                                {
                                    nrTS++;
                                    pTS *= ((females[f].topBreedingStats[s] && males[m].topBreedingStats[s]) ? 1 : 0.7);
                                }
                            }
                            t += tt;
                        }
                        if (breedingMode == BreedingMode.TopStatsConservative)
                        {
                            if (females[f].topStatsCountBP < nrTS && males[m].topStatsCountBP < nrTS)
                                t += nrTS * pTS;
                            else
                                t += .1 * nrTS * pTS;
                            // check if the best possible stat outcome already exists in a male
                            bool maleExists = false;
                            foreach (Creature cr in males)
                            {
                                maleExists = true;
                                for (int s = 0; s < 7; s++)
                                {
                                    if (cr.levelsWild[s] != bestPossLevels[s])
                                    {
                                        maleExists = false;
                                        break;
                                    }
                                }
                                if (maleExists)
                                    break;
                            }
                            if (maleExists)
                                t *= .2; // another male with the same stats is not worth much
                            else
                            {
                                // check if the best possible stat outcome already exists in a female
                                bool femaleExists = false;
                                foreach (Creature cr in females)
                                {
                                    femaleExists = true;
                                    for (int s = 0; s < 7; s++)
                                    {
                                        if (cr.levelsWild[s] != bestPossLevels[s])
                                        {
                                            femaleExists = false;
                                            break;
                                        }
                                    }
                                    if (femaleExists)
                                        break;
                                }
                                if (femaleExists)
                                    t *= .5; // another female with the same stats may be useful, but not so much in conservative breeding
                            }
                            t *= 2; // scale conservative mode as it rather displays improvement, but only scarcely
                        }

                        comboScore.Add(t * 1.25);
                        comboOrder.Add(o++);
                    }
                }
                comboOrder = comboOrder.OrderByDescending(c => comboScore[c]).ToList();

                // draw best parents
                int row = 0;
                // scrolloffsets
                int xS = AutoScrollPosition.X;
                int yS = AutoScrollPosition.Y;
                PedigreeCreature pc;
                Bitmap bm;
                Graphics g;
                PictureBox pb;

                for (int i = 0; i < maxSuggestions && i < comboOrder.Count; i++)
                {
                    pc = new PedigreeCreature(females[combinedTops[0][comboOrder[i]]], enabledColorRegions, comboOrder[i]);
                    pc.Location = new Point(10 + xS, 5 + 35 * row + yS);
                    pc.CreatureClicked += new PedigreeCreature.CreatureChangedEventHandler(CreatureClicked);
                    pc.CreatureEdit += new PedigreeCreature.CreatureEditEventHandler(CreatureEdit);
                    pc.BPRecalc += new BPRecalcEventHandler(BPRecalc);
                    pc.BestBreedingPartners += new PedigreeCreature.CreaturePartnerEventHandler(BestBreedingPartners);
                    panelCombinations.Controls.Add(pc);
                    pcs.Add(pc);
                    pc = new PedigreeCreature(males[combinedTops[1][comboOrder[i]]], enabledColorRegions, comboOrder[i]);
                    pc.Location = new Point(350 + xS, 5 + 35 * row + yS);
                    pc.CreatureClicked += new PedigreeCreature.CreatureChangedEventHandler(CreatureClicked);
                    pc.CreatureEdit += new PedigreeCreature.CreatureEditEventHandler(CreatureEdit);
                    pc.BPRecalc += new BPRecalcEventHandler(BPRecalc);
                    pc.BestBreedingPartners += new PedigreeCreature.CreaturePartnerEventHandler(BestBreedingPartners);
                    panelCombinations.Controls.Add(pc);
                    pcs.Add(pc);

                    // draw score
                    pb = new PictureBox();
                    pbs.Add(pb);
                    panelCombinations.Controls.Add(pb);
                    pb.Size = new Size(87, 15);
                    pb.Location = new Point(261 + xS, 19 + 35 * row + yS);
                    bm = new Bitmap(pb.Width, pb.Height);
                    g = Graphics.FromImage(bm);
                    g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
                    Brush br = new SolidBrush(Utils.getColorFromPercent((int)(comboScore[comboOrder[i]] * 12.5), 0.5));
                    Brush brd = new SolidBrush(Utils.getColorFromPercent((int)(comboScore[comboOrder[i]] * 12.5), -.2));
                    g.FillRectangle(brd, 0, 5, 87, 5);
                    g.FillRectangle(brd, 20, 0, 47, 15);
                    g.FillRectangle(br, 1, 6, 85, 3);
                    g.FillRectangle(br, 21, 1, 45, 13);
                    g.DrawString(comboScore[comboOrder[i]].ToString("N4"), new System.Drawing.Font("Microsoft Sans Serif", 8.25f), new System.Drawing.SolidBrush(System.Drawing.Color.Black), 24, 2);
                    pb.Image = bm;
                    g.Dispose();
                    row++;
                }

                if (updateBreedingData)
                    setBreedingData(currentSpecies);
                if (comboOrder.Count > 0)
                    setParents(comboOrder[0]);
                else
                    setParents(-1);
            }
            else
            {
                labelInfo.Text = "No possible pairings found for " + currentSpecies + ". Make sure at least one female and male are available in your library.";
                labelInfo.Visible = true;
                if (updateBreedingData)
                    setBreedingData(currentSpecies);
            }
            Cursor.Current = Cursors.Default;
            ResumeLayout();
        }
Beispiel #6
0
        /// <summary>
        /// Creates the pedigree with creature controls.
        /// </summary>
        private void CreatePedigree()
        {
            // clear old pedigreeCreatures
            ClearControls();
            if (_selectedCreature == null)
            {
                NoCreatureSelected();
                return;
            }

            SuspendLayout();

            pedigreeCreature1.SetCustomStatNames(_selectedCreature?.Species?.statNames);

            const int leftBorder           = 40;
            const int pedigreeElementWidth = 325;
            const int margin = 10;

            lbPedigreeEmpty.Visible = false;

            // create ancestors
            CreateParentsChild(_selectedCreature, leftBorder + pedigreeElementWidth + margin, 60, true, true);
            if (_selectedCreature.Mother != null)
            {
                if (CreateParentsChild(_selectedCreature.Mother, leftBorder, 20))
                {
                    _lines[1].Add(new[] { leftBorder + pedigreeElementWidth, 79, leftBorder + pedigreeElementWidth + margin, 79 });
                }
            }
            if (_selectedCreature.Father != null)
            {
                if (CreateParentsChild(_selectedCreature.Father, leftBorder + 2 * (pedigreeElementWidth + margin), 20))
                {
                    _lines[1].Add(new[] { leftBorder + 2 * pedigreeElementWidth + 2 * margin, 79, leftBorder + 2 * pedigreeElementWidth + margin, 159 });
                }
            }

            // create descendants
            int row = 0;
            // scrolloffsets
            int xS = AutoScrollPosition.X;
            int yS = AutoScrollPosition.Y;

            foreach (Creature c in _creatureChildren)
            {
                PedigreeCreature pc = new PedigreeCreature(c, _enabledColorRegions)
                {
                    Location = new Point(leftBorder + xS, 200 + 35 * row + yS)
                };
                for (int s = 0; s < PedigreeCreature.displayedStatsCount; s++)
                {
                    int si = PedigreeCreature.displayedStats[s];
                    if (_selectedCreature.valuesDom[si] > 0 && _selectedCreature.levelsWild[si] >= 0 && _selectedCreature.levelsWild[si] == c.levelsWild[si])
                    {
                        _lines[0].Add(new[] { leftBorder + 38 + 29 * s, 200 + 35 * row + 6, leftBorder + 38 + 29 * s, 200 + 35 * row + 15, 0, 0 });
                    }
                }
                pc.CreatureClicked      += CreatureClicked;
                pc.CreatureEdit         += CreatureEdit;
                pc.BestBreedingPartners += BestBreedingPartners;
                pc.ExportToClipboard    += ExportToClipboard;
                splitContainer1.Panel2.Controls.Add(pc);
                _pcs.Add(pc);
                row++;
            }

            pictureBox.Image   = CreatureColored.GetColoredCreature(_selectedCreature.colors, _selectedCreature.Species, _enabledColorRegions, 256, creatureSex: _selectedCreature.sex);
            pictureBox.Visible = true;

            Invalidate();
            ResumeLayout();
        }
Beispiel #7
0
        private void AsyncCalculateBreedingScoresAndDisplayPairs(BreedingMode breedingMode, bool updateBreedingData = false)
        {
            SuspendLayout();
            this.SuspendDrawing();
            Cursor.Current = Cursors.WaitCursor;
            ClearControls();

            // chosen Creature (only consider this one for its sex)
            bool considerChosenCreature = chosenCreature != null;

            // filter by tags
            int             crCountF = females.Count;
            int             crCountM = males.Count;
            List <Creature> chosenF, chosenM;

            if (considerChosenCreature && chosenCreature.sex == Sex.Female)
            {
                chosenF = new List <Creature>();
            }
            else
            {
                chosenF = filterByTags(females);
            }
            if (considerChosenCreature && chosenCreature.sex == Sex.Male)
            {
                chosenM = new List <Creature>();
            }
            else
            {
                chosenM = filterByTags(males);
            }

            bool creaturesTagFilteredOut = (crCountF != chosenF.Count) ||
                                           (crCountM != chosenM.Count);

            crCountF = chosenF.Count;
            crCountM = chosenM.Count;
            if (nudMutationLimit.Value >= 0)
            {
                chosenF = chosenF.Where(c => c.mutationsMaternal + c.mutationsPaternal <= nudMutationLimit.Value).ToList();
                chosenM = chosenM.Where(c => c.mutationsMaternal + c.mutationsPaternal <= nudMutationLimit.Value).ToList();
            }
            bool creaturesMutationsFilteredOut = (crCountF != chosenF.Count) ||
                                                 (crCountM != chosenM.Count);

            if (considerChosenCreature)
            {
                if (chosenCreature.sex == Sex.Female)
                {
                    chosenF.Add(chosenCreature);
                }
                if (chosenCreature.sex == Sex.Male)
                {
                    chosenM.Add(chosenCreature);
                }
            }

            labelTitle.Text = currentSpecies + (considerChosenCreature ? " (only pairings with \"" + chosenCreature.name + "\")" : "");
            if (considerChosenCreature && (chosenCreature.neutered || chosenCreature.status != CreatureStatus.Available))
            {
                labelTitle.Text += "! Breeding not possible ! (" + (chosenCreature.neutered ? "neutered" : "not available") + ")";
            }

            string warningText = "";

            if (creaturesTagFilteredOut)
            {
                warningText = "Some creatures are filtered out due to their tags";
            }
            if (creaturesMutationsFilteredOut)
            {
                warningText += (warningText.Length > 0 ? " or mutations" : "Some creatures are filtered out due to their mutations");
            }
            if (warningText.Length > 0)
            {
                setMessageLabelText(warningText + ".\nThe top-stats shown here might not be the top-stats of your entire library", MessageBoxIcon.Warning);
            }


            var combinedCreatures = new List <Creature>(chosenF);

            combinedCreatures.AddRange(chosenM);
            // determine top-stats for choosen creatures.
            int[] topStats = new int[7];
            foreach (Creature c in combinedCreatures)
            {
                for (int s = 0; s < 7; s++)
                {
                    if (c.levelsWild[s] > topStats[s])
                    {
                        topStats[s] = c.levelsWild[s];
                    }
                }
            }

            if (Properties.Settings.Default.IgnoreSexInBreedingPlan)
            {
                chosenF = new List <Creature>(combinedCreatures);
                chosenM = new List <Creature>(combinedCreatures);
            }

            if (chosenF.Count > 0 && chosenM.Count > 0)
            {
                pedigreeCreature1.Show();
                pedigreeCreature2.Show();
                labelBreedingScore.Show();

                breedingPairs.Clear();
                double  t = 0, tt = 0, eTS;
                int     nrTS;
                Int16[] bestPossLevels = new Int16[7]; // best possible levels

                foreach (Creature female in chosenF)
                {
                    foreach (Creature male in chosenM)
                    {
                        if (male == female)
                        {
                            continue;                 // happens if Properties.Settings.Default.IgnoreSexInBreedingPlan (when using S+ mutator)
                        }
                        t    = 0;
                        nrTS = 0; // number of possible top-stats
                        eTS  = 0; // expected number of top stats

                        for (int s = 0; s < 7; s++)
                        {
                            bestPossLevels[s] = 0;
                            int higherLevel = Math.Max(female.levelsWild[s], male.levelsWild[s]);
                            int lowerlevel  = Math.Min(female.levelsWild[s], male.levelsWild[s]);
                            if (higherLevel < 0)
                            {
                                higherLevel = 0;
                            }
                            if (lowerlevel < 0)
                            {
                                lowerlevel = 0;
                            }

                            tt = statWeights[s] * (0.7 * higherLevel + 0.3 * lowerlevel) / 40;
                            if (tt > 0)
                            {
                                if (breedingMode == BreedingMode.TopStatsLucky)
                                {
                                    if (female.levelsWild[s] == topStats[s] || male.levelsWild[s] == topStats[s])
                                    {
                                        if (female.levelsWild[s] == topStats[s] && male.levelsWild[s] == topStats[s])
                                        {
                                            tt *= 1.142;
                                        }
                                    }
                                    else if (bestLevels[s] > 0)
                                    {
                                        tt *= .01;
                                    }
                                }
                                else if (breedingMode == BreedingMode.TopStatsConservative && bestLevels[s] > 0)
                                {
                                    bestPossLevels[s] = (Int16)Math.Max(female.levelsWild[s], male.levelsWild[s]);
                                    tt *= .01;
                                    if (female.levelsWild[s] == topStats[s] || male.levelsWild[s] == topStats[s])
                                    {
                                        nrTS++;
                                        eTS += ((female.levelsWild[s] == topStats[s] && male.levelsWild[s] == topStats[s]) ? 1 : 0.7);
                                    }
                                }
                            }
                            t += tt;
                        }

                        if (breedingMode == BreedingMode.TopStatsConservative)
                        {
                            if (female.topStatsCountBP < nrTS && male.topStatsCountBP < nrTS)
                            {
                                t += eTS;
                            }
                            else
                            {
                                t += .1 * eTS;
                            }
                            // check if the best possible stat outcome already exists in a male
                            bool maleExists = false;

                            foreach (Creature cr in chosenM)
                            {
                                maleExists = true;
                                for (int s = 0; s < 7; s++)
                                {
                                    if (cr.levelsWild[s] != bestPossLevels[s])
                                    {
                                        maleExists = false;
                                        break;
                                    }
                                }
                                if (maleExists)
                                {
                                    break;
                                }
                            }
                            if (maleExists)
                            {
                                t *= .4; // another male with the same stats is not worth much, the mating-cooldown of males is short.
                            }
                            else
                            {
                                // check if the best possible stat outcome already exists in a female
                                bool femaleExists = false;
                                foreach (Creature cr in chosenF)
                                {
                                    femaleExists = true;
                                    for (int s = 0; s < 7; s++)
                                    {
                                        if (cr.levelsWild[s] != bestPossLevels[s])
                                        {
                                            femaleExists = false;
                                            break;
                                        }
                                    }
                                    if (femaleExists)
                                    {
                                        break;
                                    }
                                }
                                if (femaleExists)
                                {
                                    t *= .8; // another female with the same stats may be useful, but not so much in conservative breeding
                                }
                            }
                            //t *= 2; // scale conservative mode as it rather displays improvement, but only scarcely
                        }

                        breedingPairs.Add(new BreedingPair(female, male, t * 1.25));
                    }
                }

                breedingPairs = breedingPairs.OrderByDescending(p => p.BreedingScore).ToList();
                double minScore        = (breedingPairs.Count > 0 ? breedingPairs[breedingPairs.Count - 1].BreedingScore : 0);
                if (minScore < 0)
                {
                    foreach (BreedingPair bp in breedingPairs)
                    {
                        bp.BreedingScore -= minScore;
                    }
                }

                // draw best parents
                int row = 0;
                // scrolloffsets
                int xS = AutoScrollPosition.X;
                int yS = AutoScrollPosition.Y;
                PedigreeCreature pc;
                Bitmap           bm;
                Graphics         g;
                PictureBox       pb;

                for (int i = 0; i < breedingPairs.Count && i < creatureCollection.maxBreedingSuggestions; i++)
                {
                    if (2 * i < pcs.Count)
                    {
                        pcs[2 * i].Creature            = breedingPairs[i].Female;
                        pcs[2 * i].enabledColorRegions = enabledColorRegions;
                        pcs[2 * i].comboId             = i;
                        pcs[2 * i].Show();
                    }
                    else
                    {
                        pc = new PedigreeCreature(breedingPairs[i].Female, enabledColorRegions, i);
                        //pc.Location = new Point(10 + xS, 5 + 35 * row + yS);
                        pc.CreatureClicked      += new PedigreeCreature.CreatureChangedEventHandler(CreatureClicked);
                        pc.CreatureEdit         += new PedigreeCreature.CreatureEditEventHandler(CreatureEdit);
                        pc.BPRecalc             += new PedigreeCreature.BPRecalcEventHandler(recalculateBreedingPlan);
                        pc.BestBreedingPartners += new PedigreeCreature.CreaturePartnerEventHandler(BestBreedingPartners);
                        pc.exportToClipboard    += new PedigreeCreature.ExportToClipboardEventHandler(exportToClipboard);
                        flowLayoutPanelPairs.Controls.Add(pc);
                        pcs.Add(pc);
                    }

                    // draw score
                    if (i < pbs.Count)
                    {
                        pb = pbs[i];
                        pbs[i].Show();
                    }
                    else
                    {
                        pb = new PictureBox
                        {
                            Size = new Size(87, 35)
                        };
                        //pb.Location = new Point(308 + xS, 19 + 35 * row + yS);
                        pbs.Add(pb);
                        flowLayoutPanelPairs.Controls.Add(pb);
                    }

                    if (2 * i + 1 < pcs.Count)
                    {
                        pcs[2 * i + 1].Creature            = breedingPairs[i].Male;
                        pcs[2 * i + 1].enabledColorRegions = enabledColorRegions;
                        pcs[2 * i + 1].comboId             = i;
                        pcs[2 * i + 1].Show();
                    }
                    else
                    {
                        pc = new PedigreeCreature(breedingPairs[i].Male, enabledColorRegions, i);
                        //pc.Location = new Point(397 + xS, 5 + 35 * row + yS);
                        pc.CreatureClicked      += new PedigreeCreature.CreatureChangedEventHandler(CreatureClicked);
                        pc.CreatureEdit         += new PedigreeCreature.CreatureEditEventHandler(CreatureEdit);
                        pc.BPRecalc             += new PedigreeCreature.BPRecalcEventHandler(recalculateBreedingPlan);
                        pc.BestBreedingPartners += new PedigreeCreature.CreaturePartnerEventHandler(BestBreedingPartners);
                        pc.exportToClipboard    += new PedigreeCreature.ExportToClipboardEventHandler(exportToClipboard);
                        flowLayoutPanelPairs.Controls.Add(pc);
                        flowLayoutPanelPairs.SetFlowBreak(pc, true);
                        pcs.Add(pc);
                    }

                    bm = new Bitmap(pb.Width, pb.Height);
                    using (g = Graphics.FromImage(bm))
                    {
                        g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
                        Brush br  = new SolidBrush(Utils.getColorFromPercent((int)(breedingPairs[i].BreedingScore * 12.5), 0.5));
                        Brush brd = new SolidBrush(Utils.getColorFromPercent((int)(breedingPairs[i].BreedingScore * 12.5), -.2));
                        g.FillRectangle(brd, 0, 15, 87, 5);
                        g.FillRectangle(brd, 20, 10, 47, 15);
                        g.FillRectangle(br, 1, 16, 85, 3);
                        g.FillRectangle(br, 21, 11, 45, 13);
                        g.DrawString(breedingPairs[i].BreedingScore.ToString("N4"), new System.Drawing.Font("Microsoft Sans Serif", 8.25f), new System.Drawing.SolidBrush(System.Drawing.Color.Black), 24, 12);
                        pb.Image = bm;
                    }

                    row++;
                }
                // hide unused controls
                for (int i = breedingPairs.Count; i < creatureCollection.maxBreedingSuggestions && 2 * i + 1 < pcs.Count && i < pbs.Count; i++)
                {
                    pcs[2 * i].Hide();
                    pcs[2 * i + 1].Hide();
                    pbs[i].Hide();
                }

                if (updateBreedingData)
                {
                    setBreedingData(currentSpecies);
                }
                if (breedingPairs.Count > 0)
                {
                    setParents(0);

                    // if breeding mode is conservative and a creature with top-stats already exists, the scoring might seem off
                    if (breedingMode == BreedingMode.TopStatsConservative)
                    {
                        bool            bestCreatureAlreadyAvailable = true;
                        Creature        bestCreature           = null;
                        List <Creature> choosenFemalesAndMales = chosenF.Concat(chosenM).ToList();
                        bool            noWildSpeedLevels      = Values.V.species[speciesIndex].NoImprintingForSpeed == true;
                        foreach (Creature cr in choosenFemalesAndMales)
                        {
                            bestCreatureAlreadyAvailable = true;
                            for (int s = 0; s < 7; s++)
                            {
                                if (!cr.topBreedingStats[s] && !(s == 6 && noWildSpeedLevels))
                                {
                                    bestCreatureAlreadyAvailable = false;
                                    break;
                                }
                            }
                            if (bestCreatureAlreadyAvailable)
                            {
                                bestCreature = cr;
                                break;
                            }
                        }

                        if (bestCreatureAlreadyAvailable)
                        {
                            setMessageLabelText("There is already a creature in your library that has all the available top-stats ("
                                                + bestCreature.name + " " + Utils.sexSymbol(bestCreature.sex) + ")."
                                                + "\nThe currently selected conservative-breeding-mode might show some suggestions that may seem non-optimal.\n"
                                                + "Change the breeding-mode to \"High Stats\" for better suggestions.", MessageBoxIcon.Warning);
                        }
                    }
                }
                else
                {
                    setParents(-1);
                }
            }
            else
            {
                // hide unused controls
                pedigreeCreature1.Hide();
                pedigreeCreature2.Hide();
                labelBreedingScore.Hide();
                for (int i = 0; i < creatureCollection.maxBreedingSuggestions && 2 * i + 1 < pcs.Count && i < pbs.Count; i++)
                {
                    pcs[2 * i].Hide();
                    pcs[2 * i + 1].Hide();
                    pbs[i].Hide();
                }
                labelInfo.Text    = "No possible pairings found for " + currentSpecies + ". Make sure at least one female and male are available in your library and that you didn't exclude all possible creatures via the tag-selector.";
                labelInfo.Visible = true;
                if (updateBreedingData)
                {
                    setBreedingData(currentSpecies);
                }
            }
            Cursor.Current = Cursors.Default;
            this.ResumeDrawing();
            ResumeLayout();
        }
 private bool createParentsChild(Creature creature, int x, int y, bool drawWithNoParents = false, bool highlightCreature = false)
 {
     if (creature != null && (drawWithNoParents || creature.Mother != null || creature.Father != null))
     {
         // scrolloffset for control-locations (not for lines)
         int xS = AutoScrollPosition.X;
         int yS = AutoScrollPosition.Y;
         // creature
         PedigreeCreature pc = new PedigreeCreature(creature, enabledColorRegions);
         if (highlightCreature)
         {
             pc.highlight = true;
         }
         pc.Location = new Point(x + xS, y + yS + 40);
         Controls.Add(pc);
         pc.CreatureClicked      += new PedigreeCreature.CreatureChangedEventHandler(CreatureClicked);
         pc.CreatureEdit         += new PedigreeCreature.CreatureEditEventHandler(CreatureEdit);
         pc.BestBreedingPartners += new PedigreeCreature.CreaturePartnerEventHandler(BestBreedingPartners);
         pc.exportToClipboard    += new PedigreeCreature.ExportToClipboardEventHandler(exportToClipboard);
         pcs.Add(pc);
         // mother
         if (creature.Mother != null)
         {
             pc          = new PedigreeCreature(creature.Mother, enabledColorRegions);
             pc.Location = new Point(x + xS, y + yS);
             Controls.Add(pc);
             pc.CreatureClicked      += new PedigreeCreature.CreatureChangedEventHandler(CreatureClicked);
             pc.CreatureEdit         += new PedigreeCreature.CreatureEditEventHandler(CreatureEdit);
             pc.BestBreedingPartners += new PedigreeCreature.CreaturePartnerEventHandler(BestBreedingPartners);
             pc.exportToClipboard    += new PedigreeCreature.ExportToClipboardEventHandler(exportToClipboard);
             pcs.Add(pc);
         }
         // father
         if (creature.Father != null)
         {
             pc          = new PedigreeCreature(creature.Father, enabledColorRegions);
             pc.Location = new Point(x + xS, y + yS + 80);
             Controls.Add(pc);
             pc.CreatureClicked      += new PedigreeCreature.CreatureChangedEventHandler(CreatureClicked);
             pc.CreatureEdit         += new PedigreeCreature.CreatureEditEventHandler(CreatureEdit);
             pc.BestBreedingPartners += new PedigreeCreature.CreaturePartnerEventHandler(BestBreedingPartners);
             pc.exportToClipboard    += new PedigreeCreature.ExportToClipboardEventHandler(exportToClipboard);
             pcs.Add(pc);
         }
         // gene-inheritance-lines
         // better: if father < mother: 1, if mother < father: -1
         int better;
         for (int s = 0; s < 7; s++)
         {
             better = 0;
             if (creature.Mother != null && creature.Father != null)
             {
                 if (creature.Mother.levelsWild[s] < creature.Father.levelsWild[s])
                 {
                     better = -1;
                 }
                 else if (creature.Mother.levelsWild[s] > creature.Father.levelsWild[s])
                 {
                     better = 1;
                 }
             }
             // offspring can have stats that are up to 2 levels higher due to mutations. currently there are no decreasing levels due to mutations
             if (creature.Mother != null && creature.levelsWild[s] >= 0 && (creature.levelsWild[s] == creature.Mother.levelsWild[s] || creature.levelsWild[s] == creature.Mother.levelsWild[s] + 2))
             {
                 lines[0].Add(new int[] { 38 + x + 28 * s, y + 33, 38 + x + 28 * s, y + 42, (better == -1 ? 1 : 2), (creature.levelsWild[s] > creature.Mother.levelsWild[s] ? 1 : 0) });
             }
             if (creature.Father != null && creature.levelsWild[s] >= 0 && (creature.levelsWild[s] == creature.Father.levelsWild[s] || creature.levelsWild[s] == creature.Father.levelsWild[s] + 2))
             {
                 lines[0].Add(new int[] { 38 + x + 28 * s, y + 83, 38 + x + 28 * s, y + 74, (better == 1 ? 1 : 2), (creature.levelsWild[s] > creature.Father.levelsWild[s] ? 1 : 0) });
             }
         }
         return(true);
     }
     return(false);
 }
        /// <summary>
        /// call this function to create the pedigreeCreature-Elements
        /// </summary>
        public void createPedigree()
        {
            // clear old pedigreeCreatures
            ClearControls();
            if (creature != null)
            {
                this.SuspendLayout();

                int leftBorder = 200;

                lbPedigreeEmpty.Visible = false;

                // create ancestors
                createParentsChild(creature, leftBorder + 325, 60, true, true);
                if (creature.Mother != null)
                {
                    if (createParentsChild(creature.Mother, leftBorder + 10, 20, false))
                    {
                        lines[1].Add(new int[] { leftBorder + 306, 79, leftBorder + 325, 79 });
                    }
                }
                if (creature.Father != null)
                {
                    if (createParentsChild(creature.Father, leftBorder + 640, 20, false))
                    {
                        lines[1].Add(new int[] { leftBorder + 640, 79, leftBorder + 621, 159 });
                    }
                }

                // create descendants
                int row = 0;
                // scrolloffsets
                int xS = AutoScrollPosition.X;
                int yS = AutoScrollPosition.Y;
                foreach (Creature c in children)
                {
                    PedigreeCreature pc = new PedigreeCreature(c, enabledColorRegions);
                    pc.Location = new Point(leftBorder + 10 + xS, 200 + 35 * row + yS);
                    for (int s = 0; s < 7; s++)
                    {
                        if (creature.levelsWild[s] >= 0 && creature.levelsWild[s] == c.levelsWild[s])
                        {
                            lines[0].Add(new int[] { leftBorder + 10 + 38 + 28 * s, 200 + 35 * row + 6, leftBorder + 10 + 38 + 28 * s, 200 + 35 * row + 15, 0, 0 });
                        }
                    }
                    pc.CreatureClicked      += new PedigreeCreature.CreatureChangedEventHandler(CreatureClicked);
                    pc.CreatureEdit         += new PedigreeCreature.CreatureEditEventHandler(CreatureEdit);
                    pc.BestBreedingPartners += new PedigreeCreature.CreaturePartnerEventHandler(BestBreedingPartners);
                    pc.exportToClipboard    += new PedigreeCreature.ExportToClipboardEventHandler(exportToClipboard);
                    Controls.Add(pc);
                    pcs.Add(pc);
                    row++;
                }

                pictureBox.Image = CreatureColored.getColoredCreature(creature.colors, creature.species, enabledColorRegions, 256);

                this.Invalidate();
                this.ResumeLayout();
            }
            else
            {
                noCreatureSelected();
            }
        }
Beispiel #10
0
        public void drawBestParents(BreedingMode breedingMode, bool updateBreedingData = false)
        {
            SuspendLayout();
            Cursor.Current = Cursors.WaitCursor;
            ClearControls();

            // chosen Creature (only consider this one for its gender)
            bool   considerChosenCreature = chosenCreature != null;
            Gender chosenCG = (considerChosenCreature ? chosenCreature.gender : Gender.Unknown);

            labelTitle.Text = currentSpecies + (considerChosenCreature ? " (only pairings with \"" + chosenCreature.name + "\")" : "");
            if (females != null && males != null && females.Count > 0 && males.Count > 0)
            {
                combinedTops[0].Clear();
                combinedTops[1].Clear();
                comboScore.Clear();
                comboOrder.Clear();
                double  t = 0, tt = 0, pTS = 1;
                int     o = 0, nrTS = 0;
                Int16[] bestPossLevels = new Int16[7]; // best possible levels

                for (int f = 0; f < females.Count; f++)
                {
                    if (considerChosenCreature && chosenCG == Gender.Female && females[f] != chosenCreature)
                    {
                        continue;
                    }
                    for (int m = 0; m < males.Count; m++)
                    {
                        if (considerChosenCreature && chosenCG == Gender.Male && males[m] != chosenCreature)
                        {
                            continue;
                        }

                        combinedTops[0].Add(f);
                        combinedTops[1].Add(m);
                        t    = 0;
                        nrTS = 0; // number of possible top-stats
                        pTS  = 1;
                        for (int s = 0; s < 7; s++)
                        {
                            bestPossLevels[s] = 0;
                            tt = statWeights[s] * (0.7 * Math.Max(females[f].levelsWild[s], males[m].levelsWild[s]) + 0.3 * Math.Min(females[f].levelsWild[s], males[m].levelsWild[s])) / 40;
                            if (tt <= 0)
                            {
                                tt = 0;
                            }
                            else if (breedingMode == BreedingMode.TopStatsLucky)
                            {
                                if (females[f].topBreedingStats[s] || males[m].topBreedingStats[s])
                                {
                                    if (females[f].topBreedingStats[s] && males[m].topBreedingStats[s])
                                    {
                                        tt *= 1.142;
                                    }
                                }
                                else if (bestLevels[s] > 0)
                                {
                                    tt *= .01;
                                }
                            }
                            else if (breedingMode == BreedingMode.TopStatsConservative && bestLevels[s] > 0)
                            {
                                bestPossLevels[s] = (Int16)Math.Max(females[f].levelsWild[s], males[m].levelsWild[s]);
                                tt *= .01;
                                if (females[f].topBreedingStats[s] || males[m].topBreedingStats[s])
                                {
                                    nrTS++;
                                    pTS *= ((females[f].topBreedingStats[s] && males[m].topBreedingStats[s]) ? 1 : 0.7);
                                }
                            }
                            t += tt;
                        }
                        if (breedingMode == BreedingMode.TopStatsConservative)
                        {
                            if (females[f].topStatsCountBP < nrTS && males[m].topStatsCountBP < nrTS)
                            {
                                t += nrTS * pTS;
                            }
                            else
                            {
                                t += .1 * nrTS * pTS;
                            }
                            // check if the best possible stat outcome already exists in a male
                            bool maleExists = false;
                            foreach (Creature cr in males)
                            {
                                maleExists = true;
                                for (int s = 0; s < 7; s++)
                                {
                                    if (cr.levelsWild[s] != bestPossLevels[s])
                                    {
                                        maleExists = false;
                                        break;
                                    }
                                }
                                if (maleExists)
                                {
                                    break;
                                }
                            }
                            if (maleExists)
                            {
                                t *= .2; // another male with the same stats is not worth much
                            }
                            else
                            {
                                // check if the best possible stat outcome already exists in a female
                                bool femaleExists = false;
                                foreach (Creature cr in females)
                                {
                                    femaleExists = true;
                                    for (int s = 0; s < 7; s++)
                                    {
                                        if (cr.levelsWild[s] != bestPossLevels[s])
                                        {
                                            femaleExists = false;
                                            break;
                                        }
                                    }
                                    if (femaleExists)
                                    {
                                        break;
                                    }
                                }
                                if (femaleExists)
                                {
                                    t *= .5; // another female with the same stats may be useful, but not so much in conservative breeding
                                }
                            }
                            t *= 2; // scale conservative mode as it rather displays improvement, but only scarcely
                        }

                        comboScore.Add(t * 1.25);
                        comboOrder.Add(o++);
                    }
                }
                comboOrder = comboOrder.OrderByDescending(c => comboScore[c]).ToList();

                // draw best parents
                int row = 0;
                // scrolloffsets
                int xS = AutoScrollPosition.X;
                int yS = AutoScrollPosition.Y;
                PedigreeCreature pc;
                Bitmap           bm;
                Graphics         g;
                PictureBox       pb;

                for (int i = 0; i < maxSuggestions && i < comboOrder.Count; i++)
                {
                    pc                       = new PedigreeCreature(females[combinedTops[0][comboOrder[i]]], enabledColorRegions, comboOrder[i]);
                    pc.Location              = new Point(10 + xS, 5 + 35 * row + yS);
                    pc.CreatureClicked      += new PedigreeCreature.CreatureChangedEventHandler(CreatureClicked);
                    pc.CreatureEdit         += new PedigreeCreature.CreatureEditEventHandler(CreatureEdit);
                    pc.BPRecalc             += new BPRecalcEventHandler(BPRecalc);
                    pc.BestBreedingPartners += new PedigreeCreature.CreaturePartnerEventHandler(BestBreedingPartners);
                    panelCombinations.Controls.Add(pc);
                    pcs.Add(pc);
                    pc                       = new PedigreeCreature(males[combinedTops[1][comboOrder[i]]], enabledColorRegions, comboOrder[i]);
                    pc.Location              = new Point(350 + xS, 5 + 35 * row + yS);
                    pc.CreatureClicked      += new PedigreeCreature.CreatureChangedEventHandler(CreatureClicked);
                    pc.CreatureEdit         += new PedigreeCreature.CreatureEditEventHandler(CreatureEdit);
                    pc.BPRecalc             += new BPRecalcEventHandler(BPRecalc);
                    pc.BestBreedingPartners += new PedigreeCreature.CreaturePartnerEventHandler(BestBreedingPartners);
                    panelCombinations.Controls.Add(pc);
                    pcs.Add(pc);

                    // draw score
                    pb = new PictureBox();
                    pbs.Add(pb);
                    panelCombinations.Controls.Add(pb);
                    pb.Size             = new Size(87, 15);
                    pb.Location         = new Point(261 + xS, 19 + 35 * row + yS);
                    bm                  = new Bitmap(pb.Width, pb.Height);
                    g                   = Graphics.FromImage(bm);
                    g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
                    Brush br  = new SolidBrush(Utils.getColorFromPercent((int)(comboScore[comboOrder[i]] * 12.5), 0.5));
                    Brush brd = new SolidBrush(Utils.getColorFromPercent((int)(comboScore[comboOrder[i]] * 12.5), -.2));
                    g.FillRectangle(brd, 0, 5, 87, 5);
                    g.FillRectangle(brd, 20, 0, 47, 15);
                    g.FillRectangle(br, 1, 6, 85, 3);
                    g.FillRectangle(br, 21, 1, 45, 13);
                    g.DrawString(comboScore[comboOrder[i]].ToString("N4"), new System.Drawing.Font("Microsoft Sans Serif", 8.25f), new System.Drawing.SolidBrush(System.Drawing.Color.Black), 24, 2);
                    pb.Image = bm;
                    g.Dispose();
                    row++;
                }

                if (updateBreedingData)
                {
                    setBreedingData(currentSpecies);
                }
                if (comboOrder.Count > 0)
                {
                    setParents(comboOrder[0]);
                }
                else
                {
                    setParents(-1);
                }
            }
            else
            {
                labelInfo.Text    = "No possible pairings found for " + currentSpecies + ". Make sure at least one female and male are available in your library.";
                labelInfo.Visible = true;
                if (updateBreedingData)
                {
                    setBreedingData(currentSpecies);
                }
            }
            Cursor.Current = Cursors.Default;
            ResumeLayout();
        }
Beispiel #11
0
        /// <summary>
        /// call this function to create the pedigreeCreature-Elements
        /// </summary>
        public void createPedigree()
        {
            // clear old pedigreeCreatures
            ClearControls();
            if (creature != null)
            {
                this.SuspendLayout();

                labelEmptyInfo.Visible = false;

                // create ancestors
                createParentsChild(creature, 278, 60, true, true);
                if (creature.Mother != null)
                {
                    if (createParentsChild(creature.Mother, 10, 20, false))
                        lines[1].Add(new int[] { 259, 79, 278, 79 });
                }
                if (creature.Father != null)
                {
                    if (createParentsChild(creature.Father, 546, 20, false))
                        lines[1].Add(new int[] { 546, 79, 527, 159 });
                }

                // create descendants
                int row = 0;
                // scrolloffsets
                int xS = AutoScrollPosition.X;
                int yS = AutoScrollPosition.Y;
                foreach (Creature c in children)
                {
                    PedigreeCreature pc = new PedigreeCreature(c, enabledColorRegions);
                    pc.Location = new Point(10 + xS, 200 + 35 * row + yS);
                    for (int s = 0; s < 7; s++)
                    {
                        if (creature.levelsWild[s] >= 0 && creature.levelsWild[s] == c.levelsWild[s])
                            lines[0].Add(new int[] { 10 + 38 + 28 * s, 200 + 35 * row + 6, 10 + 38 + 28 * s, 200 + 35 * row + 15, 0 });
                    }
                    pc.CreatureClicked += new PedigreeCreature.CreatureChangedEventHandler(CreatureClicked);
                    pc.CreatureEdit += new PedigreeCreature.CreatureEditEventHandler(CreatureEdit);
                    pc.BestBreedingPartners += new PedigreeCreature.CreaturePartnerEventHandler(BestBreedingPartners);
                    Controls.Add(pc);
                    pcs.Add(pc);
                    row++;
                }

                pictureBox.Image = CreatureColored.getColoredCreature(creature.colors, creature.species, enabledColorRegions, 256);

                this.Invalidate();
                this.ResumeLayout();
            }
            else
            {
                noCreatureSelected();
            }
        }
Beispiel #12
0
 private bool createParentsChild(Creature creature, int x, int y, bool drawWithNoParents = false, bool highlightCreature = false)
 {
     if (creature != null && (drawWithNoParents || creature.Mother != null || creature.Father != null))
     {
         // scrolloffset for control-locations (not for lines)
         int xS = AutoScrollPosition.X;
         int yS = AutoScrollPosition.Y;
         // creature
         PedigreeCreature pc = new PedigreeCreature(creature, enabledColorRegions);
         if (highlightCreature)
             pc.highlight = true;
         pc.Location = new Point(x + xS, y + yS + 40);
         Controls.Add(pc);
         pc.CreatureClicked += new PedigreeCreature.CreatureChangedEventHandler(CreatureClicked);
         pc.CreatureEdit += new PedigreeCreature.CreatureEditEventHandler(CreatureEdit);
         pc.BestBreedingPartners += new PedigreeCreature.CreaturePartnerEventHandler(BestBreedingPartners);
         pcs.Add(pc);
         // mother
         if (creature.Mother != null)
         {
             pc = new PedigreeCreature(creature.Mother, enabledColorRegions);
             pc.Location = new Point(x + xS, y + yS);
             Controls.Add(pc);
             pc.CreatureClicked += new PedigreeCreature.CreatureChangedEventHandler(CreatureClicked);
             pc.CreatureEdit += new PedigreeCreature.CreatureEditEventHandler(CreatureEdit);
             pc.BestBreedingPartners += new PedigreeCreature.CreaturePartnerEventHandler(BestBreedingPartners);
             pcs.Add(pc);
         }
         // father
         if (creature.Father != null)
         {
             pc = new PedigreeCreature(creature.Father, enabledColorRegions);
             pc.Location = new Point(x + xS, y + yS + 80);
             Controls.Add(pc);
             pc.CreatureClicked += new PedigreeCreature.CreatureChangedEventHandler(CreatureClicked);
             pc.CreatureEdit += new PedigreeCreature.CreatureEditEventHandler(CreatureEdit);
             pc.BestBreedingPartners += new PedigreeCreature.CreaturePartnerEventHandler(BestBreedingPartners);
             pcs.Add(pc);
         }
         // gene-inheritance-lines
         // better: if father < mother: 1, if mother < father: -1
         int better;
         for (int s = 0; s < 7; s++)
         {
             better = 0;
             if (creature.Mother != null && creature.Father != null)
             {
                 if (creature.Mother.levelsWild[s] < creature.Father.levelsWild[s])
                     better = -1;
                 else if (creature.Mother.levelsWild[s] > creature.Father.levelsWild[s])
                     better = 1;
             }
             if (creature.Mother != null && creature.levelsWild[s] >= 0 && creature.levelsWild[s] == creature.Mother.levelsWild[s])
             {
                 lines[0].Add(new int[] { 38 + x + 28 * s, y + 33, 38 + x + 28 * s, y + 42, (better == -1 ? 1 : 2) });
             }
             if (creature.Father != null && creature.levelsWild[s] >= 0 && creature.levelsWild[s] == creature.Father.levelsWild[s])
             {
                 lines[0].Add(new int[] { 38 + x + 28 * s, y + 83, 38 + x + 28 * s, y + 74, (better == 1 ? 1 : 2) });
             }
         }
         return true;
     }
     return false;
 }