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_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) {
int size = TERRAIN_SIZE;
@ -1005,6 +1007,10 @@ int main(void) {
(Color){80, 140, 70, 255};
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)
for (int i = 0; i < MAX_ITEMS; i++) {
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_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 dGeomID gTerrainGeom = NULL;
@ -298,6 +300,7 @@ typedef struct Player {
uint32_t rng;
float reloadTimer;
int reloadWeapon;
float borderDamageTimer;
dBodyID body;
dGeomID geom;
} Player;
@ -466,6 +469,8 @@ static void player_ode_create(Player *p, int spawnIndex) {
dGeomSetBody(p->geom, p->body);
dGeomSetCategoryBits(p->geom, CAT_PLAYER);
dGeomSetCollideBits(p->geom, CAT_WORLD | CAT_PLAYER);
p->borderDamageTimer = 0.0f;
}
static void player_ode_destroy(Player *p) {
@ -988,27 +993,71 @@ int main(void) {
}
}
for (int i = 0; i < MAX_PLAYERS; i++) {
Player *p = &players[i];
if (!p->inUse || !p->alive)
continue;
for (int i = 0; i < MAX_PLAYERS; i++) {
Player *p = &players[i];
if (!p->inUse || !p->alive)
continue;
const dReal *lvel = dBodyGetLinearVel(p->body);
const dReal *avel = dBodyGetAngularVel(p->body);
const dReal *lvel = dBodyGetLinearVel(p->body);
const dReal *avel = dBodyGetAngularVel(p->body);
float dx = p->moveX, dz = p->moveZ;
float len = sqrtf(dx * dx + dz * dz);
if (len > 1e-6f) {
dx /= len;
dz /= len;
}
float dx = p->moveX, dz = p->moveZ;
float len = sqrtf(dx * dx + dz * dz);
if (len > 1e-6f) {
dx /= len;
dz /= len;
}
float speed = 10.0f;
float fx = sinf(p->yaw) * dz - cosf(p->yaw) * dx;
float fz = cosf(p->yaw) * dz + sinf(p->yaw) * dx;
dBodySetLinearVel(p->body, fx * speed, lvel[1], fz * speed);
dBodySetAngularVel(p->body, avel[0], 0, avel[2]);
}
float speed = 10.0f;
float fx = sinf(p->yaw) * dz - cosf(p->yaw) * dx;
float fz = cosf(p->yaw) * dz + sinf(p->yaw) * dx;
dBodySetLinearVel(p->body, fx * speed, lvel[1], fz * speed);
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};
snap.type = MSG_SNAPSHOT;