/// <summary> /// Sub-loop for loading enemy attack information. /// </summary> public static int AttackLoop(TagData line, List<Enemy> enemies) { Enemy currentEnemy = null; if (enemies.Count > 0) currentEnemy = enemies.Last(); Attack currentAttack = null; if (currentEnemy != null && currentEnemy.Attacks.Count > 0) currentAttack = currentEnemy.Attacks.Last(); // Add old attack and start a new one. if (line.Tag.Equals("attack")) { if (line.Data.Length == 0) ErrorHandler.ShowWarning("Missing info. Use \"attack='name'\"!"); currentEnemy.Attacks.Add(new Attack(LinkGenerator.CheckLinkSyntax(line.Data))); currentAttack = currentEnemy.Attacks.Last(); } // Tags from main loop. Save attack and exit this loop. else if (line.Tag.Equals("name") || line.Tag.Equals("copy") || line.Tag.Equals("potion")) return -1; else if (line.Tag.Equals("id")) HandleAttackId(line.Data, currentAttack, currentEnemy); // Tags from effect loop. Exit immediately. else if (line.Tag.Equals("effect")) { return 1; } else if (line.Tag.Equals("cooldown")) HandleCooldown(line.Data, currentAttack); else if (line.Tag.Equals("additional")) HandleAdditional(line.Data, currentAttack, currentEnemy); else if (line.Tag.Equals("animation")) HandleAnimation(line.Data, currentAttack); else if (line.Tag.Equals("image")) HandleAttackMedia(line.Data, currentAttack); else if (line.Tag.Equals("subeffect")) ErrorHandler.ShowWarning("Missing attack effect (\"effect='type'\")!"); else if (line.Tag.Equals("")) ErrorHandler.ShowWarning("Something wrong with line " + line.Data + "."); else ErrorHandler.ShowWarning("Unrecognized tag: " + line.Tag); return 0; }
/// <summary> /// Processes one line of data. /// </summary> private static void HandleLine(string line, List<Encounter> encounters, List<PathData> paths, string instance) { Encounter currentEncounter = null; if (encounters.Count > 0) currentEncounter = encounters[encounters.Count - 1]; if (!Helper.CheckLineValidity(line)) return; // Check for weird characters but allow "|" to skip next line. if (!char.IsLetterOrDigit(line[0]) && line[0] != '|' && line[0] != '~') { ErrorHandler.ShowWarning("Line starts with a weird character. Please remove!"); return; } var text = new TagData(line, Constants.TagSeparator); if (text.Tag.Equals("init")) paths.Add(new PathData(line, instance)); else if (text.Tag.Equals("path")) HandlePath(text.Data); else if (text.Tag.Equals("name")) { encounters.Add(new Encounter()); currentEncounter = encounters[encounters.Count - 1]; currentEncounter.Name = text.Data; currentEncounter.DataName = Helper.Simplify(LinkGenerator.RemoveLinks(text.Data)); currentEncounter.Paths = new List<string>(_currentPath.Split('|')); } else { if (currentEncounter == null) { ErrorHandler.ShowWarning("Ignoring the line because there is no active encounter"); return; } if (text.Tag.Equals("image")) currentEncounter.HandleMedia(text.Data, instance); else if (text.Tag.Equals("tactic")) currentEncounter.HandleTactic(text.Data, paths); else HandleNormalLine(line, currentEncounter, paths); } }
private static SubEffectInformation ExtractInformation(SubEffectInformation effect, SubEffect subEffect, TagData text, Attack baseAttack, Enemy baseEnemy) { var effectType = subEffect.Name; var effectData = text.Data.Split(':'); effect.name = text.Tag.ToLower(); effect.amount = -1; effect.duration = 0.0; effect.stacks = 1; effect.buff = ""; effect.icon = effect.name; effect.suffix = "damage"; if (effectType == EffectType.Damage || effectType == EffectType.DamageFixed || effectType == EffectType.DamagePercent) { if (effectData[0].Equals("-")) effect.amount = baseAttack.Coefficient; else if (effectData[0].Equals("?")) effect.amount = -1; else effect.amount = Helper.ParseD(effectData[0]); effect.icon = "damage"; effect.stacks = 1; } else if (effectType == EffectType.Healing || effectType == EffectType.HealingPercent) { if (effectData[0].Equals("-")) effect.amount = baseAttack.Coefficient; else if (effectData[0].Equals("?")) effect.amount = -1; else effect.amount = Helper.ParseD(effectData[0]); effect.suffix = "healing"; effect.icon = "healing"; effect.stacks = 1; } if (effectType == EffectType.Boon || effectType == EffectType.Condition || effectType == EffectType.Control) { baseEnemy.Tags.Add(effect.name); } if (effectType == EffectType.Agony || effectType == EffectType.Boon || effectType == EffectType.Condition) { if (effectData[0].Equals("-")) effect.duration = baseAttack.Coefficient; else if (effectData[0].Equals("?")) effect.duration = -1; else effect.duration = Helper.ParseD(effectData[0]); if (effectType == EffectType.Agony || effect.name.Equals("bleeding") || effect.name.Equals("torment") || effect.name.Equals("burning") || effect.name.Equals("poison") || effect.name.Equals("confusion") || effect.name.Equals("regeneration") || effect.name.Equals("might")) effect.amount = effect.duration; if (effectData.Length > 1) effect.stacks = Helper.ParseI(effectData[1]); if (subEffect.StacksDuration || effectType == EffectType.Boon) effect.suffix = "seconds"; if (effect.name.Equals("regeneration")) effect.suffix = "healing"; if (effect.name.Equals("retaliation")) effect.suffix = "damage per hit"; if (effect.name.Equals("might")) effect.suffix = "more damage"; if (effect.name.Equals("retaliation") || effect.name.Equals("might")) effect.amount = 1; } if (effectType == EffectType.Control) { if (effectData[0].Equals("?")) effect.duration = 0; else effect.duration = Helper.ParseD(effectData[0]); if (effectData.Length > 1) effect.stacks = Helper.ParseI(effectData[1]); } if (effectType == EffectType.Buff) { effect.buff = effectData[0]; effect.icon = effect.buff; if (effectData.Length > 1 && effectData[1].Length > 0) effect.duration = Helper.ParseD(effectData[1]); if (effectData.Length > 2 && effectData[2].Length > 0) effect.stacks = Helper.ParseI(effectData[2]); if (effectData.Length > 3 && effectData[3].Length > 0) effect.icon = effectData[3]; if (effectData.Length > 4) subEffect.StacksDuration = Helper.ParseI(effectData[4]) > 0 ? true : false; } return effect; }
/// <summary> /// Reads a list of instabilities. /// </summary> public static void ReadInstabilities() { Constants.Instabilities.Clear(); for (var i = 0; i < 100; i++) Constants.Instabilities.Add(new SortedSet<Instability>()); string[] lines; try { Console.WriteLine("Reading instabilities."); lines = File.ReadAllLines(@"Instabilities.txt", Encoding.GetEncoding(1252)); } catch (FileNotFoundException) { ErrorHandler.ShowWarningMessage("File 'Instabilities.txt' not found!"); return; } Instability currentInstability = null; HashSet<int> scales = null; foreach (var line in lines) { if (line == "" || line[0] == '#') continue; var text = new TagData(line, Constants.TagSeparator); if (text.Tag.Equals("name")) { if (currentInstability != null && scales != null) { foreach (var scale in scales) Constants.Instabilities[scale - 1].Add(currentInstability); } currentInstability = new Instability(); currentInstability.Name = text.Data; scales = null; } else if (text.Tag.Equals("description")) { if (currentInstability == null) { ErrorHandler.ShowWarningMessage("No active instability."); continue; } currentInstability.Description = text.Data; } else if (text.Tag.Equals("image")) { if (currentInstability == null) { ErrorHandler.ShowWarningMessage("No active instability."); continue; } currentInstability.Image = text.Data; } else if (text.Tag.Equals("scale")) { scales = GetScales(text.Data); } else { if (currentInstability == null) { ErrorHandler.ShowWarningMessage("No active instability."); continue; } currentInstability.Text.Add(line); } } if (currentInstability != null && scales != null) { foreach (var scale in scales) Constants.Instabilities[scale - 1].Add(currentInstability); } }
/// <summary> /// Processes one line of data. /// </summary> /// <param name="enemies">Current list of added enemies.</param> /// <param name="enemyAttributes">Datamined enemy information-</param> private static void HandleLine(string line, List<Enemy> enemies, Dictionary<string, EnemyAttributes> enemyAttributes) { if (!Helper.CheckLineValidity(line)) return; var tagData = new TagData(line, Constants.TagSeparator); var returnValue = 0; if (_mode == 0) returnValue = EnemyLoop(tagData, enemies, enemyAttributes); else if (_mode == 1) returnValue = AttackLoop(tagData, enemies); else if (_mode == 2) returnValue = EffectLoop(tagData, enemies); _mode += returnValue; // Moving between loop modes only happen when detecting stuff from other loops. if (returnValue != 0) { // Line has to be rechecked on the new loop. HandleLine(line, enemies, enemyAttributes); } }
/// <summary> /// Main loop for loading general enemy information. /// </summary> private static int EnemyLoop(TagData line, List<Enemy> enemies, Dictionary<string, EnemyAttributes> enemyAttributes) { Enemy currentEnemy = null; if (enemies.Count > 0) currentEnemy = enemies.Last(); if (!line.Tag.Equals("name") && !line.Tag.Equals("id") && currentEnemy != null & currentEnemy.IsNameCopied) ErrorHandler.ShowWarning("ID or name not explicitly set for a copied enemy."); if (line.Tag.Equals("copy")) { VerifyEnemy(currentEnemy); var found = FindEnemy(line.Data, enemies); enemies.Add(HandleCopy(found)); currentEnemy = enemies.Last(); } else if (line.Tag.Equals("name")) { if (currentEnemy == null || !currentEnemy.IsNameCopied) { VerifyEnemy(currentEnemy); enemies.Add(new Enemy()); currentEnemy = enemies.Last(); } currentEnemy.Name = line.Data; currentEnemy.DataName = Helper.Simplify(LinkGenerator.RemoveLinks(line.Data)); } else { if (currentEnemy == null) { ErrorHandler.ShowWarning("Ignoring the line because there is no active enemy"); return 0; } if (line.Tag.Equals("id")) HandleId(line.Data, currentEnemy, enemyAttributes); else if (line.Tag.Equals("path")) currentEnemy.Paths = new List<string>(line.Data.ToLower().Split('|')); else if (line.Tag.Equals("rank")) currentEnemy.Rank = line.Data.ToLower(); else if (line.Tag.Equals("ally")) currentEnemy.Allied = true; else if (line.Tag.Equals("alt")) HandleAlternativeNames(line.Data, currentEnemy); else if (line.Tag.Equals("image")) HandleMedia(line.Data, currentEnemy); else if (line.Tag.Equals("level")) HandleLevel(line.Data, currentEnemy); else if (line.Tag.Equals("scaling")) HandleScaling(line.Data, currentEnemy); else if (line.Tag.Equals("attack")) return 1; else if (line.Tag.Equals("tactic")) HandleTactic(line.Data, currentEnemy); else if (line.Tag.Equals("health")) HandleHealth(line.Data, currentEnemy); else if (line.Tag.Equals("toughness")) HandleToughness(line.Data, currentEnemy); else if (line.Tag.Equals("condition")) HandleCondition(line.Data, currentEnemy); else if (line.Tag.Equals("race")) currentEnemy.Attributes.Family.SetName(line.Data); else if (line.Tag.Equals("tag")) HandleTag(line.Data, currentEnemy); // Normal content. else if (line.Tag.Equals("")) { currentEnemy.Tactics.AddLine(LinkGenerator.CheckLinkSyntax(line.Data)); } else if (line.Tag.Equals("type") || line.Tag.Equals("effect") || line.Tag.Equals("cooldown") || line.Tag.Equals("additional") || line.Tag.Equals("animation")) ErrorHandler.ShowWarning("Missing attack name (\"attack='name'\")!"); else ErrorHandler.ShowWarning("Unrecognized tag: " + line.Tag); } return 0; }
/// <summary> /// Sub-sub-loop for loading enemy attack effect information. /// </summary> private static int EffectLoop(TagData line, List<Enemy> enemies) { Enemy currentEnemy = null; if (enemies.Count > 0) currentEnemy = enemies.Last(); Attack currentAttack = null; if (currentEnemy != null && currentEnemy.Attacks.Count > 0) currentAttack = currentEnemy.Attacks.Last(); Effect currentEffect = null; if (currentAttack != null && currentAttack.Effects.Count > 0) currentEffect = currentAttack.Effects.Last(); // Add old effect and start a new one. if (line.Tag.Equals("")) ErrorHandler.ShowWarning("No tag for line " + line.Data + "."); else if (line.Tag.Equals("effect")) { if (line.Data.Length == 0) ErrorHandler.ShowWarning("Missing info. Use \"effect='type'\"!"); if (currentAttack == null) { ErrorHandler.ShowWarning("Ignoring line. No active attack."); } currentAttack.Effects.Add(new Effect(LinkGenerator.CheckLinkSyntax(line.Data))); var type = line.Data.ToLower(); foreach (var enemyTag in Constants.AttackTypeTags) { if (type.Contains(enemyTag)) { currentEnemy.Tags.Add(enemyTag); if (currentAttack.CantBeBlocked && enemyTag.Equals("projectile")) currentEnemy.Tags.Add("can't reflect"); } } currentEffect = currentAttack.Effects.Last(); } // Tag from attack loop. Save effect and exit this loop. else if (line.Tag.Equals("attack")) { return -1; } // Tag from main loop. Save both effect and attack and then exit this loop. else if (line.Tag.Equals("name") || line.Tag.Equals("potion") || line.Tag.Equals("copy")) { return -2; } // Error handling for wrongly placed tags. else if (line.Tag.Equals("additional") || line.Tag.Equals("cooldown") || line.Tag.Equals("animation")) ErrorHandler.ShowWarning("Wrong position for tag " + line.Tag + ". Move above any type-tags."); else if (currentEffect == null) { ErrorHandler.ShowWarning("Ignoring line. No active effect."); return 0; } else if (line.Tag.Equals("count")) HandleCount(line.Data, currentEffect); else if (line.Tag.Equals("length")) HandleLength(line.Data, currentEffect); else if (line.Tag.Equals("frequency")) HandleFrequency(line.Data, currentEffect); else if (line.Tag.Equals("subeffect")) HandleSubeffect(line.Data, currentEffect); else ErrorHandler.ShowWarning("Unrecognized tag: " + line.Tag); return 0; }