feat: Add metro transit, gadgets, shop, social apps, and traffic models checkpoint
This commit is contained in:
1 parent
caa42b84ed
commit
74e2963a12
79 files changed
+527962
-496
No files matched your search
@@ -0,0 +1,62 @@
|
||||
using Ananta.SDK.Network;
|
||||
using Ananta.SDK.Rpc;
|
||||
using Ananta.SDK.Serialization;
|
||||
using Ananta.Server.Protocol.Client4229938;
|
||||
using SceneMethods = Ananta.Server.RpcTypes.Client4229938.Methods.GameScene;
|
||||
|
||||
namespace Ananta.Server.Handlers.Game;
|
||||
|
||||
/// <summary>
|
||||
/// Spoon server-action output ports. The client's spoon task graph asks the SERVER which
|
||||
/// output port to take (AskGetSpoonServerOutputPortIndexByType, UXRPCTask<uint>) or to
|
||||
/// perform an action (AskDoSpoonServerActionByType). We answer port 0 — byte-identical to
|
||||
/// the typed-default fallback — and, for do-action, push the nearest repair shop's
|
||||
/// inventory so the mechanic's "assortment" dialog branch opens with content.
|
||||
/// Full param decoding (SpoonServerActionParam) is deferred: the raw body is logged.
|
||||
/// </summary>
|
||||
internal sealed partial class GameRouter
|
||||
{
|
||||
[Handler(MethodId.AskGetSpoonServerOutputPortIndexByType, HandlerPacketKind.Invoke)]
|
||||
private Task SpoonOutputPortProbe(Connection conn, UxRpcMessage msg)
|
||||
{
|
||||
conn.Log.Info($"[SPOON] output-port probe bytes={msg.Body.Length} -> port 0");
|
||||
return conn.ReturnAsync(msg, 0u);
|
||||
}
|
||||
|
||||
[Handler(MethodId.AskDoSpoonServerActionByType, HandlerPacketKind.Invoke)]
|
||||
private async Task SpoonServerAction(Connection conn, UxRpcMessage msg)
|
||||
{
|
||||
conn.Log.Info($"[SPOON] do-action bytes={msg.Body.Length} -> ok (port 0)");
|
||||
await conn.ReturnEmptyOkAsync(msg);
|
||||
|
||||
// Push the nearest repair shop's inventory when the player is close to one —
|
||||
// the mechanic's assortment dialog opens empty without this push.
|
||||
var state = GetStateIfExists(conn.Session);
|
||||
if (state is null || !state.HasLastReportedPlayerTransform)
|
||||
return;
|
||||
var px = state.LastReportedPlayerPosition.X;
|
||||
var pz = state.LastReportedPlayerPosition.Z;
|
||||
var west = ShopInteriors[0];
|
||||
var seaside = ShopInteriors[1];
|
||||
float D2(SceneMethods.UxVector3 e) => (px - e.X) * (px - e.X) + (pz - e.Z) * (pz - e.Z);
|
||||
var (shopId, dist2) = D2(west.Entrance) <= D2(seaside.Entrance) ? (94100069u, D2(west.Entrance)) : (94100070u, D2(seaside.Entrance));
|
||||
if (dist2 > 60f * 60f)
|
||||
return;
|
||||
ShopCommodityCache.Value.TryGetValue(shopId, out var ids);
|
||||
var items = (ids ?? []).Select(id => new RpcTypes.Client4229938.Methods.Game.ShopCommodityItem
|
||||
{
|
||||
TemplateId = id,
|
||||
Count = 1,
|
||||
Status = 0,
|
||||
Discount = 100,
|
||||
MaxBuyCount = 0,
|
||||
}).ToList();
|
||||
await conn.Session.NotifyAsync(MethodId.IGameToClient_SyncFullCommodityInfos, UxSerializer.Serialize(
|
||||
new RpcTypes.Client4229938.Methods.Game.SyncFullCommodityInfos
|
||||
{
|
||||
shopId = shopId,
|
||||
infos = items,
|
||||
}), CancellationToken.None);
|
||||
conn.Log.Info($"[SPOON] do-action -> pushed {items.Count} commodities shop={shopId} (dist={MathF.Sqrt(dist2):F0}m)");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user