Compare commits
No commits in common. "82d8551ab10c4dd119a791caf5698699d55af965" and "233d0c9c89c2727100fb1b3a6b39af5f6c0bed4c" have entirely different histories.
82d8551ab1
...
233d0c9c89
29 changed files with 300 additions and 1134 deletions
README.md
files
src
cmdapp
lib
54
README.md
54
README.md
|
@ -4,61 +4,7 @@ Command line application and library to edit scenario and campaign files.
|
|||
|
||||
**Alpha version**
|
||||
|
||||
## Usage
|
||||
|
||||
Available commands are:
|
||||
copymap Copy parts of scenarios
|
||||
compress Recompress a decompressed scenario file
|
||||
decompress Decompress a scenario file for hex editing
|
||||
extract Extract scenarios from campaign file
|
||||
dump Dump a scenario file to JSON
|
||||
dumpunits Dump units and map tiles below
|
||||
|
||||
The command `copymap` is able convert an AOE1 to an AOE2 scenario.
|
||||
There seem to be some issues with cliffs.
|
||||
|
||||
[OpeningMoves-AOE2.scx](files/OpeningMoves-AOE2.scx)
|
||||
is a fully automated conversion of a scenario from the AOE1 demo version:
|
||||
|
||||
$ GenieEdit.exe copymap files/examples/aoe2x-Empty.scx "files/examples/aoe1demo-Reigno_1-Opening Moves.scn" files/OpeningMoves-AOE2.scx
|
||||
|
||||
(Stone are set to 100 to be able to build a town center from the beginning.)
|
||||
|
||||
It can also be used to dump units from any version of a scenario:
|
||||
|
||||
$ GenieEdit.exe dumpunits Debug2.scx
|
||||
Scenario Editor
|
||||
|
||||
ID UnitID TileID Position
|
||||
|
||||
Units of player 0:
|
||||
0 69 23 ( 1,5, 11,5)
|
||||
1 69 23 ( 2,5, 11,5)
|
||||
...
|
||||
|
||||
### Code
|
||||
|
||||
Have a look at the command implementations. They are very short.
|
||||
|
||||
## Build
|
||||
|
||||
Clone my projects MainUtil.cs ExUtil.cs and this repository
|
||||
and build `src/GenieEdit.sln`.
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are very welcome. ☺
|
||||
Keep in mind that the API is still very unstable.
|
||||
|
||||
Suggestions:
|
||||
|
||||
1. Gather UnitIDs of AOE1
|
||||
2. Much help is appreciated to figure out ID mappings
|
||||
for the conversion process.
|
||||
3. Ideas how to configure the converter (mapping tables).
|
||||
There are some notes in German:
|
||||
[AOE1](files/units-aoe1.txt),
|
||||
[AOE2](files/units-aoe2.txt)
|
||||
3. The application should be able to generate maps from images
|
||||
in the future. How should units be placed using the image?
|
||||
4. Feedback about the API.
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,59 +0,0 @@
|
|||
Gold 66
|
||||
Bush 59
|
||||
Stone 102
|
||||
Klippe 3x3 264
|
||||
Dorfbewohner 83
|
||||
|
||||
Kleiner Wall 72
|
||||
Mittelgrosser Wall 117
|
||||
Befestigungsanlage 155
|
||||
|
||||
Beobachtungsturm 2x2 79
|
||||
Abwehrturm 2x2 199
|
||||
Wachturm 2x2 69
|
||||
Geschützturm 2x2 278
|
||||
|
||||
Haus 2x2 70
|
||||
Artefakt 159
|
||||
Bauernhof=>Feld 3x3 50
|
||||
Dorfzentrum 3x3 109
|
||||
Kaserne 3x3 12
|
||||
Kornspeicher 3x3 68
|
||||
Lagergrube 3x3 103
|
||||
Stall 101
|
||||
|
||||
Baum 134
|
||||
Buche 140
|
||||
Eiche 141 144 145 146
|
||||
Esche, Fichte 148 136
|
||||
Kiefer 197 194 193 192 135 137 138 139 391 392
|
||||
Palme 150-153
|
||||
|
||||
Wald Gelaende TileID=10:
|
||||
142 143 147 195 365 366 367 393
|
||||
|
||||
Palmenhain Gelaende TileID=13:
|
||||
113 114 121 129
|
||||
|
||||
Dschungel TileID=20:
|
||||
113 114 121 129
|
||||
|
||||
Kiefernwald TileID=19:
|
||||
161 198 203 226 391 392
|
||||
|
||||
Fisch Kueste 260
|
||||
Fisch Kueste 263
|
||||
Fisch Lachs 53
|
||||
Fisch Thun 52
|
||||
Fisch Wal 370
|
||||
|
||||
Aligator 1
|
||||
Aligator Koenig 362
|
||||
Elefant 48
|
||||
Elefant Koenig 90
|
||||
Gazelle 65
|
||||
Gazelle Koenig 384
|
||||
Loewe 126
|
||||
Loewe Koenig 89
|
||||
Vogel Adler 96
|
||||
Vogel Habicht 95
|
|
@ -1,74 +0,0 @@
|
|||
Gold 66
|
||||
Bush 59
|
||||
Stone 102
|
||||
Klippe 3x3 264
|
||||
Dorfbewohner 83
|
||||
|
||||
Palisadenwall 72
|
||||
Steinwallall 117
|
||||
Befestigter Wall 155
|
||||
|
||||
Aussenposten 1x1 598
|
||||
Beobachtungsturm 1x1 79
|
||||
Wachturm 1x1 79
|
||||
Hauptturm 1x1 79
|
||||
|
||||
Haus 2x2 70
|
||||
Reliquie 285
|
||||
Bauernhof=>Feld 3x3 50 (TileID=7)
|
||||
Dorfzentrum 4x4 109
|
||||
Kaserne 3x3 12
|
||||
Muehle 2x2 68
|
||||
Holzlager 2x2 562
|
||||
Stall 3x3 101
|
||||
|
||||
Bambus 348
|
||||
Baum A-L 399-410
|
||||
Baum TD 248
|
||||
Dschungelbaum 414
|
||||
Eiche 349
|
||||
Kiefer 350
|
||||
Palme 351
|
||||
Verschneiter Kiefer 413
|
||||
Waldbaum 411
|
||||
|
||||
Wald Gelaende TileID=10:
|
||||
411
|
||||
|
||||
Palmenhain Gelaende TileID=13:
|
||||
351
|
||||
|
||||
Dschungel TileID=17:
|
||||
414
|
||||
|
||||
Kiefernwald TileID=19:
|
||||
350
|
||||
|
||||
Bambus TileID=18:
|
||||
348
|
||||
|
||||
Eichenwald TileID=20:
|
||||
349
|
||||
|
||||
Fisch Barsch 53
|
||||
Fisch Dorado 455
|
||||
Fisch Lachs 456
|
||||
Fisch Schnapper 458
|
||||
Fisch Thun 457
|
||||
|
||||
Fisch Marlin 1 451
|
||||
Fisch Marlin 2 450
|
||||
Fisch Kueste 69
|
||||
|
||||
Tiere:
|
||||
Vogel Falke 96
|
||||
Jaguar 812
|
||||
Wildes Pferd 835
|
||||
Pferd 814
|
||||
Reh 65
|
||||
Schaf 594
|
||||
Truthahn 833
|
||||
Urwolf 89
|
||||
Wolf 126
|
||||
Wilder Eber 810
|
||||
Wildschwein 48
|
|
@ -36,9 +36,6 @@
|
|||
<Compile Include="src\CompressCommand.cs" />
|
||||
<Compile Include="src\ExtractCommand.cs" />
|
||||
<Compile Include="src\DumpCommand.cs" />
|
||||
<Compile Include="src\CopymapCommand.cs" />
|
||||
<Compile Include="src\DumpunitsCommand.cs" />
|
||||
<Compile Include="src\CopymapConverter.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
|
@ -53,10 +50,6 @@
|
|||
<Project>{662FDCF9-3F6C-48DA-BFE9-F317BEFED692}</Project>
|
||||
<Name>ExUtil</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\MainUtil.cs\src\main\MainUtil.csproj">
|
||||
<Project>{8306E345-3A99-4F22-AF14-3CEA7425C2EF}</Project>
|
||||
<Name>MainUtil</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace AdrianKousz.GenieEngine
|
|||
var reader = new ScnReader(file);
|
||||
var writer = new ScnWriter(outfile);
|
||||
|
||||
var header = reader.ReadScenarioHeader();
|
||||
var header = reader.ReadScenarioHeader(null);
|
||||
reader.ReadSeparator("Custom");
|
||||
writer.Write(header);
|
||||
writer.Flush();
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public class CopymapCommand : BaseCommand
|
||||
{
|
||||
override public void Run()
|
||||
{
|
||||
Data.Scenario result;
|
||||
using (var dststream = File.OpenRead(args[0]))
|
||||
using (var srcstream = File.OpenRead(args[1]))
|
||||
{
|
||||
var srcreader = new ScnReader(srcstream);
|
||||
var src = srcreader.ReadScenario();
|
||||
var dstreader = new ScnReader(dststream);
|
||||
var dst = dstreader.ReadScenario();
|
||||
var converter = new CopymapConverter();
|
||||
dst.PlayerNames = src.PlayerNames;
|
||||
dst.StringTablePlayerNames = src.StringTablePlayerNames;
|
||||
dst.Players = src.Players;
|
||||
dst.Resources = src.Resources;
|
||||
dst.ResourcesCopy = src.ResourcesCopy;
|
||||
dst.Messages = src.Messages;
|
||||
converter.Convert(dst, src);
|
||||
result = dst;
|
||||
}
|
||||
using (var outstream = File.OpenWrite(args[2])) {
|
||||
var outwriter = new ScnWriter(outstream);
|
||||
outwriter.Write(result);
|
||||
}
|
||||
}
|
||||
|
||||
override public int GetArgumentCount()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
override public string GetDescription()
|
||||
{
|
||||
return "Copy parts of scenarios";
|
||||
}
|
||||
|
||||
override public string GetHelp()
|
||||
{
|
||||
return "Copy the parts below from scenario file 2 into scenario file 1."
|
||||
+ "\nThe result is written to scenario file 3."
|
||||
+ "\n- Messages"
|
||||
+ "\n- Player information"
|
||||
+ "\n- Resources"
|
||||
+ "\n- Map"
|
||||
+ "\n- Units"
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,206 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AdrianKousz.Util;
|
||||
using AdrianKousz.GenieEngine.Data;
|
||||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public class CopymapConverter
|
||||
{
|
||||
public void Convert(Scenario dst, Scenario src)
|
||||
{
|
||||
dst.Map = src.Map;
|
||||
dst.Units = ChangeUnits_AOE1_AOE2(src.Units);
|
||||
MoveUnits_AOE1_AOE2(dst.Units);
|
||||
ChangeTiles_AOE1_AOE2(dst.Units, dst.Map);
|
||||
RandomizeTrees_AOE2(dst.Units);
|
||||
}
|
||||
|
||||
/**
|
||||
* Some buildings are not the same size.
|
||||
* They need to be moved by half a unit.
|
||||
*/
|
||||
private void MoveUnits_AOE1_AOE2(IList<UnitInfo>[] units)
|
||||
{
|
||||
var mapping = new int[] {
|
||||
// Towers
|
||||
79, 199, 69, 278,
|
||||
// Other Buildings
|
||||
109, 68, 103,
|
||||
};
|
||||
units.ForEach((i, list) => {
|
||||
list.ForEach((j, unit) => {
|
||||
mapping.ForEach((k, buildingid) => {
|
||||
if (unit.UnitId == buildingid) {
|
||||
unit.PosX -= 0.5f;
|
||||
unit.PosY -= 0.5f;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple mapping of unit IDs
|
||||
*/
|
||||
private List<UnitInfo>[] ChangeUnits_AOE1_AOE2(IList<UnitInfo>[] units)
|
||||
{
|
||||
var array = new int[] {
|
||||
66, 66,
|
||||
59, 59,
|
||||
102, 102,
|
||||
264, 264,
|
||||
83, 83,
|
||||
125, 125,
|
||||
|
||||
// Buildings
|
||||
72, 72,
|
||||
117, 117,
|
||||
155, 155,
|
||||
79, 598,
|
||||
199, 79,
|
||||
69, 79,
|
||||
278, 79,
|
||||
70, 70,
|
||||
159, 285,
|
||||
109, 109,
|
||||
12, 12,
|
||||
68, 68,
|
||||
103, 562,
|
||||
101, 101,
|
||||
|
||||
// Trees
|
||||
141, 349,
|
||||
144, 349,
|
||||
145, 349,
|
||||
146, 349,
|
||||
197, 350,
|
||||
194, 350,
|
||||
193, 350,
|
||||
192, 350,
|
||||
135, 350,
|
||||
137, 350,
|
||||
138, 350,
|
||||
139, 350,
|
||||
161, 350,
|
||||
198, 350,
|
||||
203, 350,
|
||||
226, 350,
|
||||
391, 350,
|
||||
392, 350,
|
||||
150, 351,
|
||||
151, 351,
|
||||
152, 351,
|
||||
153, 351,
|
||||
134, 411,
|
||||
140, 411,
|
||||
148, 411,
|
||||
136, 411,
|
||||
142, 411,
|
||||
143, 411,
|
||||
147, 411,
|
||||
195, 411,
|
||||
365, 411,
|
||||
366, 411,
|
||||
367, 411,
|
||||
393, 411,
|
||||
|
||||
// Fish
|
||||
260, 69,
|
||||
263, 69,
|
||||
53, 456,
|
||||
52, 457,
|
||||
370, 451,
|
||||
|
||||
// Animals
|
||||
48, 48,
|
||||
90, 48,
|
||||
65, 65,
|
||||
384, 65,
|
||||
126, 126,
|
||||
89, 126,
|
||||
96, 96,
|
||||
|
||||
// Keep and process later
|
||||
50, 50,
|
||||
113, 113,
|
||||
114, 114,
|
||||
121, 121,
|
||||
129, 129,
|
||||
};
|
||||
var mapping = new Dictionary<int, int>();
|
||||
var ai = 0;
|
||||
while (ai < array.Length)
|
||||
mapping.Add(array[ai++], array[ai++]);
|
||||
|
||||
var result = new List<UnitInfo>[Scenario.NumPlayerSections];
|
||||
result.Fill();
|
||||
|
||||
units.ForEach((i, list) => {
|
||||
list.ForEach((j, unit) => {
|
||||
if (mapping.ContainsKey(unit.UnitId)) {
|
||||
unit.UnitId = (short)mapping[unit.UnitId];
|
||||
result[i].Add(unit);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Farms need to be converted including the underlying terrain.
|
||||
*/
|
||||
private void ChangeTiles_AOE1_AOE2(IList<UnitInfo>[] units, Map map)
|
||||
{
|
||||
units.ForEach((i, list) => {
|
||||
list.ForEach((j, unit) => {
|
||||
var posx = (int)(unit.PosX - 0.5);
|
||||
var posy = (int)(unit.PosY - 0.5);
|
||||
var linearpos = posy * map.SizeX + posx;
|
||||
if (false) {
|
||||
// switch
|
||||
} else if (unit.UnitId == 50) {
|
||||
map.LinearTiles[linearpos].Id = 7;
|
||||
map.LinearTiles[linearpos - 1].Id = 7;
|
||||
map.LinearTiles[linearpos + 1].Id = 7;
|
||||
map.LinearTiles[linearpos - map.SizeX].Id = 7;
|
||||
map.LinearTiles[linearpos - map.SizeX - 1].Id = 7;
|
||||
map.LinearTiles[linearpos - map.SizeX + 1].Id = 7;
|
||||
map.LinearTiles[linearpos + map.SizeX].Id = 7;
|
||||
map.LinearTiles[linearpos + map.SizeX - 1].Id = 7;
|
||||
map.LinearTiles[linearpos + map.SizeX + 1].Id = 7;
|
||||
} else if (unit.UnitId == 113 || unit.UnitId == 114 || unit.UnitId == 121 || unit.UnitId == 129) {
|
||||
if (map.LinearTiles[linearpos].Id == 20) {
|
||||
map.LinearTiles[linearpos].Id = 17;
|
||||
unit.UnitId = 414;
|
||||
} else {
|
||||
unit.UnitId = 351;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Forests would contain the same tree graphic
|
||||
* without this function
|
||||
*/
|
||||
private void RandomizeTrees_AOE2(IList<UnitInfo>[] units)
|
||||
{
|
||||
var treeids = new int[] {
|
||||
411, 351, 414, 350, 348, 349,
|
||||
};
|
||||
units.ForEach((i, list) => {
|
||||
list.ForEach((j, unit) => {
|
||||
treeids.ForEach((k, treeid) => {
|
||||
if (unit.UnitId == treeid) {
|
||||
unit.InitialFrame = (short)Util.Math.Rand(0, 13); // Whats the maximum?
|
||||
unit.Rotation = unit.InitialFrame;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,9 +12,9 @@ namespace AdrianKousz.GenieEngine
|
|||
var reader = new ScnReader(file);
|
||||
var writer = new ScnWriter(outfile);
|
||||
|
||||
var header = reader.ReadScenarioHeader();
|
||||
var header = reader.ReadScenarioHeader(null);
|
||||
writer.Write(header);
|
||||
writer.WriteSeperator("Custom");
|
||||
writer.WriteSeperator();
|
||||
writer.Flush();
|
||||
|
||||
using (var comp = new DeflateStream(file, CompressionMode.Decompress)) {
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace AdrianKousz.GenieEngine
|
|||
{
|
||||
using (var stream = File.OpenRead(args[0])) {
|
||||
var aoereader = new ScnReader(stream);
|
||||
var scn = aoereader.ReadScenario();
|
||||
var scn = aoereader.ReadScenario(null);
|
||||
var ser = new System.Web.Script.Serialization.JavaScriptSerializer();
|
||||
var result = ser.Serialize(scn);
|
||||
Console.WriteLine(result);
|
||||
|
@ -23,7 +23,7 @@ namespace AdrianKousz.GenieEngine
|
|||
|
||||
override public string GetDescription()
|
||||
{
|
||||
return "Dump a scenario file to JSON";
|
||||
return "Dump a scenario file to XML";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using AdrianKousz.Util;
|
||||
using AdrianKousz.GenieEngine.Data;
|
||||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public class DumpunitsCommand : BaseCommand
|
||||
{
|
||||
override public void Run()
|
||||
{
|
||||
Scenario scn;
|
||||
using (var stream = File.OpenRead(args[0])) {
|
||||
var aoereader = new ScnReader(stream);
|
||||
scn = aoereader.ReadScenario();
|
||||
}
|
||||
|
||||
Console.WriteLine("{0,-8} {1,-8} {2,-8} {3}", "ID", "UnitID", "TileID", "Position");
|
||||
Console.WriteLine();
|
||||
scn.Units.ForEach((i, list) => {
|
||||
Console.WriteLine("Units of player {0}:", i);
|
||||
list.ForEach((j, unit) => {
|
||||
var tilex = (int)(unit.PosX - 0.5);
|
||||
var tiley = (int)(unit.PosY - 0.5);
|
||||
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();
|
||||
});
|
||||
}
|
||||
|
||||
override public int GetArgumentCount()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
override public string GetDescription()
|
||||
{
|
||||
return "Dump units and map tiles below";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,11 +9,6 @@ namespace AdrianKousz.GenieEngine
|
|||
{
|
||||
System.Threading.Thread.CurrentThread.Name = "main";
|
||||
|
||||
if (System.Diagnostics.Debugger.IsAttached) {
|
||||
debug();
|
||||
return;
|
||||
}
|
||||
|
||||
new CmdApp(new Program(), args).Run();
|
||||
}
|
||||
|
||||
|
@ -25,23 +20,11 @@ namespace AdrianKousz.GenieEngine
|
|||
public IDictionary<string, ICommand<string[]>> GetCommands()
|
||||
{
|
||||
var result = new Dictionary<string, ICommand<string[]>>();
|
||||
result.Add("copymap", new CopymapCommand());
|
||||
result.Add("compress", new CompressCommand());
|
||||
result.Add("decompress", new DecompressCommand());
|
||||
result.Add("extract", new ExtractCommand());
|
||||
result.Add("dump", new DumpCommand());
|
||||
result.Add("dumpunits", new DumpunitsCommand());
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void debug()
|
||||
{
|
||||
var fn = "";
|
||||
using (var istream = System.IO.File.OpenRead(fn)) {
|
||||
var ireader = new ScnReader(istream);
|
||||
var scn = ireader.ReadScenario();
|
||||
System.Diagnostics.Debugger.Break(); // Great to inspect scn
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace AdrianKousz.GenieEngine.Data
|
|||
public String[] PlayerCustomAIs;
|
||||
public String[] PlayerCustomCTYs;
|
||||
public String[] PlayerCustomPERs;
|
||||
public Byte[] AITypes;
|
||||
public Byte[] RawAITypes;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,10 +9,6 @@ namespace AdrianKousz.GenieEngine.Data
|
|||
public String CinemaLossFn;
|
||||
public String BackgroundFn;
|
||||
|
||||
public Int32 BitmapWidth;
|
||||
public Int32 BitmapHeight;
|
||||
public Int16 BitmapUnknown;
|
||||
|
||||
public Byte[] RawBitmap;
|
||||
}
|
||||
}
|
||||
|
|
14
src/lib/AdrianKousz.GenieEngine.Data/Consts.cs
Normal file
14
src/lib/AdrianKousz.GenieEngine.Data/Consts.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace AdrianKousz.GenieEngine.Data
|
||||
{
|
||||
public static class Consts
|
||||
{
|
||||
public const Int32 Separator = -99;
|
||||
public const Int32 NumPlayers = 16;
|
||||
public const Int32 NumUnitSections = 9;
|
||||
public static readonly Encoding Encoding = Encoding.GetEncoding(1252);
|
||||
public static readonly Char[] NullChar = new Char[] { '\0' };
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace AdrianKousz.GenieEngine.Data
|
||||
{
|
||||
public class GlobalVictoryInfo
|
||||
{
|
||||
public Boolean RequireConquest;
|
||||
public Int32 Ruins;
|
||||
public Int32 Artifacts;
|
||||
public Int32 Discovery;
|
||||
public Int32 PercentExplored;
|
||||
public Int32 Unknown;
|
||||
public Boolean RequireAllCustom;
|
||||
public Int32 Mode;
|
||||
public Int32 Score;
|
||||
public Int32 Time;
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,8 @@ namespace AdrianKousz.GenieEngine.Data
|
|||
{
|
||||
public const Int32 ExpectedUnknown = 4;
|
||||
|
||||
public String Name;
|
||||
public Int32 StringTable;
|
||||
public Boolean Active;
|
||||
public Boolean Human;
|
||||
public Int32 Civ;
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using AdrianKousz.GenieEngine.Data;
|
||||
|
||||
namespace AdrianKousz.GenieEngine.Data
|
||||
{
|
||||
public class Scenario
|
||||
{
|
||||
public const Int32 Separator = -99;
|
||||
public const Int32 NumPlayers = 16;
|
||||
public const Int32 NumPlayerSections = 9;
|
||||
public static readonly Encoding Encoding = Encoding.GetEncoding(1252);
|
||||
public const Int32 PlayerSections = 9;
|
||||
|
||||
public ScenarioHeader Header;
|
||||
|
||||
|
@ -18,36 +15,22 @@ namespace AdrianKousz.GenieEngine.Data
|
|||
public Int32 NextId;
|
||||
public Single OriginalVersion;
|
||||
|
||||
public String[] PlayerNames;
|
||||
public Int32[] StringTablePlayerNames;
|
||||
public PlayerInfo[] Players;
|
||||
public Messages Messages;
|
||||
public Cinematics Cinematics;
|
||||
public AIData AIData;
|
||||
|
||||
// Seperator "Resources"
|
||||
|
||||
public ResourceInfo[] Resources;
|
||||
|
||||
// Seperator "Victory"
|
||||
|
||||
public GlobalVictoryInfo GlobalVictory;
|
||||
public Int32[] LinearDiplomacy;
|
||||
public Byte[] RawIndividualVictory;
|
||||
|
||||
// Seperator "Player Settings"
|
||||
|
||||
public Int32[] AlliedVictory;
|
||||
public Byte[] RawDisables;
|
||||
public Int32[] StartingAges;
|
||||
|
||||
// Seperator "Map"
|
||||
|
||||
public Map Map;
|
||||
public ResourceInfoCopy[] ResourcesCopy;
|
||||
public IList<UnitInfo>[] Units;
|
||||
|
||||
public byte[] RawRemaining;
|
||||
public Byte[] RawGlobalVictory;
|
||||
public Byte[] RawDiplomacy;
|
||||
public Byte[] RawIndividualVictory;
|
||||
public Byte[] RawAlliedVictory;
|
||||
public Byte[] RawDisables;
|
||||
|
||||
public Int32[] StartingAges;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,13 @@ namespace AdrianKousz.GenieEngine.Data
|
|||
{
|
||||
public class UnitInfo
|
||||
{
|
||||
public const Single ExpectedUnknown1 = 1f;
|
||||
public const Byte ExpectedUnknown2 = 2;
|
||||
public const Single ExpectedUnknown = 2f;
|
||||
|
||||
public Single PosX;
|
||||
public Single PosY;
|
||||
public Single Unknown1;
|
||||
public Int32 Id;
|
||||
public Int16 UnitId;
|
||||
public Int32 UnitId;
|
||||
public Byte Unknown2;
|
||||
public Single Rotation;
|
||||
public Int16 InitialFrame;
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace AdrianKousz.GenieEngine
|
|||
|
||||
public CpnReader(Stream input)
|
||||
{
|
||||
reader = new ExtendedBinaryReader(input, Scenario.Encoding);
|
||||
reader = new ExtendedBinaryReader(input, Data.Consts.Encoding);
|
||||
}
|
||||
|
||||
public void ExtractFiles()
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
using System;
|
||||
using AdrianKousz.GenieEngine.Data;
|
||||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public interface IScnFactory
|
||||
{
|
||||
Scenario MakeScenario(bool deep);
|
||||
ScenarioHeader MakeScenarioHeader();
|
||||
PlayerInfo MakePlayerInfo();
|
||||
Messages MakeMessages();
|
||||
Cinematics MakeCinematics();
|
||||
AIData MakeAIData();
|
||||
ResourceInfo MakeResourceInfo();
|
||||
ResourceInfoCopy MakeResourceInfoCopy();
|
||||
GlobalVictoryInfo MakeGlobalVictoryInfo();
|
||||
Map MakeMap();
|
||||
UnitInfo MakeUnitInfo();
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
using System;
|
||||
using AdrianKousz.Util;
|
||||
using AdrianKousz.GenieEngine.Data;
|
||||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public class ScnConvert
|
||||
{
|
||||
public void Convert(Scenario value, float version)
|
||||
{
|
||||
|
||||
}
|
||||
public void Convert(UnitInfo value, float from, float to)
|
||||
{
|
||||
if (from < 1.18f && to >= 1.18f) {
|
||||
value.InitialFrame = 0;
|
||||
value.GarrisonnedInId = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,148 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using AdrianKousz.Util;
|
||||
using AdrianKousz.GenieEngine.Data;
|
||||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public class ScnDefaultFactory : IScnFactory
|
||||
{
|
||||
public Scenario MakeScenario(bool deep)
|
||||
{
|
||||
var result = new Scenario();
|
||||
result.OriginalVersion = 0;
|
||||
result.NextId = 1;
|
||||
|
||||
result.StringTablePlayerNames = new int[Scenario.NumPlayers];
|
||||
|
||||
result.Units = new IList<UnitInfo>[Scenario.NumPlayerSections]
|
||||
.Fill(() => new List<UnitInfo>());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public ScenarioHeader MakeScenarioHeader()
|
||||
{
|
||||
var result = new ScenarioHeader();
|
||||
result.Unknown1 = ScenarioHeader.ExpectedUnknown1;
|
||||
result.Unknown2 = ScenarioHeader.ExpectedUnknown2;
|
||||
result.OriginalVersion = "0.00";
|
||||
result.Timestamp = System.DateTime.Now;
|
||||
result.Instructions = "";
|
||||
result.PlayerCount = 2;
|
||||
return result;
|
||||
}
|
||||
|
||||
public PlayerInfo MakePlayerInfo()
|
||||
{
|
||||
var result = new PlayerInfo();
|
||||
result.Unknown = PlayerInfo.ExpectedUnknown;
|
||||
result.Active = false;
|
||||
result.Human = false;
|
||||
result.Civ = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
public Messages MakeMessages()
|
||||
{
|
||||
var result = new Messages();
|
||||
result.Unknown1 = Messages.ExpectedUnknown1;
|
||||
result.Unknown2 = Messages.ExpectedUnknown2;
|
||||
result.Unknown3 = Messages.ExpectedUnknown3;
|
||||
result.OriginalFilename = "";
|
||||
result.TextInstructions = "";
|
||||
result.TextHints = "";
|
||||
result.TextVictory = "";
|
||||
result.TextLoss = "";
|
||||
result.TextHistory = "";
|
||||
result.TextScouts = "";
|
||||
result.StringTableInstructions = -1;
|
||||
result.StringTableHints = -1;
|
||||
result.StringTableVictory = -1;
|
||||
result.StringTableLoss = -1;
|
||||
result.StringTableHistory = -1;
|
||||
result.StringTableScouts = -1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Cinematics MakeCinematics()
|
||||
{
|
||||
var result = new Cinematics();
|
||||
result.CinemaPregameFn = "";
|
||||
result.CinemaVictoryFn = "";
|
||||
result.CinemaLossFn = "";
|
||||
result.BackgroundFn = "";
|
||||
result.RawBitmap = new byte[0];
|
||||
return result;
|
||||
}
|
||||
|
||||
public AIData MakeAIData()
|
||||
{
|
||||
var result = new AIData();
|
||||
result.PlayerAIs = new string[Scenario.NumPlayers].Fill("");
|
||||
result.PlayerCTYs = new string[Scenario.NumPlayers].Fill("");
|
||||
result.PlayerPERs = new string[Scenario.NumPlayers].Fill("");
|
||||
result.PlayerCustomAIs = new string[Scenario.NumPlayers].Fill("");
|
||||
result.PlayerCustomCTYs = new string[Scenario.NumPlayers].Fill("");
|
||||
result.PlayerCustomPERs = new string[Scenario.NumPlayers].Fill("");
|
||||
result.AITypes = new byte[Scenario.NumPlayers].Fill((byte)1);
|
||||
return result;
|
||||
}
|
||||
|
||||
public GlobalVictoryInfo MakeGlobalVictoryInfo()
|
||||
{
|
||||
var result = new GlobalVictoryInfo();
|
||||
result.RequireConquest = true;
|
||||
result.RequireAllCustom = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
public ResourceInfo MakeResourceInfo()
|
||||
{
|
||||
// AOE2 standard
|
||||
var result = new ResourceInfo();
|
||||
result.Unknown = ResourceInfo.ExpectedUnknown;
|
||||
result.Food = 200;
|
||||
result.Wood = 200;
|
||||
result.Gold = 100;
|
||||
result.Stone = 200;
|
||||
return result;
|
||||
}
|
||||
|
||||
public ResourceInfoCopy MakeResourceInfoCopy()
|
||||
{
|
||||
// AOE2 standard
|
||||
var result = new ResourceInfoCopy();
|
||||
result.Unknown = ResourceInfoCopy.ExpectedUnknown;
|
||||
result.Food = 200;
|
||||
result.Wood = 200;
|
||||
result.Gold = 100;
|
||||
result.Stone = 200;
|
||||
result.PopulationLimit = 75;
|
||||
return result;
|
||||
}
|
||||
|
||||
public Map MakeMap()
|
||||
{
|
||||
var result = new Map();
|
||||
var size = 144;
|
||||
result.CameraX = -1;
|
||||
result.CameraY = -1;
|
||||
result.GeneratorId = 2;
|
||||
result.SizeX = size;
|
||||
result.SizeY = size;
|
||||
result.LinearTiles = new Map.Tile[size*size].Fill(() => new Map.Tile(0, 1, 0));
|
||||
return result;
|
||||
}
|
||||
|
||||
public UnitInfo MakeUnitInfo()
|
||||
{
|
||||
var result = new UnitInfo();
|
||||
result.Unknown1 = UnitInfo.ExpectedUnknown1;
|
||||
result.Unknown2 = UnitInfo.ExpectedUnknown2;
|
||||
result.GarrisonnedInId = -1;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
137
src/lib/AdrianKousz.GenieEngine/ScnFactory.cs
Normal file
137
src/lib/AdrianKousz.GenieEngine/ScnFactory.cs
Normal file
|
@ -0,0 +1,137 @@
|
|||
using System.Collections.Generic;
|
||||
using AdrianKousz.Util;
|
||||
using AdrianKousz.GenieEngine.Data;
|
||||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public class ScnFactory
|
||||
{
|
||||
public Scenario GetScenario()
|
||||
{
|
||||
var result = new Scenario();
|
||||
result.OriginalVersion = -1;
|
||||
result.NextId = 1;
|
||||
|
||||
result.Header = GetScenarioHeader();
|
||||
|
||||
result.Players = new PlayerInfo[AdrianKousz.GenieEngine.Data.Consts.NumPlayers];
|
||||
result.Players.Fill(GetPlayerInfo);
|
||||
|
||||
result.Messages = GetMessages();
|
||||
result.Cinematics = GetCinematics();
|
||||
result.AIData = GetAIData();
|
||||
|
||||
result.Resources = new ResourceInfo[AdrianKousz.GenieEngine.Data.Consts.NumPlayers];
|
||||
result.Resources.Fill(GetResourceInfo);
|
||||
result.Units = new List<UnitInfo>[Scenario.PlayerSections];
|
||||
result.Units.Fill(() => new List<UnitInfo>());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public ScenarioHeader GetScenarioHeader()
|
||||
{
|
||||
var result = new ScenarioHeader();
|
||||
result.Unknown1 = ScenarioHeader.ExpectedUnknown1;
|
||||
result.Unknown2 = ScenarioHeader.ExpectedUnknown2;
|
||||
result.OriginalVersion = "0.99";
|
||||
result.Timestamp = System.DateTime.Now;
|
||||
result.Instructions = "";
|
||||
result.PlayerCount = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
public PlayerInfo GetPlayerInfo(int number)
|
||||
{
|
||||
var result = new PlayerInfo();
|
||||
result.Unknown = PlayerInfo.ExpectedUnknown;
|
||||
result.Name = "Player " + number;
|
||||
result.StringTable = -1;
|
||||
result.Active = true;
|
||||
result.Human = true;
|
||||
result.Civ = number;
|
||||
return result;
|
||||
}
|
||||
|
||||
public Messages GetMessages()
|
||||
{
|
||||
var result = new Messages();
|
||||
result.Unknown1 = Messages.ExpectedUnknown1;
|
||||
result.Unknown2 = Messages.ExpectedUnknown2;
|
||||
result.Unknown3 = Messages.ExpectedUnknown3;
|
||||
result.OriginalFilename = "";
|
||||
result.TextInstructions = "";
|
||||
result.TextHints = "";
|
||||
result.TextVictory = "";
|
||||
result.TextLoss = "";
|
||||
result.TextHistory = "";
|
||||
result.TextScouts = "";
|
||||
result.StringTableInstructions = -1;
|
||||
result.StringTableHints = -1;
|
||||
result.StringTableVictory = -1;
|
||||
result.StringTableLoss = -1;
|
||||
result.StringTableHistory = -1;
|
||||
result.StringTableScouts = -1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Cinematics GetCinematics()
|
||||
{
|
||||
var result = new Cinematics();
|
||||
result.CinemaPregameFn = "";
|
||||
result.CinemaVictoryFn = "";
|
||||
result.CinemaLossFn = "";
|
||||
result.BackgroundFn = "";
|
||||
return result;
|
||||
}
|
||||
|
||||
public AIData GetAIData()
|
||||
{
|
||||
var result = new AIData();
|
||||
result.PlayerAIs = new string[AdrianKousz.GenieEngine.Data.Consts.NumPlayers];
|
||||
result.PlayerCTYs = new string[AdrianKousz.GenieEngine.Data.Consts.NumPlayers];
|
||||
result.PlayerPERs = new string[AdrianKousz.GenieEngine.Data.Consts.NumPlayers];
|
||||
result.PlayerCustomAIs = new string[AdrianKousz.GenieEngine.Data.Consts.NumPlayers];
|
||||
result.PlayerCustomCTYs = new string[AdrianKousz.GenieEngine.Data.Consts.NumPlayers];
|
||||
result.PlayerCustomPERs = new string[AdrianKousz.GenieEngine.Data.Consts.NumPlayers];
|
||||
result.PlayerAIs.Fill("");
|
||||
result.PlayerCTYs.Fill("");
|
||||
result.PlayerPERs.Fill("");
|
||||
result.PlayerCustomAIs.Fill("");
|
||||
result.PlayerCustomCTYs.Fill("");
|
||||
result.PlayerCustomPERs.Fill("");
|
||||
result.RawAITypes = new byte[AdrianKousz.GenieEngine.Data.Consts.NumPlayers];
|
||||
result.RawAITypes.Fill((byte)1);
|
||||
return result;
|
||||
}
|
||||
|
||||
public ResourceInfo GetResourceInfo()
|
||||
{
|
||||
// AOE2 standard
|
||||
var result = new ResourceInfo();
|
||||
result.Unknown = ResourceInfo.ExpectedUnknown;
|
||||
result.Food = 200;
|
||||
result.Wood = 200;
|
||||
result.Gold = 100;
|
||||
result.Stone = 200;
|
||||
result.Ore = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
public Map GetMap()
|
||||
{
|
||||
var result = new Map();
|
||||
var size = 200;
|
||||
result.CameraX = 0;
|
||||
result.CameraY = 0;
|
||||
result.GeneratorId = 0;
|
||||
result.SizeX = size;
|
||||
result.SizeY = size;
|
||||
result.LinearTiles = new Map.Tile[size*size];
|
||||
result.LinearTiles.Fill();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,90 +8,81 @@ namespace AdrianKousz.GenieEngine
|
|||
{
|
||||
public class ScnReader
|
||||
{
|
||||
public float Version = 0;
|
||||
private static readonly string TAG = typeof(ScnReader).Name;
|
||||
|
||||
private float version = 0.99f;
|
||||
private ExtendedBinaryReader reader;
|
||||
private IScnFactory factory;
|
||||
|
||||
public ScnReader(Stream input) : this (input, new ScnDefaultFactory())
|
||||
public ScnReader(Stream input)
|
||||
{
|
||||
}
|
||||
|
||||
public ScnReader(Stream input, IScnFactory factory)
|
||||
{
|
||||
reader = new ExtendedBinaryReader(input, Scenario.Encoding);
|
||||
this.factory = factory;
|
||||
reader = new ExtendedBinaryReader(input, Data.Consts.Encoding);
|
||||
}
|
||||
|
||||
#region Reader Methods
|
||||
|
||||
public Scenario ReadScenario()
|
||||
public Scenario ReadScenario(Scenario result)
|
||||
{
|
||||
var result = factory.MakeScenario(false);
|
||||
result = Misc.MayNew(result);
|
||||
int number = 0;
|
||||
|
||||
result.Header = ReadScenarioHeader();
|
||||
result.Header = ReadScenarioHeader(result.Header);
|
||||
|
||||
var comp = new DeflateStream(reader.BaseStream, CompressionMode.Decompress);
|
||||
reader = new ExtendedBinaryReader(comp, Scenario.Encoding);
|
||||
reader = new ExtendedBinaryReader(comp, Data.Consts.Encoding);
|
||||
|
||||
result.NextId = reader.ReadInt32();
|
||||
|
||||
Version = reader.ReadSingle();
|
||||
result.OriginalVersion = Version;
|
||||
version = reader.ReadSingle();
|
||||
result.OriginalVersion = version;
|
||||
Log.i(TAG, "Detected version {0}", version);
|
||||
|
||||
result.PlayerNames = FillArray(() => reader.ReadZString(256), result.PlayerNames, Scenario.NumPlayers);
|
||||
if (Version >= 1.18f) {
|
||||
result.StringTablePlayerNames = FillArray(reader.ReadInt32, result.StringTablePlayerNames, Scenario.NumPlayers);
|
||||
}
|
||||
result.Players = FillArray(ReadPlayerInfo, result.Players, Scenario.NumPlayers);
|
||||
result.Messages = ReadMessages();
|
||||
result.Cinematics = ReadCinematics();
|
||||
result.AIData = ReadAIData();
|
||||
|
||||
result.Players = FillArray(ReadPlayerInfo, result.Players, AdrianKousz.GenieEngine.Data.Consts.NumPlayers);
|
||||
result.Messages = ReadMessages(result.Messages);
|
||||
result.Cinematics = ReadCinematics(result.Cinematics);
|
||||
result.AIData = ReadAIData(result.AIData);
|
||||
|
||||
ReadSeparator("Resources");
|
||||
|
||||
result.Resources = FillArray(ReadResourceInfo, result.Resources, Scenario.NumPlayers);
|
||||
result.Resources = FillArray(ReadResourceInfo, result.Resources, AdrianKousz.GenieEngine.Data.Consts.NumPlayers);
|
||||
|
||||
ReadSeparator("Victory");
|
||||
|
||||
result.GlobalVictory = ReadGlobalVictoryInfo();
|
||||
result.LinearDiplomacy = FillArray(reader.ReadInt32, result.LinearDiplomacy, Scenario.NumPlayers * Scenario.NumPlayers);
|
||||
result.RawGlobalVictory = reader.ReadBytes(10 * 4);
|
||||
result.RawDiplomacy = reader.ReadBytes(AdrianKousz.GenieEngine.Data.Consts.NumPlayers * AdrianKousz.GenieEngine.Data.Consts.NumPlayers * 4);
|
||||
result.RawIndividualVictory = reader.ReadBytes(11520);
|
||||
|
||||
ReadSeparator("Player Settings");
|
||||
|
||||
result.AlliedVictory = FillArray(reader.ReadInt32, result.AlliedVictory, Scenario.NumPlayers);
|
||||
result.RawAlliedVictory = reader.ReadBytes(AdrianKousz.GenieEngine.Data.Consts.NumPlayers * 4);
|
||||
|
||||
if (Version >= 1.15f) number = (Scenario.NumPlayers * ( 20 /*Disables*/) + 3 /*Unknowns*/) * 4 /*Intsize*/;
|
||||
if (Version >= 1.18f) number = (Scenario.NumPlayers * (3 /*Lengths*/ + 80 /*Disables*/) + 3 /*Unknowns*/) * 4 /*Intsize*/;
|
||||
if (Version >= 1.30f) number = (Scenario.NumPlayers * (3 /*Lengths*/ + 180 /*Disables*/) + 3 /*Unknowns*/) * 4 /*Intsize*/;
|
||||
if (1.15f <= version) number = (AdrianKousz.GenieEngine.Data.Consts.NumPlayers * ( 20 /*Disables*/) + 3 /*Unknowns*/) * 4 /*Intsize*/;
|
||||
if (1.18f <= version) number = (AdrianKousz.GenieEngine.Data.Consts.NumPlayers * (3 /*Lengths*/ + 80 /*Disables*/) + 3 /*Unknowns*/) * 4 /*Intsize*/;
|
||||
if (1.30f <= version) number = (AdrianKousz.GenieEngine.Data.Consts.NumPlayers * (3 /*Lengths*/ + 180 /*Disables*/) + 3 /*Unknowns*/) * 4 /*Intsize*/;
|
||||
result.RawDisables = reader.ReadBytes(number);
|
||||
|
||||
result.StartingAges = FillArray(reader.ReadInt32, result.StartingAges, Scenario.NumPlayers);
|
||||
result.StartingAges = new int[AdrianKousz.GenieEngine.Data.Consts.NumPlayers];
|
||||
result.StartingAges.Fill(reader.ReadInt32);
|
||||
|
||||
ReadSeparator("Map");
|
||||
|
||||
result.Map = ReadMap();
|
||||
result.Map = ReadMap(result.Map);
|
||||
|
||||
number = reader.ReadInt32();
|
||||
result.ResourcesCopy = FillArray(ReadResourceInfoCopy, result.ResourcesCopy, number - 1);
|
||||
|
||||
result.Units = FillArray(ReadUnitInfoList, result.Units, number);
|
||||
|
||||
var bytestream = new MemoryStream();
|
||||
reader.BaseStream.CopyTo(bytestream);
|
||||
result.RawRemaining = bytestream.ToArray();
|
||||
result.Units = new IList<UnitInfo>[number];
|
||||
result.Units.Fill(ReadUnitInfo);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public ScenarioHeader ReadScenarioHeader()
|
||||
public ScenarioHeader ReadScenarioHeader(ScenarioHeader result)
|
||||
{
|
||||
var result = factory.MakeScenarioHeader();
|
||||
result = Misc.MayNew(result);
|
||||
|
||||
result.OriginalVersion = reader.ReadString(4);
|
||||
reader.ReadInt32(); // Header Length
|
||||
Skip(4, "Header Length");
|
||||
result.Unknown1 = reader.ReadInt32();
|
||||
result.Timestamp = DateTimes.FromUnixTime(reader.ReadInt32());
|
||||
result.Instructions = reader.ReadZStringInt32();
|
||||
|
@ -101,10 +92,14 @@ namespace AdrianKousz.GenieEngine
|
|||
return result;
|
||||
}
|
||||
|
||||
public PlayerInfo ReadPlayerInfo()
|
||||
public PlayerInfo ReadPlayerInfo(PlayerInfo result)
|
||||
{
|
||||
var result = factory.MakePlayerInfo();
|
||||
result = Misc.MayNew(result);
|
||||
|
||||
result.Name = reader.ReadZString(256);
|
||||
if (1.18f <= version) {
|
||||
result.StringTable = reader.ReadInt32();
|
||||
}
|
||||
result.Active = reader.ReadBoolean();
|
||||
result.Human = reader.ReadBoolean();
|
||||
result.Civ = reader.ReadInt32();
|
||||
|
@ -113,23 +108,23 @@ namespace AdrianKousz.GenieEngine
|
|||
return result;
|
||||
}
|
||||
|
||||
public Messages ReadMessages()
|
||||
public Messages ReadMessages(Messages result)
|
||||
{
|
||||
var result = factory.MakeMessages();
|
||||
result = Misc.MayNew(result);
|
||||
|
||||
result.Unknown1 = reader.ReadInt32();
|
||||
result.Unknown2 = reader.ReadByte();
|
||||
result.Unknown3 = reader.ReadSingle();
|
||||
result.OriginalFilename = reader.ReadStringInt16();
|
||||
|
||||
if (Version >= 1.18f) {
|
||||
if (1.18f <= version) {
|
||||
result.StringTableInstructions = reader.ReadInt32();
|
||||
result.StringTableHints = reader.ReadInt32();
|
||||
result.StringTableVictory = reader.ReadInt32();
|
||||
result.StringTableLoss = reader.ReadInt32();
|
||||
result.StringTableHistory = reader.ReadInt32();
|
||||
}
|
||||
if (Version >= 1.22f) {
|
||||
if (1.22f <= version) {
|
||||
result.StringTableScouts = reader.ReadInt32();
|
||||
}
|
||||
|
||||
|
@ -138,16 +133,16 @@ namespace AdrianKousz.GenieEngine
|
|||
result.TextVictory = reader.ReadZStringInt16();
|
||||
result.TextLoss = reader.ReadZStringInt16();
|
||||
result.TextHistory = reader.ReadZStringInt16();
|
||||
if (Version >= 1.22f) {
|
||||
if (1.22f <= version) {
|
||||
result.TextScouts = reader.ReadZStringInt16();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Cinematics ReadCinematics()
|
||||
public Cinematics ReadCinematics(Cinematics result)
|
||||
{
|
||||
var result = factory.MakeCinematics();
|
||||
result = Misc.MayNew(result);
|
||||
|
||||
result.CinemaPregameFn = reader.ReadStringInt16();
|
||||
result.CinemaVictoryFn = reader.ReadStringInt16();
|
||||
|
@ -156,31 +151,37 @@ namespace AdrianKousz.GenieEngine
|
|||
|
||||
var hasBitmap = reader.ReadBoolean();
|
||||
|
||||
result.BitmapWidth = reader.ReadInt32();
|
||||
result.BitmapHeight = reader.ReadInt32();
|
||||
result.BitmapUnknown = reader.ReadInt16();
|
||||
Skip(4, "Bitmap width");
|
||||
Skip(4, "Bitmap height");
|
||||
Skip(2, "Bitmap Unknown");
|
||||
|
||||
if (hasBitmap) {
|
||||
result.RawBitmap = BitmapUtil.ReadRawBitmap(reader.BaseStream);
|
||||
} else {
|
||||
result.RawBitmap = new byte[0];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public AIData ReadAIData()
|
||||
public AIData ReadAIData(AIData result)
|
||||
{
|
||||
var result = factory.MakeAIData();
|
||||
result = Misc.MayNew(result);
|
||||
|
||||
result.PlayerAIs = FillArray(reader.ReadStringInt16, result.PlayerAIs, Scenario.NumPlayers);
|
||||
result.PlayerCTYs = FillArray(reader.ReadStringInt16, result.PlayerCTYs, Scenario.NumPlayers);
|
||||
result.PlayerPERs = FillArray(reader.ReadStringInt16, result.PlayerPERs, Scenario.NumPlayers);
|
||||
result.PlayerAIs = new string[AdrianKousz.GenieEngine.Data.Consts.NumPlayers];
|
||||
result.PlayerCTYs = new string[AdrianKousz.GenieEngine.Data.Consts.NumPlayers];
|
||||
result.PlayerPERs = new string[AdrianKousz.GenieEngine.Data.Consts.NumPlayers];
|
||||
result.PlayerCustomAIs = new string[AdrianKousz.GenieEngine.Data.Consts.NumPlayers];
|
||||
result.PlayerCustomCTYs = new string[AdrianKousz.GenieEngine.Data.Consts.NumPlayers];
|
||||
result.PlayerCustomPERs = new string[AdrianKousz.GenieEngine.Data.Consts.NumPlayers];
|
||||
result.RawAITypes = new byte[AdrianKousz.GenieEngine.Data.Consts.NumPlayers];
|
||||
|
||||
result.PlayerCustomAIs = new string[Scenario.NumPlayers];
|
||||
result.PlayerCustomCTYs = new string[Scenario.NumPlayers];
|
||||
result.PlayerCustomPERs = new string[Scenario.NumPlayers];
|
||||
result.PlayerAIs.Fill(reader.ReadStringInt16);
|
||||
result.PlayerCTYs.Fill(reader.ReadStringInt16);
|
||||
result.PlayerPERs.Fill(reader.ReadStringInt16);
|
||||
|
||||
int l1, l2, l3;
|
||||
for (var i = 0; i < Scenario.NumPlayers; ++i) {
|
||||
for (var i = 0; i < AdrianKousz.GenieEngine.Data.Consts.NumPlayers; ++i) {
|
||||
l1 = reader.ReadInt32();
|
||||
l2 = reader.ReadInt32();
|
||||
l3 = reader.ReadInt32();
|
||||
|
@ -189,112 +190,88 @@ namespace AdrianKousz.GenieEngine
|
|||
result.PlayerCustomPERs[i] = reader.ReadString(l3);
|
||||
}
|
||||
|
||||
if (Version >= 1.18f) {
|
||||
result.AITypes = FillArray(reader.ReadByte, result.AITypes, Scenario.NumPlayers);
|
||||
if (1.18f <= version) {
|
||||
result.RawAITypes.Fill(reader.ReadByte);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public ResourceInfo ReadResourceInfo()
|
||||
public ResourceInfo ReadResourceInfo(ResourceInfo result)
|
||||
{
|
||||
var result = factory.MakeResourceInfo();
|
||||
result = Misc.MayNew(result);
|
||||
|
||||
result.Gold = reader.ReadInt32();
|
||||
result.Wood = reader.ReadInt32();
|
||||
result.Food = reader.ReadInt32();
|
||||
result.Stone = reader.ReadInt32();
|
||||
if (Version >= 1.18f) {
|
||||
if (1.18f <= version) {
|
||||
result.Ore = reader.ReadInt32();
|
||||
if (Version < 1.3f) {
|
||||
result.Unknown = reader.ReadInt32();
|
||||
}
|
||||
result.Unknown = reader.ReadInt32();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public ResourceInfoCopy ReadResourceInfoCopy()
|
||||
public Map ReadMap(Map result)
|
||||
{
|
||||
var result = factory.MakeResourceInfoCopy();
|
||||
result = Misc.MayNew(result);
|
||||
|
||||
result.Food = reader.ReadSingle();
|
||||
result.Wood = reader.ReadSingle();
|
||||
result.Gold = reader.ReadSingle();
|
||||
result.Stone = reader.ReadSingle();
|
||||
if (Version >= 1.18f) {
|
||||
result.Ore = reader.ReadInt32();
|
||||
if (Version < 1.3f) {
|
||||
result.Unknown = reader.ReadInt32();
|
||||
}
|
||||
}
|
||||
if (Version >= 1.22f) {
|
||||
result.PopulationLimit = reader.ReadSingle();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public GlobalVictoryInfo ReadGlobalVictoryInfo()
|
||||
{
|
||||
var result = factory.MakeGlobalVictoryInfo();
|
||||
|
||||
result.RequireConquest = reader.ReadBoolean();
|
||||
result.Ruins = reader.ReadInt32();
|
||||
result.Artifacts = reader.ReadInt32();
|
||||
result.Discovery = reader.ReadInt32();
|
||||
result.PercentExplored = reader.ReadInt32();
|
||||
result.Unknown = reader.ReadInt32();
|
||||
result.RequireAllCustom = reader.ReadBoolean();
|
||||
result.Mode = reader.ReadInt32();
|
||||
result.Score = reader.ReadInt32();
|
||||
result.Time = reader.ReadInt32();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Map ReadMap()
|
||||
{
|
||||
var result = factory.MakeMap();
|
||||
|
||||
if (Version >= 1.18f) {
|
||||
if (1.18f <= version) {
|
||||
result.CameraX = reader.ReadInt32();
|
||||
result.CameraY = reader.ReadInt32();
|
||||
}
|
||||
if (Version >= 1.22f) {
|
||||
if (1.22f <= version) {
|
||||
result.GeneratorId = reader.ReadInt32();
|
||||
}
|
||||
|
||||
result.SizeX = reader.ReadInt32();
|
||||
result.SizeY = reader.ReadInt32();
|
||||
|
||||
result.LinearTiles = new Map.Tile[result.SizeX * result.SizeY]
|
||||
.Fill(() => new Map.Tile(reader.ReadByte(), reader.ReadByte(), reader.ReadByte()));
|
||||
result.LinearTiles = new Map.Tile[result.SizeX * result.SizeY];
|
||||
result.LinearTiles.Fill(() => new Map.Tile(reader.ReadByte(), reader.ReadByte(), reader.ReadByte()));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public IList<UnitInfo> ReadUnitInfoList()
|
||||
public ResourceInfoCopy ReadResourceInfoCopy(ResourceInfoCopy result)
|
||||
{
|
||||
var count = reader.ReadInt32();
|
||||
var result = new List<UnitInfo>().Fill(ReadUnitInfo, count);
|
||||
result = Misc.MayNew(result);
|
||||
|
||||
result.Food = reader.ReadSingle();
|
||||
result.Wood = reader.ReadSingle();
|
||||
result.Gold = reader.ReadSingle();
|
||||
result.Stone = reader.ReadSingle();
|
||||
if (1.18f <= version) {
|
||||
result.Ore = reader.ReadInt32();
|
||||
result.Unknown = reader.ReadInt32();
|
||||
}
|
||||
if (1.22f <= version) {
|
||||
result.PopulationLimit = reader.ReadSingle();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public UnitInfo ReadUnitInfo()
|
||||
public IList<UnitInfo> ReadUnitInfo()
|
||||
{
|
||||
var result = factory.MakeUnitInfo();
|
||||
var number = reader.ReadInt32();
|
||||
var result = new List<UnitInfo>(number);
|
||||
|
||||
result.PosX = reader.ReadSingle();
|
||||
result.PosY = reader.ReadSingle();
|
||||
result.Unknown1 = reader.ReadSingle();
|
||||
result.Id = reader.ReadInt32();
|
||||
result.UnitId = reader.ReadInt16();
|
||||
result.Unknown2 = reader.ReadByte();
|
||||
result.Rotation = reader.ReadSingle();
|
||||
if (Version >= 1.18f) {
|
||||
result.InitialFrame = reader.ReadInt16();
|
||||
result.GarrisonnedInId = reader.ReadInt32();
|
||||
for (var i = 0; i < number; i++) {
|
||||
var unit = new UnitInfo();
|
||||
unit.PosX = reader.ReadSingle();
|
||||
unit.PosY = reader.ReadSingle();
|
||||
unit.Unknown1 = reader.ReadSingle();
|
||||
unit.Id = reader.ReadInt32();
|
||||
unit.UnitId = reader.ReadInt16();
|
||||
unit.Unknown2 = reader.ReadByte();
|
||||
unit.Rotation = reader.ReadSingle();
|
||||
if (1.18f <= version) {
|
||||
unit.InitialFrame = reader.ReadInt16();
|
||||
unit.GarrisonnedInId = reader.ReadInt32();
|
||||
}
|
||||
result.Add(unit);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -302,7 +279,7 @@ namespace AdrianKousz.GenieEngine
|
|||
|
||||
public void ReadSeparator(string name) {
|
||||
int v = reader.ReadInt32();
|
||||
if (v != Scenario.Separator) {
|
||||
if (v != AdrianKousz.GenieEngine.Data.Consts.Separator) {
|
||||
var msg = "Separator \"{0}\" = {1}";
|
||||
msg = string.Format(msg, name, v);
|
||||
throw new InvalidDataException(msg);
|
||||
|
@ -313,14 +290,26 @@ namespace AdrianKousz.GenieEngine
|
|||
|
||||
#region Debug Methods
|
||||
|
||||
private T[] FillArray<T>(System.Func<T> f, T[] array, int length)
|
||||
private T[] FillArray<T>(System.Func<T, T> f, T[] array, int length) where T : new()
|
||||
{
|
||||
if (array == null || array.Length != length)
|
||||
if (array == null) {
|
||||
array = new T[length];
|
||||
} else if (array.Length != length) {
|
||||
var temp = new T[length];
|
||||
System.Array.Copy(array, temp, System.Math.Min(array.Length, temp.Length));
|
||||
}
|
||||
|
||||
array.Fill(f);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
private void Skip(int count, string name)
|
||||
{
|
||||
Log.d(TAG, "Skipping {0} bytes in \"{1}\"", count, name);
|
||||
reader.ReadBytes(count);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Collections.Generic;
|
||||
using AdrianKousz.Util;
|
||||
using AdrianKousz.GenieEngine.Data;
|
||||
|
||||
|
@ -8,76 +6,18 @@ namespace AdrianKousz.GenieEngine
|
|||
{
|
||||
public class ScnWriter
|
||||
{
|
||||
public float Version = 0;
|
||||
private static readonly string TAG = typeof(ScnWriter).Name;
|
||||
|
||||
private ExtendedBinaryWriter writer;
|
||||
|
||||
public ScnWriter(Stream output)
|
||||
public ScnWriter(Stream input)
|
||||
{
|
||||
writer = new ExtendedBinaryWriter(output, Scenario.Encoding);
|
||||
}
|
||||
|
||||
public void Write(Scenario value)
|
||||
{
|
||||
Version = Version == 0 ? value.OriginalVersion : Version;
|
||||
|
||||
Write(value.Header);
|
||||
Flush();
|
||||
|
||||
// TODO: Make wrapper.
|
||||
// This is a workaround for now. A wrapper for the reader and writer will be created.
|
||||
var originalWriter = writer;
|
||||
var compressedPart = new MemoryStream();
|
||||
var comp = new DeflateStream(compressedPart, CompressionMode.Compress);
|
||||
writer = new ExtendedBinaryWriter(comp, Scenario.Encoding);
|
||||
|
||||
writer.Write(value.NextId);
|
||||
writer.Write(Version);
|
||||
|
||||
value.PlayerNames.ForEach((x) => writer.WriteStringPadded(x, 256));
|
||||
if (Version >= 1.18f) {
|
||||
value.StringTablePlayerNames.ForEach(writer.Write);
|
||||
}
|
||||
value.Players.ForEach(Write);
|
||||
Write(value.Messages);
|
||||
Write(value.Cinematics);
|
||||
Write(value.AIData);
|
||||
|
||||
WriteSeperator("Resources");
|
||||
|
||||
value.Resources.ForEach(Write);
|
||||
|
||||
WriteSeperator("Victory");
|
||||
|
||||
Write(value.GlobalVictory);
|
||||
value.LinearDiplomacy.ForEach(writer.Write);
|
||||
writer.Write(value.RawIndividualVictory);
|
||||
|
||||
WriteSeperator("Player Settings");
|
||||
|
||||
value.AlliedVictory.ForEach(writer.Write);
|
||||
writer.Write(value.RawDisables);
|
||||
value.StartingAges.ForEach(writer.Write);
|
||||
|
||||
WriteSeperator("Map");
|
||||
|
||||
Write(value.Map);
|
||||
|
||||
writer.Write((int)value.Units.Length);
|
||||
value.ResourcesCopy.ForEach(Write);
|
||||
value.Units.ForEach(Write);
|
||||
|
||||
writer.Write(value.RawRemaining);
|
||||
|
||||
Flush();
|
||||
|
||||
comp.Dispose();
|
||||
originalWriter.Write(compressedPart.ToArray());
|
||||
writer = new ExtendedBinaryWriter(input, Data.Consts.Encoding);
|
||||
}
|
||||
|
||||
public void Write(ScenarioHeader value)
|
||||
{
|
||||
var instructionlength = writer.GetZByteCount(value.Instructions);
|
||||
var instructionlength = writer.GetByteCount(value.Instructions + " ");
|
||||
writer.WriteStringRaw(value.OriginalVersion);
|
||||
writer.Write(20 + instructionlength);
|
||||
writer.Write(value.Unknown1);
|
||||
|
@ -87,180 +27,15 @@ namespace AdrianKousz.GenieEngine
|
|||
writer.Write(value.PlayerCount);
|
||||
}
|
||||
|
||||
public void Write(PlayerInfo value)
|
||||
public void WriteSeperator()
|
||||
{
|
||||
writer.Write(value.Active);
|
||||
writer.Write(value.Human);
|
||||
writer.Write(value.Civ);
|
||||
writer.Write(value.Unknown);
|
||||
}
|
||||
|
||||
public void Write(Messages value)
|
||||
{
|
||||
writer.Write(value.Unknown1);
|
||||
writer.Write(value.Unknown2);
|
||||
writer.Write(value.Unknown3);
|
||||
writer.WriteStringInt16(value.OriginalFilename);
|
||||
|
||||
if (Version >= 1.18f) {
|
||||
writer.Write(value.StringTableInstructions);
|
||||
writer.Write(value.StringTableHints);
|
||||
writer.Write(value.StringTableVictory);
|
||||
writer.Write(value.StringTableLoss);
|
||||
writer.Write(value.StringTableHistory);
|
||||
}
|
||||
if (Version >= 1.22f) {
|
||||
writer.Write(value.StringTableScouts);
|
||||
}
|
||||
|
||||
writer.WriteZStringInt16(value.TextInstructions);
|
||||
writer.WriteZStringInt16(value.TextHints);
|
||||
writer.WriteZStringInt16(value.TextVictory);
|
||||
writer.WriteZStringInt16(value.TextLoss);
|
||||
writer.WriteZStringInt16(value.TextHistory);
|
||||
if (Version >= 1.22f) {
|
||||
writer.WriteZStringInt16(value.TextScouts);
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(Cinematics value)
|
||||
{
|
||||
writer.WriteStringInt16(value.CinemaPregameFn);
|
||||
writer.WriteStringInt16(value.CinemaVictoryFn);
|
||||
writer.WriteStringInt16(value.CinemaLossFn);
|
||||
writer.WriteStringInt16(value.BackgroundFn);
|
||||
|
||||
var hasBitmap = value.RawBitmap.Length > 0;
|
||||
|
||||
writer.Write(hasBitmap);
|
||||
writer.Write(value.BitmapWidth);
|
||||
writer.Write(value.BitmapHeight);
|
||||
writer.Write(value.BitmapUnknown);
|
||||
|
||||
if (hasBitmap)
|
||||
writer.Write(value.RawBitmap);
|
||||
}
|
||||
|
||||
public void Write(AIData value)
|
||||
{
|
||||
value.PlayerAIs.ForEach(writer.WriteStringInt16);
|
||||
value.PlayerCTYs.ForEach(writer.WriteStringInt16);
|
||||
value.PlayerPERs.ForEach(writer.WriteStringInt16);
|
||||
|
||||
for (var i = 0; i < Scenario.NumPlayers; ++i) {
|
||||
var str1 = value.PlayerCustomAIs[i];
|
||||
var str2 = value.PlayerCustomCTYs[i];
|
||||
var str3 = value.PlayerCustomPERs[i];
|
||||
writer.Write(writer.GetByteCount(str1));
|
||||
writer.Write(writer.GetByteCount(str2));
|
||||
writer.Write(writer.GetByteCount(str3));
|
||||
writer.WriteStringRaw(str1);
|
||||
writer.WriteStringRaw(str2);
|
||||
writer.WriteStringRaw(str3);
|
||||
}
|
||||
|
||||
if (Version >= 1.18f) {
|
||||
value.AITypes.ForEach(writer.Write);
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(ResourceInfo value)
|
||||
{
|
||||
writer.Write(value.Gold);
|
||||
writer.Write(value.Wood);
|
||||
writer.Write(value.Food);
|
||||
writer.Write(value.Stone);
|
||||
if (Version >= 1.18f) {
|
||||
writer.Write(value.Ore);
|
||||
if (Version < 1.3f) {
|
||||
writer.Write(value.Unknown);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(ResourceInfoCopy value)
|
||||
{
|
||||
writer.Write(value.Food);
|
||||
writer.Write(value.Wood);
|
||||
writer.Write(value.Gold);
|
||||
writer.Write(value.Stone);
|
||||
if (Version >= 1.18f) {
|
||||
writer.Write(value.Ore);
|
||||
if (Version < 1.3f) {
|
||||
writer.Write(value.Unknown);
|
||||
}
|
||||
}
|
||||
if (Version >= 1.22f) {
|
||||
writer.Write(value.PopulationLimit);
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(GlobalVictoryInfo value)
|
||||
{
|
||||
writer.Write(value.RequireConquest);
|
||||
writer.Write(value.Ruins);
|
||||
writer.Write(value.Artifacts);
|
||||
writer.Write(value.Discovery);
|
||||
writer.Write(value.PercentExplored);
|
||||
writer.Write(value.Unknown);
|
||||
writer.Write(value.RequireAllCustom);
|
||||
writer.Write(value.Mode);
|
||||
writer.Write(value.Score);
|
||||
writer.Write(value.Time);
|
||||
}
|
||||
|
||||
public void Write(Map value)
|
||||
{
|
||||
if (Version >= 1.18f) {
|
||||
writer.Write(value.CameraX);
|
||||
writer.Write(value.CameraY);
|
||||
}
|
||||
if (Version >= 1.22f) {
|
||||
writer.Write(value.GeneratorId);
|
||||
}
|
||||
writer.Write(value.SizeX);
|
||||
writer.Write(value.SizeY);
|
||||
|
||||
value.LinearTiles.ForEach(x => { writer.Write(x.Id); writer.Write(x.Elevation); writer.Write(x.Unknown); });
|
||||
}
|
||||
|
||||
public void Write(IList<UnitInfo> value)
|
||||
{
|
||||
int number = value.Count;
|
||||
writer.Write(number);
|
||||
value.ForEach(Write);
|
||||
}
|
||||
|
||||
public void Write(UnitInfo value)
|
||||
{
|
||||
writer.Write(value.PosX);
|
||||
writer.Write(value.PosY);
|
||||
writer.Write(value.Unknown1);
|
||||
writer.Write(value.Id);
|
||||
writer.Write(value.UnitId);
|
||||
writer.Write(value.Unknown2);
|
||||
writer.Write(value.Rotation);
|
||||
if (Version >= 1.18f) {
|
||||
writer.Write(value.InitialFrame);
|
||||
writer.Write(value.GarrisonnedInId);
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteSeperator(string name)
|
||||
{
|
||||
writer.Write(Scenario.Separator);
|
||||
writer.Write(AdrianKousz.GenieEngine.Data.Consts.Separator);
|
||||
}
|
||||
|
||||
public void Flush()
|
||||
{
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
private void EnsureSetVersion()
|
||||
{
|
||||
if (Version <= 1)
|
||||
throw new System.InvalidOperationException("Set output version");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,11 +34,13 @@
|
|||
<ItemGroup>
|
||||
<Compile Include="AdrianKousz.GenieEngine\BitmapUtil.cs" />
|
||||
<Compile Include="AdrianKousz.GenieEngine\CpnReader.cs" />
|
||||
<Compile Include="AdrianKousz.GenieEngine\ScnFactory.cs" />
|
||||
<Compile Include="AdrianKousz.GenieEngine\ScnReader.cs" />
|
||||
<Compile Include="AdrianKousz.GenieEngine\ScnValidator.cs" />
|
||||
<Compile Include="AdrianKousz.GenieEngine\ScnWriter.cs" />
|
||||
<Compile Include="AdrianKousz.GenieEngine.Data\AIData.cs" />
|
||||
<Compile Include="AdrianKousz.GenieEngine.Data\Cinematics.cs" />
|
||||
<Compile Include="AdrianKousz.GenieEngine.Data\Consts.cs" />
|
||||
<Compile Include="AdrianKousz.GenieEngine.Data\Map.cs" />
|
||||
<Compile Include="AdrianKousz.GenieEngine.Data\Messages.cs" />
|
||||
<Compile Include="AdrianKousz.GenieEngine.Data\PlayerInfo.cs" />
|
||||
|
@ -48,10 +50,6 @@
|
|||
<Compile Include="AdrianKousz.GenieEngine.Data\ScenarioHeader.cs" />
|
||||
<Compile Include="AdrianKousz.GenieEngine.Data\UnitInfo.cs" />
|
||||
<Compile Include="AssemblyInfo.cs" />
|
||||
<Compile Include="AdrianKousz.GenieEngine.Data\GlobalVictoryInfo.cs" />
|
||||
<Compile Include="AdrianKousz.GenieEngine\ScnConvert.cs" />
|
||||
<Compile Include="AdrianKousz.GenieEngine\ScnDefaultFactory.cs" />
|
||||
<Compile Include="AdrianKousz.GenieEngine\IScnFactory.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue