feedback3: merge W3D — 折桠's skill idle (community report #23), the ammo bar's real total (#35), unit sounds at the official chance and volume (#30), shots from the hands to the chest (GitHub #61), stuck model loads restarted (GitHub #68), the boss leader shown in prep with its hit tiles (#12)

This commit is contained in:
sganggs committed 2026-10-04 18:10:01 +08:00
commit a57c2a85e2
26 files changed
+1105 -89

No files matched your search

+13 -1
View File
@@ -98,6 +98,7 @@ export class SkillRuntime {
this.active = false;
this.timeLeft = 0;
this.ammoLeft = 0;
this.ammoMax = 0; // ammo kind: the most bullets this activation held (snapshot's draining bar)
this.pending = false; // instant/charges: next attack uses spec.attack
this.activations = 0;
this.lastStart = -Infinity;
@@ -195,6 +196,7 @@ export class SkillRuntime {
this.pending = false;
this.timeLeft = 0;
this.ammoLeft = 0;
this.ammoMax = 0;
this.charges = 0;
this.sp = 0;
this._trigKeys = null;
@@ -429,6 +431,7 @@ export class SkillRuntime {
this.active = true;
this.timeLeft = this.kind === 'duration' ? Math.max(0.01, this.duration) : (this.kind === 'ammo' && this.duration > 0 ? this.duration : Infinity);
this.ammoLeft = this.kind === 'ammo' ? Math.max(1, this.ammo) : 0;
this.ammoMax = this.ammoLeft;
this._applyMods();
} else {
// instant / charges
@@ -441,6 +444,9 @@ export class SkillRuntime {
u.skillAnimUntil = b.time + 0.5;
this._call('onStart', { reason });
if (b._hooks.skillStart) b.emit('skillStart', { unit: u, skill: this, reason });
// bullets added in skillStart (拉特兰's ×(1.05 + 0.015 × layers), 逃犯引渡手续, talents): the bar's full mark
// (community report #35: the extra bullets sat above a full bar until fewer than the base count were left)
if (this.active && this.ammoLeft > this.ammoMax) this.ammoMax = this.ammoLeft;
if (!this.isTimed && !this.pending) this.end('instant');
return true;
}
@@ -487,6 +493,7 @@ export class SkillRuntime {
this.pending = false;
this.timeLeft = 0;
this.ammoLeft = 0;
this.ammoMax = 0;
const n = this.activations;
this._call('onEnd', { reason });
if (!this.active && this.activations === n) this._removeMods();
@@ -509,7 +516,12 @@ export class SkillRuntime {
// ---- helpers for content -------------------------------------------------------------------------------
// (non-finite arguments are ignored: a NaN timer/ammo count would keep the skill active forever)
addAmmo(n) { if (this.active && this.kind === 'ammo' && Number.isFinite(n)) this.ammoLeft += n; }
// (bullets added above the activation's most so far raise the bar's full mark: the bar drains one bullet at a time)
addAmmo(n) {
if (!this.active || this.kind !== 'ammo' || !Number.isFinite(n)) return;
this.ammoLeft += n;
if (this.ammoLeft > this.ammoMax) this.ammoMax = this.ammoLeft;
}
extend(seconds) { if (this.active && Number.isFinite(this.timeLeft) && Number.isFinite(seconds)) this.timeLeft += seconds; }
addCharge(n = 1) { if (!Number.isFinite(n)) return; this.charges = Math.max(0, Math.min(this.maxCharges, this.charges + n)); if (this.charges >= this.maxCharges) this.sp = this.spCost; }
stop() { this.end('stopped'); }