Monday, July 16, 2007

Input Explained

Some people have commented that the Input class is giving them problems and I understand where they are coming from. All of this code was never meant to be understood by anyone else, lol. Anyways, the Input class handles all the user input, which is from a mouse, and is used to set targets for cards. The targets may be either a player or a card. SpellAbility setTargetPlayer(String player) and setTargetCard(Card) actually sets the target that the resolve will use. There is corresponding getTargetPlay and getTargetCard commands. This limits cards to a single target. Hex has multiple targets, but it is an exception. Multiple targets can be programmed but the code is messy.

The method SpellAbility setBeforePayMana(Input) is used to set the Input that will handle getting a card’s target. The method could have been named better.

CardFactoryUtil returns common Inputs that are useful.

To target a player, CardFactoryUtil.input_targetPlayer(SpellAbility spell). Hopefully Ancestral Recall is straightforward and easy to understand. The computer always sets himself as the target with the method setChooseTargetAI and canPlayAI makes sure the computer doesn’t have to discard any cards.


if(cardName.equals("Ancestral Recall"))
{
SpellAbility spell = new Spell(card)
{
public void resolve()
{
AllZone.GameAction.drawCard(getTargetPlayer());
AllZone.GameAction.drawCard(getTargetPlayer());
AllZone.GameAction.drawCard(getTargetPlayer());
}
public boolean canPlayAI()
{
return AllZone.Computer_Hand.getCards().length <= 5;
}
};
spell.setChooseTargetAI(CardFactoryUtil.AI_targetComputer());

spell.setBeforePayMana(CardFactoryUtil.input_targetPlayer(spell));
card.clearSpellAbility();
card.addSpellAbility(spell);


To target a creature, CardFactoryUtil. input_targetCreature(SpellAbility spell) Swords to Plowshares removes a creature from play and gives it’s controller some life.


if(cardName.equals("Swords to Plowshares"))
{
SpellAbility spell = new Spell(card)
{
public void resolve()
{
if(AllZone.GameAction.isCardInPlay(getTargetCard()))
{
//add life
String player = getTargetCard().getController();
PlayerLife life = AllZone.GameAction.getPlayerLife(player);
life.addLife(getTargetCard().getAttack());

//remove card from play
PlayerZone zone = AllZone.getZone(getTargetCard());
zone.remove(getTargetCard());
}
}//resolve()
public boolean canPlayAI()
{
CardList creature = new CardList(AllZone.Human_Play.getCards());
creature = creature.getType("Creature");
return creature.size() != 0 && (AllZone.Phase.getTurn() > 4);
}
public void chooseTargetAI()
{
CardList play = new CardList(AllZone.Human_Play.getCards());
Card target = CardFactoryUtil.AI_getBestCreature(play);
setTargetCard(target);
}
};//SpellAbility
spell.setBeforePayMana(CardFactoryUtil.input_targetCreature(spell));

card.clearSpellAbility();
card.addSpellAbility(spell);
}


To target anything in the “type” line of a card like Creature, Land, Goblin, or Forest. CardFactoryUtil.input_targetType(SpellAbility spell, String cardType)
Type can also be “All” which would let the user target any permanent.


if(cardName.equals("Stone Rain"))
{
final SpellAbility spell = new Spell(card)
{
public void resolve()
{
Card c = getTargetCard();
if(AllZone.GameAction.isCardInPlay(c))
AllZone.GameAction.destroy(c);
}

};//Spell
card.clearSpellAbility();
card.addSpellAbility(spell);

spell.setChooseTargetAI(CardFactoryUtil.AI_targetType("Land", AllZone.Human_Play));

spell.setBeforePayMana(CardFactoryUtil.input_targetType(spell, "Land"));
}


Stone Rain also configures the AI by the method
CardFactoryUtil.AI_targetType(String type, PlayerZone zone)

Type is like Forest, Creature, Land, or All. Common PlayerZones are

AllZone.Human_Play – Shock
AllZone.Computer_Play – Giant Growth
AllZone.Computer_Graveyard – Gravedigger

AllZone is just a global object that holds all of the “zones”, like in play, graveyard, etc…

The human player can only target cards in play, so cards like Gravedigger show a window so a card from the graveyard can be selected. Dark Banishing has a custom Input that targets a non-black creature. After a creature is chosen in the selectCard method, the user has to pay the mana cost which stops the current Input. The SpellAbility of Dark Banishing was omitted for clarity.


Input target = new Input()
{
public void showMessage()
{
AllZone.Display.showMessage("Select target non-black creature for " +spell.getSourceCard());

ButtonUtil.enableOnlyCancel();
}
public void selectButtonCancel() {stop();}

public void selectCard(Card card, PlayerZone zone)
{
if((!CardUtil.getColors(card).contains(Constant.Color.Black))
&& card.isCreature()
&& zone.is(Constant.Zone.Play))
{
spell.setTargetCard(card);
stopSetNext(new Input_PayManaCost(spell));
}//if
}//selectCard()
};//Input

spell.setBeforePayMana(target);

No comments: