#include "baby_idle_behavior.h" #include "esp_log.h" #include "esp_random.h" #include "esp_timer.h" static const char* TAG = "BabyIdleBehavior"; namespace sweekar { namespace demo7 { namespace { constexpr int64_t kFirstRandomIdleDelayUs = 5000000; // 5s after entering idle constexpr int64_t kRandomIdleCooldownUs = 7000000; // 7s after a random idle script constexpr const char* kBaseIdleScript = "baby/idle/look_around"; constexpr const char* kCuriousIdleScript = "baby/interaction/curious"; constexpr const char* kShyIdleScript = "baby/interaction/shy"; } // namespace void BabyIdleBehavior::OnEnter(IPetContext* ctx) { PlayBaseIdle(ctx); ScheduleRandomIdle(kFirstRandomIdleDelayUs); phase_ = Phase::WAITING_RANDOM_IDLE; } void BabyIdleBehavior::OnExit(IPetContext* ctx) { ctx->StopScript(); next_random_idle_us_ = 0; phase_ = Phase::PLAYING_BASE_IDLE; } bool BabyIdleBehavior::HandleEvent(IPetContext* ctx, const Event& evt) { switch (evt.type) { case EventType::EVT_TOUCH_TAP: ESP_LOGI(TAG, "Baby got touched. Play surprised."); ctx->PlayScript("interaction/surprised"); phase_ = Phase::PLAYING_RANDOM_IDLE; return true; case EventType::EVT_KEY_LEFT_CLICK: ESP_LOGI(TAG, "Left clicked in BabyIdle. Opening Baby Menu."); ctx->RequestModeSwitch(PetModeType::MODE_MENU); return true; case EventType::EVT_KEY_RIGHT_CLICK: ESP_LOGI(TAG, "Right clicked in BabyIdle. Learn to talk."); ctx->PlayScript("interaction/learned_to_talk"); phase_ = Phase::PLAYING_RANDOM_IDLE; return true; case EventType::EVT_GYRO_SHAKE: ESP_LOGI(TAG, "Baby shaken. Play dizzy."); ctx->PlayScript("interaction/dizzy"); phase_ = Phase::PLAYING_RANDOM_IDLE; return true; case EventType::EVT_TOUCH_SWIPE_LEFT: ESP_LOGI(TAG, "Baby touch swipe left. Play hurt."); ctx->PlayScript("baby/interaction/hurt"); phase_ = Phase::PLAYING_RANDOM_IDLE; return true; case EventType::EVT_TOUCH_SWIPE_RIGHT: ESP_LOGI(TAG, "Baby touch swipe right. Play curious."); ctx->PlayScript(kCuriousIdleScript); phase_ = Phase::PLAYING_RANDOM_IDLE; return true; case EventType::EVT_SCRIPT_DONE: ESP_LOGI(TAG, "Baby idle script done."); PlayBaseIdle(ctx); if (phase_ == Phase::PLAYING_RANDOM_IDLE) { ScheduleRandomIdle(kRandomIdleCooldownUs); phase_ = Phase::COOLDOWN_AFTER_RANDOM; } return true; default: return false; } } void BabyIdleBehavior::OnTick(IPetContext* ctx) { if (!IsRandomIdleDue()) { return; } PlayRandomIdle(ctx); phase_ = Phase::PLAYING_RANDOM_IDLE; } void BabyIdleBehavior::PlayBaseIdle(IPetContext* ctx) { ESP_LOGI(TAG, "Play base idle script: %s", kBaseIdleScript); ctx->PlayScript(kBaseIdleScript); } void BabyIdleBehavior::PlayRandomIdle(IPetContext* ctx) { uint32_t roll = esp_random() % 100; const char* script = roll < 50 ? kCuriousIdleScript : kShyIdleScript; ESP_LOGI(TAG, "Play random idle script: %s, roll=%lu", script, static_cast(roll)); ctx->PlayScript(script); } void BabyIdleBehavior::ScheduleRandomIdle(int64_t delay_us) { next_random_idle_us_ = esp_timer_get_time() + delay_us; } bool BabyIdleBehavior::IsRandomIdleDue() const { if (phase_ != Phase::WAITING_RANDOM_IDLE && phase_ != Phase::COOLDOWN_AFTER_RANDOM) { return false; } return next_random_idle_us_ > 0 && esp_timer_get_time() >= next_random_idle_us_; } } // namespace demo7 } // namespace sweekar