/// <summary> /// Constructor /// </summary> /// <param name="wallswitch">Wallswitch handle</param> /// <param name="maze">Maze handle</param> public WallSwitchControl(WallSwitch wallswitch, Maze maze) { InitializeComponent(); ActivatedIdBox.Value = wallswitch.ActivatedDecoration; DeactivatedIdBox.Value = wallswitch.DeactivatedDecoration; SquarePropertiesBox.Actor = wallswitch; SideBox.Direction = wallswitch.Side; Maze = maze; DecorationSet = maze.Decoration; WallSwitch = wallswitch; ActionScriptBox.Scripts= wallswitch.Scripts; ActionScriptBox.Dungeon = maze.Dungeon; }
/// <summary> /// Constructor /// </summary> /// <param name="maze">Parent maze handle</param> public Square(Maze maze) { Maze = maze; Type = SquareType.Wall; Monsters = new Monster[4]; InFog = true; Decorations = new int[] { -1, -1, -1, -1 }; Items = new List<Item>[] { new List<Item>(), new List<Item>(), new List<Item>(), new List<Item>() }; }
/// <summary> /// Constructor /// </summary> /// <param name="maze">Maze handle</param> /// <param name="location">View's location</param> public ViewField(Maze maze, DungeonLocation location) { Maze = maze; Blocks = new Square[16]; // Cone of vision : 15 blocks + 1 block for the Point of View // // ABCDE // FGHIJ // KLM // N^O // // ^ => Point of view switch (location.Direction) { #region North case CardinalPoint.North: { Blocks[0] = maze.GetSquare(new Point(location.Coordinate.X - 2, location.Coordinate.Y - 3)); Blocks[1] = maze.GetSquare(new Point(location.Coordinate.X - 1, location.Coordinate.Y - 3)); Blocks[2] = maze.GetSquare(new Point(location.Coordinate.X, location.Coordinate.Y - 3)); Blocks[3] = maze.GetSquare(new Point(location.Coordinate.X + 1, location.Coordinate.Y - 3)); Blocks[4] = maze.GetSquare(new Point(location.Coordinate.X + 2, location.Coordinate.Y - 3)); Blocks[5] = maze.GetSquare(new Point(location.Coordinate.X - 2, location.Coordinate.Y - 2)); Blocks[6] = maze.GetSquare(new Point(location.Coordinate.X - 1, location.Coordinate.Y - 2)); Blocks[7] = maze.GetSquare(new Point(location.Coordinate.X, location.Coordinate.Y - 2)); Blocks[8] = maze.GetSquare(new Point(location.Coordinate.X + 1, location.Coordinate.Y - 2)); Blocks[9] = maze.GetSquare(new Point(location.Coordinate.X + 2, location.Coordinate.Y - 2)); Blocks[10] = maze.GetSquare(new Point(location.Coordinate.X - 1, location.Coordinate.Y - 1)); Blocks[11] = maze.GetSquare(new Point(location.Coordinate.X, location.Coordinate.Y - 1)); Blocks[12] = maze.GetSquare(new Point(location.Coordinate.X + 1, location.Coordinate.Y - 1)); Blocks[13] = maze.GetSquare(new Point(location.Coordinate.X - 1, location.Coordinate.Y)); Blocks[15] = maze.GetSquare(new Point(location.Coordinate.X + 1, location.Coordinate.Y)); } break; #endregion #region South case CardinalPoint.South: { Blocks[0] = maze.GetSquare(new Point(location.Coordinate.X + 2, location.Coordinate.Y + 3)); Blocks[1] = maze.GetSquare(new Point(location.Coordinate.X + 1, location.Coordinate.Y + 3)); Blocks[2] = maze.GetSquare(new Point(location.Coordinate.X, location.Coordinate.Y + 3)); Blocks[3] = maze.GetSquare(new Point(location.Coordinate.X - 1, location.Coordinate.Y + 3)); Blocks[4] = maze.GetSquare(new Point(location.Coordinate.X - 2, location.Coordinate.Y + 3)); Blocks[5] = maze.GetSquare(new Point(location.Coordinate.X + 2, location.Coordinate.Y + 2)); Blocks[6] = maze.GetSquare(new Point(location.Coordinate.X + 1, location.Coordinate.Y + 2)); Blocks[7] = maze.GetSquare(new Point(location.Coordinate.X, location.Coordinate.Y + 2)); Blocks[8] = maze.GetSquare(new Point(location.Coordinate.X - 1, location.Coordinate.Y + 2)); Blocks[9] = maze.GetSquare(new Point(location.Coordinate.X - 2, location.Coordinate.Y + 2)); Blocks[10] = maze.GetSquare(new Point(location.Coordinate.X + 1, location.Coordinate.Y + 1)); Blocks[11] = maze.GetSquare(new Point(location.Coordinate.X, location.Coordinate.Y + 1)); Blocks[12] = maze.GetSquare(new Point(location.Coordinate.X - 1, location.Coordinate.Y + 1)); Blocks[13] = maze.GetSquare(new Point(location.Coordinate.X + 1, location.Coordinate.Y)); Blocks[15] = maze.GetSquare(new Point(location.Coordinate.X - 1, location.Coordinate.Y)); } break; #endregion #region East case CardinalPoint.East: { Blocks[0] = maze.GetSquare(new Point(location.Coordinate.X + 3, location.Coordinate.Y - 2)); Blocks[1] = maze.GetSquare(new Point(location.Coordinate.X + 3, location.Coordinate.Y - 1)); Blocks[2] = maze.GetSquare(new Point(location.Coordinate.X + 3, location.Coordinate.Y)); Blocks[3] = maze.GetSquare(new Point(location.Coordinate.X + 3, location.Coordinate.Y + 1)); Blocks[4] = maze.GetSquare(new Point(location.Coordinate.X + 3, location.Coordinate.Y + 2)); Blocks[5] = maze.GetSquare(new Point(location.Coordinate.X + 2, location.Coordinate.Y - 2)); Blocks[6] = maze.GetSquare(new Point(location.Coordinate.X + 2, location.Coordinate.Y - 1)); Blocks[7] = maze.GetSquare(new Point(location.Coordinate.X + 2, location.Coordinate.Y)); Blocks[8] = maze.GetSquare(new Point(location.Coordinate.X + 2, location.Coordinate.Y + 1)); Blocks[9] = maze.GetSquare(new Point(location.Coordinate.X + 2, location.Coordinate.Y + 2)); Blocks[10] = maze.GetSquare(new Point(location.Coordinate.X + 1, location.Coordinate.Y - 1)); Blocks[11] = maze.GetSquare(new Point(location.Coordinate.X + 1, location.Coordinate.Y)); Blocks[12] = maze.GetSquare(new Point(location.Coordinate.X + 1, location.Coordinate.Y + 1)); Blocks[13] = maze.GetSquare(new Point(location.Coordinate.X, location.Coordinate.Y - 1)); Blocks[15] = maze.GetSquare(new Point(location.Coordinate.X, location.Coordinate.Y + 1)); } break; #endregion #region West case CardinalPoint.West: { Blocks[0] = maze.GetSquare(new Point(location.Coordinate.X - 3, location.Coordinate.Y + 2)); Blocks[1] = maze.GetSquare(new Point(location.Coordinate.X - 3, location.Coordinate.Y + 1)); Blocks[2] = maze.GetSquare(new Point(location.Coordinate.X - 3, location.Coordinate.Y)); Blocks[3] = maze.GetSquare(new Point(location.Coordinate.X - 3, location.Coordinate.Y - 1)); Blocks[4] = maze.GetSquare(new Point(location.Coordinate.X - 3, location.Coordinate.Y - 2)); Blocks[5] = maze.GetSquare(new Point(location.Coordinate.X - 2, location.Coordinate.Y + 2)); Blocks[6] = maze.GetSquare(new Point(location.Coordinate.X - 2, location.Coordinate.Y + 1)); Blocks[7] = maze.GetSquare(new Point(location.Coordinate.X - 2, location.Coordinate.Y)); Blocks[8] = maze.GetSquare(new Point(location.Coordinate.X - 2, location.Coordinate.Y - 1)); Blocks[9] = maze.GetSquare(new Point(location.Coordinate.X - 2, location.Coordinate.Y - 2)); Blocks[10] = maze.GetSquare(new Point(location.Coordinate.X - 1, location.Coordinate.Y + 1)); Blocks[11] = maze.GetSquare(new Point(location.Coordinate.X - 1, location.Coordinate.Y)); Blocks[12] = maze.GetSquare(new Point(location.Coordinate.X - 1, location.Coordinate.Y - 1)); Blocks[13] = maze.GetSquare(new Point(location.Coordinate.X, location.Coordinate.Y + 1)); Blocks[15] = maze.GetSquare(new Point(location.Coordinate.X, location.Coordinate.Y - 1)); } break; #endregion } // Team's position Blocks[14] = maze.GetSquare(location.Coordinate); }
/* /// <summary> /// Adds a maze to the dungeon /// </summary> /// <param name="name"></param> /// <param name="node"></param> public void SetMaze(Maze maze) { if (maze == null) return; StringBuilder sb = new StringBuilder(); using (XmlWriter writer = XmlWriter.Create(sb)) maze.Save(writer); string xml = sb.ToString(); XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); // Mazes[maze.Name] = doc.DocumentElement; } */ /// <summary> /// Adss a maze to the dungeon /// </summary> /// <param name="maze">Maze to add</param> public void AddMaze(Maze maze) { if (maze == null) return; Mazes[maze.Name] = maze; }
/// <summary> /// Loads a <see cref="Dungeon"/> /// </summary> /// <param name="xml"></param> /// <returns>True on success</returns> public bool Load(XmlNode xml) { if (xml == null || xml.Name != Tag) { Trace.WriteLine("[Dungeon] Expecting \"" + XmlTag + "\" in node header, found \"" + xml.Name + "\" when loading Dungeon."); return false; } Name = xml.Attributes["name"].Value; foreach (XmlNode node in xml) { if (node.NodeType == XmlNodeType.Comment) continue; switch (node.Name.ToLower()) { case Item.Tag: { ItemTileSetName = node.Attributes["tileset"].Value; } break; case Maze.Tag: { string name = node.Attributes["name"].Value; Maze maze = new Maze(this); maze.Name = name; Mazes[name] = maze; maze.Load(node); } break; case "start": { StartLocation = new DungeonLocation(node); } break; case "note": { Note = node.InnerText; } break; } } return true; }
/// <summary> /// Does the Team can see this place /// </summary> /// <param name="maze">Maze</param> /// <param name="location">Place to see</param> /// <returns>True if can see the location</returns> /// http://tom.cs.byu.edu/~455/3DDDA.pdf /// http://www.tar.hu/gamealgorithms/ch22lev1sec1.html /// http://www.cse.yorku.ca/~amana/research/grid.pdf /// http://www.siggraph.org/education/materials/HyperGraph/scanline/outprims/drawline.htm#dda public bool CanSee(Maze maze, Point location) { Point dist = Point.Empty; // Not the same maze if (Maze != maze) return false; Rectangle rect = Rectangle.Empty; switch (Location.Direction) { case CardinalPoint.North: { if (!new Rectangle(Location.Coordinate.X - 1, Location.Coordinate.Y - 3, 3, 4).Contains(location) && location != new Point(Location.Coordinate.X - 3, Location.Coordinate.Y - 3) && location != new Point(Location.Coordinate.X - 2, Location.Coordinate.Y - 3) && location != new Point(Location.Coordinate.X - 2, Location.Coordinate.Y - 2) && location != new Point(Location.Coordinate.X + 3, Location.Coordinate.Y - 3) && location != new Point(Location.Coordinate.X + 2, Location.Coordinate.Y - 3) && location != new Point(Location.Coordinate.X + 2, Location.Coordinate.Y - 2)) return false; // Is there a wall between the Team and the location int dx = location.X - Location.Coordinate.X; int dy = location.Y - Location.Coordinate.Y; float delta = (float)dy / (float)dx; float y = 0; for (int pos = Location.Coordinate.Y; pos >= location.Y; pos--) { if (Maze.GetSquare(new Point(pos, Location.Coordinate.Y + (int)y)).Type == SquareType.Wall) return false; y += delta; } return true; } case CardinalPoint.South: { if (!new Rectangle(Location.Coordinate.X - 1, Location.Coordinate.Y, 3, 4).Contains(location) && location != new Point(Location.Coordinate.X - 3, Location.Coordinate.Y + 3) && location != new Point(Location.Coordinate.X - 2, Location.Coordinate.Y + 3) && location != new Point(Location.Coordinate.X - 2, Location.Coordinate.Y + 2) && location != new Point(Location.Coordinate.X + 3, Location.Coordinate.Y + 3) && location != new Point(Location.Coordinate.X + 2, Location.Coordinate.Y + 3) && location != new Point(Location.Coordinate.X + 2, Location.Coordinate.Y + 2)) return false; // Is there a wall between the Team and the location int dx = location.X - Location.Coordinate.X; int dy = location.Y - Location.Coordinate.Y; float delta = (float)dy / (float)dx; float y = 0; for (int pos = Location.Coordinate.Y; pos <= location.Y; pos++) { if (Maze.GetSquare(new Point(pos, Location.Coordinate.Y + (int)y)).Type == SquareType.Wall) return false; y += delta; } return true; } case CardinalPoint.West: { if (!new Rectangle(Location.Coordinate.X - 3, Location.Coordinate.Y - 1, 4, 3).Contains(location) && location != new Point(Location.Coordinate.X - 3, Location.Coordinate.Y - 3) && location != new Point(Location.Coordinate.X - 3, Location.Coordinate.Y - 2) && location != new Point(Location.Coordinate.X - 2, Location.Coordinate.Y - 2) && location != new Point(Location.Coordinate.X - 3, Location.Coordinate.Y + 3) && location != new Point(Location.Coordinate.X - 3, Location.Coordinate.Y + 2) && location != new Point(Location.Coordinate.X - 2, Location.Coordinate.Y + 2)) return false; // Is there a wall between the Team and the location int dx = location.X - Location.Coordinate.X; int dy = location.Y - Location.Coordinate.Y; float delta = (float)dy / (float)dx; float y = 0; for (int pos = Location.Coordinate.X; pos >= location.X; pos--) { if (Maze.GetSquare(new Point(pos, Location.Coordinate.Y + (int)y)).Type == SquareType.Wall) return false; y += delta; } return true; } case CardinalPoint.East: { if (!new Rectangle(Location.Coordinate.X, Location.Coordinate.Y - 1, 4, 3).Contains(location) && location != new Point(Location.Coordinate.X + 3, Location.Coordinate.Y - 3) && location != new Point(Location.Coordinate.X + 3, Location.Coordinate.Y - 2) && location != new Point(Location.Coordinate.X + 2, Location.Coordinate.Y - 2) && location != new Point(Location.Coordinate.X + 3, Location.Coordinate.Y + 3) && location != new Point(Location.Coordinate.X + 3, Location.Coordinate.Y + 2) && location != new Point(Location.Coordinate.X + 2, Location.Coordinate.Y + 2)) return false; // Is there a wall between the Team and the location int dx = location.X - Location.Coordinate.X; int dy = location.Y - Location.Coordinate.Y; float delta = (float)dy / (float)dx; float y = 0; for (int pos = Location.Coordinate.X; pos <= location.X; pos++) { if (Maze.GetSquare(new Point(pos, Location.Coordinate.Y + (int)y)).Type == SquareType.Wall) return false; y += delta; } return true; } } return false; }
/// <summary> /// Update the flying item /// </summary> /// <param name="time">Game time</param> /// <param name="maze">Maze where the flying item is</param> /// <returns>True if the blocked or false if nothing happened</rereturns> public bool Update(GameTime time, Maze maze) { // Item can't move any more if (Distance == 0) return true; LastUpdate += time.ElapsedGameTime; if (LastUpdate > Speed) { LastUpdate -= Speed; // Find the next block according to the direction Point dst = Point.Empty; switch (Location.Direction) { case CardinalPoint.North: dst = new Point(Location.Coordinate.X, Location.Coordinate.Y - 1); break; case CardinalPoint.East: dst = new Point(Location.Coordinate.X + 1, Location.Coordinate.Y); break; case CardinalPoint.South: dst = new Point(Location.Coordinate.X, Location.Coordinate.Y + 1); break; case CardinalPoint.West: dst = new Point(Location.Coordinate.X - 1, Location.Coordinate.Y); break; } // Blocked by a wall, fall before the block Square square = maze.GetSquare(dst); // Can item pass through a door ? if (square.Actor != null && square.Actor is Door) { Door door = square.Actor as Door; if (!door.CanItemsPassThrough(Item)) { Distance = 0; } } // Wall is blocking else if (square.IsBlocking) { Distance = 0; } // Blocked by an obstacle, but fall on the block if ((square.Actor != null && square.Actor.CanPassThrough) || square.MonsterCount > 0) { Location.Coordinate = dst; SquarePosition gp = Location.Position; switch (Location.Direction) { case CardinalPoint.North: if (gp == SquarePosition.NorthEast || gp == SquarePosition.SouthEast) Location.Position = SquarePosition.SouthEast; else Location.Position = SquarePosition.SouthWest; break; case CardinalPoint.South: if (gp == SquarePosition.NorthEast || gp == SquarePosition.SouthEast) Location.Position = SquarePosition.NorthEast; else Location.Position = SquarePosition.NorthWest; break; case CardinalPoint.West: if (gp == SquarePosition.NorthEast || gp == SquarePosition.NorthWest) Location.Position = SquarePosition.NorthEast; else Location.Position = SquarePosition.SouthEast; break; case CardinalPoint.East: if (gp == SquarePosition.NorthEast || gp == SquarePosition.NorthWest) Location.Position = SquarePosition.NorthWest; else Location.Position = SquarePosition.SouthWest; break; } // Get monster and hit it if (square.MonsterCount > 0) { Monster[] monsters = maze.GetSquare(Location.Coordinate).Monsters; foreach(Monster monster in monsters) if (monster != null) { Attack attack = new Attack(Caster, monster, Item); if (attack.IsAHit) Distance = 0; } } return true; } // Drop the item at good ground position if (Distance == 0) { SquarePosition gp = Location.Position; switch (Location.Direction) { case CardinalPoint.North: if (gp == SquarePosition.NorthEast || gp == SquarePosition.SouthEast) Location.Position = SquarePosition.NorthEast; else Location.Position = SquarePosition.NorthWest; break; case CardinalPoint.South: if (gp == SquarePosition.NorthEast || gp == SquarePosition.SouthEast) Location.Position = SquarePosition.SouthEast; else Location.Position = SquarePosition.SouthWest; break; case CardinalPoint.West: if (gp == SquarePosition.NorthEast || gp == SquarePosition.NorthWest) Location.Position = SquarePosition.NorthWest; else Location.Position = SquarePosition.SouthWest; break; case CardinalPoint.East: if (gp == SquarePosition.NorthEast || gp == SquarePosition.NorthWest) Location.Position = SquarePosition.NorthEast; else Location.Position = SquarePosition.SouthEast; break; } return true; } else { Distance--; Location.Coordinate = dst; } } return false; }