Skip to content

Commit

Permalink
Merge branch 'master' into dev/attack-speed-stat
Browse files Browse the repository at this point in the history
  • Loading branch information
sven-n authored Oct 19, 2024
2 parents 12539aa + fd9fbf8 commit bf5f7e8
Show file tree
Hide file tree
Showing 26 changed files with 5,270 additions and 41 deletions.
5 changes: 5 additions & 0 deletions src/AttributeSystem/AggregateType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,9 @@ public enum AggregateType
/// Adds the value to the final value.
/// </summary>
AddFinal,

/// <summary>
/// Adds only the highest available value to the raw base value (jewelry element resistance).
/// </summary>
Maximum,
}
4 changes: 3 additions & 1 deletion src/AttributeSystem/ComposableAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ 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;
rawValues += maxValues;

if (multiValues == 0 && this.Elements.All(e => e.AggregateType != AggregateType.Multiplicate))
{
Expand All @@ -75,7 +77,7 @@ private float GetAndCacheValue()
// nothing to do
}

var newValue = (rawValues * multiValues + finalValues);
var newValue = (rawValues * multiValues) + finalValues;
if (this.Definition.MaximumValue.HasValue)
{
newValue = Math.Min(this.Definition.MaximumValue.Value, newValue);
Expand Down
5 changes: 5 additions & 0 deletions src/DataModel/Configuration/GameConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ public partial class GameConfiguration
/// </summary>
public TimeSpan ItemDropDuration { get; set; }

/// <summary>
/// Gets or sets the maximum droppable item option level.
/// </summary>
public byte MaximumItemOptionLevelDrop { get; set; }

/// <summary>
/// Gets or sets the accumulated damage which needs to be done to decrease <see cref="Item.Durability"/> of a defending item by 1.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/DataModel/Configuration/Items/ItemOptionTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static class ItemOptionTypes
/// <summary>
/// Gets the luck option type.
/// </summary>
public static ItemOptionType Luck { get; } = new () { Name = "Luck (Critical Damage Chance 10%)", Id = new Guid("{3E3E9BE8-4E16-4F27-A7CF-986D48454D76}") };
public static ItemOptionType Luck { get; } = new () { Name = "Luck (Critical Damage Chance 5%)", Id = new Guid("{3E3E9BE8-4E16-4F27-A7CF-986D48454D76}") };

/// <summary>
/// Gets the standard option option type.
Expand Down
7 changes: 6 additions & 1 deletion src/GameLogic/DefaultDropGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public class DefaultDropGenerator : IDropGenerator

private readonly AsyncLock _lock = new();

private readonly byte _maxItemOptionLevelDrop;

private readonly IList<ItemDefinition> _ancientItems;

private readonly IList<ItemDefinition> _droppableItems;
Expand All @@ -41,6 +43,7 @@ public class DefaultDropGenerator : IDropGenerator
public DefaultDropGenerator(GameConfiguration config, IRandomizer randomizer)
{
this._randomizer = randomizer;
this._maxItemOptionLevelDrop = config.MaximumItemOptionLevelDrop < 1 || config.MaximumItemOptionLevelDrop > 4 ? (byte)3 : config.MaximumItemOptionLevelDrop;
this._droppableItems = config.Items.Where(i => i.DropsFromMonsters).ToList();
this._ancientItems = this._droppableItems.Where(
i => i.PossibleItemSetGroups.Any(
Expand Down Expand Up @@ -319,7 +322,9 @@ private void ApplyOption(Item item, ItemOptionDefinition option)
var itemOptionLink = new ItemOptionLink
{
ItemOption = newOption,
Level = newOption?.LevelDependentOptions.Select(l => l.Level).SelectRandom() ?? 0,
Level = newOption?.LevelDependentOptions.Select(ldo => ldo.Level)
.Concat(newOption.LevelDependentOptions.Count > 0 ? [1] : []) // For base def/dmg opts level 1 is not an ItemOptionOfLevel entry
.Distinct().Where(l => l <= this._maxItemOptionLevelDrop).SelectRandom() ?? 0,
};
item.ItemOptions.Add(itemOptionLink);
}
Expand Down
7 changes: 4 additions & 3 deletions src/GameLogic/InventoryStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace MUnique.OpenMU.GameLogic;
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;

/// <summary>
/// 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.
Expand Down Expand Up @@ -166,8 +166,9 @@ await this._player.ForEachWorldObserverAsync<IAppearanceChangedPlugIn>(
this._player.Attributes.ItemPowerUps.Add(item, factory.GetPowerUps(item, this._player.Attributes).ToList());

// reset player equipped ammunition amount
if (this.EquippedAmmunitionItem is { } ammoItem) {
this._player.Attributes[Stats.AmmunitionAmount] = (float) ammoItem.Durability;
if (this.EquippedAmmunitionItem is { } ammoItem)
{
this._player.Attributes[Stats.AmmunitionAmount] = (float)ammoItem.Durability;
}
}
}
Expand Down
16 changes: 14 additions & 2 deletions src/GameLogic/ItemExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,25 @@ public static bool IsShield(this Item item)
return item.Definition?.Group == ShieldItemGroup;
}

/// <summary>
/// Determines whether this item is a jewelry (pendant or ring) item.
/// </summary>
/// <param name="item">The item.</param>
/// <returns>
/// <c>true</c> if the specified item is jewelry; otherwise, <c>false</c>.
/// </returns>
public static bool IsJewelry(this Item item)
{
return item.ItemSlot >= InventoryConstants.PendantSlot && item.ItemSlot <= InventoryConstants.Ring2Slot;
}

/// <summary>
/// Determines whether this instance is a is weapon which deals physical damage.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="minimumDmg">The minimum physical damage of the weapon.</param>
/// <returns>
/// <c>true</c> if this instance is a is weapon which deals physical damage; otherwise, <c>false</c>.
/// <c>true</c> if this instance is a weapon which deals physical damage; otherwise, <c>false</c>.
/// </returns>
public static bool IsPhysicalWeapon(this Item item, [NotNullWhen(true)] out float? minimumDmg)
{
Expand All @@ -144,7 +156,7 @@ public static bool IsPhysicalWeapon(this Item item, [NotNullWhen(true)] out floa
/// <param name="item">The item.</param>
/// <param name="staffRise">The staff rise percentage of the weapon.</param>
/// <returns>
/// <c>true</c> if this instance is a is weapon which deals wizardry damage; otherwise, <c>false</c>.
/// <c>true</c> if this instance is a weapon which deals wizardry damage; otherwise, <c>false</c>.
/// </returns>
public static bool IsWizardryWeapon(this Item item, [NotNullWhen(true)] out float? staffRise)
{
Expand Down
18 changes: 13 additions & 5 deletions src/GameLogic/ItemPowerUpFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,20 @@ private IEnumerable<PowerUpWrapper> 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<LevelBonus>())
.FirstOrDefault(bonus => bonus.Level == item.Level)?
.GetAdditionalValueElement(attribute.AggregateType);

var levelBonus = (attribute.BonusPerLevelTable?.BonusPerLevel ?? Enumerable.Empty<LevelBonus>()).FirstOrDefault(bonus => bonus.Level == item.Level);
if (levelBonus is not null)
if (levelBonusElmt is null)
{
yield return new PowerUpWrapper(levelBonus.GetAdditionalValueElement(attribute.AggregateType), attribute.TargetAttribute, attributeHolder);
yield return new PowerUpWrapper(attribute.BaseValueElement, attribute.TargetAttribute, attributeHolder);
}
else
{
yield return new PowerUpWrapper(
new CombinedElement(attribute.BaseValueElement, levelBonusElmt),
attribute.TargetAttribute,
attributeHolder);
}
}

Expand Down Expand Up @@ -253,7 +261,7 @@ private IEnumerable<PowerUpWrapper> 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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ public enum ItemFailResult
DecreaseOptionByOne,

/// <summary>
/// Decreases the option by one level, or removes the option if the level would reach 0.
/// Removes the option.
/// </summary>
DecreaseOptionByOneOrRemove,
RemoveOption,
}

/// <summary>
Expand Down Expand Up @@ -104,13 +104,8 @@ private void HandleFailedUpgrade(Item item, ItemOptionLink itemOption)
case ItemFailResult.DecreaseOptionByOne:
itemOption.Level = Math.Max(itemOption.Level - 1, 1);
break;
case ItemFailResult.DecreaseOptionByOneOrRemove:
itemOption.Level -= 1;
if (itemOption.Level == 0)
{
item.ItemOptions.Remove(itemOption);
}

case ItemFailResult.RemoveOption:
item.ItemOptions.Remove(itemOption);
break;
case ItemFailResult.SetOptionToLevelOne:
itemOption.Level = 1;
Expand Down Expand Up @@ -142,7 +137,9 @@ private bool TryAddItemOption(Item item, IContext persistenceContext)
var optionLink = persistenceContext.CreateNew<ItemOptionLink>();
optionLink.ItemOption = possibleOptions.SelectRandom()!;
optionLink.Level = optionLink.ItemOption.LevelDependentOptions.Any()
? optionLink.ItemOption.LevelDependentOptions.Min(l => l.Level)
? optionLink.ItemOption.LevelDependentOptions.Select(ldo => ldo.Level)
.Concat(this.Configuration.OptionType == ItemOptionTypes.Option ? [1] : []) // For base def/dmg opts level 1 is not an ItemOptionOfLevel entry
.Min()
: 1;
item.ItemOptions.Add(optionLink);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class LifeJewelConsumeHandlerPlugIn : ItemUpgradeConsumeHandlerPlugIn
/// Initializes a new instance of the <see cref="LifeJewelConsumeHandlerPlugIn" /> class.
/// </summary>
public LifeJewelConsumeHandlerPlugIn()
: base(new ItemUpgradeConfiguration(ItemOptionTypes.Option, true, true, 0.5, ItemFailResult.DecreaseOptionByOneOrRemove))
: base(new ItemUpgradeConfiguration(ItemOptionTypes.Option, true, true, 0.5, ItemFailResult.RemoveOption))
{
}

Expand Down
Loading

0 comments on commit bf5f7e8

Please sign in to comment.