mirror of
https://github.com/Shu-Ying/noname-shuying.git
synced 2026-10-21 14:49:59 +08:00
fixed # 补全部分卡牌
fixed # 修复部分已知BUG
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
// 累积仅属于真实牌对象和当前会话;不写Card.storage或永久牌组。
|
||||
const NAME = "mengsan_baozou";
|
||||
const growth = new WeakMap();
|
||||
const validEntry = (card, entry) => card?.name === NAME && entry?.session.active &&
|
||||
entry.battle.session === entry.session;
|
||||
export function snapshotRampage(card) {
|
||||
const entry = growth.get(card);
|
||||
return validEntry(card, entry) ? {
|
||||
mengsanRampageBonus_shuying: entry.bonus,
|
||||
mengsanRampageSession_shuying: entry.session.id,
|
||||
} : {};
|
||||
}
|
||||
export function copyRampageGrowth(source,target,battle) {
|
||||
if(source?.cards?.length===1)source=source.cards[0];
|
||||
const from=growth.get(source);
|
||||
if(!validEntry(source,from) || from.battle!==battle || target?.name!==NAME)return;
|
||||
const entry={battle,session:battle.session,bonus:from.bonus};
|
||||
growth.set(target,entry);
|
||||
battle.session.ownResource(entry,()=>{if(growth.get(target)===entry)growth.delete(target);});
|
||||
}
|
||||
function nearestUse(event) {
|
||||
const seen = new Set();
|
||||
for (let current = event; current && !seen.has(current); current = current.parent) {
|
||||
seen.add(current);
|
||||
if (current.name === "useCard") return current;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function original(event) {
|
||||
const use = nearestUse(event);
|
||||
if(use?.card?.name===NAME && use.mengsanIcRepeatOriginal_shuying?.name===NAME)return use.mengsanIcRepeatOriginal_shuying;
|
||||
return use?.card?.name === NAME && use.cards?.length === 1 &&
|
||||
use.cards[0]?.name === NAME ? use.cards[0] : null;
|
||||
}
|
||||
function cardOf(card) {
|
||||
return card?.name === NAME && card.cards?.length === 1 && card.cards[0]?.name === NAME
|
||||
? card.cards[0] : card;
|
||||
}
|
||||
function belongsTo(event, root) {
|
||||
const seen = new Set();
|
||||
for (let current = event; current && !seen.has(current); current = current.parent) {
|
||||
if (current === root) return true;
|
||||
seen.add(current);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
export function createRampage(game, getActiveBattle) {
|
||||
const used = new WeakSet();
|
||||
const getPile = (player, battle) => player === game.me
|
||||
? battle.personalPiles : battle.monsterPiles?.get(player);
|
||||
function damage(card) {
|
||||
const node = cardOf(card), battle = getActiveBattle(), entry = growth.get(node);
|
||||
let bonus = validEntry(node, entry) && entry.battle === battle ? entry.bonus : 0;
|
||||
// Only plain, current-session UI snapshots may expose serialized growth.
|
||||
if (!node?.storage && battle?.session.active &&
|
||||
node?.mengsanRampageSession_shuying === battle.session.id &&
|
||||
Number.isSafeInteger(node.mengsanRampageBonus_shuying) && node.mengsanRampageBonus_shuying >= 0)
|
||||
bonus = node.mengsanRampageBonus_shuying;
|
||||
if (bonus > Number.MAX_SAFE_INTEGER - 9) throw new RangeError("暴走伤害越界");
|
||||
return 9 + bonus;
|
||||
}
|
||||
return {
|
||||
card: cardOf, original, damage,
|
||||
async apply(player, event, baseDamage, increase) {
|
||||
if (baseDamage !== 9 || !Number.isSafeInteger(increase) || increase <= 0)
|
||||
throw new RangeError("暴走攻击参数无效");
|
||||
const use = nearestUse(event), card = original(event);
|
||||
const battle = getActiveBattle(), session = battle?.session, root = battle?.root;
|
||||
if (!battle || !session?.active || !root || !card || use.player !== player ||
|
||||
event.card?.name !== NAME || used.has(use) || !belongsTo(use, root)) return;
|
||||
const pile = getPile(player, battle), target = event.target;
|
||||
const valid = () => getActiveBattle() === battle && battle.session === session &&
|
||||
session.active && battle.root === root && battle.players?.has(player) &&
|
||||
player.isAlive() && card.name === NAME && getPile(player, battle) === pile &&
|
||||
typeof pile?.battleCards === "function" && pile.battleCards(use.cards).includes(card);
|
||||
if (!valid() || !battle.players.has(target) || !target?.isAlive?.() ||
|
||||
target === player || !player.isEnemyOf(target)) return;
|
||||
const amount = damage(card), bonus = amount - baseDamage;
|
||||
if (increase > Number.MAX_SAFE_INTEGER - baseDamage - bonus)
|
||||
throw new RangeError("暴走累积伤害越界");
|
||||
used.add(use);
|
||||
player.line(target, "green");
|
||||
const hit = target.damage(amount, player);
|
||||
hit.mengsanAttack_shuying = true;
|
||||
await hit;
|
||||
if (!valid()) return;
|
||||
let entry = growth.get(card);
|
||||
if (!validEntry(card, entry) || entry.battle !== battle) {
|
||||
entry = { battle, session, bonus: 0 };
|
||||
const record = entry;
|
||||
session.ownResource(record, () => {
|
||||
if (growth.get(card) === record) growth.delete(card);
|
||||
});
|
||||
growth.set(card, entry);
|
||||
}
|
||||
// Damage hooks may initiate nested uses; retain their increments without overwrite.
|
||||
if (increase > Number.MAX_SAFE_INTEGER - baseDamage - entry.bonus)
|
||||
throw new RangeError("暴走累积伤害越界");
|
||||
entry.bonus += increase;
|
||||
battle.handUI?.refresh();
|
||||
battle.pilesUI?.refresh();
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user