/** * @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; }
/** * @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, *ctmp; glColour *col; 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")) { ctmp = xml_getStrd(node); if (ctmp != NULL) temp->colour = col_fromName(xml_raw(node)); /* If no named colour is present, RGB attributes are used. */ else { /* Initialize in case a colour channel is absent. */ col = calloc( 1, sizeof(glColour*) ); xmlr_attr(node,"r",ctmp); if (ctmp != NULL) { col->r = atof(ctmp); free(ctmp); } xmlr_attr(node,"g",ctmp); if (ctmp != NULL) { col->g = atof(ctmp); free(ctmp); } xmlr_attr(node,"b",ctmp); if (ctmp != NULL) { col->b = atof(ctmp); free(ctmp); } col->a = 1.; temp->colour = col; } 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; }