void CopyXMLNode(csRef<iDocumentNode> source, csRef<iDocumentNode> target, int mode)
{
    if (mode == 0)
    {
        target->RemoveNodes();
        target->RemoveAttributes();
    }
    
    // copy nodes
    csRef<iDocumentNodeIterator> nodeIter = source->GetNodes();
    while (nodeIter->HasNext())
    {
        csRef<iDocumentNode> child = nodeIter->Next();
        csRef<iDocumentNode> targetChild = target->GetNode(child->GetValue());
        if (targetChild==NULL || mode==3)  // Mode 3 means don't merge tags but just insert multiples, so we create a new one here every time
        {
            targetChild = target->CreateNodeBefore(child->GetType());
            if (targetChild == NULL)
                assert(!"failed to create XML node, you are probably using wrong XML parser (xmlread instead of xmltiny)");
            targetChild->SetValue(child->GetValue());
        }
        CopyXMLNode(child, targetChild, mode);
    }
    
    // copy attributes
    csRef <iDocumentAttributeIterator> attrIter = source->GetAttributes();
    while (attrIter->HasNext())
    {
        csRef<iDocumentAttribute> attr = attrIter->Next();
        const char* attrName = attr->GetName();
        if (mode==1  ||  !target->GetAttribute(attrName))
            target->SetAttribute(attrName, attr->GetValue());
    }
}
Exemple #2
0
csRef < iDocumentNode > MD32spr::CreateValueNode(csRef < iDocumentNode >
						 &parent, const char *name,
						 const char *value)
{
  csRef < iDocumentNode > child =
    parent->CreateNodeBefore(CS_NODE_ELEMENT, 0);
  child->SetValue(name);
  csRef < iDocumentNode > text =
    child->CreateNodeBefore(CS_NODE_TEXT, 0);
  text->SetValue(value);
  return child;
}
Exemple #3
0
void MD32spr::WriteXMLMaterials(md3Model * model,
			csRef < iDocumentNode > &parent) 
{
  int i = 0, j = 0;
  for (i = 0; i < model->header->numMeshes; i++)
    for (j = 0; j < model->meshes[i].meshHeader->numSkins; j++) {
      csRef < iDocumentNode > child =
	parent->CreateNodeBefore(CS_NODE_ELEMENT, 0);
      child->SetValue("material");
      char *name = new char[strlen(model->meshes[i].skins[j].name) + 1];
      if(basename(model->meshes[i].skins[j].name, name) == 0)
	continue;
      child->SetAttribute("name", strcat(lowercase(name), ".mat"));
      char *tname = new char[strlen(model->meshes[i].skins[j].name) + 1];
      if(basename(model->meshes[i].skins[j].name, tname) == 0)
	continue;
      CreateValueNode(child, "texture", lowercase(tname));
    }
}
Exemple #4
0
void MD32spr::WriteGeneric(md3Model * model,
			   csRef < iDocumentNode > &parent)
{
  int i = 0, j = 0, k = 0;
  csRef < iDocumentNode > localParent;

  localParent =
    parent->CreateNodeBefore(CS_NODE_ELEMENT, 0);
  localParent->SetValue("textures");

  if (model->header->numMeshes > 0) {
    WriteXMLTextures(model, localParent);
      
    localParent = parent->CreateNodeBefore(CS_NODE_ELEMENT, 0);
    localParent->SetValue("materials");
    WriteXMLMaterials(model, localParent);


    for (i = 0; i < model->header->numMeshes; i++) {
      localParent = parent->CreateNodeBefore(CS_NODE_ELEMENT, 0);
      localParent->SetValue("meshfact");
      localParent->SetAttribute("name", model->meshes[i].meshHeader->name);
      CreateValueNode(localParent, "plugin",
		      "crystalspace.mesh.loader.factory.sprite.3d");
      csRef < iDocumentNode > child =
	localParent->CreateNodeBefore(CS_NODE_ELEMENT, 0);
      child->SetValue("params");

      for (j = 0; j < model->meshes[i].meshHeader->numSkins; j++) {
	char *matName = new char[strlen(model->meshes[i].skins[j].name) + 1];
	if(basename(model->meshes[i].skins[j].name, matName) == 0)
	  continue;
	CreateValueNode(child, "material",
			strcat(matName, ".mat"));
      }

      csRef < iDocumentNode > frame;
      for (j = 0; j < model->meshes[i].meshHeader->numMeshFrames; j++) {
	csString fNum;
	int numVertices = model->meshes[i].meshHeader->numVertices;

	frame = child->CreateNodeBefore(CS_NODE_ELEMENT, 0);
	frame->SetValue("frame");
	fNum.Format ("f%d", j);
	frame->SetAttribute("name", fNum);

	for (k = 0; k < model->meshes[i].meshHeader->numVertices; k++) {
	  float u, v, x, y, z;
	  csRef < iDocumentNode > texel =
	    frame->CreateNodeBefore(CS_NODE_ELEMENT, 0);
	  texel->SetValue("v");
	  x = model->meshes[i].vertices[j * numVertices + k].vec[0];
	  y = model->meshes[i].vertices[j * numVertices + k].vec[1];
	  z = model->meshes[i].vertices[j * numVertices + k].vec[2];
	  u = model->meshes[i].texCoords[k].texCoord[0];
	  v = model->meshes[i].texCoords[k].texCoord[1];
	  texel->SetAttributeAsFloat("x", x / scaleFactor);
	  texel->SetAttributeAsFloat("y", y / scaleFactor);
	  texel->SetAttributeAsFloat("z", z / scaleFactor);
	  texel->SetAttributeAsFloat("u", u);
	  texel->SetAttributeAsFloat("v", v);
	}
      }
      if((stristr(model->fileName.GetData(), "head") || 
	 stristr(model->fileName.GetData(), "upper") || 
	 stristr(model->fileName.GetData(), "lower")) && player) {
	// Write all the actions.
	for(j = 0; j < model->numActions; j++) {
	  if(model->numActions == 1) {
	    csRef < iDocumentNode > action =
	      child->CreateNodeBefore(CS_NODE_ELEMENT, 0);
	    action->SetValue("action");
	    action->SetAttribute("name", "default");

	    for (k = 0; k < model->meshes[i].meshHeader->numMeshFrames; k++) 
	    {
	      csString fNum;
	      csRef < iDocumentNode > f =
		action->CreateNodeBefore(CS_NODE_ELEMENT, 0);
	      fNum.Format ("f%d", k);
	      f->SetValue("f");
	      f->SetAttribute("name", fNum);
	      f->SetAttribute("delay", "1000");	/// 1000 is the default delay.
	    }
	  } else {
	    csRef < iDocumentNode > action =
	      child->CreateNodeBefore(CS_NODE_ELEMENT, 0);
	    action->SetValue("action");
	    action->SetAttribute("name", model->animInfo[j].actionName);
	  
	    for(k = model->animInfo[j].startFrame; 
		k < (model->animInfo[j].startFrame + model->animInfo[j].numFrames); 
		k++) 
	    {
	      csString fNum;
	      csRef < iDocumentNode > f =
		action->CreateNodeBefore(CS_NODE_ELEMENT, 0);
	      fNum.Format ("f%d", k);
	      f->SetValue("f");
	      f->SetAttribute("name", fNum);
	      float delay = (1.0f/(float)model->animInfo[j].fps) * 1000;
	      f->SetAttributeAsFloat("delay", delay);  
	    }
	  }
	}
      } else {
	csRef < iDocumentNode > action =
	  child->CreateNodeBefore(CS_NODE_ELEMENT, 0);
	action->SetValue("action");
	action->SetAttribute("name", "default");

	for (j = 0; j < model->meshes[i].meshHeader->numMeshFrames; j++) 
	{
	  csString fNum;
	  csRef < iDocumentNode > f =
	    action->CreateNodeBefore(CS_NODE_ELEMENT, 0);
	  fNum.Format ("f%d", j);
	  f->SetValue("f");
	  f->SetAttribute("name", fNum);
	  f->SetAttribute("delay", "1000");	/// 1000 is the default delay.
	}
      }
      for (j = 0; j < model->meshes[i].meshHeader->numTriangles; j++) {
	csRef < iDocumentNode > triangles =
	  child->CreateNodeBefore(CS_NODE_ELEMENT, 0);
	triangles->SetValue("t");
	triangles->SetAttributeAsInt("v1",
				     model->meshes[i].triangles[j].
				     triangle[2]);
	triangles->SetAttributeAsInt("v2",
				     model->meshes[i].triangles[j].
				     triangle[1]);
	triangles->SetAttributeAsInt("v3",
				     model->meshes[i].triangles[j].
				     triangle[0]);
      }
    }
    for (i = 0; i < model->header->numMeshes; i++) {
      localParent = parent->CreateNodeBefore(CS_NODE_ELEMENT, 0);
      localParent->SetValue("meshobj");
      char *name =
	new char[strlen(model->fileName.GetData()) +
		 strlen(model->meshes[i].meshHeader->name) + 1];
      basename(model->fileName.GetData(), name);
      localParent->SetAttribute("name",
				strcat(name,
				       model->meshes[i].meshHeader->name));
      CreateValueNode(localParent, "plugin",
		      "crystalspace.mesh.loader.sprite.3d");
      csRef < iDocumentNode > params =
	localParent->CreateNodeBefore(CS_NODE_ELEMENT, 0);
      params->SetValue("params");
      CreateValueNode(params, "factory",
		      model->meshes[i].meshHeader->name);
      CreateValueNode(params, "action", "default");
    }
  }
}
bool psNPCLoader::WriteTrigger(csRef<iDocumentNode> specificsNode, csString &trigger,int priorID, int questID)
{
    // <trigger>
    //      <phrase value="..">
    //      <phrase value="..">
    //      <attitude min="0" max="100">
    //          <response say=".. "/>
    //          <trigger>
    //              ..
    //          </trigger>
    //      </attitude>
    // </trigger>

    Result result;
    Result phrases;

    csString escArea;
    csString escTrigger;
    db->Escape(escArea, area);
    db->Escape(escTrigger, trigger);

    if(questID == -1)
    {
        result = db->Select("SELECT response_id, "
                            "       min_attitude_required, "
                            "       max_attitude_required "
                            "FROM npc_triggers "
                            "WHERE prior_response_required=\"%i\" and trigger=\"%s\" and area=\"%s\" and quest_id<1;",
                            priorID,
                            escTrigger.GetData(),
                            escArea.GetData());

        // all triggers that have the same response id will be grouped together
        // and written to the xml file as <phrase value="..">
        phrases = db->Select("SELECT id, trigger "
                             "FROM npc_triggers "
                             "WHERE response_id=\"%i\" and area=\"%s\" and quest_id<1;",
                             result[0].GetInt(0),
                             escArea.GetData());
    }
    else
    {
        result = db->Select("SELECT response_id, "
                            "       min_attitude_required, "
                            "       max_attitude_required "
                            "FROM npc_triggers "
                            "WHERE prior_response_required=\"%i\" and trigger=\"%s\" and quest_id=\"%i\";",
                            priorID,
                            escTrigger.GetData(),
                            questID);


        // all triggers that have the same response id will be grouped together
        // and written to the xml file as <phrase value="..">
        phrases = db->Select("SELECT id, trigger, area "
                             "FROM npc_triggers "
                             "WHERE response_id=\"%i\" and quest_id=\"%i\";",
                             result[0].GetInt(0),
                             questID);
    }

    csString temp;
    csRef<iDocumentNode> triggerNode;

    for(int i=0; i< (int)phrases.Count(); i++)
    {
        int triggerID = phrases[i].GetInt(0);
        bool duplicate=false;

        for(size_t j=0; j<triggers.GetSize(); j++)
        {
            if(triggerID==triggers[j])
                duplicate=true;
        }

        // if the trigger hasn't already been added
        if(!duplicate)
        {
            triggers.Push(triggerID);
            if(!triggerNode)
            {
                triggerNode = specificsNode->CreateNodeBefore(CS_NODE_ELEMENT);
                triggerNode->SetValue("trigger");
                csString area(phrases[0][2]);
                if(this->area.IsEmpty() && !area.IsEmpty())
                    triggerNode->SetAttribute("area", area);
            }
            csRef<iDocumentNode> phraseNode = triggerNode->CreateNodeBefore(CS_NODE_ELEMENT);

            phraseNode->SetValue("phrase");
            phraseNode->SetAttribute("value", phrases[i][1]);
        }
    }

    if(triggerNode)
    {
        for(int i=0; i<(int)result.Count(); i++)
        {
            int responseID  = result[i].GetInt(0);
            int minAttitude = result[i].GetInt(1);
            int maxAttitude = result[i].GetInt(2);

            csRef<iDocumentNode> attitudeNode = triggerNode->CreateNodeBefore(CS_NODE_ELEMENT);

            attitudeNode->SetValue("attitude");
            attitudeNode->SetAttributeAsInt("min", minAttitude);
            attitudeNode->SetAttributeAsInt("max", maxAttitude);

            if(!WriteResponse(attitudeNode, responseID, questID))
                return false;

            // check if this trigger contains other triggers
            Result childResult(db->Select("SELECT DISTINCT trigger "
                                          "FROM npc_triggers "
                                          "WHERE prior_response_required=%i;" ,responseID));

            if(childResult.IsValid())
            {
                for(int j=0; j<(int)childResult.Count(); j++)
                {
                    csString res(childResult[j][0]);
                    if(!WriteTrigger(attitudeNode, res, responseID, questID))
                        return false;
                }
            }
        }
    }
    return true;
}
bool psNPCLoader::WriteResponse(csRef<iDocumentNode> attitudeNode, int id, int questID)
{
    // <attitude max=".." min="..">
    //   <pronoun him=".." her=".." it=".." them=".."/>
    //   <response say="..."/>
    //   <response say="..."/>
    //   <script>
    //      ...
    //   </script>
    // </attitude>

    Result result(db->Select("SELECT  response1, response2, response3, response4, response5, "
                             "pronoun_him, pronoun_her, pronoun_it, pronoun_them, script, quest_id "
                             "FROM npc_responses "
                             "WHERE id=\"%i\";", id));

    // Sanity check for quest_id
    if(questID != -1)
    {
        for(unsigned int i = 0; i < result.Count(); i++)
        {
            if(result[i].GetInt(10) != questID)
            {
                CPrintf(CON_ERROR, "Sanity check failed: Response id %i does not have expected quest id %i\n", id, questID);
                return false;
            }
        }
    }

    csString him  = result[0][5];
    csString her  = result[0][6];
    csString it   = result[0][7];
    csString them = result[0][8];

    if(!him.IsEmpty() || !her.IsEmpty() || !it.IsEmpty() || !them.IsEmpty())
    {
        csRef<iDocumentNode> pronounNode = attitudeNode->CreateNodeBefore(CS_NODE_ELEMENT);

        pronounNode->SetValue("pronoun");

        if(!him.IsEmpty())
            pronounNode ->SetAttribute("him", him.GetData());
        if(!her.IsEmpty())
            pronounNode ->SetAttribute("her", her.GetData());
        if(!it.IsEmpty())
            pronounNode ->SetAttribute("it", it.GetData());
        if(!them.IsEmpty())
            pronounNode ->SetAttribute("them", them.GetData());
    }


    for(int i=0; i<5; i++)
    {
        if(!csString(result[0][i]).IsEmpty())
        {
            csRef<iDocumentNode> responseNode = attitudeNode->CreateNodeBefore(CS_NODE_ELEMENT);

            responseNode->SetValue("response");
            responseNode->SetAttribute("say", result[0][i]);
        }
    }

    csString script = result[0][9];
    if(!script.IsEmpty())
    {
        csRef<iDocumentNode> scriptNode = attitudeNode->CreateNodeBefore(CS_NODE_ELEMENT);

        scriptNode->SetValue("script");
        csRef<iDocumentNode> textNode = scriptNode->CreateNodeBefore(CS_NODE_TEXT);
        textNode->SetValue(script.GetData());
    }
    return true;
}