Merge pull request #3192 from Mailaender/asset-browser
Created an Asset Browser to view and convert Sprites
This commit is contained in:
4
Makefile
4
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)
|
||||
|
||||
@@ -18,19 +18,21 @@ namespace OpenRA.FileFormats
|
||||
{
|
||||
public static class FileSystem
|
||||
{
|
||||
static List<IFolder> mountedFolders = new List<IFolder>();
|
||||
static List<IFolder> MountedFolders = new List<IFolder>();
|
||||
|
||||
static Cache<uint, List<IFolder>> allFiles = new Cache<uint, List<IFolder>>( _ => new List<IFolder>() );
|
||||
|
||||
public static List<string> FolderPaths = new List<string>();
|
||||
|
||||
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<uint, List<IFolder>>( _ => new List<IFolder>() );
|
||||
}
|
||||
|
||||
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<uint, List<IFolder>> index, string filename )
|
||||
static Stream GetFromCache(Cache<uint, List<IFolder>> 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<string, Assembly> assemblyCache = new Dictionary<string, Assembly>();
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<string, Pair<string,int>> 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,
|
||||
|
||||
@@ -238,7 +238,7 @@ namespace OpenRA
|
||||
|
||||
public static Dictionary<String, Mod> 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;
|
||||
|
||||
@@ -25,6 +25,7 @@ namespace OpenRA
|
||||
public static Dictionary<string, MusicInfo> Music;
|
||||
public static Dictionary<string, string> Movies;
|
||||
public static Dictionary<string, TileSet> TileSets;
|
||||
public static Dictionary<string, string> 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<MiniYamlNode>(), (k, _) => new MusicInfo(k.Key, k.Value));
|
||||
Movies = LoadYamlRules(m.Movies, new List<MiniYamlNode>(), (k, v) => k.Value.Value);
|
||||
PackageContents = LoadYamlRules(m.PackageContents, new List<MiniYamlNode>(), (k, v) => k.Value.Value);
|
||||
|
||||
TileSets = new Dictionary<string, TileSet>();
|
||||
foreach (var file in m.TileSets)
|
||||
@@ -46,7 +48,7 @@ namespace OpenRA
|
||||
|
||||
static Dictionary<string, T> LoadYamlRules<T>(string[] files, List<MiniYamlNode> dict, Func<MiniYamlNode, Dictionary<string, MiniYaml>, 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));
|
||||
}
|
||||
|
||||
@@ -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<string, Sprite[]>( LoadSprites );
|
||||
sprites = new Cache<string, Sprite[]>(LoadSprites);
|
||||
}
|
||||
|
||||
readonly SheetBuilder SheetBuilder;
|
||||
|
||||
@@ -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<ILoadScreen>(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)
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace OpenRA.Widgets
|
||||
public string Image = "";
|
||||
public int Frame = 0;
|
||||
public string Palette = "chrome";
|
||||
public bool LoopAnimation = false;
|
||||
|
||||
public Func<string> GetImage;
|
||||
public Func<int> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,10 +24,15 @@ namespace OpenRA.Widgets
|
||||
public float MinimumValue = 0;
|
||||
public float MaximumValue = 1;
|
||||
public float Value = 0;
|
||||
public Func<float> 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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -436,6 +436,8 @@
|
||||
<Compile Include="Widgets\ColorMixerWidget.cs" />
|
||||
<Compile Include="Widgets\HueSliderWidget.cs" />
|
||||
<Compile Include="Render\WithTurret.cs" />
|
||||
<Compile Include="Widgets\Logic\AssetBrowserLogic.cs" />
|
||||
<Compile Include="Widgets\Logic\ConvertGameFilesLogic.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
|
||||
@@ -448,6 +450,10 @@
|
||||
<Name>OpenRA.Game</Name>
|
||||
<Private>False</Private>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\OpenRA.Utility\OpenRA.Utility.csproj">
|
||||
<Project>{F33337BE-CB69-4B24-850F-07D23E408DDF}</Project>
|
||||
<Name>OpenRA.Utility</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
|
||||
261
OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs
Normal file
261
OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs
Normal file
@@ -0,0 +1,261 @@
|
||||
#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.Collections.Generic;
|
||||
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;
|
||||
|
||||
static ShpImageWidget spriteImage;
|
||||
static TextFieldWidget filenameInput;
|
||||
static SliderWidget frameSlider;
|
||||
static ButtonWidget playButton, pauseButton;
|
||||
static ScrollPanelWidget assetList;
|
||||
static ScrollItemWidget template;
|
||||
|
||||
public enum SourceType { Folders, Packages }
|
||||
public static SourceType AssetSource = SourceType.Folders;
|
||||
|
||||
public static List<string> AvailableShps = new List<string>();
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public AssetBrowserLogic(Widget widget, Action onExit, World world)
|
||||
{
|
||||
panel = widget;
|
||||
|
||||
var sourceDropdown = panel.Get<DropDownButtonWidget>("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<ShpImageWidget>("SPRITE");
|
||||
|
||||
filenameInput = panel.Get<TextFieldWidget>("FILENAME_INPUT");
|
||||
filenameInput.Text = spriteImage.Image+".shp";
|
||||
filenameInput.OnEnterKey = () => LoadAsset(filenameInput.Text);
|
||||
|
||||
frameSlider = panel.Get<SliderWidget>("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<LabelWidget>("FRAME_COUNT").GetText = () => "{0}/{1}".F(spriteImage.Frame, spriteImage.FrameCount);
|
||||
|
||||
playButton = panel.Get<ButtonWidget>("BUTTON_PLAY");
|
||||
playButton.OnClick = () =>
|
||||
{
|
||||
spriteImage.LoopAnimation = true;
|
||||
playButton.Visible = false;
|
||||
pauseButton.Visible = true;
|
||||
};
|
||||
pauseButton = panel.Get<ButtonWidget>("BUTTON_PAUSE");
|
||||
pauseButton.OnClick = () =>
|
||||
{
|
||||
spriteImage.LoopAnimation = false;
|
||||
playButton.Visible = true;
|
||||
pauseButton.Visible = false;
|
||||
};
|
||||
|
||||
panel.Get<ButtonWidget>("BUTTON_STOP").OnClick = () =>
|
||||
{
|
||||
spriteImage.LoopAnimation = false;
|
||||
frameSlider.Value = 0;
|
||||
spriteImage.Frame = 0;
|
||||
playButton.Visible = true;
|
||||
pauseButton.Visible = false;
|
||||
};
|
||||
|
||||
panel.Get<ButtonWidget>("BUTTON_NEXT").OnClick = () => { spriteImage.RenderNextFrame(); };
|
||||
panel.Get<ButtonWidget>("BUTTON_PREV").OnClick = () => { spriteImage.RenderPreviousFrame(); };
|
||||
|
||||
panel.Get<ButtonWidget>("LOAD_BUTTON").OnClick = () =>
|
||||
{
|
||||
LoadAsset(filenameInput.Text);
|
||||
};
|
||||
|
||||
assetList = panel.Get<ScrollPanelWidget>("ASSET_LIST");
|
||||
template = panel.Get<ScrollItemWidget>("ASSET_TEMPLATE");
|
||||
PopulateAssetList();
|
||||
|
||||
var palette = (WidgetUtils.ActiveModId() == "d2k") ? "d2k.pal" : "egopal.pal";
|
||||
|
||||
panel.Get<ButtonWidget>("EXPORT_BUTTON").OnClick = () =>
|
||||
{
|
||||
var ExtractGameFiles = new string[][]
|
||||
{
|
||||
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", Platform.SupportDir+"{0}.shp".F(spriteImage.Image), Platform.SupportDir+palette},
|
||||
};
|
||||
|
||||
var ImportFromPng = new string[][] { };
|
||||
|
||||
var args = new WidgetArgs()
|
||||
{
|
||||
{ "ExtractGameFiles", ExtractGameFiles },
|
||||
{ "ExportToPng", ExportToPng },
|
||||
{ "ImportFromPng", ImportFromPng}
|
||||
};
|
||||
|
||||
Ui.OpenWindow("CONVERT_ASSETS_PANEL", args);
|
||||
};
|
||||
|
||||
panel.Get<ButtonWidget>("EXTRACT_BUTTON").OnClick = () =>
|
||||
{
|
||||
var ExtractGameFilesList = new List<string[]>();
|
||||
var ExportToPngList = new List<string[]>();
|
||||
|
||||
ExtractGameFilesList.Add(new string[] { "--extract", WidgetUtils.ActiveModId(), palette, "--userdir"} );
|
||||
|
||||
foreach (var shp in AvailableShps)
|
||||
{
|
||||
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 },
|
||||
{ "ImportFromPng", ImportFromPng}
|
||||
};
|
||||
|
||||
Ui.OpenWindow("CONVERT_ASSETS_PANEL", args);
|
||||
};
|
||||
|
||||
|
||||
panel.Get<ButtonWidget>("IMPORT_BUTTON").OnClick = () =>
|
||||
{
|
||||
var imageSizeInput = panel.Get<TextFieldWidget>("IMAGE_SIZE_INPUT");
|
||||
var imageFilename = panel.Get<TextFieldWidget>("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<ButtonWidget>("CLOSE_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); };
|
||||
}
|
||||
|
||||
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<LabelWidget>("TITLE").GetText = () => filename;
|
||||
|
||||
list.AddChild(item);
|
||||
}
|
||||
|
||||
static bool LoadAsset(string sprite)
|
||||
{
|
||||
if (sprite == null)
|
||||
return false;
|
||||
|
||||
if (!sprite.ToLower().Contains("r8"))
|
||||
{
|
||||
filenameInput.Text = sprite+".shp";
|
||||
sprite = Path.GetFileNameWithoutExtension(sprite);
|
||||
}
|
||||
|
||||
spriteImage.Frame = 0;
|
||||
spriteImage.Image = sprite;
|
||||
frameSlider.MaximumValue = (float)spriteImage.FrameCount;
|
||||
frameSlider.Ticks = spriteImage.FrameCount+1;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ShowSourceDropdown(DropDownButtonWidget dropdown)
|
||||
{
|
||||
var options = new Dictionary<string, SourceType>()
|
||||
{
|
||||
{ "Folders", SourceType.Folders },
|
||||
{ "Packages", SourceType.Packages },
|
||||
};
|
||||
|
||||
Func<string, ScrollItemWidget, ScrollItemWidget> setupItem = (o, itemTemplate) =>
|
||||
{
|
||||
var item = ScrollItemWidget.Setup(itemTemplate,
|
||||
() => AssetSource == options[o],
|
||||
() => { AssetSource = options[o]; PopulateAssetList(); });
|
||||
item.Get<LabelWidget>("LABEL").GetText = () => o;
|
||||
return item;
|
||||
};
|
||||
|
||||
dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, options.Keys, setupItem);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void PopulateAssetList()
|
||||
{
|
||||
assetList.RemoveChildren();
|
||||
AvailableShps.Clear();
|
||||
|
||||
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);
|
||||
AvailableShps.Add(Path.GetFileName(shp));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (AssetSource == SourceType.Packages)
|
||||
foreach (var hiddenFile in Rules.PackageContents.Keys)
|
||||
{
|
||||
AddAsset(assetList, hiddenFile, template);
|
||||
AvailableShps.Add(hiddenFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
113
OpenRA.Mods.RA/Widgets/Logic/ConvertGameFilesLogic.cs
Normal file
113
OpenRA.Mods.RA/Widgets/Logic/ConvertGameFilesLogic.cs
Normal file
@@ -0,0 +1,113 @@
|
||||
#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 ConvertGameFilesLogic
|
||||
{
|
||||
Widget panel;
|
||||
ProgressBarWidget progressBar;
|
||||
LabelWidget statusLabel;
|
||||
ButtonWidget retryButton, backButton;
|
||||
Widget extractingContainer;
|
||||
|
||||
string[][] ExtractGameFiles, ExportToPng, ImportFromPng;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public ConvertGameFilesLogic(Widget widget, string[][] ExtractGameFiles, string[][] ExportToPng, string[][] ImportFromPng)
|
||||
{
|
||||
panel = widget.Get("CONVERT_ASSETS_PANEL");
|
||||
progressBar = panel.Get<ProgressBarWidget>("PROGRESS_BAR");
|
||||
statusLabel = panel.Get<LabelWidget>("STATUS_LABEL");
|
||||
|
||||
backButton = panel.Get<ButtonWidget>("BACK_BUTTON");
|
||||
backButton.OnClick = Ui.CloseWindow;
|
||||
|
||||
retryButton = panel.Get<ButtonWidget>("RETRY_BUTTON");
|
||||
retryButton.OnClick = Extract;
|
||||
|
||||
extractingContainer = panel.Get("EXTRACTING");
|
||||
|
||||
this.ExtractGameFiles = ExtractGameFiles;
|
||||
this.ExportToPng = ExportToPng;
|
||||
this.ImportFromPng = ImportFromPng;
|
||||
|
||||
Extract();
|
||||
}
|
||||
|
||||
void Extract()
|
||||
{
|
||||
backButton.IsDisabled = () => true;
|
||||
retryButton.IsDisabled = () => true;
|
||||
extractingContainer.IsVisible = () => true;
|
||||
|
||||
var onError = (Action<string>)(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 = () => "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 = () => "Done. Check {0}".F(Platform.SupportDir);
|
||||
backButton.IsDisabled = () => false;
|
||||
});
|
||||
}
|
||||
catch (FileNotFoundException f)
|
||||
{
|
||||
onError(f.FileName+" not found.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
onError(e.Message);
|
||||
}
|
||||
|
||||
}) { IsBackground = true };
|
||||
t.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<ButtonWidget>("MAINMENU_BUTTON_ASSET_BROWSER").OnClick = () =>
|
||||
{
|
||||
Menu = MenuType.None;
|
||||
Game.OpenWindow("ASSETBROWSER_BG", new WidgetArgs()
|
||||
{
|
||||
{ "onExit", () => Menu = MenuType.Main }
|
||||
});
|
||||
};
|
||||
|
||||
widget.Get<ButtonWidget>("MAINMENU_BUTTON_QUIT").OnClick = () => Game.Exit();
|
||||
}
|
||||
|
||||
|
||||
@@ -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<byte[]> 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.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -29,6 +29,8 @@ Packages:
|
||||
~scores2.mix
|
||||
~transit.mix
|
||||
|
||||
PackageContents:
|
||||
|
||||
Rules:
|
||||
mods/cnc/rules/defaults.yaml
|
||||
mods/cnc/rules/system.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:
|
||||
|
||||
@@ -21,6 +21,8 @@ Packages:
|
||||
~main.mix
|
||||
conquer.mix
|
||||
|
||||
PackageContents:
|
||||
|
||||
Rules:
|
||||
mods/d2k/rules/system.yaml
|
||||
mods/d2k/rules/defaults.yaml
|
||||
@@ -66,6 +68,9 @@ ChromeLayout:
|
||||
mods/ra/chrome/cheats.yaml
|
||||
mods/ra/chrome/musicplayer.yaml
|
||||
mods/d2k/chrome/tooltips.yaml
|
||||
mods/ra/chrome/assetbrowser.yaml
|
||||
mods/ra/chrome/convertassets.yaml
|
||||
|
||||
Weapons:
|
||||
mods/d2k/weapons/defaults.yaml
|
||||
mods/d2k/weapons/explosions.yaml
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
203
mods/ra/chrome/assetbrowser.yaml
Normal file
203
mods/ra/chrome/assetbrowser.yaml
Normal file
@@ -0,0 +1,203 @@
|
||||
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
|
||||
Font:Bold
|
||||
Background@SPRITE_BG:
|
||||
X:220
|
||||
Y:80
|
||||
Width:250
|
||||
Height:250
|
||||
Background:dialog4
|
||||
Children:
|
||||
ShpImage@SPRITE:
|
||||
X:4
|
||||
Y:4
|
||||
Width:246
|
||||
Height:246
|
||||
Image:mouse
|
||||
Palette:colorpicker
|
||||
Label@ACTIONS_TITLE:
|
||||
X:PARENT_RIGHT - 150
|
||||
Y:45
|
||||
Width:PARENT_RIGHT
|
||||
Height:25
|
||||
Text:Actions
|
||||
Font:Bold
|
||||
Button@EXPORT_BUTTON:
|
||||
X:PARENT_RIGHT - 200
|
||||
Y:80
|
||||
Width:160
|
||||
Height:25
|
||||
Text:Selected to PNG
|
||||
Font:Bold
|
||||
Button@EXTRACT_BUTTON:
|
||||
X:PARENT_RIGHT - 200
|
||||
Y:115
|
||||
Width:160
|
||||
Height:25
|
||||
Text:Extract all to PNG
|
||||
Font:Bold
|
||||
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:Import from 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:160
|
||||
Y:0
|
||||
Width:410
|
||||
Height:20
|
||||
MinimumValue: 0
|
||||
Label@FRAME_COUNT:
|
||||
X:585
|
||||
Y:0
|
||||
Width:25
|
||||
Height:25
|
||||
Font:Bold
|
||||
47
mods/ra/chrome/convertassets.yaml
Normal file
47
mods/ra/chrome/convertassets.yaml
Normal file
@@ -0,0 +1,47 @@
|
||||
Background@CONVERT_ASSETS_PANEL:
|
||||
Logic:ConvertGameFilesLogic
|
||||
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
|
||||
@@ -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:
|
||||
|
||||
227
mods/ra/mix/conquer.yaml
Normal file
227
mods/ra/mix/conquer.yaml
Normal file
@@ -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:
|
||||
apwrmake.shp:
|
||||
armor.shp:
|
||||
art-exp1.shp:
|
||||
arty.shp:
|
||||
atek.shp:
|
||||
atekmake.shp:
|
||||
atomicdn.shp:
|
||||
atomicup.shp:
|
||||
atomsfx.shp:
|
||||
badr.shp:
|
||||
bar3bhr.shp:
|
||||
bar3blu.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:
|
||||
135
mods/ra/mix/hires.yaml
Normal file
135
mods/ra/mix/hires.yaml
Normal file
@@ -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
|
||||
@@ -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
|
||||
@@ -73,6 +77,8 @@ ChromeLayout:
|
||||
mods/ra/chrome/cheats.yaml
|
||||
mods/ra/chrome/musicplayer.yaml
|
||||
mods/ra/chrome/tooltips.yaml
|
||||
mods/ra/chrome/assetbrowser.yaml
|
||||
mods/ra/chrome/convertassets.yaml
|
||||
|
||||
Weapons:
|
||||
mods/ra/weapons.yaml
|
||||
|
||||
Reference in New Issue
Block a user