Fixed Rebound

This commit is contained in:
magenoxx 2012-06-25 10:10:07 +04:00
parent 0c4217adf1
commit 6b57822f40
3 changed files with 40 additions and 42 deletions

View file

@ -160,11 +160,11 @@ public class CardView extends SimpleCardView {
} }
if (this.rarity == null && card instanceof StackAbility) { if (this.rarity == null && card instanceof StackAbility) {
StackAbility stackAbility = (StackAbility)card; StackAbility stackAbility = (StackAbility)card;
this.rarity = Rarity.NA;
this.rules = new ArrayList<String>();
this.rules.add(stackAbility.getRule());
if (stackAbility.getZone().equals(Constants.Zone.COMMAND)) { if (stackAbility.getZone().equals(Constants.Zone.COMMAND)) {
this.rarity = Rarity.NA;
this.expansionSetCode = stackAbility.getExpansionSetCode(); this.expansionSetCode = stackAbility.getExpansionSetCode();
this.rules = new ArrayList<String>();
this.rules.add(stackAbility.getRule());
} }
} }
} }

View file

@ -28,7 +28,6 @@
package mage.abilities.keyword; package mage.abilities.keyword;
import java.util.UUID;
import mage.Constants.Duration; import mage.Constants.Duration;
import mage.Constants.Outcome; import mage.Constants.Outcome;
import mage.Constants.Zone; import mage.Constants.Zone;
@ -46,8 +45,11 @@ import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent.EventType;
import mage.game.events.ZoneChangeEvent; import mage.game.events.ZoneChangeEvent;
import mage.game.stack.Spell; import mage.game.stack.Spell;
import mage.game.stack.StackObject;
import mage.players.Player; import mage.players.Player;
import java.util.UUID;
/** /**
* This ability has no effect by default and will always return false on the call * This ability has no effect by default and will always return false on the call
* to apply. This is because of how the {@link ReboundEffect} works. It will * to apply. This is because of how the {@link ReboundEffect} works. It will
@ -66,20 +68,20 @@ import mage.players.Player;
* ability follows the rules for paying alternative costs in rules 601.2b and 601.2e-g. * ability follows the rules for paying alternative costs in rules 601.2b and 601.2e-g.
* <p/> * <p/>
* 702.85c Multiple instances of rebound on the same spell are redundant. * 702.85c Multiple instances of rebound on the same spell are redundant.
*
* @author maurer.it_at_gmail.com * @author maurer.it_at_gmail.com, noxx
*/ */
public class ReboundAbility extends TriggeredAbilityImpl<ReboundAbility> { public class ReboundAbility extends TriggeredAbilityImpl<ReboundAbility> {
//20101001 - 702.85 //20101001 - 702.85
private boolean installReboundEffect; private boolean installReboundEffect;
private static String reboundText = "Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.)"; private static String reboundText = "Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.)";
public ReboundAbility ( ) { public ReboundAbility() {
super(Zone.STACK, null); super(Zone.STACK, null);
this.installReboundEffect = false; this.installReboundEffect = false;
} }
public ReboundAbility ( final ReboundAbility ability ) { public ReboundAbility(final ReboundAbility ability) {
super(ability); super(ability);
this.installReboundEffect = ability.installReboundEffect; this.installReboundEffect = ability.installReboundEffect;
} }
@ -87,20 +89,19 @@ public class ReboundAbility extends TriggeredAbilityImpl<ReboundAbility> {
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
//Something hit the stack from the hand, see if its a spell with this ability. //Something hit the stack from the hand, see if its a spell with this ability.
if ( event.getType() == EventType.ZONE_CHANGE && if (event.getType() == EventType.ZONE_CHANGE &&
((ZoneChangeEvent)event).getFromZone() == Zone.HAND && ((ZoneChangeEvent) event).getFromZone() == Zone.HAND &&
((ZoneChangeEvent)event).getToZone() == Zone.STACK ) ((ZoneChangeEvent) event).getToZone() == Zone.STACK) {
{ Card card = (Card) game.getObject(event.getTargetId());
Card card = (Card)game.getObject(event.getTargetId());
if ( card.getAbilities().contains(this) ) { if (card.getAbilities().contains(this)) {
this.installReboundEffect = true; this.installReboundEffect = true;
} }
} }
//Only 'install' the effect on a successfully cast spell otherwise the user //Only 'install' the effect on a successfully cast spell otherwise the user
//may cancel before paying its costs and potentially having two copies rebound //may cancel before paying its costs and potentially having two copies rebound
if ( event.getType() == EventType.SPELL_CAST && this.installReboundEffect ) { if (event.getType() == EventType.SPELL_CAST && this.installReboundEffect) {
Spell spell = game.getStack().getSpell(event.getTargetId()); Spell spell = game.getStack().getSpell(event.getTargetId());
if (spell != null && spell.getSourceId().equals(this.getSourceId())) { if (spell != null && spell.getSourceId().equals(this.getSourceId())) {
spell.getSpellAbility().addEffect(new ReboundEffect()); spell.getSpellAbility().addEffect(new ReboundEffect());
@ -135,23 +136,22 @@ class ReboundEffect extends OneShotEffect<ReboundEffect> {
super(Outcome.Benefit); super(Outcome.Benefit);
} }
public ReboundEffect ( ReboundEffect effect ) { public ReboundEffect(ReboundEffect effect) {
super(effect); super(effect);
} }
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Spell sourceSpell = (Spell)game.getObject(source.getId()); Spell sourceSpell = (Spell) game.getObject(source.getId());
if ( sourceSpell != null && sourceSpell.isCopiedSpell() ) { if (sourceSpell != null && sourceSpell.isCopiedSpell()) {
return false; return false;
} } else {
else { StackObject sourceCard = (StackObject) game.getObject(source.getSourceId());
Card sourceCard = (Card)game.getObject(source.getSourceId()); ReboundEffectCastFromExileDelayedTrigger trigger = new ReboundEffectCastFromExileDelayedTrigger(sourceCard.getSourceId(), sourceCard.getSourceId());
ReboundEffectCastFromExileDelayedTrigger trigger = new ReboundEffectCastFromExileDelayedTrigger(sourceCard.getId(), sourceCard.getId());
trigger.setControllerId(source.getControllerId()); trigger.setControllerId(source.getControllerId());
game.addDelayedTriggeredAbility(trigger); game.addDelayedTriggeredAbility(trigger);
game.getContinuousEffects().addEffect(new ReboundCastFromHandReplacementEffect(sourceCard.getId()), source); game.getContinuousEffects().addEffect(new ReboundCastFromHandReplacementEffect(source.getSourceId()), source);
return true; return true;
} }
} }
@ -175,13 +175,13 @@ class ReboundCastFromHandReplacementEffect extends ReplacementEffectImpl<Rebound
private static String replacementText = "Rebound - If you cast {this} from your hand, exile it as it resolves"; private static String replacementText = "Rebound - If you cast {this} from your hand, exile it as it resolves";
private UUID cardId; private UUID cardId;
ReboundCastFromHandReplacementEffect ( UUID cardId ) { ReboundCastFromHandReplacementEffect(UUID cardId) {
super(Duration.OneUse, Outcome.Exile); super(Duration.OneUse, Outcome.Exile);
this.cardId = cardId; this.cardId = cardId;
this.staticText = replacementText; this.staticText = replacementText;
} }
ReboundCastFromHandReplacementEffect ( ReboundCastFromHandReplacementEffect effect ) { ReboundCastFromHandReplacementEffect(ReboundCastFromHandReplacementEffect effect) {
super(effect); super(effect);
this.cardId = effect.cardId; this.cardId = effect.cardId;
} }
@ -198,15 +198,14 @@ class ReboundCastFromHandReplacementEffect extends ReplacementEffectImpl<Rebound
@Override @Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) { public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Spell sourceSpell = (Spell)game.getObject(source.getId()); Spell sourceSpell = (Spell) game.getObject(source.getId());
if ( sourceSpell != null && sourceSpell.isCopiedSpell() ) { if (sourceSpell != null && sourceSpell.isCopiedSpell()) {
return false; return false;
} } else {
else { Card sourceCard = (Card) game.getObject(source.getSourceId());
Card sourceCard = (Card)game.getObject(source.getSourceId());
Player player = game.getPlayer(sourceCard.getOwnerId()); Player player = game.getPlayer(sourceCard.getOwnerId());
sourceCard.moveToExile(source.getSourceId(), player.getName() + " Rebound Exile", source.getId(), game); sourceCard.moveToExile(this.cardId, player.getName() + " Rebound Exile", source.getId(), game);
this.used = true; this.used = true;
return true; return true;
@ -215,11 +214,10 @@ class ReboundCastFromHandReplacementEffect extends ReplacementEffectImpl<Rebound
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if ( event.getType() == EventType.ZONE_CHANGE && if (event.getType() == EventType.ZONE_CHANGE &&
((ZoneChangeEvent)event).getFromZone() == Zone.STACK && ((ZoneChangeEvent) event).getFromZone() == Zone.STACK &&
((ZoneChangeEvent)event).getToZone() == Zone.GRAVEYARD && ((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD &&
source.getSourceId() == this.cardId ) source.getSourceId() == this.cardId) {
{
return true; return true;
} }
return false; return false;
@ -237,13 +235,13 @@ class ReboundCastFromHandReplacementEffect extends ReplacementEffectImpl<Rebound
*/ */
class ReboundEffectCastFromExileDelayedTrigger extends DelayedTriggeredAbility<ReboundEffectCastFromExileDelayedTrigger> { class ReboundEffectCastFromExileDelayedTrigger extends DelayedTriggeredAbility<ReboundEffectCastFromExileDelayedTrigger> {
ReboundEffectCastFromExileDelayedTrigger ( UUID cardId, UUID sourceId ) { ReboundEffectCastFromExileDelayedTrigger(UUID cardId, UUID sourceId) {
super(new ReboundCastSpellFromExileEffect(cardId)); super(new ReboundCastSpellFromExileEffect(cardId));
setSourceId(sourceId); setSourceId(sourceId);
this.optional = true; this.optional = true;
} }
ReboundEffectCastFromExileDelayedTrigger ( ReboundEffectCastFromExileDelayedTrigger ability ) { ReboundEffectCastFromExileDelayedTrigger(ReboundEffectCastFromExileDelayedTrigger ability) {
super(ability); super(ability);
} }
@ -254,7 +252,7 @@ class ReboundEffectCastFromExileDelayedTrigger extends DelayedTriggeredAbility<R
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
if ( event.getType() == EventType.UPKEEP_STEP_PRE && MyTurnCondition.getInstance().apply(game, this) ) { if (event.getType() == EventType.UPKEEP_STEP_PRE && MyTurnCondition.getInstance().apply(game, this)) {
return true; return true;
} }
return false; return false;
@ -272,13 +270,13 @@ class ReboundCastSpellFromExileEffect extends OneShotEffect<ReboundCastSpellFrom
private static String castFromExileText = "Rebound - You may cast {this} from exile without paying its mana cost"; private static String castFromExileText = "Rebound - You may cast {this} from exile without paying its mana cost";
private UUID cardId; private UUID cardId;
ReboundCastSpellFromExileEffect ( UUID cardId ) { ReboundCastSpellFromExileEffect(UUID cardId) {
super(Outcome.Benefit); super(Outcome.Benefit);
this.cardId = cardId; this.cardId = cardId;
staticText = castFromExileText; staticText = castFromExileText;
} }
ReboundCastSpellFromExileEffect ( ReboundCastSpellFromExileEffect effect ) { ReboundCastSpellFromExileEffect(ReboundCastSpellFromExileEffect effect) {
super(effect); super(effect);
this.cardId = effect.cardId; this.cardId = effect.cardId;
} }

View file

@ -488,7 +488,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
card.cast(game, fromZone, ability, playerId); card.cast(game, fromZone, ability, playerId);
Ability spellAbility = game.getStack().getSpell(ability.getId()).getSpellAbility(); Ability spellAbility = game.getStack().getSpell(ability.getId()).getSpellAbility();
if (spellAbility.activate(game, noMana)) { if (spellAbility.activate(game, noMana)) {
for (KickerAbility kicker: card.getAbilities().getKickerAbilities()) { for (KickerAbility kicker: card.getAbilities().getKickerAbilities()) {
if (kicker.getCosts().canPay(ability.getSourceId(), playerId, game) && kicker.canChooseTarget(game)) if (kicker.getCosts().canPay(ability.getSourceId(), playerId, game) && kicker.canChooseTarget(game))
kicker.activate(game, false); kicker.activate(game, false);