diff --git a/LibW4M/Data/Highscores/HighscoreCollective.cs b/LibW4M/Data/Highscores/HighscoreCollective.cs index b032ee1..4403585 100644 --- a/LibW4M/Data/Highscores/HighscoreCollective.cs +++ b/LibW4M/Data/Highscores/HighscoreCollective.cs @@ -13,6 +13,11 @@ namespace LibW4M.Data.Highscores { } + public override void Create() + { + throw new NotImplementedException(); + } + public override void Load() { // highscore data is stored after teams data section of TeamDataCollective. diff --git a/LibW4M/Data/InputMapping/InputMappingCollective.cs b/LibW4M/Data/InputMapping/InputMappingCollective.cs index c4a4483..443ea81 100644 --- a/LibW4M/Data/InputMapping/InputMappingCollective.cs +++ b/LibW4M/Data/InputMapping/InputMappingCollective.cs @@ -2,6 +2,7 @@ using LibXom.Data; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -14,6 +15,11 @@ namespace LibW4M.Data.InputMapping { } + public override void Create() + { + throw new NotImplementedException(); + } + public override void Load() { int[] collective = mainContainer.Decompress(); @@ -39,5 +45,10 @@ namespace LibW4M.Data.InputMapping } mainContainer.CompressAndUpdate(collective); } + + private string GetDebuggerDisplay() + { + return ToString(); + } } } diff --git a/LibW4M/Data/SaveDataCollective.cs b/LibW4M/Data/SaveDataCollective.cs index cdd370a..39d4545 100644 --- a/LibW4M/Data/SaveDataCollective.cs +++ b/LibW4M/Data/SaveDataCollective.cs @@ -48,7 +48,7 @@ namespace LibW4M.Data } } } - + public abstract void Create(); public abstract override void Load(); public abstract override void Save(); diff --git a/LibW4M/Data/SaveDataEntry.cs b/LibW4M/Data/SaveDataEntry.cs index 0904cee..70aa9e6 100644 --- a/LibW4M/Data/SaveDataEntry.cs +++ b/LibW4M/Data/SaveDataEntry.cs @@ -29,7 +29,7 @@ namespace LibW4M.Data public virtual string FriendlyName { get { - return mainContainer.Type.Name; + return this.mainContainer.Type.Name; } } public override int GetHashCode() @@ -44,16 +44,24 @@ namespace LibW4M.Data public abstract void Load(); public abstract void Save(); + + internal virtual void loadDefaults() + { + //this.Save(); + } public virtual void DeleteEntries() { this.mainContainer.Delete(); } - public SaveDataEntry (W4SaveFile fileBelongs, XomContainer mainContainer) + internal SaveDataEntry (W4SaveFile fileBelongs, XomContainer mainContainer, bool load=true) { this.fileBelongs = fileBelongs; this.mainContainer = mainContainer; - this.Load(); + if (load) + this.Load(); + else + this.loadDefaults(); } } } diff --git a/LibW4M/Data/Schemes/SchemesCollective.cs b/LibW4M/Data/Schemes/SchemesCollective.cs index e481400..46910bf 100644 --- a/LibW4M/Data/Schemes/SchemesCollective.cs +++ b/LibW4M/Data/Schemes/SchemesCollective.cs @@ -14,6 +14,11 @@ namespace LibW4M.Data.Schemes { } + public override void Create() + { + throw new NotImplementedException(); + } + public override void Load() { int[] collective = mainContainer.Decompress(); diff --git a/LibW4M/Data/Stats/StatsCollective.cs b/LibW4M/Data/Stats/StatsCollective.cs index e4b1e80..8a8db83 100644 --- a/LibW4M/Data/Stats/StatsCollective.cs +++ b/LibW4M/Data/Stats/StatsCollective.cs @@ -16,6 +16,11 @@ namespace LibW4M.Data.Stats { } + public override void Create() + { + throw new NotImplementedException(); + } + public override void Load() { int[] decompressedCollective = mainContainer.Decompress(); diff --git a/LibW4M/Data/Stats/TeamStatsCollective.cs b/LibW4M/Data/Stats/TeamStatsCollective.cs index 83c1711..45f8ba9 100644 --- a/LibW4M/Data/Stats/TeamStatsCollective.cs +++ b/LibW4M/Data/Stats/TeamStatsCollective.cs @@ -105,5 +105,10 @@ namespace LibW4M.Data.Stats mainContainer.CompressAndUpdate(newCollective); } + + public override void Create() + { + throw new NotImplementedException(); + } } } diff --git a/LibW4M/Data/Teams/TeamsCollective.cs b/LibW4M/Data/Teams/TeamsCollective.cs index 49190fb..8e777e3 100644 --- a/LibW4M/Data/Teams/TeamsCollective.cs +++ b/LibW4M/Data/Teams/TeamsCollective.cs @@ -14,6 +14,11 @@ namespace LibW4M.Data.Teams { } + public override void Create() + { + throw new NotImplementedException(); + } + public override void Load() { int[] decompressedCollective = mainContainer.Decompress(); diff --git a/LibW4M/Data/WeaponFactory/WeaponData.cs b/LibW4M/Data/WeaponFactory/WeaponData.cs index 5415fad..67a818d 100644 --- a/LibW4M/Data/WeaponFactory/WeaponData.cs +++ b/LibW4M/Data/WeaponFactory/WeaponData.cs @@ -45,7 +45,7 @@ namespace LibW4M.Data.WeaponFactory public float ClusterSpread; public float ClusterMaxSpeed; - public WeaponData(W4SaveFile fileBelongs, XomContainer mainContainer) : base(fileBelongs, mainContainer) + public WeaponData(W4SaveFile fileBelongs, XomContainer mainContainer, bool load=true) : base(fileBelongs, mainContainer, load) { } @@ -122,7 +122,46 @@ namespace LibW4M.Data.WeaponFactory } } } + internal override void loadDefaults() + { + this.Name = this.fileBelongs.LookupString("Untitled Weapon"); + this.Type = 0; + this.DetonationType = DetonationType.Impact; + this.Homing = false; + this.HomingAvoidLand = false; + this.Poison = false; + this.EffectedByWind = true; + this.FireOnGround = false; + + this.RetreatTime = -1; + + this.WormDamageRadius = 0.75f; + + this.WormDamageMagnitude = 0.5f; + this.LandDamageRadius = 0.5f; + this.Push = 0.5f; + + this.ProjectileCollisionRadius = 1.0f; + this.FuseTime = -1; + + this.GraphicalResources = new XomString[4] { this.fileBelongs.LookupString("Factory.TankGunBody"), this.fileBelongs.LookupString("Factory.TankGunBarrel"), this.fileBelongs.LookupString("Factory.TankGunButt"), this.fileBelongs.LookupString("Factory.TankGunSight") }; + this.GraphicalLocators = new XomString[4] { this.fileBelongs.LookupString("TANK_body_locator"), this.fileBelongs.LookupString("TANK_barrel_root_locator"), this.fileBelongs.LookupString("TANK_butt_root_locator"), this.fileBelongs.LookupString("TANK_sight_root_locator") }; + + this.LaunchFX = this.fileBelongs.LookupString(""); + this.ArielFX = this.fileBelongs.LookupString("WXP_BazookaTrailPack"); + this.DetonationFX = this.fileBelongs.LookupString("WXP_ExplosionX_Med"); + + this.PayloadResourceId = 55; + this.ProjectileLaunchType = ProjectileLaunchType.Launched; + this.ProjectilePowersUp = true; + this.ProjectileNumClusters = 0; + this.ProjectileMaxPower = 0.5f; + this.ClusterSpread = 0.300000012f; + this.ClusterMaxSpeed = 0.0f; + + base.loadDefaults(); + } public override void Load() { using (XomStreamReader reader = new XomStreamReader(new MemoryStream(this.mainContainer.GetData()))) diff --git a/LibW4M/Data/WeaponFactory/WeaponStore.cs b/LibW4M/Data/WeaponFactory/WeaponStore.cs index 16faf47..b4bba90 100644 --- a/LibW4M/Data/WeaponFactory/WeaponStore.cs +++ b/LibW4M/Data/WeaponFactory/WeaponStore.cs @@ -17,38 +17,91 @@ namespace LibW4M.Data.WeaponFactory public WeaponData Cluster; public bool StockWeapon; - internal XomContainer weaponContainer; - internal XomContainer clusterContainer; + - public WeaponStore(W4SaveFile fileBelongs, XomContainer mainContainer) : base(fileBelongs, mainContainer) + internal WeaponStore(W4SaveFile fileBelongs, XomContainer mainContainer, bool load=true) : base(fileBelongs, mainContainer, load) { } public override void Load() { - int[] weaponStore = this.mainContainer.Decompress(); - this.StockWeapon = (weaponStore[0] == 1); - this.weaponContainer = this.fileBelongs.LookupContainerById(weaponStore[1]); - this.clusterContainer = this.fileBelongs.LookupContainerById(weaponStore[2]); + using (XomStreamReader reader = new XomStreamReader(new MemoryStream(mainContainer.GetData()))) + { + reader.Skip(3); - this.Weapon = new WeaponData(this.fileBelongs, this.weaponContainer); - this.Cluster = new WeaponData(this.fileBelongs, this.clusterContainer); + this.StockWeapon = reader.ReadBool(); + this.Weapon = new WeaponData(this.fileBelongs, this.fileBelongs.LookupContainerById(reader.ReadCompressedInt())); + this.Cluster = new WeaponData(this.fileBelongs, this.fileBelongs.LookupContainerById(reader.ReadCompressedInt())); + } } public override void Save() { this.Weapon.Save(); this.Cluster.Save(); + using (MemoryStream ms = new MemoryStream()) + { + using (XomStreamWriter writer = new XomStreamWriter(ms)) + { + writer.Skip(3); - int[] weaponStore = this.mainContainer.Decompress(); - weaponStore[0] = (this.StockWeapon ? 1 : 0); - weaponStore[1] = this.weaponContainer.Id; - weaponStore[2] = this.clusterContainer.Id; - this.mainContainer.CompressAndUpdate(weaponStore); + writer.WriteBool(this.StockWeapon); + writer.WriteCompressedInt(this.Weapon.mainContainer.Id); + writer.WriteCompressedInt(this.Cluster.mainContainer.Id); + + ms.Seek(0x00, SeekOrigin.Begin); + mainContainer.SetData(ms.ToArray()); + } + } } + internal override void loadDefaults() + { + this.StockWeapon = false; + this.Weapon = new WeaponData(this.fileBelongs, this.fileBelongs.CreateContainer("WeaponFactoryContainer"), false); + this.Cluster = new WeaponData(this.fileBelongs, this.fileBelongs.CreateContainer("WeaponFactoryContainer"), false); + + // Clusters should have different defaults, lets just go fix that :) + this.Cluster.Name = this.fileBelongs.LookupString(""); + this.Cluster.Type = 1; + this.Cluster.DetonationType = DetonationType.Impact; + + this.Cluster.Homing = false; + this.Cluster.HomingAvoidLand = false; + this.Cluster.Poison = false; + this.Cluster.EffectedByWind = false; + this.Cluster.FireOnGround = false; + + this.Cluster.RetreatTime = 0; + + this.Cluster.WormDamageRadius = 0.75f; + + this.Cluster.WormDamageMagnitude = 0.5f; + this.Cluster.LandDamageRadius = 0.5f; + this.Cluster.Push = 0.5f; + + this.Cluster.ProjectileCollisionRadius = 1.0f; + this.Cluster.FuseTime = -1; + + this.Cluster.GraphicalResources = new XomString[0]; + this.Cluster.GraphicalLocators = new XomString[0]; + + this.Cluster.LaunchFX = this.fileBelongs.LookupString(""); + this.Cluster.ArielFX = this.fileBelongs.LookupString(""); + this.Cluster.DetonationFX = this.fileBelongs.LookupString("WXP_ExploCluster"); + + this.Cluster.PayloadResourceId = 16; + this.Cluster.ProjectileLaunchType = ProjectileLaunchType.Thrown; + this.Cluster.ProjectilePowersUp = false; + this.Cluster.ProjectileNumClusters = 0; + this.Cluster.ProjectileMaxPower = 0.0f; + this.Cluster.ClusterSpread = 0.5f; + this.Cluster.ClusterMaxSpeed = 0.0f; + + base.loadDefaults(); + } public override void DeleteEntries() { diff --git a/LibW4M/Data/WeaponFactory/WeaponsCollective.cs b/LibW4M/Data/WeaponFactory/WeaponsCollective.cs index 3a587df..7821360 100644 --- a/LibW4M/Data/WeaponFactory/WeaponsCollective.cs +++ b/LibW4M/Data/WeaponFactory/WeaponsCollective.cs @@ -25,6 +25,12 @@ namespace LibW4M.Data.WeaponFactory } return null; } + + public override void Create() + { + this.collectiveEntries.Add(new WeaponStore(this.fileBelongs, this.fileBelongs.CreateContainer("StoreWeaponFactory"), false)); + } + public override void Load() { int[] collective = mainContainer.Decompress(); diff --git a/LibW4M/W4SaveFile.cs b/LibW4M/W4SaveFile.cs index b4ae952..589717f 100644 --- a/LibW4M/W4SaveFile.cs +++ b/LibW4M/W4SaveFile.cs @@ -215,6 +215,10 @@ namespace LibW4M return strings; } + public XomContainer CreateContainer(string type) + { + return xomFile.CreateContainer(type); + } public XomContainer LookupContainerById(int id) { return xomFile.GetContainerById(id); diff --git a/LibXom/Data/XomFile.cs b/LibXom/Data/XomFile.cs index 816f943..3825b80 100644 --- a/LibXom/Data/XomFile.cs +++ b/LibXom/Data/XomFile.cs @@ -54,6 +54,13 @@ namespace LibXom.Data return xomStrings.Count - 1; } + + public XomContainer CreateContainer(string typeName) + { + XomType type = GetTypeByName(typeName); + return type.NewContainer(); + } + public void ClearAllStrings() { xomStrings.Clear(); @@ -181,9 +188,9 @@ namespace LibXom.Data XomBlock[] containerBlocks = XomBlockHandler.GetBlocksByName(xomBlocks, "CTNR"); - if (moikBlock is not MoikBlock) throw new XomBlockNotFoundException("XOM contained no MOIK block!, Is it corrupted?"); - if (schemeBlock is not SchmBlock) throw new XomBlockNotFoundException("XOM contained no SCHM block!, Is it corrupted?"); - if (stringBlock is not StrsBlock) throw new XomBlockNotFoundException("XOM contained no STRS block!, Is it corrupted?"); + if (moikBlock is not MoikBlock) throw new XomBlockNotFoundException("XOM contained no MOIK block!, Is the XOM corrupted?"); + if (schemeBlock is not SchmBlock) throw new XomBlockNotFoundException("XOM contained no SCHM block!, Is the XOM corrupted?"); + if (stringBlock is not StrsBlock) throw new XomBlockNotFoundException("XOM contained no STRS block!, Is the XOM corrupted?"); version = moikBlock.Version; unk0 = schemeBlock.Unk0; diff --git a/LibXom/Data/XomType.cs b/LibXom/Data/XomType.cs index 44f29e7..c3ffc6f 100644 --- a/LibXom/Data/XomType.cs +++ b/LibXom/Data/XomType.cs @@ -60,6 +60,14 @@ namespace LibXom.Data int indx = this.getContainerIndex(container); this.xomContainers[indx].data = newData; } + + public XomContainer NewContainer() + { + XomContainer xomContainer = new XomContainer(this.fileBelongs, this.Name, new byte[0x3]); + this.xomContainers.Add(xomContainer); + return xomContainer; + } + public void DeleteContainer(XomContainer container) { int indx = this.getContainerIndex(container); diff --git a/W4Gui/Components/CollectiveListAddDelete.Designer.cs b/W4Gui/Components/CollectiveListAddDelete.Designer.cs index 008db22..33972a0 100644 --- a/W4Gui/Components/CollectiveListAddDelete.Designer.cs +++ b/W4Gui/Components/CollectiveListAddDelete.Designer.cs @@ -72,7 +72,7 @@ // btnAdd // this.btnAdd.Dock = System.Windows.Forms.DockStyle.Fill; - this.btnAdd.Enabled = false; + this.btnAdd.Enabled = true; this.btnAdd.Location = new System.Drawing.Point(3, 3); this.btnAdd.Name = "btnAdd"; this.btnAdd.Size = new System.Drawing.Size(116, 26); diff --git a/W4Gui/Tabs/WeaponsTab.cs b/W4Gui/Tabs/WeaponsTab.cs index 86fa7f4..c7a3960 100644 --- a/W4Gui/Tabs/WeaponsTab.cs +++ b/W4Gui/Tabs/WeaponsTab.cs @@ -54,7 +54,9 @@ namespace W4Gui.Tabs private void weaponList_NewButton(object sender, EventArgs e) { - throw new NotImplementedException("Adding new weapons from here not implemented yet ;)"); + DataManager.SaveFile.WeaponFactoryCollective.Create(); + weaponList.List.Add(DataManager.SaveFile.WeaponFactoryCollective.Last().FriendlyName); + weaponList.List.SelectedIndex = (weaponList.List.Items.Count - 1); } private void weaponList_DeleteButton(object sender, EventArgs e)