diff --git a/.gitattributes b/.gitattributes index ff18209be00..314f5f27d60 100644 --- a/.gitattributes +++ b/.gitattributes @@ -771,6 +771,7 @@ res/cardsfolder/b/beasts_of_bogardan.txt svneol=native#text/plain res/cardsfolder/b/beckon_apparition.txt svneol=native#text/plain res/cardsfolder/b/bedlam.txt svneol=native#text/plain res/cardsfolder/b/bee_sting.txt svneol=native#text/plain +res/cardsfolder/b/beetleback_chief.txt -text res/cardsfolder/b/befoul.txt svneol=native#text/plain res/cardsfolder/b/beguiler_of_wills.txt -text res/cardsfolder/b/behemoth_sledge.txt svneol=native#text/plain @@ -994,6 +995,7 @@ res/cardsfolder/b/boartusk_liege.txt svneol=native#text/plain res/cardsfolder/b/body_double.txt -text res/cardsfolder/b/body_of_jukai.txt svneol=native#text/plain res/cardsfolder/b/body_snatcher.txt -text svneol=unset#text/plain +res/cardsfolder/b/bog_elemental.txt -text res/cardsfolder/b/bog_glider.txt svneol=native#text/plain res/cardsfolder/b/bog_gnarr.txt svneol=native#text/plain res/cardsfolder/b/bog_hoodlums.txt svneol=native#text/plain @@ -1150,6 +1152,7 @@ res/cardsfolder/b/brimstone_dragon.txt svneol=native#text/plain res/cardsfolder/b/brimstone_mage.txt svneol=native#text/plain res/cardsfolder/b/brimstone_volley.txt -text res/cardsfolder/b/brindle_boar.txt svneol=native#text/plain +res/cardsfolder/b/brindle_shoat.txt -text res/cardsfolder/b/brine_elemental.txt -text res/cardsfolder/b/brine_shaman.txt svneol=native#text/plain res/cardsfolder/b/bringer_of_the_black_dawn.txt svneol=native#text/plain @@ -2434,6 +2437,7 @@ res/cardsfolder/d/dragon_shadow.txt -text res/cardsfolder/d/dragon_tyrant.txt svneol=native#text/plain res/cardsfolder/d/dragon_whelp.txt svneol=native#text/plain res/cardsfolder/d/dragon_wings.txt -text +res/cardsfolder/d/dragonlair_spider.txt -text res/cardsfolder/d/dragonmaster_outcast.txt svneol=native#text/plain res/cardsfolder/d/dragons_claw.txt svneol=native#text/plain res/cardsfolder/d/dragons_herald.txt -text @@ -2479,6 +2483,7 @@ res/cardsfolder/d/dream_thrush.txt -text res/cardsfolder/d/dream_twist.txt -text res/cardsfolder/d/dreamborn_muse.txt svneol=native#text/plain res/cardsfolder/d/dreamcatcher.txt svneol=native#text/plain +res/cardsfolder/d/dreampod_druid.txt -text res/cardsfolder/d/dreams_grip.txt svneol=native#text/plain res/cardsfolder/d/dreams_of_the_dead.txt -text res/cardsfolder/d/dreamscape_artist.txt svneol=native#text/plain @@ -4538,6 +4543,7 @@ res/cardsfolder/i/indomitable_ancients.txt svneol=native#text/plain res/cardsfolder/i/indomitable_archangel.txt svneol=native#text/plain res/cardsfolder/i/indomitable_will.txt svneol=native#text/plain res/cardsfolder/i/indrik_stomphowler.txt svneol=native#text/plain +res/cardsfolder/i/indrik_umbra.txt -text res/cardsfolder/i/induce_despair.txt -text res/cardsfolder/i/induce_paranoia.txt -text svneol=unset#text/plain res/cardsfolder/i/inertia_bubble.txt svneol=native#text/plain @@ -5061,6 +5067,7 @@ res/cardsfolder/k/krark_clan_shaman.txt svneol=native#text/plain res/cardsfolder/k/krark_clan_stoker.txt svneol=native#text/plain res/cardsfolder/k/kresh_the_bloodbraided.txt svneol=native#text/plain res/cardsfolder/k/kris_mage.txt svneol=native#text/plain +res/cardsfolder/k/krond_the_dawn_clad.txt -text res/cardsfolder/k/krosan_archer.txt svneol=native#text/plain res/cardsfolder/k/krosan_avenger.txt svneol=native#text/plain res/cardsfolder/k/krosan_beast.txt svneol=native#text/plain @@ -6954,6 +6961,7 @@ res/cardsfolder/p/presence_of_the_wise.txt svneol=native#text/plain res/cardsfolder/p/pretenders_claim.txt svneol=native#text/plain res/cardsfolder/p/prey_upon.txt -text res/cardsfolder/p/preys_vengeance.txt -text +res/cardsfolder/p/preyseizer_dragon.txt -text res/cardsfolder/p/price_of_progress.txt svneol=native#text/plain res/cardsfolder/p/prickly_boggart.txt svneol=native#text/plain res/cardsfolder/p/pride_guardian.txt svneol=native#text/plain @@ -9482,6 +9490,7 @@ res/cardsfolder/t/thief_of_hope.txt svneol=native#text/plain res/cardsfolder/t/thieves_fortune.txt -text res/cardsfolder/t/thieving_magpie.txt svneol=native#text/plain res/cardsfolder/t/thieving_sprite.txt -text +res/cardsfolder/t/thing_from_the_deep.txt -text res/cardsfolder/t/think_tank.txt svneol=native#text/plain res/cardsfolder/t/think_twice.txt svneol=native#text/plain res/cardsfolder/t/thirst.txt svneol=native#text/plain diff --git a/CHANGES.txt b/CHANGES.txt index f9c35f32f5b..7eecb10235f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -377,6 +377,45 @@ Fixes/Features: - Updated setdata.txt, mtg-data.txt and setInfoScript.py with Planechase 2012 info. - Fixed a bug in AF Reveal. - Added the recent commit logs to changes.txt. Preparing for the snapshot build release. +- Added a fluff piece to the changes.txt file. +- Updated AF Pump AI. +- Fixed Dream Thief. +- Fixed Rats' Feast (was referencing the incorrect svar) +- AbilityWork: Added References$ parameter to scripted abilities of 'P-R' cards where necessary. +- Added a fluff piece to the changes.txt file. +- update plugins +- Fixed Lotus Bloom. +- merged r15782-r15810 from the Trunk into CloneFix branch +- Improved AI handling some HIDDEN keywords with AF Pump. +- Performance update in staticDamagePrevention. +- Little Performance update in hasSickness(). +- Graft will no longer trigger if the card has no more +1/+1 counters. +- The AI will now be more careful when fetching legendary permanents. +- Added the recent commit logs to changes.txt. Preparing for the snapshot build release. +- Fixed Sever the Bloodline. +- Updated text of Hunting Grounds. +- Added unpairing to moveToLibrary. +- Fixed targeting in gainLifeDoTriggerAINoCost. +- CheckStyle. +- Improved AI of some cards using AF Charm. +- Creating branch for M13 Cards +- Changed delayed triggers of Pacts to abilities rather than spells; Summoner's Pact no longer shuffles into library +- Fixed Riders of Gavony. +- Added the recent commit logs to changes.txt. +- Added the recent commit logs to changes.txt. Preparing for the snapshot build release. +- Merged changes from trunk to AbilityWork: r15686-r15836 +- Somehow missed some scripts in the merge... +- Cardshop UI tweaks: +* Removed Add/Remove 4-of. +* Relabeled As Buy/Sell. +* Added credits counter. +* Added Max Selling Percentage and Price. +* Fixed labels and buttons to return to normal for regular deck editor. +- Added the recent commit logs to changes.txt. Preparing for the snapshot build release. +- Removed AI column from card shop. +- Removed New Column from Cards for Sale. +- Fixed moveToLibrary bug. +- Added the recent commit logs to changes.txt. Preparing for the snapshot build release. Many people helped with this version. A special thank you goes out to them. (Attempted to list names alphabetically): @@ -468,6 +507,15 @@ Etherium-Horn Sorcerer Maelstrom Wanderer Mass Mutiny Shardless Agent +Beetleback Chief +Brindle Shoat +Thing from the Deep +Bog Elemental +Krond the Dawn-Clad +Preyseizer Dragon +Indrik Umbra +Dragonlair Spider +Dreampod Druid end diff --git a/res/cardsfolder/b/beetleback_chief.txt b/res/cardsfolder/b/beetleback_chief.txt new file mode 100644 index 00000000000..9680a72c5e9 --- /dev/null +++ b/res/cardsfolder/b/beetleback_chief.txt @@ -0,0 +1,12 @@ +Name:Beetleback Chief +ManaCost:2 R R +Types:Creature Goblin Warrior +Text:no text +PT:2/2 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, put two 1/1 red Goblin creature tokens onto the battlefield. +SVar:TrigToken:AB$Token | Cost$ 0 | TokenAmount$ 2 | TokenName$ Goblin | TokenTypes$ Creature,Goblin | TokenOwner$ You | TokenColors$ Red | TokenPower$ 1 | TokenToughness$ 1 +SVar:Rarity:Uncommon +SVar:Picture:http://www.wizards.com/global/images/magic/general/beetleback_chief.jpg +SetInfo:PC2|Uncommon|http://magiccards.info/scans/en/pc2/40.jpg +Oracle:When Beetleback Chief enters the battlefield, put two 1/1 red Goblin creature tokens onto the battlefield. +End \ No newline at end of file diff --git a/res/cardsfolder/b/bog_elemental.txt b/res/cardsfolder/b/bog_elemental.txt new file mode 100644 index 00000000000..df72b0bf7de --- /dev/null +++ b/res/cardsfolder/b/bog_elemental.txt @@ -0,0 +1,17 @@ +Name:Bog Elemental +ManaCost:3 B B +Types:Creature Elemental +Text:no text +PT:5/4 +K:Protection from white +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigSac | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, sacrifice CARDNAME unless you sacrifice a land. +SVar:TrigSac:AB$ Sacrifice | Cost$ 0 | Amount$ 1 | SacValid$ Land | RememberSacrificed$ True | Optional$ True | SubAbility$ DBSacSelf +SVar:DBSacSelf:DB$ Sacrifice | Defined$ Self | SubAbility$ DBCleanup | ConditionCheckSVar$ X | ConditionSVarCompare$ LT1 +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:X:Remembered$Amount +SVar:RemAIDeck:True +SVar:Rarity:Rare +SVar:Picture:http://www.wizards.com/global/images/magic/general/bog_elemental.jpg +SetInfo:PCY|Rare|http://magiccards.info/scans/en/pr/57.jpg +Oracle:Protection from white\nAt the beginning of your upkeep, sacrifice Bog Elemental unless you sacrifice a land. +End \ No newline at end of file diff --git a/res/cardsfolder/b/brindle_shoat.txt b/res/cardsfolder/b/brindle_shoat.txt new file mode 100644 index 00000000000..9e67fb2937d --- /dev/null +++ b/res/cardsfolder/b/brindle_shoat.txt @@ -0,0 +1,13 @@ +Name:Brindle Shoat +ManaCost:1 G +Types:Creature Boar +Text:no text +PT:1/1 +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigToken | TriggerController$ TriggeredCardController | TriggerDescription$ When CARDNAME dies, put a 3/3 green Boar creature token onto the battlefield. +SVar:TrigToken:AB$Token | Cost$ 0 | TokenAmount$ 1 | TokenName$ Boar | TokenTypes$ Creature,Boar | TokenOwner$ TriggeredCardController | TokenColors$ Green | TokenPower$ 3 | TokenToughness$ 3 +SVar:SacMe:4 +SVar:Rarity:Uncommon +SVar:Picture:http://www.wizards.com/global/images/magic/general/brindle_shoat.jpg +SetInfo:PC2|Uncommon|http://magiccards.info/scans/en/pc2/60.jpg +Oracle:When Brindle Shoat dies, put a 3/3 green Boar creature token onto the battlefield. +End \ No newline at end of file diff --git a/res/cardsfolder/d/deftblade_elite.txt b/res/cardsfolder/d/deftblade_elite.txt index 609f8942645..411dfba4680 100644 --- a/res/cardsfolder/d/deftblade_elite.txt +++ b/res/cardsfolder/d/deftblade_elite.txt @@ -4,7 +4,7 @@ Types:Creature Human Soldier Text:no text PT:1/1 K:Provoke -A:AB$ Pump | Cost$ 1 W | KW$ HIDDEN Prevent all damage that would be dealt to CARDNAME. & HIDDEN Prevent all combat damage that would be dealt by CARDNAME. | SpellDescription$ Prevent all combat damage that would be dealt to and dealt by CARDNAME this turn. +A:AB$ Pump | Cost$ 1 W | KW$ HIDDEN Prevent all combat damage that would be dealt to and dealt by CARDNAME. | SpellDescription$ Prevent all combat damage that would be dealt to and dealt by CARDNAME this turn. SVar:RemAIDeck:True SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/deftblade_elite.jpg diff --git a/res/cardsfolder/d/dragonlair_spider.txt b/res/cardsfolder/d/dragonlair_spider.txt new file mode 100644 index 00000000000..4f48c8a066c --- /dev/null +++ b/res/cardsfolder/d/dragonlair_spider.txt @@ -0,0 +1,13 @@ +Name:Dragonlair Spider +ManaCost:2 R R G G +Types:Creature Spider +Text:no text +PT:5/6 +K:Reach +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever an opponent casts a spell, put a 1/1 green Insect creature token onto the battlefield. +SVar:TrigToken:AB$Token | Cost$ 0 | TokenAmount$ 1 | TokenName$ Insect | TokenTypes$ Creature,Insect | TokenOwner$ You | TokenColors$ Green | TokenPower$ 1 | TokenToughness$ 1 +SVar:Rarity:Rare +SVar:Picture:http://www.wizards.com/global/images/magic/general/dragonlair_spider.jpg +SetInfo:PC2|Rare|http://magiccards.info/scans/en/pc2/87.jpg +Oracle:Reach\nWhenever an opponent casts a spell, put a 1/1 green Insect creature token onto the battlefield. +End \ No newline at end of file diff --git a/res/cardsfolder/d/dreampod_druid.txt b/res/cardsfolder/d/dreampod_druid.txt new file mode 100644 index 00000000000..402a0862d51 --- /dev/null +++ b/res/cardsfolder/d/dreampod_druid.txt @@ -0,0 +1,12 @@ +Name:Dreampod Druid +ManaCost:1 G +Types:Creature Human Druid +Text:no text +PT:2/2 +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigToken | IsPresent$ Card.Self+enchanted | TriggerDescription$ At the beginning of each upkeep, if CARDNAME is enchanted, put a 1/1 green Saproling creature token onto the battlefield. +SVar:TrigToken:AB$ Token | Cost$ 0 | TokenAmount$ 1 | TokenName$ Saproling | TokenTypes$ Creature,Saproling | TokenOwner$ You | TokenColors$ Green | TokenPower$ 1 | TokenToughness$ 1 +SVar:Rarity:Uncommon +SVar:Picture:http://www.wizards.com/global/images/magic/general/dreampod_druid.jpg +SetInfo:PC2|Uncommon|http://magiccards.info/scans/en/pc2/64.jpg +Oracle:At the beginning of each upkeep, if Dreampod Druid is enchanted, put a 1/1 green Saproling creature token onto the battlefield. +End \ No newline at end of file diff --git a/res/cardsfolder/e/ebony_charm.txt b/res/cardsfolder/e/ebony_charm.txt index 83cdda1176c..7d7be22ea1a 100644 --- a/res/cardsfolder/e/ebony_charm.txt +++ b/res/cardsfolder/e/ebony_charm.txt @@ -3,8 +3,8 @@ ManaCost:B Types:Instant Text:no text A:SP$ Charm | Cost$ B | Choices$ EbonyDrain,EbonyExile,EbonyFear | Defined$ You | SpellDescription$ Choose one - Target opponent loses 1 life and you gain 1 life; or exile up to three target cards from a single graveyard; or target creature gains fear until end of turn. (It can't be blocked except by artifact creatures and/or black creatures.) -SVar:EbonyDrain:DB$LoseLife | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | LifeAmount$ 1 | SubAbility$ EbonyGain | SpellDescription$ Target opponent loses 1 life and you gain 1 life; -SVar:EbonyGain:DB$GainLife | Defined$ You | LifeAmount$ 1 +SVar:EbonyDrain:DB$ LoseLife | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | LifeAmount$ 1 | SubAbility$ EbonyGain | SpellDescription$ Target opponent loses 1 life and you gain 1 life; +SVar:EbonyGain:DB$ GainLife | Defined$ You | LifeAmount$ 1 SVar:EbonyExile:DB$ ChangeZone | TargetMin$ 0 | TargetMax$ 3 | TargetsFromSingleZone$ True | Origin$ Graveyard | Destination$ Exile | TgtPrompt$ Choose target card in a graveyard | ValidTgts$ Card | SpellDescription$ Exile up to three target cards from a single graveyard; SVar:EbonyFear:DB$ Pump | ValidTgts$ Creature | TgtPrompt$ Select target creature | KW$ Fear | SpellDescription$ Target creature gains fear until end of turn. SVar:RemAIDeck:True diff --git a/res/cardsfolder/h/hunting_grounds.txt b/res/cardsfolder/h/hunting_grounds.txt index 0c1b6c8b7ed..3a66cbceb5c 100644 --- a/res/cardsfolder/h/hunting_grounds.txt +++ b/res/cardsfolder/h/hunting_grounds.txt @@ -2,7 +2,7 @@ Name:Hunting Grounds ManaCost:G W Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigChangeZone | OptionalDecider$ You | Threshold$ True | TriggerDescription$ Threshold - Whenever an opponent casts a spell, you may put a creature card from your hand onto the battlefield. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigChangeZone | OptionalDecider$ You | Threshold$ True | TriggerDescription$ Threshold - As long as seven or more cards are in your graveyard, CARDNAME has "Whenever an opponent casts a spell, you may put a creature card from your hand onto the battlefield." SVar:TrigChangeZone:AB$ ChangeZone | Cost$ 0 | ChangeType$ Creature | ChangeNum$ 1 | Origin$ Hand | Destination$ Battlefield SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/hunting_grounds.jpg diff --git a/res/cardsfolder/i/indrik_umbra.txt b/res/cardsfolder/i/indrik_umbra.txt new file mode 100644 index 00000000000..6689f8ecb36 --- /dev/null +++ b/res/cardsfolder/i/indrik_umbra.txt @@ -0,0 +1,13 @@ +Name:Indrik Umbra +ManaCost:4 G W +Types:Enchantment Aura +Text:no text +K:Enchant creature +K:Totem armor +A:SP$ Attach | Cost$ 4 G W | ValidTgts$ Creature | AILogic$ Pump +S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddPower$ 4 | AddToughness$ 4 | AddKeyword$ First Strike | AddHiddenKeyword$ HIDDEN All creatures able to block CARDNAME do so. | Description$ Enchanted creature gets +4/+4 and has first strike, and all creatures able to block it do so. +SVar:Rarity:Rare +SVar:Picture:http://www.wizards.com/global/images/magic/general/indrik_umbra.jpg +SetInfo:PC2|Rare|http://magiccards.info/scans/en/pc2/96.jpg +Oracle:Enchant creature\nEnchanted creature gets +4/+4 and has first strike, and all creatures able to block it do so.\nTotem armor (If enchanted creature would be destroyed, instead remove all damage from it and destroy this Aura.) +End \ No newline at end of file diff --git a/res/cardsfolder/k/krond_the_dawn_clad.txt b/res/cardsfolder/k/krond_the_dawn_clad.txt new file mode 100644 index 00000000000..baed13c97db --- /dev/null +++ b/res/cardsfolder/k/krond_the_dawn_clad.txt @@ -0,0 +1,15 @@ +Name:Krond the Dawn-Clad +ManaCost:G G G W W W +Types:Legendary Creature Archon +Text:no text +PT:6/6 +K:Flying +K:Vigilance +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigExile | IsPresent$ Card.Self+enchanted | TriggerDescription$ Whenever CARDNAME attacks, if it's enchanted, exile target permanent. +SVar:TrigExile:AB$ ChangeZone | Cost$ 0 | ValidTgts$ Permanent | TgtPrompt$ Select target permanent | Origin$ Battlefield | Destination$ Exile +SVar:EnchantMe:Once +SVar:Rarity:Mythic +SVar:Picture:http://serv3.tcgimages.eu/img/cards/Portal_Second_Age/krond_the_dawn_clad.jpg +SetInfo:PC2|Mythic|http://magiccards.info/scans/en/pc2/99.jpg +Oracle:Flying, vigilance\nWhenever Krond the Dawn-Clad attacks, if it's enchanted, exile target permanent. +End \ No newline at end of file diff --git a/res/cardsfolder/p/pact_of_negation.txt b/res/cardsfolder/p/pact_of_negation.txt index 4e0dc8c1171..3731c5f885e 100644 --- a/res/cardsfolder/p/pact_of_negation.txt +++ b/res/cardsfolder/p/pact_of_negation.txt @@ -5,7 +5,7 @@ Text:no text Colors:blue A:SP$ Counter | Cost$ 0 | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | SubAbility$ DBDelTrig | SpellDescription$ Counter target spell. At the beginning of your next upkeep, pay 3 U U. If you don't, you lose the game. SVar:DBDelTrig:DB$DelayedTrigger | Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigLoseGame | TriggerDescription$ At the beginning of your next upkeep, pay 3 U U. If you don't, you lose the game. -SVar:TrigLoseGame:SP$LosesGame | Cost$ 0 | UnlessCost$ 3 U U | UnlessPayer$ You | Defined$ You +SVar:TrigLoseGame:AB$LosesGame | Cost$ 0 | UnlessCost$ 3 U U | UnlessPayer$ You | Defined$ You SVar:RemAIDeck:True SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/pact_of_negation.jpg diff --git a/res/cardsfolder/p/pact_of_the_titan.txt b/res/cardsfolder/p/pact_of_the_titan.txt index 074a5d7c1ad..d6ee64c470f 100644 --- a/res/cardsfolder/p/pact_of_the_titan.txt +++ b/res/cardsfolder/p/pact_of_the_titan.txt @@ -5,7 +5,7 @@ Text:no text Colors:red A:SP$ Token | Cost$ 0| TokenAmount$ 1 | TokenName$ Giant | TokenTypes$ Creature,Giant | TokenOwner$ You | TokenColors$ Red | TokenPower$ 4 | TokenToughness$ 4 | SubAbility$ DBDelTrig | SpellDescription$ Put a 4/4 red Giant creature token onto the battlefield. At the beginning of your next upkeep, pay 4 R. If you don't, you lose the game. SVar:DBDelTrig:DB$DelayedTrigger | Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigLoseGame | TriggerDescription$ At the beginning of your next upkeep, pay 4 R. If you don't, you lose the game. -SVar:TrigLoseGame:SP$LosesGame | Cost$ 0 | UnlessCost$ 4 R | UnlessPayer$ You | Defined$ You +SVar:TrigLoseGame:AB$LosesGame | Cost$ 0 | UnlessCost$ 4 R | UnlessPayer$ You | Defined$ You SVar:RemAIDeck:True SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/pact_of_the_titan.jpg diff --git a/res/cardsfolder/p/preyseizer_dragon.txt b/res/cardsfolder/p/preyseizer_dragon.txt new file mode 100644 index 00000000000..2c320409cdf --- /dev/null +++ b/res/cardsfolder/p/preyseizer_dragon.txt @@ -0,0 +1,15 @@ +Name:Preyseizer Dragon +ManaCost:4 R R +Types:Creature Dragon +Text:no text +PT:4/4 +K:Flying +K:Devour:2 +T:Mode$ Attacks | ValidCard$ Card.Self | OptionalDecider$ You | Execute$ TrigDealDamage | TriggerDescription$ Whenever CARDNAME attacks, it deals damage to target creature or player equal to the number of +1/+1 counters on CARDNAME. +SVar:TrigDealDamage:AB$ DealDamage | Cost$ 0 | Tgt$ TgtCP | NumDmg$ X +SVar:X:Count$CardCounters.P1P1 +SVar:Rarity:Rare +SVar:Picture:http://www.wizards.com/global/images/magic/general/preyseizer_dragon.jpg +SetInfo:PC2|Rare|http://magiccards.info/scans/en/pc2/50.jpg +Oracle:Flying\nDevour 2 (As this enters the battlefield, you may sacrifice any number of creatures. This creature enters the battlefield with twice that many +1/+1 counters on it.)\nWhenever Preyseizer Dragon attacks, it deals damage to target creature or player equal to the number of +1/+1 counters on Preyseizer Dragon. +End \ No newline at end of file diff --git a/res/cardsfolder/s/sever_the_bloodline.txt b/res/cardsfolder/s/sever_the_bloodline.txt index e59bf4d3d0c..c431378034a 100644 --- a/res/cardsfolder/s/sever_the_bloodline.txt +++ b/res/cardsfolder/s/sever_the_bloodline.txt @@ -4,7 +4,7 @@ Types:Sorcery Text:no text K:Flashback 5 B B A:SP$ ChangeZone | Cost$ 3 B | Origin$ Battlefield | Destination$ Exile | ValidTgts$ Creature | TgtPrompt$ Select target creature | RememberTargets$ True | ForgetOtherTargets$ True | SubAbility$ DBSearch | SpellDescription$ Exile target creature and all other creatures with the same name as that creature. -SVar:DBSearch:DB$ChangeZoneAll | Origin$ Battlefield | Destination$ Exile | Defined$ TargetedController | ChangeType$ Remembered.sameName | Shuffle$ True | SubAbility$ DBCleanup +SVar:DBSearch:DB$ChangeZoneAll | Origin$ Battlefield | Destination$ Exile | ChangeType$ Remembered.sameName | Shuffle$ True | SubAbility$ DBCleanup SVar:DBCleanup:DB$Cleanup | ClearRemembered$ True SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/sever_the_bloodline.jpg diff --git a/res/cardsfolder/s/slaughter_pact.txt b/res/cardsfolder/s/slaughter_pact.txt index 9d0e85cda17..ca5eefe095e 100644 --- a/res/cardsfolder/s/slaughter_pact.txt +++ b/res/cardsfolder/s/slaughter_pact.txt @@ -5,7 +5,7 @@ Text:no text Colors:black A:SP$ Destroy | Cost$ 0 | ValidTgts$ Creature.nonBlack | TgtPrompt$ Select target nonblack creature | SubAbility$ DBDelTrig | SpellDescription$ Destroy target nonblack creature. At the beginning of your next upkeep, pay 2 B. If you don't, you lose the game. SVar:DBDelTrig:DB$DelayedTrigger | Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigLoseGame | TriggerDescription$ At the beginning of your next upkeep, pay 2 B. If you don't, you lose the game. -SVar:TrigLoseGame:SP$LosesGame | Cost$ 0 | UnlessCost$ 2 B | UnlessPayer$ You | Defined$ You +SVar:TrigLoseGame:AB$LosesGame | Cost$ 0 | UnlessCost$ 2 B | UnlessPayer$ You | Defined$ You SVar:RemAIDeck:True SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/slaughter_pact.jpg diff --git a/res/cardsfolder/s/summoners_pact.txt b/res/cardsfolder/s/summoners_pact.txt index d149da465ae..086cdf4b03d 100644 --- a/res/cardsfolder/s/summoners_pact.txt +++ b/res/cardsfolder/s/summoners_pact.txt @@ -3,10 +3,9 @@ ManaCost:0 Types:Instant Text:no text Colors:green -A:SP$ ChangeZone | Cost$ 0 | Origin$ Library | Destination$ Hand | ChangeType$ Creature.Green+YouOwn | ChangeNum$ 1 | SubAbility$ DBShuffle | SpellDescription$ Search your library for a green creature card, reveal it, and put it into your hand. Then shuffle your library. At the beginning of your next upkeep, pay 2 G G. If you don't, you lose the game. -SVar:DBShuffle:DB$ChangeZone | Origin$ Stack | Destination$ Library | Shuffle$ True | SubAbility$ DBDelTrig +A:SP$ ChangeZone | Cost$ 0 | Origin$ Library | Destination$ Hand | ChangeType$ Creature.Green+YouOwn | ChangeNum$ 1 | SubAbility$ DBDelTrig | SpellDescription$ Search your library for a green creature card, reveal it, and put it into your hand. Then shuffle your library. At the beginning of your next upkeep, pay 2 G G. If you don't, you lose the game. SVar:DBDelTrig:DB$DelayedTrigger | Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigLoseGame | TriggerDescription$ At the beginning of your next upkeep, pay 2 G G. If you don't, you lose the game. -SVar:TrigLoseGame:SP$LosesGame | Cost$ 0 | UnlessCost$ 2 G G | UnlessPayer$ You | Defined$ You +SVar:TrigLoseGame:AB$LosesGame | Cost$ 0 | UnlessCost$ 2 G G | UnlessPayer$ You | Defined$ You SVar:RemAIDeck:True SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/summoners_pact.jpg diff --git a/res/cardsfolder/t/thing_from_the_deep.txt b/res/cardsfolder/t/thing_from_the_deep.txt new file mode 100644 index 00000000000..d6222366c67 --- /dev/null +++ b/res/cardsfolder/t/thing_from_the_deep.txt @@ -0,0 +1,17 @@ +Name:Thing from the Deep +ManaCost:6 U U U +Types:Creature Leviathan +Text:no text +PT:9/9 +T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ DeepDooDoo | TriggerDescription$ Whenever CARDNAME attacks, sacrifice it unless you sacrifice an Island. +SVar:DeepDooDoo:AB$ Sacrifice | Cost$ 0 | Amount$ 1 | SacValid$ Island | RememberSacrificed$ True | Optional$ True | SubAbility$ DeepSink +SVar:DeepSink:DB$ Sacrifice | Defined$ Self | SubAbility$ DeepClean | ConditionCheckSVar$ X | ConditionSVarCompare$ LT1 +SVar:DeepClean:DB$ Cleanup | ClearRemembered$ True +SVar:X:Remembered$Amount +SVar:NeedsToPlay:Island.YouCtrl +SVar:RemAIDeck:True +SVar:Rarity:Rare +SVar:Picture:http://www.wizards.com/global/images/magic/general/thing_from_the_deep.jpg +SetInfo:POR|Rare|http://magiccards.info/scans/en/po/74.jpg +Oracle:Whenever Thing from the Deep attacks, sacrifice it unless you sacrifice an Island. +End \ No newline at end of file diff --git a/res/cardsfolder/u/umezawas_jitte.txt b/res/cardsfolder/u/umezawas_jitte.txt index 5dc4a1003ba..7aead1a5e0c 100644 --- a/res/cardsfolder/u/umezawas_jitte.txt +++ b/res/cardsfolder/u/umezawas_jitte.txt @@ -8,7 +8,7 @@ A:AB$ Charm | Cost$ SubCounter<1/CHARGE> | Choices$ JittePump,JitteCurse,JitteLi SVar:JittePump:DB$ Pump | Defined$ Equipped | NumAtt$ +2 | NumDef$ +2 | SpellDescription$ Equipped creature gets +2/+2 until end of turn; SVar:JitteCurse:DB$ Pump | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ -1 | NumDef$ -1 | IsCurse$ True | SpellDescription$ or target creature gets -1/-1 until end of turn; SVar:JitteLife:DB$ GainLife | LifeAmount$ 2 | SpellDescription$ or you gain 2 life. -SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | CounterType$ CHARGE | CounterNum$ 2 +SVar:TrigPutCounter:AB$ PutCounter | Cost$ 0 | CounterType$ CHARGE | CounterNum$ 2 SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/umezawas_jitte.jpg SetInfo:BOK|Rare|http://magiccards.info/scans/en/bok/163.jpg diff --git a/res/gamedata/NonStackingKWList.txt b/res/gamedata/NonStackingKWList.txt index 290fbafab7e..9eccd6fece6 100644 --- a/res/gamedata/NonStackingKWList.txt +++ b/res/gamedata/NonStackingKWList.txt @@ -11,10 +11,13 @@ Flying Haste Hexproof Horsemanship +Indestructible Infect Intimidate Lifelink +Persist Phasing +Prevent all combat damage that would be dealt by CARDNAME. Reach Rebound Shadow @@ -22,5 +25,6 @@ Shroud Split Second Trample Unblockable +Undying Vigilance Wither \ No newline at end of file diff --git a/src/main/java/forge/Card.java b/src/main/java/forge/Card.java index c891f7d6a58..d096ff4486c 100644 --- a/src/main/java/forge/Card.java +++ b/src/main/java/forge/Card.java @@ -3653,7 +3653,7 @@ public class Card extends GameEntity implements Comparable { * @return a boolean. */ public final boolean hasSickness() { - return !this.hasKeyword("Haste") && this.sickness; + return this.sickness && !this.hasKeyword("Haste"); } /** @@ -3663,7 +3663,7 @@ public class Card extends GameEntity implements Comparable { * @return boolean */ public final boolean isSick() { - return !this.hasKeyword("Haste") && this.sickness && this.isCreature(); + return this.sickness && this.isCreature() && !this.hasKeyword("Haste"); } /** @@ -6385,15 +6385,15 @@ public class Card extends GameEntity implements Comparable { * isType. *

* - * @param cardType + * @param type * a {@link java.lang.String} object. * @return a boolean. */ - public final boolean isType(String cardType) { - cardType = this.toMixedCase(cardType); + public final boolean isType(String type) { + type = this.toMixedCase(type); - if (this.typeContains(cardType) - || ((this.isCreature() || this.isTribal()) && CardUtil.isACreatureType(cardType) && this + if (this.typeContains(type) + || ((this.isCreature() || this.isTribal()) && CardUtil.isACreatureType(type) && this .typeContains("AllCreatureTypes"))) { return true; } @@ -7943,48 +7943,52 @@ public class Card extends GameEntity implements Comparable { return 0; } - if (isCombat) { - if (this.hasKeyword("Prevent all combat damage that would be dealt to and dealt by CARDNAME.")) { + for (String kw : source.getKeyword()) { + if (isCombat) { + if (kw.equals("Prevent all combat damage that would be dealt to and dealt by CARDNAME.")) { + return 0; + } + if (kw.equals("Prevent all combat damage that would be dealt by CARDNAME.")) { + return 0; + } + } + if (kw.equals("Prevent all damage that would be dealt to and dealt by CARDNAME.")) { return 0; } - if (this.hasKeyword("Prevent all combat damage that would be dealt to CARDNAME.")) { - return 0; - } - if (source.hasKeyword("Prevent all combat damage that would be dealt to and dealt by CARDNAME.")) { - return 0; - } - if (source.hasKeyword("Prevent all combat damage that would be dealt by CARDNAME.")) { + if (kw.equals("Prevent all damage that would be dealt by CARDNAME.")) { return 0; } } - if (this.hasKeyword("Prevent all damage that would be dealt to CARDNAME.")) { - return 0; - } - if (this.hasKeyword("Prevent all damage that would be dealt to and dealt by CARDNAME.")) { - return 0; - } - if (source.hasKeyword("Prevent all damage that would be dealt to and dealt by CARDNAME.")) { - return 0; - } - if (source.hasKeyword("Prevent all damage that would be dealt by CARDNAME.")) { - return 0; - } - - if (this.hasStartOfKeyword("Absorb")) { - final int absorbed = this.getKeywordMagnitude("Absorb"); - if (restDamage > absorbed) { - restDamage = restDamage - absorbed; - } else { + for (String kw : this.getKeyword()) { + if (isCombat) { + if (kw.equals("Prevent all combat damage that would be dealt to and dealt by CARDNAME.")) { + return 0; + } + if (kw.equals("Prevent all combat damage that would be dealt to CARDNAME.")) { + return 0; + } + } + if (kw.equals("Prevent all damage that would be dealt to CARDNAME.")) { return 0; } - } - - if (this.hasStartOfKeyword("PreventAllDamageBy")) { - String valid = this.getKeyword().get(this.getKeywordPosition("PreventAllDamageBy")); - valid = valid.split(" ", 2)[1]; - if (source.isValid(valid, this.getController(), this)) { + if (kw.equals("Prevent all damage that would be dealt to and dealt by CARDNAME.")) { return 0; } + if (kw.equals("Absorb")) { + final int absorbed = this.getKeywordMagnitude("Absorb"); + if (restDamage > absorbed) { + restDamage = restDamage - absorbed; + } else { + return 0; + } + } + if (kw.startsWith("PreventAllDamageBy")) { + String valid = this.getKeyword().get(this.getKeywordPosition("PreventAllDamageBy")); + valid = valid.split(" ", 2)[1]; + if (source.isValid(valid, this.getController(), this)) { + return 0; + } + } } // Prevent Damage static abilities diff --git a/src/main/java/forge/CardUtil.java b/src/main/java/forge/CardUtil.java index 43a31795c33..9b8a8c17438 100644 --- a/src/main/java/forge/CardUtil.java +++ b/src/main/java/forge/CardUtil.java @@ -620,7 +620,14 @@ public final class CardUtil { * @return a boolean. */ public static boolean isNonStackingKeyword(final String keyword) { - return Constant.Keywords.NON_STACKING_LIST.contains(keyword); + String kw = new String(keyword); + if (kw.startsWith("HIDDEN")) { + kw = kw.substring(7); + } + if (kw.startsWith("Protection")) { + return true; + } + return Constant.Keywords.NON_STACKING_LIST.contains(kw); } /** diff --git a/src/main/java/forge/GameAction.java b/src/main/java/forge/GameAction.java index 9550a6c89a4..7e70d51088b 100644 --- a/src/main/java/forge/GameAction.java +++ b/src/main/java/forge/GameAction.java @@ -666,19 +666,19 @@ public class GameAction { AllZone.getTriggerHandler().clearSuppression(TriggerType.Transformed); } - Card lastKnownInfo = c; - if ((p != null) && p.is(ZoneType.Battlefield)) { - lastKnownInfo = CardUtil.getLKICopy(c); - c = AllZone.getCardFactory().copyCard(c); - } - - c.clearCounters(); // remove all counters - if ((libPosition == -1) || (libPosition > library.size())) { libPosition = library.size(); } - library.add(c, libPosition); + Card lastKnownInfo = c; + if (p != null && p.is(ZoneType.Battlefield)) { + lastKnownInfo = CardUtil.getLKICopy(c); + c.clearCounters(); // remove all counters + library.add(AllZone.getCardFactory().copyCard(c), libPosition); + } else { + c.clearCounters(); // remove all counters + library.add(c, libPosition); + } final HashMap runParams = new HashMap(); runParams.put("Card", lastKnownInfo); @@ -695,6 +695,12 @@ public class GameAction { owner.updateLabelObservers(); } + // Soulbond unpairing + if (c.isPaired()) { + c.getPairedWith().setPairedWith(null); + c.setPairedWith(null); + } + return c; } diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryAlterLife.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryAlterLife.java index 16be06f201c..6fb8a2c94d4 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryAlterLife.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryAlterLife.java @@ -388,10 +388,10 @@ public class AbilityFactoryAlterLife { final Target tgt = sa.getTarget(); if (tgt != null) { tgt.resetTargets(); - if (sa.canTarget(AllZone.getHumanPlayer())) { - tgt.addTarget(AllZone.getHumanPlayer()); - } else if (mandatory && sa.canTarget(AllZone.getComputerPlayer())) { + if (sa.canTarget(AllZone.getComputerPlayer())) { tgt.addTarget(AllZone.getComputerPlayer()); + } else if (mandatory && sa.canTarget(AllZone.getHumanPlayer())) { + tgt.addTarget(AllZone.getHumanPlayer()); } else { return false; } diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryChangeZone.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryChangeZone.java index 52d24a5f6ee..3ca8415d720 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryChangeZone.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryChangeZone.java @@ -166,6 +166,11 @@ public final class AbilityFactoryChangeZone { AbilityFactoryChangeZone.changeZoneResolve(af, this); } + @Override + public boolean canPlayAI() { + return AbilityFactoryChangeZone.changeZoneCanPlayAI(af, this); + } + @Override public boolean chkAIDrawback() { return AbilityFactoryChangeZone.changeZonePlayDrawbackAI(af, this); @@ -1069,33 +1074,49 @@ public final class AbilityFactoryChangeZone { c = CardUtil.getRandom(fetchList.toArray()); } else if (defined) { c = fetchList.get(0); - } else if (type.contains("Basic")) { - c = AbilityFactoryChangeZone.basicManaFixing(fetchList); - } else if (AbilityFactoryChangeZone.areAllBasics(type)) { - c = AbilityFactoryChangeZone.basicManaFixing(fetchList, type); - } else if (fetchList.getNotType("Creature").size() == 0) { - c = CardFactoryUtil.getBestCreatureAI(fetchList); // if only - // creatures - // take the - // best - } else if (ZoneType.Battlefield.equals(destination) || ZoneType.Graveyard.equals(destination)) { - c = CardFactoryUtil.getMostExpensivePermanentAI(fetchList, sa, false); - } else if (ZoneType.Exile.equals(destination)) { - // Exiling your own stuff, if Exiling opponents stuff choose - // best - if (destZone.getPlayer().isHuman()) { - c = CardFactoryUtil.getMostExpensivePermanentAI(fetchList, sa, false); - } else { - c = CardFactoryUtil.getCheapestPermanentAI(fetchList, sa, false); - } } else { - // Don't fetch another tutor with the same name - if (origin.contains(ZoneType.Library) && !fetchList.getNotName(card.getName()).isEmpty()) { - fetchList = fetchList.getNotName(card.getName()); + Card first = fetchList.get(0); + fetchList = fetchList.filter(new CardListFilter() { + @Override + public boolean addCard(final Card c) { + if (c.isType("Legendary")) { + if (!AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield, c.getName()).isEmpty()) { + return false; + } + } + return true; + } + }); + if (type.contains("Basic")) { + c = AbilityFactoryChangeZone.basicManaFixing(fetchList); + } else if (AbilityFactoryChangeZone.areAllBasics(type)) { + c = AbilityFactoryChangeZone.basicManaFixing(fetchList, type); + } else if (fetchList.getNotType("Creature").size() == 0) { + c = CardFactoryUtil.getBestCreatureAI(fetchList); // if only + // creatures + // take the + // best + } else if (ZoneType.Battlefield.equals(destination) || ZoneType.Graveyard.equals(destination)) { + c = CardFactoryUtil.getMostExpensivePermanentAI(fetchList, sa, false); + } else if (ZoneType.Exile.equals(destination)) { + // Exiling your own stuff, if Exiling opponents stuff choose + // best + if (destZone.getPlayer().isHuman()) { + c = CardFactoryUtil.getMostExpensivePermanentAI(fetchList, sa, false); + } else { + c = CardFactoryUtil.getCheapestPermanentAI(fetchList, sa, false); + } + } else { + // Don't fetch another tutor with the same name + if (origin.contains(ZoneType.Library) && !fetchList.getNotName(card.getName()).isEmpty()) { + fetchList = fetchList.getNotName(card.getName()); + } + fetchList.shuffle(); + c = fetchList.get(0); + } + if (c == null) { + c = first; } - - fetchList.shuffle(); - c = fetchList.get(0); } fetched.add(c); @@ -2233,6 +2254,11 @@ public final class AbilityFactoryChangeZone { AbilityFactoryChangeZone.changeZoneAllResolve(af, this); } + @Override + public boolean canPlayAI() { + return AbilityFactoryChangeZone.changeZoneAllCanPlayAI(af, this); + } + @Override public boolean chkAIDrawback() { return AbilityFactoryChangeZone.changeZoneAllPlayDrawbackAI(af, this); diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryCounters.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryCounters.java index df55c61a061..0542c29dc53 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryCounters.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryCounters.java @@ -171,6 +171,11 @@ public class AbilityFactoryCounters { AbilityFactoryCounters.putResolve(af, this); } + @Override + public boolean canPlayAI() { + return AbilityFactoryCounters.putCanPlayAI(af, this); + } + @Override public boolean chkAIDrawback() { return AbilityFactoryCounters.putPlayDrawbackAI(af, this); diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryDealDamage.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryDealDamage.java index 055ee8b9d5b..6222ba4a893 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryDealDamage.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryDealDamage.java @@ -173,6 +173,11 @@ public class AbilityFactoryDealDamage { return AbilityFactoryDealDamage.this.damageDrawback(this); } + @Override + public boolean canPlayAI() { + return AbilityFactoryDealDamage.this.dealDamageCanPlayAI(this); + } + @Override public String getStackDescription() { return AbilityFactoryDealDamage.this.dealDamageStackDescription( @@ -959,6 +964,11 @@ public class AbilityFactoryDealDamage { return AbilityFactoryDealDamage.this.damageAllStackDescription(this.af, this); } + @Override + public boolean canPlayAI() { + return AbilityFactoryDealDamage.this.damageAllCanPlayAI(this.af, this); + } + @Override public void resolve() { AbilityFactoryDealDamage.this.damageAllResolve(this.af, this); diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryDestroy.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryDestroy.java index 93c151ed98a..9fc6b626412 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryDestroy.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryDestroy.java @@ -688,6 +688,11 @@ public class AbilityFactoryDestroy { return AbilityFactoryDestroy.destroyAllStackDescription(af, this, this.noRegen); } + @Override + public boolean canPlayAI() { + return AbilityFactoryDestroy.destroyAllCanPlayAI(af, this, this.noRegen); + } + @Override public void resolve() { AbilityFactoryDestroy.destroyAllResolve(af, this, this.noRegen); diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryGainControl.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryGainControl.java index c745bae6134..b443c5952bd 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryGainControl.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryGainControl.java @@ -411,7 +411,11 @@ public class AbilityFactoryGainControl { GameEntity newController; if (controllers.size() == 0) { - newController = this.hostCard; + if (sa.isSpell()) { + newController = sa.getActivatingPlayer(); + } else { + newController = this.hostCard; + } } else { newController = controllers.get(0); } @@ -446,16 +450,16 @@ public class AbilityFactoryGainControl { if (this.lose != null) { if (this.lose.contains("LeavesPlay")) { - this.hostCard.addLeavesPlayCommand(this.getLoseControlCommand(tgtC, originalController)); + this.hostCard.addLeavesPlayCommand(this.getLoseControlCommand(tgtC, originalController, newController)); } if (this.lose.contains("Untap")) { - this.hostCard.addUntapCommand(this.getLoseControlCommand(tgtC, originalController)); + this.hostCard.addUntapCommand(this.getLoseControlCommand(tgtC, originalController, newController)); } if (this.lose.contains("LoseControl")) { - this.hostCard.addChangeControllerCommand(this.getLoseControlCommand(tgtC, originalController)); + this.hostCard.addChangeControllerCommand(this.getLoseControlCommand(tgtC, originalController, newController)); } if (this.lose.contains("EOT")) { - AllZone.getEndOfTurn().addAt(this.getLoseControlCommand(tgtC, originalController)); + AllZone.getEndOfTurn().addAt(this.getLoseControlCommand(tgtC, originalController, newController)); } } @@ -472,7 +476,7 @@ public class AbilityFactoryGainControl { } this.hostCard.clearGainControlReleaseCommands(); - this.hostCard.addGainControlReleaseCommand(this.getLoseControlCommand(tgtC, originalController)); + this.hostCard.addGainControlReleaseCommand(this.getLoseControlCommand(tgtC, originalController, newController)); } // end foreach target } @@ -586,14 +590,15 @@ public class AbilityFactoryGainControl { * a {@link forge.game.player.Player} object. * @return a {@link forge.Command} object. */ - private Command getLoseControlCommand(final Card c, final Player originalController) { + private Command getLoseControlCommand(final Card c, final Player originalController, final GameEntity newController) { final Command loseControl = new Command() { private static final long serialVersionUID = 878543373519872418L; @Override public void execute() { AbilityFactoryGainControl.doLoseControl(c, AbilityFactoryGainControl.this.hostCard, - AbilityFactoryGainControl.this.bTapOnLose, AbilityFactoryGainControl.this.kws); + AbilityFactoryGainControl.this.bTapOnLose, AbilityFactoryGainControl.this.kws, + newController); } // execute() }; @@ -601,12 +606,12 @@ public class AbilityFactoryGainControl { } private static void doLoseControl(final Card c, final Card host, final boolean tapOnLose, - final ArrayList addedKeywords) { + final ArrayList addedKeywords, final GameEntity newController) { if (null == c) { return; } if (AllZoneUtil.isCardInPlay(c)) { - c.removeController(host); + c.removeController(newController); // Singletons.getModel().getGameAction().changeController(new CardList(c), // c.getController(), originalController); diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryPermanentState.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryPermanentState.java index 4fb63b384be..404e1fe33b2 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryPermanentState.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryPermanentState.java @@ -150,6 +150,11 @@ public class AbilityFactoryPermanentState { AbilityFactoryPermanentState.untapResolve(af, this); } + @Override + public boolean canPlayAI() { + return AbilityFactoryPermanentState.untapCanPlayAI(af, this); + } + @Override public boolean chkAIDrawback() { return AbilityFactoryPermanentState.untapPlayDrawbackAI(af, this); @@ -714,6 +719,11 @@ public class AbilityFactoryPermanentState { AbilityFactoryPermanentState.tapResolve(af, this); } + @Override + public boolean canPlayAI() { + return AbilityFactoryPermanentState.tapCanPlayAI(af, this); + } + @Override public boolean chkAIDrawback() { return AbilityFactoryPermanentState.tapPlayDrawbackAI(af, this); @@ -1485,6 +1495,11 @@ public class AbilityFactoryPermanentState { AbilityFactoryPermanentState.tapAllResolve(af, this); } + @Override + public boolean canPlayAI() { + return AbilityFactoryPermanentState.tapAllCanPlayAI(af, this); + } + @Override public boolean chkAIDrawback() { return AbilityFactoryPermanentState.tapAllPlayDrawbackAI(af, this); diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryPump.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryPump.java index 8186ddb63a7..6a9a203cc8f 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryPump.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryPump.java @@ -302,6 +302,18 @@ public class AbilityFactoryPump { if (ph.getPhase().isBefore(PhaseType.MAIN2) || card.isUntapped() || ph.isPlayerTurn(human)) { return false; } + } else if (keyword.endsWith("Prevent all combat damage that would be dealt by CARDNAME.")) { + if (ph.isPlayerTurn(computer) && (!CombatUtil.canBlock(card) + || card.getNetCombatDamage() <= 0 + || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY) + || ph.getPhase().isBefore(PhaseType.MAIN1) + || AllZoneUtil.getCreaturesInPlay(computer).isEmpty())) { + return false; + } + if (ph.isPlayerTurn(human) && (!card.isAttacking() + || card.getNetCombatDamage() <= 0)) { + return false; + } } else if (keyword.endsWith("CARDNAME attacks each turn if able.")) { if (ph.isPlayerTurn(human) || !CombatUtil.canAttack(card) || !CombatUtil.canBeBlocked(card) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)) { @@ -1373,6 +1385,11 @@ public class AbilityFactoryPump { AbilityFactoryPump.this.pumpAllResolve(this); } // resolve + @Override + public boolean canPlayAI() { + return AbilityFactoryPump.this.pumpAllCanPlayAI(this); + } + @Override public boolean chkAIDrawback() { return AbilityFactoryPump.this.pumpAllChkDrawbackAI(this); diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryReveal.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryReveal.java index c1d1ab79a17..cfb1d351d09 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryReveal.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryReveal.java @@ -160,6 +160,11 @@ public final class AbilityFactoryReveal { AbilityFactoryReveal.digResolve(af, this); } + @Override + public boolean canPlayAI() { + return AbilityFactoryReveal.digCanPlayAI(af, this); + } + @Override public boolean chkAIDrawback() { return true; diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryZoneAffecting.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryZoneAffecting.java index ccb9ba0aa65..02d3e988c6a 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryZoneAffecting.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryZoneAffecting.java @@ -152,6 +152,11 @@ public class AbilityFactoryZoneAffecting { return AbilityFactoryZoneAffecting.drawStackDescription(af, this); } + @Override + public boolean canPlayAI() { + return AbilityFactoryZoneAffecting.drawCanPlayAI(af, this); + } + @Override public void resolve() { AbilityFactoryZoneAffecting.drawResolve(af, this); @@ -1121,6 +1126,11 @@ public class AbilityFactoryZoneAffecting { AbilityFactoryZoneAffecting.discardResolve(af, this); } + @Override + public boolean canPlayAI() { + return AbilityFactoryZoneAffecting.discardCanPlayAI(af, this); + } + @Override public boolean chkAIDrawback() { return AbilityFactoryZoneAffecting.discardCheckDrawbackAI(af, this); diff --git a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java index f068d8f5b04..fee13083de3 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java @@ -4862,11 +4862,12 @@ public class CardFactoryUtil { card.setSVar("GraftTrig", abStr); String trigStr = "Mode$ ChangesZone | ValidCard$ Creature.Other | " - + "Origin$ Any | Destination$ Battlefield"; - trigStr += " | TriggerZones$ Battlefield | OptionalDecider$ You | " - + "Execute$ GraftTrig | TriggerDescription$ "; - trigStr += "Whenever another creature enters the battlefield, you " - + "may move a +1/+1 counter from this creature onto it."; + + "Origin$ Any | Destination$ Battlefield" + + " | TriggerZones$ Battlefield | OptionalDecider$ You | " + + "IsPresent$ Card.Self+counters_GE1_P1P1 | " + + "Execute$ GraftTrig | TriggerDescription$ " + + "Whenever another creature enters the battlefield, you " + + "may move a +1/+1 counter from this creature onto it."; final Trigger myTrigger = TriggerHandler.parseTrigger(trigStr, card, true); card.addTrigger(myTrigger); diff --git a/src/main/java/forge/card/mana/ManaCostShard.java b/src/main/java/forge/card/mana/ManaCostShard.java index b4d421b1459..df87ae38d7f 100644 --- a/src/main/java/forge/card/mana/ManaCostShard.java +++ b/src/main/java/forge/card/mana/ManaCostShard.java @@ -70,7 +70,7 @@ public class ManaCostShard { /** A bitmask to represent any mana symbol as an integer. */ public abstract static class Atom { public static final int COLORLESS = 1 << 0; - + /** The Constant WHITE. */ public static final int WHITE = 1 << 1; @@ -109,9 +109,9 @@ public class ManaCostShard { * I choose the latter, because memory for boxed objects will be taken from * heap, while unboxed values will lay on stack, which is faster */ - + public static final ManaCostShard COLORLESS = new ManaCostShard(Atom.COLORLESS, "1"); - + /** The Constant X. */ public static final ManaCostShard X = new ManaCostShard(Atom.IS_X, "X"); @@ -340,11 +340,11 @@ public class ManaCostShard { public boolean isSnow() { return (this.shard & Atom.IS_SNOW) != 0; } - + public boolean isMonoColor() { int colormask = this.shard & (Atom.WHITE | Atom.BLUE | Atom.BLACK | Atom.RED | Atom.GREEN); return BinaryUtil.bitCount(colormask) == 1; - + } /** diff --git a/src/main/java/forge/card/spellability/SpellAbility.java b/src/main/java/forge/card/spellability/SpellAbility.java index 7c2d632fe35..9c104330d50 100644 --- a/src/main/java/forge/card/spellability/SpellAbility.java +++ b/src/main/java/forge/card/spellability/SpellAbility.java @@ -250,8 +250,8 @@ public abstract class SpellAbility { public void setManaCost(final String cost) { this.manaCost = cost; - } - + } + /** *

* Getter for the field additionalManaCost. diff --git a/src/main/java/forge/card/staticability/StaticAbilityContinuous.java b/src/main/java/forge/card/staticability/StaticAbilityContinuous.java index 216465ff5cf..111c792bb6d 100644 --- a/src/main/java/forge/card/staticability/StaticAbilityContinuous.java +++ b/src/main/java/forge/card/staticability/StaticAbilityContinuous.java @@ -128,6 +128,10 @@ public class StaticAbilityContinuous { addKeywords[w] = addKeywords[w].replaceAll("ChosenColor", color.substring(0, 1).toUpperCase().concat(color.substring(1, color.length()))); } } + final String chosenType = hostCard.getChosenType(); + for (int w = 0; w < addKeywords.length; w++) { + addKeywords[w] = addKeywords[w].replaceAll("ChosenType", chosenType); + } } if (params.containsKey("AddHiddenKeyword")) { diff --git a/src/main/java/forge/card/staticability/StaticAbilityCostChange.java b/src/main/java/forge/card/staticability/StaticAbilityCostChange.java index 9895ebfbf32..12ba8f0bca8 100644 --- a/src/main/java/forge/card/staticability/StaticAbilityCostChange.java +++ b/src/main/java/forge/card/staticability/StaticAbilityCostChange.java @@ -66,7 +66,7 @@ public class StaticAbilityCostChange { //modify the cost here return originalCost; } - + /** * Applies applyReduceCostAbility ability. * diff --git a/src/main/java/forge/game/limited/BoosterDraftAI.java b/src/main/java/forge/game/limited/BoosterDraftAI.java index 9a7c5553b72..7e64afb309b 100644 --- a/src/main/java/forge/game/limited/BoosterDraftAI.java +++ b/src/main/java/forge/game/limited/BoosterDraftAI.java @@ -522,17 +522,22 @@ public class BoosterDraftAI { // count each mana symbol in the mana cost for (ManaCostShard shard : mc.getShards()) { byte mask = shard.getColorMask(); - - if ((mask & CardColor.WHITE) > 0 ) + + if ((mask & CardColor.WHITE) > 0) { clrCnts[0].setCount(clrCnts[0].getCount() + 1); - if ((mask & CardColor.BLUE) > 0 ) + } + if ((mask & CardColor.BLUE) > 0) { clrCnts[1].setCount(clrCnts[1].getCount() + 1); - if ((mask & CardColor.BLACK) > 0 ) + } + if ((mask & CardColor.BLACK) > 0) { clrCnts[2].setCount(clrCnts[2].getCount() + 1); - if ((mask & CardColor.RED) > 0 ) + } + if ((mask & CardColor.RED) > 0) { clrCnts[3].setCount(clrCnts[3].getCount() + 1); - if ((mask & CardColor.GREEN) > 0 ) + } + if ((mask & CardColor.GREEN) > 0) { clrCnts[4].setCount(clrCnts[4].getCount() + 1); + } } } diff --git a/src/main/java/forge/game/limited/SealedDeck.java b/src/main/java/forge/game/limited/SealedDeck.java index af435e5dfaf..88ba97282ce 100644 --- a/src/main/java/forge/game/limited/SealedDeck.java +++ b/src/main/java/forge/game/limited/SealedDeck.java @@ -360,17 +360,22 @@ public class SealedDeck { // count each mana symbol in the mana cost for (ManaCostShard shard : mc.getShards()) { byte mask = shard.getColorMask(); - - if ((mask & CardColor.WHITE) > 0 ) + + if ((mask & CardColor.WHITE) > 0) { clrCnts[0].setCount(clrCnts[0].getCount() + 1); - if ((mask & CardColor.BLUE) > 0 ) + } + if ((mask & CardColor.BLUE) > 0) { clrCnts[1].setCount(clrCnts[1].getCount() + 1); - if ((mask & CardColor.BLACK) > 0 ) + } + if ((mask & CardColor.BLACK) > 0) { clrCnts[2].setCount(clrCnts[2].getCount() + 1); - if ((mask & CardColor.RED) > 0 ) + } + if ((mask & CardColor.RED) > 0) { clrCnts[3].setCount(clrCnts[3].getCount() + 1); - if ((mask & CardColor.GREEN) > 0 ) + } + if ((mask & CardColor.GREEN) > 0) { clrCnts[4].setCount(clrCnts[4].getCount() + 1); + } } } diff --git a/src/main/java/forge/game/player/ComputerUtilAttack.java b/src/main/java/forge/game/player/ComputerUtilAttack.java index d1af286bf42..f864df91925 100644 --- a/src/main/java/forge/game/player/ComputerUtilAttack.java +++ b/src/main/java/forge/game/player/ComputerUtilAttack.java @@ -391,7 +391,9 @@ public class ComputerUtilAttack { final Player computer = AllZone.getComputerPlayer(); for (int i = 0; i < this.attackers.size(); i++) { - if (!CombatUtil.canBeBlocked(this.attackers.get(i), this.blockers)) { + if (!CombatUtil.canBeBlocked(this.attackers.get(i), this.blockers) + || this.attackers.get(i).hasKeyword("You may have CARDNAME assign its combat damage as though" + + " it weren't blocked.")) { blockableAttackers.remove(this.attackers.get(i)); } } diff --git a/src/main/java/forge/game/player/Player.java b/src/main/java/forge/game/player/Player.java index 16e7f6cdeb8..cdfd2c81c1f 100644 --- a/src/main/java/forge/game/player/Player.java +++ b/src/main/java/forge/game/player/Player.java @@ -620,20 +620,22 @@ public abstract class Player extends GameEntity { int restDamage = damage; - if (isCombat) { - if (source.hasKeyword("Prevent all combat damage that would be dealt to and dealt by CARDNAME.")) { + for (String kw : source.getKeyword()) { + if (isCombat) { + if (kw.equals("Prevent all combat damage that would be dealt to and dealt by CARDNAME.")) { + return 0; + } + if (kw.equals("Prevent all combat damage that would be dealt by CARDNAME.")) { + return 0; + } + } + if (kw.equals("Prevent all damage that would be dealt to and dealt by CARDNAME.")) { return 0; } - if (source.hasKeyword("Prevent all combat damage that would be dealt by CARDNAME.")) { + if (kw.equals("Prevent all damage that would be dealt by CARDNAME.")) { return 0; } } - if (source.hasKeyword("Prevent all damage that would be dealt to and dealt by CARDNAME.")) { - return 0; - } - if (source.hasKeyword("Prevent all damage that would be dealt by CARDNAME.")) { - return 0; - } // Prevent Damage static abilities final CardList allp = AllZoneUtil.getCardsIn(ZoneType.Battlefield); diff --git a/src/main/java/forge/game/zone/DefaultPlayerZone.java b/src/main/java/forge/game/zone/DefaultPlayerZone.java index 0d61060ebe2..264dcf3624d 100644 --- a/src/main/java/forge/game/zone/DefaultPlayerZone.java +++ b/src/main/java/forge/game/zone/DefaultPlayerZone.java @@ -180,7 +180,7 @@ public class DefaultPlayerZone extends PlayerZone implements java.io.Serializabl public final boolean contains(final Card c) { return this.getCardList().contains(c); } - + /* * (non-Javadoc) * @@ -194,7 +194,6 @@ public class DefaultPlayerZone extends PlayerZone implements java.io.Serializabl } return index; } - /** * Removes the. diff --git a/src/main/java/forge/game/zone/IPlayerZone.java b/src/main/java/forge/game/zone/IPlayerZone.java index 9a213ba2f8e..6733d6c578e 100644 --- a/src/main/java/forge/game/zone/IPlayerZone.java +++ b/src/main/java/forge/game/zone/IPlayerZone.java @@ -156,7 +156,7 @@ interface IPlayerZone { * @return position */ Integer getPosition(Card c); - + /** * isEmpty returns true if given zone contains no cards. * diff --git a/src/main/java/forge/game/zone/MagicStack.java b/src/main/java/forge/game/zone/MagicStack.java index c08655a86e9..2e88f6d6920 100644 --- a/src/main/java/forge/game/zone/MagicStack.java +++ b/src/main/java/forge/game/zone/MagicStack.java @@ -1376,7 +1376,7 @@ public class MagicStack extends MyObservable { public final void clearSimultaneousStack() { this.simultaneousStackEntryList.clear(); } - + /** *

* addSimultaneousStackEntry. diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java index d9583a5b967..0569803411c 100644 --- a/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java +++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java @@ -41,6 +41,8 @@ import forge.gui.deckeditor.views.VCardCatalog; import forge.gui.deckeditor.views.VCurrentDeck; import forge.gui.home.quest.CSubmenuQuestDecks; import forge.gui.home.quest.SSubmenuQuestUtil; +import forge.gui.toolbox.FLabel; +import forge.gui.toolbox.FSkin; import forge.item.BoosterPack; import forge.item.CardPrinted; import forge.item.FatPack; @@ -63,8 +65,13 @@ import forge.util.closures.Lambda1; * @version $Id: CEditorQuestCardShop.java 15088 2012-04-07 11:34:05Z Max mtg $ */ public final class CEditorQuestCardShop extends ACEditorBase { - private final JLabel creditsLabel = new JLabel(); - private final JLabel sellPercentageLabel = new JLabel(); + private final JLabel creditsLabel = new FLabel.Builder() + .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_COINSTACK)) + .fontSize(15).build(); + private final JLabel sellPercentageLabel = new FLabel.Builder().text("0") + .fontSize(11) + .build(); + private double multiplier; private final QuestController questData; @@ -73,6 +80,12 @@ public final class CEditorQuestCardShop extends ACEditorBase mapPrices = this.r.getPriceList(); private Map decksUsingMyCards; + // remember changed gui elements + private String CCTabLabel = new String(); + private String CCAddLabel = new String(); + private String CDTabLabel = new String(); + private String CDRemLabel = new String(); + /** * Child controller for quest card shop UI. * @@ -106,9 +119,10 @@ public final class CEditorQuestCardShop extends ACEditorBaseSelling cards at " + formatter.format(multiPercent) + "% of their value.
" + maxSellingPrice + ""); } @@ -364,7 +395,20 @@ public final class CEditorQuestCardShop extends ACEditorBase 0) || manaCost.isPureGeneric(); final List shards = manaCost.getShards(); @@ -234,7 +233,7 @@ public class CardFaceSymbols { */ public static int getWidth(final CardManaCost manaCost) { int width = manaCost.getShards().size(); - if ( manaCost.getGenericCost() > 0 || ( manaCost.getGenericCost() == 0 && width == 0 ) ); + if (manaCost.getGenericCost() > 0 || (manaCost.getGenericCost() == 0 && width == 0)); width++; /* diff --git a/src/main/java/forge/gui/toolbox/SaveOpenDialog.java b/src/main/java/forge/gui/toolbox/SaveOpenDialog.java index 800cbf33e6b..d70726f0637 100644 --- a/src/main/java/forge/gui/toolbox/SaveOpenDialog.java +++ b/src/main/java/forge/gui/toolbox/SaveOpenDialog.java @@ -32,20 +32,19 @@ import javax.swing.filechooser.FileNameExtensionFilter; */ @SuppressWarnings("serial") public class SaveOpenDialog extends JPanel { - + private JFileChooser fc; - - + /** * Enum to contain information for filetype filtering in the open/save dialog. * Add more entries to enum as needed. - * - * + * + * */ public enum Filetypes { LAYOUT ("Layout File", "xml"), DECK ("Deck File", "dck"); - + private final String TypeName; private final String TypeExtension; Filetypes(String Name, String Extension) { @@ -53,16 +52,15 @@ public class SaveOpenDialog extends JPanel { this.TypeExtension = Extension; } } - + /** * - * constructor for a save or open dialog + * constructor for a save or open dialog. */ public SaveOpenDialog() { fc = new JFileChooser(); } - - + /** * Shows the open dialog for files. If no file selected, returns null. Pass null * to Type to allow all files to be viewed/opened. @@ -73,14 +71,13 @@ public class SaveOpenDialog extends JPanel { */ public File OpenDialog(final File defFileName, final Filetypes type) { fc.setCurrentDirectory(defFileName); - - if (type!=null) { + + if (type != null) { fc.setAcceptAllFileFilterUsed(false); final FileFilter filter = new FileNameExtensionFilter(type.TypeName, type.TypeExtension); fc.addChoosableFileFilter(filter); } - - + int RetValue = fc.showOpenDialog(getParent()); if (RetValue == JFileChooser.APPROVE_OPTION) { final File RetFile = fc.getSelectedFile(); @@ -88,7 +85,7 @@ public class SaveOpenDialog extends JPanel { } return null; } - + /** * Shows the save dialog. * @@ -100,31 +97,30 @@ public class SaveOpenDialog extends JPanel { public File SaveDialog(final File defFileName, final Filetypes type) { File RetFile = defFileName; fc.setCurrentDirectory(defFileName); - + /* set the file filter if desired */ - if (type!=null) { + if (type != null) { fc.setAcceptAllFileFilterUsed(false); final FileFilter filter = new FileNameExtensionFilter(type.TypeName, type.TypeExtension); fc.addChoosableFileFilter(filter); } - + int RetValue = fc.showSaveDialog(getParent()); - + /* user picked save */ if (RetValue == JFileChooser.APPROVE_OPTION) { RetFile = fc.getSelectedFile(); - + /* Adds extension if it is known and not given */ - if (type!=null & !(RetFile.getAbsolutePath().endsWith(type.TypeExtension))) { - RetFile = new File(RetFile.getAbsolutePath()+"."+type.TypeExtension); + if (type != null & !(RetFile.getAbsolutePath().endsWith(type.TypeExtension))) { + RetFile = new File(RetFile.getAbsolutePath() + "." + type.TypeExtension); } - - + return RetFile; } - + /* user picked cancel */ return null; } - -} \ No newline at end of file + +} diff --git a/src/main/java/forge/util/MyObservable.java b/src/main/java/forge/util/MyObservable.java index 304f71cdf2d..e0b9b3e3757 100644 --- a/src/main/java/forge/util/MyObservable.java +++ b/src/main/java/forge/util/MyObservable.java @@ -41,8 +41,8 @@ public class MyObservable extends Observable { this.notifyObservers(); if (Singletons.getModel() == null) { return; } - PhaseHandler phases = Singletons.getModel().getGameState().getPhaseHandler(); - + PhaseHandler phases = Singletons.getModel().getGameState().getPhaseHandler(); + if ((phases != null) && phases.isNeedToNextPhase()) { if (phases.isNeedToNextPhaseInit()) { // this is used. diff --git a/src/main/java/forge/view/arcane/CardPanel.java b/src/main/java/forge/view/arcane/CardPanel.java index 7fabf93523d..bfe98fcc764 100644 --- a/src/main/java/forge/view/arcane/CardPanel.java +++ b/src/main/java/forge/view/arcane/CardPanel.java @@ -406,7 +406,7 @@ public class CardPanel extends JPanel implements CardContainer { (this.cardYOffset + this.cardHeight) - (this.cardHeight / 8) - 16); } - if (this.getCard().isCreature() && this.getCard().hasSickness() && AllZoneUtil.isCardInPlay(this.getCard())) { + if (this.getCard().isSick() && AllZoneUtil.isCardInPlay(this.getCard())) { CardFaceSymbols.drawSymbol("summonsick", g, (this.cardXOffset + (this.cardWidth / 2)) - 16, (this.cardYOffset + this.cardHeight) - (this.cardHeight / 8) - 16); }