forked from mirrors/webxoss-core
148 lines
No EOL
4.7 KiB
JavaScript
148 lines
No EOL
4.7 KiB
JavaScript
'use strict';
|
|
|
|
/*
|
|
Effect 对象注册在 Timming 上,
|
|
触发时以自己为原型创建一个拷贝,
|
|
在拷贝上附加 proto,event,triggerZone 等属性.
|
|
这个拷贝注册到 EffectManager 上.
|
|
*/
|
|
|
|
function Effect (effectManager,cfg) {
|
|
this.effectManager = effectManager;
|
|
|
|
this.source = cfg.source;
|
|
this.description = cfg.description;
|
|
this.optional = cfg.optional;
|
|
this.once = !!cfg.once; // 1回合只能发动一次.
|
|
this.isBurst = cfg.isBurst; // 用于"迸发效果发动时"时点.
|
|
// 以及"发动和解决要在相同场所"的规则例外
|
|
this.triggerCondition = cfg.triggerCondition;
|
|
this.costWhite = cfg.costWhite;
|
|
this.costBlack = cfg.costBlack;
|
|
this.costRed = cfg.costRed;
|
|
this.costBlue = cfg.costBlue;
|
|
this.costGreen = cfg.costGreen;
|
|
this.costColorless = cfg.costColorless;
|
|
this.costDown = cfg.costDown;
|
|
this.costExceed = cfg.costExceed;
|
|
this.costCoin = cfg.costCoin;
|
|
this.costCondition = cfg.costCondition;
|
|
this.costAsyn = cfg.costAsyn;
|
|
this.costChange = cfg.costChange;
|
|
this.condition = cfg.condition;
|
|
this.actionAsyn = cfg.actionAsyn;
|
|
this.wisdom = cfg.wisdom || 0;
|
|
|
|
this.disabled = false; // 失去能力时设置为 true .
|
|
}
|
|
|
|
Effect.prototype.trigger = function (event) {
|
|
if (this.disabled) return;
|
|
if (this.once && inArr(this,this.effectManager.triggeredEffects)) {
|
|
return;
|
|
}
|
|
if (!this.triggerCondition || this.triggerCondition.call(this.source,event)) {
|
|
this.source.activate();
|
|
var effect = Object.create(this);
|
|
effect.proto = this;
|
|
effect.event = event;
|
|
effect.triggerZone = this.source.zone;
|
|
this.effectManager.addTriggeredEffect(effect);
|
|
}
|
|
};
|
|
|
|
Effect.prototype.triggerAndHandleAsyn = function (event) {
|
|
if (this.disabled) return Callback.immediately();
|
|
if (!this.triggerCondition || this.triggerCondition.call(this.source,event)) {
|
|
// this.source.activate();
|
|
var effect = Object.create(this);
|
|
effect.event = event;
|
|
effect.triggerZone = this.source.zone;
|
|
if (!this.checkCondition()) return Callback.immediately();
|
|
return effect.handleAsyn(false);
|
|
}
|
|
return Callback.immediately();
|
|
};
|
|
|
|
Effect.prototype.checkCondition = function () {
|
|
if (this.disabled) return false;
|
|
// "结束这个回合",如<终结之洞>
|
|
var game = this.effectManager.game;
|
|
if (game.getData(game,'endThisTurn')) return false;
|
|
// "1回合1次"
|
|
if (this.once && inArr(this.proto,this.effectManager.triggeredEffects)) {
|
|
return false;
|
|
}
|
|
// wisdom
|
|
if (this.wisdom && (this.source.player.getWisdom() !== this.wisdom)) {
|
|
return false;
|
|
}
|
|
// 隐藏规则之"发动和解决的场所必须一致"
|
|
if (!this.isBurst && this.triggerZone) { // 排除迸发
|
|
if (this.triggerZone.faceup) { // 公开领域
|
|
if (this.triggerZone !== this.source.zone) { // 发动和解决场所不一致
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
if (this.condition && !this.condition.call(this.source,this.event)) {
|
|
return false;
|
|
}
|
|
return this.source.player.enoughCost(this);
|
|
};
|
|
|
|
Effect.prototype.handleAsyn = function (needConfirm) {
|
|
var player = this.source.player;
|
|
if (!this.isOptional()) {
|
|
return Callback.immediately().callback(this,function () {
|
|
if (this.once) {
|
|
this.effectManager.triggeredEffects.push(this.proto);
|
|
}
|
|
return this.actionAsyn.call(this.source,this.event,{});
|
|
});
|
|
}
|
|
if (player.enoughCost(this)) {
|
|
return Callback.immediately().callback(this,function () {
|
|
if (!needConfirm) return this.source;
|
|
return player.selectOptionalAsyn('LAUNCH',[this.source]);
|
|
}).callback(this,function (card) {
|
|
if (!card) return;
|
|
if (this.once) {
|
|
this.effectManager.triggeredEffects.push(this.proto);
|
|
}
|
|
var costArg;
|
|
return player.payCostAsyn(this).callback(this,function (arg) {
|
|
costArg = arg;
|
|
this.source.activate();
|
|
if (this.isBurst) {
|
|
this.source.player.onBurstTriggered.trigger();
|
|
}
|
|
this.effectManager.currentEffect = this;
|
|
return this.actionAsyn.call(this.source,this.event,costArg);
|
|
}).callback(this,function () {
|
|
if (this.isBurst && this.source.player.burstTwice) {
|
|
// <Burst Rush> 再处理一次.
|
|
this.source.activate();
|
|
this.source.player.onBurstTriggered.trigger();
|
|
return this.actionAsyn.call(this.source,this.event,costArg);
|
|
}
|
|
}).callback(this,function () {
|
|
this.effectManager.currentEffect = null;
|
|
});
|
|
});
|
|
}
|
|
return Callback.immediately();
|
|
};
|
|
|
|
Effect.prototype.end = function () {
|
|
if (!this.isBurst) return;
|
|
var card = this.source;
|
|
card.handleBurstEnd(this.event.crossLifeCloth);
|
|
};
|
|
|
|
Effect.prototype.isOptional = function () {
|
|
return this.optional || this.source.player.needCost(this);
|
|
};
|
|
|
|
|
|
global.Effect = Effect; |