Пример #1
0
        private string DebugTileString(Point position)
        {
            if (position.X < 0 || position.Y < 0 || position.X >= Map.Width || position.Y >= Map.Height)
            {
                return("(nothing)");
            }

            string str = "";

            foreach (Tile.MapLayer layer in Tile.CachedAllMapLayers)
            {
                TileMetadata metadata = Map.GetMetadata(layer, position.X, position.Y);
                str += layer + " - " +
                       "\"" + Map[layer, position.X, position.Y].Name(metadata, Map.Info.Environment) + "\" " +
                       "(id '" + Map[layer, position.X, position.Y].ID + "') " +
                       " metadata: ";

                if (metadata == null || metadata.Count == 0)
                {
                    str += "(none)";
                }
                else
                {
                    foreach (KeyValuePair <string, string> pair in metadata)
                    {
                        str += "\n    " + pair.Key + ": " + pair.Value;
                    }
                }

                str += "\n";
            }

            return(str);
        }
Пример #2
0
 public override void Draw(Engine.Game game, Point mapPos, Map map, TileMetadata metadata, Map.Environment environment, Color?color = null)
 {
     game.Batch.Texture(
         new Vector2(mapPos.X * 16, mapPos.Y * 16),
         Template.TextureForDirection(game, Direction.Down),
         color.HasValue ? color.Value : Color.White);
 }
        public void MoveSelection(Keys key)
        {
            Coords       curCoords       = Tiles[SelectedTileIndex].DrawCoords;
            TileMetadata destinationTile = null;

            if (key == Keys.NumPad2)
            {
                destinationTile = Tiles
                                  .Where(t => t.DrawCoords != null && t.DrawCoords.X == curCoords.X && t.DrawCoords.Y > curCoords.Y)
                                  .OrderBy(t => t.DrawCoords.Y).FirstOrDefault();
            }
            if (key == Keys.NumPad4)
            {
                destinationTile = Tiles
                                  .Where(t => t.DrawCoords != null && t.DrawCoords.Y == curCoords.Y && t.DrawCoords.X < curCoords.X)
                                  .OrderByDescending(t => t.DrawCoords.X).FirstOrDefault();
            }
            if (key == Keys.NumPad6)
            {
                destinationTile = Tiles
                                  .Where(t => t.DrawCoords != null && t.DrawCoords.Y == curCoords.Y && t.DrawCoords.X > curCoords.X)
                                  .OrderBy(t => t.DrawCoords.X).FirstOrDefault();
            }
            if (key == Keys.NumPad8)
            {
                destinationTile = Tiles
                                  .Where(t => t.DrawCoords != null && t.DrawCoords.X == curCoords.X && t.DrawCoords.Y < curCoords.Y)
                                  .OrderByDescending(t => t.DrawCoords.Y).FirstOrDefault();
            }
            if (destinationTile != null)
            {
                SelectedTileIndex = Tiles.FindIndex(t => t == destinationTile);
            }
        }
        private static TileMetadata GenerateTile(string path)
        {
            var fn    = Path.GetFileNameWithoutExtension(path);
            var match = Pattern.Match(fn ?? "");

            if (!match.Success)
            {
                Debug.LogError("Failed to match tile data: " + fn);
                return(null);
            }

            var level = int.Parse(match.Groups[1].Value);
            var x     = int.Parse(match.Groups[2].Value);
            var y     = int.Parse(match.Groups[3].Value);

            var meshfile = Path.GetFileName(path);
            // todo: support for multiple textures per mesh
            var texturefile = $"L{level}_{x}_{y}_0.jpg";
            var bundlefile  = $"tile_{level}_{x}_{y}.bundle";

            var data = new TileMetadata
            {
                Level       = level,
                X           = x,
                Y           = y,
                MeshFile    = meshfile,
                TextureFile = texturefile,
                BundleFile  = bundlefile
            };

            return(data);
        }
Пример #5
0
        private void ParseTileList()
        {
            string file = SidebarWindow.sett.path + @"\Cache\Tiles.list";

            if (Directory.Exists(SidebarWindow.sett.path + @"\Cache") && File.Exists(file))
            {
                FileInfo f = new FileInfo(SidebarWindow.sett.path + @"\Cache\Tiles.list");
                if (Math.Abs(DateTime.Now.Day - f.LastAccessTime.Day) > 3)
                {
                    f.Delete();
                    ParseTileList();
                    return;
                }

                TileListManifest manifest;

                using (StreamReader reader = new StreamReader(file))
                {
                    XmlSerializer deserializer = new XmlSerializer(typeof(TileListManifest));
                    manifest = (TileListManifest)deserializer.Deserialize(reader);
                }

                for (int i = 0; i < manifest.Tiles.Length; i++)
                {
                    TileMetadata metadata = manifest.Tiles[i];
                    LibraryItem  item     = new LibraryItem()
                    {
                        Id          = metadata.Id,
                        Header      = metadata.Name,
                        Developer   = metadata.Developer,
                        Icon        = manifest.Provider.IconBaseUrl + metadata.Icon,
                        Link        = manifest.Provider.PackageBaseUrl + metadata.DownloadUrl,
                        Description = metadata.Description,
                        Version     = metadata.Version,
                    };
                    item.MouseLeftButtonDown += new MouseButtonEventHandler(item_MouseLeftButtonDown);
                    item.MouseDoubleClick    += new MouseButtonEventHandler(item_MouseDoubleClick);

                    DownTilesPanel.Children.Add(item);
                }

                DownTilesCaption.Text = string.Format(
                    (string)Application.Current.TryFindResource("DownloadableTiles"),
                    DownTilesPanel.Children.Count);
                ItemsCount.Text = string.Format(
                    (string)Application.Current.TryFindResource("ElementsCount"),
                    DownTilesPanel.Children.Count);
            }
        }
        public string CurrentTileForegroundColor()
        {
            string val = "y";

            try
            {
                TileMetadata tileInfo = Tiles[SelectedTileIndex];
                val = tileInfo.ForegroundColor;
            }
            catch (Exception ex)
            {
                Log($"(Error) Failed to retrieve selected tile foreground color [{ex}]");
            }
            return(val);
        }
Пример #7
0
        private void FinalizeEdit()
        {
            TileMetadata newAttribs = new TileMetadata();

            foreach (TileAttributeEditor editor in _editors)
            {
                if (!editor.IsDefaultValue)
                {
                    newAttribs[editor.Name] = editor.ValueAsString;
                }
                editor.Dispose();
            }

            BaseState.Map.SetMetadata(Layer, SelectedTile.X, SelectedTile.Y, newAttribs);

            _editors     = null;
            SelectedTile = new Point(-1, -1);

            if (BaseState.Buttons.ContainsKey("exit-edit-button"))
            {
                BaseState.Buttons.Remove("exit-edit-button");
            }
        }
Пример #8
0
 public static void GetTilesetTileDimensions(int sheetNum, out int x, out int y)
 {
     if (tileData[sheetNum] == null)
     {
         tileData[sheetNum] = new TileMetadata();
         tileData[sheetNum].Load(Paths.CachedGFXPath + "Tile\\Tiles" + sheetNum + ".tile");
     }
     x = Graphics.TextureManager.tileData[sheetNum].Size.Width / Graphics.TextureManager.TILE_SIZE;
     y = Graphics.TextureManager.tileData[sheetNum].Size.Height / Graphics.TextureManager.TILE_SIZE;
 }
Пример #9
0
        public static Texture GetTile(int sheetNum, Maps.Loc2D tileLoc)
        {
            try
            {
                if (tileData[sheetNum] == null)
                {
                    tileData[sheetNum] = new TileMetadata();
                    tileData[sheetNum].Load(Paths.CachedGFXPath + "Tile\\Tiles" + sheetNum + ".tile");
                }

                int tileNum = (tileData[sheetNum].Size.Width / TILE_SIZE) * tileLoc.Y + tileLoc.X;
                Texture cacheSheet = tileCache.Get(sheetNum + "-" + tileLoc.X + "-" + tileLoc.Y);
                if (cacheSheet != null) return cacheSheet;

                if (sheetNum > -1 && sheetNum < TOTAL_TILE_SHEETS && tileNum > -1 && tileNum < tileData[sheetNum].TotalTiles)
                {
                    Texture sheet = new Texture();

                    byte[] tileBytes = new byte[tileData[sheetNum].TileSizes[tileNum]];
                    using (FileStream stream = new FileStream(Paths.CachedGFXPath + "Tile\\Tiles" + sheetNum + ".tile", FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        // Seek to the location of the tile
                        stream.Seek(tileData[sheetNum].GetTilePosition(tileNum), SeekOrigin.Begin);
                        stream.Read(tileBytes, 0, tileBytes.Length);
                    }
                    using (MemoryStream tileStream = new MemoryStream(tileBytes))
                    {
                        sheet.LoadPixelsFromBytes(tileStream);
                        sheet.LoadTextureFromPixels32();
                    }

                    tileCache.Add(sheetNum + "-" + tileLoc.X + "-" + tileLoc.Y, sheet);
                    return sheet;
                }
            }
            catch (Exception ex)
            {
                Logs.Logger.LogError(new Exception("Error retrieving tile " + tileLoc.X + ", " + tileLoc.Y + " from Tileset #" + sheetNum + "\n", ex));
            }

            tileCache.Add(sheetNum + "-" + tileLoc.X + "-" + tileLoc.Y, ErrorTexture);
            return ErrorTexture;
        }
Пример #10
0
        public override void Draw(SpriteBatch batch, Vector2 screenSize)
        {
            batch.SamplerState = SamplerState.PointWrap;

            if (SelectedTile != new Point(-1, -1))
            {
                batch.Rectangle(new Rectangle(0, 0, screenSize.ToPoint().X, screenSize.ToPoint().Y), Color.Black * 0.6f);

                string  tileName = BaseState.Map[Layer, SelectedTile.X, SelectedTile.Y].Name(BaseState.Map.GetMetadata(Layer, SelectedTile.X, SelectedTile.Y), BaseState.Map.Info.Environment);
                string  str      = "\"" + tileName + "\" (" + SelectedTile.X + ", " + SelectedTile.Y + ")";
                Vector2 measure  = Game.DefaultFonts.Bold.Measure(15, str);
                batch.Text(FontStyle.Bold, 15, str, new Vector2(screenSize.X / 2 - measure.X / 2, screenSize.Y / 2 - 300 / 2), Color.White);
            }

            if (!BaseState.IsPointObscured(Input.MousePosition) && SelectedTile == new Point(-1, -1))
            {
                if (BaseState.Map[Layer, HoveredTile.X, HoveredTile.Y].ID == "")
                {
                    return;
                }

                batch.Transform = BaseState.Camera.Transform;

                bool         canCurrentTileHaveMetadata = BaseState.Map[Layer, HoveredTile.X, HoveredTile.Y].HasEditableAttributes;
                TileMetadata attribs = BaseState.Map.GetMetadata(Layer, HoveredTile.X, HoveredTile.Y);
                batch.Outline(new Rectangle(HoveredTile.X * 16, HoveredTile.Y * 16, 16, 16),
                              canCurrentTileHaveMetadata ? Color.White * 0.6f : Color.DarkRed * 0.6f, 1, false);

                batch.Reset();

                string tileName = BaseState.Map[Layer, HoveredTile.X, HoveredTile.Y].Name(BaseState.Map.GetMetadata(Layer, HoveredTile.X, HoveredTile.Y), BaseState.Map.Info.Environment);
                string str      = "";
                if (canCurrentTileHaveMetadata)
                {
                    if (attribs == null)
                    {
                        str = "Edit \"" + tileName + "\" (" + HoveredTile.X + ", " + HoveredTile.Y + ") [0.00 KB, no attributes set]";
                    }
                    else
                    {
                        int size = 0;
                        foreach (KeyValuePair <string, string> pair in attribs)
                        {
                            size += pair.Key.Length * 2;
                            size += pair.Value.Length * 2;
                        }

                        str = "Edit \"" + tileName + "\" (" + HoveredTile.X + ", " + HoveredTile.Y + ") [" + (size / (double)1024).ToString("0.00") + " KB @ slot " + BaseState.Map.GetMetadataSlot(Layer, HoveredTile.X, HoveredTile.Y) + "]";
                    }
                }
                else
                {
                    str = "No attributes exist for \"" + tileName + "\"";
                }

                Vector2 pos = new Vector2(HoveredTile.X * 16, HoveredTile.Y * 16) * BaseState.Camera.Zoom + BaseState.Camera.Translation -
                              new Vector2(0, 12 * BaseState.Camera.Zoom);

                if (pos.X < 5 * BaseState.Camera.Zoom)
                {
                    pos.X = 5 * BaseState.Camera.Zoom;
                }

                if (pos.Y < 5 * BaseState.Camera.Zoom)
                {
                    pos.Y  = 5 * BaseState.Camera.Zoom;
                    pos.X += 3 * BaseState.Camera.Zoom;
                }

                batch.Text(
                    SpriteBatch.FontStyle.MonoBold,
                    (uint)(8 * BaseState.Camera.Zoom),
                    str,
                    pos,
                    canCurrentTileHaveMetadata ? Color.White * 0.6f : Color.DarkRed * 0.6f);
            }
        }
Пример #11
0
        public override void Update(double deltaTime, double totalTime, long count)
        {
            BaseState.Buttons["layer-terrain"].Active    = Layer == Tile.MapLayer.Terrain;
            BaseState.Buttons["layer-decoration"].Active = Layer == Tile.MapLayer.Decoration;
            BaseState.Buttons["layer-npc"].Active        = Layer == Tile.MapLayer.NPC;
            BaseState.Buttons["layer-control"].Active    = Layer == Tile.MapLayer.Control;

            BaseState.Buttons["layer-terrain"].Disabled    = SelectedTile != new Point(-1, -1);
            BaseState.Buttons["layer-decoration"].Disabled = SelectedTile != new Point(-1, -1);
            BaseState.Buttons["layer-npc"].Disabled        = SelectedTile != new Point(-1, -1);
            BaseState.Buttons["layer-control"].Disabled    = SelectedTile != new Point(-1, -1);

            if (Game.Input.KeyPressed(Keys.T) && SelectedTile == new Point(-1, -1))
            {
                MapEditorTileEditState state = new MapEditorTileEditState();
                state.Layer            = Layer;
                BaseState.CurrentState = state;

                return;
            }

            if (Game.Input.MousePressed(MouseButton.Left) && !BaseState.IsPointObscured(Input.MousePosition) && SelectedTile == new Point(-1, -1))
            {
                bool canCurrentTileHaveMetadata = BaseState.Map[Layer, HoveredTile.X, HoveredTile.Y].HasEditableAttributes;

                if (canCurrentTileHaveMetadata)
                {
                    SelectedTile = HoveredTile;
                    TileMetadata attribs = BaseState.Map.GetMetadata(Layer, SelectedTile.X, SelectedTile.Y);

                    int currentY = Game.GraphicsDevice.Viewport.Bounds.Height / 2 - 300 / 2 + 30;
                    _editors = BaseState.Map[Layer, SelectedTile.X, SelectedTile.Y].AttributeEditors(BaseState, ref currentY);

                    if (attribs != null)
                    {
                        foreach (TileAttributeEditor editor in _editors)
                        {
                            if (attribs.IsKeySet(editor.Name))
                            {
                                editor.ValueFromExistingTile(attribs[editor.Name]);
                            }
                        }
                    }

                    BaseState.Buttons.Add("exit-edit-button", new Button()
                    {
                        Text     = "Finish editing",
                        Font     = Game.DefaultFonts.Bold,
                        Position = new TweenedVector2(Game, Vector2.Zero),
                        Clicked  = (btn) => { FinalizeEdit(); }
                    });
                }
            }

            if (BaseState.Buttons.ContainsKey("exit-edit-button"))
            {
                BaseState.Buttons["exit-edit-button"].Position.
                TweenTo(new Vector2(
                            Game.GraphicsDevice.Viewport.Bounds.Width / 2 - BaseState.Buttons["exit-edit-button"].Rectangle.Width / 2,
                            Game.GraphicsDevice.Viewport.Bounds.Height / 2 + 300 / 2 - 32), TweenEaseType.Linear, 0);
            }

            Vector2 offset = new Vector2(
                Game.GraphicsDevice.Viewport.Bounds.Width - _lastBounds.Width,
                Game.GraphicsDevice.Viewport.Bounds.Height - _lastBounds.Height) / 2;

            foreach (KeyValuePair <string, Button> pair in BaseState.Buttons)
            {
                if (pair.Key.StartsWith("editor-"))
                {
                    pair.Value.Position.TweenTo(pair.Value.Position + offset, TweenEaseType.Linear, 0);
                }
            }

            foreach (KeyValuePair <string, SelectionMenu> pair in BaseState.SelectionMenus)
            {
                if (pair.Key.StartsWith("editor-"))
                {
                    pair.Value.Rectangle.TweenTo(new Rectangle(
                                                     pair.Value.Rectangle.Value.X + (int)offset.X,
                                                     pair.Value.Rectangle.Value.Y + (int)offset.Y,
                                                     0, 0), TweenEaseType.Linear, 0);
                }
            }

            foreach (KeyValuePair <string, TextField> pair in BaseState.TextFields)
            {
                if (pair.Key.StartsWith("editor-"))
                {
                    pair.Value.Position.TweenTo(pair.Value.Position + offset, TweenEaseType.Linear, 0);
                }
            }

            foreach (KeyValuePair <string, ScrollableTextField> pair in BaseState.ScrollableTextFields)
            {
                if (pair.Key.StartsWith("editor-"))
                {
                    pair.Value.Area.TweenTo(new Rectangle(
                                                pair.Value.Area.Value.X + (int)offset.X,
                                                pair.Value.Area.Value.Y + (int)offset.Y,
                                                pair.Value.Area.Value.Width,
                                                pair.Value.Area.Value.Height), TweenEaseType.Linear, 0);
                }
            }

            foreach (KeyValuePair <string, ChoiceField> pair in BaseState.ChoiceFields)
            {
                if (pair.Key.StartsWith("editor-"))
                {
                    pair.Value.Position.TweenTo(pair.Value.Position + offset, TweenEaseType.Linear, 0);
                }
            }

            _lastBounds = Game.GraphicsDevice.Viewport.Bounds;
        }
Пример #12
0
        public override void Draw(SpriteBatch batch, Vector2 screenSize)
        {
            batch.UseSmartRound = false;
            batch.Transform     = Camera.Transform;
            batch.SamplerState  = SamplerState.PointWrap;

            Vector2 scissorPos = Vector2.Transform(Vector2.Zero, Camera.Transform);

            batch.Scissor = new Rectangle((int)scissorPos.X, (int)scissorPos.Y, (int)(Map.Width * 16 * Camera.Zoom.Value), (int)(Map.Height * 16 * Camera.Zoom.Value));

            foreach (Tile.MapLayer layer in Tile.CachedAllMapLayers)
            {
                Rectangle area = new Rectangle(
                    (int)-(Camera.Translation.X / Camera.Zoom.Value),
                    (int)-(Camera.Translation.Y / Camera.Zoom.Value),
                    (int)(screenSize.X / Math.Floor(Camera.Zoom.Value)),
                    (int)(screenSize.Y / Math.Floor(Camera.Zoom.Value)));

                if (layer == Tile.MapLayer.Control)
                {
                    bool shouldDraw = false;

                    if (CurrentState.GetType() == typeof(MapEditorTileEditState) && (CurrentState as MapEditorTileEditState).Layer == Tile.MapLayer.Control)
                    {
                        shouldDraw = true;
                    }
                    if (CurrentState.GetType() == typeof(MapEditorEditAttributesState) && (CurrentState as MapEditorEditAttributesState).Layer == Tile.MapLayer.Control)
                    {
                        shouldDraw = true;
                    }

                    if (!shouldDraw)
                    {
                        break;
                    }
                }

                if (layer == Tile.MapLayer.Control)
                {
                    batch.Rectangle(area, Color.Black * 0.4f);
                }

                Map.Draw(layer, Game, area);
            }

            batch.Scissor = null;

            batch.Outline(new Rectangle(0, 0, Map.Width * 16, Map.Height * 16),
                          Color.White, 1, false);

            //batch.Texture(new Vector2(64, 64), Assets.Get<Texture2D>("textures/buildings/mine_soviet.png"), Color.White);

            batch.Reset();

            if (_dataOperation == DataOperation.None)
            {
                CurrentState.Draw(batch, screenSize);

                string str =
                    "Map Editor\n" +
                    "Name: \"" + Map.Info.Name + "\"\n" +
                    "Size: " + Map.Width + "x" + Map.Height + "\n" +
                    "[PLACEHOLDER PLACEHOLDER PLACEHOLDER]";

                Vector2 measure = Game.DefaultFonts.Bold.Measure(15, str);
                batch.Rectangle(new Rectangle(10, (int)_topTextY, (int)(measure.X + 20), (int)(measure.Y + 20)),
                                Color.Black * (MathHelper.Clamp(_topTextFade, 0, 1) * 0.85f));

                str = str.Replace("[PLACEHOLDER PLACEHOLDER PLACEHOLDER]", CurrentHelpText)
                      .Replace("Map Editor\n", "");

                int size = Map.Width * Map.Height * 4;

                int x, y;
                foreach (Tile.MapLayer layer in Tile.CachedAllMapLayers)
                {
                    for (x = 0; x < Map.Width; x++)
                    {
                        for (y = 0; y < Map.Height; y++)
                        {
                            TileMetadata meta = Map.GetMetadata(layer, x, y);

                            if (meta != null && meta.HasValuesSet)
                            {
                                foreach (KeyValuePair <string, string> pair in meta)
                                {
                                    size += (pair.Key.Length + pair.Value.Length) * 2;
                                }
                            }
                        }
                    }
                }

                batch.Text(SpriteBatch.FontStyle.Bold, 15, "AoD Map Editor (" + (size / (double)1024).ToString("0.00") + " KB)", new Vector2(20, (int)_topTextY + 10),
                           Color.White * MathHelper.Clamp(_topTextFade, 0, 1));
                batch.Text(SpriteBatch.FontStyle.Bold, 15, str, new Vector2(20, (int)_topTextY + 10 + (15 * 1.25f)),
                           Color.White * (MathHelper.Clamp(_topTextFade, 0, 1) * 0.8f));

                foreach (Button button in Buttons.Values)
                {
                    button.Draw(Game);
                }

                foreach (SelectionMenu menu in SelectionMenus.Values)
                {
                    menu.Draw(Game);
                }

                foreach (TextField field in TextFields.Values)
                {
                    field.Draw(Game);
                }

                foreach (ScrollableTextField field in ScrollableTextFields.Values)
                {
                    field.Draw(Game);
                }

                foreach (ChoiceField field in ChoiceFields.Values)
                {
                    field.Draw(Game);
                }
            }

            batch.Rectangle(new Rectangle(0, 0, (int)screenSize.X, (int)screenSize.Y), Color.Black * _fade);

            if (_dataOperation != DataOperation.None)
            {
                string text = "Saving map...";
                if (_dataOperation == DataOperation.Loading)
                {
                    text = "Loading map...";
                }

                Vector2 measure = Game.DefaultFonts.Bold.Measure(32, text);

                float alpha = 0.6f;
                alpha = MathHelper.Clamp(alpha + (float)Math.Sin(Game.Time * 10f) * 0.05f, 0, 1);

                batch.Rectangle(new Rectangle(0, 0, (int)screenSize.X, (int)screenSize.Y), Color.Black * alpha);
                batch.Text(FontStyle.Bold, 32, text, screenSize / 2 - measure / 2, Color.White);
            }

            batch.UseSmartRound = true;
        }
Пример #13
0
        public override void Update(double deltaTime, double totalTime, long count)
        {
            /* TODO if(Game.Input.KeyPressed(Keys.E))
             * {
             *      _lastSelection = Menu.Selected;
             *      Menu.Selected = 0;
             * }
             *
             * if(Game.Input.KeyReleased(Keys.E))
             * {
             *      Menu.Selected = _lastSelection;
             *      _lastSelection = -1;
             * } */

            if (Game.Input.KeyPressed(Keys.T) && !Menu.IsHovered)
            {
                MapEditorEditAttributesState state = new MapEditorEditAttributesState();
                state.Layer            = Layer;
                BaseState.CurrentState = state;

                return;
            }

            Menu.Disabled = !Menu.IsHovered && (_eraseMode || Game.Input.Key(Keys.E));

            BaseState.Buttons["tool-paintone"].Active  = _tool == EditTool.PaintOne;
            BaseState.Buttons["tool-rectangle"].Active = _tool == EditTool.PaintRectangle;

            BaseState.Buttons["eraser"].Active = _eraseMode || Game.Input.Key(Keys.E);

            BaseState.Buttons["layer-terrain"].Active    = Layer == Tile.MapLayer.Terrain;
            BaseState.Buttons["layer-decoration"].Active = Layer == Tile.MapLayer.Decoration;
            BaseState.Buttons["layer-npc"].Active        = Layer == Tile.MapLayer.NPC;
            BaseState.Buttons["layer-control"].Active    = Layer == Tile.MapLayer.Control;

            if (BaseState.Buttons["tool-paintone"].Position.IsComplete)
            {
                float alpha = 1.0f;
                if (Menu.IsHovered)
                {
                    alpha = 0.0f;
                }

                BaseState.Buttons["tool-paintone"].Alpha  = MathHelper.Lerp(BaseState.Buttons["tool-paintone"].Alpha, alpha, (float)deltaTime * 25f);
                BaseState.Buttons["tool-rectangle"].Alpha = MathHelper.Lerp(BaseState.Buttons["tool-rectangle"].Alpha, alpha, (float)deltaTime * 25f);
                BaseState.Buttons["eraser"].Alpha         = MathHelper.Lerp(BaseState.Buttons["eraser"].Alpha, alpha, (float)deltaTime * 25f);

                BaseState.Buttons["layer-terrain"].Alpha    = MathHelper.Lerp(BaseState.Buttons["layer-terrain"].Alpha, alpha, (float)deltaTime * 25f);
                BaseState.Buttons["layer-decoration"].Alpha = MathHelper.Lerp(BaseState.Buttons["layer-decoration"].Alpha, alpha, (float)deltaTime * 25f);
                BaseState.Buttons["layer-npc"].Alpha        = MathHelper.Lerp(BaseState.Buttons["layer-npc"].Alpha, alpha, (float)deltaTime * 25f);
                BaseState.Buttons["layer-control"].Alpha    = MathHelper.Lerp(BaseState.Buttons["layer-control"].Alpha, alpha, (float)deltaTime * 25f);
            }

            if (!BaseState.IsPointObscured(Input.MousePosition))
            {
                if (Input.MousePressed(MouseButton.Middle) && !Input.Mouse(MouseButton.Left))
                {
                    _tool = _tool == EditTool.PaintOne ? EditTool.PaintRectangle : EditTool.PaintOne;
                }

                if (Input.KeyPressed(Keys.R) && !_eraseMode && !Game.Input.Key(Keys.E))
                {
                    string       flip = Input.Key(Keys.LeftShift) ? "flip-v" : "flip-h";
                    Tile         tile = BaseState.Map[Menu.SelectedTile.Layer, SelectedTile.X, SelectedTile.Y];
                    TileMetadata meta = BaseState.Map.GetMetadata(Menu.SelectedTile.Layer, SelectedTile.X, SelectedTile.Y);

                    int currentY = 0;
                    // TODO: make it easier to call this function without removing menus
                    TileAttributeEditor[] editors = tile.AttributeEditors(BaseState, ref currentY);

                    if (editors != null)
                    {
                        foreach (TileAttributeEditor editor in editors)
                        {
                            if (editor.Name == flip)
                            {
                                bool enable = !(meta != null && meta.IsKeySet(flip) && meta[flip] == "True");

                                if (enable)
                                {
                                    if (meta == null)
                                    {
                                        meta = new TileMetadata();
                                    }
                                    meta[flip] = "True";
                                    BaseState.Map.SetMetadata(Menu.SelectedTile.Layer, SelectedTile.X, SelectedTile.Y, meta);
                                }
                                else
                                {
                                    meta[flip] = "";
                                }
                            }

                            editor.Dispose();
                        }
                    }
                }

                switch (_tool)
                {
                case EditTool.PaintOne:
                    if (Input.Mouse(MouseButton.Left))
                    {
                        BaseState.Map[_eraseMode || Game.Input.Key(Keys.E) ? Layer : Menu.SelectedTile.Layer, SelectedTile.X, SelectedTile.Y] =
                            _eraseMode || Game.Input.Key(Keys.E) ? Tile.Find("", Layer) : Menu.SelectedTile;
                    }
                    break;

                case EditTool.PaintRectangle:
                    if (Input.MousePressed(MouseButton.Left))
                    {
                        _startingTile = SelectedTile;
                    }
                    if (Input.MouseReleased(MouseButton.Left))
                    {
                        for (int x = _rectangleToolRect.X; x <= _rectangleToolRect.X + _rectangleToolRect.Width; x++)
                        {
                            for (int y = _rectangleToolRect.Y; y <= _rectangleToolRect.Y + _rectangleToolRect.Height; y++)
                            {
                                BaseState.Map[_eraseMode || Game.Input.Key(Keys.E) ? Layer : Menu.SelectedTile.Layer, x, y] =
                                    _eraseMode || Game.Input.Key(Keys.E) ? Tile.Find("", Layer) : Menu.SelectedTile;
                            }
                        }

                        _startingTile = new Point(-1, -1);
                    }

                    break;
                }
            }

            Menu.MaxHeight = Game.GraphicsDevice.Viewport.Bounds.Height / 2;
            Menu.Update(Game);
        }
Пример #14
0
 public MapTreeNode(MapTreeNode parent, TileMetadata data) : base(parent, data.Level, data.X, data.Y)
 {
     Data = data;
 }
Пример #15
0
        /// <summary>
        /// Generates raster tiles using the Pegasus API and stores them in the data ocean.
        /// The source is either a DXF file or a GeoTIFF file.
        /// </summary>
        /// <param name="fileName">The path and file name of the source file</param>
        /// <param name="createExecutionMessage">The details of tile generation for Pegasus</param>
        /// <param name="customHeaders"></param>
        /// <returns>Metadata for the generated tiles including the zoom range</returns>
        private async Task <TileMetadata> GenerateTiles(string fileName, CreateExecutionMessage createExecutionMessage, IHeaderDictionary customHeaders, Action <IHeaderDictionary> setJobIdAction)
        {
            Log.LogDebug($"Pegasus execution: {JsonConvert.SerializeObject(createExecutionMessage)}");

            TileMetadata metadata = null;

            //Delete any old tiles. To avoid 2 traversals just try the delete anyway without checking for existence.
            await DeleteTiles(fileName, customHeaders);

            //In DataOcean this is actually a multifile not a folder
            string tileFolderFullName = new DataOceanFileUtil(fileName).GeneratedTilesFolder;
            //Get the parent folder id
            var parts          = tileFolderFullName.Split(DataOceanUtil.PathSeparator);
            var tileFolderName = parts[parts.Length - 1];
            var parentPath     = tileFolderFullName.Substring(0, tileFolderFullName.Length - tileFolderName.Length - 1);
            var parentId       = await dataOceanClient.GetFolderId(parentPath, customHeaders);

            //Set common parameters
            createExecutionMessage.Execution.Parameters.ParentId  = parentId;
            createExecutionMessage.Execution.Parameters.Name      = tileFolderName;
            createExecutionMessage.Execution.Parameters.TileOrder = TILE_ORDER;
            createExecutionMessage.Execution.Parameters.MultiFile = "true";
            createExecutionMessage.Execution.Parameters.Public    = "false";

            const string           baseRoute = "/api/executions";
            var                    payload   = JsonConvert.SerializeObject(createExecutionMessage);
            PegasusExecutionResult executionResult;

            using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(payload)))
            {
                executionResult = await gracefulClient.ExecuteRequest <PegasusExecutionResult>($"{pegasusBaseUrl}{baseRoute}", ms, customHeaders, HttpMethod.Post);
            }

            if (executionResult == null)
            {
                throw new ServiceException(HttpStatusCode.InternalServerError,
                                           new ContractExecutionResult(ContractExecutionStatesEnum.InternalProcessingError, $"Failed to create execution for {fileName}"));
            }

            setJobIdAction?.Invoke(new HeaderDictionary {
                { PEGASUS_LOG_JOBID_KEY, executionResult.Execution.Id.ToString() }
            });

            //2. Start the execution
            Log.LogDebug($"Starting execution for {fileName}");
            var executionRoute      = $"{baseRoute}/{executionResult.Execution.Id}";
            var startExecutionRoute = $"{executionRoute}/start";
            var startResult         = await gracefulClient.ExecuteRequest <PegasusExecutionAttemptResult>($"{pegasusBaseUrl}{startExecutionRoute}", null, customHeaders, HttpMethod.Post);

            if (startResult == null)
            {
                throw new ServiceException(HttpStatusCode.InternalServerError,
                                           new ContractExecutionResult(ContractExecutionStatesEnum.InternalProcessingError, $"Failed to start execution for {fileName}"));
            }

            //3. Monitor status of execution until done
            Log.LogDebug($"Monitoring execution status for {fileName}");

            var endJob  = DateTime.Now + TimeSpan.FromMinutes(executionTimeout);
            var done    = false;
            var success = true;

            while (!done && DateTime.Now <= endJob)
            {
                if (executionWaitInterval > 0)
                {
                    await Task.Delay(executionWaitInterval);
                }

                var policyResult = await Policy
                                   .Handle <Exception>()
                                   .WaitAndRetryAsync(
                    3,
                    attempt => TimeSpan.FromMilliseconds(1000),
                    (exception, calculatedWaitDuration) =>
                {
                    Log.LogError(exception, $"PollyAsync: Failed attempt to query Pegasus. Jobid {executionResult.Execution.Id.ToString()}");
                })
                                   .ExecuteAndCaptureAsync(async() =>
                {
                    Log.LogDebug($"Executing monitoring request for {fileName} and jobid {executionResult.Execution.Id.ToString()}");
                    executionResult = await gracefulClient.ExecuteRequest <PegasusExecutionResult>($"{pegasusBaseUrl}{executionRoute}", null, customHeaders, HttpMethod.Get);
                    var status      = executionResult.Execution.ExecutionStatus;
                    success         = string.Compare(status, ExecutionStatus.FINISHED, StringComparison.OrdinalIgnoreCase) == 0 ||
                                      string.Compare(status, ExecutionStatus.SUCCEEDED, StringComparison.OrdinalIgnoreCase) == 0;

                    if (string.Compare(status, ExecutionStatus.FAILED, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        //Try to retrieve why it failed
                        var jobEventsStream = await gracefulClient.ExecuteRequestAsStreamContent($"{pegasusBaseUrl}{executionRoute}/events", HttpMethod.Get, customHeaders);

                        if (jobEventsStream != null)
                        {
                            var jobEvents = await jobEventsStream.ReadAsStringAsync();
                            Log.LogError($"Pegasus job {executionResult.Execution.Id} failed to execute with the events: {jobEvents}");
                            setJobIdAction?.Invoke(new HeaderDictionary {
                                { PEGASUS_LOG_EVENTS_KEY, jobEvents }
                            });
                        }
                        else
                        {
                            Log.LogDebug($"Unable to resolve jobEventsStream for execution id {executionResult.Execution.Id}");
                        }
                    }

                    done = success || string.Compare(status, ExecutionStatus.FAILED, StringComparison.OrdinalIgnoreCase) == 0;

                    setJobIdAction?.Invoke(new HeaderDictionary {
                        { PEGASUS_LOG_RESULT_KEY, status }
                    });

                    Log.LogDebug($"Execution status {status} for {fileName} and jobid {executionResult.Execution.Id.ToString()}");
                });

                if (policyResult.FinalException != null)
                {
                    Log.LogCritical(policyResult.FinalException,
                                    $"TileGeneration PollyAsync: {GetType().FullName} failed with exception for jobid {executionResult.Execution.Id.ToString()}: ");
                    throw policyResult.FinalException;
                }
            }

            if (!done)
            {
                Log.LogInformation($"{nameof(GenerateTiles)} timed out: {fileName}");
            }
            else if (!success)
            {
                Log.LogInformation($"{nameof(GenerateTiles)} failed: {fileName}");
                throw new ServiceException(HttpStatusCode.InternalServerError,
                                           new ContractExecutionResult(ContractExecutionStatesEnum.InternalProcessingError, $"Failed to generate tiles for {fileName}"));
            }

            if (success)
            {
                /*
                 * Can't delete as not mutable
                 *
                 * //4. Delete the execution
                 * Log.LogDebug($"Deleting execution for {dxfFileName}");
                 * await gracefulClient.ExecuteRequest($"{pegasusBaseUrl}{executionRoute}", null, customHeaders, HttpMethod.Delete, null, 0, false);
                 */

                //5. Get the zoom range from the tile metadata file
                var metadataFileName = new DataOceanFileUtil(fileName).TilesMetadataFileName;
                Log.LogDebug($"Getting tiles metadata for {metadataFileName}");
                var stream = await dataOceanClient.GetFile(metadataFileName, customHeaders);

                using (var sr = new StreamReader(stream))
                    using (var jtr = new JsonTextReader(sr))
                    {
                        metadata = new JsonSerializer().Deserialize <TileMetadata>(jtr);
                    }
            }

            Log.LogInformation($"{nameof(GenerateTiles)}: returning {(metadata == null ? "null" : JsonConvert.SerializeObject(metadata))}");

            return(metadata);
        }