mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-27 05:23:51 +00:00
feat: add stat diff comparison in item shift-tooltip
Shift-hover tooltip now shows stat differences vs the equipped item instead of just listing the equipped item's stats. Each compared stat shows: value (▲ gain green / ▼ loss red / unchanged grey). Covers: DPS (weapons), Armor, Str/Agi/Sta/Int/Spi, and all extra stats (Hit, Crit, Haste, Expertise, AP, SP, Resilience, MP5, etc.) using a union of stat types from both items.
This commit is contained in:
parent
321aaeae54
commit
5fcf71e3ff
1 changed files with 71 additions and 15 deletions
|
|
@ -1942,23 +1942,79 @@ void InventoryScreen::renderItemTooltip(const game::ItemDef& item, const game::I
|
||||||
}
|
}
|
||||||
ImGui::TextColored(getQualityColor(eq->item.quality), "%s", eq->item.name.c_str());
|
ImGui::TextColored(getQualityColor(eq->item.quality), "%s", eq->item.name.c_str());
|
||||||
|
|
||||||
if (isWeaponInventoryType(eq->item.inventoryType) &&
|
// Helper: render a numeric stat diff line
|
||||||
eq->item.damageMax > 0.0f && eq->item.delayMs > 0) {
|
auto showDiff = [](const char* label, float newVal, float eqVal) {
|
||||||
float speed = static_cast<float>(eq->item.delayMs) / 1000.0f;
|
if (newVal == 0.0f && eqVal == 0.0f) return;
|
||||||
float dps = ((eq->item.damageMin + eq->item.damageMax) * 0.5f) / speed;
|
float diff = newVal - eqVal;
|
||||||
ImGui::Text("%.1f DPS", dps);
|
char buf[128];
|
||||||
|
if (diff > 0.0f) {
|
||||||
|
std::snprintf(buf, sizeof(buf), "%s: %.0f (▲%.0f)", label, newVal, diff);
|
||||||
|
ImGui::TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), "%s", buf);
|
||||||
|
} else if (diff < 0.0f) {
|
||||||
|
std::snprintf(buf, sizeof(buf), "%s: %.0f (▼%.0f)", label, newVal, -diff);
|
||||||
|
ImGui::TextColored(ImVec4(1.0f, 0.3f, 0.3f, 1.0f), "%s", buf);
|
||||||
|
} else {
|
||||||
|
std::snprintf(buf, sizeof(buf), "%s: %.0f", label, newVal);
|
||||||
|
ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "%s", buf);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// DPS comparison for weapons
|
||||||
|
if (isWeaponInventoryType(item.inventoryType) && isWeaponInventoryType(eq->item.inventoryType)) {
|
||||||
|
float newDps = 0.0f, eqDps = 0.0f;
|
||||||
|
if (item.damageMax > 0.0f && item.delayMs > 0)
|
||||||
|
newDps = ((item.damageMin + item.damageMax) * 0.5f) / (item.delayMs / 1000.0f);
|
||||||
|
if (eq->item.damageMax > 0.0f && eq->item.delayMs > 0)
|
||||||
|
eqDps = ((eq->item.damageMin + eq->item.damageMax) * 0.5f) / (eq->item.delayMs / 1000.0f);
|
||||||
|
showDiff("DPS", newDps, eqDps);
|
||||||
}
|
}
|
||||||
if (eq->item.armor > 0) {
|
|
||||||
ImGui::Text("%d Armor", eq->item.armor);
|
// Armor
|
||||||
|
showDiff("Armor", static_cast<float>(item.armor), static_cast<float>(eq->item.armor));
|
||||||
|
|
||||||
|
// Primary stats
|
||||||
|
showDiff("Str", static_cast<float>(item.strength), static_cast<float>(eq->item.strength));
|
||||||
|
showDiff("Agi", static_cast<float>(item.agility), static_cast<float>(eq->item.agility));
|
||||||
|
showDiff("Sta", static_cast<float>(item.stamina), static_cast<float>(eq->item.stamina));
|
||||||
|
showDiff("Int", static_cast<float>(item.intellect), static_cast<float>(eq->item.intellect));
|
||||||
|
showDiff("Spi", static_cast<float>(item.spirit), static_cast<float>(eq->item.spirit));
|
||||||
|
|
||||||
|
// Extra stats diff — union of stat types from both items
|
||||||
|
auto findExtraStat = [](const game::ItemDef& it, uint32_t type) -> int32_t {
|
||||||
|
for (const auto& es : it.extraStats)
|
||||||
|
if (es.statType == type) return es.statValue;
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
// Collect all extra stat types
|
||||||
|
std::vector<uint32_t> allTypes;
|
||||||
|
for (const auto& es : item.extraStats) allTypes.push_back(es.statType);
|
||||||
|
for (const auto& es : eq->item.extraStats) {
|
||||||
|
bool found = false;
|
||||||
|
for (uint32_t t : allTypes) if (t == es.statType) { found = true; break; }
|
||||||
|
if (!found) allTypes.push_back(es.statType);
|
||||||
}
|
}
|
||||||
std::string eqBonusLine;
|
for (uint32_t t : allTypes) {
|
||||||
appendBonus(eqBonusLine, eq->item.strength, "Str");
|
int32_t nv = findExtraStat(item, t);
|
||||||
appendBonus(eqBonusLine, eq->item.agility, "Agi");
|
int32_t ev = findExtraStat(eq->item, t);
|
||||||
appendBonus(eqBonusLine, eq->item.stamina, "Sta");
|
// Find a label for this stat type
|
||||||
appendBonus(eqBonusLine, eq->item.intellect, "Int");
|
const char* lbl = nullptr;
|
||||||
appendBonus(eqBonusLine, eq->item.spirit, "Spi");
|
switch (t) {
|
||||||
if (!eqBonusLine.empty()) {
|
case 31: lbl = "Hit"; break;
|
||||||
ImGui::TextColored(green, "%s", eqBonusLine.c_str());
|
case 32: lbl = "Crit"; break;
|
||||||
|
case 35: lbl = "Resilience"; break;
|
||||||
|
case 36: lbl = "Haste"; break;
|
||||||
|
case 37: lbl = "Expertise"; break;
|
||||||
|
case 38: lbl = "Attack Power"; break;
|
||||||
|
case 39: lbl = "Ranged AP"; break;
|
||||||
|
case 43: lbl = "MP5"; break;
|
||||||
|
case 44: lbl = "Armor Pen"; break;
|
||||||
|
case 45: lbl = "Spell Power"; break;
|
||||||
|
case 46: lbl = "HP5"; break;
|
||||||
|
case 48: lbl = "Block Value"; break;
|
||||||
|
default: lbl = nullptr; break;
|
||||||
|
}
|
||||||
|
if (!lbl) continue;
|
||||||
|
showDiff(lbl, static_cast<float>(nv), static_cast<float>(ev));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue