示例#1
0
文件: Map.cs 项目: ushalin/OpenRA
        // The standard constructor for most purposes
        public Map(string path)
        {
            Path      = path;
            Container = GlobalFileSystem.OpenPackage(path, null, int.MaxValue);

            AssertExists("map.yaml");
            AssertExists("map.bin");

            var yaml = new MiniYaml(null, MiniYaml.FromStream(Container.GetContent("map.yaml"), path));

            FieldLoader.Load(this, yaml);

            // Support for formats 1-3 dropped 2011-02-11.
            // Use release-20110207 to convert older maps to format 4
            // Use release-20110511 to convert older maps to format 5
            // Use release-20141029 to convert older maps to format 6
            if (MapFormat < 6)
            {
                throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, path));
            }

            var nd = yaml.ToDictionary();

            // Format 6 -> 7 combined the Selectable and UseAsShellmap flags into the Class enum
            if (MapFormat < 7)
            {
                MiniYaml useAsShellmap;
                if (nd.TryGetValue("UseAsShellmap", out useAsShellmap) && bool.Parse(useAsShellmap.Value))
                {
                    Visibility = MapVisibility.Shellmap;
                }
                else if (Type == "Mission" || Type == "Campaign")
                {
                    Visibility = MapVisibility.MissionSelector;
                }
            }

            SpawnPoints = Exts.Lazy(() =>
            {
                var spawns = new List <CPos>();
                foreach (var kv in ActorDefinitions.Where(d => d.Value.Value == "mpspawn"))
                {
                    var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());

                    spawns.Add(s.InitDict.Get <LocationInit>().Value(null));
                }

                return(spawns.ToArray());
            });

            RuleDefinitions          = MiniYaml.NodesOrEmpty(yaml, "Rules");
            SequenceDefinitions      = MiniYaml.NodesOrEmpty(yaml, "Sequences");
            VoxelSequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "VoxelSequences");
            WeaponDefinitions        = MiniYaml.NodesOrEmpty(yaml, "Weapons");
            VoiceDefinitions         = MiniYaml.NodesOrEmpty(yaml, "Voices");
            NotificationDefinitions  = MiniYaml.NodesOrEmpty(yaml, "Notifications");
            TranslationDefinitions   = MiniYaml.NodesOrEmpty(yaml, "Translations");
            PlayerDefinitions        = MiniYaml.NodesOrEmpty(yaml, "Players");

            ActorDefinitions  = MiniYaml.NodesOrEmpty(yaml, "Actors");
            SmudgeDefinitions = MiniYaml.NodesOrEmpty(yaml, "Smudges");

            MapTiles     = Exts.Lazy(LoadMapTiles);
            MapResources = Exts.Lazy(LoadResourceTiles);
            MapHeight    = Exts.Lazy(LoadMapHeight);

            TileShape      = Game.ModData.Manifest.TileShape;
            SubCellOffsets = Game.ModData.Manifest.SubCellOffsets;
            LastSubCell    = (SubCell)(SubCellOffsets.Length - 1);
            DefaultSubCell = (SubCell)Game.ModData.Manifest.SubCellDefaultIndex;

            if (Container.Exists("map.png"))
            {
                using (var dataStream = Container.GetContent("map.png"))
                    CustomPreview = new Bitmap(dataStream);
            }

            PostInit();

            // The Uid is calculated from the data on-disk, so
            // format changes must be flushed to disk.
            // TODO: this isn't very nice
            if (MapFormat < 7)
            {
                Save(path);
            }

            Uid = ComputeHash();
        }
示例#2
0
文件: Map.cs 项目: ushalin/OpenRA
        public void Save(string toPath)
        {
            MapFormat = 7;

            var root   = new List <MiniYamlNode>();
            var fields = new[]
            {
                "MapFormat",
                "RequiresMod",
                "Title",
                "Description",
                "Author",
                "Tileset",
                "MapSize",
                "Bounds",
                "Visibility",
                "Type",
            };

            foreach (var field in fields)
            {
                var f = this.GetType().GetField(field);
                if (f.GetValue(this) == null)
                {
                    continue;
                }
                root.Add(new MiniYamlNode(field, FieldSaver.FormatValue(this, f)));
            }

            root.Add(new MiniYamlNode("Videos", FieldSaver.SaveDifferences(Videos, new MapVideos())));

            root.Add(new MiniYamlNode("Options", FieldSaver.SaveDifferences(Options, new MapOptions())));

            root.Add(new MiniYamlNode("Players", null, PlayerDefinitions));

            root.Add(new MiniYamlNode("Actors", null, ActorDefinitions));
            root.Add(new MiniYamlNode("Smudges", null, SmudgeDefinitions));
            root.Add(new MiniYamlNode("Rules", null, RuleDefinitions));
            root.Add(new MiniYamlNode("Sequences", null, SequenceDefinitions));
            root.Add(new MiniYamlNode("VoxelSequences", null, VoxelSequenceDefinitions));
            root.Add(new MiniYamlNode("Weapons", null, WeaponDefinitions));
            root.Add(new MiniYamlNode("Voices", null, VoiceDefinitions));
            root.Add(new MiniYamlNode("Notifications", null, NotificationDefinitions));
            root.Add(new MiniYamlNode("Translations", null, TranslationDefinitions));

            var entries = new Dictionary <string, byte[]>();

            entries.Add("map.bin", SaveBinaryData());
            var s = root.WriteToString();

            entries.Add("map.yaml", Encoding.UTF8.GetBytes(s));

            // Add any custom assets
            if (Container != null)
            {
                foreach (var file in Container.AllFileNames())
                {
                    if (file == "map.bin" || file == "map.yaml")
                    {
                        continue;
                    }

                    entries.Add(file, Container.GetContent(file).ReadAllBytes());
                }
            }

            // Saving the map to a new location
            if (toPath != Path)
            {
                Path = toPath;

                // Create a new map package
                Container = GlobalFileSystem.CreatePackage(Path, int.MaxValue, entries);
            }

            // Update existing package
            Container.Write(entries);
        }
示例#3
0
        // this code is insanely stupid, and mostly my fault -- chrisf
        void PrepareMapResources(ModData modData, Map map)
        {
            Program.Rules = map.Rules;

            tileset         = Program.Rules.TileSets[map.Tileset];
            tilesetRenderer = new TileSetRenderer(tileset, modData.Manifest.TileSize);
            var shadowIndex = new int[] { 3, 4 };
            var palette     = new ImmutablePalette(GlobalFileSystem.Open(tileset.Palette), shadowIndex);

            // required for desert terrain in RA
            var playerPalette   = tileset.PlayerPalette ?? tileset.Palette;
            var shadowedPalette = new ImmutablePalette(GlobalFileSystem.Open(playerPalette), shadowIndex);

            surface1.Bind(map, tileset, tilesetRenderer, palette, shadowedPalette);

            // construct the palette of tiles
            var palettes = new[] { tilePalette, actorPalette, resourcePalette };

            foreach (var p in palettes)
            {
                p.Visible = false; p.SuspendLayout();
            }

            var templateOrder = tileset.EditorTemplateOrder ?? new string[] { };

            foreach (var tc in tileset.Templates.GroupBy(t => t.Value.Category).OrderBy(t => Array.IndexOf(templateOrder, t.Key)))
            {
                var category       = tc.Key ?? "(Uncategorized)";
                var categoryHeader = new Label
                {
                    BackColor = SystemColors.Highlight,
                    ForeColor = SystemColors.HighlightText,
                    Text      = category,
                    AutoSize  = false,
                    Height    = 24,
                    TextAlign = ContentAlignment.MiddleLeft,
                    Width     = tilePalette.ClientSize.Width,
                };

                // hook this manually, anchoring inside FlowLayoutPanel is flaky.
                tilePalette.Resize += (_, e) => categoryHeader.Width = tilePalette.ClientSize.Width;

                if (tilePalette.Controls.Count > 0)
                {
                    tilePalette.SetFlowBreak(
                        tilePalette.Controls[tilePalette.Controls.Count - 1], true);
                }
                tilePalette.Controls.Add(categoryHeader);

                foreach (var t in tc)
                {
                    try
                    {
                        var bitmap = tilesetRenderer.RenderTemplate((ushort)t.Key, palette);
                        var ibox   = new PictureBox
                        {
                            Image    = bitmap,
                            Width    = bitmap.Width / 2,
                            Height   = bitmap.Height / 2,
                            SizeMode = PictureBoxSizeMode.StretchImage
                        };

                        var brushTemplate = new BrushTemplate {
                            Bitmap = bitmap, N = t.Key
                        };
                        ibox.Click += (_, e) => surface1.SetTool(new BrushTool(brushTemplate));

                        var template = t.Value;
                        tilePalette.Controls.Add(ibox);
                        tt.SetToolTip(ibox, "{1}:{0} ({2}x{3})".F(template.Image, template.Id, template.Size.X, template.Size.Y));
                    }
                    catch { }
                }
            }

            var actorTemplates = new List <ActorTemplate>();

            foreach (var a in Program.Rules.Actors.Keys)
            {
                try
                {
                    var info = Program.Rules.Actors[a];
                    if (!info.Traits.Contains <RenderSimpleInfo>())
                    {
                        continue;
                    }

                    var etf = info.Traits.GetOrDefault <EditorTilesetFilterInfo>();
                    if (etf != null && etf.ExcludeTilesets != null &&
                        etf.ExcludeTilesets.Contains(tileset.Id))
                    {
                        continue;
                    }
                    if (etf != null && etf.RequireTilesets != null &&
                        !etf.RequireTilesets.Contains(tileset.Id))
                    {
                        continue;
                    }

                    var templatePalette = shadowedPalette;
                    var rsi             = info.Traits.GetOrDefault <RenderSimpleInfo>();

                    // exception for desert buildings
                    if (rsi != null && rsi.Palette != null && rsi.Palette.Contains("terrain"))
                    {
                        templatePalette = palette;
                    }

                    var template = RenderUtils.RenderActor(info, tileset, templatePalette);
                    var ibox     = new PictureBox
                    {
                        Image       = template.Bitmap,
                        Width       = 32,
                        Height      = 32,
                        SizeMode    = PictureBoxSizeMode.Zoom,
                        BorderStyle = BorderStyle.FixedSingle
                    };

                    ibox.Click += (_, e) => surface1.SetTool(new ActorTool(template));

                    actorPalette.Controls.Add(ibox);

                    tt.SetToolTip(ibox, "{0}".F(info.Name));

                    actorTemplates.Add(template);
                }
                catch { }
            }

            surface1.BindActorTemplates(actorTemplates);

            var resourceTemplates = new List <ResourceTemplate>();

            foreach (var a in Program.Rules.Actors["world"].Traits.WithInterface <ResourceTypeInfo>())
            {
                try
                {
                    var template = RenderUtils.RenderResourceType(a, tileset.Extensions, shadowedPalette);
                    var ibox     = new PictureBox
                    {
                        Image       = template.Bitmap,
                        Width       = 32,
                        Height      = 32,
                        SizeMode    = PictureBoxSizeMode.Zoom,
                        BorderStyle = BorderStyle.FixedSingle
                    };

                    ibox.Click += (_, e) => surface1.SetTool(new ResourceTool(template));

                    resourcePalette.Controls.Add(ibox);

                    tt.SetToolTip(ibox, "{0}:{1}cr".F(template.Info.Name, template.Info.ValuePerUnit));

                    resourceTemplates.Add(template);
                }
                catch { }
            }

            surface1.BindResourceTemplates(resourceTemplates);

            foreach (var p in palettes)
            {
                p.Visible = true;
                p.ResumeLayout();
            }

            miniMapBox.Image = Minimap.RenderMapPreview(tileset, surface1.Map, true);

            propertiesToolStripMenuItem.Enabled = true;
            toolStripMenuItemProperties.Enabled = true;
            resizeToolStripMenuItem.Enabled     = true;
            toolStripMenuItemResize.Enabled     = true;
            saveToolStripMenuItem.Enabled       = true;
            toolStripMenuItemSave.Enabled       = true;
            saveAsToolStripMenuItem.Enabled     = true;
            miniMapToPng.Enabled = true;

            PopulateActorOwnerChooser();
        }
示例#4
0
 public static List <MiniYamlNode> FromFileInPackage(string path)
 {
     using (var stream = GlobalFileSystem.Open(path))
         return(FromLines(stream.ReadAllLines(), path));
 }
示例#5
0
        public void StartGame(Arguments args)
        {
            Ui.ResetAll();
            Game.Settings.Save();

            // Check whether the mod content is installed
            // TODO: The installation code has finally been beaten into shape, so we can
            // finally move it all into the planned "Manage Content" panel in the modchooser mod.
            var installData       = Game.ModData.Manifest.Get <ContentInstaller>();
            var installModContent = !installData.TestFiles.All(f => GlobalFileSystem.Exists(f));
            var installModMusic   = args != null && args.Contains("Install.Music");

            if (installModContent || installModMusic)
            {
                var widgetArgs = new WidgetArgs()
                {
                    { "continueLoading", () => Game.InitializeMod(Game.Settings.Game.Mod, args) },
                };

                if (installData.BackgroundWidget != null)
                {
                    Ui.LoadWidget(installData.BackgroundWidget, Ui.Root, widgetArgs);
                }

                var menu = installModContent ? installData.MenuWidget : installData.MusicMenuWidget;
                Ui.OpenWindow(menu, widgetArgs);

                return;
            }

            // Join a server directly
            var connect = string.Empty;

            if (args != null)
            {
                if (args.Contains("Launch.Connect"))
                {
                    connect = args.GetValue("Launch.Connect", null);
                }

                if (args.Contains("Launch.URI"))
                {
                    connect = args.GetValue("Launch.URI", null);
                    if (connect != null)
                    {
                        connect = connect.Replace("openra://", "");
                        connect = connect.TrimEnd('/');
                    }
                }
            }

            if (!string.IsNullOrEmpty(connect))
            {
                var parts = connect.Split(':');

                if (parts.Length == 2)
                {
                    var host = parts[0];
                    var port = Exts.ParseIntegerInvariant(parts[1]);
                    Game.LoadShellMap();
                    Game.RemoteDirectConnect(host, port);
                    return;
                }
            }

            // Load a replay directly
            var replayFilename = args != null?args.GetValue("Launch.Replay", null) : null;

            if (!string.IsNullOrEmpty(replayFilename))
            {
                var replayMeta = ReplayMetadata.Read(replayFilename);
                if (ReplayUtils.PromptConfirmReplayCompatibility(replayMeta, Game.LoadShellMap))
                {
                    Game.JoinReplay(replayFilename);
                }

                if (replayMeta != null)
                {
                    var mod = replayMeta.GameInfo.Mod;
                    if (mod != null && mod != Game.ModData.Manifest.Mod.Id && ModMetadata.AllMods.ContainsKey(mod))
                    {
                        Game.InitializeMod(mod, args);
                    }
                }

                return;
            }

            Game.LoadShellMap();
            Game.Settings.Save();
        }
示例#6
0
文件: Shader.cs 项目: wytsep/OpenRA
        public Shader(string name)
        {
            // Vertex shader
            string vertexCode;

            using (var file = new StreamReader(GlobalFileSystem.Open("glsl{0}{1}.vert".F(Path.DirectorySeparatorChar, name))))
                vertexCode = file.ReadToEnd();

            var vertexShader = GL.CreateShader(ShaderType.VertexShader);

            ErrorHandler.CheckGlError();
            GL.ShaderSource(vertexShader, vertexCode);
            ErrorHandler.CheckGlError();
            GL.CompileShader(vertexShader);
            ErrorHandler.CheckGlError();
            int success;

            GL.GetShader(vertexShader, ShaderParameter.CompileStatus, out success);
            ErrorHandler.CheckGlError();
            if (success == (int)All.False)
            {
                throw new InvalidProgramException("Compile error in glsl{0}{1}.vert".F(Path.DirectorySeparatorChar, name));
            }

            // Fragment shader
            string fragmentCode;

            using (var file = new StreamReader(GlobalFileSystem.Open("glsl{0}{1}.frag".F(Path.DirectorySeparatorChar, name))))
                fragmentCode = file.ReadToEnd();

            var fragmentShader = GL.CreateShader(ShaderType.FragmentShader);

            ErrorHandler.CheckGlError();
            GL.ShaderSource(fragmentShader, fragmentCode);
            ErrorHandler.CheckGlError();
            GL.CompileShader(fragmentShader);
            ErrorHandler.CheckGlError();
            GL.GetShader(vertexShader, ShaderParameter.CompileStatus, out success);
            ErrorHandler.CheckGlError();
            if (success == (int)All.False)
            {
                throw new InvalidProgramException("Compile error in glsl{0}{1}.frag".F(Path.DirectorySeparatorChar, name));
            }

            // Assemble program
            program = GL.CreateProgram();
            ErrorHandler.CheckGlError();
            GL.AttachShader(program, vertexShader);
            ErrorHandler.CheckGlError();
            GL.AttachShader(program, fragmentShader);
            ErrorHandler.CheckGlError();

            GL.LinkProgram(program);
            ErrorHandler.CheckGlError();
            GL.GetProgram(program, ProgramParameter.LinkStatus, out success);
            ErrorHandler.CheckGlError();
            if (success == (int)All.False)
            {
                throw new InvalidProgramException("Linking error in {0} shader".F(name));
            }

            GL.UseProgram(program);
            ErrorHandler.CheckGlError();

            int numUniforms;

            GL.GetProgram(program, ProgramParameter.ActiveUniforms, out numUniforms);
            ErrorHandler.CheckGlError();

            var nextTexUnit = 0;

            for (var i = 0; i < numUniforms; i++)
            {
                int length, size;
                ActiveUniformType type;
                var sb = new StringBuilder(128);
                GL.GetActiveUniform(program, i, 128, out length, out size, out type, sb);
                var sampler = sb.ToString();
                ErrorHandler.CheckGlError();

                if (type == ActiveUniformType.Sampler2D)
                {
                    samplers.Add(sampler, nextTexUnit);

                    var loc = GL.GetUniformLocation(program, sampler);
                    ErrorHandler.CheckGlError();
                    GL.Uniform1(loc, nextTexUnit);
                    ErrorHandler.CheckGlError();

                    nextTexUnit++;
                }
            }
        }
示例#7
0
        public AssetBrowserLogic(Widget widget, Action onExit, World world)
        {
            this.world = world;

            panel       = widget;
            assetSource = GlobalFileSystem.MountedFolders.First();

            var ticker = panel.GetOrNull <LogicTickerWidget>("ANIMATION_TICKER");

            if (ticker != null)
            {
                ticker.OnTick = () =>
                {
                    if (animateFrames)
                    {
                        SelectNextFrame();
                    }
                };
            }

            var sourceDropdown = panel.GetOrNull <DropDownButtonWidget>("SOURCE_SELECTOR");

            if (sourceDropdown != null)
            {
                sourceDropdown.OnMouseDown = _ => ShowSourceDropdown(sourceDropdown);
                sourceDropdown.GetText     = () =>
                {
                    var name = assetSource != null?Platform.UnresolvePath(assetSource.Name) : "All Packages";

                    if (name.Length > 15)
                    {
                        name = "..." + name.Substring(name.Length - 15);
                    }

                    return(name);
                };
            }

            var spriteWidget = panel.GetOrNull <SpriteWidget>("SPRITE");

            if (spriteWidget != null)
            {
                spriteWidget.GetSprite  = () => currentSprites != null ? currentSprites[currentFrame] : null;
                currentPalette          = spriteWidget.Palette;
                spriteWidget.GetPalette = () => currentPalette;
                spriteWidget.IsVisible  = () => !isVideoLoaded;
            }

            var playerWidget = panel.GetOrNull <VqaPlayerWidget>("PLAYER");

            if (playerWidget != null)
            {
                playerWidget.IsVisible = () => isVideoLoaded;
            }

            var paletteDropDown = panel.GetOrNull <DropDownButtonWidget>("PALETTE_SELECTOR");

            if (paletteDropDown != null)
            {
                paletteDropDown.OnMouseDown = _ => ShowPaletteDropdown(paletteDropDown, world);
                paletteDropDown.GetText     = () => currentPalette;
            }

            var colorPreview = panel.GetOrNull <ColorPreviewManagerWidget>("COLOR_MANAGER");

            if (colorPreview != null)
            {
                colorPreview.Color = Game.Settings.Player.Color;
            }

            var colorDropdown = panel.GetOrNull <DropDownButtonWidget>("COLOR");

            if (colorDropdown != null)
            {
                colorDropdown.IsDisabled  = () => currentPalette != colorPreview.PaletteName;
                colorDropdown.OnMouseDown = _ => ColorPickerLogic.ShowColorDropDown(colorDropdown, colorPreview, world);
                panel.Get <ColorBlockWidget>("COLORBLOCK").GetColor = () => Game.Settings.Player.Color.RGB;
            }

            filenameInput = panel.Get <TextFieldWidget>("FILENAME_INPUT");
            filenameInput.OnTextEdited = () => ApplyFilter(filenameInput.Text);
            filenameInput.OnEscKey     = filenameInput.YieldKeyboardFocus;

            var frameContainer = panel.GetOrNull("FRAME_SELECTOR");

            if (frameContainer != null)
            {
                frameContainer.IsVisible = () => (currentSprites != null && currentSprites.Length > 1) ||
                                           (isVideoLoaded && player != null && player.Video != null && player.Video.Frames > 1);
            }

            frameSlider = panel.Get <SliderWidget>("FRAME_SLIDER");
            if (frameSlider != null)
            {
                frameSlider.OnChange += x =>
                {
                    if (!isVideoLoaded)
                    {
                        currentFrame = (int)Math.Round(x);
                    }
                };

                frameSlider.GetValue   = () => isVideoLoaded ? player.Video.CurrentFrame : currentFrame;
                frameSlider.IsDisabled = () => isVideoLoaded;
            }

            var frameText = panel.GetOrNull <LabelWidget>("FRAME_COUNT");

            if (frameText != null)
            {
                frameText.GetText = () =>
                                    isVideoLoaded ?
                                    "{0} / {1}".F(player.Video.CurrentFrame + 1, player.Video.Frames) :
                                    "{0} / {1}".F(currentFrame, currentSprites.Length - 1);
            }

            var playButton = panel.GetOrNull <ButtonWidget>("BUTTON_PLAY");

            if (playButton != null)
            {
                playButton.Key     = new Hotkey(Keycode.SPACE, Modifiers.None);
                playButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Play();
                    }
                    else
                    {
                        animateFrames = true;
                    }
                };

                playButton.IsVisible = () => isVideoLoaded ? player.Paused : !animateFrames;
            }

            var pauseButton = panel.GetOrNull <ButtonWidget>("BUTTON_PAUSE");

            if (pauseButton != null)
            {
                pauseButton.Key     = new Hotkey(Keycode.SPACE, Modifiers.None);
                pauseButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Pause();
                    }
                    else
                    {
                        animateFrames = false;
                    }
                };

                pauseButton.IsVisible = () => isVideoLoaded ? !player.Paused : animateFrames;
            }

            var stopButton = panel.GetOrNull <ButtonWidget>("BUTTON_STOP");

            if (stopButton != null)
            {
                stopButton.Key     = new Hotkey(Keycode.RETURN, Modifiers.None);
                stopButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Stop();
                    }
                    else
                    {
                        frameSlider.Value = 0;
                        currentFrame      = 0;
                        animateFrames     = false;
                    }
                };
            }

            var nextButton = panel.GetOrNull <ButtonWidget>("BUTTON_NEXT");

            if (nextButton != null)
            {
                nextButton.Key     = new Hotkey(Keycode.RIGHT, Modifiers.None);
                nextButton.OnClick = () =>
                {
                    if (!isVideoLoaded)
                    {
                        nextButton.OnClick = SelectNextFrame;
                    }
                };

                nextButton.IsVisible = () => !isVideoLoaded;
            }

            var prevButton = panel.GetOrNull <ButtonWidget>("BUTTON_PREV");

            if (prevButton != null)
            {
                prevButton.Key     = new Hotkey(Keycode.LEFT, Modifiers.None);
                prevButton.OnClick = () =>
                {
                    if (!isVideoLoaded)
                    {
                        SelectPreviousFrame();
                    }
                };

                prevButton.IsVisible = () => !isVideoLoaded;
            }

            assetList = panel.Get <ScrollPanelWidget>("ASSET_LIST");
            template  = panel.Get <ScrollItemWidget>("ASSET_TEMPLATE");
            PopulateAssetList();

            var closeButton = panel.GetOrNull <ButtonWidget>("CLOSE_BUTTON");

            if (closeButton != null)
            {
                closeButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Stop();
                    }
                    Ui.CloseWindow();
                    onExit();
                }
            }
            ;
        }

        void SelectNextFrame()
        {
            currentFrame++;
            if (currentFrame >= currentSprites.Length)
            {
                currentFrame = 0;
            }
        }

        void SelectPreviousFrame()
        {
            currentFrame--;
            if (currentFrame < 0)
            {
                currentFrame = currentSprites.Length - 1;
            }
        }

        Dictionary <string, bool> assetVisByName = new Dictionary <string, bool>();

        bool FilterAsset(string filename)
        {
            var filter = filenameInput.Text;

            if (string.IsNullOrWhiteSpace(filter))
            {
                return(true);
            }

            if (filename.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0)
            {
                return(true);
            }

            return(false);
        }

        void ApplyFilter(string filename)
        {
            assetVisByName.Clear();
            assetList.Layout.AdjustChildren();
            assetList.ScrollToTop();

            // Select the first visible
            var firstVisible = assetVisByName.FirstOrDefault(kvp => kvp.Value);

            if (firstVisible.Key != null)
            {
                LoadAsset(firstVisible.Key);
            }
        }

        void AddAsset(ScrollPanelWidget list, string filepath, ScrollItemWidget template)
        {
            var filename = Path.GetFileName(filepath);
            var item     = ScrollItemWidget.Setup(template,
                                                  () => currentFilename == filename,
                                                  () => { LoadAsset(filename); });

            item.Get <LabelWidget>("TITLE").GetText = () => filepath;
            item.IsVisible = () =>
            {
                bool visible;
                if (assetVisByName.TryGetValue(filepath, out visible))
                {
                    return(visible);
                }

                visible = FilterAsset(filepath);
                assetVisByName.Add(filepath, visible);
                return(visible);
            };

            list.AddChild(item);
        }

        bool LoadAsset(string filename)
        {
            if (isVideoLoaded)
            {
                player.Stop();
                player        = null;
                isVideoLoaded = false;
            }

            if (string.IsNullOrEmpty(filename))
            {
                return(false);
            }

            if (!GlobalFileSystem.Exists(filename))
            {
                return(false);
            }

            if (Path.GetExtension(filename.ToLowerInvariant()) == ".vqa")
            {
                player          = panel.Get <VqaPlayerWidget>("PLAYER");
                currentFilename = filename;
                player.Load(filename);
                player.DrawOverlay       = false;
                isVideoLoaded            = true;
                frameSlider.MaximumValue = (float)player.Video.Frames - 1;
                frameSlider.Ticks        = 0;
                return(true);
            }
            else
            {
                currentFilename          = filename;
                currentSprites           = world.Map.SequenceProvider.SpriteCache[filename];
                currentFrame             = 0;
                frameSlider.MaximumValue = (float)currentSprites.Length - 1;
                frameSlider.Ticks        = currentSprites.Length;
            }

            return(true);
        }

        bool ShowSourceDropdown(DropDownButtonWidget dropdown)
        {
            Func <IFolder, ScrollItemWidget, ScrollItemWidget> setupItem = (source, itemTemplate) =>
            {
                var item = ScrollItemWidget.Setup(itemTemplate,
                                                  () => assetSource == source,
                                                  () => { assetSource = source; PopulateAssetList(); });
                item.Get <LabelWidget>("LABEL").GetText = () => source != null?Platform.UnresolvePath(source.Name) : "All Packages";

                return(item);
            };

            // TODO: Re-enable "All Packages" once list generation is done in a background thread
            // var sources = new[] { (IFolder)null }.Concat(GlobalFileSystem.MountedFolders);
            var sources = GlobalFileSystem.MountedFolders;

            dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 280, sources, setupItem);
            return(true);
        }

        void PopulateAssetList()
        {
            assetList.RemoveChildren();
            availableShps.Clear();

            // TODO: This is too slow to run in the main thread
            // var files = AssetSource != null ? AssetSource.AllFileNames() :
            // GlobalFileSystem.MountedFolders.SelectMany(f => f.AllFileNames());
            if (assetSource == null)
            {
                return;
            }

            var files = assetSource.AllFileNames().OrderBy(s => s);

            foreach (var file in files)
            {
                if (AllowedExtensions.Any(ext => file.EndsWith(ext, true, CultureInfo.InvariantCulture)))
                {
                    AddAsset(assetList, file, template);
                    availableShps.Add(file);
                }
            }
        }

        bool ShowPaletteDropdown(DropDownButtonWidget dropdown, World world)
        {
            Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (name, itemTemplate) =>
            {
                var item = ScrollItemWidget.Setup(itemTemplate,
                                                  () => currentPalette == name,
                                                  () => currentPalette = name);
                item.Get <LabelWidget>("LABEL").GetText = () => name;

                return(item);
            };

            var palettes = world.WorldActor.TraitsImplementing <IProvidesAssetBrowserPalettes>()
                           .SelectMany(p => p.PaletteNames);

            dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 280, palettes, setupItem);
            return(true);
        }
    }
示例#8
0
        public ScriptContext(World world, WorldRenderer worldRenderer,
                             IEnumerable <string> scripts)
        {
            runtime = new MemoryConstrainedLuaRuntime();

            World              = world;
            WorldRenderer      = worldRenderer;
            knownActorCommands = Game.modData.ObjectCreator
                                 .GetTypesImplementing <ScriptActorProperties>()
                                 .ToArray();

            ActorCommands  = new Cache <ActorInfo, Type[]>(FilterActorCommands);
            PlayerCommands = Game.modData.ObjectCreator
                             .GetTypesImplementing <ScriptPlayerProperties>()
                             .ToArray();

            runtime.DoBuffer(GlobalFileSystem.Open(Path.Combine("lua", "scriptwrapper.lua")).ReadAllText(), "scriptwrapper.lua").Dispose();
            tick = (LuaFunction)runtime.Globals["Tick"];

            // Register globals
            using (var fn = runtime.CreateFunctionFromDelegate((Action <string>)FatalError))
                runtime.Globals["FatalError"] = fn;

            runtime.Globals["MaxUserScriptInstructions"] = MaxUserScriptInstructions;

            using (var registerGlobal = (LuaFunction)runtime.Globals["RegisterSandboxedGlobal"])
            {
                using (var fn = runtime.CreateFunctionFromDelegate((Action <string>)Console.WriteLine))
                    registerGlobal.Call("print", fn).Dispose();

                // Register global tables
                var bindings = Game.modData.ObjectCreator.GetTypesImplementing <ScriptGlobal>();
                foreach (var b in bindings)
                {
                    var ctor = b.GetConstructors(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(c =>
                    {
                        var p = c.GetParameters();
                        return(p.Length == 1 && p.First().ParameterType == typeof(ScriptContext));
                    });

                    if (ctor == null)
                    {
                        throw new InvalidOperationException("{0} must define a constructor that takes a ScriptContext context parameter".F(b.Name));
                    }

                    var binding = (ScriptGlobal)ctor.Invoke(new[] { this });
                    using (var obj = binding.ToLuaValue(this))
                        registerGlobal.Call(binding.Name, obj).Dispose();
                }
            }

            // System functions do not count towards the memory limit
            runtime.MaxMemoryUse = runtime.MemoryUse + MaxUserScriptMemory;

            using (var loadScript = (LuaFunction)runtime.Globals["ExecuteSandboxedScript"])
            {
                foreach (var s in scripts)
                {
                    loadScript.Call(s, GlobalFileSystem.Open(s).ReadAllText()).Dispose();
                }
            }
        }
示例#9
0
文件: Map.cs 项目: wenzeslaus/OpenRA
        // The standard constructor for most purposes
        public Map(string path)
        {
            Path      = path;
            Container = GlobalFileSystem.OpenPackage(path, null, int.MaxValue);

            AssertExists("map.yaml");
            AssertExists("map.bin");

            var yaml = new MiniYaml(null, MiniYaml.FromStream(Container.GetContent("map.yaml"), path));

            FieldLoader.Load(this, yaml);

            // Support for formats 1-3 dropped 2011-02-11.
            // Use release-20110207 to convert older maps to format 4
            // Use release-20110511 to convert older maps to format 5
            // Use release-20141029 to convert older maps to format 6
            if (MapFormat < 6)
            {
                throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, path));
            }

            var nd = yaml.ToDictionary();

            // Format 6 -> 7 combined the Selectable and UseAsShellmap flags into the Class enum
            if (MapFormat < 7)
            {
                MiniYaml useAsShellmap;
                if (nd.TryGetValue("UseAsShellmap", out useAsShellmap) && bool.Parse(useAsShellmap.Value))
                {
                    Visibility = MapVisibility.Shellmap;
                }
                else if (Type == "Mission" || Type == "Campaign")
                {
                    Visibility = MapVisibility.MissionSelector;
                }
            }

            // Load players
            foreach (var my in nd["Players"].ToDictionary().Values)
            {
                var player = new PlayerReference(my);
                Players.Add(player.Name, player);
            }

            Actors = Exts.Lazy(() =>
            {
                var ret = new Dictionary <string, ActorReference>();
                foreach (var kv in nd["Actors"].ToDictionary())
                {
                    ret.Add(kv.Key, new ActorReference(kv.Value.Value, kv.Value.ToDictionary()));
                }
                return(ret);
            });

            // Smudges
            Smudges = Exts.Lazy(() =>
            {
                var ret = new List <SmudgeReference>();
                foreach (var name in nd["Smudges"].ToDictionary().Keys)
                {
                    var vals = name.Split(' ');
                    var loc  = vals[1].Split(',');
                    ret.Add(new SmudgeReference(vals[0], new int2(
                                                    Exts.ParseIntegerInvariant(loc[0]),
                                                    Exts.ParseIntegerInvariant(loc[1])),
                                                Exts.ParseIntegerInvariant(vals[2])));
                }

                return(ret);
            });

            RuleDefinitions          = MiniYaml.NodesOrEmpty(yaml, "Rules");
            SequenceDefinitions      = MiniYaml.NodesOrEmpty(yaml, "Sequences");
            VoxelSequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "VoxelSequences");
            WeaponDefinitions        = MiniYaml.NodesOrEmpty(yaml, "Weapons");
            VoiceDefinitions         = MiniYaml.NodesOrEmpty(yaml, "Voices");
            NotificationDefinitions  = MiniYaml.NodesOrEmpty(yaml, "Notifications");
            TranslationDefinitions   = MiniYaml.NodesOrEmpty(yaml, "Translations");

            MapTiles     = Exts.Lazy(() => LoadMapTiles());
            MapResources = Exts.Lazy(() => LoadResourceTiles());
            MapHeight    = Exts.Lazy(() => LoadMapHeight());

            TileShape      = Game.ModData.Manifest.TileShape;
            SubCellOffsets = Game.ModData.Manifest.SubCellOffsets;
            LastSubCell    = (SubCell)(SubCellOffsets.Length - 1);
            DefaultSubCell = (SubCell)Game.ModData.Manifest.SubCellDefaultIndex;

            if (Container.Exists("map.png"))
            {
                using (var dataStream = Container.GetContent("map.png"))
                    CustomPreview = new Bitmap(dataStream);
            }

            PostInit();

            // The Uid is calculated from the data on-disk, so
            // format changes must be flushed to disk.
            // TODO: this isn't very nice
            if (MapFormat < 7)
            {
                Save(path);
            }

            Uid = ComputeHash();
        }
示例#10
0
        void SelectMap(Map map)
        {
            selectedMapPreview = Game.ModData.MapCache[map.Uid];

            // Cache the rules on a background thread to avoid jank
            new Thread(selectedMapPreview.CacheRules).Start();

            var briefingVideo         = selectedMapPreview.Map.Videos.Briefing;
            var briefingVideoVisible  = briefingVideo != null;
            var briefingVideoDisabled = !(briefingVideoVisible && GlobalFileSystem.Exists(briefingVideo));

            var infoVideo         = selectedMapPreview.Map.Videos.BackgroundInfo;
            var infoVideoVisible  = infoVideo != null;
            var infoVideoDisabled = !(infoVideoVisible && GlobalFileSystem.Exists(infoVideo));

            startBriefingVideoButton.IsVisible  = () => briefingVideoVisible && playingVideo != PlayingVideo.Briefing;
            startBriefingVideoButton.IsDisabled = () => briefingVideoDisabled || playingVideo != PlayingVideo.None;
            startBriefingVideoButton.OnClick    = () => PlayVideo(videoPlayer, briefingVideo, PlayingVideo.Briefing, () => StopVideo(videoPlayer));

            startInfoVideoButton.IsVisible  = () => infoVideoVisible && playingVideo != PlayingVideo.Info;
            startInfoVideoButton.IsDisabled = () => infoVideoDisabled || playingVideo != PlayingVideo.None;
            startInfoVideoButton.OnClick    = () => PlayVideo(videoPlayer, infoVideo, PlayingVideo.Info, () => StopVideo(videoPlayer));

            var text = map.Description != null?map.Description.Replace("\\n", "\n") : "";

            text                      = WidgetUtils.WrapText(text, description.Bounds.Width, descriptionFont);
            description.Text          = text;
            description.Bounds.Height = descriptionFont.Measure(text).Y;
            descriptionPanel.ScrollToTop();
            descriptionPanel.Layout.AdjustChildren();

            if (difficultyButton != null)
            {
                difficultyButton.IsDisabled = () => !map.Options.Difficulties.Any();

                difficulty = map.Options.Difficulties.FirstOrDefault();
                difficultyButton.GetText     = () => difficulty ?? "Normal";
                difficultyButton.OnMouseDown = _ =>
                {
                    var options = map.Options.Difficulties.Select(d => new DropDownOption
                    {
                        Title      = d,
                        IsSelected = () => difficulty == d,
                        OnClick    = () => difficulty = d
                    });

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };

                    difficultyButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            if (gameSpeedButton != null)
            {
                var speeds = Game.ModData.Manifest.Get <GameSpeeds>().Speeds;
                gameSpeed = "default";

                gameSpeedButton.GetText     = () => speeds[gameSpeed].Name;
                gameSpeedButton.OnMouseDown = _ =>
                {
                    var options = speeds.Select(s => new DropDownOption
                    {
                        Title      = s.Value.Name,
                        IsSelected = () => gameSpeed == s.Key,
                        OnClick    = () => gameSpeed = s.Key
                    });

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };

                    gameSpeedButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }
        }
示例#11
0
        public void Run(ModData modData, string[] args)
        {
            // HACK: The engine code assumes that Game.modData is set.
            Game.modData = modData;

            GlobalFileSystem.LoadFromManifest(Game.modData.Manifest);

            var file = new IniFile(File.Open(args[1], FileMode.Open));

            var templateIndex = 0;
            var extension     = "tem";

            var terrainTypes = new Dictionary <int, string>()
            {
                { 1, "Clear" },                 // Desert sand(?)
                { 5, "Road" },                  // Paved road
                { 6, "Rail" },                  // Monorail track
                { 7, "Impassable" },            // Building
                { 9, "Water" },                 // Deep water(?)
                { 10, "Water" },                // Shallow water
                { 11, "Road" },                 // Paved road (again?)
                { 12, "DirtRoad" },             // Dirt road
                { 13, "Clear" },                // Regular clear terrain
                { 14, "Rough" },                // Rough terrain (cracks etc)
                { 15, "Cliff" },                // Cliffs
            };

            // Loop over template sets
            try
            {
                for (var tilesetGroupIndex = 0; ; tilesetGroupIndex++)
                {
                    var section = file.GetSection("TileSet{0:D4}".F(tilesetGroupIndex));

                    var sectionCount    = int.Parse(section.GetValue("TilesInSet", "1"));
                    var sectionFilename = section.GetValue("FileName", "");
                    var sectionCategory = section.GetValue("SetName", "");

                    // Loop over templates
                    for (var i = 1; i <= sectionCount; i++, templateIndex++)
                    {
                        var templateFilename = "{0}{1:D2}.{2}".F(sectionFilename, i, extension);
                        if (!GlobalFileSystem.Exists(templateFilename))
                        {
                            continue;
                        }

                        using (var s = GlobalFileSystem.Open(templateFilename))
                        {
                            Console.WriteLine("\tTemplate@{0}:", templateIndex);
                            Console.WriteLine("\t\tCategory: {0}", sectionCategory);
                            Console.WriteLine("\t\tId: {0}", templateIndex);
                            Console.WriteLine("\t\tImage: {0}{1:D2}", sectionFilename, i);

                            var templateWidth  = s.ReadUInt32();
                            var templateHeight = s.ReadUInt32();
                            /* var tileWidth = */ s.ReadInt32();
                            /* var tileHeight = */ s.ReadInt32();
                            var offsets = new uint[templateWidth * templateHeight];
                            for (var j = 0; j < offsets.Length; j++)
                            {
                                offsets[j] = s.ReadUInt32();
                            }

                            Console.WriteLine("\t\tSize: {0}, {1}", templateWidth, templateHeight);
                            Console.WriteLine("\t\tTiles:");

                            for (var j = 0; j < offsets.Length; j++)
                            {
                                if (offsets[j] == 0)
                                {
                                    continue;
                                }

                                s.Position = offsets[j] + 40;
                                /* var height = */ s.ReadUInt8();
                                var terrainType = s.ReadUInt8();
                                /* var rampType = */ s.ReadUInt8();
                                /* var height = */ s.ReadUInt8();
                                if (!terrainTypes.ContainsKey(terrainType))
                                {
                                    throw new InvalidDataException("Unknown terrain type {0} in {1}".F(terrainType, templateFilename));
                                }

                                Console.WriteLine("\t\t\t{0}: {1}", j, terrainTypes[terrainType]);
                                // Console.WriteLine("\t\t\t\tHeight: {0}", height);
                                // Console.WriteLine("\t\t\t\tTerrainType: {0}", terrainType);
                                // Console.WriteLine("\t\t\t\tRampType: {0}", rampType);
                                // Console.WriteLine("\t\t\t\tLeftColor: {0},{1},{2}", s.ReadUInt8(), s.ReadUInt8(), s.ReadUInt8());
                                // Console.WriteLine("\t\t\t\tRightColor: {0},{1},{2}", s.ReadUInt8(), s.ReadUInt8(), s.ReadUInt8());
                            }
                        }
                    }
                }
            }
            catch (InvalidOperationException)
            {
                // GetSection will throw when we run out of sections to import
            }
        }
示例#12
0
        public void Run(ModData modData, string[] args)
        {
            // HACK: The engine code assumes that Game.modData is set.
            Game.ModData = modData;
            GlobalFileSystem.LoadFromManifest(Game.ModData.Manifest);

            var imageField             = typeof(TerrainTemplateInfo).GetField("Image");
            var pickAnyField           = typeof(TerrainTemplateInfo).GetField("PickAny");
            var tileInfoField          = typeof(TerrainTemplateInfo).GetField("tileInfo", BindingFlags.NonPublic | BindingFlags.Instance);
            var terrainTypeField       = typeof(TerrainTileInfo).GetField("TerrainType");
            var terrainLeftColorField  = typeof(TerrainTileInfo).GetField("LeftColor");
            var terrainRightColorField = typeof(TerrainTileInfo).GetField("RightColor");
            var empty = new Size(0, 0);
            var single = new int2(1, 1);
            var exts = new[] { "" }.Concat(args[1].Split(','));

            foreach (var t in Game.ModData.Manifest.TileSets)
            {
                var ts         = new TileSet(Game.ModData, t);
                var frameCache = new FrameCache(Game.ModData.SpriteLoaders);

                Console.WriteLine("Tileset: " + ts.Name);
                foreach (var template in ts.Templates.Values)
                {
                    // Find the sprite associated with this template
                    foreach (var ext in exts)
                    {
                        Stream s;
                        if (!GlobalFileSystem.TryOpen(template.Images[0] + ext, out s))
                        {
                            continue;
                        }

                        // Rewrite the template image (normally readonly) using reflection
                        imageField.SetValue(template, template.Images[0] + ext);

                        // Fetch the private tileInfo array so that we can write new entries
                        var tileInfo = (TerrainTileInfo[])tileInfoField.GetValue(template);

                        // Open the file and search for any implicit frames
                        var allFrames = frameCache[template.Images[0]];
                        var frames    = template.Frames != null?template.Frames.Select(f => allFrames[f]).ToArray() : allFrames;

                        // Resize array for new entries
                        if (frames.Length > template.TilesCount)
                        {
                            var ti = new TerrainTileInfo[frames.Length];
                            Array.Copy(tileInfo, ti, template.TilesCount);
                            tileInfoField.SetValue(template, ti);
                            tileInfo = ti;
                        }

                        for (var i = 0; i < template.TilesCount; i++)
                        {
                            if (template[i] == null && frames[i] != null && frames[i].Size != empty)
                            {
                                tileInfo[i] = new TerrainTileInfo();
                                var ti = ts.GetTerrainIndex("Clear");
                                terrainTypeField.SetValue(tileInfo[i], ti);
                                terrainLeftColorField.SetValue(tileInfo[i], ts[ti].Color);
                                terrainRightColorField.SetValue(tileInfo[i], ts[ti].Color);
                                Console.WriteLine("Fixing entry for {0}:{1}", template.Images[0], i);
                            }
                        }

                        if (template.TilesCount > 1 && template.Size == single)
                        {
                            pickAnyField.SetValue(template, true);
                        }

                        s.Dispose();
                    }
                }

                ts.Save(t);
            }
        }
示例#13
0
        public void Run(ModData modData, string[] args)
        {
            // HACK: The engine code assumes that Game.modData is set.
            Game.ModData = modData;

            GlobalFileSystem.LoadFromManifest(Game.ModData.Manifest);

            var file      = new IniFile(File.Open(args[1], FileMode.Open));
            var extension = args[2];

            var templateIndex = 0;

            var terrainTypes = new string[]
            {
                "Clear",
                "Clear",                 // Note: sometimes "Ice"
                "Ice",
                "Ice",
                "Ice",
                "Road",                 // TS defines this as "Tunnel", but we don't need this
                "Rail",
                "Impassable",           // TS defines this as "Rock", but also uses it for buildings
                "Impassable",
                "Water",
                "Water",                 // TS defines this as "Beach", but uses it for water...?
                "Road",
                "DirtRoad",              // TS defines this as "Road", but we may want different speeds
                "Clear",
                "Rough",
                "Cliff"                 // TS defines this as "Rock"
            };

            // Loop over template sets
            try
            {
                for (var tilesetGroupIndex = 0;; tilesetGroupIndex++)
                {
                    var section = file.GetSection("TileSet{0:D4}".F(tilesetGroupIndex));

                    var sectionCount    = int.Parse(section.GetValue("TilesInSet", "1"));
                    var sectionFilename = section.GetValue("FileName", "");
                    var sectionCategory = section.GetValue("SetName", "");

                    // Loop over templates
                    for (var i = 1; i <= sectionCount; i++, templateIndex++)
                    {
                        var templateFilename = "{0}{1:D2}.{2}".F(sectionFilename, i, extension);
                        if (!GlobalFileSystem.Exists(templateFilename))
                        {
                            continue;
                        }

                        using (var s = GlobalFileSystem.Open(templateFilename))
                        {
                            Console.WriteLine("\tTemplate@{0}:", templateIndex);
                            Console.WriteLine("\t\tCategory: {0}", sectionCategory);
                            Console.WriteLine("\t\tId: {0}", templateIndex);

                            var images = new List <string>();

                            images.Add("{0}{1:D2}.{2}".F(sectionFilename, i, extension));
                            for (var v = 'a'; v <= 'z'; v++)
                            {
                                var variant = "{0}{1:D2}{2}.{3}".F(sectionFilename, i, v, extension);
                                if (GlobalFileSystem.Exists(variant))
                                {
                                    images.Add(variant);
                                }
                            }

                            Console.WriteLine("\t\tImage: {0}", images.JoinWith(", "));

                            var templateWidth  = s.ReadUInt32();
                            var templateHeight = s.ReadUInt32();
                            /* var tileWidth = */ s.ReadInt32();
                            /* var tileHeight = */ s.ReadInt32();
                            var offsets = new uint[templateWidth * templateHeight];
                            for (var j = 0; j < offsets.Length; j++)
                            {
                                offsets[j] = s.ReadUInt32();
                            }

                            Console.WriteLine("\t\tSize: {0}, {1}", templateWidth, templateHeight);
                            Console.WriteLine("\t\tTiles:");

                            for (var j = 0; j < offsets.Length; j++)
                            {
                                if (offsets[j] == 0)
                                {
                                    continue;
                                }

                                s.Position = offsets[j] + 40;
                                var height      = s.ReadUInt8();
                                var terrainType = s.ReadUInt8();
                                var rampType    = s.ReadUInt8();

                                if (terrainType >= terrainTypes.Length)
                                {
                                    throw new InvalidDataException("Unknown terrain type {0} in {1}".F(terrainType, templateFilename));
                                }

                                Console.WriteLine("\t\t\t{0}: {1}", j, terrainTypes[terrainType]);
                                if (height != 0)
                                {
                                    Console.WriteLine("\t\t\t\tHeight: {0}", height);
                                }

                                if (rampType != 0)
                                {
                                    Console.WriteLine("\t\t\t\tRampType: {0}", rampType);
                                }

                                Console.WriteLine("\t\t\t\tLeftColor: {0},{1},{2}", s.ReadUInt8(), s.ReadUInt8(), s.ReadUInt8());
                                Console.WriteLine("\t\t\t\tRightColor: {0},{1},{2}", s.ReadUInt8(), s.ReadUInt8(), s.ReadUInt8());
                            }
                        }
                    }
                }
            }
            catch (InvalidOperationException)
            {
                // GetSection will throw when we run out of sections to import
            }
        }
        public void LoadPalettes(WorldRenderer wr)
        {
            var filename = world.TileSet.PlayerPalette ?? world.TileSet.Palette;

            wr.AddPalette(info.Name, new ImmutablePalette(GlobalFileSystem.Open(filename), info.ShadowIndex), info.AllowModifiers);
        }
 public void LoadPalettes(WorldRenderer wr)
 {
     wr.AddPalette(info.Name, new ImmutablePalette(GlobalFileSystem.Open(world.TileSet.Palette), info.ShadowIndex), info.AllowModifiers);
 }
示例#16
0
 public void MountFiles()
 {
     GlobalFileSystem.LoadFromManifest(Manifest);
 }
示例#17
0
        enum IniMapFormat { RedAlert = 3 }         // otherwise, cnc (2 variants exist, we don't care to differentiate)

        public void ConvertIniMap(string iniFile)
        {
            using (var stream = GlobalFileSystem.Open(iniFile))
            {
                var file            = new IniFile(stream);
                var basic           = file.GetSection("Basic");
                var mapSection      = file.GetSection("Map");
                var legacyMapFormat = (IniMapFormat)Exts.ParseIntegerInvariant(basic.GetValue("NewINIFormat", "0"));
                var offsetX         = Exts.ParseIntegerInvariant(mapSection.GetValue("X", "0"));
                var offsetY         = Exts.ParseIntegerInvariant(mapSection.GetValue("Y", "0"));
                var width           = Exts.ParseIntegerInvariant(mapSection.GetValue("Width", "0"));
                var height          = Exts.ParseIntegerInvariant(mapSection.GetValue("Height", "0"));
                mapSize = (legacyMapFormat == IniMapFormat.RedAlert) ? 128 : 64;

                var tileset = Truncate(mapSection.GetValue("Theater", "TEMPERAT"), 8);
                map = new Map(rules.TileSets[tileset], mapSize, mapSize)
                {
                    Title  = basic.GetValue("Name", Path.GetFileNameWithoutExtension(iniFile)),
                    Author = "Westwood Studios"
                };

                var tl = new PPos(offsetX, offsetY);
                var br = new PPos(offsetX + width - 1, offsetY + height - 1);
                map.SetBounds(tl, br);

                if (legacyMapFormat == IniMapFormat.RedAlert)
                {
                    UnpackRATileData(ReadPackedSection(file.GetSection("MapPack")));
                    UnpackRAOverlayData(ReadPackedSection(file.GetSection("OverlayPack")));
                    ReadRATrees(file);
                }
                else
                {
                    // CnC
                    using (var s = GlobalFileSystem.Open(iniFile.Substring(0, iniFile.Length - 4) + ".bin"))
                        UnpackCncTileData(s);
                    ReadCncOverlay(file);
                    ReadCncTrees(file);
                }

                LoadVideos(file, "BASIC");
                LoadActors(file, "STRUCTURES");
                LoadActors(file, "UNITS");
                LoadActors(file, "INFANTRY");
                LoadActors(file, "SHIPS");
                LoadSmudges(file, "SMUDGE");

                var wps = file.GetSection("Waypoints")
                          .Where(kv => Exts.ParseIntegerInvariant(kv.Value) > 0)
                          .Select(kv => Pair.New(Exts.ParseIntegerInvariant(kv.Key),
                                                 LocationFromMapOffset(Exts.ParseIntegerInvariant(kv.Value), mapSize)));

                // Add waypoint actors
                foreach (var kv in wps)
                {
                    if (kv.First <= 7)
                    {
                        var ar = new ActorReference("mpspawn")
                        {
                            new LocationInit((CPos)kv.Second),
                            new OwnerInit("Neutral")
                        };

                        map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, ar.Save()));
                    }
                    else
                    {
                        var ar = new ActorReference("waypoint")
                        {
                            new LocationInit((CPos)kv.Second),
                            new OwnerInit("Neutral")
                        };

                        map.ActorDefinitions.Add(new MiniYamlNode("waypoint" + kv.First, ar.Save()));
                    }
                }

                // Create default player definitions only if there are no players to import
                mapPlayers = new MapPlayers(map.Rules, (players.Count == 0) ? map.SpawnPoints.Value.Length : 0);
                foreach (var p in players)
                {
                    LoadPlayer(file, p, legacyMapFormat == IniMapFormat.RedAlert);
                }
                map.PlayerDefinitions = mapPlayers.ToMiniYaml();
            }
        }
示例#18
0
        internal static void Initialize(Arguments args)
        {
            Console.WriteLine("Platform is {0}", Platform.CurrentPlatform);

            AppDomain.CurrentDomain.AssemblyResolve += GlobalFileSystem.ResolveAssembly;

            InitializeSettings(args);

            Log.AddChannel("perf", "perf.log");
            Log.AddChannel("debug", "debug.log");
            Log.AddChannel("sync", "syncreport.log");
            Log.AddChannel("server", "server.log");
            Log.AddChannel("sound", "sound.log");
            Log.AddChannel("graphics", "graphics.log");
            Log.AddChannel("geoip", "geoip.log");

            if (Settings.Server.DiscoverNatDevices)
            {
                UPnP.TryNatDiscovery();
            }
            else
            {
                Settings.Server.NatDeviceAvailable = false;
                Settings.Server.AllowPortForward   = false;
            }

            try
            {
                GeoIpDatabase = new DatabaseReader("GeoLite2-Country.mmdb");
            }
            catch (Exception e)
            {
                Log.Write("geoip", "DatabaseReader failed: {0}", e);
            }

            GlobalFileSystem.Mount(Platform.GameDir);             // Needed to access shaders
            var renderers = new[] { Settings.Graphics.Renderer, "Sdl2", null };

            foreach (var r in renderers)
            {
                if (r == null)
                {
                    throw new InvalidOperationException("No suitable renderers were found. Check graphics.log for details.");
                }

                Settings.Graphics.Renderer = r;
                try
                {
                    Renderer = new Renderer(Settings.Graphics, Settings.Server);
                    break;
                }
                catch (Exception e)
                {
                    Log.Write("graphics", "{0}", e);
                    Console.WriteLine("Renderer initialization failed. Fallback in place. Check graphics.log for details.");
                }
            }

            try
            {
                Sound.Create(Settings.Sound.Engine);
            }
            catch (Exception e)
            {
                Log.Write("sound", "{0}", e);
                Console.WriteLine("Creating the sound engine failed. Fallback in place. Check sound.log for details.");
                Settings.Sound.Engine = "Null";
                Sound.Create(Settings.Sound.Engine);
            }

            Console.WriteLine("Available mods:");
            foreach (var mod in ModMetadata.AllMods)
            {
                Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Title, mod.Value.Version);
            }

            InitializeMod(Settings.Game.Mod, args);

            if (Settings.Server.DiscoverNatDevices)
            {
                RunAfterDelay(Settings.Server.NatDiscoveryTimeout, UPnP.StoppingNatDiscovery);
            }
        }
示例#19
0
        enum IniMapFormat { RedAlert = 3 }         // otherwise, cnc (2 variants exist, we don't care to differentiate)

        public void ConvertIniMap(string iniFile)
        {
            var file            = new IniFile(GlobalFileSystem.Open(iniFile));
            var basic           = file.GetSection("Basic");
            var mapSection      = file.GetSection("Map");
            var legacyMapFormat = (IniMapFormat)Exts.ParseIntegerInvariant(basic.GetValue("NewINIFormat", "0"));
            var offsetX         = Exts.ParseIntegerInvariant(mapSection.GetValue("X", "0"));
            var offsetY         = Exts.ParseIntegerInvariant(mapSection.GetValue("Y", "0"));
            var width           = Exts.ParseIntegerInvariant(mapSection.GetValue("Width", "0"));
            var height          = Exts.ParseIntegerInvariant(mapSection.GetValue("Height", "0"));

            mapSize = (legacyMapFormat == IniMapFormat.RedAlert) ? 128 : 64;
            var size = new Size(mapSize, mapSize);

            var tileset = Truncate(mapSection.GetValue("Theater", "TEMPERAT"), 8);

            map            = Map.FromTileset(rules.TileSets[tileset]);
            map.Title      = basic.GetValue("Name", Path.GetFileNameWithoutExtension(iniFile));
            map.Author     = "Westwood Studios";
            map.MapSize.X  = mapSize;
            map.MapSize.Y  = mapSize;
            map.Bounds     = Rectangle.FromLTRB(offsetX, offsetY, offsetX + width, offsetY + height);
            map.Selectable = true;

            map.Smudges      = Exts.Lazy(() => new List <SmudgeReference>());
            map.Actors       = Exts.Lazy(() => new Dictionary <string, ActorReference>());
            map.MapResources = Exts.Lazy(() => new CellLayer <ResourceTile>(TileShape.Rectangle, size));
            map.MapTiles     = Exts.Lazy(() => new CellLayer <TerrainTile>(TileShape.Rectangle, size));

            map.Options = new MapOptions();

            if (legacyMapFormat == IniMapFormat.RedAlert)
            {
                UnpackRATileData(ReadPackedSection(file.GetSection("MapPack")));
                UnpackRAOverlayData(ReadPackedSection(file.GetSection("OverlayPack")));
                ReadRATrees(file);
            }
            else
            {
                // CnC
                using (var s = GlobalFileSystem.Open(iniFile.Substring(0, iniFile.Length - 4) + ".bin"))
                    UnpackCncTileData(s);
                ReadCncOverlay(file);
                ReadCncTrees(file);
            }

            LoadActors(file, "STRUCTURES");
            LoadActors(file, "UNITS");
            LoadActors(file, "INFANTRY");
            LoadSmudges(file, "SMUDGE");

            foreach (var p in players)
            {
                LoadPlayer(file, p, legacyMapFormat == IniMapFormat.RedAlert);
            }

            var wps = file.GetSection("Waypoints")
                      .Where(kv => Exts.ParseIntegerInvariant(kv.Value) > 0)
                      .Select(kv => Pair.New(Exts.ParseIntegerInvariant(kv.Key),
                                             LocationFromMapOffset(Exts.ParseIntegerInvariant(kv.Value), mapSize)))
                      .ToArray();

            // Add waypoint actors
            foreach (var kv in wps)
            {
                if (kv.First <= 7)
                {
                    var a = new ActorReference("mpspawn");
                    a.Add(new LocationInit((CPos)kv.Second));
                    a.Add(new OwnerInit("Neutral"));
                    map.Actors.Value.Add("Actor" + map.Actors.Value.Count.ToString(), a);
                }
                else
                {
                    var a = new ActorReference("waypoint");
                    a.Add(new LocationInit((CPos)kv.Second));
                    a.Add(new OwnerInit("Neutral"));
                    map.Actors.Value.Add("waypoint" + kv.First, a);
                }
            }
        }
示例#20
0
        // Support upgrading format 5 maps to a more
        // recent version by defining upgradeForMod.
        public Map(string path, string upgradeForMod)
        {
            Path      = path;
            Container = GlobalFileSystem.OpenPackage(path, null, int.MaxValue);

            AssertExists("map.yaml");
            AssertExists("map.bin");

            var yaml = new MiniYaml(null, MiniYaml.FromStream(Container.GetContent("map.yaml")));

            FieldLoader.Load(this, yaml);

            // Support for formats 1-3 dropped 2011-02-11.
            // Use release-20110207 to convert older maps to format 4
            // Use release-20110511 to convert older maps to format 5
            if (MapFormat < 5)
            {
                throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, path));
            }

            // Format 5 -> 6 enforces the use of RequiresMod
            if (MapFormat == 5)
            {
                if (upgradeForMod == null)
                {
                    throw new InvalidDataException("Map format {0} is not supported, but can be upgraded.\n File: {1}".F(MapFormat, path));
                }

                Console.WriteLine("Upgrading {0} from Format 5 to Format 6", path);

                // TODO: This isn't very nice, but there is no other consistent way
                // of finding the mod early during the engine initialization.
                RequiresMod = upgradeForMod;
            }

            var nd = yaml.ToDictionary();

            // Load players
            foreach (var my in nd["Players"].ToDictionary().Values)
            {
                var player = new PlayerReference(my);
                Players.Add(player.Name, player);
            }

            Actors = Exts.Lazy(() =>
            {
                var ret = new Dictionary <string, ActorReference>();
                foreach (var kv in nd["Actors"].ToDictionary())
                {
                    ret.Add(kv.Key, new ActorReference(kv.Value.Value, kv.Value.ToDictionary()));
                }
                return(ret);
            });

            // Smudges
            Smudges = Exts.Lazy(() =>
            {
                var ret = new List <SmudgeReference>();
                foreach (var name in nd["Smudges"].ToDictionary().Keys)
                {
                    var vals = name.Split(' ');
                    var loc  = vals[1].Split(',');
                    ret.Add(new SmudgeReference(vals[0], new int2(
                                                    Exts.ParseIntegerInvariant(loc[0]),
                                                    Exts.ParseIntegerInvariant(loc[1])),
                                                Exts.ParseIntegerInvariant(vals[2])));
                }

                return(ret);
            });

            RuleDefinitions          = MiniYaml.NodesOrEmpty(yaml, "Rules");
            SequenceDefinitions      = MiniYaml.NodesOrEmpty(yaml, "Sequences");
            VoxelSequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "VoxelSequences");
            WeaponDefinitions        = MiniYaml.NodesOrEmpty(yaml, "Weapons");
            VoiceDefinitions         = MiniYaml.NodesOrEmpty(yaml, "Voices");
            NotificationDefinitions  = MiniYaml.NodesOrEmpty(yaml, "Notifications");
            TranslationDefinitions   = MiniYaml.NodesOrEmpty(yaml, "Translations");

            MapTiles     = Exts.Lazy(() => LoadMapTiles());
            MapResources = Exts.Lazy(() => LoadResourceTiles());
            TileShape    = Game.modData.Manifest.TileShape;

            // The Uid is calculated from the data on-disk, so
            // format changes must be flushed to disk.
            // TODO: this isn't very nice
            if (MapFormat < 6)
            {
                Save(path);
            }

            Uid = ComputeHash();

            if (Container.Exists("map.png"))
            {
                CustomPreview = new Bitmap(Container.GetContent("map.png"));
            }

            PostInit();
        }
        public AssetBrowserLogic(Widget widget, Action onExit, World world)
        {
            this.world = world;

            panel       = widget;
            assetSource = GlobalFileSystem.MountedFolders.First();

            var ticker = panel.GetOrNull <LogicTickerWidget>("ANIMATION_TICKER");

            if (ticker != null)
            {
                ticker.OnTick = () =>
                {
                    if (animateFrames)
                    {
                        SelectNextFrame();
                    }
                };
            }

            var sourceDropdown = panel.GetOrNull <DropDownButtonWidget>("SOURCE_SELECTOR");

            if (sourceDropdown != null)
            {
                sourceDropdown.OnMouseDown = _ => ShowSourceDropdown(sourceDropdown);
                sourceDropdown.GetText     = () =>
                {
                    var name = assetSource != null?assetSource.Name.Replace(Platform.SupportDir, "^") : "All Packages";

                    if (name.Length > 15)
                    {
                        name = "..." + name.Substring(name.Length - 15);
                    }

                    return(name);
                };
            }

            var spriteWidget = panel.GetOrNull <SpriteWidget>("SPRITE");

            if (spriteWidget != null)
            {
                spriteWidget.GetSprite  = () => currentSprites != null ? currentSprites[currentFrame] : null;
                currentPalette          = spriteWidget.Palette;
                spriteWidget.GetPalette = () => currentPalette;
            }

            var paletteDropDown = panel.GetOrNull <DropDownButtonWidget>("PALETTE_SELECTOR");

            if (paletteDropDown != null)
            {
                paletteDropDown.OnMouseDown = _ => ShowPaletteDropdown(paletteDropDown, world);
                paletteDropDown.GetText     = () => currentPalette;
            }

            var colorPreview = panel.GetOrNull <ColorPreviewManagerWidget>("COLOR_MANAGER");

            if (colorPreview != null)
            {
                colorPreview.Color = Game.Settings.Player.Color;
            }

            var colorDropdown = panel.GetOrNull <DropDownButtonWidget>("COLOR");

            if (colorDropdown != null)
            {
                colorDropdown.IsDisabled  = () => currentPalette != colorPreview.Palette;
                colorDropdown.OnMouseDown = _ => ShowColorDropDown(colorDropdown, colorPreview, world);
                panel.Get <ColorBlockWidget>("COLORBLOCK").GetColor = () => Game.Settings.Player.Color.RGB;
            }

            filenameInput            = panel.Get <TextFieldWidget>("FILENAME_INPUT");
            filenameInput.OnEnterKey = () => LoadAsset(filenameInput.Text);

            var frameContainer = panel.GetOrNull("FRAME_SELECTOR");

            if (frameContainer != null)
            {
                frameContainer.IsVisible = () => currentSprites != null && currentSprites.Length > 1;
            }

            frameSlider           = panel.Get <SliderWidget>("FRAME_SLIDER");
            frameSlider.OnChange += x => { currentFrame = (int)Math.Round(x); };
            frameSlider.GetValue  = () => currentFrame;

            var frameText = panel.GetOrNull <LabelWidget>("FRAME_COUNT");

            if (frameText != null)
            {
                frameText.GetText = () => "{0} / {1}".F(currentFrame + 1, currentSprites.Length);
            }

            var playButton = panel.GetOrNull <ButtonWidget>("BUTTON_PLAY");

            if (playButton != null)
            {
                playButton.OnClick   = () => animateFrames = true;
                playButton.IsVisible = () => !animateFrames;
            }

            var pauseButton = panel.GetOrNull <ButtonWidget>("BUTTON_PAUSE");

            if (pauseButton != null)
            {
                pauseButton.OnClick   = () => animateFrames = false;
                pauseButton.IsVisible = () => animateFrames;
            }

            var stopButton = panel.GetOrNull <ButtonWidget>("BUTTON_STOP");

            if (stopButton != null)
            {
                stopButton.OnClick = () =>
                {
                    frameSlider.Value = 0;
                    currentFrame      = 0;
                    animateFrames     = false;
                };
            }

            var nextButton = panel.GetOrNull <ButtonWidget>("BUTTON_NEXT");

            if (nextButton != null)
            {
                nextButton.OnClick = SelectNextFrame;
            }

            var prevButton = panel.GetOrNull <ButtonWidget>("BUTTON_PREV");

            if (prevButton != null)
            {
                prevButton.OnClick = SelectPreviousFrame;
            }

            var loadButton = panel.GetOrNull <ButtonWidget>("LOAD_BUTTON");

            if (loadButton != null)
            {
                loadButton.OnClick = () => LoadAsset(filenameInput.Text);
            }

            assetList = panel.Get <ScrollPanelWidget>("ASSET_LIST");
            template  = panel.Get <ScrollItemWidget>("ASSET_TEMPLATE");
            PopulateAssetList();

            var closeButton = panel.GetOrNull <ButtonWidget>("CLOSE_BUTTON");

            if (closeButton != null)
            {
                closeButton.OnClick = () => { Ui.CloseWindow(); onExit(); }
            }
            ;
        }

        void SelectNextFrame()
        {
            currentFrame++;
            if (currentFrame >= currentSprites.Length)
            {
                currentFrame = 0;
            }
        }

        void SelectPreviousFrame()
        {
            currentFrame--;
            if (currentFrame < 0)
            {
                currentFrame = currentSprites.Length - 1;
            }
        }

        void AddAsset(ScrollPanelWidget list, string filepath, ScrollItemWidget template)
        {
            var filename = Path.GetFileName(filepath);
            var item     = ScrollItemWidget.Setup(template,
                                                  () => currentFilename == filename,
                                                  () => { filenameInput.Text = filename; LoadAsset(filename); });

            item.Get <LabelWidget>("TITLE").GetText = () => filepath;

            list.AddChild(item);
        }

        bool LoadAsset(string filename)
        {
            if (string.IsNullOrEmpty(filename))
            {
                return(false);
            }

            if (!GlobalFileSystem.Exists(filename))
            {
                return(false);
            }

            currentFilename          = filename;
            currentSprites           = world.Map.SequenceProvider.SpriteLoader.LoadAllSprites(filename);
            currentFrame             = 0;
            frameSlider.MaximumValue = (float)currentSprites.Length - 1;
            frameSlider.Ticks        = currentSprites.Length;

            return(true);
        }

        bool ShowSourceDropdown(DropDownButtonWidget dropdown)
        {
            Func <IFolder, ScrollItemWidget, ScrollItemWidget> setupItem = (source, itemTemplate) =>
            {
                var item = ScrollItemWidget.Setup(itemTemplate,
                                                  () => assetSource == source,
                                                  () => { assetSource = source; PopulateAssetList(); });
                item.Get <LabelWidget>("LABEL").GetText = () => source != null?source.Name.Replace(Platform.SupportDir, "^") : "All Packages";

                return(item);
            };

            // TODO: Re-enable "All Packages" once list generation is done in a background thread
            // var sources = new[] { (IFolder)null }.Concat(GlobalFileSystem.MountedFolders);

            var sources = GlobalFileSystem.MountedFolders;

            dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 280, sources, setupItem);
            return(true);
        }

        void PopulateAssetList()
        {
            assetList.RemoveChildren();
            availableShps.Clear();

            // TODO: This is too slow to run in the main thread
            // var files = AssetSource != null ? AssetSource.AllFileNames() :
            // GlobalFileSystem.MountedFolders.SelectMany(f => f.AllFileNames());

            if (assetSource == null)
            {
                return;
            }

            var files = assetSource.AllFileNames().OrderBy(s => s);

            foreach (var file in files)
            {
                if (AllowedExtensions.Any(ext => file.EndsWith(ext, true, CultureInfo.InvariantCulture)))
                {
                    AddAsset(assetList, file, template);
                    availableShps.Add(file);
                }
            }
        }

        bool ShowPaletteDropdown(DropDownButtonWidget dropdown, World world)
        {
            Func <PaletteFromFile, ScrollItemWidget, ScrollItemWidget> setupItem = (palette, itemTemplate) =>
            {
                var name = palette.Name;
                var item = ScrollItemWidget.Setup(itemTemplate,
                                                  () => currentPalette == name,
                                                  () => currentPalette = name);
                item.Get <LabelWidget>("LABEL").GetText = () => name;

                return(item);
            };

            var palettes = world.WorldActor.TraitsImplementing <PaletteFromFile>();

            dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 280, palettes, setupItem);
            return(true);
        }