use of mage.game.permanent.PermanentMeld in project mage by magefree.
the class ZonesHandler method maybeRemoveFromSourceZone.
private static boolean maybeRemoveFromSourceZone(ZoneChangeInfo info, Game game, Ability source) {
ZoneChangeEvent event = info.event;
// Handle Unmelded Cards
if (info instanceof ZoneChangeInfo.Unmelded) {
ZoneChangeInfo.Unmelded unmelded = (ZoneChangeInfo.Unmelded) info;
MeldCard meld = game.getMeldCard(event.getTargetId());
for (Iterator<ZoneChangeInfo> itr = unmelded.subInfo.iterator(); itr.hasNext(); ) {
ZoneChangeInfo subInfo = itr.next();
if (!maybeRemoveFromSourceZone(subInfo, game, source)) {
itr.remove();
} else if (Objects.equals(subInfo.event.getTargetId(), meld.getTopHalfCard().getId())) {
meld.setTopLastZoneChangeCounter(meld.getTopHalfCard().getZoneChangeCounter(game));
} else if (Objects.equals(subInfo.event.getTargetId(), meld.getBottomHalfCard().getId())) {
meld.setBottomLastZoneChangeCounter(meld.getBottomHalfCard().getZoneChangeCounter(game));
}
}
if (unmelded.subInfo.isEmpty()) {
return false;
}
// We arbitrarily prefer the bottom half card. This should never be relevant.
meld.updateZoneChangeCounter(game, unmelded.subInfo.get(unmelded.subInfo.size() - 1).event);
return true;
}
// Handle all normal cases
Card card = getTargetCard(game, event.getTargetId());
if (card == null) {
// If we can't find the card we can't remove it.
return false;
}
boolean success = false;
if (info.faceDown) {
card.setFaceDown(true, game);
} else if (event.getToZone().equals(Zone.BATTLEFIELD)) {
if (!card.isPermanent(game) && (!card.isTransformable() || Boolean.FALSE.equals(game.getState().getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId())))) {
// Non permanents (Instants, Sorceries, ... stay in the zone they are if an abilty/effect tries to move it to the battlefield
return false;
}
}
if (!game.replaceEvent(event)) {
Zone fromZone = event.getFromZone();
if (event.getToZone() == Zone.BATTLEFIELD) {
// prepare card and permanent
// If needed take attributes from the spell (e.g. color of spell was changed)
card = takeAttributesFromSpell(card, event, game);
// controlling player can be replaced so use event player now
Permanent permanent;
if (card instanceof MeldCard) {
permanent = new PermanentMeld(card, event.getPlayerId(), game);
} else if (card instanceof ModalDoubleFacesCard) {
// main mdf card must be processed before that call (e.g. only halfes can be moved to battlefield)
throw new IllegalStateException("Unexpected trying of move mdf card to battlefield instead half");
} else if (card instanceof Permanent) {
throw new IllegalStateException("Unexpected trying of move permanent to battlefield instead card");
} else {
permanent = new PermanentCard(card, event.getPlayerId(), game);
}
// put onto battlefield with possible counters
game.getPermanentsEntering().put(permanent.getId(), permanent);
card.checkForCountersToAdd(permanent, source, game);
permanent.setTapped(info instanceof ZoneChangeInfo.Battlefield && ((ZoneChangeInfo.Battlefield) info).tapped);
permanent.setFaceDown(info.faceDown, game);
if (info.faceDown) {
card.setFaceDown(false, game);
}
// make sure the controller of all continuous effects of this card are switched to the current controller
game.setScopeRelevant(true);
game.getContinuousEffects().setController(permanent.getId(), permanent.getControllerId());
if (permanent.entersBattlefield(source, game, fromZone, true) && card.removeFromZone(game, fromZone, source)) {
success = true;
event.setTarget(permanent);
} else {
// revert controller to owner if permanent does not enter
game.getContinuousEffects().setController(permanent.getId(), permanent.getOwnerId());
game.getPermanentsEntering().remove(permanent.getId());
}
game.setScopeRelevant(false);
} else if (event.getTarget() != null) {
card.setFaceDown(info.faceDown, game);
Permanent target = event.getTarget();
success = target.removeFromZone(game, fromZone, source) && game.getPlayer(target.getControllerId()).removeFromBattlefield(target, source, game);
} else {
card.setFaceDown(info.faceDown, game);
success = card.removeFromZone(game, fromZone, source);
}
}
if (success) {
// KickerTest do many tests for token's zcc
if (event.getToZone() == Zone.BATTLEFIELD && event.getTarget() != null) {
event.getTarget().updateZoneChangeCounter(game, event);
} else if (!(card instanceof Permanent)) {
card.updateZoneChangeCounter(game, event);
}
}
return success;
}
use of mage.game.permanent.PermanentMeld in project mage by magefree.
the class YorionSkyNomadEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = source.getSourceObject(game);
if (sourceObject == null || controller == null) {
return false;
}
TargetPermanent target = new TargetPermanent(0, Integer.MAX_VALUE, filter, true);
controller.choose(outcome, target, source.getSourceId(), game);
Set<Card> toExile = target.getTargets().stream().map(game::getPermanent).collect(Collectors.toSet());
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
controller.moveCardsToExile(toExile, source, game, true, exileId, sourceObject.getIdName());
Cards cardsToReturn = new CardsImpl();
for (Card exiled : toExile) {
if (exiled instanceof PermanentMeld) {
MeldCard meldCard = (MeldCard) ((PermanentCard) exiled).getCard();
Card topCard = meldCard.getTopHalfCard();
Card bottomCard = meldCard.getBottomHalfCard();
if (topCard.getZoneChangeCounter(game) == meldCard.getTopLastZoneChangeCounter()) {
cardsToReturn.add(topCard);
}
if (bottomCard.getZoneChangeCounter(game) == meldCard.getBottomLastZoneChangeCounter()) {
cardsToReturn.add(bottomCard);
}
} else if (exiled.getZoneChangeCounter(game) == game.getState().getZoneChangeCounter(exiled.getId()) - 1) {
cardsToReturn.add(exiled);
}
}
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false);
effect.setTargetPointer(new FixedTargets(cardsToReturn, game));
AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect);
game.addDelayedTriggeredAbility(delayedAbility, source);
return true;
}
use of mage.game.permanent.PermanentMeld in project mage by magefree.
the class CardUtil method putCardOntoBattlefieldWithEffects.
/**
* Put card to battlefield without resolve (for cheats and tests only)
*
* @param source must be non null (if you need it empty then use fakeSourceAbility)
* @param game
* @param newCard
* @param player
*/
public static void putCardOntoBattlefieldWithEffects(Ability source, Game game, Card newCard, Player player) {
// same logic as ZonesHandler->maybeRemoveFromSourceZone
// workaround to put real permanent from one side (example: you call mdf card by cheats)
Card permCard = getDefaultCardSideForBattlefield(game, newCard);
// prepare card and permanent
permCard.setZone(Zone.BATTLEFIELD, game);
permCard.setOwnerId(player.getId());
PermanentCard permanent;
if (permCard instanceof MeldCard) {
permanent = new PermanentMeld(permCard, player.getId(), game);
} else {
permanent = new PermanentCard(permCard, player.getId(), game);
}
// put onto battlefield with possible counters
game.getPermanentsEntering().put(permanent.getId(), permanent);
permCard.checkForCountersToAdd(permanent, source, game);
permanent.entersBattlefield(source, game, Zone.OUTSIDE, false);
game.addPermanent(permanent, game.getState().getNextPermanentOrderNumber());
game.getPermanentsEntering().remove(permanent.getId());
// workaround for special tapped status from test framework's command (addCard)
if (permCard instanceof PermanentCard && ((PermanentCard) permCard).isTapped()) {
permanent.setTapped(true);
}
// remove sickness
permanent.removeSummoningSickness();
// init effects on static abilities (init continuous effects; warning, game state contains copy)
for (ContinuousEffect effect : game.getState().getContinuousEffects().getLayeredEffects(game)) {
Optional<Ability> ability = game.getState().getContinuousEffects().getLayeredEffectAbilities(effect).stream().findFirst();
if (ability.isPresent() && permanent.getId().equals(ability.get().getSourceId())) {
effect.init(ability.get(), game, player.getId());
}
}
}
use of mage.game.permanent.PermanentMeld in project mage by magefree.
the class EerieInterludeEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = source.getSourceObject(game);
if (sourceObject != null && controller != null) {
Set<Card> toExile = new HashSet<>();
for (UUID targetId : getTargetPointer().getTargets(game, source)) {
Permanent targetCreature = game.getPermanent(targetId);
if (targetCreature != null) {
toExile.add(targetCreature);
}
}
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
controller.moveCardsToExile(toExile, source, game, true, exileId, sourceObject.getIdName());
Cards cardsToReturn = new CardsImpl();
for (Card exiled : toExile) {
if (exiled instanceof PermanentMeld) {
MeldCard meldCard = (MeldCard) ((PermanentCard) exiled).getCard();
Card topCard = meldCard.getTopHalfCard();
Card bottomCard = meldCard.getBottomHalfCard();
if (topCard.getZoneChangeCounter(game) == meldCard.getTopLastZoneChangeCounter()) {
cardsToReturn.add(topCard);
}
if (bottomCard.getZoneChangeCounter(game) == meldCard.getBottomLastZoneChangeCounter()) {
cardsToReturn.add(bottomCard);
}
} else if (exiled.getZoneChangeCounter(game) == game.getState().getZoneChangeCounter(exiled.getId()) - 1) {
cardsToReturn.add(exiled);
}
}
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false);
effect.setTargetPointer(new FixedTargets(cardsToReturn, game));
AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect);
game.addDelayedTriggeredAbility(delayedAbility, source);
return true;
}
return false;
}
Aggregations