mirror of
https://github.com/DarkflameUniverse/DarkflameServer
synced 2024-08-30 18:43:58 +00:00
fix: Dismantling basically being O(n!) (#1295)
This commit is contained in:
parent
59303a232e
commit
8b270ca97a
@ -2708,7 +2708,7 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent
|
|||||||
PropertyManagementComponent::Instance()->AddModel(newEntity->GetObjectID(), newIDL);
|
PropertyManagementComponent::Instance()->AddModel(newEntity->GetObjectID(), newIDL);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameMessages::HandlePropertyEntranceSync(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) {
|
void GameMessages::HandlePropertyEntranceSync(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) {
|
||||||
@ -5441,10 +5441,8 @@ void GameMessages::HandleRemoveItemFromInventory(RakNet::BitStream* inStream, En
|
|||||||
iStackCount = std::min<uint32_t>(item->GetCount(), iStackCount);
|
iStackCount = std::min<uint32_t>(item->GetCount(), iStackCount);
|
||||||
|
|
||||||
if (bConfirmed) {
|
if (bConfirmed) {
|
||||||
for (auto i = 0; i < iStackCount; ++i) {
|
if (eInvType == eInventoryType::MODELS) {
|
||||||
if (eInvType == eInventoryType::MODELS) {
|
item->DisassembleModel(iStackCount);
|
||||||
item->DisassembleModel();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
item->SetCount(item->GetCount() - iStackCount, true);
|
item->SetCount(item->GetCount() - iStackCount, true);
|
||||||
|
@ -395,14 +395,13 @@ void Item::Disassemble(const eInventoryType inventoryType) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Item::DisassembleModel() {
|
void Item::DisassembleModel(uint32_t numToDismantle) {
|
||||||
auto* table = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
|
auto* table = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
|
||||||
|
|
||||||
const auto componentId = table->GetByIDAndType(GetLot(), eReplicaComponentType::RENDER);
|
const auto componentId = table->GetByIDAndType(GetLot(), eReplicaComponentType::RENDER);
|
||||||
|
|
||||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
auto query = CDClientDatabase::CreatePreppedStmt("SELECT render_asset, LXFMLFolder FROM RenderComponent WHERE id = ?;");
|
||||||
"SELECT render_asset, LXFMLFolder FROM RenderComponent WHERE id = ?;");
|
query.bind(1, static_cast<int>(componentId));
|
||||||
query.bind(1, (int)componentId);
|
|
||||||
|
|
||||||
auto result = query.execQuery();
|
auto result = query.execQuery();
|
||||||
|
|
||||||
@ -426,8 +425,6 @@ void Item::DisassembleModel() {
|
|||||||
|
|
||||||
std::istream file(&buffer);
|
std::istream file(&buffer);
|
||||||
|
|
||||||
result.finalize();
|
|
||||||
|
|
||||||
if (!file.good()) {
|
if (!file.good()) {
|
||||||
buffer.close();
|
buffer.close();
|
||||||
return;
|
return;
|
||||||
@ -438,39 +435,49 @@ void Item::DisassembleModel() {
|
|||||||
|
|
||||||
buffer.close();
|
buffer.close();
|
||||||
|
|
||||||
if (data.str().empty()) {
|
uint32_t fileSize;
|
||||||
|
file.seekg(0, std::ios::end);
|
||||||
|
fileSize = static_cast<uint32_t>(file.tellg());
|
||||||
|
file.seekg(0, std::ios::beg);
|
||||||
|
|
||||||
|
if (fileSize == 0) return;
|
||||||
|
|
||||||
|
tinyxml2::XMLDocument doc;
|
||||||
|
|
||||||
|
if (doc.Parse(data.str().c_str(), data.str().size()) != tinyxml2::XML_SUCCESS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<tinyxml2::XMLDocument> doc(new tinyxml2::XMLDocument());
|
auto* lxfml = doc.FirstChildElement("LXFML");
|
||||||
|
if (!lxfml) return;
|
||||||
if (!doc) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (doc->Parse(data.str().c_str(), data.str().size()) != 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<int> parts;
|
|
||||||
|
|
||||||
auto* lxfml = doc->FirstChildElement("LXFML");
|
|
||||||
auto* bricks = lxfml->FirstChildElement("Bricks");
|
auto* bricks = lxfml->FirstChildElement("Bricks");
|
||||||
std::string searchTerm = "Brick";
|
std::string searchTerm = "Brick";
|
||||||
|
|
||||||
if (!bricks) {
|
if (!bricks) {
|
||||||
searchTerm = "Part";
|
searchTerm = "Part";
|
||||||
bricks = lxfml->FirstChildElement("Scene")->FirstChildElement("Model")->FirstChildElement("Group");
|
auto* scene = lxfml->FirstChildElement("Scene");
|
||||||
|
if (!scene) return;
|
||||||
|
|
||||||
if (!bricks) {
|
auto* model = scene->FirstChildElement("Model");
|
||||||
return;
|
if (!model) return;
|
||||||
}
|
|
||||||
|
auto* group = model->FirstChildElement("Group");
|
||||||
|
if (!group) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* currentBrick = bricks->FirstChildElement(searchTerm.c_str());
|
auto* currentBrick = bricks->FirstChildElement(searchTerm.c_str());
|
||||||
|
|
||||||
|
// First iteration gets the count
|
||||||
|
std::map<int32_t, int32_t> parts;
|
||||||
while (currentBrick) {
|
while (currentBrick) {
|
||||||
if (currentBrick->Attribute("designID") != nullptr) {
|
auto* designID = currentBrick->Attribute("designID");
|
||||||
parts.push_back(std::stoi(currentBrick->Attribute("designID")));
|
if (designID) {
|
||||||
|
uint32_t designId;
|
||||||
|
if (!GeneralUtils::TryParse(designID, designId)) {
|
||||||
|
LOG("Failed to parse designID %s", designID);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
parts[designId]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentBrick = currentBrick->NextSiblingElement(searchTerm.c_str());
|
currentBrick = currentBrick->NextSiblingElement(searchTerm.c_str());
|
||||||
@ -478,16 +485,16 @@ void Item::DisassembleModel() {
|
|||||||
|
|
||||||
auto* brickIDTable = CDClientManager::Instance().GetTable<CDBrickIDTableTable>();
|
auto* brickIDTable = CDClientManager::Instance().GetTable<CDBrickIDTableTable>();
|
||||||
|
|
||||||
for (unsigned int part : parts) {
|
// Second iteration actually distributes the bricks
|
||||||
const auto brickID = brickIDTable->Query([=](const CDBrickIDTable& entry) {
|
for (const auto&[part, count] : parts) {
|
||||||
return entry.LEGOBrickID == part;
|
const auto partLocal = part;
|
||||||
|
const auto brickID = brickIDTable->Query([&](const CDBrickIDTable& entry) {
|
||||||
|
return entry.LEGOBrickID == partLocal;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (brickID.empty()) {
|
if (brickID.empty()) continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
GetInventory()->GetComponent()->AddItem(brickID[0].NDObjectID, 1, eLootSourceType::DELETION);
|
GetInventory()->GetComponent()->AddItem(brickID[0].NDObjectID, count * numToDismantle, eLootSourceType::DELETION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Disassembles this item into bricks
|
* Disassembles this item into bricks
|
||||||
*/
|
*/
|
||||||
void DisassembleModel();
|
void DisassembleModel(uint32_t numToDismantle);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the item from the linked inventory
|
* Removes the item from the linked inventory
|
||||||
|
Loading…
Reference in New Issue
Block a user