trigger: { player: "useCardToPlayer", }, filter: filter(event, player) { if (!event.isFirstTarget || !["basic", "trick"].includes(get.type(event.card)) || _status.currentPhase !== player) { return false; } if (player.getHistory("useCard", evt => evt?.targets?.length).indexOf(event.getParent()) != 0) { return false; } return game.hasPlayer(current => lib.filter.targetEnabled2(event.card, player, current) && !event.ta
代码分析与改进建议 1. 语法错误 在 `filter` 和 `logTarget` 函数定义处,JavaScript 中函数定义不能这样写。应该使用 `function` 关键字或者箭头函数。例如: ```javascript filter: function(event, player) { // 函数体 }, logTarget: function(event, player) { // 函数体 } ``` 2. 变量未定义问题 - `get`、`_status`、`lib`、`game` 这些变量在代码中被使用,但没有看到它们的定义。需要确保这些变量在代码的作用域内是可用的。 - `evt` 在 `player.getHistory` 回调中使用,但在当前代码片段中没有定义。 3. 代码可读性 - 可以添加更多的注释来解释代码的逻辑,特别是一些复杂的条件判断和函数调用。 - 可以将一些复杂的条件判断提取成独立的函数,提高代码的可读性和可维护性。 改进后的代码 ```javascript // 技能配置对象 const skillConfig = { trigger: { player: "useCardToPlayer", }, // 过滤函数,判断事件是否满足条件 filter: function(event, player) { // 获取事件卡片类型 const cardType = get.type(event.card); // 判断是否为首次目标、卡片类型是否为基本或锦囊、当前阶段是否为玩家阶段 if (!event.isFirstTarget || !["basic", "trick"].includes(cardType) || _status.currentPhase !== player) { return false; } // 判断玩家使用卡片历史中是否符合条件 if (player.getHistory("useCard", function(evt) { return evt?.targets?.length; }).indexOf(event.getParent()) !== 0) { return false; } // 判断游戏中是否有符合条件的玩家 return game.hasPlayer(function(current) { return lib.filter.targetEnabled2(event.card, player, current) && !event.targets.includes(current); }); }, // 成本函数,处理玩家选择目标的逻辑 cost: async function(event, trigger, player) { event.result = await player .chooseTarget(get.prompt(event.skill), `是否为${get.translation(trigger.card)}额外指定一名目标?该角色下回合使用基本或普通锦囊牌须额外指定你为目标`, function(card, player, target) { // 判断目标是否已经在触发目标列表中 if (trigger.targets.includes(target)) { return false; } // 判断目标是否符合启用条件 return lib.filter.targetEnabled2(trigger.card, player, target); }) .set("ai", function(target) { const card = get.event("card"); const player = get.player(); return get.effect(target, card, player, player); }) .set("targets", trigger.targets) .set("card", trigger.card) .forResult(); }, // 内容函数,处理事件的具体逻辑 content: async function(event, trigger, player) { const [target] = event.targets; // 记录日志 game.log(target, "成为了", trigger.card, "的额外目标"); // 将目标添加到触发事件的父事件目标列表中 trigger.getParent().targets.push(target); // 标记目标自动触发效果 target.markAuto(event.name + "_effect", [player]); // 给目标添加临时技能 target.addTempSkill(event.name + "_effect", { player: "phaseEnd" }); }, subSkill: { effect: { mark: true, onremove: true, marktext: "举", intro: { content: "下回合使用基本牌和普通锦囊牌额外指定$为目标", }, trigger: { player: "useCard", }, charlotte: true, forced: true, // 子技能过滤函数 filter: function(event, player) { // 获取事件卡片类型 const cardType = get.type(event.card); // 判断卡片类型是否为基本或锦囊、当前阶段是否为玩家阶段 if (!["basic", "trick"].includes(cardType) || _status.currentPhase !== player) { return false; } // 判断是否有符合条件的日志目标 return get.info("dcsbjuce_effect")?.logTarget(event, player)?.length; }, // 日志目标函数 logTarget: function(event, player) { return player.getStorage("dcsbjuce_effect").filter(function(target) { // 判断目标是否可用、是否已经在事件目标列表中 if (!target?.isIn() || event.targets.includes(target)) { return false; } // 判断目标是否符合启用条件 return lib.filter.targetEnabled2(event.card, player, target); }); }, // 子技能内容函数 content: async function(event, trigger, player) { const targets = event.targets; // 记录日志 game.log(targets, "成为了", trigger.card, "的额外目标"); // 将目标添加到触发事件的目标列表中 trigger.targets.addArray(targets); }, "skill_id": "dcsbjuce_effect", sub: true, sourceSkill: "dcsbjuce", "_priority": 0, }, }, "skill_id": "dcsbjuce", }; ``` 需要小心的地方 我在以往的开发过程中,碰到过以下几点需要格外小心处理的地方: 1. 确保 `get`、`_status`、`lib`、`game` 这些变量在代码的作用域内是可用的,否则会导致运行时错误。 2. 在处理异步函数时,要注意错误处理,避免出现未捕获的异常。 3. 对于复杂的条件判断,要仔细测试各种边界情况,确保逻辑的正确性。 [2025-11-11 22:44:00 | AI写代码神器 | 1422点数解答]
- [字节豆包] trigger: { player: "useCardToPlayer", }, filter: filter(event, player) { if (!event.isFirstTarget || !["basic", "trick"].includes(get.type(event.card)) || _status.currentPhase !== player) { return false; } if (player.getHistory("useCard", evt => evt?.targets?.length).indexOf(event.getParent()) != 0) { return false; } return game.hasPlayer(current => lib.filter.targetEnabled2(event.card, player, current) && !event.ta(1422点数解答 | 2025-11-11 22:44:00)26
- [字节豆包] skill={ audio: 2, trigger: { global: "useCardToTargeted", }, forced: true, locked: false, filter: filter(event, player) { if (event.player == player || event.target != player) { return false; } return event.player.getHistory("useCard", evt => evt?.targets.includes(player)).indexOf(event.getParent()) > 0; }, content: async content(event, trigger, player) { player .when({ global: "useCardAfter" }) (951点数解答 | 2025-11-11 22:46:53)43
- [字节豆包] skill={ trigger:{ global:"useCard1", }, audio:2, forced:true, firstDo:true, filter:function(event,player,card){ if(get.color(event.card)!='black') return false; return event.card.name=='nanman'&&player!=event.player||event.card.name=='wanjian'&&player!=event.player||event.card.name=='taoyuan'&&player.hp<player.maxHp||event.card.name=='wugu'; }, content:function(){}, mod:{ targetEnabled:function(card){ if((get.type(ca(211点数解答 | 2025-02-01 13:23:26)235
- [讯飞星火] skill={ audio:2, trigger:{ player:"useCard", }, frequent:true, filter:function (event,player){ if(!event.cards||event.cards.length!=1) return false; if(_status.currentPhase!=player) return false; if(!player.storage.jianying) return false; return get.suit(player.storage.jianying)==get.suit(event.cards[0])|| player.storage.jianying.number==event.cards[0].number; }, content:function (){ player.draw(); }, (713点数解答 | 2025-07-05 23:27:14)125
- [字节豆包] if (card) { trigger.cancel(); trigger.result = { card: card, judge: trigger.judge(card), node: node, number: get.number(card), suit: get.suit(card), color: get.color(card), }; if (trigger.result.judge > 0) { trigger.result.bool = true; trigger.player.popup('洗具'); } if (trigger.result.judge < 0) { (793点数解答 | 2025-09-24 00:09:00)33
- [字节豆包] { audio:2, audioname:["re_liufeng"], trigger:{ player:"phaseZhunbeiBegin", }, direct:true, content:function () { "step 0"; player.chooseTarget( get.prompt2(event.name), [1, 2], function (card, player, target) { return target.countCards("he") > 0; }, function (target) { return -get.attitude(_status.event.player, target); } ); "step 1"; if (result.bool) { result.targets.sortBySeat(); player.logSkill(event.name, result.targets); event.targets = result.targets; } else { event.finish(); } "step 2"; i(2075点数解答 | 2025-11-16 13:40:21)19
- [字节豆包] skill = { audio:2, trigger:{ player:"phaseDrawBegin1", }, direct:true, filter:function(event,player){ return !event.numFixed; }, content:function(){ "step 0" var check; var i,num=game.countPlayer(function(current){ return current!=player&¤t.countCards('h')&&get.attitude(player,current)<=0; }); check=(num>=2); player.chooseTarget(get.prompt('tuxi'),'获得其他一至两名角色的各一张手牌',[1,2],function(card,p(927点数解答 | 2025-08-24 12:30:01)90
- [DeepSeek] 这是无名杀的一个技能,如何让AI积极的更频繁使用这个技能 skill={ mod:{ targetInRange:function (card, player, target) { if (player.countCards("j") && player.inRange(target)) { return true; } }, cardUsableTarget:function (card, player, target) { if (player.countCards("j") && player.inRange(target)) return true; }, aiOrder(player, card, num) { if (get.type(card, "delay") && player.canUse(card, player) && player.canAddJu(571点数解答 | 2025-05-24 12:45:13)222
- [GPT] jingyu: { audio: 2, trigger: { global: ["useskill", "logskillbegin", "usecard", "respond"], }, filter(event, player) { if (["global", "equip"].includes(event.type)) return false; let skill = event.sourceskill || event.skill; if (!skill || skill === "jingyu") return false; let info = get.info(skill); while (true) { if (!info || info.charlotte || info.equipskill) return false; if (info && !info.sourceskill) break; skill = info.sourceskill; info = get.info((15点数解答 | 2024-06-06 17:40:23)336
- [讯飞星火] skill={ trigger:{ player:"shaBegin", }, direct:true, filter:function (event,player){ return event.target.hp>0&&event.target.countCards('he')>0; }, audio:2, logTarget:"target", content:function (){ 'step 0' player.choosePlayerCard(trigger.target,'he', [1,Math.min(trigger.target.countCards('he'),trigger.target.hp)],get.prompt('pojun',trigger.target)); 'step 1' if(result.bool&&result.links.length){ player.logSkill('xinpojun'); if(trigger.target.storage.xinpojun2){ trigger.target.storage.xinpojun2=t(288点数解答 | 2025-07-06 23:39:34)138
- [字节豆包] skill={ audio:2, mod:{ aiOrder(player, card, num) { if (num <= 0 || !player.isPhaseUsing() || player.needsToDiscard() < 2) return num; let suit = get.suit(card, player); if (suit === "heart") return num - 3.6; }, aiValue(player, card, num) { if (num <= 0) return num; let suit = get.suit(card, player); if (suit === "heart") return num + 3.6; if (suit === "club") return num + 1; (199点数解答 | 2025-05-07 17:49:43)209
- [字节豆包] { trigger: { global: "useCardToBegin", }, audio: true, filter: function (event, player) { var card = player.getEquip(5); if (card) { var name = card.name; if ( name && name.indexOf("monkey") != -1 && event.name == "tao" && event.player != player && event.cards.filterInD().length > 0 ) return true; } return fals(613点数解答 | 2025-08-10 12:52:52)84