mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 10:48:00 +00:00
Refactor Maestros Ascendancy
This commit is contained in:
@@ -319,7 +319,11 @@ public final class GameActionUtil {
|
||||
newSA.getMapParams().put("ValidAfterStack", o.getAbility().getParam("ValidAfterStack"));
|
||||
}
|
||||
if (o.getAbility().hasParam("RaiseCost")) {
|
||||
newSA.getMapParams().put("RaiseCost", Integer.toString(AbilityUtils.calculateAmount(host, o.getAbility().getParam("RaiseCost"), o.getAbility())));
|
||||
String raise = o.getAbility().getParam("RaiseCost");
|
||||
if (o.getAbility().hasSVar(raise)) {
|
||||
raise = Integer.toString(AbilityUtils.calculateAmount(host, raise, o.getAbility()));
|
||||
}
|
||||
newSA.getMapParams().put("RaiseCost", raise);
|
||||
}
|
||||
|
||||
final SpellAbilityRestriction sar = newSA.getRestrictions();
|
||||
|
||||
@@ -449,13 +449,13 @@ public class PlayEffect extends SpellAbilityEffect {
|
||||
if (sa.hasParam("ReplaceGraveyard")) {
|
||||
if (!sa.hasParam("ReplaceGraveyardValid")
|
||||
|| tgtSA.isValid(sa.getParam("ReplaceGraveyardValid").split(","), controller, source, sa)) {
|
||||
addReplaceGraveyardEffect(tgtCard, sa, tgtSA, sa.getParam("ReplaceGraveyard"), moveParams);
|
||||
addReplaceGraveyardEffect(tgtCard, source, sa, tgtSA, sa.getParam("ReplaceGraveyard"));
|
||||
}
|
||||
}
|
||||
|
||||
// For Illusionary Mask effect
|
||||
if (sa.hasParam("ReplaceIlluMask")) {
|
||||
addIllusionaryMaskReplace(tgtCard, sa, moveParams);
|
||||
addIllusionaryMaskReplace(tgtCard, sa);
|
||||
}
|
||||
|
||||
// Add controlled by player to target SA so when the spell is resolving, the controller would be changed again
|
||||
@@ -500,8 +500,7 @@ public class PlayEffect extends SpellAbilityEffect {
|
||||
}
|
||||
}
|
||||
|
||||
protected void addReplaceGraveyardEffect(Card c, SpellAbility sa, SpellAbility tgtSA, String zone, Map<AbilityKey, Object> moveParams) {
|
||||
final Card hostCard = sa.getHostCard();
|
||||
public static void addReplaceGraveyardEffect(Card c, Card hostCard, SpellAbility sa, SpellAbility tgtSA, String zone) {
|
||||
final Game game = hostCard.getGame();
|
||||
final Player controller = sa.getActivatingPlayer();
|
||||
final String name = hostCard.getName() + "'s Effect";
|
||||
@@ -535,7 +534,7 @@ public class PlayEffect extends SpellAbilityEffect {
|
||||
game.getAction().moveToCommand(eff, sa);
|
||||
}
|
||||
|
||||
protected void addIllusionaryMaskReplace(Card c, SpellAbility sa, Map<AbilityKey, Object> moveParams) {
|
||||
protected void addIllusionaryMaskReplace(Card c, SpellAbility sa) {
|
||||
final Card hostCard = sa.getHostCard();
|
||||
final Game game = hostCard.getGame();
|
||||
final Player controller = sa.getActivatingPlayer();
|
||||
|
||||
@@ -3777,8 +3777,8 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
public final void setMayPlay(final Player player, final boolean withoutManaCost, final Cost altManaCost, final boolean altIsAdditional, final boolean withFlash, final boolean grantZonePermissions, final StaticAbility sta) {
|
||||
this.mayPlay.put(sta, new CardPlayOption(player, sta, withoutManaCost, altManaCost, altIsAdditional, withFlash, grantZonePermissions));
|
||||
public final void setMayPlay(final Player player, final boolean withoutManaCost, final Cost altManaCost, final boolean withFlash, final boolean grantZonePermissions, final StaticAbility sta) {
|
||||
this.mayPlay.put(sta, new CardPlayOption(player, sta, withoutManaCost, altManaCost, withFlash, grantZonePermissions));
|
||||
this.updateMayPlay();
|
||||
}
|
||||
public final void removeMayPlay(final StaticAbility sta) {
|
||||
|
||||
@@ -3954,7 +3954,7 @@ public class CardFactoryUtil {
|
||||
String effect = "Mode$ AttackVigilance | ValidCard$ Card.Self | Secondary$ True | Description$ Vigilance (" + inst.getReminderText() + ")";
|
||||
inst.addStaticAbility(StaticAbility.create(effect, state.getCard(), state, intrinsic));
|
||||
} else if (keyword.equals("MayFlashSac")) {
|
||||
String effect = "Mode$ Continuous | EffectZone$ All | Affected$ Card.Self | Secondary$ True | MayPlay$ True"
|
||||
String effect = "Mode$ Continuous | EffectZone$ All | Affected$ Card.Self | Secondary$ True | MayPlay$ True | MayPlayDontGrantZonePermissions$ True"
|
||||
+ " | MayPlayNotSorcerySpeed$ True | MayPlayWithFlash$ True | MayPlayText$ Sacrifice at the next cleanup step"
|
||||
+ " | AffectedZone$ Exile,Graveyard,Hand,Library,Stack | Description$ " + inst.getReminderText();
|
||||
inst.addStaticAbility(StaticAbility.create(effect, state.getCard(), state, intrinsic));
|
||||
|
||||
@@ -23,12 +23,11 @@ public final class CardPlayOption {
|
||||
private final boolean withFlash;
|
||||
private final boolean grantsZonePermissions;
|
||||
private final Cost altManaCost;
|
||||
private final boolean altIsAdditional;
|
||||
|
||||
public CardPlayOption(final Player player, final StaticAbility sta, final boolean withoutManaCost, final Cost altManaCost, final boolean altIsAdditional, final boolean withFlash, final boolean grantZonePermissions) {
|
||||
this(player, sta, withoutManaCost ? PayManaCost.NO : PayManaCost.YES, altManaCost, altIsAdditional, withFlash, grantZonePermissions);
|
||||
public CardPlayOption(final Player player, final StaticAbility sta, final boolean withoutManaCost, final Cost altManaCost, final boolean withFlash, final boolean grantZonePermissions) {
|
||||
this(player, sta, withoutManaCost ? PayManaCost.NO : PayManaCost.YES, altManaCost, withFlash, grantZonePermissions);
|
||||
}
|
||||
private CardPlayOption(final Player player, final StaticAbility sta, final PayManaCost payManaCost, final Cost altManaCost, final boolean altIsAdditional, final boolean withFlash,
|
||||
private CardPlayOption(final Player player, final StaticAbility sta, final PayManaCost payManaCost, final Cost altManaCost, final boolean withFlash,
|
||||
final boolean grantZonePermissions) {
|
||||
this.player = player;
|
||||
this.sta = sta;
|
||||
@@ -36,7 +35,6 @@ public final class CardPlayOption {
|
||||
this.withFlash = withFlash;
|
||||
this.grantsZonePermissions = grantZonePermissions;
|
||||
this.altManaCost = altManaCost;
|
||||
this.altIsAdditional = altIsAdditional;
|
||||
}
|
||||
|
||||
|
||||
@@ -102,14 +100,9 @@ public final class CardPlayOption {
|
||||
switch (getPayManaCost()) {
|
||||
case YES:
|
||||
if (altManaCost != null) {
|
||||
if (altIsAdditional) {
|
||||
String desc = sta.getParam("Description");
|
||||
sb.append(" (").append(desc, desc.indexOf("by "), desc.indexOf("."));
|
||||
} else {
|
||||
String insteadCost = getFormattedAltManaCost();
|
||||
insteadCost = insteadCost.replace("Pay ","");
|
||||
sb.append(" (by paying ").append(insteadCost).append(" instead of paying its mana cost");
|
||||
}
|
||||
String insteadCost = getFormattedAltManaCost();
|
||||
insteadCost = insteadCost.replace("Pay ","");
|
||||
sb.append(" (by paying ").append(insteadCost).append(" instead of paying its mana cost");
|
||||
if (isWithFlash()) {
|
||||
sb.append(" and as though it has flash");
|
||||
}
|
||||
@@ -120,6 +113,10 @@ public final class CardPlayOption {
|
||||
} else if (isIgnoreManaCostColor()) {
|
||||
sb.append(" (may spend mana as though it were mana of any color to cast it)");
|
||||
}
|
||||
if (sta.hasParam("RaiseCost")) {
|
||||
String desc = sta.getParam("Description");
|
||||
sb.append(" (").append(desc, desc.indexOf("by ") + desc.indexOf("pay "), desc.indexOf(".")).append(")");
|
||||
}
|
||||
break;
|
||||
case NO:
|
||||
sb.append(" (without paying its mana cost");
|
||||
|
||||
@@ -84,15 +84,16 @@ public class CostAdjustment {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sa.hasParam("RaiseCost")) {
|
||||
String raise = sa.getParam("RaiseCost");
|
||||
ManaCost mc;
|
||||
Cost inc;
|
||||
if (sa.hasSVar(raise)) {
|
||||
mc = ManaCost.get(AbilityUtils.calculateAmount(host, raise, sa));
|
||||
inc = new Cost(ManaCost.get(AbilityUtils.calculateAmount(host, raise, sa)), false);
|
||||
} else {
|
||||
mc = new ManaCost(new ManaCostParser(raise));
|
||||
inc = new Cost(raise, false);
|
||||
}
|
||||
result.add(new Cost(mc, false));
|
||||
result.add(inc);
|
||||
}
|
||||
|
||||
// Raise cost
|
||||
|
||||
@@ -938,15 +938,11 @@ public final class StaticAbilityContinuous {
|
||||
|
||||
if (controllerMayPlay && (mayPlayLimit == null || stAb.getMayPlayTurn() < mayPlayLimit)) {
|
||||
String mayPlayAltCost = mayPlayAltManaCost;
|
||||
boolean additional = mayPlayAltCost != null && mayPlayAltCost.contains("RegularCost");
|
||||
|
||||
if (mayPlayAltCost != null) {
|
||||
if (mayPlayAltCost.contains("ConvertedManaCost")) {
|
||||
final String costcmc = Integer.toString(affectedCard.getCMC());
|
||||
mayPlayAltCost = mayPlayAltCost.replace("ConvertedManaCost", costcmc);
|
||||
} else if (additional) {
|
||||
final String regCost = affectedCard.getManaCost().getShortString();
|
||||
mayPlayAltCost = mayPlayAltManaCost.replace("RegularCost", regCost);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -954,7 +950,7 @@ public final class StaticAbilityContinuous {
|
||||
AbilityUtils.getDefinedPlayers(affectedCard, params.get("MayPlayPlayer"), stAb).get(0) :
|
||||
controller;
|
||||
affectedCard.setMayPlay(mayPlayController, mayPlayWithoutManaCost,
|
||||
mayPlayAltCost != null ? new Cost(mayPlayAltCost, false, affectedCard.equals(hostCard)) : null, additional, mayPlayWithFlash,
|
||||
mayPlayAltCost != null ? new Cost(mayPlayAltCost, false, affectedCard.equals(hostCard)) : null, mayPlayWithFlash,
|
||||
mayPlayGrantZonePermissions, stAb);
|
||||
|
||||
// If the MayPlay effect only affected itself, check if it is in graveyard and give other player who cast Shaman's Trance MayPlay
|
||||
@@ -962,7 +958,7 @@ public final class StaticAbilityContinuous {
|
||||
for (final Player p : game.getPlayers()) {
|
||||
if (p.hasKeyword("Shaman's Trance") && mayPlayController != p) {
|
||||
affectedCard.setMayPlay(p, mayPlayWithoutManaCost,
|
||||
mayPlayAltCost != null ? new Cost(mayPlayAltCost, false) : null, additional,
|
||||
mayPlayAltCost != null ? new Cost(mayPlayAltCost, false) : null,
|
||||
mayPlayWithFlash, mayPlayGrantZonePermissions, stAb);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ import forge.game.*;
|
||||
import forge.game.ability.AbilityKey;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.ApiType;
|
||||
import forge.game.ability.effects.PlayEffect;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCopyService;
|
||||
import forge.game.event.EventValueChangeType;
|
||||
@@ -85,7 +86,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
||||
|
||||
private final List<Card> thisTurnCast = Lists.newArrayList();
|
||||
private List<Card> lastTurnCast = Lists.newArrayList();
|
||||
private final List<SpellAbility> abilitiesActivatedThisTurn = Lists.newArrayList();
|
||||
private final List<SpellAbility> thisTurnActivated = Lists.newArrayList();
|
||||
|
||||
private Card curResolvingCard = null;
|
||||
private final Map<String, List<GameCommand>> commandList = Maps.newHashMap();
|
||||
@@ -493,6 +494,9 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
||||
|
||||
if (sp.isSpell() && sp.getMayPlay() != null) {
|
||||
sp.getMayPlay().incMayPlayTurn();
|
||||
if (sp.getMayPlay().hasParam("ReplaceGraveyard")) {
|
||||
PlayEffect.addReplaceGraveyardEffect(sp.getHostCard(), sp.getMayPlay().getHostCard(), sp, sp, sp.getMayPlay().getParam("ReplaceGraveyard"));
|
||||
}
|
||||
}
|
||||
si = si == null ? new SpellAbilityStackInstance(sp, id) : si;
|
||||
|
||||
@@ -503,7 +507,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
||||
Set<Integer> sources = new TreeSet<>();
|
||||
for (SpellAbilityStackInstance s : stack) {
|
||||
if (s.isSpell()) {
|
||||
distinctSources += 1;
|
||||
distinctSources++;
|
||||
} else {
|
||||
sources.add(s.getSourceCard().getId());
|
||||
}
|
||||
@@ -895,11 +899,14 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
||||
public final List<Card> getSpellsCastThisTurn() {
|
||||
return thisTurnCast;
|
||||
}
|
||||
public final List<Card> getSpellsCastLastTurn() {
|
||||
return lastTurnCast;
|
||||
}
|
||||
|
||||
public final void onNextTurn() {
|
||||
final Player active = game.getPhaseHandler().getPlayerTurn();
|
||||
game.getStackZone().resetCardsAddedThisTurn();
|
||||
this.abilitiesActivatedThisTurn.clear();
|
||||
this.thisTurnActivated.clear();
|
||||
if (thisTurnCast.isEmpty()) {
|
||||
lastTurnCast = Lists.newArrayList();
|
||||
active.resetSpellCastSinceBegOfYourLastTurn();
|
||||
@@ -914,17 +921,13 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
||||
game.updateStackForView();
|
||||
}
|
||||
|
||||
public final List<Card> getSpellsCastLastTurn() {
|
||||
return lastTurnCast;
|
||||
}
|
||||
|
||||
public void addAbilityActivatedThisTurn(SpellAbility sa, final Card source) {
|
||||
source.addAbilityActivated(sa);
|
||||
abilitiesActivatedThisTurn.add(sa.copy(CardCopyService.getLKICopy(source), true));
|
||||
thisTurnActivated.add(sa.copy(CardCopyService.getLKICopy(source), true));
|
||||
}
|
||||
|
||||
public List<SpellAbility> getAbilityActivatedThisTurn() {
|
||||
return abilitiesActivatedThisTurn;
|
||||
return thisTurnActivated;
|
||||
}
|
||||
|
||||
public final void addCastCommand(final String valid, final GameCommand c) {
|
||||
|
||||
@@ -6,7 +6,7 @@ K:Flying
|
||||
K:Trample
|
||||
K:etbCounter:SHIELD:1
|
||||
S:Mode$ Continuous | Affected$ Card.TopLibrary+YouOwn | AffectedZone$ Library | MayLookAt$ You | Description$ You may look at the top card of your library any time.
|
||||
S:Mode$ Continuous | Affected$ Card.TopLibrary+YouOwn+nonLand | AffectedZone$ Library | MayPlay$ True | MayPlayAltManaCost$ RegularCost RemoveAnyCounter<1/Any/Creature.YouCtrl/a creature you control> | Description$ You may cast spells from the top of your library by removing a counter from a creature you control in addition to paying their other costs.
|
||||
S:Mode$ Continuous | Affected$ Card.TopLibrary+YouOwn+nonLand | AffectedZone$ Library | MayPlay$ True | RaiseCost$ RemoveAnyCounter<1/Any/Creature.YouCtrl/a creature you control> | Description$ You may cast spells from the top of your library by removing a counter from a creature you control in addition to paying their other costs.
|
||||
DeckHas:Ability$Counters
|
||||
DeckHints:Ability$Counters|Proliferate
|
||||
Oracle:Flying, trample\nFalco Spara, Pactweaver enters the battlefield with a shield counter on it.\nYou may look at the top card of your library any time.\nYou may cast spells from the top of your library by removing a counter from a creature you control in addition to paying their other costs.
|
||||
|
||||
@@ -3,7 +3,5 @@ ManaCost:1 U B R
|
||||
Types:Legendary Creature Human Wizard
|
||||
PT:3/4
|
||||
K:Flying
|
||||
S:Mode$ Continuous | Affected$ Instant.YouCtrl,Sorcery.YouCtrl | Condition$ PlayerTurn | MayPlay$ True | MayPlayLimit$ 1 | EffectZone$ Battlefield | AffectedZone$ Graveyard | Description$ During each of your turns, you may cast an instant or sorcery spell from your graveyard. If a spell cast this way would be put into your graveyard, exile it instead.
|
||||
R:Event$ Moved | ValidLKI$ Card.CastSa Spell.MayPlaySource | Origin$ Stack | Destination$ Graveyard | ReplaceWith$ MoveExile
|
||||
SVar:MoveExile:DB$ ChangeZone | Defined$ ReplacedCard | Origin$ Stack | Destination$ Exile
|
||||
S:Mode$ Continuous | Affected$ Instant.YouCtrl,Sorcery.YouCtrl | Condition$ PlayerTurn | ReplaceGraveyard$ Exile | MayPlay$ True | MayPlayLimit$ 1 | EffectZone$ Battlefield | AffectedZone$ Graveyard | Description$ During each of your turns, you may cast an instant or sorcery spell from your graveyard. If a spell cast this way would be put into your graveyard, exile it instead.
|
||||
Oracle:Flying\nDuring each of your turns, you may cast an instant or sorcery spell from your graveyard. If a spell cast this way would be put into your graveyard, exile it instead.
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
Name:Maestros Ascendancy
|
||||
ManaCost:U B R
|
||||
Types:Enchantment
|
||||
S:Mode$ Continuous | Affected$ Instant.YouCtrl,Sorcery.YouCtrl | Condition$ PlayerTurn | MayPlay$ True | MayPlayAltManaCost$ RegularCost Sac<1/Creature> | MayPlayLimit$ 1 | EffectZone$ Battlefield | AffectedZone$ Graveyard | Description$ Once during each of your turns, you may cast an instant or sorcery spell from your graveyard by sacrificing a creature in addition to paying its other costs. If a spell cast this way would be put into your graveyard, exile it instead.
|
||||
R:Event$ Moved | ValidLKI$ Card.CastSa Spell.MayPlaySource | Origin$ Stack | Destination$ Graveyard | ReplaceWith$ MoveExile
|
||||
SVar:MoveExile:DB$ ChangeZone | Defined$ ReplacedCard | Origin$ Stack | Destination$ Exile
|
||||
S:Mode$ Continuous | Affected$ Instant.YouCtrl,Sorcery.YouCtrl | Condition$ PlayerTurn | ReplaceGraveyard$ Exile | MayPlay$ True | RaiseCost$ Sac<1/Creature> | MayPlayLimit$ 1 | EffectZone$ Battlefield | AffectedZone$ Graveyard | Description$ Once during each of your turns, you may cast an instant or sorcery spell from your graveyard by sacrificing a creature in addition to paying its other costs. If a spell cast this way would be put into your graveyard, exile it instead.
|
||||
Oracle:Once during each of your turns, you may cast an instant or sorcery spell from your graveyard by sacrificing a creature in addition to paying its other costs. If a spell cast this way would be put into your graveyard, exile it instead.
|
||||
|
||||
@@ -4,7 +4,6 @@ Types:Creature Human Cleric
|
||||
PT:1/1
|
||||
K:A deck can have any number of cards named CARDNAME.
|
||||
A:AB$ ChangeZone | Cost$ B Sac<6/Creature.namedShadowborn Apostle/creatures named Shadowborn Apostle> | Origin$ Library | Destination$ Battlefield | ChangeType$ Creature.Demon | ChangeNum$ 1 | SpellDescription$ Search your library for a Demon creature card, put it onto the battlefield, then shuffle.
|
||||
DeckNeeds:Name$Shadowborn Apostle
|
||||
DeckNeeds:Type$Demon
|
||||
DeckNeeds:Name$Shadowborn Apostle & Type$Demon
|
||||
DeckHints:Name$Shadowborn Demon
|
||||
Oracle:A deck can have any number of cards named Shadowborn Apostle.\n{B}, Sacrifice six creatures named Shadowborn Apostle: Search your library for a Demon creature card, put it onto the battlefield, then shuffle.
|
||||
|
||||
Reference in New Issue
Block a user