source: network-game/common/WorldMap.cpp@ 90eaad2

Last change on this file since 90eaad2 was 233e736, checked in by Dmitry Portnoy <dportnoy@…>, 11 years ago

Fixed a client-side map loading bug

  • Property mode set to 100644
File size: 8.1 KB
Line 
1#include "WorldMap.h"
2
3#include <string>
4#include <iostream>
5#include <fstream>
6#include <sstream>
7#include <cstdlib>
8#include <cstring>
9
10using namespace std;
11
12WorldMap::WorldMap(int width, int height)
13{
14 this->width = width;
15 this->height = height;
16
17 vctMap = new vector<vector<TerrainType>*>(width);
18 vctStructures = new vector<vector<StructureType>*>(width);
19 vctObjects = new vector<Object>();
20
21 for (int x=0; x<width; x++) {
22 vector<TerrainType>* newMapVector = new vector<TerrainType>(height);
23 vector<StructureType>* newStructureVector = new vector<StructureType>(height);
24
25 for (int y=0; y<height; y++) {
26 (*newMapVector)[y] = TERRAIN_NONE;
27 (*newStructureVector)[y] = STRUCTURE_NONE;
28 }
29
30 (*vctMap)[x] = newMapVector;
31 (*vctStructures)[x] = newStructureVector;
32 }
33}
34
35WorldMap::~WorldMap()
36{
37 for (int x=0; x<width; x++) {
38 delete (*vctMap)[x];
39 delete (*vctStructures)[x];
40 }
41
42 delete vctMap;
43 delete vctStructures;
44 delete vctObjects;
45}
46
47WorldMap::TerrainType WorldMap::getElement(int x, int y)
48{
49 return (*(*vctMap)[x])[y];
50}
51
52void WorldMap::setElement(int x, int y, TerrainType t)
53{
54 (*(*vctMap)[x])[y] = t;
55}
56
57WorldMap::StructureType WorldMap::getStructure(int x, int y)
58{
59 return (*(*vctStructures)[x])[y];
60}
61
62void WorldMap::setStructure(int x, int y, StructureType t)
63{
64 (*(*vctStructures)[x])[y] = t;
65}
66
67POSITION WorldMap::getStructureLocation(StructureType t)
68{
69 POSITION pos;
70 pos.x = 0;
71 pos.y = 0;
72
73 for (int x=0; x<vctStructures->size(); x++) {
74 for (int y=0; y<(*vctStructures)[x]->size(); y++) {
75 if ((*(*vctStructures)[x])[y] == t) {
76 pos.x = x;
77 pos.y = y;
78 return pos;
79 }
80 }
81 }
82
83 return pos;
84}
85
86vector<WorldMap::Object>* WorldMap::getObjects() {
87 return vctObjects;
88}
89
90vector<WorldMap::Object> WorldMap::getObjects(int x, int y) {
91 vector<WorldMap::Object> vctObjectsInRegion;
92
93 vector<WorldMap::Object>::iterator it;
94 for (it = vctObjects->begin(); it != vctObjects->end(); it++) {
95 if (it->pos.x/25 == x && it->pos.y/25 == y)
96 vctObjectsInRegion.push_back(*it);
97 }
98
99 return vctObjectsInRegion;
100}
101
102// used by the server to create new objects
103void WorldMap::addObject(WorldMap::ObjectType t, int x, int y) {
104 int id;
105 vector<WorldMap::Object>::iterator it;
106
107 for (id = 0; id < vctObjects->size(); id++) {
108 for (it = vctObjects->begin(); it != vctObjects->end(); it++) {
109 if (id == it->id)
110 break;
111 }
112
113 if (it == vctObjects->end()) // if no objects with this id exists
114 break;
115 }
116
117 WorldMap::Object o(id, t, x, y);
118 vctObjects->push_back(o);
119}
120
121// used by the client to update object positions or create objects it has not seen before
122void WorldMap::updateObject(int id, WorldMap::ObjectType t, int x, int y) {
123 vector<WorldMap::Object>::iterator it;
124 bool foundObject = false;
125
126 cout << "Searching for object to update" << endl;
127 switch (t) {
128 case WorldMap::OBJECT_BLUE_FLAG:
129 cout << "BLUE_FLAG" << endl;
130 break;
131 case WorldMap::OBJECT_RED_FLAG:
132 cout << "RED_FLAG" << endl;
133 break;
134 }
135
136 for (it = vctObjects->begin(); it != vctObjects->end(); it++) {
137 if (it->id == id) {
138 foundObject = true;
139 cout << "Found object with id " << id << endl;
140 switch (it->type) {
141 case WorldMap::OBJECT_BLUE_FLAG:
142 cout << "BLUE_FLAG" << endl;
143 break;
144 case WorldMap::OBJECT_RED_FLAG:
145 cout << "RED_FLAG" << endl;
146 break;
147 }
148 it->pos.x = x;
149 it->pos.y = y;
150 }
151 }
152
153 if (!foundObject) {
154 WorldMap::Object o(id, t, x, y);
155 vctObjects->push_back(o);
156 }
157}
158
159bool WorldMap::removeObject(int id) {
160 vector<WorldMap::Object>::iterator it;
161
162 for (it = vctObjects->begin(); it != vctObjects->end(); it++) {
163 if (it->id == id) {
164 vctObjects->erase(it);
165 return true;
166 }
167 }
168
169 return false; // no object with that id was found
170}
171
172WorldMap* WorldMap::createDefaultMap()
173{
174 WorldMap* m = new WorldMap(12l, 12);
175
176 for(int x=0; x<12; x++)
177 {
178 for(int y=0; y<12; y++)
179 {
180 if (x ==0 || y == 0 || x == 11 || y == 11)
181 m->setElement(x, y, TERRAIN_OCEAN);
182 else
183 m->setElement(x, y, TERRAIN_GRASS);
184
185 m->setStructure(x, y, STRUCTURE_NONE);
186 }
187 }
188
189 m->setElement(5, 5, TERRAIN_ROCK);
190
191 return m;
192}
193
194WorldMap* WorldMap::loadMapFromFile(string filename)
195{
196 WorldMap* m = NULL;
197
198 ifstream file(filename.c_str());
199
200 cout << "Trying to open file: " << filename << endl;
201
202 if (file.is_open())
203 {
204 cout << filename << " opened successfully" << endl;
205
206 string line;
207 int width, height;
208
209 // read the map dimensions
210 getline(file, line);
211 if (line.size() > 0)
212 {
213 istringstream iss(line);
214 string token;
215 getline(iss, token, 'x');
216 width = atoi(token.c_str());
217 getline(iss, token, 'x');
218 height = atoi(token.c_str());
219 }
220
221 cout << "width: " << width << endl;
222 cout << "height: " << height << endl;
223
224 m = new WorldMap(width, height);
225
226 // read the map contents
227 int row = 0;
228 while ( file.good() )
229 {
230 getline(file, line);
231 if (line.size() > 0)
232 {
233 //cout << "row: " << row << endl;
234 //cout << "line: " << line << endl;
235
236 istringstream iss(line);
237 string token;
238
239 if (row < height) {
240 // load terrain
241
242 int type;
243 TerrainType terrain;
244
245 for(int x=0; x<width; x++)
246 {
247 getline(iss, token, ',');
248 type = atoi(token.c_str());
249
250 //cout << "x: " << x << endl;
251 //cout << "token: " << token << endl;
252 //cout << "type: " << type << endl;
253
254 switch(type) {
255 case 1:
256 terrain = TERRAIN_GRASS;
257 break;
258 case 2:
259 terrain = TERRAIN_OCEAN;
260 break;
261 case 3:
262 terrain = TERRAIN_ROCK;
263 break;
264 }
265
266 m->setElement(x, row, terrain);
267 }
268 }else {
269 // load structure
270
271 int x, y, type;
272 StructureType structure;
273
274 getline(iss, token, ',');
275 //cout << "token(x): " << token << endl;
276 x = atoi(token.c_str());
277
278 getline(iss, token, ',');
279 //cout << "token(y): " << token << endl;
280 y = atoi(token.c_str());
281
282 getline(iss, token, ',');
283 //cout << "token(type): " << token << endl;
284 type = atoi(token.c_str());
285
286 switch(type) {
287 case 0:
288 structure = STRUCTURE_NONE;
289 break;
290 case 1:
291 structure = STRUCTURE_BLUE_FLAG;
292 break;
293 case 2:
294 structure = STRUCTURE_RED_FLAG;
295 break;
296 }
297
298 m->setStructure(x, y, structure);
299 }
300 }
301
302 row++;
303 }
304 file.close();
305 cout << filename << " closed" << endl;
306 }
307 else
308 cout << "Could not open the file" << endl;
309
310 cout << "Finished file processing" << endl;
311
312 return m;
313}
314
315
316/*** Functions for Object ***/
317
318WorldMap::Object::Object(int id, ObjectType type, int x, int y) {
319 this->type = type;
320 this->id = id;
321 this->pos.x = x;
322 this->pos.y = y;
323}
324
325WorldMap::Object::Object(int id, ObjectType type, POSITION pos) {
326 this->type = type;
327 this->id = id;
328 this->pos = pos;
329}
330
331WorldMap::Object::~Object() {
332}
333
334void WorldMap::Object::serialize(char* buffer) {
335 memcpy(buffer, &this->type, 4);
336 memcpy(buffer+4, &this->id, 4);
337 memcpy(buffer+8, &this->pos.x, 4);
338 memcpy(buffer+12, &this->pos.y, 4);
339}
340
341void WorldMap::Object::deserialize(char* buffer) {
342 memcpy(&this->type, buffer, 4);
343 memcpy(&this->id, buffer+4, 4);
344 memcpy(&this->pos.x, buffer+8, 4);
345 memcpy(&this->pos.y, buffer+12, 4);
346}
Note: See TracBrowser for help on using the repository browser.