mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 02:08:00 +00:00
Cycling: add YouCycledThisTurn, OnlyFirst for Trigger and ValidCause for ReplaceDraw
This commit is contained in:
committed by
Michael Kamensky
parent
6b38bc4b7f
commit
ef95f02fa2
@@ -1461,12 +1461,18 @@ public class GameAction {
|
|||||||
revealTo(card, Collections.singleton(to));
|
revealTo(card, Collections.singleton(to));
|
||||||
}
|
}
|
||||||
public void revealTo(final CardCollectionView cards, final Player to) {
|
public void revealTo(final CardCollectionView cards, final Player to) {
|
||||||
revealTo(cards, Collections.singleton(to));
|
revealTo(cards, to, null);
|
||||||
|
}
|
||||||
|
public void revealTo(final CardCollectionView cards, final Player to, String messagePrefix) {
|
||||||
|
revealTo(cards, Collections.singleton(to), messagePrefix);
|
||||||
}
|
}
|
||||||
public void revealTo(final Card card, final Iterable<Player> to) {
|
public void revealTo(final Card card, final Iterable<Player> to) {
|
||||||
revealTo(new CardCollection(card), to);
|
revealTo(new CardCollection(card), to);
|
||||||
}
|
}
|
||||||
public void revealTo(final CardCollectionView cards, final Iterable<Player> to) {
|
public void revealTo(final CardCollectionView cards, final Iterable<Player> to) {
|
||||||
|
revealTo(cards, to, null);
|
||||||
|
}
|
||||||
|
public void revealTo(final CardCollectionView cards, final Iterable<Player> to, String messagePrefix) {
|
||||||
if (cards.isEmpty()) {
|
if (cards.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1474,7 +1480,7 @@ public class GameAction {
|
|||||||
final ZoneType zone = cards.getFirst().getZone().getZoneType();
|
final ZoneType zone = cards.getFirst().getZone().getZoneType();
|
||||||
final Player owner = cards.getFirst().getOwner();
|
final Player owner = cards.getFirst().getOwner();
|
||||||
for (final Player p : to) {
|
for (final Player p : to) {
|
||||||
p.getController().reveal(cards, zone, owner);
|
p.getController().reveal(cards, zone, owner, messagePrefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public class DrawEffect extends SpellAbilityEffect {
|
|||||||
actualNum = p.getController().chooseNumber(sa, "lblHowMayCardDoYouWantDraw", 0, numCards);
|
actualNum = p.getController().chooseNumber(sa, "lblHowMayCardDoYouWantDraw", 0, numCards);
|
||||||
}
|
}
|
||||||
|
|
||||||
final CardCollectionView drawn = p.drawCards(actualNum);
|
final CardCollectionView drawn = p.drawCards(actualNum, sa);
|
||||||
if (sa.hasParam("Reveal")) {
|
if (sa.hasParam("Reveal")) {
|
||||||
p.getGame().getAction().reveal(drawn, p);
|
p.getGame().getAction().reveal(drawn, p);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -909,6 +909,9 @@ public class CardFactoryUtil {
|
|||||||
return doXMath(c.getXManaCostPaidCount(colors.toString()), m, c);
|
return doXMath(c.getXManaCostPaidCount(colors.toString()), m, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sq[0].equals("YouCycledThisTurn")) {
|
||||||
|
return doXMath(cc.getCycledThisTurn(), m, c);
|
||||||
|
}
|
||||||
|
|
||||||
if (sq[0].equals("YouDrewThisTurn")) {
|
if (sq[0].equals("YouDrewThisTurn")) {
|
||||||
return doXMath(cc.getNumDrawnThisTurn(), m, c);
|
return doXMath(cc.getNumDrawnThisTurn(), m, c);
|
||||||
|
|||||||
@@ -877,6 +877,16 @@ public class CardProperty {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
default:
|
||||||
|
final CardCollection cards1 = AbilityUtils.getDefinedCards(card, restriction, spellAbility);
|
||||||
|
if (cards1.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (Card c : cards1) {
|
||||||
|
if (!card.sharesCardTypeWith(c)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (property.equals("sharesPermanentTypeWith")) {
|
} else if (property.equals("sharesPermanentTypeWith")) {
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ public class CostDraw extends CostPart {
|
|||||||
@Override
|
@Override
|
||||||
public final boolean payAsDecided(final Player ai, final PaymentDecision decision, SpellAbility ability) {
|
public final boolean payAsDecided(final Player ai, final PaymentDecision decision, SpellAbility ability) {
|
||||||
for (final Player p : getPotentialPlayers(ai, ability.getHostCard())) {
|
for (final Player p : getPotentialPlayers(ai, ability.getHostCard())) {
|
||||||
p.drawCards(decision.c);
|
p.drawCards(decision.c, ability);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
private int landsPlayedLastTurn = 0;
|
private int landsPlayedLastTurn = 0;
|
||||||
private int investigatedThisTurn = 0;
|
private int investigatedThisTurn = 0;
|
||||||
private int surveilThisTurn = 0;
|
private int surveilThisTurn = 0;
|
||||||
|
private int cycledThisTurn = 0;
|
||||||
private int lifeLostThisTurn = 0;
|
private int lifeLostThisTurn = 0;
|
||||||
private int lifeLostLastTurn = 0;
|
private int lifeLostLastTurn = 0;
|
||||||
private int lifeGainedThisTurn = 0;
|
private int lifeGainedThisTurn = 0;
|
||||||
@@ -1269,7 +1270,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final CardCollectionView drawCard() {
|
public final CardCollectionView drawCard() {
|
||||||
return drawCards(1);
|
return drawCards(1, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void surveil(int num, SpellAbility cause) {
|
public void surveil(int num, SpellAbility cause) {
|
||||||
@@ -1339,8 +1340,11 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final CardCollectionView drawCards(final int n) {
|
public final CardCollectionView drawCards(final int n) {
|
||||||
|
return drawCards(n, null);
|
||||||
|
}
|
||||||
|
public final CardCollectionView drawCards(final int n, SpellAbility cause) {
|
||||||
final CardCollection drawn = new CardCollection();
|
final CardCollection drawn = new CardCollection();
|
||||||
final CardCollection toReveal = new CardCollection();
|
final Map<Player, CardCollection> toReveal = Maps.newHashMap();
|
||||||
|
|
||||||
// Replacement effects
|
// Replacement effects
|
||||||
final Map<AbilityKey, Object> repRunParams = AbilityKey.mapFromAffected(this);
|
final Map<AbilityKey, Object> repRunParams = AbilityKey.mapFromAffected(this);
|
||||||
@@ -1357,11 +1361,14 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
if (gameStarted && !canDraw()) {
|
if (gameStarted && !canDraw()) {
|
||||||
return drawn;
|
return drawn;
|
||||||
}
|
}
|
||||||
drawn.addAll(doDraw(toReveal));
|
drawn.addAll(doDraw(toReveal, cause));
|
||||||
}
|
}
|
||||||
if (toReveal.size() > 1) {
|
|
||||||
// reveal multiple drawn cards when playing with the top of the library revealed
|
// reveal multiple drawn cards when playing with the top of the library revealed
|
||||||
game.getAction().reveal(toReveal, this, true, "Revealing cards drawn from ");
|
for (Map.Entry<Player, CardCollection> e : toReveal.entrySet()) {
|
||||||
|
if (e.getValue().size() > 1) {
|
||||||
|
game.getAction().revealTo(e.getValue(), e.getKey(), "Revealing cards drawn from ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return drawn;
|
return drawn;
|
||||||
}
|
}
|
||||||
@@ -1369,31 +1376,36 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
/**
|
/**
|
||||||
* @return a CardCollectionView of cards actually drawn
|
* @return a CardCollectionView of cards actually drawn
|
||||||
*/
|
*/
|
||||||
private CardCollectionView doDraw(CardCollection revealed) {
|
private CardCollectionView doDraw(Map<Player, CardCollection> revealed, SpellAbility cause) {
|
||||||
final CardCollection drawn = new CardCollection();
|
final CardCollection drawn = new CardCollection();
|
||||||
final PlayerZone library = getZone(ZoneType.Library);
|
final PlayerZone library = getZone(ZoneType.Library);
|
||||||
|
|
||||||
// Replacement effects
|
// Replacement effects
|
||||||
if (game.getReplacementHandler().run(ReplacementType.Draw, AbilityKey.mapFromAffected(this)) != ReplacementResult.NotReplaced) {
|
Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(this);
|
||||||
|
repParams.put(AbilityKey.Cause, cause);
|
||||||
|
if (game.getReplacementHandler().run(ReplacementType.Draw, repParams) != ReplacementResult.NotReplaced) {
|
||||||
return drawn;
|
return drawn;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!library.isEmpty()) {
|
if (!library.isEmpty()) {
|
||||||
Card c = library.get(0);
|
Card c = library.get(0);
|
||||||
boolean topCardRevealed = false;
|
|
||||||
|
|
||||||
for (Player p : this.getAllOtherPlayers()) {
|
List<Player> pList = Lists.newArrayList();
|
||||||
|
|
||||||
|
for (Player p : getAllOtherPlayers()) {
|
||||||
if (c.mayPlayerLook(p)) {
|
if (c.mayPlayerLook(p)) {
|
||||||
topCardRevealed = true;
|
pList.add(p);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c = game.getAction().moveToHand(c, null);
|
c = game.getAction().moveToHand(c, cause);
|
||||||
drawn.add(c);
|
drawn.add(c);
|
||||||
|
|
||||||
if (topCardRevealed) {
|
for(Player p : pList) {
|
||||||
revealed.add(c);
|
if (!revealed.containsKey(p)) {
|
||||||
|
revealed.put(p, new CardCollection());
|
||||||
|
}
|
||||||
|
revealed.get(p).add(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
setLastDrawnCard(c);
|
setLastDrawnCard(c);
|
||||||
@@ -2454,6 +2466,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
resetLandsPlayedThisTurn();
|
resetLandsPlayedThisTurn();
|
||||||
resetInvestigatedThisTurn();
|
resetInvestigatedThisTurn();
|
||||||
resetSurveilThisTurn();
|
resetSurveilThisTurn();
|
||||||
|
resetCycledThisTurn();
|
||||||
resetSacrificedThisTurn();
|
resetSacrificedThisTurn();
|
||||||
resetCounterToPermThisTurn();
|
resetCounterToPermThisTurn();
|
||||||
clearAssignedDamage();
|
clearAssignedDamage();
|
||||||
@@ -3157,4 +3170,22 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
}
|
}
|
||||||
return controlVotes.last();
|
return controlVotes.last();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addCycled(SpellAbility sp) {
|
||||||
|
cycledThisTurn++;
|
||||||
|
|
||||||
|
Map<AbilityKey, Object> cycleParams = AbilityKey.mapFromCard(sp.getHostCard());
|
||||||
|
cycleParams.put(AbilityKey.Cause, sp);
|
||||||
|
cycleParams.put(AbilityKey.Player, this);
|
||||||
|
cycleParams.put(AbilityKey.NumThisTurn, cycledThisTurn);
|
||||||
|
game.getTriggerHandler().runTrigger(TriggerType.Cycled, cycleParams, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCycledThisTurn() {
|
||||||
|
return cycledThisTurn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetCycledThisTurn() {
|
||||||
|
cycledThisTurn = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,17 +6,18 @@
|
|||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package forge.game.replacement;
|
package forge.game.replacement;
|
||||||
|
|
||||||
|
import forge.game.Game;
|
||||||
import forge.game.ability.AbilityKey;
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
@@ -25,7 +26,7 @@ import forge.game.spellability.SpellAbility;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Write javadoc for this type.
|
* TODO: Write javadoc for this type.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -46,16 +47,29 @@ public class ReplaceDraw extends ReplacementEffect {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(Map<AbilityKey, Object> runParams) {
|
public boolean canReplace(Map<AbilityKey, Object> runParams) {
|
||||||
|
final Game game = this.getHostCard().getGame();
|
||||||
if (hasParam("ValidPlayer")) {
|
if (hasParam("ValidPlayer")) {
|
||||||
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), this.getHostCard())) {
|
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasParam("ValidCause")) {
|
||||||
|
if (!runParams.containsKey(AbilityKey.Cause)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SpellAbility cause = (SpellAbility) runParams.get(AbilityKey.Cause);
|
||||||
|
if (cause == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!matchesValid(cause, getParam("ValidCause").split(","), getHostCard())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (hasParam("NotFirstCardInDrawStep")) {
|
if (hasParam("NotFirstCardInDrawStep")) {
|
||||||
final Player p = (Player)runParams.get(AbilityKey.Affected);
|
final Player p = (Player)runParams.get(AbilityKey.Affected);
|
||||||
if (p.numDrawnThisDrawStep() == 0
|
if (p.numDrawnThisDrawStep() == 0 && game.getPhaseHandler().is(PhaseType.DRAW, p)) {
|
||||||
&& this.getHostCard().getGame().getPhaseHandler().is(PhaseType.DRAW)
|
|
||||||
&& this.getHostCard().getGame().getPhaseHandler().isPlayerTurn(p)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,5 +85,12 @@ public class ReplaceDraw extends ReplacementEffect {
|
|||||||
@Override
|
@Override
|
||||||
public void setReplacingObjects(Map<AbilityKey, Object> runParams, SpellAbility sa) {
|
public void setReplacingObjects(Map<AbilityKey, Object> runParams, SpellAbility sa) {
|
||||||
sa.setReplacingObject(AbilityKey.Player, runParams.get(AbilityKey.Affected));
|
sa.setReplacingObject(AbilityKey.Player, runParams.get(AbilityKey.Affected));
|
||||||
|
if (runParams.containsKey(AbilityKey.Cause)) {
|
||||||
|
SpellAbility cause = (SpellAbility) runParams.get(AbilityKey.Cause);
|
||||||
|
if (cause != null) {
|
||||||
|
sa.setReplacingObject(AbilityKey.Cause, cause);
|
||||||
|
sa.setReplacingObject(AbilityKey.Source, cause.getHostCard());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package forge.game.trigger;
|
|||||||
|
|
||||||
import forge.game.ability.AbilityKey;
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.util.Localizer;
|
import forge.util.Localizer;
|
||||||
|
|
||||||
@@ -68,8 +69,22 @@ public class TriggerCycled extends Trigger {
|
|||||||
@Override
|
@Override
|
||||||
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
||||||
if (hasParam("ValidCard")) {
|
if (hasParam("ValidCard")) {
|
||||||
return matchesValid(runParams.get(AbilityKey.Card), getParam("ValidCard").split(","),
|
if (!matchesValid(runParams.get(AbilityKey.Card), getParam("ValidCard").split(","), getHostCard())) {
|
||||||
this.getHostCard());
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasParam("ValidPlayer")) {
|
||||||
|
Player p = (Player) runParams.get(AbilityKey.Player);
|
||||||
|
if (!matchesValid(p, getParam("ValidPlayer").split(","), getHostCard())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasParam("OnlyFirst")) {
|
||||||
|
if ((int) runParams.get(AbilityKey.NumThisTurn) != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,9 +314,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
|||||||
|
|
||||||
// Run Cycled triggers
|
// Run Cycled triggers
|
||||||
if (sp.isCycling()) {
|
if (sp.isCycling()) {
|
||||||
Map<AbilityKey, Object> cycleParams = AbilityKey.mapFromCard(sp.getHostCard());
|
activator.addCycled(sp);
|
||||||
cycleParams.put(AbilityKey.Cause, sp);
|
|
||||||
game.getTriggerHandler().runTrigger(TriggerType.Cycled, cycleParams, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sp.hasParam("Crew")) {
|
if (sp.hasParam("Crew")) {
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
Name:Spellpyre Phoenix
|
||||||
|
ManaCost:3 R R
|
||||||
|
Types:Creature Phoenix
|
||||||
|
PT:4/2
|
||||||
|
K:Flying
|
||||||
|
T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigChangeZone | TriggerDescription$ When CARDNAME enters the battlefield, you may return target instant or sorcery card with a cycling ability from your graveyard to your hand.
|
||||||
|
SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | ValidTgts$ Instant.YouOwn+withCycling,Instant.YouOwn+withTypeCycling,Sorcery.YouOwn+withCycling,Sorcery.YouOwn+withTypeCycling | TgtPrompt$ Select target instant or sorcery card with a cycling ability from your graveyard
|
||||||
|
T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Graveyard | CheckSVar$ YouCycled | SVarCompare$ GE2 | Execute$ TrigReturn | TriggerDescription$ At the beginning of each end step, if you cycled two or more cards this turn, return CARDNAME from your graveyard to your hand.
|
||||||
|
SVar:TrigReturn:DB$ ChangeZone | Defined$ Self | Origin$ Graveyard | Destination$ Hand
|
||||||
|
SVar:YouCycled:Count$YouCycledThisTurn
|
||||||
|
Oracle:Flying\nWhen Spellpyre Phoenix enters the battlefield, you may return target instant or sorcery card with a cycling ability from your graveyard to your hand.\nAt the beginning of each end step, if you cycled two or more cards this turn, return Spellpyre Phoenix from your graveyard to your hand.
|
||||||
10
forge-gui/res/cardsfolder/upcoming/unpredictable_cyclone.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/unpredictable_cyclone.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Name:Unpredictable Cyclone
|
||||||
|
ManaCost:3 R R
|
||||||
|
Types:Enchantment
|
||||||
|
K:Cycling:2
|
||||||
|
R:Event$ Draw | ValidCause$ Activated.Cycling+nonLand | ValidPlayer$ You | ActiveZones$ Battlefield | ReplaceWith$ DBDig | Description$ If a cycling ability of another nonland card would cause you to draw a card, instead exile cards from the top of your library until you exile a card that shares a card type with the cycled card. You may cast that card without paying its mana cost. Then put the exiled cards that weren't cast this way on the bottom of your library in a random order.
|
||||||
|
SVar:DBDig:DB$ DigUntil | Defined$ You | Valid$ Card.sharesCardTypeWith ReplacedSource | ValidDescription$ shares a card type with exiled card | FoundDestination$ Exile | RevealedDestination$ Exile | RememberFound$ True | RememberRevealed$ True | SubAbility$ DBPlay
|
||||||
|
SVar:DBPlay:DB$ Play | Defined$ Remembered.nonLand+sharesCardTypeWith ReplacedSource | WithoutManaCost$ True | Optional$ True | ForgetTargetRemembered$ True | SubAbility$ DBRestRandomOrder
|
||||||
|
SVar:DBRestRandomOrder:DB$ ChangeZone | Defined$ Remembered | AtRandom$ True | Origin$ Library | Destination$ Library | LibraryPosition$ -1 | SubAbility$ DBCleanup
|
||||||
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
|
Oracle:If a cycling ability of another nonland card would cause you to draw a card, instead exile cards from the top of your library until you exile a card that shares a card type with the cycled card. You may cast that card without paying its mana cost. Then put the exiled cards that weren't cast this way on the bottom of your library in a random order.\nCycling {2} ({2}, Discard this card: Draw a card.)
|
||||||
8
forge-gui/res/cardsfolder/upcoming/valiant_rescuer.txt
Normal file
8
forge-gui/res/cardsfolder/upcoming/valiant_rescuer.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Name:Valiant Rescuer
|
||||||
|
ManaCost:1 W
|
||||||
|
Types:Creature Human Soldier
|
||||||
|
PT:3/1
|
||||||
|
T:Mode$ Cycled | ValidCard$ Card.Other | ValidPlayer$ You | TriggerZones$ Battlefield | OnlyFirst$ True | Execute$ TrigToken | TriggerDescription$ Whenever you cycle another card for the first time each turn, create a 1/1 white Human Soldier creature token.
|
||||||
|
SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_human_soldier | TokenOwner$ You | LegacyImage$ w 1 1 human soldier iko
|
||||||
|
K:Cycling:2
|
||||||
|
Oracle:Whenever you cycle another card for the first time each turn, create a 1/1 white Human Soldier creature token.\nCycling {2} ({2}, Discard this card: Draw a card.)
|
||||||
@@ -345,7 +345,7 @@ public class HumanPlay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Player player : res) {
|
for (Player player : res) {
|
||||||
player.drawCards(amount);
|
player.drawCards(amount, sourceAbility);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (part instanceof CostGainLife) {
|
else if (part instanceof CostGainLife) {
|
||||||
|
|||||||
Reference in New Issue
Block a user