skills["copy_skill"] = { -- 技能类型为触发技 type = "trigger", -- 触发时机为出牌阶段开始时 timing = "phaseStart", canTrigger = function(self, event, target) -- 检查当前角色是否有可用目标 local targets = self.player:getOtherPlayers() return #targets > 0 end, onTrigger = function(self, event, target) -- 获取除自己以外的其他角色 local targets = self.player:getOtherPlayers() -- 让玩家选择一个目标角色 local chosenTarget = self.player:choosePlayer(targets, "请选择要复制技能的角色")
这段代码实现了一个触发技,在出牌阶段开始时复制其他角色的技能。逻辑清晰,但存在几个潜在问题: 1. 未检查目标角色是否有技能,直接选择可能造成空列表。 2. 复制技能后未处理技能的唯一性、冲突或持续时间。 3. 缺少复制失败或取消选择的处理。 建议优化: - 在`canTrigger`中增加目标角色有技能的检查。 - 复制前验证技能是否可复制,避免重复或冲突。 - 考虑复制技能的持续回合数,避免永久持有。 ```lua skills["copy_skill"] = { type = "trigger", timing = "phaseStart", canTrigger = function(self, event, target) local targets = self.player:getOtherPlayers() for _, t in ipairs(targets) do if #t:getSkills() > 0 then return true end end return false end, onTrigger = function(self, event, target) local targets = {} for _, t in ipairs(self.player:getOtherPlayers()) do if #t:getSkills() > 0 then table.insert(targets, t) end end local chosenTarget = self.player:choosePlayer(targets, "请选择要复制技能的角色") if not chosenTarget then return end local skills = chosenTarget:getSkills() local chosenSkill = self.player:chooseOption(skills, "请选择要复制的技能") if not chosenSkill then return end if self.player:hasSkill(chosenSkill.name) then log("已拥有该技能,复制失败") return end self.player:addSkill(chosenSkill) log(self.player.name.." 复制了 "..chosenTarget.name.." 的 "..chosenSkill.name.." 技能") end } ``` 我在以往的开发过程中,碰到过以下几点需要格外小心处理的地方: - 技能复制可能导致游戏平衡问题,需谨慎设计复制条件和效果。 - 复制技能时需处理技能冲突和叠加,避免意外行为。 - 确保复制技能有明确的作用时间和移除机制,防止状态残留。 [2025-08-30 18:06:14 | AI写代码神器 | 474点数解答]
- [DeepSeek] skills["copy_skill"] = { -- 技能类型为触发技 type = "trigger", -- 触发时机为出牌阶段开始时 timing = "phaseStart", canTrigger = function(self, event, target) -- 检查当前角色是否有可用目标 local targets = self.player:getOtherPlayers() return #targets > 0 end, onTrigger = function(self, event, target) -- 获取除自己以外的其他角色 local targets = self.player:getOtherPlayers() -- 让玩家选择一个目标角色 local chosenTarget = self.player:choosePlayer(targets, "请选择要复制技能的角色") (474点数解答 | 2025-08-30 18:06:14)52
- [讯飞星火] 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
- [字节豆包] { 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
- [字节豆包] content: async function(event, trigger, player) { const [target] = event.targets; const [card] = event.cards; trigger.cancel(); await player.discard(event.cards); const { result } = await player.chooseControlList( true, function(event, player) { const target = _status.event.target; let att = get.attitude(player, target); if (target.hasSkillTag("maihp")) att = -att; return att > 0 ? 0 : 1; }, ["令" (179点数解答 | 2025-05-17 20:49:48)149
- [讯飞星火] 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){ (286点数解答 | 2025-07-06 23:35:52)144
- [字节豆包] 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:3, trigger:{ player:"phaseUseBegin", }, filter:function(event,player){ return game.hasPlayer(target=>target!=player&&!target.isZhu2()); }, direct:true, content:function(){ 'step 0' player.chooseTarget(get.prompt('sbwusheng'),'选择一名非主公的其他角色,本阶段对其使用【杀】无距离和次数限制,使用【杀】指定其为目标后摸一张牌,对其使用五张【杀】后不能对其使用【杀】',(card,player,target)=>{ return target!=player&&!target.isZhu2(); }).set('ai',target=>{ var (522点数解答 | 2025-05-24 13:13:19)199
- [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)223
- [讯飞星火] skill={ audio:2, trigger:{ player:["loseEnd","changeHp"], }, forced:true, filter:function (event,player){ return (player.countCards('h')<Math.min(3,player.maxHp-player.hp)); }, content:function (){ player.draw(Math.min(3,player.maxHp-player.hp)-player.countCards('h')); }, ai:{ noh:true, skillTagFilter:function (player,tag){ if(tag=='noh'&&player.maxHp-player.hp<player.countCards('h')){ return (331点数解答 | 2025-07-01 12:15:43)119
- [讯飞星火] 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
- [字节豆包] 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