forked from External/mage
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
|
|
@ -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());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue