This commit is contained in:
kuangthree 2024-02-03 12:25:27 +08:00
parent eb3046fcf6
commit 99e249789b
5 changed files with 154 additions and 85 deletions

View File

@ -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]);

View File

@ -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];
}

View File

@ -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] + '<br>').slice(0, -4);
uiintro.addText(str);
if(initFilters.length){
const str = initFilters.reduce((strx, stry) => strx + lib.InitFilter[stry] + '<br>').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);
});
}
}

View File

@ -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;
}

View File

@ -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']);