1
0
Fork 0
mirror of https://github.com/correl/mage.git synced 2025-04-04 09:16:04 -09:00

* Gather Specimens - Fixed that it did not work for token creatures the opponent brought onto the battlefield.

This commit is contained in:
LevelX2 2014-12-01 13:28:39 +01:00
parent cb014226c4
commit 6514e30b59
5 changed files with 51 additions and 19 deletions
Mage.Sets/src/mage/sets/shardsofalara
Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters
Mage/src/mage
cards
game
events
permanent/token

View file

@ -37,10 +37,10 @@ import mage.constants.Duration;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.common.FilterCreatureCard;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent; import mage.game.events.ZoneChangeEvent;
import mage.players.Player;
/** /**
* *
@ -71,8 +71,6 @@ public class GatherSpecimens extends CardImpl {
class GatherSpecimensReplacementEffect extends ReplacementEffectImpl { class GatherSpecimensReplacementEffect extends ReplacementEffectImpl {
private static final FilterCreatureCard filter = new FilterCreatureCard();
public GatherSpecimensReplacementEffect() { public GatherSpecimensReplacementEffect() {
super(Duration.EndOfTurn, Outcome.GainControl); super(Duration.EndOfTurn, Outcome.GainControl);
staticText = "If a creature would enter the battlefield under an opponent's control this turn, it enters the battlefield under your control instead"; staticText = "If a creature would enter the battlefield under an opponent's control this turn, it enters the battlefield under your control instead";
@ -94,25 +92,31 @@ class GatherSpecimensReplacementEffect extends ReplacementEffectImpl {
@Override @Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) { public boolean replaceEvent(GameEvent event, Ability source, Game game) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event; Player controller = game.getPlayer(source.getControllerId());
Card card = game.getCard(((ZoneChangeEvent) event).getTargetId()); if (controller != null) {
if (card != null) { event.setPlayerId(controller.getId());
card.putOntoBattlefield(game, zEvent.getFromZone(), zEvent.getSourceId(), source.getControllerId(), zEvent.comesIntoPlayTapped(), zEvent.getAppliedEffects());
} }
return true; return false;
} }
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE if (event.getType() == GameEvent.EventType.ZONE_CHANGE
&& ((ZoneChangeEvent) event).getToZone() == Zone.BATTLEFIELD) { && ((ZoneChangeEvent) event).getToZone() == Zone.BATTLEFIELD) {
Card card = game.getCard(((ZoneChangeEvent) event).getTargetId()); Card card = game.getCard(event.getTargetId());
if (card != null && filter.match(card, source.getSourceId(), source.getControllerId(), game)) { if (card.getCardType().contains(CardType.CREATURE)) { // TODO: Bestow Card cast as Enchantment probably not handled correctly
if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { Player controller = game.getPlayer(source.getControllerId());
if (controller != null && controller.hasOpponent(event.getPlayerId(), game)) {
return true; return true;
} }
} }
} }
if (event.getType() == GameEvent.EventType.CREATE_TOKEN && event.getFlag()) { // flag indicates if it's a creature token
Player controller = game.getPlayer(source.getControllerId());
if (controller != null && controller.hasOpponent(event.getPlayerId(), game)) {
return true;
}
}
return false; return false;
} }
} }

View file

@ -41,6 +41,27 @@ public class GatherSpecimensTest extends CardTestPlayerBase {
assertPermanentCount(playerB, "Memnite", 0); assertPermanentCount(playerB, "Memnite", 0);
} }
@Test
public void testTokenCreatedFromSpellEffect() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 6);
addCard(Zone.HAND, playerA, "Gather Specimens", 1);
addCard(Zone.BATTLEFIELD, playerB, "Plains", 3);
addCard(Zone.HAND, playerB, "Spectral Procession", 1);
castSpell(2, PhaseStep.UPKEEP, playerA, "Gather Specimens");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Spectral Procession");
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Spirit", 3);
assertPermanentCount(playerB, "Spirit", 0);
}
@Test @Test
public void testFromGraveyardEffect() { public void testFromGraveyardEffect() {
@ -83,6 +104,7 @@ public class GatherSpecimensTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.UPKEEP, playerA, "Gather Specimens"); castSpell(1, PhaseStep.UPKEEP, playerA, "Gather Specimens");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Oblivion Ring"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Oblivion Ring");
addTarget(playerA, "Memnite");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Disenchant", "Oblivion Ring"); castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Disenchant", "Oblivion Ring");
@ -94,4 +116,6 @@ public class GatherSpecimensTest extends CardTestPlayerBase {
assertPermanentCount(playerB, "Memnite", 0); assertPermanentCount(playerB, "Memnite", 0);
} }
} }

View file

@ -377,7 +377,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
} }
break; break;
case BATTLEFIELD: case BATTLEFIELD:
PermanentCard permanent = new PermanentCard(this, ownerId); PermanentCard permanent = new PermanentCard(this, event.getPlayerId()); // controller can be replaced (e.g. Gather Specimens)
game.resetForSourceId(permanent.getId()); game.resetForSourceId(permanent.getId());
game.addPermanent(permanent); game.addPermanent(permanent);
game.setZone(objectId, Zone.BATTLEFIELD); game.setZone(objectId, Zone.BATTLEFIELD);
@ -399,7 +399,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
.append("] source [").append(sourceCard != null ? sourceCard.getName():"null").append("]").toString()); .append("] source [").append(sourceCard != null ? sourceCard.getName():"null").append("]").toString());
return false; return false;
} }
setControllerId(ownerId); setControllerId(event.getPlayerId());
game.setZone(objectId, event.getToZone()); game.setZone(objectId, event.getToZone());
game.addSimultaneousEvent(event); game.addSimultaneousEvent(event);
return game.getState().getZone(objectId) == toZone; return game.getState().getZone(objectId) == toZone;
@ -543,11 +543,11 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
} }
} }
updateZoneChangeCounter(); updateZoneChangeCounter();
PermanentCard permanent = new PermanentCard(this, controllerId); PermanentCard permanent = new PermanentCard(this, event.getPlayerId());
// reset is done to end continuous effects from previous instances of that permanent (e.g undying) // reset is done to end continuous effects from previous instances of that permanent (e.g undying)
game.resetForSourceId(permanent.getId()); game.resetForSourceId(permanent.getId());
// make sure the controller of all continuous effects of this card are switched to the current controller // make sure the controller of all continuous effects of this card are switched to the current controller
game.getContinuousEffects().setController(objectId, controllerId); game.getContinuousEffects().setController(objectId, event.getPlayerId());
game.addPermanent(permanent); game.addPermanent(permanent);
game.setZone(objectId, Zone.BATTLEFIELD); game.setZone(objectId, Zone.BATTLEFIELD);
game.setScopeRelevant(true); game.setScopeRelevant(true);
@ -555,7 +555,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
permanent.entersBattlefield(sourceId, game, event.getFromZone(), true); permanent.entersBattlefield(sourceId, game, event.getFromZone(), true);
game.setScopeRelevant(false); game.setScopeRelevant(false);
game.applyEffects(); game.applyEffects();
game.fireEvent(new ZoneChangeEvent(permanent, controllerId, fromZone, Zone.BATTLEFIELD)); game.fireEvent(new ZoneChangeEvent(permanent, event.getPlayerId(), fromZone, Zone.BATTLEFIELD));
return true; return true;
} }
return false; return false;

View file

@ -186,6 +186,10 @@ public class GameEvent {
return sourceId; return sourceId;
} }
public void setPlayerId(UUID playerId) {
this.playerId = playerId;
}
public UUID getPlayerId() { public UUID getPlayerId() {
return playerId; return playerId;
} }

View file

@ -139,11 +139,11 @@ public class Token extends MageObjectImpl {
} else { } else {
setCode = source != null ? source.getExpansionSetCode() : null; setCode = source != null ? source.getExpansionSetCode() : null;
} }
GameEvent event = GameEvent.getEvent(EventType.CREATE_TOKEN, null, sourceId, controllerId, amount); GameEvent event = new GameEvent(EventType.CREATE_TOKEN, null, sourceId, controllerId, amount, this.getCardType().contains(CardType.CREATURE));
if (!game.replaceEvent(event)) { if (!game.replaceEvent(event)) {
amount = event.getAmount(); amount = event.getAmount();
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
PermanentToken newToken = new PermanentToken(this, controllerId, setCode, game); PermanentToken newToken = new PermanentToken(this, event.getPlayerId(), setCode, game); // use event.getPlayerId() because it can be replaced by replacement effect
game.getState().addCard(newToken); game.getState().addCard(newToken);
game.addPermanent(newToken); game.addPermanent(newToken);
if (tapped) { if (tapped) {
@ -156,7 +156,7 @@ public class Token extends MageObjectImpl {
newToken.entersBattlefield(sourceId, game, Zone.OUTSIDE, true); newToken.entersBattlefield(sourceId, game, Zone.OUTSIDE, true);
game.setScopeRelevant(false); game.setScopeRelevant(false);
game.applyEffects(); game.applyEffects();
game.fireEvent(new ZoneChangeEvent(newToken, controllerId, Zone.OUTSIDE, Zone.BATTLEFIELD)); game.fireEvent(new ZoneChangeEvent(newToken, event.getPlayerId(), Zone.OUTSIDE, Zone.BATTLEFIELD));
if (attacking && game.getCombat() != null) { if (attacking && game.getCombat() != null) {
game.getCombat().addAttackingCreature(newToken.getId(), game); game.getCombat().addAttackingCreature(newToken.getId(), game);
} }