package forge.card.spellability; import forge.*; import forge.card.abilityFactory.AbilityFactory; import forge.card.cardFactory.CardFactoryUtil; import java.util.ArrayList; /** * <p>Target class.</p> * * @author Forge * @version $Id: $ */ public class Target { // Target has two things happening: // 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 Target_Choices choice = null; /** * <p>getTargetChoices.</p> * * @return a {@link forge.card.spellability.Target_Choices} object. */ public Target_Choices getTargetChoices() { return choice; } /** * <p>setTargetChoices.</p> * * @param tc a {@link forge.card.spellability.Target_Choices} object. */ public void setTargetChoices(Target_Choices tc) { choice = tc; } private boolean bMandatory = false; /** * <p>getMandatory.</p> * * @return a boolean. */ public boolean getMandatory() { return bMandatory; } /** * <p>setMandatory.</p> * * @param m a boolean. */ public void setMandatory(boolean m) { bMandatory = m; } private boolean tgtValid = false; private String ValidTgts[]; private String vtSelection = ""; /** * <p>doesTarget.</p> * * @return a boolean. */ public boolean doesTarget() { return tgtValid; } /** * <p>getValidTgts.</p> * * @return an array of {@link java.lang.String} objects. */ public String[] getValidTgts() { return ValidTgts; } /** * <p>getVTSelection.</p> * * @return a {@link java.lang.String} object. */ public String getVTSelection() { return vtSelection; } private String minTargets; private String maxTargets; /** * <p>Getter for the field <code>minTargets</code>.</p> * * @param c a {@link forge.Card} object. * @param sa a {@link forge.card.spellability.SpellAbility} object. * @return a int. */ public int getMinTargets(Card c, SpellAbility sa) { return AbilityFactory.calculateAmount(c, minTargets, sa); } /** * <p>Getter for the field <code>maxTargets</code>.</p> * * @param c a {@link forge.Card} object. * @param sa a {@link forge.card.spellability.SpellAbility} object. * @return a int. */ public int getMaxTargets(Card c, SpellAbility sa) { return AbilityFactory.calculateAmount(c, maxTargets, sa); } /** * <p>isMaxTargetsChosen.</p> * * @param c a {@link forge.Card} object. * @param sa a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ public boolean isMaxTargetsChosen(Card c, SpellAbility sa) { return choice != null && getMaxTargets(c, sa) == choice.getNumTargeted(); } /** * <p>isMinTargetsChosen.</p> * * @param c a {@link forge.Card} object. * @param sa a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ public boolean isMinTargetsChosen(Card c, SpellAbility sa) { if (getMinTargets(c, sa) == 0) return true; return choice != null && getMinTargets(c, sa) <= choice.getNumTargeted(); } private String tgtZone = Constant.Zone.Battlefield; /** * <p>setZone.</p> * * @param tZone a {@link java.lang.String} object. */ public void setZone(String tZone) { tgtZone = tZone; } /** * <p>getZone.</p> * * @return a {@link java.lang.String} object. */ public String getZone() { return tgtZone; } // Used for Counters. Currently, Spell,Activated,Triggered can be Comma-separated private String targetSpellAbilityType = null; /** * <p>Setter for the field <code>targetSpellAbilityType</code>.</p> * * @param tgtSAType a {@link java.lang.String} object. */ public void setTargetSpellAbilityType(String tgtSAType) { targetSpellAbilityType = tgtSAType; } /** * <p>Getter for the field <code>targetSpellAbilityType</code>.</p> * * @return a {@link java.lang.String} object. */ public String getTargetSpellAbilityType() { return targetSpellAbilityType; } // Used for Counters. The target SA of this SA must be targeting a Valid X private String saValidTargeting = null; /** * <p>setSAValidTargeting.</p> * * @param saValidTgting a {@link java.lang.String} object. */ public void setSAValidTargeting(String saValidTgting) { saValidTargeting = saValidTgting; } /** * <p>getSAValidTargeting.</p> * * @return a {@link java.lang.String} object. */ public String getSAValidTargeting() { return saValidTargeting; } // Leaving old structure behind for compatibility. /** * <p>addTarget.</p> * * @param o a {@link java.lang.Object} object. * @return a boolean. */ public boolean addTarget(Object o) { if (choice == null) choice = new Target_Choices(); if (o instanceof Card) return choice.addTarget((Card) o); if (o instanceof Player) return choice.addTarget((Player) o); if (o instanceof SpellAbility) return choice.addTarget((SpellAbility) o); return false; } /** * <p>getTargetCards.</p> * * @return a {@link java.util.ArrayList} object. */ public ArrayList<Card> getTargetCards() { if (choice == null) return new ArrayList<Card>(); return choice.getTargetCards(); } /** * <p>getTargetPlayers.</p> * * @return a {@link java.util.ArrayList} object. */ public ArrayList<Player> getTargetPlayers() { if (choice == null) return new ArrayList<Player>(); return choice.getTargetPlayers(); } /** * <p>getTargetSAs.</p> * * @return a {@link java.util.ArrayList} object. */ public ArrayList<SpellAbility> getTargetSAs() { if (choice == null) return new ArrayList<SpellAbility>(); return choice.getTargetSAs(); } /** * <p>getTargets.</p> * * @return a {@link java.util.ArrayList} object. */ public ArrayList<Object> getTargets() { if (choice == null) return new ArrayList<Object>(); return choice.getTargets(); } /** * <p>getNumTargeted.</p> * * @return a int. */ public int getNumTargeted() { if (choice == null) return 0; return choice.getNumTargeted(); } /** * <p>resetTargets.</p> */ public void resetTargets() { choice = null; } /** * <p>Constructor for Target.</p> * * @param src a {@link forge.Card} object. * @param parse a {@link java.lang.String} object. */ public Target(Card src, String parse) { this(src, parse, "1", "1"); } /** * <p>Constructor for Target.</p> * * @param src a {@link forge.Card} object. * @param parse a {@link java.lang.String} object. * @param min a {@link java.lang.String} object. * @param max a {@link java.lang.String} object. */ public Target(Card src, String parse, String min, String max) { // parse=Tgt{C}{P} - Primarily used for Pump or Damage // C = Creature P=Player/Planeswalker // CP = All three tgtValid = true; srcCard = src; if (parse.contains("Tgt")) { parse = parse.replace("Tgt", ""); } String valid; String prompt; StringBuilder sb = new StringBuilder(); if (parse.equals("CP")) { valid = "Creature,Planeswalker.YouDontCtrl,Player"; prompt = "Select target creature, planeswalker, or player"; } else if (parse.equals("C")) { valid = "Creature"; prompt = "Select target creature"; } else if (parse.equals("P")) { valid = "Planeswalker.YouDontCtrl,Player"; prompt = "Select target planeswalker or player"; } else { System.out.println("Bad Parsing in Target(parse, min, max): " + parse); return; } if (src != null) sb.append(src + " - "); sb.append(prompt); vtSelection = sb.toString(); ValidTgts = valid.split(","); minTargets = min; maxTargets = max; } /** * <p>Constructor for Target.</p> * * @param src a {@link forge.Card} object. * @param select a {@link java.lang.String} object. * @param valid an array of {@link java.lang.String} objects. */ public Target(Card src, String select, String[] valid) { this(src, select, valid, "1", "1"); } /** * <p>Constructor for Target.</p> * * @param src a {@link forge.Card} object. * @param select a {@link java.lang.String} object. * @param valid a {@link java.lang.String} object. */ public Target(Card src, String select, String valid) { this(src, select, valid.split(","), "1", "1"); } /** * <p>Constructor for Target.</p> * * @param src a {@link forge.Card} object. * @param select a {@link java.lang.String} object. * @param valid an array of {@link java.lang.String} objects. * @param min a {@link java.lang.String} object. * @param max a {@link java.lang.String} object. */ public Target(Card src, String select, String[] valid, String min, String max) { srcCard = src; tgtValid = true; vtSelection = select; ValidTgts = valid; minTargets = min; maxTargets = max; } /** * <p>getTargetedString.</p> * * @return a {@link java.lang.String} object. */ public String getTargetedString() { ArrayList<Object> tgts = getTargets(); StringBuilder sb = new StringBuilder(""); for (Object o : tgts) { if (o instanceof Player) { Player p = (Player) o; sb.append(p.getName()); } if (o instanceof Card) { Card c = (Card) o; sb.append(c); } sb.append(" "); } return sb.toString(); } /** * <p>canOnlyTgtOpponent.</p> * * @return a boolean. */ public boolean canOnlyTgtOpponent() { boolean player = false; boolean opponent = false; for (String s : ValidTgts) { if (s.equals("Opponent")) opponent = true; else if (s.equals("Player")) player = true; } return opponent && !player; } /** * <p>canTgtPlayer.</p> * * @return a boolean. */ public boolean canTgtPlayer() { for (String s : ValidTgts) { if (s.equals("Player") || s.equals("Opponent")) return true; } return false; } /** * <p>canTgtCreature.</p> * * @return a boolean. */ public boolean canTgtPermanent() { for (String s : ValidTgts) { if (s.contains("Permanent")) return true; } return false; } public boolean canTgtCreature() { for (String s : ValidTgts) { if (s.contains("Creature") && !s.contains("nonCreature")) return true; } return false; } /** * <p>canTgtCreatureAndPlayer.</p> * * @return a boolean. */ public boolean canTgtCreatureAndPlayer() { return canTgtPlayer() && canTgtCreature(); } /** * <p>hasCandidates.</p> * * @return a boolean. */ public boolean hasCandidates() { if (canTgtPlayer()) { return true; } for (Card c : AllZoneUtil.getCardsInZone(tgtZone, AllZone.getHumanPlayer())) { if (c.isValidCard(ValidTgts, srcCard.getController(), srcCard) && CardFactoryUtil.canTarget(srcCard, c)) { return true; } } for (Card c : AllZoneUtil.getCardsInZone(tgtZone, AllZone.getComputerPlayer())) { if (c.isValidCard(ValidTgts, srcCard.getController(), srcCard) && CardFactoryUtil.canTarget(srcCard, c)) { return true; } } return false; } }