Playtest #6 fixes: summons placed by hand, boss pool stall, bounties, 联防 leak counter, distinct offers, 机变 card text, phone buy tap, skill triggers, blocking, push force, 孤立, enemies, element bar

- #1 #2 skill / device summons (赫默's drone, 巫恋's doll, 凯瑟琳's devices) are hand cards placed by the player;
  placed summons deploy once at battle start, then a skill summon re-appears at its tile on each cast (the user's call)
- #3 叙拉古 隐匿 ends on time (32 + 0.4 × layers s); 忍冬 S3 迷彩 lasts until her next cast (official), kept apart from 隐匿
- #4 multi-round bounty cards last two battles (the user's call; MULTI_ROUND_BOUNTY_BATTLES), blue / red card text
- #5 the shared boss pool's float dust (≈3.6e-12 HP) stalled Final Assault leaders at 0 %; < 1 HP now clears the pool,
  and the team LP reaching 0 first is a defeat (PRTS)
- #6 #10 机变 cards show their official effect text; an invisible 详情 button no longer swallows the confirming tap on phones
- #7 live ×N counter of a leaker's enemies still on the 联防 field (LP loss stays capped at 10)
- #8 #15 #16 skill triggers per 技能策略: skill-range triggers, injured-ally heals (古米, 塞雷娅), tank take-damage
  triggers with a 3 s cooldown; 新约能天使 S2 shields the highest-aggro operator in range
- #9 official per-enemy model scales (威龙)
- #11 element bar under the unit's HP bar (white = 元素值 left, element-coloured refill after a burst), floor rounding
- #12 枯朽战车 kit per PRTS; every ranged enemy reaches its target's 0.25 collider
- #13 恐惧 wander (萨科塔之翼 at half HP, operator fears make enemies flee) with re-planning after pushes
- #14 push / pull distance by 力度 − 重量 (PRTS table); #17 every blocker attacks what it blocks; ASPD floor 20
- #18 炎佑 is 孤立: no heals or ally buffs
- #19 every free pick-one chess offer (promotion reward, 信标, 寻呼模块) shows different operators
- DESIGN §20 and the normative lines, SIM / META / DATA / PLAYING updated; 2747 unit tests and all 27 browser suites
  green; dev recordings regenerated
This commit is contained in:
sganggs committed 2026-10-01 19:08:23 +08:00
1 parent e6628f0cfe
commit 6464e4b46a
138 files changed
+7946 -1379

No files matched your search

+8 -18
View File
@@ -5,7 +5,8 @@
// it (round(y), round(x)) is one of the absolute range tiles — a huge enemy (巨型单位) when any tile its hit rectangle
// occupies is (body.js; user playtest #5 item 10). `rangeExtend` (ability_range_forward_extend) adds N tiles
// past the furthest cell of every row, along +dCol BEFORE rotating (DESIGN §3).
// Operator priority: (1) enemies it blocks (melee units only: meleeUnit), (2) profile priority (fly/lowDef/…),
// Operator priority: (1) enemies it blocks (every blocker, ranged ones on melee tiles included — user playtest #6
// follow-up "阻挡了就一定要能打到"; Battle.blockedTargets), (2) profile priority (fly/lowDef/…),
// (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.
@@ -49,18 +50,6 @@ export function tileKeyOf(u) {
return r * COLS + c;
}
/**
* A melee unit (近战位: data `position` MELEE — melee-tile operators and summons, 重装要塞 / 领主 / 哨戒铁卫 included):
* it may always select, and selects first, the enemies it blocks — PRTS 选择器 "可以选择且优先选择阻挡单位" (the
* BlockedOrAdvancedSelector of units whose range is smaller than their block radius), 索敌的概念 "我方索敌优先级:
* 阻挡(近战限定)". A ranged operator standing on a melee tile (卫戍协议 "所有行动内远程干员可部署在近战位") blocks, but
* targets by its range alone: "远程位干员通常而言不会优先攻击自己阻挡的目标;甚至如果这个目标被阻挡在该干员的身后,该干员
* 可能因为敌人未处于自身攻击范围而无法攻击到这个敌人" (索敌的概念). Used by Battle.blockedTargets and sortEnemyTargets.
*/
export function meleeUnit(u) {
return String(u?.def?.position ?? 'MELEE').toUpperCase() === 'MELEE';
}
/** Can `attacker` (ally) target enemy `e` at all (ignoring range)? */
export function canTargetEnemy(attacker, e, profile) {
if (!e.alive || e.hidden || !e.deployed) return false;
@@ -73,17 +62,19 @@ export function canTargetEnemy(attacker, e, profile) {
}
/**
* Can enemy `e` target ally `a`? `ranged` = the attack is a ranged (non-blocked) one. A stealthed ally (隐匿 / 迷彩, the
* Can enemy `e` target ally `a`? `ranged` = the attack is a ranged (non-blocked) one. A stealthed ally (隐匿, the
* 排气格栅 tile) is a target only for the enemy it blocks — PRTS 作战机制 §隐匿 "我方干员并不会因为阻挡而解除隐匿" and 索敌的
* 概念 "敌人会在自身被干员阻挡情况下强行无视对方可选性发动攻击" (the term text "不阻挡时…" is the short form; 异常效果:
* "隐匿与'阻挡时解除'没有直接关系"). Devices are never targets (阻隔工事: obstacles nobody can select; “双眼皮”: 迷彩 and
* off the enemy paths — PRTS).
* off the enemy paths — PRTS). 迷彩 (flag `camou`, term ba.camou "不阻挡时不成为敌方普通攻击的目标") works the same way:
* PRTS 异常效果 gives both anomalies the note "与'阻挡时解除'没有直接关系" [ASSUMED: enemy skills and splash selectors
* treat 迷彩 like target selection — officially splash and selectors without a projectile ignore it].
*/
export function canTargetAlly(e, a, ranged) {
if (!a.alive || !a.deployed || a.hidden || a.kind === 'device') return false;
const f = a.s.flags;
if (f.untargetable || f.sleep) return false;
if (ranged && f.stealth && e.blockedBy !== a) return false;
if (ranged && (f.stealth || f.camou) && e.blockedBy !== a) return false;
return true;
}
@@ -111,10 +102,9 @@ export function sortEnemyTargets(battle, attacker, cands, priority) {
if (cands.length <= 1) return cands;
const pf = priority ? (PRIORITY_FNS[priority] || (priority === 'nearest' || priority === 'farthest' ? null : null)) : null;
const ax = attacker.x, ay = attacker.y;
const melee = meleeUnit(attacker);
const keyed = cands.map((e) => ({
e,
b: melee && e.blockedBy === attacker ? 0 : 1,
b: e.blockedBy === attacker ? 0 : 1,
p: pf ? pf(e) : priority === 'nearest' ? bodyDist(e, ax, ay) : priority === 'farthest' ? -bodyDist(e, ax, ay) : 0,
t: -(e.s.taunt || 0),
d: battle.remainingDistance(e),