mirror of
https://github.com/magefree/mage.git
synced 2026-01-10 12:52:06 -08:00
Fix copying subabilities to no longer duplicate them (#11399)
* Fix Subability copy bug (fix #10526 ) * Cards which copy abilities of other cards should not copy subabilities. * Enable previously-failing tests * Find more addAbility that should be done without subabilities * Add documentation to addAbility function * Add warning about not using basic addAbility when copying from a source * Invert withSubabilities to fromExistingObject
This commit is contained in:
parent
3972e80860
commit
ec4c79e0e0
39 changed files with 83 additions and 40 deletions
|
|
@ -139,7 +139,7 @@ class AgathasSoulCauldronAbilityEffect extends ContinuousEffectImpl {
|
|||
}
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)) {
|
||||
for (Ability ability : abilities) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
permanent.addAbility(ability, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ class DarkImpostorContinuousEffect extends ContinuousEffectImpl {
|
|||
for (Card card : exileZone.getCards(StaticFilters.FILTER_CARD_CREATURE, game)) {
|
||||
for (Ability ability : card.getAbilities(game)) {
|
||||
if (ability instanceof ActivatedAbility) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
permanent.addAbility(ability, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ class DranaAndLinvalaGainAbilitiesEffect extends ContinuousEffectImpl {
|
|||
.filter(ability -> ability.getAbilityType() == AbilityType.ACTIVATED
|
||||
|| ability.getAbilityType() == AbilityType.MANA)
|
||||
.collect(Collectors.toList())) {
|
||||
Ability addedAbility = perm.addAbility(ability, source.getSourceId(), game);
|
||||
Ability addedAbility = perm.addAbility(ability, source.getSourceId(), game, true);
|
||||
if (addedAbility != null) {
|
||||
addedAbility.getEffects().setValue("dranaLinvalaFlag", true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ class ExperimentKrajEffect extends ContinuousEffectImpl {
|
|||
for (Permanent creature :game.getState().getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)){
|
||||
for (Ability ability: creature.getAbilities()) {
|
||||
if (ability instanceof ActivatedAbility) {
|
||||
perm.addAbility(ability, source.getSourceId(), game);
|
||||
perm.addAbility(ability, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ import mage.filter.FilterCard;
|
|||
import mage.filter.common.FilterCreatureCard;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.common.TargetCardInGraveyard;
|
||||
|
||||
|
|
@ -188,7 +187,7 @@ class HavengulLichEffect extends ContinuousEffectImpl {
|
|||
Card card = game.getCard(cardId);
|
||||
if (permanent != null && card != null) {
|
||||
for (ActivatedAbility ability : card.getAbilities(game).getActivatedAbilities(Zone.BATTLEFIELD)) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
permanent.addAbility(ability, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ class KasminaEnigmaSageGainAbilitiesEffect extends ContinuousEffectImpl {
|
|||
continue;
|
||||
}
|
||||
for (Ability ability : loyaltyAbilities) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
permanent.addAbility(ability, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ class MairsilThePretenderGainAbilitiesEffect extends ContinuousEffectImpl {
|
|||
if (ability instanceof ActivatedAbility) {
|
||||
ActivatedAbility copyAbility = (ActivatedAbility) ability.copy();
|
||||
copyAbility.setMaxActivationsPerTurn(1);
|
||||
perm.addAbility(copyAbility, source.getSourceId(), game);
|
||||
perm.addAbility(copyAbility, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ class ManascapeRefractorGainAbilitiesEffect extends ContinuousEffectImpl {
|
|||
|| perm.getAbilities(game)
|
||||
.stream()
|
||||
.noneMatch(ability.getClass()::isInstance)) {
|
||||
perm.addAbility(ability, source.getSourceId(), game);
|
||||
perm.addAbility(ability, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ class MetamorphicAlterationEffect extends ContinuousEffectImpl {
|
|||
permanent.getColor(game).setColor(copied.getColor(game));
|
||||
permanent.removeAllAbilities(source.getSourceId(), game);
|
||||
for (Ability ability : copied.getAbilities()) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
permanent.addAbility(ability, source.getSourceId(), game, true);
|
||||
}
|
||||
permanent.getPower().setModifiedBaseValue(copied.getPower().getBaseValue());
|
||||
permanent.getToughness().setModifiedBaseValue(copied.getToughness().getBaseValue());
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ class MirranSafehouseEffect extends ContinuousEffectImpl {
|
|||
.filter(ActivatedAbility.class::isInstance)
|
||||
.collect(Collectors.toSet());
|
||||
for (Ability ability : abilities) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
permanent.addAbility(ability, source.getSourceId(), game, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ class MyrWelderContinuousEffect extends ContinuousEffectImpl {
|
|||
if (card != null) {
|
||||
for (Ability ability : card.getAbilities(game)) {
|
||||
if (ability instanceof ActivatedAbility) {
|
||||
perm.addAbility(ability, source.getId(), game);
|
||||
perm.addAbility(ability, source.getId(), game, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ class NecroticOozeEffect extends ContinuousEffectImpl {
|
|||
.filter(ActivatedAbility.class::isInstance)
|
||||
.collect(Collectors.toSet());
|
||||
for (Ability ability : abilities) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
permanent.addAbility(ability, source.getSourceId(), game, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ class NicolBolasDragonGodGainAbilitiesEffect extends ContinuousEffectImpl {
|
|||
)) {
|
||||
for (Ability ability : permanent.getAbilities()) {
|
||||
if (ability instanceof LoyaltyAbility) {
|
||||
perm.addAbility(ability, source.getSourceId(), game);
|
||||
perm.addAbility(ability, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ class PatchworkCrawlerEffect extends ContinuousEffectImpl {
|
|||
for (Card card : exileZone.getCards(StaticFilters.FILTER_CARD_CREATURE, game)) {
|
||||
for (Ability ability : card.getAbilities(game)) {
|
||||
if (ability instanceof ActivatedAbility) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
permanent.addAbility(ability, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ class QuicksilverElementalEffect extends OneShotEffect {
|
|||
for (ActivatedAbility ability : creature.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) {
|
||||
Ability newAbility = ability.copy();
|
||||
newAbility.newOriginalId();
|
||||
newAbility.getSubAbilities().clear(); //Should not copy subabilities
|
||||
game.addEffect(new GainAbilitySourceEffect(newAbility, Duration.EndOfTurn), source);
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ class RobaranMercenariesEffect extends ContinuousEffectImpl {
|
|||
|| perm.getAbilities(game)
|
||||
.stream()
|
||||
.noneMatch(ability.getClass()::isInstance)) {
|
||||
perm.addAbility(ability, source.getSourceId(), game);
|
||||
perm.addAbility(ability, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ class SchemingFenceGainEffect extends ContinuousEffectImpl {
|
|||
if (!(ability instanceof LoyaltyAbility)) {
|
||||
Ability copied = ability.copy();
|
||||
ability.getEffects().setValue("schemingFence", source.getSourceId());
|
||||
permanent.addAbility(copied, source.getSourceId(), game);
|
||||
permanent.addAbility(copied, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ class SharkeyTyrantOfTheShireContinousEffect extends ContinuousEffectImpl {
|
|||
.filter(Objects::nonNull)
|
||||
.filter(ability -> ability.getAbilityType() == AbilityType.ACTIVATED) // Mana abilities are separated in their own AbilityType.Mana
|
||||
.collect(Collectors.toList())) {
|
||||
perm.addAbility(ability, source.getSourceId(), game);
|
||||
perm.addAbility(ability, source.getSourceId(), game, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ class TheBookOfVileDarknessEffect extends OneShotEffect {
|
|||
Ability copyAbility = ability.copy();
|
||||
copyAbility.newId();
|
||||
copyAbility.setControllerId(source.getControllerId());
|
||||
token.addAbility(copyAbility);
|
||||
token.addAbility(copyAbility, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ class TrazynTheInfiniteEffect extends ContinuousEffectImpl {
|
|||
.filter(ActivatedAbility.class::isInstance)
|
||||
.collect(Collectors.toSet());
|
||||
for (Ability ability : abilities) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
permanent.addAbility(ability, source.getSourceId(), game, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ class VolrathsShapeshifterEffect extends ContinuousEffectImpl {
|
|||
|
||||
for (Ability ability : card.getAbilities(game)) {
|
||||
if (!permanent.getAbilities().contains(ability)) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
permanent.addAbility(ability, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -198,9 +198,7 @@ public class SquadTest extends CardTestPlayerBase {
|
|||
}
|
||||
|
||||
// The squad status is a copiable value of the spell, and should be carried over on copy.
|
||||
@Ignore
|
||||
@Test
|
||||
//TODO: Enable after fixing subability copying twice bug
|
||||
public void test_CopyingSpellMustKeepSquadStatus() {
|
||||
|
||||
addCard(Zone.HAND, playerA, flagellant, 1);
|
||||
|
|
|
|||
|
|
@ -80,7 +80,6 @@ public class CopyPermanentSpellTest extends CardTestPlayerBase {
|
|||
assertPermanentCount(playerA, "Dead Weight", 2);
|
||||
}
|
||||
|
||||
@Ignore // currently fails
|
||||
@Test
|
||||
public void testKickerTrigger() {
|
||||
makeTester();
|
||||
|
|
@ -98,7 +97,6 @@ public class CopyPermanentSpellTest extends CardTestPlayerBase {
|
|||
assertPowerToughness(playerA, "Grizzly Bears", 4, 2);
|
||||
}
|
||||
|
||||
@Ignore // currently fails
|
||||
@Test
|
||||
public void testKickerReplacement() {
|
||||
makeTester();
|
||||
|
|
|
|||
|
|
@ -332,6 +332,8 @@ public interface Ability extends Controllable, Serializable {
|
|||
|
||||
/**
|
||||
* Gets the list of sub-abilities associated with this ability.
|
||||
* When copying, subabilities are copied separately and thus the list is desynced.
|
||||
* Do not interact with the subabilities list during a game!
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -119,11 +119,11 @@ public class CopyEffect extends ContinuousEffectImpl {
|
|||
permanent.removeAllAbilities(source.getSourceId(), game);
|
||||
if (copyFromObject instanceof Permanent) {
|
||||
for (Ability ability : ((Permanent) copyFromObject).getAbilities(game)) {
|
||||
permanent.addAbility(ability, getSourceId(), game);
|
||||
permanent.addAbility(ability, getSourceId(), game, true);
|
||||
}
|
||||
} else {
|
||||
for (Ability ability : copyFromObject.getAbilities()) {
|
||||
permanent.addAbility(ability, getSourceId(), game);
|
||||
permanent.addAbility(ability, getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public class CopyTokenEffect extends ContinuousEffectImpl {
|
|||
}
|
||||
permanent.getAbilities().clear();
|
||||
for (Ability ability : token.getAbilities()) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
permanent.addAbility(ability, source.getSourceId(), game, true);
|
||||
}
|
||||
permanent.getPower().setModifiedBaseValue(token.getPower().getModifiedBaseValue());
|
||||
permanent.getToughness().setModifiedBaseValue(token.getToughness().getModifiedBaseValue());
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public class GainActivatedAbilitiesOfTopCardEffect extends ContinuousEffectImpl
|
|||
if (permanent != null) {
|
||||
for (Ability ability : card.getAbilities(game)) {
|
||||
if (ability instanceof ActivatedAbility) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
permanent.addAbility(ability, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ public class BecomesCreatureAllEffect extends ContinuousEffectImpl {
|
|||
case AbilityAddingRemovingEffects_6:
|
||||
if (!token.getAbilities().isEmpty()) {
|
||||
for (Ability ability : token.getAbilities()) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
permanent.addAbility(ability, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ public class BecomesCreatureAttachedEffect extends ContinuousEffectImpl {
|
|||
break;
|
||||
}
|
||||
for (Ability ability : token.getAbilities()) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
permanent.addAbility(ability, source.getSourceId(), game, true);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl {
|
|||
permanent.removeAllAbilities(source.getSourceId(), game);
|
||||
}
|
||||
for (Ability ability : token.getAbilities()) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
permanent.addAbility(ability, source.getSourceId(), game, true);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ public class BecomesCreatureTargetEffect extends ContinuousEffectImpl {
|
|||
if (sublayer == SubLayer.NA) {
|
||||
if (!token.getAbilities().isEmpty()) {
|
||||
for (Ability ability : token.getAbilities()) {
|
||||
permanent.addAbility(ability, source.getSourceId(), game);
|
||||
permanent.addAbility(ability, source.getSourceId(), game, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ public class CrewAbility extends SimpleActivatedAbility {
|
|||
this.addIcon(new CardIconImpl(CardIconType.ABILITY_CREW, "Crew " + value));
|
||||
this.value = value;
|
||||
if (altCost != null) {
|
||||
//TODO: the entire alternative cost should be included in the subability, not just the hint text
|
||||
// Heart of Kiran's alternative crew cost is a static ability, not part of the activated ability directly
|
||||
this.addSubAbility(new SimpleStaticAbility(Zone.ALL, new InfoEffect(
|
||||
"you may " + CardUtil.addCostVerb(altCost.getText())
|
||||
+ " rather than pay {this}'s crew cost"
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ public class TransformAbility extends SimpleStaticAbility {
|
|||
for (Ability ability : sourceCard.getAbilities()) {
|
||||
// source == null -- call from init card (e.g. own abilities)
|
||||
// source != null -- from apply effect
|
||||
permanent.addAbility(ability, source == null ? permanent.getId() : source.getSourceId(), game);
|
||||
permanent.addAbility(ability, source == null ? permanent.getId() : source.getSourceId(), game, true);
|
||||
}
|
||||
permanent.getPower().setModifiedBaseValue(sourceCard.getPower().getValue());
|
||||
permanent.getToughness().setModifiedBaseValue(sourceCard.getToughness().getValue());
|
||||
|
|
|
|||
|
|
@ -218,6 +218,7 @@ public interface Permanent extends Card, Controllable {
|
|||
* @return can be null for exists abilities
|
||||
*/
|
||||
Ability addAbility(Ability ability, UUID sourceId, Game game);
|
||||
Ability addAbility(Ability ability, UUID sourceId, Game game, boolean fromExistingObject);
|
||||
|
||||
void removeAllAbilities(UUID sourceId, Game game);
|
||||
|
||||
|
|
|
|||
|
|
@ -388,8 +388,29 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
|
|||
return super.getAbilities(game);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an ability to the permanent. When copying from an existing source
|
||||
* you should use the fromExistingObject variant of this function to prevent double-copying subabilities
|
||||
* @param ability The ability to be added
|
||||
* @param sourceId id of the source doing the added (for the effect created to add it)
|
||||
* @param game
|
||||
* @return The newly added ability copy
|
||||
*/
|
||||
@Override
|
||||
public Ability addAbility(Ability ability, UUID sourceId, Game game) {
|
||||
return addAbility(ability, sourceId, game, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ability The ability to be added
|
||||
* @param sourceId id of the source doing the added (for the effect created to add it)
|
||||
* @param game
|
||||
* @param fromExistingObject if copying abilities from an existing source then must ignore sub-abilities because they're already on the source object
|
||||
* Otherwise sub-abilities will be added twice to the resulting object
|
||||
* @return The newly added ability copy
|
||||
*/
|
||||
@Override
|
||||
public Ability addAbility(Ability ability, UUID sourceId, Game game, boolean fromExistingObject) {
|
||||
// singleton abilities -- only one instance
|
||||
// other abilities -- any amount of instances
|
||||
if (!abilities.containsKey(ability.getId())) {
|
||||
|
|
@ -404,7 +425,9 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
|
|||
game.getState().addAbility(copyAbility, sourceId, this);
|
||||
}
|
||||
abilities.add(copyAbility);
|
||||
abilities.addAll(ability.getSubAbilities());
|
||||
if (!fromExistingObject) {
|
||||
abilities.addAll(copyAbility.getSubAbilities());
|
||||
}
|
||||
return copyAbility;
|
||||
}
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -89,7 +89,8 @@ public class PermanentToken extends PermanentImpl {
|
|||
// first time -> create ContinuousEffects only once
|
||||
// so sourceId must be null (keep triggered abilities forever?)
|
||||
for (Ability ability : token.getAbilities()) {
|
||||
this.addAbility(ability, null, game);
|
||||
//Don't add subabilities since the original token already has them in its abilities list
|
||||
this.addAbility(ability, null, game, true);
|
||||
}
|
||||
}
|
||||
this.abilities.setControllerId(this.controllerId);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ public interface Token extends MageObject {
|
|||
List<UUID> getLastAddedTokenIds();
|
||||
|
||||
void addAbility(Ability ability);
|
||||
void addAbility(Ability ability, boolean fromExistingObject);
|
||||
|
||||
void removeAbility(Ability abilityToRemove);
|
||||
|
||||
|
|
|
|||
|
|
@ -77,15 +77,33 @@ public abstract class TokenImpl extends MageObjectImpl implements Token {
|
|||
return new ArrayList<>(lastAddedTokenIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an ability to the token. When copying from an existing source
|
||||
* you should use the fromExistingObject variant of this function to prevent double-copying subabilities
|
||||
* @param ability The ability to be added
|
||||
*/
|
||||
@Override
|
||||
public void addAbility(Ability ability) {
|
||||
addAbility(ability, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ability The ability to be added
|
||||
* @param fromExistingObject if copying abilities from an existing source then must ignore sub-abilities because they're already on the source object
|
||||
* Otherwise sub-abilities will be added twice to the resulting object
|
||||
*/
|
||||
@Override
|
||||
public void addAbility(Ability ability, boolean fromExistingObject) {
|
||||
ability.setSourceId(this.getId());
|
||||
abilities.add(ability);
|
||||
abilities.addAll(ability.getSubAbilities());
|
||||
if (!fromExistingObject) {
|
||||
abilities.addAll(ability.getSubAbilities());
|
||||
}
|
||||
|
||||
// TODO: remove all override and backFace changes (bug example: active transform ability in back face)
|
||||
if (backFace != null) {
|
||||
backFace.addAbility(ability);
|
||||
// Maybe supposed to add subabilities here too?
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -140,8 +140,8 @@ public class CopyTokenFunction {
|
|||
// otherwise there are problems to check for created continuous effects to check if
|
||||
// the source (the Token) has still this ability
|
||||
ability.newOriginalId();
|
||||
|
||||
target.addAbility(ability);
|
||||
//Don't re-add subabilities since they've already in sourceObj's abilities list
|
||||
target.addAbility(ability, true);
|
||||
}
|
||||
|
||||
target.setPower(sourceObj.getPower().getBaseValue());
|
||||
|
|
@ -152,7 +152,6 @@ public class CopyTokenFunction {
|
|||
|
||||
private Token from(Card source, Game game, Spell spell) {
|
||||
apply(source, game);
|
||||
|
||||
// token's ZCC must be synced with original card to keep abilities settings
|
||||
// Example: kicker ability and kicked status
|
||||
if (spell != null) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue