mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 20:58:03 +00:00
*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:
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user