名将吴懿,修改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"]],
old_lingju: ["female", "qun", 3, ["jieyuan", "fenxin_old"]],
sp_mushun: ["male", "qun", 4, ["moukui"]],
dc_wuyi: ["male", "shu", 4, ["dcbenxi"]],
};
export default characters;

View File

@ -2,6 +2,90 @@ import { lib, game, ui, get, ai, _status } from "../../noname.js";
/** @type { importCharacterConfig['skill'] } */
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测试高达一号
//打赢复活赛的牢达[哭]
dclonghun: {
@ -355,7 +439,7 @@ const skills = {
player.gain(trigger.cards, "gain2");
}
player.draw(player.countMark("dcjianxiong") + 1, "nodelay");
"step 1";
("step 1");
if (player.countMark("dcjianxiong") < 4) player.addMark("dcjianxiong", 1, false);
},
marktext: "雄",
@ -410,7 +494,7 @@ const skills = {
player.addTempSkill("dcrende_targeted", "phaseUseAfter");
player.markAuto("dcrende_targeted", [target]);
player.gainPlayerCard(target, "h", true, 2);
"step 1";
("step 1");
var list = [];
for (var name of lib.inpile) {
if (get.type(name) != "basic") continue;
@ -469,7 +553,7 @@ const skills = {
} else {
event.finish();
}
"step 2";
("step 2");
if (result && result.bool && result.links[0]) {
var card = {
name: result.links[0][2],
@ -543,7 +627,7 @@ const skills = {
break;
}
}
"step 1";
("step 1");
player.draw(event.num + cards.length);
},
subSkill: {
@ -624,7 +708,7 @@ const skills = {
}
var skills = characters.map(i => lib.skill.dcbianzhuang.characterMap[i]);
player.chooseControl(skills).set("dialog", ["选择获得一个技能并“变装”", [characters, "character"]]);
"step 1";
("step 1");
var skill = result.control;
player.addTempSkills(skill, "dcbianzhuangAfter");
for (var i in lib.skill.dcbianzhuang.characterMap) {
@ -636,7 +720,7 @@ const skills = {
}
}
player.chooseUseTarget("sha", true, false, "nodistance");
"step 2";
("step 2");
if (result.bool && !player.storage.dcbianzhuang_inited) {
player.addMark("dcbianzhuang", 1, false);
if (player.countMark("dcbianzhuang") > 2) {
@ -713,7 +797,7 @@ const skills = {
var player = _status.event.player;
return 1 + Math.max(0, player.getUseValue(card, null, true));
});
"step 1";
("step 1");
if (result.bool) {
player.logSkill("dctongliao");
player.addGaintag(result.cards, "dctongliao");
@ -835,7 +919,7 @@ const skills = {
return get.effect(target, { name: "sha" }, _status.event.player);
})
.setHiddenSkill("clbjisu");
"step 1";
("step 1");
if (result.bool) {
player.useCard({ name: "sha", isCard: true }, result.targets[0], false, "clbjisu");
trigger.cancel();
@ -983,7 +1067,7 @@ const skills = {
content() {
"step 0";
player.removeGaintag("dcshixian_yayun");
"step 1";
("step 1");
player.addGaintag(
player.getCards("h", card => {
return get.is.yayun(get.translation(card.name), get.translation(trigger.card.name));
@ -1009,7 +1093,7 @@ const skills = {
content() {
"step 0";
trigger.cancel();
"step 1";
("step 1");
var card = get.cardPile2(function (card) {
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) {
return lib.skill.dcsitian.weathers[button.link].ai(_status.event.player);
});
"step 1";
("step 1");
if (result.bool) {
var choice = result.links[0];
game.log(player, "将当前天气变更为", "#g" + choice);
@ -1126,7 +1210,7 @@ const skills = {
var targets = game.filterPlayer(current => current != player).sortBySeat();
player.line(targets, "thunder");
event.targets = targets;
"step 1";
("step 1");
var target = targets.shift();
if (!target.isIn()) {
if (targets.length > 0) event.redo();
@ -1139,7 +1223,7 @@ const skills = {
event.judgestr = get.translation("shandian");
target.judge(lib.card.shandian.judge, event.judgestr).judge2 = lib.card.shandian.judge2;
//game.delayx(1.5);
"step 2";
("step 2");
var name = "shandian";
if (event.cancelled && !event.direct) {
if (lib.card[name].cancel) {
@ -1179,7 +1263,7 @@ const skills = {
var targets = game.filterPlayer(current => current != player).sortBySeat();
player.line(targets, "green");
event.targets = targets;
"step 1";
("step 1");
var target = targets.shift();
if (target.isIn()) {
var num = target.countCards("e");
@ -1220,7 +1304,7 @@ const skills = {
}
return get.effect(current, { name: "losehp" }, player, player);
});
"step 1";
("step 1");
if (result.bool) {
var target = result.targets[0];
player.line(target, "green");
@ -1512,14 +1596,14 @@ const skills = {
}
event.finish();
}
"step 1";
("step 1");
if (result.bool) {
if (!event.isMine() && !event.isOnline()) game.delayx();
event.targets = result.targets;
} else {
event.finish();
}
"step 2";
("step 2");
player.logSkill("ruyijingubang_effect", event.targets);
trigger.targets.addArray(event.targets);
},
@ -1625,7 +1709,7 @@ const skills = {
event.card = get.cards()[0];
game.cardsGotoOrdering(event.card);
player.showCards(event.card);
"step 1";
("step 1");
player
.chooseTarget("令一名角色获得" + get.translation(card), true)
.set("ai", function (target) {
@ -1641,7 +1725,7 @@ const skills = {
return att;
})
.set("du", card.name == "du");
"step 2";
("step 2");
if (result && result.bool) {
var target = result.targets[0];
target.gain(card, "gain2");
@ -1673,7 +1757,7 @@ const skills = {
content() {
"step 0";
player.chooseDrawRecover("###" + get.prompt("spcangni") + "###摸两张牌或回复1点体力然后将武将牌翻面", 2).logSkill = "spcangni";
"step 1";
("step 1");
if (result.control != "cancel2") player.turnOver();
},
group: ["spcangni_gain", "spcangni_lose"],
@ -1755,7 +1839,7 @@ const skills = {
content() {
"step 0";
player.give(cards, targets[0]);
"step 1";
("step 1");
if (!targets[0].isIn() || !targets[1].isIn()) {
event.finish();
return;
@ -1774,7 +1858,7 @@ const skills = {
return lib.filter.targetEnabled.apply(this, arguments);
})
.set("sourcex", targets[1]);
"step 2";
("step 2");
if (!result.bool && targets[0].countCards("h")) targets[1].gainPlayerCard(targets[0], "visible", "h", true);
},
ai: {
@ -1828,7 +1912,7 @@ const skills = {
return true;
})()
);
"step 1";
("step 1");
if (result.bool) {
var target = trigger.player;
player.logSkill("spfengyin", target);

View File

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

View File

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

View File

@ -1450,7 +1450,7 @@ export class Game {
* //如果key中包含发动技能的角色名player则直接改用info.audioname2[player]来播放语音
* ```
*/
parseSkillAudio(skill, player, skillInfo, useRawAudio) {
parseSkillAudio(skill, player, skillInfo) {
if (typeof player === "string") player = { name: player };
else if (typeof player !== "object" || player === null) player = {};
@ -1537,7 +1537,7 @@ export class Game {
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]);
return [useRawAudio ? audioInfo : `${path}${audioInfo}${format}`];
return [`${path}${audioInfo}${format}`];
}
let _audioname = getName(i => audioname.includes(i));
@ -1548,8 +1548,7 @@ export class Game {
const audioList = [];
list[2] = parseInt(list[2]);
for (let i = 1; i <= list[2]; i++) {
if (useRawAudio) audioList.push(`${skill}${_audioname}${i}`);
else audioList.push(`${list[1] || "skill"}/${skill}${_audioname}${i}.${list[3] || "mp3"}`);
audioList.push(`${list[1] || "skill"}/${skill}${_audioname}${i}.${list[3] || "mp3"}`);
}
return audioList;
}
@ -1564,11 +1563,10 @@ export class Game {
* @returns { string[] } 语音地址列表
*/
parseSkillText(skill, player, skillInfo) {
const audios = game.parseSkillAudio(skill, player, skillInfo, true);
const audios = game.parseSkillTextMap(skill, player, skillInfo);
const voiceMap = [];
audios.forEach(audioname => {
const voiceText = lib.translate[`#${audioname}`];
if (voiceText) voiceMap.push(voiceText);
if(audioname.text) voiceMap.push(audioname.text);
});
return voiceMap;
}
@ -1577,16 +1575,112 @@ export class Game {
* @param { string } skill 技能名
* @param { Player | Object | string } [player] 角色/角色名
* @param { skillInfo | audioInfo } [skillInfo] 预设的skillInfo/audioInfo(转为skillInfo)覆盖lib.skill[skill]
* @returns { Object } 语音地址列表
* @returns { any[] } 语音地址列表
*/
parseSkillTextMap(skill, player, skillInfo) {
const audios = game.parseSkillAudio(skill, player, skillInfo, true);
const voiceMap = {};
audios.forEach(audioname => {
const voiceText = lib.translate[`#${audioname}`];
if (voiceText) voiceMap[audioname] = voiceText;
});
return voiceMap;
if (typeof player === "string") player = { name: player };
else if (typeof player !== "object" || player === null) player = {};
if (skillInfo && (typeof skillInfo !== "object" || Array.isArray(skillInfo))) skillInfo = { audio: skillInfo };
const checkSkill = (skill, history) => {
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);
}
/**
*