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