1
0
Fork 0
mirror of https://github.com/correl/mage.git synced 2025-03-29 17:00:07 -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.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.players.Player;
/**
*
@ -71,8 +71,6 @@ public class GatherSpecimens extends CardImpl {
class GatherSpecimensReplacementEffect extends ReplacementEffectImpl {
private static final FilterCreatureCard filter = new FilterCreatureCard();
public GatherSpecimensReplacementEffect() {
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";
@ -94,25 +92,31 @@ class GatherSpecimensReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
Card card = game.getCard(((ZoneChangeEvent) event).getTargetId());
if (card != null) {
card.putOntoBattlefield(game, zEvent.getFromZone(), zEvent.getSourceId(), source.getControllerId(), zEvent.comesIntoPlayTapped(), zEvent.getAppliedEffects());
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
event.setPlayerId(controller.getId());
}
return true;
return false;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE
&& ((ZoneChangeEvent) event).getToZone() == Zone.BATTLEFIELD) {
Card card = game.getCard(((ZoneChangeEvent) event).getTargetId());
if (card != null && filter.match(card, source.getSourceId(), source.getControllerId(), game)) {
if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) {
Card card = game.getCard(event.getTargetId());
if (card.getCardType().contains(CardType.CREATURE)) { // TODO: Bestow Card cast as Enchantment probably not handled correctly
Player controller = game.getPlayer(source.getControllerId());
if (controller != null && controller.hasOpponent(event.getPlayerId(), game)) {
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;
}
}

View file

@ -41,6 +41,27 @@ public class GatherSpecimensTest extends CardTestPlayerBase {
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
public void testFromGraveyardEffect() {
@ -83,6 +104,7 @@ public class GatherSpecimensTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.UPKEEP, playerA, "Gather Specimens");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Oblivion Ring");
addTarget(playerA, "Memnite");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Disenchant", "Oblivion Ring");
@ -94,4 +116,6 @@ public class GatherSpecimensTest extends CardTestPlayerBase {
assertPermanentCount(playerB, "Memnite", 0);
}
}

View file

@ -377,7 +377,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
}
break;
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.addPermanent(permanent);
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());
return false;
}
setControllerId(ownerId);
setControllerId(event.getPlayerId());
game.setZone(objectId, event.getToZone());
game.addSimultaneousEvent(event);
return game.getState().getZone(objectId) == toZone;
@ -543,11 +543,11 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
}
}
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)
game.resetForSourceId(permanent.getId());
// 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.setZone(objectId, Zone.BATTLEFIELD);
game.setScopeRelevant(true);
@ -555,7 +555,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
permanent.entersBattlefield(sourceId, game, event.getFromZone(), true);
game.setScopeRelevant(false);
game.applyEffects();
game.fireEvent(new ZoneChangeEvent(permanent, controllerId, fromZone, Zone.BATTLEFIELD));
game.fireEvent(new ZoneChangeEvent(permanent, event.getPlayerId(), fromZone, Zone.BATTLEFIELD));
return true;
}
return false;

View file

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

View file

@ -139,11 +139,11 @@ public class Token extends MageObjectImpl {
} else {
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)) {
amount = event.getAmount();
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.addPermanent(newToken);
if (tapped) {
@ -156,7 +156,7 @@ public class Token extends MageObjectImpl {
newToken.entersBattlefield(sourceId, game, Zone.OUTSIDE, true);
game.setScopeRelevant(false);
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) {
game.getCombat().addAttackingCreature(newToken.getId(), game);
}