无名杀吧 关注:64,022贴子:287,348
  • 8回复贴,共1

交换特定装备栏或判定区的技能思路: 改自swapEquip和moveCard

只看楼主收藏回复

之前询问小吧说没有此类函数说我可以写一个. 我想对各位大佬来说应该不在话下, 我在此班门弄斧根据现有游戏内函数进行解读并参考写成技能给各位想做类似效果的提供一个思路.
另外就是我不知道能不能编写那些可调用的函数, 所以我就直接以技能形式呈现了. 然后本帖无关发动的filter判断, 只是讨论具体效果的实现思路. 码字带整理思路可能较慢, 见谅.


IP属地:上海1楼2023-03-29 01:15回复
    我想下文顺序应该会是
    swapEquip的代码解读
    交换单项装备栏思路
    moveCard的代码解读
    交换判定区的思路


    IP属地:上海2楼2023-03-29 01:16
    回复
      首先是交换特定装备栏, 参考吴国太的甘露我们会发现其实现效果的核心内容是swapEquip函数. 我们打开game.js找到swapEquip的代码:

      上边step 0基本是判断废除栏位的还有打log, 我们直接看step 1开始
      基本思路大概就是 先用一个变量将双方的装备卡记录下来做成二维数组, 然后用lose先把这两位角色的装备牌全部"失去", 然后$give我认为应该是不起实际作用的, 只是做了个动画效果. 最后根据双方记录的装备的数量用for给对方一个一个装备上. 也就是说实际上就是 失去装备->对方装备刚才你失去的装备, 中间再插个动画.
      那么作为简化的交换装备区, 交换装备栏直接把它for去掉就行了, 判断双方该栏位有卡, 然后将这1到两张记录在一个变量里, 然后lose, $give, equip就好了


      IP属地:上海3楼2023-03-29 01:25
      回复
        然后判定区就比较麻烦, 因为不像装备区直接equip, 判定牌是有"视为"的情况的. 我们参考一下目前能对判定卡进行移动的moveCard函数代码...
        啊不好意思140行 我们同样直接撇去一些判断, 直接去找实现的核心代码:

        之前的step概述: 0 选定移动目标(加判断目标是否可移动卡)设定AI设定prompt等等等等; 1 判断是否选了目标 然后line效果; 2 game.delay(); 3 选择移动的牌
        这里我们注意到对判定区有用的两个信息: 1. 移动判定牌依然是用addJudge再贴上去的; 2. 判断"视为"的牌的方法
        这里的link就是上一步玩家选定的移动牌, 也就是说里边的信息就是卡, 然后该卡可能附带信息viewAs, 这就是视为牌的核心. 然后addJudge({name:})这里直接调用了原卡牌"视为"信息link.viewAs.
        但是我们想要交换判定区跟只移动一张判定牌是不一样的, 移动判定牌会检测比如说双方都有乐那么乐就无法移动. 所以我们交换判定区首先思路上要跟上边交换装备栏类似, 双方失去->对方添加判定. 但是我怕失去以后的牌不再自带viewAs属性, 我决定额外做两个变量以单独储存卡牌的viewAs信息, 思路如下:

        对每个target进行一次:
        for遍历所有判定卡->判断该卡是否有viewAs->将该卡的viewAs信息push进某个变量中, 同时将该卡的位置信息(也就是for里的i)push进另一个位置变量中. 这样能保证该卡位置变量跟视为信息变量的位置一一对应.
        然后给对方addJudge时再for一次, 然后判断位置变量中是否contains这个位置(i), 如果contain则找到这个i在位置变量中的位置(使用函数indexOf), 在同位置找到该卡的viewAs信息放到上述addJudge函数{name:}里. 如果位置变量里不包含这个i那么直接addJudge这张卡就好(这张卡非转化).
        最后需要注意的一点: 三国杀的判定有个特性是后添加先判, 也就是说好像它addJudge是往数组头部添加的. 那么用于addJudge的for需要反过来写: for(var i=event.cards.length-1;i>=0;i--) 这样才能保证添加的判定牌顺序是和原角色完全一样.


        IP属地:上海4楼2023-03-29 01:49
        回复
          最后分享一下一边写一边做测试的交换判定区原型技能, 交换装备栏的比较简单就不放了:
          skill={
          enable:"phaseUse",
          selectTarget:2,
          filterTarget:function(card,player,target){
          if(target.isMin()) return false;
          if(ui.selected.targets.length==0) return true;
          if(ui.selected.targets[0].countCards('j')==0&&target.countCards('j')==0) return false;
          return true;
          },
          prompt:"请选择两名角色以交换判定区",
          multitarget:true,
          content:function(){
          if(targets[0].countCards('j')!=0&&targets[1].countCards('j')!=0){
          event.cards=[targets[0].getCards('j'),targets[1].getCards('j')];
          event.vAname0=[];
          event.vAname1=[]
          event.pos0=[];
          event.pos1=[];
          for(var i=0;i<event.cards[0].length;i++){
          if(event.cards[0][i].viewAs){
          event.vAname0.push(event.cards[0][i].viewAs);
          event.pos0.push(i);
          }
          }
          for(var i=0;i<event.cards[1].length;i++){
          if(event.cards[1][i].viewAs){
          event.vAname1.push(event.cards[1][i].viewAs);
          event.pos1.push(i);
          }
          }
          targets[0].lose(event.cards[0],ui.ordering,'visible');
          targets[1].lose(event.cards[1],ui.ordering,'visible');
          targets[0].$give(event.cards[0],targets[1],false);
          targets[1].$give(event.cards[1],targets[0],false);
          for(var i=event.cards[0].length-1;i>=0;i--){
          if(event.pos0.contains(i)){
          var pos=event.pos0.indexOf(i);
          event.targets[1].addJudge({name:event.vAname0[pos]},[event.cards[0][i]]);
          }
          else event.targets[1].addJudge(event.cards[0][i]);
          }
          for(var i=event.cards[1].length-1;i>=0;i--){
          if(event.pos1.contains(i)){
          var pos=event.pos1.indexOf(i);
          event.targets[0].addJudge({name:event.vAname1[pos]},[event.cards[1][i]]);
          }
          else event.targets[0].addJudge(event.cards[1][i]);
          }
          }
          else if(targets[0].countCards('j')==0){
          event.cards=targets[1].getCards('j');
          event.vAname=[];
          event.position=[];
          for(var i=0;i<event.cards.length;i++){
          if(event.cards[i].viewAs){
          event.vAname.push(event.cards[i].viewAs);
          event.position.push(i);
          }
          }
          targets[1].lose(event.cards,ui.ordering,'visible');
          targets[1].$give(event.cards,targets[0],false);
          for(var i=event.cards.length-1;i>=0;i--){
          if(event.position.contains(i)){
          var pos=event.position.indexOf(i);
          event.targets[0].addJudge({name:event.vAname[pos]},[event.cards[i]]);
          }
          else event.targets[0].addJudge(event.cards[i]);
          }
          }
          else{
          event.cards=targets[0].getCards('j');
          event.vAname=[];
          event.position=[];
          for(var i=0;i<event.cards.length;i++){
          if(event.cards[i].viewAs){
          event.vAname.push(event.cards[i].viewAs);
          event.position.push(i);
          }
          }
          targets[0].lose(event.cards,ui.ordering,'visible');
          targets[0].$give(event.cards,targets[1],false);
          for(var i=event.cards.length-1;i>=0;i--){
          if(event.position.contains(i)){
          var pos=event.position.indexOf(i);
          event.targets[1].addJudge({name:event.vAname[pos]},[event.cards[i]]);
          }
          else event.targets[1].addJudge(event.cards[i]);
          }
          }
          },
          }


          IP属地:上海5楼2023-03-29 01:51
          回复
            以上是我的思路, 是第一时间想到思路就直接去实现的, 应该还有很大简化和优化空间, 也没有判断废除判定区的情况, 仅供各位参考


            IP属地:上海6楼2023-03-29 01:53
            回复
              谢谢大佬,九级老吧友雨幽在此希望能学会无名杀代码(但是保住头发)


              IP属地:福建来自Android客户端7楼2023-03-29 03:57
              回复
                如果是遇到张秀废除判定区之类的 还能交换吗


                IP属地:贵州来自Android客户端8楼2023-03-29 14:32
                收起回复