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
36 changes: 36 additions & 0 deletions docs/Packets/C1-D1-00-KanturuStateInfo_by-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# C1 D1 00 - KanturuStateInfo (by server)

## Is sent when

The player requests state information from the Kanturu gateway NPC.

## Causes the following actions on the client side

The client shows the Kanturu entry dialog (INTERFACE_KANTURU2ND_ENTERNPC) with event state, detail state, whether entry is possible, current player count and remaining time.

## Structure

| Index | Length | Data Type | Value | Description |
|-------|--------|-----------|-------|-------------|
| 0 | 1 | Byte | 0xC1 | [Packet type](PacketTypes.md) |
| 1 | 1 | Byte | 12 | Packet header - length of the packet |
| 2 | 1 | Byte | 0xD1 | Packet header - packet type identifier |
| 3 | 1 | Byte | 0x00 | Packet header - sub packet type identifier |
| 4 | 1 | StateType | | State |
| 5 | 1 | Byte | | DetailState; Detail state; semantics depend on the main State field. See the game logic enums for per-state values. |
| 6 | 1 | Boolean | | CanEnter; 1 = entrance is open (Enter button enabled); 0 = entrance closed. |
| 7 | 1 | Byte | | UserCount; Number of players currently inside the event map (capped at 255). |
| 8 | 4 | IntegerLittleEndian | | RemainSeconds; Remaining time in seconds. Standby: seconds until event opens. Tower: seconds the tower has been open. Otherwise 0. |

### StateType Enum

Main state of the Kanturu event, matching the client KANTURU_STATE_TYPE enum.

| Value | Name | Description |
|-------|------|-------------|
| 0 | None | No active state. |
| 1 | Standby | Waiting for players to enter before the event starts. |
| 2 | MayaBattle | Maya battle phase covering Phases 1 through 3 and their boss waves. |
| 3 | NightmareBattle | Nightmare battle phase after all three Maya phases are cleared. |
| 4 | Tower | Tower of Refinement phase; opens after Nightmare is defeated. |
| 5 | End | Event has ended. |
28 changes: 28 additions & 0 deletions docs/Packets/C1-D1-01-KanturuEnterResult_by-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# C1 D1 01 - KanturuEnterResult (by server)

## Is sent when

The player attempted to enter the Kanturu event through the gateway NPC.

## Causes the following actions on the client side

The client closes the NPC animation and shows an error popup on failure. On success the player has already been teleported to the event map.

## Structure

| Index | Length | Data Type | Value | Description |
|-------|--------|-----------|-------|-------------|
| 0 | 1 | Byte | 0xC1 | [Packet type](PacketTypes.md) |
| 1 | 1 | Byte | 5 | Packet header - length of the packet |
| 2 | 1 | Byte | 0xD1 | Packet header - packet type identifier |
| 3 | 1 | Byte | 0x01 | Packet header - sub packet type identifier |
| 4 | 1 | EnterResult | | Result |

### EnterResult Enum

Result of the Kanturu enter request.

| Value | Name | Description |
|-------|------|-------------|
| 0 | Failed | Entry failed (generic failure). |
| 1 | Success | The player has been successfully entered into the event. |
33 changes: 33 additions & 0 deletions docs/Packets/C1-D1-03-KanturuStateChange_by-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# C1 D1 03 - KanturuStateChange (by server)

## Is sent when

The Kanturu event transitions to a new phase or sub-phase.

## Causes the following actions on the client side

The client shows or hides the in-map HUD, switches background music, and when entering the Tower state reloads the barrier-open terrain file (EncTerrain_n_01.att) to visually remove the Elphis barrier.

## Structure

| Index | Length | Data Type | Value | Description |
|-------|--------|-----------|-------|-------------|
| 0 | 1 | Byte | 0xC1 | [Packet type](PacketTypes.md) |
| 1 | 1 | Byte | 6 | Packet header - length of the packet |
| 2 | 1 | Byte | 0xD1 | Packet header - packet type identifier |
| 3 | 1 | Byte | 0x03 | Packet header - sub packet type identifier |
| 4 | 1 | StateType | | State; Refers to the KanturuStateInfo.StateType enum values. |
| 5 | 1 | Byte | | DetailState; Detail state within the main state. Maya battle: 0=none, 2=notify, 3=monster1, 4=maya1, 8=monster2, 9=maya2, 13=monster3, 14=maya3, 16=endcycle. Nightmare: 0=none, 1=idle, 2=intro, 3=battle, 4=end. Tower: 0=none, 1=revitalization, 2=notify, 3=close. |

### StateType Enum

Main state; see KanturuStateInfo.StateType for value descriptions.

| Value | Name | Description |
|-------|------|-------------|
| 0 | None | No active state. |
| 1 | Standby | Standby phase; the event is waiting for players to enter. |
| 2 | MayaBattle | Maya battle phase, which consists of three monster waves and the boss fights against her hands. |
| 3 | NightmareBattle | Nightmare battle phase after all three Maya phases are cleared. |
| 4 | Tower | Tower of Refinement phase; opens after Nightmare is defeated. |
| 5 | End | Event has ended. |
28 changes: 28 additions & 0 deletions docs/Packets/C1-D1-04-KanturuBattleResult_by-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# C1 D1 04 - KanturuBattleResult (by server)

## Is sent when

The Kanturu event ends with a victory or defeat outcome.

## Causes the following actions on the client side

The client displays the Success_kantru.tga overlay on victory or the Failure_kantru.tga overlay on defeat.

## Structure

| Index | Length | Data Type | Value | Description |
|-------|--------|-----------|-------|-------------|
| 0 | 1 | Byte | 0xC1 | [Packet type](PacketTypes.md) |
| 1 | 1 | Byte | 5 | Packet header - length of the packet |
| 2 | 1 | Byte | 0xD1 | Packet header - packet type identifier |
| 3 | 1 | Byte | 0x04 | Packet header - sub packet type identifier |
| 4 | 1 | BattleResult | | Result |

### BattleResult Enum

Outcome of the Kanturu battle.

| Value | Name | Description |
|-------|------|-------------|
| 0 | Failure | The event ended in failure; shows Failure_kantru.tga. |
| 1 | Victory | Nightmare was defeated; shows Success_kantru.tga. |
19 changes: 19 additions & 0 deletions docs/Packets/C1-D1-05-KanturuTimeLimit_by-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# C1 D1 05 - KanturuTimeLimit (by server)

## Is sent when

A timed phase begins in the Kanturu event.

## Causes the following actions on the client side

The client starts a countdown timer shown in the Kanturu HUD. The value is divided by 1000 to obtain seconds.

## Structure

| Index | Length | Data Type | Value | Description |
|-------|--------|-----------|-------|-------------|
| 0 | 1 | Byte | 0xC1 | [Packet type](PacketTypes.md) |
| 1 | 1 | Byte | 8 | Packet header - length of the packet |
| 2 | 1 | Byte | 0xD1 | Packet header - packet type identifier |
| 3 | 1 | Byte | 0x05 | Packet header - sub packet type identifier |
| 4 | 4 | IntegerLittleEndian | | TimeLimitMilliseconds; Countdown duration in milliseconds. |
30 changes: 30 additions & 0 deletions docs/Packets/C1-D1-06-KanturuMayaWideAreaAttack_by-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# C1 D1 06 - KanturuMayaWideAreaAttack (by server)

## Is sent when

The Maya body executes a wide-area attack during the Maya battle phase.

## Causes the following actions on the client side

The client calls MayaSceneMayaAction(type) which plays one of two visual sequences on the Maya body model: storm (0) or stone-rain (1). This is a purely cosmetic packet — damage is handled server-side.

## Structure

| Index | Length | Data Type | Value | Description |
|-------|--------|-----------|-------|-------------|
| 0 | 1 | Byte | 0xC1 | [Packet type](PacketTypes.md) |
| 1 | 1 | Byte | 7 | Packet header - length of the packet |
| 2 | 1 | Byte | 0xD1 | Packet header - packet type identifier |
| 3 | 1 | Byte | 0x06 | Packet header - sub packet type identifier |
| 4 | 1 | Byte | | ObjClassH; High byte of the Maya object class; ignored by the client. |
| 5 | 1 | Byte | | ObjClassL; Low byte of the Maya object class; ignored by the client. |
| 6 | 1 | AttackType | | Type |

### AttackType Enum

Visual type of the Maya wide-area attack.

| Value | Name | Description |
|-------|------|-------------|
| 0 | Storm | Stone-storm effect (MODEL_STORM3 plus falling debris around the hero). |
| 1 | Rain | Stone-rain effect (MODEL_MAYASTONE projectiles falling on the hero). |
20 changes: 20 additions & 0 deletions docs/Packets/C1-D1-07-KanturuMonsterUserCount_by-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# C1 D1 07 - KanturuMonsterUserCount (by server)

## Is sent when

A monster is killed or the player count changes during the Kanturu event.

## Causes the following actions on the client side

The client updates the monster count and user count numbers displayed in the Kanturu HUD.

## Structure

| Index | Length | Data Type | Value | Description |
|-------|--------|-----------|-------|-------------|
| 0 | 1 | Byte | 0xC1 | [Packet type](PacketTypes.md) |
| 1 | 1 | Byte | 6 | Packet header - length of the packet |
| 2 | 1 | Byte | 0xD1 | Packet header - packet type identifier |
| 3 | 1 | Byte | 0x07 | Packet header - sub packet type identifier |
| 4 | 1 | Byte | | MonsterCount; Number of monsters still alive in the current wave (capped at 255). |
| 5 | 1 | Byte | | UserCount; Number of players currently inside the event map (capped at 255). |
7 changes: 7 additions & 0 deletions docs/Packets/ServerToClient.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,13 @@
* [C1 C8 - RemoveLetter (by server)](C1-C8-RemoveLetter_by-server.md)
* [C3 CA - ChatRoomConnectionInfo (by server)](C3-CA-ChatRoomConnectionInfo_by-server.md)
* [C3 CB - FriendInvitationResult (by server)](C3-CB-FriendInvitationResult_by-server.md)
* [C1 D1 00 - KanturuStateInfo (by server)](C1-D1-00-KanturuStateInfo_by-server.md)
* [C1 D1 01 - KanturuEnterResult (by server)](C1-D1-01-KanturuEnterResult_by-server.md)
* [C1 D1 03 - KanturuStateChange (by server)](C1-D1-03-KanturuStateChange_by-server.md)
* [C1 D1 04 - KanturuBattleResult (by server)](C1-D1-04-KanturuBattleResult_by-server.md)
* [C1 D1 05 - KanturuTimeLimit (by server)](C1-D1-05-KanturuTimeLimit_by-server.md)
* [C1 D1 06 - KanturuMayaWideAreaAttack (by server)](C1-D1-06-KanturuMayaWideAreaAttack_by-server.md)
* [C1 D1 07 - KanturuMonsterUserCount (by server)](C1-D1-07-KanturuMonsterUserCount_by-server.md)
* [C1 D4 - ObjectWalked (by server)](C1-D4-ObjectWalked_by-server.md)
* [C1 D4 - ObjectWalkedExtended (by server)](C1-D4-ObjectWalkedExtended_by-server.md)
* [C1 DE 00 - CharacterClassCreationUnlock (by server)](C1-DE-00-CharacterClassCreationUnlock_by-server.md)
Expand Down
5 changes: 5 additions & 0 deletions src/DataModel/Configuration/MiniGameType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,9 @@ public enum MiniGameType
/// The doppelganger event.
/// </summary>
Doppelganger,

/// <summary>
/// The Kanturu Refinery Tower event.
/// </summary>
Kanturu,
}
6 changes: 5 additions & 1 deletion src/GameLogic/GameContext.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// <copyright file="GameContext.cs" company="MUnique">
// <copyright file="GameContext.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>

Expand All @@ -10,6 +10,7 @@ namespace MUnique.OpenMU.GameLogic;
using System.Globalization;
using System.Threading;
using MUnique.OpenMU.GameLogic.MiniGames;
using MUnique.OpenMU.GameLogic.MiniGames.Kanturu;
using MUnique.OpenMU.GameLogic.PlugIns;
using MUnique.OpenMU.GameLogic.Views;
using MUnique.OpenMU.Interfaces;
Expand Down Expand Up @@ -283,6 +284,9 @@ public async ValueTask<MiniGameContext> GetMiniGameAsync(MiniGameDefinition mini
case MiniGameType.BloodCastle:
miniGameContext = new BloodCastleContext(miniGameKey, miniGameDefinition, this, this._mapInitializer);
break;
case MiniGameType.Kanturu:
miniGameContext = new KanturuContext(miniGameKey, miniGameDefinition, this, this._mapInitializer);
break;
default:
miniGameContext = new MiniGameContext(miniGameKey, miniGameDefinition, this, this._mapInitializer);
break;
Expand Down
93 changes: 93 additions & 0 deletions src/GameLogic/MiniGames/Kanturu/IKanturuEventViewPlugIn.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// <copyright file="IKanturuEventViewPlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>

namespace MUnique.OpenMU.GameLogic.MiniGames.Kanturu;

using MUnique.OpenMU.GameLogic.Views;

/// <summary>
/// View plugin interface for Kanturu-specific server-to-client packets (0xD1 group).
/// Each method maps to one packet subcode.
/// </summary>
public interface IKanturuEventViewPlugIn : IViewPlugIn
{
/// <summary>
/// Shows packet 0xD1/0x00 — Kanturu state info (response to NPC talk / info request).
/// This opens the <c>INTERFACE_KANTURU2ND_ENTERNPC</c> dialog on the client, showing
/// the current event state, how many players are inside, and whether entry is possible.
/// </summary>
/// <param name="state">Main event state.</param>
/// <param name="detailState">Detail state for the current main state.</param>
/// <param name="canEnter">True if entrance is open (Enter button enabled).</param>
/// <param name="userCount">Number of players currently inside the event map.</param>
/// <param name="remainTime">
/// Remaining time. Semantics depend on state:
/// Standby → time until the event opens (client shows minutes).
/// Tower → time the tower has been open (client shows hours).
/// Otherwise zero.
/// </param>
ValueTask ShowStateInfoAsync(KanturuState state, byte detailState, bool canEnter, int userCount, TimeSpan remainTime);

/// <summary>
/// Shows packet 0xD1/0x01 — Kanturu enter result.
/// Sent after the player's entry attempt is processed.
/// On the client side this stops the NPC animation and closes the dialog.
/// On success the player is teleported before this is sent.
/// </summary>
/// <param name="success">True if the player was successfully entered; false otherwise.</param>
ValueTask ShowEnterResultAsync(bool success);

/// <summary>
/// Shows packet 0xD1/0x03 — Kanturu state change.
/// On the client side this:
/// - Shows/hides the in-map HUD (<c>INTERFACE_KANTURU_INFO</c>).
/// - Switches background music (Maya, Nightmare, Tower themes).
/// - When <paramref name="state"/> == <see cref="KanturuState.Tower"/> and
/// <paramref name="detailState"/> is <see cref="KanturuTowerDetailState.Revitalization"/> or <see cref="KanturuTowerDetailState.Notify"/>,
/// reloads the success terrain file (<c>EncTerrain&lt;n&gt;01.att</c>), which visually removes the Elphis barrier.
/// </summary>
/// <param name="state">Main state.</param>
/// <param name="detailState">Detail state for the current main state.</param>
ValueTask ShowStateChangeAsync(KanturuState state, byte detailState);

/// <summary>
/// Shows packet 0xD1/0x04 — Kanturu battle result.
/// <list type="bullet">
/// <item>False = failure — shows <c>Failure_kantru.tga</c> overlay.</item>
/// <item>True = success — shows <c>Success_kantru.tga</c> overlay
/// (only when client state is already <see cref="KanturuState.NightmareBattle"/>).</item>
/// </list>
/// </summary>
/// <param name="victory">True if the event was won; false if defeated.</param>
ValueTask ShowBattleResultAsync(bool victory);

/// <summary>
/// Shows packet 0xD1/0x05 — countdown timer for the Kanturu HUD.
/// The HUD divides by 1000 to get seconds and counts down visually.
/// </summary>
/// <param name="timeLimit">The time limit to display.</param>
ValueTask ShowTimeLimitAsync(TimeSpan timeLimit);

/// <summary>
/// Shows packet 0xD1/0x07 — remaining monster count and current user count.
/// Updates the numbers displayed in the Kanturu HUD.
/// </summary>
/// <param name="monsterCount">Number of monsters still alive in the current wave.</param>
/// <param name="userCount">Number of players currently inside the event map.</param>
ValueTask ShowMonsterUserCountAsync(int monsterCount, int userCount);

/// <summary>
/// Shows packet 0xD1/0x06 — Maya wide-area attack visual trigger.
/// The client calls <c>MayaSceneMayaAction(attackType)</c> on receipt, which plays
/// one of two client-side visual sequences on the Maya body object:
/// <list type="bullet">
/// <item>Storm (true) = stone-storm effect (<c>MODEL_STORM3</c> + falling debris around Hero)</item>
/// <item>Rain (false) = stone-rain effect (<c>MODEL_MAYASTONE</c> projectiles falling on Hero)</item>
/// </list>
/// This is a purely cosmetic broadcast — damage is handled by the server-side
/// <see cref="MonsterDefinition.AttackSkill"/> on Maya Hands (#362/#363).
/// </summary>
/// <param name="isStorm">True for storm visual; false for stone-rain visual.</param>
ValueTask ShowMayaWideAreaAttackAsync(bool isStorm);
}
Loading
Loading