private const double probLowerLvl  = 0.45; // probability of inheriting the higher level-stat

        public BreedingPlan()
        {
            InitializeComponent();
            SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
            for (int i = 0; i < 8; i++)
            {
                statWeights[i] = 1;
            }

            breedingMode = BreedingMode.TopStatsConservative;

            breedingPairs = new List <BreedingPair>();
            pedigreeCreatureBest.IsVirtual  = true;
            pedigreeCreatureWorst.IsVirtual = true;
            pedigreeCreatureBestPossibleInSpecies.IsVirtual = true;
            pedigreeCreatureBest.onlyLevels  = true;
            pedigreeCreatureWorst.onlyLevels = true;
            pedigreeCreatureBestPossibleInSpecies.onlyLevels = true;
            pedigreeCreatureBest.Clear();
            pedigreeCreatureWorst.Clear();
            pedigreeCreatureBestPossibleInSpecies.Clear();
            pedigreeCreatureBest.HandCursor  = false;
            pedigreeCreatureWorst.HandCursor = false;
            pedigreeCreatureBestPossibleInSpecies.HandCursor = false;

            statWeighting           = statWeighting1;
            breedingPlanNeedsUpdate = false;
            dontUpdateBreedingPlan  = false;

            cbServerFilterLibrary.Checked = Properties.Settings.Default.UseServerFilterForBreedingPlan;

            tagSelectorList1.OnTagChanged += TagSelectorList1_OnTagChanged;
        }
Example #2
0
 private void radioButtonBPHighStats_CheckedChanged(object sender, EventArgs e)
 {
     if (rbBPHighStats.Checked)
     {
         breedingMode = BreedingMode.BestNextGen;
         calculateBreedingScoresAndDisplayPairs();
     }
 }
Example #3
0
 private void radioButtonBPTopStats_CheckedChanged(object sender, EventArgs e)
 {
     if (rbBPTopStats.Checked)
     {
         breedingMode = BreedingMode.TopStatsLucky;
         calculateBreedingScoresAndDisplayPairs();
     }
 }
Example #4
0
 private void radioButtonBPTopStatsCn_CheckedChanged(object sender, EventArgs e)
 {
     if (radioButtonBPTopStatsCn.Checked)
     {
         breedingMode = BreedingMode.TopStatsConservative;
         calculateBreedingScoresAndDisplayPairs();
     }
 }
Example #5
0
        private async void CalculateBreedingScoresAndDisplayPairs(BreedingMode breedingMode, bool updateBreedingData = false)
        {
            cancelSource?.Cancel();
            using (cancelSource = new CancellationTokenSource())
            {
                try
                {
                    await Task.Delay(400, cancelSource.Token); // recalculate breedingplan at most a certain interval

                    AsyncCalculateBreedingScoresAndDisplayPairs(breedingMode, updateBreedingData);
                }
                catch (TaskCanceledException)
                {
                    return;
                }
            }
            cancelSource = null;
        }
        public void determineBestBreeding(Creature chosenCreature = null, bool forceUpdate = false)
        {
            string selectedSpecies = (chosenCreature != null ? chosenCreature.species : "");
            bool   newSpecies      = false;

            if (selectedSpecies.Length == 0 && listViewSpeciesBP.SelectedIndices.Count > 0)
            {
                selectedSpecies = listViewSpeciesBP.SelectedItems[0].Text;
            }
            if (selectedSpecies.Length > 0 && CurrentSpecies != selectedSpecies)
            {
                CurrentSpecies = selectedSpecies;
                newSpecies     = true;

                int s = Values.V.speciesNames.IndexOf(selectedSpecies);
                EnabledColorRegions = (s >= 0 ? Values.V.species[s].colors.Select(n => n.name != "").ToArray() : new bool[6] {
                    true, true, true, true, true, true
                });

                breedingPlanNeedsUpdate = true;
            }
            if (forceUpdate || breedingPlanNeedsUpdate)
            {
                Creatures = creatureCollection.creatures.Where(c => (c != null && c == chosenCreature) ||
                                                               (c.species == selectedSpecies && c.status == CreatureStatus.Available && !c.neutered && (checkBoxIncludeCooldowneds.Checked || (c.cooldownUntil < DateTime.Now && c.growingUntil < DateTime.Now)))).ToList();
            }

            statWeights = statWeighting1.Weightings;
            BreedingMode bm = BreedingMode.TopStatsConservative;

            if (radioButtonBPTopStats.Checked)
            {
                bm = BreedingMode.TopStatsLucky;
            }
            else if (radioButtonBPHighStats.Checked)
            {
                bm = BreedingMode.BestNextGen;
            }

            this.chosenCreature = chosenCreature;
            drawBestParents(bm, newSpecies);
            breedingPlanNeedsUpdate = false;
        }
Example #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);
            }

            // 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();
        }
Example #8
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();
        }
        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();
        }
Example #10
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();
        }
Example #11
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();
        }