/**\brief Configure the ship's weapon slots based on the XML node weaponSlots. */ bool Model::ConfigureWeaponSlots( xmlDocPtr doc, xmlNodePtr node ) { xmlNodePtr slotPtr; string value; //if( (slotPtr = FirstChildNamed(node,"slot")) ){ for( slotPtr = FirstChildNamed(node,"slot"); slotPtr != NULL; slotPtr = NextSiblingNamed(slotPtr,"slot") ){ WeaponSlot newSlot; xmlNodePtr attr; if( (attr = FirstChildNamed(slotPtr,"name")) ){ value = NodeToString(doc,attr); newSlot.name = value; } else return false; if( (attr = FirstChildNamed(slotPtr,"coord")) ){ value = NodeToString(doc,attr); // go deeper... xmlNodePtr coordAttr; if( (coordAttr = FirstChildNamed(attr,"x")) ){ newSlot.x = NodeToInt(doc,coordAttr); } else return false; if( (coordAttr = FirstChildNamed(attr,"y")) ){ newSlot.y = NodeToInt(doc,coordAttr); } else return false; } else return false; if( (attr = FirstChildNamed(slotPtr,"angle")) ){ newSlot.angle = NodeToFloat(doc,attr); } else return false; if( (attr = FirstChildNamed(slotPtr,"motionAngle")) ){ value = NodeToString(doc,attr); newSlot.motionAngle = atof(value.c_str()); } else return false; if( (attr = FirstChildNamed(slotPtr,"content")) ){ // this check is necessary because NodeToString() won't translate <item></item> into "" if(attr->xmlChildrenNode) value = NodeToString(doc,attr); else value = ""; // slot is empty newSlot.content = Menu::GetCurrentScenario()->GetWeapons()->GetWeapon( value ); } else return false; if( (attr = FirstChildNamed(slotPtr,"firingGroup")) ){ newSlot.firingGroup = NodeToInt(doc,attr); } else return false; weaponSlots.push_back(newSlot); } return true; }
/**\brief Extract this PlayerInfo from an XML Node * \param[in] doc The XML document. * \param[in] xnode The XML Node. * \returns true if the PlayerInfo was loaded correctly. */ bool PlayerInfo::FromXMLNode( xmlDocPtr doc, xmlNodePtr node ) { xmlNodePtr attr; // If the node has a Model then it is using the old format. // Create that player's XML File before continuing if( (attr = FirstChildNamed(node,"model")) ) { node = ConvertOldVersion( doc, node ); } // The file attribute is the saved game xml file. if( (attr = FirstChildNamed(node,"file")) ) { file = NodeToString(doc,attr); if( File::Exists( file ) == false ) { LogMsg(ERR, "Player %s is Corrupt. There is no file '%s'.", name.c_str(), file.c_str() ); return false; } } else { LogMsg(ERR, "Player %s is Corrupt. There is no file attribute.", name.c_str() ); return false; } // A corrupt avatar isn't fatal, just don't try to draw it. if( (attr = FirstChildNamed(node,"avatar")) ){ avatar = Image::Get( NodeToString(doc,attr) ); if( avatar == NULL ) { LogMsg(WARN, "Player %s has a corrupt avatar. There is no image '%s' ", name.c_str(), NodeToString(doc,attr).c_str() ); } } if( (attr = FirstChildNamed(node,"simulation")) ){ simulation = NodeToString(doc,attr); } else { simulation = "default"; } if( (attr = FirstChildNamed(node,"seed")) ){ seed = NodeToInt(doc,attr); } else { seed = 0; } // A corrupt lastLoadTime isn't fatal, just use January 1, 1970. if( (attr = FirstChildNamed(node,"lastLoadTime")) ){ lastLoadTime = NodeToInt(doc,attr); } else { lastLoadTime = (time_t)0; } return true; }
Mission* Mission::FromXMLNode( xmlDocPtr doc, xmlNodePtr node ) { string type; int version = 0;; int missionTable; xmlNodePtr typeNode = FirstChildNamed(node,"type"); xmlNodePtr versionNode = FirstChildNamed(node,"version"); xmlNodePtr missionNode = FirstChildNamed(node,"value"); type = NodeToString(doc, typeNode); if( versionNode != NULL ) { version = NodeToInt(doc, versionNode); } lua_State *L = Lua::CurrentState(); // Turn the XML data into a Table Lua::ConvertFromXML(L, doc, missionNode); // pop the name off the top of the stack. It should just be "missionTable" anyway. assert(lua_istable(L,lua_gettop(L))); // Gets and pops the top of the stack, which should have the the missionTable. missionTable = luaL_ref(L, LUA_REGISTRYINDEX); assert(lua_isstring(L,lua_gettop(L))); lua_pop(L,1); // Pop the Name // Validate this Mission if( !Mission::ValidateMission(L, type, missionTable, version) ) { LogMsg(ERR, "Something important!"); return NULL; } return new Mission(L, type, missionTable); }
/**\brief Parses weapon information */ bool Weapon::FromXMLNode( xmlDocPtr doc, xmlNodePtr node ) { xmlNodePtr attr; string value; if( (attr = FirstChildNamed(node,"weaponType")) ){ weaponType = (short int)NodeToInt(doc,attr); } else { LogMsg(ERR,"Could not find child node weaponType while searching component"); return false; } if( (attr = FirstChildNamed(node,"imageName")) ){ image = Image::Get( NodeToString(doc,attr) ); } else { LogMsg(ERR,"Could not find child node imageName while searching component"); return false; } if( (attr = FirstChildNamed(node,"picName")) ){ Image* pic = Image::Get( NodeToString(doc,attr) ); // This image can be accessed by either the path or the Weapon Name Image::Store(name, pic); SetPicture(pic); } else { LogMsg(ERR,"Could not find child node picName while searching component"); return false; } if( (attr = FirstChildNamed(node,"description")) ){ value = NodeToString(doc,attr); SetDescription( value ); } else { LogMsg( WARN, "%s does not have a description.", GetName().c_str() ); } if( (attr = FirstChildNamed(node,"payload")) ){ payload = NodeToInt(doc,attr); } else { LogMsg(ERR,"Could not find child node payload while searching component"); return false; } if( (attr = FirstChildNamed(node,"velocity")) ){ velocity = NodeToInt(doc,attr); } else { LogMsg(ERR,"Could not find child node velocity while searching component"); return false; } if( (attr = FirstChildNamed(node,"acceleration")) ){ acceleration = NodeToInt(doc,attr); } else { LogMsg(ERR,"Could not find child node acceleration while searching component"); return false; } if( (attr = FirstChildNamed(node,"ammoType")) ){ value = NodeToString(doc,attr); ammoType = AmmoNameToType(value); if(ammoType>=max_ammo) { LogMsg(ERR,"ammoType is >= max_ammo in Weapons XML parsing"); return false; } } else { LogMsg(ERR,"Could not find child node ammoType while searching component"); return false; } if( (attr = FirstChildNamed(node,"ammoConsumption")) ){ ammoConsumption = NodeToInt(doc,attr); } else { LogMsg(ERR,"Could not find child node ammoConsumption while searching component"); return false; } if( (attr = FirstChildNamed(node, "fireDelay")) ) { fireDelay = NodeToInt(doc,attr); } else { LogMsg(ERR, "Could not find child node fireDelay while searching component"); return false; } if( (attr = FirstChildNamed(node, "lifetime")) ) { lifetime = NodeToInt(doc,attr); } else { LogMsg(ERR, "Could not find child node lifetime while searching component"); return false; } if( (attr = FirstChildNamed(node,"tracking")) ) { float _tracking = NodeToFloat(doc,attr); if (_tracking > 1.0f ) _tracking = 1.0f; if (_tracking < 0.0001f ) _tracking = 0.0f; tracking = _tracking; } else { LogMsg(ERR, "Could not find child node tracking while searching component"); return false; } if( (attr = FirstChildNamed(node, "msrp")) ) { value = NodeToString(doc,attr); SetMSRP( (short int)atoi( value.c_str() )); } else { LogMsg(ERR, "Could not find child node msrp while searching component"); return false; } if( (attr = FirstChildNamed(node, "sound")) ) { value = NodeToString(doc,attr); this->sound = Sound::Get( value ); if( this->sound == NULL) { // Do not return false here - they may be disabling audio on purpose or audio may not be supported on their system LogMsg(WARN, "Could not load sound file while searching component"); } } else { LogMsg(ERR, "Could not find child node sound while searching component"); return false; } return true; }
/**\brief Parse one player out of an xml node */ bool Player::FromXMLNode( xmlDocPtr doc, xmlNodePtr node ) { xmlNodePtr attr; string value; Coordinate pos; if( (attr = FirstChildNamed(node,"name")) ){ SetName(NodeToString(doc,attr)); } if( (attr = FirstChildNamed(node, "planet"))){ string temp; xmlNodePtr name = FirstChildNamed(attr,"name"); lastPlanet = NodeToString(doc,name); Planet* p = Planets::Instance()->GetPlanet( lastPlanet ); if( p != NULL ) { SetWorldPosition( p->GetWorldPosition() ); } }else return false; if( (attr = FirstChildNamed(node,"model")) ){ value = NodeToString(doc,attr); Model* model = Models::Instance()->GetModel( value ); if( NULL!=model) { SetModel( model ); } else { LogMsg(ERR,"No such model as '%s'", value.c_str()); return false; } } else return false; if( (attr = FirstChildNamed(node,"engine")) ){ value = NodeToString(doc,attr); Engine* engine = Engines::Instance()->GetEngine( value ); if( NULL!=engine) { SetEngine( engine ); } else { LogMsg(ERR,"No such engine as '%s'", value.c_str()); return false; } } else return false; if( (attr = FirstChildNamed(node,"credits")) ){ value = NodeToString(doc,attr); SetCredits( atoi(value.c_str()) ); } else return false; for( attr = FirstChildNamed(node,"weapon"); attr!=NULL; attr = NextSiblingNamed(attr,"weapon") ){ AddShipWeapon( NodeToString(doc,attr) ); } for( attr = FirstChildNamed(node,"outfit"); attr!=NULL; attr = NextSiblingNamed(attr,"outfit") ){ AddOutfit( NodeToString(doc,attr) ); } for( attr = FirstChildNamed(node,"cargo"); attr!=NULL; attr = NextSiblingNamed(attr,"cargo") ){ xmlNodePtr type = FirstChildNamed(attr,"type"); xmlNodePtr ammt = FirstChildNamed(attr,"amount"); if(!type || !ammt) return false; if( NodeToInt(doc,ammt) > 0 ) { StoreCommodities( NodeToString(doc,type), NodeToInt(doc,ammt) ); } } for( attr = FirstChildNamed(node,"ammo"); attr!=NULL; attr = NextSiblingNamed(attr,"ammo") ){ xmlNodePtr type = FirstChildNamed(attr,"type"); xmlNodePtr ammt = FirstChildNamed(attr,"amount"); if(!type || !ammt) return false; AmmoType ammoType = Weapon::AmmoNameToType( NodeToString(doc,type) ); int ammoCount = NodeToInt(doc,ammt); if( ammoType < max_ammo ) { AddAmmo( ammoType, ammoCount ); } else return false; } for( attr = FirstChildNamed(node,"Mission"); attr!=NULL; attr = NextSiblingNamed(attr,"Mission") ){ Mission *mission = Mission::FromXMLNode(doc,attr); if( mission != NULL ) { LogMsg(INFO, "Successfully loaded the %s mission of player '%s'", mission->GetName().c_str(), this->GetName().c_str() ); missions.push_back( mission ); } else { LogMsg(INFO, "Aborted loading mission of player '%s'", this->GetName().c_str() ); } } for( attr = FirstChildNamed(node,"favor"); attr!=NULL; attr = NextSiblingNamed(attr,"favor") ){ xmlNodePtr alliance = FirstChildNamed(attr,"alliance"); xmlNodePtr value = FirstChildNamed(attr,"value"); if(!alliance || !value) return false; if( NodeToInt(doc,value) > 0 ) { UpdateFavor( NodeToString(doc,alliance), NodeToInt(doc,value) ); } } for( attr = FirstChildNamed(node,"hiredEscort"); attr!=NULL; attr = NextSiblingNamed(attr,"hiredEscort") ){ xmlNodePtr typePtr = FirstChildNamed(attr, "type"); xmlNodePtr payPtr = FirstChildNamed(attr, "pay"); assert(typePtr && payPtr); if(!typePtr || !payPtr) return false; string type = NodeToString(doc, typePtr); int pay = atoi( NodeToString(doc, payPtr).c_str() ); // Adding it with sprite ID -1 means it's up to player.lua to go ahead and create the correct sprite. this->AddHiredEscort(type, pay, -1); } if(this->ConfigureWeaponSlots(doc, node)){ // great - it worked LogMsg( INFO, "Successfully loaded weapon slots"); } else { LogMsg( ERR, "Weapon slot XML helper failed to configure weapon slots"); } if( (attr = FirstChildNamed(node,"lastLoadTime")) ){ lastLoadTime = NodeToInt(doc,attr); } else { lastLoadTime = (time_t)0; } RemoveLuaControlFunc(); return true; }
/**\brief Load an XML file * \arg filename The XML file that should be parsed. * \arg optional If this is true, an error is not returned if the file doesn't exist. */ bool Components::Load(string filename, bool optional) { xmlDocPtr doc; xmlNodePtr cur, ver; int versionMajor = 0, versionMinor = 0, versionMacro = 0; int numObjs = 0; bool success = true; File xmlfile = File (filename); long filelen = xmlfile.GetLength(); char *buffer = xmlfile.Read(); doc = xmlParseMemory( buffer, static_cast<int>(filelen) ); delete [] buffer; if( doc == NULL ) { LogMsg(ERR, "Could not load '%s' for parsing.", filename.c_str() ); return optional; } cur = xmlDocGetRootElement( doc ); if( cur == NULL ) { LogMsg(ERR, "'%s' file appears to be empty.", filename.c_str() ); xmlFreeDoc( doc ); return false; } if( xmlStrcmp( cur->name, (const xmlChar *)rootName.c_str() ) ) { LogMsg(ERR, "'%s' appears to be invalid. Root element was %s.", filename.c_str(), (char *)cur->name ); xmlFreeDoc( doc ); return false; } else { LogMsg(INFO, "'%s' file found and valid, parsing...", filename.c_str() ); } // Get the version number if( (ver = FirstChildNamed(cur, "version-major")) != NULL ) { versionMajor = NodeToInt(doc,ver); } if( (ver = FirstChildNamed(cur, "version-minor")) != NULL ) { versionMinor = NodeToInt(doc,ver); } if( (ver = FirstChildNamed(cur, "version-macro")) != NULL ) { versionMacro = NodeToInt(doc,ver); } if( ( versionMajor != EPIAR_VERSION_MAJOR ) || ( versionMinor != EPIAR_VERSION_MINOR ) || ( versionMacro != EPIAR_VERSION_MICRO ) ) { LogMsg(WARN, "File '%s' is version %d.%d.%d. This may cause problems since it does not match the current version %d.%d.%d.", filename.c_str(), versionMajor, versionMinor, versionMacro, EPIAR_VERSION_MAJOR, EPIAR_VERSION_MINOR, EPIAR_VERSION_MICRO ); } // Get the components cur = cur->xmlChildrenNode; while( success && cur != NULL ) { // Parse for the version information and any children nodes if( ( !xmlStrcmp( cur->name, BAD_CAST componentName.c_str() ) ) ) { // Parse a Component success = ParseXMLNode( doc, cur ); assert(success || optional); if(success) numObjs++; } cur = cur->next; } xmlFreeDoc( doc ); filepath = filename; LogMsg(INFO, "Parsing of file '%s' done, found %d objects. File is version %d.%d.%d.", filename.c_str(), numObjs, versionMajor, versionMinor, versionMacro ); return success; }