public void removeCopiedCard(Card card) { if (copiedCards.containsKey(card.getId())) { copiedCards.remove(card.getId()); cardState.remove(card.getId()); zones.remove(card.getId()); zoneChangeCounter.remove(card.getId()); } // TODO Watchers? // TODO Abilities? if (card.isSplitCard()) { removeCopiedCard(((SplitCard) card).getLeftHalfCard()); removeCopiedCard(((SplitCard) card).getRightHalfCard()); } }
public SplitCard(SplitCard card) { super(card); this.leftHalfCard = card.getLeftHalfCard().copy(); ((SplitCardHalf) leftHalfCard).setParentCard(this); this.rightHalfCard = card.rightHalfCard.copy(); ((SplitCardHalf) rightHalfCard).setParentCard(this); }
public Spell(Card card, SpellAbility ability, UUID controllerId, Zone fromZone) { this.card = card; this.color = card.getColor(null).copy(); this.frameColor = card.getFrameColor(null).copy(); this.frameStyle = card.getFrameStyle(); id = ability.getId(); this.ability = ability; this.ability.setControllerId(controllerId); if (ability.getSpellAbilityType() == SpellAbilityType.SPLIT_FUSED) { spellCards.add(((SplitCard) card).getLeftHalfCard()); spellAbilities.add(((SplitCard) card).getLeftHalfCard().getSpellAbility().copy()); spellCards.add(((SplitCard) card).getRightHalfCard()); spellAbilities.add(((SplitCard) card).getRightHalfCard().getSpellAbility().copy()); } else { spellCards.add(card); spellAbilities.add(ability); } this.controllerId = controllerId; this.fromZone = fromZone; this.countered = false; }
@Override public boolean apply(MageObject input, Game game) { Set<String> cardNames = new HashSet<>(); UUID exileId = CardUtil.getCardExileZoneId(game, sourceId); ExileZone exileZone = game.getExile().getExileZone(exileId); if (exileZone != null) { for (Card card : exileZone.getCards(game)) { cardNames.add(card.getName()); } } // If a player names a card, the player may name either half of a split card, but not both. // A split card has the chosen name if one of its two names matches the chosen name. if (input instanceof SplitCard) { return cardNames.contains(((SplitCard) input).getLeftHalfCard().getName()) || cardNames.contains(((SplitCard) input).getRightHalfCard().getName()); } else if (input instanceof Spell && ((Spell) input).getSpellAbility().getSpellAbilityType() == SpellAbilityType.SPLIT_FUSED) { SplitCard card = (SplitCard) ((Spell) input).getCard(); return cardNames.contains(card.getLeftHalfCard().getName()) || cardNames.contains(card.getRightHalfCard().getName()); } else { return cardNames.contains(input.getName()); } }
@Override public boolean apply(MageObject input, Game game) { String name = input.getName(); if (input instanceof SplitCard) { return hasTwoWords(((SplitCard)input).getLeftHalfCard().getName()) || hasTwoWords(((SplitCard)input).getRightHalfCard().getName()); } else if (input instanceof Spell && ((Spell) input).getSpellAbility().getSpellAbilityType() == SpellAbilityType.SPLIT_FUSED){ SplitCard card = (SplitCard) ((Spell)input).getCard(); return hasTwoWords(card.getLeftHalfCard().getName()) || hasTwoWords(card.getRightHalfCard().getName()); } else { if (name.contains(" // ")) { String leftName = name.substring(0, name.indexOf(" // ")); String rightName = name.substring(name.indexOf(" // ") + 4, name.length()); return hasTwoWords(leftName) || hasTwoWords(rightName); } else { return hasTwoWords(name); } } }
@Override public boolean apply(MageObject input, Game game) { String name = input.getName(); if (input instanceof SplitCard) { return sharesWordWithName(((SplitCard)input).getLeftHalfCard().getName()) || sharesWordWithName(((SplitCard)input).getRightHalfCard().getName()); } else if (input instanceof Spell && ((Spell) input).getSpellAbility().getSpellAbilityType() == SpellAbilityType.SPLIT_FUSED){ SplitCard card = (SplitCard) ((Spell)input).getCard(); return sharesWordWithName(card.getLeftHalfCard().getName()) || sharesWordWithName(card.getRightHalfCard().getName()); } else { if (name.contains(" // ")) { String leftName = name.substring(0, name.indexOf(" // ")); String rightName = name.substring(name.indexOf(" // ") + 4, name.length()); return sharesWordWithName(leftName) || sharesWordWithName(rightName); } else { return sharesWordWithName(name); } } }
@Override public boolean canTarget(UUID id, Game game) { if (super.canTarget(id, game)) { Card card = game.getCard(id); if (card != null) { if (targets.size() == 1) { Card card2 = game.getCard(targets.entrySet().iterator().next().getKey()); return card2 != null && card2.getName().equals(card.getName()); } else { FilterCard nameFilter = new FilterCard(); nameFilter.add(new NamePredicate(card.isSplitCard() ? ((SplitCard) card).getLeftHalfCard().getName() : card.getName())); Player player = game.getPlayer(card.getOwnerId()); return player != null && player.getHand().getCards(nameFilter, game).size() > 1; } } } return false; }
@Override public boolean cast(Game game, Zone fromZone, SpellAbility ability, UUID controllerId) { switch (ability.getSpellAbilityType()) { case SPLIT_LEFT: return this.getLeftHalfCard().cast(game, fromZone, ability, controllerId); case SPLIT_RIGHT: return this.getRightHalfCard().cast(game, fromZone, ability, controllerId); default: this.getLeftHalfCard().getSpellAbility().setControllerId(controllerId); this.getRightHalfCard().getSpellAbility().setControllerId(controllerId); return super.cast(game, fromZone, ability, controllerId); } }
@Override public LinkedHashMap<UUID, ActivatedAbility> getUseableActivatedAbilities(MageObject object, Zone zone, Game game) { LinkedHashMap<UUID, ActivatedAbility> useable = new LinkedHashMap<>(); if (object instanceof StackAbility) { // It may not be possible to activate abilities of stack abilities return useable; } if (object instanceof SplitCard) { SplitCard splitCard = (SplitCard) object; getUseableActivatedAbilitiesHalfImpl(splitCard.getLeftHalfCard(), zone, game, splitCard.getLeftHalfCard().getAbilities(), useable); getUseableActivatedAbilitiesHalfImpl(splitCard.getRightHalfCard(), zone, game, splitCard.getRightHalfCard().getAbilities(), useable); getUseableActivatedAbilitiesHalfImpl(splitCard, zone, game, splitCard.getSharedAbilities(), useable); } else { getUseableActivatedAbilitiesHalfImpl(object, zone, game, object.getAbilities(), useable); } getOtherUseableActivatedAbilities(object, zone, game, useable); return useable; }
@Override public void setZone(Zone zone, Game game) { super.setZone(zone, game); game.setZone(getLeftHalfCard().getId(), zone); game.setZone(getRightHalfCard().getId(), zone); }
@Override public void setZone(Zone zone, Game game) { game.setZone(splitCardParent.getId(), zone); game.setZone(splitCardParent.getLeftHalfCard().getId(), zone); game.setZone(splitCardParent.getRightHalfCard().getId(), zone); }
@Override public void loadCards(Set<Card> cards, UUID ownerId) { for (Card card : cards) { if (card instanceof PermanentCard) { card = ((PermanentCard) card).getCard(); } card.setOwnerId(ownerId); gameCards.put(card.getId(), card); state.addCard(card); if (card.isSplitCard()) { Card leftCard = ((SplitCard) card).getLeftHalfCard(); leftCard.setOwnerId(ownerId); gameCards.put(leftCard.getId(), leftCard); state.addCard(leftCard); Card rightCard = ((SplitCard) card).getRightHalfCard(); rightCard.setOwnerId(ownerId); gameCards.put(rightCard.getId(), rightCard); state.addCard(rightCard); } } }
public Card copyCard(Card cardToCopy, Ability source, Game game) { Card copiedCard = cardToCopy.copy(); copiedCard.assignNewId(); copiedCard.setOwnerId(source.getControllerId()); copiedCard.setCopy(true, cardToCopy); copiedCards.put(copiedCard.getId(), copiedCard); addCard(copiedCard); if (copiedCard.isSplitCard()) { Card leftCard = ((SplitCard) copiedCard).getLeftHalfCard(); copiedCards.put(leftCard.getId(), leftCard); addCard(leftCard); Card rightCard = ((SplitCard) copiedCard).getRightHalfCard(); copiedCards.put(rightCard.getId(), rightCard); addCard(rightCard); } return copiedCard; }
private boolean isCardFormatValid(Card card, Card commander, FilterMana color) { if (!cardHasValideColor(color, card)) { invalid.put(card.getName(), "Invalid color (" + commander.getName() + ')'); return false; } //905.5b - Converted mana cost must be 3 or less if (card instanceof SplitCard) { if (((SplitCard) card).getLeftHalfCard().getManaCost().convertedManaCost() > 3) { invalid.put(card.getName(), "Invalid cost (" + ((SplitCard) card).getLeftHalfCard().getManaCost().convertedManaCost() + ')'); return false; } if (((SplitCard) card).getRightHalfCard().getManaCost().convertedManaCost() > 3) { invalid.put(card.getName(), "Invalid cost (" + ((SplitCard) card).getRightHalfCard().getManaCost().convertedManaCost() + ')'); return false; } } else if (card.getManaCost().convertedManaCost() > 3) { invalid.put(card.getName(), "Invalid cost (" + card.getManaCost().convertedManaCost() + ')'); return false; } return true; }
@Override public boolean moveToZone(Zone toZone, UUID sourceId, Game game, boolean flag, List<UUID> appliedEffects) { if (super.moveToZone(toZone, sourceId, game, flag, appliedEffects)) { game.getState().setZone(getLeftHalfCard().getId(), toZone); game.getState().setZone(getRightHalfCard().getId(), toZone); return true; } return false; }
@Override public boolean moveToExile(UUID exileId, String name, UUID sourceId, Game game, List<UUID> appliedEffects) { if (super.moveToExile(exileId, name, sourceId, game, appliedEffects)) { Zone currentZone = game.getState().getZone(getId()); game.getState().setZone(getLeftHalfCard().getId(), currentZone); game.getState().setZone(getRightHalfCard().getId(), currentZone); return true; } return false; }
private boolean isConvertedManaCostEqual(Ability sourceAbility, int amount) { for (Cost cost : sourceAbility.getCosts()) { if (cost.isPaid() && cost instanceof ExileFromHandCost) { for (Card card : ((ExileFromHandCost) cost).getCards()) { if (card instanceof SplitCard) { if (((SplitCard) card).getLeftHalfCard().getConvertedManaCost() == amount) { return true; } if (((SplitCard) card).getRightHalfCard().getConvertedManaCost() == amount) { return true; } } else if (card.getConvertedManaCost() == amount) { return true; } } return false; } } // No alternate costs payed so compare to X value return sourceAbility.getManaCostsToPay().getX() == amount; }
@Override public boolean canChooseTarget(Game game) { if (this instanceof SpellAbility) { if (SpellAbilityType.SPLIT_FUSED.equals(((SpellAbility) this).getSpellAbilityType())) { Card card = game.getCard(getSourceId()); if (card != null) { return canChooseTargetAbility(((SplitCard) card).getLeftHalfCard().getSpellAbility(), game, getControllerId()) && canChooseTargetAbility(((SplitCard) card).getRightHalfCard().getSpellAbility(), game, getControllerId()); } return false; } } return canChooseTargetAbility(this, game, getControllerId()); }
@Override public boolean canChoose(UUID sourceControllerId, Game game) { Cards cardsToCheck = new CardsImpl(); Player player = game.getPlayer(sourceControllerId); if (player == null) { return false; } for (Card card : player.getHand().getCards(filter, game)) { cardsToCheck.add(card.getId()); } int possibleCards = 0; for (Card card : cardsToCheck.getCards(game)) { FilterCard nameFilter = new FilterCard(); nameFilter.add(new NamePredicate(card.isSplitCard() ? ((SplitCard) card).getLeftHalfCard().getName() : card.getName())); if (cardsToCheck.count(nameFilter, game) > 1) { ++possibleCards; } } return possibleCards > 0; }
@Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); if (controller == null || controller.getHand().isEmpty() || sourceObject == null) { return false; } Card cardToReveal = null; Target target = new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE); target.setNotTarget(true); if (controller.chooseTarget(outcome, target, source, game)) { cardToReveal = game.getCard(target.getFirstTarget()); } if (cardToReveal == null) { return false; } controller.revealCards("from hand :" + sourceObject.getName(), new CardsImpl(cardToReveal), game); String nameToSearch = cardToReveal.isSplitCard() ? ((SplitCard) cardToReveal).getLeftHalfCard().getName() : cardToReveal.getName(); FilterCard filterCard = new FilterCard("card named " + nameToSearch); filterCard.add(new NamePredicate(nameToSearch)); return new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filterCard), true, true).apply(game, source); } }