diff --git a/.gitattributes b/.gitattributes index faa6ed5fa89..90aa2b9bcd6 100644 --- a/.gitattributes +++ b/.gitattributes @@ -22,6 +22,7 @@ res/blockdata/setdata.txt svneol=native#text/plain res/blockdata/starters.txt -text res/booster-decks -text res/cardTemplateScript.py -text svneol=unset#text/x-python +res/cardsfolder/a/a_display_of_my_dark_power.txt -text res/cardsfolder/a/abandon_hope.txt -text res/cardsfolder/a/abandoned_outpost.txt svneol=native#text/plain res/cardsfolder/a/abattoir_ghoul.txt -text @@ -210,6 +211,7 @@ res/cardsfolder/a/ali_from_cairo.txt svneol=native#text/plain res/cardsfolder/a/alibans_tower.txt svneol=native#text/plain res/cardsfolder/a/all_hallows_eve.txt svneol=native#text/plain res/cardsfolder/a/all_is_dust.txt svneol=native#text/plain +res/cardsfolder/a/all_shall_smolder_in_my_wake.txt -text res/cardsfolder/a/all_suns_dawn.txt svneol=native#text/plain res/cardsfolder/a/allay.txt svneol=native#text/plain res/cardsfolder/a/alley_grifters.txt svneol=native#text/plain @@ -376,6 +378,7 @@ res/cardsfolder/a/appetite_for_brains.txt -text res/cardsfolder/a/apprentice_necromancer.txt svneol=native#text/plain res/cardsfolder/a/apprentice_sorcerer.txt svneol=native#text/plain res/cardsfolder/a/apprentice_wizard.txt svneol=native#text/plain +res/cardsfolder/a/approach_my_molten_realm.txt -text res/cardsfolder/a/aquamoeba.txt svneol=native#text/plain res/cardsfolder/a/aquamorph_entity.txt -text res/cardsfolder/a/aquastrand_spider.txt -text @@ -840,6 +843,7 @@ 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 res/cardsfolder/b/behemoths_herald.txt -text +res/cardsfolder/b/behold_the_power_of_destruction.txt -text res/cardsfolder/b/belbes_armor.txt svneol=native#text/plain res/cardsfolder/b/belbes_percher.txt svneol=native#text/plain res/cardsfolder/b/belbes_portal.txt svneol=native#text/plain @@ -2164,6 +2168,7 @@ res/cardsfolder/d/damping_matrix.txt -text res/cardsfolder/d/dance_of_many.txt svneol=native#text/plain res/cardsfolder/d/dance_of_shadows.txt svneol=native#text/plain res/cardsfolder/d/dance_of_the_dead.txt svneol=native#text/plain +res/cardsfolder/d/dance_pathetic_marionette.txt -text res/cardsfolder/d/dancing_scimitar.txt svneol=native#text/plain res/cardsfolder/d/dandan.txt svneol=native#text/plain res/cardsfolder/d/dangerous_wager.txt -text @@ -2992,6 +2997,7 @@ res/cardsfolder/e/emberstrike_duo.txt svneol=native#text/plain res/cardsfolder/e/emberwilde_augur.txt svneol=native#text/plain res/cardsfolder/e/emberwilde_caliph.txt svneol=native#text/plain res/cardsfolder/e/emblem_of_the_warmind.txt svneol=native#text/plain +res/cardsfolder/e/embrace_my_diabolical_vision.txt -text res/cardsfolder/e/emerald_charm.txt svneol=native#text/plain res/cardsfolder/e/emerald_dragonfly.txt svneol=native#text/plain res/cardsfolder/e/emerald_medallion.txt svneol=native#text/plain @@ -3160,6 +3166,9 @@ res/cardsfolder/e/everglove_courier.txt svneol=native#text/plain res/cardsfolder/e/everlasting_torment.txt -text res/cardsfolder/e/evermind.txt -text res/cardsfolder/e/evernight_shade.txt -text +res/cardsfolder/e/every_hope_shall_vanish.txt -text +res/cardsfolder/e/every_last_vestige_shall_rot.txt -text +res/cardsfolder/e/evil_comes_to_fruition.txt -text res/cardsfolder/e/evil_eye_of_orms_by_gore.txt svneol=native#text/plain res/cardsfolder/e/evil_eye_of_urborg.txt svneol=native#text/plain res/cardsfolder/e/evil_presence.txt svneol=native#text/plain @@ -4809,6 +4818,8 @@ res/cardsfolder/h/hypnox.txt -text res/cardsfolder/h/hypochondria.txt svneol=native#text/plain res/cardsfolder/h/hysterical_blindness.txt -text res/cardsfolder/h/hystrodon.txt svneol=native#text/plain +res/cardsfolder/i/i_call_on_the_ancient_magics.txt -text +res/cardsfolder/i/i_know_all_i_see_all.txt -text res/cardsfolder/i/ib_halfheart_goblin_tactician.txt -text svneol=unset#text/plain res/cardsfolder/i/icatian_crier.txt svneol=native#text/plain res/cardsfolder/i/icatian_javelineers.txt svneol=native#text/plain @@ -4842,6 +4853,7 @@ res/cardsfolder/i/igneous_golem.txt svneol=native#text/plain res/cardsfolder/i/igneous_pouncer.txt svneol=native#text/plain res/cardsfolder/i/ignite_disorder.txt svneol=native#text/plain res/cardsfolder/i/ignite_memories.txt svneol=native#text/plain +res/cardsfolder/i/ignite_the_cloneforge.txt -text res/cardsfolder/i/ignoble_soldier.txt -text res/cardsfolder/i/ignorant_bliss.txt -text res/cardsfolder/i/ihsans_shade.txt svneol=native#text/plain @@ -4879,6 +4891,7 @@ res/cardsfolder/i/imperious_perfect.txt svneol=native#text/plain res/cardsfolder/i/implements_of_sacrifice.txt svneol=native#text/plain res/cardsfolder/i/implode.txt svneol=native#text/plain res/cardsfolder/i/imposing_visage.txt -text +res/cardsfolder/i/imprison_this_insolent_wretch.txt -text res/cardsfolder/i/impromptu_raid.txt -text res/cardsfolder/i/improvised_armor.txt svneol=native#text/plain res/cardsfolder/i/imps_taunt.txt -text @@ -5802,6 +5815,7 @@ res/cardsfolder/l/long_forgotten_gohei.txt svneol=native#text/plain res/cardsfolder/l/long_term_plans.txt svneol=native#text/plain res/cardsfolder/l/longbow_archer.txt svneol=native#text/plain res/cardsfolder/l/longhorn_firebeast.txt -text +res/cardsfolder/l/look_skyward_and_despair.txt -text res/cardsfolder/l/looming_hoverguard.txt svneol=native#text/plain res/cardsfolder/l/looming_shade.txt svneol=native#text/plain res/cardsfolder/l/looter_il_kor.txt svneol=native#text/plain @@ -6484,6 +6498,7 @@ res/cardsfolder/m/morphling.txt svneol=native#text/plain res/cardsfolder/m/morsel_theft.txt svneol=native#text/plain res/cardsfolder/m/morselhoarder.txt svneol=native#text/plain res/cardsfolder/m/mortal_combat.txt svneol=native#text/plain +res/cardsfolder/m/mortal_flesh_is_weak.txt -text res/cardsfolder/m/mortal_wound.txt svneol=native#text/plain res/cardsfolder/m/mortarpod.txt svneol=native#text/plain res/cardsfolder/m/mortician_beetle.txt svneol=native#text/plain @@ -6564,6 +6579,8 @@ res/cardsfolder/m/muzzle.txt svneol=native#text/plain res/cardsfolder/m/mwonvuli_acid_moss.txt svneol=native#text/plain res/cardsfolder/m/mwonvuli_beast_tracker.txt -text res/cardsfolder/m/mwonvuli_ooze.txt svneol=native#text/plain +res/cardsfolder/m/my_genius_knows_no_bounds.txt -text +res/cardsfolder/m/my_wish_is_your_command.txt -text res/cardsfolder/m/mycoid_shepherd.txt svneol=native#text/plain res/cardsfolder/m/mycologist.txt svneol=native#text/plain res/cardsfolder/m/mycoloth.txt svneol=native#text/plain @@ -6857,6 +6874,7 @@ res/cardsfolder/n/norwood_riders.txt svneol=native#text/plain res/cardsfolder/n/norwood_warrior.txt svneol=native#text/plain res/cardsfolder/n/nostalgic_dreams.txt -text res/cardsfolder/n/nosy_goblin.txt svneol=native#text/plain +res/cardsfolder/n/nothing_can_stop_me_now.txt -text res/cardsfolder/n/notorious_assassin.txt svneol=native#text/plain res/cardsfolder/n/notorious_throng.txt -text svneol=unset#text/plain res/cardsfolder/n/nourish.txt svneol=native#text/plain @@ -7231,6 +7249,7 @@ res/cardsfolder/p/peppersmoke.txt svneol=native#text/plain res/cardsfolder/p/peregrine_drake.txt svneol=native#text/plain res/cardsfolder/p/peregrine_griffin.txt svneol=native#text/plain res/cardsfolder/p/peregrine_mask.txt svneol=native#text/plain +res/cardsfolder/p/perhaps_youve_met_my_cohort.txt -text res/cardsfolder/p/perilous_forays.txt svneol=native#text/plain res/cardsfolder/p/perilous_myr.txt svneol=native#text/plain res/cardsfolder/p/perilous_research.txt svneol=native#text/plain @@ -7428,6 +7447,7 @@ res/cardsfolder/p/platinum_angel.txt svneol=native#text/plain res/cardsfolder/p/platinum_emperion.txt svneol=native#text/plain res/cardsfolder/p/plaxcaster_frogling.txt -text res/cardsfolder/p/plaxmanta.txt -text +res/cardsfolder/p/plots-that-span-centuries.txt -text res/cardsfolder/p/plover_knights.txt svneol=native#text/plain res/cardsfolder/p/plow_through_reito.txt -text res/cardsfolder/p/plow_under.txt svneol=native#text/plain @@ -7891,6 +7911,7 @@ res/cardsfolder/r/reality_ripple.txt -text res/cardsfolder/r/reality_spasm.txt svneol=native#text/plain res/cardsfolder/r/reality_strobe.txt svneol=native#text/plain res/cardsfolder/r/realm_razer.txt -text svneol=unset#text/plain +res/cardsfolder/r/realms_befitting_my_majesty.txt -text res/cardsfolder/r/realms_uncharted.txt -text res/cardsfolder/r/reanimate.txt svneol=native#text/plain res/cardsfolder/r/reap.txt -text @@ -8253,6 +8274,7 @@ res/cardsfolder/r/rootgrapple.txt svneol=native#text/plain res/cardsfolder/r/rooting_kavu.txt -text res/cardsfolder/r/rootrunner.txt svneol=native#text/plain res/cardsfolder/r/roots.txt svneol=native#text/plain +res/cardsfolder/r/roots_of_all_evil.txt -text res/cardsfolder/r/rootwalla.txt svneol=native#text/plain res/cardsfolder/r/rootwater_alligator.txt svneol=native#text/plain res/cardsfolder/r/rootwater_commando.txt svneol=native#text/plain @@ -10211,10 +10233,13 @@ res/cardsfolder/t/the_abyss.txt svneol=native#text/plain res/cardsfolder/t/the_brute.txt svneol=native#text/plain res/cardsfolder/t/the_fallen.txt -text res/cardsfolder/t/the_hive.txt svneol=native#text/plain +res/cardsfolder/t/the_iron_guardian_stirs.txt -text res/cardsfolder/t/the_lady_of_the_mountain.txt svneol=native#text/plain +res/cardsfolder/t/the_pieces_are_coming_together.txt -text res/cardsfolder/t/the_rack.txt svneol=native#text/plain res/cardsfolder/t/the_tabernacle_at_pendrell_vale.txt svneol=native#text/plain res/cardsfolder/t/the_unspeakable.txt svneol=native#text/plain +res/cardsfolder/t/the_very_soil_shall_shake.txt -text res/cardsfolder/t/the_wretched.txt -text svneol=unset#text/plain res/cardsfolder/t/theft_of_dreams.txt svneol=native#text/plain res/cardsfolder/t/thelonite_druid.txt -text @@ -10433,6 +10458,7 @@ res/cardsfolder/t/tomorrow_azamis_familiar.txt -text res/cardsfolder/t/tonic_peddler.txt svneol=native#text/plain res/cardsfolder/t/tooth_and_claw.txt -text res/cardsfolder/t/tooth_and_nail.txt svneol=native#text/plain +res/cardsfolder/t/tooth_claw_and_tail.txt -text res/cardsfolder/t/tooth_of_chiss_goria.txt svneol=native#text/plain res/cardsfolder/t/tooth_of_ramos.txt svneol=native#text/plain res/cardsfolder/t/topan_ascetic.txt svneol=native#text/plain @@ -11361,6 +11387,7 @@ res/cardsfolder/w/wheel_of_torture.txt svneol=native#text/plain res/cardsfolder/w/where_ancients_tread.txt svneol=native#text/plain res/cardsfolder/w/whetstone.txt svneol=native#text/plain res/cardsfolder/w/whetwheel.txt svneol=native#text/plain +res/cardsfolder/w/which_of_you_burns_brightest.txt -text res/cardsfolder/w/whimwader.txt svneol=native#text/plain res/cardsfolder/w/whip_sergeant.txt svneol=native#text/plain res/cardsfolder/w/whip_silk.txt svneol=native#text/plain @@ -11661,6 +11688,9 @@ res/cardsfolder/y/yosei_the_morning_star.txt svneol=native#text/plain res/cardsfolder/y/yotian_soldier.txt svneol=native#text/plain res/cardsfolder/y/young_wei_recruits.txt svneol=native#text/plain res/cardsfolder/y/young_wolf.txt -text +res/cardsfolder/y/your_fate_is_thrice_sealed.txt -text +res/cardsfolder/y/your_puny_minds_cannot_fathom.txt -text +res/cardsfolder/y/your_will_is_not_your_own.txt -text res/cardsfolder/y/youthful_knight.txt svneol=native#text/plain res/cardsfolder/y/yuan_shao_the_indecisive.txt svneol=native#text/plain res/cardsfolder/y/yuan_shaos_infantry.txt svneol=native#text/plain @@ -12791,6 +12821,7 @@ src/main/java/forge/card/abilityfactory/ai/TwoPilesAi.java -text src/main/java/forge/card/abilityfactory/ai/UnattachAllAi.java -text src/main/java/forge/card/abilityfactory/ai/UntapAi.java -text src/main/java/forge/card/abilityfactory/ai/UntapAllAi.java -text +src/main/java/forge/card/abilityfactory/effects/AbandonEffect.java -text src/main/java/forge/card/abilityfactory/effects/AddTurnEffect.java -text src/main/java/forge/card/abilityfactory/effects/AnimateAllEffect.java -text src/main/java/forge/card/abilityfactory/effects/AnimateEffect.java -text @@ -12875,6 +12906,7 @@ src/main/java/forge/card/abilityfactory/effects/RevealHandEffect.java -text src/main/java/forge/card/abilityfactory/effects/SacrificeAllEffect.java -text src/main/java/forge/card/abilityfactory/effects/SacrificeEffect.java -text src/main/java/forge/card/abilityfactory/effects/ScryEffect.java -text +src/main/java/forge/card/abilityfactory/effects/SetInMotionEffect.java -text src/main/java/forge/card/abilityfactory/effects/SetStateAllEffect.java -text src/main/java/forge/card/abilityfactory/effects/SetStateEffect.java -text src/main/java/forge/card/abilityfactory/effects/ShuffleEffect.java -text @@ -12933,6 +12965,7 @@ src/main/java/forge/card/replacement/ReplaceDraw.java -text src/main/java/forge/card/replacement/ReplaceGainLife.java -text src/main/java/forge/card/replacement/ReplaceGameLoss.java -text src/main/java/forge/card/replacement/ReplaceMoved.java -text +src/main/java/forge/card/replacement/ReplaceSetInMotion.java -text src/main/java/forge/card/replacement/ReplacementEffect.java -text src/main/java/forge/card/replacement/ReplacementHandler.java -text src/main/java/forge/card/replacement/ReplacementLayer.java -text @@ -12991,6 +13024,7 @@ src/main/java/forge/card/trigger/TriggerLifeLost.java svneol=native#text/plain src/main/java/forge/card/trigger/TriggerLosesGame.java -text src/main/java/forge/card/trigger/TriggerPhase.java svneol=native#text/plain src/main/java/forge/card/trigger/TriggerSacrificed.java svneol=native#text/plain +src/main/java/forge/card/trigger/TriggerSetInMotion.java -text src/main/java/forge/card/trigger/TriggerShuffled.java svneol=native#text/plain src/main/java/forge/card/trigger/TriggerSpellAbilityCast.java svneol=native#text/plain src/main/java/forge/card/trigger/TriggerTaps.java svneol=native#text/plain @@ -13187,6 +13221,7 @@ src/main/java/forge/gui/deckeditor/controllers/CEditorLimited.java -text src/main/java/forge/gui/deckeditor/controllers/CEditorPreferences.java -text src/main/java/forge/gui/deckeditor/controllers/CEditorQuest.java svneol=native#text/plain src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java -text +src/main/java/forge/gui/deckeditor/controllers/CEditorScheme.java -text src/main/java/forge/gui/deckeditor/controllers/CFilters.java -text src/main/java/forge/gui/deckeditor/controllers/CProbabilities.java -text src/main/java/forge/gui/deckeditor/controllers/CStatistics.java -text diff --git a/res/PerSetTracking.py b/res/PerSetTracking.py index 88253878698..66bd4fbda79 100755 --- a/res/PerSetTracking.py +++ b/res/PerSetTracking.py @@ -80,7 +80,7 @@ for currentSet in setCodes : if currentSet == 'VG4' or currentSet == 'VGO' or currentSet == 'VG ' : continue if currentSet == 'FVD' or currentSet == 'FVE' or currentSet == 'FVR' : continue if currentSet == 'SDC' or currentSet == 'AST' or currentSet == 'DKM' : continue - if currentSet == 'BTD' or currentSet == 'ARC' or currentSet == 'COM' : continue + if currentSet == 'BTD' or currentSet == 'COM' : continue #if currentSet == 'CHR' or currentSet == 'MED' or currentSet == 'H09' : continue if currentSet == 'ME2' or currentSet == 'ME3' or currentSet == 'ME4' : continue if currentSet == 'ATH' or currentSet == 'HOP' or currentSet == 'BRB' : continue @@ -132,4 +132,4 @@ with open(sys.path[0] + os.sep + "PerSetTrackingResults" + os.sep + "CompleteSta statsfile.write("\n") statsfile.write("Total over all sets: " + str(totalImplemented) + " (" + str(totalMissing) + ") / " + str(fullTotal)) -print "Done!" \ No newline at end of file +print "Done!" diff --git a/res/blockdata/setdata.txt b/res/blockdata/setdata.txt index 0b1d29c14fc..e8c6c545fed 100644 --- a/res/blockdata/setdata.txt +++ b/res/blockdata/setdata.txt @@ -91,4 +91,5 @@ Index:81|Code2:PC2|Code3:PC2|Name:Planechase 2012 Edition Index:82|Code2:M13|Code3:M13|Name:Magic 2013 Index:83|Code2:RTR|Code3:RTR|Name:Return to Ravnica -Index:86|Code2:VAN|Code3:VAN|Name:Vanguard \ No newline at end of file +Index:86|Code2:VAN|Code3:VAN|Name:Vanguard +Index:87|Code2:ARC|Code3:ARC|Name:Archenemy \ No newline at end of file diff --git a/res/cardsfolder/a/a_display_of_my_dark_power.txt b/res/cardsfolder/a/a_display_of_my_dark_power.txt new file mode 100644 index 00000000000..d1aad90ef57 --- /dev/null +++ b/res/cardsfolder/a/a_display_of_my_dark_power.txt @@ -0,0 +1,13 @@ +Name:A Display of My Dark Power +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ DarkEffect | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, until your next turn, whenever a player taps a land for mana, that player adds one mana to his or her mana pool of any type that land produced. +SVar:DarkEffect:AB$ Effect | Cost$ 0 | Name$ Dark Power Scheme | Duration$ UntilYourNextTurn | Triggers$ DarkPower | SVars$ DarkMana +SVar:DarkPower:Mode$ TapsForMana | ValidCard$ Land | Execute$ DarkMana | TriggerZones$ Command | Static$ True | TriggerDescription$ Whenever a player taps a land for mana, that player adds one mana to his or her mana pool of any type that land produced. +SVar:DarkMana:AB$ ManaReflected | Cost$ 0 | ColorOrType$ Type | Valid$ Defined.Triggered | ReflectProperty$ Produced | Defined$ TriggeredPlayer +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/a_display_of_my_dark_power.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/a-display-of-my-dark-power.jpg +Oracle:When you set this scheme in motion, until your next turn, whenever a player taps a land for mana, that player adds one mana to his or her mana pool of any type that land produced. +End \ No newline at end of file diff --git a/res/cardsfolder/a/academy_rector.txt b/res/cardsfolder/a/academy_rector.txt index 122c27b39c6..a41d695d242 100644 --- a/res/cardsfolder/a/academy_rector.txt +++ b/res/cardsfolder/a/academy_rector.txt @@ -4,8 +4,8 @@ Types:Creature Human Cleric Text:no text PT:1/2 T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigExile | OptionalDecider$ TriggeredCardController | TriggerController$ TriggeredCardController | TriggerDescription$ When CARDNAME dies, you may exile it. If you do, search your library for an enchantment card and put that card onto the battlefield. Then shuffle your library. -SVar:TrigExile:AB$ChangeZone | Cost$ 0 | Origin$ Graveyard | Destination$ Exile | ValidCard$ Card.Self | SubAbility$ DBReturn -SVar:DBReturn:DB$ChangeZone | Origin$ Library | Destination$ Battlefield | ChangeType$ Enchantment.YouOwn | ChangeNum$ 1 +SVar:TrigExile:AB$ ChangeZone | Cost$ 0 | Origin$ Graveyard | Destination$ Exile | ValidCard$ Card.Self | SubAbility$ DBReturn +SVar:DBReturn:DB$ ChangeZone | Origin$ Library | Destination$ Battlefield | ChangeType$ Enchantment.YouOwn | ChangeNum$ 1 SVar:SacMe:4 SVar:RemRandomDeck:True DeckNeeds:Type$Enchantment diff --git a/res/cardsfolder/a/all_shall_smolder_in_my_wake.txt b/res/cardsfolder/a/all_shall_smolder_in_my_wake.txt new file mode 100644 index 00000000000..b46cb2fb23d --- /dev/null +++ b/res/cardsfolder/a/all_shall_smolder_in_my_wake.txt @@ -0,0 +1,13 @@ +Name:All Shall Smolder in My Wake +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ Ignite | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, destroy up to one target artifact, up to one target enchantment, and up to one target nonbasic land. +SVar:Ignite:AB$ Destroy | Cost$ 0 | TargetMin$ 0 | TargetMax$ 1 | ValidTgts$ Artifact | TgtPrompt$ Select target artifact to destroy | SubAbility$ Burn +SVar:Burn:DB$ Destroy | TargetMin$ 0 | TargetMax$ 1 | ValidTgts$ Enchantment | TgtPrompt$ Select target enchantment to destroy | SubAbility$ Smolder +SVar:Smolder:DB$ Destroy | TargetMin$ 0 | TargetMax$ 1 | ValidTgts$ Land.nonBasic | TgtPrompt$ Select target nonbasic land to destroy +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/all_shall_smolder_in_my_wake.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/all-shall-smolder-in-my-wake.jpg +Oracle:When you set this scheme in motion, destroy up to one target artifact, up to one target enchantment, and up to one target nonbasic land. +End \ No newline at end of file diff --git a/res/cardsfolder/a/approach_my_molten_realm.txt b/res/cardsfolder/a/approach_my_molten_realm.txt new file mode 100644 index 00000000000..fd4620a0e7b --- /dev/null +++ b/res/cardsfolder/a/approach_my_molten_realm.txt @@ -0,0 +1,16 @@ +Name:Approach My Molten Realm +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ MoltenEffect | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, until your next turn, if a source would deal damage, it deals double that damage instead. +SVar:MoltenEffect:AB$ Effect | Cost$ 0 | Name$ Molten Realm Effect | ReplacementEffects$ MoltenRealm,MoltenRealmCombat | SVars$ DmgTimes2,DmgTimes2Combat,MoltenX | Duration$ UntilYourNextTurn +SVar:MoltenRealm:Event$ DamageDone | ActiveZones$ Command | ValidSource$ Card | ReplaceWith$ DmgTimes2 | IsCombat$ False | Description$ Until your next turn, if a source would deal damage, it deals double that damage instead. +SVar:MoltenRealmCombat:Event$ DamageDone | ActiveZones$ Command | ValidSource$ Card | ReplaceWith$ DmgTimes2Combat | IsCombat$ True | Secondary$ True | Description$ Until your next turn, if a source would deal damage, it deals double that damage instead. +SVar:DmgTimes2:AB$ DealDamage | Cost$ 0 | Defined$ ReplacedTarget | DamageSource$ ReplacedSource | NumDmg$ MoltenX | References$ MoltenX +SVar:DmgTimes2Combat:AB$ DealDamage | Cost$ 0 | CombatDamage$ True | Defined$ ReplacedTarget | DamageSource$ ReplacedSource | NumDmg$ MoltenX | References$ MoltenX +SVar:MoltenX:ReplaceCount$DamageAmount/Twice +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/approach_my_molten_realm.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/approach-my-molten-realm.jpg +Oracle:When you set this scheme in motion, until your next turn, if a source would deal damage, it deals double that damage instead. +End \ No newline at end of file diff --git a/res/cardsfolder/b/behold_the_power_of_destruction.txt b/res/cardsfolder/b/behold_the_power_of_destruction.txt new file mode 100644 index 00000000000..7b9176a13c4 --- /dev/null +++ b/res/cardsfolder/b/behold_the_power_of_destruction.txt @@ -0,0 +1,11 @@ +Name:Behold the Power of Destruction +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ DarkEffect | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, destroy all nonland permanents target opponent controls. +SVar:DarkEffect:AB$ DestroyAll | Cost$ 0 | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | ValidCards$ Permanent.nonLand +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/behold_the_power_of_destruction.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/behold-the-power-of-destruction.jpg +Oracle:When you set this scheme in motion, destroy all nonland permanents target opponent controls. +End \ No newline at end of file diff --git a/res/cardsfolder/d/dance_pathetic_marionette.txt b/res/cardsfolder/d/dance_pathetic_marionette.txt new file mode 100644 index 00000000000..59f9789ad0e --- /dev/null +++ b/res/cardsfolder/d/dance_pathetic_marionette.txt @@ -0,0 +1,14 @@ +Name:Dance, Pathetic Marionette +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ LibraryDance | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, each opponent reveals cards from the top of his or her library until he or she reveals a creature card. Choose one of the revealed creature cards and put it onto the battlefield under your control. Put all other cards revealed this way into their owners' graveyards. +SVar:LibraryDance:AB$ DigUntil | Cost$ 0 | Defined$ Player.Opponent | Valid$ Creature | ValidDescription$ creature | RememberFound$ True | NoMoveFound$ True | FoundDestination$ Library | FoundLibraryPosition$ 0 | RevealedDestination$ Graveyard | SubAbility$ MakeItDance +SVar:MakeItDance:DB$ ChangeZone | Defined$ Remembered | ChangeNum$ 1 | Origin$ Library | Destination$ Battlefield | Mandatory$ True | SelectPrompt$ Choose one of the revealed creature cards: | GainControl$ True | ForgetChanged$ True | SubAbility$ TakeOutTheTrash +SVar:TakeOutTheTrash:DB$ ChangeZoneAll | ChangeType$ Card.IsRemembered | Origin$ Library | Destination$ Graveyard | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/dance_pathetic_marionette.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/dance-pathetic-marionette.jpg +Oracle:When you set this scheme in motion, each opponent reveals cards from the top of his or her library until he or she reveals a creature card. Choose one of the revealed creature cards and put it onto the battlefield under your control. Put all other cards revealed this way into their owners' graveyards. +End \ No newline at end of file diff --git a/res/cardsfolder/e/embrace_my_diabolical_vision.txt b/res/cardsfolder/e/embrace_my_diabolical_vision.txt new file mode 100644 index 00000000000..cae8d6f7c3e --- /dev/null +++ b/res/cardsfolder/e/embrace_my_diabolical_vision.txt @@ -0,0 +1,14 @@ +Name:Embrace My Diabolical Vision +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ GraveEmbrace | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, each player shuffles his or her hand and graveyard into his or her library. You draw seven cards, then each other player draws four cards. +SVar:GraveEmbrace:AB$ ChangeZoneAll | Cost$ 0 | ChangeType$ Card | Origin$ Graveyard | Destination$ Library | Shuffle$ True | SubAbility$ EmbraceShuffle +SVar:EmbraceShuffle:DB$ ChangeZoneAll | ChangeType$ Card | Origin$ Hand | Destination$ Library | Shuffle$ True | SubAbility$ MyVision +SVar:MyVision:DB$ Draw | Defined$ You | NumCards$ 7 | SubAbility$ PitifulDraw +SVar:PitifulDraw:DB$ Draw | Defined$ Player.Other | NumCards$ 4 +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/embrace_my_diabolical_vision.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/embrace-my-diabolical-vision.jpg +Oracle:When you set this scheme in motion, each player shuffles his or her hand and graveyard into his or her library. You draw seven cards, then each other player draws four cards. +End \ No newline at end of file diff --git a/res/cardsfolder/e/every_hope_shall_vanish.txt b/res/cardsfolder/e/every_hope_shall_vanish.txt new file mode 100644 index 00000000000..89a37065a65 --- /dev/null +++ b/res/cardsfolder/e/every_hope_shall_vanish.txt @@ -0,0 +1,11 @@ +Name:Every Hope Shall Vanish +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ DiscardHope | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, each opponent reveals his or her hand. Choose a nonland card from each of those hands. Those players discard those cards. +SVar:DiscardHope:AB$ Discard | Cost$ 0 | Defined$ Player.Opponent | Mode$ RevealYouChoose | DiscardValid$ Card.nonLand | NumCards$ 1 +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/every_hope_shall_vanish.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/every-hope-shall-vanish.jpg +Oracle:When you set this scheme in motion, each opponent reveals his or her hand. Choose a nonland card from each of those hands. Those players discard those cards. +End \ No newline at end of file diff --git a/res/cardsfolder/e/every_last_vestige_shall_rot.txt b/res/cardsfolder/e/every_last_vestige_shall_rot.txt new file mode 100644 index 00000000000..499ebedc826 --- /dev/null +++ b/res/cardsfolder/e/every_last_vestige_shall_rot.txt @@ -0,0 +1,12 @@ +Name:Every Last Vestige Shall Rot +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ MoveToBottom | TriggerZones$ Command | OptionalDecider$ You | TriggerDescription$ When you set this scheme in motion, you may pay X. If you do, put each nonland permanent target player controls with converted mana cost X or less on the bottom of its owner's library. +SVar:MoveToBottom:AB$ ChangeZoneAll | Cost$ X | ChangeType$ Permanent.nonLand+cmcLEX | ValidTgts$ Player | TgtPrompt$ Select target player | Origin$ Battlefield | Destination$ Library | LibraryPosition$ -1 +SVar:X:Count$xPaid +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/every_last_vestige_shall_rot.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/every-last-vestige-shall-rot.jpg +Oracle:When you set this scheme in motion, you may pay {X}. If you do, put each nonland permanent target player controls with converted mana cost X or less on the bottom of its owner's library. +End \ No newline at end of file diff --git a/res/cardsfolder/e/evil_comes_to_fruition.txt b/res/cardsfolder/e/evil_comes_to_fruition.txt new file mode 100644 index 00000000000..3e5da088201 --- /dev/null +++ b/res/cardsfolder/e/evil_comes_to_fruition.txt @@ -0,0 +1,13 @@ +Name:Evil Comes to Fruition +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ NewEvil | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, put seven 0/1 green Plant creature tokens onto the battlefield. If you control ten or more lands, put seven 3/3 green Elemental creature tokens onto the battlefield instead. +SVar:NewEvil:AB$ Token | Cost$ 0 | TokenAmount$ 7 | TokenName$ Plant | TokenTypes$ Creature,Plant | TokenOwner$ You | TokenColors$ Green | TokenPower$ 0 | TokenToughness$ 1 | ConditionPresent$ Land.YouCtrl | ConditionCompare$ LT10 | SubAbility$ MatureEvil +SVar:MatureEvil:DB$ Token | Cost$ 0 | TokenAmount$ 7 | TokenName$ Elemental | TokenTypes$ Creature,Elemental | TokenOwner$ You | TokenColors$ Green | TokenPower$ 3 | TokenToughness$ 3 | ConditionPresent$ Land.YouCtrl | ConditionCompare$ GE10 +SVar:X:Count$NumTypeYouCtrl.Land +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/evil_comes_to_fruition.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/evil-comes-to-fruition.jpg +Oracle:When you set this scheme in motion, put seven 0/1 green Plant creature tokens onto the battlefield. If you control ten or more lands, put seven 3/3 green Elemental creature tokens onto the battlefield instead. +End \ No newline at end of file diff --git a/res/cardsfolder/i/i_call_on_the_ancient_magics.txt b/res/cardsfolder/i/i_call_on_the_ancient_magics.txt new file mode 100644 index 00000000000..00270d88f85 --- /dev/null +++ b/res/cardsfolder/i/i_call_on_the_ancient_magics.txt @@ -0,0 +1,12 @@ +Name:I Call on the Ancient Magics +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ OppTutor | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, each other player searches his or her library for a card, reveals it, and puts it into his or her hand. Then you search your library for two cards and put them into your hand. Each player shuffles his or her library. +SVar:OppTutor:AB$ ChangeZone | Cost$ 0 | DefinedPlayer$ Player.Other | Origin$ Library | Destination$ Hand | ChangeType$ Card | ChangeNum$ 1 | Reveal$ True | Mandatory$ True | SubAbility$ MyMagic +SVar:MyMagic:DB$ ChangeZone | DefinedPlayer$ You | Origin$ Library | Destination$ Hand | ChangeType$ Card | ChangeNum$ 2 | Mandatory$ True +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/i_call_on_the_ancient_magics.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/i-call-on-the-ancient-magics.jpg +Oracle:When you set this scheme in motion, each other player searches his or her library for a card, reveals it, and puts it into his or her hand. Then you search your library for two cards and put them into your hand. Each player shuffles his or her library. +End \ No newline at end of file diff --git a/res/cardsfolder/i/i_know_all_i_see_all.txt b/res/cardsfolder/i/i_know_all_i_see_all.txt new file mode 100644 index 00000000000..76e110dd61a --- /dev/null +++ b/res/cardsfolder/i/i_know_all_i_see_all.txt @@ -0,0 +1,13 @@ +Name:I Know All, I See All +ManaCost:no cost +Types:Ongoing Scheme +Text:no text +S:Mode$ Continuous | EffectZone$ Command | Affected$ Permanent.YouCtrl | AddHiddenKeyword$ CARDNAME untaps during each other player's untap step. | Description$ Untap all permanents you control during each other player's untap step. +T:Mode$ Phase | Phase$ End of Turn | Execute$ Abandon | TriggerZones$ Command | CheckSVar$ X | SVarCompare$ GE3 | TriggerDescription$ At the beginning of each end step, if three or more cards were put into your graveyard this turn from anywhere, abandon this scheme. +SVar:Abandon:AB$ Abandon | Cost$ 0 +SVar:X:Count$ThisTurnEntered_Graveyard_Card.YouOwn +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/i_know_all_i_see_all.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/i-know-all-i-see-all.jpg +Oracle:(An ongoing scheme remains face up until it's abandoned.)\nUntap all permanents you control during each opponent's untap step.\nAt the beginning of each end step, if three or more cards were put into your graveyard this turn from anywhere, abandon this scheme. +End \ No newline at end of file diff --git a/res/cardsfolder/i/ignite_the_cloneforge.txt b/res/cardsfolder/i/ignite_the_cloneforge.txt new file mode 100644 index 00000000000..874d639e47b --- /dev/null +++ b/res/cardsfolder/i/ignite_the_cloneforge.txt @@ -0,0 +1,11 @@ +Name:Ignite the Cloneforge! +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ DarkEffect | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, put a token onto the battlefield that's a copy of target permanent an opponent controls. +SVar:DarkEffect:AB$ CopyPermanent | Cost$ 0 | ValidTgts$ Permanent.OppCtrl | TgtPrompt$ Select target permanent an opponent controls +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/ignite_the_cloneforge.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/ignite-the-cloneforge.jpg +Oracle:When you set this scheme in motion, put a token onto the battlefield that's a copy of target permanent an opponent controls. +End \ No newline at end of file diff --git a/res/cardsfolder/i/imprison_this_insolent_wretch.txt b/res/cardsfolder/i/imprison_this_insolent_wretch.txt new file mode 100644 index 00000000000..b1e7b56e284 --- /dev/null +++ b/res/cardsfolder/i/imprison_this_insolent_wretch.txt @@ -0,0 +1,15 @@ +Name:Imprison This Insolent Wretch +ManaCost:no cost +Types:Ongoing Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ ChooseTheWretch | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, choose an opponent. +SVar:ChooseTheWretch:AB$ ChoosePlayer | Cost$ 0 | Defined$ You | Choices$ Opponent | AILogic$ Curse +S:Mode$ Continuous | EffectZone$ Command | Affected$ Permanent.ChosenCtrl | AffectedZone$ Battlefield | AddHiddenKeyword$ CARDNAME doesn't untap during your untap step. | Description$ Permanents the chosen player controls don't untap during his or her untap step. +T:Mode$ Attacks | ValidCard$ Card | Attacked$ Player.Chosen | Execute$ Abandon | TriggerZones$ Command | TriggerDescription$ When the chosen player is attacked or becomes the target of a spell or ability, abandon this scheme. +T:Mode$ SpellAbilityCast | TargetsValid$ Player.Chosen | TriggerZones$ Command | Execute$ Abandon | Secondary$ True | TriggerDescription$ When the chosen player is attacked or becomes the target of a spell or ability, abandon this scheme. +SVar:Abandon:AB$ Abandon | Cost$ 0 +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/imprison_this_insolent_wretch.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/imprison-this-insolent-wretch.jpg +Oracle:When you set this scheme in motion, choose an opponent.\nPermanents the chosen player controls don't untap during his or her untap step.\nWhen the chosen player is attacked or becomes the target of a spell or ability, abandon this scheme. +End \ No newline at end of file diff --git a/res/cardsfolder/k/kiki_jiki_mirror_breaker.txt b/res/cardsfolder/k/kiki_jiki_mirror_breaker.txt index 541cba55a3d..048182cc287 100644 --- a/res/cardsfolder/k/kiki_jiki_mirror_breaker.txt +++ b/res/cardsfolder/k/kiki_jiki_mirror_breaker.txt @@ -4,7 +4,7 @@ Types:Legendary Creature Goblin Shaman Text:no text PT:2/2 K:Haste -A:AB$CopyPermanent | Cost$ T | ValidTgts$ Creature.nonLegendary+YouCtrl | TgtPrompt$ Select target nonlegendary creature you control | Keywords$ Haste | AtEOT$ Sacrifice | SpellDescription$ Put a token that's a copy of target nonlegendary creature you control onto the battlefield. That token has haste. Sacrifice it at the beginning of the next end step. +A:AB$ CopyPermanent | Cost$ T | ValidTgts$ Creature.nonLegendary+YouCtrl | TgtPrompt$ Select target nonlegendary creature you control | Keywords$ Haste | AtEOT$ Sacrifice | SpellDescription$ Put a token that's a copy of target nonlegendary creature you control onto the battlefield. That token has haste. Sacrifice it at the beginning of the next end step. SVar:Rarity:Rare SVar:Picture:http://resources.wizards.com/magic/cards/chk/en-us/card50321.jpg SetInfo:CHK|Rare|http://magiccards.info/scans/en/chk/175.jpg diff --git a/res/cardsfolder/l/look_skyward_and_despair.txt b/res/cardsfolder/l/look_skyward_and_despair.txt new file mode 100644 index 00000000000..0e76ae8d33c --- /dev/null +++ b/res/cardsfolder/l/look_skyward_and_despair.txt @@ -0,0 +1,11 @@ +Name:Look Skyward and Despair +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ DarkEffect | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, put a 5/5 red Dragon creature token with flying onto the battlefield. +SVar:DarkEffect:AB$ Token | Cost$ 0 | TokenAmount$ 1 | TokenName$ Dragon | TokenTypes$ Creature,Dragon | TokenOwner$ You | TokenColors$ Red | TokenPower$ 5 | TokenToughness$ 5 | TokenKeywords$ Flying +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/look_skyward_and_despair.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/look-skyward-and-despair.jpg +Oracle:When you set this scheme in motion, put a 5/5 red Dragon creature token with flying onto the battlefield. +End \ No newline at end of file diff --git a/res/cardsfolder/m/mortal_flesh_is_weak.txt b/res/cardsfolder/m/mortal_flesh_is_weak.txt new file mode 100644 index 00000000000..ae360b8e644 --- /dev/null +++ b/res/cardsfolder/m/mortal_flesh_is_weak.txt @@ -0,0 +1,12 @@ +Name:Mortal Flesh Is Weak +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ ShowTheWeakness | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, each opponent's life total becomes the lowest life total among your opponents. +SVar:ShowTheWeakness:AB$ SetLife | Cost$ 0 | Defined$ Player.Opponent | LifeAmount$ X | References$ X +SVar:X:Count$LowestLifeTotal Opponent +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/mortal_flesh_is_weak.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/mortal-flesh-is-weak.jpg +Oracle:When you set this scheme in motion, each opponent's life total becomes the lowest life total among your opponents. +End \ No newline at end of file diff --git a/res/cardsfolder/m/my_genius_knows_no_bounds.txt b/res/cardsfolder/m/my_genius_knows_no_bounds.txt new file mode 100644 index 00000000000..f6ff450fced --- /dev/null +++ b/res/cardsfolder/m/my_genius_knows_no_bounds.txt @@ -0,0 +1,13 @@ +Name:My Genius Knows No Bounds +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ GeniusLife | TriggerZones$ Command | OptionalDecider$ You | TriggerDescription$ When you set this scheme in motion, you may pay X. If you do, you gain X life and draw X cards. +SVar:GeniusLife:AB$ GainLife | Cost$ X | Defined$ You | LifeAmount$ X | SubAbility$ GeniusCards +SVar:GeniusCards:DB$ Draw | Defined$ You | NumCards$ X +SVar:X:Count$xPaid +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/my_genius_knows_no_bounds.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/my-genius-knows-no-bounds.jpg +Oracle:When you set this scheme in motion, you may pay {X}. If you do, you gain X life and draw X cards. +End \ No newline at end of file diff --git a/res/cardsfolder/m/my_wish_is_your_command.txt b/res/cardsfolder/m/my_wish_is_your_command.txt new file mode 100644 index 00000000000..90b8072ea21 --- /dev/null +++ b/res/cardsfolder/m/my_wish_is_your_command.txt @@ -0,0 +1,13 @@ +Name:My Wish Is Your Command +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ MyWish | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, each opponent reveals his or her hand. You may choose a noncreature, nonland card revealed this way and cast it without paying its mana cost. +SVar:MyWish:AB$ RevealHand | Cost$ 0 | Defined$ Player.Opponent | RememberRevealed$ True | SubAbility$ MyPleasure +SVar:MyPleasure:DB$ Play | Valid$ Card.nonCreature+nonLand+IsRemembered | WithoutManaCost$ True | Optional$ True | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/my_wish_is_your_command.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/my-wish-is-your-command.jpg +Oracle:When you set this scheme in motion, each opponent reveals his or her hand. You may choose a noncreature, nonland card revealed this way and cast it without paying its mana cost. +End \ No newline at end of file diff --git a/res/cardsfolder/n/nothing_can_stop_me_now.txt b/res/cardsfolder/n/nothing_can_stop_me_now.txt new file mode 100644 index 00000000000..6cc163917a0 --- /dev/null +++ b/res/cardsfolder/n/nothing_can_stop_me_now.txt @@ -0,0 +1,13 @@ +Name:Nothing Can Stop Me Now +ManaCost:no cost +Types:Ongoing Scheme +Text:(An ongoing scheme remains face up until it's abandoned.) +S:Mode$ PreventDamage | EffectZone$ Command | Target$ You | Source$ Card.OppCtrl | Amount$ 1 | Description$ If a source an opponent controls would deal damage to you, prevent 1 of that damage. +T:Mode$ Phase | Phase$ End of Turn | CheckSVar$ X | SVarCompare$ GE5 | TriggerZones$ Command | Execute$ Abandon | TriggerDescription$ At the beginning of each end step, if you've been dealt 5 or more damage this turn, abandon this scheme. +SVar:Abandon:AB$ Abandon | Cost$ 0 +SVar:X:Count$YourDamageThisTurn +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/nothing_can_stop_me_now.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/nothing-can-stop-me-now.jpg +Oracle:(An ongoing scheme remains face up until it's abandoned.)\nIf a source an opponent controls would deal damage to you, prevent 1 of that damage.\nAt the beginning of each end step, if you've been dealt 5 or more damage this turn, abandon this scheme. +End \ No newline at end of file diff --git a/res/cardsfolder/p/perhaps_youve_met_my_cohort.txt b/res/cardsfolder/p/perhaps_youve_met_my_cohort.txt new file mode 100644 index 00000000000..8e210a3694c --- /dev/null +++ b/res/cardsfolder/p/perhaps_youve_met_my_cohort.txt @@ -0,0 +1,11 @@ +Name:Perhaps You've Met My Cohort +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ DarkEffect | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, search your library for a planeswalker card and put that card onto the battlefield, then shuffle your library. +SVar:DarkEffect:AB$ ChangeZone | Cost$ 0 | Origin$ Library | Destination$ Battlefield | ChangeType$ Planeswalker.YouOwn | ChangeNum$ 1 +SVar:Rarity:Rare +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/perhaps_youve_met_my_cohort.jpg +SetInfo:ARC|Rare|http://magiccards.info/extras/scheme/archenemy/perhaps-youve-met-my-cohort.jpg +Oracle:When you set this scheme in motion, search your library for a planeswalker card, put it onto the battlefield, then shuffle your library. +End \ No newline at end of file diff --git a/res/cardsfolder/p/plots-that-span-centuries.txt b/res/cardsfolder/p/plots-that-span-centuries.txt new file mode 100644 index 00000000000..8720bee72aa --- /dev/null +++ b/res/cardsfolder/p/plots-that-span-centuries.txt @@ -0,0 +1,14 @@ +Name:Plots That Span Centuries +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ PlotEffect | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, the next time you would set a scheme in motion, set three schemes in motion instead. +SVar:PlotEffect:AB$ Effect | Cost$ 0 | Name$ Plots Scheme | Duration$ Permanent | ReplacementEffects$ PlotPower | SVars$ PlotRep,ExilePlot +SVar:PlotPower:Event$ SetInMotion | ReplaceWith$ PlotRep | Description$ The next time you would set a scheme in motion, set three schemes in motion instead. +SVar:PlotRep:AB$ SetInMotion | Cost$ 0 | RepeatNum$ 3 | SubAbility$ ExilePlot +SVar:ExilePlot:DB$ ChangeZone | Cost$ 0 | Defined$ Self | Origin$ Command | Destination$ Exile +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/plots_that_span_centuries.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/plots-that-span-centuries.jpg +Oracle:When you set this scheme in motion, the next time you would set a scheme in motion, set three schemes in motion instead. +End \ No newline at end of file diff --git a/res/cardsfolder/r/realms_befitting_my_majesty.txt b/res/cardsfolder/r/realms_befitting_my_majesty.txt new file mode 100644 index 00000000000..390e52af8cb --- /dev/null +++ b/res/cardsfolder/r/realms_befitting_my_majesty.txt @@ -0,0 +1,11 @@ +Name:Realms Befitting My Majesty +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | ValidCard$ Card.Self | Execute$ GetRealms | TriggerZones$ Command | OptionalDecider$ You | TriggerDescription$ When you set this scheme in motion, search your library for up to two basic land cards, put them onto the battlefield tapped, then shuffle your library. +SVar:GetRealms:AB$ ChangeZone | Cost$ 0 | Origin$ Library | Destination$ Battlefield | Tapped$ True | ChangeType$ Land.Basic | ChangeNum$ 2 +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/realms_befitting_my_majesty.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/realms-befitting-my-majesty.jpg +Oracle:When you set this scheme in motion, search your library for up to two basic land cards, put them onto the battlefield tapped, then shuffle your library. +End \ No newline at end of file diff --git a/res/cardsfolder/r/repay_in_kind.txt b/res/cardsfolder/r/repay_in_kind.txt index 6cc28580814..037453c8c8e 100644 --- a/res/cardsfolder/r/repay_in_kind.txt +++ b/res/cardsfolder/r/repay_in_kind.txt @@ -2,7 +2,7 @@ Name:Repay in Kind ManaCost:5 B B Types:Sorcery Text:no text -A:SP$ SetLife | Cost$ 5 B B | Defined$ Each | LifeAmount$ X | References$ X | SpellDescription$ Each player's life total becomes the lowest life total among all players. +A:SP$ SetLife | Cost$ 5 B B | Defined$ Player | LifeAmount$ X | References$ X | SpellDescription$ Each player's life total becomes the lowest life total among all players. SVar:X:Count$LowestLifeTotal SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/repay_in_kind.jpg diff --git a/res/cardsfolder/r/roots_of_all_evil.txt b/res/cardsfolder/r/roots_of_all_evil.txt new file mode 100644 index 00000000000..5af85342a3a --- /dev/null +++ b/res/cardsfolder/r/roots_of_all_evil.txt @@ -0,0 +1,11 @@ +Name:Roots of All Evil +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ GetSaps | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, put five 1/1 green Saproling creature tokens onto the battlefield. +SVar:GetSaps:DB$ Token | Cost$ 0 | TokenAmount$ 5 | TokenName$ Saproling | TokenTypes$ Creature,Saproling | TokenOwner$ You | TokenColors$ Green | TokenPower$ 1 | TokenToughness$ 1 +SVar:Rarity:Common +SVar:Picture:http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=212602&type=card +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/roots-of-all-evil.jpg +Oracle:When you set this scheme in motion, put five 1/1 green Saproling creature tokens onto the battlefield. +End \ No newline at end of file diff --git a/res/cardsfolder/t/the_iron_guardian_stirs.txt b/res/cardsfolder/t/the_iron_guardian_stirs.txt new file mode 100644 index 00000000000..9d3a5012863 --- /dev/null +++ b/res/cardsfolder/t/the_iron_guardian_stirs.txt @@ -0,0 +1,11 @@ +Name:The Iron Guardian Stirs +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ DarkEffect | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, put a 4/6 colorless Golem creature token onto the battlefield. +SVar:DarkEffect:AB$ Token | Cost$ 0 | TokenAmount$ 1 | TokenName$ Golem | TokenTypes$ Artifact,Creature,Golem | TokenOwner$ You | TokenColors$ Colorless | TokenPower$ 4 | TokenToughness$ 6 +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/the_iron_guardian_stirs.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/the-iron-guardian-stirs.jpg +Oracle:When you set this scheme in motion, put a 4/6 colorless Golem artifact creature token onto the battlefield. +End \ No newline at end of file diff --git a/res/cardsfolder/t/the_pieces_are_coming_together.txt b/res/cardsfolder/t/the_pieces_are_coming_together.txt new file mode 100644 index 00000000000..1298851061d --- /dev/null +++ b/res/cardsfolder/t/the_pieces_are_coming_together.txt @@ -0,0 +1,12 @@ +Name:The Pieces Are Coming Together +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ ConstructDestiny | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, draw two cards. Artifact spells you cast this turn cost 2 less to cast. +SVar:ConstructDestiny:AB$ Effect | Cost$ 0 | Name$ Pieces Coming Together | StaticAbilities$ CheapParts +SVar:CheapParts:Mode$ ReduceCost | EffectZone$ Command | ValidCard$ Artifact | Type$ Spell | Activator$ You | Amount$ 2 | Description$ Artifact spells you cast this turn cost 2 less to cast. +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/the_pieces_are_coming_together.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/the-pieces-are-coming-together.jpg +Oracle:When you set this scheme in motion, draw two cards. Artifact spells you cast this turn cost {2} less to cast. +End \ No newline at end of file diff --git a/res/cardsfolder/t/the_very_soil_shall_shake.txt b/res/cardsfolder/t/the_very_soil_shall_shake.txt new file mode 100644 index 00000000000..0cf5aa703a1 --- /dev/null +++ b/res/cardsfolder/t/the_very_soil_shall_shake.txt @@ -0,0 +1,12 @@ +Name:The Very Soil Shall Shake +ManaCost:no cost +Types:Ongoing Scheme +Text:no text +S:Mode$ Continuous | Affected$ Creature.YouCtrl | EffectZone$ Command | AddPower$ 2 | AddToughness$ 2 | AddKeyword$ Trample | Description$ Creatures you control get +2/+2 and have trample. +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.YouCtrl | Execute$ Abandon | TriggerDescription$ When a creature you control dies, abandon this scheme. +SVar:Abandon:AB$ Abandon | Cost$ 0 +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/the_very_soil_shall_shake.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/the-very-soil-shall-shake.jpg +Oracle:(An ongoing scheme remains face up until it's abandoned.)\nCreatures you control get +2/+2 and have trample.\nWhen a creature you control dies, abandon this scheme. +End \ No newline at end of file diff --git a/res/cardsfolder/t/tooth_claw_and_tail.txt b/res/cardsfolder/t/tooth_claw_and_tail.txt new file mode 100644 index 00000000000..2dd5279b567 --- /dev/null +++ b/res/cardsfolder/t/tooth_claw_and_tail.txt @@ -0,0 +1,11 @@ +Name:Tooth, Claw, and Tail +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | Execute$ DarkEffect | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, destroy up to three target nonland permanents. +SVar:DarkEffect:AB$ Destroy | Cost$ 0 | TargetMin$ 0 | TargetMax$ 3 | ValidTgts$ Permanent.nonLand | TgtPrompt$ Select target nonland permanent +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/tooth_claw_and_tail.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/tooth-claw-and-tail.jpg +Oracle:When you set this scheme in motion, destroy up to three target nonland permanents. +End \ No newline at end of file diff --git a/res/cardsfolder/w/which_of_you_burns_brightest.txt b/res/cardsfolder/w/which_of_you_burns_brightest.txt new file mode 100644 index 00000000000..2a7c265e4a7 --- /dev/null +++ b/res/cardsfolder/w/which_of_you_burns_brightest.txt @@ -0,0 +1,12 @@ +Name:Which of You Burns Brightest? +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ DarkEffect | TriggerZones$ Command | OptionalDecider$ You | TriggerDescription$ When you set this scheme in motion, you may pay X. If you do, this scheme deals X damage to target opponent and each creature he or she controls. +SVar:DarkEffect:AB$ DamageAll | Cost$ X | NumDmg$ X | ValidTgts$ Player | TgtPrompt$ Select a player | ValidCards$ Creature | ValidPlayers$ Targeted | ValidDescription$ target player and each creature he or she controls. | References$ X +SVar:X:Count$xPaid +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/which_of_you_burns_brightest.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/which-of-you-burns-brightest.jpg +Oracle:When you set this scheme in motion, you may pay {X}. If you do, this scheme deals X damage to target opponent and each creature he or she controls. +End \ No newline at end of file diff --git a/res/cardsfolder/y/your_fate_is_thrice_sealed.txt b/res/cardsfolder/y/your_fate_is_thrice_sealed.txt new file mode 100644 index 00000000000..3d8771c983d --- /dev/null +++ b/res/cardsfolder/y/your_fate_is_thrice_sealed.txt @@ -0,0 +1,11 @@ +Name:Your Fate Is Thrice Sealed +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ RevealFate | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, reveal the top three cards of your library. Put all land cards revealed this way onto the battlefield and the rest into your hand. +SVar:RevealFate:AB$ Dig | Cost$ 0 | DigNum$ 3 | Reveal$ True | ChangeNum$ All | ChangeValid$ Land | DestinationZone$ Battlefield | DestinationZone2$ Hand | +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/your_fate_is_thrice_sealed.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/your-fate-is-thrice-sealed.jpg +Oracle:When you set this scheme in motion, reveal the top three cards of your library. Put all land cards revealed this way onto the battlefield and the rest into your hand. +End \ No newline at end of file diff --git a/res/cardsfolder/y/your_puny_minds_cannot_fathom.txt b/res/cardsfolder/y/your_puny_minds_cannot_fathom.txt new file mode 100644 index 00000000000..5d09ff37a3a --- /dev/null +++ b/res/cardsfolder/y/your_puny_minds_cannot_fathom.txt @@ -0,0 +1,13 @@ +Name:Your Puny Minds Cannot Fathom +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ GreatMind | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, draw four cards. You have no maximum hand size until your next turn. +SVar:GreatMind:AB$ Draw | Cost$ 0 | Defined$ You | NumCards$ 4 | SubAbility$ Unfathomable +SVar:Unfathomable:DB$ Effect | Name$ Unfathomable Mind Effect | StaticAbilities$ STHandSize | Duration$ UntilYourNextTurn +SVar:STHandSize:Mode$ Continuous | EffectZone$ Command | Affected$ You | SetMaxHandSize$ Unlimited | Description$ You have no maximum hand size. +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/your_puny_minds_cannot_fathom.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/your-puny-minds-cannot-fathom.jpg +Oracle:When you set this scheme in motion, draw four cards. You have no maximum hand size until your next turn. +End \ No newline at end of file diff --git a/res/cardsfolder/y/your_will_is_not_your_own.txt b/res/cardsfolder/y/your_will_is_not_your_own.txt new file mode 100644 index 00000000000..b0f46e4cb56 --- /dev/null +++ b/res/cardsfolder/y/your_will_is_not_your_own.txt @@ -0,0 +1,12 @@ +Name:Your Will Is Not Your Own +ManaCost:no cost +Types:Scheme +Text:no text +T:Mode$ SetInMotion | Execute$ DarkEffect | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, gain control of target creature an opponent controls until end of turn. Untap that creature. It gets +3/+3 and gains haste and trample until end of turn. +SVar:DarkEffect:AB$ GainControl | Cost$ 0 | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature an opponent controls | Untap$ True | LoseControl$ EOT | SubAbility$ DBPump +SVar:DBPump:DB$ Pump | Defined$ Targeted | NumAtt$ +3 | NumDef$ +3 | KW$ Haste & Trample +SVar:Rarity:Common +SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/your_will_is_not_your_own.jpg +SetInfo:ARC|Common|http://magiccards.info/extras/scheme/archenemy/your-will-is-not-your-own.jpg +Oracle:When you set this scheme in motion, gain control of target creature an opponent controls until end of turn. Untap that creature. It gets +3/+3 and gains haste and trample until end of turn. +End \ No newline at end of file diff --git a/src/main/java/forge/Card.java b/src/main/java/forge/Card.java index 8c1b88dd201..8874d1d7b19 100644 --- a/src/main/java/forge/Card.java +++ b/src/main/java/forge/Card.java @@ -5430,6 +5430,10 @@ public class Card extends GameEntity implements Comparable { public final boolean isEquipment() { return this.typeContains("Equipment"); } + + public final boolean isScheme() { + return this.typeContains("Scheme"); + } /** *

diff --git a/src/main/java/forge/GameAction.java b/src/main/java/forge/GameAction.java index 74678fa616f..3b6df5e713d 100644 --- a/src/main/java/forge/GameAction.java +++ b/src/main/java/forge/GameAction.java @@ -46,6 +46,7 @@ import forge.card.spellability.AbilityStatic; import forge.card.spellability.Spell; import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbilityRequirements; +import forge.card.spellability.SpellAbilityStackInstance; import forge.card.spellability.Target; import forge.card.spellability.TargetSelection; import forge.card.staticability.StaticAbility; @@ -1063,6 +1064,7 @@ public class GameAction { } } } // if isEquipped() + if (c.isEquipping()) { final Card equippedCreature = c.getEquipping().get(0); diff --git a/src/main/java/forge/card/CardType.java b/src/main/java/forge/card/CardType.java index 389cf0d41b5..b391da45eac 100644 --- a/src/main/java/forge/card/CardType.java +++ b/src/main/java/forge/card/CardType.java @@ -212,6 +212,15 @@ public final class CardType implements Comparable { public boolean isVanguard() { return this.coreType.contains(CardCoreType.Vanguard); } + + /** + * Checks if is scheme. + * + * @return true if scheme + */ + public boolean isScheme() { + return this.coreType.contains(CardCoreType.Scheme); + } /** * Checks if is enchantment. diff --git a/src/main/java/forge/card/abilityfactory/ApiType.java b/src/main/java/forge/card/abilityfactory/ApiType.java index 47ffbcf2e4c..37ff2b0ffc5 100644 --- a/src/main/java/forge/card/abilityfactory/ApiType.java +++ b/src/main/java/forge/card/abilityfactory/ApiType.java @@ -10,6 +10,7 @@ import forge.card.abilityfactory.effects.*; */ public enum ApiType { + Abandon (AbandonEffect.class, AlwaysPlayAi.class), AddTurn (AddTurnEffect.class, AddTurnAi.class), Animate (AnimateEffect.class, AnimateAi.class), AnimateAll (AnimateAllEffect.class, AnimateAllAi.class), @@ -91,6 +92,7 @@ public enum ApiType { Sacrifice (SacrificeEffect.class, SacrificeAi.class), SacrificeAll (SacrificeAllEffect.class, SacrificeAllAi.class), Scry (ScryEffect.class, ScryAi.class), + SetInMotion (SetInMotionEffect.class, AlwaysPlayAi.class), SetLife (LifeSetEffect.class, LifeSetAi.class), SetState (SetStateEffect.class, SetStateAi.class), SetStateAll (SetStateAllEffect.class, SetStateAllAi.class), diff --git a/src/main/java/forge/card/abilityfactory/ai/ChangeZoneAi.java b/src/main/java/forge/card/abilityfactory/ai/ChangeZoneAi.java index 82bed67e943..04db4181252 100644 --- a/src/main/java/forge/card/abilityfactory/ai/ChangeZoneAi.java +++ b/src/main/java/forge/card/abilityfactory/ai/ChangeZoneAi.java @@ -1310,8 +1310,9 @@ public class ChangeZoneAi extends SpellAiLogic { player.shuffle(); } - if (!ZoneType.Battlefield.equals(destination) && !"Card".equals(type) && !defined) { - final String picked = sa.getSourceCard().getName() + " - Computer picked:"; + if ((!ZoneType.Battlefield.equals(destination) && !"Card".equals(type) && !defined) + || (sa.hasParam("Reveal") && !fetched.isEmpty())) { + final String picked = player + " picked:"; if (fetched.size() > 0) { GuiChoose.one(picked, fetched); } else { diff --git a/src/main/java/forge/card/abilityfactory/effects/AbandonEffect.java b/src/main/java/forge/card/abilityfactory/effects/AbandonEffect.java new file mode 100644 index 00000000000..9ae61489c40 --- /dev/null +++ b/src/main/java/forge/card/abilityfactory/effects/AbandonEffect.java @@ -0,0 +1,33 @@ +package forge.card.abilityfactory.effects; + + +import forge.Card; +import forge.Singletons; +import forge.card.abilityfactory.AbilityFactory; +import forge.card.abilityfactory.SpellEffect; +import forge.card.spellability.SpellAbility; +import forge.card.trigger.TriggerType; +import forge.game.GameState; +import forge.game.player.Player; +import forge.game.zone.ZoneType; + +public class AbandonEffect extends SpellEffect { + + private GameState game = Singletons.getModel().getGame(); + + /* (non-Javadoc) + * @see forge.card.abilityfactory.SpellEffect#resolve(java.util.Map, forge.card.spellability.SpellAbility) + */ + @Override + public void resolve(SpellAbility sa) { + Card source = sa.getSourceCard(); + Player controller = source.getController(); + + game.getTriggerHandler().suppressMode(TriggerType.ChangesZone); + controller.getZone(ZoneType.Command).remove(source); + game.getTriggerHandler().clearSuppression(TriggerType.ChangesZone); + + controller.getSchemeDeck().add(source); + } + +} diff --git a/src/main/java/forge/card/abilityfactory/effects/ChangeZoneAllEffect.java b/src/main/java/forge/card/abilityfactory/effects/ChangeZoneAllEffect.java index e7b22238aa4..2cce3f5bfd3 100644 --- a/src/main/java/forge/card/abilityfactory/effects/ChangeZoneAllEffect.java +++ b/src/main/java/forge/card/abilityfactory/effects/ChangeZoneAllEffect.java @@ -65,7 +65,8 @@ public class ChangeZoneAllEffect extends SpellEffect { final int libraryPos = sa.hasParam("LibraryPosition") ? Integer.parseInt(sa.getParam("LibraryPosition")) : 0; - if (sa.getActivatingPlayer().isHuman() && destination.equals(ZoneType.Library) && !sa.hasParam("Shuffle")) { + if (sa.getActivatingPlayer().isHuman() && destination.equals(ZoneType.Library) && !sa.hasParam("Shuffle") + && cards.size() >= 2) { cards = GuiChoose.getOrderChoices("Choose order of cards to put into the library", "Put first", 0, cards, null, null); } diff --git a/src/main/java/forge/card/abilityfactory/effects/DigUntilEffect.java b/src/main/java/forge/card/abilityfactory/effects/DigUntilEffect.java index 8a6a99835ee..84faafcefaf 100644 --- a/src/main/java/forge/card/abilityfactory/effects/DigUntilEffect.java +++ b/src/main/java/forge/card/abilityfactory/effects/DigUntilEffect.java @@ -133,6 +133,8 @@ public class DigUntilEffect extends SpellEffect { if (sa.hasParam("GainControl") && foundDest.equals(ZoneType.Battlefield)) { c.addController(sa.getSourceCard()); Singletons.getModel().getGame().getAction().moveTo(c.getController().getZone(foundDest), c); + } else if (sa.hasParam("NoMoveFound") && foundDest.equals(ZoneType.Library)) { + //Don't do anything } else { Singletons.getModel().getGame().getAction().moveTo(foundDest, c, foundLibPos); } diff --git a/src/main/java/forge/card/abilityfactory/effects/SetInMotionEffect.java b/src/main/java/forge/card/abilityfactory/effects/SetInMotionEffect.java new file mode 100644 index 00000000000..1ab83aab5f0 --- /dev/null +++ b/src/main/java/forge/card/abilityfactory/effects/SetInMotionEffect.java @@ -0,0 +1,38 @@ +package forge.card.abilityfactory.effects; + + +import forge.Card; +import forge.Singletons; +import forge.card.abilityfactory.AbilityFactory; +import forge.card.abilityfactory.SpellEffect; +import forge.card.spellability.SpellAbility; +import forge.card.trigger.TriggerType; +import forge.game.GameState; +import forge.game.player.Player; +import forge.game.zone.ZoneType; + +public class SetInMotionEffect extends SpellEffect { + + /* (non-Javadoc) + * @see forge.card.abilityfactory.SpellEffect#resolve(java.util.Map, forge.card.spellability.SpellAbility) + */ + @Override + public void resolve(SpellAbility sa) { + System.out.println("AF_SIM"); + Card source = sa.getSourceCard(); + Player controller = source.getController(); + + int repeats = 1; + + if(sa.hasParam("RepeatNum")) + { + repeats = AbilityFactory.calculateAmount(sa.getSourceCard(), sa.getParam("RepeatNum"), sa); + } + + for(int i=0;i 1 && playerType[1].equals("Opponent")) { + return CardFactoryUtil.doXMath( + Aggregates.min(cardController.getOpponents(), Player.Accessors.FN_GET_LIFE), m, c); + } else { + return CardFactoryUtil.doXMath( + Aggregates.min(Singletons.getModel().getGame().getPlayers(), Player.Accessors.FN_GET_LIFE), m, c); + } } // Count$TopOfLibraryCMC diff --git a/src/main/java/forge/card/replacement/ReplaceSetInMotion.java b/src/main/java/forge/card/replacement/ReplaceSetInMotion.java new file mode 100644 index 00000000000..19ac3f4f57f --- /dev/null +++ b/src/main/java/forge/card/replacement/ReplaceSetInMotion.java @@ -0,0 +1,69 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.card.replacement; + +import java.util.HashMap; + +import forge.Card; + +/** + * TODO: Write javadoc for this type. + * + */ +public class ReplaceSetInMotion extends ReplacementEffect { + + /** + * Instantiates a new replace draw. + * + * @param params the params + * @param host the host + */ + public ReplaceSetInMotion(final HashMap params, final Card host) { + super(params, host); + } + + /* (non-Javadoc) + * @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap) + */ + @Override + public boolean canReplace(HashMap runParams) { + if (!runParams.get("Event").equals("SetInMotion")) { + return false; + } + if (this.getMapParams().containsKey("ValidPlayer")) { + if (!matchesValid(runParams.get("Affected"), this.getMapParams().get("ValidPlayer").split(","), this.getHostCard())) { + return false; + } + } + + return true; + } + + /* (non-Javadoc) + * @see forge.card.replacement.ReplacementEffect#getCopy() + */ + @Override + public ReplacementEffect getCopy() { + ReplacementEffect res = new ReplaceSetInMotion(this.getMapParams(), this.getHostCard()); + res.setOverridingAbility(this.getOverridingAbility()); + res.setActiveZone(validHostZones); + res.setLayer(getLayer()); + return res; + } + +} diff --git a/src/main/java/forge/card/replacement/ReplacementHandler.java b/src/main/java/forge/card/replacement/ReplacementHandler.java index 74392609d6a..8bfe7af3c5b 100644 --- a/src/main/java/forge/card/replacement/ReplacementHandler.java +++ b/src/main/java/forge/card/replacement/ReplacementHandler.java @@ -282,6 +282,8 @@ public class ReplacementHandler { ret = new ReplaceGameLoss(mapParams, host); } else if (eventToReplace.equals("Moved")) { ret = new ReplaceMoved(mapParams, host); + } else if (eventToReplace.equals("SetInMotion")) { + ret = new ReplaceSetInMotion(mapParams, host); } String activeZones = mapParams.get("ActiveZones"); diff --git a/src/main/java/forge/card/trigger/TriggerSetInMotion.java b/src/main/java/forge/card/trigger/TriggerSetInMotion.java new file mode 100644 index 00000000000..a0df64e8f07 --- /dev/null +++ b/src/main/java/forge/card/trigger/TriggerSetInMotion.java @@ -0,0 +1,79 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.card.trigger; + +import forge.Card; +import forge.card.spellability.SpellAbility; + +/** + *

+ * Trigger_LifeGained class. + *

+ * + * @author Forge + * @version $Id: TriggerLifeGained.java 17802 2012-10-31 08:05:14Z Max mtg $ + */ +public class TriggerSetInMotion extends Trigger { + + /** + *

+ * Constructor for Trigger_LifeGained. + *

+ * + * @param params + * a {@link java.util.HashMap} object. + * @param host + * a {@link forge.Card} object. + * @param intrinsic + * the intrinsic + */ + public TriggerSetInMotion(final java.util.Map params, final Card host, final boolean intrinsic) { + super(params, host, intrinsic); + } + + /** {@inheritDoc} */ + @Override + public final boolean performTest(final java.util.Map runParams2) { + if (this.getMapParams().containsKey("ValidCard")) { + if (!matchesValid(runParams2.get("Scheme"), this.getMapParams().get("ValidCard").split(","), + this.getHostCard())) { + return false; + } + } + + return true; + } + + /** {@inheritDoc} */ + @Override + public final Trigger getCopy() { + final Trigger copy = new TriggerSetInMotion(this.getMapParams(), this.getHostCard(), this.isIntrinsic()); + if (this.getOverridingAbility() != null) { + copy.setOverridingAbility(this.getOverridingAbility()); + } + + copyFieldsTo(copy); + return copy; + } + + /** {@inheritDoc} */ + @Override + public final void setTriggeringObjects(final SpellAbility sa) { + sa.setTriggeringObject("Scheme", this.getRunParams().get("Scheme")); + } +} diff --git a/src/main/java/forge/card/trigger/TriggerType.java b/src/main/java/forge/card/trigger/TriggerType.java index b74a680d6cf..70edd795529 100644 --- a/src/main/java/forge/card/trigger/TriggerType.java +++ b/src/main/java/forge/card/trigger/TriggerType.java @@ -47,7 +47,8 @@ public enum TriggerType { Discarded(TriggerDiscarded.class), Shuffled(TriggerShuffled.class), LandPlayed(TriggerLandPlayed.class), - LosesGame(TriggerLosesGame.class); + LosesGame(TriggerLosesGame.class), + SetInMotion(TriggerSetInMotion.class); private final Class classTrigger; private TriggerType(Class clasz) { diff --git a/src/main/java/forge/deck/Deck.java b/src/main/java/forge/deck/Deck.java index 65282633cec..db5bf874361 100644 --- a/src/main/java/forge/deck/Deck.java +++ b/src/main/java/forge/deck/Deck.java @@ -154,6 +154,7 @@ public class Deck extends DeckBase { result.sideboard.addAll(this.sideboard); result.avatar = this.avatar; result.commander = this.commander; + result.schemes.addAll(this.schemes); } /* diff --git a/src/main/java/forge/deck/DeckgenUtil.java b/src/main/java/forge/deck/DeckgenUtil.java index 21c189ab189..c24cdc26816 100644 --- a/src/main/java/forge/deck/DeckgenUtil.java +++ b/src/main/java/forge/deck/DeckgenUtil.java @@ -16,17 +16,22 @@ import javax.swing.JOptionPane; import org.apache.commons.lang3.ArrayUtils; +import com.google.common.collect.Iterables; + import forge.Singletons; import forge.deck.generate.Generate2ColorDeck; import forge.deck.generate.Generate3ColorDeck; import forge.deck.generate.Generate5ColorDeck; import forge.deck.generate.GenerateThemeDeck; import forge.game.player.PlayerType; +import forge.item.CardDb; import forge.item.CardPrinted; +import forge.item.ItemPool; import forge.item.ItemPoolView; import forge.quest.QuestEvent; import forge.quest.QuestEventManager; import forge.util.IStorage; +import forge.util.MyRandom; /** * Utility collection for various types of decks. @@ -302,4 +307,32 @@ public class DeckgenUtil { } return result; } + + public static Deck generateSchemeDeck() { + Deck res = new Deck(); + + Iterable allSchemes = Iterables.filter(CardDb.instance().getAllNonTraditionalCards(),CardPrinted.Predicates.type("Scheme")); + + for(int i=0;i<20;i++) { + CardPrinted cp = Iterables.get(allSchemes, MyRandom.getRandom().nextInt(Iterables.size(allSchemes))); + int appearances = 0; + for(CardPrinted added : res.getSchemes().toFlatList()) { + if(added.getName().equals(cp.getName())) + { + appearances++; + } + } + + if(appearances < 2) + { + res.getSchemes().add(cp); + } + else + { + i--; + } + } + + return res; + } } diff --git a/src/main/java/forge/game/GameNew.java b/src/main/java/forge/game/GameNew.java index d8edfb932ed..37ab5f6529b 100644 --- a/src/main/java/forge/game/GameNew.java +++ b/src/main/java/forge/game/GameNew.java @@ -144,10 +144,17 @@ public class GameNew { if (inCommand != null) { for (final Card c : inCommand) { c.setOwner(player); + com.add(c, false); c.refreshUniqueNumber(); } } + + Iterable schemes = p.getValue().getSchemes(); + if(schemes != null) { + player.setSchemeDeck(schemes); + } + prepareSingleLibrary(player, p.getValue().getDeck(), removedAnteCards, rAICards, canRandomFoil); player.updateObservers(); diff --git a/src/main/java/forge/game/MatchStartHelper.java b/src/main/java/forge/game/MatchStartHelper.java index 9b6943f9e10..9d6d3754db4 100644 --- a/src/main/java/forge/game/MatchStartHelper.java +++ b/src/main/java/forge/game/MatchStartHelper.java @@ -49,6 +49,29 @@ public class MatchStartHelper { players.put(player, start); } + + public void addArchenemy(final LobbyPlayer player, final Deck deck, final Iterable schemes) { + PlayerStartConditions start = new PlayerStartConditions(deck); + + start.setStartingLife(40); + + start.setSchemes(new Supplier>() { + + @Override + public Iterable get() { + List res = new ArrayList(); + for(CardPrinted cp : schemes) + { + res.add(cp.toForgeCard()); + } + + return res; + } + + }); + + players.put(player, start); + } public Map getPlayerMap() { diff --git a/src/main/java/forge/game/PlayerStartConditions.java b/src/main/java/forge/game/PlayerStartConditions.java index a7f225dea3e..57e4964fbdd 100644 --- a/src/main/java/forge/game/PlayerStartConditions.java +++ b/src/main/java/forge/game/PlayerStartConditions.java @@ -14,6 +14,7 @@ public class PlayerStartConditions { private int startingHand = 7; private Supplier> cardsOnBattlefield = null; private Supplier> cardsInCommand = null; + private Supplier> schemes = null; public PlayerStartConditions(Deck deck0) { deck = deck0; @@ -65,5 +66,19 @@ public class PlayerStartConditions { this.cardsInCommand = cardsInCommand0; } + /** + * @return the schemes + */ + public Iterable getSchemes() { + return schemes == null ? null : schemes.get(); + } + + /** + * @param schemes0 the schemes to set + */ + public void setSchemes(Supplier> s) { + this.schemes = s; + } + } diff --git a/src/main/java/forge/game/phase/PhaseHandler.java b/src/main/java/forge/game/phase/PhaseHandler.java index 8dcc04c4d2b..7182bcf4000 100644 --- a/src/main/java/forge/game/phase/PhaseHandler.java +++ b/src/main/java/forge/game/phase/PhaseHandler.java @@ -27,6 +27,7 @@ import forge.Card; import forge.CardLists; import forge.CardPredicates; import forge.Singletons; +import forge.card.spellability.SpellAbilityStackInstance; import forge.card.trigger.TriggerType; import forge.game.GameState; import forge.game.event.EndOfTurnEvent; @@ -269,6 +270,11 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { this.getPlayerTurn().drawCards(1, true); } break; + + case MAIN1: + if(this.getPlayerTurn().isArchenemy()) + this.getPlayerTurn().setSchemeInMotion(); + break; case COMBAT_BEGIN: //PhaseUtil.verifyCombat(); @@ -711,6 +717,36 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { if (game.isGameOver()) { return; } + + //904.10. If a non-ongoing scheme card is face up in the + //command zone, and it isn't the source of a triggered ability + //that has triggered but not yet left the stack, that scheme card + //is turned face down and put on the bottom of its owner's scheme + //deck the next time a player would receive priority. + //(This is a state-based action. See rule 704.) + for (int i=0; i { private final Map zones = new EnumMap(ZoneType.class); private PlayerStatistics stats = new PlayerStatistics(); + + private final List schemeDeck = new ArrayList(); + private Card activeScheme = null; /** The Constant ALL_ZONES. */ public static final List ALL_ZONES = Collections.unmodifiableList(Arrays.asList(ZoneType.Battlefield, @@ -205,6 +208,55 @@ public abstract class Player extends GameEntity implements Comparable { //@Deprecated public abstract boolean isComputer(); public abstract PlayerType getType(); + + public List getSchemeDeck() + { + return schemeDeck; + } + + public void setSchemeDeck(Iterable sd) + { + schemeDeck.clear(); + for(Card c : sd) + { + schemeDeck.add(c); + c.setOwner(this); + } + CardLists.shuffle(schemeDeck); + } + + public boolean isArchenemy() + { + //Only the archenemy has schemes. + return schemeDeck.size() > 0; + } + + public void setSchemeInMotion() + { + // Replacement effects + final HashMap repRunParams = new HashMap(); + repRunParams.put("Event", "SetInMotion"); + repRunParams.put("Affected", this); + + if (game.getReplacementHandler().run(repRunParams) != ReplacementResult.NotReplaced) { + return; + } + + game.getTriggerHandler().suppressMode(TriggerType.ChangesZone); + + activeScheme = schemeDeck.get(0); + + schemeDeck.remove(0); + + this.getZone(ZoneType.Command).add(activeScheme); + + game.getTriggerHandler().clearSuppression(TriggerType.ChangesZone); + + // Run triggers + final HashMap runParams = new HashMap(); + runParams.put("Scheme", activeScheme); + game.getTriggerHandler().runTrigger(TriggerType.SetInMotion, runParams); + } /** *

diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorScheme.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorScheme.java new file mode 100644 index 00000000000..f5304c7a307 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorScheme.java @@ -0,0 +1,164 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.gui.deckeditor.controllers; + +import java.util.List; + +import com.google.common.base.Supplier; +import com.google.common.collect.Iterables; + +import forge.Singletons; +import forge.deck.Deck; +import forge.gui.deckeditor.SEditorIO; +import forge.gui.deckeditor.SEditorUtil; +import forge.gui.deckeditor.tables.DeckController; +import forge.gui.deckeditor.tables.SColumnUtil; +import forge.gui.deckeditor.tables.SColumnUtil.ColumnName; +import forge.gui.deckeditor.tables.TableColumnInfo; +import forge.gui.deckeditor.tables.EditorTableView; +import forge.gui.deckeditor.views.VCardCatalog; +import forge.gui.deckeditor.views.VCurrentDeck; +import forge.gui.framework.EDocID; +import forge.item.CardDb; +import forge.item.CardPrinted; +import forge.item.InventoryItem; +import forge.item.ItemPool; +import forge.properties.ForgePreferences.FPref; + +/** + * Child controller for constructed deck editor UI. + * This is the least restrictive mode; + * all cards are available. + * + *

(C at beginning of class name denotes a control class.) + * + * @author Forge + * @version $Id: CEditorConstructed.java 18430 2012-11-27 22:42:36Z Hellfish $ + */ +public final class CEditorScheme extends ACEditorBase { + private final DeckController controller; + + //=========== Constructor + /** + * Child controller for constructed deck editor UI. + * This is the least restrictive mode; + * all cards are available. + */ + public CEditorScheme() { + super(); + + final EditorTableView tblCatalog = new EditorTableView(true, CardPrinted.class); + final EditorTableView tblDeck = new EditorTableView(true, CardPrinted.class); + + VCardCatalog.SINGLETON_INSTANCE.setTableView(tblCatalog.getTable()); + VCurrentDeck.SINGLETON_INSTANCE.setTableView(tblDeck.getTable()); + + this.setTableCatalog(tblCatalog); + this.setTableDeck(tblDeck); + + final Supplier newCreator = new Supplier() { + @Override + public Deck get() { + return new Deck(); + } + }; + this.controller = new DeckController(Singletons.getModel().getDecks().getScheme(), this, newCreator); + } + + //=========== Overridden from ACEditorBase + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#addCard() + */ + @Override + public void addCard() { + final InventoryItem item = this.getTableCatalog().getSelectedCard(); + if ((item == null) || !(item instanceof CardPrinted)) { + return; + } + + final CardPrinted card = (CardPrinted) item; + this.getTableDeck().addCard(card); + this.controller.notifyModelChanged(); + VCurrentDeck.SINGLETON_INSTANCE.getTabLabel().setText("*Current Deck"); + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#removeCard() + */ + @Override + public void removeCard() { + final InventoryItem item = this.getTableDeck().getSelectedCard(); + if ((item == null) || !(item instanceof CardPrinted)) { + return; + } + + final CardPrinted card = (CardPrinted) item; + this.getTableDeck().removeCard(card); + this.controller.notifyModelChanged(); + VCurrentDeck.SINGLETON_INSTANCE.getTabLabel().setText("*Current Deck"); + } + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#updateView() + */ + @Override + public void resetTables() { + this.getTableCatalog().setDeck(ItemPool.createFrom(Iterables.filter(CardDb.instance().getAllNonTraditionalCards(),CardPrinted.Predicates.type("Scheme")), CardPrinted.class)); + this.getTableDeck().setDeck(this.controller.getModel().getSchemes()); + } + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#getController() + */ + @Override + public DeckController getDeckController() { + return this.controller; + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#show(forge.Command) + */ + @Override + public void init() { + final List> lstCatalogCols = SColumnUtil.getCatalogDefaultColumns(); + lstCatalogCols.remove(SColumnUtil.getColumn(ColumnName.CAT_QUANTITY)); + + this.getTableCatalog().setup(VCardCatalog.SINGLETON_INSTANCE, lstCatalogCols); + this.getTableDeck().setup(VCurrentDeck.SINGLETON_INSTANCE, SColumnUtil.getDeckDefaultColumns()); + + SEditorUtil.resetUI(); + + this.controller.newModel(); + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.controllers.ACEditorBase#exit() + */ + @Override + public boolean exit() { + // Override the submenu save choice - tell it to go to "constructed". + Singletons.getModel().getPreferences().setPref(FPref.SUBMENU_CURRENTMENU, EDocID.HOME_ARCHENEMY.toString()); + + return SEditorIO.confirmSaveChanges(); + } +} diff --git a/src/main/java/forge/gui/framework/EDocID.java b/src/main/java/forge/gui/framework/EDocID.java index 9e458018c5f..1318242d998 100644 --- a/src/main/java/forge/gui/framework/EDocID.java +++ b/src/main/java/forge/gui/framework/EDocID.java @@ -68,7 +68,7 @@ public enum EDocID { /** */ HOME_GAUNTLETLOAD (VSubmenuGauntletLoad.SINGLETON_INSTANCE), /** */ HOME_GAUNTLETQUICK (VSubmenuGauntletQuick.SINGLETON_INSTANCE), /** */ HOME_GAUNTLETCONTESTS (VSubmenuGauntletContests.SINGLETON_INSTANCE), /** */ - HOME_MULTITEST (VSubmenuArchenemy.SINGLETON_INSTANCE), /** */ + HOME_ARCHENEMY (VSubmenuArchenemy.SINGLETON_INSTANCE), /** */ HOME_PREFERENCES (VSubmenuPreferences.SINGLETON_INSTANCE), /** */ HOME_AVATARS (VSubmenuAvatars.SINGLETON_INSTANCE), /** */ HOME_UTILITIES (VSubmenuDownloaders.SINGLETON_INSTANCE), /** */ diff --git a/src/main/java/forge/gui/home/variant/CSubmenuArchenemy.java b/src/main/java/forge/gui/home/variant/CSubmenuArchenemy.java index 9d70f541a52..8e90ba6bab8 100644 --- a/src/main/java/forge/gui/home/variant/CSubmenuArchenemy.java +++ b/src/main/java/forge/gui/home/variant/CSubmenuArchenemy.java @@ -2,25 +2,38 @@ package forge.gui.home.variant; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import javax.swing.JRadioButton; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + import javax.swing.SwingUtilities; import javax.swing.SwingWorker; +import com.google.common.collect.Iterables; + import forge.Command; +import forge.GameActionUtil; import forge.Singletons; +import forge.control.FControl; import forge.control.Lobby; import forge.deck.Deck; import forge.deck.DeckgenUtil; import forge.game.GameType; import forge.game.MatchController; import forge.game.MatchStartHelper; -import forge.game.PlayerStartConditions; +import forge.game.player.LobbyPlayer; import forge.game.player.PlayerType; import forge.gui.SOverlayUtils; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.controllers.CEditorScheme; import forge.gui.framework.ICDoc; +import forge.gui.toolbox.FDeckChooser; +import forge.item.CardPrinted; +import forge.properties.ForgePreferences; +import forge.properties.ForgePreferences.FPref; /** - * Controls the deck editor submenu option in the home UI. + * Controls the constructed submenu in the home UI. * *

(C at beginning of class name denotes a control class.) * @@ -28,48 +41,81 @@ import forge.gui.framework.ICDoc; public enum CSubmenuArchenemy implements ICDoc { /** */ SINGLETON_INSTANCE; - private final VSubmenuArchenemy view = VSubmenuArchenemy.SINGLETON_INSTANCE; + /* (non-Javadoc) - * @see forge.control.home.IControlSubmenu#update() + * @see forge.gui.home.ICSubmenu#initialize() + */ + @Override + public void update() { + // Nothing to see here... + } + + /* (non-Javadoc) + * @see forge.gui.home.ICSubmenu#initialize() */ @Override public void initialize() { - view.getDcHuman().initialize(); + + VSubmenuArchenemy.SINGLETON_INSTANCE.getLblEditor().setCommand(new Command() { + @Override + public void execute() { + CDeckEditorUI.SINGLETON_INSTANCE.setCurrentEditorController(new CEditorScheme()); + FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_CONSTRUCTED); + } + }); + + final ForgePreferences prefs = Singletons.getModel().getPreferences(); + for (FDeckChooser fdc : view.getDeckChoosers()) { + fdc.initialize(); + } + // Checkbox event handling view.getBtnStart().addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent arg0) { - start(); + startGame(); } }); + + // Checkbox event handling + view.getCbSingletons().addActionListener(new ActionListener() { + @Override + public void actionPerformed(final ActionEvent arg0) { + prefs.setPref(FPref.DECKGEN_SINGLETONS, + String.valueOf(view.getCbSingletons().isSelected())); + prefs.save(); + } + }); + + view.getCbArtifacts().addActionListener(new ActionListener() { + @Override + public void actionPerformed(final ActionEvent arg0) { + prefs.setPref( + FPref.DECKGEN_ARTIFACTS, String.valueOf(view.getCbArtifacts().isSelected())); + prefs.save(); + } + }); + + view.getCbRemoveSmall().addActionListener(new ActionListener() { + @Override + public void actionPerformed(final ActionEvent arg0) { + prefs.setPref( + FPref.DECKGEN_NOSMALL, String.valueOf(view.getCbRemoveSmall().isSelected())); + prefs.save(); + } + }); + + // Pre-select checkboxes + view.getCbSingletons().setSelected(prefs.getPrefBoolean(FPref.DECKGEN_SINGLETONS)); + view.getCbArtifacts().setSelected(prefs.getPrefBoolean(FPref.DECKGEN_ARTIFACTS)); + view.getCbRemoveSmall().setSelected(prefs.getPrefBoolean(FPref.DECKGEN_NOSMALL)); } - /* (non-Javadoc) - * @see forge.control.home.IControlSubmenu#update() - */ - @Override - public void update() { } - /* (non-Javadoc) - * @see forge.gui.framework.ICDoc#getCommandOnSelect() - */ - @Override - public Command getCommandOnSelect() { - return null; - } - - private void start() { - // Retrieve selections - JRadioButton radTemp = null; - - for (JRadioButton rad : view.getFieldRadios()) { - if (rad.isSelected()) { radTemp = rad; break; } } - - final int numFields = (radTemp == null ? 2 : Integer.valueOf(radTemp.getText())); - - // Boilerplate start game code + /** @param lists0   {@link java.util.List}<{@link javax.swing.JList}> */ + private void startGame() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { @@ -81,21 +127,79 @@ public enum CSubmenuArchenemy implements ICDoc { final SwingWorker worker = new SwingWorker() { @Override public Object doInBackground() { - Deck humanDeck = view.getDcHuman().getDeck(); + Random rnd = new Random(); + String nl = System.getProperty("line.separator"); + boolean usedDefaults = false; - MatchStartHelper starter = new MatchStartHelper(); - Lobby lobby = Singletons.getControl().getLobby(); + List playerDecks = new ArrayList(); + for (int i = 0; i < view.getNumPlayers(); i++) { + Deck d = view.getDeckChoosers().get(i).getDeck(); - PlayerStartConditions humanStart = new PlayerStartConditions(humanDeck); - starter.addPlayer(lobby.findLocalPlayer(PlayerType.HUMAN), humanStart); - humanStart.setStartingLife(10 + 10 * numFields); // will have 40 life to play against 3 opponents - - for (int i = 0; i < numFields; i++) { - starter.addPlayer(lobby.findLocalPlayer(PlayerType.COMPUTER), DeckgenUtil.getRandomColorDeck(PlayerType.COMPUTER)); + if (d == null) { + //ERROR! + GameActionUtil.showInfoDialg("No deck selected for player " + (i + 1)); + return null; + } + playerDecks.add(d); } + List schemes = null; + Object obj = view.getArchenemySchemes().getSelectedValue(); + + boolean useDefault = VSubmenuArchenemy.SINGLETON_INSTANCE.getCbUseDefaultSchemes().isSelected(); + useDefault &= !playerDecks.get(0).getSchemes().isEmpty(); + + System.out.println(useDefault); + if (useDefault) { + + schemes = playerDecks.get(0).getSchemes().toFlatList(); + System.out.println(schemes.toString()); + usedDefaults = true; + + } else { + + if (obj instanceof String) { + String sel = (String)obj; + if(sel.equals("Random")) + { + schemes = Iterables.get(view.getAllSchemeDecks(), rnd.nextInt(Iterables.size(view.getAllSchemeDecks()))).getSchemes().toFlatList(); + } + else + { + //Generate + schemes = DeckgenUtil.generateSchemeDeck().getSchemes().toFlatList(); + } + } else { + schemes = ((Deck)obj).getSchemes().toFlatList(); + } + } + if (schemes == null) { + //ERROR! + GameActionUtil.showInfoDialg("No scheme deck selected!"); + return null; + } + + if (usedDefaults) { + + GameActionUtil.showInfoDialg("Using default scheme deck."); + } + + Lobby lobby = Singletons.getControl().getLobby(); + MatchStartHelper helper = new MatchStartHelper(); + for (int i = 0; i < view.getNumPlayers(); i++) { + LobbyPlayer player = lobby.findLocalPlayer(i == 0 ? PlayerType.HUMAN : PlayerType.COMPUTER); + + if(i == 0) + { + helper.addArchenemy(player, playerDecks.get(i), schemes); + } + else + { + helper.addPlayer(player, playerDecks.get(i)); + } + } MatchController mc = Singletons.getModel().getMatch(); - mc.initMatch(GameType.Constructed, starter.getPlayerMap()); + mc.initMatch(GameType.Archenemy, helper.getPlayerMap()); mc.startRound(); return null; @@ -108,4 +212,13 @@ public enum CSubmenuArchenemy implements ICDoc { }; worker.execute(); } + + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#getCommandOnSelect() + */ + @Override + public Command getCommandOnSelect() { + return null; + } } diff --git a/src/main/java/forge/gui/home/variant/VSubmenuArchenemy.java b/src/main/java/forge/gui/home/variant/VSubmenuArchenemy.java index 13eb3237b4e..2d6a34f658e 100644 --- a/src/main/java/forge/gui/home/variant/VSubmenuArchenemy.java +++ b/src/main/java/forge/gui/home/variant/VSubmenuArchenemy.java @@ -1,29 +1,51 @@ package forge.gui.home.variant; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; import java.util.ArrayList; import java.util.List; +import java.util.Vector; import javax.swing.ButtonGroup; import javax.swing.JButton; +import javax.swing.JCheckBox; import javax.swing.JPanel; import javax.swing.JRadioButton; +import javax.swing.JScrollPane; +import javax.swing.ScrollPaneConstants; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +import com.google.common.collect.Iterables; import net.miginfocom.swing.MigLayout; +import forge.Singletons; +import forge.deck.Deck; import forge.game.player.PlayerType; +import forge.gui.CardDetailPanel; import forge.gui.framework.DragCell; import forge.gui.framework.DragTab; import forge.gui.framework.EDocID; import forge.gui.home.EMenuGroup; import forge.gui.home.IVSubmenu; +import forge.gui.home.LblHeader; import forge.gui.home.StartButton; import forge.gui.home.VHomeUI; +import forge.gui.toolbox.ExperimentalLabel; +import forge.gui.toolbox.FCheckBox; import forge.gui.toolbox.FDeckChooser; import forge.gui.toolbox.FLabel; +import forge.gui.toolbox.FList; import forge.gui.toolbox.FPanel; import forge.gui.toolbox.FRadioButton; +import forge.gui.toolbox.FScrollPane; +import forge.gui.toolbox.FSkin; +import forge.gui.toolbox.FTabbedPane; +import forge.item.CardDb; +import forge.item.CardPrinted; /** - * Assembles Swing components of deck editor submenu option singleton. + * Assembles Swing components of constructed submenu singleton. * *

(V at beginning of class name denotes a view class.) * @@ -34,72 +56,142 @@ public enum VSubmenuArchenemy implements IVSubmenu { // Fields used with interface IVDoc private DragCell parentCell; - private final DragTab tab = new DragTab("Multiplayer Test"); - private final JPanel pnlFields; + private final DragTab tab = new DragTab("Archenemy Mode"); /** */ - private final List fieldRadios = new ArrayList(); - private final StartButton btnStart = new StartButton(); - private final ButtonGroup grpFields = new ButtonGroup(); + private final LblHeader lblTitle = new LblHeader("Variant: Archenemy"); - private final FDeckChooser dcHuman = new FDeckChooser("Choose your deck", PlayerType.HUMAN); + private final JPanel pnlStart = new JPanel(new MigLayout("insets 0, gap 0, wrap 2")); + + private final StartButton btnStart = new StartButton(); + + private final JCheckBox cbSingletons = new FCheckBox("Singleton Mode"); + private final JCheckBox cbArtifacts = new FCheckBox("Remove Artifacts"); + private final JCheckBox cbRemoveSmall = new FCheckBox("Remove Small Creatures"); + + ////////////////////////////// + + private ExperimentalLabel lblEditor = new ExperimentalLabel("Scheme Deck Editor"); + private final FTabbedPane tabPane = new FTabbedPane(); + private final List playerPanels = new ArrayList(); + private final List deckChoosers = new ArrayList(); + private final FList archenemySchemes = new FList(); + private final List allSchemeDecks = new ArrayList(); + private final JCheckBox cbUseDefaultSchemes = new FCheckBox("Use default scheme decks if possible."); + private final List fieldRadios = new ArrayList(); + private final ButtonGroup grpFields = new ButtonGroup(); + private int currentNumTabsShown = 8; + + ////////////////////////////// private VSubmenuArchenemy() { - FRadioButton temp; - for (int i = 2; i < 8; i++) { - temp = new FRadioButton(); - temp.setText(String.valueOf(i)); - fieldRadios.add(temp); - grpFields.add(temp); + lblTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + + //This listener will look for any of the radio buttons being selected + //and call the method that shows/hides tabs appropriately. + ItemListener iListener = new ItemListener() { + + @Override + public void itemStateChanged(ItemEvent arg0) { + FRadioButton aButton = (FRadioButton) arg0.getSource(); + + if (arg0.getStateChange() == ItemEvent.SELECTED) { + changeTabs(Integer.parseInt(aButton.getText())); + } + } + + }; + + //Create all 8 player settings panel + FRadioButton tempRadio = null; + FPanel tempPanel; + FDeckChooser tempChooser; + + //Settings panel + FPanel settingsPanel = new FPanel(); + settingsPanel.setLayout(new MigLayout("wrap 2")); + FPanel radioPane = new FPanel(); + radioPane.setLayout(new MigLayout("wrap 1")); + radioPane.setOpaque(false); + radioPane.add(new FLabel.Builder().text("Set number of opponents").build(), "wrap"); + for (int i = 1; i < 8; i++) { + tempRadio = new FRadioButton(); + tempRadio.setText(String.valueOf(i)); + fieldRadios.add(tempRadio); + grpFields.add(tempRadio); + tempRadio.setSelected(true); + tempRadio.addItemListener(iListener); + radioPane.add(tempRadio, "wrap,align 50% 50%"); + } + settingsPanel.add(radioPane, "span 1 2"); + settingsPanel.add(cbUseDefaultSchemes); + settingsPanel.add(lblEditor); + tabPane.add("Settings", settingsPanel); + + //Player panels (Human + 7 AIs) + for (int i = 0; i < 8; i++) { + tempPanel = new FPanel(); + tempPanel.setLayout(new MigLayout("insets 0, gap 0 , wrap 2, flowy")); + + tempChooser = new FDeckChooser("Select deck:", i == 0 ? PlayerType.HUMAN : PlayerType.COMPUTER); + tempChooser.initialize(); + + deckChoosers.add(tempChooser); + + tempPanel.add(tempChooser, "span 1 2, w 44%!, gap 0 0 20px 20px, growy, pushy, wrap"); + if(i == 0) + { + tempPanel.add(new FLabel.Builder().text("Select Scheme deck:").build(), "flowy"); + + Vector listData = new Vector(); + listData.add("Random"); + listData.add("Generate"); + for(Deck schemeDeck : Singletons.getModel().getDecks().getScheme()) { + listData.add(schemeDeck); + } + + archenemySchemes.setListData(listData); + archenemySchemes.setSelectedIndex(0); + archenemySchemes.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); + + JScrollPane scrSchemes = new FScrollPane(archenemySchemes, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + tempPanel.add(scrSchemes, "h 90%!,wrap"); + } + + playerPanels.add(tempPanel); + if (i == 0) { + tabPane.add("Human", tempPanel); + } else { + tabPane.add("Opponent " + i, tempPanel); + } } + final String strCheckboxConstraints = "w 200px!, h 30px!, gap 0 20px 0 0"; + pnlStart.setOpaque(false); + pnlStart.add(cbSingletons, strCheckboxConstraints); + pnlStart.add(btnStart, "span 1 3, growx, pushx, align center"); + pnlStart.add(cbArtifacts, strCheckboxConstraints); + pnlStart.add(cbRemoveSmall, strCheckboxConstraints); + } - - pnlFields = new FPanel(); - pnlFields.setLayout(new MigLayout("insets 0, gap 0, wrap")); - pnlFields.add(new FLabel.Builder().text("How many AI opponents are you ready to handle?").build(), "h 30px!"); - - for (JRadioButton rad : fieldRadios) { - pnlFields.add(rad, "w 100px!, h 30px!, gap 30px 0 0 0"); + private void changeTabs(int toShow) { + if (toShow < currentNumTabsShown) { + for (int i = currentNumTabsShown; i > toShow + 1; i--) { + tabPane.remove(i); + } + currentNumTabsShown = tabPane.getComponentCount() - 1; + } + else { + for (int i = currentNumTabsShown; i <= toShow; i++) { + tabPane.add("Opponent " + i, playerPanels.get(i)); + } + currentNumTabsShown = tabPane.getComponentCount() - 1; } - - fieldRadios.get(0).setSelected(true); - } - - /** @return {@link javax.swing.JButton} */ - public JButton getBtnStart() { - return btnStart; - } - - /** @return {@link java.util.List} */ - public List getFieldRadios() { - return fieldRadios; } /* (non-Javadoc) - * @see forge.view.home.IViewSubmenu#populate() - */ - @Override - public void populate() { - VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().removeAll(); - VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().setLayout(new MigLayout("insets 0, gap 0, wrap 2")); - - VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(pnlFields, "w 41%!, gap 6% 6% 50px 0, growy, pushy"); - dcHuman.populate(); - VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(dcHuman, "w 41%!, gap 0 0 50px 0, growy, pushy"); - - VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(new FLabel.Builder() - .text("Starts a new game with preconstructed 2 color decks for each field.") - .build(), "gap 0 0 50px 5px, ax center, span 2"); - VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(btnStart, "gap 0 0 50px 50px, ax center, span 2"); - - VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().repaintSelf(); - VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().revalidate(); - } - - /* (non-Javadoc) - * @see forge.view.home.IViewSubmenu#getGroup() + * @see forge.gui.home.IVSubmenu#getGroupEnum() */ @Override public EMenuGroup getGroupEnum() { @@ -119,7 +211,52 @@ public enum VSubmenuArchenemy implements IVSubmenu { */ @Override public EDocID getItemEnum() { - return EDocID.HOME_MULTITEST; + return EDocID.HOME_ARCHENEMY; + } + + /* (non-Javadoc) + * @see forge.gui.home.IVSubmenu#populate() + */ + @Override + public void populate() { + VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().removeAll(); + VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().setLayout(new MigLayout("insets 0, gap 0, wrap 1, ax right")); + + VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(lblTitle, "w 80%!, h 40px!, gap 0 0 15px 15px, span 2, ax right"); + + for (FDeckChooser fdc : deckChoosers) { + fdc.populate(); + } + + VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(tabPane, "gap 0 0 50px 50px, growx, growy"); + + VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(pnlStart, "span 1, ax center"); + + VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().revalidate(); + VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().repaintSelf(); + + } + + + /** @return {@link javax.swing.JButton} */ + public JButton getBtnStart() { + return this.btnStart; + } + + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getCbSingletons() { + return cbSingletons; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getCbArtifacts() { + return cbArtifacts; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getCbRemoveSmall() { + return cbRemoveSmall; } //========== Overridden from IVDoc @@ -129,7 +266,7 @@ public enum VSubmenuArchenemy implements IVSubmenu { */ @Override public EDocID getDocumentID() { - return EDocID.HOME_MULTITEST; + return EDocID.HOME_ARCHENEMY; } /* (non-Javadoc) @@ -164,7 +301,43 @@ public enum VSubmenuArchenemy implements IVSubmenu { return parentCell; } - public final FDeckChooser getDcHuman() { - return dcHuman; + /** + * + * @return a deckchooser for every player + */ + public List getDeckChoosers() { + return deckChoosers; + } + + public int getNumPlayers() { + return currentNumTabsShown; + } + + /** + * @return the lblEditor + */ + public ExperimentalLabel getLblEditor() { + return lblEditor; + } + + /** + * @return the cbUseDefaultSchemes + */ + public JCheckBox getCbUseDefaultSchemes() { + return cbUseDefaultSchemes; + } + + /** + * @return the archenemySchemes + */ + public FList getArchenemySchemes() { + return archenemySchemes; + } + + /** + * @return the allSchemeDecks + */ + public List getAllSchemeDecks() { + return allSchemeDecks; } } diff --git a/src/main/java/forge/item/CardPrinted.java b/src/main/java/forge/item/CardPrinted.java index 2eecb483530..d9dca3f1e90 100644 --- a/src/main/java/forge/item/CardPrinted.java +++ b/src/main/java/forge/item/CardPrinted.java @@ -112,7 +112,8 @@ public final class CardPrinted implements Comparable, InventoryItem } public boolean isTraditional() { - return !getCard().getType().isVanguard(); + return !(getCard().getType().isVanguard() + || getCard().getType().isScheme()); } /**