Compare commits
9 Commits
d1593f38c5
...
d2960720bd
Author | SHA1 | Date |
---|---|---|
Adrian | d2960720bd | |
Adrian | e56d02ae18 | |
Adrian | e1af13f4a9 | |
Adrian | e580e0d8ed | |
Adrian | 11f9804f24 | |
Adrian | 01a1739496 | |
Adrian | 5a19ea7103 | |
Adrian | ad4bd15136 | |
Adrian | 621336afec |
|
@ -32,20 +32,19 @@
|
|||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="src\Program.cs" />
|
||||
<Compile Include="src\BaseCommand.cs" />
|
||||
<Compile Include="src\ExtractCommand.cs" />
|
||||
<Compile Include="src\ToJsonCommand.cs" />
|
||||
<Compile Include="src\FromJsonCommand.cs" />
|
||||
<Compile Include="src\CompressCommand.cs" />
|
||||
<Compile Include="src\DecompressCommand.cs" />
|
||||
<Compile Include="src\DumpunitsCommand.cs" />
|
||||
<Compile Include="src\CopymapConverter.cs" />
|
||||
<Compile Include="src\ConvertCommand.cs" />
|
||||
<Compile Include="src\AddBitmapCommand.cs" />
|
||||
<Compile Include="src\DelBitmapCommand.cs" />
|
||||
<Compile Include="src\PackCommand.cs" />
|
||||
<Compile Include="src\Bmp2MapCommand.cs" />
|
||||
<Compile Include="src\BitmapHelpers.cs" />
|
||||
<Compile Include="src\ConvertCommandHelper.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
|
@ -66,12 +65,11 @@
|
|||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Web.Extensions" />
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
using System.IO;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using AdrianKousz.Util;
|
||||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public class AddBitmapCommand : BaseCommand
|
||||
public class AddBitmapCommand : CmdApp.Command
|
||||
{
|
||||
override public void Run()
|
||||
override public void Run(string[] args)
|
||||
{
|
||||
using (var input = File.OpenRead(args[0]))
|
||||
using (var output = File.OpenWrite(args[1]))
|
||||
|
@ -23,20 +22,11 @@ namespace AdrianKousz.GenieEngine
|
|||
GenieFile.Serialize(scn, output);
|
||||
}
|
||||
}
|
||||
|
||||
override public int GetArgumentCount()
|
||||
public AddBitmapCommand()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
override public string GetDescription()
|
||||
{
|
||||
return "Add a pregame bitmap";
|
||||
}
|
||||
|
||||
override public string GetHelp()
|
||||
{
|
||||
return "Add a pregame bitmap to a scenario."
|
||||
MinArgumentCount = 3;
|
||||
Description = "Add a pregame bitmap";
|
||||
Help = "Add a pregame bitmap to a scenario."
|
||||
+ "\nThe bitmap has to be indexed, otherwise, the game will probably crash."
|
||||
+ "\nAdditionally, a game-specific palette will be used to display the image."
|
||||
+ "\n"
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
using System;
|
||||
using AdrianKousz.Util;
|
||||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public class BaseCommand : ICommand<string[]>
|
||||
{
|
||||
protected string[] args;
|
||||
|
||||
virtual public string GetDescription()
|
||||
{
|
||||
return "(Empty description)";
|
||||
}
|
||||
|
||||
virtual public string GetHelp()
|
||||
{
|
||||
return "(Empty help text)";
|
||||
}
|
||||
|
||||
virtual public int GetArgumentCount()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual public void SetArguments(string[] args)
|
||||
{
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
virtual public void Run()
|
||||
{
|
||||
foreach (var str in args)
|
||||
Console.WriteLine(str);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,25 +9,24 @@ namespace AdrianKousz.GenieEngine
|
|||
{
|
||||
public static class BitmapHelpers
|
||||
{
|
||||
public static unsafe void FillMap(Scenario scn, Bitmap bmp, Bitmap bmp2)
|
||||
public static unsafe void FillMap(Scenario scn, Bitmap bmp1, Bitmap bmp2)
|
||||
{
|
||||
using (var ubmp = new UnsafeBitmap(bmp))
|
||||
using (var ubmp1 = new UnsafeBitmap(bmp1))
|
||||
using (var ubmp2 = new UnsafeBitmap(bmp2))
|
||||
{
|
||||
var factory = new ScnDefaultFactory();
|
||||
|
||||
Check(ubmp);
|
||||
Check(ubmp2);
|
||||
EnsureValid(ubmp1, ubmp2);
|
||||
|
||||
var ptr = ubmp.Scan0;
|
||||
var last = ptr + ubmp.Stride * ubmp.Height;
|
||||
var ptr1 = ubmp1.Scan0;
|
||||
var last1 = ptr1 + ubmp1.Stride * ubmp1.Height;
|
||||
|
||||
var ptr2 = ubmp2.Scan0;
|
||||
var last2 = ptr2 + ubmp2.Stride * ubmp2.Height;
|
||||
|
||||
var map = factory.MakeMap();
|
||||
map.SizeX = ubmp.Width;
|
||||
map.SizeY = ubmp.Height;
|
||||
map.SizeX = ubmp1.Width;
|
||||
map.SizeY = ubmp1.Height;
|
||||
map.LinearTiles = new Scenario.ScnMap.Tile[map.SizeX * map.SizeY];
|
||||
|
||||
var gaiaunits = new List<Scenario.ScnUnit>();
|
||||
|
@ -41,26 +40,37 @@ namespace AdrianKousz.GenieEngine
|
|||
treemapping[20] = 349;
|
||||
|
||||
var i = 0;
|
||||
while (ptr < last && ptr2 < last2) {
|
||||
var treeid = treemapping[*ptr];
|
||||
var id = 0;
|
||||
while (ptr1 < last1 && ptr2 < last2) {
|
||||
var treeid = treemapping[*ptr1];
|
||||
if (treeid != 0) {
|
||||
var unit = factory.MakeUnit();
|
||||
var posy = i / map.SizeX;
|
||||
var posx = i - (posy * map.SizeX);
|
||||
unit.Id = id++;
|
||||
unit.UnitId = treeid;
|
||||
unit.PosX = posx + 0.5f;
|
||||
unit.PosY = posy + 0.5f;
|
||||
unit.Rotation = (short)Util.Math.Rand(0, 13);
|
||||
unit.Rotation = unit.InitialFrame = (short)Util.Math.Rand(0, 14);
|
||||
gaiaunits.Add(unit);
|
||||
}
|
||||
map.LinearTiles[i++] = new Scenario.ScnMap.Tile(*ptr++, (byte)(*ptr2++ / 37), 0);
|
||||
map.LinearTiles[i++] = new Scenario.ScnMap.Tile(*ptr1++, (byte)(*ptr2++ / 40), 0);
|
||||
}
|
||||
|
||||
scn.NextId = id;
|
||||
scn.Map = map;
|
||||
scn.Units[0] = gaiaunits;
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnsureValid(UnsafeBitmap ubmp1, UnsafeBitmap ubmp2)
|
||||
{
|
||||
if (ubmp1.Width != ubmp2.Width || ubmp1.Height != ubmp2.Height)
|
||||
throw new ArgumentException("Bitmaps have unequal dimensions");
|
||||
Check(ubmp1);
|
||||
Check(ubmp2);
|
||||
}
|
||||
|
||||
private static void Check(UnsafeBitmap ubmp)
|
||||
{
|
||||
if (ubmp.PixelFormat != PixelFormat.Format8bppIndexed)
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.IO;
|
||||
using System.Drawing;
|
||||
using AdrianKousz.Util;
|
||||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public class Bmp2MapCommand : BaseCommand
|
||||
public class Bmp2MapCommand : CmdApp.Command
|
||||
{
|
||||
override public void Run()
|
||||
override public void Run(string[] args)
|
||||
{
|
||||
using (var srcstream = File.OpenRead(args[0]))
|
||||
using (var outstream = File.OpenWrite(args[1]))
|
||||
|
@ -23,24 +22,16 @@ namespace AdrianKousz.GenieEngine
|
|||
}
|
||||
}
|
||||
|
||||
override public int GetArgumentCount()
|
||||
public Bmp2MapCommand()
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
override public string GetDescription()
|
||||
{
|
||||
return "Generate a scenario map based on bitmaps";
|
||||
}
|
||||
|
||||
override public string GetHelp()
|
||||
{
|
||||
return "Generate a scenario map based on bitmaps with automatic forest generation."
|
||||
MinArgumentCount = 4;
|
||||
Description = "Generate a scenario map based on bitmaps";
|
||||
Help = "Generate a scenario map based on bitmaps with automatic forest generation."
|
||||
+ "\n"
|
||||
+ "\nTwo bitmaps need to be specified: One terrain map and one elevation map."
|
||||
+ "\nBoth bitmaps need to be indexed or grayscale."
|
||||
+ "\nThe index/gray values of the first bitmap are translated directly to a terrain ID."
|
||||
+ "\nThe index/gray values of the second bitmap are divided by 37 to generate elevations 0-6."
|
||||
+ "\nThe index/gray values of the second bitmap are divided by 40 to generate elevations 0-6."
|
||||
+ "\n"
|
||||
+ "\nParameters:"
|
||||
+ "\n<input scenario> <output scenario> <terrain bitmap> <elevation bitmap>"
|
||||
|
|
|
@ -1,31 +1,24 @@
|
|||
using System.IO;
|
||||
using AdrianKousz.Util;
|
||||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public class CompressCommand : BaseCommand
|
||||
public class CompressCommand : CmdApp.Command
|
||||
{
|
||||
override public void Run()
|
||||
override public void Run(string[] args)
|
||||
{
|
||||
using (var input = File.OpenRead(args[0]))
|
||||
using (var output = File.OpenWrite(args[1]))
|
||||
{
|
||||
GenieFile.ScenarioCompression(input, output, false);
|
||||
GenieFile.ScenarioCompress(input, output);
|
||||
}
|
||||
}
|
||||
|
||||
override public int GetArgumentCount()
|
||||
public CompressCommand()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
override public string GetDescription()
|
||||
{
|
||||
return "Recompress a decompressed scenario file";
|
||||
}
|
||||
|
||||
override public string GetHelp()
|
||||
{
|
||||
return "Recompress a previously decompressed scenario file."
|
||||
MinArgumentCount = 2;
|
||||
Description = "Recompress a decompressed scenario file";
|
||||
Help = "Recompress a previously decompressed scenario file."
|
||||
+ "\n"
|
||||
+ "\nParameters:"
|
||||
+ "\n<input binary file> <output scenario>"
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.IO;
|
||||
using AdrianKousz.Util;
|
||||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public class ConvertCommand : BaseCommand
|
||||
public class ConvertCommand : CmdApp.Command
|
||||
{
|
||||
override public void Run()
|
||||
override public void Run(string[] args)
|
||||
{
|
||||
using (var srcstream = File.OpenRead(args[0]))
|
||||
using (var outstream = File.OpenWrite(args[1]))
|
||||
|
@ -15,37 +14,46 @@ namespace AdrianKousz.GenieEngine
|
|||
var refscn = GenieFile.Deserialize<Scenario>(refstream);
|
||||
var srcscn = GenieFile.Deserialize<Scenario>(srcstream);
|
||||
|
||||
srcscn.VersionString = refscn.VersionString;
|
||||
srcscn.VersionNumber = refscn.VersionNumber;
|
||||
srcscn.RawIndividualVictory = refscn.RawIndividualVictory;
|
||||
srcscn.RawDisables = refscn.RawDisables;
|
||||
srcscn.RawRemaining = refscn.RawRemaining;
|
||||
refscn.Filename = srcscn.Filename;
|
||||
refscn.InstructionsUncompressed = srcscn.InstructionsUncompressed;
|
||||
refscn.NextId = srcscn.NextId;
|
||||
refscn.PlayerCount = srcscn.PlayerCount;
|
||||
|
||||
srcscn.PlayerSettings.ForEach(x => {
|
||||
x.FilenameAI = x.FilenameCTY = x.FilenamePER = "RandomGame";
|
||||
x.ScriptAI = x.ScriptCTY = x.ScriptPER = "";
|
||||
refscn.PlayerSettings = srcscn.PlayerSettings;
|
||||
refscn.Resources2 = srcscn.Resources2;
|
||||
refscn.Messages = srcscn.Messages;
|
||||
refscn.Cinematics = srcscn.Cinematics;
|
||||
refscn.GlobalVictory = srcscn.GlobalVictory;
|
||||
|
||||
refscn.Map = srcscn.Map;
|
||||
refscn.Units = srcscn.Units;
|
||||
|
||||
refscn.PlayerSettings.ForEach(x => {
|
||||
x.NameStringID = -1;
|
||||
x.FilenameAI = "RandomGame"; x.FilenameCTY = ""; x.FilenamePER = "";
|
||||
x.ScriptAI = ""; x.ScriptCTY = ""; x.ScriptPER = "";
|
||||
});
|
||||
|
||||
var converter = new CopymapConverter();
|
||||
converter.Convert(srcscn);
|
||||
Enumerables.ForBoth(refscn.PlayerSettings2, srcscn.PlayerSettings2, (r, s) => {
|
||||
r.Name = s.Name;
|
||||
r.CameraX = s.CameraX;
|
||||
r.CameraY = s.CameraY;
|
||||
r.AlliedVictory = s.AlliedVictory;
|
||||
r.Stances = s.Stances;
|
||||
});
|
||||
|
||||
GenieFile.Serialize(srcscn, outstream);
|
||||
var converter = new ConvertCommandHelper();
|
||||
converter.Convert(refscn);
|
||||
|
||||
GenieFile.Serialize(refscn, outstream);
|
||||
}
|
||||
}
|
||||
|
||||
override public int GetArgumentCount()
|
||||
public ConvertCommand()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
override public string GetDescription()
|
||||
{
|
||||
return "Convert AOE1 scenario";
|
||||
}
|
||||
|
||||
override public string GetHelp()
|
||||
{
|
||||
return "Convert AOE1 scenario to AOE2"
|
||||
MinArgumentCount = 3;
|
||||
Description = "Convert AOE1 scenario";
|
||||
Help = "Convert AOE1 scenario to AOE2"
|
||||
+ "\n"
|
||||
+ "\nThe converter needs an existing AOE2 scenario to start with."
|
||||
+ "\n"
|
||||
|
|
|
@ -4,44 +4,20 @@ using AdrianKousz.Util;
|
|||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public class CopymapConverter
|
||||
public class ConvertCommandHelper
|
||||
{
|
||||
public void Convert(Scenario scn)
|
||||
{
|
||||
scn.Units = ChangeUnits_AOE1_AOE2(scn.Units);
|
||||
MoveUnits_AOE1_AOE2(scn.Units);
|
||||
ChangeTiles_AOE1_AOE2(scn.Units, scn.Map);
|
||||
RandomizeTrees_AOE2(scn.Units);
|
||||
}
|
||||
|
||||
/**
|
||||
* Some buildings are not the same size.
|
||||
* They need to be moved by half a unit.
|
||||
*/
|
||||
private void MoveUnits_AOE1_AOE2(IList<Scenario.ScnUnit>[] units)
|
||||
{
|
||||
var mapping = new int[] {
|
||||
// Towers
|
||||
79, 199, 69, 278,
|
||||
// Other Buildings
|
||||
109, 68, 103,
|
||||
};
|
||||
units.ForEach(list => {
|
||||
list.ForEach(unit => {
|
||||
mapping.ForEach(buildingid => {
|
||||
if (unit.UnitId == buildingid) {
|
||||
unit.PosX -= 0.5f;
|
||||
unit.PosY -= 0.5f;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
ChangeUnits_AOE1_AOE2(scn);
|
||||
MoveUnits_AOE1_AOE2(scn);
|
||||
ChangeTiles_AOE1_AOE2(scn);
|
||||
RandomizeTrees_AOE2(scn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple mapping of unit IDs
|
||||
*/
|
||||
private List<Scenario.ScnUnit>[] ChangeUnits_AOE1_AOE2(IList<Scenario.ScnUnit>[] units)
|
||||
private void ChangeUnits_AOE1_AOE2(Scenario scn)
|
||||
{
|
||||
var mapping = new short[] {
|
||||
// Resources
|
||||
|
@ -141,26 +117,43 @@ namespace AdrianKousz.GenieEngine
|
|||
129, 129,
|
||||
}.ToDictionary();
|
||||
|
||||
var result = units.Map(list => {
|
||||
return list
|
||||
scn.Units = scn.Units.Map(list => {
|
||||
return (IList<Scenario.ScnUnit>)list
|
||||
.Filter(unit => mapping.ContainsKey(unit.UnitId))
|
||||
.ForEach(unit => {
|
||||
.Map(unit => {
|
||||
unit.UnitId = mapping[unit.UnitId];
|
||||
return unit;
|
||||
})
|
||||
.ToList();
|
||||
}).ToList();
|
||||
}).ToArray();
|
||||
}
|
||||
|
||||
return result;
|
||||
/**
|
||||
* Some buildings are not the same size.
|
||||
* They need to be moved by half a unit.
|
||||
*/
|
||||
private void MoveUnits_AOE1_AOE2(Scenario scn)
|
||||
{
|
||||
var minus = new int[] { 79, 68, 562, };
|
||||
var plus = new int[] { 109, };
|
||||
scn.Units.ForEach(list => {
|
||||
list.ForEach(unit => {
|
||||
minus.ForEach(buildingid => { if (unit.UnitId != buildingid) return; unit.PosX -= 0.5f; unit.PosY -= 0.5f; });
|
||||
plus.ForEach(buildingid => { if (unit.UnitId != buildingid) return; unit.PosX += 0.5f; unit.PosY += 0.5f; });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Farms need to be converted including the underlying terrain.
|
||||
*/
|
||||
private void ChangeTiles_AOE1_AOE2(IList<Scenario.ScnUnit>[] units, Scenario.ScnMap map)
|
||||
private void ChangeTiles_AOE1_AOE2(Scenario scn)
|
||||
{
|
||||
units.ForEach(list => {
|
||||
var map = scn.Map;
|
||||
scn.Units.ForEach(list => {
|
||||
list.ForEach(unit => {
|
||||
var posx = (int)(unit.PosX - 0.5);
|
||||
var posy = (int)(unit.PosY - 0.5);
|
||||
var posx = (int)unit.PosX;
|
||||
var posy = (int)unit.PosY;
|
||||
var linearpos = posy * map.SizeX + posx;
|
||||
if (false) {
|
||||
// switch
|
||||
|
@ -191,16 +184,16 @@ namespace AdrianKousz.GenieEngine
|
|||
* Forests would contain the same tree graphic
|
||||
* without this function
|
||||
*/
|
||||
private void RandomizeTrees_AOE2(IList<Scenario.ScnUnit>[] units)
|
||||
private void RandomizeTrees_AOE2(Scenario scn)
|
||||
{
|
||||
var treeids = new int[] {
|
||||
411, 351, 414, 350, 348, 349,
|
||||
};
|
||||
units.ForEach(list => {
|
||||
scn.Units.ForEach(list => {
|
||||
list.ForEach(unit => {
|
||||
treeids.ForEach(treeid => {
|
||||
if (unit.UnitId == treeid) {
|
||||
unit.Rotation = (short)Util.Math.Rand(0, 13); // Whats the maximum?
|
||||
unit.Rotation = unit.InitialFrame = (short)Util.Math.Rand(0, 14);
|
||||
}
|
||||
});
|
||||
});
|
|
@ -1,31 +1,24 @@
|
|||
using System.IO;
|
||||
using AdrianKousz.Util;
|
||||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public class DecompressCommand : BaseCommand
|
||||
public class DecompressCommand : CmdApp.Command
|
||||
{
|
||||
override public void Run()
|
||||
override public void Run(string[] args)
|
||||
{
|
||||
using (var input = File.OpenRead(args[0]))
|
||||
using (var output = File.OpenWrite(args[1]))
|
||||
{
|
||||
GenieFile.ScenarioCompression(input, output, true);
|
||||
GenieFile.ScenarioDecompress(input, output);
|
||||
}
|
||||
}
|
||||
|
||||
override public int GetArgumentCount()
|
||||
public DecompressCommand()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
override public string GetDescription()
|
||||
{
|
||||
return "Decompress a scenario file";
|
||||
}
|
||||
|
||||
override public string GetHelp()
|
||||
{
|
||||
return "Decompress a scenario file for hex editing."
|
||||
MinArgumentCount = 2;
|
||||
Description = "Decompress a scenario file";
|
||||
Help = "Decompress a scenario file for hex editing."
|
||||
+ "\n"
|
||||
+ "\nParameters:"
|
||||
+ "\n<input scenario> <output binary file>"
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
using System.IO;
|
||||
using System.Drawing;
|
||||
using AdrianKousz.Util;
|
||||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public class DelBitmapCommand : BaseCommand
|
||||
public class DelBitmapCommand : CmdApp.Command
|
||||
{
|
||||
override public void Run()
|
||||
override public void Run(string[] args)
|
||||
{
|
||||
using (var input = File.OpenRead(args[0]))
|
||||
using (var output = File.OpenWrite(args[1]))
|
||||
|
@ -21,19 +20,11 @@ namespace AdrianKousz.GenieEngine
|
|||
}
|
||||
}
|
||||
|
||||
override public int GetArgumentCount()
|
||||
public DelBitmapCommand()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
override public string GetDescription()
|
||||
{
|
||||
return "Remove the pregame bitmap";
|
||||
}
|
||||
|
||||
override public string GetHelp()
|
||||
{
|
||||
return "Remove the pregame bitmap from a scenario."
|
||||
MinArgumentCount = 2;
|
||||
Description = "Remove the pregame bitmap";
|
||||
Help = "Remove the pregame bitmap from a scenario."
|
||||
+ "\n"
|
||||
+ "\nParameters:"
|
||||
+ "\n<input scenario> <output scenario>"
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using AdrianKousz.Util;
|
||||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public class DumpunitsCommand : BaseCommand
|
||||
public class DumpunitsCommand : CmdApp.Command
|
||||
{
|
||||
override public void Run()
|
||||
override public void Run(string[] args)
|
||||
{
|
||||
Scenario scn;
|
||||
using (var input = File.OpenRead(args[0]))
|
||||
|
@ -15,29 +14,24 @@ namespace AdrianKousz.GenieEngine
|
|||
scn = GenieFile.Deserialize<Scenario>(input);
|
||||
}
|
||||
|
||||
Console.WriteLine("{0,-8} {1,-8} {2,-8} {3}", "ID", "UnitID", "TileID", "Position");
|
||||
Console.WriteLine("{0,-8} {1,-8} {2,-8} {3,-8} {4}", "Player", "ID", "UnitID", "TileID", "Position");
|
||||
Console.WriteLine();
|
||||
var i = 0;
|
||||
scn.Units.ForEach(list => {
|
||||
Console.WriteLine("Units of player {0}:", i++);
|
||||
list.ForEach(unit => {
|
||||
var tilex = (int)(unit.PosX - 0.5);
|
||||
var tiley = (int)(unit.PosY - 0.5);
|
||||
var tilex = (int)unit.PosX;
|
||||
var tiley = (int)unit.PosY;
|
||||
var tile = scn.Map.LinearTiles[tiley * scn.Map.SizeX + tilex];
|
||||
Console.WriteLine("{0,-8} {1,-8} {2,-8} ({3,6:0.##},{4,6:0.##})", unit.Id, unit.UnitId, tile.Id, unit.PosX, unit.PosY);
|
||||
Console.WriteLine("{0,-8} {1,-8} {2,-8} {3,-8} ({4,6:0.##},{5,6:0.##})", i, unit.Id, unit.UnitId, tile.Id, unit.PosX, unit.PosY);
|
||||
});
|
||||
Console.WriteLine();
|
||||
i++;
|
||||
});
|
||||
}
|
||||
|
||||
override public int GetArgumentCount()
|
||||
public DumpunitsCommand()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
override public string GetDescription()
|
||||
{
|
||||
return "Dump units and map tiles below";
|
||||
MinArgumentCount = 1;
|
||||
Description = "Dump units and underlying map tiles";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@ using AdrianKousz.Util;
|
|||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public class ExtractCommand : BaseCommand
|
||||
public class ExtractCommand : CmdApp.Command
|
||||
{
|
||||
override public void Run()
|
||||
override public void Run(string[] args)
|
||||
{
|
||||
using (var file = File.OpenRead(args[0]))
|
||||
{
|
||||
|
@ -22,14 +22,10 @@ namespace AdrianKousz.GenieEngine
|
|||
}
|
||||
}
|
||||
|
||||
override public int GetArgumentCount()
|
||||
public ExtractCommand()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
override public string GetDescription()
|
||||
{
|
||||
return "Extract files from campaign file";
|
||||
MinArgumentCount = 1;
|
||||
Description = "Extract files from campaign file";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@ using AdrianKousz.Util;
|
|||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public class FromJsonCommand : BaseCommand
|
||||
public class FromJsonCommand : CmdApp.Command
|
||||
{
|
||||
override public void Run()
|
||||
override public void Run(string[] args)
|
||||
{
|
||||
using (var input = File.OpenRead(args[0]))
|
||||
using (var reader = input.GetReader())
|
||||
|
@ -18,19 +18,11 @@ namespace AdrianKousz.GenieEngine
|
|||
}
|
||||
}
|
||||
|
||||
override public int GetArgumentCount()
|
||||
public FromJsonCommand()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
override public string GetDescription()
|
||||
{
|
||||
return "Convert a JSON file to a scenario";
|
||||
}
|
||||
|
||||
override public string GetHelp()
|
||||
{
|
||||
return "Read a Scenario structure formatted as JSON and save it as a Scenario."
|
||||
MinArgumentCount = 2;
|
||||
Description = "Convert a JSON file to a scenario";
|
||||
Help = "Read a Scenario structure formatted as JSON and save it as a Scenario."
|
||||
+ "\n"
|
||||
+ "\nParameters:"
|
||||
+ "\n<input json> <output scenario>"
|
||||
|
|
|
@ -4,9 +4,9 @@ using AdrianKousz.Util;
|
|||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public class PackCommand : BaseCommand
|
||||
public class PackCommand : CmdApp.Command
|
||||
{
|
||||
override public void Run()
|
||||
override public void Run(string[] args)
|
||||
{
|
||||
var files = new List<Campaign.CpnFile>();
|
||||
for (var i = 2; i < args.Length; i++) {
|
||||
|
@ -33,14 +33,10 @@ namespace AdrianKousz.GenieEngine
|
|||
}
|
||||
}
|
||||
|
||||
override public int GetArgumentCount()
|
||||
public PackCommand()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
override public string GetDescription()
|
||||
{
|
||||
return "Pack files into a campaign file";
|
||||
MinArgumentCount = 3;
|
||||
Description = "Pack files into a campaign file";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,51 +1,39 @@
|
|||
using AdrianKousz.Util;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Forms;
|
||||
using AdrianKousz.Util;
|
||||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public class Program : IApp<string, string[]>
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
System.Threading.Thread.CurrentThread.Name = "main";
|
||||
Log.SetUncaughtExceptionHandler();
|
||||
|
||||
if (System.Diagnostics.Debugger.IsAttached) {
|
||||
debug();
|
||||
return;
|
||||
new CmdApp.Builder()
|
||||
.Header("Scenario Editor")
|
||||
.NoArg(new MessageBoxCommand())
|
||||
.Add("convert", new ConvertCommand())
|
||||
.Add("bmp2map", new Bmp2MapCommand())
|
||||
.Add("addbmp", new AddBitmapCommand())
|
||||
.Add("delbmp", new DelBitmapCommand())
|
||||
.Add("compress", new CompressCommand())
|
||||
.Add("decompress", new DecompressCommand())
|
||||
.Add("tojson", new ToJsonCommand())
|
||||
.Add("fromjson", new FromJsonCommand())
|
||||
.Add("dumpunits", new DumpunitsCommand())
|
||||
.Add("extract", new ExtractCommand())
|
||||
.Add("pack", new PackCommand())
|
||||
.Build()
|
||||
.Run(args);
|
||||
}
|
||||
|
||||
new CmdApp(new Program(), args).Run();
|
||||
}
|
||||
|
||||
public string GetHeader()
|
||||
private class MessageBoxCommand : CmdApp.Command
|
||||
{
|
||||
return "Scenario Editor";
|
||||
}
|
||||
|
||||
public IDictionary<string, ICommand<string[]>> GetCommands()
|
||||
public override void Run(string[] args)
|
||||
{
|
||||
var result = new Dictionary<string, ICommand<string[]>>();
|
||||
result.Add("convert", new ConvertCommand());
|
||||
result.Add("bmp2map", new Bmp2MapCommand());
|
||||
result.Add("addbmp", new AddBitmapCommand());
|
||||
result.Add("delbmp", new DelBitmapCommand());
|
||||
result.Add("compress", new CompressCommand());
|
||||
result.Add("decompress", new DecompressCommand());
|
||||
result.Add("tojson", new ToJsonCommand());
|
||||
result.Add("fromjson", new FromJsonCommand());
|
||||
result.Add("dumpunits", new DumpunitsCommand());
|
||||
result.Add("extract", new ExtractCommand());
|
||||
result.Add("pack", new PackCommand());
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void debug()
|
||||
{
|
||||
var fn = "";
|
||||
using (var istream = System.IO.File.OpenRead(fn)) {
|
||||
var scn = GenieFile.Deserialize<Scenario>(istream);
|
||||
System.Diagnostics.Debugger.Break(); // Great to inspect scn
|
||||
MessageBox.Show("Start the program on the command line like \n> GenieEdit.exe help");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@ using AdrianKousz.Util;
|
|||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public class ToJsonCommand : BaseCommand
|
||||
public class ToJsonCommand : CmdApp.Command
|
||||
{
|
||||
override public void Run()
|
||||
override public void Run(string[] args)
|
||||
{
|
||||
using (var input = File.OpenRead(args[0]))
|
||||
using (var output = File.OpenWrite(args[1]))
|
||||
|
@ -18,19 +18,11 @@ namespace AdrianKousz.GenieEngine
|
|||
}
|
||||
}
|
||||
|
||||
override public int GetArgumentCount()
|
||||
public ToJsonCommand()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
override public string GetDescription()
|
||||
{
|
||||
return "Convert a scenario to a JSON file";
|
||||
}
|
||||
|
||||
override public string GetHelp()
|
||||
{
|
||||
return "Save a Scenario structure formatted as JSON."
|
||||
MinArgumentCount = 2;
|
||||
Description = "Convert a scenario to a JSON file";
|
||||
Help = "Save a Scenario structure formatted as JSON."
|
||||
+ "\n"
|
||||
+ "\nParameters:"
|
||||
+ "\n<input scenario> <output json>"
|
||||
|
|
|
@ -31,14 +31,12 @@ namespace AdrianKousz.GenieEngine
|
|||
number = reader.ReadInt32();
|
||||
|
||||
result.Files = new PositionInfo()
|
||||
.CreateList()
|
||||
.Fill(number, () => {
|
||||
return new PositionInfo {
|
||||
.CreateArray(number)
|
||||
.Fill(() => new PositionInfo {
|
||||
Size = reader.ReadInt32(),
|
||||
Offset = reader.ReadInt32(),
|
||||
Name = reader.ReadZString(255),
|
||||
Filename = reader.ReadZString(257),
|
||||
};
|
||||
})
|
||||
.Map(x => {
|
||||
var file = new Campaign.CpnFile();
|
||||
|
@ -48,7 +46,7 @@ namespace AdrianKousz.GenieEngine
|
|||
file.Filename = x.Filename;
|
||||
return file;
|
||||
})
|
||||
.ToArray();
|
||||
.ToList();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -101,13 +101,29 @@ namespace AdrianKousz.GenieEngine
|
|||
return new ExtendedBinaryWriter(new NonDisposingStreamWrapper(stream), Scenario.Encoding);
|
||||
}
|
||||
|
||||
public static void ScenarioCompression(Stream input, Stream output, bool decompress)
|
||||
public static void ScenarioDecompress(Stream input, Stream output)
|
||||
{
|
||||
var mode = decompress ? CompressionMode.Decompress : CompressionMode.Compress;
|
||||
CopyHeader(input, output);
|
||||
|
||||
byte[] buffer;
|
||||
using (var comp = new DeflateStream(input, CompressionMode.Decompress))
|
||||
{
|
||||
comp.CopyTo(output);
|
||||
}
|
||||
}
|
||||
|
||||
buffer = input.ReadBytes(8);
|
||||
public static void ScenarioCompress(Stream input, Stream output)
|
||||
{
|
||||
CopyHeader(input, output);
|
||||
|
||||
using (var comp = new DeflateStream(output, CompressionMode.Compress))
|
||||
{
|
||||
input.CopyTo(comp);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CopyHeader(Stream input, Stream output)
|
||||
{
|
||||
var buffer = input.ReadBytes(8);
|
||||
output.Write(buffer);
|
||||
|
||||
var headerLength = buffer[4]
|
||||
|
@ -118,11 +134,6 @@ namespace AdrianKousz.GenieEngine
|
|||
|
||||
buffer = input.ReadBytes(headerLength);
|
||||
output.Write(buffer);
|
||||
|
||||
using (var comp = new DeflateStream(input, mode))
|
||||
{
|
||||
comp.CopyTo(output);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -4,10 +4,11 @@
|
|||
{
|
||||
Scenario MakeScenario();
|
||||
Scenario.ScnPlayerSettings MakePlayerSettings();
|
||||
Scenario.ScnResource2 MakeResources2();
|
||||
Scenario.ScnPlayerSettings2 MakePlayerSettings2();
|
||||
Scenario.ScnMessages MakeMessages();
|
||||
Scenario.ScnCinematics MakeCinematics();
|
||||
Scenario.ScnGlobalVictory MakeGlobalVictory();
|
||||
Scenario.ScnResourceCopy MakeResourceCopy();
|
||||
Scenario.ScnMap MakeMap();
|
||||
Scenario.ScnUnit MakeUnit();
|
||||
}
|
||||
|
|
|
@ -22,30 +22,30 @@ namespace AdrianKousz.GenieEngine
|
|||
public String Filename;
|
||||
public DateTime Timestamp;
|
||||
public String InstructionsUncompressed;
|
||||
|
||||
public Int32 NextId;
|
||||
public Int32 PlayerCount;
|
||||
|
||||
public IList<ScnPlayerSettings> PlayerSettings;
|
||||
public IList<ScnResource2> Resources2;
|
||||
public IList<ScnPlayerSettings2> PlayerSettings2;
|
||||
|
||||
public ScnMessages Messages;
|
||||
public ScnCinematics Cinematics;
|
||||
public ScnGlobalVictory GlobalVictory;
|
||||
|
||||
public ScnMap Map;
|
||||
public IList<IList<ScnUnit>> Units;
|
||||
|
||||
public ScnPlayerSettings[] PlayerSettings;
|
||||
public ScnResourceCopy[] ResourceCopies;
|
||||
public IList<ScnUnit>[] Units;
|
||||
|
||||
// NOTE: Raw byte arrays that do not have a parser (yet?)
|
||||
public Byte[] RawIndividualVictory;
|
||||
public Byte[] RawDisables;
|
||||
public Byte[] RawRemaining;
|
||||
|
||||
// NOTE: Unknown values
|
||||
public Int32 Unknown1;
|
||||
public Int32 Unknown2;
|
||||
public Int32 Unknown3;
|
||||
public Byte Unknown4;
|
||||
public Single Unknown5;
|
||||
|
||||
public Byte[] RawIndividualVictory;
|
||||
public Byte[] RawDisables;
|
||||
public Byte[] RawRemaining;
|
||||
|
||||
public class ScnPlayerSettings
|
||||
{
|
||||
public const Int32 ExpectedUnknownInfo = 4;
|
||||
|
@ -55,16 +55,10 @@ namespace AdrianKousz.GenieEngine
|
|||
public Int32 NameStringID;
|
||||
public Boolean Active;
|
||||
public Boolean Human;
|
||||
public Int32 Civ;
|
||||
public Int32 UnknownInfo;
|
||||
|
||||
public String FilenameAI;
|
||||
public String FilenameCTY;
|
||||
public String FilenamePER;
|
||||
public String ScriptAI;
|
||||
public String ScriptCTY;
|
||||
public String ScriptPER;
|
||||
public Byte AIType;
|
||||
public Int32 Civ;
|
||||
public Int32 StartingAge;
|
||||
public Int32 UnknownInfo;
|
||||
|
||||
public Int32 ResourceWood;
|
||||
public Int32 ResourceFood;
|
||||
|
@ -73,9 +67,51 @@ namespace AdrianKousz.GenieEngine
|
|||
public Int32 ResourceOre;
|
||||
public Int32 UnknownResource;
|
||||
|
||||
public Int32[] Diplomacy;
|
||||
public Boolean AlliedVictory;
|
||||
public Int32 StartingAge;
|
||||
public Int32[] Diplomacy;
|
||||
|
||||
public String FilenameAI;
|
||||
public String FilenameCTY;
|
||||
public String FilenamePER;
|
||||
public String ScriptAI;
|
||||
public String ScriptCTY;
|
||||
public String ScriptPER;
|
||||
}
|
||||
|
||||
public class ScnResource2
|
||||
{
|
||||
public const Single ExpectedUnknown = 0;
|
||||
|
||||
public Single Wood;
|
||||
public Single Food;
|
||||
public Single Gold;
|
||||
public Single Stone;
|
||||
public Single Ore;
|
||||
public Single Unknown;
|
||||
public Single PopulationLimit;
|
||||
}
|
||||
|
||||
public class ScnPlayerSettings2
|
||||
{
|
||||
public String Name;
|
||||
|
||||
public Single CameraX;
|
||||
public Single CameraY;
|
||||
public Int16 UnknownX;
|
||||
public Int16 UnknownY;
|
||||
public Int32 Color;
|
||||
public Byte AlliedVictory;
|
||||
public Stance[] Stances;
|
||||
|
||||
public Single Unknown1;
|
||||
public Int32 Unknown2;
|
||||
public Byte[] Unknown;
|
||||
|
||||
public class Stance
|
||||
{
|
||||
public Byte Stance1;
|
||||
public Int32 Stance2;
|
||||
}
|
||||
}
|
||||
|
||||
public class ScnMessages
|
||||
|
@ -127,19 +163,6 @@ namespace AdrianKousz.GenieEngine
|
|||
public Int32 Unknown;
|
||||
}
|
||||
|
||||
public class ScnResourceCopy
|
||||
{
|
||||
public const Single ExpectedUnknownResource = 0;
|
||||
|
||||
public Single ResourceGold;
|
||||
public Single ResourceWood;
|
||||
public Single ResourceFood;
|
||||
public Single ResourceStone;
|
||||
public Single ResourceOre;
|
||||
public Single UnknownResource;
|
||||
public Single PopulationLimit;
|
||||
}
|
||||
|
||||
public class ScnMap
|
||||
{
|
||||
public Int32 CameraX;
|
||||
|
|
|
@ -32,13 +32,10 @@ namespace AdrianKousz.GenieEngine
|
|||
result.Cinematics = MakeCinematics();
|
||||
result.GlobalVictory = MakeGlobalVictory();
|
||||
result.Map = MakeMap();
|
||||
result.ResourceCopies = new Scenario.ScnResourceCopy[Scenario.NumPlayerSections - 1]
|
||||
.Fill(MakeResourceCopy);
|
||||
result.PlayerSettings = new Scenario.ScnPlayerSettings[Scenario.NumPlayers]
|
||||
.Fill(MakePlayerSettings);
|
||||
result.Units = new List<Scenario.ScnUnit>[Scenario.NumPlayerSections]
|
||||
.Fill();
|
||||
|
||||
result.PlayerSettings = result.PlayerSettings.NewList().Fill(Scenario.NumPlayers, MakePlayerSettings);
|
||||
result.Resources2 = result.Resources2.NewList().Fill(Scenario.NumPlayerSections - 1, MakeResources2);
|
||||
result.PlayerSettings2 = result.PlayerSettings2.NewList().Fill(Scenario.NumPlayerSections - 1, MakePlayerSettings2);
|
||||
result.Units = MakeUnitList(Scenario.NumPlayerSections);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -63,6 +60,25 @@ namespace AdrianKousz.GenieEngine
|
|||
return result;
|
||||
}
|
||||
|
||||
public Scenario.ScnResource2 MakeResources2()
|
||||
{
|
||||
// AOE2 standard
|
||||
var result = new Scenario.ScnResource2();
|
||||
result.Unknown = Scenario.ScnResource2.ExpectedUnknown;
|
||||
result.Food = 200;
|
||||
result.Wood = 200;
|
||||
result.Gold = 100;
|
||||
result.Stone = 200;
|
||||
result.PopulationLimit = 75;
|
||||
return result;
|
||||
}
|
||||
|
||||
public Scenario.ScnPlayerSettings2 MakePlayerSettings2()
|
||||
{
|
||||
var result = new Scenario.ScnPlayerSettings2();
|
||||
return result;
|
||||
}
|
||||
|
||||
public Scenario.ScnMessages MakeMessages()
|
||||
{
|
||||
var result = new Scenario.ScnMessages();
|
||||
|
@ -101,19 +117,6 @@ namespace AdrianKousz.GenieEngine
|
|||
return result;
|
||||
}
|
||||
|
||||
public Scenario.ScnResourceCopy MakeResourceCopy()
|
||||
{
|
||||
// AOE2 standard
|
||||
var result = new Scenario.ScnResourceCopy();
|
||||
result.UnknownResource = Scenario.ScnResourceCopy.ExpectedUnknownResource;
|
||||
result.ResourceFood = 200;
|
||||
result.ResourceWood = 200;
|
||||
result.ResourceGold = 100;
|
||||
result.ResourceStone = 200;
|
||||
result.PopulationLimit = 75;
|
||||
return result;
|
||||
}
|
||||
|
||||
public Scenario.ScnMap MakeMap()
|
||||
{
|
||||
var result = new Scenario.ScnMap();
|
||||
|
@ -135,6 +138,13 @@ namespace AdrianKousz.GenieEngine
|
|||
result.GarrisonnedInId = -1;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static IList<IList<Scenario.ScnUnit>> MakeUnitList(int count = Scenario.NumPlayerSections)
|
||||
{
|
||||
IList<IList<Scenario.ScnUnit>> result = new List<IList<Scenario.ScnUnit>>()
|
||||
.Fill(count, () => (IList<Scenario.ScnUnit>)new List<Scenario.ScnUnit>());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace AdrianKousz.GenieEngine
|
|||
result.VersionString = reader.ReadString(4);
|
||||
reader.ReadInt32(); // Header Length
|
||||
result.Unknown1 = reader.ReadInt32();
|
||||
result.Timestamp = DateTimes.FromUnixTime(reader.ReadInt32());
|
||||
result.Timestamp = reader.ReadInt32().ToDateTime();
|
||||
result.InstructionsUncompressed = reader.ReadZStringInt32();
|
||||
result.Unknown2 = reader.ReadInt32();
|
||||
result.PlayerCount = reader.ReadInt32();
|
||||
|
@ -49,8 +49,7 @@ namespace AdrianKousz.GenieEngine
|
|||
result.VersionNumber = reader.ReadSingle();
|
||||
Version = result.VersionNumber;
|
||||
|
||||
result.PlayerSettings = new Scenario.ScnPlayerSettings[Scenario.NumPlayers]
|
||||
.Fill(factory.MakePlayerSettings);
|
||||
result.PlayerSettings = result.PlayerSettings.NewList().Fill(Scenario.NumPlayers, factory.MakePlayerSettings);
|
||||
|
||||
// PlayerSettings 1
|
||||
|
||||
|
@ -65,8 +64,8 @@ namespace AdrianKousz.GenieEngine
|
|||
}
|
||||
|
||||
result.PlayerSettings.ForEach(x => {
|
||||
x.Active = reader.ReadBoolean();
|
||||
x.Human = reader.ReadBoolean();
|
||||
x.Active = reader.ReadBooleanInt32();
|
||||
x.Human = reader.ReadBooleanInt32();
|
||||
x.Civ = reader.ReadInt32();
|
||||
x.UnknownInfo = reader.ReadInt32();
|
||||
});
|
||||
|
@ -110,7 +109,7 @@ namespace AdrianKousz.GenieEngine
|
|||
result.Cinematics.FilenameLoss = reader.ReadStringInt16();
|
||||
result.Cinematics.FilenameBitmap = reader.ReadStringInt16();
|
||||
|
||||
var hasBitmap = reader.ReadBoolean();
|
||||
var hasBitmap = reader.ReadBooleanInt32();
|
||||
|
||||
result.Cinematics.BitmapWidth = reader.ReadInt32();
|
||||
result.Cinematics.BitmapHeight = reader.ReadInt32();
|
||||
|
@ -166,13 +165,13 @@ namespace AdrianKousz.GenieEngine
|
|||
|
||||
result.GlobalVictory = factory.MakeGlobalVictory();
|
||||
|
||||
result.GlobalVictory.RequireConquest = reader.ReadBoolean();
|
||||
result.GlobalVictory.RequireConquest = reader.ReadBooleanInt32();
|
||||
result.GlobalVictory.Ruins = reader.ReadInt32();
|
||||
result.GlobalVictory.Artifacts = reader.ReadInt32();
|
||||
result.GlobalVictory.Discovery = reader.ReadInt32();
|
||||
result.GlobalVictory.PercentExplored = reader.ReadInt32();
|
||||
result.GlobalVictory.Unknown = reader.ReadInt32();
|
||||
result.GlobalVictory.RequireAllCustom = reader.ReadBoolean();
|
||||
result.GlobalVictory.RequireAllCustom = reader.ReadBooleanInt32();
|
||||
result.GlobalVictory.Mode = reader.ReadInt32();
|
||||
result.GlobalVictory.Score = reader.ReadInt32();
|
||||
result.GlobalVictory.Time = reader.ReadInt32();
|
||||
|
@ -188,7 +187,7 @@ namespace AdrianKousz.GenieEngine
|
|||
ReadSeparator(reader, "Player Environment");
|
||||
|
||||
result.PlayerSettings.ForEach(x => {
|
||||
x.AlliedVictory = reader.ReadBoolean();
|
||||
x.AlliedVictory = reader.ReadBooleanInt32();
|
||||
});
|
||||
|
||||
if (Version >= 1.15f) number = (Scenario.NumPlayers * ( 20 /*Disables*/) + 3 /*Unknowns*/) * 4 /*Intsize*/;
|
||||
|
@ -223,18 +222,17 @@ namespace AdrianKousz.GenieEngine
|
|||
|
||||
number = reader.ReadInt32();
|
||||
|
||||
result.ResourceCopies = new Scenario.ScnResourceCopy[number - 1]
|
||||
.Fill(factory.MakeResourceCopy);
|
||||
result.Resources2 = result.Resources2.NewList().Fill(number - 1, factory.MakeResources2);
|
||||
|
||||
result.ResourceCopies.ForEach(x => {
|
||||
x.ResourceFood = reader.ReadSingle();
|
||||
x.ResourceWood = reader.ReadSingle();
|
||||
x.ResourceGold = reader.ReadSingle();
|
||||
x.ResourceStone = reader.ReadSingle();
|
||||
result.Resources2.ForEach(x => {
|
||||
x.Food = reader.ReadSingle();
|
||||
x.Wood = reader.ReadSingle();
|
||||
x.Gold = reader.ReadSingle();
|
||||
x.Stone = reader.ReadSingle();
|
||||
if (Version >= 1.18f) {
|
||||
x.ResourceOre = reader.ReadInt32();
|
||||
x.Ore = reader.ReadSingle();
|
||||
if (Version < 1.3f) {
|
||||
x.UnknownResource = reader.ReadInt32();
|
||||
x.Unknown = reader.ReadSingle();
|
||||
}
|
||||
}
|
||||
if (Version >= 1.22f) {
|
||||
|
@ -244,7 +242,7 @@ namespace AdrianKousz.GenieEngine
|
|||
|
||||
// Units
|
||||
|
||||
result.Units = new List<Scenario.ScnUnit>[number].Fill();
|
||||
result.Units = ScnDefaultFactory.MakeUnitList(number);
|
||||
|
||||
result.Units.ForEach(x => {
|
||||
var count = reader.ReadInt32();
|
||||
|
@ -265,7 +263,39 @@ namespace AdrianKousz.GenieEngine
|
|||
});
|
||||
});
|
||||
|
||||
// More Player Settings and Triggers
|
||||
// PlayerSettings2
|
||||
|
||||
number = reader.ReadInt32();
|
||||
|
||||
result.PlayerSettings2 = result.PlayerSettings2.NewList().Fill(number - 1, factory.MakePlayerSettings2);
|
||||
|
||||
result.PlayerSettings2.ForEach(x => {
|
||||
x.Name = reader.ReadZStringInt16();
|
||||
x.CameraX = reader.ReadSingle();
|
||||
x.CameraY = reader.ReadSingle();
|
||||
x.UnknownX = reader.ReadInt16();
|
||||
x.UnknownY = reader.ReadInt16();
|
||||
x.AlliedVictory = reader.ReadByte();
|
||||
number = reader.ReadInt16();
|
||||
x.Stances = new Scenario.ScnPlayerSettings2.Stance[number].Fill();
|
||||
x.Stances.ForEach(y => { y.Stance1 = reader.ReadByte(); });
|
||||
x.Stances.ForEach(y => { y.Stance2 = reader.ReadInt32(); });
|
||||
if (Version >= 1.18f) {
|
||||
x.Color = reader.ReadInt32();
|
||||
}
|
||||
|
||||
x.Unknown1 = reader.ReadSingle();
|
||||
x.Unknown2 = reader.ReadInt32();
|
||||
|
||||
if (x.Unknown1 == 1.0f || x.Unknown1 == 2.0f) {
|
||||
x.Unknown = reader.ReadBytes(1 + (int)x.Unknown1 * 8 + x.Unknown2 * 44);
|
||||
} else {
|
||||
var msg = string.Format("Numbers {0}/{1} for {2}", x.Unknown1, x.Unknown2, x.Name);
|
||||
throw new System.NotImplementedException(msg);
|
||||
}
|
||||
});
|
||||
|
||||
// Triggers
|
||||
|
||||
var bytestream = new MemoryStream();
|
||||
reader.BaseStream.CopyTo(bytestream);
|
||||
|
|
|
@ -17,13 +17,15 @@ namespace AdrianKousz.GenieEngine
|
|||
|
||||
public void Write(ExtendedBinaryWriter writer, Scenario value)
|
||||
{
|
||||
EnsureValid(value);
|
||||
|
||||
var Version = value.VersionNumber;
|
||||
var UncompressedHeaderLength = 20 + writer.GetZByteCount(value.InstructionsUncompressed);
|
||||
|
||||
// Uncompressed header
|
||||
|
||||
writer.WriteStringRaw(value.VersionString);
|
||||
writer.Write((int)UncompressedHeaderLength);
|
||||
writer.Write((System.Int32)UncompressedHeaderLength);
|
||||
writer.Write(value.Unknown1);
|
||||
writer.Write((System.Int32)DateTimes.ToUnixTime(value.Timestamp));
|
||||
writer.WriteZStringInt32(value.InstructionsUncompressed);
|
||||
|
@ -53,8 +55,8 @@ namespace AdrianKousz.GenieEngine
|
|||
}
|
||||
|
||||
value.PlayerSettings.ForEach(x => {
|
||||
writer.Write(x.Active);
|
||||
writer.Write(x.Human);
|
||||
writer.WriteBooleanInt32(x.Active);
|
||||
writer.WriteBooleanInt32(x.Human);
|
||||
writer.Write(x.Civ);
|
||||
writer.Write(x.UnknownInfo);
|
||||
});
|
||||
|
@ -96,7 +98,7 @@ namespace AdrianKousz.GenieEngine
|
|||
|
||||
var hasBitmap = value.Cinematics.RawBitmap.Length > 0;
|
||||
|
||||
writer.Write(hasBitmap);
|
||||
writer.WriteBooleanInt32(hasBitmap);
|
||||
writer.Write(value.Cinematics.BitmapWidth);
|
||||
writer.Write(value.Cinematics.BitmapHeight);
|
||||
writer.Write(value.Cinematics.BitmapUnknown);
|
||||
|
@ -113,9 +115,9 @@ namespace AdrianKousz.GenieEngine
|
|||
});
|
||||
|
||||
value.PlayerSettings.ForEach(x => {
|
||||
writer.Write((int)writer.GetByteCount(x.ScriptAI));
|
||||
writer.Write((int)writer.GetByteCount(x.ScriptCTY));
|
||||
writer.Write((int)writer.GetByteCount(x.ScriptPER));
|
||||
writer.Write((System.Int32)writer.GetByteCount(x.ScriptAI));
|
||||
writer.Write((System.Int32)writer.GetByteCount(x.ScriptCTY));
|
||||
writer.Write((System.Int32)writer.GetByteCount(x.ScriptPER));
|
||||
writer.WriteStringRaw(x.ScriptAI);
|
||||
writer.WriteStringRaw(x.ScriptCTY);
|
||||
writer.WriteStringRaw(x.ScriptPER);
|
||||
|
@ -148,13 +150,13 @@ namespace AdrianKousz.GenieEngine
|
|||
|
||||
// Diplomacy
|
||||
|
||||
writer.Write(value.GlobalVictory.RequireConquest);
|
||||
writer.WriteBooleanInt32(value.GlobalVictory.RequireConquest);
|
||||
writer.Write(value.GlobalVictory.Ruins);
|
||||
writer.Write(value.GlobalVictory.Artifacts);
|
||||
writer.Write(value.GlobalVictory.Discovery);
|
||||
writer.Write(value.GlobalVictory.PercentExplored);
|
||||
writer.Write(value.GlobalVictory.Unknown);
|
||||
writer.Write(value.GlobalVictory.RequireAllCustom);
|
||||
writer.WriteBooleanInt32(value.GlobalVictory.RequireAllCustom);
|
||||
writer.Write(value.GlobalVictory.Mode);
|
||||
writer.Write(value.GlobalVictory.Score);
|
||||
writer.Write(value.GlobalVictory.Time);
|
||||
|
@ -172,7 +174,7 @@ namespace AdrianKousz.GenieEngine
|
|||
WriteSeparator(writer, "Player Environment");
|
||||
|
||||
value.PlayerSettings.ForEach(x => {
|
||||
writer.Write(x.AlliedVictory);
|
||||
writer.WriteBooleanInt32(x.AlliedVictory);
|
||||
});
|
||||
|
||||
writer.Write(value.RawDisables);
|
||||
|
@ -203,17 +205,17 @@ namespace AdrianKousz.GenieEngine
|
|||
|
||||
// ResourceCopies
|
||||
|
||||
writer.Write((int)value.Units.Length);
|
||||
writer.Write((System.Int32)value.Units.Count);
|
||||
|
||||
value.ResourceCopies.ForEach(x => {
|
||||
writer.Write(x.ResourceFood);
|
||||
writer.Write(x.ResourceWood);
|
||||
writer.Write(x.ResourceGold);
|
||||
writer.Write(x.ResourceStone);
|
||||
value.Resources2.ForEach(x => {
|
||||
writer.Write(x.Food);
|
||||
writer.Write(x.Wood);
|
||||
writer.Write(x.Gold);
|
||||
writer.Write(x.Stone);
|
||||
if (Version >= 1.18f) {
|
||||
writer.Write(x.ResourceOre);
|
||||
writer.Write(x.Ore);
|
||||
if (Version < 1.3f) {
|
||||
writer.Write(x.UnknownResource);
|
||||
writer.Write(x.Unknown);
|
||||
}
|
||||
}
|
||||
if (Version >= 1.22f) {
|
||||
|
@ -224,7 +226,7 @@ namespace AdrianKousz.GenieEngine
|
|||
// Units
|
||||
|
||||
value.Units.ForEach(x => {
|
||||
writer.Write((int)x.Count);
|
||||
writer.Write((System.Int32)x.Count);
|
||||
x.ForEach(y => {
|
||||
writer.Write(y.PosX);
|
||||
writer.Write(y.PosY);
|
||||
|
@ -240,7 +242,31 @@ namespace AdrianKousz.GenieEngine
|
|||
});
|
||||
});
|
||||
|
||||
// More Player Settings and Triggers
|
||||
// PlayerSettings2
|
||||
|
||||
writer.Write((System.Int32)(value.PlayerSettings2.Count + 1));
|
||||
|
||||
value.PlayerSettings2.ForEach(x => {
|
||||
writer.WriteZStringInt16(x.Name);
|
||||
writer.Write(x.CameraX);
|
||||
writer.Write(x.CameraY);
|
||||
writer.Write(x.UnknownX);
|
||||
writer.Write(x.UnknownY);
|
||||
writer.Write(x.AlliedVictory);
|
||||
writer.Write((System.Int16)x.Stances.Length);
|
||||
x.Stances.ForEach(y => { writer.Write(y.Stance1); });
|
||||
x.Stances.ForEach(y => { writer.Write(y.Stance2); });
|
||||
if (Version >= 1.18f) {
|
||||
writer.Write(x.Color);
|
||||
}
|
||||
|
||||
writer.Write(x.Unknown1);
|
||||
writer.Write(x.Unknown2);
|
||||
|
||||
writer.Write(x.Unknown);
|
||||
});
|
||||
|
||||
// Triggers
|
||||
|
||||
writer.Write(value.RawRemaining);
|
||||
|
||||
|
@ -256,6 +282,14 @@ namespace AdrianKousz.GenieEngine
|
|||
{
|
||||
writer.Write(Scenario.Separator);
|
||||
}
|
||||
|
||||
private void EnsureValid(Scenario value)
|
||||
{
|
||||
if (value.PlayerSettings.Count != Scenario.NumPlayers)
|
||||
throw new System.InvalidOperationException("PlayerSettings.Count != 16");
|
||||
if (value.Units.Count - 1 != value.Resources2.Count)
|
||||
throw new System.InvalidOperationException("Conflicting unit and resource copy count");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,4 +2,4 @@
|
|||
|
||||
[assembly: AssemblyTitle("ScenLib")]
|
||||
[assembly: AssemblyDescription("Read and write scenario data from Genie Engine games")]
|
||||
[assembly: AssemblyVersion("0.5")]
|
||||
[assembly: AssemblyVersion("0.6")]
|
||||
|
|
Loading…
Reference in New Issue