feedback5: merge R19G — 蕾缪安's S3 waits with its bullets and locks when nothing is in her range instead of ending (skill text 「打完后结束」, PRTS 卫戍协议/帮助 「通常不会自动关闭技能」; community report); golden as R19G's commit (roster-018, boss-boss_3-pair, coop2-NORMAL-14-standins), the merged tree's golden equals the branch's

This commit is contained in:
sganggs committed 2026-10-07 12:29:01 +08:00
commit 6b05295fab
11 files changed
+286 -103

No files matched your search

+2 -1
View File
@@ -18,7 +18,8 @@
// blasts explosions (fireball, flash, shockwave + coloured ground ring, sparks, smoke; heavy ones add debris
// and a scorch mark) for blast fx kinds and shell impacts
// bombard 蕾缪安 S3: fx 'lock' keeps a reticle on the locked enemy until the 'bombard' of the shell fired at it
// (or LOCK_T game s after the shooter's last lock / shell; the S2 aim lock until the snipe's 'crit'); 'bombardShell' = a shell fired now that
// (or LOCK_T game s after the shooter's last lock / shell — a held S3 lock, `hold`, LOCK_T after her skill
// ends: it waits with its bullets while nothing is in range; the S2 aim lock until the snipe's 'crit'); 'bombardShell' = a shell fired now that
// lands on the spot after `t` game s — a launch streak leaves the shooter upwards and the shell drops out
// of the sky onto the spot (a long flight climbs out of her first), a closing warning ring marks the spot
// meanwhile; 'bombard' is the big explosion at the impact
+9 -4
View File
@@ -4,6 +4,7 @@
import { SHOT_HEIGHT, bodyZ } from './camera.js';
import { FX_KINDS } from './kinds.js';
import { easeOut } from './limits.js';
import { UF } from '../../../../shared/constants.js';
/**
* Lock reticle: how long (game s) a lock outlives the last sign of its shooter's S3 going on — its latest lock, shell or
@@ -18,9 +19,11 @@ export class FxLocks {
/**
* fx 'lock': a reticle on the locked enemy (following its view; at the last spot once it is gone) until its shell
* lands (mortar / _landed) or the aimed shot fires ('crit' from the same shooter); at most LOCK_T game seconds after
* the shooter's last lock / shell / bombard (_touchLocks).
* the shooter's last lock / shell / bombard (_touchLocks). A held lock (`hold`: 蕾缪安 S3, whose skill waits with its
* bullets and locks while nothing is in range) waits as long as its shooter's skill runs (the view's UF.SKILL), its
* LOCK_T counted from the skill's end.
*/
_lock(view, src, x, y, z) {
_lock(view, src, x, y, z, hold = false) {
let L = this.lockFree.pop();
if (!L) {
const P = this.P;
@@ -34,7 +37,7 @@ export class FxLocks {
L = { ring, core };
}
L.view = view; L.id = view ? view.id : null; L.src = src ?? null; L.x = x; L.y = y; L.z = z;
L.t = 0; L.idle = 0; L.max = LOCK_T / this._ts(); L.out = -1; L.shell = false; L.sx = x; L.sy = y;
L.t = 0; L.idle = 0; L.max = LOCK_T / this._ts(); L.out = -1; L.shell = false; L.sx = x; L.sy = y; L.hold = !!hold;
L.ring.tint = L.core.tint = FX_KINDS.lock.c;
L.ring.alpha = L.core.alpha = 0;
L.ring.visible = L.core.visible = true;
@@ -77,10 +80,12 @@ export class FxLocks {
L.t += dt;
L.idle += dt;
if (L.out < 0 && L.idle >= L.max) L.out = 0;
// the shooter knocked out / withdrawn: the sim fires no more shells — only a shell already in the air still lands
// the shooter knocked out / withdrawn: the sim fires no more shells — only a shell already in the air still lands;
// a held lock waits while its shooter's skill runs (蕾缪安 S3 with nothing in range: its bullets and locks wait)
if (L.out < 0 && !L.shell && L.src != null && this.ctx.view) {
const sv = this._viewOf(L.src);
if (!sv || sv.alive === false) L.out = 0;
else if (L.hold && (sv.flags & UF.SKILL)) L.idle = 0;
}
if (L.out >= 0) { L.out += dt; if (L.out >= LOCK_FADE) { this._freeLock(L); continue; } }
const v = L.view;
+3 -2
View File
@@ -50,7 +50,7 @@ export class FxSim {
* counter, dp, coin, crate, down, beam, bolt, strike, volley, pillar, lp, chill, element, flame), except kinds whose
* archetype is 'none' (hitCap: a leader hit cancelled by 限伤 draws nothing); unknown kinds get a generic sparkle. `extra` keys used: id (anchor unit — or the shooter of a `pt` kind), r | radius, dur | duration,
* t (shell flight, game s), src / from / to / target / targets (unit ids), fx, fy / fromX, fromY / tx, ty (positions),
* element, n, scale, kind, tiles.
* element, n, scale, kind, tiles, hold ('lock': the reticle waits while the shooter's skill runs).
*/
simFx(kind, x, y, extra) {
const ex = extra && typeof extra === 'object' ? extra : {};
@@ -178,9 +178,10 @@ export class FxSim {
case 'mark': case 'reticle': {
if (kind === 'lock') {
// `id` is always the locked enemy: the reticle sticks to its view even a little off the event's spot
// (`hold`: 蕾缪安 S3 — the reticle waits while her skill runs, however long nothing is in range)
const lv = at.v || this._viewOf(ex.id);
this._touchLocks(ex.src ?? null);
this._lock(lv, ex.src ?? null, lv ? lv.x : at.x, lv ? lv.y : at.y, lv ? bodyZ(cam, lv, SHOT_HEIGHT.aim) : at.z + 0.55);
this._lock(lv, ex.src ?? null, lv ? lv.x : at.x, lv ? lv.y : at.y, lv ? bodyZ(cam, lv, SHOT_HEIGHT.aim) : at.z + 0.55, !!ex.hold);
break;
}
const v = at.v;