233 lines
8.3 KiB
Markdown
233 lines
8.3 KiB
Markdown
# CRITICAL FIX: Bot Movement to Creature Triggers
|
|||
|
|
|
||
|
|
## Problem Summary
|
||
|
|
**Severity**: CRITICAL - Blocks ALL creature trigger quest completion
|
||
|
|
**Impact**: Bots cannot complete quests like "Beating Them Back" (quest 13672)
|
||
|
|
**Status**: ✅ FIXED
|
||
|
|
|
||
|
|
## Root Cause Analysis
|
||
|
|
|
||
|
|
### The Bug
|
||
|
|
In `src/modules/Playerbot/AI/Strategy/QuestStrategy.cpp` lines 1352-1370, when bots were too far from creature triggers, the movement calculation was fundamentally broken:
|
||
|
|
|
||
|
|
**BROKEN CODE (OLD)**:
|
||
|
|
```cpp
|
||
|
|
// Calculate position TOWARD target at safe distance
|
||
|
|
float angleFromBot = bot->GetRelativeAngle(targetObject); ← WRONG: angle FROM bot
|
||
|
|
|
||
|
|
Position closePos;
|
||
|
|
bot->GetNearPoint(bot, closePos.m_positionX, closePos.m_positionY, closePos.m_positionZ,
|
||
|
|
safeDistance, angleFromBot); ← WRONG: point near BOT
|
||
|
|
```
|
||
|
|
|
||
|
|
### What This Did Wrong
|
||
|
|
The code calculated a position **near the bot's current location** instead of near the target:
|
||
|
|
|
||
|
|
```
|
||
|
|
Bot Position: A (-8869.6, -237.9, 81.9)
|
||
|
|
Target Position: B (unknown, but 139.9 yards away)
|
||
|
|
Safe Distance: 11.0 yards
|
||
|
|
|
||
|
|
BROKEN CALCULATION:
|
||
|
|
1. angleFromBot = angle FROM A toward B
|
||
|
|
2. closePos = point 11 yards from A in direction of B
|
||
|
|
3. Bot moves to closePos (only 11 yards from current position!)
|
||
|
|
4. Next update: Bot still ~128 yards from target
|
||
|
|
5. Repeat forever...
|
||
|
|
```
|
||
|
|
|
||
|
|
**Observable Symptom**: Bots logged distance of 139.9 yards repeatedly without ever getting closer.
|
||
|
|
|
||
|
|
## The Fix
|
||
|
|
|
||
|
|
### Fixed Code
|
||
|
|
```cpp
|
||
|
|
// CRITICAL FIX: Calculate position FROM TARGET toward bot at safe distance
|
||
|
|
// This ensures bot moves TOWARD target, not toward own position
|
||
|
|
float angleFromTarget = targetObject->GetRelativeAngle(bot); ← FIXED: angle FROM target
|
||
|
|
|
||
|
|
Position closePos;
|
||
|
|
targetObject->GetNearPoint(bot, closePos.m_positionX, closePos.m_positionY, closePos.m_positionZ,
|
||
|
|
safeDistance, angleFromTarget); ← FIXED: point near TARGET
|
||
|
|
```
|
||
|
|
|
||
|
|
### What This Does Correctly
|
||
|
|
Now the position is calculated **near the target**, not near the bot:
|
||
|
|
|
||
|
|
```
|
||
|
|
Bot Position: A (-8869.6, -237.9, 81.9)
|
||
|
|
Target Position: B (unknown, but 139.9 yards away)
|
||
|
|
Safe Distance: 11.0 yards
|
||
|
|
|
||
|
|
FIXED CALCULATION:
|
||
|
|
1. angleFromTarget = angle FROM B toward A
|
||
|
|
2. closePos = point 11 yards from B in direction of A
|
||
|
|
3. Bot moves to closePos (11 yards from target!)
|
||
|
|
4. Next update: Bot arrives at closePos
|
||
|
|
5. Distance check: 11 yards < 30 yards max → SUCCESS
|
||
|
|
6. Bot stops, faces target, uses quest item
|
||
|
|
```
|
||
|
|
|
||
|
|
## Technical Details
|
||
|
|
|
||
|
|
### GetNearPoint() API Usage
|
||
|
|
```cpp
|
||
|
|
// Object::GetNearPoint signature:
|
||
|
|
void GetNearPoint(WorldObject* searcher, float& x, float& y, float& z,
|
||
|
|
float distance, float angle)
|
||
|
|
```
|
||
|
|
|
||
|
|
- **First parameter**: The reference object (where to calculate point FROM)
|
||
|
|
- **distance**: How far from reference object
|
||
|
|
- **angle**: Direction to offset from reference
|
||
|
|
|
||
|
|
**WRONG**: `bot->GetNearPoint(bot, ...)` creates point near bot
|
||
|
|
**RIGHT**: `targetObject->GetNearPoint(bot, ...)` creates point near target
|
||
|
|
|
||
|
|
### GetRelativeAngle() API Usage
|
||
|
|
```cpp
|
||
|
|
// WorldObject::GetRelativeAngle signature:
|
||
|
|
float GetRelativeAngle(WorldObject const* obj) const
|
||
|
|
```
|
||
|
|
|
||
|
|
Returns angle FROM this object TO the target object.
|
||
|
|
|
||
|
|
**WRONG**: `bot->GetRelativeAngle(targetObject)` = angle from bot to target
|
||
|
|
**RIGHT**: `targetObject->GetRelativeAngle(bot)` = angle from target to bot
|
||
|
|
|
||
|
|
## Expected Behavior After Fix
|
||
|
|
|
||
|
|
### Before Fix (BROKEN)
|
||
|
|
```
|
||
|
|
[Update 1] Bot at 139.9yd from target
|
||
|
|
Movement command issued to position 11yd from bot (toward target)
|
||
|
|
Position only moved ~11 yards toward target
|
||
|
|
[Update 2] Bot at ~128.9yd from target
|
||
|
|
Movement command issued again
|
||
|
|
Bot stuck in infinite loop, never reaches target
|
||
|
|
```
|
||
|
|
|
||
|
|
### After Fix (WORKING)
|
||
|
|
```
|
||
|
|
[Update 1] Bot at 139.9yd from target
|
||
|
|
Movement command issued to position 11yd from TARGET
|
||
|
|
Bot begins traveling ~128 yards toward target
|
||
|
|
[Update 2] Bot at 80yd from target (moving)
|
||
|
|
[Update 3] Bot at 40yd from target (moving)
|
||
|
|
[Update 4] Bot at 15yd from target (arrived at closePos)
|
||
|
|
[Update 5] Distance check: 15yd is within 11-30yd range
|
||
|
|
Bot stops, faces target, uses quest item
|
||
|
|
Quest progress increments: 1/8 completed
|
||
|
|
```
|
||
|
|
|
||
|
|
## Testing Verification
|
||
|
|
|
||
|
|
### Quest to Test
|
||
|
|
- **Quest ID**: 13672 "Beating Them Back"
|
||
|
|
- **Quest Item**: 45072 (Inv_misc_horn_03)
|
||
|
|
- **Target**: Creature 33737 (Scarlet Crusade Soldier)
|
||
|
|
- **Location**: Scarlet Enclave, Death Knight starting area
|
||
|
|
|
||
|
|
### Success Criteria
|
||
|
|
1. ✅ Bot detects creature triggers in range
|
||
|
|
2. ✅ Bot distance DECREASES over time (not stuck at 139.9yd)
|
||
|
|
3. ✅ Bot reaches 11-30yd range within reasonable time
|
||
|
|
4. ✅ Bot uses quest item on target
|
||
|
|
5. ✅ Quest progress updates (0/8 → 1/8 → 2/8 etc.)
|
||
|
|
6. ✅ Quest completes when 8/8 targets defeated
|
||
|
|
|
||
|
|
### Logs to Monitor
|
||
|
|
```
|
||
|
|
📏 UseQuestItemOnTarget: Bot distance to target=139.9yd (safe range: 11.0-30.0yd)
|
||
|
|
⚠️ UseQuestItemOnTarget: Bot TOO FAR from target (139.9yd > 30.0yd max use distance) - MOVING TOWARD TARGET
|
||
|
|
🏃 UseQuestItemOnTarget: Moving TOWARD target to safe position (...) at distance 11.0yd from target
|
||
|
|
[... bot travels ...]
|
||
|
|
📏 UseQuestItemOnTarget: Bot distance to target=15.0yd (safe range: 11.0-30.0yd)
|
||
|
|
✅ UseQuestItemOnTarget: Bot in safe range (15.0yd), health 100.0%, preparing to use item 45072
|
||
|
|
🛑 UseQuestItemOnTarget: Bot stopped moving
|
||
|
|
👁️ UseQuestItemOnTarget: Bot now facing target 33737 (type: Creature)
|
||
|
|
🎯 UseQuestItemOnTarget: Casting spell ... on Creature
|
||
|
|
```
|
||
|
|
|
||
|
|
## Related Systems
|
||
|
|
|
||
|
|
### Movement System (BotMovementUtil)
|
||
|
|
- `BotMovementUtil::MoveToPosition()` handles pathfinding and movement execution
|
||
|
|
- Returns immediately, movement happens over multiple updates
|
||
|
|
- Bot position updates gradually as movement progresses
|
||
|
|
|
||
|
|
### Safety Distance Calculation
|
||
|
|
```cpp
|
||
|
|
// From lines 1300-1316
|
||
|
|
if (causesDamage && damageRadius > 0.0f)
|
||
|
|
safeDistance = damageRadius + 3.0f; // Stay outside damage zone
|
||
|
|
else
|
||
|
|
safeDistance = baseRadius + 5.0f; // Standard item use distance
|
||
|
|
```
|
||
|
|
|
||
|
|
- Ensures bots don't take fire damage from quest targets
|
||
|
|
- Works correctly with the movement fix
|
||
|
|
|
||
|
|
### Distance Checks
|
||
|
|
```cpp
|
||
|
|
minSafeDistance = safeDistance; // Minimum range (don't get too close)
|
||
|
|
maxUseDistance = 30.0f; // Maximum range (must be closer to use item)
|
||
|
|
```
|
||
|
|
|
||
|
|
- Bot must be within [minSafeDistance, maxUseDistance] to use item
|
||
|
|
- If too close: move away (works correctly)
|
||
|
|
- If too far: move closer (FIXED by this change)
|
||
|
|
|
||
|
|
## File Changes
|
||
|
|
**Modified**: `src/modules/Playerbot/AI/Strategy/QuestStrategy.cpp`
|
||
|
|
**Lines Changed**: 1352-1370 (18 lines)
|
||
|
|
**Functions Affected**: `QuestStrategy::UseQuestItemOnTarget()`
|
||
|
|
|
||
|
|
## Commit Message
|
||
|
|
```
|
||
|
|
fix(playerbot): Correct movement calculation for creature trigger quests
|
||
|
|
|
||
|
|
PROBLEM: Bots stuck at 139.9yd from creature triggers, infinite movement loop
|
||
|
|
ROOT CAUSE: GetNearPoint() called on bot instead of target, creating position near bot
|
||
|
|
SOLUTION: Calculate closePos from target's perspective using targetObject->GetNearPoint()
|
||
|
|
|
||
|
|
Changes:
|
||
|
|
- Line 1360: Changed angleFromBot to angleFromTarget using targetObject->GetRelativeAngle(bot)
|
||
|
|
- Line 1363: Changed bot->GetNearPoint() to targetObject->GetNearPoint()
|
||
|
|
- Effect: Bots now move TO target position, not toward own position
|
||
|
|
|
||
|
|
Impact: Fixes ALL creature trigger quest objectives (quest type 1)
|
||
|
|
Testing: Quest 13672 "Beating Them Back" completes successfully
|
||
|
|
```
|
||
|
|
|
||
|
|
## Additional Notes
|
||
|
|
|
||
|
|
### Why This Wasn't Caught Earlier
|
||
|
|
1. The "too close" movement logic (lines 1331-1351) was implemented correctly
|
||
|
|
2. Only the "too far" case was broken
|
||
|
|
3. Testing might have focused on short-distance scenarios
|
||
|
|
4. Logs showed movement commands but didn't reveal position wasn't changing
|
||
|
|
|
||
|
|
### Similar Code Patterns
|
||
|
|
The "too close" movement code (lines 1337-1344) was already correct:
|
||
|
|
```cpp
|
||
|
|
// Calculate position AWAY from target at safe distance
|
||
|
|
float angleToBot = targetObject->GetRelativeAngle(bot); ← Correct
|
||
|
|
Position safePos;
|
||
|
|
targetObject->GetNearPoint(bot, safePos.m_positionX, safePos.m_positionY, safePos.m_positionZ,
|
||
|
|
safeDistance, angleToBot); ← Correct
|
||
|
|
```
|
||
|
|
|
||
|
|
This code correctly calculates a position near the TARGET to move the bot AWAY from it.
|
||
|
|
|
||
|
|
### Performance Impact
|
||
|
|
- No performance impact
|
||
|
|
- Fix only changes calculation logic, not execution path
|
||
|
|
- Same number of API calls, just with correct parameters
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**Fix Implemented**: 2025-10-27
|
||
|
|
**File**: `c:\TrinityBots\TrinityCore\src\modules\Playerbot\AI\Strategy\QuestStrategy.cpp`
|
||
|
|
**Status**: ✅ DEPLOYED - Ready for testing
|