Exemplo n.º 1
0
 /***********************************************************************************************
 * GenerateEnemies / 2014-08-01 / Wethospu                                                      *
 *                                                                                              *
 * Generates enemies for one dungeon.                                                           *
 *                                                                                              *
 * Returns list of generated enemies.                                                           *
 * enemyAttributes: Datamined enemy attributes and other info.                                  *
 *                                                                                              *
 ***********************************************************************************************/
 public static List<Enemy> GenerateEnemies(Dictionary<string, EnemyAttributes> enemyAttributes)
 {
     var enemyData = new List<Enemy>();
       if (!Directory.Exists(Constants.DataEnemyRaw))
       {
     Helper.ShowWarning("Directory " + Constants.DataEnemyRaw + " doesn't exist.");
     return enemyData;
       }
       var enemyFiles = Directory.GetFiles(Constants.DataEnemyRaw);
       foreach (var file in enemyFiles)
       {
     if (Path.GetExtension(file) != ".txt")
       continue;
     string[] lines;
     if (File.Exists(file))
       lines = File.ReadAllLines(file, Constants.Encoding);
     else
     {
       Helper.ShowWarningMessage("File " + file + " doesn't exist!");
       return null;
     }
     Helper.CurrentFile = file;
     for (var row = 0; row < lines.Length; row++)
     {
       Helper.InitializeWarningSystem(row + 1, lines[row]);
       HandleLine(lines[row], enemyData, enemyAttributes);
     }
       }
       // Add the last enemy.
       if (_currentEffect != null && _currentAttack != null)
     _currentAttack.Effects.Add(_currentEffect);
       if (_currentAttack != null && _currentEnemy != null)
     _currentEnemy.Attacks.Add(_currentAttack);
       if (_currentEnemy != null)
     enemyData.Add(_currentEnemy);
       // Reset internal state.
       Helper.InitializeWarningSystem(-1, "");
       _currentEnemy = null;
       _currentAttack = null;
       _currentEffect = null;
       // Sort for consistency (also allows see enemies without proper ids). / 2015-10-05 / Wethospu
       enemyData.Sort();
       // Set up internal indexes. / 2015-10-05 / Wethospu
       for (var i = 0; i < enemyData.Count; i++)
     enemyData[i].Index = i;
       return enemyData;
 }
Exemplo n.º 2
0
        /***********************************************************************************************
         * EffectLoop / 2014-08-01 / Wethospu                                                          *
         *                                                                                             *
         * Sub process loop for attack effects.                                                        *
         *                                                                                             *
         * tag: Tag of the line.                                                                       *
         * data: Data of the line.                                                                     *
         *                                                                                             *
         ***********************************************************************************************/
        private static int EffectLoop(string tag, string data)
        {
            // Add old effect and start a new one.
              if (tag.Equals("effect"))
              {
            if (data.Length == 0)
              Helper.ShowWarning("Missing info. Use \"effect='type'\"!");
            if (_currentEffect != null)
              _currentAttack.Effects.Add(_currentEffect);
            var type = data.ToLower();
            foreach (var enemyTag in Constants.AttackTypeTags)
            {
              if (type.Contains(enemyTag))
            _currentEnemy.Tags.Add(enemyTag);
            }
            _currentEffect = new Effect(LinkGenerator.CreatePageLinks(LinkGenerator.CheckLinkSyntax(data)));
              }
              // Tag from attack loop. Save effect and exit this loop.
              else if (tag.Equals("attack"))
              {
            if (_currentEffect != null)
              _currentAttack.Effects.Add(_currentEffect);
            _currentEffect = null;
            return -1;
              }
              // Tag from main loop. Save both effect and attack and then exit this loop.
              else if (tag.Equals("name") || tag.Equals("potion") || tag.Equals("copy"))
              {
            if (_currentEffect != null)
            {
              _currentAttack.Effects.Add(_currentEffect);
              _currentEnemy.Attacks.Add(_currentAttack);
            }
            _currentEffect = null;
            _currentAttack = null;
            return -2;
              }
              else if (tag.Equals("count"))
              {
            if (data.Length > 0)
            {
              if (data.Equals("?"))
            _currentEffect.HitCount = -1;
              else
            _currentEffect.HitCount = Helper.ParseI(data);
              if (_currentEffect.HitCount == 0)
            Helper.ShowWarning("Hit count can't be zero.");
            }

            else
              Helper.ShowWarning("Missing info. Use \"count='number'\"");
              }
              else if (tag.Equals("length"))
              {
            if (data.Length > 0)
              _currentEffect.HitLength = Helper.ParseD(data);
            else
              Helper.ShowWarning("Missing info. Use \"length='number'\"");
              }
              else if (tag.Equals("frequency"))
              {
            if (data.Length > 0)
              _currentEffect.HitFrequency = Helper.ParseD(data);
            else
              Helper.ShowWarning("Missing info. Use \"frequency='number'\"");
              }
              // Add subeffects to the effect.
              else if (tag.Equals("subeffect"))
              {
            if (data.Length > 0)
            {
              data = LinkGenerator.CheckLinkSyntax(data);
              _currentEffect.SubEffects.Add(data);
            }
            else
              Helper.ShowWarning("Missing info. Use TODO!");
              }
              // Error handling for wrongly placed tags.
              else if (tag.Equals("additional") || tag.Equals("cooldown") || tag.Equals("animation"))
            Helper.ShowWarning("Wrong position for tag " + tag + ". Move above any type-tags.");
              else if (tag.Equals(""))
            Helper.ShowWarning("Something wrong with line " + data + ".");
              else
            Helper.ShowWarning("Unrecognized tag: " + tag);
              return 0;
        }
Exemplo n.º 3
0
        /***********************************************************************************************
         * EnemyLoop / 2014-08-01 / Wethospu                                                           *
         *                                                                                             *
         * Main process loop for enemies.                                                              *
         *                                                                                             *
         * tag: Tag of the line.                                                                       *
         * data: Data of the line.                                                                     *
         * enemies: Output. List of processed enemies.                                                 *
         *                                                                                             *
         ***********************************************************************************************/
        private static int EnemyLoop(string tag, string data, List<Enemy> enemies, Dictionary<string, EnemyAttributes> enemyAttributes)
        {
            if (!tag.Equals("name") && !tag.Equals("id") && _currentEnemy != null & _currentEnemy.IsNameCopied)
            Helper.ShowWarning("ID or name not explicitly set for a copied enemy.");
              if (tag.Equals("copy"))
              {
            if (_currentEnemy != null)
              enemies.Add(_currentEnemy);
            var found = FindEnemy(data, enemies);
            if (found != null)
            {
              _currentEnemy = Helper.CloneJson(found);
              _currentEnemy.IsNameCopied = true;
              _currentEnemy.AreAnimationsCopied = true;
            }
            else
              Helper.ShowWarning("Copying failed. Enemy not found!");
              }
              else if (tag.Equals("name"))
              {
            if (data.Length > 0)
            {
              if (_currentEnemy != null && !_currentEnemy.IsNameCopied)
              {
            enemies.Add(_currentEnemy);
            if (_currentEnemy.Paths.Count == 0)
              Helper.ShowWarning("Path not set for enemy " + _currentEnemy.Name);
              }
              if (data.Contains('_'))
            Helper.ShowWarning("Enemy name " + data + "  containts '_'. Replace them with ' '!");
              // For copies only set the name. / 2015-10-05 / Wethospu
              if (_currentEnemy != null && _currentEnemy.IsNameCopied)
            _currentEnemy.Name = data;
              else
            _currentEnemy = new Enemy(data);
              _currentEnemy.IsNameCopied = false;
              _currentAttack = null;
              _currentEffect = null;
            }
            else
              Helper.ShowWarning("Missing info. Use \"name='name'\"!");
              }
              else if (tag.Equals("id"))
              {
            if (_currentEnemy == null)
              Helper.ShowWarning("Enemy not initialized with name.");
            else if (data.Length > 0)
            {
              _currentEnemy.IsNameCopied = false;
              var ids = data.Split('|');
              // Enemies can have multiple genders if there are model variations. / 2015 - 09 - 28 / Wethospu
              // Each model has a different id so store old ones to get all added. / 2015-09-28 / Wethospu
              var oldGenders = "";
              foreach (var id in ids)
              {
            _currentEnemy.InternalIds.Add(Helper.ParseI(id));
            if (enemyAttributes.ContainsKey(id))
            {
              _currentEnemy.Attributes = enemyAttributes[id];
              if (oldGenders.Length > 0)
              {
                var genders = oldGenders.Split('|');
                // If the sex is already there it can be ignored. / 2015-09-28 / Wethospu
                if (genders.Contains(_currentEnemy.Attributes.Gender))
                  _currentEnemy.Attributes.Gender = oldGenders;
                else
                  _currentEnemy.Attributes.Gender = oldGenders + "|" + _currentEnemy.Attributes.Gender;
              }
              _currentEnemy.Rank = _currentEnemy.Attributes.GetRank();
              oldGenders = _currentEnemy.Attributes.Gender;
            }
            else
              Helper.ShowWarning("Id " + data + " not found in enemy attributes.");
              }
            }
            else
              Helper.ShowWarning("Missing info. Use \"id='id'\"!");
              }
              else if (tag.Equals("path"))
              {
            if (data.Length == 0)
              Helper.ShowWarning("Missing info. Use \"path='path1'|'path2'|'pathN'\"!");
            if (data.Contains(" "))
            {
              Helper.ShowWarning("' ' found. Use syntax \"path='path1'|'path2'|'pathN'\"");
              data = data.Replace(' ', '|');
            }
            if (_currentEnemy == null)
              Helper.ShowWarning("Enemy not initialized with name.");
            else
              _currentEnemy.Paths = new List<string>(data.ToLower().Split('|'));
              }
              else if (tag.Equals("rank"))
              {
            if (_currentEnemy == null)
              Helper.ShowWarning("Enemy not initialized with name.");
            else if (data.Length > 0)
            {
              _currentEnemy.Rank = data.ToLower();
              if (!LinkGenerator.EnemyCategories.Contains(_currentEnemy.Rank))
            Helper.ShowWarning("Rank " + _currentEnemy.Rank + " not recognized. Check syntax for correct categories.");
            }
            else
              Helper.ShowWarning("Missing info. Use \"rank='rank'\"!");
              }
              else if (tag.Equals("alt"))
              {
            if (_currentEnemy == null)
              Helper.ShowWarning("Enemy not initialized with name.");
            else if (data.Length > 0)
            {
              if (data.Contains('_'))
            Helper.ShowWarning("Alt names " + data + "  containts '_'. Replace them with ' '!");
              var altNames = data.Split('|');
              _currentEnemy.AltNames.Clear();
              foreach (var altName in altNames)
            _currentEnemy.AddAlt(altName);
            }
            else
              Helper.ShowWarning("Missing info. Use \"alt='alt1'|'alt2'|'altN'\"!");
              }
              else if (tag.Equals("image"))
              {
            if (_currentEnemy == null)
              Helper.ShowWarning("Enemy not initialized with name.");
            else if (data.Length > 0)
            {
              if (_currentEnemy.AreAnimationsCopied)
              {
            _currentEnemy.Medias.Clear();
            _currentEnemy.AreAnimationsCopied = false;
              }
              _currentEnemy.Medias.Add(new Media(data));
            }
            else
              Helper.ShowWarning("Missing info. Use \"image='imagelink'\"!");
              }
              else if (tag.Equals("level"))
              {
            if (_currentEnemy == null)
              Helper.ShowWarning("Enemy not initialized with name.");
            else if (data.Length > 0)
            {
              _currentEnemy.Level = Helper.ParseI(data);
            }
            else
              Helper.ShowWarning("Missing info. Use \"level='amount'\"");
              }
              else if (tag.Equals("scaling"))
              {
            if (_currentEnemy == null)
              Helper.ShowWarning("Enemy not initialized with name.");
            else if (data.Length > 0)
            {
              var scalingSplit = data.Split('|');
              _currentEnemy.ScalingType = scalingSplit[0];
              if (scalingSplit.Length > 1)
              {
            int result;
            if (int.TryParse(scalingSplit[1], out result))
              _currentEnemy.ScalingFractal = result;
            else
              Helper.ShowWarning("Fractal scale " + scalingSplit[1] + " is not an integer!");
            if (scalingSplit.Length > 2)
            {
              if (int.TryParse(scalingSplit[2], out result))
                _currentEnemy.ScalingLevel = result;
              else
                Helper.ShowWarning("Enemy level " + scalingSplit[2] + " is not an integer!");

            }
              }
            }

            else
              Helper.ShowWarning("Missing info. Use \"scaling='type'|'fractal scale'|'enemy level'\"!");
              }
              else if (tag.Equals("attack"))
              {
            if (_currentEnemy == null)
              Helper.ShowWarning("Enemy not initialized with name.");
            else if (_currentEnemy.Rank.Length == 0)
              Helper.ShowWarningMessage("Rank not set for enemy " + _currentEnemy.Name + ". Please fix!");
            return 1;
              }
              else if (tag.Equals("tactic"))
              {
            // Set validity to over max so custom tactics never get overridden. / 2015-08-09 / Wethospu
            _currentEnemy.TacticValidity = 2.0;
            if (data.Length > 0)
              _currentEnemy.Tactics.AddTactics(data);
            else
              Helper.ShowWarning("Missing info. Use \"tactic='tactic1'|'tactic2'|'tacticN'\".");
              }
              else if (tag.Equals("health"))
              {
            if (data.Length > 0)
            {
              _currentEnemy.Attributes.Multipliers.HealthMultiplier = Helper.ParseD(data);
              // If vitality is not set, initialize it with something sensible so the page can calculate something. / 2015-09-10 / Wethospu
              if (_currentEnemy.Attributes.Multipliers.Vitality < 0.1)
            _currentEnemy.Attributes.Multipliers.Vitality = 1;
              if (Helper.ParseD(data) > 1000)
            Helper.ShowWarning("Health values should be multipliers. Calculate the multiplier.");
            }
            else
              Helper.ShowWarning("Missing info. Use \"health='amount'.");
              }
              else if (tag.Equals("toughness"))
              {
            if (data.Length > 0)
            {
              _currentEnemy.Attributes.Multipliers.Toughness = Helper.ParseD(data);
              if (Helper.ParseD(data) > 100)
            Helper.ShowWarning("Toughness values should be multipliers. Calculate the multiplier.");
            }
            else
              Helper.ShowWarning("Missing info. Use \"toughness='amount'.");
              }
              else if (tag.Equals("armor"))
              {
            Helper.ShowWarning("Armor values shouldn't be used. Calculate the toughness multiplier.");
              }
              else if (tag.Equals("condition"))
              {
            if (data.Length > 0)
            {
              _currentEnemy.Attributes.Multipliers.ConditionDamage = Helper.ParseD(data);
              if (Helper.ParseD(data) > 100)
            Helper.ShowWarning("Condition damage values should be multipliers. Calculate the multiplier.");
            }
            else
              Helper.ShowWarning("Missing info. Use \"condition='amount'.");
              }
              else if (tag.Equals("race"))
              {
            if (data.Length > 0)
            {
              _currentEnemy.Attributes.Family.Name = data;
            }
            else
              Helper.ShowWarning("Missing info. Use \"race='value'.");
              }
              else if (tag.Equals("tag"))
              {
            if (data.Length > 0)
            {
              var split = data.Split('|');
              foreach (var str in split)
            _currentEnemy.Tags.Add(str.ToLower());
            }
            else
              Helper.ShowWarning("Missing info. Use \"tag='tactic1'|'tactic2'|'tacticN'\"!");
              }
              // Normal content.
              else if (tag.Equals(""))
              {
            // Preprocess the line to avoid doing same stuff 25+ times.
            _currentEnemy.Tactics.AddLine(LinkGenerator.CreatePageLinks(LinkGenerator.CheckLinkSyntax(data)));
              }
              else if (tag.Equals("type") || tag.Equals("effect") || tag.Equals("cooldown") || tag.Equals("additional") || tag.Equals("animation"))
            Helper.ShowWarning("Missing attack name (\"attack='name'\")!");
              else
            Helper.ShowWarning("Unrecognized tag: " + tag);
              return 0;
        }
Exemplo n.º 4
0
        /***********************************************************************************************
         * AttackLoop / 2014-08-01 / Wethospu                                                          *
         *                                                                                             *
         * Sub process loop for enemy attacks.                                                         *
         *                                                                                             *
         * tag: Tag of the line.                                                                       *
         * data: Data of the line.                                                                     *
         *                                                                                             *
         ***********************************************************************************************/
        static int AttackLoop(string tag, string data)
        {
            // Add old attack and start a new one.
              if (tag.Equals("attack"))
              {
            if (data.Length == 0)
              Helper.ShowWarning("Missing info. Use \"attack='name'\"!");

            if (_currentAttack != null)
              _currentEnemy.Attacks.Add(_currentAttack);
            _currentAttack = new Attack(LinkGenerator.CreatePageLinks(LinkGenerator.CheckLinkSyntax(data)));
            _currentEffect = null;
              }
              // Tags from main loop. Save attack and exit this loop.
              else if (tag.Equals("name") || tag.Equals("copy") || tag.Equals("potion"))
              {
            if (_currentAttack != null)
              _currentEnemy.Attacks.Add(_currentAttack);
            _currentAttack = null;
            _currentEffect = null;
            return -1;
              }
              else if (tag.Equals("id"))
              {
            if (data.Length > 0)
            {
              _currentAttack.LoadAttributes(Helper.ParseI(data), _currentEnemy.Attributes);
            }
            else
              Helper.ShowWarning("Missing info. Use \"id=number\".");
              }
              // Tags from effect loop. Exit immediately.
              else if (tag.Equals("effect"))
              {
            return 1;
              }
              else if (tag.Equals("cooldown"))
              {
            if (data.Length > 0)
              _currentAttack.Cooldown = Helper.ParseD(data);
            else
              Helper.ShowWarning("Missing info. Use \"cooldown='number'\".");
              }
              else if (tag.Equals("additional"))
              {
            // Treat additional as an effect. / 2015-09-22 / Wethospu
            if (data.Length == 0)
              Helper.ShowWarning("Missing info. Use \"additional='text'\".");
            if (_currentEffect != null)
              _currentAttack.Effects.Add(_currentEffect);
            var lower = data.ToLower();
            // Check for interesting tags. / 2015-09-22 / Wethospu
            if (lower.Contains("can't be blocked") || lower.Contains("can't block"))
              _currentEnemy.Tags.Add("can't block");
            if (lower.Contains("can't be evaded") || lower.Contains("can't evade"))
              _currentEnemy.Tags.Add("can't evade");
            _currentEffect = new Effect(LinkGenerator.CreatePageLinks(LinkGenerator.CheckLinkSyntax(data)));
              }
              else if (tag.Equals("animation"))
              {
            if (data.Length > 0)
            {
              if (data.Contains(':') && !data.Contains('='))
            Helper.ShowWarning("Potentially use of wrong syntax. Use \"animation='pre cast'|'time'|'after cast'\" !");
              _currentAttack.Animation = data;
            }
            else
              Helper.ShowWarning("Missing info. Use \"animation='pre cast'|'time'|'after cast'\" !");
              }
              else if (tag.Equals("image"))
              {
            if (data.Length > 0)
            {
              _currentAttack.Medias.Add(new Media(data));
            }
            else
              Helper.ShowWarning("Missing info. Use \"image='imagelink'\"!");
              }
              else if (tag.Equals("subeffect"))
            Helper.ShowWarning("Missing attack effect (\"effect='type'\")!");
              else if (tag.Equals(""))
            Helper.ShowWarning("Something wrong with line " + data + ".");
              else
            Helper.ShowWarning("Unrecognized tag: " + tag);

              return 0;
        }
Exemplo n.º 5
0
        /// <summary>
        /// Converts raw effect data to html outpout.
        /// </summary>
        /// <param name="effectStr">Effect information-</param>
        /// <param name="baseEffect">Base effect.</param>
        /// <param name="baseAttack">Base attack for the base effect.</param>
        /// <param name="baseEnemy">Base enemy for the base attack.</param>
        /// <returns>Converted data.</returns>
        public static string HandleEffect(string effectStr, Effect baseEffect, Attack baseAttack, Enemy baseEnemy)
        {
            /* What is wanted:
              * Damage: <span>(count*stack*amount)</span> over time (<span>amount</span> per hit).
              * Swiftness: (count*stack*amount) over time (amount per hit).
              * count*stack stability: for amount over time (stack per hit)
              * count*stack might: <span>count*stack</span>% more damage for amount over time (<span>stack</span>% more damage per hit)
              */
              // Note: Listing per hit for might/stability may not make sense if there is only stack.

              // Keep the original string for error logging purposes.
              var original = string.Copy(effectStr);
              // Copy values from the base effect to avoid changing it. If this ever gets refactored feel free to use them directly.
              SubEffectInformation information = new SubEffectInformation();
              information.hitCount = baseEffect.HitCount;
              information.hitLength = baseEffect.HitLength;
              information.hitFrequency = baseEffect.HitFrequency;
              information.variableHitCount = false;
              var split = effectStr.Split('|');
              effectStr = split[0];
              // Some effects get applied randomly. Don't add total damage/effect in those cases. Refactor this if possible.
              var effectChance = "";
              if (split.Length > 1)
            effectChance = split[1];
              if (effectChance.Length > 0)
            information.hitCount = 1;
              if (information.hitCount < 0)
              {
            information.variableHitCount = true;
            information.hitCount = 1;
              }
              // First effect type determines the icon.
              var firstType = "";
              var firstStacks = 0;
              var startIcon = "";
              var index = 0;
              while (true)
              {
            TagData text = TagData.FromString(effectStr, ':', ref index, new[] { ' ', '|', '(' }, new[] { ' ', '|', ')' });
            if (text == null)
              break;
            // Ignore other stuff like enemies.
            if (text.Tag.Contains("="))
              continue;
            if (text.Tag.Length == 0 || text.Data.Length == 0)
            {
              ErrorHandler.ShowWarningMessage("Enemy " + baseEnemy.Name + ": Something wrong with line '" + original + "'. Note: Use '\\:' instead of ':' in the text!");
              effectStr = effectStr.Remove(index, 1);
              continue;
            }
            if (!SubEffect.EffectTypes.ContainsKey(text.Tag.ToLower()))
            {
              ErrorHandler.ShowWarningMessage("Skipping an effect. Effect " + text.Tag + " not recognized.");
              continue;
            }
            var subEffect = SubEffect.EffectTypes[text.Tag.ToLower()];
            var effectType = subEffect.Name;
            // Effect info format varies based on tag (separated by :).
            information = ExtractInformation(information, subEffect, text, baseAttack, baseEnemy);
            var tag = SubEffect.GetTag(effectType);
            if (tag.Length > 0)
              baseEnemy.Tags.Add(tag);
            information = HandleStackingRules(information, subEffect);
            StringBuilder replace = GenerateReplace(information, subEffect, baseAttack);
            var toReplace = text.Tag + ":" + text.Data;
            effectStr = effectStr.Replace(toReplace, replace.ToString());
            index = index - toReplace.Length + replace.Length;
            // Get the first subeffect type to display an icon.
            if (firstType.Equals(""))
            {
              if (information.icon.Equals("-") && effectType == EffectType.Buff)
            startIcon = "Buff";
              else
            startIcon = "<span class=" + Constants.IconClass + " data-src=\"" + information.icon.ToLower() + "\" title=\"" + Helper.ToUpper(information.name.Replace('_', ' ')) + "\">" + Helper.ToUpper(information.name.Replace('_', ' ')) + "</span>";
              firstType = information.name;
              firstStacks = information.stacks;
            }
              }
              return BuildHTML(firstType, startIcon, firstStacks, effectStr, effectChance).ToString();
        }
Exemplo n.º 6
0
 private static void HandleSubeffect(string data, Effect currentEffect)
 {
     if (data.Length == 0)
     ErrorHandler.ShowWarning("Missing info. Use TODO!");
       currentEffect.SubEffects.Add(LinkGenerator.CheckLinkSyntax(data));
 }
Exemplo n.º 7
0
 private static void HandleLength(string data, Effect currentEffect)
 {
     if (data.Length == 0)
     ErrorHandler.ShowWarning("Missing info. Use \"length='number'\"");
       currentEffect.HitLength = Helper.ParseD(data);
 }
Exemplo n.º 8
0
 private static void HandleCount(string data, Effect currentEffect)
 {
     if (data.Length == 0)
     ErrorHandler.ShowWarning("Missing info. Use \"count='number'\"");
       if (data.Equals("?"))
     currentEffect.HitCount = -1;
       else
     currentEffect.HitCount = Helper.ParseI(data);
       if (currentEffect.HitCount == 0)
     ErrorHandler.ShowWarning("Hit count can't be zero.");
 }