feedback3 WB: 圣聆初雪 S2 freezes the protection point (the blue gate) once it holds 5 snow layers, deploy attributes ignored, and no other tile; the frozen gate shows as an ice diamond instead of her own face (PRTS 备注, community report #32)

This commit is contained in:
sganggs committed 2026-10-04 17:38:07 +08:00
1 parent e53a181ae9
commit 3e9f81fcbf
6 files changed
+83 -17

No files matched your search

+13 -1
View File
@@ -1077,7 +1077,7 @@ const DIAMOND_MAX = 160; // ≈ 16 MB of 160×160 canvases at most (plus t
* @param {{ enemy?: boolean, golden?: boolean }} [o]
*/
export function diamondTexture(key, img, color, o = {}) {
const k = `${key}|${img ? 1 : 0}|${color}|${o.golden ? 1 : 0}`;
const k = `${key}|${img ? 1 : 0}|${color}|${o.golden ? 1 : 0}|${o.ice ? 1 : 0}`;
let tex = _diamonds.get(k);
if (tex) { _diamonds.delete(k); _diamonds.set(k, tex); return tex; }
const P = PIXI();
@@ -1095,6 +1095,18 @@ export function diamondTexture(key, img, color, o = {}) {
const sc = Math.max((S - 20) / img.width, (S - 20) / img.height) * 1.02;
const w = img.width * sc, hh = img.height * sc;
try { c.drawImage(img, h - w / 2, h - hh / 2, w, hh); } catch { /* tainted/broken image */ }
} else if (o.ice) {
// 圣聆初雪's frozen gate (保护目标(冻结状态), PRTS 无头像, no model in the manifest): a snowflake on a frosty field
const g = c.createRadialGradient(h, h, 4, h, h, h);
g.addColorStop(0, 'rgba(205,240,255,0.95)'); g.addColorStop(1, 'rgba(0,0,0,0)');
c.fillStyle = g; c.fillRect(0, 0, S, S);
c.strokeStyle = '#f2fbff'; c.lineWidth = 6; c.lineCap = 'round';
for (let i = 0; i < 6; i++) {
const a = (i * Math.PI) / 3, x1 = h + Math.cos(a) * 34, y1 = h + Math.sin(a) * 34;
c.beginPath(); c.moveTo(h, h); c.lineTo(x1, y1); c.stroke();
const bx = h + Math.cos(a) * 20, by = h + Math.sin(a) * 20;
for (const s of [-1, 1]) { c.beginPath(); c.moveTo(bx, by); c.lineTo(bx + Math.cos(a + s * 0.8) * 11, by + Math.sin(a + s * 0.8) * 11); c.stroke(); }
}
} else {
// procedural glyph (e.g. 心烛 enemy_5601_entlec has no art anywhere)
const g = c.createRadialGradient(h, h, 4, h, h, h);
+9 -2
View File
@@ -99,6 +99,11 @@ export function dieClipDur(entry) {
/** World step (x = col, y = row) of a direction. */
export const DIR_STEP = Object.freeze({ UP: [0, 1], RIGHT: [1, 0], DOWN: [0, -1], LEFT: [-1, 0] });
const nowMs = () => (globalThis.performance ? globalThis.performance.now() : Date.now());
/** Units with no art in the game data drawn as an ice diamond: 圣聆初雪 S2's frozen protection point (保护目标(冻结状态), PRTS
* 无头像; data/assets.json has no avatar or model for it, so the token fallback showed 圣聆初雪's own face) — the marker of a
* frozen gate. */
const ICE_TOKENS = new Set(['token_10058_sbell2_icetgt']);
const ICE_FRAME = 0x9fe6ff;
/** How long a view waits for its avatar before showing the image-less placeholder diamond. */
const PIC_WAIT_MS = 400;
/**
@@ -380,6 +385,7 @@ export class UnitView {
_frameColor() {
if (this.isEnemy) return this.isBoss ? ENEMY_FRAME.boss : this.tier >= 2 ? ENEMY_FRAME.elite : ENEMY_FRAME.normal;
if (ICE_TOKENS.has(this.info.defId)) return ICE_FRAME;
if (this.golden) return 0xffc600;
return TIER_COLORS[this.tier] || TIER_COLORS[1];
}
@@ -390,7 +396,8 @@ export class UnitView {
// is missing or still loading after PIC_WAIT_MS).
_loadPicture() {
const a = this.ctx.assets;
const url = a && (a.picture ? a.picture(this.info.avatar) || a.picture(this.info.defId) || a.picture(this.info.spine) : null);
// (an ICE_TOKENS unit takes no picture: the token fallback would be its owner's face — assets.js tokenAvatarUrl)
const url = ICE_TOKENS.has(this.info.defId) ? null : a && (a.picture ? a.picture(this.info.avatar) || a.picture(this.info.defId) || a.picture(this.info.spine) : null);
this._pic = { key: String(this.info.avatar || this.info.defId || 'unknown'), color: this._frameColor(), img: null, state: 'none', shown: null, t0: nowMs() };
if (!url || !a.image) return;
const cached = typeof a.imageNow === 'function' ? a.imageNow(url) : null;
@@ -409,7 +416,7 @@ export class UnitView {
let want = pic.state === 'img' ? 'img' : 'placeholder';
if (pic.state === 'wait' && nowMs() - pic.t0 < PIC_WAIT_MS) want = null;
if (!want || pic.shown === want) return;
this.fallback.texture = diamondTexture(pic.key, want === 'img' ? pic.img : null, pic.color, { enemy: this.isEnemy, golden: this.golden });
this.fallback.texture = diamondTexture(pic.key, want === 'img' ? pic.img : null, pic.color, { enemy: this.isEnemy, golden: this.golden, ice: ICE_TOKENS.has(this.info.defId) });
pic.shown = want;
}