/** * @brief Creatse a shipstat list element from an xml node. * * @param node Node to create element from. * @return Liste lement created from node. */ ShipStatList* ss_listFromXML( xmlNodePtr node ) { const ShipStatsLookup *sl; ShipStatList *ll; ShipStatsType type; /* Try to get type. */ type = ss_typeFromName( (char*) node->name ); if (type == SS_TYPE_NIL) return NULL; /* Allocate. */ ll = malloc( sizeof(ShipStatList) ); ll->next = NULL; ll->target = 0; ll->type = type; /* Set the data. */ sl = &ss_lookup[ type ]; switch (sl->data) { case SS_DATA_TYPE_DOUBLE: ll->d.d = xml_getFloat(node) / 100.; break; case SS_DATA_TYPE_DOUBLE_ABSOLUTE: ll->d.d = xml_getFloat(node); break; case SS_DATA_TYPE_BOOLEAN: ll->d.i = !!xml_getInt(node); break; case SS_DATA_TYPE_INTEGER: ll->d.i = xml_getInt(node); break; } return ll; }
/** * @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)); }
/** * @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; }
/** * @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; }
/** * @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, sub; 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. */ sub = cur->xmlChildrenNode; do { if (xml_isNode(sub,"standing")) { /* Must not be static. */ if (!faction_isFlag( &faction_stack[faction], FACTION_STATIC )) faction_stack[faction].player = xml_getFloat(sub); continue; } if (xml_isNode(sub,"known")) { faction_setFlag(&faction_stack[faction], FACTION_KNOWN); continue; } } while (xml_nextNode(sub)); } free(str); } } while (xml_nextNode(cur)); } } while (xml_nextNode(node)); return 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; }
/** * @brief Unpersists Lua data. * * @param L State to unperisist data into. * @param parent Node containing all the Lua persisted data. * @return 0 on success. */ static int nxml_unpersistDataNode( lua_State *L, xmlNodePtr parent ) { LuaPlanet p; LuaSystem s; LuaFaction f; LuaShip sh; LuaTime lt; Planet *pnt; StarSystem *ss; xmlNodePtr node; char *name, *type, *buf, *num; int keynum; node = parent->xmlChildrenNode; do { if (xml_isNode(node,"data")) { /* Get general info. */ xmlr_attr(node,"name",name); xmlr_attr(node,"type",type); /* Check to see if key is a number. */ xmlr_attr(node,"keynum",num); if (num != NULL) { keynum = 1; lua_pushnumber(L, atof(name)); free(num); } else lua_pushstring(L, name); /* handle data types */ /* Recursive tables. */ if (strcmp(type,"table")==0) { xmlr_attr(node,"name",buf); /* Create new table. */ lua_newtable(L); /* Save data. */ nxml_unpersistDataNode(L,node); /* Set table. */ free(buf); } else if (strcmp(type,"number")==0) lua_pushnumber(L,xml_getFloat(node)); else if (strcmp(type,"bool")==0) lua_pushboolean(L,xml_getInt(node)); else if (strcmp(type,"string")==0) lua_pushstring(L,xml_get(node)); else if (strcmp(type,"planet")==0) { pnt = planet_get(xml_get(node)); if (pnt != NULL) { p.id = planet_index(pnt); lua_pushplanet(L,p); } else WARN("Failed to load unexistent planet '%s'", xml_get(node)); } else if (strcmp(type,"system")==0) { ss = system_get(xml_get(node)); if (ss != NULL) { s.id = system_index( ss ); lua_pushsystem(L,s); } else WARN("Failed to load unexistent system '%s'", xml_get(node)); } else if (strcmp(type,"faction")==0) { f.f = faction_get(xml_get(node)); lua_pushfaction(L,f); } else if (strcmp(type,"ship")==0) { sh.ship = ship_get(xml_get(node)); lua_pushship(L,sh); } else if (strcmp(type,"time")==0) { lt.t = xml_getLong(node); lua_pushtime(L,lt); } else { WARN("Unknown lua data type!"); lua_pop(L,1); return -1; } /* Set field. */ lua_settable(L, -3); /* cleanup */ free(type); free(name); } } while (xml_nextNode(node)); return 0; }