feat: Add Kanturu Refinery Tower event (resubmission of #719) - #923
Open
sven-n wants to merge 7 commits into
Open
feat: Add Kanturu Refinery Tower event (resubmission of #719)#923sven-n wants to merge 7 commits into
sven-n wants to merge 7 commits into
Conversation
Resubmits the work of PR #719 (by @apraxico) together with the fixes contributed by @foxtnaider on top of the current master. Contents: - KanturuContext with the eight event phases, Maya hands, Nightmare boss and the Tower of Refinement phase - View plug-in, packet handlers and packet definitions for the D1 packet group - Periodic start plug-in and configuration - Season 6 initializer, map spawn definitions and configuration update plug-ins for existing databases Fixes taken from the follow-up work: - Kanturu packets are defined inside <Packets> so the XSLT generator emits the connection extensions instead of them being hand-written - GameContext creates a KanturuContext for MiniGameType.Kanturu Co-Authored-By: apraxico <80994201+apraxico@users.noreply.github.com> Co-Authored-By: foxtnaider <46683504+foxtnaider@users.noreply.github.com> Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6STKnRbNYW5JPSuNXNFx4
Follow-up on the resubmitted work of #719: - Resolve all analyzer warnings the new files introduced (SA1201, SA1204, SA1210, SA1501, SA1515, SA1525, SA1611, SA1623, SA1117, VSTHRD200, CS1574). - Apply the configured KanturuStartConfiguration.TowerOfRefinementDuration: it was only settable, the context always used its hard-coded default, because GameContext creates the context without the optional parameter. The context now reads the value from the start plug-in's configuration. - Move the Kanturu state enums into their own file, so the view plug-in interface file only contains the interface. - Document the KanturuStateChange.StateType enum values in the packet definition, which removes six CS1591 warnings from the generated code. - Share the event wave spawns between the map initializer and AddKanturuMapContentUpdatePlugIn instead of maintaining two copies of the same 16 spawn areas, and name the monster numbers. - Use localized plug-in names/descriptions (PlugInResources) for the new GameServer plug-ins, like all other plug-ins there. - Restore the byte order mark of the two touched Season 6 files and fix the Nightmare spawn coordinates in the map comments. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6STKnRbNYW5JPSuNXNFx4
ServerToClientPacketTests.cs is generated from ServerToClientPackets.xml and checked in. As long as the Kanturu packets were outside <Packets>, the generator skipped them, so the file didn't contain their tests. Now that they are inside, it does. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6STKnRbNYW5JPSuNXNFx4
The comment line ended with a semicolon and started with a method name, so SonarCSharp_S125 flagged it as commented out code (the one issue Codacy reported on this PR). Same meaning, different wording. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6STKnRbNYW5JPSuNXNFx4
Addresses the review of the Kanturu event. Own sub-namespace, one type per file: All Kanturu game logic moved into MUnique.OpenMU.GameLogic.MiniGames.Kanturu. The four client state enums, which shared one file, now have their own. A configuration instead of hardcoded values: The run of the event is described by a KanturuEventDefinition, which is configured at the KanturuStartPlugIn and can therefore be changed in the admin panel without code changes. It holds the intro, the ordered list of phases and the settings of the Tower of Refinement. Each KanturuPhaseDefinition describes what the context previously had hardcoded in its game loop and in the switch of OnMonsterDied: the state which is sent to the clients, the spawn wave, the monsters which count towards the kill target, the time limit, the messages and the standby time after the phase. A KanturuPhaseKind selects how a phase is executed, so the three repeating shapes - monster wave, transition and boss fight - each exist once instead of once per phase. The boss fight gets its teleport positions and health thresholds from KanturuNightmareDefinition, the barrier areas and the Elphis coordinates come from the definition too. The game loop is now a foreach over the phases, and OnMonsterDied is a lookup in the current phase instead of a nine case switch. KanturuEventDefinition.Default describes the original season 6 event, so the behaviour is unchanged. Opened NPC check: The gateway plug-in now sets LeavesDialogOpen, so the player stays assigned to the Gateway Machine while its dialog is open. The 0xD1/0x00 and 0xD1/0x01 handlers check that assignment, like the castle siege handlers do, so the packets can't be used without talking to the NPC first. On a successful entry the assignment is cleared, because the client closes the dialog when it changes the map. Also adds the byte order mark to the Kanturu files which still missed it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6STKnRbNYW5JPSuNXNFx4
The phases and the boss fight referenced their monsters by number, which required the numbers to be looked up by hand. They now hold MonsterDefinition references instead, so the admin panel can offer the monsters for selection. The custom configuration of a plug-in is serialized with the ByDataSourceReferenceHandler, so the references are stored as the id of the monster and resolved from the game configuration when they are read - the same way the NpcChatCommandPlugIn references its merchant. Because ISupportDefaultCustomConfiguration.CreateDefaultConfig has no game configuration, it can't resolve the monsters. KanturuEventDefinition.Default therefore became CreateDefault(GameConfiguration), and the data initialization seeds the configuration of the start plug-in with it, like it already does for the BlessJewelConsumeHandlerPlugIn. For databases which have no configuration yet, the context falls back to CreateDefault with the game configuration it runs on, so the event works either way. The spawned monsters are compared to the configured definitions by their number, because the definition of a spawned monster can be a different instance than the configured one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6STKnRbNYW5JPSuNXNFx4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resubmission of the stale PR #719 by @apraxico, rebased onto the current
masterand combined with the fixes @foxtnaider contributed on hiskanturu-fixesbranch, plus a review pass on top.Credit for the implementation goes to @apraxico; credit for making it build and actually run goes to @foxtnaider, who tested the result end-to-end on a Season 6 server.
What it adds
The server-side logic for the Kanturu Refinery Tower mini-game (map 39), following the plug-in patterns of BloodCastle and ChaosCastle:
KanturuContextIKanturuEventViewPlugIn/KanturuStatesKanturuEventViewPlugInKanturuGatewayPlugInKanturuStartPlugIn/KanturuStartConfiguration/KanturuGameServerStateKanturuEnterRequestHandlerPlugIn/KanturuInfoRequestHandlerPlugIn/KanturuGroupHandlerPlugInKanturuInitializerMiniGameDefinitionAddKanturuDataUpdatePlugIn/AddKanturuMapContentUpdatePlugInModified:
MiniGameType(newKanturuvalue),GameContext(creates aKanturuContext),GameConfigurationInitializer,KanturuEvent(bosses and wave spawns), the server-to-client packet definitions and the player messages.Fixes carried over from the follow-up work
<Packet>elements were direct children of the root, outside<Packets>.GenerateExtensions.xsltonly iterates the children of<Packets>, so the generator emitted nothing for them and theSendKanturuXxxAsyncmethods had been added to the generatedConnectionExtensions.csby hand. A clean build overwrote them, which is theCS1061build failure reported on feat: Add Kanturu Refinery Tower event implementation #719. The elements are now inside<Packets>and everything is generated.GameContexthad nocase MiniGameType.Kanturu, so the event fell through to a plainMiniGameContext: it opened the map, accepted players and then did nothing.ObjClassH/ObjClassLarguments onSendKanturuMayaWideAreaAttackAsync(CS7036).Review pass in this PR
KanturuStartConfiguration.TowerOfRefinementDurationwas write-only:GameContextconstructs the context without the optional parameter, so the hard-coded one-hour default always won. The context now reads the value from the start plug-in's configuration.CS1591warnings in the generated packet code, which are fixed by documenting theKanturuStateChange.StateTypeenum values in the packet definition.KanturuEvent, once inAddKanturuMapContentUpdatePlugIn. They are now shared, and the monster numbers are named constants.PlugInResourcesnames and descriptions like the other plug-ins there.Verification
dotnet build src/Startup/MUnique.OpenMU.Startup.csproj— clean, from a fresh checkout, with the packet generator running: 0 errors, no warnings from the new files, and the generated files are byte-identical to what is committed.dotnet build ... -p:ci=true(what the CI workflow runs) — 0 errors.dotnet test tests/MUnique.OpenMU.Persistence.Initialization.Tests— 12 passed, 2 skipped.Closes #719.
Generated by Claude Code