]> git.lizzy.rs Git - dragonblocks_alpha.git/blob - src/mapgen.c
Proper mapgen
[dragonblocks_alpha.git] / src / mapgen.c
1 #include <stdlib.h>
2 #include <perlin/perlin.h>
3 #include "mapgen.h"
4
5 int seed = 0;
6 static Server *server = NULL;
7
8 // mapgen prototype
9 static void generate_block(MapBlock *block)
10 {
11         for (u8 x = 0; x < 16; x++) {
12                 u32 ux = x + block->pos.x * 16 + ((u32) 1 << 31);
13                 for (u8 z = 0; z < 16; z++) {
14                         u32 uz = z + block->pos.z * 16 + ((u32) 1 << 31);
15                         s32 height = smooth2d((double) ux / 32.0f, (double) uz / 32.0f, 0, seed) * 16.0f;
16                         for (u8 y = 0; y < 16; y++) {
17                                 s32 ay = y + block->pos.y * 16;
18                                 Node type;
19                                 if (ay > height)
20                                         type = NODE_AIR;
21                                 else if (ay == height)
22                                         type = NODE_GRASS;
23                                 else if (ay >= height - 4)
24                                         type = NODE_DIRT;
25                                 else
26                                         type = NODE_STONE;
27                                 block->data[x][y][z] = map_node_create(type);
28                         }
29                 }
30         }
31         ITERATE_LIST(&server->clients, pair) {
32                 Client *client = pair->value;
33                 if (client->state == CS_ACTIVE) {
34                         pthread_mutex_lock(&client->mtx);
35                         (void) (write_u32(client->fd, CC_BLOCK) && map_serialize_block(client->fd, block));
36                         pthread_mutex_unlock(&client->mtx);
37                 }
38         }
39         block->ready = true;
40 }
41
42 void mapgen_init(Server *srv)
43 {
44         server = srv;
45         server->map->on_block_create = &generate_block;
46 }
47
48 #define RANGE 3
49
50 static void *mapgen_thread(void *cliptr)
51 {
52         Client *client = cliptr;
53
54         while (client->state != CS_DISCONNECTED) {
55                 v3s32 pos = map_node_to_block_pos((v3s32) {client->pos.x, client->pos.y, client->pos.z}, NULL);
56                 for (s32 x = pos.x - RANGE; x <= pos.x + RANGE; x++)
57                         for (s32 y = pos.y - RANGE; y <= pos.y + RANGE; y++)
58                                 for (s32 z = pos.z - RANGE; z <= pos.z + RANGE; z++)
59                                         map_get_block(client->server->map, (v3s32) {x, y, z}, true);
60         }
61
62         return NULL;
63 }
64
65 void mapgen_start_thread(Client *client)
66 {
67         (void) client;
68         (void) mapgen_thread;
69         pthread_t thread;
70         pthread_create(&thread, NULL, &mapgen_thread, client);
71 }