From e7b74f0a2286d50920cf06e4b86e0899f604c006 Mon Sep 17 00:00:00 2001 From: youbetterdont Date: Sun, 1 Mar 2020 14:17:52 -0800 Subject: [PATCH] Added support for filtering items based on skill charges. The new keyword is CHSK and is used much the same way as SK. --- BH/Modules/Item/ItemDisplay.cpp | 35 +++++++++++++++++++++++++++++++++ BH/Modules/Item/ItemDisplay.h | 12 +++++++++++ 2 files changed, 47 insertions(+) diff --git a/BH/Modules/Item/ItemDisplay.cpp b/BH/Modules/Item/ItemDisplay.cpp index 3c9991b5..7204e35d 100644 --- a/BH/Modules/Item/ItemDisplay.cpp +++ b/BH/Modules/Item/ItemDisplay.cpp @@ -821,6 +821,13 @@ void Condition::BuildConditions(vector &conditions, string token) { return; } Condition::AddOperand(conditions, new ItemStatCondition(STAT_NONCLASSSKILL, num, operation, value)); + } else if (key.compare(0, 4, "CHSK") == 0) { // skills granted by charges + int num = -1; + stringstream ss(key.substr(4)); + if ((ss >> num).fail() || num < 0 || num > (int)SKILL_MAX) { + return; + } + Condition::AddOperand(conditions, new ChargedCondition(operation, num, value)); } else if (key.compare(0, 4, "CLSK") == 0) { int num = -1; stringstream ss(key.substr(4)); @@ -1145,6 +1152,34 @@ bool DurabilityCondition::EvaluateInternalFromPacket(ItemInfo *info, Condition * return IntegerCompare(value, operation, targetDurability); } +bool ChargedCondition::EvaluateInternal(UnitItemInfo *uInfo, Condition *arg1, Condition *arg2) { + DWORD value = 0; + Stat aStatList[256] = { NULL }; + StatList* pStatList = D2COMMON_GetStatList(uInfo->item, NULL, 0x40); + if (pStatList) { + DWORD dwStats = D2COMMON_CopyStatList(pStatList, (Stat*)aStatList, 256); + for (UINT i = 0; i < dwStats; i++) { + //if (aStatList[i].wStatIndex == STAT_CHARGED) + // PrintText(1, "ChargedCondition::EvaluateInternal: Index=%hx, SubIndex=%hx, Value=%x", aStatList[i].wStatIndex, aStatList[i].wSubIndex, aStatList[i].dwStatValue); + if (aStatList[i].wStatIndex == STAT_CHARGED && (aStatList[i].wSubIndex>>6) == skill) { // 10 MSBs of subindex is the skill ID + unsigned int level = aStatList[i].wSubIndex & 0x3F; // 6 LSBs are the skill level + value = (level > value) ? level : value; // use highest level + } + } + } + return IntegerCompare(value, operation, targetLevel); +} +bool ChargedCondition::EvaluateInternalFromPacket(ItemInfo *info, Condition *arg1, Condition *arg2) { + DWORD num = 0; + for (vector::iterator prop = info->properties.begin(); prop < info->properties.end(); prop++) { + if (prop->stat == STAT_CHARGED && prop->skill == skill) { + num = (prop->level > num) ? prop->level : num; // use the highest level charges for the comparison + //PrintText(1, "Found charged skill. skill=%u level=%u", prop->skill, prop->level); + } + } + return IntegerCompare(num, operation, targetLevel); +} + bool FoolsCondition::EvaluateInternal(UnitItemInfo *uInfo, Condition *arg1, Condition *arg2) { // 1 = MAX DMG / level // 2 = AR / level diff --git a/BH/Modules/Item/ItemDisplay.h b/BH/Modules/Item/ItemDisplay.h index e99f5f35..8e4f9db7 100644 --- a/BH/Modules/Item/ItemDisplay.h +++ b/BH/Modules/Item/ItemDisplay.h @@ -367,6 +367,18 @@ class DurabilityCondition : public Condition bool EvaluateInternalFromPacket(ItemInfo *info, Condition *arg1, Condition *arg2); }; +class ChargedCondition : public Condition +{ +public: + ChargedCondition(BYTE op, unsigned int sk, unsigned int target) : operation(op), skill(sk), targetLevel(target) { conditionType = CT_Operand; }; +private: + BYTE operation; + unsigned int skill; + unsigned int targetLevel; + bool EvaluateInternal(UnitItemInfo *uInfo, Condition *arg1, Condition *arg2); + bool EvaluateInternalFromPacket(ItemInfo *info, Condition *arg1, Condition *arg2); +}; + class FoolsCondition : public Condition { public: