FIFE  be64c707dea6b3250bd4355bf5c825d25920087d
maploader.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2019 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 
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 
367  if (objectId) {
368  if (namespaceId) {
369  ns = *namespaceId;
370  }
371 
372  Object* object = m_model->getObject(*objectId, ns);
373 
374  if (object) {
375  Instance* inst = NULL;
376  if (instanceId) {
377  inst = layer->createInstance(object, ExactModelCoordinate(x,y,z), *instanceId);
378  }
379  else {
380  inst = layer->createInstance(object, ExactModelCoordinate(x,y,z));
381  }
382 
383  if (inst) {
384  if (rRetVal != TIXML_SUCCESS) {
385  ObjectVisual* objVisual = object->getVisual<ObjectVisual>();
386  std::vector<int> angles;
387  objVisual->getStaticImageAngles(angles);
388  if (!angles.empty()) {
389  r = angles[0];
390  }
391  }
392 
393  inst->setRotation(r);
394 
395  InstanceVisual* instVisual = InstanceVisual::create(inst);
396 
397  if (instVisual && (stackRetVal == TIXML_SUCCESS)) {
398  instVisual->setStackPosition(stackpos);
399  }
400 
401  if (cellStackRetVal == TIXML_SUCCESS) {
402  inst->setCellStackPosition(cellStack);
403  }
404 
405  if (costId) {
406  double cost = 0;
407  int costRetVal = instance->QueryValueAttribute("cost", &cost);
408  if (costRetVal == TIXML_SUCCESS) {
409  inst->setCost(*costId, cost);
410  }
411  }
412 
413  if (object->getAction("default")) {
414  Location target(layer);
415 
416  inst->actRepeat("default", target);
417  }
418  }
419  else
420  {
421  std::ostringstream oss;
422  oss << " Failed to create instance of object "
423  << *objectId
424  << " : " << __FILE__
425  << " [" << __LINE__ << "]"
426  << std::endl;
427  FL_ERR(_log, oss.str());
428  }
429  }
430  }
431 
432  // increment % done counter
434  }
435  }
436  }
437  }
438  }
439 
440  // increment % done counter
442  }
443 
444  // init CellCaches
445  map->initializeCellCaches();
446  // add Cells from xml File
447  for (const TiXmlElement* cacheElements = root->FirstChildElement("cellcaches"); cacheElements; cacheElements = cacheElements->NextSiblingElement("cellcaches")) {
448  for (const TiXmlElement* cacheElement = cacheElements->FirstChildElement("cellcache"); cacheElement; cacheElement = cacheElement->NextSiblingElement("cellcache")) {
449  double cacheCost = 1.0;
450  double cacheSpeed = 1.0;
451  const std::string* layerId = cacheElement->Attribute(std::string("id"));
452 
453  if (layerId) {
454  cacheElement->QueryDoubleAttribute("default_cost", &cacheCost);
455  cacheElement->QueryDoubleAttribute("default_speed", &cacheSpeed);
456 
457  Layer* layer = map->getLayer(*layerId);
458  if (layer) {
459  CellCache* cache = layer->getCellCache();
460  if (cache) {
461  int searchNarrow = 0;
462  cacheElement->QueryIntAttribute("search_narrow", &searchNarrow);
463  cache->setSearchNarrowCells(searchNarrow != 0);
464 
465  cache->setDefaultCostMultiplier(cacheCost);
466  cache->setDefaultSpeedMultiplier(cacheSpeed);
467  for (const TiXmlElement* cellElement = cacheElement->FirstChildElement("cell"); cellElement; cellElement = cellElement->NextSiblingElement("cell")) {
468  int cellX = 0;
469  int cellY = 0;
470  int success = cellElement->QueryIntAttribute("x", &cellX);
471  success &= cellElement->QueryIntAttribute("y", &cellY);
472  if (success == TIXML_SUCCESS) {
473  ModelCoordinate mc(cellX, cellY);
474  Cell* cell = cache->createCell(mc);
475 
476  const std::string* cellBlocker = cellElement->Attribute(std::string("blocker_type"));
477  if (cellBlocker) {
478  if (*cellBlocker == "no_blocker") {
480  cell->setCellType(cti);
481  } else if (*cellBlocker == "blocker") {
483  cell->setCellType(cti);
484  }
485  }
486 
487  double cellCost = 1.0;
488  double cellSpeed = 1.0;
489  success = cellElement->QueryDoubleAttribute("default_cost", &cellCost);
490  if (success == TIXML_SUCCESS) {
491  cell->setCostMultiplier(cellCost);
492  }
493  success = cellElement->QueryDoubleAttribute("default_speed", &cellSpeed);
494  if (success == TIXML_SUCCESS) {
495  cell->setSpeedMultiplier(cellSpeed);
496 
497  }
498 
499  int isNarrow = 0;
500  cellElement->QueryIntAttribute("narrow", &isNarrow);
501  if (isNarrow != 0) {
502  cache->addNarrowCell(cell);
503  }
504  // add cost with given id to cell
505  for (const TiXmlElement* costElement = cellElement->FirstChildElement("cost"); costElement; costElement = costElement->NextSiblingElement("cost")) {
506  const std::string* costId = costElement->Attribute(std::string("id"));
507  double cost = 1.0;
508  success = costElement->QueryDoubleAttribute("value", &cost);
509  if (costId && success == TIXML_SUCCESS) {
510  cache->registerCost(*costId, cost);
511  cache->addCellToCost(*costId, cell);
512  }
513  }
514  // add area to cell
515  for (const TiXmlElement* areaElement = cellElement->FirstChildElement("area"); areaElement; areaElement = areaElement->NextSiblingElement("area")) {
516  const std::string* areaId = areaElement->Attribute(std::string("id"));
517  if (areaId) {
518  cache->addCellToArea(*areaId, cell);
519  }
520  }
521  }
522  }
523  }
524  }
525  }
526  }
527  }
528  // finalize CellCaches
529  map->finalizeCellCaches();
530  // add Transistions
531  for (const TiXmlElement* cacheElements = root->FirstChildElement("cellcaches"); cacheElements; cacheElements = cacheElements->NextSiblingElement("cellcaches")) {
532  for (const TiXmlElement* cacheElement = cacheElements->FirstChildElement("cellcache"); cacheElement; cacheElement = cacheElement->NextSiblingElement("cellcache")) {
533  const std::string* layerId = cacheElement->Attribute(std::string("id"));
534  if (layerId) {
535  Layer* layer = map->getLayer(*layerId);
536  if (layer) {
537  CellCache* cache = layer->getCellCache();
538  if (cache) {
539  for (const TiXmlElement* cellElement = cacheElement->FirstChildElement("cell"); cellElement; cellElement = cellElement->NextSiblingElement("cell")) {
540  int cellX = 0;
541  int cellY = 0;
542  int success = cellElement->QueryIntAttribute("x", &cellX);
543  success &= cellElement->QueryIntAttribute("y", &cellY);
544  if (success == TIXML_SUCCESS) {
545  ModelCoordinate mc(cellX, cellY);
546  Cell* cell = cache->getCell(mc);
547  if (!cell) {
548  continue;
549  }
550  for (const TiXmlElement* transitionElement = cellElement->FirstChildElement("transition"); transitionElement; transitionElement = transitionElement->NextSiblingElement("transition")) {
551  int targetX = 0;
552  int targetY = 0;
553  int targetZ = 0;
554  success = transitionElement->QueryIntAttribute("x", &targetX);
555  success &= transitionElement->QueryIntAttribute("y", &targetY);
556  transitionElement->QueryIntAttribute("z", &targetZ);
557  if (success == TIXML_SUCCESS) {
558  ModelCoordinate mc(targetX, targetY, targetZ);
559  Layer* targetLayer = NULL;
560  const std::string* targetLayerId = transitionElement->Attribute(std::string("id"));
561  if (targetLayerId) {
562  targetLayer = map->getLayer(*targetLayerId);
563  }
564  if (!targetLayer) {
565  targetLayer = layer;
566  }
567 
568  int immediate = 0;
569  transitionElement->QueryIntAttribute("immediate", &immediate);
570  cell->createTransition(targetLayer, mc, immediate != 0);
571  }
572  }
573  }
574  }
575  }
576  }
577  }
578  }
579  }
580 
581  for (const TiXmlElement* triggerElements = root->FirstChildElement("triggers"); triggerElements; triggerElements = triggerElements->NextSiblingElement("triggers")) {
582  TriggerController* triggerController = map->getTriggerController();
583  for (const TiXmlElement* triggerElement = triggerElements->FirstChildElement("trigger"); triggerElement; triggerElement = triggerElement->NextSiblingElement("trigger")) {
584  const std::string* triggerName = triggerElement->Attribute(std::string("name"));
585  int triggered = 0;
586  int allInstances = 0;
587  triggerElement->QueryIntAttribute("triggered", &triggered);
588  triggerElement->QueryIntAttribute("all_instances", &allInstances);
589 
590  Trigger* trigger = triggerController->createTrigger(*triggerName);
591  if (triggered > 0) {
592  trigger->setTriggered();
593  }
594  if (allInstances > 0) {
595  trigger->enableForAllInstances();
596  }
597 
598  const std::string* instanceId = triggerElement->Attribute(std::string("attached_instance"));
599  const std::string* layerId = triggerElement->Attribute(std::string("attached_layer"));
600  if (instanceId && layerId) {
601  Layer* layer = map->getLayer(*layerId);
602  if (layer) {
603  Instance* instance = layer->getInstance(*instanceId);
604  if (instance) {
605  trigger->attach(instance);
606  }
607  }
608  }
609  for (const TiXmlElement* assignElement = triggerElement->FirstChildElement("assign"); assignElement; assignElement = assignElement->NextSiblingElement("assign")) {
610  layerId = assignElement->Attribute(std::string("layer_id"));
611  if (!layerId) {
612  continue;
613  }
614  int x = 0;
615  int y = 0;
616  assignElement->QueryIntAttribute("x", &x);
617  assignElement->QueryIntAttribute("y", &y);
618  Layer* layer = map->getLayer(*layerId);
619  if (layer) {
620  trigger->assign(layer, ModelCoordinate(x, y));
621  }
622  }
623  for (const TiXmlElement* enabledElement = triggerElement->FirstChildElement("enabled"); enabledElement; enabledElement = enabledElement->NextSiblingElement("enabled")) {
624  layerId = enabledElement->Attribute(std::string("layer_id"));
625  instanceId = enabledElement->Attribute(std::string("instance_id"));
626  if (!instanceId || !layerId) {
627  continue;
628  }
629  Layer* layer = map->getLayer(*layerId);
630  if (layer) {
631  Instance* instance = layer->getInstance(*instanceId);
632  if (instance) {
633  trigger->enableForInstance(instance);
634  }
635  }
636  }
637  for (const TiXmlElement* conditionElement = triggerElement->FirstChildElement("condition"); conditionElement; conditionElement = conditionElement->NextSiblingElement("condition")) {
638  int conditionId = -1;
639  conditionElement->QueryIntAttribute("id", &conditionId);
640  if (conditionId != -1) {
641  trigger->addTriggerCondition(static_cast<TriggerCondition>(conditionId));
642  }
643  }
644  }
645  }
646 
647 
648  for (const TiXmlElement* cameraElement = root->FirstChildElement("camera"); cameraElement; cameraElement = cameraElement->NextSiblingElement("camera")) {
649  const std::string* cameraId = cameraElement->Attribute(std::string("id"));
650 
651  int refCellWidth = 0;
652  int refCellHeight = 0;
653  int success = cameraElement->QueryIntAttribute("ref_cell_width", &refCellWidth);
654  success &= cameraElement->QueryIntAttribute("ref_cell_height", &refCellHeight);
655 
656  if (cameraId && success == TIXML_SUCCESS) {
657  double tilt = 0.0;
658  double zoom = 1.0;
659  double rotation = 0.0;
660  double zToY = 0.0;
661  cameraElement->QueryDoubleAttribute("tilt", &tilt);
662  cameraElement->QueryDoubleAttribute("zoom", &zoom);
663  cameraElement->QueryDoubleAttribute("rotation", &rotation);
664  success = cameraElement->QueryDoubleAttribute("ztoy", &zToY);
665 
666  const std::string* viewport = cameraElement->Attribute(std::string("viewport"));
667 
668  Camera* cam = NULL;
669 
670  if (viewport) {
671  // parse out the viewport parameters
672  IntVector viewportParameters = tokenize(*viewport, ',');
673 
674  // make sure the right number of viewport parameters were parsed
675  if (viewportParameters.size() == 4) {
676  Rect rect(viewportParameters[0], viewportParameters[1],
677  viewportParameters[2], viewportParameters[3]);
678 
679  try {
680  cam = map->addCamera(*cameraId, rect);
681  }
682  catch (NameClash&) {
683  // TODO - handle exception
684  assert(false);
685  }
686  }
687  } else {
689 
690  try {
691  cam = map->addCamera(*cameraId, rect);
692  }
693  catch (NameClash&) {
694  // TODO - handle exception
695  assert(false);
696  }
697  }
698 
699 
700  if (cam) {
701  cam->setCellImageDimensions(refCellWidth, refCellHeight);
702  cam->setRotation(rotation);
703  cam->setTilt(tilt);
704  cam->setZoom(zoom);
705  if (success == TIXML_SUCCESS) {
706  cam->setZToY(zToY);
707  }
708 
709  // active instance renderer for camera
710  InstanceRenderer* instanceRenderer = InstanceRenderer::getInstance(cam);
711  if (instanceRenderer)
712  {
713  instanceRenderer->activateAllLayers(map);
714  }
715  }
716  }
717 
718  // increment % done counter
720  }
721  }
722  }
723  }
724 
725  return map;
726  }
727 
729  assert(objectLoader);
730 
731  m_objectLoader = objectLoader;
732  }
733 
735  return m_objectLoader;
736  }
737 
739  assert(animationLoader);
740 
741  m_objectLoader->setAnimationLoader(animationLoader);
742  }
743 
745  if (m_objectLoader) {
747  }
748  return FIFE::AnimationLoaderPtr();
749  }
750 
752  assert(atlasLoader);
753 
754  m_objectLoader->setAtlasLoader(atlasLoader);
755  }
756 
758  if (m_objectLoader) {
759  return m_objectLoader->getAtlasLoader();
760  }
761  return FIFE::AtlasLoaderPtr();
762  }
763 
764  bool MapLoader::isLoadable(const std::string& filename) const {
765  bfs::path mapPath(filename);
766 
767  TiXmlDocument mapFile;
768 
769  std::string mapFilename = mapPath.string();
770 
771  try {
772  RawData* data = m_vfs->open(mapFilename);
773 
774  if (data) {
775  if (data->getDataLength() != 0) {
776  mapFile.Parse(data->readString(data->getDataLength()).c_str());
777 
778  if (mapFile.Error()) {
779  return false;
780  }
781 
782  const TiXmlElement* root = mapFile.RootElement();
783 
784  if (root) {
785  const std::string* loaderName = root->Attribute(std::string("loader"));
786 
787  // if the file does not specify a loader but was opened and parsed
788  // correctly then we know we have a compatible extension so we will
789  // attempt to load it, if it does specify a loader then the loader
790  // name will be checked
791  if (!loaderName || (loaderName && *loaderName == getLoaderName())) {
792  return true;
793  }
794  }
795  }
796 
797  // done with file delete the resource
798  delete data;
799  data = 0;
800  }
801  }
802  catch (NotFound& e) {
803  FL_ERR(_log, e.what());
804 
805  return false;
806  }
807 
808  return false;
809  }
810 
811  void MapLoader::loadImportFile(const std::string& file, const std::string& directory) {
812  if (!file.empty()) {
813  bfs::path importFilePath(directory);
814  importFilePath /= file;
815 
816  std::string importFileString = importFilePath.string();
818  m_objectLoader->getAtlasLoader()->loadMultiple(importFileString);
819  }
821  m_objectLoader->getAnimationLoader()->loadMultiple(importFileString);
822  }
823  if (m_objectLoader && m_objectLoader->isLoadable(importFileString)) {
824  m_objectLoader->load(importFileString);
825  }
826  }
827  }
828 
829  void MapLoader::loadImportDirectory(const std::string& directory) {
830  if (!directory.empty()) {
831  bfs::path importDirectory(directory);
832  std::string importDirectoryString = importDirectory.string();
833 
834  std::set<std::string> files = m_vfs->listFiles(importDirectoryString);
835 
836  // load all xml files in the directory
837  std::set<std::string>::iterator iter;
838  for (iter = files.begin(); iter != files.end(); ++iter) {
839  // TODO - vtchill - may need a way to allow clients to load things other
840  // than .xml and .zip files
841  std::string ext = bfs::extension(*iter);
842  if (ext == ".xml" || ext == ".zip") {
843  loadImportFile(*iter, importDirectoryString);
844  }
845  }
846 
847  std::set<std::string> nestedDirectories = m_vfs->listDirectories(importDirectoryString);
848  for (iter = nestedDirectories.begin(); iter != nestedDirectories.end(); ++iter) {
849  // do not attempt to load anything from a .svn directory
850  if ((*iter).find(".svn") == std::string::npos) {
851  loadImportDirectory(importDirectoryString + "/" + *iter);
852  }
853  }
854  }
855  }
856 
859  }
860 
861  const std::string& MapLoader::getLoaderName() const {
862  return m_loaderName;
863 
864  }
865 
866  MapLoader* createDefaultMapLoader(Model* model, VFS* vfs, ImageManager* imageManager, RenderBackend* renderBackend) {
867  return (new MapLoader(model, vfs, imageManager, renderBackend));
868  }
869 }
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:207
Action * getAction(const std::string &identifier, bool deepsearch=true) const
Gets action with given id.
Definition: object.cpp:121
void addPercentDoneListener(PercentDoneListener *listener)
allows adding a listener to the map loader for percent completed events
Definition: maploader.cpp:857
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
std::list< Object * > getObjects(const std::string &name_space) const
Get all the objects in the given namespace.
Definition: model.cpp:290
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:1401
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:738
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:151
void setDefaultCostMultiplier(double multi)
Sets default cost for this CellCache.
Definition: cellcache.cpp:1153
void setSpeedMultiplier(double multi)
Changes the cell speed.
Definition: cell.cpp:249
void addCellToCost(const std::string &costId, Cell *cell)
Assigns a cell to a cost identifier.
Definition: cellcache.cpp:1030
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:294
std::string m_loaderName
Definition: maploader.h:130
void setAtlasLoader(const FIFE::AtlasLoaderPtr &atlasLoader)
Definition: maploader.cpp:751
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
bool isLoadable(const std::string &filename) const
Definition: maploader.cpp:764
static Logger _log(LM_AUDIO)
void registerCost(const std::string &costId, double cost)
Adds a cost with the given id and value.
Definition: cellcache.cpp:983
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:811
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:164
uint32_t getScreenWidth() const
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:866
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
uint32_t getScreenHeight() const
void setObjectLoader(const FIFE::ObjectLoaderPtr &objectLoader)
Definition: maploader.cpp:728
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 ...
std::set< std::string > listFiles(const std::string &path) const
Get a filelist of the given directory.
Definition: vfs.cpp:182
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
#define FL_ERR(logger, msg)
Definition: logger.h:73
uint32_t getDataLength() const
get the complete datalength
Definition: rawdata.cpp:75
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:704
Point3D ModelCoordinate
Definition: modelcoords.h:38
uint8_t CellTypeInfo
Definition: cell.h:65
ObjectLoaderPtr m_objectLoader
Definition: maploader.h:126
void getStaticImageAngles(std::vector< int32_t > &angles)
Returns list of available static image angles for this object.
Definition: visual.cpp:163
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
Layer * createLayer(const std::string &identifier, CellGrid *grid)
Add a Layer to this Map.
Definition: map.cpp:86
FIFE::AnimationLoaderPtr getAnimationLoader()
Definition: maploader.cpp:744
virtual AnimationLoaderPtr getAnimationLoader()=0
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:861
ImageManager * m_imageManager
Definition: maploader.h:124
FIFE::ObjectLoaderPtr getObjectLoader()
Definition: maploader.cpp:734
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:123
void setInteract(bool interact, const std::string &id)
Sets interact for the layer.
Definition: layer.cpp:531
std::list< std::string > getNamespaces() const
Get a list of namespaces currently referenced by objects in the metamodel.
Definition: model.cpp:196
void setDefaultSpeedMultiplier(double multi)
Sets default speed for this CellCache.
Definition: cellcache.cpp:1161
void setCellStackPosition(uint8_t stack)
Sets the cell stack position.
Definition: instance.cpp:541
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
std::set< std::string > listDirectories(const std::string &path) const
Get a directorylist of the given directory.
Definition: vfs.cpp:198
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 addCellToArea(const std::string &id, Cell *cell)
Adds a cell to a specific area group.
Definition: cellcache.cpp:1405
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:233
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.
Camera * addCamera(const std::string &id, const Rect &viewport)
Adds camera to the map.
Definition: map.cpp:245
void actRepeat(const std::string &actionName, const Location &direction)
Performs given named action to the instance, repeated.
Definition: instance.cpp:582
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:346
FIFE::AtlasLoaderPtr getAtlasLoader()
Definition: maploader.cpp:757
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:339
void setRotation(int32_t rotation)
Set the rotation offset of this instance.
Definition: instance.cpp:319
virtual AtlasLoaderPtr getAtlasLoader()=0
Cell * createCell(const ModelCoordinate &mc)
Creates cell on this CellCache.
Definition: cellcache.cpp:695
void addNarrowCell(Cell *cell)
Adds cell to narrow cells.
Definition: cellcache.cpp:1370
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:829
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:322
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:228
A container of Layer(s).
Definition: map.h:88
static InstanceRenderer * getInstance(IRendererContainer *cnt)
Gets instance for interface access.
TriggerController * getTriggerController() const
Definition: map.h:220
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:94
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:1007
Used to access diffrent kinds of data.
Definition: rawdata.h:48
void setZoom(double zoom)
Sets zoom for the camera.
Definition: camera.cpp:177