forked from External/mage
New way of copying permanents - supports copies of copies. +1 test pass.
This commit is contained in:
parent
e5b6807d91
commit
0d732e8f86
11 changed files with 149 additions and 49 deletions
|
|
@ -27,8 +27,6 @@
|
|||
*/
|
||||
package mage.sets.magic2012;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.Constants;
|
||||
import mage.Constants.CardType;
|
||||
import mage.Constants.Outcome;
|
||||
import mage.Constants.Rarity;
|
||||
|
|
@ -38,7 +36,6 @@ import mage.abilities.common.BecomesTargetTriggeredAbility;
|
|||
import mage.abilities.common.EntersBattlefieldAbility;
|
||||
import mage.abilities.effects.EntersBattlefieldEffect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CopyEffect;
|
||||
import mage.abilities.effects.common.SacrificeSourceEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
|
|
@ -47,6 +44,9 @@ import mage.game.permanent.Permanent;
|
|||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.util.functions.ApplyToPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -98,15 +98,17 @@ class PhantasmalImageCopyEffect extends OneShotEffect<PhantasmalImageCopyEffect>
|
|||
target.setRequired(true);
|
||||
target.setNotTarget(true);
|
||||
player.choose(Outcome.Copy, target, source.getSourceId(), game);
|
||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||
UUID targetId = target.getFirstTarget();
|
||||
Permanent permanent = game.getPermanent(targetId);
|
||||
if (permanent != null) {
|
||||
permanent = permanent.copy();
|
||||
permanent.reset(game);
|
||||
permanent.assignNewId();
|
||||
permanent.getSubtype().add("Illusion");
|
||||
permanent.addAbility(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()), game);
|
||||
|
||||
game.addEffect(new CopyEffect(permanent), source);
|
||||
game.copyPermanent(permanent, source, new ApplyToPermanent() {
|
||||
@Override
|
||||
public Boolean apply(Game game, Permanent permanent) {
|
||||
permanent.getSubtype().add("Illusion");
|
||||
permanent.addAbility(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()), game);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@
|
|||
|
||||
package mage.sets.newphyrexia;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.Constants.CardType;
|
||||
import mage.Constants.Outcome;
|
||||
import mage.Constants.Rarity;
|
||||
|
|
@ -38,7 +36,6 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.common.EntersBattlefieldAbility;
|
||||
import mage.abilities.effects.EntersBattlefieldEffect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CopyEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.filter.Filter;
|
||||
import mage.filter.FilterPermanent;
|
||||
|
|
@ -47,6 +44,9 @@ import mage.game.permanent.Permanent;
|
|||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.util.functions.ApplyToPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -96,7 +96,6 @@ class PhyrexianMetamorphEffect extends OneShotEffect<PhyrexianMetamorphEffect> {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
//TODO: handle copying copies
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null) {
|
||||
Target target = new TargetPermanent(filter);
|
||||
|
|
@ -104,12 +103,16 @@ class PhyrexianMetamorphEffect extends OneShotEffect<PhyrexianMetamorphEffect> {
|
|||
player.choose(Outcome.Copy, target, source.getSourceId(), game);
|
||||
Permanent perm = game.getPermanent(target.getFirstTarget());
|
||||
if (perm != null) {
|
||||
perm = perm.copy();
|
||||
perm.reset(game);
|
||||
perm.assignNewId();
|
||||
if (!perm.getCardType().contains(CardType.ARTIFACT))
|
||||
perm.getCardType().add(CardType.ARTIFACT);
|
||||
game.addEffect(new CopyEffect(perm), source);
|
||||
game.copyPermanent(perm, source, new ApplyToPermanent() {
|
||||
@Override
|
||||
public Boolean apply(Game game, Permanent permanent) {
|
||||
if (!permanent.getCardType().contains(CardType.ARTIFACT)) {
|
||||
permanent.getCardType().add(CardType.ARTIFACT);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ public class PhantasmalImageTest extends CardTestPlayerBase {
|
|||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Illusionary Servant");
|
||||
|
||||
setChoice(playerA, "Illusionary Servant");
|
||||
setChoice(playerA, "Phantasmal Image");
|
||||
setChoice(playerA, "Illusionary Servant-M12");
|
||||
|
||||
castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Phantasmal Image");
|
||||
castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Phantasmal Image");
|
||||
|
|
|
|||
|
|
@ -189,6 +189,12 @@ public class TestPlayer extends ComputerPlayer<TestPlayer> {
|
|||
choices.remove(choose2);
|
||||
return true;
|
||||
}
|
||||
} else if ((permanent.getName()+"-"+permanent.getExpansionSetCode()).equals(choose2)) {
|
||||
if (((TargetPermanent)target).canTarget(playerId, permanent.getId(), null, game) && !target.getTargets().contains(permanent.getId())) {
|
||||
target.add(permanent.getId(), game);
|
||||
choices.remove(choose2);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ public class ContinuousEffects implements Serializable {
|
|||
|
||||
}
|
||||
|
||||
private List<ContinuousEffect> getLayeredEffects(Game game) {
|
||||
public List<ContinuousEffect> getLayeredEffects(Game game) {
|
||||
List<ContinuousEffect> layerEffects = new ArrayList<ContinuousEffect>();
|
||||
for (ContinuousEffect effect: layeredEffects) {
|
||||
switch (effect.getDuration()) {
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ import mage.abilities.effects.ContinuousEffectImpl;
|
|||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
|
|
@ -46,15 +48,18 @@ import mage.game.permanent.Permanent;
|
|||
public class CopyEffect extends ContinuousEffectImpl<CopyEffect> {
|
||||
|
||||
private MageObject target;
|
||||
private UUID sourceId;
|
||||
|
||||
public CopyEffect(MageObject target) {
|
||||
public CopyEffect(Permanent target, UUID sourceId) {
|
||||
super(Duration.WhileOnBattlefield, Layer.CopyEffects_1, SubLayer.NA, Outcome.BecomeCreature);
|
||||
this.target = target;
|
||||
this.sourceId = sourceId;
|
||||
}
|
||||
|
||||
public CopyEffect(final CopyEffect effect) {
|
||||
super(effect);
|
||||
this.target = effect.target.copy();
|
||||
this.sourceId = effect.sourceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -63,7 +68,7 @@ public class CopyEffect extends ContinuousEffectImpl<CopyEffect> {
|
|||
if (permanent == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
permanent.setName(target.getName());
|
||||
permanent.getColor().setColor(target.getColor());
|
||||
permanent.getManaCost().clear();
|
||||
|
|
@ -95,4 +100,15 @@ public class CopyEffect extends ContinuousEffectImpl<CopyEffect> {
|
|||
return new CopyEffect(this);
|
||||
}
|
||||
|
||||
public MageObject getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public void setTarget(MageObject target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public UUID getSourceId() {
|
||||
return sourceId;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
*/
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.Constants;
|
||||
import mage.Constants.Outcome;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
|
|
@ -37,6 +38,7 @@ import mage.game.permanent.Permanent;
|
|||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.util.functions.ApplyToPermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -63,7 +65,6 @@ public class CopyPermanentEffect extends OneShotEffect<CopyPermanentEffect> {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
//TODO: handle copying copies
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null) {
|
||||
Target target = new TargetPermanent(filter);
|
||||
|
|
@ -71,11 +72,16 @@ public class CopyPermanentEffect extends OneShotEffect<CopyPermanentEffect> {
|
|||
player.choose(Outcome.Copy, target, source.getSourceId(), game);
|
||||
Permanent perm = game.getPermanent(target.getFirstTarget());
|
||||
if (perm != null) {
|
||||
perm = perm.copy();
|
||||
game.getState().addCard(perm);
|
||||
perm.reset(game);
|
||||
perm.assignNewId();
|
||||
game.addEffect(new CopyEffect(perm), source);
|
||||
game.copyPermanent(perm, source, new ApplyToPermanent() {
|
||||
@Override
|
||||
public Boolean apply(Game game, Permanent permanent) {
|
||||
if (!permanent.getCardType().contains(Constants.CardType.ARTIFACT)) {
|
||||
permanent.getCardType().add(Constants.CardType.ARTIFACT);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,42 +28,42 @@
|
|||
|
||||
package mage.game;
|
||||
|
||||
import mage.actions.impl.MageAction;
|
||||
import mage.game.match.MatchType;
|
||||
import mage.cards.Card;
|
||||
import mage.game.stack.SpellStack;
|
||||
import mage.MageObject;
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
|
||||
import mage.Constants.MultiplayerAttackOption;
|
||||
import mage.Constants.RangeOfInfluence;
|
||||
import mage.Constants.Zone;
|
||||
import mage.MageItem;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.ActivatedAbility;
|
||||
import mage.abilities.DelayedTriggeredAbility;
|
||||
import mage.abilities.TriggeredAbilities;
|
||||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.ContinuousEffects;
|
||||
import mage.actions.impl.MageAction;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.choices.Choice;
|
||||
import mage.game.combat.Combat;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.TableEvent;
|
||||
import mage.game.events.Listener;
|
||||
import mage.game.events.PlayerQueryEvent;
|
||||
import mage.game.events.TableEvent;
|
||||
import mage.game.match.MatchType;
|
||||
import mage.game.permanent.Battlefield;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.PermanentCard;
|
||||
import mage.game.stack.SpellStack;
|
||||
import mage.game.turn.Phase;
|
||||
import mage.game.turn.Step;
|
||||
import mage.game.turn.Turn;
|
||||
import mage.players.Player;
|
||||
import mage.players.PlayerList;
|
||||
import mage.players.Players;
|
||||
import mage.util.functions.ApplyToPermanent;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
|
||||
public interface Game extends MageItem, Serializable {
|
||||
|
||||
|
|
@ -160,7 +160,17 @@ public interface Game extends MageItem, Serializable {
|
|||
public void concede(UUID playerId);
|
||||
public void emptyManaPools();
|
||||
public void addEffect(ContinuousEffect continuousEffect, Ability source);
|
||||
public void addTriggeredAbility(TriggeredAbility ability);
|
||||
|
||||
/**
|
||||
* This version supports copying of copies of any depth.
|
||||
*
|
||||
* @param targetPermanent
|
||||
* @param source
|
||||
* @param applier
|
||||
*/
|
||||
public void copyPermanent(Permanent targetPermanent, Ability source, ApplyToPermanent applier);
|
||||
|
||||
public void addTriggeredAbility(TriggeredAbility ability);
|
||||
public void addDelayedTriggeredAbility(DelayedTriggeredAbility delayedAbility);
|
||||
public void applyEffects();
|
||||
public boolean checkStateAndTriggered();
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ import mage.abilities.TriggeredAbility;
|
|||
import mage.abilities.common.ChancellorAbility;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.ContinuousEffects;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.CopyEffect;
|
||||
import mage.abilities.keyword.LeylineAbility;
|
||||
import mage.abilities.mana.TriggeredManaAbility;
|
||||
import mage.actions.impl.MageAction;
|
||||
|
|
@ -67,6 +69,7 @@ import mage.players.Players;
|
|||
import mage.target.Target;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.TargetPlayer;
|
||||
import mage.util.functions.ApplyToPermanent;
|
||||
import mage.watchers.common.*;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
|
|
@ -649,15 +652,17 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
if (isPaused() || isGameOver()) return;
|
||||
if (allPassed()) {
|
||||
if (!state.getStack().isEmpty()) {
|
||||
//20091005 - 115.4
|
||||
//20091005 - 115.4
|
||||
resolve();
|
||||
applyEffects();
|
||||
state.getPlayers().resetPassed();
|
||||
fireUpdatePlayersEvent();
|
||||
state.getRevealed().reset();
|
||||
resetLKI();
|
||||
break;
|
||||
} else {
|
||||
//removeBookmark(bookmark);
|
||||
resetLKI();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -718,14 +723,53 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
|
||||
@Override
|
||||
public void addEffect(ContinuousEffect continuousEffect, Ability source) {
|
||||
ContinuousEffect newEffect = (ContinuousEffect)continuousEffect.copy();
|
||||
Ability newAbility = source.copy();
|
||||
Ability newAbility = source.copy();
|
||||
|
||||
ContinuousEffect newEffect = (ContinuousEffect)continuousEffect.copy();
|
||||
newEffect.newId();
|
||||
newEffect.setTimestamp();
|
||||
newEffect.init(newAbility, this);
|
||||
state.addEffect(newEffect, newAbility);
|
||||
|
||||
state.addEffect(newEffect, newAbility);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyPermanent(Permanent targetPermanent, Ability source, ApplyToPermanent applier) {
|
||||
Permanent permanent = targetPermanent.copy();
|
||||
//getState().addCard(permanent);
|
||||
permanent.reset(this);
|
||||
permanent.assignNewId();
|
||||
applier.apply(this, permanent);
|
||||
|
||||
Ability newAbility = source.copy();
|
||||
|
||||
CopyEffect newEffect = new CopyEffect(permanent, source.getSourceId());
|
||||
newEffect.newId();
|
||||
newEffect.setTimestamp();
|
||||
newEffect.init(newAbility, this);
|
||||
|
||||
// handle copies of copies
|
||||
for (Effect effect : getState().getContinuousEffects().getLayeredEffects(this)) {
|
||||
if (effect instanceof CopyEffect) {
|
||||
CopyEffect copyEffect = (CopyEffect) effect;
|
||||
// there is another copy effect that our targetPermanent copies stats from
|
||||
if (copyEffect.getSourceId().equals(targetPermanent.getId())) {
|
||||
MageObject object = ((CopyEffect) effect).getTarget();
|
||||
if (object instanceof Permanent) {
|
||||
// so we will use original card instead of target
|
||||
Permanent original = (Permanent)object;
|
||||
// copy it and apply changes we need
|
||||
original = original.copy();
|
||||
applier.apply(this, original);
|
||||
newEffect.setTarget(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.addEffect(newEffect, newAbility);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTriggeredAbility(TriggeredAbility ability) {
|
||||
if (ability instanceof TriggeredManaAbility) {
|
||||
|
|
@ -758,7 +802,6 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
|
|||
}
|
||||
somethingHappened = true;
|
||||
}
|
||||
resetLKI();
|
||||
return somethingHappened;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -506,8 +506,10 @@ public abstract class PermanentImpl<T extends PermanentImpl<T>> extends CardImpl
|
|||
}
|
||||
|
||||
@Override
|
||||
public void clearConnectedCards() {
|
||||
this.connectedCards.clear();
|
||||
public void clearConnectedCards(String key) {
|
||||
if (this.connectedCards.containsKey(key)) {
|
||||
this.connectedCards.get(key).clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
12
Mage/src/mage/util/functions/ApplyToPermanent.java
Normal file
12
Mage/src/mage/util/functions/ApplyToPermanent.java
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
package mage.util.functions;
|
||||
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
* @author noxx
|
||||
*/
|
||||
public abstract class ApplyToPermanent {
|
||||
|
||||
public abstract Boolean apply(Game game, Permanent permanent);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue