feedback3 WG: a 隐匿 blocker is hit only by the blocked enemy's attacks, not by its areas, zones or auras (GitHub #97)

This commit is contained in:
sganggs committed 2026-10-04 20:33:35 +08:00
1 parent 95b8a24d28
commit 13e71fccba
6 files changed
+39 -36

No files matched your search

+1 -1
View File
@@ -1668,7 +1668,7 @@ export class Battle {
/**
* Every deployed ally within `r` of (x, y) — no selection rule: an enemy's area effect selects among them with
* targeting.js areaSelectable (content/enemies.js areaAllies: no unblocking 隐匿 ally, DESIGN §22.12).
* targeting.js areaSelectable (content/enemies.js areaAllies: no 隐匿 ally, the blocker included, GitHub #97; DESIGN §22.12).
*/
alliesInRadius(x, y, r, ownerId = null, { includeDevices = false } = {}) {
const out = [];
+2 -2
View File
@@ -59,7 +59,7 @@
// (a direct pick) and the ticks of a debuff already on it (【自然涌动】: a tick selects nobody).
// Every area effect of a leader or part — pulses, strikes around an echo, blasts, charges and tramples, crosses, columns,
// whole-field skills — selects with enemies.js areaAllies / areaAlliesInTiles / fieldAllies (targeting.js
// areaSelectable): no 隐匿 operator that does not block the unit, no untargetable or sleeping one, no 起飞 one for a
// areaSelectable): no 隐匿 operator, the one blocking the unit included (GitHub #97), no untargetable or sleeping one, no 起飞 one for a
// ground unit; 迷彩 is not checked (splash-type, 中点判定 / 格子判定 or "无视迷彩" on PRTS; the rest [ASSUMED], DESIGN
// §22.12). Only 【盲信之誓】 ("无视无法选择、迷彩") takes everyone on its lines.
// LP effects ('lpLoss' hook + result.lpLoss) must be applied by the match (see the report of this module's owner).
@@ -334,7 +334,7 @@ export function fairOrder(b, e, list, P) {
* 斩胄之剑 / 破胄之锤 (PRTS 行动方式 飞行) — and its damage 无来源, so 对地规避 does not stop it: `ignoreSelect` (an airborne
* 起飞 ally in the 3×3 is stunned and hurt like the others, although the credited 胄 walks). It is still that unit's area
* selection (PRTS: "令自身周围8格内的所有我方单位…" / "…无视迷彩,可对空", no 无视无法选择): areaAlliesInTiles of `by` — no
* 隐匿 ally that does not block it (掷剑 / 掷锤's "无视无法选择" is their pick of the operator they fly at, not the blast).
* 隐匿 ally, the one blocking it included (GitHub #97; 掷剑 / 掷锤's "无视无法选择" is their pick of the operator they fly at, not the blast).
*/
function stunBlast(b, src, by, r, c, stun, dot, dur, kind) {
b.fx('explode', { x: c, y: r, r: 1.5, kind, tiles: 'box' });
+10 -10
View File
@@ -36,7 +36,7 @@
// (targeting.js aggroCmp — PRTS 索敌: 特殊优先级 → 仇恨值). Area effects — splash, blasts, area skills and statuses,
// pulses, the zones an enemy leaves, chain / bounce jumps, 周围四格 additions, whole-column / whole-field skills —
// select with areaAllies / areaAlliesInTiles / fieldAllies (targeting.js areaSelectable; PRTS 作战机制 §AOE伤害判定
// "AOE的判定是对攻击范围内的每个可以被选中的敌人进行判定"): no 隐匿 ally that does not block the enemy, no untargetable
// "AOE的判定是对攻击范围内的每个可以被选中的敌人进行判定"): no 隐匿 ally, the one blocking the enemy included (GitHub #97), no untargetable
// or sleeping one, no airborne 起飞 one for a ground enemy; 迷彩 is not checked (splash-type, 中点判定 / 格子判定 and
// aura effects ignore it — ba.camou "无法躲避溅射类攻击", PRTS 异常效果 迷彩; the sites with no such reading are
// [ASSUMED] in DESIGN §22.12). Buff auras select with auraAllies (auraSelectable: 隐匿 kept out, 起飞 not). A locked
@@ -63,7 +63,7 @@
// gauge whose burst is the official one (termDescription ba.dt.erosion: "永久降低100点防御力并受到800点物理伤害").
// DOT — damage zones (污染秽蚀: true damage, one tick per second however many cover a unit, "可对空,无视无法选择"
// — `ignoreSelect`, 起飞 / 隐匿 allies included; 燃烧区域: the enemy's area selection — PRTS 集团军重型火炮
// "碰撞不受迷彩制约,不可对空", no 无视无法选择 —, so no 起飞 or unblocking 隐匿 ally; 假想敌:蚀裂's sourceless
// "碰撞不受迷彩制约,不可对空", no 无视无法选择 —, so no 起飞 or 隐匿 ally; 假想敌:蚀裂's sourceless
// 毒雾 skips a 隐匿 ally, not a 起飞 one), bleeding (removed by healing), pulsing damage around an enemy
// (area selection).
// INVISIBLE — permanent `stealth` flag (engine: untargetable unless blocked or revealed). An operator's radius area
@@ -72,7 +72,7 @@
// still hit it); tile selectors (enemiesInKeys) always skipped it. After a block it hides again only
// STEALTH_RESTORE (3) s later — or after the "(解除阻挡N秒后恢复)" of its PRTS page (STEALTH_RESTORE_BY_KEY,
// 清明's veil 0 s) — Battle._stealthSwitch / targeting.js enemyStealthed (until 0.1.2: at once).
// The mirror rule for an ally's 隐匿 — enemy area effects skip it unless it blocks the enemy — is areaAllies (since 0.1.2, DESIGN §22.12).
// The mirror rule for an ally's 隐匿 — enemy area effects skip it even when it blocks the enemy (0.1.3, GitHub #97) — is areaAllies.
// REFLECTION — 折射 (ba.refraction "生效时,法术抗性+70"): RES +refracting.magic_resistance while NOT silenced
// (the ability line is SILENCE-flagged: silencing turns it off); 镜膜 also gets max HP +100 % while on.
// SPECIAL — mostly stats; prisoners, 穿刺手, 暴虐兵长, 镜卫, 动力装甲 … below.
@@ -471,7 +471,7 @@ export function allTargets(b, e) {
/**
* The allies an AREA effect of enemy `src` selects within `r` of (x, y) — splash, blast, area skill / status, pulse, zone
* tick, chain or bounce jump (targeting.js areaSelectable: no unblocking 隐匿, untargetable or sleeping ally, no 起飞 one
* tick, chain or bounce jump (targeting.js areaSelectable: no 隐匿 ally, the blocker included, no untargetable or sleeping ally, no 起飞 one
* for a ground `src`; 迷彩 is not checked). `src` = the enemy whose effect it is (null: none — 隐匿 still applies). A
* locked target goes first through targetAndArea. Abilities PRTS marks "无视无法选择 / 无视可选性" use b.alliesInRadius with
* `ignoreSelect` instead.
@@ -491,7 +491,7 @@ export function fieldAllies(b, src) {
}
/**
* The allies within `r` of (x, y) a buff aura of enemy `src` takes (targeting.js auraSelectable: no unblocking 隐匿,
* The allies within `r` of (x, y) a buff aura of enemy `src` takes (targeting.js auraSelectable: no 隐匿 ally, the blocker included,
* untargetable or sleeping ally — PRTS "隐匿状态下的单位一般无法被敌方的…Buff选择器选中"; an airborne 起飞 ally is still
* taken [ASSUMED, §21.22]). 寒霜's aura, which PRTS says ignores 隐匿, keeps b.alliesInRadius (allyAura).
*/
@@ -722,8 +722,8 @@ const onHitStatus = (key, dur, value) => ({ dealt(c, b, e) { if (dur > 0) b.appl
* attack starts (`before`): `unblocked` = only an attack begun while not blocked splashes (the others are the plain melee
* hit at `meleeScale`). The main target takes the engine's attack at `scale` × ATK (e.profile.atkScale, a normal attack:
* on-hit effects apply); when it lands (the main hit's 'hit', before its dodge) the others around the target take
* `scale` × ATK as a splash — an area selection (areaAllies / areaAlliesInTiles: no 隐匿 ally that does not block the
* enemy, no airborne 起飞 one for a ground enemy; 迷彩 is not checked — DESIGN §22.12). `tiles` 1 = the target's tile and
* `scale` × ATK as a splash — an area selection (areaAllies / areaAlliesInTiles: no 隐匿 ally, the blocker included
* (GitHub #97), no airborne 起飞 one for a ground enemy; 迷彩 is not checked — DESIGN §22.12). `tiles` 1 = the target's tile and
* its 8 neighbours (格子判定), else `radius` around the target (中点判定). `noAir`: "不可对空" (a flying ally — the 炎佑
* dragon — is skipped; without it "可溅射飞行单位"). `dodge`: the splash hits may be dodged (烹泉 / 沏虹, whose PRTS 天赋 calls
* them 法术普通伤害 — a normal attack's damage); a 溅射伤害 splash cannot. `onEach(b, e, u)` runs on every unit hit (the target
@@ -1651,7 +1651,7 @@ function kitHolyGuard(ab) {
tick(b, e) {
const on = b.enemiesInRadius(e.x, e.y, r).some((o) => /enemy_1175_dushdo/.test(o.defId));
if (!on) return;
// a buff aura (auraAllies): no 隐匿 operator that does not block it (PRTS 作战机制 §隐匿与Buff的关系 — no 无视 note on
// a buff aura (auraAllies): no 隐匿 operator, the blocker included (PRTS 作战机制 §隐匿与Buff的关系 — no 无视 note on
// its page), but an airborne 起飞 one still [ASSUMED, as §21.22's ground-enemy auras]
for (const u of auraAllies(b, e, e.x, e.y, r)) auraBuff(b, u, 'ab:forceField', 0.5, { aspd }, null, true);
},
@@ -2074,7 +2074,7 @@ function kitLeaderMisc(key, ab, e) {
// PRTS 碎骨 天赋: "不会攻击飞行单位"; below half HP ATK +50 %; "未被阻挡时发射榴弹对目标及其周围八格的我方单位造成相当于攻击力
// 26%的物理伤害,并令其在5秒内防御力下降50%" ("榴弹对主目标造成物理普通伤害,对溅射目标造成物理溅射伤害,可溅射飞行单位") — the
// 26 % / 5 s / 3×3 are PRTS's, the −50 % is the blackboard's defdown.def. A blocked attack is its plain melee hit. The
// splash is an area selection: a 隐匿 operator next to the target that does not block it is spared (GitHub issue #32
// splash is an area selection: a 隐匿 operator is spared, the one blocking this enemy included (GitHub #97; #32
// item 6, DESIGN §22.12). Community report #14 (0.1.2): the grenade used to be a full attack + 100 % on 4 neighbours.
const dd = -(T(ab, 'defdown.def') ?? 0);
return [lowHpBuff(T(ab, 'atkup.hp_ratio') ?? 0.5, { atkPct: T(ab, 'atkup.atk') ?? 0 }), noAirTargets(),
@@ -2520,7 +2520,7 @@ function kitWolfLord(ab) {
const P = { form2: false, caught: 0, waitUntil: -Infinity, cast: null };
const caught = (b) => b.allies().some((u) => u.findBuff('ab:fearCage'));
const cure = (b) => { for (const u of b.allies()) { const d = u.findBuff('ab:fearCage'); if (d) b.removeBuff(u, d); } };
// 【远古威慑】 (a buff aura, auraAllies): no 隐匿 operator that does not block it, an airborne 起飞 one still — as 深池伙友卫队's
// 【远古威慑】 (a buff aura, auraAllies): no 隐匿 operator, the blocker included, an airborne 起飞 one still — as 深池伙友卫队's
const awe = (b, e) => { for (const u of auraAllies(b, e, e.x, e.y, WOLF_AWE_RADIUS)) auraBuff(b, u, 'ab:ancientAwe', 0.2, { aspd: WOLF_AWE_ASPD }, null, true); };
return [{
spawn(b, e, a, ab2) {
+10 -9
View File
@@ -11,8 +11,8 @@
// (3) higher enemy taunt, (4) least remaining path distance to the goal, (5) earliest spawned. Air units
// (Unit.isFlying: FLY, 近地悬浮, 浮空) need a profile that can hit them (`canHitFly`, never `groundOnly`). Enemy
// priority: sortAllyTargets. 起飞 (an ally's flag `liftoff`) = 对地规避: no ground enemy selects it (evadesGround).
// An enemy's area effects select allies with areaSelectable, its buff auras with auraSelectable (no unblocking 隐匿
// ally; 迷彩 is not checked — DESIGN §22.12).
// An enemy's area effects select allies with areaSelectable, its buff auras with auraSelectable (no 隐匿 ally, the one
// blocking the source included — GitHub #97; 迷彩 is not checked — DESIGN §22.12).
import { COLS, ROWS } from './constants.js';
import { normDir, rotateOffset } from './dir.js';
@@ -112,9 +112,10 @@ export function canTargetAlly(e, a, ranged) {
* 任何敌方的能力索敌选中"; PRTS 异常效果 §无法选择: with 隐匿, 不可选中, 无敌, 塔不可选中 or 对地规避 "常见的、来自不同阵营的
* “选择”行为将无视这些单位进行(如同范围内不存在这个单位)", and the abilities PRTS marks "无视可选性" are those that skip
* that check. So not:
* - a 隐匿 ally (flag `stealth`: 伪装服, 叙拉古 6, 伊内丝 S2, the 排气格栅 tile) unless it blocks `src` — a blocked enemy
* attacks its blocker whatever its selectability (PRTS 作战机制 "因为“阻挡优先级最高”的效果,敌人会无视一切可选性对该干员
* 进行攻击"; read for its area abilities too [ASSUMED]); a dead `src` (death blasts) blocks nobody;
* - a 隐匿 ally (flag `stealth`: 伪装服, 叙拉古 6, 伊内丝 S2, the 排气格栅 tile), even when it blocks `src`. The blocked
* enemy still attacks that blocker (canTargetAlly; PRTS 作战机制 "因为“阻挡优先级最高”的效果,敌人会无视一切可选性对该干员
* 进行攻击"). Its splash, blast, zone and aura do not (GitHub #97, owner 2026-10-04; the 0.1.2 [ASSUMED] that the
* blocker's area also hit is withdrawn). A dead `src` (death blasts) blocks nobody;
* - an untargetable (不可选中) or sleeping (沉睡 = 无敌 + 无法行动) ally;
* - an airborne 起飞 ally when `src` walks (evadesGround — the same refusal the damage pipeline makes).
* An invulnerable (`invulnerable`, 无敌) ally is still selected, as by canTargetAlly — a known deviation from 无法选择
@@ -134,15 +135,15 @@ export function areaSelectable(src, a) {
* May a BUFF AURA of enemy-side `src` (a 光环 refreshed on whoever stands in it — 深池伙友卫队's force field, 扎罗's
* 远古威慑; content/enemies.js auraAllies) take ally `a`? PRTS 作战机制 §隐匿与Buff的关系 "隐匿状态下的单位一般无法被敌方的
* 索敌机制和Buff选择器选中为目标", "目前明日方舟中使用能选中隐匿状态单位的Buff效果一定是无视隐匿状态起作用的" (its example:
* 寒霜's 攻速下降 Debuff — content/enemies.js allyAura keeps that one on every ally): no 隐匿 ally unless it blocks `src`,
* no untargetable or sleeping one; 迷彩 does not protect ("所有光环类能力…均不受迷彩制约"). Unlike areaSelectable it does not
* 寒霜's 攻速下降 Debuff — content/enemies.js allyAura keeps that one on every ally): no 隐匿 ally, the one blocking `src`
* included (GitHub #97), no untargetable or sleeping one; 迷彩 does not protect ("所有光环类能力…均不受迷彩制约"). Unlike areaSelectable it does not
* apply 对地规避: a ground enemy's aura still reaches an airborne 起飞 ally [ASSUMED, DESIGN §21.20 / §21.22].
*/
export function auraSelectable(src, a) {
if (!a || !a.alive || !a.deployed || a.hidden || a.kind === 'device') return false;
const f = a.s.flags;
if (f.untargetable || f.sleep) return false;
return !(f.stealth && !(src && src.alive && src.blockedBy === a));
if (f.untargetable || f.sleep || f.stealth) return false;
return true;
}
/**