void CLoader::LoadAll(const CHAR** pcPaths, UINT uCount) { UINT uType; if( ALCHEMY_GET_EVENT_TYPE(uType, LOAD_COMPLETE, CLoader) ) { CLoaderListener* pListener; if(m_uFreeListenerCount) pListener = m_FreeListeners[-- m_uFreeListenerCount]; else { ALCHEMY_DEBUG_NEW( pListener, CLoaderListener(*this) ); m_Listeners.Add(pListener); } pListener->Reset(pcPaths, uCount); AddEventListener(uType, *pListener); CMap<STRING, bool, STRINGLESS> PathMap; const CHAR* pcPath; bool* pbIsCommonPath; for(UINT i = 0; i < uCount; ++ i) { pcPath = pcPaths[i]; pbIsCommonPath = PathMap.Get(pcPath); if(!pbIsCommonPath) { PathMap.Insert(pcPath, true); Load(pcPath); } } } }
int CConverter::LoadMapMTA(std::string const &strName, bool callPawnFunctions) { // Map object CMap* pMap = NULL; int id = mapUpperID++; std::string strMapName; char szPath[MAX_PATH]; if (strName.find_first_of("scriptfiles") != 0) { strMapName = strName; sprintf(szPath, "scriptfiles/maps/MTA/%s", strName.c_str()); } else { strMapName = strName.substr(strName.find_last_of("\\") + 1, strName.length()); strcpy(szPath, strName.c_str()); } //logprintf("path: %s, mapname: %s, id %d", szPath, strMapName.c_str(), mapUpperID); pMap = new CMap(strMapName); maps.emplace(id, pMap); mapNames.emplace(strMapName, id); // Load the map file pugi::xml_document doc; pugi::xml_parse_result result = doc.load_file(szPath); //logprintf("value: %s", doc.child("map").attribute("mod").value()); // If MTA:DM map const pugi::xml_node &mapNode = doc.child("map"); if(mapNode.attribute("edf:definitions").value()[0] || !strcmp(mapNode.attribute("mod").value(), "deathmatch")) { pMap->mapType = MTA_DM; CCallbackManager::OnMapLoadingStart(id, pMap, callPawnFunctions); for (auto it : mapNode) { // objects if(!strcmp(it.name(), "object")) { object_t *object = new object_t; object->wModelID = static_cast<WORD>(it.attribute("model").as_int()); object->vecPos.fX = it.attribute("posX").as_float(); object->vecPos.fY = it.attribute("posY").as_float(); object->vecPos.fZ = it.attribute("posZ").as_float(); object->vecRot.fX = it.attribute("rotX").as_float(); object->vecRot.fY = it.attribute("rotY").as_float(); object->vecRot.fZ = it.attribute("rotZ").as_float(); object->byteInterior = static_cast<BYTE>(it.attribute("interior").as_int()); object->iWorld = it.attribute("dimension").as_int(); object->ucAlpha = static_cast<BYTE>(it.attribute("alpha").as_int()); object->strName = it.attribute("id").value(); // Call our own callback if (callPawnFunctions) object->extraID = CCallbackManager::OnObjectDataLoaded(id, object); pMap->Insert(object); } // remove objects if(!strcmp(it.name(), "removeWorldObject")) { removeobject_t *removeobject = new removeobject_t; removeobject->wModelID = static_cast<WORD>(it.attribute("model").as_int()); WORD usLOD = static_cast<WORD>(it.attribute("lodModel").as_int()); removeobject->vecPos.fX = it.attribute("posX").as_float(); removeobject->vecPos.fY = it.attribute("posY").as_float(); removeobject->vecPos.fZ = it.attribute("posZ").as_float(); removeobject->fRadius = it.attribute("radius").as_float(); // Call our own callback if (callPawnFunctions) removeobject->extraID = CCallbackManager::OnRemoveObjectDataLoaded(id, removeobject); pMap->Insert(removeobject); // If model has LOD model, then push it too to the vector with same parameters if(usLOD) { // Call our own callback if (callPawnFunctions) removeobject->extraID = CCallbackManager::OnRemoveObjectDataLoaded(id, removeobject); else removeobject->extraID = 0; pMap->Insert(removeobject); } } // vehicle if(!strcmp(it.name(), "vehicle") || !strcmp(it.name(), "spawnpoint")) { vehicle_t *vehicle = new vehicle_t; // Default vehicle format from deathmatch resource if(!strcmp(it.name(), "vehicle")) { vehicle->wModelID = static_cast<WORD>(it.attribute("model").as_int()); vehicle->vecPos.fX = it.attribute("posX").as_float(); vehicle->vecPos.fY = it.attribute("posY").as_float(); vehicle->vecPos.fZ = it.attribute("posZ").as_float(); vehicle->fAngle = it.attribute("rotZ").as_float(); vehicle->strName = it.attribute("id").value(); } else // Another vehicle format, from race resource in MTA DM { vehicle->wModelID = static_cast<WORD>(it.attribute("vehicle").as_int()); vehicle->vecPos.fX = it.attribute("posX").as_float(); vehicle->vecPos.fY = it.attribute("posY").as_float(); vehicle->vecPos.fZ = it.attribute("posZ").as_float(); vehicle->fAngle = it.attribute("rotZ").as_float(); vehicle->strName = it.attribute("name").value(); } // If color attribute is present if(it.attribute("color")) { BYTE ucColorByte[12]; BYTE i = 1; // Extract colors from string to array ucColorByte[0] = static_cast<BYTE>(atoi(strtok((char*)it.attribute("color").value(), ","))); for( ; i != 12; i++) { char *szRet = strtok(NULL, ","); if(!szRet) break; ucColorByte[i] = static_cast<BYTE>(atoi(szRet)); //logprintf("color %d - %d", i, ucColorByte[i]); } // New MTA - use HEX colors if(i > 4) { // Get GTA color ID from given hex color vehicle->iColor1 = (int)CUtils::GetPaletteIndexFromRGB(ucColorByte[0], ucColorByte[1], ucColorByte[2]); vehicle->iColor2 = (int)CUtils::GetPaletteIndexFromRGB(ucColorByte[3], ucColorByte[4], ucColorByte[5]); } else { vehicle->iColor1 = ucColorByte[0]; vehicle->iColor2 = ucColorByte[1]; } } else { vehicle->iColor1 = -1; vehicle->iColor2 = -1; } if(it.attribute("paintjob")) vehicle->ucPaintjob = static_cast<BYTE>(it.attribute("paintjob").as_int()); else vehicle->ucPaintjob = 3; // Extract vehicle upgrades from string to array memset(vehicle->iUpgrades, 0, sizeof(vehicle->iUpgrades)); if(it.attribute("upgrades")) { //logprintf("vantuning geci"); char szUpgrades[128]; strcpy(szUpgrades, it.attribute("upgrades").value()); vehicle->iUpgrades[0] = atoi(strtok(szUpgrades, ",")); for(BYTE i = 1; i != 14; i++) { char *szRet = strtok(NULL, ","); if(!szRet) break; vehicle->iUpgrades[i] = atoi(szRet); //logprintf("upgrades %d - %d", i, vehicle.iUpgrades[i]); } } if(it.attribute("plate")) strcpy(vehicle->szPlate, it.attribute("plate").value()); else vehicle->szPlate[0] = NULL; // If interior attribute is present if(it.attribute("interior")) vehicle->byteInterior = static_cast<BYTE>(it.attribute("interior").as_int()); else vehicle->byteInterior = 0; // If dimension attribute is present if(it.attribute("dimension")) vehicle->iWorld = static_cast<BYTE>(it.attribute("dimension").as_int()); else vehicle->iWorld = 0; // Call our own callback if (callPawnFunctions) vehicle->extraID = CCallbackManager::OnVehicleDataLoaded(id, vehicle); pMap->Insert(vehicle); } // marker if(!strcmp(it.name(), "marker")) { marker_t *marker = new marker_t; // "arrow", "checkpoint", "corona", "cylinder", "ring" switch (it.attribute("type").value()[1]) { // arrow case 'r': marker->type = marker_t::MarkerType::ARROW; break; case 'h': marker->type = marker_t::MarkerType::CHECKPOINT; break; case 'o': marker->type = marker_t::MarkerType::CORONA; break; case 'y': marker->type = marker_t::MarkerType::CYLINDER; break; case 'i': marker->type = marker_t::MarkerType::RING; break; } marker->vecPos.fX = it.attribute("posX").as_float(); marker->vecPos.fY = it.attribute("posY").as_float(); marker->vecPos.fZ = it.attribute("posZ").as_float(); marker->fSize = it.attribute("size").as_float(); std::string hexstring = std::string(it.attribute("color").as_string()).substr(1); marker->dwColor = std::strtoul(hexstring.c_str(), 0, 16); marker->byteInterior = static_cast<BYTE>(it.attribute("interior").as_int()); marker->iWorld = it.attribute("dimension").as_int(); marker->strName = it.attribute("id").value(); // Call our own callback if (callPawnFunctions) marker->extraID = CCallbackManager::OnMarkerDataLoaded(id, marker); pMap->Insert(marker); } // pickup if(!strcmp(it.name(), "pickup")) { pickup_t *pickup = new pickup_t; std::string strType = it.attribute("type").as_string(); // If it's a weapon if (IsNumeric(strType)) { WORD weaponid = CUtils::GetWeaponModel(it.attribute("type").as_int()); if (weaponid) pickup->wModelID = weaponid; else pickup->wModelID = static_cast<WORD>(it.attribute("type").as_int()); } else { if (strType == "health") pickup->wModelID = 1240; else if (strType == "armor") pickup->wModelID = 1242; } pickup->vecPos.fX = it.attribute("posX").as_float(); pickup->vecPos.fY = it.attribute("posY").as_float(); pickup->vecPos.fZ = it.attribute("posZ").as_float(); pickup->iWorld = it.attribute("dimension").as_int(); pickup->strName = it.attribute("id").value(); // Call our own callback if (callPawnFunctions) pickup->extraID = CCallbackManager::OnPickupDataLoaded(id, pickup); pMap->Insert(pickup); } // ped if (!strcmp(it.name(), "ped")) { ped_t *ped = new ped_t; ped->wModelID = static_cast<WORD>(it.attribute("model").as_int()); ped->vecPos.fX = it.attribute("posX").as_float(); ped->vecPos.fY = it.attribute("posY").as_float(); ped->vecPos.fZ = it.attribute("posZ").as_float(); ped->fAngle = it.attribute("rotZ").as_float(); ped->strName = it.attribute("id").value(); ped->iWorld = it.attribute("dimension").as_int(); // Call our own callback if (callPawnFunctions) ped->extraID = CCallbackManager::OnActorDataLoaded(id, ped); pMap->Insert(ped); } } } else { object_t object; vehicle_t vehicle; //logprintf("mta race map"); pMap->mapType = MTA_RACE; CCallbackManager::OnMapLoadingStart(id, pMap, callPawnFunctions); for (auto it : mapNode) { // object if(!strcmp(it.name(), "object")) { char *szPos = (char*)it.child_value("model"); if(!szPos) continue; object.wModelID = static_cast<WORD>(atoi(szPos)); if(!(szPos = strtok((char*)it.child_value("position"), " "))) continue; object.vecPos.fX = (float)atof(szPos); if(!(szPos = strtok(NULL, " "))) continue; object.vecPos.fY = (float)atof(szPos); if(!(szPos = strtok(NULL, " "))) continue; object.vecPos.fZ = (float)atof(szPos); if(!(szPos = strtok((char*)it.child_value("rotation"), " "))) continue; object.vecRot.fZ = CUtils::RadToDeg((float)atof(szPos)); if(!(szPos = strtok(NULL, " "))) continue; object.vecRot.fY = CUtils::RadToDeg((float)atof(szPos)); if(!(szPos = strtok(NULL, " "))) continue; object.vecRot.fX = CUtils::RadToDeg((float)atof(szPos)); object.byteInterior = 0; object.iWorld = 0; object.ucAlpha = 0xFF; object.strName = it.attribute("name").value(); // To avoid memory leaks object_t *pObject = new object_t; memcpy(pObject, &object, sizeof(object_t)); // Call our own callback if (callPawnFunctions) pObject->extraID = CCallbackManager::OnObjectDataLoaded(id, pObject); pMap->Insert(pObject); } if(!strcmp(it.name(), "spawnpoint")) { char *szPos = (char*)it.child_value("vehicle"); if(!szPos) continue; vehicle.wModelID = static_cast<WORD>(atoi(szPos)); if(!(szPos = strtok((char*)it.child_value("position"), " "))) continue;; vehicle.vecPos.fX = (float)atof(szPos); if(!(szPos = strtok(NULL, " "))) continue; vehicle.vecPos.fY = (float)atof(szPos); if(!(szPos = strtok(NULL, " "))) continue; vehicle.vecPos.fZ = (float)atof(szPos); if(!(szPos = (char*)it.child_value("rotation"))) continue; vehicle.fAngle = (float)atoi(szPos); vehicle.iColor1 = -1; vehicle.iColor2 = -1; vehicle.ucPaintjob = 3; memset(vehicle.iUpgrades, 0, sizeof(vehicle.iUpgrades)); vehicle.szPlate[0] = NULL; vehicle.byteInterior = 0; vehicle.iWorld = 0; vehicle.strName = it.attribute("name").value(); // To avoid memory leaks vehicle_t *pVehicle = new vehicle_t; memcpy(pVehicle, &vehicle, sizeof(vehicle_t)); // Call our own callback if (callPawnFunctions) pVehicle->extraID = CCallbackManager::OnVehicleDataLoaded(id, pVehicle); pMap->Insert(pVehicle); } } } CCallbackManager::OnMapLoadingFinish(id, pMap, callPawnFunctions, pMap->vectorObjects.size(), pMap->vectorRemoveObjects.size(), pMap->vectorVehicles.size(), pMap->vectorMarkers.size(), pMap->vectorPickups.size(), pMap->vectorPeds.size()); return id; }
// TODO - Fix rotations int CConverter::LoadMapIPL(std::string const &strName, bool callPawnFunctions) { // 17512, LODgwforum1_LAe, 0, 2737.75, -1760.0625, 26.2265625, 0, 0, -8.742277657e-008, 1, -1 CMap* pMap = NULL; int id = mapUpperID++; std::string strMapName; char szPath[MAX_PATH]; if (strName.find_first_of("scriptfiles") != 0) { strMapName = strName; sprintf(szPath, "scriptfiles/maps/MTA/%s", strName.c_str()); } else { strMapName = strName.substr(strName.find_last_of("\\") + 1, strName.length()); strcpy(szPath, strName.c_str()); } //logprintf("patch: %s, mapname: %s, id %d", szPath, strMapName.c_str(), mapUpperID); pMap = new CMap(strMapName); maps.emplace(id, pMap); mapNames.emplace(strMapName, id); pMap->mapType = GTA_IPL; CCallbackManager::OnMapLoadingStart(id, pMap, callPawnFunctions); std::ifstream IPLFile(szPath); std::string line; bool bInst; while(std::getline(IPLFile, line)) { if (line == "inst") bInst = true; if (bInst) { if (line == "end") bInst = false; } if(bInst) { int modelid; char szName[64]; int interior; CVector vecPos; quat_t quat; int lod; if(sscanf(line.c_str(), "%d, %s %d, %f, %f, %f, %lf, %lf, %lf, %lf, %d", &modelid, &szName, &interior, &vecPos.fX, &vecPos.fY, &vecPos.fZ, &quat.x, &quat.y, &quat.z, &quat.w, &lod)) { //logprintf("%d, %s %d, %f, %f, %f, %lf, %lf, %lf, %lf, %d", modelid, szName, interior, vecPos.fX, vecPos.fY, vecPos.fZ, // quat.x, quat.y, quat.z, quat.w, lod); object_t* object = new object_t; object->wModelID = modelid; object->vecPos = vecPos; CUtils::QuatToEuler(quat, object->vecRot); object->byteInterior = interior; object->iWorld = 0; object->ucAlpha = 0xFF; // Call our own callback if (callPawnFunctions) CCallbackManager::OnObjectDataLoaded(id, object); pMap->Insert(object); } } } CCallbackManager::OnMapLoadingFinish(id, pMap, callPawnFunctions, pMap->vectorObjects.size(), 0, 0, 0, 0, 0); IPLFile.close(); return true; }