tarinai/js/tarinai_cursor_care_system.js

39 lines
1.6 KiB
JavaScript

"use strict";
// Layer: entity-runtime/tarinai/update-system
// Owns pointer proximity care and cursor-heart effects.
(function (global) {
function updateBody(dt) {
const pointer = this.world?.pointer;
if (!pointer?.inside || !this.isAwakeCursorFriendly()) return;
const d = distXY(this.x, this.y, pointer.x, pointer.y);
const touch = this.radius * 1.35;
if (d > touch) return;
const p = clamp(1 - d / touch, 0, 1);
const relief = dt * (1.35 + 2.65 * p);
applyNeedRelief(this, { safety: -relief * 1.2, fulfill: -relief * 1.6 });
this.adjustPersonality("openness", dt * 0.006 * (0.4 + p), "after being petted.");
this.moodLiftTimer = Math.max(this.moodLiftTimer || 0, 0.5);
this.cursorPetting = clamp((this.cursorPetting || 0) + dt * (1.0 + p * 2.4), 0, 1.75);
this.goodMode = "smile";
if ((this.world.time || 0) >= (this.nextCursorHeartAt || 0)) {
this.nextCursorHeartAt = (this.world.time || 0) + Math.max(0.08, 0.22 - p * 0.10);
for (let i = 0; i < (p > 0.62 ? 3 : 2); i++) {
this.world.effects?.push(new Effect("heart", this.x + rand(-this.radius * 0.58, this.radius * 0.58), this.y - this.radius * rand(0.68, 1.58), {
vx: rand(-16, 16), vy: rand(-44, -20), size: rand(7, 13) * (0.8 + p * 0.45), life: rand(0.62, 0.95), color: "rgba(240,91,135,0.92)"
}));
}
}
}
function updateOne(tarinai, dt) {
if (!tarinai || tarinai.dead) return false;
updateBody.call(tarinai, dt);
return true;
}
global.TarinaiCursorCareSystem = Object.freeze({
updateOne,
});
})(typeof window !== "undefined" ? window : globalThis);