Пример #1
0
        public void Resize(int width, int height)                       // editor magic.
        {
            var oldMapTiles     = MapTiles.Value;
            var oldMapResources = MapResources.Value;

            MapTiles     = Exts.Lazy(() => Exts.ResizeArray(oldMapTiles, oldMapTiles[0, 0], width, height));
            MapResources = Exts.Lazy(() => Exts.ResizeArray(oldMapResources, oldMapResources[0, 0], width, height));
            MapSize      = new int2(width, height);
        }
Пример #2
0
        public ModData(string mod, bool useLoadScreen = false)
        {
            Languages     = new string[0];
            Manifest      = new Manifest(mod);
            ObjectCreator = new ObjectCreator(Manifest);
            Manifest.LoadCustomData(ObjectCreator);

            if (useLoadScreen)
            {
                LoadScreen = ObjectCreator.CreateObject <ILoadScreen>(Manifest.LoadScreen.Value);
                LoadScreen.Init(Manifest, Manifest.LoadScreen.ToDictionary(my => my.Value));
                LoadScreen.Display();
            }

            WidgetLoader = new WidgetLoader(this);
            RulesetCache = new RulesetCache(this);
            RulesetCache.LoadingProgress += HandleLoadingProgress;
            MapCache = new MapCache(this);

            var spriteLoaders = new List <ISpriteLoader>();

            foreach (var format in Manifest.SpriteFormats)
            {
                var loader = ObjectCreator.FindType(format + "Loader");
                if (loader == null || !loader.GetInterfaces().Contains(typeof(ISpriteLoader)))
                {
                    throw new InvalidOperationException("Unable to find a sprite loader for type '{0}'.".F(format));
                }

                spriteLoaders.Add((ISpriteLoader)ObjectCreator.CreateBasic(loader));
            }

            SpriteLoaders = spriteLoaders.ToArray();

            var sequenceFormat = Manifest.Get <SpriteSequenceFormat>();
            var sequenceLoader = ObjectCreator.FindType(sequenceFormat.Type + "Loader");
            var ctor           = sequenceLoader != null?sequenceLoader.GetConstructor(new[] { typeof(ModData) }) : null;

            if (sequenceLoader == null || !sequenceLoader.GetInterfaces().Contains(typeof(ISpriteSequenceLoader)) || ctor == null)
            {
                throw new InvalidOperationException("Unable to find a sequence loader for type '{0}'.".F(sequenceFormat.Type));
            }

            SpriteSequenceLoader = (ISpriteSequenceLoader)ctor.Invoke(new[] { this });
            SpriteSequenceLoader.OnMissingSpriteError = s => Log.Write("debug", s);

            // HACK: Mount only local folders so we have a half-working environment for the asset installer
            GlobalFileSystem.UnmountAll();
            foreach (var dir in Manifest.Folders)
            {
                GlobalFileSystem.Mount(dir);
            }

            defaultRules = Exts.Lazy(() => RulesetCache.Load());

            initialThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;
        }
Пример #3
0
        public MapCache(ModData modData)
        {
            this.modData = modData;

            var gridType = Exts.Lazy(() => modData.Manifest.Get <MapGrid>().Type);

            previews     = new Cache <string, MapPreview>(uid => new MapPreview(modData, uid, gridType.Value, this));
            sheetBuilder = new SheetBuilder(SheetType.BGRA);
        }
Пример #4
0
        public ModData(string mod, bool useLoadScreen = false)
        {
            Languages = new string[0];
            Manifest  = new Manifest(mod);
            ModFiles.LoadFromManifest(Manifest);

            ObjectCreator = new ObjectCreator(Manifest, ModFiles);
            Manifest.LoadCustomData(ObjectCreator);

            if (useLoadScreen)
            {
                LoadScreen = ObjectCreator.CreateObject <ILoadScreen>(Manifest.LoadScreen.Value);
                LoadScreen.Init(this, Manifest.LoadScreen.ToDictionary(my => my.Value));
                LoadScreen.Display();
            }

            WidgetLoader = new WidgetLoader(this);
            MapCache     = new MapCache(this);

            SoundLoaders  = GetLoaders <ISoundLoader>(Manifest.SoundFormats, "sound");
            SpriteLoaders = GetLoaders <ISpriteLoader>(Manifest.SpriteFormats, "sprite");

            var sequenceFormat = Manifest.Get <SpriteSequenceFormat>();
            var sequenceLoader = ObjectCreator.FindType(sequenceFormat.Type + "Loader");
            var ctor           = sequenceLoader != null?sequenceLoader.GetConstructor(new[] { typeof(ModData) }) : null;

            if (sequenceLoader == null || !sequenceLoader.GetInterfaces().Contains(typeof(ISpriteSequenceLoader)) || ctor == null)
            {
                throw new InvalidOperationException("Unable to find a sequence loader for type '{0}'.".F(sequenceFormat.Type));
            }

            SpriteSequenceLoader = (ISpriteSequenceLoader)ctor.Invoke(new[] { this });
            SpriteSequenceLoader.OnMissingSpriteError = s => Log.Write("debug", s);

            defaultRules    = Exts.Lazy(() => Ruleset.LoadDefaults(this));
            defaultTileSets = Exts.Lazy(() =>
            {
                var items = new Dictionary <string, TileSet>();

                foreach (var file in Manifest.TileSets)
                {
                    var t = new TileSet(DefaultFileSystem, file);
                    items.Add(t.Id, t);
                }

                return((IReadOnlyDictionary <string, TileSet>)(new ReadOnlyDictionary <string, TileSet>(items)));
            });

            defaultSequences = Exts.Lazy(() =>
            {
                var items = DefaultTileSets.ToDictionary(t => t.Key, t => new SequenceProvider(DefaultFileSystem, this, t.Value, null));
                return((IReadOnlyDictionary <string, SequenceProvider>)(new ReadOnlyDictionary <string, SequenceProvider>(items)));
            });

            initialThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;
        }
Пример #5
0
        public void Resize(int width, int height)                       // editor magic.
        {
            var oldMapTiles     = MapTiles.Value;
            var oldMapResources = MapResources.Value;
            var newSize         = new Size(width, height);

            MapTiles     = Exts.Lazy(() => CellLayer.Resize(oldMapTiles, newSize, oldMapTiles[0, 0]));
            MapResources = Exts.Lazy(() => CellLayer.Resize(oldMapResources, newSize, oldMapResources[0, 0]));
            MapSize      = new int2(newSize);
        }
Пример #6
0
        public MapCache(ModData modData)
        {
            this.modData = modData;

            var gridType = Exts.Lazy(() => modData.Manifest.Get <MapGrid>().Type);

            previews     = new Cache <string, MapPreview>(uid => new MapPreview(modData, uid, gridType.Value, this));
            sheetBuilder = new SheetBuilder(SheetType.BGRA);

            MapLocations = new ReadOnlyDictionary <IReadOnlyPackage, MapClassification>(mapLocations);
        }
Пример #7
0
        internal Actor(World world, string name, TypeDictionary initDict)
        {
            var init = new ActorInitializer(this, initDict);

            World   = world;
            ActorID = world.NextAID();
            if (initDict.Contains <OwnerInit>())
            {
                Owner = init.Get <OwnerInit, Player>();
            }

            occupySpace = Exts.Lazy(() => TraitOrDefault <IOccupySpace>());

            if (name != null)
            {
                name = name.ToLowerInvariant();

                if (!world.Map.Rules.Actors.ContainsKey(name))
                {
                    throw new NotImplementedException("No rules definition for unit " + name);
                }

                Info = world.Map.Rules.Actors[name];
                foreach (var trait in Info.TraitsInConstructOrder())
                {
                    AddTrait(trait.Create(init));
                }
            }

            facing         = Exts.Lazy(() => TraitOrDefault <IFacing>());
            health         = Exts.Lazy(() => TraitOrDefault <Health>());
            effectiveOwner = Exts.Lazy(() => TraitOrDefault <IEffectiveOwner>());

            bounds = Exts.Lazy(() =>
            {
                var si   = Info.Traits.GetOrDefault <SelectableInfo>();
                var size = (si != null && si.Bounds != null) ? new int2(si.Bounds[0], si.Bounds[1]) :
                           TraitsImplementing <IAutoSelectionSize>().Select(x => x.SelectionSize(this)).FirstOrDefault();

                var offset = -size / 2;
                if (si != null && si.Bounds != null && si.Bounds.Length > 2)
                {
                    offset += new int2(si.Bounds[2], si.Bounds[3]);
                }

                return(new Rectangle(offset.X, offset.Y, size.X, size.Y));
            });

            renderModifiers = TraitsImplementing <IRenderModifier>().ToArray();
            renders         = TraitsImplementing <IRender>().ToArray();
            disables        = TraitsImplementing <IDisable>().ToArray();
        }
Пример #8
0
 public ActorReference(string type, Dictionary <string, MiniYaml> inits)
 {
     Type     = type;
     initDict = Exts.Lazy(() =>
     {
         var dict = new TypeDictionary();
         foreach (var i in inits)
         {
             dict.Add(LoadInit(i.Key, i.Value));
         }
         return(dict);
     });
 }
Пример #9
0
        void PostInit()
        {
            rules = Exts.Lazy(() =>
            {
                try
                {
                    return(Game.ModData.RulesetCache.Load(this));
                }
                catch (Exception e)
                {
                    InvalidCustomRules = true;
                    Log.Write("debug", "Failed to load rules for {0} with error {1}", Title, e.Message);
                }

                return(Game.ModData.DefaultRules);
            });

            cachedTileSet = Exts.Lazy(() => Rules.TileSets[Tileset]);

            var tl = new MPos(0, 0).ToCPos(this);
            var br = new MPos(MapSize.X - 1, MapSize.Y - 1).ToCPos(this);

            AllCells = new CellRegion(Grid.Type, tl, br);

            var btl = new PPos(Bounds.Left, Bounds.Top);
            var bbr = new PPos(Bounds.Right - 1, Bounds.Bottom - 1);

            SetBounds(btl, bbr);

            CustomTerrain = new CellLayer <byte>(this);
            foreach (var uv in AllCells.MapCoords)
            {
                CustomTerrain[uv] = byte.MaxValue;
            }

            var leftDelta   = Grid.Type == MapGridType.RectangularIsometric ? new WVec(-512, 0, 0) : new WVec(-512, -512, 0);
            var topDelta    = Grid.Type == MapGridType.RectangularIsometric ? new WVec(0, -512, 0) : new WVec(512, -512, 0);
            var rightDelta  = Grid.Type == MapGridType.RectangularIsometric ? new WVec(512, 0, 0) : new WVec(512, 512, 0);
            var bottomDelta = Grid.Type == MapGridType.RectangularIsometric ? new WVec(0, 512, 0) : new WVec(-512, 512, 0);

            CellCorners = CellCornerHalfHeights.Select(ramp => new WVec[]
            {
                leftDelta + new WVec(0, 0, 512 * ramp[0]),
                topDelta + new WVec(0, 0, 512 * ramp[1]),
                rightDelta + new WVec(0, 0, 512 * ramp[2]),
                bottomDelta + new WVec(0, 0, 512 * ramp[3])
            }).ToArray();
        }
Пример #10
0
        void PostInit()
        {
            rules         = Exts.Lazy(() => Game.modData.RulesetCache.LoadMapRules(this));
            cachedTileSet = Exts.Lazy(() => Rules.TileSets[Tileset]);

            var tl = Map.MapToCell(TileShape, new CPos(Bounds.Left, Bounds.Top));
            var br = Map.MapToCell(TileShape, new CPos(Bounds.Right - 1, Bounds.Bottom - 1));

            Cells = new CellRegion(TileShape, tl, br);

            CustomTerrain = new CellLayer <int>(this);
            foreach (var cell in Cells)
            {
                CustomTerrain[cell] = -1;
            }
        }
Пример #11
0
        public void Resize(int width, int height)                       // editor magic.
        {
            var oldMapTiles     = MapTiles.Value;
            var oldMapResources = MapResources.Value;
            var oldMapHeight    = MapHeight.Value;
            var newSize         = new Size(width, height);

            MapTiles     = Exts.Lazy(() => CellLayer.Resize(oldMapTiles, newSize, oldMapTiles[MPos.Zero]));
            MapResources = Exts.Lazy(() => CellLayer.Resize(oldMapResources, newSize, oldMapResources[MPos.Zero]));
            MapHeight    = Exts.Lazy(() => CellLayer.Resize(oldMapHeight, newSize, oldMapHeight[MPos.Zero]));
            MapSize      = new int2(newSize);

            var tl = new MPos(0, 0).ToCPos(this);
            var br = new MPos(MapSize.X - 1, MapSize.Y - 1).ToCPos(this);

            AllCells = new CellRegion(Grid.Type, tl, br);
        }
Пример #12
0
        /// <summary>
        /// Initializes a new map created by the editor or importer.
        /// The map will not recieve a valid UID until after it has been saved and reloaded.
        /// </summary>
        public Map(TileSet tileset, int width, int height)
        {
            var size = new Size(width, height);

            Grid = Game.ModData.Manifest.Get <MapGrid>();
            var tileRef = new TerrainTile(tileset.Templates.First().Key, (byte)0);

            Title       = "Name your map here";
            Description = "Describe your map here";
            Author      = "Your name here";

            MapSize = new int2(size);
            Tileset = tileset.Id;
            Videos  = new MapVideos();
            Options = new MapOptions();

            MapResources = Exts.Lazy(() => new CellLayer <ResourceTile>(Grid.Type, size));

            MapTiles = Exts.Lazy(() =>
            {
                var ret = new CellLayer <TerrainTile>(Grid.Type, size);
                ret.Clear(tileRef);
                if (Grid.MaximumTerrainHeight > 0)
                {
                    ret.CellEntryChanged += UpdateProjection;
                }
                return(ret);
            });

            MapHeight = Exts.Lazy(() =>
            {
                var ret = new CellLayer <byte>(Grid.Type, size);
                ret.Clear(0);
                if (Grid.MaximumTerrainHeight > 0)
                {
                    ret.CellEntryChanged += UpdateProjection;
                }
                return(ret);
            });

            SpawnPoints = Exts.Lazy(() => new CPos[0]);

            PostInit();
        }
Пример #13
0
        public MapCache(ModData modData)
        {
            this.modData = modData;

            var gridType = Exts.Lazy(() => modData.Manifest.Get <MapGrid>().Type);

            previews     = new Cache <string, MapPreview>(uid => new MapPreview(modData, uid, gridType.Value, this));
            sheetBuilder = new SheetBuilder(SheetType.BGRA);

            // Enumerate map directories
            var mapLocations = new Dictionary <IReadOnlyPackage, MapClassification>();

            foreach (var kv in modData.Manifest.MapFolders)
            {
                var name           = kv.Key;
                var classification = string.IsNullOrEmpty(kv.Value)
                                        ? MapClassification.Unknown : Enum <MapClassification> .Parse(kv.Value);

                IReadOnlyPackage package;
                var optional = name.StartsWith("~");
                if (optional)
                {
                    name = name.Substring(1);
                }

                try
                {
                    package = modData.ModFiles.OpenPackage(name);
                }
                catch
                {
                    if (optional)
                    {
                        continue;
                    }

                    throw;
                }

                mapLocations.Add(package, classification);
            }

            MapLocations = new ReadOnlyDictionary <IReadOnlyPackage, MapClassification>(mapLocations);
        }
Пример #14
0
        public ModData(string mod, bool useLoadScreen = false)
        {
            Languages = new string[0];
            Manifest  = new Manifest(mod);

            // Allow mods to load types from the core Game assembly, and any additional assemblies they specify.
            var assemblies =
                new[] { typeof(Game).Assembly }.Concat(
                Manifest.Assemblies.Select(path => Assembly.LoadFrom(Platform.ResolvePath(path))));

            ObjectCreator = new ObjectCreator(assemblies);
            Manifest.LoadCustomData(ObjectCreator);

            if (useLoadScreen)
            {
                LoadScreen = ObjectCreator.CreateObject <ILoadScreen>(Manifest.LoadScreen.Value);
                LoadScreen.Init(Manifest, Manifest.LoadScreen.ToDictionary(my => my.Value));
                LoadScreen.Display();
            }

            WidgetLoader = new WidgetLoader(this);
            RulesetCache = new RulesetCache(this);
            RulesetCache.LoadingProgress += HandleLoadingProgress;
            MapCache = new MapCache(this);

            SoundLoaders  = GetLoaders <ISoundLoader>(Manifest.SoundFormats, "sound");
            SpriteLoaders = GetLoaders <ISpriteLoader>(Manifest.SpriteFormats, "sprite");

            var sequenceFormat = Manifest.Get <SpriteSequenceFormat>();
            var sequenceLoader = ObjectCreator.FindType(sequenceFormat.Type + "Loader");
            var ctor           = sequenceLoader != null?sequenceLoader.GetConstructor(new[] { typeof(ModData) }) : null;

            if (sequenceLoader == null || !sequenceLoader.GetInterfaces().Contains(typeof(ISpriteSequenceLoader)) || ctor == null)
            {
                throw new InvalidOperationException("Unable to find a sequence loader for type '{0}'.".F(sequenceFormat.Type));
            }

            SpriteSequenceLoader = (ISpriteSequenceLoader)ctor.Invoke(new[] { this });
            SpriteSequenceLoader.OnMissingSpriteError = s => Log.Write("debug", s);

            defaultRules = Exts.Lazy(() => RulesetCache.Load());

            initialThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;
        }
Пример #15
0
        public ActorReference(string type, Dictionary <string, MiniYaml> inits)
        {
            Type     = type;
            initDict = Exts.Lazy(() =>
            {
                var dict = new TypeDictionary();
                foreach (var i in inits)
                {
                    var init = LoadInit(i.Key, i.Value);
                    if (init is ISingleInstanceInit && dict.Contains(init.GetType()))
                    {
                        throw new InvalidDataException("Duplicate initializer '{0}'".F(init.GetType().Name));
                    }

                    dict.Add(init);
                }

                return(dict);
            });
        }
Пример #16
0
        public static Map FromTileset(TileSet tileset)
        {
            var size      = new Size(1, 1);
            var tileShape = Game.ModData.Manifest.TileShape;
            var tileRef   = new TerrainTile(tileset.Templates.First().Key, (byte)0);

            var makeMapTiles = Exts.Lazy(() =>
            {
                var ret = new CellLayer <TerrainTile>(tileShape, size);
                ret.Clear(tileRef);
                return(ret);
            });

            var makeMapHeight = Exts.Lazy(() =>
            {
                var ret = new CellLayer <byte>(tileShape, size);
                ret.Clear(0);
                return(ret);
            });

            var map = new Map()
            {
                Title        = "Name your map here",
                Description  = "Describe your map here",
                Author       = "Your name here",
                MapSize      = new int2(size),
                Tileset      = tileset.Id,
                Videos       = new MapVideos(),
                Options      = new MapOptions(),
                MapResources = Exts.Lazy(() => new CellLayer <ResourceTile>(tileShape, size)),
                MapTiles     = makeMapTiles,
                MapHeight    = makeMapHeight,

                SpawnPoints = Exts.Lazy(() => new CPos[0])
            };

            map.PostInit();

            return(map);
        }
Пример #17
0
        /// <summary>
        /// Initializes a new map created by the editor or importer.
        /// The map will not recieve a valid UID until after it has been saved and reloaded.
        /// </summary>
        public Map(TileSet tileset, int width, int height)
        {
            containsTest = Contains;

            var size      = new Size(width, height);
            var tileShape = Game.ModData.Manifest.TileShape;
            var tileRef   = new TerrainTile(tileset.Templates.First().Key, (byte)0);

            Title       = "Name your map here";
            Description = "Describe your map here";
            Author      = "Your name here";

            MapSize = new int2(size);
            Tileset = tileset.Id;
            Videos  = new MapVideos();
            Options = new MapOptions();

            MapResources = Exts.Lazy(() => new CellLayer <ResourceTile>(tileShape, size));

            MapTiles = Exts.Lazy(() =>
            {
                var ret = new CellLayer <TerrainTile>(tileShape, size);
                ret.Clear(tileRef);
                return(ret);
            });

            MapHeight = Exts.Lazy(() =>
            {
                var ret = new CellLayer <byte>(tileShape, size);
                ret.Clear(0);
                return(ret);
            });

            SpawnPoints          = Exts.Lazy(() => new CPos[0]);
            TileShape            = tileShape;
            MaximumTerrainHeight = Game.ModData.Manifest.MaximumTerrainHeight;

            PostInit();
        }
Пример #18
0
        public ModData(string mod)
        {
            Languages     = new string[0];
            Manifest      = new Manifest(mod);
            ObjectCreator = new ObjectCreator(Manifest);
            LoadScreen    = ObjectCreator.CreateObject <ILoadScreen>(Manifest.LoadScreen.Value);
            LoadScreen.Init(Manifest, Manifest.LoadScreen.ToDictionary(my => my.Value));
            LoadScreen.Display();
            WidgetLoader = new WidgetLoader(this);
            RulesetCache = new RulesetCache(this);
            RulesetCache.LoadingProgress += HandleLoadingProgress;
            MapCache = new MapCache(this);

            var loaders = new List <ISpriteLoader>();

            foreach (var format in Manifest.SpriteFormats)
            {
                var loader = ObjectCreator.FindType(format + "Loader");
                if (loader == null || !loader.GetInterfaces().Contains(typeof(ISpriteLoader)))
                {
                    throw new InvalidOperationException("Unable to find a sprite loader for type '{0}'.".F(format));
                }

                loaders.Add((ISpriteLoader)ObjectCreator.CreateBasic(loader));
            }

            SpriteLoaders = loaders.ToArray();

            // HACK: Mount only local folders so we have a half-working environment for the asset installer
            GlobalFileSystem.UnmountAll();
            foreach (var dir in Manifest.Folders)
            {
                GlobalFileSystem.Mount(dir);
            }

            defaultRules = Exts.Lazy(() => RulesetCache.LoadDefaultRules());

            initialThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;
        }
Пример #19
0
        public ModData(string mod)
        {
            Languages     = new string[0];
            Manifest      = new Manifest(mod);
            ObjectCreator = new ObjectCreator(Manifest);
            LoadScreen    = ObjectCreator.CreateObject <ILoadScreen>(Manifest.LoadScreen.Value);
            LoadScreen.Init(Manifest, Manifest.LoadScreen.ToDictionary(my => my.Value));
            LoadScreen.Display();
            WidgetLoader = new WidgetLoader(this);
            RulesetCache = new RulesetCache(this);
            RulesetCache.LoadingProgress += HandleLoadingProgress;
            MapCache = new MapCache(this);

            // HACK: Mount only local folders so we have a half-working environment for the asset installer
            GlobalFileSystem.UnmountAll();
            foreach (var dir in Manifest.Folders)
            {
                GlobalFileSystem.Mount(dir);
            }

            defaultRules = Exts.Lazy(() => RulesetCache.LoadDefaultRules());

            initialThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;
        }
Пример #20
0
 void PostInit()
 {
     rules = Exts.Lazy(() => Game.modData.RulesetCache.LoadMapRules(this));
 }
Пример #21
0
        // Support upgrading format 5 maps to a more
        // recent version by defining upgradeForMod.
        public Map(string path, string upgradeForMod)
        {
            Path      = path;
            Container = GlobalFileSystem.OpenPackage(path, null, int.MaxValue);

            AssertExists("map.yaml");
            AssertExists("map.bin");

            var yaml = new MiniYaml(null, MiniYaml.FromStream(Container.GetContent("map.yaml")));

            FieldLoader.Load(this, yaml);

            // Support for formats 1-3 dropped 2011-02-11.
            // Use release-20110207 to convert older maps to format 4
            // Use release-20110511 to convert older maps to format 5
            if (MapFormat < 5)
            {
                throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, path));
            }

            // Format 5 -> 6 enforces the use of RequiresMod
            if (MapFormat == 5)
            {
                if (upgradeForMod == null)
                {
                    throw new InvalidDataException("Map format {0} is not supported, but can be upgraded.\n File: {1}".F(MapFormat, path));
                }

                Console.WriteLine("Upgrading {0} from Format 5 to Format 6", path);

                // TODO: This isn't very nice, but there is no other consistent way
                // of finding the mod early during the engine initialization.
                RequiresMod = upgradeForMod;
            }

            var nd = yaml.ToDictionary();

            // Load players
            foreach (var my in nd["Players"].ToDictionary().Values)
            {
                var player = new PlayerReference(my);
                Players.Add(player.Name, player);
            }

            Actors = Exts.Lazy(() =>
            {
                var ret = new Dictionary <string, ActorReference>();
                foreach (var kv in nd["Actors"].ToDictionary())
                {
                    ret.Add(kv.Key, new ActorReference(kv.Value.Value, kv.Value.ToDictionary()));
                }
                return(ret);
            });

            // Smudges
            Smudges = Exts.Lazy(() =>
            {
                var ret = new List <SmudgeReference>();
                foreach (var name in nd["Smudges"].ToDictionary().Keys)
                {
                    var vals = name.Split(' ');
                    var loc  = vals[1].Split(',');
                    ret.Add(new SmudgeReference(vals[0], new int2(
                                                    Exts.ParseIntegerInvariant(loc[0]),
                                                    Exts.ParseIntegerInvariant(loc[1])),
                                                Exts.ParseIntegerInvariant(vals[2])));
                }

                return(ret);
            });

            RuleDefinitions          = MiniYaml.NodesOrEmpty(yaml, "Rules");
            SequenceDefinitions      = MiniYaml.NodesOrEmpty(yaml, "Sequences");
            VoxelSequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "VoxelSequences");
            WeaponDefinitions        = MiniYaml.NodesOrEmpty(yaml, "Weapons");
            VoiceDefinitions         = MiniYaml.NodesOrEmpty(yaml, "Voices");
            NotificationDefinitions  = MiniYaml.NodesOrEmpty(yaml, "Notifications");
            TranslationDefinitions   = MiniYaml.NodesOrEmpty(yaml, "Translations");

            MapTiles     = Exts.Lazy(() => LoadMapTiles());
            MapResources = Exts.Lazy(() => LoadResourceTiles());
            TileShape    = Game.modData.Manifest.TileShape;

            // The Uid is calculated from the data on-disk, so
            // format changes must be flushed to disk.
            // TODO: this isn't very nice
            if (MapFormat < 6)
            {
                Save(path);
            }

            Uid = ComputeHash();

            if (Container.Exists("map.png"))
            {
                CustomPreview = new Bitmap(Container.GetContent("map.png"));
            }

            PostInit();
        }
Пример #22
0
        // The standard constructor for most purposes
        public Map(string path)
        {
            Path      = path;
            Container = GlobalFileSystem.OpenPackage(path, null, int.MaxValue);

            AssertExists("map.yaml");
            AssertExists("map.bin");

            var yaml = new MiniYaml(null, MiniYaml.FromStream(Container.GetContent("map.yaml"), path));

            FieldLoader.Load(this, yaml);

            // Support for formats 1-3 dropped 2011-02-11.
            // Use release-20110207 to convert older maps to format 4
            // Use release-20110511 to convert older maps to format 5
            // Use release-20141029 to convert older maps to format 6
            if (MapFormat < 6)
            {
                throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, path));
            }

            var nd = yaml.ToDictionary();

            // Format 6 -> 7 combined the Selectable and UseAsShellmap flags into the Class enum
            if (MapFormat < 7)
            {
                MiniYaml useAsShellmap;
                if (nd.TryGetValue("UseAsShellmap", out useAsShellmap) && bool.Parse(useAsShellmap.Value))
                {
                    Visibility = MapVisibility.Shellmap;
                }
                else if (Type == "Mission" || Type == "Campaign")
                {
                    Visibility = MapVisibility.MissionSelector;
                }
            }

            // Load players
            foreach (var my in nd["Players"].ToDictionary().Values)
            {
                var player = new PlayerReference(my);
                Players.Add(player.Name, player);
            }

            Actors = Exts.Lazy(() =>
            {
                var ret = new Dictionary <string, ActorReference>();
                foreach (var kv in nd["Actors"].ToDictionary())
                {
                    ret.Add(kv.Key, new ActorReference(kv.Value.Value, kv.Value.ToDictionary()));
                }
                return(ret);
            });

            // Smudges
            Smudges = Exts.Lazy(() =>
            {
                var ret = new List <SmudgeReference>();
                foreach (var name in nd["Smudges"].ToDictionary().Keys)
                {
                    var vals = name.Split(' ');
                    var loc  = vals[1].Split(',');
                    ret.Add(new SmudgeReference(vals[0], new int2(
                                                    Exts.ParseIntegerInvariant(loc[0]),
                                                    Exts.ParseIntegerInvariant(loc[1])),
                                                Exts.ParseIntegerInvariant(vals[2])));
                }

                return(ret);
            });

            RuleDefinitions          = MiniYaml.NodesOrEmpty(yaml, "Rules");
            SequenceDefinitions      = MiniYaml.NodesOrEmpty(yaml, "Sequences");
            VoxelSequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "VoxelSequences");
            WeaponDefinitions        = MiniYaml.NodesOrEmpty(yaml, "Weapons");
            VoiceDefinitions         = MiniYaml.NodesOrEmpty(yaml, "Voices");
            NotificationDefinitions  = MiniYaml.NodesOrEmpty(yaml, "Notifications");
            TranslationDefinitions   = MiniYaml.NodesOrEmpty(yaml, "Translations");

            MapTiles     = Exts.Lazy(() => LoadMapTiles());
            MapResources = Exts.Lazy(() => LoadResourceTiles());
            MapHeight    = Exts.Lazy(() => LoadMapHeight());

            TileShape      = Game.ModData.Manifest.TileShape;
            SubCellOffsets = Game.ModData.Manifest.SubCellOffsets;
            LastSubCell    = (SubCell)(SubCellOffsets.Length - 1);
            DefaultSubCell = (SubCell)Game.ModData.Manifest.SubCellDefaultIndex;

            if (Container.Exists("map.png"))
            {
                using (var dataStream = Container.GetContent("map.png"))
                    CustomPreview = new Bitmap(dataStream);
            }

            PostInit();

            // The Uid is calculated from the data on-disk, so
            // format changes must be flushed to disk.
            // TODO: this isn't very nice
            if (MapFormat < 7)
            {
                Save(path);
            }

            Uid = ComputeHash();
        }
Пример #23
0
        // The standard constructor for most purposes
        public Map(string path)
        {
            Path      = path;
            Container = GlobalFileSystem.OpenPackage(path, null, int.MaxValue);

            AssertExists("map.yaml");
            AssertExists("map.bin");

            var yaml = new MiniYaml(null, MiniYaml.FromStream(Container.GetContent("map.yaml"), path));

            FieldLoader.Load(this, yaml);

            // Support for formats 1-3 dropped 2011-02-11.
            // Use release-20110207 to convert older maps to format 4
            // Use release-20110511 to convert older maps to format 5
            // Use release-20141029 to convert older maps to format 6
            if (MapFormat < 6)
            {
                throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, path));
            }

            var nd = yaml.ToDictionary();

            // Format 6 -> 7 combined the Selectable and UseAsShellmap flags into the Class enum
            if (MapFormat < 7)
            {
                MiniYaml useAsShellmap;
                if (nd.TryGetValue("UseAsShellmap", out useAsShellmap) && bool.Parse(useAsShellmap.Value))
                {
                    Visibility = MapVisibility.Shellmap;
                }
                else if (Type == "Mission" || Type == "Campaign")
                {
                    Visibility = MapVisibility.MissionSelector;
                }
            }

            SpawnPoints = Exts.Lazy(() =>
            {
                var spawns = new List <CPos>();
                foreach (var kv in ActorDefinitions.Where(d => d.Value.Value == "mpspawn"))
                {
                    var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());

                    spawns.Add(s.InitDict.Get <LocationInit>().Value(null));
                }

                return(spawns.ToArray());
            });

            RuleDefinitions          = MiniYaml.NodesOrEmpty(yaml, "Rules");
            SequenceDefinitions      = MiniYaml.NodesOrEmpty(yaml, "Sequences");
            VoxelSequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "VoxelSequences");
            WeaponDefinitions        = MiniYaml.NodesOrEmpty(yaml, "Weapons");
            VoiceDefinitions         = MiniYaml.NodesOrEmpty(yaml, "Voices");
            NotificationDefinitions  = MiniYaml.NodesOrEmpty(yaml, "Notifications");
            TranslationDefinitions   = MiniYaml.NodesOrEmpty(yaml, "Translations");
            PlayerDefinitions        = MiniYaml.NodesOrEmpty(yaml, "Players");

            ActorDefinitions  = MiniYaml.NodesOrEmpty(yaml, "Actors");
            SmudgeDefinitions = MiniYaml.NodesOrEmpty(yaml, "Smudges");

            MapTiles     = Exts.Lazy(LoadMapTiles);
            MapResources = Exts.Lazy(LoadResourceTiles);
            MapHeight    = Exts.Lazy(LoadMapHeight);

            TileShape      = Game.ModData.Manifest.TileShape;
            SubCellOffsets = Game.ModData.Manifest.SubCellOffsets;
            LastSubCell    = (SubCell)(SubCellOffsets.Length - 1);
            DefaultSubCell = (SubCell)Game.ModData.Manifest.SubCellDefaultIndex;

            if (Container.Exists("map.png"))
            {
                using (var dataStream = Container.GetContent("map.png"))
                    CustomPreview = new Bitmap(dataStream);
            }

            PostInit();

            // The Uid is calculated from the data on-disk, so
            // format changes must be flushed to disk.
            // TODO: this isn't very nice
            if (MapFormat < 7)
            {
                Save(path);
            }

            Uid = ComputeHash();
        }
Пример #24
0
 public void OnScriptBind(ScriptContext context)
 {
     luaInterface = Exts.Lazy(() => new ScriptPlayerInterface(context, this));
 }
Пример #25
0
        public ModData(Manifest mod, InstalledMods mods, bool useLoadScreen = false)
        {
            Languages = new string[0];

            // Take a local copy of the manifest
            Manifest       = new Manifest(mod.Id, mod.Package);
            ObjectCreator  = new ObjectCreator(Manifest, mods);
            PackageLoaders = ObjectCreator.GetLoaders <IPackageLoader>(Manifest.PackageFormats, "package");

            ModFiles = new FS(mod.Id, mods, PackageLoaders);
            ModFiles.LoadFromManifest(Manifest);
            Manifest.LoadCustomData(ObjectCreator);

            if (useLoadScreen)
            {
                LoadScreen = ObjectCreator.CreateObject <ILoadScreen>(Manifest.LoadScreen.Value);
                LoadScreen.Init(this, Manifest.LoadScreen.ToDictionary(my => my.Value));
                LoadScreen.Display();
            }

            WidgetLoader = new WidgetLoader(this);
            MapCache     = new MapCache(this);

            SoundLoaders  = ObjectCreator.GetLoadersInherits <SoundLoader>(Manifest.SoundFormats, "sound");
            SpriteLoaders = ObjectCreator.GetLoadersInherits <SpriteLoaderBase>(Manifest.SpriteFormats, "sprite");

            var sequenceFormat = Manifest.Get <SpriteSequenceFormat>();
            var sequenceLoader = ObjectCreator.FindType(sequenceFormat.Type + "Loader");
            var sequenceCtor   = sequenceLoader != null?sequenceLoader.GetConstructor(new[] { typeof(ModData) }) : null;

            if (sequenceLoader == null || !sequenceLoader.GetInterfaces().Contains(typeof(ISpriteSequenceLoader)) || sequenceCtor == null)
            {
                throw new InvalidOperationException("Unable to find a sequence loader for type '{0}'.".F(sequenceFormat.Type));
            }

            SpriteSequenceLoader = (ISpriteSequenceLoader)sequenceCtor.Invoke(new[] { this });
            SpriteSequenceLoader.OnMissingSpriteError = s => Log.Write("debug", s);

            var modelFormat = Manifest.Get <ModelSequenceFormat>();
            var modelLoader = ObjectCreator.FindType(modelFormat.Type + "Loader");
            var modelCtor   = modelLoader != null?modelLoader.GetConstructor(new[] { typeof(ModData) }) : null;

            if (modelLoader == null || !modelLoader.GetInterfaces().Contains(typeof(IModelSequenceLoader)) || modelCtor == null)
            {
                throw new InvalidOperationException("Unable to find a model loader for type '{0}'.".F(modelFormat.Type));
            }

            ModelSequenceLoader = (IModelSequenceLoader)modelCtor.Invoke(new[] { this });
            ModelSequenceLoader.OnMissingModelError = s => Log.Write("debug", s);

            Hotkeys = new HotkeyManager(ModFiles, Game.Settings.Keys, Manifest);

            defaultRules    = Exts.Lazy(() => Ruleset.LoadDefaults(this));
            defaultTileSets = Exts.Lazy(() =>
            {
                var items = new Dictionary <string, TileSet>();

                foreach (var file in Manifest.TileSets)
                {
                    var t = new TileSet(DefaultFileSystem, file);
                    items.Add(t.Id, t);
                }

                return((IReadOnlyDictionary <string, TileSet>)(new ReadOnlyDictionary <string, TileSet>(items)));
            });

            ResetSequenceProviders();

            //defaultSequences = Exts.Lazy(() =>
            //{
            //	var items = DefaultTileSets.ToDictionary(t => t.Key, t => new SequenceProvider(DefaultFileSystem, this, t.Value, null));
            //	return (IReadOnlyDictionary<string, SequenceProvider>)(new ReadOnlyDictionary<string, SequenceProvider>(items));
            //});

            initialThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;
        }
Пример #26
0
        public ModData(Manifest mod, InstalledMods mods, bool useLoadScreen = false)
        {
            Languages = Array.Empty <string>();

            // Take a local copy of the manifest
            Manifest       = new Manifest(mod.Id, mod.Package);
            ObjectCreator  = new ObjectCreator(Manifest, mods);
            PackageLoaders = ObjectCreator.GetLoaders <IPackageLoader>(Manifest.PackageFormats, "package");

            ModFiles = new FS(mod.Id, mods, PackageLoaders);
            ModFiles.LoadFromManifest(Manifest);
            Manifest.LoadCustomData(ObjectCreator);

            if (useLoadScreen)
            {
                LoadScreen = ObjectCreator.CreateObject <ILoadScreen>(Manifest.LoadScreen.Value);
                LoadScreen.Init(this, Manifest.LoadScreen.ToDictionary(my => my.Value));
                LoadScreen.Display();
            }

            WidgetLoader = new WidgetLoader(this);
            MapCache     = new MapCache(this);

            SoundLoaders  = ObjectCreator.GetLoaders <ISoundLoader>(Manifest.SoundFormats, "sound");
            SpriteLoaders = ObjectCreator.GetLoaders <ISpriteLoader>(Manifest.SpriteFormats, "sprite");
            VideoLoaders  = ObjectCreator.GetLoaders <IVideoLoader>(Manifest.VideoFormats, "video");

            var terrainFormat = Manifest.Get <TerrainFormat>();
            var terrainLoader = ObjectCreator.FindType(terrainFormat.Type + "Loader");
            var terrainCtor   = terrainLoader?.GetConstructor(new[] { typeof(ModData) });

            if (terrainLoader == null || !terrainLoader.GetInterfaces().Contains(typeof(ITerrainLoader)) || terrainCtor == null)
            {
                throw new InvalidOperationException($"Unable to find a terrain loader for type '{terrainFormat.Type}'.");
            }

            TerrainLoader = (ITerrainLoader)terrainCtor.Invoke(new[] { this });

            var sequenceFormat = Manifest.Get <SpriteSequenceFormat>();
            var sequenceLoader = ObjectCreator.FindType(sequenceFormat.Type + "Loader");
            var sequenceCtor   = sequenceLoader?.GetConstructor(new[] { typeof(ModData) });

            if (sequenceLoader == null || !sequenceLoader.GetInterfaces().Contains(typeof(ISpriteSequenceLoader)) || sequenceCtor == null)
            {
                throw new InvalidOperationException($"Unable to find a sequence loader for type '{sequenceFormat.Type}'.");
            }

            SpriteSequenceLoader = (ISpriteSequenceLoader)sequenceCtor.Invoke(new[] { this });

            var modelFormat = Manifest.Get <ModelSequenceFormat>();
            var modelLoader = ObjectCreator.FindType(modelFormat.Type + "Loader");
            var modelCtor   = modelLoader?.GetConstructor(new[] { typeof(ModData) });

            if (modelLoader == null || !modelLoader.GetInterfaces().Contains(typeof(IModelSequenceLoader)) || modelCtor == null)
            {
                throw new InvalidOperationException($"Unable to find a model loader for type '{modelFormat.Type}'.");
            }

            ModelSequenceLoader = (IModelSequenceLoader)modelCtor.Invoke(new[] { this });
            ModelSequenceLoader.OnMissingModelError = s => Log.Write("debug", s);

            Hotkeys = new HotkeyManager(ModFiles, Game.Settings.Keys, Manifest);

            Translation = new Translation(Game.Settings.Player.Language, Manifest.Translations, DefaultFileSystem);

            defaultRules       = Exts.Lazy(() => Ruleset.LoadDefaults(this));
            defaultTerrainInfo = Exts.Lazy(() =>
            {
                var items = new Dictionary <string, ITerrainInfo>();

                foreach (var file in Manifest.TileSets)
                {
                    var t = TerrainLoader.ParseTerrain(DefaultFileSystem, file);
                    items.Add(t.Id, t);
                }

                return((IReadOnlyDictionary <string, ITerrainInfo>)(new ReadOnlyDictionary <string, ITerrainInfo>(items)));
            });

            defaultSequences = Exts.Lazy(() =>
            {
                var items = DefaultTerrainInfo.ToDictionary(t => t.Key, t => new SequenceProvider(DefaultFileSystem, this, t.Key, null));
                return((IReadOnlyDictionary <string, SequenceProvider>)(new ReadOnlyDictionary <string, SequenceProvider>(items)));
            });

            initialThreadId = Environment.CurrentManagedThreadId;
        }