2026-09-18 14:19:52 +07:00
using Ananta.SDK.Network ;
namespace Ananta.Server.Gameplay.Traffic ;
2026-10-29 01:55:01 +07:00
/// <summary>One lane-progress sample for the batched Aether lane sync.</summary>
public readonly record struct AetherLaneSample ( ulong EntityId , int LaneHandle , float Distance , byte Status );
/// <summary>One Aether vehicle spawn sample for the batch form.</summary>
public readonly record struct AetherVehicleInit (
ulong EntityId , uint ConfigId , uint ColorPartId , int LaneHandle , float Distance ,
float Speed , double Timestamp , float X , float Y , float Z , float Yaw ,
List <( float X , float Y , float Z )>? CruisePoints = null );
2026-09-18 14:19:52 +07:00
public interface ITrafficVehicleDriver
{
Task <( bool Ok , ulong EntityId )> SpawnTrafficVehicleAsync (
TcpSession session , uint configId , float x , float y , float z , float yaw );
Task DestroyTrafficVehicleAsync (
TcpSession session , ulong entityId );
Task SendVehicleMoveAsync (
TcpSession session , ulong entityId , float x , float y , float z , float yaw , float vx , float vz );
2026-10-29 01:55:01 +07:00
/// <summary>
/// Native client-driven spawn: registers an Aether vehicle on the client's own zone graph.
/// The client simulates/renders it from lane handle + distance; no scene entity is created.
/// </summary>
Task SpawnAetherVehicleAsync (
TcpSession session , ulong entityId , uint configId , uint colorPartId , int laneHandle ,
float distanceAlongLane , float speed , double timestamp , float x , float y , float z , float yaw );
/// <summary>
/// Spawns Aether vehicles on the client's zone graph. The 4229938 client has NO batch
/// AddDatas method — the implementer must send one SyncAetherAIVehicleAddData (68916691)
/// notify per vehicle.
/// </summary>
Task SpawnAetherVehiclesAsync (
TcpSession session , IReadOnlyList < AetherVehicleInit > vehicles );
/// <summary>Binds a driver/passenger NPC into an Aether vehicle seat (SyncAetherAIVehicleNpcAdd).</summary>
Task SpawnAetherVehicleNpcAsync (
TcpSession session , ulong npcId , uint npcFormworkId , ulong vehicleId , byte seatIndex );
/// <summary>Removes an Aether vehicle NPC (SyncAetherAINpcRemove 68332284 — the only Aether NPC remove the client has).</summary>
Task RemoveAetherVehicleNpcAsync ( TcpSession session , ulong npcId );
/// <summary>Pushes one intersection period change (SyncAetherAIIntersectionUpdateData); the id is the InstanceId previously sent in the init.</summary>
Task SendAetherIntersectionUpdateAsync (
TcpSession session , ulong intersectionInstanceId , int currentPeriod , int nextPeriod , byte state );
/// <summary>
/// Batched lane-progress sync (one packet per session per tick); the client interpolates
/// between samples using its 0.35s delay buffer.
/// </summary>
Task SendAetherLaneDatasAsync (
TcpSession session , List < AetherLaneSample > samples , double timestamp );
/// <summary>Removes an Aether vehicle from the client's traffic simulation.</summary>
Task RemoveAetherVehicleAsync (
TcpSession session , ulong entityId );
2026-09-18 14:19:52 +07:00
bool IsVehiclePlayerControlled ( ulong entityId );
( bool HasPlayer , float X , float Y , float Z , float Yaw , uint RaidId ) GetPlayerPosition ( TcpSession session );
}