feat(items): add Imperial Sword (0/50) and Imperial Staff (5/50)

Two new weapons placed at free item slots so they never collide with
standard Season 6 items. The client name DB (Item_eng.bmd) is the source
of tooltip name/stats, so only free slots are usable for custom items.

Both seed paths are covered:
- Fresh DB: Weapons.Initialize() calls the new CreateImperialWeapons050().
- Existing DB: AddImperialWeapons050UpdateSeason6 (UpdateVersion 95),
  applied from the AdminPanel Updates page, with an idempotency guard.

Imperial Sword is a Magic Gladiator weapon (copy of 0/28), Imperial Staff
is a Wizard weapon (copy of 5/31).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Acentech Dev
2026-07-16 22:03:08 +03:00
parent fbe75d55be
commit ef3bffe39c
3 changed files with 83 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
// <copyright file="AddImperialWeapons050UpdateSeason6.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Persistence.Initialization.Updates;
using System.Runtime.InteropServices;
using MUnique.OpenMU.DataModel.Configuration;
using MUnique.OpenMU.Persistence.Initialization.VersionSeasonSix.Items;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// Adds two new weapons at item number 50: Imperial Sword (group 0, Magic Gladiator) and
/// Imperial Staff (group 5, Wizard), as full working weapons (damage, attack speed, requirements,
/// options, equip flags). Placed at free slots so they never collide with standard items.
/// </summary>
[PlugIn]
[Display(Name = PlugInName, Description = PlugInDescription)]
[Guid("BE9DD7D1-F352-4C56-A646-D78C36978982")]
public class AddImperialWeapons050UpdateSeason6 : UpdatePlugInBase
{
internal const string PlugInName = "Add Imperial Weapons (0/50, 5/50)";
internal const string PlugInDescription = "Adds Imperial Sword (0/50) and Imperial Staff (5/50) as fully working weapons.";
/// <inheritdoc />
public override UpdateVersion Version => UpdateVersion.AddImperialWeapons050Season6;
/// <inheritdoc />
public override string DataInitializationKey => VersionSeasonSix.DataInitialization.Id;
/// <inheritdoc />
public override string Name => PlugInName;
/// <inheritdoc />
public override string Description => PlugInDescription;
/// <inheritdoc />
public override bool IsMandatory => true;
/// <inheritdoc />
public override DateTime CreatedAt => new(2026, 07, 16, 12, 0, 0, DateTimeKind.Utc);
/// <inheritdoc />
#pragma warning disable CS1998
protected override async ValueTask ApplyAsync(IContext context, GameConfiguration gameConfiguration)
#pragma warning restore CS1998
{
// Idempotency guard: skip if the Imperial Sword 0/50 already exists.
if (gameConfiguration.Items.Any(i => i.Group == 0 && i.Number == 50))
{
return;
}
new Weapons(context, gameConfiguration).CreateImperialWeapons050();
}
}

View File

@@ -479,4 +479,9 @@ public enum UpdateVersion
/// The version of the <see cref="AddIsQuestItemFlagPlugIn"/>.
/// </summary>
AddIsQuestItemFlag = 94,
/// <summary>
/// The version of the <see cref="AddImperialWeapons050UpdateSeason6"/>.
/// </summary>
AddImperialWeapons050Season6 = 95,
}

View File

@@ -269,6 +269,9 @@ internal class Weapons : InitializerBase
this.CreateWeapon(5, 34, 0, 0, 1, 4, false, "Raven Stick", 147, 70, 78, 30, 98, 130, 0, 50, 14, 0, 0, 0, 0, 0, 0, 0, 2, 0);
this.CreateWeapon(5, 36, 0, 0, 1, 4, false, "Divine Stick of Archangel", 104, 153, 165, 30, 182, 146, 0, 55, 13, 0, 0, 0, 0, 0, 0, 0, 1, 0);
// ADAMU-CUSTOM: new Imperial weapons at free slots (fresh-DB seed path; existing DBs get them via AddImperialWeapons050UpdateSeason6).
this.CreateImperialWeapons050();
this.AddGuardianOptions();
}
@@ -522,6 +525,25 @@ internal class Weapons : InitializerBase
}
}
/// <summary>
/// Creates only the two new "Imperial" weapons at item number 50 (Imperial Sword 0/50 and
/// Imperial Staff 5/50), reusing <see cref="CreateWeapon"/> and the already-persisted
/// item level bonus tables (looked up by name). Intended for a configuration update
/// plug-in running against an existing database, so it does NOT recreate the tables.
/// </summary>
public void CreateImperialWeapons050()
{
this._weaponDamageIncreaseTable = this.GameConfiguration.ItemLevelBonusTables.First(t => t.Name == "Damage Increase (Weapons)");
this._staffRiseTableEven = this.GameConfiguration.ItemLevelBonusTables.First(t => t.Name == "Staff Rise (even)");
this._staffRiseTableOdd = this.GameConfiguration.ItemLevelBonusTables.First(t => t.Name == "Staff Rise (odd)");
// Imperial Sword (copy of 0/28, Magic Gladiator) at number 50.
this.CreateWeapon(0, 50, 0, 56, 1, 4, true, "Imperial Sword", 139, 98, 122, 45, 90, 109, 380, 91, 73, 17, 0, 0, 0, 0, 1, 0, 0, 0);
// Imperial Staff (copy of 5/31, Wizard) at number 50.
this.CreateWeapon(5, 50, 0, 0, 1, 4, true, "Imperial Staff", 137, 57, 61, 30, 182, 124, 380, 48, 14, 0, 0, 2, 0, 0, 0, 0, 0, 0);
}
private void AddGuardianOptions()
{
var weaponOption = this.GameConfiguration.ItemOptions.First(io => io.PossibleOptions.Any(po => po.OptionType == ItemOptionTypes.GuardianOption && po.Number == (int)ItemGroups.Weapon));