1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
#pragma once
#include <time.h>
#include <math.h>
#include <stdbool.h>
// inputs bitmask
#define INPUT_FORWARD (1 << 0)
#define INPUT_BACK (1 << 1)
#define INPUT_LEFT (1 << 2)
#define INPUT_RIGHT (1 << 3)
#define INPUT_JUMP (1 << 4)
#define INPUT_SPRINT (1 << 5)
#define HZ 20.0
#define NETWORK_RATE (1.0 / HZ)
#define TICK_RATE (1.0 / HZ)
#define MAX_PLAYERS 16
#define MAX_VIEW_NPCS 32
#define MAX_NPCS 2000
typedef struct {
float x;
float y;
float z;
} Vec3;
typedef enum {
PACKET_CLIENT_INPUT,
PACKET_SERVER_SNAPSHOT,
PACKET_PLAYER_JOINED,
PACKET_PLAYER_LEFT,
PACKET_HANDSHAKE,
PACKET_HANDSHAKE_RESPONSE,
PACKET_WORLD_EVENT,
PACKET_PING,
PACKET_PONG
} PacketType;
typedef struct {
PacketType type;
double sentTime;
} PingPacket;
// client → server
typedef struct {
PacketType type;
int playerId;
int inputs;
float yaw;
float dt;
int characterClass; // 0=warrior, 1=mage etc
} ClientPacket;
typedef struct {
PacketType type;
int playerId;
char name[32];
int characterClass; // 0=warrior, 1=mage etc
Vec3 position;
} PlayerJoinedPacket;
// server → client (full world snapshot)
typedef struct {
PacketType type;
int playerCount;
struct {
int id;
Vec3 position;
Vec3 velocity; // add this
float yaw;
int animationState;
bool onGround;
} players[MAX_PLAYERS];
int npcCount;
struct {
int id;
Vec3 position;
float rotation;
int state; // IDLE, WALKING, COMBAT
int health;
int scale;
int model;
} npcs[MAX_VIEW_NPCS];
int eventCount;
struct {
int objectId;
int eventType; // OBJECT_REMOVED, DOOR_OPENED etc
Vec3 position;
} events[8];
} ServerSnapshot;
typedef struct {
PacketType type;
char name[32];
int characterClass; // 0=warrior, 1=mage etc
} HandshakePacket;
typedef struct {
PacketType type;
int playerId;
float spawnX;
float spawnY;
float spawnZ;
} HandshakeResponsePacket;
static inline float Vec3Distance(Vec3 a, Vec3 b) {
float dx = a.x - b.x;
float dy = a.y - b.y;
float dz = a.z - b.z;
return sqrtf(dx*dx + dy*dy + dz*dz);
}
static inline double GetWallTime() {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return ts.tv_sec + ts.tv_nsec / 1e9;
}
|