New keyword: spBounceTgt
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
16 posts
• Page 1 of 2 • 1, 2
New keyword: spBounceTgt
by Sloth » 29 Jul 2010, 18:42
I just made my first keyword: spBounceTgt
It is mostly just a copy of spDestroyTgt:
It is mostly just a copy of spDestroyTgt:
- Code: Select all
// Generic bounce target card
if(hasKeyword(card, "spBounceTgt") != -1) {
int n = hasKeyword(card, "spBounceTgt");
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 = "Select target " + tmpDesc + " to return to owners hand.";
card.clearSpellAbility();
final SpellAbility spBnceTgt = new Spell(card) {
private static final long serialVersionUID = 152897134770L;
@Override
public boolean canPlayAI() {
CardList results = new CardList();
CardList choices = getTargets();
choices = choices.filter(new CardListFilter(){
public boolean addCard(Card c)
{
return !c.getKeyword().contains("Shroud");
}
});
if(choices.size() > 0) {
for(int i = 0; i < Tgts.length; i++) {
if(Tgts[i].equals("Artifact")) {
if(CardFactoryUtil.AI_getBestArtifact(choices) != null) results.add(CardFactoryUtil.AI_getBestArtifact(choices));
} else if(Tgts[i].equals("Creature")) {
if(CardFactoryUtil.AI_getBestCreature(choices) != null) results.add(CardFactoryUtil.AI_getBestCreature(choices));
} else if(Tgts[i].equals("Enchantment")) {
if(CardFactoryUtil.AI_getBestEnchantment(choices, card, true) != null) results.add(CardFactoryUtil.AI_getBestEnchantment(
choices, card, true));
} else if(Tgts[i].equals("Land")) {
if(CardFactoryUtil.AI_getBestLand(choices) != null) results.add(CardFactoryUtil.AI_getBestLand(choices));
} else if(Tgts[i].equals("Permanent")) {
if(CardFactoryUtil.AI_getMostExpensivePermanent(choices, card, true) != null) 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 = tmpList.filter(new CardListFilter() {
public boolean addCard(Card c) {
return (CardFactoryUtil.canTarget(card, c));
}
});
return tmpList.getValidCards(Tgts);
}
@Override
public void resolve() {
if(AllZone.GameAction.isCardInPlay(getTargetCard())
&& CardFactoryUtil.canTarget(card, getTargetCard())) {
if(getTargetCard().isToken()) AllZone.getZone(getTargetCard()).remove(getTargetCard());
else {
PlayerZone hand = AllZone.getZone(Constant.Zone.Hand, getTargetCard().getOwner());
AllZone.GameAction.moveTo(hand, getTargetCard());
}
}
}
}; //SpBnceTgt
Input InGetTarget = CardFactoryUtil.input_targetValid(spBnceTgt, Tgts, Selec);
/*new Input() {
private static final long serialVersionUID = -152897134770L;
@Override
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));
}
});* ///Input_targetSpecific already checks for this
CardList choices = allCards.getValidCards(Tgts);
boolean free = false;
if(this.isFree()) free = true;
stopSetNext(CardFactoryUtil.input_targetSpecific(spBnceTgt, choices, Selec, true, free));
}
};*///InGetTarget
//card.clearSpellAbility();
card.setSVar("PlayMain1", "TRUE");
spBnceTgt.setBeforePayMana(InGetTarget);
spBnceTgt.setDescription(card.getText());
card.setText("");
card.addSpellAbility(spBnceTgt);
String bbCost = card.getSVar("Buyback");
if (!bbCost.equals(""))
{
SpellAbility bbBnceTgt = spBnceTgt.copy();
bbBnceTgt.setManaCost(CardUtil.addManaCosts(card.getManaCost(), bbCost));
bbBnceTgt.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.)");
bbBnceTgt.setIsBuyBackAbility(true);
bbBnceTgt.setBeforePayMana(CardFactoryUtil.input_targetValid(bbBnceTgt, Tgts, Selec));
card.addSpellAbility(bbBnceTgt);
}
}//spBounceTgt
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: New keyword: spBounceTgt
by Rob Cashwalker » 29 Jul 2010, 21:49
Man.. I was gonna do that one....
I was going to revamp DestroyTgt, enabling Drawback$. Then when you copied it, it would already include it.
I would also include provision for different zones for the card to be bounced to.
I was going to revamp DestroyTgt, enabling Drawback$. Then when you copied it, it would already include it.
I would also include provision for different zones for the card to be bounced to.
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: New keyword: spBounceTgt
by Chris H. » 30 Jul 2010, 00:16
This line in the canPlayAI() method:
should be replaced with this line:
This way you are filtering out cards with both Shroud and Protection from {source card colors}.
I will remove the commented out cards from CardFactory tomorrow. We can then concentrate on converting the pre-existing bounce cards from implemented via code to keyword-ed.
- Code: Select all
return !c.getKeyword().contains("Shroud");
should be replaced with this line:
- Code: Select all
return CardFactoryUtil.canTarget(card, c)
This way you are filtering out cards with both Shroud and Protection from {source card colors}.
I will remove the commented out cards from CardFactory tomorrow. We can then concentrate on converting the pre-existing bounce cards from implemented via code to keyword-ed.

-
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: New keyword: spBounceTgt
by Sloth » 30 Jul 2010, 06:21
Sorry....Rob Cashwalker wrote:Man.. I was gonna do that one....
No problem, just do it. I'll try to update spBounceTgt or just copy the new version and start from that.Rob Cashwalker wrote:I was going to revamp DestroyTgt, enabling Drawback$. Then when you copied it, it would already include it.
I added top of the library. I will try to add Exile. Are there any other zones?Rob Cashwalker wrote: I would also include provision for different zones for the card to be bounced to.
Right I forgot about protection. I will replace the line.Chris H. wrote:This line in the canPlayAI() method:`
- Code: Select all
return !c.getKeyword().contains("Shroud");
should be replaced with this line:`
- Code: Select all
return CardFactoryUtil.canTarget(card, c)
This way you are filtering out cards with both Shroud and Protection from {source card colors}.
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: New keyword: spBounceTgt
by Rob Cashwalker » 30 Jul 2010, 11:50
ShuffleIntoLibrary, I think is the only other form.
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: New keyword: spBounceTgt
by Sloth » 30 Jul 2010, 12:15
Good catch, this definitely belongs here. I will try to add this feature. Oblation needs to have Drawback$ though and Deglamer is the only other card I found. Did I miss any?Rob Cashwalker wrote:ShuffleIntoLibrary, I think is the only other form.
By the way Rob:
If you're working on the DestroyTgt keyword, wouldn't it be possible to exclude permanents with regeneration if the spell doesn't have NoRegen in canPlayAI here:
- Code: Select all
choices = choices.filter(new CardListFilter(){
public boolean addCard(Card c)
{
return !c.getKeyword().contains("Indestructible");
}
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: New keyword: spBounceTgt
by Rob Cashwalker » 30 Jul 2010, 13:59
A likewise, good catch.
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: New keyword: spBounceTgt
by Chris H. » 02 Aug 2010, 15:00
We have a few bounce spells that were originally coded without the use of this new keyword. I guess that we should convert them over to implemented via keyword.
I'm looking at the card object for:
Boomerang
Eye of Nowhere
Rescind
Surging AEther
Deny Reality
These original spells have an interesting if short canPlayAI method and I guess that I should add this to the new keyword.
I'm looking at the card object for:
Boomerang
Eye of Nowhere
Rescind
Surging AEther
Deny Reality
These original spells have an interesting if short canPlayAI method and I guess that I should add this to the new keyword.
- Code: Select all
public boolean canPlayAI() {
CardList human = CardFactoryUtil.AI_getHumanCreature(card, true);
return 3 < AllZone.Phase.getTurn() && 0 < human.size();
}
-
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: New keyword: spBounceTgt
by DennisBergkamp » 02 Aug 2010, 15:43
Definitely interesting, I guess the AI won't bounce stuff until after turn 3?
-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: New keyword: spBounceTgt
by Sloth » 02 Aug 2010, 16:04
Doesn't make a big difference, but it would have a higher chance of hitting the player at a crucial point of his mana curve (i.e. a three mana permanent when he doesn't have a fourth land).DennisBergkamp wrote:Definitely interesting, I guess the AI won't bounce stuff until after turn 3?
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: New keyword: spBounceTgt
by Chris H. » 02 Aug 2010, 21:48
I made a minor adjustment to the spBounceTgt AI. I tried to keep it simple and we can always go back and change the number or remove the additional line of code. The start of the canPlayAI() method now looks like this:
- Code: Select all
public boolean canPlayAI() {
if (AllZone.Phase.getTurn() <= 3) return false;
CardList results = new CardList();
CardList choices = getTargets();
choices = choices.filter(new CardListFilter(){
public boolean addCard(Card c)
{
return CardFactoryUtil.canTarget(card, c);
}
});
-
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: New keyword: spBounceTgt
by friarsol » 03 Aug 2010, 15:52
I haven't looked into this keyword yet, but I figured I'd ask first. Is there a way to have multiple targets?
This would be needed for spells like Whiplash Trap or Plow Under.
This would be needed for spells like Whiplash Trap or Plow Under.
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: New keyword: spBounceTgt
by Sloth » 03 Aug 2010, 16:23
There's always a way. But it has to be coded first.friarisol wrote:I haven't looked into this keyword yet, but I figured I'd ask first. Is there a way to have multiple targets?
This would be needed for spells like Whiplash Trap or Plow Under.
I'm not planning to do this at the moment (I will be on vacation at least the next week). If someone wants to give it a try - Go for it.
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: New keyword: spBounceTgt
by Chris H. » 03 Aug 2010, 17:48
`Sloth wrote:I'm not planning to do this at the moment (I will be on vacation at least the next week). If someone wants to give it a try - Go for it.
You have committed an amazing amount of good work these last several weeks.


-
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: New keyword: spBounceTgt
by friarsol » 03 Aug 2010, 18:46
Hah. I just meant was it available for use. I'm going on vacation soon myself, but figured I could get a few things done before that happens.Sloth wrote:There's always a way. But it has to be coded first.friarisol wrote:I haven't looked into this keyword yet, but I figured I'd ask first. Is there a way to have multiple targets?
This would be needed for spells like Whiplash Trap or Plow Under.
I'm not planning to do this at the moment (I will be on vacation at least the next week). If someone wants to give it a try - Go for it.
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
16 posts
• Page 1 of 2 • 1, 2
Who is online
Users browsing this forum: No registered users and 41 guests