private void buttonEdit_Click(object sender, EventArgs e) { SuspendLayout(); if (creature != null) { if (panel1.Visible) { CloseSettings(false); } else { checkBoxIsBred.Checked = creature.isBred; panelParents.Visible = creature.isBred; if (creature.isBred) { PopulateParentsList(); } textBoxName.Text = creature.name; textBoxOwner.Text = creature.owner; textBoxNote.Text = creature.note; sex = creature.sex; buttonSex.Text = Utils.sexSymbol(sex); creatureStatus = creature.status; buttonStatus.Text = Utils.statusSymbol(creatureStatus); textBoxName.SelectAll(); textBoxName.Focus(); panel1.Visible = true; } } ResumeLayout(); }
public void buttonEdit_Click(object sender, EventArgs e) { SuspendLayout(); if (creature != null) { if (panel1.Visible) { closeSettings(false); } else { checkBoxIsBred.Checked = creature.isBred; panelParents.Visible = creature.isBred; if (creature.isBred) { populateParentsList(); } textBoxName.Text = creature.name; textBoxOwner.Text = creature.owner; textBoxNote.Text = creature.note; sex = creature.gender; buttonSex.Text = Utils.sexSymbol(sex); status = creature.status; buttonStatus.Text = Utils.statusSymbol(status); textBoxName.SelectAll(); textBoxName.Focus(); panel1.Visible = true; for (int s = 0; s < 7; s++) { numUDLevelsDom[s].Value = creature.levelsDom[s]; } } } ResumeLayout(); }
private void buttonGender_Click(object sender, EventArgs e) { c.gender = Utils.nextSex(c.gender); buttonSex.Text = Utils.sexSymbol(c.gender); checkBoxSex.Checked = true; tt.SetToolTip(buttonSex, "Sex: " + c.gender.ToString()); }
public void setCreature(Creature creature) { this.creature = creature; groupBox1.Text = (!onlyLevels && creature.status != CreatureStatus.Available ? "(" + Utils.statusSymbol(creature.status) + ") " : "") + creature.name + " (" + creature.levelHatched + (totalLevelUnknown ? "+" : "") + ")"; if (!onlyLevels && creature.status == CreatureStatus.Dead) { groupBox1.ForeColor = SystemColors.GrayText; tt.SetToolTip(groupBox1, "Creature has passed away"); } else if (!onlyLevels && creature.status == CreatureStatus.Unavailable) { groupBox1.ForeColor = SystemColors.GrayText; tt.SetToolTip(groupBox1, "Creature is currently not available"); } for (int s = 0; s < 7; s++) { if (creature.levelsWild[s] < 0) { labels[s].Text = "?"; labels[s].BackColor = Color.WhiteSmoke; labels[s].ForeColor = Color.LightGray; } else { labels[s].Text = creature.levelsWild[s].ToString(); labels[s].BackColor = Utils.getColorFromPercent((int)(creature.levelsWild[s] * 2.5), (creature.topBreedingStats[s] ? 0.2 : 0.7)); labels[s].ForeColor = SystemColors.ControlText; tt.SetToolTip(labels[s], Utils.statName(s) + ": " + (creature.valuesBreeding[s] * (Utils.precision(s) == 3 ? 100 : 1)).ToString() + (Utils.precision(s) == 3 ? "%" : "")); } labels[s].Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, (creature.topBreedingStats[s] ? System.Drawing.FontStyle.Bold : System.Drawing.FontStyle.Regular), System.Drawing.GraphicsUnit.Point, ((byte)(0))); } if (onlyLevels) { labelSex.Visible = false; pictureBox1.Visible = false; plainTextcurrentValuesToolStripMenuItem.Visible = false; aRKChatcurrentValuesToolStripMenuItem.Visible = false; } else { labelSex.Visible = true; labelSex.Text = Utils.sexSymbol(creature.gender); labelSex.BackColor = creature.neutered ? SystemColors.GrayText : Utils.sexColor(creature.gender); // creature Colors pictureBox1.Image = CreatureColored.getColoredCreature(creature.colors, "", enabledColorRegions, 24, 22, true); labelSex.Visible = true; pictureBox1.Visible = true; plainTextcurrentValuesToolStripMenuItem.Visible = true; aRKChatcurrentValuesToolStripMenuItem.Visible = true; } labelMutations.BackColor = Color.FromArgb(225, 192, 255); labelMutations.Text = creature.mutationCounter.ToString(); labelMutations.Visible = creature.mutationCounter > 0; contextMenuAvailable = true; }
public void updateLabel() { if (creature != null) { labelGender.Text = Utils.sexSymbol(creature.gender); groupBox1.Text = creature.name + " (Lvl " + creature.level + "/" + (creature.levelHatched + maxDomLevel) + ")"; if (creature.Mother != null || creature.Father != null) { labelParents.Text = ""; if (creature.Mother != null) { labelParents.Text = "Mo: " + creature.Mother.name; } if (creature.Father != null && creature.Mother != null) { labelParents.Text += "; "; } if (creature.Father != null) { labelParents.Text += "Fa: " + creature.Father.name; } } else if (creature.isBred) { labelParents.Text = "bred, click 'edit' to add parents"; } else { labelParents.Text = "found wild " + creature.levelFound + (creature.tamingEff >= 0 ? ", tamed with TE: " + (creature.tamingEff * 100).ToString("N1") + "%" : ", TE unknown."); } for (int s = 0; s < 8; s++) { updateStat(s); } labelNotes.Text = creature.note; labelSpecies.Text = creature.species; pictureBox1.Image = CreatureColored.getColoredCreature(creature.colors, creature.species, colorRegionUseds); pictureBox1.Visible = true; for (int c = 0; c < 6; c++) { if (colorRegionUseds[c]) { setColorButton(colorButtons[c], Utils.creatureColor(creature.colors[c])); tt.SetToolTip(colorButtons[c], colorRegions[c].name); colorButtons[c].Visible = true; } else { colorButtons[c].Visible = false; } } } }
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(); }
private void buttonSex_Click(object sender, EventArgs e) { sex = Utils.nextSex(sex); buttonSex.Text = Utils.sexSymbol(sex); }
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(); }
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(); }