mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Fix DBC loading and bank drag-and-drop reliability
- Force binary loading for SkillLine.dbc (CSV exports are garbled) - Handle quoted numeric values in DBC CSV parser - Fix bank slot drag-and-drop to use mouse-release detection instead of click detection, preventing item drops on wrong slots - Fix action bar item drop to use hoveredOnRelease for consistency
This commit is contained in:
parent
5cb469e318
commit
25412ff5cc
3 changed files with 47 additions and 25 deletions
|
|
@ -251,20 +251,21 @@ std::shared_ptr<DBCFile> AssetManager::loadDBC(const std::string& name) {
|
|||
|
||||
std::vector<uint8_t> dbcData;
|
||||
|
||||
// Some visual DBC CSV exports are known to be malformed in community datasets
|
||||
// Some DBC CSV exports are known to be malformed in community datasets
|
||||
// (string columns shifted, missing numeric ID field). Force binary MPQ data for
|
||||
// these tables to keep model/texture mappings correct.
|
||||
const bool forceBinaryForVisualDbc =
|
||||
// these tables to keep mappings correct.
|
||||
const bool forceBinaryDbc =
|
||||
(name == "CreatureDisplayInfo.dbc" ||
|
||||
name == "CreatureDisplayInfoExtra.dbc" ||
|
||||
name == "ItemDisplayInfo.dbc" ||
|
||||
name == "CreatureModelData.dbc" ||
|
||||
name == "GroundEffectTexture.dbc" ||
|
||||
name == "GroundEffectDoodad.dbc");
|
||||
name == "GroundEffectDoodad.dbc" ||
|
||||
name == "SkillLine.dbc");
|
||||
|
||||
// Try expansion-specific CSV first (e.g. Data/expansions/wotlk/db/Spell.csv)
|
||||
bool loadedFromCSV = false;
|
||||
if (!forceBinaryForVisualDbc && !expansionDataPath_.empty()) {
|
||||
if (!forceBinaryDbc && !expansionDataPath_.empty()) {
|
||||
// Derive CSV name from DBC name: "Spell.dbc" -> "Spell.csv"
|
||||
std::string baseName = name;
|
||||
auto dot = baseName.rfind('.');
|
||||
|
|
@ -286,7 +287,7 @@ std::shared_ptr<DBCFile> AssetManager::loadDBC(const std::string& name) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (forceBinaryForVisualDbc && !expansionDataPath_.empty()) {
|
||||
if (forceBinaryDbc && !expansionDataPath_.empty()) {
|
||||
LOG_INFO("Skipping CSV override for visual DBC, using binary: ", name);
|
||||
}
|
||||
|
||||
|
|
@ -296,10 +297,10 @@ std::shared_ptr<DBCFile> AssetManager::loadDBC(const std::string& name) {
|
|||
dbcData = readFile(dbcPath);
|
||||
}
|
||||
|
||||
// If binary DBC not found and we skipped CSV earlier (forceBinaryForVisualDbc),
|
||||
// If binary DBC not found and we skipped CSV earlier (forceBinaryDbc),
|
||||
// try CSV as a last resort — better than no data at all (e.g. Classic expansion
|
||||
// where binary DBCs come from MPQ extraction the user may not have done).
|
||||
if (dbcData.empty() && forceBinaryForVisualDbc && !expansionDataPath_.empty()) {
|
||||
if (dbcData.empty() && forceBinaryDbc && !expansionDataPath_.empty()) {
|
||||
std::string baseName = name;
|
||||
auto dot = baseName.rfind('.');
|
||||
if (dot != std::string::npos) {
|
||||
|
|
|
|||
|
|
@ -291,6 +291,31 @@ bool DBCFile::loadCSV(const std::vector<uint8_t>& csvData) {
|
|||
stringBlock.push_back(0); // null terminator
|
||||
row.fields[col] = offset;
|
||||
}
|
||||
} else if (pos < line.size() && line[pos] == '"') {
|
||||
// Quoted value in numeric field — skip quotes, try to parse content
|
||||
pos++; // skip opening quote
|
||||
std::string str;
|
||||
while (pos < line.size()) {
|
||||
if (line[pos] == '"') {
|
||||
if (pos + 1 < line.size() && line[pos + 1] == '"') {
|
||||
str += '"';
|
||||
pos += 2;
|
||||
} else {
|
||||
pos++; // closing quote
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
str += line[pos++];
|
||||
}
|
||||
}
|
||||
if (pos < line.size() && line[pos] == ',') pos++;
|
||||
if (!str.empty()) {
|
||||
try {
|
||||
row.fields[col] = static_cast<uint32_t>(std::stoul(str));
|
||||
} catch (...) {
|
||||
row.fields[col] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Numeric field — read until comma or end of line
|
||||
size_t end = line.find(',', pos);
|
||||
|
|
|
|||
|
|
@ -3590,7 +3590,7 @@ void GameScreen::renderActionBar(game::GameHandler& gameHandler) {
|
|||
gameHandler.setActionBarSlot(i, game::ActionBarSlot::SPELL,
|
||||
spellbookScreen.getDragSpellId());
|
||||
spellbookScreen.consumeDragSpell();
|
||||
} else if (clicked && inventoryScreen.isHoldingItem()) {
|
||||
} else if (hoveredOnRelease && inventoryScreen.isHoldingItem()) {
|
||||
// Drop held item from inventory onto action bar
|
||||
const auto& held = inventoryScreen.getHeldItem();
|
||||
gameHandler.setActionBarSlot(i, game::ActionBarSlot::ITEM, held.itemId);
|
||||
|
|
@ -7739,7 +7739,7 @@ void GameScreen::renderBankWindow(game::GameHandler& gameHandler) {
|
|||
}
|
||||
ImGui::Button("##bank", ImVec2(42, 42));
|
||||
if (isHolding) ImGui::PopStyleColor(2);
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Left) && isHolding) {
|
||||
if (ImGui::IsItemHovered() && isHolding && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) {
|
||||
// Drop held item into empty bank slot
|
||||
inventoryScreen.dropIntoBankSlot(gameHandler, 0xFF, static_cast<uint8_t>(39 + i));
|
||||
}
|
||||
|
|
@ -7752,14 +7752,12 @@ void GameScreen::renderBankWindow(game::GameHandler& gameHandler) {
|
|||
if (slot.item.stackCount <= 1) label = "##b" + std::to_string(i);
|
||||
ImGui::Button(label.c_str(), ImVec2(42, 42));
|
||||
ImGui::PopStyleColor(2);
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) {
|
||||
if (isHolding) {
|
||||
// Swap held item with bank slot
|
||||
inventoryScreen.dropIntoBankSlot(gameHandler, 0xFF, static_cast<uint8_t>(39 + i));
|
||||
} else {
|
||||
// Withdraw on click
|
||||
gameHandler.withdrawItem(0xFF, static_cast<uint8_t>(39 + i));
|
||||
}
|
||||
if (isHolding && ImGui::IsItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) {
|
||||
// Drop held item into occupied bank slot (swap)
|
||||
inventoryScreen.dropIntoBankSlot(gameHandler, 0xFF, static_cast<uint8_t>(39 + i));
|
||||
} else if (!isHolding && ImGui::IsItemClicked(ImGuiMouseButton_Left)) {
|
||||
// Withdraw on click
|
||||
gameHandler.withdrawItem(0xFF, static_cast<uint8_t>(39 + i));
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
|
|
@ -7811,7 +7809,7 @@ void GameScreen::renderBankWindow(game::GameHandler& gameHandler) {
|
|||
}
|
||||
ImGui::Button("##bb", ImVec2(42, 42));
|
||||
if (isHolding) ImGui::PopStyleColor(2);
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Left) && isHolding) {
|
||||
if (isHolding && ImGui::IsItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) {
|
||||
inventoryScreen.dropIntoBankSlot(gameHandler, static_cast<uint8_t>(67 + bagIdx), static_cast<uint8_t>(s));
|
||||
}
|
||||
} else {
|
||||
|
|
@ -7821,12 +7819,10 @@ void GameScreen::renderBankWindow(game::GameHandler& gameHandler) {
|
|||
std::string lbl = slot.item.stackCount > 1 ? std::to_string(slot.item.stackCount) : ("##bb" + std::to_string(bagIdx * 100 + s));
|
||||
ImGui::Button(lbl.c_str(), ImVec2(42, 42));
|
||||
ImGui::PopStyleColor(2);
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) {
|
||||
if (isHolding) {
|
||||
inventoryScreen.dropIntoBankSlot(gameHandler, static_cast<uint8_t>(67 + bagIdx), static_cast<uint8_t>(s));
|
||||
} else {
|
||||
gameHandler.withdrawItem(static_cast<uint8_t>(67 + bagIdx), static_cast<uint8_t>(s));
|
||||
}
|
||||
if (isHolding && ImGui::IsItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) {
|
||||
inventoryScreen.dropIntoBankSlot(gameHandler, static_cast<uint8_t>(67 + bagIdx), static_cast<uint8_t>(s));
|
||||
} else if (!isHolding && ImGui::IsItemClicked(ImGuiMouseButton_Left)) {
|
||||
gameHandler.withdrawItem(static_cast<uint8_t>(67 + bagIdx), static_cast<uint8_t>(s));
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue