コード例 #1
0
ファイル: MapPreview.cs プロジェクト: matija-hustic/OpenRA
        public void UpdateFromMap(IReadOnlyPackage p, IReadOnlyPackage parent, MapClassification classification, string[] mapCompatibility, MapGridType gridType)
        {
            Dictionary <string, MiniYaml> yaml;

            using (var yamlStream = p.GetStream("map.yaml"))
            {
                if (yamlStream == null)
                {
                    throw new FileNotFoundException("Required file map.yaml not present in this map");
                }

                yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, "map.yaml", stringPool: cache.StringPool)).ToDictionary();
            }

            Package       = p;
            parentPackage = parent;

            var newData = innerData.Clone();

            newData.GridType = gridType;
            newData.Class    = classification;

            if (yaml.TryGetValue("MapFormat", out var temp))
            {
                var format = FieldLoader.GetValue <int>("MapFormat", temp.Value);
                if (format != Map.SupportedMapFormat)
                {
                    throw new InvalidDataException($"Map format {format} is not supported.");
                }
            }

            if (yaml.TryGetValue("Title", out temp))
            {
                newData.Title = temp.Value;
            }

            if (yaml.TryGetValue("Categories", out temp))
            {
                newData.Categories = FieldLoader.GetValue <string[]>("Categories", temp.Value);
            }

            if (yaml.TryGetValue("Tileset", out temp))
            {
                newData.TileSet = temp.Value;
            }

            if (yaml.TryGetValue("Author", out temp))
            {
                newData.Author = temp.Value;
            }

            if (yaml.TryGetValue("Bounds", out temp))
            {
                newData.Bounds = FieldLoader.GetValue <Rectangle>("Bounds", temp.Value);
            }

            if (yaml.TryGetValue("Visibility", out temp))
            {
                newData.Visibility = FieldLoader.GetValue <MapVisibility>("Visibility", temp.Value);
            }

            string requiresMod = string.Empty;

            if (yaml.TryGetValue("RequiresMod", out temp))
            {
                requiresMod = temp.Value;
            }

            if (yaml.TryGetValue("MapFormat", out temp))
            {
                newData.MapFormat = FieldLoader.GetValue <int>("MapFormat", temp.Value);
            }

            newData.Status = mapCompatibility == null || mapCompatibility.Contains(requiresMod) ?
                             MapStatus.Available : MapStatus.Unavailable;

            try
            {
                // Actor definitions may change if the map format changes
                if (yaml.TryGetValue("Actors", out var actorDefinitions))
                {
                    var spawns = new List <CPos>();
                    foreach (var kv in actorDefinitions.Nodes.Where(d => d.Value.Value == "mpspawn"))
                    {
                        var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
                        spawns.Add(s.Get <LocationInit>().Value);
                    }

                    newData.SpawnPoints = spawns.ToArray();
                }
                else
                {
                    newData.SpawnPoints = Array.Empty <CPos>();
                }
            }
            catch (Exception)
            {
                newData.SpawnPoints = Array.Empty <CPos>();
                newData.Status      = MapStatus.Unavailable;
            }

            try
            {
                // Player definitions may change if the map format changes
                if (yaml.TryGetValue("Players", out var playerDefinitions))
                {
                    newData.Players     = new MapPlayers(playerDefinitions.Nodes);
                    newData.PlayerCount = newData.Players.Players.Count(x => x.Value.Playable);
                }
            }
            catch (Exception)
            {
                newData.Status = MapStatus.Unavailable;
            }

            newData.SetCustomRules(modData, this, yaml);

            if (p.Contains("map.png"))
            {
                using (var dataStream = p.GetStream("map.png"))
                    newData.Preview = new Png(dataStream);
            }

            // Assign the new data atomically
            innerData = newData;
        }
コード例 #2
0
        public Map(ModData modData, IReadOnlyPackage package)
        {
            this.modData = modData;
            Package      = package;

            if (!Package.Contains("map.yaml") || !Package.Contains("map.bin"))
            {
                throw new InvalidDataException("Not a valid map\n File: {0}".F(package.Name));
            }

            var yaml = new MiniYaml(null, MiniYaml.FromStream(Package.GetStream("map.yaml"), package.Name));

            foreach (var field in YamlFields)
            {
                field.Deserialize(this, yaml.Nodes);
            }

            if (MapFormat != SupportedMapFormat)
            {
                throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, package.Name));
            }

            PlayerDefinitions = MiniYaml.NodesOrEmpty(yaml, "Players");
            ActorDefinitions  = MiniYaml.NodesOrEmpty(yaml, "Actors");

            Grid = modData.Manifest.Get <MapGrid>();

            var size = new Size(MapSize.X, MapSize.Y);

            Tiles     = new CellLayer <TerrainTile>(Grid.Type, size);
            Resources = new CellLayer <ResourceTile>(Grid.Type, size);
            Height    = new CellLayer <byte>(Grid.Type, size);

            using (var s = Package.GetStream("map.bin"))
            {
                var header = new BinaryDataHeader(s, MapSize);
                if (header.TilesOffset > 0)
                {
                    s.Position = header.TilesOffset;
                    for (var i = 0; i < MapSize.X; i++)
                    {
                        for (var j = 0; j < MapSize.Y; j++)
                        {
                            var tile  = s.ReadUInt16();
                            var index = s.ReadUInt8();

                            // TODO: Remember to remove this when rewriting tile variants / PickAny
                            if (index == byte.MaxValue)
                            {
                                index = (byte)(i % 4 + (j % 4) * 4);
                            }

                            Tiles[new MPos(i, j)] = new TerrainTile(tile, index);
                        }
                    }
                }

                if (header.ResourcesOffset > 0)
                {
                    s.Position = header.ResourcesOffset;
                    for (var i = 0; i < MapSize.X; i++)
                    {
                        for (var j = 0; j < MapSize.Y; j++)
                        {
                            var type    = s.ReadUInt8();
                            var density = s.ReadUInt8();
                            Resources[new MPos(i, j)] = new ResourceTile(type, density);
                        }
                    }
                }

                if (header.HeightsOffset > 0)
                {
                    s.Position = header.HeightsOffset;
                    for (var i = 0; i < MapSize.X; i++)
                    {
                        for (var j = 0; j < MapSize.Y; j++)
                        {
                            Height[new MPos(i, j)] = s.ReadUInt8().Clamp((byte)0, Grid.MaximumTerrainHeight);
                        }
                    }
                }
            }

            if (Grid.MaximumTerrainHeight > 0)
            {
                Tiles.CellEntryChanged  += UpdateProjection;
                Height.CellEntryChanged += UpdateProjection;
            }

            PostInit();

            Uid = ComputeUID(Package);
        }
コード例 #3
0
        public void UpdateFromMap(IReadOnlyPackage p, IReadOnlyPackage parent, MapClassification classification, string[] mapCompatibility, MapGridType gridType)
        {
            Dictionary <string, MiniYaml> yaml;

            using (var yamlStream = p.GetStream("map.yaml"))
            {
                if (yamlStream == null)
                {
                    throw new FileNotFoundException("Required file map.yaml not present in this map");
                }

                yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, "map.yaml")).ToDictionary();
            }

            Package       = p;
            parentPackage = parent;

            var newData = innerData.Clone();

            newData.GridType = gridType;
            newData.Class    = classification;

            MiniYaml temp;

            if (yaml.TryGetValue("MapFormat", out temp))
            {
                var format = FieldLoader.GetValue <int>("MapFormat", temp.Value);
                if (format != Map.SupportedMapFormat)
                {
                    throw new InvalidDataException("Map format {0} is not supported.".F(format));
                }
            }

            if (yaml.TryGetValue("Title", out temp))
            {
                newData.Title = temp.Value;
            }

            if (yaml.TryGetValue("Categories", out temp))
            {
                newData.Categories = FieldLoader.GetValue <string[]>("Categories", temp.Value);
            }

            if (yaml.TryGetValue("Tileset", out temp))
            {
                newData.TileSet = temp.Value;
            }

            if (yaml.TryGetValue("Author", out temp))
            {
                newData.Author = temp.Value;
            }

            if (yaml.TryGetValue("Bounds", out temp))
            {
                newData.Bounds = FieldLoader.GetValue <Rectangle>("Bounds", temp.Value);
            }

            if (yaml.TryGetValue("Visibility", out temp))
            {
                newData.Visibility = FieldLoader.GetValue <MapVisibility>("Visibility", temp.Value);
            }

            string requiresMod = string.Empty;

            if (yaml.TryGetValue("RequiresMod", out temp))
            {
                requiresMod = temp.Value;
            }

            newData.Status = mapCompatibility == null || mapCompatibility.Contains(requiresMod) ?
                             MapStatus.Available : MapStatus.Unavailable;

            try
            {
                // Actor definitions may change if the map format changes
                MiniYaml actorDefinitions;
                if (yaml.TryGetValue("Actors", out actorDefinitions))
                {
                    var spawns = new List <CPos>();
                    foreach (var kv in actorDefinitions.Nodes.Where(d => d.Value.Value == "mpspawn"))
                    {
                        var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
                        spawns.Add(s.InitDict.Get <LocationInit>().Value(null));
                    }

                    newData.SpawnPoints = spawns.ToArray();
                }
                else
                {
                    newData.SpawnPoints = new CPos[0];
                }
            }
            catch (Exception)
            {
                newData.SpawnPoints = new CPos[0];
                newData.Status      = MapStatus.Unavailable;
            }

            try
            {
                // Player definitions may change if the map format changes
                MiniYaml playerDefinitions;
                if (yaml.TryGetValue("Players", out playerDefinitions))
                {
                    newData.Players     = new MapPlayers(playerDefinitions.Nodes);
                    newData.PlayerCount = newData.Players.Players.Count(x => x.Value.Playable);
                }
            }
            catch (Exception)
            {
                newData.Status = MapStatus.Unavailable;
            }

            newData.SetRulesetGenerator(modData, () =>
            {
                var ruleDefinitions          = LoadRuleSection(yaml, "Rules");
                var weaponDefinitions        = LoadRuleSection(yaml, "Weapons");
                var voiceDefinitions         = LoadRuleSection(yaml, "Voices");
                var musicDefinitions         = LoadRuleSection(yaml, "Music");
                var notificationDefinitions  = LoadRuleSection(yaml, "Notifications");
                var sequenceDefinitions      = LoadRuleSection(yaml, "Sequences");
                var modelSequenceDefinitions = LoadRuleSection(yaml, "ModelSequences");
                var rules = Ruleset.Load(modData, this, TileSet, ruleDefinitions, weaponDefinitions,
                                         voiceDefinitions, notificationDefinitions, musicDefinitions, sequenceDefinitions, modelSequenceDefinitions);
                var flagged = Ruleset.DefinesUnsafeCustomRules(modData, this, ruleDefinitions,
                                                               weaponDefinitions, voiceDefinitions, notificationDefinitions, sequenceDefinitions);
                return(Pair.New(rules, flagged));
            });

            if (p.Contains("map.png"))
            {
                using (var dataStream = p.GetStream("map.png"))
                    newData.Preview = new Bitmap(dataStream);
            }

            // Assign the new data atomically
            innerData = newData;
        }
コード例 #4
0
ファイル: MapPreview.cs プロジェクト: pchote/OpenRA
        public void UpdateFromMap(IReadOnlyPackage p, IReadOnlyPackage parent, MapClassification classification, string[] mapCompatibility, MapGridType gridType)
        {
            Dictionary<string, MiniYaml> yaml;
            using (var yamlStream = p.GetStream("map.yaml"))
            {
                if (yamlStream == null)
                    throw new FileNotFoundException("Required file map.yaml not present in this map");

                yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, "map.yaml")).ToDictionary();
            }

            Package = p;
            parentPackage = parent;

            var newData = innerData.Clone();
            newData.GridType = gridType;
            newData.Class = classification;

            MiniYaml temp;
            if (yaml.TryGetValue("MapFormat", out temp))
            {
                var format = FieldLoader.GetValue<int>("MapFormat", temp.Value);
                if (format != Map.SupportedMapFormat)
                    throw new InvalidDataException("Map format {0} is not supported.".F(format));
            }

            if (yaml.TryGetValue("Title", out temp))
                newData.Title = temp.Value;

            if (yaml.TryGetValue("Categories", out temp))
                newData.Categories = FieldLoader.GetValue<string[]>("Categories", temp.Value);

            if (yaml.TryGetValue("Tileset", out temp))
                newData.TileSet = temp.Value;

            if (yaml.TryGetValue("Author", out temp))
                newData.Author = temp.Value;

            if (yaml.TryGetValue("Bounds", out temp))
                newData.Bounds = FieldLoader.GetValue<Rectangle>("Bounds", temp.Value);

            if (yaml.TryGetValue("Visibility", out temp))
                newData.Visibility = FieldLoader.GetValue<MapVisibility>("Visibility", temp.Value);

            string requiresMod = string.Empty;
            if (yaml.TryGetValue("RequiresMod", out temp))
                requiresMod = temp.Value;

            newData.Status = mapCompatibility == null || mapCompatibility.Contains(requiresMod) ?
                MapStatus.Available : MapStatus.Unavailable;

            try
            {
                // Actor definitions may change if the map format changes
                MiniYaml actorDefinitions;
                if (yaml.TryGetValue("Actors", out actorDefinitions))
                {
                    var spawns = new List<CPos>();
                    foreach (var kv in actorDefinitions.Nodes.Where(d => d.Value.Value == "mpspawn"))
                    {
                        var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
                        spawns.Add(s.InitDict.Get<LocationInit>().Value(null));
                    }

                    newData.SpawnPoints = spawns.ToArray();
                }
                else
                    newData.SpawnPoints = new CPos[0];
            }
            catch (Exception)
            {
                newData.SpawnPoints = new CPos[0];
                newData.Status = MapStatus.Unavailable;
            }

            try
            {
                // Player definitions may change if the map format changes
                MiniYaml playerDefinitions;
                if (yaml.TryGetValue("Players", out playerDefinitions))
                {
                    newData.Players = new MapPlayers(playerDefinitions.Nodes);
                    newData.PlayerCount = newData.Players.Players.Count(x => x.Value.Playable);
                }
            }
            catch (Exception)
            {
                newData.Status = MapStatus.Unavailable;
            }

            newData.SetRulesetGenerator(modData, () =>
            {
                var ruleDefinitions = LoadRuleSection(yaml, "Rules");
                var weaponDefinitions = LoadRuleSection(yaml, "Weapons");
                var voiceDefinitions = LoadRuleSection(yaml, "Voices");
                var musicDefinitions = LoadRuleSection(yaml, "Music");
                var notificationDefinitions = LoadRuleSection(yaml, "Notifications");
                var sequenceDefinitions = LoadRuleSection(yaml, "Sequences");
                var rules = Ruleset.Load(modData, this, TileSet, ruleDefinitions, weaponDefinitions,
                    voiceDefinitions, notificationDefinitions, musicDefinitions, sequenceDefinitions);
                var flagged = Ruleset.DefinesUnsafeCustomRules(modData, this, ruleDefinitions,
                    weaponDefinitions, voiceDefinitions, notificationDefinitions, sequenceDefinitions);
                return Pair.New(rules, flagged);
            });

            if (p.Contains("map.png"))
                using (var dataStream = p.GetStream("map.png"))
                    newData.Preview = new Bitmap(dataStream);

            // Assign the new data atomically
            innerData = newData;
        }
コード例 #5
0
ファイル: Map.cs プロジェクト: pchote/OpenRA
        public Map(ModData modData, IReadOnlyPackage package)
        {
            this.modData = modData;
            Package = package;

            if (!Package.Contains("map.yaml") || !Package.Contains("map.bin"))
                throw new InvalidDataException("Not a valid map\n File: {0}".F(package.Name));

            var yaml = new MiniYaml(null, MiniYaml.FromStream(Package.GetStream("map.yaml"), package.Name));
            foreach (var field in YamlFields)
                field.Deserialize(this, yaml.Nodes);

            if (MapFormat != SupportedMapFormat)
                throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, package.Name));

            PlayerDefinitions = MiniYaml.NodesOrEmpty(yaml, "Players");
            ActorDefinitions = MiniYaml.NodesOrEmpty(yaml, "Actors");

            Grid = modData.Manifest.Get<MapGrid>();

            var size = new Size(MapSize.X, MapSize.Y);
            Tiles = new CellLayer<TerrainTile>(Grid.Type, size);
            Resources = new CellLayer<ResourceTile>(Grid.Type, size);
            Height = new CellLayer<byte>(Grid.Type, size);

            using (var s = Package.GetStream("map.bin"))
            {
                var header = new BinaryDataHeader(s, MapSize);
                if (header.TilesOffset > 0)
                {
                    s.Position = header.TilesOffset;
                    for (var i = 0; i < MapSize.X; i++)
                    {
                        for (var j = 0; j < MapSize.Y; j++)
                        {
                            var tile = s.ReadUInt16();
                            var index = s.ReadUInt8();

                            // TODO: Remember to remove this when rewriting tile variants / PickAny
                            if (index == byte.MaxValue)
                                index = (byte)(i % 4 + (j % 4) * 4);

                            Tiles[new MPos(i, j)] = new TerrainTile(tile, index);
                        }
                    }
                }

                if (header.ResourcesOffset > 0)
                {
                    s.Position = header.ResourcesOffset;
                    for (var i = 0; i < MapSize.X; i++)
                    {
                        for (var j = 0; j < MapSize.Y; j++)
                        {
                            var type = s.ReadUInt8();
                            var density = s.ReadUInt8();
                            Resources[new MPos(i, j)] = new ResourceTile(type, density);
                        }
                    }
                }

                if (header.HeightsOffset > 0)
                {
                    s.Position = header.HeightsOffset;
                    for (var i = 0; i < MapSize.X; i++)
                        for (var j = 0; j < MapSize.Y; j++)
                            Height[new MPos(i, j)] = s.ReadUInt8().Clamp((byte)0, Grid.MaximumTerrainHeight);
                }
            }

            if (Grid.MaximumTerrainHeight > 0)
            {
                Tiles.CellEntryChanged += UpdateProjection;
                Height.CellEntryChanged += UpdateProjection;
            }

            PostInit();

            Uid = ComputeUID(Package);
        }
コード例 #6
0
        bool LoadAsset(IReadOnlyPackage package, string filename)
        {
            ClearLoadedAssets();

            if (string.IsNullOrEmpty(filename))
            {
                return(false);
            }

            if (!package.Contains(filename))
            {
                return(false);
            }

            isLoadError = false;

            try
            {
                currentPackage  = package;
                currentFilename = filename;
                var prefix = "";

                if (modData.DefaultFileSystem is OpenRA.FileSystem.FileSystem fs)
                {
                    prefix = fs.GetPrefix(package);
                    if (prefix != null)
                    {
                        prefix += "|";
                    }
                }

                var fileExtension = Path.GetExtension(filename.ToLowerInvariant());
                if (allowedSpriteExtensions.Contains(fileExtension))
                {
                    currentSprites = world.Map.Rules.Sequences.SpriteCache[prefix + filename];
                    currentFrame   = 0;

                    if (frameSlider != null)
                    {
                        frameSlider.MaximumValue = (float)currentSprites.Length - 1;
                        frameSlider.Ticks        = currentSprites.Length;
                    }

                    currentVoxel = null;
                }
                else if (allowedModelExtensions.Contains(fileExtension))
                {
                    var voxelName = Path.GetFileNameWithoutExtension(filename);
                    currentVoxel   = world.ModelCache.GetModel(voxelName);
                    currentSprites = null;
                }
                else if (allowedAudioExtensions.Contains(fileExtension))
                {
                    // Mute music so it doesn't interfere with the current asset.
                    MuteSounds();

                    currentAudioStream = Game.ModData.DefaultFileSystem.Open(prefix + filename);
                    foreach (var modDataSoundLoader in Game.ModData.SoundLoaders)
                    {
                        if (modDataSoundLoader.TryParseSound(currentAudioStream, out currentSoundFormat))
                        {
                            if (frameSlider != null)
                            {
                                frameSlider.MaximumValue = currentSoundFormat.LengthInSeconds * currentSoundFormat.SampleRate;
                                frameSlider.Ticks        = 0;
                            }

                            break;
                        }
                    }
                }
                else if (allowedVideoExtensions.Contains(fileExtension))
                {
                    // Mute music so it doesn't interfere with the current asset.
                    MuteSounds();

                    var video = VideoLoader.GetVideo(Game.ModData.DefaultFileSystem.Open(filename), true, Game.ModData.VideoLoaders);
                    if (video != null)
                    {
                        player = panel.Get <VideoPlayerWidget>("PLAYER");
                        player.Load(prefix + filename);
                        player.DrawOverlay = false;
                        isVideoLoaded      = true;

                        if (frameSlider != null)
                        {
                            frameSlider.MaximumValue = (float)player.Video.FrameCount - 1;
                            frameSlider.Ticks        = 0;
                        }
                    }
                }
                else
                {
                    return(false);
                }
            }
            catch (Exception ex)
            {
                isLoadError = true;
                Log.AddChannel("assetbrowser", "assetbrowser.log");
                Log.Write("assetbrowser", "Error reading {0}:{3} {1}{3}{2}", filename, ex.Message, ex.StackTrace, Environment.NewLine);

                return(false);
            }

            return(true);
        }