From 840c13d2c3d5a409fb4c9cc357211136d489f4a5 Mon Sep 17 00:00:00 2001 From: ze-dom Date: Tue, 24 Sep 2024 12:50:59 +0100 Subject: [PATCH 01/12] Fixed max element jewelry resistance --- src/GameLogic/Attributes/PowerUpWrapper.cs | 5 + src/GameLogic/Attributes/Stats.cs | 14 +-- src/GameLogic/IItemPowerUpFactory.cs | 4 +- src/GameLogic/InventoryStorage.cs | 97 +++++++++++++++++-- src/GameLogic/ItemExtensions.cs | 16 ++- src/GameLogic/ItemPowerUpFactory.cs | 20 ++-- .../Initialization/Items/OptionExtensions.cs | 2 +- .../Version075/Items/Jewelery.cs | 5 +- 8 files changed, 136 insertions(+), 27 deletions(-) diff --git a/src/GameLogic/Attributes/PowerUpWrapper.cs b/src/GameLogic/Attributes/PowerUpWrapper.cs index 7e50e2b93..d409002ad 100644 --- a/src/GameLogic/Attributes/PowerUpWrapper.cs +++ b/src/GameLogic/Attributes/PowerUpWrapper.cs @@ -44,6 +44,11 @@ public PowerUpWrapper(IElement element, AttributeDefinition targetAttribute, Att /// public AggregateType AggregateType => this._element.AggregateType; + /// + /// Gets the parent attribute. + /// + public ComposableAttribute? ParentAttribute => this._parentAttribute; + /// /// Creates elements by a . /// diff --git a/src/GameLogic/Attributes/Stats.cs b/src/GameLogic/Attributes/Stats.cs index 6a28bbf6f..f51b4ea28 100644 --- a/src/GameLogic/Attributes/Stats.cs +++ b/src/GameLogic/Attributes/Stats.cs @@ -553,37 +553,37 @@ public class Stats public static AttributeDefinition IsStunned { get; } = new (new Guid("22C86BAF-7F27-478D-8075-E4465C2859DD"), "Is stunned", "The player is poisoned and loses health"); /// - /// Gets the ice resistance attribute definition. Value range from 0 to 1. + /// Gets the ice resistance attribute definition. Value range from 0 to 0.5. /// public static AttributeDefinition IceResistance { get; } = new (new Guid("47235C36-41BB-44B4-8823-6FC415709F59"), "Ice Resistance", string.Empty); /// - /// Gets the fire resistance attribute definition. Value range from 0 to 1. + /// Gets the fire resistance attribute definition. Value range from 0 to 0.5. /// public static AttributeDefinition FireResistance { get; } = new (new Guid("9AE4D80D-5706-48B9-AD11-EAC4FE088A81"), "Fire Resistance", string.Empty); /// - /// Gets the water resistance attribute definition. Value range from 0 to 1. + /// Gets the water resistance attribute definition. Value range from 0 to 0.5. /// public static AttributeDefinition WaterResistance { get; } = new (new Guid("3AF88672-D8DB-44E1-937A-7E6484134C39"), "Water Resistance", string.Empty); /// - /// Gets the earth resistance attribute definition. Value range from 0 to 1. + /// Gets the earth resistance attribute definition. Value range from 0 to 0.5. /// public static AttributeDefinition EarthResistance { get; } = new (new Guid("4470890F-00CE-44A6-BADB-203684B6014D"), "Earth Resistance", string.Empty); /// - /// Gets the wind resistance attribute definition. Value range from 0 to 1. + /// Gets the wind resistance attribute definition. Value range from 0 to 0.5. /// public static AttributeDefinition WindResistance { get; } = new (new Guid("03A29C46-7B7E-424D-8325-8390692570C3"), "Wind Resistance", string.Empty); /// - /// Gets the poison resistance attribute definition. Value range from 0 to 1. + /// Gets the poison resistance attribute definition. Value range from 0 to 0.5. /// public static AttributeDefinition PoisonResistance { get; } = new (new Guid("3D50D0B7-63A2-4DA9-8855-12173EAE6B39"), "Poison Resistance", string.Empty); /// - /// Gets the lightning resistance attribute definition. Value range from 0 to 1. + /// Gets the lightning resistance attribute definition. Value range from 0 to 0.5. /// public static AttributeDefinition LightningResistance { get; } = new (new Guid("3E339393-2D17-452E-81D9-3987947A407F"), "Lightning Resistance", string.Empty); diff --git a/src/GameLogic/IItemPowerUpFactory.cs b/src/GameLogic/IItemPowerUpFactory.cs index f5ee5e07e..a73f59b30 100644 --- a/src/GameLogic/IItemPowerUpFactory.cs +++ b/src/GameLogic/IItemPowerUpFactory.cs @@ -19,8 +19,10 @@ public interface IItemPowerUpFactory /// /// The item. /// The attribute system of the player who equipped the item. + /// If only the item base power ups should be built. + /// If only the item option power ups should be built. /// The created power ups. - IEnumerable GetPowerUps(Item item, AttributeSystem attributeSystem); + IEnumerable GetPowerUps(Item item, AttributeSystem attributeSystem, bool skipBasePowerUps = false, bool skipOptionPowerUps = false); /// /// Gets the set power ups, which are created for existing s in the equipped items. diff --git a/src/GameLogic/InventoryStorage.cs b/src/GameLogic/InventoryStorage.cs index a0805a57b..9b5a1c6fb 100644 --- a/src/GameLogic/InventoryStorage.cs +++ b/src/GameLogic/InventoryStorage.cs @@ -4,11 +4,12 @@ namespace MUnique.OpenMU.GameLogic; +using MUnique.OpenMU.AttributeSystem; using MUnique.OpenMU.DataModel; using MUnique.OpenMU.GameLogic.Attributes; using MUnique.OpenMU.GameLogic.Views.World; using MUnique.OpenMU.PlugIns; -using static OpenMU.DataModel.InventoryConstants; +using static MUnique.OpenMU.DataModel.InventoryConstants; /// /// The storage of an inventory of a player, which also contains equippable slots. This class also manages the powerups which get created by equipped items. @@ -145,9 +146,19 @@ await this._player.ForEachWorldObserverAsync( return; } - if (this._player.Attributes.ItemPowerUps.TryGetValue(item, out var itemPowerUps)) + var attributes = this._player.Attributes; + var factory = this._gameContext.ItemPowerUpFactory; + bool itemIsJewelry = item.IsJewelry(); + + if (attributes.ItemPowerUps.TryGetValue(item, out var itemPowerUps)) { - this._player.Attributes.ItemPowerUps.Remove(item); + if (itemIsJewelry) + { // Run this before remmoving power ups + this.HandleJewelryBasePowerUps(item, true); + } + + attributes.ItemPowerUps.Remove(item); + foreach (var powerUp in itemPowerUps) { powerUp.Dispose(); @@ -162,12 +173,18 @@ await this._player.ForEachWorldObserverAsync( var itemAdded = this.EquippedItems.Contains(item); if (itemAdded) { - var factory = this._gameContext.ItemPowerUpFactory; - this._player.Attributes.ItemPowerUps.Add(item, factory.GetPowerUps(item, this._player.Attributes).ToList()); + bool skipBasePowerUps = false; + if (itemIsJewelry) + { + skipBasePowerUps = this.HandleJewelryBasePowerUps(item); + } + + attributes.ItemPowerUps.Add(item, factory.GetPowerUps(item, attributes, skipBasePowerUps, false).ToList()); // reset player equipped ammunition amount - if (this.EquippedAmmunitionItem is { } ammoItem) { - this._player.Attributes[Stats.AmmunitionAmount] = (float) ammoItem.Durability; + if (this.EquippedAmmunitionItem is { } ammoItem) + { + attributes[Stats.AmmunitionAmount] = (float)ammoItem.Durability; } } } @@ -189,7 +206,13 @@ private void InitializePowerUps() { foreach (var item in this.EquippedItems) { - this._player.Attributes.ItemPowerUps.Add(item, factory.GetPowerUps(item, this._player.Attributes).ToList()); + bool skipBasePowerUps = false; + if (item.IsJewelry()) + { + skipBasePowerUps = this.HandleJewelryBasePowerUps(item); + } + + this._player.Attributes.ItemPowerUps.Add(item, factory.GetPowerUps(item, this._player.Attributes, skipBasePowerUps, false).ToList()); } this.UpdateSetPowerUps(); @@ -218,4 +241,62 @@ private void UpdateSetPowerUps() var factory = this._gameContext.ItemPowerUpFactory; this._player.Attributes.ItemSetPowerUps = factory.GetSetPowerUps(this.EquippedItems, this._player.Attributes, this._player.GameContext.Configuration).ToList(); } + + /// + /// Manages jewelry (pendant and rings) element resistance (fire, poison, ice, etc.) base power up attributes. + /// + /// The context item being (un)equipped. + /// true if the item is being unequipped; false if it is being equipped. + /// true if the jewelry item's base power up should be skipped (on item equip); false otherwise. + /// All jewelry base power up attributes are comprised of one single element resistance. Only the highest resistance value applies (no stacking). + private bool HandleJewelryBasePowerUps(Item item, bool onItemUnequip = false) + { + var baseAttribute = item.Definition!.BasePowerUpAttributes.FirstOrDefault()?.TargetAttribute; + if (baseAttribute is null) // Ring of Magic and Pendant of Ability have no base attributes + { + return true; + } + + var attributes = this._player.Attributes; + var jewelrySharingAttribute = this.EquippedItems + .Where(eqItem => eqItem.IsJewelry() && eqItem != item && eqItem.Definition!.BasePowerUpAttributes.FirstOrDefault()?.TargetAttribute == baseAttribute); + var highestItem = jewelrySharingAttribute.MaxBy(jsa => jsa.Level); + + if (onItemUnequip) + { + if (highestItem is not null && attributes!.ItemPowerUps[item].Any(powerUp => powerUp.ParentAttribute!.Definition == baseAttribute)) + { // Unequipped item had the resistance base power up active => load the new highest jewelry item's + var factory = this._gameContext.ItemPowerUpFactory; + attributes!.ItemPowerUps[highestItem] = attributes!.ItemPowerUps[highestItem].Concat(factory.GetPowerUps(highestItem, attributes, false, true).ToList()).ToList(); + } + } + else if (attributes!.GetComposableAttribute(baseAttribute!) is ComposableAttribute compAttr) + { + if (item.Level < highestItem?.Level || (item.Level == highestItem?.Level && compAttr.Elements.Any())) + { // There is a ring or pendant with higher or equal resistance/level + return true; + } + + if (item.Level > highestItem?.Level) + { // Equipped item has highest resistance + // Remove all existing elements under the resistance composable attribute + while (compAttr.Elements.Any()) + { + compAttr.RemoveElement(compAttr.Elements.Last()); + } + + // Remove active resistance base power up for previous highest jewelry item + foreach (var jewelryItem in jewelrySharingAttribute) + { + if (attributes!.ItemPowerUps.TryGetValue(jewelryItem, out IReadOnlyList? powerUps) && powerUps.Any(pu => pu.ParentAttribute!.Definition == baseAttribute)) + { + attributes!.ItemPowerUps[jewelryItem] = powerUps.Where(pu => pu.ParentAttribute!.Definition != baseAttribute).ToList(); + break; + } + } + } + } + + return false; + } } \ No newline at end of file diff --git a/src/GameLogic/ItemExtensions.cs b/src/GameLogic/ItemExtensions.cs index a8cbb23bd..6a6f63441 100644 --- a/src/GameLogic/ItemExtensions.cs +++ b/src/GameLogic/ItemExtensions.cs @@ -124,13 +124,25 @@ public static bool IsShield(this Item item) return item.Definition?.Group == ShieldItemGroup; } + /// + /// Determines whether this item is a jewelry (pendant or ring) item. + /// + /// The item. + /// + /// true if the specified item is jewelry; otherwise, false. + /// + public static bool IsJewelry(this Item item) + { + return item.ItemSlot >= InventoryConstants.PendantSlot && item.ItemSlot <= InventoryConstants.Ring2Slot; + } + /// /// Determines whether this instance is a is weapon which deals physical damage. /// /// The item. /// The minimum physical damage of the weapon. /// - /// true if this instance is a is weapon which deals physical damage; otherwise, false. + /// true if this instance is a weapon which deals physical damage; otherwise, false. /// public static bool IsPhysicalWeapon(this Item item, [NotNullWhen(true)] out float? minimumDmg) { @@ -144,7 +156,7 @@ public static bool IsPhysicalWeapon(this Item item, [NotNullWhen(true)] out floa /// The item. /// The staff rise percentage of the weapon. /// - /// true if this instance is a is weapon which deals wizardry damage; otherwise, false. + /// true if this instance is a weapon which deals wizardry damage; otherwise, false. /// public static bool IsWizardryWeapon(this Item item, [NotNullWhen(true)] out float? staffRise) { diff --git a/src/GameLogic/ItemPowerUpFactory.cs b/src/GameLogic/ItemPowerUpFactory.cs index 63af2ff0a..22317da10 100644 --- a/src/GameLogic/ItemPowerUpFactory.cs +++ b/src/GameLogic/ItemPowerUpFactory.cs @@ -27,7 +27,7 @@ public ItemPowerUpFactory(ILogger logger) } /// - public IEnumerable GetPowerUps(Item item, AttributeSystem attributeHolder) + public IEnumerable GetPowerUps(Item item, AttributeSystem attributeHolder, bool skipBasePowerUps = false, bool skipOptionPowerUps = false) { if (item.Definition is null) { @@ -45,17 +45,23 @@ public IEnumerable GetPowerUps(Item item, AttributeSystem attrib yield break; } - foreach (var attribute in item.Definition.BasePowerUpAttributes) + if (!skipBasePowerUps) { - foreach (var powerUp in this.GetBasePowerUpWrappers(item, attributeHolder, attribute)) + foreach (var attribute in item.Definition.BasePowerUpAttributes) { - yield return powerUp; + foreach (var powerUp in this.GetBasePowerUpWrappers(item, attributeHolder, attribute)) + { + yield return powerUp; + } } } - foreach (var powerUp in this.GetPowerUpsOfItemOptions(item, attributeHolder)) + if (!skipOptionPowerUps) { - yield return powerUp; + foreach (var powerUp in this.GetPowerUpsOfItemOptions(item, attributeHolder)) + { + yield return powerUp; + } } if (this.GetPetLevel(item, attributeHolder) is { } petLevel) @@ -253,7 +259,7 @@ private IEnumerable CreateExcellentAndAncientBasePowerUpWrappers var baseDropLevel = item.Definition!.DropLevel; var ancientDropLevel = item.Definition!.CalculateDropLevel(true, false, 0); - if (InventoryConstants.IsDefenseItemSlot(item.ItemSlot)) + if (InventoryConstants.IsDefenseItemSlot(item.ItemSlot) && !item.IsJewelry()) { var baseDefense = (int)(item.Definition?.BasePowerUpAttributes.FirstOrDefault(a => a.TargetAttribute == Stats.DefenseBase)?.BaseValue ?? 0); var additionalDefense = (baseDefense * 12 / baseDropLevel) + (baseDropLevel / 5) + 4; diff --git a/src/Persistence/Initialization/Items/OptionExtensions.cs b/src/Persistence/Initialization/Items/OptionExtensions.cs index 7ff273a35..651cd89ce 100644 --- a/src/Persistence/Initialization/Items/OptionExtensions.cs +++ b/src/Persistence/Initialization/Items/OptionExtensions.cs @@ -80,6 +80,6 @@ public static ItemOptionDefinition ExcellentPhysicalAttackOptions(this GameConfi /// The excellent wizardry attack options. public static ItemOptionDefinition ExcellentWizardryAttackOptions(this GameConfiguration gameConfiguration) { - return gameConfiguration.ItemOptions.First(o => o.Name == ExcellentOptions.PhysicalAttackOptionsName); + return gameConfiguration.ItemOptions.First(o => o.Name == ExcellentOptions.WizardryAttackOptionsName); } } \ No newline at end of file diff --git a/src/Persistence/Initialization/Version075/Items/Jewelery.cs b/src/Persistence/Initialization/Version075/Items/Jewelery.cs index 407d6db53..1cf4827d3 100644 --- a/src/Persistence/Initialization/Version075/Items/Jewelery.cs +++ b/src/Persistence/Initialization/Version075/Items/Jewelery.cs @@ -5,7 +5,6 @@ namespace MUnique.OpenMU.Persistence.Initialization.Version075.Items; using MUnique.OpenMU.AttributeSystem; -using MUnique.OpenMU.DataModel.Attributes; using MUnique.OpenMU.DataModel.Configuration; using MUnique.OpenMU.DataModel.Configuration.Items; using MUnique.OpenMU.GameLogic.Attributes; @@ -29,6 +28,9 @@ public Jewelery(IContext context, GameConfiguration gameConfiguration) { } + /// + protected override int MaximumOptionLevel => 3; + /// public sealed override void Initialize() { @@ -164,6 +166,7 @@ protected ItemDefinition CreateJewelery(byte number, int slot, bool dropsFromMon { var powerUp = this.CreateItemBasePowerUpDefinition(resistanceAttribute, 0.1f, AggregateType.AddRaw); powerUp.BonusPerLevelTable = this._resistancesBonusTable; + item.BasePowerUpAttributes.Add(powerUp); } foreach (var characterClass in this.GameConfiguration.CharacterClasses) From cb74c9e369c838b6cc28270068f66b31824dbc2b Mon Sep 17 00:00:00 2001 From: ze-dom Date: Tue, 24 Sep 2024 14:14:55 +0100 Subject: [PATCH 02/12] Added else clause --- src/GameLogic/InventoryStorage.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/GameLogic/InventoryStorage.cs b/src/GameLogic/InventoryStorage.cs index 9b5a1c6fb..8444d5c94 100644 --- a/src/GameLogic/InventoryStorage.cs +++ b/src/GameLogic/InventoryStorage.cs @@ -296,6 +296,10 @@ private bool HandleJewelryBasePowerUps(Item item, bool onItemUnequip = false) } } } + else + { + // Continue + } return false; } From cd0eecd123a06847fb2bc1af63299f7fbf98f0b8 Mon Sep 17 00:00:00 2001 From: ze-dom Date: Fri, 27 Sep 2024 10:40:15 +0100 Subject: [PATCH 03/12] WIP --- src/AttributeSystem/AggregateType.cs | 5 + src/AttributeSystem/ComposableAttribute.cs | 3 +- src/GameLogic/Attributes/PowerUpWrapper.cs | 16 ++ src/GameLogic/Attributes/Stats.cs | 14 +- src/GameLogic/InventoryStorage.cs | 142 +++++++++--------- src/GameLogic/ItemPowerUpFactory.cs | 21 ++- .../Version075/Items/Jewelery.cs | 2 +- 7 files changed, 119 insertions(+), 84 deletions(-) diff --git a/src/AttributeSystem/AggregateType.cs b/src/AttributeSystem/AggregateType.cs index 6f5a6fa8c..57f277092 100644 --- a/src/AttributeSystem/AggregateType.cs +++ b/src/AttributeSystem/AggregateType.cs @@ -23,4 +23,9 @@ public enum AggregateType /// Adds the value to the final value. /// AddFinal, + + /// + /// Only the highest available value from all items takes effect (jewelry element resistance). + /// + Maximum, } \ No newline at end of file diff --git a/src/AttributeSystem/ComposableAttribute.cs b/src/AttributeSystem/ComposableAttribute.cs index 4423689e1..bdab604fa 100644 --- a/src/AttributeSystem/ComposableAttribute.cs +++ b/src/AttributeSystem/ComposableAttribute.cs @@ -61,6 +61,7 @@ private float GetAndCacheValue() var rawValues = this.Elements.Where(e => e.AggregateType == AggregateType.AddRaw).Sum(e => e.Value); var multiValues = this.Elements.Where(e => e.AggregateType == AggregateType.Multiplicate).Select(e => e.Value).Concat(Enumerable.Repeat(1.0F, 1)).Aggregate((a, b) => a * b); var finalValues = this.Elements.Where(e => e.AggregateType == AggregateType.AddFinal).Sum(e => e.Value); + var maxValues = this.Elements.Where(e => e.AggregateType == AggregateType.Maximum).MaxBy(e => e.Value)?.Value ?? 0; if (multiValues == 0 && this.Elements.All(e => e.AggregateType != AggregateType.Multiplicate)) { @@ -75,7 +76,7 @@ private float GetAndCacheValue() // nothing to do } - this._cachedValue = (rawValues * multiValues + finalValues); + this._cachedValue = (rawValues * multiValues) + maxValues + finalValues; return this._cachedValue.Value; } diff --git a/src/GameLogic/Attributes/PowerUpWrapper.cs b/src/GameLogic/Attributes/PowerUpWrapper.cs index d409002ad..116c78eab 100644 --- a/src/GameLogic/Attributes/PowerUpWrapper.cs +++ b/src/GameLogic/Attributes/PowerUpWrapper.cs @@ -31,6 +31,22 @@ public PowerUpWrapper(IElement element, AttributeDefinition targetAttribute, Att } this._element = element; + // if (element.AggregateType == AggregateType.Maximum && this._parentAttribute.Elements.Any()) + // { + // foreach (var parentElmt in this._parentAttribute.Elements) + // { + // if (parentElmt.AggregateType == AggregateType.Maximum && element.Value > parentElmt.Value) + // { // Only one element with AggregateType.Maximum should exist + // this._parentAttribute.RemoveElement(parentElmt); + // this._parentAttribute.AddElement(element); + // break; + // } + // } + // } + // else + // { + // this._parentAttribute.AddElement(this); + // } this._parentAttribute.AddElement(this); this._element.ValueChanged += this.OnValueChanged; } diff --git a/src/GameLogic/Attributes/Stats.cs b/src/GameLogic/Attributes/Stats.cs index f51b4ea28..6a28bbf6f 100644 --- a/src/GameLogic/Attributes/Stats.cs +++ b/src/GameLogic/Attributes/Stats.cs @@ -553,37 +553,37 @@ public class Stats public static AttributeDefinition IsStunned { get; } = new (new Guid("22C86BAF-7F27-478D-8075-E4465C2859DD"), "Is stunned", "The player is poisoned and loses health"); /// - /// Gets the ice resistance attribute definition. Value range from 0 to 0.5. + /// Gets the ice resistance attribute definition. Value range from 0 to 1. /// public static AttributeDefinition IceResistance { get; } = new (new Guid("47235C36-41BB-44B4-8823-6FC415709F59"), "Ice Resistance", string.Empty); /// - /// Gets the fire resistance attribute definition. Value range from 0 to 0.5. + /// Gets the fire resistance attribute definition. Value range from 0 to 1. /// public static AttributeDefinition FireResistance { get; } = new (new Guid("9AE4D80D-5706-48B9-AD11-EAC4FE088A81"), "Fire Resistance", string.Empty); /// - /// Gets the water resistance attribute definition. Value range from 0 to 0.5. + /// Gets the water resistance attribute definition. Value range from 0 to 1. /// public static AttributeDefinition WaterResistance { get; } = new (new Guid("3AF88672-D8DB-44E1-937A-7E6484134C39"), "Water Resistance", string.Empty); /// - /// Gets the earth resistance attribute definition. Value range from 0 to 0.5. + /// Gets the earth resistance attribute definition. Value range from 0 to 1. /// public static AttributeDefinition EarthResistance { get; } = new (new Guid("4470890F-00CE-44A6-BADB-203684B6014D"), "Earth Resistance", string.Empty); /// - /// Gets the wind resistance attribute definition. Value range from 0 to 0.5. + /// Gets the wind resistance attribute definition. Value range from 0 to 1. /// public static AttributeDefinition WindResistance { get; } = new (new Guid("03A29C46-7B7E-424D-8325-8390692570C3"), "Wind Resistance", string.Empty); /// - /// Gets the poison resistance attribute definition. Value range from 0 to 0.5. + /// Gets the poison resistance attribute definition. Value range from 0 to 1. /// public static AttributeDefinition PoisonResistance { get; } = new (new Guid("3D50D0B7-63A2-4DA9-8855-12173EAE6B39"), "Poison Resistance", string.Empty); /// - /// Gets the lightning resistance attribute definition. Value range from 0 to 0.5. + /// Gets the lightning resistance attribute definition. Value range from 0 to 1. /// public static AttributeDefinition LightningResistance { get; } = new (new Guid("3E339393-2D17-452E-81D9-3987947A407F"), "Lightning Resistance", string.Empty); diff --git a/src/GameLogic/InventoryStorage.cs b/src/GameLogic/InventoryStorage.cs index 8444d5c94..ec6a3b6ac 100644 --- a/src/GameLogic/InventoryStorage.cs +++ b/src/GameLogic/InventoryStorage.cs @@ -148,14 +148,14 @@ await this._player.ForEachWorldObserverAsync( var attributes = this._player.Attributes; var factory = this._gameContext.ItemPowerUpFactory; - bool itemIsJewelry = item.IsJewelry(); + // bool itemIsJewelry = item.IsJewelry(); if (attributes.ItemPowerUps.TryGetValue(item, out var itemPowerUps)) { - if (itemIsJewelry) - { // Run this before remmoving power ups - this.HandleJewelryBasePowerUps(item, true); - } + // if (itemIsJewelry) + // { // Run this before remmoving power ups + // this.HandleJewelryBasePowerUps(item, true); + // } attributes.ItemPowerUps.Remove(item); @@ -173,13 +173,13 @@ await this._player.ForEachWorldObserverAsync( var itemAdded = this.EquippedItems.Contains(item); if (itemAdded) { - bool skipBasePowerUps = false; - if (itemIsJewelry) - { - skipBasePowerUps = this.HandleJewelryBasePowerUps(item); - } + // bool skipBasePowerUps = false; + // if (itemIsJewelry) + // { + // skipBasePowerUps = this.HandleJewelryBasePowerUps(item); + // } - attributes.ItemPowerUps.Add(item, factory.GetPowerUps(item, attributes, skipBasePowerUps, false).ToList()); + attributes.ItemPowerUps.Add(item, factory.GetPowerUps(item, attributes/*, skipBasePowerUps, false*/).ToList()); // reset player equipped ammunition amount if (this.EquippedAmmunitionItem is { } ammoItem) @@ -206,13 +206,13 @@ private void InitializePowerUps() { foreach (var item in this.EquippedItems) { - bool skipBasePowerUps = false; - if (item.IsJewelry()) - { - skipBasePowerUps = this.HandleJewelryBasePowerUps(item); - } + // bool skipBasePowerUps = false; + // if (item.IsJewelry()) + // { + // skipBasePowerUps = this.HandleJewelryBasePowerUps(item); + // } - this._player.Attributes.ItemPowerUps.Add(item, factory.GetPowerUps(item, this._player.Attributes, skipBasePowerUps, false).ToList()); + this._player.Attributes.ItemPowerUps.Add(item, factory.GetPowerUps(item, this._player.Attributes/*, skipBasePowerUps, false*/).ToList()); } this.UpdateSetPowerUps(); @@ -249,58 +249,58 @@ private void UpdateSetPowerUps() /// true if the item is being unequipped; false if it is being equipped. /// true if the jewelry item's base power up should be skipped (on item equip); false otherwise. /// All jewelry base power up attributes are comprised of one single element resistance. Only the highest resistance value applies (no stacking). - private bool HandleJewelryBasePowerUps(Item item, bool onItemUnequip = false) - { - var baseAttribute = item.Definition!.BasePowerUpAttributes.FirstOrDefault()?.TargetAttribute; - if (baseAttribute is null) // Ring of Magic and Pendant of Ability have no base attributes - { - return true; - } - - var attributes = this._player.Attributes; - var jewelrySharingAttribute = this.EquippedItems - .Where(eqItem => eqItem.IsJewelry() && eqItem != item && eqItem.Definition!.BasePowerUpAttributes.FirstOrDefault()?.TargetAttribute == baseAttribute); - var highestItem = jewelrySharingAttribute.MaxBy(jsa => jsa.Level); - - if (onItemUnequip) - { - if (highestItem is not null && attributes!.ItemPowerUps[item].Any(powerUp => powerUp.ParentAttribute!.Definition == baseAttribute)) - { // Unequipped item had the resistance base power up active => load the new highest jewelry item's - var factory = this._gameContext.ItemPowerUpFactory; - attributes!.ItemPowerUps[highestItem] = attributes!.ItemPowerUps[highestItem].Concat(factory.GetPowerUps(highestItem, attributes, false, true).ToList()).ToList(); - } - } - else if (attributes!.GetComposableAttribute(baseAttribute!) is ComposableAttribute compAttr) - { - if (item.Level < highestItem?.Level || (item.Level == highestItem?.Level && compAttr.Elements.Any())) - { // There is a ring or pendant with higher or equal resistance/level - return true; - } - - if (item.Level > highestItem?.Level) - { // Equipped item has highest resistance - // Remove all existing elements under the resistance composable attribute - while (compAttr.Elements.Any()) - { - compAttr.RemoveElement(compAttr.Elements.Last()); - } - - // Remove active resistance base power up for previous highest jewelry item - foreach (var jewelryItem in jewelrySharingAttribute) - { - if (attributes!.ItemPowerUps.TryGetValue(jewelryItem, out IReadOnlyList? powerUps) && powerUps.Any(pu => pu.ParentAttribute!.Definition == baseAttribute)) - { - attributes!.ItemPowerUps[jewelryItem] = powerUps.Where(pu => pu.ParentAttribute!.Definition != baseAttribute).ToList(); - break; - } - } - } - } - else - { - // Continue - } - - return false; - } + // private bool HandleJewelryBasePowerUps(Item item, bool onItemUnequip = false) + // { + // var baseAttribute = item.Definition!.BasePowerUpAttributes.FirstOrDefault()?.TargetAttribute; + // if (baseAttribute is null) // Ring of Magic and Pendant of Ability have no base attributes + // { + // return true; + // } + + // var attributes = this._player.Attributes; + // var jewelrySharingAttribute = this.EquippedItems + // .Where(eqItem => eqItem.IsJewelry() && eqItem != item && eqItem.Definition!.BasePowerUpAttributes.FirstOrDefault()?.TargetAttribute == baseAttribute); + // var highestItem = jewelrySharingAttribute.MaxBy(jsa => jsa.Level); + + // if (onItemUnequip) + // { + // if (highestItem is not null && attributes!.ItemPowerUps[item].Any(powerUp => powerUp.ParentAttribute!.Definition == baseAttribute)) + // { // Unequipped item had the resistance base power up active => load the new highest jewelry item's + // var factory = this._gameContext.ItemPowerUpFactory; + // attributes!.ItemPowerUps[highestItem] = attributes!.ItemPowerUps[highestItem].Concat(factory.GetPowerUps(highestItem, attributes, false, true).ToList()).ToList(); + // } + // } + // else if (attributes!.GetComposableAttribute(baseAttribute!) is ComposableAttribute compAttr) + // { + // if (item.Level < highestItem?.Level || (item.Level == highestItem?.Level && compAttr.Elements.Any())) + // { // There is a ring or pendant with higher or equal resistance/level + // return true; + // } + + // if (item.Level > highestItem?.Level) + // { // Equipped item has highest resistance + // // Remove all existing elements under the resistance composable attribute + // while (compAttr.Elements.Any()) + // { + // compAttr.RemoveElement(compAttr.Elements.Last()); + // } + + // // Remove active resistance base power up for previous highest jewelry item + // foreach (var jewelryItem in jewelrySharingAttribute) + // { + // if (attributes!.ItemPowerUps.TryGetValue(jewelryItem, out IReadOnlyList? powerUps) && powerUps.Any(pu => pu.ParentAttribute!.Definition == baseAttribute)) + // { + // attributes!.ItemPowerUps[jewelryItem] = powerUps.Where(pu => pu.ParentAttribute!.Definition != baseAttribute).ToList(); + // break; + // } + // } + // } + // } + // else + // { + // // Continue + // } + + // return false; + // } } \ No newline at end of file diff --git a/src/GameLogic/ItemPowerUpFactory.cs b/src/GameLogic/ItemPowerUpFactory.cs index 22317da10..966cc5cc7 100644 --- a/src/GameLogic/ItemPowerUpFactory.cs +++ b/src/GameLogic/ItemPowerUpFactory.cs @@ -190,12 +190,25 @@ private IEnumerable GetBasePowerUpWrappers(Item item, AttributeS attribute.ThrowNotInitializedProperty(attribute.BaseValueElement is null, nameof(attribute.BaseValueElement)); attribute.ThrowNotInitializedProperty(attribute.TargetAttribute is null, nameof(attribute.TargetAttribute)); - yield return new PowerUpWrapper(attribute.BaseValueElement, attribute.TargetAttribute, attributeHolder); + var levelBonusElmt = (attribute.BonusPerLevelTable?.BonusPerLevel ?? Enumerable.Empty()) + .FirstOrDefault(bonus => bonus.Level == item.Level)? + .GetAdditionalValueElement(attribute.AggregateType); - var levelBonus = (attribute.BonusPerLevelTable?.BonusPerLevel ?? Enumerable.Empty()).FirstOrDefault(bonus => bonus.Level == item.Level); - if (levelBonus is not null) + if (item.IsJewelry() && levelBonusElmt is not null) { - yield return new PowerUpWrapper(levelBonus.GetAdditionalValueElement(attribute.AggregateType), attribute.TargetAttribute, attributeHolder); + yield return new PowerUpWrapper( + new CombinedElement(attribute.BaseValueElement, levelBonusElmt), + attribute.TargetAttribute, + attributeHolder); + } + else + { + yield return new PowerUpWrapper(attribute.BaseValueElement, attribute.TargetAttribute, attributeHolder); + + if (levelBonusElmt is not null) + { + yield return new PowerUpWrapper(levelBonusElmt, attribute.TargetAttribute, attributeHolder); + } } } diff --git a/src/Persistence/Initialization/Version075/Items/Jewelery.cs b/src/Persistence/Initialization/Version075/Items/Jewelery.cs index 1cf4827d3..60b584ea0 100644 --- a/src/Persistence/Initialization/Version075/Items/Jewelery.cs +++ b/src/Persistence/Initialization/Version075/Items/Jewelery.cs @@ -164,7 +164,7 @@ protected ItemDefinition CreateJewelery(byte number, int slot, bool dropsFromMon if (resistanceAttribute != null) { - var powerUp = this.CreateItemBasePowerUpDefinition(resistanceAttribute, 0.1f, AggregateType.AddRaw); + var powerUp = this.CreateItemBasePowerUpDefinition(resistanceAttribute, 0.1f, AggregateType.Maximum); powerUp.BonusPerLevelTable = this._resistancesBonusTable; item.BasePowerUpAttributes.Add(powerUp); } From 6500e56bd30b785b5dc64a95efa90ec6b96b149f Mon Sep 17 00:00:00 2001 From: ze-dom Date: Fri, 27 Sep 2024 16:02:46 +0100 Subject: [PATCH 04/12] Reverted previous changes --- src/AttributeSystem/ComposableAttribute.cs | 3 +- src/GameLogic/Attributes/PowerUpWrapper.cs | 16 ---- src/GameLogic/IItemPowerUpFactory.cs | 4 +- src/GameLogic/InventoryStorage.cs | 93 ++-------------------- src/GameLogic/ItemPowerUpFactory.cs | 18 ++--- 5 files changed, 14 insertions(+), 120 deletions(-) diff --git a/src/AttributeSystem/ComposableAttribute.cs b/src/AttributeSystem/ComposableAttribute.cs index bdab604fa..b8907c5c0 100644 --- a/src/AttributeSystem/ComposableAttribute.cs +++ b/src/AttributeSystem/ComposableAttribute.cs @@ -62,6 +62,7 @@ private float GetAndCacheValue() var multiValues = this.Elements.Where(e => e.AggregateType == AggregateType.Multiplicate).Select(e => e.Value).Concat(Enumerable.Repeat(1.0F, 1)).Aggregate((a, b) => a * b); var finalValues = this.Elements.Where(e => e.AggregateType == AggregateType.AddFinal).Sum(e => e.Value); var maxValues = this.Elements.Where(e => e.AggregateType == AggregateType.Maximum).MaxBy(e => e.Value)?.Value ?? 0; + rawValues += maxValues; if (multiValues == 0 && this.Elements.All(e => e.AggregateType != AggregateType.Multiplicate)) { @@ -76,7 +77,7 @@ private float GetAndCacheValue() // nothing to do } - this._cachedValue = (rawValues * multiValues) + maxValues + finalValues; + this._cachedValue = (rawValues * multiValues) + finalValues; return this._cachedValue.Value; } diff --git a/src/GameLogic/Attributes/PowerUpWrapper.cs b/src/GameLogic/Attributes/PowerUpWrapper.cs index 116c78eab..d409002ad 100644 --- a/src/GameLogic/Attributes/PowerUpWrapper.cs +++ b/src/GameLogic/Attributes/PowerUpWrapper.cs @@ -31,22 +31,6 @@ public PowerUpWrapper(IElement element, AttributeDefinition targetAttribute, Att } this._element = element; - // if (element.AggregateType == AggregateType.Maximum && this._parentAttribute.Elements.Any()) - // { - // foreach (var parentElmt in this._parentAttribute.Elements) - // { - // if (parentElmt.AggregateType == AggregateType.Maximum && element.Value > parentElmt.Value) - // { // Only one element with AggregateType.Maximum should exist - // this._parentAttribute.RemoveElement(parentElmt); - // this._parentAttribute.AddElement(element); - // break; - // } - // } - // } - // else - // { - // this._parentAttribute.AddElement(this); - // } this._parentAttribute.AddElement(this); this._element.ValueChanged += this.OnValueChanged; } diff --git a/src/GameLogic/IItemPowerUpFactory.cs b/src/GameLogic/IItemPowerUpFactory.cs index a73f59b30..f5ee5e07e 100644 --- a/src/GameLogic/IItemPowerUpFactory.cs +++ b/src/GameLogic/IItemPowerUpFactory.cs @@ -19,10 +19,8 @@ public interface IItemPowerUpFactory /// /// The item. /// The attribute system of the player who equipped the item. - /// If only the item base power ups should be built. - /// If only the item option power ups should be built. /// The created power ups. - IEnumerable GetPowerUps(Item item, AttributeSystem attributeSystem, bool skipBasePowerUps = false, bool skipOptionPowerUps = false); + IEnumerable GetPowerUps(Item item, AttributeSystem attributeSystem); /// /// Gets the set power ups, which are created for existing s in the equipped items. diff --git a/src/GameLogic/InventoryStorage.cs b/src/GameLogic/InventoryStorage.cs index ec6a3b6ac..451f34f3c 100644 --- a/src/GameLogic/InventoryStorage.cs +++ b/src/GameLogic/InventoryStorage.cs @@ -146,18 +146,9 @@ await this._player.ForEachWorldObserverAsync( return; } - var attributes = this._player.Attributes; - var factory = this._gameContext.ItemPowerUpFactory; - // bool itemIsJewelry = item.IsJewelry(); - - if (attributes.ItemPowerUps.TryGetValue(item, out var itemPowerUps)) + if (this._player.Attributes.ItemPowerUps.TryGetValue(item, out var itemPowerUps)) { - // if (itemIsJewelry) - // { // Run this before remmoving power ups - // this.HandleJewelryBasePowerUps(item, true); - // } - - attributes.ItemPowerUps.Remove(item); + this._player.Attributes.ItemPowerUps.Remove(item); foreach (var powerUp in itemPowerUps) { @@ -173,18 +164,12 @@ await this._player.ForEachWorldObserverAsync( var itemAdded = this.EquippedItems.Contains(item); if (itemAdded) { - // bool skipBasePowerUps = false; - // if (itemIsJewelry) - // { - // skipBasePowerUps = this.HandleJewelryBasePowerUps(item); - // } - - attributes.ItemPowerUps.Add(item, factory.GetPowerUps(item, attributes/*, skipBasePowerUps, false*/).ToList()); + this._player.Attributes.ItemPowerUps.Add(item, this._gameContext.ItemPowerUpFactory.GetPowerUps(item, this._player.Attributes).ToList()); // reset player equipped ammunition amount if (this.EquippedAmmunitionItem is { } ammoItem) { - attributes[Stats.AmmunitionAmount] = (float)ammoItem.Durability; + this._player.Attributes[Stats.AmmunitionAmount] = (float)ammoItem.Durability; } } } @@ -206,13 +191,7 @@ private void InitializePowerUps() { foreach (var item in this.EquippedItems) { - // bool skipBasePowerUps = false; - // if (item.IsJewelry()) - // { - // skipBasePowerUps = this.HandleJewelryBasePowerUps(item); - // } - - this._player.Attributes.ItemPowerUps.Add(item, factory.GetPowerUps(item, this._player.Attributes/*, skipBasePowerUps, false*/).ToList()); + this._player.Attributes.ItemPowerUps.Add(item, factory.GetPowerUps(item, this._player.Attributes).ToList()); } this.UpdateSetPowerUps(); @@ -241,66 +220,4 @@ private void UpdateSetPowerUps() var factory = this._gameContext.ItemPowerUpFactory; this._player.Attributes.ItemSetPowerUps = factory.GetSetPowerUps(this.EquippedItems, this._player.Attributes, this._player.GameContext.Configuration).ToList(); } - - /// - /// Manages jewelry (pendant and rings) element resistance (fire, poison, ice, etc.) base power up attributes. - /// - /// The context item being (un)equipped. - /// true if the item is being unequipped; false if it is being equipped. - /// true if the jewelry item's base power up should be skipped (on item equip); false otherwise. - /// All jewelry base power up attributes are comprised of one single element resistance. Only the highest resistance value applies (no stacking). - // private bool HandleJewelryBasePowerUps(Item item, bool onItemUnequip = false) - // { - // var baseAttribute = item.Definition!.BasePowerUpAttributes.FirstOrDefault()?.TargetAttribute; - // if (baseAttribute is null) // Ring of Magic and Pendant of Ability have no base attributes - // { - // return true; - // } - - // var attributes = this._player.Attributes; - // var jewelrySharingAttribute = this.EquippedItems - // .Where(eqItem => eqItem.IsJewelry() && eqItem != item && eqItem.Definition!.BasePowerUpAttributes.FirstOrDefault()?.TargetAttribute == baseAttribute); - // var highestItem = jewelrySharingAttribute.MaxBy(jsa => jsa.Level); - - // if (onItemUnequip) - // { - // if (highestItem is not null && attributes!.ItemPowerUps[item].Any(powerUp => powerUp.ParentAttribute!.Definition == baseAttribute)) - // { // Unequipped item had the resistance base power up active => load the new highest jewelry item's - // var factory = this._gameContext.ItemPowerUpFactory; - // attributes!.ItemPowerUps[highestItem] = attributes!.ItemPowerUps[highestItem].Concat(factory.GetPowerUps(highestItem, attributes, false, true).ToList()).ToList(); - // } - // } - // else if (attributes!.GetComposableAttribute(baseAttribute!) is ComposableAttribute compAttr) - // { - // if (item.Level < highestItem?.Level || (item.Level == highestItem?.Level && compAttr.Elements.Any())) - // { // There is a ring or pendant with higher or equal resistance/level - // return true; - // } - - // if (item.Level > highestItem?.Level) - // { // Equipped item has highest resistance - // // Remove all existing elements under the resistance composable attribute - // while (compAttr.Elements.Any()) - // { - // compAttr.RemoveElement(compAttr.Elements.Last()); - // } - - // // Remove active resistance base power up for previous highest jewelry item - // foreach (var jewelryItem in jewelrySharingAttribute) - // { - // if (attributes!.ItemPowerUps.TryGetValue(jewelryItem, out IReadOnlyList? powerUps) && powerUps.Any(pu => pu.ParentAttribute!.Definition == baseAttribute)) - // { - // attributes!.ItemPowerUps[jewelryItem] = powerUps.Where(pu => pu.ParentAttribute!.Definition != baseAttribute).ToList(); - // break; - // } - // } - // } - // } - // else - // { - // // Continue - // } - - // return false; - // } } \ No newline at end of file diff --git a/src/GameLogic/ItemPowerUpFactory.cs b/src/GameLogic/ItemPowerUpFactory.cs index 966cc5cc7..832f9d253 100644 --- a/src/GameLogic/ItemPowerUpFactory.cs +++ b/src/GameLogic/ItemPowerUpFactory.cs @@ -27,7 +27,7 @@ public ItemPowerUpFactory(ILogger logger) } /// - public IEnumerable GetPowerUps(Item item, AttributeSystem attributeHolder, bool skipBasePowerUps = false, bool skipOptionPowerUps = false) + public IEnumerable GetPowerUps(Item item, AttributeSystem attributeHolder) { if (item.Definition is null) { @@ -45,23 +45,17 @@ public IEnumerable GetPowerUps(Item item, AttributeSystem attrib yield break; } - if (!skipBasePowerUps) + foreach (var attribute in item.Definition.BasePowerUpAttributes) { - foreach (var attribute in item.Definition.BasePowerUpAttributes) + foreach (var powerUp in this.GetBasePowerUpWrappers(item, attributeHolder, attribute)) { - foreach (var powerUp in this.GetBasePowerUpWrappers(item, attributeHolder, attribute)) - { - yield return powerUp; - } + yield return powerUp; } } - if (!skipOptionPowerUps) + foreach (var powerUp in this.GetPowerUpsOfItemOptions(item, attributeHolder)) { - foreach (var powerUp in this.GetPowerUpsOfItemOptions(item, attributeHolder)) - { - yield return powerUp; - } + yield return powerUp; } if (this.GetPetLevel(item, attributeHolder) is { } petLevel) From 52a7fa992a4bcd4c0a5f5acaddc11ad8e539431b Mon Sep 17 00:00:00 2001 From: ze-dom Date: Fri, 27 Sep 2024 16:06:19 +0100 Subject: [PATCH 05/12] Reverted more unneeded changes --- src/GameLogic/Attributes/PowerUpWrapper.cs | 5 ----- src/GameLogic/InventoryStorage.cs | 1 - 2 files changed, 6 deletions(-) diff --git a/src/GameLogic/Attributes/PowerUpWrapper.cs b/src/GameLogic/Attributes/PowerUpWrapper.cs index d409002ad..7e50e2b93 100644 --- a/src/GameLogic/Attributes/PowerUpWrapper.cs +++ b/src/GameLogic/Attributes/PowerUpWrapper.cs @@ -44,11 +44,6 @@ public PowerUpWrapper(IElement element, AttributeDefinition targetAttribute, Att /// public AggregateType AggregateType => this._element.AggregateType; - /// - /// Gets the parent attribute. - /// - public ComposableAttribute? ParentAttribute => this._parentAttribute; - /// /// Creates elements by a . /// diff --git a/src/GameLogic/InventoryStorage.cs b/src/GameLogic/InventoryStorage.cs index 451f34f3c..53c035c34 100644 --- a/src/GameLogic/InventoryStorage.cs +++ b/src/GameLogic/InventoryStorage.cs @@ -4,7 +4,6 @@ namespace MUnique.OpenMU.GameLogic; -using MUnique.OpenMU.AttributeSystem; using MUnique.OpenMU.DataModel; using MUnique.OpenMU.GameLogic.Attributes; using MUnique.OpenMU.GameLogic.Views.World; From cff8606781745ab60921edfe35d1df08bc51c745 Mon Sep 17 00:00:00 2001 From: ze-dom Date: Fri, 27 Sep 2024 16:16:34 +0100 Subject: [PATCH 06/12] Reverted more unneeded changes, added code comment --- src/GameLogic/InventoryStorage.cs | 4 ++-- src/GameLogic/ItemPowerUpFactory.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/GameLogic/InventoryStorage.cs b/src/GameLogic/InventoryStorage.cs index 53c035c34..12fb47c2d 100644 --- a/src/GameLogic/InventoryStorage.cs +++ b/src/GameLogic/InventoryStorage.cs @@ -148,7 +148,6 @@ await this._player.ForEachWorldObserverAsync( if (this._player.Attributes.ItemPowerUps.TryGetValue(item, out var itemPowerUps)) { this._player.Attributes.ItemPowerUps.Remove(item); - foreach (var powerUp in itemPowerUps) { powerUp.Dispose(); @@ -163,7 +162,8 @@ await this._player.ForEachWorldObserverAsync( var itemAdded = this.EquippedItems.Contains(item); if (itemAdded) { - this._player.Attributes.ItemPowerUps.Add(item, this._gameContext.ItemPowerUpFactory.GetPowerUps(item, this._player.Attributes).ToList()); + var factory = this._gameContext.ItemPowerUpFactory; + this._player.Attributes.ItemPowerUps.Add(item, factory.GetPowerUps(item, this._player.Attributes).ToList()); // reset player equipped ammunition amount if (this.EquippedAmmunitionItem is { } ammoItem) diff --git a/src/GameLogic/ItemPowerUpFactory.cs b/src/GameLogic/ItemPowerUpFactory.cs index 832f9d253..5b437cf8f 100644 --- a/src/GameLogic/ItemPowerUpFactory.cs +++ b/src/GameLogic/ItemPowerUpFactory.cs @@ -189,7 +189,7 @@ private IEnumerable GetBasePowerUpWrappers(Item item, AttributeS .GetAdditionalValueElement(attribute.AggregateType); if (item.IsJewelry() && levelBonusElmt is not null) - { + { // Combine element resistance for jewelry so that the highest value from one single item can be sorted out yield return new PowerUpWrapper( new CombinedElement(attribute.BaseValueElement, levelBonusElmt), attribute.TargetAttribute, From 0bbecbafbc6e307e4bf25e10269cc19702578e18 Mon Sep 17 00:00:00 2001 From: ze-dom Date: Fri, 27 Sep 2024 17:47:44 +0100 Subject: [PATCH 07/12] Edited comment --- src/AttributeSystem/AggregateType.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AttributeSystem/AggregateType.cs b/src/AttributeSystem/AggregateType.cs index 57f277092..660211fff 100644 --- a/src/AttributeSystem/AggregateType.cs +++ b/src/AttributeSystem/AggregateType.cs @@ -25,7 +25,7 @@ public enum AggregateType AddFinal, /// - /// Only the highest available value from all items takes effect (jewelry element resistance). + /// Adds only the highest available value to the raw base value (jewelry element resistance). /// Maximum, } \ No newline at end of file From 53e0095f4b948ccabcd955bbcfc78dc3329ad7aa Mon Sep 17 00:00:00 2001 From: ze-dom Date: Tue, 8 Oct 2024 10:25:36 +0100 Subject: [PATCH 08/12] Generalized CombinedElement for base power ups & changed wings bonus per level table values --- src/GameLogic/ItemPowerUpFactory.cs | 17 ++++++----------- .../VersionSeasonSix/Items/Wings.cs | 4 ++-- .../Initialization/WingsInitializerBase.cs | 15 ++++++--------- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/src/GameLogic/ItemPowerUpFactory.cs b/src/GameLogic/ItemPowerUpFactory.cs index 5b437cf8f..7159e8f73 100644 --- a/src/GameLogic/ItemPowerUpFactory.cs +++ b/src/GameLogic/ItemPowerUpFactory.cs @@ -188,22 +188,17 @@ private IEnumerable GetBasePowerUpWrappers(Item item, AttributeS .FirstOrDefault(bonus => bonus.Level == item.Level)? .GetAdditionalValueElement(attribute.AggregateType); - if (item.IsJewelry() && levelBonusElmt is not null) - { // Combine element resistance for jewelry so that the highest value from one single item can be sorted out + if (levelBonusElmt is null) + { + yield return new PowerUpWrapper(attribute.BaseValueElement, attribute.TargetAttribute, attributeHolder); + } + else + { yield return new PowerUpWrapper( new CombinedElement(attribute.BaseValueElement, levelBonusElmt), attribute.TargetAttribute, attributeHolder); } - else - { - yield return new PowerUpWrapper(attribute.BaseValueElement, attribute.TargetAttribute, attributeHolder); - - if (levelBonusElmt is not null) - { - yield return new PowerUpWrapper(levelBonusElmt, attribute.TargetAttribute, attributeHolder); - } - } } private IEnumerable GetPowerUpsOfItemOptions(Item item, AttributeSystem attributeHolder) diff --git a/src/Persistence/Initialization/VersionSeasonSix/Items/Wings.cs b/src/Persistence/Initialization/VersionSeasonSix/Items/Wings.cs index 18e0abbe4..e5c41dd68 100644 --- a/src/Persistence/Initialization/VersionSeasonSix/Items/Wings.cs +++ b/src/Persistence/Initialization/VersionSeasonSix/Items/Wings.cs @@ -166,7 +166,7 @@ private ItemDefinition CreateWing(byte number, byte width, byte height, string n if (damageIncreaseInitial > 0) { - var powerUp = this.CreateItemBasePowerUpDefinition(Stats.AttackDamageIncrease, 1f + damageIncreaseInitial / 100f, AggregateType.Multiplicate); + var powerUp = this.CreateItemBasePowerUpDefinition(Stats.AttackDamageIncrease, 1f + (damageIncreaseInitial / 100f), AggregateType.Multiplicate); powerUp.BonusPerLevelTable = damageIncreasePerLevel; wing.BasePowerUpAttributes.Add(powerUp); } @@ -277,7 +277,7 @@ private ItemOptionDefinition CreateThirdClassWingOptions() definition.MaximumOptionsPerItem = 1; definition.PossibleOptions.Add(this.CreateWingOption(1, Stats.DefenseIgnoreChance, 0.05f, AggregateType.AddRaw)); // Ignore opponent's defensive power by 5% - definition.PossibleOptions.Add(this.CreateWingOption(2, Stats.DamageReflection, 0.05f, AggregateType.AddRaw)); // Ignore opponent's defensive power by 5% + definition.PossibleOptions.Add(this.CreateWingOption(2, Stats.DamageReflection, 0.05f, AggregateType.AddRaw)); // Reflect opponent's offensive power by 5% definition.PossibleOptions.Add(this.CreateWingOption(3, Stats.FullyRecoverHealthAfterHitChance, 0.05f, AggregateType.AddRaw)); // Fully restore health when hit by 5 % definition.PossibleOptions.Add(this.CreateWingOption(4, Stats.FullyRecoverManaAfterHitChance, 0.05f, AggregateType.AddRaw)); // Fully recover mana when hit by 5 % diff --git a/src/Persistence/Initialization/WingsInitializerBase.cs b/src/Persistence/Initialization/WingsInitializerBase.cs index 0749b3538..09de38071 100644 --- a/src/Persistence/Initialization/WingsInitializerBase.cs +++ b/src/Persistence/Initialization/WingsInitializerBase.cs @@ -81,10 +81,9 @@ protected ItemLevelBonusTable CreateAbsorbBonusPerLevel() { IEnumerable Generate() { - yield return 1f; - for (int level = 1; level <= this.MaximumItemLevel; level++) + for (int level = 0; level <= this.MaximumItemLevel; level++) { - yield return 1f - (0.02f * level); + yield return -0.02f * level; } } @@ -95,10 +94,9 @@ protected ItemLevelBonusTable CreateDamageIncreaseBonusPerLevelFirstAndThirdWing { IEnumerable Generate() { - yield return 1f; - for (int level = 1; level <= this.MaximumItemLevel; level++) + for (int level = 0; level <= this.MaximumItemLevel; level++) { - yield return 1f + (0.02f * level); + yield return 0.02f * level; } } @@ -109,10 +107,9 @@ protected ItemLevelBonusTable CreateDamageIncreaseBonusPerLevelSecondWings() { IEnumerable Generate() { - yield return 1; - for (int level = 1; level <= this.MaximumItemLevel; level++) + for (int level = 0; level <= this.MaximumItemLevel; level++) { - yield return 1 + (0.01f * level); + yield return 0.01f * level; } } From aa71b20a96d6597044b3b8d378327b00c01aa08e Mon Sep 17 00:00:00 2001 From: ze-dom Date: Tue, 8 Oct 2024 15:26:34 +0100 Subject: [PATCH 09/12] Added update for wings dmg rates level bonus tables --- .../FixWingsDmgRatesUpdatePlugIn075.cs | 24 ++++++++ .../FixWingsDmgRatesUpdatePlugIn095d.cs | 24 ++++++++ .../FixWingsDmgRatesUpdatePlugInBase.cs | 59 +++++++++++++++++++ .../FixWingsDmgRatesUpdatePlugInSeason6.cs | 24 ++++++++ .../Initialization/Updates/UpdateVersion.cs | 15 +++++ 5 files changed, 146 insertions(+) create mode 100644 src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugIn075.cs create mode 100644 src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugIn095d.cs create mode 100644 src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugInBase.cs create mode 100644 src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugInSeason6.cs diff --git a/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugIn075.cs b/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugIn075.cs new file mode 100644 index 000000000..4f5df1d1b --- /dev/null +++ b/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugIn075.cs @@ -0,0 +1,24 @@ +// +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace MUnique.OpenMU.Persistence.Initialization.Updates; + +using System.Runtime.InteropServices; +using MUnique.OpenMU.AttributeSystem; +using MUnique.OpenMU.PlugIns; + +/// +/// This update fixes the wings damage absorption and increase bonus level tables values for a (sum) calculation, instead of a compound calculation +/// for version 075. +/// +[PlugIn(PlugInName, PlugInDescription)] +[Guid("3821267A-9C37-40E5-B023-BAB1A8E4DAB7")] +public class FixWingsDmgRatesUpdatePlugIn075 : FixWingsDmgRatesUpdatePlugInBase +{ + /// + public override string DataInitializationKey => Version075.DataInitialization.Id; + + /// + public override UpdateVersion Version => UpdateVersion.FixWingsDmgRatesPlugIn075; +} \ No newline at end of file diff --git a/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugIn095d.cs b/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugIn095d.cs new file mode 100644 index 000000000..ca3983429 --- /dev/null +++ b/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugIn095d.cs @@ -0,0 +1,24 @@ +// +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace MUnique.OpenMU.Persistence.Initialization.Updates; + +using System.Runtime.InteropServices; +using MUnique.OpenMU.AttributeSystem; +using MUnique.OpenMU.PlugIns; + +/// +/// This update fixes the wings damage absorption and increase bonus level tables values for a (sum) calculation, instead of a compound calculation +/// for version 095d. +/// +[PlugIn(PlugInName, PlugInDescription)] +[Guid("F45FA4D0-B19B-48E2-9592-A37F3B36348A")] +public class FixWingsDmgRatesUpdatePlugIn095d : FixWingsDmgRatesUpdatePlugInBase +{ + /// + public override string DataInitializationKey => Version095d.DataInitialization.Id; + + /// + public override UpdateVersion Version => UpdateVersion.FixWingsDmgRatesPlugIn095d; +} \ No newline at end of file diff --git a/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugInBase.cs b/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugInBase.cs new file mode 100644 index 000000000..45623208e --- /dev/null +++ b/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugInBase.cs @@ -0,0 +1,59 @@ +// +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace MUnique.OpenMU.Persistence.Initialization.Updates; + +using MUnique.OpenMU.AttributeSystem; +using MUnique.OpenMU.DataModel.Configuration; + +/// +/// This update fixes the wings damage absorption and increase bonus level tables values for a (sum) calculation, instead of a compound calculation. +/// +public abstract class FixWingsDmgRatesUpdatePlugInBase : UpdatePlugInBase +{ + /// + /// The plug in name. + /// + internal const string PlugInName = "Fix Wings Damage Rates"; + + /// + /// The plug in description. + /// + internal const string PlugInDescription = "This update fixes the wings damage absorption and increase bonus level tables values."; + + /// + public override string Name => PlugInName; + + /// + public override string Description => PlugInDescription; + + /// + public override bool IsMandatory => true; + + /// + public override DateTime CreatedAt => new(2023, 10, 8, 16, 0, 0, DateTimeKind.Utc); + + /// + protected override async ValueTask ApplyAsync(IContext context, GameConfiguration gameConfiguration) + { + string dmgAbsorbCommonName = "Wing absorb"; + string dmgIncreaseCommonName = "Damage Increase (1st and 3rd Wings)"; + string dmgIncrease2ndWingsName = "Damage Increase (2nd Wings)"; + + string[] wingDmgTableNames = [dmgAbsorbCommonName, dmgIncrease2ndWingsName, dmgIncreaseCommonName]; + + foreach (var tableName in wingDmgTableNames) + { + var bonusEntries = gameConfiguration.ItemLevelBonusTables.FirstOrDefault(ilbt => ilbt.Name == tableName)?.BonusPerLevel; + + if (bonusEntries is not null) + { + foreach (var bonusEntry in bonusEntries) + { + bonusEntry.AdditionalValue -= 1.0f; + } + } + } + } +} \ No newline at end of file diff --git a/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugInSeason6.cs b/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugInSeason6.cs new file mode 100644 index 000000000..7e995bc2c --- /dev/null +++ b/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugInSeason6.cs @@ -0,0 +1,24 @@ +// +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace MUnique.OpenMU.Persistence.Initialization.Updates; + +using System.Runtime.InteropServices; +using MUnique.OpenMU.AttributeSystem; +using MUnique.OpenMU.PlugIns; + +/// +/// This update fixes the wings damage absorption and increase bonus level tables values for a (sum) calculation, instead of a compound calculation +/// for season 6. +/// +[PlugIn(PlugInName, PlugInDescription)] +[Guid("03F49890-CB0E-40B7-A590-174BBA1962F4")] +public class FixWingsDmgRatesUpdatePlugInSeason6 : FixWingsDmgRatesUpdatePlugInBase +{ + /// + public override string DataInitializationKey => VersionSeasonSix.DataInitialization.Id; + + /// + public override UpdateVersion Version => UpdateVersion.FixWingsDmgRatesPlugInSeason6; +} \ No newline at end of file diff --git a/src/Persistence/Initialization/Updates/UpdateVersion.cs b/src/Persistence/Initialization/Updates/UpdateVersion.cs index b66aae1d0..1c9a3d9f5 100644 --- a/src/Persistence/Initialization/Updates/UpdateVersion.cs +++ b/src/Persistence/Initialization/Updates/UpdateVersion.cs @@ -164,4 +164,19 @@ public enum UpdateVersion /// The version of the . /// FixMaxManaAndAbilityJewelryOptionsSeason6 = 31, + + /// + /// The version of the . + /// + FixWingsDmgRatesPlugIn075 = 32, + + /// + /// The version of the . + /// + FixWingsDmgRatesPlugIn095d = 33, + + /// + /// The version of the . + /// + FixWingsDmgRatesPlugInSeason6 = 34, } \ No newline at end of file From db1cc2bb1f1f26cb2d5fee0aab9edb5143bd74a6 Mon Sep 17 00:00:00 2001 From: ze-dom Date: Tue, 8 Oct 2024 15:38:24 +0100 Subject: [PATCH 10/12] Changed class name to conform to Codacy Pascal naming rules --- .../Initialization/Updates/FixWingsDmgRatesUpdatePlugIn095d.cs | 2 +- src/Persistence/Initialization/Updates/UpdateVersion.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugIn095d.cs b/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugIn095d.cs index ca3983429..bab3f24ea 100644 --- a/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugIn095d.cs +++ b/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugIn095d.cs @@ -14,7 +14,7 @@ namespace MUnique.OpenMU.Persistence.Initialization.Updates; /// [PlugIn(PlugInName, PlugInDescription)] [Guid("F45FA4D0-B19B-48E2-9592-A37F3B36348A")] -public class FixWingsDmgRatesUpdatePlugIn095d : FixWingsDmgRatesUpdatePlugInBase +public class FixWingsDmgRatesUpdatePlugIn095D : FixWingsDmgRatesUpdatePlugInBase { /// public override string DataInitializationKey => Version095d.DataInitialization.Id; diff --git a/src/Persistence/Initialization/Updates/UpdateVersion.cs b/src/Persistence/Initialization/Updates/UpdateVersion.cs index 1c9a3d9f5..923421ea1 100644 --- a/src/Persistence/Initialization/Updates/UpdateVersion.cs +++ b/src/Persistence/Initialization/Updates/UpdateVersion.cs @@ -171,7 +171,7 @@ public enum UpdateVersion FixWingsDmgRatesPlugIn075 = 32, /// - /// The version of the . + /// The version of the . /// FixWingsDmgRatesPlugIn095d = 33, From cb7e9a75ff3b038f7518ea6639227156a6790f79 Mon Sep 17 00:00:00 2001 From: ze-dom Date: Wed, 9 Oct 2024 10:43:06 +0100 Subject: [PATCH 11/12] Reversed comment (will address issue in posterior dev PR) --- src/Persistence/Initialization/VersionSeasonSix/Items/Wings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Persistence/Initialization/VersionSeasonSix/Items/Wings.cs b/src/Persistence/Initialization/VersionSeasonSix/Items/Wings.cs index e5c41dd68..53415b041 100644 --- a/src/Persistence/Initialization/VersionSeasonSix/Items/Wings.cs +++ b/src/Persistence/Initialization/VersionSeasonSix/Items/Wings.cs @@ -277,7 +277,7 @@ private ItemOptionDefinition CreateThirdClassWingOptions() definition.MaximumOptionsPerItem = 1; definition.PossibleOptions.Add(this.CreateWingOption(1, Stats.DefenseIgnoreChance, 0.05f, AggregateType.AddRaw)); // Ignore opponent's defensive power by 5% - definition.PossibleOptions.Add(this.CreateWingOption(2, Stats.DamageReflection, 0.05f, AggregateType.AddRaw)); // Reflect opponent's offensive power by 5% + definition.PossibleOptions.Add(this.CreateWingOption(2, Stats.DamageReflection, 0.05f, AggregateType.AddRaw)); // Ignore opponent's defensive power by 5% definition.PossibleOptions.Add(this.CreateWingOption(3, Stats.FullyRecoverHealthAfterHitChance, 0.05f, AggregateType.AddRaw)); // Fully restore health when hit by 5 % definition.PossibleOptions.Add(this.CreateWingOption(4, Stats.FullyRecoverManaAfterHitChance, 0.05f, AggregateType.AddRaw)); // Fully recover mana when hit by 5 % From 5dfb06d3cf6245d90cc4af5864afc40794f7d77f Mon Sep 17 00:00:00 2001 From: ze-dom Date: Fri, 18 Oct 2024 10:42:26 +0100 Subject: [PATCH 12/12] Corrected file attribute value for copyright doc --- .../Initialization/Updates/FixWingsDmgRatesUpdatePlugIn075.cs | 2 +- .../Initialization/Updates/FixWingsDmgRatesUpdatePlugIn095d.cs | 2 +- .../Initialization/Updates/FixWingsDmgRatesUpdatePlugInBase.cs | 2 +- .../Updates/FixWingsDmgRatesUpdatePlugInSeason6.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugIn075.cs b/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugIn075.cs index 4f5df1d1b..6992be509 100644 --- a/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugIn075.cs +++ b/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugIn075.cs @@ -1,4 +1,4 @@ -// +// // Licensed under the MIT License. See LICENSE file in the project root for full license information. // diff --git a/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugIn095d.cs b/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugIn095d.cs index bab3f24ea..9c3192a95 100644 --- a/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugIn095d.cs +++ b/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugIn095d.cs @@ -1,4 +1,4 @@ -// +// // Licensed under the MIT License. See LICENSE file in the project root for full license information. // diff --git a/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugInBase.cs b/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugInBase.cs index 45623208e..8a8c0d58b 100644 --- a/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugInBase.cs +++ b/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugInBase.cs @@ -1,4 +1,4 @@ -// +// // Licensed under the MIT License. See LICENSE file in the project root for full license information. // diff --git a/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugInSeason6.cs b/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugInSeason6.cs index 7e995bc2c..8adabb9ca 100644 --- a/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugInSeason6.cs +++ b/src/Persistence/Initialization/Updates/FixWingsDmgRatesUpdatePlugInSeason6.cs @@ -1,4 +1,4 @@ -// +// // Licensed under the MIT License. See LICENSE file in the project root for full license information. //