Kaynağa Gözat

set player char default pos for when manually loading a map

Paul 11 yıl önce
ebeveyn
işleme
a0e3ef8b73
1 değiştirilmiş dosya ile 69 ekleme ve 60 silme
  1. 69 60
      utilities/q-gears-launcher/src/ff7DataInstaller.cpp

+ 69 - 60
utilities/q-gears-launcher/src/ff7DataInstaller.cpp

@@ -456,6 +456,64 @@ static void FF7PcFieldToQGearsField(
         xmlMovementRotation->SetAttribute("degree", std::to_string(triggers->MovementRotation()));
         element->LinkEndChild(xmlMovementRotation.release());
 
+        // Get this fields Id
+        const size_t thisFieldId = FieldId(field->getName(), fieldIdToNameLookup);
+
+        // Use that to find the pre-computed list of gateways in all other fields that link to this field
+        auto spawnIterator = spawnMap.find(thisFieldId);
+
+        Ogre::Vector3 firstEntityPoint = Ogre::Vector3::ZERO;
+
+        // If not found that it probably just means no other fields have doors to this one
+        if (spawnIterator != std::end(spawnMap))
+        {
+            const std::vector<SpawnPointDb::Record>& spawnPointRecords = spawnIterator->second.mGatewaysToThisField;
+
+            for (size_t i = 0; i < spawnPointRecords.size(); i++)
+            {
+                const QGears::TriggersFile::Gateway& gateway = spawnPointRecords[i].mGateway;
+                // entity_point
+                std::unique_ptr<TiXmlElement> xmlEntityPoint(new TiXmlElement("entity_point"));
+
+                if (spawnPointRecords[i].mFromScript)
+                {
+                    // Spawn points from map jumps have a another algorithm
+                    xmlEntityPoint->SetAttribute("name", fieldIdToNameLookup.at(spawnPointRecords[i].mFieldId) + "_" + spawnPointRecords[i].mEntityName + "_" + spawnPointRecords[i].mScriptFunctionName + "_addr_" + std::to_string(spawnPointRecords[i].GatewayIndexOrMapJumpAddress));
+                }
+                else
+                {
+                    // Must also include the gateway index for the case where 2 fields have more than one door linking to each other
+                    xmlEntityPoint->SetAttribute("name", "Spawn_" + fieldIdToNameLookup.at(spawnPointRecords[i].mFieldId) + "_" + std::to_string(spawnPointRecords[i].GatewayIndexOrMapJumpAddress));
+                }
+
+                const float downscaler_next = 128.0f * FieldScaleFactor(scaleFactorMap, gateway.destinationFieldId);
+
+                // Position Z is actually the target walkmesh triangle ID, so this is tiny bit more
+                // complex as we have to say "get the Z value of the triangle with that ID". Note that ID actually just means index.
+                unsigned int triIndex = static_cast<unsigned int>(gateway.destination.z);
+                if (triIndex >= field->getWalkmesh()->getTriangles().size())
+                {
+                    std::cout << "WARNING MAP JUMP TRIANGLE OUT OF BOUNDS" << std::endl;
+                    triIndex = 0;
+                }
+                const float zOfTriangleWithId = field->getWalkmesh()->getTriangles().at(triIndex).a.z;
+
+                const Ogre::Vector3 posVec(gateway.destination.x / downscaler_next, gateway.destination.y / downscaler_next, zOfTriangleWithId);
+                if (posVec != Ogre::Vector3::ZERO && firstEntityPoint == Ogre::Vector3::ZERO)
+                {
+                    firstEntityPoint = posVec;
+                }
+
+                xmlEntityPoint->SetAttribute("position", Ogre::StringConverter::toString(posVec));
+
+                const float rotation = (360.0f * static_cast<float>(gateway.dir)) / 255.0f;
+                xmlEntityPoint->SetAttribute("rotation", std::to_string(rotation));
+
+                element->LinkEndChild(xmlEntityPoint.release());
+            }
+        }
+
+
         for (const auto& it : decompiled.entities)
         {
             const int charId = it.second;
@@ -477,13 +535,17 @@ static void FF7PcFieldToQGearsField(
                 QGears::StringUtil::toLowerCase(lowerCaseHrcName);
                 xmlEntityScript->SetAttribute("file_name", FieldModelDir() + "/" + modelAnimationDb.ModelMetaDataName(lowerCaseHrcName));
 
-                // TODO: entity_model - name, file_name,  position, direction
-                // We set char 1 position to be position of first entity_point so player is spawned in sane
-                // position if map is manually loaded via console.
-                // None player chars set their first position in the init scripts. We know its a entity_model
-                // because it uses PC opcode in init script.
-                // entity_manager:get_entity("cl") is done via CHAR opcode
-                xmlEntityScript->SetAttribute("position", "0 0 0");
+                if (desc.type == QGears::ModelListFile::PLAYER)
+                {
+                    // For player models we set the position in the xml because if a map is loaded manually this is where the player
+                    // will end up. Hence we set the position to the first entity_point that we have
+                    xmlEntityScript->SetAttribute("position", Ogre::StringConverter::toString(firstEntityPoint));
+                }
+                else
+                {
+                    xmlEntityScript->SetAttribute("position", Ogre::StringConverter::toString(Ogre::Vector3::ZERO));
+                }
+
 
                 xmlEntityScript->SetAttribute("direction", "0");
 
@@ -503,8 +565,6 @@ static void FF7PcFieldToQGearsField(
             }
         }
 
-        // Get this fields Id
-        const size_t thisFieldId = FieldId(field->getName(), fieldIdToNameLookup);
 
         const float downscaler_this = 128.0f * FieldScaleFactor(scaleFactorMap, thisFieldId);
 
@@ -533,57 +593,6 @@ static void FF7PcFieldToQGearsField(
             }
         }
 
-
-        // Use that to find the pre-computed list of gateways in all other fields that link to this field
-        auto spawnIterator = spawnMap.find(thisFieldId);
-
-        // If not found that it probably just means no other fields have doors to this one
-        if (spawnIterator != std::end(spawnMap))
-        {
-            const std::vector<SpawnPointDb::Record>& spawnPointRecords = spawnIterator->second.mGatewaysToThisField;
-
-            for (size_t i = 0; i < spawnPointRecords.size(); i++)
-            {
-                const QGears::TriggersFile::Gateway& gateway = spawnPointRecords[i].mGateway;
-                // entity_point
-                std::unique_ptr<TiXmlElement> xmlEntityPoint(new TiXmlElement("entity_point"));
-
-                if (spawnPointRecords[i].mFromScript)
-                {
-                    // Spawn points from map jumps have a another algorithm
-                    
-
-                    xmlEntityPoint->SetAttribute("name", fieldIdToNameLookup.at(spawnPointRecords[i].mFieldId) + "_" + spawnPointRecords[i].mEntityName + "_" + spawnPointRecords[i].mScriptFunctionName + "_addr_" + std::to_string(spawnPointRecords[i].GatewayIndexOrMapJumpAddress));
-                }
-                else
-                {
-                    // Must also include the gateway index for the case where 2 fields have more than one door linking to each other
-                    xmlEntityPoint->SetAttribute("name", "Spawn_" + fieldIdToNameLookup.at(spawnPointRecords[i].mFieldId) + "_" + std::to_string(spawnPointRecords[i].GatewayIndexOrMapJumpAddress));
-                }
-
-                const float downscaler_next = 128.0f * FieldScaleFactor(scaleFactorMap, gateway.destinationFieldId);
-
-                // Position Z is actually the target walkmesh triangle ID, so this is tiny bit more
-                // complex as we have to say "get the Z value of the triangle with that ID". Note that ID actually just means index.
-                unsigned int triIndex = static_cast<unsigned int>(gateway.destination.z);
-                if (triIndex >= field->getWalkmesh()->getTriangles().size())
-                {
-                    std::cout << "WARNING MAP JUMP TRIANGLE OUT OF BOUNDS" << std::endl;
-                    triIndex = 0;
-                }
-                const float zOfTriangleWithId = field->getWalkmesh()->getTriangles().at(triIndex).a.z;
-
-                const Ogre::Vector3 posVec(gateway.destination.x / downscaler_next, gateway.destination.y / downscaler_next, zOfTriangleWithId);
-
-                xmlEntityPoint->SetAttribute("position", Ogre::StringConverter::toString(posVec));
-
-                const float rotation = (360.0f * static_cast<float>(gateway.dir)) / 255.0f;
-                xmlEntityPoint->SetAttribute("rotation", std::to_string(rotation));
-
-                element->LinkEndChild(xmlEntityPoint.release());
-            }
-        }
-
         doc.LinkEndChild(element.release());
         doc.SaveFile(outDir + "/" + FieldMapDir() + "/" + field->getName() + "/map.xml");