*Added Convoke for the human only. (AI will always pay full cost currently.)

*Converted Sprout Swarm to script and completed it.
*Added
	Autochthon Wurm
	Conclave Equenaut
	Conclave Phalanx
	Conclave's Blessing
	Devouring Light
	Gather Courage
	Guardian of Vitu-Ghazi
	Hour of Reckoning
	Kavu Primarch
	Overwhelm
	Root-Kin Ally
	Scatter the Seeds
	Siege Wurm
	Sundering Vitae
This commit is contained in:
Hellfish
2011-11-05 13:32:31 +00:00
parent d7d1b71c13
commit 3e4f405fb3
22 changed files with 409 additions and 62 deletions

View File

@@ -16,6 +16,7 @@ import org.apache.commons.lang3.StringUtils;
import forge.card.mana.ManaCost;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityList;
import forge.gui.input.InputPayManaCostUtil;
import forge.item.CardPrinted;
import forge.properties.ForgeProps;
import forge.properties.NewConstants;
@@ -928,5 +929,31 @@ public final class CardUtil {
return res;
}
public static ArrayList<String> getConvokableColors(final Card cardToConvoke, ManaCost cost)
{
ArrayList<String> usableColors = new ArrayList<String>();
if(cost.getColorlessManaAmount() > 0)
{
usableColors.add("colorless");
}
for(CardColor col : cardToConvoke.getColor())
{
for(String strCol : col.toStringArray())
{
if(strCol.equals("colorless"))
{
continue;
}
if(cost.toString().contains(InputPayManaCostUtil.getShortColorString(strCol)))
{
usableColors.add(strCol.toString());
}
}
}
return usableColors;
}
} // end class CardUtil

View File

@@ -36,6 +36,7 @@ import forge.gui.GuiUtils;
import forge.gui.input.InputMulligan;
import forge.gui.input.InputPayManaCost;
import forge.gui.input.InputPayManaCostAbility;
import forge.gui.input.InputPayManaCostUtil;
import forge.item.CardPrinted;
import forge.properties.ForgeProps;
import forge.properties.NewConstants.Lang.GameAction.GameActionText;
@@ -2032,7 +2033,103 @@ public class GameAction {
this.exile(chosen);
}
manaCost = new ManaCost(originalCost.toString());
manaCost.decreaseColorlessMana(numToExile);
}
} else if (spell.getSourceCard().hasKeyword("Convoke")) {
CardList untappedCreats = spell.getActivatingPlayer().getCardsIn(Zone.Battlefield).getType("Creature");
untappedCreats = untappedCreats.filter(new CardListFilter() {
public boolean addCard(Card c) {
return !c.isTapped();
}
});
if(untappedCreats.size() != 0)
{
ArrayList<Object> choices = new ArrayList<Object>();
for(Card c : untappedCreats) {
choices.add(c);
}
choices.add("DONE");
ArrayList<String> usableColors = new ArrayList<String>();
ManaCost newCost = new ManaCost(originalCost.toString());
Object tapForConvoke = null;
if(sa.getActivatingPlayer().isHuman())
{
tapForConvoke = GuiUtils.getChoiceOptional("Tap for Convoke? " + newCost.toString(), choices.toArray());
}
else {
//TODO: AI to choose a creature to tap would go here
//Probably along with deciding how many creatures to tap
}
while(tapForConvoke != null && (tapForConvoke instanceof Card) && untappedCreats.size() != 0) {
Card workingCard = (Card) tapForConvoke;
usableColors = CardUtil.getConvokableColors(workingCard, newCost);
if(usableColors.size() != 0)
{
String chosenColor = usableColors.get(0);
if(usableColors.size() > 1)
{
if(sa.getActivatingPlayer().isHuman())
{
chosenColor = (String)GuiUtils.getChoice("Convoke for which color?", usableColors.toArray());
}
else
{
//TODO: AI for choosing which color to convoke goes here.
}
}
if(chosenColor.equals("colorless"))
{
newCost.decreaseColorlessMana(1);
}
else
{
String newCostStr = newCost.toString();
newCostStr = newCostStr.replaceFirst(InputPayManaCostUtil.getShortColorString(chosenColor), "");
newCost = new ManaCost(newCostStr.trim());
}
sa.addTappedForConvoke(workingCard);
choices.remove(workingCard);
untappedCreats.remove(workingCard);
if(choices.size() < 2 || newCost.getConvertedManaCost() == 0) {
break;
}
}
else
{
untappedCreats.remove(workingCard);
}
if(sa.getActivatingPlayer().isHuman())
{
tapForConvoke = GuiUtils.getChoiceOptional("Tap for Convoke? " + newCost.toString(), choices.toArray());
}
else {
//TODO: AI to choose a creature to tap would go here
}
}
//will only be null if user cancelled.
if(tapForConvoke != null) {
//Convoked creats are tapped here with triggers suppressed,
//Then again when payment is done(In InputPayManaCost.done()) with suppression cleared.
//This is to make sure that triggers go off at the right time
//AND that you can't use mana tapabilities of convoked creatures
//to pay the convoked cost.
AllZone.getTriggerHandler().suppressMode("Taps");
for(Card c : sa.getTappedForConvoke()) {
c.tap();
}
AllZone.getTriggerHandler().clearSuppression("Taps");
manaCost = newCost;
}
}
}
} // isSpell
@@ -2535,7 +2632,7 @@ public class GameAction {
AllZone.getInputControl().setInput(sa.getAfterPayMana());
}
} else if (sa.getBeforePayMana() == null) {
AllZone.getInputControl().setInput(new InputPayManaCost(sa));
AllZone.getInputControl().setInput(new InputPayManaCost(sa,manaCost));
} else {
AllZone.getInputControl().setInput(sa.getBeforePayMana());
}

View File

@@ -52,53 +52,7 @@ public class CardFactoryInstants {
public static Card getCard(final Card card, final String cardName) {
// *************** START *********** START **************************
if (cardName.equals("Sprout Swarm")) {
final SpellAbility spellOne = new Spell(card) {
private static final long serialVersionUID = -609007714604161377L;
@Override
public boolean canPlayAI() {
return false;
}
@Override
public void resolve() {
CardFactoryUtil.makeTokenSaproling(card.getController());
}
}; // SpellAbility
final SpellAbility spellTwo = new Spell(card) {
private static final long serialVersionUID = -1387385820860395676L;
@Override
public void resolve() {
CardFactoryUtil.makeTokenSaproling(card.getController());
// return card to the hand
final PlayerZone hand = card.getController().getZone(Constant.Zone.Hand);
AllZone.getGameAction().moveTo(hand, card);
}
}; // SpellAbility
spellOne.setManaCost("1 G");
spellTwo.setManaCost("4 G");
spellTwo.setAdditionalManaCost("3");
spellOne.setDescription("Put a 1/1 green Saproling token onto the battlefield.");
spellTwo.setDescription("Buyback 3 (You may pay an additional 3 as you cast this spell. "
+ "If you do, put this card into your hand as it resolves.)");
spellOne.setStackDescription("Sprout Swarm - Put a 1/1 green Saproling token onto the battlefield");
spellTwo.setStackDescription("Sprout Swarm - Buyback, Put a 1/1 green "
+ "Saproling token onto the battlefield");
spellTwo.setIsBuyBackAbility(true);
card.addSpellAbility(spellOne);
card.addSpellAbility(spellTwo);
} // *************** END ************ END **************************
// *************** START *********** START **************************
else if (cardName.equals("Fact or Fiction")) {
if (cardName.equals("Fact or Fiction")) {
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = 1481112451519L;

View File

@@ -387,11 +387,38 @@ public class CostMana extends CostPart {
source.setXManaCostPaid(0);
CostUtil.setInput(CostMana.inputPayXMana(sa, payment, costMana, costMana.getXMana()));
}
//If this is a spell with convoke, re-tap all creatures used for it.
//This is done to make sure Taps triggers go off at the right time
//(i.e. AFTER cost payment, they are tapped previously as well so that
//any mana tapabilities can't be used in payment as well as being tapped for convoke)
if(sa.getTappedForConvoke() != null)
{
AllZone.getTriggerHandler().suppressMode("Untaps");
for(Card c : sa.getTappedForConvoke()) {
c.untap();
c.tap();
}
AllZone.getTriggerHandler().clearSuppression("Untaps");
sa.clearTappedForConvoke();
}
}
@Override
public void selectButtonCancel() {
//If we're paying for a spell with convoke, untap all creatures used for it.
if(sa.getTappedForConvoke() != null)
{
AllZone.getTriggerHandler().suppressMode("Untaps");
for(Card c : sa.getTappedForConvoke()) {
c.untap();
}
AllZone.getTriggerHandler().clearSuppression("Untaps");
sa.clearTappedForConvoke();
}
this.stop();
this.resetManaCost();
payment.cancelCost();

View File

@@ -108,6 +108,8 @@ public abstract class SpellAbility {
public void execute(final Object o) {
}
};
private CardList tappedForConvoke = null;
/**
* <p>
@@ -1706,5 +1708,28 @@ public abstract class SpellAbility {
public void setChosenTarget(Target chosenTarget) {
this.chosenTarget = chosenTarget; // TODO: Add 0 to parameter's name.
}
public void addTappedForConvoke(Card c)
{
if(tappedForConvoke == null)
{
tappedForConvoke = new CardList();
}
tappedForConvoke.add(c);
}
public CardList getTappedForConvoke()
{
return tappedForConvoke;
}
public void clearTappedForConvoke()
{
if(tappedForConvoke != null)
{
tappedForConvoke.clear();
}
}
}

View File

@@ -72,6 +72,18 @@ public class InputPayManaCost extends Input {
}
}
/**
* <p>
* Constructor for Input_PayManaCost.
* </p>
*
* @param sa
* a {@link forge.card.spellability.SpellAbility} object.
*/
public InputPayManaCost(final SpellAbility sa) {
this(sa,new ManaCost(sa.getManaCost()));
}
/**
* <p>
* Constructor for Input_PayManaCost.
@@ -79,9 +91,12 @@ public class InputPayManaCost extends Input {
*
* @param sa
* a {@link forge.card.spellability.SpellAbility} object.
*
* @param manaCostToPay
* a {@link forge.card.mana.ManaCost} object.
*/
public InputPayManaCost(final SpellAbility sa) {
this.originalManaCost = sa.getManaCost(); // Change
public InputPayManaCost(final SpellAbility sa, final ManaCost manaCostToPay) {
this.originalManaCost = manaCostToPay.toString(); // Change
this.originalCard = sa.getSourceCard();
this.spell = sa;
@@ -95,7 +110,7 @@ public class InputPayManaCost extends Input {
AllZone.getStack().add(this.spell);
}
} else {
this.manaCost = AllZone.getGameAction().getSpellCostChange(sa, new ManaCost(this.originalManaCost));
this.manaCost = manaCostToPay;//AllZone.getGameAction().getSpellCostChange(sa, new ManaCost(this.originalManaCost));
}
} else {
this.manaCost = new ManaCost(sa.getManaCost());
@@ -196,25 +211,43 @@ public class InputPayManaCost extends Input {
}
AllZone.getInputControl().resetInput();
}
//If this is a spell with convoke, re-tap all creatures used for it.
//This is done to make sure Taps triggers go off at the right time
//(i.e. AFTER cost payment, they are tapped previously as well so that
//any mana tapabilities can't be used in payment as well as being tapped for convoke)
if(spell.getTappedForConvoke() != null)
{
AllZone.getTriggerHandler().suppressMode("Untaps");
for(Card c : spell.getTappedForConvoke()) {
c.untap();
c.tap();
}
AllZone.getTriggerHandler().clearSuppression("Untaps");
spell.clearTappedForConvoke();
}
}
}
/** {@inheritDoc} */
@Override
public final void selectButtonCancel() {
//If this is a spell with convoke, untap all creatures used for it.
if(spell.getTappedForConvoke() != null)
{
AllZone.getTriggerHandler().suppressMode("Untaps");
for(Card c : spell.getTappedForConvoke()) {
c.untap();
}
AllZone.getTriggerHandler().clearSuppression("Untaps");
spell.clearTappedForConvoke();
}
this.resetManaCost();
AllZone.getHumanPlayer().getManaPool().unpaid(this.spell, true);
AllZone.getHumanPlayer().getZone(Zone.Battlefield).updateObservers(); // DO
// NOT
// REMOVE
// THIS,
// otherwise
// the
// cards
// don't
// always
// tap
this.stop();
}