/// <summary> /// Adds door to place. /// </summary> /// <param name="direction"></param> /// <param name="doorType"></param> private void AddDoor(int direction, DungeonBlockType doorType) { var door = _room.GetPuzzleDoor(direction); // We'll create new door and replace if we want locked door instead of normal one here if (door != null && doorType == DungeonBlockType.Door) { this.Doors[direction] = door; return; } // Create new door var floorData = this.Puzzle.FloorData; var doorBlock = this.Puzzle.Dungeon.Data.Style.Get(doorType, direction); var doorName = string.Format("{0}_door_{1}{2}_{3}", _name, this.X, this.Y, direction); door = new Door(doorBlock.PropId, 0, this.X, this.Y, doorBlock.Rotation, doorType, doorName); door.Info.Color1 = floorData.Color1; door.Info.Color2 = floorData.Color2; door.Info.Color3 = this.LockColor; if (doorType == DungeonBlockType.BossDoor) { if (this.Puzzle.Dungeon.Data.BlockBoss) door.BlockBoss = true; door.Behavior += this.Puzzle.Dungeon.BossDoorBehavior; } door.Behavior += this.Puzzle.PuzzleEvent; this.Doors[direction] = door; this.Puzzle.Props[doorName] = door; _room.SetPuzzleDoor(door, direction); _room.SetDoorType(direction, (int)doorType); }
/// <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 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.PuzzleDoors[Direction.Down] = _bossDoor; // making sure another open dummy door won't be added here region.AddProp(_bossDoor); } else { _bossDoor = endRoomTrait.PuzzleDoors[Direction.Down]; } // 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) => { 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]); } } } } }
public void SetPuzzleDoor(Door door, int direction) { this.PuzzleDoors[direction] = door; var opposite_direction = Direction.GetOppositeDirection(direction); var room = this.Neighbor[direction]; if (room != null) room.PuzzleDoors[opposite_direction] = door; }