summaryrefslogtreecommitdiff
path: root/src/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/server.c')
-rw-r--r--src/server.c71
1 files changed, 25 insertions, 46 deletions
diff --git a/src/server.c b/src/server.c
index adbbe80..45d8384 100644
--- a/src/server.c
+++ b/src/server.c
@@ -20,6 +20,7 @@
#include "str.h"
#include "ser.h"
#include "sig.h"
+#include "chunk.h"
typedef enum {
MAP_VALLEY,
@@ -33,19 +34,15 @@ typedef struct {
const char *filename;
str name;
map_type type;
- uint32_t width;
- uint32_t height;
- int32_t off_x;
- int32_t off_y;
int8_t z; // caves: -1
- node *nodes;
+ chunk chunk;
} map;
typedef struct {
bool auth;
str name;
uint64_t id;
- int32_t x, y;
+ vec2 pos;
int8_t z;
peer conn;
} player;
@@ -59,20 +56,13 @@ typedef struct {
uint64_t entity_id;
} game;
-node *map_local_node(map *m, int32_t x, int32_t y)
-{
- if (x < 0 || y < 0 || (uint32_t) x >= m->width || (uint32_t) y >= m->height)
- return NULL;
- return &m->nodes[x*m->height+y];
-}
-
-node *map_node(game *g, int32_t x, int32_t y, int8_t z)
+node *map_node(game *g, vec2 p, int8_t z)
{
for (size_t i = 0; i < g->maps.len; i++) {
map *m = &g->maps.data[i];
if (m->z != z)
continue;
- node *n = map_local_node(m, x - m->off_x, y - m->off_y);
+ node *n = chunk_index_abs(m->chunk, p);
if (n == NULL || !n->present)
continue;
return n;
@@ -80,17 +70,19 @@ node *map_node(game *g, int32_t x, int32_t y, int8_t z)
return NULL;
}
-void map_load_node(map *m, uint32_t x, uint32_t y, uint32_t color)
+void map_load_node(map *m, uvec2 v, color col)
{
- node *n = map_local_node(m, x, y);
- n->present = color != 0xffffff;
+ uint32_t ucol = color_to_u32(col);
+
+ node *n = chunk_index(m->chunk, v);
+ n->present = ucol != 0xffffff;
if (!n->present)
return;
n->z = 0;
- n->col = u32_color(color);
- switch (color) {
+ n->col = col;
+ switch (ucol) {
case 0x00880d: n->type = N_GRASS; break; // TODO: color
case 0x595959: n->type = N_ROCK; n->z = 1; break;
case 0x484848: n->type = N_ROCK; n->z = 2; break;
@@ -104,7 +96,7 @@ void map_load_node(map *m, uint32_t x, uint32_t y, uint32_t color)
case 0x016300: n->type = N_BIG_TREE; break;
default:
fprintf(stderr, "invalid color in map %.*s at %"PRIu32" %"PRIu32": %06x\n",
- PSTR(m->name), x, y, color);
+ PSTR(m->name), v.x, v.y, ucol);
n->present = false;
break;
}
@@ -136,12 +128,10 @@ bool map_load(map *m)
png_uint_32 height = png_get_image_height(png, info);
png_byte color_type = png_get_color_type(png, info);
- TRY(width == m->width, "%s: width mismatch\n", m->filename)
- TRY(height == m->height, "%s: height mismatch\n", m->filename)
+ TRY(width == m->chunk.bounds.size.x, "%s: width mismatch\n", m->filename)
+ TRY(height == m->chunk.bounds.size.y, "%s: height mismatch\n", m->filename)
TRY(color_type == PNG_COLOR_TYPE_RGB, "%s: color type is not RGB\n", m->filename)
- m->nodes = malloc(m->width * m->height * sizeof *m->nodes);
-
// uint32_t colors[100] = {0};
png_uint_32 pitch = png_get_rowbytes(png, info);
@@ -152,8 +142,6 @@ bool map_load(map *m)
for (png_uint_32 x = 0; x < width; x++) {
png_bytep p = &row[x*3];
- uint32_t col = color_u32((color) { p[0], p[1], p[2] });
-
/*
for (size_t i = 0; i < 100; i++) {
if (colors[i] == color) {
@@ -165,7 +153,7 @@ bool map_load(map *m)
}
}*/
- map_load_node(m, x, y, col);
+ map_load_node(m, UVEC2(x, y), (color) { p[0], p[1], p[2] });
}
}
@@ -209,17 +197,13 @@ void send_players(game *g)
}
// send_nudes when
-void send_nodes(player *p, game *g, int8_t z, int32_t x, int32_t y, uint32_t w, uint32_t h)
+void send_nodes(player *p, game *g, box2 bounds, int8_t z)
{
SEND_PKT(p->conn, CPKT_NODES,
- ser_i8(&pkt, z);
- ser_i32(&pkt, x);
- ser_i32(&pkt, y);
- ser_u32(&pkt, w);
- ser_u32(&pkt, h);
- for (uint32_t xi = 0; xi < w; xi++)
- for (uint32_t yi = 0; yi < w; yi++)
- ser_node(&pkt, map_node(g, x+xi, y+yi, z));
+ ser_box2(&pkt, bounds);
+ for (uint32_t x = 0; x < bounds.size.x; x++)
+ for (uint32_t y = 0; y < bounds.size.y; y++)
+ ser_node(&pkt, map_node(g, vec2_add(bounds.pos, VEC2(x, y)), z));
)
}
@@ -246,7 +230,7 @@ void game_exit(game *g, int ret)
for (size_t i = 0; i < g->maps.len; i++) {
free(g->maps.data[i].name.data);
- free(g->maps.data[i].nodes);
+ free(g->maps.data[i].chunk.data);
}
free(g->maps.data);
@@ -281,14 +265,13 @@ bool handle_hi(str pkt, player *p, game *g)
p->auth = true;
p->name = str_clone(name);
- p->x = p->y = 0;
+ p->pos.x = p->pos.y = 0;
p->z = 0;
SEND_PKT(p->conn, CPKT_HI, ser_str(&pkt, g->motd);)
send_players(g);
- uint32_t range = 10;
- send_nodes(p, g, p->z, p->x-range, p->y-range, range*2, range*2);
+ send_nodes(p, g, box2_around(p->pos, SIGHT_RANGE), p->z);
return true;
}
@@ -325,12 +308,8 @@ int main()
.filename = "assets/map_valley.png",
.name = str_clone(S("Valley")),
.type = MAP_VALLEY,
- .off_x = -50,
- .off_y = -50,
.z = 0,
- .width = 100,
- .height = 100,
- .nodes = NULL,
+ .chunk = chunk_alloc((box2) { { -50, -50 }, { 100, 100 } }),
};
if (!map_load(&g.maps.data[0]))