Merge pull request #1099 from PZ157/PR-Branch

卡牌修复、优化、更新draw键值、添加语音;武将技能修复和优化
This commit is contained in:
Spmario233 2024-03-17 19:22:01 +08:00 committed by GitHub
commit 64fa4537b7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 521 additions and 149 deletions

Binary file not shown.

View File

@ -229,9 +229,9 @@ game.import('card',function(lib,game,ui,get,ai,_status){
}, },
ai:{ ai:{
basic:{ basic:{
order:4, order:9.2,
value:[3,1], value:[3,1],
useful:1, useful:0.6,
}, },
wuxie:function(target,card,player,viewer,status){ wuxie:function(target,card,player,viewer,status){
if(get.attitude(viewer,player._trueMe||player)>0) return 0; if(get.attitude(viewer,player._trueMe||player)>0) return 0;

View File

@ -1095,30 +1095,42 @@ game.import('card',function(lib,game,ui,get,ai,_status){
target.chooseToDiscard(2,'he',true).ai=get.disvalue; target.chooseToDiscard(2,'he',true).ai=get.disvalue;
}, },
ai:{ ai:{
wuxie:function(){ wuxie: function () {
return 0; return 0;
}, },
basic:{ basic: {
useful:3, order: 9,
value:3, useful: 1.5,
order:5 value: 3
}, },
result:{ result: {
target:function(player,target){ target(player, target) {
var hs=target.getCards('h'); let i,
if(hs.length<=1){ add = 0,
if(target==player&&(hs.length==0||hs[0].name=='yiyi')){ y = 1,
return 0; 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 true;
} });
return Math.sqrt(target.countCards('he')); else i = target.countCards('he');
}, if (target.hasSkillTag('noh')) add++;
return add + Math.sqrt(i / 3.6 + tars) / 2;
}
}, },
tag:{ tag: {
loseCard:1, draw: 2,
discard:1, loseCard: 2,
norepeat:1 discard: 2,
multitarget: true,
norepeat: 1
} }
}, },
}, },

View File

@ -369,7 +369,8 @@ game.import('card',function(lib,game,ui,get,ai,_status){
useful:4, useful:4,
value:10, value:10,
tag:{ tag:{
draw:2 draw:3,
discard:1
}, },
result:{ result:{
target:function(player,target){ target:function(player,target){

View File

@ -272,17 +272,17 @@ game.import('card',function(lib,game,ui,get,ai,_status){
useful:[5,3,1], useful:[5,3,1],
value:[5,3,1], value:[5,3,1],
}, },
order:function(item,player){ order(item, player) {
if(player.hasSkillTag('presha',true,null,true)) return 10; let res = 3.2;
if(typeof item==='object'&&game.hasNature(item,'linked')){ if (player.hasSkillTag('presha', true, null, true)) res = 10;
if(game.hasPlayer(function(current){ if (typeof item !== 'object' || !game.hasNature(item, 'linked') || game.countPlayer(cur => cur.isLinked()) < 2) return res;
return current!=player&&lib.card.sha.ai.canLink(player,current,item)&&player.canUse(item,current,null,true)&&get.effect(current,item,player,player)>0; //let used = player.getCardUsable('sha') - 1.5, natures = ['thunder', 'fire', 'ice', 'kami'];
})&&game.countPlayer(function(current){ let uv = player.getUseValue(item, true);
return current.isLinked()&&get.damageEffect(current,player,player,get.nature(item))>0; if (uv <= 0) return res;
})>1) return 3.1; let temp = player.getUseValue('sha', true) - uv;
return 3; if (temp < 0) return res + 0.15;
} if (temp > 0) return res - 0.15;
return 3.05; return res;
}, },
result:{ result:{
target:function(player,target,card,isLink){ target:function(player,target,card,isLink){
@ -995,43 +995,171 @@ game.import('card',function(lib,game,ui,get,ai,_status){
} }
}, },
ai:{ ai:{
wuxie:function(target,card,player,viewer){ wuxie(target, card, player, viewer, status) {
if(get.attitude(viewer,target)>0&&target.countCards('h','sha')){ let att = get.attitude(viewer, target), eff = get.effect(target, card, player, target);
if(!target.countCards('h')||target.hp==1||Math.random()<0.7) return 0; 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:{ tag: {
order:9, respond: 1,
useful:[5,1], respondSha: 1,
value:5 damage: 1,
}, multitarget: 1,
result:{ multineg: 1
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,
} }
} }
}, },
@ -1079,43 +1207,170 @@ game.import('card',function(lib,game,ui,get,ai,_status){
} }
}, },
ai:{ ai:{
wuxie:function(target,card,player,viewer){ wuxie(target, card, player, viewer, status) {
if(get.attitude(viewer,target)>0&&target.countCards('h','shan')){ let att = get.attitude(viewer, target), eff = get.effect(target, card, player, target);
if(!target.countCards('h')||target.hp==1||Math.random()<0.7) return 0; 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:{ tag: {
order:9, respond: 1,
useful:1, respondShan: 1,
value:5 damage: 1,
}, multitarget: 1,
result:{ multineg: 1
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,
} }
} }
}, },

View File

@ -1089,7 +1089,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){
value:7, value:7,
useful:1, useful:1,
tag:{ tag:{
draw:2 gain:1
}, },
result:{ result:{
target:function(player,target){ target:function(player,target){

View File

@ -407,7 +407,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){
value:[6,1], value:[6,1],
useful:[3,1], useful:[3,1],
tag:{ tag:{
draw:1 draw:3
}, },
result:{ result:{
target:function(player,target){ target:function(player,target){
@ -480,39 +480,79 @@ game.import('card',function(lib,game,ui,get,ai,_status){
fullskin:true, fullskin:true,
type:'trick', type:'trick',
enable:true, enable:true,
filterTarget:function(card,player,target){ filterTarget:true,
return (target.isMinHp()&&target.isDamaged())||target.isMinHandcard(); content(){
},
content:function(){
'step 0' 'step 0'
if(target.isMinHp()&&target.isDamaged()){ if(target.isMinHp()&&target.isDamaged()){
target.recover(); target.recover();
event.rec=true; event.rec=true;
} }
'step 1' 'step 1'
if(target.isMinHandcard()){ if(target.isMinHandcard()) target.draw(event.rec?1:2);
target.draw(event.rec?1:2);
}
}, },
ai:{ ai:{
order:2.5, order(){
let player=_status.event.player,
nan=player.hasCard(card=>{
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, value:7,
result:{ result:{
target:function(player,target){ target(player,target){
var num=0; let num=0,
if(target.isMinHp()&&get.recoverEffect(target)>0){ current=player.next,
if(target.hp==1){ mei=1,
num+=3; draw=target.hasSkillTag('nogain')?0.1:1;
} if(!ui.selected.cards) mei=0;
else{ let mine=player.countCards('h',card=>{
num+=2; 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')<min) min=current.countCards('h');
current=current.next;
} }
if(target.isMinHandcard()){ if(target.isMinHp()&&target.isDamaged()&&get.recoverEffect(target)>0){
num+=2; 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; return num;
} }
},
tag:{
draw:1.2,
recover:0.5
} }
} }
}, },

View File

@ -9901,7 +9901,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
if(th>0){ if(th>0){
event.num=Math.ceil(th/2); event.num=Math.ceil(th/2);
var list=[ var list=[
'本回合不能使用或打出手牌,然后'+str+'摸两张牌', '本回合不能使用手牌,然后'+str+'摸两张牌',
'展示所有手牌,并将其中一种花色的所有牌交给'+str, '展示所有手牌,并将其中一种花色的所有牌交给'+str,
'弃置'+get.cnNumber(event.num)+'张手牌', '弃置'+get.cnNumber(event.num)+'张手牌',
]; ];
@ -9944,10 +9944,13 @@ game.import('character',function(lib,game,ui,get,ai,_status){
subSkill:{ subSkill:{
block:{ block:{
mark:true, mark:true,
intro:{content:'不能使用或打出手牌'}, intro:{content:'不能使用手牌'},
charlotte:true, charlotte:true,
mod:{ mod:{
cardEnabled2:function(card){ cardEnabled:function(card){
if(get.position(card)=='h') return false;
},
cardSavable:function(card){
if(get.position(card)=='h') return false; if(get.position(card)=='h') return false;
}, },
}, },

View File

@ -18318,8 +18318,16 @@ game.import('character',function(lib,game,ui,get,ai,_status){
return get.info('ollongdan').ai.skillTagFilter(player,tag); return get.info('ollongdan').ai.skillTagFilter(player,tag);
}, },
order:function(item,player){ order:function(item,player){
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); 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 max=0;
var list=['sha','tao','jiu']; var list=['sha','tao','jiu'];
var map={sha:'shan',tao:'jiu',jiu:'tao'} var map={sha:'shan',tao:'jiu',jiu:'tao'}
@ -18333,7 +18341,6 @@ game.import('character',function(lib,game,ui,get,ai,_status){
if(max>0) max+=(awakened?0.3:-0.3); if(max>0) max+=(awakened?0.3:-0.3);
return max; return max;
} }
if(!player) player=_status.event.player;
return awakened?4:1; return awakened?4:1;
}, },
}, },

View File

@ -2319,6 +2319,14 @@ game.import('character',function(lib,game,ui,get,ai,_status){
}, },
twchungang:{ twchungang:{
audio:2, 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']}, trigger:{global:['gainAfter','loseAsyncAfter']},
filter:function(event,player){ filter:function(event,player){
var evt=event.getParent('phaseDraw'); var evt=event.getParent('phaseDraw');
@ -2340,10 +2348,34 @@ game.import('character',function(lib,game,ui,get,ai,_status){
i.chooseToDiscard('he',true); i.chooseToDiscard('he',true);
} }
}, },
ai:{ subSkill: {
//能和一技能有配合但仍旧搅shi棍技能 global: {
threaten:3, 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];
}
}
}
}
}
}, },
//海外主公技 //海外主公技
//张鲁 //张鲁

View File

@ -1864,24 +1864,40 @@ export class Player extends HTMLDivElement {
} }
/** /**
* @param { string } name * @param { string } name
* @param { string } type
*/ */
hasUsableCard(name) { hasUsableCard(name, type) {
if (this.countCards('hs', name)) return true; if (typeof type !== 'string') type = type ? 'limit' : 'all';
const skills = this.getSkills('invisible').concat(lib.skill.global); 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); game.expandSkills(skills);
for (let i = 0; i < skills.length; i++) { for (let i = 0; i < skills.length; i++) {
const ifo = get.info(skills[i]); 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.viewAs && typeof ifo.viewAs !== 'function' && typeof ifo.viewAs !== 'string' && ifo.viewAs.name === name) {
if (!ifo.viewAsFilter || ifo.viewAsFilter(this) !== false) { if (!ifo.viewAsFilter || ifo.viewAsFilter(this) !== false) return true;
return true;
}
} }
else { else if (typeof hiddenCard == 'function') {
const hiddenCard = get.info(skills[i]).hiddenCard; if (hiddenCard(this, name)) return true;
if (typeof hiddenCard == 'function' && 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', 'sha')) return true;
if (this.countCards('hs', 'hufu')) return true; if (this.countCards('hs', 'hufu')) return true;
if (!noauto && this.countCards('hs', 'yuchanqian')) return true; if (!noauto && this.countCards('hs', 'yuchanqian')) return true;
if (this.hasSkillTag('respondSha', true, respond ? 'respond' : 'use', true)) return true; let tag = respond;
return this.hasUsableCard('sha'); 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) { hasShan(respond) {
if (this.countCards('hs', 'shan')) return true; if (this.countCards('hs', 'shan')) return true;
if (this.countCards('hs', 'hufu')) return true; if (this.countCards('hs', 'hufu')) return true;
if (this.hasSkillTag('respondShan', true, respond ? 'respond' : 'use', true)) return true; let tag = respond;
return this.hasUsableCard('shan'); 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) { mayHaveSha(viewer, type, ignore, rvt) {
/** /**