diff --git a/forge-game/src/main/java/forge/game/card/CounterEnumType.java b/forge-game/src/main/java/forge/game/card/CounterEnumType.java index 1a8645dedad..b56b8352582 100644 --- a/forge-game/src/main/java/forge/game/card/CounterEnumType.java +++ b/forge-game/src/main/java/forge/game/card/CounterEnumType.java @@ -49,6 +49,8 @@ public enum CounterEnumType { AWAKENING("AWAKE", 0, 231, 79), + BAIT("BAIT", 120, 100, 60), + BLAZE("BLAZE", 255, 124, 82), BLESSING("BLESS", 251, 0, 94), diff --git a/forge-game/src/main/java/forge/game/cost/CostTapType.java b/forge-game/src/main/java/forge/game/cost/CostTapType.java index 509f402adf0..4c8cd61f831 100644 --- a/forge-game/src/main/java/forge/game/cost/CostTapType.java +++ b/forge-game/src/main/java/forge/game/cost/CostTapType.java @@ -148,6 +148,10 @@ public final boolean canPay(final SpellAbility ability, final Player payer, fina String type = this.getType(); boolean sameType = false; + if (type.equals("OriginalHost")) { + return ability.getOriginalHost().canTap(); + } + if (type.contains(".sharesCreatureTypeWith")) { sameType = true; type = TextUtil.fastReplace(type, ".sharesCreatureTypeWith", ""); diff --git a/forge-gui/res/cardsfolder/a/ace_fearless_rebel.txt b/forge-gui/res/cardsfolder/a/ace_fearless_rebel.txt index 0e578ce535a..bb9d38e48dd 100644 --- a/forge-gui/res/cardsfolder/a/ace_fearless_rebel.txt +++ b/forge-gui/res/cardsfolder/a/ace_fearless_rebel.txt @@ -2,7 +2,7 @@ Name:Ace, Fearless Rebel ManaCost:3 G Types:Legendary Creature Human Rebel PT:2/2 -T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigImmediateTrig | OptionalDecider$ You | TriggerDescription$ Nitro-9 — Whenever CARDNAME attacks, you may sacrifice an artifact. When you do, put a +1/+1 counter on CARDNAME, then it fights up to one target creature defending player controls. +T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigImmediateTrig | TriggerDescription$ Nitro-9 — Whenever CARDNAME attacks, you may sacrifice an artifact. When you do, put a +1/+1 counter on CARDNAME, then it fights up to one target creature defending player controls. SVar:TrigImmediateTrig:AB$ ImmediateTrigger | Cost$ Sac<1/Artifact> | Execute$ TrigPutCounter | TriggerDescription$ When you do, put a +1/+1 counter on CARDNAME, then it fights up to one target creature defending player controls. SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBFight SVar:DBFight:DB$ Fight | Defined$ Self | TargetMin$ 0 | TargetMax$ 1 | ValidTgts$ Creature.ControlledBy Spawner>TriggeredDefendingPlayer | TgtPrompt$ Select up to one target creature defending player controls diff --git a/forge-gui/res/cardsfolder/upcoming/alesha_who_laughs_at_fate.txt b/forge-gui/res/cardsfolder/upcoming/alesha_who_laughs_at_fate.txt new file mode 100644 index 00000000000..2e817fec6dc --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/alesha_who_laughs_at_fate.txt @@ -0,0 +1,12 @@ +Name:Alesha, Who Laughs at Fate +ManaCost:1 B R +Types:Legendary Creature Human Warrior +PT:2/2 +K:First Strike +T:Mode$ Attacks | ValidCard$ Creature.Self | Execute$ TrigPutCounter | TriggerDescription$ Whenever NICKNAME attacks, put a +1/+1 counter on it. +SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 +T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | CheckSVar$ RaidTest | Execute$ TrigChangeZone | TriggerDescription$ Raid — At the beginning of your end step, if you attacked this turn, return target creature card with mana value less than or equal to NICKNAME's power from your graveyard to the battlefield. +SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ValidTgts$ Creature.YouOwn+cmcLEX | TgtPrompt$ Select target creature card with mana value less than or equal to Alesha's power +SVar:RaidTest:Count$AttackersDeclared +SVar:X:Count$CardPower +Oracle:First strike\nWhenever Alesha attacks, put a +1/+1 counter on it.\nRaid — At the beginning of your end step, if you attacked this turn, return target creature card with mana value less than or equal to Alesha's power from your graveyard to the battlefield. diff --git a/forge-gui/res/cardsfolder/upcoming/bulk_up.txt b/forge-gui/res/cardsfolder/upcoming/bulk_up.txt new file mode 100644 index 00000000000..fef34370f83 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/bulk_up.txt @@ -0,0 +1,6 @@ +Name:Bulk Up +ManaCost:1 R +Types:Instant +A:SP$ Pump | ValidTgts$ Creature | NumAtt$ Double | StackDescription$ REP target creature_{c:Targeted} | SpellDescription$ Double target creature's power until end of turn. +K:Flashback:4 R R +Oracle:Double target creature's power until end of turn.\nFlashback {4}{R}{R} (You may cast this card from your graveyard for its flashback cost. Then exile it.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/fiery_annihilation.txt b/forge-gui/res/cardsfolder/upcoming/fiery_annihilation.txt new file mode 100644 index 00000000000..ddec1b15b7f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fiery_annihilation.txt @@ -0,0 +1,6 @@ +Name:Fiery Annihilation +ManaCost:2 R +Types:Instant +A:SP$ DealDamage | NumDmg$ 5 | ValidTgts$ Creature | TgtPrompt$ Select target creature | ReplaceDyingDefined$ Targeted | SubAbility$ DBChangeZone | SpellDescription$ CARDNAME deals 5 damage to target creature. Exile up to one target Equipment attached to that creature. If that creature would die this turn, exile it instead. +SVar:DBChangeZone:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | ValidTgts$ Equipment.AttachedTo ParentTarget | TargetMin$ 0 | TargetMax$ 1 +Oracle:Fiery Annihilation deals 5 damage to target creature. Exile up to one target Equipment attached to that creature. If that creature would die this turn, exile it instead. diff --git a/forge-gui/res/cardsfolder/upcoming/fishing_pole.txt b/forge-gui/res/cardsfolder/upcoming/fishing_pole.txt new file mode 100644 index 00000000000..4187aed2881 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fishing_pole.txt @@ -0,0 +1,12 @@ +Name:Fishing Pole +ManaCost:1 +Types:Artifact Equipment +S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddAbility$ FishingPoleBaiting | Description$ Equipped creature has "{1}, {T}, Tap CARDNAME: Put a bait counter on CARDNAME." +SVar:FishingPoleBaiting:AB$ PutCounter | Cost$ 1 T tapXType<1/OriginalHost/Fishing Pole> | CounterType$ BAIT | CounterNum$ 1 | Defined$ OriginalHost | SpellDescription$ Put a bait counter on ORIGINALHOST. +T:Mode$ Untaps | ValidCard$ Creature.EquippedBy | TriggerZones$ Battlefield | Execute$ TrigRemoveCounter | TriggerDescription$ Whenever equipped creature becomes untapped, remove a bait counter from this Equipment. If you do, create a 1/1 blue Fish creature token. +SVar:TrigRemoveCounter:DB$ RemoveCounter | Defined$ Self | CounterType$ BAIT | CounterNum$ 1 | RememberRemoved$ True | SubAbility$ DBToken +SVar:DBToken:DB$ Token | TokenAmount$ 1 | ConditionCheckSVar$ X | ConditionSVarCompare$ GE1 | TokenScript$ u_1_1_fish | TokenOwner$ You | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:X:Count$RememberedSize +K:Equip:2 +Oracle:Equipped creature has "{1}, {T}, Tap Fishing Pole: Put a bait counter on Fishing Pole."\nWhenever equipped creature becomes untapped, remove a bait counter from this Equipment. If you do, create a 1/1 blue Fish creature token.\nEquip {2} ({2}: Attach to target creature you control. Equip only as a sorcery.) diff --git a/forge-gui/res/cardsfolder/upcoming/gornog_the_red_reaper.txt b/forge-gui/res/cardsfolder/upcoming/gornog_the_red_reaper.txt new file mode 100644 index 00000000000..d1c58504ff6 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/gornog_the_red_reaper.txt @@ -0,0 +1,12 @@ +Name:Gornog, the Red Reaper +ManaCost:2 R +Types:Legendary Creature Minotaur Warrior +PT:2/3 +K:Haste +S:Mode$ CantBlockBy | ValidAttacker$ Creature.Warrior | ValidBlocker$ Creature.Coward | Description$ Cowards can't block Warriors. +T:Mode$ AttackersDeclaredOneTarget | AttackedTarget$ Player | ValidAttackers$ Creature.Warrior+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigAnimate | TriggerDescription$ Whenever one or more Warriors you control attack a player, target creature that player controls becomes a Coward. +SVar:TrigAnimate:DB$ Animate | ValidTgts$ Creature | TargetsWithDefinedController$ TriggeredAttackedTarget | TgtPrompt$ Select target creature that player controls | Types$ Coward | RemoveCreatureTypes$ True | Duration$ Permanent +S:Mode$ Continuous | Affected$ Creature.Warrior+attacking+YouCtrl | AddPower$ X | Description$ Attacking Warriors you control get +X/+0, where X is the number of Cowards your opponents control. +SVar:X:Count$Valid Coward.OppCtrl +SVar:PlayMain1:TRUE +Oracle:Haste\nCowards can't block Warriors.\nWhenever one or more Warriors you control attack a player, target creature that player controls becomes a Coward.\nAttacking Warriors you control get +X/+0, where X is the number of Cowards your opponents control. diff --git a/forge-gui/res/cardsfolder/upcoming/grappling_kraken.txt b/forge-gui/res/cardsfolder/upcoming/grappling_kraken.txt new file mode 100644 index 00000000000..0eeb8426e01 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/grappling_kraken.txt @@ -0,0 +1,10 @@ +Name:Grappling Kraken +ManaCost:4 U U +Types:Creature Kraken +PT:5/6 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Land.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigTap | TriggerDescription$ Landfall — Whenever a land you control enters, tap target creature an opponent controls and put a stun counter on it. (If a permanent with a stun counter would become untapped, remove one from it instead.) +SVar:TrigTap:DB$ Tap | ValidTgts$ Creature.OppCtrl | SubAbility$ DBCounter +SVar:DBCounter:DB$ PutCounter | Defined$ Targeted | CounterType$ Stun | CounterNum$ 1 +DeckHas:Ability$Counters +SVar:BuffedBy:Land +Oracle:Landfall — Whenever a land you control enters, tap target creature an opponent controls and put a stun counter on it. (If a permanent with a stun counter would become untapped, remove one from it instead.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/guarded_heir.txt b/forge-gui/res/cardsfolder/upcoming/guarded_heir.txt new file mode 100644 index 00000000000..cb4e489059c --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/guarded_heir.txt @@ -0,0 +1,8 @@ +Name:Guarded Heir +ManaCost:5 W +Types:Creature Human Noble +PT:1/1 +K:Lifelink +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When this creature enters, create two 3/3 white Knight creature tokens. +SVar:TrigToken:DB$ Token | TokenAmount$ 2 | TokenScript$ w_3_3_knight | TokenOwner$ You +Oracle:Lifelink (Damage dealt by this creature also causes you to gain that much life.)\nWhen this creature enters, create two 3/3 white Knight creature tokens. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/high_fae_trickster.txt b/forge-gui/res/cardsfolder/upcoming/high_fae_trickster.txt new file mode 100644 index 00000000000..2a25d913acc --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/high_fae_trickster.txt @@ -0,0 +1,8 @@ +Name:High Fae Trickster +ManaCost:3 U +Types:Creature Faerie Wizard +PT:4/2 +K:Flash +K:Flying +S:Mode$ CastWithFlash | ValidCard$ Card | ValidSA$ Spell | Caster$ You | Description$ You may cast spells as though they had flash. +Oracle:Flash (You may cast this spell any time you could cast an instant.)\nFlying\nYou may cast spells as though they had flash. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/high_society_hunter.txt b/forge-gui/res/cardsfolder/upcoming/high_society_hunter.txt new file mode 100644 index 00000000000..c5d150dd8e1 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/high_society_hunter.txt @@ -0,0 +1,12 @@ +Name:High-Society Hunter +ManaCost:3 B B +Types:Creature Vampire Noble +PT:5/3 +K:Flying +T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever this creature attacks, you may sacrifice another creature. If you do, put a +1/+1 counter on this creature. +SVar:TrigPutCounter:AB$ PutCounter | Cost$ Sac<1/Creature.Other/another creature> | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 +T:Mode$ ChangesZone | ValidCard$ Creature.nonToken+Other | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever another nontoken creature dies, draw a card. +SVar:TrigDraw:DB$ Draw +SVar:HasAttackEffect:TRUE +DeckHas:Ability$Counters|Sacrifice +Oracle:Flying\nWhenever this creature attacks, you may sacrifice another creature. If you do, put a +1/+1 counter on this creature.\nWhenever another nontoken creature dies, draw a card. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/hungry_megasloth.txt b/forge-gui/res/cardsfolder/upcoming/hungry_megasloth.txt new file mode 100644 index 00000000000..7243d4df99b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/hungry_megasloth.txt @@ -0,0 +1,7 @@ +Name:Hungry Megasloth +ManaCost:2 G +Types:Creature Sloth Beast +PT:3/3 +K:Reach +A:AB$ PutCounter | Cost$ 2 T | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on CARDNAME. +Oracle:Reach (This creature can block creatures with flying.)\n{2}, {T}: Put a +1/+1 counter on Hungry Megasloth. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/hurska_sweet_tooth.txt b/forge-gui/res/cardsfolder/upcoming/hurska_sweet_tooth.txt new file mode 100644 index 00000000000..a9dfe015692 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/hurska_sweet_tooth.txt @@ -0,0 +1,11 @@ +Name:Hurska Sweet-Tooth +ManaCost:2 G +Types:Legendary Creature Bear +PT:3/3 +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ Whenever CARDNAME attacks, create a Food token. (It's an artifact with "{2}, {T}, Sacrifice this artifact: You gain 3 life.") +SVar:TrigToken:DB$ Token | TokenScript$ c_a_food_sac +T:Mode$ LifeGained | ValidPlayer$ You | Execute$ TrigImmediateTrig | TriggerZones$ Battlefield | TriggerDescription$ Whenever you gain life, you may pay {G/W}. When you do, target creature gets +X/+X until end of turn, where X is the amount of life you gained. +SVar:TrigImmediateTrig:AB$ ImmediateTrigger | Cost$ GW | Execute$ TrigPump | TriggerDescription$ When you do, target creature gets +X/+X until end of turn, where X is the amount of life you gained. +SVar:TrigPump:DB$ Pump | ValidTgts$ Creature | NumAtt$ Spawner>TriggerCount$LifeAmount | NumDef$ Spawner>TriggerCount$LifeAmount +DeckHas:Ability$Sacrifice|Token & Type$Food|Artifact +Oracle:Whenever Hurska Sweet-Tooth attacks, create a Food token. (It's an artifact with "{2}, {T}, Sacrifice this artifact: You gain 3 life.")\nWhenever you gain life, you may pay {G/W}. When you do, target creature gets +X/+X until end of turn, where X is the amount of life you gained. diff --git a/forge-gui/res/cardsfolder/upcoming/inspiration_from_beyond.txt b/forge-gui/res/cardsfolder/upcoming/inspiration_from_beyond.txt new file mode 100644 index 00000000000..9c78a83e484 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/inspiration_from_beyond.txt @@ -0,0 +1,8 @@ +Name:Inspiration from Beyond +ManaCost:2 U +Types:Sorcery +A:SP$ Mill | NumCards$ 3 | Defined$ You | SubAbility$ DBChangeZone | SpellDescription$ Mill three cards, then return an instant or sorcery card from your graveyard to your hand. +SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | Mandatory$ True | ChangeType$ Instant.YouOwn,Sorcery.YouOwn | ChangeNum$ 1 | Hidden$ True +K:Flashback:5 U U +DeckHas:Ability$Graveyard +Oracle:Mill three cards, then return an instant or sorcery card from your graveyard to your hand.\nFlashback {5}{U}{U} (You may cast this card from your graveyard for its flashback cost. Then exile it.) \ No newline at end of file diff --git a/forge-gui/res/tokenscripts/w_3_3_knight.txt b/forge-gui/res/tokenscripts/w_3_3_knight.txt new file mode 100644 index 00000000000..9b9e5713138 --- /dev/null +++ b/forge-gui/res/tokenscripts/w_3_3_knight.txt @@ -0,0 +1,6 @@ +Name:Knight Token +ManaCost:no cost +Colors:white +Types:Creature Knight +PT:3/3 +Oracle: \ No newline at end of file diff --git a/forge-gui/src/main/java/forge/player/HumanCostDecision.java b/forge-gui/src/main/java/forge/player/HumanCostDecision.java index b64572b0c43..73402c00b5a 100644 --- a/forge-gui/src/main/java/forge/player/HumanCostDecision.java +++ b/forge-gui/src/main/java/forge/player/HumanCostDecision.java @@ -1141,16 +1141,18 @@ public PaymentDecision visit(final CostSacrifice cost) { String type = cost.getType(); if (cost.payCostFromSource()) { - if (source.getController() == ability.getActivatingPlayer() && source.canBeSacrificedBy(ability, isEffect())) { - return mandatory || confirmAction(cost, Localizer.getInstance().getMessage("lblSacrificeCardConfirm", CardTranslation.getTranslatedName(source.getName()))) ? PaymentDecision.card(source) : null; + if (source.getController() == ability.getActivatingPlayer() && source.canBeSacrificedBy(ability, isEffect()) && + (mandatory || confirmAction(cost, Localizer.getInstance().getMessage("lblSacrificeCardConfirm", CardTranslation.getTranslatedName(source.getName()))))) { + return PaymentDecision.card(source); } return null; } if (type.equals("OriginalHost")) { Card host = ability.getOriginalHost(); - if (host.getController() == ability.getActivatingPlayer() && host.canBeSacrificedBy(ability, isEffect())) { - return confirmAction(cost, Localizer.getInstance().getMessage("lblSacrificeCardConfirm", CardTranslation.getTranslatedName(host.getName()))) ? PaymentDecision.card(host) : null; + if (host.getController() == ability.getActivatingPlayer() && host.canBeSacrificedBy(ability, isEffect()) && + confirmAction(cost, Localizer.getInstance().getMessage("lblSacrificeCardConfirm", CardTranslation.getTranslatedName(host.getName())))) { + return PaymentDecision.card(host); } return null; } @@ -1218,6 +1220,14 @@ public PaymentDecision visit(final CostTapType cost) { String type = cost.getType(); final String amount = cost.getAmount(); + if (type.equals("OriginalHost")) { + Card host = ability.getOriginalHost(); + if (host.canTap()) { + return PaymentDecision.card(host); + } + return null; + } + boolean sameType = false; if (type.contains(".sharesCreatureTypeWith")) { sameType = true; @@ -1232,8 +1242,7 @@ public PaymentDecision visit(final CostTapType cost) { type = TextUtil.fastReplace(type, TextUtil.concatNoSpace("+withTotalPowerGE", totalP), ""); } - CardCollection typeList = CardLists.getValidCards(player.getCardsIn(ZoneType.Battlefield), type.split(";"), player, - source, ability); + CardCollection typeList = CardLists.getValidCards(player.getCardsIn(ZoneType.Battlefield), type.split(";"), player, source, ability); typeList = CardLists.filter(typeList, ability.isCrew() ? Presets.CAN_CREW : Presets.CAN_TAP); Integer c = null;