public MapRenderable3D(MapDataId mapId, MapData3D mapData, LabyrinthData labyrinthData, Vector3 tileSize) : base(Handlers) { _mapId = mapId; _mapData = mapData; _labyrinthData = labyrinthData; _tileSize = tileSize; }
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); }
public LogicalMap3D(MapData3D mapData, LabyrinthData labyrinth, MapChangeCollection tempChanges, MapChangeCollection permChanges) : base(mapData, tempChanges, permChanges) { _mapData = mapData ?? throw new ArgumentNullException(nameof(mapData)); _labyrinth = labyrinth ?? throw new ArgumentNullException(nameof(labyrinth)); }
public MapRenderable3D(MapId mapId, MapData3D mapData, LabyrinthData labyrinthData, Vector3 tileSize) { On <SlowClockEvent>(OnSlowClock); On <SortMapTilesEvent>(e => _isSorting = e.IsSorting); On <LoadPaletteEvent>(e => { }); _mapId = mapId; _mapData = mapData; _labyrinthData = labyrinthData; _tileSize = tileSize; }
public DungeonMap(MapId mapId, MapData3D mapData) { On <WorldCoordinateSelectEvent>(Select); On <MapInitEvent>(e => FireEventChains(TriggerTypes.MapInit, true)); On <SlowClockEvent>(e => FireEventChains(TriggerTypes.EveryStep, false)); On <HourElapsedEvent>(e => FireEventChains(TriggerTypes.EveryHour, false)); On <DayElapsedEvent>(e => FireEventChains(TriggerTypes.EveryDay, false)); // On<UnloadMapEvent>(e => Unload()); MapId = mapId; _mapData = mapData ?? throw new ArgumentNullException(nameof(mapData)); }
public static List <TiledMapLayer> BuildLayers(MapData3D map, ref int nextLayerId) { int floorId = nextLayerId++; int wallId = nextLayerId++; int contentId = nextLayerId++; int ceilingid = nextLayerId++; return(new List <TiledMapLayer> { new() { Id = floorId, Name = LayerName.Floors, Width = map.Width, Height = map.Height, Data = new LayerData { Encoding = "csv", Content = BuildCsvData(map, IsometricMode.Floors) } }, new() { Id = wallId, Name = LayerName.Walls, Width = map.Width, Height = map.Height, Data = new LayerData { Encoding = "csv", Content = BuildCsvData(map, IsometricMode.Walls) } }, new() { Id = contentId, Name = LayerName.Contents, Width = map.Width, Height = map.Height, Data = new LayerData { Encoding = "csv", Content = BuildCsvData(map, IsometricMode.Contents) } }, new() { Id = ceilingid, Name = LayerName.Ceilings, Width = map.Width, Height = map.Height, Opacity = 0.5, Data = new LayerData { Encoding = "csv", Content = BuildCsvData(map, IsometricMode.Ceilings) } } });
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.") });
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 });
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."); } }
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); }
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 });
public static IEnumerable <ObjectGroup> BuildMarkers(MapData3D map, int tileWidth, int tileHeight, ref int nextObjectGroupId, ref int nextObjectId) { if (map.Automap == null || map.Automap.Count == 0 || map.AutomapGraphics == null) { return(Enumerable.Empty <ObjectGroup>()); } int nextId = nextObjectId; int npcGroupId = nextObjectGroupId++; var group = new ObjectGroup { Id = npcGroupId, Name = "Map Markers", Objects = map.Automap .Zip(map.AutomapGraphics) .Select(x => BuildMarker(tileWidth, tileHeight, x.First, x.Second, ref nextId)) .ToList() }; nextObjectId = nextId; return(new[] { group }); }
void LoadMap() { var assets = Resolve <IAssetManager>(); _mapData = assets.LoadMap3D(MapId); _labyrinthData = assets.LoadLabyrinthData(_mapData.LabDataId); if (_labyrinthData == null) { TileSize = Vector3.One * 512; return; } TileSize = new Vector3(_labyrinthData.EffectiveWallWidth, _labyrinthData.WallHeight, _labyrinthData.EffectiveWallWidth); _renderable = new MapRenderable3D(MapId, _mapData, _labyrinthData, TileSize); Exchange.Attach(_renderable); Children.Add(_renderable); if (_labyrinthData.BackgroundId.HasValue) { _skybox = new Skybox(_labyrinthData.BackgroundId.Value); Exchange.Attach(_skybox); Children.Add(_skybox); } var palette = assets.LoadPalette(_mapData.PaletteId); uint backgroundColour = palette.GetPaletteAtTime(0)[_labyrinthData.BackgroundColour]; _backgroundRed = (backgroundColour & 0xff) / 255.0f; _backgroundGreen = (backgroundColour & 0xff00 >> 8) / 255.0f; _backgroundBlue = (backgroundColour & 0xff0000 >> 16) / 255.0f; //if(_labyrinthData.CameraHeight != 0) // Debugger.Break(); //if(_labyrinthData.Unk12 != 0) // 7=1|2|4 (Jirinaar), 54=32|16|4|2, 156=128|16|8|2 (Tall town) // Debugger.Break(); var maxObjectHeightRaw = _labyrinthData.ObjectGroups.Max(x => x.SubObjects.Max(y => (int?)y.Y)); float objectYScaling = TileSize.Y / _labyrinthData.WallHeight; if (maxObjectHeightRaw > _labyrinthData.WallHeight * 1.5f) { objectYScaling /= 2; // TODO: Figure out the proper way to handle this. } Raise(new LogEvent(LogEvent.Level.Info, $"WallHeight: {_labyrinthData.WallHeight} MaxObj: {maxObjectHeightRaw} EffWallWidth: {_labyrinthData.EffectiveWallWidth}")); foreach (var npc in _mapData.Npcs) { var objectData = _labyrinthData.ObjectGroups[npc.ObjectNumber - 1]; foreach (var subObject in objectData.SubObjects) { var sprite = BuildMapObject(npc.Waypoints[0].X, npc.Waypoints[0].Y, subObject, objectYScaling); if (sprite == null) { continue; } Exchange.Attach(sprite); Children.Add(sprite); } } for (int y = 0; y < _mapData.Height; y++) { for (int x = 0; x < _mapData.Width; x++) { var contents = _mapData.Contents[y * _mapData.Width + x]; if (contents == 0 || contents >= _labyrinthData.ObjectGroups.Count) { continue; } var objectInfo = _labyrinthData.ObjectGroups[contents - 1]; foreach (var subObject in objectInfo.SubObjects) { var sprite = BuildMapObject(x, y, subObject, objectYScaling); if (sprite == null) { continue; } Exchange.Attach(sprite); Children.Add(sprite); } } } }
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); }