From 881fcf11913c9418ac1fbe33be7a3b8f3142da6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Wed, 15 May 2013 18:13:33 +0200 Subject: [PATCH 01/11] added in-game SHP viewer with frame slider --- OpenRA.FileFormats/Filesystem/FileSystem.cs | 38 ++-- OpenRA.Game/Graphics/SpriteLoader.cs | 4 +- OpenRA.Game/Widgets/ShpImageWidget.cs | 34 ++- OpenRA.Game/Widgets/SliderWidget.cs | 12 +- OpenRA.Mods.RA/OpenRA.Mods.RA.csproj | 1 + .../Widgets/Logic/AssetBrowserLogic.cs | 124 +++++++++++ .../Widgets/Logic/MainMenuButtonsLogic.cs | 12 +- mods/ra/chrome/assetbrowser.yaml | 196 ++++++++++++++++++ mods/ra/chrome/mainmenu.yaml | 11 +- mods/ra/mod.yaml | 1 + 10 files changed, 408 insertions(+), 25 deletions(-) create mode 100644 OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs create mode 100644 mods/ra/chrome/assetbrowser.yaml diff --git a/OpenRA.FileFormats/Filesystem/FileSystem.cs b/OpenRA.FileFormats/Filesystem/FileSystem.cs index 396b719763..c2e1004c45 100644 --- a/OpenRA.FileFormats/Filesystem/FileSystem.cs +++ b/OpenRA.FileFormats/Filesystem/FileSystem.cs @@ -18,19 +18,21 @@ namespace OpenRA.FileFormats { public static class FileSystem { - static List mountedFolders = new List(); + static List MountedFolders = new List(); static Cache> allFiles = new Cache>( _ => new List() ); + public static List FolderPaths = new List(); + static void MountInner(IFolder folder) { - mountedFolders.Add(folder); + MountedFolders.Add(folder); - foreach( var hash in folder.AllFileHashes() ) + foreach (var hash in folder.AllFileHashes()) { var l = allFiles[hash]; - if( !l.Contains( folder ) ) - l.Add( folder ); + if (!l.Contains(folder)) + l.Add(folder); } } @@ -78,6 +80,9 @@ namespace OpenRA.FileFormats if (name.StartsWith("^")) name = Platform.SupportDir+name.Substring(1); + if (Directory.Exists(name)) + FolderPaths.Add(name); + var a = (Action)(() => FileSystem.MountInner(OpenPackage(name))); if (optional) @@ -89,28 +94,29 @@ namespace OpenRA.FileFormats public static void UnmountAll() { - mountedFolders.Clear(); + MountedFolders.Clear(); + FolderPaths.Clear(); allFiles = new Cache>( _ => new List() ); } public static bool Unmount(IFolder mount) { - return (mountedFolders.RemoveAll(f => f == mount) > 0); + return (MountedFolders.RemoveAll(f => f == mount) > 0); } public static void Mount(IFolder mount) { - if (!mountedFolders.Contains(mount)) mountedFolders.Add(mount); + if (!MountedFolders.Contains(mount)) MountedFolders.Add(mount); } - public static void LoadFromManifest( Manifest manifest ) + public static void LoadFromManifest(Manifest manifest) { UnmountAll(); foreach (var dir in manifest.Folders) Mount(dir); foreach (var pkg in manifest.Packages) Mount(pkg); } - static Stream GetFromCache( Cache> index, string filename ) + static Stream GetFromCache(Cache> index, string filename) { var folder = index[PackageEntry.HashFilename(filename)] .Where(x => x.Exists(filename)) @@ -125,21 +131,21 @@ namespace OpenRA.FileFormats public static Stream Open(string filename) { return OpenWithExts(filename, ""); } - public static Stream OpenWithExts( string filename, params string[] exts ) + public static Stream OpenWithExts(string filename, params string[] exts) { if( filename.IndexOfAny( new char[] { '/', '\\' } ) == -1 ) { foreach( var ext in exts ) { - var s = GetFromCache( allFiles, filename + ext ); - if( s != null ) + var s = GetFromCache(allFiles, filename + ext); + if (s != null) return s; } } - foreach( var ext in exts ) + foreach (var ext in exts) { - var folder = mountedFolders + var folder = MountedFolders .Where(x => x.Exists(filename + ext)) .OrderByDescending(x => x.Priority) .FirstOrDefault(); @@ -151,7 +157,7 @@ namespace OpenRA.FileFormats throw new FileNotFoundException("File not found: {0}".F(filename), filename); } - public static bool Exists(string filename) { return mountedFolders.Any(f => f.Exists(filename)); } + public static bool Exists(string filename) { return MountedFolders.Any(f => f.Exists(filename)); } static Dictionary assemblyCache = new Dictionary(); diff --git a/OpenRA.Game/Graphics/SpriteLoader.cs b/OpenRA.Game/Graphics/SpriteLoader.cs index 97134fc646..ca6e7f49b9 100644 --- a/OpenRA.Game/Graphics/SpriteLoader.cs +++ b/OpenRA.Game/Graphics/SpriteLoader.cs @@ -16,11 +16,11 @@ namespace OpenRA.Graphics { public class SpriteLoader { - public SpriteLoader( string[] exts, SheetBuilder sheetBuilder ) + public SpriteLoader(string[] exts, SheetBuilder sheetBuilder) { SheetBuilder = sheetBuilder; this.exts = exts; - sprites = new Cache( LoadSprites ); + sprites = new Cache(LoadSprites); } readonly SheetBuilder SheetBuilder; diff --git a/OpenRA.Game/Widgets/ShpImageWidget.cs b/OpenRA.Game/Widgets/ShpImageWidget.cs index 88388f1aca..7198598ccb 100644 --- a/OpenRA.Game/Widgets/ShpImageWidget.cs +++ b/OpenRA.Game/Widgets/ShpImageWidget.cs @@ -18,6 +18,7 @@ namespace OpenRA.Widgets public string Image = ""; public int Frame = 0; public string Palette = "chrome"; + public bool LoopAnimation = false; public Func GetImage; public Func GetFrame; @@ -26,12 +27,13 @@ namespace OpenRA.Widgets readonly WorldRenderer worldRenderer; [ObjectCreator.UseCtor] - public ShpImageWidget( WorldRenderer worldRenderer) + public ShpImageWidget(WorldRenderer worldRenderer) : base() { GetImage = () => { return Image; }; GetFrame = () => { return Frame; }; GetPalette = () => { return Palette; }; + this.worldRenderer = worldRenderer; } @@ -41,9 +43,12 @@ namespace OpenRA.Widgets Image = other.Image; Frame = other.Frame; Palette = other.Palette; + LoopAnimation = other.LoopAnimation; + GetImage = other.GetImage; GetFrame = other.GetFrame; GetPalette = other.GetPalette; + worldRenderer = other.worldRenderer; } @@ -68,5 +73,32 @@ namespace OpenRA.Widgets Game.Renderer.SpriteRenderer.DrawSprite(sprite, RenderOrigin, worldRenderer, palette); } + + public int FrameCount + { + get { return Game.modData.SpriteLoader.LoadAllSprites(Image).Length-1; } + } + + public void RenderNextFrame() + { + if (Frame < FrameCount) + Frame++; + else + Frame = 0; + } + + public void RenderPreviousFrame() + { + if (Frame > 0) + Frame--; + else + Frame = FrameCount; + } + + public override void Tick() + { + if (LoopAnimation) + RenderNextFrame(); + } } } diff --git a/OpenRA.Game/Widgets/SliderWidget.cs b/OpenRA.Game/Widgets/SliderWidget.cs index 545cfd161f..d172914f8f 100755 --- a/OpenRA.Game/Widgets/SliderWidget.cs +++ b/OpenRA.Game/Widgets/SliderWidget.cs @@ -24,10 +24,15 @@ namespace OpenRA.Widgets public float MinimumValue = 0; public float MaximumValue = 1; public float Value = 0; + public Func GetValue; protected bool isMoving = false; - public SliderWidget() : base() {} + public SliderWidget() + : base() + { + GetValue = () => Value; + } public SliderWidget(SliderWidget other) : base(other) @@ -38,6 +43,7 @@ namespace OpenRA.Widgets MaximumValue = other.MaximumValue; Value = other.Value; TrackHeight = other.TrackHeight; + GetValue = other.GetValue; } void UpdateValue(float newValue) @@ -53,7 +59,7 @@ namespace OpenRA.Widgets if (mi.Event == MouseInputEvent.Down && !TakeFocus(mi)) return false; if (!Focused) return false; - switch( mi.Event ) + switch(mi.Event) { case MouseInputEvent.Up: isMoving = false; @@ -99,6 +105,8 @@ namespace OpenRA.Widgets if (!IsVisible()) return; + Value = GetValue(); + var tr = ThumbRect; var rb = RenderBounds; var trackWidth = rb.Width; diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index f1ef383574..9bcf55ea19 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -436,6 +436,7 @@ + diff --git a/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs new file mode 100644 index 0000000000..7bd85985b2 --- /dev/null +++ b/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs @@ -0,0 +1,124 @@ +#region Copyright & License Information +/* + * Copyright 2007-2013 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.IO; +using System.Linq; +using OpenRA.FileFormats; +using OpenRA.GameRules; +using OpenRA.Graphics; +using OpenRA.Widgets; + +namespace OpenRA.Mods.RA.Widgets.Logic +{ + public class AssetBrowserLogic + { + Widget panel; + + ShpImageWidget spriteImage; + TextFieldWidget filenameInput; + SliderWidget frameSlider; + ButtonWidget playButton; + ButtonWidget pauseButton; + + [ObjectCreator.UseCtor] + public AssetBrowserLogic(Widget widget, Action onExit, World world) + { + panel = widget; + + spriteImage = panel.Get("SPRITE"); + + filenameInput = panel.Get("FILENAME_INPUT"); + filenameInput.Text = spriteImage.Image; + filenameInput.OnEnterKey = () => LoadAsset(filenameInput.Text); + + var assetList = panel.Get("ASSET_LIST"); + var template = panel.Get("ASSET_TEMPLATE"); + + assetList.RemoveChildren(); + foreach (var folder in FileSystem.FolderPaths) + { + if (Directory.Exists(folder)) + { + var shps = Directory.GetFiles(folder, "*.shp"); + foreach (var shp in shps) + AddAsset(assetList, shp, template); + } + } + + frameSlider = panel.Get("FRAME_SLIDER"); + frameSlider.MaximumValue = (float)spriteImage.FrameCount; + frameSlider.Ticks = spriteImage.FrameCount+1; + frameSlider.OnChange += x => { spriteImage.Frame = (int)Math.Round(x); }; + frameSlider.GetValue = () => spriteImage.Frame; + + panel.Get("FRAME_COUNT").GetText = () => spriteImage.Frame.ToString(); + + playButton = panel.Get("BUTTON_PLAY"); + playButton.OnClick = () => + { + spriteImage.LoopAnimation = true; + playButton.Visible = false; + pauseButton.Visible = true; + }; + pauseButton = panel.Get("BUTTON_PAUSE"); + pauseButton.OnClick = () => + { + spriteImage.LoopAnimation = false; + playButton.Visible = true; + pauseButton.Visible = false; + }; + + panel.Get("BUTTON_STOP").OnClick = () => + { + spriteImage.LoopAnimation = false; + frameSlider.Value = 0; + spriteImage.Frame = 0; + playButton.Visible = true; + pauseButton.Visible = false; + }; + + panel.Get("BUTTON_NEXT").OnClick = () => { spriteImage.RenderNextFrame(); }; + panel.Get("BUTTON_PREV").OnClick = () => { spriteImage.RenderPreviousFrame(); }; + + panel.Get("LOAD_BUTTON").OnClick = () => + { + LoadAsset(filenameInput.Text); + }; + + panel.Get("CLOSE_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); }; + } + + void AddAsset(ScrollPanelWidget list, string filepath, ScrollItemWidget template) + { + var sprite = Path.GetFileNameWithoutExtension(filepath); + + var item = ScrollItemWidget.Setup(template, + () => spriteImage != null && spriteImage.Image == sprite, + () => LoadAsset(sprite)); + item.Get("TITLE").GetText = () => sprite; + + list.AddChild(item); + } + + bool LoadAsset(string filename) + { + if (filename == null) + return false; + + filenameInput.Text = filename; + spriteImage.Frame = 0; + spriteImage.Image = filename; + frameSlider.MaximumValue = (float)spriteImage.FrameCount; + frameSlider.Ticks = spriteImage.FrameCount+1; + return true; + } + } +} diff --git a/OpenRA.Mods.RA/Widgets/Logic/MainMenuButtonsLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/MainMenuButtonsLogic.cs index 46f713596b..2ad69c8871 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/MainMenuButtonsLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/MainMenuButtonsLogic.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2013 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -14,7 +14,6 @@ namespace OpenRA.Mods.RA.Widgets.Logic { public class MainMenuButtonsLogic { - enum MenuType { Main, None } MenuType Menu = MenuType.Main; @@ -73,6 +72,15 @@ namespace OpenRA.Mods.RA.Widgets.Logic }); }; + widget.Get("MAINMENU_BUTTON_ASSET_BROWSER").OnClick = () => + { + Menu = MenuType.None; + Game.OpenWindow("ASSETBROWSER_BG", new WidgetArgs() + { + { "onExit", () => Menu = MenuType.Main } + }); + }; + widget.Get("MAINMENU_BUTTON_QUIT").OnClick = () => Game.Exit(); } diff --git a/mods/ra/chrome/assetbrowser.yaml b/mods/ra/chrome/assetbrowser.yaml new file mode 100644 index 0000000000..21c62fbbd6 --- /dev/null +++ b/mods/ra/chrome/assetbrowser.yaml @@ -0,0 +1,196 @@ +Background@ASSETBROWSER_BG: + Logic:AssetBrowserLogic + X:(WINDOW_RIGHT - WIDTH)/2 + Y:(WINDOW_BOTTOM - HEIGHT)/2 + Width:700 + Height:410 + Children: + Label@ASSETBROWSER_TITLE: + X:0 + Y:20 + Width:PARENT_RIGHT + Height:25 + Text:Game Asset Viewer & Converter + Align:Center + Font:Bold + DropDownButton@SOURCE_SELECTOR: + X:40 + Y:45 + Width:160 + Height:25 + Font:Bold + Text:Folders + ScrollPanel@ASSET_LIST: + X:40 + Y:80 + Width:160 + Height:190 + Children: + ScrollItem@ASSET_TEMPLATE: + Width:PARENT_RIGHT-27 + Height:25 + X:2 + Y:0 + Visible:false + Children: + Label@TITLE: + X:10 + Width:PARENT_RIGHT-20 + Height:25 + TextField@FILENAME_INPUT: + X:40 + Y:280 + Width:140 + Height:25 + Button@LOAD_BUTTON: + X:40 + Y:310 + Width:140 + Height:25 + Text:Load + Font:Bold + Key:return + Label@PREVIEW_TITLE: + X:320 + Y:45 + Width:PARENT_RIGHT + Height:25 + Text:Preview + Background@SPRITE_BG: + X:220 + Y:80 + Width:250 + Height:250 + Background:dialog3 + Children: + ShpImage@SPRITE: + X:80 + Y:80 + Width:246 + Height:246 + Image:fact + Palette:player + Label@ACTIONS_TITLE: + X:PARENT_RIGHT - 150 + Y:45 + Width:PARENT_RIGHT + Height:25 + Text:Actions + Button@REMAP_BUTTON: + X:PARENT_RIGHT - 200 + Y:PARENT_BOTTOM - 305 + Width:160 + Height:25 + Text:Change Palette + Font:Bold + Button@IMPORT_BUTTON: + X:PARENT_RIGHT - 200 + Y:PARENT_BOTTOM - 270 + Width:160 + Height:25 + Text:Import from PNG + Font:Bold + Button@EXTRACT_BUTTON: + X:PARENT_RIGHT - 200 + Y:PARENT_BOTTOM - 235 + Width:160 + Height:25 + Text:Extract to Folder + Font:Bold + Button@EXPORT_BUTTON: + X:PARENT_RIGHT - 200 + Y:PARENT_BOTTOM - 200 + Width:160 + Height:25 + Text:Export as PNG + Font:Bold + Button@CLOSE_BUTTON: + X:PARENT_RIGHT - 200 + Y:PARENT_BOTTOM - 115 + Width:160 + Height:25 + Text:Close + Font:Bold + Key:escape + Container@FRAME_SELECTOR: + X:45 + Y:360 + Children: + Button@BUTTON_PREV: + X:0 + Y:0 + Width:25 + Height:25 + Children: + Image@IMAGE_PREV: + X:0 + Y:0 + Width:25 + Height:25 + ImageCollection:music + ImageName:prev + Button@BUTTON_PLAY: + X:35 + Y:0 + Width:25 + Height:25 + Children: + Image@IMAGE_PLAY: + X:0 + Y:0 + Width:25 + Height:25 + ImageCollection:music + ImageName:play + Button@BUTTON_PAUSE: + Visible: no + X:35 + Y:0 + Width:25 + Height:25 + Children: + Image@IMAGE_PAUSE: + X:0 + Y:0 + Width:25 + Height:25 + ImageCollection:music + ImageName:pause + Button@BUTTON_STOP: + X:70 + Y:0 + Width:25 + Height:25 + Children: + Image@IMAGE_STOP: + X:0 + Y:0 + Width:25 + Height:25 + ImageCollection:music + ImageName:stop + Button@BUTTON_NEXT: + X:105 + Y:0 + Width:25 + Height:25 + Children: + Image@IMAGE_NEXT: + X:0 + Y:0 + Width:25 + Height:25 + ImageCollection:music + ImageName:next + Slider@FRAME_SLIDER: + X:175 + Y:0 + Width:410 + Height:20 + MinimumValue: 0 + Label@FRAME_COUNT: + X:610 + Y:0 + Width:25 + Height:25 + Font:Bold \ No newline at end of file diff --git a/mods/ra/chrome/mainmenu.yaml b/mods/ra/chrome/mainmenu.yaml index 08b9df2ef7..caac30da30 100644 --- a/mods/ra/chrome/mainmenu.yaml +++ b/mods/ra/chrome/mainmenu.yaml @@ -23,7 +23,7 @@ Container@MAINMENU: X:(WINDOW_RIGHT - WIDTH)/8 Y:(WINDOW_BOTTOM - HEIGHT)/2 Width:250 - Height:505 + Height:555 Logic:MainMenuButtonsLogic Children: Label@MAINMENU_LABEL_TITLE: @@ -83,11 +83,18 @@ Container@MAINMENU: Height:35 Text:Replay Viewer Font:Bold - Button@MAINMENU_BUTTON_QUIT: + Button@MAINMENU_BUTTON_ASSET_BROWSER: X:45 Y:430 Width:160 Height:35 + Text:Asset Browser + Font:Bold + Button@MAINMENU_BUTTON_QUIT: + X:45 + Y:480 + Width:160 + Height:35 Text:Quit Font:Bold Background@PERF_BG: diff --git a/mods/ra/mod.yaml b/mods/ra/mod.yaml index 9be827a088..f7137f7323 100644 --- a/mods/ra/mod.yaml +++ b/mods/ra/mod.yaml @@ -73,6 +73,7 @@ ChromeLayout: mods/ra/chrome/cheats.yaml mods/ra/chrome/musicplayer.yaml mods/ra/chrome/tooltips.yaml + mods/ra/chrome/assetbrowser.yaml Weapons: mods/ra/weapons.yaml From 3ae61c5f8c91e67a8386e4c8b212220ec0e83858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Sat, 27 Apr 2013 15:37:52 +0200 Subject: [PATCH 02/11] added the game asset viewer to d2k mod --- OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs | 12 ++++++------ mods/d2k/chrome/mainmenu.yaml | 11 +++++++++-- mods/d2k/mod.yaml | 2 ++ mods/ra/chrome/assetbrowser.yaml | 4 ++-- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs index 7bd85985b2..60154c5f2d 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs @@ -33,12 +33,6 @@ namespace OpenRA.Mods.RA.Widgets.Logic { panel = widget; - spriteImage = panel.Get("SPRITE"); - - filenameInput = panel.Get("FILENAME_INPUT"); - filenameInput.Text = spriteImage.Image; - filenameInput.OnEnterKey = () => LoadAsset(filenameInput.Text); - var assetList = panel.Get("ASSET_LIST"); var template = panel.Get("ASSET_TEMPLATE"); @@ -53,6 +47,12 @@ namespace OpenRA.Mods.RA.Widgets.Logic } } + spriteImage = panel.Get("SPRITE"); + + filenameInput = panel.Get("FILENAME_INPUT"); + filenameInput.Text = spriteImage.Image; + filenameInput.OnEnterKey = () => LoadAsset(filenameInput.Text); + frameSlider = panel.Get("FRAME_SLIDER"); frameSlider.MaximumValue = (float)spriteImage.FrameCount; frameSlider.Ticks = spriteImage.FrameCount+1; diff --git a/mods/d2k/chrome/mainmenu.yaml b/mods/d2k/chrome/mainmenu.yaml index 2e762ef458..c9092ef014 100644 --- a/mods/d2k/chrome/mainmenu.yaml +++ b/mods/d2k/chrome/mainmenu.yaml @@ -2,7 +2,7 @@ Background@MAINMENU: X:(WINDOW_RIGHT - WIDTH)/2 Y:(WINDOW_BOTTOM - HEIGHT)/2 Width:250 - Height:420 + Height:460 Visible:true Logic:MainMenuButtonsLogic Children: @@ -63,11 +63,18 @@ Background@MAINMENU: Height:25 Text:Replay Viewer Font:Bold - Button@MAINMENU_BUTTON_QUIT: + Button@MAINMENU_BUTTON_ASSET_BROWSER: X:45 Y:350 Width:160 Height:25 + Text:Asset Browser + Font:Bold + Button@MAINMENU_BUTTON_QUIT: + X:45 + Y:390 + Width:160 + Height:25 Text:Quit Font:Bold Background@PERF_BG: diff --git a/mods/d2k/mod.yaml b/mods/d2k/mod.yaml index 6c759fa3b1..de3390ecfb 100644 --- a/mods/d2k/mod.yaml +++ b/mods/d2k/mod.yaml @@ -66,6 +66,8 @@ ChromeLayout: mods/ra/chrome/cheats.yaml mods/ra/chrome/musicplayer.yaml mods/d2k/chrome/tooltips.yaml + mods/ra/chrome/assetbrowser.yaml + Weapons: mods/d2k/weapons/defaults.yaml mods/d2k/weapons/explosions.yaml diff --git a/mods/ra/chrome/assetbrowser.yaml b/mods/ra/chrome/assetbrowser.yaml index 21c62fbbd6..cd07b7bc53 100644 --- a/mods/ra/chrome/assetbrowser.yaml +++ b/mods/ra/chrome/assetbrowser.yaml @@ -68,8 +68,8 @@ Background@ASSETBROWSER_BG: Y:80 Width:246 Height:246 - Image:fact - Palette:player + Image:mouse + Palette:colorpicker Label@ACTIONS_TITLE: X:PARENT_RIGHT - 150 Y:45 From 4a1ebb69c3acdd887ab070368245f26512057e54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Sat, 27 Apr 2013 16:53:44 +0200 Subject: [PATCH 03/11] remove duplicate ra-desert bridge tiles --- mods/ra/bits/desert/br1a.shp | Bin 2510 -> 0 bytes mods/ra/bits/desert/br1b.shp | Bin 3409 -> 0 bytes mods/ra/bits/desert/br1c.shp | Bin 3083 -> 0 bytes mods/ra/bits/desert/br1x.shp | Bin 3600 -> 0 bytes mods/ra/bits/desert/br2a.shp | Bin 2292 -> 0 bytes mods/ra/bits/desert/br2b.shp | Bin 3070 -> 0 bytes mods/ra/bits/desert/br2c.shp | Bin 1715 -> 0 bytes mods/ra/bits/desert/br2x.shp | Bin 3927 -> 0 bytes mods/ra/bits/desert/br3a.shp | Bin 2107 -> 0 bytes mods/ra/bits/desert/br3b.shp | Bin 2677 -> 0 bytes mods/ra/bits/desert/br3c.shp | Bin 2612 -> 0 bytes mods/ra/bits/desert/br3d.shp | Bin 2269 -> 0 bytes mods/ra/bits/desert/br3e.shp | Bin 1270 -> 0 bytes mods/ra/bits/desert/br3f.shp | Bin 926 -> 0 bytes 14 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 mods/ra/bits/desert/br1a.shp delete mode 100644 mods/ra/bits/desert/br1b.shp delete mode 100644 mods/ra/bits/desert/br1c.shp delete mode 100644 mods/ra/bits/desert/br1x.shp delete mode 100644 mods/ra/bits/desert/br2a.shp delete mode 100644 mods/ra/bits/desert/br2b.shp delete mode 100644 mods/ra/bits/desert/br2c.shp delete mode 100644 mods/ra/bits/desert/br2x.shp delete mode 100644 mods/ra/bits/desert/br3a.shp delete mode 100644 mods/ra/bits/desert/br3b.shp delete mode 100644 mods/ra/bits/desert/br3c.shp delete mode 100644 mods/ra/bits/desert/br3d.shp delete mode 100644 mods/ra/bits/desert/br3e.shp delete mode 100644 mods/ra/bits/desert/br3f.shp diff --git a/mods/ra/bits/desert/br1a.shp b/mods/ra/bits/desert/br1a.shp deleted file mode 100644 index 5b051ad06771f3c55212aa1e62528f7d97cc425d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2510 zcmX|Ce{2+09{;}C{$fk%>=uz)+Uu4UyeL0vIH0SY+ELg&r|V32XJ}{E?QYr9gkDi_ zyR+pEl{Y)Hr4aG7iG}VTT-2E35*wjP$emPl3c=fgfKU+3*-b8mhKmtzX^mbt_tr~p z{+M|)`Fy_bGoR1*y@w!og<$?W7rtnr2K@qox{*MN?7LjH;?x zbMnN=G1n<3&ASD+An_iK=Xhm7ktA6Nl^hoM9#LHIwT0UxPP~$}fG>VT7NGFZ72gp_ z7G+TsWLQtWt6D6U%>xt1Xc;Ux2G*h2*ol)T-0o9p4=)IAkKj=_ps)n%;tD72E+Hhz z5P08PJy3U0XcK(lHs4O!2ki#W3!(%?hU9X&Q!omj5@^hbs?nGUC2$#nuaCLiuC&L^ z3vP+$LxSd)>97zOxT45BpY4IMg9~kAG8NC`E4r(C0_FTWl0gx zVNDcKnJ#7}4(ec5F6*jk-tT7ohZjhx2E*Nqm+*58Jh2 z1-Ysd@D0>yvfP|cCQvjoF7#{LX-R?U%s^q zKL>&JGCiTG>g^3^K$hg66}}zq)&zmxYh)!}mf#u`qj$-_`{k@{b!(TFVbK0+nR+L# zMpHM25FEuk{6zHAr)U#ii)V@R7i_y7S8Y1p z@Jb>p^Fdj*Rn}j1=y>55bW?_9YgeF^Wd&ciQktXy3-4nQS_V0h6We*23(}|U^%}9! z0t$M74(C_~+sH7DOJjCMGfdmQ8)KwLQ5kI2csEL+uh47o3iWurh39E|tBzKCodfd> z!@72v8@{F3+ocxVo6QHw;)VA#u^lM17rVhhV(YWjHS3y3ZZ!uQ*-SIT^rBa4zrv;v zgK;c_7rIg>5&RkV+HMg!Ld{*vi&&zLLwhcm&eg5vfjJj5H^(%+V0Y@#s2LMt8s|n+ zRQ1JDiatg-GFlC{>xbZZEKna|g}zR;I0$c$Wtlk_%d~}UE2t!4c|5R|vclV`Jyb&B zgZzIMfW>_ExTt~^^5VS2S(d}AttMvCJ_yIRdc!;3e8Q=@J*^*3UZ$`gJ|;0mpyG+U zsg+cjLzBf;(_mce+&pZL4~M&IE4Djz4=1>rKfJi!V#}+JZ0McTDBCRN(dP~`o_4vY zkpwfxh~e%p)+3?^jl!Uz_*-AUGhW^)P}+4*MpEWx#fyTe_5eMB&9G-O#+{FaS$QOcVqM7A=M z?^v*6yX`QkVLVT)We517a94LYe4(I#Y(yTk1@1XKmp&w_;o}XxDJl&&C6jXJX_axwq=#1U_M_pWy88LcCjE7Sev zui1*4b0D5)om%?GrPmI) z*oMAH)N~Y#4jMBvfk4ohF>(dN$5Q=8dk#PPiPwqKs0zCZFB_ZBMWeICVDq418WZO1 zy?a6P#@R(zt`J~e1NLki#f{XHn1!`bb-3sAj{( zx*i-aUbV<$Ow1;e20k6t;N7E#teVVi+oWaY;BV+P-9?ro`bW{agKBJM zXL2UFb2fA%TZ}#V+?EU$_UOBuHHD6U1hOC%a zj5Brr8er4?KlHO~{!jSMBQGs^OpB>V(?iLSF?DRo!*^G`1bn3rD~m4dCJF1A%v^KP zARUAd`X|0qSwzG{Yu>{Ke0Jm5lJarvc_@SWDn{zd!TQ_xsd`kgY!p>OC)K38)WGB; z7pZr#xn>!1T$X zl|8R3K}oDHr>$b2*4SM1SfXiDBvKNA7JVi#5m@rr$`DQ!{~Jf)^U6q0SOL?fA&15X z9p%efw~ZcZW*;;&P4~|?oV!ykt(`{w=v%OmIb%&Hr>1FJRju|bX&IOAEE(v(OZ}8+ z`hKJ#60om@5MH_T4=Z?j2lz`*#8WYKs+wK_wOU+uy9-NEdEBoAe^*0?4m|1Hcz*Lp f$3*EfaZ`Q4;?+%c;tqWpcHr3A$5GW$9NYh2vALc^ diff --git a/mods/ra/bits/desert/br1b.shp b/mods/ra/bits/desert/br1b.shp deleted file mode 100644 index 19e97f6b3d03aeb3723a4ac8b3286b419842ba24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3409 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 diff --git a/mods/ra/bits/desert/br1x.shp b/mods/ra/bits/desert/br1x.shp deleted file mode 100644 index 184593b0fcaf3dc5199cb517e5113038e15d79ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3600 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 F{{b=7b(#PG diff --git a/mods/ra/bits/desert/br2a.shp b/mods/ra/bits/desert/br2a.shp deleted file mode 100644 index 30db9909bcb1bccef600f6c0b06cadc2a1265658..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2292 zcmX|CYj6|S6+U-YvgH@-N;W2d9Y4TLLmq}9HkRwf7GSBfR_|hKUGG&C@klzMbtfe9 zuAIOCcUO{4NaE>ZA|BH;4W%>5v`m5-Hyu*rWNm^GI02FjX(ws)2byWIA#qHbU`?<2 z(Ve-w_srbyoc+G@xCj=Wtx$jWTL-XzVKeKxYySWBTU*y{J8l@dZN%exMmKETFzlM) zw@wZR0{(1{2Qnb%R87N#?d1ef3CS^^%&^UPJm&zL#sv*{8izu*qN%t1l0O@So|jaW zXhc!uAPxpGo@Ss3oME{5pl;}K+py#CVRCr*@VSzuvJ{1vh|E% zoJ4yD{UcH~Aj`NaViH`PfcIx!0xKRpDvX%%I>I_DupOluZ^?Lryghnmxb5y3{!(H!iuh$;)QnVam0 z`!H494U8YE16OjMgh+_{eIlpfs1lnIoSj}X5QJ7!(_l;4kib8WgCRN8gEct{o&h%Oq)du$2KUX>N|iloHukY@)o(ipMitOWlbO%h{SrQ&yd;sRI0D zZJr=+YtHwg<^|C6l5|^Y@nw(1O7btdZj@hXKe4G#9fC;Sk1x=??(<@^_`y#dN!R^}&KJ zS`F{AI_KAAkZK;n{I;h(sWb`Wjyv!qYnz=5XrT}|)-+jEdC>1`k=9S>`j@s1_Og!? zwr%LkKU$Yb;ZTpNgwIEc*8HR4sRa-ea)(*OmaH`AgE7Xj>9LyXdvY!?EZtVu^-%1X zG&Nih%5W~Osr{+8HMGMky5jZ9GulUijOEiv-Q(SaFtf2&6smMF` zgsY~h?kUd%4STrOLjIxd#swkiEZ3Iw`~2U$4(bD&TiF!1xdP@dj4EhoiA>Y5kqx5u zvL7zn!+M~zY?EVW%K(!`lS6&x>>Qj%`x1V?PePvyr^RJeE>pMB9|n5Uvihi^6&-MW zoge`@z4YbK6mV2=Ot9I+-Qd#h=Bh$ULVfNd3BQ!>uX)wcpNvl%#E%RQw!a_7Eq_aixI%bayw81{ z+WcSO4Q`c{4t0s;W*{x5_=}HE)&5b)pG*}$-sc%P=*#wh)$e19N!QC7R&*_|FDbF? zcxd%NDxFr;t}e9K3Z&C$rRU%|35xc6P39?l!8hzUuFH?6v&Tbx)Yd zs0(L3JU?d1IK`~=AnED~g)r%5Qyyc_#n9A4Esp!oZ!CGn%gQX8=x4FH4GF&yxgdnN zV=HTfVw!e{pbmB^;T}~E1YoCgDgRw)YSk~++_!zRaia9oWcKX(##^i^{E}UB;lUDt ztFp(~&HarqN_*g_nZ^zg-78jBjXK8RPtL;`SoD(<(3Na^x#?^Z`>7)X6D7X!$oRF+ zMp{==;>kl_BzpsdgwO@r%WEH;DMBB^dy`uk>R?NoblbO~F%~O{K}YIZWIUqlONK2Y zo+gHy-HoV81;*v!p`Cm z@d5KFL6?BDc)}AF zmYQD%;BDILSSl7yeO|oMT)^B-`-`*L+%JE+W1Fu%c;vD1cL5T{qvO>OF~_e9Z^IL= LW>h=&1={~VSWGqm diff --git a/mods/ra/bits/desert/br2b.shp b/mods/ra/bits/desert/br2b.shp deleted file mode 100644 index 3ed2328f64f8521c9478d728d8be468027f30712..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3070 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 Db<+5J diff --git a/mods/ra/bits/desert/br2c.shp b/mods/ra/bits/desert/br2c.shp deleted file mode 100644 index 1261082a6b9b400ef8f94bf38c9c6957e3631bea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1715 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 diff --git a/mods/ra/bits/desert/br3a.shp b/mods/ra/bits/desert/br3a.shp deleted file mode 100644 index 602c08222491fedf499ca342956028df2009ff86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2107 zcmX|Be{2)y8GgUBogYq2&iMfZXt0xzK|@8LA|dW_#NOaeySU$x_@dmI;EVwi8WY*< zvoqEezPodhHH>MRR723{)~$bZnkXe*hDHgrm!w(JY7|zd{LxZNQ&2aNkk*8)Bi_F7 z$4>h0zE66e_qpeL-{(cJ^7KH%lW!fssg=!h1y7Fuf4yQQG|NiFb>e4$l7^yvNxqtYTP}1~HBVjd+PWerD9l`S@jA3b-w~Bq+J=E?a0<+b`YEVTV`%QW)cwrR- z-3ijkviNl{k@mL3a16Ys*Nycb{4UuIw!hA(!DArYRzLzQAfNIL}+I@pTEJ;F83Zjq8 z%Tbm46B1-z)#dQ~16%nA4*~Q^1md{@U6NGAO0LAz{?N(96``Wdc-)$ow1K zGDJy4Cv>c$%}G&JBpo8XKakm z&@}5%Ocw=|CW>PR`cTKq=#ykn4Cgvam(d*37aDBU=i7bdx8a8SMZGOo>p@;vH7Kb# zf*&u-^KaPq{G#1g_9uF4_NbvQFT-T@GK?7#Ex>((A-d3z2M4G2F}fr;PDAH_`X3c{ zsZyR&%9EV?q%P+my4dSDa*+h>@7jLfuZG*?oWhQ>7CJ$4&}*o&$VOKh%+M0F1f}PQ zRN6=tqB-46jwxgVm44Fb;JA1HD9Oh*n(8 z2>_N?KMM57aHDw2uBOx#LCVG=8; zP=|YsE~Lm+i=a(^}u;2!OTNPY>qSFsZgQP-^S{Z#Cb!d#dH=%>ZbFKpc6gL zZ!GIv%ZjLEfNP3=utjqG^68@VU8mmBWeX)!I7K^Uqr1v8mNyL@y-q!-1bpNnvuiNG zai2w_vAKdBL~9%YD}AHTknu5_Vx*+Uwi~O9nZ0$>(ADFlzZ&o*Gylr)JRIzAjzu-g zTR-I3MZEA%x~C8>z%>K6JyEEEMZ#rFt21wXXVc2n zkSya*@&W$g>mYC4(@H1x?DfLKS!l2Lru}HkK!a0P#86DnF2PlF(&YI7hdyPmy4QIM zX2*)Dac=I(63IS6M+|en_D-vlsG(Ttu*q|ozUp7w`;v+IczkZ{vrm7Nex(SM!!+1q zk>K>VR|R}J$CckQ{h7W#7&rJ9mwN+y#l5-owb{F_^61WN*&iD6dz=Ixij|EH1u}hK z^aZFS?p{UXs`~mbT`pqHZgkascT@J6KB5**^*RH-{%m&1zw`(_Wqi@sXMfS)xqD?{ zs#0So%WSh3infex%A(l%;q8^+WN5L`dUy*WW*^PX>^Av$_xo&!`E70Wo&6;%p^gD? z_-Ux#g{Mvx0h7#3?rK`3CEz)$`u%5IEaS0UKS}o#Q&|er${yHWlV5Sv% zQ{v%)30Gjedwj0FiPTl4+;?ZM7w^fIJ#VTJIkdf!b%tU?Eq?A%V0TkA>WV^}IoCbj zy{f*Zhs+dx32)b*UFq;CdlB;LIO45by|3#BL;k=+Keu~vvU%d3N3JbFeeOGOw0P9L zm7Gt1#%{`%>m@S5t3`*;H4utbf7QSH!Ekf5d(+R1gjQ4jzN;9lRLZKMjGx(gZadOx2fpIjMwBq~6z0j?X-(#=9;ezK-jgg3)KlMLU$@{7R diff --git a/mods/ra/bits/desert/br3b.shp b/mods/ra/bits/desert/br3b.shp deleted file mode 100644 index bd110e9062899c6162c6497dfc7658036ac3a0aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2677 zcmX|CYjE7u6~5Ys?R9LtYda)yUUp1VNT8viI=iI}9*=r}b`Ra2y08h@or0cIP|9^YU$fgY=o5`e&Og5VyPiKsDCSxoc zK0X9_$eS?;V@SYNENw*yOBlNzpX&!1HJfziaX9Q691*?I-dGRo!p`B>Sl>i*Xpc3dn+FK0R(^ zn5AlF90WWMO-FXIJRD*9Xe@@IumcNNlmsf!ZUND$1EAw!@CJAb+(iuV{=xHIBP{fc zO(+Y3B1l`ArTs3(6e9;bFntk_bfiViE{`nn@&G90Ziz98p2zWHssiyeV1$3djiloVG4B+K!*AnyBDX{#!UBb5H1)6#BqDP=YgEHvmh9(DmW3Qwv^Y_e7`j%g%o6s|b3uJmY&!#mdx0f9p~o%RI`c>i8~jRJBasi@$+3OqHW%E?2Z* zigzSIrtx?{oqoi3-MN+o7(0mB%cfbddAq<<)@E}#(74}0xC*6iNfIy?r(X?3mNa*P z_wvbIT_)H`qLG$xurFs8Sv%z|sgEZp7*!=@swo(Lt1q24vOFJXW!k_=Ey@b|PyB(wZiP}ssp8nwv_G=QcZ3WD5B9=nsbG5v6|`t!4R|2@=K-_8Igry!!P_*X zJ7I%}Q;!5Yl{JD2O&}aBT0Cc-Ia64BIpq3xJXB?3H zWuY9aM2k+8x6M6;+~wSCJWpHQI#;lC$8lXOikDY`aPokwmrbkelwWsZ0?#MI_Y%|h z!^r1*Wl`(;4k7iQ)gDCUsgHupW9o69`ApMw6rB2Qcfah) zq9~)__kUI3@I#WgJ+2p_U8ZsBz^PYj-T438ZR{%%h@wvX2@y>xg_@Rr{5#&|kAOQuq~;3xjGdpEMIWtVL+ zYB4M`#T-@zCA8ajG%yYPnuIB15O)4HOiTXdm2N(ulrA1nih6)^(uY6aG+eXB2Zsi!BMZn=|m zEap7Dpcf(gA`_Wzfy{Fr7~?@Hqgy+v_ui~e?}Y+g|(PG zw0Z+6`qm9_Ec<0o&z|#j*OT;Idj0fOT_yk91CZ)S>PB|mF=G4g*+*d|iLs1nQHP;V zdnJYPoNs;ehF-H|@;vxy-}*g0X`^H1Q^9ql1H3nJD&$+NIS|!9S$}QKLIT^q@~sMV z9YA~vR__oh2uDrx3fsJ)W*Xc*7-iRurPJRU1~A$_u5F!ITEDVzK$H~O733>{E+wjWhw38&bUQ+C+R3+MDkP1fSTDNl#>cQ5N$;MRc*Nl%;%wN1{U;UN_v=3jlq zl!OF%-q!>%Khq$z!M4akGUD3+-X)wr(aZ7dSYqA>^ZwSbZSkCm|ITTxB?|bX?^|8g z%ajTZk`#fKb-h#;Bxuq3L1MKXZJkRBAjIrfi!TAGd86n}(20``L<;!x6{NTeZ}qJY ze~@=%xf+@bbgJ07A*&V&ZAaCD1>Rja2}8#Ntt3}BN~}fuLO1s3I8QJ3!rV2D_pQ8g)0wOF;s!Sp zx8dDE7oQd7N{K39G%rd>51j>L{*k)Bs3W=1KULFa7T0|kcwFPz3oVN0B^^H9;-7qO z4smOuPYFWz3_2uJs8es&imqJ6w5ic+@jYaC)#D4a&=n7nQ!nRy8}oc7@nJZ=@Wz{s zPoA68F9=o7R%epLVhE9$uL6r0y>U<*8uoyJzmuE~=1;F%d&#R3o;8+zcvEB8*KRca zV)9f|&GWrgZZqEWi6`YLUu!{LSymO#y!obEL;ca3&{ggSa5{06wc Nu8Zl^vdJS){txVjetG}^ diff --git a/mods/ra/bits/desert/br3c.shp b/mods/ra/bits/desert/br3c.shp deleted file mode 100644 index 651e6c53f7a2226bb1f269c21607fe7f0501b8f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2612 zcmX|CdvMeC9skLW69*8L6CR=6b$LJ-v>lXo35h4QD2**DjJ#{aY8lyK?fOTFdCdCB zS+)ZtInIj|=tJU?>$QLMcJr;JEh${-6=+W~r8um|c1_!@4>UIA+TQXgPE1JRO=fq~ zAA0?MpU>y}`hC9$C|>Pg^POis07r^14==g%`TyHndIIWtLKLAcCK50UMIDNwUOV#k zY06Le%>YFOXog$l*c~*@u^d;h`3g=T%85jw1n5!%3jwE;08dGY>ZnA3DBvX)@ckUi z(g7wAV3;C8%7RniqK!**LlGu)u%t&64L?Pkt-g??=|TbHL9|B;g@SEV;0_=GqDh$5 zMdZh_m<1)a!d=7r2tRd}@ZuX7lo@XX^B2oeoJk?UY=idK$Vmm}2zt_&1b2H+ciW6jP zfeTYHj$Nb|wE3w`0DP!q&z~G(}DR6!hva zfks+05$yfyux-u9*fQWQ#_aew6ufwz&@`H3w0V`D*zf2`=n?O}eP~^&=MWYJqric= z2FGDs5N;BrM$c;t;6s@UO}>SsGCl*%pp~UHO5I-Ikh0hk3EH&6U^*TlREE+zG*$iQ z#3pB-n6NA(8a2j2Ck{A3pbte2-V(Eky6TI_ zmjxHlZAK`ec5a3KxR7r3dd>VT+_^*wPfR(HHL^7h+GRcAj6Qt0`qwo-D(c%Pw7=PF z5|5}18)hdDI97Zk@s-bDd!=lRS+PwS6$HNRe1ziZtva^v!MC5{EK{3QWeI^Nl7nw_2MV;NqE z+*I3w)0;s3p6qrPGUG&!ifU&kL7gE?;!F%Vn)Irn!o-`11d*yo+b_TFT1UJnX3fqs z6h{$MM?ezr=fZRXjfKjlFOCsX&fWHP;b2rn8PL;078E|2)#2m1*kPvE3E z6h|FO%bRyt+88uUD2OcU!gfrR&$vm2Ekm9vX@_dSmJ=p#>J^ zw5KbiB;hCUVki`nXapCqU#@!r+f&5%JVBZ_p;fbXYs=rUO|r$W-ZD6}wb7iTG>!|9 zJD#X*mS!AVZJ1q0l7Kw!o>`Ho`bQC(V)1DKjz9F5x-YhOA=YsLy&4}ndmSgqZL=m} z<{Zs^<}K6jH_howSi4kn-vHPm)qv;6J}8&eDqMotV0G{IF54X;QnuxU5Ra#u8oUh+ zs4zuL6Q=38H`N%)Gz|%0v)%R@?*0_pQj}FV?U7YyWkJ}u>9<|At=QdC2K>o(Ej`c_ zzd4or!8EU%opw^=70nOsu$ze}!Lf_wDUO?ukzTMJseEu&awLl(%>+TC=uV z|NQ(iDX@Y|g@Uwpd(J;Bk)_L%T8tt$UjmU-1V!Pf0Ioqoqp0Ei$hfNOSzP2aHE**M$ruv~x%yIC zO!cWW+Ba}|WQ5vgreOq5dghK=aO-quC+XMPE!FvxZkDCEHg~1W;3d6d(Pc8rl)jQ$ zB)9oHLN*yKheH)RCA#cog`-2OP9^;m*#JVG@8m3WJ<*>*Nq+b4c3u!YugO}mp;0nn zu6Sn*ECV+bhNC{Hv+Fg)mHx5f4X{j!vTeIg$ur&uSj5$fLTDHfUMu}~w; z!tMN+3W3)nho#}M>lnD8Fj{!?IjK+_0pSpG28-68vN41*n@g{JKq`(gd!$IUZl~P~ zH%g*iayYs#0{Od_OW%$?x?E-gh$3m#=Oh|Agse%1xoF#lO|B`dz1Q2^AlBAI4CK;L aON>P73R7+>7 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 diff --git a/mods/ra/bits/desert/br3f.shp b/mods/ra/bits/desert/br3f.shp deleted file mode 100644 index 53488c796fcdc9c2009316cb93bcea33c0377343..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 926 zcmX|7U1(c%6hHs_zaMG7_D@2!M38%vwssHGq%vtiX1jK^RcVveZPhubt1WqukxFx~ zn}WG%+yuc@d=Q~-6=aPdu}nm9GVAU-Z<3oO%~kV-8c=I}*lp&Ed$85p37&`F`JIp7 zIfsK_*Cruw*LMQMcgY2OH~b&ojfpW)kwj4uB}q|oG0EhymXsd?Yb5A)**B^LOi z(2k5IkVRR9v`gf#5Jr|rx+J5mCiI0MEyrA^$l-*N1Bc!~yC=X!@)UAX`&=SC>3(bn zgHr0Jnky)w2)-mqyIvxPAAJaD0+k5YGSxp zybb}jFvv7l=SgL+SN9+MQR={aET;Is3HEFiD1Ov^J1|acPbXca?FN*l@e9fP z*NiM~6`0};tiH+RdDeJ{UGJb}V=kGGv&}J7JV%?f!5U*+wTq#XB$DhD1%cdfokx%F z^@8>b-%{?F|d;lQr!F zG%uc*(_X~&w@|rZ_5IcUp8re24)$mBSSXhNM3p|<$W&V@G|}BET$}RON2ziOyY-1w z?~JB8Ig{NHqW z)gDFzL+%5wd_<1vhFyzVD;C5*{QNU>Hd)JGK-CqdyyPU0s2$D@{kuD;;$nYlIHrc& z_vsVV?5)BXwjOt=zd7$c_x Date: Sat, 27 Apr 2013 18:32:09 +0200 Subject: [PATCH 04/11] added .mix file support for game asset browser --- OpenRA.FileFormats/Graphics/ShpReader.cs | 64 ++--- OpenRA.FileFormats/Manifest.cs | 7 +- OpenRA.Game/Game.cs | 2 +- OpenRA.Game/GameRules/Rules.cs | 4 +- OpenRA.Game/ModData.cs | 8 +- .../Widgets/Logic/AssetBrowserLogic.cs | 85 +++++-- mods/cnc/mod.yaml | 2 + mods/d2k/mod.yaml | 2 + mods/ra/chrome/assetbrowser.yaml | 4 + mods/ra/mix/conquer.yaml | 227 ++++++++++++++++++ mods/ra/mix/hires.yaml | 135 +++++++++++ mods/ra/mod.yaml | 4 + 12 files changed, 484 insertions(+), 60 deletions(-) create mode 100644 mods/ra/mix/conquer.yaml create mode 100644 mods/ra/mix/hires.yaml diff --git a/OpenRA.FileFormats/Graphics/ShpReader.cs b/OpenRA.FileFormats/Graphics/ShpReader.cs index 2ccf5d76e1..0795b2696a 100644 --- a/OpenRA.FileFormats/Graphics/ShpReader.cs +++ b/OpenRA.FileFormats/Graphics/ShpReader.cs @@ -62,9 +62,9 @@ namespace OpenRA.FileFormats int recurseDepth = 0; - public ShpReader( Stream stream ) + public ShpReader(Stream stream) { - using( var reader = new BinaryReader( stream ) ) + using (var reader = new BinaryReader(stream)) { ImageCount = reader.ReadUInt16(); reader.ReadUInt16(); @@ -73,60 +73,60 @@ namespace OpenRA.FileFormats Height = reader.ReadUInt16(); reader.ReadUInt32(); - for( int i = 0 ; i < ImageCount ; i++ ) - headers.Add( new ImageHeader( reader ) ); + for (int i = 0 ; i < ImageCount ; i++) + headers.Add(new ImageHeader(reader)); - new ImageHeader( reader ); // end-of-file header - new ImageHeader( reader ); // all-zeroes header + new ImageHeader(reader); // end-of-file header + new ImageHeader(reader); // all-zeroes header var offsets = headers.ToDictionary(h => h.Offset, h =>h); - for( int i = 0 ; i < ImageCount ; i++ ) + for (int i = 0 ; i < ImageCount ; i++) { var h = headers[ i ]; - if( h.Format == Format.Format20 ) - h.RefImage = headers[ i - 1 ]; + if (h.Format == Format.Format20) + h.RefImage = headers[i - 1]; - else if( h.Format == Format.Format40 ) - if( !offsets.TryGetValue( h.RefOffset, out h.RefImage ) ) - throw new InvalidDataException( "Reference doesnt point to image data {0}->{1}".F(h.Offset, h.RefOffset) ); + else if (h.Format == Format.Format40) + if (!offsets.TryGetValue(h.RefOffset, out h.RefImage)) + throw new InvalidDataException("Reference doesnt point to image data {0}->{1}".F(h.Offset, h.RefOffset)); } - foreach( ImageHeader h in headers ) - Decompress( stream, h ); + foreach (ImageHeader h in headers) + Decompress(stream, h); } } - public ImageHeader this[ int index ] + public ImageHeader this[int index] { - get { return headers[ index ]; } + get { return headers[index]; } } - void Decompress( Stream stream, ImageHeader h ) + void Decompress(Stream stream, ImageHeader h) { - if( recurseDepth > ImageCount ) - throw new InvalidDataException( "Format20/40 headers contain infinite loop" ); + if (recurseDepth > ImageCount) + throw new InvalidDataException("Format20/40 headers contain infinite loop"); - switch( h.Format ) + switch(h.Format) { case Format.Format20: case Format.Format40: { - if( h.RefImage.Image == null ) + if (h.RefImage.Image == null) { ++recurseDepth; - Decompress( stream, h.RefImage ); + Decompress(stream, h.RefImage); --recurseDepth; } - h.Image = CopyImageData( h.RefImage.Image ); + h.Image = CopyImageData(h.RefImage.Image); Format40.DecodeInto(ReadCompressedData(stream, h), h.Image); break; } case Format.Format80: { - var imageBytes = new byte[ Width * Height ]; - Format80.DecodeInto( ReadCompressedData( stream, h ), imageBytes ); + var imageBytes = new byte[Width * Height]; + Format80.DecodeInto(ReadCompressedData(stream, h), imageBytes); h.Image = imageBytes; break; } @@ -135,11 +135,11 @@ namespace OpenRA.FileFormats } } - static byte[] ReadCompressedData( Stream stream, ImageHeader h ) + static byte[] ReadCompressedData(Stream stream, ImageHeader h) { stream.Position = h.Offset; - // Actually, far too big. There's no length field with the correct length though :( - var compressedLength = (int)( stream.Length - stream.Position ); + // TODO: Actually, far too big. There's no length field with the correct length though :( + var compressedLength = (int)(stream.Length - stream.Position); var compressedBytes = new byte[ compressedLength ]; stream.Read( compressedBytes, 0, compressedLength ); @@ -147,11 +147,11 @@ namespace OpenRA.FileFormats return compressedBytes; } - byte[] CopyImageData( byte[] baseImage ) + byte[] CopyImageData(byte[] baseImage) { - var imageData = new byte[ Width * Height ]; - for( int i = 0 ; i < Width * Height ; i++ ) - imageData[ i ] = baseImage[ i ]; + var imageData = new byte[Width * Height]; + for (int i = 0 ; i < Width * Height ; i++) + imageData[i] = baseImage[i]; return imageData; } diff --git a/OpenRA.FileFormats/Manifest.cs b/OpenRA.FileFormats/Manifest.cs index 1db3f1bbf1..989574cb62 100644 --- a/OpenRA.FileFormats/Manifest.cs +++ b/OpenRA.FileFormats/Manifest.cs @@ -9,6 +9,7 @@ #endregion using System.Collections.Generic; +using System.IO; using System.Linq; namespace OpenRA.FileFormats @@ -20,7 +21,8 @@ namespace OpenRA.FileFormats public readonly string[] Mods, Folders, Packages, Rules, ServerTraits, Sequences, Cursors, Chrome, Assemblies, ChromeLayout, - Weapons, Voices, Notifications, Music, Movies, TileSets, ChromeMetrics; + Weapons, Voices, Notifications, Music, Movies, TileSets, + ChromeMetrics, PackageContents; public readonly MiniYaml LoadScreen; public readonly Dictionary> Fonts; public readonly int TileSize = 24; @@ -29,7 +31,7 @@ namespace OpenRA.FileFormats { Mods = mods; var yaml = new MiniYaml(null, mods - .Select(m => MiniYaml.FromFile("mods/" + m + "/mod.yaml")) + .Select(m => MiniYaml.FromFile("mods{0}{1}{0}mod.yaml".F(Path.DirectorySeparatorChar, m))) .Aggregate(MiniYaml.MergeLiberal)).NodesDict; // TODO: Use fieldloader @@ -49,6 +51,7 @@ namespace OpenRA.FileFormats Movies = YamlList(yaml, "Movies"); TileSets = YamlList(yaml, "TileSets"); ChromeMetrics = YamlList(yaml, "ChromeMetrics"); + PackageContents = YamlList(yaml, "PackageContents"); LoadScreen = yaml["LoadScreen"]; Fonts = yaml["Fonts"].NodesDict.ToDictionary(x => x.Key, diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index 3e8a69fa0f..28b59218cb 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -238,7 +238,7 @@ namespace OpenRA public static Dictionary CurrentMods { - get { return Mod.AllMods.Where( k => modData.Manifest.Mods.Contains( k.Key )).ToDictionary( k => k.Key, k => k.Value ); } + get { return Mod.AllMods.Where(k => modData.Manifest.Mods.Contains(k.Key)).ToDictionary(k => k.Key, k => k.Value); } } static Modifiers modifiers; diff --git a/OpenRA.Game/GameRules/Rules.cs b/OpenRA.Game/GameRules/Rules.cs index bf0d6fd4d5..2b6842ff01 100755 --- a/OpenRA.Game/GameRules/Rules.cs +++ b/OpenRA.Game/GameRules/Rules.cs @@ -25,6 +25,7 @@ namespace OpenRA public static Dictionary Music; public static Dictionary Movies; public static Dictionary TileSets; + public static Dictionary PackageContents; public static void LoadRules(Manifest m, Map map) { @@ -35,6 +36,7 @@ namespace OpenRA Notifications = LoadYamlRules(m.Notifications, map.Notifications, (k, _) => new SoundInfo(k.Value)); Music = LoadYamlRules(m.Music, new List(), (k, _) => new MusicInfo(k.Key, k.Value)); Movies = LoadYamlRules(m.Movies, new List(), (k, v) => k.Value.Value); + PackageContents = LoadYamlRules(m.PackageContents, new List(), (k, v) => k.Value.Value); TileSets = new Dictionary(); foreach (var file in m.TileSets) @@ -46,7 +48,7 @@ namespace OpenRA static Dictionary LoadYamlRules(string[] files, List dict, Func, T> f) { - var y = files.Select(a => MiniYaml.FromFile(a)).Aggregate(dict,MiniYaml.MergeLiberal); + var y = files.Select(a => MiniYaml.FromFile(a)).Aggregate(dict, MiniYaml.MergeLiberal); var yy = y.ToDictionary( x => x.Key, x => x.Value ); return y.ToDictionary(kv => kv.Key.ToLowerInvariant(), kv => f(kv, yy)); } diff --git a/OpenRA.Game/ModData.cs b/OpenRA.Game/ModData.cs index f5c298d4b7..51d9f11fb8 100755 --- a/OpenRA.Game/ModData.cs +++ b/OpenRA.Game/ModData.cs @@ -29,14 +29,14 @@ namespace OpenRA public SheetBuilder SheetBuilder; public SpriteLoader SpriteLoader; - public ModData( params string[] mods ) + public ModData(params string[] mods) { - Manifest = new Manifest( mods ); - ObjectCreator = new ObjectCreator( Manifest ); + Manifest = new Manifest(mods); + ObjectCreator = new ObjectCreator(Manifest); LoadScreen = ObjectCreator.CreateObject(Manifest.LoadScreen.Value); LoadScreen.Init(Manifest.LoadScreen.NodesDict.ToDictionary(x => x.Key, x => x.Value.Value)); LoadScreen.Display(); - WidgetLoader = new WidgetLoader( this ); + WidgetLoader = new WidgetLoader(this); } public void LoadInitialAssets(bool enumMaps) diff --git a/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs index 60154c5f2d..cc6f67b072 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs @@ -9,6 +9,7 @@ #endregion using System; +using System.Collections.Generic; using System.IO; using System.Linq; using OpenRA.FileFormats; @@ -22,30 +23,27 @@ namespace OpenRA.Mods.RA.Widgets.Logic { Widget panel; - ShpImageWidget spriteImage; - TextFieldWidget filenameInput; - SliderWidget frameSlider; - ButtonWidget playButton; - ButtonWidget pauseButton; + static ShpImageWidget spriteImage; + static TextFieldWidget filenameInput; + static SliderWidget frameSlider; + static ButtonWidget playButton; + static ButtonWidget pauseButton; + static ScrollPanelWidget assetList; + static ScrollItemWidget template; + + public enum SourceType { Folders, Packages } + public static SourceType AssetSource = SourceType.Folders; [ObjectCreator.UseCtor] public AssetBrowserLogic(Widget widget, Action onExit, World world) { panel = widget; - var assetList = panel.Get("ASSET_LIST"); - var template = panel.Get("ASSET_TEMPLATE"); - - assetList.RemoveChildren(); - foreach (var folder in FileSystem.FolderPaths) - { - if (Directory.Exists(folder)) - { - var shps = Directory.GetFiles(folder, "*.shp"); - foreach (var shp in shps) - AddAsset(assetList, shp, template); - } - } + var sourceDropdown = panel.Get("SOURCE_SELECTOR"); + sourceDropdown.OnMouseDown = _ => ShowSourceDropdown(sourceDropdown); + sourceDropdown.GetText = () => AssetSource == SourceType.Folders ? "Folders" + : AssetSource == SourceType.Packages ? "Packages" : "None"; + sourceDropdown.Disabled = !Rules.PackageContents.Keys.Any(); spriteImage = panel.Get("SPRITE"); @@ -93,10 +91,14 @@ namespace OpenRA.Mods.RA.Widgets.Logic LoadAsset(filenameInput.Text); }; + assetList = panel.Get("ASSET_LIST"); + template = panel.Get("ASSET_TEMPLATE"); + PopulateAssetList(); + panel.Get("CLOSE_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); }; } - void AddAsset(ScrollPanelWidget list, string filepath, ScrollItemWidget template) + static void AddAsset(ScrollPanelWidget list, string filepath, ScrollItemWidget template) { var sprite = Path.GetFileNameWithoutExtension(filepath); @@ -108,7 +110,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic list.AddChild(item); } - bool LoadAsset(string filename) + static bool LoadAsset(string filename) { if (filename == null) return false; @@ -120,5 +122,48 @@ namespace OpenRA.Mods.RA.Widgets.Logic frameSlider.Ticks = spriteImage.FrameCount+1; return true; } + + public static bool ShowSourceDropdown(DropDownButtonWidget dropdown) + { + var options = new Dictionary() + { + { "Folders", SourceType.Folders }, + { "Packages", SourceType.Packages }, + }; + + Func setupItem = (o, itemTemplate) => + { + var item = ScrollItemWidget.Setup(itemTemplate, + () => AssetSource == options[o], + () => { AssetSource = options[o]; PopulateAssetList(); }); + item.Get("LABEL").GetText = () => o; + return item; + }; + + dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, options.Keys, setupItem); + return true; + } + + public static void PopulateAssetList() + { + assetList.RemoveChildren(); + + if (AssetSource == SourceType.Folders) + { + foreach (var folder in FileSystem.FolderPaths) + { + if (Directory.Exists(folder)) + { + var shps = Directory.GetFiles(folder, "*.shp"); + foreach (var shp in shps) + AddAsset(assetList, shp, template); + } + } + } + + if (AssetSource == SourceType.Packages) + foreach (var hiddenFile in Rules.PackageContents.Keys) + AddAsset(assetList, hiddenFile, template); + } } } diff --git a/mods/cnc/mod.yaml b/mods/cnc/mod.yaml index a306881e58..9b6a4fa3fb 100644 --- a/mods/cnc/mod.yaml +++ b/mods/cnc/mod.yaml @@ -29,6 +29,8 @@ Packages: ~scores2.mix ~transit.mix +PackageContents: + Rules: mods/cnc/rules/defaults.yaml mods/cnc/rules/system.yaml diff --git a/mods/d2k/mod.yaml b/mods/d2k/mod.yaml index de3390ecfb..62442e1ebd 100644 --- a/mods/d2k/mod.yaml +++ b/mods/d2k/mod.yaml @@ -21,6 +21,8 @@ Packages: ~main.mix conquer.mix +PackageContents: + Rules: mods/d2k/rules/system.yaml mods/d2k/rules/defaults.yaml diff --git a/mods/ra/chrome/assetbrowser.yaml b/mods/ra/chrome/assetbrowser.yaml index cd07b7bc53..2e3243059c 100644 --- a/mods/ra/chrome/assetbrowser.yaml +++ b/mods/ra/chrome/assetbrowser.yaml @@ -83,6 +83,7 @@ Background@ASSETBROWSER_BG: Height:25 Text:Change Palette Font:Bold + Disabled: yes Button@IMPORT_BUTTON: X:PARENT_RIGHT - 200 Y:PARENT_BOTTOM - 270 @@ -90,6 +91,7 @@ Background@ASSETBROWSER_BG: Height:25 Text:Import from PNG Font:Bold + Disabled: yes Button@EXTRACT_BUTTON: X:PARENT_RIGHT - 200 Y:PARENT_BOTTOM - 235 @@ -97,6 +99,7 @@ Background@ASSETBROWSER_BG: Height:25 Text:Extract to Folder Font:Bold + Disabled: yes Button@EXPORT_BUTTON: X:PARENT_RIGHT - 200 Y:PARENT_BOTTOM - 200 @@ -104,6 +107,7 @@ Background@ASSETBROWSER_BG: Height:25 Text:Export as PNG Font:Bold + Disabled: yes Button@CLOSE_BUTTON: X:PARENT_RIGHT - 200 Y:PARENT_BOTTOM - 115 diff --git a/mods/ra/mix/conquer.yaml b/mods/ra/mix/conquer.yaml new file mode 100644 index 0000000000..91f479af5c --- /dev/null +++ b/mods/ra/mix/conquer.yaml @@ -0,0 +1,227 @@ +# conquer.mix filename list for the game asset browser +#appear1.aud: +#beepy6.aud: +#briefing.aud: +#clock1.aud: +#country1.aud: +#country4.aud: +#keystrok.aud: +#mapwipe2.aud: +#mapwipe5.aud: +#scold1.aud: +#sfx4.aud: +#toney10.aud: +#toney4.aud: +#toney7.aud: +#type.fnt: +#alibackh.pcx: +#sovback.pcx: +120mm.shp: +1tnk.shp:light tank +2tnk.shp:medium tank +3tnk.shp:heavy tank +4tnk.shp:mammoth tank +50cal.shp: +afld.shp: +afldmake.shp: +agun.shp: +agunmake.shp: +apc.shp: +apwr.shp: +apwramke.shp: +armor.shp: +art-exp1.shp: +arty.shp: +atek.shp: +atekmake.shp: +atomicdn.shp: +atomicup.shp: +atomsfx.shp: +badr.shp: +bar3bhr.shp: +bar3blue.shp: +bar3red.shp: +bar3rhr.shp: +barb.shp: +barl.shp: +barr.shp: +barrmake.shp: +bio.shp: +biomake.shp: +bomb.shp: +bomblet.shp: +brik.shp: +brl3.shp: +burn-l.shp: +burn-m.shp: +burn-s.shp: +ca.shp: +chronbox.shp: +countrya.shp: +countrye.shp: +credsa.shp: +credsahr.shp: +credsu.shp: +credsuhr.shp: +cycl.shp: +dd.shp: +deviator.shp: +dog.shp: +dogbullt.shp: +dollar.shp: +dome.shp: +domemake.shp: +dragon.shp: +earth.shp: +ebtn-dn.shp: +electdog.shp: +empulse.shp: +fact.shp: +factmake.shp: +fb1.shp: +fb2.shp: +fball1.shp: +fcom.shp: +fenc.shp: +fire1.shp: +fire2.shp: +fire3.shp: +fire4.shp: +fix.shp: +fixmake.shp: +flagfly.shp: +flak.shp: +flmspt.shp: +fpls.shp: +fpower.shp: +frag1.shp: +ftnk.shp: +ftur.shp: +fturmake.shp: +gap.shp: +gapmake.shp: +gpsbox.shp: +gun.shp: +gunfire.shp: +gunmake.shp: +h2o_exp1.shp: +h2o_exp2.shp: +h2o_exp3.shp: +harv.shp: +heli.shp: +hind.shp: +hisc1-hr.shp: +hisc2-hr.shp: +hiscore1.shp: +hiscore2.shp: +hosp.shp: +hospmake.shp: +hpad.shp: +hpadmake.shp: +invulbox.shp: +invun.shp: +iron.shp: +ironmake.shp: +jeep.shp: +kenn.shp: +kennmake.shp: +litning.shp: +lrotor.shp: +lst.shp: +mcv.shp: +mgg.shp: +mgun.shp: +mhq.shp: +mig.shp: +mine.shp: +minigun.shp: +minp.shp: +minpmake.shp: +minv.shp: +minvmake.shp: +miss.shp: +missile.shp: +missile2.shp: +mlrs.shp: +mnly.shp: +mrj.shp: +napalm1.shp: +napalm2.shp: +napalm3.shp: +orca.shp: +parabomb.shp: +parabox.shp: +parach.shp: +patriot.shp: +pbox.shp: +pboxmake.shp: +pdox.shp: +pdoxmake.shp: +piff.shp: +piffpiff.shp: +powr.shp: +powrmake.shp: +pt.shp: +pumpmake.shp: +radarfrm.shp: +rapid.shp: +rrotor.shp: +sam.shp: +samfire.shp: +sammake.shp: +sbag.shp: +scrate.shp: +select.shp: +repair.shp: +shadow.shp: +silo.shp: +silomake.shp: +smig.shp: +smoke_m.shp: +smokey.shp: +smokland.shp: +sonarbox.shp: +speed.shp: +spen.shp: +spenmake.shp: +sputdoor.shp: +sputnik.shp: +ss.shp: +ssam.shp: +stealth2.shp: +stek.shp: +stekmake.shp: +stnk.shp: +syrd.shp: +syrdmake.shp: +tent.shp: +tentmake.shp: +time.shp: +timehr.shp: +tquake.shp: +tran.shp: +truk.shp: +tsla.shp: +tslamake.shp: +turr.shp: +twinkle1.shp: +twinkle2.shp: +twinkle3.shp: +u2.shp: +v19.shp: +v2.shp: +v2rl.shp: +veh-hit1.shp: +veh-hit2.shp: +wake.shp: +wcrate.shp: +weap.shp: +weap2.shp: +weapmake.shp: +wood.shp: +wwcrate.shp: +yak.shp: +#trans.icn: +#ali-tran.wsa: +#mltiplyr.wsa: +#sov-tran.wsa: \ No newline at end of file diff --git a/mods/ra/mix/hires.yaml b/mods/ra/mix/hires.yaml new file mode 100644 index 0000000000..61bf1bcb3e --- /dev/null +++ b/mods/ra/mix/hires.yaml @@ -0,0 +1,135 @@ +# hires.mix filename list for the game asset browser +1tnkicon.shp: +2tnkicon.shp: +3tnkicon.shp: +4tnkicon.shp: +afldicon.shp: +agunicon.shp: +apcicon.shp: +apwricon.shp: +artyicon.shp: +atekicon.shp: +atomicon.shp: +badricon.shp: +barricon.shp: +brikicon.shp: +btn-dn.shp: +btn-pl.shp: +btn-st.shp: +btn-up.shp: +c1.shp: +c2.shp: +caicon.shp: +camicon.shp: +chan.shp: +clock.shp: +dd-bkgnd.shp: +dd-botm.shp: +dd-crnr.shp: +dd-edge.shp: +dd-left.shp: +dd-right.shp: +dd-top.shp: +ddicon.shp: +delphi.shp: +dogicon.shp: +domeicon.shp: +domficon.shp: +e1.shp: +e1icon.shp: +e2.shp: +e2icon.shp: +e3.shp: +e3icon.shp: +e4.shp: +e4icon.shp: +e5.shp: +e6.shp: +e6icon.shp: +e7.shp: +e7icon.shp: +einstein.shp: +facficon.shp: +facticon.shp: +fencicon.shp: +fixicon.shp: +fturicon.shp: +gapicon.shp: +gnrl.shp: +gpssicon.shp: +gunicon.shp: +harvicon.shp: +hboxicon.shp: +heliicon.shp: +hindicon.shp: +hpadicon.shp: +infxicon.shp: +ironicon.shp: +jeepicon.shp: +kennicon.shp: +lsticon.shp: +map.shp: +mcvicon.shp: +medi.shp: +mediicon.shp: +mggicon.shp: +migicon.shp: +mnlyicon.shp: +mrjicon.shp: +msloicon.shp: +natoradr.shp: +nradrfrm.shp: +pbmbicon.shp: +pboxicon.shp: +pdoxicon.shp: +pinficon.shp: +pips.shp: +power.shp: +powerbar.shp: +powricon.shp: +procicon.shp: +pticon.shp: +pulse.shp: +repair.shp: +samicon.shp: +sbagicon.shp: +sell.shp: +side1na.shp: +side1us.shp: +side2na.shp: +side2us.shp: +side3na.shp: +side3us.shp: +#sidebar.shp:will crash +siloicon.shp: +smigicon.shp: +sonricon.shp: +speficon.shp: +spenicon.shp: +spy.shp: +spyicon.shp: +ssicon.shp: +stekicon.shp: +strip.shp: +stripdn.shp: +stripna.shp: +stripup.shp: +stripus.shp: +syrdicon.shp: +syrficon.shp: +tabs.shp: +tenticon.shp: +thf.shp: +thficon.shp: +tranicon.shp: +trukicon.shp: +tslaicon.shp: +u2icon.shp: +uradrfrm.shp: +ussrradr.shp: +v2rlicon.shp: +warpicon.shp: +weaficon.shp: +weapicon.shp: +yakicon.shp: +#mouse.shp:Dune II format \ No newline at end of file diff --git a/mods/ra/mod.yaml b/mods/ra/mod.yaml index f7137f7323..64df95e7cf 100644 --- a/mods/ra/mod.yaml +++ b/mods/ra/mod.yaml @@ -29,6 +29,10 @@ Packages: ~movies1.mix ~movies2.mix +PackageContents: + mods/ra/mix/conquer.yaml + mods/ra/mix/hires.yaml + Rules: mods/ra/rules/defaults.yaml mods/ra/rules/system.yaml From 7f40f59d857ee37208394721a0545fd333e014ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Sun, 28 Apr 2013 19:42:01 +0200 Subject: [PATCH 05/11] added button to extract the selected SHP and convert it to PNG --- OpenRA.Game/Widgets/WidgetUtils.cs | 6 + OpenRA.Mods.RA/OpenRA.Mods.RA.csproj | 5 + .../Widgets/Logic/AssetBrowserLogic.cs | 24 ++++ .../Widgets/Logic/ExtractGameFilesLogic.cs | 103 ++++++++++++++++++ mods/d2k/mod.yaml | 1 + mods/ra/chrome/assetbrowser.yaml | 5 +- mods/ra/chrome/extractassets.yaml | 47 ++++++++ mods/ra/mod.yaml | 1 + 8 files changed, 189 insertions(+), 3 deletions(-) create mode 100644 OpenRA.Mods.RA/Widgets/Logic/ExtractGameFilesLogic.cs create mode 100644 mods/ra/chrome/extractassets.yaml diff --git a/OpenRA.Game/Widgets/WidgetUtils.cs b/OpenRA.Game/Widgets/WidgetUtils.cs index ad179c422f..7120dacc3e 100644 --- a/OpenRA.Game/Widgets/WidgetUtils.cs +++ b/OpenRA.Game/Widgets/WidgetUtils.cs @@ -227,6 +227,12 @@ namespace OpenRA.Widgets return Mod.AllMods[mod].Title; } + public static string ActiveModId() + { + var mod = Game.modData.Manifest.Mods[0]; + return Mod.AllMods[mod].Id; + } + public static string ChooseInitialMap(string map) { var availableMaps = Game.modData.AvailableMaps; diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 9bcf55ea19..5d1a147e5a 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -437,6 +437,7 @@ + @@ -449,6 +450,10 @@ OpenRA.Game False + + {F33337BE-CB69-4B24-850F-07D23E408DDF} + OpenRA.Utility + diff --git a/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs index cc6f67b072..1d3d5ea16b 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs @@ -95,6 +95,30 @@ namespace OpenRA.Mods.RA.Widgets.Logic template = panel.Get("ASSET_TEMPLATE"); PopulateAssetList(); + panel.Get("EXPORT_BUTTON").OnClick = () => + { + var palette = (WidgetUtils.ActiveModId() == "d2k") ? "d2k.pal" : "egopal.pal"; + + var ExtractGameFiles = new string[][] + { + new string[] {"--extract", WidgetUtils.ActiveModId(), palette}, + new string[] {"--extract", WidgetUtils.ActiveModId(), "{0}.shp".F(spriteImage.Image)}, + }; + + var ExportToPng = new string[][] + { + new string[] {"--png", "{0}.shp".F(spriteImage.Image), palette}, + }; + + var args = new WidgetArgs() + { + { "ExtractGameFiles", ExtractGameFiles }, + { "ExportToPng", ExportToPng } + }; + + Ui.OpenWindow("EXTRACT_ASSETS_PANEL", args); + }; + panel.Get("CLOSE_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); }; } diff --git a/OpenRA.Mods.RA/Widgets/Logic/ExtractGameFilesLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ExtractGameFilesLogic.cs new file mode 100644 index 0000000000..db4520ff65 --- /dev/null +++ b/OpenRA.Mods.RA/Widgets/Logic/ExtractGameFilesLogic.cs @@ -0,0 +1,103 @@ +#region Copyright & License Information +/* + * Copyright 2007-2013 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.IO; +using System.Linq; +using System.Threading; +using System.Diagnostics; +using OpenRA.FileFormats; +using OpenRA.FileFormats.Graphics; +using OpenRA.Widgets; +using OpenRA.Utility; + +namespace OpenRA.Mods.RA.Widgets.Logic +{ + public class ExtractGameFilesLogic + { + Widget panel; + ProgressBarWidget progressBar; + LabelWidget statusLabel; + ButtonWidget retryButton, backButton; + Widget extractingContainer; + + string[][] ExtractGameFiles, ExportToPng; + + [ObjectCreator.UseCtor] + public ExtractGameFilesLogic(Widget widget, string[][] ExtractGameFiles, string[][] ExportToPng) + { + panel = widget.Get("EXTRACT_ASSETS_PANEL"); + progressBar = panel.Get("PROGRESS_BAR"); + statusLabel = panel.Get("STATUS_LABEL"); + + backButton = panel.Get("BACK_BUTTON"); + backButton.OnClick = Ui.CloseWindow; + + retryButton = panel.Get("RETRY_BUTTON"); + retryButton.OnClick = Extract; + + extractingContainer = panel.Get("EXTRACTING"); + + this.ExtractGameFiles = ExtractGameFiles; + foreach (var s in ExtractGameFiles) + foreach (var ss in s) + Console.WriteLine(ss); + this.ExportToPng = ExportToPng; + + Extract(); + } + + void Extract() + { + backButton.IsDisabled = () => true; + retryButton.IsDisabled = () => true; + extractingContainer.IsVisible = () => true; + + var onError = (Action)(s => Game.RunAfterTick(() => + { + statusLabel.GetText = () => "Error: "+s; + backButton.IsDisabled = () => false; + retryButton.IsDisabled = () => false; + })); + + var t = new Thread( _ => + { + try + { + for (int i = 0; i < ExtractGameFiles.Length; i++) + { + progressBar.Percentage = i*100/ExtractGameFiles.Count(); + statusLabel.GetText = () => "Extracting..."; + Utility.Command.ExtractFiles(ExtractGameFiles[i]); + } + + for (int i = 0; i < ExportToPng.Length; i++) + { + progressBar.Percentage = i*100/ExportToPng.Count(); + statusLabel.GetText = () => "Converting..."; + Utility.Command.ConvertShpToPng(ExportToPng[i]); + } + + Game.RunAfterTick(() => + { + progressBar.Percentage = 100; + statusLabel.GetText = () => "Extraction and conversion complete."; + backButton.IsDisabled = () => false; + }); + } + catch + { + onError("Extraction or conversion failed"); + } + }) { IsBackground = true }; + t.Start(); + } + } +} diff --git a/mods/d2k/mod.yaml b/mods/d2k/mod.yaml index 62442e1ebd..22ce2ee495 100644 --- a/mods/d2k/mod.yaml +++ b/mods/d2k/mod.yaml @@ -69,6 +69,7 @@ ChromeLayout: mods/ra/chrome/musicplayer.yaml mods/d2k/chrome/tooltips.yaml mods/ra/chrome/assetbrowser.yaml + mods/ra/chrome/extractassets.yaml Weapons: mods/d2k/weapons/defaults.yaml diff --git a/mods/ra/chrome/assetbrowser.yaml b/mods/ra/chrome/assetbrowser.yaml index 2e3243059c..619a562a5b 100644 --- a/mods/ra/chrome/assetbrowser.yaml +++ b/mods/ra/chrome/assetbrowser.yaml @@ -97,7 +97,7 @@ Background@ASSETBROWSER_BG: Y:PARENT_BOTTOM - 235 Width:160 Height:25 - Text:Extract to Folder + Text:Extract all to PNG Font:Bold Disabled: yes Button@EXPORT_BUTTON: @@ -105,9 +105,8 @@ Background@ASSETBROWSER_BG: Y:PARENT_BOTTOM - 200 Width:160 Height:25 - Text:Export as PNG + Text:Selected to PNG Font:Bold - Disabled: yes Button@CLOSE_BUTTON: X:PARENT_RIGHT - 200 Y:PARENT_BOTTOM - 115 diff --git a/mods/ra/chrome/extractassets.yaml b/mods/ra/chrome/extractassets.yaml new file mode 100644 index 0000000000..199eb7a06b --- /dev/null +++ b/mods/ra/chrome/extractassets.yaml @@ -0,0 +1,47 @@ +Background@EXTRACT_ASSETS_PANEL: + Logic:ExtractGameFilesLogic + X:(WINDOW_RIGHT - WIDTH)/2 + Y:(WINDOW_BOTTOM - HEIGHT)/2 + Width:500 + Height:160 + Children: + Label@TITLE: + X:0 + Y:20 + Width:PARENT_RIGHT + Height:25 + Text:Extracting and Converting Gamefiles + Align:Center + Font:Bold + Container@EXTRACTING: + Width:PARENT_RIGHT + Height:PARENT_BOTTOM + Visible: false + Children: + ProgressBar@PROGRESS_BAR: + X:50 + Y:55 + Width:PARENT_RIGHT - 100 + Height:25 + Label@STATUS_LABEL: + X:50 + Y:80 + Width:PARENT_RIGHT - 100 + Height:25 + Align:Left + Button@RETRY_BUTTON: + X:PARENT_RIGHT - 280 + Y:PARENT_BOTTOM - 45 + Width:120 + Height:25 + Text:Retry + Font:Bold + Key:return + Button@BACK_BUTTON: + X:PARENT_RIGHT - 140 + Y:PARENT_BOTTOM - 45 + Width:120 + Height:25 + Text:Back + Font:Bold + Key:escape \ No newline at end of file diff --git a/mods/ra/mod.yaml b/mods/ra/mod.yaml index 64df95e7cf..2af52f08d0 100644 --- a/mods/ra/mod.yaml +++ b/mods/ra/mod.yaml @@ -78,6 +78,7 @@ ChromeLayout: mods/ra/chrome/musicplayer.yaml mods/ra/chrome/tooltips.yaml mods/ra/chrome/assetbrowser.yaml + mods/ra/chrome/extractassets.yaml Weapons: mods/ra/weapons.yaml From 0c1b6f21b961374c82f3f0425a2e11caf967e9d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Sun, 28 Apr 2013 20:36:18 +0200 Subject: [PATCH 06/11] add a dump everything to PNG options for @xanax --- .../Widgets/Logic/AssetBrowserLogic.cs | 41 +++++++++++++++++-- .../Widgets/Logic/ExtractGameFilesLogic.cs | 3 -- mods/ra/chrome/assetbrowser.yaml | 1 - mods/ra/mix/conquer.yaml | 4 +- 4 files changed, 39 insertions(+), 10 deletions(-) diff --git a/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs index 1d3d5ea16b..61a7c060dc 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs @@ -26,14 +26,15 @@ namespace OpenRA.Mods.RA.Widgets.Logic static ShpImageWidget spriteImage; static TextFieldWidget filenameInput; static SliderWidget frameSlider; - static ButtonWidget playButton; - static ButtonWidget pauseButton; + static ButtonWidget playButton, pauseButton; static ScrollPanelWidget assetList; static ScrollItemWidget template; public enum SourceType { Folders, Packages } public static SourceType AssetSource = SourceType.Folders; + public static List AvailableShps = new List(); + [ObjectCreator.UseCtor] public AssetBrowserLogic(Widget widget, Action onExit, World world) { @@ -95,10 +96,10 @@ namespace OpenRA.Mods.RA.Widgets.Logic template = panel.Get("ASSET_TEMPLATE"); PopulateAssetList(); + var palette = (WidgetUtils.ActiveModId() == "d2k") ? "d2k.pal" : "egopal.pal"; + panel.Get("EXPORT_BUTTON").OnClick = () => { - var palette = (WidgetUtils.ActiveModId() == "d2k") ? "d2k.pal" : "egopal.pal"; - var ExtractGameFiles = new string[][] { new string[] {"--extract", WidgetUtils.ActiveModId(), palette}, @@ -115,7 +116,32 @@ namespace OpenRA.Mods.RA.Widgets.Logic { "ExtractGameFiles", ExtractGameFiles }, { "ExportToPng", ExportToPng } }; + + Ui.OpenWindow("EXTRACT_ASSETS_PANEL", args); + }; + panel.Get("EXTRACT_BUTTON").OnClick = () => + { + var ExtractGameFilesList = new List(); + var ExportToPngList = new List(); + + ExtractGameFilesList.Add(new string[] { "--extract", WidgetUtils.ActiveModId(), palette} ); + + foreach (var shp in AvailableShps) + { + ExtractGameFilesList.Add(new string[] { "--extract", WidgetUtils.ActiveModId(), shp } ); + ExportToPngList.Add(new string[] { "--png", shp, palette } ); + } + + var ExtractGameFiles = ExtractGameFilesList.ToArray(); + var ExportToPng = ExportToPngList.ToArray(); + + var args = new WidgetArgs() + { + { "ExtractGameFiles", ExtractGameFiles }, + { "ExportToPng", ExportToPng } + }; + Ui.OpenWindow("EXTRACT_ASSETS_PANEL", args); }; @@ -171,6 +197,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic public static void PopulateAssetList() { assetList.RemoveChildren(); + AvailableShps.Clear(); if (AssetSource == SourceType.Folders) { @@ -180,14 +207,20 @@ namespace OpenRA.Mods.RA.Widgets.Logic { var shps = Directory.GetFiles(folder, "*.shp"); foreach (var shp in shps) + { AddAsset(assetList, shp, template); + AvailableShps.Add(shp); + } } } } if (AssetSource == SourceType.Packages) foreach (var hiddenFile in Rules.PackageContents.Keys) + { AddAsset(assetList, hiddenFile, template); + AvailableShps.Add(hiddenFile); + } } } } diff --git a/OpenRA.Mods.RA/Widgets/Logic/ExtractGameFilesLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ExtractGameFilesLogic.cs index db4520ff65..0acdb3293d 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/ExtractGameFilesLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/ExtractGameFilesLogic.cs @@ -46,9 +46,6 @@ namespace OpenRA.Mods.RA.Widgets.Logic extractingContainer = panel.Get("EXTRACTING"); this.ExtractGameFiles = ExtractGameFiles; - foreach (var s in ExtractGameFiles) - foreach (var ss in s) - Console.WriteLine(ss); this.ExportToPng = ExportToPng; Extract(); diff --git a/mods/ra/chrome/assetbrowser.yaml b/mods/ra/chrome/assetbrowser.yaml index 619a562a5b..fbb639cf1f 100644 --- a/mods/ra/chrome/assetbrowser.yaml +++ b/mods/ra/chrome/assetbrowser.yaml @@ -99,7 +99,6 @@ Background@ASSETBROWSER_BG: Height:25 Text:Extract all to PNG Font:Bold - Disabled: yes Button@EXPORT_BUTTON: X:PARENT_RIGHT - 200 Y:PARENT_BOTTOM - 200 diff --git a/mods/ra/mix/conquer.yaml b/mods/ra/mix/conquer.yaml index 91f479af5c..83bba64bc1 100644 --- a/mods/ra/mix/conquer.yaml +++ b/mods/ra/mix/conquer.yaml @@ -28,7 +28,7 @@ agun.shp: agunmake.shp: apc.shp: apwr.shp: -apwramke.shp: +apwrmake.shp: armor.shp: art-exp1.shp: arty.shp: @@ -39,7 +39,7 @@ atomicup.shp: atomsfx.shp: badr.shp: bar3bhr.shp: -bar3blue.shp: +bar3blu.shp: bar3red.shp: bar3rhr.shp: barb.shp: From 2762c245ee4c1e109e380a04ae0c6e5e660a8ea2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Sun, 28 Apr 2013 20:45:03 +0200 Subject: [PATCH 07/11] fix Makefile OpenRA.Mods.RA.dll now depends on the Utility.exe --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 45c4733b64..343d413e01 100644 --- a/Makefile +++ b/Makefile @@ -93,8 +93,8 @@ STD_MOD_DEPS = $(STD_MOD_LIBS) $(ralint_TARGET) mod_ra_SRCS := $(shell find OpenRA.Mods.RA/ -iname '*.cs') mod_ra_TARGET = mods/ra/OpenRA.Mods.RA.dll mod_ra_KIND = library -mod_ra_DEPS = $(STD_MOD_DEPS) -mod_ra_LIBS = $(COMMON_LIBS) $(STD_MOD_LIBS) +mod_ra_DEPS = $(STD_MOD_DEPS) $(utility_TARGET) +mod_ra_LIBS = $(COMMON_LIBS) $(STD_MOD_LIBS) $(utility_TARGET) mod_ra_EXTRA_CMDS = mono --debug RALint.exe ra PROGRAMS += mod_ra mod_ra: $(mod_ra_TARGET) From f14441d2f4dc9acf1f5a8b3fb28030db6dec5133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Mon, 29 Apr 2013 09:39:46 +0200 Subject: [PATCH 08/11] added MinimumThumbSize to ScrollPanelWidget closes #2865 --- OpenRA.Game/Widgets/ScrollPanelWidget.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/OpenRA.Game/Widgets/ScrollPanelWidget.cs b/OpenRA.Game/Widgets/ScrollPanelWidget.cs index b227547bb2..b88c15b112 100644 --- a/OpenRA.Game/Widgets/ScrollPanelWidget.cs +++ b/OpenRA.Game/Widgets/ScrollPanelWidget.cs @@ -26,6 +26,7 @@ namespace OpenRA.Widgets public string Background = "scrollpanel-bg"; public int ContentHeight = 0; public ILayout Layout; + public int MinimumThumbSize = 10; protected float ListOffset = 0; protected bool UpPressed = false; protected bool DownPressed = false; @@ -79,7 +80,7 @@ namespace OpenRA.Widgets var ScrollbarHeight = rb.Height - 2 * ScrollbarWidth; - var thumbHeight = ContentHeight == 0 ? 0 : (int)(ScrollbarHeight*Math.Min(rb.Height*1f/ContentHeight, 1f)); + var thumbHeight = ContentHeight == 0 ? 0 : Math.Max(MinimumThumbSize, (int)(ScrollbarHeight*Math.Min(rb.Height*1f/ContentHeight, 1f))); var thumbOrigin = rb.Y + ScrollbarWidth + (int)((ScrollbarHeight - thumbHeight)*(-1f*ListOffset/(ContentHeight - rb.Height))); if (thumbHeight == ScrollbarHeight) thumbHeight = 0; @@ -206,7 +207,7 @@ namespace OpenRA.Widgets { var rb = RenderBounds; var ScrollbarHeight = rb.Height - 2 * ScrollbarWidth; - var thumbHeight = ContentHeight == 0 ? 0 : (int)(ScrollbarHeight*Math.Min(rb.Height*1f/ContentHeight, 1f)); + var thumbHeight = ContentHeight == 0 ? 0 : Math.Max(MinimumThumbSize, (int)(ScrollbarHeight*Math.Min(rb.Height*1f/ContentHeight, 1f))); var oldOffset = ListOffset; ListOffset += (int)((lastMouseLocation.Y - mi.Location.Y)*(ContentHeight - rb.Height)*1f/(ScrollbarHeight - thumbHeight)); ListOffset = Math.Min(0,Math.Max(rb.Height - ContentHeight, ListOffset)); From 8f822f6cad0c418b9c473ded8024e5f3449acc9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Mon, 29 Apr 2013 10:03:15 +0200 Subject: [PATCH 09/11] game asset browser UI polishing - display file extension - show total frame count - dark background for preview --- .../Widgets/Logic/AssetBrowserLogic.cs | 19 ++++++++++--------- mods/ra/chrome/assetbrowser.yaml | 12 +++++++----- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs index 61a7c060dc..aadc21c521 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs @@ -49,8 +49,8 @@ namespace OpenRA.Mods.RA.Widgets.Logic spriteImage = panel.Get("SPRITE"); filenameInput = panel.Get("FILENAME_INPUT"); - filenameInput.Text = spriteImage.Image; - filenameInput.OnEnterKey = () => LoadAsset(filenameInput.Text); + filenameInput.Text = spriteImage.Image+".shp"; + filenameInput.OnEnterKey = () => LoadAsset(Path.GetFileNameWithoutExtension(filenameInput.Text)); frameSlider = panel.Get("FRAME_SLIDER"); frameSlider.MaximumValue = (float)spriteImage.FrameCount; @@ -58,7 +58,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic frameSlider.OnChange += x => { spriteImage.Frame = (int)Math.Round(x); }; frameSlider.GetValue = () => spriteImage.Frame; - panel.Get("FRAME_COUNT").GetText = () => spriteImage.Frame.ToString(); + panel.Get("FRAME_COUNT").GetText = () => "{0}/{1}".F(spriteImage.Frame, spriteImage.FrameCount); playButton = panel.Get("BUTTON_PLAY"); playButton.OnClick = () => @@ -89,7 +89,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic panel.Get("LOAD_BUTTON").OnClick = () => { - LoadAsset(filenameInput.Text); + LoadAsset(Path.GetFileNameWithoutExtension(filenameInput.Text)); }; assetList = panel.Get("ASSET_LIST"); @@ -151,23 +151,24 @@ namespace OpenRA.Mods.RA.Widgets.Logic static void AddAsset(ScrollPanelWidget list, string filepath, ScrollItemWidget template) { var sprite = Path.GetFileNameWithoutExtension(filepath); + var filename = Path.GetFileName(filepath); var item = ScrollItemWidget.Setup(template, () => spriteImage != null && spriteImage.Image == sprite, () => LoadAsset(sprite)); - item.Get("TITLE").GetText = () => sprite; + item.Get("TITLE").GetText = () => filename; list.AddChild(item); } - static bool LoadAsset(string filename) + static bool LoadAsset(string sprite) { - if (filename == null) + if (sprite == null) return false; - filenameInput.Text = filename; + filenameInput.Text = sprite+".shp"; spriteImage.Frame = 0; - spriteImage.Image = filename; + spriteImage.Image = sprite; frameSlider.MaximumValue = (float)spriteImage.FrameCount; frameSlider.Ticks = spriteImage.FrameCount+1; return true; diff --git a/mods/ra/chrome/assetbrowser.yaml b/mods/ra/chrome/assetbrowser.yaml index fbb639cf1f..25c4f13fc2 100644 --- a/mods/ra/chrome/assetbrowser.yaml +++ b/mods/ra/chrome/assetbrowser.yaml @@ -56,16 +56,17 @@ Background@ASSETBROWSER_BG: Width:PARENT_RIGHT Height:25 Text:Preview + Font:Bold Background@SPRITE_BG: X:220 Y:80 Width:250 Height:250 - Background:dialog3 + Background:dialog4 Children: ShpImage@SPRITE: - X:80 - Y:80 + X:4 + Y:4 Width:246 Height:246 Image:mouse @@ -76,6 +77,7 @@ Background@ASSETBROWSER_BG: Width:PARENT_RIGHT Height:25 Text:Actions + Font:Bold Button@REMAP_BUTTON: X:PARENT_RIGHT - 200 Y:PARENT_BOTTOM - 305 @@ -185,13 +187,13 @@ Background@ASSETBROWSER_BG: ImageCollection:music ImageName:next Slider@FRAME_SLIDER: - X:175 + X:160 Y:0 Width:410 Height:20 MinimumValue: 0 Label@FRAME_COUNT: - X:610 + X:585 Y:0 Width:25 Height:25 From 6262aa846f38ea326aad5133a6f246d29980644a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Mon, 29 Apr 2013 11:58:45 +0200 Subject: [PATCH 10/11] wire up the import from PNG to SHP button store everything in user directory to not junk up the game and for file permissions on Mac/Linux when installed --- OpenRA.Mods.RA/OpenRA.Mods.RA.csproj | 2 +- .../Widgets/Logic/AssetBrowserLogic.cs | 51 +++++++++++++++---- ...FilesLogic.cs => ConvertGameFilesLogic.cs} | 29 ++++++++--- OpenRA.Utility/Command.cs | 27 ++++++---- OpenRA.Utility/Program.cs | 2 +- mods/d2k/mod.yaml | 2 +- mods/ra/chrome/assetbrowser.yaml | 33 ++++++------ ...{extractassets.yaml => convertassets.yaml} | 4 +- mods/ra/mod.yaml | 2 +- 9 files changed, 101 insertions(+), 51 deletions(-) rename OpenRA.Mods.RA/Widgets/Logic/{ExtractGameFilesLogic.cs => ConvertGameFilesLogic.cs} (73%) rename mods/ra/chrome/{extractassets.yaml => convertassets.yaml} (92%) diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 5d1a147e5a..cc11db4350 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -437,7 +437,7 @@ - + diff --git a/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs index aadc21c521..a2823f9405 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs @@ -102,22 +102,25 @@ namespace OpenRA.Mods.RA.Widgets.Logic { var ExtractGameFiles = new string[][] { - new string[] {"--extract", WidgetUtils.ActiveModId(), palette}, - new string[] {"--extract", WidgetUtils.ActiveModId(), "{0}.shp".F(spriteImage.Image)}, + new string[] {"--extract", WidgetUtils.ActiveModId(), palette, "--userdir"}, + new string[] {"--extract", WidgetUtils.ActiveModId(), "{0}.shp".F(spriteImage.Image), "--userdir"}, }; var ExportToPng = new string[][] { - new string[] {"--png", "{0}.shp".F(spriteImage.Image), palette}, + new string[] {"--png", Platform.SupportDir+"{0}.shp".F(spriteImage.Image), Platform.SupportDir+palette}, }; + var ImportFromPng = new string[][] { }; + var args = new WidgetArgs() { { "ExtractGameFiles", ExtractGameFiles }, - { "ExportToPng", ExportToPng } + { "ExportToPng", ExportToPng }, + { "ImportFromPng", ImportFromPng} }; - Ui.OpenWindow("EXTRACT_ASSETS_PANEL", args); + Ui.OpenWindow("CONVERT_ASSETS_PANEL", args); }; panel.Get("EXTRACT_BUTTON").OnClick = () => @@ -125,24 +128,50 @@ namespace OpenRA.Mods.RA.Widgets.Logic var ExtractGameFilesList = new List(); var ExportToPngList = new List(); - ExtractGameFilesList.Add(new string[] { "--extract", WidgetUtils.ActiveModId(), palette} ); + ExtractGameFilesList.Add(new string[] { "--extract", WidgetUtils.ActiveModId(), palette, "--userdir"} ); foreach (var shp in AvailableShps) { - ExtractGameFilesList.Add(new string[] { "--extract", WidgetUtils.ActiveModId(), shp } ); - ExportToPngList.Add(new string[] { "--png", shp, palette } ); + ExtractGameFilesList.Add(new string[] { "--extract", WidgetUtils.ActiveModId(), shp, "--userdir" } ); + ExportToPngList.Add(new string[] { "--png", Platform.SupportDir+shp, Platform.SupportDir+palette } ); + Console.WriteLine(Platform.SupportDir+shp); } var ExtractGameFiles = ExtractGameFilesList.ToArray(); var ExportToPng = ExportToPngList.ToArray(); + var ImportFromPng = new string[][] { }; var args = new WidgetArgs() { { "ExtractGameFiles", ExtractGameFiles }, - { "ExportToPng", ExportToPng } + { "ExportToPng", ExportToPng }, + { "ImportFromPng", ImportFromPng} }; - Ui.OpenWindow("EXTRACT_ASSETS_PANEL", args); + Ui.OpenWindow("CONVERT_ASSETS_PANEL", args); + }; + + + panel.Get("IMPORT_BUTTON").OnClick = () => + { + var imageSizeInput = panel.Get("IMAGE_SIZE_INPUT"); + var imageFilename = panel.Get("IMAGE_FILENAME_INPUT"); + + var ExtractGameFiles = new string[][] { }; + var ExportToPng = new string[][] { }; + var ImportFromPng = new string[][] + { + new string[] {"--shp", Platform.SupportDir+imageFilename.Text, imageSizeInput.Text}, + }; + + var args = new WidgetArgs() + { + { "ExtractGameFiles", ExtractGameFiles }, + { "ExportToPng", ExportToPng }, + { "ImportFromPng", ImportFromPng} + }; + + Ui.OpenWindow("CONVERT_ASSETS_PANEL", args); }; panel.Get("CLOSE_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); }; @@ -210,7 +239,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic foreach (var shp in shps) { AddAsset(assetList, shp, template); - AvailableShps.Add(shp); + AvailableShps.Add(Path.GetFileName(shp)); } } } diff --git a/OpenRA.Mods.RA/Widgets/Logic/ExtractGameFilesLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ConvertGameFilesLogic.cs similarity index 73% rename from OpenRA.Mods.RA/Widgets/Logic/ExtractGameFilesLogic.cs rename to OpenRA.Mods.RA/Widgets/Logic/ConvertGameFilesLogic.cs index 0acdb3293d..8c1f537a9d 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/ExtractGameFilesLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/ConvertGameFilesLogic.cs @@ -20,7 +20,7 @@ using OpenRA.Utility; namespace OpenRA.Mods.RA.Widgets.Logic { - public class ExtractGameFilesLogic + public class ConvertGameFilesLogic { Widget panel; ProgressBarWidget progressBar; @@ -28,12 +28,12 @@ namespace OpenRA.Mods.RA.Widgets.Logic ButtonWidget retryButton, backButton; Widget extractingContainer; - string[][] ExtractGameFiles, ExportToPng; + string[][] ExtractGameFiles, ExportToPng, ImportFromPng; [ObjectCreator.UseCtor] - public ExtractGameFilesLogic(Widget widget, string[][] ExtractGameFiles, string[][] ExportToPng) + public ConvertGameFilesLogic(Widget widget, string[][] ExtractGameFiles, string[][] ExportToPng, string[][] ImportFromPng) { - panel = widget.Get("EXTRACT_ASSETS_PANEL"); + panel = widget.Get("CONVERT_ASSETS_PANEL"); progressBar = panel.Get("PROGRESS_BAR"); statusLabel = panel.Get("STATUS_LABEL"); @@ -47,6 +47,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic this.ExtractGameFiles = ExtractGameFiles; this.ExportToPng = ExportToPng; + this.ImportFromPng = ImportFromPng; Extract(); } @@ -78,21 +79,33 @@ namespace OpenRA.Mods.RA.Widgets.Logic for (int i = 0; i < ExportToPng.Length; i++) { progressBar.Percentage = i*100/ExportToPng.Count(); - statusLabel.GetText = () => "Converting..."; + statusLabel.GetText = () => "Exporting SHP to PNG..."; Utility.Command.ConvertShpToPng(ExportToPng[i]); } + for (int i = 0; i < ImportFromPng.Length; i++) + { + progressBar.Percentage = i*100/ImportFromPng.Count(); + statusLabel.GetText = () => "Converting PNG to SHP..."; + Utility.Command.ConvertPngToShp(ImportFromPng[i]); + } + Game.RunAfterTick(() => { progressBar.Percentage = 100; - statusLabel.GetText = () => "Extraction and conversion complete."; + statusLabel.GetText = () => "Done. Check {0}".F(Platform.SupportDir); backButton.IsDisabled = () => false; }); } - catch + catch (FileNotFoundException f) { - onError("Extraction or conversion failed"); + onError(f.FileName+" not found."); } + catch (Exception e) + { + onError(e.Message); + } + }) { IsBackground = true }; t.Start(); } diff --git a/OpenRA.Utility/Command.cs b/OpenRA.Utility/Command.cs index 82f321abad..15d9611fb6 100644 --- a/OpenRA.Utility/Command.cs +++ b/OpenRA.Utility/Command.cs @@ -55,7 +55,7 @@ namespace OpenRA.Utility ShpWriter.Write(destStream, width, srcImage.Height, srcImage.ToFrames(width)); - Console.WriteLine(dest+" saved"); + Console.WriteLine(dest+" saved."); } static IEnumerable ToFrames(this Bitmap bitmap, int width) @@ -108,10 +108,11 @@ namespace OpenRA.Utility x += srcImage.Width; - bitmap.UnlockBits( data ); + bitmap.UnlockBits(data); } bitmap.Save(dest); + Console.WriteLine(dest+" saved"); } } @@ -348,8 +349,8 @@ namespace OpenRA.Utility if (template.Value == null) throw new InvalidOperationException("No such template '{0}'".F(templateName)); - using( var image = tileset.RenderTemplate(template.Value.Id, palette) ) - image.Save( Path.ChangeExtension( templateName, ".png" ) ); + using (var image = tileset.RenderTemplate(template.Value.Id, palette)) + image.Save(Path.ChangeExtension(templateName, ".png")); } } @@ -359,17 +360,17 @@ namespace OpenRA.Utility var dest = args[2]; Dune2ShpReader srcImage = null; - using( var s = File.OpenRead( src ) ) + using(var s = File.OpenRead(src)) srcImage = new Dune2ShpReader(s); var size = srcImage.First().Size; - if (!srcImage.All( im => im.Size == size )) + if (!srcImage.All(im => im.Size == size)) throw new InvalidOperationException("All the frames must be the same size to convert from Dune2 to RA"); - using( var destStream = File.Create(dest) ) + using (var destStream = File.Create(dest)) ShpWriter.Write(destStream, size.Width, size.Height, - srcImage.Select( im => im.Image )); + srcImage.Select(im => im.Image)); } public static void ExtractFiles(string[] args) @@ -380,14 +381,18 @@ namespace OpenRA.Utility var manifest = new Manifest(mods); FileSystem.LoadFromManifest(manifest); - foreach( var f in files ) + foreach (var f in files) { + if (f == "--userdir") + break; + var src = FileSystem.Open(f); if (src == null) throw new InvalidOperationException("File not found: {0}".F(f)); var data = src.ReadAllBytes(); - - File.WriteAllBytes( f, data ); + var output = args.Contains("--userdir") ? Platform.SupportDir+f : f; + File.WriteAllBytes(output, data); + Console.WriteLine(output+" saved."); } } diff --git a/OpenRA.Utility/Program.cs b/OpenRA.Utility/Program.cs index 7fae4fb735..d891ef2218 100644 --- a/OpenRA.Utility/Program.cs +++ b/OpenRA.Utility/Program.cs @@ -60,7 +60,7 @@ namespace OpenRA.Utility Console.WriteLine(" --shp PNGFILE FRAMEWIDTH Convert a single PNG with multiple frames appended after another to a SHP"); Console.WriteLine(" --png SHPFILE PALETTE [--noshadow] Convert a SHP to a PNG containing all of its frames, optionally removing the shadow"); Console.WriteLine(" --fromd2 DUNE2SHP C&CSHP Convert a Dune II SHP (C&C mouse cursor) to C&C SHP format."); - Console.WriteLine(" --extract MOD[,MOD]* FILES Extract files from mod packages"); + Console.WriteLine(" --extract MOD[,MOD]* FILES [--userdir] Extract files from mod packages to the current (or user) directory"); Console.WriteLine(" --tmp-png MOD[,MOD]* THEATER FILES Extract terrain tiles to PNG"); Console.WriteLine(" --remap SRCMOD:PAL DESTMOD:PAL SRCSHP DESTSHP Remap SHPs to another palette"); Console.WriteLine(" --r8 R8FILE PALETTE START END FILENAME [--noshadow] [--infrantry] [--vehicle] [--projectile] [--building] [--wall] [--tileset] Convert Dune 2000 DATA.R8 to PNGs choosing start- and endframe as well as type for correct offset to append multiple frames to one PNG named by filename optionally removing the shadow."); diff --git a/mods/d2k/mod.yaml b/mods/d2k/mod.yaml index 22ce2ee495..dbebb7c280 100644 --- a/mods/d2k/mod.yaml +++ b/mods/d2k/mod.yaml @@ -69,7 +69,7 @@ ChromeLayout: mods/ra/chrome/musicplayer.yaml mods/d2k/chrome/tooltips.yaml mods/ra/chrome/assetbrowser.yaml - mods/ra/chrome/extractassets.yaml + mods/ra/chrome/convertassets.yaml Weapons: mods/d2k/weapons/defaults.yaml diff --git a/mods/ra/chrome/assetbrowser.yaml b/mods/ra/chrome/assetbrowser.yaml index 25c4f13fc2..fb77ec748c 100644 --- a/mods/ra/chrome/assetbrowser.yaml +++ b/mods/ra/chrome/assetbrowser.yaml @@ -78,35 +78,38 @@ Background@ASSETBROWSER_BG: Height:25 Text:Actions Font:Bold - Button@REMAP_BUTTON: + Button@EXPORT_BUTTON: X:PARENT_RIGHT - 200 - Y:PARENT_BOTTOM - 305 + Y:80 Width:160 Height:25 - Text:Change Palette + Text:Selected to PNG Font:Bold - Disabled: yes - Button@IMPORT_BUTTON: - X:PARENT_RIGHT - 200 - Y:PARENT_BOTTOM - 270 - Width:160 - Height:25 - Text:Import from PNG - Font:Bold - Disabled: yes Button@EXTRACT_BUTTON: X:PARENT_RIGHT - 200 - Y:PARENT_BOTTOM - 235 + Y:115 Width:160 Height:25 Text:Extract all to PNG Font:Bold - Button@EXPORT_BUTTON: + TextField@IMAGE_FILENAME_INPUT: + X:PARENT_RIGHT - 200 + Y:PARENT_BOTTOM - 235 + Width:100 + Height:25 + Text:pixelart.png + TextField@IMAGE_SIZE_INPUT: + X:PARENT_RIGHT - 90 + Y:PARENT_BOTTOM - 235 + Width:50 + Height:25 + Text:width + Button@IMPORT_BUTTON: X:PARENT_RIGHT - 200 Y:PARENT_BOTTOM - 200 Width:160 Height:25 - Text:Selected to PNG + Text:Import from PNG Font:Bold Button@CLOSE_BUTTON: X:PARENT_RIGHT - 200 diff --git a/mods/ra/chrome/extractassets.yaml b/mods/ra/chrome/convertassets.yaml similarity index 92% rename from mods/ra/chrome/extractassets.yaml rename to mods/ra/chrome/convertassets.yaml index 199eb7a06b..ecd4cc73af 100644 --- a/mods/ra/chrome/extractassets.yaml +++ b/mods/ra/chrome/convertassets.yaml @@ -1,5 +1,5 @@ -Background@EXTRACT_ASSETS_PANEL: - Logic:ExtractGameFilesLogic +Background@CONVERT_ASSETS_PANEL: + Logic:ConvertGameFilesLogic X:(WINDOW_RIGHT - WIDTH)/2 Y:(WINDOW_BOTTOM - HEIGHT)/2 Width:500 diff --git a/mods/ra/mod.yaml b/mods/ra/mod.yaml index 2af52f08d0..76cb2a1749 100644 --- a/mods/ra/mod.yaml +++ b/mods/ra/mod.yaml @@ -78,7 +78,7 @@ ChromeLayout: mods/ra/chrome/musicplayer.yaml mods/ra/chrome/tooltips.yaml mods/ra/chrome/assetbrowser.yaml - mods/ra/chrome/extractassets.yaml + mods/ra/chrome/convertassets.yaml Weapons: mods/ra/weapons.yaml From 2d1bc7bac8a9b8d4959649e4bbe13abd707e4a25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Wed, 1 May 2013 20:18:11 +0200 Subject: [PATCH 11/11] adapt asset browser for R8 files --- OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs index a2823f9405..91da7972ee 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs @@ -50,7 +50,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic filenameInput = panel.Get("FILENAME_INPUT"); filenameInput.Text = spriteImage.Image+".shp"; - filenameInput.OnEnterKey = () => LoadAsset(Path.GetFileNameWithoutExtension(filenameInput.Text)); + filenameInput.OnEnterKey = () => LoadAsset(filenameInput.Text); frameSlider = panel.Get("FRAME_SLIDER"); frameSlider.MaximumValue = (float)spriteImage.FrameCount; @@ -89,7 +89,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic panel.Get("LOAD_BUTTON").OnClick = () => { - LoadAsset(Path.GetFileNameWithoutExtension(filenameInput.Text)); + LoadAsset(filenameInput.Text); }; assetList = panel.Get("ASSET_LIST"); @@ -195,7 +195,12 @@ namespace OpenRA.Mods.RA.Widgets.Logic if (sprite == null) return false; - filenameInput.Text = sprite+".shp"; + if (!sprite.ToLower().Contains("r8")) + { + filenameInput.Text = sprite+".shp"; + sprite = Path.GetFileNameWithoutExtension(sprite); + } + spriteImage.Frame = 0; spriteImage.Image = sprite; frameSlider.MaximumValue = (float)spriteImage.FrameCount;