357 lines
10 KiB
Markdown
357 lines
10 KiB
Markdown
# Playerbot Movement Integration Examples
|
|||
|
|
|
||
|
|
## Quick Start Integration
|
||
|
|
|
||
|
|
### 1. Add to BotAI Class
|
||
|
|
|
||
|
|
**In BotAI.h:**
|
||
|
|
```cpp
|
||
|
|
// Add these includes near the top
|
||
|
|
#include "Movement/MovementIntegration.h"
|
||
|
|
#include "Humanization/Core/AdvancedPersonalityProfile.h"
|
||
|
|
|
||
|
|
// Add to BotAI class declaration
|
||
|
|
class BotAI
|
||
|
|
{
|
||
|
|
private:
|
||
|
|
std::unique_ptr<MovementIntegration> _movementIntegration;
|
||
|
|
std::unique_ptr<AdvancedPersonalityProfile> _advancedPersonality;
|
||
|
|
|
||
|
|
public:
|
||
|
|
// Movement interface methods
|
||
|
|
bool MoveTo(Position const& destination, uint32 priority = 0);
|
||
|
|
bool Follow(Unit* target, float distance, uint32 priority = 0);
|
||
|
|
bool Wander(Position const& center, float radius, Milliseconds duration);
|
||
|
|
void StopMovement();
|
||
|
|
|
||
|
|
// Access to subsystems
|
||
|
|
MovementIntegration* GetMovementIntegration() const { return _movementIntegration.get(); }
|
||
|
|
AdvancedPersonalityProfile* GetAdvancedPersonality() const { return _advancedPersonality.get(); }
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
**In BotAI.cpp:**
|
||
|
|
```cpp
|
||
|
|
// In constructor:
|
||
|
|
BotAI::BotAI(Player* bot)
|
||
|
|
: _bot(bot)
|
||
|
|
{
|
||
|
|
// Initialize movement integration
|
||
|
|
_movementIntegration = std::make_unique<MovementIntegration>(_bot);
|
||
|
|
|
||
|
|
// Initialize advanced personality
|
||
|
|
_advancedPersonality = std::make_unique<AdvancedPersonalityProfile>(
|
||
|
|
AdvancedPersonalityType::CASUAL_EXPLORER);
|
||
|
|
|
||
|
|
// Configure movement systems
|
||
|
|
MovementSystemConfig config;
|
||
|
|
config.enableHumanizedMovement = true;
|
||
|
|
config.enableAdvancedDeduplication = true;
|
||
|
|
config.humanizationStrength = 0.8f;
|
||
|
|
config.deduplicationStrength = 0.8f;
|
||
|
|
_movementIntegration->SetConfig(config);
|
||
|
|
|
||
|
|
// Initialize systems
|
||
|
|
_movementIntegration->Initialize();
|
||
|
|
}
|
||
|
|
|
||
|
|
// In UpdateAI:
|
||
|
|
void BotAI::UpdateAI(uint32 diff)
|
||
|
|
{
|
||
|
|
// Update movement integration
|
||
|
|
if (_movementIntegration)
|
||
|
|
_movementIntegration->Update(diff);
|
||
|
|
|
||
|
|
// Rest of your existing UpdateAI logic...
|
||
|
|
}
|
||
|
|
|
||
|
|
// Movement interface implementations:
|
||
|
|
bool BotAI::MoveTo(Position const& destination, uint32 priority)
|
||
|
|
{
|
||
|
|
if (_movementIntegration)
|
||
|
|
return _movementIntegration->MoveTo(destination, priority, "BotAI");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool BotAI::Follow(Unit* target, float distance, uint32 priority)
|
||
|
|
{
|
||
|
|
if (_movementIntegration)
|
||
|
|
return _movementIntegration->Follow(target, distance, priority);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool BotAI::Wander(Position const& center, float radius, Milliseconds duration)
|
||
|
|
{
|
||
|
|
if (_movementIntegration)
|
||
|
|
return _movementIntegration->Wander(center, radius, duration);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
void BotAI::StopMovement()
|
||
|
|
{
|
||
|
|
if (_movementIntegration)
|
||
|
|
_movementIntegration->StopMovement();
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. Replace Existing Movement Calls
|
||
|
|
|
||
|
|
**Find and replace patterns:**
|
||
|
|
|
||
|
|
**Old code:**
|
||
|
|
```cpp
|
||
|
|
BotMovementUtil::MoveToPosition(bot, destination);
|
||
|
|
bot->GetMotionMaster()->MovePoint(0, destX, destY, destZ);
|
||
|
|
bot->GetMotionMaster()->MoveChase(target, distance);
|
||
|
|
```
|
||
|
|
|
||
|
|
**New code:**
|
||
|
|
```cpp
|
||
|
|
// Replace with:
|
||
|
|
if (botAI->GetMovementIntegration()) {
|
||
|
|
botAI->GetMovementIntegration()->MoveTo(destination, priority, "SpecificSystem");
|
||
|
|
} else {
|
||
|
|
// Fallback to original
|
||
|
|
BotMovementUtil::MoveToPosition(bot, destination);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. Update Strategy Classes
|
||
|
|
|
||
|
|
**Example in a movement strategy:**
|
||
|
|
```cpp
|
||
|
|
class MoveToTargetStrategy : public Strategy
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
ActionResult Execute(BotAI* ai, ActionContext const& context) override
|
||
|
|
{
|
||
|
|
Unit* target = context.GetValue<Unit*>("target");
|
||
|
|
if (!target)
|
||
|
|
return ActionResult::FAILED;
|
||
|
|
|
||
|
|
// Use enhanced movement
|
||
|
|
if (ai->GetMovementIntegration())
|
||
|
|
{
|
||
|
|
Position targetPos = target->GetPosition();
|
||
|
|
bool result = ai->GetMovementIntegration()->MoveTo(targetPos, 5, "MoveToTargetStrategy");
|
||
|
|
return result ? ActionResult::SUCCESS : ActionResult::FAILED;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Fallback
|
||
|
|
return ai->DoAction("move to target", context);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
### 4. Personality-Driven Behavior
|
||
|
|
|
||
|
|
**Example of using advanced personality:**
|
||
|
|
```cpp
|
||
|
|
class SocialBehaviorStrategy : public Strategy
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
ActionResult Execute(BotAI* ai, ActionContext const& context) override
|
||
|
|
{
|
||
|
|
auto* personality = ai->GetAdvancedPersonality();
|
||
|
|
if (!personality)
|
||
|
|
return ActionResult::FAILED;
|
||
|
|
|
||
|
|
// Check if bot should socialize based on personality
|
||
|
|
float socialTendency = personality->GetTraits().extraversion;
|
||
|
|
if (urand(0, 100) < socialTendency * 100)
|
||
|
|
{
|
||
|
|
// Find nearby players to greet
|
||
|
|
Player* nearbyPlayer = FindNearbyPlayer(ai->GetBot(), 15.0f);
|
||
|
|
if (nearbyPlayer)
|
||
|
|
{
|
||
|
|
// Calculate greeting likelihood based on personality
|
||
|
|
float greetChance = personality->CalculateSocialLikelihood("greeting");
|
||
|
|
if (urand(0, 100) < greetChance * 100)
|
||
|
|
{
|
||
|
|
ai->GetBot()->Say("Hello there!", LANG_UNIVERSAL);
|
||
|
|
return ActionResult::SUCCESS;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return ActionResult::FAILED;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
### 5. Configuration Integration
|
||
|
|
|
||
|
|
**Add to your config system:**
|
||
|
|
```cpp
|
||
|
|
// In your config loading code:
|
||
|
|
void LoadMovementConfig()
|
||
|
|
{
|
||
|
|
MovementSystemConfig config;
|
||
|
|
|
||
|
|
config.enableHumanizedMovement = sConfigMgr->GetBoolDefault("Playerbot.HumanizedMovement.Enabled", true);
|
||
|
|
config.enableAdvancedDeduplication = sConfigMgr->GetBoolDefault("Playerbot.Deduplication.Enabled", true);
|
||
|
|
config.humanizationStrength = sConfigMgr->GetFloatDefault("Playerbot.Humanization.Strength", 0.8f);
|
||
|
|
config.deduplicationStrength = sConfigMgr->GetFloatDefault("Playerbot.Deduplication.Strength", 0.8f);
|
||
|
|
config.cacheSize = sConfigMgr->GetIntDefault("Playerbot.Deduplication.CacheSize", 1000);
|
||
|
|
config.cacheAgeMs = sConfigMgr->GetIntDefault("Playerbot.Deduplication.CacheAge", 300000);
|
||
|
|
|
||
|
|
// Apply to all bots
|
||
|
|
for (auto& botAI : allBotAIs)
|
||
|
|
{
|
||
|
|
if (botAI->GetMovementIntegration())
|
||
|
|
botAI->GetMovementIntegration()->SetConfig(config);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 6. CMakeLists.txt Updates
|
||
|
|
|
||
|
|
**Add to your CMakeLists.txt:**
|
||
|
|
```cmake
|
||
|
|
# Add new movement files
|
||
|
|
set(PLAYERBOT_MOVEMENT_SOURCES
|
||
|
|
${CMAKE_SOURCE_DIR}/src/modules/Playerbot/Movement/HumanizedMovement.cpp
|
||
|
|
${CMAKE_SOURCE_DIR}/src/modules/Playerbot/Movement/EnhancedMovementDeduplication.cpp
|
||
|
|
${CMAKE_SOURCE_DIR}/src/modules/Playerbot/Movement/MovementIntegration.cpp
|
||
|
|
# ... existing movement sources
|
||
|
|
)
|
||
|
|
|
||
|
|
# Add new humanization files
|
||
|
|
set(PLAYERBOT_HUMANIZATION_SOURCES
|
||
|
|
${CMAKE_SOURCE_DIR}/src/modules/Playerbot/Humanization/Core/AdvancedPersonalityProfile.cpp
|
||
|
|
# ... existing humanization sources
|
||
|
|
)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Testing Your Integration
|
||
|
|
|
||
|
|
### 1. Basic Movement Test
|
||
|
|
```cpp
|
||
|
|
// Test command to verify movement works
|
||
|
|
bool TestMovement(BotAI* ai)
|
||
|
|
{
|
||
|
|
Position testPos = ai->GetBot()->GetPosition();
|
||
|
|
testPos.Relocate(testPos.GetPositionX() + 10.0f,
|
||
|
|
testPos.GetPositionY() + 10.0f,
|
||
|
|
testPos.GetPositionZ());
|
||
|
|
|
||
|
|
return ai->MoveTo(testPos, 1, "TestMovement");
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. Personality Test
|
||
|
|
```cpp
|
||
|
|
// Test different personalities
|
||
|
|
void TestPersonalities(BotAI* ai)
|
||
|
|
{
|
||
|
|
auto* personality = ai->GetAdvancedPersonality();
|
||
|
|
if (!personality)
|
||
|
|
return;
|
||
|
|
|
||
|
|
TC_LOG_INFO("test", "Personality type: {}", personality->GetTypeName());
|
||
|
|
TC_LOG_INFO("test", "Extraversion: {:.2f}", personality->GetTraits().extraversion);
|
||
|
|
TC_LOG_INFO("test", "Risk taking: {:.2f}", personality->GetTraits().behavior.riskTaking);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. Performance Test
|
||
|
|
```cpp
|
||
|
|
// Monitor movement performance
|
||
|
|
void MonitorMovementPerformance(BotAI* ai)
|
||
|
|
{
|
||
|
|
auto* integration = ai->GetMovementIntegration();
|
||
|
|
if (!integration)
|
||
|
|
return;
|
||
|
|
|
||
|
|
auto stats = integration->GetStatistics();
|
||
|
|
TC_LOG_INFO("performance", "Total movements: {}", stats.totalMovements);
|
||
|
|
TC_LOG_INFO("performance", "Humanized: {} ({:.1f}%)",
|
||
|
|
stats.humanizedMovements,
|
||
|
|
stats.humanizationScore * 100.0f);
|
||
|
|
TC_LOG_INFO("performance", "Deduplicated: {} ({:.1f}%)",
|
||
|
|
stats.deduplicatedMovements,
|
||
|
|
stats.averageReduction * 100.0f);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Troubleshooting Integration Issues
|
||
|
|
|
||
|
|
### Common Problems and Solutions
|
||
|
|
|
||
|
|
**1. Compilation Errors:**
|
||
|
|
```cpp
|
||
|
|
// Missing includes - add these:
|
||
|
|
#include "Movement/MovementIntegration.h"
|
||
|
|
#include "Humanization/Core/AdvancedPersonalityProfile.h"
|
||
|
|
#include "Player.h"
|
||
|
|
#include "Position.h"
|
||
|
|
```
|
||
|
|
|
||
|
|
**2. Linker Errors:**
|
||
|
|
```cmake
|
||
|
|
# Make sure new files are included in CMakeLists.txt
|
||
|
|
# Check that namespaces are correct
|
||
|
|
using namespace Playerbot;
|
||
|
|
using namespace Playerbot::Humanization;
|
||
|
|
```
|
||
|
|
|
||
|
|
**3. Runtime Crashes:**
|
||
|
|
```cpp
|
||
|
|
// Always check for null pointers:
|
||
|
|
if (!ai->GetMovementIntegration()) {
|
||
|
|
TC_LOG_WARN("playerbot", "Movement integration not initialized");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check bot is in world:
|
||
|
|
if (!_bot->IsInWorld()) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**4. Movement Not Working:**
|
||
|
|
```cpp
|
||
|
|
// Verify configuration:
|
||
|
|
MovementSystemConfig config = movementIntegration->GetConfig();
|
||
|
|
TC_LOG_INFO("debug", "Humanized enabled: {}", config.enableHumanizedMovement);
|
||
|
|
TC_LOG_INFO("debug", "Deduplication enabled: {}", config.enableAdvancedDeduplication);
|
||
|
|
|
||
|
|
// Check initialization:
|
||
|
|
if (!movementIntegration->IsInitialized()) {
|
||
|
|
movementIntegration->Initialize();
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Migration Checklist
|
||
|
|
|
||
|
|
- [ ] Add new files to CMakeLists.txt
|
||
|
|
- [ ] Update BotAI class with movement integration
|
||
|
|
- [ ] Replace existing movement calls with new interface
|
||
|
|
- [ ] Add configuration options
|
||
|
|
- [ ] Test basic movement functionality
|
||
|
|
- [ ] Test personality-driven behavior
|
||
|
|
- [ ] Verify performance improvements
|
||
|
|
- [ ] Update documentation
|
||
|
|
- [ ] Train staff on new systems
|
||
|
|
|
||
|
|
## Performance Monitoring
|
||
|
|
|
||
|
|
After integration, monitor these metrics:
|
||
|
|
|
||
|
|
**Movement Efficiency:**
|
||
|
|
- Movement calls per second (should decrease by 60-80%)
|
||
|
|
- CPU usage for movement calculations
|
||
|
|
- Pathfinding cache hit rates
|
||
|
|
|
||
|
|
**Behavior Quality:**
|
||
|
|
- Player feedback on bot naturalness
|
||
|
|
- Personality diversity in behavior
|
||
|
|
- Social interaction frequency
|
||
|
|
|
||
|
|
**System Stability:**
|
||
|
|
- Crash rates
|
||
|
|
- Memory usage
|
||
|
|
- Response times
|
||
|
|
|
||
|
|
This integration provides a solid foundation for more natural, efficient playerbot movement while maintaining compatibility with your existing systems.
|