mirror of
https://github.com/correl/mage.git
synced 2024-12-25 11:11:16 +00:00
Fixed Rebound
This commit is contained in:
parent
0c4217adf1
commit
6b57822f40
3 changed files with 40 additions and 42 deletions
|
@ -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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue