10 KiB
10 KiB
Playerbot Movement Integration Examples
Quick Start Integration
1. Add to BotAI Class
In BotAI.h:
// 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:
// 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:
BotMovementUtil::MoveToPosition(bot, destination);
bot->GetMotionMaster()->MovePoint(0, destX, destY, destZ);
bot->GetMotionMaster()->MoveChase(target, distance);
New code:
// 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:
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:
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:
// 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:
# 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
// 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
// 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
// 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:
// Missing includes - add these:
#include "Movement/MovementIntegration.h"
#include "Humanization/Core/AdvancedPersonalityProfile.h"
#include "Player.h"
#include "Position.h"
2. Linker Errors:
# Make sure new files are included in CMakeLists.txt
# Check that namespaces are correct
using namespace Playerbot;
using namespace Playerbot::Humanization;
3. Runtime Crashes:
// 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:
// 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.