baseline: OpenMU upstream b5a0961 (fresh source)

This commit is contained in:
Acentech Dev
2026-07-14 19:00:35 +03:00
parent 450402e47d
commit 36fc125d5c
11968 changed files with 748705 additions and 0 deletions

View File

@@ -0,0 +1,96 @@
// <copyright file="WizardTeleportAction.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameLogic.PlayerActions;
using MUnique.OpenMU.GameLogic.Views.World;
using MUnique.OpenMU.Pathfinding;
/// <summary>
/// Action to warp to another place through a gate.
/// </summary>
public class WizardTeleportAction
{
private const ushort TeleportSkillId = 6;
private const ushort TeleportTargetSkillId = 15;
private static readonly byte[] PreventingMagicEffects =
{
0x39, // Stone
0x3D, // Stun
0x48, // Sleep
0x92, // Freeze2
0x93, // Earth Binds
};
/// <summary>
/// Tries to teleport to the specified target with the teleport skill.
/// </summary>
/// <param name="player">The player.</param>
/// <param name="target">The target.</param>
public async ValueTask TryTeleportWithSkillAsync(Player player, Point target)
{
// todo: additional checks:
// - During castle siege, can't teleport over the non-destroyed gates (simple y-axis check)
if (!player.IsAtSafezone()
&& player.IsActive()
&& player.SkillList?.GetSkill(TeleportSkillId) is { Skill: { } skill }
&& player.CurrentMap!.Terrain.WalkMap[target.X, target.Y]
&& !player.CurrentMap.Terrain.SafezoneMap[target.X, target.Y]
&& player.IsInRange(target, skill.Range)
&& CanPlayerBeTeleported(player)
&& await player.TryConsumeForSkillAsync(skill).ConfigureAwait(false))
{
_ = Task.Run(() => player.TeleportAsync(target, skill));
}
else
{
await player.InvokeViewPlugInAsync<ITeleportPlugIn>(p => p.ShowTeleportedAsync()).ConfigureAwait(false);
}
}
/// <summary>
/// Tries to teleport the target with the 'Teleport Ally' skill.
/// </summary>
/// <param name="player">The player.</param>
/// <param name="targetId">The target identifier.</param>
/// <param name="target">The target.</param>
public async ValueTask TryTeleportTargetWithSkillAsync(Player player, ushort targetId, Point target)
{
if (!player.IsAtSafezone()
&& player.IsActive()
&& player.SkillList?.GetSkill(TeleportTargetSkillId) is { Skill: { } skill }
&& player.Party is not null
&& player.CurrentMap!.Terrain.WalkMap[target.X, target.Y]
&& !player.CurrentMap.Terrain.SafezoneMap[target.X, target.Y]
&& await player.GetObservingPlayerWithIdAsync(targetId).ConfigureAwait(false) is { } targetPlayer
&& targetPlayer.Party == player.Party
&& targetPlayer.IsActive()
&& CanPlayerBeTeleported(targetPlayer)
&& targetPlayer.IsInRange(target, skill.Range + 1)
&& await player.TryConsumeForSkillAsync(skill).ConfigureAwait(false))
{
_ = Task.Run(() => targetPlayer.TeleportAsync(target, skill));
}
}
private static bool CanPlayerBeTeleported(Player player)
{
var currentEffects = player.MagicEffectList.ActiveEffects;
if (currentEffects.Count == 0)
{
return true;
}
for (int i = 0; i < PreventingMagicEffects.Length; i++)
{
if (currentEffects.ContainsKey(PreventingMagicEffects[i]))
{
return false;
}
}
return true;
}
}