hmm?
This commit is contained in:
parent
9ef1b8dbb1
commit
d875df8600
22 changed files with 625 additions and 496 deletions
|
|
@ -10,9 +10,31 @@
|
|||
const quality = this.world.performanceQuality?.() || {};
|
||||
const effectDensity = clamp(Number(quality.effectDensity || 1) || 1, 0.12, 1);
|
||||
const showDecor = effectDensity > 0.45 || this.world.selected === this;
|
||||
if (this.state === "sunbath" || (this.sunbathTimer || 0) > 0.04) this.preloadSunbathSprites?.();
|
||||
const sprite = this.spriteId();
|
||||
const img = typeof getRenderableImage === "function" ? getRenderableImage(sprite, "smile") : (images.get(sprite) || images.get(this.type));
|
||||
const metrics = getImageMetrics(sprite) || getImageMetrics(this.type) || getImageMetrics("smile");
|
||||
const sunbathSprite = String(sprite || "").startsWith("sunbath");
|
||||
const sunbathCandidates = sunbathSprite && this.sunbathSpriteCandidates ? this.sunbathSpriteCandidates() : [];
|
||||
if (sunbathSprite) {
|
||||
for (const id of sunbathCandidates) {
|
||||
if (typeof ensureImage === "function") ensureImage(id);
|
||||
else if (globalThis.TarinaiAssets?.ensureImage) globalThis.TarinaiAssets.ensureImage(id);
|
||||
}
|
||||
}
|
||||
const spriteFallback = sunbathSprite ? "" : "smile";
|
||||
let renderSprite = sprite;
|
||||
let img = typeof getRenderableImage === "function" ? getRenderableImage(sprite, spriteFallback) : (images.get(sprite) || images.get(spriteFallback) || images.get(this.type));
|
||||
if (sunbathSprite) {
|
||||
const ready = (id) => typeof isImageReady === "function" ? isImageReady(id) : !!(images?.get?.(id)?.complete || images?.get?.(id)?.naturalWidth || images?.get?.(id)?.width);
|
||||
if (!ready(sprite)) {
|
||||
const fallbackSunbath = sunbathCandidates.find(id => ready(id));
|
||||
if (fallbackSunbath) {
|
||||
renderSprite = fallbackSunbath;
|
||||
img = images.get(fallbackSunbath);
|
||||
}
|
||||
}
|
||||
if (!img) img = typeof getRenderableImage === "function" ? getRenderableImage("smile", "smile") : (images.get("smile") || images.get(this.type));
|
||||
}
|
||||
const metrics = getImageMetrics(renderSprite) || getImageMetrics(sprite) || getImageMetrics(this.type) || getImageMetrics("smile");
|
||||
const w = metrics?.w || 512;
|
||||
const h = metrics?.h || 512;
|
||||
const moveSpeed = Math.hypot(this.vx, this.vy);
|
||||
|
|
@ -265,7 +287,19 @@
|
|||
const cacheW = Math.max(1, Math.round((dw * renderScale) / 8) * 8);
|
||||
const cacheH = Math.max(1, Math.round((dh * renderScale) / 8) * 8);
|
||||
if (img) {
|
||||
const spriteCanvas = typeof getCachedSpriteCanvas === "function" ? getCachedSpriteCanvas(sprite, img, cacheW, cacheH) : img;
|
||||
let spriteCacheKey = sprite;
|
||||
try {
|
||||
if (typeof images !== "undefined" && images.get?.(sprite) !== img) {
|
||||
let fallbackId = "fallback";
|
||||
for (const [imageId, imageObj] of images) {
|
||||
if (imageObj === img) { fallbackId = imageId; break; }
|
||||
}
|
||||
spriteCacheKey = `${sprite}:fallback:${fallbackId}`;
|
||||
}
|
||||
} catch (err) {
|
||||
spriteCacheKey = sprite;
|
||||
}
|
||||
const spriteCanvas = sunbathSprite ? img : (typeof getCachedSpriteCanvas === "function" ? getCachedSpriteCanvas(spriteCacheKey, img, cacheW, cacheH) : img);
|
||||
ctx.drawImage(spriteCanvas, -dw / 2, -dh / 2, dw, dh);
|
||||
} else {
|
||||
ctx.save();
|
||||
|
|
@ -279,7 +313,7 @@
|
|||
ctx.restore();
|
||||
}
|
||||
if (img && (this.zunchiStain || 0) > 3 && typeof getCachedStainOverlayCanvas === "function") {
|
||||
const stainCanvas = getCachedStainOverlayCanvas(sprite, img, cacheW, cacheH, clamp((this.zunchiStain || 0) / 100, 0, 1), this.zunchiStainSeed || 0.5);
|
||||
const stainCanvas = getCachedStainOverlayCanvas(renderSprite || sprite, img, cacheW, cacheH, clamp((this.zunchiStain || 0) / 100, 0, 1), this.zunchiStainSeed || 0.5);
|
||||
if (stainCanvas) {
|
||||
ctx.save();
|
||||
ctx.globalAlpha = clamp((this.zunchiStain || 0) / 100, 0.10, 0.88);
|
||||
|
|
@ -364,6 +398,87 @@
|
|||
}
|
||||
},
|
||||
|
||||
drawSunbathSpriteDirect(ctx, t, lightState, showDecor = true) {
|
||||
return false;
|
||||
const ids = this.sunbathSpriteCandidates ? this.sunbathSpriteCandidates() : ["sunbath_1", "sunbath_2", "sunbath_3"];
|
||||
const candidates = (Array.isArray(ids) && ids.length ? ids : ["sunbath_1", "sunbath_2", "sunbath_3"]).filter(id => String(id || "").startsWith("sunbath"));
|
||||
const now = Number(this.world?.time ?? t ?? 0) || 0;
|
||||
const frameKey = Math.floor(now / 0.5);
|
||||
if (this._sunbathRenderFrameKey !== frameKey || !candidates.includes(this._sunbathRenderSpriteId)) {
|
||||
const prev = this._sunbathRenderSpriteId || this.sunbathSpriteVariant || "";
|
||||
const choices = candidates.length > 1 ? candidates.filter(id => id !== prev) : candidates;
|
||||
this._sunbathRenderSpriteId = choices[Math.floor(Math.random() * choices.length)] || candidates[0] || "sunbath_1";
|
||||
this._sunbathRenderFrameKey = frameKey;
|
||||
}
|
||||
const sprite = this._sunbathRenderSpriteId || this.sunbathSpriteVariant || candidates[0] || "sunbath_1";
|
||||
this.sunbathSpriteVariant = sprite;
|
||||
this.visibleSpriteId = sprite;
|
||||
this.spriteLockUntil = now;
|
||||
for (const id of candidates) {
|
||||
if (typeof ensureImage === "function") ensureImage(id);
|
||||
else if (globalThis.TarinaiAssets?.ensureImage) globalThis.TarinaiAssets.ensureImage(id);
|
||||
}
|
||||
|
||||
let img = null;
|
||||
const ordered = [sprite, this.sunbathSpriteVariant, ...candidates, "smile"];
|
||||
const seen = new Set();
|
||||
for (const id of ordered) {
|
||||
if (!id || seen.has(id)) continue;
|
||||
seen.add(id);
|
||||
const next = typeof getRenderableImage === "function"
|
||||
? getRenderableImage(id, id === "smile" ? "smile" : "smile")
|
||||
: (typeof images !== "undefined" ? (images.get(id) || images.get("smile")) : null);
|
||||
const ready = next && (next.complete || next.naturalWidth || next.width);
|
||||
if (ready) { img = next; break; }
|
||||
}
|
||||
|
||||
const metrics = (typeof getImageMetrics === "function" ? (getImageMetrics(sprite) || getImageMetrics(img) || getImageMetrics("smile")) : null) || {};
|
||||
const w = metrics.w || img?.naturalWidth || img?.width || 512;
|
||||
const h = metrics.h || img?.naturalHeight || img?.height || 468;
|
||||
const visualScale = this.effectiveScale ? this.effectiveScale() : this.scale;
|
||||
const breathing = Math.sin(t * 1.4 + this.age * 0.18);
|
||||
const bob = breathing * 0.55;
|
||||
const drawW = w * visualScale * 0.30;
|
||||
const drawH = h * visualScale * 0.30;
|
||||
const squish = 1 + breathing * 0.006;
|
||||
const dw = drawW * squish;
|
||||
const dh = drawH / squish;
|
||||
const faceRight = this.facingDir ? this.facingDir() > 0 : (this.facing || 1) > 0;
|
||||
const nestHideAlpha = this.nestFade ? clamp(1 - this.nestFade, 0, 1) : 1;
|
||||
if (nestHideAlpha <= 0.01) return true;
|
||||
|
||||
const shadow = projectedShadowParams(lightState, 0.95 + visualScale * 0.8);
|
||||
const shadowContactY = this.y + bob + dh * 0.30;
|
||||
if (showDecor && img) {
|
||||
drawImageProjectedShadow(ctx, img, this.x, shadowContactY, dw, dh, shadow, {
|
||||
faceRight,
|
||||
alpha: shadow.alpha * 0.92 * nestHideAlpha,
|
||||
});
|
||||
} else if (showDecor) {
|
||||
drawProjectedShadow(ctx, this.x, shadowContactY, drawW * 0.52, drawH * 0.13, { ...shadow, alpha: shadow.alpha * 0.82 * nestHideAlpha });
|
||||
}
|
||||
if (showDecor) drawCreatureGlow(ctx, this, drawW, drawH, lightState);
|
||||
|
||||
ctx.save();
|
||||
ctx.translate(this.x, this.y + bob);
|
||||
ctx.rotate((faceRight ? 1 : -1) * (Math.PI / 18));
|
||||
if (faceRight) ctx.scale(-1, 1);
|
||||
ctx.globalAlpha = nestHideAlpha;
|
||||
if (img) {
|
||||
ctx.drawImage(img, -dw / 2, -dh / 2, dw, dh);
|
||||
} else {
|
||||
ctx.fillStyle = "#f4ead6";
|
||||
ctx.strokeStyle = "rgba(92,71,49,0.48)";
|
||||
ctx.lineWidth = 2;
|
||||
ctx.beginPath();
|
||||
ctx.ellipse(0, 0, dw * 0.42, dh * 0.36, 0, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
ctx.stroke();
|
||||
}
|
||||
ctx.restore();
|
||||
return true;
|
||||
},
|
||||
|
||||
contains(x, y) {
|
||||
if (this.insideNestBoxId || (this.nestFade || 0) >= 0.92) return false;
|
||||
const hit = this.world.screenSizeToWorld ? this.world.screenSizeToWorld(this.radius * 1.9) : this.radius * 1.9;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue