]> git.lizzy.rs Git - dragonblocks_alpha.git/blob - src/server/schematic.c
af92cfa9d4b161b82590c0bac42e299e86b349ff
[dragonblocks_alpha.git] / src / server / schematic.c
1 #include <getline/getline.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include "server/schematic.h"
5 #include "server/server_node.h"
6 #include "terrain.h"
7
8 void schematic_load(List *schematic, const char *path, SchematicMapping *mappings, size_t num_mappings)
9 {
10         list_ini(schematic);
11
12         FILE *file = fopen(path, "r");
13         if (!file) {
14                 fprintf(stderr, "[warning] failed to open schematic %s\n", path);
15                 return;
16         }
17
18         char *line = NULL;
19         size_t siz = 0;
20         ssize_t length;
21         int count = 0;
22
23         // getline is POSIX 2008, so we can use it
24         while ((length = getline(&line, &siz, file)) > 0) {
25                 count++;
26
27                 if (*line == '#')
28                         continue;
29
30                 SchematicNode *node = malloc(sizeof *node);
31
32                 v3s32 color;
33                 if (sscanf(line, "%d %d %d %2x%2x%2x",
34                                 &node->pos.x, &node->pos.z, &node->pos.y,
35                                 &color.x, &color.y, &color.z) != 6) {
36                         fprintf(stderr, "[warning] syntax error in schematic %s in line %d: %s\n",
37                                 path, count, line);
38                         free(node);
39                         continue;
40                 }
41
42                 SchematicMapping *mapping = NULL;
43                 for (size_t i = 0; i < num_mappings; i++)
44                         if (v3s32_equals(color, mappings[i].color)) {
45                                 mapping = &mappings[i];
46                                 break;
47                         }
48
49                 if (!mapping) {
50                         fprintf(stderr, "[warning] color not mapped to node in schematic %s in line %d: %02x%02x%02x\n",
51                                 path, count, color.x, color.y, color.z);
52                         free(node);
53                         continue;
54                 }
55
56                 node->node = mapping->use_color
57                         ? server_node_create_color(mapping->type, (v3f32) {
58                                 (f32) color.x / 0xFF,
59                                 (f32) color.y / 0xFF,
60                                 (f32) color.z / 0xFF,
61                         }) : server_node_create(mapping->type);
62
63                 list_apd(schematic, node);
64         }
65
66         if (line)
67                 free(line);
68
69         fclose(file);
70 }
71
72 void schematic_place(List *schematic, v3s32 pos, TerrainGenStage tgs, List *changed_chunks)
73 {
74         LIST_ITERATE(schematic, list_node) {
75                 SchematicNode *node = list_node->dat;
76
77                 server_terrain_gen_node(
78                         v3s32_add(pos, node->pos),
79                         server_node_copy(node->node),
80                         tgs, changed_chunks);
81         }
82 }
83
84 static void delete_schematic_node(SchematicNode *node)
85 {
86         server_node_delete(&node->node);
87         free(node);
88 }
89
90 void schematic_delete(List *schematic)
91 {
92         list_clr(schematic, &delete_schematic_node, NULL, NULL);
93 }