Academy Rector code question
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Agetian, friarsol, Blacksmith, KrazyTheFox, CCGHQ Admins
5 posts
• Page 1 of 1
Academy Rector code question
by Chris H. » 19 Dec 2010, 15:12
In recnt months I have tried to add a yes/no dialog to the cards which are missing this choice. I am also trying to replace the list-form yes/no dialog with a button-type yes/no dialog. I have some initial work done for Academy Rector. I ran into a couple of issues and I could use some advice on how to proceed.
On my local copy Academy Rector will now use a button-type yes/no dialog. A list dialog comes up with a listing of all of the enchantments located in your library.
I noticed that in the old code if you selected an Enchant creature aura that you would get a listing with the creatures on both sides of the battlefield. This can make it difficult to select the correct creature for your curse or your buff.
There are a number of cards which share the "When CARDNAME is put into a graveyard from " {play or battlefield} style of code. They have a Command which does much of the work and use one of the CardFactoryUtil inputs. These inputs require a spell ability as a parameter included in the call.
These cards have a spell ability and a stack description. Academy Rector does not and is different and is handled differently. So, is having a spell ability, an "AllZone.Stack.add(ability);" and a stack description a rules correct way of implementing these types of cards. If not, then they may have been coded this way inorder to use one of the more user-frindly inputs.
So I am kind of stuck on the Academy Rector code mods for the moment. Should I add the missing spell ability, an "AllZone.Stack.add(ability);" and a stack description? Or if this is not correct, is it possible to modify the input_targetSpecific() method and make a 2nd one which would use a command rather than a sa as a parameter?
On my local copy Academy Rector will now use a button-type yes/no dialog. A list dialog comes up with a listing of all of the enchantments located in your library.
I noticed that in the old code if you selected an Enchant creature aura that you would get a listing with the creatures on both sides of the battlefield. This can make it difficult to select the correct creature for your curse or your buff.
There are a number of cards which share the "When CARDNAME is put into a graveyard from " {play or battlefield} style of code. They have a Command which does much of the work and use one of the CardFactoryUtil inputs. These inputs require a spell ability as a parameter included in the call.
These cards have a spell ability and a stack description. Academy Rector does not and is different and is handled differently. So, is having a spell ability, an "AllZone.Stack.add(ability);" and a stack description a rules correct way of implementing these types of cards. If not, then they may have been coded this way inorder to use one of the more user-frindly inputs.
So I am kind of stuck on the Academy Rector code mods for the moment. Should I add the missing spell ability, an "AllZone.Stack.add(ability);" and a stack description? Or if this is not correct, is it possible to modify the input_targetSpecific() method and make a 2nd one which would use a command rather than a sa as a parameter?
-

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: Academy Rector code question
by Sloth » 19 Dec 2010, 15:57
Ruleswise the ability should use the stack (it's a triggered ability), so your opponent is able to Stifle it.Chris H. wrote:So I am kind of stuck on the Academy Rector code mods for the moment. Should I add the missing spell ability, an "AllZone.Stack.add(ability);" and a stack description? Or if this is not correct, is it possible to modify the input_targetSpecific() method and make a 2nd one which would use a command rather than a sa as a parameter?
-

Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: Academy Rector code question
by friarsol » 19 Dec 2010, 16:22
From a rules perspective here's what happens with all of those cards:
It hits the graveyard from the battlefield, and it's triggered ability goes on the stack. When it resolves you choose whether or not to exile it. If you do, you search up an enchantment and put it onto the battlefield. If the enchantment is an Aura, you then choose a legal card to attach it to (this is non-targeted).
Technically, all of that is one resolving ability. If there are two abilities (one for the trigger and one for the fetch) it's not quite right.
In the future, once we have AF_Trigger setup it should be able to handle this situation in one encompassing Ability. (Assuming at that point we have some type of "conditional" AF. That will handle "You may do X. If you do, do <subAbility>")
It hits the graveyard from the battlefield, and it's triggered ability goes on the stack. When it resolves you choose whether or not to exile it. If you do, you search up an enchantment and put it onto the battlefield. If the enchantment is an Aura, you then choose a legal card to attach it to (this is non-targeted).
Technically, all of that is one resolving ability. If there are two abilities (one for the trigger and one for the fetch) it's not quite right.
In the future, once we have AF_Trigger setup it should be able to handle this situation in one encompassing Ability. (Assuming at that point we have some type of "conditional" AF. That will handle "You may do X. If you do, do <subAbility>")
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Academy Rector code question
by Chris H. » 19 Dec 2010, 17:08
Thank you for the info Sloth and Sol. 
-

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: Academy Rector code question
by Chris H. » 21 Dec 2010, 19:42
I finished my improvements for Academy Rector. It was more work than I expected but I had a null error to fix ... had to make my own input to avoid this bug.
I have included the code below but it will be hard to read given the amount of indentation needed to make it work. The destroy Command now only holds the "AllZone.Stack.add(ability);" line of code. Everything else was moved into an ability. The input is also inside of the ability. I think this is what Sol wanted to see.
I have included the code below but it will be hard to read given the amount of indentation needed to make it work. The destroy Command now only holds the "AllZone.Stack.add(ability);" line of code. Everything else was moved into an ability. The input is also inside of the ability. I think this is what Sol wanted to see.
- Code: Select all
//*************** START *********** START **************************
else if(cardName.equals("Academy Rector")) {
final SpellAbility ability = new Ability(card, "0") {
@Override
public void resolve() {
if (card.getController().equals(AllZone.HumanPlayer)) {
StringBuilder question = new StringBuilder();
question.append("Exile ").append(card.getName());
question.append(" and place an enchantment from your library onto the battlefield?");
if (GameActionUtil.showYesNoDialog(card, question.toString())) {
AllZone.GameAction.exile(card);
PlayerZone lib = AllZone.getZone(Constant.Zone.Library, AllZone.HumanPlayer);
CardList list = AllZoneUtil.getPlayerCardsInLibrary(AllZone.HumanPlayer);
list = list.getType("Enchantment");
if (list.size() > 0) {
Object objectSelected = AllZone.Display.getChoiceOptional("Choose an enchantment", list.toArray());
if (objectSelected != null) {
PlayerZone play = AllZone.getZone(Constant.Zone.Battlefield, AllZone.HumanPlayer);
final Card c = (Card) objectSelected;
lib.remove(c);
play.add(c);
if (c.isAura()) {
String enchantThisType[] = {""};
String message[] = {""};
// The type following "Enchant" maybe upercase or lowercase, cardsfolder has both
// Note that I am being overly cautious.
if (c.getKeyword().contains("Enchant creature without flying") || c.getKeyword().contains("Enchant Creature without flying")) {
enchantThisType[0] = "Creature.withoutFlying";
message[0] = "Select a creature without flying";
} else if (c.getKeyword().contains("Enchant creature with converted mana cost 2 or less") || c.getKeyword().contains("Enchant Creature with converted mana cost 2 or less")) {
enchantThisType[0] = "Creature.cmcLE2";
message[0] = "Select a creature with converted mana cost 2 or less";
} else if (c.getKeyword().contains("Enchant red or green creature")) {
enchantThisType[0] = "Creature.Red,Creature.Green";
message[0] = "Select a red or green creature";
} else if (c.getKeyword().contains("Enchant tapped creature")) {
enchantThisType[0] = "Creature.tapped";
message[0] = "Select a tapped creature";
} else if (c.getKeyword().contains("Enchant creature") || c.getKeyword().contains("Enchant Creature")) {
enchantThisType[0] = "Creature";
message[0] = "Select a creature";
} else if (c.getKeyword().contains("Enchant wall") || c.getKeyword().contains("Enchant Wall")) {
enchantThisType[0] = "Wall";
message[0] = "Select a Wall";
} else if (c.getKeyword().contains("Enchant land you control") || c.getKeyword().contains("Enchant Land you control")) {
enchantThisType[0] = "Land.YouCtrl";
message[0] = "Select a land you control";
} else if (c.getKeyword().contains("Enchant land") || c.getKeyword().contains("Enchant Land")) {
enchantThisType[0] = "Land";
message[0] = "Select a land";
} else if (c.getKeyword().contains("Enchant artifact") || c.getKeyword().contains("Enchant Artifact")) {
enchantThisType[0] = "Artifact";
message[0] = "Select an artifact";
} else if (c.getKeyword().contains("Enchant enchantment") || c.getKeyword().contains("Enchant Enchantment")) {
enchantThisType[0] = "Enchantment";
message[0] = "Select an enchantment";
}
CardList allCards = new CardList();
allCards.addAll(AllZone.Human_Battlefield.getCards());
allCards.addAll(AllZone.Computer_Battlefield.getCards());
// Make sure that we were able to match the selected aura with our list of criteria
if (enchantThisType[0] != "" && message[0] != "") {
final CardList choices = allCards.getValidCards(enchantThisType[0], card.getController(), card);
final String msg = message[0];
AllZone.InputControl.setInput(new Input() {
private static final long serialVersionUID = -6271957194091955059L;
@Override
public void showMessage() {
AllZone.Display.showMessage(msg);
ButtonUtil.enableOnlyOK();
}
@Override
public void selectButtonOK() {
stop();
}
@Override
public void selectCard(Card card, PlayerZone zone) {
if (choices.contains(card)) {
if (AllZone.GameAction.isCardInPlay(card)) {
c.enchantCard(card);
stop();
}
}
}//selectCard()
});// Input()
}// if we were able to match the selected aura with our list of criteria
}// If enchantment selected is an aura
}// If an enchantment is selected
}// If there are enchantments in library
}// If answered yes to may exile
}// If player is human
// player is the computer
else {
PlayerZone lib = AllZone.getZone(Constant.Zone.Library, AllZone.ComputerPlayer);
CardList list = new CardList(lib.getCards());
list = list.filter(new CardListFilter() {
public boolean addCard(Card c) {
return c.isEnchantment() && !c.isAura();
}
});
if (list.size() > 0) {
PlayerZone play = AllZone.getZone(Constant.Zone.Battlefield, AllZone.ComputerPlayer);
Card c = CardFactoryUtil.AI_getBestEnchantment(list, card, false);
lib.remove(c);
play.add(c);
AllZone.GameAction.exile(card);
}
}// player is the computer
}// resolve()
};// ability
StringBuilder sb = new StringBuilder();
sb.append("Academy Rector - ").append(card.getController());
sb.append(" may exile this card and place an enchantment from his library onto the battlefield.");
ability.setStackDescription(sb.toString());
final Command destroy = new Command() {
private static final long serialVersionUID = -4352349741511065318L;
public void execute() {
AllZone.Stack.add(ability);
}// execute()
};// Command destroy
card.addDestroyCommand(destroy);
}//*************** 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
5 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 23 guests