111
void GameMap::processStyles(std::string styles, int chars_per_style)
113
int c = chars_per_style;
115
for (int j = 0; j < s_height; j++)
117
// remove newline and carriage return lines
118
char test = styles[j*s_width*c + offset];
119
while (test == '\n' || test == '\r')
122
test = styles[j*s_width*c + offset];
125
for (int i = 0; i < s_width; i++)
128
//due to the circumstances, styles is a long stream of
129
//hex digit pairs, so read it character for character
132
memcpy (&hexstr[2], &styles[j*s_width*c + (i * c) + offset], c);
133
hexstr[2 + c + 1 - 1] = '\0';
135
unsigned long int val = 0;
137
val = strtoul (hexstr, &end, 16);
138
Uint32 id = (Uint32) val;
139
TileStyle *style = d_tileSet->getTileStyle(id);
141
style = d_tileSet->getTileStyle(0);
142
d_map[j*s_width + i]->setTileStyle(style);
147
int GameMap::determineCharsPerStyle(std::string styles)
149
return styles.length() / (s_width * s_height);
106
152
GameMap::GameMap(XML_Helper* helper)
108
154
std::string types;
154
for (int j = 0; j < s_height; j++)
156
// remove newline and carriage return lines
157
char test = styles[j*s_width*2 + offset];
158
while (test == '\n' || test == '\r')
161
test = styles[j*s_width*2 + offset];
164
for (int i = 0; i < s_width; i++)
167
//due to the circumstances, styles is a long stream of
168
//hex digit pairs, so read it character for character
171
hexstr[2] = styles[j*s_width*2 + (i * 2) + offset];
172
hexstr[3] = styles[j*s_width*2 + (i * 2) + offset + 1];
175
unsigned long int val = 0;
177
val = strtoul (hexstr, &end, 16);
178
Uint32 id = (Uint32) val;
179
TileStyle *style = d_tileSet->getTileStyle(id);
180
d_map[j*s_width + i]->setTileStyle(style);
199
int chars_per_style = determineCharsPerStyle(styles);
200
processStyles(styles, chars_per_style);
184
202
//add some callbacks for item loading
185
helper->registerTag("itemstack", sigc::mem_fun(this, &GameMap::loadItems));
186
helper->registerTag("item", sigc::mem_fun(this, &GameMap::loadItems));
203
helper->registerTag(GameMap::d_itemstack_tag,
204
sigc::mem_fun(this, &GameMap::loadItems));
205
helper->registerTag(Item::d_tag, sigc::mem_fun(this, &GameMap::loadItems));
262
281
std::stringstream styles;
284
int largest_style_id = d_tileSet->getLargestTileStyleId();
264
285
for (int i = 0; i < s_height; i++)
266
287
for (int j = 0; j < s_width; j++)
268
289
char *hexstr = NULL;
290
int byteswritten = -1;
269
291
TileStyle *style = getTile(j, i)->getTileStyle();
270
asprintf (&hexstr, "%02x", style->getId());
292
if (largest_style_id < 256)
293
byteswritten = asprintf (&hexstr, "%02x", style->getId());
294
else if (largest_style_id < 4096)
295
byteswritten = asprintf (&hexstr, "%03x", style->getId());
296
else if (largest_style_id < 65536)
297
byteswritten = asprintf (&hexstr, "%04x", style->getId());
298
if (hexstr && byteswritten > -1)
278
retval &= helper->openTag("map");
308
retval &= helper->openTag(GameMap::d_tag);
279
309
retval &= helper->saveData("width", s_width);
280
310
retval &= helper->saveData("height", s_height);
281
311
retval &= helper->saveData("tileset", d_tileSet->getSubDir());
287
317
// last, save all items lying around somewhere
288
318
for (int i = 0; i < s_width; i++)
289
for (int j = 0; j < s_height; j++)
290
if (!getTile(i,j)->getItems().empty())
292
retval &= helper->openTag("itemstack");
293
retval &= helper->saveData("x", i);
294
retval &= helper->saveData("y", j);
296
std::list<Item*> items = getTile(i,j)->getItems();
298
std::list<Item*>::const_iterator it;
299
for (it = items.begin(); it != items.end(); it++)
302
retval &= helper->closeTag();
319
for (int j = 0; j < s_height; j++)
320
if (!getTile(i,j)->getBackpack()->empty())
321
retval &= getTile(i,j)->getBackpack()->save(helper);
305
323
retval &= helper->closeTag();
790
bool GameMap::are_those_tiles_similar(Tile::Type outer_tile,Tile::Type inner_tile, bool checking_loneliness)
792
if(checking_loneliness || inner_tile == Tile::HILLS)
794
if( (outer_tile == Tile::MOUNTAIN && inner_tile == Tile::HILLS) ||
795
(inner_tile == Tile::MOUNTAIN && outer_tile == Tile::HILLS))
796
// Mountains and hills are similar, MapGenerator::surroundMountains()
797
// makes sure that mountains are surrounded by hills. So a hill tile
798
// with only a mountain neighbour is not a lone tile
800
// There never should be a lone mountain in grass (not surrounded by hills).
801
// Mountain surrounded by hills is perfectly correct.
803
return outer_tile == inner_tile;
806
{ // to pick correct tile picture for a mountain we treat hills as a tile
807
// different than mountain.
808
return outer_tile == inner_tile;
766
812
int GameMap::tile_is_connected_to_other_like_tiles (Tile::Type tile, int i, int j)
823
869
if (smooth_terrain)
825
demote_lone_tile(0, 0, s_height, s_width, Tile::FOREST, Tile::GRASS);
826
demote_lone_tile(0, 0, s_height, s_width, Tile::MOUNTAIN, Tile::HILLS);
827
demote_lone_tile(0, 0, s_height, s_width, Tile::HILLS, Tile::GRASS);
828
demote_lone_tile(0, 0, s_height, s_width, Tile::WATER, Tile::SWAMP);
871
demote_lone_tile(minx, miny, maxx, maxy, Tile::FOREST, Tile::GRASS);
872
demote_lone_tile(minx, miny, maxx, maxy, Tile::MOUNTAIN, Tile::HILLS);
873
demote_lone_tile(minx, miny, maxx, maxy, Tile::HILLS, Tile::GRASS);
874
demote_lone_tile(minx, miny, maxx, maxy, Tile::WATER, Tile::SWAMP);
875
surroundMountains(minx, miny, maxx, maxy);
831
878
for (int i = minx; i < maxx; i++)
858
896
for (int i = 0; i < s_width; i++)
860
898
if (d_map[j*s_width + i])
861
if (d_map[j*s_width + i]->getItems().empty() == false)
899
if (d_map[j*s_width + i]->getBackpack()->empty() == false)
862
900
items.push_back(Vector<int>(i, j));
906
#define offmap(bx,by) (by<0)||(by>=s_height)||(bx<0)||(bx>=s_width)
907
void GameMap::surroundMountains(int minx, int miny, int maxx, int maxy)
909
for(int j = miny; j < maxy; j++)
910
for(int i = minx; i < maxx; i++)
914
if(getTile(j, i)->getMaptileType() == Tile::MOUNTAIN)
915
for(int J = -1; J <= +1; ++J)
916
for(int I = -1; I <= +1; ++I)
917
if((!(offmap(j+J,i+I))) &&
918
(getTile((j+J),(i+I))->getMaptileType() != Tile::MOUNTAIN))
920
if(getTile((j+J), (i+I))->getMaptileType() != Tile::WATER)
922
new Maptile (d_tileSet, j+J, i+I,
923
d_tileSet->getIndex(Tile::HILLS), NULL));
925
// water has priority here, there was some work done to conenct bodies of water
926
// so don't break those connections.
928
new Maptile (d_tileSet, j, i,
929
d_tileSet->getIndex(Tile::HILLS), NULL));
934
void GameMap::applyTileStyle (int i, int j)
936
Maptile *mtile = getTile(j, i);
937
Tileset *tileset = getTileset();
938
TileStyle *style = calculatePreferredStyle(i, j);
940
style = tileset->getRandomTileStyle(mtile->getType(),
943
style = tileset->getRandomTileStyle(mtile->getType(),
944
TileStyle::INNERMIDDLECENTER);
946
printf ("applying null tile style at %d,%d for tile of kind %d\n", i, j,
947
mtile->getMaptileType());
948
mtile->setTileStyle(style);
951
Vector<int> GameMap::findNearestObjectInDir(Vector<int> pos, Vector<int> dir)
953
std::vector<Vector<int> > objects;
954
Road *road = Roadlist::getInstance()->getNearestObjectInDir(pos, dir);
956
objects.push_back(road->getPos());
957
Bridge *bridge = Bridgelist::getInstance()->getNearestObjectInDir(pos, dir);
959
objects.push_back(bridge->getPos());
960
City *city = Citylist::getInstance()->getNearestObjectInDir(pos, dir);
962
objects.push_back(city->getPos());
963
Temple *temple = Templelist::getInstance()->getNearestObjectInDir(pos, dir);
965
objects.push_back(temple->getPos());
966
Ruin *ruin = Ruinlist::getInstance()->getNearestObjectInDir(pos, dir);
967
if (ruin && ruin->isHidden() == false)
968
objects.push_back(ruin->getPos());
969
if (objects.size() == 0)
970
return Vector<int>(-1,-1);
972
int min_distance = -1;
973
Vector<int> closest = Vector<int>(-1,-1);
974
for (unsigned int i = 0; i < objects.size(); i++)
976
int distance = dist(pos, objects[i]);
977
if (min_distance == -1 || distance < min_distance)
979
min_distance = distance;
980
closest = objects[i];
986
Vector<int> GameMap::findNearestObjectToTheNorth(Vector<int> pos)
988
Vector<int> dir = Vector<int>(0, -1);
989
return findNearestObjectInDir(pos, dir);
992
Vector<int> GameMap::findNearestObjectToTheSouth(Vector<int> pos)
994
Vector<int> dir = Vector<int>(0, 1);
995
return findNearestObjectInDir(pos, dir);
998
Vector<int> GameMap::findNearestObjectToTheEast(Vector<int> pos)
1000
Vector<int> dir = Vector<int>(1, 0);
1001
return findNearestObjectInDir(pos, dir);
1004
Vector<int> GameMap::findNearestObjectToTheWest(Vector<int> pos)
1006
Vector<int> dir = Vector<int>(-1, 0);
1007
return findNearestObjectInDir(pos, dir);