#pragma once #include "raylib.h" #include "shared.h" #include "queue.h" #include "net_compat.h" static int networkFd = -1; static struct sockaddr_in server; extern PacketQueue incomingQueue; extern ClientPacket latestPacket; extern pthread_mutex_t packetLock; extern double lastSendTime; extern Mesh terrainMesh; extern Matrix terrainTransform; extern double pingMs; extern int scene; // your own player - full prediction typedef struct { int id; Vector3 position; Vector3 velocity; float yaw; float pitch; float height; float speed; int sprint; bool onGround; } Player; // other players - no prediction, just interpolate typedef struct { int id; bool active; Vector3 currentPosition; // what we render Vector3 serverPosition; // latest from server float currentYaw; float serverYaw; float serverVelocityY; // add this bool serverOnGround; int animationState; Model model; int characterClass; } RemotePlayer; // npcs - no AI, just interpolate typedef struct { int id; bool active; Vector3 currentPosition; // what we render Vector3 serverPosition; // latest from server float currentRotation; float serverRotation; int state; int health; int model; Vector3 scale; } ClientNPC; extern Player player; extern RemotePlayer remotePlayers[MAX_PLAYERS]; extern ClientNPC clientNPCs[MAX_VIEW_NPCS]; void NetworkInit(); void NetworkShutdown(); void SendPlayerUpdate(ClientPacket*); void *RecvThread(void *arg); void *SendThread(void *arg); void ProcessIncoming(); void ReconcilePlayer(Player *p, Vector3 serverPosition); void HandleSnapshot(ServerSnapshot *snapshot); void HandlePlayerJoined(PlayerJoinedPacket *packet); void HandlePlayerLeft(PlayerJoinedPacket *packet); void HandleHandshakeResponse(HandshakeResponsePacket *packet); void InitRemotePlayers(); float GetTerrainHeight(float x, float z); void UpdateRemotePlayer(RemotePlayer *p, float dt); void SendPing();