1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
#include <memory>
#include <filesystem>
#include <pugixml.hpp>
#include <map>
#include "backend/Location.h"
#include "backend/LocationFactory.h"
#include "backend/Dungeon.h"
#include "load_dungeon.h"
#include "Exception.h"
#include "frontend/strings.h"
using namespace std;
using namespace pugi;
unique_ptr<Dungeon> load_dungeon(const string & filename) {
unique_ptr<Dungeon> dungeon = make_unique<Dungeon>();
xml_document doc;
string canonical = filename;
if (canonical.starts_with("~/"))
canonical = getenv("HOME") + canonical.substr(1);
try {
canonical = filesystem::canonical(canonical);
} catch (...) {
throw Exception("Kon bestand niet vinden");
}
xml_parse_result result = doc.load_file(canonical.c_str());
if (!result)
throw Exception("Kon XML-bestand niet lezen");
xml_node locations = doc.child("locaties");
if (!locations)
throw Exception("XML-bestand mist een <locaties> tag");
LocationFactory factory;
struct TempData {
Location * location;
unsigned edges[4];
};
map<unsigned, TempData> temp_map;
for (xml_node & tag : locations) {
const char * name = tag.text().as_string();
const char * description = tag.child("beschrijving").text().as_string();
// vector<string> objects_hidden = split_string(tag.attribute("objectenverborgen").as_string(), ";");
// vector<string> objects_visible = split_string(tag.attribute("objectenzichtbaar").as_string(), ";");
// vector<string> enemies = split_string(tag.attribute("vijand").as_string(), ";");
Location * location = factory.create_location(name, description);
temp_map[tag.attribute("id").as_uint()] = {
.location = location,
.edges = {
tag.attribute("noord").as_uint(0),
tag.attribute("oost").as_uint(0),
tag.attribute("zuid").as_uint(0),
tag.attribute("west").as_uint(0),
},
};
dungeon->add_location(location);
}
// connect edges after creating all locations
for (auto & [here, temp] : temp_map) {
for (Direction direction : DIRECTIONS) {
unsigned there = temp.edges[direction];
if (temp.edges[direction] == 0) continue;
if (!temp_map.contains(there)) continue;
temp.location->set_exit(direction, temp_map[there].location);
}
}
return dungeon;
}
|