名将吴懿,修改game.parseSkillTextMap的返回值
This commit is contained in:
parent
61689d4be7
commit
1c92bd3b7e
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -10,6 +10,7 @@ import { characterSort, characterSortTranslate } from "./sort.js";
|
|||
game.import("character", function () {
|
||||
return {
|
||||
name: "key",
|
||||
connect: true,
|
||||
character: { ...characters },
|
||||
characterSort: {
|
||||
key: characterSort,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
/**
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue