feat: add /stopmacro support and low durability warning for equipped items

- /stopmacro [conditions] halts remaining macro commands; supports all existing
  macro conditionals ([combat], [nocombat], [mod:shift], etc.) via the sentinel
  action trick on evaluateMacroConditionals
- macroStopped_ flag in GameScreen; executeMacroText resets and checks it after
  each command so /stopmacro mid-macro skips all subsequent lines
- Emit a "X is about to break!" UI error + system chat when an equipped item's
  durability drops below 20% via SMSG_UPDATE_OBJECT field delta; warning fires
  once per threshold crossing (prevDur >= maxDur/5, newDur < maxDur/5)
This commit is contained in:
Kelsi 2026-03-18 04:14:44 -07:00
parent d7c377292e
commit 09b0bea981
3 changed files with 52 additions and 0 deletions

View file

@ -12302,8 +12302,30 @@ void GameHandler::applyUpdateObjectBlock(const UpdateBlock& block, bool& newItem
}
} else if (key == itemDurField && isItemInInventory) {
if (it->second.curDurability != val) {
const uint32_t prevDur = it->second.curDurability;
it->second.curDurability = val;
inventoryChanged = true;
// Warn once when durability drops below 20% for an equipped item.
const uint32_t maxDur = it->second.maxDurability;
if (maxDur > 0 && val < maxDur / 5u && prevDur >= maxDur / 5u) {
// Check if this item is in an equip slot (not bag inventory).
bool isEquipped = false;
for (uint64_t slotGuid : equipSlotGuids_) {
if (slotGuid == block.guid) { isEquipped = true; break; }
}
if (isEquipped) {
std::string itemName;
const auto* info = getItemInfo(it->second.entry);
if (info) itemName = info->name;
char buf[128];
if (!itemName.empty())
std::snprintf(buf, sizeof(buf), "%s is about to break!", itemName.c_str());
else
std::snprintf(buf, sizeof(buf), "An equipped item is about to break!");
addUIError(buf);
addSystemChatMessage(buf);
}
}
}
} else if (key == itemMaxDurField && isItemInInventory) {
if (it->second.maxDurability != val) {