Disciple of Kangee
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
20 posts
• Page 1 of 2 • 1, 2
Disciple of Kangee
by Chris H. » 17 Dec 2009, 18:17
I think that I have completed the Disciple of Kangee card. Target creature now gains flying and becomes blue until end of turn. I ran some tests and now realize that I am not sure if I understand the implementation.
Currently, I can change a white creature into a white and blue creature with a gold border. Is this correct?
Or should the blue replace the white until end of turn?
Currently, I can change a white creature into a white and blue creature with a gold border. Is this correct?
Or should the blue replace the white until end of turn?
- Code: Select all
Disciple of Kangee
2 W
Creature Wizard
no text
2/2
- Code: Select all
//*************** START *********** START **************************
else if(cardName.equals("Disciple of Kangee"))
{
final SpellAbility ability = new Ability_Tap(card, "U")
{
private static final long serialVersionUID = -5169389637917649036L;
public boolean canPlayAI()
{
if(CardFactoryUtil.AI_doesCreatureAttack(card))
return false;
return CardFactoryUtil.AI_getHumanCreature("Flying", card, false).isEmpty() &&
(getCreature().size() != 0);
}
public void chooseTargetAI()
{
card.tap();
Card target = CardFactoryUtil.AI_getBestCreature(getCreature());
setTargetCard(target);
}
CardList getCreature()
{
CardList list = new CardList(AllZone.Computer_Play.getCards());
list = list.filter(new CardListFilter()
{
public boolean addCard(Card c)
{
return c.isCreature() && (!CardFactoryUtil.AI_doesCreatureAttack(c)) &&
(! c.getKeyword().contains("Flying")) && CardFactoryUtil.canTarget(card, c);
}
});
list.remove(card);
return list;
}//getCreature()
public void resolve()
{
if(AllZone.GameAction.isCardInPlay(getTargetCard()) && CardFactoryUtil.canTarget(card, getTargetCard()) )
{
final Card[] creature = new Card[1];
final Command EOT = new Command()
{
private static final long serialVersionUID = -1899153704584793548L;
public void execute()
{
if(AllZone.GameAction.isCardInPlay(creature[0]))
{
creature[0].removeExtrinsicKeyword("Flying");
creature[0].removeExtrinsicKeyword(creature[0].getName() + " is blue.");
}
}
};
creature[0] = getTargetCard();
creature[0].addExtrinsicKeyword("Flying");
if(!creature[0].getManaCost().equals("U"))
{
creature[0].addExtrinsicKeyword(creature[0].getName() + " is blue.");
}
AllZone.EndOfTurn.addUntil(EOT);
}//if (card is in play)
}//resolve()
};//SpellAbility
card.addSpellAbility(ability);
ability.setDescription("U, tap: Target creature gains flying and becomes blue until end of turn.");
ability.setBeforePayMana(CardFactoryUtil.input_targetCreature(ability));
}//*************** END ************ END **************************
-
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: Disciple of Kangee
by Marek14 » 17 Dec 2009, 18:22
It replaces the original color. Compare Disciple of Kangee with Indigo Faerie.
Re: Disciple of Kangee
by DennisBergkamp » 17 Dec 2009, 19:48
I think your new code works correctly now Chris... The targeted creature will ONLY be blue, except the GUI doesn't really show it correctly yet (look at Ghostfire, it can target spells that have protection from red, but the GUI will still show a red border).
-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: Disciple of Kangee
by Chris H. » 17 Dec 2009, 20:01
`DennisBergkamp wrote:I think your new code works correctly now Chris... The targeted creature will ONLY be blue, except the GUI doesn't really show it correctly yet (look at Ghostfire, it can target spells that have protection from red, but the GUI will still show a red border).
Great.

I was starting to consider saving the manaCost to a var and checking to see if any other zerker type color keywords are present. This way I could delete this color data and restore it at end of turn.

I quess that it would be nice to adapt other sections of the code to reflect the current color status, just more work. The deck Editors for example.
-
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: Disciple of Kangee
by Chris H. » 17 Dec 2009, 20:58
Drat. I just ran a test and verified that zerker's color keyword is additive and not a replacement effect.
I ran the two decks below against each other.
The computer used it's Disciple of Kangee on it's Devoted Hero. The Devoted Hero then attacked. I used my Disciple of Kangee on my Crimson Kobolds and then gave it pro from white with my Mother of Runes.
My Crimson Kobolds block the computer's attacking Devoted Hero and my Crimson Kobolds survived. I will need to do some more coding to finish off the updated Disciple of Kangee code.

The computer used it's Disciple of Kangee on it's Devoted Hero. The Devoted Hero then attacked. I used my Disciple of Kangee on my Crimson Kobolds and then gave it pro from white with my Mother of Runes.
My Crimson Kobolds block the computer's attacking Devoted Hero and my Crimson Kobolds survived. I will need to do some more coding to finish off the updated Disciple of Kangee code.
- Code: Select all
Computer Devoted Hero
[general]
constructed
[main]
1 Devoted Hero
3 Mox Pearl
1 Mox Sapphire
1 Disciple of Kangee
1 Phyrexian Walker
[sideboard]
- Code: Select all
Human Mother of Runes
[general]
constructed
[main]
1 Crimson Kobolds
2 Mox Pearl
1 Mox Sapphire
1 Disciple of Kangee
1 Phyrexian Walker
1 Mother of Runes
[sideboard]
-
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: Disciple of Kangee
by Chris H. » 18 Dec 2009, 14:25
I have changed the code and now the Disciple of Kangee ability is a replacement rather than an additive effect. I check for and remove zerker's color keywords and add them back in at EOT. We can now change a Crimson Kobolds to the appropriate color. Great.
But what do we do with the target's mana cost? I originally changed the mana cost to "" but I realized that this could create problems with other effects.
Currently, I toLowerCase and then to UpperCase the mana cost. This is somewhat better but will still likely create problems with other effects. Gotta love them hacks.
What should I do? Is there a command that can be used to quickly convert the mana cost to it's CCC? Does anyone have any ideas?
But what do we do with the target's mana cost? I originally changed the mana cost to "" but I realized that this could create problems with other effects.
Currently, I toLowerCase and then to UpperCase the mana cost. This is somewhat better but will still likely create problems with other effects. Gotta love them hacks.
What should I do? Is there a command that can be used to quickly convert the mana cost to it's CCC? Does anyone have any ideas?
- Code: Select all
//*************** START *********** START **************************
else if(cardName.equals("Disciple of Kangee"))
{
final SpellAbility ability = new Ability_Tap(card, "U")
{
private static final long serialVersionUID = -5169389637917649036L;
public boolean canPlayAI()
{
if(CardFactoryUtil.AI_doesCreatureAttack(card))
return false;
return CardFactoryUtil.AI_getHumanCreature("Flying", card, false).isEmpty() &&
(getCreature().size() != 0);
}
public void chooseTargetAI()
{
card.tap();
Card target = CardFactoryUtil.AI_getBestCreature(getCreature());
setTargetCard(target);
}
CardList getCreature()
{
CardList list = new CardList(AllZone.Computer_Play.getCards());
list = list.filter(new CardListFilter()
{
public boolean addCard(Card c)
{
return c.isCreature() && (!CardFactoryUtil.AI_doesCreatureAttack(c)) &&
(! c.getKeyword().contains("Flying")) && CardFactoryUtil.canTarget(card, c);
}
});
list.remove(card);
return list;
}//getCreature()
public void resolve()
{
if (AllZone.GameAction.isCardInPlay(getTargetCard()) && CardFactoryUtil.canTarget(card, getTargetCard()) )
{
final Card[] creature = new Card[1];
creature[0] = getTargetCard();
final String origManaCost = creature[0].getManaCost();
final String tgtName = creature[0].getName();
final String[] creatureIsColor = {tgtName + " is black.", tgtName + " is blue.", tgtName + " is green.",
tgtName + " is red.", tgtName + " is white.", tgtName + " is colorless."};
final boolean[] colorFlag = {false, false, false, false, false, false};
for (int i=0; i<6; i++)
{
if (creature[0].getIntrinsicKeyword().contains(creatureIsColor[i]))
{
colorFlag[i] = true;
// creature[0].removeExtrinsicKeyword(creatureIsColor[i]);
}
}
final Command EOT = new Command()
{
private static final long serialVersionUID = -1899153704584793548L;
public void execute()
{
if (AllZone.GameAction.isCardInPlay(creature[0]))
{
creature[0].removeExtrinsicKeyword("Flying");
creature[0].removeExtrinsicKeyword(tgtName + " is blue.");
creature[0].setManaCost(origManaCost.toUpperCase());
for (int i=0; i<6; i++)
{
if (colorFlag[i])
{
creature[0].addIntrinsicKeyword(creatureIsColor[i]);
}
}
}
}
};
creature[0].setManaCost(origManaCost.toLowerCase());
for (int i=0; i<6; i++)
{
if (colorFlag[i])
{
creature[0].removeIntrinsicKeyword(creatureIsColor[i]);
}
}
creature[0].addExtrinsicKeyword("Flying");
creature[0].addExtrinsicKeyword(tgtName + " is blue.");
AllZone.EndOfTurn.addUntil(EOT);
}//if (card is in play)
}//resolve()
};//SpellAbility
card.addSpellAbility(ability);
ability.setDescription("U, tap: Target creature gains flying and becomes blue until end of turn.");
ability.setBeforePayMana(CardFactoryUtil.input_targetCreature(ability));
}//*************** END ************ END **************************
-
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: Disciple of Kangee
by Marek14 » 18 Dec 2009, 14:37
In ideal world, the effects that change color do that regardless of the mana cost - the mana cost is never changed (save from copy effects), and it's only used as the "first step" in determining color.
Re: Disciple of Kangee
by Chris H. » 19 Dec 2009, 02:31
I found the cmc method and I have updated the code to use this to remove the color from the target card. It is a hack, but this is probably as close as I can get to being rules compliant.
I will make an update to the SVN this weekend. I see that the weather forecast will have me snowed in all weekend.
](./images/smilies/eusa_wall.gif)

- Code: Select all
//*************** START *********** START **************************
else if(cardName.equals("Disciple of Kangee"))
{
final SpellAbility ability = new Ability_Tap(card, "U")
{
private static final long serialVersionUID = -5169389637917649036L;
public boolean canPlayAI()
{
if(CardFactoryUtil.AI_doesCreatureAttack(card))
return false;
return CardFactoryUtil.AI_getHumanCreature("Flying", card, false).isEmpty() &&
(getCreature().size() != 0);
}
public void chooseTargetAI()
{
card.tap();
Card target = CardFactoryUtil.AI_getBestCreature(getCreature());
setTargetCard(target);
}
CardList getCreature()
{
CardList list = new CardList(AllZone.Computer_Play.getCards());
list = list.filter(new CardListFilter()
{
public boolean addCard(Card c)
{
return c.isCreature() && (!CardFactoryUtil.AI_doesCreatureAttack(c)) &&
(! c.getKeyword().contains("Flying")) && CardFactoryUtil.canTarget(card, c);
}
});
list.remove(card);
return list;
}//getCreature()
public void resolve()
{
if (AllZone.GameAction.isCardInPlay(getTargetCard()) && CardFactoryUtil.canTarget(card, getTargetCard()) )
{
final Card[] creature = new Card[1];
creature[0] = getTargetCard();
final String origManaCost = creature[0].getManaCost();
final String tgtName = creature[0].getName();
final String[] creatureIsColor = {tgtName + " is black.", tgtName + " is blue.", tgtName + " is green.",
tgtName + " is red.", tgtName + " is white.", tgtName + " is colorless."};
final boolean[] colorFlag = {false, false, false, false, false, false};
for (int i=0; i<6; i++)
{
if (creature[0].getIntrinsicKeyword().contains(creatureIsColor[i]))
{
colorFlag[i] = true;
}
}
final Command EOT = new Command()
{
private static final long serialVersionUID = -1899153704584793548L;
public void execute()
{
if (AllZone.GameAction.isCardInPlay(creature[0]))
{
creature[0].removeExtrinsicKeyword("Flying");
creature[0].removeExtrinsicKeyword(tgtName + " is blue.");
creature[0].setManaCost(origManaCost);
for (int i=0; i<6; i++)
{
if (colorFlag[i])
{
creature[0].addIntrinsicKeyword(creatureIsColor[i]);
}
}
}
}
};
creature[0].setManaCost(Integer.toString(CardUtil.getConvertedManaCost(origManaCost)));
for (int i=0; i<6; i++)
{
if (colorFlag[i])
{
creature[0].removeIntrinsicKeyword(creatureIsColor[i]);
}
}
creature[0].addExtrinsicKeyword("Flying");
creature[0].addExtrinsicKeyword(tgtName + " is blue.");
AllZone.EndOfTurn.addUntil(EOT);
}//if (card is in play)
}//resolve()
};//SpellAbility
card.addSpellAbility(ability);
ability.setDescription("U, tap: Target creature gains flying and becomes blue until end of turn.");
ability.setBeforePayMana(CardFactoryUtil.input_targetCreature(ability));
}//*************** END ************ END **************************
I will make an update to the SVN this weekend. I see that the weather forecast will have me snowed in all weekend.

-
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: Disciple of Kangee
by zerker2000 » 19 Dec 2009, 02:56
Optimal solution(which I, coder of color keywords, hereby endorse): in getColors, blank the output array the first time you encounter such keywords. Maybe in fact whenever you encounter them, as long as the parser can be made to understand "all colors" and/or "is COLOR1 and COLOR2[ and COLOR3...]" and such provisions are made for Transguild Courier.
EDIT: As far as I can remember, comp rules say it's supposed to work this way in the first place.
EDIT: As far as I can remember, comp rules say it's supposed to work this way in the first place.
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: Disciple of Kangee
by Chris H. » 19 Dec 2009, 13:40
I think that I found your color keyword code in CardUtil.java. There is a section which starts with:
An interesting section of code and a step in the right direction.
I admit that my knowledge base and skill level is fairly limited. I can see that there will need to be a way to determine if this keyword needs to be an additive or a replacement effect. I will have to let the lead programmers deal with this part of the code base.
- Code: Select all
public static ArrayList<String> getColors(Card c)
An interesting section of code and a step in the right direction.
I admit that my knowledge base and skill level is fairly limited. I can see that there will need to be a way to determine if this keyword needs to be an additive or a replacement effect. I will have to let the lead programmers deal with this part of the code base.
-
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: Disciple of Kangee
by zerker2000 » 20 Dec 2009, 04:55
CardUtil.getColors is the method used by spells/abilities requiring colors, and what should be used by GUI(though I think it isn't). I think originally it did something along the lines of "For each letter in the mana cost, add the appropriate color to the output array". Then I came along and inserted keyword handling.
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: Disciple of Kangee
by Chris H. » 25 Dec 2009, 01:52
While I have been fairly busy recently, I did set aside some time to look at some of the color code. I agree that some of the GUI appears to not use this color code. Kobolds have a black border rather than a red one for example. It is somewhat confusing to see black, color keyword and colorless cards with a black border.
I see that with v12-14 that the Kobolds now have a designation of red in the color column of the deck editor. That is a nice addition.
I see that with v12-14 that the Kobolds now have a designation of red in the color column of the deck editor. That is a nice addition.
-
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: Disciple of Kangee
by Chris H. » 25 Dec 2009, 15:21
I think that I found the GUI code which creates the color borders for cards located in GuiDisplay.java. I think that zerker's color keyword could be added this code and this would allow cards to have the appropriate border color with his keyword.
This brings up several issues. I imagine that Rares originally wrote this code when there were no card jpgs to display. The few cards that were included were simple enough that it did not at that time lead to some of the discrepancies that I am seeing at this time.
Some people are creatures of habit and may not like it if too many modifications are made to this code. Other people will want to see card border colors become more rules compliant.
I think that I am in the second camp. I recently modified the Disciple of Kangee. It would be nice if the target creature would have it's border color changed to blue until the end of turn.
How do other people feel?
This brings up several issues. I imagine that Rares originally wrote this code when there were no card jpgs to display. The few cards that were included were simple enough that it did not at that time lead to some of the discrepancies that I am seeing at this time.
Some people are creatures of habit and may not like it if too many modifications are made to this code. Other people will want to see card border colors become more rules compliant.
I think that I am in the second camp. I recently modified the Disciple of Kangee. It would be nice if the target creature would have it's border color changed to blue until the end of turn.
How do other people feel?
-
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: Disciple of Kangee
by DennisBergkamp » 25 Dec 2009, 16:36
Yeah I think border colors should change (it's not like we're changing the color of the card picture after all).
-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: Disciple of Kangee
by Chris H. » 25 Dec 2009, 17:49
I have made the changes and it appears to work correctly. Kobolds now have a red colored border. Ghostfire has a gray colored border, yeah ... but for some reason zerkers color keyword is no displaying the cart text:
"Ghostfire is colorless."
The code changes below:
There is another code section which follows, I have not changed it and things appear to work so far. The code below, I guess should also be changed?
"Ghostfire is colorless."
The code changes below:
- Code: Select all
if(CardUtil.getColors(card).size() != 1)
color = Color.orange;
else if(CardUtil.getColor(card).equals(Constant.Color.Colorless) || (card.getIntrinsicKeyword().contains(card.getName() + " is colorless.")))
color = Color.gray;
else if(CardUtil.getColor(card).equals(Constant.Color.Black) || (card.getIntrinsicKeyword().contains(card.getName() + " is black.")))
color = Color.black;
else if(CardUtil.getColor(card).equals(Constant.Color.Green) || (card.getIntrinsicKeyword().contains(card.getName() + " is green.")))
color = new Color(0, 220, 39);
else if(CardUtil.getColor(card).equals(Constant.Color.White) || (card.getIntrinsicKeyword().contains(card.getName() + " is white.")))
color = Color.white;
else if(CardUtil.getColor(card).equals(Constant.Color.Red) || (card.getIntrinsicKeyword().contains(card.getName() + " is red.")))
color = Color.red;
else if(CardUtil.getColor(card).equals(Constant.Color.Blue) || (card.getIntrinsicKeyword().contains(card.getName() + " is blue.")))
color = Color.blue;
else color = Color.gray;
There is another code section which follows, I have not changed it and things appear to work so far. The code below, I guess should also be changed?
- Code: Select all
if(!card.isArtifact()) {
int r = color.getRed();
int g = color.getGreen();
int b = color.getBlue();
int shade = 10;
r -= shade;
g -= shade;
b -= shade;
r = Math.max(0, r);
g = Math.max(0, g);
b = Math.max(0, b);
color = new Color(r, g, b);
}
-
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
20 posts
• Page 1 of 2 • 1, 2
Who is online
Users browsing this forum: No registered users and 26 guests