Files
noname-shuying/mengsan/monsters/inklet-intent.js
T
Diuse 9e1732d2f8 fixed # 补全部分卡牌
fixed # 修复部分已知BUG
2026-10-04 19:32:38 +08:00

54 lines
2.9 KiB
JavaScript

import { isVantom } from "./vantom-intent.js";
// 灰机 Wiki 墨宝:奇数位刺击起手;偶数位旋风起手后刺击;以后随机招与刺击交替。
export const INKLET_CHARACTER = "mengsan_inklet_shuying";
export const INKLET_MOVES = Object.freeze({
jab: Object.freeze({ id: "jab", name: "刺击", damage: 3 }),
whirlwind: Object.freeze({ id: "whirlwind", name: "旋风斩", damage: 2, hits: 3 }),
gaze: Object.freeze({ id: "gaze", name: "锐利凝视", damage: 10 }),
});
const roll = random => {
const value = random();
if (!Number.isFinite(value) || value < 0 || value >= 1) throw new RangeError("墨宝随机数必须在[0,1)内");
return value;
};
const positionOf = state => {
const position = state.position ?? 1;
if (!Number.isInteger(position) || position < 1 || position > 7) throw new RangeError("墨宝站位必须为1~7");
return position;
};
const stageOf = state => {
const stage = state.stage ?? "opening";
if (!["opening", "jab", "random"].includes(stage)) throw new RangeError("墨宝行动节点无效");
return stage;
};
export function selectInkletMove(state = {}, random) {
const position = positionOf(state), stage = stageOf(state);
if (stage === "opening") return position % 2 ? INKLET_MOVES.jab : INKLET_MOVES.whirlwind;
if (stage === "jab") return INKLET_MOVES.jab;
return roll(random) < 0.5 ? INKLET_MOVES.gaze : INKLET_MOVES.whirlwind;
}
export function recordInkletAction(state = {}, advance = true) {
const position = positionOf(state), stage = stageOf(state), turns = state.turnsTaken ?? 0;
if (!Number.isSafeInteger(turns) || turns < 0 || turns === Number.MAX_SAFE_INTEGER || typeof advance !== "boolean") {
throw new RangeError("墨宝行动记录无效");
}
const next = stage === "opening" ? (position % 2 ? "random" : "jab") : stage === "jab" ? "random" : "jab";
return { position, stage: advance ? next : stage, turnsTaken: turns + 1 };
}
export const rollInkletHp = random => 11 + Math.floor(roll(random) * 7);
export const isInklet = player => player?.name === INKLET_CHARACTER &&
player.storage?.mengsanCamp_shuying === "enemy";
// 在梦三的原生changeHp事件创建后限幅;保留护甲消耗量,只将穿透后的生命损失限制为1。
// 层数由实际changeHp通知消耗,完全格挡、零伤害及取消事件不消耗。
export function capInkletHpLoss(player, event) {
if (!(isInklet(player) || isVantom(player)) || !(player.storage.mengsanSlippery_shuying > 0) ||
!Number.isFinite(event.num) || event.num >= 0) return event;
const parent = event.getParent();
if (parent?.unreal) return event;
const armor = parent?.name === "damage" && !parent.nohujia && !player.hasSkillTag("nohujia") ?
Math.max(0, player.hujia || 0) : 0;
if (-event.num > armor) event.num = -Math.min(-event.num, armor + 1);
return event;
}