From a276e57b989d38100f7d84bbda60c34ca03e7896 Mon Sep 17 00:00:00 2001 From: Halflight Date: Thu, 7 Dec 2023 12:32:03 +0800 Subject: [PATCH 1/5] Prevent equipping two-handed items with shields --- .../PlayerActions/Items/MoveItemAction.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/GameLogic/PlayerActions/Items/MoveItemAction.cs b/src/GameLogic/PlayerActions/Items/MoveItemAction.cs index 297e02314..26f2ca3a2 100644 --- a/src/GameLogic/PlayerActions/Items/MoveItemAction.cs +++ b/src/GameLogic/PlayerActions/Items/MoveItemAction.cs @@ -234,11 +234,18 @@ private async ValueTask CanMoveAsync(Player player, Item item, byte to if (itemDefinition.ItemSlot.ItemSlots.Contains(toSlot) && player.CompliesRequirements(item)) { - if (itemDefinition.ItemSlot.ItemSlots.Contains(RightHandSlot) - && itemDefinition.ItemSlot.ItemSlots.Contains(LeftHandSlot) - && toSlot == RightHandSlot - && storage.GetItem(LeftHandSlot)?.Definition!.Width >= 2) + static bool IsOneHandedOrShield(ItemDefinition definition) => + (definition.ItemSlot!.ItemSlots.Contains(RightHandSlot) && definition.ItemSlot.ItemSlots.Contains(LeftHandSlot)) || definition.Group == 6; + + if ((toSlot == LeftHandSlot + && itemDefinition.Width >= 2 + && IsOneHandedOrShield(storage.GetItem(RightHandSlot)?.Definition!)) + || (toSlot == RightHandSlot + && IsOneHandedOrShield(itemDefinition) + && storage.GetItem(LeftHandSlot)?.Definition!.Width >= 2)) { + // Trying to equip a two-handed item to the left hand slot when the right hand slot has a one-handed item/shield, + // or equip a one-handed weapon/shield to the right hand slot when the left hand slot has a two-handed item. return Movement.None; } From 91ad3be936333b7d9ed8012fe8f83f22351b53d3 Mon Sep 17 00:00:00 2001 From: Halflight Date: Thu, 7 Dec 2023 13:02:12 +0800 Subject: [PATCH 2/5] Cherry-picked the wrong commit --- src/GameLogic/PlayerActions/Items/MoveItemAction.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/GameLogic/PlayerActions/Items/MoveItemAction.cs b/src/GameLogic/PlayerActions/Items/MoveItemAction.cs index 26f2ca3a2..36b05a874 100644 --- a/src/GameLogic/PlayerActions/Items/MoveItemAction.cs +++ b/src/GameLogic/PlayerActions/Items/MoveItemAction.cs @@ -239,13 +239,13 @@ static bool IsOneHandedOrShield(ItemDefinition definition) => if ((toSlot == LeftHandSlot && itemDefinition.Width >= 2 - && IsOneHandedOrShield(storage.GetItem(RightHandSlot)?.Definition!)) + && storage.GetItem(RightHandSlot)?.Definition!.Group == 6) || (toSlot == RightHandSlot && IsOneHandedOrShield(itemDefinition) && storage.GetItem(LeftHandSlot)?.Definition!.Width >= 2)) { - // Trying to equip a two-handed item to the left hand slot when the right hand slot has a one-handed item/shield, - // or equip a one-handed weapon/shield to the right hand slot when the left hand slot has a two-handed item. + // Attempting to equip a two-handed item to the left hand slot when a shield is in the right hand slot, + // or trying to equip a one-handed weapon or shield to the right hand slot when a two-handed item is in the left hand slot. return Movement.None; } From d4e320c466d4598d45ca59ae6516631c4e4362a9 Mon Sep 17 00:00:00 2001 From: Halflight Date: Sun, 10 Dec 2023 09:12:53 +0800 Subject: [PATCH 3/5] Add missing using --- src/GameLogic/PlayerActions/Items/MoveItemAction.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/GameLogic/PlayerActions/Items/MoveItemAction.cs b/src/GameLogic/PlayerActions/Items/MoveItemAction.cs index 36b05a874..87c050b1a 100644 --- a/src/GameLogic/PlayerActions/Items/MoveItemAction.cs +++ b/src/GameLogic/PlayerActions/Items/MoveItemAction.cs @@ -5,6 +5,7 @@ namespace MUnique.OpenMU.GameLogic.PlayerActions.Items; using System.ComponentModel; +using MUnique.OpenMU.DataModel.Configuration.Items; using MUnique.OpenMU.GameLogic.PlugIns; using MUnique.OpenMU.GameLogic.Views; using MUnique.OpenMU.GameLogic.Views.Inventory; From 528e59f6eaab7e7b8debe966cf0e7b6db7dae5d0 Mon Sep 17 00:00:00 2001 From: Halflight Date: Sun, 10 Dec 2023 10:14:45 +0800 Subject: [PATCH 4/5] Compensate level-up points when gaining Hero Status beyond level 220 --- .../PlayerActions/Quests/QuestCompletionAction.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/GameLogic/PlayerActions/Quests/QuestCompletionAction.cs b/src/GameLogic/PlayerActions/Quests/QuestCompletionAction.cs index 22bfce1d3..72dc18695 100644 --- a/src/GameLogic/PlayerActions/Quests/QuestCompletionAction.cs +++ b/src/GameLogic/PlayerActions/Quests/QuestCompletionAction.cs @@ -6,6 +6,7 @@ namespace MUnique.OpenMU.GameLogic.PlayerActions.Quests; using MUnique.OpenMU.AttributeSystem; using MUnique.OpenMU.DataModel.Configuration.Quests; +using MUnique.OpenMU.GameLogic.Attributes; using MUnique.OpenMU.GameLogic.Views.Character; using MUnique.OpenMU.GameLogic.Views.Inventory; using MUnique.OpenMU.GameLogic.Views.Quest; @@ -104,6 +105,12 @@ private static async ValueTask AddRewardAsync(Player player, QuestReward reward) player.SelectedCharacter.Attributes.Add(attribute); } + // Compensate level-up points when gaining Hero Status beyond level 220. + if (reward.AttributeReward?.Id == Stats.GainHeroStatusQuestCompleted.Id && attribute.Value == 0) + { + player.SelectedCharacter!.LevelUpPoints += (int)player.Attributes![Stats.Level] - 220; + } + attribute.Value += reward.Value; await player.InvokeViewPlugInAsync(p => p.ShowAsync(player, QuestRewardType.Attribute, reward.Value, attribute.Definition)).ConfigureAwait(false); From ca574e0518e1195620d0791aa3c288afd8cee3af Mon Sep 17 00:00:00 2001 From: Halflight Date: Mon, 11 Dec 2023 19:20:09 +0800 Subject: [PATCH 5/5] Use quest definition instead of hard-coded numbers --- .../Quests/QuestCompletionAction.cs | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/GameLogic/PlayerActions/Quests/QuestCompletionAction.cs b/src/GameLogic/PlayerActions/Quests/QuestCompletionAction.cs index 72dc18695..8dbb73f61 100644 --- a/src/GameLogic/PlayerActions/Quests/QuestCompletionAction.cs +++ b/src/GameLogic/PlayerActions/Quests/QuestCompletionAction.cs @@ -86,34 +86,35 @@ public async ValueTask CompleteQuestAsync(Player player, short group, short numb foreach (var reward in activeQuest.Rewards) { - await AddRewardAsync(player, reward).ConfigureAwait(false); + await AddRewardAsync(player, reward, activeQuest).ConfigureAwait(false); } await questState.ClearAsync(player.PersistenceContext).ConfigureAwait(false); await player.InvokeViewPlugInAsync(p => p.QuestCompletedAsync(activeQuest)).ConfigureAwait(false); } - private static async ValueTask AddRewardAsync(Player player, QuestReward reward) + private static async ValueTask AddRewardAsync(Player player, QuestReward reward, QuestDefinition quest) { switch (reward.RewardType) { - case QuestRewardType.Attribute: - var attribute = player.SelectedCharacter!.Attributes.FirstOrDefault(a => a.Definition == reward.AttributeReward); - if (attribute is null) - { - attribute = player.PersistenceContext.CreateNew(reward.AttributeReward, 0); - player.SelectedCharacter.Attributes.Add(attribute); - } - - // Compensate level-up points when gaining Hero Status beyond level 220. - if (reward.AttributeReward?.Id == Stats.GainHeroStatusQuestCompleted.Id && attribute.Value == 0) + case QuestRewardType.Attribute: + var attribute = player.SelectedCharacter!.Attributes.FirstOrDefault(a => a.Definition == reward.AttributeReward); + if (attribute is null) { - player.SelectedCharacter!.LevelUpPoints += (int)player.Attributes![Stats.Level] - 220; - } - - attribute.Value += reward.Value; - - await player.InvokeViewPlugInAsync(p => p.ShowAsync(player, QuestRewardType.Attribute, reward.Value, attribute.Definition)).ConfigureAwait(false); + attribute = player.PersistenceContext.CreateNew(reward.AttributeReward, 0); + player.SelectedCharacter.Attributes.Add(attribute); + } + + attribute.Value += reward.Value; + + // Compensate level-up points when doing a quest at a later level. + if (attribute.Definition == Stats.PointsPerLevelUp) + { + var playerLevel = (int)player.Attributes![Stats.Level]; + player.SelectedCharacter.LevelUpPoints += (playerLevel - quest.MinimumCharacterLevel) * reward.Value; + } + + await player.InvokeViewPlugInAsync(p => p.ShowAsync(player, QuestRewardType.Attribute, reward.Value, attribute.Definition)).ConfigureAwait(false); break; case QuestRewardType.Item: var item = player.PersistenceContext.CreateNew();