diff options
Diffstat (limited to 'src/map.cpp')
-rw-r--r-- | src/map.cpp | 158 |
1 files changed, 124 insertions, 34 deletions
diff --git a/src/map.cpp b/src/map.cpp index 3976b63..8c1c6f0 100644 --- a/src/map.cpp +++ b/src/map.cpp | |||
@@ -2,43 +2,111 @@ | |||
2 | #include "game.h" | 2 | #include "game.h" |
3 | #include <cstdlib> | 3 | #include <cstdlib> |
4 | #include <cstring> | 4 | #include <cstring> |
5 | #include <libxml/parser.h> | ||
6 | #include <map> | ||
7 | #include "entityfactory.h" | ||
8 | |||
9 | static std::map<std::string, Map> maps; | ||
5 | 10 | ||
6 | Map::Map() | 11 | Map::Map() |
7 | { | 12 | { |
8 | 13 | title = (char*) calloc(1, sizeof(char)); | |
14 | mapdata = (int*) calloc(1, sizeof(int)); | ||
9 | } | 15 | } |
10 | 16 | ||
11 | Map::Map(const char* filename) | 17 | Map::Map(const std::string name) |
12 | { | 18 | { |
13 | FILE* f = fopen(filename, "r"); | 19 | xmlDocPtr doc = xmlParseFile(("../maps/" + name + ".xml").c_str()); |
20 | if (doc == nullptr) | ||
21 | { | ||
22 | fprintf(stderr, "Error reading map %s\n", name.c_str()); | ||
23 | exit(-1); | ||
24 | } | ||
14 | 25 | ||
15 | m_mapdata = (int*) malloc(MAP_WIDTH*(MAP_HEIGHT-1)*sizeof(int)); | 26 | xmlNodePtr top = xmlDocGetRootElement(doc); |
16 | for (int i=0; i<MAP_HEIGHT-1; i++) | 27 | if (top == nullptr) |
17 | { | 28 | { |
18 | for (int j=0; j<MAP_WIDTH; j++) | 29 | fprintf(stderr, "Empty map %s\n", name.c_str()); |
30 | exit(-1); | ||
31 | } | ||
32 | |||
33 | if (xmlStrcmp(top->name, (const xmlChar*) "map-def")) | ||
34 | { | ||
35 | fprintf(stderr, "Invalid map definition %s\n", name.c_str()); | ||
36 | exit(-1); | ||
37 | } | ||
38 | |||
39 | for (xmlNodePtr node = top->xmlChildrenNode; node != NULL; node = node->next) | ||
40 | { | ||
41 | if (!xmlStrcmp(node->name, (const xmlChar*) "name")) | ||
42 | { | ||
43 | xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); | ||
44 | title = (char*) calloc(xmlStrlen(key) + 1, sizeof(char)); | ||
45 | strcpy(title, (char*) key); | ||
46 | xmlFree(key); | ||
47 | } else if (!xmlStrcmp(node->name, (const xmlChar*) "environment")) | ||
48 | { | ||
49 | xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); | ||
50 | mapdata = (int*) malloc(MAP_WIDTH*(MAP_HEIGHT-1)*sizeof(int)); | ||
51 | mapdata[0] = atoi(strtok((char*) key, ",\n")); | ||
52 | for (int i=1; i<(MAP_WIDTH*(MAP_HEIGHT-1)); i++) | ||
53 | { | ||
54 | mapdata[i] = atoi(strtok(NULL, ",\n")); | ||
55 | } | ||
56 | xmlFree(key); | ||
57 | } else if (!xmlStrcmp(node->name, (const xmlChar*) "entities")) | ||
19 | { | 58 | { |
20 | fscanf(f, "%d,", &(m_mapdata[i*MAP_WIDTH + j])); | 59 | for (xmlNodePtr entityNode = node->xmlChildrenNode; entityNode != NULL; entityNode = entityNode->next) |
60 | { | ||
61 | if (!xmlStrcmp(entityNode->name, (const xmlChar*) "entity")) | ||
62 | { | ||
63 | EntityData data; | ||
64 | for (xmlNodePtr entityDataNode = entityNode->xmlChildrenNode; entityDataNode != NULL; entityDataNode = entityDataNode->next) | ||
65 | { | ||
66 | if (!xmlStrcmp(entityDataNode->name, (const xmlChar*) "entity-type")) | ||
67 | { | ||
68 | xmlChar* key = xmlNodeListGetString(doc, entityDataNode->xmlChildrenNode, 1); | ||
69 | data.name = std::string((char*) key); | ||
70 | xmlFree(key); | ||
71 | } else if (!xmlStrcmp(entityDataNode->name, (const xmlChar*) "entity-position")) | ||
72 | { | ||
73 | xmlChar* key = xmlNodeListGetString(doc, entityDataNode->xmlChildrenNode, 1); | ||
74 | sscanf((char*) key, "%lf,%lf", &(data.position.first), &(data.position.second)); | ||
75 | xmlFree(key); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | entities.push_back(data); | ||
80 | } | ||
81 | } | ||
82 | } else if (!xmlStrcmp(node->name, (const xmlChar*) "leftmap")) | ||
83 | { | ||
84 | xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); | ||
85 | leftMap = &Map::getNamedMap(std::string((char*) key)); | ||
86 | xmlFree(key); | ||
87 | } else if (!xmlStrcmp(node->name, (const xmlChar*) "rightmap")) | ||
88 | { | ||
89 | xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); | ||
90 | rightMap = &Map::getNamedMap(std::string((char*) key)); | ||
91 | xmlFree(key); | ||
21 | } | 92 | } |
22 | |||
23 | fgetc(f); | ||
24 | } | 93 | } |
25 | 94 | ||
26 | m_title = (char*) calloc(41, sizeof(char)); | 95 | xmlFreeDoc(doc); |
27 | fgets(m_title, 41, f); | ||
28 | |||
29 | fclose(f); | ||
30 | } | 96 | } |
31 | 97 | ||
32 | Map::Map(Map& map) | 98 | Map::Map(const Map& map) |
33 | { | 99 | { |
34 | m_mapdata = (int*) malloc(MAP_WIDTH*(MAP_HEIGHT-1)*sizeof(int)); | 100 | mapdata = (int*) malloc(MAP_WIDTH*(MAP_HEIGHT-1)*sizeof(int)); |
35 | memcpy(m_mapdata, map.m_mapdata, MAP_WIDTH*(MAP_HEIGHT-1)*sizeof(int)); | 101 | memcpy(mapdata, map.mapdata, MAP_WIDTH*(MAP_HEIGHT-1)*sizeof(int)); |
102 | |||
103 | title = (char*) malloc((MAP_WIDTH+1)*sizeof(char)); | ||
104 | strncpy(title, map.title, MAP_WIDTH+1); | ||
36 | 105 | ||
37 | m_title = (char*) malloc((MAP_WIDTH+1)*sizeof(char)); | 106 | leftMap = map.leftMap; |
38 | strncpy(m_title, map.m_title, MAP_WIDTH+1); | 107 | rightMap = map.rightMap; |
39 | 108 | ||
40 | m_leftMap = map.m_leftMap; | 109 | entities = map.entities; |
41 | m_rightMap = map.m_rightMap; | ||
42 | } | 110 | } |
43 | 111 | ||
44 | Map::Map(Map&& map) : Map() | 112 | Map::Map(Map&& map) : Map() |
@@ -48,8 +116,8 @@ Map::Map(Map&& map) : Map() | |||
48 | 116 | ||
49 | Map::~Map() | 117 | Map::~Map() |
50 | { | 118 | { |
51 | free(m_mapdata); | 119 | free(mapdata); |
52 | free(m_title); | 120 | free(title); |
53 | } | 121 | } |
54 | 122 | ||
55 | Map& Map::operator= (Map map) | 123 | Map& Map::operator= (Map map) |
@@ -61,38 +129,60 @@ Map& Map::operator= (Map map) | |||
61 | 129 | ||
62 | void swap(Map& first, Map& second) | 130 | void swap(Map& first, Map& second) |
63 | { | 131 | { |
64 | std::swap(first.m_mapdata, second.m_mapdata); | 132 | std::swap(first.mapdata, second.mapdata); |
65 | std::swap(first.m_title, second.m_title); | 133 | std::swap(first.title, second.title); |
66 | std::swap(first.m_leftMap, second.m_leftMap); | 134 | std::swap(first.leftMap, second.leftMap); |
67 | std::swap(first.m_rightMap, second.m_rightMap); | 135 | std::swap(first.rightMap, second.rightMap); |
136 | std::swap(first.entities, second.entities); | ||
68 | } | 137 | } |
69 | 138 | ||
70 | const int* Map::mapdata() const | 139 | const int* Map::getMapdata() const |
71 | { | 140 | { |
72 | return m_mapdata; | 141 | return mapdata; |
73 | } | 142 | } |
74 | 143 | ||
75 | const char* Map::title() const | 144 | const char* Map::getTitle() const |
76 | { | 145 | { |
77 | return m_title; | 146 | return title; |
78 | } | 147 | } |
79 | 148 | ||
80 | const Map* Map::getLeftMap() const | 149 | const Map* Map::getLeftMap() const |
81 | { | 150 | { |
82 | return m_leftMap; | 151 | return leftMap; |
83 | } | 152 | } |
84 | 153 | ||
85 | const Map* Map::getRightMap() const | 154 | const Map* Map::getRightMap() const |
86 | { | 155 | { |
87 | return m_rightMap; | 156 | return rightMap; |
88 | } | 157 | } |
89 | 158 | ||
90 | void Map::setLeftMap(const Map* m) | 159 | void Map::setLeftMap(const Map* m) |
91 | { | 160 | { |
92 | m_leftMap = m; | 161 | leftMap = m; |
93 | } | 162 | } |
94 | 163 | ||
95 | void Map::setRightMap(const Map* m) | 164 | void Map::setRightMap(const Map* m) |
96 | { | 165 | { |
97 | m_rightMap = m; | 166 | rightMap = m; |
167 | } | ||
168 | |||
169 | void Map::createEntities(std::list<std::shared_ptr<Entity>>& entities) const | ||
170 | { | ||
171 | for (auto data : this->entities) | ||
172 | { | ||
173 | auto entity = EntityFactory::createNamedEntity(data.name, *this); | ||
174 | entity->position = data.position; | ||
175 | |||
176 | entities.push_back(entity); | ||
177 | } | ||
178 | } | ||
179 | |||
180 | Map& Map::getNamedMap(const std::string name) | ||
181 | { | ||
182 | if (maps.count(name) == 0) | ||
183 | { | ||
184 | maps[name] = Map {name}; | ||
185 | } | ||
186 | |||
187 | return maps[name]; | ||
98 | } | 188 | } |