mirror of
https://github.com/correl/mage.git
synced 2024-12-26 11:09:27 +00:00
* Copied cards - Copied cards cease to exist on check of next state based effects if they are returned to hand (#611).
This commit is contained in:
parent
751365124e
commit
e7e6a5bb99
4 changed files with 76 additions and 27 deletions
|
@ -39,6 +39,7 @@ import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
import mage.game.stack.Spell;
|
import mage.game.stack.Spell;
|
||||||
import mage.game.stack.StackObject;
|
import mage.game.stack.StackObject;
|
||||||
|
import mage.players.Player;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author nantuko, North
|
* @author nantuko, North
|
||||||
|
@ -78,25 +79,40 @@ public class CounterTargetWithReplacementEffect extends OneShotEffect {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
UUID objectId = source.getFirstTarget();
|
UUID objectId = source.getFirstTarget();
|
||||||
UUID sourceId = source.getSourceId();
|
UUID sourceId = source.getSourceId();
|
||||||
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
StackObject stackObject = game.getStack().getStackObject(objectId);
|
if (controller != null) {
|
||||||
if (stackObject != null && !game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.COUNTER, objectId, sourceId, stackObject.getControllerId()))) {
|
StackObject stackObject = game.getStack().getStackObject(objectId);
|
||||||
boolean spell = false;
|
if (stackObject != null && !game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.COUNTER, objectId, sourceId, stackObject.getControllerId()))) {
|
||||||
if (stackObject instanceof Spell) {
|
boolean spell = false;
|
||||||
game.rememberLKI(objectId, Zone.STACK, stackObject);
|
if (stackObject instanceof Spell) {
|
||||||
spell = true;
|
game.rememberLKI(objectId, Zone.STACK, stackObject);
|
||||||
}
|
spell = true;
|
||||||
game.getStack().remove(stackObject);
|
|
||||||
if (spell && !((Spell) stackObject).isCopiedSpell()) {
|
|
||||||
MageObject card = game.getObject(stackObject.getSourceId());
|
|
||||||
if (card instanceof Card) {
|
|
||||||
((Card) card).moveToZone(targetZone, sourceId, game, flag);
|
|
||||||
} else {
|
|
||||||
game.informPlayers("Server: Couldn't move card to zone = " + targetZone + " as it has other than Card type.");
|
|
||||||
}
|
}
|
||||||
|
game.getStack().remove(stackObject);
|
||||||
|
if (spell && !((Spell) stackObject).isCopiedSpell()) {
|
||||||
|
MageObject mageObject = game.getObject(stackObject.getSourceId());
|
||||||
|
if (mageObject instanceof Card) {
|
||||||
|
Card card = (Card) mageObject;
|
||||||
|
switch (targetZone) {
|
||||||
|
case HAND:
|
||||||
|
controller.moveCardToHandWithInfo(card, sourceId, game, Zone.STACK);
|
||||||
|
break;
|
||||||
|
case LIBRARY:
|
||||||
|
controller.moveCardToLibraryWithInfo(card, sourceId, game, Zone.STACK, flag, true);
|
||||||
|
break;
|
||||||
|
case EXILED:
|
||||||
|
controller.moveCardToExileWithInfo(card, null, "", sourceId, game, Zone.STACK);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
card.moveToZone(targetZone, sourceId, game, flag);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.COUNTERED, objectId, sourceId, stackObject.getControllerId()));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.COUNTERED, objectId, sourceId, stackObject.getControllerId()));
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,7 @@ public interface Game extends MageItem, Serializable {
|
||||||
|
|
||||||
//game data methods
|
//game data methods
|
||||||
void loadCards(Set<Card> cards, UUID ownerId);
|
void loadCards(Set<Card> cards, UUID ownerId);
|
||||||
|
void unloadCard(Card card);
|
||||||
Collection<Card> getCards();
|
Collection<Card> getCards();
|
||||||
Object getCustomData();
|
Object getCustomData();
|
||||||
void setCustomData(Object data);
|
void setCustomData(Object data);
|
||||||
|
|
|
@ -290,6 +290,20 @@ public abstract class GameImpl implements Game, Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unloadCard(Card card) {
|
||||||
|
gameCards.remove(card.getId());
|
||||||
|
state.removeCard(card);
|
||||||
|
if (card.isSplitCard()) {
|
||||||
|
Card leftCard = ((SplitCard)card).getLeftHalfCard();
|
||||||
|
gameCards.remove(leftCard.getId());
|
||||||
|
state.removeCard(leftCard);
|
||||||
|
Card rightCard = ((SplitCard)card).getRightHalfCard();
|
||||||
|
gameCards.remove(rightCard.getId());
|
||||||
|
state.removeCard(rightCard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Card> getCards() {
|
public Collection<Card> getCards() {
|
||||||
return gameCards.values();
|
return gameCards.values();
|
||||||
|
@ -1414,6 +1428,25 @@ public abstract class GameImpl implements Game, Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 704.5e
|
||||||
|
for (Player player: getPlayers().values()) {
|
||||||
|
for (Card card: player.getHand().getCards(this)) {
|
||||||
|
if (card.isCopy()) {
|
||||||
|
player.getHand().remove(card);
|
||||||
|
this.unloadCard(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// (Isochron Scepter) 12/1/2004: If you don't want to cast the copy, you can choose not to; the copy ceases to exist the next time state-based actions are checked.
|
||||||
|
for (Card card: this.getState().getExile().getAllCards(this)) {
|
||||||
|
if (card.isCopy()) {
|
||||||
|
this.getState().getExile().removeCard(card, this);
|
||||||
|
this.unloadCard(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO Library + graveyard
|
||||||
|
|
||||||
|
|
||||||
List<Permanent> planeswalkers = new ArrayList<>();
|
List<Permanent> planeswalkers = new ArrayList<>();
|
||||||
List<Permanent> legendary = new ArrayList<>();
|
List<Permanent> legendary = new ArrayList<>();
|
||||||
for (Permanent perm: getBattlefield().getAllActivePermanents()) {
|
for (Permanent perm: getBattlefield().getAllActivePermanents()) {
|
||||||
|
@ -1649,13 +1682,6 @@ public abstract class GameImpl implements Game, Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// (Isochron Scepter) 12/1/2004: If you don't want to cast the copy, you can choose not to; the copy ceases to exist the next time state-based actions are checked.
|
|
||||||
for(Card card: this.getState().getExile().getAllCards(this)) {
|
|
||||||
if (card.isCopy()) {
|
|
||||||
this.getState().getExile().removeCard(card, this);
|
|
||||||
this.removeCard(card.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//TODO: implement the rest
|
//TODO: implement the rest
|
||||||
|
|
||||||
return somethingHappened;
|
return somethingHappened;
|
||||||
|
|
|
@ -539,9 +539,15 @@ public class GameState implements Serializable, Copyable<GameState> {
|
||||||
for (Ability ability: card.getAbilities()) {
|
for (Ability ability: card.getAbilities()) {
|
||||||
addAbility(ability, card);
|
addAbility(ability, card);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeCard(Card card) {
|
||||||
|
zones.remove(card.getId());
|
||||||
|
// TODO Watchers?
|
||||||
|
// TODO Abilities?
|
||||||
if (card.isSplitCard()) {
|
if (card.isSplitCard()) {
|
||||||
addCard( ((SplitCard)card).getLeftHalfCard());
|
removeCard( ((SplitCard)card).getLeftHalfCard());
|
||||||
addCard( ((SplitCard)card).getRightHalfCard());
|
removeCard( ((SplitCard)card).getRightHalfCard());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue