world border

This commit is contained in:
Masashi 2025-12-19 11:20:00 +05:30
commit 2d98574830
4 changed files with 76 additions and 21 deletions

Binary file not shown.

View file

@ -179,6 +179,8 @@ float get_terrain_height(float x, float z) {
#define TERRAIN_SIZE 256 #define TERRAIN_SIZE 256
#define TERRAIN_SCALE 1.0f #define TERRAIN_SCALE 1.0f
#define TERRAIN_MIN (-TERRAIN_SIZE * TERRAIN_SCALE / 2.0f)
#define TERRAIN_MAX (TERRAIN_SIZE * TERRAIN_SCALE / 2.0f)
static Mesh generate_terrain_mesh(void) { static Mesh generate_terrain_mesh(void) {
int size = TERRAIN_SIZE; int size = TERRAIN_SIZE;
@ -1005,6 +1007,10 @@ int main(void) {
(Color){80, 140, 70, 255}; (Color){80, 140, 70, 255};
DrawModel(terrainModel, (Vector3){0, 0, 0}, 1.0f, WHITE); DrawModel(terrainModel, (Vector3){0, 0, 0}, 1.0f, WHITE);
// Draw border
float borderSize = TERRAIN_MAX - TERRAIN_MIN;
DrawCube((Vector3){0, 0, 0}, borderSize, 1000, borderSize, (Color){255, 0, 0, 100});
// Items with basic lighting (no shader for now to keep it simple) // Items with basic lighting (no shader for now to keep it simple)
for (int i = 0; i < MAX_ITEMS; i++) { for (int i = 0; i < MAX_ITEMS; i++) {
if (!wi[i].present) if (!wi[i].present)

Binary file not shown.

View file

@ -153,6 +153,8 @@ float get_terrain_height(float x, float z) {
#define TERRAIN_SIZE 256 #define TERRAIN_SIZE 256
#define TERRAIN_SCALE 1.0f #define TERRAIN_SCALE 1.0f
#define TERRAIN_MIN (-TERRAIN_SIZE * TERRAIN_SCALE / 2.0f)
#define TERRAIN_MAX (TERRAIN_SIZE * TERRAIN_SCALE / 2.0f)
static dReal *gHeightData = NULL; static dReal *gHeightData = NULL;
static dGeomID gTerrainGeom = NULL; static dGeomID gTerrainGeom = NULL;
@ -298,6 +300,7 @@ typedef struct Player {
uint32_t rng; uint32_t rng;
float reloadTimer; float reloadTimer;
int reloadWeapon; int reloadWeapon;
float borderDamageTimer;
dBodyID body; dBodyID body;
dGeomID geom; dGeomID geom;
} Player; } Player;
@ -466,6 +469,8 @@ static void player_ode_create(Player *p, int spawnIndex) {
dGeomSetBody(p->geom, p->body); dGeomSetBody(p->geom, p->body);
dGeomSetCategoryBits(p->geom, CAT_PLAYER); dGeomSetCategoryBits(p->geom, CAT_PLAYER);
dGeomSetCollideBits(p->geom, CAT_WORLD | CAT_PLAYER); dGeomSetCollideBits(p->geom, CAT_WORLD | CAT_PLAYER);
p->borderDamageTimer = 0.0f;
} }
static void player_ode_destroy(Player *p) { static void player_ode_destroy(Player *p) {
@ -988,27 +993,71 @@ int main(void) {
} }
} }
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)
continue; continue;
const dReal *lvel = dBodyGetLinearVel(p->body); const dReal *lvel = dBodyGetLinearVel(p->body);
const dReal *avel = dBodyGetAngularVel(p->body); const dReal *avel = dBodyGetAngularVel(p->body);
float dx = p->moveX, dz = p->moveZ; float dx = p->moveX, dz = p->moveZ;
float len = sqrtf(dx * dx + dz * dz); float len = sqrtf(dx * dx + dz * dz);
if (len > 1e-6f) { if (len > 1e-6f) {
dx /= len; dx /= len;
dz /= len; dz /= len;
} }
float speed = 10.0f; float speed = 10.0f;
float fx = sinf(p->yaw) * dz - cosf(p->yaw) * dx; float fx = sinf(p->yaw) * dz - cosf(p->yaw) * dx;
float fz = cosf(p->yaw) * dz + sinf(p->yaw) * dx; float fz = cosf(p->yaw) * dz + sinf(p->yaw) * dx;
dBodySetLinearVel(p->body, fx * speed, lvel[1], fz * speed); dBodySetLinearVel(p->body, fx * speed, lvel[1], fz * speed);
dBodySetAngularVel(p->body, avel[0], 0, avel[2]); dBodySetAngularVel(p->body, avel[0], 0, avel[2]);
} }
// Border damage
for (int i = 0; i < MAX_PLAYERS; i++) {
Player *p = &players[i];
if (!p->inUse || !p->alive)
continue;
const dReal *pos = dBodyGetPosition(p->body);
float px = (float)pos[0], pz = (float)pos[2];
if (px < TERRAIN_MIN || px > TERRAIN_MAX || pz < TERRAIN_MIN || pz > TERRAIN_MAX) {
p->borderDamageTimer += DT;
if (p->borderDamageTimer >= 0.5f) {
p->borderDamageTimer -= 0.5f;
p->hp -= 1;
if (p->hp <= 0) {
p->hp = 0;
p->alive = 0;
// Drop loot as in shooting death
const dReal *pos2 = dBodyGetPosition(p->body);
float x = (float)pos2[0], z = (float)pos2[2];
if (p->pistolAmmo > 0) {
int qty = p->pistolAmmo;
if (qty > 12) qty = 12;
item_spawn(ITEM_AMMO_PISTOL, qty, x + frand_signed(&p->rng) * 2.0f, z + frand_signed(&p->rng) * 2.0f);
p->pistolAmmo -= qty;
}
if (p->rifleAmmo > 0) {
int qty = p->rifleAmmo;
if (qty > 30) qty = 30;
item_spawn(ITEM_AMMO_RIFLE, qty, x + frand_signed(&p->rng) * 2.0f, z + frand_signed(&p->rng) * 2.0f);
p->rifleAmmo -= qty;
}
if (p->medkits > 0) {
int qty = p->medkits;
if (qty > 2) qty = 2;
item_spawn(ITEM_MEDKIT, qty, x + frand_signed(&p->rng) * 2.0f, z + frand_signed(&p->rng) * 2.0f);
p->medkits -= qty;
}
printf("Player %d died from border damage and dropped loot\n", i);
}
}
} else {
p->borderDamageTimer = 0.0f;
}
}
MsgSnapshot snap = {0}; MsgSnapshot snap = {0};
snap.type = MSG_SNAPSHOT; snap.type = MSG_SNAPSHOT;