Merge branch 'Dev-Pref-ESModule' of github.com:nofficalfs/noname into Dev-Pref-ESModule

This commit is contained in:
Rintim 2023-12-22 21:03:00 +08:00
commit ecb82db7f1
No known key found for this signature in database
GPG Key ID: BE9E1EA615BACFCF
16 changed files with 1357 additions and 552 deletions

View File

@ -123,31 +123,43 @@ game.import('card',function(lib,game,ui,get,ai,_status){
return 0; return 0;
}, },
result:{ result:{
target:(player,target)=>{ target:(player,target,card)=>{
if(target&&target.isDying()) return 2; if(target&&target.isDying()) return 2;
if(!target || target._jiu_temp || !target.isPhaseUsing()) return 0; if(!target || target._jiu_temp || !target.isPhaseUsing()) return 0;
if(!target.getCardUsable('sha') || lib.config.mode==='stone'&&!player.isMin()&&player.getActCount()+1>=player.actcount) return 0; let usable=target.getCardUsable('sha');
let shas = player.getCards('hs',card=>get.name(card)==='sha'&&!ui.selected.cards.includes(card)), card; if(!usable || lib.config.mode==='stone'&&!player.isMin()&&player.getActCount()+1>=player.actcount || !target.mayHaveSha(player,'use',card)) return 0;
if(!shas.length || !target.hasSha() || shas.length>1&&(target.getCardUsable('sha')>1 || target.countCards('hs','zhuge'))) return 0; let effs={order:0},temp;
target._jiu_temp = true; target.getCards('hs',i=>{
shas.sort((a,b)=>get.order(b)-get.order(a)); if(get.name(i)!=='sha' || ui.selected.cards.includes(i)) return false;
for(let i=0; i<shas.length; i++){ temp=get.order(i,target);
let tars = []; if(temp<effs.order) return false;
if(lib.filter.filterCard(shas[i],target)) tars = game.filterPlayer(current=>{ if(temp>effs.order) effs={order:temp};
return get.attitude(target,current)<0&&target.canUse(shas[i],current,null,true)&&!current.hasSkillTag('filterDamage',null,{ effs[i.cardid]={
card:i,
target:null,
eff:0
};
});
delete effs.order;
for(let i in effs){
if(!lib.filter.filterCard(effs[i].card,target)) continue;
game.filterPlayer(current=>{
if(get.attitude(target,current)>=0 || !target.canUse(effs[i].card,current,null,true) || current.hasSkillTag('filterDamage',null,{
player:target, player:target,
card:shas[i], card:effs[i].card,
jiu:true jiu:true
})&&get.effect(current,shas[i],target)>0; })) return false;
temp=get.effect(current,effs[i].card,target,player);
if(temp<=effs[i].eff) return false;
effs[i].target=current;
effs[i].eff=temp;
return false;
}); });
if(!tars.length) continue; if(!effs[i].target) continue;
tars.sort((a,b)=>{ if(target.hasSkillTag('directHit_ai',true,{
return get.effect(b,shas[i],target)-get.effect(a,shas[i],target); target:effs[i].target,
}); card:i
if(!tars[0].mayHaveShan(player,'use') || target.hasSkillTag('directHit_ai',true,{ },true) || usable===1&&(target.needsToDiscard()>Math.max(0,3-target.hp) || !effs[i].target.mayHaveShan(player,'use'))){
target:tars[0],
card:shas[i]
},true) || target.needsToDiscard()>Math.max(0,3-target.hp)){
delete target._jiu_temp; delete target._jiu_temp;
return 1; return 1;
} }

View File

@ -252,10 +252,6 @@ game.import('card',function(lib,game,ui,get,ai,_status){
}, },
canLink:function(player,target,card){ canLink:function(player,target,card){
if(!target.isLinked()&&!player.hasSkill('wutiesuolian_skill')) return false; if(!target.isLinked()&&!player.hasSkill('wutiesuolian_skill')) return false;
if(target.mayHaveShan()&&!player.hasSkillTag('directHit_ai',true,{
target:target,
card:card,
},true)) return false;
if(player.hasSkill('jueqing')||player.hasSkill('gangzhi')||target.hasSkill('gangzhi')) return false; if(player.hasSkill('jueqing')||player.hasSkill('gangzhi')||target.hasSkill('gangzhi')) return false;
return true; return true;
}, },
@ -264,42 +260,87 @@ game.import('card',function(lib,game,ui,get,ai,_status){
value:[5,3,1], value:[5,3,1],
}, },
order:function(item,player){ order:function(item,player){
if(player.hasSkillTag('presha',true,null,true)) return 10; let res=3.2;
if(game.hasNature(item,'linked')){ if(player.hasSkillTag('presha',true,null,true)) res=10;
if(game.hasPlayer(function(current){ if(get.itemtype(player)!=='player') return res;
return current!=player&&current.isLinked()&&player.canUse(item,current,null,true)&&get.effect(current,item,player,player)>0&&lib.card.sha.ai.canLink(player,current,item); /*let uv=player.getUseValue(item,true);
})&&game.countPlayer(function(current){ if(uv<=0) return res;*/
return current.isLinked()&&get.damageEffect(current,player,player,get.nature(item))>0; let ignore=get.copy(ui.selected.cards),used=player.getCardUsable('sha')-1.5,ph=player.getCards('hs');
})>1) return 3.1; ignore.add(item);
return 3; if(typeof item==='object'&&item.cards) ignore.addArray(item.cards);
let na=get.natureList(item),number=get.number(item),natures=['thunder','fire','ice','kami'],nb;
for(let i of ph){
if(ignore.includes(i)||get.name(i)!=='sha'||!lib.filter.cardEnabled(i,player)) continue;
nb=get.natureList(i);
if(na.length===nb.length&&(!na.length||na[0]===nb[0])){
if(number>get.number(i)) return res-0.15;
continue;
}
if(used*(na.length-nb.length)>0) return res-0.15;
if(na.length===nb.length){
if(used*(natures.indexOf(na[0])-natures.indexOf(nb[0]))>0) return res-0.15;
}
/*usev=player.getUseValue(i,true);
if(usev>0&&used*(uv-usev)>0) return res-0.15;*/
} }
return 3.05; return res;
}, },
result:{ result:{
target:function(player,target,card,isLink){ target:(player,target,card,isLink)=>{
var eff=function(){ if(target._sha_result_temp) return -1.5;
if(!isLink&&player.hasSkill('jiu')){ target._sha_result_temp=true;
if(!target.hasSkillTag('filterDamage',null,{ let basic=1,eff=-1.5,zhu=target.isZhu&&target.identityShown;
player:player, if(!target.hasSkillTag('filterDamage',null,{
card:card, player:player,
jiu:true, card:card,
})){ jiu:player.hasSkill('jiu'),
if(get.attitude(player,target)>0){ })&&(player.hasSkill('jiu')||player.hasSkillTag('damageBonus',true,{
return -7; target:target,
} card:card
else{ }))){
return -4; if(target.hp<2) basic=5;
} else if(target.hp===2) basic=3;
} else basic=2;
return -0.5; }
else if(target.hp<2) basic*=3;
if(zhu) eff*=Math.max(1,9/target.hp/target.hp);
if(isLink){
let rate=_status.event.getTempCache('sha_result','mayShan');
if(rate&&rate.id===card.sha_ai_id) rate=rate.rate;
delete target._sha_result_temp;
if(typeof rate==='boolean'||typeof rate==='number'){
if(rate>=1) return eff;
return basic*eff*(1.3-0.9*rate);
} }
return -1.5; delete _status.event._tempCache['sha_result']['mayShan'];
}(); return basic*eff;
if(!isLink&&target.mayHaveShan()&&!player.hasSkillTag('directHit_ai',true,{ }
let mayShan;
if(player.hasSkillTag('directHit_ai',true,{
target:target, target:target,
card:card, card:card,
},true)) return eff/1.2; },true)||game.hasNature(card,'stab')&&target.countCards('he')<2&&!target.hasSkillTag('noh')) mayShan=false;
return eff; else{
let temp=target.getKnownCards(player);
if(temp.some(i=>{
let name=get.name(i,target);
if(name==='shan'||name==='hufu') return lib.filter.cardEnabled(i,target,'forceEnable');
return false;
})) mayShan=true;
else mayShan=1-Math.pow(0.7,(target.hasSkillTag('respondShan',true,'use',true)?1:0)+target.countCards('hs')-temp.length);
}
if(game.hasNature(card,'linked',player)){
if(!_status.sha_ai_id) _status.sha_ai_id=1;
else _status.sha_ai_id++;
card.sha_ai_id=_status.sha_ai_id;
_status.event.putTempCache('sha_result','mayShan',{
id:_status.sha_ai_id,
rate:mayShan
});
}
delete target._sha_result_temp;
if(mayShan>=1) return eff;
return basic*eff*(1.3-0.9*mayShan);
}, },
}, },
tag:{ tag:{
@ -457,7 +498,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){
if(target.hp>0){ if(target.hp>0){
if(!player.isPhaseUsing()) return 0; if(!player.isPhaseUsing()) return 0;
let min = 7.2-4*player.hp/player.maxHp, let min = 7.2-4*player.hp/player.maxHp,
nd = player.needsToDiscard(-player.countCards('h',i=>!taos.includes(i)&&get.value(i)<min)), nd = player.needsToDiscard(i=>taos.includes(i)||get.value(i)>=min),
keep = nd?0:2; keep = nd?0:2;
if(nd>2 || taos.length>1&&(nd>1||nd&&player.hp<1+taos.length) || target.identity==='zhu'&&(nd||target.hp<3)&&(mode==='identity'||mode==='versus'||mode==='chess') || !player.hasFriend()) return 2; if(nd>2 || taos.length>1&&(nd>1||nd&&player.hp<1+taos.length) || target.identity==='zhu'&&(nd||target.hp<3)&&(mode==='identity'||mode==='versus'||mode==='chess') || !player.hasFriend()) return 2;
if(game.hasPlayer(current=>{ if(game.hasPlayer(current=>{
@ -1844,12 +1885,12 @@ game.import('card',function(lib,game,ui,get,ai,_status){
return num+get.value(i,player); return num+get.value(i,player);
},0); },0);
}, },
target:(player,target)=>{ target:(player,target,card)=>{
let targets=get.copy(ui.selected.targets); let targets=get.copy(ui.selected.targets);
if(_status.event.preTarget) targets.add(_status.event.preTarget); if(_status.event.preTarget) targets.add(_status.event.preTarget);
if(targets.length){ if(targets.length){
let preTarget=targets.lastItem,pre=_status.event.getTempCache('jiedao_result',preTarget); let preTarget=targets.lastItem,pre=_status.event.getTempCache('jiedao_result',preTarget.playerid);
if(pre&&pre.target.isIn()) return target===pre.target?pre.eff:0; if(pre&&pre.card===card&&pre.target.isIn()) return target===pre.target?pre.eff:0;
return get.effect(target,{name:'sha'},preTarget,player)/get.attitude(player,target); return get.effect(target,{name:'sha'},preTarget,player)/get.attitude(player,target);
} }
let arms=(target.hasSkillTag('noe')?0.32:-0.15)*target.getEquips(1).reduce((num,i)=>{ let arms=(target.hasSkillTag('noe')?0.32:-0.15)*target.getEquips(1).reduce((num,i)=>{
@ -1865,7 +1906,8 @@ game.import('card',function(lib,game,ui,get,ai,_status){
},-100); },-100);
if(!addTar) return arms; if(!addTar) return arms;
sha/=get.attitude(player,target); sha/=get.attitude(player,target);
_status.event.putTempCache('jiedao_result',target,{ _status.event.putTempCache('jiedao_result',target.playerid,{
card:card,
target:addTar, target:addTar,
eff:sha eff:sha
}); });

View File

@ -162,11 +162,11 @@ game.import('card',function(lib,game,ui,get,ai,_status){
ai:{ ai:{
order:9, order:9,
value:function(card,player){ value:function(card,player){
if(player.getEquips(1).contains(card)) return 0; if(player.getEquips(1).contains(card)) return 0.4;
return 4; return 4;
}, },
equipValue:function(card,player){ equipValue:function(card,player){
if(player.getCards('e').contains(card)) return 0; if(player.getCards('e').contains(card)) return 0.4;
return -get.value(player.getCards('e')); return -get.value(player.getCards('e'));
}, },
basic:{ basic:{
@ -226,11 +226,17 @@ game.import('card',function(lib,game,ui,get,ai,_status){
ai:{ ai:{
order:9, order:9,
equipValue:function(card,player){ equipValue:function(card,player){
if(get.position(card)=='e') return -2; if(get.position(card)=='e'){
if(player.hasSex('male')) return -7;
return 0;
}
return 2; return 2;
}, },
value:function(card,player){ value:function(card,player){
if(player.getEquips(2).contains(card)) return -3; if(player.getEquips(2).contains(card)){
if(player.hasSex('male')) return -8;
return 0;
}
return 3; return 3;
}, },
basic:{ basic:{
@ -260,11 +266,11 @@ game.import('card',function(lib,game,ui,get,ai,_status){
ai:{ ai:{
order:9, order:9,
equipValue:function(card,player){ equipValue:function(card,player){
if(get.position(card)=='e') return -1; if(get.position(card)=='e') return -8;
return 1; return 1;
}, },
value:function(card,player){ value:function(card,player){
if(player.getEquips(2).contains(card)) return -2.5; if(player.getEquips(2).contains(card)) return -10;
return 2.5; return 2.5;
}, },
basic:{ basic:{

View File

@ -397,7 +397,10 @@ game.import('card',function(lib,game,ui,get,ai,_status){
return 2; return 2;
}, },
value:function(card,player){ value:function(card,player){
if(player.getEquips(1).contains(card)) return -1.5; if(player.getEquips(1).contains(card)){
if(player.hasSkillTag('noh')) return 0;
return -3.5;
}
return 1.5; return 1.5;
}, },
basic:{ basic:{
@ -436,7 +439,7 @@ game.import('card',function(lib,game,ui,get,ai,_status){
return 2; return 2;
}, },
value:function(card,player){ value:function(card,player){
if(player.getEquips(1).contains(card)) return -3; if(player.getEquips(1).contains(card)) return -3.5;
return 3; return 3;
}, },
basic:{ basic:{
@ -471,11 +474,11 @@ game.import('card',function(lib,game,ui,get,ai,_status){
ai:{ ai:{
order:9, order:9,
equipValue:function(card,player){ equipValue:function(card,player){
if(get.position(card)=='e') return -1; if(get.position(card)=='e') return -7;
return 1; return 1;
}, },
value:function(card,player){ value:function(card,player){
if(player.getEquips(2).contains(card)) return -2.5; if(player.getEquips(2).contains(card)) return -9;
return 2.5; return 2.5;
}, },
basic:{ basic:{

View File

@ -372,10 +372,21 @@ game.import('character',function(lib,game,ui,get,ai,_status){
} }
}, },
ai:{ ai:{
order:1, order:function(item,player){
if(player.hasCard((i)=>{
return get.value(i)>Math.max(6,9-player.hp);
},'he')) return 1;
return 10;
},
result:{ result:{
player:1 player:1
}, },
nokeep:true,
skillTagFilter:function(player,tag,arg){
if(tag==='nokeep') return (!arg||arg&&arg.card&&get.name(arg.card)==='tao')&&player.isPhaseUsing()&&player.countSkill('dczhiheng')<1+player.getStorage('dczhiheng_hit').length&&player.hasCard((card)=>{
return get.name(card)!=='tao';
},'h');
},
threaten:1.55 threaten:1.55
}, },
}, },

View File

@ -5440,7 +5440,7 @@ game.import('character',function(lib,game,ui,get,ai,_status){
}, },
effect:{ effect:{
player:(card,player,target)=>{ player:(card,player,target)=>{
if(player.hasSkill('rewansha')&&target.hp<=1&&get.tag(card,'damage')) return [1,0,1.5,-1.5]; if(target&&player.hasSkill('rewansha')&&target.hp<=1&&get.tag(card,'damage')) return [1,0,1.5,-1.5];
} }
} }
} }

View File

@ -5399,11 +5399,11 @@ game.import('character',function(lib,game,ui,get,ai,_status){
effect:{ effect:{
target:function(card,player,target){ target:function(card,player,target){
if(player._jsrgzhenqiao_aiChecking) return; if(player._jsrgzhenqiao_aiChecking) return;
if(target==player&&get.subtype(card)=='equip1'&&!player.getEquip(1)){ if(target===player&&get.subtype(card)==='equip1'&&!player.getEquip(1)){
player._jsrgzhenqiao_aiChecking=true; if(card.name!=='zhuge'||target.getCardUsable('sha')||!target.needsToDiscard()) return;
var eff=get.effect(target,card,player,player); if(target.countCards('hs',i=>{
delete player._jsrgzhenqiao_aiChecking; return get.name(i)==='sha'&&lib.filter.cardEnabled(i,target);
if(eff<3) return 'zerotarget'; })>1) return 'zeroplayertarget';
} }
} }
} }

View File

@ -47,10 +47,7 @@ new Promise(resolve => {
/** /**
* @type { Promise<import('../noname.js')> } * @type { Promise<import('../noname.js')> }
*
* game.js不是一个模块所以导入的路径是从html文件开始算起的
*/ */
// @ts-ignore
const module = import('../noname.js'); const module = import('../noname.js');
module.then(({ ai, game, get, lib, _status, ui, boot }) => { module.then(({ ai, game, get, lib, _status, ui, boot }) => {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 553 KiB

After

Width:  |  Height:  |  Size: 534 KiB

View File

@ -13357,7 +13357,13 @@ game.import('mode',function(lib,game,ui,get,ai,_status){
var target=targets.shift(); var target=targets.shift();
event.target=target; event.target=target;
source.line(target,'green'); source.line(target,'green');
target.chooseBool('是否响应'+get.translation(source)+'发起的【拉拢人心】?','将势力改为'+event.text).set('choice',Math.random()<=0.98);//反骨[doge] target.chooseBool('是否响应'+get.translation(source)+'发起的【拉拢人心】?','将势力改为'+event.text).set('ai',_status.event.choice).set('choice',function(){
let fs=target.getFriends(true).length;
if(game.players.length<=2*fs) return false;
if(source.getFriends(true).length+fs>game.players.length/2) return true;
if(target.isDamaged()||target.countCards('h')<4) return false;
return true;
}());
'step 6' 'step 6'
if(result.bool){ if(result.bool){
target.chat('加入'); target.chat('加入');

View File

@ -7,11 +7,17 @@ import { GNC as gnc } from '../gnc/index.js';
import { Uninstantable } from "../util/index.js"; import { Uninstantable } from "../util/index.js";
export class Basic extends Uninstantable { export class Basic extends Uninstantable {
/**
* @param { (
* button: import('../library/index.js').Button,
* buttons?: import('../library/index.js').Button[]
* ) => number } check
*/
static chooseButton(check) { static chooseButton(check) {
var event = _status.event; const event = _status.event;
var i, j, range, buttons, buttons2; let i, j, range, buttons, buttons2;
var ok = false, forced = event.forced; let ok = false, forced = event.forced;
var iwhile = 100; let iwhile = 100;
while (iwhile--) { while (iwhile--) {
range = get.select(event.selectButton); range = get.select(event.selectButton);
if (ui.selected.buttons.length >= range[0]) { if (ui.selected.buttons.length >= range[0]) {
@ -29,10 +35,10 @@ export class Basic extends Uninstantable {
return ok; return ok;
} }
buttons2 = buttons.slice(0); buttons2 = buttons.slice(0);
var ix = 0; let ix = 0;
var checkix = check(buttons[0], buttons2); let checkix = check(buttons[0], buttons2);
for (i = 1; i < buttons.length; i++) { for (i = 1; i < buttons.length; i++) {
var checkixtmp = check(buttons[i], buttons2); let checkixtmp = check(buttons[i], buttons2);
if (checkixtmp > checkix) { if (checkixtmp > checkix) {
ix = i; ix = i;
checkix = checkixtmp; checkix = checkixtmp;
@ -57,12 +63,19 @@ export class Basic extends Uninstantable {
} }
} }
} }
/**
* @param { (
* card?: import('../library/index.js').Card,
* cards?: import('../library/index.js').Card[]
* ) => number } check
* @returns { boolean | undefined }
*/
static chooseCard(check) { static chooseCard(check) {
var event = _status.event; const event = _status.event;
if (event.filterCard == undefined) return (check() > 0); if (event.filterCard == undefined) return (check() > 0);
var i, j, range, cards, cards2, skills, check, effect; let i, j, range, cards, cards2, skills, effect;
var ok = false, forced = event.forced; let ok = false, forced = event.forced;
var iwhile = 100; let iwhile = 100;
while (iwhile--) { while (iwhile--) {
range = get.select(event.selectCard); range = get.select(event.selectCard);
if (ui.selected.cards.length >= range[0]) { if (ui.selected.cards.length >= range[0]) {
@ -80,6 +93,7 @@ export class Basic extends Uninstantable {
} }
cards = get.selectableCards(); cards = get.selectableCards();
if (!_status.event.player._noSkill) { if (!_status.event.player._noSkill) {
// @ts-ignore
cards = cards.concat(get.skills()); cards = cards.concat(get.skills());
} }
if (cards.length == 0) { if (cards.length == 0) {
@ -127,12 +141,18 @@ export class Basic extends Uninstantable {
} }
} }
} }
/**
* @param { (
* target?: import('../library/index.js').Player,
* targets?: import('../library/index.js').Player[]
* ) => number } check
*/
static chooseTarget(check) { static chooseTarget(check) {
var event = _status.event; const event = _status.event;
if (event.filterTarget == undefined) return (check() > 0); if (event.filterTarget == undefined) return (check() > 0);
var i, j, range, targets, targets2, effect; let i, j, range, targets, targets2, effect;
var ok = false, forced = event.forced; let ok = false, forced = event.forced;
var iwhile = 100; let iwhile = 100;
while (iwhile--) { while (iwhile--) {
range = get.select(event.selectTarget); range = get.select(event.selectTarget);
if (ui.selected.targets.length >= range[0]) { if (ui.selected.targets.length >= range[0]) {
@ -158,10 +178,10 @@ export class Basic extends Uninstantable {
// targets.sort(function(a,b){ // targets.sort(function(a,b){
// return check(b)-check(a); // return check(b)-check(a);
// }); // });
var ix = 0; let ix = 0;
var checkix = check(targets[0], targets2); let checkix = check(targets[0], targets2);
for (i = 1; i < targets.length; i++) { for (i = 1; i < targets.length; i++) {
var checkixtmp = check(targets[i], targets2); let checkixtmp = check(targets[i], targets2);
if (checkixtmp > checkix) { if (checkixtmp > checkix) {
ix = i; ix = i;
checkix = checkixtmp; checkix = checkixtmp;

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
import { userAgent, Uninstantable } from "../util/index.js"; import { userAgent, Uninstantable, GeneratorFunction, AsyncFunction } from "../util/index.js";
import { AI as ai } from '../ai/index.js'; import { AI as ai } from '../ai/index.js';
import { Game as game } from '../game/index.js'; import { Game as game } from '../game/index.js';
import { Library as lib } from '../library/index.js'; import { Library as lib } from '../library/index.js';
@ -1832,12 +1832,65 @@ export class Get extends Uninstantable {
return Math.sqrt(dx * dx + dy * dy); return Math.sqrt(dx * dx + dy * dy);
} }
static xyDistance(from, to) { return Math.sqrt((from[0] - to[0]) * (from[0] - to[0]) + (from[1] - to[1]) * (from[1] - to[1])) } static xyDistance(from, to) { return Math.sqrt((from[0] - to[0]) * (from[0] - to[0]) + (from[1] - to[1]) * (from[1] - to[1])) }
/**
* @overload
* @returns { void }
*/
/**
* @overload
* @param { string } obj
* @returns { 'position' | 'natures' | 'nature' }
*/
/**
* @overload
* @param { import('../library/index.js').Player[] } obj
* @returns { 'players' }
*/
/**
* @overload
* @param { import('../library/index.js').Card[] } obj
* @returns { 'cards' }
*/
/**
* @overload
* @param { [number, number] } obj
* @returns { 'select' }
*/
/**
* @overload
* @param { [number, number, number, number] } obj
* @returns { 'divposition' }
*/
/**
* @overload
* @param { import('../library/index.js').Button } obj
* @returns { 'button' }
*/
/**
* @overload
* @param { import('../library/index.js').Card } obj
* @returns { 'card' }
*/
/**
* @overload
* @param { import('../library/index.js').Player } obj
* @returns { 'player' }
*/
/**
* @overload
* @param { import('../library/index.js').Dialog } obj
* @returns { 'dialog' }
*/
/**
* @overload
* @param { import('../library/index.js').GameEvent | import('../library/index.js').GameEventPromise } obj
* @returns { 'event' }
*/
static itemtype(obj) { static itemtype(obj) {
var i, j;
if (typeof obj == 'string') { if (typeof obj == 'string') {
if (obj.length <= 5) { if (obj.length <= 5) {
var bool = true; let bool = true;
for (i = 0; i < obj.length; i++) { for (let i = 0; i < obj.length; i++) {
if (/h|e|j|s|x/.test(obj[i]) == false) { if (/h|e|j|s|x/.test(obj[i]) == false) {
bool = false; break; bool = false; break;
} }
@ -1847,42 +1900,26 @@ export class Get extends Uninstantable {
if (obj.includes(lib.natureSeparator) && obj.split(lib.natureSeparator).every(n => lib.nature.has(n))) return 'natures'; if (obj.includes(lib.natureSeparator) && obj.split(lib.natureSeparator).every(n => lib.nature.has(n))) return 'natures';
if (lib.nature.has(obj)) return 'nature'; if (lib.nature.has(obj)) return 'nature';
} }
if (Array.isArray(obj) && obj.length) { if (Array.isArray(obj) && obj.length > 0) {
var isPlayers = true; if (obj.every(p => p instanceof lib.element.Player)) return 'players';
for (i = 0; i < obj.length; i++) { if (obj.every(p => p instanceof lib.element.Card)) return 'cards';
if (get.itemtype(obj[i]) != 'player') { isPlayers = false; break; }
}
if (isPlayers) return 'players';
var isCards = true;
for (i = 0; i < obj.length; i++) {
if (get.itemtype(obj[i]) != 'card') { isCards = false; break; }
}
if (isCards) return 'cards';
if (obj.length == 2) { if (obj.length == 2) {
if (typeof obj[0] == 'number' && typeof obj[1] == 'number') { if (typeof obj[0] == 'number' && typeof obj[1] == 'number') {
if (obj[0] <= obj[1] || obj[1] <= -1) return 'select'; if (obj[0] <= obj[1] || obj[1] <= -1) return 'select';
} }
} }
if (obj.length == 4) { if (obj.length == 4) {
var isPosition = true; if (obj.every(p => typeof p == 'number')) {
for (i = 0; i < obj.length; i++) { return 'divposition';
if (typeof obj[i] != 'number') { isPosition = false; break; }
} }
if (isPosition) return 'divposition';
} }
} }
if (get.objtype(obj) == 'div') { if (obj instanceof lib.element.Button) return 'button';
if (obj.classList.contains('button')) return 'button'; if (obj instanceof lib.element.Card) return 'card';
if (obj.classList.contains('card')) return 'card'; if (obj instanceof lib.element.Player) return 'player';
if (obj.classList.contains('player')) return 'player'; if (obj instanceof lib.element.Dialog) return 'dialog';
if (obj.classList.contains('dialog')) return 'dialog'; if (obj instanceof lib.element.GameEvent ||
} obj instanceof lib.element.GameEventPromise) return 'event';
if (get.is.object(obj)) {
if (obj.isMine == lib.element.GameEvent.prototype.isMine) return 'event';
}
} }
static equipNum(card) { static equipNum(card) {
if (get.type(card) == 'equip') { if (get.type(card) == 'equip') {
@ -2172,11 +2209,15 @@ export class Get extends Uninstantable {
return lib.card[name]; return lib.card[name];
} }
} }
/**
* @param { number | [number, number] | (()=>[number, number]) } [select]
* @returns { [number, number] }
*/
static select(select) { static select(select) {
if (typeof select == 'number') return [select, select];
if (get.itemtype(select) == 'select') return select;
if (typeof select == 'function') return get.select(select()); if (typeof select == 'function') return get.select(select());
return [1, 1] else if (typeof select == 'number') return [select, select];
else if (select && get.itemtype(select) == 'select') return select;
return [1, 1];
} }
static card(original) { static card(original) {
if (_status.event.skill) { if (_status.event.skill) {
@ -2428,6 +2469,10 @@ export class Get extends Uninstantable {
result = handleZero(result); result = handleZero(result);
return result; return result;
} }
/**
* @param {((a: import('../library/index.js').Button, b: import('../library/index.js').Button) => number)} [sort] 排序函数
* @returns { import('../library/index.js').Button[] }
*/
static selectableButtons(sort) { static selectableButtons(sort) {
if (!_status.event.player) return []; if (!_status.event.player) return [];
var buttons = _status.event.dialog.buttons; var buttons = _status.event.dialog.buttons;
@ -2443,6 +2488,10 @@ export class Get extends Uninstantable {
} }
return selectable; return selectable;
} }
/**
* @param {((a: import('../library/index.js').Card, b: import('../library/index.js').Card) => number)} [sort] 排序函数
* @returns { import('../library/index.js').Card[] }
*/
static selectableCards(sort) { static selectableCards(sort) {
if (!_status.event.player) return []; if (!_status.event.player) return [];
var cards = _status.event.player.getCards('hes'); var cards = _status.event.player.getCards('hes');
@ -2458,6 +2507,9 @@ export class Get extends Uninstantable {
} }
return selectable; return selectable;
} }
/**
* @returns { string[] } 技能名数组
*/
static skills() { static skills() {
var skills = []; var skills = [];
if (ui.skills) { if (ui.skills) {
@ -2532,6 +2584,10 @@ export class Get extends Uninstantable {
} }
return list; return list;
} }
/**
* @param {((a: import('../library/index.js').Player, b: import('../library/index.js').Player) => number)} [sort] 排序函数
* @returns { import('../library/index.js').Player[] }
*/
static selectableTargets(sort) { static selectableTargets(sort) {
var selectable = []; var selectable = [];
var players = game.players.slice(0); var players = game.players.slice(0);

View File

@ -1,10 +1,14 @@
/** /**
* @typedef {InstanceType<typeof lib.element.Player>} Player * @typedef { InstanceType<typeof lib.element.Player> } Player
* @typedef {InstanceType<typeof lib.element.Card>} Card * @typedef { InstanceType<typeof lib.element.Card> } Card
* @typedef {InstanceType<typeof lib.element.VCard>} VCard * @typedef { InstanceType<typeof lib.element.VCard> } VCard
* @typedef {InstanceType<typeof lib.element.GameEvent>} GameEvent * @typedef { InstanceType<typeof lib.element.Button> } Button
* @typedef {InstanceType<typeof lib.element.GameEventPromise>} GameEventPromise * @typedef { InstanceType<typeof lib.element.Dialog> } Dialog
* @typedef {InstanceType<typeof lib.element.NodeWS>} NodeWS * @typedef { InstanceType<typeof lib.element.GameEvent> } GameEvent
* @typedef { InstanceType<typeof lib.element.GameEvent> & InstanceType<typeof lib.element.GameEventPromise> & typeof Promise<typeof lib.element.GameEvent> } GameEventPromise
* @typedef { InstanceType<typeof lib.element.NodeWS> } NodeWS
* @typedef { 'male' | 'female' | 'dobule' | 'none' } Sex
* @typedef { [Sex, string, number | string, string[], any[]] } Character
*/ */
import { nonameInitialized, assetURL, userAgent, Uninstantable, GeneratorFunction, AsyncFunction } from "../util/index.js"; import { nonameInitialized, assetURL, userAgent, Uninstantable, GeneratorFunction, AsyncFunction } from "../util/index.js";
import { AI as ai } from '../ai/index.js'; import { AI as ai } from '../ai/index.js';
@ -33,6 +37,9 @@ export class Library extends Uninstantable {
static changeLog = []; static changeLog = [];
static updates = []; static updates = [];
static canvasUpdates = []; static canvasUpdates = [];
/**
* @type { import('../game/index.js').Video[] }
*/
static video = []; static video = [];
static skilllist = []; static skilllist = [];
static connectBanned = []; static connectBanned = [];
@ -78,6 +85,17 @@ export class Library extends Uninstantable {
static extensionPack = {}; static extensionPack = {};
static cardType = {}; static cardType = {};
static hook = { globalskill: {} }; static hook = { globalskill: {} };
/**
* @returns {never}
*/
static typeAnnotation() {
/**
* @type { import('../game/index.js').Videos[] }
*/
// @ts-ignore
this.videos;
throw new Error('Do not call this method');
}
//函数钩子 //函数钩子
static hooks = { static hooks = {
// 本体势力的颜色 // 本体势力的颜色
@ -20953,20 +20971,20 @@ export class Library extends Uninstantable {
var player = _status.event.player; var player = _status.event.player;
var event = _status.event.getParent(); var event = _status.event.getParent();
var getn = function (card) { var getn = function (card) {
if (player.hasSkill('tianbian') && get.suit(card) == 'heart') return 13 * (event.small ? -1 : 1); if (player.hasSkill('tianbian') && get.suit(card) == 'heart') return 13 * (Boolean(event.small) ? -1 : 1);
return get.number(card) * (event.small ? -1 : 1); return get.number(card) * (Boolean(event.small) ? -1 : 1);
} }
if (source && source != player) { if (source && source != player) {
if (get.attitude(player, source) > 1) { if (get.attitude(player, source) > 1) {
if (event.small) return getn(card) - get.value(card) / 2 + addi; if (Boolean(event.small)) return getn(card) - get.value(card) / 3 + addi;
return -getn(card) - get.value(card) / 2 + addi; return -getn(card) - get.value(card) / 3 + addi;
} }
if (event.small) return -getn(card) - get.value(card) / 2 + addi; if (Boolean(event.small)) return -getn(card) - get.value(card) / 5 + addi;
return getn(card) - get.value(card) / 2 + addi; return getn(card) - get.value(card) / 5 + addi;
} }
else { else {
if (event.small) return -getn(card) - get.value(card) / 2 + addi; if (Boolean(event.small)) return -getn(card) - get.value(card) / 5 + addi;
return getn(card) - get.value(card) / 2 + addi; return getn(card) - get.value(card) / 5 + addi;
} }
} }
next.setContent('chooseToCompareMultiple'); next.setContent('chooseToCompareMultiple');
@ -20987,18 +21005,15 @@ export class Library extends Uninstantable {
var event = _status.event.getParent(); var event = _status.event.getParent();
var to = (player == event.player ? event.target : event.player); var to = (player == event.player ? event.target : event.player);
var addi = (get.value(card) >= 8 && get.type(card) != 'equip') ? -6 : 0; var addi = (get.value(card) >= 8 && get.type(card) != 'equip') ? -6 : 0;
var friend = get.attitude(player, to) > 0;
if (card.name == 'du') addi -= 5; if (card.name == 'du') addi -= 5;
if (player == event.player) { if (player == event.player) {
if (event.small) { if (Boolean(event.small)) return -getn(card) - get.value(card) / (friend ? 4 : 5) + addi;
return -getn(card) - get.value(card) / 2 + addi; return getn(card) - get.value(card) / (friend ? 4 : 5) + addi;
}
return getn(card) - get.value(card) / 2 + addi;
} }
else { else {
if ((get.attitude(player, to) <= 0) == Boolean(event.small)) { if (friend == Boolean(event.small)) return getn(card) - get.value(card) / (friend ? 3 : 5) + addi;
return -getn(card) - get.value(card) / 2 + addi; return -getn(card) - get.value(card) / (friend ? 3 : 5) + addi;
}
return getn(card) - get.value(card) / 2 + addi;
} }
} }
next.setContent('chooseToCompare'); next.setContent('chooseToCompare');
@ -25338,20 +25353,20 @@ export class Library extends Uninstantable {
if (this.hasSkillTag('respondShan', true, null, true)) return true; if (this.hasSkillTag('respondShan', true, null, true)) return true;
return this.hasUsableCard('shan'); return this.hasUsableCard('shan');
} }
mayHaveSha(viewer, type, ignore) { mayHaveSha(viewer, type, ignore, rvt) {
if ((this.hp > 2 || !this.isZhu && this.hp > 1) && this.hasSkillTag('respondSha', true, type, true)) return true; //rvt: return value type 'count', 'odds', 'bool'(default)
let count = 0;
if ((this.hp > 2 || !this.isZhu && this.hp > 1) && this.hasSkillTag('respondSha', true, type, true)) {
if (rvt === 'count') count++;
else return true;
}
if (get.itemtype(viewer) !== 'player') viewer = _status.event.player; if (get.itemtype(viewer) !== 'player') viewer = _status.event.player;
let cards, selected = get.copy(ui.selected.cards); let cards, selected = get.copy(ui.selected.cards);
if (get.itemtype(ignore) === 'cards') selected.addArray(ignore); if (get.itemtype(ignore) === 'cards') selected.addArray(ignore);
else if (get.itemtype(ignore) === 'card') selected.add(ignore); else if (get.itemtype(ignore) === 'card') selected.add(ignore);
/*if(this===viewer||get.itemtype(viewer)==='player'&&viewer.hasSkillTag('viewHandcard',null,this,true)) cards=this.getCards('h'); if (this === viewer || get.itemtype(viewer) == 'player') cards = this.getKnownCards(viewer);
else cards=this.getShownCards();*/ else cards = this.getShownCards();
if (this === viewer || get.itemtype(viewer) == 'player') { count += cards.filter(card => {
cards = this.getKnownCards(viewer);
} else {
cards = this.getShownCards();
}
if (cards.some(card => {
if (selected.includes(card)) return false; if (selected.includes(card)) return false;
let name = get.name(card, this); let name = get.name(card, this);
if (name == 'sha' || name == 'hufu' || name == 'yuchanqian') { if (name == 'sha' || name == 'hufu' || name == 'yuchanqian') {
@ -25360,25 +25375,36 @@ export class Library extends Uninstantable {
return true; return true;
} }
return false; return false;
})) return true; }).length;
if (count && rvt !== 'count') return true;
let hs = this.getCards('hs').filter(i => !cards.includes(i) && !selected.includes(i)).length; let hs = this.getCards('hs').filter(i => !cards.includes(i) && !selected.includes(i)).length;
if (hs === 0) return false; if (!hs) {
return Math.pow(hs + (this.isPhaseUsing() ? 6 : 4), 2) > 100 * _status.event.getRand('mayHaveSha'); if (rvt === 'count') return count;
return false;
}
if (rvt === 'count') {
if (this.isPhaseUsing()) return count + hs / 4;
return count + hs / 4.8;
}
if (this.isPhaseUsing()) count += Math.pow(2 + hs, 2) / 40;
else count += -1.5 * Math.log(1 - hs / 10);
if (rvt === 'odds') return Math.min(1, count);
return count > _status.event.getRand('mayHaveSha' + hs + this.playerid);
} }
mayHaveShan(viewer, type, ignore) { mayHaveShan(viewer, type, ignore, rvt) {
if ((this.hp > 2 || !this.isZhu && this.hp > 1) && this.hasSkillTag('respondShan', true, type, true)) return true; //rvt: return value type 'count', 'odds', 'bool'(default)
let count = 0;
if ((this.hp > 2 || !this.isZhu && this.hp > 1) && this.hasSkillTag('respondShan', true, type, true)) {
if (rvt === 'count') count++;
else return true;
}
if (get.itemtype(viewer) !== 'player') viewer = _status.event.player; if (get.itemtype(viewer) !== 'player') viewer = _status.event.player;
let cards, selected = get.copy(ui.selected.cards); let cards, selected = get.copy(ui.selected.cards);
if (get.itemtype(ignore) === 'cards') selected.addArray(ignore); if (get.itemtype(ignore) === 'cards') selected.addArray(ignore);
else if (get.itemtype(ignore) === 'card') selected.add(ignore); else if (get.itemtype(ignore) === 'card') selected.add(ignore);
/*if(this===viewer||get.itemtype(viewer)==='player'&&viewer.hasSkillTag('viewHandcard',null,this,true)) cards=this.getCards('h'); if (this === viewer || get.itemtype(viewer) == 'player') cards = this.getKnownCards(viewer);
else cards=this.getShownCards();*/ else cards = this.getShownCards();
if (this === viewer || get.itemtype(viewer) == 'player') { count += cards.filter(card => {
cards = this.getKnownCards(viewer);
} else {
cards = this.getShownCards();
}
if (cards.some(card => {
if (selected.includes(card)) return false; if (selected.includes(card)) return false;
let name = get.name(card, this); let name = get.name(card, this);
if (name === 'shan' || name === 'hufu') { if (name === 'shan' || name === 'hufu') {
@ -25387,10 +25413,21 @@ export class Library extends Uninstantable {
return true; return true;
} }
return false; return false;
})) return true; }).length;
if (count && rvt !== 'count') return true;
let hs = this.getCards('hs').filter(i => !cards.includes(i) && !selected.includes(i)).length; let hs = this.getCards('hs').filter(i => !cards.includes(i) && !selected.includes(i)).length;
if (hs === 0) return false; if (!hs) {
return Math.pow(hs + (this.isPhaseUsing() ? 3 : 5), 2) > 100 * _status.event.getRand('mayHaveShan'); if (rvt === 'count') return count;
return false;
}
if (rvt === 'count') {
if (this.isPhaseUsing()) return count + hs / 6;
return count + hs / 3.5;
}
if (this.isPhaseUsing()) count += -1.5 * Math.log(1 - hs / 10);
else count += 2 * hs / (5 + hs);
if (rvt === 'odds') return Math.min(1, count);
return count > _status.event.getRand('mayHaveShan' + hs + this.playerid);
} }
hasCard(name, position) { hasCard(name, position) {
if (typeof name == 'function') { if (typeof name == 'function') {
@ -27842,7 +27879,7 @@ export class Library extends Uninstantable {
} }
}, },
GameEvent: class { GameEvent: class {
/** @type { Promise<GameEvent> & GameEvent & GameEventPromise } */ /** @type { GameEventPromise } */
#promise; #promise;
/** /**
* @param {string} [name] * @param {string} [name]
@ -27861,11 +27898,11 @@ export class Library extends Uninstantable {
this.step = 0; this.step = 0;
this.finished = false; this.finished = false;
/** /**
* @type {(Promise<GameEvent> & GameEvent & GameEventPromise)[]} * @type {(GameEventPromise)[]}
*/ */
this.next = []; this.next = [];
/** /**
* @type {(Promise<GameEvent> & GameEvent & GameEventPromise)[]} * @type {(GameEventPromise)[]}
*/ */
this.after = []; this.after = [];
this.custom = { this.custom = {
@ -28647,7 +28684,7 @@ export class Library extends Uninstantable {
/** /**
* 事件转为Promise化 * 事件转为Promise化
* *
* @returns { Promise<GameEvent> & GameEvent & GameEventPromise } * @returns { GameEventPromise }
*/ */
toPromise() { toPromise() {
if (!this.#promise) { if (!this.#promise) {

View File

@ -6,8 +6,9 @@ export const status = {
clicked: false, clicked: false,
auto: false, auto: false,
/** /**
* @type {GameEvent} * @type {import('../library/index.js').GameEventPromise}
*/ */
// @ts-ignore
event: null, event: null,
ai: {}, ai: {},
lastdragchange: [], lastdragchange: [],
@ -15,6 +16,9 @@ export const status = {
dieClose: [], dieClose: [],
dragline: [], dragline: [],
dying: [], dying: [],
/**
* @type { import('../game/index.js').History[] }
*/
globalHistory: [{ globalHistory: [{
cardMove: [], cardMove: [],
custom: [], custom: [],
@ -32,6 +36,10 @@ export const status = {
renku: [], renku: [],
prehidden_skills: [], prehidden_skills: [],
postReconnect: {}, postReconnect: {},
/**
* @type { string | void }
*/
extension:undefined,
}; };
export const _status = status; export const _status = status;

View File

@ -14001,7 +14001,18 @@ export class UI extends Uninstantable {
static create = Create; static create = Create;
static click = Click; static click = Click;
static selected = { static selected = {
buttons: [], cards: [], targets: [] /**
* @type { import('../library/index.js').Button[]}
*/
buttons: [],
/**
* @type { import('../library/index.js').Card[]}
*/
cards: [],
/**
* @type { import('../library/index.js').Player[]}
*/
targets: []
} }
static refresh(node) { static refresh(node) {
void window.getComputedStyle(node, null).getPropertyValue("opacity"); void window.getComputedStyle(node, null).getPropertyValue("opacity");