Search in sources :

Example 21 with ActivatedManaAbilityImpl

use of mage.abilities.mana.ActivatedManaAbilityImpl in project mage by magefree.

the class MageObjectImpl method getFrameColor.

@Override
public ObjectColor getFrameColor(Game game) {
    // its frame colors while game is active to represent ability changes during the game.
    if (this.isLand(game) && !(this instanceof MockCard)) {
        ObjectColor cl = frameColor.copy();
        Set<ManaType> manaTypes = EnumSet.noneOf(ManaType.class);
        for (Ability ab : getAbilities()) {
            if (ab instanceof ActivatedManaAbilityImpl) {
                manaTypes.addAll(((ActivatedManaAbilityImpl) ab).getProducableManaTypes(game));
            }
        }
        cl.setWhite(manaTypes.contains(ManaType.WHITE));
        cl.setBlue(manaTypes.contains(ManaType.BLUE));
        cl.setBlack(manaTypes.contains(ManaType.BLACK));
        cl.setRed(manaTypes.contains(ManaType.RED));
        cl.setGreen(manaTypes.contains(ManaType.GREEN));
        return cl;
    } else {
        // For everything else, just return the frame colors
        return frameColor;
    }
}
Also used : Ability(mage.abilities.Ability) ActivatedManaAbilityImpl(mage.abilities.mana.ActivatedManaAbilityImpl) MockCard(mage.cards.mock.MockCard)

Example 22 with ActivatedManaAbilityImpl

use of mage.abilities.mana.ActivatedManaAbilityImpl in project mage by magefree.

the class TestPlayer method priority.

@Override
public boolean priority(Game game) {
    // later remove actions (ai commands related)
    if (actionsToRemoveLater.size() > 0) {
        List<PlayerAction> removed = new ArrayList<>();
        actionsToRemoveLater.forEach((action, step) -> {
            if (game.getStep().getType() != step) {
                action.onActionRemovedLater(game, this);
                actions.remove(action);
                removed.add(action);
            }
        });
        removed.forEach(actionsToRemoveLater::remove);
    }
    // fake test ability for triggers and events
    Ability source = new SimpleStaticAbility(Zone.OUTSIDE, new InfoEffect("adding testing cards"));
    source.setControllerId(this.getId());
    int numberOfActions = actions.size();
    List<PlayerAction> tempActions = new ArrayList<>();
    tempActions.addAll(actions);
    for (PlayerAction action : tempActions) {
        if (action.getTurnNum() == game.getTurnNum() && action.getStep() == game.getStep().getType()) {
            if (action.getAction().startsWith(ACTIVATE_ABILITY)) {
                String command = action.getAction();
                command = command.substring(command.indexOf(ACTIVATE_ABILITY) + ACTIVATE_ABILITY.length());
                groupsForTargetHandling = null;
                String[] groups = command.split("\\$");
                if (groups.length > 2 && !checkExecuteCondition(groups, game)) {
                    break;
                }
                // must process all duplicated abilities (aliases need objects to search)
                for (ActivatedAbility ability : computerPlayer.getPlayable(game, true, Zone.ALL, false)) {
                    // add wrong action log?
                    if (hasAbilityTargetNameOrAlias(game, ability, groups[0])) {
                        int bookmark = game.bookmarkState();
                        ActivatedAbility newAbility = ability.copy();
                        if (groups.length > 1 && !groups[1].equals("target=" + NO_TARGET)) {
                            groupsForTargetHandling = groups;
                        }
                        if (computerPlayer.activateAbility(newAbility, game)) {
                            actions.remove(action);
                            groupsForTargetHandling = null;
                            // Reset enless loop check because of no action
                            foundNoAction = 0;
                            return true;
                        } else {
                            computerPlayer.restoreState(bookmark, ability.getRule(), game);
                            // skip failed command
                            if (!choices.isEmpty() && choices.get(0).equals(SKIP_FAILED_COMMAND)) {
                                actions.remove(action);
                                choices.remove(0);
                                return true;
                            }
                        }
                        groupsForTargetHandling = null;
                    }
                }
            // TODO: fix wrong commands (on non existing card), it's HUGE (350+ failed tests with wrong commands)
            // Assert.fail("Can't find ability to activate command: " + command);
            } else if (action.getAction().startsWith(ACTIVATE_MANA)) {
                String command = action.getAction();
                command = command.substring(command.indexOf(ACTIVATE_MANA) + ACTIVATE_MANA.length());
                String[] groups = command.split("\\$");
                List<MageObject> manaObjects = computerPlayer.getAvailableManaProducers(game);
                for (MageObject mageObject : manaObjects) {
                    if (mageObject instanceof Permanent) {
                        for (Ability manaAbility : ((Permanent) mageObject).getAbilities(game).getAvailableActivatedManaAbilities(Zone.BATTLEFIELD, getId(), game)) {
                            if (hasAbilityTargetNameOrAlias(game, manaAbility, groups[0])) {
                                Ability newManaAbility = manaAbility.copy();
                                computerPlayer.activateAbility((ActivatedAbility) newManaAbility, game);
                                actions.remove(action);
                                return true;
                            }
                        }
                    } else if (mageObject instanceof Card) {
                        for (Ability manaAbility : ((Card) mageObject).getAbilities(game).getAvailableActivatedManaAbilities(game.getState().getZone(mageObject.getId()), getId(), game)) {
                            if (hasAbilityTargetNameOrAlias(game, manaAbility, groups[0])) {
                                Ability newManaAbility = manaAbility.copy();
                                computerPlayer.activateAbility((ActivatedAbility) newManaAbility, game);
                                actions.remove(action);
                                return true;
                            }
                        }
                    } else {
                        for (Ability manaAbility : mageObject.getAbilities().getAvailableActivatedManaAbilities(game.getState().getZone(mageObject.getId()), getId(), game)) {
                            if (hasAbilityTargetNameOrAlias(game, manaAbility, groups[0])) {
                                Ability newManaAbility = manaAbility.copy();
                                computerPlayer.activateAbility((ActivatedAbility) newManaAbility, game);
                                actions.remove(action);
                                return true;
                            }
                        }
                    }
                }
                List<Permanent> manaPermsWithCost = computerPlayer.getAvailableManaProducersWithCost(game);
                for (Permanent perm : manaPermsWithCost) {
                    for (ActivatedManaAbilityImpl manaAbility : perm.getAbilities().getAvailableActivatedManaAbilities(Zone.BATTLEFIELD, getId(), game)) {
                        if (hasAbilityTargetNameOrAlias(game, manaAbility, groups[0]) && manaAbility.canActivate(computerPlayer.getId(), game).canActivate()) {
                            Ability newManaAbility = manaAbility.copy();
                            computerPlayer.activateAbility((ActivatedAbility) newManaAbility, game);
                            actions.remove(action);
                            return true;
                        }
                    }
                }
            } else if (action.getAction().startsWith("addCounters:")) {
                String command = action.getAction();
                command = command.substring(command.indexOf("addCounters:") + 12);
                String[] groups = command.split("\\$");
                for (Permanent permanent : game.getBattlefield().getAllActivePermanents()) {
                    if (hasObjectTargetNameOrAlias(permanent, groups[0])) {
                        CounterType counterType = CounterType.findByName(groups[1]);
                        Assert.assertNotNull("Invalid counter type " + groups[1], counterType);
                        Counter counter = counterType.createInstance(Integer.parseInt(groups[2]));
                        permanent.addCounters(counter, source.getControllerId(), source, game);
                        actions.remove(action);
                        return true;
                    }
                }
            } else if (action.getAction().startsWith("waitStackResolved")) {
                boolean skipOneStackObjectOnly = action.getAction().equals("waitStackResolved:1");
                if (game.getStack().isEmpty()) {
                    // all done, can use next command
                    actions.remove(action);
                    continue;
                } else {
                    // need to wait (don't remove command, except one skip only)
                    tryToPlayPriority(game);
                    if (skipOneStackObjectOnly) {
                        actions.remove(action);
                    }
                    return true;
                }
            } else if (action.getAction().startsWith("playerAction:")) {
                String command = action.getAction();
                command = command.substring(command.indexOf("playerAction:") + 13);
                groupsForTargetHandling = null;
                String[] groups = command.split("\\$");
                if (groups.length > 0) {
                    if (groups[0].equals("Rollback")) {
                        if (groups.length > 2 && groups[1].startsWith("turns=") && groups[2].startsWith("rollbackBlock=")) {
                            int turns = Integer.parseInt(groups[1].substring(6));
                            int rollbackBlockNumber = Integer.parseInt(groups[2].substring(14));
                            game.rollbackTurns(turns);
                            actions.remove(action);
                            addActionsAfterRollback(game, rollbackBlockNumber);
                            return true;
                        } else {
                            Assert.fail("Rollback command misses parameter: " + command);
                        }
                    }
                    if (groups[0].equals("Concede")) {
                        game.concede(getId());
                        ((GameImpl) game).checkConcede();
                        actions.remove(action);
                        return true;
                    }
                }
            } else if (action.getAction().startsWith(AI_PREFIX)) {
                String command = action.getAction();
                command = command.substring(command.indexOf(AI_PREFIX) + AI_PREFIX.length());
                // play priority
                if (command.equals(AI_COMMAND_PLAY_PRIORITY)) {
                    // disable on action's remove
                    AIRealGameSimulation = true;
                    computerPlayer.priority(game);
                    actions.remove(action);
                    return true;
                }
                // play step
                if (command.equals(AI_COMMAND_PLAY_STEP)) {
                    // disable on action's remove
                    AIRealGameSimulation = true;
                    actionsToRemoveLater.put(action, game.getStep().getType());
                    computerPlayer.priority(game);
                    return true;
                }
                Assert.fail("Unknown ai command: " + command);
            } else if (action.getAction().startsWith(RUN_PREFIX)) {
                String command = action.getAction();
                command = command.substring(command.indexOf(RUN_PREFIX) + RUN_PREFIX.length());
                // custom code execute
                if (command.equals(RUN_COMMAND_CODE)) {
                    action.getCodePayload().run(action.getActionName(), computerPlayer, game);
                    actions.remove(action);
                    return true;
                }
                Assert.fail("Unknown run command: " + command);
            } else if (action.getAction().startsWith(CHECK_PREFIX)) {
                String command = action.getAction();
                command = command.substring(command.indexOf(CHECK_PREFIX) + CHECK_PREFIX.length());
                String[] params = command.split(CHECK_PARAM_DELIMETER);
                boolean wasProccessed = false;
                if (params.length > 0) {
                    // check PT: card name, P, T
                    if (params[0].equals(CHECK_COMMAND_PT) && params.length == 4) {
                        assertPT(action, game, computerPlayer, params[1], Integer.parseInt(params[2]), Integer.parseInt(params[3]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check damage: card name, damage
                    if (params[0].equals(CHECK_COMMAND_DAMAGE) && params.length == 3) {
                        assertDamage(action, game, computerPlayer, params[1], Integer.parseInt(params[2]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check life: life
                    if (params[0].equals(CHECK_COMMAND_LIFE) && params.length == 2) {
                        assertLife(action, game, computerPlayer, Integer.parseInt(params[1]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check player in game: target player, must be in game
                    if (params[0].equals(CHECK_COMMAND_PLAYER_IN_GAME) && params.length == 3) {
                        assertPlayerInGame(action, game, game.getPlayer(UUID.fromString(params[1])), Boolean.parseBoolean(params[2]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check ability: card name, ability class, must have
                    if (params[0].equals(CHECK_COMMAND_ABILITY) && params.length == 4) {
                        assertAbility(action, game, computerPlayer, params[1], params[2], Boolean.parseBoolean(params[3]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check playable ability: ability text, must have
                    if (params[0].equals(CHECK_COMMAND_PLAYABLE_ABILITY) && params.length == 3) {
                        assertPlayableAbility(action, game, computerPlayer, params[1], Boolean.parseBoolean(params[2]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check battlefield count: target player, card name, count
                    if (params[0].equals(CHECK_COMMAND_PERMANENT_COUNT) && params.length == 4) {
                        assertPermanentCount(action, game, game.getPlayer(UUID.fromString(params[1])), params[2], Integer.parseInt(params[3]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check permanent tapped count: target player, card name, tapped status, count
                    if (params[0].equals(CHECK_COMMAND_PERMANENT_TAPPED) && params.length == 5) {
                        assertPermanentTapped(action, game, game.getPlayer(UUID.fromString(params[1])), params[2], Boolean.parseBoolean(params[3]), Integer.parseInt(params[4]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check permanent counters: card name, counter type, count
                    if (params[0].equals(CHECK_COMMAND_PERMANENT_COUNTERS) && params.length == 4) {
                        assertPermanentCounters(action, game, computerPlayer, params[1], CounterType.findByName(params[2]), Integer.parseInt(params[3]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check card counters: card name, counter type, count
                    if (params[0].equals(CHECK_COMMAND_CARD_COUNTERS) && params.length == 4) {
                        assertCardCounters(action, game, computerPlayer, params[1], CounterType.findByName(params[2]), Integer.parseInt(params[3]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check exile count: card name, count
                    if (params[0].equals(CHECK_COMMAND_EXILE_COUNT) && params.length == 3) {
                        assertExileCount(action, game, params[1], Integer.parseInt(params[2]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check graveyard count: card name, count
                    if (params[0].equals(CHECK_COMMAND_GRAVEYARD_COUNT) && params.length == 3) {
                        assertGraveyardCount(action, game, computerPlayer, params[1], Integer.parseInt(params[2]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check library count: card name, count
                    if (params[0].equals(CHECK_COMMAND_LIBRARY_COUNT) && params.length == 3) {
                        assertLibraryCount(action, game, computerPlayer, params[1], Integer.parseInt(params[2]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check hand count: count
                    if (params[0].equals(CHECK_COMMAND_HAND_COUNT) && params.length == 2) {
                        assertHandCount(action, game, computerPlayer, Integer.parseInt(params[1]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check hand card count: card name, count
                    if (params[0].equals(CHECK_COMMAND_HAND_CARD_COUNT) && params.length == 3) {
                        assertHandCardCount(action, game, computerPlayer, params[1], Integer.parseInt(params[2]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check command card count: card name, count
                    if (params[0].equals(CHECK_COMMAND_COMMAND_CARD_COUNT) && params.length == 3) {
                        assertCommandCardCount(action, game, computerPlayer, params[1], Integer.parseInt(params[2]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check color: card name, colors, must have
                    if (params[0].equals(CHECK_COMMAND_COLOR) && params.length == 4) {
                        assertColor(action, game, computerPlayer, params[1], params[2], Boolean.parseBoolean(params[3]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check type: card name, type, must have
                    if (params[0].equals(CHECK_COMMAND_TYPE) && params.length == 4) {
                        assertType(action, game, computerPlayer, params[1], CardType.fromString(params[2]), Boolean.parseBoolean(params[3]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check subtype: card name, subtype, must have
                    if (params[0].equals(CHECK_COMMAND_SUBTYPE) && params.length == 4) {
                        assertSubType(action, game, computerPlayer, params[1], SubType.fromString(params[2]), Boolean.parseBoolean(params[3]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check mana pool: colors, amount
                    if (params[0].equals(CHECK_COMMAND_MANA_POOL) && params.length == 3) {
                        assertManaPool(action, game, computerPlayer, params[1], Integer.parseInt(params[2]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check alias at zone: alias name, zone, must have (only for TestPlayer)
                    if (params[0].equals(CHECK_COMMAND_ALIAS_ZONE) && params.length == 4) {
                        assertAliasZone(action, game, this, params[1], Zone.valueOf(params[2]), Boolean.parseBoolean(params[3]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check stack size: need size
                    if (params[0].equals(CHECK_COMMAND_STACK_SIZE) && params.length == 2) {
                        assertStackSize(action, game, Integer.parseInt(params[1]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // check stack object: stack ability name, amount
                    if (params[0].equals(CHECK_COMMAND_STACK_OBJECT) && params.length == 3) {
                        assertStackObject(action, game, params[1], Integer.parseInt(params[2]));
                        actions.remove(action);
                        wasProccessed = true;
                    }
                }
                if (wasProccessed) {
                    return true;
                } else {
                    Assert.fail("Unknown check command or params: " + command);
                }
            } else if (action.getAction().startsWith(SHOW_PREFIX)) {
                String command = action.getAction();
                command = command.substring(command.indexOf(SHOW_PREFIX) + SHOW_PREFIX.length());
                String[] params = command.split(CHECK_PARAM_DELIMETER);
                boolean wasProccessed = false;
                if (params.length > 0) {
                    // show library
                    if (params[0].equals(SHOW_COMMAND_LIBRARY) && params.length == 1) {
                        printStart(action.getActionName());
                        // do not sort
                        printCards(computerPlayer.getLibrary().getCards(game), false);
                        printEnd();
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // show hand
                    if (params[0].equals(SHOW_COMMAND_HAND) && params.length == 1) {
                        printStart(action.getActionName());
                        printCards(computerPlayer.getHand().getCards(game));
                        printEnd();
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // show command
                    if (params[0].equals(SHOW_COMMAND_COMMAND) && params.length == 1) {
                        printStart(action.getActionName());
                        CardsImpl cards = new CardsImpl(game.getCommandersIds(computerPlayer, CommanderCardType.ANY, false));
                        printCards(cards.getCards(game));
                        printEnd();
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // show battlefield
                    if (params[0].equals(SHOW_COMMAND_BATTLEFIELD) && params.length == 1) {
                        printStart(action.getActionName());
                        printPermanents(game, game.getBattlefield().getAllActivePermanents(computerPlayer.getId()));
                        printEnd();
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // show graveyard
                    if (params[0].equals(SHOW_COMMAND_GRAVEYEARD) && params.length == 1) {
                        printStart(action.getActionName());
                        printCards(computerPlayer.getGraveyard().getCards(game));
                        printEnd();
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // show exile
                    if (params[0].equals(SHOW_COMMAND_EXILE) && params.length == 1) {
                        printStart(action.getActionName());
                        printCards(game.getExile().getAllCards(game).stream().filter(card -> card.isOwnedBy(computerPlayer.getId())).collect(Collectors.toList()), true);
                        printEnd();
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // show available abilities
                    if (params[0].equals(SHOW_COMMAND_AVAILABLE_ABILITIES) && params.length == 1) {
                        printStart(action.getActionName());
                        printAbilities(game, computerPlayer.getPlayable(game, true));
                        printEnd();
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // show available mana
                    if (params[0].equals(SHOW_COMMAND_AVAILABLE_MANA) && params.length == 1) {
                        printStart(action.getActionName());
                        printMana(game, computerPlayer.getManaAvailable(game));
                        printEnd();
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // show aliases
                    if (params[0].equals(SHOW_COMMAND_ALIASES) && params.length == 1) {
                        printStart(action.getActionName());
                        printAliases(game, this);
                        printEnd();
                        actions.remove(action);
                        wasProccessed = true;
                    }
                    // show stack
                    if (params[0].equals(SHOW_COMMAND_STACK) && params.length == 1) {
                        printStart(action.getActionName());
                        printStack(game);
                        printEnd();
                        actions.remove(action);
                        wasProccessed = true;
                    }
                }
                if (wasProccessed) {
                    return true;
                } else {
                    Assert.fail("Unknown show command or params: " + command);
                }
            }
            // you don't need to use stack command all the time, so some cast commands can be skiped to next check
            if (game.getStack().isEmpty()) {
                this.chooseStrictModeFailed("cast/activate", game, "Can't find available command - " + action.getAction() + " (use checkPlayableAbility for \"non available\" checks)", true);
            }
        }
    // turn/step
    }
    tryToPlayPriority(game);
    // check to prevent endless loops
    if (numberOfActions == actions.size()) {
        foundNoAction++;
        if (foundNoAction > maxCallsWithoutAction) {
            throw new AssertionError("Too much priority calls to " + getName() + " without taking any action than allowed (" + maxCallsWithoutAction + ") on turn " + game.getTurnNum());
        }
    } else {
        foundNoAction = 0;
    }
    return false;
}
Also used : SimpleStaticAbility(mage.abilities.common.SimpleStaticAbility) CounterType(mage.counters.CounterType) Permanent(mage.game.permanent.Permanent) SimpleStaticAbility(mage.abilities.common.SimpleStaticAbility) ActivatedManaAbilityImpl(mage.abilities.mana.ActivatedManaAbilityImpl) InfoEffect(mage.abilities.effects.common.InfoEffect) Card(mage.cards.Card) GameImpl(mage.game.GameImpl) Counter(mage.counters.Counter) CardsImpl(mage.cards.CardsImpl)

Example 23 with ActivatedManaAbilityImpl

use of mage.abilities.mana.ActivatedManaAbilityImpl in project mage by magefree.

the class ComputerPlayer method playManaHandling.

protected boolean playManaHandling(Ability ability, ManaCost unpaid, final Game game) {
    // log.info("paying for " + unpaid.getText());
    ApprovingObject approvingObject = game.getContinuousEffects().asThough(ability.getSourceId(), AsThoughEffectType.SPEND_OTHER_MANA, ability, ability.getControllerId(), game);
    ManaCost cost;
    List<MageObject> producers;
    if (unpaid instanceof ManaCosts) {
        ManaCosts<ManaCost> manaCosts = (ManaCosts<ManaCost>) unpaid;
        cost = manaCosts.get(manaCosts.size() - 1);
        producers = getSortedProducers((ManaCosts) unpaid, game);
    } else {
        cost = unpaid;
        producers = this.getAvailableManaProducers(game);
        producers.addAll(this.getAvailableManaProducersWithCost(game));
    }
    for (MageObject mageObject : producers) {
        // otherwise the computer may not be able to pay the cost for that source
        ManaAbility: for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) {
            int colored = 0;
            for (Mana mana : manaAbility.getNetMana(game)) {
                if (!unpaid.getMana().includesMana(mana)) {
                    continue ManaAbility;
                }
                colored += mana.countColored();
            }
            if (colored > 1 && (cost instanceof ColoredManaCost)) {
                for (Mana netMana : manaAbility.getNetMana(game)) {
                    if (cost.testPay(netMana)) {
                        if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) {
                            continue;
                        }
                        if (approvingObject != null && !canUseAsThoughManaToPayManaCost(cost, ability, netMana, manaAbility, mageObject, game)) {
                            continue;
                        }
                        if (activateAbility(manaAbility, game)) {
                            return true;
                        }
                    }
                }
            }
        }
    }
    for (MageObject mageObject : producers) {
        // pay all colored costs first
        for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) {
            if (cost instanceof ColoredManaCost) {
                for (Mana netMana : manaAbility.getNetMana(game)) {
                    if (cost.testPay(netMana) || approvingObject != null) {
                        if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) {
                            continue;
                        }
                        if (approvingObject != null && !canUseAsThoughManaToPayManaCost(cost, ability, netMana, manaAbility, mageObject, game)) {
                            continue;
                        }
                        if (activateAbility(manaAbility, game)) {
                            return true;
                        }
                    }
                }
            }
        }
        // pay snow covered mana
        for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) {
            if (cost instanceof SnowManaCost) {
                for (Mana netMana : manaAbility.getNetMana(game)) {
                    if (cost.testPay(netMana) || approvingObject != null) {
                        if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) {
                            continue;
                        }
                        if (approvingObject != null && !canUseAsThoughManaToPayManaCost(cost, ability, netMana, manaAbility, mageObject, game)) {
                            continue;
                        }
                        if (activateAbility(manaAbility, game)) {
                            return true;
                        }
                    }
                }
            }
        }
        // then pay hybrid
        for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) {
            if (cost instanceof HybridManaCost) {
                for (Mana netMana : manaAbility.getNetMana(game)) {
                    if (cost.testPay(netMana) || approvingObject != null) {
                        if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) {
                            continue;
                        }
                        if (approvingObject != null && !canUseAsThoughManaToPayManaCost(cost, ability, netMana, manaAbility, mageObject, game)) {
                            continue;
                        }
                        if (activateAbility(manaAbility, game)) {
                            return true;
                        }
                    }
                }
            }
        }
        // then pay mono hybrid
        for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) {
            if (cost instanceof MonoHybridManaCost) {
                for (Mana netMana : manaAbility.getNetMana(game)) {
                    if (cost.testPay(netMana) || approvingObject != null) {
                        if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) {
                            continue;
                        }
                        if (approvingObject != null && !canUseAsThoughManaToPayManaCost(cost, ability, netMana, manaAbility, mageObject, game)) {
                            continue;
                        }
                        if (activateAbility(manaAbility, game)) {
                            return true;
                        }
                    }
                }
            }
        }
        // pay colorless
        for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) {
            if (cost instanceof ColorlessManaCost) {
                for (Mana netMana : manaAbility.getNetMana(game)) {
                    if (cost.testPay(netMana) || approvingObject != null) {
                        if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) {
                            continue;
                        }
                        if (approvingObject != null && !canUseAsThoughManaToPayManaCost(cost, ability, netMana, manaAbility, mageObject, game)) {
                            continue;
                        }
                        if (activateAbility(manaAbility, game)) {
                            return true;
                        }
                    }
                }
            }
        }
        // finally pay generic
        for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) {
            if (cost instanceof GenericManaCost) {
                for (Mana netMana : manaAbility.getNetMana(game)) {
                    if (cost.testPay(netMana) || approvingObject != null) {
                        if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) {
                            continue;
                        }
                        if (approvingObject != null && !canUseAsThoughManaToPayManaCost(cost, ability, netMana, manaAbility, mageObject, game)) {
                            continue;
                        }
                        if (activateAbility(manaAbility, game)) {
                            return true;
                        }
                    }
                }
            }
        }
    }
    // pay phyrexian life costs
    if (cost.isPhyrexian()) {
        return cost.pay(ability, game, ability, playerId, false, null) || approvingObject != null;
    }
    // pay special mana like convoke cost (tap for pay)
    // GUI: user see "special" button while pay spell's cost
    // TODO: AI can't prioritize special mana types to pay, e.g. it will use first available
    SpecialAction specialAction = game.getState().getSpecialActions().getControlledBy(this.getId(), true).values().stream().findFirst().orElse(null);
    ManaOptions specialMana = specialAction == null ? null : specialAction.getManaOptions(ability, game, unpaid);
    if (specialMana != null) {
        for (Mana netMana : specialMana) {
            if (cost.testPay(netMana) || approvingObject != null) {
                if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) {
                    continue;
                }
                specialAction.setUnpaidMana(unpaid);
                if (activateAbility(specialAction, game)) {
                    return true;
                }
                // only one time try to pay
                break;
            }
        }
    }
    return false;
}
Also used : ManaOptions(mage.abilities.mana.ManaOptions) ApprovingObject(mage.ApprovingObject) ConditionalMana(mage.ConditionalMana) Mana(mage.Mana) MageObject(mage.MageObject) ActivatedManaAbilityImpl(mage.abilities.mana.ActivatedManaAbilityImpl) ConditionalMana(mage.ConditionalMana)

Example 24 with ActivatedManaAbilityImpl

use of mage.abilities.mana.ActivatedManaAbilityImpl in project mage by magefree.

the class ComputerPlayer method findPlayables.

protected void findPlayables(Game game) {
    playableInstant.clear();
    playableNonInstant.clear();
    unplayable.clear();
    playableAbilities.clear();
    Set<Card> nonLands = hand.getCards(new FilterNonlandCard(), game);
    ManaOptions available = getManaAvailable(game);
    for (Card card : nonLands) {
        ManaOptions options = card.getManaCost().getOptions();
        if (!card.getManaCost().getVariableCosts().isEmpty()) {
            // don't use variable mana costs unless there is at least 3 extra mana for X
            for (Mana option : options) {
                option.add(Mana.GenericMana(3));
            }
        }
        for (Mana mana : options) {
            for (Mana avail : available) {
                if (mana.enough(avail)) {
                    SpellAbility ability = card.getSpellAbility();
                    GameEvent castEvent = GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, ability.getId(), ability, playerId);
                    castEvent.setZone(game.getState().getZone(card.getMainCard().getId()));
                    if (ability != null && ability.canActivate(playerId, game).canActivate() && !game.getContinuousEffects().preventedByRuleModification(castEvent, ability, game, true)) {
                        if (card.isInstant(game) || card.hasAbility(FlashAbility.getInstance(), game)) {
                            playableInstant.add(card);
                        } else {
                            playableNonInstant.add(card);
                        }
                    }
                } else if (!playableInstant.contains(card) && !playableNonInstant.contains(card)) {
                    unplayable.put(mana.needed(avail), card);
                }
            }
        }
    }
    // TODO: wtf?! change to player.getPlayable
    for (Permanent permanent : game.getBattlefield().getAllActivePermanents(playerId)) {
        for (ActivatedAbility ability : permanent.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) {
            if (!(ability instanceof ActivatedManaAbilityImpl) && ability.canActivate(playerId, game).canActivate()) {
                if (ability instanceof EquipAbility && permanent.getAttachedTo() != null) {
                    continue;
                }
                ManaOptions abilityOptions = ability.getManaCosts().getOptions();
                if (!ability.getManaCosts().getVariableCosts().isEmpty()) {
                    // don't use variable mana costs unless there is at least 3 extra mana for X
                    for (Mana option : abilityOptions) {
                        option.add(Mana.GenericMana(3));
                    }
                }
                if (abilityOptions.isEmpty()) {
                    playableAbilities.add(ability);
                } else {
                    for (Mana mana : abilityOptions) {
                        for (Mana avail : available) {
                            if (mana.enough(avail)) {
                                playableAbilities.add(ability);
                            }
                        }
                    }
                }
            }
        }
    }
    for (Card card : graveyard.getCards(game)) {
        for (ActivatedAbility ability : card.getAbilities(game).getActivatedAbilities(Zone.GRAVEYARD)) {
            if (ability.canActivate(playerId, game).canActivate()) {
                ManaOptions abilityOptions = ability.getManaCosts().getOptions();
                if (abilityOptions.isEmpty()) {
                    playableAbilities.add(ability);
                } else {
                    for (Mana mana : abilityOptions) {
                        for (Mana avail : available) {
                            if (mana.enough(avail)) {
                                playableAbilities.add(ability);
                            }
                        }
                    }
                }
            }
        }
    }
    if (log.isDebugEnabled()) {
        log.debug("findPlayables: " + playableInstant.toString() + "---" + playableNonInstant.toString() + "---" + playableAbilities.toString());
    }
}
Also used : ManaOptions(mage.abilities.mana.ManaOptions) ConditionalMana(mage.ConditionalMana) Mana(mage.Mana) Permanent(mage.game.permanent.Permanent) FilterPermanent(mage.filter.FilterPermanent) GameEvent(mage.game.events.GameEvent) ActivatedManaAbilityImpl(mage.abilities.mana.ActivatedManaAbilityImpl) RateCard(mage.game.draft.RateCard) Card(mage.cards.Card) FilterCard(mage.filter.FilterCard)

Example 25 with ActivatedManaAbilityImpl

use of mage.abilities.mana.ActivatedManaAbilityImpl in project mage by magefree.

the class ComputerPlayer method playALand.

protected void playALand(Set<Card> lands, Game game) {
    log.debug("playALand");
    // play a land that will allow us to play an unplayable
    for (Mana mana : unplayable.keySet()) {
        for (Card card : lands) {
            for (ActivatedManaAbilityImpl ability : card.getAbilities(game).getActivatedManaAbilities(Zone.BATTLEFIELD)) {
                for (Mana netMana : ability.getNetMana(game)) {
                    if (netMana.enough(mana)) {
                        this.playLand(card, game, false);
                        lands.remove(card);
                        return;
                    }
                }
            }
        }
    }
    // play a land that will get us closer to playing an unplayable
    for (Mana mana : unplayable.keySet()) {
        for (Card card : lands) {
            for (ActivatedManaAbilityImpl ability : card.getAbilities(game).getActivatedManaAbilities(Zone.BATTLEFIELD)) {
                for (Mana netMana : ability.getNetMana(game)) {
                    if (mana.contains(netMana)) {
                        this.playLand(card, game, false);
                        lands.remove(card);
                        return;
                    }
                }
            }
        }
    }
    // play first available land
    this.playLand(lands.iterator().next(), game, false);
    lands.remove(lands.iterator().next());
}
Also used : ConditionalMana(mage.ConditionalMana) Mana(mage.Mana) ActivatedManaAbilityImpl(mage.abilities.mana.ActivatedManaAbilityImpl) RateCard(mage.game.draft.RateCard) Card(mage.cards.Card) FilterCard(mage.filter.FilterCard)

Aggregations

ActivatedManaAbilityImpl (mage.abilities.mana.ActivatedManaAbilityImpl)29 Permanent (mage.game.permanent.Permanent)12 StackAbility (mage.game.stack.StackAbility)7 MageObject (mage.MageObject)6 Mana (mage.Mana)5 Ability (mage.abilities.Ability)5 ManaCost (mage.abilities.costs.mana.ManaCost)5 Card (mage.cards.Card)5 FilterCard (mage.filter.FilterCard)5 FilterPermanent (mage.filter.FilterPermanent)5 TargetPermanent (mage.target.TargetPermanent)5 UUID (java.util.UUID)4 ConditionalMana (mage.ConditionalMana)4 ManaOptions (mage.abilities.mana.ManaOptions)4 FilterControlledPermanent (mage.filter.common.FilterControlledPermanent)4 PermanentCard (mage.game.permanent.PermanentCard)4 LinkedHashMap (java.util.LinkedHashMap)3 ManaCostsImpl (mage.abilities.costs.mana.ManaCostsImpl)3 Counter (mage.counters.Counter)3 Player (mage.players.Player)3