Skip to content

Commit

Permalink
Fixed autoreroll so it checks all of the stats of a given property in…
Browse files Browse the repository at this point in the history
…stead of just the first

Added a threshold to autoreroll
Fixed crash when unloading autoreroll
Added goodstats_ar.txt to autoreroll
Added 'RequirePErfectStats' to autoreroll.ini to enable perfect stat rerolls
Added 'PerfectionPercentage' to autoreroll.ini to give a bit of a threshold when determining if an item is perfect or perfectenough
  • Loading branch information
nooperation committed Feb 3, 2024
1 parent 0106f16 commit 89e0a19
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 18 deletions.
50 changes: 38 additions & 12 deletions D2Hackit/Modules/autoReroll/AutoReroll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
#undef min
#undef max

std::vector<DWORD> gemsInInventory;
std::unordered_set<int> goodPrefix;
std::unordered_set<int> goodSuffix;
std::unordered_set<int> goodStats;

std::unordered_set<std::string> gemItemCodes;
std::unordered_set<std::string> gemCanItemCodes;
std::unordered_set<std::string> canOpenerItemCodes;
Expand Down Expand Up @@ -105,9 +110,16 @@ bool AutoReroll::Init(bool useChat)
return false;
}

if(!ReadAffixConfig(".\\plugin\\goodStats_ar.txt", goodStats))
{
return false;
}

minPrefix = GetPrivateProfileInt("AutoReroll", "PrefixCount", 2, CONFIG_PATH);
minSuffix = GetPrivateProfileInt("AutoReroll", "SuffixCount", 0, CONFIG_PATH);
numGemsToUse = GetPrivateProfileInt("AutoReroll", "GemCount", 2, CONFIG_PATH);
requirePerfectStats = GetPrivateProfileInt("AutoReroll", "RequirePerfectStats", 0, CONFIG_PATH) != 0;
perfectionPercentage = GetPrivateProfileInt("AutoReroll", "PerfectionPercentage", 100, CONFIG_PATH);

char buff[128];
if (GetPrivateProfileStringA("AutoReroll", "CustomExtractorItemCode", "", buff, sizeof(buff), CONFIG_PATH) > 0)
Expand Down Expand Up @@ -348,18 +360,35 @@ bool AutoReroll::IsPerfectProperty(GAMEUNIT& itemUnit, UnitAny* unit, const D2Pr
return true;
}

auto minimumValue = std::min(property.nMin, property.nMax);
auto maximumValue = std::max(property.nMin, property.nMax);

if (maximumValue == minimumValue)
{
return true;
}

bool isPerfect = false;
for (int propertyTxtIndex = 0; propertyTxtIndex < sizeof(propertyTxt->wStat) / sizeof(propertyTxt->wStat[0]); ++propertyTxtIndex)
{
if (propertyTxt->wStat[propertyTxtIndex] < 0)
{
break;
}

if (!requirePerfectStats && goodStats.find(propertyTxt->wStat[propertyTxtIndex]) == goodStats.end())
{
// We don't care about this stat since we're only looking for specific stats to be perfect
continue;
}

auto statTxt = server->GetItemStatCostTxtRecord(propertyTxt->wStat[propertyTxtIndex]);
if (statTxt == nullptr)
{
server->GameStringf("Invalid propertyTxt stat %d", propertyTxt->wStat[propertyTxtIndex]);
return true;
}

auto minimumValue = std::min(property.nMin, property.nMax);
auto maximumValue = std::max(property.nMin, property.nMax);

std::string propertyName = server->GetPropertyName(property.nProperty);
switch (propertyTxt->nFunc[propertyTxtIndex])
{
Expand All @@ -369,35 +398,32 @@ bool AutoReroll::IsPerfectProperty(GAMEUNIT& itemUnit, UnitAny* unit, const D2Pr
auto actualValue = (int32_t)server->GetUnitStat(&itemUnit, propertyTxt->wStat[propertyTxtIndex]);
actualValue >>= statTxt->nValShift;

if (actualValue < maximumValue && actualValue >= minimumValue)
auto percentPerfect = (int)(100.0 * (actualValue - minimumValue)) / (maximumValue - minimumValue);
if (percentPerfect < perfectionPercentage)
{
return false;
}

return true;
}
case 21: // +class skills
{
auto actualValue = server->GetUnitStatBonus(unit, propertyTxt->wStat[propertyTxtIndex], propertyTxt->wVal[propertyTxtIndex]);
actualValue >>= statTxt->nValShift;

if (actualValue < maximumValue && actualValue >= minimumValue)
auto percentPerfect = (int)(100.0 * (actualValue - minimumValue)) / (maximumValue - minimumValue);
if (percentPerfect < perfectionPercentage)
{
return false;
}

return true;
}
case 22: // oskills
{
auto actualValue = server->GetUnitStatBonus(unit, propertyTxt->wStat[propertyTxtIndex], property.nLayer);

if (actualValue < maximumValue && actualValue >= minimumValue)
auto percentPerfect = (int)(100.0 * (actualValue - minimumValue)) / (maximumValue - minimumValue);
if (percentPerfect < perfectionPercentage)
{
return false;
}

return true;
}
}
}
Expand Down
8 changes: 2 additions & 6 deletions D2Hackit/Modules/autoReroll/AutoReroll.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,13 @@ class AutoReroll
bool Init(bool useChat);

void OnItemToCube(const ITEM &item);
void OnItemFromCube(DWORD itemID);
void OnItemFromInventory(DWORD itemID);
bool OnEmptyCubeMessage(const std::string_view &message);
bool OnAutoExtractorMessage(const std::string_view &message);
void OnTick();
void Abort();

private:
void StartStocking();
bool CheckRerolledItem(const ITEM &item);
bool IsPerfectProperty(GAMEUNIT& itemUnit, UnitAny* unit, const D2PropertyStrc& property, D2DataTablesStrc* dataTables);

Expand All @@ -59,7 +57,6 @@ class AutoReroll
void ExtractMoreGems();
void MoveGemCanAndOpenerToCube();
void MoveNextGemToCube();
void FinishedEmptyCube();

bool ReadAffixConfig(const std::string &configPath, std::unordered_set<int> &readTo);

Expand All @@ -69,11 +66,10 @@ class AutoReroll
int minPrefix;
int minSuffix;
int numGemsToUse;
bool requirePerfectStats;
int perfectionPercentage;
DWORD itemToRerollID;
int currentGemIndex;
std::vector<DWORD> gemsInInventory;
std::unordered_set<int> goodPrefix;
std::unordered_set<int> goodSuffix;

States currentState;
GemCanStuff gemCanAndOpener;
Expand Down
3 changes: 3 additions & 0 deletions D2Hackit/Modules/autoReroll/AutoReroll.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ xcopy /Y $(TargetPath) $(SolutionDir)\Publish_$(Configuration)\</Command>
<None Include="Resources\goodPrefix_ar.txt" />
<None Include="Resources\goodSuffix_ar.txt" />
</ItemGroup>
<ItemGroup>
<Text Include="goodStats_ar.txt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
Expand Down
5 changes: 5 additions & 0 deletions D2Hackit/Modules/autoReroll/AutoReroll.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,9 @@
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Text Include="goodStats_ar.txt">
<Filter>Resource Files</Filter>
</Text>
</ItemGroup>
</Project>
2 changes: 2 additions & 0 deletions D2Hackit/Modules/autoReroll/Resources/autoreroll.ini
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ GemCount = 2
;CustomExtractorItemCode = key
;CustomGemItemCode = 6gk
;CustomGemCanItemCode = kk0
;RequirePerfectStats =
;PerfectionPercentage = 100
7 changes: 7 additions & 0 deletions D2Hackit/Modules/autoReroll/goodStats_ar.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
437 passive_mag_pierce
335 passive_cold_pierce
429 passive_cold_mastery_multi
331 passive_cold_mastery
127 item_allskills
37 magicresist
85 item_addexperience

0 comments on commit 89e0a19

Please sign in to comment.