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