public IExtrudedTilemap CreateTilemap(TilemapRequest request) { if (request == null) { throw new ArgumentNullException(nameof(request)); } if (request.Id == null) { throw new ArgumentException("The tilemap request did not have an id set", nameof(request)); } var properties = new DungeonTileMapProperties( request.Scale, request.Rotation, request.Origin, request.HorizontalSpacing, request.VerticalSpacing, request.Width, request.AmbientLightLevel, request.FogColor, request.ObjectYScaling); var result = new ExtrudedTilemap( this, request.Id, request.Id.ToString(), request.TileCount, properties, request.DayPalette, request.NightPalette) { RendererId = request.Pipeline }; AttachChild(result); return(result); }
public void Load(LabyrinthId labyrinthId, IsometricMode mode, TilemapRequest request, int?paletteId) { var assets = Resolve <IAssetManager>(); var labyrinthData = assets.LoadLabyrinthData(labyrinthId); var info = assets.GetAssetInfo(labyrinthId); if (labyrinthData == null || info == null) { return; } Load(labyrinthData, info, mode, request, paletteId, assets); }
public void Update(TilemapRequest request) { if (request == null) { return; } _tilemap.Width = request.Width; _tilemap.TileCount = request.TileCount; _tilemap.Scale = request.Scale; _tilemap.Rotation = request.Rotation; _tilemap.Origin = request.Origin; _tilemap.VerticalSpacing = request.VerticalSpacing; _tilemap.HorizontalSpacing = request.HorizontalSpacing; _tilemap.FogColor = request.FogColor; _tilemap.AmbientLightLevel = request.AmbientLightLevel; _tilemap.ObjectYScaling = request.ObjectYScaling; }
void AddSprites(LabyrinthData labyrinthData, int index, TilemapRequest request) { int contents = _contents[index]; if (contents == 0 || contents >= labyrinthData.ObjectGroups.Count) { return; } var x = (int)(index % request.Width); var y = (int)(index / request.Width); var objectInfo = labyrinthData.ObjectGroups[contents - 1]; foreach (var subObject in objectInfo.SubObjects) { var mapObject = AttachChild(MapObject.Build(x, y, labyrinthData, subObject, request)); if (mapObject != null) { Info($"at ({x},{y}): ({subObject.X}, {subObject.Y}, {subObject.Z}) resolves to {mapObject.Position} ({mapObject.SpriteId})"); } } }
public MapRenderable3D(LogicalMap3D logicalMap, LabyrinthData labyrinthData, TilemapRequest properties) { if (logicalMap == null) { throw new ArgumentNullException(nameof(logicalMap)); } if (labyrinthData == null) { throw new ArgumentNullException(nameof(labyrinthData)); } On <SlowClockEvent>(OnSlowClock); On <RenderEvent>(_ => Update(false)); On <SortMapTilesEvent>(e => _isSorting = e.IsSorting); On <PaletteChangedEvent>(_ => { var paletteManager = Resolve <IPaletteManager>(); if (_tilemap != null) { _tilemap.DayFloors.Palette = paletteManager.Palette; _tilemap.DayWalls.Palette = paletteManager.Palette; } }); _logicalMap = logicalMap; _labyrinthData = labyrinthData; _properties = properties; _logicalMap.Dirty += (_, args) => { if (args.Type is IconChangeType.Floor or IconChangeType.Ceiling or IconChangeType.Wall) { _dirty.Add(_logicalMap.Index(args.X, args.Y)); } }; }
public void Load(LabyrinthData labyrinthData, AssetInfo info, IsometricMode mode, TilemapRequest request, int?paletteNumber, IAssetManager assets) { if (labyrinthData == null) { throw new ArgumentNullException(nameof(labyrinthData)); } if (info == null) { throw new ArgumentNullException(nameof(info)); } if (request == null) { throw new ArgumentNullException(nameof(request)); } if (assets == null) { throw new ArgumentNullException(nameof(assets)); } RemoveAllChildren(); bool floors = mode is IsometricMode.Floors or IsometricMode.All; bool ceilings = mode is IsometricMode.Ceilings or IsometricMode.All; bool walls = mode is IsometricMode.Walls or IsometricMode.All; bool contents = mode is IsometricMode.Contents or IsometricMode.All; paletteNumber ??= info.Get(AssetProperty.PaletteId, 0); var paletteId = new PaletteId(AssetType.Palette, paletteNumber.Value); var palette = assets.LoadPalette(paletteId); if (palette == null) { Error($"Could not load palette {paletteNumber}"); palette = assets.LoadPalette(Base.Palette.Common); } else { Raise(new LoadPaletteEvent(paletteId)); } var etmManager = Resolve <IEtmManager>(); request.Pipeline = DungeonTilemapPipeline.NoCulling; request.DayPalette = palette; _tilemap = etmManager.CreateTilemap(request /*labyrinthData.Id, 0, request, palette, null, DungeonTilemapPipeline.NoCulling */); // Layout: // [Empty] [First frame of all floors] [First frame of all ceilings] [First frame of all walls] [Additional floor frames] [Additional ceiling frames] [Additional wall frames] int totalTiles = 1; if (floors || ceilings) { for (int i = 0; i < labyrinthData.FloorAndCeilings.Count; i++) { var floorInfo = labyrinthData.FloorAndCeilings[i]; var floor = floorInfo == null ? null : assets.LoadTexture(floorInfo.SpriteId); _tilemap.DefineFloor(i + 1, floor); if (floors) { totalTiles += _tilemap.DayFloors.GetFrameCountForLogicalId(i + 1); } if (ceilings) { totalTiles += _tilemap.DayFloors.GetFrameCountForLogicalId(i + 1); } } } if (walls) { for (int i = 0; i < labyrinthData.Walls.Count; i++) { var wallInfo = labyrinthData.Walls[i]; bool isAlphaTested = wallInfo != null && (wallInfo.Properties & Wall.WallFlags.AlphaTested) != 0; var wall = wallInfo == null ? null : assets.LoadTexture(wallInfo.SpriteId); _tilemap.DefineWall(i + 1, wall, 0, 0, wallInfo?.TransparentColour ?? 0, isAlphaTested); foreach (var overlayInfo in wallInfo?.Overlays ?? Array.Empty <Overlay>()) { if (overlayInfo.SpriteId.IsNone) { continue; } var overlay = assets.LoadTexture(overlayInfo.SpriteId); _tilemap.DefineWall(i + 1, overlay, overlayInfo.XOffset, overlayInfo.YOffset, wallInfo?.TransparentColour ?? 0, isAlphaTested); } totalTiles += _tilemap.DayWalls.GetFrameCountForLogicalId(i + 1); } } if (contents) { var transparent = new SimpleTexture <byte>(AssetId.None, "Transparent", 1, 1, new byte[] { 0 }) .AddRegion(Vector2.Zero, Vector2.One, 0); for (byte i = 1; i <= labyrinthData.ObjectGroups.Count; i++) { _tilemap.DefineWall(i, transparent, 0, 0, 0, true); } totalTiles += labyrinthData.ObjectGroups.Count; } _wallCount = labyrinthData.Walls.Count; _floors = new byte[totalTiles]; _ceilings = new byte[totalTiles]; _contents = new byte[totalTiles]; var frames = new int[totalTiles]; int index = 1; // Add initial frames if (floors) { FloorFrames = new List <int> [labyrinthData.FloorAndCeilings.Count + 1]; FloorFrames[0] = new List <int> { 0 }; for (byte i = 1; i <= labyrinthData.FloorAndCeilings.Count; i++) { _floors[index] = i; FloorFrames[i] = new List <int> { index }; index++; } } if (ceilings) { CeilingFrames = new List <int> [labyrinthData.FloorAndCeilings.Count + 1]; CeilingFrames[0] = new List <int> { 0 }; for (byte i = 1; i <= labyrinthData.FloorAndCeilings.Count; i++) { _ceilings[index] = i; CeilingFrames[i] = new List <int> { index }; index++; } } if (walls) { WallFrames = new List <int> [labyrinthData.Walls.Count + 1]; WallFrames[0] = new List <int> { 0 }; for (byte i = 1; i <= labyrinthData.Walls.Count; i++) { _contents[index] = (byte)(i + 100); WallFrames[i] = new List <int> { index }; index++; } } if (contents) { ContentsFrames = new List <int> [labyrinthData.ObjectGroups.Count + 1]; ContentsFrames[0] = new List <int> { 0 }; for (byte i = 1; i <= labyrinthData.ObjectGroups.Count; i++) { _contents[index] = i; ContentsFrames[i] = new List <int> { index }; index++; } } // Add animation frames if (floors) { for (byte i = 1; i <= labyrinthData.FloorAndCeilings.Count; i++) { int frameCount = _tilemap.DayFloors.GetFrameCountForLogicalId(i); for (int j = 1; j < frameCount; j++) { _floors[index] = i; FloorFrames[i].Add(index); frames[index++] = j; } } } if (ceilings) { for (byte i = 1; i <= labyrinthData.FloorAndCeilings.Count; i++) { int frameCount = _tilemap.DayFloors.GetFrameCountForLogicalId(i); for (int j = 1; j < frameCount; j++) { _ceilings[index] = i; CeilingFrames[i].Add(index); frames[index++] = j; } } } if (walls) { for (byte i = 1; i <= labyrinthData.Walls.Count; i++) { int frameCount = _tilemap.DayWalls.GetFrameCountForLogicalId(i); for (int j = 1; j < frameCount; j++) { _contents[index] = (byte)(i + 100); WallFrames[i].Add(index); frames[index++] = j; } } } _tilemap.TileCount = totalTiles; for (int i = 0; i < totalTiles; i++) { SetTile(i, i, frames[i]); } for (int i = 0; i < totalTiles; i++) { AddSprites(labyrinthData, i, request); } }
protected override void Subscribed() { if (_labyrinthData != null) { Raise(new SetClearColourEvent(_backgroundRed, _backgroundGreen, _backgroundBlue, 1.0f)); return; } var assets = Resolve <IAssetManager>(); var state = Resolve <IGameState>(); var factory = Resolve <ICoreFactory>(); _labyrinthData = assets.LoadLabyrinthData(_mapData.LabDataId); if (_labyrinthData == null) { return; } _logicalMap = new LogicalMap3D(_mapData, _labyrinthData, state.TemporaryMapChanges, state.PermanentMapChanges); var properties = new TilemapRequest { Id = MapId, Width = (uint)_logicalMap.Width, Scale = _labyrinthData.TileSize, Origin = _labyrinthData.TileSize.Y / 2 * Vector3.UnitY, HorizontalSpacing = _labyrinthData.TileSize * Vector3.UnitX, VerticalSpacing = _labyrinthData.TileSize * Vector3.UnitZ, AmbientLightLevel = _labyrinthData.Lighting, FogColor = _labyrinthData.FogColor, ObjectYScaling = _labyrinthData.ObjectYScaling, Pipeline = DungeonTilemapPipeline.Normal }; _selection = AttachChild(new Selection3D()); AttachChild(new MapRenderable3D(_logicalMap, _labyrinthData, properties)); AttachChild(new ScriptManager()); AttachChild(new Collider3D(_logicalMap)); if (!_labyrinthData.BackgroundId.IsNone) { var background = assets.LoadTexture(_labyrinthData.BackgroundId); _skybox = factory.CreateSkybox(background); } var palette = assets.LoadPalette(_logicalMap.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(); // Raise(new LogEvent(LogEvent.Level.Info, $"WallHeight: {_labyrinthData.WallHeight} MaxObj: {maxObjectHeightRaw} EffWallWidth: {_labyrinthData.EffectiveWallWidth}")); foreach (var npc in _logicalMap.Npcs) { if (npc.SpriteOrGroup.IsNone) { continue; } if (npc.SpriteOrGroup.Type != AssetType.ObjectGroup) { Warn($"[3DMap] Tried to load npc with object group of incorrect type: {npc.SpriteOrGroup}"); continue; } if (npc.SpriteOrGroup.Id >= _labyrinthData.ObjectGroups.Count) { Warn($"[3DMap] Tried to load object group {npc.SpriteOrGroup.Id}, but the max group id is {_labyrinthData.ObjectGroups.Count-1}."); continue; } var objectData = _labyrinthData.ObjectGroups[npc.SpriteOrGroup.Id]; // TODO: Verify SpriteOrGroup is an ObjectGroup // TODO: Build proper NPC objects with AI, sound effects etc foreach (var subObject in objectData.SubObjects) { AttachChild(MapObject.Build(npc.Waypoints[0].X, npc.Waypoints[0].Y, _labyrinthData, subObject, properties)); } } for (int y = 0; y < _logicalMap.Height; y++) { for (int x = 0; x < _logicalMap.Width; x++) { var group = _logicalMap.GetObject(x, y); if (group == null) { continue; } foreach (var subObject in group.SubObjects) { AttachChild(MapObject.Build(x, y, _labyrinthData, subObject, properties)); } } } Raise(new SetClearColourEvent(_backgroundRed, _backgroundGreen, _backgroundBlue, 1.0f)); }