diff --git a/inf3.csproj b/inf3.csproj index 78e6313..3438185 100644 --- a/inf3.csproj +++ b/inf3.csproj @@ -9,27 +9,28 @@ Exe inf3 inf3 + v4.0 - true + True full - false + False bin\Debug DEBUG; prompt 4 x86 - false + False /unsafe none - true + True bin\Release prompt 4 x86 - false + False @@ -74,6 +75,7 @@ + diff --git a/src/Backend.cs b/src/Backend.cs index cee9537..d871297 100644 --- a/src/Backend.cs +++ b/src/Backend.cs @@ -1,6 +1,6 @@ using System.Net.Sockets; using System.Collections.Generic; -using WorldOfPeacecraft; +using System.Threading; namespace WorldOfPeacecraft { @@ -16,6 +16,7 @@ namespace WorldOfPeacecraft private Map Map; private Buffer SenderBuffer; private IGui Gui; + private int SelfId; public Backend (IGui gui) { @@ -30,15 +31,21 @@ namespace WorldOfPeacecraft Rec = new Receiver (Client, receiverBuffer); Send = new Sender (Client, SenderBuffer); SenderBuffer.AddLine ("get:map"); + SenderBuffer.AddLine ("get:me"); SenderBuffer.AddLine ("get:ents"); } - public IEnumerable GetDragons () + public void SetSelfId (int id) + { + this.SelfId = id; + } + + public IEnumerable GetDragons () { return Dragons.Values; } - public IEnumerable GetPlayers () + public IEnumerable GetPlayers () { return Players.Values; } @@ -139,6 +146,26 @@ namespace WorldOfPeacecraft SenderBuffer.AddLine("ask:mv:rgt"); } + public void MoveTo (int x, int y) + { + if (Map.GetTiles () [x, y].IsWalkable ()) { + Thread thread = new Thread (() => WalkTo (x, y)); + thread.IsBackground = true; + thread.Start (); + } + } + + private void WalkTo (int x, int y) + { + LinkedList path = Pathfinder.FindPath (Players [SelfId].Coord, new Coordinate (x, y), Map); + Pathwalker walker = new Pathwalker (); + walker.SetCoords (path); + while (walker.HasMoreSteps()) { + SenderBuffer.AddLine("ask:" + walker.NextStep()); + Thread.Sleep(250); + } + } + public void RefreshGui() { Gui.PerformRefresh(); @@ -157,3 +184,4 @@ namespace WorldOfPeacecraft } } } + diff --git a/src/Entity.cs b/src/Entity.cs index b613655..355eaea 100644 --- a/src/Entity.cs +++ b/src/Entity.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace WorldOfPeacecraft { - public abstract class Entity : IPositionable + public abstract class Entity : IEntity { public int Id; public Coordinate Coord; diff --git a/src/Gui/Gui.cs b/src/Gui/Gui.cs index d96ea2a..a9e5a93 100644 --- a/src/Gui/Gui.cs +++ b/src/Gui/Gui.cs @@ -74,7 +74,6 @@ namespace WorldOfPeacecraft ChatPanel.Location = new Point (MapPanel.Width, 0); ChatPanel.Size = new Size (ChatWidth, MapPanel.Height); this.ResumeLayout(); - this.PerformLayout(); ChatPanel.UpdateData (); this.Refresh(); })); diff --git a/src/Gui/IBackend.cs b/src/Gui/IBackend.cs index 2cda33a..4270ce1 100644 --- a/src/Gui/IBackend.cs +++ b/src/Gui/IBackend.cs @@ -6,9 +6,9 @@ namespace WorldOfPeacecraft { ITile[,] GetMap(); - IEnumerable GetPlayers(); + IEnumerable GetPlayers(); - IEnumerable GetDragons(); + IEnumerable GetDragons(); IEnumerable GetChatMessages(); @@ -17,10 +17,10 @@ namespace WorldOfPeacecraft void SendCommand (string command); void moveUp(); - void moveDown(); void moveLeft(); void moveRight(); + void MoveTo(int x, int y); void StartThreads(); diff --git a/src/Gui/IEntity.cs b/src/Gui/IEntity.cs new file mode 100644 index 0000000..44e59c2 --- /dev/null +++ b/src/Gui/IEntity.cs @@ -0,0 +1,7 @@ +namespace WorldOfPeacecraft +{ + public interface IEntity : IPositionable + { + int GetId(); + } +} diff --git a/src/Gui/MapPanel.cs b/src/Gui/MapPanel.cs index 5f7cd92..82a6965 100644 --- a/src/Gui/MapPanel.cs +++ b/src/Gui/MapPanel.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; @@ -10,11 +11,31 @@ namespace WorldOfPeacecraft private const int EntitySize = 10; private IBackend Backend; + private string ImagesFolder = "textures/"; + private Image BowAndArrow; + private Image Dragon1; + private Image Dragon2; + private Image Dragon3; + private Image Forest; + private Image Knight; + private Image Walkable; + private Image Water; + private Dictionary dragonImageMappings = new Dictionary(); + private Random random = new Random (); + public MapPanel (IBackend backend) { + SetStyle (ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); Backend = backend; - this.Paint += DoPaint; - this.PreviewKeyDown += board_KeyPress; + this.PreviewKeyDown += board_KeyPress; + BowAndArrow = Image.FromFile (ImagesFolder + "bow-and-arrow.png", false); + Dragon1 = Image.FromFile (ImagesFolder + "dragon1.png"); + Dragon2 = Image.FromFile (ImagesFolder + "dragon2.png"); + Dragon3 = Image.FromFile (ImagesFolder + "dragon3.png"); + Forest = Image.FromFile (ImagesFolder + "forest.png"); + Knight = Image.FromFile (ImagesFolder + "knight.png"); + Walkable = Image.FromFile (ImagesFolder + "walkable.jpg"); + Water = Image.FromFile (ImagesFolder + "water.jpg"); } protected override void OnLayout (LayoutEventArgs levent) @@ -50,18 +71,18 @@ namespace WorldOfPeacecraft protected override void OnMouseClick (MouseEventArgs e) { base.OnMouseClick (e); - //TODO: Things. + int targetX = e.X / TileSize; + int targetY = e.Y / TileSize; + Backend.MoveTo (targetX, targetY); } - public void DoPaint (object source, PaintEventArgs args) + protected override void OnPaint (PaintEventArgs e) { - BufferedGraphics buffer = BufferedGraphicsManager.Current.Allocate (this.CreateGraphics (), this.DisplayRectangle); - Graphics g = buffer.Graphics; + Graphics g = e.Graphics; lock (Backend) { PaintMap (g); PaintEntities (g); } - buffer.Render(); } public void PaintMap (Graphics g) @@ -70,7 +91,9 @@ namespace WorldOfPeacecraft if (map != null) { for (int y = 0; y < map.GetLength(1); y++) { for (int x = 0; x < map.GetLength(0); x++) { - PaintTile (g, map [x, y], x, y); + int posx = x * TileSize; + int posy = y * TileSize; + PaintTile (g, map [x, y], posx, posy); } } } @@ -81,44 +104,71 @@ namespace WorldOfPeacecraft public void PaintTile (Graphics g, ITile tile, int x, int y) { - int posx = x * TileSize; - int posy = y * TileSize; - Color color; - if (tile.IsHuntable ()) { - color = Color.DarkGreen; - } // Stupid parenthesis - else if (tile.IsForest ()) { - color = Color.Green; - } else if (tile.IsWater ()) { - color = Color.Blue; - } else if (tile.IsWalkable ()) { - color = Color.Yellow; - } else if (tile.IsWall ()) { - color = Color.DarkGray; - } else { - color = Color.Black; + Image image = null; + if (tile.IsWater ()) { + image = Water; + } + else { + image = Walkable; + } + if (image != null) { + PaintImage (g, x, y, image); + } else { + g.FillRectangle(new SolidBrush(Color.Red), x, y, TileSize, TileSize); + } + if (tile.IsWall ()) { + g.FillEllipse(new SolidBrush(Color.Gray), x + 3, y + 3, TileSize - 6 , TileSize - 6); + } + if (tile.IsForest ()) { + PaintImage (g, x, y, Forest); + } + if (tile.IsHuntable ()) { + PaintImage (g, x, y, BowAndArrow); } - g.FillRectangle(new SolidBrush(color), posx, posy, TileSize, TileSize); } - + public void PaintEntities (Graphics g) { - IEnumerable dragons = Backend.GetDragons (); - IEnumerable players = Backend.GetPlayers (); - foreach (IPositionable dragon in dragons) { - PaintEntity (g, dragon, Color.Red); + IEnumerable dragons = Backend.GetDragons (); + IEnumerable players = Backend.GetPlayers (); + foreach (IEntity dragon in dragons) { + int id = dragon.GetId(); + if (!dragonImageMappings.ContainsKey(id)) + { + dragonImageMappings[id] = random.Next (3); + } + Image image; + switch (dragonImageMappings[id]) + { + case 0: + image = Dragon1; + break; + case 1: + image = Dragon2; + break; + case 2: + image = Dragon3; + break; + default: + throw new Exception("dragonImageMapping '" + dragonImageMappings[id] + "' doesn't exist"); + } + PaintImage(g, dragon.GetX() * TileSize, dragon.GetY() * TileSize, image); } - foreach (IPositionable player in players) { - PaintEntity (g, player, Color.LightGreen); + foreach (IEntity player in players) { + PaintImage(g, player.GetX() * TileSize, player.GetY () * TileSize, Knight); } } + public void PaintImage (Graphics g, int posx, int posy, Image image) + { + int x = posx + (TileSize - image.Width) / 2; + int y = posy + (TileSize - image.Height) / 2; + g.DrawImage(image, x, y, image.Width, image.Height); + } + public void PaintEntity (Graphics g, IPositionable entity, Color color) { - int x = entity.GetX () * TileSize + TileSize / 2 - EntitySize / 2; - int y = entity.GetY () * TileSize + TileSize / 2 - EntitySize / 2; - g.FillRectangle (new SolidBrush (color), x, y, EntitySize, EntitySize); - g.DrawRectangle (new Pen( new SolidBrush (Color.Black)), x, y, EntitySize, EntitySize); + } } } diff --git a/src/Parser.cs b/src/Parser.cs index 5bf5f21..7d3bed9 100644 --- a/src/Parser.cs +++ b/src/Parser.cs @@ -119,7 +119,7 @@ namespace WorldOfPeacecraft ProcessChallenge (block); break; case MessPlayer: - ProcessPlayer (block); + ProcessPlayerSelf (block); break; case MessYourid: ProcessYourid (block); @@ -287,6 +287,15 @@ namespace WorldOfPeacecraft Challenge c = new Challenge(id, type, accepted); } + private void ProcessPlayerSelf (Block playerBlock) + { + Player self = MapPlayer (playerBlock); + lock (Backend) { + Backend.SetSelfId(self.GetId()); + Backend.SetPlayer(self); + } + Backend.RefreshGui (); + } private void ProcessPlayer (Block playerBlock) { diff --git a/src/Pathfinder.cs b/src/Pathfinder.cs index bd0d14a..a2e48d3 100644 --- a/src/Pathfinder.cs +++ b/src/Pathfinder.cs @@ -8,45 +8,45 @@ namespace WorldOfPeacecraft [StructLayout(LayoutKind.Sequential)] private struct PathNode { - [MarshalAs(UnmanagedType.U4)] - public uint X; - [MarshalAs(UnmanagedType.U4)] - public uint Y; + [MarshalAs(UnmanagedType.I4)] + public int X; + [MarshalAs(UnmanagedType.I4)] + public int Y; } public static unsafe LinkedList FindPath (Coordinate posFrom, Coordinate posTo, Map map) { PathNode nFrom; - nFrom.X = (uint) posFrom.X; - nFrom.Y = (uint) posFrom.Y; + nFrom.X = posFrom.X; + nFrom.Y = posFrom.Y; PathNode nTo; - nTo.X = (uint) posTo.X; - nTo.Y = (uint) posTo.Y; + nTo.X = posTo.X; + nTo.Y = posTo.Y; Tile[,] tiles = map.GetTiles(); - uint mapWidth = (uint) tiles.GetLength (0); - uint mapHeight = (uint) tiles.GetLength (1); - bool* boolMap = stackalloc bool[(int)(mapWidth * mapHeight)]; + int mapWidth = tiles.GetLength (0); + int mapHeight = tiles.GetLength (1); + bool* boolMap = stackalloc bool[mapWidth * mapHeight]; for (int y = 0; y < mapHeight; y++) { for (int x = 0; x < mapWidth; x++) { boolMap [x + y * mapWidth] = tiles [x, y].IsWalkable (); } } - PathNode* result = stackalloc PathNode[(int) (mapHeight * mapWidth)]; - uint noSteps = findPath (nFrom, nTo, mapWidth, mapHeight, boolMap, result); + PathNode* result = stackalloc PathNode[mapHeight * mapWidth]; + int noSteps = findPath (nFrom, nTo, mapWidth, mapHeight, boolMap, result); LinkedList mappedResult = new LinkedList(); for (int i = 0; i < noSteps; i++) { - mappedResult.AddLast(new Coordinate((int) result[i].X, (int) result[i].Y)); + mappedResult.AddLast(new Coordinate(result[i].X, result[i].Y)); } return mappedResult; } [DllImport("pathfinding")] - [return: MarshalAs(UnmanagedType.U4)] - private static extern unsafe uint findPath( + [return: MarshalAs(UnmanagedType.I4)] + private static extern unsafe int findPath( PathNode posFrom, PathNode posTo, - [MarshalAs(UnmanagedType.U4)] uint mapWidth, - [MarshalAs(UnmanagedType.U4)] uint mapHeight, + [MarshalAs(UnmanagedType.I4)] int mapWidth, + [MarshalAs(UnmanagedType.I4)] int mapHeight, bool* map, PathNode* result); } diff --git a/src/Pathwalker.cs b/src/Pathwalker.cs index da694ca..501cfe5 100644 --- a/src/Pathwalker.cs +++ b/src/Pathwalker.cs @@ -13,6 +13,11 @@ namespace WorldOfPeacecraft Coords = null; } + public bool HasMoreSteps() + { + return Coords != null && Coords.Count >= 2; + } + public string NextStep () { if (Coords == null) { @@ -30,13 +35,13 @@ namespace WorldOfPeacecraft } string command; if (src.X > dst.X) { - command = "mv:dwn"; - } else if (src.X < dst.X) { - command = "mv:up"; - } else if (src.Y > dst.Y) { command = "mv:lft"; - } else if (src.Y < dst.Y) { + } else if (src.X < dst.X) { command = "mv:rgt"; + } else if (src.Y > dst.Y) { + command = "mv:up"; + } else if (src.Y < dst.Y) { + command = "mv:dwn"; } else { command = NextStep (); }