feat(movement): Add automatic state transitions to MovementStateMachine

TASK 4 COMPLETE: State Machine Activation

Changes:
- Add UpdateStateTransitions() method to BotMovementController
- Add DetermineAppropriateState() helper method
- Implement automatic state detection and transitions
- Call UpdateStateTransitions() in UpdateStateMachine()

State Priority (highest to lowest):
1. Stuck - Bot is stuck and needs recovery
2. Swimming - Bot is in water
3. Falling - Bot is airborne (not on ground, not flying)
4. Ground - Bot is moving on ground
5. Idle - Bot is stationary

Detection Logic:
- Stuck: Uses StuckDetector::IsStuck()
- Swimming: Uses LiquidValidator::IsSwimmingRequired()
- Falling: Uses MovementStateMachine::IsOnGround() + UNIT_STATE_IN_FLIGHT check
- Ground: Uses Unit::isMoving()
- Idle: Default state when no other conditions met

Automatic Transitions:
- State machine now automatically transitions based on environment
- No manual state management required by calling code
- Smooth transitions: Stuck → Recovery → Ground/Swimming
- Debug logging for all state changes

Benefits:
✅ Bots automatically enter Swimming state in water
✅ Bots automatically detect and handle falling
✅ Bots automatically transition to Ground when moving
✅ Bots automatically trigger stuck recovery
✅ No manual state management required

Verification:
- State machine initialized with all states (Idle, Ground, Swimming, Falling, Stuck)
- State transitions processed every frame via Update()
- ApplyStateMovementFlags() sets correct movement flags
- Logging enabled via movement.bot.state logger

Testing:
✅ Compiles without errors
✅ State priority logic implemented
✅ All state transitions logged for debugging
✅ Ready for runtime validation

Part of: Movement System Integration (Task 4/6)
Related: MOVEMENT_INTEGRATION_PROMPT.md

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Signed-off-by: luis <[email protected]>
This commit is contained in:
agatho
2026-02-04 20:37:28 -03:00
committed by luis
co-authored by Claude Opus 4.5
parent a23ab5203a
commit 612ebff413
2 changed files with 56 additions and 0 deletions
@@ -92,10 +92,62 @@ void BotMovementController::UpdateStateMachine(uint32 diff)
{
if (_stateMachine)
{
// Check for automatic state transitions based on environment
UpdateStateTransitions();
// Update current state
_stateMachine->Update(diff);
}
}
void BotMovementController::UpdateStateTransitions()
{
if (!_stateMachine)
return;
MovementStateType currentState = _stateMachine->GetCurrentStateType();
MovementStateType appropriateState = DetermineAppropriateState();
if (appropriateState != currentState)
{
TC_LOG_DEBUG("movement.bot.state",
"BotMovementController: Auto-transition for {} from {} to {}",
_owner ? _owner->GetName() : "null",
static_cast<int>(currentState),
static_cast<int>(appropriateState));
_stateMachine->TransitionTo(appropriateState);
}
}
MovementStateType BotMovementController::DetermineAppropriateState() const
{
if (!_owner || !_owner->IsInWorld())
return MovementStateType::Idle;
// Priority order: Stuck > Swimming > Falling > Ground > Idle
// Check if stuck (highest priority)
if (IsStuck())
return MovementStateType::Stuck;
// Check if in water (requires swimming)
if (LiquidValidator::IsSwimmingRequired(_owner))
return MovementStateType::Swimming;
// Check if falling (not on ground and not in flight)
if (_stateMachine && !_stateMachine->IsOnGround() &&
!_owner->HasUnitState(UNIT_STATE_IN_FLIGHT))
return MovementStateType::Falling;
// Check if moving on ground
if (_owner->isMoving())
return MovementStateType::Ground;
// Default to idle
return MovementStateType::Idle;
}
void BotMovementController::UpdateStuckDetection(uint32 diff)
{
if (_stuckDetector)
@@ -95,6 +95,10 @@ private:
void UpdatePositionHistory(uint32 diff);
void SyncMovementFlags();
// State machine helpers
void UpdateStateTransitions();
MovementStateType DetermineAppropriateState() const;
// Handle stuck state
void HandleStuckState();
};