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
48 changes: 48 additions & 0 deletions docs/Packets/C1-F7-02-ImperialGuardianEnterResult_by-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# C1 F7 02 - ImperialGuardianEnterResult (by server)

## Is sent when

The player requested to enter the imperial guardian event, or entered the next zone of it.

## Causes the following actions on the client side

The client shows a message when entering failed. On success, it remembers the day and zone for the timer and the result, and sets the weather of the map.

## 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 | 0xF7 | Packet header - packet type identifier |
| 3 | 1 | Byte | 0x02 | Packet header - sub packet type identifier |
| 4 | 1 | EnterResult | | Result; The result of the request. |
| 5 | 1 | Byte | | Day; The day of the week, from 1 (monday) to 7 (sunday). The client shows it as the round. |
| 6 | 1 | Byte | | Zone; The zone, starting at 1. |
| 7 | 1 | WeatherType | | Weather; The weather of the map. |
| 8 | 4 | IntegerLittleEndian | | RemainingMilliseconds; The remaining time in milliseconds. When the result is NotOpen, the client shows the minutes until the event can be entered. The field is aligned to 4 bytes, because the client structure is not packed. |

### EnterResult Enum

The result of an enter request.

| Value | Name | Description |
|-------|------|-------------|
| 0 | Success | The player entered the event. |
| 1 | NotOpen | The event can not be entered yet. |
| 2 | MissingTicket | The player has no Gaion's Order or Complete Secromicon. |
| 3 | Full | The zone is full. |
| 4 | ZoneTimeRemaining | There is still time remaining in this zone. |
| 5 | PartyRequired | The player can only enter as a member of a party. |
| 6 | CharacterLevelTooLow | The character level is too low. The client doesn't show a message. |

### WeatherType Enum

The weather of the map.

| Value | Name | Description |
|-------|------|-------------|
| 0 | Sun | The sun shines. |
| 1 | Rain | It rains. |
| 2 | Fog | There is fog. |
| 3 | Storm | There is a storm. |
31 changes: 31 additions & 0 deletions docs/Packets/C1-F7-04-ImperialGuardianTimer_by-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# C1 F7 04 - ImperialGuardianTimer (by server)

## Is sent when

Every second during the imperial guardian event.

## Causes the following actions on the client side

The client shows the timer with the remaining time and the number of remaining monsters. The client doesn't count down the time by itself.

## Structure

| Index | Length | Data Type | Value | Description |
|-------|--------|-----------|-------|-------------|
| 0 | 1 | Byte | 0xC1 | [Packet type](PacketTypes.md) |
| 1 | 1 | Byte | 16 | Packet header - length of the packet |
| 2 | 1 | Byte | 0xF7 | Packet header - packet type identifier |
| 3 | 1 | Byte | 0x04 | Packet header - sub packet type identifier |
| 4 | 1 | TimerType | | Type; The type of the timer. |
| 8 | 4 | IntegerLittleEndian | | RemainingMilliseconds; The remaining time in milliseconds. The field is aligned to 4 bytes, because the client structure is not packed. |
| 12 | 1 | Byte | | MonsterCount; The number of remaining monsters. |

### TimerType Enum

The type of the timer.

| Value | Name | Description |
|-------|------|-------------|
| 0 | LootTime | The time to collect the loot. |
| 1 | Standby | The time until the monsters appear. |
| 2 | TimeAttack | The time to kill the monsters. |
30 changes: 30 additions & 0 deletions docs/Packets/C1-F7-06-ImperialGuardianResult_by-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# C1 F7 06 - ImperialGuardianResult (by server)

## Is sent when

A zone of the imperial guardian event has been cleared, or the event ended.

## Causes the following actions on the client side

The client shows the result and hides the timer.

## 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 | 0xF7 | Packet header - packet type identifier |
| 3 | 1 | Byte | 0x06 | Packet header - sub packet type identifier |
| 4 | 1 | ResultType | | Result; The result. |
| 8 | 4 | IntegerLittleEndian | | Experience; The rewarded experience, when the event has been completed. The field is aligned to 4 bytes, because the client structure is not packed. |

### ResultType Enum

The result of the imperial guardian event.

| Value | Name | Description |
|-------|------|-------------|
| 0 | Failed | The event failed. |
| 1 | ZoneCleared | The zone has been cleared. |
| 2 | Success | The event has been completed. |
3 changes: 3 additions & 0 deletions docs/Packets/ServerToClient.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,4 +300,7 @@
* [C1 F6 1A - QuestStateList (by server)](C1-F6-1A-QuestStateList_by-server.md)
* [C1 F6 1B - QuestState (by server)](C1-F6-1B-QuestState_by-server.md)
* [C2 F6 1B - QuestStateExtended (by server)](C2-F6-1B-QuestStateExtended_by-server.md)
* [C1 F7 02 - ImperialGuardianEnterResult (by server)](C1-F7-02-ImperialGuardianEnterResult_by-server.md)
* [C1 F7 04 - ImperialGuardianTimer (by server)](C1-F7-04-ImperialGuardianTimer_by-server.md)
* [C1 F7 06 - ImperialGuardianResult (by server)](C1-F7-06-ImperialGuardianResult_by-server.md)
* [C3 F9 01 - OpenNpcDialog (by server)](C3-F9-01-OpenNpcDialog_by-server.md)
5 changes: 5 additions & 0 deletions src/DataModel/Configuration/MiniGameType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,9 @@ public enum MiniGameType
/// The Kanturu Refinery Tower event.
/// </summary>
Kanturu,

/// <summary>
/// The imperial guardian event (fortress of the imperial guardian).
/// </summary>
ImperialGuardian,
}
20 changes: 20 additions & 0 deletions src/GameLogic/AttackableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,26 @@ public static async ValueTask ApplyMaceMasteryStunEffectAsync(this Player attack
await attackable.MagicEffectList.AddEffectAsync(magicEffect).ConfigureAwait(false);
}

/// <summary>
/// Applies the stun effect to the player for the specified duration, e.g. by a skill of a monster.
/// </summary>
/// <param name="target">The player.</param>
/// <param name="duration">The duration of the stun.</param>
/// <returns>A task representing the asynchronous operation.</returns>
public static async ValueTask ApplyStunEffectAsync(this Player target, TimeSpan duration)
{
if (target.Attributes is not { } attributes
|| target.GameContext.Configuration.MagicEffects.FirstOrDefault(m => m.Number == StunnedMagicEffectNumber) is not { } effectDefinition
|| effectDefinition.PowerUpDefinitions.FirstOrDefault(pu => pu.TargetAttribute == Stats.IsStunned) is not { } powerUpDefinition)
{
return;
}

var powerUp = attributes.CreateElement(powerUpDefinition);
var magicEffect = new MagicEffect(duration, effectDefinition, [new MagicEffect.ElementWithTarget(powerUp, Stats.IsStunned)]);
await target.MagicEffectList.AddEffectAsync(magicEffect).ConfigureAwait(false);
}

/// <summary>
/// Ensures the skill attributes of the specified skill entry are set up.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// <copyright file="IImperialGuardianViewPlugIn.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.ImperialGuardian;

using MUnique.OpenMU.GameLogic.Views;

/// <summary>
/// View plugin interface for the imperial guardian event.
/// </summary>
public interface IImperialGuardianViewPlugIn : IViewPlugIn
{
/// <summary>
/// Shows the result of an enter request, or the zone which the player entered.
/// </summary>
/// <param name="result">The result.</param>
/// <param name="day">The day of the week (1 = monday, ..., 7 = sunday).</param>
/// <param name="zone">The zone, starting at 0.</param>
/// <param name="weather">The weather of the map.</param>
/// <param name="remainingTime">The remaining time.</param>
ValueTask ShowEnterResultAsync(ImperialGuardianEnterResult result, byte day, int zone, ImperialGuardianWeather weather, TimeSpan remainingTime);

/// <summary>
/// Shows the timer of the current zone.
/// </summary>
/// <param name="type">The type of the timer.</param>
/// <param name="remainingTime">The remaining time.</param>
/// <param name="monsterCount">The number of remaining monsters.</param>
ValueTask ShowTimerAsync(ImperialGuardianTimerType type, TimeSpan remainingTime, int monsterCount);

/// <summary>
/// Shows the result of a zone or of the event.
/// </summary>
/// <param name="result">The result.</param>
/// <param name="experience">The rewarded experience.</param>
ValueTask ShowResultAsync(ImperialGuardianResult result, int experience);

/// <summary>
/// Shows the animation of a skill of a monster.
/// </summary>
/// <param name="monster">The monster.</param>
/// <param name="target">The target of the skill.</param>
/// <param name="skillNumber">The number of the skill, which the client uses for the animation.</param>
ValueTask ShowMonsterSkillAsync(IAttacker monster, IAttackable target, short skillNumber);
}
Loading
Loading