#include #include #include #include #include #include "GameDependencies.h" #include "ItemSetPassiveAbility.h" #include "CDClientDatabase.h" #include "CDClientManager.h" #include "CDScriptComponentTable.h" #include "CDSkillBehaviorTable.h" #include "CDBehaviorTemplateTable.h" // Item set passive abilities come from the CDClient (DarkInspiration set skills) and the item // scripts linked to the set items (equipmenttriggers). These tests check both against the values // the server used to hardcode per set ID. namespace { std::array, 5> ReadSkillSets(uint32_t setID) { std::array, 5> skillSets; auto query = CDClientDatabase::CreatePreppedStmt( "SELECT skillSetWith2, skillSetWith3, skillSetWith4, skillSetWith5, skillSetWith6 FROM ItemSets WHERE setID = ?;"); query.bind(1, static_cast(setID)); auto result = query.execQuery(); if (result.eof()) return skillSets; for (int i = 0; i < 5; ++i) { if (result.fieldIsNull(i)) continue; auto skillQuery = CDClientDatabase::CreatePreppedStmt("SELECT SkillID FROM ItemSetSkills WHERE SkillSetID = ?;"); skillQuery.bind(1, result.getIntField(i)); auto skills = skillQuery.execQuery(); while (!skills.eof()) { skillSets[i].push_back(skills.getIntField(0)); skills.nextRow(); } } return skillSets; } std::vector ReadItems(uint32_t setID) { std::vector items; auto query = CDClientDatabase::CreatePreppedStmt("SELECT itemIDs FROM ItemSets WHERE setID = ?;"); query.bind(1, static_cast(setID)); auto result = query.execQuery(); if (result.eof()) return items; std::string ids = result.getStringField(0); std::string token; for (const char c : ids + ",") { if (c == ',') { if (!token.empty()) items.push_back(std::stoi(token)); token.clear(); } else if (!std::isspace(static_cast(c))) { token += c; } } return items; } float Parameter(uint32_t behaviorID, const std::string& name) { auto query = CDClientDatabase::CreatePreppedStmt("SELECT value FROM BehaviorParameter WHERE behaviorID = ? AND parameterID = ?;"); query.bind(1, static_cast(behaviorID)); query.bind(2, name.c_str()); auto result = query.execQuery(); return result.eof() ? -1.0f : static_cast(result.getFloatField(0)); } uint32_t Template(uint32_t behaviorID) { auto query = CDClientDatabase::CreatePreppedStmt("SELECT templateID FROM BehaviorTemplate WHERE behaviorID = ?;"); query.bind(1, static_cast(behaviorID)); auto result = query.execQuery(); return result.eof() ? 0 : result.getIntField(0); } // What a DarkInspiration on-kill behavior ends up doing to the wearer: "