Compare commits
2 Commits
3cb2c123f2
...
7694fb0c03
Author | SHA1 | Date |
---|---|---|
Adrian | 7694fb0c03 | |
Adrian | 982dc159cf |
|
@ -9,9 +9,9 @@ namespace AdrianKousz.GenieEngine
|
|||
Scenario.ScnPlayerSettings MakePlayerSettings();
|
||||
Scenario.ScnMessages MakeMessages();
|
||||
Scenario.ScnCinematics MakeCinematics();
|
||||
Scenario.ScnGlobalVictory MakeGlobalVictoryInfo();
|
||||
Scenario.ScnResourceCopy MakeResourceCopyInfo();
|
||||
Scenario.ScnGlobalVictory MakeGlobalVictory();
|
||||
Scenario.ScnResourceCopy MakeResourceCopy();
|
||||
Scenario.ScnMap MakeMap();
|
||||
Scenario.ScnUnit MakeUnitInfo();
|
||||
Scenario.ScnUnit MakeUnit();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,10 +27,19 @@ namespace AdrianKousz.GenieEngine
|
|||
result.Timestamp = System.DateTime.Now;
|
||||
result.PlayerCount = 2;
|
||||
|
||||
if (deep) {
|
||||
result.Messages = MakeMessages();
|
||||
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();
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -53,8 +62,7 @@ namespace AdrianKousz.GenieEngine
|
|||
result.ResourceGold = 100;
|
||||
result.ResourceStone = 100;
|
||||
result.StartingAge = -1;
|
||||
result.Diplomacy = new int[Scenario.NumPlayers];
|
||||
result.Diplomacy.Fill(3);
|
||||
result.Diplomacy = new int[Scenario.NumPlayers].Fill(3);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,292 @@
|
|||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Collections.Generic;
|
||||
using AdrianKousz.Util;
|
||||
|
||||
namespace AdrianKousz.GenieEngine
|
||||
{
|
||||
public class ScnSerializerReader
|
||||
{
|
||||
private IScnFactory factory;
|
||||
|
||||
public static ScnSerializerReader CreateDefault()
|
||||
{
|
||||
var factory = new ScnDefaultFactory();
|
||||
return new ScnSerializerReader(factory);
|
||||
}
|
||||
|
||||
private ScnSerializerReader(IScnFactory factory)
|
||||
{
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public Scenario ReadScenario(ExtendedBinaryReader reader)
|
||||
{
|
||||
var Version = 0f;
|
||||
var number = 0;
|
||||
var result = factory is ScnDefaultFactory
|
||||
? factory.MakeScenario(false)
|
||||
: factory.MakeScenario();
|
||||
|
||||
// Uncompressed header
|
||||
|
||||
result.VersionString = reader.ReadString(4);
|
||||
reader.ReadInt32(); // Header Length
|
||||
result.Unknown1 = reader.ReadInt32();
|
||||
result.Timestamp = DateTimes.FromUnixTime(reader.ReadInt32());
|
||||
result.InstructionsUncompressed = reader.ReadZStringInt32();
|
||||
result.Unknown2 = reader.ReadInt32();
|
||||
result.PlayerCount = reader.ReadInt32();
|
||||
|
||||
// Compression starts
|
||||
|
||||
var originalReader = reader;
|
||||
var compressedPart = new NonDisposingStreamWrapper(reader.BaseStream);
|
||||
var comp = new DeflateStream(compressedPart, CompressionMode.Decompress);
|
||||
reader = new ExtendedBinaryReader(comp, originalReader.Encoding);
|
||||
|
||||
result.NextId = reader.ReadInt32();
|
||||
result.VersionNumber = reader.ReadSingle();
|
||||
Version = result.VersionNumber;
|
||||
|
||||
result.PlayerSettings = new Scenario.ScnPlayerSettings[Scenario.NumPlayers]
|
||||
.Fill(factory.MakePlayerSettings);
|
||||
|
||||
// PlayerSettings 1
|
||||
|
||||
result.PlayerSettings.ForEach(x => {
|
||||
x.Name = reader.ReadZString(256);
|
||||
});
|
||||
|
||||
if (Version >= 1.18f) {
|
||||
result.PlayerSettings.ForEach(x => {
|
||||
x.NameStringID = reader.ReadInt32();
|
||||
});
|
||||
}
|
||||
|
||||
result.PlayerSettings.ForEach(x => {
|
||||
x.Active = reader.ReadBoolean();
|
||||
x.Human = reader.ReadBoolean();
|
||||
x.Civ = reader.ReadInt32();
|
||||
x.UnknownInfo = reader.ReadInt32();
|
||||
});
|
||||
|
||||
result.Unknown3 = reader.ReadInt32();
|
||||
result.Unknown4 = reader.ReadSByte();
|
||||
result.Unknown5 = reader.ReadSingle();
|
||||
|
||||
result.Filename = reader.ReadStringInt16();
|
||||
|
||||
// Messages
|
||||
|
||||
result.Messages = factory.MakeMessages();
|
||||
|
||||
if (Version >= 1.18f) {
|
||||
result.Messages.InstructionsStringID = reader.ReadInt32();
|
||||
result.Messages.HintsStringID = reader.ReadInt32();
|
||||
result.Messages.VictoryStringID = reader.ReadInt32();
|
||||
result.Messages.LossStringID = reader.ReadInt32();
|
||||
result.Messages.HistoryStringID = reader.ReadInt32();
|
||||
}
|
||||
if (Version >= 1.22f) {
|
||||
result.Messages.ScoutsStringID = reader.ReadInt32();
|
||||
}
|
||||
|
||||
result.Messages.Instructions = reader.ReadZStringInt16();
|
||||
result.Messages.Hints = reader.ReadZStringInt16();
|
||||
result.Messages.Victory = reader.ReadZStringInt16();
|
||||
result.Messages.Loss = reader.ReadZStringInt16();
|
||||
result.Messages.History = reader.ReadZStringInt16();
|
||||
if (Version >= 1.22f) {
|
||||
result.Messages.Scouts = reader.ReadZStringInt16();
|
||||
}
|
||||
|
||||
// Cinematics
|
||||
|
||||
result.Cinematics = factory.MakeCinematics();
|
||||
|
||||
result.Cinematics.FilenamePregame = reader.ReadStringInt16();
|
||||
result.Cinematics.FilenameVictory = reader.ReadStringInt16();
|
||||
result.Cinematics.FilenameLoss = reader.ReadStringInt16();
|
||||
result.Cinematics.FilenameBitmap = reader.ReadStringInt16();
|
||||
|
||||
var hasBitmap = reader.ReadBoolean();
|
||||
|
||||
result.Cinematics.BitmapWidth = reader.ReadInt32();
|
||||
result.Cinematics.BitmapHeight = reader.ReadInt32();
|
||||
result.Cinematics.BitmapUnknown = reader.ReadInt16();
|
||||
|
||||
if (hasBitmap) {
|
||||
result.Cinematics.RawBitmap = BitmapUtil.ReadRawBitmap(reader.BaseStream);
|
||||
}
|
||||
|
||||
// PlayerSettings 2
|
||||
|
||||
result.PlayerSettings.ForEach(x => {
|
||||
x.FilenameAI = reader.ReadStringInt16();
|
||||
x.FilenameCTY = reader.ReadStringInt16();
|
||||
x.FilenamePER = reader.ReadStringInt16();
|
||||
});
|
||||
|
||||
result.PlayerSettings.ForEach(x => {
|
||||
var l1 = reader.ReadInt32();
|
||||
var l2 = reader.ReadInt32();
|
||||
var l3 = reader.ReadInt32();
|
||||
x.ScriptAI = reader.ReadString(l1);
|
||||
x.ScriptCTY = reader.ReadString(l2);
|
||||
x.ScriptPER = reader.ReadString(l3);
|
||||
});
|
||||
|
||||
if (Version >= 1.18f) {
|
||||
result.PlayerSettings.ForEach(x => {
|
||||
x.AIType = reader.ReadSByte();
|
||||
});
|
||||
}
|
||||
|
||||
ReadSeparator(reader, "Resources");
|
||||
|
||||
// Resources
|
||||
|
||||
result.PlayerSettings.ForEach(x => {
|
||||
x.ResourceGold = reader.ReadInt32();
|
||||
x.ResourceWood = reader.ReadInt32();
|
||||
x.ResourceFood = reader.ReadInt32();
|
||||
x.ResourceStone = reader.ReadInt32();
|
||||
if (Version >= 1.18f) {
|
||||
x.ResourceOre = reader.ReadInt32();
|
||||
if (Version < 1.3f) {
|
||||
x.UnknownResource = reader.ReadInt32();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ReadSeparator(reader, "Victory");
|
||||
|
||||
// Diplomacy
|
||||
|
||||
result.GlobalVictory = factory.MakeGlobalVictory();
|
||||
|
||||
result.GlobalVictory.RequireConquest = reader.ReadBoolean();
|
||||
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.Mode = reader.ReadInt32();
|
||||
result.GlobalVictory.Score = reader.ReadInt32();
|
||||
result.GlobalVictory.Time = reader.ReadInt32();
|
||||
|
||||
// PlayerSettings 3
|
||||
|
||||
result.PlayerSettings.ForEach(x => {
|
||||
x.Diplomacy = new int[Scenario.NumPlayers].Fill(reader.ReadInt32());
|
||||
});
|
||||
|
||||
result.RawIndividualVictory = reader.ReadBytes(11520);
|
||||
|
||||
ReadSeparator(reader, "Player Environment");
|
||||
|
||||
result.PlayerSettings.ForEach(x => {
|
||||
x.AlliedVictory = reader.ReadInt32();
|
||||
});
|
||||
|
||||
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*/;
|
||||
result.RawDisables = reader.ReadBytes(number);
|
||||
|
||||
result.PlayerSettings.ForEach(x => {
|
||||
x.StartingAge = reader.ReadInt32();
|
||||
});
|
||||
|
||||
ReadSeparator("Map");
|
||||
|
||||
// Map
|
||||
|
||||
result.Map = factory.MakeMap();
|
||||
|
||||
if (Version >= 1.18f) {
|
||||
result.Map.CameraX = reader.ReadInt32();
|
||||
result.Map.CameraY = reader.ReadInt32();
|
||||
}
|
||||
if (Version >= 1.22f) {
|
||||
result.Map.GeneratorId = reader.ReadInt32();
|
||||
}
|
||||
result.Map.SizeX = reader.ReadInt32();
|
||||
result.Map.SizeY = reader.ReadInt32();
|
||||
|
||||
result.Map.LinearTiles = new Scenario.ScnMap.Tile[result.Map.SizeX * result.Map.SizeY]
|
||||
.Fill(() => new Scenario.ScnMap.Tile(reader.ReadSByte(), reader.ReadSByte(), reader.ReadSByte()));
|
||||
|
||||
// ResourceCopies
|
||||
|
||||
number = reader.ReadInt32();
|
||||
|
||||
result.ResourceCopies = new Scenario.ScnResourceCopy[number - 1]
|
||||
.Fill(factory.MakeResourceCopy);
|
||||
|
||||
result.ResourceCopies.ForEach(x => {
|
||||
x.ResourceFood = reader.ReadSingle();
|
||||
x.ResourceWood = reader.ReadSingle();
|
||||
x.ResourceGold = reader.ReadSingle();
|
||||
x.ResourceStone = reader.ReadSingle();
|
||||
if (Version >= 1.18f) {
|
||||
x.ResourceOre = reader.ReadInt32();
|
||||
if (Version < 1.3f) {
|
||||
x.UnknownResource = reader.ReadInt32();
|
||||
}
|
||||
}
|
||||
if (Version >= 1.22f) {
|
||||
x.PopulationLimit = reader.ReadSingle();
|
||||
}
|
||||
});
|
||||
|
||||
// Units
|
||||
|
||||
result.Units = new List<Scenario.ScnUnit>[number].Fill();
|
||||
|
||||
result.Units.ForEach(x => {
|
||||
var count = reader.ReadInt32();
|
||||
x.Fill(() => {
|
||||
var unit = factory.MakeUnit();
|
||||
unit.PosX = reader.ReadSingle();
|
||||
unit.PosY = reader.ReadSingle();
|
||||
unit.Unknown1 = reader.ReadSingle();
|
||||
unit.Id = reader.ReadInt32();
|
||||
unit.UnitId = reader.ReadInt16();
|
||||
unit.Unknown2 = reader.ReadSByte();
|
||||
unit.Rotation = reader.ReadSingle();
|
||||
if (Version >= 1.18f) {
|
||||
unit.InitialFrame = reader.ReadInt16();
|
||||
unit.GarrisonnedInId = reader.ReadInt32();
|
||||
}
|
||||
return unit;
|
||||
}, count);
|
||||
});
|
||||
|
||||
// More Player Settings and Triggers
|
||||
|
||||
var bytestream = new MemoryStream();
|
||||
reader.BaseStream.CopyTo(bytestream);
|
||||
result.RawRemaining = bytestream.ToArray();
|
||||
|
||||
// End of reading
|
||||
|
||||
reader.Dispose();
|
||||
comp.Dispose();
|
||||
compressedPart.Dispose();
|
||||
return result;
|
||||
}
|
||||
|
||||
public void ReadSeparator(ExtendedBinaryReader reader, string name) {
|
||||
int v = reader.ReadInt32();
|
||||
if (v != Scenario.Separator) {
|
||||
var msg = "Separator \"{0}\" = {1}";
|
||||
msg = string.Format(msg, name, v);
|
||||
throw new InvalidDataException(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ namespace AdrianKousz.GenieEngine
|
|||
var originalWriter = writer;
|
||||
var compressedPart = new MemoryStream();
|
||||
var comp = new DeflateStream(compressedPart, CompressionMode.Compress);
|
||||
writer = new ExtendedBinaryWriter(comp, writer.Encoding);
|
||||
writer = new ExtendedBinaryWriter(comp, originalWriter.Encoding);
|
||||
|
||||
writer.Write(value.NextId);
|
||||
writer.Write(value.VersionNumber);
|
||||
|
@ -54,10 +54,10 @@ namespace AdrianKousz.GenieEngine
|
|||
}
|
||||
|
||||
value.PlayerSettings.ForEach(x => {
|
||||
writer.WriteStringPadded(x.Active);
|
||||
writer.WriteStringPadded(x.Human);
|
||||
writer.WriteStringPadded(x.Civ);
|
||||
writer.WriteStringPadded(x.UnknownInfo);
|
||||
writer.Write(x.Active);
|
||||
writer.Write(x.Human);
|
||||
writer.Write(x.Civ);
|
||||
writer.Write(x.UnknownInfo);
|
||||
});
|
||||
|
||||
writer.Write(value.Unknown3);
|
||||
|
@ -125,11 +125,13 @@ namespace AdrianKousz.GenieEngine
|
|||
writer.WriteStringRaw(x.ScriptPER);
|
||||
});
|
||||
|
||||
if (Version >= 1.18f) {
|
||||
value.PlayerSettings.ForEach(x => {
|
||||
writer.Write(x.AIType);
|
||||
});
|
||||
}
|
||||
|
||||
WriteSeperator(writer, "Resources");
|
||||
WriteSeparator(writer, "Resources");
|
||||
|
||||
// Resources
|
||||
|
||||
|
@ -146,7 +148,7 @@ namespace AdrianKousz.GenieEngine
|
|||
}
|
||||
});
|
||||
|
||||
WriteSeperator(writer, "Victory");
|
||||
WriteSeparator(writer, "Victory");
|
||||
|
||||
// Diplomacy
|
||||
|
||||
|
@ -171,7 +173,7 @@ namespace AdrianKousz.GenieEngine
|
|||
|
||||
writer.Write(value.RawIndividualVictory);
|
||||
|
||||
WriteSeperator(writer, "Player Environment");
|
||||
WriteSeparator(writer, "Player Environment");
|
||||
|
||||
value.PlayerSettings.ForEach(x => {
|
||||
writer.Write(x.AlliedVictory);
|
||||
|
@ -183,7 +185,7 @@ namespace AdrianKousz.GenieEngine
|
|||
writer.Write(x.StartingAge);
|
||||
});
|
||||
|
||||
WriteSeperator(writer, "Map");
|
||||
WriteSeparator(writer, "Map");
|
||||
|
||||
// Map
|
||||
|
||||
|
@ -246,12 +248,15 @@ namespace AdrianKousz.GenieEngine
|
|||
|
||||
writer.Write(value.RawRemaining);
|
||||
|
||||
// End of writing
|
||||
|
||||
writer.Dispose();
|
||||
comp.Dispose();
|
||||
compressedPart.Dispose();
|
||||
originalWriter.Write(compressedPart.ToArray());
|
||||
}
|
||||
|
||||
public void WriteSeperator(ExtendedBinaryWriter writer, string name)
|
||||
public void WriteSeparator(ExtendedBinaryWriter writer, string name)
|
||||
{
|
||||
writer.Write(Scenario.Separator);
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
<Compile Include="AdrianKousz.GenieEngine\IScnFactory.cs" />
|
||||
<Compile Include="AdrianKousz.GenieEngine\ScnSerializerWriter.cs" />
|
||||
<Compile Include="AdrianKousz.GenieEngine\Scenario.cs" />
|
||||
<Compile Include="AdrianKousz.GenieEngine\ScnSerializerReader.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
|
|
Loading…
Reference in New Issue