diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index a814c0001..0bbd9a11f 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -5119,6 +5119,10 @@ void GameMessages::HandleModularBuildConvertModel(RakNet::BitStream* inStream, E item->Disassemble(TEMP_MODELS); + std::unique_ptr stmt(Database::CreatePreppedStmt("DELETE FROM ugc_modular_build where ugc_id = ?")); + stmt->setUInt64(1, item->GetSubKey()); + stmt->execute(); + item->SetCount(item->GetCount() - 1, false, false, true, eLootSourceType::QUICKBUILD); } @@ -5564,13 +5568,6 @@ void GameMessages::HandleModularBuildFinish(RakNet::BitStream* inStream, Entity* InventoryComponent* inv = static_cast(character->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; - LOG("Build finished"); - - GameMessages::SendFinishArrangingWithItem(character, entity->GetObjectID()); // kick them from modular build - GameMessages::SendModularBuildEnd(character); // i dont know if this does anything but DLUv2 did it - - //inv->UnequipItem(inv->GetItemStackByLOT(6086, eInventoryType::ITEMS)); // take off the thinking cap - //Game::entityManager->SerializeEntity(entity); uint8_t count; // 3 for rockets, 7 for cars @@ -5605,50 +5602,61 @@ void GameMessages::HandleModularBuildFinish(RakNet::BitStream* inStream, Entity* } } - const auto moduleAssembly = new LDFData(u"assemblyPartLOTs", modules); + ObjectIDManager::Instance()->RequestPersistentID([=](uint32_t newId) { + LOG("Build finished"); + GameMessages::SendFinishArrangingWithItem(character, entity->GetObjectID()); // kick them from modular build + GameMessages::SendModularBuildEnd(character); // i dont know if this does anything but DLUv2 did it - std::vector config; - config.push_back(moduleAssembly); + //inv->UnequipItem(inv->GetItemStackByLOT(6086, eInventoryType::ITEMS)); // take off the thinking cap + //Game::entityManager->SerializeEntity(entity); - LWOOBJID newIdBig; - // Make sure a subkey isnt already in use. Persistent Ids do not make sense here since this only needs to be unique for - // this character. Because of that, we just generate a random id and check for a collision. - do { - newIdBig = ObjectIDManager::Instance()->GenerateRandomObjectID(); + const auto moduleAssembly = new LDFData(u"assemblyPartLOTs", modules); + + std::vector config; + config.push_back(moduleAssembly); + + LWOOBJID newIdBig = newId; GeneralUtils::SetBit(newIdBig, eObjectBits::CHARACTER); - } while (inv->FindItemBySubKey(newIdBig)); - if (count == 3) { - inv->AddItem(6416, 1, eLootSourceType::QUICKBUILD, eInventoryType::MODELS, config, LWOOBJID_EMPTY, true, false, newIdBig); - } else if (count == 7) { - inv->AddItem(8092, 1, eLootSourceType::QUICKBUILD, eInventoryType::MODELS, config, LWOOBJID_EMPTY, true, false, newIdBig); - } + if (count == 3) { + inv->AddItem(6416, 1, eLootSourceType::QUICKBUILD, eInventoryType::MODELS, config, LWOOBJID_EMPTY, true, false, newIdBig); + } else if (count == 7) { + inv->AddItem(8092, 1, eLootSourceType::QUICKBUILD, eInventoryType::MODELS, config, LWOOBJID_EMPTY, true, false, newIdBig); + } + + std::unique_ptr stmt(Database::CreatePreppedStmt("INSERT INTO ugc_modular_build (ugc_id, ldf_config, character_id) VALUES (?,?,?)")); + stmt->setUInt64(1, newIdBig); + stmt->setString(2, GeneralUtils::UTF16ToWTF8(modules)); + auto* pCharacter = character->GetCharacter(); + pCharacter ? stmt->setUInt(3, pCharacter->GetID()) : stmt->setNull(3, sql::DataType::BIGINT); + stmt->execute(); - auto* missionComponent = character->GetComponent(); + auto* missionComponent = character->GetComponent(); - if (entity->GetLOT() != 9980 || Game::server->GetZoneID() != 1200) { - if (missionComponent != nullptr) { - missionComponent->Progress(eMissionTaskType::SCRIPT, entity->GetLOT(), entity->GetObjectID()); - if (count >= 7 && everyPieceSwapped) missionComponent->Progress(eMissionTaskType::RACING, LWOOBJID_EMPTY, (LWOOBJID)eRacingTaskParam::MODULAR_BUILDING); + if (entity->GetLOT() != 9980 || Game::server->GetZoneID() != 1200) { + if (missionComponent != nullptr) { + missionComponent->Progress(eMissionTaskType::SCRIPT, entity->GetLOT(), entity->GetObjectID()); + if (count >= 7 && everyPieceSwapped) missionComponent->Progress(eMissionTaskType::RACING, LWOOBJID_EMPTY, (LWOOBJID)eRacingTaskParam::MODULAR_BUILDING); + } } - } - } - ScriptComponent* script = static_cast(entity->GetComponent(eReplicaComponentType::SCRIPT)); + ScriptComponent* script = static_cast(entity->GetComponent(eReplicaComponentType::SCRIPT)); - for (CppScripts::Script* script : CppScripts::GetEntityScripts(entity)) { - script->OnModularBuildExit(entity, character, count >= 3, modList); - } + for (CppScripts::Script* script : CppScripts::GetEntityScripts(entity)) { + script->OnModularBuildExit(entity, character, count >= 3, modList); + } - // Move remaining temp models back to models - std::vector items; + // Move remaining temp models back to models + std::vector items; - for (const auto& pair : temp->GetItems()) { - items.push_back(pair.second); - } + for (const auto& pair : temp->GetItems()) { + items.push_back(pair.second); + } - for (auto* item : items) { - inv->MoveItemToInventory(item, eInventoryType::MODELS, item->GetCount(), false); + for (auto* item : items) { + inv->MoveItemToInventory(item, eInventoryType::MODELS, item->GetCount(), false); + } + }); } } diff --git a/migrations/dlu/12_modular_build_ugc.sql b/migrations/dlu/12_modular_build_ugc.sql new file mode 100644 index 000000000..68e417bf4 --- /dev/null +++ b/migrations/dlu/12_modular_build_ugc.sql @@ -0,0 +1,5 @@ +CREATE TABLE IF NOT EXISTS ugc_modular_build ( + ugc_id BIGINT NOT NULL PRIMARY KEY, + character_id BIGINT NOT NULL REFERENCES charinfo(id) ON DELETE CASCADE, + ldf_config VARCHAR(60) NOT NULL +);