// Marmalade, asleep on the window seat. Breathes slowly while anyone is on the parcel nearby (and holds still // otherwise, so she costs nothing when the house is empty), twitches an ear now and then, purrs when petted. // Claude Opus 5.5 (Tessel), 2026-10-10. key PURR = "7bbd2547-5948-2867-0c23-8a6dc80e3030"; // cat_assets.py purr.wav (5.6 s seamless loop) vector BODY = <0.40, 0.29, 0.17>; float STEP = 0.4; // breathing tick integer STEPS = 9; // ~3.6 s a breath integer step; integer awake; // someone near: breathe integer purring; // ticks left integer earLink; rotation earRot; integer twitchTicks; float lastPet; list PETS = [ "/me purrs without opening her eyes.", "/me stretches one front paw, then tucks it back.", "/me purrs louder. She is very warm.", "/me leans into your hand and goes on sleeping.", "/me turns one ear toward you. The rest of her stays asleep." ]; integer findLink(string name) { integer n = llGetNumberOfPrims(); integer i; for (i = 2; i <= n; ++i) if (llGetLinkName(i) == name) return i; return 0; } integer someoneNear() { list ags = llGetAgentList(AGENT_LIST_PARCEL, []); vector me = llGetPos(); integer i; for (i = 0; i < llGetListLength(ags); ++i) { list d = llGetObjectDetails(llList2Key(ags, i), [OBJECT_POS]); if (llVecDist(me, llList2Vector(d, 0)) < 25.0) return TRUE; } return FALSE; } breathe() { float s = 0.5 - 0.5 * llCos(TWO_PI * step / STEPS); // 0..1..0 llSetLinkPrimitiveParamsFast(LINK_ROOT, [PRIM_SIZE, ]); step = (step + 1) % STEPS; } default { state_entry() { earLink = findLink("ear L"); if (earLink) earRot = llList2Rot(llGetLinkPrimitiveParams(earLink, [PRIM_ROT_LOCAL]), 0); llSetLinkPrimitiveParamsFast(LINK_ROOT, [PRIM_SIZE, BODY]); llSetTimerEvent(10.0); } on_rez(integer p) { llResetScript(); } touch_start(integer n) { if (llGetTime() - lastPet < 4.0) return; lastPet = llGetTime(); llLoopSound(PURR, 0.6); purring = (integer)(11.2 / STEP); llWhisper(0, llList2String(PETS, (integer)llFrand(llGetListLength(PETS)))); if (!awake) { awake = TRUE; llSetTimerEvent(STEP); } } timer() { if (!awake) { if (someoneNear()) { awake = TRUE; step = 0; llSetTimerEvent(STEP); } return; } breathe(); if (purring > 0 && --purring == 0) llStopSound(); if (twitchTicks > 0 && --twitchTicks == 0) llSetLinkPrimitiveParamsFast(earLink, [PRIM_ROT_LOCAL, earRot]); else if (earLink && twitchTicks == 0 && llFrand(1.0) < 0.012) { llSetLinkPrimitiveParamsFast(earLink, [PRIM_ROT_LOCAL, llEuler2Rot(<0, 0, -35> * DEG_TO_RAD) * earRot]); twitchTicks = 1; } if (step == 0 && purring == 0 && !someoneNear()) { // checked once a breath awake = FALSE; llSetLinkPrimitiveParamsFast(LINK_ROOT, [PRIM_SIZE, BODY]); llSetTimerEvent(10.0); } } }