Add the Raklion event (Battle of Selupan) - #977
Conversation
Defines the packets of the raklion event, as expected by the season 6 client: the state info, current state, state change (group 0xD1, 0x10 to 0x12) and battle result (0x13), and the monster skill animation (0x69), which the client uses to show the skills of Selupan. The client structures aren't packed, so the remaining seconds of the state info are aligned at offset 8, and the ids of the monster skill animation at offsets 6 and 8. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The hatchery of raklion (map 58) runs as a continuous event: the spider eggs appear, when they're destroyed Selupan appears, after some time the hatchery closes and only the players inside fight against Selupan. After the battle, the hatchery opens again. - RaklionPlugIn (feature + periodic task, configurable in the admin panel) - RaklionContext with the state machine of the event - SelupanIntelligence with the patterns by health, berserk and the skills - view plugin for the 0xD1 0x10-0x13 and 0x69 packets, D1 10 request handler - the monster spawns of the hatchery are spawned by the event (waves) - update plugin which adapts the spawns of existing databases Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The client searches the target of a monster skill by its id as it is, so the flag for a successful skill made it ignore the packet. The teleport of selupan moved it instantly, which the client shows as sliding; it's now a teleport. The attacks are used more often than the teleport. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Selupan vanishes with the effect of the teleport skill and appears at a diagonal position 3 to 6 fields away. It teleports a bit more often. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The messages are shown to all players of the game server, like the original game does, and the opening of the hatchery gate is announced. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Like the original game, only players which entered the hatchery while it was open may stay there; others are moved to the entrance of raklion. After the battle, the remaining players are moved out after a configurable time. The hatchery opens again after 12 hours by default (like IGCN), which is configurable as well. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- the event doesn't run without the monster spawns of the hatchery, instead of announcing Selupan without spawning it - selupan isn't teleported when it died while vanishing - dead summoned monsters are removed from the event - remove unused usings and an obsolete todo - test that the data update can be applied twice Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The result and the time until the hatchery opens are shown in one message, so that they don't replace each other on the screen, and in the chat, so that they can be read again. The time is shown in hours and minutes. Players which try to enter the closed hatchery after the battle are told when it opens again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- players in the hatchery while it's open are allowed to stay, even when the tick sees them before the event handler of the map registered them - players which left the hatchery aren't counted as battle players - monsters summoned while the battle ended are removed Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The Codacy findings are addressed, except S1128 (unnecessary The Azure build fails within 0 seconds, like on master and on the previous PRs, so it's the known issue of the build infrastructure. |
…ation The output buffer is reused, so the padding byte, which the client doesn't read, may contain data of a previous packet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Hey there! You can see in this source that: There is already a base skill multiplier of 2 in OpenMU. |
…iers Selupan attacked with a null skill, and in CalculateDamageAsync the whole multiplier block sits inside `if (skill != null)`. Its Stats.SkillMultiplier of 2 was therefore never read, and Poison, Ice Storm and Ice Strike all hit exactly the same. The three attack skills are now defined with an attribute relationship to Stats.SkillFinalMultiplier, and the intelligence passes their skill entry to the damage calculation. InputOperator.Maximum keeps the multipliers absolute, independent of the Stats.SkillMultiplier of the monster: Poison 2.0 Ice Storm 2.2 Ice Strike 2.3 The values are the ones of the original server, reported by ze-dom in the review of MUnique#977. The update plug-in adds the skills to existing databases, and the data test covers both a new and an updated database. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Thanks @ze-dom, that was a useful pointer. I looked into it and the gap turned out to be bigger than the multipliers themselves.
Fixed in 3959137: the three attack skills are now defined with an attribute relationship to
One detail worth mentioning: I used The update plug-in adds the skills to existing databases as well, and On skill 253: in this PR I left the magic effects out of this commit on purpose. Adding the elemental modifier without the accompanying effects would only route the damage through the players' resistances, which is half the picture. Happy to do it as a follow-up. The old TODO in |
Resolve the conflict of the update versions: AddItemRuleFlags (116) and AddDarkHorseCanFly (117) are on master, so AddRaklionEvent becomes 118. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MThSFvdPBdZUk1ew2x3WFW
sven-n
left a comment
There was a problem hiding this comment.
Review
I read the whole change: RaklionContext (state machine, hatchery access, summons), SelupanIntelligence, RaklionPlugIn, the packets, the view plugin and request handler, the data and update plugin, and the tests. I also built it and ran the tests locally. The code looks good.
Verified
- The full solution builds with no errors.
MUnique.OpenMU.Tests(1034),Network.Packets.Tests(607) andPersistence.Initialization.Tests(27, 6 skipped) all pass. - The
OnceAtWaveStartspawns don't respawn and aren't created at map creation, so the event fully controls eggs, Selupan and Coolutins. - A dead Selupan is removed and disposed by
AttackableNpcBase(it doesn't respawn), so the intelligence timer is released. Removing a live Selupan throughRemoveMonsterAsyncdisposes it too. MonsterAttributeHolder.AddElementhonours added elements over the static mappings. So invincibility (a ×0 element onDamageReceiveDecrement) and the berserk damage (on the physical base damage stats) take effect.- Skill multipliers: passing a
SkillEntryis what makesCalculateDamageAsyncapply a multiplier at all, so the fix in 3959137 is right. The update plugin skips skills that already exist, so running it twice is safe.
Blocking: merge conflict with master
#983 (AddItemRuleFlags = 116) and AddDarkHorseCanFly = 117 were merged, so AddRaklionEvent = 116 now conflicts in UpdateVersion.cs. The fix is AddRaklionEvent = 118. I resolved it with a merge commit on claude/pr-977-review-merge-2rzt3i (0ba2e66). The merged tree builds, and all tests pass (1047 / 607 / 32). I couldn't push to the fork's branch. @apraxico, please merge master (or cherry-pick that resolution) into feature/raklion-event. The PR description should then say version 118 instead of 116.
Non-blocking notes
InputOperator.Maximummakes the final multipliermax(SkillMultiplier, factor), not an absolute value. If Selupan'sSkillMultiplierwere raised above 2.3, all three skills would hit the same. That's fine for the current data, but the remark that the values "stay correct ifSkillMultiplierchanges" only holds while it stays at or below 2.0.- CI: Azure fails in 0s here and on master, so it's the known infrastructure issue. The remaining Codacy S1128 finding is a false positive, as noted above.
I'll merge once the conflict is resolved on the PR branch.
Generated by Claude Code
…ll multipliers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks for the review and for preparing the resolution, @sven-n!
|
|
Re-checked
Merging. Thanks @apraxico, and thanks @ze-dom for the multiplier pointer! Generated by Claude Code |
|
@apraxico yes, apparently when Selupan appears falling from the sky it can damage a target. |
Thanks for the video, @ze-dom, that settled it! The server sources agree: the fall hits every player closer than 4 fields to Selupan, with a multiplier of 2.5, and pushes them 4 fields away. Both are added in #994. Your pointer also led to more: the push of the frost shock, and a fix for the skill multipliers from this PR, which weren't applied when a monster attacked. Those are in #994 as well. |
Part of #23.
Summary
The Raklion hatchery (map 58) now runs the Selupan event, like the original game:
All times and values are configurable in the admin panel (plugin "Raklion Event").
Selupan
SelupanIntelligenceuses a skill every 1.5 seconds. Its pattern (1 to 7) depends on its remaining health(80/60/50/40/20/10 %). With each pattern, it gets additional damage (berserk) and more skills:
The poison and ice skills hit the players in an area with their damage multipliers of the original server
(2.0, 2.2 and 2.3). Simplifications: there is no poison damage over time and the players aren't pushed back.
Hatchery access
Like the original game, only players which entered the hatchery while it was open may stay there. Others,
e.g. players entering while it's closed, are moved to the entrance of Raklion. After the battle, the remaining
players are moved out after a configurable time (
PlayerRemovalDelay, 5 minutes by default). Unlike theoriginal game, game masters aren't exempt from these rules.
Changes
RaklionPlugIn(feature plugin with periodic task and custom configuration),RaklionContext(state machine),
SelupanIntelligence,RaklionEventDefinition,IRaklionEventViewPlugIn.Monster.TeleportAsync: new public method, so that a monster can be teleported (MoveType.Teleport)instead of moved instantly, which the client shows as sliding.
D1 10(state info),D1 11(current state),D1 12(state change),D1 13(battle result)and
69(monster skill animation, used for the skills of Selupan). The structures of the client aren'tpacked, so some fields are aligned (documented in the packet descriptions).
RaklionEventViewPlugInand the handler of the C2SD1 10request, which was defined but unhandled.2 = Selupan, 3 = Coolutins summoned by Selupan. They were automatic spawns before.
AddRaklionEventUpdatePlugIn(version 118, mandatory, idempotent): changes the automaticspawns of the hatchery of existing databases to the waves and adds the attack skills of Selupan (250 to 252) with
their damage multipliers. Without it, the event doesn't start and logs one warning.
the result of the battle and the time until the hatchery opens are shown in one new message, which is also written
to the chat, so that they don't replace each other on the screen.
Drops of Selupan are left to the configuration of each server (drop groups), like the difficulty.
Notes
configuration of public server files (IGCN). No code was copied or converted.
D1 10-D1 12; it ignoresD1 13, which is sent for completeness.MonsterSkillAnimation(0x69): the client searches the target by its id as it is, so the flag for a successfulskill (highest bit of the target id) isn't set.
Tests
Network.Packets.Tests), view plugin serialization, pattern/berserk/skill selection of the definition,data of a new database, and the update plugin (applied twice).
(all players died or left), the messages, the closed hatchery after the battle, the removal of the players and
the reopening.
🤖 Generated with Claude Code