Files
behavior3editor/baby/baby_idle_behavior copy.cpp
T

116 lines
3.7 KiB
C++

#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<unsigned long>(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