* Animate Dead (finished). Only Battlefield layout can't handle a attached card in graveyard yet.

This commit is contained in:
LevelX2 2014-11-06 15:34:18 +01:00
parent 813841eccd
commit 220331dcd9
4 changed files with 70 additions and 47 deletions

View file

@ -57,7 +57,7 @@ public class RelativeLayout implements LayoutManager2, java.io.Serializable {
private static final int MINIMUM = 0; private static final int MINIMUM = 0;
private static final int PREFERRED = 1; private static final int PREFERRED = 1;
private Map<Component, Float> constraints = new HashMap<Component, Float>(); private final Map<Component, Float> constraints = new HashMap<>();
/** /**
* The axis of the Components within the Container. * The axis of the Components within the Container.
@ -222,6 +222,7 @@ public class RelativeLayout implements LayoutManager2, java.io.Serializable {
/** /**
* Change size of relative components to fill the space available For X-AXIS aligned components the height will be * Change size of relative components to fill the space available For X-AXIS aligned components the height will be
* filled. For Y-AXIS aligned components the width will be filled. * filled. For Y-AXIS aligned components the width will be filled.
* @param fill
*/ */
public void setFill(boolean fill) { public void setFill(boolean fill) {
this.fill = fill; this.fill = fill;
@ -238,6 +239,7 @@ public class RelativeLayout implements LayoutManager2, java.io.Serializable {
/** /**
* Specify the number of pixels by which the fill size is decreased when setFill(true) has been specified. * Specify the number of pixels by which the fill size is decreased when setFill(true) has been specified.
* @param fillGap
*/ */
public void setFillGap(int fillGap) { public void setFillGap(int fillGap) {
this.fillGap = fillGap; this.fillGap = fillGap;
@ -258,6 +260,7 @@ public class RelativeLayout implements LayoutManager2, java.io.Serializable {
* DO_NOTHING FIRST - extra pixels added to the first relative component LAST - extra pixels added to the last * DO_NOTHING FIRST - extra pixels added to the first relative component LAST - extra pixels added to the last
* relative component LARGEST (default) - extra pixels added to the larger relative component EQUAL - a single pixel * relative component LARGEST (default) - extra pixels added to the larger relative component EQUAL - a single pixel
* is added to each relative component (until pixels are used up) * is added to each relative component (until pixels are used up)
* @param roundingPolicy
*/ */
public void setRoundingPolicy(int roundingPolicy) { public void setRoundingPolicy(int roundingPolicy) {
this.roundingPolicy = roundingPolicy; this.roundingPolicy = roundingPolicy;
@ -275,6 +278,8 @@ public class RelativeLayout implements LayoutManager2, java.io.Serializable {
/** /**
* Not supported * Not supported
* @param name
* @param component
*/ */
@Override @Override
public void addLayoutComponent(String name, Component component) { public void addLayoutComponent(String name, Component component) {
@ -310,7 +315,7 @@ public class RelativeLayout implements LayoutManager2, java.io.Serializable {
* of a column layout is the largest preferred height of each row in the container, plus the vertical padding times * of a column layout is the largest preferred height of each row in the container, plus the vertical padding times
* the number of rows minus one, plus the top and bottom insets of the target container. * the number of rows minus one, plus the top and bottom insets of the target container.
* *
* @param target the container in which to do the layout * @param parent the container in which to do the layout
* @return the preferred dimensions to lay out the subcomponents of the specified container * @return the preferred dimensions to lay out the subcomponents of the specified container
* @see java.awt.RelativeLayout#minimumLayoutSize * @see java.awt.RelativeLayout#minimumLayoutSize
* @see java.awt.Container#getPreferredSize() * @see java.awt.Container#getPreferredSize()
@ -329,7 +334,7 @@ public class RelativeLayout implements LayoutManager2, java.io.Serializable {
* layout is the largest minimum height of each row in the container, plus the vertical padding times the number of * layout is the largest minimum height of each row in the container, plus the vertical padding times the number of
* rows minus one, plus the top and bottom insets of the target container. * rows minus one, plus the top and bottom insets of the target container.
* *
* @param target the container in which to do the layout * @param parent the container in which to do the layout
* @return the minimum dimensions needed to lay out the subcomponents of the specified container * @return the minimum dimensions needed to lay out the subcomponents of the specified container
* @see java.awt.RelativeLayout#preferredLayoutSize * @see java.awt.RelativeLayout#preferredLayoutSize
* @see java.awt.Container#doLayout * @see java.awt.Container#doLayout
@ -349,7 +354,7 @@ public class RelativeLayout implements LayoutManager2, java.io.Serializable {
* the layout. The container's free space equals the container's size minus any insets and any specified horizontal * the layout. The container's free space equals the container's size minus any insets and any specified horizontal
* or vertical gap. All components in a grid layout are given the same size. * or vertical gap. All components in a grid layout are given the same size.
* *
* @param target the container in which to do the layout * @param parent the container in which to do the layout
* @see java.awt.Container * @see java.awt.Container
* @see java.awt.Container#doLayout * @see java.awt.Container#doLayout
*/ */
@ -581,7 +586,7 @@ public class RelativeLayout implements LayoutManager2, java.io.Serializable {
Float constraint = constraints.get(component); Float constraint = constraints.get(component);
if (constraint != null) { if (constraint != null) {
int space = (int) (spaceAvailable * constraint.floatValue() / relativeTotal); int space = (int) (spaceAvailable * constraint / relativeTotal);
relativeSpace[i] = space; relativeSpace[i] = space;
spaceUsed += space; spaceUsed += space;
} }
@ -750,6 +755,8 @@ public class RelativeLayout implements LayoutManager2, java.io.Serializable {
/** /**
* There is no maximum. * There is no maximum.
* @param target
* @return
*/ */
@Override @Override
public Dimension maximumLayoutSize(Container target) { public Dimension maximumLayoutSize(Container target) {
@ -758,6 +765,8 @@ public class RelativeLayout implements LayoutManager2, java.io.Serializable {
/** /**
* Returns the alignment along the x axis. Use center alignment. * Returns the alignment along the x axis. Use center alignment.
* @param parent
* @return
*/ */
@Override @Override
public float getLayoutAlignmentX(Container parent) { public float getLayoutAlignmentX(Container parent) {
@ -766,6 +775,8 @@ public class RelativeLayout implements LayoutManager2, java.io.Serializable {
/** /**
* Returns the alignment along the y axis. Use center alignment. * Returns the alignment along the y axis. Use center alignment.
* @param parent
* @return
*/ */
@Override @Override
public float getLayoutAlignmentY(Container parent) { public float getLayoutAlignmentY(Container parent) {
@ -774,6 +785,7 @@ public class RelativeLayout implements LayoutManager2, java.io.Serializable {
/** /**
* Invalidates the layout, indicating that if the layout manager has cached information it should be discarded. * Invalidates the layout, indicating that if the layout manager has cached information it should be discarded.
* @param target
*/ */
@Override @Override
public void invalidateLayout(Container target) { public void invalidateLayout(Container target) {

View file

@ -41,7 +41,6 @@ import mage.client.plugins.impl.Plugins;
import mage.client.util.Config; import mage.client.util.Config;
import mage.client.util.audio.AudioManager; import mage.client.util.audio.AudioManager;
import mage.client.util.layout.CardLayoutStrategy; import mage.client.util.layout.CardLayoutStrategy;
import mage.client.util.layout.impl.OldCardLayoutStrategy;
import mage.constants.CardType; import mage.constants.CardType;
import mage.utils.CardUtil; import mage.utils.CardUtil;
import mage.view.CounterView; import mage.view.CounterView;
@ -56,6 +55,7 @@ import java.awt.event.ComponentEvent;
import java.util.*; import java.util.*;
import java.util.List; import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
import mage.client.util.layout.impl.OldCardLayoutStrategy;
/** /**
* *
@ -75,7 +75,7 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
private JScrollPane jScrollPane; private JScrollPane jScrollPane;
private int width; private int width;
private CardLayoutStrategy layoutStrategy = new OldCardLayoutStrategy(); private final CardLayoutStrategy layoutStrategy = new OldCardLayoutStrategy();
//private static int iCounter = 0; //private static int iCounter = 0;
@ -137,7 +137,7 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
if (s1 != s2) { if (s1 != s2) {
changed = true; changed = true;
} else if (s1 > 0) { } else if (s1 > 0) {
Set<UUID> attachmentIds = new HashSet<UUID>(); Set<UUID> attachmentIds = new HashSet<>();
attachmentIds.addAll(permanent.getAttachments()); attachmentIds.addAll(permanent.getAttachments());
for (MagePermanent magePermanent : oldMagePermanent.getLinks()) { for (MagePermanent magePermanent : oldMagePermanent.getLinks()) {
if (!attachmentIds.contains(magePermanent.getOriginalPermanent().getId())) { if (!attachmentIds.contains(magePermanent.getOriginalPermanent().getId())) {
@ -164,7 +164,7 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
List<CounterView> counters2 = permanent.getCounters(); List<CounterView> counters2 = permanent.getCounters();
if (counters1 == null && counters2 != null || counters1 != null && counters2 == null) { if (counters1 == null && counters2 != null || counters1 != null && counters2 == null) {
changed = true; changed = true;
} else if (counters1 != null && counters1.size() != counters2.size()) { } else if (counters1 != null && counters2 != null && counters1.size() != counters2.size()) {
changed = true; changed = true;
} }
} }

View file

@ -29,24 +29,27 @@ package mage.sets.limitedalpha;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.StaticAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.LeavesBattlefieldTriggeredAbility; import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.SourceOnBattelfieldCondition; import mage.abilities.condition.common.SourceOnBattelfieldCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continious.BoostEnchantedEffect; import mage.abilities.effects.common.continious.BoostEnchantedEffect;
import mage.abilities.effects.common.continious.SourceEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.SubLayer;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.common.FilterCreatureCard; import mage.filter.common.FilterCreatureCard;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.other.AuraPermanentCanAttachToPermanentId;
import mage.filter.predicate.permanent.PermanentIdPredicate; import mage.filter.predicate.permanent.PermanentIdPredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -72,15 +75,17 @@ public class AnimateDead extends CardImpl {
TargetCardInGraveyard auraTarget = new TargetCardInGraveyard(new FilterCreatureCard("creature card in a graveyard")); TargetCardInGraveyard auraTarget = new TargetCardInGraveyard(new FilterCreatureCard("creature card in a graveyard"));
this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AnimateDeadAttachEffect(Outcome.PutCreatureInPlay)); this.getSpellAbility().addEffect(new AnimateDeadAttachEffect(Outcome.PutCreatureInPlay));
Ability enchantAbility = new AnimateDeadEnchantAbility(auraTarget.getTargetName()); Ability enchantAbility = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(enchantAbility); this.addAbility(enchantAbility);
// When Animate Dead enters the battlefield, if it's on the battlefield, it loses "enchant creature card in a graveyard" // When Animate Dead enters the battlefield, if it's on the battlefield, it loses "enchant creature card in a graveyard"
// and gains "enchant creature put onto the battlefield with Animate Dead." Return enchanted creature card to the battlefield // and gains "enchant creature put onto the battlefield with Animate Dead." Return enchanted creature card to the battlefield
// under your control and attach Animate Dead to it. When Animate Dead leaves the battlefield, that creature's controller sacrifices it. // under your control and attach Animate Dead to it. When Animate Dead leaves the battlefield, that creature's controller sacrifices it.
this.addAbility(new ConditionalTriggeredAbility( Ability ability = new ConditionalTriggeredAbility(
new EntersBattlefieldTriggeredAbility(new AnimateDeadReAttachEffect(), false), new EntersBattlefieldTriggeredAbility(new AnimateDeadReAttachEffect(), false),
SourceOnBattelfieldCondition.getInstance(), SourceOnBattelfieldCondition.getInstance(),
"When Animate Dead enters the battlefield, if it's on the battlefield, it loses \"enchant creature card in a graveyard\" and gains \"enchant creature put onto the battlefield with Animate Dead.\" Return enchanted creature card to the battlefield under your control and attach Animate Dead to it.")); "When Animate Dead enters the battlefield, if it's on the battlefield, it loses \"enchant creature card in a graveyard\" and gains \"enchant creature put onto the battlefield with Animate Dead.\" Return enchanted creature card to the battlefield under your control and attach Animate Dead to it.");
ability.addEffect(new AnimateDeadChangeAbilityEffect());
this.addAbility(ability);
this.addAbility(new LeavesBattlefieldTriggeredAbility(new AnimateDeadLeavesBattlefieldTriggeredEffect(), false)); this.addAbility(new LeavesBattlefieldTriggeredAbility(new AnimateDeadLeavesBattlefieldTriggeredEffect(), false));
// Enchanted creature gets -1/-0. // Enchanted creature gets -1/-0.
@ -102,7 +107,7 @@ class AnimateDeadReAttachEffect extends OneShotEffect {
public AnimateDeadReAttachEffect() { public AnimateDeadReAttachEffect() {
super(Outcome.Benefit); super(Outcome.Benefit);
this.staticText = "if it's on the battlefield, it loses \"enchant creature card in a graveyard\" and gains \"enchant creature put onto the battlefield with Animate Dead.\" Return enchanted creature card to the battlefield under your control and attach Animate Dead to it"; this.staticText = "Return enchanted creature card to the battlefield under your control and attach {this} to it";
} }
public AnimateDeadReAttachEffect(final AnimateDeadReAttachEffect effect) { public AnimateDeadReAttachEffect(final AnimateDeadReAttachEffect effect) {
@ -129,20 +134,10 @@ class AnimateDeadReAttachEffect extends OneShotEffect {
controller.putOntoBattlefieldWithInfo(cardInGraveyard, game, Zone.GRAVEYARD, source.getSourceId()); controller.putOntoBattlefieldWithInfo(cardInGraveyard, game, Zone.GRAVEYARD, source.getSourceId());
Permanent enchantedCreature = game.getPermanent(cardInGraveyard.getId()); Permanent enchantedCreature = game.getPermanent(cardInGraveyard.getId());
AnimateDeadEnchantAbility enchantAbility = null;
for (Ability ability : enchantment.getAbilities()) {
if (ability instanceof AnimateDeadEnchantAbility) {
enchantAbility = (AnimateDeadEnchantAbility) ability;
break;
}
}
if (enchantAbility == null) {
return false;
}
FilterCreaturePermanent filter = new FilterCreaturePermanent("enchant creature put onto the battlefield with Animate Dead"); FilterCreaturePermanent filter = new FilterCreaturePermanent("enchant creature put onto the battlefield with Animate Dead");
filter.add(new PermanentIdPredicate(cardInGraveyard.getId())); filter.add(new PermanentIdPredicate(cardInGraveyard.getId()));
Target target = new TargetCreaturePermanent(filter); Target target = new TargetCreaturePermanent(filter);
enchantAbility.setTargetName(target.getTargetName()); //enchantAbility.setTargetName(target.getTargetName());
if (enchantedCreature != null) { if (enchantedCreature != null) {
target.addTarget(enchantedCreature.getId(), source, game); target.addTarget(enchantedCreature.getId(), source, game);
enchantment.getSpellAbility().getTargets().clear(); enchantment.getSpellAbility().getTargets().clear();
@ -225,36 +220,51 @@ class AnimateDeadAttachEffect extends OneShotEffect {
} }
class AnimateDeadEnchantAbility extends StaticAbility { class AnimateDeadChangeAbilityEffect extends ContinuousEffectImpl implements SourceEffect {
protected String targetName; private final static Ability newAbility = new EnchantAbility("creature put onto the battlefield with Animate Dead");
public AnimateDeadEnchantAbility(String targetName) { static {
super(Zone.BATTLEFIELD, null); newAbility.setRuleAtTheTop(true);
this.targetName = targetName;
} }
public AnimateDeadEnchantAbility(final AnimateDeadEnchantAbility ability) { public AnimateDeadChangeAbilityEffect() {
super(ability); super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
this.targetName = ability.targetName; staticText = "it loses \"enchant creature card in a graveyard\" and gains \"enchant creature put onto the battlefield with Animate Dead\"";
}
public AnimateDeadChangeAbilityEffect(final AnimateDeadChangeAbilityEffect effect) {
super(effect);
} }
@Override @Override
public AnimateDeadEnchantAbility copy() { public AnimateDeadChangeAbilityEffect copy() {
return new AnimateDeadEnchantAbility(this); return new AnimateDeadChangeAbilityEffect(this);
}
public void setTargetName(String name) {
this.targetName = name;
} }
@Override @Override
public String getRule() { public void init(Ability source, Game game) {
StringBuilder sb = new StringBuilder(); super.init(source, game);
sb.append("Enchant ").append(targetName); getAffectedObjects().add(source.getSourceId());
if (!this.getEffects().isEmpty()) { }
sb.append(". ").append(super.getRule());
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
Ability abilityToRemove = null;
for (Ability ability: permanent.getAbilities()) {
if (ability instanceof EnchantAbility) {
abilityToRemove = ability;
}
}
if (abilityToRemove != null) {
permanent.getAbilities().remove(abilityToRemove);
}
permanent.addAbility(newAbility, source.getSourceId(), game);
return true;
} }
return sb.toString(); return false;
} }
} }

View file

@ -471,6 +471,7 @@ public abstract class AbilityImpl implements Ability {
return variableManaCost; return variableManaCost;
} }
// called at end of turn for each Permanent
@Override @Override
public void reset(Game game) {} public void reset(Game game) {}