spDestroyTgt keyword
Post MTG Forge Related Programming Questions Here
	Moderators: timmermac, Agetian, friarsol, Blacksmith, KrazyTheFox, CCGHQ Admins
			54 posts
			 • Page 2 of 4 • 1, 2, 3, 4
		
	
Re: spDestroyTgt keyword
 by MageKing17 » 05 Jul 2009, 21:33
by MageKing17 » 05 Jul 2009, 21:33 
I had some similar problems when creating the new match objects for Incantus (I wanted them to make their own description strings, so isCreature.isColor("U").isSubtype("Faerie").isSupertype("Legendary") would turn into "legendary blue Faerie creature"), and originally decided that if you wanted to use OR logic, you'd have to do things the hard way. Then Incantus had an idea that was something along the lines of:
			
		- Code: Select all
- isCreature.with(colors="U", subtypes="Faerie", supertypes="Legendary").or(colors="R", subtypes="Goblin", supertypes="Snow")
- 
				 
 MageKing17
- Programmer
- Posts: 473
- Joined: 12 Jun 2008, 20:40
- Has thanked: 5 times
- Been thanked: 9 times
Re: spDestroyTgt keyword
 by zerker2000 » 06 Jul 2009, 00:01
by zerker2000 » 06 Jul 2009, 00:01 
As much as I understand it, we already have a very efficient CardListFilter method that works with native java boolean logic, however I think the topic here is making an easily-parseable easily-writable keyword interface, e.g(for your example)
I just went through gatherer searching for "destroy target", got to about the E's, and it seems that an easy way to parse a bunch of oracle "spDestroyTgt" keywords would be: .
.
			- Code: Select all
- Goblin/Faerie Destruction
 Instant
 B
 no text
 spDestroyTgt: Legendary Blue Faerie Creature or Snow Red Goblin Creature
(OK maybe not the last one)Them Wizards wrote:Destroy target artifact or enchantment.
Destroy target creature with power 4 or greater
Destroy target artifact, creature, or land.
Destroy target red permanent.
Destroy target land or nonblack creature.
Destroy target non-Swamp land.
Destroy target tapped creature.
Destroy target Wall.
Destroy target noncreature permanent.
Destroy target creature that isn't enchanted.
<when deals cmbDmg to a player, you may>destroy target artifact that player controls.
Destroy target nonsnow creature;
Destroy target creature with a -1/-1 counter on it.
Destroy target Scarecrow or Plains.
Destroy target nonblack attacking creature.
Destroy target nonblack creature that came into play this turn.
Destroy target creature blocking or blocked by Cromat.
Destroy target Aura attached to a creature.
Destroy target creature token.
Destroy target creature <you/an opponent> controls.
Destroy target artifact, creature, or land you control.
Destroy target non-Zombie creature.
Destroy target artifact or creature with converted mana cost X.
Destroy target Creature with shadow.
Destroy silver-bordered permanent in any game you can see from your seat.
I just went through gatherer searching for "destroy target", got to about the E's, and it seems that an easy way to parse a bunch of oracle "spDestroyTgt" keywords would be:
- Code: Select all
- //orig is the original keyword string
 //we're in "inPlay.filter(new cardListFilter(){boolean addcard(Card card){"
 boolean res=false;
 if(!orig.startsWith("Destroy target)) throw(new Exception(/*insert message here*/);
 destroyKeyword=orig.substring(15);//removes "Destroy target "
 destroyKeyword=destroyKeyword.replaceAll(",", "or");
 orparse:
 for(String m : destroyKeyword.split("or"))
 {
 if(res) break;
 m=m.trim()
 boolean with=false;
 for(String s: m.split(" "))
 {
 if(s.equals("with")){with=true; continue;}
 if(with)
 {
 with = false;
 s=(s.charAt(0)+"").toUppercase()+s.substring(1);//Keywords are uppercase(I think)
 if(card.getKeywords().contains(s))continue;
 continue orparse;
 }
 boolean match=false;
 boolean non=s.contains("non");
 if(non) s=s.substring(3)
 if(s.startsWith("-")) s=s.substring(1);
 for(String color : Constant.Colors.onlyColors)
 {
 if(!s.equals(color)) continue;
 String short = Input_PayManaCostUtil.getColor2(color)//I think
 if(!card.getManaCost.contains(short)continue;
 match = true;
 break;
 }
 s=(s.charAt(0)+"").toUppercase()+s.substring(1);//types are stored as uppercase, right?
 if(!match) match = card.typeContains(s);
 if (non) match=!match;//I think there's better way to do this
 if(match)continue;
 continue orparse;
 }
 res=true;
 }
 return res;
 .
.O forest, hold thy wand'ring son
Though fears assail the door.
O foliage, cloak thy ravaged one
In vestments cut for war.
--Eladamri, the Seed of Freyalise
		Though fears assail the door.
O foliage, cloak thy ravaged one
In vestments cut for war.
--Eladamri, the Seed of Freyalise
- zerker2000
- Programmer
- Posts: 569
- Joined: 09 May 2009, 21:40
- Location: South Pasadena, CA
- Has thanked: 0 time
- Been thanked: 0 time
Re: spDestroyTgt keyword
 by Rob Cashwalker » 06 Jul 2009, 02:27
by Rob Cashwalker » 06 Jul 2009, 02:27 
I can't seem to follow your code. I'm not a fan of free-form parsing, though I'm sure it could be done.
I'm leaning to some form of the following:
Terror spDestroyTgt:Creature.nonBlack+nonArtifact:NoRegen
Naturalize spDestroyTgt:Artifact,Enchantment
Creeping Mold spDestroyTgt:Artifact,Enchantment,Land
Deathmark spDestroyTgt:Creature.Green,Creature.White
Commas separate the inclusive restrictions, periods and plus signs separate the exclusive restrictions. So for Naturalize, it will pull a list of Artifacts and a list of Enchantments, then combine them (Creeping Mold is similar). For Terror, it will pull a list of Creatures, then filter that list for nonBlack and nonArtifact.
			I'm leaning to some form of the following:
Terror spDestroyTgt:Creature.nonBlack+nonArtifact:NoRegen
Naturalize spDestroyTgt:Artifact,Enchantment
Creeping Mold spDestroyTgt:Artifact,Enchantment,Land
Deathmark spDestroyTgt:Creature.Green,Creature.White
Commas separate the inclusive restrictions, periods and plus signs separate the exclusive restrictions. So for Naturalize, it will pull a list of Artifacts and a list of Enchantments, then combine them (Creeping Mold is similar). For Terror, it will pull a list of Creatures, then filter that list for nonBlack and nonArtifact.
The Force will be with you, Always.
		- 
				 
 Rob Cashwalker
- Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: spDestroyTgt keyword
 by zerker2000 » 06 Jul 2009, 03:44
by zerker2000 » 06 Jul 2009, 03:44 
I very much am, and envision Forge(someday) being able to ReadCard Allsets.txt(official one; attached) and import 90% of the cards correctly...parsing text that follows rigid formatting isn't Rocket ScienceRob Cashwalker wrote:I can't seem to follow your code. I'm not a fan of free-form parsing, though I'm sure it could be done.
 .
.- Attachments
- 
		 Allsets-2009-03-21.zip Allsets-2009-03-21.zip
- A text file containing oracle texts for all Magic cards as of March, zipped.
- (369.6 KiB) Downloaded 528 times
 
O forest, hold thy wand'ring son
Though fears assail the door.
O foliage, cloak thy ravaged one
In vestments cut for war.
--Eladamri, the Seed of Freyalise
		Though fears assail the door.
O foliage, cloak thy ravaged one
In vestments cut for war.
--Eladamri, the Seed of Freyalise
- zerker2000
- Programmer
- Posts: 569
- Joined: 09 May 2009, 21:40
- Location: South Pasadena, CA
- Has thanked: 0 time
- Been thanked: 0 time
Re: spDestroyTgt keyword
 by Rob Cashwalker » 06 Jul 2009, 12:03
by Rob Cashwalker » 06 Jul 2009, 12:03 
Rares has the same delusions of grandeur.... No, it's not rocket science - rockets are easy. I have parsed text quite often in VB and am very good at picking out patterns that I can use to take some shortcuts. A number of those shortcuts just don't work that way in the structure of Java, and we're still left with huge if blocks that spread the relevant code far apart from each other that makes it less readable.zerker2000 wrote: I very much am, and envision Forge(someday) being able to ReadCard Allsets.txt(official one; attached) and import 90% of the cards correctly...parsing text that follows rigid formatting isn't Rocket Science.
The Force will be with you, Always.
		- 
				 
 Rob Cashwalker
- Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: spDestroyTgt keyword
 by MageKing17 » 06 Jul 2009, 21:09
by MageKing17 » 06 Jul 2009, 21:09 
I also have the same delusion for Incantus... I have spent quite some time talking about how much it would simplify things if the program could look at "Nightmare's power and toughness are each equal to the number of Swamps you control" and know what it was supposed to do. I even started looking into parsers, but unfortunately Pybison (suggested by telengard) doesn't work with Windows.Rob Cashwalker wrote:Rares has the same delusions of grandeur.... No, it's not rocket science - rockets are easy. I have parsed text quite often in VB and am very good at picking out patterns that I can use to take some shortcuts. A number of those shortcuts just don't work that way in the structure of Java, and we're still left with huge if blocks that spread the relevant code far apart from each other that makes it less readable.zerker2000 wrote: I very much am, and envision Forge(someday) being able to ReadCard Allsets.txt(official one; attached) and import 90% of the cards correctly...parsing text that follows rigid formatting isn't Rocket Science.
If anyone knows a good parser that runs on Windows, Linux, and Mac, give me a shout.

- 
				 
 MageKing17
- Programmer
- Posts: 473
- Joined: 12 Jun 2008, 20:40
- Has thanked: 5 times
- Been thanked: 9 times
Re: spDestroyTgt keyword
 by Arch » 07 Jul 2009, 09:00
by Arch » 07 Jul 2009, 09:00 
Even though it's starting to feel like this thread is being hijacked I'll add my thoughts here.MageKing17 wrote:I also have the same delusion for Incantus... I have spent quite some time talking about how much it would simplify things if the program could look at "Nightmare's power and toughness are each equal to the number of Swamps you control" and know what it was supposed to do. I even started looking into parsers, but unfortunately Pybison (suggested by telengard) doesn't work with Windows.Rob Cashwalker wrote:Rares has the same delusions of grandeur.... No, it's not rocket science - rockets are easy. I have parsed text quite often in VB and am very good at picking out patterns that I can use to take some shortcuts. A number of those shortcuts just don't work that way in the structure of Java, and we're still left with huge if blocks that spread the relevant code far apart from each other that makes it less readable.zerker2000 wrote: I very much am, and envision Forge(someday) being able to ReadCard Allsets.txt(official one; attached) and import 90% of the cards correctly...parsing text that follows rigid formatting isn't Rocket Science.
If anyone knows a good parser that runs on Windows, Linux, and Mac, give me a shout.
You'd still have to implement all the functionality related to whatever you're parsing, but the actual parsing would just be mapping of these functions to card-objects. I don't belive it would mean more work than doing it another way; that mapping still has to be done. You'd possibly go about the design of it all a bit different though.
About cross-platform parsing. Doesn't feel like you'd need anything really advanced in this case. Mapping reg-exp to functions/objects (however you implement that functionality) seems like the simplest way. Unless you're after a way to teach your program that Nightmare should have P/T = count(Swamps) without you explicitly telling it _how_ to do it; but that's another ball-game all together.
Python provides "shlex" for parsing, not sure that's what you're looking for though. Either way Python was pretty much made for text-processing.

Re: spDestroyTgt keyword
 by zerker2000 » 07 Jul 2009, 09:43
by zerker2000 » 07 Jul 2009, 09:43 
Nightmare shouldnt be too hard for a parser to follow: "equal to" means you need to evaluate what follows, "the number of" means we are going to need a natural number, "Swamps in play" means we are looking for cards in the AllZone.Play-s, that match "Swamp"; "Nightmare" get swapt with "{name}", "{name]'s" obviously refer to characteristics, "Power and Toughness" means we are refering the characteristics "Power" and Toughness"... it really shouldn't be very difficultUnless you're after a way to teach your program that Nightmare should have P/T = count(Swamps) without you explicitly telling it _how_ to do it; but that's another ball-game all together.
 .
.O forest, hold thy wand'ring son
Though fears assail the door.
O foliage, cloak thy ravaged one
In vestments cut for war.
--Eladamri, the Seed of Freyalise
		Though fears assail the door.
O foliage, cloak thy ravaged one
In vestments cut for war.
--Eladamri, the Seed of Freyalise
- zerker2000
- Programmer
- Posts: 569
- Joined: 09 May 2009, 21:40
- Location: South Pasadena, CA
- Has thanked: 0 time
- Been thanked: 0 time
Re: spDestroyTgt keyword
 by Rob Cashwalker » 07 Jul 2009, 15:42
by Rob Cashwalker » 07 Jul 2009, 15:42 
Nightmare and other */* creatures might be the easiest corner case you could pick. Until you realize that MTGForge needs to evaluate the P/T every time state based effects are checked. So, what would you do parse the card each time?
I've finalized a specification for the targeting restriction. I moved the getValidCards into the CardList object and made it more generic to basically become a filter. So it works equally well for cards in play for Destroy Target, or let's say tutoring for a subset of types of cards, or to filter the opponents hand for nonLand cards to be discarded, etc.
It will follow this spec:
Type1[.restriction1[+restriction2...+restrictionN]][,Type2[.restriction1...]]
ie: Creature.nonBlack+nonArtifact
Artifact,Enchantment,Land
Creature.Green,Creature.White
			I've finalized a specification for the targeting restriction. I moved the getValidCards into the CardList object and made it more generic to basically become a filter. So it works equally well for cards in play for Destroy Target, or let's say tutoring for a subset of types of cards, or to filter the opponents hand for nonLand cards to be discarded, etc.
It will follow this spec:
Type1[.restriction1[+restriction2...+restrictionN]][,Type2[.restriction1...]]
ie: Creature.nonBlack+nonArtifact
Artifact,Enchantment,Land
Creature.Green,Creature.White
The Force will be with you, Always.
		- 
				 
 Rob Cashwalker
- Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: spDestroyTgt keyword
 by MageKing17 » 07 Jul 2009, 17:59
by MageKing17 » 07 Jul 2009, 17:59 
Ideally, you wouldn't re-parse the entire card every timestep, and instead have a more computer-readable list of "arguments" for the ability, and only check for when those are changed (for instance, if "Swamp" gets changed to "Plains" by a text-changing effect).Rob Cashwalker wrote:Nightmare and other */* creatures might be the easiest corner case you could pick. Until you realize that MTGForge needs to evaluate the P/T every time state based effects are checked. So, what would you do parse the card each time?
It would almost certainly mean less work total, since so many abilities are copied (with little or no changes) between large numbers of cards. Even if we have to do all the really advanced abilities individually (and I think at least a few of them could fall under a parser), we're no worse off than currently (in Incantus, where we have to do every ability except for keywords by hand).Arch wrote:You'd still have to implement all the functionality related to whatever you're parsing, but the actual parsing would just be mapping of these functions to card-objects. I don't belive it would mean more work than doing it another way; that mapping still has to be done. You'd possibly go about the design of it all a bit different though.
Also, I suppose good ol' regular expressions could do the trick, but the syntax of Pybison seemed interesting. Oh well, I suppose a regexp would be more cross-platform... and easier for me to code, since I've used them (in Perl) before.
Perhaps we should split this off into a different thread.
- 
				 
 MageKing17
- Programmer
- Posts: 473
- Joined: 12 Jun 2008, 20:40
- Has thanked: 5 times
- Been thanked: 9 times
Re: spDestroyTgt keyword
 by zerker2000 » 08 Jul 2009, 04:34
by zerker2000 » 08 Jul 2009, 04:34 
Yes, the parsing results should be stored as an Input[] in the ability, and the parser should be run every time the relevant line of cardText is changed.MageKing17 wrote:Ideally, you wouldn't re-parse the entire card every timestep, and instead have a more computer-readable list of "arguments" for the ability, and only check for when those are changed (for instance, if "Swamp" gets changed to "Plains" by a text-changing effect).
EDIT:
Naah, how to parse ability description text is relevant enough to the thread's purpose ... after all, the main challenge for making spDestroyTgt was exactly that.Perhaps we should split this off into a different thread.
O forest, hold thy wand'ring son
Though fears assail the door.
O foliage, cloak thy ravaged one
In vestments cut for war.
--Eladamri, the Seed of Freyalise
		Though fears assail the door.
O foliage, cloak thy ravaged one
In vestments cut for war.
--Eladamri, the Seed of Freyalise
- zerker2000
- Programmer
- Posts: 569
- Joined: 09 May 2009, 21:40
- Location: South Pasadena, CA
- Has thanked: 0 time
- Been thanked: 0 time
Re: spDestroyTgt keyword
 by Rob Cashwalker » 08 Jul 2009, 05:01
by Rob Cashwalker » 08 Jul 2009, 05:01 
Take 2:
Add to CardList:
			Add to CardList:
- Code: Select all
- public CardList getValidCards(String Restrictions[])
 {
 CardList tmpList = new CardList(toArray());
 CardList retList = new CardList();
 
 for (int i=0;i<Restrictions.length;i++)
 {
 String incR[] = Restrictions[i].split("\\."); // Inclusive restrictions are Card types
 
 if (! incR[0].equals("Permanent")) // Since the cards don't actually say "Permanent"
 tmpList = getType(incR[0]);
 
 if (incR.length > 1)
 {
 final String excR = incR[1];
 tmpList = tmpList.filter(new CardListFilter()
 {
 public boolean addCard(Card c)
 {
 boolean r = true;
 String exR[] = excR.split("\\+"); // Exclusive Restrictions are ...
 for (int j=0;j<exR.length;j++)
 {
 if (exR[j].contains("White") || // ... Card colors
 exR[j].contains("Blue") ||
 exR[j].contains("Black") ||
 exR[j].contains("Red") ||
 exR[j].contains("Green") ||
 exR[j].contains("Colorless"))
 if (exR[j].startsWith("non"))
 r = r && (! CardUtil.getColors(c).contains(exR[j].substring(3).toLowerCase()));
 else
 r = r && (CardUtil.getColors(c).contains(exR[j].toLowerCase()));
 else if (exR[j].contains("MultiColor")) // ... Card is multicolored
 if (exR[j].startsWith("non"))
 r = r && (CardUtil.getColors(c).size() == 1);
 else
 r = r && (CardUtil.getColors(c).size() > 1);
 else if (exR[j].contains("with")) // ... Card keywords
 if (exR[j].startsWith("without"))
 r = r && (! c.getKeyword().contains(exR[j].substring(7)));
 else
 r = r && (c.getKeyword().contains(exR[j].substring(4)));
 //TODO: converted mana cost
 //TODO: tapped
 //TODO: enchanted
 //TODO: enchanting
 //TODO: token
 //TODO: counters
 else
 if (exR[j].startsWith("non")) // ... Other Card types
 r = r && (! c.getType().contains(exR[j].substring(3)));
 else
 r = r && (c.getType().contains(exR[j]));
 }
 return r;
 }
 });
 }
 retList.addAll(tmpList.toArray());
 }
 return retList;
 }//getValidCards
- Code: Select all
- // Generic destroy target card
 if (shouldSpDestroyTgt(card) != -1)
 {
 int n = shouldSpDestroyTgt(card);
 
 String parse = card.getKeyword().get(n).toString();
 card.removeIntrinsicKeyword(parse);
 
 String k[] = parse.split(":");
 String Targets = k[1]; // Artifact, Creature, Enchantment, Land, Permanent, White, Blue, Black, Red, Green, Colorless, MultiColor
 // non-Artifact, non-Creature, non-Enchantment, non-Land, non-Permanent,
 //non-White, non-Blue, non-Black, non-Red, non-Green, non-Colorless, non-MultiColor
 final String Tgts[] = Targets.split(",");
 
 String tmpDesc = card.getText().substring(15);
 int i = tmpDesc.indexOf(".");
 tmpDesc = tmpDesc.substring(0, i);
 final String Selec = new String("Select target " + tmpDesc + " to destroy.");
 
 final boolean NoRegen = (k.length == 3);
 
 card.clearSpellAbility();
 
 final SpellAbility spDstryTgt = new Spell(card)
 {
 private static final long serialVersionUID = 142142142142L;
 
 public boolean canPlayAI()
 {
 CardList results = new CardList();
 CardList choices = getTargets();
 
 if (choices.size() > 0)
 {
 for (int i = 0; i < Tgts.length; i++)
 {
 if (Tgts[i].equals("Artifact"))
 results.add(CardFactoryUtil.AI_getBestArtifact(choices));
 else if (Tgts[i].equals("Creature"))
 results.add(CardFactoryUtil.AI_getBestCreature(choices));
 else if (Tgts[i].equals("Enchantment"))
 results.add(CardFactoryUtil.AI_getBestEnchantment(choices, card, true));
 else if (Tgts[i].equals("Land"))
 results.add(CardFactoryUtil.AI_getBestLand(choices));
 else if (Tgts[i].equals("Permanent"))
 results.add(CardFactoryUtil.AI_getMostExpensivePermanent(choices, card, true));
 }
 }
 if (results.size() > 0)
 {
 results.shuffle();
 setTargetCard(results.get(0));
 return true;
 }
 return false;
 }
 CardList getTargets()
 {
 CardList tmpList = new CardList();
 tmpList.addAll(AllZone.Human_Play.getCards());
 tmpList.filter(new CardListFilter()
 {
 public boolean addCard(Card c)
 {
 return (CardFactoryUtil.canTarget(card, c));
 }
 });
 
 return tmpList.getValidCards(Tgts);
 }
 public void resolve()
 {
 if (AllZone.GameAction.isCardInPlay(getTargetCard()) && CardFactoryUtil.canTarget(card, getTargetCard()))
 if (NoRegen)
 AllZone.GameAction.destroyNoRegeneration(getTargetCard());
 else
 AllZone.GameAction.destroy(getTargetCard());
 
 }
 }; //SpDstryTgt
 
 Input InGetTarget = new Input()
 {
 private static final long serialVersionUID = -142142142142L;
 
 public void showMessage()
 {
 CardList allCards = new CardList();
 allCards.addAll(AllZone.Human_Play.getCards());
 allCards.addAll(AllZone.Computer_Play.getCards());
 allCards.filter(new CardListFilter()
 {
 public boolean addCard(Card c)
 {
 return (CardFactoryUtil.canTarget(card, c));
 }
 });
 
 CardList choices = allCards.getValidCards(Tgts);
 stopSetNext(CardFactoryUtil.input_targetSpecific(spDstryTgt, choices, Selec, true));
 }
 };//InGetTarget
 
 spDstryTgt.setBeforePayMana(InGetTarget);
 card.addSpellAbility(spDstryTgt);
 }//spDestroyTgt
- Code: Select all
- public static Card AI_getBestLand(CardList list)
 {
 CardList land = list.getType("Land");
 if (! (land.size() > 0))
 return null;
 
 CardList nbLand = land.filter(new CardListFilter () // prefer to target non basic lands
 {
 public boolean addCard(Card c)
 {
 return (!c.getType().contains("Basic"));
 }
 }
 );
 
 if (nbLand.size() > 0)
 {
 //TODO: Rank non basics?
 
 Random r = new Random();
 return nbLand.get(r.nextInt(nbLand.size()));
 }
 
 // if no non-basic lands, target the least represented basic land type
 String names[] = {"Plains", "Island", "Swamp", "Mountain", "Forest"};
 String sminBL = new String();
 int iminBL = 20000; // hopefully no one will ever have more than 20000 lands of one type....
 int n = 0;
 for (int i = 0; i < 5; i++)
 {
 n = land.getType(names[i]).size();
 if (n < iminBL && n > 0) // if two or more are tied, only the first one checked will be used
 {
 iminBL = n;
 sminBL = names[i];
 }
 }
 if (iminBL == 20000)
 return null; // no basic land was a minimum
 
 CardList BLand = land.getType(sminBL);
 for (int i=0; i<BLand.size(); i++)
 if (!BLand.get(i).isTapped()) // prefer untapped lands
 return BLand.get(i);
 
 Random r = new Random();
 return BLand.get(r.nextInt(BLand.size())); // random tapped land of least represented type
 }
The Force will be with you, Always.
		- 
				 
 Rob Cashwalker
- Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: spDestroyTgt keyword
 by Rob Cashwalker » 09 Jul 2009, 03:12
by Rob Cashwalker » 09 Jul 2009, 03:12 
After a little testing, I made a slight change in the code:
CardFactory:
I also see how important it is for a SpellAbility to have a description - if there are two modes of the card, but one of the SpellAbilities has a blank description, then it doesn't show up in the dialog box.
spDestroyTgt uses the plain english card text for the input object, but now the code copies it into the SpellAbility and then trashes it. Not ideal, but it doesn't make sense for it to be printed twice in the card text in the GUI.
Maybe the better solution is to modify Card.getText() to filter SpellAbility descriptions that are already present in the card text. Or add a boolean flag in the SpellAbility object which is checked in Card.getText(), which triggers it to not be used in building the card text that is returned.
			CardFactory:
- Code: Select all
- spDstryTgt.setBeforePayMana(InGetTarget);
 spDstryTgt.setDescription(card.getText());
 card.setText("");
 card.addSpellAbility(spDstryTgt);
I also see how important it is for a SpellAbility to have a description - if there are two modes of the card, but one of the SpellAbilities has a blank description, then it doesn't show up in the dialog box.
spDestroyTgt uses the plain english card text for the input object, but now the code copies it into the SpellAbility and then trashes it. Not ideal, but it doesn't make sense for it to be printed twice in the card text in the GUI.
Maybe the better solution is to modify Card.getText() to filter SpellAbility descriptions that are already present in the card text. Or add a boolean flag in the SpellAbility object which is checked in Card.getText(), which triggers it to not be used in building the card text that is returned.
The Force will be with you, Always.
		- 
				 
 Rob Cashwalker
- Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: spDestroyTgt keyword
 by DennisBergkamp » 24 Jul 2009, 14:54
by DennisBergkamp » 24 Jul 2009, 14:54 
Rob,
			
		I guess this is ready to be merged into the next release then?Take 2:
...
- 
				 
 DennisBergkamp
- AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: spDestroyTgt keyword
 by Rob Cashwalker » 24 Jul 2009, 20:15
by Rob Cashwalker » 24 Jul 2009, 20:15 
Yeah, taking the change from the additional post above into account.DennisBergkamp wrote:Rob,I guess this is ready to be merged into the next release then?Take 2:
...
Also consider comments I've made here and in other threads about the order of processing for Cycling, Morph and "Tack On" abilities.
The Force will be with you, Always.
		- 
				 
 Rob Cashwalker
- Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
			54 posts
			 • Page 2 of 4 • 1, 2, 3, 4
		
	
Who is online
Users browsing this forum: No registered users and 38 guests
 
 