Search in sources :

Example 1 with Watcher

use of mage.watchers.Watcher in project mage by magefree.

the class MetzaliTowerOfTriumphEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Watcher watcher = game.getState().getWatcher(AttackedThisTurnWatcher.class);
    if (watcher instanceof AttackedThisTurnWatcher) {
        Set<MageObjectReference> attackedThisTurn = ((AttackedThisTurnWatcher) watcher).getAttackedThisTurnCreatures();
        List<Permanent> available = new ArrayList<>();
        for (MageObjectReference mor : attackedThisTurn) {
            Permanent permanent = mor.getPermanent(game);
            if (permanent != null && permanent.isCreature(game)) {
                available.add(permanent);
            }
        }
        if (!available.isEmpty()) {
            Permanent permanent = available.get(RandomUtil.nextInt(available.size()));
            if (permanent != null) {
                permanent.destroy(source, game, false);
            }
        }
        return true;
    }
    return false;
}
Also used : Permanent(mage.game.permanent.Permanent) AttackedThisTurnWatcher(mage.watchers.common.AttackedThisTurnWatcher) ArrayList(java.util.ArrayList) AttackedThisTurnWatcher(mage.watchers.common.AttackedThisTurnWatcher) Watcher(mage.watchers.Watcher) MageObjectReference(mage.MageObjectReference)

Example 2 with Watcher

use of mage.watchers.Watcher in project mage by magefree.

the class VerifyCardDataTest method test_checkWatcherCopyMethods.

@Test
public void test_checkWatcherCopyMethods() {
    Collection<String> errorsList = new ArrayList<>();
    Collection<String> warningsList = new ArrayList<>();
    Reflections reflections = new Reflections("mage.");
    Set<Class<? extends Watcher>> watcherClassesList = reflections.getSubTypesOf(Watcher.class);
    for (Class<? extends Watcher> watcherClass : watcherClassesList) {
        // only watcher class can be extended (e.g. final)
        if (!watcherClass.getSuperclass().equals(Watcher.class)) {
            errorsList.add("Error: only Watcher class can be extended: " + watcherClass.getName());
        }
        // no copy methods
        try {
            Method m = watcherClass.getMethod("copy");
            if (!m.getGenericReturnType().getTypeName().equals("T")) {
                errorsList.add("Error: copy() method must be deleted from watcher class: " + watcherClass.getName());
            }
        } catch (NoSuchMethodException e) {
            errorsList.add("Error: can't find copy() method in watcher class: " + watcherClass.getName());
        }
        // no constructor for copy
        try {
            Constructor<? extends Watcher> constructor = watcherClass.getDeclaredConstructor(watcherClass);
            errorsList.add("Error: copy constructor is not allowed in watcher class: " + watcherClass.getName());
        } catch (NoSuchMethodException e) {
        // all fine, no needs in copy constructors
        }
        // errors on create
        try {
            List<?> constructors = Arrays.asList(watcherClass.getDeclaredConstructors());
            Constructor<? extends Watcher> constructor = (Constructor<? extends Watcher>) constructors.get(0);
            Object[] args = new Object[constructor.getParameterCount()];
            for (int index = 0; index < constructor.getParameterTypes().length; index++) {
                Class<?> parameterType = constructor.getParameterTypes()[index];
                if (parameterType.getSimpleName().equalsIgnoreCase("boolean")) {
                    args[index] = false;
                } else {
                    args[index] = null;
                }
            }
            constructor.setAccessible(true);
            Watcher w1 = constructor.newInstance(args);
            // errors on copy
            try {
                Watcher w2 = w1.copy();
                if (w2 == null) {
                    errorsList.add("Error: can't copy watcher with unknown error, look at error logs above: " + watcherClass.getName());
                }
            } catch (Exception e) {
                errorsList.add("Error: can't copy watcher: " + watcherClass.getName() + " (" + e.getMessage() + ")");
            }
        } catch (Exception e) {
            errorsList.add("Error: can't create watcher: " + watcherClass.getName() + " (" + e.getMessage() + ")");
        }
    }
    printMessages(warningsList);
    printMessages(errorsList);
    if (errorsList.size() > 0) {
        Assert.fail("Found watcher errors: " + errorsList.size());
    }
}
Also used : Constructor(java.lang.reflect.Constructor) Watcher(mage.watchers.Watcher) Method(java.lang.reflect.Method) InvocationTargetException(java.lang.reflect.InvocationTargetException) IOException(java.io.IOException) Reflections(org.reflections.Reflections) Test(org.junit.Test)

Example 3 with Watcher

use of mage.watchers.Watcher in project mage by magefree.

the class PakoArcaneRetrieverWatcher method apply.

@Override
public boolean apply(Game game, Ability source) {
    Player controller = game.getPlayer(source.getControllerId());
    PakoArcaneRetrieverWatcher watcher = game.getState().getWatcher(PakoArcaneRetrieverWatcher.class);
    if (controller == null || watcher == null) {
        return false;
    }
    Cards cards = new CardsImpl();
    game.getState().getPlayersInRange(controller.getId(), game).stream().map(game::getPlayer).map(Player::getLibrary).map(library -> library.getFromTop(game)).forEach(cards::add);
    controller.moveCards(cards, Zone.EXILED, source, game);
    cards.removeIf(cardId -> game.getState().getZone(cardId) != Zone.EXILED);
    int counters = cards.count(StaticFilters.FILTER_CARD_NON_CREATURE, game);
    if (cards.isEmpty()) {
        return true;
    }
    cards.getCards(game).stream().filter(card -> card.addCounters(CounterType.FETCH.createInstance(), source.getControllerId(), source, game)).filter(card -> !card.isCreature(game)).forEach(card -> watcher.addCard(controller.getId(), card, game));
    Permanent permanent = game.getPermanent(source.getSourceId());
    if (permanent == null || counters == 0) {
        return true;
    }
    return permanent.addCounters(CounterType.P1P1.createInstance(counters), source.getControllerId(), source, game);
}
Also used : StaticFilters(mage.filter.StaticFilters) java.util(java.util) PartnerWithAbility(mage.abilities.keyword.PartnerWithAbility) mage.cards(mage.cards) AttacksTriggeredAbility(mage.abilities.common.AttacksTriggeredAbility) HasteAbility(mage.abilities.keyword.HasteAbility) MageObjectReference(mage.MageObjectReference) OneShotEffect(mage.abilities.effects.OneShotEffect) MageInt(mage.MageInt) Player(mage.players.Player) Game(mage.game.Game) Watcher(mage.watchers.Watcher) GameEvent(mage.game.events.GameEvent) Permanent(mage.game.permanent.Permanent) mage.constants(mage.constants) CounterType(mage.counters.CounterType) Ability(mage.abilities.Ability) Player(mage.players.Player) mage.cards(mage.cards) Permanent(mage.game.permanent.Permanent)

Example 4 with Watcher

use of mage.watchers.Watcher in project mage by magefree.

the class GameState method addAbility.

/**
 * Abilities that are applied to other objects or applied for a certain time
 * span
 *
 * @param ability
 * @param sourceId   - if source object can be moved between zones then you
 *                   must set it here (each game cycle clear all source related triggers)
 * @param attachedTo
 */
public void addAbility(Ability ability, UUID sourceId, MageObject attachedTo) {
    if (ability instanceof StaticAbility) {
        for (UUID modeId : ability.getModes().getSelectedModes()) {
            Mode mode = ability.getModes().get(modeId);
            for (Effect effect : mode.getEffects()) {
                if (effect instanceof ContinuousEffect) {
                    addEffect((ContinuousEffect) effect, sourceId, ability);
                }
            }
        }
    } else if (ability instanceof TriggeredAbility) {
        addTrigger((TriggeredAbility) ability, sourceId, attachedTo);
    }
    // Workaround to prevent ConcurrentModificationException, not clear to me why this is happening now
    List<Watcher> watcherList = new ArrayList<>(ability.getWatchers());
    for (Watcher watcher : watcherList) {
        // TODO: Check that watcher for commanderAbility (where attachedTo = null) also work correctly
        UUID controllerId = ability.getControllerId();
        if (attachedTo instanceof Card) {
            controllerId = ((Card) attachedTo).getOwnerId();
        } else if (attachedTo instanceof Controllable) {
            controllerId = ((Controllable) attachedTo).getControllerId();
        }
        watcher.setControllerId(controllerId);
        watcher.setSourceId(attachedTo == null ? ability.getSourceId() : attachedTo.getId());
        watchers.add(watcher);
    }
    for (Ability sub : ability.getSubAbilities()) {
        addAbility(sub, sourceId, attachedTo);
    }
}
Also used : Watcher(mage.watchers.Watcher) ContinuousEffect(mage.abilities.effects.ContinuousEffect) Effect(mage.abilities.effects.Effect) ContinuousEffect(mage.abilities.effects.ContinuousEffect) PermanentCard(mage.game.permanent.PermanentCard)

Example 5 with Watcher

use of mage.watchers.Watcher in project mage by magefree.

the class GameState method addDelayedTriggeredAbility.

public void addDelayedTriggeredAbility(DelayedTriggeredAbility ability) {
    this.delayed.add(ability);
    // Workaround to prevent ConcurrentModificationException, not clear to me why this is happening now
    List<Watcher> watcherList = new ArrayList<>(ability.getWatchers());
    for (Watcher watcher : watcherList) {
        watcher.setControllerId(ability.getControllerId());
        watcher.setSourceId(ability.getSourceId());
        this.watchers.add(watcher);
    }
}
Also used : Watcher(mage.watchers.Watcher)

Aggregations

Watcher (mage.watchers.Watcher)6 MageObjectReference (mage.MageObjectReference)2 Permanent (mage.game.permanent.Permanent)2 IOException (java.io.IOException)1 Constructor (java.lang.reflect.Constructor)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Method (java.lang.reflect.Method)1 java.util (java.util)1 ArrayList (java.util.ArrayList)1 MageInt (mage.MageInt)1 Ability (mage.abilities.Ability)1 AttacksTriggeredAbility (mage.abilities.common.AttacksTriggeredAbility)1 ContinuousEffect (mage.abilities.effects.ContinuousEffect)1 Effect (mage.abilities.effects.Effect)1 OneShotEffect (mage.abilities.effects.OneShotEffect)1 HasteAbility (mage.abilities.keyword.HasteAbility)1 PartnerWithAbility (mage.abilities.keyword.PartnerWithAbility)1 mage.cards (mage.cards)1 Card (mage.cards.Card)1 mage.constants (mage.constants)1