foul-magics/Mage/src/main/java/mage/abilities/effects/common/CopyEffect.java
Evan Kranzler 8617bc128e
Fixing issues with Changelings and general problems with creature types (ready to merge) (#7098)
* updated Changelings to use setIsAllCreatureTypes

* updated Dr Julius Jumblemorph and Mistform Ultimus to not use changeling

* added test for Mistform Ultimus

* updated effects which give all creature types to controlled creatures

* updated effects which give all creature types to targeted creatures

* Update LoseAllCreatureTypesTargetEffect.java

* updated effects which give all creature types to attached creatures

* Update EgoErasure.java

* added another test for changelings

* updated two tokens I left out before

* updated hasSubtype

* updated shareCreatureTypes

* fixed an incorrect test

* cleaned up some cards which check for shared creature types

* added new changeling test

* fixed issue with shareCreatureTypes

* fixed a text issue

* added new tests for subtype effects

* various individual card fixes and cleanups

* fixed and updated various effects

* many more fixes

* a few more fixes

* added test for One with the Stars

* added changeling verify test

* updated effects which add additional subtypes

* more miscellaneous fixes

* added additional test

* some fixes for card type checks

* updated methods for adding types to make it easier to avoid duplicates and illegal additions

* small test update

* fixed a recursive loop issue

* fixed another error

* fixed it for real this time

* streamlined type removal process

* streamlined subtype set generation
2020-10-30 22:32:59 -04:00

176 lines
6.9 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package mage.abilities.effects.common;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.Card;
import mage.constants.*;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard;
import mage.game.permanent.PermanentToken;
import mage.util.functions.ApplyToPermanent;
import java.util.UUID;
/**
* @author BetaSteward_at_googlemail.com
*/
public class CopyEffect extends ContinuousEffectImpl {
/**
* Object we copy from
*/
protected MageObject copyFromObject;
protected UUID copyToObjectId;
protected ApplyToPermanent applier;
public CopyEffect(MageObject copyFromObject, UUID copyToObjectId) {
this(Duration.Custom, copyFromObject, copyToObjectId);
}
public CopyEffect(Duration duration, MageObject copyFromObject, UUID copyToObjectId) {
super(duration, Layer.CopyEffects_1, SubLayer.NA, Outcome.BecomeCreature);
this.copyFromObject = copyFromObject;
this.copyToObjectId = copyToObjectId;
}
public CopyEffect(final CopyEffect effect) {
super(effect);
this.copyFromObject = effect.copyFromObject.copy();
this.copyToObjectId = effect.copyToObjectId;
this.applier = effect.applier;
}
@Override
public void init(Ability source, Game game) {
super.init(source, game);
if (!(copyFromObject instanceof Permanent) && (copyFromObject instanceof Card)) {
this.copyFromObject = new PermanentCard((Card) copyFromObject, source.getControllerId(), game);
}
Permanent permanent = game.getPermanent(copyToObjectId);
if (permanent != null) {
affectedObjectList.add(new MageObjectReference(permanent, game));
} else if (source.getAbilityType() == AbilityType.STATIC) {
// for replacement effects that let a permanent enter the battlefield as a copy of another permanent we need to apply that copy
// before the permanent is added to the battlefield
permanent = game.getPermanentEntering(copyToObjectId);
if (permanent != null) {
copyToPermanent(permanent, game, source);
// set reference to the permanent later on the battlefield so we have to add already one (if no token) to the zone change counter
int ZCCDiff = 1;
if (permanent instanceof PermanentToken) {
ZCCDiff = 0;
}
affectedObjectList.add(new MageObjectReference(permanent.getId(), game.getState().getZoneChangeCounter(copyToObjectId) + ZCCDiff, game));
}
}
}
@Override
public boolean apply(Game game, Ability source) {
if (affectedObjectList.isEmpty()) {
this.discard();
return false;
}
Permanent permanent = affectedObjectList.get(0).getPermanent(game);
if (permanent == null) {
permanent = (Permanent) game.getLastKnownInformation(getSourceId(), Zone.BATTLEFIELD, source.getSourceObjectZoneChangeCounter());
// As long as the permanent is still in the LKI continue to copy to get triggered abilities to TriggeredAbilites for dies events.
if (permanent == null) {
discard();
return false;
}
}
return copyToPermanent(permanent, game, source);
}
protected boolean copyToPermanent(Permanent permanent, Game game, Ability source) {
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();
permanent.getManaCost().add(copyFromObject.getManaCost());
permanent.getCardType().clear();
for (CardType type : copyFromObject.getCardType()) {
permanent.addCardType(type);
}
permanent.removeAllSubTypes(game);
permanent.getSubtype(game).addAll(copyFromObject.getSubtype(game));
permanent.setIsAllCreatureTypes(copyFromObject.isAllCreatureTypes());
permanent.getSuperType().clear();
for (SuperType type : copyFromObject.getSuperType()) {
permanent.addSuperType(type);
}
permanent.removeAllAbilities(source.getSourceId(), game);
if (copyFromObject instanceof Permanent) {
for (Ability ability : ((Permanent) copyFromObject).getAbilities(game)) {
permanent.addAbility(ability, getSourceId(), game);
}
} else {
for (Ability ability : copyFromObject.getAbilities()) {
permanent.addAbility(ability, getSourceId(), game);
}
}
// Primal Clay example:
// If a creature thats already on the battlefield becomes a copy of this creature, it copies the power, toughness,
// and abilities that were chosen for this creature as it entered the battlefield. (2018-03-16)
permanent.getPower().setValue(copyFromObject.getPower().getBaseValueModified());
permanent.getToughness().setValue(copyFromObject.getToughness().getBaseValueModified());
if (copyFromObject instanceof Permanent) {
Permanent targetPermanent = (Permanent) copyFromObject;
permanent.setTransformed(targetPermanent.isTransformed());
permanent.setSecondCardFace(targetPermanent.getSecondCardFace());
permanent.setFlipCard(targetPermanent.isFlipCard());
permanent.setFlipCardName(targetPermanent.getFlipCardName());
}
// to get the image of the copied permanent copy number und expansionCode
if (copyFromObject instanceof PermanentCard) {
permanent.setCardNumber(((PermanentCard) copyFromObject).getCard().getCardNumber());
permanent.setExpansionSetCode(((PermanentCard) copyFromObject).getCard().getExpansionSetCode());
} else if (copyFromObject instanceof PermanentToken || copyFromObject instanceof Card) {
permanent.setCardNumber(((Card) copyFromObject).getCardNumber());
permanent.setExpansionSetCode(((Card) copyFromObject).getExpansionSetCode());
}
return true;
}
@Override
public CopyEffect copy() {
return new CopyEffect(this);
}
public MageObject getTarget() {
return copyFromObject;
}
public void setTarget(MageObject target) {
this.copyFromObject = target;
}
public UUID getSourceId() {
return copyToObjectId;
}
public ApplyToPermanent getApplier() {
return applier;
}
public void setApplier(ApplyToPermanent applier) {
this.applier = applier;
}
}