mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
merge latest trunk
This commit is contained in:
20
.gitattributes
vendored
20
.gitattributes
vendored
@@ -553,7 +553,7 @@ res/cardsfolder/a/aspect_of_wolf.txt svneol=native#text/plain
|
|||||||
res/cardsfolder/a/assassinate.txt svneol=native#text/plain
|
res/cardsfolder/a/assassinate.txt svneol=native#text/plain
|
||||||
res/cardsfolder/a/assassins_blade.txt svneol=native#text/plain
|
res/cardsfolder/a/assassins_blade.txt svneol=native#text/plain
|
||||||
res/cardsfolder/a/assassins_strike.txt -text
|
res/cardsfolder/a/assassins_strike.txt -text
|
||||||
res/cardsfolder/a/assault__battery.txt -text
|
res/cardsfolder/a/assault_battery.txt -text
|
||||||
res/cardsfolder/a/assault_griffin.txt svneol=native#text/plain
|
res/cardsfolder/a/assault_griffin.txt svneol=native#text/plain
|
||||||
res/cardsfolder/a/assault_strobe.txt svneol=native#text/plain
|
res/cardsfolder/a/assault_strobe.txt svneol=native#text/plain
|
||||||
res/cardsfolder/a/assault_zeppelid.txt svneol=native#text/plain
|
res/cardsfolder/a/assault_zeppelid.txt svneol=native#text/plain
|
||||||
@@ -1181,6 +1181,7 @@ res/cardsfolder/b/bonfire_of_the_damned.txt -text
|
|||||||
res/cardsfolder/b/booby_trap.txt -text
|
res/cardsfolder/b/booby_trap.txt -text
|
||||||
res/cardsfolder/b/book_burning.txt -text
|
res/cardsfolder/b/book_burning.txt -text
|
||||||
res/cardsfolder/b/book_of_rass.txt svneol=native#text/plain
|
res/cardsfolder/b/book_of_rass.txt svneol=native#text/plain
|
||||||
|
res/cardsfolder/b/boom_bust.txt -text
|
||||||
res/cardsfolder/b/boomerang.txt svneol=native#text/plain
|
res/cardsfolder/b/boomerang.txt svneol=native#text/plain
|
||||||
res/cardsfolder/b/boon_reflection.txt svneol=native#text/plain
|
res/cardsfolder/b/boon_reflection.txt svneol=native#text/plain
|
||||||
res/cardsfolder/b/borborygmos.txt svneol=native#text/plain
|
res/cardsfolder/b/borborygmos.txt svneol=native#text/plain
|
||||||
@@ -2098,6 +2099,7 @@ res/cardsfolder/c/crescendo_of_war.txt -text
|
|||||||
res/cardsfolder/c/crested_craghorn.txt -text
|
res/cardsfolder/c/crested_craghorn.txt -text
|
||||||
res/cardsfolder/c/crevasse.txt svneol=native#text/plain
|
res/cardsfolder/c/crevasse.txt svneol=native#text/plain
|
||||||
res/cardsfolder/c/crib_swap.txt svneol=native#text/plain
|
res/cardsfolder/c/crib_swap.txt svneol=native#text/plain
|
||||||
|
res/cardsfolder/c/crime_punishment.txt -text
|
||||||
res/cardsfolder/c/crimson_acolyte.txt svneol=native#text/plain
|
res/cardsfolder/c/crimson_acolyte.txt svneol=native#text/plain
|
||||||
res/cardsfolder/c/crimson_hellkite.txt -text
|
res/cardsfolder/c/crimson_hellkite.txt -text
|
||||||
res/cardsfolder/c/crimson_kobolds.txt svneol=native#text/plain
|
res/cardsfolder/c/crimson_kobolds.txt svneol=native#text/plain
|
||||||
@@ -2372,6 +2374,7 @@ res/cardsfolder/d/day_of_the_dragons.txt svneol=native#text/plain
|
|||||||
res/cardsfolder/d/daybreak_coronet.txt -text
|
res/cardsfolder/d/daybreak_coronet.txt -text
|
||||||
res/cardsfolder/d/daybreak_ranger_nightfall_predator.txt -text
|
res/cardsfolder/d/daybreak_ranger_nightfall_predator.txt -text
|
||||||
res/cardsfolder/d/daze.txt svneol=native#text/plain
|
res/cardsfolder/d/daze.txt svneol=native#text/plain
|
||||||
|
res/cardsfolder/d/dead_gone.txt -text
|
||||||
res/cardsfolder/d/dead_iron_sledge.txt svneol=native#text/plain
|
res/cardsfolder/d/dead_iron_sledge.txt svneol=native#text/plain
|
||||||
res/cardsfolder/d/dead_reckoning.txt -text svneol=unset#text/plain
|
res/cardsfolder/d/dead_reckoning.txt -text svneol=unset#text/plain
|
||||||
res/cardsfolder/d/dead_reveler.txt -text
|
res/cardsfolder/d/dead_reveler.txt -text
|
||||||
@@ -4870,6 +4873,7 @@ res/cardsfolder/h/hidden_path.txt svneol=native#text/plain
|
|||||||
res/cardsfolder/h/hidden_predators.txt -text
|
res/cardsfolder/h/hidden_predators.txt -text
|
||||||
res/cardsfolder/h/hidden_spider.txt svneol=native#text/plain
|
res/cardsfolder/h/hidden_spider.txt svneol=native#text/plain
|
||||||
res/cardsfolder/h/hidden_stag.txt -text svneol=unset#text/plain
|
res/cardsfolder/h/hidden_stag.txt -text svneol=unset#text/plain
|
||||||
|
res/cardsfolder/h/hide_seek.txt -text
|
||||||
res/cardsfolder/h/hideous_end.txt svneol=native#text/plain
|
res/cardsfolder/h/hideous_end.txt svneol=native#text/plain
|
||||||
res/cardsfolder/h/hideous_laughter.txt -text
|
res/cardsfolder/h/hideous_laughter.txt -text
|
||||||
res/cardsfolder/h/hideous_visage.txt svneol=native#text/plain
|
res/cardsfolder/h/hideous_visage.txt svneol=native#text/plain
|
||||||
@@ -5117,6 +5121,7 @@ res/cardsfolder/i/ill_gotten_gains.txt svneol=native#text/plain
|
|||||||
res/cardsfolder/i/illness_in_the_ranks.txt -text
|
res/cardsfolder/i/illness_in_the_ranks.txt -text
|
||||||
res/cardsfolder/i/illuminated_wings.txt svneol=native#text/plain
|
res/cardsfolder/i/illuminated_wings.txt svneol=native#text/plain
|
||||||
res/cardsfolder/i/illumination.txt svneol=native#text/plain
|
res/cardsfolder/i/illumination.txt svneol=native#text/plain
|
||||||
|
res/cardsfolder/i/illusion_reality.txt -text
|
||||||
res/cardsfolder/i/illusionary_forces.txt svneol=native#text/plain
|
res/cardsfolder/i/illusionary_forces.txt svneol=native#text/plain
|
||||||
res/cardsfolder/i/illusionary_servant.txt svneol=native#text/plain
|
res/cardsfolder/i/illusionary_servant.txt svneol=native#text/plain
|
||||||
res/cardsfolder/i/illusionary_wall.txt svneol=native#text/plain
|
res/cardsfolder/i/illusionary_wall.txt svneol=native#text/plain
|
||||||
@@ -5995,6 +6000,7 @@ res/cardsfolder/l/lieutenant_kirtar.txt svneol=native#text/plain
|
|||||||
res/cardsfolder/l/life_and_limb.txt svneol=native#text/plain
|
res/cardsfolder/l/life_and_limb.txt svneol=native#text/plain
|
||||||
res/cardsfolder/l/life_burst.txt svneol=native#text/plain
|
res/cardsfolder/l/life_burst.txt svneol=native#text/plain
|
||||||
res/cardsfolder/l/life_chisel.txt svneol=native#text/plain
|
res/cardsfolder/l/life_chisel.txt svneol=native#text/plain
|
||||||
|
res/cardsfolder/l/life_death.txt -text
|
||||||
res/cardsfolder/l/life_from_the_loam.txt svneol=native#text/plain
|
res/cardsfolder/l/life_from_the_loam.txt svneol=native#text/plain
|
||||||
res/cardsfolder/l/life_matrix.txt -text svneol=unset#text/plain
|
res/cardsfolder/l/life_matrix.txt -text svneol=unset#text/plain
|
||||||
res/cardsfolder/l/lifeblood.txt svneol=native#text/plain
|
res/cardsfolder/l/lifeblood.txt svneol=native#text/plain
|
||||||
@@ -7151,6 +7157,7 @@ res/cardsfolder/n/niblis_of_the_mist.txt -text
|
|||||||
res/cardsfolder/n/niblis_of_the_urn.txt -text
|
res/cardsfolder/n/niblis_of_the_urn.txt -text
|
||||||
res/cardsfolder/n/nicol_bolas.txt svneol=native#text/plain
|
res/cardsfolder/n/nicol_bolas.txt svneol=native#text/plain
|
||||||
res/cardsfolder/n/nicol_bolas_planeswalker.txt svneol=native#text/plain
|
res/cardsfolder/n/nicol_bolas_planeswalker.txt svneol=native#text/plain
|
||||||
|
res/cardsfolder/n/night_day.txt -text
|
||||||
res/cardsfolder/n/night_dealings.txt -text svneol=unset#text/plain
|
res/cardsfolder/n/night_dealings.txt -text svneol=unset#text/plain
|
||||||
res/cardsfolder/n/night_of_souls_betrayal.txt svneol=native#text/plain
|
res/cardsfolder/n/night_of_souls_betrayal.txt svneol=native#text/plain
|
||||||
res/cardsfolder/n/night_revelers.txt -text
|
res/cardsfolder/n/night_revelers.txt -text
|
||||||
@@ -7421,6 +7428,7 @@ res/cardsfolder/o/orcish_spy.txt svneol=native#text/plain
|
|||||||
res/cardsfolder/o/orcish_squatters.txt -text svneol=unset#text/plain
|
res/cardsfolder/o/orcish_squatters.txt -text svneol=unset#text/plain
|
||||||
res/cardsfolder/o/orcish_squatters_avatar.txt -text
|
res/cardsfolder/o/orcish_squatters_avatar.txt -text
|
||||||
res/cardsfolder/o/orcish_veteran.txt svneol=native#text/plain
|
res/cardsfolder/o/orcish_veteran.txt svneol=native#text/plain
|
||||||
|
res/cardsfolder/o/order_chaos.txt -text
|
||||||
res/cardsfolder/o/order_of_leitbur.txt svneol=native#text/plain
|
res/cardsfolder/o/order_of_leitbur.txt svneol=native#text/plain
|
||||||
res/cardsfolder/o/order_of_the_ebon_hand.txt svneol=native#text/plain
|
res/cardsfolder/o/order_of_the_ebon_hand.txt svneol=native#text/plain
|
||||||
res/cardsfolder/o/order_of_the_golden_cricket.txt svneol=native#text/plain
|
res/cardsfolder/o/order_of_the_golden_cricket.txt svneol=native#text/plain
|
||||||
@@ -7515,6 +7523,7 @@ res/cardsfolder/p/pact_of_negation.txt svneol=native#text/plain
|
|||||||
res/cardsfolder/p/pact_of_the_titan.txt svneol=native#text/plain
|
res/cardsfolder/p/pact_of_the_titan.txt svneol=native#text/plain
|
||||||
res/cardsfolder/p/pain_kami.txt svneol=native#text/plain
|
res/cardsfolder/p/pain_kami.txt svneol=native#text/plain
|
||||||
res/cardsfolder/p/pain_magnification.txt svneol=native#text/plain
|
res/cardsfolder/p/pain_magnification.txt svneol=native#text/plain
|
||||||
|
res/cardsfolder/p/pain_suffering.txt -text
|
||||||
res/cardsfolder/p/painbringer.txt -text svneol=unset#text/plain
|
res/cardsfolder/p/painbringer.txt -text svneol=unset#text/plain
|
||||||
res/cardsfolder/p/painful_memories.txt svneol=native#text/plain
|
res/cardsfolder/p/painful_memories.txt svneol=native#text/plain
|
||||||
res/cardsfolder/p/painful_quandary.txt -text
|
res/cardsfolder/p/painful_quandary.txt -text
|
||||||
@@ -8063,6 +8072,7 @@ res/cardsfolder/p/puppeteer_clique.txt svneol=native#text/plain
|
|||||||
res/cardsfolder/p/puppets_verdict.txt -text
|
res/cardsfolder/p/puppets_verdict.txt -text
|
||||||
res/cardsfolder/p/pure_intentions.txt -text svneol=unset#text/plain
|
res/cardsfolder/p/pure_intentions.txt -text svneol=unset#text/plain
|
||||||
res/cardsfolder/p/pure_reflection.txt -text
|
res/cardsfolder/p/pure_reflection.txt -text
|
||||||
|
res/cardsfolder/p/pure_simple.txt -text
|
||||||
res/cardsfolder/p/purelace.txt -text
|
res/cardsfolder/p/purelace.txt -text
|
||||||
res/cardsfolder/p/puresight_merrow.txt svneol=native#text/plain
|
res/cardsfolder/p/puresight_merrow.txt svneol=native#text/plain
|
||||||
res/cardsfolder/p/puresteel_paladin.txt -text
|
res/cardsfolder/p/puresteel_paladin.txt -text
|
||||||
@@ -8751,6 +8761,7 @@ res/cardsfolder/r/rotting_fensnake.txt -text
|
|||||||
res/cardsfolder/r/rotting_giant.txt -text
|
res/cardsfolder/r/rotting_giant.txt -text
|
||||||
res/cardsfolder/r/rotting_legion.txt svneol=native#text/plain
|
res/cardsfolder/r/rotting_legion.txt svneol=native#text/plain
|
||||||
res/cardsfolder/r/rotting_rats.txt svneol=native#text/plain
|
res/cardsfolder/r/rotting_rats.txt svneol=native#text/plain
|
||||||
|
res/cardsfolder/r/rough_tumble.txt -text
|
||||||
res/cardsfolder/r/roughshod_mentor.txt svneol=native#text/plain
|
res/cardsfolder/r/roughshod_mentor.txt svneol=native#text/plain
|
||||||
res/cardsfolder/r/rouse.txt svneol=native#text/plain
|
res/cardsfolder/r/rouse.txt svneol=native#text/plain
|
||||||
res/cardsfolder/r/rowan_treefolk.txt svneol=native#text/plain
|
res/cardsfolder/r/rowan_treefolk.txt svneol=native#text/plain
|
||||||
@@ -10065,6 +10076,7 @@ res/cardsfolder/s/spiritual_guardian.txt svneol=native#text/plain
|
|||||||
res/cardsfolder/s/spiritual_sanctuary.txt svneol=native#text/plain
|
res/cardsfolder/s/spiritual_sanctuary.txt svneol=native#text/plain
|
||||||
res/cardsfolder/s/spiritual_visit.txt -text
|
res/cardsfolder/s/spiritual_visit.txt -text
|
||||||
res/cardsfolder/s/spiritualize.txt -text svneol=unset#text/plain
|
res/cardsfolder/s/spiritualize.txt -text svneol=unset#text/plain
|
||||||
|
res/cardsfolder/s/spite_malice.txt -text
|
||||||
res/cardsfolder/s/spitebellows.txt svneol=native#text/plain
|
res/cardsfolder/s/spitebellows.txt svneol=native#text/plain
|
||||||
res/cardsfolder/s/spiteflame_witch.txt svneol=native#text/plain
|
res/cardsfolder/s/spiteflame_witch.txt svneol=native#text/plain
|
||||||
res/cardsfolder/s/spiteful_bully.txt svneol=native#text/plain
|
res/cardsfolder/s/spiteful_bully.txt svneol=native#text/plain
|
||||||
@@ -10167,6 +10179,7 @@ res/cardsfolder/s/stampede_driver.txt svneol=native#text/plain
|
|||||||
res/cardsfolder/s/stampeding_rhino.txt svneol=native#text/plain
|
res/cardsfolder/s/stampeding_rhino.txt svneol=native#text/plain
|
||||||
res/cardsfolder/s/stampeding_serow.txt svneol=native#text/plain
|
res/cardsfolder/s/stampeding_serow.txt svneol=native#text/plain
|
||||||
res/cardsfolder/s/stampeding_wildebeests.txt svneol=native#text/plain
|
res/cardsfolder/s/stampeding_wildebeests.txt svneol=native#text/plain
|
||||||
|
res/cardsfolder/s/stand_deliver.txt -text
|
||||||
res/cardsfolder/s/stand_firm.txt svneol=native#text/plain
|
res/cardsfolder/s/stand_firm.txt svneol=native#text/plain
|
||||||
res/cardsfolder/s/stand_together.txt -text
|
res/cardsfolder/s/stand_together.txt -text
|
||||||
res/cardsfolder/s/standardize.txt -text svneol=unset#text/plain
|
res/cardsfolder/s/standardize.txt -text svneol=unset#text/plain
|
||||||
@@ -10449,6 +10462,7 @@ res/cardsfolder/s/suntail_hawk.txt svneol=native#text/plain
|
|||||||
res/cardsfolder/s/suntouched_myr.txt svneol=native#text/plain
|
res/cardsfolder/s/suntouched_myr.txt svneol=native#text/plain
|
||||||
res/cardsfolder/s/sunweb.txt svneol=native#text/plain
|
res/cardsfolder/s/sunweb.txt svneol=native#text/plain
|
||||||
res/cardsfolder/s/superior_numbers.txt -text svneol=unset#text/plain
|
res/cardsfolder/s/superior_numbers.txt -text svneol=unset#text/plain
|
||||||
|
res/cardsfolder/s/supply_demand.txt -text
|
||||||
res/cardsfolder/s/suppress.txt -text svneol=unset#text/plain
|
res/cardsfolder/s/suppress.txt -text svneol=unset#text/plain
|
||||||
res/cardsfolder/s/suppression_field.txt -text
|
res/cardsfolder/s/suppression_field.txt -text
|
||||||
res/cardsfolder/s/supreme_exemplar.txt svneol=native#text/plain
|
res/cardsfolder/s/supreme_exemplar.txt svneol=native#text/plain
|
||||||
@@ -11175,6 +11189,7 @@ res/cardsfolder/t/treva_the_renewer.txt svneol=native#text/plain
|
|||||||
res/cardsfolder/t/trevas_attendant.txt svneol=native#text/plain
|
res/cardsfolder/t/trevas_attendant.txt svneol=native#text/plain
|
||||||
res/cardsfolder/t/trevas_charm.txt svneol=native#text/plain
|
res/cardsfolder/t/trevas_charm.txt svneol=native#text/plain
|
||||||
res/cardsfolder/t/trevas_ruins.txt svneol=native#text/plain
|
res/cardsfolder/t/trevas_ruins.txt svneol=native#text/plain
|
||||||
|
res/cardsfolder/t/trial_error.txt -text
|
||||||
res/cardsfolder/t/triangle_of_war.txt svneol=native#text/plain
|
res/cardsfolder/t/triangle_of_war.txt svneol=native#text/plain
|
||||||
res/cardsfolder/t/triassic_egg.txt svneol=native#text/plain
|
res/cardsfolder/t/triassic_egg.txt svneol=native#text/plain
|
||||||
res/cardsfolder/t/tribal_flames.txt svneol=native#text/plain
|
res/cardsfolder/t/tribal_flames.txt svneol=native#text/plain
|
||||||
@@ -11931,6 +11946,7 @@ res/cardsfolder/w/wave_of_reckoning.txt -text
|
|||||||
res/cardsfolder/w/wave_of_terror.txt svneol=native#text/plain
|
res/cardsfolder/w/wave_of_terror.txt svneol=native#text/plain
|
||||||
res/cardsfolder/w/waves_of_aggression.txt -text
|
res/cardsfolder/w/waves_of_aggression.txt -text
|
||||||
res/cardsfolder/w/waveskimmer_aven.txt svneol=native#text/plain
|
res/cardsfolder/w/waveskimmer_aven.txt svneol=native#text/plain
|
||||||
|
res/cardsfolder/w/wax_wane.txt -text
|
||||||
res/cardsfolder/w/waxmane_baku.txt -text
|
res/cardsfolder/w/waxmane_baku.txt -text
|
||||||
res/cardsfolder/w/way_of_the_thief.txt -text
|
res/cardsfolder/w/way_of_the_thief.txt -text
|
||||||
res/cardsfolder/w/wayfarers_bauble.txt svneol=native#text/plain
|
res/cardsfolder/w/wayfarers_bauble.txt svneol=native#text/plain
|
||||||
@@ -13053,6 +13069,7 @@ res/quest/duels/Pointy[!!-~]Haired[!!-~]Boss[!!-~]3.dck -text
|
|||||||
res/quest/duels/Princess[!!-~]Selenia[!!-~]1.dck -text
|
res/quest/duels/Princess[!!-~]Selenia[!!-~]1.dck -text
|
||||||
res/quest/duels/Professor[!!-~]X[!!-~]2.dck -text
|
res/quest/duels/Professor[!!-~]X[!!-~]2.dck -text
|
||||||
res/quest/duels/Professor[!!-~]X[!!-~]3.dck -text
|
res/quest/duels/Professor[!!-~]X[!!-~]3.dck -text
|
||||||
|
res/quest/duels/Quicksilver[!!-~]3.dck -text
|
||||||
res/quest/duels/R2-D2[!!-~]3.dck -text
|
res/quest/duels/R2-D2[!!-~]3.dck -text
|
||||||
res/quest/duels/Radagast[!!-~]2.dck -text
|
res/quest/duels/Radagast[!!-~]2.dck -text
|
||||||
res/quest/duels/Radiant[!!-~]2.dck -text
|
res/quest/duels/Radiant[!!-~]2.dck -text
|
||||||
@@ -14102,6 +14119,7 @@ src/main/java/forge/deck/generate/Generate3ColorDeck.java svneol=native#text/pla
|
|||||||
src/main/java/forge/deck/generate/Generate5ColorDeck.java svneol=native#text/plain
|
src/main/java/forge/deck/generate/Generate5ColorDeck.java svneol=native#text/plain
|
||||||
src/main/java/forge/deck/generate/GenerateColoredDeckBase.java -text
|
src/main/java/forge/deck/generate/GenerateColoredDeckBase.java -text
|
||||||
src/main/java/forge/deck/generate/GenerateDeckUtil.java -text
|
src/main/java/forge/deck/generate/GenerateDeckUtil.java -text
|
||||||
|
src/main/java/forge/deck/generate/GenerateMonoColorDeck.java -text
|
||||||
src/main/java/forge/deck/generate/GenerateThemeDeck.java svneol=native#text/plain
|
src/main/java/forge/deck/generate/GenerateThemeDeck.java svneol=native#text/plain
|
||||||
src/main/java/forge/deck/generate/package-info.java svneol=native#text/plain
|
src/main/java/forge/deck/generate/package-info.java svneol=native#text/plain
|
||||||
src/main/java/forge/deck/io/DeckFileHeader.java -text
|
src/main/java/forge/deck/io/DeckFileHeader.java -text
|
||||||
|
|||||||
24
CHANGES.txt
24
CHANGES.txt
@@ -8,12 +8,18 @@ Release Notes:
|
|||||||
|
|
||||||
A new quest world by Serrasmurf based on Ravinca has been added.
|
A new quest world by Serrasmurf based on Ravinca has been added.
|
||||||
|
|
||||||
An effort is being made to implement the split cards (e.g. Fire/Ice) in Forge.
|
An effort is being made to implement the split cards (e.g. Fire/Ice) in Forge. The initial effort to add support for split cards may be considered complete and the relevant branch has reen reintegrated to trunk. Expect some rough edges and incompatibilities along the way.
|
||||||
|
|
||||||
The "Scale Image Larger" option in the preferences should be fixed. It should no longer continue to scale images larger when it is disabled.
|
The "Scale Image Larger" option in the preferences should be fixed. It should no longer continue to scale images larger when it is disabled.
|
||||||
|
|
||||||
The fat packs should now be available for purchase in the quest mode card shop.
|
The fat packs should now be available for purchase in the quest mode card shop.
|
||||||
|
|
||||||
|
Information for non-card items in spell shop are now shown in the card details panel.
|
||||||
|
|
||||||
|
Multiple problems with Convoke have been fixed.
|
||||||
|
|
||||||
|
Forge should now be the Magic rules enforcing program with the most supported cards! That means we finally beat MtGO! MtGO is missing 828 cards. Even subtracting the Power Nine, which were available in the MtGO cube for some time, that's more than we are missing (805) at the time this was written.
|
||||||
|
|
||||||
|
|
||||||
New Cards:
|
New Cards:
|
||||||
|
|
||||||
@@ -28,6 +34,22 @@ Delaying Shield
|
|||||||
Fatal Lore
|
Fatal Lore
|
||||||
Library of Lat-Nam
|
Library of Lat-Nam
|
||||||
Misfortune
|
Misfortune
|
||||||
|
Assault // Battery
|
||||||
|
Fire // Ice
|
||||||
|
Night // Day
|
||||||
|
Trial // Error
|
||||||
|
Wax // Wane
|
||||||
|
Dead // Gone
|
||||||
|
Illusion // Reality
|
||||||
|
Life // Death
|
||||||
|
Pure // Simple
|
||||||
|
Rough // Tumble
|
||||||
|
Supply // Demand
|
||||||
|
Hide // Seek
|
||||||
|
Order // Chaos
|
||||||
|
Pain // Suffering
|
||||||
|
Spite // Malice
|
||||||
|
Stand // Deliver
|
||||||
|
|
||||||
|
|
||||||
New Phenomenons:
|
New Phenomenons:
|
||||||
|
|||||||
@@ -3,9 +3,7 @@ ManaCost:R
|
|||||||
AlternateMode: Split
|
AlternateMode: Split
|
||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ DealDamage | Cost$ R | NumDmg$ 2 | ValidTgts$ Creature,Player | TgtPrompt$ Select target creature or player | SpellDescription$ Assault deals 2 damage to target creature or player.
|
A:SP$ DealDamage | Cost$ R | NumDmg$ 2 | ValidTgts$ Creature,Player | TgtPrompt$ Select target creature or player | SpellDescription$ Assault deals 2 damage to target creature or player.
|
||||||
SetInfo:INV Uncommon
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/assault_battery.jpg
|
||||||
SetInfo:TSB Uncommon
|
|
||||||
SetInfo:HOP Uncommon
|
|
||||||
Oracle:Assault deals 2 damage to target creature or player.
|
Oracle:Assault deals 2 damage to target creature or player.
|
||||||
|
|
||||||
ALTERNATE
|
ALTERNATE
|
||||||
@@ -15,4 +13,6 @@ ManaCost:3 G
|
|||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ Token | Cost$ 3 G | TokenAmount$ 1 | TokenName$ Elephant| TokenTypes$ Creature,Elephant| TokenOwner$ You | TokenColors$ Green | TokenPower$ 3 | TokenToughness$ 3 | TokenImage$ g 3 3 elephant | SpellDescription$ Put a 3/3 green Elephant creature token onto the battlefield.
|
A:SP$ Token | Cost$ 3 G | TokenAmount$ 1 | TokenName$ Elephant| TokenTypes$ Creature,Elephant| TokenOwner$ You | TokenColors$ Green | TokenPower$ 3 | TokenToughness$ 3 | TokenImage$ g 3 3 elephant | SpellDescription$ Put a 3/3 green Elephant creature token onto the battlefield.
|
||||||
Oracle:Put a 3/3 green Elephant creature token onto the battlefield.
|
Oracle:Put a 3/3 green Elephant creature token onto the battlefield.
|
||||||
End
|
SetInfo:TSB Special
|
||||||
|
SetInfo:HOP Uncommon
|
||||||
|
SetInfo:INV Uncommon
|
||||||
17
res/cardsfolder/b/boom_bust.txt
Normal file
17
res/cardsfolder/b/boom_bust.txt
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
Name:Boom
|
||||||
|
ManaCost:1 R
|
||||||
|
AlternateMode: Split
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ Destroy | Cost$ 1 R | TgtPrompt$ Choose target land you control to destroy | ValidTgts$ Land.YouCtrl | SubAbility$ DestroyOpp | SpellDescription$ Destroy target land you control and target land you don't control.
|
||||||
|
SVar:DestroyOpp:DB$ Destroy | TgtPrompt$ Choose target land you don't control to destroy | ValidTgts$ Land.YouDontCtrl
|
||||||
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/boombust.jpg
|
||||||
|
Oracle:Destroy target land you control and target land you don't control.
|
||||||
|
|
||||||
|
ALTERNATE
|
||||||
|
|
||||||
|
Name:Bust
|
||||||
|
ManaCost:5 R
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ DestroyAll | Cost$ 5 R | ValidCards$ Land | SpellDescription$ Destroy all lands.
|
||||||
|
Oracle:Destroy all lands.
|
||||||
|
SetInfo:PLC Rare
|
||||||
17
res/cardsfolder/c/crime_punishment.txt
Normal file
17
res/cardsfolder/c/crime_punishment.txt
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
Name:Crime
|
||||||
|
ManaCost:3 W B
|
||||||
|
AlternateMode: Split
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ ChangeZone | Cost$ 3 W B | Origin$ Graveyard | Destination$ Battlefield | GainControl$ True | TgtPrompt$ Choose target creature or enchantment in an opponent's graveyard | ValidTgts$ Creature.OppCtrl,Enchantment.OppCtrl | SpellDescription$ Put target creature or enchantment card from an opponent's graveyard onto the battlefield under your control.
|
||||||
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/crimepunishment.jpg
|
||||||
|
Oracle:Put target creature or enchantment card from an opponent's graveyard onto the battlefield under your control.
|
||||||
|
|
||||||
|
ALTERNATE
|
||||||
|
|
||||||
|
Name:Punishment
|
||||||
|
ManaCost:X B G
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ DestroyAll | Cost$ X B G | ValidCards$ Artifact.cmcEQX,Creature.cmcEQX,Enchantment.cmcEQX | References$ X | SpellDescription$ Destroy each artifact, creature, and enchantment with converted mana cost X.
|
||||||
|
SVar:X:Count$xPaid
|
||||||
|
Oracle:Destroy each artifact, creature, and enchantment with converted mana cost X.
|
||||||
|
SetInfo:DIS Rare
|
||||||
16
res/cardsfolder/d/dead_gone.txt
Normal file
16
res/cardsfolder/d/dead_gone.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
Name:Dead
|
||||||
|
ManaCost:R
|
||||||
|
AlternateMode: Split
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ DealDamage | Cost$ R | ValidTgts$ Creature | NumDmg$ 2 | SpellDescription$ Dead deals 2 damage to target creature.
|
||||||
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/deadgone.jpg
|
||||||
|
Oracle:Dead deals 2 damage to target creature.
|
||||||
|
|
||||||
|
ALTERNATE
|
||||||
|
|
||||||
|
Name:Gone
|
||||||
|
ManaCost:2 R
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ ChangeZone | Cost$ 2 R | ValidTgts$ Creature.YouDontCtrl | TgtPrompt$ Select target creature you don't control | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return target creature you don't control to its owner's hand.
|
||||||
|
Oracle:Return target creature you don't control to its owner's hand.
|
||||||
|
SetInfo:PLC Common
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
Name:Eye of the Storm
|
Name:Eye of the Storm
|
||||||
ManaCost:5 U U
|
ManaCost:5 U U
|
||||||
Types:Enchantment
|
Types:Enchantment
|
||||||
T:Mode$ SpellCast | ValidCard$ Card.Instant,Card.Sorcery | Execute$ TrigExileSpell | TriggerZones$ Battlefield | TriggerDescription$ Whenever a player casts an instant or sorcery card, exile it. Then that player copies each instant or sorcery card exiled with CARDNAME. For each copy, the player may cast the copy without paying its mana cost.
|
T:Mode$ SpellCast | ValidCard$ Instant.nonToken,Sorcery.nonToken | Execute$ TrigExileSpell | TriggerZones$ Battlefield | TriggerDescription$ Whenever a player casts an instant or sorcery card, exile it. Then that player copies each instant or sorcery card exiled with CARDNAME. For each copy, the player may cast the copy without paying its mana cost.
|
||||||
SVar:TrigExileSpell:AB$ ChangeZone | Cost$ 0 | Defined$ TriggeredCard | Origin$ Stack | Destination$ Exile | Fizzle$ True | RememberChanged$ True | SubAbility$ DBPlaySpell
|
SVar:TrigExileSpell:AB$ ChangeZone | Cost$ 0 | Defined$ TriggeredCard | Origin$ Stack | Destination$ Exile | Fizzle$ True | RememberChanged$ True | SubAbility$ DBPlaySpell
|
||||||
SVar:DBPlaySpell:DB$ RepeatEach | UseImprinted$ True | RepeatCards$ Card.IsRemembered | ChooseOrder$ True | Zone$ Exile | RepeatSubAbility$ DBPlay
|
SVar:DBPlaySpell:DB$ RepeatEach | UseImprinted$ True | RepeatCards$ Card.IsRemembered | ChooseOrder$ True | Zone$ Exile | RepeatSubAbility$ DBPlay
|
||||||
SVar:DBPlay:DB$ Play | Defined$ Imprinted | Controller$ TriggeredCardController | WithoutManaCost$ True | CopyCard$ True | Optional$ True
|
SVar:DBPlay:DB$ Play | Defined$ Imprinted | Controller$ TriggeredCardController | WithoutManaCost$ True | CopyCard$ True | Optional$ True
|
||||||
|
|||||||
@@ -3,9 +3,7 @@ ManaCost:1 R
|
|||||||
AlternateMode: Split
|
AlternateMode: Split
|
||||||
Types:Instant
|
Types:Instant
|
||||||
A:SP$ DealDamage | Cost$ 1 R | ValidTgts$ Creature,Player | TgtPrompt$ Select target creature or player to distribute damage to | NumDmg$ 2 | TargetMin$ 1 | TargetMax$ 2 | DividedAsYouChoose$ 2 | SpellDescription$ Fire deals 2 damage divided as you choose among one or two target creatures and/or players.
|
A:SP$ DealDamage | Cost$ 1 R | ValidTgts$ Creature,Player | TgtPrompt$ Select target creature or player to distribute damage to | NumDmg$ 2 | TargetMin$ 1 | TargetMax$ 2 | DividedAsYouChoose$ 2 | SpellDescription$ Fire deals 2 damage divided as you choose among one or two target creatures and/or players.
|
||||||
SetInfo:APC Uncommon
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/fire_ice.jpg
|
||||||
SetInfo:COM Uncommon
|
|
||||||
SetInfo:DDJ Uncommon
|
|
||||||
Oracle:Fire deals 2 damage divided as you choose among one or two target creatures and/or players.
|
Oracle:Fire deals 2 damage divided as you choose among one or two target creatures and/or players.
|
||||||
|
|
||||||
ALTERNATE
|
ALTERNATE
|
||||||
@@ -16,4 +14,6 @@ Types:Instant
|
|||||||
A:SP$ Tap | Cost$ 1 U | ValidTgts$ Permanent | TgtPrompt$ Select target permanent | SubAbility$ DBDraw | SpellDescription$ Tap target permanent. Draw a card.
|
A:SP$ Tap | Cost$ 1 U | ValidTgts$ Permanent | TgtPrompt$ Select target permanent | SubAbility$ DBDraw | SpellDescription$ Tap target permanent. Draw a card.
|
||||||
SVar:DBDraw:DB$ Draw | NumCards$ 1
|
SVar:DBDraw:DB$ Draw | NumCards$ 1
|
||||||
Oracle:Tap target permanent.\nDraw a card.
|
Oracle:Tap target permanent.\nDraw a card.
|
||||||
End
|
SetInfo:APC Uncommon
|
||||||
|
SetInfo:COM Uncommon
|
||||||
|
SetInfo:DDJ Uncommon
|
||||||
20
res/cardsfolder/h/hide_seek.txt
Normal file
20
res/cardsfolder/h/hide_seek.txt
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
Name:Hide
|
||||||
|
ManaCost:W R
|
||||||
|
AlternateMode: Split
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ ChangeZone | Cost$ W R | ValidTgts$ Artifact,Enchantment | TgtPrompt$ Select target artifact or enchantment | Origin$ Battlefield | Destination$ Library | LibraryPosition$ -1 | SpellDescription$ Put target artifact or enchantment on the bottom of its owner's library.
|
||||||
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/hideseek.jpg
|
||||||
|
|
||||||
|
Oracle:Put target artifact or enchantment on the bottom of its owner's library.
|
||||||
|
|
||||||
|
ALTERNATE
|
||||||
|
|
||||||
|
Name:Seek
|
||||||
|
ManaCost:W B
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ ChangeZone | Cost$ W B | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | Origin$ Library | DefinedPlayer$ Targeted | Chooser$ You | Destination$ Exile | Changetype$ Card | ChangeNum$ 1 | RememberChanged$ True | SubAbility$ DBGainLife | SpellDescription$ Search target opponent's library for a card and exile it. You gain life equal to its converted mana cost. Then that player shuffles his or her library.
|
||||||
|
SVar:DBGainLife:DB$ GainLife | LifeAmount$ X | References$ X | SubAbility$ DBCleanup
|
||||||
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
|
SVar:X:Remembered$CardManaCost
|
||||||
|
Oracle:Search target opponent's library for a card and exile it. You gain life equal to its converted mana cost. Then that player shuffles his or her library.
|
||||||
|
SetInfo:DIS Rare
|
||||||
17
res/cardsfolder/i/illusion_reality.txt
Normal file
17
res/cardsfolder/i/illusion_reality.txt
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
Name:Illusion
|
||||||
|
ManaCost:U
|
||||||
|
AlternateMode: Split
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ ChooseColor | Cost$ U | Defined$ You | SubAbility$ Animate | SpellDescription$ Target spell or permanent becomes the color of your choice until end of turn.
|
||||||
|
SVar:Animate:DB$ Animate | ValidTgts$ Card | TgtPrompt$ Select target spell or permanent to change the color of | TgtZone$ Stack,Battlefield | Colors$ ChosenColor | OverwriteColors$ True
|
||||||
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/illusion_reality.jpg
|
||||||
|
Oracle:Target spell or permanent becomes the color of your choice until end of turn.
|
||||||
|
|
||||||
|
ALTERNATE
|
||||||
|
|
||||||
|
Name:Reality
|
||||||
|
ManaCost:2 G
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ Destroy | Cost$ 2 G | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | SpellDescription$ Destroy target artifact.
|
||||||
|
Oracle:Destroy target artifact.
|
||||||
|
SetInfo:APC Uncommon
|
||||||
19
res/cardsfolder/l/life_death.txt
Normal file
19
res/cardsfolder/l/life_death.txt
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
Name:Life
|
||||||
|
ManaCost:G
|
||||||
|
AlternateMode: Split
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ AnimateAll | Cost$ G | Power$ 1 | Toughness$ 1 | Types$ Creature | ValidCards$ Land.YouCtrl | SpellDescription$ All lands you control become 1/1 creatures until end of turn. They're still lands.
|
||||||
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/life_death.jpg
|
||||||
|
Oracle:All lands you control become 1/1 creatures until end of turn. They're still lands.
|
||||||
|
|
||||||
|
ALTERNATE
|
||||||
|
|
||||||
|
Name:Death
|
||||||
|
ManaCost:1 B
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ ChangeZone | Cost$ 1 B | Origin$ Graveyard | Destination$ Battlefield | ValidTgts$ Creature.YouOwn | TgtPrompt$ Choose target creature card in your graveyard | GainControl$ True | SubAbility$ DBLoseLifeYou | SpellDescription$ Return target creature card from your graveyard to the battlefield. You lose life equal to its converted mana cost.
|
||||||
|
SVar:DBLoseLifeYou:DB$ LoseLife | Defined$ You | LifeAmount$ X | References$ X
|
||||||
|
SVar:X:Targeted$CardManaCost
|
||||||
|
Oracle:Return target creature card from your graveyard to the battlefield. You lose life equal to its converted mana cost.
|
||||||
|
SetInfo:APC Uncommon
|
||||||
|
SetInfo:DDJ Uncommon
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
Name:Murderous Spoils
|
Name:Murderous Spoils
|
||||||
ManaCost:5 B
|
ManaCost:5 B
|
||||||
Types:Instant
|
Types:Instant
|
||||||
A:SP$ Destroy | Cost$ 5 B | ValidTgts$ Creature | TgtPrompt$ Select target creature | SubAbility$ StealEquip | NoRegen$ True | SpellDescription$ Destroy target nonblack creature. It can't be regenerated. You gain control of all Equipment that was attached to it. (This effect lasts indefinitely.)
|
A:SP$ Destroy | Cost$ 5 B | ValidTgts$ Creature.nonBlack | TgtPrompt$ Select target non-black creature | SubAbility$ StealEquip | NoRegen$ True | SpellDescription$ Destroy target nonblack creature. It can't be regenerated. You gain control of all Equipment that was attached to it. (This effect lasts indefinitely.)
|
||||||
SVar:StealEquip:DB$ GainControl | AllValid$ Targeted.Equipment+Attached
|
SVar:StealEquip:DB$ GainControl | AllValid$ Targeted.Equipment+Attached
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/murderous_spoils.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/murderous_spoils.jpg
|
||||||
Oracle:Destroy target nonblack creature. It can't be regenerated. You gain control of all Equipment that was attached to it. (This effect lasts indefinitely.)
|
Oracle:Destroy target nonblack creature. It can't be regenerated. You gain control of all Equipment that was attached to it. (This effect lasts indefinitely.)
|
||||||
|
|||||||
16
res/cardsfolder/n/night_day.txt
Normal file
16
res/cardsfolder/n/night_day.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
Name:Night
|
||||||
|
ManaCost:B
|
||||||
|
AlternateMode: Split
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ Pump | Cost$ B | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ -1 | NumDef$ -1 | IsCurse$ True | SpellDescription$ Target creature gets -1/-1 until end of turn.
|
||||||
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/night_day.jpg
|
||||||
|
Oracle:Target creature gets -1/-1 until end of turn.
|
||||||
|
|
||||||
|
ALTERNATE
|
||||||
|
|
||||||
|
Name:Day
|
||||||
|
ManaCost:2 W
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ PumpAll | Cost$ 1 W | ValidTgts$ Player | TgtPrompt$ Select target player | ValidCards$ Creature | NumAtt$ +1 | NumDef$ +1 | SpellDescription$ Creatures target player controls get +1/+1 until end of turn.
|
||||||
|
Oracle:Creatures target player controls get +1/+1 until end of turn.
|
||||||
|
SetInfo:APC Uncommon
|
||||||
20
res/cardsfolder/o/order_chaos.txt
Normal file
20
res/cardsfolder/o/order_chaos.txt
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
Name:Order
|
||||||
|
ManaCost:3 W
|
||||||
|
AlternateMode: Split
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ ChangeZone | Cost$ 3 W | ValidTgts$ Creature.attacking | TgtPrompt$ Select target attacking creature | Origin$ Battlefield | Destination$ Exile | SpellDescription$ Exile target attacking creature.
|
||||||
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/order_chaos.jpg
|
||||||
|
|
||||||
|
Oracle:Exile target attacking creature.
|
||||||
|
|
||||||
|
ALTERNATE
|
||||||
|
|
||||||
|
Name:Chaos
|
||||||
|
ManaCost:2 R
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ Effect | Cost$ 2 R | Name$ Chaos Effect | StaticAbilities$ KWPump | AILogic$ Evasion | SpellDescription$ Creatures can't block this turn.
|
||||||
|
SVar:KWPump:Mode$ Continuous | EffectZone$ Command | AffectedZone$ Battlefield | Affected$ Creature | AddHiddenKeyword$ CARDNAME can't block. | Description$ Creatures can't block this turn.
|
||||||
|
SVar:RemAIDeck:True
|
||||||
|
Oracle:Creatures can't block this turn.
|
||||||
|
SetInfo:APC Uncommon
|
||||||
|
SetInfo:HOP Uncommon
|
||||||
17
res/cardsfolder/p/pain_suffering.txt
Normal file
17
res/cardsfolder/p/pain_suffering.txt
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
Name:Pain
|
||||||
|
ManaCost:B
|
||||||
|
AlternateMode: Split
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ Discard | Cost$ B | ValidTgts$ Player | NumCards$ 1 | Mode$ TgtChoose | SpellDescription$ Target player discards a card.
|
||||||
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/pain_suffering.jpg
|
||||||
|
Oracle:Target player discards a card.
|
||||||
|
|
||||||
|
ALTERNATE
|
||||||
|
|
||||||
|
Name:Suffering
|
||||||
|
ManaCost:3 R
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ Destroy | Cost$ 3 R | ValidTgts$ Land | TgtPrompt$ Select target land | SpellDescription$ Destroy target land.
|
||||||
|
Oracle:Destroy target land.
|
||||||
|
SetInfo:DDH Uncommon
|
||||||
|
SetInfo:INV Uncommon
|
||||||
16
res/cardsfolder/p/pure_simple.txt
Normal file
16
res/cardsfolder/p/pure_simple.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
Name:Pure
|
||||||
|
ManaCost:1 R G
|
||||||
|
AlternateMode: Split
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ Destroy | Cost$ 1 R G | ValidTgts$ Permanent.MultiColor | TgtPrompt$ Select target multicolored permanent | SpellDescription$ Destroy target multicolored permanent.
|
||||||
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/puresimple.jpg
|
||||||
|
Oracle:Destroy target multicolored permanent.
|
||||||
|
|
||||||
|
ALTERNATE
|
||||||
|
|
||||||
|
Name:Simple
|
||||||
|
ManaCost:1 W G
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ DestroyAll | Cost$ 1 W G | ValidCards$ Aura,Equipment | SpellDescription$ Destroy all Auras and Equipment.
|
||||||
|
Oracle:Destroy all Auras and Equipment.
|
||||||
|
SetInfo:DIS Uncommon
|
||||||
16
res/cardsfolder/r/rough_tumble.txt
Normal file
16
res/cardsfolder/r/rough_tumble.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
Name:Rough
|
||||||
|
ManaCost:1 R
|
||||||
|
AlternateMode: Split
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ DamageAll | Cost$ 1 R | ValidCards$ Creature.withoutFlying | NumDmg$ 2 | SpellDescription$ Rough deals 2 damage to each creature without flying.
|
||||||
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/rough_tumble.jpg
|
||||||
|
Oracle:Rough deals 2 damage to each creature without flying.
|
||||||
|
|
||||||
|
ALTERNATE
|
||||||
|
|
||||||
|
Name:Tumble
|
||||||
|
ManaCost:5 R
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ DamageAll | Cost$ 5 R | ValidCards$ Creature.withFlying | NumDmg$ 6 | SpellDescription$ Tumble deals 6 damage to each creature with flying.
|
||||||
|
Oracle:Tumble deals 6 damage to each creature with flying.
|
||||||
|
SetInfo:PLC Uncommon
|
||||||
@@ -4,7 +4,7 @@ Types:Legendary Creature Human Rogue
|
|||||||
PT:3/1
|
PT:3/1
|
||||||
# Make Svars for granting abilities and triggers on clones distinct to avoid SVars getting overwritten when cloning a clone
|
# Make Svars for granting abilities and triggers on clones distinct to avoid SVars getting overwritten when cloning a clone
|
||||||
K:ETBReplacement:Copy:ChooseCreature:Optional
|
K:ETBReplacement:Copy:ChooseCreature:Optional
|
||||||
SVar:ChooseCreature:AB$ ChooseCard | Cost$ 0 | Defined$ You | Amount$ 1 | Choices$ Creature.Other | SubAbility$ DBCopy | RememberChosen$ True | SpellDescription$ You may have CARDNAME enter the battlefield as a copy of any creature on the battlefield, except its name is still CARDNAME, it's legendary in addition to its other types, and it gains "2 U U: Return CARDNAME to its owner's hand at the beginning of the next end step."
|
SVar:ChooseCreature:DB$ ChooseCard | Defined$ You | Amount$ 1 | Choices$ Creature.Other | SubAbility$ DBCopy | RememberChosen$ True | SpellDescription$ You may have CARDNAME enter the battlefield as a copy of any creature on the battlefield, except its name is still CARDNAME, it's legendary in addition to its other types, and it gains "2 U U: Return CARDNAME to its owner's hand at the beginning of the next end step."
|
||||||
SVar:DBCopy:DB$ Clone | Defined$ Remembered | KeepName$ True | AddTypes$ Legendary | AddAbilities$ ReturnSakashima | AddSVars$ TrigReturnSak
|
SVar:DBCopy:DB$ Clone | Defined$ Remembered | KeepName$ True | AddTypes$ Legendary | AddAbilities$ ReturnSakashima | AddSVars$ TrigReturnSak
|
||||||
SVar:ReturnSakashima:AB$ DelayedTrigger | Cost$ 2 U U | Mode$ Phase | Phase$ End of Turn | Execute$ TrigReturnSak | SpellDescription$ Return CARDNAME to it's owners hand at the beginning of the next end step.
|
SVar:ReturnSakashima:AB$ DelayedTrigger | Cost$ 2 U U | Mode$ Phase | Phase$ End of Turn | Execute$ TrigReturnSak | SpellDescription$ Return CARDNAME to it's owners hand at the beginning of the next end step.
|
||||||
SVar:TrigReturnSak:AB$ChangeZone | Cost$ 0 | Defined$ Self | Origin$ Battlefield | Destination$ Hand
|
SVar:TrigReturnSak:AB$ChangeZone | Cost$ 0 | Defined$ Self | Origin$ Battlefield | Destination$ Hand
|
||||||
|
|||||||
17
res/cardsfolder/s/spite_malice.txt
Normal file
17
res/cardsfolder/s/spite_malice.txt
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
Name:Spite
|
||||||
|
ManaCost:3 U
|
||||||
|
AlternateMode: Split
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ Counter | Cost$ 3 U | TargetType$ Spell | TgtPrompt$ Select target nonCreature spell | ValidTgts$ Card.nonCreature | SpellDescription$ Counter target noncreature spell.
|
||||||
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/spite_malice.jpg
|
||||||
|
Oracle:Counter target noncreature spell.
|
||||||
|
|
||||||
|
ALTERNATE
|
||||||
|
|
||||||
|
Name:Malice
|
||||||
|
ManaCost:3 B
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ Destroy | Cost$ 3 B | ValidTgts$ Creature.nonBlack | TgtPrompt$ Select target nonblack creature | NoRegen$ True | SpellDescription$ Destroy target nonblack creature. It can't be regenerated.
|
||||||
|
Oracle:Destroy target nonblack creature. It can't be regenerated.
|
||||||
|
SetInfo:DDH Uncommon
|
||||||
|
SetInfo:INV Uncommon
|
||||||
17
res/cardsfolder/s/stand_deliver.txt
Normal file
17
res/cardsfolder/s/stand_deliver.txt
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
Name:Stand
|
||||||
|
ManaCost:W
|
||||||
|
AlternateMode: Split
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ PreventDamage | Cost$ W | ValidTgts$ Creature | Amount$ 2 | TgtPrompt$ Select target creature | SpellDescription$ Prevent the next 2 damage that would be dealt to target creature this turn.
|
||||||
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/stand_deliver.jpg
|
||||||
|
|
||||||
|
Oracle:Prevent the next 2 damage that would be dealt to target creature this turn.
|
||||||
|
|
||||||
|
ALTERNATE
|
||||||
|
|
||||||
|
Name:Deliver
|
||||||
|
ManaCost:2 U
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ ChangeZone | Cost$ 2 U | ValidTgts$ Permanent | TgtPrompt$ Select target permanent | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return target permanent to its owner's hand.
|
||||||
|
Oracle:Return target permanent to its owner's hand.
|
||||||
|
SetInfo:INV Uncommon
|
||||||
17
res/cardsfolder/s/supply_demand.txt
Normal file
17
res/cardsfolder/s/supply_demand.txt
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
Name:Supply
|
||||||
|
ManaCost:X W G
|
||||||
|
AlternateMode: Split
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ Token | Cost$ X W G | TokenAmount$ X | References$ X | TokenName$ Saproling | TokenTypes$ Creature,Saproling | TokenOwner$ You | TokenColors$ Green | TokenPower$ 1 | TokenToughness$ 1 | SpellDescription$ Put X 1/1 green Saproling creature tokens onto the battlefield.
|
||||||
|
SVar:X:Count$xPaid
|
||||||
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/supplydemand.jpg
|
||||||
|
Oracle:Put X 1/1 green Saproling creature tokens onto the battlefield.
|
||||||
|
|
||||||
|
ALTERNATE
|
||||||
|
|
||||||
|
Name:Demand
|
||||||
|
ManaCost:1 W U
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ ChangeZone | Cost$ 1 W U | Origin$ Library | Destination$ Hand | ChangeType$ Card.MultiColor | ChangeNum$ 1 | SpellDescription$ Search your library for a multicolored card, reveal it, and put it into your hand. Then shuffle your library.
|
||||||
|
Oracle:Search your library for a multicolored card, reveal it, and put it into your hand. Then shuffle your library.
|
||||||
|
SetInfo:DIS Uncommon
|
||||||
18
res/cardsfolder/t/trial_error.txt
Normal file
18
res/cardsfolder/t/trial_error.txt
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
Name:Trial
|
||||||
|
ManaCost:W U
|
||||||
|
AlternateMode: Split
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ ChangeZoneAll | Cost$ W U | ValidTgts$ Creature | TgtPrompt$ Select target creature | RememberTargets$ True | ChangeType$ Creature.blockingRemembered,Creature.isBlockedByRemembered | Origin$ Battlefield | Destination$ Hand | SubAbility$ DBCleanup | SpellDescription$ Return all creatures blocking or blocked by target creature to their owner's hand.
|
||||||
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
|
SVar:RemAIDeck:True
|
||||||
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/trialerror.jpg
|
||||||
|
Oracle:Return all creatures blocking or blocked by target creature to their owner's hand.
|
||||||
|
|
||||||
|
ALTERNATE
|
||||||
|
|
||||||
|
Name:Error
|
||||||
|
ManaCost:U B
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ Counter | Cost$ U B | TargetType$ Spell | TgtPrompt$ Select target multicolored spell | ValidTgts$ Card.MultiColor | SpellDescription$ Counter target multicolored spell.
|
||||||
|
Oracle:Counter target multicolored spell.
|
||||||
|
SetInfo:DIS Uncommon
|
||||||
17
res/cardsfolder/w/wax_wane.txt
Normal file
17
res/cardsfolder/w/wax_wane.txt
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
Name:Wax
|
||||||
|
ManaCost:G
|
||||||
|
AlternateMode: Split
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ Pump | Cost$ G | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ +2 | NumDef$ +2 | SpellDescription$ Target creature gets +2/+2 until end of turn.
|
||||||
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/wax_wane.jpg
|
||||||
|
Oracle:Target creature gets +2/+2 until end of turn.
|
||||||
|
|
||||||
|
ALTERNATE
|
||||||
|
|
||||||
|
Name:Wane
|
||||||
|
ManaCost:W
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ Destroy | Cost$ W | ValidTgts$ Enchantment | TgtPrompt$ Select target enchantment | SpellDescription$ Destroy target enchantment.
|
||||||
|
Oracle:Destroy target enchantment.
|
||||||
|
SetInfo:ARC Uncommon
|
||||||
|
SetInfo:INV Uncommon
|
||||||
42
res/quest/duels/Quicksilver 3.dck
Normal file
42
res/quest/duels/Quicksilver 3.dck
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
[duel]
|
||||||
|
[metadata]
|
||||||
|
Name=Quicksilver 3
|
||||||
|
Title=Quicksilver
|
||||||
|
Difficulty=very hard
|
||||||
|
Description=WUG Hypergenesis/Show and Tell deck with huge creatures
|
||||||
|
Icon=Quicksilver.jpg
|
||||||
|
Deck Type=constructed
|
||||||
|
[main]
|
||||||
|
2 Tropical Island
|
||||||
|
3 Tundra
|
||||||
|
4 Misty Rainforest
|
||||||
|
3 Polluted Delta
|
||||||
|
3 Scalding Tarn
|
||||||
|
2 Flooded Strand
|
||||||
|
1 Island
|
||||||
|
1 Plains
|
||||||
|
4 Elvish Spirit Guide
|
||||||
|
4 Simian Spirit Guide
|
||||||
|
2 Hypergenesis
|
||||||
|
4 Ardent Plea
|
||||||
|
4 Shardless Agent
|
||||||
|
4 Show and Tell
|
||||||
|
1 Angel of Serenity
|
||||||
|
1 Angel of Despair
|
||||||
|
1 Avacyn, Angel of Hope
|
||||||
|
1 Blazing Archon
|
||||||
|
1 Blightsteel Colossus
|
||||||
|
1 Bogardan Hellkite
|
||||||
|
1 Elesh Norn, Grand Cenobite
|
||||||
|
1 Emrakul, the Aeons Torn
|
||||||
|
1 Gisela, Blade of Goldnight
|
||||||
|
1 Iona, Shield of Emeria
|
||||||
|
1 Jin-Gitaxias, Core Augur
|
||||||
|
1 Karrthus, Tyrant of Jund
|
||||||
|
2 Maelstrom Wanderer
|
||||||
|
1 Molten Primordial
|
||||||
|
1 Pelakka Wurm
|
||||||
|
1 Platinum Emperion
|
||||||
|
1 Progenitus
|
||||||
|
1 Thraximundar
|
||||||
|
[sideboard]
|
||||||
@@ -27,6 +27,7 @@ http://www.cardforge.org/fpics/questAvatars/Buffy.jpg
|
|||||||
http://www.cardforge.org/fpics/questAvatars/Bushwhacked.jpg
|
http://www.cardforge.org/fpics/questAvatars/Bushwhacked.jpg
|
||||||
http://www.cardforge.org/fpics/questAvatars/C3PO.jpg
|
http://www.cardforge.org/fpics/questAvatars/C3PO.jpg
|
||||||
http://www.cardforge.org/fpics/questAvatars/Cable.jpg
|
http://www.cardforge.org/fpics/questAvatars/Cable.jpg
|
||||||
|
http://www.cardforge.org/fpics/questAvatars/Carnage.jpg
|
||||||
http://www.cardforge.org/fpics/questAvatars/Captain%20America.jpg
|
http://www.cardforge.org/fpics/questAvatars/Captain%20America.jpg
|
||||||
http://www.cardforge.org/fpics/questAvatars/Catwoman.jpg
|
http://www.cardforge.org/fpics/questAvatars/Catwoman.jpg
|
||||||
http://www.cardforge.org/fpics/questAvatars/Chief_Wiggum.jpg
|
http://www.cardforge.org/fpics/questAvatars/Chief_Wiggum.jpg
|
||||||
@@ -145,6 +146,7 @@ http://www.cardforge.org/fpics/questAvatars/Princess%20Selenia.jpg
|
|||||||
http://www.cardforge.org/fpics/questAvatars/Private%20Domain.jpg
|
http://www.cardforge.org/fpics/questAvatars/Private%20Domain.jpg
|
||||||
http://www.cardforge.org/fpics/questAvatars/Professor%20X.jpg
|
http://www.cardforge.org/fpics/questAvatars/Professor%20X.jpg
|
||||||
http://www.cardforge.org/fpics/questAvatars/Quest%20for%20Ulas%20Temple.jpg
|
http://www.cardforge.org/fpics/questAvatars/Quest%20for%20Ulas%20Temple.jpg
|
||||||
|
http://www.cardforge.org/fpics/questAvatars/Quicksilver.jpg
|
||||||
http://www.cardforge.org/fpics/questAvatars/R2-D2.jpg
|
http://www.cardforge.org/fpics/questAvatars/R2-D2.jpg
|
||||||
http://www.cardforge.org/fpics/questAvatars/Radagast.jpg
|
http://www.cardforge.org/fpics/questAvatars/Radagast.jpg
|
||||||
http://www.cardforge.org/fpics/questAvatars/Radiant.jpg
|
http://www.cardforge.org/fpics/questAvatars/Radiant.jpg
|
||||||
|
|||||||
@@ -1632,6 +1632,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
return this.getCharacteristics().getManaCost();
|
return this.getCharacteristics().getManaCost();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* addColor.
|
* addColor.
|
||||||
@@ -9194,7 +9195,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
System.out.println("Trying to sacrifice immutables: " + this);
|
System.out.println("Trying to sacrifice immutables: " + this);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (source != null && !getController().isOpponentOf(source.getActivatingPlayer())
|
if (source != null && getController().isOpponentOf(source.getActivatingPlayer())
|
||||||
&& getController().hasKeyword("Spells and abilities your opponents control can't cause you to sacrifice permanents.")) {
|
&& getController().hasKeyword("Spells and abilities your opponents control can't cause you to sacrifice permanents.")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import forge.card.ability.effects.ChangeZoneAllEffect;
|
|||||||
import forge.card.ability.effects.ChangeZoneEffect;
|
import forge.card.ability.effects.ChangeZoneEffect;
|
||||||
import forge.card.ability.effects.ManaEffect;
|
import forge.card.ability.effects.ManaEffect;
|
||||||
import forge.card.ability.effects.ManaReflectedEffect;
|
import forge.card.ability.effects.ManaReflectedEffect;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
import forge.card.cardfactory.CardFactory;
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.spellability.AbilityActivated;
|
import forge.card.spellability.AbilityActivated;
|
||||||
import forge.card.spellability.AbilityManaPart;
|
import forge.card.spellability.AbilityManaPart;
|
||||||
@@ -50,7 +50,7 @@ public class AbilityApiBased extends AbilityActivated {
|
|||||||
public AbilityActivated getCopy() {
|
public AbilityActivated getCopy() {
|
||||||
Target tgt = getTarget() == null ? null : new Target(getTarget());
|
Target tgt = getTarget() == null ? null : new Target(getTarget());
|
||||||
AbilityActivated res = new AbilityApiBased(api, getSourceCard(), getPayCosts(), tgt, params);
|
AbilityActivated res = new AbilityApiBased(api, getSourceCard(), getPayCosts(), tgt, params);
|
||||||
CardFactoryUtil.copySpellAbility(this, res);
|
CardFactory.copySpellAbility(this, res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.CardLists;
|
import forge.CardLists;
|
||||||
|
import forge.CardPredicates;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
@@ -21,42 +22,8 @@ public class SacrificeAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canPlayAI(AIPlayer ai, SpellAbility sa) {
|
protected boolean canPlayAI(AIPlayer ai, SpellAbility sa) {
|
||||||
boolean chance = sacrificeTgtAI(ai, sa);
|
|
||||||
|
|
||||||
// Some additional checks based on what is being sacrificed, and who is
|
return sacrificeTgtAI(ai, sa);
|
||||||
// sacrificing
|
|
||||||
final Target tgt = sa.getTarget();
|
|
||||||
if (tgt != null) {
|
|
||||||
final String valid = sa.getParam("SacValid");
|
|
||||||
String num = sa.getParam("Amount");
|
|
||||||
num = (num == null) ? "1" : num;
|
|
||||||
final int amount = AbilityUtils.calculateAmount(sa.getSourceCard(), num, sa);
|
|
||||||
|
|
||||||
List<Card> list =
|
|
||||||
CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid.split(","), sa.getActivatingPlayer(), sa.getSourceCard());
|
|
||||||
|
|
||||||
if (list.size() == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Card source = sa.getSourceCard();
|
|
||||||
if (num.equals("X") && source.getSVar(num).equals("Count$xPaid")) {
|
|
||||||
// Set PayX here to maximum value.
|
|
||||||
final int xPay = Math.min(ComputerUtilMana.determineLeftoverMana(sa, ai), amount);
|
|
||||||
source.setSVar("PayX", Integer.toString(xPay));
|
|
||||||
}
|
|
||||||
|
|
||||||
final int half = (amount / 2) + (amount % 2); // Half of amount
|
|
||||||
// rounded up
|
|
||||||
|
|
||||||
// If the Human has at least half rounded up of the amount to be
|
|
||||||
// sacrificed, cast the spell
|
|
||||||
if (list.size() < half) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return chance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -83,16 +50,49 @@ public class SacrificeAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
private boolean sacrificeTgtAI(final Player ai, final SpellAbility sa) {
|
private boolean sacrificeTgtAI(final Player ai, final SpellAbility sa) {
|
||||||
|
|
||||||
final Card card = sa.getSourceCard();
|
final Card source = sa.getSourceCard();
|
||||||
final Target tgt = sa.getTarget();
|
final Target tgt = sa.getTarget();
|
||||||
|
final boolean destroy = sa.hasParam("Destroy");
|
||||||
|
|
||||||
Player opp = ai.getOpponent();
|
Player opp = ai.getOpponent();
|
||||||
if (tgt != null) {
|
if (tgt != null) {
|
||||||
tgt.resetTargets();
|
tgt.resetTargets();
|
||||||
if (opp.canBeTargetedBy(sa)) {
|
if (!opp.canBeTargetedBy(sa)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
tgt.addTarget(opp);
|
tgt.addTarget(opp);
|
||||||
return true;
|
final String valid = sa.getParam("SacValid");
|
||||||
|
String num = sa.getParam("Amount");
|
||||||
|
num = (num == null) ? "1" : num;
|
||||||
|
final int amount = AbilityUtils.calculateAmount(sa.getSourceCard(), num, sa);
|
||||||
|
|
||||||
|
List<Card> list =
|
||||||
|
CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid.split(","), sa.getActivatingPlayer(), sa.getSourceCard());
|
||||||
|
if (!destroy) {
|
||||||
|
list = CardLists.filter(list, CardPredicates.canBeSacrificedBy(sa));
|
||||||
} else {
|
} else {
|
||||||
|
if (!CardLists.getKeyword(list, "Indestructible").isEmpty()) {
|
||||||
|
// human can choose to destroy indestructibles
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list.size() == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num.equals("X") && source.getSVar(num).equals("Count$xPaid")) {
|
||||||
|
// Set PayX here to maximum value.
|
||||||
|
final int xPay = Math.min(ComputerUtilMana.determineLeftoverMana(sa, ai), amount);
|
||||||
|
source.setSVar("PayX", Integer.toString(xPay));
|
||||||
|
}
|
||||||
|
|
||||||
|
final int half = (amount / 2) + (amount % 2); // Half of amount
|
||||||
|
// rounded up
|
||||||
|
|
||||||
|
// If the Human has at least half rounded up of the amount to be
|
||||||
|
// sacrificed, cast the spell
|
||||||
|
if (!sa.isTrigger() && list.size() < half) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,9 +109,8 @@ public class SacrificeAi extends SpellAbilityAi {
|
|||||||
// TODO: Cast if the type is favorable: my "worst" valid is
|
// TODO: Cast if the type is favorable: my "worst" valid is
|
||||||
// worse than his "worst" valid
|
// worse than his "worst" valid
|
||||||
final String num = sa.hasParam("Amount") ? sa.getParam("Amount") : "1";
|
final String num = sa.hasParam("Amount") ? sa.getParam("Amount") : "1";
|
||||||
int amount = AbilityUtils.calculateAmount(card, num, sa);
|
int amount = AbilityUtils.calculateAmount(source, num, sa);
|
||||||
|
|
||||||
final Card source = sa.getSourceCard();
|
|
||||||
if (num.equals("X") && source.getSVar(num).equals("Count$xPaid")) {
|
if (num.equals("X") && source.getSVar(num).equals("Count$xPaid")) {
|
||||||
// Set PayX here to maximum value.
|
// Set PayX here to maximum value.
|
||||||
amount = Math.min(ComputerUtilMana.determineLeftoverMana(sa, ai), amount);
|
amount = Math.min(ComputerUtilMana.determineLeftoverMana(sa, ai), amount);
|
||||||
|
|||||||
@@ -1,18 +1,31 @@
|
|||||||
package forge.card.ability.ai;
|
package forge.card.ability.ai;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import forge.Card;
|
||||||
|
import forge.CardLists;
|
||||||
|
import forge.Singletons;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.spellability.AbilitySub;
|
import forge.card.spellability.AbilitySub;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
|
import forge.game.zone.ZoneType;
|
||||||
|
|
||||||
public class UntapAllAi extends SpellAbilityAi {
|
public class UntapAllAi extends SpellAbilityAi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canPlayAI(AIPlayer aiPlayer, SpellAbility sa) {
|
protected boolean canPlayAI(AIPlayer aiPlayer, SpellAbility sa) {
|
||||||
// check SubAbilities DoTrigger?
|
final Card source = sa.getSourceCard();
|
||||||
|
|
||||||
final AbilitySub abSub = sa.getSubAbility();
|
final AbilitySub abSub = sa.getSubAbility();
|
||||||
if (abSub != null) {
|
if (abSub != null) {
|
||||||
return true;
|
String valid = "";
|
||||||
|
List<Card> list = Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield);
|
||||||
|
if (sa.hasParam("ValidCards")) {
|
||||||
|
valid = sa.getParam("ValidCards");
|
||||||
|
}
|
||||||
|
list = CardLists.getValidCards(list, valid.split(","), source.getController(), source);
|
||||||
|
return !list.isEmpty();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import forge.Command;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityEffect;
|
import forge.card.ability.SpellAbilityEffect;
|
||||||
|
import forge.card.cardfactory.CardFactory;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
import forge.card.cardfactory.CardFactoryUtil;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
@@ -122,7 +123,7 @@ public class CloneEffect extends SpellAbilityEffect {
|
|||||||
stateToCopy = cardToCopy.getCurState();
|
stateToCopy = cardToCopy.getCurState();
|
||||||
}
|
}
|
||||||
|
|
||||||
CardFactoryUtil.copyState(cardToCopy, stateToCopy, tgtCard);
|
CardFactory.copyState(cardToCopy, stateToCopy, tgtCard);
|
||||||
// must call this before addAbilityFactoryAbilities so cloned added abilities are handled correctly
|
// must call this before addAbilityFactoryAbilities so cloned added abilities are handled correctly
|
||||||
addExtraCharacteristics(tgtCard, sa, origSVars);
|
addExtraCharacteristics(tgtCard, sa, origSVars);
|
||||||
CardFactoryUtil.addAbilityFactoryAbilities(tgtCard);
|
CardFactoryUtil.addAbilityFactoryAbilities(tgtCard);
|
||||||
@@ -140,7 +141,7 @@ public class CloneEffect extends SpellAbilityEffect {
|
|||||||
tgtCard.addAlternateState(CardCharacteristicName.Flipped);
|
tgtCard.addAlternateState(CardCharacteristicName.Flipped);
|
||||||
tgtCard.setState(CardCharacteristicName.Flipped);
|
tgtCard.setState(CardCharacteristicName.Flipped);
|
||||||
}
|
}
|
||||||
CardFactoryUtil.copyState(cardToCopy, CardCharacteristicName.Flipped, tgtCard);
|
CardFactory.copyState(cardToCopy, CardCharacteristicName.Flipped, tgtCard);
|
||||||
addExtraCharacteristics(tgtCard, sa, origSVars);
|
addExtraCharacteristics(tgtCard, sa, origSVars);
|
||||||
CardFactoryUtil.addAbilityFactoryAbilities(tgtCard);
|
CardFactoryUtil.addAbilityFactoryAbilities(tgtCard);
|
||||||
for (int i = 0; i < tgtCard.getStaticAbilityStrings().size(); i++) {
|
for (int i = 0; i < tgtCard.getStaticAbilityStrings().size(); i++) {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import forge.Command;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityEffect;
|
import forge.card.ability.SpellAbilityEffect;
|
||||||
|
import forge.card.cardfactory.CardFactory;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
import forge.card.cardfactory.CardFactoryUtil;
|
||||||
import forge.card.mana.ManaCost;
|
import forge.card.mana.ManaCost;
|
||||||
import forge.card.spellability.Ability;
|
import forge.card.spellability.Ability;
|
||||||
@@ -82,7 +83,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
|
|||||||
if (!c.isToken() || c.isCopiedToken()) {
|
if (!c.isToken() || c.isCopiedToken()) {
|
||||||
// copy creature and put it onto the battlefield
|
// copy creature and put it onto the battlefield
|
||||||
|
|
||||||
copy = Singletons.getModel().getCardFactory().getCard(CardDb.getCard(c), sa.getActivatingPlayer());
|
copy = CardFactory.getCard(CardDb.getCard(c), sa.getActivatingPlayer());
|
||||||
|
|
||||||
// when copying something stolen:
|
// when copying something stolen:
|
||||||
copy.addController(controller);
|
copy.addController(controller);
|
||||||
@@ -90,7 +91,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
|
|||||||
copy.setToken(true);
|
copy.setToken(true);
|
||||||
copy.setCopiedToken(true);
|
copy.setCopiedToken(true);
|
||||||
} else { // isToken()
|
} else { // isToken()
|
||||||
copy = CardFactoryUtil.copyStats(c);
|
copy = CardFactory.copyStats(c);
|
||||||
|
|
||||||
copy.setName(c.getName());
|
copy.setName(c.getName());
|
||||||
copy.setImageFilename(c.getImageFilename());
|
copy.setImageFilename(c.getImageFilename());
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import java.util.Iterator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.Singletons;
|
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityEffect;
|
import forge.card.ability.SpellAbilityEffect;
|
||||||
|
import forge.card.cardfactory.CardFactory;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.gui.GuiChoose;
|
import forge.gui.GuiChoose;
|
||||||
@@ -99,7 +99,7 @@ public class CopySpellAbilityEffect extends SpellAbilityEffect {
|
|||||||
for (final SpellAbility chosenSAcopy : chosenSAs) {
|
for (final SpellAbility chosenSAcopy : chosenSAs) {
|
||||||
chosenSAcopy.setActivatingPlayer(controller);
|
chosenSAcopy.setActivatingPlayer(controller);
|
||||||
for (int i = 0; i < amount; i++) {
|
for (int i = 0; i < amount; i++) {
|
||||||
Singletons.getModel().getCardFactory().copySpellontoStack(card, chosenSAcopy.getSourceCard(), chosenSAcopy, true);
|
CardFactory.copySpellontoStack(card, chosenSAcopy.getSourceCard(), chosenSAcopy, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,7 +115,7 @@ public class CopySpellAbilityEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
chosenSA.setActivatingPlayer(controller);
|
chosenSA.setActivatingPlayer(controller);
|
||||||
for (int i = 0; i < amount; i++) {
|
for (int i = 0; i < amount; i++) {
|
||||||
Singletons.getModel().getCardFactory().copySpellontoStack(card, chosenSA.getSourceCard(), chosenSA, true);
|
CardFactory.copySpellontoStack(card, chosenSA.getSourceCard(), chosenSA, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // end resolve
|
} // end resolve
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ public class PlayEffect extends SpellAbilityEffect {
|
|||||||
source.clearRemembered();
|
source.clearRemembered();
|
||||||
}
|
}
|
||||||
if (sa.hasParam("CopyCard")) {
|
if (sa.hasParam("CopyCard")) {
|
||||||
tgtCard = Singletons.getModel().getCardFactory().getCard(CardDb.getCard(tgtCard), sa.getActivatingPlayer());
|
tgtCard = CardDb.getCard(tgtCard).toForgeCard(sa.getActivatingPlayer());
|
||||||
// when copying something stolen:
|
// when copying something stolen:
|
||||||
tgtCard.addController(sa.getActivatingPlayer());
|
tgtCard.addController(sa.getActivatingPlayer());
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package forge.card.ability.effects;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
|
import forge.CardLists;
|
||||||
|
import forge.CardPredicates;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityEffect;
|
import forge.card.ability.SpellAbilityEffect;
|
||||||
@@ -51,6 +53,9 @@ public class SacrificeEffect extends SpellAbilityEffect {
|
|||||||
for (final Player p : tgts) {
|
for (final Player p : tgts) {
|
||||||
List<Card> battlefield = p.getCardsIn(ZoneType.Battlefield);
|
List<Card> battlefield = p.getCardsIn(ZoneType.Battlefield);
|
||||||
List<Card> validTargets = AbilityUtils.filterListByType(battlefield, valid, sa);
|
List<Card> validTargets = AbilityUtils.filterListByType(battlefield, valid, sa);
|
||||||
|
if (!destroy) {
|
||||||
|
validTargets = CardLists.filter(validTargets, CardPredicates.canBeSacrificedBy(sa));
|
||||||
|
}
|
||||||
|
|
||||||
if (sa.hasParam("Random")) {
|
if (sa.hasParam("Random")) {
|
||||||
choosenToSacrifice = Aggregates.random(validTargets, Math.min(amount, validTargets.size()));
|
choosenToSacrifice = Aggregates.random(validTargets, Math.min(amount, validTargets.size()));
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import forge.CardCharacteristicName;
|
|||||||
import forge.CardColor;
|
import forge.CardColor;
|
||||||
import forge.CardUtil;
|
import forge.CardUtil;
|
||||||
import forge.Color;
|
import forge.Color;
|
||||||
|
import forge.card.CardCharacteristics;
|
||||||
import forge.card.CardRules;
|
import forge.card.CardRules;
|
||||||
import forge.card.CardSplitType;
|
import forge.card.CardSplitType;
|
||||||
import forge.card.ICardFace;
|
import forge.card.ICardFace;
|
||||||
@@ -39,12 +40,9 @@ import forge.card.spellability.SpellAbility;
|
|||||||
import forge.card.spellability.SpellPermanent;
|
import forge.card.spellability.SpellPermanent;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.card.trigger.TriggerHandler;
|
import forge.card.trigger.TriggerHandler;
|
||||||
import forge.error.BugReporter;
|
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.gui.GuiUtils;
|
|
||||||
import forge.item.CardDb;
|
import forge.item.CardDb;
|
||||||
import forge.item.IPaperCard;
|
import forge.item.IPaperCard;
|
||||||
import forge.properties.NewConstants;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -65,33 +63,6 @@ import forge.properties.NewConstants;
|
|||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public class CardFactory {
|
public class CardFactory {
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Constructor for CardFactory.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param file
|
|
||||||
* a {@link java.io.File} object.
|
|
||||||
*/
|
|
||||||
private final CardStorageReader reader;
|
|
||||||
|
|
||||||
public CardFactory() {
|
|
||||||
|
|
||||||
GuiUtils.checkEDT("CardFactory$constructor", false);
|
|
||||||
reader = new CardStorageReader(NewConstants.CARD_DATA_DIR.defaultLoc, true);
|
|
||||||
try {
|
|
||||||
// this fills in our map of card names to Card instances.
|
|
||||||
final List<CardRules> listCardRules = reader.loadCards();
|
|
||||||
CardDb.setup(listCardRules.iterator());
|
|
||||||
|
|
||||||
} catch (final Exception ex) {
|
|
||||||
BugReporter.reportException(ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // constructor
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* copyCard.
|
* copyCard.
|
||||||
@@ -101,15 +72,15 @@ public class CardFactory {
|
|||||||
* a {@link forge.Card} object.
|
* a {@link forge.Card} object.
|
||||||
* @return a {@link forge.Card} object.
|
* @return a {@link forge.Card} object.
|
||||||
*/
|
*/
|
||||||
public final Card copyCard(final Card in) {
|
public final static Card copyCard(final Card in) {
|
||||||
final CardCharacteristicName curState = in.getCurState();
|
final CardCharacteristicName curState = in.getCurState();
|
||||||
if (in.isInAlternateState()) {
|
if (in.isInAlternateState()) {
|
||||||
in.setState(CardCharacteristicName.Original);
|
in.setState(CardCharacteristicName.Original);
|
||||||
}
|
}
|
||||||
final Card out = this.getCard(CardDb.getCard(in), in.getOwner());
|
final Card out = getCard(CardDb.getCard(in), in.getOwner());
|
||||||
out.setUniqueNumber(in.getUniqueNumber());
|
out.setUniqueNumber(in.getUniqueNumber());
|
||||||
|
|
||||||
CardFactoryUtil.copyCharacteristics(in, out);
|
CardFactory.copyCharacteristics(in, out);
|
||||||
if (in.hasAlternateState()) {
|
if (in.hasAlternateState()) {
|
||||||
for (final CardCharacteristicName state : in.getStates()) {
|
for (final CardCharacteristicName state : in.getStates()) {
|
||||||
in.setState(state);
|
in.setState(state);
|
||||||
@@ -117,7 +88,7 @@ public class CardFactory {
|
|||||||
out.addAlternateState(state);
|
out.addAlternateState(state);
|
||||||
}
|
}
|
||||||
out.setState(state);
|
out.setState(state);
|
||||||
CardFactoryUtil.copyCharacteristics(in, out);
|
CardFactory.copyCharacteristics(in, out);
|
||||||
}
|
}
|
||||||
in.setState(curState);
|
in.setState(curState);
|
||||||
out.setState(curState);
|
out.setState(curState);
|
||||||
@@ -154,7 +125,7 @@ public class CardFactory {
|
|||||||
* @param bCopyDetails
|
* @param bCopyDetails
|
||||||
* a boolean.
|
* a boolean.
|
||||||
*/
|
*/
|
||||||
public final void copySpellontoStack(final Card source, final Card original, final SpellAbility sa,
|
public final static void copySpellontoStack(final Card source, final Card original, final SpellAbility sa,
|
||||||
final boolean bCopyDetails) {
|
final boolean bCopyDetails) {
|
||||||
//Player originalController = original.getController();
|
//Player originalController = original.getController();
|
||||||
Player controller = sa.getActivatingPlayer();
|
Player controller = sa.getActivatingPlayer();
|
||||||
@@ -240,7 +211,7 @@ public class CardFactory {
|
|||||||
* @return a {@link forge.Card} instance, owned by owner; or the special
|
* @return a {@link forge.Card} instance, owned by owner; or the special
|
||||||
* blankCard
|
* blankCard
|
||||||
*/
|
*/
|
||||||
public final Card getCard(final IPaperCard cp, final Player owner) {
|
public final static Card getCard(final IPaperCard cp, final Player owner) {
|
||||||
|
|
||||||
//System.out.println(cardName);
|
//System.out.println(cardName);
|
||||||
CardRules cardRules = cp.getRules();
|
CardRules cardRules = cp.getRules();
|
||||||
@@ -435,4 +406,110 @@ public class CardFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Copies stats like power, toughness, etc.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param sim
|
||||||
|
* a {@link java.lang.Object} object.
|
||||||
|
* @return a {@link forge.Card} object.
|
||||||
|
*/
|
||||||
|
public static Card copyStats(final Card sim) {
|
||||||
|
final Card c = new Card();
|
||||||
|
|
||||||
|
c.setFlipCard(sim.isFlipCard());
|
||||||
|
c.setDoubleFaced(sim.isDoubleFaced());
|
||||||
|
c.setCurSetCode(sim.getCurSetCode());
|
||||||
|
|
||||||
|
final CardCharacteristicName origState = sim.getCurState();
|
||||||
|
for (final CardCharacteristicName state : sim.getStates()) {
|
||||||
|
c.addAlternateState(state);
|
||||||
|
c.setState(state);
|
||||||
|
sim.setState(state);
|
||||||
|
CardFactory.copyCharacteristics(sim, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
sim.setState(origState);
|
||||||
|
c.setState(origState);
|
||||||
|
c.setRules(sim.getRules());
|
||||||
|
|
||||||
|
return c;
|
||||||
|
} // copyStats()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy characteristics.
|
||||||
|
*
|
||||||
|
* @param from
|
||||||
|
* the from
|
||||||
|
* @param to
|
||||||
|
* the to
|
||||||
|
*/
|
||||||
|
private static void copyCharacteristics(final Card from, final Card to) {
|
||||||
|
to.setBaseAttack(from.getBaseAttack());
|
||||||
|
to.setBaseDefense(from.getBaseDefense());
|
||||||
|
to.setBaseLoyalty(from.getBaseLoyalty());
|
||||||
|
to.setBaseAttackString(from.getBaseAttackString());
|
||||||
|
to.setBaseDefenseString(from.getBaseDefenseString());
|
||||||
|
to.setIntrinsicKeyword(from.getIntrinsicKeyword());
|
||||||
|
to.setName(from.getName());
|
||||||
|
to.setType(from.getCharacteristics().getType());
|
||||||
|
to.setText(from.getSpellText());
|
||||||
|
to.setManaCost(from.getManaCost());
|
||||||
|
to.setColor(from.getColor());
|
||||||
|
to.setSVars(from.getSVars());
|
||||||
|
to.setIntrinsicAbilities(from.getIntrinsicAbilities());
|
||||||
|
|
||||||
|
to.setImageFilename(from.getImageFilename());
|
||||||
|
to.setTriggers(from.getTriggers());
|
||||||
|
to.setReplacementEffects(from.getReplacementEffects());
|
||||||
|
to.setStaticAbilityStrings(from.getStaticAbilityStrings());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy characteristics.
|
||||||
|
*
|
||||||
|
* @param from
|
||||||
|
* the from
|
||||||
|
* @param stateToCopy
|
||||||
|
* the state to copy
|
||||||
|
* @param to
|
||||||
|
* the to
|
||||||
|
*/
|
||||||
|
public static void copyState(final Card from, final CardCharacteristicName stateToCopy, final Card to) {
|
||||||
|
|
||||||
|
// copy characteristics not associated with a state
|
||||||
|
to.setBaseLoyalty(from.getBaseLoyalty());
|
||||||
|
to.setBaseAttackString(from.getBaseAttackString());
|
||||||
|
to.setBaseDefenseString(from.getBaseDefenseString());
|
||||||
|
to.setText(from.getSpellText());
|
||||||
|
|
||||||
|
// get CardCharacteristics for desired state
|
||||||
|
CardCharacteristics characteristics = from.getState(stateToCopy);
|
||||||
|
to.getCharacteristics().copy(characteristics);
|
||||||
|
// handle triggers and replacement effect through Card class interface
|
||||||
|
to.setTriggers(characteristics.getTriggers());
|
||||||
|
to.setReplacementEffects(characteristics.getReplacementEffects());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void copySpellAbility(SpellAbility from, SpellAbility to) {
|
||||||
|
to.setDescription(from.getDescription());
|
||||||
|
to.setStackDescription(from.getDescription());
|
||||||
|
|
||||||
|
if (from.getSubAbility() != null) {
|
||||||
|
to.setSubAbility(from.getSubAbility().getCopy());
|
||||||
|
}
|
||||||
|
if (from.getRestrictions() != null) {
|
||||||
|
to.setRestrictions(from.getRestrictions());
|
||||||
|
}
|
||||||
|
if (from.getConditions() != null) {
|
||||||
|
to.setConditions(from.getConditions());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String sVar : from.getSVars()) {
|
||||||
|
to.setSVar(sVar, from.getSVar(sVar));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // end class AbstractCardFactory
|
} // end class AbstractCardFactory
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class CardFactoryArtifacts {
|
|||||||
public AbilityActivated getCopy() {
|
public AbilityActivated getCopy() {
|
||||||
AbilityActivated res = new AbilityGrindstone(getSourceCard(),
|
AbilityActivated res = new AbilityGrindstone(getSourceCard(),
|
||||||
getPayCosts(), getTarget() == null ? null : new Target(getTarget()));
|
getPayCosts(), getTarget() == null ? null : new Target(getTarget()));
|
||||||
CardFactoryUtil.copySpellAbility(this, res);
|
CardFactory.copySpellAbility(this, res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ class CardFactoryArtifacts {
|
|||||||
public AbilityActivated getCopy() {
|
public AbilityActivated getCopy() {
|
||||||
AbilityActivated res = new AbilityScrollRack(getSourceCard(),
|
AbilityActivated res = new AbilityScrollRack(getSourceCard(),
|
||||||
getPayCosts(), getTarget() == null ? null : new Target(getTarget()));
|
getPayCosts(), getTarget() == null ? null : new Target(getTarget()));
|
||||||
CardFactoryUtil.copySpellAbility(this, res);
|
CardFactory.copySpellAbility(this, res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,7 +261,7 @@ class CardFactoryArtifacts {
|
|||||||
public AbilityActivated getCopy() {
|
public AbilityActivated getCopy() {
|
||||||
AbilityActivated res = new AbilityTemporalAperture(getSourceCard(),
|
AbilityActivated res = new AbilityTemporalAperture(getSourceCard(),
|
||||||
getPayCosts(), getTarget() == null ? null : new Target(getTarget()));
|
getPayCosts(), getTarget() == null ? null : new Target(getTarget()));
|
||||||
CardFactoryUtil.copySpellAbility(this, res);
|
CardFactory.copySpellAbility(this, res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ import forge.Constant;
|
|||||||
import forge.CounterType;
|
import forge.CounterType;
|
||||||
import forge.GameEntity;
|
import forge.GameEntity;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.CardCharacteristics;
|
|
||||||
import forge.card.ability.AbilityFactory;
|
import forge.card.ability.AbilityFactory;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.ApiType;
|
import forge.card.ability.ApiType;
|
||||||
@@ -146,7 +145,7 @@ public class CardFactoryUtil {
|
|||||||
public AbilityActivated getCopy() {
|
public AbilityActivated getCopy() {
|
||||||
AbilityActivated res = new AbilityUnearth(getSourceCard(),
|
AbilityActivated res = new AbilityUnearth(getSourceCard(),
|
||||||
getPayCosts(), getTarget() == null ? null : new Target(getTarget()));
|
getPayCosts(), getTarget() == null ? null : new Target(getTarget()));
|
||||||
CardFactoryUtil.copySpellAbility(this, res);
|
CardFactory.copySpellAbility(this, res);
|
||||||
final SpellAbilityRestriction restrict = new SpellAbilityRestriction();
|
final SpellAbilityRestriction restrict = new SpellAbilityRestriction();
|
||||||
restrict.setZone(ZoneType.Graveyard);
|
restrict.setZone(ZoneType.Graveyard);
|
||||||
restrict.setSorcerySpeed(true);
|
restrict.setSorcerySpeed(true);
|
||||||
@@ -359,7 +358,7 @@ public class CardFactoryUtil {
|
|||||||
public AbilityActivated getCopy() {
|
public AbilityActivated getCopy() {
|
||||||
AbilityActivated res = new AbilityTransmute(getSourceCard(),
|
AbilityActivated res = new AbilityTransmute(getSourceCard(),
|
||||||
getPayCosts(), getTarget() == null ? null : new Target(getTarget()));
|
getPayCosts(), getTarget() == null ? null : new Target(getTarget()));
|
||||||
CardFactoryUtil.copySpellAbility(this, res);
|
CardFactory.copySpellAbility(this, res);
|
||||||
res.getRestrictions().setZone(ZoneType.Hand);
|
res.getRestrictions().setZone(ZoneType.Hand);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -2488,7 +2487,7 @@ public class CardFactoryUtil {
|
|||||||
|
|
||||||
final int multiplier = controller.getTokenDoublersMagnitude();
|
final int multiplier = controller.getTokenDoublersMagnitude();
|
||||||
for (int i = 0; i < multiplier; i++) {
|
for (int i = 0; i < multiplier; i++) {
|
||||||
Card temp = CardFactoryUtil.copyStats(c);
|
Card temp = CardFactory.copyStats(c);
|
||||||
|
|
||||||
for (final String kw : intrinsicKeywords) {
|
for (final String kw : intrinsicKeywords) {
|
||||||
temp.addIntrinsicKeyword(kw);
|
temp.addIntrinsicKeyword(kw);
|
||||||
@@ -2669,112 +2668,6 @@ public class CardFactoryUtil {
|
|||||||
|| (c == CounterType.TIME);
|
|| (c == CounterType.TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Copies stats like power, toughness, etc.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param sim
|
|
||||||
* a {@link java.lang.Object} object.
|
|
||||||
* @return a {@link forge.Card} object.
|
|
||||||
*/
|
|
||||||
public static Card copyStats(final Card sim) {
|
|
||||||
final Card c = new Card();
|
|
||||||
|
|
||||||
c.setFlipCard(sim.isFlipCard());
|
|
||||||
c.setDoubleFaced(sim.isDoubleFaced());
|
|
||||||
c.setCurSetCode(sim.getCurSetCode());
|
|
||||||
|
|
||||||
final CardCharacteristicName origState = sim.getCurState();
|
|
||||||
for (final CardCharacteristicName state : sim.getStates()) {
|
|
||||||
c.addAlternateState(state);
|
|
||||||
c.setState(state);
|
|
||||||
sim.setState(state);
|
|
||||||
CardFactoryUtil.copyCharacteristics(sim, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
sim.setState(origState);
|
|
||||||
c.setState(origState);
|
|
||||||
c.setRules(sim.getRules());
|
|
||||||
|
|
||||||
return c;
|
|
||||||
} // copyStats()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy characteristics.
|
|
||||||
*
|
|
||||||
* @param from
|
|
||||||
* the from
|
|
||||||
* @param to
|
|
||||||
* the to
|
|
||||||
*/
|
|
||||||
public static void copyCharacteristics(final Card from, final Card to) {
|
|
||||||
to.setBaseAttack(from.getBaseAttack());
|
|
||||||
to.setBaseDefense(from.getBaseDefense());
|
|
||||||
to.setBaseLoyalty(from.getBaseLoyalty());
|
|
||||||
to.setBaseAttackString(from.getBaseAttackString());
|
|
||||||
to.setBaseDefenseString(from.getBaseDefenseString());
|
|
||||||
to.setIntrinsicKeyword(from.getIntrinsicKeyword());
|
|
||||||
to.setName(from.getName());
|
|
||||||
to.setType(from.getCharacteristics().getType());
|
|
||||||
to.setText(from.getSpellText());
|
|
||||||
to.setManaCost(from.getManaCost());
|
|
||||||
to.setColor(from.getColor());
|
|
||||||
to.setSVars(from.getSVars());
|
|
||||||
to.setIntrinsicAbilities(from.getIntrinsicAbilities());
|
|
||||||
|
|
||||||
to.setImageFilename(from.getImageFilename());
|
|
||||||
to.setTriggers(from.getTriggers());
|
|
||||||
to.setReplacementEffects(from.getReplacementEffects());
|
|
||||||
to.setStaticAbilityStrings(from.getStaticAbilityStrings());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy characteristics.
|
|
||||||
*
|
|
||||||
* @param from
|
|
||||||
* the from
|
|
||||||
* @param stateToCopy
|
|
||||||
* the state to copy
|
|
||||||
* @param to
|
|
||||||
* the to
|
|
||||||
*/
|
|
||||||
public static void copyState(final Card from, final CardCharacteristicName stateToCopy, final Card to) {
|
|
||||||
|
|
||||||
// copy characteristics not associated with a state
|
|
||||||
to.setBaseLoyalty(from.getBaseLoyalty());
|
|
||||||
to.setBaseAttackString(from.getBaseAttackString());
|
|
||||||
to.setBaseDefenseString(from.getBaseDefenseString());
|
|
||||||
to.setText(from.getSpellText());
|
|
||||||
|
|
||||||
// get CardCharacteristics for desired state
|
|
||||||
CardCharacteristics characteristics = from.getState(stateToCopy);
|
|
||||||
to.getCharacteristics().copy(characteristics);
|
|
||||||
// handle triggers and replacement effect through Card class interface
|
|
||||||
to.setTriggers(characteristics.getTriggers());
|
|
||||||
to.setReplacementEffects(characteristics.getReplacementEffects());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void copySpellAbility(SpellAbility from, SpellAbility to) {
|
|
||||||
to.setDescription(from.getDescription());
|
|
||||||
to.setStackDescription(from.getDescription());
|
|
||||||
|
|
||||||
if (from.getSubAbility() != null) {
|
|
||||||
to.setSubAbility(from.getSubAbility().getCopy());
|
|
||||||
}
|
|
||||||
if (from.getRestrictions() != null) {
|
|
||||||
to.setRestrictions(from.getRestrictions());
|
|
||||||
}
|
|
||||||
if (from.getConditions() != null) {
|
|
||||||
to.setConditions(from.getConditions());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String sVar : from.getSVars()) {
|
|
||||||
to.setSVar(sVar, from.getSVar(sVar));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void correctAbilityChainSourceCard(final SpellAbility sa, final Card card) {
|
public static void correctAbilityChainSourceCard(final SpellAbility sa, final Card card) {
|
||||||
|
|
||||||
sa.setSourceCard(card);
|
sa.setSourceCard(card);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import forge.card.ability.effects.ChangeZoneAllEffect;
|
|||||||
import forge.card.ability.effects.ChangeZoneEffect;
|
import forge.card.ability.effects.ChangeZoneEffect;
|
||||||
import forge.card.ability.effects.ManaEffect;
|
import forge.card.ability.effects.ManaEffect;
|
||||||
import forge.card.ability.effects.ManaReflectedEffect;
|
import forge.card.ability.effects.ManaReflectedEffect;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
import forge.card.cardfactory.CardFactory;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -109,7 +109,7 @@ public final class AbilitySub extends SpellAbility implements java.io.Serializab
|
|||||||
public AbilitySub getCopy() {
|
public AbilitySub getCopy() {
|
||||||
Target t = getTarget() == null ? null : new Target(getTarget());
|
Target t = getTarget() == null ? null : new Target(getTarget());
|
||||||
AbilitySub res = new AbilitySub(api, getSourceCard(), t, params);
|
AbilitySub res = new AbilitySub(api, getSourceCard(), t, params);
|
||||||
CardFactoryUtil.copySpellAbility(this, res);
|
CardFactory.copySpellAbility(this, res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -148,6 +148,9 @@ public class InputControl extends MyObservable implements java.io.Serializable {
|
|||||||
* @return a {@link forge.control.input.Input} object.
|
* @return a {@link forge.control.input.Input} object.
|
||||||
*/
|
*/
|
||||||
public final Input getActualInput() {
|
public final Input getActualInput() {
|
||||||
|
if ( !game.hasMulliganned() )
|
||||||
|
return new InputMulligan();
|
||||||
|
|
||||||
final PhaseHandler handler = game.getPhaseHandler();
|
final PhaseHandler handler = game.getPhaseHandler();
|
||||||
final PhaseType phase = handler.getPhase();
|
final PhaseType phase = handler.getPhase();
|
||||||
final Player playerTurn = handler.getPlayerTurn();
|
final Player playerTurn = handler.getPlayerTurn();
|
||||||
|
|||||||
@@ -174,7 +174,6 @@ public class InputMulligan extends Input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ga.checkStateEffects();
|
ga.checkStateEffects();
|
||||||
Singletons.getModel().getMatch().getInput().clearInput();
|
|
||||||
|
|
||||||
Player next = game.getPhaseHandler().getPlayerTurn();
|
Player next = game.getPhaseHandler().getPlayerTurn();
|
||||||
|
|
||||||
@@ -187,7 +186,9 @@ public class InputMulligan extends Input {
|
|||||||
VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(next);
|
VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(next);
|
||||||
SDisplayUtil.showTab(nextField);
|
SDisplayUtil.showTab(nextField);
|
||||||
|
|
||||||
game.getPhaseHandler().nextPhase();
|
game.setMulliganned(true);
|
||||||
|
Singletons.getModel().getMatch().getInput().clearInput();
|
||||||
|
Singletons.getModel().getMatch().getInput().resetInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ import forge.Singletons;
|
|||||||
import forge.deck.generate.Generate2ColorDeck;
|
import forge.deck.generate.Generate2ColorDeck;
|
||||||
import forge.deck.generate.Generate3ColorDeck;
|
import forge.deck.generate.Generate3ColorDeck;
|
||||||
import forge.deck.generate.Generate5ColorDeck;
|
import forge.deck.generate.Generate5ColorDeck;
|
||||||
|
import forge.deck.generate.GenerateColoredDeckBase;
|
||||||
|
import forge.deck.generate.GenerateMonoColorDeck;
|
||||||
import forge.deck.generate.GenerateThemeDeck;
|
import forge.deck.generate.GenerateThemeDeck;
|
||||||
import forge.game.player.PlayerType;
|
import forge.game.player.PlayerType;
|
||||||
import forge.item.CardDb;
|
import forge.item.CardDb;
|
||||||
@@ -67,7 +69,7 @@ public class DeckgenUtil {
|
|||||||
* @return {@link forge.deck.Deck}
|
* @return {@link forge.deck.Deck}
|
||||||
*/
|
*/
|
||||||
public static Deck buildColorDeck(final String[] selection, PlayerType pt) {
|
public static Deck buildColorDeck(final String[] selection, PlayerType pt) {
|
||||||
ItemPoolView<CardPrinted> cards = null;
|
|
||||||
final Deck deck;
|
final Deck deck;
|
||||||
|
|
||||||
// Replace "random" with "AI" for deck generation code
|
// Replace "random" with "AI" for deck generation code
|
||||||
@@ -75,22 +77,20 @@ public class DeckgenUtil {
|
|||||||
selection[i] = COLOR_VALS.get(selection[i]);
|
selection[i] = COLOR_VALS.get(selection[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2, 3, and 5 colors.
|
GenerateColoredDeckBase gen = null;
|
||||||
if (selection.length == 2) {
|
|
||||||
final Generate2ColorDeck gen = new Generate2ColorDeck(
|
if (selection.length == 1) {
|
||||||
selection[0], selection[1]);
|
gen = new GenerateMonoColorDeck(selection[0]);
|
||||||
cards = gen.get2ColorDeck(60, pt);
|
} else if (selection.length == 2) {
|
||||||
}
|
gen = new Generate2ColorDeck(selection[0], selection[1]);
|
||||||
else if (selection.length == 3) {
|
} else if (selection.length == 3) {
|
||||||
final Generate3ColorDeck gen = new Generate3ColorDeck(
|
gen = new Generate3ColorDeck(selection[0], selection[1], selection[2]);
|
||||||
selection[0], selection[1], selection[2]);
|
} else {
|
||||||
cards = gen.get3ColorDeck(60, pt);
|
gen = new Generate5ColorDeck();
|
||||||
}
|
|
||||||
else {
|
|
||||||
final Generate5ColorDeck gen = new Generate5ColorDeck();
|
|
||||||
cards = gen.get5ColorDeck(60, pt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ItemPoolView<CardPrinted> cards = gen == null ? null : gen.getDeck(60, pt);
|
||||||
|
|
||||||
// After generating card lists, build deck.
|
// After generating card lists, build deck.
|
||||||
deck = new Deck();
|
deck = new Deck();
|
||||||
deck.getMain().addAll(cards);
|
deck.getMain().addAll(cards);
|
||||||
@@ -132,8 +132,8 @@ public class DeckgenUtil {
|
|||||||
|
|
||||||
/** @return {@link forge.deck.Deck} */
|
/** @return {@link forge.deck.Deck} */
|
||||||
public static Deck getRandomColorDeck(PlayerType pt) {
|
public static Deck getRandomColorDeck(PlayerType pt) {
|
||||||
final int[] colorCount = new int[] {2, 3, 5};
|
final int[] colorCount = new int[] {1, 2, 3, 5};
|
||||||
final int count = colorCount[(int) (Math.round(Math.random() * 2))];
|
final int count = colorCount[MyRandom.getRandom().nextInt(colorCount.length)];
|
||||||
final String[] selection = new String[count];
|
final String[] selection = new String[count];
|
||||||
|
|
||||||
// A simulated selection of "random 1" will trigger the AI selection process.
|
// A simulated selection of "random 1" will trigger the AI selection process.
|
||||||
@@ -288,14 +288,7 @@ public class DeckgenUtil {
|
|||||||
public static boolean colorCheck(final String[] colors0) {
|
public static boolean colorCheck(final String[] colors0) {
|
||||||
boolean result = true;
|
boolean result = true;
|
||||||
|
|
||||||
if (colors0.length == 1) {
|
if (colors0.length == 4) {
|
||||||
JOptionPane.showMessageDialog(null,
|
|
||||||
"Sorry, single color generated decks aren't supported yet."
|
|
||||||
+ "\n\rPlease choose at least one more color for this deck.",
|
|
||||||
"Generate deck: 1 color", JOptionPane.ERROR_MESSAGE);
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
else if (colors0.length == 4) {
|
|
||||||
JOptionPane.showMessageDialog(null,
|
JOptionPane.showMessageDialog(null,
|
||||||
"Sorry, four color generated decks aren't supported yet."
|
"Sorry, four color generated decks aren't supported yet."
|
||||||
+ "\n\rPlease use 2, 3, or 5 colors for this deck.",
|
+ "\n\rPlease use 2, 3, or 5 colors for this deck.",
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public class Generate2ColorDeck extends GenerateColoredDeckBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public final ItemPoolView<CardPrinted> get2ColorDeck(final int size, final PlayerType pt) {
|
public final ItemPoolView<CardPrinted> getDeck(final int size, final PlayerType pt) {
|
||||||
addCreaturesAndSpells(size, cmcLevels, cmcAmounts, pt);
|
addCreaturesAndSpells(size, cmcLevels, cmcAmounts, pt);
|
||||||
|
|
||||||
// Add lands
|
// Add lands
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public class Generate3ColorDeck extends GenerateColoredDeckBase {
|
|||||||
* the pt
|
* the pt
|
||||||
* @return a {@link forge.CardList} object.
|
* @return a {@link forge.CardList} object.
|
||||||
*/
|
*/
|
||||||
public final ItemPoolView<CardPrinted> get3ColorDeck(final int size, final PlayerType pt) {
|
public final ItemPoolView<CardPrinted> getDeck(final int size, final PlayerType pt) {
|
||||||
addCreaturesAndSpells(size, cmcLevels, cmcAmounts, pt);
|
addCreaturesAndSpells(size, cmcLevels, cmcAmounts, pt);
|
||||||
|
|
||||||
// Add lands
|
// Add lands
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public class Generate5ColorDeck extends GenerateColoredDeckBase {
|
|||||||
* a PlayerType
|
* a PlayerType
|
||||||
* @return a {@link forge.CardList} object.
|
* @return a {@link forge.CardList} object.
|
||||||
*/
|
*/
|
||||||
public final ItemPoolView<CardPrinted> get5ColorDeck(final int size, final PlayerType pt) {
|
public final ItemPoolView<CardPrinted> getDeck(final int size, final PlayerType pt) {
|
||||||
addCreaturesAndSpells(size, cmcLevels, cmcAmounts, pt);
|
addCreaturesAndSpells(size, cmcLevels, cmcAmounts, pt);
|
||||||
|
|
||||||
// Add lands
|
// Add lands
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import forge.game.player.PlayerType;
|
|||||||
import forge.item.CardDb;
|
import forge.item.CardDb;
|
||||||
import forge.item.CardPrinted;
|
import forge.item.CardPrinted;
|
||||||
import forge.item.ItemPool;
|
import forge.item.ItemPool;
|
||||||
|
import forge.item.ItemPoolView;
|
||||||
import forge.properties.ForgePreferences.FPref;
|
import forge.properties.ForgePreferences.FPref;
|
||||||
import forge.util.Aggregates;
|
import forge.util.Aggregates;
|
||||||
import forge.util.MyRandom;
|
import forge.util.MyRandom;
|
||||||
@@ -88,6 +89,9 @@ public abstract class GenerateColoredDeckBase {
|
|||||||
addCmcAdjusted(spells, spellCnt, cmcLevels, cmcAmounts);
|
addCmcAdjusted(spells, spellCnt, cmcLevels, cmcAmounts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ItemPoolView<CardPrinted> getDeck(final int size, final PlayerType pt) {
|
||||||
|
return null; // all but theme deck do override this method
|
||||||
|
}
|
||||||
|
|
||||||
protected void addSome(int cnt, List<CardPrinted> source) {
|
protected void addSome(int cnt, List<CardPrinted> source) {
|
||||||
for (int i = 0; i < cnt; i++) {
|
for (int i = 0; i < cnt; i++) {
|
||||||
|
|||||||
94
src/main/java/forge/deck/generate/GenerateMonoColorDeck.java
Normal file
94
src/main/java/forge/deck/generate/GenerateMonoColorDeck.java
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package forge.deck.generate;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import forge.card.ColorSet;
|
||||||
|
import forge.card.MagicColor;
|
||||||
|
import forge.deck.generate.GenerateDeckUtil.FilterCMC;
|
||||||
|
import forge.game.player.PlayerType;
|
||||||
|
import forge.item.CardPrinted;
|
||||||
|
import forge.item.ItemPoolView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Generate2ColorDeck class.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Forge
|
||||||
|
* @version $Id: Generate2ColorDeck.java 19765 2013-02-20 03:01:37Z myk $
|
||||||
|
*/
|
||||||
|
public class GenerateMonoColorDeck extends GenerateColoredDeckBase {
|
||||||
|
@Override protected final float getLandsPercentage() { return 0.39f; }
|
||||||
|
@Override protected final float getCreatPercentage() { return 0.36f; }
|
||||||
|
@Override protected final float getSpellPercentage() { return 0.25f; }
|
||||||
|
|
||||||
|
final List<FilterCMC> cmcLevels = Arrays.asList(
|
||||||
|
new GenerateDeckUtil.FilterCMC(0, 2),
|
||||||
|
new GenerateDeckUtil.FilterCMC(3, 4),
|
||||||
|
new GenerateDeckUtil.FilterCMC(5, 6),
|
||||||
|
new GenerateDeckUtil.FilterCMC(7, 20));
|
||||||
|
final int[] cmcAmounts = {10, 8, 5, 3};
|
||||||
|
|
||||||
|
// mana curve of the card pool
|
||||||
|
// 20x 0 - 2
|
||||||
|
// 16x 3 - 4
|
||||||
|
// 12x 5 - 6
|
||||||
|
// 4x 7 - 20
|
||||||
|
// = 52x - card pool (before further random filtering)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Constructor for Generate2ColorDeck.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param clr1
|
||||||
|
* a {@link java.lang.String} object.
|
||||||
|
* @param clr2
|
||||||
|
* a {@link java.lang.String} object.
|
||||||
|
*/
|
||||||
|
public GenerateMonoColorDeck(final String clr1) {
|
||||||
|
|
||||||
|
if (clr1.equals("AI")) {
|
||||||
|
int color1 = r.nextInt(5);
|
||||||
|
colors = ColorSet.fromMask(MagicColor.WHITE << color1);
|
||||||
|
} else {
|
||||||
|
colors = ColorSet.fromNames(clr1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public final ItemPoolView<CardPrinted> getDeck(final int size, final PlayerType pt) {
|
||||||
|
addCreaturesAndSpells(size, cmcLevels, cmcAmounts, pt);
|
||||||
|
|
||||||
|
// Add lands
|
||||||
|
int numLands = (int) (getLandsPercentage() * size);
|
||||||
|
|
||||||
|
tmpDeck.append("numLands:").append(numLands).append("\n");
|
||||||
|
|
||||||
|
addBasicLand(numLands);
|
||||||
|
tmpDeck.append("DeckSize:").append(tDeck.countAll()).append("\n");
|
||||||
|
|
||||||
|
adjustDeckSize(size);
|
||||||
|
tmpDeck.append("DeckSize:").append(tDeck.countAll()).append("\n");
|
||||||
|
|
||||||
|
return tDeck;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,6 +38,7 @@ import forge.GameEntity;
|
|||||||
import forge.card.CardSplitType;
|
import forge.card.CardSplitType;
|
||||||
import forge.card.CardType;
|
import forge.card.CardType;
|
||||||
import forge.card.ability.effects.AttachEffect;
|
import forge.card.ability.effects.AttachEffect;
|
||||||
|
import forge.card.cardfactory.CardFactory;
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.mana.ManaCost;
|
import forge.card.mana.ManaCost;
|
||||||
import forge.card.replacement.ReplacementEffect;
|
import forge.card.replacement.ReplacementEffect;
|
||||||
@@ -159,7 +160,7 @@ public class GameAction {
|
|||||||
if (zoneFrom.is(ZoneType.Battlefield)) {
|
if (zoneFrom.is(ZoneType.Battlefield)) {
|
||||||
c.setFlipStaus(false);
|
c.setFlipStaus(false);
|
||||||
}
|
}
|
||||||
copied = forge.Singletons.getModel().getCardFactory().copyCard(c);
|
copied = CardFactory.copyCard(c);
|
||||||
copied.setUnearthed(c.isUnearthed());
|
copied.setUnearthed(c.isUnearthed());
|
||||||
copied.setTapped(false);
|
copied.setTapped(false);
|
||||||
for (final Trigger trigger : copied.getTriggers()) {
|
for (final Trigger trigger : copied.getTriggers()) {
|
||||||
@@ -671,7 +672,7 @@ public class GameAction {
|
|||||||
if (p != null && p.is(ZoneType.Battlefield)) {
|
if (p != null && p.is(ZoneType.Battlefield)) {
|
||||||
lastKnownInfo = CardUtil.getLKICopy(c);
|
lastKnownInfo = CardUtil.getLKICopy(c);
|
||||||
c.clearCounters(); // remove all counters
|
c.clearCounters(); // remove all counters
|
||||||
library.add(forge.Singletons.getModel().getCardFactory().copyCard(c), libPosition);
|
library.add(CardFactory.copyCard(c), libPosition);
|
||||||
} else {
|
} else {
|
||||||
c.clearCounters(); // remove all counters
|
c.clearCounters(); // remove all counters
|
||||||
library.add(c, libPosition);
|
library.add(c, libPosition);
|
||||||
|
|||||||
@@ -73,6 +73,9 @@ public class GameActionPlay {
|
|||||||
* a {@link forge.card.spellability.SpellAbility} object.
|
* a {@link forge.card.spellability.SpellAbility} object.
|
||||||
*/
|
*/
|
||||||
public final void playSpellAbilityForFree(final SpellAbility sa) {
|
public final void playSpellAbilityForFree(final SpellAbility sa) {
|
||||||
|
final Card source = sa.getSourceCard();
|
||||||
|
setSplitCardState(source, sa); // Split card support
|
||||||
|
|
||||||
if (sa.getPayCosts() != null) {
|
if (sa.getPayCosts() != null) {
|
||||||
if (sa.getApi() == ApiType.Charm && !sa.isWrapper()) {
|
if (sa.getApi() == ApiType.Charm && !sa.isWrapper()) {
|
||||||
CharmEffect.makeChoices(sa);
|
CharmEffect.makeChoices(sa);
|
||||||
@@ -180,23 +183,20 @@ public class GameActionPlay {
|
|||||||
List<Card> untappedCreats = CardLists.filter(spell.getActivatingPlayer().getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES);
|
List<Card> untappedCreats = CardLists.filter(spell.getActivatingPlayer().getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES);
|
||||||
untappedCreats = CardLists.filter(untappedCreats, CardPredicates.Presets.UNTAPPED);
|
untappedCreats = CardLists.filter(untappedCreats, CardPredicates.Presets.UNTAPPED);
|
||||||
|
|
||||||
if (untappedCreats.size() != 0) {
|
if (!untappedCreats.isEmpty()) {
|
||||||
final List<Card> choices = new ArrayList<Card>();
|
final List<Card> choices = new ArrayList<Card>();
|
||||||
for (final Card c : untappedCreats) {
|
choices.addAll(untappedCreats);
|
||||||
choices.add(c);
|
|
||||||
}
|
|
||||||
ArrayList<String> usableColors = new ArrayList<String>();
|
ArrayList<String> usableColors = new ArrayList<String>();
|
||||||
ManaCostBeingPaid newCost = new ManaCostBeingPaid(originalCost.toString());
|
ManaCostBeingPaid newCost = new ManaCostBeingPaid(originalCost.toString());
|
||||||
Card tapForConvoke = null;
|
Card tapForConvoke = null;
|
||||||
if (sa.getActivatingPlayer().isHuman()) {
|
if (sa.getActivatingPlayer().isHuman()) {
|
||||||
tapForConvoke = GuiChoose.oneOrNone("Tap for Convoke? " + newCost.toString(),
|
tapForConvoke = GuiChoose.oneOrNone("Tap for Convoke? " + newCost.toString(), choices);
|
||||||
choices);
|
|
||||||
} else {
|
} else {
|
||||||
// TODO: AI to choose a creature to tap would go here
|
// TODO: AI to choose a creature to tap would go here
|
||||||
// Probably along with deciding how many creatures to
|
// Probably along with deciding how many creatures to
|
||||||
// tap
|
// tap
|
||||||
}
|
}
|
||||||
while (tapForConvoke != null && untappedCreats.size() != 0) {
|
while (tapForConvoke != null && !untappedCreats.isEmpty()) {
|
||||||
final Card workingCard = (Card) tapForConvoke;
|
final Card workingCard = (Card) tapForConvoke;
|
||||||
usableColors = GameActionPlay.getConvokableColors(workingCard, newCost);
|
usableColors = GameActionPlay.getConvokableColors(workingCard, newCost);
|
||||||
|
|
||||||
@@ -223,7 +223,7 @@ public class GameActionPlay {
|
|||||||
sa.addTappedForConvoke(workingCard);
|
sa.addTappedForConvoke(workingCard);
|
||||||
choices.remove(workingCard);
|
choices.remove(workingCard);
|
||||||
untappedCreats.remove(workingCard);
|
untappedCreats.remove(workingCard);
|
||||||
if ((choices.size() < 2) || (newCost.getConvertedManaCost() == 0)) {
|
if (choices.isEmpty() || (newCost.getConvertedManaCost() == 0)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -239,7 +239,7 @@ public class GameActionPlay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// will only be null if user cancelled.
|
// will only be null if user cancelled.
|
||||||
if (tapForConvoke != null) {
|
if (!sa.getTappedForConvoke().isEmpty()) {
|
||||||
// Convoked creats are tapped here with triggers
|
// Convoked creats are tapped here with triggers
|
||||||
// suppressed,
|
// suppressed,
|
||||||
// Then again when payment is done(In
|
// Then again when payment is done(In
|
||||||
|
|||||||
@@ -23,16 +23,12 @@ import forge.CardUtil;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.trigger.TriggerHandler;
|
import forge.card.trigger.TriggerHandler;
|
||||||
import forge.card.trigger.TriggerType;
|
import forge.card.trigger.TriggerType;
|
||||||
import forge.control.input.Input;
|
|
||||||
import forge.control.input.InputControl;
|
|
||||||
import forge.control.input.InputMulligan;
|
|
||||||
import forge.deck.CardPool;
|
import forge.deck.CardPool;
|
||||||
import forge.deck.Deck;
|
import forge.deck.Deck;
|
||||||
import forge.deck.DeckSection;
|
import forge.deck.DeckSection;
|
||||||
import forge.error.BugReporter;
|
import forge.error.BugReporter;
|
||||||
import forge.game.event.FlipCoinEvent;
|
import forge.game.event.FlipCoinEvent;
|
||||||
import forge.game.phase.PhaseHandler;
|
import forge.game.phase.PhaseHandler;
|
||||||
import forge.game.phase.PhaseType;
|
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
import forge.game.player.LobbyPlayer;
|
import forge.game.player.LobbyPlayer;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
@@ -195,8 +191,6 @@ public class GameNew {
|
|||||||
removedAnteCards.put(player, myRemovedAnteCards);
|
removedAnteCards.put(player, myRemovedAnteCards);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (rAICards.size() > 0) {
|
if (rAICards.size() > 0) {
|
||||||
String message = buildFourColumnList("AI deck contains the following cards that it can't play or may be buggy:", rAICards);
|
String message = buildFourColumnList("AI deck contains the following cards that it can't play or may be buggy:", rAICards);
|
||||||
if (GameType.Quest == game.getType()) {
|
if (GameType.Quest == game.getType()) {
|
||||||
@@ -215,7 +209,116 @@ public class GameNew {
|
|||||||
JOptionPane.showMessageDialog(null, ante.toString(), "", JOptionPane.INFORMATION_MESSAGE);
|
JOptionPane.showMessageDialog(null, ante.toString(), "", JOptionPane.INFORMATION_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
GameNew.actuateGame(match, game, false);
|
// Deciding which cards go to ante
|
||||||
|
if (preferences.getPrefBoolean(FPref.UI_ANTE)) {
|
||||||
|
final String nl = System.getProperty("line.separator");
|
||||||
|
final StringBuilder msg = new StringBuilder();
|
||||||
|
for (final Player p : game.getPlayers()) {
|
||||||
|
|
||||||
|
final List<Card> lib = p.getCardsIn(ZoneType.Library);
|
||||||
|
Predicate<Card> goodForAnte = Predicates.not(CardPredicates.Presets.BASIC_LANDS);
|
||||||
|
Card ante = Aggregates.random(Iterables.filter(lib, goodForAnte));
|
||||||
|
if (ante == null) {
|
||||||
|
throw new RuntimeException(p + " library is empty.");
|
||||||
|
}
|
||||||
|
game.getGameLog().add("Ante", p + " anted " + ante, 0);
|
||||||
|
VAntes.SINGLETON_INSTANCE.addAnteCard(p, ante);
|
||||||
|
game.getAction().moveTo(ZoneType.Ante, ante);
|
||||||
|
msg.append(p.getName()).append(" ante: ").append(ante).append(nl);
|
||||||
|
}
|
||||||
|
JOptionPane.showMessageDialog(null, msg, "Ante", JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
determineFirstTurnPlayer(match.getLastGameOutcome(), game);
|
||||||
|
|
||||||
|
// Draw <handsize> cards
|
||||||
|
for (final Player p1 : game.getPlayers()) {
|
||||||
|
p1.drawCards(p1.getMaxHandSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread thGame = new GameInputUpdatesThread(match, game);
|
||||||
|
thGame.setName("Game input updater");
|
||||||
|
thGame.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ultimate of Karn the Liberated
|
||||||
|
public static void restartGame(final MatchController match, final GameState game, final Player startingTurn, Map<Player, List<Card>> playerLibraries) {
|
||||||
|
|
||||||
|
Map<LobbyPlayer, PlayerStartConditions> players = match.getPlayers();
|
||||||
|
Map<Player, PlayerStartConditions> playersConditions = new HashMap<Player, PlayerStartConditions>();
|
||||||
|
|
||||||
|
for (Player p : game.getPlayers()) {
|
||||||
|
playersConditions.put(p, players.get(p.getLobbyPlayer()));
|
||||||
|
}
|
||||||
|
|
||||||
|
game.setMulliganned(false);
|
||||||
|
match.getInput().clearInput();
|
||||||
|
|
||||||
|
//Card.resetUniqueNumber();
|
||||||
|
// need this code here, otherwise observables fail
|
||||||
|
forge.card.trigger.Trigger.resetIDs();
|
||||||
|
TriggerHandler trigHandler = game.getTriggerHandler();
|
||||||
|
trigHandler.clearTriggerSettings();
|
||||||
|
trigHandler.clearDelayedTrigger();
|
||||||
|
trigHandler.cleanUpTemporaryTriggers();
|
||||||
|
trigHandler.suppressMode(TriggerType.ChangesZone);
|
||||||
|
|
||||||
|
game.getStack().reset();
|
||||||
|
GameAction action = game.getAction();
|
||||||
|
|
||||||
|
|
||||||
|
for (Entry<Player, PlayerStartConditions> p : playersConditions.entrySet()) {
|
||||||
|
final Player player = p.getKey();
|
||||||
|
player.setStartingLife(p.getValue().getStartingLife());
|
||||||
|
player.setNumLandsPlayed(0);
|
||||||
|
putCardsOnBattlefield(player, p.getValue().getCardsOnBattlefield(player));
|
||||||
|
|
||||||
|
PlayerZone library = player.getZone(ZoneType.Library);
|
||||||
|
List<Card> newLibrary = playerLibraries.get(player);
|
||||||
|
for (Card c : newLibrary) {
|
||||||
|
action.moveTo(library, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
player.shuffle();
|
||||||
|
player.getZone(ZoneType.Battlefield).updateObservers();
|
||||||
|
player.updateObservers();
|
||||||
|
player.getZone(ZoneType.Hand).updateObservers();
|
||||||
|
}
|
||||||
|
|
||||||
|
trigHandler.clearSuppression(TriggerType.ChangesZone);
|
||||||
|
|
||||||
|
PhaseHandler phaseHandler = game.getPhaseHandler();
|
||||||
|
phaseHandler.setPlayerTurn(startingTurn);
|
||||||
|
|
||||||
|
// Draw <handsize> cards
|
||||||
|
for (final Player p : game.getPlayers()) {
|
||||||
|
p.drawCards(p.getMaxHandSize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Write javadoc for this method.
|
||||||
|
* @param match
|
||||||
|
* @param game
|
||||||
|
*/
|
||||||
|
private static void determineFirstTurnPlayer(final GameOutcome lastGameOutcome, final GameState game) {
|
||||||
|
// Only cut/coin toss if it's the first game of the match
|
||||||
|
Player goesFirst;
|
||||||
|
Player humanPlayer = Singletons.getControl().getPlayer();
|
||||||
|
boolean isFirstGame = lastGameOutcome == null;
|
||||||
|
if (isFirstGame) {
|
||||||
|
goesFirst = GameNew.seeWhoPlaysFirstDice(game);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
goesFirst = lastGameOutcome.isWinner(humanPlayer.getLobbyPlayer()) ? humanPlayer.getOpponent() : humanPlayer;
|
||||||
|
}
|
||||||
|
String message = goesFirst + ( isFirstGame ? " has won the coin toss." : " lost the last game.");
|
||||||
|
boolean willPlay = goesFirst.getController().getWillPlayOnFirstTurn(message);
|
||||||
|
if ( goesFirst != humanPlayer ) {
|
||||||
|
JOptionPane.showMessageDialog(null, message + "\nComputer Going First", "You are drawing", JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
}
|
||||||
|
goesFirst = willPlay ? goesFirst : goesFirst.getOpponent();
|
||||||
|
game.getPhaseHandler().setPlayerTurn(goesFirst);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void initVariantsZones(final Player player, final PlayerStartConditions psc) {
|
private static void initVariantsZones(final Player player, final PlayerStartConditions psc) {
|
||||||
@@ -283,128 +386,6 @@ public class GameNew {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ultimate of Karn the Liberated
|
|
||||||
public static void restartGame(final MatchController match, final GameState game, final Player startingTurn, Map<Player, List<Card>> playerLibraries) {
|
|
||||||
|
|
||||||
Map<LobbyPlayer, PlayerStartConditions> players = match.getPlayers();
|
|
||||||
Map<Player, PlayerStartConditions> playersConditions = new HashMap<Player, PlayerStartConditions>();
|
|
||||||
|
|
||||||
for (Player p : game.getPlayers()) {
|
|
||||||
playersConditions.put(p, players.get(p.getLobbyPlayer()));
|
|
||||||
}
|
|
||||||
|
|
||||||
match.getInput().clearInput();
|
|
||||||
|
|
||||||
//Card.resetUniqueNumber();
|
|
||||||
// need this code here, otherwise observables fail
|
|
||||||
forge.card.trigger.Trigger.resetIDs();
|
|
||||||
TriggerHandler trigHandler = game.getTriggerHandler();
|
|
||||||
trigHandler.clearTriggerSettings();
|
|
||||||
trigHandler.clearDelayedTrigger();
|
|
||||||
trigHandler.cleanUpTemporaryTriggers();
|
|
||||||
trigHandler.suppressMode(TriggerType.ChangesZone);
|
|
||||||
|
|
||||||
game.getStack().reset();
|
|
||||||
GameAction action = game.getAction();
|
|
||||||
|
|
||||||
|
|
||||||
for (Entry<Player, PlayerStartConditions> p : playersConditions.entrySet()) {
|
|
||||||
final Player player = p.getKey();
|
|
||||||
player.setStartingLife(p.getValue().getStartingLife());
|
|
||||||
player.setNumLandsPlayed(0);
|
|
||||||
putCardsOnBattlefield(player, p.getValue().getCardsOnBattlefield(player));
|
|
||||||
|
|
||||||
PlayerZone library = player.getZone(ZoneType.Library);
|
|
||||||
List<Card> newLibrary = playerLibraries.get(player);
|
|
||||||
for (Card c : newLibrary) {
|
|
||||||
action.moveTo(library, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
player.shuffle();
|
|
||||||
player.getZone(ZoneType.Battlefield).updateObservers();
|
|
||||||
player.updateObservers();
|
|
||||||
player.getZone(ZoneType.Hand).updateObservers();
|
|
||||||
}
|
|
||||||
|
|
||||||
trigHandler.clearSuppression(TriggerType.ChangesZone);
|
|
||||||
|
|
||||||
PhaseHandler phaseHandler = game.getPhaseHandler();
|
|
||||||
phaseHandler.setPlayerTurn(startingTurn);
|
|
||||||
|
|
||||||
GameNew.actuateGame(match, game, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This must be separated from the newGame method since life totals and
|
|
||||||
* player details could be adjusted before the game is started.
|
|
||||||
*
|
|
||||||
* That process (also cleanup and observer updates) should be done in
|
|
||||||
* newGame, then when all is ready, call this function.
|
|
||||||
* @param isRestartedGame Whether the actuated game is the first start or a restart
|
|
||||||
*/
|
|
||||||
private static void actuateGame(final MatchController match, final GameState game, boolean isRestartedGame) {
|
|
||||||
if (!isRestartedGame) {
|
|
||||||
// Deciding which cards go to ante
|
|
||||||
if (preferences.getPrefBoolean(FPref.UI_ANTE)) {
|
|
||||||
final String nl = System.getProperty("line.separator");
|
|
||||||
final StringBuilder msg = new StringBuilder();
|
|
||||||
for (final Player p : game.getPlayers()) {
|
|
||||||
|
|
||||||
final List<Card> lib = p.getCardsIn(ZoneType.Library);
|
|
||||||
Predicate<Card> goodForAnte = Predicates.not(CardPredicates.Presets.BASIC_LANDS);
|
|
||||||
Card ante = Aggregates.random(Iterables.filter(lib, goodForAnte));
|
|
||||||
if (ante == null) {
|
|
||||||
throw new RuntimeException(p + " library is empty.");
|
|
||||||
}
|
|
||||||
game.getGameLog().add("Ante", p + " anted " + ante, 0);
|
|
||||||
VAntes.SINGLETON_INSTANCE.addAnteCard(p, ante);
|
|
||||||
game.getAction().moveTo(ZoneType.Ante, ante);
|
|
||||||
msg.append(p.getName()).append(" ante: ").append(ante).append(nl);
|
|
||||||
}
|
|
||||||
JOptionPane.showMessageDialog(null, msg, "Ante", JOptionPane.INFORMATION_MESSAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
GameOutcome lastGameOutcome = match.getLastGameOutcome();
|
|
||||||
// Only cut/coin toss if it's the first game of the match
|
|
||||||
Player goesFirst;
|
|
||||||
Player humanPlayer = Singletons.getControl().getPlayer();
|
|
||||||
boolean isFirstGame = lastGameOutcome == null;
|
|
||||||
if (isFirstGame) {
|
|
||||||
goesFirst = GameNew.seeWhoPlaysFirstDice(game);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
goesFirst = lastGameOutcome.isWinner(humanPlayer.getLobbyPlayer()) ? humanPlayer.getOpponent() : humanPlayer;
|
|
||||||
}
|
|
||||||
String message = goesFirst + ( isFirstGame ? " has won the coin toss." : " lost the last game.");
|
|
||||||
boolean willPlay = goesFirst.getController().getWillPlayOnFirstTurn(message);
|
|
||||||
if ( goesFirst != humanPlayer ) {
|
|
||||||
JOptionPane.showMessageDialog(null, message + "\nComputer Going First", "You are drawing", JOptionPane.INFORMATION_MESSAGE);
|
|
||||||
}
|
|
||||||
goesFirst = willPlay ? goesFirst : goesFirst.getOpponent();
|
|
||||||
game.getPhaseHandler().setPlayerTurn(goesFirst);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw <handsize> cards
|
|
||||||
for (final Player p : game.getPlayers()) {
|
|
||||||
p.drawCards(p.getMaxHandSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
game.getPhaseHandler().setPhaseState(PhaseType.MULLIGAN);
|
|
||||||
|
|
||||||
InputControl control = match.getInput();
|
|
||||||
Input tmp = new InputMulligan();
|
|
||||||
control.setInput(tmp);
|
|
||||||
|
|
||||||
|
|
||||||
Thread thGame = new GameInputUpdatesThread(match, game);
|
|
||||||
|
|
||||||
match.getInput().getInput().showMessage();
|
|
||||||
thGame.setName("Game input updater");
|
|
||||||
thGame.start();
|
|
||||||
} // newGame()
|
|
||||||
|
|
||||||
private static String buildFourColumnList(String firstLine, Iterable<CardPrinted> cAnteRemoved) {
|
private static String buildFourColumnList(String firstLine, Iterable<CardPrinted> cAnteRemoved) {
|
||||||
StringBuilder sb = new StringBuilder(firstLine);
|
StringBuilder sb = new StringBuilder(firstLine);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|||||||
@@ -666,4 +666,8 @@ public class GameState {
|
|||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return actionPlay;
|
return actionPlay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean mulliganned = false;
|
||||||
|
public boolean hasMulliganned(){ return mulliganned; }
|
||||||
|
public void setMulliganned(boolean value) { mulliganned = value; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ import forge.game.GameActionUtil;
|
|||||||
import forge.game.GameState;
|
import forge.game.GameState;
|
||||||
import forge.game.GlobalRuleChange;
|
import forge.game.GlobalRuleChange;
|
||||||
import forge.game.ai.ComputerUtil;
|
import forge.game.ai.ComputerUtil;
|
||||||
import forge.game.ai.ComputerUtilBlock;
|
|
||||||
import forge.game.ai.ComputerUtilCard;
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.ai.ComputerUtilCost;
|
import forge.game.ai.ComputerUtilCost;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
@@ -57,7 +56,6 @@ import forge.game.zone.PlayerZone;
|
|||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.GuiChoose;
|
import forge.gui.GuiChoose;
|
||||||
import forge.gui.GuiDialog;
|
import forge.gui.GuiDialog;
|
||||||
import forge.gui.GuiUtils;
|
|
||||||
import forge.gui.framework.EDocID;
|
import forge.gui.framework.EDocID;
|
||||||
import forge.gui.framework.SDisplayUtil;
|
import forge.gui.framework.SDisplayUtil;
|
||||||
import forge.gui.match.views.VCombat;
|
import forge.gui.match.views.VCombat;
|
||||||
@@ -431,20 +429,7 @@ public class CombatUtil {
|
|||||||
if (blockers.size() <= 1) {
|
if (blockers.size() <= 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
List<Card> orderedBlockers = player.getController().orderBlockers(attacker, blockers);
|
||||||
List<Card> orderedBlockers = null;
|
|
||||||
if (player.isHuman()) {
|
|
||||||
GuiUtils.setPanelSelection(attacker);
|
|
||||||
List<Card> ordered = GuiChoose.order("Choose Blocking Order", "Damaged First", 0, blockers, null, attacker);
|
|
||||||
|
|
||||||
orderedBlockers = new ArrayList<Card>();
|
|
||||||
for (Object o : ordered) {
|
|
||||||
orderedBlockers.add((Card) o);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
orderedBlockers = ComputerUtilBlock.orderBlockers(attacker, blockers);
|
|
||||||
}
|
|
||||||
combat.setBlockerList(attacker, orderedBlockers);
|
combat.setBlockerList(attacker, orderedBlockers);
|
||||||
}
|
}
|
||||||
CombatUtil.showCombat();
|
CombatUtil.showCombat();
|
||||||
@@ -459,19 +444,7 @@ public class CombatUtil {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Card> orderedAttacker = null;
|
List<Card> orderedAttacker = blocker.getController().getController().orderAttackers(blocker, attackers);
|
||||||
if (blocker.getController().isHuman()) {
|
|
||||||
GuiUtils.setPanelSelection(blocker);
|
|
||||||
List<Card> ordered = GuiChoose.order("Choose Blocking Order", "Damaged First", 0, attackers, null, blocker);
|
|
||||||
|
|
||||||
orderedAttacker = new ArrayList<Card>();
|
|
||||||
for (Object o : ordered) {
|
|
||||||
orderedAttacker.add((Card) o);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
orderedAttacker = ComputerUtilBlock.orderAttackers(blocker, attackers);
|
|
||||||
}
|
|
||||||
combat.setAttackersBlockedByList(blocker, orderedAttacker);
|
combat.setAttackersBlockedByList(blocker, orderedAttacker);
|
||||||
}
|
}
|
||||||
CombatUtil.showCombat();
|
CombatUtil.showCombat();
|
||||||
|
|||||||
@@ -52,9 +52,9 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
|||||||
/** Constant <code>serialVersionUID=5207222278370963197L</code>. */
|
/** Constant <code>serialVersionUID=5207222278370963197L</code>. */
|
||||||
private static final long serialVersionUID = 5207222278370963197L;
|
private static final long serialVersionUID = 5207222278370963197L;
|
||||||
|
|
||||||
private PhaseType phase = PhaseType.MULLIGAN;
|
private PhaseType phase = PhaseType.UNTAP;
|
||||||
private int turn = 0;
|
private int turn = 1;
|
||||||
// Start turn at 0, so first untap step will turn it to 1
|
// Start turn at 1, since first untap is where we start
|
||||||
|
|
||||||
private final transient Stack<ExtraTurn> extraTurns = new Stack<ExtraTurn>();
|
private final transient Stack<ExtraTurn> extraTurns = new Stack<ExtraTurn>();
|
||||||
private final transient Map<PhaseType, Stack<PhaseType>> extraPhases = new HashMap<PhaseType, Stack<PhaseType>>();
|
private final transient Map<PhaseType, Stack<PhaseType>> extraPhases = new HashMap<PhaseType, Stack<PhaseType>>();
|
||||||
@@ -262,7 +262,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DRAW:
|
case DRAW:
|
||||||
if (getTurn() == 1 || PhaseUtil.skipDraw(this.getPlayerTurn())) {
|
if (getTurn() == 1 || this.getPlayerTurn().isSkippingDraw()) {
|
||||||
this.setPlayersPriorityPermission(false);
|
this.setPlayersPriorityPermission(false);
|
||||||
} else {
|
} else {
|
||||||
this.getPlayerTurn().drawCards(1, true);
|
this.getPlayerTurn().drawCards(1, true);
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
|
|
||||||
|
|
||||||
public enum PhaseType {
|
public enum PhaseType {
|
||||||
MULLIGAN("Mulligan"),
|
|
||||||
// Note: Mulligan is not part of "All Phases" which are strictly ingame phases
|
|
||||||
UNTAP("Untap"),
|
UNTAP("Untap"),
|
||||||
UPKEEP("Upkeep"),
|
UPKEEP("Upkeep"),
|
||||||
DRAW("Draw"),
|
DRAW("Draw"),
|
||||||
|
|||||||
@@ -114,28 +114,7 @@ public class PhaseUtil {
|
|||||||
game.getPhaseHandler().setPlayersPriorityPermission(false);
|
game.getPhaseHandler().setPlayersPriorityPermission(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* skipDraw.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param player
|
|
||||||
* a {@link forge.game.player.Player} object.
|
|
||||||
* @return a boolean.
|
|
||||||
*/
|
|
||||||
public static boolean skipDraw(final Player player) {
|
|
||||||
|
|
||||||
if (player.hasKeyword("Skip your next draw step.")) {
|
|
||||||
player.removeKeyword("Skip your next draw step.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (player.hasKeyword("Skip your draw step.")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ********* Declare Attackers ***********
|
// ********* Declare Attackers ***********
|
||||||
|
|
||||||
|
|||||||
@@ -354,13 +354,14 @@ public class Upkeep extends Phase {
|
|||||||
final Command paidCommand = Command.BLANK;
|
final Command paidCommand = Command.BLANK;
|
||||||
|
|
||||||
final Ability blankAbility = Upkeep.BlankAbility(c, upkeepCost);
|
final Ability blankAbility = Upkeep.BlankAbility(c, upkeepCost);
|
||||||
|
blankAbility.setActivatingPlayer(controller);
|
||||||
|
|
||||||
final Ability upkeepAbility = new Ability(c, ManaCost.ZERO) {
|
final Ability upkeepAbility = new Ability(c, ManaCost.ZERO) {
|
||||||
@Override
|
@Override
|
||||||
public void resolve() {
|
public void resolve() {
|
||||||
if (controller.isHuman()) {
|
if (controller.isHuman()) {
|
||||||
GameActionUtil.payCostDuringAbilityResolve(controller, blankAbility, blankAbility.getPayCosts(),
|
GameActionUtil.payCostDuringAbilityResolve(controller, blankAbility, blankAbility.getPayCosts(),
|
||||||
paidCommand, unpaidCommand, null, game);
|
paidCommand, unpaidCommand, this, game);
|
||||||
} else { // computer
|
} else { // computer
|
||||||
if (ComputerUtilCost.shouldPayCost(controller, c, upkeepCost) && ComputerUtilCost.canPayCost(blankAbility, controller)) {
|
if (ComputerUtilCost.shouldPayCost(controller, c, upkeepCost) && ComputerUtilCost.canPayCost(blankAbility, controller)) {
|
||||||
ComputerUtil.playNoStack((AIPlayer)controller, blankAbility, game);
|
ComputerUtil.playNoStack((AIPlayer)controller, blankAbility, game);
|
||||||
|
|||||||
@@ -3241,6 +3241,20 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
|
|||||||
game.getStack().add(miracleTrigger);
|
game.getStack().add(miracleTrigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSkippingDraw() {
|
||||||
|
|
||||||
|
if (hasKeyword("Skip your next draw step.")) {
|
||||||
|
removeKeyword("Skip your next draw step.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasKeyword("Skip your draw step.")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Write javadoc for this type.
|
* TODO: Write javadoc for this type.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -97,4 +97,7 @@ public abstract class PlayerController {
|
|||||||
public abstract boolean confirmAction(SpellAbility sa, String mode, String message);
|
public abstract boolean confirmAction(SpellAbility sa, String mode, String message);
|
||||||
public abstract boolean getWillPlayOnFirstTurn(String message);
|
public abstract boolean getWillPlayOnFirstTurn(String message);
|
||||||
public abstract boolean confirmStaticApplication(Card hostCard, GameEntity affected, String logic, String message);
|
public abstract boolean confirmStaticApplication(Card hostCard, GameEntity affected, String logic, String message);
|
||||||
|
|
||||||
|
public abstract List<Card> orderBlockers(Card attacker, List<Card> blockers);
|
||||||
|
public abstract List<Card> orderAttackers(Card blocker, List<Card> attackers);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import forge.game.ai.AiController;
|
|||||||
import forge.game.ai.AiInputBlock;
|
import forge.game.ai.AiInputBlock;
|
||||||
import forge.game.ai.AiInputCommon;
|
import forge.game.ai.AiInputCommon;
|
||||||
import forge.game.ai.ComputerUtil;
|
import forge.game.ai.ComputerUtil;
|
||||||
|
import forge.game.ai.ComputerUtilBlock;
|
||||||
import forge.game.ai.ComputerUtilCombat;
|
import forge.game.ai.ComputerUtilCombat;
|
||||||
import forge.gui.GuiChoose;
|
import forge.gui.GuiChoose;
|
||||||
|
|
||||||
@@ -208,4 +209,14 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
return brains.confirmStaticApplication(hostCard, affected, logic, message);
|
return brains.confirmStaticApplication(hostCard, affected, logic, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Card> orderBlockers(Card attacker, List<Card> blockers) {
|
||||||
|
return ComputerUtilBlock.orderBlockers(attacker, blockers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Card> orderAttackers(Card blocker, List<Card> attackers) {
|
||||||
|
return ComputerUtilBlock.orderAttackers(blocker, attackers);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import forge.game.GameType;
|
|||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
import forge.gui.GuiChoose;
|
import forge.gui.GuiChoose;
|
||||||
import forge.gui.GuiDialog;
|
import forge.gui.GuiDialog;
|
||||||
|
import forge.gui.GuiUtils;
|
||||||
import forge.gui.match.CMatchUI;
|
import forge.gui.match.CMatchUI;
|
||||||
import forge.item.CardPrinted;
|
import forge.item.CardPrinted;
|
||||||
|
|
||||||
@@ -260,4 +261,16 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
|
|
||||||
return !playDraw.equals(1);
|
return !playDraw.equals(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Card> orderBlockers(Card attacker, List<Card> blockers) {
|
||||||
|
GuiUtils.setPanelSelection(attacker);
|
||||||
|
return GuiChoose.order("Choose Blocking Order", "Damaged First", 0, blockers, null, attacker);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Card> orderAttackers(Card blocker, List<Card> attackers) {
|
||||||
|
GuiUtils.setPanelSelection(blocker);
|
||||||
|
return GuiChoose.order("Choose Blocking Order", "Damaged First", 0, attackers, null, blocker);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import forge.CardPredicates.Presets;
|
|||||||
import forge.Command;
|
import forge.Command;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
|
import forge.card.cardfactory.CardFactory;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
import forge.card.cardfactory.CardFactoryUtil;
|
||||||
import forge.card.mana.ManaCost;
|
import forge.card.mana.ManaCost;
|
||||||
import forge.card.mana.ManaCostBeingPaid;
|
import forge.card.mana.ManaCostBeingPaid;
|
||||||
@@ -608,7 +609,7 @@ public class MagicStack extends MyObservable {
|
|||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
for (int i = 0; i < sp.getSourceCard().getReplicateMagnitude(); i++) {
|
for (int i = 0; i < sp.getSourceCard().getReplicateMagnitude(); i++) {
|
||||||
Singletons.getModel().getCardFactory().copySpellontoStack(sp.getSourceCard(), sp.getSourceCard(), sp, false);
|
CardFactory.copySpellontoStack(sp.getSourceCard(), sp.getSourceCard(), sp, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -36,10 +36,12 @@ import javax.swing.border.EtchedBorder;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
|
import forge.CardCharacteristicName;
|
||||||
import forge.CounterType;
|
import forge.CounterType;
|
||||||
import forge.GameEntity;
|
import forge.GameEntity;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.CardEdition;
|
import forge.card.CardEdition;
|
||||||
|
import forge.card.CardSplitType;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.toolbox.FLabel;
|
import forge.gui.toolbox.FLabel;
|
||||||
@@ -202,10 +204,14 @@ public class CardDetailPanel extends FPanel {
|
|||||||
|
|
||||||
final boolean canShowThis = card.canBeShownTo(Singletons.getControl().getPlayer());
|
final boolean canShowThis = card.canBeShownTo(Singletons.getControl().getPlayer());
|
||||||
if (canShowThis) {
|
if (canShowThis) {
|
||||||
if (card.getManaCost().toString().equals("") || card.isLand()) {
|
if (card.getManaCost().isNoCost()) {
|
||||||
this.nameCostLabel.setText(card.getName());
|
this.nameCostLabel.setText(card.getName());
|
||||||
} else {
|
} else {
|
||||||
this.nameCostLabel.setText(card.getName() + " - " + card.getManaCost());
|
String manaCost = card.getManaCost().toString();
|
||||||
|
if ( card.getRules() != null && card.getRules().getSplitType() == CardSplitType.Split && card.getCurState() == CardCharacteristicName.Original) {
|
||||||
|
manaCost = card.getRules().getMainPart().getManaCost().toString() + " // " + card.getRules().getOtherPart().getManaCost().toString();
|
||||||
|
}
|
||||||
|
this.nameCostLabel.setText(card.getName() + " - " + manaCost);
|
||||||
}
|
}
|
||||||
this.typeLabel.setText(GuiDisplayUtil.formatCardType(card));
|
this.typeLabel.setText(GuiDisplayUtil.formatCardType(card));
|
||||||
|
|
||||||
|
|||||||
@@ -431,7 +431,7 @@ public final class GuiDisplayUtil {
|
|||||||
for (final String element : data) {
|
for (final String element : data) {
|
||||||
final String[] cardinfo = element.trim().split("\\|");
|
final String[] cardinfo = element.trim().split("\\|");
|
||||||
|
|
||||||
final Card c = Singletons.getModel().getCardFactory().getCard(CardDb.instance().getCard(cardinfo[0]), player);
|
final Card c = CardDb.instance().getCard(cardinfo[0]).toForgeCard(player);
|
||||||
|
|
||||||
boolean hasSetCurSet = false;
|
boolean hasSetCurSet = false;
|
||||||
for (final String info : cardinfo) {
|
for (final String info : cardinfo) {
|
||||||
@@ -596,7 +596,7 @@ public final class GuiDisplayUtil {
|
|||||||
*/
|
*/
|
||||||
public static void devModeCardToHand() {
|
public static void devModeCardToHand() {
|
||||||
final List<Player> players = Singletons.getModel().getGame().getPlayers();
|
final List<Player> players = Singletons.getModel().getGame().getPlayers();
|
||||||
final Player p = GuiChoose.oneOrNone("Put card in play for which player?", players);
|
final Player p = GuiChoose.oneOrNone("Put card in hand for which player?", players);
|
||||||
if (null == p) {
|
if (null == p) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class InputProxy extends MyObservable implements Observer {
|
|||||||
* @param in
|
* @param in
|
||||||
* a {@link forge.control.input.Input} object.
|
* a {@link forge.control.input.Input} object.
|
||||||
*/
|
*/
|
||||||
public void setInput(final Input in) {
|
public final void setInput(final Input in) {
|
||||||
valid = true;
|
valid = true;
|
||||||
this.input = in;
|
this.input = in;
|
||||||
this.input.showMessage(); // this call may invalidate the input by the time it returns
|
this.input.showMessage(); // this call may invalidate the input by the time it returns
|
||||||
|
|||||||
@@ -106,15 +106,15 @@ public enum CDeckgen implements ICDoc {
|
|||||||
switch (colorCount0) {
|
switch (colorCount0) {
|
||||||
case 2:
|
case 2:
|
||||||
genConstructed.getMain().addAll(
|
genConstructed.getMain().addAll(
|
||||||
(new Generate2ColorDeck("AI", "AI")).get2ColorDeck(60, PlayerType.HUMAN));
|
(new Generate2ColorDeck("AI", "AI")).getDeck(60, PlayerType.HUMAN));
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
genConstructed.getMain().addAll(
|
genConstructed.getMain().addAll(
|
||||||
(new Generate3ColorDeck("AI", "AI", "AI")).get3ColorDeck(60, PlayerType.HUMAN));
|
(new Generate3ColorDeck("AI", "AI", "AI")).getDeck(60, PlayerType.HUMAN));
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
genConstructed.getMain().addAll(
|
genConstructed.getMain().addAll(
|
||||||
(new Generate5ColorDeck()).get5ColorDeck(60, PlayerType.HUMAN));
|
(new Generate5ColorDeck()).getDeck(60, PlayerType.HUMAN));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ import java.util.List;
|
|||||||
import javax.swing.JTable;
|
import javax.swing.JTable;
|
||||||
import javax.swing.table.DefaultTableCellRenderer;
|
import javax.swing.table.DefaultTableCellRenderer;
|
||||||
|
|
||||||
|
import forge.card.CardRules;
|
||||||
|
import forge.card.CardSplitType;
|
||||||
import forge.card.mana.ManaCost;
|
import forge.card.mana.ManaCost;
|
||||||
import forge.card.mana.ManaCostShard;
|
import forge.card.mana.ManaCostShard;
|
||||||
import forge.gui.toolbox.CardFaceSymbols;
|
import forge.gui.toolbox.CardFaceSymbols;
|
||||||
@@ -34,7 +36,13 @@ import forge.gui.toolbox.CardFaceSymbols;
|
|||||||
public class ManaCostRenderer extends DefaultTableCellRenderer {
|
public class ManaCostRenderer extends DefaultTableCellRenderer {
|
||||||
private static final long serialVersionUID = 1770527102334163549L;
|
private static final long serialVersionUID = 1770527102334163549L;
|
||||||
|
|
||||||
private ManaCost value;
|
static final int elemtWidth = 13;
|
||||||
|
static final int elemtGap = 0;
|
||||||
|
static final int padding0 = 1;
|
||||||
|
static final int spaceBetweenSplitCosts = 3;
|
||||||
|
|
||||||
|
private ManaCost v1;
|
||||||
|
private ManaCost v2;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
@@ -46,8 +54,10 @@ public class ManaCostRenderer extends DefaultTableCellRenderer {
|
|||||||
@Override
|
@Override
|
||||||
public final Component getTableCellRendererComponent(final JTable table, final Object value,
|
public final Component getTableCellRendererComponent(final JTable table, final Object value,
|
||||||
final boolean isSelected, final boolean hasFocus, final int row, final int column) {
|
final boolean isSelected, final boolean hasFocus, final int row, final int column) {
|
||||||
this.value = (ManaCost) value;
|
CardRules v = value instanceof CardRules ? (CardRules) value : null;
|
||||||
this.setToolTipText(this.value.toString());
|
this.v1 = v == null ? ManaCost.NO_COST : v.getMainPart().getManaCost();
|
||||||
|
this.v2 = v == null || v.getSplitType() != CardSplitType.Split ? null : v.getOtherPart().getManaCost();
|
||||||
|
this.setToolTipText(v2 == null ? v1.toString() : v1.toString() + " / " + v2.toString());
|
||||||
return super.getTableCellRendererComponent(table, "", isSelected, hasFocus, row, column);
|
return super.getTableCellRendererComponent(table, "", isSelected, hasFocus, row, column);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,18 +70,38 @@ public class ManaCostRenderer extends DefaultTableCellRenderer {
|
|||||||
public final void paint(final Graphics g) {
|
public final void paint(final Graphics g) {
|
||||||
super.paint(g);
|
super.paint(g);
|
||||||
|
|
||||||
final int elemtWidth = 13;
|
|
||||||
final int elemtGap = 0;
|
|
||||||
final int padding = 1;
|
|
||||||
|
|
||||||
float xpos = padding;
|
|
||||||
|
|
||||||
final int genericManaCost = this.value.getGenericCost();
|
|
||||||
final int xManaCosts = this.value.countX();
|
|
||||||
final boolean hasGeneric = (genericManaCost > 0) || this.value.isPureGeneric();
|
|
||||||
final List<ManaCostShard> shards = this.value.getShards();
|
|
||||||
|
|
||||||
final int cellWidth = this.getWidth();
|
final int cellWidth = this.getWidth();
|
||||||
|
|
||||||
|
if ( null == v2 )
|
||||||
|
drawCost(g, v1, padding0, cellWidth);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int shards1 = v1.isPureGeneric() || v1.getGenericCost() > 0 ? 1 : 0;
|
||||||
|
int shards2 = v2.isPureGeneric() || v2.getGenericCost() > 0 ? 1 : 0;
|
||||||
|
shards1 += v1.getShards().size();
|
||||||
|
shards2 += v2.getShards().size();
|
||||||
|
|
||||||
|
int perGlyph = (cellWidth - padding0 - spaceBetweenSplitCosts) / (shards1 + shards2);
|
||||||
|
perGlyph = Math.min(perGlyph, elemtWidth + elemtGap);
|
||||||
|
drawCost(g, v1, padding0, padding0 + perGlyph * shards1);
|
||||||
|
drawCost(g, v2, cellWidth - perGlyph * shards2, cellWidth );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Write javadoc for this method.
|
||||||
|
* @param g
|
||||||
|
* @param padding
|
||||||
|
* @param cellWidth
|
||||||
|
*/
|
||||||
|
private void drawCost(final Graphics g, ManaCost value, final int padding, final int cellWidth) {
|
||||||
|
float xpos = padding;
|
||||||
|
final int genericManaCost = value.getGenericCost();
|
||||||
|
final int xManaCosts = value.countX();
|
||||||
|
final boolean hasGeneric = (genericManaCost > 0) || this.v1.isPureGeneric();
|
||||||
|
final List<ManaCostShard> shards = value.getShards();
|
||||||
|
|
||||||
|
|
||||||
final int cntGlyphs = hasGeneric ? shards.size() + 1 : shards.size();
|
final int cntGlyphs = hasGeneric ? shards.size() + 1 : shards.size();
|
||||||
final float offsetIfNoSpace = cntGlyphs > 1 ? (cellWidth - padding - elemtWidth) / (cntGlyphs - 1f)
|
final float offsetIfNoSpace = cntGlyphs > 1 ? (cellWidth - padding - elemtWidth) / (cntGlyphs - 1f)
|
||||||
: elemtWidth + elemtGap;
|
: elemtWidth + elemtGap;
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import forge.Singletons;
|
|||||||
import forge.card.CardAiHints;
|
import forge.card.CardAiHints;
|
||||||
import forge.card.CardEdition;
|
import forge.card.CardEdition;
|
||||||
import forge.card.CardRarity;
|
import forge.card.CardRarity;
|
||||||
|
import forge.card.CardRules;
|
||||||
import forge.card.ColorSet;
|
import forge.card.ColorSet;
|
||||||
import forge.card.mana.ManaCost;
|
import forge.card.mana.ManaCost;
|
||||||
import forge.deck.DeckBase;
|
import forge.deck.DeckBase;
|
||||||
@@ -318,11 +319,14 @@ public final class SColumnUtil {
|
|||||||
private static final Pattern AE_FINDER = Pattern.compile("AE", Pattern.LITERAL);
|
private static final Pattern AE_FINDER = Pattern.compile("AE", Pattern.LITERAL);
|
||||||
|
|
||||||
private static ManaCost toManaCost(final InventoryItem i) {
|
private static ManaCost toManaCost(final InventoryItem i) {
|
||||||
return i instanceof CardPrinted ? ((IPaperCard) i).getRules().getManaCost() : ManaCost.NO_COST;
|
return i instanceof IPaperCard ? ((IPaperCard) i).getRules().getManaCost() : ManaCost.NO_COST;
|
||||||
|
}
|
||||||
|
private static CardRules toCardRules(final InventoryItem i) {
|
||||||
|
return i instanceof IPaperCard ? ((IPaperCard) i).getRules() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ColorSet toColor(final InventoryItem i) {
|
private static ColorSet toColor(final InventoryItem i) {
|
||||||
return i instanceof CardPrinted ? ((IPaperCard) i).getRules().getColor() : ColorSet.getNullColor();
|
return i instanceof IPaperCard ? ((IPaperCard) i).getRules().getColor() : ColorSet.getNullColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int toPower(final InventoryItem i) {
|
private static int toPower(final InventoryItem i) {
|
||||||
@@ -430,7 +434,7 @@ public final class SColumnUtil {
|
|||||||
private static final Function<Entry<InventoryItem, Integer>, Object> FN_COST_GET = new Function<Entry<InventoryItem, Integer>, Object>() {
|
private static final Function<Entry<InventoryItem, Integer>, Object> FN_COST_GET = new Function<Entry<InventoryItem, Integer>, Object>() {
|
||||||
@Override
|
@Override
|
||||||
public Object apply(final Entry<InventoryItem, Integer> from) {
|
public Object apply(final Entry<InventoryItem, Integer> from) {
|
||||||
return SColumnUtil.toManaCost(from.getKey());
|
return SColumnUtil.toCardRules(from.getKey());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,11 @@ public class GuiDownloadPicturesLQ extends GuiDownloader {
|
|||||||
|
|
||||||
for (final IPaperCard c : CardDb.instance().getUniqueCards()) {
|
for (final IPaperCard c : CardDb.instance().getUniqueCards()) {
|
||||||
CardRules cardRules = c.getRules();
|
CardRules cardRules = c.getRules();
|
||||||
|
if (cardRules != null && cardRules.getSplitType() == CardSplitType.Split && cardRules.getOtherPart() != null) {
|
||||||
|
this.createDLObjects(cardRules.getPictureUrl(), String.format("%s%s", cardRules.getMainPart().getName(), cardRules.getOtherPart().getName()));
|
||||||
|
} else {
|
||||||
this.createDLObjects(cardRules.getPictureUrl(), cardRules.getMainPart().getName());
|
this.createDLObjects(cardRules.getPictureUrl(), cardRules.getMainPart().getName());
|
||||||
|
}
|
||||||
|
|
||||||
ICardCharacteristics secondSide = cardRules.getOtherPart();
|
ICardCharacteristics secondSide = cardRules.getOtherPart();
|
||||||
if (secondSide != null && cardRules.getSplitType() == CardSplitType.Transform) {
|
if (secondSide != null && cardRules.getSplitType() == CardSplitType.Transform) {
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
package forge.gui.home;
|
package forge.gui.home;
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.FocusEvent;
|
import java.awt.event.FocusEvent;
|
||||||
import java.awt.event.FocusListener;
|
import java.awt.event.FocusListener;
|
||||||
|
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
import forge.gui.toolbox.FSkin;
|
import forge.gui.toolbox.FSkin;
|
||||||
|
|
||||||
@@ -30,5 +33,17 @@ public class StartButton extends JButton {
|
|||||||
setIcon(FSkin.getIcon(FSkin.ButtonImages.IMG_BTN_START_OVER));
|
setIcon(FSkin.getIcon(FSkin.ButtonImages.IMG_BTN_START_OVER));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
setEnabled(false);
|
||||||
|
|
||||||
|
// ensure the click action can resolve before we allow the button to be clicked again
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override public void run() { setEnabled(true); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import forge.Command;
|
|||||||
import forge.Constant;
|
import forge.Constant;
|
||||||
import forge.Constant.Preferences;
|
import forge.Constant.Preferences;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
|
import forge.card.cardfactory.CardFactory;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
import forge.card.cardfactory.CardFactoryUtil;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.control.input.Input;
|
import forge.control.input.Input;
|
||||||
@@ -298,7 +299,7 @@ public class CField implements ICDoc {
|
|||||||
faceDown.setName("Face Down");
|
faceDown.setName("Face Down");
|
||||||
choices2.add(faceDown);
|
choices2.add(faceDown);
|
||||||
} else {
|
} else {
|
||||||
final Card faceDown = Singletons.getModel().getCardFactory().copyCard(crd);
|
final Card faceDown = CardFactory.copyCard(crd);
|
||||||
faceDown.setState(CardCharacteristicName.Original);
|
faceDown.setState(CardCharacteristicName.Original);
|
||||||
choices2.add(faceDown);
|
choices2.add(faceDown);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -221,6 +221,7 @@ public class CardFaceSymbols {
|
|||||||
g.drawImage(image, x, y, null);
|
g.drawImage(image, x, y, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* getWidth.
|
* getWidth.
|
||||||
@@ -239,4 +240,8 @@ public class CardFaceSymbols {
|
|||||||
//System.out.println(String.format("%d for %s", width, manaCost.toString()));
|
//System.out.println(String.format("%d for %s", width, manaCost.toString()));
|
||||||
return width * 14;
|
return width * 14;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getHeight() {
|
||||||
|
return 14;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ package forge.item;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
@@ -80,7 +79,7 @@ public final class CardDb {
|
|||||||
* @param list
|
* @param list
|
||||||
* the new up
|
* the new up
|
||||||
*/
|
*/
|
||||||
public static void setup(final Iterator<CardRules> list) {
|
public static void setup(final Iterable<CardRules> list) {
|
||||||
if (CardDb.commonCards != null) {
|
if (CardDb.commonCards != null) {
|
||||||
throw new RuntimeException("CardDb has already been initialized, don't do it twice please");
|
throw new RuntimeException("CardDb has already been initialized, don't do it twice please");
|
||||||
}
|
}
|
||||||
@@ -425,9 +424,9 @@ public final class CardDb {
|
|||||||
uniqueSpecialCards.put(cardName, lastAdded);
|
uniqueSpecialCards.put(cardName, lastAdded);
|
||||||
}
|
}
|
||||||
|
|
||||||
CardSorter(final Iterator<CardRules> parser) {
|
CardSorter(final Iterable<CardRules> parser) {
|
||||||
while (parser.hasNext()) {
|
for (CardRules cr : parser) {
|
||||||
this.addNewCard(parser.next());
|
this.addNewCard(cr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import forge.CardUtil;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.CardRarity;
|
import forge.card.CardRarity;
|
||||||
import forge.card.CardRules;
|
import forge.card.CardRules;
|
||||||
|
import forge.card.cardfactory.CardFactory;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
|
|
||||||
|
|
||||||
@@ -295,7 +296,7 @@ public final class CardPrinted implements Comparable<IPaperCard>, InventoryItemF
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Card toForgeCard(Player owner) {
|
public Card toForgeCard(Player owner) {
|
||||||
final Card c = Singletons.getModel().getCardFactory().getCard(this, owner);
|
final Card c = CardFactory.getCard(this, owner);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package forge.item;
|
package forge.item;
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.Singletons;
|
|
||||||
import forge.card.CardRarity;
|
import forge.card.CardRarity;
|
||||||
import forge.card.CardRules;
|
import forge.card.CardRules;
|
||||||
|
import forge.card.cardfactory.CardFactory;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
|
|
||||||
public class CardToken implements InventoryItemFromSet, IPaperCard {
|
public class CardToken implements InventoryItemFromSet, IPaperCard {
|
||||||
@@ -40,7 +40,7 @@ public class CardToken implements InventoryItemFromSet, IPaperCard {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Card toForgeCard(Player owner) {
|
public Card toForgeCard(Player owner) {
|
||||||
final Card c = Singletons.getModel().getCardFactory().getCard(this, owner);
|
final Card c = CardFactory.getCard(this, owner);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,9 @@ import forge.card.CardBlock;
|
|||||||
import forge.card.EditionCollection;
|
import forge.card.EditionCollection;
|
||||||
import forge.card.FatPackData;
|
import forge.card.FatPackData;
|
||||||
import forge.card.FormatCollection;
|
import forge.card.FormatCollection;
|
||||||
import forge.card.cardfactory.CardFactory;
|
import forge.card.cardfactory.CardStorageReader;
|
||||||
import forge.deck.CardCollections;
|
import forge.deck.CardCollections;
|
||||||
|
import forge.error.BugReporter;
|
||||||
import forge.error.ExceptionHandler;
|
import forge.error.ExceptionHandler;
|
||||||
import forge.game.GameState;
|
import forge.game.GameState;
|
||||||
import forge.game.GameType;
|
import forge.game.GameType;
|
||||||
@@ -41,8 +42,11 @@ import forge.game.MatchController;
|
|||||||
import forge.game.limited.GauntletMini;
|
import forge.game.limited.GauntletMini;
|
||||||
import forge.game.player.LobbyPlayer;
|
import forge.game.player.LobbyPlayer;
|
||||||
import forge.gauntlet.GauntletData;
|
import forge.gauntlet.GauntletData;
|
||||||
|
import forge.gui.GuiUtils;
|
||||||
|
import forge.item.CardDb;
|
||||||
import forge.properties.ForgePreferences;
|
import forge.properties.ForgePreferences;
|
||||||
import forge.properties.ForgePreferences.FPref;
|
import forge.properties.ForgePreferences.FPref;
|
||||||
|
import forge.properties.NewConstants;
|
||||||
import forge.quest.QuestController;
|
import forge.quest.QuestController;
|
||||||
import forge.quest.QuestWorld;
|
import forge.quest.QuestWorld;
|
||||||
import forge.quest.data.QuestPreferences;
|
import forge.quest.data.QuestPreferences;
|
||||||
@@ -74,7 +78,6 @@ public enum FModel {
|
|||||||
private GauntletData gauntletData;
|
private GauntletData gauntletData;
|
||||||
private GauntletMini gauntlet;
|
private GauntletMini gauntlet;
|
||||||
|
|
||||||
private final CardFactory cardFactory;
|
|
||||||
private final QuestController quest;
|
private final QuestController quest;
|
||||||
private final CardCollections decks;
|
private final CardCollections decks;
|
||||||
|
|
||||||
@@ -144,7 +147,16 @@ public enum FModel {
|
|||||||
this.loadDynamicGamedata();
|
this.loadDynamicGamedata();
|
||||||
|
|
||||||
// Loads all cards (using progress bar).
|
// Loads all cards (using progress bar).
|
||||||
this.cardFactory = new CardFactory();
|
GuiUtils.checkEDT("CardFactory$constructor", false);
|
||||||
|
final CardStorageReader reader = new CardStorageReader(NewConstants.CARD_DATA_DIR.defaultLoc, true);
|
||||||
|
try {
|
||||||
|
// this fills in our map of card names to Card instances.
|
||||||
|
CardDb.setup(reader.loadCards());
|
||||||
|
|
||||||
|
} catch (final Exception ex) {
|
||||||
|
BugReporter.reportException(ex);
|
||||||
|
}
|
||||||
|
|
||||||
this.decks = new CardCollections();
|
this.decks = new CardCollections();
|
||||||
this.quest = new QuestController();
|
this.quest = new QuestController();
|
||||||
}
|
}
|
||||||
@@ -380,14 +392,6 @@ public enum FModel {
|
|||||||
return gameState;
|
return gameState;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: Write javadoc for this method.
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public CardFactory getCardFactory() {
|
|
||||||
return cardFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GauntletMini getGauntletMini() {
|
public GauntletMini getGauntletMini() {
|
||||||
|
|
||||||
if (gauntlet == null) {
|
if (gauntlet == null) {
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ import forge.util.storage.IStorageView;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class QuestUtilUnlockSets {
|
public class QuestUtilUnlockSets {
|
||||||
|
private static int UNLOCK_COST = 4000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Consider unlocking a new expansion in limited quest format.
|
* Consider unlocking a new expansion in limited quest format.
|
||||||
@@ -66,10 +67,10 @@ public class QuestUtilUnlockSets {
|
|||||||
final List<ImmutablePair<CardEdition, Integer>> setPrices = new ArrayList<ImmutablePair<CardEdition, Integer>>();
|
final List<ImmutablePair<CardEdition, Integer>> setPrices = new ArrayList<ImmutablePair<CardEdition, Integer>>();
|
||||||
|
|
||||||
for (CardEdition ed : getUnlockableEditions(qData)) {
|
for (CardEdition ed : getUnlockableEditions(qData)) {
|
||||||
int price = 7500;
|
int price = UNLOCK_COST;
|
||||||
if (mapPrices.containsKey(ed.getName() + " Booster Pack")) {
|
if (mapPrices.containsKey(ed.getName() + " Booster Pack")) {
|
||||||
price = Math.max(new Double(60 * Math.pow(Math.sqrt(mapPrices.get(ed.getName()
|
price = Math.max(new Double(60 * Math.pow(Math.sqrt(mapPrices.get(ed.getName()
|
||||||
+ " Booster Pack")), 1.65)).intValue(), 7500);
|
+ " Booster Pack")), 1.65)).intValue(), UNLOCK_COST);
|
||||||
}
|
}
|
||||||
setPrices.add(ImmutablePair.of(ed, price));
|
setPrices.add(ImmutablePair.of(ed, price));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,10 +36,13 @@ import javax.swing.JRootPane;
|
|||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
|
import forge.CardCharacteristicName;
|
||||||
import forge.CounterType;
|
import forge.CounterType;
|
||||||
import forge.ImageCache;
|
import forge.ImageCache;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.CardEdition;
|
import forge.card.CardEdition;
|
||||||
|
import forge.card.CardSplitType;
|
||||||
|
import forge.card.mana.ManaCost;
|
||||||
import forge.gui.CardContainer;
|
import forge.gui.CardContainer;
|
||||||
import forge.gui.toolbox.CardFaceSymbols;
|
import forge.gui.toolbox.CardFaceSymbols;
|
||||||
import forge.properties.ForgePreferences.FPref;
|
import forge.properties.ForgePreferences.FPref;
|
||||||
@@ -351,6 +354,17 @@ public class CardPanel extends JPanel implements CardContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Write javadoc for this method.
|
||||||
|
* @param g
|
||||||
|
* @param manaCost
|
||||||
|
*/
|
||||||
|
private void drawManaCost(final Graphics g, ManaCost cost, int deltaY ) {
|
||||||
|
int width = CardFaceSymbols.getWidth(cost);
|
||||||
|
int height = CardFaceSymbols.getHeight();
|
||||||
|
CardFaceSymbols.draw(g, cost, (this.cardXOffset + (this.cardWidth / 2)) - (width / 2), deltaY + this.cardYOffset + (this.cardHeight / 2) - height/2);
|
||||||
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
protected final void paintChildren(final Graphics g) {
|
protected final void paintChildren(final Graphics g) {
|
||||||
@@ -361,10 +375,16 @@ public class CardPanel extends JPanel implements CardContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.showCastingCost) {
|
if (this.showCastingCost) {
|
||||||
int width = CardFaceSymbols.getWidth(this.getGameCard().getManaCost());
|
|
||||||
if (this.cardWidth < 200) {
|
if (this.cardWidth < 200) {
|
||||||
CardFaceSymbols.draw(g, this.getGameCard().getManaCost(), (this.cardXOffset + (this.cardWidth / 2))
|
Card gameCard = this.getGameCard();
|
||||||
- (width / 2), this.cardYOffset + (this.cardHeight / 2));
|
boolean showSplitMana = gameCard.getRules() != null && gameCard.getRules().getSplitType() == CardSplitType.Split && gameCard.getCurState() == CardCharacteristicName.Original;
|
||||||
|
if ( !showSplitMana ) {
|
||||||
|
drawManaCost(g, gameCard.getManaCost(), 0);
|
||||||
|
} else {
|
||||||
|
drawManaCost(g, gameCard.getRules().getMainPart().getManaCost(), +12);
|
||||||
|
drawManaCost(g, gameCard.getRules().getOtherPart().getManaCost(), -12);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public class Generate2ColorDeckTest {
|
|||||||
@Test(enabled = false)
|
@Test(enabled = false)
|
||||||
public void generate2ColorDeckTest1() {
|
public void generate2ColorDeckTest1() {
|
||||||
final Generate2ColorDeck gen = new Generate2ColorDeck("white", "blue");
|
final Generate2ColorDeck gen = new Generate2ColorDeck("white", "blue");
|
||||||
final ItemPoolView<CardPrinted> cardList = gen.get2ColorDeck(60, null);
|
final ItemPoolView<CardPrinted> cardList = gen.getDeck(60, null);
|
||||||
Assert.assertNotNull(cardList);
|
Assert.assertNotNull(cardList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public class Generate3ColorDeckTest {
|
|||||||
@Test(timeOut = 1000, enabled = false)
|
@Test(timeOut = 1000, enabled = false)
|
||||||
public void generate3ColorDeckTest1() {
|
public void generate3ColorDeckTest1() {
|
||||||
final Generate3ColorDeck gen = new Generate3ColorDeck("white", "blue", "black");
|
final Generate3ColorDeck gen = new Generate3ColorDeck("white", "blue", "black");
|
||||||
final ItemPoolView<CardPrinted> cardList = gen.get3ColorDeck(60, null);
|
final ItemPoolView<CardPrinted> cardList = gen.getDeck(60, null);
|
||||||
Assert.assertNotNull(cardList);
|
Assert.assertNotNull(cardList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public class Generate5ColorDeckTest {
|
|||||||
@Test(timeOut = 1000, enabled = false)
|
@Test(timeOut = 1000, enabled = false)
|
||||||
public void generate5ColorDeckTest1() {
|
public void generate5ColorDeckTest1() {
|
||||||
final Generate5ColorDeck gen = new Generate5ColorDeck();
|
final Generate5ColorDeck gen = new Generate5ColorDeck();
|
||||||
final ItemPoolView<CardPrinted> cardList = gen.get5ColorDeck(60, null);
|
final ItemPoolView<CardPrinted> cardList = gen.getDeck(60, null);
|
||||||
Assert.assertNotNull(cardList);
|
Assert.assertNotNull(cardList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user