feat: Upgrade server with HyNB v2.4 modular architecture, minigames, admin GM web panel, companion summons, and car radio
This commit is contained in:
1 parent
74e2963a12
commit
3e5adf1dc5
1571 files changed
+336468
-6348
No files matched your search
@@ -0,0 +1,67 @@
|
||||
using Ananta.SDK.Network;
|
||||
using Ananta.SDK.Serialization;
|
||||
using Ananta.Server.ClientData.Client4229938;
|
||||
using Ananta.Server.Protocol.Client4229938;
|
||||
using SceneMethods = Ananta.Server.RpcTypes.Client4229938.Methods.GameScene;
|
||||
|
||||
namespace Ananta.Server.Handlers.Game;
|
||||
|
||||
/// <summary>
|
||||
/// 敌人战斗姿态握手(2026-09-26 Wave 2,原生战斗管线复活)—— 移植 7k-v0.5
|
||||
/// <c>GameRouter.EnemyAi.cs:21-49 SendEnemyCombatStanceAsync / ClearEnemyGunAim4229938</c>,
|
||||
/// 逐行对齐,唯一差异:我们的 <c>TcpSession</c> 没有 <c>ClosedToken</c>,一律
|
||||
/// <c>CancellationToken.None</c>(与 GameAdminBridge 既有风格一致)。
|
||||
///
|
||||
/// 这条握手是「客户端原生受击/战斗 locomotion」的激活钥匙之一:
|
||||
/// <c>SyncBattleAnimSet</c> 让客户端把单位切到指定 AnimationSetConfig(空手 325/327、
|
||||
/// 远程 337/338/340),原生 hurt/stagger 反应才有对应动画集可播;
|
||||
/// <c>SyncAgentChangeWeapon</c> 负责卸/换武器(melee 空手 = weaponId 0)。
|
||||
/// 7K 对 template 模式 / 无动画集可换的模板<b>整段跳过</b>,我们保持同样的判据,
|
||||
/// 所以 spawnCombatMode=off / template 时本文件一个包都不会发。
|
||||
/// </summary>
|
||||
internal sealed partial class GameRouter
|
||||
{
|
||||
/// <summary>7K 原判据:melee 模式 + 已卸武器 + 有空手技能 = 空手单位。</summary>
|
||||
private static bool IsUnarmedEnemyProfile4229938(EnemyAiProfile4229938? profile)
|
||||
=> profile is { CombatMode: "melee", Weapon: 0, UnarmedAttacks.Count: > 0 };
|
||||
|
||||
/// <summary>
|
||||
/// 清空上半身持枪瞄准(移植 7K <c>ClearEnemyGunAim4229938</c>,消费方注释原文保留)。
|
||||
/// 两个包都是裸 u64(8B,无 marker)—— 7K 用 <c>new UxWriter().U64(id)</c>,照抄。
|
||||
/// </summary>
|
||||
private static async Task ClearEnemyGunAim4229938(TcpSession session, ulong id)
|
||||
{
|
||||
// Native 127C7F20 -> GunAimModule_Npc.Stop(pid): upper-body aim is
|
||||
// independent of the weapon model and the selected battle locomotion set.
|
||||
var payload = new UxWriter().U64(id).ToArray();
|
||||
await session.NotifyAsync(MethodId.IGameSceneToClient_SyncEndShootingState, payload, CancellationToken.None);
|
||||
// Native 127704B0 removes shooting tag 919, sends inward signal 1850,
|
||||
// and exits the shooting skill transition when the state-tree is active.
|
||||
await session.NotifyAsync(MethodId.IGameSceneToClient_SyncEndShootGameplayTag, payload, CancellationToken.None);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 战斗姿态握手(移植 7K <c>SendEnemyCombatStanceAsync</c>)。
|
||||
/// 判据与 7K 完全一致:profile null → 跳过;非空手且 BattleAnimSetTag==0 → 跳过
|
||||
/// (template / 持武器近战模板 7K 本来一个包都不发)。
|
||||
/// </summary>
|
||||
internal static async Task SendEnemyCombatStanceAsync(TcpSession session, ulong id, EnemyAiProfile4229938? profile)
|
||||
{
|
||||
if (profile is null) return;
|
||||
var unarmed = IsUnarmedEnemyProfile4229938(profile);
|
||||
if (!unarmed && profile.BattleAnimSetTag == 0) return;
|
||||
if (unarmed) await ClearEnemyGunAim4229938(session, id);
|
||||
// Weapon removal alone does not replace the battle movement action set.
|
||||
await session.NotifyAsync(MethodId.SyncAgentChangeWeapon, UxSerializer.Serialize(
|
||||
new SceneMethods.EnemyAiWeapon4229938 { agentId = id, weaponId = profile.Weapon }), CancellationToken.None);
|
||||
// ApplyBattleAnimSetTag returns immediately for the same cached tag.
|
||||
// During the bounded loading warmups, remove/re-add the override so it
|
||||
// cannot remain a cached no-op after a late weapon/module initialization.
|
||||
if (unarmed && profile.BattleAnimSetTag != 0)
|
||||
await session.NotifyAsync(MethodId.IGameSceneToClient_SyncBattleAnimSet, UxSerializer.Serialize(
|
||||
new SceneMethods.EnemyAiBattleAnim4229938 { id = id, animSetTag = 0 }), CancellationToken.None);
|
||||
await session.NotifyAsync(MethodId.IGameSceneToClient_SyncBattleAnimSet, UxSerializer.Serialize(
|
||||
new SceneMethods.EnemyAiBattleAnim4229938 { id = id, animSetTag = profile.BattleAnimSetTag }), CancellationToken.None);
|
||||
session.Log.Info($"[ENEMY-STANCE] uid={id} mode={profile.CombatMode} unarmed={unarmed} weapon={profile.Weapon} animSet={profile.BattleAnimSetTag} attacks={string.Join(',', profile.Attacks)}");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user