mirror of
https://github.com/magefree/mage.git
synced 2025-12-24 12:31:59 -08:00
Refactor: added copyFrom info for all objects (original card used for copy, copy of copy and etc);
This commit is contained in:
parent
28ac95cb10
commit
59bda7f1d5
25 changed files with 269 additions and 220 deletions
|
|
@ -64,20 +64,14 @@ public interface MageObject extends MageItem, Serializable {
|
|||
|
||||
void adjustTargets(Ability ability, Game game);
|
||||
|
||||
// memory object copy (not mtg)
|
||||
MageObject copy();
|
||||
|
||||
/**
|
||||
* Defines that MageObject is a copy of another object
|
||||
*
|
||||
* @param isCopy
|
||||
*/
|
||||
void setCopy(boolean isCopy);
|
||||
// copied card info (mtg)
|
||||
void setCopy(boolean isCopy, MageObject copiedFrom);
|
||||
|
||||
MageObject getCopyFrom();
|
||||
|
||||
/**
|
||||
* Checks if current MageObject is a copy of another object
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isCopy();
|
||||
|
||||
int getZoneChangeCounter(Game game);
|
||||
|
|
|
|||
|
|
@ -1,11 +1,5 @@
|
|||
|
||||
package mage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Abilities;
|
||||
import mage.abilities.AbilitiesImpl;
|
||||
import mage.abilities.Ability;
|
||||
|
|
@ -20,16 +14,14 @@ import mage.abilities.mana.ActivatedManaAbilityImpl;
|
|||
import mage.abilities.text.TextPart;
|
||||
import mage.abilities.text.TextPartSubType;
|
||||
import mage.cards.FrameStyle;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubLayer;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SubTypeSet;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.util.GameLog;
|
||||
import mage.util.SubTypeList;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public abstract class MageObjectImpl implements MageObject {
|
||||
|
||||
protected UUID objectId;
|
||||
|
|
@ -48,6 +40,7 @@ public abstract class MageObjectImpl implements MageObject {
|
|||
protected MageInt power;
|
||||
protected MageInt toughness;
|
||||
protected boolean copy;
|
||||
protected MageObject copyFrom; // copied card INFO (used to call original adjusters)
|
||||
protected List<TextPart> textParts;
|
||||
|
||||
public MageObjectImpl() {
|
||||
|
|
@ -82,6 +75,7 @@ public abstract class MageObjectImpl implements MageObject {
|
|||
isAllCreatureTypes = object.isAllCreatureTypes;
|
||||
supertype.addAll(object.supertype);
|
||||
this.copy = object.copy;
|
||||
this.copyFrom = (object.copyFrom != null ? object.copyFrom.copy() : null);
|
||||
textParts = new ArrayList<>();
|
||||
textParts.addAll(object.textParts);
|
||||
}
|
||||
|
|
@ -263,8 +257,14 @@ public abstract class MageObjectImpl implements MageObject {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setCopy(boolean isCopy) {
|
||||
public void setCopy(boolean isCopy, MageObject copyFrom) {
|
||||
this.copy = isCopy;
|
||||
this.copyFrom = (copyFrom != null ? copyFrom.copy() : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MageObject getCopyFrom() {
|
||||
return this.copyFrom;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -322,7 +322,7 @@ public abstract class MageObjectImpl implements MageObject {
|
|||
*/
|
||||
@Override
|
||||
public void removePTCDA() {
|
||||
for (Iterator<Ability> iter = this.getAbilities().iterator(); iter.hasNext();) {
|
||||
for (Iterator<Ability> iter = this.getAbilities().iterator(); iter.hasNext(); ) {
|
||||
Ability ability = iter.next();
|
||||
for (Effect effect : ability.getEffects()) {
|
||||
if (effect instanceof ContinuousEffect && ((ContinuousEffect) effect).getSublayer() == SubLayer.CharacteristicDefining_7a) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.MageObject;
|
||||
|
|
@ -16,7 +15,6 @@ import mage.util.functions.ApplyToPermanent;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class CopyEffect extends ContinuousEffectImpl {
|
||||
|
|
@ -90,7 +88,13 @@ public class CopyEffect extends ContinuousEffectImpl {
|
|||
}
|
||||
|
||||
protected boolean copyToPermanent(Permanent permanent, Game game, Ability source) {
|
||||
permanent.setCopy(true);
|
||||
if (copyFromObject.getCopyFrom() != null) {
|
||||
// copy from temp blueprints (they are already copies)
|
||||
permanent.setCopy(true, copyFromObject.getCopyFrom());
|
||||
} else {
|
||||
// copy object to object
|
||||
permanent.setCopy(true, copyFromObject);
|
||||
}
|
||||
permanent.setName(copyFromObject.getName());
|
||||
permanent.getColor(game).setColor(copyFromObject.getColor(game));
|
||||
permanent.getManaCost().clear();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
|
|
@ -12,7 +11,6 @@ import mage.game.stack.Spell;
|
|||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class ExileSpellEffect extends OneShotEffect implements MageSingleton {
|
||||
|
|
@ -38,7 +36,7 @@ public class ExileSpellEffect extends OneShotEffect implements MageSingleton {
|
|||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
Spell spell = game.getStack().getSpell(source.getId());
|
||||
if (spell != null && !spell.isCopiedSpell()) {
|
||||
if (spell != null && !spell.isCopy()) {
|
||||
Card spellCard = spell.getCard();
|
||||
if (spellCard != null) {
|
||||
controller.moveCards(spellCard, Zone.EXILED, source, game);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.abilities.keyword;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.DelayedTriggeredAbility;
|
||||
|
|
@ -21,6 +19,8 @@ import mage.game.events.ZoneChangeEvent;
|
|||
import mage.game.stack.Spell;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
@ -93,7 +93,7 @@ class ReboundCastFromHandReplacementEffect extends ReplacementEffectImpl {
|
|||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
Spell sourceSpell = game.getStack().getSpell(source.getSourceId());
|
||||
if (sourceSpell != null && sourceSpell.isCopiedSpell()) {
|
||||
if (sourceSpell != null && sourceSpell.isCopy()) {
|
||||
return false;
|
||||
} else {
|
||||
Card sourceCard = game.getCard(source.getSourceId());
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
|
||||
package mage.cards;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Abilities;
|
||||
import mage.abilities.AbilitiesImpl;
|
||||
import mage.abilities.Ability;
|
||||
|
|
@ -13,8 +10,11 @@ import mage.constants.SpellAbilityType;
|
|||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public abstract class SplitCard extends CardImpl {
|
||||
|
|
@ -58,10 +58,10 @@ public abstract class SplitCard extends CardImpl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setCopy(boolean isCopy) {
|
||||
super.setCopy(isCopy);
|
||||
leftHalfCard.setCopy(isCopy);
|
||||
rightHalfCard.setCopy(isCopy);
|
||||
public void setCopy(boolean isCopy, MageObject copiedFrom) {
|
||||
super.setCopy(isCopy, copiedFrom);
|
||||
leftHalfCard.setCopy(isCopy, copiedFrom);
|
||||
rightHalfCard.setCopy(isCopy, copiedFrom);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
|
||||
package mage.designations;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class CitysBlessing extends Designation {
|
||||
|
|
@ -10,4 +8,13 @@ public class CitysBlessing extends Designation {
|
|||
public CitysBlessing() {
|
||||
super(DesignationType.CITYS_BLESSING, "RIX");
|
||||
}
|
||||
|
||||
private CitysBlessing(final CitysBlessing card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CitysBlessing copy() {
|
||||
return new CitysBlessing(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,5 @@
|
|||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package mage.designations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.ObjectColor;
|
||||
|
|
@ -28,8 +19,12 @@ import mage.game.events.ZoneChangeEvent;
|
|||
import mage.util.GameLog;
|
||||
import mage.util.SubTypeList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public abstract class Designation implements MageObject {
|
||||
|
|
@ -43,6 +38,8 @@ public abstract class Designation implements MageObject {
|
|||
private DesignationType designationType;
|
||||
private UUID id;
|
||||
private FrameStyle frameStyle;
|
||||
private boolean copy;
|
||||
private MageObject copyFrom; // copied card INFO (used to call original adjusters)
|
||||
private Abilities<Ability> abilites = new AbilitiesImpl<>();
|
||||
private String expansionSetCodeForImage;
|
||||
private final boolean unique; // can a designation be added multiple times (false) or only once to an object (true)
|
||||
|
|
@ -65,6 +62,8 @@ public abstract class Designation implements MageObject {
|
|||
this.name = designation.name;
|
||||
this.designationType = designation.designationType;
|
||||
this.frameStyle = designation.frameStyle;
|
||||
this.copy = designation.copy;
|
||||
this.copyFrom = (designation.copyFrom != null ? designation.copyFrom.copy() : null);
|
||||
this.abilites = designation.abilites.copy();
|
||||
this.unique = designation.unique;
|
||||
}
|
||||
|
|
@ -78,6 +77,22 @@ public abstract class Designation implements MageObject {
|
|||
this.id = UUID.randomUUID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCopy(boolean isCopy, MageObject copyFrom) {
|
||||
this.copy = isCopy;
|
||||
this.copyFrom = (copyFrom != null ? copyFrom.copy() : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCopy() {
|
||||
return this.copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MageObject getCopyFrom() {
|
||||
return this.copyFrom;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
|
|
@ -198,20 +213,6 @@ public abstract class Designation implements MageObject {
|
|||
public void adjustTargets(Ability ability, Game game) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCopy(boolean isCopy) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCopy() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Designation copy() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getZoneChangeCounter(Game game) {
|
||||
return 1; // Emblems can't move zones until now so return always 1
|
||||
|
|
@ -232,7 +233,6 @@ public abstract class Designation implements MageObject {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param game
|
||||
* @param controllerId
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.designations;
|
||||
|
||||
import mage.MageObject;
|
||||
|
|
@ -15,7 +14,6 @@ import mage.game.permanent.Permanent;
|
|||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class Monarch extends Designation {
|
||||
|
|
@ -25,6 +23,15 @@ public class Monarch extends Designation {
|
|||
addAbility(new MonarchDrawTriggeredAbility());
|
||||
addAbility(new MonarchDealsCombatDamageToAPlayerTriggeredAbility());
|
||||
}
|
||||
|
||||
private Monarch(final Monarch monarch) {
|
||||
super(monarch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Monarch copy() {
|
||||
return new Monarch(this);
|
||||
}
|
||||
}
|
||||
|
||||
// At the beginning of the monarch's end step, that player draws a card
|
||||
|
|
|
|||
|
|
@ -44,12 +44,12 @@ public class FilterPlayer extends FilterImpl<Player> {
|
|||
return object instanceof Player;
|
||||
}
|
||||
|
||||
public boolean match(Player player, UUID sourceId, UUID playerId, Game game) {
|
||||
if (!this.match(player, game)) {
|
||||
public boolean match(Player checkPlayer, UUID sourceId, UUID sourceControllerId, Game game) {
|
||||
if (!this.match(checkPlayer, game)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Predicates.and(extraPredicates).apply(new ObjectSourcePlayer(player, sourceId, playerId), game);
|
||||
return Predicates.and(extraPredicates).apply(new ObjectSourcePlayer(checkPlayer, sourceId, sourceControllerId), game);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ public class ObjectSourcePlayer<T> extends ObjectPlayer<T> {
|
|||
|
||||
protected final UUID sourceId;
|
||||
|
||||
public ObjectSourcePlayer(T object, UUID sourceId, UUID playerId) {
|
||||
super(object, playerId);
|
||||
public ObjectSourcePlayer(T object, UUID sourceId, UUID sourceControllerId) {
|
||||
super(object, sourceControllerId);
|
||||
this.sourceId = sourceId;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1638,6 +1638,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
if (newBluePrint == null) {
|
||||
newBluePrint = copyFromPermanent.copy();
|
||||
newBluePrint.reset(this);
|
||||
|
||||
//getState().addCard(permanent);
|
||||
if (copyFromPermanent.isMorphed() || copyFromPermanent.isManifested()) {
|
||||
MorphAbility.setPermanentToFaceDownCreature(newBluePrint);
|
||||
|
|
@ -1651,6 +1652,9 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
applier.apply(this, newBluePrint, source, copyToPermanentId);
|
||||
}
|
||||
|
||||
// save original copy link (handle copy of copies too)
|
||||
newBluePrint.setCopy(true, (copyFromPermanent.getCopyFrom() != null ? copyFromPermanent.getCopyFrom() : copyFromPermanent));
|
||||
|
||||
CopyEffect newEffect = new CopyEffect(duration, newBluePrint, copyToPermanentId);
|
||||
newEffect.newId();
|
||||
newEffect.setApplier(applier);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
package mage.game;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.*;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
|
|
@ -35,15 +32,17 @@ import mage.util.ThreadLocalStringBuilder;
|
|||
import mage.watchers.Watcher;
|
||||
import mage.watchers.Watchers;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*
|
||||
* <p>
|
||||
* since at any time the game state may be copied and restored you cannot rely
|
||||
* on any object maintaining it's instance it then becomes necessary to only
|
||||
* refer to objects by their ids since these will always remain constant
|
||||
* throughout its lifetime
|
||||
*
|
||||
*/
|
||||
public class GameState implements Serializable, Copyable<GameState> {
|
||||
|
||||
|
|
@ -590,6 +589,7 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
// public void addMessage(String message) {
|
||||
// this.messages.add(message);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Returns a list of all players of the game ignoring range or if a player
|
||||
* has lost or left the game.
|
||||
|
|
@ -758,7 +758,7 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
}
|
||||
for (Map.Entry<ZoneChangeData, List<GameEvent>> entry : eventsByKey.entrySet()) {
|
||||
Set<Card> movedCards = new LinkedHashSet<>();
|
||||
for (Iterator<GameEvent> it = entry.getValue().iterator(); it.hasNext();) {
|
||||
for (Iterator<GameEvent> it = entry.getValue().iterator(); it.hasNext(); ) {
|
||||
GameEvent event = it.next();
|
||||
ZoneChangeEvent castEvent = (ZoneChangeEvent) event;
|
||||
UUID targetId = castEvent.getTargetId();
|
||||
|
|
@ -943,7 +943,7 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
/**
|
||||
* Other abilities are used to implement some special kind of continuous
|
||||
* effects that give abilities to non permanents.
|
||||
*
|
||||
* <p>
|
||||
* Crucible of Worlds - You may play land cards from your graveyard. Past in
|
||||
* Flames - Each instant and sorcery card in your graveyard gains flashback
|
||||
* until end of turn. The flashback cost is equal to its mana cost. Varolz,
|
||||
|
|
@ -984,7 +984,7 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
* @param attachedTo
|
||||
* @param ability
|
||||
* @param copyAbility copies non MageSingleton abilities before adding to
|
||||
* state
|
||||
* state
|
||||
*/
|
||||
public void addOtherAbility(Card attachedTo, Ability ability, boolean copyAbility) {
|
||||
Ability newAbility;
|
||||
|
|
@ -1134,7 +1134,7 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
Card copiedCard = cardToCopy.copy();
|
||||
copiedCard.assignNewId();
|
||||
copiedCard.setOwnerId(source.getControllerId());
|
||||
copiedCard.setCopy(true);
|
||||
copiedCard.setCopy(true, cardToCopy);
|
||||
copiedCards.put(copiedCard.getId(), copiedCard);
|
||||
addCard(copiedCard);
|
||||
if (copiedCard.isSplitCard()) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
|
||||
package mage.game.command;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.Abilities;
|
||||
import mage.abilities.AbilitiesImpl;
|
||||
|
|
@ -24,9 +21,15 @@ import mage.game.events.ZoneChangeEvent;
|
|||
import mage.util.GameLog;
|
||||
import mage.util.SubTypeList;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class Commander implements CommandObject {
|
||||
|
||||
private final Card sourceObject;
|
||||
private boolean copy;
|
||||
private MageObject copyFrom; // copied card INFO (used to call original adjusters)
|
||||
private final Abilities<Ability> abilities = new AbilitiesImpl<>();
|
||||
|
||||
public Commander(Card card) {
|
||||
|
|
@ -40,8 +43,10 @@ public class Commander implements CommandObject {
|
|||
}
|
||||
}
|
||||
|
||||
private Commander(Commander copy) {
|
||||
this.sourceObject = copy.sourceObject;
|
||||
private Commander(final Commander commander) {
|
||||
this.sourceObject = commander.sourceObject;
|
||||
this.copy = commander.copy;
|
||||
this.copyFrom = (commander.copyFrom != null ? commander.copyFrom.copy() : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -68,6 +73,22 @@ public class Commander implements CommandObject {
|
|||
return new Commander(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCopy(boolean isCopy, MageObject copyFrom) {
|
||||
this.copy = isCopy;
|
||||
this.copyFrom = (copyFrom != null ? copyFrom.copy() : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCopy() {
|
||||
return this.copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MageObject getCopyFrom() {
|
||||
return this.copyFrom;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return sourceObject.getName();
|
||||
|
|
@ -170,15 +191,6 @@ public class Commander implements CommandObject {
|
|||
public void adjustTargets(Ability ability, Game game) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCopy(boolean isCopy) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCopy() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getId() {
|
||||
return sourceObject.getId();
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
package mage.game.command;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.ObjectColor;
|
||||
|
|
@ -25,6 +22,10 @@ import mage.game.events.ZoneChangeEvent;
|
|||
import mage.util.GameLog;
|
||||
import mage.util.SubTypeList;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author nantuko
|
||||
*/
|
||||
|
|
@ -38,6 +39,8 @@ public class Emblem implements CommandObject {
|
|||
private UUID id;
|
||||
private UUID controllerId;
|
||||
private MageObject sourceObject;
|
||||
private boolean copy;
|
||||
private MageObject copyFrom; // copied card INFO (used to call original adjusters)
|
||||
private FrameStyle frameStyle;
|
||||
private Abilities<Ability> abilites = new AbilitiesImpl<>();
|
||||
private String expansionSetCodeForImage = "";
|
||||
|
|
@ -52,6 +55,8 @@ public class Emblem implements CommandObject {
|
|||
this.frameStyle = emblem.frameStyle;
|
||||
this.controllerId = emblem.controllerId;
|
||||
this.sourceObject = emblem.sourceObject;
|
||||
this.copy = emblem.copy;
|
||||
this.copyFrom = (emblem.copyFrom != null ? emblem.copyFrom : null);
|
||||
this.abilites = emblem.abilites.copy();
|
||||
this.expansionSetCodeForImage = emblem.expansionSetCodeForImage;
|
||||
}
|
||||
|
|
@ -101,6 +106,22 @@ public class Emblem implements CommandObject {
|
|||
this.abilites.setControllerId(controllerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCopy(boolean isCopy, MageObject copyFrom) {
|
||||
this.copy = isCopy;
|
||||
this.copyFrom = (copyFrom != null ? copyFrom.copy() : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCopy() {
|
||||
return this.copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MageObject getCopyFrom() {
|
||||
return this.copyFrom;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
|
|
@ -204,15 +225,6 @@ public class Emblem implements CommandObject {
|
|||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCopy(boolean isCopy) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCopy() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Emblem copy() {
|
||||
return new Emblem(this);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ public class Plane implements CommandObject {
|
|||
private UUID id;
|
||||
private UUID controllerId;
|
||||
private MageObject sourceObject;
|
||||
private boolean copy;
|
||||
private MageObject copyFrom; // copied card INFO (used to call original adjusters)
|
||||
private FrameStyle frameStyle;
|
||||
private Abilities<Ability> abilites = new AbilitiesImpl<>();
|
||||
private String expansionSetCodeForImage = "";
|
||||
|
|
@ -56,6 +58,8 @@ public class Plane implements CommandObject {
|
|||
this.frameStyle = plane.frameStyle;
|
||||
this.controllerId = plane.controllerId;
|
||||
this.sourceObject = plane.sourceObject;
|
||||
this.copy = plane.copy;
|
||||
this.copyFrom = (plane.copyFrom != null ? plane.copyFrom.copy() : null);
|
||||
this.abilites = plane.abilites.copy();
|
||||
this.expansionSetCodeForImage = plane.expansionSetCodeForImage;
|
||||
}
|
||||
|
|
@ -105,6 +109,22 @@ public class Plane implements CommandObject {
|
|||
this.abilites.setControllerId(controllerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCopy(boolean isCopy, MageObject copyFrom) {
|
||||
this.copy = isCopy;
|
||||
this.copyFrom = (copyFrom != null ? copyFrom.copy() : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCopy() {
|
||||
return this.copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MageObject getCopyFrom() {
|
||||
return this.copyFrom;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
|
|
@ -208,15 +228,6 @@ public class Plane implements CommandObject {
|
|||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCopy(boolean isCopy) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCopy() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plane copy() {
|
||||
return new Plane(this);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,5 @@
|
|||
|
||||
package mage.game.stack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.Mana;
|
||||
|
|
@ -39,8 +34,12 @@ import mage.players.Player;
|
|||
import mage.util.GameLog;
|
||||
import mage.util.SubTypeList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class Spell extends StackObjImpl implements Card {
|
||||
|
|
@ -63,7 +62,8 @@ public class Spell extends StackObjImpl implements Card {
|
|||
private final UUID id;
|
||||
|
||||
private UUID controllerId;
|
||||
private boolean copiedSpell;
|
||||
private boolean copy;
|
||||
private MageObject copyFrom; // copied card INFO (used to call original adjusters)
|
||||
private boolean faceDown;
|
||||
private boolean countered;
|
||||
private boolean resolving = false;
|
||||
|
|
@ -118,7 +118,8 @@ public class Spell extends StackObjImpl implements Card {
|
|||
this.frameStyle = spell.frameStyle;
|
||||
|
||||
this.controllerId = spell.controllerId;
|
||||
this.copiedSpell = spell.copiedSpell;
|
||||
this.copy = spell.copy;
|
||||
this.copyFrom = (spell.copyFrom != null ? spell.copyFrom.copy() : null);
|
||||
this.faceDown = spell.faceDown;
|
||||
this.countered = spell.countered;
|
||||
this.resolving = spell.resolving;
|
||||
|
|
@ -155,7 +156,7 @@ public class Spell extends StackObjImpl implements Card {
|
|||
|
||||
public String getActivatedMessage(Game game) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (isCopiedSpell()) {
|
||||
if (isCopy()) {
|
||||
sb.append(" copies ");
|
||||
} else {
|
||||
sb.append(" casts ");
|
||||
|
|
@ -362,7 +363,7 @@ public class Spell extends StackObjImpl implements Card {
|
|||
@Override
|
||||
public void counter(UUID sourceId, Game game, Zone zone, boolean owner, ZoneDetail zoneDetail) {
|
||||
this.countered = true;
|
||||
if (!isCopiedSpell()) {
|
||||
if (!isCopy()) {
|
||||
Player player = game.getPlayer(game.getControllerId(sourceId));
|
||||
if (player == null) {
|
||||
player = game.getPlayer(getControllerId());
|
||||
|
|
@ -706,7 +707,7 @@ public class Spell extends StackObjImpl implements Card {
|
|||
newAbility.newId();
|
||||
copy.addSpellAbility(newAbility);
|
||||
}
|
||||
copy.setCopy(true);
|
||||
copy.setCopy(true, this);
|
||||
copy.setControllerId(newController);
|
||||
return copy;
|
||||
}
|
||||
|
|
@ -740,7 +741,7 @@ public class Spell extends StackObjImpl implements Card {
|
|||
// 706.10a If a copy of a spell is in a zone other than the stack, it ceases to exist.
|
||||
// If a copy of a card is in any zone other than the stack or the battlefield, it ceases to exist.
|
||||
// These are state-based actions. See rule 704.
|
||||
if (this.isCopiedSpell() && zone != Zone.STACK) {
|
||||
if (this.isCopy() && zone != Zone.STACK) {
|
||||
return true;
|
||||
}
|
||||
return card.moveToZone(zone, sourceId, game, flag, appliedEffects);
|
||||
|
|
@ -753,7 +754,7 @@ public class Spell extends StackObjImpl implements Card {
|
|||
|
||||
@Override
|
||||
public boolean moveToExile(UUID exileId, String name, UUID sourceId, Game game, List<UUID> appliedEffects) {
|
||||
if (this.isCopiedSpell()) {
|
||||
if (this.isCopy()) {
|
||||
game.getStack().remove(this, game);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -835,26 +836,24 @@ public class Spell extends StackObjImpl implements Card {
|
|||
// do nothing
|
||||
}
|
||||
|
||||
public void setCopiedSpell(boolean isCopied) {
|
||||
this.copiedSpell = isCopied;
|
||||
}
|
||||
|
||||
public boolean isCopiedSpell() {
|
||||
return this.copiedSpell;
|
||||
}
|
||||
|
||||
public Zone getFromZone() {
|
||||
return this.fromZone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCopy(boolean isCopy) {
|
||||
setCopiedSpell(isCopy);
|
||||
public void setCopy(boolean isCopy, MageObject copyFrom) {
|
||||
this.copy = isCopy;
|
||||
this.copyFrom = (copyFrom != null ? copyFrom.copy() : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCopy() {
|
||||
return isCopiedSpell();
|
||||
return this.copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MageObject getCopyFrom() {
|
||||
return this.copyFrom;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
package mage.game.stack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.ObjectColor;
|
||||
|
|
@ -32,8 +28,12 @@ import mage.util.GameLog;
|
|||
import mage.util.SubTypeList;
|
||||
import mage.watchers.Watcher;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class StackAbility extends StackObjImpl implements Ability {
|
||||
|
|
@ -47,6 +47,8 @@ public class StackAbility extends StackObjImpl implements Ability {
|
|||
|
||||
private final Ability ability;
|
||||
private UUID controllerId;
|
||||
private boolean copy;
|
||||
private MageObject copyFrom; // copied card INFO (used to call original adjusters)
|
||||
private String name;
|
||||
private String expansionSetCode;
|
||||
private TargetAdjuster targetAdjuster = null;
|
||||
|
|
@ -60,6 +62,8 @@ public class StackAbility extends StackObjImpl implements Ability {
|
|||
public StackAbility(final StackAbility stackAbility) {
|
||||
this.ability = stackAbility.ability.copy();
|
||||
this.controllerId = stackAbility.controllerId;
|
||||
this.copy = stackAbility.copy;
|
||||
this.copyFrom = (stackAbility.copyFrom != null ? stackAbility.copyFrom.copy() : null);
|
||||
this.name = stackAbility.name;
|
||||
this.expansionSetCode = stackAbility.expansionSetCode;
|
||||
this.targetAdjuster = stackAbility.targetAdjuster;
|
||||
|
|
@ -104,6 +108,22 @@ public class StackAbility extends StackObjImpl implements Ability {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCopy(boolean isCopy, MageObject copyFrom) {
|
||||
this.copy = isCopy;
|
||||
this.copyFrom = (copyFrom != null ? copyFrom.copy() : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCopy() {
|
||||
return this.copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MageObject getCopyFrom() {
|
||||
return this.copyFrom;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
|
|
@ -408,15 +428,6 @@ public class StackAbility extends StackObjImpl implements Ability {
|
|||
throw new UnsupportedOperationException("Not supported.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCopy(boolean isCopy) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCopy() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getRuleAtTheTop() {
|
||||
return this.ability.getRuleAtTheTop();
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
package mage.players;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import mage.ConditionalMana;
|
||||
import mage.MageObject;
|
||||
import mage.MageObjectReference;
|
||||
|
|
@ -72,6 +68,11 @@ import mage.util.GameLog;
|
|||
import mage.util.RandomUtil;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public abstract class PlayerImpl implements Player, Serializable {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(PlayerImpl.class);
|
||||
|
|
@ -2573,7 +2574,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
/**
|
||||
* @param game
|
||||
* @param appliedEffects
|
||||
* @param numSides Number of sides the dice has
|
||||
* @param numSides Number of sides the dice has
|
||||
* @return the number that the player rolled
|
||||
*/
|
||||
@Override
|
||||
|
|
@ -2607,10 +2608,10 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
/**
|
||||
* @param game
|
||||
* @param appliedEffects
|
||||
* @param numberChaosSides The number of chaos sides the planar die
|
||||
* currently has (normally 1 but can be 5)
|
||||
* @param numberChaosSides The number of chaos sides the planar die
|
||||
* currently has (normally 1 but can be 5)
|
||||
* @param numberPlanarSides The number of chaos sides the planar die
|
||||
* currently has (normally 1)
|
||||
* currently has (normally 1)
|
||||
* @return the outcome that the player rolled. Either ChaosRoll, PlanarRoll
|
||||
* or NilRoll
|
||||
*/
|
||||
|
|
@ -2767,7 +2768,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
/**
|
||||
* @param ability
|
||||
* @param available if null, it won't be checked if enough mana is available
|
||||
* @param available if null, it won't be checked if enough mana is available
|
||||
* @param sourceObject
|
||||
* @param game
|
||||
* @return
|
||||
|
|
@ -3319,7 +3320,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
@Override
|
||||
public boolean canPaySacrificeCost(Permanent permanent, UUID sourceId,
|
||||
UUID controllerId, Game game
|
||||
UUID controllerId, Game game
|
||||
) {
|
||||
return sacrificeCostFilter == null || !sacrificeCostFilter.match(permanent, sourceId, controllerId, game);
|
||||
}
|
||||
|
|
@ -3467,8 +3468,8 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
@Override
|
||||
public boolean moveCards(Card card, Zone toZone,
|
||||
Ability source, Game game,
|
||||
boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects
|
||||
Ability source, Game game,
|
||||
boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects
|
||||
) {
|
||||
Set<Card> cardList = new HashSet<>();
|
||||
if (card != null) {
|
||||
|
|
@ -3479,22 +3480,22 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
@Override
|
||||
public boolean moveCards(Cards cards, Zone toZone,
|
||||
Ability source, Game game
|
||||
Ability source, Game game
|
||||
) {
|
||||
return moveCards(cards.getCards(game), toZone, source, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveCards(Set<Card> cards, Zone toZone,
|
||||
Ability source, Game game
|
||||
Ability source, Game game
|
||||
) {
|
||||
return moveCards(cards, toZone, source, game, false, false, false, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveCards(Set<Card> cards, Zone toZone,
|
||||
Ability source, Game game,
|
||||
boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects
|
||||
Ability source, Game game,
|
||||
boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects
|
||||
) {
|
||||
if (cards.isEmpty()) {
|
||||
return true;
|
||||
|
|
@ -3580,8 +3581,8 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
@Override
|
||||
public boolean moveCardsToExile(Card card, Ability source,
|
||||
Game game, boolean withName, UUID exileId,
|
||||
String exileZoneName
|
||||
Game game, boolean withName, UUID exileId,
|
||||
String exileZoneName
|
||||
) {
|
||||
Set<Card> cards = new HashSet<>();
|
||||
cards.add(card);
|
||||
|
|
@ -3590,8 +3591,8 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
@Override
|
||||
public boolean moveCardsToExile(Set<Card> cards, Ability source,
|
||||
Game game, boolean withName, UUID exileId,
|
||||
String exileZoneName
|
||||
Game game, boolean withName, UUID exileId,
|
||||
String exileZoneName
|
||||
) {
|
||||
if (cards.isEmpty()) {
|
||||
return true;
|
||||
|
|
@ -3606,14 +3607,14 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
@Override
|
||||
public boolean moveCardToHandWithInfo(Card card, UUID sourceId,
|
||||
Game game
|
||||
Game game
|
||||
) {
|
||||
return this.moveCardToHandWithInfo(card, sourceId, game, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveCardToHandWithInfo(Card card, UUID sourceId,
|
||||
Game game, boolean withName
|
||||
Game game, boolean withName
|
||||
) {
|
||||
boolean result = false;
|
||||
Zone fromZone = game.getState().getZone(card.getId());
|
||||
|
|
@ -3638,7 +3639,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
@Override
|
||||
public Set<Card> moveCardsToGraveyardWithInfo(Set<Card> allCards, Ability source,
|
||||
Game game, Zone fromZone
|
||||
Game game, Zone fromZone
|
||||
) {
|
||||
UUID sourceId = source == null ? null : source.getSourceId();
|
||||
Set<Card> movedCards = new LinkedHashSet<>();
|
||||
|
|
@ -3646,7 +3647,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
// identify cards from one owner
|
||||
Cards cards = new CardsImpl();
|
||||
UUID ownerId = null;
|
||||
for (Iterator<Card> it = allCards.iterator(); it.hasNext();) {
|
||||
for (Iterator<Card> it = allCards.iterator(); it.hasNext(); ) {
|
||||
Card card = it.next();
|
||||
if (cards.isEmpty()) {
|
||||
ownerId = card.getOwnerId();
|
||||
|
|
@ -3707,7 +3708,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
@Override
|
||||
public boolean moveCardToGraveyardWithInfo(Card card, UUID sourceId,
|
||||
Game game, Zone fromZone
|
||||
Game game, Zone fromZone
|
||||
) {
|
||||
if (card == null) {
|
||||
return false;
|
||||
|
|
@ -3736,8 +3737,8 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
@Override
|
||||
public boolean moveCardToLibraryWithInfo(Card card, UUID sourceId,
|
||||
Game game, Zone fromZone,
|
||||
boolean toTop, boolean withName
|
||||
Game game, Zone fromZone,
|
||||
boolean toTop, boolean withName
|
||||
) {
|
||||
if (card == null) {
|
||||
return false;
|
||||
|
|
@ -3771,7 +3772,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
@Override
|
||||
public boolean moveCardToExileWithInfo(Card card, UUID exileId, String exileName, UUID sourceId,
|
||||
Game game, Zone fromZone, boolean withName) {
|
||||
Game game, Zone fromZone, boolean withName) {
|
||||
if (card == null) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -3786,7 +3787,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
}
|
||||
} else if (card instanceof Spell) {
|
||||
final Spell spell = (Spell) card;
|
||||
if (spell.isCopiedSpell()) {
|
||||
if (spell.isCopy()) {
|
||||
// Copied spell, only remove from stack
|
||||
game.getStack().remove(spell, game);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue