mirror of
https://github.com/correl/mage.git
synced 2024-11-25 03:00:11 +00:00
* Fixed a bug that order of triggered abilities of tokens were not shown to human player and the UI was locked (fixes #910).
This commit is contained in:
parent
b62dadf95d
commit
78071ce0a3
5 changed files with 65 additions and 17 deletions
|
@ -89,6 +89,9 @@ public class CardsView extends LinkedHashMap<UUID, CardView> {
|
||||||
case EXILED:
|
case EXILED:
|
||||||
case GRAVEYARD:
|
case GRAVEYARD:
|
||||||
sourceObject = game.getCard(ability.getSourceId());
|
sourceObject = game.getCard(ability.getSourceId());
|
||||||
|
if (sourceObject == null) {
|
||||||
|
sourceObject = game.getPermanent(ability.getSourceId());
|
||||||
|
}
|
||||||
isCard = true;
|
isCard = true;
|
||||||
break;
|
break;
|
||||||
case BATTLEFIELD:
|
case BATTLEFIELD:
|
||||||
|
|
|
@ -846,7 +846,8 @@ public class GameController implements GameCallback {
|
||||||
perform(playerId, new Command() {
|
perform(playerId, new Command() {
|
||||||
@Override
|
@Override
|
||||||
public void execute(UUID playerId) {
|
public void execute(UUID playerId) {
|
||||||
getGameSession(playerId).target(question, new CardsView(abilities, game), null, required, options);
|
CardsView cardsView = new CardsView(abilities, game);
|
||||||
|
getGameSession(playerId).target(question, cardsView, null, required, options);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,12 +28,12 @@
|
||||||
package mage.sets.tenthedition;
|
package mage.sets.tenthedition;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.constants.CardType;
|
|
||||||
import mage.constants.Rarity;
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.effects.common.GainLifeEffect;
|
import mage.abilities.effects.common.GainLifeEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Rarity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -50,6 +50,8 @@ public class VenerableMonk extends CardImpl {
|
||||||
|
|
||||||
this.power = new MageInt(2);
|
this.power = new MageInt(2);
|
||||||
this.toughness = new MageInt(2);
|
this.toughness = new MageInt(2);
|
||||||
|
|
||||||
|
// When Venerable Monk enters the battlefield, you gain 2 life.
|
||||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new GainLifeEffect(2)));
|
this.addAbility(new EntersBattlefieldTriggeredAbility(new GainLifeEffect(2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,16 +28,16 @@
|
||||||
package mage.sets.zendikar;
|
package mage.sets.zendikar;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.constants.CardType;
|
|
||||||
import mage.constants.Outcome;
|
|
||||||
import mage.constants.Rarity;
|
|
||||||
import mage.constants.Zone;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.condition.common.KickedCondition;
|
import mage.abilities.condition.common.KickedCondition;
|
||||||
import mage.abilities.decorator.ConditionalOneShotEffect;
|
import mage.abilities.decorator.ConditionalOneShotEffect;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.keyword.KickerAbility;
|
import mage.abilities.keyword.KickerAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.Rarity;
|
||||||
|
import mage.constants.Zone;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.game.permanent.token.EmptyToken;
|
import mage.game.permanent.token.EmptyToken;
|
||||||
|
@ -54,7 +54,6 @@ public class RiteOfReplication extends CardImpl {
|
||||||
super(ownerId, 61, "Rite of Replication", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{2}{U}{U}");
|
super(ownerId, 61, "Rite of Replication", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{2}{U}{U}");
|
||||||
this.expansionSetCode = "ZEN";
|
this.expansionSetCode = "ZEN";
|
||||||
|
|
||||||
|
|
||||||
// Kicker {5}
|
// Kicker {5}
|
||||||
this.addAbility(new KickerAbility("{5}"));
|
this.addAbility(new KickerAbility("{5}"));
|
||||||
|
|
||||||
|
|
|
@ -7,17 +7,19 @@ import org.junit.Test;
|
||||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Doubling Season:
|
* Doubling Season: If an effect would put one or more tokens onto the
|
||||||
* If an effect would put one or more tokens onto the battlefield under your control, it puts twice that many of those tokens onto the battlefield instead.
|
* battlefield under your control, it puts twice that many of those tokens onto
|
||||||
* If an effect would place one or more counters on a permanent you control, it places twice that many of those counters on that permanent instead.
|
* the battlefield instead. If an effect would place one or more counters on a
|
||||||
|
* permanent you control, it places twice that many of those counters on that
|
||||||
|
* permanent instead.
|
||||||
*
|
*
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
public class DoublingSeasonTest extends CardTestPlayerBase {
|
public class DoublingSeasonTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that instead of one spore counter there were two spore counters added to Pallid Mycoderm
|
* Tests that instead of one spore counter there were two spore counters
|
||||||
* if Doubling Season is on the battlefield.
|
* added to Pallid Mycoderm if Doubling Season is on the battlefield.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDoubleSporeCounter() {
|
public void testDoubleSporeCounter() {
|
||||||
|
@ -35,8 +37,9 @@ public class DoublingSeasonTest extends CardTestPlayerBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests if 3 damage are prevented with Test of Faith and Doubling Season is on
|
* Tests if 3 damage are prevented with Test of Faith and Doubling Season is
|
||||||
* the battlefield, that 6 +1/+1 counters are added to the target creature.
|
* on the battlefield, that 6 +1/+1 counters are added to the target
|
||||||
|
* creature.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDoubleP1P1Counter() {
|
public void testDoubleP1P1Counter() {
|
||||||
|
@ -63,9 +66,10 @@ public class DoublingSeasonTest extends CardTestPlayerBase {
|
||||||
assertPowerToughness(playerA, "Silvercoat Lion", 8, 8);
|
assertPowerToughness(playerA, "Silvercoat Lion", 8, 8);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that 2 Saproling tokens are created instead of one if Doubling Season is on
|
* Tests that 2 Saproling tokens are created instead of one if Doubling
|
||||||
* the battlefield.
|
* Season is on the battlefield.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDoubleTokens() {
|
public void testDoubleTokens() {
|
||||||
|
@ -89,4 +93,43 @@ public class DoublingSeasonTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creatures with enter the battlefield triggers are causing a bug when
|
||||||
|
* multiple copies are made simultaneously (ie via Doubling Season +
|
||||||
|
* Kiki-Jiki, Mirror Breaker or Rite of Replication). After the tokens have
|
||||||
|
* entered the battlefield it asks their controller to choose the order that
|
||||||
|
* the triggered abilities on the stack but no window opens to select the
|
||||||
|
* triggers leaving no option to move the game forward (besides rollback and
|
||||||
|
* just not making the tokens). Several attempts with the different
|
||||||
|
* combinations make it *seem to be a general bug about duplicates entering
|
||||||
|
* at the same time and not related to the specific cards.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testDoubleRiteOfReplication() {
|
||||||
|
/**
|
||||||
|
* If an effect would put one or more tokens onto the battlefield under
|
||||||
|
* your control, it puts twice that many of those tokens onto the
|
||||||
|
* battlefield instead. If an effect would place one or more counters on
|
||||||
|
* a permanent you control, it places twice that many of those counters
|
||||||
|
* on that permanent instead.
|
||||||
|
*/
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Doubling Season");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Island", 9);
|
||||||
|
|
||||||
|
// Put a token that's a copy of target creature onto the battlefield. If Rite of Replication was kicked, put five of those tokens onto the battlefield instead.
|
||||||
|
addCard(Zone.HAND, playerA, "Rite of Replication");
|
||||||
|
// When Venerable Monk enters the battlefield, you gain 2 life.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Venerable Monk", 1);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rite of Replication", "Venerable Monk");
|
||||||
|
setChoice(playerA, "Yes");
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertLife(playerA, 40);
|
||||||
|
assertPermanentCount(playerA, "Venerable Monk", 10);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue