Search in sources :

Example 1 with MageObject

use of mage.MageObject in project mage by magefree.

the class HumanPlayer method chooseTargetAmount.

@Override
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) {
    // human can choose or un-choose MULTIPLE targets at once
    if (gameInCheckPlayableState(game)) {
        return true;
    }
    UUID abilityControllerId = playerId;
    if (target.getAbilityController() != null) {
        abilityControllerId = target.getAbilityController();
    }
    int amountTotal = target.getAmountTotal(game, source);
    // 1. Select targets
    while (canRespond()) {
        Set<UUID> possibleTargets = target.possibleTargets(source == null ? null : source.getSourceId(), abilityControllerId, game);
        boolean required = target.isRequired(source != null ? source.getSourceId() : null, game);
        if (possibleTargets.isEmpty() || target.getSize() >= target.getNumberOfTargets()) {
            required = false;
        }
        // selected
        Map<String, Serializable> options = getOptions(target, null);
        java.util.List<UUID> chosen = target.getTargets();
        options.put("chosen", (Serializable) chosen);
        // selectable
        java.util.List<UUID> choosable = new ArrayList<>();
        for (UUID targetId : possibleTargets) {
            if (target.canTarget(abilityControllerId, targetId, source, game)) {
                choosable.add(targetId);
            }
        }
        if (!choosable.isEmpty()) {
            options.put("choosable", (Serializable) choosable);
        }
        // if nothing to choose then show dialog (user must see non selectable items and click on any of them)
        if (required && choosable.isEmpty()) {
            required = false;
        }
        updateGameStatePriority("chooseTargetAmount", game);
        prepareForResponse(game);
        if (!isExecutingMacro()) {
            // target amount uses for damage only, if you see another use case then message must be changed here and on getMultiAmount call
            String message = String.format("Select targets to distribute %d damage (selected %d)", amountTotal, target.getTargets().size());
            game.fireSelectTargetEvent(playerId, new MessageToClient(message, getRelatedObjectName(source, game)), possibleTargets, required, options);
        }
        waitForResponse(game);
        UUID responseId = getFixedResponseUUID(game);
        if (responseId != null) {
            if (target.contains(responseId)) {
                // unselect
                target.remove(responseId);
            } else if (possibleTargets.contains(responseId) && target.canTarget(abilityControllerId, responseId, source, game)) {
                // select
                target.addTarget(responseId, source, game);
            }
        } else if (!required) {
            break;
        }
    }
    // no targets to choose or disconnected
    List<UUID> targets = target.getTargets();
    if (targets.isEmpty()) {
        return false;
    }
    // 2. Distribute amount between selected targets
    // prepare targets list with p/t or life stats (cause that's dialog used for damage distribute)
    List<String> targetNames = new ArrayList<>();
    for (UUID targetId : targets) {
        MageObject targetObject = game.getObject(targetId);
        if (targetObject != null) {
            targetNames.add(String.format("%s, P/T: %d/%d", targetObject.getIdName(), targetObject.getPower().getValue(), targetObject.getToughness().getValue()));
        } else {
            Player player = game.getPlayer(targetId);
            if (player != null) {
                targetNames.add(String.format("%s, life: %d", player.getName(), player.getLife()));
            } else {
                targetNames.add("ERROR, unknown target " + targetId.toString());
            }
        }
    }
    // ask and assign new amount
    List<Integer> targetValues = getMultiAmount(outcome, targetNames, 1, amountTotal, MultiAmountType.DAMAGE, game);
    for (int i = 0; i < targetValues.size(); i++) {
        int newAmount = targetValues.get(i);
        UUID targetId = targets.get(i);
        if (newAmount <= 0) {
            // remove target
            target.remove(targetId);
        } else {
            // set amount
            target.setTargetAmount(targetId, newAmount, source, game);
        }
    }
    return true;
}
Also used : Serializable(java.io.Serializable) Player(mage.players.Player) MessageToClient(mage.util.MessageToClient) MageObject(mage.MageObject) java.util(java.util)

Example 2 with MageObject

use of mage.MageObject in project mage by magefree.

the class HumanPlayer method chooseTriggeredAbility.

@Override
public TriggeredAbility chooseTriggeredAbility(java.util.List<TriggeredAbility> abilities, Game game) {
    // choose triggered abilitity from list
    if (gameInCheckPlayableState(game)) {
        return null;
    }
    String autoOrderRuleText = null;
    boolean autoOrderUse = getControllingPlayersUserData(game).isAutoOrderTrigger();
    while (canRespond()) {
        // try to set trigger auto order
        java.util.List<TriggeredAbility> abilitiesWithNoOrderSet = new ArrayList<>();
        TriggeredAbility abilityOrderLast = null;
        for (TriggeredAbility ability : abilities) {
            if (triggerAutoOrderAbilityFirst.contains(ability.getOriginalId())) {
                return ability;
            }
            MageObject object = game.getObject(ability.getSourceId());
            String rule = ability.getRule(object != null ? object.getName() : null);
            if (triggerAutoOrderNameFirst.contains(rule)) {
                return ability;
            }
            if (triggerAutoOrderAbilityLast.contains(ability.getOriginalId())) {
                abilityOrderLast = ability;
                continue;
            }
            if (triggerAutoOrderNameLast.contains(rule)) {
                abilityOrderLast = ability;
                continue;
            }
            if (autoOrderUse) {
                if (autoOrderRuleText == null) {
                    autoOrderRuleText = rule;
                } else if (!rule.equals(autoOrderRuleText)) {
                    autoOrderUse = false;
                }
            }
            abilitiesWithNoOrderSet.add(ability);
        }
        if (abilitiesWithNoOrderSet.isEmpty()) {
            return abilityOrderLast;
        }
        if (abilitiesWithNoOrderSet.size() == 1 || autoOrderUse) {
            return abilitiesWithNoOrderSet.iterator().next();
        }
        macroTriggeredSelectionFlag = true;
        updateGameStatePriority("chooseTriggeredAbility", game);
        prepareForResponse(game);
        if (!isExecutingMacro()) {
            game.fireSelectTargetTriggeredAbilityEvent(playerId, "Pick triggered ability (goes to the stack first)", abilitiesWithNoOrderSet);
        }
        waitForResponse(game);
        UUID responseId = getFixedResponseUUID(game);
        if (responseId != null) {
            for (TriggeredAbility ability : abilitiesWithNoOrderSet) {
                if (ability.getId().equals(responseId) || (!macroTriggeredSelectionFlag && ability.getSourceId().equals(responseId))) {
                    if (recordingMacro) {
                        PlayerResponse tResponse = new PlayerResponse();
                        tResponse.setUUID(ability.getSourceId());
                        actionQueueSaved.add(tResponse);
                        logger.debug("Adding Triggered Ability Source: " + tResponse);
                    }
                    macroTriggeredSelectionFlag = false;
                    return ability;
                }
            }
        }
    }
    macroTriggeredSelectionFlag = false;
    return null;
}
Also used : java.util(java.util) MageObject(mage.MageObject)

Example 3 with MageObject

use of mage.MageObject in project mage by magefree.

the class ComputerPlayer method logList.

protected void logList(String message, List<MageObject> list) {
    StringBuilder sb = new StringBuilder();
    sb.append(message).append(": ");
    for (MageObject object : list) {
        sb.append(object.getName()).append(',');
    }
    log.info(sb.toString());
}
Also used : MageObject(mage.MageObject)

Example 4 with MageObject

use of mage.MageObject in project mage by magefree.

the class BeaconOfDestinyEffect method applies.

@Override
public boolean applies(GameEvent event, Ability source, Game game) {
    // check source
    MageObject object = game.getObject(event.getSourceId());
    if (object == null) {
        game.informPlayers("Couldn't find source of damage");
        return false;
    }
    if (!object.getId().equals(damageSource.getFirstTarget()) && (!(object instanceof Spell) || !((Spell) object).getSourceId().equals(damageSource.getFirstTarget()))) {
        return false;
    }
    TargetPermanent target = new TargetPermanent();
    target.add(source.getSourceId(), game);
    this.redirectTarget = target;
    // check player
    Player player = game.getPlayer(event.getTargetId());
    if (player != null) {
        if (player.getId().equals(source.getControllerId())) {
            return true;
        }
    }
    return false;
}
Also used : Player(mage.players.Player) MageObject(mage.MageObject) TargetPermanent(mage.target.TargetPermanent) Spell(mage.game.stack.Spell)

Example 5 with MageObject

use of mage.MageObject in project mage by magefree.

the class BorderlandExplorerEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Player controller = game.getPlayer(source.getControllerId());
    MageObject sourceObject = source.getSourceObject(game);
    if (controller != null && sourceObject != null) {
        // Store for each player the cards to discard, that's important because all discard shall happen at the same time
        Map<UUID, Cards> cardsToDiscard = new HashMap<>();
        // Store for each player the lands to reveal, that's important because all reveals shall happen at the same time
        Map<UUID, Cards> cardsToReveal = new HashMap<>();
        // choose cards to discard
        for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
            Player player = game.getPlayer(playerId);
            if (player != null) {
                Target target = new TargetDiscard(0, 1, new FilterCard(), playerId);
                player.chooseTarget(outcome, target, source, game);
                Cards cards = new CardsImpl(target.getTargets());
                cardsToDiscard.put(playerId, cards);
            }
        }
        // discard all chosen cards
        for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
            Player player = game.getPlayer(playerId);
            if (player != null) {
                Cards cardsPlayer = cardsToDiscard.get(playerId);
                if (cardsPlayer != null) {
                    for (UUID cardId : cardsPlayer) {
                        Card card = game.getCard(cardId);
                        player.discard(card, false, source, game);
                    }
                }
            }
        }
        // search for a land for each player that discarded
        for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
            Player player = game.getPlayer(playerId);
            if (player != null) {
                Cards cardsPlayer = cardsToDiscard.get(playerId);
                if (cardsPlayer != null && !cardsPlayer.isEmpty()) {
                    TargetCardInLibrary target = new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_BASIC_LAND);
                    if (player.searchLibrary(target, source, game)) {
                        if (!target.getTargets().isEmpty()) {
                            Cards cards = new CardsImpl(target.getTargets());
                            cards.addAll(target.getTargets());
                            cardsToReveal.put(playerId, cards);
                        }
                    }
                }
            }
        }
        // reveal the searched lands, put in hands, and shuffle
        for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
            Player player = game.getPlayer(playerId);
            if (player != null) {
                Cards cardsPlayer = cardsToReveal.get(playerId);
                if (cardsPlayer != null) {
                    for (UUID cardId : cardsPlayer) {
                        Card card = game.getCard(cardId);
                        Cards cards = new CardsImpl(game.getCard(cardId));
                        if (card != null && !cards.isEmpty()) {
                            player.revealCards(sourceObject.getIdName() + " (" + player.getName() + ')', cards, game);
                            player.moveCards(card, Zone.HAND, source, game);
                            player.shuffleLibrary(source, game);
                        }
                    }
                }
            }
        }
        return true;
    }
    return false;
}
Also used : FilterCard(mage.filter.FilterCard) Player(mage.players.Player) Target(mage.target.Target) HashMap(java.util.HashMap) MageObject(mage.MageObject) UUID(java.util.UUID) TargetDiscard(mage.target.common.TargetDiscard) TargetCardInLibrary(mage.target.common.TargetCardInLibrary) FilterCard(mage.filter.FilterCard)

Aggregations

MageObject (mage.MageObject)738 Player (mage.players.Player)554 Permanent (mage.game.permanent.Permanent)239 UUID (java.util.UUID)224 Card (mage.cards.Card)210 FilterCard (mage.filter.FilterCard)113 CardsImpl (mage.cards.CardsImpl)106 TargetCard (mage.target.TargetCard)91 Cards (mage.cards.Cards)73 Spell (mage.game.stack.Spell)68 FixedTarget (mage.target.targetpointer.FixedTarget)66 HashSet (java.util.HashSet)56 Ability (mage.abilities.Ability)52 ContinuousEffect (mage.abilities.effects.ContinuousEffect)51 TargetPermanent (mage.target.TargetPermanent)48 TargetCreaturePermanent (mage.target.common.TargetCreaturePermanent)48 FilterCreaturePermanent (mage.filter.common.FilterCreaturePermanent)46 Target (mage.target.Target)44 Effect (mage.abilities.effects.Effect)42 OneShotEffect (mage.abilities.effects.OneShotEffect)41