コード例 #1
0
    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);
    }
コード例 #2
0
ファイル: IsometricLayout.cs プロジェクト: lucorp/ualbion
        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);
        }
コード例 #3
0
ファイル: IsometricLayout.cs プロジェクト: lucorp/ualbion
        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;
        }
コード例 #4
0
ファイル: IsometricLayout.cs プロジェクト: lucorp/ualbion
        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})");
                }
            }
        }
コード例 #5
0
ファイル: MapRenderable3D.cs プロジェクト: csinkers/ualbion
    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));
            }
        };
    }
コード例 #6
0
ファイル: IsometricLayout.cs プロジェクト: lucorp/ualbion
        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);
            }
        }
コード例 #7
0
        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));
        }