Esempio n. 1
0
/**
 * @brief Loads the player's faction standings.
 *
 *    @param parent Parent xml node to read from.
 *    @return 0 on success.
 */
int pfaction_load( xmlNodePtr parent )
{
   xmlNodePtr node, cur;
   char *str;
   int faction;

   node = parent->xmlChildrenNode;

   do {
      if (xml_isNode(node,"factions")) {
         cur = node->xmlChildrenNode;
         do {
            if (xml_isNode(cur,"faction")) {
               xmlr_attr(cur,"name",str); 
               faction = faction_get(str);
               if (faction != -1) /* Faction is valid. */
                  faction_stack[faction].player = xml_getFloat(cur);
               free(str);
            }
         } while (xml_nextNode(cur));
      }
   } while (xml_nextNode(node));

   return 0;
}
Esempio n. 2
0
/**
 * @brief Loads the player's faction standings.
 *
 *    @param parent Parent xml node to read from.
 *    @return 0 on success.
 */
int pfaction_load( xmlNodePtr parent )
{
   xmlNodePtr node, cur;
   char *str;
   int faction;

   node = parent->xmlChildrenNode;

   do {
      if (xml_isNode(node,"factions")) {
         cur = node->xmlChildrenNode;
         do {
            if (xml_isNode(cur,"faction")) {
               xmlr_attr(cur,"name",str);
               faction = faction_get(str);

               if (faction != -1) { /* Faction is valid. */

                  /* Must not be static. */
                  if (!faction_isFlag( &faction_stack[faction], FACTION_STATIC ))
                     faction_stack[faction].player = xml_getFloat(cur);
               }
               free(str);
            }
         } while (xml_nextNode(cur));
      }
   } while (xml_nextNode(node));

   return 0;
}
Esempio n. 3
0
File: outfit.c Progetto: pegue/naev
/**
 * @brief Parses the modification tidbits of the outfit.
 *
 *    @param temp Outfit to finish loading.
 *    @param parent Outfit's parent node.
 */
static void outfit_parseSMod( Outfit* temp, const xmlNodePtr parent )
{
   xmlNodePtr node;
   node = parent->children;

   do { /* load all the data */
      /* movement */
      xmlr_float(node,"thrust",temp->u.mod.thrust);
      xmlr_float(node,"turn",temp->u.mod.turn);
      xmlr_float(node,"speed",temp->u.mod.speed);
      /* health */
      xmlr_float(node,"armour",temp->u.mod.armour);
      xmlr_float(node,"shield",temp->u.mod.shield);
      xmlr_float(node,"energy",temp->u.mod.energy);
      xmlr_float(node,"fuel",temp->u.mod.fuel);
      if (xml_isNode(node,"armour_regen"))
         temp->u.mod.armour_regen = xml_getFloat(node)/60.0;
      else if (xml_isNode(node,"shield_regen"))
         temp->u.mod.shield_regen = xml_getFloat(node)/60.0;
      else if (xml_isNode(node,"energy_regen"))
         temp->u.mod.energy_regen = xml_getFloat(node)/60.0;
      /* misc */
      xmlr_int(node,"cargo",temp->u.mod.cargo);
   } while (xml_nextNode(node));
}
Esempio n. 4
0
/**
 * @brief Parses the actual individual event nodes.
 *
 *    @param parent Parent node to parse.
 *    @return 0 on success.
 */
static int events_parseActive( xmlNodePtr parent )
{
   char *buf;
   unsigned int id;
   int data;
   xmlNodePtr node, cur;
   Event_t *ev;

   node = parent->xmlChildrenNode;
   do {
      if (!xml_isNode(node,"event"))
         continue;

      xmlr_attr(node,"name",buf);
      if (buf==NULL) {
         WARN("Event has missing 'name' attribute, skipping.");
         continue;
      }
      data = event_dataID( buf );
      if (data < 0) {
         WARN("Event in save has name '%s' but event data not found matching name. Skipping.", buf);
         free(buf);
         continue;
      }
      free(buf);
      xmlr_attr(node,"id",buf);
      if (buf==NULL) {
         WARN("Event with data '%s' has missing 'id' attribute, skipping.", event_dataName(data));
         continue;
      }
      id = atoi(buf);
      free(buf);
      if (id==0) {
         WARN("Event with data '%s' has invalid 'id' attribute, skipping.", event_dataName(data));
         continue;
      }

      /* Create the event. */
      event_create( data, &id );
      ev = event_get( id );
      if (ev == NULL) {
         WARN("Event with data '%s' was not created, skipping.", event_dataName(data));
         continue;
      }
      ev->save = 1; /* Should save by default again. */

      /* Get the data. */
      cur = node->xmlChildrenNode;
      do {
         if (xml_isNode(cur,"lua"))
            nxml_unpersistLua( ev->L, cur );
      } while (xml_nextNode(cur));

      /* Claims. */
      if (xml_isNode(node,"claims"))
         ev->claims = claim_xmlLoad( node );
   } while (xml_nextNode(node));

   return 0;
}
Esempio n. 5
0
/**
 * @brief Parses the social tidbits of a faction: allies and enemies.
 *
 *    @param parent Node containing the faction.
 */
static void faction_parseSocial( xmlNodePtr parent )
{
   xmlNodePtr node, cur;
   char *buf;
   Faction *base;
   int mod;
   int mem;

   buf = xml_nodeProp(parent,"name");
   base = &faction_stack[faction_get(buf)];
   free(buf);

   node = parent->xmlChildrenNode;
   do {

      /* Grab the allies */
      if (xml_isNode(node,"allies")) {
         cur = node->xmlChildrenNode;

         mem = 0;
         do {
            if (xml_isNode(cur,"ally")) {
               mod = faction_get(xml_get(cur));
               base->nallies++;
               if (base->nallies > mem) {
                  mem += CHUNK_SIZE;
                  base->allies = realloc(base->allies, sizeof(int)*mem);
               }
               base->allies[base->nallies-1] = mod;
            }
         } while (xml_nextNode(cur));
         if (base->nallies > 0)
            base->allies = realloc(base->allies, sizeof(int)*base->nallies);
      }

      /* Grab the enemies */
      if (xml_isNode(node,"enemies")) {
         cur = node->xmlChildrenNode;

         mem = 0;
         do {
            if (xml_isNode(cur,"enemy")) {
               mod = faction_get(xml_get(cur));
               base->nenemies++;
               if (base->nenemies > mem) {
                  mem += CHUNK_SIZE;
                  base->enemies = realloc(base->enemies, sizeof(int)*mem);
               }
               base->enemies[base->nenemies-1] = mod;
            }
         } while (xml_nextNode(cur));
         if (base->nenemies > 0)
            base->enemies = realloc(base->enemies, sizeof(int)*base->nenemies);
      }
   } while (xml_nextNode(node));
}
Esempio n. 6
0
/**
 * @brief Loads the dtype stack.
 *
 *    @return 0 on success.
 */
int dtype_load (void)
{
   int mem;
   uint32_t bufsize;
   char *buf;
   xmlNodePtr node;
   xmlDocPtr doc;

   /* Load and read the data. */
   buf = ndata_read( DTYPE_DATA, &bufsize );
   doc = xmlParseMemory( buf, bufsize );

   /* Check to see if document exists. */
   node = doc->xmlChildrenNode;
   if (!xml_isNode(node,DTYPE_XML_ID)) {
      ERR("Malformed '"DTYPE_DATA"' file: missing root element '"DTYPE_XML_ID"'");
      return -1;
   }

   /* Check to see if is populated. */
   node = node->xmlChildrenNode; /* first system node */
   if (node == NULL) {
      ERR("Malformed '"DTYPE_DATA"' file: does not contain elements");
      return -1;
   }

   /* Load up the individual damage types. */
   mem = 0;
   do {
      xml_onlyNodes(node);

      if (!xml_isNode(node,DTYPE_XML_TAG)) {
         WARN("'"DTYPE_DATA"' has unknown node '%s'.", node->name);
         continue;
      }

      dtype_ntypes++;
      if (dtype_ntypes > mem) {
         if (mem == 0)
            mem = DTYPE_CHUNK_MIN;
         else
            mem *= 2;
         dtype_types = realloc(dtype_types, sizeof(DTYPE)*mem);
      }
      DTYPE_parse( &dtype_types[dtype_ntypes-1], node );

   } while (xml_nextNode(node));
   /* Shrink back to minimum - shouldn't change ever. */
   dtype_types = realloc(dtype_types, sizeof(DTYPE) * dtype_ntypes);

   /* Clean up. */
   xmlFreeDoc(doc);
   free(buf);

   return 0;
}
Esempio n. 7
0
File: spfx.c Progetto: zid/naev
/**
 * @brief Loads the spfx stack.
 *
 *    @return 0 on success.
 *
 * @todo Make spfx not hardcoded.
 */
int spfx_load (void)
{
   int mem;
   uint32_t bufsize;
   char *buf;
   xmlNodePtr node;
   xmlDocPtr doc;

   /* Load and read the data. */
   buf = ndata_read( SPFX_DATA, &bufsize );
   doc = xmlParseMemory( buf, bufsize );

   /* Check to see if document exists. */
   node = doc->xmlChildrenNode;
   if (!xml_isNode(node,SPFX_XML_ID)) {
      ERR("Malformed '"SPFX_DATA"' file: missing root element '"SPFX_XML_ID"'");
      return -1;
   }

   /* Check to see if is populated. */
   node = node->xmlChildrenNode; /* first system node */
   if (node == NULL) {
      ERR("Malformed '"SPFX_DATA"' file: does not contain elements");
      return -1;
   }

   /* First pass, loads up ammunition. */
   mem = 0;
   do {
      if (xml_isNode(node,SPFX_XML_TAG)) {

         spfx_neffects++;
         if (spfx_neffects > mem) {
            mem += CHUNK_SIZE;
            spfx_effects = realloc(spfx_effects, sizeof(SPFX_Base)*mem);
         }
         spfx_base_parse( &spfx_effects[spfx_neffects-1], node );
      }
   } while (xml_nextNode(node));
   /* Shrink back to minimum - shouldn't change ever. */
   spfx_effects = realloc(spfx_effects, sizeof(SPFX_Base) * spfx_neffects);

   /* Clean up. */
   xmlFreeDoc(doc);
   free(buf);


   /*
    * Now initialize force feedback.
    */
   spfx_hapticInit();

   return 0;
}
Esempio n. 8
0
/**
 * @brief Loads all the mission data.
 *
 *    @return 0 on success.
 */
int missions_load (void)
{
   int i, m;
   uint32_t bufsize;
   char *buf;

   for (i=0; i<MISSION_MAX; i++)
      player_missions[i] = calloc(1, sizeof(Mission));

   buf = ndata_read( MISSION_DATA_PATH, &bufsize );

   xmlNodePtr node;
   xmlDocPtr doc = xmlParseMemory( buf, bufsize );

   node = doc->xmlChildrenNode;
   if (!xml_isNode(node,XML_MISSION_ID)) {
      ERR("Malformed '"MISSION_DATA_PATH"' file: missing root element '"XML_MISSION_ID"'");
      return -1;
   }

   node = node->xmlChildrenNode; /* first mission node */
   if (node == NULL) {
      ERR("Malformed '"MISSION_DATA_PATH"' file: does not contain elements");
      return -1;
   }

   m = 0;
   do {
      if (xml_isNode(node,XML_MISSION_TAG)) {

         /* See if must grow. */
         mission_nstack++;
         if (mission_nstack > m) {
            m += MISSION_CHUNK;
            mission_stack = realloc(mission_stack, sizeof(MissionData)*m);
         }

         /* Load it. */
         mission_parse( &mission_stack[mission_nstack-1], node );
      }
   } while (xml_nextNode(node));

   /* Shrink to minimum. */
   mission_stack = realloc(mission_stack, sizeof(MissionData)*mission_nstack);

   /* Clean up. */
   xmlFreeDoc(doc);
   free(buf);

   DEBUG("Loaded %d Mission%s", mission_nstack, (mission_nstack==1) ? "" : "s" );

   return 0;
}
Esempio n. 9
0
File: outfit.c Progetto: pegue/naev
/**
 * @brief Loads all the outfits.
 *
 *    @return 0 on success.
 */
int outfit_load (void)
{
   int i, mem;
   uint32_t bufsize;
   char *buf = ndata_read( OUTFIT_DATA, &bufsize );

   xmlNodePtr node;
   xmlDocPtr doc = xmlParseMemory( buf, bufsize );

   node = doc->xmlChildrenNode;
   if (!xml_isNode(node,XML_OUTFIT_ID)) {
      ERR("Malformed '"OUTFIT_DATA"' file: missing root element '"XML_OUTFIT_ID"'");
      return -1;
   }        

   node = node->xmlChildrenNode; /* first system node */
   if (node == NULL) {
      ERR("Malformed '"OUTFIT_DATA"' file: does not contain elements");
      return -1;
   }        

   /* First pass, loads up ammunition. */
   mem = 0;
   do {
      if (xml_isNode(node,XML_OUTFIT_TAG)) {

         outfit_nstack++;
         if (outfit_nstack > mem) {
            mem += CHUNK_SIZE;
            outfit_stack = realloc(outfit_stack, sizeof(Outfit)*mem);
         }
         outfit_parse( &outfit_stack[outfit_nstack-1], node );               
      }
   } while (xml_nextNode(node));
   /* Shrink back to minimum - shouldn't change ever. */
   outfit_stack = realloc(outfit_stack, sizeof(Outfit) * outfit_nstack);

   /* Second pass, sets up ammunition relationships. */
   for (i=0; i<outfit_nstack; i++) {
      if (outfit_isLauncher(&outfit_stack[i]))
         outfit_stack[i].u.lau.ammo = outfit_get( outfit_stack[i].u.lau.ammo_name );
      else if (outfit_isFighterBay(&outfit_stack[i]))
         outfit_stack[i].u.bay.ammo = outfit_get( outfit_stack[i].u.bay.ammo_name );
   }

   xmlFreeDoc(doc);
   free(buf);

   DEBUG("Loaded %d Outfit%s", outfit_nstack, (outfit_nstack==1) ? "" : "s" );

   return 0;
}
Esempio n. 10
0
/**
 * @brief Parses a single faction, but doesn't set the allies/enemies bit.
 *
 *    @param temp Faction to load data into.
 *    @param parent Parent node to extract faction from.
 *    @return Faction created from parent node.
 */
static int faction_parse( Faction* temp, xmlNodePtr parent )
{
   xmlNodePtr node;
   int player;
   char buf[PATH_MAX];

   /* Clear memory. */
   memset( temp, 0, sizeof(Faction) );

   temp->name = xml_nodeProp(parent,"name");
   if (temp->name == NULL) WARN("Faction from "FACTION_DATA" has invalid or no name");

   player = 0;
   node = parent->xmlChildrenNode;
   do {
      /* Can be 0 or negative, so we have to take that into account. */
      if (xml_isNode(node,"player")) {
         temp->player_def = xml_getFloat(node);
         player = 1;
         continue;
      }

      xmlr_strd(node,"longname",temp->longname);
      if (xml_isNode(node, "colour"))
         temp->colour = col_fromName(xml_raw(node));

      if (xml_isNode(node,"logo")) {
         snprintf( buf, PATH_MAX, FACTION_LOGO_PATH"%s_small.png", xml_get(node));
         temp->logo_small = gl_newImage(buf, 0);
         continue;
      }

      if (xml_isNode(node,"static")) {
         faction_setFlag(temp, FACTION_STATIC);
         continue;
      }

      if (xml_isNode(node,"invisible")) {
         faction_setFlag(temp, FACTION_INVISIBLE);
         continue;
      }
   } while (xml_nextNode(node));

   if (player==0)
      DEBUG("Faction '%s' missing player tag.", temp->name);

   return 0;
}
Esempio n. 11
0
/**
 * @brief Loads a claim.
 *
 *    @param parent Parent node containing the claim data.
 *    @return The system claim.
 */
SysClaim_t *claim_xmlLoad( xmlNodePtr parent )
{
   SysClaim_t *claim;
   xmlNodePtr node;
   StarSystem *sys;

   /* Create the claim. */
   claim = claim_create();

   /* Load the nodes. */
   node = parent->xmlChildrenNode;
   do {
      if (xml_isNode(node,"sys")) {
         sys = system_get( xml_get(node) );
         if (sys != NULL)
            claim_add( claim, system_index(sys) );
         else
            WARN("System Claim trying to load system '%s' which doesn't exist.", xml_get(node));
      }
   } while (xml_nextNode(node));

   /* Activate the claim. */
   claim_activate( claim );

   return claim;
}
Esempio n. 12
0
File: spfx.c Progetto: zid/naev
/**
 * @brief Parses an xml node containing a SPFX.
 *
 *    @param temp Address to load SPFX into.
 *    @param parent XML Node containing the SPFX data.
 *    @return 0 on success.
 */
static int spfx_base_parse( SPFX_Base *temp, const xmlNodePtr parent )
{
   xmlNodePtr node;

   /* Clear data. */
   memset( temp, 0, sizeof(SPFX_Base) );

   /* Get the name (mallocs). */
   temp->name = xml_nodeProp(parent,"name");

   /* Extract the data. */
   node = parent->xmlChildrenNode;
   do {
      xmlr_float(node, "anim", temp->anim);
      xmlr_float(node, "ttl", temp->ttl);
      if (xml_isNode(node,"gfx"))
         temp->gfx = xml_parseTexture( node,
               SPFX_GFX_PRE"%s"SPFX_GFX_SUF, 6, 5, 0 );
   } while (xml_nextNode(node));

   /* Convert from ms to s. */
   temp->anim /= 1000.;
   temp->ttl  /= 1000.;
   if (temp->ttl == 0.)
      temp->ttl = temp->anim;

#define MELEMENT(o,s) \
   if (o) WARN("SPFX '%s' missing/invalid '"s"' element", temp->name) /**< Define to help check for data errors. */
   MELEMENT(temp->anim==0.,"anim");
   MELEMENT(temp->ttl==0.,"ttl");
   MELEMENT(temp->gfx==NULL,"gfx");
#undef MELEMENT

   return 0;
}
Esempio n. 13
0
/**
 * @brief Loads all the commodity data.
 *
 *    @return 0 on success.
 */
int commodity_load (void)
{
   uint32_t bufsize;
   char *buf;
   xmlNodePtr node;
   xmlDocPtr doc;

   /* Load the file. */
   buf = ndata_read( COMMODITY_DATA, &bufsize);
   if (buf == NULL)
      return -1;

   /* Handle the XML. */
   doc = xmlParseMemory( buf, bufsize );
   if (doc == NULL) {
      WARN("'%s' is not valid XML.", COMMODITY_DATA);
      return -1;
   }

   node = doc->xmlChildrenNode; /* Commoditys node */
   if (strcmp((char*)node->name,XML_COMMODITY_ID)) {
      ERR("Malformed "COMMODITY_DATA" file: missing root element '"XML_COMMODITY_ID"'");
      return -1;
   }

   node = node->xmlChildrenNode; /* first faction node */
   if (node == NULL) {
      ERR("Malformed "COMMODITY_DATA" file: does not contain elements");
      return -1;
   }

   do {
      if (xml_isNode(node, XML_COMMODITY_TAG)) {

         /* Make room for commodity. */
         commodity_stack = realloc(commodity_stack,
               sizeof(Commodity)*(++commodity_nstack));

         /* Load commodity. */
         commodity_parse(&commodity_stack[commodity_nstack-1], node);

         /* See if should get added to commodity list. */
         if (commodity_stack[commodity_nstack-1].price > 0.) {
            econ_nprices++;
            econ_comm = realloc(econ_comm, econ_nprices * sizeof(int));
            econ_comm[econ_nprices-1] = commodity_nstack-1;
         }
      }
   } while (xml_nextNode(node));

   xmlFreeDoc(doc);
   free(buf);

   DEBUG("Loaded %d Commodit%s", commodity_nstack, (commodity_nstack==1) ? "y" : "ies" );

   return 0;


}
Esempio n. 14
0
File: unidiff.c Progetto: naev/naev
/**
 * @brief Applies a diff to the universe.
 *
 *    @param name Diff to apply.
 *    @return 0 on success.
 */
int diff_apply( const char *name )
{
   xmlNodePtr node;
   xmlDocPtr doc;
   size_t bufsize;
   char *buf;
   char *diffname;

   /* Check if already applied. */
   if (diff_isApplied(name))
      return 0;

   buf = ndata_read( DIFF_DATA_PATH, &bufsize );
   doc = xmlParseMemory( buf, bufsize );

   node = doc->xmlChildrenNode;
   if (strcmp((char*)node->name,"unidiffs")) {
      ERR(_("Malformed unidiff file: missing root element 'unidiffs'"));
      return 0;
   }

   node = node->xmlChildrenNode; /* first system node */
   if (node == NULL) {
      ERR(_("Malformed unidiff file: does not contain elements"));
      return 0;
   }

   do {
      if (xml_isNode(node,"unidiff")) {
         /* Check to see if it's the diff we're looking for. */
         xmlr_attr(node,"name",diffname);
         if (strcmp(diffname,name)==0) {
            /* Apply it. */
            diff_patch( node );

            /* Clean up. */
            free(diffname);
            xmlFreeDoc(doc);
            free(buf);

            economy_execQueued();

            return 0;
         }
         free(diffname);
      }
   } while (xml_nextNode(node));

   /* More clean up. */
   xmlFreeDoc(doc);
   free(buf);

   WARN(_("UniDiff '%s' not found in %s."), name, DIFF_DATA_PATH);
   return -1;
}
Esempio n. 15
0
File: unidiff.c Progetto: naev/naev
/**
 * @brief Loads the diffs.
 *
 *    @param parent Parent node containing diffs.
 *    @return 0 on success.
 */
int diff_load( xmlNodePtr parent )
{
   xmlNodePtr node, cur;

   diff_clear();

   node = parent->xmlChildrenNode;
   do {
      if (xml_isNode(node,"diffs")) {
         cur = node->xmlChildrenNode;
         do {
            if (xml_isNode(cur,"diff"))
               diff_apply( xml_get(cur) );
         } while (xml_nextNode(cur));
      }
   } while (xml_nextNode(node));

   return 0;

}
Esempio n. 16
0
File: outfit.c Progetto: pegue/naev
/**
 * @brief Parses the afterburner tidbits of the outfit.
 *
 *    @param temp Outfit to finish loading.
 *    @param parent Outfit's parent node.
 */
static void outfit_parseSAfterburner( Outfit* temp, const xmlNodePtr parent )
{
   xmlNodePtr node;
   node = parent->children;

   /* must be >= 1. */
   temp->u.afb.thrust_perc = 1.;
   temp->u.afb.speed_perc = 1.;
   
   do { /* parse the data */
      xmlr_float(node,"rumble",temp->u.afb.rumble);
      if (xml_isNode(node,"sound"))
         temp->u.afb.sound = sound_get( xml_get(node) );

      if (xml_isNode(node,"thrust_perc"))
         temp->u.afb.thrust_perc = 1. + xml_getFloat(node)/100.;
      xmlr_float(node,"thrust_abs",temp->u.afb.thrust_abs);
      if (xml_isNode(node,"speed_perc"))
         temp->u.afb.speed_perc = 1. + xml_getFloat(node)/100.;
      xmlr_float(node,"speed_abs",temp->u.afb.speed_abs);
      xmlr_float(node,"energy",temp->u.afb.energy);
   } while (xml_nextNode(node));
}
Esempio n. 17
0
/**
 * @brief Allocates space for and populates a list of asset mods from a unistate xml tree.
 * 
 * @param rootNode A node pointer to the root node of unistate tree
 * @return A pointer to the first node of the linked list.
 */
assetStatePtr unistate_populateList(xmlNodePtr root)
{
   assetStatePtr listHead = NULL, curElement = NULL;
   xmlNodePtr elementNode = NULL, listNode = NULL;
#ifdef UNISTATE_DEBUG
   char debugBuffer[PATH_MAX];
#endif
   
   //no root node?
   if(!root) return NULL;
   //root has no children?
   if(!(listNode = root->children)) return NULL;
   //iterate over assets
   do {
      //if the node is named right
      if(xml_isNode(listNode, "asset"))
      {
         elementNode = listNode->children;
         //set up list element
         curElement = malloc(sizeof(assetState));
         curElement->next = listHead;
         listHead = curElement;
         curElement->name = curElement->faction = NULL;
         curElement->presence = -1;
         //get info from file
         xmlr_attr(listNode, "name", curElement->name);
         //debug stuff
   #ifdef UNISTATE_DEBUG
         snprintf(debugBuffer, sizeof(char) * (PATH_MAX - 1),\
            "UniState Debug: Asset name '%s' parsed\n", curElement->name);
         logprintf(stdout, debugBuffer);
   #endif
         do {
            xml_onlyNodes(elementNode);
            xmlr_strd(elementNode, "faction", curElement->faction);
            xmlr_int(elementNode, "presence", curElement->presence);
            xmlr_int(elementNode, "presence_range", curElement->range);
         } while(xml_nextNode(elementNode));
         //more debug stuff
   #ifdef UNISTATE_DEBUG
         snprintf(debugBuffer, sizeof(char) * (PATH_MAX - 1),\
            "UniState Debug: Asset faction '%s' and Asset presence '%i' parsed\n",\
            (curElement->faction == NULL ? "<Default>" : curElement->faction), curElement->presence);
         logprintf(stdout, debugBuffer);
   #endif
      }
   } while(xml_nextNode(listNode));
   //return the list
   return listHead;
}
Esempio n. 18
0
/**
 * @brief Loads the player's active missions from a save.
 *
 *    @param parent Node containing the player's active missions.
 *    @return 0 on success.
 */
int missions_loadActive( xmlNodePtr parent )
{
   xmlNodePtr node;

   /* cleanup old missions */
   missions_cleanup();

   node = parent->xmlChildrenNode;
   do {
      if (xml_isNode(node,"missions"))
         if (missions_parseActive( node ) < 0) return -1;
   } while (xml_nextNode(node));

   return 0;
}
Esempio n. 19
0
/**
 * @brief Loads the player's active events from a save.
 *
 *    @param parent Node containing the player's active events.
 *    @return 0 on success.
 */
int events_loadActive( xmlNodePtr parent )
{
   xmlNodePtr node;

   /* cleanup old events */
   events_cleanup();

   node = parent->xmlChildrenNode;
   do {
      if (xml_isNode(node,"events"))
         if (events_parseActive( node ) < 0) return -1;
   } while (xml_nextNode(node));

   return 0;
}
Esempio n. 20
0
File: fleet.c Progetto: Dinth/naev
/**
 * @brief Loads all the fleets.
 *
 *    @return 0 on success.
 */
static int fleet_loadFleets (void)
{
   int mem;
   uint32_t bufsize;
   char *buf;
   xmlNodePtr node;
   xmlDocPtr doc;

   /* Load the data. */
   buf = ndata_read( FLEET_DATA, &bufsize);
   doc = xmlParseMemory( buf, bufsize );

   node = doc->xmlChildrenNode; /* fleets node */
   if (strcmp((char*)node->name,"Fleets")) {
      ERR("Malformed "FLEET_DATA" file: missing root element 'Fleets'.");
      return -1;
   }

   node = node->xmlChildrenNode; /* first fleet node */
   if (node == NULL) {
      ERR("Malformed "FLEET_DATA" file: does not contain elements.");
      return -1;
   }

   mem = 0;
   do {
      if (xml_isNode(node,"fleet")) {
         /* See if memory must grow. */
         nfleets++;
         if (nfleets > mem) {
            mem += CHUNK_SIZE;
            fleet_stack = realloc(fleet_stack, sizeof(Fleet) * mem);
         }

         /* Load the fleet. */
         fleet_parse( &fleet_stack[nfleets-1], node );
      }
   } while (xml_nextNode(node));
   /* Shrink to minimum. */
   fleet_stack = realloc(fleet_stack, sizeof(Fleet) * nfleets);

   xmlFreeDoc(doc);
   free(buf);

   return 0;
}
Esempio n. 21
0
File: unidiff.c Progetto: naev/naev
/**
 * @brief Patches a asset.
 *
 *    @param diff Diff that is doing the patching.
 *    @param node Node containing the asset.
 *    @return 0 on success.
 */
static int diff_patchAsset( UniDiff_t *diff, xmlNodePtr node )
{
   UniHunk_t base, hunk;
   xmlNodePtr cur;

   /* Set the target. */
   memset(&base, 0, sizeof(UniHunk_t));
   base.target.type = HUNK_TARGET_ASSET;
   xmlr_attr(node,"name",base.target.u.name);
   if (base.target.u.name==NULL) {
      WARN(_("Unidiff '%s' has an target node without a 'name' tag"), diff->name);
      return -1;
   }

   /* Now parse the possible changes. */
   cur = node->xmlChildrenNode;
   do {
      xml_onlyNodes(cur);
      if (xml_isNode(cur,"faction")) {
         hunk.target.type = base.target.type;
         hunk.target.u.name = strdup(base.target.u.name);

         /* Outfit type is constant. */
         hunk.type = HUNK_TYPE_ASSET_FACTION;

         /* Get the data. */
         hunk.u.name = xml_getStrd(cur);

         /* Apply diff. */
         if (diff_patchHunk( &hunk ) < 0)
            diff_hunkFailed( diff, &hunk );
         else
            diff_hunkSuccess( diff, &hunk );
         continue;
      }
      WARN(_("Unidiff '%s' has unknown node '%s'."), diff->name, node->name);
   } while (xml_nextNode(cur));

   /* Clean up some stuff. */
   free(base.target.u.name);
   base.target.u.name = NULL;

   return 0;
}
Esempio n. 22
0
/**
 * @brief Loads the state of the universe into an xml file (Used in load.c)
 * 
 * @param rootNode pointer to the root node of the game save file we are loading off of
 * @return 0 on success
 */
int unistate_load(xmlNodePtr rootNode)
{
   if(!rootNode) return -1;
   assetStatePtr cur = NULL;
   xmlNodePtr elementNode = NULL;
   Planet *p;
   int f_id;
   elementNode = rootNode->children;
   do {
      if(xml_isNode(elementNode, "uni_state"))
      {
	 //populate list
         if(!(unistateList = unistate_populateList(elementNode))) 
            return -1;
         cur = unistateList;
         while(cur != NULL)
         {
            //Get planet struct and faction ID. If either return errors, bail.
            if((p = planet_get(cur->name)) == NULL) 
            {
               WARN("Invalid planet or faction passed");
               cur = cur->next;
               continue;
            }
            //Change the faction of the planet
            if(cur->faction != NULL && (f_id = faction_get(cur->faction)) != -1) 
               planet_setFaction(p, f_id);
            //Change presence of planet
            if(cur->presence != -1)
               p->presenceAmount = (double)cur->presence;
            //Change range of presence
            if(cur->range != -1)
               p->presenceRange = (double)cur->range;
            //update the universe
            space_reconstructPresences();
            //move along
            cur = cur->next;
         }
         return 0;
      }
   } while(xml_nextNode(elementNode));
   //if it fell through to here then it didn't find what we were looking for
   return -2;
}
Esempio n. 23
0
File: outfit.c Progetto: pegue/naev
/**
 * @brief Parses a damage node.
 *
 * Example damage node would be:
 * @code
 * <damage type="kinetic">10</damage>
 * @endcode
 *
 *    @param[out] dtype Stores the damage type here.
 *    @param[out] dmg Storse the damage here.
 *    @param[in] node Node to parse damage from.
 *    @return 0 on success.
 */
static int outfit_parseDamage( DamageType *dtype, double *dmg, xmlNodePtr node )
{
   char *buf;

   if (xml_isNode(node,"damage")) {
      /* Get type */
      xmlr_attr(node,"type",buf);
      (*dtype) = outfit_strToDamageType(buf);
      if (buf) free(buf);
      /* Get damage */
      (*dmg) = xml_getFloat(node);
      return 0;
   }

   /* Unknown type */
   (*dtype) = DAMAGE_TYPE_NULL;
   (*dmg) = 0;
   WARN("Trying to parse non-damage node as damage node!");
   return 1;
}
Esempio n. 24
0
File: tech.c Progetto: s0be/naev
/**
 * @brief Parses an XML tech node.
 */
static int tech_parseNodeData( tech_group_t *tech, xmlNodePtr parent )
{
   xmlNodePtr node;
   char *buf, *name;
   int ret;

   /* Parse the data. */
   node = parent->xmlChildrenNode;
   do {
      xml_onlyNodes(node);
      if (xml_isNode(node,"item")) {

         /* Must have name. */
         name = xml_get( node );
         if (name == NULL) {
            WARN("Tech group '%s' has an item without a value.", tech->name);
            continue;
         }

         /* Try to find hardcoded type. */
         buf = xml_nodeProp( node, "type" );
         if (buf == NULL) {
            ret = 1;
            if (ret)
               ret = tech_addItemGroup( tech, name );
            if (ret)
               ret = tech_addItemOutfit( tech, name );
            if (ret)
               ret = tech_addItemShip( tech, name );
            if (ret)
               ret = tech_addItemCommodity( tech, name );
            if (ret) {
               WARN("Generic item '%s' not found in tech group '%s'",
                     name, tech->name );
               continue;
            }
         }
         else if (strcmp(buf,"group")==0) {
            if (!tech_addItemGroup( tech, name )) {
               WARN("Group item '%s' not found in tech group '%s'.",
                     name, tech->name );
               continue;
            }
         }
         else if (strcmp(buf,"outfit")==0) {
            if (!tech_addItemGroup( tech, name )) {
               WARN("Outfit item '%s' not found in tech group '%s'.",
                     name, tech->name );
               continue;
            }
         }
         else if (strcmp(buf,"ship")==0) {
            if (!tech_addItemGroup( tech, name )) {
               WARN("Ship item '%s' not found in tech group '%s'.",
                     name, tech->name );
               continue;
            }
         }
         else if (strcmp(buf,"commodity")==0) {
            if (!tech_addItemGroup( tech, name )) {
               WARN("Commodity item '%s' not found in tech group '%s'.",
                     name, tech->name );
               continue;
            }
         }
         continue;
      }
      WARN("Tech group '%s' has unknown node '%s'.", tech->name, node->name);
   } while (xml_nextNode( node ));

   return 0;
}
Esempio n. 25
0
File: event.c Progetto: Arakash/naev
/**
 * @brief Loads all the events.
 *
 *    @return 0 on success.
 */
int events_load (void)
{
   int m;
   uint32_t bufsize;
   char *buf;
   xmlNodePtr node;
   xmlDocPtr doc;
 
   /* Load the data. */
   buf = ndata_read( EVENT_DATA, &bufsize );
   if (buf == NULL) {
      WARN("Unable to read data from '%s'", EVENT_DATA);
      return -1;
   }

   /* Load the document. */
   doc = xmlParseMemory( buf, bufsize );
   if (doc == NULL) {
      WARN("Unable to parse document '%s'", EVENT_DATA);
      return -1;
   }

   /* Get the root node. */
   node = doc->xmlChildrenNode;
   if (!xml_isNode(node,XML_EVENT_ID)) {
      WARN("Malformed '"EVENT_DATA"' file: missing root element '"XML_EVENT_ID"'");
      return -1;
   }

   /* Get the first node. */
   node = node->xmlChildrenNode; /* first mission node */
   if (node == NULL) {
      WARN("Malformed '"EVENT_DATA"' file: does not contain elements");
      return -1;
   }

   m = 0;
   do {
      if (xml_isNode(node,XML_EVENT_TAG)) {

         /* See if must grow. */
         event_ndata++;
         if (event_ndata > m) {
            m += EVENT_CHUNK;
            event_data = realloc(event_data, sizeof(EventData_t)*m);
         }

         /* Load it. */
         event_parse( &event_data[event_ndata-1], node );
      }
   } while (xml_nextNode(node));

   /* Shrink to minimum. */
   event_data = realloc(event_data, sizeof(EventData_t)*event_ndata);

   /* Clean up. */                                                        
   xmlFreeDoc(doc);
   free(buf);

   DEBUG("Loaded %d Event%s", event_ndata, (event_ndata==1) ? "" : "s" );

   return 0;
}
Esempio n. 26
0
File: event.c Progetto: Arakash/naev
/**
 * @brief Loads up an event from an XML node.
 *
 *    @param temp Event to load up.
 *    @param parent Event parent node.
 *    @return 0 on success.
 */
static int event_parse( EventData_t *temp, const xmlNodePtr parent )
{
   xmlNodePtr node, cur;
   char str[PATH_MAX] = "\0";
   char *buf;

#ifdef DEBUGGING
   /* To check if mission is valid. */
   lua_State *L;
   int ret;
   uint32_t len;
#endif /* DEBUGGING */

   memset( temp, 0, sizeof(EventData_t) );

   /* get the name */
   temp->name = xml_nodeProp(parent,"name");
   if (temp->name == NULL)
      WARN("Event in "EVENT_DATA" has invalid or no name");

   node = parent->xmlChildrenNode;

   do { /* load all the data */

      /* Only check nodes. */
      xml_onlyNodes(node);

      if (xml_isNode(node,"lua")) {
         snprintf( str, PATH_MAX, EVENT_LUA_PATH"%s.lua", xml_get(node) );
         temp->lua = strdup( str );
         str[0] = '\0';

#ifdef DEBUGGING
         /* Check to see if syntax is valid. */
         L = luaL_newstate();
         buf = ndata_read( temp->lua, &len );
         ret = luaL_loadbuffer(L, buf, len, temp->name );
         if (ret == LUA_ERRSYNTAX) {
            WARN("Event Lua '%s' of mission '%s' syntax error: %s",
                  temp->name, temp->lua, lua_tostring(L,-1) );
         }
         free(buf);
         lua_close(L);
#endif /* DEBUGGING */

         continue;
      }

      /* Trigger. */
      else if (xml_isNode(node,"trigger")) {
         buf = xml_get(node);
         if (buf == NULL)
            WARN("Event '%s': Null trigger type.", temp->name);
         else if (strcmp(buf,"enter")==0)
            temp->trigger = EVENT_TRIGGER_ENTER;
         else if (strcmp(buf,"land")==0)
            temp->trigger = EVENT_TRIGGER_LAND;
         else
            WARN("Event '%s' has invalid 'trigger' parameter: %s", temp->name, buf);

         continue;
      }

      /* Flags. */
      else if (xml_isNode(node,"flags")) { /* set the various flags */
         cur = node->children;
         do {
            if (xml_isNode(cur,"unique"))
               temp->flags |= EVENT_FLAG_UNIQUE;
         } while (xml_nextNode(cur));
         continue;
      }

      /* Condition. */
      xmlr_strd(node,"cond",temp->cond);

      /* Get chance. */
      xmlr_float(node,"chance",temp->chance);

      DEBUG("Unknown node '%s' in event '%s'", node->name, temp->name);
   } while (xml_nextNode(node));

   /* Process. */
   temp->chance /= 100.;

#define MELEMENT(o,s) \
   if (o) WARN("Mission '%s' missing/invalid '"s"' element", temp->name)
   MELEMENT(temp->lua==NULL,"lua");
   MELEMENT(temp->chance==0.,"chance");
   MELEMENT(temp->trigger==EVENT_TRIGGER_NULL,"trigger");
#undef MELEMENT

   return 0;
}
Esempio n. 27
0
File: tech.c Progetto: s0be/naev
/**
 * @brief Loads the tech information.
 */
int tech_load (void)
{
   int i, ret, s;
   uint32_t bufsize;
   char *buf, *data;
   xmlNodePtr node, parent;
   xmlDocPtr doc;
   tech_group_t *tech;

   /* Load the data. */
   data = ndata_read( TECH_DATA, &bufsize );
   if (data == NULL)
      return -1;

   /* Load the document. */
   doc = xmlParseMemory( data, bufsize );
   if (doc == NULL) {
      WARN("'%s' is not a valid XML file.", TECH_DATA);
      return -1;
   }

   /* Load root element. */
   parent = doc->xmlChildrenNode;
   if (!xml_isNode(parent,XML_TECH_ID)) {
      WARN("Malformed "TECH_DATA" file: missing root element '"XML_TECH_ID"'");
      return -1;
   }

   /* Get first node. */
   node = parent->xmlChildrenNode;
   if (node == NULL) {
      WARN("Malformed "TECH_DATA" file: does not contain elements");
      return -1;
   }

   /* Create the array. */
   tech_groups = array_create( tech_group_t );

   /* First pass create the groups - needed to reference them later. */
   ret   = 0;
   tech  = NULL;
   do {
      xml_onlyNodes(node);
      /* Must match tag. */
      if (!xml_isNode(node, XML_TECH_TAG)) {
         WARN("'"XML_TECH_ID"' has unknown node '%s'.", node->name);
         continue;
      }
      if (ret==0) /* Write over failures. */
         tech = &array_grow( &tech_groups );
      ret = tech_parseNode( tech, node );
   } while (xml_nextNode(node));
   array_shrink( &tech_groups );

   /* Now we load the data. */
   node  = parent->xmlChildrenNode;
   s     = array_size( tech_groups );
   do {
      /* Must match tag. */
      if (!xml_isNode(node, XML_TECH_TAG))
         continue;

      /* Must avoid warning by checking explicit NULL. */
      xmlr_attr( node, "name", buf );
      if (buf == NULL)
         continue;

      /* Load next tech. */
      for (i=0; i<s; i++) {
         tech  = &tech_groups[i];
         if (strcmp(tech->name, buf)==0)
            tech_parseNodeData( tech, node );
      }

      /* Free memory. */
      free(buf);
   } while (xml_nextNode(node));

   /* Info. */
   DEBUG("Loaded %d tech group%s", s, (s == 1) ? "" : "s" );

   /* Free memory. */
   free(data);
   xmlFreeDoc(doc);

   return 0;
}
Esempio n. 28
0
/**
 * @brief Loads the module start data.
 *
 *    @return 0 on success.
 */
int start_load (void)
{
   uint32_t bufsize;
   char *buf;
   xmlNodePtr node, cur, tmp;
   xmlDocPtr doc;
   int scu, stp, stu;

   /* Defaults. */
   scu = -1;
   stp = -1;
   stu = -1;

   /* Try to read the file. */
   buf = ndata_read( START_DATA_PATH, &bufsize );
   if (buf == NULL)
      return -1;

   /* Load the XML file. */
   doc = xmlParseMemory( buf, bufsize );

   node = doc->xmlChildrenNode;
   if (!xml_isNode(node,XML_START_ID)) {
      ERR("Malformed '"START_DATA_PATH"' file: missing root element '"XML_START_ID"'");
      return -1;
   }

   node = node->xmlChildrenNode; /* first system node */
   if (node == NULL) {
      ERR("Malformed '"START_DATA_PATH"' file: does not contain elements");
      return -1;
   }
   do {
      xml_onlyNodes(node);

      xmlr_strd( node, "name", start_data.name );

      if (xml_isNode(node, "player")) { /* we are interested in the player */
         cur = node->children;
         do {
            xml_onlyNodes(cur);

            xmlr_uint( cur, "credits", start_data.credits );
            xmlr_strd( cur, "mission", start_data.mission );
            xmlr_strd( cur, "event",   start_data.event );

            if (xml_isNode(cur,"ship")) {
               xmlr_attr( cur, "name",    start_data.shipname);
               xmlr_strd( cur, "ship",    start_data.ship );
            }
            else if (xml_isNode(cur,"system")) {
               tmp = cur->children;
               do {
                  xml_onlyNodes(tmp);
                  /** system name, @todo percent chance */
                  xmlr_strd( tmp, "name", start_data.system );
                  /* position */
                  xmlr_float( tmp, "x", start_data.x );
                  xmlr_float( tmp, "y", start_data.y );
                  WARN("'"START_DATA_PATH"' has unknown system node '%s'.", tmp->name);
               } while (xml_nextNode(tmp));
               continue;
            }
            WARN("'"START_DATA_PATH"' has unknown player node '%s'.", cur->name);
         } while (xml_nextNode(cur));
         continue;
      }

      if (xml_isNode(node,"date")) {
         cur = node->children;
         do {
            xml_onlyNodes(cur);

            xmlr_int( cur, "scu", scu );
            xmlr_int( cur, "stp", stp );
            xmlr_int( cur, "stu", stu );
            WARN("'"START_DATA_PATH"' has unknown date node '%s'.", cur->name);
         } while (xml_nextNode(cur));
         continue;
      }

      if (xml_isNode(node,"tutorial")) {
         cur = node->children;
         do {
            xml_onlyNodes(cur);

            xmlr_strd( cur, "mission", start_data.tutmisn );
            xmlr_strd( cur, "event", start_data.tutevt );

            if (xml_isNode(cur,"system")) {
               tmp = cur->children;
               do {
                  xml_onlyNodes(tmp);
                  /** system name, @todo percent chance */
                  xmlr_strd( tmp, "name", start_data.tutsys );
                  /* position */
                  xmlr_float( tmp, "x", start_data.tutx );
                  xmlr_float( tmp, "y", start_data.tuty );
                  WARN("'"START_DATA_PATH"' has unknown system node '%s'.", tmp->name);
               } while (xml_nextNode(tmp));
               continue;
            }

            WARN("'"START_DATA_PATH"' has unknown tutorial node '%s'.", cur->name);
         } while (xml_nextNode(cur));
         continue;
      }

      WARN("'"START_DATA_PATH"' has unknown node '%s'.", node->name);
   } while (xml_nextNode(node));

   /* Clean up. */
   xmlFreeDoc(doc);
   free(buf);

   /* Sanity checking. */
#define MELEMENT(o,s) \
   if (o) WARN("Module start data missing/invalid '"s"' element") /**< Define to help check for data errors. */
   MELEMENT( start_data.name==NULL, "name" );
   MELEMENT( start_data.credits==0, "credits" );
   MELEMENT( start_data.ship==NULL, "ship" );
   MELEMENT( start_data.system==NULL, "player system" );
   MELEMENT( start_data.tutsys==NULL, "tutorial system" );
   MELEMENT( scu<0, "scu" );
   MELEMENT( stp<0, "stp" );
   MELEMENT( stu<0, "stu" );
#undef MELEMENT

   /* Post process. */
   start_data.date = ntime_create( scu, stp, stu );

   return 0;
}
Esempio n. 29
0
/**
 * @brief Loads up all the factions from the data file.
 *
 *    @return 0 on success.
 */
int factions_load (void)
{
   int mem;
   uint32_t bufsize;
   char *buf = ndata_read( FACTION_DATA_PATH, &bufsize);

   xmlNodePtr factions, node;
   xmlDocPtr doc = xmlParseMemory( buf, bufsize );

   node = doc->xmlChildrenNode; /* Factions node */
   if (!xml_isNode(node,XML_FACTION_ID)) {
      ERR("Malformed "FACTION_DATA_PATH" file: missing root element '"XML_FACTION_ID"'");
      return -1;
   }

   factions = node->xmlChildrenNode; /* first faction node */
   if (factions == NULL) {
      ERR("Malformed "FACTION_DATA_PATH" file: does not contain elements");
      return -1;
   }

   /* player faction is hard-coded */
   faction_stack = calloc( 1, sizeof(Faction) );
   faction_stack[0].name = strdup("Player");
   faction_stack[0].flags = FACTION_STATIC | FACTION_INVISIBLE;
   faction_nstack++;

   /* First pass - gets factions */
   node = factions;
   mem = 0;
   do {
      if (xml_isNode(node,XML_FACTION_TAG)) {
         /* See if must grow memory.  */
         faction_nstack++;
         if (faction_nstack > mem) {
            mem += CHUNK_SIZE;
            faction_stack = realloc(faction_stack, sizeof(Faction)*mem);
         }

         /* Load faction. */
         faction_parse(&faction_stack[faction_nstack-1], node);
      }
   } while (xml_nextNode(node));

   /* Shrink to minimum size. */
   faction_stack = realloc(faction_stack, sizeof(Faction)*faction_nstack);

   /* Second pass - sets allies and enemies */
   node = factions;
   do {
      if (xml_isNode(node,XML_FACTION_TAG))
         faction_parseSocial(node);
   } while (xml_nextNode(node));

#ifdef DEBUGGING
   int i, j, k, r;
   Faction *f, *sf;

   /* Third pass, makes sure allies/enemies are sane. */
   for (i=0; i<faction_nstack; i++) {
      f = &faction_stack[i];

      /* First run over allies and make sure it's mutual. */
      for (j=0; j < f->nallies; j++) {
         sf = &faction_stack[ f->allies[j] ];

         r = 0;
         for (k=0; k < sf->nallies; k++)
            if (sf->allies[k] == i)
               r = 1;

         if (r == 0)
            WARN("Faction: %s and %s aren't completely mutual allies!",
                  f->name, sf->name );
      }

      /* Now run over enemies. */
      for (j=0; j < f->nenemies; j++) {
         sf = &faction_stack[ f->enemies[j] ];

         r = 0;
         for (k=0; k < sf->nenemies; k++)
            if (sf->enemies[k] == i)
               r = 1;

         if (r == 0)
            WARN("Faction: %s and %s aren't completely mutual enemies!",
                  f->name, sf->name );
      }
   }
#endif /* DEBUGGING */

   xmlFreeDoc(doc);
   free(buf);

   DEBUG("Loaded %d Faction%s", faction_nstack, (faction_nstack==1) ? "" : "s" );

   return 0;
}
Esempio n. 30
0
/**
 * @brief Parses a single faction, but doesn't set the allies/enemies bit.
 *
 *    @param temp Faction to load data into.
 *    @param parent Parent node to extract faction from.
 *    @return Faction created from parent node.
 */
static int faction_parse( Faction* temp, xmlNodePtr parent )
{
   xmlNodePtr node;
   int player;
   char buf[PATH_MAX], *dat;
   uint32_t ndat;

   /* Clear memory. */
   memset( temp, 0, sizeof(Faction) );

   temp->name = xml_nodeProp(parent,"name");
   if (temp->name == NULL)
      WARN("Faction from "FACTION_DATA_PATH" has invalid or no name");

   player = 0;
   node = parent->xmlChildrenNode;
   do {

      /* Only care about nodes. */
      xml_onlyNodes(node);

      /* Can be 0 or negative, so we have to take that into account. */
      if (xml_isNode(node,"player")) {
         temp->player_def = xml_getFloat(node);
         player = 1;
         continue;
      }

      xmlr_strd(node,"longname",temp->longname);
      xmlr_strd(node,"display",temp->displayname);
      if (xml_isNode(node, "colour")) {
         temp->colour = col_fromName(xml_raw(node));
         continue;
      }

      if (xml_isNode(node, "spawn")) {
         if (temp->sched_state != NULL)
            WARN("Faction '%s' has duplicate 'spawn' tag.", temp->name);
         nsnprintf( buf, sizeof(buf), "dat/factions/spawn/%s.lua", xml_raw(node) );
         temp->sched_state = nlua_newState();
         nlua_loadStandard( temp->sched_state, 0 );
         dat = ndata_read( buf, &ndat );
         if (luaL_dobuffer(temp->sched_state, dat, ndat, buf) != 0) {
            WARN("Failed to run spawn script: %s\n"
                  "%s\n"
                  "Most likely Lua file has improper syntax, please check",
                  buf, lua_tostring(temp->sched_state,-1));
            lua_close( temp->sched_state );
            temp->sched_state = NULL;
         }
         free(dat);
         continue;
      }

      if (xml_isNode(node, "standing")) {
         if (temp->state != NULL)
            WARN("Faction '%s' has duplicate 'standing' tag.", temp->name);
         nsnprintf( buf, sizeof(buf), "dat/factions/standing/%s.lua", xml_raw(node) );
         temp->state = nlua_newState();
         nlua_loadStandard( temp->state, 0 );
         dat = ndata_read( buf, &ndat );
         if (luaL_dobuffer(temp->state, dat, ndat, buf) != 0) {
            WARN("Failed to run standing script: %s\n"
                  "%s\n"
                  "Most likely Lua file has improper syntax, please check",
                  buf, lua_tostring(temp->state,-1));
            lua_close( temp->state );
            temp->state = NULL;
         }
         free(dat);
         continue;
      }

      if (xml_isNode(node, "known")) {
         faction_setFlag(temp, FACTION_KNOWN);
         continue;
      }

      if (xml_isNode(node, "equip")) {
         if (temp->equip_state != NULL)
            WARN("Faction '%s' has duplicate 'equip' tag.", temp->name);
         nsnprintf( buf, sizeof(buf), "dat/factions/equip/%s.lua", xml_raw(node) );
         temp->equip_state = nlua_newState();
         nlua_loadStandard( temp->equip_state, 0 );
         dat = ndata_read( buf, &ndat );
         if (luaL_dobuffer(temp->equip_state, dat, ndat, buf) != 0) {
            WARN("Failed to run equip script: %s\n"
                  "%s\n"
                  "Most likely Lua file has improper syntax, please check",
                  buf, lua_tostring(temp->equip_state,-1));
            lua_close( temp->equip_state );
            temp->equip_state = NULL;
         }
         free(dat);
         continue;
      }

      if (xml_isNode(node,"logo")) {
         if (temp->logo_small != NULL)
            WARN("Faction '%s' has duplicate 'logo' tag.", temp->name);
         nsnprintf( buf, PATH_MAX, FACTION_LOGO_PATH"%s_small.png", xml_get(node));
         temp->logo_small = gl_newImage(buf, 0);
         nsnprintf( buf, PATH_MAX, FACTION_LOGO_PATH"%s_tiny.png", xml_get(node));
         temp->logo_tiny = gl_newImage(buf, 0);
         continue;
      }

      if (xml_isNode(node,"static")) {
         faction_setFlag(temp, FACTION_STATIC);
         continue;
      }

      if (xml_isNode(node,"invisible")) {
         faction_setFlag(temp, FACTION_INVISIBLE);
         continue;
      }

      /* Avoid warnings. */
      if (xml_isNode(node,"allies") || xml_isNode(node,"enemies"))
         continue;

      DEBUG("Unknown node '%s' in faction '%s'",node->name,temp->name);
   } while (xml_nextNode(node));

   if (player==0)
      DEBUG("Faction '%s' missing player tag.", temp->name);
   if ((temp->state!=NULL) && faction_isFlag( temp, FACTION_STATIC ))
      WARN("Faction '%s' has Lua and is static!", temp->name);
   if ((temp->state==NULL) && !faction_isFlag( temp, FACTION_STATIC ))
      WARN("Faction '%s' has no Lua and isn't static!", temp->name);

   return 0;
}