名将吴懿,修改game.parseSkillTextMap的返回值

This commit is contained in:
Spmario233 2024-05-04 12:10:24 +08:00
parent 61689d4be7
commit 1c92bd3b7e
5 changed files with 222 additions and 43 deletions

View File

@ -19,6 +19,7 @@ const characters = {
sp_fuwan: ["male", "qun", 3, ["spfengyin", "spchizhong"]], sp_fuwan: ["male", "qun", 3, ["spfengyin", "spchizhong"]],
old_lingju: ["female", "qun", 3, ["jieyuan", "fenxin_old"]], old_lingju: ["female", "qun", 3, ["jieyuan", "fenxin_old"]],
sp_mushun: ["male", "qun", 4, ["moukui"]], sp_mushun: ["male", "qun", 4, ["moukui"]],
dc_wuyi: ["male", "shu", 4, ["dcbenxi"]],
}; };
export default characters; export default characters;

View File

@ -2,6 +2,90 @@ import { lib, game, ui, get, ai, _status } from "../../noname.js";
/** @type { importCharacterConfig['skill'] } */ /** @type { importCharacterConfig['skill'] } */
const skills = { const skills = {
//名将吴懿
dcbenxi: {
trigger: {
player: ["loseAfter"],
global: ["equipAfter", "addJudgeAfter", "gainAfter", "loseAsyncAfter", "addToExpansionAfter"],
},
forced: true,
zhuanhuanji: true,
filter(event, player) {
const evt = event.getl(player);
return evt && evt.hs && evt.hs.length > 0;
},
async content(event, trigger, player) {
player.changeZhuanhuanji("dcbenxi");
if (player.storage.dcbenxi) {
const map = lib.skill.dcbenxi.getMap(),
list = Object.keys(map);
if (list.length > 0) {
const skill = list.randomGet(),
voiceMap = game.parseSkillTextMap(skill, map[skill]);
console.log(voiceMap);
player.storage.dcbenxi_pending = skill;
findaudio: for (let data of voiceMap) {
if(!data.text) continue;
const pinyins = get.pinyin(data.text, false);
for (let i = 0; i < pinyins.length - 1; i++) {
if (pinyins[i] === "wu" && pinyins[i + 1] === "yi") {
player.chat(data.text);
game.broadcastAll(file => game.playAudio(file), data.file)
break findaudio;
}
}
}
}
} else {
const skill = player.storage.dcbenxi_pending;
if (skill) {
if (player.hasSkill(skill, null, false)){
const targets = game.filterPlayer(current => current != player).sortBySeat();
player.line(targets, 'fire');
for(let target of targets){
if(target.isIn()) await target.damage();
}
}
else{
await player.addTempSkills([skill], {player: 'phaseBegin'});
}
delete player.storage.dcbenxi_pending;
}
}
},
getMap() {
if (!_status.dcbenxi_map) {
_status.dcbenxi_map = {};
let list;
if (_status.connectMode) {
list = get.charactersOL();
} else {
list = get.gainableCharacters();
}
list.forEach(name => {
if (name !== "dc_wuyi") {
const skills = get.character(name).skills;
skills.forEach(skill => {
if (skill in _status.dcbenxi_map) return;
const voices = game.parseSkillText(skill, name);
if (
voices.some(text => {
const pinyins = get.pinyin(text, false);
for (let i = 0; i < pinyins.length - 1; i++) {
if (pinyins[i] === "wu" && pinyins[i + 1] === "yi") return true;
}
return false;
})
) {
_status.dcbenxi_map[skill] = name;
}
});
}
});
}
return _status.dcbenxi_map;
},
},
//新InitFilter测试高达一号 //新InitFilter测试高达一号
//打赢复活赛的牢达[哭] //打赢复活赛的牢达[哭]
dclonghun: { dclonghun: {
@ -355,7 +439,7 @@ const skills = {
player.gain(trigger.cards, "gain2"); player.gain(trigger.cards, "gain2");
} }
player.draw(player.countMark("dcjianxiong") + 1, "nodelay"); player.draw(player.countMark("dcjianxiong") + 1, "nodelay");
"step 1"; ("step 1");
if (player.countMark("dcjianxiong") < 4) player.addMark("dcjianxiong", 1, false); if (player.countMark("dcjianxiong") < 4) player.addMark("dcjianxiong", 1, false);
}, },
marktext: "雄", marktext: "雄",
@ -410,7 +494,7 @@ const skills = {
player.addTempSkill("dcrende_targeted", "phaseUseAfter"); player.addTempSkill("dcrende_targeted", "phaseUseAfter");
player.markAuto("dcrende_targeted", [target]); player.markAuto("dcrende_targeted", [target]);
player.gainPlayerCard(target, "h", true, 2); player.gainPlayerCard(target, "h", true, 2);
"step 1"; ("step 1");
var list = []; var list = [];
for (var name of lib.inpile) { for (var name of lib.inpile) {
if (get.type(name) != "basic") continue; if (get.type(name) != "basic") continue;
@ -469,7 +553,7 @@ const skills = {
} else { } else {
event.finish(); event.finish();
} }
"step 2"; ("step 2");
if (result && result.bool && result.links[0]) { if (result && result.bool && result.links[0]) {
var card = { var card = {
name: result.links[0][2], name: result.links[0][2],
@ -543,7 +627,7 @@ const skills = {
break; break;
} }
} }
"step 1"; ("step 1");
player.draw(event.num + cards.length); player.draw(event.num + cards.length);
}, },
subSkill: { subSkill: {
@ -624,7 +708,7 @@ const skills = {
} }
var skills = characters.map(i => lib.skill.dcbianzhuang.characterMap[i]); var skills = characters.map(i => lib.skill.dcbianzhuang.characterMap[i]);
player.chooseControl(skills).set("dialog", ["选择获得一个技能并“变装”", [characters, "character"]]); player.chooseControl(skills).set("dialog", ["选择获得一个技能并“变装”", [characters, "character"]]);
"step 1"; ("step 1");
var skill = result.control; var skill = result.control;
player.addTempSkills(skill, "dcbianzhuangAfter"); player.addTempSkills(skill, "dcbianzhuangAfter");
for (var i in lib.skill.dcbianzhuang.characterMap) { for (var i in lib.skill.dcbianzhuang.characterMap) {
@ -636,7 +720,7 @@ const skills = {
} }
} }
player.chooseUseTarget("sha", true, false, "nodistance"); player.chooseUseTarget("sha", true, false, "nodistance");
"step 2"; ("step 2");
if (result.bool && !player.storage.dcbianzhuang_inited) { if (result.bool && !player.storage.dcbianzhuang_inited) {
player.addMark("dcbianzhuang", 1, false); player.addMark("dcbianzhuang", 1, false);
if (player.countMark("dcbianzhuang") > 2) { if (player.countMark("dcbianzhuang") > 2) {
@ -713,7 +797,7 @@ const skills = {
var player = _status.event.player; var player = _status.event.player;
return 1 + Math.max(0, player.getUseValue(card, null, true)); return 1 + Math.max(0, player.getUseValue(card, null, true));
}); });
"step 1"; ("step 1");
if (result.bool) { if (result.bool) {
player.logSkill("dctongliao"); player.logSkill("dctongliao");
player.addGaintag(result.cards, "dctongliao"); player.addGaintag(result.cards, "dctongliao");
@ -835,7 +919,7 @@ const skills = {
return get.effect(target, { name: "sha" }, _status.event.player); return get.effect(target, { name: "sha" }, _status.event.player);
}) })
.setHiddenSkill("clbjisu"); .setHiddenSkill("clbjisu");
"step 1"; ("step 1");
if (result.bool) { if (result.bool) {
player.useCard({ name: "sha", isCard: true }, result.targets[0], false, "clbjisu"); player.useCard({ name: "sha", isCard: true }, result.targets[0], false, "clbjisu");
trigger.cancel(); trigger.cancel();
@ -983,7 +1067,7 @@ const skills = {
content() { content() {
"step 0"; "step 0";
player.removeGaintag("dcshixian_yayun"); player.removeGaintag("dcshixian_yayun");
"step 1"; ("step 1");
player.addGaintag( player.addGaintag(
player.getCards("h", card => { player.getCards("h", card => {
return get.is.yayun(get.translation(card.name), get.translation(trigger.card.name)); return get.is.yayun(get.translation(card.name), get.translation(trigger.card.name));
@ -1009,7 +1093,7 @@ const skills = {
content() { content() {
"step 0"; "step 0";
trigger.cancel(); trigger.cancel();
"step 1"; ("step 1");
var card = get.cardPile2(function (card) { var card = get.cardPile2(function (card) {
return get.type(card, null, false) == "equip"; return get.type(card, null, false) == "equip";
}), }),
@ -1054,7 +1138,7 @@ const skills = {
player.chooseButton(true, ["请选择执行一个天气", [list.map(i => [i, '<div class="popup text" style="width:calc(100% - 10px);display:inline-block"><div class="skill">【' + i + "】</div><div>" + lib.skill.dcsitian.weathers[i].description + "</div></div>"]), "textbutton"]]).set("ai", function (button) { player.chooseButton(true, ["请选择执行一个天气", [list.map(i => [i, '<div class="popup text" style="width:calc(100% - 10px);display:inline-block"><div class="skill">【' + i + "】</div><div>" + lib.skill.dcsitian.weathers[i].description + "</div></div>"]), "textbutton"]]).set("ai", function (button) {
return lib.skill.dcsitian.weathers[button.link].ai(_status.event.player); return lib.skill.dcsitian.weathers[button.link].ai(_status.event.player);
}); });
"step 1"; ("step 1");
if (result.bool) { if (result.bool) {
var choice = result.links[0]; var choice = result.links[0];
game.log(player, "将当前天气变更为", "#g" + choice); game.log(player, "将当前天气变更为", "#g" + choice);
@ -1126,7 +1210,7 @@ const skills = {
var targets = game.filterPlayer(current => current != player).sortBySeat(); var targets = game.filterPlayer(current => current != player).sortBySeat();
player.line(targets, "thunder"); player.line(targets, "thunder");
event.targets = targets; event.targets = targets;
"step 1"; ("step 1");
var target = targets.shift(); var target = targets.shift();
if (!target.isIn()) { if (!target.isIn()) {
if (targets.length > 0) event.redo(); if (targets.length > 0) event.redo();
@ -1139,7 +1223,7 @@ const skills = {
event.judgestr = get.translation("shandian"); event.judgestr = get.translation("shandian");
target.judge(lib.card.shandian.judge, event.judgestr).judge2 = lib.card.shandian.judge2; target.judge(lib.card.shandian.judge, event.judgestr).judge2 = lib.card.shandian.judge2;
//game.delayx(1.5); //game.delayx(1.5);
"step 2"; ("step 2");
var name = "shandian"; var name = "shandian";
if (event.cancelled && !event.direct) { if (event.cancelled && !event.direct) {
if (lib.card[name].cancel) { if (lib.card[name].cancel) {
@ -1179,7 +1263,7 @@ const skills = {
var targets = game.filterPlayer(current => current != player).sortBySeat(); var targets = game.filterPlayer(current => current != player).sortBySeat();
player.line(targets, "green"); player.line(targets, "green");
event.targets = targets; event.targets = targets;
"step 1"; ("step 1");
var target = targets.shift(); var target = targets.shift();
if (target.isIn()) { if (target.isIn()) {
var num = target.countCards("e"); var num = target.countCards("e");
@ -1220,7 +1304,7 @@ const skills = {
} }
return get.effect(current, { name: "losehp" }, player, player); return get.effect(current, { name: "losehp" }, player, player);
}); });
"step 1"; ("step 1");
if (result.bool) { if (result.bool) {
var target = result.targets[0]; var target = result.targets[0];
player.line(target, "green"); player.line(target, "green");
@ -1512,14 +1596,14 @@ const skills = {
} }
event.finish(); event.finish();
} }
"step 1"; ("step 1");
if (result.bool) { if (result.bool) {
if (!event.isMine() && !event.isOnline()) game.delayx(); if (!event.isMine() && !event.isOnline()) game.delayx();
event.targets = result.targets; event.targets = result.targets;
} else { } else {
event.finish(); event.finish();
} }
"step 2"; ("step 2");
player.logSkill("ruyijingubang_effect", event.targets); player.logSkill("ruyijingubang_effect", event.targets);
trigger.targets.addArray(event.targets); trigger.targets.addArray(event.targets);
}, },
@ -1625,7 +1709,7 @@ const skills = {
event.card = get.cards()[0]; event.card = get.cards()[0];
game.cardsGotoOrdering(event.card); game.cardsGotoOrdering(event.card);
player.showCards(event.card); player.showCards(event.card);
"step 1"; ("step 1");
player player
.chooseTarget("令一名角色获得" + get.translation(card), true) .chooseTarget("令一名角色获得" + get.translation(card), true)
.set("ai", function (target) { .set("ai", function (target) {
@ -1641,7 +1725,7 @@ const skills = {
return att; return att;
}) })
.set("du", card.name == "du"); .set("du", card.name == "du");
"step 2"; ("step 2");
if (result && result.bool) { if (result && result.bool) {
var target = result.targets[0]; var target = result.targets[0];
target.gain(card, "gain2"); target.gain(card, "gain2");
@ -1673,7 +1757,7 @@ const skills = {
content() { content() {
"step 0"; "step 0";
player.chooseDrawRecover("###" + get.prompt("spcangni") + "###摸两张牌或回复1点体力然后将武将牌翻面", 2).logSkill = "spcangni"; player.chooseDrawRecover("###" + get.prompt("spcangni") + "###摸两张牌或回复1点体力然后将武将牌翻面", 2).logSkill = "spcangni";
"step 1"; ("step 1");
if (result.control != "cancel2") player.turnOver(); if (result.control != "cancel2") player.turnOver();
}, },
group: ["spcangni_gain", "spcangni_lose"], group: ["spcangni_gain", "spcangni_lose"],
@ -1755,7 +1839,7 @@ const skills = {
content() { content() {
"step 0"; "step 0";
player.give(cards, targets[0]); player.give(cards, targets[0]);
"step 1"; ("step 1");
if (!targets[0].isIn() || !targets[1].isIn()) { if (!targets[0].isIn() || !targets[1].isIn()) {
event.finish(); event.finish();
return; return;
@ -1774,7 +1858,7 @@ const skills = {
return lib.filter.targetEnabled.apply(this, arguments); return lib.filter.targetEnabled.apply(this, arguments);
}) })
.set("sourcex", targets[1]); .set("sourcex", targets[1]);
"step 2"; ("step 2");
if (!result.bool && targets[0].countCards("h")) targets[1].gainPlayerCard(targets[0], "visible", "h", true); if (!result.bool && targets[0].countCards("h")) targets[1].gainPlayerCard(targets[0], "visible", "h", true);
}, },
ai: { ai: {
@ -1828,7 +1912,7 @@ const skills = {
return true; return true;
})() })()
); );
"step 1"; ("step 1");
if (result.bool) { if (result.bool) {
var target = trigger.player; var target = trigger.player;
player.logSkill("spfengyin", target); player.logSkill("spfengyin", target);

View File

@ -95,11 +95,10 @@ const translates = {
dczhanjiang: "斩将", dczhanjiang: "斩将",
dczhanjiang_info: "准备阶段,若场上有【青釭剑】,则你可以获得之。", dczhanjiang_info: "准备阶段,若场上有【青釭剑】,则你可以获得之。",
collab_olympic: "OL·伦敦奥运会", dc_wuyi: "经典吴懿",
collab_tongque: "OL·铜雀台", dc_wuyi_prefix: "经典",
collab_duanwu: "新服·端午畅玩", dcbenxi: "奔袭",
collab_decade: "新服·创玩节", dcbenxi_info: "转换技锁定技。当你失去手牌后系统随机检索出一句转换为拼音后包含“wu,yi”的技能台词然后你念出此台词。阳你获得上次所念出的台词对应的技能若你已拥有该技能则改为对其他角色各造成1点伤害。",
collab_remake: "新服·共创武将",
}; };
export default translates; export default translates;

View File

@ -10,6 +10,7 @@ import { characterSort, characterSortTranslate } from "./sort.js";
game.import("character", function () { game.import("character", function () {
return { return {
name: "key", name: "key",
connect: true,
character: { ...characters }, character: { ...characters },
characterSort: { characterSort: {
key: characterSort, key: characterSort,

View File

@ -1450,7 +1450,7 @@ export class Game {
* //如果key中包含发动技能的角色名player则直接改用info.audioname2[player]来播放语音 * //如果key中包含发动技能的角色名player则直接改用info.audioname2[player]来播放语音
* ``` * ```
*/ */
parseSkillAudio(skill, player, skillInfo, useRawAudio) { parseSkillAudio(skill, player, skillInfo) {
if (typeof player === "string") player = { name: player }; if (typeof player === "string") player = { name: player };
else if (typeof player !== "object" || player === null) player = {}; else if (typeof player !== "object" || player === null) player = {};
@ -1537,7 +1537,7 @@ export class Game {
if (!/^db:|^ext:|\//.test(audioInfo)) path = "skill/"; if (!/^db:|^ext:|\//.test(audioInfo)) path = "skill/";
if (!/\.\w+$/.test(audioInfo) && !["data:", "blob:"].some(name => audioInfo.startsWith(name))) format = ".mp3"; if (!/\.\w+$/.test(audioInfo) && !["data:", "blob:"].some(name => audioInfo.startsWith(name))) format = ".mp3";
if (path && format) return parseAudio(audioInfo, options, [true, 2]); if (path && format) return parseAudio(audioInfo, options, [true, 2]);
return [useRawAudio ? audioInfo : `${path}${audioInfo}${format}`]; return [`${path}${audioInfo}${format}`];
} }
let _audioname = getName(i => audioname.includes(i)); let _audioname = getName(i => audioname.includes(i));
@ -1548,8 +1548,7 @@ export class Game {
const audioList = []; const audioList = [];
list[2] = parseInt(list[2]); list[2] = parseInt(list[2]);
for (let i = 1; i <= list[2]; i++) { for (let i = 1; i <= list[2]; i++) {
if (useRawAudio) audioList.push(`${skill}${_audioname}${i}`); audioList.push(`${list[1] || "skill"}/${skill}${_audioname}${i}.${list[3] || "mp3"}`);
else audioList.push(`${list[1] || "skill"}/${skill}${_audioname}${i}.${list[3] || "mp3"}`);
} }
return audioList; return audioList;
} }
@ -1564,11 +1563,10 @@ export class Game {
* @returns { string[] } 语音地址列表 * @returns { string[] } 语音地址列表
*/ */
parseSkillText(skill, player, skillInfo) { parseSkillText(skill, player, skillInfo) {
const audios = game.parseSkillAudio(skill, player, skillInfo, true); const audios = game.parseSkillTextMap(skill, player, skillInfo);
const voiceMap = []; const voiceMap = [];
audios.forEach(audioname => { audios.forEach(audioname => {
const voiceText = lib.translate[`#${audioname}`]; if(audioname.text) voiceMap.push(audioname.text);
if (voiceText) voiceMap.push(voiceText);
}); });
return voiceMap; return voiceMap;
} }
@ -1577,16 +1575,112 @@ export class Game {
* @param { string } skill 技能名 * @param { string } skill 技能名
* @param { Player | Object | string } [player] 角色/角色名 * @param { Player | Object | string } [player] 角色/角色名
* @param { skillInfo | audioInfo } [skillInfo] 预设的skillInfo/audioInfo(转为skillInfo)覆盖lib.skill[skill] * @param { skillInfo | audioInfo } [skillInfo] 预设的skillInfo/audioInfo(转为skillInfo)覆盖lib.skill[skill]
* @returns { Object } 语音地址列表 * @returns { any[] } 语音地址列表
*/ */
parseSkillTextMap(skill, player, skillInfo) { parseSkillTextMap(skill, player, skillInfo) {
const audios = game.parseSkillAudio(skill, player, skillInfo, true); if (typeof player === "string") player = { name: player };
const voiceMap = {}; else if (typeof player !== "object" || player === null) player = {};
audios.forEach(audioname => {
const voiceText = lib.translate[`#${audioname}`]; if (skillInfo && (typeof skillInfo !== "object" || Array.isArray(skillInfo))) skillInfo = { audio: skillInfo };
if (voiceText) voiceMap[audioname] = voiceText;
}); const checkSkill = (skill, history) => {
return voiceMap; if (!lib.skill[skill]) return false;
if (!history.includes(skill)) return true;
if (history[0] === skill) return false;
//deadlock
throw new RangeError(`parseSkillAudio: ${skill} in ${history}forms a deadlock`);
};
const getName = filter => {
const name = (player.tempname || []).find(i => filter(i));
return (
name ||
[player.name, player.name1, player.name2].reduce((result, name) => {
if (result) return result;
if (!name) return result;
if (filter(name)) return name;
let tempname = (get.character(name).trashBin || []).find(tag => tag.startsWith("tempname:"));
if (!tempname) return result;
tempname = tempname
.split(":")
.slice(1)
.find(i => filter(i));
return tempname || result;
}, void 0)
);
};
function getAudioList(skill, options, skillInfo) {
const info = skillInfo || lib.skill[skill];
if (!info) {
console.error(new ReferenceError(`parseSkillAudio: Cannot find ${skill} in lib.skill`));
return parseAudio(skill, options, [true, 2]);
}
const { audioname, history } = options;
history.unshift(skill);
let audioInfo = info.audio;
if (Array.isArray(info.audioname)) audioname.addArray(info.audioname);
if (info.audioname2) audioInfo = info.audioname2[getName(i => info.audioname2[i])] || audioInfo;
if (typeof audioInfo === "function") audioInfo = audioInfo(player);
return parseAudio(skill, options, audioInfo);
}
function parseAudio(skill, options, audioInfo) {
const audioname = options.audioname.slice();
const history = options.history.slice();
options = { audioname, history };
if (Array.isArray(audioInfo)) {
if (typeof audioInfo[0] === "string" && typeof audioInfo[1] === "number") {
// [audioname, number]
if (checkSkill(audioInfo[0], history)) return getAudioList(audioInfo[0], options).slice(0, audioInfo[1]);
return parseAudio(audioInfo[0], options, audioInfo[1]);
}
return audioInfo.reduce((total, i) => total.addArray(parseAudio(skill, options, i)), []);
}
if (!["string", "number", "boolean"].includes(typeof audioInfo)) return parseAudio(skill, options, [true, 2]);
if (audioInfo === false) return [];
if (typeof audioInfo === "string" && checkSkill(audioInfo, history)) return getAudioList(audioInfo, options);
audioInfo = String(audioInfo);
let list = audioInfo.match(/(?:(.*):|^)(true|\d+)(?::(.*)|$)/); // [path, number|true, format]
if (!list) {
let path = "",
format = "";
if (!/^db:|^ext:|\//.test(audioInfo)) path = "skill/";
if (!/\.\w+$/.test(audioInfo) && !["data:", "blob:"].some(name => audioInfo.startsWith(name))) format = ".mp3";
if (path && format) return parseAudio(audioInfo, options, [true, 2]);
const key = audioInfo, file = `${path}${audioInfo}${format}`;
const data = {key, file};
if(lib.translate[`#${key}`]) data.text = lib.translate[`#${key}`];
return [data];
}
let _audioname = getName(i => audioname.includes(i));
_audioname = _audioname ? `_${_audioname}` : "";
if (list[2] === "true") {
const key = `${skill}${_audioname}`, file = `${list[1] || "skill"}/${skill}${_audioname}.${list[3] || "mp3"}`;
const data = {key, file};
if(lib.translate[`#${key}`]) data.text = lib.translate[`#${key}`];
return [data];
}
const audioList = []
list[2] = parseInt(list[2]);
for (let i = 1; i <= list[2]; i++) {
const key = `${skill}${_audioname}${i}`, file = `${list[1] || "skill"}/${skill}${_audioname}${i}.${list[3] || "mp3"}`;
const data = {key, file};
if(lib.translate[`#${key}`]) data.text = lib.translate[`#${key}`];
audioList.push(data);
}
return audioList;
}
return getAudioList(skill, { audioname: [], history: [] }, skillInfo);
} }
/** /**
* *