mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-14 17:58:01 +00:00
Merge branch 'master' into AI_ATTACK_TIMEOUT
This commit is contained in:
@@ -100,7 +100,7 @@ public final class ManaCost implements Comparable<ManaCost>, Iterable<ManaCostSh
|
|||||||
}
|
}
|
||||||
int generic = parser.getTotalGenericCost(); // collect generic mana here
|
int generic = parser.getTotalGenericCost(); // collect generic mana here
|
||||||
this.hasNoCost = generic == -1;
|
this.hasNoCost = generic == -1;
|
||||||
this.genericCost = generic == -1 ? 0 : generic;
|
this.genericCost = hasNoCost ? 0 : generic;
|
||||||
sealClass(shardsTemp);
|
sealClass(shardsTemp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,11 @@ public class CounterEffect extends SpellAbilityEffect {
|
|||||||
final CardZoneTable zoneMovements = AbilityKey.addCardZoneTableParams(params, sa);
|
final CardZoneTable zoneMovements = AbilityKey.addCardZoneTableParams(params, sa);
|
||||||
|
|
||||||
for (final SpellAbility tgtSA : getTargetSpells(sa)) {
|
for (final SpellAbility tgtSA : getTargetSpells(sa)) {
|
||||||
|
if (sa.hasParam("Optional") && !sa.getActivatingPlayer().getController().confirmAction(sa, null,
|
||||||
|
Localizer.getInstance().getMessage("lblWouldYouLikeProceedWithOptionalAbility") + " " + sa.getHostCard() + "?", null)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final Card tgtSACard = tgtSA.getHostCard();
|
final Card tgtSACard = tgtSA.getHostCard();
|
||||||
// should remember even that spell cannot be countered
|
// should remember even that spell cannot be countered
|
||||||
// currently all effects using this are targeted in case the spell gets countered before
|
// currently all effects using this are targeted in case the spell gets countered before
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ public class ManaCostBeingPaid {
|
|||||||
public int getTotalGenericCost() {
|
public int getTotalGenericCost() {
|
||||||
ShardCount c = unpaidShards.get(ManaCostShard.GENERIC);
|
ShardCount c = unpaidShards.get(ManaCostShard.GENERIC);
|
||||||
if (c == null) {
|
if (c == null) {
|
||||||
return unpaidShards.isEmpty() ? -1 : 0;
|
return unpaidShards.isEmpty() && cntX == 0 ? -1 : 0;
|
||||||
}
|
}
|
||||||
return c.totalCount;
|
return c.totalCount;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1213,19 +1213,20 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
return drawn;
|
return drawn;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replacement effects
|
|
||||||
final Map<AbilityKey, Object> repRunParams = AbilityKey.mapFromAffected(this);
|
|
||||||
repRunParams.put(AbilityKey.Number, n);
|
|
||||||
if (params != null) {
|
|
||||||
repRunParams.putAll(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (game.getReplacementHandler().run(ReplacementType.DrawCards, repRunParams) != ReplacementResult.NotReplaced) {
|
|
||||||
return drawn;
|
|
||||||
}
|
|
||||||
|
|
||||||
// always allow drawing cards before the game actually starts (e.g. Maralen of the Mornsong Avatar)
|
// always allow drawing cards before the game actually starts (e.g. Maralen of the Mornsong Avatar)
|
||||||
final boolean gameStarted = game.getAge().ordinal() > GameStage.Mulligan.ordinal();
|
final boolean gameStarted = game.getAge().ordinal() > GameStage.Mulligan.ordinal();
|
||||||
|
|
||||||
|
if (gameStarted) {
|
||||||
|
final Map<AbilityKey, Object> repRunParams = AbilityKey.mapFromAffected(this);
|
||||||
|
repRunParams.put(AbilityKey.Number, n);
|
||||||
|
if (params != null) {
|
||||||
|
repRunParams.putAll(params);
|
||||||
|
}
|
||||||
|
if (game.getReplacementHandler().run(ReplacementType.DrawCards, repRunParams) != ReplacementResult.NotReplaced) {
|
||||||
|
return drawn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final Map<Player, CardCollection> toReveal = Maps.newHashMap();
|
final Map<Player, CardCollection> toReveal = Maps.newHashMap();
|
||||||
|
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
@@ -1256,14 +1257,17 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
cause = (SpellAbility) cause.getReplacingObject(AbilityKey.Cause);
|
cause = (SpellAbility) cause.getReplacingObject(AbilityKey.Cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replacement effects
|
final boolean gameStarted = game.getAge().ordinal() > GameStage.Mulligan.ordinal();
|
||||||
Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(this);
|
|
||||||
repParams.put(AbilityKey.Cause, cause);
|
if (gameStarted) {
|
||||||
if (params != null) {
|
Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(this);
|
||||||
repParams.putAll(params);
|
repParams.put(AbilityKey.Cause, cause);
|
||||||
}
|
if (params != null) {
|
||||||
if (game.getReplacementHandler().run(ReplacementType.Draw, repParams) != ReplacementResult.NotReplaced) {
|
repParams.putAll(params);
|
||||||
return drawn;
|
}
|
||||||
|
if (game.getReplacementHandler().run(ReplacementType.Draw, repParams) != ReplacementResult.NotReplaced) {
|
||||||
|
return drawn;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!library.isEmpty()) {
|
if (!library.isEmpty()) {
|
||||||
@@ -1298,7 +1302,6 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
revealed.get(p).add(c);
|
revealed.get(p).add(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean gameStarted = game.getAge().ordinal() > GameStage.Mulligan.ordinal();
|
|
||||||
if (gameStarted) {
|
if (gameStarted) {
|
||||||
setLastDrawnCard(c);
|
setLastDrawnCard(c);
|
||||||
c.setDrawnThisTurn(true);
|
c.setDrawnThisTurn(true);
|
||||||
|
|||||||
@@ -71,8 +71,6 @@ public class ReplacementHandler {
|
|||||||
game = gameState;
|
game = gameState;
|
||||||
}
|
}
|
||||||
|
|
||||||
//private final List<ReplacementEffect> tmpEffects = new ArrayList<ReplacementEffect>();
|
|
||||||
|
|
||||||
public List<ReplacementEffect> getReplacementList(final ReplacementType event, final Map<AbilityKey, Object> runParams, final ReplacementLayer layer) {
|
public List<ReplacementEffect> getReplacementList(final ReplacementType event, final Map<AbilityKey, Object> runParams, final ReplacementLayer layer) {
|
||||||
final CardCollection preList = new CardCollection();
|
final CardCollection preList = new CardCollection();
|
||||||
boolean checkAgain = false;
|
boolean checkAgain = false;
|
||||||
@@ -108,13 +106,6 @@ public class ReplacementHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final List<ReplacementEffect> possibleReplacers = Lists.newArrayList();
|
final List<ReplacementEffect> possibleReplacers = Lists.newArrayList();
|
||||||
// Round up Non-static replacement effects ("Until EOT," or
|
|
||||||
// "The next time you would..." etc)
|
|
||||||
/*for (final ReplacementEffect replacementEffect : this.tmpEffects) {
|
|
||||||
if (!replacementEffect.hasRun() && replacementEffect.canReplace(runParams) && replacementEffect.getLayer() == layer) {
|
|
||||||
possibleReplacers.add(replacementEffect);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Round up Static replacement effects
|
// Round up Static replacement effects
|
||||||
game.forEachCardInGame(new Visitor<Card>() {
|
game.forEachCardInGame(new Visitor<Card>() {
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ PT:5/5
|
|||||||
K:Flying
|
K:Flying
|
||||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigMonarch | TriggerDescription$ When CARDNAME enters, you become the monarch.
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigMonarch | TriggerDescription$ When CARDNAME enters, you become the monarch.
|
||||||
SVar:TrigMonarch:DB$ BecomeMonarch | Defined$ You
|
SVar:TrigMonarch:DB$ BecomeMonarch | Defined$ You
|
||||||
R:Event$ LifeReduced | ValidPlayer$ You | IsDamage$ True | Monarch$ True | Layer$ CantHappen | Description$ As long as you're the monarch, damage doesn't cause you to lose life. (When a creature deals combat damage to you, its controller still becomes the monarch.)
|
R:Event$ LifeReduced | ValidPlayer$ You | IsDamage$ True | Monarch$ True | Layer$ CantHappen | ActiveZones$ Battlefield | Description$ As long as you're the monarch, damage doesn't cause you to lose life. (When a creature deals combat damage to you, its controller still becomes the monarch.)
|
||||||
Oracle:Flying\nWhen Archon of Coronation enters, you become the monarch.\nAs long as you're the monarch, damage doesn't cause you to lose life. (When a creature deals combat damage to you, its controller still becomes the monarch.)
|
Oracle:Flying\nWhen Archon of Coronation enters, you become the monarch.\nAs long as you're the monarch, damage doesn't cause you to lose life. (When a creature deals combat damage to you, its controller still becomes the monarch.)
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ Types:Instant
|
|||||||
K:Cycling:2 U
|
K:Cycling:2 U
|
||||||
A:SP$ Counter | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | UnlessCost$ 3 | SpellDescription$ Counter target spell unless its controller pays {3}.
|
A:SP$ Counter | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | UnlessCost$ 3 | SpellDescription$ Counter target spell unless its controller pays {3}.
|
||||||
T:Mode$ Cycled | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When you cycle CARDNAME, you may counter target spell unless its controller pays {1}.
|
T:Mode$ Cycled | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When you cycle CARDNAME, you may counter target spell unless its controller pays {1}.
|
||||||
SVar:TrigExile:DB$ Counter | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | UnlessCost$ 1
|
SVar:TrigExile:DB$ Counter | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | Optional$ True | UnlessCost$ 1
|
||||||
Oracle:Counter target spell unless its controller pays {3}.\nCycling {2}{U} ({2}{U}, Discard this card: Draw a card.)\nWhen you cycle Complicate, you may counter target spell unless its controller pays {1}.
|
Oracle:Counter target spell unless its controller pays {3}.\nCycling {2}{U} ({2}{U}, Discard this card: Draw a card.)\nWhen you cycle Complicate, you may counter target spell unless its controller pays {1}.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ Name:Mystic Remora
|
|||||||
ManaCost:U
|
ManaCost:U
|
||||||
Types:Enchantment
|
Types:Enchantment
|
||||||
K:Cumulative upkeep:1
|
K:Cumulative upkeep:1
|
||||||
T:Mode$ SpellCast | ValidCard$ Card.nonCreature | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDraw | OptionalDecider$ You | TriggerDescription$ Whenever an opponent casts a noncreature spell, you may draw a card unless that player pays {4}.
|
T:Mode$ SpellCast | ValidCard$ Card.nonCreature | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever an opponent casts a noncreature spell, you may draw a card unless that player pays {4}.
|
||||||
SVar:TrigDraw:DB$ Draw | Defined$ You | UnlessCost$ 4 | UnlessPayer$ TriggeredPlayer | NumCards$ 1
|
SVar:TrigDraw:DB$ Draw | Defined$ You | UnlessCost$ 4 | UnlessPayer$ TriggeredPlayer | NumCards$ 1 | OptionalDecider$ You
|
||||||
AI:RemoveDeck:Random
|
AI:RemoveDeck:Random
|
||||||
Oracle:Cumulative upkeep {1} (At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.)\nWhenever an opponent casts a noncreature spell, you may draw a card unless that player pays {4}.
|
Oracle:Cumulative upkeep {1} (At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.)\nWhenever an opponent casts a noncreature spell, you may draw a card unless that player pays {4}.
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ Name:Paradise Druid
|
|||||||
ManaCost:1 G
|
ManaCost:1 G
|
||||||
Types:Creature Elf Druid
|
Types:Creature Elf Druid
|
||||||
PT:2/1
|
PT:2/1
|
||||||
S:Mode$ Continuous | Affected$ Card.Self+untapped | AddKeyword$ Hexproof | Description$ CARDNAME has hexproof as long as it's untapped.(It can't be the target of spells or abilities your opponents control.)
|
S:Mode$ Continuous | Affected$ Card.Self+untapped | AddKeyword$ Hexproof | Description$ CARDNAME has hexproof as long as it's untapped. (It can't be the target of spells or abilities your opponents control.)
|
||||||
A:AB$ Mana | Cost$ T | Produced$ Any | SpellDescription$ Add one mana of any color.
|
A:AB$ Mana | Cost$ T | Produced$ Any | SpellDescription$ Add one mana of any color.
|
||||||
Oracle:Paradise Druid has hexproof as long as it's untapped.(It can't be the target of spells or abilities your opponents control.)\n{T}: Add one mana of any color.
|
Oracle:Paradise Druid has hexproof as long as it's untapped. (It can't be the target of spells or abilities your opponents control.)\n{T}: Add one mana of any color.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
Name:Plumb the Forbidden
|
Name:Plumb the Forbidden
|
||||||
ManaCost:1 B
|
ManaCost:1 B
|
||||||
Types:Instant
|
Types:Instant
|
||||||
T:Mode$ SpellCast | ValidCard$ Card.Self | Execute$ TrigCopy | CheckSVar$ X | TriggerDescription$ As an additional cost to cast this spell, you may sacrifice one or more creatures. When you do, copy this spell for each creature sacrificed this way.
|
T:Mode$ SpellCast | ValidCard$ Card.Self | Execute$ TrigCopy | CheckSVar$ CastSA>Count$xPaid | TriggerDescription$ As an additional cost to cast this spell, you may sacrifice one or more creatures. When you do, copy this spell for each creature sacrificed this way.
|
||||||
SVar:TrigCopy:DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | Amount$ X
|
SVar:TrigCopy:DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | Amount$ X
|
||||||
A:SP$ Draw | Cost$ 1 B Sac<X/Creature> | SubAbility$ DBLoseLife | CostDesc$ | SpellDescription$ You draw a card and you lose 1 life.
|
A:SP$ Draw | Cost$ 1 B Sac<X/Creature> | SubAbility$ DBLoseLife | CostDesc$ | SpellDescription$ You draw a card and you lose 1 life.
|
||||||
SVar:DBLoseLife:DB$ LoseLife | LifeAmount$ 1
|
SVar:DBLoseLife:DB$ LoseLife | LifeAmount$ 1
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Types:Creature Basilisk Mutant
|
|||||||
PT:0/0
|
PT:0/0
|
||||||
K:Graft:3
|
K:Graft:3
|
||||||
A:AB$ Animate | Cost$ 1 G | ValidTgts$ Creature.counters_GE1_P1P1 | TgtPrompt$ Select target creature with a +1/+1 counter on it | Triggers$ DestroyTrigger | SpellDescription$ Until end of turn, target creature with a +1/+1 counter on it gains "Whenever this creature deals combat damage to a creature, destroy that creature at end of combat."
|
A:AB$ Animate | Cost$ 1 G | ValidTgts$ Creature.counters_GE1_P1P1 | TgtPrompt$ Select target creature with a +1/+1 counter on it | Triggers$ DestroyTrigger | SpellDescription$ Until end of turn, target creature with a +1/+1 counter on it gains "Whenever this creature deals combat damage to a creature, destroy that creature at end of combat."
|
||||||
SVar:DestroyTrigger:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Creature | CombatDamage$ True | TriggerZones$ Battlefield | Execute$ DelTrig | TriggerDescription$ Whenever CARDNAME deals combat damage to a creature, destroy that creature at end of combat.
|
SVar:DestroyTrigger:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Creature | CombatDamage$ True | TriggerZones$ Battlefield | Execute$ DelTrigSimic | TriggerDescription$ Whenever CARDNAME deals combat damage to a creature, destroy that creature at end of combat.
|
||||||
SVar:DelTrigSimic:DB$ DelayedTrigger | Mode$ Phase | Phase$ EndCombat | ValidPlayer$ Player | Execute$ TrigDestroySimic | RememberObjects$ TriggeredTargetLKICopy | TriggerDescription$ Destroy damaged creature at end of combat.
|
SVar:DelTrigSimic:DB$ DelayedTrigger | Mode$ Phase | Phase$ EndCombat | ValidPlayer$ Player | Execute$ TrigDestroySimic | RememberObjects$ TriggeredTargetLKICopy | TriggerDescription$ Destroy damaged creature at end of combat.
|
||||||
SVar:TrigDestroySimic:DB$ Destroy | Defined$ DelayTriggerRememberedLKI
|
SVar:TrigDestroySimic:DB$ Destroy | Defined$ DelayTriggerRememberedLKI
|
||||||
SVar:AIGraftPreference:DontMoveCounterIfLethal
|
SVar:AIGraftPreference:DontMoveCounterIfLethal
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ ManaCost:3 B
|
|||||||
Types:Creature Demon
|
Types:Creature Demon
|
||||||
PT:3/3
|
PT:3/3
|
||||||
A:AB$ Effect | PrecostDesc$ Jolly Gutpipes — | Cost$ 2 T Sac<1/Creature> | StaticAbilities$ GrantCascade | Triggers$ ExileEffect | SpellDescription$ The next creature spell you cast this turn has cascade. (When you cast your next creature spell, exile cards from the top of your library until you exile a nonland card that costs less. You may cast it without paying its mana cost. Put the exiled cards on the bottom of your library in a random order.)
|
A:AB$ Effect | PrecostDesc$ Jolly Gutpipes — | Cost$ 2 T Sac<1/Creature> | StaticAbilities$ GrantCascade | Triggers$ ExileEffect | SpellDescription$ The next creature spell you cast this turn has cascade. (When you cast your next creature spell, exile cards from the top of your library until you exile a nonland card that costs less. You may cast it without paying its mana cost. Put the exiled cards on the bottom of your library in a random order.)
|
||||||
SVar:GrantCascade:Mode$ Continuous | EffectZone$ Command | Affected$ Card.Creature+YouCtrl | AffectedZone$ Stack | Execute$ ExileEff | AddKeyword$ Cascade | Description$ The next noncreature spell you cast this turn has cascade.
|
SVar:GrantCascade:Mode$ Continuous | EffectZone$ Command | Affected$ Card.Creature+YouCtrl | AffectedZone$ Stack | AddKeyword$ Cascade | Description$ The next noncreature spell you cast this turn has cascade.
|
||||||
SVar:ExileEffect:Mode$ SpellCast | EffectZone$ Command | ValidCard$ Card.Creature+YouCtrl | Execute$ RemoveEffect | Static$ True
|
SVar:ExileEffect:Mode$ SpellCast | EffectZone$ Command | ValidCard$ Card.Creature+YouCtrl | Execute$ RemoveEffect | Static$ True
|
||||||
SVar:RemoveEffect:DB$ ChangeZone | Origin$ Command | Destination$ Exile | Defined$ Self
|
SVar:RemoveEffect:DB$ ChangeZone | Origin$ Command | Destination$ Exile | Defined$ Self
|
||||||
DeckHas:Keyword$Cascade & Ability$Sacrifice
|
DeckHas:Keyword$Cascade & Ability$Sacrifice
|
||||||
|
|||||||
Reference in New Issue
Block a user