From 99e249789b37e32939b25d312284d682a6197c83 Mon Sep 17 00:00:00 2001 From: kuangthree Date: Sat, 3 Feb 2024 12:25:27 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- noname/ai/basic.js | 10 ++++ noname/game/index.js | 6 +- noname/get/index.js | 73 +++++++++++------------ noname/library/cache/cacheContext.js | 61 +++++++++++++++---- noname/library/element/player.js | 89 ++++++++++++++++++---------- 5 files changed, 154 insertions(+), 85 deletions(-) diff --git a/noname/ai/basic.js b/noname/ai/basic.js index 9eed973a8..760175368 100644 --- a/noname/ai/basic.js +++ b/noname/ai/basic.js @@ -86,11 +86,13 @@ export class Basic extends Uninstantable { if (ui.selected.cards.length == 0) return true; j = 0; CacheContext.setCacheContext(new CacheContext()); + CacheContext.setInCacheEnvironment(true); for (i = 0; i < ui.selected.cards.length; i++) { effect = check(ui.selected.cards[i]); if (effect < 0) j -= Math.sqrt(-effect); else j += Math.sqrt(effect); } + CacheContext.setInCacheEnvironment(false); CacheContext.removeCacheContext(); return (j > 0); } @@ -109,6 +111,7 @@ export class Basic extends Uninstantable { // }); var ix = 0; CacheContext.setCacheContext(new CacheContext()); + CacheContext.setInCacheEnvironment(true); var checkix = check(cards[0], cards2); for (i = 1; i < cards.length; i++) { var checkixtmp = check(cards[i], cards2); @@ -119,10 +122,12 @@ export class Basic extends Uninstantable { } if (check(cards[ix]) <= 0) { if (!forced || ok) { + CacheContext.setInCacheEnvironment(false); CacheContext.removeCacheContext(); return ok; } } + CacheContext.setInCacheEnvironment(false); CacheContext.removeCacheContext(); if (typeof cards[ix] == 'string') { ui.click.skill(cards[ix]); @@ -168,11 +173,13 @@ export class Basic extends Uninstantable { if (range[1] <= -1) { j = 0; CacheContext.setCacheContext(new CacheContext()); + CacheContext.setInCacheEnvironment(true); for (i = 0; i < ui.selected.targets.length; i++) { effect = check(ui.selected.targets[i]); if (effect < 0) j -= Math.sqrt(-effect); else j += Math.sqrt(effect); } + CacheContext.setInCacheEnvironment(false); CacheContext.removeCacheContext(); return (j > 0); } @@ -189,6 +196,7 @@ export class Basic extends Uninstantable { // }); let ix = 0; CacheContext.setCacheContext(new CacheContext()); + CacheContext.setInCacheEnvironment(true); let checkix = check(targets[0], targets2); for (i = 1; i < targets.length; i++) { let checkixtmp = check(targets[i], targets2); @@ -199,10 +207,12 @@ export class Basic extends Uninstantable { } if (check(targets[ix]) <= 0) { if (!forced || ok) { + CacheContext.setInCacheEnvironment(false); CacheContext.removeCacheContext(); return ok; } } + CacheContext.setInCacheEnvironment(false); CacheContext.removeCacheContext(); targets[ix].classList.add('selected'); ui.selected.targets.add(targets[ix]); diff --git a/noname/game/index.js b/noname/game/index.js index 0148f631e..00c61270c 100644 --- a/noname/game/index.js +++ b/noname/game/index.js @@ -7496,7 +7496,7 @@ export class Game extends Uninstantable { const argumentArray = Array.from(arguments), name = argumentArray[argumentArray.length - 2]; let skills = argumentArray[argumentArray.length - 1]; if (typeof skills.getModableSkills == 'function') { - skills = skills.getModableSkills(_status.event.useCache === true); + skills = skills.getModableSkills(); } else if (typeof skills.getSkills == 'function') { skills = skills.getSkills().concat(lib.skill.global); game.expandSkills(skills); @@ -7510,8 +7510,8 @@ export class Game extends Uninstantable { skills.forEach(value => { var mod = get.info(value).mod[name]; if (!mod) return; - const result = mod.apply(this, arg); - if (typeof arg[arg.length - 1] != 'object' && result != undefined) arg[arg.length - 1] = result; + const result = mod.call(this,...arg); + if (result != undefined && typeof arg[arg.length - 1] != 'object') arg[arg.length - 1] = result; }); return arg[arg.length - 1]; } diff --git a/noname/get/index.js b/noname/get/index.js index cac221cc3..1d61b6750 100644 --- a/noname/get/index.js +++ b/noname/get/index.js @@ -2866,8 +2866,10 @@ export class Get extends Uninstantable { if (!lib.characterInitFilter[node.name]) return true; return lib.characterInitFilter[node.name](tag) !== false; }); - const str = initFilters.reduce((strx, stry) => strx + lib.InitFilter[stry] + '
').slice(0, -4); - uiintro.addText(str); + if(initFilters.length){ + const str = initFilters.reduce((strx, stry) => strx + lib.InitFilter[stry] + '
').slice(0, -4); + uiintro.addText(str); + } } if (!node.noclick) { @@ -4028,7 +4030,7 @@ export class Get extends Uninstantable { if (!from || !to) return 0; from = from._trueMe || from; arguments[0] = from; - var att = get.rawAttitude.apply(this, arguments); + var att = CacheContext.requireCacheContext().get.rawAttitude.apply(this, arguments); if (from.isMad()) att = -att; if (to.isMad() && att > 0) { if (to.identity == 'zhu') { @@ -4192,11 +4194,8 @@ export class Get extends Uninstantable { return 1; } static cacheOrder(item){ - let cache = CacheContext.getCacheContext(); - if(cache){ - return cache.get.order(item); - } - return get.order(item); + let cache = CacheContext.requireCacheContext(); + return cache.get.order(item); } static order(item) { let cache = CacheContext.requireCacheContext(); @@ -4235,13 +4234,11 @@ export class Get extends Uninstantable { return result; } static cacheEffectUse(target, card, player, player2, isLink){ - let cache = CacheContext.getCacheContext(); - if(cache){ - return cache.get.effect_use(target,card,player,player2,isLink); - } - return get.effect_use(target,card,player,player2,isLink); + let cache = CacheContext.requireCacheContext(); + return cache.get.effect_use(target,card,player,player2,isLink); } static effect_use(target, card, player, player2, isLink) { + let cache = CacheContext.requireCacheContext(); var event = _status.event; var eventskill = null; if (player == undefined) player = _status.event.player; @@ -4262,7 +4259,7 @@ export class Get extends Uninstantable { info.changeTarget(player, targets); var eff = 0; for (var i of targets) { - eff += get.effect(i, card, player, player2, isLink); + eff += cache.get.effect(i, card, player, player2, isLink); } return eff; } @@ -4280,10 +4277,10 @@ export class Get extends Uninstantable { for (var i = 0; i < skills1.length; i++) { temp1 = get.info(skills1[i]).ai; if (temp1 && typeof temp1.effect == 'object' && typeof temp1.effect.player_use == 'function') { - temp1 = temp1.effect.player_use(card, player, target, result1, isLink); + temp1 = cache.delegate(temp1.effect).player_use(card, player, target, result1, isLink); } else if (temp1 && typeof temp1.effect == 'object' && typeof temp1.effect.player == 'function') { - temp1 = temp1.effect.player(card, player, target, result1, isLink); + temp1 = cache.delegate(temp1.effect).player(card, player, target, result1, isLink); } else temp1 = undefined; if (typeof temp1 == 'object') { @@ -4323,7 +4320,7 @@ export class Get extends Uninstantable { target: target, skill: skills2[i], isLink: isLink, - })) temp2 = temp2.effect(card, player, target, result2, isLink); + })) temp2 = cache.delegate(temp2).effect(card, player, target, result2, isLink); else temp2 = undefined; } else if (temp2 && typeof temp2.effect == 'object' && typeof temp2.effect.target_use == 'function') { @@ -4332,7 +4329,7 @@ export class Get extends Uninstantable { target: target, skill: skills2[i], isLink: isLink, - })) temp2 = temp2.effect.target_use(card, player, target, result2, isLink); + })) temp2 = cache.delegate(temp2.effect).target_use(card, player, target, result2, isLink); else temp2 = undefined; } else if (temp2 && typeof temp2.effect == 'object' && typeof temp2.effect.target == 'function') { @@ -4341,7 +4338,7 @@ export class Get extends Uninstantable { target: target, skill: skills2[i], isLink: isLink, - })) temp2 = temp2.effect.target(card, player, target, result2, isLink); + })) temp2 = cache.delegate(temp2.effect).target(card, player, target, result2, isLink); else temp2 = undefined; } else temp2 = undefined; @@ -4386,7 +4383,7 @@ export class Get extends Uninstantable { result2 += temp02; result1 += temp01; if (typeof card == 'object' && !result.ignoreStatus) { - if (get.attitude(player, target) < 0) { + if (cache.get.attitude(player, target) < 0) { result2 *= Math.sqrt(threaten); } else { @@ -4394,7 +4391,7 @@ export class Get extends Uninstantable { } if (target.hp == 1) result2 *= 2.5; if (target.hp == 2) result2 *= 1.8; - let countTargetCards = target.cacheCountCards('h'); + let countTargetCards = target.countCards('h'); if (countTargetCards == 0) { if (get.tag(card, 'respondSha') || get.tag(card, 'respondShan')) { result2 *= 1.7; @@ -4419,32 +4416,30 @@ export class Get extends Uninstantable { if (zerotarget) result2 = 0; var final = 0; if (player2) { - final = (result1 * get.attitude(player2, player) + (target ? result2 * get.attitude(player2, target) : 0)); + final = (result1 * cache.get.attitude(player2, player) + (target ? result2 * cache.get.attitude(player2, target) : 0)); } - else final = (result1 * get.attitude(player, player) + (target ? result2 * get.attitude(player, target) : 0)); + else final = (result1 * cache.get.attitude(player, player) + (target ? result2 * cache.get.attitude(player, target) : 0)); if (!isLink && get.tag(card, 'natureDamage') && !zerotarget) { var info = get.info(card); if (!info || !info.ai || !info.ai.canLink) { if (target.isLinked()) game.players.forEach(function (current) { - if (current != target && current.isLinked()) final += get.effect(current, card, player, player2, true); + if (current != target && current.isLinked()) final += cache.get.effect(current, card, player, player2, true); }); } else if (info.ai.canLink(player, target, card)) { game.players.forEach(function (current) { - if (current != target && current.isLinked()) final += get.effect(current, card, player, player2, true); + if (current != target && current.isLinked()) final += cache.get.effect(current, card, player, player2, true); }); } } return final; } static cacheEffect(target, card, player, player2, isLink){ - let cache = CacheContext.getCacheContext(); - if(cache){ - return cache.get.effect(target,card,player,player2,isLink); - } - return get.effect(target,card,player,player2,isLink); + let cache = CacheContext.requireCacheContext(); + return cache.get.effect(target,card,player,player2,isLink); } static effect(target, card, player, player2, isLink) { + let cache = CacheContext.requireCacheContext(); var event = _status.event; var eventskill = null; if (player == undefined) player = _status.event.player; @@ -4505,7 +4500,7 @@ export class Get extends Uninstantable { game.expandSkills(skills2); for (var i = 0; i < skills2.length; i++) { temp2 = get.info(skills2[i]).ai; - if (temp2 && temp2.threaten) temp3 = temp2.threaten; + if (temp2 && temp2.threaten) temp3 = cache.delegate(temp2).threaten; else temp3 = undefined; if (temp2 && typeof temp2.effect == 'function') { if (!player.hasSkillTag('ignoreSkill', true, { @@ -4513,7 +4508,7 @@ export class Get extends Uninstantable { target: target, skill: skills2[i], isLink: isLink, - })) temp2 = temp2.effect(card, player, target, result2, isLink); + })) temp2 = cache.delegate(temp2).effect(card, player, target, result2, isLink); else temp2 = undefined; } else if (temp2 && typeof temp2.effect == 'object' && typeof temp2.effect.target == 'function') { @@ -4522,7 +4517,7 @@ export class Get extends Uninstantable { target: target, skill: skills2[i], isLink: isLink, - })) temp2 = temp2.effect.target(card, player, target, result2, isLink); + })) temp2 = cache.delegate(temp2.effect).target(card, player, target, result2, isLink); else temp2 = undefined; } else temp2 = undefined; @@ -4567,7 +4562,7 @@ export class Get extends Uninstantable { result2 += temp02; result1 += temp01; if (typeof card == 'object' && !result.ignoreStatus) { - if (get.attitude(player, target) < 0) { + if (cache.get.attitude(player, target) < 0) { result2 *= Math.sqrt(threaten); } else { @@ -4576,7 +4571,7 @@ export class Get extends Uninstantable { // *** continue here *** if (target.hp == 1) result2 *= 2.5; if (target.hp == 2) result2 *= 1.8; - let targetCountCards = target.cacheCountCards('h'); + let targetCountCards = target.countCards('h'); if (targetCountCards == 0) { if (get.tag(card, 'respondSha') || get.tag(card, 'respondShan')) { result2 *= 1.7; @@ -4601,19 +4596,19 @@ export class Get extends Uninstantable { if (zerotarget) result2 = 0; var final = 0; if (player2) { - final = (result1 * get.attitude(player2, player) + (target ? result2 * get.attitude(player2, target) : 0)); + final = (result1 * cache.get.attitude(player2, player) + (target ? result2 * cache.get.attitude(player2, target) : 0)); } - else final = (result1 * get.attitude(player, player) + (target ? result2 * get.attitude(player, target) : 0)); + else final = (result1 * cache.get.attitude(player, player) + (target ? result2 * cache.get.attitude(player, target) : 0)); if (!isLink && get.tag(card, 'natureDamage') && !zerotarget) { var info = get.info(card); if (!info || !info.ai || !info.ai.canLink) { if (target.isLinked()) game.players.forEach(function (current) { - if (current != target && current.isLinked()) final += get.effect(current, card, player, player2, true); + if (current != target && current.isLinked()) final += cache.get.effect(current, card, player, player2, true); }); } else if (info.ai.canLink(player, target, card)) { game.players.forEach(function (current) { - if (current != target && current.isLinked()) final += get.effect(current, card, player, player2, true); + if (current != target && current.isLinked()) final += cache.get.effect(current, card, player, player2, true); }); } } diff --git a/noname/library/cache/cacheContext.js b/noname/library/cache/cacheContext.js index 702d22203..5bb071023 100644 --- a/noname/library/cache/cacheContext.js +++ b/noname/library/cache/cacheContext.js @@ -12,7 +12,12 @@ export class CacheContext{ this.lib = this.createCacheProxy(Library); this.game = this.createCacheProxy(Game); this.get = this.createCacheProxy(Get); - this.sourceMap = {}; + this.sourceMap = new Map(); + this.storageMap = new Map(); + } + + static setInCacheEnvironment(cache){ + _status.cacheEnvironment = cache; } static setCacheContext(context){ @@ -36,14 +41,43 @@ export class CacheContext{ } delegate(source){ - if(source === null || source === undefined)return null; - if(typeof source.getCacheKey !== 'function')return source; - let cacheKey = source.getCacheKey(); - if(this.sourceMap[cacheKey]){ - return this.sourceMap[cacheKey]; + if(source === null || source === undefined)return source; + if(source._cacheDelegateSource)return source; + let proxy = this.sourceMap.get(source); + if(proxy){ + return proxy; } - this.sourceMap[cacheKey] = this.createCacheProxy(source); - return this.sourceMap[cacheKey]; + proxy = this.createCacheProxy(source); + this.sourceMap.set(source,proxy); + return proxy; + } + + static inject(source,methods){ + if(source == null || source === undefined)return null; + for(let method of methods){ + let func = source[method]; + if(typeof func != 'function')continue; + source[method] = function(){ + try{ + if(!_status.cacheEnvironment){ + return func.call(this,...arguments); + } + return CacheContext + .getCacheValueFromObject(CacheContext.requireCacheContext().requireStorage(this),method,arguments,this,func); + }catch(e){ + return func.call(this,...arguments); + } + } + } + } + + requireStorage(obj){ + let storage = this.storageMap.get(obj); + if(!storage){ + storage = {}; + this.storageMap.set(obj,storage); + } + return storage; } /** @@ -56,6 +90,7 @@ export class CacheContext{ const cacheStorage = {}; return new Proxy(delegateObject,{ get:(target,key)=>{ + if(key == '_cacheDelegateSource')return delegateObject; let value = target[key]; if(key.indexOf('cache') == 0){ return value; @@ -73,7 +108,7 @@ export class CacheContext{ return CacheContext .getCacheValueFromObject(cacheStorage,key,arguments,target); }catch(e){ - return value.apply(target,arguments); + return value.call(target,...arguments); } }; cacheFuncObj[key] = wrapFunc; @@ -85,16 +120,18 @@ export class CacheContext{ }); } - static getCacheValueFromObject(storage,key,params,source){ + static getCacheValueFromObject(storage,key,params,source,func){ let cache = storage; let funcCache = CacheContext.ensureMember(cache,key); let cacheKey = CacheContext.wrapParametersToCacheKey(params); let ret = funcCache[cacheKey]; if(ret === undefined){ - ret = source[key](...params); + ret = ((typeof func == 'function')?func:source[key]).call(source,...params); funcCache[cacheKey] = ret; + //console.log('缓存未命中!'+key+":"+cacheKey+":"+params.length+":ret:"+ret); + }else{ + //console.log(key+":"+cacheKey+":"+params.length+":ret:"+ret); } - //console.log(key+":"+cacheKey+":"+params.length+":ret:"+ret); return ret; } diff --git a/noname/library/element/player.js b/noname/library/element/player.js index f2101a0ad..bc8151131 100644 --- a/noname/library/element/player.js +++ b/noname/library/element/player.js @@ -3247,6 +3247,8 @@ export class Player extends HTMLDivElement { if(arg2){ if(typeof arg2 == 'string'){ filter = card=>(getCardName(card) == arg2); + }else if(Array.isArray(arg2)){ + filter = card=>arg2.includes(getCardName(card)); }else if(typeof arg2 == 'object'){ filter = card=>{ for (let j in arg2) { @@ -3355,13 +3357,6 @@ export class Player extends HTMLDivElement { } return list; } - cacheCountCards(arg1){ - let cache = CacheContext.getCacheContext(); - if(cache){ - return cache.delegate(this).countCards(arg1); - } - return this.countCards(arg1); - } countCards(arg1, arg2) { let count = 0; for(let item of this.iterableGetCards(arg1,arg2)){ @@ -3398,19 +3393,15 @@ export class Player extends HTMLDivElement { } return skills; } - getModableSkills(useCache) { - var func = function (player) { - var skills = player.getSkills().concat(lib.skill.global); - game.expandSkills(skills); - skills = skills.filter(function (skill) { - var info = get.info(skill); - return info && info.mod; - }); - skills.sort((a, b) => get.priority(a) - get.priority(b)); - return skills; - }; - if (!useCache) return func(this); - return game.callFuncUseStepCache("player.getModableSkills", func, [this]); + getModableSkills() { + var skills = this.getSkills().concat(lib.skill.global); + game.expandSkills(skills); + skills = skills.filter(function (skill) { + var info = get.info(skill); + return info && info.mod; + }); + skills.sort((a, b) => get.priority(a) - get.priority(b)); + return skills; } getSkills(arg2, arg3, arg4) { var skills = this.skills.slice(0); @@ -4760,9 +4751,6 @@ export class Player extends HTMLDivElement { } }); } - cacheSupportFunction(){ - return ['hasCard','hasValueTarget','getCardIndex','countCards','getSkills','getUseValue','canUse']; - } moveCard() { var next = game.createEvent('moveCard'); next.player = this; @@ -4830,7 +4818,7 @@ export class Player extends HTMLDivElement { this.logSkill(event.logSkill); } else if (Array.isArray(event.logSkill)) { - this.logSkill.apply(this, event.logSkill); + this.logSkill.call(this,...event.logSkill); } } if (result.card || !result.skill) { @@ -6914,8 +6902,47 @@ export class Player extends HTMLDivElement { return player.canUse(card, current, distance, includecard); }); } - hasValueTarget() { - return this.getUseValue.apply(this, arguments) > 0; + hasValueTarget(card, distance, includecard) { + if (typeof (card) == 'string') { + card = { name: card, isCard: true }; + } + var player = this; + var targets = game.filterPlayer(); + var value = []; + var min = 0; + var info = get.info(card); + if (!info || info.notarget) return false; + var range; + var select = get.copy(info.selectTarget); + if (select == undefined) { + if (info.filterTarget == undefined) return true; + range = [1, 1]; + } + else if (typeof select == 'number') range = [select, select]; + else if (get.itemtype(select) == 'select') range = select; + else if (typeof select == 'function') range = select(card, player); + if (info.singleCard) range = [1, 1]; + game.checkMod(card, player, range, 'selectTarget', player); + if (!range) return false; + + let cache = CacheContext.requireCacheContext(); + for (var i = 0; i < targets.length; i++) { + if (player.canUse(card, targets[i], distance, includecard)) { + var eff = cache.get.effect(targets[i], card, player, player); + if(range[1]!=-1 && eff > 0){ + return true; + } + value.push(eff); + } + } + value.sort(function (a, b) { + return b - a; + }); + for (var i = 0; i < value.length; i++) { + if (i == range[1] || range[1] != -1 && value[i] <= 0) break; + min += value[i]; + } + return min > 0; } getUseValue(card, distance, includecard) { if (typeof (card) == 'string') { @@ -6940,10 +6967,7 @@ export class Player extends HTMLDivElement { game.checkMod(card, player, range, 'selectTarget', player); if (!range) return 0; - let cache = CacheContext.getCacheContext(); - if(!cache){ - cache = new CacheContext(); - } + let cache = CacheContext.requireCacheContext(); for (var i = 0; i < targets.length; i++) { if (player.canUse(card, targets[i], distance, includecard)) { var eff = cache.get.effect(targets[i], card, player, player); @@ -8076,7 +8100,7 @@ export class Player extends HTMLDivElement { return targets; } isEnemyOf() { - return !this.isFriendOf.apply(this, arguments); + return !this.isFriendOf.call(this,...arguments); } isFriendOf(player) { if (get.mode() == 'guozhan') { @@ -10154,3 +10178,6 @@ export class Player extends HTMLDivElement { } } } + +CacheContext.inject(Player.prototype, + ['hasCard','hasValueTarget','getModableSkills','getCardIndex','countCards','getSkills','getUseValue','canUse']); \ No newline at end of file