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