From 75ee5a6da82cc3a4677999b5cd61a0695307868e Mon Sep 17 00:00:00 2001 From: Masashi Date: Thu, 18 Dec 2025 21:32:05 +0530 Subject: [PATCH 1/8] I CAN SEE --- game/client | Bin 0 -> 30248 bytes game/client.c | 329 +++++++++++++++++++++++++++++++++--------------- game/server | Bin 0 -> 35160 bytes game/terrain.fs | 86 +++++++++++++ game/terrain.vs | 31 +++++ 5 files changed, 342 insertions(+), 104 deletions(-) create mode 100755 game/client create mode 100755 game/server create mode 100644 game/terrain.fs create mode 100644 game/terrain.vs diff --git a/game/client b/game/client new file mode 100755 index 0000000000000000000000000000000000000000..09033d3f38765b7bb5af2aebc2b3e6cf44ce0e1d GIT binary patch literal 30248 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 z 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 OLPg@vZV9@v!hZu-qb#og literal 0 HcmV?d00001 diff --git a/game/client.c b/game/client.c index c7eb9e5..56670b4 100644 --- a/game/client.c +++ b/game/client.c @@ -53,7 +53,40 @@ typedef struct { float shadowIntensity; // How dark shadows are (0-1) } DirectionalLight; -// ============== SIMPLEX NOISE ============== +// ============== TERRAIN SHADER ============== +typedef struct { + Shader shader; + int locViewPos; + int locLightDir; + int locLightColor; + int locLightIntensity; + int locAmbientIntensity; + int locTerrainColor; +} TerrainShader; + +static TerrainShader load_terrain_shader(void) { + TerrainShader ts = {0}; + ts.shader = LoadShader("terrain.vs", "terrain.fs"); + + // Get uniform locations + ts.locViewPos = GetShaderLocation(ts.shader, "viewPos"); + ts.locLightDir = GetShaderLocation(ts.shader, "lightDir"); + ts.locLightColor = GetShaderLocation(ts.shader, "lightColor"); + ts.locLightIntensity = GetShaderLocation(ts.shader, "lightIntensity"); + ts.locAmbientIntensity = GetShaderLocation(ts.shader, "ambientIntensity"); + ts.locTerrainColor = GetShaderLocation(ts.shader, "terrainColor"); + + return ts; +} + +static void unload_terrain_shader(TerrainShader *ts) { + if (ts && ts->shader.id != 0) { + UnloadShader(ts->shader); + ts->shader.id = 0; + } +} + +// ============== END TERRAIN SHADER ============== static const uint8_t perm[512] = { 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, @@ -205,60 +238,40 @@ static Mesh generate_terrain_mesh(void) { } } - // Calculate normals - for (int i = 0; i < vertexCount; i++) { - mesh.normals[i * 3 + 0] = 0; - mesh.normals[i * 3 + 1] = 1; - mesh.normals[i * 3 + 2] = 0; - } - - for (int t = 0; t < triangleCount; t++) { - int i0 = mesh.indices[t * 3 + 0]; - int i1 = mesh.indices[t * 3 + 1]; - int i2 = mesh.indices[t * 3 + 2]; - - float v0x = mesh.vertices[i0 * 3 + 0]; - float v0y = mesh.vertices[i0 * 3 + 1]; - float v0z = mesh.vertices[i0 * 3 + 2]; - - float v1x = mesh.vertices[i1 * 3 + 0]; - float v1y = mesh.vertices[i1 * 3 + 1]; - float v1z = mesh.vertices[i1 * 3 + 2]; - - float v2x = mesh.vertices[i2 * 3 + 0]; - float v2y = mesh.vertices[i2 * 3 + 1]; - float v2z = mesh.vertices[i2 * 3 + 2]; - - float e1x = v1x - v0x, e1y = v1y - v0y, e1z = v1z - v0z; - float e2x = v2x - v0x, e2y = v2y - v0y, e2z = v2z - v0z; - - float nx = e1y * e2z - e1z * e2y; - float ny = e1z * e2x - e1x * e2z; - float nz = e1x * e2y - e1y * e2x; - - mesh.normals[i0 * 3 + 0] += nx; - mesh.normals[i0 * 3 + 1] += ny; - mesh.normals[i0 * 3 + 2] += nz; - - mesh.normals[i1 * 3 + 0] += nx; - mesh.normals[i1 * 3 + 1] += ny; - mesh.normals[i1 * 3 + 2] += nz; - - mesh.normals[i2 * 3 + 0] += nx; - mesh.normals[i2 * 3 + 1] += ny; - mesh.normals[i2 * 3 + 2] += nz; - } - - // Normalize normals - for (int i = 0; i < vertexCount; i++) { - float nx = mesh.normals[i * 3 + 0]; - float ny = mesh.normals[i * 3 + 1]; - float nz = mesh.normals[i * 3 + 2]; - float len = sqrtf(nx * nx + ny * ny + nz * nz); - if (len > 0.0001f) { - mesh.normals[i * 3 + 0] = nx / len; - mesh.normals[i * 3 + 1] = ny / len; - mesh.normals[i * 3 + 2] = nz / len; + // Calculate normals using tangent plane approximation from terrain gradients + // This preserves terrain curvature better than simple triangle averaging + for (int z = 0; z < size; z++) { + for (int x = 0; x < size; x++) { + int idx = z * size + x; + float wx = ((float)x - size / 2.0f) * TERRAIN_SCALE; + float wz = ((float)z - size / 2.0f) * TERRAIN_SCALE; + + // Sample height gradients to compute terrain normal + // Use neighboring vertices for finite difference approximation + float h_right = (x + 1 < size) ? mesh.vertices[(z * size + (x + 1)) * 3 + 1] : mesh.vertices[idx * 3 + 1]; + float h_left = (x - 1 >= 0) ? mesh.vertices[(z * size + (x - 1)) * 3 + 1] : mesh.vertices[idx * 3 + 1]; + float h_down = (z + 1 < size) ? mesh.vertices[((z + 1) * size + x) * 3 + 1] : mesh.vertices[idx * 3 + 1]; + float h_up = (z - 1 >= 0) ? mesh.vertices[((z - 1) * size + x) * 3 + 1] : mesh.vertices[idx * 3 + 1]; + + // Compute finite differences + float dh_dx = (h_right - h_left) / (2.0f * TERRAIN_SCALE); + float dh_dz = (h_down - h_up) / (2.0f * TERRAIN_SCALE); + + // Normal from height field: (-dh/dx, 1, -dh/dz) then normalized + float nx = -dh_dx; + float ny = 1.0f; + float nz = -dh_dz; + + float len = sqrtf(nx * nx + ny * ny + nz * nz); + if (len > 0.0001f) { + mesh.normals[idx * 3 + 0] = nx / len; + mesh.normals[idx * 3 + 1] = ny / len; + mesh.normals[idx * 3 + 2] = nz / len; + } else { + mesh.normals[idx * 3 + 0] = 0; + mesh.normals[idx * 3 + 1] = 1; + mesh.normals[idx * 3 + 2] = 0; + } } } @@ -364,12 +377,117 @@ static Color apply_lighting_with_shadows(Color baseColor, Vector3 normal, } static Vector3 v3_normalize(Vector3 v) { - float len = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); - if (len < 0.0001f) - return (Vector3){0, 1, 0}; - return (Vector3){v.x / len, v.y / len, v.z / len}; + float len = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); + if (len < 0.0001f) + return (Vector3){0, 1, 0}; + return (Vector3){v.x / len, v.y / len, v.z / len}; + } + +// ============== VECTOR3 HELPERS ============== +static Vector3 v3(float x, float y, float z) { + Vector3 v = {x, y, z}; + return v; } -// ============== END LIGHTING HELPERS ============== +static Vector3 v3_add(Vector3 a, Vector3 b) { + return v3(a.x + b.x, a.y + b.y, a.z + b.z); +} +static Vector3 v3_sub(Vector3 a, Vector3 b) { + return v3(a.x - b.x, a.y - b.y, a.z - b.z); +} +static float v3_dot(Vector3 a, Vector3 b) { + return a.x * b.x + a.y * b.y + a.z * b.z; +} +static float v3_len(Vector3 a) { + return sqrtf(a.x * a.x + a.y * a.y + a.z * a.z); +} +static Vector3 v3_norm(Vector3 a) { + float l = v3_len(a); + if (l <= 1e-6f) + return v3(0, 0, 1); + return v3(a.x / l, a.y / l, a.z / l); +} +// ============== END VECTOR3 HELPERS ============== + +// ============== ENHANCED LIGHTING & AMBIENT OCCLUSION ============== + +// calculate_ambient_occlusion: Estimates how occluded a point is based on terrain curvature +// Samples heights in cardinal directions and computes horizon angle to terrain +// Returns occlusion factor from 0 (fully occluded) to 1 (fully lit) +static float calculate_ambient_occlusion(Vector3 worldPos, Vector3 normal) { + // AO based on terrain curvature: check if terrain rises around the point + float sampleRadius = 3.0f; + float aoAccum = 0.0f; + int numSamples = 8; + + float centerHeight = worldPos.y; + + // Sample 8 directions around the point + for (int i = 0; i < numSamples; i++) { + float angle = (2.0f * 3.14159265f * (float)i) / (float)numSamples; + float sx = worldPos.x + cosf(angle) * sampleRadius; + float sz = worldPos.z + sinf(angle) * sampleRadius; + float sh = get_terrain_height(sx, sz); + + // Check if terrain is higher relative to surface normal + // Higher terrain in shadow-casting areas reduces occlusion + float heightDiff = sh - centerHeight; + if (heightDiff > 0.1f) { + // Terrain is higher, contributes to shadow + float aoAmount = fminf(1.0f, heightDiff / 2.0f); + aoAccum += aoAmount; + } + } + + float aoFactor = 1.0f - (aoAccum / (float)numSamples) * 0.6f; // 60% max occlusion + return fmaxf(0.2f, aoFactor); // Min 20% brightness +} + +// apply_phong_lighting_per_pixel: Advanced Phong lighting with per-pixel normals +// Includes diffuse, specular highlight, and ambient occlusion for geometry detail +static Color apply_phong_lighting_per_pixel(Color baseColor, Vector3 normal, + Vector3 worldPos, Vector3 camPos, + DirectionalLight light) { + // Normalize inputs + Vector3 lightDir = v3_normalize(light.direction); + Vector3 normal_norm = v3_normalize(normal); + + // Compute view direction (from surface to camera) + Vector3 viewDir = v3_normalize(v3_sub(camPos, worldPos)); + + // Diffuse component: Lambertian shading + float diffuse = fmaxf(0.0f, -v3_dot(lightDir, normal_norm)); + + // Specular component: Blinn-Phong specular highlight + Vector3 halfVec = v3_normalize(v3_add(v3_norm((Vector3){-lightDir.x, -lightDir.y, -lightDir.z}), viewDir)); + float specular = powf(fmaxf(0.0f, v3_dot(halfVec, normal_norm)), 32.0f) * 0.5f; + + // Ambient occlusion from terrain geometry + float ao = calculate_ambient_occlusion(worldPos, normal_norm); + + // Shadow based on height (distant higher terrain casts softer shadows) + float shadowFactor = calculate_shadow_factor(worldPos, light.direction, 10.0f); + + // Combine lighting components + float brightness = light.ambientIntensity * ao; + brightness += diffuse * light.intensity * shadowFactor * (1.0f - light.ambientIntensity) * ao; + brightness += specular * light.intensity * shadowFactor * 0.6f; // Specular less affected by AO + + brightness = fminf(1.0f, brightness); + + // Apply brightness to base color + int r = (int)(baseColor.r * brightness); + int g = (int)(baseColor.g * brightness); + int b = (int)(baseColor.b * brightness); + + // Clamp to valid RGB range + if (r > 255) r = 255; + if (g > 255) g = 255; + if (b > 255) b = 255; + + return (Color){r, g, b, baseColor.a}; +} + +// ============== END ENHANCED LIGHTING & AMBIENT OCCLUSION ============== static void set_nonblocking(int sock) { #ifdef _WIN32 @@ -465,29 +583,6 @@ typedef struct WorldItem { Vector3 pos; } WorldItem; -static Vector3 v3(float x, float y, float z) { - Vector3 v = {x, y, z}; - return v; -} -static Vector3 v3_add(Vector3 a, Vector3 b) { - return v3(a.x + b.x, a.y + b.y, a.z + b.z); -} -static Vector3 v3_sub(Vector3 a, Vector3 b) { - return v3(a.x - b.x, a.y - b.y, a.z - b.z); -} -static float v3_dot(Vector3 a, Vector3 b) { - return a.x * b.x + a.y * b.y + a.z * b.z; -} -static float v3_len(Vector3 a) { - return sqrtf(a.x * a.x + a.y * a.y + a.z * a.z); -} -static Vector3 v3_norm(Vector3 a) { - float l = v3_len(a); - if (l <= 1e-6f) - return v3(0, 0, 1); - return v3(a.x / l, a.y / l, a.z / l); -} - static const char *ItemName(uint8_t t) { switch (t) { case ITEM_MEDKIT: @@ -565,6 +660,17 @@ int main(void) { dirLight.shadowBias = 0.005f; dirLight.shadowIntensity = 0.4f; + // Load terrain shader + TerrainShader terrainShader = load_terrain_shader(); + if (terrainShader.shader.id == 0) { + fprintf(stderr, "Warning: Failed to load terrain shader, using default rendering\n"); + // Fallback: Make terrain very bright red to show shader failed + terrainModel.materials[0].maps[MATERIAL_MAP_DIFFUSE].color = (Color){255, 100, 100, 255}; + } else { + terrainModel.materials[0].shader = terrainShader.shader; + fprintf(stderr, "Shader loaded successfully!\n"); + } + int sock = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock < 0) { perror("socket"); @@ -586,10 +692,12 @@ int main(void) { Vector3 camPos = v3(0, 5.0f, 6); float yaw = 0.0f, pitch = 0.0f; - float recoilYaw = 0.0f, recoilPitch = 0.0f, crossSpread = 0.0f; - float fireCooldown = 0.0f; - int shotsInBurst = 0; - float burstResetTimer = 0.0f; + float recoilYaw = 0.0f, recoilPitch = 0.0f, crossSpread = 0.0f; + float fireCooldown = 0.0f; + int shotsInBurst = 0; + float burstResetTimer = 0.0f; + + const float pistolFireRate = 4.0f, rifleFireRate = 12.0f; const float recoilReturn = 18.0f, crossReturn = 14.0f; @@ -738,6 +846,8 @@ int main(void) { if (IsKeyPressed(KEY_SPACE)) buttons |= BTN_JUMP; + + if (myId != 255) { MsgInput in = {0}; in.type = MSG_INPUT; @@ -796,20 +906,30 @@ int main(void) { BeginMode3D(cam); - // Calculate terrain normal at camera position for lighting - Vector3 terrainNormal = v3(0, 1, 0); // Default up normal + // Set up shader uniforms for terrain rendering + if (terrainShader.shader.id != 0) { + // Convert light direction to shader format (should be pointing TO the light) + float lightDirArray[3] = {-dirLight.direction.x, -dirLight.direction.y, -dirLight.direction.z}; + float lightColorArray[3] = {dirLight.color.x, dirLight.color.y, dirLight.color.z}; + float viewPosArray[3] = {camPos.x, camPos.y, camPos.z}; + // Terrain color in 0-1 range (80, 140, 70) / 255 + float terrainColorArray[3] = {80.0f/255.0f, 140.0f/255.0f, 70.0f/255.0f}; - // Draw smooth terrain with directional lighting + shadows - // For Raylib, we apply lighting by adjusting material colors - Color terrainBaseColor = (Color){80, 140, 70, 255}; - Color litTerrainColor = apply_lighting_with_shadows( - terrainBaseColor, terrainNormal, v3(0, 2, 0), dirLight); + // Debug mode: 0=normal lighting, 1=show normals as colors, 2=show AO only - terrainModel.materials[0].maps[MATERIAL_MAP_DIFFUSE].color = - litTerrainColor; + SetShaderValue(terrainShader.shader, terrainShader.locViewPos, viewPosArray, SHADER_UNIFORM_VEC3); + SetShaderValue(terrainShader.shader, terrainShader.locLightDir, lightDirArray, SHADER_UNIFORM_VEC3); + SetShaderValue(terrainShader.shader, terrainShader.locLightColor, lightColorArray, SHADER_UNIFORM_VEC3); + SetShaderValue(terrainShader.shader, terrainShader.locLightIntensity, &dirLight.intensity, SHADER_UNIFORM_FLOAT); + SetShaderValue(terrainShader.shader, terrainShader.locAmbientIntensity, &dirLight.ambientIntensity, SHADER_UNIFORM_FLOAT); + SetShaderValue(terrainShader.shader, terrainShader.locTerrainColor, terrainColorArray, SHADER_UNIFORM_VEC3); + } + + // Draw terrain with shader + terrainModel.materials[0].maps[MATERIAL_MAP_DIFFUSE].color = (Color){80, 140, 70, 255}; DrawModel(terrainModel, (Vector3){0, 0, 0}, 1.0f, WHITE); - // Items with lighting and shadows + // Items with basic lighting (no shader for now to keep it simple) for (int i = 0; i < MAX_ITEMS; i++) { if (!wi[i].present) continue; @@ -821,13 +941,13 @@ int main(void) { if (wi[i].type == ITEM_AMMO_RIFLE) ic = (Color){255, 180, 120, 255}; - // Apply lighting with shadows to items - Color litColor = - apply_lighting_with_shadows(ic, terrainNormal, wi[i].pos, dirLight); + // Apply basic lighting to items + Vector3 itemNormal = v3(0, 1, 0); + Color litColor = apply_lighting_with_shadows(ic, itemNormal, wi[i].pos, dirLight); DrawSphere(wi[i].pos, 0.3f, litColor); } - // Players with lighting and shadows + // Players with basic lighting for (int i = 0; i < MAX_PLAYERS; i++) { if (!rp[i].present) continue; @@ -837,9 +957,9 @@ int main(void) { if (!rp[i].alive) c = (Color){120, 120, 120, 255}; - // Apply lighting with shadows to player models - Color litPlayerColor = - apply_lighting_with_shadows(c, terrainNormal, p, dirLight); + // Apply basic lighting to players + Vector3 playerNormal = v3(0, 1, 0); + Color litPlayerColor = apply_lighting_with_shadows(c, playerNormal, p, dirLight); DrawCapsule(v3(p.x, p.y - 0.5f, p.z), v3(p.x, p.y + 0.5f, p.z), 0.35f, 8, 8, litPlayerColor); } @@ -923,6 +1043,7 @@ int main(void) { } UnloadModel(terrainModel); + unload_terrain_shader(&terrainShader); CloseWindow(); CLOSESOCK(sock); #ifdef _WIN32 diff --git a/game/server b/game/server new file mode 100755 index 0000000000000000000000000000000000000000..1b9cead009e6f19583bcf60134dfe74d15ab3adf GIT binary patch literal 35160 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 IdZEhy0w3a2WdHyG literal 0 HcmV?d00001 diff --git a/game/terrain.fs b/game/terrain.fs new file mode 100644 index 0000000..fae6101 --- /dev/null +++ b/game/terrain.fs @@ -0,0 +1,86 @@ +#version 330 + +// Input from vertex shader +in vec3 fragPosition; +in vec3 fragNormal; +in vec2 fragTexCoord; + +// Uniforms +uniform sampler2D texture0; +uniform vec3 viewPos; +uniform vec3 lightDir; +uniform vec3 lightColor; +uniform float lightIntensity; +uniform float ambientIntensity; +uniform vec3 terrainColor; + +// Output +out vec4 finalColor; + +// Simplex noise for AO calculation +float hash(float n) { + return fract(sin(n) * 43758.5453123); +} + +float noise(vec3 p) { + vec3 i = floor(p); + vec3 f = fract(p); + f = f * f * (3.0 - 2.0 * f); + + float n = i.x + i.y * 157.0 + i.z * 113.0; + return mix( + mix(mix(hash(n), hash(n + 1.0), f.x), + mix(hash(n + 157.0), hash(n + 158.0), f.x), f.y), + mix(mix(hash(n + 113.0), hash(n + 114.0), f.x), + mix(hash(n + 270.0), hash(n + 271.0), f.x), f.y), + f.z + ); +} + +// Calculate ambient occlusion with more contrast +float calculateAO(vec3 position, vec3 normal) { + // Sample 8 directions around the surface + float ao = 0.0; + float radius = 2.5; + int samples = 8; + + for (int i = 0; i < samples; i++) { + float angle = 6.28318530718 * float(i) / float(samples); + vec3 offset = vec3(cos(angle) * radius, noise(position * 0.5 + float(i)), sin(angle) * radius); + + // Sample height variation (approximated via noise) + float heightVariation = noise((position + offset) * 0.3); + + // Calculate occlusion based on height and normal + float dotProduct = max(0.0, dot(normal, normalize(offset))); + ao += mix(0.0, dotProduct * heightVariation, 0.7); + } + + // Increased contrast: 0.8 multiplier instead of 0.6 + ao = 1.0 - (ao / float(samples)) * 0.8; + // Min 0.1 (darker shadows) instead of 0.2 + return max(0.1, ao); +} + +void main() +{ + // Normalize interpolated normal + vec3 norm = normalize(fragNormal); + + // Use normal Y component to create geometry-revealing green shading + // Higher Y normal (upward-facing) = brighter green (peaks/flat areas) + // Lower Y normal (sloped) = darker green (slopes/valleys) + float brightness = (norm.y + 1.0) * 0.5; // Map -1..1 to 0..1 + + // Increase contrast: darker minimum, brighter maximum + // Old range: 0.4 to 1.0 (0.6 total range) + // New range: 0.2 to 1.2 (1.0 total range) - much more contrast + float contrastMultiplier = 0.2 + brightness * 1.0; + + // Create base terrain color modulated by geometry + vec3 baseColor = terrainColor; + vec3 finalColorRGB = baseColor * contrastMultiplier; + + finalColor = vec4(finalColorRGB, 1.0); +} + diff --git a/game/terrain.vs b/game/terrain.vs new file mode 100644 index 0000000..6764ee3 --- /dev/null +++ b/game/terrain.vs @@ -0,0 +1,31 @@ +#version 330 + +// Input vertex attributes +in vec3 vertexPosition; +in vec3 vertexNormal; +in vec2 vertexTexCoord; + +// Uniforms +uniform mat4 mvp; +uniform mat4 matModel; +uniform mat4 matNormal; + +// Output to fragment shader +out vec3 fragPosition; +out vec3 fragNormal; +out vec2 fragTexCoord; + +void main() +{ + // Transform vertex position to world space + fragPosition = vec3(matModel * vec4(vertexPosition, 1.0)); + + // Transform normal to world space + fragNormal = normalize(vec3(matNormal * vec4(vertexNormal, 0.0))); + + // Pass texture coordinates + fragTexCoord = vertexTexCoord; + + // Transform to clip space + gl_Position = mvp * vec4(vertexPosition, 1.0); +} From a092c1001723bc198c05c9dea5ed24105c591de2 Mon Sep 17 00:00:00 2001 From: Masashi Date: Thu, 18 Dec 2025 21:41:17 +0530 Subject: [PATCH 2/8] BETTER TERRAIN --- game/client | Bin 30248 -> 30248 bytes game/client.c | 169 ++++++++++++++++++++++++++++++-------------------- game/server | Bin 35160 -> 35160 bytes game/server.c | 9 +-- 4 files changed, 106 insertions(+), 72 deletions(-) diff --git a/game/client b/game/client index 09033d3f38765b7bb5af2aebc2b3e6cf44ce0e1d..b57a50bfa8e44b4f4c0913b8889194a7f623074a 100755 GIT binary patch delta 8602 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 0) ? mesh.vertices[(z * size + (x - 1)) * 3 + 1] : mesh.vertices[idx * 3 + 1]; - float h_down = (z + 1 < size) ? mesh.vertices[((z + 1) * size + x) * 3 + 1] : mesh.vertices[idx * 3 + 1]; - float h_up = (z - 1 >= 0) ? mesh.vertices[((z - 1) * size + x) * 3 + 1] : mesh.vertices[idx * 3 + 1]; - + float h_right = (x + 1 < size) + ? mesh.vertices[(z * size + (x + 1)) * 3 + 1] + : mesh.vertices[idx * 3 + 1]; + float h_left = (x - 1 >= 0) ? mesh.vertices[(z * size + (x - 1)) * 3 + 1] + : mesh.vertices[idx * 3 + 1]; + float h_down = (z + 1 < size) + ? mesh.vertices[((z + 1) * size + x) * 3 + 1] + : mesh.vertices[idx * 3 + 1]; + float h_up = (z - 1 >= 0) ? mesh.vertices[((z - 1) * size + x) * 3 + 1] + : mesh.vertices[idx * 3 + 1]; + // Compute finite differences float dh_dx = (h_right - h_left) / (2.0f * TERRAIN_SCALE); float dh_dz = (h_down - h_up) / (2.0f * TERRAIN_SCALE); - + // Normal from height field: (-dh/dx, 1, -dh/dz) then normalized float nx = -dh_dx; float ny = 1.0f; float nz = -dh_dz; - + float len = sqrtf(nx * nx + ny * ny + nz * nz); if (len > 0.0001f) { mesh.normals[idx * 3 + 0] = nx / len; @@ -377,11 +383,11 @@ static Color apply_lighting_with_shadows(Color baseColor, Vector3 normal, } static Vector3 v3_normalize(Vector3 v) { - float len = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); - if (len < 0.0001f) - return (Vector3){0, 1, 0}; - return (Vector3){v.x / len, v.y / len, v.z / len}; - } + float len = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); + if (len < 0.0001f) + return (Vector3){0, 1, 0}; + return (Vector3){v.x / len, v.y / len, v.z / len}; +} // ============== VECTOR3 HELPERS ============== static Vector3 v3(float x, float y, float z) { @@ -410,24 +416,25 @@ static Vector3 v3_norm(Vector3 a) { // ============== ENHANCED LIGHTING & AMBIENT OCCLUSION ============== -// calculate_ambient_occlusion: Estimates how occluded a point is based on terrain curvature -// Samples heights in cardinal directions and computes horizon angle to terrain -// Returns occlusion factor from 0 (fully occluded) to 1 (fully lit) +// calculate_ambient_occlusion: Estimates how occluded a point is based on +// terrain curvature Samples heights in cardinal directions and computes horizon +// angle to terrain Returns occlusion factor from 0 (fully occluded) to 1 (fully +// lit) static float calculate_ambient_occlusion(Vector3 worldPos, Vector3 normal) { // AO based on terrain curvature: check if terrain rises around the point float sampleRadius = 3.0f; float aoAccum = 0.0f; int numSamples = 8; - + float centerHeight = worldPos.y; - + // Sample 8 directions around the point for (int i = 0; i < numSamples; i++) { float angle = (2.0f * 3.14159265f * (float)i) / (float)numSamples; float sx = worldPos.x + cosf(angle) * sampleRadius; float sz = worldPos.z + sinf(angle) * sampleRadius; float sh = get_terrain_height(sx, sz); - + // Check if terrain is higher relative to surface normal // Higher terrain in shadow-casting areas reduces occlusion float heightDiff = sh - centerHeight; @@ -437,53 +444,63 @@ static float calculate_ambient_occlusion(Vector3 worldPos, Vector3 normal) { aoAccum += aoAmount; } } - - float aoFactor = 1.0f - (aoAccum / (float)numSamples) * 0.6f; // 60% max occlusion - return fmaxf(0.2f, aoFactor); // Min 20% brightness + + float aoFactor = + 1.0f - (aoAccum / (float)numSamples) * 0.6f; // 60% max occlusion + return fmaxf(0.2f, aoFactor); // Min 20% brightness } -// apply_phong_lighting_per_pixel: Advanced Phong lighting with per-pixel normals -// Includes diffuse, specular highlight, and ambient occlusion for geometry detail +// apply_phong_lighting_per_pixel: Advanced Phong lighting with per-pixel +// normals Includes diffuse, specular highlight, and ambient occlusion for +// geometry detail static Color apply_phong_lighting_per_pixel(Color baseColor, Vector3 normal, Vector3 worldPos, Vector3 camPos, DirectionalLight light) { // Normalize inputs Vector3 lightDir = v3_normalize(light.direction); Vector3 normal_norm = v3_normalize(normal); - + // Compute view direction (from surface to camera) Vector3 viewDir = v3_normalize(v3_sub(camPos, worldPos)); - + // Diffuse component: Lambertian shading float diffuse = fmaxf(0.0f, -v3_dot(lightDir, normal_norm)); - + // Specular component: Blinn-Phong specular highlight - Vector3 halfVec = v3_normalize(v3_add(v3_norm((Vector3){-lightDir.x, -lightDir.y, -lightDir.z}), viewDir)); - float specular = powf(fmaxf(0.0f, v3_dot(halfVec, normal_norm)), 32.0f) * 0.5f; - + Vector3 halfVec = v3_normalize(v3_add( + v3_norm((Vector3){-lightDir.x, -lightDir.y, -lightDir.z}), viewDir)); + float specular = + powf(fmaxf(0.0f, v3_dot(halfVec, normal_norm)), 32.0f) * 0.5f; + // Ambient occlusion from terrain geometry float ao = calculate_ambient_occlusion(worldPos, normal_norm); - + // Shadow based on height (distant higher terrain casts softer shadows) - float shadowFactor = calculate_shadow_factor(worldPos, light.direction, 10.0f); - + float shadowFactor = + calculate_shadow_factor(worldPos, light.direction, 10.0f); + // Combine lighting components float brightness = light.ambientIntensity * ao; - brightness += diffuse * light.intensity * shadowFactor * (1.0f - light.ambientIntensity) * ao; - brightness += specular * light.intensity * shadowFactor * 0.6f; // Specular less affected by AO - + brightness += diffuse * light.intensity * shadowFactor * + (1.0f - light.ambientIntensity) * ao; + brightness += specular * light.intensity * shadowFactor * + 0.6f; // Specular less affected by AO + brightness = fminf(1.0f, brightness); - + // Apply brightness to base color int r = (int)(baseColor.r * brightness); int g = (int)(baseColor.g * brightness); int b = (int)(baseColor.b * brightness); - + // Clamp to valid RGB range - if (r > 255) r = 255; - if (g > 255) g = 255; - if (b > 255) b = 255; - + if (r > 255) + r = 255; + if (g > 255) + g = 255; + if (b > 255) + b = 255; + return (Color){r, g, b, baseColor.a}; } @@ -663,9 +680,12 @@ int main(void) { // Load terrain shader TerrainShader terrainShader = load_terrain_shader(); if (terrainShader.shader.id == 0) { - fprintf(stderr, "Warning: Failed to load terrain shader, using default rendering\n"); + fprintf( + stderr, + "Warning: Failed to load terrain shader, using default rendering\n"); // Fallback: Make terrain very bright red to show shader failed - terrainModel.materials[0].maps[MATERIAL_MAP_DIFFUSE].color = (Color){255, 100, 100, 255}; + terrainModel.materials[0].maps[MATERIAL_MAP_DIFFUSE].color = + (Color){255, 100, 100, 255}; } else { terrainModel.materials[0].shader = terrainShader.shader; fprintf(stderr, "Shader loaded successfully!\n"); @@ -692,12 +712,10 @@ int main(void) { Vector3 camPos = v3(0, 5.0f, 6); float yaw = 0.0f, pitch = 0.0f; - float recoilYaw = 0.0f, recoilPitch = 0.0f, crossSpread = 0.0f; - float fireCooldown = 0.0f; - int shotsInBurst = 0; - float burstResetTimer = 0.0f; - - + float recoilYaw = 0.0f, recoilPitch = 0.0f, crossSpread = 0.0f; + float fireCooldown = 0.0f; + int shotsInBurst = 0; + float burstResetTimer = 0.0f; const float pistolFireRate = 4.0f, rifleFireRate = 12.0f; const float recoilReturn = 18.0f, crossReturn = 14.0f; @@ -790,6 +808,10 @@ int main(void) { camPos.x = body.x; camPos.y = body.y + 1.0f; camPos.z = body.z + 0.0001f; + + // Prevent camera from clipping into terrain + float terrain_h = get_terrain_height(camPos.x, camPos.z); + camPos.y = fmaxf(camPos.y, terrain_h + 1.5f); } } else if (type == MSG_ITEMS && n >= (int)sizeof(MsgItems)) { MsgItems *m = (MsgItems *)buf; @@ -846,8 +868,6 @@ int main(void) { if (IsKeyPressed(KEY_SPACE)) buttons |= BTN_JUMP; - - if (myId != 255) { MsgInput in = {0}; in.type = MSG_INPUT; @@ -908,25 +928,36 @@ int main(void) { // Set up shader uniforms for terrain rendering if (terrainShader.shader.id != 0) { - // Convert light direction to shader format (should be pointing TO the light) - float lightDirArray[3] = {-dirLight.direction.x, -dirLight.direction.y, -dirLight.direction.z}; - float lightColorArray[3] = {dirLight.color.x, dirLight.color.y, dirLight.color.z}; + // Convert light direction to shader format (should be pointing TO the + // light) + float lightDirArray[3] = {-dirLight.direction.x, -dirLight.direction.y, + -dirLight.direction.z}; + float lightColorArray[3] = {dirLight.color.x, dirLight.color.y, + dirLight.color.z}; float viewPosArray[3] = {camPos.x, camPos.y, camPos.z}; // Terrain color in 0-1 range (80, 140, 70) / 255 - float terrainColorArray[3] = {80.0f/255.0f, 140.0f/255.0f, 70.0f/255.0f}; + float terrainColorArray[3] = {80.0f / 255.0f, 140.0f / 255.0f, + 70.0f / 255.0f}; // Debug mode: 0=normal lighting, 1=show normals as colors, 2=show AO only - SetShaderValue(terrainShader.shader, terrainShader.locViewPos, viewPosArray, SHADER_UNIFORM_VEC3); - SetShaderValue(terrainShader.shader, terrainShader.locLightDir, lightDirArray, SHADER_UNIFORM_VEC3); - SetShaderValue(terrainShader.shader, terrainShader.locLightColor, lightColorArray, SHADER_UNIFORM_VEC3); - SetShaderValue(terrainShader.shader, terrainShader.locLightIntensity, &dirLight.intensity, SHADER_UNIFORM_FLOAT); - SetShaderValue(terrainShader.shader, terrainShader.locAmbientIntensity, &dirLight.ambientIntensity, SHADER_UNIFORM_FLOAT); - SetShaderValue(terrainShader.shader, terrainShader.locTerrainColor, terrainColorArray, SHADER_UNIFORM_VEC3); + SetShaderValue(terrainShader.shader, terrainShader.locViewPos, + viewPosArray, SHADER_UNIFORM_VEC3); + SetShaderValue(terrainShader.shader, terrainShader.locLightDir, + lightDirArray, SHADER_UNIFORM_VEC3); + SetShaderValue(terrainShader.shader, terrainShader.locLightColor, + lightColorArray, SHADER_UNIFORM_VEC3); + SetShaderValue(terrainShader.shader, terrainShader.locLightIntensity, + &dirLight.intensity, SHADER_UNIFORM_FLOAT); + SetShaderValue(terrainShader.shader, terrainShader.locAmbientIntensity, + &dirLight.ambientIntensity, SHADER_UNIFORM_FLOAT); + SetShaderValue(terrainShader.shader, terrainShader.locTerrainColor, + terrainColorArray, SHADER_UNIFORM_VEC3); } - + // Draw terrain with shader - terrainModel.materials[0].maps[MATERIAL_MAP_DIFFUSE].color = (Color){80, 140, 70, 255}; + terrainModel.materials[0].maps[MATERIAL_MAP_DIFFUSE].color = + (Color){80, 140, 70, 255}; DrawModel(terrainModel, (Vector3){0, 0, 0}, 1.0f, WHITE); // Items with basic lighting (no shader for now to keep it simple) @@ -943,7 +974,8 @@ int main(void) { // Apply basic lighting to items Vector3 itemNormal = v3(0, 1, 0); - Color litColor = apply_lighting_with_shadows(ic, itemNormal, wi[i].pos, dirLight); + Color litColor = + apply_lighting_with_shadows(ic, itemNormal, wi[i].pos, dirLight); DrawSphere(wi[i].pos, 0.3f, litColor); } @@ -959,7 +991,8 @@ int main(void) { // Apply basic lighting to players Vector3 playerNormal = v3(0, 1, 0); - Color litPlayerColor = apply_lighting_with_shadows(c, playerNormal, p, dirLight); + Color litPlayerColor = + apply_lighting_with_shadows(c, playerNormal, p, dirLight); DrawCapsule(v3(p.x, p.y - 0.5f, p.z), v3(p.x, p.y + 0.5f, p.z), 0.35f, 8, 8, litPlayerColor); } diff --git a/game/server b/game/server index 1b9cead009e6f19583bcf60134dfe74d15ab3adf..f9cddc2ebdaac3b72e0cc239fb1d29de81633af8 100755 GIT binary patch delta 8901 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 & BTN_JUMP) { const dReal *lvel = dBodyGetLinearVel(p->body); - dBodySetLinearVel(p->body, lvel[0], 12.0f, lvel[2]); // Set upward velocity + dBodySetLinearVel(p->body, lvel[0], 12.0f, + lvel[2]); // Set upward velocity printf("Player %d jumped\n", pid); } } From 6b8564cb0c7844b019a9b58191043d1bc9b7b88e Mon Sep 17 00:00:00 2001 From: Masashi Date: Thu, 18 Dec 2025 21:51:21 +0530 Subject: [PATCH 3/8] wider terrain --- game/client | Bin 30248 -> 30248 bytes game/client.c | 12 +++++++----- game/server | Bin 35160 -> 35160 bytes game/server.c | 6 +++--- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/game/client b/game/client index b57a50bfa8e44b4f4c0913b8889194a7f623074a..fbb164f9b646dcbefd146289c96ff69e39629fd8 100755 GIT binary patch delta 3165 zcmZuzYgAO%6~1SfA)w$HR1oENt*A4{cqER_!CpWtO!%)+kyTKpE8P@)c`*L}Gm0QB)Fq5L9lzb4UHrC2KMJoNw>5 z&)(nO=bXE}gKY00|J)ijFn`;$efI*n4Sf?$2Z!#;lq%;P{m!>HY*z}o&*l%`O13hc z=p@-}jaW&V*=_L$1yO?Jc8XIqf*|jDswjus;2+l2U!Dts;N9~KUdrt)4`J}hk`hK&GE^MMPC3$(a}|AMNzniKsYuQ=m1-{^kS*&U8oTID$WyRqa2cT4+pW2 zGK*q2ronz?GJGN=M+O(s)$ClRp$2y4_8Z_^swCCq1McO4dkmMR1dkm z%-Ut?RTQg7XN51T`+LdVZ9L1F5&7I>6?47+>P2_lokCM;)nI4qf(CWl>s%PFhnTp* zmXAzG4kfYp1Igi!a*TU;0}(bmf-LsIt$wkT^b?-Ao;$$Loc zdrpDMqzkUkeZXIk9+w*$)g(p?~=DT zm1{Gc;%VL-I8NVH7CC}cM7B^sF zb{~P!MI14rUJ_XV``8w+6)y5rl>kpog(P&)N%Hc@ZnfNshK7M7Kq>y8LwYO;(kYCf0Q+ z%3&=GEpDauKN0R`qhJ0VFv(jlYQZcx-N-)68BG?jYdP~sI5X#_4bSCtd31wOM^xCf zGer;rPH{cF@IOGKG|Zj5DE+-oMREG6t8afna5%+!D2Wy2#=HrSO%2<<0DpF)?!?(vaL*5sh>b|IJ-=4w|asBsDZqL$HfB z>j;c>bf(Ob^2XL&4f!zH%V$_({!sEYdow?^ p5BliAawje*B ze8jfo$C9}l3I?-N`EiNWVg=S65;r1Xnscd(##D!k=rz&I(1i(GnjT< z=@{Q_MX`9+s?11^Be|unW7M@c65Z;l78e1j<@uHx6;JH>ShWhVSJ;Q+Qpi-cd7NGK zJwC2x1dW*XOt%FX z-%hsO44tFn@gV>&o9?i>pz;4V{&J(vz+K5)dpzvBq^4YPg6radE*z zJwE7gGe@Yb&e5g7IW?T(8jG0Q7=rc44GTtXV842E!ay~y6DV*+GtB1rQH0a%$eUA> zt75QrK)sj>hjgF6sa+r0Vm|@Liu;nhjpa=!N^A$;@DzKVOHRQ#41#y?aV3vsYbGQ{ zwV@%5_pIJUS;5_G&jg87u%{E|OVGbi$SC35q~heSvLgj;@#T zNt>FCzPN+WTK%(VPB&fU3t6hqU>8mA|WLadt)9IQg{Z6NaRYdixP1lrTIGtlH9Q#Jgu~I%f;7j>& HWa|F_It`nx delta 2997 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 delta 3153 zcmZuz4OEm>8vgFc1Z<4okc@x`OwNb=!wksJpyUh;^Z`Qx>ZV4@3FK5}5&^m8N!WpO z8aR@#?b6@oww+z~ueP0bOCw@3Q(McQEmvLAVvq76mISWhsrB3Eeo%Jy?3^?A{d?|v z?|t9*zV|z|Q+H~ot~ZKVpNhU5TDeHjewF@kwnG8j`M$liK3 zZ;t= zaC+W@a6kwW1ZT&$n(n22oD8%JRFfdZa$fcxl)d{WM58|BHbDS2O%)2lULYtzGM!VF z|3_72UtvRoAnaor{wy6yShaQviw|(cJAA-43>gI))u(_er@1+fn`h0KBWKL#>@e@+ z<}hy7&6ux14KMm}Zhnq_y0BZnSAc5@Pc+Zo2Bo{_W$7~8UKeRM~akxFQ&DflzR%Ba|OZWy=og&p8mJ0mie}B zmb=szgA#lV(!tv|b3f2FO=|=6e2R_5(?=V=h%?M9uAo=6mzQGv*C2XR*!nT81gKW=2;|M>F2o`VSt3z=hy)U;m=rp-AK> zI+};T}FdXdb zj<6z1U5CZa<1l#oBbp!zV&{HHH*zL>BP3-hy^@ny`fB=g5n<+LK(SL(EmU2HTSGW6 zgLiw!8^xqUa^SOI6j^srFL0=`{Mjd?dnSG$1eyIvA0HM6=OMbv^ zNkLzceJdoRZE(!!8Dz5OV!J1O$|!ag0O2VRTE=91`R3O1PWwTzb0MGA$7AT}51L8J zE#zJttGn`rf5YN=LF^Pgv9uH|`@^Mi>>0YW)NTp>oUi1PP&%7(&Me@|75=?U5Q@a) zmV5_SenPS%?%tEY@nl^EWahXdkPWjfT0-@lmU}ywXcy={fN_B|!R@`EBoE(^F-boP zCrZ%&D2KRm2Yuvlup$zjme~8xX-gVXVBoXLL9x5HWZ*JrnKROP^6a$VJ*bue9U`Z! zz#P7^rr}vBL2OmPWZy2yiY~0RLEPP2;(>0Y-#9I-hW>^zgDyKWb=N;7b5SZgPVS;K z_A>pX$imv`g(5RsM*|pdqjMNzcNSZ8*M=yecmYFniY@FldZ5_MdZ`EFCVHjVGP`03 zP2oc%#O>>p_K>Z3E=#1V#a--|w8drSPBFr%%fc4ZFvdu_sl=k2JVU7^@u=L25;OOT z5nf9y>;ZZWqfDP*l;|4tvuIwaSvP!|mXt1F1GKKxGVj^bSoFOwctwr#GC%Hq%DA*}O7x z`U+Kpj_%iL(=8cGY*=RtbBwMdRZgq=>I}S^9>!C1<;IhQNO$0Qz+#VbVxMX;$v*v$ z0g}50TSC>(#Q1h(N!UL_fv?u^Ipy?N*?g8jePwZ}2~Y{G*(+sF;h7w;viE$80i|#u zPY_hoA*hskEdIX!+dTTbY#I9#*~;g!r^sD?Yv`tvs)}bKb`!OgKN))|f}dp77}pGG zeC;GIIWD>}_G5~z$Yy__>WUoJM%yZ!Y!Mx<$eD9}t{`}Zbzm zA&y3>7aG4YXu5`J-B$*Rtw~7!Xj-{Kib4WhnyFTrKPj%&hlO)^xJwFy3;pkCL(TH^ ztZB5NMx($Rfeav&_(KA6wZ355rq89Z8uYjf`qA<`oPGFuli8T~hJH=P%r1i9)-8p& zwr{uzlTRTS+faZ#Rm|nB=P!_ckEm^+KCIDelIWS`aqKVj=JI4~Dh`gfHEIBDSWrGa zGA-e|Z08J%G)Kwavv=L?taaW!n&uB*arEY$b@%Ani>RS)fo{;@-(EL+7OSJ5*WZbH zyj-7Sv*L-^40jH^8*hS|M^$wQbT{ZYsP&Snn$f6wagD1$&9t&16&2mluoPV*&|onw z!Bg=NkoZRQr2g%d|JIe28Gyaw) * dz - cosf(p->yaw) * dx; float fz = cosf(p->yaw) * dz + sinf(p->yaw) * dx; dBodySetLinearVel(p->body, fx * speed, lvel[1], fz * speed); From 7fc4e9cd3c81d7afc9f81d45ed511cf8a3f681ad Mon Sep 17 00:00:00 2001 From: Masashi Date: Thu, 18 Dec 2025 21:55:51 +0530 Subject: [PATCH 4/8] wider terrain --- game/client | Bin 30248 -> 30248 bytes game/client.c | 20 ++++++++++-------- game/server | Bin 35160 -> 35160 bytes game/server.c | 55 ++++++++++++++++++++++++++++++++++++-------------- 4 files changed, 52 insertions(+), 23 deletions(-) diff --git a/game/client b/game/client index fbb164f9b646dcbefd146289c96ff69e39629fd8..44a59f91f0ab91f3947805b09d423a8cba05bc5e 100755 GIT binary patch delta 3544 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 delta 3464 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 MSv$P8Cw`dqe@mzG+yDRo diff --git a/game/client.c b/game/client.c index c775424..055f10e 100644 --- a/game/client.c +++ b/game/client.c @@ -21,7 +21,7 @@ typedef int socklen_t; #define CLOSESOCK close #endif -#define PROTOCOL_VERSION 5 +#define PROTOCOL_VERSION 67 #define SERVER_PORT 27015 #define MAX_PLAYERS 16 #define USERNAME_MAX 16 @@ -558,6 +558,7 @@ typedef struct PlayerStateNet { float x, y, z, yaw, pitch; uint8_t weapon; int16_t pistolMag, rifleMag, pistolAmmo, rifleAmmo, medkits; + int16_t reloadTimeLeft; char username[USERNAME_MAX]; } PlayerStateNet; @@ -589,6 +590,7 @@ typedef struct RemotePlayer { float yaw, pitch; uint8_t weapon; int16_t pistolMag, rifleMag, pistolAmmo, rifleAmmo, medkits; + int16_t reloadTimeLeft; char username[USERNAME_MAX]; } RemotePlayer; @@ -715,7 +717,7 @@ int main(void) { float recoilYaw = 0.0f, recoilPitch = 0.0f, crossSpread = 0.0f; float fireCooldown = 0.0f; int shotsInBurst = 0; - float burstResetTimer = 0.0f; + float burstResetTimer = 0.0f; const float pistolFireRate = 4.0f, rifleFireRate = 12.0f; const float recoilReturn = 18.0f, crossReturn = 14.0f; @@ -799,15 +801,16 @@ int main(void) { p->pistolAmmo = ps->pistolAmmo; p->rifleAmmo = ps->rifleAmmo; p->medkits = ps->medkits; + p->reloadTimeLeft = ps->reloadTimeLeft; memset(p->username, 0, USERNAME_MAX); strncpy(p->username, ps->username, USERNAME_MAX - 1); } if (myId != 255 && rp[myId].present) { Vector3 body = rp[myId].pos; - camPos.x = body.x; - camPos.y = body.y + 1.0f; - camPos.z = body.z + 0.0001f; + camPos.x = body.x; + camPos.y = body.y + 1.0f; + camPos.z = body.z + 0.0001f; // Prevent camera from clipping into terrain float terrain_h = get_terrain_height(camPos.x, camPos.z); @@ -854,8 +857,6 @@ int main(void) { if (IsKeyDown(KEY_S)) moveZ -= 1.0f; - - uint8_t buttons = 0; if (IsKeyPressed(KEY_ONE)) buttons |= BTN_SWITCH_PISTOL; @@ -1055,7 +1056,10 @@ int main(void) { DrawText(TextFormat("%d", currentMag), sw - 250, sh - 75, 40, RAYWHITE); DrawText(TextFormat("/ %d", reserveAmmo), sw - 140, sh - 65, 24, (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}); } diff --git a/game/server b/game/server index e113afb8f9efb29ae34ce5b9e6970ae18cc4b406..1bf56063225deb474713e667740d708cbf60fdee 100755 GIT binary patch delta 8696 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 delta 8608 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 = WEAPON_RIFLE; if (m->buttons & BTN_RELOAD) { - if (p->weapon == 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; - } + if (p->reloadTimer <= 0.0f) { + p->reloadTimer = 2.0f; // 2 second reload time + p->reloadWeapon = p->weapon; } } @@ -730,6 +722,9 @@ int main(void) { if (now - sh->lastShotTime > 0.18) sh->shotsInBurst = 0; + if (sh->reloadTimer > 0.0f) + continue; + int *mag = (sh->weapon == WEAPON_PISTOL) ? &sh->pistolMag : &sh->rifleMag; if (*mag <= 0) @@ -801,6 +796,35 @@ int main(void) { dWorldQuickStep(gWorld, DT); 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++) { Player *p = &players[i]; if (!p->inUse || !p->alive) @@ -847,6 +871,7 @@ int main(void) { ps->pistolAmmo = (int16_t)players[i].pistolAmmo; ps->rifleAmmo = (int16_t)players[i].rifleAmmo; 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); } broadcast(sock, players, &snap, (int)sizeof(snap)); From de14cb8f14dafa682eb3308a5b7fab0a70b29340 Mon Sep 17 00:00:00 2001 From: Masashi Date: Thu, 18 Dec 2025 22:04:23 +0530 Subject: [PATCH 5/8] i fogot --- game/client | Bin 30248 -> 34344 bytes game/client.c | 4 ++-- game/server | Bin 35160 -> 35296 bytes game/server.c | 33 ++++++++++++++++++++++++++++++--- 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/game/client b/game/client index 44a59f91f0ab91f3947805b09d423a8cba05bc5e..aa0316e22786c52b08bbbc4e847de1bbef911223 100755 GIT binary patch delta 12188 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 diff --git a/game/client.c b/game/client.c index 055f10e..9d38b78 100644 --- a/game/client.c +++ b/game/client.c @@ -176,9 +176,9 @@ static float fbm_noise(float x, float y, int octaves) { } float get_terrain_height(float x, float z) { - float height = fbm_noise(x * 0.03f, z * 0.03f, 4); + float height = fbm_noise(x * 0.05f, z * 0.05f, 2); height += fbm_noise(x * 0.01f, z * 0.01f, 2) * 1.5f; - return height * 6.0f + 2.0f; + return height * 4.0f + 2.0f; } #define TERRAIN_SIZE 256 diff --git a/game/server b/game/server index 1bf56063225deb474713e667740d708cbf60fdee..8a2b6891af6ba32baeea0bca61915852cf8ffe89 100755 GIT binary patch delta 11485 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 #include #include +#include #include #include @@ -142,9 +143,9 @@ static float fbm_noise(float x, float y, int octaves) { } float get_terrain_height(float x, float z) { - float height = fbm_noise(x * 0.03f, z * 0.03f, 4); + float height = fbm_noise(x * 0.05f, z * 0.05f, 2); height += fbm_noise(x * 0.01f, z * 0.01f, 2) * 1.5f; - return height * 5.0f + 2.0f; + return height * 4.0f + 2.0f; } #define TERRAIN_SIZE 256 @@ -550,6 +551,8 @@ int main(void) { WSAStartup(MAKEWORD(2, 2), &wsa); #endif + srand((unsigned)time(NULL)); + ode_init_world(); int sock = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); @@ -571,7 +574,7 @@ int main(void) { } Player players[MAX_PLAYERS] = {0}; - uint32_t serverTick = 0, itemsTickDiv = 0; + uint32_t serverTick = 0, itemsTickDiv = 0, spawnCounter = 0; printf("Server listening UDP %d\n", SERVER_PORT); double nextTick = now_seconds(); @@ -791,6 +794,7 @@ int main(void) { if (t >= nextTick) { nextTick += DT; serverTick++; + spawnCounter++; dSpaceCollide(gSpace, 0, &nearCallback); dWorldQuickStep(gWorld, DT); @@ -825,6 +829,29 @@ int main(void) { } } + // Spawn random items every 30 seconds (900 ticks at 30Hz) + if (spawnCounter >= 900) { + spawnCounter = 0; + for (int i = 0; i < 2; i++) { + int type_idx = rand() % 3; + uint8_t type; + int qty; + if (type_idx == 0) { + type = ITEM_MEDKIT; + qty = 1; + } else if (type_idx == 1) { + type = ITEM_AMMO_PISTOL; + qty = 10 + (rand() % 6); + } else { + type = ITEM_AMMO_RIFLE; + qty = 20 + (rand() % 11); + } + float x = (float)(rand() % 200 - 100); + float z = (float)(rand() % 200 - 100); + item_spawn(type, qty, x, z); + } + } + for (int i = 0; i < MAX_PLAYERS; i++) { Player *p = &players[i]; if (!p->inUse || !p->alive) From 7b8e7986620bc34ea2444aadf6587a6009eb7486 Mon Sep 17 00:00:00 2001 From: Masashi Date: Thu, 18 Dec 2025 22:07:12 +0530 Subject: [PATCH 6/8] scope --- game/client | Bin 34344 -> 34344 bytes game/client.c | 15 +++++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/game/client b/game/client index aa0316e22786c52b08bbbc4e847de1bbef911223..87018d34770d6938fa5887bc54b4dbc8377fa81a 100755 GIT binary patch delta 8485 zcmbtae_WJRx_@VwF(CB}2!;qsdelKh!O+meW^l0A92Lv9p@?M-xo+1jH%Hf6bx?-n zZ9r*Xw(EA;d#!c*xW(O@!K$!ae)t14)37c3p`~k@XVMHsT{Ua&_c`w%c|YCH{o~H( z!<=)T^F7ab&Ut>E=bT|%rFmPWxjMnz?S3ioLiEK9MSd=3)W@1On&axSFZ|B))K}N% z{?~t7u3Nqo##*@`0kp-^a-2|dAS zBXsY`kwZkRq7 znEfIeZm#w)57mmf2j5#U|0F@g8iZn6mu)(jK9RH>1pY==Q=a|OmGt!=k+&PKp(S!BBq|NY= z=6jqhX5-~Mq0GQ#*jT{NyFe{r&ooQJP^*j*ga)Z*wQO%G8e6#%Az`)LW>ji;3Mwr1 z7QT|FOM)>DWBlA930pZC4@(_c%d2IjhHsH&C4Wnne%^+X45>^1?Sy-L#3vB{3Y=4| zntT%lvsY(t zOV*BRo#cz;sqn?O!4a6Z&=TjmL!m&kPc~H8cNnsnAo~D1jTuF!1pQCU8ep7S2S9>A zul*?KNeSu%=sbbe094{+Prp~fp57N|mMl^Ai66}EFvRNyzJx70MDPo!>?>hQ+gYlG zi>W_4Q{t_eF4IhL0J*egxmD1Ng+m0|J~c2vTOjocU0?@5{=hVc=;3Wmg>FD+sg=Bx z_6vY5DA7%D+T?1Knu`~gx3TgYLlmXS0lqCDQY@OQSErBlWumX*_m@H;r`DPAzSh|S z{VEx4?y3f9Olnmf&jU$32#8AywOG(y`fjAQJEKiZ0Zpx{;c)=K8s?`XlEGLMwbL(Y zs4A!?5lf?LL)EPOe1ltS;M+hFzLDRALK$t1rD!0yQb>fA=iQ+wjcp(`F-dRcn^DS6 zKbLVBpvmCX;pZ;mu4)~ql5LtWVFt>XlIr41L_793;{arLHrha(t93WUQzurK9^r#! zwBl$8N&7-XNYf{vFJOHa&e`eWML<%SKxLqoSD-*dSW1D;mi8t2Z{QHp{-7+(-B^TK6Pxb(%ziiL;Uo^a_6m&>Tcgmv7Hint5A<%cpilg!EaWMu?Uvk({{21k*zSW?wy+&T51<2< zMFS@sVmUHEBFGjnJBH+2tJ0(`C5WvTLLu-SPXRi)47Q9?vd)kHg??^Qk`GZj#=^l7 zq7>}ISR4c%lt#qfE!+kJFHfRb)vB<)N@=Y_!BB`%BHK|T_qX(hdBv)-Yu2^PU2I1){~5OYTx~_Ig^Uq-zycJCSon1) zr0toHv77coQ9*$(Hr#~?pA^`nfjv3Q7WZZ@dE=$4IITeig})iROfBsiZAb8ve}qC+ zYa`SrX_Nc^HCUxTk(rP*6egOT3+H1SZKzTZB9~CH$|d?snF%wOz-82_uy=1lCpyq5 zYfJBRP{1?jD+Jr&=ZhgI49LIhdx*B98yll_pNlHH?qL2u>gO|Ez9QLS0BP&6QRM&h zLAAQC+SOOJL9Q?$udiC&SMBPn+OYq<*uH9YZ`B72?5+E`tzRFwuUg$#?dq%AumSX; z)tx};(u#RXZpLYswv=Z^tD4t3BCz}>im|HpIg7bNY&$0%Bds}& zqV_j!&a%BGxh#v((%;}~avH-IqetJo06(iV0bb;Vu_78tWF~vH< z;FFxFpSXAM6bvy2dfb%%8BxrZ38cr%y=>wU(6E!n(4%AILgNqXZ z5KFGZCWcRWl-5`_L#!k-;tpYM!RvWspiSjrC(Ak-L85*YfF7Z0)^ zu?eGSBDo-_8^8*ZACm6}ZxH;F6)JEbd>8ZdfZT5igC7GzAJ}%g4~BRNl}b4iCTTFv zQ2X~7)gV&?W~cBkz1DLch&rhS7WW;q2buj{Fu1@5HS;Z!BYJ7mSsYv#2f5*t`@n+P zJJ{eLORWp21joyd>#FjNFTA=cVOkM8xEff ziQl8f?C3=Poi4LVnir?xN#N+n?M7)F<a-wQ=GJDAQdbV~nxEj>yX6ApD$_V}G>CwJ9Bc;v6KVX!}GpTek+bl>$ ziB*9$O7_6^98g68MVOdku8N~yNbAj>hQMV&3#}6*wBQ=EcZwb8H|Vq|>=iZx(~{vy zoAb!V;~qa>C~KZ}_Nev!(FQZ|oWWgAXT#KuA?!V~UjrY5TiPB#!N}S=LN1_zF9jQU zd{CT*Q7_RS${rmL-x|MX>V7uAy#mSHcrv~CU+GoZ_rw<9*ws#;UAeayRq@d&{r&7Q zzIX1H{Nkx(_Txbx(h7h^y&a~%Zj{MypbRbwcfKUS9}s>%NGdXE%Gu-zo~xa4YR8d* zp9Dq4neLdaUC8)4XoC8CTsSp~4UX9!lujRVUuR&YrTprO7}ppdWmQUbwM0r-zBP~%)}1ZKSV*hUgWyIH z7(9AcW4pD!TAn4luwqqKZt4B?`^TFtCjEo^NBY(dr_uCcQ!x2i)Tef_`MX)%mn^Pp z9ZXEYGN0MY25sdIW13Oz0I?lyY!G}Hr1q1xs6FcrLd=l%sZdUaLS_3*v&%XhW#8Gn zGo67MvM%il+Qs4UE_c=92|+sNphDb{3O~l*NtgxJ=a&&1 zroWfj&!W8*=K>BZ5ROAHr?CrrnEexU6!3K2?Bu>K%m_QF-YbvJEs9n`nI){cOV?Ij_w( z*-1?#TWn%C+wf-tGFd`iMWY2bMO=8W6a)~8I=B{z*PsEgl>{8<4sADWzH4eX^Y??v zv|K?bZlteWS1{U9(E|ly$<|ZJl2^rhjl@-|UgtTJed|9nBwu+qysWGPs@>~wmVJ-p zx)C@hGLiSo4|vZwOQ&+C3_-RN;S|O8v{J6 z`6+V92yT~_V(m&XoGciR zM2?~gtb?*AZ<5TyH98WJiU(?BCSLwND?eexn6iplz z$i$4ZxBN*^TUY9@&KxuivW&;AwB?_md1uwEeyN?rTYUIArrp)uedTx~q8EBvUO?GI zJS9{#e6BaoyxaFuACCH*RXd&rqb3^DO2?j91^_n0>K_U+_-$!f0zhji^~Ir2{QEHo z=a=arX3i5n2ul~FCAg`o0he(+lac<|N$W$Lz3r$4TWPz}n*ZM?tyoSwXFS}|Axqcd zKjA(n#*xrSQPailPw8=pPGWkTFILAHul1~a2#y+c-ClabfBXq&f%6Gxq4TGE^txHY zELmdaXZqn;iLsAjQ^X>0poL}yDsh3kF)Jw=X>{53>1@-82z~eiGalFuA)MB+}d1?DoI+%Lz2}_e794Ag2_y$Mjbp7+SLF z69bynxC$ei;6HdC%U+5>Ijpsz|MS3?lwW1@jv!k)4n#)V_Ei-hvYkiPy`w0rRypzd zStC2dWNbmM)-Bzv32%PTL}!Z>XWS?H-D;v^Czy)p-uZG$oBJ;VcZK=)zyNaC&YJ#S zw4F_%my1KQ*v`uStI$-dtdY10x>)Na{dskmPj!*>^0h@Q#*8j(6q5VZNEDK20gIsU zmVRX98$PDn>s74gMKHkAUkUcrx$DZ6E1^c@Zc0-*pd_P2=L5}Jad`sXW8kMqd_zM+ zs4;=?n}8or1H8mO6$401((Ovhnk}p4Vm6UeG4n%tlnC(0 zFAg+6i7)RwVX=&5h(rT;{&rxu8T;S6fH3mn2a;tskhvLcyd8PEwT1eLaX^>oQ3X*5|31dd(XTg>D3hegcjPon*sHiNl_73H$G!T^)_dKGOWlzFjDF2LifEviYa1V0g_!N-DlbF84YRS|W zxbII^V&!(YcqBH(&GB2S2bm5ojux@*Z~A|@Q=)(RH@T6?tugvXZf#gr3=Qy{gD)i4 zO2;bbL25)PZ*oeEzIN^;^YlUb+jBF`{o-{o*J0iptB;+RIcQ@Xen~im+w2)gg)BEa z!>0doUb=Zstp1028PgKbz0K?`M$hCn`4rgVS_G@(!u z0YuVSXf2Yhe5=UVZ^&{l@Y_b5~ydW8NJW%w8Y+ b+|@{P*#td${eXzIjm@$Le_TK@_dc0eXG70 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 XJT^ri{lcu#9?CBG199#P7f1XLpVl!6 diff --git a/game/client.c b/game/client.c index 9d38b78..8b5bddd 100644 --- a/game/client.c +++ b/game/client.c @@ -714,8 +714,9 @@ int main(void) { Vector3 camPos = v3(0, 5.0f, 6); float yaw = 0.0f, pitch = 0.0f; - float recoilYaw = 0.0f, recoilPitch = 0.0f, crossSpread = 0.0f; - float fireCooldown = 0.0f; + float recoilYaw = 0.0f, recoilPitch = 0.0f, crossSpread = 0.0f; + int scoped = 0; + float fireCooldown = 0.0f; int shotsInBurst = 0; float burstResetTimer = 0.0f; @@ -870,6 +871,8 @@ int main(void) { buttons |= BTN_USE_MEDKIT; if (IsKeyPressed(KEY_SPACE)) buttons |= BTN_JUMP; + if (IsKeyPressed(KEY_Z)) + scoped = !scoped; if (myId != 255) { MsgInput in = {0}; @@ -921,7 +924,7 @@ int main(void) { cam.position = camPos; cam.target = v3_add(camPos, forward); cam.up = v3(0, 1, 0); - cam.fovy = 75.0f; + cam.fovy = scoped ? 30.0f : 75.0f; cam.projection = CAMERA_PERSPECTIVE; BeginDrawing(); @@ -1068,14 +1071,14 @@ int main(void) { // Crosshair { int cx = sw / 2, cy = sh / 2; - int gap = 6 + (int)crossSpread; - int len = 10, thick = 2; + int gap = scoped ? 2 : 6 + (int)crossSpread; + int len = scoped ? 5 : 10, thick = 2; Color col = (Color){240, 240, 245, 220}; DrawRectangle(cx - gap - len, cy - thick / 2, len, thick, col); DrawRectangle(cx + gap, cy - thick / 2, len, thick, col); DrawRectangle(cx - thick / 2, cy - gap - len, thick, len, col); DrawRectangle(cx - thick / 2, cy + gap, thick, len, col); - DrawCircleLines(cx, cy, 3.0f, (Color){240, 240, 245, 160}); + DrawCircleLines(cx, cy, scoped ? 1.5f : 3.0f, (Color){240, 240, 245, 160}); } EndDrawing(); From d1782e1265373426c01208486493988d1bf6ac81 Mon Sep 17 00:00:00 2001 From: Masashi Date: Thu, 18 Dec 2025 22:28:54 +0530 Subject: [PATCH 7/8] gam --- game/client | Bin 34344 -> 34416 bytes game/client.c | 68 ++++++++++++++----- game/server | Bin 35296 -> 39600 bytes game/server.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 221 insertions(+), 27 deletions(-) diff --git a/game/client b/game/client index 87018d34770d6938fa5887bc54b4dbc8377fa81a..0c15c789d7d2a3dd201ea555dbb94f2d64ed0f1f 100755 GIT binary patch delta 11723 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 yl^m#xCq7U86&#l^h{d%5AQP;60i(BmNgw0J{$W delta 11072 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[i].qty; wi[i].pos = v3(m->items[i].x, m->items[i].y, m->items[i].z); } + } else if (type == MSG_ROOM_STATE && n >= (int)sizeof(MsgRoomState)) { + const MsgRoomState *rs = (const MsgRoomState *)buf; + roomState = rs->state; + countdownRemaining = rs->countdownRemaining; + memset(winnerName, 0, USERNAME_MAX); + if (rs->winnerId < 255) { + strncpy(winnerName, rs->winnerName, USERNAME_MAX - 1); + } } } @@ -1068,6 +1079,30 @@ int main(void) { DrawFPS(sw - 90, 10); + // Room state overlay + if (roomState == 0) { // Waiting + DrawRectangle(sw / 2 - 150, sh / 2 - 50, 300, 100, (Color){0, 0, 0, 200}); + DrawText("WAITING FOR PLAYERS", sw / 2 - 120, sh / 2 - 30, 24, RAYWHITE); + DrawText("Need at least 2 players", sw / 2 - 100, sh / 2 - 5, 18, + (Color){200, 200, 200, 255}); + } else if (roomState == 1) { // Counting down + DrawRectangle(sw / 2 - 150, sh / 2 - 50, 300, 100, (Color){0, 0, 0, 200}); + DrawText("GAME STARTING SOON", sw / 2 - 120, sh / 2 - 30, 24, + (Color){255, 255, 80, 255}); + DrawText(TextFormat("%.1f seconds", countdownRemaining), sw / 2 - 60, + sh / 2 - 5, 20, RAYWHITE); + } else if (roomState == 3) { // Finished + DrawRectangle(sw / 2 - 200, sh / 2 - 50, 400, 100, (Color){0, 0, 0, 200}); + DrawText("GAME FINISHED", sw / 2 - 80, sh / 2 - 30, 28, + (Color){255, 80, 80, 255}); + if (winnerName[0]) { + DrawText(TextFormat("Winner: %s", winnerName), sw / 2 - 100, sh / 2 - 5, + 24, (Color){255, 255, 80, 255}); + } else { + DrawText("No winner", sw / 2 - 50, sh / 2 - 5, 24, RAYWHITE); + } + } + // Crosshair { int cx = sw / 2, cy = sh / 2; @@ -1078,7 +1113,8 @@ int main(void) { DrawRectangle(cx + gap, cy - thick / 2, len, thick, col); DrawRectangle(cx - thick / 2, cy - gap - len, thick, len, col); DrawRectangle(cx - thick / 2, cy + gap, thick, len, col); - DrawCircleLines(cx, cy, scoped ? 1.5f : 3.0f, (Color){240, 240, 245, 160}); + DrawCircleLines(cx, cy, scoped ? 1.5f : 3.0f, + (Color){240, 240, 245, 160}); } EndDrawing(); diff --git a/game/server b/game/server index 8a2b6891af6ba32baeea0bca61915852cf8ffe89..03a07482de264198b4064e3ed8b5d116efeb1c4b 100755 GIT binary patch literal 39600 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 literal 35296 zcmeHwdwf*Ywg1UuAR@^L7;IF~(GD6Y#son@K{8aW|%NR@sUiqttx*o9INf$f-vp3IEMqH5YBZD$nlu6|3i9Lbfkn zEH?u`wzav}EYf0qT8K0=KSqlY_-UZ=idDFoPu>*#_&6y4bw~VD53SF=cj0ed@2J>( zV)C{Jir=}Us&d(7Q!c40ySS>drm^YbrfHX5eA$%rhT8PWq8#cn^&$B`y0)Oe(L-?F zYeTO>{fFXz6FP>X7ux7K2Zj#Czr{xXO*VS2w$bxb8~TGbdSY$L{o1BpRW|zP*znJ@ zp|7^l^HbP)0b~YWX*T?&Hug`lsqX?C`pY)@{{lmXdR{l#@aNjtlVVfuDjRya4ZY1q zf2R$7yp5iSO}(br@XxfNAGImhXQTheHhO+$!~d3z{`+kFpKYT*-iCjXO}S6n@c+h! zztN`LjW+i8*yvwu!(U^gf0>OvV{Ph-Km zx#OU~IamqsM4NIa+3<`X>CJ=RyMc1wt8;4H@mj%Hi;PJmCILn zD=N#Y$~-0Bk_F6btSM{I%E$xO{Mv>}Z)I(bWJf;Pw6g1K>#NFu&8;t4S?Ptc+4bcm z-g1jNDc~t@@YdHN-xSE1pC45v&EOrH@+xb}OX?SwS7~LrHI?3LJvq__WVvgWH&&I@ zdrGS7Dr=T&Wmnf$)_C1sZ%OG2t;{HCSh1k4q_kXG5LNyy!)Mo4RaKUiXIFYrJITDD zZUr116`741EU&G^bwIj#Ea93JHUy^z7Oi*zJwhO;$Tv zH9nyECG>}BBQP^LyQHq65szOw)3k;n7QgfPWH(mgdDb?vt%zry+aPKaEp=W=1D#-2 zPS`iMzP7Q>RBEmK7yRkfwJ6fH0JdMm5hNzgxlm#(;_sG_8@ zN~s`B=7mfBFR)zza-R%j5cW}tW(Q}rdc;ZAhw)C>}8%gTvO zW4ctb&CScro?SFKeRBF#%}h^;rZO*&CNG_W5hRxJEdG7_9)pNB&XOZJ$Qy&0xu4%* zNi%Pl;ON(B>XwqiC^Q{l?b`xv@mGASnAsJvcFxt1|6r%$HHFV^8IBh5l*oy{x5CsX9-&%CDjWQsJ?r=(>0c$d89+KRa0 z<6Y86$fUUE`y@g=r^}?c7x*MX`be1+_hO$!NJm47UMqYuNqSP0s%do=x^AI2S?K0k zli5BCeH01mTI-Vu>OVu#2-f)|LVAi!iu-z>L`YX#A%d{cLO)Zoi2G&>{W})=77IPq zLf>wopJkzkEcCN2^ezki91FeMLT3zPUI%?LMf=Y+iGV#miI9GtOp1HhClS(}GAZu8 zK8cWizD$by37P^FSXFuTIf?O^mP{cR11B*g|4>rMD9il{c;QcW($3qg}%i?pKhUVx6rS! z&_fpb3=6%>LZ4}&cU$PQEcAmGy4ynUvCy+E^i#=G9ysNJQyw_wfm0qh<$+TkIOTy; z9{6AJz%l*YuZ-r86O5o^ZxNQuEg^4gU$@cxLc%Vgrf=#?Aoq=b8F&4>ETo99U|yuB z57+ok;xWX#1-^qgw+bR5f&Y#;w+JFz1pYYjc;Xuc{wQ&72}ITj{9)qU3W)dw{s3_< z%OZ6GzlS)N{*hvV-$k5D{z$&SZzs;Bek4oa^~AZvk7Nk^X5u4>I|aUsIG6O1WPvXs z&ZT@r6Zm}MT*60sPl7Q1YT{hFM|uRFO`J>iNVmYRAkM9uNJ!w5iF4^5*&^_X#8ZfG z6!-DUfOT?YTdj#G|{Cwiw0^dQL zOY2BT;J+izC3R$rz#k{hrF3MYz#k>fC3Iw+z#k^grE|n5@CS%<$sDN@_&vnARE`u2 z{4U~LB1iHCemik4jU!nCuP4qWaU?_FHxuVlIN}ueGU8kUN0J4;ggBSJ5l!IpiF3&t z>HU{@{=~V|jr0gSn>d%ak#2!sL7Yq5NJ!w5iE~LC*&^_X#JQA>Y!vtf#JPlxtP}Xz z#JO~h_yj(hIG3!EI)RTM&ZTOkSm3e5xkQcR3;e4afpcjZ$rAWc;@ldHWC;8t;#{Ie zoWPB?nU4bre~!8a4u{`D4UM4RWuU>88Q+T^Pe(V7H&(w;0LpfD^BZn-FLmGOzR6v* z3&Ir?eg?uvy25OK73unUesF18g?^q#)7;m)7rPhbWPajaxM+c~`eUjoGlDaOVk59q zl$6;Q-o*0vgkJ#&7r?IY@1ZQS&j>i~DMtxE21#IEVn6vB1?ivdKdL7uK5-RBt>DZu z&@1$`P6*_Zr5%cp?P!4uK=y z1RsH&b+7(L(*2fXI zrhB{K3hcoX>ZqlgcX7( z{KpgMR=Zk4`dSVSnfn8Ko}+3ww1Gx)8V(%xy_^u}1gV%6Y1`^r2eWr@h6@}v_V``x ztOYJ4H}ogT6suL<9iE6HSitY#vb?q@UHO=cGegfNBmcR(D>W@I@RJ>38{%E!<@Ub{m0sSGXC*uoE&fADKrDeWKsB7AYg(cWs9~$lc4_ zZq)fGn&Rtd+T>~#%8Y==mBH-4iR^+7ia99`TAonjaitM46yhYZR29&T0*DtVyi4H= z6&_MJBOhuGE4)nMJqj;Y_(6qx6|NCNf1SclsQfC0_bPmq!s$-(Hz_K23M9#+iVd@|Wv>kbY_j2^})hY|RwTVFai6=geIkYBkU zz3M`Q5}v?ubm!|n@9WDAKJTMXTKc@n;a=1ychB7<@X8I|*~E;*@UKM1+$K_=k>Zt&;Py_ixH>L8?Y|Vm3mZP+9m6KNteE+3?utdy)f}E@)-K0FT-2l zm&iPjJ;AMF*wDA_6unu0rd2!|{h4;xqj)4aEyuk{6<4;p*t&K9Luk34;7->;U^%FO z$YMj+{g0xZdV(8V#bC*4IV7{#>~;S%v`bI0-4zyD`(+k8f$mQbQmw8!wECQuy)uhk zLihg+k-G;0(Fu_il3DB>y8mHFA;$-RCnAhsH_`o*Q4%r|&@;>ob{XA219He%XUSmq z(fx~LMk;!PDZ!qi`{QL98!Z{^GP?g&tT5<Kje-)I`2U|pz@&P-N?vE9< zX?IOS2gqqrK47=f{U?P~t1Be3ln>a+bbp5Ofq|xx8FD|57_l!$*g3sbbUoew1F&TI z`eO7J_T1)^Df+!XXJV&oAB1M>Eftu4+|7M`y1xmm(N>icI2nHE7@B429pg&+s^=P{(8`*6Ml}3{is;lrnzMd`!0*lv{a# zmDjiVT^~S#_N27Jp3Sk|({nNpc>)_!))S5Qj#jLD{DK1aYnx-dXDKSZr(fbv34vK} ze(fw|Cg?3+rvfH>XXI8MXDPwfDNiE5W$zsmgY8q=k!=2|^v-jeBQedLX9Z;Dvt?kM z{*r#}zJO%e?9}~75kkz9I<5}xoYDo!@P^O&`b-3)RN~86sR8CEmTv zJgclaJfD?saxJnwoe!(4{-t2PcTZLwWVDw3ddnuX{$O2R^U2fid^%_>gx{Xpfnh|O za8x)*YM-z#=0L!BIZ*e4D5r6~TSSekcZ!+389}0ccLnA$OkrZi(ftlQyPV*ySs09U z{|V^h{1MLkl#|SzO}T;H;X2d`tC{3$Gk7nWf{0g7`zsa%9rytjpdnv}=k55_#h9$P zeCWdOASY}mCFV}!9G-!4jNmF)8hnw*MaHNNt~AiXKR{7%0B9@_sZAnuLqZ00NJvgS z?NzaYDU6`pcQ8jLUjsF?pb%@Sg1-TdDS!#^Ay!d^jy#cGg7walQ21+AA+CaH3ZDzx z27dX;;a@X%wV00crmu2k=q+z!{zABWGaO=Yx<7lPlKceRVE+;$*&Updrl_B8TW(55{XY5*k3YR62m@`duW-f%_PehxrcdeyJWb!$u>(_(X512*YP79#d@ua&$D9%NU`Z$j zQVhJwddr6*8fX>K0A^y$8)BaGtGPa;w@d*6^ByPomOi~Dp6FIFsiR%Cyo%8X5g#XV zN1ez2z|K&j3WuurTM>g3#*XyecZ&1OmpBl$hpKt`vv9=JyD>(6%@l zI7k>0|DkgY%nb8?y>XtB{kY7G9pxY(ND2%ylB`O{m&_xnu zw8h*DfYQs1u@L3xExm9RqeVV54n!@_3Bm>uQz78fTUrI7-Nom|?$vU=ARwR=1T=~Z z1i`ODCzSFDAMH-@j#WSP!i9pRYPb3Zzcg2k<4cUbJXYU|+|V=NTPg z=Y+1dky(N630=CM;au~H7~Ov>65$jGh+P6D6?rt6uB1+!PbptpyfLBE({_6bHrcp3 z3%?VV0lbnpujR;fro@F4x++6mFl$0*TlR)y`os_(Jk}TCUrU+2XbeCxHBuP9qC(jE zU+U-z>*FvGG@nFNI0hl3WtABDC8pG1U4HY)ar%9UOdADo?!B={?%)Q9nych2RS>Al zk9>%22KqJ$PhM}?22aDc$w1&+x>#>{6g1&m_wyWdBUSJneRYA)~h)YpMFOX;%2S8J0a33X-pd`}qO!SsDvWyHMQHlEgGSH~C$N}KA>TS^; z@?{x4K%x>e`paNTiEL65=Q8kb`BX|cfkY+V=$C*ZEy6Nc24i}?r9evXbH=EIr(Xh{ z7hAUo%0`ap$Z|`V6>Ck`P>EEaOeTZfJA;kEMqoVQi z&A<>gtC-IdY)#=%!4c1YEwY+-rmUmcy59{f8fY7Vg=m1QJ|qb#PKRPHj_v~uT!y=jD}R=Zg8zc1RL@M z{PEk79ToYEU7$T)1geyH5E8+y@f*MsY>(dv!0Ox$kL9*`9Qha;?ri`|ZsniXqH4`) zF-CCbNJgN|{*hG7=+Hls78rq68Q*k#KqIiH#dyfTki)2l(>8*ag2d-tA{IFgj{PD$ z;>?bybx8&c^N(cojXvA%%7PFQtuBvDc;Up$-=`CWR>W1NYRGLcBdAScOH625D>ZF! z&5#N^p-aP&rpfW<+B#DF;(FiA^*ad=;7{j`F*>m4@sM zV$UtSKr9PorJ>)f2o^r9Nb}B-e5z<8Iyx8f#|6JD;P|@%Rgljna?FFE{wK^sLT%r{ z>aZ|!tE)#C2{%daB<~c3legWpr&YQz8{3Uj_@r33gF>wE1-G8ogNK1AGI`u&Sx9GB zj9Xv$x<_9m_Bv3_9*@5GPuQGBczIaVuNW23(~vGa$XE(d@X~|OM2Pqk4k(kJ@VizZ z5zfV=r>E^f8CwMbiA{n9G6(uXK@9K2WC_0>%Er=bC%i!)v$$krvbY4mKzBz^ zVrC~mc$5G=4ubI*^I_h^gMn^@`QwINKx3DVd+>ZsBY!u2@p_=M6@ ziaa^6%Lpax!{J-s5j~sZ*C+VBhs6?oir;=Cz>NyuiDBOsO!#2u{81YSirsuo!KL%TTkt z0P2MaApB$KqU0-p*tDtRq@eqM`w{zmtBWyVUf`q5(2+BmLwIG=DaN!D$-4hOa5P_` zdBeu^dwh^-JnWvn2jf2l8O#XAo$+dXF98{YCYSJSi$CNTxePN@pj}WRvyr=w)7E2R zqC58!G5v0~PIMzcQ`0YIWi1i_PKlLbqFaa+1t#n!Akk?n3p6DWPl@Z5#5OTu_ezQF z)(QK~ehJK&T4cPEs1QNHjw7NBeqazS<1x@w8GJDlIR*{1YBxNrw{*%fx`0F_p6V|H z)zcy!N@5L4)LTNbjJ4JY`^o+?xVaU%j}p_{UDu$0>Mg5*i3lAJYZD$d_T}=K;pr5M zE|2c{Dsm%u#M=EB{Dui<~kF`F>m8 zOee=lCp%u?FLLdRnVwq;d>!hau>yL-Z@opGwNrnI4=mi3yMKGzO!qGYDIa6w435O%eXxh2O$YL^JQTejc;f58Ib;!D4dyN~F9b98y#$gM z_#o^$+>eX#4b0&_3loXIBJmy&-EDJDsu62%TS^POp|!%@ zkDCG*SsmY;16x$_7|P_kY;L%;izo*P%$|6Uees*3PKlpj5kLzPVF4U+M-B`*UzogA zQ~|>#tJck`J#1K!A9kzg zkZD6OeDFFL9uW-aWkZ|MNuC<3{rAP&~4ceaqD88A58)GR~exGFS#r-|3`s(nZ zPx81Ld?yHG1$TI{GdJd%Y4}KsA)zNYn(y~!fGK+JhxYHPHGIuX8tX z+ttH-U&eY3-l{q@fL_HXk1x=)|3~JjGT^Kxd|3o zaw585ey#~T!TAYs?ISmVYx+_B+5-WZ#)h*4c9hbNwv-GbczY_}V(W6hU?e)I*e`e% zkpSLS8iCi2Jt4jvRZH>bCc!qTd9y_`(?>SBpA+HOzAtE#h%k4HB*Gpo@&}O=G2s@G z6#F2*6iE^HJuH%(ZzA`Jq=-2EBFTU{a+^qs_^n1H#XeQ3NYdO$fk?s>Eiw;D(_~sA zP3DU*(-}-hK0PU3ij4E(oiiTs_&UJI#~5n34Urc(8mUKr&+NmFt|Ke*4yN+{PtnBp zdHnu2^OM}bzMBlJ6q?`b&0mP^4~&6rGu>!+ePe!csiuA2F9iBtd|`lH=1zj?C%j|u z>F^pb@zdec`g-*9e6UvAr6Bkp68uviAeeB{2=p2qpUyHmPQ)28yN!J(y(v(zNGV9@ z>yh6Ln)0;IH**nWwZ=;q8O<|CfD;YyeQzS-0{o|Rt#8bU$rwLNVeD?lBoJb5+|_R{ z^kiATzoWj$a_}nq7NDV{<-d+^pwUGN$Ms_IjW9+m#_;+HeTS=ke1{hwe&?_1{S!MB z2za$2M3J56if8olyyO`78z^Bv%|yqV6haCe4d2&ceTTPKkem4Twv;%18$REg*qO-= zh$5Eu;P)z}K<&}Dh4i$qJlG`A(~fc-%gq9~hMJbX%ss2Lh@SS2{*w;Xqg0 zkLiqg-6-9!Z%a8dh8p%OYE_~PP+u~!}JaI8#J|wZtqS)Pf z+UM9B!kcZ>c6`?vcz+%1Ed$rotyr0$K)ku-#zny^_~Gl#!o-cB<172*8{luWQ5rX9 zEohN<(V>CEj87s<`r9e+_l`VQu?}!=WVhh)!9eOhe&lEU?HzbuT9I}^VV zC}Y2f)!E+q2YqBEjuB?^U}`WL$YJ<+`KF#m2p0aZIVbRxnI zKiMt5F1&Xu@Zf?vzH-?oimJt2y=QhE#K3n;f<9_C`Y+aWjNySe1;PLZNQOWdRs+cr z$aab33#3aT#dy8qy#~vU+4m-6t;nYf(br*=J*CBqh(HUWFH!B#X2MKH)Hy1c;3Jwr}wvGVM{SwGN@cZucKSddif+G>$OfI zvR=abX1(|a?I2SexgCXspZ*Jbl}FRi9^aSWq~`{{F#=z>7cMXY$1wV*mE{FpqIKp4 z%DZv{uZHjcGn-!HNUW{HEh6o8W8Z8C{DjRgM0fmncq!Va5zOhbJl_w{E{wMFgEyGp z$y?_m$|S%TD9sJL82$!&b5DEG-TZ!h<92kD5F!HE1EhYV4P9afV}tOcuh5)39x&GD z2HwZk8oP-R(_;j3wp+e0$6R_Fx}|#$R?Kx`*DiPUi-I*cH3R>v0F&l)fZRPT(@+nn zz{}p2WF*7&&@Zgo6aE#ff}#ATV*`>1Bk(~WK9LMx^D?k2tG73RvaRuMJi%|%ZYI1lLVm|OA$q^4Jei5%1U>@Mt?FE=X zAvuzh>wLjk=(tH}#&imO_zInqahVIH+~g>bWlEak8i5t|pj1pO7<5OK;R8+aIr~Ca zN;pmyjHD=(pIdyQr}aW7C#Qe1Y{~3}l?M=vL675IL}H@UWR}Nw*rfKDRM=AJctc{2 z1ArLe({^Fd?)Q&-5&k2D(RT5sNt%Y17tTBckEI?-8^C1YZ{CFy!shdEk@>PI=&z2Tpn5lm||E;D5&h z{CkQ|E&sz+t>p#yU$MSft>p&+wOROuG;K=uA1_}s^_7?NW&)ix;{wAjQ`sOZ7JFEDoXKU~`SDlMI`QRI&54wJ`F>u2Yy*Y7jQSsEy$nbYsUCYnSxi_J7eD9bM-+69W`xi|geP28K z#j9@m*P%Z(e)n|e^xvLe@X3#-UH??dkJdi1+4GyLe>rzeFyoxZ<~{JU4;R$FfBTHT zwtVnr<m6}f zQ(k}ft5rXAymaBet-Pae{-Rg^^5-l6eo68bqqhBV?8L**JpQ*^Ppprf^zbj{y!BA| zPk;5jCr?{_=0)F}v8<}*+8^|UfA?(NiZ_mzy!Z75M>{^el$$LJ2<;J(`XOBxYjTv z-`75U;yv~`T)is4E=!==6a`%&;^nWr;;sABEOyI%~t5R+4ANu-wu!W-~CC^Dpy;?v0)&!q6>+CBhUh294RLzMW z?aqR2uha4Fq~zw} zQk&!ECap_|8yzzuDHXb)z`zEA;C}(I3vc)4vrfoc6FWO`*qr;~?u~DA;zib>)Yj)7k?X#c`1nM;|Mos`@bo1K)}8s|=Ou8B92 z(wZH)Nm=+ixg(O&JV{P>QYu)olM-@I_avo(CrS`)ZYgwZe6FwW{)?op`>5;Qxa=fn zTYOGZTC2mIl(A-*J84?;aMbM*;aB>8BxLd-qJh{ve9f>{M_c^8arebmk4Ty}Cn>|7 zlm-=0CChfRT3S4Q^e4^cxfHxeud=$^Y7X-hT~=C z|MO&DE%9zu9>06x#rF}shDo6Hs(f?Bm7)R(5o~~maTKpH5=8GxObg#BNetn5ZC3>` zuH?lpYj}M}0xdyAm;H1DFUfeBc83I}Y5ewvms$STeX>3v30ACKMg0!)Lm^yv3np;W z4urr0&r|tdD%`YNO8vjTo9D+3F8MO2q|8xpv4Rx}u2gW1f)6VAn1b6B+^ygN1wT;m zxPrsZ*Ti+Ef)^@ynSyf^T&!S)f-4nVqu_%IKBnL{1$QfWK*0|bJgy-B_X)2v6}(Wv z%M_fW;9>Jk{mx`G+lF+NV>U5b^;}T&$W_nuFobYda+ob z;C*MT%*S_Kg1>jZ#Kl?+$!z>$w6iqlJ(6zrXNr@aF^GOW=q$HRE@3pW4g;-H@jLHA zf|pWMhhz*!gA>Yc${cN#pr56s4btDN=vjm4_bK|cLG%rv3%|LLz@@4!(nIxd2gq@X8i`3t3pSlc2w3Jqc?J>RvV zXV}o)HuP(3=*6HXW(DnMc4gcdd^!qWdIbmmbwP~S* zzX$&)^b4(6;^sQK(?-v0HuR5d=qGLHBhi2_7-)*XE&_e1=QvH!6SZR1KE+-GBxc(1 z&#|E|0ew_#YIOWDO;~Qjf13^6?!3Q;ZTR^u(opq!+J?TH^w^|mJY?GWvJHR4hJMn9 zKFX$D*`3cg%ZC3t8~V*Q^dH*L`2p2X{&~cP{$n)M(H!UVq-Vt59g@Gd;eWw~{<;nQ zeH%JAnnuSWI&_*(M8aX9vt4O-4Wy42b`GQwn_xq~%!WSOhQ8Q_UTH(W&4zv-=p4re zj}IFJ{VdH;^MzTHM{M*wWkc_KO-_!`)fE~JW1EfR-IkS<-lFlO!6>p^9myxoztfhBbM3TBZ+Uf5LtV+OHR+W& z^({R^Tb>J2gSPyd@+L2nxn7;*VR`BIGs+~GL6%9`}j+A1Cyhd8h( z$0(XJ-#ss<$neb9iadqaxaZ~0){5rlU7PLBE4p^hoCP@xix#@G^Ky#Rd2(6ik#Ia7 zP98!xfP}N|iqvboBKcxZosKx*Fh3fDgY|fno;dz)fQo^qDUt`LKK7sDS5#ic10Utf z!GVHG?SOL?DUYK1k4BUy{)s~j&0`&la<9eNdS#V0MU4&RWka97C=ae2P@X!(asaK& zdQRb>gZTzB4n8JQ9P1Z70a2YGI6$PRsH~y3Xa!FE!zqg5?7#up(r>bQ(L){0gCNBz zmom?K#$@yu#=!>}@-)H9Z=X9DEf9zQnP(M7X>1bWctrTydN3m&%b@ch)v=56xWpk9 z^gr+chbTsQaS$P2;zn^%xb1Xe1Rc;VRd0Kl{QPHx72345IwA5k9b3oA# zAs_8>V#pfMhbI4*=gtm1jZ=*kmbN$OTv~O?syfi~zc{8=*lwQkDbCXz;36%(;kIgT z$udB1y@V^wR86h7JbighV|rbEE!sB@1x=5Vmhl+Wiz~~tbezpuUSFpP#uYd)R!c9t ztp-XZ^w!H9%p(mv>Q=BRqzHNS;angcPn`ln(_!A#5LId1)y?I)Rga4@+LIYhAIKeHs#Iz z%NszWh$(OG!D)%@|d2?UWglm+XX}`&5Lhhe%&(y@teNz)MpBL>X zk7++?ytvKFXJX2m`?e+wA&-|?zA10kKY%>SXOjt+xeshYbKjWq-(fzPaGCP|hBSSm z+}t0GIzhx`?vG3C+wa5gMTS-0>6Dx%6yG?Q!hqP>5tj-1Uuv!L;sXhCsD}HC$$~w4 zb4F7#@pAyHyt&VBLUaG$6dTm_2GCLzahzI!swF~<*PM{Sp^;$Hki eiM(eHTq@5j*JK@q#8C2{)so}PK>~wN?LPsWz!z`; diff --git a/game/server.c b/game/server.c index 28bceea..b3c61b9 100644 --- a/game/server.c +++ b/game/server.c @@ -29,7 +29,7 @@ typedef int socklen_t; #define MAX_PLAYERS 16 #define USERNAME_MAX 16 -#define TICK_HZ 30 +#define TICK_HZ 20 #define DT (1.0f / (float)TICK_HZ) #define WEAPON_PISTOL 0 @@ -49,11 +49,15 @@ typedef int socklen_t; #define BTN_USE_MEDKIT (1u << 4) #define BTN_JUMP (1u << 5) +#define ROOM_STATE_WAITING 0 +#define ROOM_STATE_COUNTING_DOWN 1 +#define ROOM_STATE_RUNNING 2 +#define ROOM_STATE_FINISHED 3 + #define CAT_WORLD (1u << 0) #define CAT_PLAYER (1u << 1) #define CAT_ITEM (1u << 2) -// ============== SIMPLEX NOISE ============== static const uint8_t perm[512] = { 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, @@ -167,7 +171,6 @@ static void generate_smooth_terrain(void) { printf("Generated smooth heightmap terrain %dx%d\n", size, size); } -// ============== END SIMPLEX NOISE ============== static double now_seconds(void) { #ifdef _WIN32 @@ -204,7 +207,8 @@ typedef enum MsgType : uint8_t { MSG_INPUT = 3, MSG_SNAPSHOT = 4, MSG_SHOOT = 5, - MSG_ITEMS = 6 + MSG_ITEMS = 6, + MSG_ROOM_STATE = 7 } MsgType; typedef struct MsgHello { @@ -263,6 +267,14 @@ typedef struct MsgItems { uint8_t count; ItemNet items[MAX_ITEMS]; } MsgItems; + +typedef struct MsgRoomState { + uint8_t type; + uint8_t state; + float countdownRemaining; + uint8_t winnerId; + char winnerName[USERNAME_MAX]; +} MsgRoomState; #pragma pack(pop) typedef struct Item { @@ -291,6 +303,13 @@ typedef struct Player { dGeomID geom; } Player; +typedef struct RoomState { + int state; + double countdownEndTime; + int winnerId; + int playerCount; +} RoomState; + static int addr_equal(const struct sockaddr_in *a, const struct sockaddr_in *b) { return (a->sin_family == b->sin_family) && (a->sin_port == b->sin_port) && @@ -319,6 +338,7 @@ static dSpaceID gSpace; static dJointGroupID gContactGroup; static Item gItems[MAX_ITEMS]; static uint16_t gNextItemId = 1; +static RoomState gRoomState; static void item_destroy(Item *it) { if (it->geom) { @@ -397,10 +417,25 @@ static void ode_init_world(void) { dGeomSetCategoryBits(gTerrainGeom, CAT_WORLD); dGeomSetCollideBits(gTerrainGeom, CAT_PLAYER); - item_spawn(ITEM_MEDKIT, 1, 10.0f, 10.0f); - item_spawn(ITEM_MEDKIT, 1, -15.0f, 20.0f); - item_spawn(ITEM_AMMO_RIFLE, 30, 5.0f, -10.0f); - item_spawn(ITEM_AMMO_PISTOL, 12, -10.0f, -15.0f); + // Spawn initial random loot + for (int i = 0; i < 4; i++) { + float x = (float)(rand() % 200 - 100); + float z = (float)(rand() % 200 - 100); + uint8_t type; + int qty; + int type_idx = rand() % 3; + if (type_idx == 0) { + type = ITEM_MEDKIT; + qty = 1; + } else if (type_idx == 1) { + type = ITEM_AMMO_PISTOL; + qty = 10 + (rand() % 6); + } else { + type = ITEM_AMMO_RIFLE; + qty = 20 + (rand() % 11); + } + item_spawn(type, qty, x, z); + } } static void ode_shutdown_world(void) { @@ -422,8 +457,9 @@ static void player_ode_create(Player *p, int spawnIndex) { dBodySetLinearDamping(p->body, 0.05); dBodySetAngularDamping(p->body, 0.99); - float sx = (float)(spawnIndex * 4 - 8); - float sz = (float)(spawnIndex * 3 - 6); + // Random spawn position + float sx = (float)(rand() % 200 - 100); // -100 to 99 + float sz = (float)(rand() % 200 - 100); float sy = get_terrain_height(sx, sz) + 3.0f; dBodySetPosition(p->body, sx, sy, sz); @@ -553,6 +589,12 @@ int main(void) { srand((unsigned)time(NULL)); + // Initialize room state + gRoomState.state = ROOM_STATE_WAITING; + gRoomState.countdownEndTime = 0.0; + gRoomState.winnerId = -1; + gRoomState.playerCount = 0; + ode_init_world(); int sock = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); @@ -612,6 +654,9 @@ int main(void) { continue; if (pid < 0) { + // Only allow joining if room is not running + if (gRoomState.state == ROOM_STATE_RUNNING) + continue; for (int i = 0; i < MAX_PLAYERS; i++) if (!players[i].inUse) { pid = i; @@ -631,6 +676,7 @@ int main(void) { p->medkits = 2; p->rng = 0xA341316Cu ^ (uint32_t)(i * 2654435761u); player_ode_create(p, i); + gRoomState.playerCount++; printf("Player %d joined as '%s'\n", pid, p->username); break; } @@ -715,7 +761,7 @@ int main(void) { } else if (type == MSG_SHOOT && n >= (int)sizeof(MsgShoot)) { const MsgShoot *m = (const MsgShoot *)buf; if (pid >= 0 && m->playerId == (uint8_t)pid && players[pid].inUse && - players[pid].alive) { + players[pid].alive && gRoomState.state == ROOM_STATE_RUNNING) { Player *sh = &players[pid]; const double now = now_seconds(); double fireInterval = @@ -783,6 +829,37 @@ int main(void) { if (players[victim].hp <= 0) { players[victim].hp = 0; players[victim].alive = 0; + // Drop loot + const dReal *pos = dBodyGetPosition(players[victim].body); + float x = (float)pos[0], z = (float)pos[2]; + if (players[victim].pistolAmmo > 0) { + int qty = players[victim].pistolAmmo; + if (qty > 12) + qty = 12; // Max per drop + item_spawn(ITEM_AMMO_PISTOL, qty, + x + frand_signed(&players[victim].rng) * 2.0f, + z + frand_signed(&players[victim].rng) * 2.0f); + players[victim].pistolAmmo -= qty; + } + if (players[victim].rifleAmmo > 0) { + int qty = players[victim].rifleAmmo; + if (qty > 30) + qty = 30; + item_spawn(ITEM_AMMO_RIFLE, qty, + x + frand_signed(&players[victim].rng) * 2.0f, + z + frand_signed(&players[victim].rng) * 2.0f); + players[victim].rifleAmmo -= qty; + } + if (players[victim].medkits > 0) { + int qty = players[victim].medkits; + if (qty > 2) + qty = 2; + item_spawn(ITEM_MEDKIT, qty, + x + frand_signed(&players[victim].rng) * 2.0f, + z + frand_signed(&players[victim].rng) * 2.0f); + players[victim].medkits -= qty; + } + printf("Player %d died and dropped loot\n", victim); } } } @@ -790,6 +867,66 @@ int main(void) { } } + // Room state management + { + double now = now_seconds(); + if (gRoomState.state == ROOM_STATE_WAITING) { + // Count active players + int activePlayers = 0; + for (int i = 0; i < MAX_PLAYERS; i++) { + if (players[i].inUse) + activePlayers++; + } + gRoomState.playerCount = activePlayers; + if (activePlayers >= 2) { + gRoomState.state = ROOM_STATE_COUNTING_DOWN; + gRoomState.countdownEndTime = now + 10.0; // 10 seconds + printf("Starting countdown for game start\n"); + } + } else if (gRoomState.state == ROOM_STATE_COUNTING_DOWN) { + if (now >= gRoomState.countdownEndTime) { + gRoomState.state = ROOM_STATE_RUNNING; + // Respawn and heal all players + for (int i = 0; i < MAX_PLAYERS; i++) { + if (players[i].inUse) { + players[i].alive = 1; + players[i].hp = 100; + player_ode_create(&players[i], i); // Recreate body + } + } + printf("Game started!\n"); + } + } else if (gRoomState.state == ROOM_STATE_RUNNING) { + // Check win condition + int aliveCount = 0; + int lastAlive = -1; + for (int i = 0; i < MAX_PLAYERS; i++) { + if (players[i].inUse && players[i].alive) { + aliveCount++; + lastAlive = i; + } + } + if (aliveCount <= 1) { + gRoomState.state = ROOM_STATE_FINISHED; + gRoomState.winnerId = lastAlive; + printf("Game finished! Winner: %s\n", + lastAlive >= 0 ? players[lastAlive].username : "None"); + } + } else if (gRoomState.state == ROOM_STATE_FINISHED) { + // Wait a bit, then reset + static double finishTime = 0.0; + if (finishTime == 0.0) + finishTime = now; + if (now - finishTime > 5.0) { // 5 seconds after finish + gRoomState.state = ROOM_STATE_WAITING; + gRoomState.winnerId = -1; + finishTime = 0.0; + // Remove dead players or something? For now, keep them + printf("Room resetting to waiting\n"); + } + } + } + double t = now_seconds(); if (t >= nextTick) { nextTick += DT; @@ -923,6 +1060,27 @@ int main(void) { } broadcast(sock, players, &im, (int)sizeof(im)); } + + // Send room state every few ticks + static uint32_t roomStateTickDiv = 0; + roomStateTickDiv++; + if (roomStateTickDiv >= 30) { // Every 30 ticks, about 0.5s + roomStateTickDiv = 0; + MsgRoomState rs = {0}; + rs.type = MSG_ROOM_STATE; + rs.state = (uint8_t)gRoomState.state; + rs.countdownRemaining = + (gRoomState.state == ROOM_STATE_COUNTING_DOWN) + ? (float)(gRoomState.countdownEndTime - now_seconds()) + : 0.0f; + rs.winnerId = + (gRoomState.winnerId >= 0) ? (uint8_t)gRoomState.winnerId : 255; + if (gRoomState.winnerId >= 0) { + strncpy(rs.winnerName, players[gRoomState.winnerId].username, + USERNAME_MAX - 1); + } + broadcast(sock, players, &rs, (int)sizeof(rs)); + } } double now = now_seconds(); From 57d8c7a2b7708838ba59c96f51ee5806868ef7a6 Mon Sep 17 00:00:00 2001 From: Masashi Date: Thu, 18 Dec 2025 22:30:33 +0530 Subject: [PATCH 8/8] gam --- game/libfishsoup | 1 + 1 file changed, 1 insertion(+) create mode 120000 game/libfishsoup diff --git a/game/libfishsoup b/game/libfishsoup new file mode 120000 index 0000000..9b31e29 --- /dev/null +++ b/game/libfishsoup @@ -0,0 +1 @@ +../libfishsoup \ No newline at end of file