FIFE
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
maploader.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2013 by the FIFE team *
3  * http://www.fifengine.net *
4  * This file is part of FIFE. *
5  * *
6  * FIFE is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU Lesser General Public *
8  * License as published by the Free Software Foundation; either *
9  * version 2.1 of the License, or (at your option) any later version. *
10  * *
11  * This library is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14  * Lesser General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU Lesser General Public *
17  * License along with this library; if not, write to the *
18  * Free Software Foundation, Inc., *
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20  ***************************************************************************/
21 
22 // Standard C++ library includes
23 #include <string>
24 #include <vector>
25 
26 // 3rd party includes
27 
28 // FIFE includes
29 // These includes are split up in two parts, separated by one empty line
30 // First block: files included from the FIFE root src directory
31 // Second block: files included from the same folder
32 #include "ext/tinyxml/fife_tinyxml.h"
33 #include "model/model.h"
34 #include "model/structures/layer.h"
36 #include "model/structures/cell.h"
42 #include "model/metamodel/action.h"
44 #include "vfs/vfs.h"
45 #include "vfs/vfsdirectory.h"
46 #include "vfs/raw/rawdata.h"
47 #include "util/base/exception.h"
48 #include "util/log/logger.h"
49 #include "util/resource/resource.h"
50 #include "util/structures/rect.h"
51 #include "video/imagemanager.h"
52 #include "video/image.h"
53 #include "video/renderbackend.h"
54 #include "view/visual.h"
55 #include "view/camera.h"
57 #include "util/base/stringutils.h"
58 
59 #include "atlasloader.h"
60 #include "maploader.h"
61 #include "animationloader.h"
62 #include "objectloader.h"
63 
64 namespace FIFE {
68  static Logger _log(LM_NATIVE_LOADERS);
69 
70  MapLoader::MapLoader(Model* model, VFS* vfs, ImageManager* imageManager, RenderBackend* renderBackend)
71  : m_model(model), m_vfs(vfs), m_imageManager(imageManager), m_renderBackend(renderBackend),
72  m_loaderName("fife"), m_mapDirectory("") {
76  }
77 
79 
80  }
81 
82  Map* MapLoader::load(const std::string& filename) {
83  Map* map = NULL;
84 
85  // reset percent done listener just in case
86  // it has residual data from last load
88 
89  bfs::path mapPath(filename);
90 
91  if (HasParentPath(mapPath)) {
92  if (GetParentPath(mapPath).string() != m_mapDirectory) {
93  // save the directory where the map file is located
94  m_mapDirectory = GetParentPath(mapPath).string();
95  }
96  }
97 
98  TiXmlDocument mapFile;
99 
100  std::string mapFilename = mapPath.string();
101 
102  try {
103  RawData* data = m_vfs->open(mapFilename);
104 
105  if (data) {
106  if (data->getDataLength() != 0) {
107  mapFile.Parse(data->readString(data->getDataLength()).c_str());
108 
109  if (mapFile.Error()) {
110  std::ostringstream oss;
111  oss << " Failed to load"
112  << mapFilename
113  << " : " << __FILE__
114  << " [" << __LINE__ << "]"
115  << std::endl;
116  FL_ERR(_log, oss.str());
117 
118  return map;
119  }
120  }
121 
122  // done with data delete resource
123  delete data;
124  data = 0;
125  }
126  }
127  catch (NotFound& e)
128  {
129  FL_ERR(_log, e.what());
130 
131  // TODO - should we abort here
132  // or rethrow the exception
133  // or just keep going
134 
135  return map;
136  }
137 
138  // if we get here then everything loaded properly
139  // so we can just parse out the contents
140  const TiXmlElement* root = mapFile.RootElement();
141 
142  if (root) {
143  const std::string* loaderName = root->Attribute(std::string("loaderName"));
144 
145  if (loaderName) {
146  m_loaderName = *loaderName;
147  }
148 
149  int numElements = 0;
150  root->QueryValueAttribute("elements", &numElements);
152 
153  const std::string* mapName = root->Attribute(std::string("id"));
154 
155  if (mapName) {
156  try {
157  map = m_model->createMap(*mapName);
158  }
159  catch (NameClash& e) {
160  FL_ERR(_log, e.what());
161 
162  // just rethrow to client
163  throw;
164  }
165 
166  if (map) {
167  map->setFilename(mapFilename);
168 
169  std::string ns = "";
170  for (const TiXmlElement *importElement = root->FirstChildElement("import"); importElement; importElement = importElement->NextSiblingElement("import")) {
171  const std::string* importDir = importElement->Attribute(std::string("dir"));
172  const std::string* importFile = importElement->Attribute(std::string("file"));
173 
174  std::string directory = "";
175  if (importDir) {
176  directory = *importDir;
177  }
178 
179  std::string file = "";
180  if (importFile) {
181  file = *importFile;
182  }
183 
184  if (importDir && !importFile) {
185  bfs::path fullPath(m_mapDirectory);
186  fullPath /= directory;
187  loadImportDirectory(fullPath.string());
188  }
189  else if (importFile) {
190  bfs::path fullFilePath(file);
191  bfs::path fullDirPath(directory);
192  if (importDir) {
193  fullDirPath = bfs::path(m_mapDirectory);
194  fullDirPath /= directory;
195  }
196  else {
197  fullFilePath = bfs::path(m_mapDirectory);
198  fullFilePath /= file;
199  }
200  loadImportFile(fullFilePath.string(), fullDirPath.string());
201  }
202  }
203  // converts multiobject part id to object pointer
204  std::list<std::string> namespaces = m_model->getNamespaces();
205  std::list<std::string>::iterator name_it = namespaces.begin();
206  for (; name_it != namespaces.end(); ++name_it) {
207  std::list<Object*> objects = m_model->getObjects(*name_it);
208  std::list<Object*>::iterator object_it = objects.begin();
209  for (; object_it != objects.end(); ++object_it) {
210  if ((*object_it)->isMultiObject()) {
211  const std::list<std::string>& multiParts = (*object_it)->getMultiPartIds();
212  std::list<std::string>::const_iterator multi_it = multiParts.begin();
213  for (; multi_it != multiParts.end(); ++multi_it) {
214  Object* partObj = m_model->getObject(*multi_it, *name_it);
215  if (partObj) {
216  partObj->setMultiPart(true);
217  (*object_it)->addMultiPart(partObj);
218  }
219  }
220  }
221  }
222  }
223 
224  // iterate over elements looking for layers
225  for (const TiXmlElement* layerElement = root->FirstChildElement("layer"); layerElement; layerElement = layerElement->NextSiblingElement("layer")) {
226  // defaults
227  double xOffset = 0.0;
228  double yOffset = 0.0;
229  double zOffset = 0.0;
230  double xScale = 1.0;
231  double yScale = 1.0;
232  double zScale = 1.0;
233  double rotation = 0.0;
234 
235  int xOffsetRetVal = layerElement->QueryValueAttribute("x_offset", &xOffset);
236  int yOffsetRetVal = layerElement->QueryValueAttribute("y_offset", &yOffset);
237  layerElement->QueryValueAttribute("z_offset", &zOffset);
238  int xScaleRetVal = layerElement->QueryValueAttribute("x_scale", &xScale);
239  int yScaleRetVal = layerElement->QueryValueAttribute("y_scale", &yScale);
240  layerElement->QueryValueAttribute("z_scale", &zScale);
241  int rotationRetVal = layerElement->QueryValueAttribute("rotation", &rotation);
242 
243  const std::string* layerName = layerElement->Attribute(std::string("id"));
244  const std::string* pathing = layerElement->Attribute(std::string("pathing"));
245  const std::string* sorting = layerElement->Attribute(std::string("sorting"));
246  const std::string* gridType = layerElement->Attribute(std::string("grid_type"));
247  const std::string* layerType = layerElement->Attribute(std::string("layer_type"));
248  const std::string* layerTypeName = layerElement->Attribute(std::string("layer_type_id"));
249 
250  if (xOffsetRetVal == TIXML_SUCCESS &&
251  yOffsetRetVal == TIXML_SUCCESS &&
252  xScaleRetVal == TIXML_SUCCESS &&
253  yScaleRetVal == TIXML_SUCCESS &&
254  rotationRetVal == TIXML_SUCCESS &&
255  layerName &&
256  pathing &&
257  gridType) {
258 
259  PathingStrategy pathStrategy = CELL_EDGES_ONLY;
260  if ("cell_edges_and_diagonals" == *pathing) {
261  pathStrategy = CELL_EDGES_AND_DIAGONALS;
262  }
263 
264  SortingStrategy sortStrategy = SORTING_CAMERA;
265  if (sorting) {
266  if (*sorting == "location") {
267  sortStrategy = SORTING_LOCATION;
268  } else if (*sorting == "camera_and_location") {
269  sortStrategy = SORTING_CAMERA_AND_LOCATION;
270  }
271  }
272 
273  CellGrid* grid = NULL;
274  if (gridType) {
275  grid = m_model->getCellGrid(*gridType);
276  }
277  else {
278  grid = m_model->getCellGrid("square");
279  }
280 
281  if (grid) {
282  grid->setXShift(xOffset);
283  grid->setXScale(xScale);
284  grid->setYShift(yOffset);
285  grid->setYScale(yScale);
286  grid->setZShift(zOffset);
287  grid->setZScale(zScale);
288  grid->setRotation(rotation);
289 
290  Layer *layer = NULL;
291  try {
292  layer = map->createLayer(*layerName, grid);
293  }
294  catch (NameClash&) {
295  // TODO - handle exception
296  assert(false);
297  }
298 
299  if (layer) {
300  layer->setPathingStrategy(pathStrategy);
301  layer->setSortingStrategy(sortStrategy);
302  if (layerType) {
303  if (*layerType == "walkable") {
304  layer->setWalkable(true);
305  } else if (*layerType == "interact") {
306  layer->setInteract(true, *layerTypeName);
307  }
308  }
309 
310  double curr_x = 0;
311  double curr_y = 0;
312 
313  for (const TiXmlElement* instances = layerElement->FirstChildElement("instances"); instances; instances = instances->NextSiblingElement("instances")) {
314  for (const TiXmlElement* instance = instances->FirstChildElement("i"); instance; instance = instance->NextSiblingElement("i")) {
315  double x = 0;
316  double y = 0;
317  double z = 0;
318  int r = 0;
319  int stackpos = 0;
320  int cellStack = 0;
321  int visitorRadius = 0;
322 
323  const std::string* instanceId = instance->Attribute(std::string("id"));
324  const std::string* objectId = instance->Attribute(std::string("o"));
325  const std::string* costId = instance->Attribute(std::string("cost_id"));
326 
327  if (!objectId) {
328  objectId = instance->Attribute(std::string("object"));
329  }
330 
331  if (!objectId) {
332  objectId = instance->Attribute(std::string("obj"));
333  }
334 
335  const std::string* namespaceId = instance->Attribute(std::string("ns"));
336 
337  if (!namespaceId) {
338  namespaceId = instance->Attribute(std::string("namespace"));
339  }
340 
341  int xRetVal = instance->QueryValueAttribute("x", &x);
342  int yRetVal = instance->QueryValueAttribute("y", &y);
343  instance->QueryValueAttribute("z", &z);
344  int rRetVal = instance->QueryValueAttribute("r", &r);
345 
346  if (xRetVal == TIXML_SUCCESS) {
347  curr_x = x;
348  }
349  else {
350  x = ++curr_x;
351  }
352 
353  if (yRetVal == TIXML_SUCCESS) {
354  curr_y = y;
355  }
356  else {
357  y = curr_y;
358  }
359 
360  if (rRetVal != TIXML_SUCCESS) {
361  rRetVal = instance->QueryValueAttribute("rotation", &r);
362  }
363 
364  int stackRetVal = instance->QueryValueAttribute("stackpos", &stackpos);
365  int cellStackRetVal = instance->QueryValueAttribute("cellstack", &cellStack);
366  int visitorRetVal = instance->QueryValueAttribute("visitor_radius", &visitorRadius);
367  const std::string* shapeType = instance->Attribute(std::string("visitor_shape"));
368  VisitorShapeInfo visitorShape = ITYPE_NO_SHAPE;
369  if (shapeType) {
370  if ("quad" == *shapeType) {
371  visitorShape = ITYPE_QUAD_SHAPE;
372  } else if ("circle" == *shapeType) {
373  visitorShape = ITYPE_CIRCLE_SHAPE;
374  }
375  }
376 
377  if (objectId) {
378  if (namespaceId) {
379  ns = *namespaceId;
380  }
381 
382  Object* object = m_model->getObject(*objectId, ns);
383 
384  if (object) {
385  Instance* inst = NULL;
386  if (instanceId) {
387  inst = layer->createInstance(object, ExactModelCoordinate(x,y,z), *instanceId);
388  }
389  else {
390  inst = layer->createInstance(object, ExactModelCoordinate(x,y,z));
391  }
392 
393  if (inst) {
394  if (rRetVal != TIXML_SUCCESS) {
395  ObjectVisual* objVisual = object->getVisual<ObjectVisual>();
396  std::vector<int> angles;
397  objVisual->getStaticImageAngles(angles);
398  if (!angles.empty()) {
399  r = angles[0];
400  }
401  }
402 
403  inst->setRotation(r);
404 
405  InstanceVisual* instVisual = InstanceVisual::create(inst);
406 
407  if (instVisual && (stackRetVal == TIXML_SUCCESS)) {
408  instVisual->setStackPosition(stackpos);
409  }
410 
411  if (cellStackRetVal == TIXML_SUCCESS) {
412  inst->setCellStackPosition(cellStack);
413  }
414 
415  if (visitorRetVal == TIXML_SUCCESS) {
416  inst->setVisitor(true);
417  inst->setVisitorRadius(visitorRadius);
418  inst->setVisitorShape(visitorShape);
419  }
420 
421  if (costId) {
422  double cost = 0;
423  int costRetVal = instance->QueryValueAttribute("cost", &cost);
424  if (costRetVal == TIXML_SUCCESS) {
425  inst->setCost(*costId, cost);
426  }
427  }
428 
429  if (object->getAction("default")) {
430  Location target(layer);
431 
432  inst->actRepeat("default", target);
433  }
434  }
435  else
436  {
437  std::ostringstream oss;
438  oss << " Failed to create instance of object "
439  << *objectId
440  << " : " << __FILE__
441  << " [" << __LINE__ << "]"
442  << std::endl;
443  FL_ERR(_log, oss.str());
444  }
445  }
446  }
447 
448  // increment % done counter
450  }
451  }
452  }
453  }
454  }
455 
456  // increment % done counter
458  }
459 
460  // init CellCaches
461  map->initializeCellCaches();
462  // add Cells from xml File
463  for (const TiXmlElement* cacheElements = root->FirstChildElement("cellcaches"); cacheElements; cacheElements = cacheElements->NextSiblingElement("cellcaches")) {
464  for (const TiXmlElement* cacheElement = cacheElements->FirstChildElement("cellcache"); cacheElement; cacheElement = cacheElement->NextSiblingElement("cellcache")) {
465  double cacheCost = 1.0;
466  double cacheSpeed = 1.0;
467  const std::string* layerId = cacheElement->Attribute(std::string("id"));
468 
469  if (layerId) {
470  cacheElement->QueryDoubleAttribute("default_cost", &cacheCost);
471  cacheElement->QueryDoubleAttribute("default_speed", &cacheSpeed);
472 
473  Layer* layer = map->getLayer(*layerId);
474  if (layer) {
475  CellCache* cache = layer->getCellCache();
476  if (cache) {
477  int searchNarrow = 0;
478  cacheElement->QueryIntAttribute("search_narrow", &searchNarrow);
479  cache->setSearchNarrowCells(searchNarrow != 0);
480 
481  cache->setDefaultCostMultiplier(cacheCost);
482  cache->setDefaultSpeedMultiplier(cacheSpeed);
483  for (const TiXmlElement* cellElement = cacheElement->FirstChildElement("cell"); cellElement; cellElement = cellElement->NextSiblingElement("cell")) {
484  int cellX = 0;
485  int cellY = 0;
486  int success = cellElement->QueryIntAttribute("x", &cellX);
487  success &= cellElement->QueryIntAttribute("y", &cellY);
488  if (success == TIXML_SUCCESS) {
489  ModelCoordinate mc(cellX, cellY);
490  Cell* cell = cache->createCell(mc);
491 
492  const std::string* cellVisual = cellElement->Attribute(std::string("state"));
493  if (cellVisual) {
495  if (*cellVisual == "concealed") {
496  cve = CELLV_CONCEALED;
497  } else if (*cellVisual == "masked") {
498  cve = CELLV_MASKED;
499  }
500  cell->setFoWType(cve);
501  }
502 
503  const std::string* cellBlocker = cellElement->Attribute(std::string("blocker_type"));
504  if (cellBlocker) {
505  if (*cellBlocker == "no_blocker") {
507  cell->setCellType(cti);
508  } else if (*cellBlocker == "blocker") {
510  cell->setCellType(cti);
511  }
512  }
513 
514  double cellCost = 1.0;
515  double cellSpeed = 1.0;
516  success = cellElement->QueryDoubleAttribute("default_cost", &cellCost);
517  if (success == TIXML_SUCCESS) {
518  cell->setCostMultiplier(cellCost);
519  }
520  success = cellElement->QueryDoubleAttribute("default_speed", &cellSpeed);
521  if (success == TIXML_SUCCESS) {
522  cell->setSpeedMultiplier(cellSpeed);
523 
524  }
525 
526  int isNarrow = 0;
527  cellElement->QueryIntAttribute("narrow", &isNarrow);
528  if (isNarrow != 0) {
529  cache->addNarrowCell(cell);
530  }
531  // add cost with given id to cell
532  for (const TiXmlElement* costElement = cellElement->FirstChildElement("cost"); costElement; costElement = costElement->NextSiblingElement("cost")) {
533  const std::string* costId = costElement->Attribute(std::string("id"));
534  double cost = 1.0;
535  success = costElement->QueryDoubleAttribute("value", &cost);
536  if (costId && success == TIXML_SUCCESS) {
537  cache->registerCost(*costId, cost);
538  cache->addCellToCost(*costId, cell);
539  }
540  }
541  // add area to cell
542  for (const TiXmlElement* areaElement = cellElement->FirstChildElement("area"); areaElement; areaElement = areaElement->NextSiblingElement("area")) {
543  const std::string* areaId = areaElement->Attribute(std::string("id"));
544  if (areaId) {
545  cache->addCellToArea(*areaId, cell);
546  }
547  }
548  }
549  }
550  }
551  }
552  }
553  }
554  }
555  // finalize CellCaches
556  map->finalizeCellCaches();
557  // add Transistions
558  for (const TiXmlElement* cacheElements = root->FirstChildElement("cellcaches"); cacheElements; cacheElements = cacheElements->NextSiblingElement("cellcaches")) {
559  for (const TiXmlElement* cacheElement = cacheElements->FirstChildElement("cellcache"); cacheElement; cacheElement = cacheElement->NextSiblingElement("cellcache")) {
560  const std::string* layerId = cacheElement->Attribute(std::string("id"));
561  if (layerId) {
562  Layer* layer = map->getLayer(*layerId);
563  if (layer) {
564  CellCache* cache = layer->getCellCache();
565  if (cache) {
566  for (const TiXmlElement* cellElement = cacheElement->FirstChildElement("cell"); cellElement; cellElement = cellElement->NextSiblingElement("cell")) {
567  int cellX = 0;
568  int cellY = 0;
569  int success = cellElement->QueryIntAttribute("x", &cellX);
570  success &= cellElement->QueryIntAttribute("y", &cellY);
571  if (success == TIXML_SUCCESS) {
572  ModelCoordinate mc(cellX, cellY);
573  Cell* cell = cache->getCell(mc);
574  if (!cell) {
575  continue;
576  }
577  for (const TiXmlElement* transitionElement = cellElement->FirstChildElement("transition"); transitionElement; transitionElement = transitionElement->NextSiblingElement("transition")) {
578  int targetX = 0;
579  int targetY = 0;
580  int targetZ = 0;
581  success = transitionElement->QueryIntAttribute("x", &targetX);
582  success &= transitionElement->QueryIntAttribute("y", &targetY);
583  transitionElement->QueryIntAttribute("z", &targetZ);
584  if (success == TIXML_SUCCESS) {
585  ModelCoordinate mc(targetX, targetY, targetZ);
586  Layer* targetLayer = NULL;
587  const std::string* targetLayerId = transitionElement->Attribute(std::string("id"));
588  if (targetLayerId) {
589  targetLayer = map->getLayer(*targetLayerId);
590  }
591  if (!targetLayer) {
592  targetLayer = layer;
593  }
594 
595  int immediate = 0;
596  transitionElement->QueryIntAttribute("immediate", &immediate);
597  cell->createTransition(targetLayer, mc, immediate != 0);
598  }
599  }
600  }
601  }
602  }
603  }
604  }
605  }
606  }
607 
608  for (const TiXmlElement* triggerElements = root->FirstChildElement("triggers"); triggerElements; triggerElements = triggerElements->NextSiblingElement("triggers")) {
609  TriggerController* triggerController = map->getTriggerController();
610  for (const TiXmlElement* triggerElement = triggerElements->FirstChildElement("trigger"); triggerElement; triggerElement = triggerElement->NextSiblingElement("trigger")) {
611  const std::string* triggerName = triggerElement->Attribute(std::string("name"));
612  int triggered = 0;
613  int allInstances = 0;
614  triggerElement->QueryIntAttribute("triggered", &triggered);
615  triggerElement->QueryIntAttribute("all_instances", &allInstances);
616 
617  Trigger* trigger = triggerController->createTrigger(*triggerName);
618  if (triggered > 0) {
619  trigger->setTriggered();
620  }
621  if (allInstances > 0) {
622  trigger->enableForAllInstances();
623  }
624 
625  const std::string* instanceId = triggerElement->Attribute(std::string("attached_instance"));
626  const std::string* layerId = triggerElement->Attribute(std::string("attached_layer"));
627  if (instanceId && layerId) {
628  Layer* layer = map->getLayer(*layerId);
629  if (layer) {
630  Instance* instance = layer->getInstance(*instanceId);
631  if (instance) {
632  trigger->attach(instance);
633  }
634  }
635  }
636  for (const TiXmlElement* assignElement = triggerElement->FirstChildElement("assign"); assignElement; assignElement = assignElement->NextSiblingElement("assign")) {
637  layerId = assignElement->Attribute(std::string("layer_id"));
638  if (!layerId) {
639  continue;
640  }
641  int x = 0;
642  int y = 0;
643  assignElement->QueryIntAttribute("x", &x);
644  assignElement->QueryIntAttribute("y", &y);
645  Layer* layer = map->getLayer(*layerId);
646  if (layer) {
647  trigger->assign(layer, ModelCoordinate(x, y));
648  }
649  }
650  for (const TiXmlElement* enabledElement = triggerElement->FirstChildElement("enabled"); enabledElement; enabledElement = enabledElement->NextSiblingElement("enabled")) {
651  layerId = enabledElement->Attribute(std::string("layer_id"));
652  instanceId = enabledElement->Attribute(std::string("instance_id"));
653  if (!instanceId || !layerId) {
654  continue;
655  }
656  Layer* layer = map->getLayer(*layerId);
657  if (layer) {
658  Instance* instance = layer->getInstance(*instanceId);
659  if (instance) {
660  trigger->enableForInstance(instance);
661  }
662  }
663  }
664  for (const TiXmlElement* conditionElement = triggerElement->FirstChildElement("condition"); conditionElement; conditionElement = conditionElement->NextSiblingElement("condition")) {
665  int conditionId = -1;
666  conditionElement->QueryIntAttribute("id", &conditionId);
667  if (conditionId != -1) {
668  trigger->addTriggerCondition(static_cast<TriggerCondition>(conditionId));
669  }
670  }
671  }
672  }
673 
674 
675  for (const TiXmlElement* cameraElement = root->FirstChildElement("camera"); cameraElement; cameraElement = cameraElement->NextSiblingElement("camera")) {
676  const std::string* cameraId = cameraElement->Attribute(std::string("id"));
677  const std::string* refLayerId = cameraElement->Attribute(std::string("ref_layer_id"));
678 
679  int refCellWidth = 0;
680  int refCellHeight = 0;
681  int success = cameraElement->QueryIntAttribute("ref_cell_width", &refCellWidth);
682  success &= cameraElement->QueryIntAttribute("ref_cell_height", &refCellHeight);
683 
684  if (cameraId && refLayerId && success == TIXML_SUCCESS) {
685  double tilt = 0.0;
686  double zoom = 1.0;
687  double rotation = 0.0;
688  double zToY = 0.0;
689  cameraElement->QueryDoubleAttribute("tilt", &tilt);
690  cameraElement->QueryDoubleAttribute("zoom", &zoom);
691  cameraElement->QueryDoubleAttribute("rotation", &rotation);
692  success = cameraElement->QueryDoubleAttribute("ztoy", &zToY);
693 
694  const std::string* viewport = cameraElement->Attribute(std::string("viewport"));
695 
696  Layer* layer = NULL;
697  try {
698  layer = map->getLayer(*refLayerId);
699  }
700  catch (NotFound&) {
701  // TODO - handle exception
702  assert(false);
703  }
704 
705  Camera* cam = NULL;
706  if (layer) {
707  if (viewport) {
708  // parse out the viewport parameters
709  IntVector viewportParameters = tokenize(*viewport, ',');
710 
711  // make sure the right number of viewport parameters were parsed
712  if (viewportParameters.size() == 4) {
713  Rect rect(viewportParameters[0], viewportParameters[1],
714  viewportParameters[2], viewportParameters[3]);
715 
716  try {
717  cam = map->addCamera(*cameraId, layer, rect);
718  }
719  catch (NameClash&) {
720  // TODO - handle exception
721  assert(false);
722  }
723  }
724  }
725  else {
727 
728  try {
729  cam = map->addCamera(*cameraId, layer, rect);
730  }
731  catch (NameClash&) {
732  // TODO - handle exception
733  assert(false);
734  }
735  }
736  }
737 
738  if (cam) {
739  cam->setCellImageDimensions(refCellWidth, refCellHeight);
740  cam->setRotation(rotation);
741  cam->setTilt(tilt);
742  cam->setZoom(zoom);
743  if (success == TIXML_SUCCESS) {
744  cam->setZToY(zToY);
745  }
746 
747  // active instance renderer for camera
748  InstanceRenderer* instanceRenderer = InstanceRenderer::getInstance(cam);
749  if (instanceRenderer)
750  {
751  instanceRenderer->activateAllLayers(map);
752  }
753  }
754  }
755 
756  // increment % done counter
758  }
759  }
760  }
761  }
762 
763  return map;
764  }
765 
767  assert(objectLoader);
768 
769  m_objectLoader = objectLoader;
770  }
771 
772 
774  assert(animationLoader);
775 
776  m_objectLoader->setAnimationLoader(animationLoader);
777  }
778 
780  assert(atlasLoader);
781 
782  m_atlasLoader = atlasLoader;
783  }
784 
785  bool MapLoader::isLoadable(const std::string& filename) const {
786  bfs::path mapPath(filename);
787 
788  TiXmlDocument mapFile;
789 
790  std::string mapFilename = mapPath.string();
791 
792  try {
793  RawData* data = m_vfs->open(mapFilename);
794 
795  if (data) {
796  if (data->getDataLength() != 0) {
797  mapFile.Parse(data->readString(data->getDataLength()).c_str());
798 
799  if (mapFile.Error()) {
800  return false;
801  }
802 
803  const TiXmlElement* root = mapFile.RootElement();
804 
805  if (root) {
806  const std::string* loaderName = root->Attribute(std::string("loader"));
807 
808  // if the file does not specify a loader but was opened and parsed
809  // correctly then we know we have a compatible extension so we will
810  // attempt to load it, if it does specify a loader then the loader
811  // name will be checked
812  if (!loaderName || (loaderName && *loaderName == getLoaderName())) {
813  return true;
814  }
815  }
816  }
817 
818  // done with file delete the resource
819  delete data;
820  data = 0;
821  }
822  }
823  catch (NotFound& e) {
824  FL_ERR(_log, e.what());
825 
826  return false;
827  }
828 
829  return false;
830  }
831 
832  void MapLoader::loadImportFile(const std::string& file, const std::string& directory) {
833  if (!file.empty()) {
834  bfs::path importFilePath(directory);
835  importFilePath /= file;
836 
837  std::string importFileString = importFilePath.string();
838  if (m_objectLoader && m_objectLoader->isLoadable(importFileString)) {
839  m_objectLoader->load(importFileString);
840  }
841  else if (m_atlasLoader && m_atlasLoader->isLoadable(importFileString)) {
842  m_atlasLoader->load(importFileString);
843  }
844  }
845  }
846 
847  void MapLoader::loadImportDirectory(const std::string& directory) {
848  if (!directory.empty()) {
849  bfs::path importDirectory(directory);
850  std::string importDirectoryString = importDirectory.string();
851 
852  std::set<std::string> files = m_vfs->listFiles(importDirectoryString);
853 
854  // load all xml files in the directory
855  std::set<std::string>::iterator iter;
856  for (iter = files.begin(); iter != files.end(); ++iter) {
857  // TODO - vtchill - may need a way to allow clients to load things other
858  // than .xml and .zip files
859  std::string ext = bfs::extension(*iter);
860  if (ext == ".xml" || ext == ".zip") {
861  loadImportFile(*iter, importDirectoryString);
862  }
863  }
864 
865  std::set<std::string> nestedDirectories = m_vfs->listDirectories(importDirectoryString);
866  for (iter = nestedDirectories.begin(); iter != nestedDirectories.end(); ++iter) {
867  // do not attempt to load anything from a .svn directory
868  if ((*iter).find(".svn") == std::string::npos) {
869  loadImportDirectory(importDirectoryString + "/" + *iter);
870  }
871  }
872  }
873  }
874 
877  }
878 
879  const std::string& MapLoader::getLoaderName() const {
880  return m_loaderName;
881 
882  }
883 
884  MapLoader* createDefaultMapLoader(Model* model, VFS* vfs, ImageManager* imageManager, RenderBackend* renderBackend) {
885  return (new MapLoader(model, vfs, imageManager, renderBackend));
886  }
887 }
std::list< std::string > getNamespaces() const
Get a list of namespaces currently referenced by objects in the metamodel.
Definition: model.cpp:149
void setZScale(const double scale)
Set the cellgrid z-scaling.
Definition: cellgrid.h:192
static InstanceVisual * create(Instance *instance)
Constructs and assigns it to the passed item.
Definition: visual.cpp:179
Abstract interface for all the renderbackends.
void setZToY(double zToY)
Sets zToY value for the camera and enables their use.
Definition: camera.cpp:191
std::set< std::string > listFiles(const std::string &path) const
Get a filelist of the given directory.
Definition: vfs.cpp:182
uint32_t getDataLength() const
get the complete datalength
Definition: rawdata.cpp:75
uint32_t getScreenHeight() const
void addPercentDoneListener(PercentDoneListener *listener)
allows adding a listener to the map loader for percent completed events
Definition: maploader.cpp:875
ImageManager.
Definition: imagemanager.h:54
Map * load(const std::string &filename)
Definition: maploader.cpp:82
Layer * getLayer(const std::string &identifier)
Get the layer with the given id.
Definition: map.cpp:73
Camera * addCamera(const std::string &id, Layer *layer, const Rect &viewport)
Adds camera to the map.
Definition: map.cpp:245
void attach(Instance *instance)
Attaches the trigger to the given instance.
Definition: trigger.cpp:286
Object class.
Definition: object.h:51
Instance visual contains data that is needed to visualize the instance on screen. ...
Definition: visual.h:158
void setZShift(const double zshift)
Set the cellgrid z shift.
Definition: cellgrid.h:163
void activateAllLayers(Map *elevation)
Activates all layers from given elevation.
void setSearchNarrowCells(bool search)
Sets if narrow cells should be searched automatic.
Definition: cellcache.cpp:1392
void reset(T *ptr=0)
reset this pointer to a null shared pointer this can be used to lower the reference count of the shar...
Definition: sharedptr.h:164
void setAnimationLoader(const FIFE::AnimationLoaderPtr &animationLoader)
Definition: maploader.cpp:773
A CellCache is an abstract depiction of one or a few layers and contains additional information...
Definition: cellcache.h:111
MapLoader(Model *model, VFS *vfs, ImageManager *imageManager, RenderBackend *renderBackend)
Definition: maploader.cpp:70
void enableForInstance(Instance *instance)
Enables trigger for given instance.
Definition: trigger.cpp:212
void setSortingStrategy(SortingStrategy strategy)
Sets sorting strategy for the layer.
Definition: layer.cpp:515
void setTilt(double tilt)
Sets tilt for the camera.
Definition: camera.cpp:136
void setDefaultCostMultiplier(double multi)
Sets default cost for this CellCache.
Definition: cellcache.cpp:1144
void setSpeedMultiplier(double multi)
Changes the cell speed.
Definition: cell.cpp:454
void addCellToCost(const std::string &costId, Cell *cell)
Assigns a cell to a cost identifier.
Definition: cellcache.cpp:1021
RawData * open(const std::string &path)
Open a file.
Definition: vfs.cpp:172
CellCache * getCellCache()
Returns the CellCache of this layer.
Definition: layer.cpp:573
void setCellType(CellTypeInfo type)
Sets blocker type.
Definition: cell.cpp:499
std::string m_loaderName
Definition: maploader.h:114
void setAtlasLoader(const FIFE::AtlasLoaderPtr &atlasLoader)
Definition: maploader.cpp:779
void addTriggerCondition(TriggerCondition type)
Adds trigger condition.
Definition: trigger.cpp:194
Instance * createInstance(Object *object, const ModelCoordinate &p, const std::string &id="")
Add an instance of an object at a specific position.
Definition: layer.cpp:109
static Logger _log(LM_AUDIO)
void setVisitorRadius(uint16_t radius)
Sets the range for a visitor.
Definition: instance.cpp:547
void registerCost(const std::string &costId, double cost)
Adds a cost with the given id and value.
Definition: cellcache.cpp:974
void loadImportFile(const std::string &file, const std::string &directory="")
used to load an object file if directory is provided then file is assumed relative to directory if re...
Definition: maploader.cpp:832
void setXShift(const double &xshift)
Set the cellgrid x shift.
Definition: cellgrid.h:137
void setRotation(double rotation)
Sets rotation for the camera.
Definition: camera.cpp:149
MapLoader * createDefaultMapLoader(Model *model, VFS *vfs, ImageManager *imageManager, RenderBackend *renderBackend)
convenience function for creating the default fife map loader deleting the object returned from this ...
Definition: maploader.cpp:884
Camera describes properties of a view port shown in the main screen Main screen can have multiple cam...
Definition: camera.h:58
void setYScale(const double scale)
Set the cellgrid y-scaling.
Definition: cellgrid.h:184
void setObjectLoader(const FIFE::ObjectLoaderPtr &objectLoader)
Definition: maploader.cpp:766
virtual void load(const std::string &filename)=0
responsible for loading the object resource and populating the engine
void setXScale(const double scale)
Set the cellgrid x-scaling.
Definition: cellgrid.h:176
TriggerController * getTriggerController() const
Definition: map.h:225
#define FL_ERR(logger, msg)
Definition: logger.h:73
void setPathingStrategy(PathingStrategy strategy)
Sets pathing strategy for the layer.
Definition: layer.cpp:506
PercentDoneCallback m_percentDoneListener
Definition: maploader.h:112
virtual bool isLoadable(const std::string &filename)=0
determines whether the resource is in the correct format for this loader
bool HasParentPath(const bfs::path &path)
Helper function to determine if a path object has a parent path.
void setMultiPart(bool part)
Sets the object as a part of a multi object.
Definition: object.cpp:403
std::vector< int32_t > IntVector
Definition: stringutils.h:32
bfs::path GetParentPath(const bfs::path &path)
Helper function to retrieve a parent path object from a path object.
void setYShift(const double yshift)
Set the cellgrid y shift.
Definition: cellgrid.h:150
virtual bool isLoadable(const std::string &filename) const =0
determines whether the resource is in the correct format for this loader
Cell * getCell(const ModelCoordinate &mc)
Returns cell on this coordinate.
Definition: cellcache.cpp:706
Point3D ModelCoordinate
Definition: modelcoords.h:37
uint8_t CellTypeInfo
Definition: cell.h:65
ObjectLoaderPtr m_objectLoader
Definition: maploader.h:109
virtual AtlasPtr load(const std::string &filename)=0
responsible for loading the atlas returns a shared pointer to an image resource
uint8_t VisitorShapeInfo
Definition: instance.h:95
void getStaticImageAngles(std::vector< int32_t > &angles)
Returns list of available static image angles for this object.
Definition: visual.cpp:163
uint32_t getScreenWidth() const
Instance * getInstance(const std::string &identifier)
Get the first instance on this layer with the given identifier.
Definition: layer.cpp:241
A basic layer on a map.
Definition: layer.h:99
const std::string & getLoaderName() const
returns the loader name associated with this map file loader, this will only be populated after the l...
Definition: maploader.cpp:879
Layer * createLayer(const std::string &identifier, CellGrid *grid)
Add a Layer to this Map.
Definition: map.cpp:86
ImageManager * m_imageManager
Definition: maploader.h:108
void assign(Layer *layer, const ModelCoordinate &pt)
Assigns trigger on given layer and position.
Definition: trigger.cpp:242
SortingStrategy
Definition: layer.h:63
A model is a facade for everything in the model.
Definition: model.h:53
RenderBackend * m_renderBackend
Definition: maploader.h:111
A basic cell on a CellCache.
Definition: cell.h:136
uint8_t CellVisualEffect
Definition: cell.h:78
void setInteract(bool interact, const std::string &id)
Sets interact for the layer.
Definition: layer.cpp:531
void setDefaultSpeedMultiplier(double multi)
Sets default speed for this CellCache.
Definition: cellcache.cpp:1152
void setCellStackPosition(uint8_t stack)
Sets the cell stack position.
Definition: instance.cpp:555
void setWalkable(bool walkable)
Sets walkable for the layer.
Definition: layer.cpp:523
Object visual contains data that is needed for visualizing objects.
Definition: visual.h:91
std::string readString(size_t len)
read a string with len bytes, not assuming a terminating 0 Appends a null terminator character to the...
Definition: rawdata.cpp:128
DoublePoint3D ExactModelCoordinate
Definition: modelcoords.h:36
virtual void setAnimationLoader(const AnimationLoaderPtr &animationLoader)=0
allows setting which animation loader will be used to load animation files
CellGrid * getCellGrid(const std::string &gridtype)
Returns new copy of cellgrid corresponding given name.
Definition: model.cpp:96
void setFoWType(CellVisualEffect type)
Sets the cell visual.
Definition: cell.cpp:398
void addCellToArea(const std::string &id, Cell *cell)
Adds a cell to a specific area group.
Definition: cellcache.cpp:1396
IntVector tokenize(const std::string &str, char delim, char group)
Definition: stringutils.cpp:38
void setCostMultiplier(double multi)
Changes the cell cost.
Definition: cell.cpp:438
std::string m_mapDirectory
Definition: maploader.h:115
A 3D Point.
Definition: point.h:202
PathingStrategy
Defines how pathing can be performed on this layer.
Definition: layer.h:58
the main VFS (virtual file system) class
Definition: vfs.h:58
void setStackPosition(int32_t stackposition)
Sets stack position of the instance Stack position is used to define the order in which instances res...
Definition: visual.cpp:214
Trigger * createTrigger(const std::string &triggerName)
Creates a trigger.
void actRepeat(const std::string &actionName, const Location &direction)
Performs given named action to the instance, repeated.
Definition: instance.cpp:596
Trigger get triggered when a specific set of criteria are met.
Definition: trigger.h:83
Model * m_model
Definition: maploader.h:106
void finalizeCellCaches()
Creates cellcaches for this map.
Definition: map.cpp:350
void setRotation(const double rotation)
Set the cellgrid rotation.
Definition: cellgrid.h:215
void createTransition(Layer *layer, const ModelCoordinate &mc, bool immediate=false)
Creates a transistion from this cell to the given layer and coordinates.
Definition: cell.cpp:544
void setRotation(int32_t rotation)
Set the rotation offset of this instance.
Definition: instance.cpp:319
Cell * createCell(const ModelCoordinate &mc)
Creates cell on this CellCache.
Definition: cellcache.cpp:697
void addNarrowCell(Cell *cell)
Adds cell to narrow cells.
Definition: cellcache.cpp:1361
Object * getObject(const std::string &id, const std::string &name_space)
Get an object by its id.
Definition: model.cpp:233
AtlasLoaderPtr m_atlasLoader
Definition: maploader.h:110
void loadImportDirectory(const std::string &directory)
used to load a directory of object files recursively if relativeToMap is true then the directory is a...
Definition: maploader.cpp:847
Action * getAction(const std::string &identifier, bool deepsearch=true) const
Gets action with given id.
Definition: object.cpp:121
void setTotalNumberOfElements(unsigned int totalElements)
void enableForAllInstances()
Enables trigger for all instances.
Definition: trigger.cpp:230
void initializeCellCaches()
Creates cellcaches for this map.
Definition: map.cpp:326
void addListener(PercentDoneListener *listener)
This class serves as a central place to manage triggers for a Map.
void setCellImageDimensions(uint32_t width, uint32_t height)
Sets screen cell image dimensions.
Definition: camera.cpp:212
A container of Layer(s).
Definition: map.h:88
static InstanceRenderer * getInstance(IRendererContainer *cnt)
Gets instance for interface access.
An Instance is an "instantiation" of an Object at a Location.
Definition: instance.h:100
std::list< Object * > getObjects(const std::string &name_space) const
Get all the objects in the given namespace.
Definition: model.cpp:243
bool isLoadable(const std::string &filename) const
Definition: maploader.cpp:785
void setFilename(const std::string &file)
Definition: map.h:201
void setTriggered()
Sets the trigger to triggered and calls ITriggerListener->onTriggered()
Definition: trigger.cpp:179
Map * createMap(const std::string &identifier)
Add a map this model, and get a pointer to it.
Definition: model.cpp:64
void setCost(const std::string &id, double cost)
Sets for the given cost id a cost.
Definition: instance.cpp:1016
Used to access diffrent kinds of data.
Definition: rawdata.h:48
void setZoom(double zoom)
Sets zoom for the camera.
Definition: camera.cpp:161
std::set< std::string > listDirectories(const std::string &path) const
Get a directorylist of the given directory.
Definition: vfs.cpp:198
void setVisitor(bool visit)
Marks this instance as a visitor.
Definition: instance.cpp:531
void setVisitorShape(VisitorShapeInfo info)
Sets the shape type for a visitor.
Definition: instance.cpp:539