Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Text;
- namespace D2MonsterAuxParser
- {
- public class Program
- {
- public static string[] SplitAggregateData(string data)
- {
- data = data.Replace(" ", ""); // Remove spaces
- data = data.Replace(",", ""); // Remove Commas (they exist for some pages and not others)
- data = data.Trim(); // This may not be needed.
- return data.Split('/');
- }
- public static string[] SplitTreasureClassData(string data)
- {
- data = data.Replace(" ", ""); // Remove spaces
- data = data.Trim(); // This may not be needed.
- string[] split = data.Split(',');
- return new string[] {
- split[0].Split('/')[0].Trim(),
- split[1].Split('/')[0].Trim(),
- split[2].Split('/')[0].Trim(),
- };
- }
- public static string[] ParseBlockData(string data)
- {
- // D2 Blocking data is basically a cluster fuck.
- data = data.Trim();
- data = data.Replace("--", "0");
- data = data.Replace("%", "");
- if (data.Equals("0"))
- {
- return new string[] { "0", "0", "0" };
- }
- int count = 0;
- foreach (char character in data)
- {
- if (character == '/')
- {
- count++;
- }
- }
- if (count == 0)
- {
- // Blocking is universal for all difficulties
- return new string[] { data, data, data };
- }
- if (count == 2)
- {
- // There are three separate blocking values; one for each difficulty
- string[] split = data.Split("/");
- return new string[] {
- split[0],
- split[1],
- split[2] };
- }
- // Throw an error, because there is an edge case we're not prepared for!
- throw new Exception("Blocking edge case detected!");
- }
- public static void Main(string[] args)
- {
- bool isDebugging = false;
- bool filterNullData = false;
- Dictionary<string, string> auxData = new Dictionary<string, string>();
- StringBuilder builder = new StringBuilder();
- /**
- * Get the monster base type from the user; this can be null
- */
- Console.WriteLine("Enter the monster base type:");
- Console.WriteLine("NOTE: For Unique Monsters, this should be left NULL");
- Console.WriteLine("(Enter 'null' to skip)");
- string input = Console.ReadLine();
- if (!input.Equals("null"))
- {
- auxData.Add("ibasename",input.Trim());
- }
- else
- {
- auxData.Add("ibasename","0");
- }
- /**
- * Parse Statistics: Name, Level Experience, Hit Points, Speed, and Max TC
- */
- Console.WriteLine("Input First Row 'Statistics' Data: ");
- input = Console.ReadLine();
- string[] firstRowSegments = input.Split('_');
- // Name
- auxData.Add("imvariant_name", firstRowSegments[0].Trim());
- // Level
- string[] splitCache = SplitAggregateData(firstRowSegments[1]);
- auxData.Add("imlvl_norm", splitCache[0]);
- auxData.Add("imlvl_night", splitCache[1]);
- auxData.Add("imlvl_hell", splitCache[2]);
- // Max TC
- splitCache = SplitTreasureClassData(firstRowSegments[5]);
- auxData.Add("imtrclass_norm", splitCache[0]);
- auxData.Add("imtrclass_night", splitCache[1]);
- auxData.Add("imtrclass_hell", splitCache[2]);
- // Experience
- splitCache = SplitAggregateData(firstRowSegments[2]);
- auxData.Add("imxp_norm", splitCache[0]);
- auxData.Add("imxp_night", splitCache[1]);
- auxData.Add("imxp_hell", splitCache[2]);
- // Hitpoints
- splitCache = SplitAggregateData(firstRowSegments[3]);
- auxData.Add("imhp_norm", splitCache[0]);
- auxData.Add("imhp_night", splitCache[1]);
- auxData.Add("imhp_hell", splitCache[2]);
- // Speed (Unused for Diablo2.io
- // We won't parse it because we don't need to
- /**
- * Parse Defenses: Defense, Blocking, Regen Rate, Drain Effectiveness, Chill Effectiveness
- */
- Console.WriteLine("Input Second Row 'Defense' Data:");
- input = Console.ReadLine();
- string[] secondRowSegments = input.Split('_');
- // Defense
- splitCache = SplitAggregateData(secondRowSegments[0]);
- auxData.Add("imdefense_norm", splitCache[0]);
- auxData.Add("imdefense_night", splitCache[1]);
- auxData.Add("imdefense_hell", splitCache[2]);
- // Blocking
- splitCache = ParseBlockData(secondRowSegments[1]);
- auxData.Add("imblock_norm", splitCache[0]);
- auxData.Add("imblock_night", splitCache[1]);
- auxData.Add("imblock_hell", splitCache[2]);
- // Regen Rate
- // We won't parse it because we don't need to
- // Drain Effectiveness
- splitCache = SplitAggregateData(secondRowSegments[3]);
- auxData.Add("imdrain_norm", splitCache[0]);
- auxData.Add("imdrain_night", splitCache[1]);
- auxData.Add("imdrain_hell", splitCache[2]);
- // Chill Effectiveness
- splitCache = SplitAggregateData(secondRowSegments[4]);
- auxData.Add("imchill_norm", splitCache[0]);
- auxData.Add("imchill_night", splitCache[1]);
- auxData.Add("imchill_hell", splitCache[2]);
- /**
- * Parse Resistances: Physical, Fire, Cold, Lightning, Poison, Magic
- */
- Console.WriteLine("Input Third Row 'Resistances' Data:");
- input = Console.ReadLine();
- string[] thirdRowSegments = input.Split('_');
- // Physical
- splitCache = SplitAggregateData(thirdRowSegments[0]);
- auxData.Add("imdmgres_norm", splitCache[0].Replace("%", ""));
- auxData.Add("imdmgres_night", splitCache[1].Replace("%", ""));
- auxData.Add("imdmgres_hell", splitCache[2].Replace("%", ""));
- // Fire
- splitCache = SplitAggregateData(thirdRowSegments[1]);
- auxData.Add("imfireres_norm", splitCache[0].Replace("%", ""));
- auxData.Add("imfireres_night", splitCache[1].Replace("%", ""));
- auxData.Add("imfireres_hell", splitCache[2].Replace("%", ""));
- // Cold
- splitCache = SplitAggregateData(thirdRowSegments[2]);
- auxData.Add("imcoldres_norm", splitCache[0].Replace("%", ""));
- auxData.Add("imcoldres_night", splitCache[1].Replace("%", ""));
- auxData.Add("imcoldres_hell", splitCache[2].Replace("%", ""));
- // Lightning
- splitCache = SplitAggregateData(thirdRowSegments[3]);
- auxData.Add("imlightres_norm", splitCache[0].Replace("%", ""));
- auxData.Add("imlightres_night", splitCache[1].Replace("%", ""));
- auxData.Add("imlightres_hell", splitCache[2].Replace("%", ""));
- // Poison
- splitCache = SplitAggregateData(thirdRowSegments[4]);
- auxData.Add("impoisres_norm", splitCache[0].Replace("%", ""));
- auxData.Add("impoisres_night", splitCache[1].Replace("%", ""));
- auxData.Add("impoisres_hell", splitCache[2].Replace("%", ""));
- // Magic
- splitCache = SplitAggregateData(thirdRowSegments[5]);
- auxData.Add("immagicres_norm", splitCache[0].Replace("%", ""));
- auxData.Add("immagicres_night", splitCache[1].Replace("%", ""));
- auxData.Add("immagicres_hell", splitCache[2].Replace("%", ""));
- /**
- * We need to manually input attack1 and attack2 as well as attackrating1 and attackrating2
- * because there are far too many ways of inputing this data, and it's nearly
- * impossible, if not literally impossible to parse.
- */
- Console.WriteLine("Input Attack1 Damage and Attack Rating (Enter 'null' to skip)");
- Console.WriteLine("Format Hint: 'DamageNormal/DamageNightmare/DamageHell_ARNormal/ARNightmare/ARHell'");
- Console.WriteLine("Format Example: '1-4/1-4/1-4_20/20/20'");
- input = Console.ReadLine();
- if (!input.Equals("null"))
- {
- string[] attack1DamAndARSegments = input.Split("_");
- // Attack1 Damage
- splitCache = SplitAggregateData(attack1DamAndARSegments[0]);
- auxData.Add("imattack1_norm", splitCache[0].Replace(",", "").Trim());
- auxData.Add("imattack1_night", splitCache[1].Replace(",", "").Trim());
- auxData.Add("imattack1_hell", splitCache[2].Replace(",", "").Trim());
- // Attack1 Attack Rating
- splitCache = SplitAggregateData(attack1DamAndARSegments[1]);
- auxData.Add("imrating1_norm", splitCache[0].Replace(",", "").Trim());
- auxData.Add("imrating1_night", splitCache[1].Replace(",", "").Trim());
- auxData.Add("imrating1_hell", splitCache[2].Replace(",", "").Trim());
- }
- else
- {
- // Fill in null data
- auxData.Add("imattack1_norm", "0");
- auxData.Add("imattack1_night", "0");
- auxData.Add("imattack1_hell", "0");
- auxData.Add("imrating1_norm", "0");
- auxData.Add("imrating1_night", "0");
- auxData.Add("imrating1_hell", "0");
- }
- Console.WriteLine("Input Attack1 Damage and Attack Rating (Enter 'null' to skip)");
- Console.WriteLine("Format Hint: 'DamageNormal/DamageNightmare/DamageHell_ARNormal/ARNightmare/ARHell'");
- Console.WriteLine("Format Example: '1-4/1-4/1-4_20/20/20'");
- input = Console.ReadLine();
- if (!input.Equals("null"))
- {
- string[] attack2DamAndARSegments = input.Split("_");
- // Attack2 Damage
- splitCache = SplitAggregateData(attack2DamAndARSegments[0]);
- auxData.Add("imattack2_norm", splitCache[0].Replace(",", "").Trim());
- auxData.Add("imattack2_night", splitCache[1].Replace(",", "").Trim());
- auxData.Add("imattack2_hell", splitCache[2].Replace(",", "").Trim());
- // Attack2 Attack Rating
- splitCache = SplitAggregateData(attack2DamAndARSegments[1]);
- auxData.Add("imrating2_norm", splitCache[0].Replace(",", "").Trim());
- auxData.Add("imrating2_night", splitCache[1].Replace(",", "").Trim());
- auxData.Add("imrating2_hell", splitCache[2].Replace(",", "").Trim());
- }
- else
- {
- // Fill in null data
- auxData.Add("imattack2_norm", "0");
- auxData.Add("imattack2_night", "0");
- auxData.Add("imattack2_hell", "0");
- auxData.Add("imrating2_norm", "0");
- auxData.Add("imrating2_night", "0");
- auxData.Add("imrating2_hell", "0");
- }
- /**
- * Next, we need to parse for immunities using the data we already gained.
- * If any resistance is greater than or equal to 100, we treat it as an immunity.
- * This seems to be standard in all the tables I looked at.
- */
- #region Automagically Detect Immunity Shenanigans
- string normalImmunity = "0";
- string nightmareImmunity = "0";
- string hellImmunity1 = "0";
- string hellImmunity2 = "0";
- foreach (KeyValuePair<string, string> pair in auxData)
- {
- switch (pair.Key)
- {
- case "imdmgres_norm":
- case "immagicres_norm":
- case "imfireres_norm":
- case "imcoldres_norm":
- case "imlightres_norm":
- case "impoisres_norm":
- if (normalImmunity.Equals("0"))
- {
- if (pair.Value.StartsWith("-"))
- {
- // The resistance is negative
- continue;
- }
- else
- {
- if (Int32.TryParse(pair.Value, out int normalResistance))
- {
- if (normalResistance >= 100)
- {
- switch (pair.Key)
- {
- case "imdmgres_norm":
- normalImmunity = "Physical";
- break;
- case "immagicres_norm":
- normalImmunity = "Magic";
- break;
- case "imfireres_norm":
- normalImmunity = "Fire";
- break;
- case "imcoldres_norm":
- normalImmunity = "Cold";
- break;
- case "imlightres_norm":
- normalImmunity = "Lightning";
- break;
- case "impoisres_norm":
- normalImmunity = "Poison";
- break;
- default:
- break; // Should never happen.
- }
- }
- }
- }
- }
- break;
- case "imdmgres_night":
- case "immagicres_night":
- case "imfireres_night":
- case "imcoldres_night":
- case "imlightres_night":
- case "impoisres_night":
- if (nightmareImmunity.Equals("0"))
- {
- if (pair.Value.StartsWith("-"))
- {
- // The resistance is negative
- continue;
- }
- else
- {
- if (Int32.TryParse(pair.Value, out int nightmareResistance))
- {
- if (nightmareResistance >= 100)
- {
- switch (pair.Key)
- {
- case "imdmgres_night":
- nightmareImmunity = "Physical";
- break;
- case "immagicres_night":
- nightmareImmunity = "Magic";
- break;
- case "imfireres_night":
- nightmareImmunity = "Fire";
- break;
- case "imcoldres_night":
- nightmareImmunity = "Cold";
- break;
- case "imlightres_night":
- nightmareImmunity = "Lightning";
- break;
- case "impoisres_night":
- nightmareImmunity = "Poison";
- break;
- default:
- break; // Should never happen.
- }
- }
- }
- }
- }
- break;
- case "imdmgres_hell":
- case "immagicres_hell":
- case "imfireres_hell":
- case "imcoldres_hell":
- case "imlightres_hell":
- case "impoisres_hell":
- /**
- * An inherent edge case exists here, because Hell difficulty
- * is listed as having two possible immunities.
- */
- if (pair.Value.StartsWith("-"))
- {
- // The resistance is negative
- continue;
- }
- else
- {
- if (Int32.TryParse(pair.Value, out int hellResistance))
- {
- if (hellResistance >= 100)
- {
- switch (pair.Key)
- {
- case "imdmgres_hell":
- if (hellImmunity1.Equals("0"))
- {
- hellImmunity1 = "Physical";
- }
- else
- {
- hellImmunity2 = "Physical";
- }
- break;
- case "immagicres_hell":
- if (hellImmunity1.Equals("0"))
- {
- hellImmunity1 = "Magic";
- }
- else
- {
- hellImmunity2 = "Magic";
- }
- break;
- case "imfireres_hell":
- if (hellImmunity1.Equals("0"))
- {
- hellImmunity1 = "Fire";
- }
- else
- {
- hellImmunity2 = "Fire";
- }
- break;
- case "imcoldres_hell":
- if (hellImmunity1.Equals("0"))
- {
- hellImmunity1 = "Cold";
- }
- else
- {
- hellImmunity2 = "Cold";
- }
- break;
- case "imlightres_hell":
- if (hellImmunity1.Equals("0"))
- {
- hellImmunity1 = "Lightning";
- }
- else
- {
- hellImmunity2 = "Lightning";
- }
- break;
- case "impoisres_hell":
- if (hellImmunity1.Equals("0"))
- {
- hellImmunity1 = "Poison";
- }
- else
- {
- hellImmunity2 = "Poison";
- }
- break;
- default:
- break; // Should never happen.
- }
- }
- }
- }
- break;
- default:
- break;
- }
- }
- // Add the new immunity data to the auxdata
- auxData.Add("imimm_norm", normalImmunity);
- auxData.Add("imimm_night", nightmareImmunity);
- auxData.Add("imimm_hell", hellImmunity1);
- auxData.Add("imimm_hell2", hellImmunity2);
- #endregion
- /**
- * Continue to debugging and then finally generating
- * and printing data out.
- */
- if (isDebugging)
- {
- Console.WriteLine();
- Console.WriteLine("Printing Debug Log...");
- foreach (KeyValuePair<string, string> pair in auxData)
- {
- Console.WriteLine(pair.Key + " " + pair.Value);
- }
- Console.WriteLine("Debug Log Finished.");
- }
- /**
- * Generate Diablo2.io Markup
- */
- Console.WriteLine();
- Console.WriteLine("Generating Diablo2.io Markup...");
- builder.AppendLine("[zform][form][b]irarity[/b][/form][fbox]Monster (Auxiliary)[/fbox][/zform]");
- builder.AppendLine("[zform][form][b]igraphic[/b][/form][att][attachment=0][/attachment][/att][/zform]");
- foreach (KeyValuePair<string, string> pair in auxData)
- {
- if (filterNullData)
- {
- if (pair.Value.Equals("0"))
- {
- continue;
- }
- }
- builder.AppendLine("[zform][form][b]" + pair.Key + "[/b][/form][fbox]" + pair.Value + "[/fbox][/zform]");
- }
- Console.WriteLine("Finished generating markup!");
- Console.WriteLine("Printing Diablo2.io Aux Markup!");
- Console.WriteLine(builder.ToString());
- }
- }
- }
Add Comment
Please, Sign In to add comment