public static ArcaneCodex Initialize() { var codex = new ArcaneCodex(); Console.WriteLine("Loading images from {0}...", Program.CurrentWorkingDirectory); codex.SubdomainCircle1 = Bitmap.FromFile(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Sub-Domain_1_(Optional)\Group_1.png")); codex.SubdomainCircle2 = Bitmap.FromFile(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Sub-Domain_2_(Optional)\Group_1_copy.png")); codex.SubdomainCircle3 = Bitmap.FromFile(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Sub-Domain_3_(Optional)\Group_1_copy_2.png")); codex.ArchformCircle = Bitmap.FromFile(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Techniques\Fire_Bonus_Form\Base_copy.png")); codex.ArchpraxisCircle = Bitmap.FromFile(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Techniques\Air_Bonus_Praxis\Base_copy_3.png")); codex.ArchsealCircle = Bitmap.FromFile(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Techniques\Water_Bonus_Seal\Base.png")); codex.ArchtheoremCircle = Bitmap.FromFile(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Techniques\Earth_Bonus_Theorem\Base_copy_2.png")); codex.Abstract = Bitmap.FromFile(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Abstract\Base.png")); foreach (var elementFile in Directory.GetFiles(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Elements"))) { codex.Elements.Add(Path.GetFileNameWithoutExtension(elementFile).ToLower(), Bitmap.FromFile(elementFile)); } foreach (var durationFile in Directory.GetFiles(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Number_Symbols\Duration"))) { codex.Durations.Add(Path.GetFileNameWithoutExtension(durationFile), Bitmap.FromFile(durationFile)); } foreach (var powerFile in Directory.GetFiles(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Number_Symbols\Power"))) { codex.Powers.Add(Path.GetFileNameWithoutExtension(powerFile), Bitmap.FromFile(powerFile)); } foreach (var rangeFile in Directory.GetFiles(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Number_Symbols\Range"))) { codex.Ranges.Add(Path.GetFileNameWithoutExtension(rangeFile), Bitmap.FromFile(rangeFile)); } foreach (var domainFile in Directory.GetFiles(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Domain"))) { codex.Domains.Add(Path.GetFileNameWithoutExtension(domainFile).ToLower(), Bitmap.FromFile(domainFile)); } foreach (var subdomainFile1 in Directory.GetFiles(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Sub-Domain_1_(Optional)"))) { codex.Subdomains1.Add(Path.GetFileNameWithoutExtension(subdomainFile1).ToLower(), Bitmap.FromFile(subdomainFile1)); } foreach (var subdomainFile2 in Directory.GetFiles(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Sub-Domain_2_(Optional)"))) { codex.Subdomains2.Add(Path.GetFileNameWithoutExtension(subdomainFile2).ToLower(), Bitmap.FromFile(subdomainFile2)); } foreach (var subdomainFile3 in Directory.GetFiles(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Sub-Domain_3_(Optional)"))) { codex.Subdomains3.Add(Path.GetFileNameWithoutExtension(subdomainFile3).ToLower(), Bitmap.FromFile(subdomainFile3)); } foreach (var typeFile in Directory.GetFiles(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Type"))) { codex.Types.Add(Path.GetFileNameWithoutExtension(typeFile).ToLower(), Bitmap.FromFile(typeFile)); } // Technique loading foreach (var techniqueDir in Directory.GetDirectories(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Techniques\Forms"))) { codex.Techniques.Add(techniqueDir.Split(Path.DirectorySeparatorChar).Last().ToLower(), new Technique { Type = "Form", Images = Directory.GetFiles(techniqueDir).Select(d => Bitmap.FromFile(d)).ToList() }); } foreach (var techniqueDir in Directory.GetDirectories(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Techniques\Praxes"))) { codex.Techniques.Add(techniqueDir.Split(Path.DirectorySeparatorChar).Last().ToLower(), new Technique { Type = "Praxis", Images = Directory.GetFiles(techniqueDir).Select(d => Bitmap.FromFile(d)).ToList() }); } foreach (var techniqueDir in Directory.GetDirectories(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Techniques\Seals"))) { codex.Techniques.Add(techniqueDir.Split(Path.DirectorySeparatorChar).Last().ToLower(), new Technique { Type = "Seal", Images = Directory.GetFiles(techniqueDir).Select(d => Bitmap.FromFile(d)).ToList() }); } foreach (var techniqueDir in Directory.GetDirectories(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Techniques\Theorems"))) { codex.Techniques.Add(techniqueDir.Split(Path.DirectorySeparatorChar).Last().ToLower(), new Technique { Type = "Theorem", Images = Directory.GetFiles(techniqueDir).Select(d => Bitmap.FromFile(d)).ToList() }); } // Bonus technique loading foreach (var techniqueDir in Directory.GetDirectories(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Techniques\Earth_Bonus_Theorem"))) { codex.BonusTechniques.Add(techniqueDir.Split(Path.DirectorySeparatorChar).Last().ToLower(), new Technique { Type = "Theorem", Images = Directory.GetFiles(techniqueDir).Select(d => Bitmap.FromFile(d)).ToList() }); } foreach (var techniqueDir in Directory.GetDirectories(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Techniques\Fire_Bonus_Form"))) { codex.BonusTechniques.Add(techniqueDir.Split(Path.DirectorySeparatorChar).Last().ToLower(), new Technique { Type = "Form", Images = Directory.GetFiles(techniqueDir).Select(d => Bitmap.FromFile(d)).ToList() }); } foreach (var techniqueDir in Directory.GetDirectories(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Techniques\Air_Bonus_Praxis"))) { codex.BonusTechniques.Add(techniqueDir.Split(Path.DirectorySeparatorChar).Last().ToLower(), new Technique { Type = "Praxis", Images = Directory.GetFiles(techniqueDir).Select(d => Bitmap.FromFile(d)).ToList() }); } foreach (var techniqueDir in Directory.GetDirectories(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Techniques\Water_Bonus_Seal"))) { codex.BonusTechniques.Add(techniqueDir.Split(Path.DirectorySeparatorChar).Last().ToLower(), new Technique { Type = "Seal", Images = Directory.GetFiles(techniqueDir).Select(d => Bitmap.FromFile(d)).ToList() }); } foreach (var abstractImageDir in Directory.GetDirectories(Path.Combine(Program.CurrentWorkingDirectory, @"Layers\Spell_Building\Abstract"))) { codex.AbstractImages.Add(Directory.GetFiles(abstractImageDir).Select(f => Bitmap.FromFile(f)).ToList()); } return(codex); }
static void Main(string[] args) { // build cwd CurrentWorkingDirectory = Environment.CurrentDirectory; //var cwd = Environment.CurrentDirectory; //var tokens = cwd.Split(Path.DirectorySeparatorChar); //CurrentWorkingDirectory = string.Join(Path.DirectorySeparatorChar.ToString(), // tokens.Take(tokens.Length - 3)); // back three Console.WriteLine("Please select a sheet to parse:"); var fd = new OpenFileDialog(); fd.DefaultExt = ".csv"; var fdResult = fd.ShowDialog(); if (fdResult != DialogResult.OK) { Environment.Exit(-1); } Console.WriteLine("Parsing: {0}...", fd.FileName); var engine = new FileHelperEngine <RawSpell>(); var results = engine.ReadFile(fd.FileName); var spells = new List <Spell>(); foreach (var result in results.Skip(1)) { if (string.IsNullOrEmpty(result.SpellName)) { continue; } var spell = new Spell { SpellMechanics = result.SpellMechanics, SpellName = result.SpellName, Power = Int32.Parse(result.P), Range = Int32.Parse(result.R), Duration = Int32.Parse(result.D), Element = result.Element, Key = result.Element + "/" + result.Group, Complexity = Int32.Parse(result.Complex), Techniques = SortTechniques(ParseSplit(result.Techniques, ',')), Adjuncts = ParseSplit(result.Adjuncts, ','), Fallacies = ParseSplit(result.Fallacies, ','), Domains = ParseSplit(result.Domains, '/'), Type = result.Type.Trim(' ') }; spells.Add(spell); } Console.WriteLine("Done."); Console.WriteLine("Loading arcane codex..."); var codex = ArcaneCodex.Initialize(); Console.WriteLine("Done."); Console.WriteLine("Loading fonts..."); var gothicFonts = new PrivateFontCollection(); gothicFonts.AddFontFile(Path.Combine(CurrentWorkingDirectory, @"AquilineTwo.ttf")); gothicFonts.AddFontFile(Path.Combine(CurrentWorkingDirectory, @"Of Wildflowers and Wings 2.ttf")); var aquilineTwoFont = new Font(gothicFonts.Families[0], 18f); var complexityFont = new Font(gothicFonts.Families[1], 36); var fallacyFont = new Font(gothicFonts.Families[1], 30, FontStyle.Bold); var mechanicsFont = new Font(gothicFonts.Families[1], 26); Console.WriteLine("Done."); Console.WriteLine("Generating spells..."); var background = Bitmap.FromFile(Path.Combine(CurrentWorkingDirectory, @"Layers\Background.png")); var source1 = Bitmap.FromFile(Path.Combine(CurrentWorkingDirectory, @"Layers\Clear_Base_v2_-_No_Touchy.png")); // your source images - assuming they're the same size var aurumSource = Bitmap.FromFile(Path.Combine(CurrentWorkingDirectory, @"Layers\Aurum_Clear_Base_v2_-_No_Touchy.png")); // your source images - assuming they're the same size var source2 = Bitmap.FromFile(Path.Combine(CurrentWorkingDirectory, @"Layers\Layer_121.png")); var source3 = Bitmap.FromFile(Path.Combine(CurrentWorkingDirectory, @"Layers\~What_is_written_here_can_only_be_understood_if_you_have_Magic.png")); var source4 = Bitmap.FromFile(Path.Combine(CurrentWorkingDirectory, @"Layers\Thesis.png")); var outputDir = Path.Combine(CurrentWorkingDirectory, "Output"); foreach (var spell in spells) { Image arrayBase; if (spell.Fallacies.Any(s => s.Contains("Aurum"))) { arrayBase = aurumSource; } else { arrayBase = source1; } if (!Directory.Exists(Path.Combine(outputDir, spell.Key))) { Directory.CreateDirectory(Path.Combine(outputDir, spell.Key)); } var filename = Path.Combine(Path.Combine(outputDir, spell.Key), spell.SpellName + ".png"); var target = new Bitmap(arrayBase.Width, arrayBase.Height, PixelFormat.Format32bppArgb); var graphics = Graphics.FromImage(target); graphics.CompositingMode = CompositingMode.SourceOver; // this is the default, but just to be clear // ------------------------------------------ // Ensure the best possible quality rendering // ------------------------------------------ // The smoothing mode specifies whether lines, curves, and the edges of filled areas use smoothing (also called antialiasing). // One exception is that path gradient brushes do not obey the smoothing mode. // Areas filled using a PathGradientBrush are rendered the same way (aliased) regardless of the SmoothingMode property. graphics.SmoothingMode = SmoothingMode.AntiAlias; // The interpolation mode determines how intermediate values between two endpoints are calculated. graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; // Use this property to specify either higher quality, slower rendering, or lower quality, faster rendering of the contents of this Graphics object. graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; // This one is important graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; graphics.DrawImage(background, 0, 0); graphics.DrawImage(arrayBase, 0, 0); graphics.DrawImage(source2, 0, 0); graphics.DrawImage(source3, 0, 0); graphics.DrawImage(source4, 0, 0); graphics.DrawImage(codex.Elements[spell.Element.ToLower()], 0, 0); graphics.DrawImage(codex.Durations[spell.Duration.ToString()], 0, 0); graphics.DrawImage(codex.Powers[spell.Power.ToString()], 0, 0); graphics.DrawImage(codex.Ranges[spell.Range.ToString()], 0, 0); if (!codex.Types.ContainsKey(spell.Type.ToLower())) { throw new Exception("Could not find spell type: " + spell.Type); } graphics.DrawImage(codex.Types[spell.Type.ToLower()], 0, 0); var domain = codex.Domains.Keys.FirstOrDefault(k => k.Contains(spell.Domains[0].ToLower())); if (domain == null) { throw new Exception("Couldn't find domain: " + spell.Domains[0]); } graphics.DrawImage(codex.Domains[domain], 0, 0); if (spell.Domains.Length > 1) { graphics.DrawImage(codex.SubdomainCircle1, 0, 0); var subdomain = codex.Domains.Keys.FirstOrDefault(k => k.Contains(spell.Domains[1].ToLower())); if (subdomain == null) { throw new Exception("Couldn't find domain: " + spell.Domains[1]); } graphics.DrawImage(codex.Subdomains1[subdomain], 0, 0); } if (spell.Domains.Length > 2) { graphics.DrawImage(codex.SubdomainCircle2, 0, 0); var subdomain = codex.Domains.Keys.FirstOrDefault(k => k.Contains(spell.Domains[2].ToLower())); if (subdomain == null) { throw new Exception("Couldn't find domain: " + spell.Domains[2]); } graphics.DrawImage(codex.Subdomains2[subdomain], 0, 0); } if (spell.Domains.Length > 3) { graphics.DrawImage(codex.SubdomainCircle3, 0, 0); var subdomain = codex.Domains.Keys.FirstOrDefault(k => k.Contains(spell.Domains[3].ToLower())); if (subdomain == null) { throw new Exception("Couldn't find domain: " + spell.Domains[3]); } graphics.DrawImage(codex.Subdomains3[subdomain], 0, 0); } if (spell.Techniques.Length > 0) { var techniqueCount = new Dictionary <string, int> { { "Form", 0 }, { "Praxis", 0 }, { "Seal", 0 }, { "Theorem", 0 } }; foreach (var techniqueName in spell.Techniques) { var cleansedName = techniqueName.Last(':').Replace("Form", "").Replace("Praxis", "") .Trim(' ').ToLower().Replace(' ', '_'); if (techniqueName.Contains("Domain Specialization")) // domain spec hack { cleansedName = "domain_specialization"; } var techniqueKey = codex.Techniques.Keys.FirstOrDefault(k => k.Contains(cleansedName)); if (techniqueKey == null) { if (techniqueName.ToLower().StartsWith("arch")) { Console.WriteLine("[WARNING] {0} for spell {1} should be in the adjuncts column.", techniqueName, spell.SpellName); continue; } Console.WriteLine("[WARNING] Could not find technique " + techniqueName); continue; } var technique = codex.Techniques[techniqueKey]; techniqueCount[technique.Type] += 1; if (techniqueCount[technique.Type] < 2) { foreach (var image in technique.Images) { graphics.DrawImage(image, 0, 0); } } else { switch (technique.Type) { case "Form": graphics.DrawImage(codex.ArchformCircle, 0, 0); break; case "Theorem": graphics.DrawImage(codex.ArchtheoremCircle, 0, 0); break; case "Praxis": graphics.DrawImage(codex.ArchpraxisCircle, 0, 0); break; case "Seal": graphics.DrawImage(codex.ArchsealCircle, 0, 0); break; } var bonusTechnique = codex.BonusTechniques[techniqueKey]; foreach (var image in bonusTechnique.Images) { graphics.DrawImage(image, 0, 0); } } } } // Create string formatting options (used for alignment) StringFormat format = new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }; // Spell Name graphics.DrawString(spell.SpellName, aquilineTwoFont, Brushes.Black, new RectangleF(230, 43, 500, 35), format); // Mechanics Text var mechanicsText = new StringBuilder(spell.SpellMechanics); if (spell.Adjuncts.Length > 0) { mechanicsText.AppendLine(Environment.NewLine); mechanicsText.AppendLine("Adjuncts: " + string.Join(", ", spell.Adjuncts)); } if (spell.Techniques.Length > 0) { mechanicsText.AppendLine(Environment.NewLine); mechanicsText.AppendLine("Techniques: " + string.Join(", ", spell.Techniques)); } graphics.DrawString(mechanicsText.ToString(), mechanicsFont, Brushes.Black, new RectangleF(100, 1040, 750, 220), format); // Complexity graphics.DrawString(spell.Complexity.ToString(), complexityFont, Brushes.Black, new RectangleF(422, 556, 110, 60), format); if (spell.Fallacies.Length > 0) { DrawCurvedText(graphics, string.Join(", ", spell.Fallacies.Take(2)), new Point(480, 480), 427, 3.6f, fallacyFont, Brushes.Black); } if (spell.Fallacies.Length > 2) { DrawCurvedText(graphics, string.Join(", ", spell.Fallacies.Skip(2).Take(2)), new Point(480, 480), 427, 2.65f, fallacyFont, Brushes.Black); } if (spell.Fallacies.Contains("Abstract")) { var random = new Random(spell.SpellName.GetHashCode()); graphics.DrawImage(codex.Abstract, 0, 0); foreach (var abstractImageSet in codex.AbstractImages) { graphics.DrawImage(abstractImageSet[random.Next(0, abstractImageSet.Count - 1)], 0, 0); } } target.Save(filename, ImageFormat.Png); } Console.WriteLine("Generated {0} spells.", spells.Count); Console.WriteLine("Parser complete. Press any key to exit."); Console.ReadKey(); }