Пример #1
0
        public WdTank(string id, JsonDict json, WdCountry country, WdData data)
        {
            RawId   = id;
            Country = country;
            Raw     = json;

            var tags1 = Raw["tags"].WdString().Split("\r\n").Select(s => s.Trim()).ToHashSet();
            var tags2 = Raw["tags"].WdString().Split(' ').Select(s => s.Trim()).ToHashSet();

            Tags      = tags1.Count > tags2.Count ? tags1 : tags2;
            NotInShop = Raw.ContainsKey("notInShop") && Raw["notInShop"].GetBool();
            Price     = Raw["price"] is JsonDict ? Raw["price"][""].WdInt() : Raw["price"].WdInt();
            Gold      = Raw["price"] is JsonDict && Raw["price"].ContainsKey("gold");

            if (Tags.Contains("lightTank"))
            {
                Class = "lightTank";
            }
            else if (Tags.Contains("mediumTank"))
            {
                Class = "mediumTank";
            }
            else if (Tags.Contains("heavyTank"))
            {
                Class = "heavyTank";
            }
            else if (Tags.Contains("SPG"))
            {
                Class = "SPG";
            }
            else if (Tags.Contains("AT-SPG"))
            {
                Class = "AT-SPG";
            }
            else
            {
                Class = null;
            }

            Tier   = Raw["level"].WdInt();
            Secret = Tags.Contains("secret");
            string scriptsFolder = string.IsNullOrEmpty(data.VersionConfig.PathSourceScripts) ? @"res\scripts" : data.VersionConfig.PathSourceScripts;

            var path = WotFileExporter.CombinePaths(data.Installation.Path, scriptsFolder,
                                                    @"item_defs\vehicles\{0}\{1}.xml".Fmt(Country.Name, id));

            using (var stream = WotFileExporter.GetFileStream(path))
            {
                RawExtra = BxmlReader.ReadFile(stream);
            }

            FullName    = data.ResolveString(Raw["userString"].WdString());
            ShortName   = Raw.ContainsKey("shortUserString") ? data.ResolveString(Raw["shortUserString"].WdString()) : FullName;
            Description = data.ResolveString(Raw["description"].WdString());

            MaxSpeedForward = RawExtra["speedLimits"]["forward"].WdDecimal();
            MaxSpeedReverse = RawExtra["speedLimits"]["backward"].WdDecimal();

            RepairCost = RawExtra["repairCost"].WdDecimal();

            Hull = new WdHull(RawExtra["hull"].GetDict());

            Chassis = new List <WdChassis>();
            Turrets = new List <WdTurret>();
            Engines = new List <WdEngine>();
            Radios  = new List <WdRadio>();
            // these lists are populated once all the tanks are loaded, since some shared modules occur before the non-shared "definition" of the module.

            foreach (var kvp in RawExtra["chassis"].GetDict())
            {
                if (kvp.Value.GetStringLenientSafe() != "shared" && kvp.Value.Safe[""].GetStringSafe() != "shared" && !kvp.Value.ContainsKey("shared"))
                {
                    Country.Chassis.Add(kvp.Key, new WdChassis(kvp.Key, kvp.Value.GetDict(), data));
                }
            }
            foreach (var kvp in RawExtra["turrets0"].GetDict())
            {
                if (kvp.Value.GetStringLenientSafe() != "shared" && kvp.Value.Safe[""].GetStringSafe() != "shared" && !kvp.Value.ContainsKey("shared"))
                {
                    Country.Turrets.Add(kvp.Key, new WdTurret(kvp.Key, kvp.Value.GetDict(), data));
                }
            }
            // RawExtra["engines"] and RawExtra["radios"] only contain information about unlocks; the rest is contained in separate files parsed in WdCountry.
        }
Пример #2
0
        /// <summary>
        /// Port of Path.Combine without illegal chars check
        /// </summary>
        /// <param name="paths">An array of paths to combine</param>
        /// <returns>Combined path</returns>
        public static string CombinePaths(params String[] paths)
        {
            if (paths == null)
            {
                throw new ArgumentNullException("paths");
            }

            int finalSize      = 0;
            int firstComponent = 0;

            // We have two passes, the first calcuates how large a buffer to allocate and does some precondition
            // checks on the paths passed in.  The second actually does the combination.

            for (int i = 0; i < paths.Length; i++)
            {
                if (paths[i] == null)
                {
                    throw new ArgumentNullException("paths");
                }

                if (paths[i].Length == 0)
                {
                    continue;
                }

                //CheckInvalidPathChars(paths[i]);

                if (WotFileExporter.IsPathRooted(paths[i]))
                {
                    firstComponent = i;
                    finalSize      = paths[i].Length;
                }
                else
                {
                    finalSize += paths[i].Length;
                }

                char ch = paths[i][paths[i].Length - 1];
                if (ch != Path.DirectorySeparatorChar && ch != Path.AltDirectorySeparatorChar && ch != Path.VolumeSeparatorChar && ch != '|')
                {
                    finalSize++;
                }
            }

            StringBuilder finalPath = new StringBuilder(finalSize);

            for (int i = firstComponent; i < paths.Length; i++)
            {
                if (paths[i].Length == 0)
                {
                    continue;
                }

                if (finalPath.Length == 0)
                {
                    finalPath.Append(paths[i]);
                }
                else
                {
                    char ch = finalPath[finalPath.Length - 1];
                    if (ch != Path.DirectorySeparatorChar && ch != Path.AltDirectorySeparatorChar && ch != Path.VolumeSeparatorChar && ch != '|')
                    {
                        finalPath.Append(Path.DirectorySeparatorChar);
                    }

                    finalPath.Append(paths[i]);
                }
            }

            return(finalPath.ToString());
        }
Пример #3
0
        public WdData(GameInstallation installation, GameVersionConfig versionConfig)
        {
            Countries     = new Dictionary <string, WdCountry>();
            Warnings      = new List <string>();
            Installation  = installation;
            VersionConfig = versionConfig;

            IList <string> countries = new[] { "ussr", "germany", "usa", "france", "china", "uk", "japan", "czech", "sweden", "poland" };

            countries =
                countries.Where(
                    c =>
                    WotFileExporter.Exists(WotFileExporter.CombinePaths(installation.Path,
                                                                        versionConfig.PathVehicleList.Replace(@"""Country""", c)))).ToList();

            string scriptsFolder = string.IsNullOrEmpty(versionConfig.PathSourceScripts) ? @"res\scripts" : versionConfig.PathSourceScripts;

            foreach (var country in countries)
            {
                JsonDict tanks, engines, guns, radios, shells;
                string   path;

                path = WotFileExporter.CombinePaths(installation.Path, versionConfig.PathVehicleList.Replace(@"""Country""", country));
                try
                {
                    using (var stream = WotFileExporter.GetFileStream(path))
                    {
                        tanks = BxmlReader.ReadFile(stream);
                    }
                }
                catch (Exception e) { throw new WotDataException("Couldn't read vehicle list for country \"{0}\" from file \"{1}\"".Fmt(country, path), e); }

                path = WotFileExporter.CombinePaths(installation.Path, scriptsFolder, @"item_defs\vehicles\{0}\components\engines.xml").Fmt(country);
                try
                {
                    using (var stream = WotFileExporter.GetFileStream(path))
                    {
                        engines = BxmlReader.ReadFile(stream);
                    }
                }
                catch (Exception e) { throw new WotDataException("Couldn't read engines data for country \"{0}\" from file \"{1}\"".Fmt(country, path), e); }

                path = WotFileExporter.CombinePaths(installation.Path, scriptsFolder, @"item_defs\vehicles\{0}\components\guns.xml").Fmt(country);
                try
                {
                    using (var stream = WotFileExporter.GetFileStream(path))
                    {
                        guns = BxmlReader.ReadFile(stream);
                    }
                }
                catch (Exception e) { throw new WotDataException("Couldn't read guns data for country \"{0}\" from file \"{1}\"".Fmt(country, path), e); }

                path = WotFileExporter.CombinePaths(installation.Path, scriptsFolder, @"item_defs\vehicles\{0}\components\radios.xml").Fmt(country);
                try
                {
                    using (var stream = WotFileExporter.GetFileStream(path))
                    {
                        radios = BxmlReader.ReadFile(stream);
                    }
                }
                catch (Exception e) { throw new WotDataException("Couldn't read radios data for country \"{0}\" from file \"{1}\"".Fmt(country, path), e); }

                path = WotFileExporter.CombinePaths(installation.Path, scriptsFolder, @"item_defs\vehicles\{0}\components\shells.xml").Fmt(country);
                try
                {
                    using (var stream = WotFileExporter.GetFileStream(path))
                    {
                        shells = BxmlReader.ReadFile(stream);
                    }
                }
                catch (Exception e) { throw new WotDataException("Couldn't read shells data for country \"{0}\" from file \"{1}\"".Fmt(country, path), e); }

                // Nothing interesting in these:
                //chassis = BxmlReader.ReadFile(ZipFileExporter.CombinePaths(installation.Path, scriptsFolder, @"item_defs\vehicles\{0}\components\chassis.xml").Fmt(country));
                //turrets = BxmlReader.ReadFile(ZipFileExporter.CombinePaths(installation.Path, scriptsFolder, @"item_defs\vehicles\{0}\components\turrets.xml").Fmt(country));
                // Observe that these are the exact same pieces of information that are available directly in the vehicle definition (parsed in WdTank)

                try
                {
                    Countries.Add(country, new WdCountry(country, this, tanks, engines, guns, radios, shells));
                }
                catch (Exception e)
                {
                    throw new WotDataException("Could not parse game data for country \"{0}\"".Fmt(country), e);
                }
            }

            foreach (var country in Countries.Values)
            {
                // Link all the modules to each tank
                foreach (var tank in country.Tanks.Values)
                {
                    foreach (var key in tank.RawExtra["chassis"].GetDict().Keys)
                    {
                        tank.Chassis.Add(country.Chassis[key]);
                    }
                    foreach (var key in tank.RawExtra["turrets0"].GetDict().Keys)
                    {
                        tank.Turrets.Add(country.Turrets[key]);
                    }
                    foreach (var key in tank.RawExtra["engines"].GetDict().Keys)
                    {
                        tank.Engines.Add(country.Engines[key]);
                    }
                    foreach (var key in tank.RawExtra["radios"].GetDict().Keys)
                    {
                        if (key != "")
                        {
                            tank.Radios.Add(country.Radios[key]);
                        }
                    }
                }
                // Guns are a bit weird; it appears that there's a base definition + turret-specific overrides.
                foreach (var turret in country.Turrets.Values)
                {
                    foreach (var kvp in turret.Raw["guns"].GetDict())
                    {
                        if (!country.Guns.ContainsKey(kvp.Key))
                        {
                            Warnings.Add("Could not complete gun loading for turret “{0}”, gun “{1}”.".Fmt(turret.Id, kvp.Key));
                            continue;
                        }
                        var gun = country.Guns[kvp.Key].Clone();
                        gun.UpdateFrom(kvp.Value.GetDict(), country);
                        if (turret.Raw.ContainsKey("yawLimits")) // earlier game versions have this data in the turret record
                        {
                            var parts = turret.Raw["yawLimits"].WdString().Split(' ').Select(x => decimal.Parse(x, NumberStyles.Float, CultureInfo.InvariantCulture)).ToArray();
                            gun.YawLeftLimit  = parts[0]; // not too sure about which is which
                            gun.YawRightLimit = parts[1];
                        }
                        turret.Guns.Add(gun);
                    }
                }
                // Validate that the guns loaded fully
                foreach (var gun in country.Guns.Values)
                {
                    try { gun.Validate(); }
                    catch (Exception e) { Warnings.Add("Incomplete data for gun “{0}”: {1}".Fmt(gun.Id, e.Message)); }
                }
            }

            // Clear the string data, since it's no longer needed
            _moFiles.Clear();
            _moFiles = null;
        }