Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs-website/docs/server-features/cash-shop.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ buff icons are the ones which the game client shows for these items:
| Master Seal of Ascension | master experience ×1.5 | 30 minutes |
| Master Seal of Wealth | master experience ×2, item drop rate ×1.5 | 30 minutes |
| Seal of Wealth (13/116) | item drop rate ×1.5 | 30 minutes |
| Gladiator's Honor | experience +20% in Vulcanus | 30 minutes |
| Max AG Boost Aura | maximum AG + character level | 30 minutes |
| Max SD Boost Aura | maximum SD + character level × 10 | 30 minutes |
| Scroll of Quickness | attack speed +15 | 30 minutes |
Expand All @@ -310,6 +311,12 @@ drops stays the same. Existing databases get the item drop rate with the
configuration update *Add the item drop rate of seals*, which also adds the
second Seal of Wealth (13/116). It isn't sold in the in-game shop.

The Gladiator's Honor can only be used in Vulcanus, and its experience bonus
only counts there. The game client doesn't tell its duration, so it lasts as
long as a seal. The map is set in the configuration of the plugins "Gladiator's
Honor consume handler" and "Vulcanus experience bonus". Its higher drop rate
of rare items isn't implemented yet.

:::note
Not implemented yet: the Seal of Mobility and the Party EXP Scroll.
:::
Expand Down
6 changes: 6 additions & 0 deletions src/GameLogic/Attributes/Stats.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ public class Stats
/// <remarks>So far includes skeleton xfm ring, pet panda, pet skeleton bonus.</remarks>
public static AttributeDefinition BonusExperienceRate { get; } = new(new Guid("D48A9D05-533A-4556-9FC3-F71C8BEC4B8E"), "Bonus Experience Rate", "The bonus experience rate which is added to the base experience rate multiplier.");

/// <summary>
/// Gets the experience rate which is added while the player is in Vulcanus, e.g. by the Gladiator's Honor.
/// </summary>
/// <remarks>The experience is multiplied by one plus this rate by the <c>VulcanusExperiencePlugIn</c>.</remarks>
public static AttributeDefinition VulcanusExperienceRate { get; } = new(new Guid("199015AC-3139-4E6B-A7C0-5439DD4F7052"), "Vulcanus Experience Rate", "The experience rate which is added while the player is in Vulcanus.");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid introducing a stat solely for Gladiator's Honor

The only producer of this attribute is the new Gladiator's Honor effect in BuffItems, and its only consumer is VulcanusExperiencePlugIn. This violates rule 3 of docs/CODING_RULES.md: “Don't introduce new stats for one specific item or skill.” It turns this item's implementation detail into a permanent persisted attribute/GUID contract and requires additional attribute-creation handling during upgrades. Keep the map restriction in the feature plugin and represent the bonus through existing experience attributes or item/plugin configuration instead.

AGENTS.md reference: AGENTS.md:L16-L17

Useful? React with 👍 / 👎.


/// <summary>
/// Gets the master level definition.
/// </summary>
Expand Down
5 changes: 5 additions & 0 deletions src/GameLogic/ItemConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ public class ItemConstants
/// </summary>
public static ItemIdentifier InvitationToSantaVillage => new(66, 13);

/// <summary>
/// Gets the identifier for the Gladiator's Honor, which increases the experience in Vulcanus.
/// </summary>
public static ItemIdentifier GladiatorsHonor => new(95, 13);

/// <summary>
/// Gets the identifier for the demon.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// <copyright file="GladiatorsHonorConsumeHandlerPlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>

namespace MUnique.OpenMU.GameLogic.PlayerActions.ItemConsumeActions;

using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic.PlugIns;
using MUnique.OpenMU.PlugIns;

/// <summary>
/// The consume handler for the Gladiator's Honor, which applies its effect only in Vulcanus,
/// like the game client describes it.
/// </summary>
/// <remarks>
/// The experience bonus of its effect is applied by the <see cref="VulcanusExperiencePlugIn"/>,
/// so it only counts while the player stays in Vulcanus.
/// </remarks>
[PlugIn]
[Display(Name = nameof(PlugInResources.GladiatorsHonorConsumeHandlerPlugIn_Name), Description = nameof(PlugInResources.GladiatorsHonorConsumeHandlerPlugIn_Description), ResourceType = typeof(PlugInResources))]
[Guid("FBB2F1AB-8097-41B0-A10E-8323C10D053A")]
public class GladiatorsHonorConsumeHandlerPlugIn : ApplyMagicEffectConsumeHandlerPlugIn, ISupportCustomConfiguration<VulcanusMapConfiguration>, ISupportDefaultCustomConfiguration
{
/// <inheritdoc />
public VulcanusMapConfiguration? Configuration { get; set; }

/// <inheritdoc />
public override ItemIdentifier Key => ItemConstants.GladiatorsHonor;

/// <inheritdoc />
public override async ValueTask<bool> ConsumeItemAsync(Player player, Item item, Item? targetItem, FruitUsage fruitUsage)
{
var mapNumber = (this.Configuration ??= new VulcanusMapConfiguration()).MapNumber;
if (player.CurrentMap?.MapId != mapNumber)
{
await player.ShowLocalizedBlueMessageAsync(nameof(PlayerMessage.ItemCantBeUsedOnThisMap)).ConfigureAwait(false);
return false;
}

return await base.ConsumeItemAsync(player, item, targetItem, fruitUsage).ConfigureAwait(false);
}

/// <inheritdoc />
public object CreateDefaultConfig() => new VulcanusMapConfiguration();
}
38 changes: 38 additions & 0 deletions src/GameLogic/PlugIns/VulcanusExperiencePlugIn.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// <copyright file="VulcanusExperiencePlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>

namespace MUnique.OpenMU.GameLogic.PlugIns;

using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic.Attributes;
using MUnique.OpenMU.PlugIns;

/// <summary>
/// Increases the experience of a player in Vulcanus by its <see cref="Stats.VulcanusExperienceRate"/>,
/// which is given e.g. by the Gladiator's Honor.
/// </summary>
[PlugIn]
[Display(Name = nameof(PlugInResources.VulcanusExperiencePlugIn_Name), Description = nameof(PlugInResources.VulcanusExperiencePlugIn_Description), ResourceType = typeof(PlugInResources))]
[Guid("03E6A271-821E-49B8-B6E9-B24E95B6D16E")]
public class VulcanusExperiencePlugIn : IExperienceCalculationPlugIn, ISupportCustomConfiguration<VulcanusMapConfiguration>, ISupportDefaultCustomConfiguration
{
/// <inheritdoc />
public VulcanusMapConfiguration? Configuration { get; set; }

/// <inheritdoc />
public ValueTask CalculateExperienceAsync(Player player, ExperienceCalculationArgs args)
{
var mapNumber = (this.Configuration ??= new VulcanusMapConfiguration()).MapNumber;
if (player.CurrentMap?.MapId == mapNumber
&& player.Attributes?[Stats.VulcanusExperienceRate] is > 0 and var rate)
{
args.Experience *= 1 + rate;
}

return ValueTask.CompletedTask;
}

/// <inheritdoc />
public object CreateDefaultConfig() => new VulcanusMapConfiguration();
}
22 changes: 22 additions & 0 deletions src/GameLogic/PlugIns/VulcanusMapConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// <copyright file="VulcanusMapConfiguration.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>

namespace MUnique.OpenMU.GameLogic.PlugIns;

/// <summary>
/// Configuration of the plugins of the Gladiator's Honor, which only apply in Vulcanus.
/// </summary>
public class VulcanusMapConfiguration
{
/// <summary>
/// The default number of the map Vulcanus.
/// </summary>
internal const short DefaultMapNumber = 63;

/// <summary>
/// Gets or sets the number of the map in which the Gladiator's Honor can be used and gives its bonus.
/// </summary>
[Display(ResourceType = typeof(PlugInResources), Name = nameof(PlugInResources.VulcanusMapConfiguration_MapNumber_Name))]
public short MapNumber { get; set; } = DefaultMapNumber;
}
9 changes: 9 additions & 0 deletions src/GameLogic/Properties/PlayerMessage.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/GameLogic/Properties/PlayerMessage.de.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1021,6 +1021,9 @@ Inventarerweiterungen: {18}</value>
<data name="WarpOnlyForGameMasters" xml:space="preserve">
<value>Dieser Warp ist nur für Game Master verfügbar.</value>
</data>
<data name="ItemCantBeUsedOnThisMap" xml:space="preserve">
<value>Dieser Gegenstand kann auf dieser Karte nicht benutzt werden.</value>
</data>
<data name="ItemsWaitForSpace" xml:space="preserve">
<value>{0} Gegenstand/Gegenstände warten auf Platz in Ihrem Inventar. Sie werden hineingelegt, sobald sie passen:</value>
</data>
Expand Down
3 changes: 3 additions & 0 deletions src/GameLogic/Properties/PlayerMessage.pt.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1174,6 +1174,9 @@ Extensões de inventário: {18}</value>
<data name="WarpOnlyForGameMasters" xml:space="preserve">
<value>Este warp está disponível apenas para game masters.</value>
</data>
<data name="ItemCantBeUsedOnThisMap" xml:space="preserve">
<value>Este item não pode ser usado neste mapa.</value>
</data>
<data name="ItemsWaitForSpace" xml:space="preserve">
<value>{0} item(ns) aguardam espaço no seu inventário. Eles serão colocados nele assim que couberem:</value>
</data>
Expand Down
3 changes: 3 additions & 0 deletions src/GameLogic/Properties/PlayerMessage.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1174,6 +1174,9 @@ Inventory Extensions: {18}</value>
<data name="WarpOnlyForGameMasters" xml:space="preserve">
<value>This warp is only available to game masters.</value>
</data>
<data name="ItemCantBeUsedOnThisMap" xml:space="preserve">
<value>This item can't be used on this map.</value>
</data>
<data name="ItemsWaitForSpace" xml:space="preserve">
<value>{0} item(s) wait for space in your inventory. They are put into it as soon as they fit:</value>
</data>
Expand Down
3 changes: 3 additions & 0 deletions src/GameLogic/Properties/PlayerMessage.zh-CN.resx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
<data name="MiniGamePlayerKillersCantEnter" xml:space="preserve"><value>红名玩家无法进入!</value></data>
<data name="MiniGameTicketRequired" xml:space="preserve"><value>参加此活动需要入场券。</value></data>
<data name="NoKalimaGateInKalima" xml:space="preserve"><value>无法在卡利玛创建卡利玛之门。</value></data>
<data name="ItemCantBeUsedOnThisMap" xml:space="preserve">
<value>此物品无法在此地图使用。</value>
</data>
<data name="ItemsWaitForSpace" xml:space="preserve">
<value>有 {0} 件物品正在等待背包空间,有足够空间时会自动放入背包:</value>
</data>
Expand Down
45 changes: 45 additions & 0 deletions src/GameLogic/Properties/PlugInResources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions src/GameLogic/Properties/PlugInResources.de.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2016,6 +2016,21 @@
<data name="ShowWarpListAfterEnterWorldPlugIn_Description" xml:space="preserve">
<value>Teilt dem Client beim Betreten des Spiels mit, welche Warps der Spieler im Warp-Fenster auswählen kann.</value>
</data>
<data name="GladiatorsHonorConsumeHandlerPlugIn_Name" xml:space="preserve">
<value>Verbrauch der Ehre des Gladiators</value>
</data>
<data name="GladiatorsHonorConsumeHandlerPlugIn_Description" xml:space="preserve">
<value>Wendet den Effekt der Ehre des Gladiators an, die nur in Vulcanus benutzt werden kann.</value>
</data>
<data name="VulcanusExperiencePlugIn_Name" xml:space="preserve">
<value>Erfahrungsbonus in Vulcanus</value>
</data>
<data name="VulcanusExperiencePlugIn_Description" xml:space="preserve">
<value>Erhöht die Erfahrung von Spielern in Vulcanus um ihre Vulcanus-Erfahrungsrate, z. B. durch die Ehre des Gladiators.</value>
</data>
<data name="VulcanusMapConfiguration_MapNumber_Name" xml:space="preserve">
<value>Kartennummer</value>
</data>
<data name="WaitingItemsDeliveryPlugIn_Name" xml:space="preserve">
<value>Zustellung wartender Gegenstände</value>
</data>
Expand Down
15 changes: 15 additions & 0 deletions src/GameLogic/Properties/PlugInResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2061,6 +2061,21 @@
<data name="ShowWarpListAfterEnterWorldPlugIn_Description" xml:space="preserve">
<value>Tells the client which warps the player can select in the warp window, when the player enters the game.</value>
</data>
<data name="GladiatorsHonorConsumeHandlerPlugIn_Name" xml:space="preserve">
<value>Gladiator's Honor consume handler</value>
</data>
<data name="GladiatorsHonorConsumeHandlerPlugIn_Description" xml:space="preserve">
<value>Applies the effect of the Gladiator's Honor, which can only be used in Vulcanus.</value>
</data>
<data name="VulcanusExperiencePlugIn_Name" xml:space="preserve">
<value>Vulcanus experience bonus</value>
</data>
<data name="VulcanusExperiencePlugIn_Description" xml:space="preserve">
<value>Increases the experience of players in Vulcanus by their Vulcanus experience rate, e.g. of the Gladiator's Honor.</value>
</data>
<data name="VulcanusMapConfiguration_MapNumber_Name" xml:space="preserve">
<value>Map number</value>
</data>
<data name="WaitingItemsDeliveryPlugIn_Name" xml:space="preserve">
<value>Waiting items delivery</value>
</data>
Expand Down
15 changes: 15 additions & 0 deletions src/GameLogic/Properties/PlugInResources.zh-CN.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1804,6 +1804,21 @@
<data name="IllusionTempleAllianceStorageTalkPlugIn_Description" xml:space="preserve"><value>处理玩家与幻影寺院盟军物品仓库的交互。盟军将圣物送至此处可获得一分。</value></data>
<data name="IllusionTempleIllusionStorageTalkPlugIn_Name" xml:space="preserve"><value>幻影寺院幻影物品仓库交互</value></data>
<data name="IllusionTempleIllusionStorageTalkPlugIn_Description" xml:space="preserve"><value>处理玩家与幻影寺院幻影物品仓库的交互。幻影军将圣物送至此处可获得一分。</value></data>
<data name="GladiatorsHonorConsumeHandlerPlugIn_Name" xml:space="preserve">
<value>角斗士的荣耀使用</value>
</data>
<data name="GladiatorsHonorConsumeHandlerPlugIn_Description" xml:space="preserve">
<value>应用角斗士的荣耀的效果,该物品只能在囚禁之岛使用。</value>
</data>
<data name="VulcanusExperiencePlugIn_Name" xml:space="preserve">
<value>囚禁之岛经验加成</value>
</data>
<data name="VulcanusExperiencePlugIn_Description" xml:space="preserve">
<value>按玩家在囚禁之岛的经验倍率(例如角斗士的荣耀)增加其在囚禁之岛获得的经验。</value>
</data>
<data name="VulcanusMapConfiguration_MapNumber_Name" xml:space="preserve">
<value>地图编号</value>
</data>
<data name="WaitingItemsDeliveryPlugIn_Name" xml:space="preserve">
<value>等待物品发放</value>
</data>
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/Persistence/Initialization/Properties/ItemNames.de.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2259,4 +2259,7 @@
<data name="TalismanOfItemProtection" xml:space="preserve">
<value>Talisman des Gegenstandsschutzes</value>
</data>
<data name="GladiatorsHonor" xml:space="preserve">
<value>Ehre des Gladiators</value>
</data>
</root>
3 changes: 3 additions & 0 deletions src/Persistence/Initialization/Properties/ItemNames.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2343,4 +2343,7 @@
<data name="TalismanOfItemProtection" xml:space="preserve">
<value>Talisman of Item Protection</value>
</data>
<data name="GladiatorsHonor" xml:space="preserve">
<value>Gladiator's Honor</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -2343,4 +2343,7 @@
<data name="TalismanOfItemProtection" xml:space="preserve">
<value>物品保护护身符</value>
</data>
<data name="GladiatorsHonor" xml:space="preserve">
<value>角斗士的荣耀</value>
</data>
</root>

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -972,4 +972,10 @@
<data name="FixCrywolfGateTerrainUpdatePlugIn_Description" xml:space="preserve">
<value>Macht den südlichen Zugang zum Tor der Festung Crywolf im Tal von Loren begehbar, den Spieler außerhalb der Burgbelagerung benutzen. Der nördliche Zugang und alle anderen Felder bleiben unverändert.</value>
</data>
<data name="AddGladiatorsHonorUpdatePlugIn_Name" xml:space="preserve">
<value>Ehre des Gladiators hinzufügen</value>
</data>
<data name="AddGladiatorsHonorUpdatePlugIn_Description" xml:space="preserve">
<value>Dieses Update fügt die Ehre des Gladiators hinzu, welche die Erfahrung in Vulcanus 30 Minuten lang um 20 % erhöht.</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -456,4 +456,10 @@
<data name="AddProtectionTalismansUpdatePlugIn_Description" xml:space="preserve"><value>This update adds the Talisman of Guardian, which protects from the death penalty, and the Talisman of Item Protection, which keeps the durability of the equipped items.</value></data>
<data name="FixCrywolfGateTerrainUpdatePlugIn_Name" xml:space="preserve"><value>Fix the Crywolf entrance in Valley of Loren</value></data>
<data name="FixCrywolfGateTerrainUpdatePlugIn_Description" xml:space="preserve"><value>Makes the south entry of the gate to Crywolf Fortress in Valley of Loren walkable, which players use outside of Castle Siege. The north entry and all other tiles are kept.</value></data>
<data name="AddGladiatorsHonorUpdatePlugIn_Name" xml:space="preserve">
<value>Add the Gladiator's Honor</value>
</data>
<data name="AddGladiatorsHonorUpdatePlugIn_Description" xml:space="preserve">
<value>This update adds the Gladiator's Honor, which increases the experience in Vulcanus by 20 % for 30 minutes.</value>
</data>
</root>
Loading
Loading