diff --git a/.eslintrc.json b/.eslintrc.json
index fde84ce4b7..84e8898fc3 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -31,4 +31,4 @@
"ecmaVersion": 13,
"sourceType": "module"
}
-}
\ No newline at end of file
+}
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index d2239a1e25..feaeaf832c 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -32,4 +32,4 @@
- [ ] 如果此次PR需要扩展跟进,我已在`扩展适配`中写入详细文档
- [ ] 如果这个PR解决了一个issue,我在`诱因和背景`中明确链接到该issue
- [ ] 我保证该PR中没有随意修改换行符等内容,没有制造出大量的Diff
-- [ ] 我保证该PR遵循项目中`.editorconfig`、`.eslintrc.json`和`.prettierrc`所规定的代码样式,并且已经通过`prettier`格式化过代码
+- [ ] 我保证该PR遵循项目中`.editorconfig`、`eslint.config.mjs`和`prettier.config.mjs`所规定的代码样式,并且已经通过`prettier`格式化过代码
diff --git a/.gitignore b/.gitignore
index cf3bd6cc25..c8875aef3e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,3 +30,4 @@ noname.ico
package-lock.json
package.json
Thumbs.db
+bun.lockb
diff --git a/.prettierrc b/.prettierrc
deleted file mode 100644
index b138a611b1..0000000000
--- a/.prettierrc
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "arrowParens": "always",
- "bracketSpacing": true,
- "endOfLine": "lf",
- "printWidth": 110,
- "proseWrap": "preserve",
- "quoteProps": "as-needed",
- "semi": true,
- "tabWidth": 4,
- "trailingComma": "es5",
- "useTabs": true
-}
diff --git a/card/standard.js b/card/standard.js
index aeca20f1be..9ea1a0d370 100644
--- a/card/standard.js
+++ b/card/standard.js
@@ -2146,138 +2146,48 @@ game.import("card", function () {
},
result: {
player: function (player, target) {
- let att = get.attitude(player, target),
- hs = target.hasCard(
- (card) => lib.filter.canBeGained(card, player, target),
- "h"
- ),
- lose = hs,
- gain = att > 0 ? 0.52 : 1.28;
- if (Math.abs(att) < 5.03) {
- let temp = 0.015 * att * att;
- if (att < 0) gain = 0.9 + temp;
- else gain = 0.9 - temp;
+ const hs = target.getGainableCards(player, 'h');
+ const es = target.getGainableCards(player, 'e');
+ const js = target.getGainableCards(player, 'j');
+ const att = get.attitude(player, target);
+ if (att < 0) {
+ if (!hs.length && !es.some(card => {
+ return get.value(card, target) > 0 && card != target.getEquip('jinhe');
+ }) && !js.some(card => {
+ var cardj = card.viewAs ? { name: card.viewAs } : card;
+ return get.effect(target, cardj, target, player) < 0;
+ })) return 0;
}
- target.countCards("e", function (card) {
- if (
- card.name != "jinhe" &&
- lib.filter.canBeGained(card, player, target) &&
- att * get.value(card, target) < 0
- ) {
- lose = true;
- let val = get.value(card, player);
- if (val > 0) gain = Math.max(gain, val / 7);
- }
- });
- target.countCards("j", function (card) {
- let cardj = card.viewAs ? new lib.element.VCard({ name: card.viewAs }) : card;
- if (
- lib.filter.canBeGained(card, player, target) &&
- att * get.effect(target, cardj, target, target) < 0
- ) {
- lose = true;
- if (cardj.name == "lebu") {
- let needs = target.needsToDiscard(2);
- if (att > 0) gain = Math.max(gain, 1.6 + needs / 10);
- } else if (
- cardj.name == "shandian" ||
- cardj.name == "fulei" ||
- cardj.name == "plague"
- )
- gain = Math.max(gain, 1.5 / Math.max(1, target.hp));
- else if (att > 0) gain = Math.max(gain, 1.7);
- }
- });
- if (!lose) return 0;
- return gain;
+ else if (att > 1) {
+ return (es.some(card => {
+ return get.value(card, target) <= 0;
+ }) || js.some(card => {
+ var cardj = card.viewAs ? { name: card.viewAs } : card;
+ return get.effect(target, cardj, target, player) < 0;
+ })) ? 1.5 : 0;
+ }
+ return 1;
},
target: function (player, target) {
- let att = get.attitude(player, target),
- hs = target.countCards("h", (card) =>
- lib.filter.canBeGained(card, player, target)
- ),
- es = target.countCards("e", (card) =>
- lib.filter.canBeGained(card, player, target)
- ),
- js = target.countCards("j", (card) =>
- lib.filter.canBeGained(card, player, target)
- ),
- noh = !hs || target.hasSkillTag("noh"),
- noe = !es || target.hasSkillTag("noe"),
- check = [-1, att > 0 ? -1.3 : 1.3, att > 0 ? -2.5 : 2.5],
- idx = -1;
- if (hs) {
- idx = 0;
- if (noh) check[0] = 0.7;
- }
- if (es) {
- if (idx < 0) idx = 1;
- if (
- target.getEquip("baiyin") &&
- target.isDamaged() &&
- lib.filter.canBeGained(target.getEquip("baiyin"), player, target)
- ) {
- let rec = get.recoverEffect(target, player, target);
- if (es == 1 || att * rec > 0) {
- let val = 3 - 0.6 * Math.min(5, target.hp);
- if (rec > 0) check[1] = val;
- else if (rec < 0) check[1] = -val;
- }
- }
- target.countCards("e", function (card) {
- let val = get.value(card, target);
- if (
- card.name == "jinhe" ||
- att * val >= 0 ||
- !lib.filter.canBeGained(card, player, target)
- )
- return false;
- if (att > 0) {
- check[1] = Math.max(1.3, check[1]);
- return true;
- }
- let sub = get.subtype(card);
- if (sub == "equip2" || sub == "equip5") val += 4;
- else if (sub == "equip1") val *= 0.4 * Math.min(3.6, target.hp);
- else val *= 0.6;
- if (target.hp < 3 && sub != "equip2" && sub != "equip5") val *= 0.4;
- check[1] = Math.min(-0.16 * val, check[1]);
- });
- if (noe) check[1] += 0.9;
- }
- if (js) {
- let func = function (num) {
- if (att > 0) check[2] = Math.max(check[2], num);
- else check[2] = Math.min(check[2], 0.6 - num);
- };
- if (idx < 0) idx = 2;
- target.countCards("j", function (card) {
- let cardj = card.viewAs
- ? new lib.element.VCard({ name: card.viewAs })
- : card;
- if (
- !lib.filter.canBeGained(card, player, target) ||
- att * get.effect(target, cardj, target, target) >= 0
- )
- return false;
- if (cardj.name == "lebu") func(2.1 + 0.4 * target.needsToDiscard(2));
- else if (cardj.name == "bingliang") func(2.4);
- else if (
- cardj.name == "shandian" ||
- cardj.name == "fulei" ||
- cardj.name == "plague"
- )
- func(Math.abs(check[2]) / (1 + target.hp));
- else func(2.1);
- });
- }
- if (idx < 0) return 0;
- for (let i = idx + 1; i < 3; i++) {
- if ((i == 1 && !es) || (i == 2 && !js)) continue;
- if ((att > 0 && check[i] > check[idx]) || (att <= 0 && check[i] < check[idx]))
- idx = i;
+ const hs = target.getGainableCards(player, 'h');
+ const es = target.getGainableCards(player, 'e');
+ const js = target.getGainableCards(player, 'j');
+
+ if (get.attitude(player, target) <= 0) {
+ if (hs.length > 0) return -1.5;
+ return (es.some(card => {
+ return get.value(card, target) > 0 && card != target.getEquip('jinhe');
+ }) || js.some(card => {
+ var cardj = card.viewAs ? { name: card.viewAs } : card;
+ return get.effect(target, cardj, target, player) < 0;
+ })) ? -1.5 : 1.5;
}
- return check[idx];
+ return (es.some(card => {
+ return get.value(card, target) <= 0;
+ }) || js.some(card => {
+ var cardj = card.viewAs ? { name: card.viewAs } : card;
+ return get.effect(target, cardj, target, player) < 0;
+ })) ? 1.5 : -1.5;
},
},
tag: {
@@ -2546,92 +2456,38 @@ game.import("card", function () {
},
result: {
target: function (player, target) {
- let att = get.attitude(player, target),
- hs = target.countCards("h", (card) =>
- lib.filter.canBeDiscarded(card, player, target)
- ),
- es = target.countCards("e", (card) =>
- lib.filter.canBeDiscarded(card, player, target)
- ),
- js = target.countCards("j", (card) =>
- lib.filter.canBeDiscarded(card, player, target)
- ),
- noh = !hs || target.hasSkillTag("noh"),
- noe = !es || target.hasSkillTag("noe"),
- check = [-1, att > 0 ? -1.3 : 1.3, att > 0 ? -2.5 : 2.5],
- idx = -1;
- if (hs) {
- idx = 0;
- if (noh) check[0] = 0.7;
- }
- if (es) {
- if (idx < 0) idx = 1;
- if (
- target.getEquip("baiyin") &&
- target.isDamaged() &&
- lib.filter.canBeDiscarded(target.getEquip("baiyin"), player, target)
- ) {
- let rec = get.recoverEffect(target, player, target);
- if (es == 1 || att * rec > 0) {
- let val = 3 - 0.6 * Math.min(5, target.hp);
- if (rec > 0) check[1] = val;
- else if (rec < 0) check[1] = -val;
- }
+ const att = get.attitude(player, target);
+ const hs = target.getDiscardableCards(player, 'h');
+ const es = target.getDiscardableCards(player, 'e');
+ const js = target.getDiscardableCards(player, 'j');
+ if (!hs.length && !es.length && !js.length) return 0;
+ if (att > 0) {
+ if (js.some(card => {
+ const cardj = card.viewAs ? { name: card.viewAs } : card;
+ return get.effect(target, cardj, target, player) < 0;
+ })) return 3;
+ if (target.isDamaged() && es.some(card => card.name == 'baiyin') &&
+ get.recoverEffect(target, player, player) > 0) {
+ if (target.hp == 1 && !target.hujia) return 1.6;
}
- target.countCards("e", function (card) {
- let val = get.value(card, target);
- if (
- card.name == "jinhe" ||
- att * val >= 0 ||
- !lib.filter.canBeDiscarded(card, player, target)
- )
- return false;
- if (att > 0) {
- check[1] = Math.max(1.3, check[1]);
- return true;
- }
- let sub = get.subtype(card);
- if (sub == "equip2" || sub == "equip5") val += 4;
- else if (sub == "equip1") val *= 0.4 * Math.min(3.6, target.hp);
- else val *= 0.6;
- if (target.hp < 3 && sub != "equip2" && sub != "equip5") val *= 0.4;
- check[1] = Math.min(-0.16 * val, check[1]);
- });
- if (noe) check[1] += 0.9;
- }
- if (js) {
- let func = function (num) {
- if (att > 0) check[2] = Math.max(check[2], num);
- else check[2] = Math.min(check[2], 0.6 - num);
- };
- if (idx < 0) idx = 2;
- target.countCards("j", function (card) {
- let cardj = card.viewAs
- ? new lib.element.VCard({ name: card.viewAs })
- : card;
- if (
- !lib.filter.canBeDiscarded(card, player, target) ||
- att * get.effect(target, cardj, target, target) >= 0
- )
- return false;
- if (cardj.name == "lebu") func(2.1 + 0.4 * target.needsToDiscard(2));
- else if (cardj.name == "bingliang") func(2.4);
- else if (
- cardj.name == "shandian" ||
- cardj.name == "fulei" ||
- cardj.name == "plague"
- )
- func(Math.abs(check[2]) / (1 + target.hp));
- else func(2.1);
- });
+ if (es.some(card => {
+ return get.value(card, target) < 0;
+ })) return 1;
+ return -1.5;
}
- if (idx < 0) return 0;
- for (let i = idx + 1; i < 3; i++) {
- if ((i == 1 && !es) || (i == 2 && !js)) continue;
- if ((att > 0 && check[i] > check[idx]) || (att <= 0 && check[i] < check[idx]))
- idx = i;
+ else {
+ const noh = (hs.length == 0 || target.hasSkillTag('noh'));
+ const noe = (es.length == 0 || target.hasSkillTag('noe'));
+ const noe2 = (noe || !es.some(card => {
+ return get.value(card, target) > 0;
+ }));
+ const noj = (js.length == 0 || !js.some(card => {
+ const cardj = card.viewAs ? { name: card.viewAs } : card;
+ return get.effect(target, cardj, target, player) < 0;
+ }))
+ if (noh && noe2 && noj) return 1.5;
+ return -1.5;
}
- return check[idx];
},
},
tag: {
@@ -2989,7 +2845,7 @@ game.import("card", function () {
cf = Math.pow(get.threaten(target, player), 2);
if (!num) return -0.01 * cf;
if (target.hp > 2) num--;
- let dist = Math.sqrt(get.distance(player, target, "absolute"));
+ let dist = Math.sqrt(1 + get.distance(player, target, "absolute"));
if (dist < 1) dist = 1;
if (target.isTurnedOver()) dist++;
return (Math.min(-0.1, -num) * cf) / dist;
diff --git a/character/clan.js b/character/clan.js
index 2e209b4705..c99823343e 100644
--- a/character/clan.js
+++ b/character/clan.js
@@ -1162,7 +1162,7 @@ game.import("character", function () {
var num = get.cardNameLength(event.card);
return typeof num == "number" && num > 0 && player.countCards("he") > 0;
},
- async content(event, trigger, player) {
+ async cost(event, trigger, player) {
var num = get.cardNameLength(trigger.card),
str = "";
if (player.getDamagedHp() > 0)
diff --git a/character/ddd.js b/character/ddd.js
index 07065aeb25..adaa7e8ba4 100644
--- a/character/ddd.js
+++ b/character/ddd.js
@@ -3361,6 +3361,9 @@ game.import("character", function () {
content() {
player.draw(3);
},
+ ai: {
+ combo: "dddfusi"
+ },
},
dddchashi: {
trigger: { global: "phaseUseBegin" },
@@ -5113,6 +5116,9 @@ game.import("character", function () {
},
},
},
+ ai: {
+ combo: "dddyouxue"
+ },
},
dddyouxue_old: {
audio: 2,
@@ -6624,7 +6630,7 @@ game.import("character", function () {
"锁定技。出牌阶段开始时,你选择一名角色,其弃置两张牌,然后你对一名角色造成1点伤害。" +
(player.storage["dddxiaheng_del"]
? ""
- : "。“若两名角色:均不为你,你失去一点体力上限;为同一名角色,你失去一点体力;然后若以此法对包括你在内三名不同的角色造成伤害,删除双引号里的描述内容”")
+ : "“若两名角色:均不为你,你失去一点体力上限;为同一名角色,你失去一点体力;然后若以此法对包括你在内三名不同的角色造成伤害,删除双引号里的描述内容”")
);
},
dddshichao(player) {
@@ -6638,9 +6644,8 @@ game.import("character", function () {
return (
"转换技,摸牌阶段,你" +
(player.hasMark("dddxuanlun_del") ? "" : "可") +
- "展示手牌(无牌则不展示),并改为摸其中" +
- (!player.storage["dddlanghuai"] ? "包含" : "缺少") +
- "花色数的牌。"
+ "展示手牌(无牌则不展示),并改为摸其中:" +
+ (player.storage["dddlanghuai"] ? '阴:包含花色数的牌;阳:缺少花色数的牌。' : '阴:包含花色数的牌;阳:缺少花色数的牌。')
);
},
dddxuanlun(player) {
diff --git a/character/diy.js b/character/diy.js
index 36bb7ae458..4d338ba346 100755
--- a/character/diy.js
+++ b/character/diy.js
@@ -5467,6 +5467,9 @@ game.import("character", function () {
content: () => {
trigger.forceYingbian = true;
},
+ ai: {
+ combo: "asara_shelu"
+ },
},
yukito_kongwu: {
enable: "phaseUse",
diff --git a/character/extra.js b/character/extra.js
index 1be166f7ac..77939c6101 100755
--- a/character/extra.js
+++ b/character/extra.js
@@ -753,6 +753,7 @@ game.import("character", function () {
},
direct: true,
changeSeat: true,
+ derivation: "tamo_faq",
async content(event, trigger, player) {
const toSortPlayers = game.filterPlayer((current) => !current.isZhu2());
toSortPlayers.sortBySeat(game.findPlayer2((current) => current.getSeatNum() == 1, true));
@@ -870,7 +871,7 @@ game.import("character", function () {
});
const { result } = await next;
if (!result.bool) return;
- player.logSkill("tamo");
+ await player.logSkill("tamo");
const resultList = result.moved[0].map((info) => {
return parseInt(info.split("|")[0]);
});
@@ -891,6 +892,25 @@ game.import("character", function () {
game.swapSeat(list[0], list[1], false);
}
}, toSwapList);
+ if (trigger.name === "phase" && !trigger.player.isZhu2() && trigger.player !== toSortPlayers[0] && !trigger._finished) {
+ trigger.finish();
+ trigger._triggered = 5;
+ const evt = toSortPlayers[0].insertPhase();
+ delete evt.skill;
+ const evt2 = trigger.getParent();
+ if (evt2.name == "phaseLoop" && evt2._isStandardLoop) {
+ evt2.player = toSortPlayers[0];
+ }
+ //跳过新回合的phaseBefore
+ evt.pushHandler("onPhase", (event, option) => {
+ if (
+ event.step === 0 &&
+ option.state === "begin"
+ ) {
+ event.step = 1;
+ }
+ });
+ }
await game.asyncDelay();
},
},
@@ -899,8 +919,9 @@ game.import("character", function () {
audio: 2,
trigger: { player: "phaseAfter" },
filter(event, player) {
- return game.hasPlayer((current) => {
- return current.countCards("h") + player.countCards("h") > 0 && player != current;
+ return game.hasPlayer(target => {
+ if(target==player||target.countCards('h')+player.countCards('h')==0) return false;
+ return get.mode()=='identity'||target.countCards('h')<=player.countCards('h')+1;
});
},
direct: true,
@@ -912,9 +933,8 @@ game.import("character", function () {
get.prompt("zhimeng"),
"与一名其他角色平分手牌",
(card, player, target) => {
- return (
- target.countCards("h") + player.countCards("h") > 0 && player != target
- );
+ if(target==player||target.countCards('h')+player.countCards('h')==0) return false;
+ return get.mode()=='identity'||target.countCards('h')<=player.countCards('h')+1;
}
)
.set("ai", (target) => {
@@ -1164,7 +1184,6 @@ game.import("character", function () {
default:
return false;
}
- break;
}
},
forced: true,
@@ -9397,6 +9416,9 @@ game.import("character", function () {
}
}
},
+ ai: {
+ combo: "nzry_junlve"
+ },
},
nzry_dinghuo: {
audio: 2,
@@ -10814,10 +10836,14 @@ game.import("character", function () {
dingzhou_info:
"出牌阶段限一次。你可以将X张牌交给一名场上有牌的角色,然后你获得其场上的所有牌(X为其场上的牌数+1)。",
tamo: "榻谟",
- tamo_info: "游戏开始时,你可以重新分配除主公外所有角色的座次。",
+ tamo_info:
+ "游戏开始时,你可以重新分配除主公外所有角色的座次。",
+ tamo_faq: "FAQ",
+ tamo_faq_info:
+ "
Q:在一号位不为主公的情况下,〖榻谟〗如何结算?A:该角色可以正常进行座次交换。若受此技能影响导致一号位角色发生了变化,则以排列后的一号位角色为起始角色开始本局游戏。",
zhimeng: "智盟",
- zhimeng_info:
- "回合结束后,你可以与一名其他角色将各自所有手牌置于处理区,然后你随机获得这些牌中的一半(向上取整),其获得剩余的牌。",
+ zhimeng_info_identity:'回合结束后,你可以选择一名其他角色。若如此做,你与其将各自所有手牌置于处理区,然后你随机获得这些牌中的一半(向上取整),其获得剩余的牌。',
+ zhimeng_info:'回合结束后,你可以选择一名手牌数不大于Y的其他角色(Y为你的手牌数+1)。若如此做,你与其将各自所有手牌置于处理区,然后你随机获得这些牌中的一半(向上取整),其获得剩余的牌。',
shen_xuzhu: "神许褚",
shen_xuzhu_prefix: "神",
zhengqing: "争擎",
diff --git a/character/huicui.js b/character/huicui.js
index a4a7236292..d1bc8a5636 100644
--- a/character/huicui.js
+++ b/character/huicui.js
@@ -7987,7 +7987,7 @@ game.import("character", function () {
},
async content(event, trigger, player) {
if (event.cards && event.cards.length) {
- await player.dicard(cards);
+ await player.discard(event.cards);
lib.skill.dcxieshou.change(player, 1);
} else {
player.drawTo(player.maxHp);
@@ -8005,6 +8005,9 @@ game.import("character", function () {
return false;
},
},
+ ai: {
+ neg: true
+ },
},
//公孙度
dczhenze: {
@@ -10831,7 +10834,10 @@ game.import("character", function () {
player.addTempSkill("zhishi_mark", { player: "phaseBegin" });
}
},
- ai: { expose: 0.3 },
+ ai: {
+ combo: "xunli",
+ expose: 0.3
+ },
subSkill: {
mark: {
trigger: {
@@ -12096,6 +12102,9 @@ game.import("character", function () {
}
}
},
+ ai: {
+ combo: "huguan"
+ },
},
mingluan: {
audio: 2,
@@ -15060,6 +15069,10 @@ game.import("character", function () {
content: function () {
player.removeMark("recangchu", Math.min(player.countMark("recangchu"), trigger.num || 1));
},
+ ai: {
+ combo: "recangchu",
+ neg: true
+ },
group: "reshishou2",
},
reshishou2: {
@@ -15493,7 +15506,7 @@ game.import("character", function () {
var list = ["sha", "shan", "tao", "jiu"];
for (var i of list) {
var strx = "【" + get.translation(i) + "】";
- if (!info || !info[0].includes(i))
+ if (info && !info[0].includes(i))
strx = '' + strx + "";
str += strx;
if (i != "jiu") str += "/";
diff --git a/character/jsrg.js b/character/jsrg.js
index d5015f55d0..1d2830e010 100644
--- a/character/jsrg.js
+++ b/character/jsrg.js
@@ -8741,6 +8741,9 @@ game.import("character", function () {
.set("cards", trigger.cards);
}
},
+ ai: {
+ combo: "jsrglirang"
+ },
},
//朱儁
jsrgfendi: {
diff --git a/character/mobile.js b/character/mobile.js
index 0a4992fc2e..38dbc9102d 100644
--- a/character/mobile.js
+++ b/character/mobile.js
@@ -394,8 +394,6 @@ game.import("character", function () {
"南华老仙,是古典小说《三国演义》中的虚拟人物。其原型来自道教典籍中对庄子的封号,又称“南华仙人”、“南华真人”等。在古典小说《三国演义》通行本的第一回中,描述了南华老仙将《太平要术》赠送给张角的情节。",
chenzhen:
"陈震(?—公元235年),字孝起。荆州南阳郡(今河南南阳)人。三国时期蜀汉官员。刘备领荆州牧时,辟陈震为从事。后随刘备入蜀,为蜀郡北部都尉、汶山太守、犍为太守。建兴三年(225年),拜尚书,迁尚书令。建兴七年(229年),孙权称帝。蜀汉以陈震为卫尉,前往祝贺,与孙权开坛歃盟,交分天下。还蜀,封城阳亭侯。建兴十三年(235年),卒。",
- nanhualaoxian:
- "南华老仙,其原型来自道教典籍中对庄子的封号,又称“南华仙人”、“南华真人”等。在古典小说《三国演义》通行本的第一回中,描述了南华老仙将《太平要术》赠送给张角的情节。",
hucheer:
"胡车儿(生卒年不详),东汉末年武将,初从张绣,为其心腹猛将,勇冠三军,与贾诩交情甚佳。宛城大战后,张绣投降曹操,曹操爱胡车儿之骁勇,手以黄金与之。后因曹操私纳张绣亡叔张济的遗孀邹氏,张绣深感其辱,欲杀曹操,与贾诩商议后决心反曹。《三国演义》中,作者考虑到典韦的勇猛,便增加了令胡车儿盗走典韦的双戟的情节。最终典韦、曹昂(曹操长子)、曹安民(曹操侄子)皆死于此次战斗。野史说胡车儿跟随曹操征战,被赵云在长坂坡上红枪挑死。",
simashi:
@@ -660,7 +658,6 @@ game.import("character", function () {
},
mbshishou: {
audio: 2,
- forced: true,
trigger: { player: "useSkillAfter" },
filter(event, player) {
return event.skill === "mbzuoyou" && !event.targets.includes(player);
@@ -675,6 +672,9 @@ game.import("character", function () {
player
);
},
+ ai: {
+ combo: "mbzuoyou"
+ },
},
//成济
mbkuangli: {
@@ -1061,6 +1061,9 @@ game.import("character", function () {
})
);
},
+ ai: {
+ combo: "mbqianlong"
+ },
},
mbcmqingzheng: {
audio: "sbqingzheng",
@@ -1732,6 +1735,9 @@ game.import("character", function () {
},
},
},
+ ai: {
+ combo: "mbxuetu"
+ },
},
//霍骏
sidai: {
@@ -1907,10 +1913,9 @@ game.import("character", function () {
if (name == "damageSource" && player.getHistory("sourceDamage").indexOf(event) != 0)
return false;
return game.hasPlayer((target) => {
- if (get.mode() != "doudizhu") {
- if (name == "damageEnd" && get.distance(player, target) <= 2) return false;
- if (name == "damageSource" && get.distance(player, target) > 2) return false;
- }
+ const num = (get.mode() == 'doudizhu' ? 1 : 2);
+ if (name == "damageEnd" && get.distance(player, target) <= num) return false;
+ if (name == "damageSource" && get.distance(player, target) > num) return false;
const zhoufa = player.storage.zhoulin_zhoufa;
if (!zhoufa) return true;
if (zhoufa == "豹" || zhoufa == "兔") return true;
@@ -1931,7 +1936,7 @@ game.import("character", function () {
: "令其随机执行一个效果";
const nodoudizhu =
get.mode() == "doudizhu"
- ? ""
+ ? "距离" + (event.triggername == "damageEnd" ? "" : "不") + "大于1的"
: "距离" + (event.triggername == "damageEnd" ? "" : "不") + "大于2的";
const {
result: { bool, targets },
@@ -1941,12 +1946,9 @@ game.import("character", function () {
"选择一名" + nodoudizhu + "角色," + str,
(card, player, target) => {
const name = _status.event.triggername;
- if (get.mode() != "doudizhu") {
- if (name == "damageEnd" && get.distance(player, target) <= 2)
- return false;
- if (name == "damageSource" && get.distance(player, target) > 2)
- return false;
- }
+ const num = (get.mode() == 'doudizhu' ? 1 : 2);
+ if (name == "damageEnd" && get.distance(player, target) <= num) return false;
+ if (name == "damageSource" && get.distance(player, target) > num) return false;
const zhoufa = player.storage.zhoulin_zhoufa;
if (!zhoufa) return true;
if (zhoufa == "豹" || zhoufa == "兔") return true;
@@ -2714,7 +2716,6 @@ game.import("character", function () {
},
forced: true,
popup: false,
- onremove: true,
firstDo: true,
init: function (player, skill) {
player.storage[skill] = 0;
@@ -10578,23 +10579,6 @@ game.import("character", function () {
//钟会
requanji: {
audio: 2,
- mod: {
- aiOrder: (player, card, num) => {
- if (
- num <= 0 ||
- typeof card !== "object" ||
- !player.isPhaseUsing() ||
- !player.hasSkill("zili") ||
- player.needsToDiscard()
- )
- return num;
- if (
- player.getExpansions("quanji").length < 3 &&
- player.getUseValue(card) < Math.min(4, (player.hp * player.hp) / 4)
- )
- return 0;
- },
- },
trigger: { player: ["damageEnd", "phaseUseEnd"] },
frequent: true,
locked: false,
@@ -10634,9 +10618,24 @@ game.import("character", function () {
}
},
mod: {
- maxHandcard: function (player, num) {
+ maxHandcard(player, num) {
return num + player.getExpansions("quanji").length;
},
+ aiOrder(player, card, num) {
+ if (
+ num <= 0 ||
+ typeof card !== "object" ||
+ !player.isPhaseUsing() ||
+ !player.hasSkill("zili") ||
+ player.needsToDiscard()
+ )
+ return num;
+ if (
+ player.getExpansions("quanji").length < 3 &&
+ player.getUseValue(card) < Math.min(4, (player.hp * player.hp) / 4)
+ )
+ return 0;
+ },
},
onremove: function (player, skill) {
var cards = player.getExpansions("quanji");
@@ -14213,6 +14212,9 @@ game.import("character", function () {
evt.targets.push(target);
}
},
+ ai: {
+ combo: "zhengjian"
+ },
},
//一 将 成 名
zhilve: {
@@ -20043,7 +20045,7 @@ game.import("character", function () {
},
shoufa: function (player) {
const zhoufa = player.storage.zhoulin_zhoufa;
- const nodoudizhu = get.mode() == "doudizhu" ? "" : "与你距离大于/不大于2的";
+ const nodoudizhu = get.mode() == "doudizhu" ? "与你距离大于/不大于1的" : "与你距离大于/不大于2的";
if (!zhoufa)
return (
"当你受到伤害后/于一回合首次造成伤害后,你可以选择一名" +
@@ -21081,10 +21083,6 @@ game.import("character", function () {
re_liru_prefix: "手杀界",
re_chenqun: "手杀界陈群",
re_chenqun_prefix: "手杀界",
- re_liru: "手杀界李儒",
- re_liru_prefix: "手杀界",
- re_chenqun: "手杀界陈群",
- re_chenqun_prefix: "手杀界",
old_yuanshu: "手杀袁术",
old_yuanshu_prefix: "手杀",
baoxin: "鲍信",
@@ -21161,7 +21159,7 @@ game.import("character", function () {
shoufa_info:
"当你受到伤害后/于一回合首次造成伤害后,你可以选择一名与你距离大于/不大于2的角色,令其随机执行以下一项:豹,令其受到1点无来源伤害;鹰,你随机获得其一张牌;熊,你随机弃置其装备区的一张牌;兔,令其摸一张牌。",
shoufa_info_doudizhu:
- "当你受到伤害后/于一回合首次造成伤害后,你可以选择一名角色,令其随机执行以下一项:豹,令其受到1点无来源伤害;鹰,你随机获得其一张牌;熊,你随机弃置其装备区的一张牌;兔,令其摸一张牌。",
+ "当你受到伤害后/于一回合首次造成伤害后,你可以选择一名与你距离大于/不大于1的角色,令其随机执行以下一项:豹,令其受到1点无来源伤害;鹰,你随机获得其一张牌;熊,你随机弃置其装备区的一张牌;兔,令其摸一张牌。",
yuxiang: "御象",
yuxiang_info:
"锁定技,若你有护甲值,则:①你计算与其他角色的距离-1,其他角色计算与你的距离+1;②当你受到火焰伤害时,此伤害+1。",
diff --git a/character/offline.js b/character/offline.js
index f606dda500..662a28be9e 100644
--- a/character/offline.js
+++ b/character/offline.js
@@ -4049,6 +4049,7 @@ game.import("character", function () {
result: {
player: 1,
},
+ combo: "zyquanji"
},
},
//孙綝
@@ -6954,6 +6955,9 @@ game.import("character", function () {
player.loseToDiscardpile(cards);
if (num <= 1) player.draw();
},
+ ai: {
+ combo: "spyicong"
+ },
},
sptuji2: {
onremove: true,
diff --git a/character/old.js b/character/old.js
index a4f2eaeed9..aaf9d071f3 100755
--- a/character/old.js
+++ b/character/old.js
@@ -1169,7 +1169,13 @@ game.import("character", function () {
content: function () {
player.addToExpansion(cards, player, "give").gaintag.add("old_jijun");
},
- ai: { order: 1, result: { player: 1 } },
+ ai: {
+ order: 1,
+ result: {
+ player: 1
+ },
+ combo: "old_fangtong"
+ },
},
old_fangtong: {
trigger: {
@@ -1186,6 +1192,9 @@ game.import("character", function () {
var winners = player.getFriends();
game.over(player == game.me || winners.includes(game.me));
},
+ ai:{
+ combo: "oldjijun"
+ },
},
oldanxu: {
enable: "phaseUse",
diff --git a/character/rank.js b/character/rank.js
index 04ecef1a0c..3ad34972e2 100644
--- a/character/rank.js
+++ b/character/rank.js
@@ -1,6 +1,6 @@
window.noname_character_rank = {
s: [
- 'sp_sunce',
+ "sp_sunce",
"gjqt_bailitusu",
"gjqt_beiluo",
"gjqt_xieyi",
@@ -1720,7 +1720,7 @@ window.noname_character_rank = {
],
rarity: {
legend: [
- 'sp_sunce',
+ "sp_sunce",
"star_caoren",
"dc_zhaoyun",
"dc_caocao",
diff --git a/character/sb.js b/character/sb.js
index a294009df6..519e02fdca 100644
--- a/character/sb.js
+++ b/character/sb.js
@@ -890,7 +890,7 @@ game.import("character", function () {
} = await player
.chooseTarget(
get.prompt("sbjieming"),
- `令一名角色摸三张牌,然后其可以弃置任意张牌。若其弃置的牌数不大于${get.cnNumber(
+ `令一名角色摸四张牌,然后其可以弃置任意张牌。若其弃置的牌数不大于${get.cnNumber(
num
)}张,你失去1点体力。`
)
@@ -921,7 +921,7 @@ game.import("character", function () {
if (!bool) return;
const target = targets[0];
player.logSkill("sbjieming", target);
- await target.draw(3);
+ await target.draw(4);
num = Math.max(1, player.getDamagedHp());
const {
result: { bool: bool2, cards },
@@ -8984,7 +8984,7 @@ game.import("character", function () {
"出牌阶段限一次。你可以选择两名有牌的其他角色,你与这些角色同时将任意张牌扣置于武将牌上。若你以此法扣置的牌唯一最少,则扣置牌最多的其他角色获得你扣置的牌,且这些角色获得各自扣置的牌;否则这两名角色中扣置牌较多的角色对较少的角色造成1点伤害,获得你扣置的牌,然后这些角色将各自扣置的牌置入弃牌堆(若这两名角色扣置的牌数相同,视为与你逆时针最近座次的角色扣置牌较多)。",
sbjieming: "节命",
sbjieming_info:
- "当你受到伤害后,你可以令一名角色摸三张牌,然后其可以弃置任意张牌。若其弃置的牌数不大于X,你失去1点体力(X为你已损失的体力值,至少为1)。",
+ "当你受到伤害后,你可以令一名角色摸四张牌,然后其可以弃置任意张牌。若其弃置的牌数不大于X,你失去1点体力(X为你已损失的体力值,至少为1)。",
sb_xiahoudun: "谋夏侯惇",
sb_xiahoudun_prefix: "谋",
sbganglie: "刚烈",
diff --git a/character/shiji.js b/character/shiji.js
index acf6dddf13..88ed695d2c 100644
--- a/character/shiji.js
+++ b/character/shiji.js
@@ -3554,6 +3554,9 @@ game.import("character", function () {
"step 1";
player.addSkills("xinmouli");
},
+ ai: {
+ combo: "xingqi"
+ },
group: ["mibei_fail", "mibei_silent"],
derivation: "xinmouli",
subSkill: {
diff --git a/character/sp.js b/character/sp.js
index 0caadc3a33..1654df0524 100755
--- a/character/sp.js
+++ b/character/sp.js
@@ -18,6 +18,7 @@ game.import("character", function () {
"tengfanglan",
"ruiji",
"caoxiancaohua",
+ "caoyu",
],
sp_sibi: [
"ol_lukai",
@@ -143,7 +144,7 @@ game.import("character", function () {
"sp_zhangliao",
"sp_ol_zhanghe",
"sp_menghuo",
- 'sp_sunce',
+ "sp_sunce",
],
sp_qifu: [
"ol_feiyi",
@@ -168,7 +169,6 @@ game.import("character", function () {
"ol_tw_zhangji",
"ol_liwan",
"ol_liuyan",
- "caoyu",
"liupan",
"ol_liupi",
],
@@ -184,12 +184,12 @@ game.import("character", function () {
ol_mengda(mode) {
return mode !== "guozhan";
},
- ol_mengda(mode){
- return mode!=='guozhan';
+ ol_mengda(mode) {
+ return mode !== "guozhan";
},
},
character: {
- sp_sunce:['male','qun',4,['olliantao']],
+ sp_sunce: ["male", "qun", 4, ["olliantao"]],
ol_liupi: ["male", "qun", 4, ["olyicheng"]],
ol_lukai: ["male", "wu", 3, ["olxuanzhu", "oljiane"]],
liupan: ["male", "qun", 4, ["olpijing"]],
@@ -968,117 +968,177 @@ game.import("character", function () {
},
skill: {
//SP孙策
- olliantao:{
- audio:2,
- trigger:{player:'phaseUseBegin'},
- filter(event,player){
- return game.hasPlayer(target=>target!=player);
- },
- async cost(event,trigger,player){
- event.result=await player.chooseTarget(get.prompt2('olliantao'),lib.filter.notMe).set('ai',target=>{
- const player=get.event('player'),att=get.attitude(player,target);
- const colors=Object.keys(lib.color).filter(i=>i!='none');
- if(!colors.some(color=>player.hasCard(card=>{
- const juedou=get.autoViewAs({name:'juedou'},[card]);
- return player.canUse(juedou,target,false);
- },'h'))) return 20+(3-get.sgn(att))+Math.random();
- const effs=colors.reduce((list,color)=>{
- const cards=player.getCards('h',card=>{
- const juedou=get.autoViewAs({name:'juedou'},[card]);
- return player.canUse(juedou,target,false);
- });
- if(cards.length){
- list.push(cards.reduce((sum,card)=>{
- const juedou=get.autoViewAs({name:'juedou'},[card]);
- return sum+get.effect(target,card,player,player);
- },0));
- }
- return list;
- },[]);
- return Math[att>0?'max':'min'].apply(Math,list);
- }).forResult();
- },
- async content(event,trigger,player){
- const target=event.targets[0];
- const colors=Object.keys(lib.color).filter(i=>i!='none');
- if(colors.length&&player.countCards('h')){
- const result=await target.chooseControl(colors)
- .set('prompt','连讨:请选择一个颜色').set('ai',()=>{
- const player=get.event('player'),source=get.event().getParent().player;
- let controls=get.event('controls').slice();
- if(controls.length==1) return controls[0];
- const getSum=function(color,player,source){
- return source.getCards('h',card=>{
- if(get.color(card)!=color) return false;
- const juedou=get.autoViewAs({name:'juedou'},[card]);
- return source.canUse(juedou,player,false);
- }).reduce((num,card)=>{
- const juedou=get.autoViewAs({name:'juedou'},[card]);
- return num+get.effect(player,card,source,player);
- },0);
- };
- return controls.sort((a,b)=>getSum(b,player,source)-getSum(a,player,source))[0];
- }).set('prompt2',get.translation(player)+'将对你依次使用由其手牌中所有此颜色的牌转化的【决斗】').forResult();
- const color=result.control;
- game.broadcastAll((color,target)=>{
- lib.skill.olliantao_backup.filterCardx=[color,target];
- lib.skill.olliantao_backup.filterCard=function(card,player){
- const list=lib.skill.olliantao_backup.filterCardx;
- if(get.color(card)!=list[0]) return false;
- const juedou=get.autoViewAs({name:'juedou'},[card]);
- return player.canUse(juedou,list[1],false);
- };
- },color,target);
- while(target.isIn()&&player.hasCard(card=>lib.skill.olliantao_backup.filterCard(card,player))&&!game.getGlobalHistory('everything',evt=>{
- return evt.name=='dying'&&[player,target].includes(evt.player)&&evt.getParent('olliantao')==event;
- }).length){
- await player.chooseToUse().set('forced',true)
- .set('openskilldialog','连讨:将一张'+get.translation(color)+'手牌当作【决斗】对'+get.translation(target)+'使用')
- .set('norestore',true).set('_backupevent','olliantao_backup').set('custom',{
- add:{},
- replace:{window:function(){}},
- }).backup('olliantao_backup').set('targetRequired',true).set('complexSelect',true)
- .set('filterTarget',function(card,player,target){
- if(target!=_status.event.sourcex&&!ui.selected.targets.includes(_status.event.sourcex)) return false;
- return lib.filter.targetEnabled.apply(this, arguments);
- }).set('sourcex',target).set('addCount',false);
- }
- }
- const num=player.getHistory('sourceDamage',evt=>{
- return evt.getParent(4)==event;
- }).reduce((sum,evt)=>sum+evt.num,0);
- if(num) await player.draw(num);
- if(!game.hasPlayer2(current=>{
- return current.getHistory('damage',evt=>{
- return evt.getParent(4)==event;
- }).length;
- })){
+ olliantao: {
+ audio: 2,
+ trigger: { player: "phaseUseBegin" },
+ filter(event, player) {
+ return game.hasPlayer((target) => target != player);
+ },
+ async cost(event, trigger, player) {
+ event.result = await player
+ .chooseTarget(get.prompt2("olliantao"), lib.filter.notMe)
+ .set("ai", (target) => {
+ const player = get.event("player"),
+ att = get.attitude(player, target);
+ const colors = Object.keys(lib.color).filter((i) => i != "none");
+ if (
+ !colors.some((color) =>
+ player.hasCard((card) => {
+ const juedou = get.autoViewAs({ name: "juedou" }, [card]);
+ return player.canUse(juedou, target, false);
+ }, "h")
+ )
+ )
+ return 20 + (3 - get.sgn(att)) + Math.random();
+ const effs = colors.reduce((list, color) => {
+ const cards = player.getCards("h", (card) => {
+ const juedou = get.autoViewAs({ name: "juedou" }, [card]);
+ return player.canUse(juedou, target, false);
+ });
+ if (cards.length) {
+ list.push(
+ cards.reduce((sum, card) => {
+ const juedou = get.autoViewAs({ name: "juedou" }, [card]);
+ return sum + get.effect(target, juedou, player, player);
+ }, 0)
+ );
+ }
+ return list;
+ }, []);
+ return Math[att > 0 ? "max" : "min"].apply(Math, list);
+ })
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ const target = event.targets[0];
+ const colors = Object.keys(lib.color).filter((i) => i != "none");
+ if (colors.length && player.countCards("h")) {
+ const result = await target
+ .chooseControl(colors)
+ .set("prompt", "连讨:请选择一个颜色")
+ .set("ai", () => {
+ const player = get.event("player"),
+ source = get.event().getParent().player;
+ let controls = get.event("controls").slice();
+ if (controls.length == 1) return controls[0];
+ const getSum = function (color, player, source) {
+ return source
+ .getCards("h", (card) => {
+ if (get.color(card) != color) return false;
+ const juedou = get.autoViewAs({ name: "juedou" }, [card]);
+ return source.canUse(juedou, player, false);
+ })
+ .reduce((num, card) => {
+ const juedou = get.autoViewAs({ name: "juedou" }, [card]);
+ return num + get.effect(player, juedou, source, player);
+ }, 0);
+ };
+ return controls.sort(
+ (a, b) => getSum(b, player, source) - getSum(a, player, source)
+ )[0];
+ })
+ .set(
+ "prompt2",
+ get.translation(player) +
+ "将对你依次使用由其手牌中所有此颜色的牌转化的【决斗】"
+ )
+ .forResult();
+ const color = result.control;
+ game.broadcastAll(
+ (color, target) => {
+ lib.skill.olliantao_backup.filterCardx = [color, target];
+ lib.skill.olliantao_backup.filterCard = function (card, player) {
+ const list = lib.skill.olliantao_backup.filterCardx;
+ if (get.color(card) != list[0]) return false;
+ const juedou = get.autoViewAs({ name: "juedou" }, [card]);
+ return player.canUse(juedou, list[1], false);
+ };
+ },
+ color,
+ target
+ );
+ while (
+ target.isIn() &&
+ player.hasCard((card) => lib.skill.olliantao_backup.filterCard(card, player)) &&
+ !game.getGlobalHistory("everything", (evt) => {
+ return (
+ evt.name == "dying" &&
+ [player, target].includes(evt.player) &&
+ evt.getParent("olliantao") == event
+ );
+ }).length
+ ) {
+ await player
+ .chooseToUse()
+ .set("forced", true)
+ .set(
+ "openskilldialog",
+ "连讨:将一张" +
+ get.translation(color) +
+ "手牌当作【决斗】对" +
+ get.translation(target) +
+ "使用"
+ )
+ .set("norestore", true)
+ .set("_backupevent", "olliantao_backup")
+ .set("custom", {
+ add: {},
+ replace: { window: function () {} },
+ })
+ .backup("olliantao_backup")
+ .set("targetRequired", true)
+ .set("complexSelect", true)
+ .set("filterTarget", function (card, player, target) {
+ if (
+ target != _status.event.sourcex &&
+ !ui.selected.targets.includes(_status.event.sourcex)
+ )
+ return false;
+ return lib.filter.targetEnabled.apply(this, arguments);
+ })
+ .set("sourcex", target)
+ .set("addCount", false);
+ }
+ }
+ const num = player
+ .getHistory("sourceDamage", (evt) => {
+ return evt.getParent(4) == event;
+ })
+ .reduce((sum, evt) => sum + evt.num, 0);
+ if (num) await player.draw(num);
+ if (
+ !game.hasPlayer2((current) => {
+ return current.getHistory("damage", (evt) => {
+ return evt.getParent(4) == event;
+ }).length;
+ })
+ ) {
await player.draw(3);
- player.addTempSkill('olliantao_buff');
- player.addMark('olliantao_buff',3,false);
+ player.addTempSkill("olliantao_buff");
+ player.addMark("olliantao_buff", 3, false);
}
},
- subSkill:{
- backup:{
- viewAs:{name:'juedou'},
- position:'h',
- check:()=>1+Math.random(),
- precontent(){
+ subSkill: {
+ backup: {
+ viewAs: { name: "juedou" },
+ position: "h",
+ check: () => 1 + Math.random(),
+ precontent() {
delete event.result.skill;
},
},
- buff:{
- charlotte:true,
- onremove:true,
- mod:{
- maxHandcard(player,num){
- return num+player.countMark('olliantao_buff');
+ buff: {
+ charlotte: true,
+ onremove: true,
+ mod: {
+ maxHandcard(player, num) {
+ return num + player.countMark("olliantao_buff");
},
- cardEnabled(card){
- if(card.name=='sha') return false;
+ cardEnabled(card) {
+ if (card.name == "sha") return false;
},
},
- intro:{content:'手牌上限+#,不能使用【杀】'},
+ intro: { content: "手牌上限+#,不能使用【杀】" },
},
},
},
@@ -1088,7 +1148,7 @@ game.import("character", function () {
enable: "phaseUse",
usable: 1,
async content(event, trigger, player) {
- let cards = get.cards(3);
+ let num = player.maxHp, cards = get.cards(num);
await game.cardsGotoOrdering(cards);
await player.showCards(cards, get.translation(player) + "发动了【易城】");
if (player.countCards("h")) {
@@ -1121,7 +1181,7 @@ game.import("character", function () {
.set("filterOk", (moved) => moved[1].some((i) => !get.owner(i)))
.set("processAI", (list) => {
const player = get.event("player"),
- limit = Math.min(3, player.countCards("h"));
+ limit = Math.min(get.event("num"), player.countCards("h"));
let cards = list[0][1].slice(),
hs = player.getCards("h");
if (
@@ -1156,7 +1216,8 @@ game.import("character", function () {
}
return list;
}
- });
+ })
+ .set("num", num);
if (bool) {
const puts = player.getCards("h", (i) => moved[0].includes(i));
const gains = cards.filter((i) => moved[1].includes(i));
@@ -2606,18 +2667,18 @@ game.import("character", function () {
if (!ui.selected.targets.length) return 0;
const target = ui.selected.targets[0];
if (
- player.getHistory("useSkill", (evt) => {
+ player.hasAllHistory("useSkill", (evt) => {
return (
evt.skill == "olgongjie" &&
(evt.targets || [evt.target]).includes(target)
);
- }).length &&
- player.getHistory("useSkill", (evt) => {
+ }) &&
+ player.hasAllHistory("useSkill", (evt) => {
return (
evt.skill == "olxiangxv" &&
(evt.targets || [evt.target]).includes(target)
);
- }).length
+ })
) {
if (get.attitude(player, target) > 0) return 1;
if (player.canSaveCard(card, player)) return 0;
@@ -2634,18 +2695,18 @@ game.import("character", function () {
ai2(target) {
const player = get.event("player");
const goon =
- player.getHistory("useSkill", (evt) => {
+ player.hasAllHistory("useSkill", (evt) => {
return (
evt.skill == "olgongjie" &&
(evt.targets || [evt.target]).includes(target)
);
- }).length &&
- player.getHistory("useSkill", (evt) => {
+ }) &&
+ player.hasAllHistory("useSkill", (evt) => {
return (
evt.skill == "olxiangxv" &&
(evt.targets || [evt.target]).includes(target)
);
- }).length,
+ }),
att = get.attitude(player, target);
if (goon) return 5 * att;
if (!!player.countCards("he", (cardx) => player.canSaveCard(cardx, player)))
@@ -2664,12 +2725,12 @@ game.import("character", function () {
player.awakenSkill("olxiangzuo");
await player.give(cards, target);
if (
- player.getHistory("useSkill", (evt) => {
+ player.hasAllHistory("useSkill", (evt) => {
return evt.skill == "olgongjie" && evt.targets.includes(target);
- }).length &&
- player.getHistory("useSkill", (evt) => {
+ }) &&
+ player.hasAllHistory("useSkill", (evt) => {
return evt.skill == "olxiangxv" && evt.targets.includes(target);
- }).length
+ })
)
await player.recover(cards.length);
},
@@ -3056,7 +3117,7 @@ game.import("character", function () {
? ""
: `。若${get.translation(
trigger.player
- )}受到了此【杀】的伤害,你获得其一张牌。`
+ )}受到了此【杀】的伤害,你获得其一张牌。`
}`
);
next.set("norestore", true);
@@ -3395,9 +3456,8 @@ game.import("character", function () {
];
[0, 1, 2].forEach((item, index) => {
if (event.list.includes(item)) {
- choiceList[
- index
- ] = `${choiceList[index]}`;
+ choiceList[index] =
+ `${choiceList[index]}`;
} else choices.push(`选项${get.cnNumber(index + 1, true)}`);
});
game.me
@@ -7028,7 +7088,7 @@ game.import("character", function () {
delete stat.gushe;
},
ai: {
- combo: "gushe"
+ combo: "gushe",
},
},
//OL刘老板
@@ -12778,10 +12838,13 @@ game.import("character", function () {
(_status.connectMode || current.hasSha())
) {
current
- .chooseToUse(function (card, player, event) {
- if (get.name(card) != "sha") return false;
- return lib.filter.filterCard.apply(this, arguments);
- }, "同协:是否对" + get.translation(target) + "使用一张杀?")
+ .chooseToUse(
+ function (card, player, event) {
+ if (get.name(card) != "sha") return false;
+ return lib.filter.filterCard.apply(this, arguments);
+ },
+ "同协:是否对" + get.translation(target) + "使用一张杀?"
+ )
.set("targetRequired", true)
.set("complexSelect", true)
.set("filterTarget", function (card, player, target) {
@@ -14430,6 +14493,10 @@ game.import("character", function () {
"的选项"
);
},
+ ai: {
+ combo: "luochong",
+ neg: true
+ },
},
//SP孟获
spmanwang: {
@@ -17318,10 +17385,13 @@ game.import("character", function () {
"step 0";
var target = trigger.targets[0];
target
- .chooseToUse(function (card, player, event) {
- if (get.name(card) != "sha") return false;
- return lib.filter.filterCard.apply(this, arguments);
- }, "武娘:是否对" + get.translation(player) + "使用一张杀?")
+ .chooseToUse(
+ function (card, player, event) {
+ if (get.name(card) != "sha") return false;
+ return lib.filter.filterCard.apply(this, arguments);
+ },
+ "武娘:是否对" + get.translation(player) + "使用一张杀?"
+ )
.set("targetRequired", true)
.set("complexSelect", true)
.set("filterTarget", function (card, player, target) {
@@ -21948,7 +22018,7 @@ game.import("character", function () {
},
},
ai: {
- combo: "wylianji"
+ combo: "wylianji",
},
},
jingong: {
@@ -28882,7 +28952,7 @@ game.import("character", function () {
player.changeSkills(["xiaoji"], ["liangzhu"]);
},
ai: {
- combo: "liangzhu"
+ combo: "liangzhu",
},
},
mingshi: {
@@ -31423,6 +31493,7 @@ game.import("character", function () {
},
usable: 1,
direct: true,
+ derivation: ["lingren_jianxiong", "lingren_xingshang"],
content: function () {
"step 0";
player
@@ -32577,6 +32648,9 @@ game.import("character", function () {
player.gain(event.togain, "gain2");
}
},
+ ai: {
+ combo: "xinfu_falu"
+ },
},
zhenyi_spade: {
trigger: {
@@ -32783,7 +32857,7 @@ game.import("character", function () {
},
spmanwang: function (player) {
var num = 4 - player.countMark("spmanwang");
- var str = "出牌阶段,你可以弃置任意张牌。然后你依次执行以下选项中的前X项:";
+ var str = "出牌阶段,你可以弃置任意张牌。然后你依次执行以下选项中的前等量项:";
var list = ["⒈获得〖叛侵〗。", "⒉摸一张牌。", "⒊回复1点体力。", "⒋摸两张牌并失去〖叛侵〗。"];
for (var i = 0; i < 4; i++) {
if (i == num) {
@@ -34465,7 +34539,7 @@ game.import("character", function () {
"当你的手牌数变为全场最少时,你可以获得以下效果:本回合结束时,将手牌数调整至与当前回合角色手牌数相同(至多摸至五张),然后若你以此法弃置了至少两张手牌,则你回复1点体力。",
olxiangzuo: "襄胙",
olxiangzuo_info:
- "限定技,当你进入濒死状态时,你可以交给一名其他角色任意张牌,然后若你本回合已对其发动过〖恭节〗和〖相胥〗,你回复等量的体力。",
+ "限定技,当你进入濒死状态时,你可以交给一名其他角色任意张牌,然后若你已对其发动过〖恭节〗和〖相胥〗,你回复等量的体力。",
liyi: "李异",
olchanshuang: "缠双",
olchanshuang_info:
@@ -34504,11 +34578,12 @@ game.import("character", function () {
ol_liupi: "刘辟",
olyicheng: "易城",
olyicheng_info:
- "出牌阶段限一次,你可以亮出牌堆顶的三张牌,然后你可以以任意手牌交换这些牌,若这三张牌的点数和因此增加,则你可以选择用所有手牌交换这三张牌。最后你将这三张牌置于牌堆顶。",
- sp_sunce:'SP孙策',
- sp_sunce_prefix:'SP',
- olliantao:'连讨',
- olliantao_info:'出牌阶段开始时,你可以令一名其他角色选择一个颜色,然后你依次将此颜色的所有手牌当作【决斗】对其使用直到有一方进入濒死状态,然后你摸X张牌(X为你本次以此法造成的伤害数)。若没有角色因本次技能结算受到伤害,你摸三张牌,本回合手牌上限+3且本回合你不能使用【杀】。',
+ "出牌阶段限一次,你可以亮出牌堆顶的X张牌(X为你的体力上限),然后你可以以任意手牌交换其中等量张牌,若亮出的牌的点数和因此增加,则你可以选择用所有手牌交换亮出的牌。最后你将亮出的牌置于牌堆顶。",
+ sp_sunce: "SP孙策",
+ sp_sunce_prefix: "SP",
+ olliantao: "连讨",
+ olliantao_info:
+ "出牌阶段开始时,你可以令一名其他角色选择一个颜色,然后你依次将此颜色的所有手牌当作【决斗】对其使用直到有一方进入濒死状态,然后你摸X张牌(X为你本次以此法造成的伤害数)。若没有角色因本次技能结算受到伤害,你摸三张牌,本回合手牌上限+3且本回合你不能使用【杀】。",
sp_tianji: "天极·皇室宗亲",
sp_sibi: "四弼·辅国文曲",
diff --git a/character/sp2.js b/character/sp2.js
index 6caefd98f7..de3e006b48 100644
--- a/character/sp2.js
+++ b/character/sp2.js
@@ -2448,7 +2448,7 @@ game.import("character", function () {
} = await player.chooseButton(dialog, true).set("ai", (button) => {
const player = get.event("player"),
target = get.event().getParent().targets[0];
- return get.value(card, player) * get.value(card, target) * (1 + Math.random());
+ return get.value(button.link, player) * get.value(button.link, target) * (1 + Math.random());
});
if (bool) {
await player.gain(links, target, "giveAuto", "bySelf");
@@ -9794,6 +9794,9 @@ game.import("character", function () {
player.markSkill("mubing_rewrite");
player.chooseDrawRecover(2, true);
},
+ ai: {
+ combo: "mubing"
+ },
derivation: "mubing_rewrite",
},
refenyin_wufan: { audio: 2 },
diff --git a/character/standard.js b/character/standard.js
index 0e8a9e9946..6f2226595a 100755
--- a/character/standard.js
+++ b/character/standard.js
@@ -279,6 +279,9 @@ game.import("character", function () {
evt.targets.remove(trigger.target);
evt.targets.push(player);
},
+ ai: {
+ neg: true
+ },
},
hujia: {
audio: 2,
@@ -2492,6 +2495,7 @@ game.import("character", function () {
trigger.source.chooseDrawRecover(true);
},
ai: {
+ halfneg: true,
effect: {
target(card, player, target, current) {
if (card.name == "sha" && get.color(card) == "red") {
diff --git a/character/tw.js b/character/tw.js
index 9c1cc61cd0..e4e72e3109 100644
--- a/character/tw.js
+++ b/character/tw.js
@@ -18750,7 +18750,9 @@ game.import("character", function () {
audio: 2,
enable: "phaseUse",
usable: 1,
- filterTarget: lib.filter.notMe,
+ filterTarget: function (card, player, target) {
+ return target.hp >= player.hp;
+ },
content: function () {
"step 0";
var str = get.translation(target);
diff --git a/character/xianding.js b/character/xianding.js
index aa1b34a2c7..efbc5c73b7 100644
--- a/character/xianding.js
+++ b/character/xianding.js
@@ -19631,7 +19631,7 @@ game.import("character", function () {
zhugemengxue: "诸葛梦雪",
dcjichun: "寄春",
dcjichun_info:
- "出牌阶段限一次,你可以展示一张手牌并选择一项:①将此牌交给一名手牌数小于你的角色,然后摸X张牌。②弃置此牌并弃置一名手牌数大于你的角色区域里至多X张牌。(X为此牌牌名字数)",
+ "出牌阶段限一次,你可以展示一张牌并选择一项:①将此牌交给一名手牌数小于你的角色,然后摸X张牌。②弃置此牌并弃置一名手牌数大于你的角色区域里至多X张牌。(X为此牌牌名字数)",
dchanying: "寒英",
dchanying_info:
"准备阶段,你可以亮出牌堆里的一张非赠物装备牌,然后令一名手牌数等于你的角色使用此牌。",
diff --git a/eslint.config.mjs b/eslint.config.mjs
new file mode 100644
index 0000000000..127cec053a
--- /dev/null
+++ b/eslint.config.mjs
@@ -0,0 +1,39 @@
+import js from "@eslint/js";
+import globals from "globals";
+
+export default [
+ js.configs.recommended,
+ {
+ rules: {
+ "no-console": 0,
+ "no-constant-condition": [
+ "error",
+ {
+ checkLoops: false,
+ },
+ ],
+ "no-irregular-whitespace": [
+ "error",
+ {
+ skipStrings: true,
+ skipTemplates: true,
+ },
+ ],
+ "no-redeclare": 0,
+ "no-undef": 0,
+ "no-unused-vars": 0,
+ "require-yield": 0,
+ },
+ languageOptions: {
+ ecmaVersion: 13,
+ sourceType: "module",
+ globals: {
+ ...globals.browser,
+ ...globals.es2015,
+ ...globals.node,
+ ...globals.serviceworker,
+ ...globals.worker,
+ },
+ },
+ },
+];
diff --git a/game/update.js b/game/update.js
index 3ad3d7dbe6..374e6f21fa 100644
--- a/game/update.js
+++ b/game/update.js
@@ -1,13 +1,9 @@
window.noname_update = {
- version: "1.10.11.1",
+ version: "1.10.11.2",
update: "NULL", //新版本更新文件较多,直接强制进行全量更新
changeLog: [
- "整合@Rintim @mengxinzxz @nonameShijian @lieren2023 @itsnoteasytonameaccount @kuangshen04 @IceCola97 @PZ157 @universe-st @Iking123 @copcap @nineMangos 的Pull Request",
- "OL族王广、族王明山、界王异、刘辟、SP孙策;十周年曹芳、武关羽、神华佗、SP甄姬",
- "手杀SP毌丘俭、曹髦、成济、李昭&焦伯;海外服颜良、文丑、袁谭",
- "添加“无限火力”单挑模式",
- "拆分“技能的消耗”和“技能的效果”,加入“按点卖血”等同时机多次发动技能的机制,逐步淘汰direct:true的写法",
- "其他AI优化与bug修复",
+ "整合@Rintim @nonameShijian @copcap @PZ157 @mengxinzxz @lieren2023 的Pull Request",
+ "bug修复",
],
files: [],
};
diff --git a/mode/versus.js b/mode/versus.js
index 952c2dc8c0..8a1967da4f 100644
--- a/mode/versus.js
+++ b/mode/versus.js
@@ -1248,14 +1248,14 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
next.setContent(function () {
"step 0";
ui.arena.classList.add("choose-character");
- for (var i in lib.skill) {
- if (lib.skill[i].changeSeat) {
- lib.skill[i] = {};
- if (lib.translate[i + "_info"]) {
- lib.translate[i + "_info"] = "此模式下不可用";
- }
- }
- }
+ // for (var i in lib.skill) {
+ // if (lib.skill[i].changeSeat) {
+ // lib.skill[i] = {};
+ // if (lib.translate[i + "_info"]) {
+ // lib.translate[i + "_info"] = "此模式下不可用";
+ // }
+ // }
+ // }
var bool = Math.random() < 0.5;
var bool2 = Math.random() < 0.5;
var ref = game.players[0];
diff --git a/node_modules/@types/noname-typings/cordova-plugin-android-permissions.d.ts b/node_modules/@types/noname-typings/cordova-plugin-android-permissions.d.ts
new file mode 100644
index 0000000000..7c8af5f8b5
--- /dev/null
+++ b/node_modules/@types/noname-typings/cordova-plugin-android-permissions.d.ts
@@ -0,0 +1,197 @@
+// from npm @types/cordova-plugin-android-permissions
+
+interface PermissionStatus {
+ hasPermission: boolean;
+}
+
+interface Permissions {
+ ACCESS_CHECKIN_PROPERTIES: "android.permission.ACCESS_CHECKIN_PROPERTIES";
+ ACCESS_BACKGROUND_LOCATION: "android.permission.ACCESS_BACKGROUND_LOCATION";
+ ACCESS_COARSE_LOCATION: "android.permission.ACCESS_COARSE_LOCATION";
+ ACCESS_FINE_LOCATION: "android.permission.ACCESS_FINE_LOCATION";
+ ACCESS_LOCATION_EXTRA_COMMANDS: "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS";
+ ACCESS_MOCK_LOCATION: "android.permission.ACCESS_MOCK_LOCATION";
+ ACCESS_NETWORK_STATE: "android.permission.ACCESS_NETWORK_STATE";
+ ACCESS_SURFACE_FLINGER: "android.permission.ACCESS_SURFACE_FLINGER";
+ ACCESS_WIFI_STATE: "android.permission.ACCESS_WIFI_STATE";
+ ACCOUNT_MANAGER: "android.permission.ACCOUNT_MANAGER";
+ ACTIVITY_RECOGNITION: "android.permission.ACTIVITY_RECOGNITION";
+ ADD_VOICEMAIL: "com.android.voicemail.permission.ADD_VOICEMAIL";
+ AUTHENTICATE_ACCOUNTS: "android.permission.AUTHENTICATE_ACCOUNTS";
+ BATTERY_STATS: "android.permission.BATTERY_STATS";
+ BIND_ACCESSIBILITY_SERVICE: "android.permission.BIND_ACCESSIBILITY_SERVICE";
+ BIND_APPWIDGET: "android.permission.BIND_APPWIDGET";
+ BIND_CARRIER_MESSAGING_SERVICE: "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
+ BIND_DEVICE_ADMIN: "android.permission.BIND_DEVICE_ADMIN";
+ BIND_DREAM_SERVICE: "android.permission.BIND_DREAM_SERVICE";
+ BIND_INPUT_METHOD: "android.permission.BIND_INPUT_METHOD";
+ BIND_NFC_SERVICE: "android.permission.BIND_NFC_SERVICE";
+ BIND_NOTIFICATION_LISTENER_SERVICE: "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE";
+ BIND_PRINT_SERVICE: "android.permission.BIND_PRINT_SERVICE";
+ BIND_REMOTEVIEWS: "android.permission.BIND_REMOTEVIEWS";
+ BIND_TEXT_SERVICE: "android.permission.BIND_TEXT_SERVICE";
+ BIND_TV_INPUT: "android.permission.BIND_TV_INPUT";
+ BIND_VOICE_INTERACTION: "android.permission.BIND_VOICE_INTERACTION";
+ BIND_VPN_SERVICE: "android.permission.BIND_VPN_SERVICE";
+ BIND_WALLPAPER: "android.permission.BIND_WALLPAPER";
+ BLUETOOTH: "android.permission.BLUETOOTH";
+ BLUETOOTH_ADMIN: "android.permission.BLUETOOTH_ADMIN";
+ BLUETOOTH_ADVERTISE: "android.permission.BLUETOOTH_ADVERTISE";
+ BLUETOOTH_CONNECT: "android.permission.BLUETOOTH_CONNECT";
+ BLUETOOTH_PRIVILEGED: "android.permission.BLUETOOTH_PRIVILEGED";
+ BLUETOOTH_SCAN: "android.permission.BLUETOOTH_SCAN";
+ BODY_SENSORS: "android.permission.BODY_SENSORS";
+ BRICK: "android.permission.BRICK";
+ BROADCAST_PACKAGE_REMOVED: "android.permission.BROADCAST_PACKAGE_REMOVED";
+ BROADCAST_SMS: "android.permission.BROADCAST_SMS";
+ BROADCAST_STICKY: "android.permission.BROADCAST_STICKY";
+ BROADCAST_WAP_PUSH: "android.permission.BROADCAST_WAP_PUSH";
+ CALL_PHONE: "android.permission.CALL_PHONE";
+ CALL_PRIVILEGED: "android.permission.CALL_PRIVILEGED";
+ CAMERA: "android.permission.CAMERA";
+ CAPTURE_AUDIO_OUTPUT: "android.permission.CAPTURE_AUDIO_OUTPUT";
+ CAPTURE_SECURE_VIDEO_OUTPUT: "android.permission.CAPTURE_SECURE_VIDEO_OUTPUT";
+ CAPTURE_VIDEO_OUTPUT: "android.permission.CAPTURE_VIDEO_OUTPUT";
+ CHANGE_COMPONENT_ENABLED_STATE: "android.permission.CHANGE_COMPONENT_ENABLED_STATE";
+ CHANGE_CONFIGURATION: "android.permission.CHANGE_CONFIGURATION";
+ CHANGE_NETWORK_STATE: "android.permission.CHANGE_NETWORK_STATE";
+ CHANGE_WIFI_MULTICAST_STATE: "android.permission.CHANGE_WIFI_MULTICAST_STATE";
+ CHANGE_WIFI_STATE: "android.permission.CHANGE_WIFI_STATE";
+ CLEAR_APP_CACHE: "android.permission.CLEAR_APP_CACHE";
+ CLEAR_APP_USER_DATA: "android.permission.CLEAR_APP_USER_DATA";
+ CONTROL_LOCATION_UPDATES: "android.permission.CONTROL_LOCATION_UPDATES";
+ DELETE_CACHE_FILES: "android.permission.DELETE_CACHE_FILES";
+ DELETE_PACKAGES: "android.permission.DELETE_PACKAGES";
+ DEVICE_POWER: "android.permission.DEVICE_POWER";
+ DIAGNOSTIC: "android.permission.DIAGNOSTIC";
+ DISABLE_KEYGUARD: "android.permission.DISABLE_KEYGUARD";
+ DUMP: "android.permission.DUMP";
+ EXPAND_STATUS_BAR: "android.permission.EXPAND_STATUS_BAR";
+ FACTORY_TEST: "android.permission.FACTORY_TEST";
+ FLASHLIGHT: "android.permission.FLASHLIGHT";
+ FORCE_BACK: "android.permission.FORCE_BACK";
+ GET_ACCOUNTS: "android.permission.GET_ACCOUNTS";
+ GET_PACKAGE_SIZE: "android.permission.GET_PACKAGE_SIZE";
+ GET_TASKS: "android.permission.GET_TASKS";
+ GET_TOP_ACTIVITY_INFO: "android.permission.GET_TOP_ACTIVITY_INFO";
+ GLOBAL_SEARCH: "android.permission.GLOBAL_SEARCH";
+ HARDWARE_TEST: "android.permission.HARDWARE_TEST";
+ INJECT_EVENTS: "android.permission.INJECT_EVENTS";
+ INSTALL_LOCATION_PROVIDER: "android.permission.INSTALL_LOCATION_PROVIDER";
+ INSTALL_PACKAGES: "android.permission.INSTALL_PACKAGES";
+ INSTALL_SHORTCUT: "com.android.launcher.permission.INSTALL_SHORTCUT";
+ INTERNAL_SYSTEM_WINDOW: "android.permission.INTERNAL_SYSTEM_WINDOW";
+ INTERNET: "android.permission.INTERNET";
+ KILL_BACKGROUND_PROCESSES: "android.permission.KILL_BACKGROUND_PROCESSES";
+ LOCATION_HARDWARE: "android.permission.LOCATION_HARDWARE";
+ MANAGE_ACCOUNTS: "android.permission.MANAGE_ACCOUNTS";
+ MANAGE_APP_TOKENS: "android.permission.MANAGE_APP_TOKENS";
+ MANAGE_DOCUMENTS: "android.permission.MANAGE_DOCUMENTS";
+ MASTER_CLEAR: "android.permission.MASTER_CLEAR";
+ MEDIA_CONTENT_CONTROL: "android.permission.MEDIA_CONTENT_CONTROL";
+ MODIFY_AUDIO_SETTINGS: "android.permission.MODIFY_AUDIO_SETTINGS";
+ MODIFY_PHONE_STATE: "android.permission.MODIFY_PHONE_STATE";
+ MOUNT_FORMAT_FILESYSTEMS: "android.permission.MOUNT_FORMAT_FILESYSTEMS";
+ MOUNT_UNMOUNT_FILESYSTEMS: "android.permission.MOUNT_UNMOUNT_FILESYSTEMS";
+ NFC: "android.permission.NFC";
+ PERSISTENT_ACTIVITY: "android.permission.PERSISTENT_ACTIVITY";
+ POST_NOTIFICATIONS: "android.permission.POST_NOTIFICATIONS";
+ PROCESS_OUTGOING_CALLS: "android.permission.PROCESS_OUTGOING_CALLS";
+ READ_CALENDAR: "android.permission.READ_CALENDAR";
+ READ_CALL_LOG: "android.permission.READ_CALL_LOG";
+ READ_CONTACTS: "android.permission.READ_CONTACTS";
+ READ_EXTERNAL_STORAGE: "android.permission.READ_EXTERNAL_STORAGE";
+ READ_FRAME_BUFFER: "android.permission.READ_FRAME_BUFFER";
+ READ_HISTORY_BOOKMARKS: "com.android.browser.permission.READ_HISTORY_BOOKMARKS";
+ READ_INPUT_STATE: "android.permission.READ_INPUT_STATE";
+ READ_LOGS: "android.permission.READ_LOGS";
+ READ_MEDIA_AUDIO: "android.permission.READ_MEDIA_AUDIO";
+ READ_MEDIA_IMAGES: "android.permission.READ_MEDIA_IMAGES";
+ READ_MEDIA_VIDEO: "android.permission.READ_MEDIA_VIDEO";
+ READ_PHONE_STATE: "android.permission.READ_PHONE_STATE";
+ READ_PROFILE: "android.permission.READ_PROFILE";
+ READ_SMS: "android.permission.READ_SMS";
+ READ_SOCIAL_STREAM: "android.permission.READ_SOCIAL_STREAM";
+ READ_SYNC_SETTINGS: "android.permission.READ_SYNC_SETTINGS";
+ READ_SYNC_STATS: "android.permission.READ_SYNC_STATS";
+ READ_USER_DICTIONARY: "android.permission.READ_USER_DICTIONARY";
+ READ_VOICEMAIL: "com.android.voicemail.permission.READ_VOICEMAIL";
+ REBOOT: "android.permission.REBOOT";
+ RECEIVE_BOOT_COMPLETED: "android.permission.RECEIVE_BOOT_COMPLETED";
+ RECEIVE_MMS: "android.permission.RECEIVE_MMS";
+ RECEIVE_SMS: "android.permission.RECEIVE_SMS";
+ RECEIVE_WAP_PUSH: "android.permission.RECEIVE_WAP_PUSH";
+ RECORD_AUDIO: "android.permission.RECORD_AUDIO";
+ REORDER_TASKS: "android.permission.REORDER_TASKS";
+ RESTART_PACKAGES: "android.permission.RESTART_PACKAGES";
+ SEND_RESPOND_VIA_MESSAGE: "android.permission.SEND_RESPOND_VIA_MESSAGE";
+ SEND_SMS: "android.permission.SEND_SMS";
+ SET_ACTIVITY_WATCHER: "android.permission.SET_ACTIVITY_WATCHER";
+ SET_ALARM: "com.android.alarm.permission.SET_ALARM";
+ SET_ALWAYS_FINISH: "android.permission.SET_ALWAYS_FINISH";
+ SET_ANIMATION_SCALE: "android.permission.SET_ANIMATION_SCALE";
+ SET_DEBUG_APP: "android.permission.SET_DEBUG_APP";
+ SET_ORIENTATION: "android.permission.SET_ORIENTATION";
+ SET_POINTER_SPEED: "android.permission.SET_POINTER_SPEED";
+ SET_PREFERRED_APPLICATIONS: "android.permission.SET_PREFERRED_APPLICATIONS";
+ SET_PROCESS_LIMIT: "android.permission.SET_PROCESS_LIMIT";
+ SET_TIME: "android.permission.SET_TIME";
+ SET_TIME_ZONE: "android.permission.SET_TIME_ZONE";
+ SET_WALLPAPER: "android.permission.SET_WALLPAPER";
+ SET_WALLPAPER_HINTS: "android.permission.SET_WALLPAPER_HINTS";
+ SIGNAL_PERSISTENT_PROCESSES: "android.permission.SIGNAL_PERSISTENT_PROCESSES";
+ STATUS_BAR: "android.permission.STATUS_BAR";
+ SUBSCRIBED_FEEDS_READ: "android.permission.SUBSCRIBED_FEEDS_READ";
+ SUBSCRIBED_FEEDS_WRITE: "android.permission.SUBSCRIBED_FEEDS_WRITE";
+ SYSTEM_ALERT_WINDOW: "android.permission.SYSTEM_ALERT_WINDOW";
+ TRANSMIT_IR: "android.permission.TRANSMIT_IR";
+ UNINSTALL_SHORTCUT: "com.android.launcher.permission.UNINSTALL_SHORTCUT";
+ UPDATE_DEVICE_STATS: "android.permission.UPDATE_DEVICE_STATS";
+ USE_CREDENTIALS: "android.permission.USE_CREDENTIALS";
+ USE_SIP: "android.permission.USE_SIP";
+ VIBRATE: "android.permission.VIBRATE";
+ WAKE_LOCK: "android.permission.WAKE_LOCK";
+ WRITE_APN_SETTINGS: "android.permission.WRITE_APN_SETTINGS";
+ WRITE_CALENDAR: "android.permission.WRITE_CALENDAR";
+ WRITE_CALL_LOG: "android.permission.WRITE_CALL_LOG";
+ WRITE_CONTACTS: "android.permission.WRITE_CONTACTS";
+ WRITE_EXTERNAL_STORAGE: "android.permission.WRITE_EXTERNAL_STORAGE";
+ WRITE_GSERVICES: "android.permission.WRITE_GSERVICES";
+ WRITE_HISTORY_BOOKMARKS: "com.android.browser.permission.WRITE_HISTORY_BOOKMARKS";
+ WRITE_PROFILE: "android.permission.WRITE_PROFILE";
+ WRITE_SECURE_SETTINGS: "android.permission.WRITE_SECURE_SETTINGS";
+ WRITE_SETTINGS: "android.permission.WRITE_SETTINGS";
+ WRITE_SMS: "android.permission.WRITE_SMS";
+ WRITE_SOCIAL_STREAM: "android.permission.WRITE_SOCIAL_STREAM";
+ WRITE_SYNC_SETTINGS: "android.permission.WRITE_SYNC_SETTINGS";
+ WRITE_USER_DICTIONARY: "android.permission.WRITE_USER_DICTIONARY";
+ WRITE_VOICEMAIL: "com.android.voicemail.permission.WRITE_VOICEMAIL";
+
+ checkPermission: (
+ permission: string,
+ successCallback: (status: PermissionStatus) => void,
+ errorCallback: () => void
+ ) => void;
+
+ requestPermission: (
+ permission: string,
+ successCallback: (status: PermissionStatus) => void,
+ errorCallback: () => void
+ ) => void;
+
+ requestPermissions: (
+ permissions: string[],
+ successCallback: (status: PermissionStatus) => void,
+ errorCallback: () => void
+ ) => void;
+
+ hasPermission: (
+ permission: string,
+ successCallback: (status: PermissionStatus) => void,
+ errorCallback: () => void
+ ) => void;
+}
+
+interface CordovaPlugins {
+ permissions: Permissions;
+}
\ No newline at end of file
diff --git a/node_modules/@types/noname-typings/cordova-plugin-device.d.ts b/node_modules/@types/noname-typings/cordova-plugin-device.d.ts
new file mode 100644
index 0000000000..7b6a2b5ba0
--- /dev/null
+++ b/node_modules/@types/noname-typings/cordova-plugin-device.d.ts
@@ -0,0 +1,35 @@
+// Type definitions for cordova-plugin-device
+// Project: https://github.com/apache/cordova-plugin-device
+// Definitions by: Microsoft Open Technologies Inc
+// Tim Brust
+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
+
+/**
+ * This plugin defines a global device object, which describes the device's hardware and software.
+ * Although the object is in the global scope, it is not available until after the deviceready event.
+ */
+interface Device {
+ /** Get the version of Cordova running on the device. */
+ cordova: string;
+ /** Indicates that Cordova initialize successfully. */
+ available: boolean;
+ /**
+ * The device.model returns the name of the device's model or product. The value is set
+ * by the device manufacturer and may be different across versions of the same product.
+ */
+ model: string;
+ /** Get the device's operating system name. */
+ platform: string;
+ /** Get the device's Universally Unique Identifier (UUID). */
+ uuid: string;
+ /** Get the operating system version. */
+ version: string;
+ /** Get the device's manufacturer. */
+ manufacturer: string;
+ /** Whether the device is running on a simulator. */
+ isVirtual: boolean;
+ /** Get the device hardware serial number. */
+ serial: string;
+}
+
+declare var device: Device;
\ No newline at end of file
diff --git a/node_modules/@types/noname-typings/index.d.ts b/node_modules/@types/noname-typings/index.d.ts
index 387ebd5ce6..c89de0bb47 100644
--- a/node_modules/@types/noname-typings/index.d.ts
+++ b/node_modules/@types/noname-typings/index.d.ts
@@ -9,6 +9,8 @@
///
///
///
+///
+///
///
///
///
diff --git a/node_modules/@types/noname-typings/windowEx.d.ts b/node_modules/@types/noname-typings/windowEx.d.ts
index fca9c3721b..f089f64781 100644
--- a/node_modules/@types/noname-typings/windowEx.d.ts
+++ b/node_modules/@types/noname-typings/windowEx.d.ts
@@ -70,4 +70,6 @@ declare interface Window {
initReadWriteFunction?(game: Game): Promise;
bannedKeyWords: string[];
+
+ device: Device;
}
diff --git a/noname/game/index.js b/noname/game/index.js
index 74b898be0d..002c12b422 100644
--- a/noname/game/index.js
+++ b/noname/game/index.js
@@ -7308,7 +7308,7 @@ export class Game {
for (let i = 0; i < event.config.size; i++) {
ui.window.appendChild(event.nodes[i]);
}
- ("step 1");
+ "step 1";
let rand1 = event.config.first;
if (rand1 == "rand") {
rand1 = Math.random() < 0.5;
@@ -7350,7 +7350,7 @@ export class Game {
}
game.delay();
lib.init.onfree();
- ("step 2");
+ "step 2";
if (event.checkredo()) return;
if (event._skiprest) return;
if (event.side < 2) {
@@ -7366,7 +7366,7 @@ export class Game {
event.aiMove();
game.delay();
}
- ("step 3");
+ "step 3";
if (typeof event.fast == "number" && get.time() - event.fast <= 1000) {
event.fast = true;
} else {
@@ -7401,7 +7401,7 @@ export class Game {
game.delay();
}
}
- ("step 4");
+ "step 4";
if (event.checkredo()) return;
if (event.skipnode) event.skipnode.delete();
if (event.replacenode) event.replacenode.delete();
@@ -7423,7 +7423,7 @@ export class Game {
}
}
game.delay();
- ("step 5");
+ "step 5";
event.prompt("选择" + get.cnNumber(event.config.num) + "名出场武将");
event.enemylist = [];
for (let i = 0; i < event.avatars.length; i++) {
@@ -7453,7 +7453,7 @@ export class Game {
event.nodes[i].hide();
}
game.pause();
- ("step 6");
+ "step 6";
event.promptbar.delete();
if (ui.cardPileButton) ui.cardPileButton.style.display = "";
lib.onresize.remove(event.resize);
diff --git a/noname/gnc/index.js b/noname/gnc/index.js
index 99460f6ca9..7cbdcebd99 100644
--- a/noname/gnc/index.js
+++ b/noname/gnc/index.js
@@ -8,45 +8,49 @@ export class GNC {
* @returns
*/
of(fn) {
- return this.is.generatorFunc(fn)
- ? /**
- * @param {Parameters} args
- * @returns {Promise>}
- */
- function genCoroutine(...args) {
- let gen = fn.apply(this, args);
- gen.status = "next";
- gen.state = undefined;
- const callback = (resolve, reject) => {
- let result,
- nexts = resolve,
- throws = reject;
- try {
- result = gen[gen.status](gen.state);
- } catch (error) {
- reject(error);
- return;
- }
- if (!result.done) {
- nexts = (item) => {
- gen.state = item;
- gen.status = "next";
- callback(resolve, reject);
- };
- throws = (err) => {
- gen.state = err;
- gen.status = "throw";
- callback(resolve, reject);
- };
- }
- result = result.value;
- Promise.resolve(result).then(nexts, throws);
+ /**
+ * @param {Parameters} args
+ * @returns {Promise>}
+ */
+ function genCoroutine(...args) {
+ /**
+ * @type {Generator & { status: "next" | "throw" , state?: any}}
+ */
+ // @ts-expect-error Must Ok
+ let gen = fn.apply(this, args);
+ gen.status = "next";
+ gen.state = undefined;
+ const callback = (resolve, reject) => {
+ let result,
+ nexts = resolve,
+ throws = reject;
+ try {
+ result = gen[gen.status](gen.state);
+ } catch (error) {
+ reject(error);
+ return;
+ }
+ if (!result.done) {
+ nexts = (item) => {
+ gen.state = item;
+ gen.status = "next";
+ callback(resolve, reject);
};
- return new Promise(callback);
- }
- : (() => {
- throw new TypeError("gnc.of needs a GeneratorFunction.");
- })();
+ throws = (err) => {
+ gen.state = err;
+ gen.status = "throw";
+ callback(resolve, reject);
+ };
+ }
+ result = result.value;
+ Promise.resolve(result).then(nexts, throws);
+ };
+ return new Promise(callback);
+ }
+
+ if (!this.is.generatorFunc(fn)) throw new TypeError("gnc.of needs a GeneratorFunction.");
+
+ return genCoroutine;
}
is = new Is();
}
diff --git a/noname/init/cordova.js b/noname/init/cordova.js
index 73e8904b28..da48c7f7e1 100644
--- a/noname/init/cordova.js
+++ b/noname/init/cordova.js
@@ -1,10 +1,10 @@
-// @ts-nocheck
import { get } from "../get/index.js";
import { lib } from "../library/index.js";
import { game } from "../game/index.js";
import { _status } from "../status/index.js";
import { ui } from "../ui/index.js";
import { nonameInitialized } from "../util/index.js";
+import { checkVersion } from "../library/update.js";
export async function cordovaReady() {
if (lib.device == "android") {
@@ -49,21 +49,33 @@ export async function cordovaReady() {
if ("cordova" in window && "plugins" in window.cordova && "permissions" in window.cordova.plugins) {
const permissions = cordova.plugins.permissions;
const requests = ["WRITE_EXTERNAL_STORAGE", "READ_EXTERNAL_STORAGE"];
- requests.forEach((request) => {
- permissions.checkPermission(
- permissions[request],
- (status) => {
- if (!status.hasPermission) {
- permissions.requestPermission(
- permissions[request],
- lib.other.ignore,
- lib.other.ignore
- );
- }
- },
+ if (typeof device == 'object') {
+ // 安卓13或以上
+ if (checkVersion(device.version, "13") >= 0) {
+ requests.length = 0;
+ requests.push('READ_MEDIA_IMAGES', 'READ_MEDIA_VIDEO', 'READ_MEDIA_AUDIO');
+ }
+ }
+ Promise.all(requests.map(request => {
+ return new Promise((resolve, reject) => {
+ permissions.checkPermission(permissions[request], status => {
+ resolve({
+ request: request,
+ hasPermission: status.hasPermission
+ });
+ }, reject);
+ });
+ })).then(shouldRequestPermissions => {
+ return shouldRequestPermissions
+ .filter(({ hasPermission }) => !hasPermission)
+ .map(({ request }) => permissions[request] || `android.permission.${request}`);
+ }).then(willRequestPermissions => {
+ permissions.requestPermissions(
+ willRequestPermissions,
+ lib.other.ignore,
lib.other.ignore
);
- });
+ }).catch(console.log);
}
}
game.download = function (url, folder, onsuccess, onerror, dev, onprogress) {
diff --git a/noname/library/element/content.js b/noname/library/element/content.js
index 7ed9cb15c0..0cd1bda8a0 100644
--- a/noname/library/element/content.js
+++ b/noname/library/element/content.js
@@ -5296,6 +5296,16 @@ export const Content = {
bool: true,
links: [],
};
+ } else if (event.autochoose()) {
+ event.result = {
+ bool: true,
+ autochoose: true,
+ cards: player.getCards(event.position),
+ confirm: "ok",
+ buttons: [],
+ targets: [],
+ links: [],
+ };
} else {
if (event.isMine()) {
game.check();
diff --git a/noname/library/element/player.js b/noname/library/element/player.js
index a032847db0..4212473106 100644
--- a/noname/library/element/player.js
+++ b/noname/library/element/player.js
@@ -4522,7 +4522,9 @@ export class Player extends HTMLDivElement {
next.autochoose = function () {
if (!this.forced) return false;
if (typeof this.selectCard == "function") return false;
+ if (this.complexCard || this.complexSelect || this.filterOk) return false;
var cards = this.player.getCards(this.position);
+ if (cards.some(card => !this.filterCard(card, this))) return false;
var num = cards.length;
for (var i = 0; i < cards.length; i++) {
if (!lib.filter.cardDiscardable(cards[i], this.player, this)) num--;
@@ -4776,6 +4778,14 @@ export class Player extends HTMLDivElement {
if (next.filterCard == undefined) next.filterCard = lib.filter.all;
if (next.selectCard == undefined) next.selectCard = [1, 1];
if (next.ai == undefined) next.ai = get.unuseful3;
+ next.autochoose = function () {
+ if (!this.forced) return false;
+ if (typeof this.selectCard == "function") return false;
+ if (this.complexCard || this.complexSelect || this.filterOk) return false;
+ var cards = this.player.getCards(this.position);
+ if (cards.some(card => !this.filterCard(card, this))) return false;
+ return get.select(this.selectCard)[0] >= this.player.countCards(this.position);
+ };
next.setContent("chooseCard");
next._args = Array.from(arguments);
return next;
diff --git a/noname/ui/create/menu/pages/exetensionMenu.js b/noname/ui/create/menu/pages/exetensionMenu.js
index 4d670eef61..df9bd3cb31 100644
--- a/noname/ui/create/menu/pages/exetensionMenu.js
+++ b/noname/ui/create/menu/pages/exetensionMenu.js
@@ -426,6 +426,13 @@ export const extensionMenu = function (connectMenu) {
'import { lib, game, ui, get, ai, _status } from "../../noname.js";\ngame.import("extension",function(){\n\treturn ' +
str +
"\n});",
+ "info.json": JSON.stringify({
+ name: page.currentExtension,
+ author: authorExtLine.querySelector("input").value || "",
+ diskURL: diskExtLine.querySelector("input").value || "",
+ forumURL: forumExtLine.querySelector("input").value || "",
+ version: versionExtLine.querySelector("input").value || ""
+ }),
};
for (var i in dash1.content.image) {
extension[i] = dash1.content.image[i];
diff --git a/noname/ui/create/menu/pages/otherMenu.js b/noname/ui/create/menu/pages/otherMenu.js
index a36c1c3238..627c44a8b5 100644
--- a/noname/ui/create/menu/pages/otherMenu.js
+++ b/noname/ui/create/menu/pages/otherMenu.js
@@ -349,7 +349,7 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM
}
}
const str =
- versionResult > 0
+ versionResult < 0
? `有新版本${description.name}可用,是否下载?`
: `本地版本${lib.version}高于或等于github版本${description.name},是否强制下载?`;
const str2 = description.body;
@@ -454,7 +454,7 @@ export const otherMenu = function (/** @type { boolean | undefined } */ connectM
const result = await asyncFilter(files.flat(), async v => {
return game.promises.readFile(v.path).then(data => {
return v.size != data.byteLength;
- })
+ }).catch(()=>true)
}).then(arr => arr.map((v) => v.path));
console.log("需要更新的文件有:", result);
diff --git a/prettier.config.mjs b/prettier.config.mjs
new file mode 100644
index 0000000000..e8760a4fde
--- /dev/null
+++ b/prettier.config.mjs
@@ -0,0 +1,13 @@
+/** @type {import("prettier").Config} */
+export default {
+ arrowParens: "always",
+ bracketSpacing: true,
+ endOfLine: "lf",
+ printWidth: 110,
+ proseWrap: "preserve",
+ quoteProps: "as-needed",
+ semi: true,
+ tabWidth: 4,
+ trailingComma: "es5",
+ useTabs: true,
+};