From ecc1179069ea9a2eda6ef6a8bfada42ead5e58ad Mon Sep 17 00:00:00 2001 From: 157 <3619242020@qq.com> Date: Sat, 16 Mar 2024 22:19:55 +0800 Subject: [PATCH 1/5] bugfix --- character/huicui.js | 9 ++++++--- character/sp.js | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/character/huicui.js b/character/huicui.js index c2db9e267..085fea268 100644 --- a/character/huicui.js +++ b/character/huicui.js @@ -9901,7 +9901,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(th>0){ event.num=Math.ceil(th/2); var list=[ - '本回合不能使用或打出手牌,然后'+str+'摸两张牌', + '本回合不能使用手牌,然后'+str+'摸两张牌', '展示所有手牌,并将其中一种花色的所有牌交给'+str, '弃置'+get.cnNumber(event.num)+'张手牌', ]; @@ -9944,10 +9944,13 @@ game.import('character',function(lib,game,ui,get,ai,_status){ subSkill:{ block:{ mark:true, - intro:{content:'不能使用或打出手牌'}, + intro:{content:'不能使用手牌'}, charlotte:true, mod:{ - cardEnabled2:function(card){ + cardEnabled:function(card){ + if(get.position(card)=='h') return false; + }, + cardSavable:function(card){ if(get.position(card)=='h') return false; }, }, diff --git a/character/sp.js b/character/sp.js index a3303d4a9..2aa6f6358 100755 --- a/character/sp.js +++ b/character/sp.js @@ -18230,6 +18230,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return get.info('ollongdan').ai.skillTagFilter(player,tag); }, order:function(item,player){ + if(!player||!player.storage) return; const awakened=Object.keys(player.storage).some(i=>typeof i=='string'&&i.indexOf('fuhan')!=-1); if(player&&_status.event.type=='phase'){ var max=0; From 8360f72c1ed8770afa7182d343cdaf4d5eabd7b0 Mon Sep 17 00:00:00 2001 From: 157 <3619242020@qq.com> Date: Sun, 17 Mar 2024 11:56:32 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E4=BC=98=E5=8C=96=E3=80=90=E6=9D=80?= =?UTF-8?q?=E3=80=91=E3=80=90=E5=8D=97=E8=9B=AE=E5=85=A5=E4=BE=B5=E3=80=91?= =?UTF-8?q?=E3=80=90=E4=B8=87=E7=AE=AD=E9=BD=90=E5=8F=91=E3=80=91=E3=80=90?= =?UTF-8?q?=E7=81=AB=E6=94=BB=E3=80=91=E3=80=90=E4=BB=A5=E9=80=B8=E5=BE=85?= =?UTF-8?q?=E5=8A=B3=E3=80=91ai?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- card/extra.js | 4 +- card/guozhan.js | 50 +++--- card/standard.js | 417 ++++++++++++++++++++++++++++++++++++++--------- character/sp.js | 12 +- 4 files changed, 378 insertions(+), 105 deletions(-) diff --git a/card/extra.js b/card/extra.js index e3dc67ed2..df068778b 100644 --- a/card/extra.js +++ b/card/extra.js @@ -229,9 +229,9 @@ game.import('card',function(lib,game,ui,get,ai,_status){ }, ai:{ basic:{ - order:4, + order:9.2, value:[3,1], - useful:1, + useful:0.6, }, wuxie:function(target,card,player,viewer,status){ if(get.attitude(viewer,player._trueMe||player)>0) return 0; diff --git a/card/guozhan.js b/card/guozhan.js index 3e5ad1a4f..86780a879 100644 --- a/card/guozhan.js +++ b/card/guozhan.js @@ -1095,30 +1095,42 @@ game.import('card',function(lib,game,ui,get,ai,_status){ target.chooseToDiscard(2,'he',true).ai=get.disvalue; }, ai:{ - wuxie:function(){ + wuxie: function () { return 0; }, - basic:{ - useful:3, - value:3, - order:5 + basic: { + order: 9, + useful: 1.5, + value: 3 }, - result:{ - target:function(player,target){ - var hs=target.getCards('h'); - if(hs.length<=1){ - if(target==player&&(hs.length==0||hs[0].name=='yiyi')){ - return 0; + result: { + target(player, target) { + let i, + add = 0, + y = 1, + tars = 0; + if (!ui.selected.cards) y = 0; + if (ui.selected.targets) tars = 0.01 * ui.selected.targets.length; + else tars = 0; + if (target == player) i = player.countCards('h', function (card) { + if (y > 0 && ui.selected.cards.includes(card)) return false; + if (!y && get.name(card) === 'yiyi') { + y = -1; + return false; } - return 0.3; - } - return Math.sqrt(target.countCards('he')); - }, + return true; + }); + else i = target.countCards('he'); + if (target.hasSkillTag('noh')) add++; + return add + Math.sqrt(i / 3.6 + tars) / 2; + } }, - tag:{ - loseCard:1, - discard:1, - norepeat:1 + tag: { + draw: 2, + loseCard: 2, + discard: 2, + multitarget: true, + norepeat: 1 } }, }, diff --git a/card/standard.js b/card/standard.js index 26c4a68ac..6c6e26e84 100644 --- a/card/standard.js +++ b/card/standard.js @@ -272,17 +272,17 @@ game.import('card',function(lib,game,ui,get,ai,_status){ useful:[5,3,1], value:[5,3,1], }, - order:function(item,player){ - if(player.hasSkillTag('presha',true,null,true)) return 10; - if(typeof item==='object'&&game.hasNature(item,'linked')){ - if(game.hasPlayer(function(current){ - return current!=player&&lib.card.sha.ai.canLink(player,current,item)&&player.canUse(item,current,null,true)&&get.effect(current,item,player,player)>0; - })&&game.countPlayer(function(current){ - return current.isLinked()&&get.damageEffect(current,player,player,get.nature(item))>0; - })>1) return 3.1; - return 3; - } - return 3.05; + order(item, player) { + let res = 3.2; + if (player.hasSkillTag('presha', true, null, true)) res = 10; + if (typeof item !== 'object' || !game.hasNature(item, 'linked') || game.countPlayer(cur => cur.isLinked()) < 2) return res; + //let used = player.getCardUsable('sha') - 1.5, natures = ['thunder', 'fire', 'ice', 'kami']; + let uv = player.getUseValue(item, true); + if (uv <= 0) return res; + let temp = player.getUseValue('sha', true) - uv; + if (temp < 0) return res + 0.15; + if (temp > 0) return res - 0.15; + return res; }, result:{ target:function(player,target,card,isLink){ @@ -995,43 +995,171 @@ game.import('card',function(lib,game,ui,get,ai,_status){ } }, ai:{ - wuxie:function(target,card,player,viewer){ - if(get.attitude(viewer,target)>0&&target.countCards('h','sha')){ - if(!target.countCards('h')||target.hp==1||Math.random()<0.7) return 0; + wuxie(target, card, player, viewer, status) { + let att = get.attitude(viewer, target), eff = get.effect(target, card, player, target); + if (Math.abs(att) < 1 || status * eff * att >= 0) return 0; + let evt = _status.event.getParent('useCard'), pri = 1, bonus = player.hasSkillTag('damageBonus', true, { + target: target, + card: card + }), damage = 1, isZhu = function (tar) { + return tar.isZhu || tar === game.boss || tar === game.trueZhu || tar === game.falseZhu; + }, canSha = function (tar, blur) { + let known = tar.getKnownCards(viewer); + if (!blur) return known.some(card => { + let name = get.name(card, tar); + return (name === 'sha' || name === 'hufu' || name === 'yuchanqian') && lib.filter.cardRespondable(card, tar); + }); + if (tar.countCards('hs', i => !known.includes(i)) > 4.67 - 2 * tar.hp / tar.maxHp) return true; + if (!tar.hasSkillTag('respondSha', true, 'respond', true)) return false; + if (tar.hp <= damage) return false; + if (tar.hp <= damage + 1) return isZhu(tar); + return true; + }, self = false; + if (canSha(target)) return 0; + if (bonus && !viewer.hasSkillTag('filterDamage', null, { + player: player, + card: card + })) damage = 2; + if ((viewer.hp <= damage || viewer.hp <= damage + 1 && isZhu(viewer)) && !canSha(viewer)) { + if (viewer === target) return status; + let fv = true; + if (evt && evt.targets) for (let i of evt.targets) { + if (fv) { + if (target === i) fv = false; + continue; + } + if (viewer == i) { + if (isZhu(viewer)) return 0; + self = true; + break; + } + } + } + let maySha = canSha(target, true); + if (bonus && !target.hasSkillTag('filterDamage', null, { + player: player, + card: card + })) damage = 2; + else damage = 1; + if (isZhu(target)) { + if (eff < 0) { + if (target.hp <= damage + 1 || !maySha && target.hp <= damage + 2) return 1; + if (maySha && target.hp > damage + 2) return 0; + else if (maySha || target.hp > damage + 2) pri = 3; + else pri = 4; + } + else if (target.hp > damage + 1) pri = 2; + else return 0; + } + else if (self) return 0; + else if (eff < 0) { + if (!maySha && target.hp <= damage) pri = 5; + else if (maySha) return 0; + else if (target.hp > damage + 1) pri = 2; + else if (target.hp === damage + 1) pri = 3; + else pri = 4; + } + else if (target.hp <= damage) return 0; + let find = false; + if (evt && evt.targets) for (let i = 0; i < evt.targets.length; i++) { + if (!find) { + if (evt.targets[i] === target) find = true; + continue; + } + let att1 = get.attitude(viewer, evt.targets[i]), eff1 = get.effect(evt.targets[i], card, player, evt.targets[i]), temp = 1; + if (Math.abs(att1) < 1 || att1 * eff1 >= 0 || canSha(evt.targets[i])) continue; + maySha = canSha(evt.targets[i], true); + if (bonus && !evt.targets[i].hasSkillTag('filterDamage', null, { + player: player, + card: card + })) damage = 2; + else damage = 1; + if (isZhu(evt.targets[i])) { + if (eff1 < 0) { + if (evt.targets[i].hp <= damage + 1 || !maySha && evt.targets[i].hp <= damage + 2) return 0; + if (maySha && evt.targets[i].hp > damage + 2) continue; + if (maySha || evt.targets[i].hp > damage + 2) temp = 3; + else temp = 4; + } + else if (evt.targets[i].hp > damage + 1) temp = 2; + else continue; + } + else if (eff1 < 0) { + if (!maySha && evt.targets[i].hp <= damage) temp = 5; + else if (maySha) continue; + else if (evt.targets[i].hp > damage + 1) temp = 2; + else if (evt.targets[i].hp === damage + 1) temp = 3; + else temp = 4; + } + else if (evt.targets[i].hp > damage + 1) temp = 2; + if (temp > pri) return 0; + } + return 1; + }, + basic: { + order: 9, + useful: [5, 1], + value: 5 + }, + result: { + player(player, target) { + if (player._nanman_temp || player.hasSkillTag('jueqing', false, target)) return 0; + player._nanman_temp = true; + let eff = get.effect(target, new lib.element.VCard({ name: 'nanman' }), player, target); + delete player._nanman_temp; + if (eff >= 0) return 0; + if (target.hp > 2 || target.hp > 1 && !target.isZhu && target != game.boss && target != game.trueZhu && target != game.falseZhu) return 0; + if (target.hp > 1 && target.hasSkillTag('respondSha', true, 'respond', true)) return 0; + let known = target.getKnownCards(player); + if (known.some(card => { + let name = get.name(card, target); + if (name === 'sha' || name === 'hufu' || name === 'yuchanqian') return lib.filter.cardRespondable(card, target); + if (name === 'wuxie') return lib.filter.cardEnabled(card, target, 'forceEnable'); + })) return 0; + if (target.hp > 1 || target.countCards('hs', i => !known.includes(i)) > 4.67 - 2 * target.hp / target.maxHp) return 0; + let res = 0, att = get.sgnAttitude(player, target); + res -= att * (0.8 * target.countCards('hs') + 0.6 * target.countCards('e') + 3.6); + if (get.mode() === 'identity' && target.identity === 'fan') res += 2.4; + if (get.mode() === 'guozhan' && player.identity !== 'ye' && player.identity === target.identity || + get.mode() === 'identity' && player.identity === 'zhu' && (target.identity === 'zhong' || target.identity === 'mingzhong')) res -= 0.8 * player.countCards('he'); + return res; + }, + target(player, target) { + let zhu = (get.mode() === 'identity' && target.isZhu) || target.identity === 'zhu'; + if (!lib.filter.cardRespondable({ name: 'sha' }, target)) { + if (zhu) { + if (target.hp < 2) return -99; + if (target.hp === 2) return -3.6; + } + return -2; + } + let known = target.getKnownCards(player); + if (known.some(card => { + let name = get.name(card, target); + if (name === 'sha' || name === 'hufu' || name === 'yuchanqian') return lib.filter.cardRespondable(card, target); + if (name === 'wuxie') return lib.filter.cardEnabled(card, target, 'forceEnable'); + })) return -1.2; + let nh = target.countCards('hs', i => !known.includes(i)); + if (zhu && target.hp <= 1) { + if (nh === 0) return -99; + if (nh === 1) return -60; + if (nh === 2) return -36; + if (nh === 3) return -12; + if (nh === 4) return -8; + return -5; + } + if (target.hasSkillTag('respondSha', true, 'respond', true)) return -1.35; + if (!nh) return -2; + if (nh === 1) return -1.8; + return -1.5; } }, - basic:{ - order:9, - useful:[5,1], - value:5 - }, - result:{ - target_use:function(player,target){ - if(player.hasUnknown(2)&&get.mode()!='guozhan') return 0; - var nh=target.countCards('h'); - if(get.mode()=='identity'){ - if(target.isZhu&&nh<=2&&target.hp<=1) return -100; - } - if(nh==0) return -2; - if(nh==1) return -1.7 - return -1.5; - }, - target:function(player,target){ - var nh=target.countCards('h'); - if(get.mode()=='identity'){ - if(target.isZhu&&nh<=2&&target.hp<=1) return -100; - } - if(nh==0) return -2; - if(nh==1) return -1.7 - return -1.5; - }, - }, - tag:{ - respond:1, - respondSha:1, - damage:1, - multitarget:1, - multineg:1, + tag: { + respond: 1, + respondSha: 1, + damage: 1, + multitarget: 1, + multineg: 1 } } }, @@ -1079,43 +1207,170 @@ game.import('card',function(lib,game,ui,get,ai,_status){ } }, ai:{ - wuxie:function(target,card,player,viewer){ - if(get.attitude(viewer,target)>0&&target.countCards('h','shan')){ - if(!target.countCards('h')||target.hp==1||Math.random()<0.7) return 0; + wuxie(target, card, player, viewer, status) { + let att = get.attitude(viewer, target), eff = get.effect(target, card, player, target); + if (Math.abs(att) < 1 || status * eff * att >= 0) return 0; + let evt = _status.event.getParent('useCard'), pri = 1, bonus = player.hasSkillTag('damageBonus', true, { + target: target, + card: card + }), damage = 1, isZhu = function (tar) { + return tar.isZhu || tar === game.boss || tar === game.trueZhu || tar === game.falseZhu; + }, canShan = function (tar, blur) { + let known = tar.getKnownCards(viewer); + if (!blur) return known.some(card => { + let name = get.name(card, tar); + return (name === 'shan' || name === 'hufu') && lib.filter.cardRespondable(card, tar); + }); + if (tar.countCards('hs', i => !known.includes(i)) > 3.67 - 2 * tar.hp / tar.maxHp) return true; + if (!tar.hasSkillTag('respondShan', true, 'respond', true)) return false; + if (tar.hp <= damage) return false; + if (tar.hp <= damage + 1) return isZhu(tar); + return true; + }, self = false; + if (canShan(target)) return 0; + if (bonus && !viewer.hasSkillTag('filterDamage', null, { + player: player, + card: card + })) damage = 2; + if ((viewer.hp <= damage || viewer.hp <= damage + 1 && isZhu(viewer)) && !canShan(viewer)) { + if (viewer === target) return status; + let fv = true; + if (evt && evt.targets) for (let i of evt.targets) { + if (fv) { + if (target === i) fv = false; + continue; + } + if (viewer == i) { + if (isZhu(viewer)) return 0; + self = true; + break; + } + } + } + let mayShan = canShan(target, true); + if (bonus && !target.hasSkillTag('filterDamage', null, { + player: player, + card: card + })) damage = 2; + else damage = 1; + if (isZhu(target)) { + if (eff < 0) { + if (target.hp <= damage + 1 || !mayShan && target.hp <= damage + 2) return 1; + if (mayShan && target.hp > damage + 2) return 0; + else if (mayShan || target.hp > damage + 2) pri = 3; + else pri = 4; + } + else if (target.hp > damage + 1) pri = 2; + else return 0; + } + else if (self) return 0; + else if (eff < 0) { + if (!mayShan && target.hp <= damage) pri = 5; + else if (mayShan) return 0; + else if (target.hp > damage + 1) pri = 2; + else if (target.hp === damage + 1) pri = 3; + else pri = 4; + } + else if (target.hp <= damage) return 0; + let find = false; + if (evt && evt.targets) for (let i = 0; i < evt.targets.length; i++) { + if (!find) { + if (evt.targets[i] === target) find = true; + continue; + } + let att1 = get.attitude(viewer, evt.targets[i]), eff1 = get.effect(evt.targets[i], card, player, evt.targets[i]), temp = 1; + if (Math.abs(att1) < 1 || att1 * eff1 >= 0 || canShan(evt.targets[i])) continue; + mayShan = canShan(evt.targets[i], true); + if (bonus && !evt.targets[i].hasSkillTag('filterDamage', null, { + player: player, + card: card + })) damage = 2; + else damage = 1; + if (isZhu(evt.targets[i])) { + if (eff1 < 0) { + if (evt.targets[i].hp <= damage + 1 || !mayShan && evt.targets[i].hp <= damage + 2) return 0; + if (mayShan && evt.targets[i].hp > damage + 2) continue; + if (mayShan || evt.targets[i].hp > damage + 2) temp = 3; + else temp = 4; + } + else if (evt.targets[i].hp > damage + 1) temp = 2; + else continue; + } + else if (eff1 < 0) { + if (!mayShan && evt.targets[i].hp <= damage) temp = 5; + else if (mayShan) continue; + else if (evt.targets[i].hp > damage + 1) temp = 2; + else if (evt.targets[i].hp === damage + 1) temp = 3; + else temp = 4; + } + else if (evt.targets[i].hp > damage + 1) temp = 2; + if (temp > pri) return 0; + } + return 1; + }, + basic: { + order: 9, + useful: 1, + value: 5 + }, + result: { + player(player, target) { + if (player._wanjian_temp || player.hasSkillTag('jueqing', false, target)) return 0; + player._wanjian_temp = true; + let eff = get.effect(target, new lib.element.VCard({ name: 'wanjian' }), player, target); + delete player._wanjian_temp; + if (eff >= 0) return 0; + if (target.hp > 2 || target.hp > 1 && !target.isZhu && target != game.boss && target != game.trueZhu && target != game.falseZhu) return 0; + if (target.hp > 1 && target.hasSkillTag('respondShan', true, 'respond', true)) return 0; + let known = target.getKnownCards(player); + if (known.some(card => { + let name = get.name(card, target); + if (name === 'shan' || name === 'hufu') return lib.filter.cardRespondable(card, target); + if (name === 'wuxie') return lib.filter.cardEnabled(card, target, 'forceEnable'); + })) return 0; + if (target.hp > 1 || target.countCards('hs', i => !known.includes(i)) > 3.67 - 2 * target.hp / target.maxHp) return 0; + let res = 0, att = get.sgnAttitude(player, target); + res -= att * (0.8 * target.countCards('hs') + 0.6 * target.countCards('e') + 3.6); + if (get.mode() === 'identity' && target.identity === 'fan') res += 2.4; + if (get.mode() === 'guozhan' && player.identity !== 'ye' && player.identity === target.identity || + get.mode() === 'identity' && player.identity === 'zhu' && (target.identity === 'zhong' || target.identity === 'mingzhong')) res -= 0.8 * player.countCards('he'); + return res; + }, + target(player, target) { + let zhu = (get.mode() === 'identity' && target.isZhu) || target.identity === 'zhu'; + if (!lib.filter.cardRespondable({ name: 'shan' }, target)) { + if (zhu) { + if (target.hp < 2) return -99; + if (target.hp === 2) return -3.6; + } + return -2; + } + let known = target.getKnownCards(player); + if (known.some(card => { + let name = get.name(card, target); + if (name === 'shan' || name === 'hufu') return lib.filter.cardRespondable(card, target); + if (name === 'wuxie') return lib.filter.cardEnabled(card, target, 'forceEnable'); + })) return -1.2; + let nh = target.countCards('hs', i => !known.includes(i)); + if (zhu && target.hp <= 1) { + if (nh === 0) return -99; + if (nh === 1) return -60; + if (nh === 2) return -36; + if (nh === 3) return -8; + return -5; + } + if (target.hasSkillTag('respondShan', true, 'respond', true)) return -1.35; + if (!nh) return -2; + if (nh === 1) return -1.65; + return -1.5; } }, - basic:{ - order:9, - useful:1, - value:5 - }, - result:{ - target_use:function(player,target){ - if(player.hasUnknown(2)&&get.mode()!='guozhan') return 0; - var nh=target.countCards('h'); - if(get.mode()=='identity'){ - if(target.isZhu&&nh<=2&&target.hp<=1) return -100; - } - if(nh==0) return -2; - if(nh==1) return -1.7 - return -1.5; - }, - target:function(player,target){ - var nh=target.countCards('h'); - if(get.mode()=='identity'){ - if(target.isZhu&&nh<=2&&target.hp<=1) return -100; - } - if(nh==0) return -2; - if(nh==1) return -1.7 - return -1.5; - }, - }, - tag:{ - respond:1, - respondShan:1, - damage:1, - multitarget:1, - multineg:1, + tag: { + respond: 1, + respondShan: 1, + damage: 1, + multitarget: 1, + multineg: 1 } } }, diff --git a/character/sp.js b/character/sp.js index 11697fb42..7ce5b7b63 100755 --- a/character/sp.js +++ b/character/sp.js @@ -18318,9 +18318,16 @@ game.import('character',function(lib,game,ui,get,ai,_status){ return get.info('ollongdan').ai.skillTagFilter(player,tag); }, order:function(item,player){ - if(!player||!player.storage) return; + if(!player||!player.storage){ + player=_status.event.player; + if(!player||!player.storage) return 0; + if(Object.keys(player.storage).some(i=>{ + return typeof i=='string'&&i.indexOf('fuhan')!=-1; + })) return 4; + return 1; + } const awakened=Object.keys(player.storage).some(i=>typeof i=='string'&&i.indexOf('fuhan')!=-1); - if(player&&_status.event.type=='phase'){ + if(_status.event.type=='phase'){ var max=0; var list=['sha','tao','jiu']; var map={sha:'shan',tao:'jiu',jiu:'tao'} @@ -18334,7 +18341,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){ if(max>0) max+=(awakened?0.3:-0.3); return max; } - if(!player) player=_status.event.player; return awakened?4:1; }, }, From d124f8edd6fd43679470a6272d2d7981ae630172 Mon Sep 17 00:00:00 2001 From: 157 <3619242020@qq.com> Date: Sun, 17 Mar 2024 12:02:07 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B9=B6=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E3=80=90=E6=9C=9B=E6=A2=85=E6=AD=A2=E6=B8=B4=E3=80=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- audio/card/male/wangmeizhike.mp3 | Bin 0 -> 10291 bytes card/yunchou.js | 76 +++++++++++++++++++++++-------- 2 files changed, 58 insertions(+), 18 deletions(-) create mode 100644 audio/card/male/wangmeizhike.mp3 diff --git a/audio/card/male/wangmeizhike.mp3 b/audio/card/male/wangmeizhike.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..4705dfe0c117b08e0f6af84916ab2abadb567dbf GIT binary patch literal 10291 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 o76-RJaDPfWvQpXMR)EM-0<8b~Bm_|azi{ + return get.name(card)==='nanman'; + },'hs'), + wan=player.hasCard(card=>{ + return get.name(card)==='wanjian'; + },'hs'), + aoe=0, + max=0; + game.countPlayer(current=>{ + if(get.attitude(player,current)<=0) return false; + let hp=current.isMinHp(), + hc=current.isMinHandcard(); + if((nan || wan)&&(hp || hc)) aoe=1; + if(hp&&hc&&max!==1) max=current===player?1:-1; + }); + if(aoe){ + if(nan) aoe=Math.max(aoe,get.order('nanman')); + if(wan) aoe=Math.max(aoe,get.order('wanjian')); + return aoe+0.2; + } + if(max) return 5.8; + if(player.isDamaged()&&player.isMinHp()&&player.countCards('hs','tao')) return get.order('tao')+0.2; + return 0.5; + }, value:7, result:{ - target:function(player,target){ - var num=0; - if(target.isMinHp()&&get.recoverEffect(target)>0){ - if(target.hp==1){ - num+=3; - } - else{ - num+=2; + target(player,target){ + let num=0, + current=player.next, + mei=1, + draw=target.hasSkillTag('nogain')?0.1:1; + if(!ui.selected.cards) mei=0; + let mine=player.countCards('h',card=>{ + if(mei>0&& ui.selected.cards.includes(card)) return false; + if(!mei&&get.name(card)==='phd_wmzk'){ + mei=-1; + return false; } + return true; + }); + if(player.hasSkillTag('noh')&&player.countCards('h')) mine++; + let min=mine; + while(current!==player){ + if(current.countCards('h')0){ + if(target.hp===1) num+=3; + else num+=2; } + if(player===target){ + if(mine<=min) num+=(num?2:1)*draw; + } + else if(target.countCards('h')<=min) num+=(num?2:1)*draw; return num; } + }, + tag:{ + draw:1, + recover:0.5 } } }, From 8a75817f330682d4174eeba5b5488034ed2aa7d1 Mon Sep 17 00:00:00 2001 From: 157 <3619242020@qq.com> Date: Sun, 17 Mar 2024 12:14:56 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E4=BC=98=E5=8C=96=E3=80=90=E7=BA=AF?= =?UTF-8?q?=E5=88=9A=E3=80=91ai?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- card/sp.js | 3 ++- card/swd.js | 2 +- card/yunchou.js | 4 ++-- character/tw.js | 40 ++++++++++++++++++++++++++++++++++++---- 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/card/sp.js b/card/sp.js index 8d3cd2ad8..ea1dbd73b 100644 --- a/card/sp.js +++ b/card/sp.js @@ -369,7 +369,8 @@ game.import('card',function(lib,game,ui,get,ai,_status){ useful:4, value:10, tag:{ - draw:2 + draw:3, + discard:1 }, result:{ target:function(player,target){ diff --git a/card/swd.js b/card/swd.js index 26ad13b04..5d10daaf9 100644 --- a/card/swd.js +++ b/card/swd.js @@ -1089,7 +1089,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ value:7, useful:1, tag:{ - draw:2 + gain:1 }, result:{ target:function(player,target){ diff --git a/card/yunchou.js b/card/yunchou.js index e26e8049c..72027ab01 100644 --- a/card/yunchou.js +++ b/card/yunchou.js @@ -407,7 +407,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ value:[6,1], useful:[3,1], tag:{ - draw:1 + draw:3 }, result:{ target:function(player,target){ @@ -551,7 +551,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){ } }, tag:{ - draw:1, + draw:1.2, recover:0.5 } } diff --git a/character/tw.js b/character/tw.js index f333bac0e..dbe112c18 100644 --- a/character/tw.js +++ b/character/tw.js @@ -2278,6 +2278,14 @@ game.import('character',function(lib,game,ui,get,ai,_status){ }, twchungang:{ audio:2, + init: ()=>{ + game.addGlobalSkill('twchungang_global'); + }, + onremove: player => { + if (!game.hasPlayer(i => { + return player !== i && i.hasSkill('twchungang'); + }, true)) game.removeGlobalSkill('twchungang_global'); + }, trigger:{global:['gainAfter','loseAsyncAfter']}, filter:function(event,player){ var evt=event.getParent('phaseDraw'); @@ -2299,10 +2307,34 @@ game.import('character',function(lib,game,ui,get,ai,_status){ i.chooseToDiscard('he',true); } }, - ai:{ - //能和一技能有配合,但仍旧搅shi棍技能 - threaten:3, - }, + subSkill: { + global: { + trigger: { + player: 'dieAfter' + }, + filter(event, player) { + return !game.hasPlayer(i => i.hasSkill('twchungang'), true) + }, + silent: true, + forceDie: true, + charlotte: true, + content() { + game.removeGlobalSkill('twchungang_global'); + }, + ai: { + effect: { + target(card, player, target) { + if ((get.tag(card, 'gain') || 0) < 2 && (get.tag(card, 'draw') || 0) < 2) return; + let evt = _status.event.getParent('phaseDraw'), dis = game.countPlayer(i => { + return target !== i && i.hasSkill('twchungang'); + }); + if (!dis || evt && evt.player === target) return; + return [1, -dis]; + } + } + } + } + } }, //海外主公技 //张鲁 From 7ccb20a9302651b1e320b77b1c3aeefce8d5adbf Mon Sep 17 00:00:00 2001 From: 157 <3619242020@qq.com> Date: Sun, 17 Mar 2024 14:49:19 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E6=8B=93=E5=AE=BDhasUsableCard=E4=B8=9A?= =?UTF-8?q?=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- noname/library/element/player.js | 56 ++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/noname/library/element/player.js b/noname/library/element/player.js index 515600f12..f35fe7c39 100644 --- a/noname/library/element/player.js +++ b/noname/library/element/player.js @@ -1864,24 +1864,40 @@ export class Player extends HTMLDivElement { } /** * @param { string } name + * @param { string } type */ - hasUsableCard(name) { - if (this.countCards('hs', name)) return true; - const skills = this.getSkills('invisible').concat(lib.skill.global); + hasUsableCard(name, type) { + if (typeof type !== 'string') type = type ? 'limit' : 'all'; + if (this.hasCard(i => { + if (get.name(i, this) !== name) return false; + if (type === 'all') return true; + let event = _status.event, evt = event.getParent('chooseToUse'); + if (get.itemtype(evt) !== 'event') evt = event; + if (type === 'respond') return lib.filter.cardRespondable(i, this, evt); + return lib.filter.cardEnabled(i, this, type === 'limit' ? evt : 'forceEnable'); + }, 'hs')) return true; + const skills = this.getSkills('invisible').concat(lib.skill.global), str = 'respond' + name[0].toUpperCase() + name.slice(1); game.expandSkills(skills); for (let i = 0; i < skills.length; i++) { - const ifo = get.info(skills[i]); - if (ifo.viewAs && typeof ifo.viewAs != 'function' && typeof ifo.viewAs != 'string' && ifo.viewAs.name == name) { - if (!ifo.viewAsFilter || ifo.viewAsFilter(this) !== false) { - return true; - } + const ifo = get.info(skills[i]), hiddenCard = ifo.hiddenCard; + if (ifo.viewAs && typeof ifo.viewAs !== 'function' && typeof ifo.viewAs !== 'string' && ifo.viewAs.name === name) { + if (!ifo.viewAsFilter || ifo.viewAsFilter(this) !== false) return true; } - else { - const hiddenCard = get.info(skills[i]).hiddenCard; - if (typeof hiddenCard == 'function' && hiddenCard(this, name)) { - return true; - } + else if (typeof hiddenCard == 'function') { + if (hiddenCard(this, name)) return true; } + /*else if (ifo.ai && ifo.ai[str]) { + if (ifo.ai.skillTagFilter) { + if ((type === 'respond' || type === 'all')&& ifo.ai.skillTagFilter(this, str, 'respond') !== false) return true; + if (type !== 'respond' && ifo.ai.skillTagFilter(this, str, 'use') !== false) return true; + continue; + } + if (type === 'all') return true; + if (typeof ifo.ai[str] === 'string') { + if (ifo.ai[str] === 'use' || type === 'respond' && ifo.ai[str] === type) return true; + } + else return true; + }*/ } } /** @@ -8859,14 +8875,20 @@ export class Player extends HTMLDivElement { if (this.countCards('hs', 'sha')) return true; if (this.countCards('hs', 'hufu')) return true; if (!noauto && this.countCards('hs', 'yuchanqian')) return true; - if (this.hasSkillTag('respondSha', true, respond ? 'respond' : 'use', true)) return true; - return this.hasUsableCard('sha'); + let tag = respond; + if (typeof tag !== 'string') tag = respond ? 'respond' : 'use'; + if (this.hasSkillTag('respondSha', true, tag, true)) return true; + if (typeof respond !== 'string') respond = respond ? 'respond' : 'all'; + return this.hasUsableCard('sha', respond); } hasShan(respond) { if (this.countCards('hs', 'shan')) return true; if (this.countCards('hs', 'hufu')) return true; - if (this.hasSkillTag('respondShan', true, respond ? 'respond' : 'use', true)) return true; - return this.hasUsableCard('shan'); + let tag = respond; + if (typeof tag !== 'string') tag = respond ? 'respond' : 'use'; + if (this.hasSkillTag('respondShan', true, tag, true)) return true; + if (typeof respond !== 'string') respond = respond ? 'respond' : 'all'; + return this.hasUsableCard('shan', respond); } mayHaveSha(viewer, type, ignore, rvt) { /**