Search in sources :

Example 1 with MageSingleton

use of mage.abilities.MageSingleton in project mage by magefree.

the class ContinuousEffects method getApplicableRestrictionEffects.

public Map<RestrictionEffect, Set<Ability>> getApplicableRestrictionEffects(Permanent permanent, Game game) {
    Map<RestrictionEffect, Set<Ability>> effects = new HashMap<>();
    for (RestrictionEffect effect : restrictionEffects) {
        Set<Ability> abilities = restrictionEffects.getAbility(effect.getId());
        Set<Ability> applicableAbilities = new HashSet<>();
        for (Ability ability : abilities) {
            if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, ability instanceof MageSingleton ? permanent : null, null)) {
                if (effect.applies(permanent, ability, game)) {
                    applicableAbilities.add(ability);
                }
            }
        }
        if (!applicableAbilities.isEmpty()) {
            effects.put(effect, abilities);
        }
    }
    return effects;
}
Also used : StaticAbility(mage.abilities.StaticAbility) Ability(mage.abilities.Ability) StaticAbility(mage.abilities.StaticAbility) MageSingleton(mage.abilities.MageSingleton)

Example 2 with MageSingleton

use of mage.abilities.MageSingleton in project mage by magefree.

the class ContinuousEffects method getApplicableRequirementEffects.

public Map<RequirementEffect, Set<Ability>> getApplicableRequirementEffects(Permanent permanent, boolean playerRealted, Game game) {
    Map<RequirementEffect, Set<Ability>> effects = new HashMap<>();
    for (RequirementEffect effect : requirementEffects) {
        if (playerRealted == effect.isPlayerRelated()) {
            Set<Ability> abilities = requirementEffects.getAbility(effect.getId());
            Set<Ability> applicableAbilities = new HashSet<>();
            for (Ability ability : abilities) {
                if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, ability instanceof MageSingleton ? permanent : null, null)) {
                    if (effect.applies(permanent, ability, game)) {
                        applicableAbilities.add(ability);
                    }
                }
            }
            if (!applicableAbilities.isEmpty()) {
                effects.put(effect, abilities);
            }
        }
    }
    return effects;
}
Also used : StaticAbility(mage.abilities.StaticAbility) Ability(mage.abilities.Ability) StaticAbility(mage.abilities.StaticAbility) MageSingleton(mage.abilities.MageSingleton)

Example 3 with MageSingleton

use of mage.abilities.MageSingleton in project mage by magefree.

the class ContinuousEffectsList method isInactive.

private boolean isInactive(T effect, Game game) {
    // ends all inactive effects -- calls on player leave or apply new effect
    if (game.getState().isGameOver()) {
        // no need to remove effects after end -- users and tests must see last game state
        return false;
    }
    /*
        800.4a  When a player leaves the game, all objects (see rule 109) owned by that player leave the game and any effects
        which give that player control of any objects or players end. Then, if that player controlled any objects on the stack
        not represented by cards, those objects cease to exist. Then, if there are any objects still controlled by that player,
        those objects are exiled. This is not a state-based action. It happens as soon as the player leaves the game.
        If the player who left the game had priority at the time they left, priority passes to the next player in turn
        order who’s still in the game.
         */
    // objects removes doing in player.leave() call... effects removes is here
    Set<Ability> set = effectAbilityMap.get(effect.getId());
    if (set == null) {
        logger.debug("No abilities for effect found: " + effect.toString());
        return false;
    }
    Iterator<Ability> it = set.iterator();
    while (it.hasNext()) {
        Ability ability = it.next();
        if (ability == null) {
            it.remove();
        } else if (ability instanceof MageSingleton) {
            return false;
        } else if (effect.isDiscarded()) {
            it.remove();
        } else {
            // 800.4k  When a player leaves the game, any continuous effects with durations that last until that
            // player’s next turn or until a specific point in that turn will last until that turn would have begun.
            // They neither expire immediately nor last indefinitely.
            MageObject object = game.getObject(ability.getSourceId());
            // Commander effects have no sourceId
            boolean isObjectInGame = ability.getSourceId() == null || object != null;
            boolean hasOwnerLeftGame = false;
            if (object instanceof Card) {
                Player owner = game.getPlayer(((Card) object).getOwnerId());
                hasOwnerLeftGame = !owner.isInGame();
            }
            switch(effect.getDuration()) {
                // 
                case WhileOnBattlefield:
                case WhileInGraveyard:
                case WhileOnStack:
                case EndOfStep:
                case EndOfCombat:
                case EndOfGame:
                    // if the related source object does no longer exist in game - the effect has to be removed
                    if (hasOwnerLeftGame || !isObjectInGame) {
                        it.remove();
                    }
                    break;
                case OneUse:
                    if (hasOwnerLeftGame || effect.isUsed()) {
                        it.remove();
                    }
                    break;
                case Custom:
                case UntilYourNextTurn:
                case UntilEndOfYourNextTurn:
                    // 800.4a (only any effects which give that player control of any objects or players end)
                    if (effect.isInactive(ability, game)) {
                        it.remove();
                    }
                    break;
                case EndOfTurn:
                    // 514.2
                    break;
                case UntilSourceLeavesBattlefield:
                    if (hasOwnerLeftGame || game.getState().getZone(ability.getSourceId()) != Zone.BATTLEFIELD) {
                        it.remove();
                    }
                    break;
                case WhileControlled:
                    Permanent permanent = ability.getSourcePermanentIfItStillExists(game);
                    if (hasOwnerLeftGame || permanent == null || !permanent.isControlledBy(ability.getControllerId())) {
                        it.remove();
                    }
                    break;
                default:
                    throw new IllegalStateException("Effects gets unknown duration " + effect.getDuration() + ", effect: " + effect.toString());
            }
        }
    }
    return set.isEmpty();
}
Also used : Ability(mage.abilities.Ability) Player(mage.players.Player) Permanent(mage.game.permanent.Permanent) MageObject(mage.MageObject) MageSingleton(mage.abilities.MageSingleton) Card(mage.cards.Card)

Example 4 with MageSingleton

use of mage.abilities.MageSingleton in project mage by magefree.

the class ContinuousEffects method traceAddContinuousEffects.

public static void traceAddContinuousEffects(Map orderedEffects, ContinuousEffectsList<?> cel, Game game, String listName) {
    for (ContinuousEffect effect : cel) {
        Set<Ability> abilities = cel.getAbility(effect.getId());
        for (Ability ability : abilities) {
            Player controller = game.getPlayer(ability.getControllerId());
            MageObject source = game.getObject(ability.getSourceId());
            TraceInfo traceInfo = new TraceInfo();
            traceInfo.setInfo(listName);
            traceInfo.setOrder(effect.getOrder());
            if (ability instanceof MageSingleton) {
                traceInfo.setPlayerName("Mage Singleton");
                traceInfo.setSourceName("Mage Singleton");
            } else {
                traceInfo.setPlayerName(controller == null ? "no controller" : controller.getName());
                traceInfo.setSourceName(source == null ? "no source" : source.getIdName());
            }
            traceInfo.setRule(ability.getRule());
            traceInfo.setAbilityId(ability.getId());
            traceInfo.setEffectId(effect.getId());
            traceInfo.setDuration(effect.getDuration());
            orderedEffects.put(traceInfo.getPlayerName() + traceInfo.getSourceName() + effect.getId() + ability.getId(), traceInfo);
        }
    }
}
Also used : StaticAbility(mage.abilities.StaticAbility) Ability(mage.abilities.Ability) Player(mage.players.Player) MageObject(mage.MageObject) MageSingleton(mage.abilities.MageSingleton) TraceInfo(mage.util.trace.TraceInfo)

Aggregations

Ability (mage.abilities.Ability)4 MageSingleton (mage.abilities.MageSingleton)4 StaticAbility (mage.abilities.StaticAbility)3 MageObject (mage.MageObject)2 Player (mage.players.Player)2 Card (mage.cards.Card)1 Permanent (mage.game.permanent.Permanent)1 TraceInfo (mage.util.trace.TraceInfo)1