mirror of
https://github.com/webxoss/webxoss-core.git
synced 2024-11-20 06:49:53 +01:00
add WX14
This commit is contained in:
parent
deffae5f3a
commit
f8f461aea1
8 changed files with 9283 additions and 5768 deletions
37
Card.js
37
Card.js
|
@ -4,6 +4,7 @@ function Card (game,player,zone,pid,side) {
|
|||
// 引用
|
||||
this.game = game;
|
||||
this.player = player;
|
||||
this.owner = player;
|
||||
this.zone = zone;
|
||||
|
||||
// 状态
|
||||
|
@ -98,6 +99,8 @@ function Card (game,player,zone,pid,side) {
|
|||
this.effectFilters = [];
|
||||
this.registeredEffects = [];
|
||||
this.charm = null; // 魅饰卡
|
||||
this._data = null; // 私有的数据储存,约定: 只能在 CardInfo.js 自身的代码里访问
|
||||
this.fieldData = {}; // 离场即清空的数据
|
||||
|
||||
// 时点
|
||||
this.onMove = new Timming(game);
|
||||
|
@ -123,7 +126,6 @@ function Card (game,player,zone,pid,side) {
|
|||
this.doubleCrash = false;
|
||||
this.tripleCrash = false;
|
||||
this.frozen = false;
|
||||
this._trashWhenTurnEnd = false;
|
||||
this.forceSummonZone = false;
|
||||
this.trashCharmInsteadOfBanish = false;
|
||||
this.attachedCostColorless = 0; // <星占之巫女 忆·夜>
|
||||
|
@ -144,10 +146,12 @@ function Card (game,player,zone,pid,side) {
|
|||
this.discardSpellInsteadOfBanish = false; // <核心代号 S・W・T>
|
||||
this.attackCostColorless = 0; // <黑幻虫 水熊虫>
|
||||
this.canNotGainAbility = false; // <迷宫代号 金阁>
|
||||
this.canNotGainAbilityBySelfPlayer = false; // <城堡代号 凡尔赛宫>
|
||||
this._SnoropNaturalPlantPrincess = false; // <罗植姬 雪花莲>
|
||||
this._CodeLabyrinthLouvre = null; // <卢浮宫>
|
||||
this.powerAddProtected = false; // <幻兽 苍龙>
|
||||
this._GustaftCenterBallista = false; // <弩中砲 グスタフト>
|
||||
this.colorLost = false; // <侍从 ∞>
|
||||
this.banishProtections = [];
|
||||
// 注意hasAbility
|
||||
}
|
||||
|
@ -255,8 +259,9 @@ Card.prototype.canGrow = function (ignoreCost) {
|
|||
}
|
||||
}
|
||||
if (!ignoreCost && !this.player.enoughCost(this.getGrowCostObj())) return false;
|
||||
// LRIG type
|
||||
if (this.classes.every(function (cls) {
|
||||
return !this.player.lrig.hasClass(cls);
|
||||
return !this.player.lrig.hasClass(cls) && (cls !== '?'); // <紡ぐ者>
|
||||
},this)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -305,13 +310,20 @@ Card.prototype.canSummon = function () {
|
|||
Card.prototype.canSummonWith = function (signis) {
|
||||
// 类型
|
||||
if (this.type !== 'SIGNI') return false;
|
||||
// <绿罗植 世界树>
|
||||
if (this.player.canNotUseColorlessSigni) {
|
||||
if (this.hasColor('colorless')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// summonConditions
|
||||
var flag = this.summonConditions.some(function (condition) {
|
||||
return !condition.call(this);
|
||||
},this);
|
||||
if (flag) return false;
|
||||
// 限定
|
||||
if (!this.checkLimiting()) return false;
|
||||
flag = ths.player.ignoreLimitingOfLevel5Signi && (this.level === 5);
|
||||
if (!flag && !this.checkLimiting()) return false;
|
||||
// 等级限制
|
||||
if (this.level > this.player.lrig.level) return false;
|
||||
// SIGNI 数量限制
|
||||
|
@ -466,6 +478,12 @@ Card.prototype.canUse = function (timming,ignoreCost) {
|
|||
if (!this.checkLimiting()) return false;
|
||||
if (this.useCondition && !this.useCondition()) return false;
|
||||
if (this.type === 'SPELL') {
|
||||
// <绿罗植 世界树>
|
||||
if (this.player.canNotUseColorlessSpell) {
|
||||
if (this.hasColor('colorless')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (this.player.spellBanned) return false;
|
||||
if (ignoreCost) return true;
|
||||
return this.enoughCost();
|
||||
|
@ -503,8 +521,12 @@ Card.prototype.hasClass = function (cls) {
|
|||
},this);
|
||||
};
|
||||
|
||||
// 注意:不保证唯一性
|
||||
Card.prototype.getColors = function (ignoreColorless) {
|
||||
var colors = this.otherColors.concat(this.color);
|
||||
if (this.colorLost) {
|
||||
colors = ['colorless'];
|
||||
}
|
||||
if (ignoreColorless) {
|
||||
removeFromArr('colorless',colors);
|
||||
}
|
||||
|
@ -709,7 +731,7 @@ Card.prototype.moveTo = function (zone,arg) {
|
|||
// 是 SIGNI
|
||||
leaveFieldEvent = moveEvent;
|
||||
card.frozen = false;
|
||||
card._trashWhenTurnEnd = false;
|
||||
card.fieldData = {};
|
||||
charm = card.charm;
|
||||
card.charm = null;
|
||||
removeFromArr(card,card.player.signis);
|
||||
|
@ -996,6 +1018,7 @@ Card.prototype.attackAsyn = function () {
|
|||
// onAttack 的事件对象
|
||||
var event = {
|
||||
prevented: prevented,
|
||||
preventedByGuard: false,
|
||||
card: card,
|
||||
banishAttackingSigniSource: null,
|
||||
wontBeDamaged: false,
|
||||
|
@ -1117,9 +1140,11 @@ Card.prototype.attackAsyn = function () {
|
|||
}).callback(this,function (succ) {
|
||||
if (succ) {
|
||||
event.prevented = true;
|
||||
event.preventedByGuard = true;
|
||||
return;
|
||||
};
|
||||
if (event.wontBeDamaged || opponent.wontBeDamaged) return;
|
||||
if (player.wontBeDamagedByOpponentLrig) return;
|
||||
crashArg.damage = true;
|
||||
if (opponent.lifeClothZone.cards.length) {
|
||||
var count = 1;
|
||||
|
@ -1300,7 +1325,7 @@ Card.prototype.banishSigniAsyn = function (power,min,max,above) {
|
|||
});
|
||||
};
|
||||
|
||||
Card.prototype.decreasePowerAsyn = function(power,filter) {
|
||||
Card.prototype.decreasePowerAsyn = function (power,filter) {
|
||||
return this.player.selectOpponentSigniAsyn(filter).callback(this,function (card) {
|
||||
if (!card) return;
|
||||
this.game.tillTurnEndAdd(this,card,'power',-power);
|
||||
|
@ -1308,7 +1333,7 @@ Card.prototype.decreasePowerAsyn = function(power,filter) {
|
|||
};
|
||||
|
||||
Card.prototype.trashWhenTurnEnd = function () {
|
||||
this._trashWhenTurnEnd = true;
|
||||
this.fieldData.trashWhenTurnEnd = true;
|
||||
};
|
||||
|
||||
// 获得所谓的类别,在wx中,类别组成为"大类:小类"
|
||||
|
|
7492
CardInfo.js
7492
CardInfo.js
File diff suppressed because it is too large
Load diff
|
@ -144,7 +144,7 @@ ConstEffect.prototype.add = function (target,prop,value,arg) {
|
|||
|
||||
ConstEffect.prototype._setAdd = function (masks,target,prop,value,arg) {
|
||||
if (!arg) arg = {};
|
||||
var mask = new Mask(target,prop,value,!!arg.forced);
|
||||
var mask = new Mask(this.source,target,prop,value,!!arg.forced);
|
||||
if (!mask.checkFilter(this.source)) return;
|
||||
this.constEffectManager.setBase(target,prop);
|
||||
masks.push(mask);
|
||||
|
|
17
Game.js
17
Game.js
|
@ -996,11 +996,20 @@ Game.prototype.setAdd = function (source,obj,prop,value,isSet,arg) {
|
|||
if (!arg) arg = {};
|
||||
if (!arg.forced) {
|
||||
if (obj.isEffectFiltered && obj.isEffectFiltered(source)) return;
|
||||
if (obj.canNotGainAbility) {
|
||||
if (inArr(prop,Card.abilityProps)) return;
|
||||
var card = null;
|
||||
if (obj.player && inArr(prop,Card.abilityProps)) {
|
||||
card = obj;
|
||||
} else if (isObj(value) && (value.constructor === Effect)) {
|
||||
card = value.source;
|
||||
if (card.isEffectFiltered(source)) return;
|
||||
}
|
||||
if (card) {
|
||||
if (card.canNotGainAbility || card.player.canNotGainAbility) return;
|
||||
if (card.canNotGainAbilityBySelfPlayer) {
|
||||
if (source.player === card.player) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (isObj(value) && (value.constructor === Effect)) {
|
||||
if (value.source.canNotGainAbility) return;
|
||||
}
|
||||
}
|
||||
var destroyTimming = [this.phase.onTurnEnd];
|
||||
|
|
22
Mask.js
22
Mask.js
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
function Mask (target,prop,value,forced) {
|
||||
function Mask (source,target,prop,value,forced) {
|
||||
this.source = source;
|
||||
this.target = target;
|
||||
this.prop = prop;
|
||||
this.value = value;
|
||||
|
@ -26,10 +27,15 @@ Mask.prototype.set = function (reset) {
|
|||
var timming = item;
|
||||
var effect = this.value;
|
||||
var source = effect.source;
|
||||
if (source.canNotGainAbility || source.player.canNotGainAbility) {
|
||||
// 不能获得新能力
|
||||
if (source.canNotGainAbility || source.player.canNotGainAbility) {
|
||||
return;
|
||||
}
|
||||
if (source.canNotGainAbilityBySelfPlayer) {
|
||||
if (this.source.player === source.player) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
effect.disabled = false;
|
||||
timming.effects.push(effect);
|
||||
effect.source.registeredEffects.push(effect);
|
||||
|
@ -46,10 +52,16 @@ Mask.prototype.set = function (reset) {
|
|||
effect.disabled = true;
|
||||
},this);
|
||||
} else {
|
||||
if (!reset && inArr(this.prop,Card.abilityProps)) {
|
||||
if (!reset && target.player && inArr(this.prop,Card.abilityProps)) {
|
||||
// 不能获得新能力
|
||||
if (target.canNotGainAbility) return;
|
||||
if (target.player && target.player.canNotGainAbility) return;
|
||||
if (target.canNotGainAbility && target.player.canNotGainAbility) {
|
||||
return;
|
||||
}
|
||||
if (target.canNotGainAbilityBySelfPlayer) {
|
||||
if (this.source === target.player) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
target[this.prop] = this.value;
|
||||
}
|
||||
|
|
8
Phase.js
8
Phase.js
|
@ -279,8 +279,12 @@ Phase.prototype.endPhase = function () {
|
|||
// 处理"回合结束时,把XXX放到废弃区".
|
||||
// 同时触发"回合结束时"时点.
|
||||
var cards = concat(this.player.signis,this.player.opponent.signis).filter(function (signi) {
|
||||
if (signi._trashWhenTurnEnd) {
|
||||
signi._trashWhenTurnEnd = false;
|
||||
if (signi.fieldData.excludeWhenTurnEnd) {
|
||||
signi.fieldData.excludeWhenTurnEnd = false;
|
||||
return true;
|
||||
}
|
||||
if (signi.fieldData.trashWhenTurnEnd) {
|
||||
signi.fieldData.trashWhenTurnEnd = false;
|
||||
return true;
|
||||
}
|
||||
},this);
|
||||
|
|
93
Player.js
93
Player.js
|
@ -102,11 +102,13 @@ function Player (game,io,mainDeck,lrigDeck) {
|
|||
this.spellBanned = false;
|
||||
this.skipEnerPhase = false;
|
||||
this.ignoreLimitingOfArtsAndSpell = false;
|
||||
this.ignoreLimitingOfLevel5Signi = false; // <紡ぐ者>
|
||||
this.summonPowerLimit = 0;
|
||||
this.additionalRevealCount = 0; // <反复的独立性 网格>
|
||||
this.useBikouAsWhiteCost = false; // <不思議な童話 メルへ>
|
||||
this.burstTwice = false; // <Burst Rush>
|
||||
this.wontBeDamaged = false; // <音阶的右律 G>
|
||||
this.wontBeDamagedByOpponentLrig = false; // <紡ぐ者>
|
||||
this.charmedActionEffectBanned = false; // <黒幻蟲 アラクネ・パイダ>
|
||||
this.canNotGrow = false; // <ドント・グロウ>
|
||||
this._HammerChance = false; // <ハンマー・チャンス>
|
||||
|
@ -133,10 +135,12 @@ function Player (game,io,mainDeck,lrigDeck) {
|
|||
this.canNotBeBounced = false;
|
||||
this.canNotGainAbility = false;
|
||||
this.canNotBeDownedByOpponentEffect = false;
|
||||
this.canNotUseColorlessSigni = false; // <绿罗植 世界树>
|
||||
this.canNotUseColorlessSpell = false; // <绿罗植 世界树>
|
||||
|
||||
this.usedActionEffects = [];
|
||||
this.chain = null;
|
||||
this.inResonaAction = false; // 是否正在执行共鸣单位的出现条件
|
||||
this.inResonaAction = null; // 是否正在执行共鸣单位的出现条件. (同时也是正在执行出现条件的那只共鸣单位)
|
||||
this.inActionEffectCost = false; // 是否正在支付起动能力的COST
|
||||
this.bannedCards = []; // <漆黑之棺>
|
||||
this.oneArtEachTurn = false; // <博愛の使者 サシェ・リュンヌ>
|
||||
|
@ -441,9 +445,9 @@ Player.prototype.getResonas = function (arg) {
|
|||
};
|
||||
|
||||
Player.prototype.summonResonaAsyn = function (card) {
|
||||
this.inResonaAction = true;
|
||||
this.inResonaAction = card;
|
||||
return card.resonaAsyn().callback(this,function (resonaArg) {
|
||||
this.inResonaAction = false;
|
||||
this.inResonaAction = null;
|
||||
return this.selectSummonZoneAsyn(false).callback(this,function (zone) {
|
||||
if (!zone) return;
|
||||
return this.game.blockAsyn(this,function () {
|
||||
|
@ -507,10 +511,10 @@ Player.prototype.useSpellAsyn = function () {
|
|||
return this.selectAsyn('USE_SPELL',cards).callback(this,this.handleSpellAsyn);
|
||||
};
|
||||
|
||||
Player.prototype.handleSpellAsyn = function (card,ignoreCost,costObj) {
|
||||
Player.prototype.handleSpellAsyn = function (card,ignoreCost,costObj,arg) {
|
||||
if (!costObj) costObj = card;
|
||||
if (!arg) arg = {};
|
||||
var effect,target,costArg;
|
||||
var owner = card.player;
|
||||
this.game.setData(this,'flagSpellUsed',true);
|
||||
var count = this.game.getData(this,'CodeHeartAMS') || 0;
|
||||
this.game.setData(this,'CodeHeartAMS',count + 1);
|
||||
|
@ -599,11 +603,16 @@ Player.prototype.handleSpellAsyn = function (card,ignoreCost,costObj) {
|
|||
}).callback(this,function () {
|
||||
// 6. 放到废弃区
|
||||
// 恢复控制权
|
||||
card.player = owner;
|
||||
card.player = card.owner;
|
||||
this.game.spellToCutIn = null;
|
||||
if (card.zone !== this.checkZone) return;
|
||||
return this.game.blockAsyn(this,function () {
|
||||
// <皮露露可 APEX>
|
||||
if (arg.excludeAfterUse) {
|
||||
card.exclude()
|
||||
} else {
|
||||
card.trash();
|
||||
}
|
||||
});
|
||||
}).callback(this,function () {
|
||||
// <混乱交织> 的特殊处理
|
||||
|
@ -655,11 +664,23 @@ Player.prototype.handleArtsAsyn = function (card,ignoreCost) {
|
|||
}
|
||||
}).callback(this,function () {
|
||||
// 2. 支付费用
|
||||
// アンコール费用
|
||||
// アンコール费用,约定: 除了颜色费用,其它属性直接覆盖
|
||||
if (!card.encore) return;
|
||||
var encoredCost = Object.create(costObj);
|
||||
var enerCostProps = [
|
||||
'costColorless',
|
||||
'costWhite',
|
||||
'costBlack',
|
||||
'costRed',
|
||||
'costBlue',
|
||||
'costGreen',
|
||||
];
|
||||
for (var prop in card.encore) {
|
||||
if (inArr(prop,enerCostProps)) {
|
||||
encoredCost[prop] += card.encore[prop];
|
||||
} else {
|
||||
encoredCost[prop] = card.encore[prop];
|
||||
}
|
||||
}
|
||||
if (!this.enoughCost(encoredCost)) return;
|
||||
return this.confirmAsyn('CONFIRM_ENCORE').callback(this,function (answer) {
|
||||
|
@ -766,11 +787,12 @@ Player.prototype.useMainPhaseArtsAsyn = function () {
|
|||
});
|
||||
};
|
||||
|
||||
Player.prototype.canUseActionEffect = function (effect,onAttack,arg) {
|
||||
Player.prototype.canUseActionEffect = function (effect,arg) {
|
||||
if (!arg) arg = {};
|
||||
if (this.charmedActionEffectBanned && effect.source.charm) return false;
|
||||
if (effect.source.abilityLost) return false;
|
||||
if (onAttack && !effect.onAttack) return false;
|
||||
if (!onAttack && effect.onAttack) return false;
|
||||
if (arg.onAttack && !effect.onAttack) return false;
|
||||
if (!arg.onAttack && effect.onAttack) return false;
|
||||
if (effect.cross && !effect.source.crossed) return false;
|
||||
if (effect.once && inArr(effect,this.usedActionEffects)) return false;
|
||||
if (effect.useCondition && !effect.useCondition.call(effect.source,arg)) return false;
|
||||
|
@ -786,51 +808,51 @@ Player.prototype.canUseActionEffect = function (effect,onAttack,arg) {
|
|||
} else {
|
||||
obj.costColorless = effect.source.attachedCostColorless;
|
||||
}
|
||||
if (arg.ignoreExceedCost) {
|
||||
obj.costExceed = 0;
|
||||
}
|
||||
return this.enoughCost(obj);
|
||||
};
|
||||
|
||||
// 玩家使用起动效果
|
||||
Player.prototype.useActionEffectAsyn = function () {
|
||||
var effects = [];
|
||||
concat(this.lrig,this.signis).forEach(function (card) {
|
||||
var cards = concat(this.lrig,this.signis,this.trashZone.cards,this.hands);
|
||||
cards.forEach(function (card) {
|
||||
card.actionEffects.forEach(function (effect) {
|
||||
if (effect.spellCutIn) return;
|
||||
if (effect.attackPhase && !effect.mainPhase) return;
|
||||
if (effect.activatedInTrashZone) return;
|
||||
if (effect.activatedInTrashZone && card.zone !== this.trashZone) return;
|
||||
if (effect.activatedInHand && card.zone !== this.handZone) return;
|
||||
if (this.canUseActionEffect(effect)) {
|
||||
effects.push(effect);
|
||||
}
|
||||
},this);
|
||||
},this);
|
||||
this.trashZone.cards.forEach(function (card) {
|
||||
// if (card.type !== 'SIGNI') return;
|
||||
card.actionEffects.forEach(function (effect) {
|
||||
if (effect.spellCutIn) return;
|
||||
if (effect.attackPhase && !effect.mainPhase) return;
|
||||
if (!effect.activatedInTrashZone) return;
|
||||
if (this.canUseActionEffect(effect)) {
|
||||
effects.push(effect);
|
||||
}
|
||||
},this);
|
||||
},this);
|
||||
});
|
||||
});
|
||||
if (!effects.length) return Callback.never();
|
||||
return this.selectAsyn('USE_ACTION_EFFECT',effects).callback(this,function (effect) {
|
||||
return this.handleActionEffectAsyn(effect,{},true);
|
||||
return this.handleActionEffectAsyn(effect,{
|
||||
cancelable: true,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Player.prototype.useOnAttackActionEffectAsyn = function (event) {
|
||||
var effects = this.lrig.actionEffects.filter(function (effect) {
|
||||
return this.canUseActionEffect(effect,true,event);
|
||||
return this.canUseActionEffect(effect,{
|
||||
onAttack: true,
|
||||
event: event,
|
||||
});
|
||||
},this);
|
||||
if (!effects.length) return Callback.immediately();
|
||||
return this.selectOptionalAsyn('LAUNCH',effects).callback(this,function (effect) {
|
||||
if (!effect) return;
|
||||
return this.handleActionEffectAsyn(effect,event);
|
||||
return this.handleActionEffectAsyn(effect,{event: event});
|
||||
});
|
||||
};
|
||||
|
||||
Player.prototype.handleActionEffectAsyn = function (effect,event,cancelable) {
|
||||
Player.prototype.handleActionEffectAsyn = function (effect,arg) {
|
||||
if (!arg) arg = {};
|
||||
this.usedActionEffects.push(effect);
|
||||
return this.game.blockAsyn(this,function () {
|
||||
var obj = Object.create(effect);
|
||||
|
@ -839,6 +861,9 @@ Player.prototype.handleActionEffectAsyn = function (effect,event,cancelable) {
|
|||
} else {
|
||||
obj.costColorless = effect.source.attachedCostColorless;
|
||||
}
|
||||
if (arg.ignoreExceedCost) {
|
||||
obj.costExceed = 0;
|
||||
}
|
||||
// <混沌之键主 乌姆尔=FYRA>
|
||||
if (effect.activatedInTrashZone) {
|
||||
if (this.game.getData(effect.source,'zeroActionCostInTrash')) {
|
||||
|
@ -847,12 +872,12 @@ Player.prototype.handleActionEffectAsyn = function (effect,event,cancelable) {
|
|||
}
|
||||
}
|
||||
this.inActionEffectCost = true;
|
||||
return this.payCostAsyn(obj,cancelable).callback(this,function (costArg) {
|
||||
return this.payCostAsyn(obj,arg.cancelable).callback(this,function (costArg) {
|
||||
this.inActionEffectCost = false;
|
||||
if (!costArg) return; // canceled
|
||||
effect.source.activate();
|
||||
return this.game.blockAsyn(effect.source,this,function () {
|
||||
return effect.actionAsyn.call(effect.source,costArg,event);
|
||||
return effect.actionAsyn.call(effect.source,costArg,arg);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1049,6 +1074,12 @@ Player.prototype.crashAsyn = function (n,arg) {
|
|||
|
||||
Player.prototype.damageAsyn = function () {
|
||||
if (this.wontBeDamaged) return Callback.immediately(false);
|
||||
if (this.wontBeDamagedByOpponentLrig) {
|
||||
var source = this.game.getEffectSource();
|
||||
if (source === this.player.opponent.lrig) {
|
||||
return Callback.immediately(false);
|
||||
}
|
||||
}
|
||||
if (!this.lifeClothZone.cards.length) {
|
||||
if (this.game.win(this.opponent)) return Callback.never();
|
||||
return Callback.immediately(false);
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 1cd5ce68eaa244096cfb358624c88f5b0c2c04b3
|
||||
Subproject commit a1b421e2b205a326cddfb8d1d9b2db27f2efac86
|
Loading…
Reference in a new issue