/// <summary> /// Set text of labels for stats. Only used for header control. /// </summary> public void SetCustomStatNames(Dictionary <string, string> customStatNames = null) { for (int s = 0; s < displayedStatsCount; s++) { labels[s].Text = Utils.StatName(displayedStats[s], true, customStatNames); tt.SetToolTip(labels[s], Utils.StatName(displayedStats[s], customStatNames: customStatNames)); } }
private void setLocalizations(bool init = true) { if (init) initLocalization(); // menu Loc.ControlText(fileToolStripMenuItem); Loc.ControlText(newToolStripMenuItem); Loc.ControlText(loadToolStripMenuItem); Loc.ControlText(loadAndAddToolStripMenuItem); Loc.ControlText(saveToolStripMenuItem); Loc.ControlText(saveAsToolStripMenuItem); Loc.ControlText(importingFromSavegameToolStripMenuItem); Loc.ControlText(importingFromSavegameEmptyToolStripMenuItem); //Loc.ControlText(runDefaultExtractionAndImportFileToolStripMenuItem); //Loc.ControlText(runDefaultExtractionToolStripMenuItem); //Loc.ControlText(importCreatedJsonfileToolStripMenuItem); Loc.ControlText(importExportedCreaturesToolStripMenuItem); //Loc.ControlText(runDefaultExtractionAndImportFileToolStripMenuItem); //Loc.ControlText(runDefaultExtractionToolStripMenuItem); //Loc.ControlText(importCreatedJsonfileToolStripMenuItem); Loc.ControlText(modValueManagerToolStripMenuItem); Loc.ControlText(settingsToolStripMenuItem); Loc.ControlText(openSettingsToolStripMenuItem); Loc.ControlText(quitToolStripMenuItem); Loc.ControlText(editToolStripMenuItem); Loc.ControlText(exportValuesToClipboardToolStripMenuItem); Loc.ControlText(importValuesFromClipboardToolStripMenuItem); Loc.ControlText(setStatusToolStripMenuItem); Loc.ControlText(multiSetterToolStripMenuItem); Loc.ControlText(deleteSelectedToolStripMenuItem); Loc.ControlText(findDuplicatesToolStripMenuItem); Loc.ControlText(copyCreatureToolStripMenuItem); Loc.ControlText(pasteCreatureToolStripMenuItem); Loc.ControlText(libraryFilterToolStripMenuItem); Loc.ControlText(helpToolStripMenuItem); Loc.ControlText(aboutToolStripMenuItem); Loc.ControlText(onlinehelpToolStripMenuItem); Loc.ControlText(BreedingPlanHelpToolStripMenuItem); Loc.ControlText(extractionIssuesToolStripMenuItem); Loc.ControlText(checkForUpdatedStatsToolStripMenuItem); Loc.ControlText(toolStripButtonCopy2Tester); Loc.ControlText(toolStripButtonCopy2Extractor); Loc.ControlText(toolStripButtonClear); Loc.ControlText(toolStripButtonAddNote); Loc.ControlText(toolStripButtonRemoveNote); Loc.ControlText(toolStripButtonDeleteExpiredIncubationTimers); Loc.ControlText(toolStripButtonSaveCreatureValuesTemp); Loc.ControlText(toolStripButtonDeleteTempCreature); Loc.ControlText(tsBtAddAsExtractionTest); Loc.ControlText(copyToMultiplierTesterToolStripButton); // top bar Loc.ControlText(cbGuessSpecies, _tt); Loc.ControlText(btReadValuesFromArk, _tt); Loc.ControlText(btImportLastExported, _tt); Loc.ControlText(cbToggleOverlay); // tester Loc.ControlText(tabPageStatTesting, "statTesting"); Loc.ControlText(rbWildTester, "wild"); Loc.ControlText(rbTamedTester, "tamed"); Loc.ControlText(rbBredTester, "bred"); Loc.ControlText(lbTesterWildLevel, "wildLvl"); Loc.ControlText(lbTesterDomLevel, "domLvl"); Loc.ControlText(lbCurrentValue, "currentValue"); Loc.ControlText(lbBreedingValueTester, "breedingValue"); Loc.ControlText(lbNotYetTamed); Loc.ControlText(gpPreviewEdit); Loc.ControlText(lbTestingInfo); Loc.ControlText(gbStatChart, "statChart"); Loc.ControlText(lbCurrentCreature, "CurrentCreature"); Loc.SetToolTip(lbImprintedCount, _tt); Loc.SetToolTip(lbTesterDomLevel, "domLevelExplanation", _tt); Loc.SetToolTip(lbTesterWildLevel, "wildLevelExplanation", _tt); // extractor Loc.ControlText(tabPageExtractor, "extractor"); Loc.ControlText(lbCurrentStatEx, "currentStatValue"); Loc.ControlText(lbExtractorWildLevel, "wildLvl"); Loc.ControlText(lbExtractorDomLevel, "domLvl"); Loc.ControlText(lbSum); Loc.ControlText(lbShouldBe); Loc.ControlText(lbImprintingFailInfo); Loc.ControlText(cbExactlyImprinting, _tt); Loc.ControlText(btExtractLevels); Loc.ControlText(cbQuickWildCheck, _tt); Loc.ControlText(rbWildExtractor, "wild"); Loc.ControlText(rbTamedExtractor, "tamed"); Loc.ControlText(rbBredExtractor, "bred"); Loc.SetToolTip(lbImprintingCuddleCountExtractor, _tt); Loc.SetToolTip(lbSumWild, _tt); Loc.SetToolTip(lbSumDom, _tt); Loc.SetToolTip(lbSumDomSB, _tt); Loc.SetToolTip(lbListening, _tt); Loc.SetToolTip(lbExtractorDomLevel, "domLevelExplanation", _tt); Loc.SetToolTip(lbExtractorWildLevel, "wildLevelExplanation", _tt); var statNames = speciesSelector1.SelectedSpecies?.statNames; for (int si = 0; si < _statIOs.Count; si++) { _statIOs[si].Title = Utils.StatName(si, false, statNames); _testingIOs[si].Title = Utils.StatName(si, false, statNames); } // library Loc.ControlText(tabPageLibrary, "library"); columnHeaderName.Text = Loc.S("Name"); columnHeaderOwner.Text = Loc.S("Owner"); columnHeaderTribe.Text = Loc.S("Tribe"); columnHeaderNote.Text = Loc.S("Note"); columnHeaderServer.Text = Loc.S("Server"); columnHeaderHP.Text = Utils.StatName(StatNames.Health, true); columnHeaderSt.Text = Utils.StatName(StatNames.Stamina, true); columnHeaderOx.Text = Utils.StatName(StatNames.Oxygen, true); columnHeaderFo.Text = Utils.StatName(StatNames.Food, true); columnHeaderWe.Text = Utils.StatName(StatNames.Weight, true); columnHeaderDm.Text = Utils.StatName(StatNames.MeleeDamageMultiplier, true); columnHeaderSp.Text = Utils.StatName(StatNames.SpeedMultiplier, true); columnHeaderTo.Text = Utils.StatName(StatNames.Torpidity, true); columnHeaderWa.Text = Utils.StatName(StatNames.CraftingSpeedMultiplier, true); columnHeaderTemp.Text = Utils.StatName(StatNames.Temperature, true); columnHeaderCr.Text = Utils.StatName(StatNames.Water, true); columnHeaderFr.Text = Utils.StatName(StatNames.TemperatureFortitude, true); columnHeaderTopStatsNr.Text = Loc.S("Top"); columnHeaderTopness.Text = Loc.S("topPercentage"); columnHeaderGen.Text = Loc.S("Generation_Abb"); columnHeaderLW.Text = Loc.S("LevelWild_Abb"); columnHeaderMutations.Text = Loc.S("Mutations_Abb"); columnHeaderAdded.Text = Loc.S("added"); columnHeaderCooldown.Text = Loc.S("cooldownGrowing"); columnHeaderColor0.Text = Loc.S("C0"); columnHeaderColor1.Text = Loc.S("C1"); columnHeaderColor2.Text = Loc.S("C2"); columnHeaderColor3.Text = Loc.S("C3"); columnHeaderColor4.Text = Loc.S("C4"); columnHeaderColor5.Text = Loc.S("C5"); // other tabs Loc.ControlText(tabPagePedigree, "pedigree"); Loc.ControlText(tabPageTaming, "Taming"); Loc.ControlText(tabPageBreedingPlan, "BreedingPlan"); Loc.ControlText(tabPageRaising, "Raising"); Loc.ControlText(tabPagePlayerTribes, "Player"); // other controls creatureInfoInputTester.SetLocalizations(); creatureInfoInputExtractor.SetLocalizations(); pedigree1.SetLocalizations(); tamingControl1.SetLocalizations(); breedingPlan1.SetLocalizations(); }
/// <summary> /// Import exported file. Used by a fileWatcher. /// </summary> /// <param name="filePath"></param> private void ImportExportedAddIfPossible(string filePath) { bool alreadyExists = ExtractExportedFileInExtractor(filePath); bool added = false; bool copyNameToClipboard = Properties.Settings.Default.copyNameToClipboardOnImportWhenAutoNameApplied && (Properties.Settings.Default.applyNamePatternOnImportIfEmptyName || (!alreadyExists && Properties.Settings.Default.applyNamePatternOnAutoImportForNewCreatures)); Species species = speciesSelector1.SelectedSpecies; if (_extractor.uniqueResults || (alreadyExists && _extractor.validResults)) { AddCreatureToCollection(true, goToLibraryTab: false); SetMessageLabelText($"Successful {(alreadyExists ? "updated" : "added")} {creatureInfoInputExtractor.CreatureName} ({species.name}) of the exported file\n" + filePath, MessageBoxIcon.Information); added = true; } bool topLevels = false; bool newTopLevels = false; // give feedback in overlay string infoText; Color textColor; const int colorSaturation = 200; if (added) { var sb = new StringBuilder(); sb.AppendLine($"{species.name} \"{creatureInfoInputExtractor.CreatureName}\" {(alreadyExists ? "updated in " : "added to")} the library."); if (copyNameToClipboard) { sb.AppendLine("Name copied to clipboard."); } for (int s = 0; s < values.Values.STATS_COUNT; s++) { int statIndex = values.Values.statsDisplayOrder[s]; if (!species.UsesStat(statIndex)) { continue; } sb.Append($"{Utils.StatName(statIndex, true, species.IsGlowSpecies)}: {_statIOs[statIndex].LevelWild} ({_statIOs[statIndex].BreedingValue})"); if (_statIOs[statIndex].TopLevel == StatIOStatus.NewTopLevel) { sb.Append($" {Loc.S("newTopLevel")}"); newTopLevels = true; } else if (_statIOs[statIndex].TopLevel == StatIOStatus.TopLevel) { sb.Append($" {Loc.S("topLevel")}"); topLevels = true; } sb.AppendLine(); } infoText = sb.ToString(); textColor = Color.FromArgb(colorSaturation, 255, colorSaturation); } else { infoText = $"Creature \"{creatureInfoInputExtractor.CreatureName}\" couldn't be extracted uniquely, manual level selection is necessary."; textColor = Color.FromArgb(255, colorSaturation, colorSaturation); } _overlay?.SetInfoText(infoText, textColor); if (added) { if (Properties.Settings.Default.MoveAutoImportedFileToSubFolder) { string importedPath = Path.Combine(Path.GetDirectoryName(filePath), "imported"); if (!FileService.TryCreateDirectory(importedPath, out string errorMessage)) { MessageBox.Show($"Subfolder\n{importedPath}\ncould not be created.\n{errorMessage}", $"{Loc.S("error")} - {Utils.ApplicationNameVersion}", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } FileService.TryMoveFile(filePath, Path.Combine(importedPath, Path.GetFileName(filePath))); } else if (Properties.Settings.Default.DeleteAutoImportedFile) { FileService.TryDeleteFile(filePath); } } else if (copyNameToClipboard) { // extraction failed, user might expect the name of the new creature in the clipboard Clipboard.SetText("Automatic extraction was not possible"); } if (Properties.Settings.Default.PlaySoundOnAutoImport) { if (added) { if (newTopLevels) { Utils.BeepSignal(3); } else if (topLevels) { Utils.BeepSignal(2); } else { Utils.BeepSignal(1); } } else { Utils.BeepSignal(0); } } }
/// <summary> /// Import exported file. Used by a fileWatcher. /// </summary> /// <param name="filePath"></param> private void ImportExportedAddIfPossible(string filePath) { var loadResult = ExtractExportedFileInExtractor(filePath); if (!loadResult.HasValue) { return; } bool alreadyExists = loadResult.Value; bool added = false; bool copyNameToClipboard = Properties.Settings.Default.copyNameToClipboardOnImportWhenAutoNameApplied && (Properties.Settings.Default.applyNamePatternOnAutoImportAlways || Properties.Settings.Default.applyNamePatternOnImportIfEmptyName || (!alreadyExists && Properties.Settings.Default.applyNamePatternOnAutoImportForNewCreatures) ); Species species = speciesSelector1.SelectedSpecies; Creature creature = null; if (_extractor.UniqueResults || (alreadyExists && _extractor.ValidResults)) { creature = AddCreatureToCollection(true, goToLibraryTab: Properties.Settings.Default.AutoImportGotoLibraryAfterSuccess); SetMessageLabelText($"Successful {(alreadyExists ? "updated" : "added")} {creature.name} ({species.name}) of the exported file\n" + filePath, MessageBoxIcon.Information, filePath); added = true; } bool topLevels = false; bool newTopLevels = false; // give feedback in overlay string infoText; Color textColor; const int colorSaturation = 200; if (added) { var sb = new StringBuilder(); sb.AppendLine($"{species.name} \"{creature.name}\" {(alreadyExists ? "updated in " : "added to")} the library."); if (copyNameToClipboard) { sb.AppendLine("Name copied to clipboard."); } for (int s = 0; s < values.Values.STATS_COUNT; s++) { int statIndex = values.Values.statsDisplayOrder[s]; if (!species.UsesStat(statIndex)) { continue; } sb.Append($"{Utils.StatName(statIndex, true, species.statNames)}: { _statIOs[statIndex].LevelWild} ({_statIOs[statIndex].BreedingValue})"); if (_statIOs[statIndex].TopLevel == StatIOStatus.NewTopLevel) { sb.Append($" {Loc.S("newTopLevel")}"); newTopLevels = true; } else if (_statIOs[statIndex].TopLevel == StatIOStatus.TopLevel) { sb.Append($" {Loc.S("topLevel")}"); topLevels = true; } sb.AppendLine(); } infoText = sb.ToString(); textColor = Color.FromArgb(colorSaturation, 255, colorSaturation); } else { infoText = $"Creature \"{creatureInfoInputExtractor.CreatureName}\" couldn't be extracted uniquely, manual level selection is necessary."; textColor = Color.FromArgb(255, colorSaturation, colorSaturation); } if (_overlay != null) { _overlay.SetInfoText(infoText, textColor); if (Properties.Settings.Default.DisplayInheritanceInOverlay && creature != null) { _overlay.SetInheritanceCreatures(creature, creature.Mother, creature.Father); } } if (added) { if (Properties.Settings.Default.DeleteAutoImportedFile) { FileService.TryDeleteFile(filePath); } else if (Properties.Settings.Default.MoveAutoImportedFileToSubFolder || Properties.Settings.Default.AutoImportedExportFileRename) { string newPath = Properties.Settings.Default.MoveAutoImportedFileToSubFolder ? (string.IsNullOrEmpty(Properties.Settings.Default.ImportExportedArchiveFolder) ? Path.Combine(Path.GetDirectoryName(filePath), "imported") : Properties.Settings.Default.ImportExportedArchiveFolder) : Path.GetDirectoryName(filePath); if (Properties.Settings.Default.MoveAutoImportedFileToSubFolder && !FileService.TryCreateDirectory(newPath, out string errorMessage)) { MessageBoxes.ShowMessageBox($"Subfolder\n{newPath}\ncould not be created.\n{errorMessage}"); return; } string namePattern = Properties.Settings.Default.AutoImportedExportFileRenamePattern; string newFileName = Properties.Settings.Default.AutoImportedExportFileRename && !string.IsNullOrWhiteSpace(namePattern) ? NamePatterns.GenerateCreatureName(creature, _creatureCollection.creatures.Where(c => c.Species == speciesSelector1.SelectedSpecies).ToArray(), null, null, _customReplacingNamingPattern, false, -1, false, namePattern) : Path.GetFileName(filePath); string newFileNameWithoutExtension = Path.GetFileNameWithoutExtension(newFileName); string newFileNameExtension = Path.GetExtension(newFileName); string newFilePath = Path.Combine(newPath, newFileName); int fileSuffix = 1; while (File.Exists(newFilePath)) { newFilePath = Path.Combine(newPath, $"{newFileNameWithoutExtension}_{++fileSuffix}{newFileNameExtension}"); } if (FileService.TryMoveFile(filePath, newFilePath)) { _librarySelectionInfoClickPath = newFilePath; } } } else if (copyNameToClipboard) { // extraction failed, user might expect the name of the new creature in the clipboard Clipboard.SetText("Automatic extraction was not possible"); } if (Properties.Settings.Default.PlaySoundOnAutoImport) { if (added) { if (alreadyExists) { SoundFeedback.BeepSignal(SoundFeedback.FeedbackSounds.Indifferent); } if (newTopLevels) { SoundFeedback.BeepSignal(SoundFeedback.FeedbackSounds.Great); } else if (topLevels) { SoundFeedback.BeepSignal(SoundFeedback.FeedbackSounds.Good); } else { SoundFeedback.BeepSignal(SoundFeedback.FeedbackSounds.Success); } } else { SoundFeedback.BeepSignal(SoundFeedback.FeedbackSounds.Failure); } } }
/// <summary> /// Draws a chart with the given levels. /// </summary> /// <param name="levels">If null, the previous values are redrawn.</param> public void SetLevels(int[] levels = null) { if ((levels != null && levels.Length <= 6) || _maxR <= 5) { return; } Bitmap bmp = new Bitmap(Width, Height); using (Graphics g = Graphics.FromImage(bmp)) using (Pen penLine = new Pen(Color.FromArgb(128, 255, 255, 255))) using (var font = new Font("Microsoft Sans Serif", 8f)) { g.SmoothingMode = SmoothingMode.AntiAlias; // the indices of the displayed stats var levelIndices = new[] { (int)StatNames.Health, (int)StatNames.Stamina, (int)StatNames.Oxygen, (int)StatNames.Food, (int)StatNames.Weight, (int)StatNames.MeleeDamageMultiplier, (int)StatNames.SpeedMultiplier }; for (int s = 0; s < levelIndices.Length; s++) { if (levels == null || levels[levelIndices[s]] != _oldLevels[s]) { if (levels != null) { _oldLevels[s] = levels[levelIndices[s]]; } int r = _oldLevels[s] * _maxR / _maxLevel; if (r < 0) { r = 0; } if (r > _maxR) { r = _maxR; } double angle = AnglePerStat * s - AngleOffset; _ps[s] = new Point(_xm + (int)(r * Math.Cos(angle)), _ym + (int)(r * Math.Sin(angle))); } } g.FillEllipse(_grBrushBg, _xm - _maxR, _ym - _maxR, 2 * _maxR + 1, 2 * _maxR + 1); g.FillPolygon(_grBrushFg, _ps.ToArray()); g.DrawPolygon(penLine, _ps.ToArray()); double stepFactor = (double)_step / _maxLevel; for (int r = 0; r < 5; r++) { using (var pen = new Pen(Utils.GetColorFromPercent((int)(100 * r * stepFactor), -0.4))) g.DrawEllipse(pen, (int)(_xm - _maxR * r * stepFactor), (int)(_ym - _maxR * r * stepFactor), (int)(2 * _maxR * r * stepFactor + 1), (int)(2 * _maxR * r * stepFactor + 1)); } using (var pen = new Pen(Utils.GetColorFromPercent(100, -0.4))) g.DrawEllipse(pen, _xm - _maxR, _ym - _maxR, 2 * _maxR + 1, 2 * _maxR + 1); using (var pen = new Pen(Color.Gray)) for (int s = 0; s < levelIndices.Length; s++) { pen.Width = 1; pen.Color = Color.Gray; g.DrawLine(pen, _xm, _ym, _maxPs[s].X, _maxPs[s].Y); Color cl = Utils.GetColorFromPercent(100 * _oldLevels[s] / _maxLevel); pen.Color = cl; pen.Width = 3; g.DrawLine(pen, _xm, _ym, _ps[s].X, _ps[s].Y); Brush b = new SolidBrush(cl); g.FillEllipse(b, _ps[s].X - 4, _ps[s].Y - 4, 8, 8); g.DrawEllipse(penLine, _ps[s].X - 4, _ps[s].Y - 4, 8, 8); b.Dispose(); } using (var brush = new SolidBrush(Color.FromArgb(190, 255, 255, 255))) { for (int r = 1; r < 5; r++) { g.DrawString((_step * r).ToString("N0"), font, brush, _xm - 8, _ym - 6 + r * _maxR / 5); } g.DrawString((_maxLevel).ToString("N0"), font, brush, _xm - 8, _ym - 11 + _maxR); } g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; using (var brushBlack = new SolidBrush(Color.Black)) { for (int s = 0; s < levelIndices.Length; s++) { double angle = AnglePerStat * s - AngleOffset; g.DrawString(Utils.StatName(levelIndices[s], true), font, brushBlack, _xm - 9 + (int)((_maxR + 10) * Math.Cos(angle)), _ym - 5 + (int)((_maxR + 10) * Math.Sin(angle))); } } } Image?.Dispose(); Image = bmp; }
public void setLevels(int[] levels) { if (levels != null && levels.Length > 6 && maxR > 5) { Bitmap bmp = new Bitmap(Width, Height); Graphics g = Graphics.FromImage(bmp); g.SmoothingMode = SmoothingMode.AntiAlias; const double angleSeven = Math.PI / 3.5; const double offset = Math.PI / 2; // the indices of the displayed stats var levelIndices = new int[] { (int)StatNames.Health, (int)StatNames.Stamina, (int)StatNames.Oxygen, (int)StatNames.Food, (int)StatNames.Weight, (int)StatNames.MeleeDamageMultiplier, (int)StatNames.SpeedMultiplier }; for (int s = 0; s < levelIndices.Length; s++) { if (levels[levelIndices[s]] != oldLevels[s]) { oldLevels[s] = levels[levelIndices[s]]; int r = oldLevels[s] * maxR / maxLevel; if (r < 0) { r = 0; } if (r > maxR) { r = maxR; } double angle = angleSeven * s - offset; ps[s] = new Point(xm + (int)(r * Math.Cos(angle)), ym + (int)(r * Math.Sin(angle))); } } g.FillEllipse(grBrushBG, xm - maxR, ym - maxR, 2 * maxR + 1, 2 * maxR + 1); Pen penL = new Pen(Color.FromArgb(128, 255, 255, 255)); g.FillPolygon(grBrushFG, ps.ToArray()); g.DrawPolygon(penL, ps.ToArray()); double stepFactor = (double)step / maxLevel; for (int r = 0; r < 5; r++) { g.DrawEllipse(new Pen(Utils.GetColorFromPercent((int)(100 * r * stepFactor), -0.4)), (int)(xm - maxR * r * stepFactor), (int)(ym - maxR * r * stepFactor), (int)(2 * maxR * r * stepFactor + 1), (int)(2 * maxR * r * stepFactor + 1)); } g.DrawEllipse(new Pen(Utils.GetColorFromPercent(100, -0.4)), xm - maxR, ym - maxR, 2 * maxR + 1, 2 * maxR + 1); Pen pen = new Pen(Color.Black); for (int s = 0; s < levelIndices.Length; s++) { pen.Width = 1; pen.Color = Color.Gray; g.DrawLine(pen, xm, ym, maxPs[s].X, maxPs[s].Y); Color cl = Utils.GetColorFromPercent(100 * oldLevels[s] / maxLevel); pen.Color = cl; pen.Width = 3; g.DrawLine(pen, xm, ym, ps[s].X, ps[s].Y); Brush b = new SolidBrush(cl); g.FillEllipse(b, ps[s].X - 4, ps[s].Y - 4, 8, 8); g.DrawEllipse(penL, ps[s].X - 4, ps[s].Y - 4, 8, 8); b.Dispose(); } for (int r = 1; r < 5; r++) { g.DrawString((step * r).ToString("N0"), new Font("Microsoft Sans Serif", 8f), new SolidBrush(Color.FromArgb(190, 255, 255, 255)), xm - 8, ym - 6 + r * maxR / 5); } g.DrawString((maxLevel).ToString("N0"), new Font("Microsoft Sans Serif", 8f), new SolidBrush(Color.FromArgb(190, 255, 255, 255)), xm - 8, ym - 11 + maxR); g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; for (int s = 0; s < levelIndices.Length; s++) { double angle = angleSeven * s - offset; g.DrawString(Utils.StatName(levelIndices[s], true), new Font("Microsoft Sans Serif", 8f), new SolidBrush(Color.Black), xm - 9 + (int)((maxR + 10) * Math.Cos(angle)), ym - 5 + (int)((maxR + 10) * Math.Sin(angle))); } g.Dispose(); Image = bmp; } }