Tyvar Kell and gain ability fixes:

* GainAbilityTargetEffect - reworked to support static/dynamic targets, added support of spells (card + related permanent);
* SpellCastControllerTriggeredAbility - now it can setup the target to a card instead a spell;
* Added checks/errors on wrong ability adding code (example: if you add permanent's ability by game state instead permanent's method);
* Tyvar Kell Emblem now use a standard code;
* Test framework: added additional logs for some errors;
This commit is contained in:
Oleg Agafonov 2021-01-12 04:37:13 +04:00
parent f131fd0d12
commit 6dcbcbe962
13 changed files with 291 additions and 140 deletions

View file

@ -1,9 +1,5 @@
package mage.game;
import java.io.Serializable;
import java.util.*;
import static java.util.Collections.emptyList;
import java.util.stream.Collectors;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.*;
@ -25,6 +21,7 @@ import mage.game.command.Plane;
import mage.game.events.*;
import mage.game.permanent.Battlefield;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard;
import mage.game.permanent.PermanentToken;
import mage.game.stack.SpellStack;
import mage.game.stack.StackObject;
@ -39,6 +36,12 @@ import mage.util.ThreadLocalStringBuilder;
import mage.watchers.Watcher;
import mage.watchers.Watchers;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
import static java.util.Collections.emptyList;
/**
* @author BetaSteward_at_googlemail.com
* <p>
@ -1067,6 +1070,8 @@ public class GameState implements Serializable, Copyable<GameState> {
* @param ability
*/
public void addOtherAbility(Card attachedTo, Ability ability) {
checkWrongDynamicAbilityUsage(attachedTo, ability);
addOtherAbility(attachedTo, ability, true);
}
@ -1079,6 +1084,8 @@ public class GameState implements Serializable, Copyable<GameState> {
* state
*/
public void addOtherAbility(Card attachedTo, Ability ability, boolean copyAbility) {
checkWrongDynamicAbilityUsage(attachedTo, ability);
Ability newAbility;
if (ability instanceof MageSingleton || !copyAbility) {
newAbility = ability;
@ -1094,6 +1101,16 @@ public class GameState implements Serializable, Copyable<GameState> {
addAbility(newAbility, attachedTo.getId(), attachedTo);
}
private void checkWrongDynamicAbilityUsage(Card attachedTo, Ability ability) {
// dynamic abilities for card only
// permanent's abilities are static and generated each reset cycle
if (attachedTo instanceof PermanentCard) {
throw new IllegalArgumentException("Error, wrong code usage. If you want to add new ability to the "
+ "permanent then use a permanent.addAbility(a, source, game): "
+ ability.getClass().getCanonicalName() + " - " + ability.toString());
}
}
/**
* Removes Triggered abilities that belong to sourceId This is used if a
* token leaves the battlefield