예제 #1
0
        /// <summary>
        /// Performs the conversion of .mon files to .json files.
        /// </summary>
        /// <param name="monDirPath">Optional. The path to the directory containing the .mon files. Defaults to the initialization <see cref="options"/> value if not supplied.</param>
        /// <param name="jsonDirPath">Optional. The path to the directory that will contain the .json files. Defaults to the initialization <see cref="options"/> value if not supplied.</param>
        /// <param name="overwriteFiles">Optional. A value indicating whether to overwrite files at the destination folder. Defaults to the initialization <see cref="options"/> value if not supplied.</param>
        public void Convert(string monDirPath = null, string jsonDirPath = null, bool?overwriteFiles = null)
        {
            this.options.MonsterFilesDirectory = monDirPath ?? this.options.MonsterFilesDirectory;
            this.options.OutputDirectory       = jsonDirPath ?? this.options.OutputDirectory;
            this.options.OverwriteFiles        = overwriteFiles ?? this.options.OverwriteFiles;

            DataAnnotationsValidator.ValidateObjectRecursive(this.options);

            var itemDictionary = this.itemTypesLoader.LoadTypes();

            var monDirectoryInfo  = new DirectoryInfo(monDirPath);
            var jsonDirectoryInfo = new DirectoryInfo(jsonDirPath);

            if (!monDirectoryInfo.Exists)
            {
                throw new ArgumentException($"The specified directory for .mon files: [{monDirectoryInfo.FullName}] does not exist.");
            }

            if (!jsonDirectoryInfo.Exists)
            {
                jsonDirectoryInfo.Create();

                if (!jsonDirectoryInfo.Exists)
                {
                    throw new ArgumentException($"The specified output directory: [{jsonDirectoryInfo.FullName}] does not exist and could not be created.");
                }
            }

            var existingFiles = monDirectoryInfo.GetFiles($"*{MonExtension}");
            var modelMap      = new Dictionary <string, MonsterModel>();
            var raceMap       = new Dictionary <uint, string>();

            // Now that both directories exist, start processing files serially.
            foreach (var monFileInfo in existingFiles)
            {
                var parsedMonsterModel = CipFileParser.ParseMonsterFile(monFileInfo);

                if (parsedMonsterModel == null)
                {
                    continue;
                }

                var targetModel        = parsedMonsterModel.ToSerializableModel();
                var fileNameWithoutExt = monFileInfo.Name.Replace(MonExtension, string.Empty);

                modelMap.Add(fileNameWithoutExt, targetModel);
                raceMap.Add(parsedMonsterModel.RaceId, fileNameWithoutExt);
            }

            // Ammend item names and summon references
            foreach (var convertedModel in modelMap.Values)
            {
                this.AmmendInventoryItemNames(itemDictionary, convertedModel);
                this.AmmendSummonReferences(raceMap, convertedModel);
            }

            // Output converted models
            foreach (var(fileNameWithoutExt, convertedModel) in modelMap)
            {
                var convertedFilePath = Path.Combine(jsonDirectoryInfo.FullName, Path.GetTempFileName());
                var targetFilePath    = $"{Path.Combine(jsonDirectoryInfo.FullName, fileNameWithoutExt)}{JsonExtension}";
                var tempFileSream     = File.Create(convertedFilePath);

                using (var fw = new StreamWriter(tempFileSream))
                {
                    var serializedMonster = JsonConvert.SerializeObject(convertedModel, Formatting.Indented);

                    fw.Write(serializedMonster);
                    fw.Flush();
                    fw.Close();
                }

                File.Move(convertedFilePath, targetFilePath, overwriteFiles ?? false);
            }
        }
예제 #2
0
        /// <summary>
        /// Reads a <see cref="MonsterTypeEntity"/> out of a monster file.
        /// </summary>
        /// <param name="monsterFileInfo">The information about the monster file.</param>
        /// <returns>The <see cref="MonsterTypeEntity"/> instance.</returns>
        private static MonsterTypeEntity ReadMonsterFile(FileInfo monsterFileInfo)
        {
            monsterFileInfo.ThrowIfNull(nameof(monsterFileInfo));

            if (!monsterFileInfo.Exists)
            {
                return(null);
            }

            var parsedMonster = CipFileParser.ParseMonsterFile(monsterFileInfo);

            var monsterType = new MonsterTypeEntity()
            {
                RaceId         = parsedMonster.RaceId.ToString(),
                Name           = parsedMonster.Name,
                Article        = parsedMonster.Article,
                OriginalOutfit = new Outfit()
                {
                    Id   = parsedMonster.Outfit.Id,
                    Head = parsedMonster.Outfit.Head,
                    Body = parsedMonster.Outfit.Body,
                    Legs = parsedMonster.Outfit.Legs,
                    Feet = parsedMonster.Outfit.Feet,
                },
                Corpse                = (ushort)parsedMonster.Corpse,
                BloodType             = parsedMonster.BloodType,
                BaseExperienceYield   = parsedMonster.Experience,
                SummonCost            = parsedMonster.SummonCost,
                HitpointFleeThreshold = parsedMonster.FleeThreshold,
                BaseAttack            = parsedMonster.Attack,
                BaseDefense           = parsedMonster.Defense,
                BaseArmorRating       = parsedMonster.Armor,
                LoseTargetDistance    = parsedMonster.LoseTarget,
                Strategy              = parsedMonster.Strategy,
            };

            foreach (var flag in parsedMonster.Flags)
            {
                if (flag.ToCreatureFlag() is CreatureFlag creatureFlag)
                {
                    monsterType.SetCreatureFlag(creatureFlag);
                }
            }

            foreach (var(skillType, defaultLevel, currentLevel, maximumLevel, targetCount, countIncreaseFactor, increaserPerLevel) in parsedMonster.Skills)
            {
                if (!Enum.TryParse(skillType, ignoreCase: true, out CipMonsterSkillType mSkill))
                {
                    continue;
                }

                switch (mSkill)
                {
                case CipMonsterSkillType.Hitpoints:
                    monsterType.MaxHitpoints = currentLevel < 0 ? ushort.MaxValue : (ushort)defaultLevel;
                    break;

                case CipMonsterSkillType.GoStrength:
                    monsterType.BaseSpeed = currentLevel < 0 ? ushort.MinValue : (ushort)defaultLevel;
                    break;

                case CipMonsterSkillType.CarryStrength:
                    monsterType.Capacity = currentLevel < 0 ? ushort.MinValue : (ushort)defaultLevel;
                    break;

                case CipMonsterSkillType.FistFighting:
                    if (currentLevel > 0)
                    {
                        monsterType.SetSkill(SkillType.NoWeapon, Convert.ToInt32(currentLevel), Convert.ToInt32(defaultLevel), Convert.ToInt32(maximumLevel), targetCount, countIncreaseFactor, increaserPerLevel);
                    }

                    break;
                }
            }

            foreach (var spellRule in parsedMonster.Spells)
            {
                // Not implemented yet.
            }

            monsterType.SetInventory(parsedMonster.Inventory);
            monsterType.SetPhrases(parsedMonster.Phrases);

            return(monsterType);
        }