feedback1 integrate: follow-ups from the workstream notes (official rules)
- an operator's radius area damage skips unblocked 隐匿 and untargetable enemies (Battle.foesInRadius; PRTS 作战机制 AOE伤害判定), the 逐火 embers included - PRTS 溅射半径一览: 投掷手 0.9, 链术师 1.7, 格雷伊 1.0; 迷迭香 S2 radius 1.5 - 阿罗玛's first-attack mark is shared between 阿罗玛 and leaves with its setter (PRTS 备注) - 奥术法阵 on the field: 炎佑's damage silences its target (PRTS 盟约记录 备注) - skills restart from their initial cooldown when a 重生 ends (PRTS 特殊机制) - 高准度伦蒂尼姆城防自行炮: lock in range, 3x3 area, every 0.5 s up to 10 shots, 失衡/控制免疫 meanwhile - 琳琅诗怀雅 S3 coins go to range 2-4 in front and the units she blocks - 阿戈尔 devour is a 物理流失 reduced by the target's DEF
This commit is contained in:
1 parent
4e68100065
commit
75e2f02590
21 files changed
+346
-112
No files matched your search
@@ -43,6 +43,8 @@ const LINE = Object.freeze(Array.from({ length: COLS }, (_, i) => Object.freeze(
|
||||
const BILLRO_S3_RAMP = 20;
|
||||
/** 卡涅利安 S3 charged mark: one buff per enemy, shared by every 卡涅利安 (PRTS 备注), ≤ 5 stacks (skill text). */
|
||||
const BILLRO_MARK = 'billro:mark';
|
||||
/** 阿罗玛's 非首次标记 (talent 起泡性能测试): one per enemy, shared by every 阿罗玛 (PRTS 备注). */
|
||||
const AROMA_MARK = 'aroma:bubbled';
|
||||
const BILLRO_MARK_MAX = 5;
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
@@ -863,14 +865,26 @@ const kits = {
|
||||
}),
|
||||
skill: { kind: 'duration', mods: { atkPct: num(bb.atk) }, onStart({ battle, unit }) { battle.fx('slippery', { x: unit.x, y: unit.y, id: unit.id }); } },
|
||||
talents: [{ install(battle, unit) { // first attack on each enemy: ×1.1 and levitate 2.5 s
|
||||
unit.mem.bubbled = new Set();
|
||||
// PRTS 阿罗玛 备注: "天赋采用施加非首次标记的方式判断是否为'首次进行攻击',自身离场时移除自身已施加的标记,不同阿罗玛之间的
|
||||
// 非首次标记通用" — one mark per enemy (AROMA_MARK, the setter as source) for every 阿罗玛; hers go when she leaves
|
||||
// the field (until 0.1.1 each 阿罗玛 kept her own list, so two of them both triggered on one enemy)
|
||||
unit.mem.bubbled = new Set(); // the enemies she marked
|
||||
battle.on('hit', (c) => {
|
||||
const e = c.target;
|
||||
if (c.source !== unit || !c.dmg.isAttack || e.side !== 'enemy' || unit.mem.bubbled.has(e.id)) return;
|
||||
if (c.source !== unit || !c.dmg.isAttack || e.side !== 'enemy' || e.findBuff(AROMA_MARK)) return;
|
||||
battle.addBuff(e, { key: AROMA_MARK, source: unit });
|
||||
unit.mem.bubbled.add(e.id);
|
||||
c.dmg.mul *= num(t0.damage_scale, 1.1);
|
||||
if (battle.applyStatus(e, 'levitate', { duration: num(t0.levitate_duration, 2.5), source: unit })) battle.fx('levitate', { x: e.x, y: e.y, id: e.id });
|
||||
}, { owner: unit });
|
||||
battle.on('death', (c) => {
|
||||
if (c.unit !== unit) return;
|
||||
for (const id of unit.mem.bubbled) {
|
||||
const e = battle.unitById(id);
|
||||
if (e && e.findBuff(AROMA_MARK)?.source === unit) battle.removeBuff(e, AROMA_MARK);
|
||||
}
|
||||
unit.mem.bubbled.clear();
|
||||
}, { owner: unit });
|
||||
} }],
|
||||
install(battle, unit) {
|
||||
// S2: landing damage for every levitated enemy (any source) that lands inside her range while the skill runs
|
||||
@@ -979,7 +993,7 @@ const kits = {
|
||||
onTick({ battle, unit, dt }) {
|
||||
const T = unit.mem.tornado;
|
||||
if (!T) return;
|
||||
const inside = battle.enemiesInRadius(T.x, T.y, R);
|
||||
const inside = battle.foesInRadius(T.x, T.y, R);
|
||||
for (const e of inside) pulse(battle, e, `glady:slow:${unit.id}`, { moveMul: Math.max(0, 1 + num(bb.move_speed, -0.5)) });
|
||||
T.acc += dt;
|
||||
if (T.acc + 1e-9 < iv) return;
|
||||
@@ -996,7 +1010,7 @@ const kits = {
|
||||
const T = unit.mem.tornado;
|
||||
unit.mem.tornado = null;
|
||||
if (!T || reason === 'death' || !unit.alive) return;
|
||||
for (const e of battle.enemiesInRadius(T.x, T.y, R)) pullSelf(battle, unit, e, force);
|
||||
for (const e of battle.foesInRadius(T.x, T.y, R)) pullSelf(battle, unit, e, force);
|
||||
battle.fx('pull', { x: T.x, y: T.y, id: unit.id });
|
||||
},
|
||||
},
|
||||
@@ -1946,7 +1960,7 @@ const kits = {
|
||||
if (S2 && skillActive(unit)) {
|
||||
// S2: motes orbit wider and hit enemies instead of operators
|
||||
const hitAt = unit.mem.moteHit || (unit.mem.moteHit = new Map());
|
||||
const foes = battle.enemiesInRadius(unit.x, unit.y, num(bb.outside_radius, 2)).filter((e) => canTargetEnemy(unit, e, { canHitFly: true }))
|
||||
const foes = battle.foesInRadius(unit.x, unit.y, num(bb.outside_radius, 2)).filter((e) => canTargetEnemy(unit, e, { canHitFly: true }))
|
||||
.sort((a, b) => a.id - b.id);
|
||||
for (const e of foes) {
|
||||
if ((hitAt.get(e.id) ?? -Infinity) > battle.time + 1e-9) continue;
|
||||
|
||||
Reference in new issue
Block a user