**** Note: If you write card codeblocks, please be aware that "TgtV" Target constructor is no longer used. Use Target(String message, String[] Valid) instead.

- Changing Target class to always use ValidCards, converted older keywords to follow the new format. 
- Added AF_Tap, converted Burst of Energy and Mind Games
This commit is contained in:
jendave
2011-08-06 10:26:27 +00:00
parent a449eb5a6b
commit 961d74e6a4
12 changed files with 291 additions and 508 deletions

View File

@@ -2,7 +2,7 @@ Name:Burst of Energy
ManaCost:W
Types:Instant
Text:no text
K:spUntapTgt:Permanent:Untap target permanent.
A:SP$Untap|Cost$W|TgtPrompt$Choose target permanent|ValidTgts$Permanent|SpellDescription$Untap target Permanent.
SVar:RemAIDeck:True
SVar:Rarity:Common
SVar:Picture:http://www.wizards.com/global/images/magic/general/burst_of_energy.jpg

View File

@@ -2,7 +2,7 @@ Name:Mind Games
ManaCost:U
Types:Instant
Text:no text
K:spTapTgt:Artifact,Creature,Land:Tap target artifact, creature, or land.
A:SP$Tap|Cost$U|TgtPrompt$Choose target artifact, creature or land|ValidTgts$Artifact,Creature,Land|SpellDescription$Tap target artifact, creature or land.
SVar:Buyback:2 U
SVar:RemAIDeck:True
SVar:Rarity:Common

View File

@@ -136,10 +136,14 @@ public class AbilityFactory {
if (isTargeted)
{
int min = mapParams.containsKey("TargetMin") ? Integer.parseInt(mapParams.get("TargetMin")) : 1;
int max = mapParams.containsKey("TargetMax") ? Integer.parseInt(mapParams.get("TargetMax")) : 1;
if (hasValid)
abTgt = new Target("TgtV", mapParams.get("TgtPrompt"), mapParams.get("ValidTgts").split(","));
abTgt = new Target(mapParams.get("TgtPrompt"), mapParams.get("ValidTgts").split(","), min, max);
else
abTgt = new Target(mapParams.get("Tgt"));
abTgt = new Target(mapParams.get("Tgt"), min, max);
if (mapParams.containsKey("TgtZone")) // if Targeting something not in play, this Key should be set
abTgt.setZone(mapParams.get("TgtZone"));
}
@@ -251,6 +255,14 @@ public class AbilityFactory {
}
}
if (API.equals("Tap")){
if (isAb)
SA = AbilityFactory_PermanentState.createAbilityTap(this);
if (isSp){
SA = AbilityFactory_PermanentState.createSpellTap(this);
}
}
if (API.equals("Regenerate")){
if (isAb)
SA = AbilityFactory_Regenerate.getAbility(this);

View File

@@ -176,7 +176,8 @@ public class AbilityFactory_DealDamage {
else if (AF.isSpell())
rr = true;
if(AF.getAbTgt().canTgtCreaturePlayer()) {
// TODO: Consider targeting the planeswalker
if(AF.getAbTgt().canTgtCreatureAndPlayer()) {
if(shouldTgtP(damage)) {
saMe.setTargetPlayer(AllZone.HumanPlayer);
return rr;

View File

@@ -171,8 +171,8 @@ public class AbilityFactory_Fetch {
// Fetching should occur fairly often as it helps cast more spells, and have access to more mana
Ability_Cost abCost = af.getAbCost();
Card source = af.getHostCard();
HashMap<String,String> params = af.getMapParams();
String destination = params.get("Destination");
//HashMap<String,String> params = af.getMapParams();
//String destination = params.get("Destination");
if (abCost != null){
// AI currently disabled for these costs

View File

@@ -4,6 +4,7 @@ import java.util.HashMap;
import java.util.Random;
public class AbilityFactory_PermanentState {
// Untapping
public static SpellAbility createAbilityUntap(final AbilityFactory AF){
final SpellAbility abUntap = new Ability_Activated(AF.getHostCard(), AF.getAbCost(), AF.getAbTgt()){
private static final long serialVersionUID = 5445572699000471299L;
@@ -89,17 +90,7 @@ public class AbilityFactory_PermanentState {
untapList = untapList.getTargetableCards(source);
untapList = untapList.filter(AllZoneUtil.tapped);
if (tgt.canTgtCreature()){
untapList = untapList.getType("Creature");
if (untapList.size() == 0)
return false;
Card c = CardFactoryUtil.AI_getBestCreature(untapList);
if (c != null)
sa.setTargetCard(c);
}
else if (tgt.canTgtValid()){
if (tgt.doesTarget()){
untapList = untapList.getValidCards(tgt.getValidTgts(), source.getController());
if (untapList.size() == 0)
@@ -149,4 +140,145 @@ public class AbilityFactory_PermanentState {
CardFactoryUtil.doDrawBack(DrawBack, 0, card.getController(), card.getController().getOpponent(), card.getController(), card, null, sa);
}
// ****** Tapping ********
public static SpellAbility createAbilityTap(final AbilityFactory AF){
final SpellAbility abTap = new Ability_Activated(AF.getHostCard(), AF.getAbCost(), AF.getAbTgt()){
private static final long serialVersionUID = 5445572699000471299L;
final AbilityFactory af = AF;
@Override
public String getStackDescription(){
// when getStackDesc is called, just build exactly what is happening
StringBuilder sb = new StringBuilder("Untap ");
String name = af.getHostCard().getName();
Card tgt = getTargetCard();
if (tgt != null)
sb.append(tgt.getName());
else
sb.append(name);
return sb.toString();
}
public boolean canPlay(){
// super takes care of AdditionalCosts
return super.canPlay();
}
public boolean canPlayAI()
{
return tapCanPlayAI(af,this);
}
@Override
public void resolve() {
tapResolve(af, this);
}
};
return abTap;
}
public static SpellAbility createSpellTap(final AbilityFactory AF){
final SpellAbility spTap = new Spell(AF.getHostCard(), AF.getAbCost(), AF.getAbTgt()){
private static final long serialVersionUID = -4990932993654533449L;
final AbilityFactory af = AF;
public boolean canPlay(){
// super takes care of AdditionalCosts
return super.canPlay();
}
public boolean canPlayAI()
{
return tapCanPlayAI(af, this);
}
@Override
public void resolve() {
tapResolve(af, this);
}
};
return spTap;
}
public static boolean tapCanPlayAI(final AbilityFactory af, SpellAbility sa){
// AI cannot use this properly until he can use SAs during Humans turn
if (!ComputerUtil.canPayCost(sa))
return false;
Target tgt = af.getAbTgt();
Card source = sa.getSourceCard();
Random r = new Random();
boolean randomReturn = r.nextFloat() <= Math.pow(.6667, source.getAbilityUsed());
if (tgt == null){
if (sa.getSourceCard().isTapped())
return false;
}
else{
CardList tapList = AllZoneUtil.getPlayerCardsInPlay(AllZone.HumanPlayer);
tapList = tapList.getTargetableCards(source);
tapList = tapList.filter(AllZoneUtil.untapped);
if (tgt.doesTarget()){
tapList = tapList.getValidCards(tgt.getValidTgts(), source.getController());
if (tapList.size() == 0)
return false;
Card c = null;
CardList dChoices = new CardList();
String[] Tgts = tgt.getValidTgts();
for(int i = 0; i < Tgts.length; i++) {
if (Tgts[i].startsWith("Creature")) {
c = CardFactoryUtil.AI_getBestCreature(tapList);
if (c != null)
dChoices.add(c);
}
CardListUtil.sortByTextLen(tapList);
dChoices.add(tapList.get(0));
CardListUtil.sortCMC(tapList);
dChoices.add(tapList.get(0));
}
c = dChoices.get(CardUtil.getRandomIndex(dChoices));
sa.setTargetCard(c);
}
}
return randomReturn;
}
public static void tapResolve(final AbilityFactory af, final SpellAbility sa){
HashMap<String,String> params = af.getMapParams();
Card card = sa.getSourceCard();
Card target = sa.getTargetCard();
if (af.getAbTgt() == null)
card.tap();
else if(AllZone.GameAction.isCardInPlay(target) && CardFactoryUtil.canTarget(card, target))
target.tap();
else // Fizzle?
return;
String DrawBack = params.get("SubAbility");
if (af.hasSubAbility())
CardFactoryUtil.doDrawBack(DrawBack, 0, card.getController(), card.getController().getOpponent(), card.getController(), card, null, sa);
}
// Untap All/Tap All
//Phasing? Something else? Who knows!
}

View File

@@ -1655,7 +1655,6 @@ public class CardFactory implements NewConstants {
String k[] = parse.split(":");
String tmpCost[] = k[0].replace("abAllPump", "").split(" ", 2);
final Target abTgt = new Target(tmpCost[0]);
final Ability_Cost abCost = new Ability_Cost(tmpCost[1], card.getName(), true);
final String Scope[] = k[1].split("/");
@@ -1739,7 +1738,7 @@ public class CardFactory implements NewConstants {
}
}
SpellAbility abAllPump = new Ability_Activated(card, abCost, abTgt)
SpellAbility abAllPump = new Ability_Activated(card, abCost, null)
{
private static final long serialVersionUID = 7783282947592874L;
@@ -1921,7 +1920,13 @@ public class CardFactory implements NewConstants {
final boolean bPumpEquipped = (tmpCost[0].equals("Equipped"));
final Target abTgt = new Target(tmpCost[0]);
final Target abTgt;
if (tmpCost[0].equals("TgtC"))
abTgt = new Target(tmpCost[0]);
else
abTgt = null;
final Ability_Cost abCost = new Ability_Cost(tmpCost[1], card.getName(), true);
final int NumAttack[] = {-1138};
@@ -1985,7 +1990,7 @@ public class CardFactory implements NewConstants {
String d = "none";
StringBuilder sbD = new StringBuilder();
if(abTgt.doesTarget())
if(abTgt != null && abTgt.doesTarget())
sbD.append("Target creature");
else if (bPumpEquipped)
sbD.append("Equipped creature");
@@ -2111,7 +2116,7 @@ public class CardFactory implements NewConstants {
if(AllZone.Phase.getPhase().equals(Constant.Phase.Main2)) return false;
if(!abTgt.doesTarget()) {
if(abTgt == null) {
Card creature;
if (bPumpEquipped)
creature = card.getEquippingCard();
@@ -2183,7 +2188,7 @@ public class CardFactory implements NewConstants {
@Override
public void resolve() {
final Card[] creature = new Card[1];
if(abTgt.doesTarget())
if(abTgt != null && abTgt.doesTarget())
creature[0] = getTargetCard();
else if (bPumpEquipped)
creature[0] = card.getEquippingCard();
@@ -2191,7 +2196,7 @@ public class CardFactory implements NewConstants {
creature[0] = card;
if(creature[0] != null && AllZone.GameAction.isCardInPlay(creature[0])
&& (!abTgt.doesTarget() || CardFactoryUtil.canTarget(card, getTargetCard()))) {
&& (abTgt == null || CardFactoryUtil.canTarget(card, getTargetCard()))) {
final int a = getNumAttack();
final int d = getNumDefense();
@@ -2238,9 +2243,6 @@ public class CardFactory implements NewConstants {
ability.setDescription(spDesc[0]);
ability.setStackDescription(stDesc[0]);
if(!abTgt.doesTarget())
ability.setTargetCard(card);
card.addSpellAbility(ability);
}
}//while
@@ -2685,14 +2687,15 @@ public class CardFactory implements NewConstants {
int drawBack = 2;
final Target abTgt = new Target(tmpCost[0]);
if (abTgt.canTgtValid()){
// TODO: These can do for some converting for an improved message box
final Target abTgt;
if (tmpCost[0].contains("TgtV")){
int valid = drawBack;
// Looks like VTSelection is used for the Message box, should improve the message
abTgt.setVTSelection("Select a target: " + k[valid]);
abTgt.setValidTgts(k[valid].split(","));
abTgt = new Target("Select a target: " + k[valid], k[valid].split(","));
drawBack++;
}
else
abTgt = new Target(tmpCost[0]);
final Ability_Cost abCost = new Ability_Cost(tmpCost[1], card.getName(), true);
@@ -2728,7 +2731,7 @@ public class CardFactory implements NewConstants {
sb.append(card.getName());
sb.append(" deals " + NumDmg[0] + " damage to ");
sb.append(abTgt.targetString());
sb.append(abTgt.getVTSelection());
spDesc[0] = sb.toString();
stDesc[0] = card.getName() + " -" + sb.toString();
}
@@ -2818,7 +2821,7 @@ public class CardFactory implements NewConstants {
if(r.nextFloat() <= Math.pow(.6667, card.getAbilityUsed()))
rr = true;
if(abTgt.canTgtCreaturePlayer()) {
if(abTgt.canTgtCreatureAndPlayer()) {
if(shouldTgtP()) {
setTargetPlayer(AllZone.HumanPlayer);
return rr;
@@ -3041,9 +3044,7 @@ public class CardFactory implements NewConstants {
String tmpCost = k[0].substring(13);
final Ability_Cost abCost = new Ability_Cost(tmpCost, card.getName(), true);
final Target tgtDstryTgt = new Target("TgtV");
final String Tgts[] = k[1].split(",");
tgtDstryTgt.setValidTgts(Tgts);
final boolean NoRegen[] = {false};
final String Drawback[] = {"none"};
@@ -3074,8 +3075,9 @@ public class CardFactory implements NewConstants {
String tmpDesc = spDesc[0].substring(15);
int i = tmpDesc.indexOf(".");
tmpDesc = tmpDesc.substring(0, i);
//final String Selec = "Select target " + tmpDesc + " to destroy.";
tgtDstryTgt.setVTSelection("Select target " + tmpDesc + " to destroy.");
String Selec = "Select target " + tmpDesc + " to destroy.";
final Target tgtDstryTgt = new Target(Selec, Tgts);
spDesc[0] = abCost.toString() + spDesc[0];
@@ -4563,10 +4565,7 @@ public class CardFactory implements NewConstants {
if (tmpCost[0].equals(""))
abTgt = null;
else{
//abTgt = new Target(tmpCost[0]);
//abTgt.setValidTgts("player".split(","));
//abTgt.setVTSelection("Target a player to draw cards");
abTgt = new Target("TgtP");
abTgt = new Target("Target a player to draw cards", "player".split(","));
}
final Ability_Cost abCost = new Ability_Cost(tmpCost[1], card.getName(), true);
@@ -4952,9 +4951,7 @@ public class CardFactory implements NewConstants {
if (tmpCost[0].equals(""))
abTgt = null;
else{
abTgt = new Target(tmpCost[0]+"V");
abTgt.setValidTgts("player".split(","));
abTgt.setVTSelection("Target a player to lose life");
abTgt = new Target("Target a player to lose life", "player".split(","));
}
final Ability_Cost abCost = new Ability_Cost(tmpCost[1], card.getName(), true);
@@ -5241,9 +5238,7 @@ public class CardFactory implements NewConstants {
if (tmpCost[0].equals(""))
abTgt = null;
else{
abTgt = new Target(tmpCost[0]);
abTgt.setValidTgts(k[1].split(","));
abTgt.setVTSelection("Target a player to gain life");
abTgt = new Target("Target a player to gain life", k[1].split(","));
inc++;
}
@@ -6362,16 +6357,19 @@ public class CardFactory implements NewConstants {
String tmpCost = k[0].substring(8);
final Ability_Cost abCost = new Ability_Cost(tmpCost, card.getName(), true);
final Target tapTargets = new Target("TgtV");
final String Tgts[] = k[1].split(",");
tapTargets.setValidTgts(Tgts);
final String abDesc[] = {"none"};
abDesc[0] = k[2];
String tmpDesc = abDesc[0].substring(11);
int i = tmpDesc.indexOf(".");
tmpDesc = tmpDesc.substring(0, i);
tapTargets.setVTSelection("Select target " + tmpDesc + " to tap.");
StringBuilder vtDesc = new StringBuilder();
vtDesc.append("Select target ").append(tmpDesc).append(" to tap.");
final Target tapTargets = new Target(vtDesc.toString(), Tgts);
abDesc[0] = abCost.toString() + abDesc[0];
@@ -6650,16 +6648,19 @@ public class CardFactory implements NewConstants {
String tmpCost = k[0].substring(10);
final Ability_Cost abCost = new Ability_Cost(tmpCost, card.getName(), true);
final Target untapTargets = new Target("TgtV");
final String Tgts[] = k[1].split(",");
untapTargets.setValidTgts(Tgts);
final String abDesc[] = {"none"};
abDesc[0] = k[2];
String tmpDesc = abDesc[0].substring(13);
int i = tmpDesc.indexOf(".");
tmpDesc = tmpDesc.substring(0, i);
untapTargets.setVTSelection("Select target " + tmpDesc + " to untap.");
StringBuilder vtDesc = new StringBuilder();
vtDesc.append("Select target ").append(tmpDesc).append(" to untap.");
final Target untapTargets = new Target(vtDesc.toString(), Tgts);
abDesc[0] = abCost.toString() + abDesc[0];
@@ -6748,123 +6749,6 @@ public class CardFactory implements NewConstants {
card.addSpellAbility(AbUntapTgt);
}//End abUntapTgt
/*
* Generic tap target ___ spell
*
* syntax: spTapTgt:{Valid Targets}:{Description}
*/
if (hasKeyword(card, "spTapTgt") != -1) {
int n = hasKeyword(card, "spTapTgt");
String parse = card.getKeyword().get(n).toString();
card.removeIntrinsicKeyword(parse);
String k[] = parse.split(":");
final Target tapTargets = new Target("TgtV");
final String Tgts[] = k[1].split(",");
tapTargets.setValidTgts(Tgts);
final String spDesc[] = {"none"};
spDesc[0] = k[2];
String tmpDesc = spDesc[0].substring(11);
int i = tmpDesc.indexOf(".");
tmpDesc = tmpDesc.substring(0, i);
String Selec = "Select target " + tmpDesc + " to tap.";
card.clearSpellAbility();
final SpellAbility SpTapTgt = new Spell(card) {
private static final long serialVersionUID = 6956356114247328396L;
@Override
public boolean canPlayAI() {
CardList hCards = getTargets();
Random r = new Random();
boolean rr = false;
if (r.nextFloat() <= .6667)
rr = true;
if(hCards.size() > 0) {
Card c = null;
CardList dChoices = new CardList();
for(int i = 0; i < Tgts.length; i++) {
if (Tgts[i].startsWith("Creature")) {
c = CardFactoryUtil.AI_getBestCreature(hCards);
if (c != null)
dChoices.add(c);
}
CardListUtil.sortByTextLen(hCards);
dChoices.add(hCards.get(0));
CardListUtil.sortCMC(hCards);
dChoices.add(hCards.get(0));
}
c = dChoices.get(CardUtil.getRandomIndex(dChoices));
setTargetCard(c);
return rr;
}
return false;
}
CardList getTargets() {
CardList tmpList = AllZoneUtil.getPlayerCardsInPlay(AllZone.HumanPlayer);
tmpList = tmpList.getValidCards(Tgts, card.getController());
tmpList = tmpList.getTargetableCards(card);
tmpList = tmpList.filter(AllZoneUtil.untapped);
return tmpList;
}
/*
@Override
public boolean canPlay() {
return (CardFactoryUtil.canUseAbility(card) && super.canPlay());
}
*/
@Override
public void resolve() {
Card tgtC = getTargetCard();
if(AllZone.GameAction.isCardInPlay(tgtC)
&& CardFactoryUtil.canTarget(card, tgtC)) {
tgtC.tap();
}
}
}; //SpTapTgt
Input InGetTarget = CardFactoryUtil.input_targetValid(SpTapTgt, Tgts, Selec);
SpTapTgt.setBeforePayMana(InGetTarget);
SpTapTgt.setDescription(spDesc[0]);
card.addSpellAbility(SpTapTgt);
card.setSVar("PlayMain1", "TRUE");
String bbCost = card.getSVar("Buyback");
if (!bbCost.equals(""))
{
SpellAbility bbDstryTgt = SpTapTgt.copy();
bbDstryTgt.setManaCost(CardUtil.addManaCosts(card.getManaCost(), bbCost));
StringBuilder sb = new StringBuilder();
sb.append("Buyback ").append(bbCost).append(" (You may pay an additional ").append(bbCost);
sb.append(" as you cast this spell. If you do, put this card into your hand as it resolves.)");
bbDstryTgt.setDescription(sb.toString());
// bbDstryTgt.setDescription("Buyback " + bbCost + "(You may pay an additional " + bbCost + " as you cast this spell. If you do, put this card into your hand as it resolves.)");
bbDstryTgt.setIsBuyBackAbility(true);
bbDstryTgt.setBeforePayMana(CardFactoryUtil.input_targetValid(bbDstryTgt, Tgts, Selec));
card.addSpellAbility(bbDstryTgt);
}
}//End spTapTgt
/*
* Generic untap all targets spell
@@ -6879,11 +6763,10 @@ public class CardFactory implements NewConstants {
String k[] = parse.split(":");
final Target untapTargets = new Target("TgtV");
String Targets = k[1];
final String Tgts[] = Targets.split(",");
untapTargets.setValidTgts(Tgts);
final String spDesc[] = {"none"};
final String stackDesc[] = {"none"};
stackDesc[0] = k[2];
@@ -6965,98 +6848,6 @@ public class CardFactory implements NewConstants {
card.setSVar("PlayMain1", "TRUE");
}//End spUntapAll keyword
/*
* Generic untap target ___ spell
*
* syntax: spUntapTgt:{Valid Targets}:{Description}
*/
if (hasKeyword(card, "spUntapTgt") != -1) {
int n = hasKeyword(card, "spUntapTgt");
String parse = card.getKeyword().get(n).toString();
card.removeIntrinsicKeyword(parse);
String k[] = parse.split(":");
final Target untapTargets = new Target("TgtV");
final String Tgts[] = k[1].split(",");
untapTargets.setValidTgts(Tgts);
final String spDesc[] = {"none"};
spDesc[0] = k[2];
String tmpDesc = spDesc[0].substring(13);
int i = tmpDesc.indexOf(".");
tmpDesc = tmpDesc.substring(0, i);
String Selec = "Select target " + tmpDesc + " to untap.";
final SpellAbility SpUntapTgt = new Spell(card) {
private static final long serialVersionUID = 1740994300027185986L;
@Override
public boolean canPlayAI() {
/*CardList hCards = getTargets();
Random r = new Random();
boolean rr = false;
if (r.nextFloat() <= .6667)
rr = true;
if(hCards.size() > 0) {
Card c = null;
CardList dChoices = new CardList();
for(int i = 0; i < Tgts.length; i++) {
if (Tgts[i].startsWith("Creature")) {
c = CardFactoryUtil.AI_getBestCreature(hCards);
if (c != null)
dChoices.add(c);
}
CardListUtil.sortByTextLen(hCards);
dChoices.add(hCards.get(0));
CardListUtil.sortCMC(hCards);
dChoices.add(hCards.get(0));
}
c = dChoices.get(CardUtil.getRandomIndex(dChoices));
setTargetCard(c);
return rr;
}
*/
return false;
}
/*
CardList getTargets() {
CardList tmpList = AllZoneUtil.getPlayerCardsInPlay(AllZone.HumanPlayer);
tmpList = tmpList.getValidCards(Tgts);
tmpList = tmpList.getTargetableCards(card);
tmpList = tmpList.filter(AllZoneUtil.untapped);
return tmpList;
}*/
@Override
public void resolve() {
Card tgtC = getTargetCard();
if(AllZone.GameAction.isCardInPlay(tgtC)
&& CardFactoryUtil.canTarget(card, tgtC)) {
tgtC.untap();
}
}
}; //SpUntapTgt
card.clearSpellAbility();
Input InGetTarget = CardFactoryUtil.input_targetValid(SpUntapTgt, Tgts, Selec);
SpUntapTgt.setBeforePayMana(InGetTarget);
SpUntapTgt.setDescription(spDesc[0]);
card.addSpellAbility(SpUntapTgt);
card.setSVar("PlayMain1", "TRUE");
}//End spUntapTgt
if (hasKeyword(card, "Flashback") != -1) {
int n = hasKeyword(card, "Flashback");
if (n != -1) {
@@ -8601,7 +8392,7 @@ public class CardFactory implements NewConstants {
else if(cardName.equals("AEther Spellbomb")) {
Ability_Cost abCost = new Ability_Cost("U Sac<1/CARDNAME>", cardName, true);
String[] valid = {"Creature"};
Target abTgt = new Target("TgtV", "Target a creature to bounce", valid);
Target abTgt = new Target("Target a creature to bounce", valid);
final Ability_Activated ability = new Ability_Activated(card, abCost, abTgt) {
private static final long serialVersionUID = 1L;
@@ -8643,7 +8434,7 @@ public class CardFactory implements NewConstants {
else if(cardName.equals("Lifespark Spellbomb")) {
Ability_Cost abCost = new Ability_Cost("G Sac<1/CARDNAME>", cardName, true);
String[] valid = {"Land"};
Target abTgt = new Target("TgtV", "Target a land to animate", valid);
Target abTgt = new Target("Target a land to animate", valid);
final Ability_Activated ability = new Ability_Activated(card, abCost, abTgt) {
private static final long serialVersionUID = -5744842090293912606L;
@@ -8711,7 +8502,7 @@ public class CardFactory implements NewConstants {
else if(cardName.equals("Necrogen Spellbomb")) {
Ability_Cost abCost = new Ability_Cost("B Sac<1/CARDNAME>", cardName, true);
String[] valid = {"player"};
Target abTgt = new Target("TgtV","Target player discards a card", valid);
Target abTgt = new Target("Target player discards a card", valid);
final Ability_Activated ability = new Ability_Activated(card, abCost, abTgt) {
private static final long serialVersionUID = -5712428914792877529L;
@@ -9041,7 +8832,7 @@ public class CardFactory implements NewConstants {
else if(cardName.equals("Volrath's Dungeon")) {
Ability_Cost dungeonCost = new Ability_Cost("Discard<1/Any>", cardName, true);
Target dungeonTgt = new Target("TgtV", "Volrath's Dungeon - Target player" , "player".split(","));
Target dungeonTgt = new Target("Volrath's Dungeon - Target player" , "player".split(","));
final SpellAbility dungeon = new Ability_Activated(card, dungeonCost, dungeonTgt){
private static final long serialVersionUID = 334033015590321821L;
@@ -9649,7 +9440,7 @@ public class CardFactory implements NewConstants {
final String[] Tgts = { "Creature.nonArtifact" };
Ability_Cost abCost = new Ability_Cost("T Sac<1/CARDNAME>", cardName, true);
Target abTgt = new Target("TgtV", "Target a non-Artifact Creature to Transmogrify", Tgts);
Target abTgt = new Target("Target a non-Artifact Creature to Transmogrify", Tgts);
final Ability_Activated ability = new Ability_Activated(card, abCost, abTgt){
private static final long serialVersionUID = -401631574059431293L;
@@ -11658,10 +11449,8 @@ public class CardFactory implements NewConstants {
//*************** START *********** START **************************
else if(cardName.equals("Barl's Cage")) {
Target target = new Target("TgtV");
target.setVTSelection("Select target creature.");
final String Tgts[] = {"Creature"};
target.setValidTgts(Tgts);
Target target= new Target("Select target creature.", Tgts, 1, 1);
final Ability_Cost cost = new Ability_Cost("3", card.getName(), true);

View File

@@ -3394,9 +3394,7 @@ public class CardFactoryUtil {
Target tgt = ability.getTarget();
if (tgt != null){
// Reconfirm the Validity of a TgtValid, or if the Creature is still a Creature
if (tgt.canTgtValid() && !target.isValidCard(tgt.getValidTgts(), ability.getActivatingPlayer()))
return false;
else if (tgt.canTgtCreature() && !target.isCreature())
if (tgt.doesTarget() && !target.isValidCard(tgt.getValidTgts(), ability.getActivatingPlayer(), ability.getSourceCard()))
return false;
// Check if the target is in the zone it needs to be in to be targeted

View File

@@ -1556,7 +1556,7 @@ class CardFactory_Auras {
};//addSpellAbility
// Target AbCost and Restriction are set here to get this working as expected
Target tgt = new Target("TgtV", "Select a creature in a graveyard", "Creature".split(","));
Target tgt = new Target("Select a creature in a graveyard", "Creature".split(","));
tgt.setZone(Constant.Zone.Graveyard);
animate.setTarget(tgt);

View File

@@ -13910,7 +13910,7 @@ public class CardFactory_Creatures {
else if(cardName.equals("Tradewind Rider")) {
String select = "Select target permanent to return to owner's hand.";
final String Tgts[] = {"Permanent"};
Target target = new Target("TgtV", select, Tgts);
Target target = new Target(select, Tgts);
final Ability_Cost cost = new Ability_Cost("T tapXType<2/Creature>", card.getName(), true);
@@ -20416,7 +20416,7 @@ public class CardFactory_Creatures {
//*************** START *********** START **************************
else if(cardName.equals("Singing Tree")) {
final String Tgts[] = {"Creature.attacking"};
Target target = new Target("TgtV", "Select target attacking creature.", Tgts);
Target target = new Target("Select target attacking creature.", Tgts);
final Ability_Cost cost = new Ability_Cost("T", card.getName(), true);
@@ -20657,7 +20657,7 @@ public class CardFactory_Creatures {
//*************** START *********** START **************************
else if(cardName.equals("Witch Hunter")) {
final String Tgts[] = {"Creature+YouDontCtrl"};
Target target = new Target("TgtV", "Select target creature you don't control.", Tgts);
Target target = new Target("Select target creature you don't control.", Tgts);
final Ability_Cost abCost = new Ability_Cost("1 W W T", card.getName(), true);
final SpellAbility ability = new Ability_Activated(card, abCost, target) {

View File

@@ -1,31 +1,23 @@
package forge;
public class Target {
private boolean tgtPlayer = false;
public boolean canTgtPlayer() { return tgtPlayer; }
private boolean tgtCreature = false;
public boolean canTgtCreature() { return tgtCreature; }
public boolean canTgtCreaturePlayer() { return tgtCreature && tgtPlayer; }
public boolean doesTarget() { return tgtCreature || tgtPlayer || tgtValid; }
private boolean tgtValid = false;
private String ValidTgts[];
private String vtSelection = "";
public boolean canTgtValid() { return tgtValid; }
public boolean doesTarget() { return tgtValid; }
public String[] getValidTgts() { return ValidTgts; }
public void setValidTgts(String vTgts[]) { ValidTgts = vTgts; }
public String getVTSelection() { return vtSelection; }
public void setVTSelection(String vtSelStr) { vtSelection = vtSelStr; }
private int minTargets = 1;
public int getMinTargets() { return minTargets; }
private int maxTargets = 1;
public int getMaxTargets() { return maxTargets; }
private String tgtZone = Constant.Zone.Play;
public void setZone(String tZone) { tgtZone = tZone; }
public String getZone() { return tgtZone; }
private int minTargets = 0;
public int getMinTargets() { return minTargets; }
private int maxTargets = 0;
public int getMaxTargets() { return maxTargets; }
// add array of targets here?
private int numTargeted = 0;
@@ -34,82 +26,76 @@ public class Target {
public void resetTargets() { numTargeted = 0; }
public Target(String parse){
if (parse.contains("Tgt")){
// Tgt{C}{P}[/<MinTargets>/<MaxTargets>] min-max is optional
String tgtStr = parse.replace("Tgt", "");
String[] tgtSplit = tgtStr.split("/");
if (tgtSplit[0].contains("C")) // creature
tgtCreature = true;
if (tgtSplit[0].contains("P")) // player
tgtPlayer = true;
if (tgtSplit[0].contains("V")) // valid
tgtValid = true;
if (tgtSplit.length != 3){
minTargets = 1;
maxTargets = 1;
}
else{
minTargets = Integer.parseInt(tgtSplit[1]);
maxTargets = Integer.parseInt(tgtSplit[2]);
}
}
}
public Target(String parse, String select, String[] valid){
if (parse.contains("Tgt")){
// Tgt{C}{P}{V}[/<MinTargets>/<MaxTargets>] min-max is optional
String tgtStr = parse.replace("Tgt", "");
String[] tgtSplit = tgtStr.split("/");
if (tgtSplit[0].contains("C")) // creature
tgtCreature = true;
if (tgtSplit[0].contains("P")) // player
tgtPlayer = true;
if (tgtSplit[0].contains("V")) // valid
tgtValid = true;
if (tgtSplit.length != 3){
minTargets = 1;
maxTargets = 1;
}
else{
minTargets = Integer.parseInt(tgtSplit[1]);
maxTargets = Integer.parseInt(tgtSplit[2]);
}
if (tgtValid){
vtSelection = select;
ValidTgts = valid;
}
}
this(parse, 1, 1);
}
public Target(String parse, int min, int max){
minTargets = min;
maxTargets = max;
// parse=Tgt{C}{P} - Primarily used for Pump or Damage
// C = Creature P=Player/Planeswalker
// CP = All three
tgtValid = true;
ValidTgts = parse.split(",");
if (parse.contains("Tgt")){
parse = parse.replace("Tgt", "");
}
public String targetString()
{
StringBuilder sb = new StringBuilder("target ");
String valid;
String prompt;
if (tgtCreature)
sb.append("creature");
if (tgtPlayer){
if (tgtCreature)
sb.append(" or ");
sb.append("player");
if (parse.equals("CP")){
valid = "Creature,Planeswalker,Player";
prompt = "Select target creature, planeswalker, or player";
}
if (tgtValid){
sb.append(vtSelection);
else if (parse.equals("C")){
valid = "Creature";
prompt = "Select target creature";
}
else if (parse.equals("P")){
valid = "Planeswalker,Player";
prompt = "Select target planeswalker or player";
}
else{
System.out.println("Bad Parsing in Target(parse, min, max)");
return;
}
sb.append(".");
return sb.toString();
vtSelection = prompt;
ValidTgts = valid.split(",");
minTargets = min;
maxTargets = max;
}
public Target(String select, String[] valid){
this(select, valid, 1, 1);
}
public Target(String select, String[] valid, int min, int max){
tgtValid = true;
vtSelection = select;
ValidTgts = valid;
minTargets = min;
maxTargets = max;
}
// These below functions are quite limited to the damage classes, we should find a way to move them into AF_DealDamage
public boolean canTgtPlayer() {
for(String s: ValidTgts){
if (s.equals("Player"))
return true;
}
return false;
}
public boolean canTgtCreature() {
for(String s: ValidTgts){
if (s.contains("Creature") && !s.contains("nonCreature"))
return true;
}
return false;
}
public boolean canTgtCreatureAndPlayer() { return canTgtPlayer() && canTgtCreature(); }
}

View File

@@ -54,13 +54,6 @@ public class Target_Selection {
// if we haven't reached minimum targets, or we're still less than Max targets keep choosing
// targeting, with forward code for multiple target abilities
if (!bDoneTarget && target.getMinTargets() > 0 && target.getNumTargeted() < target.getMaxTargets()){
if (target.canTgtCreature() && target.canTgtPlayer())
changeInput.stopSetNext(targetCreaturePlayer(ability, Command.Blank, true, this, req));
else if(target.canTgtCreature())
changeInput.stopSetNext(targetCreature(ability, this, req));
else if(target.canTgtPlayer())
changeInput.stopSetNext(targetPlayer(ability, this, req));
else if (target.canTgtValid())
changeInput.stopSetNext(input_targetValid(ability, target.getValidTgts(), target.getVTSelection(), this, req));
return false;
}
@@ -68,134 +61,6 @@ public class Target_Selection {
return true;
}
public static Input targetCreaturePlayer(final SpellAbility ability, final Command paid, final boolean targeted,
final Target_Selection select, final SpellAbility_Requirements req) {
Input target = new Input() {
private static final long serialVersionUID = 2781418414287281005L;
@Override
public void showMessage() {
AllZone.Display.showMessage("Select target Creature, Player, or Planeswalker");
// when multi targets (Arc Mage) are added, need this:
// if payment.targeted < mintarget only enable cancel
// else if payment.targeted < maxtarget enable cancel and ok
ButtonUtil.enableOnlyCancel();
}
@Override
public void selectButtonCancel() {
select.setCancel(true);
stop();
req.finishedTargeting();
}
@Override
public void selectButtonOK() {
select.setDoneTarget(true);
stop();
req.finishedTargeting();
}
@Override
public void selectCard(Card card, PlayerZone zone) {
if((card.isCreature() || card.isPlaneswalker()) && zone.is(Constant.Zone.Play)
&& (!targeted || CardFactoryUtil.canTarget(ability, card))) {
ability.setTargetCard(card);
done();
}
}//selectCard()
@Override
public void selectPlayer(Player player) {
ability.setTargetPlayer(player);
// if multitarget increment then select again
done();
}
void done() {
select.incrementTargets();
paid.execute();
stop();
req.finishedTargeting();
}
};
return target;
}//input_targetCreaturePlayer()
public static Input targetCreature(final SpellAbility ability, final Target_Selection select, final SpellAbility_Requirements req) {
Input target = new Input() {
private static final long serialVersionUID = 2781418414287281005L;
@Override
public void showMessage() {
AllZone.Display.showMessage("Select target Creature");
ButtonUtil.enableOnlyCancel();
}
@Override
public void selectButtonCancel() {
select.setCancel(true);
stop();
req.finishedTargeting();
}
@Override
public void selectCard(Card card, PlayerZone zone) {
if(card.isCreature() && zone.is(Constant.Zone.Play) && (CardFactoryUtil.canTarget(ability, card))) {
ability.setTargetCard(card);
done();
}
}//selectCard()
void done() {
select.incrementTargets();
stop();
req.finishedTargeting();
}
};
return target;
}//targetCreature()
public static Input targetPlayer(final SpellAbility ability, final Target_Selection select, final SpellAbility_Requirements req) {
Input target = new Input() {
private static final long serialVersionUID = 2781418414287281005L;
@Override
public void showMessage() {
AllZone.Display.showMessage("Select target Player or Planeswalker");
ButtonUtil.enableOnlyCancel();
}
@Override
public void selectButtonCancel() {
select.setCancel(true);
stop();
req.finishedTargeting();
}
@Override
public void selectCard(Card card, PlayerZone zone) {
if(card.isPlaneswalker() && zone.is(Constant.Zone.Play) && (!CardFactoryUtil.canTarget(ability, card))) {
ability.setTargetCard(card);
done();
}
}//selectCard()
@Override
public void selectPlayer(Player player) {
ability.setTargetPlayer(player);
done();
}
void done() {
select.incrementTargets();
stop();
req.finishedTargeting();
}
};
return target;
}//targetPlayer()
// 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
public static Input input_targetValid(final SpellAbility sa, final String[] Tgts, final String message,
@@ -213,7 +78,7 @@ public class Target_Selection {
if (zone.equals(Constant.Zone.Play)){
boolean canTargetPlayer = false;
for(String s : Tgts)
if (s.equals("player"))
if (s.equals("player") || s.equals("Player"))
canTargetPlayer = true;
stopSetNext(input_targetSpecific(sa, choices, message, true, canTargetPlayer, select, req));