forked from mirrors/webxoss-core
implement trap
This commit is contained in:
parent
09e42d6252
commit
e4d556f5b3
4 changed files with 166 additions and 89 deletions
165
Card.js
165
Card.js
|
@ -829,6 +829,10 @@ Card.prototype.moveTo = function (zone,arg) {
|
||||||
moveEvent.isCharm = true;
|
moveEvent.isCharm = true;
|
||||||
signi.charm = null;
|
signi.charm = null;
|
||||||
}
|
}
|
||||||
|
// 处理陷阱
|
||||||
|
if (card === card.zone.trap) {
|
||||||
|
card.zone.trap = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -841,7 +845,7 @@ Card.prototype.moveTo = function (zone,arg) {
|
||||||
// 进入 SIGNI 区
|
// 进入 SIGNI 区
|
||||||
if (zone.getActualCards().length) {
|
if (zone.getActualCards().length) {
|
||||||
// rise
|
// rise
|
||||||
if (card.rise) {
|
if (!arg.bottom && card.rise) {
|
||||||
// 被 rise 的卡“离场”
|
// 被 rise 的卡“离场”
|
||||||
signi = zone.getActualCards()[0];
|
signi = zone.getActualCards()[0];
|
||||||
removeFromArr(signi,signi.player.signis);
|
removeFromArr(signi,signi.player.signis);
|
||||||
|
@ -908,6 +912,7 @@ Card.prototype.moveTo = function (zone,arg) {
|
||||||
// 手牌中非公开的卡,在游戏逻辑中是"背面朝上"的,即:
|
// 手牌中非公开的卡,在游戏逻辑中是"背面朝上"的,即:
|
||||||
// 对方不能查看;己方能查看(这是因为手牌区是 checkable 的).
|
// 对方不能查看;己方能查看(这是因为手牌区是 checkable 的).
|
||||||
// 但在客户端中,手牌里的卡即使逻辑上是背面朝上的,仍显示为正面朝上.
|
// 但在客户端中,手牌里的卡即使逻辑上是背面朝上的,仍显示为正面朝上.
|
||||||
|
// PS: 增加了陷阱,陷阱和手牌一样,是仅己方玩家可见的。
|
||||||
card.player.output({
|
card.player.output({
|
||||||
type: 'MOVE_CARD',
|
type: 'MOVE_CARD',
|
||||||
content: {
|
content: {
|
||||||
|
@ -915,7 +920,7 @@ Card.prototype.moveTo = function (zone,arg) {
|
||||||
pid: (card.isFaceup || zone.checkable)? card.pid : 0,
|
pid: (card.isFaceup || zone.checkable)? card.pid : 0,
|
||||||
zone: zone,
|
zone: zone,
|
||||||
up: arg.up,
|
up: arg.up,
|
||||||
faceup: zone.inhand? true : arg.faceup,
|
faceup: (arg.isTrap || zone.inhand)? true : arg.faceup,
|
||||||
bottom: arg.bottom,
|
bottom: arg.bottom,
|
||||||
isSide: arg.isSide
|
isSide: arg.isSide
|
||||||
}
|
}
|
||||||
|
@ -1124,8 +1129,8 @@ Card.prototype.attackAsyn = function () {
|
||||||
}).callback(this,function () {
|
}).callback(this,function () {
|
||||||
// 选择攻击的区域
|
// 选择攻击的区域
|
||||||
var zones = [];
|
var zones = [];
|
||||||
var opposingZone = this.player.opponent.signiZones[2-index];
|
|
||||||
var index = this.player.signiZones.indexOf(this.zone);
|
var index = this.player.signiZones.indexOf(this.zone);
|
||||||
|
var opposingZone = this.player.opponent.signiZones[2-index];
|
||||||
if (this.canAttackAnySigniZone) {
|
if (this.canAttackAnySigniZone) {
|
||||||
zones = this.player.opponent.signiZones;
|
zones = this.player.opponent.signiZones;
|
||||||
} else if (this.canAttackNearbySigniZone) {
|
} else if (this.canAttackNearbySigniZone) {
|
||||||
|
@ -1184,79 +1189,91 @@ Card.prototype.attackAsyn = function () {
|
||||||
}
|
}
|
||||||
this.game.frameEnd();
|
this.game.frameEnd();
|
||||||
}).callback(this,function () {
|
}).callback(this,function () {
|
||||||
// 强制结束回合
|
|
||||||
if (this.game.phase.checkForcedEndTurn()) return;
|
|
||||||
// 此时,攻击的卡可能已不在场上
|
|
||||||
if (!inArr(card,player.signis)) return;
|
|
||||||
// 被无效化
|
|
||||||
if (event.prevented) return;
|
|
||||||
// 攻击时发动的起动效果 (<被侵犯的神判 安=Fifth>)
|
// 攻击时发动的起动效果 (<被侵犯的神判 安=Fifth>)
|
||||||
return opponent.useOnAttackActionEffectAsyn(event).callback(this,function () {
|
return opponent.useOnAttackActionEffectAsyn(event).callback(this,function () {
|
||||||
// 攻击的卡不在场上或攻击被无效化,结束处理.
|
// 强制结束回合
|
||||||
|
if (this.game.phase.checkForcedEndTurn()) return;
|
||||||
|
// 攻击的卡不在场上,结束处理.
|
||||||
if (!inArr(card,player.signis)) return;
|
if (!inArr(card,player.signis)) return;
|
||||||
if (event.prevented) return;
|
// 处理陷阱
|
||||||
// 若攻击的目标存在,进行战斗;
|
|
||||||
// (暗杀的情况下,目标为正对面的 SIGNI 时,不战斗)
|
|
||||||
var opposingSigni = card.getOpposingSigni();
|
var opposingSigni = card.getOpposingSigni();
|
||||||
var target = attackedZone.getActualCards()[0] || null;
|
var index = this.player.signiZones.indexOf(this.zone);
|
||||||
var battle = true;
|
var opposingZone = this.player.opponent.signiZones[2-index];
|
||||||
if (!target) battle = false;
|
var trap = opposingZone.trap
|
||||||
if (card.assassin && (target === opposingSigni)) return false;
|
return Callback.immediately().callback(this,function () {
|
||||||
if (battle) {
|
if (opposingSigni || !trap) return;
|
||||||
// 战斗
|
return this.player.selectOptionalAsyn('LAUNCH',[trap]).callback(this,function (card) {
|
||||||
// 触发"进行战斗"时点
|
if (!card) return;
|
||||||
var onBattleEvent = {
|
card.beSelectedAsTarget();
|
||||||
card: card,
|
return card.trap.actionAsyn.call(card).callback(this,function () {
|
||||||
target: target,
|
card.trash();
|
||||||
};
|
});
|
||||||
return this.game.blockAsyn(this,function () {
|
|
||||||
this.game.frameStart();
|
|
||||||
card.onBattle.trigger(onBattleEvent);
|
|
||||||
target.onBattle.trigger(onBattleEvent);
|
|
||||||
this.game.frameEnd();
|
|
||||||
}).callback(this,function () {
|
|
||||||
// 此时,攻击的卡可能已不在场上
|
|
||||||
if (!inArr(card,player.signis)) return;
|
|
||||||
// 受攻击的卡也可能已不在场上
|
|
||||||
// 注意: 根据事务所QA,此时不击溃对方的生命护甲(即使有 lancer ). (<大剣 レヴァテイン>)
|
|
||||||
if (!inArr(target,target.player.signis)) return;
|
|
||||||
// 结算战斗伤害
|
|
||||||
if (card.power >= target.power) {
|
|
||||||
// 保存此时的 lancer 属性作为参考,
|
|
||||||
// 因为驱逐被攻击的 SIGNI 后,攻击侧的 lancer 可能改变.
|
|
||||||
var lancer = card.lancer;
|
|
||||||
return this.game.blockAsyn(this,function () {
|
|
||||||
return target.banishAsyn({attackingSigni: card}).callback(this,function (succ) {
|
|
||||||
if (succ && lancer) {
|
|
||||||
crashArg.lancer = lancer;
|
|
||||||
return opponent.crashAsyn(1,crashArg);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}).callback(this,function () {
|
|
||||||
if (onBattleEvent._1877 && inArr(target,target.player.signis)) {
|
|
||||||
return this.game.blockAsyn(onBattleEvent._1877,this,function () {
|
|
||||||
target.moveTo(target.player.mainDeck,{bottom: true});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else {
|
}).callback(this,function () {
|
||||||
// 伤害
|
// 攻击被无效,结束处理
|
||||||
if (target !== opposingSigni) return;
|
if (event.prevented) return;
|
||||||
if (event.wontBeDamaged || opponent.wontBeDamaged) return;
|
// 若攻击的目标存在,进行战斗;
|
||||||
crashArg.damage = true;
|
// (暗杀的情况下,目标为正对面的 SIGNI 时,不战斗)
|
||||||
if (opponent.lifeClothZone.cards.length) {
|
var target = attackedZone.getActualCards()[0] || null;
|
||||||
var count = 1;
|
var battle = true;
|
||||||
if (this.doubleCrash) count = 2;
|
if (!target) battle = false;
|
||||||
if (this.tripleCrash) count = 3;
|
if (card.assassin && (target === opposingSigni)) return false;
|
||||||
crashArg.doubleCrash = this.doubleCrash;
|
if (battle) {
|
||||||
return opponent.crashAsyn(count,crashArg);
|
// 战斗
|
||||||
|
// 触发"进行战斗"时点
|
||||||
|
var onBattleEvent = {
|
||||||
|
card: card,
|
||||||
|
target: target,
|
||||||
|
};
|
||||||
|
return this.game.blockAsyn(this,function () {
|
||||||
|
this.game.frameStart();
|
||||||
|
card.onBattle.trigger(onBattleEvent);
|
||||||
|
target.onBattle.trigger(onBattleEvent);
|
||||||
|
this.game.frameEnd();
|
||||||
|
}).callback(this,function () {
|
||||||
|
// 此时,攻击的卡可能已不在场上
|
||||||
|
if (!inArr(card,player.signis)) return;
|
||||||
|
// 受攻击的卡也可能已不在场上
|
||||||
|
// 注意: 根据事务所QA,此时不击溃对方的生命护甲(即使有 lancer ). (<大剣 レヴァテイン>)
|
||||||
|
if (!inArr(target,target.player.signis)) return;
|
||||||
|
// 结算战斗伤害
|
||||||
|
if (card.power >= target.power) {
|
||||||
|
// 保存此时的 lancer 属性作为参考,
|
||||||
|
// 因为驱逐被攻击的 SIGNI 后,攻击侧的 lancer 可能改变.
|
||||||
|
var lancer = card.lancer;
|
||||||
|
return this.game.blockAsyn(this,function () {
|
||||||
|
return target.banishAsyn({attackingSigni: card}).callback(this,function (succ) {
|
||||||
|
if (succ && lancer) {
|
||||||
|
crashArg.lancer = lancer;
|
||||||
|
return opponent.crashAsyn(1,crashArg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).callback(this,function () {
|
||||||
|
if (onBattleEvent._1877 && inArr(target,target.player.signis)) {
|
||||||
|
return this.game.blockAsyn(onBattleEvent._1877,this,function () {
|
||||||
|
target.moveTo(target.player.mainDeck,{bottom: true});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
if (card.game.win(player)) return Callback.never();
|
// 伤害
|
||||||
return;
|
if (target !== opposingSigni) return;
|
||||||
|
if (event.wontBeDamaged || opponent.wontBeDamaged) return;
|
||||||
|
crashArg.damage = true;
|
||||||
|
if (opponent.lifeClothZone.cards.length) {
|
||||||
|
var count = 1;
|
||||||
|
if (this.doubleCrash) count = 2;
|
||||||
|
if (this.tripleCrash) count = 3;
|
||||||
|
crashArg.doubleCrash = this.doubleCrash;
|
||||||
|
return opponent.crashAsyn(count,crashArg);
|
||||||
|
} else {
|
||||||
|
if (card.game.win(player)) return Callback.never();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
}).callback(this,function () {
|
}).callback(this,function () {
|
||||||
// "这场战斗结束之后,就回老家结婚" (划掉)
|
// "这场战斗结束之后,就回老家结婚" (划掉)
|
||||||
|
@ -1531,6 +1548,16 @@ Card.prototype.charmTo = function (signi) {
|
||||||
this.game.frameEnd();
|
this.game.frameEnd();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Card.prototype.trapTo = function(zone) {
|
||||||
|
if (zone.trap) zone.trap.trash();
|
||||||
|
zone.trap = this;
|
||||||
|
this.moveTo(zone,{
|
||||||
|
faceup: false,
|
||||||
|
up: signi.isUp,
|
||||||
|
isTrap: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
Card.prototype.getAccedCards = function () {
|
Card.prototype.getAccedCards = function () {
|
||||||
if (!inArr(this,this.player.signis)) return [];
|
if (!inArr(this,this.player.signis)) return [];
|
||||||
return this.zone.cards.filter(function (card) {
|
return this.zone.cards.filter(function (card) {
|
||||||
|
|
58
CardInfo.js
58
CardInfo.js
|
@ -127029,7 +127029,7 @@ var CardInfo = {
|
||||||
actionAsyn: function (card) {
|
actionAsyn: function (card) {
|
||||||
return card.banishAsyn().callback(this,function (succ) {
|
return card.banishAsyn().callback(this,function (succ) {
|
||||||
if (!succ) return;
|
if (!succ) return;
|
||||||
// TODO...
|
return this.player.setTrapFromDeckTopAsyn(3);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},{
|
},{
|
||||||
|
@ -127039,7 +127039,16 @@ var CardInfo = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
actionAsyn: function (card) {
|
actionAsyn: function (card) {
|
||||||
// TODO...
|
return card.banishAsyn().callback(this,function (succ) {
|
||||||
|
if (!succ) return;
|
||||||
|
var zones = this.player.signiZones.filter(function (zone) {
|
||||||
|
return zone.trap;
|
||||||
|
},this);
|
||||||
|
return this.player.selectAsyn('TARGET',zones).callback(this,function (zone) {
|
||||||
|
if (!zone) return;
|
||||||
|
zone.trap.moveTo(this.player.handZone);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
|
@ -128424,7 +128433,7 @@ var CardInfo = {
|
||||||
this.player.informCards(cards);
|
this.player.informCards(cards);
|
||||||
return this.player.selectOptionalAsyn('TARGET',cards).callback(this,function (card) {
|
return this.player.selectOptionalAsyn('TARGET',cards).callback(this,function (card) {
|
||||||
if (!card) return;
|
if (!card) return;
|
||||||
// TODO...
|
return this.player.setTrapFromDeckTopAsyn(2);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
|
@ -128443,7 +128452,6 @@ var CardInfo = {
|
||||||
burstEffect: {
|
burstEffect: {
|
||||||
actionAsyn: function () {
|
actionAsyn: function () {
|
||||||
return this.player.opponent.discardAsyn(1).callback(this,function () {
|
return this.player.opponent.discardAsyn(1).callback(this,function () {
|
||||||
// TODO...
|
|
||||||
if (this.player.getTraps().length) {
|
if (this.player.getTraps().length) {
|
||||||
var filter = function (card) {
|
var filter = function (card) {
|
||||||
return card.isUp;
|
return card.isUp;
|
||||||
|
@ -129316,7 +129324,12 @@ var CardInfo = {
|
||||||
source: this,
|
source: this,
|
||||||
description: '2068-attached-1',
|
description: '2068-attached-1',
|
||||||
actionAsyn: function () {
|
actionAsyn: function () {
|
||||||
// TODO...
|
return this.player.selectOptionalAsyn('TARGET',this.player.hands).callback(this,function (card) {
|
||||||
|
if (!card) return;
|
||||||
|
return this.player.selectAsyn('TARGET',this.player.signiZones).callback(this,function (zone) {
|
||||||
|
card.trapTo(zone);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
return this.player.selectAsyn('LAUNCH',effects).callback(this,function (effect) {
|
return this.player.selectAsyn('LAUNCH',effects).callback(this,function (effect) {
|
||||||
|
@ -129389,7 +129402,7 @@ var CardInfo = {
|
||||||
startUpEffects: [{
|
startUpEffects: [{
|
||||||
actionAsyn: function () {
|
actionAsyn: function () {
|
||||||
if (this.player.getTraps().length) return;
|
if (this.player.getTraps().length) return;
|
||||||
// TODO...
|
return this.player.setTrapFromDeckTopAsyn(2);
|
||||||
},
|
},
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
|
@ -129551,8 +129564,9 @@ var CardInfo = {
|
||||||
extraTexts_en: [
|
extraTexts_en: [
|
||||||
"[Trap]: You may put 1 of your other [Trap] on the field into the trash, and pay [Blue]. If you do, banish 1 of your opponent's SIGNI."
|
"[Trap]: You may put 1 of your other [Trap] on the field into the trash, and pay [Blue]. If you do, banish 1 of your opponent's SIGNI."
|
||||||
],
|
],
|
||||||
// TODO...
|
|
||||||
trap: {
|
trap: {
|
||||||
|
// TODO...
|
||||||
|
// not cost
|
||||||
costBlue: 1,
|
costBlue: 1,
|
||||||
costCondition: function () {
|
costCondition: function () {
|
||||||
return this.getTraps().some(function (card) {
|
return this.getTraps().some(function (card) {
|
||||||
|
@ -129608,10 +129622,21 @@ var CardInfo = {
|
||||||
source: this,
|
source: this,
|
||||||
description: '2071-burst-2',
|
description: '2071-burst-2',
|
||||||
actionAsyn: function () {
|
actionAsyn: function () {
|
||||||
var cards = this.player.mainDeck.getTopCards(2);
|
var cards = this.mainDeck.getTopCards(count);
|
||||||
if (cards.length) return;
|
|
||||||
this.player.informCards(cards);
|
this.player.informCards(cards);
|
||||||
// TODO...
|
var done = false;
|
||||||
|
return Callback.loop(this,2,function () {
|
||||||
|
if (done) return;
|
||||||
|
return this.player.selectOptionalAsyn('TARGET',cards).callback(this,function (card) {
|
||||||
|
if (!card) return done = true;
|
||||||
|
removeFromArr(card,cards);
|
||||||
|
return this.player.selectAsyn('TARGET',this.player.signiZones).callback(this,function (zone) {
|
||||||
|
card.trapTo(zone);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}).callback(this,function () {
|
||||||
|
this.game.trashCards(cards);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
return this.player.selectAsyn('LAUNCH',effects).callback(this,function (effect) {
|
return this.player.selectAsyn('LAUNCH',effects).callback(this,function (effect) {
|
||||||
|
@ -130479,7 +130504,6 @@ var CardInfo = {
|
||||||
"[Trap]: Down 2 of your opponent's SIGNI."
|
"[Trap]: Down 2 of your opponent's SIGNI."
|
||||||
],
|
],
|
||||||
trap: {
|
trap: {
|
||||||
costBlue: 1,
|
|
||||||
actionAsyn: function () {
|
actionAsyn: function () {
|
||||||
var cards = this.player.opponent.signis.filter(function (signi) {
|
var cards = this.player.opponent.signis.filter(function (signi) {
|
||||||
return signi.isUp;
|
return signi.isUp;
|
||||||
|
@ -130822,7 +130846,7 @@ var CardInfo = {
|
||||||
],
|
],
|
||||||
spellEffect: {
|
spellEffect: {
|
||||||
actionAsyn: function () {
|
actionAsyn: function () {
|
||||||
// TODO...
|
return this.player.setTrapFromDeckTopAsyn(4);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -132454,13 +132478,7 @@ var CardInfo = {
|
||||||
source: this,
|
source: this,
|
||||||
description: '1396-const-0',
|
description: '1396-const-0',
|
||||||
actionAsyn: function () {
|
actionAsyn: function () {
|
||||||
var cards = this.player.mainDeck.getTopCards(2);
|
return this.player.setTrapFromDeckTopAsyn(2);
|
||||||
if (!cards.length) return;
|
|
||||||
this.player.informCards(cards);
|
|
||||||
return this.player.selectOptionalAsyn('TARGET',cards).callback(this,function (card) {
|
|
||||||
if (!card) return;
|
|
||||||
// TODO...
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
add(this.player,'onMainPhaseStart',effect);
|
add(this.player,'onMainPhaseStart',effect);
|
||||||
|
@ -135244,7 +135262,7 @@ var CardInfo = {
|
||||||
source: this,
|
source: this,
|
||||||
description: '2167-const-0',
|
description: '2167-const-0',
|
||||||
actionAsyn: function () {
|
actionAsyn: function () {
|
||||||
// !TODO...
|
// TODO...
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
add(this,'onBanish',effect);
|
add(this,'onBanish',effect);
|
||||||
|
|
31
Player.js
31
Player.js
|
@ -2339,4 +2339,35 @@ Player.prototype.infectZoneAsyn = function() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Player.prototype.setTrapFromDeckTopAsyn = function(count,max) {
|
||||||
|
if (!isNum(max)) max = 1;
|
||||||
|
var cards = this.mainDeck.getTopCards(count);
|
||||||
|
this.informCards(cards);
|
||||||
|
var done = false;
|
||||||
|
return Callback.loop(this,max,function () {
|
||||||
|
if (done) return;
|
||||||
|
return this.selectOptionalAsyn('TARGET',cards).callback(this,function (card) {
|
||||||
|
if (!card) return done = true;
|
||||||
|
removeFromArr(card,cards);
|
||||||
|
return this.selectAsyn('TARGET',this.signiZones).callback(this,function (zone) {
|
||||||
|
card.trapTo(zone);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}).callback(this,function () {
|
||||||
|
var len = cards.length;
|
||||||
|
if (!len) return;
|
||||||
|
return this.selectSomeAsyn('SET_ORDER',cards,len,len,true).callback(this,function (cards) {
|
||||||
|
this.mainDeck.moveCardsToBottom(cards);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Player.prototype.getTraps = function() {
|
||||||
|
return this.player.signiZones.filter(function (zone) {
|
||||||
|
return zone.trap;
|
||||||
|
}).map(function (zone) {
|
||||||
|
return zone.trap;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
global.Player = Player;
|
global.Player = Player;
|
1
Zone.js
1
Zone.js
|
@ -36,6 +36,7 @@ function Zone (game,player,name,args,pids) {
|
||||||
this.disabled = false; // <ワーム・ホール>
|
this.disabled = false; // <ワーム・ホール>
|
||||||
this.powerDown = false; // <黒幻蟲 サソリス>
|
this.powerDown = false; // <黒幻蟲 サソリス>
|
||||||
this.virus = false;
|
this.virus = false;
|
||||||
|
this.trap = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Zone.prototype.getTopCards = function (n) {
|
Zone.prototype.getTopCards = function (n) {
|
||||||
|
|
Loading…
Reference in a new issue