/**\brief Load a player from a file. * \param[in] filename of a player's xml saved game. * \returns pointer to new Player instance. */ Player* Player::Load( string filename ) { xmlDocPtr doc; xmlNodePtr cur; Player* newPlayer = new Player(); File xmlfile = File (filename); long filelen = xmlfile.GetLength(); char *buffer = xmlfile.Read(); doc = xmlParseMemory( buffer, static_cast<int>(filelen) ); cur = xmlDocGetRootElement( doc ); newPlayer->FromXMLNode( doc, cur ); // We check the planet location at loadtime in case planet moved or lastPlanet changed. // This happens with --random-universe. TODO: Does this matter? random-universe was removed. Planet* p = Menu::GetCurrentScenario()->GetPlanets()->GetPlanet( newPlayer->lastPlanet ); if( p != NULL ) { newPlayer->SetWorldPosition( p->GetWorldPosition() ); } else { LogMsg(INFO, "There is no planet named: '%s'.", newPlayer->lastPlanet.c_str() ); } newPlayer->RemoveLuaControlFunc(); // We can't start the game with bad player Information assert( newPlayer->GetModelName() != "" ); assert( newPlayer->GetEngineName() != "" ); // Tell Lua to initialize these escorts. for(list<Player::HiredEscort*>::iterator iter_escort = newPlayer->hiredEscorts.begin(); iter_escort != newPlayer->hiredEscorts.end(); iter_escort++) { (*iter_escort)->Lua_Initialize( newPlayer->GetID(), newPlayer->GetWorldPosition() ); } // Remember this Player newPlayer->lastLoadTime = time(NULL); LogMsg(INFO, "Successfully loaded the player: '%s'.", newPlayer->GetName().c_str() ); LogMsg(INFO, "Loaded Player '%s' with Model='%s' Engine='%s' Credits = %d at (%.0f,%.0f).", newPlayer->GetName().c_str(), newPlayer->GetModel()->GetName().c_str(), newPlayer->GetEngine()->GetName().c_str(), newPlayer->GetCredits(), newPlayer->GetWorldPosition().GetX(), newPlayer->GetWorldPosition().GetY() ); return newPlayer; }
/**\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; }