From b52bf403e4ee36d979280016ccb1f10e468f62c9 Mon Sep 17 00:00:00 2001 From: Jackson Martin Date: Thu, 23 Jan 2025 11:12:52 -0500 Subject: [PATCH 1/7] ItemObject Properties Sync Synced ItemObject Properties Listed in #994. Vec3 will need to be Serialized --- .../ItemObjects/ItemObjectSyncTest.cs | 53 +++++++++++++++++-- .../Services/ItemObjects/ItemObjectSync.cs | 23 ++++++++ 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/source/E2E.Tests/Services/ItemObjects/ItemObjectSyncTest.cs b/source/E2E.Tests/Services/ItemObjects/ItemObjectSyncTest.cs index 0cfc9034a..e4e832ee3 100644 --- a/source/E2E.Tests/Services/ItemObjects/ItemObjectSyncTest.cs +++ b/source/E2E.Tests/Services/ItemObjects/ItemObjectSyncTest.cs @@ -7,8 +7,14 @@ using TaleWorlds.CampaignSystem.Settlements.Buildings; using TaleWorlds.CampaignSystem.Siege; using TaleWorlds.Core; +using TaleWorlds.Library; using TaleWorlds.Localization; using Xunit.Abstractions; +using GameInterface.Tests.Bootstrap.Modules; +using System.ComponentModel; +using Autofac; +using NuGet.Frameworks; +using Newtonsoft.Json.Serialization; namespace E2E.Tests.Services.ItemObjectService { @@ -35,14 +41,34 @@ public void ServerCreateItemObject_SyncAllClients() string? itemObjectId = null; var typeField = AccessTools.Field(typeof(ItemObject), nameof(ItemObject.Type)); - var typeIntercept = TestEnvironment.GetIntercept(typeField); - + + var culture = new BasicCultureObject() { Name = new TextObject("Battania") }; + var weaponDesign = ObjectHelper.SkipConstructor(); + var holsterPositionShift = new Vec3(1, 2, 3, 4); server.Call(() => { ItemObject itemObject = new ItemObject(); Assert.True(server.ObjectManager.TryGetId(itemObject, out itemObjectId)); + + itemObject.Weight = 3.5f; + itemObject.Name = new TextObject("Name"); + itemObject.MultiMeshName = "MultiMeshName"; + itemObject.HolsterMeshName = "HolsterMeshName"; + itemObject.HolsterWithWeaponMeshName = "WithWeaponMeshName"; + //itemObject.HolsterPositionShift = holsterPositionShift; + itemObject.FlyingMeshName = "FlyingMeshName"; + itemObject.BodyName = "BodyName"; + itemObject.HolsterBodyName = "HolsterBodyName"; + itemObject.CollisionBodyName = "CollisionBodyName"; + itemObject.RecalculateBody = false; + itemObject.Culture = culture; + itemObject.Difficulty = 1; + itemObject.ScaleFactor = 3.5f; + itemObject.ItemFlags = ItemFlags.Civilian; + itemObject.Appearance = 3.5f; + itemObject.WeaponDesign = weaponDesign; }); // Assert @@ -54,6 +80,8 @@ public void ServerCreateItemObject_SyncAllClients() }); server.ObjectManager.TryGetId(itemObject, out string serverObjectId); + server.ObjectManager.TryGetId(itemObject.Culture, out string serverCultureId); + server.ObjectManager.TryGetId(itemObject.WeaponDesign, out string serverWeaponDesignId); foreach (var client in TestEnvironment.Clients) { @@ -61,8 +89,27 @@ public void ServerCreateItemObject_SyncAllClients() Assert.Equal(itemObject.Type, clientItemObject.Type); client.ObjectManager.TryGetId(clientItemObject, out string clientObjectId); - + client.ObjectManager.TryGetId(clientItemObject.Culture, out string clientCultureId); + client.ObjectManager.TryGetId(clientItemObject.WeaponDesign, out string clientWeaponDesignId); Assert.Equal(serverObjectId, clientObjectId); + + Assert.Equal(3.5f, clientItemObject.Weight); + Assert.Equal("Name", clientItemObject.Name.ToString()); + Assert.Equal("MultiMeshName", clientItemObject.MultiMeshName); + Assert.Equal("HolsterMeshName", clientItemObject.HolsterMeshName); + Assert.Equal("WithWeaponMeshName", clientItemObject.HolsterWithWeaponMeshName); + //Assert.Equal(holsterPositionShift, clientItemObject.HolsterPositionShift); + Assert.Equal("FlyingMeshName", clientItemObject.FlyingMeshName); + Assert.Equal("BodyName", clientItemObject.BodyName); + Assert.Equal("HolsterBodyName", clientItemObject.HolsterBodyName); + Assert.Equal("CollisionBodyName", clientItemObject.CollisionBodyName); + Assert.False(clientItemObject.RecalculateBody); + Assert.Equal(clientCultureId, serverCultureId); + Assert.Equal(1, clientItemObject.Difficulty); + Assert.Equal(3.5f, clientItemObject.ScaleFactor); + Assert.Equal(ItemFlags.Civilian, clientItemObject.ItemFlags); + Assert.Equal(3.5f, clientItemObject.Appearance); + Assert.Equal(clientWeaponDesignId, serverWeaponDesignId); } } } diff --git a/source/GameInterface/Services/ItemObjects/ItemObjectSync.cs b/source/GameInterface/Services/ItemObjects/ItemObjectSync.cs index aa32dec5e..755d4a4ca 100644 --- a/source/GameInterface/Services/ItemObjects/ItemObjectSync.cs +++ b/source/GameInterface/Services/ItemObjects/ItemObjectSync.cs @@ -7,9 +7,32 @@ namespace GameInterface.Services.ItemObjects { public class ItemObjectSync : IAutoSync { + /** + * HolsterPositionShift (Vec3) does not like to be serialized, not sure how to approach this one + */ public ItemObjectSync(IAutoSyncBuilder autoSyncBuilder) { + //Fields autoSyncBuilder.AddField(AccessTools.Field(typeof(ItemObject), nameof(ItemObject.Type))); + + //Properties + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.Weight))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.Name))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.MultiMeshName))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.HolsterMeshName))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.HolsterWithWeaponMeshName))); + //autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.HolsterPositionShift))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.FlyingMeshName))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.BodyName))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.HolsterBodyName))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.CollisionBodyName))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.RecalculateBody))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.Culture))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.Difficulty))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.ScaleFactor))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.ItemFlags))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.Appearance))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.WeaponDesign))); } } } From bf970477a46e27513cb2370ea40f39bae1d75136 Mon Sep 17 00:00:00 2001 From: Jackson Martin Date: Thu, 23 Jan 2025 11:43:26 -0500 Subject: [PATCH 2/7] ItemObject Collections Sync Synced ItemObject Collections --- .../Services/ItemObjects/ItemObjectSyncTest.cs | 12 ++++++++++++ .../Services/ItemObjects/ItemObjectSync.cs | 3 +++ 2 files changed, 15 insertions(+) diff --git a/source/E2E.Tests/Services/ItemObjects/ItemObjectSyncTest.cs b/source/E2E.Tests/Services/ItemObjects/ItemObjectSyncTest.cs index e4e832ee3..ce295798d 100644 --- a/source/E2E.Tests/Services/ItemObjects/ItemObjectSyncTest.cs +++ b/source/E2E.Tests/Services/ItemObjects/ItemObjectSyncTest.cs @@ -46,6 +46,7 @@ public void ServerCreateItemObject_SyncAllClients() var culture = new BasicCultureObject() { Name = new TextObject("Battania") }; var weaponDesign = ObjectHelper.SkipConstructor(); var holsterPositionShift = new Vec3(1, 2, 3, 4); + string[] itemHolsters = { "holster1", "holster2", "holster3" }; server.Call(() => { @@ -69,6 +70,7 @@ public void ServerCreateItemObject_SyncAllClients() itemObject.ItemFlags = ItemFlags.Civilian; itemObject.Appearance = 3.5f; itemObject.WeaponDesign = weaponDesign; + itemObject.ItemHolsters = itemHolsters; }); // Assert @@ -82,17 +84,22 @@ public void ServerCreateItemObject_SyncAllClients() server.ObjectManager.TryGetId(itemObject, out string serverObjectId); server.ObjectManager.TryGetId(itemObject.Culture, out string serverCultureId); server.ObjectManager.TryGetId(itemObject.WeaponDesign, out string serverWeaponDesignId); + server.ObjectManager.TryGetId(itemObject.ItemHolsters, out string serverItemHolstersId); foreach (var client in TestEnvironment.Clients) { Assert.True(client.ObjectManager.TryGetObject(serverObjectId, out ItemObject clientItemObject)); + + //Field Assert.Equal(itemObject.Type, clientItemObject.Type); client.ObjectManager.TryGetId(clientItemObject, out string clientObjectId); client.ObjectManager.TryGetId(clientItemObject.Culture, out string clientCultureId); client.ObjectManager.TryGetId(clientItemObject.WeaponDesign, out string clientWeaponDesignId); + client.ObjectManager.TryGetId(clientItemObject.ItemHolsters, out string clientItemHolstersId); Assert.Equal(serverObjectId, clientObjectId); + //Properties Assert.Equal(3.5f, clientItemObject.Weight); Assert.Equal("Name", clientItemObject.Name.ToString()); Assert.Equal("MultiMeshName", clientItemObject.MultiMeshName); @@ -110,6 +117,11 @@ public void ServerCreateItemObject_SyncAllClients() Assert.Equal(ItemFlags.Civilian, clientItemObject.ItemFlags); Assert.Equal(3.5f, clientItemObject.Appearance); Assert.Equal(clientWeaponDesignId, serverWeaponDesignId); + + //Collection + Assert.Equal(itemHolsters, clientItemObject.ItemHolsters); + Assert.Equal(itemHolsters[0], clientItemObject.ItemHolsters[0]); + Assert.Equal(serverItemHolstersId, clientItemHolstersId); } } } diff --git a/source/GameInterface/Services/ItemObjects/ItemObjectSync.cs b/source/GameInterface/Services/ItemObjects/ItemObjectSync.cs index 755d4a4ca..953b87db7 100644 --- a/source/GameInterface/Services/ItemObjects/ItemObjectSync.cs +++ b/source/GameInterface/Services/ItemObjects/ItemObjectSync.cs @@ -33,6 +33,9 @@ public ItemObjectSync(IAutoSyncBuilder autoSyncBuilder) autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.ItemFlags))); autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.Appearance))); autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.WeaponDesign))); + + //Collection + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.ItemHolsters))); } } } From 377df253584d7f02ea127fb609b57a8fc74bce46 Mon Sep 17 00:00:00 2001 From: Jackson Martin Date: Fri, 24 Jan 2025 09:33:23 -0500 Subject: [PATCH 3/7] Vec3 Surrogate Added Vec3 Surrogate --- .../Surrogates/SurrogateCollection.cs | 3 ++ .../GameInterface/Surrogates/Vec3Surrogate.cs | 36 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 source/GameInterface/Surrogates/Vec3Surrogate.cs diff --git a/source/GameInterface/Surrogates/SurrogateCollection.cs b/source/GameInterface/Surrogates/SurrogateCollection.cs index 1990c8fa7..7bef3e60a 100644 --- a/source/GameInterface/Surrogates/SurrogateCollection.cs +++ b/source/GameInterface/Surrogates/SurrogateCollection.cs @@ -29,5 +29,8 @@ public SurrogateCollection() if (RuntimeTypeModel.Default.CanSerialize(typeof(Banner)) == false) RuntimeTypeModel.Default.SetSurrogate(); + + if (RuntimeTypeModel.Default.CanSerialize(typeof(Vec3)) == false) + RuntimeTypeModel.Default.SetSurrogate(); } } diff --git a/source/GameInterface/Surrogates/Vec3Surrogate.cs b/source/GameInterface/Surrogates/Vec3Surrogate.cs new file mode 100644 index 000000000..b7e50a34b --- /dev/null +++ b/source/GameInterface/Surrogates/Vec3Surrogate.cs @@ -0,0 +1,36 @@ +using ProtoBuf; +using TaleWorlds.Library; + +namespace GameInterface.Surrogates; + +[ProtoContract] +internal struct Vec3Surrogate +{ + [ProtoMember(1)] + public float X { get; set; } + + [ProtoMember(2)] + public float Y { get; set; } + [ProtoMember(3)] + public float Z { get; set; } + [ProtoMember(4)] + public float W { get; set; } + + public Vec3Surrogate(Vec3 vec3) + { + X = vec3.x; + Y = vec3.y; + Z = vec3.z; + W = vec3.w; + } + + public static implicit operator Vec3Surrogate(Vec3 vec3) + { + return new Vec3Surrogate(vec3); + } + + public static implicit operator Vec3(Vec3Surrogate surrogate) + { + return new Vec3(surrogate.X, surrogate.Y, surrogate.Z, surrogate.W); + } +} From fcea087a208df1d3a96c87f1ab225d9fa4a4eb1e Mon Sep 17 00:00:00 2001 From: Jackson Martin Date: Fri, 24 Jan 2025 09:37:25 -0500 Subject: [PATCH 4/7] Uncommented Sync and Tests Readded HolsterPositionShift to Sync and Tests --- source/E2E.Tests/Services/ItemObjects/ItemObjectSyncTest.cs | 4 ++-- source/GameInterface/Services/ItemObjects/ItemObjectSync.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/E2E.Tests/Services/ItemObjects/ItemObjectSyncTest.cs b/source/E2E.Tests/Services/ItemObjects/ItemObjectSyncTest.cs index ce295798d..a04f4413f 100644 --- a/source/E2E.Tests/Services/ItemObjects/ItemObjectSyncTest.cs +++ b/source/E2E.Tests/Services/ItemObjects/ItemObjectSyncTest.cs @@ -58,7 +58,7 @@ public void ServerCreateItemObject_SyncAllClients() itemObject.MultiMeshName = "MultiMeshName"; itemObject.HolsterMeshName = "HolsterMeshName"; itemObject.HolsterWithWeaponMeshName = "WithWeaponMeshName"; - //itemObject.HolsterPositionShift = holsterPositionShift; + itemObject.HolsterPositionShift = holsterPositionShift; itemObject.FlyingMeshName = "FlyingMeshName"; itemObject.BodyName = "BodyName"; itemObject.HolsterBodyName = "HolsterBodyName"; @@ -105,7 +105,7 @@ public void ServerCreateItemObject_SyncAllClients() Assert.Equal("MultiMeshName", clientItemObject.MultiMeshName); Assert.Equal("HolsterMeshName", clientItemObject.HolsterMeshName); Assert.Equal("WithWeaponMeshName", clientItemObject.HolsterWithWeaponMeshName); - //Assert.Equal(holsterPositionShift, clientItemObject.HolsterPositionShift); + Assert.Equal(holsterPositionShift, clientItemObject.HolsterPositionShift); Assert.Equal("FlyingMeshName", clientItemObject.FlyingMeshName); Assert.Equal("BodyName", clientItemObject.BodyName); Assert.Equal("HolsterBodyName", clientItemObject.HolsterBodyName); diff --git a/source/GameInterface/Services/ItemObjects/ItemObjectSync.cs b/source/GameInterface/Services/ItemObjects/ItemObjectSync.cs index 953b87db7..69a0396e9 100644 --- a/source/GameInterface/Services/ItemObjects/ItemObjectSync.cs +++ b/source/GameInterface/Services/ItemObjects/ItemObjectSync.cs @@ -21,7 +21,7 @@ public ItemObjectSync(IAutoSyncBuilder autoSyncBuilder) autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.MultiMeshName))); autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.HolsterMeshName))); autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.HolsterWithWeaponMeshName))); - //autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.HolsterPositionShift))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.HolsterPositionShift))); autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.FlyingMeshName))); autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.BodyName))); autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.HolsterBodyName))); From 8a82783c92e79429fd695401ad29190f30dc2c9f Mon Sep 17 00:00:00 2001 From: Jackson Martin Date: Fri, 31 Jan 2025 18:00:29 -0500 Subject: [PATCH 5/7] Added Rest of ItemObject Properties Also added surrogates for all the object needed for serialization. --- .../ItemObjects/ItemObjectSyncTest.cs | 53 ++- .../Services/ItemObjects/ItemObjectSync.cs | 19 +- .../Surrogates/ArmorComponentSurrogate.cs | 111 ++++++ .../Surrogates/HorseComponentSurrogate.cs | 78 ++++ .../Surrogates/ItemCategorySurrogate.cs | 63 +++ .../Surrogates/ItemComponentSurrogate.cs | 198 ++++++++++ .../Surrogates/ItemObjectSurrogate.cs | 123 ++++++ .../Surrogates/MonsterSurrogate.cs | 369 ++++++++++++++++++ .../Surrogates/SaddleComponentSurrogate.cs | 42 ++ .../Surrogates/SkeletonScaleSurrogate.cs | 56 +++ .../Surrogates/SurrogateCollection.cs | 30 +- .../Surrogates/TradeItemComponentSurrogate.cs | 43 ++ .../Surrogates/WeaponComponentSurrogate.cs | 42 ++ 13 files changed, 1222 insertions(+), 5 deletions(-) create mode 100644 source/GameInterface/Surrogates/ArmorComponentSurrogate.cs create mode 100644 source/GameInterface/Surrogates/HorseComponentSurrogate.cs create mode 100644 source/GameInterface/Surrogates/ItemCategorySurrogate.cs create mode 100644 source/GameInterface/Surrogates/ItemComponentSurrogate.cs create mode 100644 source/GameInterface/Surrogates/ItemObjectSurrogate.cs create mode 100644 source/GameInterface/Surrogates/MonsterSurrogate.cs create mode 100644 source/GameInterface/Surrogates/SaddleComponentSurrogate.cs create mode 100644 source/GameInterface/Surrogates/SkeletonScaleSurrogate.cs create mode 100644 source/GameInterface/Surrogates/TradeItemComponentSurrogate.cs create mode 100644 source/GameInterface/Surrogates/WeaponComponentSurrogate.cs diff --git a/source/E2E.Tests/Services/ItemObjects/ItemObjectSyncTest.cs b/source/E2E.Tests/Services/ItemObjects/ItemObjectSyncTest.cs index a04f4413f..b7300addd 100644 --- a/source/E2E.Tests/Services/ItemObjects/ItemObjectSyncTest.cs +++ b/source/E2E.Tests/Services/ItemObjects/ItemObjectSyncTest.cs @@ -15,6 +15,8 @@ using Autofac; using NuGet.Frameworks; using Newtonsoft.Json.Serialization; +using JetBrains.Annotations; +using System.Diagnostics; namespace E2E.Tests.Services.ItemObjectService { @@ -47,6 +49,11 @@ public void ServerCreateItemObject_SyncAllClients() var weaponDesign = ObjectHelper.SkipConstructor(); var holsterPositionShift = new Vec3(1, 2, 3, 4); string[] itemHolsters = { "holster1", "holster2", "holster3" }; + var itemComponent = new TradeItemComponent(); + var itemCategory = ObjectHelper.SkipConstructor(); + var prerequisiteItem = new ItemObject(); + var itemTypeEnum = ItemObject.ItemTypeEnum.OneHandedWeapon; + server.Call(() => { @@ -71,6 +78,24 @@ public void ServerCreateItemObject_SyncAllClients() itemObject.Appearance = 3.5f; itemObject.WeaponDesign = weaponDesign; itemObject.ItemHolsters = itemHolsters; + + //Rest of Properties + itemObject.ItemComponent = itemComponent; + itemObject.HasLowerHolsterPriority = true; + itemObject.PrefabName = "PrefabName"; + itemObject.ItemCategory = itemCategory; + itemObject.Value = 1; + itemObject.Effectiveness = 3.5f; + itemObject.IsUsingTableau = true; + itemObject.ArmBandMeshName = "ArmBandMeshName"; + itemObject.IsFood = true; + itemObject.IsUniqueItem = true; + itemObject.MultiplayerItem = true; + itemObject.NotMerchandise = true; + itemObject.IsCraftedByPlayer = true; + itemObject.LodAtlasIndex = 1; + itemObject.PrerequisiteItem = prerequisiteItem; + itemObject.ItemType = itemTypeEnum; }); // Assert @@ -78,13 +103,16 @@ public void ServerCreateItemObject_SyncAllClients() server.Call(() => { - typeIntercept.Invoke(null, new object[] { itemObject, 69 }); + //typeIntercept.Invoke(null, new object[] { itemObject, 69 }); }); server.ObjectManager.TryGetId(itemObject, out string serverObjectId); server.ObjectManager.TryGetId(itemObject.Culture, out string serverCultureId); server.ObjectManager.TryGetId(itemObject.WeaponDesign, out string serverWeaponDesignId); server.ObjectManager.TryGetId(itemObject.ItemHolsters, out string serverItemHolstersId); + server.ObjectManager.TryGetId(itemObject.ItemComponent, out string serverItemComponentId); + server.ObjectManager.TryGetId(itemObject.ItemCategory, out string serverItemCategoryId); + server.ObjectManager.TryGetId(itemObject.PrerequisiteItem, out string serverPrerequisiteItemId); foreach (var client in TestEnvironment.Clients) { @@ -97,8 +125,12 @@ public void ServerCreateItemObject_SyncAllClients() client.ObjectManager.TryGetId(clientItemObject.Culture, out string clientCultureId); client.ObjectManager.TryGetId(clientItemObject.WeaponDesign, out string clientWeaponDesignId); client.ObjectManager.TryGetId(clientItemObject.ItemHolsters, out string clientItemHolstersId); + client.ObjectManager.TryGetId(clientItemObject.ItemComponent, out string clientItemComponentId); + client.ObjectManager.TryGetId(clientItemObject.ItemCategory, out string clientItemCategoryId); + client.ObjectManager.TryGetId(clientItemObject.PrerequisiteItem, out string clientPrerequisiteItemId); Assert.Equal(serverObjectId, clientObjectId); + //Properties Assert.Equal(3.5f, clientItemObject.Weight); Assert.Equal("Name", clientItemObject.Name.ToString()); @@ -118,6 +150,25 @@ public void ServerCreateItemObject_SyncAllClients() Assert.Equal(3.5f, clientItemObject.Appearance); Assert.Equal(clientWeaponDesignId, serverWeaponDesignId); + //Rest of Properties + Assert.Equal(serverItemComponentId, clientItemComponentId); + Assert.True(clientItemObject.HasLowerHolsterPriority); + Assert.Equal("PrefabName", clientItemObject.PrefabName); + Assert.Equal(serverItemCategoryId, clientItemCategoryId); + Assert.Equal(1, clientItemObject.Value); + Assert.Equal(3.5f, clientItemObject.Effectiveness); + Assert.True(clientItemObject.IsUsingTableau); + Assert.Equal("ArmBandMeshName", clientItemObject.ArmBandMeshName); + Assert.True(clientItemObject.IsFood); + Assert.True(clientItemObject.IsUniqueItem); + Assert.True(clientItemObject.MultiplayerItem); + Assert.True(clientItemObject.NotMerchandise); + Assert.True(clientItemObject.IsCraftedByPlayer); + Assert.Equal(1, clientItemObject.LodAtlasIndex); + Assert.Equal(serverPrerequisiteItemId, clientPrerequisiteItemId); + Assert.Equal(ItemObject.ItemTypeEnum.OneHandedWeapon, clientItemObject.ItemType); + + //Collection Assert.Equal(itemHolsters, clientItemObject.ItemHolsters); Assert.Equal(itemHolsters[0], clientItemObject.ItemHolsters[0]); diff --git a/source/GameInterface/Services/ItemObjects/ItemObjectSync.cs b/source/GameInterface/Services/ItemObjects/ItemObjectSync.cs index 69a0396e9..4e27119b6 100644 --- a/source/GameInterface/Services/ItemObjects/ItemObjectSync.cs +++ b/source/GameInterface/Services/ItemObjects/ItemObjectSync.cs @@ -7,9 +7,6 @@ namespace GameInterface.Services.ItemObjects { public class ItemObjectSync : IAutoSync { - /** - * HolsterPositionShift (Vec3) does not like to be serialized, not sure how to approach this one - */ public ItemObjectSync(IAutoSyncBuilder autoSyncBuilder) { //Fields @@ -33,6 +30,22 @@ public ItemObjectSync(IAutoSyncBuilder autoSyncBuilder) autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.ItemFlags))); autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.Appearance))); autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.WeaponDesign))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.ItemComponent))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.HasLowerHolsterPriority))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.PrefabName))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.ItemCategory))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.Value))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.Effectiveness))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.IsUsingTableau))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.ArmBandMeshName))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.IsFood))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.IsUniqueItem))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.MultiplayerItem))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.NotMerchandise))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.IsCraftedByPlayer))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.LodAtlasIndex))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.PrerequisiteItem))); + autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.ItemType))); //Collection autoSyncBuilder.AddProperty(AccessTools.Property(typeof(ItemObject), nameof(ItemObject.ItemHolsters))); diff --git a/source/GameInterface/Surrogates/ArmorComponentSurrogate.cs b/source/GameInterface/Surrogates/ArmorComponentSurrogate.cs new file mode 100644 index 000000000..1c5985705 --- /dev/null +++ b/source/GameInterface/Surrogates/ArmorComponentSurrogate.cs @@ -0,0 +1,111 @@ +using Common.Util; +using ProtoBuf; +using System; +using System.Collections.Generic; +using TaleWorlds.Core; + +namespace GameInterface.Surrogates +{ + [ProtoContract] + internal struct ArmorComponentSurrogate + { + [ProtoMember(1)] + public ItemObject Item { get; set; } + [ProtoMember(2)] + public ItemModifierGroup ItemModifierGroup { get; set; } + [ProtoMember(3)] + public int HeadArmor { get; set; } + [ProtoMember(4)] + public int BodyArmor { get; set; } + [ProtoMember(5)] + public int LegArmor { get; set; } + [ProtoMember(6)] + public int ArmArmor { get; set; } + [ProtoMember(7)] + public int ManeuverBonus { get; set; } + [ProtoMember(8)] + public int SpeedBonus { get; set; } + [ProtoMember(9)] + public int ChargeBonus { get; set; } + [ProtoMember(10)] + public int FamilyType { get; set; } + [ProtoMember(11)] + public ArmorComponent.ArmorMaterialTypes MaterialType { get; set; } + [ProtoMember(12)] + public SkinMask MeshesMask { get; set; } + [ProtoMember(13)] + public ArmorComponent.BodyMeshTypes BodyMeshType { get; set; } + [ProtoMember(14)] + public ArmorComponent.BodyDeformTypes BodyDeformType { get; set; } + [ProtoMember(15)] + public ArmorComponent.HairCoverTypes HairCoverType { get; set; } + [ProtoMember(16)] + public ArmorComponent.BeardCoverTypes BeardCoverType { get; set; } + [ProtoMember(17)] + public ArmorComponent.HorseHarnessCoverTypes ManeCoverType { get; set; } + [ProtoMember(18)] + public ArmorComponent.HorseTailCoverTypes TailCoverType { get; set; } + [ProtoMember(19)] + public string ReinsMesh { get; set; } + + + public ArmorComponentSurrogate(ArmorComponent armorComponent) + { + if (armorComponent == null) + { + Item = ObjectHelper.SkipConstructor(); + ItemModifierGroup = ObjectHelper.SkipConstructor(); + HeadArmor = -1; + BodyArmor = -1; + LegArmor = -1; + ArmArmor = -1; + ManeuverBonus = -1; + SpeedBonus = -1; + ChargeBonus = -1; + FamilyType = -1; + MaterialType = ArmorComponent.ArmorMaterialTypes.None; + MeshesMask = ObjectHelper.SkipConstructor(); + BodyMeshType = ArmorComponent.BodyMeshTypes.Normal; + BodyDeformType = ArmorComponent.BodyDeformTypes.Medium; + HairCoverType = ArmorComponent.HairCoverTypes.None; + BeardCoverType = ArmorComponent.BeardCoverTypes.None; + ManeCoverType = ArmorComponent.HorseHarnessCoverTypes.None; + TailCoverType = ArmorComponent.HorseTailCoverTypes.None; + ReinsMesh = ""; + + } + else + { + Item = armorComponent.Item; + ItemModifierGroup = armorComponent.ItemModifierGroup; + HeadArmor = armorComponent.HeadArmor; + BodyArmor = armorComponent.BodyArmor; + LegArmor = armorComponent.LegArmor; + ArmArmor = armorComponent.ArmArmor; + ManeuverBonus = armorComponent.ManeuverBonus; + SpeedBonus = armorComponent.SpeedBonus; + ChargeBonus = armorComponent.ChargeBonus; + FamilyType = armorComponent.FamilyType; + MaterialType = armorComponent.MaterialType; + MeshesMask = armorComponent.MeshesMask; + BodyMeshType = armorComponent.BodyMeshType; + BodyDeformType = armorComponent.BodyDeformType; + HairCoverType = armorComponent.HairCoverType; + BeardCoverType = armorComponent.BeardCoverType; + ManeCoverType = armorComponent.ManeCoverType; + TailCoverType = armorComponent.TailCoverType; + ReinsMesh = armorComponent.ReinsMesh; + } + } + + public static implicit operator ArmorComponentSurrogate(ArmorComponent armorComponent) + { + return new ArmorComponentSurrogate(armorComponent); + } + + public static implicit operator ArmorComponent(ArmorComponentSurrogate surrogate) + { + return new ArmorComponent(surrogate.Item); + } + } +} \ No newline at end of file diff --git a/source/GameInterface/Surrogates/HorseComponentSurrogate.cs b/source/GameInterface/Surrogates/HorseComponentSurrogate.cs new file mode 100644 index 000000000..8956236a5 --- /dev/null +++ b/source/GameInterface/Surrogates/HorseComponentSurrogate.cs @@ -0,0 +1,78 @@ +using Common.Util; +using ProtoBuf; +using System; +using System.Collections.Generic; +using TaleWorlds.Core; + +namespace GameInterface.Surrogates +{ + [ProtoContract] + internal struct HorseComponentSurrogate + { + [ProtoMember(1)] + public ItemObject Item { get; set; } + [ProtoMember(2)] + public ItemModifierGroup ItemModifierGroup { get; set; } + [ProtoMember(3)] + public Monster Monster { get; set; } + [ProtoMember(4)] + public int Manuever { get; set; } + [ProtoMember(5)] + public int ChargeDamage { get; set; } + [ProtoMember(6)] + public int Speed { get; set; } + [ProtoMember(7)] + public int BodyLength { get; set; } + [ProtoMember(8)] + public int HitPoints { get; set; } + [ProtoMember(9)] + public bool IsRideable { get; set; } + [ProtoMember(10)] + public bool IsPackAnimal { get; set; } + [ProtoMember(11)] + public SkeletonScale SkeletonScale { get; set; } + + + public HorseComponentSurrogate(HorseComponent horseComponent) + { + if (horseComponent == null) + { + Item = ObjectHelper.SkipConstructor(); + ItemModifierGroup = ObjectHelper.SkipConstructor(); + Monster = ObjectHelper.SkipConstructor(); + Manuever = -1; + ChargeDamage = -1; + Speed = -1; + BodyLength = -1; + HitPoints = -1; + IsRideable = false; + IsPackAnimal = false; + SkeletonScale = ObjectHelper.SkipConstructor(); + } + else + { + Item = horseComponent.Item; + ItemModifierGroup = horseComponent.ItemModifierGroup; + Monster = horseComponent.Monster; + Manuever = horseComponent.Maneuver; + ChargeDamage = horseComponent.ChargeDamage; + Speed = horseComponent.Speed; + BodyLength = horseComponent.BodyLength; + HitPoints = horseComponent.HitPoints; + IsRideable = horseComponent.IsRideable; + IsPackAnimal = horseComponent.IsPackAnimal; + SkeletonScale = horseComponent.SkeletonScale; + } + } + + public static implicit operator HorseComponentSurrogate(HorseComponent horseComponent) + { + return new HorseComponentSurrogate(horseComponent); + } + + public static implicit operator HorseComponent(HorseComponentSurrogate surrogate) + { + return new HorseComponent(); + } + } +} diff --git a/source/GameInterface/Surrogates/ItemCategorySurrogate.cs b/source/GameInterface/Surrogates/ItemCategorySurrogate.cs new file mode 100644 index 000000000..347325b50 --- /dev/null +++ b/source/GameInterface/Surrogates/ItemCategorySurrogate.cs @@ -0,0 +1,63 @@ +using Common.Util; +using ProtoBuf; +using System; +using System.Collections.Generic; +using TaleWorlds.Core; + +namespace GameInterface.Surrogates; +[ProtoContract] +internal struct ItemCategorySurrogate +{ + [ProtoMember(1)] + public bool IsTradeGood { get; set; } + [ProtoMember(2)] + public bool IsAnimal { get; set; } + [ProtoIgnore] + public ItemCategory CanSubstitute { get; set; } + [ProtoMember(4)] + public float SubstitutionFactor { get; set; } + [ProtoMember(5)] + public ItemCategory.Property Properties { get; set; } + [ProtoMember(6)] + public bool IsValid { get; set; } + [ProtoMember(7)] + public float BaseDemand { get; private set; } + [ProtoMember(8)] + public float LuxuryDemand { get; private set; } + + public ItemCategorySurrogate(ItemCategory ItemCategory) + { + if (ItemCategory == null) + { + IsTradeGood = false; + IsAnimal = false; + CanSubstitute = ObjectHelper.SkipConstructor(); + SubstitutionFactor = -1f; + Properties = ItemCategory.Property.None; + IsValid = false; + BaseDemand = -1f; + LuxuryDemand = -1f; + } + else + { + IsTradeGood = ItemCategory.IsTradeGood; + IsAnimal = ItemCategory.IsAnimal; + CanSubstitute = ItemCategory.CanSubstitute; + SubstitutionFactor = ItemCategory.SubstitutionFactor; + Properties = ItemCategory.Properties; + IsValid = ItemCategory.IsValid; + BaseDemand = ItemCategory.BaseDemand; + LuxuryDemand = ItemCategory.LuxuryDemand; + } + } + + public static implicit operator ItemCategorySurrogate(ItemCategory item) + { + return new ItemCategorySurrogate(item); + } + + public static implicit operator ItemCategory(ItemCategorySurrogate item) + { + return new ItemCategory(); + } +} diff --git a/source/GameInterface/Surrogates/ItemComponentSurrogate.cs b/source/GameInterface/Surrogates/ItemComponentSurrogate.cs new file mode 100644 index 000000000..ffdf2c22c --- /dev/null +++ b/source/GameInterface/Surrogates/ItemComponentSurrogate.cs @@ -0,0 +1,198 @@ +using Common.Util; +using ProtoBuf; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using TaleWorlds.Core; + +namespace GameInterface.Surrogates; +[ProtoContract] +internal struct ItemComponentSurrogate +{ + [ProtoMember(1)] + public ItemObjectSurrogate Item { get; set; } + [ProtoMember(2)] + public ItemModifierGroup ItemModifierGroup { get; set; } + + //Horse + [ProtoMember(3)] + public Monster Monster { get; set; } + [ProtoMember(4)] + public int Manuever { get; set; } + [ProtoMember(5)] + public int ChargeDamage { get; set; } + [ProtoMember(6)] + public int Speed { get; set; } + [ProtoMember(7)] + public int BodyLength { get; set; } + [ProtoMember(8)] + public int HitPoints { get; set; } + [ProtoMember(9)] + public bool IsRideable { get; set; } + [ProtoMember(10)] + public bool IsPackAnimal { get; set; } + [ProtoMember(11)] + public SkeletonScale SkeletonScale { get; set; } + + //Armor + [ProtoMember(12)] + public int HeadArmor { get; set; } + [ProtoMember(13)] + public int BodyArmor { get; set; } + [ProtoMember(14)] + public int LegArmor { get; set; } + [ProtoMember(15)] + public int ArmArmor { get; set; } + [ProtoMember(16)] + public int ManeuverBonus { get; set; } + [ProtoMember(17)] + public int SpeedBonus { get; set; } + [ProtoMember(18)] + public int ChargeBonus { get; set; } + [ProtoMember(19)] + public int FamilyType { get; set; } + [ProtoMember(20)] + public ArmorComponent.ArmorMaterialTypes MaterialType { get; set; } + [ProtoMember(21)] + public SkinMask MeshesMask { get; set; } + [ProtoMember(22)] + public ArmorComponent.BodyMeshTypes BodyMeshType { get; set; } + [ProtoMember(23)] + public ArmorComponent.BodyDeformTypes BodyDeformType { get; set; } + [ProtoMember(24)] + public ArmorComponent.HairCoverTypes HairCoverType { get; set; } + [ProtoMember(25)] + public ArmorComponent.BeardCoverTypes BeardCoverType { get; set; } + [ProtoMember(26)] + public ArmorComponent.HorseHarnessCoverTypes ManeCoverType { get; set; } + [ProtoMember(27)] + public ArmorComponent.HorseTailCoverTypes TailCoverType { get; set; } + [ProtoMember(28)] + public string ReinsMesh { get; set; } + [ProtoMember(29)] + public ItemComponentType ComponentType { get; set; } + + public enum ItemComponentType + { + None, + Weapon, + TradeItem, + Saddle, + Horse, + Armor + } + + public ItemComponentSurrogate(ItemComponent itemComponent) + { + Item = ObjectHelper.SkipConstructor(); + ItemModifierGroup = ObjectHelper.SkipConstructor(); + Monster = ObjectHelper.SkipConstructor(); + Manuever = -1; + ChargeDamage = -1; + Speed = -1; + BodyLength = -1; + HitPoints = -1; + IsRideable = false; + IsPackAnimal = false; + SkeletonScale = ObjectHelper.SkipConstructor(); + HeadArmor = -1; + BodyArmor = -1; + LegArmor = -1; + ArmArmor = -1; + ManeuverBonus = -1; + SpeedBonus = -1; + ChargeBonus = -1; + FamilyType = -1; + MaterialType = ArmorComponent.ArmorMaterialTypes.None; + MeshesMask = SkinMask.NoneVisible; + BodyMeshType = ArmorComponent.BodyMeshTypes.Normal; + BodyDeformType = ArmorComponent.BodyDeformTypes.Medium; + HairCoverType = ArmorComponent.HairCoverTypes.None; + BeardCoverType = ArmorComponent.BeardCoverTypes.None; + ManeCoverType = ArmorComponent.HorseHarnessCoverTypes.None; + TailCoverType = ArmorComponent.HorseTailCoverTypes.None; + ReinsMesh = ""; + ComponentType = ItemComponentType.None; + + if (itemComponent != null) + { + Item = itemComponent.Item; + ItemModifierGroup = itemComponent.ItemModifierGroup; + + if (itemComponent is ArmorComponent armorComponent) + { + HeadArmor = armorComponent.HeadArmor; + BodyArmor = armorComponent.BodyArmor; + LegArmor = armorComponent.LegArmor; + ArmArmor = armorComponent.ArmArmor; + ManeuverBonus = armorComponent.ManeuverBonus; + SpeedBonus = armorComponent.SpeedBonus; + ChargeBonus = armorComponent.ChargeBonus; + FamilyType = armorComponent.FamilyType; + MaterialType = armorComponent.MaterialType; + MeshesMask = armorComponent.MeshesMask; + BodyMeshType = armorComponent.BodyMeshType; + BodyDeformType = armorComponent.BodyDeformType; + HairCoverType = armorComponent.HairCoverType; + BeardCoverType = armorComponent.BeardCoverType; + ManeCoverType = armorComponent.ManeCoverType; + TailCoverType = armorComponent.TailCoverType; + ReinsMesh = armorComponent.ReinsMesh; + } + else if (itemComponent is HorseComponent horseComponent) + { + Monster = horseComponent.Monster; + Manuever = horseComponent.Maneuver; + ChargeDamage = horseComponent.ChargeDamage; + Speed = horseComponent.Speed; + BodyLength = horseComponent.BodyLength; + HitPoints = horseComponent.HitPoints; + IsRideable = horseComponent.IsRideable; + IsPackAnimal = horseComponent.IsPackAnimal; + SkeletonScale = horseComponent.SkeletonScale; + } + } + if (itemComponent != null) + { + Type type = itemComponent.GetType(); + + if (type == typeof(ArmorComponent)) + ComponentType = ItemComponentType.Armor; + else if (type == typeof(HorseComponent)) + ComponentType = ItemComponentType.Horse; + else if (type == typeof(WeaponComponent)) + ComponentType = ItemComponentType.Weapon; + else if (type == typeof(TradeItemComponent)) + ComponentType = ItemComponentType.TradeItem; + else if (type == typeof(SaddleComponent)) + ComponentType = ItemComponentType.Saddle; + else + ComponentType = ItemComponentType.None; + } + } + + public static implicit operator ItemComponentSurrogate(ItemComponent itemComponent) + { + return new ItemComponentSurrogate(itemComponent); + } + + public static implicit operator ItemComponent(ItemComponentSurrogate surrogate) + { + switch (surrogate.ComponentType) + { + case ItemComponentType.Weapon: + return new WeaponComponent(surrogate.Item); + case ItemComponentType.TradeItem: + return new TradeItemComponent(); + case ItemComponentType.Saddle: + return new SaddleComponent((SaddleComponent)surrogate); + case ItemComponentType.Horse: + return new HorseComponent(); + case ItemComponentType.Armor: + return new ArmorComponent(surrogate.Item); + default: + throw new InvalidOperationException("Unknown ItemComponentSurrogate type."); + } + } +} + diff --git a/source/GameInterface/Surrogates/ItemObjectSurrogate.cs b/source/GameInterface/Surrogates/ItemObjectSurrogate.cs new file mode 100644 index 000000000..213ee8e46 --- /dev/null +++ b/source/GameInterface/Surrogates/ItemObjectSurrogate.cs @@ -0,0 +1,123 @@ +using Common.Util; +using ProtoBuf; +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +using TaleWorlds.Core; +using TaleWorlds.Library; +using TaleWorlds.Localization; + +namespace GameInterface.Surrogates; + +[ProtoContract] +internal struct ItemObjectSurrogate +{ + [ProtoIgnore] + public ItemComponent ItemComponent { get; set; } + [ProtoMember(2)] + public string MultiMeshName { get; set; } + [ProtoMember(3)] + public string HolsterMeshName { get; set; } + [ProtoMember(4)] + public string HolsterWithWeaponMeshName { get; set; } + [ProtoMember(5)] + public string[] ItemHolsters { get; set; } + [ProtoMember(6)] + public Vec3 HolsterPositionShift { get; set; } + [ProtoMember(7)] + public bool HasLowerHolsterPriority { get; set; } + [ProtoMember(8)] + public string FlyingMeshName { get; set; } + [ProtoMember(9)] + public string BodyName { get; set; } + [ProtoMember(10)] + public string HolsterBodyName { get; set; } + [ProtoMember(11)] + public string CollisionBodyName { get; set; } + [ProtoMember(12)] + public bool RecalculateBody { get; set; } + [ProtoMember(13)] + public string PrefabName { get; set; } + [ProtoMember(14)] + public TextObject Name { get; set; } + [ProtoMember(15)] + public ItemFlags ItemFlags { get; set; } + [ProtoMember(16)] + public ItemCategory ItemCategory { get; set; } + [ProtoMember(17)] + public int Value { get; set; } + [ProtoMember(18)] + public float Effectiveness { get; set; } + [ProtoMember(19)] + public float Weight { get; set; } + [ProtoMember(20)] + public int Difficulty { get; set; } + [ProtoMember(21)] + public float Appearance { get; set; } + [ProtoMember(22)] + public bool IsUsingTableau { get; set; } + + public ItemObjectSurrogate(ItemObject ItemObject) + { + if (ItemObject == null) + { + ItemComponent = new TradeItemComponent(); + MultiMeshName = ""; + HolsterMeshName = ""; + HolsterWithWeaponMeshName = ""; + ItemHolsters = new string[] {""}; + HolsterPositionShift = ObjectHelper.SkipConstructor(); + HasLowerHolsterPriority = false; + FlyingMeshName = ""; + BodyName = ""; + HolsterBodyName = ""; + CollisionBodyName = ""; + RecalculateBody = false; + PrefabName = ""; + Name = ObjectHelper.SkipConstructor(); + ItemFlags = ItemFlags.Civilian; + ItemCategory = ObjectHelper.SkipConstructor(); + Value = -1; + Effectiveness = -1f; + Weight = -1f; + Difficulty = -1; + Appearance = -1f; + IsUsingTableau = false; + } + else + { + ItemComponent = ItemObject.ItemComponent; + MultiMeshName = ItemObject.MultiMeshName; + HolsterMeshName = ItemObject.HolsterMeshName; + HolsterWithWeaponMeshName = ItemObject.HolsterWithWeaponMeshName; + ItemHolsters = ItemObject.ItemHolsters; + HolsterPositionShift = ItemObject.HolsterPositionShift; + HasLowerHolsterPriority = ItemObject.HasLowerHolsterPriority; + FlyingMeshName = ItemObject.FlyingMeshName; + BodyName = ItemObject.BodyName; + HolsterBodyName = ItemObject.HolsterBodyName; + CollisionBodyName = ItemObject.CollisionBodyName; + RecalculateBody = ItemObject.RecalculateBody; + PrefabName = ItemObject.PrefabName; + Name = ItemObject.Name; + ItemFlags = ItemObject.ItemFlags; + ItemCategory = ItemObject.ItemCategory; + Value = ItemObject.Value; + Effectiveness = ItemObject.Effectiveness; + Weight = ItemObject.Weight; + Difficulty = ItemObject.Difficulty; + Appearance = ItemObject.Appearance; + IsUsingTableau = ItemObject.IsUsingTableau; + } + } + + public static implicit operator ItemObjectSurrogate(ItemObject ItemObject) + { + return new ItemObjectSurrogate(ItemObject); + } + + public static implicit operator ItemObject(ItemObjectSurrogate ItemObject) + { + return new ItemObject(); + } +} diff --git a/source/GameInterface/Surrogates/MonsterSurrogate.cs b/source/GameInterface/Surrogates/MonsterSurrogate.cs new file mode 100644 index 000000000..4c9d4c681 --- /dev/null +++ b/source/GameInterface/Surrogates/MonsterSurrogate.cs @@ -0,0 +1,369 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Common.Util; +using ProtoBuf; +using TaleWorlds.Core; +using TaleWorlds.Library; + +namespace GameInterface.Surrogates; +[ProtoContract] +internal struct MonsterSurrogate +{ + [ProtoMember(1)] + public string BaseMonster { get; set; } + [ProtoMember(2)] + public float BodyCapsuleRadius { get; set; } + [ProtoMember(3)] + public Vec3 BodyCapsulePoint1 { get; set; } + [ProtoMember(4)] + public Vec3 BodyCapsulePoint2 { get; set; } + [ProtoMember(5)] + public float CrouchedBodyCapsuleRadius { get; set; } + [ProtoMember(6)] + public Vec3 CrouchedBodyCapsulePoint1 { get; set; } + [ProtoMember(7)] + public Vec3 CrouchedBodyCapsulePoint2 { get; set; } + [ProtoMember(8)] + public AgentFlag Flags { get; set; } + [ProtoMember(9)] + public int Weight { get; set; } + [ProtoMember(10)] + public int HitPoints { get; set; } + [ProtoMember(11)] + public string ActionSetCode { get; set; } + [ProtoMember(12)] + public string FemaleActionSetCode { get; set; } + [ProtoMember(13)] + public int NumPaces { get; set; } + [ProtoMember(14)] + public string MonsterUsage { get; set; } + [ProtoMember(15)] + public float WalkingSpeedLimit { get; set; } + [ProtoMember(16)] + public float CrouchWalkingSpeedLimit { get; set; } + [ProtoMember(17)] + public float JumpAcceleration { get; set; } + [ProtoMember(18)] + public float AbsorbedDamageRatio { get; set; } + [ProtoMember(19)] + public string SoundAndCollisionInfoClassName { get; set; } + [ProtoMember(20)] + public float RiderCameraHeightAdder { get; set; } + [ProtoMember(21)] + public float RiderBodyCapsuleHeightAdder { get; set; } + [ProtoMember(22)] + public float RiderBodyCapsuleForwardAdder { get; set; } + [ProtoMember(23)] + public float StandingChestHeight { get; set; } + [ProtoMember(24)] + public float StandingPelvisHeight { get; set; } + [ProtoMember(25)] + public float StandingEyeHeight { get; set; } + [ProtoMember(26)] + public float CrouchEyeHeight { get; set; } + [ProtoMember(27)] + public float MountedEyeHeight { get; set; } + [ProtoMember(28)] + public float RiderEyeHeightAdder { get; set; } + [ProtoMember(29)] + public Vec3 EyeOffsetWrtHead { get; set; } + [ProtoMember(30)] + public Vec3 FirstPersonCameraOffsetWrtHead { get; set; } + [ProtoMember(31)] + public float ArmLength { get; set; } + [ProtoMember(32)] + public float ArmWeight { get; set; } + [ProtoMember(33)] + public float JumpSpeedLimit { get; set; } + [ProtoMember(34)] + public float RelativeSpeedLimitForCharge { get; set; } + [ProtoMember(35)] + public int FamilyType { get; set; } + [ProtoMember(36)] + public sbyte[] IndicesOfRagdollBonesToCheckForCorpses { get; set; } + [ProtoMember(37)] + public sbyte[] RagdollFallSoundBoneIndices { get; set; } + [ProtoMember(38)] + public sbyte HeadLookDirectionBoneIndex { get; set; } + [ProtoMember(39)] + public sbyte SpineLowerBoneIndex { get; set; } + [ProtoMember(40)] + public sbyte SpineUpperBoneIndex { get; set; } + [ProtoMember(41)] + public sbyte ThoraxLookDirectionBoneIndex { get; set; } + [ProtoMember(42)] + public sbyte NeckRootBoneIndex { get; set; } + [ProtoMember(43)] + public sbyte PelvisBoneIndex { get; set; } + [ProtoMember(44)] + public sbyte RightUpperArmBoneIndex { get; set; } + [ProtoMember(45)] + public sbyte LeftUpperArmBoneIndex { get; set; } + [ProtoMember(46)] + public sbyte FallBlowDamageBoneIndex { get; set; } + [ProtoMember(47)] + public sbyte TerrainDecalBone0Index { get; set; } + [ProtoMember(48)] + public sbyte TerrainDecalBone1Index { get; set; } + [ProtoMember(49)] + public sbyte[] RagdollStationaryCheckBoneIndices { get; set; } + [ProtoMember(50)] + public sbyte[] MoveAdderBoneIndices { get; set; } + [ProtoMember(51)] + public sbyte[] SplashDecalBoneIndices { get; set; } + [ProtoMember(52)] + public sbyte[] BloodBurstBoneIndices { get; set; } + [ProtoMember(53)] + public sbyte MainHandBoneIndex { get; set; } + [ProtoMember(54)] + public sbyte OffHandBoneIndex { get; set; } + [ProtoMember(55)] + public sbyte MainHandItemBoneIndex { get; set; } + [ProtoMember(56)] + public sbyte OffHandItemBoneIndex { get; set; } + [ProtoMember(57)] + public sbyte MainHandItemSecondaryBoneIndex { get; set; } + [ProtoMember(58)] + public sbyte OffHandItemSecondaryBoneIndex { get; set; } + [ProtoMember(59)] + public sbyte OffHandShoulderBoneIndex { get; set; } + [ProtoMember(60)] + public sbyte HandNumBonesForIk { get; set; } + [ProtoMember(61)] + public sbyte PrimaryFootBoneIndex { get; set; } + [ProtoMember(62)] + public sbyte SecondaryFootBoneIndex { get; set; } + [ProtoMember(63)] + public sbyte RightFootIkEndEffectorBoneIndex { get; set; } + [ProtoMember(64)] + public sbyte LeftFootIkEndEffectorBoneIndex { get; set; } + [ProtoMember(65)] + public sbyte RightFootIkTipBoneIndex { get; set; } + [ProtoMember(66)] + public sbyte LeftFootIkTipBoneIndex { get; set; } + [ProtoMember(67)] + public sbyte FootNumBonesForIk { get; set; } + [ProtoMember(68)] + public Vec3 ReinHandleLeftLocalPosition { get; set; } + [ProtoMember(69)] + public Vec3 ReinHandleRightLocalPosition { get; set; } + [ProtoMember(70)] + public string ReinSkeleton { get; set; } + [ProtoMember(71)] + public string ReinCollisionBody { get; set; } + [ProtoMember(72)] + public sbyte FrontBoneToDetectGroundSlopeIndex { get; set; } + [ProtoMember(73)] + public sbyte BackBoneToDetectGroundSlopeIndex { get; set; } + [ProtoMember(74)] + public sbyte[] BoneIndicesToModifyOnSlopingGround { get; set; } + [ProtoMember(75)] + public sbyte BodyRotationReferenceBoneIndex { get; set; } + [ProtoMember(76)] + public sbyte RiderSitBoneIndex { get; set; } + [ProtoMember(77)] + public sbyte ReinHandleBoneIndex { get; set; } + [ProtoMember(78)] + public sbyte ReinCollision1BoneIndex { get; set; } + [ProtoMember(79)] + public sbyte ReinCollision2BoneIndex { get; set; } + [ProtoMember(80)] + public sbyte ReinHeadBoneIndex { get; set; } + [ProtoMember(81)] + public sbyte ReinHeadRightAttachmentBoneIndex { get; set; } + [ProtoMember(82)] + public sbyte ReinHeadLeftAttachmentBoneIndex { get; set; } + [ProtoMember(83)] + public sbyte ReinRightHandBoneIndex { get; set; } + [ProtoMember(84)] + public sbyte ReinLeftHandBoneIndex { get; set; } + + public MonsterSurrogate(Monster Monster) + { + if (Monster == null) + { + BaseMonster = ""; + BodyCapsuleRadius = -1; + BodyCapsulePoint1 = ObjectHelper.SkipConstructor(); + BodyCapsulePoint2 = ObjectHelper.SkipConstructor(); + CrouchedBodyCapsuleRadius = -1; + CrouchedBodyCapsulePoint1 = ObjectHelper.SkipConstructor(); + CrouchedBodyCapsulePoint2 = ObjectHelper.SkipConstructor(); + Flags = AgentFlag.None; + Weight = -1; + HitPoints = -1; + ActionSetCode = ""; + FemaleActionSetCode = ""; + NumPaces = -1; + MonsterUsage = ""; + WalkingSpeedLimit = -1; + CrouchWalkingSpeedLimit = -1; + JumpAcceleration = -1; + AbsorbedDamageRatio = -1; + SoundAndCollisionInfoClassName = ""; + RiderCameraHeightAdder = -1; + RiderBodyCapsuleHeightAdder = -1; + RiderBodyCapsuleForwardAdder = -1; + StandingChestHeight = -1; + StandingPelvisHeight = -1; + StandingEyeHeight = -1; + CrouchEyeHeight = -1; + MountedEyeHeight = -1; + RiderEyeHeightAdder = -1; + EyeOffsetWrtHead = ObjectHelper.SkipConstructor(); + FirstPersonCameraOffsetWrtHead = ObjectHelper.SkipConstructor(); + ArmLength = -1; + ArmWeight = -1; + JumpSpeedLimit = -1; + RelativeSpeedLimitForCharge = -1; + FamilyType = -1; + IndicesOfRagdollBonesToCheckForCorpses = new sbyte[0]; + RagdollFallSoundBoneIndices = new sbyte[0]; + HeadLookDirectionBoneIndex = -1; + SpineLowerBoneIndex = -1; + SpineUpperBoneIndex = -1; + ThoraxLookDirectionBoneIndex = -1; + NeckRootBoneIndex = -1; + PelvisBoneIndex = -1; + RightUpperArmBoneIndex = -1; + LeftUpperArmBoneIndex = -1; + FallBlowDamageBoneIndex = -1; + TerrainDecalBone0Index = -1; + TerrainDecalBone1Index = -1; + RagdollStationaryCheckBoneIndices = new sbyte[0]; + MoveAdderBoneIndices = new sbyte[0]; + SplashDecalBoneIndices = new sbyte[0]; + BloodBurstBoneIndices = new sbyte[0]; + MainHandBoneIndex = -1; + OffHandBoneIndex = -1; + MainHandItemBoneIndex = -1; + OffHandItemBoneIndex = -1; + MainHandItemSecondaryBoneIndex = -1; + OffHandItemSecondaryBoneIndex = -1; + OffHandShoulderBoneIndex = -1; + HandNumBonesForIk = -1; + PrimaryFootBoneIndex = -1; + SecondaryFootBoneIndex = -1; + RightFootIkEndEffectorBoneIndex = -1; + LeftFootIkEndEffectorBoneIndex = -1; + RightFootIkTipBoneIndex = -1; + LeftFootIkTipBoneIndex = -1; + FootNumBonesForIk = -1; + ReinHandleLeftLocalPosition = ObjectHelper.SkipConstructor(); + ReinHandleRightLocalPosition = ObjectHelper.SkipConstructor(); + ReinSkeleton = ""; + ReinCollisionBody = ""; + FrontBoneToDetectGroundSlopeIndex = -1; + BackBoneToDetectGroundSlopeIndex = -1; + BoneIndicesToModifyOnSlopingGround = new sbyte[0]; + BodyRotationReferenceBoneIndex = -1; + RiderSitBoneIndex = -1; + ReinHandleBoneIndex = -1; + ReinCollision1BoneIndex = -1; + ReinCollision2BoneIndex = -1; + ReinHeadBoneIndex = -1; + ReinHeadRightAttachmentBoneIndex = -1; + ReinHeadLeftAttachmentBoneIndex = -1; + ReinRightHandBoneIndex = -1; + ReinLeftHandBoneIndex = -1; + } + else + { + BaseMonster = Monster.BaseMonster; + BodyCapsuleRadius = Monster.BodyCapsuleRadius; + BodyCapsulePoint1 = Monster.BodyCapsulePoint1; + BodyCapsulePoint2 = Monster.BodyCapsulePoint2; + CrouchedBodyCapsuleRadius = Monster.CrouchedBodyCapsuleRadius; + CrouchedBodyCapsulePoint1 = Monster.CrouchedBodyCapsulePoint1; + CrouchedBodyCapsulePoint2 = Monster.CrouchedBodyCapsulePoint2; + Flags = Monster.Flags; + Weight = Monster.Weight; + HitPoints = Monster.HitPoints; + ActionSetCode = Monster.ActionSetCode; + FemaleActionSetCode = Monster.FemaleActionSetCode; + NumPaces = Monster.NumPaces; + MonsterUsage = Monster.MonsterUsage; + WalkingSpeedLimit = Monster.WalkingSpeedLimit; + CrouchWalkingSpeedLimit = Monster.CrouchWalkingSpeedLimit; + JumpAcceleration = Monster.JumpAcceleration; + AbsorbedDamageRatio = Monster.AbsorbedDamageRatio; + SoundAndCollisionInfoClassName = Monster.SoundAndCollisionInfoClassName; + RiderCameraHeightAdder = Monster.RiderCameraHeightAdder; + RiderBodyCapsuleHeightAdder = Monster.RiderBodyCapsuleHeightAdder; + RiderBodyCapsuleForwardAdder = Monster.RiderBodyCapsuleForwardAdder; + StandingChestHeight = Monster.StandingChestHeight; + StandingPelvisHeight = Monster.StandingPelvisHeight; + StandingEyeHeight = Monster.StandingEyeHeight; + CrouchEyeHeight = Monster.CrouchEyeHeight; + MountedEyeHeight = Monster.MountedEyeHeight; + RiderEyeHeightAdder = Monster.RiderEyeHeightAdder; + EyeOffsetWrtHead = Monster.EyeOffsetWrtHead; + FirstPersonCameraOffsetWrtHead = Monster.FirstPersonCameraOffsetWrtHead; + ArmLength = Monster.ArmLength; + ArmWeight = Monster.ArmWeight; + JumpSpeedLimit = Monster.JumpSpeedLimit; + RelativeSpeedLimitForCharge = Monster.RelativeSpeedLimitForCharge; + FamilyType = Monster.FamilyType; + IndicesOfRagdollBonesToCheckForCorpses = Monster.IndicesOfRagdollBonesToCheckForCorpses ?? new sbyte[0]; + RagdollFallSoundBoneIndices = Monster.RagdollFallSoundBoneIndices ?? new sbyte[0]; + HeadLookDirectionBoneIndex = Monster.HeadLookDirectionBoneIndex; + SpineLowerBoneIndex = Monster.SpineLowerBoneIndex; + SpineUpperBoneIndex = Monster.SpineUpperBoneIndex; + ThoraxLookDirectionBoneIndex = Monster.ThoraxLookDirectionBoneIndex; + NeckRootBoneIndex = Monster.NeckRootBoneIndex; + PelvisBoneIndex = Monster.PelvisBoneIndex; + RightUpperArmBoneIndex = Monster.RightUpperArmBoneIndex; + LeftUpperArmBoneIndex = Monster.LeftUpperArmBoneIndex; + FallBlowDamageBoneIndex = Monster.FallBlowDamageBoneIndex; + TerrainDecalBone0Index = Monster.TerrainDecalBone0Index; + TerrainDecalBone1Index = Monster.TerrainDecalBone1Index; + RagdollStationaryCheckBoneIndices = Monster.RagdollStationaryCheckBoneIndices ?? new sbyte[0]; + MoveAdderBoneIndices = Monster.MoveAdderBoneIndices ?? new sbyte[0]; + SplashDecalBoneIndices = Monster.SplashDecalBoneIndices ?? new sbyte[0]; + BloodBurstBoneIndices = Monster.BloodBurstBoneIndices ?? new sbyte[0]; + MainHandBoneIndex = Monster.MainHandBoneIndex; + OffHandBoneIndex = Monster.OffHandBoneIndex; + MainHandItemBoneIndex = Monster.MainHandItemBoneIndex; + OffHandItemBoneIndex = Monster.OffHandItemBoneIndex; + MainHandItemSecondaryBoneIndex = Monster.MainHandItemSecondaryBoneIndex; + OffHandItemSecondaryBoneIndex = Monster.OffHandItemSecondaryBoneIndex; + OffHandShoulderBoneIndex = Monster.OffHandShoulderBoneIndex; + HandNumBonesForIk = Monster.HandNumBonesForIk; + PrimaryFootBoneIndex = Monster.PrimaryFootBoneIndex; + SecondaryFootBoneIndex = Monster.SecondaryFootBoneIndex; + RightFootIkEndEffectorBoneIndex = Monster.RightFootIkEndEffectorBoneIndex; + LeftFootIkEndEffectorBoneIndex = Monster.LeftFootIkEndEffectorBoneIndex; + RightFootIkTipBoneIndex = Monster.RightFootIkTipBoneIndex; + LeftFootIkTipBoneIndex = Monster.LeftFootIkTipBoneIndex; + FootNumBonesForIk = Monster.FootNumBonesForIk; + ReinHandleLeftLocalPosition = Monster.ReinHandleLeftLocalPosition; + ReinHandleRightLocalPosition = Monster.ReinHandleRightLocalPosition; + ReinSkeleton = Monster.ReinSkeleton; + ReinCollisionBody = Monster.ReinCollisionBody; + FrontBoneToDetectGroundSlopeIndex = Monster.FrontBoneToDetectGroundSlopeIndex; + BackBoneToDetectGroundSlopeIndex = Monster.BackBoneToDetectGroundSlopeIndex; + BoneIndicesToModifyOnSlopingGround = Monster.BoneIndicesToModifyOnSlopingGround; + BodyRotationReferenceBoneIndex = Monster.BodyRotationReferenceBoneIndex; + RiderSitBoneIndex = Monster.RiderSitBoneIndex; + ReinHandleBoneIndex = Monster.ReinHandleBoneIndex; + ReinCollision1BoneIndex = Monster.ReinCollision1BoneIndex; + ReinCollision2BoneIndex = Monster.ReinCollision2BoneIndex; + ReinHeadBoneIndex = Monster.ReinHeadBoneIndex; + ReinHeadRightAttachmentBoneIndex = Monster.ReinHeadRightAttachmentBoneIndex; + ReinHeadLeftAttachmentBoneIndex = Monster.ReinHeadLeftAttachmentBoneIndex; + ReinRightHandBoneIndex = Monster.ReinRightHandBoneIndex; + ReinLeftHandBoneIndex = Monster.ReinLeftHandBoneIndex; + } + } + + public static implicit operator MonsterSurrogate(Monster Monster) + { + return new MonsterSurrogate(Monster); + } + + public static implicit operator Monster(MonsterSurrogate MonsterSurrogate) + { + return new Monster(); + } +} diff --git a/source/GameInterface/Surrogates/SaddleComponentSurrogate.cs b/source/GameInterface/Surrogates/SaddleComponentSurrogate.cs new file mode 100644 index 000000000..f63072bee --- /dev/null +++ b/source/GameInterface/Surrogates/SaddleComponentSurrogate.cs @@ -0,0 +1,42 @@ +using Common.Util; +using ProtoBuf; +using System; +using System.Collections.Generic; +using TaleWorlds.Core; + +namespace GameInterface.Surrogates +{ + [ProtoContract] + internal struct SaddleComponentSurrogate + { + [ProtoMember(1)] + public ItemObject Item { get; set; } + [ProtoMember(2)] + public ItemModifierGroup ItemModifierGroup { get; set; } + + + public SaddleComponentSurrogate(SaddleComponent saddleComponent) + { + if (saddleComponent == null) + { + Item = ObjectHelper.SkipConstructor(); + ItemModifierGroup = ObjectHelper.SkipConstructor(); + } + else + { + Item = saddleComponent.Item; + ItemModifierGroup = saddleComponent.ItemModifierGroup; + } + } + + public static implicit operator SaddleComponentSurrogate(SaddleComponent saddleComponent) + { + return new SaddleComponentSurrogate(saddleComponent); + } + + public static implicit operator SaddleComponent(SaddleComponentSurrogate surrogate) + { + return new SaddleComponent(surrogate); + } + } +} diff --git a/source/GameInterface/Surrogates/SkeletonScaleSurrogate.cs b/source/GameInterface/Surrogates/SkeletonScaleSurrogate.cs new file mode 100644 index 000000000..5d969c10d --- /dev/null +++ b/source/GameInterface/Surrogates/SkeletonScaleSurrogate.cs @@ -0,0 +1,56 @@ +using Common.Util; +using ProtoBuf; +using System; +using System.Collections.Generic; +using TaleWorlds.Core; +using TaleWorlds.Library; + +namespace GameInterface.Surrogates; +[ProtoContract] +internal struct SkeletonScaleSurrogate +{ + [ProtoMember(1)] + public string SkeletonModel { get; private set; } + [ProtoMember(2)] + public Vec3 MountSitBoneScale { get; private set; } + [ProtoMember(3)] + public float MountRadiusAdder { get; private set; } + [ProtoMember(4)] + public Vec3[] Scales { get; private set; } + [ProtoMember(5)] + public List BoneNames { get; private set; } + [ProtoMember(6)] + public sbyte[] BoneIndices { get; private set; } + + public SkeletonScaleSurrogate(SkeletonScale SkeletonScale) + { + if (SkeletonScale == null) + { + SkeletonModel = ""; + MountSitBoneScale = ObjectHelper.SkipConstructor(); + MountRadiusAdder = -1f; + Scales = ObjectHelper.SkipConstructor(); + BoneNames = new List() { "" }; + BoneIndices = new sbyte[] { 0 }; + } + else + { + SkeletonModel = SkeletonScale.SkeletonModel; + MountSitBoneScale = SkeletonScale.MountSitBoneScale; + MountRadiusAdder = SkeletonScale.MountRadiusAdder; + Scales = SkeletonScale.Scales; + BoneNames = SkeletonScale.BoneNames; + BoneIndices = SkeletonScale.BoneIndices; + } + } + + public static implicit operator SkeletonScaleSurrogate(SkeletonScale SkeletonScale) + { + return new SkeletonScaleSurrogate(SkeletonScale); + } + + public static implicit operator SkeletonScale(SkeletonScaleSurrogate SkeletonScale) + { + return new SkeletonScale(); + } +} diff --git a/source/GameInterface/Surrogates/SurrogateCollection.cs b/source/GameInterface/Surrogates/SurrogateCollection.cs index 7bef3e60a..4d6d31740 100644 --- a/source/GameInterface/Surrogates/SurrogateCollection.cs +++ b/source/GameInterface/Surrogates/SurrogateCollection.cs @@ -1,4 +1,5 @@ -using ProtoBuf.Meta; +using System; +using ProtoBuf.Meta; using TaleWorlds.CampaignSystem; using TaleWorlds.Core; using TaleWorlds.Library; @@ -32,5 +33,32 @@ public SurrogateCollection() if (RuntimeTypeModel.Default.CanSerialize(typeof(Vec3)) == false) RuntimeTypeModel.Default.SetSurrogate(); + + if (RuntimeTypeModel.Default.CanSerialize(typeof(ItemObject)) == false) + RuntimeTypeModel.Default.SetSurrogate(); + + if (RuntimeTypeModel.Default.CanSerialize(typeof(ItemComponent)) == false) + RuntimeTypeModel.Default.SetSurrogate(); + + if (RuntimeTypeModel.Default.CanSerialize(typeof(ItemCategory)) == false) + RuntimeTypeModel.Default.SetSurrogate(); + + if (RuntimeTypeModel.Default.CanSerialize(typeof(SkeletonScale)) == false) + RuntimeTypeModel.Default.SetSurrogate(); + + if (RuntimeTypeModel.Default.CanSerialize(typeof(Monster)) == false) + RuntimeTypeModel.Default.SetSurrogate(); + + if (RuntimeTypeModel.Default.CanSerialize(typeof(WeaponComponent)) == false) + RuntimeTypeModel.Default.SetSurrogate(); + + if (RuntimeTypeModel.Default.CanSerialize(typeof(SaddleComponent)) == false) + RuntimeTypeModel.Default.SetSurrogate(); + + if (RuntimeTypeModel.Default.CanSerialize(typeof(HorseComponent)) == false) + RuntimeTypeModel.Default.SetSurrogate(); + + if (RuntimeTypeModel.Default.CanSerialize(typeof(ArmorComponent)) == false) + RuntimeTypeModel.Default.SetSurrogate(); } } diff --git a/source/GameInterface/Surrogates/TradeItemComponentSurrogate.cs b/source/GameInterface/Surrogates/TradeItemComponentSurrogate.cs new file mode 100644 index 000000000..eaadf9ee7 --- /dev/null +++ b/source/GameInterface/Surrogates/TradeItemComponentSurrogate.cs @@ -0,0 +1,43 @@ +using Common.Util; +using ProtoBuf; +using System; +using System.Collections.Generic; +using TaleWorlds.Core; + +namespace GameInterface.Surrogates +{ + [ProtoContract] + internal struct TradeItemComponentSurrogate + { + [ProtoMember(1)] + public ItemObject Item { get; set; } + [ProtoMember(2)] + public ItemModifierGroup ItemModifierGroup { get; set; } + + + public TradeItemComponentSurrogate(TradeItemComponent tradeItemComponent) + { + if (tradeItemComponent == null) + { + Item = ObjectHelper.SkipConstructor(); + ItemModifierGroup = ObjectHelper.SkipConstructor(); + } + else + { + Item = tradeItemComponent.Item; + ItemModifierGroup = tradeItemComponent.ItemModifierGroup; + } + } + + public static implicit operator TradeItemComponentSurrogate(TradeItemComponent tradeItemComponent) + { + return new TradeItemComponentSurrogate(tradeItemComponent); + } + + public static implicit operator TradeItemComponent(TradeItemComponentSurrogate surrogate) + { + return new TradeItemComponent(); + } + } +} + diff --git a/source/GameInterface/Surrogates/WeaponComponentSurrogate.cs b/source/GameInterface/Surrogates/WeaponComponentSurrogate.cs new file mode 100644 index 000000000..e4db05dc1 --- /dev/null +++ b/source/GameInterface/Surrogates/WeaponComponentSurrogate.cs @@ -0,0 +1,42 @@ +using Common.Util; +using ProtoBuf; +using System; +using System.Collections.Generic; +using TaleWorlds.Core; + +namespace GameInterface.Surrogates; + + +[ProtoContract] +internal struct WeaponComponentSurrogate +{ + [ProtoMember(1)] + public ItemObject Item { get; set; } + [ProtoMember(2)] + public ItemModifierGroup ItemModifierGroup { get; set; } + + + public WeaponComponentSurrogate(WeaponComponent weaponComponent) + { + if (weaponComponent == null) + { + Item = ObjectHelper.SkipConstructor(); + ItemModifierGroup = ObjectHelper.SkipConstructor(); + } + else + { + Item = weaponComponent.Item; + ItemModifierGroup = weaponComponent.ItemModifierGroup; + } + } + + public static implicit operator WeaponComponentSurrogate(WeaponComponent weaponComponent) + { + return new WeaponComponentSurrogate(weaponComponent); + } + + public static implicit operator WeaponComponent(WeaponComponentSurrogate surrogate) + { + return new WeaponComponent(surrogate.Item); + } +} From 8b8492305c6a9341d55f3fd09d28b49c31120439 Mon Sep 17 00:00:00 2001 From: Jackson Martin Date: Fri, 31 Jan 2025 18:07:24 -0500 Subject: [PATCH 6/7] Changed ItemComponentSurrogate.Item to ItemObject Changed ItemComponentSurrogate.Item to ItemObject --- source/GameInterface/Surrogates/ItemComponentSurrogate.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/GameInterface/Surrogates/ItemComponentSurrogate.cs b/source/GameInterface/Surrogates/ItemComponentSurrogate.cs index ffdf2c22c..90f1f3f1e 100644 --- a/source/GameInterface/Surrogates/ItemComponentSurrogate.cs +++ b/source/GameInterface/Surrogates/ItemComponentSurrogate.cs @@ -10,7 +10,7 @@ namespace GameInterface.Surrogates; internal struct ItemComponentSurrogate { [ProtoMember(1)] - public ItemObjectSurrogate Item { get; set; } + public ItemObject Item { get; set; } [ProtoMember(2)] public ItemModifierGroup ItemModifierGroup { get; set; } From aae7114e49eda860765010259b4ebf7ce92dbf15 Mon Sep 17 00:00:00 2001 From: Alexander Egard Date: Sun, 9 Feb 2025 00:35:08 +0100 Subject: [PATCH 7/7] Fixed tests and updated Harmony version --- .../ItemObjects/ItemObjectSyncTest.cs | 48 +++++++------------ .../GameInterface.Tests.csproj | 2 +- 2 files changed, 18 insertions(+), 32 deletions(-) diff --git a/source/E2E.Tests/Services/ItemObjects/ItemObjectSyncTest.cs b/source/E2E.Tests/Services/ItemObjects/ItemObjectSyncTest.cs index b7300addd..8ebdf8f8a 100644 --- a/source/E2E.Tests/Services/ItemObjects/ItemObjectSyncTest.cs +++ b/source/E2E.Tests/Services/ItemObjects/ItemObjectSyncTest.cs @@ -1,24 +1,12 @@ using Common.Util; using E2E.Tests.Environment; using HarmonyLib; -using System.Runtime.ConstrainedExecution; -using System.Runtime.InteropServices; -using TaleWorlds.CampaignSystem; -using TaleWorlds.CampaignSystem.Settlements.Buildings; -using TaleWorlds.CampaignSystem.Siege; using TaleWorlds.Core; using TaleWorlds.Library; using TaleWorlds.Localization; using Xunit.Abstractions; -using GameInterface.Tests.Bootstrap.Modules; -using System.ComponentModel; -using Autofac; -using NuGet.Frameworks; -using Newtonsoft.Json.Serialization; -using JetBrains.Annotations; -using System.Diagnostics; - -namespace E2E.Tests.Services.ItemObjectService + +namespace E2E.Tests.Services.ItemObjects { public class ItemObjectSyncTest : IDisposable { @@ -48,13 +36,12 @@ public void ServerCreateItemObject_SyncAllClients() var culture = new BasicCultureObject() { Name = new TextObject("Battania") }; var weaponDesign = ObjectHelper.SkipConstructor(); var holsterPositionShift = new Vec3(1, 2, 3, 4); - string[] itemHolsters = { "holster1", "holster2", "holster3" }; + string[] itemHolsters = { "holster12", "holster23", "holster34" }; var itemComponent = new TradeItemComponent(); var itemCategory = ObjectHelper.SkipConstructor(); var prerequisiteItem = new ItemObject(); var itemTypeEnum = ItemObject.ItemTypeEnum.OneHandedWeapon; - server.Call(() => { ItemObject itemObject = new ItemObject(); @@ -106,13 +93,13 @@ public void ServerCreateItemObject_SyncAllClients() //typeIntercept.Invoke(null, new object[] { itemObject, 69 }); }); - server.ObjectManager.TryGetId(itemObject, out string serverObjectId); - server.ObjectManager.TryGetId(itemObject.Culture, out string serverCultureId); - server.ObjectManager.TryGetId(itemObject.WeaponDesign, out string serverWeaponDesignId); - server.ObjectManager.TryGetId(itemObject.ItemHolsters, out string serverItemHolstersId); - server.ObjectManager.TryGetId(itemObject.ItemComponent, out string serverItemComponentId); - server.ObjectManager.TryGetId(itemObject.ItemCategory, out string serverItemCategoryId); - server.ObjectManager.TryGetId(itemObject.PrerequisiteItem, out string serverPrerequisiteItemId); + Assert.True(server.ObjectManager.TryGetId(itemObject, out string serverObjectId)); + Assert.True(server.ObjectManager.TryGetId(itemObject.Culture, out string serverCultureId)); + Assert.True(server.ObjectManager.TryGetId(itemObject.WeaponDesign, out string serverWeaponDesignId)); + Assert.True(server.ObjectManager.TryGetId(itemObject.ItemHolsters, out string serverItemHolstersId)); + Assert.True(server.ObjectManager.TryGetId(itemObject.ItemComponent, out string serverItemComponentId)); + Assert.True(server.ObjectManager.TryGetId(itemObject.ItemCategory, out string serverItemCategoryId)); + Assert.True(server.ObjectManager.TryGetId(itemObject.PrerequisiteItem, out string serverPrerequisiteItemId)); foreach (var client in TestEnvironment.Clients) { @@ -121,13 +108,13 @@ public void ServerCreateItemObject_SyncAllClients() //Field Assert.Equal(itemObject.Type, clientItemObject.Type); - client.ObjectManager.TryGetId(clientItemObject, out string clientObjectId); - client.ObjectManager.TryGetId(clientItemObject.Culture, out string clientCultureId); - client.ObjectManager.TryGetId(clientItemObject.WeaponDesign, out string clientWeaponDesignId); - client.ObjectManager.TryGetId(clientItemObject.ItemHolsters, out string clientItemHolstersId); - client.ObjectManager.TryGetId(clientItemObject.ItemComponent, out string clientItemComponentId); - client.ObjectManager.TryGetId(clientItemObject.ItemCategory, out string clientItemCategoryId); - client.ObjectManager.TryGetId(clientItemObject.PrerequisiteItem, out string clientPrerequisiteItemId); + Assert.True(client.ObjectManager.TryGetId(clientItemObject, out string clientObjectId)); + Assert.True(client.ObjectManager.TryGetId(clientItemObject.Culture, out string clientCultureId)); + Assert.True(client.ObjectManager.TryGetId(clientItemObject.WeaponDesign, out string clientWeaponDesignId)); + Assert.True(client.ObjectManager.TryGetId(clientItemObject.ItemHolsters, out string clientItemHolstersId)); + Assert.True(client.ObjectManager.TryGetId(clientItemObject.ItemComponent, out string clientItemComponentId)); + Assert.True(client.ObjectManager.TryGetId(clientItemObject.ItemCategory, out string clientItemCategoryId)); + Assert.True(client.ObjectManager.TryGetId(clientItemObject.PrerequisiteItem, out string clientPrerequisiteItemId)); Assert.Equal(serverObjectId, clientObjectId); @@ -168,7 +155,6 @@ public void ServerCreateItemObject_SyncAllClients() Assert.Equal(serverPrerequisiteItemId, clientPrerequisiteItemId); Assert.Equal(ItemObject.ItemTypeEnum.OneHandedWeapon, clientItemObject.ItemType); - //Collection Assert.Equal(itemHolsters, clientItemObject.ItemHolsters); Assert.Equal(itemHolsters[0], clientItemObject.ItemHolsters[0]); diff --git a/source/GameInterface.Tests/GameInterface.Tests.csproj b/source/GameInterface.Tests/GameInterface.Tests.csproj index d3c8d366d..1e5536159 100644 --- a/source/GameInterface.Tests/GameInterface.Tests.csproj +++ b/source/GameInterface.Tests/GameInterface.Tests.csproj @@ -33,7 +33,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - +