mirror of
https://github.com/Shu-Ying/noname-shuying.git
synced 2026-10-20 22:29:59 +08:00
fixed # 修复部分天书乱斗的问题
This commit is contained in:
+9
-19
@@ -1,4 +1,6 @@
|
||||
// 天书羁绊只通过技能表达具体效果;羁绊管理器负责决定当前应持有哪一级技能。
|
||||
import { lib, game, ui, get, ai, _status } from "../../../noname.js";
|
||||
|
||||
const skill = {
|
||||
shuYing_Tianshu_BondSha1: {
|
||||
charlotte: true,
|
||||
@@ -109,8 +111,8 @@ const skill = {
|
||||
locked: true,
|
||||
popup: false,
|
||||
group: [
|
||||
"shuYing_Tianshu_Skill_02_Count2_draw",
|
||||
"shuYing_Tianshu_Skill_02_Count2_discard",
|
||||
"shuYing_Tianshu_Skill_02_Skill2_draw",
|
||||
"shuYing_Tianshu_Skill_02_Skill2_discard",
|
||||
],
|
||||
subSkill: {
|
||||
draw: {
|
||||
@@ -181,9 +183,9 @@ const skill = {
|
||||
locked: true,
|
||||
popup: false,
|
||||
group: [
|
||||
"shuYing_Tianshu_Skill_02_Count3_draw",
|
||||
"shuYing_Tianshu_Skill_02_Count3_discard",
|
||||
"shuYing_Tianshu_Skill_02_Count3_gain",
|
||||
"shuYing_Tianshu_Skill_02_Skill3_draw",
|
||||
"shuYing_Tianshu_Skill_02_Skill3_discard",
|
||||
"shuYing_Tianshu_Skill_02_Skill3_gain",
|
||||
],
|
||||
subSkill: {
|
||||
draw: {
|
||||
@@ -334,13 +336,7 @@ const skill = {
|
||||
async content(event, trigger, player) {
|
||||
const target = trigger.target;
|
||||
const cards = target
|
||||
.getCards("he", card => {
|
||||
return lib.filter.cardDiscardable(
|
||||
card,
|
||||
target,
|
||||
event.name
|
||||
);
|
||||
})
|
||||
.getDiscardableCards(player, "he")
|
||||
.randomGets(1);
|
||||
|
||||
if (!cards.length) return;
|
||||
@@ -389,13 +385,7 @@ const skill = {
|
||||
}
|
||||
|
||||
const cards = target
|
||||
.getCards("he", card => {
|
||||
return lib.filter.cardDiscardable(
|
||||
card,
|
||||
target,
|
||||
event.name
|
||||
);
|
||||
})
|
||||
.getDiscardableCards(player, "he")
|
||||
.randomGets(2);
|
||||
|
||||
if (!cards.length) return;
|
||||
|
||||
+59
-1
@@ -118,7 +118,11 @@ const bossDifficulty = {
|
||||
lvbu_boss_shuying: createBossConfig(bossDifficultyTemplates.qingqingzijin, addSkillFromHard("zhanjia_shuying")),
|
||||
dongzhuo_boss_shuying: createBossConfig(bossDifficultyTemplates.qingqingzijin, addSkillFromHard("qubu_shuying")),
|
||||
yuanshu_boss_shuying: createBossConfig(bossDifficultyTemplates.qingqingzijin, addSkillFromHard("duoxi_shuying")),
|
||||
zhangjiao_boss_shuying: createBossConfig(bossDifficultyTemplates.qingqingzijin, addSkillFromHard("yinlei_shuying")),
|
||||
zhangjiao_boss_shuying: createBossConfig({
|
||||
normal: createDifficultyConfig(6, 4),
|
||||
hard: createDifficultyConfig(8, 12),
|
||||
nightmare: createDifficultyConfig(10, 20),
|
||||
}, addSkillFromHard("yinlei_shuying")),
|
||||
|
||||
...createBossGroup(["shaohao_boss_shuying", "xuannv_boss_shuying", "hanba_boss_shuying"], bossDifficultyTemplates.tianshuluandou),
|
||||
shuishengonggong_boss_shuying: createBossConfig(bossDifficultyTemplates.tianshuluandou, {
|
||||
@@ -210,6 +214,60 @@ const tianshuConfig = {
|
||||
banned: ["huoxin", "jueqing", "qinqing", "beige", "huashen", "drlt_zhiti", "olzhiti", "xinfu_pdgyingshi", "rebeige"],
|
||||
},
|
||||
bonds: [
|
||||
{
|
||||
id: "taoyuan",
|
||||
name: "桃园",
|
||||
condition: { type: "skillRecover" },
|
||||
levels: [
|
||||
{
|
||||
level: 1,
|
||||
count: 1,
|
||||
skills: ["shuYing_Tianshu_BondTaoyuan1"],
|
||||
text: "你通过技能回复体力时,回复值+1",
|
||||
},
|
||||
{
|
||||
level: 2,
|
||||
count: 2,
|
||||
skills: ["shuYing_Tianshu_BondTaoyuan2"],
|
||||
text: "你通过技能回复体力时,回复值+1,"
|
||||
+ "并可以令一名其他角色回复或失去1点体力",
|
||||
},
|
||||
{
|
||||
level: 3,
|
||||
count: 3,
|
||||
skills: ["shuYing_Tianshu_BondTaoyuan3"],
|
||||
text: "你通过技能回复体力时,回复值+1,"
|
||||
+ "并可以令一名其他角色回复或失去1点体力;"
|
||||
+ "按原体力上限结算回复后,将溢出回复转为受回复角色的体力上限",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "directDamage",
|
||||
name: "直伤",
|
||||
condition: { type: "directDamage" },
|
||||
levels: [
|
||||
{
|
||||
level: 1,
|
||||
count: 1,
|
||||
skills: ["shuYing_Tianshu_BondDirectDamage1"],
|
||||
text: "你通过技能直接造成的伤害+1",
|
||||
},
|
||||
{
|
||||
level: 2,
|
||||
count: 2,
|
||||
skills: ["shuYing_Tianshu_BondDirectDamage2"],
|
||||
text: "你通过技能直接造成的伤害+1,并摸等同于最终伤害值的牌",
|
||||
},
|
||||
{
|
||||
level: 3,
|
||||
count: 3,
|
||||
skills: ["shuYing_Tianshu_BondDirectDamage3"],
|
||||
text: "你通过技能直接造成的伤害+1,并摸等同于最终伤害值的牌;"
|
||||
+ "你可以令此次伤害改为无来源,仍结算增伤和摸牌",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "shafa",
|
||||
name: "杀伐",
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
export const directDamageStorage = "shuYing_tianshu_directDamageSkills";
|
||||
|
||||
export function getDirectDamageOrigin(event, lib, get) {
|
||||
if (!event || event.num <= 0 || event.unreal) return null;
|
||||
if (typeof event.notLink == "function" && !event.notLink()) return null;
|
||||
let current = event.getParent?.(1, true);
|
||||
const visited = new Set();
|
||||
while (current && !visited.has(current)) {
|
||||
visited.add(current);
|
||||
if (["useCard", "respond", "damage", "_lianhuan", "_lianhuan2"]
|
||||
.includes(current.name) || current.name?.endsWith("_cost")) {
|
||||
return null;
|
||||
}
|
||||
const skill = lib.skill[current.name] ? current.name : current.skill;
|
||||
if (skill && lib.skill[skill]) {
|
||||
return { skill: get.sourceSkillFor(skill), player: current.player };
|
||||
}
|
||||
current = current.getParent?.(1, true);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getDirectDamageSkillCount(player, skills, lib) {
|
||||
const recorded = player?.storage?.[directDamageStorage];
|
||||
if (!Array.isArray(recorded)) return 0;
|
||||
return new Set(skills.filter(skill => recorded.includes(skill))
|
||||
.map(skill => lib.translate[skill] || skill)).size;
|
||||
}
|
||||
+235
-5
@@ -1,5 +1,9 @@
|
||||
import tianshuConfig from "./config.js";
|
||||
import bondSkillPack from "./bondSkills.js";
|
||||
import { directDamageStorage, getDirectDamageOrigin,
|
||||
getDirectDamageSkillCount } from "./directDamage.js";
|
||||
import { skillRecoverStorage, getSkillRecoverOrigin, getSkillRecoverCount,
|
||||
wrapSkillRecoverEvent } from "./skillRecover.js";
|
||||
import { lib, game, ui, get, ai, _status } from "../../../noname.js";
|
||||
|
||||
export default function initTianshu(lib, game, ui, get, ai, _status, shuYing) {
|
||||
@@ -22,6 +26,7 @@ export default function initTianshu(lib, game, ui, get, ai, _status, shuYing) {
|
||||
originalGameCheck: null,
|
||||
checkHookInstalled: false,
|
||||
bondHooksInstalled: false,
|
||||
recoverHookInstalled: false,
|
||||
corpseChooseCleanup: null,
|
||||
corpseChooseEvent: null,
|
||||
initialBoss: null,
|
||||
@@ -274,10 +279,15 @@ export default function initTianshu(lib, game, ui, get, ai, _status, shuYing) {
|
||||
}
|
||||
};
|
||||
// 新 Boss 入场并重排座位后,若当前行动者属于玩家方(含虚拟偶像)且实际下家为 Boss 或虚拟偶像,则启用旧轮次。
|
||||
const shouldUseLegacyBossTurn = current => {
|
||||
const shouldUseLegacyBossTurn = (current, stageDeadPlayers) => {
|
||||
if (!lib.config[tianshuConfig.settings.legacyRoundConfigKey]) return false;
|
||||
if (!current || !current.isIn?.() || !isCapturedPlayerSide(current)) return false;
|
||||
const next = current.next || current.getNext?.();
|
||||
let next = current.next || current.getNext?.();
|
||||
const visited = new Set([current]);
|
||||
while (next && stageDeadPlayers?.has(next) && !visited.has(next)) {
|
||||
visited.add(next);
|
||||
next = next.next || next.getNext?.();
|
||||
}
|
||||
return Boolean(next && (isCurrentStageBoss(next) || isVirtualIdol(next)));
|
||||
};
|
||||
// 从玩家方1号位沿上家方向查找当前关 Boss,作为旧轮次的行动者。
|
||||
@@ -293,9 +303,9 @@ export default function initTianshu(lib, game, ui, get, ai, _status, shuYing) {
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const getNextStageTurnPlayer = current => {
|
||||
const getNextStageTurnPlayer = (current, stageDeadPlayers) => {
|
||||
const next = current?.next || null;
|
||||
if (!shouldUseLegacyBossTurn(current)) return next;
|
||||
if (!shouldUseLegacyBossTurn(current, stageDeadPlayers)) return next;
|
||||
return getLegacyBossTurnPlayer() || next;
|
||||
};
|
||||
// 开局捕获玩家方成员,避免后续 game.boss 变化导致阵营误判。
|
||||
@@ -738,6 +748,14 @@ export default function initTianshu(lib, game, ui, get, ai, _status, shuYing) {
|
||||
if (!condition.type && condition.not) return !matchesBondCondition(player, condition.not);
|
||||
|
||||
const owned = getBondConditionSkills(player);
|
||||
if (condition.type == "directDamage") {
|
||||
return getDirectDamageSkillCount(player, owned, lib)
|
||||
>= Math.max(1, Number(condition.count) || 1);
|
||||
}
|
||||
if (condition.type == "skillRecover") {
|
||||
return getSkillRecoverCount(player, owned, lib)
|
||||
>= Math.max(1, Number(condition.count) || 1);
|
||||
}
|
||||
if (condition.type == "keyword") {
|
||||
if (!condition.keyword) return false;
|
||||
const marker = `【${condition.keyword}】`;
|
||||
@@ -812,6 +830,12 @@ export default function initTianshu(lib, game, ui, get, ai, _status, shuYing) {
|
||||
if (!condition.type && condition.not) return false;
|
||||
|
||||
const skillName = lib.translate[skill] || "";
|
||||
if (condition.type == "directDamage") {
|
||||
return getDirectDamageSkillCount(player, [skill], lib) > 0;
|
||||
}
|
||||
if (condition.type == "skillRecover") {
|
||||
return getSkillRecoverCount(player, [skill], lib) > 0;
|
||||
}
|
||||
if (condition.type == "keyword") {
|
||||
if (!condition.keyword) return false;
|
||||
const info = typeof get.skillInfoTranslation == "function" ? get.skillInfoTranslation(skill, player) : lib.translate[`${skill}_info`];
|
||||
@@ -1088,6 +1112,9 @@ export default function initTianshu(lib, game, ui, get, ai, _status, shuYing) {
|
||||
game.over(!state.defending);
|
||||
return;
|
||||
}
|
||||
const stageDeadPlayers = new Set(getPlayerSidePlayers({
|
||||
aliveOnly: false, includeVirtual: true,
|
||||
}).filter(player => player.isDead()));
|
||||
await reviveVirtualIdolIfNeeded();
|
||||
if (lib.config[tianshuConfig.settings.revivePlayersConfigKey]) {
|
||||
const deadPlayers = getPlayerSidePlayers({ aliveOnly: false, includeVirtual: false }).filter(player => player.isDead());
|
||||
@@ -1116,7 +1143,8 @@ export default function initTianshu(lib, game, ui, get, ai, _status, shuYing) {
|
||||
state.stageIndex++;
|
||||
await spawnStage(state.stageIndex);
|
||||
// 必须在新 Boss 召唤并完成座位重排后,再按新座位链决定控制权归属。
|
||||
const nextTurnPlayer = getNextStageTurnPlayer(currentTurnPlayer);
|
||||
const nextTurnPlayer = getNextStageTurnPlayer(
|
||||
currentTurnPlayer, stageDeadPlayers);
|
||||
if (nextTurnPlayer) finishCurrentPhaseTo(nextTurnPlayer);
|
||||
};
|
||||
// 处理 Boss 死亡事件:击杀奖励、隐藏尸体、判断是否清关。
|
||||
@@ -1135,6 +1163,79 @@ export default function initTianshu(lib, game, ui, get, ai, _status, shuYing) {
|
||||
if (!stageCleared) return;
|
||||
await clearStage();
|
||||
};
|
||||
const settleSkillRecover = async (event, record, overflow) => {
|
||||
const { player, skill, level } = record;
|
||||
const rewardSkill = getTianshuRewardSkills(player)
|
||||
.find(current => get.sourceSkillFor(current) == skill);
|
||||
if (rewardSkill) {
|
||||
const recorded = player.storage[skillRecoverStorage] || [];
|
||||
if (!recorded.includes(rewardSkill)) {
|
||||
recorded.push(rewardSkill);
|
||||
player.storage[skillRecoverStorage] = recorded;
|
||||
game.broadcast((current, key, value) => {
|
||||
current.storage[key] = value;
|
||||
}, player, skillRecoverStorage, recorded);
|
||||
player.syncStorage?.(skillRecoverStorage);
|
||||
refreshTianshuBonds(player);
|
||||
game.log(player, "登记桃园技能",
|
||||
`【${get.translation(rewardSkill)}】`);
|
||||
}
|
||||
}
|
||||
if (overflow > 0) game.log(player, "将", overflow,
|
||||
"点溢出回复转为", event.player, "的体力上限");
|
||||
if (level < 2 || !player.isIn()) return;
|
||||
const result = await player.chooseTarget(
|
||||
"桃园:可以令一名其他角色回复或失去1点体力",
|
||||
(card, current, target) => target != current && target.isIn())
|
||||
.set("ai", target => Math.abs(get.attitude(player, target)))
|
||||
.forResult();
|
||||
if (!result.bool || !result.targets?.[0]?.isIn()) return;
|
||||
const target = result.targets[0];
|
||||
const choice = await player.chooseControl("回复体力", "失去体力")
|
||||
.set("prompt", `桃园:令${get.translation(target)}执行哪项?`)
|
||||
.set("ai", () => get.attitude(player, target) > 0 ? 0 : 1)
|
||||
.forResult();
|
||||
if (!target.isIn()) return;
|
||||
player.line(target);
|
||||
if (choice.control == "回复体力") {
|
||||
const next = target.recover(1, player);
|
||||
next.shuYing_tianshu_taoyuanSecondary = true;
|
||||
await next;
|
||||
} else if (choice.control == "失去体力") {
|
||||
await target.loseHp(1);
|
||||
}
|
||||
};
|
||||
const installSkillRecoverHook = () => {
|
||||
if (state.recoverHookInstalled) return;
|
||||
const prototype = lib.element.Player?.prototype || lib.element.player;
|
||||
const original = prototype.recover.shuYing_taoyuanBase
|
||||
|| prototype.recover;
|
||||
const recover = function () {
|
||||
const next = original.apply(this, arguments);
|
||||
if (!state.running || _status.over || !this.isIn()) return next;
|
||||
const origin = getSkillRecoverOrigin(next, lib, get);
|
||||
const player = origin?.player;
|
||||
if (!player?.isIn() || player != next.source
|
||||
|| !isCapturedPlayerSide(player)
|
||||
|| (isVirtualIdol(player)
|
||||
&& !canVirtualIdolReceiveRewards())) return next;
|
||||
const level = player.storage.shuYing_tianshu_bondLevels
|
||||
?.taoyuan || 0;
|
||||
const originalContent = next.content.original;
|
||||
const nativeContent = typeof originalContent == "string"
|
||||
? lib.element.content[originalContent]
|
||||
|| lib.element.contents?.[originalContent]
|
||||
: originalContent || next.content;
|
||||
wrapSkillRecoverEvent(next, {
|
||||
player, skill: origin.skill, level,
|
||||
}, settleSkillRecover, nativeContent,
|
||||
() => player.storage.shuYing_tianshu_bondLevels?.taoyuan || 0);
|
||||
return next;
|
||||
};
|
||||
recover.shuYing_taoyuanBase = original;
|
||||
prototype.recover = recover;
|
||||
state.recoverHookInstalled = true;
|
||||
};
|
||||
// gameStart 时启动天书乱斗流程,完成难度选择并等待 gameDrawAfter 召唤第一关。
|
||||
const startRun = async (player = game.me) => {
|
||||
if (state.running) return;
|
||||
@@ -1159,6 +1260,7 @@ export default function initTianshu(lib, game, ui, get, ai, _status, shuYing) {
|
||||
installHiddenBossCorpseCheckHook();
|
||||
spawnVirtualIdol();
|
||||
capturePlayerSide();
|
||||
installSkillRecoverHook();
|
||||
installTianshuBondHooks();
|
||||
installBondOverviewButton();
|
||||
state.pendingSpawn = true;
|
||||
@@ -1259,6 +1361,9 @@ export default function initTianshu(lib, game, ui, get, ai, _status, shuYing) {
|
||||
game.addGlobalSkill("shuYing_Tianshu_DefendingControl");
|
||||
game.addGlobalSkill("shuYing_Tianshu_StageRoundHistory");
|
||||
game.addGlobalSkill("shuYing_Tianshu_BondManager");
|
||||
game.addGlobalSkill("shuYing_Tianshu_DirectDamageCapture");
|
||||
game.addGlobalSkill("shuYing_Tianshu_DirectDamageSettle");
|
||||
game.addGlobalSkill("shuYing_Tianshu_SkillRecoverCapture");
|
||||
},
|
||||
},
|
||||
shuYing_Tianshu_DefendingControl: {
|
||||
@@ -1297,6 +1402,113 @@ export default function initTianshu(lib, game, ui, get, ai, _status, shuYing) {
|
||||
game.getGlobalHistory().isRound = true;
|
||||
},
|
||||
},
|
||||
shuYing_Tianshu_BondDirectDamage1: { charlotte: true, popup: false },
|
||||
shuYing_Tianshu_BondDirectDamage2: { charlotte: true, popup: false },
|
||||
shuYing_Tianshu_BondDirectDamage3: { charlotte: true, popup: false },
|
||||
shuYing_Tianshu_DirectDamageCapture: {
|
||||
mode: ["boss"],
|
||||
trigger: { global: "damageBegin1" },
|
||||
forced: true,
|
||||
silent: true,
|
||||
charlotte: true,
|
||||
firstDo: true,
|
||||
priority: 1000,
|
||||
filter(event) {
|
||||
const player = event.source;
|
||||
if (!state.running || event.shuYing_tianshu_directDamage
|
||||
|| !player?.isIn()
|
||||
|| !isCapturedPlayerSide(player)
|
||||
|| (isVirtualIdol(player)
|
||||
&& !canVirtualIdolReceiveRewards())) return false;
|
||||
const origin = getDirectDamageOrigin(event, lib, get);
|
||||
return Boolean(origin && origin.player == player);
|
||||
},
|
||||
async content(event, trigger) {
|
||||
if (trigger.shuYing_tianshu_directDamage) return;
|
||||
const origin = getDirectDamageOrigin(trigger, lib, get);
|
||||
if (!origin) return;
|
||||
const player = trigger.source;
|
||||
const level = player.storage.shuYing_tianshu_bondLevels
|
||||
?.directDamage || 0;
|
||||
trigger.shuYing_tianshu_directDamage = {
|
||||
player, skill: origin.skill, level,
|
||||
};
|
||||
if (!level) return;
|
||||
trigger.num++;
|
||||
if (level < 3) return;
|
||||
const result = await player.chooseBool(
|
||||
"直伤:是否令此次伤害改为无来源?",
|
||||
"仍会增加1点伤害,并按最终伤害值摸牌。")
|
||||
.set("ai", () => false).forResult();
|
||||
if (result.bool) {
|
||||
delete trigger.source;
|
||||
game.log(player, "令此次技能伤害改为无来源");
|
||||
}
|
||||
},
|
||||
},
|
||||
shuYing_Tianshu_DirectDamageSettle: {
|
||||
mode: ["boss"],
|
||||
trigger: { global: "damage" },
|
||||
forced: true,
|
||||
silent: true,
|
||||
charlotte: true,
|
||||
firstDo: true,
|
||||
priority: 1000,
|
||||
filter(event) {
|
||||
return Boolean(state.running && event.num > 0
|
||||
&& !event.unreal && event.shuYing_tianshu_directDamage
|
||||
&& !event.shuYing_tianshu_directDamage.settled);
|
||||
},
|
||||
async content(event, trigger) {
|
||||
const record = trigger.shuYing_tianshu_directDamage;
|
||||
record.settled = true;
|
||||
const { player, skill, level } = record;
|
||||
const num = trigger.num;
|
||||
const rewardSkill = getTianshuRewardSkills(player)
|
||||
.find(current => get.sourceSkillFor(current) == skill);
|
||||
if (rewardSkill) {
|
||||
const recorded = player.storage[directDamageStorage] || [];
|
||||
if (!recorded.includes(rewardSkill)) {
|
||||
recorded.push(rewardSkill);
|
||||
player.storage[directDamageStorage] = recorded;
|
||||
game.broadcast((current, key, value) => {
|
||||
current.storage[key] = value;
|
||||
}, player, directDamageStorage, recorded);
|
||||
player.syncStorage?.(directDamageStorage);
|
||||
refreshTianshuBonds(player);
|
||||
game.log(player, "登记直伤技能",
|
||||
`【${get.translation(rewardSkill)}】`);
|
||||
}
|
||||
}
|
||||
if (level >= 2 && player.isIn()) await player.draw(num);
|
||||
},
|
||||
},
|
||||
shuYing_Tianshu_BondTaoyuan1: { charlotte: true, popup: false },
|
||||
shuYing_Tianshu_BondTaoyuan2: { charlotte: true, popup: false },
|
||||
shuYing_Tianshu_BondTaoyuan3: { charlotte: true, popup: false },
|
||||
shuYing_Tianshu_SkillRecoverCapture: {
|
||||
mode: ["boss"],
|
||||
trigger: { global: "recoverBegin" },
|
||||
forced: true,
|
||||
silent: true,
|
||||
charlotte: true,
|
||||
firstDo: true,
|
||||
priority: 1000,
|
||||
filter(event) {
|
||||
const record = event.shuYing_tianshu_skillRecover;
|
||||
return Boolean(state.running && event.num > 0 && record
|
||||
&& !record.boosted
|
||||
&& !event.shuYing_tianshu_taoyuanSecondary);
|
||||
},
|
||||
async content(event, trigger) {
|
||||
const record = trigger.shuYing_tianshu_skillRecover;
|
||||
if (record.boosted || trigger.shuYing_tianshu_taoyuanSecondary) {
|
||||
return;
|
||||
}
|
||||
record.boosted = true;
|
||||
if (record.level >= 1) trigger.num++;
|
||||
},
|
||||
},
|
||||
shuYing_Tianshu_BondManager: {
|
||||
mode: ["boss"],
|
||||
trigger: { global: "changeSkillsAfter" },
|
||||
@@ -1397,6 +1609,24 @@ export default function initTianshu(lib, game, ui, get, ai, _status, shuYing) {
|
||||
shuYing_Skill_Tianshu_intro5: { nobracket: true },
|
||||
};
|
||||
tianshu.translate = {
|
||||
shuYing_Tianshu_BondTaoyuan1: "桃园·壹",
|
||||
shuYing_Tianshu_BondTaoyuan1_info: "你通过技能回复体力时,回复值+1。",
|
||||
shuYing_Tianshu_BondTaoyuan2: "桃园·贰",
|
||||
shuYing_Tianshu_BondTaoyuan2_info:
|
||||
"你通过技能回复体力时,回复值+1,并可以令一名其他角色回复或失去1点体力。",
|
||||
shuYing_Tianshu_BondTaoyuan3: "桃园·叁",
|
||||
shuYing_Tianshu_BondTaoyuan3_info:
|
||||
"你通过技能回复体力时,回复值+1,并可以令一名其他角色回复或失去1点体力;"
|
||||
+ "按原体力上限结算回复后,将溢出回复转为受回复角色的体力上限。",
|
||||
shuYing_Tianshu_BondDirectDamage1: "直伤·壹",
|
||||
shuYing_Tianshu_BondDirectDamage1_info: "你通过技能直接造成的伤害+1。",
|
||||
shuYing_Tianshu_BondDirectDamage2: "直伤·贰",
|
||||
shuYing_Tianshu_BondDirectDamage2_info:
|
||||
"你通过技能直接造成的伤害+1,并摸等同于最终伤害值的牌。",
|
||||
shuYing_Tianshu_BondDirectDamage3: "直伤·叁",
|
||||
shuYing_Tianshu_BondDirectDamage3_info:
|
||||
"你通过技能直接造成的伤害+1,并摸等同于最终伤害值的牌;"
|
||||
+ "你可以令此次伤害改为无来源,仍结算增伤和摸牌。",
|
||||
tianshu_boss_shuYing: "天书乱斗",
|
||||
shuYing_Skill_Tianshu_Go: "天书乱斗",
|
||||
shuYing_Skill_Tianshu_intro1: " 第一关",
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
export const skillRecoverStorage = "shuYing_tianshu_skillRecoverSkills";
|
||||
|
||||
export function getSkillRecoverOrigin(event, lib, get) {
|
||||
if (!event || event.num <= 0 || event.shuYing_tianshu_taoyuanSecondary) {
|
||||
return null;
|
||||
}
|
||||
let current = event.getParent?.(1, true);
|
||||
const visited = new Set();
|
||||
while (current && !visited.has(current)) {
|
||||
visited.add(current);
|
||||
if (["useCard", "respond", "recover", "damage"]
|
||||
.includes(current.name) || current.name?.endsWith("_cost")) {
|
||||
return null;
|
||||
}
|
||||
const skill = lib.skill[current.name] ? current.name : current.skill;
|
||||
if (skill && lib.skill[skill]) {
|
||||
return { skill: get.sourceSkillFor(skill), player: current.player };
|
||||
}
|
||||
current = current.getParent?.(1, true);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getSkillRecoverCount(player, skills, lib) {
|
||||
const recorded = player?.storage?.[skillRecoverStorage];
|
||||
if (!Array.isArray(recorded)) return 0;
|
||||
return new Set(skills.filter(skill => recorded.includes(skill))
|
||||
.map(skill => lib.translate[skill] || skill)).size;
|
||||
}
|
||||
|
||||
export function wrapSkillRecoverEvent(event, record, onSettle, nativeContent,
|
||||
getLevel) {
|
||||
const originalFilter = event.filterStop;
|
||||
const originalContent = nativeContent
|
||||
|| (typeof event.content.original == "function"
|
||||
? event.content.original : event.content);
|
||||
event.shuYing_tianshu_skillRecover = record;
|
||||
event.filterStop = function () {
|
||||
if (!record.boosted && getLevel) record.level = getLevel();
|
||||
if (record.level >= 3 && this.num > 0 && this.player.isHealthy()
|
||||
&& !this.shuYing_tianshu_taoyuanSecondary) return false;
|
||||
return originalFilter?.call(this) || false;
|
||||
};
|
||||
event.setContent(async current => {
|
||||
if (record.settled) return;
|
||||
if (current.shuYing_tianshu_taoyuanSecondary) {
|
||||
await originalContent(current, current._trigger, current.player);
|
||||
return;
|
||||
}
|
||||
const missing = Math.max(0, current.player.maxHp - current.player.hp);
|
||||
const overflow = record.level >= 3
|
||||
? Math.max(0, current.num - missing) : 0;
|
||||
if (record.level >= 3) current.num = Math.min(current.num, missing);
|
||||
await originalContent(current, current._trigger, current.player);
|
||||
if (overflow > 0) await current.player.gainMaxHp(overflow);
|
||||
record.settled = true;
|
||||
if (current.num > 0 || overflow > 0) {
|
||||
await onSettle(current, record, overflow);
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user