Search in sources :

Example 16 with PermanentIdPredicate

use of mage.filter.predicate.permanent.PermanentIdPredicate in project mage by magefree.

the class LastOneStandingEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    List<Permanent> creatureList = game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game);
    if (creatureList.size() < 2) {
        return true;
    }
    int toSave = RandomUtil.nextInt(creatureList.size());
    FilterCreaturePermanent filter = new FilterCreaturePermanent();
    filter.add(Predicates.not(new PermanentIdPredicate(creatureList.get(toSave).getId())));
    return new DestroyAllEffect(filter).apply(game, source);
}
Also used : PermanentIdPredicate(mage.filter.predicate.permanent.PermanentIdPredicate) FilterCreaturePermanent(mage.filter.common.FilterCreaturePermanent) Permanent(mage.game.permanent.Permanent) FilterCreaturePermanent(mage.filter.common.FilterCreaturePermanent) DestroyAllEffect(mage.abilities.effects.common.DestroyAllEffect)

Example 17 with PermanentIdPredicate

use of mage.filter.predicate.permanent.PermanentIdPredicate in project mage by magefree.

the class MirrorWeaveEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Player controller = game.getPlayer(source.getControllerId());
    FilterCreaturePermanent filter = new FilterCreaturePermanent();
    if (controller != null) {
        Permanent copyFromCreature = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
        if (copyFromCreature != null) {
            filter.add(Predicates.not(new PermanentIdPredicate(copyFromCreature.getId())));
            for (Permanent copyToCreature : game.getBattlefield().getAllActivePermanents(filter, game)) {
                if (copyToCreature != null) {
                    game.copyPermanent(Duration.EndOfTurn, copyFromCreature, copyToCreature.getId(), source, new EmptyCopyApplier());
                }
            }
        }
        return true;
    }
    return false;
}
Also used : PermanentIdPredicate(mage.filter.predicate.permanent.PermanentIdPredicate) Player(mage.players.Player) FilterCreaturePermanent(mage.filter.common.FilterCreaturePermanent) Permanent(mage.game.permanent.Permanent) FilterCreaturePermanent(mage.filter.common.FilterCreaturePermanent) TargetPermanent(mage.target.TargetPermanent) EmptyCopyApplier(mage.util.functions.EmptyCopyApplier)

Example 18 with PermanentIdPredicate

use of mage.filter.predicate.permanent.PermanentIdPredicate in project mage by magefree.

the class PlayerImpl method untap.

@Override
public void untap(Game game) {
    // create list of all "notMoreThan" effects to track which one are consumed
    Map<Entry<RestrictionUntapNotMoreThanEffect, Set<Ability>>, Integer> notMoreThanEffectsUsage = new HashMap<>();
    for (Entry<RestrictionUntapNotMoreThanEffect, Set<Ability>> restrictionEffect : game.getContinuousEffects().getApplicableRestrictionUntapNotMoreThanEffects(this, game).entrySet()) {
        notMoreThanEffectsUsage.put(restrictionEffect, restrictionEffect.getKey().getNumber());
    }
    if (!notMoreThanEffectsUsage.isEmpty()) {
        // create list of all permanents that can be untapped generally
        List<Permanent> canBeUntapped = new ArrayList<>();
        for (Permanent permanent : game.getBattlefield().getAllActivePermanents(playerId)) {
            boolean untap = true;
            for (RestrictionEffect effect : game.getContinuousEffects().getApplicableRestrictionEffects(permanent, game).keySet()) {
                untap &= effect.canBeUntapped(permanent, null, game, true);
            }
            if (untap) {
                canBeUntapped.add(permanent);
            }
        }
        // selected permanents to untap
        List<Permanent> selectedToUntap = new ArrayList<>();
        // player can cancel the selection of an effect to use a preferred order of restriction effects
        boolean playerCanceledSelection;
        do {
            playerCanceledSelection = false;
            // select permanents to untap to consume the "notMoreThan" effects
            for (Map.Entry<Entry<RestrictionUntapNotMoreThanEffect, Set<Ability>>, Integer> handledEntry : notMoreThanEffectsUsage.entrySet()) {
                // select a permanent to untap for this entry
                int numberToUntap = handledEntry.getValue();
                if (numberToUntap > 0) {
                    List<Permanent> leftForUntap = getPermanentsThatCanBeUntapped(game, canBeUntapped, handledEntry.getKey().getKey(), notMoreThanEffectsUsage);
                    FilterControlledPermanent filter = handledEntry.getKey().getKey().getFilter().copy();
                    String message = filter.getMessage();
                    // omit already from other untap effects selected permanents
                    for (Permanent permanent : selectedToUntap) {
                        filter.add(Predicates.not(new PermanentIdPredicate(permanent.getId())));
                    }
                    // while targets left and there is still allowed to untap
                    while (canRespond() && !leftForUntap.isEmpty() && numberToUntap > 0) {
                        // player has to select the permanent they want to untap for this restriction
                        Ability ability = handledEntry.getKey().getValue().iterator().next();
                        if (ability != null) {
                            StringBuilder sb = new StringBuilder(message).append(" to untap").append(" (").append(Math.min(leftForUntap.size(), numberToUntap)).append(" in total");
                            MageObject effectSource = game.getObject(ability.getSourceId());
                            if (effectSource != null) {
                                sb.append(" from ").append(effectSource.getLogName());
                            }
                            sb.append(')');
                            filter.setMessage(sb.toString());
                            Target target = new TargetPermanent(1, 1, filter, true);
                            if (!this.chooseTarget(Outcome.Untap, target, ability, game)) {
                                // player canceled, go on with the next effect (if no other effect available, this effect will be active again)
                                playerCanceledSelection = true;
                                break;
                            }
                            Permanent selectedPermanent = game.getPermanent(target.getFirstTarget());
                            if (leftForUntap.contains(selectedPermanent)) {
                                selectedToUntap.add(selectedPermanent);
                                numberToUntap--;
                                // don't allow to select same permanent twice
                                filter.add(Predicates.not(new PermanentIdPredicate(selectedPermanent.getId())));
                                // reduce available untap numbers from other "UntapNotMoreThan" effects if selected permanent applies to their filter too
                                for (Entry<Entry<RestrictionUntapNotMoreThanEffect, Set<Ability>>, Integer> notMoreThanEffect : notMoreThanEffectsUsage.entrySet()) {
                                    if (notMoreThanEffect.getValue() > 0 && notMoreThanEffect.getKey().getKey().getFilter().match(selectedPermanent, game)) {
                                        notMoreThanEffect.setValue(notMoreThanEffect.getValue() - 1);
                                    }
                                }
                                // update the left for untap list
                                leftForUntap = getPermanentsThatCanBeUntapped(game, canBeUntapped, handledEntry.getKey().getKey(), notMoreThanEffectsUsage);
                                // remove already selected permanents
                                for (Permanent permanent : selectedToUntap) {
                                    leftForUntap.remove(permanent);
                                }
                            } else {
                                // player selected an permanent that is restricted by another effect, disallow it (so AI can select another one)
                                filter.add(Predicates.not(new PermanentIdPredicate(selectedPermanent.getId())));
                                if (this.isHuman() && !game.isSimulation()) {
                                    game.informPlayer(this, "This permanent can't be untapped because of other restricting effect.");
                                }
                            }
                        }
                    }
                }
            }
        } while (canRespond() && playerCanceledSelection);
        if (!game.isSimulation()) {
            // show in log which permanents were selected to untap
            for (Permanent permanent : selectedToUntap) {
                game.informPlayers(this.getLogName() + " untapped " + permanent.getLogName());
            }
        }
        // untap if permanent is not concerned by notMoreThan effects or is included in the selectedToUntapList
        for (Permanent permanent : canBeUntapped) {
            boolean doUntap = true;
            if (!selectedToUntap.contains(permanent)) {
                // if the permanent is covered by one of the restriction effects, don't untap it
                for (Entry<Entry<RestrictionUntapNotMoreThanEffect, Set<Ability>>, Integer> notMoreThanEffect : notMoreThanEffectsUsage.entrySet()) {
                    if (notMoreThanEffect.getKey().getKey().getFilter().match(permanent, game)) {
                        doUntap = false;
                        break;
                    }
                }
            }
            if (permanent != null && doUntap) {
                permanent.untap(game);
            }
        }
    } else {
        for (Permanent permanent : game.getBattlefield().getAllActivePermanents(playerId)) {
            boolean untap = true;
            for (RestrictionEffect effect : game.getContinuousEffects().getApplicableRestrictionEffects(permanent, game).keySet()) {
                untap &= effect.canBeUntapped(permanent, null, game, true);
            }
            if (untap) {
                permanent.untap(game);
            }
        }
    }
}
Also used : AlternateManaPaymentAbility(mage.abilities.costs.mana.AlternateManaPaymentAbility) StackAbility(mage.game.stack.StackAbility) WhileSearchingPlayFromLibraryAbility(mage.abilities.common.WhileSearchingPlayFromLibraryAbility) AtTheEndOfTurnStepPostDelayedTriggeredAbility(mage.abilities.common.delayed.AtTheEndOfTurnStepPostDelayedTriggeredAbility) PassAbility(mage.abilities.common.PassAbility) PlayLandAsCommanderAbility(mage.abilities.common.PlayLandAsCommanderAbility) PermanentIdPredicate(mage.filter.predicate.permanent.PermanentIdPredicate) Permanent(mage.game.permanent.Permanent) FilterPermanent(mage.filter.FilterPermanent) FilterControlledPermanent(mage.filter.common.FilterControlledPermanent) TargetPermanent(mage.target.TargetPermanent) FilterControlledPermanent(mage.filter.common.FilterControlledPermanent) RestrictionUntapNotMoreThanEffect(mage.abilities.effects.RestrictionUntapNotMoreThanEffect) Entry(java.util.Map.Entry) Target(mage.target.Target) TargetPermanent(mage.target.TargetPermanent) RestrictionEffect(mage.abilities.effects.RestrictionEffect) ImmutableMap(com.google.common.collect.ImmutableMap)

Example 19 with PermanentIdPredicate

use of mage.filter.predicate.permanent.PermanentIdPredicate in project mage by magefree.

the class Combat method handleBanding.

private void handleBanding(UUID creatureId, Game game) {
    Player player = game.getPlayer(attackingPlayerId);
    Permanent attacker = game.getPermanent(creatureId);
    if (attacker == null || player == null) {
        return;
    }
    CombatGroup combatGroup = findGroup(attacker.getId());
    if (combatGroup == null || !attacker.getBandedCards().isEmpty() || getAttackers().size() <= 1) {
        return;
    }
    boolean canBand = attacker.hasAbility(BandingAbility.getInstance(), game);
    List<Ability> bandsWithOther = new ArrayList<>();
    for (Ability ability : attacker.getAbilities()) {
        if (ability.getClass().equals(BandsWithOtherAbility.class)) {
            bandsWithOther.add(ability);
        }
    }
    boolean canBandWithOther = !bandsWithOther.isEmpty();
    if (!canBand && !canBandWithOther) {
        return;
    }
    boolean isBanded = false;
    FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("attacking creature to band with " + attacker.getLogName());
    filter.add(Predicates.not(new PermanentIdPredicate(creatureId)));
    // creature that isn't already banded, and is attacking the same player or planeswalker
    filter.add(new AttackingSameNotBandedPredicate(combatGroup.getDefenderId()));
    List<Predicate<MageObject>> predicates = new ArrayList<>();
    if (!canBand && canBandWithOther) {
        for (Ability ab : bandsWithOther) {
            BandsWithOtherAbility ability = (BandsWithOtherAbility) ab;
            if (ability.getSubtype() != null) {
                predicates.add(ability.getSubtype().getPredicate());
            }
            if (ability.getSupertype() != null) {
                predicates.add(ability.getSupertype().getPredicate());
            }
            if (ability.getName() != null) {
                predicates.add(new NamePredicate(ability.getName()));
            }
        }
        filter.add(Predicates.or(predicates));
    }
    while (player.canRespond()) {
        TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true);
        target.setRequired(false);
        canBand &= target.canChoose(attackingPlayerId, game);
        canBandWithOther &= target.canChoose(attackingPlayerId, game);
        if (game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_ATTACKERS, attackingPlayerId, attackingPlayerId)) || (!canBand && !canBandWithOther) || !player.chooseUse(Outcome.Benefit, (isBanded ? "Band " + attacker.getLogName() + " with another " : "Form a band with " + attacker.getLogName() + " and an ") + "attacking creature?", null, game)) {
            break;
        }
        if (canBand && canBandWithOther) {
            if (player.chooseUse(Outcome.Detriment, "Choose type of banding ability to apply:", attacker.getLogName(), "Banding", "Bands with other", null, game)) {
                canBandWithOther = false;
            } else {
                canBand = false;
                for (Ability ab : bandsWithOther) {
                    BandsWithOtherAbility ability = (BandsWithOtherAbility) ab;
                    if (ability.getSubtype() != null) {
                        predicates.add(ability.getSubtype().getPredicate());
                    }
                    if (ability.getSupertype() != null) {
                        predicates.add(ability.getSupertype().getPredicate());
                    }
                    if (ability.getName() != null) {
                        predicates.add(new NamePredicate(ability.getName()));
                    }
                }
                filter.add(Predicates.or(predicates));
            }
        }
        if (target.choose(Outcome.Benefit, attackingPlayerId, null, game)) {
            isBanded = true;
            for (UUID targetId : target.getTargets()) {
                Permanent permanent = game.getPermanent(targetId);
                if (permanent != null) {
                    for (UUID bandedId : attacker.getBandedCards()) {
                        permanent.addBandedCard(bandedId);
                        Permanent banded = game.getPermanent(bandedId);
                        if (banded != null) {
                            banded.addBandedCard(targetId);
                        }
                    }
                    permanent.addBandedCard(creatureId);
                    attacker.addBandedCard(targetId);
                    if (canBand) {
                        if (!permanent.hasAbility(BandingAbility.getInstance(), game)) {
                            filter.add(new AbilityPredicate(BandingAbility.class));
                            canBandWithOther = false;
                        }
                    } else if (canBandWithOther) {
                        List<Predicate<MageObject>> newPredicates = new ArrayList<>();
                        for (Predicate<MageObject> predicate : predicates) {
                            if (predicate.apply(permanent, game)) {
                                newPredicates.add(predicate);
                            }
                        }
                        filter.add(Predicates.or(newPredicates));
                        canBand = false;
                    }
                }
            }
        }
    }
    if (!isBanded) {
        return;
    }
    StringBuilder sb = new StringBuilder(player.getLogName()).append(" formed a band with ").append(attacker.getBandedCards().size()).append(1).append(" creatures: ");
    sb.append(attacker.getLogName());
    for (UUID id : attacker.getBandedCards()) {
        sb.append(", ");
        Permanent permanent = game.getPermanent(id);
        if (permanent != null) {
            sb.append(permanent.getLogName());
        }
    }
    game.informPlayers(sb.toString());
}
Also used : JohanVigilanceAbility(mage.abilities.keyword.special.JohanVigilanceAbility) VigilanceAbility(mage.abilities.keyword.VigilanceAbility) BandingAbility(mage.abilities.keyword.BandingAbility) BandsWithOtherAbility(mage.abilities.keyword.BandsWithOtherAbility) Ability(mage.abilities.Ability) PermanentIdPredicate(mage.filter.predicate.permanent.PermanentIdPredicate) Player(mage.players.Player) AttackingSameNotBandedPredicate(mage.filter.predicate.permanent.AttackingSameNotBandedPredicate) NamePredicate(mage.filter.predicate.mageobject.NamePredicate) FilterControlledCreaturePermanent(mage.filter.common.FilterControlledCreaturePermanent) FilterCreaturePermanent(mage.filter.common.FilterCreaturePermanent) Permanent(mage.game.permanent.Permanent) TargetControlledPermanent(mage.target.common.TargetControlledPermanent) FilterControlledCreaturePermanent(mage.filter.common.FilterControlledCreaturePermanent) MageObject(mage.MageObject) PermanentIdPredicate(mage.filter.predicate.permanent.PermanentIdPredicate) Predicate(mage.filter.predicate.Predicate) AttackingSameNotBandedPredicate(mage.filter.predicate.permanent.AttackingSameNotBandedPredicate) NamePredicate(mage.filter.predicate.mageobject.NamePredicate) AbilityPredicate(mage.filter.predicate.mageobject.AbilityPredicate) TargetControlledPermanent(mage.target.common.TargetControlledPermanent) BandingAbility(mage.abilities.keyword.BandingAbility) BandsWithOtherAbility(mage.abilities.keyword.BandsWithOtherAbility) PlayerList(mage.players.PlayerList) AbilityPredicate(mage.filter.predicate.mageobject.AbilityPredicate)

Example 20 with PermanentIdPredicate

use of mage.filter.predicate.permanent.PermanentIdPredicate in project mage by magefree.

the class FlamesOfTheRazeBoarEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Permanent permanent = game.getPermanent(source.getFirstTarget());
    if (permanent == null) {
        return false;
    }
    permanent.damage(4, source.getSourceId(), source, game);
    if (!FerociousCondition.instance.apply(game, source)) {
        return true;
    }
    FilterPermanent filter = new FilterCreaturePermanent();
    filter.add(new ControllerIdPredicate(permanent.getControllerId()));
    filter.add(Predicates.not(new PermanentIdPredicate(permanent.getId())));
    return new DamageAllEffect(2, filter).apply(game, source);
}
Also used : PermanentIdPredicate(mage.filter.predicate.permanent.PermanentIdPredicate) FilterPermanent(mage.filter.FilterPermanent) FilterCreaturePermanent(mage.filter.common.FilterCreaturePermanent) FilterPermanent(mage.filter.FilterPermanent) TargetOpponentsCreaturePermanent(mage.target.common.TargetOpponentsCreaturePermanent) Permanent(mage.game.permanent.Permanent) FilterCreaturePermanent(mage.filter.common.FilterCreaturePermanent) ControllerIdPredicate(mage.filter.predicate.permanent.ControllerIdPredicate) DamageAllEffect(mage.abilities.effects.common.DamageAllEffect)

Aggregations

PermanentIdPredicate (mage.filter.predicate.permanent.PermanentIdPredicate)45 Permanent (mage.game.permanent.Permanent)38 Player (mage.players.Player)26 FilterCreaturePermanent (mage.filter.common.FilterCreaturePermanent)24 FilterPermanent (mage.filter.FilterPermanent)19 TargetPermanent (mage.target.TargetPermanent)19 Target (mage.target.Target)17 TargetCreaturePermanent (mage.target.common.TargetCreaturePermanent)17 UUID (java.util.UUID)14 NamePredicate (mage.filter.predicate.mageobject.NamePredicate)9 ControllerIdPredicate (mage.filter.predicate.permanent.ControllerIdPredicate)7 FilterControlledCreaturePermanent (mage.filter.common.FilterControlledCreaturePermanent)5 FilterControlledPermanent (mage.filter.common.FilterControlledPermanent)5 MageObject (mage.MageObject)4 Predicate (mage.filter.predicate.Predicate)4 ContinuousEffect (mage.abilities.effects.ContinuousEffect)3 BecomesFaceDownCreatureAllEffect (mage.abilities.effects.common.continuous.BecomesFaceDownCreatureAllEffect)3 BoostAllEffect (mage.abilities.effects.common.continuous.BoostAllEffect)3 AbilityPredicate (mage.filter.predicate.mageobject.AbilityPredicate)3 ArrayList (java.util.ArrayList)2