feat(hs): web-applicable update plugin for the Heykel Savasi event
AddHeykelSavasiEventUpdateSeason6 (version 100): adds map 92 + terrain, statue/guard monsters, red/blue base gates, event NPC 560 in Lorencia, and the mini-game definition to an EXISTING config via the admin Updates page (no DB wipe). Reuses HeykelSavasiMap/HeykelSavasiInitializer; idempotent. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
// <copyright file="AddHeykelSavasiEventUpdateSeason6.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.Events;
|
||||
using MUnique.OpenMU.Persistence.Initialization.VersionSeasonSix.Maps;
|
||||
using MUnique.OpenMU.PlugIns;
|
||||
|
||||
/// <summary>
|
||||
/// Adds the Heykel Savasi team event data to an existing configuration: the imported LoL arena map
|
||||
/// (server number 92 / client World93) with its terrain, the statue (561) and guard (580) monster
|
||||
/// definitions, the red/blue base spawn gates, the event NPC (560) placed in Lorencia, and the
|
||||
/// mini-game definition. The event logic (context, packet handlers, chat commands, buffs) ships in
|
||||
/// the game-logic assemblies and needs no configuration update.
|
||||
/// </summary>
|
||||
[PlugIn]
|
||||
[Display(Name = PlugInName, Description = PlugInDescription)]
|
||||
[Guid("F2A7C4D9-3E1B-4A86-9C0D-5B7E2A1F8D42")]
|
||||
public class AddHeykelSavasiEventUpdateSeason6 : UpdatePlugInBase
|
||||
{
|
||||
internal const string PlugInName = "Add Heykel Savasi event (map 92)";
|
||||
|
||||
internal const string PlugInDescription = "Adds the Heykel Savasi team-vs-team event: the LoL arena map (server 92 / World93) with terrain, statue+guard monsters, red/blue base spawn gates, the event NPC (560) in Lorencia, and the mini-game definition.";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override UpdateVersion Version => UpdateVersion.AddHeykelSavasiEventSeason6;
|
||||
|
||||
/// <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, 21, 12, 0, 0, DateTimeKind.Utc);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override async ValueTask ApplyAsync(IContext context, GameConfiguration gameConfiguration)
|
||||
{
|
||||
// Idempotency guard: skip if the Heykel Savasi map (92) already exists.
|
||||
if (gameConfiguration.Maps.Any(m => m.Number == HeykelSavasiMap.Number))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. Map (No 92) + terrain (Terrain93.att) + statue (561) / guard (580) monster definitions.
|
||||
var mapInitializer = new HeykelSavasiMap(context, gameConfiguration);
|
||||
mapInitializer.Initialize();
|
||||
mapInitializer.SetSafezoneMap();
|
||||
|
||||
var map = gameConfiguration.Maps.First(m => m.Number == HeykelSavasiMap.Number);
|
||||
|
||||
// 2. Host the map on every game server configuration (fresh seeds do this automatically,
|
||||
// but existing databases need it added explicitly).
|
||||
var serverConfigs = await context.GetAsync<GameServerConfiguration>().ConfigureAwait(false);
|
||||
foreach (var serverConfig in serverConfigs)
|
||||
{
|
||||
if (serverConfig.Maps.All(m => m.Number != HeykelSavasiMap.Number))
|
||||
{
|
||||
serverConfig.Maps.Add(map);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Red/Blue base spawn gates. The X1/Y1 anchors MUST match HeykelSavasiContext.GetTeamSpawnGate
|
||||
// (Red = 42,10 top tip of the arena diamond; Blue = 42,92 bottom tip).
|
||||
var redBase = context.CreateNew<ExitGate>();
|
||||
map.ExitGates.Add(redBase);
|
||||
redBase.Map = map;
|
||||
redBase.X1 = 42;
|
||||
redBase.Y1 = 10;
|
||||
redBase.X2 = 42;
|
||||
redBase.Y2 = 10;
|
||||
redBase.Direction = Direction.South;
|
||||
redBase.IsSpawnGate = true;
|
||||
|
||||
var blueBase = context.CreateNew<ExitGate>();
|
||||
map.ExitGates.Add(blueBase);
|
||||
blueBase.Map = map;
|
||||
blueBase.X1 = 42;
|
||||
blueBase.Y1 = 92;
|
||||
blueBase.X2 = 42;
|
||||
blueBase.Y2 = 92;
|
||||
blueBase.Direction = Direction.North;
|
||||
blueBase.IsSpawnGate = true;
|
||||
|
||||
// 4. Event NPC (560) placed in Lorencia.
|
||||
if (gameConfiguration.Monsters.All(m => m.Number != 560))
|
||||
{
|
||||
var npc = context.CreateNew<MonsterDefinition>();
|
||||
gameConfiguration.Monsters.Add(npc);
|
||||
npc.Number = 560;
|
||||
npc.Designation = "Heykel Savasi Gorevlisi";
|
||||
npc.NpcWindow = NpcWindow.Undefined;
|
||||
npc.ObjectKind = NpcObjectKind.PassiveNpc;
|
||||
npc.SetGuid(npc.Number);
|
||||
|
||||
var lorencia = gameConfiguration.Maps.First(m => m.Number == Lorencia.Number);
|
||||
var spawn = context.CreateNew<MonsterSpawnArea>();
|
||||
lorencia.MonsterSpawns.Add(spawn);
|
||||
spawn.GameMap = lorencia;
|
||||
spawn.MonsterDefinition = npc;
|
||||
spawn.Quantity = 1;
|
||||
spawn.X1 = 140;
|
||||
spawn.X2 = 140;
|
||||
spawn.Y1 = 120;
|
||||
spawn.Y2 = 120;
|
||||
spawn.Direction = Direction.SouthEast;
|
||||
spawn.SpawnTrigger = SpawnTrigger.Automatic;
|
||||
}
|
||||
|
||||
// 5. Mini-game definition (its Entrance references a spawn gate on the map -> after step 3).
|
||||
new HeykelSavasiInitializer(context, gameConfiguration).Initialize();
|
||||
}
|
||||
}
|
||||
@@ -504,4 +504,9 @@ public enum UpdateVersion
|
||||
/// The version of the <see cref="AddWarriorWingsUpdateSeason6"/> (Warrior Wings/Cape 12/242-247).
|
||||
/// </summary>
|
||||
AddWarriorWingsSeason6 = 99,
|
||||
|
||||
/// <summary>
|
||||
/// The version of the <see cref="AddHeykelSavasiEventUpdateSeason6"/> (Heykel Savasi team event: map 92, NPC 560, mini game definition).
|
||||
/// </summary>
|
||||
AddHeykelSavasiEventSeason6 = 100,
|
||||
}
|
||||
Reference in New Issue
Block a user