Search in sources :

Example 21 with Game

use of mage.game.Game in project mage by magefree.

the class StormTheVaultTest method createNewGameAndPlayers.

@Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
    Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20);
    playerA = createPlayer(game, playerA, "PlayerA");
    playerB = createPlayer(game, playerB, "PlayerB");
    playerC = createPlayer(game, playerC, "PlayerC");
    return game;
}
Also used : Game(mage.game.Game) FreeForAll(mage.game.FreeForAll)

Example 22 with Game

use of mage.game.Game in project mage by magefree.

the class SystemUtil method addCardsForTesting.

/**
 * Replaces cards in player's hands by specified in config/init.txt.<br/>
 * <br/>
 * <b>Implementation note:</b><br/>
 * 1. Read init.txt line by line<br/>
 * 2. Parse line using for searching groups like: [group 1] 3. Parse line
 * using the following format: line ::=
 * <zone>:<nickname>:<card name>:<amount><br/>
 * 4. If zone equals to 'hand', add card to player's library<br/>
 * 5a. Then swap added card with any card in player's hand<br/>
 * 5b. Parse next line (go to 2.), If EOF go to 4.<br/>
 * 6. Log message to all players that cards were added (to prevent unfair
 * play).<br/>
 * 7. Exit<br/>
 *
 * @param game
 */
public static void addCardsForTesting(Game game, String fileSource, Player feedbackPlayer) {
    // fake test ability for triggers and events
    Ability fakeSourceAbilityTemplate = new SimpleStaticAbility(Zone.OUTSIDE, new InfoEffect("adding testing cards"));
    fakeSourceAbilityTemplate.setControllerId(feedbackPlayer.getId());
    try {
        String fileName = fileSource;
        if (fileName == null) {
            fileName = INIT_FILE_PATH;
        }
        File f = new File(fileName);
        if (!f.exists()) {
            logger.warn("Couldn't find init file: " + fileName);
            return;
        }
        logger.info("Parsing init file... ");
        // steps:
        // 1. parse groups and commands
        // 2. ask user if many groups
        // 3. process system commands
        // 4. run commands from selected group
        // 1. parse
        List<CommandGroup> groups = new ArrayList<>();
        try (Scanner scanner = new Scanner(f)) {
            CommandGroup currentGroup = null;
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine().trim();
                // skip comments
                if (line.isEmpty() || line.startsWith("#") || line.startsWith("//")) {
                    continue;
                }
                // group
                Matcher matchGroup = patternGroup.matcher(line);
                if (matchGroup.matches()) {
                    String groupName = matchGroup.group(1);
                    if (groupName.startsWith("@")) {
                        // special command group
                        if (supportedCommands.containsKey(groupName)) {
                            currentGroup = new CommandGroup(groupName, true);
                            groups.add(currentGroup);
                        } else {
                            logger.warn("Special group [" + groupName + "] is not supported.");
                        }
                        continue;
                    } else {
                        // basic group
                        currentGroup = new CommandGroup(groupName);
                        groups.add(currentGroup);
                        continue;
                    }
                }
                // command
                if (currentGroup == null) {
                    currentGroup = new CommandGroup("default group");
                    groups.add(currentGroup);
                }
                currentGroup.commands.add(line);
            }
        }
        // 2. ask user
        CommandGroup runGroup = null;
        if (groups.size() == 1) {
            // not need to ask
            runGroup = groups.get(0);
        } else if (groups.size() > 1) {
            // need to ask
            logger.info("Found " + groups.size() + " groups. Need to select.");
            // choice dialog
            Map<String, String> list = new LinkedHashMap<>();
            Map<String, Integer> sort = new LinkedHashMap<>();
            for (int i = 0; i < groups.size(); i++) {
                list.put(Integer.toString(i + 1), groups.get(i).getPrintNameWithStats());
                sort.put(Integer.toString(i + 1), i);
            }
            Choice groupChoice = new ChoiceImpl(false);
            groupChoice.setMessage("Choose commands group to run");
            groupChoice.setKeyChoices(list);
            groupChoice.setSortData(sort);
            if (feedbackPlayer.choose(Outcome.Benefit, groupChoice, game)) {
                String need = groupChoice.getChoiceKey();
                if ((need != null) && list.containsKey(need)) {
                    runGroup = groups.get(Integer.parseInt(need) - 1);
                }
            }
        }
        if (runGroup == null) {
            // was canceled
            logger.info("Command file was empty or canceled");
            return;
        }
        logger.info("Selected group [" + runGroup.name + "] with " + runGroup.commands.size() + " commands");
        // 3. system commands
        if (runGroup.isSpecialCommand) {
            Player opponent = game.getPlayer(game.getOpponents(feedbackPlayer.getId()).stream().findFirst().orElse(null));
            String info;
            switch(runGroup.name) {
                case COMMAND_SHOW_OPPONENT_HAND:
                    if (opponent != null) {
                        info = getCardsListForSpecialInform(game, opponent.getHand(), runGroup.commands);
                        game.informPlayer(feedbackPlayer, info);
                    }
                    break;
                case COMMAND_SHOW_OPPONENT_LIBRARY:
                    if (opponent != null) {
                        info = getCardsListForSpecialInform(game, opponent.getLibrary().getCardList(), runGroup.commands);
                        game.informPlayer(feedbackPlayer, info);
                    }
                    break;
                case COMMAND_SHOW_MY_HAND:
                    info = getCardsListForSpecialInform(game, feedbackPlayer.getHand(), runGroup.commands);
                    game.informPlayer(feedbackPlayer, info);
                    break;
                case COMMAND_SHOW_MY_LIBRARY:
                    info = getCardsListForSpecialInform(game, feedbackPlayer.getLibrary().getCardList(), runGroup.commands);
                    game.informPlayer(feedbackPlayer, info);
                    break;
                case COMMAND_ACTIVATE_OPPONENT_ABILITY:
                    // WARNING, maybe very bugged if called in wrong priority
                    // uses choose triggered ability dialog to select it
                    UUID savedPriorityPlayer = null;
                    if (game.getActivePlayerId() != opponent.getId()) {
                        savedPriorityPlayer = game.getActivePlayerId();
                    }
                    // change active player to find and play selected abilities (it's danger and buggy code)
                    if (savedPriorityPlayer != null) {
                        game.getState().setPriorityPlayerId(opponent.getId());
                        game.firePriorityEvent(opponent.getId());
                    }
                    List<ActivatedAbility> abilities = opponent.getPlayable(game, true);
                    Map<String, String> choices = new HashMap<>();
                    abilities.forEach(ability -> {
                        MageObject object = ability.getSourceObject(game);
                        choices.put(ability.getId().toString(), object.getName() + ": " + ability.toString());
                    });
                    // TODO: set priority for us?
                    Choice choice = new ChoiceImpl();
                    choice.setMessage("Choose playable ability to activate by opponent " + opponent.getName());
                    choice.setKeyChoices(choices);
                    if (feedbackPlayer.choose(Outcome.Detriment, choice, game) && choice.getChoiceKey() != null) {
                        String needId = choice.getChoiceKey();
                        Optional<ActivatedAbility> ability = abilities.stream().filter(a -> a.getId().toString().equals(needId)).findFirst();
                        if (ability.isPresent()) {
                            // TODO: set priority for player?
                            ActivatedAbility activatedAbility = ability.get();
                            game.informPlayers(feedbackPlayer.getLogName() + " as another player " + opponent.getLogName() + " trying to force an activate ability: " + activatedAbility.getGameLogMessage(game));
                            if (opponent.activateAbility(activatedAbility, game)) {
                                game.informPlayers("Force to activate ability: DONE");
                            } else {
                                game.informPlayers("Force to activate ability: FAIL");
                            }
                        }
                    }
                    // restore original priority player
                    if (savedPriorityPlayer != null) {
                        game.getState().setPriorityPlayerId(savedPriorityPlayer);
                        game.firePriorityEvent(savedPriorityPlayer);
                    }
                    break;
            }
            return;
        }
        // insert group refs as extra commands (only user defined groups allowed, no special)
        Map<String, CommandGroup> otherGroupRefs = new HashMap<>();
        for (CommandGroup group : groups) {
            if (group != runGroup) {
                otherGroupRefs.putIfAbsent(COMMAND_REF_PREFIX + group.name, group);
            }
        }
        for (int i = runGroup.commands.size() - 1; i >= 0; i--) {
            String line = runGroup.commands.get(i);
            // replace ref by real commands from another group
            if (line.startsWith(COMMAND_REF_PREFIX)) {
                CommandGroup other = otherGroupRefs.getOrDefault(line, null);
                if (other != null && !other.isSpecialCommand) {
                    logger.info("Replace ref group " + line + " by " + other.commands.size() + " commands");
                    runGroup.commands.remove(i);
                    runGroup.commands.addAll(i, other.commands);
                } else {
                    logger.error("Can't find ref group: " + line);
                }
            }
        }
        // 4. run commands
        for (String line : runGroup.commands) {
            CardCommandData command = parseCardCommand(line);
            if (!command.OK) {
                logger.warn(command.Error + ": " + line);
                continue;
            }
            Optional<Player> playerOptional = findPlayer(game, command.player);
            if (!playerOptional.isPresent()) {
                logger.warn("Unknown player: " + line);
                continue;
            }
            Player player = playerOptional.get();
            // SPECIAL token/emblem call (without SET name)
            if ("token".equalsIgnoreCase(command.zone)) {
                // eg: token:Human:HippoToken:1
                Class<?> c = Class.forName("mage.game.permanent.token." + command.cardName);
                Constructor<?> cons = c.getConstructor();
                Object obj = cons.newInstance();
                if (obj instanceof Token) {
                    Token token = (Token) obj;
                    Ability fakeSourceAbility = fakeSourceAbilityTemplate.copy();
                    fakeSourceAbility.setSourceId(token.getId());
                    token.putOntoBattlefield(command.Amount, game, fakeSourceAbility, player.getId(), false, false);
                    continue;
                }
            } else if ("emblem".equalsIgnoreCase(command.zone)) {
                // eg: emblem:Human:ElspethSunsChampionEmblem:1
                Class<?> c = Class.forName("mage.game.command.emblems." + command.cardName);
                Constructor<?> cons = c.getConstructor();
                Object emblem = cons.newInstance();
                if (emblem instanceof mage.game.command.Emblem) {
                    ((mage.game.command.Emblem) emblem).setControllerId(player.getId());
                    game.addEmblem((mage.game.command.Emblem) emblem, null, player.getId());
                    continue;
                }
            } else if ("plane".equalsIgnoreCase(command.zone)) {
                if (putPlaneToGame(game, player, command.cardName)) {
                    continue;
                }
            } else if ("loyalty".equalsIgnoreCase(command.zone)) {
                for (Permanent perm : game.getBattlefield().getAllActivePermanents(player.getId())) {
                    if (perm.getName().equals(command.cardName) && perm.getCardType(game).contains(CardType.PLANESWALKER)) {
                        Ability fakeSourceAbility = fakeSourceAbilityTemplate.copy();
                        fakeSourceAbility.setSourceId(perm.getId());
                        perm.addCounters(CounterType.LOYALTY.createInstance(command.Amount), fakeSourceAbility.getControllerId(), fakeSourceAbility, game);
                    }
                }
                continue;
            } else if ("stack".equalsIgnoreCase(command.zone)) {
                // simple cast (without targets or modes)
                // find card info
                CardInfo cardInfo = CardRepository.instance.findCard(command.cardName);
                if (cardInfo == null) {
                    logger.warn("Unknown card for stack command [" + command.cardName + "]: " + line);
                    continue;
                }
                // put card to game
                Set<Card> cardsToLoad = new HashSet<>();
                for (int i = 0; i < command.Amount; i++) {
                    cardsToLoad.add(cardInfo.getCard());
                }
                game.loadCards(cardsToLoad, player.getId());
                // move card from exile to stack
                for (Card card : cardsToLoad) {
                    Ability fakeSourceAbility = fakeSourceAbilityTemplate.copy();
                    fakeSourceAbility.setSourceId(card.getId());
                    putCardToZone(fakeSourceAbility, game, player, card, Zone.STACK);
                }
                continue;
            }
            Zone gameZone;
            if ("hand".equalsIgnoreCase(command.zone)) {
                gameZone = Zone.HAND;
            } else if ("battlefield".equalsIgnoreCase(command.zone)) {
                gameZone = Zone.BATTLEFIELD;
            } else if ("graveyard".equalsIgnoreCase(command.zone)) {
                gameZone = Zone.GRAVEYARD;
            } else if ("library".equalsIgnoreCase(command.zone)) {
                gameZone = Zone.LIBRARY;
            } else if ("token".equalsIgnoreCase(command.zone)) {
                gameZone = Zone.BATTLEFIELD;
            } else if ("exiled".equalsIgnoreCase(command.zone)) {
                gameZone = Zone.EXILED;
            } else if ("outside".equalsIgnoreCase(command.zone)) {
                gameZone = Zone.OUTSIDE;
            } else if ("emblem".equalsIgnoreCase(command.zone)) {
                gameZone = Zone.COMMAND;
            } else if ("plane".equalsIgnoreCase(command.zone)) {
                gameZone = Zone.COMMAND;
            } else if ("commander".equalsIgnoreCase(command.zone)) {
                gameZone = Zone.COMMAND;
            } else if ("sideboard".equalsIgnoreCase(command.zone)) {
                gameZone = Zone.OUTSIDE;
            } else {
                logger.warn("Unknown zone [" + command.zone + "]: " + line);
                continue;
            }
            List<CardInfo> cards = null;
            if (command.cardSet.isEmpty()) {
                // by name
                cards = CardRepository.instance.findCards(command.cardName);
            } else {
                // by name and set
                cards = CardRepository.instance.findCards(new CardCriteria().setCodes(command.cardSet).name(command.cardName));
            }
            if (cards.isEmpty()) {
                logger.warn("Unknown card [" + command.cardName + "]: " + line);
                continue;
            }
            Set<Card> cardsToLoad = new HashSet<>();
            for (int i = 0; i < command.Amount; i++) {
                CardInfo cardInfo = cards.get(RandomUtil.nextInt(cards.size()));
                Card card = cardInfo != null ? cardInfo.getCard() : null;
                if (card != null) {
                    cardsToLoad.add(card);
                }
            }
            game.loadCards(cardsToLoad, player.getId());
            if ("commander".equalsIgnoreCase(command.zone) && cardsToLoad.size() > 0) {
                // as commander (only commander games, look at init code in GameCommanderImpl)
                if (game instanceof GameCommanderImpl) {
                    GameCommanderImpl gameCommander = (GameCommanderImpl) game;
                    cardsToLoad.forEach(card -> gameCommander.addCommander(card, player));
                    cardsToLoad.forEach(card -> gameCommander.initCommander(card, player));
                } else {
                    logger.fatal("Commander card can be used in commander game only: " + command.cardName);
                }
            } else if ("sideboard".equalsIgnoreCase(command.zone) && cardsToLoad.size() > 0) {
                // put to sideboard
                for (Card card : cardsToLoad) {
                    player.getSideboard().add(card);
                }
            } else {
                // as other card
                for (Card card : cardsToLoad) {
                    Ability fakeSourceAbility = fakeSourceAbilityTemplate.copy();
                    fakeSourceAbility.setSourceId(card.getId());
                    putCardToZone(fakeSourceAbility, game, player, card, gameZone);
                }
            }
        }
    } catch (Exception e) {
        logger.fatal("", e);
    }
}
Also used : SimpleStaticAbility(mage.abilities.common.SimpleStaticAbility) java.util(java.util) Zone(mage.constants.Zone) CardCriteria(mage.cards.repository.CardCriteria) SimpleDateFormat(java.text.SimpleDateFormat) Constructor(java.lang.reflect.Constructor) ContinuousEffect(mage.abilities.effects.ContinuousEffect) Player(mage.players.Player) Matcher(java.util.regex.Matcher) GameCommanderImpl(mage.game.GameCommanderImpl) CardType(mage.constants.CardType) MageObject(mage.MageObject) ActivatedAbility(mage.abilities.ActivatedAbility) Planes(mage.constants.Planes) Card(mage.cards.Card) RandomUtil(mage.util.RandomUtil) DateFormat(java.text.DateFormat) Choice(mage.choices.Choice) Outcome(mage.constants.Outcome) Plane(mage.game.command.Plane) CardUtil(mage.util.CardUtil) CardRepository(mage.cards.repository.CardRepository) Collectors(java.util.stream.Collectors) CommandObject(mage.game.command.CommandObject) File(java.io.File) TimeUnit(java.util.concurrent.TimeUnit) Game(mage.game.Game) ChoiceImpl(mage.choices.ChoiceImpl) Token(mage.game.permanent.token.Token) Effect(mage.abilities.effects.Effect) InfoEffect(mage.abilities.effects.common.InfoEffect) CardInfo(mage.cards.repository.CardInfo) Permanent(mage.game.permanent.Permanent) Pattern(java.util.regex.Pattern) CounterType(mage.counters.CounterType) Ability(mage.abilities.Ability) Choice(mage.choices.Choice) Permanent(mage.game.permanent.Permanent) Matcher(java.util.regex.Matcher) Token(mage.game.permanent.token.Token) InfoEffect(mage.abilities.effects.common.InfoEffect) SimpleStaticAbility(mage.abilities.common.SimpleStaticAbility) ActivatedAbility(mage.abilities.ActivatedAbility) Ability(mage.abilities.Ability) GameCommanderImpl(mage.game.GameCommanderImpl) Player(mage.players.Player) CardCriteria(mage.cards.repository.CardCriteria) Constructor(java.lang.reflect.Constructor) Zone(mage.constants.Zone) SimpleStaticAbility(mage.abilities.common.SimpleStaticAbility) ActivatedAbility(mage.abilities.ActivatedAbility) MageObject(mage.MageObject) CardInfo(mage.cards.repository.CardInfo) Card(mage.cards.Card) ChoiceImpl(mage.choices.ChoiceImpl) MageObject(mage.MageObject) CommandObject(mage.game.command.CommandObject) File(java.io.File)

Example 23 with Game

use of mage.game.Game in project mage by magefree.

the class AberrantResearcherEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Player controller = game.getPlayer(source.getControllerId());
    if (controller == null || controller.millCards(1, source, game).getCards(game).stream().noneMatch(card -> card.isInstantOrSorcery(game))) {
        return false;
    }
    new TransformSourceEffect().apply(game, source);
    return true;
}
Also used : OneShotEffect(mage.abilities.effects.OneShotEffect) UUID(java.util.UUID) MageInt(mage.MageInt) TransformSourceEffect(mage.abilities.effects.common.TransformSourceEffect) Player(mage.players.Player) CardSetInfo(mage.cards.CardSetInfo) BeginningOfUpkeepTriggeredAbility(mage.abilities.common.BeginningOfUpkeepTriggeredAbility) Game(mage.game.Game) TransformAbility(mage.abilities.keyword.TransformAbility) CardImpl(mage.cards.CardImpl) FlyingAbility(mage.abilities.keyword.FlyingAbility) mage.constants(mage.constants) Ability(mage.abilities.Ability) Player(mage.players.Player) TransformSourceEffect(mage.abilities.effects.common.TransformSourceEffect)

Example 24 with Game

use of mage.game.Game in project mage by magefree.

the class BackdraftHellkiteEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Player player = game.getPlayer(source.getControllerId());
    if (player == null) {
        return false;
    }
    player.getGraveyard().stream().filter(cardId -> affectedObjectList.contains(new MageObjectReference(cardId, game))).forEachOrdered(cardId -> {
        Card card = game.getCard(cardId);
        if (card == null) {
            return;
        }
        FlashbackAbility ability = new FlashbackAbility(card, card.getManaCost());
        ability.setSourceId(cardId);
        ability.setControllerId(card.getOwnerId());
        game.getState().addOtherAbility(card, ability);
    });
    return true;
}
Also used : AttacksTriggeredAbility(mage.abilities.common.AttacksTriggeredAbility) MageObjectReference(mage.MageObjectReference) UUID(java.util.UUID) MageInt(mage.MageInt) Player(mage.players.Player) CardSetInfo(mage.cards.CardSetInfo) ContinuousEffectImpl(mage.abilities.effects.ContinuousEffectImpl) Game(mage.game.Game) CardImpl(mage.cards.CardImpl) FlashbackAbility(mage.abilities.keyword.FlashbackAbility) FlyingAbility(mage.abilities.keyword.FlyingAbility) Card(mage.cards.Card) mage.constants(mage.constants) Ability(mage.abilities.Ability) FlashbackAbility(mage.abilities.keyword.FlashbackAbility) Player(mage.players.Player) MageObjectReference(mage.MageObjectReference) Card(mage.cards.Card)

Example 25 with Game

use of mage.game.Game in project mage by magefree.

the class BreechesBrazenPlundererEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Player player = game.getPlayer(source.getControllerId());
    if (player == null) {
        return false;
    }
    Cards cards = new CardsImpl();
    opponentIds.stream().map(game::getPlayer).filter(Objects::nonNull).map(Player::getLibrary).map(library -> library.getFromTop(game)).forEach(cards::add);
    player.moveCards(cards, Zone.EXILED, source, game);
    cards.removeIf(uuid -> game.getState().getZone(uuid) != Zone.EXILED);
    if (cards.isEmpty()) {
        return false;
    }
    for (Card card : cards.getCards(game)) {
        CardUtil.makeCardPlayable(game, source, card, Duration.EndOfTurn, true);
    }
    return true;
}
Also used : PartnerAbility(mage.abilities.keyword.PartnerAbility) mage.cards(mage.cards) Set(java.util.Set) OneShotEffect(mage.abilities.effects.OneShotEffect) CardUtil(mage.util.CardUtil) UUID(java.util.UUID) MageInt(mage.MageInt) Player(mage.players.Player) DamagedPlayerBatchEvent(mage.game.events.DamagedPlayerBatchEvent) HashSet(java.util.HashSet) Objects(java.util.Objects) TriggeredAbilityImpl(mage.abilities.TriggeredAbilityImpl) Game(mage.game.Game) GameEvent(mage.game.events.GameEvent) Permanent(mage.game.permanent.Permanent) DamagedEvent(mage.game.events.DamagedEvent) MenaceAbility(mage.abilities.keyword.MenaceAbility) mage.constants(mage.constants) Ability(mage.abilities.Ability) Player(mage.players.Player) mage.cards(mage.cards)

Aggregations

Game (mage.game.Game)212 Ability (mage.abilities.Ability)139 Player (mage.players.Player)126 UUID (java.util.UUID)117 OneShotEffect (mage.abilities.effects.OneShotEffect)104 CardSetInfo (mage.cards.CardSetInfo)102 CardImpl (mage.cards.CardImpl)100 CardType (mage.constants.CardType)82 Outcome (mage.constants.Outcome)78 Permanent (mage.game.permanent.Permanent)66 MageInt (mage.MageInt)60 mage.constants (mage.constants)47 Zone (mage.constants.Zone)46 GameEvent (mage.game.events.GameEvent)44 Objects (java.util.Objects)41 StaticFilters (mage.filter.StaticFilters)40 Collectors (java.util.stream.Collectors)35 SubType (mage.constants.SubType)34 Card (mage.cards.Card)32 MageObjectReference (mage.MageObjectReference)30