コード例 #1
0
ファイル: Dungeon.cs プロジェクト: trueever/aura
        /// <summary>
        /// Spawns treasure chests in treasure room.
        /// </summary>
        private void SpawnTreasureChests()
        {
            var region = this.Regions.Last();
            var rnd    = RandomProvider.Get();

            for (int i = 0; i < _treasureChests.Count; ++i)
            {
                var pos = new Generation.Position(this.Generator.Floors.Last().MazeGenerator.EndPos);

                pos.X *= Dungeon.TileSize;
                pos.Y *= Dungeon.TileSize;

                pos.X += Dungeon.TileSize / 2;
                pos.Y += (int)(Dungeon.TileSize * 2.5f);

                var placement = _treasurePlacementProvider.GetPosition();

                pos.X += placement[0];
                pos.Y += placement[1];
                var rotation = MabiMath.DegreeToRadian(placement[2]);

                var prop = _treasureChests[i];
                prop.RegionId       = region.Id;
                prop.Info.X         = pos.X;
                prop.Info.Y         = pos.Y;
                prop.Info.Direction = rotation;
                region.AddProp(prop);
            }
        }
コード例 #2
0
        public void InCone()
        {
            var centerPos = new Position(0, 0);
            var topPos    = new Position(0, 500);
            var bottomPos = new Position(0, -500);
            var leftPos   = new Position(-500, 0);
            var rightPos  = new Position(500, 0);

            var up    = MabiMath.DegreeToRadian(90);
            var down  = MabiMath.DegreeToRadian(270);
            var left  = MabiMath.DegreeToRadian(180);
            var right = MabiMath.DegreeToRadian(0);

            Assert.Equal(true, topPos.InCone(centerPos, up, 600, MabiMath.DegreeToRadian(10)));
            Assert.Equal(true, bottomPos.InCone(centerPos, down, 600, MabiMath.DegreeToRadian(10)));
            Assert.Equal(true, leftPos.InCone(centerPos, left, 600, MabiMath.DegreeToRadian(10)));
            Assert.Equal(true, rightPos.InCone(centerPos, right, 600, MabiMath.DegreeToRadian(10)));

            Assert.Equal(true, topPos.InCone(centerPos, up, 500, MabiMath.DegreeToRadian(10)));
            Assert.Equal(false, topPos.InCone(centerPos, up, 500, MabiMath.DegreeToRadian(180)));
            Assert.Equal(true, topPos.InCone(centerPos, up, 600, MabiMath.DegreeToRadian(180)));
            Assert.Equal(true, topPos.InCone(centerPos, up, 1000, MabiMath.DegreeToRadian(180)));

            Assert.Equal(true, topPos.InCone(centerPos, up, 1000, MabiMath.DegreeToRadian(190)));
            Assert.Equal(true, topPos.InCone(centerPos, up, 1000, MabiMath.DegreeToRadian(-190)));
            Assert.Equal(true, topPos.InCone(centerPos, up, 1000, MabiMath.DegreeToRadian(9999)));
            Assert.Equal(true, topPos.InCone(centerPos, up, 1000, MabiMath.DegreeToRadian(-9999)));

            Assert.Equal(false, topPos.InCone(centerPos, MabiMath.DegreeToRadian(45), 2000, MabiMath.DegreeToRadian(45)));
            Assert.Equal(true, topPos.InCone(centerPos, MabiMath.DegreeToRadian(68), 2000, MabiMath.DegreeToRadian(45)));
        }
コード例 #3
0
        public void GetRelative()
        {
            var pos1 = new Position(100, 100);
            var pos2 = new Position(100, 200);

            Assert.Equal(new Position(100, 250), pos1.GetRelative(pos2, 50));
            Assert.Equal(new Position(100, 150), pos1.GetRelative(pos2, -50));
            Assert.Equal(new Position(100, -50), pos1.GetRelative(pos2, -250));

            var pos3 = new Position(50, 100);

            Assert.Equal(new Position(0, 100), pos1.GetRelative(pos3, 50));
            Assert.Equal(new Position(100, 100), pos1.GetRelative(pos3, -50));
            Assert.Equal(new Position(300, 100), pos1.GetRelative(pos3, -250));

            var up    = MabiMath.DegreeToRadian(90);
            var down  = MabiMath.DegreeToRadian(270);
            var left  = MabiMath.DegreeToRadian(180);
            var right = MabiMath.DegreeToRadian(0);

            Assert.Equal(new Position(100, 200), pos1.GetRelative(up, 100));
            Assert.Equal(new Position(100, 0), pos1.GetRelative(down, 100));
            Assert.Equal(new Position(0, 100), pos1.GetRelative(left, 100));
            Assert.Equal(new Position(200, 100), pos1.GetRelative(right, 100));
        }
コード例 #4
0
    public override void OnPuzzleCreate(Puzzle puzzle)
    {
        var lockedPlace = puzzle.GetPlace("LockedPlace");
        var key         = puzzle.LockPlace(lockedPlace, "Boss");

        var chest = new Chest(puzzle, "KeyChest");

        lockedPlace.AddProp(chest, Placement.Center);

        chest.Info.Direction = MabiMath.DegreeToRadian(90);
        chest.Add(Item.Create(GoddessPass));
        chest.Add(key);
    }
コード例 #5
0
        public void GetDirection()
        {
            var up    = MabiMath.DegreeToRadian(90);
            var down  = MabiMath.DegreeToRadian(270);
            var left  = MabiMath.DegreeToRadian(180);
            var right = MabiMath.DegreeToRadian(0);

            var pos = new Position(100, 100);

            Assert.Equal(up, pos.GetDirection(new Position(100, 200)));
            Assert.Equal(down, pos.GetDirection(new Position(100, 0)));
            Assert.Equal(left, pos.GetDirection(new Position(0, 100)));
            Assert.Equal(right, pos.GetDirection(new Position(200, 100)));
        }
コード例 #6
0
        /// <summary>
        /// Adds prop to puzzle in place.
        /// </summary>
        /// <param name="place"></param>
        /// <param name="prop"></param>
        /// <param name="positionType"></param>
        public void AddProp(PuzzlePlace place, DungeonProp prop, Placement positionType)
        {
            if (this.Region == null)
            {
                throw new PuzzleException("AddProp outside of OnPuzzleCreate.");
            }

            var pos = place.GetPosition(positionType);

            prop.RegionId = this.Region.Id;
            prop.Info.X   = pos[0];
            prop.Info.Y   = pos[1];
            prop.UpdateShapes();
            prop.Info.Direction = MabiMath.DegreeToRadian(pos[2]);
            prop.Behavior      += PuzzleEvent;

            this.Region.AddProp(prop);
            this.Props[prop.Name] = prop;
        }
コード例 #7
0
        /// <summary>
        /// Creates new door prop.
        /// </summary>
        /// <param name="propId"></param>
        /// <param name="regionId"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="direction">Direction the door faces in, in degree.</param>
        /// <param name="doorType"></param>
        /// <param name="name"></param>
        /// <param name="state"></param>
        public Door(int propId, int regionId, int x, int y, int direction, DungeonBlockType doorType, string name, string state = "open")
            : base(propId, regionId, x, y, direction, 1, 0, state, "", "")
        {
            this.Name      = name;
            this.DoorType  = doorType;
            this.BlockBoss = false;
            this.Behavior  = this.DefaultBehavior;
            _isSwitchDoor  = false;
            _closedFrom    = new Position(x / Dungeon.TileSize, y / Dungeon.TileSize);

            // Set direction and adjust Y for boss doors
            if (doorType == DungeonBlockType.BossDoor)
            {
                this.Info.Direction = MabiMath.DirectionToRadian(0, 1);
                this.Info.Y        += Dungeon.TileSize + Dungeon.TileSize / 2;
            }
            else
            {
                this.Info.Direction = MabiMath.DegreeToRadian(direction);
            }
        }
コード例 #8
0
ファイル: Dungeon.cs プロジェクト: trueever/aura
        /// <summary>
        /// Initiates floor, creating puzzles and props.
        /// </summary>
        /// <param name="iRegion"></param>
        public void InitFloorRegion(int iRegion)
        {
            this.CreatePuzzles(iRegion);

            var region    = this.Regions[iRegion];
            var floor     = this.Generator.Floors[iRegion - 1];
            var gen       = floor.MazeGenerator;
            var floorData = this.Data.Floors[iRegion - 1];

            var iPrevRegion = iRegion - 1;
            var iNextRegion = iRegion + 1;

            var startTile                  = gen.StartPos;
            var startPos                   = new Generation.Position(startTile.X * Dungeon.TileSize + Dungeon.TileSize / 2, startTile.Y * Dungeon.TileSize + Dungeon.TileSize / 2);
            var startRoomTrait             = floor.GetRoom(startTile);
            var startRoomIncomingDirection = startRoomTrait.GetIncomingDirection();

            var endTile          = gen.EndPos;
            var endPos           = new Generation.Position(endTile.X * Dungeon.TileSize + Dungeon.TileSize / 2, endTile.Y * Dungeon.TileSize + Dungeon.TileSize / 2);
            var endRoomTrait     = floor.GetRoom(endTile);
            var endRoomDirection = 0;

            for (int dir = 0; dir < 4; ++dir)
            {
                if (endRoomTrait.Links[dir] == LinkType.To)
                {
                    endRoomDirection = dir;
                    break;
                }
            }

            // Create upstairs prop
            var stairsBlock = this.Data.Style.Get(DungeonBlockType.StairsUp, startRoomIncomingDirection);
            var stairs      = new Prop(stairsBlock.PropId, region.Id, startPos.X, startPos.Y, MabiMath.DegreeToRadian(stairsBlock.Rotation), 1, 0, "single");

            stairs.Info.Color1 = floorData.Color1;
            stairs.Info.Color2 = floorData.Color1;
            stairs.Info.Color3 = floorData.Color3;
            region.AddProp(stairs);

            // Create portal prop leading to prev floor
            var portalBlock = this.Data.Style.Get(DungeonBlockType.PortalUp, startRoomIncomingDirection);
            var portal      = new Prop(portalBlock.PropId, region.Id, startPos.X, startPos.Y, MabiMath.DegreeToRadian(portalBlock.Rotation), 1, 0, "single", "_upstairs", Localization.Get("<mini>TO</mini> Upstairs"));

            portal.Info.Color1 = floorData.Color1;
            portal.Info.Color2 = floorData.Color1;
            portal.Info.Color3 = floorData.Color3;
            portal.Behavior    = (cr, pr) =>
            {
                // Indoor_RDungeon_EB marks the end position on the prev floor.
                var clientEvent = this.Regions[iPrevRegion].GetClientEvent("Indoor_RDungeon_EB");
                if (clientEvent == null)
                {
                    Log.Error("Event 'Indoor_RDungeon_EB' not found while trying to warp to '{0}'.", this.Regions[iPrevRegion].Name);
                    return;
                }

                // Warp to prev region
                var regionId = this.Regions[iPrevRegion].Id;
                var x        = (int)clientEvent.Data.X;
                var y        = (int)clientEvent.Data.Y;

                cr.Warp(regionId, x, y);
            };
            region.AddProp(portal);

            // Create save statue
            if (floorData.Statue)
            {
                var saveStatue = new Prop(this.Data.SaveStatuePropId, region.Id, startPos.X, startPos.Y, MabiMath.DegreeToRadian(stairsBlock.Rotation + 180), 1, 0, "single");
                saveStatue.Info.Color1 = floorData.Color1;
                saveStatue.Info.Color2 = floorData.Color1;
                saveStatue.Info.Color3 = floorData.Color3;
                saveStatue.Behavior    = (cr, pr) =>
                {
                    cr.DungeonSaveLocation = cr.GetLocation();
                    Send.Notice(cr, Localization.Get("You have memorized this location."));

                    // Scroll message
                    var msg = string.Format("You're currently on Floor {0} of {1}. ", iRegion, this.Data.EngName);
                    Send.Notice(cr, NoticeType.Top, ScrollMessageDuration, msg + this.GetPlayerListScrollMessage());
                };
                region.AddProp(saveStatue);
            }

            // Spawn boss or downstair props
            // TODO: There is one dungeon that has two boss rooms.
            if (floor.IsLastFloor)
            {
                // Create door to treasure room
                _bossExitDoor             = new Prop(this.Data.BossExitDoorId, region.Id, endPos.X, endPos.Y + Dungeon.TileSize / 2, Rotation(Direction.Up), 1, 0, "closed");
                _bossExitDoor.Info.Color1 = floorData.Color1;
                _bossExitDoor.Info.Color2 = floorData.Color1;
                _bossExitDoor.Info.Color3 = floorData.Color3;
                region.AddProp(_bossExitDoor);

                // Get or create boss door
                if (endRoomTrait.PuzzleDoors[Direction.Down] == null)
                {
                    Log.Warning("Dungeon.InitFloorRegion: No locked place in last section of '{0}'.", this.Name);

                    _bossDoor             = new Door(this.Data.BossDoorId, region.Id, endPos.X, endPos.Y - Dungeon.TileSize, Direction.Up, DungeonBlockType.BossDoor, "", "closed");
                    _bossDoor.Info.Color1 = floorData.Color1;
                    _bossDoor.Info.Color2 = floorData.Color1;
                    _bossDoor.Info.Color3 = floorData.Color3;
                    _bossDoor.Behavior    = (cr, pr) => { _bossDoor.Open(); };
                    _bossDoor.Behavior   += this.BossDoorBehavior;
                    _bossDoor.UpdateShapes();
                    endRoomTrait.SetPuzzleDoor(_bossDoor, Direction.Down);                     // making sure another open dummy door won't be added here
                    region.AddProp(_bossDoor);
                }
                else
                {
                    _bossDoor = endRoomTrait.PuzzleDoors[Direction.Down];
                    if (_bossDoor.State == "open")
                    {
                        Log.Warning("Dungeon.InitFloorRegion: Boss door was left open, closing. Dungeon: '{0}'.", this.Name);
                        _bossDoor.Close(endRoomTrait.X, endRoomTrait.Y);
                    }
                }

                // Create exit statue
                var exitStatue = new Prop(this.Data.LastStatuePropId, region.Id, endPos.X, endPos.Y + Dungeon.TileSize * 2, Rotation(Direction.Up), 1, 0, "single");
                exitStatue.Info.Color1 = floorData.Color1;
                exitStatue.Info.Color2 = floorData.Color1;
                exitStatue.Info.Color3 = floorData.Color3;
                exitStatue.Extensions.AddSilent(new ConfirmationPropExtension("GotoLobby", "_LT[code.standard.msg.dungeon_exit_notice_msg]", "_LT[code.standard.msg.dungeon_exit_notice_title]", "haskey(chest)"));
                exitStatue.Behavior = (cr, pr) =>
                {
                    ChannelServer.Instance.Events.OnPlayerClearedDungeon(cr, this);
                    cr.Warp(this.Data.Exit);
                };
                region.AddProp(exitStatue);
            }
            else
            {
                // Create downstairs prop
                var stairsDownBlock = this.Data.Style.Get(DungeonBlockType.StairsDown, endRoomDirection);
                var stairsDown      = new Prop(stairsDownBlock.PropId, region.Id, endPos.X, endPos.Y, MabiMath.DegreeToRadian(stairsDownBlock.Rotation), 1, 0, "single");
                stairsDown.Info.Color1 = floorData.Color1;
                stairsDown.Info.Color2 = floorData.Color1;
                stairsDown.Info.Color3 = floorData.Color3;
                region.AddProp(stairsDown);

                // Create portal leading to the next floor
                var portalDownBlock = this.Data.Style.Get(DungeonBlockType.PortalDown, endRoomDirection);
                var portalDown      = new Prop(portalDownBlock.PropId, region.Id, endPos.X, endPos.Y, MabiMath.DegreeToRadian(portalDownBlock.Rotation), 1, 0, "single", "_downstairs", Localization.Get("<mini>TO</mini> Downstairs"));
                portalDown.Info.Color1 = floorData.Color1;
                portalDown.Info.Color2 = floorData.Color1;
                portalDown.Info.Color3 = floorData.Color3;
                portalDown.Behavior    = (cr, pr) =>
                {
                    // Indoor_RDungeon_SB marks the start position on the next floor.
                    var clientEvent = this.Regions[iNextRegion].GetClientEvent("Indoor_RDungeon_SB");
                    if (clientEvent == null)
                    {
                        Log.Error("Event 'Indoor_RDungeon_SB' not found while trying to warp to '{0}'.", this.Regions[iNextRegion].Name);
                        return;
                    }

                    // Warp to next floor
                    var regionId = this.Regions[iNextRegion].Id;
                    var x        = (int)clientEvent.Data.X;
                    var y        = (int)clientEvent.Data.Y;

                    cr.Warp(regionId, x, y);
                };
                region.AddProp(portalDown);
            }

            // Place dummy doors
            for (int x = 0; x < floor.MazeGenerator.Width; ++x)
            {
                for (int y = 0; y < floor.MazeGenerator.Height; ++y)
                {
                    var room      = floor.MazeGenerator.GetRoom(x, y);
                    var roomTrait = floor.GetRoom(x, y);
                    var isRoom    = (roomTrait.RoomType >= RoomType.Start);

                    if (!room.Visited || !isRoom)
                    {
                        continue;
                    }

                    for (var dir = 0; dir < 4; ++dir)
                    {
                        // Skip stairs
                        if (roomTrait.RoomType == RoomType.Start && dir == startRoomIncomingDirection)
                        {
                            continue;
                        }
                        if (roomTrait.RoomType == RoomType.End && dir == endRoomDirection)
                        {
                            continue;
                        }

                        if (roomTrait.Links[dir] == LinkType.None)
                        {
                            continue;
                        }

                        if (roomTrait.PuzzleDoors[dir] == null)
                        {
                            var doorX = x * Dungeon.TileSize + Dungeon.TileSize / 2;
                            var doorY = y * Dungeon.TileSize + Dungeon.TileSize / 2;

                            var doorBlock = this.Data.Style.Get(DungeonBlockType.Door, dir);
                            var doorProp  = new Prop(doorBlock.PropId, region.Id, doorX, doorY, MabiMath.DegreeToRadian(doorBlock.Rotation), state: "open");
                            doorProp.Info.Color1 = floorData.Color1;
                            doorProp.Info.Color2 = floorData.Color2;
                            doorProp.Info.Color3 = floorData.Color3;
                            region.AddProp(doorProp);
                        }
                        else if (roomTrait.PuzzleDoors[dir].EntityId == 0)
                        {
                            // Add doors from failed puzzles
                            roomTrait.PuzzleDoors[dir].Info.Region = region.Id;
                            region.AddProp(roomTrait.PuzzleDoors[dir]);
                        }
                    }
                }
            }
        }
コード例 #9
0
        /// <summary>
        /// Generates areas, incl (client) props and events.
        /// </summary>
        private void GenerateAreas()
        {
            this.Data = new RegionInfoData();

            var areaId = 2;
            var floor  = this.Floor;

            for (int x = 0; x < floor.MazeGenerator.Width; ++x)
            {
                for (int y = 0; y < floor.MazeGenerator.Height; ++y)
                {
                    var room      = floor.MazeGenerator.GetRoom(x, y);
                    var roomTrait = floor.GetRoom(x, y);

                    if (!room.Visited)
                    {
                        continue;
                    }

                    var isStart    = (roomTrait.RoomType == RoomType.Start);
                    var isEnd      = (roomTrait.RoomType == RoomType.End);
                    var isRoom     = (roomTrait.RoomType >= RoomType.Start);
                    var isBossRoom = (floor.HasBossRoom && isEnd);
                    var eventId    = 0L;

                    if (!isBossRoom)
                    {
                        var areaData = new AreaData();
                        areaData.Id   = areaId++;
                        areaData.Name = "Tile" + areaData.Id;

                        areaData.X1 = x * Dungeon.TileSize;
                        areaData.Y1 = y * Dungeon.TileSize;
                        areaData.X2 = x * Dungeon.TileSize + Dungeon.TileSize;
                        areaData.Y2 = y * Dungeon.TileSize + Dungeon.TileSize;

                        this.Data.Areas.Add(areaData);

                        var type = (isRoom ? DungeonBlockType.Room : DungeonBlockType.Alley);

                        var propEntityId = MabiId.ClientProps | ((long)this.Id << 32) | ((long)areaData.Id << 16) | 1;
                        var block        = this.Dungeon.Data.Style.Get(type, room.Directions);
                        var tileCenter   = new Point(x * Dungeon.TileSize + Dungeon.TileSize / 2, y * Dungeon.TileSize + Dungeon.TileSize / 2);

                        var prop = new Prop(propEntityId, block.PropId, this.Id, tileCenter.X, tileCenter.Y, MabiMath.DegreeToRadian(block.Rotation), 1, 0, "", "", "");
                        this.AddProp(prop);

                        // Debug
                        //foreach (var points in prop.Shapes)
                        //{
                        //	foreach (var point in points)
                        //	{
                        //		var pole = new Prop(30, this.Id, point.X, point.Y, 0, 1, 0, "", "", "");
                        //		pole.Shapes.Clear();
                        //		this.AddProp(pole);
                        //	}
                        //}

                        // TODO: This region/data stuff is a mess... create
                        //   proper classes, put them in the regions and be
                        //   done with it.

                        if (isStart || isEnd)
                        {
                            var xp = tileCenter.X;
                            var yp = tileCenter.Y;

                            if (roomTrait.DoorType[Direction.Up] >= 3000)
                            {
                                yp += 400;
                            }
                            else if (roomTrait.DoorType[Direction.Right] >= 3000)
                            {
                                xp += 400;
                            }
                            else if (roomTrait.DoorType[Direction.Down] >= 3000)
                            {
                                yp -= 400;
                            }
                            else if (roomTrait.DoorType[Direction.Left] >= 3000)
                            {
                                xp -= 400;
                            }

                            var eventData = new EventData();
                            eventData.Id   = MabiId.AreaEvents | ((long)this.Id << 32) | ((long)areaData.Id << 16) | eventId++;
                            eventData.Name = (isStart ? "Indoor_RDungeon_SB" : "Indoor_RDungeon_EB");
                            eventData.X    = xp;
                            eventData.Y    = yp;

                            var shape = new ShapeData();
                            shape.DirX1 = 1;
                            shape.DirY2 = 1;
                            shape.LenX  = 100;
                            shape.LenY  = 100;
                            shape.PosX  = xp;
                            shape.PosY  = yp;
                            eventData.Shapes.Add(shape);

                            areaData.Events.Add(eventData.Id, eventData);
                            _clientEvents.Add(eventData.Id, new ClientEvent(eventData, this.Data.Name, areaData.Name));
                        }
                    }
                    else
                    {
                        // Big main room
                        var areaData = new AreaData();
                        areaData.Id   = areaId++;
                        areaData.Name = "Tile" + areaData.Id;

                        areaData.X1 = x * Dungeon.TileSize - Dungeon.TileSize;
                        areaData.Y1 = y * Dungeon.TileSize;
                        areaData.X2 = x * Dungeon.TileSize + Dungeon.TileSize * 2;
                        areaData.Y2 = y * Dungeon.TileSize + Dungeon.TileSize * 2;

                        this.Data.Areas.Add(areaData);

                        var block        = this.Dungeon.Data.Style.Get(DungeonBlockType.BossRoom);
                        var propEntityId = MabiId.ClientProps | ((long)this.Id << 32) | ((long)areaData.Id << 16) | 1;
                        var tileCenter   = new Point(x * Dungeon.TileSize + Dungeon.TileSize / 2, y * Dungeon.TileSize + Dungeon.TileSize);

                        var prop = new Prop(propEntityId, block.PropId, this.Id, tileCenter.X, tileCenter.Y, MabiMath.DegreeToRadian(block.Rotation), 1, 0, "", "", "");
                        this.AddProp(prop);

                        // Debug
                        //foreach (var points in prop.Shapes)
                        //{
                        //	foreach (var point in points)
                        //	{
                        //		var pole = new Prop(30, this.Id, point.X, point.Y, 0, 1, 0, "", "", "");
                        //		pole.Shapes.Clear();
                        //		this.AddProp(pole);
                        //	}
                        //}

                        // Treasure room
                        areaData      = new AreaData();
                        areaData.Id   = areaId++;
                        areaData.Name = "Tile" + areaData.Id;

                        areaData.X1 = x * Dungeon.TileSize;
                        areaData.Y1 = y * Dungeon.TileSize + Dungeon.TileSize * 2;
                        areaData.X2 = x * Dungeon.TileSize + Dungeon.TileSize;
                        areaData.Y2 = y * Dungeon.TileSize + Dungeon.TileSize * 2 + Dungeon.TileSize;

                        this.Data.Areas.Add(areaData);
                    }
                }
            }
        }
コード例 #10
0
    public override void OnCreation(Dungeon dungeon)
    {
        var region       = dungeon.Regions.Last();
        var bossLocation = dungeon.GetBossRoomCenter();

        // Gargoyles
        region.AddProp(new Prop(29001, bossLocation.RegionId, bossLocation.X, bossLocation.Y, 0));
        region.AddProp(new Prop(29002, bossLocation.RegionId, bossLocation.X, bossLocation.Y, 0));
        region.AddProp(new Prop(29003, bossLocation.RegionId, bossLocation.X, bossLocation.Y, MabiMath.DegreeToRadian(90)));
        region.AddProp(new Prop(29004, bossLocation.RegionId, bossLocation.X, bossLocation.Y, MabiMath.DegreeToRadian(90)));
        region.AddProp(new Prop(29005, bossLocation.RegionId, bossLocation.X, bossLocation.Y, 0));
        region.AddProp(new Prop(29006, bossLocation.RegionId, bossLocation.X, bossLocation.Y, 0));
    }