Ejemplo n.º 1
0
//===========================================
// Sprite::assignData
//
// All tags and attributes are optional.
//===========================================
void Sprite::assignData(const XmlNode data) {
   if (data.isNull() || data.name() != "Sprite") return;

   try {
      XmlNode node = data.firstChild();

      if (!node.isNull() && node.name() == "Entity") {
         Entity::assignData(node);
         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "EntityAnimations") {
         EntityAnimations::assignData(node);
         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "EntityTransformations") {
         EntityTransformations::assignData(node);
      }
   }
   catch (XmlException& e) {
      e.prepend("Error parsing XML for instance of class Sprite; ");
      throw;
   }
}
Ejemplo n.º 2
0
      //===========================================
      // PhysicalSprite::assignData
      //===========================================
      virtual void assignData(const XmlNode data) {
         if (data.isNull() || data.name() != "PhysicalSprite") return;

         XmlNode node = data.firstChild();

         if (!node.isNull() && node.name() == "Sprite") {
            Sprite::assignData(node);
            node = node.nextSibling();
         }

         if (!node.isNull() && node.name() == "EntityPhysics") {
            T_PHYSICS::assignData(data.nthChild(1));
         }
      }
Ejemplo n.º 3
0
//===========================================
// EntityParallax::assignData
//===========================================
void EntityParallax::assignData(const XmlNode data) {
    try {
        if (data.isNull() || data.name() != "EntityParallax") return;

        XmlNode node = data.firstChild();
        if (!node.isNull() && node.name() == "range") {
            m_range = Vec2f(node.firstChild());
        }
    }
    catch (XmlException& e) {
        e.prepend("Error parsing XML for instance of class EntityParallax; ");
        throw;
    }

    init();
}
Ejemplo n.º 4
0
//===========================================
// Polygon::Polygon
//===========================================
Polygon::Polygon(const XmlNode data)
   : Asset(internString("Polygon")),
     m_outlineModel(Renderer::LINES),
     m_interiorModel(Renderer::TRIANGLES),
     m_renderer(Renderer::getInstance()) {

   try {
      XML_NODE_CHECK(data, Polygon);

      clear();

      XmlNode node = data.firstChild();
      while (!node.isNull() && node.name() == "Vec2f") {
         boost::shared_ptr<Vec2f> vert(new Vec2f(node));
         m_verts.push_back(vert);

         ++m_nVerts;
         node = node.nextSibling();
      }
   }
   catch (XmlException& e) {
      e.prepend("Error parsing XML for instance of class Polygon; ");
      throw;
   }

   restructure();
   updateModels();
}
Ejemplo n.º 5
0
//===========================================
// Box2dPhysics::assignData
//===========================================
void Box2dPhysics::assignData(const XmlNode data) {
   if (data.isNull() || data.name() != "Box2dPhysics") return;

   try {
      XmlAttribute attr = data.firstAttribute();
      if (!attr.isNull() && attr.name() == "dynamic") {
         m_opts.dynamic = attr.getBool();
         attr = attr.nextAttribute();
      }

      if (!attr.isNull() && attr.name() == "fixedAngle") {
         m_opts.fixedAngle = attr.getBool();
         attr = attr.nextAttribute();
      }

      if (!attr.isNull() && attr.name() == "density") {
         m_opts.density = attr.getFloat();
         attr = attr.nextAttribute();
      }

      if (!attr.isNull() && attr.name() == "friction") {
         m_opts.friction = attr.getFloat();
      }
   }
   catch (XmlException& e) {
      e.prepend("Error parsing XML for instance of class Box2dPhysics ;");
      throw;
   }
}
Ejemplo n.º 6
0
	void CreateGameScreen::AddGameModes(XmlNode* mapNode)
	{
		string defMode = XmlUtility::XmlGetString(mapNode->first_node("DefaultMode"), "name");
		_currentMode = 0;
		_availableModes.clear();
		_comboGameMode->removeAllItems();

		XmlNode* modesListNode = mapNode->first_node("Modes");
		int modeNum = 0;
		XmlNode* modeNode = modesListNode->first_node();
		while(modeNode != 0)
		{
			Mode mode;
			mode.Name = modeNode->name();
			mode.Display = XmlUtility::XmlGetStringIfExists(modeNode, "display", mode.Name.c_str());
			mode.IsCustomisable = XmlUtility::XmlGetBoolIfExists(modeNode, "customisable", true);
			_availableModes.push_back(mode);
			_comboGameMode->addItem(mode.Display, modeNum);

			// Additionaly find default mode index
			if(mode.Name.compare(defMode) == 0)
			{
				_currentMode = modeNum;
				_comboGameMode->setIndexSelected(modeNum);
			}

			++modeNum;
			modeNode = modeNode->next_sibling();
		}
	}
Ejemplo n.º 7
0
//===========================================
// Animation::Animation
//===========================================
Animation::Animation(const XmlNode data)
   : Asset(internString("Animation")),
     m_state(STOPPED),
     m_frameReady(false) {

   try {
      XML_NODE_CHECK(data, Animation);

      XmlAttribute attr = data.firstAttribute();
      XML_ATTR_CHECK(attr, name);
      m_name = internString(attr.getString());

      attr = attr.nextAttribute();
      XML_ATTR_CHECK(attr, duration);
      m_duration = attr.getFloat();

      uint_t f = 0;
      XmlNode node = data.firstChild();
      while (!node.isNull() && node.name() == "AnimFrame") {
         AnimFrame frame(node);
         frame.number = f;

         m_frames.push_back(frame);

         ++f;
         node = node.nextSibling();
      }
   }
   catch (XmlException& e) {
      e.prepend("Error parsing XML for instance of class Animation; ");
      throw;
   }
}
Ejemplo n.º 8
0
void XmlParser::readModel(Transform * transform, XmlNode * modelNode) {
    // Create model
    glm::mat4 model;

    if (modelNode) {
        // Get each transformation
        XmlNode * transformNode = modelNode->first_node();

        while (transformNode) {
            std::string type(transformNode->name());

            // Translate
            if (type == "translate") {
                XmlAttr * x, * y, * z;
                xmlAttribute(x, transformNode);
                xmlAttribute(y, transformNode);
                xmlAttribute(z, transformNode);

                // Apply transformation
                transform->translate(atof(x->value()), atof(y->value()), atof(z->value()));
            }
            // Rotate
            else if (type == "rotate") {
                // Read angle
                XmlAttr * angle;
                xmlAttribute(angle, transformNode);

                // Check normal
                glm::vec3 normal(0, 1, 0);
                XmlNode * normalNode = transformNode->first_node("normal");
                if (normalNode) {
                    XmlAttr * x, * y, * z;
                    xmlAttribute(x, normalNode);
                    xmlAttribute(y, normalNode);
                    xmlAttribute(z, normalNode);

                    // Set new normal
                    normal = glm::vec3(atof(x->value()), atof(y->value()), atof(z->value()));
                }

                // Apply transformation
                transform->rotate(atof(angle->value()), normal);
            }
            // Scale
            else if (type == "scale") {
                XmlAttr * x, * y, * z;
                xmlAttribute(x, transformNode);
                xmlAttribute(y, transformNode);
                xmlAttribute(z, transformNode);

                // Apply transformation
                transform->scale(atof(x->value()), atof(y->value()), atof(z->value()));
            }

            // Get next transformation
            transformNode = transformNode->next_sibling();
        }
    }
}
Ejemplo n.º 9
0
//===========================================
// GameSettings::parseGameModes
//===========================================
void GameSettings::parseGameModes(XmlNode data) {
   XmlNode node = data.firstChild();

   while (!node.isNull() && node.name() == "GameOptions") {
      difficultyModes.push_back(pGameOptions_t(new GameOptions(node)));
      node = node.nextSibling();
   }
}
Ejemplo n.º 10
0
//===========================================
// Counter::assignData
//===========================================
void Counter::assignData(const Dodge::XmlNode data) {
   try {
      XML_NODE_CHECK(data, Counter)

      XmlNode node = data.firstChild();
      if (!node.isNull() && node.name() == "CTextEntity") {
         CTextEntity::assignData(node);
         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "value") {
         m_value = node.getInt();
      }
   }
   catch (XmlException& e) {
      e.prepend("Error parsing XML for instance of class Counter; ");
      throw;
   }
}
Ejemplo n.º 11
0
//===========================================
// Throwable::assignData
//===========================================
void Throwable::assignData(const Dodge::XmlNode data) {
   try {
      XML_NODE_CHECK(data, Throwable)

      XmlNode node = data.firstChild();
      if (!node.isNull() && node.name() == "Item") {
         Item::assignData(node);
         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "Sprite") {
         Sprite::assignData(node);
      }
   }
   catch (XmlException& e) {
      e.prepend("Error parsing XML for instance of class Throwable; ");
      throw;
   }
}
Ejemplo n.º 12
0
//===========================================
// PauseMenu::assignData
//===========================================
void PauseMenu::assignData(const XmlNode data) {
   try {
      XML_NODE_CHECK(data, PauseMenu)

      XmlNode node = data.firstChild();
      if (!node.isNull() && node.name() == "Menu") {
         Menu::assignData(node);
      }
   }
   catch (XmlException& e) {
      e.prepend("Error parsing XML for instance of class PauseMenu; ");
      throw;
   }
}
Ejemplo n.º 13
0
//===========================================
// TextEntity::assignData
//===========================================
void TextEntity::assignData(const XmlNode data) {
   try {
      if (data.isNull() || data.name() != "TextEntity") return;

      XmlNode node = data.nthChild(1);
      if (!node.isNull() && node.name() == "font") {

         XmlAttribute attr = node.firstAttribute();
         if (!attr.isNull() && attr.name() == "ptr") {
            long fontId = attr.getLong();

            AssetManager assetManager;
            pFont_t font = boost::dynamic_pointer_cast<Dodge::Font>(assetManager.getAssetPointer(fontId));

            if (!font)
               throw XmlException("Bad asset id", __FILE__, __LINE__);

            m_font = font;
         }

         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "textSize") {
         m_size = Vec2f(node.firstChild());
         node = node.nextSibling();
      }

      XML_NODE_CHECK(node, text);
      setText(node.getString());
   }
   catch (XmlException& e) {
      e.prepend("Error parsing XML for instance of class TextEntity; ");
      throw;
   }
}
Ejemplo n.º 14
0
//===========================================
// Entity::Entity
//===========================================
Entity::Entity(const XmlNode data)
   : Asset(internString("Entity")),
     m_silent(false),
     m_parent(NULL) {

   AssetManager assetManager;
   ShapeFactory shapeFactory;

   try {
      setSilent(true);

      XML_NODE_CHECK(data, Entity);

      XmlAttribute attr = data.firstAttribute();
      XML_ATTR_CHECK(attr, type);
      m_type = internString(attr.getString());

      attr = attr.nextAttribute();
      XML_ATTR_CHECK(attr, name);
      m_name = internString(attr.getString());

      attr = attr.nextAttribute();
      XML_ATTR_CHECK(attr, x);
      m_transl.x = attr.getFloat();

      attr = attr.nextAttribute();
      XML_ATTR_CHECK(attr, y);
      m_transl.y = attr.getFloat();

      attr = attr.nextAttribute();
      XML_ATTR_CHECK(attr, z);
      m_z = attr.getFloat();

      // So that no Z values are 'exactly' equal
      m_z += 0.1f * static_cast<float32_t>(rand()) / static_cast<float32_t>(RAND_MAX);

      attr = attr.nextAttribute();
      XML_ATTR_CHECK(attr, rot);
      float32_t rot = attr.getFloat();

      XmlNode node = data.firstChild();
      if (!node.isNull() && node.name() == "shape") {
         m_shape = unique_ptr<Shape>(shapeFactory.create(node.firstChild()));
         node = node.nextSibling();
      }

      m_rot = 0;
      setRotation(rot);

      XML_NODE_CHECK(node, scale);
      m_scale = Vec2f(1.f, 1.f);
      setScale(Vec2f(node.firstChild()));

      node = node.nextSibling();
      XML_NODE_CHECK(node, fillColour);
      m_fillColour = Colour(node.firstChild());

      node = node.nextSibling();
      XML_NODE_CHECK(node, lineColour);
      m_lineColour = Colour(node.firstChild());

      node = node.nextSibling();
      XML_NODE_CHECK(node, lineWidth);
      m_lineWidth = node.getInt();

      node = node.nextSibling();
      XML_NODE_CHECK(node, children);
      XmlNode node_ = node.firstChild();
      while (!node_.isNull() && node_.name() == "child") {
         XmlAttribute attr = node_.firstAttribute();

         if (!attr.isNull() && attr.name() == "ptr") {
            long id = attr.getLong();

            pEntity_t child = boost::dynamic_pointer_cast<Entity>(assetManager.getAssetPointer(id));

            if (!child)
               throw XmlException("Bad entity asset id", __FILE__, __LINE__);

            addChild(child);
         }

         node_ = node_.nextSibling();
      }

      setSilent(false);

      ++m_count;
   }
   catch (XmlException& e) {
      e.prepend("Error parsing XML for instance of class Entity; ");
      throw;
   }

   recomputeBoundary();
}
Ejemplo n.º 15
0
bool Test::testCase1() const {
    bool pass = true;
    bool b = false;

    if (m_verbose) cout << "\tCASE 1: Parsing good document and checking tree\n";
    try {
        XmlDocument doc;
        doc.parse("./test1.xml");

        /*
        <?xml version="1.0" encoding="utf-8"?>
        <element1 a="1" b="2">
           <element2 c="3" d="true"/>
           <element3>Hello World!</element3>
           <element4 a="123">
              <element5 yes="no">
                 <element6 str="This is a string" num="4.5"/>
                 <element7>99.8</element7>
              </element5>
           </element4>
        </element1>
        */

        XmlNode node = doc.firstNode();
        node = node.nextSibling();

        SUBCASE_CHECK_CRITICAL(!node.isNull());
        SUBCASE_CHECK(node.name().compare("element1") == 0, pass, b);

        XmlAttribute attr = node.firstAttribute();
        SUBCASE_CHECK_CRITICAL(!attr.isNull());
        SUBCASE_CHECK(attr.name().compare("a") == 0, pass, b);
        SUBCASE_CHECK(attr.getInt() == 1, pass, b);

        attr = attr.nextAttribute();
        SUBCASE_CHECK_CRITICAL(!attr.isNull());
        SUBCASE_CHECK(attr.name().compare("b") == 0, pass, b);
        SUBCASE_CHECK(attr.getInt() == 2, pass, b);

        {
            XmlNode node_ = node.firstChild();
            SUBCASE_CHECK_CRITICAL(!node_.isNull());
            SUBCASE_CHECK(node_.name().compare("element2") == 0, pass, b);

            XmlAttribute attr = node_.firstAttribute();
            SUBCASE_CHECK_CRITICAL(!attr.isNull());
            SUBCASE_CHECK(attr.name().compare("c") == 0, pass, b);
            SUBCASE_CHECK(attr.getInt() == 3, pass, b);

            attr = attr.nextAttribute();
            SUBCASE_CHECK_CRITICAL(!attr.isNull());
            SUBCASE_CHECK(attr.name().compare("d") == 0, pass, b);
            SUBCASE_CHECK(attr.getString().compare("true") == 0, pass, b);

            node_ = node_.nextSibling();
            SUBCASE_CHECK_CRITICAL(!node_.isNull());
            SUBCASE_CHECK(node_.name().compare("element3") == 0, pass, b);
            SUBCASE_CHECK(node_.getString().compare("Hello World!") == 0, pass, b);

            node_ = node_.nextSibling();
            SUBCASE_CHECK_CRITICAL(!node_.isNull());
            SUBCASE_CHECK(node_.name().compare("element4") == 0, pass, b);

            attr = node_.firstAttribute();
            SUBCASE_CHECK_CRITICAL(!attr.isNull());
            SUBCASE_CHECK(attr.name().compare("a") == 0, pass, b);
            SUBCASE_CHECK(attr.getInt() == 123, pass, b);

            {
                XmlNode node__ = node_.firstChild();
                SUBCASE_CHECK_CRITICAL(!node__.isNull());
                SUBCASE_CHECK(node__.name().compare("element5") == 0, pass, b);

                XmlAttribute attr = node__.firstAttribute();
                SUBCASE_CHECK_CRITICAL(!attr.isNull());
                SUBCASE_CHECK(attr.name().compare("yes") == 0, pass, b);
                SUBCASE_CHECK(attr.getString().compare("no") == 0, pass, b);

                {
                    XmlNode node___ = node__.firstChild();
                    SUBCASE_CHECK_CRITICAL(!node___.isNull());
                    SUBCASE_CHECK(node___.name().compare("element6") == 0, pass, b);

                    XmlAttribute attr = node___.firstAttribute();
                    SUBCASE_CHECK_CRITICAL(!attr.isNull());
                    SUBCASE_CHECK(attr.name().compare("str") == 0, pass, b);
                    SUBCASE_CHECK(attr.getString().compare("This is a string") == 0, pass, b);

                    attr = attr.nextAttribute();
                    SUBCASE_CHECK_CRITICAL(!attr.isNull());
                    SUBCASE_CHECK(attr.name().compare("num") == 0, pass, b);
                    SUBCASE_CHECK(attr.getFloat() == 4.5, pass, b);
                }
            }
        }
    }
    catch (XmlException& e) {
        pass = false;
        if (m_verbose) {
            cout << e.what() << "\n";
        }
    }

    if (m_verbose) cout << (pass ? "\tPASS\n" : "\tFAIL\n");
    return pass;
}
Ejemplo n.º 16
0
bool Test::testCase4() const {
    if (m_verbose) cout << "\tCase 4: Move node between documents (2)\n";

    /*
    <nodeA>
       <nodeB a="1" b="two" c="3.4"/>
       <nodeC d="true">
          <nodeD>
             Hello World!
          </nodeD>
          <nodeE>
             Goodbye World!
          </nodeE>
       </nodeC>
    </nodeA>
    */

    XmlDocument doc2;

    try {
        XmlDocument doc1;
        doc1.parse("./test4.xml");

        XmlNode node = doc1.firstNode();
        XML_NODE_CHECK(node, nodeA);

        node = node.firstChild();
        XML_NODE_CHECK(node, nodeB);

        node = node.nextSibling();
        XML_NODE_CHECK(node, nodeC);

        XmlNode node_ = doc2.addNode("MyNode");
        node_.addNode(node);
    } // doc1 destroyed here
    catch (XmlException& e) {
        if (m_verbose) {
            cout << e.what() << "\n";
        }
        return false;
    }

    bool pass = true;
    bool b = false;

    XmlNode node = doc2.firstNode();
    SUBCASE_CHECK_CRITICAL(!node.isNull());
    SUBCASE_CHECK(node.name().compare("MyNode") == 0, pass, b);

    XmlNode node_ = node.firstChild();
    SUBCASE_CHECK_CRITICAL(!node_.isNull());
    SUBCASE_CHECK(node_.name().compare("nodeC") == 0, pass, b);

    XmlAttribute attr = node_.firstAttribute();
    SUBCASE_CHECK_CRITICAL(!attr.isNull());
    SUBCASE_CHECK(attr.name().compare("d") == 0, pass, b);
    SUBCASE_CHECK(attr.getString().compare("true") == 0, pass, b);

    XmlNode node__ = node_.firstChild();
    SUBCASE_CHECK_CRITICAL(!node__.isNull());
    SUBCASE_CHECK(node__.name().compare("nodeD") == 0, pass, b);

    node__ = node__.nextSibling();
    SUBCASE_CHECK_CRITICAL(!node__.isNull());
    SUBCASE_CHECK(node__.name().compare("nodeE") == 0, pass, b);

    if (m_verbose) cout << (pass ? "\tPASS\n" : "\tFAIL\n");
    return pass;
}
Ejemplo n.º 17
0
//===========================================
// Entity::assignData
//===========================================
void Entity::assignData(const XmlNode data) {
   if (data.isNull() || data.name() != "Entity") return;

   AssetManager assetManager;
   ShapeFactory shapeFactory;

   try {
      bool silent = isSilent();
      setSilent(true);

      XmlAttribute attr = data.firstAttribute();
      if (!attr.isNull() && attr.name() == "type") {
         m_type = internString(attr.getString());
         attr = attr.nextAttribute();
      }

      if (!attr.isNull() && attr.name() == "name") {
         m_name = internString(attr.getString());
         attr = attr.nextAttribute();
      }

      Vec2f transl = m_transl;

      if (!attr.isNull() && attr.name() == "x") {
         transl.x = attr.getFloat();
         attr = attr.nextAttribute();
      }

      if (!attr.isNull() && attr.name() == "y") {
         transl.y = attr.getFloat();
         attr = attr.nextAttribute();
      }

      setTranslation(transl);

      if (!attr.isNull() && attr.name() == "z") {
         m_z = attr.getFloat();

         // So that no Z values are 'exactly' equal
         m_z += 0.1f * static_cast<float32_t>(rand()) / static_cast<float32_t>(RAND_MAX);

         attr = attr.nextAttribute();
      }

      XmlNode node = data.firstChild();
      if (!node.isNull() && node.name() == "shape") {
         m_shape = unique_ptr<Shape>(shapeFactory.create(node.firstChild()));
         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "scale") {
         setScale(Vec2f(node.firstChild()));
         node = node.nextSibling();
      }

      if (!attr.isNull() && attr.name() == "rot") {
         setRotation(attr.getFloat());
      }

      if (!node.isNull() && node.name() == "fillColour") {
         m_fillColour = Colour(node.firstChild());
         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "lineColour") {
         m_lineColour = Colour(node.firstChild());
         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "lineWidth") {
         m_lineWidth = node.getInt();
         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "children") {
         XmlNode node_ = node.firstChild();

         while (!node_.isNull() && node_.name() == "child") {
            XmlAttribute attr = node_.firstAttribute();

            if (!attr.isNull() && attr.name() == "ptr") {
               long id = attr.getLong();

               pEntity_t child = boost::dynamic_pointer_cast<Entity>(assetManager.getAssetPointer(id));

               if (!child)
                  throw XmlException("Bad entity asset id", __FILE__, __LINE__);

               addChild(child);
            }

            node_ = node_.nextSibling();
         }
      }

      setSilent(silent);
   }
   catch (XmlException& e) {
      e.prepend("Error parsing XML for instance of class Entity; ");
      throw;
   }

   recomputeBoundary();
}
Ejemplo n.º 18
0
	XmlNodeIteratorByName::XmlNodeIteratorByName(const XmlNode & node)
		: mNode(node)
		, mName(node ? node.name() : string())
	{}
Ejemplo n.º 19
0
//===========================================
// Application::constructAsset
//===========================================
pAsset_t Application::constructAsset(const XmlNode data) {
   long proto = -1;
   bool addToWorld = false;

   XmlAttribute attr = data.firstAttribute();
   attr = attr.nextAttribute();

   if (!attr.isNull() && attr.name() == "proto") {
      proto = attr.getLong();
      attr = attr.nextAttribute();
   }

   if (!attr.isNull() && attr.name() == "addToWorld") {
      addToWorld = attr.getBool();
   }

   XmlNode node = data.firstChild();


   // Construct non-Entity assets

   if (node.name() == "Texture") return pAsset_t(new Texture(node));
   // ...


   // Construct Entities

   pEntity_t entity;

   // Does the XML description reference a prototype?
   if (proto != -1) {
      entity = pEntity_t(dynamic_cast<Entity*>(m_assetManager.cloneAsset(proto)));

      if (!entity)
         throw Exception("Prototype not found", __FILE__, __LINE__);

      // If the prototype has an Item object (aux data), set it to point at the entity.
      IAuxData* p = entity->getAuxDataPtr();
      if (p) {
         Item* item = dynamic_cast<Item*>(p);
         assert(item);

         item->setEntity(entity.get());
      }

      // If this XML node contains the entity along with an Item
      bool hasAuxData = false;
      if (node.name() == "ExtEntity") {
         node = node.firstChild();
         hasAuxData = true;
      }

      // The Entity node comes before the Item node
      entity->assignData(node);

      // Now we construct the Item
      if (hasAuxData) {
         node = node.nextSibling();

         if (node.name() != "Item")
            throw Exception("Expected Item node", __FILE__, __LINE__);

         Item* item = new Item(node);
         item->setEntity(entity.get());

         entity->attachAuxData(unique_ptr<Item>(item));
      }
   }
   // If XML description does not reference a prototype
   else {
      bool hasAuxData = false;
      if (node.name() == "ExtEntity") {
         node = node.firstChild();
         hasAuxData = true;
      }

      if (node.name() == "Player") entity = pEntity_t(new Player(node));
      if (node.name() == "Soil") entity = pEntity_t(new Soil(node));
      if (node.name() == "ParallaxSprite") entity = pEntity_t(new ParallaxSprite(node));
      if (node.name() == "Entity") entity = pEntity_t(new Entity(node));
      if (node.name() == "Sprite") entity = pEntity_t(new Sprite(node));
      if (node.name() == "PhysicalEntity") entity = pEntity_t(new PhysicalEntity<Box2dPhysics>(node));
      if (node.name() == "PhysicalSprite") entity = pEntity_t(new PhysicalSprite<Box2dPhysics>(node));

      if (!entity) {
         Exception ex("Unrecognised entity type '", __FILE__, __LINE__);
         ex.append(node.name());
         ex.append("'");
         throw ex;
      }

      if (hasAuxData) {
         node = node.nextSibling();

         if (node.name() != "Item")
            throw Exception("Expected Item node", __FILE__, __LINE__);

         Item* item = new Item(node);
         item->setEntity(entity.get());

         entity->attachAuxData(unique_ptr<Item>(item));
      }
   }

   if (addToWorld) {
      entity->addToWorld();
      m_worldSpace.insertAndTrackEntity(entity);
      m_entities[entity->getName()] = entity;
   }

   return entity;
}