Exemple #1
0
    public static List <TiledMapLayer> BuildLayers(MapData2D map, TilesetData tileset, ref int nextLayerId)
    {
        var underlayId = nextLayerId++;
        var overlayId  = nextLayerId++;

        return(new()
        {
            new()
            {
                Id = underlayId,
                Name = LayerName.Underlay,
                Width = map.Width,
                Height = map.Height,
                Data = new LayerData {
                    Encoding = "csv", Content = BuildCsvData(map, tileset, false)
                }
            },
            new()
            {
                Id = overlayId,
                Name = LayerName.Overlay,
                Width = map.Width,
                Height = map.Height,
                Data = new LayerData {
                    Encoding = "csv", Content = BuildCsvData(map, tileset, true)
                }
            }
        });
    }
Exemple #2
0
        void Write(BaseMapData existing, AssetInfo info, ISerializer s)
        {
            (byte[] bytes, string script) = existing switch
            {
                MapData2D map2d => Write2D(map2d, info),
                MapData3D map3d => Write3D(map3d, info),
                _ => (null, null)
            };

            if (bytes != null)
            {
                s.Bytes(null, bytes, bytes.Length);
            }

            var disk          = Resolve <IFileSystem>();
            var scriptPattern = info.Get(AssetProperty.ScriptPattern, "");

            if (script == null || string.IsNullOrEmpty(scriptPattern))
            {
                return;
            }

            // TODO: Find a less hacky way of doing this
            var scriptPath = info.BuildFilename(scriptPattern, 0);
            var assetDir   = GetAssetDir(info);

            if (!disk.DirectoryExists(assetDir))
            {
                disk.CreateDirectory(assetDir);
            }
            disk.WriteAllText(Path.Combine(assetDir, scriptPath), script);
        }
Exemple #3
0
        public MapRenderable2D(MapData2D mapData, ITexture tileset, TilesetData tileData) : base(Handlers)
        {
            _mapData  = mapData;
            _tileset  = tileset;
            _tileData = tileData;
            _tileset.GetSubImageDetails(0, out var tileSize, out _, out _, out _);
            TileSize = tileSize;

            var underlay = new SpriteInstanceData[_mapData.Width * _mapData.Height];
            var overlay  = new SpriteInstanceData[_mapData.Width * _mapData.Height];

            _underlay = new MultiSprite(new SpriteKey(
                                            _tileset,
                                            (int)DrawLayer.Underlay,
                                            underlay[0].Flags))
            {
                Instances = underlay.ToArray()
            };

            _overlay = new MultiSprite(new SpriteKey(
                                           _tileset,
                                           (int)DrawLayer.Overlay3,
                                           overlay[0].Flags))
            {
                Instances = overlay.ToArray()
            };
        }
Exemple #4
0
        static IEnumerable <ObjectGroup> BuildTriggers(
            MapData2D map,
            TilemapProperties properties,
            EventFormatter eventFormatter,
            ref int nextObjectGroupId,
            ref int nextObjectId)
        {
            var objectGroups = new List <ObjectGroup>();

            var regions = TriggerZoneBuilder.BuildZones(map);
            var groupedByTriggerType = regions
                                       .Where(x => x.Item1.Chain != null)
                                       .GroupBy(x => x.Item1.Trigger)
                                       .OrderBy(x => x.Key);

            foreach (var triggerType in groupedByTriggerType)
            {
                objectGroups.Add(BuildTriggerObjectGroup(
                                     nextObjectGroupId++,
                                     $"T:{triggerType.Key}",
                                     triggerType,
                                     properties,
                                     eventFormatter,
                                     ref nextObjectId));
            }

            return(objectGroups);
        }
Exemple #5
0
        public LogicalMap2D(IAssetManager assetManager, MapData2D mapData,
                            IList <MapChange> tempChanges,
                            IList <MapChange> permChanges)
        {
            _mapData        = mapData ?? throw new ArgumentNullException(nameof(mapData));
            _tempChanges    = tempChanges ?? throw new ArgumentNullException(nameof(tempChanges));
            _permChanges    = permChanges ?? throw new ArgumentNullException(nameof(permChanges));
            _tileData       = assetManager.LoadTileData(_mapData.TilesetId);
            _blockList      = assetManager.LoadBlockList((BlockListId)_mapData.TilesetId); // Note: Assuming a 1:1 correspondence between blocklist and tileset ids.
            UseSmallSprites = _tileData.UseSmallGraphics;

            // Clear out temp changes for other maps
            for (int i = 0; i < tempChanges.Count;)
            {
                if (_tempChanges[i].MapId != mapData.Id)
                {
                    _tempChanges.RemoveAt(i);
                }
                else
                {
                    i++;
                }
            }

            // Replay any changes for this map
            foreach (var change in permChanges.Where(x => x.MapId == mapData.Id))
            {
                ApplyChange(change.X, change.Y, change.ChangeType, change.Value, change.Unk3);
            }

            foreach (var change in tempChanges)
            {
                ApplyChange(change.X, change.Y, change.ChangeType, change.Value, change.Unk3);
            }
        }
 public MapRenderable2D(MapData2D mapData, ITexture tileset, TilesetData tileData) : base(Handlers)
 {
     _mapData  = mapData;
     _tileset  = tileset;
     _tileData = tileData;
     _tileset.GetSubImageDetails(0, out var tileSize, out _, out _, out _);
     TileSize = tileSize;
 }
Exemple #7
0
        public static (Map, string) FromAlbionMap2D(
            MapData2D map,
            TilesetData tileset,
            Tilemap2DProperties properties,
            string tilesetPath,
            Tileset npcTileset,
            EventFormatter eventFormatter)
        {
            if (map == null)
            {
                throw new ArgumentNullException(nameof(map));
            }
            if (tileset == null)
            {
                throw new ArgumentNullException(nameof(tileset));
            }
            if (properties == null)
            {
                throw new ArgumentNullException(nameof(properties));
            }
            if (npcTileset == null)
            {
                throw new ArgumentNullException(nameof(npcTileset));
            }

            ushort blankTileIndex = 0;
            int    nextObjectId   = 1;
            int    nextLayerId    = 3; // 1 & 2 are always underlay & overlay.

            npcTileset.GidOffset            = tileset.Tiles.Count;
            var(script, functionsByEventId) = BuildScript(map, eventFormatter);

            var result = new Map
            {
                TiledVersion    = "1.4.2",
                Version         = "1.4",
                Width           = map.Width,
                Height          = map.Height,
                TileWidth       = properties.TileWidth,
                TileHeight      = properties.TileHeight,
                Infinite        = 0,
                NextLayerId     = 5, // max(layer or objectgroup id) + 1
                Orientation     = "orthogonal",
                RenderOrder     = "right-down",
                BackgroundColor = "#000000",
                Properties      = BuildMapProperties(map),
                Tilesets        = new List <MapTileset>
                {
                    new() { FirstGid = 0, Source = tilesetPath, },
                    new() { FirstGid = npcTileset.GidOffset, Source = npcTileset.Filename }
                },
Exemple #8
0
 public LogicalMap2D(
     IAssetManager assetManager,
     MapData2D mapData,
     MapChangeCollection tempChanges,
     MapChangeCollection permChanges) : base(mapData, tempChanges, permChanges)
 {
     if (assetManager == null)
     {
         throw new ArgumentNullException(nameof(assetManager));
     }
     _mapData        = mapData ?? throw new ArgumentNullException(nameof(mapData));
     _tileData       = assetManager.LoadTileData(_mapData.TilesetId);
     _blockList      = assetManager.LoadBlockList(_mapData.TilesetId.ToBlockList());
     UseSmallSprites = _tileData.UseSmallGraphics;
 }
Exemple #9
0
        public IMapData Serdes(IMapData existing, ISerializer s, AssetKey key, AssetInfo config)
        {
            var startPosition = s.Offset;

            s.UInt16("DummyRead", 0); // Initial flags + npc count, will be re-read by the 2D/3D specific map loader
            MapType mapType = s.EnumU8(nameof(mapType), existing?.MapType ?? MapType.Unknown);

            s.Seek(startPosition);

            return(mapType switch
            {
                MapType.TwoD => MapData2D.Serdes((MapData2D)existing, s, config),
                MapType.TwoDOutdoors => MapData2D.Serdes((MapData2D)existing, s, config),
                MapType.ThreeD => MapData3D.Serdes((MapData3D)existing, s, config),
                _ => throw new NotImplementedException($"Unrecognised map type {mapType} found.")
            });
Exemple #10
0
        public FlatMap(MapId mapId, MapData2D mapData)
        {
            On <PlayerEnteredTileEvent>(OnPlayerEnteredTile);
            On <NpcEnteredTileEvent>(OnNpcEnteredTile);
            On <ChangeIconEvent>(ChangeIcon);
            On <MapInitEvent>(e => FireEventChains(TriggerTypes.MapInit, true));
            On <SlowClockEvent>(e => FireEventChains(TriggerTypes.EveryStep, false));
            On <HourElapsedEvent>(e => FireEventChains(TriggerTypes.EveryHour, true));
            On <DayElapsedEvent>(e => FireEventChains(TriggerTypes.EveryDay, true));
            On <DisableEventChainEvent>(e => _logicalMap.DisableChain(e.ChainNumber));
            On <PartyChangedEvent>(e => RebuildPartyMembers());
            // On<UnloadMapEvent>(e => Unload());

            MapId    = mapId;
            _mapData = mapData ?? throw new ArgumentNullException(nameof(mapData));
        }
Exemple #11
0
        public object Load(BinaryReader br, long streamLength, string name, AssetInfo config)
        {
            var startPosition = br.BaseStream.Position;

            br.ReadUInt16(); // Initial flags + npc count, will be re-read by the 2D/3D specific map loader
            int mapType = br.ReadByte();

            br.BaseStream.Position = startPosition;
            switch (mapType)
            {
            case 1: return(MapData3D.Load(br, streamLength, name));

            case 2: return(MapData2D.Load(br, streamLength, name));

            default: throw new NotImplementedException($"Unrecognised map type {mapType} found.");
            }
        }
Exemple #12
0
        IMap BuildMap(MapId mapId)
        {
            var assets  = Resolve <IAssetManager>();
            var game    = Resolve <IGameState>();
            var mapData = assets.LoadMap(mapId);

            if (mapData == null)
            {
                return(null);
            }

            return(mapData switch
            {
                MapData2D map2d => new Entities.Map2D.FlatMap(mapId, map2d),
                MapData3D map3d => new Entities.Map3D.DungeonMap(mapId, map3d),
                _ => null
            });
Exemple #13
0
        public override void Subscribed()
        {
            if (_mapData == null)
            {
                var assets = Resolve <IAssetManager>();
                _mapData = assets.LoadMap2D(MapId);
                var tileset = assets.LoadTexture((IconGraphicsId)_mapData.TilesetId);
                _tileData        = assets.LoadTileData((IconDataId)_mapData.TilesetId);
                _renderable      = new MapRenderable2D(_mapData, tileset, _tileData);
                _useSmallSprites = _tileData.UseSmallGraphics;

                Exchange.Attach(_renderable);
                Children.Add(_renderable);
                foreach (var npc in _mapData.Npcs)
                {
                    IComponent sprite =
                        _useSmallSprites
                            ? new SmallNpc((SmallNpcId)npc.ObjectNumber, npc.Waypoints) as IComponent
                            : new LargeNpc((LargeNpcId)npc.ObjectNumber, npc.Waypoints);

                    Exchange.Attach(sprite);
                    Children.Add(sprite);
                }

                IMovement partyMovement = new PartyMovement(_useSmallSprites, Vector2.Zero, PartyMovement.Direction.Right);  // TODO: Initial position.
                Exchange.Register(partyMovement);
                Children.Add(partyMovement);

                var state = Resolve <IGameState>();
                foreach (var player in state.Party.StatusBarOrder)
                {
                    player.GetPosition = () => partyMovement.GetPositionHistory(player.Id).Item1;
                    var playerSprite = _useSmallSprites
                        ? (IComponent) new SmallPlayer(player.Id, (SmallPartyGraphicsId)player.Id, () => partyMovement.GetPositionHistory(player.Id)) // TODO: Use a function to translate logical to sprite id
                        : new LargePlayer(player.Id, (LargePartyGraphicsId)player.Id, () => partyMovement.GetPositionHistory(player.Id));             // TODO: Use a function to translate logical to sprite id

                    Exchange.Attach(playerSprite);
                    Children.Add(playerSprite);
                }
            }

            Raise(new SetClearColourEvent(0, 0, 0));
        }
Exemple #14
0
    static string BuildCsvData(MapData2D map, TilesetData tileset, bool useOverlay)
    {
        var sb = new StringBuilder();

        for (int j = 0; j < map.Height; j++)
        {
            for (int i = 0; i < map.Width; i++)
            {
                int index     = j * map.Width + i;
                var tileIndex = useOverlay ? map.Overlay[index] : map.Underlay[index];
                var tile      = tileset.Tiles[tileIndex];
                sb.Append(tile.IsBlank ? BlankTileIndex : tileIndex);
                sb.Append(',');
            }

            sb.AppendLine();
        }
        return(sb.ToString(0, sb.Length - (Environment.NewLine.Length + 1)));
    }
Exemple #15
0
    void Write(BaseMapData existing, AssetInfo info, ISerializer s)
    {
        (byte[] bytes, string script) = existing switch
        {
            MapData2D map2d => Write2D(map2d, info),
            MapData3D map3d => Write3D(map3d, info),
            _ => (null, null)
        };

        if (bytes != null)
        {
            s.Bytes(null, bytes, bytes.Length);
        }
        else
        {
            Warn($"No bytes were generated when saving map {info.Id}");
        }

        if (script == null)
        {
            Warn($"No script for map {info.Id}, aborting script output");
            return;
        }

        var scriptPath = GetScriptFilename(info);

        if (string.IsNullOrEmpty(scriptPath))
        {
            Warn($"No script path was set for map {info.Id}, aborting script output");
            return;
        }

        var disk     = Resolve <IFileSystem>();
        var assetDir = GetAssetDir(info);

        if (!disk.DirectoryExists(assetDir))
        {
            disk.CreateDirectory(assetDir);
        }
        disk.WriteAllText(Path.Combine(assetDir, scriptPath), script);
    }
Exemple #16
0
        public LogicalMap2D(
            IAssetManager assetManager,
            MapData2D mapData,
            MapChangeCollection tempChanges,
            MapChangeCollection permChanges)
        {
            if (assetManager == null)
            {
                throw new ArgumentNullException(nameof(assetManager));
            }
            _mapData        = mapData ?? throw new ArgumentNullException(nameof(mapData));
            _tempChanges    = tempChanges ?? throw new ArgumentNullException(nameof(tempChanges));
            _permChanges    = permChanges ?? throw new ArgumentNullException(nameof(permChanges));
            _tileData       = assetManager.LoadTileData(_mapData.TilesetId);
            _blockList      = assetManager.LoadBlockList(_mapData.TilesetId.ToBlockList());
            UseSmallSprites = _tileData.UseSmallGraphics;

            // Clear out temp changes for other maps
            for (int i = 0; i < tempChanges.Count;)
            {
                if (_tempChanges[i].MapId != mapData.Id)
                {
                    _tempChanges.RemoveAt(i);
                }
                else
                {
                    i++;
                }
            }

            // Replay any changes for this map
            foreach (var change in permChanges.Where(x => x.MapId == mapData.Id))
            {
                ApplyChange(change.X, change.Y, change.ChangeType, change.Value);
            }

            foreach (var change in tempChanges)
            {
                ApplyChange(change.X, change.Y, change.ChangeType, change.Value);
            }
        }
Exemple #17
0
        IMap BuildMap(MapId mapId)
        {
            var assets  = Resolve <IAssetManager>();
            var game    = Resolve <IGameState>();
            var mapData = assets.LoadMap(mapId);

            if (mapData == null)
            {
                return(null);
            }

            mapData.AttachEventSets(
                x => game.GetSheet(x),
                x => assets.LoadEventSet(x));

            return(mapData switch
            {
                MapData2D map2d => new Entities.Map2D.FlatMap(mapId, map2d),
                MapData3D map3d => new Entities.Map3D.DungeonMap(mapId, map3d),
                _ => null
            });
Exemple #18
0
 public FlatMapEditor(string name, MapData2D map) : base(map)
 {
     _name = name;
     _map  = map ?? throw new ArgumentNullException(nameof(map));
 }
Exemple #19
0
    public static (Map, string) FromAlbionMap2D(
        MapData2D map,
        TilesetData tileset,
        Tilemap2DProperties properties,
        string tilesetPath,
        Tileset npcTileset,
        EventFormatter eventFormatter)
    {
        if (map == null)
        {
            throw new ArgumentNullException(nameof(map));
        }
        if (tileset == null)
        {
            throw new ArgumentNullException(nameof(tileset));
        }
        if (properties == null)
        {
            throw new ArgumentNullException(nameof(properties));
        }
        if (npcTileset == null)
        {
            throw new ArgumentNullException(nameof(npcTileset));
        }

        int npcGidOffset = tileset.Tiles.Count;

        var(script, functionsByEventId) = BuildScript(map, eventFormatter);

        (int?tileId, int w, int h) GetNpcTileInfo(AssetId id)
        {
            var assetName = id.ToString();
            var tile      = npcTileset.Tiles.FirstOrDefault(x => x.Properties.Any(p => p.Name == NpcMapping.Prop.Visual && p.Value == assetName));

            return(
                tile?.Id + npcGidOffset ?? 0,
                tile?.Image.Width ?? properties.TileWidth,
                tile?.Image.Height ?? properties.TileHeight);
        }

        int nextObjectId = 1;
        int nextLayerId  = 1;

        var result = new Map
        {
            TiledVersion    = "1.4.2",
            Version         = "1.4",
            Width           = map.Width,
            Height          = map.Height,
            TileWidth       = properties.TileWidth,
            TileHeight      = properties.TileHeight,
            Infinite        = 0,
            Orientation     = "orthogonal",
            RenderOrder     = "right-down",
            BackgroundColor = "#000000",
            Properties      = MapMapping.BuildMapProperties(map),
            Tilesets        = new List <MapTileset>
            {
                new() { FirstGid = 0, Source = tilesetPath, },
                new() { FirstGid = npcGidOffset, Source = npcTileset.Filename }
            },
Exemple #20
0
        public static Map FromAlbionMap(
            MapData2D map,
            TilesetData tileset,
            TilemapProperties properties,
            string tilesetPath,
            Tileset npcTileset,
            EventFormatter eventFormatter)
        {
            if (map == null)
            {
                throw new ArgumentNullException(nameof(map));
            }
            if (tileset == null)
            {
                throw new ArgumentNullException(nameof(tileset));
            }
            if (properties == null)
            {
                throw new ArgumentNullException(nameof(properties));
            }
            if (npcTileset == null)
            {
                throw new ArgumentNullException(nameof(npcTileset));
            }

            ushort blankTileIndex    = (ushort)(tileset.Tiles.Max(x => x.ImageNumber + x.FrameCount - 1) + 1);
            int    nextObjectId      = 1;
            int    nextObjectGroupId = 3; // 1 & 2 are always underlay & overlay.

            npcTileset.GidOffset = tileset.Tiles.Count + 1;

            return(new Map
            {
                TiledVersion = "1.4.2",
                Version = "1.4",
                Width = map.Width,
                Height = map.Height,
                TileWidth = properties.TileWidth,
                TileHeight = properties.TileHeight,
                Infinite = 0,
                NextLayerId = 5, // max(layer or objectgroup id) + 1
                NextObjectId = 1,
                Orientation = "orthogonal",
                RenderOrder = "right-down",
                BackgroundColor = "#000000",
                Tilesets = new List <MapTileset>
                {
                    new MapTileset {
                        FirstGid = 1, Source = tilesetPath,
                    },
                    new MapTileset {
                        FirstGid = npcTileset.GidOffset, Source = npcTileset.Filename
                    }
                },
                Layers = new List <MapLayer> {
                    new MapLayer
                    {
                        Id = 1,
                        Name = "Underlay",
                        Width = map.Width,
                        Height = map.Height,
                        Data = new LayerData {
                            Encoding = "csv", Content = BuildCsvData(map, tileset, false, blankTileIndex)
                        }
                    },
                    new MapLayer
                    {
                        Id = 2,
                        Name = "Overlay",
                        Width = map.Width,
                        Height = map.Height,
                        Data = new LayerData {
                            Encoding = "csv", Content = BuildCsvData(map, tileset, true, blankTileIndex)
                        }
                    }
                },
                ObjectGroups = new[] {
                    BuildTriggers(map, properties, eventFormatter, ref nextObjectGroupId, ref nextObjectId),
                    BuildNpcs(map, properties, eventFormatter, npcTileset, ref nextObjectGroupId, ref nextObjectId)
                }.SelectMany(x => x).ToList()
            });
        }
Exemple #21
0
    public static BaseMapData ToAlbion(this Map map, AssetInfo info, string script)
    {
        if (map == null)
        {
            throw new ArgumentNullException(nameof(map));
        }
        if (info == null)
        {
            throw new ArgumentNullException(nameof(info));
        }

        // Check width/height <= 255
        if (map.Width > 255)
        {
            throw new FormatException($"Map widths above 255 are not currently supported (was {map.Width})");
        }
        if (map.Height > 255)
        {
            throw new FormatException($"Map heights above 255 are not currently supported (was {map.Height})");
        }

        bool is3d        = map.Orientation == "isometric";
        var  mapId       = (MapId)info.AssetId;
        var  eventLayout = AlbionCompiler.Compile(script, mapId.ToMapText());

        List <TriggerInfo>  triggers    = new();
        List <MapNpc>       npcs        = new();
        List <MapEventZone> zones       = new();
        List <AutomapInfo>  markers     = new();
        List <byte>         markerTiles = new();

        ObjectGroupMapping.LoadObjectGroups(
            info, map,
            is3d ? map.TileHeight : map.TileWidth,
            map.TileHeight,
            eventLayout, triggers, npcs, zones,
            markers, markerTiles);

        var paletteId = MapperUtil.PropId(map, MapMapping.Prop.Palette, true);

        BaseMapData albionMap;

        if (is3d)
        {
            var labId = MapperUtil.PropId(map, MapMapping.Prop.Labyrinth, true);
            var map3d = new MapData3D(info.AssetId, paletteId, labId, (byte)map.Width, (byte)map.Height, eventLayout.Events, eventLayout.Chains, npcs, zones);
            LayerMapping3D.ReadLayers(map3d, map.Layers);

            for (int i = 0; i < markerTiles.Count; i++)
            {
                map3d.AutomapGraphics[i] = markerTiles[i];
            }

            map3d.Automap.Clear();
            map3d.Automap.AddRange(markers);

            albionMap = map3d;
        }
        else
        {
            var tilesetId = MapperUtil.PropId(map, MapMapping.Prop.Tileset, true);
            albionMap = new MapData2D(info.AssetId, paletteId, tilesetId, (byte)map.Width, (byte)map.Height, eventLayout.Events, eventLayout.Chains, npcs, zones)
            {
                RawLayout = LayerMapping2D.ReadLayout(map)
            };
        }

        MapMapping.ReadMapProperties(albionMap, map);
        return(albionMap);
    }