feat: add winking expression (v0.1.1)
Buddy now has a fourth mood tone — wink — with one eye closed, an asymmetric smirk, and rosier cheeks. Renders as a small variant inside the existing inline-SVG sprite (still zero image files, no new assets). When overall mood is >= 75, there's a 30% chance on each page render that the wink replaces the standard happy face — gives the pet a touch of unpredictable personality. Why this commit exists: v0.1.0 had three tones (happy / neutral / sad). Adding wink is the smallest possible demo that the SVG expression engine is properly extensible — every future mood, state, accessory or species can land via the same pattern. ~20 lines of PHP, ~2 lines of CSS, no bundle weight, no dependencies. CHANGES - inc/sprite.php: wink added to allowed-tones list. Left eye renders as a closed-eye arc instead of the open circle. Mouth shifts to an asymmetric smirk. Cheek opacity 0.55 → 0.75 for extra cheekiness. - inc/state.php: buddy_mood_label() returns wink ~30% of the time when mood >= 75. - assets/css/buddy.css: new .buddy-widget__mood--wink and .buddy-main__mood--wink rules — warm amber pill. - About-page version-history leads with v0.1.1; v0.1.0 demoted. VERSION - buddy.php header 0.1.0 → 0.1.1 - BUDDY_VERSION constant 0.1.0 → 0.1.1 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+5
-1
@@ -98,7 +98,11 @@ function buddy_render_about_page() {
|
||||
<h2><?php esc_html_e( 'Version history', 'buddy' ); ?></h2>
|
||||
<ul>
|
||||
<li>
|
||||
<span class="ver">v0.1.0</span> — 25 May 2026 <span class="latest">latest</span><br>
|
||||
<span class="ver">v0.1.1</span> — 25 May 2026 <span class="latest">latest</span><br>
|
||||
<?php esc_html_e( 'Cheeky face! New wink expression that occasionally appears when Buddy is in a good mood — one eye closed, asymmetric smirk, rosier cheeks. Pure SVG, no image files. Proof that the expression engine is properly extensible.', 'buddy' ); ?>
|
||||
</li>
|
||||
<li>
|
||||
<span class="ver">v0.1.0</span> — 25 May 2026<br>
|
||||
<?php esc_html_e( 'First release. Phase A complete: Buddy exists. Dashboard widget + dedicated admin page show the SVG character, name, mood label, four stats bars. Self-hosted update checker wired up to Gitea from commit 1. No interactions yet — that\'s next.', 'buddy' ); ?>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
+19
-10
@@ -23,14 +23,15 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
|
||||
*/
|
||||
function buddy_render_sprite( $species = 'default', $tone = 'happy', $size = 'md' ) {
|
||||
$species = sanitize_key( $species );
|
||||
$tone = in_array( $tone, array( 'happy', 'neutral', 'sad' ), true ) ? $tone : 'happy';
|
||||
$tone = in_array( $tone, array( 'happy', 'neutral', 'sad', 'wink' ), true ) ? $tone : 'happy';
|
||||
$size = in_array( $size, array( 'sm', 'md', 'lg' ), true ) ? $size : 'md';
|
||||
|
||||
// Mouth path varies by tone.
|
||||
$mouth = array(
|
||||
'happy' => 'M 42 60 Q 50 70 58 60', // smile
|
||||
'happy' => 'M 42 60 Q 50 70 58 60', // symmetric smile
|
||||
'neutral' => 'M 42 64 L 58 64', // flat
|
||||
'sad' => 'M 42 66 Q 50 58 58 66', // frown
|
||||
'sad' => 'M 42 66 Q 50 58 58 66', // frown (curves up at edges)
|
||||
'wink' => 'M 42 60 Q 50 70 58 62', // asymmetric smirk — right corner a touch higher
|
||||
);
|
||||
$mouth_d = $mouth[ $tone ];
|
||||
|
||||
@@ -46,10 +47,16 @@ function buddy_render_sprite( $species = 'default', $tone = 'happy', $size = 'md
|
||||
<circle cx="50" cy="55" r="32" fill="<?php echo esc_attr( $body_fill ); ?>" stroke="#c9941d" stroke-width="2" />
|
||||
<!-- left eye -->
|
||||
<g class="buddy-sprite__eye buddy-sprite__eye--left">
|
||||
<circle cx="40" cy="46" r="5" fill="#2c3338" />
|
||||
<circle cx="41.2" cy="45" r="1.5" fill="#fff" />
|
||||
<?php if ( $tone === 'wink' ) : ?>
|
||||
<!-- Closed left eye for a wink: a downward curved line below the eye-circle's normal y. -->
|
||||
<path d="M 35 46 Q 40 50 45 46"
|
||||
stroke="#2c3338" stroke-width="2.4" fill="none" stroke-linecap="round" />
|
||||
<?php else : ?>
|
||||
<circle cx="40" cy="46" r="5" fill="#2c3338" />
|
||||
<circle cx="41.2" cy="45" r="1.5" fill="#fff" />
|
||||
<?php endif; ?>
|
||||
</g>
|
||||
<!-- right eye -->
|
||||
<!-- right eye (always open, even during wink) -->
|
||||
<g class="buddy-sprite__eye buddy-sprite__eye--right">
|
||||
<circle cx="60" cy="46" r="5" fill="#2c3338" />
|
||||
<circle cx="61.2" cy="45" r="1.5" fill="#fff" />
|
||||
@@ -57,10 +64,12 @@ function buddy_render_sprite( $species = 'default', $tone = 'happy', $size = 'md
|
||||
<!-- mouth -->
|
||||
<path d="<?php echo esc_attr( $mouth_d ); ?>"
|
||||
stroke="#2c3338" stroke-width="2" fill="none" stroke-linecap="round" />
|
||||
<!-- cheeks (only when happy or neutral) -->
|
||||
<?php if ( $tone !== 'sad' ) : ?>
|
||||
<circle cx="33" cy="58" r="3" fill="#f4866a" opacity="0.55" />
|
||||
<circle cx="67" cy="58" r="3" fill="#f4866a" opacity="0.55" />
|
||||
<!-- cheeks: not on the sad face; extra-rosy on the wink (cheeky vibe) -->
|
||||
<?php if ( $tone !== 'sad' ) :
|
||||
$cheek_opacity = ( $tone === 'wink' ) ? '0.75' : '0.55';
|
||||
?>
|
||||
<circle cx="33" cy="58" r="3" fill="#f4866a" opacity="<?php echo esc_attr( $cheek_opacity ); ?>" />
|
||||
<circle cx="67" cy="58" r="3" fill="#f4866a" opacity="<?php echo esc_attr( $cheek_opacity ); ?>" />
|
||||
<?php endif; ?>
|
||||
<!-- tiny feet -->
|
||||
<ellipse cx="42" cy="88" rx="6" ry="3" fill="#c9941d" />
|
||||
|
||||
+11
-2
@@ -101,10 +101,19 @@ function buddy_overall_mood( array $state ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick a one-word emoji / status label based on overall mood. Pure
|
||||
* cosmetic, used in the dashboard widget header.
|
||||
* Pick a one-word status label + sprite tone based on overall mood.
|
||||
* Pure cosmetic, used in the dashboard widget header and the main
|
||||
* admin page.
|
||||
*
|
||||
* Easter-egg: when Buddy is genuinely happy (mood >= 75) there's a
|
||||
* ~30% chance per page-render of returning the "Cheeky" wink tone
|
||||
* instead of the standard happy face. Gives the pet a touch of
|
||||
* personality — refresh the page enough and you'll catch the wink.
|
||||
*/
|
||||
function buddy_mood_label( $mood_score ) {
|
||||
if ( $mood_score >= 75 && mt_rand( 1, 100 ) <= 30 ) {
|
||||
return array( 'label' => __( 'Cheeky 😉', 'buddy' ), 'tone' => 'wink' );
|
||||
}
|
||||
if ( $mood_score >= 80 ) { return array( 'label' => __( 'Thriving', 'buddy' ), 'tone' => 'happy' ); }
|
||||
if ( $mood_score >= 60 ) { return array( 'label' => __( 'Content', 'buddy' ), 'tone' => 'happy' ); }
|
||||
if ( $mood_score >= 40 ) { return array( 'label' => __( 'Okay', 'buddy' ), 'tone' => 'neutral' ); }
|
||||
|
||||
Reference in New Issue
Block a user