wider terrain

This commit is contained in:
Masashi 2025-12-18 21:55:51 +05:30
commit 7fc4e9cd3c
4 changed files with 52 additions and 23 deletions

Binary file not shown.

View file

@ -21,7 +21,7 @@ typedef int socklen_t;
#define CLOSESOCK close #define CLOSESOCK close
#endif #endif
#define PROTOCOL_VERSION 5 #define PROTOCOL_VERSION 67
#define SERVER_PORT 27015 #define SERVER_PORT 27015
#define MAX_PLAYERS 16 #define MAX_PLAYERS 16
#define USERNAME_MAX 16 #define USERNAME_MAX 16
@ -558,6 +558,7 @@ typedef struct PlayerStateNet {
float x, y, z, yaw, pitch; float x, y, z, yaw, pitch;
uint8_t weapon; uint8_t weapon;
int16_t pistolMag, rifleMag, pistolAmmo, rifleAmmo, medkits; int16_t pistolMag, rifleMag, pistolAmmo, rifleAmmo, medkits;
int16_t reloadTimeLeft;
char username[USERNAME_MAX]; char username[USERNAME_MAX];
} PlayerStateNet; } PlayerStateNet;
@ -589,6 +590,7 @@ typedef struct RemotePlayer {
float yaw, pitch; float yaw, pitch;
uint8_t weapon; uint8_t weapon;
int16_t pistolMag, rifleMag, pistolAmmo, rifleAmmo, medkits; int16_t pistolMag, rifleMag, pistolAmmo, rifleAmmo, medkits;
int16_t reloadTimeLeft;
char username[USERNAME_MAX]; char username[USERNAME_MAX];
} RemotePlayer; } RemotePlayer;
@ -715,7 +717,7 @@ int main(void) {
float recoilYaw = 0.0f, recoilPitch = 0.0f, crossSpread = 0.0f; float recoilYaw = 0.0f, recoilPitch = 0.0f, crossSpread = 0.0f;
float fireCooldown = 0.0f; float fireCooldown = 0.0f;
int shotsInBurst = 0; int shotsInBurst = 0;
float burstResetTimer = 0.0f; float burstResetTimer = 0.0f;
const float pistolFireRate = 4.0f, rifleFireRate = 12.0f; const float pistolFireRate = 4.0f, rifleFireRate = 12.0f;
const float recoilReturn = 18.0f, crossReturn = 14.0f; const float recoilReturn = 18.0f, crossReturn = 14.0f;
@ -799,15 +801,16 @@ int main(void) {
p->pistolAmmo = ps->pistolAmmo; p->pistolAmmo = ps->pistolAmmo;
p->rifleAmmo = ps->rifleAmmo; p->rifleAmmo = ps->rifleAmmo;
p->medkits = ps->medkits; p->medkits = ps->medkits;
p->reloadTimeLeft = ps->reloadTimeLeft;
memset(p->username, 0, USERNAME_MAX); memset(p->username, 0, USERNAME_MAX);
strncpy(p->username, ps->username, USERNAME_MAX - 1); strncpy(p->username, ps->username, USERNAME_MAX - 1);
} }
if (myId != 255 && rp[myId].present) { if (myId != 255 && rp[myId].present) {
Vector3 body = rp[myId].pos; Vector3 body = rp[myId].pos;
camPos.x = body.x; camPos.x = body.x;
camPos.y = body.y + 1.0f; camPos.y = body.y + 1.0f;
camPos.z = body.z + 0.0001f; camPos.z = body.z + 0.0001f;
// Prevent camera from clipping into terrain // Prevent camera from clipping into terrain
float terrain_h = get_terrain_height(camPos.x, camPos.z); float terrain_h = get_terrain_height(camPos.x, camPos.z);
@ -854,8 +857,6 @@ int main(void) {
if (IsKeyDown(KEY_S)) if (IsKeyDown(KEY_S))
moveZ -= 1.0f; moveZ -= 1.0f;
uint8_t buttons = 0; uint8_t buttons = 0;
if (IsKeyPressed(KEY_ONE)) if (IsKeyPressed(KEY_ONE))
buttons |= BTN_SWITCH_PISTOL; buttons |= BTN_SWITCH_PISTOL;
@ -1055,7 +1056,10 @@ int main(void) {
DrawText(TextFormat("%d", currentMag), sw - 250, sh - 75, 40, RAYWHITE); DrawText(TextFormat("%d", currentMag), sw - 250, sh - 75, 40, RAYWHITE);
DrawText(TextFormat("/ %d", reserveAmmo), sw - 140, sh - 65, 24, DrawText(TextFormat("/ %d", reserveAmmo), sw - 140, sh - 65, 24,
(Color){180, 180, 180, 255}); (Color){180, 180, 180, 255});
if (currentMag == 0) if (rp[myId].reloadTimeLeft > 0)
DrawText("RELOADING...", sw - 250, sh - 30, 20,
(Color){255, 200, 80, 255});
else if (currentMag == 0)
DrawText("RELOAD!", sw - 250, sh - 30, 20, (Color){255, 80, 80, 255}); DrawText("RELOAD!", sw - 250, sh - 30, 20, (Color){255, 80, 80, 255});
} }

Binary file not shown.

View file

@ -23,7 +23,7 @@ typedef int socklen_t;
#define CLOSESOCK close #define CLOSESOCK close
#endif #endif
#define PROTOCOL_VERSION 5 #define PROTOCOL_VERSION 67
#define SERVER_PORT 27015 #define SERVER_PORT 27015
#define MAX_PLAYERS 16 #define MAX_PLAYERS 16
#define USERNAME_MAX 16 #define USERNAME_MAX 16
@ -238,6 +238,7 @@ typedef struct PlayerStateNet {
float x, y, z, yaw, pitch; float x, y, z, yaw, pitch;
uint8_t weapon; uint8_t weapon;
int16_t pistolMag, rifleMag, pistolAmmo, rifleAmmo, medkits; int16_t pistolMag, rifleMag, pistolAmmo, rifleAmmo, medkits;
int16_t reloadTimeLeft;
char username[USERNAME_MAX]; char username[USERNAME_MAX];
} PlayerStateNet; } PlayerStateNet;
@ -283,6 +284,8 @@ typedef struct Player {
double lastShotTime; double lastShotTime;
int shotsInBurst; int shotsInBurst;
uint32_t rng; uint32_t rng;
float reloadTimer;
int reloadWeapon;
dBodyID body; dBodyID body;
dGeomID geom; dGeomID geom;
} Player; } Player;
@ -656,20 +659,9 @@ int main(void) {
p->weapon = WEAPON_RIFLE; p->weapon = WEAPON_RIFLE;
if (m->buttons & BTN_RELOAD) { if (m->buttons & BTN_RELOAD) {
if (p->weapon == WEAPON_PISTOL) { if (p->reloadTimer <= 0.0f) {
int need = 12 - p->pistolMag; p->reloadTimer = 2.0f; // 2 second reload time
if (need > 0 && p->pistolAmmo > 0) { p->reloadWeapon = p->weapon;
int take = (p->pistolAmmo < need) ? p->pistolAmmo : need;
p->pistolAmmo -= take;
p->pistolMag += take;
}
} else {
int need = 30 - p->rifleMag;
if (need > 0 && p->rifleAmmo > 0) {
int take = (p->rifleAmmo < need) ? p->rifleAmmo : need;
p->rifleAmmo -= take;
p->rifleMag += take;
}
} }
} }
@ -730,6 +722,9 @@ int main(void) {
if (now - sh->lastShotTime > 0.18) if (now - sh->lastShotTime > 0.18)
sh->shotsInBurst = 0; sh->shotsInBurst = 0;
if (sh->reloadTimer > 0.0f)
continue;
int *mag = int *mag =
(sh->weapon == WEAPON_PISTOL) ? &sh->pistolMag : &sh->rifleMag; (sh->weapon == WEAPON_PISTOL) ? &sh->pistolMag : &sh->rifleMag;
if (*mag <= 0) if (*mag <= 0)
@ -801,6 +796,35 @@ int main(void) {
dWorldQuickStep(gWorld, DT); dWorldQuickStep(gWorld, DT);
dJointGroupEmpty(gContactGroup); dJointGroupEmpty(gContactGroup);
// Handle reload timers
for (int i = 0; i < MAX_PLAYERS; i++) {
Player *p = &players[i];
if (!p->inUse || !p->alive)
continue;
if (p->reloadTimer > 0.0f) {
p->reloadTimer -= DT;
if (p->reloadTimer <= 0.0f) {
p->reloadTimer = 0.0f;
// Perform reload
if (p->reloadWeapon == WEAPON_PISTOL) {
int need = 12 - p->pistolMag;
if (need > 0 && p->pistolAmmo > 0) {
int take = (p->pistolAmmo < need) ? p->pistolAmmo : need;
p->pistolAmmo -= take;
p->pistolMag += take;
}
} else {
int need = 30 - p->rifleMag;
if (need > 0 && p->rifleAmmo > 0) {
int take = (p->rifleAmmo < need) ? p->rifleAmmo : need;
p->rifleAmmo -= take;
p->rifleMag += take;
}
}
}
}
}
for (int i = 0; i < MAX_PLAYERS; i++) { for (int i = 0; i < MAX_PLAYERS; i++) {
Player *p = &players[i]; Player *p = &players[i];
if (!p->inUse || !p->alive) if (!p->inUse || !p->alive)
@ -847,6 +871,7 @@ int main(void) {
ps->pistolAmmo = (int16_t)players[i].pistolAmmo; ps->pistolAmmo = (int16_t)players[i].pistolAmmo;
ps->rifleAmmo = (int16_t)players[i].rifleAmmo; ps->rifleAmmo = (int16_t)players[i].rifleAmmo;
ps->medkits = (int16_t)players[i].medkits; ps->medkits = (int16_t)players[i].medkits;
ps->reloadTimeLeft = (int16_t)(players[i].reloadTimer * 1000.0f);
strncpy(ps->username, players[i].username, USERNAME_MAX - 1); strncpy(ps->username, players[i].username, USERNAME_MAX - 1);
} }
broadcast(sock, players, &snap, (int)sizeof(snap)); broadcast(sock, players, &snap, (int)sizeof(snap));