diff --git a/res/cardsfolder/a/arc_trail.txt b/res/cardsfolder/a/arc_trail.txt index d5f86659ba4..34ce5354f25 100644 --- a/res/cardsfolder/a/arc_trail.txt +++ b/res/cardsfolder/a/arc_trail.txt @@ -3,7 +3,7 @@ ManaCost:1 R Types:Sorcery Text:no text A:SP$ DealDamage | Cost$ 1 R | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select target creature or player (2 damage) | NumDmg$ 2 | SubAbility$ SVar=DBDealDamage | SpellDescription$ CARDNAME deals 2 damage to target creature or player and 1 damage to another target creature or player. -SVar:DBDealDamage:DB$DealDamage | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select target creature or player (1 damage) | NumDmg$ 1 +SVar:DBDealDamage:DB$ DealDamage | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select target creature or player (1 damage) | TargetUnique$ True | NumDmg$ 1 SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/arc_trail.jpg SetInfo:SOM|Uncommon|http://magiccards.info/scans/en/som/81.jpg diff --git a/src/main/java/forge/card/abilityFactory/AbilityFactory.java b/src/main/java/forge/card/abilityFactory/AbilityFactory.java index 0ba9fc616dc..bf9cbdc9389 100644 --- a/src/main/java/forge/card/abilityFactory/AbilityFactory.java +++ b/src/main/java/forge/card/abilityFactory/AbilityFactory.java @@ -264,6 +264,10 @@ public class AbilityFactory { // TargetValidTargeting most for Counter: e.g. target spell that targets X. if (mapParams.containsKey("TargetValidTargeting")) abTgt.setSAValidTargeting(mapParams.get("TargetValidTargeting")); + + if (mapParams.containsKey("TargetUnique")){ + abTgt.setUniqueTargets(true); + } } hasSubAb = mapParams.containsKey("SubAbility"); diff --git a/src/main/java/forge/card/spellability/Target.java b/src/main/java/forge/card/spellability/Target.java index be47c04f390..3a86f9504cb 100644 --- a/src/main/java/forge/card/spellability/Target.java +++ b/src/main/java/forge/card/spellability/Target.java @@ -17,7 +17,7 @@ public class Target { // Targeting restrictions (Creature, Min/Maxm etc) which are true for this whole Target // Target Choices (which is specific for the StackInstance) private Card srcCard; - + private boolean uniqueTargets = false; private Target_Choices choice = null; /** @@ -491,4 +491,12 @@ public class Target { return false; } + + public boolean isUniqueTargets() { + return uniqueTargets; + } + + public void setUniqueTargets(boolean unique) { + this.uniqueTargets = unique; + } } diff --git a/src/main/java/forge/card/spellability/Target_Selection.java b/src/main/java/forge/card/spellability/Target_Selection.java index a0a6d7ad516..9b0791bd60c 100644 --- a/src/main/java/forge/card/spellability/Target_Selection.java +++ b/src/main/java/forge/card/spellability/Target_Selection.java @@ -158,6 +158,17 @@ public class Target_Selection { return false; } + public ArrayList getUniqueTargets(SpellAbility ability){ + ArrayList targets = new ArrayList(); + SpellAbility child = ability; + while(child instanceof Ability_Sub){ + child = ((Ability_Sub)child).getParent(); + targets.addAll(child.getTarget().getTargets()); + } + + return targets; + } + // these have been copied over from CardFactoryUtil as they need two extra parameters for target selection. // however, due to the changes necessary for SA_Requirements this is much different than the original @@ -177,17 +188,29 @@ public class Target_Selection { CardList choices = AllZoneUtil.getCardsInZone(zone).getValidCards(target.getValidTgts(), ability.getActivatingPlayer(), ability.getSourceCard()); + ArrayList objects = new ArrayList(); + if (tgt.isUniqueTargets()){ + objects = getUniqueTargets(ability); + for (Object o : objects) { + if (o instanceof Card && objects.contains(o)){ + choices.remove((Card)o); + } + } + } + // Remove cards already targeted ArrayList targeted = tgt.getTargetCards(); for (Card c : targeted) { - if (choices.contains(c)) + if (choices.contains(c)){ choices.remove(c); + } } - + if (zone.equals(Constant.Zone.Battlefield)) { - AllZone.getInputControl().setInput(input_targetSpecific(choices, true, mandatory)); - } else + AllZone.getInputControl().setInput(input_targetSpecific(choices, true, mandatory, objects)); + } else{ chooseCardFromList(choices, true, mandatory); + } }//input_targetValid //CardList choices are the only cards the user can successful select @@ -197,9 +220,10 @@ public class Target_Selection { * @param choices a {@link forge.CardList} object. * @param targeted a boolean. * @param mandatory a boolean. + * @param objects TODO * @return a {@link forge.gui.input.Input} object. */ - public Input input_targetSpecific(final CardList choices, final boolean targeted, final boolean mandatory) { + public Input input_targetSpecific(final CardList choices, final boolean targeted, final boolean mandatory, final ArrayList alreadyTargeted) { final SpellAbility sa = this.ability; final Target_Selection select = this; final Target tgt = this.target; @@ -212,6 +236,9 @@ public class Target_Selection { public void showMessage() { StringBuilder sb = new StringBuilder(); sb.append("Targeted: "); + for(Object o : alreadyTargeted){ + sb.append(o).append(" "); + } sb.append(tgt.getTargetedString()); sb.append("\n"); sb.append(tgt.getVTSelection()); @@ -254,6 +281,10 @@ public class Target_Selection { @Override public void selectPlayer(Player player) { + if (alreadyTargeted.contains(player)){ + return; + } + if ((tgt.canTgtPlayer() || (tgt.canOnlyTgtOpponent() && player.equals(sa.getActivatingPlayer().getOpponent()))) && player.canTarget(sa)) { tgt.addTarget(player);