mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 10:48:00 +00:00
- Converted Ripple to script
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
Name:Thrumming Stone
|
||||
ManaCost:5
|
||||
Types:Legendary Artifact
|
||||
Text:Spells you cast have ripple 4.
|
||||
T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigRem | TriggerDescription$ Spells you cast have ripple 4. (Whenever you cast a spell, you may reveal the top four cards of your library. You may cast any revealed cards with the same name as the spell without paying their mana costs. Put the rest on the bottom of your library.)
|
||||
SVar:TrigRem:AB$ Pump | Cost$ 0 | ImprintCards$ TriggeredCard | SubAbility$ TrigRipple
|
||||
SVar:TrigRipple:DB$ Dig | NoMove$ True | DigNum$ 4 | Reveal$ True | RememberRevealed$ True | SubAbility$ DBThrummingRipple
|
||||
SVar:DBThrummingRipple:DB$ Play | Valid$ Card.IsRemembered+sharesNameWith Imprinted | ValidZone$ Library | WithoutManaCost$ True | Optional$ True | Amount$ All | SubAbility$ ThrummingMoveToBottom
|
||||
SVar:ThrummingMoveToBottom:DB$ ChangeZoneAll | ChangeType$ Card.IsRemembered | Origin$ Library | Destination$ Library | LibraryPosition$ -1 | SubAbility$ ThrummingCleanup
|
||||
SVar:ThrummingCleanup:DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/thrumming_stone.jpg
|
||||
Oracle:Spells you cast have ripple 4. (Whenever you cast a spell, you may reveal the top four cards of your library. You may cast any revealed cards with the same name as the spell without paying their mana costs. Put the rest on the bottom of your library.)
|
||||
@@ -3192,6 +3192,36 @@ public class CardFactoryUtil {
|
||||
final Trigger myTrigger = TriggerHandler.parseTrigger(trigStr, card, true);
|
||||
card.addTrigger(myTrigger);
|
||||
} // Recover
|
||||
|
||||
int ripplePos = hasKeyword(card, "Ripple");
|
||||
while (ripplePos != -1) {
|
||||
final int n = ripplePos;
|
||||
final String parse = card.getKeyword().get(n);
|
||||
final String[] k = parse.split(":");
|
||||
final int num = Integer.parseInt(k[1]);
|
||||
UUID triggerSvar = UUID.randomUUID();
|
||||
|
||||
final String actualTrigger = "Mode$ SpellCast | ValidCard$ Card.Self | " +
|
||||
"Execute$ " + triggerSvar + " | Secondary$ True | TriggerDescription$" +
|
||||
" Ripple " + num + " - CARDNAME | OptionalDecider$ You";
|
||||
final String abString = "AB$ Dig | Cost$ 0 | NoMove$ True | DigNum$ " + num +
|
||||
" | Reveal$ True | RememberRevealed$ True | SubAbility$ DBCastRipple";
|
||||
final String dbCast = "DB$ Play | Valid$ Card.IsRemembered+sameName | " +
|
||||
"ValidZone$ Library | WithoutManaCost$ True | Optional$ True | " +
|
||||
"Amount$ All | SubAbility$ RippleMoveToBottom";
|
||||
|
||||
card.setSVar(triggerSvar.toString(), abString);
|
||||
card.setSVar("DBCastRipple", dbCast);
|
||||
card.setSVar("RippleMoveToBottom", "DB$ ChangeZoneAll | ChangeType$ " +
|
||||
"Card.IsRemembered | Origin$ Library | Destination$ Library | " +
|
||||
"LibraryPosition$ -1 | SubAbility$ RippleCleanup");
|
||||
card.setSVar("RippleCleanup", "DB$ Cleanup | ClearRemembered$ True");
|
||||
|
||||
final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, card, true);
|
||||
card.addTrigger(parsedTrigger);
|
||||
|
||||
ripplePos = hasKeyword(card, "Ripple", n + 1);
|
||||
} // Ripple
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -51,14 +51,8 @@ import forge.card.spellability.AbilitySub;
|
||||
import forge.card.spellability.OptionalCost;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.SpellAbilityRestriction;
|
||||
import forge.game.ai.AiController;
|
||||
import forge.game.player.HumanPlay;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerActionConfirmMode;
|
||||
import forge.game.player.PlayerControllerAi;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.GuiChoose;
|
||||
import forge.gui.GuiDialog;
|
||||
import forge.util.TextUtil;
|
||||
|
||||
|
||||
@@ -72,135 +66,135 @@ import forge.util.TextUtil;
|
||||
*/
|
||||
public final class GameActionUtil {
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this type.
|
||||
*
|
||||
*/
|
||||
public static final class RippleAbility extends Ability {
|
||||
private final Player controller;
|
||||
private final int rippleCount;
|
||||
private final Card rippleCard;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for Constructor.
|
||||
* @param sourceCard
|
||||
* @param manaCost
|
||||
* @param controller
|
||||
* @param rippleCount
|
||||
* @param rippleCard
|
||||
*/
|
||||
private RippleAbility(Card sourceCard, ManaCost manaCost, Player controller, int rippleCount,
|
||||
Card rippleCard) {
|
||||
super(sourceCard, manaCost);
|
||||
this.controller = controller;
|
||||
this.rippleCount = rippleCount;
|
||||
this.rippleCard = rippleCard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolve() {
|
||||
final List<Card> topOfLibrary = controller.getCardsIn(ZoneType.Library);
|
||||
final List<Card> revealed = new ArrayList<Card>();
|
||||
int rippleNumber = rippleCount;
|
||||
if (topOfLibrary.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Shouldn't Have more than Ripple 10, seeing as no
|
||||
// cards exist with a ripple greater than 4
|
||||
final int rippleMax = 10;
|
||||
final Card[] rippledCards = new Card[rippleMax];
|
||||
Card crd;
|
||||
if (topOfLibrary.size() < rippleNumber) {
|
||||
rippleNumber = topOfLibrary.size();
|
||||
}
|
||||
|
||||
for (int i = 0; i < rippleNumber; i++) {
|
||||
crd = topOfLibrary.get(i);
|
||||
revealed.add(crd);
|
||||
if (crd.getName().equals(rippleCard.getName())) {
|
||||
rippledCards[i] = crd;
|
||||
}
|
||||
} // for
|
||||
GuiChoose.oneOrNone("Revealed cards:", revealed);
|
||||
for (int i = 0; i < rippleMax; i++) {
|
||||
if (rippledCards[i] != null) {
|
||||
Player p = rippledCards[i].getController();
|
||||
|
||||
if (p.isHuman()) {
|
||||
if (GuiDialog.confirm(rippledCards[i], "Cast " + rippledCards[i].getName() + "?")) {
|
||||
HumanPlay.playCardWithoutPayingManaCost(p, rippledCards[i]);
|
||||
revealed.remove(rippledCards[i]);
|
||||
}
|
||||
} else {
|
||||
final AiController aic = ((PlayerControllerAi)p.getController()).getAi();
|
||||
SpellAbility saPlayed = aic.chooseAndPlaySa(rippledCards[i].getBasicSpells(), false, true);
|
||||
if ( saPlayed != null )
|
||||
revealed.remove(rippledCards[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
CardLists.shuffle(revealed);
|
||||
for (final Card bottom : revealed) {
|
||||
controller.getGame().getAction().moveToBottomOfLibrary(bottom);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this type.
|
||||
*
|
||||
*/
|
||||
public static final class RippleExecutor implements Command {
|
||||
private final Player controller;
|
||||
private final Card c;
|
||||
private static final long serialVersionUID = -845154812215847505L;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for Constructor.
|
||||
* @param controller
|
||||
* @param c
|
||||
*/
|
||||
public RippleExecutor(Player controller, Card c) {
|
||||
this.controller = controller;
|
||||
this.c = c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
final List<Card> thrummingStones = controller.getCardsIn(ZoneType.Battlefield, "Thrumming Stone");
|
||||
for (int i = 0; i < thrummingStones.size(); i++) {
|
||||
c.addExtrinsicKeyword("Ripple:4");
|
||||
}
|
||||
|
||||
for (String parse : c.getKeyword()) {
|
||||
if (parse.startsWith("Ripple")) {
|
||||
final String[] k = parse.split(":");
|
||||
this.doRipple(c, Integer.valueOf(k[1]), controller);
|
||||
}
|
||||
}
|
||||
} // execute()
|
||||
|
||||
void doRipple(final Card c, final int rippleCount, final Player controller) {
|
||||
final Card rippleCard = c;
|
||||
|
||||
final Ability ability = new RippleAbility(c, ManaCost.ZERO, controller, rippleCount, rippleCard);
|
||||
|
||||
if (controller.getController().confirmAction(ability, PlayerActionConfirmMode.Ripple, "Activate Ripple for " + c + "?")) {
|
||||
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(c).append(" - Ripple.");
|
||||
ability.setStackDescription(sb.toString());
|
||||
ability.setDescription(sb.toString());
|
||||
ability.setActivatingPlayer(controller);
|
||||
|
||||
controller.getGame().getStack().addSimultaneousStackEntry(ability);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
// /**
|
||||
// * TODO: Write javadoc for this type.
|
||||
// *
|
||||
// */
|
||||
// public static final class RippleAbility extends Ability {
|
||||
// private final Player controller;
|
||||
// private final int rippleCount;
|
||||
// private final Card rippleCard;
|
||||
//
|
||||
// /**
|
||||
// * TODO: Write javadoc for Constructor.
|
||||
// * @param sourceCard
|
||||
// * @param manaCost
|
||||
// * @param controller
|
||||
// * @param rippleCount
|
||||
// * @param rippleCard
|
||||
// */
|
||||
// private RippleAbility(Card sourceCard, ManaCost manaCost, Player controller, int rippleCount,
|
||||
// Card rippleCard) {
|
||||
// super(sourceCard, manaCost);
|
||||
// this.controller = controller;
|
||||
// this.rippleCount = rippleCount;
|
||||
// this.rippleCard = rippleCard;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void resolve() {
|
||||
// final List<Card> topOfLibrary = controller.getCardsIn(ZoneType.Library);
|
||||
// final List<Card> revealed = new ArrayList<Card>();
|
||||
// int rippleNumber = rippleCount;
|
||||
// if (topOfLibrary.size() == 0) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // Shouldn't Have more than Ripple 10, seeing as no
|
||||
// // cards exist with a ripple greater than 4
|
||||
// final int rippleMax = 10;
|
||||
// final Card[] rippledCards = new Card[rippleMax];
|
||||
// Card crd;
|
||||
// if (topOfLibrary.size() < rippleNumber) {
|
||||
// rippleNumber = topOfLibrary.size();
|
||||
// }
|
||||
//
|
||||
// for (int i = 0; i < rippleNumber; i++) {
|
||||
// crd = topOfLibrary.get(i);
|
||||
// revealed.add(crd);
|
||||
// if (crd.getName().equals(rippleCard.getName())) {
|
||||
// rippledCards[i] = crd;
|
||||
// }
|
||||
// } // for
|
||||
// GuiChoose.oneOrNone("Revealed cards:", revealed);
|
||||
// for (int i = 0; i < rippleMax; i++) {
|
||||
// if (rippledCards[i] != null) {
|
||||
// Player p = rippledCards[i].getController();
|
||||
//
|
||||
// if (p.isHuman()) {
|
||||
// if (GuiDialog.confirm(rippledCards[i], "Cast " + rippledCards[i].getName() + "?")) {
|
||||
// HumanPlay.playCardWithoutPayingManaCost(p, rippledCards[i]);
|
||||
// revealed.remove(rippledCards[i]);
|
||||
// }
|
||||
// } else {
|
||||
// final AiController aic = ((PlayerControllerAi)p.getController()).getAi();
|
||||
// SpellAbility saPlayed = aic.chooseAndPlaySa(rippledCards[i].getBasicSpells(), false, true);
|
||||
// if ( saPlayed != null )
|
||||
// revealed.remove(rippledCards[i]);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// CardLists.shuffle(revealed);
|
||||
// for (final Card bottom : revealed) {
|
||||
// controller.getGame().getAction().moveToBottomOfLibrary(bottom);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * TODO: Write javadoc for this type.
|
||||
// *
|
||||
// */
|
||||
// public static final class RippleExecutor implements Command {
|
||||
// private final Player controller;
|
||||
// private final Card c;
|
||||
// private static final long serialVersionUID = -845154812215847505L;
|
||||
//
|
||||
// /**
|
||||
// * TODO: Write javadoc for Constructor.
|
||||
// * @param controller
|
||||
// * @param c
|
||||
// */
|
||||
// public RippleExecutor(Player controller, Card c) {
|
||||
// this.controller = controller;
|
||||
// this.c = c;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void run() {
|
||||
//
|
||||
// final List<Card> thrummingStones = controller.getCardsIn(ZoneType.Battlefield, "Thrumming Stone");
|
||||
// for (int i = 0; i < thrummingStones.size(); i++) {
|
||||
// c.addExtrinsicKeyword("Ripple:4");
|
||||
// }
|
||||
//
|
||||
// for (String parse : c.getKeyword()) {
|
||||
// if (parse.startsWith("Ripple")) {
|
||||
// final String[] k = parse.split(":");
|
||||
// this.doRipple(c, Integer.valueOf(k[1]), controller);
|
||||
// }
|
||||
// }
|
||||
// } // execute()
|
||||
//
|
||||
// void doRipple(final Card c, final int rippleCount, final Player controller) {
|
||||
// final Card rippleCard = c;
|
||||
//
|
||||
// final Ability ability = new RippleAbility(c, ManaCost.ZERO, controller, rippleCount, rippleCard);
|
||||
//
|
||||
// if (controller.getController().confirmAction(ability, PlayerActionConfirmMode.Ripple, "Activate Ripple for " + c + "?")) {
|
||||
//
|
||||
// final StringBuilder sb = new StringBuilder();
|
||||
// sb.append(c).append(" - Ripple.");
|
||||
// ability.setStackDescription(sb.toString());
|
||||
// ability.setDescription(sb.toString());
|
||||
// ability.setActivatingPlayer(controller);
|
||||
//
|
||||
// controller.getGame().getStack().addSimultaneousStackEntry(ability);
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
private GameActionUtil() {
|
||||
throw new AssertionError();
|
||||
|
||||
@@ -650,7 +650,7 @@ public class AiController {
|
||||
if ( null == api ) {
|
||||
if( mode != null ) switch (mode) {
|
||||
case BraidOfFire: return true;
|
||||
case Ripple: return true;
|
||||
// case Ripple: return true;
|
||||
}
|
||||
|
||||
String exMsg = String.format("AI confirmAction does not know what to decide about %s mode (api is null).", mode);
|
||||
|
||||
@@ -7,7 +7,7 @@ package forge.game.player;
|
||||
public enum PlayerActionConfirmMode {
|
||||
Random,
|
||||
BraidOfFire,
|
||||
FromOpeningHand,
|
||||
Ripple;
|
||||
FromOpeningHand;
|
||||
// Ripple;
|
||||
|
||||
}
|
||||
@@ -33,7 +33,6 @@ import com.google.common.collect.Iterables;
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.CardPredicates;
|
||||
import forge.Command;
|
||||
import forge.FThreads;
|
||||
import forge.ITargetable;
|
||||
import forge.Singletons;
|
||||
@@ -56,7 +55,6 @@ import forge.card.spellability.TargetChoices;
|
||||
import forge.card.trigger.Trigger;
|
||||
import forge.card.trigger.TriggerType;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameActionUtil.RippleExecutor;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.event.GameEventSpellAbilityCast;
|
||||
@@ -483,8 +481,8 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
||||
if (sp.isSpell() && !sp.isCopied()) {
|
||||
this.thisTurnCast.add(sp.getSourceCard());
|
||||
|
||||
final Command ripple = new RippleExecutor(sp.getActivatingPlayer(), sp.getSourceCard());
|
||||
ripple.run();
|
||||
/*final Command ripple = new RippleExecutor(sp.getActivatingPlayer(), sp.getSourceCard());
|
||||
ripple.run();*/
|
||||
}
|
||||
return si;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user