mirror of
https://github.com/correl/mage.git
synced 2024-11-15 11:09:30 +00:00
Fixed that if cards from opponents were cast, that spell cast triggered abilities from this cards or optional additional costs from this card (e.g. Buyback) were controlled by the casting player.
This commit is contained in:
parent
538bb91222
commit
1a93d3a96d
5 changed files with 37 additions and 33 deletions
|
@ -33,6 +33,8 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Rarity;
|
||||
|
@ -41,7 +43,6 @@ import mage.filter.Filter;
|
|||
import mage.filter.FilterCard;
|
||||
import mage.filter.common.FilterNonlandCard;
|
||||
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
|
||||
import mage.game.ExileZone;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInExile;
|
||||
|
@ -58,7 +59,6 @@ public class VillainousWealth extends CardImpl {
|
|||
super(ownerId, 211, "Villainous Wealth", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{X}{B}{G}{U}");
|
||||
this.expansionSetCode = "KTK";
|
||||
|
||||
|
||||
// Target opponent exiles the top X cards of his or her library. You may cast any number of nonland cards with converted mana cost X or less from among them without paying their mana cost.
|
||||
this.getSpellAbility().addTarget(new TargetOpponent());
|
||||
this.getSpellAbility().addEffect(new VillainousWealthEffect());
|
||||
|
@ -101,30 +101,26 @@ class VillainousWealthEffect extends OneShotEffect {
|
|||
filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.LessThan, source.getManaCostsToPay().getX() + 1));
|
||||
UUID exileId = CardUtil.getCardExileZoneId(game, source);
|
||||
if (player != null) {
|
||||
|
||||
// putting cards to exile shouldn't end the game, so getting minimun available
|
||||
int cardsCount = Math.min(source.getManaCostsToPay().getX(), player.getLibrary().size());
|
||||
for (int i = 0; i < cardsCount; i++) {
|
||||
Card card = player.getLibrary().getFromTop(game);
|
||||
if (card != null) {
|
||||
controller.moveCardToExileWithInfo(card, exileId, mageObject.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true);
|
||||
Cards cardsToExile = new CardsImpl();
|
||||
cardsToExile.addAll(player.getLibrary().getTopCards(game, source.getManaCostsToPay().getX()));
|
||||
controller.moveCards(cardsToExile, null, Zone.EXILED, source, game, true);
|
||||
if (controller.chooseUse(Outcome.PlayForFree, "Cast cards exiled with " + mageObject.getLogName() + " without paying its mana cost?", source, game)) {
|
||||
OuterLoop:
|
||||
while (cardsToExile.count(filter, game) > 0) {
|
||||
TargetCardInExile target = new TargetCardInExile(0, 1, filter, exileId, false);
|
||||
while (cardsToExile.count(filter, game) > 0 && controller.choose(Outcome.PlayForFree, cardsToExile, target, game)) {
|
||||
Card card = game.getCard(target.getFirstTarget());
|
||||
if (card != null) {
|
||||
controller.cast(card.getSpellAbility(), game, true);
|
||||
cardsToExile.remove(card);
|
||||
} else {
|
||||
break OuterLoop;
|
||||
}
|
||||
target.clearChosen();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ExileZone exileZone = game.getExile().getExileZone(exileId);
|
||||
while (exileZone != null && exileZone.count(filter, game) > 0
|
||||
&& controller.chooseUse(Outcome.PlayForFree, "Cast cards exiled with " + mageObject.getLogName() +" without paying its mana cost?", source, game)) {
|
||||
TargetCardInExile target = new TargetCardInExile(0,1, filter, exileId, false);
|
||||
while (exileZone.count(filter, game) > 0 && controller.choose(Outcome.PlayForFree, exileZone, target, game)) {
|
||||
Card card = game.getCard(target.getFirstTarget());
|
||||
if (card != null) {
|
||||
controller.cast(card.getSpellAbility(), game, true);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
target.clearChosen();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ public class UlamogTheInfiniteGyre extends CardImpl {
|
|||
|
||||
this.power = new MageInt(10);
|
||||
this.toughness = new MageInt(10);
|
||||
|
||||
|
||||
// When you cast Ulamog, the Infinite Gyre, destroy target permanent.
|
||||
this.addAbility(new UlamogTheInfiniteGyreDestroyOnCastAbility());
|
||||
// Annihilator 4 (Whenever this creature attacks, defending player sacrifices four permanents.)
|
||||
|
@ -87,7 +87,7 @@ public class UlamogTheInfiniteGyre extends CardImpl {
|
|||
|
||||
class UlamogTheInfiniteGyreDestroyOnCastAbility extends TriggeredAbilityImpl {
|
||||
|
||||
UlamogTheInfiniteGyreDestroyOnCastAbility ( ) {
|
||||
UlamogTheInfiniteGyreDestroyOnCastAbility() {
|
||||
super(Zone.STACK, new DestroyTargetEffect());
|
||||
this.addTarget(new TargetPermanent());
|
||||
}
|
||||
|
@ -114,13 +114,13 @@ class UlamogTheInfiniteGyreDestroyOnCastAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return new StringBuilder("When you cast {this}, ").append(super.getRule()).toString();
|
||||
return "When you cast {this}, " + super.getRule();
|
||||
}
|
||||
}
|
||||
|
||||
class UlamogTheInfiniteGyreEnterGraveyardEffect extends OneShotEffect {
|
||||
|
||||
UlamogTheInfiniteGyreEnterGraveyardEffect ( ) {
|
||||
UlamogTheInfiniteGyreEnterGraveyardEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "its owner shuffles his or her graveyard into his or her library";
|
||||
}
|
||||
|
@ -144,9 +144,9 @@ class UlamogTheInfiniteGyreEnterGraveyardEffect extends OneShotEffect {
|
|||
}
|
||||
Player player = game.getPlayer(ownerId);
|
||||
if (player != null) {
|
||||
for (Card cardToMove: player.getGraveyard().getCards(game)) {
|
||||
for (Card cardToMove : player.getGraveyard().getCards(game)) {
|
||||
cardToMove.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
player.shuffleLibrary(game);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ import mage.game.Game;
|
|||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.stack.Spell;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -95,6 +96,9 @@ public class TriggeredAbilities extends ConcurrentHashMap<String, TriggeredAbili
|
|||
if (!controllerSet) {
|
||||
if (object instanceof Permanent) {
|
||||
ability.setControllerId(((Permanent) object).getControllerId());
|
||||
} else if (object instanceof Spell) {
|
||||
// needed so that cast triggered abilities have to correct controller (e.g. Ulamog, the Infinite Gyre).
|
||||
ability.setControllerId(((Spell) object).getControllerId());
|
||||
} else if (object instanceof Card) {
|
||||
ability.setControllerId(((Card) object).getOwnerId());
|
||||
}
|
||||
|
|
|
@ -33,11 +33,14 @@ import mage.game.Game;
|
|||
/**
|
||||
* Interface for abilities that add additional costs to the source.
|
||||
*
|
||||
* Example of such additional source costs: {@link mage.abilities.keyword.KickerAbility}
|
||||
* Example of such additional source costs:
|
||||
* {@link mage.abilities.keyword.KickerAbility}
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public interface OptionalAdditionalSourceCosts {
|
||||
|
||||
void addOptionalAdditionalCosts(Ability ability, Game game);
|
||||
|
||||
String getCastMessageSuffix();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@ public class BuybackAbility extends StaticAbility implements OptionalAdditionalS
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActivated() {
|
||||
if (buybackCost != null) {
|
||||
return buybackCost.isActivated();
|
||||
|
@ -112,11 +113,11 @@ public class BuybackAbility extends StaticAbility implements OptionalAdditionalS
|
|||
@Override
|
||||
public void addOptionalAdditionalCosts(Ability ability, Game game) {
|
||||
if (ability instanceof SpellAbility) {
|
||||
Player player = game.getPlayer(controllerId);
|
||||
Player player = game.getPlayer(ability.getControllerId());
|
||||
if (player != null) {
|
||||
this.resetBuyback();
|
||||
if (buybackCost != null) {
|
||||
if (player.chooseUse(Outcome.Benefit, new StringBuilder("Pay ").append(buybackCost.getText(false)).append(" ?").toString(), ability, game)) {
|
||||
if (player.chooseUse(Outcome.Benefit, "Pay " + buybackCost.getText(false) + " ?", ability, game)) {
|
||||
buybackCost.activate();
|
||||
for (Iterator it = ((Costs) buybackCost).iterator(); it.hasNext();) {
|
||||
Cost cost = (Cost) it.next();
|
||||
|
|
Loading…
Reference in a new issue