spDiscard[Tgt|Opp]
Post MTG Forge Related Programming Questions Here
	Moderators: timmermac, Agetian, friarsol, Blacksmith, KrazyTheFox, CCGHQ Admins
			25 posts
			 • Page 1 of 2 • 1, 2
		
	
spDiscard[Tgt|Opp]
 by Rob Cashwalker » 09 Jul 2010, 11:49
by Rob Cashwalker » 09 Jul 2010, 11:49 
Finally assembled this keyword.. I had begun working on it a couple months ago.
Right now it only handles basic discards, where the targeted player or opponent chooses. The reveal and choose type are next, and will be part of the same keyword.
Syntax:
			Right now it only handles basic discards, where the targeted player or opponent chooses. The reveal and choose type are next, and will be part of the same keyword.
Syntax:
- Code: Select all
- spDiscard[Tgt|Opp]:[TgtChoose|OppChoose|AtRandom|Hand]:<numCards>:<Drawback:Spell Description:StackDescription>
- Code: Select all
- if (hasKeyword(card, "spDiscard") != -1)
 {
 int n = hasKeyword(card, "spDiscard");
 
 String parse = card.getKeyword().get(n).toString();
 card.removeIntrinsicKeyword(parse);
 
 String k[] = parse.split(":");
 final boolean Tgt = k[0].contains("Tgt");
 final boolean Opp = k[0].contains("Opp");
 
 final String DiscardMethod = k[1];
 
 final int NumCards[] = {-1138};
 final String NumCardsX[] = {"none"};
 final String UnlessType[] = {"none"};
 
 if (k[2].length() > 1)
 {
 String kk[] = k[2].split("/");
 if (kk[1].startsWith("UnlessDiscardType"))
 {
 String jk[] = kk[1].split("\\.");
 UnlessType[0] = jk[1];
 }
 }
 else if (k[2].matches("X"))
 {
 String xy = card.getSVar(k[2]);
 if (xy.startsWith("Count$"))
 {
 String kk[] = xy.split("\\$");
 NumCardsX[0] = kk[1];
 }
 }
 else if (k[2].matches("[0-9]"))
 {
 NumCards[0] = Integer.parseInt(k[2]);
 }
 
 
 final String Drawback[] = {"none"};
 final String spDesc[] = {"none"};
 final String stDesc[] = {"none"};
 
 if (k[3].contains("Drawback$"))
 {
 String kk[] = k[3].split("\\$");
 Drawback[0] = kk[1];
 if (k.length > 4) spDesc[0] = k[4];
 if (k.length > 5) stDesc[0] = k[5];
 }
 else
 {
 if (k.length > 3) spDesc[0] = k[3];
 if (k.length > 4) stDesc[0] = k[4];
 }
 
 SpellAbility spDiscard = new Spell(card)
 {
 private static final long serialVersionUID = 837472987492L;
 
 private int getNumCards() {
 if(NumCards[0] != -1138) return NumCards[0];
 
 if(!NumCardsX[0].equals("none")) return CardFactoryUtil.xCount(card, NumCardsX[0]);
 
 return 0;
 }
 
 public boolean canPlayAI()
 {
 int nCards = getNumCards();
 
 PlayerZone pzH = AllZone.getZone(Constant.Zone.Hand, Constant.Player.Human);
 int numHHand = pzH.size();
 
 if (numHHand > (nCards - 1))
 return true;
 
 return false;
 }
 public void resolve()
 {
 int nCards = getNumCards();
 
 if (DiscardMethod.equals("OppChoose"))
 {
 String opp = AllZone.GameAction.getOpponent(card.getController());
 
 if (!UnlessType[0].equals("none"))
 AllZone.GameAction.discardUnless(opp, nCards, UnlessType[0]);
 else
 AllZone.GameAction.discard(opp, nCards);
 }
 else if (DiscardMethod.equals("TgtChoose"))
 {
 if (!UnlessType[0].equals("none"))
 AllZone.GameAction.discardUnless(getTargetPlayer(), nCards, UnlessType[0]);
 else
 AllZone.GameAction.discard(getTargetPlayer(), nCards);
 }
 else if (DiscardMethod.equals("AtRandom"))
 {
 AllZone.GameAction.discardRandom(getTargetPlayer(), nCards);
 }
 else if (DiscardMethod.equals("Hand"))
 {
 AllZone.GameAction.discardHand(getTargetPlayer());
 }
 
 if (!Drawback[0].equals("none"))
 {
 CardFactoryUtil.doDrawBack(Drawback[0], 0, card.getController(), AllZone.GameAction.getOpponent(card.getController()), card.getController(), card, card);
 }
 }
 };
 
 if (Tgt)
 spDiscard.setBeforePayMana(CardFactoryUtil.input_targetPlayer(spDiscard));
 else
 spDiscard.setTargetPlayer(AllZone.GameAction.getOpponent(card.getController()));
 
 spDiscard.setDescription(spDesc[0]);
 spDiscard.setStackDescription(stDesc[0]);
 
 card.clearSpellAbility();
 card.addSpellAbility(spDiscard);
 
 String bbCost = card.getSVar("Buyback");
 if (!bbCost.equals(""))
 {
 SpellAbility bbDiscardTgt = spDiscard.copy();
 bbDiscardTgt.setManaCost(CardUtil.addManaCosts(card.getManaCost(), bbCost));
 bbDiscardTgt.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.)");
 bbDiscardTgt.setIsBuyBackAbility(true);
 
 if (Tgt)
 bbDiscardTgt.setBeforePayMana(CardFactoryUtil.input_targetPlayer(bbDiscardTgt));
 else
 bbDiscardTgt.setTargetPlayer(AllZone.GameAction.getOpponent(card.getController()));
 
 card.addSpellAbility(bbDiscardTgt);
 }
 }//spDiscardTgt
- Code: Select all
- Unnerve
 3 B
 Sorcery
 no text
 spDiscardOpp:OppChoose:2:Each opponent discards two cards.:Unnerve - opponent discards cards
 Wheel and Deal
 3 U
 Instant
 no text
 spDiscardOpp:Hand:0:Drawback$OppDraw/7:Any number of target opponents each discards his or her hand and draws seven cards.:Wheel and Deal - target player discards cards
 Draw a card.
 Stupor
 2 B
 Sorcery
 no text
 spDiscardOpp:AtRandom:1:Drawback$OppDiscard/1:Target opponent discards a card at random, then discards a card.:Stupor - opponent discards cards
 Mind Knives
 1 B
 Sorcery
 no text
 spDiscardOpp:AtRandom:1:Target opponent discards a card at random.:Mind Knives - opponent discards cards
 Deception
 2 B
 Sorcery
 no text
 spDiscardOpp:OppChoose:2:Target opponent discards two cards.:Deception - opponent discards cards
 Wit's End
 5 B B
 Sorcery
 no text
 spDiscardTgt:Hand:0:Target player discards his or her hand.:Wit's End - target player discards cards
 Waking Nightmare
 2 B
 Sorcery Arcane
 no text
 spDiscardTgt:TgtChoose:2:Target player discards two cards.:Waking Nightmare - target player discards cards
 Voices from the Void
 4 B
 Sorcery
 no text
 spDiscardTgt:TgtChoose:X:Domain - Target player discards a card for each basic land type among lands you control.:Voices from the Void - target player discards cards
 Unhinge
 2 B
 Sorcery
 no text
 spDiscardTgt:TgtChoose:1:Target player discards a card.:Unhinge - target player discards a card
 Draw a card.
 Unburden
 1 B B
 Sorcery
 no text
 spDiscardTgt:TgtChoose:2:Target player discards two cards.:Unburden - target player discards cards
 Cycling:2
 Three Tragedies
 3 B B
 Sorcery Arcane
 no text
 spDiscardTgt:TgtChoose:3:Target player discards three cards.:Three Tragedies - target player discards cards
 Specter's Wail
 1 B
 Sorcery
 no text
 spDiscardTgt:AtRandom:1:Target player discards a card at random.:Specter's Wail - target player discards a card
 Mind Twist
 X B
 Sorcery
 no text
 spDiscardTgt:AtRandom:X:Target player discards X cards at random.:Mind Twist - target player discards cards
 SVar:X:Count$xPaid
 Mind Sludge
 4 B
 Sorcery
 no text
 spDiscardTgt:TgtChoose:X:Target player discards a card for each Swamp you control.:Mind Sludge - target player discards cards
 SVar:X:Count$TypeYouCtrl.Swamp
 Mind Shatter
 X B B
 Sorcery
 spDiscardTgt:AtRandom:X:Target player discards X cards at random.:Mind Shatter - target player discards cards
 SVar:X:Count$xPaid
 Mind Rot
 2 B
 Sorcery
 no text
 spDiscardTgt:TgtChoose:2:Target player discards two cards.:Mind Rot - target player discards cards
 Mind Peel
 B
 Sorcery
 no text
 spDiscardTgt:1:Target player discards a card.:Mind Peel - target player discards a card
 SVar:Buyback:2 B B
 Mind Burst
 1 B
 Sorcery
 no text
 spDiscardTgt:TgtChoose:X:Target player discards X cards, where X is one plus the number of cards named Mind Burst in all graveyards.:Mind Burst - target player discards cards
 SVar:X:Count$NamedInAllYards.Mind Burst/Plus.1
 Hymn to Tourach
 B B
 Sorcery
 no text
 spDiscardTgt:AtRandom:2:Target player discards two cards at random.:Hymn to Tourach - target player discards cards
 Haunting Hymn
 4 B B
 Instant
 no text
 spDiscardTgt:TgtChoose:X:Target player discards two cards. If you cast this spell during your main phase, that player discards four cards instead.:Haunting Hymn - target player discards cards
 SVar:X:Count$IfMainPhase.4.2
 Fugue
 3 B B
 Sorcery
 no text
 spDiscardTgt:TgtChoose:3:Target player discards three cards.:Fugue - target player discards cards
 Forget
 U U
 Sorcery
 no text
 spDiscardTgt:TgtChoose:2:Drawback$TgtDraw/2:Target player discards two cards, then draws as many cards as he or she discarded this way.:Forget - target player discards cards
 Fill with Fright
 3 B
 Sorcery
 no text
 spDiscardTgt:TgtChoose:2:Target player discards two cards.:Fill with Fright - target player discards cards
 Scry 2
 Wrench Mind
 B B
 Sorcery
 no text
 spDiscardTgt:TgtChoose:2/UnlessDiscardType.Artifact:Target player discards two cards unless he or she discards an artifact card.:Wrench Mind - target player discards cards
 Surging Dementia
 1 B
 Sorcery
 no text
 spDiscardTgt:TgtChoose:1:Target player discards a card.:Surging Dementia - Target player discards a card.
 Ripple:4
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: spDiscard[Tgt|Opp]
 by Sloth » 09 Jul 2010, 13:10
by Sloth » 09 Jul 2010, 13:10 
You're version of Forget seems to allow a player to draw two cards if it is the last card in his hand. This should not be possible with the oracle wording.
Syphon Mind has the same problem.
			
		Syphon Mind has the same problem.
- 
				 
 Sloth
- Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: spDiscard[Tgt|Opp]
 by Rob Cashwalker » 09 Jul 2010, 13:57
by Rob Cashwalker » 09 Jul 2010, 13:57 
good catch. Forget about Forget.
			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: spDiscard[Tgt|Opp]
 by Chris H. » 09 Jul 2010, 14:24
by Chris H. » 09 Jul 2010, 14:24 
I merged my local copy up to r1390 and noticed a warning in CardFactory.java. The local variable Opp is never read. This is line 468.
Some of the cards you list use the Opp rather than the Tgt in k[0] … so I wild hold off on adding new cards or converting over the existing cards for the moment.
			
		- Code: Select all
- if (hasKeyword(card, "spDiscard") != -1)
 {
 int n = hasKeyword(card, "spDiscard");
 
 String parse = card.getKeyword().get(n).toString();
 card.removeIntrinsicKeyword(parse);
 
 String k[] = parse.split(":");
 final boolean Tgt = k[0].contains("Tgt");
 final boolean Opp = k[0].contains("Opp");
Some of the cards you list use the Opp rather than the Tgt in k[0] … so I wild hold off on adding new cards or converting over the existing cards for the moment.
- 
				 
 Chris H.
- Forge Moderator
- Posts: 6320
- Joined: 04 Nov 2008, 12:11
- Location: Mac OS X Yosemite
- Has thanked: 644 times
- Been thanked: 643 times
Re: spDiscard[Tgt|Opp]
 by Rob Cashwalker » 09 Jul 2010, 15:25
by Rob Cashwalker » 09 Jul 2010, 15:25 
No, go ahead with it. The "Opp" flag may become useful for the next stage.
			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: spDiscard[Tgt|Opp]
 by friarsol » 09 Jul 2010, 16:14
by friarsol » 09 Jul 2010, 16:14 
Could this keyword also work for "(You) Discard a card" as a cost? With Self as an option for the target. This could work great for spellshapers.
It may be easier for parsing to have the keyword just be spDiscard and let the first parameter be who is discarding.
Ex.
spDiscard:[Tgt|Opp|(Self)]:[TgtChoose|OppChoose|AtRandom|Hand]:<numCards>:<Drawback:Spell Description:StackDescription>
As for the second parameter, what is the difference betwen TgtChoose and OppChoose? It seems they might be "Discarding player chooses" and "Opponent of discarding player chooses". Maybe they can be clarified to OwnerChoose and OpponentChoose?
Although, I feel like that still may be confusing since the Opponent in the first parameter is different than the Opponent in the second parameter. Unless I'm confused myself.
			
		It may be easier for parsing to have the keyword just be spDiscard and let the first parameter be who is discarding.
Ex.
spDiscard:[Tgt|Opp|(Self)]:[TgtChoose|OppChoose|AtRandom|Hand]:<numCards>:<Drawback:Spell Description:StackDescription>
As for the second parameter, what is the difference betwen TgtChoose and OppChoose? It seems they might be "Discarding player chooses" and "Opponent of discarding player chooses". Maybe they can be clarified to OwnerChoose and OpponentChoose?
Although, I feel like that still may be confusing since the Opponent in the first parameter is different than the Opponent in the second parameter. Unless I'm confused myself.
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: spDiscard[Tgt|Opp]
 by Rob Cashwalker » 09 Jul 2010, 16:27
by Rob Cashwalker » 09 Jul 2010, 16:27 
No, discarding as a cost should be done as a cost. The AI for this assumes the intention is to make the player discard. Discarding as a cost should have AI that doesn't so much care about the discarding, more about the ultimate effect.
Same goes for how using "spDamageTgtP:0:Drawback$TgtDiscard:1" achieves the mechanical effect of "target player discards a card". However the AI for it assumes it's trying to deal damage to the player, so it would likely play the spell (if the AI calculation using zero damage even gets that far) even when the player had no cards in hand.
Tgt goes with TgtChoose and Opp goes with OppChoose. They're distinct effects - you could choose yourself if it's "target player" but not if it's "target opponent". However, we could probably drop the OppChoose, because the target player is set specifically to the opponent if not Tgt.
			Same goes for how using "spDamageTgtP:0:Drawback$TgtDiscard:1" achieves the mechanical effect of "target player discards a card". However the AI for it assumes it's trying to deal damage to the player, so it would likely play the spell (if the AI calculation using zero damage even gets that far) even when the player had no cards in hand.
Tgt goes with TgtChoose and Opp goes with OppChoose. They're distinct effects - you could choose yourself if it's "target player" but not if it's "target opponent". However, we could probably drop the OppChoose, because the target player is set specifically to the opponent if not Tgt.
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: spDiscard[Tgt|Opp]
 by Chris H. » 09 Jul 2010, 16:29
by Chris H. » 09 Jul 2010, 16:29 
`Rob Cashwalker wrote:No, go ahead with it. The "Opp" flag may become useful for the next stage.
OK, no prob. I will add the cards and pic urls. Several cards will need to be converted. While I am at it I will put in a suppress warning.

- 
				 
 Chris H.
- Forge Moderator
- Posts: 6320
- Joined: 04 Nov 2008, 12:11
- Location: Mac OS X Yosemite
- Has thanked: 644 times
- Been thanked: 643 times
Re: spDiscard[Tgt|Opp]
 by friarsol » 09 Jul 2010, 16:34
by friarsol » 09 Jul 2010, 16:34 
Ok, so this currently wouldn't handle a card like Coercion, because the Caster is the one who chooses (and not the target)?Rob Cashwalker wrote:Tgt goes with TgtChoose and Opp goes with OppChoose. They're distinct effects - you could choose yourself if it's "target player" but not if it's "target opponent". However, we could probably drop the OppChoose, because the target player is set specifically to the opponent if not Tgt.
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: spDiscard[Tgt|Opp]
 by Rob Cashwalker » 09 Jul 2010, 16:48
by Rob Cashwalker » 09 Jul 2010, 16:48 
Right... RevealYouChoose will be the next method implemented.
			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: spDiscard[Tgt|Opp]
 by Chris H. » 09 Jul 2010, 17:00
by Chris H. » 09 Jul 2010, 17:00 
The cards.txt entries that use the spDiscardOpp form of the keyword are causing a null error.
			
		- Code: Select all
- An error has occured. You can copy/paste this message or save it to a file.
 Please report this, plus what you tried to do, to:
 http://www.slightlymagic.net/forum/viewforum.php?f=26
 If you don't want to register an account, you can mail it directly to
 mtgerror@yahoo.com
 null
 Version:
 Forge -- official beta: $Date: 2010-05-01 03:21:42 -0400 (Sat, 01 May 2010) $, SVN revision: $Revision: 916 $
 OS: Mac OS X Version: 10.6.4 Architecture: x86_64
 Java Version: 1.6.0_20 Vendor: Apple Inc.
 Detailed error trace:
 java.lang.NullPointerException
 at forge.CardFactory.getCard2(CardFactory.java:580)
 at forge.CardFactory.getCard(CardFactory.java:220)
 at forge.CardFactory.<init>(CardFactory.java:67)
 at forge.AllZone.<clinit>(AllZone.java:22)
 at forge.Gui_NewGame.main(Gui_NewGame.java:131)
- 
				 
 Chris H.
- Forge Moderator
- Posts: 6320
- Joined: 04 Nov 2008, 12:11
- Location: Mac OS X Yosemite
- Has thanked: 644 times
- Been thanked: 643 times
Re: spDiscard[Tgt|Opp]
 by Rob Cashwalker » 09 Jul 2010, 19:05
by Rob Cashwalker » 09 Jul 2010, 19:05 
Hmm... 
When the card's being created it has no controller... duh.
fixed it in r.1393
Plus, I make use of Opp, so no more warning.
			When the card's being created it has no controller... duh.
fixed it in r.1393
Plus, I make use of Opp, so no more warning.
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: spDiscard[Tgt|Opp]
 by Chris H. » 09 Jul 2010, 21:45
by Chris H. » 09 Jul 2010, 21:45 
Thank you Rob.
I will merge in the new code and will then run a test to see if I am still having trouble adding Mind Peel. Mind Peel gave me an error in reference to the mana cost of the SVar Buyback:
Mind Peel
B
Sorcery
no text
spDiscardTgt:TgtChoose:1:Target player discards a card.:Mind Peel - target player discards a card
SVar:Buyback:2 B B
			
		I will merge in the new code and will then run a test to see if I am still having trouble adding Mind Peel. Mind Peel gave me an error in reference to the mana cost of the SVar Buyback:
Mind Peel
B
Sorcery
no text
spDiscardTgt:TgtChoose:1:Target player discards a card.:Mind Peel - target player discards a card
SVar:Buyback:2 B B
- Code: Select all
- An error has occured. You can copy/paste this message or save it to a file.
 Please report this, plus what you tried to do, to:
 http://www.slightlymagic.net/forum/viewforum.php?f=26
 If you don't want to register an account, you can mail it directly to
 mtgerror@yahoo.com
 For input string: ""
 Version:
 Forge -- official beta: $Date: 2010-05-01 03:21:42 -0400 (Sat, 01 May 2010) $, SVN revision: $Revision: 916 $
 OS: Mac OS X Version: 10.6.4 Architecture: x86_64
 Java Version: 1.6.0_20 Vendor: Apple Inc.
 Detailed error trace:
 java.lang.NumberFormatException: For input string: ""
 at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
 at java.lang.Integer.parseInt(Integer.java:470)
 at java.lang.Integer.valueOf(Integer.java:554)
 at forge.CardUtil.addManaCosts(CardUtil.java:244)
 at forge.CardFactory.getCard2(CardFactory.java:592)
 at forge.CardFactory.getCard(CardFactory.java:220)
 at forge.CardFactory.<init>(CardFactory.java:67)
 at forge.AllZone.<clinit>(AllZone.java:22)
 at forge.Gui_NewGame.main(Gui_NewGame.java:131)
- 
				 
 Chris H.
- Forge Moderator
- Posts: 6320
- Joined: 04 Nov 2008, 12:11
- Location: Mac OS X Yosemite
- Has thanked: 644 times
- Been thanked: 643 times
Re: spDiscard[Tgt|Opp]
 by Chris H. » 10 Jul 2010, 12:01
by Chris H. » 10 Jul 2010, 12:01 
I converted the 5 existing cards from code based to keyword-ed and they have been merged. All but 2 of the new cards have also been merged. So, all of the cards listed have been taken care of except for:
Forget
Mind Peel
			
		Forget
Mind Peel
- 
				 
 Chris H.
- Forge Moderator
- Posts: 6320
- Joined: 04 Nov 2008, 12:11
- Location: Mac OS X Yosemite
- Has thanked: 644 times
- Been thanked: 643 times
Re: spDiscard[Tgt|Opp]
 by Rob Cashwalker » 10 Jul 2010, 16:44
by Rob Cashwalker » 10 Jul 2010, 16:44 
I fixed the addManaCosts method to correctly handle adding a mana cost with no numeric component. Mind Peel costs B, so Integer.valueOf("") apparantly is the number format exception.... In VB Val("") is 0.
			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
			25 posts
			 • Page 1 of 2 • 1, 2
		
	
Who is online
Users browsing this forum: No registered users and 23 guests
