mirror of
https://github.com/Shu-Ying/noname-shuying.git
synced 2026-10-25 01:00:04 +08:00
120 lines
11 KiB
JavaScript
120 lines
11 KiB
JavaScript
import { readCombatStatusSources } from '../../battle/status-sources.js';
|
|
import { slowPercent } from '../../monsters/effigy-slow.js';
|
|
|
|
// The descriptions describe Mengsan's current rules, not an imported Wiki engine.
|
|
const storageStatuses = [
|
|
['vulnerable', '易伤', 'mengsanVulnerable_shuying', '回合', '受到攻击伤害增加;剩余自身回合数,倍率按攻击来源及当前效果结算。', 'mengsan_vulnerable_shuying'],
|
|
['weak', '虚弱', 'mengsanWeak_shuying', '回合', '攻击伤害减少25%;纸鹤对敌人采用40%减伤。自身回合结束减少。', 'mengsan_weak_shuying'],
|
|
['frail', '脆弱', 'mengsanFrail_shuying', '回合', '获得格挡减少25%,向下取整;自身回合结束减少。', 'mengsan_frail_shuying'],
|
|
['artifact', '人工制品', 'mengsanArtifact_shuying', '次', '每次抵消一次符合规则的负面状态施加,不抵消伤害。', 'mengsan_artifact_shuying'],
|
|
['constrict', '紧缠', 'mengsanConstrict_shuying', '伤害', '自身回合结束受到等量非攻击伤害;来源死亡解除。', 'mengsan_constrict_shuying'],
|
|
['tangled', '缠结', 'mengsanTangled_shuying', '回合', '攻击牌费用增加1,持续时间可叠加,加费不叠加。', 'mengsan_tangled_shuying'],
|
|
['shrink', '缩小', 'mengsanShrink_shuying', '', '攻击伤害减少30%,不重复叠加;来源死亡解除。', 'mengsan_shrink_shuying'],
|
|
['plow', '横冲直撞', 'mengsanPlow_shuying', '生命阈值', '受到伤害后生命不高于该阈值时击晕,清零力量并进入第二阶段。', 'mengsan_plow_shuying'],
|
|
['slippery', '滑溜', 'mengsanSlippery_shuying', '次', '下一次实际生命损失限制为1,完全格挡不消耗。', 'mengsan_slippery_shuying'],
|
|
['territorial', '领地意识', 'mengsanTerritorial_shuying', '力量', '自身回合结束获得等量力量。', 'mengsan_territorial_shuying'],
|
|
['infested', '寄生物', 'mengsanInfested_shuying', '召唤数', '死亡后立即召唤扭动虫,必须消灭召唤单位才能获胜。', 'mengsan_infested_shuying'],
|
|
];
|
|
// [display name, icon, value meaning, description]; only actual effect fields are read.
|
|
const effects = {
|
|
turnStrength: ['恶魔形态', 'demon_form', '力量', '自身回合开始获得力量。'],
|
|
turnEnergy: ['每回合费用', 'demesne', '费用', '自身回合开始额外获得费用。'],
|
|
turnBlock: ['绯红披风', 'crimson_mantle', '格挡', '自身回合开始获得格挡;失血部分另列。'],
|
|
turnLoseHp: ['披风失血', 'crimson_mantle', '生命', '自身回合开始失去生命。'],
|
|
infernoLoseHp: ['狱火失血', 'inferno', '生命', '自身回合开始失去生命。'],
|
|
lossDamage: ['狱火', 'inferno', '伤害', '自身回合失去生命时,对所有敌人造成伤害。'],
|
|
lossStrength: ['撕裂', 'rupture', '力量', '自身回合失去生命时获得力量。'],
|
|
vulnerableBonus: ['易伤增幅', 'vicious', '倍率加成', '对易伤敌人的伤害倍率额外加成。'],
|
|
attackBlock: ['狂怒', 'rage', '格挡', '本回合每打出一张攻击牌获得格挡。'],
|
|
retaliation: ['火焰屏障', 'flame_barrier', '伤害', '本回合受到攻击后反击。'],
|
|
colossus: ['巨像', 'colossus', '', '本回合受到易伤敌人的攻击伤害减少50%。'],
|
|
freeAttack: ['免费攻击', 'free_attack', '', '下一张符合规则的攻击牌免费。'],
|
|
noDraw: ['不可抽牌', 'no_draw', '', '本回合不能继续抽牌。'],
|
|
noEnergy: ['无法获得费用', 'no_energy_gain', '', '本回合不能再获得费用。'],
|
|
doubleTap: ['连环拳', 'one_two_punch', '张', '本回合接下来的攻击牌额外打出一次。'],
|
|
plating: ['覆甲', 'plating', '格挡', '回合末获得等量格挡;自身回合开始减少1层。'],
|
|
exhaustBlock: ['无惧疼痛', 'feel_no_pain', '格挡', '卡牌消耗后获得格挡。'],
|
|
exhaustDraw: ['黑暗之拥', 'dark_embrace', '张', '卡牌消耗后抽牌。'],
|
|
vulnerableDraw: ['凶恶', 'vicious', '张', '每次成功施加易伤后抽牌。'],
|
|
juggle: ['杂耍', 'juggling', '', '自身回合第三张攻击牌复制至手牌。'],
|
|
endAttack: ['惊逃', 'stampede', '张', '回合结束随机免费打出攻击手牌。'],
|
|
retrieveAttack: ['好勇斗狠', 'aggression', '张', '自身回合开始从弃牌堆获得攻击牌并强化。'],
|
|
bodyguard: ['肉盾', 'tank', '', '自身承受敌人双倍伤害,其他友方受到敌人的伤害减半。'],
|
|
autoStrike: ['地狱狂徒', 'hellraiser', '', '抽到杀或名称含打击的攻击牌时自动打出。'],
|
|
firstBlock: ['不动', 'unmovable', '张', '每个自身回合首批获得格挡的卡牌,格挡翻倍。'],
|
|
blockDamage: ['势不可当', 'juggernaut', '伤害', '获得格挡时对随机敌人造成伤害。'],
|
|
barricade: ['壁垒', 'barricade', '', '自身回合开始保留格挡。'],
|
|
corruption: ['腐化', 'corruption', '', '技能牌费用变为0,打出后消耗。'],
|
|
dexterity: ['敏捷', 'dexterity', '格挡', '影响从卡牌中获得的格挡。'],
|
|
noCardBlock: ['不可格挡', 'no_block', '回合', '无法从卡牌中获得格挡。'],
|
|
intangible: ['无实体', 'intangible', '回合', '按当前规则限制伤害和生命损失。'],
|
|
gambit: ['孤注一掷', 'the_gambit', '', '受到未被格挡的攻击伤害时死亡。'],
|
|
retain: ['保留手牌', 'retain_hand', '', '本回合保留手牌。'],
|
|
panache: ['神气制胜', 'panache', '伤害', '自身回合每打出5张牌,对所有敌人造成伤害。'],
|
|
defendBonus: ['勒紧', 'fasten', '格挡', '防御牌额外获得格挡。'],
|
|
turnVigor: ['准备时间', 'prep_time', '活力', '自身回合开始获得活力。'],
|
|
automation: ['自动化', 'automation', '费用', '抽牌达到计数要求后获得费用。'],
|
|
powerDiscount: ['好奇', 'curious', '费用', '能力牌费用降低。'],
|
|
boulder: ['滚石', 'rolling_boulder', '伤害', '回合开始对所有敌人造成伤害,随后伤害增加5。'],
|
|
nostalgia: ['怀旧', 'nostalgia', '', '每回合首张攻击或技能牌放回抽牌堆顶。'],
|
|
entropy: ['熵', 'entropy', '', '自身回合开始变化手牌。'],
|
|
beacon_of_hope: ['希望灯塔', 'beacon_of_hope', '', '获得格挡时向其他友方提供格挡。'],
|
|
mayhem: ['乱战', 'mayhem', '', '自身回合开始自动打出抽牌堆顶的牌。'],
|
|
calamity: ['劫难', 'calamity', '', '打出攻击牌时生成随机攻击牌。'],
|
|
};
|
|
const activeValue = value => value === true || typeof value === 'number' && Number.isFinite(value) && value !== 0;
|
|
const number = value => typeof value === 'number' && Number.isFinite(value) ? value : 0;
|
|
const make = (id, name, icon, value, unit, detail, markSkills = []) => ({ id, name,
|
|
icon: icon ? `${icon}_power.png` : null, value: value === true ? null : value, unit, detail, markSkills });
|
|
|
|
export const statusIconNames = [...new Set(['strength', 'ringing', 'slow', 'the_bomb', 'vigor', 'draw_cards_next_turn', 'energy_next_turn', 'block_next_turn',
|
|
...storageStatuses.map(row => row[0]), ...Object.values(effects).map(row => row[1])])].map(id => `${id}_power.png`);
|
|
|
|
export function collectCombatStatuses(player, battle) {
|
|
if (!battle?.session?.active) return [];
|
|
const storage = player.storage || {}, result = [], sources = readCombatStatusSources(player, battle.session);
|
|
const penalty = sources.reduce((n, entry) => n + number(entry.state.negativeStrength), 0);
|
|
const permanent = number(storage.mengsanStrength_shuying), temporary = number(storage.mengsanSetupStrength_shuying);
|
|
if (permanent || temporary || penalty) result.push(make('strength', '力量', 'strength', permanent + temporary - penalty, '伤害',
|
|
`常驻力量 ${permanent};临时力量 ${temporary};本回合减益 ${penalty}。不同临时来源按各自原规则到期。`,
|
|
['mengsan_raider_strength_shuying', 'mengsan_setup_strength_shuying']));
|
|
for (const [id, name, key, unit, detail, skill] of storageStatuses) {
|
|
if (activeValue(storage[key])) result.push(make(id, name, id, storage[key], unit, detail, [skill]));
|
|
}
|
|
if (storage.mengsanRinging_shuying || player.hasSkill?.('mengsan_ringing_shuying')) result.push(make('ringing', '昏眩', 'ringing',
|
|
`${Math.min(1, number(storage.mengsanRingingUsed_shuying))}/1`, '主动出牌', '本次自身回合至多主动使用1张牌,不限制响应;回合结束解除。', ['mengsan_ringing_shuying']));
|
|
if (player.hasSkill?.('mengsan_slow_shuying')) result.push(make('slow', '缓慢', 'slow', slowPercent(player), '%',
|
|
`缓慢 ${number(storage.mengsanSlow_shuying)} 层;友方回合每打出一张牌,受到的攻击牌伤害增加层数×10%;换回合计数重置。`, ['mengsan_slow_shuying']));
|
|
for (const { id, state } of sources) {
|
|
for (const zone of ['powers', 'turn', 'defense']) {
|
|
for (const [key, value] of Object.entries(state[zone] || {})) {
|
|
const definition = effects[key];
|
|
if (!definition || !activeValue(value)) continue;
|
|
const [name, icon, unit, detail] = definition;
|
|
result.push(make(`${id}:${zone}:${key}`, name, icon, key === 'vulnerableBonus' ? `${Math.round(value * 100)}%` : value, unit, detail,
|
|
id === 'ironclad' ? ['mengsan_ic_powers_shuying'] : []));
|
|
}
|
|
}
|
|
if (activeValue(state.vigor)) result.push(make(`${id}:vigor`, '活力', 'vigor', state.vigor, '伤害', '下一张攻击牌获得额外伤害。'));
|
|
(state.bombs || []).forEach((bomb, index) => result.push(make(`${id}:bomb:${index}`, '炸弹', 'the_bomb', bomb.turns, '回合',
|
|
`此实例倒计时结束后对所有敌人造成${bomb.damage}点伤害;各炸弹独立结算。`)));
|
|
(state.nextTurn || []).forEach((next, index) => {
|
|
for (const [key, name, icon, unit] of [['draw', '下回合抽牌', 'draw_cards_next_turn', '张'], ['energy', '下回合费用', 'energy_next_turn', '费用'], ['block', '下回合格挡', 'block_next_turn', '格挡']]) {
|
|
if (activeValue(next[key])) result.push(make(`${id}:next:${index}:${key}`, name, icon, next[key], unit,
|
|
`自身回合开始获得;${next.remaining ? `剩余${next.remaining}次。` : '此实例结算一次。'}`));
|
|
}
|
|
});
|
|
}
|
|
if (battle.relics?.displayState && battle.owner === player) {
|
|
const relic = battle.relics.displayState();
|
|
for (const [key, name, icon, unit, detail] of [
|
|
['dexterity', '遗物敏捷', 'dexterity', '格挡', '遗物提供的卡牌格挡修正。'],
|
|
['plating', '遗物覆甲', 'plating', '格挡', '遗物提供的回合末格挡。'],
|
|
['nextEnergy', '下回合费用', 'energy_next_turn', '费用', '遗物将在下个自身回合提供费用。'],
|
|
['nextBlock', '下回合格挡', 'block_next_turn', '格挡', '遗物将在下个自身回合提供格挡。']]) {
|
|
if (activeValue(relic[key])) result.push(make(`relic:${key}`, name, icon, relic[key], unit, detail));
|
|
}
|
|
}
|
|
return result;
|
|
}
|