Add a coffee break
Every so often a mug appears at the cat's nose, it sits down, dips its head in and takes a few slow sips while steam rises. M01, optional stop. The mug lives in its own click-through window like the chip, or inside the overlay on Wayland. It goes away as soon as the cat is petted, dragged, sent to sleep or moves on to something else, so no mug is ever left standing. Also renames OverlayWindow's mode flag, which shadowed QWindow::active. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0f1df75a1d
commit
403ac30b3a
14 files changed
+283
-18
No files matched your search
@@ -99,6 +99,19 @@ void AppSettings::setChipsEnabled(bool enabled)
|
||||
emit chipsEnabledChanged();
|
||||
}
|
||||
|
||||
bool AppSettings::coffeeEnabled() const
|
||||
{
|
||||
return m_settings.value("coffeeEnabled", true).toBool();
|
||||
}
|
||||
|
||||
void AppSettings::setCoffeeEnabled(bool enabled)
|
||||
{
|
||||
if (enabled == coffeeEnabled())
|
||||
return;
|
||||
m_settings.setValue("coffeeEnabled", enabled);
|
||||
emit coffeeEnabledChanged();
|
||||
}
|
||||
|
||||
int AppSettings::petCount() const
|
||||
{
|
||||
return m_settings.value("petCount", 0).toInt();
|
||||
|
||||
@@ -18,6 +18,7 @@ class AppSettings : public QObject
|
||||
Q_PROPERTY(int bottomMargin READ bottomMargin WRITE setBottomMargin NOTIFY bottomMarginChanged)
|
||||
Q_PROPERTY(bool showCodes READ showCodes WRITE setShowCodes NOTIFY showCodesChanged)
|
||||
Q_PROPERTY(bool chipsEnabled READ chipsEnabled WRITE setChipsEnabled NOTIFY chipsEnabledChanged)
|
||||
Q_PROPERTY(bool coffeeEnabled READ coffeeEnabled WRITE setCoffeeEnabled NOTIFY coffeeEnabledChanged)
|
||||
Q_PROPERTY(int petCount READ petCount NOTIFY petCountChanged)
|
||||
|
||||
public:
|
||||
@@ -44,6 +45,9 @@ public:
|
||||
bool chipsEnabled() const;
|
||||
void setChipsEnabled(bool enabled);
|
||||
|
||||
bool coffeeEnabled() const;
|
||||
void setCoffeeEnabled(bool enabled);
|
||||
|
||||
int petCount() const;
|
||||
void incrementPetCount();
|
||||
|
||||
@@ -55,6 +59,7 @@ signals:
|
||||
void bottomMarginChanged();
|
||||
void showCodesChanged();
|
||||
void chipsEnabledChanged();
|
||||
void coffeeEnabledChanged();
|
||||
void petCountChanged();
|
||||
|
||||
private:
|
||||
|
||||
@@ -95,6 +95,7 @@ void CatController::setPaused(bool paused)
|
||||
m_moodTimer.stop();
|
||||
m_chipTimer.stop();
|
||||
endChase();
|
||||
endCoffee();
|
||||
setMood(Mood::Sleeping);
|
||||
} else {
|
||||
pickNextMood();
|
||||
@@ -112,6 +113,7 @@ void CatController::setDragging(bool dragging)
|
||||
return;
|
||||
if (dragging) {
|
||||
m_moodTimer.stop();
|
||||
endCoffee();
|
||||
setMood(Mood::Alert);
|
||||
} else if (!m_paused) {
|
||||
holdMood(Mood::Sitting, 1500);
|
||||
@@ -132,6 +134,7 @@ void CatController::pet()
|
||||
return;
|
||||
m_settings->incrementPetCount();
|
||||
endChase();
|
||||
endCoffee();
|
||||
holdMood(Mood::Loving, 1800);
|
||||
}
|
||||
|
||||
@@ -140,7 +143,13 @@ void CatController::doTrick(Mood mood)
|
||||
if (m_paused)
|
||||
return;
|
||||
m_frozen = false;
|
||||
if (mood == Mood::Drinking) {
|
||||
coffeeBreak();
|
||||
return;
|
||||
}
|
||||
endChase();
|
||||
if (mood != Mood::Drinking)
|
||||
endCoffee();
|
||||
holdMood(mood, mood == Mood::Sleeping ? 15000 : 3500);
|
||||
}
|
||||
|
||||
@@ -155,6 +164,10 @@ void CatController::tossChip()
|
||||
{
|
||||
if (m_paused || m_frozen || m_chipVisible)
|
||||
return;
|
||||
if (m_cupVisible) { // finish the coffee first
|
||||
scheduleChip();
|
||||
return;
|
||||
}
|
||||
if (!m_settings->chipsEnabled()) {
|
||||
scheduleChip();
|
||||
return;
|
||||
@@ -173,6 +186,40 @@ void CatController::tossChip()
|
||||
setMood(Mood::Chasing);
|
||||
}
|
||||
|
||||
// A mug appears at the cat's nose, it sits down and takes its time.
|
||||
void CatController::coffeeBreak()
|
||||
{
|
||||
if (m_paused || m_frozen)
|
||||
return;
|
||||
|
||||
endChase();
|
||||
const qreal reach = m_catWidth * 1.08; // just past the whiskers
|
||||
const qreal edge = m_catWidth * 0.5;
|
||||
|
||||
// Put the mug on the side the cat faces, unless that runs off the screen.
|
||||
qreal wanted = m_facingRight ? m_x + reach : m_x + m_catWidth - reach;
|
||||
if (wanted < edge || wanted > m_stageWidth - edge) {
|
||||
setFacingRight(!m_facingRight);
|
||||
wanted = m_facingRight ? m_x + reach : m_x + m_catWidth - reach;
|
||||
}
|
||||
m_cupX = qBound(edge, wanted, m_stageWidth - edge);
|
||||
emit cupXChanged();
|
||||
|
||||
if (!m_cupVisible) {
|
||||
m_cupVisible = true;
|
||||
emit cupVisibleChanged();
|
||||
}
|
||||
holdMood(Mood::Drinking, QRandomGenerator::global()->bounded(7000, 12000));
|
||||
}
|
||||
|
||||
void CatController::endCoffee()
|
||||
{
|
||||
if (!m_cupVisible)
|
||||
return;
|
||||
m_cupVisible = false;
|
||||
emit cupVisibleChanged();
|
||||
}
|
||||
|
||||
void CatController::batChip()
|
||||
{
|
||||
auto *rng = QRandomGenerator::global();
|
||||
@@ -306,9 +353,15 @@ void CatController::pickNextMood()
|
||||
return;
|
||||
}
|
||||
|
||||
endCoffee();
|
||||
|
||||
auto *rng = QRandomGenerator::global();
|
||||
const int roll = rng->bounded(100);
|
||||
|
||||
if (roll < 8 && m_settings->coffeeEnabled()) {
|
||||
coffeeBreak();
|
||||
return;
|
||||
}
|
||||
if (roll < 45) {
|
||||
if (rng->bounded(100) < 20)
|
||||
setFacingRight(!m_facingRight);
|
||||
|
||||
+12
-1
@@ -30,9 +30,11 @@ class CatController : public QObject
|
||||
Q_PROPERTY(bool chipVisible READ chipVisible NOTIFY chipVisibleChanged)
|
||||
Q_PROPERTY(qreal chipX READ chipX NOTIFY chipXChanged)
|
||||
Q_PROPERTY(int chipKick READ chipKick NOTIFY chipKickChanged)
|
||||
Q_PROPERTY(bool cupVisible READ cupVisible NOTIFY cupVisibleChanged)
|
||||
Q_PROPERTY(qreal cupX READ cupX NOTIFY cupXChanged)
|
||||
|
||||
public:
|
||||
enum class Mood { Walking, Running, Sitting, Grooming, Stretching, Sleeping, Loving, Alert, Chasing, Batting };
|
||||
enum class Mood { Walking, Running, Sitting, Grooming, Stretching, Sleeping, Loving, Alert, Chasing, Batting, Drinking };
|
||||
Q_ENUM(Mood)
|
||||
|
||||
explicit CatController(AppSettings *settings, QObject *parent = nullptr);
|
||||
@@ -67,10 +69,13 @@ public:
|
||||
bool chipVisible() const { return m_chipVisible; }
|
||||
qreal chipX() const { return m_chipX; }
|
||||
int chipKick() const { return m_chipKick; }
|
||||
bool cupVisible() const { return m_cupVisible; }
|
||||
qreal cupX() const { return m_cupX; }
|
||||
|
||||
Q_INVOKABLE void pet();
|
||||
Q_INVOKABLE void doTrick(Mood mood);
|
||||
Q_INVOKABLE void tossChip();
|
||||
Q_INVOKABLE void coffeeBreak();
|
||||
|
||||
signals:
|
||||
void xChanged();
|
||||
@@ -86,6 +91,8 @@ signals:
|
||||
void chipVisibleChanged();
|
||||
void chipXChanged();
|
||||
void chipKickChanged();
|
||||
void cupVisibleChanged();
|
||||
void cupXChanged();
|
||||
|
||||
private:
|
||||
void tick();
|
||||
@@ -97,6 +104,7 @@ private:
|
||||
void holdMood(Mood mood, int ms);
|
||||
void batChip();
|
||||
void endChase();
|
||||
void endCoffee();
|
||||
void scheduleChip();
|
||||
qreal catNose() const;
|
||||
|
||||
@@ -124,4 +132,7 @@ private:
|
||||
qreal m_chipX = 0;
|
||||
int m_chipKick = 0;
|
||||
int m_batsLeft = 0;
|
||||
|
||||
bool m_cupVisible = false;
|
||||
qreal m_cupX = 0;
|
||||
};
|
||||
@@ -17,6 +17,7 @@ TrayController::TrayController(CatController *cat, QObject *parent)
|
||||
{ QT_TR_NOOP("Stretch"), CatController::Mood::Stretching },
|
||||
{ QT_TR_NOOP("Dash"), CatController::Mood::Running },
|
||||
{ QT_TR_NOOP("Nap"), CatController::Mood::Sleeping },
|
||||
{ QT_TR_NOOP("Coffee break"), CatController::Mood::Drinking },
|
||||
};
|
||||
for (const auto &e : entries) {
|
||||
const auto mood = e.mood;
|
||||
|
||||
Reference in new issue
Block a user