This commit is contained in:
BetaSteward 2010-11-03 04:06:47 +00:00
parent 2b1d3f6b37
commit ff33253646
37 changed files with 240 additions and 84 deletions

View file

@ -80,8 +80,13 @@ public class PlayerView implements Serializable {
//show permanents controlled by player or attachments to permanents controlled by player
if (permanent.getAttachedTo() == null)
return permanent.getControllerId().equals(playerId);
else
return game.getPermanent(permanent.getAttachedTo()).getControllerId().equals(playerId);
else {
Permanent attachedTo = game.getPermanent(permanent.getAttachedTo());
if (attachedTo != null)
return attachedTo.getControllerId().equals(playerId);
else
return permanent.getControllerId().equals(playerId);
}
}
public int getLife() {

View file

@ -62,7 +62,7 @@ public class Constructed extends DeckValidatorImpl {
countCards(counts, deck.getSideboard());
for (Entry<String, Integer> entry: counts.entrySet()) {
if (entry.getValue() > 4) {
if (!basicLandNames.contains(entry.getKey())) {
if (!basicLandNames.contains(entry.getKey()) && !entry.getKey().equals("Relentless Rats")) {
return false;
}
}

View file

@ -64,7 +64,7 @@ public class ArmoredAscension extends CardImpl<ArmoredAscension> {
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
Ability ability = new EnchantAbility(Outcome.BoostCreature, auraTarget);
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ArmoredAscensionEffect()));

View file

@ -64,7 +64,7 @@ public class IceCage extends CardImpl<IceCage> {
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
Ability ability = new EnchantAbility(Outcome.Detriment, auraTarget);
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new IceCageEffect()));
this.addAbility(new IceCageAbility());

View file

@ -62,7 +62,7 @@ public class MindControl extends CardImpl<MindControl> {
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
Ability ability = new EnchantAbility(Outcome.Detriment, auraTarget);
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MindControlEffect()));

View file

@ -29,6 +29,7 @@
package mage.sets.magic2010;
import java.util.UUID;
import mage.Constants.Rarity;
/**
*
@ -39,6 +40,7 @@ public class PlatinumAngel extends mage.sets.tenth.PlatinumAngel {
public PlatinumAngel(UUID ownerId) {
super(ownerId);
this.expansionSetCode = "M10";
this.rarity = Rarity.MYTHIC;
}
public PlatinumAngel(final PlatinumAngel card) {

View file

@ -61,7 +61,7 @@ public class Weakness extends CardImpl<Weakness> {
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.UnboostCreature));
Ability ability = new EnchantAbility(Outcome.BoostCreature, auraTarget);
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new WeaknessEffect()));
}
@ -77,7 +77,7 @@ public class Weakness extends CardImpl<Weakness> {
@Override
public String getArt() {
return "102510_typ_reg_sty_010.jpg";
return "02510_typ_reg_sty_010.jpg";
}
}

View file

@ -65,7 +65,7 @@ public class DryadsFavor extends CardImpl<DryadsFavor> {
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Benefit));
Ability ability = new EnchantAbility(Outcome.Benefit, auraTarget);
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DryadsFavorEffect()));

View file

@ -71,7 +71,7 @@ public class NecroticPlague extends CardImpl<NecroticPlague> {
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
Ability ability = new EnchantAbility(Outcome.Detriment, auraTarget);
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new NecroticPlagueEffect()));

View file

@ -34,7 +34,7 @@ import java.util.UUID;
*
* @author BetaSteward_at_googlemail.com
*/
public class PlatinumAngel extends mage.sets.tenth.PlatinumAngel {
public class PlatinumAngel extends mage.sets.magic2010.PlatinumAngel {
public PlatinumAngel(UUID ownerId) {
super(ownerId);

View file

@ -62,7 +62,7 @@ public class PrimalCocoon extends CardImpl<PrimalCocoon> {
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Benefit));
Ability ability = new EnchantAbility(Outcome.Benefit, auraTarget);
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
this.addAbility(new PrimalCocoonAbility1());
this.addAbility(new PrimalCocoonAbility2());

View file

@ -62,7 +62,7 @@ public class HolyStrength extends CardImpl<HolyStrength> {
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
Ability ability = new EnchantAbility(Outcome.BoostCreature, auraTarget);
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new HolyStrengthEffect()));

View file

@ -65,7 +65,7 @@ public class Pacifism extends CardImpl<Pacifism> {
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
Ability ability = new EnchantAbility(Outcome.Detriment, auraTarget);
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PacifismEffect()));

View file

@ -52,7 +52,7 @@ import mage.game.events.GameEvent.EventType;
public class PlatinumAngel extends CardImpl<PlatinumAngel> {
public PlatinumAngel(UUID ownerId) {
super(ownerId, "Platinum Angel", Rarity.MYTHIC, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{7}");
super(ownerId, "Platinum Angel", Rarity.RARE, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{7}");
this.expansionSetCode = "10E";
this.subtype.add("Angel");
this.power = new MageInt(4);

View file

@ -98,7 +98,7 @@ class OranRiefTheVastwoodEffect extends OneShotEffect<OranRiefTheVastwoodEffect>
filter.getColor().setGreen(true);
for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
if (permanent.getTurnsOnBattlefield() == 0) {
permanent.getCounters().addCounter(new PlusOneCounter());
permanent.addCounters(new PlusOneCounter());
}
}
return true;

View file

@ -65,7 +65,7 @@ public class SpreadingSeas extends CardImpl<SpreadingSeas> {
TargetPermanent auraTarget = new TargetLandPermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
Ability ability = new EnchantAbility(Outcome.Detriment, auraTarget);
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardControllerEffect(1), false));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SpreadingSeasEffect()));

View file

@ -284,6 +284,7 @@ public final class Constants {
Tap(false),
Untap(true),
Win(true),
Copy(true),
Benefit(true),
Detriment(false),
Neutral(true);

View file

@ -46,6 +46,8 @@ import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.Effects;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.Card;
import mage.choices.Choice;
import mage.choices.Choices;
import mage.game.Game;
@ -139,21 +141,40 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
@Override
public boolean activate(Game game, boolean noMana) {
//20100716 - 601.2b
if (choices.size() > 0 && choices.choose(game, this) == false) {
logger.fine("activate failed - choice");
return false;
}
//20100716 - 114.1b
// if (game.getObject(sourceId).getSubtype().contains("Aura")) {
// for (Ability ability: game.getObject(sourceId).getAbilities()) {
// if (ability instanceof EnchantAbility) {
// Targets enchantTargets = ability.getTargets();
// if (enchantTargets.size() > 0 && enchantTargets.chooseTargets(ability.getEffects().get(0).getOutcome(), this.controllerId, this, game) == false) {
// logger.fine("activate failed - target");
// return false;
// }
// break;
// }
// }
// }
//20100716 - 601.2b
if (targets.size() > 0 && targets.chooseTargets(effects.get(0).getOutcome(), this.controllerId, this, game) == false) {
logger.fine("activate failed - target");
return false;
}
game.getObject(sourceId).adjustCosts(this, game);
//20100716 - 601.2e
if (game.getObject(sourceId) != null)
game.getObject(sourceId).adjustCosts(this, game);
if (!useAlternativeCost(game)) {
//20100716 - 601.2f
if (!manaCosts.pay(game, sourceId, controllerId, noMana)) {
logger.fine("activate failed - mana");
return false;
}
}
//20100716 - 601.2g
if (!costs.pay(game, sourceId, controllerId, noMana)) {
logger.fine("activate failed - non mana costs");
return false;

View file

@ -67,7 +67,7 @@ public class RemoveCountersSourceCost extends CostImpl<RemoveCountersSourceCost>
public boolean pay(Game game, UUID sourceId, UUID controllerId, boolean noMana) {
Permanent permanent = game.getPermanent(sourceId);
if (permanent != null && permanent.getCounters().getCount(name) >= amount) {
permanent.getCounters().removeCounter(name, amount);
permanent.removeCounters(name, amount, game);
this.paid = true;
}
return paid;

View file

@ -60,9 +60,7 @@ public class AddCountersSourceEffect extends OneShotEffect<AddCountersSourceEffe
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
Counter counter = new Counter(name);
counter.add(amount);
permanent.getCounters().addCounter(counter);
permanent.addCounters(name, amount);
}
return true;
}

View file

@ -60,9 +60,7 @@ public class AddCountersTargetEffect extends OneShotEffect<AddCountersTargetEffe
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (permanent != null) {
Counter counter = new Counter(name);
counter.add(amount);
permanent.getCounters().addCounter(counter);
permanent.addCounters(name, amount);
}
return true;
}

View file

@ -64,7 +64,7 @@ public class AddPlusOneCountersAttachedEffect extends OneShotEffect<AddPlusOneCo
if (enchantment != null && enchantment.getAttachedTo() != null) {
Permanent creature = game.getPermanent(enchantment.getAttachedTo());
if (creature != null) {
creature.getCounters().addCounter(new PlusOneCounter(amount));
creature.addCounters(new PlusOneCounter(amount));
}
}
return true;

View file

@ -62,7 +62,7 @@ public class AddPlusOneCountersSourceEffect extends OneShotEffect<AddPlusOneCoun
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
permanent.getCounters().addCounter(new PlusOneCounter(amount));
permanent.addCounters(new PlusOneCounter(amount));
}
return true;
}

View file

@ -33,8 +33,6 @@ import mage.Constants.Outcome;
import mage.abilities.Ability;
import mage.abilities.effects.RequirementAttackEffect;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetDefender;

View file

@ -39,7 +39,6 @@ import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.stack.Spell;
import mage.game.stack.StackObject;
/**
*
@ -86,9 +85,9 @@ public class CantCounterControlledEffect extends ReplacementEffectImpl<CantCount
if (event.getType() == EventType.COUNTER) {
filterTarget.getControllerId().clear();
filterTarget.getControllerId().add(source.getControllerId());
StackObject stackObject = game.getStack().getStackObject(event.getTargetId());
if (stackObject != null && stackObject instanceof Spell) {
if (filterTarget.match((Spell) stackObject)) {
Spell spell = game.getStack().getSpell(event.getTargetId());
if (spell != null) {
if (filterTarget.match(spell)) {
if (filterSource == null)
return true;
else {

View file

@ -34,6 +34,7 @@ import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
@ -42,12 +43,20 @@ import mage.players.Player;
*/
public class ReturnSourceFromGraveyardToBattlefieldEffect extends OneShotEffect<ReturnSourceFromGraveyardToBattlefieldEffect> {
private boolean tapped;
public ReturnSourceFromGraveyardToBattlefieldEffect() {
this(false);
}
public ReturnSourceFromGraveyardToBattlefieldEffect(boolean tapped) {
super(Outcome.PutCreatureInPlay);
this.tapped = tapped;
}
public ReturnSourceFromGraveyardToBattlefieldEffect(final ReturnSourceFromGraveyardToBattlefieldEffect effect) {
super(effect);
this.tapped = effect.tapped;
}
@Override
@ -61,15 +70,24 @@ public class ReturnSourceFromGraveyardToBattlefieldEffect extends OneShotEffect<
Card card = player.getGraveyard().get(source.getSourceId(), game);
if (card != null) {
player.removeFromGraveyard(card, game);
card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getControllerId());
return true;
if (card.putOntoBattlefield(game, Zone.HAND, source.getControllerId())) {
if (tapped) {
Permanent permanent = game.getPermanent(card.getId());
if (permanent != null)
permanent.setTapped(true);
}
return true;
}
}
return false;
}
@Override
public String getText(Ability source) {
return "Return {this} from your graveyard to the battlefield";
if (tapped)
return "Return {this} from your graveyard to the battlefield tapped";
else
return "Return {this} from your graveyard to the battlefield";
}
}

View file

@ -40,13 +40,16 @@ import mage.target.TargetPermanent;
*/
public class EnchantAbility extends StaticAbility<EnchantAbility> {
public EnchantAbility(Outcome outcome, TargetPermanent target) {
super(Zone.BATTLEFIELD, new AttachEffect(outcome));
this.addTarget(target);
protected String targetName;
public EnchantAbility(String targetName) {
super(Zone.BATTLEFIELD, null);
this.targetName = targetName;
}
public EnchantAbility(final EnchantAbility ability) {
super(ability);
this.targetName = ability.targetName;
}
@Override
@ -56,7 +59,7 @@ public class EnchantAbility extends StaticAbility<EnchantAbility> {
@Override
public String getRule() {
return "Enchant " + this.getTargets().get(0).getTargetName();
return "Enchant " + targetName;
}

View file

@ -83,40 +83,6 @@ public class UnearthAbility extends ActivatedAbilityImpl<UnearthAbility> {
}
//class UnearthEffect extends OneShotEffect<UnearthEffect> {
//
// public UnearthEffect() {
// super(Outcome.PutCreatureInPlay);
// }
//
// public UnearthEffect(final UnearthEffect effect) {
// super(effect);
// }
//
// @Override
// public UnearthEffect copy() {
// return new UnearthEffect(this);
// }
//
// @Override
// public boolean apply(Game game, Ability source) {
// Player player = game.getPlayer(source.getControllerId());
// Card card = player.getGraveyard().get(source.getSourceId(), game);
// if (card != null) {
// player.putOntoBattlefield(card, game);
// player.removeFromGraveyard(card, game);
// return true;
// }
// return false;
// }
//
// @Override
// public String getText(Ability source) {
// return "Return {this} from your graveyard to the battlefield";
// }
//
//}
class UnearthDelayedTriggeredAbility extends DelayedTriggeredAbility<UnearthDelayedTriggeredAbility> {
public UnearthDelayedTriggeredAbility() {

View file

@ -0,0 +1,58 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.filter.common;
import mage.Constants.CardType;
import mage.filter.FilterPermanent;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class FilterAura extends FilterPermanent<FilterAura> {
public FilterAura() {
this("aura");
}
public FilterAura(String name) {
super(name);
this.cardType.add(CardType.ENCHANTMENT);
this.getSubtype().add("Aura");
}
public FilterAura(final FilterAura filter) {
super(filter);
}
@Override
public FilterAura copy() {
return new FilterAura(this);
}
}

View file

@ -57,7 +57,9 @@ import mage.abilities.keyword.LeylineAbility;
import mage.cards.Card;
import mage.cards.Cards;
import mage.choices.Choice;
import mage.filter.Filter;
import mage.filter.Filter.ComparisonScope;
import mage.filter.common.FilterAura;
import mage.filter.common.FilterEquipment;
import mage.filter.common.FilterFortification;
import mage.filter.common.FilterLegendaryPermanent;
@ -89,6 +91,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
private static FilterPlaneswalkerPermanent filterPlaneswalker = new FilterPlaneswalkerPermanent();
private static FilterLegendaryPermanent filterLegendary = new FilterLegendaryPermanent();
private static FilterLegendaryPermanent filterLegendName = new FilterLegendaryPermanent();
private static FilterAura filterAura = new FilterAura();
private static FilterEquipment filterEquipment = new FilterEquipment();
private static FilterFortification filterFortification = new FilterFortification();
@ -570,6 +573,25 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
}
}
}
//20091005 - 704.5n
for (Permanent perm: getBattlefield().getAllActivePermanents(filterAura)) {
if (perm.getAttachedTo() == null) {
perm.moveToZone(Zone.GRAVEYARD, this, false);
}
else {
//TODO: handle player auras
Permanent attachedTo = getPermanent(perm.getAttachedTo());
if (attachedTo == null) {
perm.moveToZone(Zone.GRAVEYARD, this, false);
}
else {
Filter auraFilter = perm.getSpellAbility().getTargets().get(0).getFilter();
if (!auraFilter.match(attachedTo)) {
perm.moveToZone(Zone.GRAVEYARD, this, false);
}
}
}
}
//20091005 - 704.5k, 801.12
if (getBattlefield().countAll(filterLegendary) > 1) { //don't bother checking if less than 2 legends in play
for (Permanent legend: getBattlefield().getAllActivePermanents(filterLegendary)) {

View file

@ -41,6 +41,7 @@ public class GameEvent {
private UUID sourceId;
private UUID playerId;
private int amount;
private String data;
public enum EventType {
@ -109,6 +110,7 @@ public class GameEvent {
SACRIFICE_PERMANENT, SACRIFICED_PERMANENT,
ATTACH, ATTACHED,
UNATTACH, UNATTACHED,
COUNTER_REMOVED,
//combat events
COMBAT_DAMAGE_APPLIED,
@ -164,4 +166,11 @@ public class GameEvent {
this.amount = amount;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}

View file

@ -30,10 +30,10 @@ package mage.game.permanent;
import java.util.List;
import java.util.UUID;
import mage.Constants.Zone;
import mage.MageObject;
import mage.abilities.Ability;
import mage.cards.Card;
import mage.counters.Counter;
import mage.counters.Counters;
import mage.game.Game;
import mage.game.events.GameEvent;
@ -71,12 +71,13 @@ public interface Permanent extends Card {
public int damage(int damage, UUID sourceId, Game game, boolean preventable);
public void removeAllDamage(Game game);
public Counters getCounters();
public void addCounters(String name, int amount);
public void addCounters(Counter counter);
public void removeCounters(String name, int amount, Game game);
public void reset(Game game);
public boolean destroy(UUID sourceId, Game game, boolean noRegen);
public boolean sacrifice(UUID sourceId, Game game);
public void entersBattlefield(Game game);
// public boolean moveToZone(Zone zone, Game game, boolean flag);
// public boolean moveToExile(UUID exileId, String name, Game game);
public String getValue();
public void setArt(String art);

View file

@ -50,6 +50,7 @@ import mage.abilities.keyword.LifelinkAbility;
import mage.abilities.keyword.ProtectionAbility;
import mage.abilities.keyword.ShroudAbility;
import mage.cards.CardImpl;
import mage.counters.Counter;
import mage.counters.Counters;
import mage.game.Game;
import mage.game.events.GameEvent;
@ -141,6 +142,25 @@ public abstract class PermanentImpl<T extends PermanentImpl<T>> extends CardImpl
return counters;
}
@Override
public void addCounters(String name, int amount) {
counters.addCounter(name, amount);
}
@Override
public void addCounters(Counter counter) {
counters.addCounter(counter);
}
@Override
public void removeCounters(String name, int amount, Game game) {
counters.removeCounter(name, amount);
GameEvent event = GameEvent.getEvent(EventType.COUNTER_REMOVED, objectId, controllerId);
event.setData(name);
for (int i = 0; i < amount; i++)
game.fireEvent(event);
}
@Override
public int getTurnsOnBattlefield() {
return turnsOnBattlefield;

View file

@ -36,14 +36,18 @@ import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.MageInt;
import mage.MageObject;
import mage.ObjectColor;
import mage.abilities.Abilities;
import mage.abilities.Ability;
import mage.abilities.costs.mana.ManaCost;
import mage.abilities.costs.mana.ManaCosts;
import mage.abilities.effects.common.ExileSpellEffect;
import mage.abilities.keyword.KickerAbility;
import mage.cards.Card;
import mage.game.events.GameEvent;
import mage.players.Player;
import mage.target.Target;
import mage.watchers.Watchers;
/**
@ -83,7 +87,6 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
game.getExile().getPermanentExile().add(card);
else
card.moveToZone(Zone.GRAVEYARD, game, false);
// game.getPlayers().get(controllerId).putInGraveyard(card, game, false);
return result;
}
//20091005 - 608.2b
@ -121,6 +124,26 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
return replaced;
}
public boolean chooseNewTargets(Game game) {
Player player = game.getPlayer(controllerId);
for (Target target: ability.getTargets()) {
Target newTarget = target.copy();
newTarget.clearChosen();
for (UUID targetId: target.getTargets()) {
MageObject object = game.getObject(targetId);
if (player.chooseUse(ability.getEffects().get(0).getOutcome(), "Change target from " + object.getName() + "?", game)) {
if (!player.chooseTarget(ability.getEffects().get(0).getOutcome(), newTarget, ability, game))
newTarget.addTarget(targetId, ability, game);
}
}
target.getTargets().clear();
for (UUID newTargetId: newTarget.getTargets()) {
target.getTargets().add(newTargetId);
}
}
return true;
}
@Override
public void counter(Game game) {
card.moveToZone(Zone.GRAVEYARD, game, false);
@ -168,7 +191,7 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
}
@Override
public Abilities getAbilities() {
public Abilities<Ability> getAbilities() {
return card.getAbilities();
}
@ -178,7 +201,7 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
}
@Override
public ManaCosts getManaCost() {
public ManaCosts<ManaCost> getManaCost() {
return card.getManaCost();
}

View file

@ -121,6 +121,18 @@ public class SpellStack extends Stack<StackObject> {
return null;
}
public Spell getSpell(UUID id) {
for (StackObject stackObject: this) {
if (stackObject.getId().equals(id)) {
if (stackObject instanceof Spell)
return (Spell)stackObject;
else
return null;
}
}
return null;
}
public SpellStack copy() {
return new SpellStack(this);
}

View file

@ -337,7 +337,9 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
permanent.removeFromCombat(game);
game.getBattlefield().removePermanent(permanent.getId());
if (permanent.getAttachedTo() != null) {
game.getPermanent(permanent.getAttachedTo()).removeAttachment(permanent.getId(), game);
Permanent attachedTo = game.getPermanent(permanent.getAttachedTo());
if (attachedTo != null)
attachedTo.removeAttachment(permanent.getId(), game);
}
return true;
}

View file

@ -78,9 +78,9 @@ public class TargetSpell extends TargetObject<TargetSpell> {
@Override
public boolean canTarget(UUID id, Ability source, Game game) {
StackObject stackObject = game.getStack().getStackObject(id);
if (stackObject != null && stackObject instanceof Spell) {
return filter.match((Spell)stackObject);
Spell spell = game.getStack().getSpell(id);
if (spell != null) {
return filter.match(spell);
}
return false;
}