-
Notifications
You must be signed in to change notification settings - Fork 0
Pvp with master mutex #77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -16,6 +16,34 @@ | |||||
| #include "SpellAuraEffects.h" | ||||||
| #include "SpellMgr.h" | ||||||
| #include "Unit.h" | ||||||
| #include "AreaDefines.h" | ||||||
| #include <unordered_map> | ||||||
| #include <mutex> | ||||||
|
|
||||||
| // Level difference thresholds for attack probability | ||||||
| constexpr int32 EXTREME_LEVEL_DIFF = 5; // Don't attack if enemy is this much higher | ||||||
| constexpr int32 HIGH_LEVEL_DIFF = 4; // 25% chance at +/- this difference | ||||||
| constexpr int32 MID_LEVEL_DIFF = 3; // 50% chance at +/- this difference | ||||||
| constexpr int32 LOW_LEVEL_DIFF = 2; // 75% chance at +/- this difference | ||||||
|
|
||||||
| // Cache duration before reconsidering attack decision, and old cache cleanup interval | ||||||
| constexpr uint32 ATTACK_DECISION_CACHE_DURATION = 2 * MINUTE; | ||||||
| constexpr uint32 ATTACK_DECISION_CACHE_CLEANUP_INTERVAL = 10 * MINUTE; | ||||||
|
|
||||||
| // Custom hash function for (botGUID, targetGUID) pairs | ||||||
| struct PairGuidHash | ||||||
| { | ||||||
| std::size_t operator()(const std::pair<ObjectGuid, ObjectGuid>& pair) const | ||||||
| { | ||||||
| return std::hash<uint64>()(pair.first.GetRawValue()) ^ | ||||||
| (std::hash<uint64>()(pair.second.GetRawValue()) << 1); | ||||||
| } | ||||||
| }; | ||||||
|
|
||||||
| // Cache for probability-based attack decisions (Per-bot: non-global) | ||||||
| // Map: (botGUID, targetGUID) -> (should attack decision, timestamp) | ||||||
| static std::unordered_map<std::pair<ObjectGuid, ObjectGuid>, std::pair<bool, time_t>, PairGuidHash> attackDecisionCache; | ||||||
| static std::mutex attackDecisionCacheMutex; | ||||||
|
|
||||||
| void PossibleTargetsValue::FindUnits(std::list<Unit*>& targets) | ||||||
| { | ||||||
|
|
@@ -24,7 +52,121 @@ void PossibleTargetsValue::FindUnits(std::list<Unit*>& targets) | |||||
| Cell::VisitObjects(bot, searcher, range); | ||||||
| } | ||||||
|
|
||||||
| bool PossibleTargetsValue::AcceptUnit(Unit* unit) { return AttackersValue::IsPossibleTarget(unit, bot, range); } | ||||||
| static void CleanupAttackDecisionCache() | ||||||
| { | ||||||
| // Mutex already held by caller in AcceptUnit | ||||||
| time_t currentTime = time(nullptr); | ||||||
| for (auto it = attackDecisionCache.begin(); it != attackDecisionCache.end();) | ||||||
| { | ||||||
| if (currentTime - it->second.second >= ATTACK_DECISION_CACHE_DURATION) | ||||||
| it = attackDecisionCache.erase(it); | ||||||
| else | ||||||
| ++it; | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| bool PossibleTargetsValue::AcceptUnit(Unit* unit) | ||||||
| { | ||||||
| if (!AttackersValue::IsPossibleTarget(unit, bot, range)) | ||||||
| return false; | ||||||
|
|
||||||
| // Level-based PvP restrictions | ||||||
| if (unit->IsPlayer()) | ||||||
| { | ||||||
| // Self-defense - always allow fighting back | ||||||
| if (bot->IsInCombat() && bot->GetVictim() == unit) | ||||||
| return true; // Already fighting | ||||||
|
|
||||||
| Unit* botAttacker = bot->getAttackerForHelper(); | ||||||
| if (botAttacker) | ||||||
| { | ||||||
| if (botAttacker == unit) | ||||||
| return true; // Enemy attacking | ||||||
|
|
||||||
| if (botAttacker->IsPet()) | ||||||
| { | ||||||
| Unit* petOwner = botAttacker->GetOwner(); | ||||||
| if (petOwner && petOwner == unit) | ||||||
| return true; // Enemy's pet attacking | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| // Skip restrictions in BG/Arena | ||||||
| if (bot->InBattleground() || bot->InArena()) | ||||||
| return true; | ||||||
|
|
||||||
| // Skip restrictions if in duel with this player | ||||||
| if (bot->duel && bot->duel->Opponent == unit) | ||||||
| return true; | ||||||
|
|
||||||
| // Capital cities - no restrictions | ||||||
| uint32 zoneId = bot->GetZoneId(); | ||||||
| bool inCapitalCity = (zoneId == AREA_STORMWIND_CITY || | ||||||
| zoneId == AREA_IRONFORGE || | ||||||
| zoneId == AREA_DARNASSUS || | ||||||
| zoneId == AREA_THE_EXODAR || | ||||||
| zoneId == AREA_ORGRIMMAR || | ||||||
| zoneId == AREA_THUNDER_BLUFF || | ||||||
| zoneId == AREA_UNDERCITY || | ||||||
| zoneId == AREA_SILVERMOON_CITY); | ||||||
|
Comment on lines
+103
to
+111
|
||||||
|
|
||||||
| if (inCapitalCity) | ||||||
| return true; | ||||||
|
|
||||||
| // Level difference check | ||||||
| int32 levelDifference = unit->GetLevel() - bot->GetLevel(); | ||||||
| int32 absLevelDifference = std::abs(levelDifference); | ||||||
|
|
||||||
| // Extreme difference - do not attack | ||||||
| if (levelDifference >= EXTREME_LEVEL_DIFF) | ||||||
| return false; | ||||||
|
|
||||||
| // Calculate attack chance based on level difference | ||||||
| uint32 attackChance = 100; // Default 100%: Bot and target's levels are very close | ||||||
|
|
||||||
| // There's a chance a bot might gank on an extremly low target | ||||||
|
||||||
| // There's a chance a bot might gank on an extremly low target | |
| // There's a chance a bot might gank on an extremely low target |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The AREA_* constants used in this capital city check (e.g. AREA_STORMWIND_CITY, AREA_ORGRIMMAR, etc.) are not defined anywhere in the current codebase, and the only reference to AreaDefines.h is this new include. This will cause compilation failures due to undefined identifiers unless AreaDefines.h and these macros are added elsewhere in the project. Either include an existing header that already defines these IDs, or switch to using AreaTableEntry flags (e.g. AREA_FLAG_CAPITAL) consistently with the rest of the codebase.