Deserialize/Serialize Weapons Factory Store and Container !

This commit is contained in:
Li 2023-01-09 17:32:49 -08:00
parent 835c9002ab
commit 3b89a6967f
9 changed files with 238 additions and 114 deletions

View File

@ -19,14 +19,12 @@ namespace LibW4M.Data
return guid.ToString();
}
}
public abstract void Delete();
public abstract void Load();
public abstract void Save();
public SaveDataEntry (W4SaveFile fileBelongs, XomContainer mainContainer)
{
this.fileBelongs = fileBelongs;
this.mainContainer = mainContainer;
this.Load();
}
}
}

View File

@ -6,11 +6,12 @@ using System.Threading.Tasks;
namespace LibW4M.Data.WeaponFactory
{
public enum WeaponType : int
public enum Detonation : int
{
StopsMoving = 0,
Impact = 0,
Fuse = 1,
User = 2
User = 2,
StopsMoving = 3,
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LibW4M.Data.WeaponFactory
{
public enum ProjectileLaunchType : int
{
AirStrike = 0
Launched = 1,
Thrown = 2
}
}

View File

@ -0,0 +1,153 @@
using LibXom.Data;
using LibXom.Streams;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace LibW4M.Data.WeaponFactory
{
internal class WeaponData
{
private XomFile saveFile;
private XomString WeaponName;
public int Type;
public Detonation DetonationType;
public bool Homing;
public bool HomingAvoidLand;
public bool EffectedByWind;
public bool FireOnGround;
public bool Poison;
public int RetreatTime;
public float WormDamageRadius;
public float WormDamageMagnitude;
public float LandDamageRadius;
public float ProjectileCollisionRadius;
public float Push;
public int FuseTime;
public int[] GraphicalResourceIds;
public int[] GraphicalLocatorIds;
public XomString LaunchFX;
public XomString ArielFX;
public XomString DetonationFX;
public int PayloadResourceId;
public ProjectileLaunchType ProjectileLaunchType;
public bool ProjectilePowersUp;
public int ProjectileNumClusters;
public float ProjectileMaxPower;
public float ClusterSpread;
public float ClusterMaxSpeed;
internal byte[] serialize()
{
using (XomStreamWriter writer = new XomStreamWriter(new MemoryStream()))
{
writer.Skip(3);
writer.WriteCompressedInt(this.WeaponName.Id);
writer.WriteInt32(this.Type);
writer.WriteInt32((int)this.DetonationType);
writer.WriteBool(this.Homing);
writer.WriteBool(this.HomingAvoidLand);
writer.WriteBool(this.EffectedByWind);
writer.WriteBool(this.FireOnGround);
writer.WriteBool(this.Poison);
writer.WriteInt32(this.RetreatTime);
writer.WriteFloat(this.WormDamageRadius);
writer.WriteFloat(this.WormDamageMagnitude);
writer.WriteFloat(this.LandDamageRadius);
writer.WriteFloat(this.ProjectileCollisionRadius);
writer.WriteFloat(this.Push);
writer.WriteInt32(this.FuseTime);
writer.WriteCompressedIntArray(this.GraphicalResourceIds);
writer.WriteCompressedIntArray(this.GraphicalLocatorIds);
writer.WriteCompressedInt(this.LaunchFX.Id);
writer.WriteCompressedInt(this.ArielFX.Id);
writer.WriteCompressedInt(this.DetonationFX.Id);
writer.WriteInt32(this.PayloadResourceId);
writer.WriteInt32((int)this.ProjectileLaunchType);
writer.WriteBool(this.ProjectilePowersUp);
writer.WriteInt32(this.ProjectileNumClusters);
writer.WriteFloat(this.ProjectileMaxPower);
writer.WriteFloat(this.ClusterSpread);
writer.WriteFloat(this.ClusterMaxSpeed);
writer.Skip(1);
writer.BaseStream.Seek(0x00, SeekOrigin.Begin);
MemoryStream ms = (MemoryStream)(writer.BaseStream).ToArray();
}
}
internal void deserailize(byte[] data)
{
using (XomStreamReader reader = new XomStreamReader(new MemoryStream(data)))
{
reader.Skip(3);
this.WeaponName = saveFile.GetStringById(reader.ReadCompressedInt());
this.Type = reader.ReadInt32();
this.DetonationType = (Detonation)reader.ReadInt32();
this.Homing = reader.ReadBool();
this.HomingAvoidLand = reader.ReadBool();
this.EffectedByWind = reader.ReadBool();
this.FireOnGround = reader.ReadBool();
this.Poison = reader.ReadBool();
this.RetreatTime = reader.ReadInt32();
this.WormDamageRadius = reader.ReadFloat();
this.WormDamageMagnitude = reader.ReadFloat();
this.LandDamageRadius = reader.ReadFloat();
this.ProjectileCollisionRadius = reader.ReadFloat();
this.Push = reader.ReadFloat();
this.FuseTime = reader.ReadInt32();
this.GraphicalResourceIds = reader.ReadCompressedIntArray();
this.GraphicalLocatorIds = reader.ReadCompressedIntArray();
this.LaunchFX = saveFile.GetStringById(reader.ReadCompressedInt());
this.ArielFX = saveFile.GetStringById(reader.ReadCompressedInt());
this.DetonationFX = saveFile.GetStringById(reader.ReadCompressedInt());
this.PayloadResourceId = reader.ReadInt32();
this.ProjectileLaunchType = (ProjectileLaunchType)reader.ReadInt32();
this.ProjectilePowersUp = reader.ReadBool();
this.ProjectileNumClusters = reader.ReadInt32();
this.ProjectileMaxPower = reader.ReadFloat();
this.ClusterSpread = reader.ReadFloat();
this.ClusterMaxSpeed = reader.ReadFloat();
reader.Skip(1);
}
}
internal WeaponData(byte[] data, XomFile saveFile)
{
this.saveFile = saveFile;
this.deserailize(data);
}
}
}

View File

@ -12,56 +12,17 @@ namespace LibW4M.Data.WeaponFactory
internal class WeaponEntry : SaveDataEntry
{
private int weaponNameId;
public string WeaponName
{
get
{
return this.fileBelongs.w4Save.GetStringById(this.weaponNameId).Value;
}
}
public WeaponData Weapon;
public WeaponData Cluster;
private int weaponType;
private WeaponType detonationType;
private bool homing;
private bool homingAvoidLand;
private bool effectedByWind;
private bool fireOnGround;
private bool poison;
private int retreatTime;
private float wormDamageRadius;
private float wormDamageMagnitude;
private float landDamageRadius;
private float projectileCollisionRadius;
private float push;
private int fuseTime;
private int[] graphicalResourceIds;
private int[] graphicalLocatorIds;
private int launchFX;
private int arielFX;
private int detonationFX;
private int payloadResourceId;
private int projectileLaunchType;
private bool projectilePowersUp;
private int projectileNumClusters;
private float projectileMaxPower;
private float clusterSpread;
private float clusterMaxSpeed;
private XomContainer[] dataContainers;
private XomContainer weaponContainer;
private XomContainer clusterContainer;
public WeaponEntry(W4SaveFile fileBelongs, XomContainer mainContainer) : base(fileBelongs, mainContainer)
{
this.Load();
}
public override void Delete()
{
throw new NotImplementedException();
@ -69,67 +30,23 @@ namespace LibW4M.Data.WeaponFactory
public override void Load()
{
int[] sWpFc = this.mainContainer.Decompress();
XomContainer top = this.fileBelongs.w4Save.GetContainerById(sWpFc[1]);
XomContainer btm = this.fileBelongs.w4Save.GetContainerById(sWpFc[1]);
int[] weaponStore = this.mainContainer.Decompress();
this.weaponContainer = this.fileBelongs.xomFile.GetContainerById(weaponStore[1]);
this.clusterContainer = this.fileBelongs.xomFile.GetContainerById(weaponStore[2]);
// parse top
using(XomStreamReader reader = new XomStreamReader(new MemoryStream(top.GetData())))
{
this.weaponNameId = XomCompressor.DecompressInt(reader.ReadInt32());
reader.Skip(1);
this.detonationType = (WeaponType)reader.ReadInt32();
reader.Skip(1);
this.homing = (reader.ReadByte() == 0x01);
this.homingAvoidLand = (reader.ReadByte() == 0x01);
this.effectedByWind = (reader.ReadByte() == 0x01);
this.fireOnGround = (reader.ReadByte() == 0x01);
this.poison = (reader.ReadByte() == 0x01);
this.retreatTime = reader.ReadInt32();
this.wormDamageRadius = reader.ReadFloat();
this.wormDamageMagnitude = reader.ReadFloat();
this.landDamageRadius = reader.ReadFloat();
this.projectileCollisionRadius = reader.ReadFloat();
this.push = reader.ReadFloat();
this.fuseTime = reader.ReadInt32();
// read GraphicalResourceIds
int totalGraphicalResourceIds = reader.ReadCompressedInt();
this.graphicalResourceIds = new int[totalGraphicalResourceIds];
for (int i = 0; i < totalGraphicalResourceIds; i++) this.graphicalResourceIds[i] = reader.ReadCompressedInt();
// read GraphicalLocatorIds
int totalGraphicalLocatorIds = reader.ReadCompressedInt();
this.graphicalLocatorIds = new int[totalGraphicalLocatorIds];
for (int i = 0; i < totalGraphicalLocatorIds; i++) this.graphicalLocatorIds[i] = reader.ReadCompressedInt();
this.launchFX = reader.ReadCompressedInt();
this.arielFX = reader.ReadCompressedInt();
this.detonationFX = reader.ReadCompressedInt();
this.payloadResourceId = reader.ReadInt32();
this.projectileLaunchType = reader.ReadInt32();
this.projectilePowersUp = (reader.ReadByte() == 0x01);
this.projectileNumClusters = reader.ReadInt32();
this.projectileMaxPower = reader.ReadFloat();
this.clusterSpread = reader.ReadFloat();
this.clusterMaxSpeed = reader.ReadFloat();
}
// parse btm
this.Weapon = new WeaponData(this.weaponContainer.GetData(), this.fileBelongs.xomFile);
this.Cluster = new WeaponData(this.clusterContainer.GetData(), this.fileBelongs.xomFile);
}
public override void Save()
{
throw new NotImplementedException();
this.weaponContainer.SetData(this.Weapon.serialize());
this.clusterContainer.SetData(this.Cluster.serialize());
int[] weaponStore = this.mainContainer.Decompress();
weaponStore[1] = this.weaponContainer.Id;
weaponStore[2] = this.clusterContainer.Id;
this.mainContainer.CompressAndUpdate(weaponStore);
}
}
}

View File

@ -5,10 +5,10 @@ namespace LibW4M
public class W4SaveFile
{
public XomFile w4Save;
public XomFile xomFile;
public W4SaveFile(XomFile w4Save)
{
this.w4Save = w4Save;
this.xomFile = w4Save;
}
}
}

View File

@ -11,7 +11,7 @@ namespace LibXom.Data
{
public class XomCompressor
{
private static int getNumberByteCount(int num)
internal static int getNumberByteCount(int num)
{
uint unum = Convert.ToUInt32(num);
if (unum <= 0xFF) return 1;
@ -35,16 +35,20 @@ namespace LibXom.Data
return DecompressInt(BitConverter.ToInt32(buffer));
}
internal static void compressIntAndWriteToStream(Stream s, int uncompressedInt)
{
int c = XomCompressor.CompressInt(uncompressedInt);
int sz = XomCompressor.getNumberByteCount(c);
byte[] buffer = BitConverter.GetBytes(c);
s.Write(buffer, 0x00, sz);
}
internal static byte[] compressBuffer(int[] input)
{
using(MemoryStream ms = new MemoryStream())
{
foreach(int enc in input)
{
int c = CompressInt(enc);
int sz = getNumberByteCount(c);
byte[] buffer = BitConverter.GetBytes(c);
ms.Write(buffer, 0x00, sz);
compressIntAndWriteToStream(ms, enc);
}
ms.Seek(0, SeekOrigin.Begin);
return ms.ToArray();

View File

@ -17,6 +17,15 @@ namespace LibXom.Streams
return xStream;
}
}
public int[] ReadCompressedIntArray()
{
int len = this.ReadCompressedInt();
int[] arr = new int[len];
for(int i = 0; i < len; i++) arr[i] = this.ReadCompressedInt();
return arr;
}
public int ReadCompressedInt()
{
return XomCompressor.ReadCompressedIntFromStream(xStream);
@ -27,6 +36,10 @@ namespace LibXom.Streams
xStream.Read(buffer, 0, amt);
return buffer;
}
public bool ReadBool()
{
return (ReadByte() == 0x01);
}
public byte ReadByte()
{
return Convert.ToByte(xStream.ReadByte());

View File

@ -1,4 +1,5 @@
using System;
using LibXom.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -53,10 +54,32 @@ namespace LibXom.Streams
buf[i] = pad;
WriteBytes(buf);
}
public void WriteCompressedIntArray(int[] uncompressedArr)
{
this.WriteCompressedInt(uncompressedArr.Length);
for (int i = 0; i < uncompressedArr.Length; i++) WriteCompressedInt(uncompressedArr[i]);
}
public void WriteCompressedInt(int uncompressedInt)
{
XomCompressor.compressIntAndWriteToStream(xStream, uncompressedInt);
}
public void WriteBytes(byte[] bytes)
{
xStream.Write(bytes, 0, bytes.Length);
}
public void WriteBool(bool value)
{
if (value) this.WriteByte(0x01);
else this.WriteByte(0x00);
}
public void WriteFloat(float value)
{
byte[] buffer = BitConverter.GetBytes(value);
WriteBytes(buffer);
}
public void WriteInt32(int value)
{
byte[] buffer = BitConverter.GetBytes(value);