merged limited to trunk

master
melvin 2011-05-19 16:22:33 +08:00
commit 2114cb3980
77 changed files with 2440 additions and 4365 deletions

View File

@ -1,46 +0,0 @@
<project name="Magarena" basedir="." default="jar">
<description>
ANT Build file for Magarena.
</description>
<property environment="env"/>
<property name="debuglevel" value="source,lines,vars"/>
<property name="target" value="1.6"/>
<property name="source" value="1.6"/>
<!-- init - Create temporary directory to build the program -->
<target name="init">
<mkdir dir="build"/>
</target>
<!-- clean - Remove temporary directory -->
<target name="clean">
<delete dir="build"/>
</target>
<!-- build - Compile sources and copy resources to build directory -->
<target depends="init" name="build">
<javac debug="true" debuglevel="${debuglevel}" destdir="build" source="${source}" target="${target}">
<src path="src"/>
</javac>
<copy includeemptydirs="false" todir="build">
<fileset dir="resources">
<exclude name="**/.svn"/>
</fileset>
</copy>
</target>
<!-- jar (default target) - Create .jar file -->
<target depends="build" name="jar">
<jar destfile="launch4j/Magarena.jar" basedir="build" includes="**/*.*">
<manifest>
<attribute name="Main-Class" value="magic.MagicMain" />
</manifest>
</jar>
</target>
<!-- javadoc - Generate Javadoc -->
<target name="javadoc">
<javadoc sourcepath="src" destdir="javadoc" />
</target>
</project>

View File

@ -1,24 +0,0 @@
# suggested by est...@gmail.com, http://code.google.com/p/arena-card-game/issues/detail?id=52
# 7 creatures
2 Darkslick Drake
1 Draining Whelk
3 Guard Gomazoa
2 Man-o'-War
1 Murkfiend Liege
1 Sphinx of Lost Truths
2 Spiketail Hatchling
# 9 spells
1 Dissipation Field
1 Flight of Fancy
2 Followed Footsteps
1 Halcyon Glaze
1 Narcolepsy
1 Rite of Replication
2 Sword of Body and Mind
1 Time Warp
2 Twincast
# 1 lands
16 Island

View File

@ -1,30 +0,0 @@
# suggested by LSK, http://www.slightlymagic.net/forum/viewtopic.php?f=82&t=4233#p57234
# 9 creatures
1 Hypnotic Specter
1 Liliana's Specter
1 Vampire Nighthawk
1 Carnifex Demon
1 Massacre Wurm
1 Midnight Banshee
1 Grave Titan
1 Mirri the Cursed
1 Skinrender
# 14 spells
1 Black Sun's Zenith
1 Reanimate
1 Zombify
1 Beacon of Unrest
1 Recover
1 Phyrexian Arena
1 Hideous End
1 Smother
1 Sign in Blood
1 Cruel Edict
1 Disfigure
1 Last Gasp
1 Go for the Throat
1 Quest for the Gravelord
# 17 lands
17 Swamp

View File

@ -1,30 +0,0 @@
# suggested by LSK, http://www.slightlymagic.net/forum/viewtopic.php?f=82&t=4233#p57268
# 15 creatures
1 Kavu Titan
1 Blurred Mongoose
1 River Boa
1 Mire Boa
1 Silhana Ledgewalker
1 Sacred Wolf
1 Troll Ascetic
1 Thrun, the Last Troll
1 Chameleon Colossus
1 Mist Leopard
1 Kodama of the North Tree
1 Terra Stomper
1 Kalonian Behemoth
1 Llanowar Elves
1 Noble Hierarch
# 8 spells
1 Soul's Majesty
1 Harmonize
1 Rancor
1 Giant Growth
1 Elephant Guide
1 Wildsize
1 Bestial Menace
1 Snake Umbra
# Land
17 Forest

View File

@ -1,41 +0,0 @@
# suggested by LSK, http://www.slightlymagic.net/forum/viewtopic.php?f=82&t=4233#p57220
# 16 creatures
1 Putrid Leech
1 Sprouting Thrinax
1 Broodmate Dragon
1 Ashenmoor Gouger
1 Jund Hackblade
1 Boggart Ram-Gang
1 Ember Hauler
1 Flametongue Kavu
1 Siege-Gang Commander
1 Skinrender
1 Taurean Mauler
1 Birds of Paradise
1 Vampire Nighthawk
1 Murderous Redcap
1 Madrush Cyclops
1 Lord of Shatterskull Pass
1 Chameleon Colossus
# 7 spells
1 Terminate
1 Maelstrom Pulse
1 Lightning Bolt
1 Blightning
1 Basilisk Collar
1 Burst Lightning
1 Doom Blade
# 12 lands
4 Savage Lands
1 Raging Ravine
1 Rootbound Crag
1 Stomping Ground
1 Blackcleave Cliffs
1 Dragonskull Summit
1 Blood Crypt
1 Copperline Gorge
2 Forest
2 Mountain
1 Swamp

View File

@ -1,34 +0,0 @@
# suggested by LSK, http://www.slightlymagic.net/forum/viewtopic.php?f=82&t=4233#p57268
# 15 creatures
1 Noble Hierarch
1 Baneslayer Angel
1 Wall of Reverence
1 Knight of Meadowgrain
1 Lone Missionary
1 Suture Priest
1 Kitchen Finks
1 Oracle of Nectars
1 Guardian Seraph
1 Lightkeeper of Emeria
1 Loxodon Hierarch
1 Mycoid Shepherd
1 Ravenous Baloth
1 Archon of Redemption
1 Pelakka Wurm
# 8 spells
1 Behemoth Sledge
1 Loxodon Warhammer
1 Armadillo Cloak
1 Solemn Offering
1 Chastise
1 Withstand
1 True Conviction
1 Victory's Herald
# 17 lands
3 Graypelt Refuge
2 Razorverge Thicket
1 Temple Garden
6 Plains
5 Forest

View File

@ -1,30 +0,0 @@
# suggested by LSK, http://www.slightlymagic.net/forum/viewtopic.php?f=82&t=4233#p57233
# 13 creatures
1 Frenzied Goblin
1 Goblin Bushwhacker
1 Chandra's Spitfire
1 Cunning Sparkmage
1 Goblin Artillery
1 Ember Hauler
1 Fireslinger
1 Raging Goblin
1 Mogg Fanatic
1 Cinder Elemental
1 Flametongue Kavu
1 Fire Servant
1 Flameblast Dragon
# 10 spells
1 Burst Lightning
1 Flame Slash
1 Lightning Bolt
1 Seal of Fire
1 Incinerate
1 Char
1 Puncture Blast
1 Beacon of Destruction
1 Gratuitous Violence
1 Sword of Fire and Ice
#17 lands
17 Mountain

View File

@ -1,33 +0,0 @@
# suggested by LSK, from http://www.slightlymagic.net/forum/viewtopic.php?f=82&t=4233#p57209
# 17 creatures
1 Mirror Entity
1 Goblin Wardriver
1 Mogg Fanatic
1 Accorder Paladin
1 Hero of Bladehold
1 Rakdos Guildmage
1 Siege-Gang Commander
1 Suture Priest
1 Veteran Armorer
1 Elesh Norn, Grand Cenobite
1 Frenzied Goblin
1 Flametongue Kavu
1 Flame-Kin Zealot
1 Goblin Bushwhacker
1 Goblin Chieftain
1 Goblin Shortcutter
1 Kiki-Jiki, Mirror Breaker
# 6 spells
1 Rise of the Hobgoblins
1 Eldrazi Monument
1 Martial Coup
1 Glorious Anthem
1 Incinerate
1 Lightning Bolt
# 7 lands
4 Sacred Foundry
3 Jungle Shrine
5 Plains
5 Mountain

View File

@ -1,42 +0,0 @@
# suggested by LSK, http://www.slightlymagic.net/forum/viewtopic.php?f=82&t=4233&start=15#p57309
# 15 creatures
1 Prickly Boggart
1 Birds of Paradise
1 Noble Hierarch
1 Llanowar Elves
1 Flametongue Kavu
1 Goblin Gaveleer
1 Silhana Ledgewalker
1 Lord of Extinction
1 Mogg Fanatic
1 Marisi's Twinclaws
1 Rakdos Guildmage
1 Defiant Elf
1 Treetop Scout
1 Vampire Nighthawk
1 Goblin Deathraiders
# 5 equipment
1 Sword of Light and Shadow
1 Sword of Body and Mind
1 Sword of Feast and Famine
1 Sword of Fire and Ice
1 Skullclamp
# 3 other
1 Corpsehatch
1 Awakening Zone
1 Doom Blade
# 17 land
1 Savage Lands
1 Dragonskull Summit
1 Copperline Gorge
1 Blackcleave Cliffs
1 Stomping Ground
1 Overgrown Tomb
1 Blood Crypt
1 Rootbound Crag
2 Mountain
4 Forest
3 Swamp

View File

@ -1,30 +0,0 @@
# suggested by LSK, http://www.slightlymagic.net/forum/viewtopic.php?f=82&t=4233&start=15#p57309
# 9 creatures
1 Sphinx of Magosi
1 Keiga, the Tide Star
1 Draining Whelk
1 Sphinx of Lost Truths
1 Glen Elendra Archmage
1 Venser, Shaper Savant
1 Merfolk Seastalkers
1 Cursecatcher
1 Spiketail Hatchling
# 13 spells
1 Time Warp
1 Evacuation
1 Sleep
1 Sift
1 Time Ebb
1 Repulse
1 Exhaustion
1 Divination
1 Mana Leak
1 Essence Scatter
1 Into the Roil
1 Counterspell
1 Force Spike
1 Rite of Replication
#17 lands
17 Island

View File

@ -1,34 +0,0 @@
# suggested by LSK, http://www.slightlymagic.net/forum/viewtopic.php?f=82&t=4233#p57232
#18 creatures
1 Suntail Hawk
1 Zephyr Sprite
1 Mistral Charger
1 Sea Eagle
1 Courier Hawk
1 Talon Trooper
1 Plumeveil
1 Avian Changeling
1 Silkbind Faerie
1 Razorfoot Griffin
1 Archon of Redemption
1 Air Servant
1 Serra Angel
1 Mahamoti Djinn
1 Goliath Sphinx
1 Sunblast Angel
1 Iridescent Angel
1 Akroma, Angel of Wrath
#5 spells
1 Divination
1 Mana Leak
1 Turn to Mist
1 Kiss of the Amesha
1 Solemn Offering
#17 lands
2 Celestial Colonnade
2 Hallowed Fountain
2 Seachrome Coast
6 Island
5 Plains

View File

@ -1,20 +0,0 @@
# suggested by est...@gmail.com, http://code.google.com/p/arena-card-game/issues/detail?id=52
# 5 creatures
2 Akrasan Squire
3 Captain of the Watch
1 Guardian Seraph
3 Hero of Bladehold
2 Wall of Reverence
# 7 spells
2 Accorder's Shield
2 Chastise
3 Glorious Anthem
2 Pacifism
1 Promise of Bunrei
1 Safe Passage
2 Vulshok Morningstar
# 1 lands
16 Plains

View File

@ -1,31 +0,0 @@
# suggested by Aswan jaguar, http://www.slightlymagic.net/forum/viewtopic.php?f=82&t=4233#p57237
# 16 creatures
2 Llanowar Elves
1 Cylian Elf
1 Defiant Elf
1 Elvish Archers
1 Elvish Warrior
2 Ezuri's Archers
1 Llanowar Knight
2 Oracle of Nectars
1 Safehold Elite
2 Tolsimir Wolfblood
2 Wilt-Leaf Cavaliers
# 8 spells
1 Giant Growth
1 Naturalize
1 Plummet
2 Sigil Blessing
2 Raking Canopy
1 Hurricane
# 6 lands
1 Graypelt Refuge
1 Jungle Shrine
8 Forest
1 Razorverge Thicket
1 Temple Garden
4 Sunpetal Grove

Binary file not shown.

Binary file not shown.

View File

@ -1,38 +1,54 @@
Magarena by ubeefx
==================
Magarena Limited Edition by ubeefx
==================================
Project page url : http://magarena.dyndns.org or http://code.google.com/p/arena-card-game/
The Limited Edition needs a premade Magarena data folder that must be downloaded separately.
The download comes as a password protected zip archive and the location can be found on the forum.
This archive must be unzipped to the same folder as where this release is unzipped.
The data folder is not fully compatible with the regular release of Magarena.
There must be a Java Runtime 6 (java.com) installed on your computer to play.
Installing on Windows is quite simple, just put Magarena.exe on your desktop and execute.
To obtain the Java jar, Magarena.exe can simply be renamed to Magarena.jar because it is also an archive.
To execute the Java jar, use java -Xmx256m -jar Magarena.jar.
If a Magarena folder is present where the program is executed, that folder is used as data folder.
Do not forget to execute "Download images" in the Arena menu the first time you run a new release.
Otherwise you will see a lot of question marks. The application stops automatically when downloading is finished.
An executable is provided for Windows. To execute the Java jar, use java -Xmx256m -jar Magarena.jar.
Magarena supports the following keyboard shortcuts :
- Space or Right key : action button
- Escape or Left key : undo button
- Enter key : switch between graphical and text mode
- F1 key : show or hide game messages
The UI of Magarena can be customized with downloadable themes coming in zip files.
A theme pack with five color themes can be downloaded on the project page.
The theme pack should be unzipped into the mods folder of the Magarena data folder.
There are also separate themes like the mystic theme which can be placed directly into the mods folder.
It is best to restart the application each time after switching to one of these themes in preferences.
Thanks to epiko for creating the very nice Magarena logo and the amazing color themes.
Thanks to Salasnet for the felt theme.
Thanks to singularita for creating the scripts to add over 300 additional creature cards to Magarena.
You can play with these cards by selecting the all cube in the "New duel" dialog.
- F1 or M key : show or hide game messages
The desired AI can be selected in the preferences.
Recommended MiniMax AI difficulty level for the best balance of speed and strength is the default 6.
The Vegas AI should be fast on all difficulty levels.
Thanks to Melvin Zhang for implementing the Monte Carlo Tree Search AI.
Have fun!
Thanks to everyone one the CCGHQ forum (slightlymagic.net).
Thanks to epiko for creating the very nice Magarena logo and the amazing color themes.
Thanks to Salasnet for the felt theme and pedro1973 for the dark battle theme.
Thanks to singularita for creating the scripts to add over 300 additional creature cards.
Thanks to Melvin Zhang for implementing the Monte Carlo Tree Search AI.
Thanks for your support and have fun!
Release LE 1.13 (April 24, 2011)
===============
- default cube (600 cards)
- all cube (900 cards)
- added sound effects, disabled by default, can be enabled in preferences
- right mouse click on hand zone can now be used as a shortcut for action button
- infect and wither abilities are also shown on cards with same icon as deathtouch
Release LE 1.12 (April 17, 2011)
===============
- default cube (567 cards)
- all cube (888 cards)
- modified game to work with a premade Magarena data folder
- added selectable avatar sets in preferences, separate from theme
- added unlimited undo support
- added "Reset game" in menu, undoing all moves
- added M key as an additional shortcut for messages
Release 1.11 (April 11, 2011)
============
@ -48,7 +64,7 @@ Release 1.11 (April 11, 2011)
- three new AI implementations are available next to the default MiniMax AI : Monte Carlo, Vegas and Random
- the preferred AI can be selected in preferences, the deck strength calculator always uses MiniMax AI
- added New and Load Duel buttons on startup screen
- added option to a select random deck from decks folder in New Duel dialog (folder icon)
- added option to select a random deck from decks folder in New Duel dialog (folder icon)
- fixed Lightning Helix, it can now target your own permanents with filter legal targets enabled
@ -189,4 +205,4 @@ Release 1.1 (December 7, 2010)
Release 1.0 (November 25, 2010)
===========
- initial release
- initial release (450 cards)

693
launch4j/gpl-3.0.html Normal file
View File

@ -0,0 +1,693 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>GNU General Public License v3.0 - GNU Project - Free Software Foundation (FSF)</title>
<link rel="alternate" type="application/rdf+xml" href="http://www.gnu.org/licenses/gpl-3.0.rdf">
</head><body>
<h3 style="text-align: center;">GNU GENERAL PUBLIC LICENSE</h3>
<p style="text-align: center;">Version 3, 29 June 2007</p>
<p>Copyright © 2007 Free Software Foundation, Inc.
&lt;<a href="http://fsf.org/">http://fsf.org/</a>&gt;</p><p>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.</p>
<h3><a name="preamble"></a>Preamble</h3>
<p>The GNU General Public License is a free, copyleft license for
software and other kinds of works.</p>
<p>The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.</p>
<p>When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.</p>
<p>To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.</p>
<p>For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.</p>
<p>Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.</p>
<p>For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.</p>
<p>Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.</p>
<p>Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.</p>
<p>The precise terms and conditions for copying, distribution and
modification follow.</p>
<h3><a name="terms"></a>TERMS AND CONDITIONS</h3>
<h4><a name="section0"></a>0. Definitions.</h4>
<p>“This License” refers to version 3 of the GNU General Public License.</p>
<p>“Copyright” also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.</p>
<p>“The Program” refers to any copyrightable work licensed under this
License. Each licensee is addressed as “you”. “Licensees” and
“recipients” may be individuals or organizations.</p>
<p>To “modify” a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a “modified version” of the
earlier work or a work “based on” the earlier work.</p>
<p>A “covered work” means either the unmodified Program or a work based
on the Program.</p>
<p>To “propagate” a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.</p>
<p>To “convey” a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.</p>
<p>An interactive user interface displays “Appropriate Legal Notices”
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.</p>
<h4><a name="section1"></a>1. Source Code.</h4>
<p>The “source code” for a work means the preferred form of the work
for making modifications to it. “Object code” means any non-source
form of a work.</p>
<p>A “Standard Interface” means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.</p>
<p>The “System Libraries” of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
“Major Component”, in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.</p>
<p>The “Corresponding Source” for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.</p>
<p>The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.</p>
<p>The Corresponding Source for a work in source code form is that
same work.</p>
<h4><a name="section2"></a>2. Basic Permissions.</h4>
<p>All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.</p>
<p>You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.</p>
<p>Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.</p>
<h4><a name="section3"></a>3. Protecting Users' Legal Rights From Anti-Circumvention Law.</h4>
<p>No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.</p>
<p>When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.</p>
<h4><a name="section4"></a>4. Conveying Verbatim Copies.</h4>
<p>You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.</p>
<p>You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.</p>
<h4><a name="section5"></a>5. Conveying Modified Source Versions.</h4>
<p>You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:</p>
<ul>
<li>a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.</li>
<li>b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
“keep intact all notices”.</li>
<li>c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.</li>
<li>d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.</li>
</ul>
<p>A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
“aggregate” if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.</p>
<h4><a name="section6"></a>6. Conveying Non-Source Forms.</h4>
<p>You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:</p>
<ul>
<li>a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.</li>
<li>b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.</li>
<li>c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.</li>
<li>d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.</li>
<li>e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.</li>
</ul>
<p>A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.</p>
<p>A “User Product” is either (1) a “consumer product”, which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, “normally used” refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.</p>
<p>“Installation Information” for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.</p>
<p>If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).</p>
<p>The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.</p>
<p>Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.</p>
<h4><a name="section7"></a>7. Additional Terms.</h4>
<p>“Additional permissions” are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.</p>
<p>When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.</p>
<p>Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:</p>
<ul>
<li>a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or</li>
<li>b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or</li>
<li>c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or</li>
<li>d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or</li>
<li>e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or</li>
<li>f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.</li>
</ul>
<p>All other non-permissive additional terms are considered “further
restrictions” within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.</p>
<p>If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.</p>
<p>Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.</p>
<h4><a name="section8"></a>8. Termination.</h4>
<p>You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).</p>
<p>However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.</p>
<p>Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.</p>
<p>Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.</p>
<h4><a name="section9"></a>9. Acceptance Not Required for Having Copies.</h4>
<p>You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.</p>
<h4><a name="section10"></a>10. Automatic Licensing of Downstream Recipients.</h4>
<p>Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.</p>
<p>An “entity transaction” is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.</p>
<p>You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.</p>
<h4><a name="section11"></a>11. Patents.</h4>
<p>A “contributor” is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's “contributor version”.</p>
<p>A contributor's “essential patent claims” are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, “control” includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.</p>
<p>Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.</p>
<p>In the following three paragraphs, a “patent license” is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To “grant” such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.</p>
<p>If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. “Knowingly relying” means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.</p>
<p>If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.</p>
<p>A patent license is “discriminatory” if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.</p>
<p>Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.</p>
<h4><a name="section12"></a>12. No Surrender of Others' Freedom.</h4>
<p>If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.</p>
<h4><a name="section13"></a>13. Use with the GNU Affero General Public License.</h4>
<p>Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.</p>
<h4><a name="section14"></a>14. Revised Versions of this License.</h4>
<p>The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.</p>
<p>Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License “or any later version” applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.</p>
<p>If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.</p>
<p>Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.</p>
<h4><a name="section15"></a>15. Disclaimer of Warranty.</h4>
<p>THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</p>
<h4><a name="section16"></a>16. Limitation of Liability.</h4>
<p>IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.</p>
<h4><a name="section17"></a>17. Interpretation of Sections 15 and 16.</h4>
<p>If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.</p>
<p>END OF TERMS AND CONDITIONS</p>
<h3><a name="howto"></a>How to Apply These Terms to Your New Programs</h3>
<p>If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.</p>
<p>To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the “copyright” line and a pointer to where the full notice is found.</p>
<pre> &lt;one line to give the program's name and a brief idea of what it does.&gt;
Copyright (C) &lt;year&gt; &lt;name of author&gt;
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 &lt;http://www.gnu.org/licenses/&gt;.
</pre>
<p>Also add information on how to contact you by electronic and paper mail.</p>
<p>If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:</p>
<pre> &lt;program&gt; Copyright (C) &lt;year&gt; &lt;name of author&gt;
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
</pre>
<p>The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an “about box”.</p>
<p>You should also get your employer (if you work as a programmer) or school,
if any, to sign a “copyright disclaimer” for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
&lt;<a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>&gt;.</p>
<p>The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
&lt;<a href="http://www.gnu.org/philosophy/why-not-lgpl.html">http://www.gnu.org/philosophy/why-not-lgpl.html</a>&gt;.</p>
</body></html>

View File

@ -1,10 +0,0 @@
@echo off
set JDK_HOME=
set L4J_HOME=
del Magarena.jar
del Magarena.exe
cd ..\bin
%JDK_HOME%\bin\jar cfm ..\launch4j\Magarena.jar ..\launch4j\MANIFEST.MF magic
cd ..\launch4j
%L4J_HOME%\launch4jc.exe arena.xml
pause

View File

@ -1,876 +0,0 @@
Absorb
Accorder Paladin
Accorder's Shield
Acidic Slime
Affa Guard Hound
Air Elemental
Air Servant
Akoum Refuge
Akrasan Squire
Akroma's Memorial
Akroma, Angel of Wrath
Alpha Myr
Alpha Tyrranax
Anaba Bodyguard
Anaconda
Ancient Spider
Angel of Despair
Angel of Retribution
Angelic Shield
Angelic Wall
Anurid Murkdiver
Arachnoid
Arcane Sanctum
Arcanis the Omnipotent
Archon of Justice
Archon of Redemption
Ardent Militia
Armadillo Cloak
Armored Cancrix
Asceticism
Ashcoat Bear
Ashen Monstrosity
Ashenmoor Gouger
Assassinate
Assault Griffin
Assault Zeppelid
Aven Envoy
Aven Mimeomancer
Aven Smokeweaver
Aven Squire
Avian Changeling
Awakening Zone
Axegrinder Giant
Azure Drake
Back to Nature
Backlash
Balduvian Barbarians
Balefire Liege
Baneslayer Angel
Bant Sureblade
Barbed Battlegear
Barony Vampire
Basilisk Collar
Battle Hurda
Battlegrace Angel
Beacon of Destruction
Beacon of Unrest
Behemoth Sledge
Bellowing Tanglewurm
Beloved Chaplain
Benalish Knight
Benthic Behemoth
Berserkers of Blood Ridge
Bestial Menace
Birds of Paradise
Black Knight
Black Sun's Zenith
Blackcleave Cliffs
Blackcleave Goblin
Blade of the Sixth Pride
Bladed Pinions
Bladetusk Boar
Blaze
Blazing Specter
Blightning
Blightwidow
Blind Phantasm
Blood Crypt
Blood Knight
Bloodmark Mentor
Bloodrock Cyclops
Blurred Mongoose
Boar Umbra
Boartusk Liege
Bog Imp
Bog Raiders
Bog Tatters
Bog Wraith
Boggart Ram-Gang
Bonesplitter
Border Patrol
Boros Guildmage
Boros Recruit
Boros Swiftblade
Bottle Gnomes
Breeding Pool
Brigid, Hero of Kinsbaile
Brion Stoutarm
Brittle Effigy
Broodmate Dragon
Bull Cerodon
Bull Hippo
Burst Lightning
Butcher of Malakir
Cairn Wanderer
Canopy Spider
Canyon Minotaur
Canyon Wildcat
Captain of the Watch
Captive Flame
Caravan Hurda
Carnifex Demon
Celestial Colonnade
Centaur Courser
Cerodon Yearling
Chain Reaction
Chameleon Colossus
Chandra's Spitfire
Changeling Sentinel
Char
Charging Troll
Chastise
Child of Night
Chimeric Mass
Cinder Elemental
Cliff Threader
Clinging Darkness
Cloud Crusader
Cloud Elemental
Cloud Sprite
Cloudcrown Oak
Coast Watcher
Colossal Might
Commander Eesha
Contagious Nim
Copperline Gorge
Coral Eel
Coral Merfolk
Corpsehatch
Counterspell
Countersquall
Courier Hawk
Court Archers
Covert Operative
Craw Wurm
Crazed Goblin
Creakwood Liege
Creeping Tar Pit
Cruel Edict
Crumbling Necropolis
Cumber Stone
Cunning Sparkmage
Cursecatcher
Cylian Elf
Cystbearer
Daggerback Basilisk
Daggerclaw Imp
Dancing Scimitar
Darkslick Drake
Darkslick Shores
Darksteel Gargoyle
Darksteel Myr
Darksteel Sentinel
Dauntless Escort
Day of Judgment
Deadly Recluse
Death Grasp
Deathbringer Liege
Deathless Angel
Debtors' Knell
Defiant Elf
Deft Duelist
Deluge
Diminish
Disfigure
Dismal Failure
Dissipation Field
Divination
Diving Griffin
Doom Blade
Doomgape
Double Cleave
Douse in Gloom
Dragon Fodder
Dragon Roost
Dragonmaster Outcast
Dragonskull Summit
Dragonstalker
Draining Whelk
Drake Umbra
Drana, Kalastria Bloodchief
Dread
Dreg Reaver
Dromar, the Banisher
Dross Crocodile
Dross Prowler
Drowned Catacomb
Drudge Reavers
Dusk Imp
Duskdale Wurm
Dust Corona
Dwarven Grunt
Eager Cadet
Earth Elemental
Earthquake
Echo Mage
Eel Umbra
Eldrazi Monument
Elephant Guide
Elesh Norn, Grand Cenobite
Elite Vanguard
Elvish Archers
Elvish Warrior
Ember Hauler
Emerald Oryx
Empyrial Archangel
Enormous Baloth
Epic Proportions
Esper Battlemage
Esper Cormorants
Esper Stormblade
Essence Scatter
Ethercaste Knight
Ethersworn Adjudicator
Evacuation
Exhaustion
Ezuri's Archers
Fallen Angel
Fangren Hunter
Femeref Archers
Fervent Charge
Fighting Drake
Fire Elemental
Fire Servant
Fires of Yavimaya
Fireshrieker
Fireslinger
Fists of Ironwood
Fists of the Anvil
Flame Slash
Flame-Kin Zealot
Flameblast Dragon
Flameborn Hellion
Flametongue Kavu
Flayer Husk
Flensermite
Flight of Fancy
Followed Footsteps
Fomori Nomad
Foot Soldiers
Force Spike
Force of Savagery
Forest
Foul Imp
Frenzied Goblin
Frost Ogre
Fugitive Wizard
Fume Spitter
Furnace Whelp
Gaea's Skyfolk
Galina's Knight
Galvanic Arc
Game-Trail Changeling
Garruk's Companion
Gelectrode
Ghost Council of Orzhova
Ghostway
Giant Cockroach
Giant Growth
Giant Octopus
Giant Scorpion
Giant Solifuge
Giant Spider
Giant Warthog
Glacial Fortress
Glacial Wall
Glass Golem
Glen Elendra Archmage
Glen Elendra Liege
Glissa's Courier
Gloomhunter
Gloomwidow
Glorious Anthem
Glorious Charge
Glory Seeker
Glory of Warfare
Gluttonous Zombie
Gnarled Mass
Go for the Throat
Goblin Artillery
Goblin Brigand
Goblin Bushwhacker
Goblin Chariot
Goblin Chieftain
Goblin Deathraiders
Goblin Gaveleer
Goblin Glider
Goblin Mountaineer
Goblin Outlander
Goblin Piker
Goblin Raider
Goblin Roughrider
Goblin Ruinblaster
Goblin Shortcutter
Goblin Sky Raider
Goblin Spelunkers
Goblin Striker
Goblin War Paint
Goblin Wardriver
Godhead of Awe
Godless Shrine
Godsire
Goliath Sphinx
Goliath Spider
Gorgon Flail
Grappler Spider
Grasp of Darkness
Gratuitous Violence
Grave Titan
Gravelgill Axeshark
Graypelt Refuge
Grayscaled Gharial
Great Sable Stag
Greater Basilisk
Griffin Guide
Griffin Sentinel
Grixis Grimblade
Grizzled Leotau
Grizzly Bears
Guard Gomazoa
Guardian Seraph
Guardian of the Guildpact
Guardians of Akrasa
Guul Draz Specter
Guul Draz Vampire
Halberdier
Halcyon Glaze
Hallowed Fountain
Harmonize
Harvest Gwyllion
Hateflayer
Havenwood Wurm
Havoc Demon
Hearthfire Hobgoblin
Hellkite Overlord
Hero of Bladehold
Heroes' Reunion
Hideous End
Hill Giant
Hillcomber Giant
Hissing Miasma
Hobgoblin Dragoon
Horned Turtle
Hoverguard Observer
Hulking Cyclops
Humble Budoka
Hungry Spriggan
Hurricane
Hyena Umbra
Hypnotic Specter
Incinerate
Incurable Ogre
Indomitable Ancients
Infest
Inkfathom Infiltrator
Inkwell Leviathan
Inspirit
Into the Roil
Iridescent Angel
Iron-Barb Hellion
Isamaru, Hound of Konda
Island
Jagwasp Swarm
Jhessian Balmgiver
Jhessian Infiltrator
Jhessian Lookout
Jukai Messenger
Jund Hackblade
Jungle Shrine
Juniper Order Ranger
Juvenile Gloomwidow
Jwar Isle Refuge
Jwari Scuttler
Kabuto Moth
Kaervek the Merciless
Kalonian Behemoth
Kami of Old Stone
Kavu Titan
Kazandu Refuge
Kazuul, Tyrant of the Cliffs
Keening Banshee
Keiga, the Tide Star
Kelinore Bat
Kiki-Jiki, Mirror Breaker
Kindled Fury
King Cheetah
Kinsbaile Cavalier
Kiss of the Amesha
Kitchen Finks
Kitesail
Kitesail Apprentice
Knight Errant
Knight Exemplar
Knight of Meadowgrain
Kodama of the North Tree
Kokusho, the Evening Star
Koth's Courier
Kraken Hatchling
Kulrath Knight
Lagac Lizard
Lantern Kami
Last Gasp
Lavaborn Muse
Leaf Dancer
Leatherback Baloth
Leonin Scimitar
Leonin Skyhunter
Levitation
Lightkeeper of Emeria
Lightning Angel
Lightning Bolt
Lightning Elemental
Lightning Greaves
Lightning Helix
Lightning Reaver
Lightning Talons
Liliana's Specter
Lingering Tormentor
Llanowar Elves
Llanowar Knight
Loamdragger Giant
Lone Missionary
Longbow Archer
Lord of Extinction
Lord of Shatterskull Pass
Lotus Petal
Loxodon Hierarch
Loxodon Partisan
Loxodon Warhammer
Loxodon Wayfarer
Lumengrid Warden
Madrush Cyclops
Maelstrom Pulse
Mage Slayer
Mahamoti Djinn
Makindi Griffin
Man-o'-War
Mana Leak
Marisi's Twinclaws
Maritime Guard
Marsh Casualties
Marsh Threader
Martial Coup
Mask of Memory
Mask of Riddles
Mass of Ghouls
Massacre Wurm
Meglonoth
Memnite
Merfolk Seastalkers
Merfolk of the Pearl Trident
Messenger Falcons
Midnight Banshee
Might of Oaks
Mighty Leap
Mind Spring
Mind Stone
Mire Boa
Mirran Crusader
Mirri the Cursed
Mirri, Cat Warrior
Mirror Entity
Mist Leopard
Mistral Charger
Mnemonic Wall
Mogg Fanatic
Moonglove Extract
Moonglove Winnower
Mordant Dragon
Moriok Reaver
Moroii
Mortify
Moss Kami
Moss Monster
Mountain
Mourning Thrull
Murderous Redcap
Murkfiend Liege
Mycoid Shepherd
Mystic Snake
Nacatl Outlander
Nantuko Shade
Narcolepsy
Naturalize
Needlepeak Spider
Needleshot Gourna
Nema Siltlurker
Nemesis of Reason
Nessian Courser
Nether Horror
Neurok Invisimancer
Nezumi Cutthroat
Nightguard Patrol
Nightshade Stinger
Nip Gwyllion
Nirkana Cutthroat
Noble Hierarch
Norwood Ranger
Novablast Wurm
Nulltread Gargantuan
Oakgnarl Warrior
Offering to Asha
Ogre Sentry
Ogre Taskmaster
Ogre's Cleaver
Old Ghastbark
Omega Myr
Omnibian
Oona's Gatewarden
Oracle of Nectars
Order of the Sacred Bell
Ornithopter
Oros, the Avenger
Outrider of Jhess
Overgrown Tomb
Overwhelming Stampede
Pacifism
Paladin en-Vec
Pegasus Charger
Pelakka Wurm
Perilous Myr
Perimeter Captain
Phantom Warrior
Phyrexian Arena
Phyrexian Crusader
Phyrexian Digester
Phyrexian Hulk
Phyrexian Juggernaut
Phyrexian Vatmother
Pierce Strider
Pillarfield Ox
Pillory of the Sleepless
Pincher Beetles
Plague Beetle
Plague Stinger
Plains
Plasma Elemental
Plated Seastrider
Platinum Angel
Plover Knights
Plumeveil
Plummet
Pongify
Predator Dragon
Prickly Boggart
Priests of Norn
Promise of Bunrei
Protective Bubble
Pulse of the Tangle
Puncture Blast
Puppeteer Clique
Putrefy
Putrid Leech
Qasali Pridemage
Quest for the Gemblades
Quest for the Gravelord
Quietus Spike
Rafiq of the Many
Rage Nimbus
Raging Goblin
Raging Kavu
Raging Ravine
Rakdos Guildmage
Raking Canopy
Rally the Forces
Rampaging Baloths
Rancor
Ravenous Baloth
Razorfoot Griffin
Razorjaw Oni
Razortooth Rats
Razorverge Thicket
Reanimate
Recoil
Recover
Redwood Treefolk
Remand
Rendclaw Trow
Repulse
Retaliator Griffin
Rhox Brute
Rhox Charger
Rhox War Monk
Ridgetop Raptor
Rip-Clan Crasher
Rise of the Hobgoblins
Rite of Replication
Rith, the Awakener
River Bear
River Boa
River Kaijin
Rock Badger
Ronin Warclub
Rootbound Crag
Rootbreaker Wurm
Rootwater Commando
Rorix Bladewing
Rumbling Slum
Runeclaw Bear
Rupture Spire
Rushwood Dryad
Rustrazor Butcher
Ruthless Cullblade
Sabertooth Nishoba
Sabretooth Tiger
Sacred Foundry
Sacred Wolf
Safe Passage
Safehold Elite
Savage Lands
Savage Twister
Scaled Wurm
Scar
Scathe Zombies
Scattershot Archer
Scavenging Scarab
Scoria Elemental
Scuzzback Marauders
Scuzzback Scrapper
Sea Eagle
Seachrome Coast
Seal of Doom
Seal of Fire
Seaside Citadel
Sejiri Refuge
Sentinels of Glen Elendra
Septic Rats
Serendib Efreet
Serra Angel
Serra's Embrace
Serrated Arrows
Severed Legion
Sewn-Eye Drake
Shadowmage Infiltrator
Shanodin Dryads
Shatterskull Giant
Shepherd of the Lost
Shield of the Righteous
Shivan Wurm
Shivan Zombie
Sickle Ripper
Siege Mastodon
Siege-Gang Commander
Sift
Sigil Blessing
Sigiled Behemoth
Sigiled Paladin
Sign in Blood
Silhana Ledgewalker
Silkbind Faerie
Silver Knight
Silverback Ape
Silvercoat Lion
Silvos, Rogue Elemental
Simic Sky Swallower
Skeletal Vampire
Skinrender
Skithiryx, the Blight Dragon
Skullcage
Skullclamp
Sky Ruin Drake
Skyknight Legionnaire
Skyshroud Falcon
Slagwurm Armor
Slave of Bolas
Sleep
Slinking Serpent
Smash to Smithereens
Smite
Smoldering Butcher
Smother
Snake Umbra
Snapping Drake
Sokenzan Bruiser
Solemn Offering
Soul Feast
Soul Link
Soul's Majesty
Soul's Might
Soulbound Guardians
Souls of the Faultless
Specter's Shroud
Sphinx of Lost Truths
Sphinx of Magosi
Sphinx of the Steel Wind
Spider Umbra
Spidersilk Net
Spiketail Hatchling
Spined Wurm
Spineless Thug
Spirit of the Hearth
Spiritmonger
Spitemare
Sporecap Spider
Sprouting Thrinax
Stalker Hag
Stampeding Rhino
Standing Troops
Steadfast Guard
Steam Vents
Steel Wall
Steppe Lynx
Steward of Valeron
Stirring Wildwood
Stomper Cub
Stomping Ground
Stone Golem
Stonebrow, Krosan Hero
Stonework Puma
Storm Crow
Stormfront Pegasus
Strandwalker
Stratozeppelid
Streetbreaker Wurm
Strider Harness
Student of Warfare
Stuffy Doll
Stun Sniper
Stupor
Sunblast Angel
Sunpetal Grove
Suntail Hawk
Surveilling Sprite
Suture Priest
Swamp
Sword of Body and Mind
Sword of Feast and Famine
Sword of Fire and Ice
Sword of Light and Shadow
Sword of Vengeance
Swords to Plowshares
Sylvok Lifestaff
Szadek, Lord of Secrets
Talon Trooper
Tangle Spider
Tattermunge Maniac
Taurean Mauler
Temple Garden
Teneb, the Harvester
Terminate
Terra Stomper
Thieving Magpie
Thornweald Archer
Thoughtweft Gambit
Thrun, the Last Troll
Thunder Dragon
Thunder Strike
Thundering Giant
Thundersong Trumpeter
Tidal Kraken
Tidehollow Strix
Time Ebb
Time Warp
Titanic Ultimatum
To Arms!
Tolsimir Wolfblood
Torpor Dust
Tower Gargoyle
Trained Armodon
Trained Orgg
Trapjaw Kelpie
Tree Monkey
Treetop Scout
Treetop Sentinel
Treva, the Renewer
Trip Noose
Troll Ascetic
True Conviction
Trumpet Blast
Trusty Machete
Trygon Predator
Tuktuk the Explorer
Tundra Wolves
Turn the Tide
Turn to Mist
Twinblade Slasher
Twincast
Undermine
Unmake
Unsummon
Urborg Drake
Ursapine
Utvara Scalper
Valeron Outlander
Valiant Guard
Vampire Hexmage
Vampire Nighthawk
Vastwood Gorger
Vault Skyward
Vedalken Mastermind
Vedalken Outlander
Venser, Shaper Savant
Veteran Armorer
Veteran Cavalier
Veteran's Reflexes
Viashino Spearhunter
Victory's Herald
Vigor
Vindicate
Vine Trellis
Vines of Vastwood
Viridian Claw
Visara the Dreadful
Vivid Crag
Vivid Creek
Vivid Grove
Vivid Marsh
Vivid Meadow
Vizzerdrix
Vodalian Zombie
Volcanic Fallout
Volcanic Strength
Vorosh, the Hunter
Vulshok Battlegear
Vulshok Berserker
Vulshok Morningstar
Wall of Air
Wall of Bone
Wall of Denial
Wall of Frost
Wall of Reverence
Wall of Spears
Wall of Stone
Wall of Swords
Wall of Vines
Wall of Wood
Wandering Ones
Warpath Ghoul
Wasp Lancer
Watchwolf
Watery Grave
Waveskimmer Aven
Weakness
Welkin Tern
Whispersilk Cloak
White Knight
Wild Griffin
Wildsize
Wildslayer Elves
Wilt-Leaf Cavaliers
Wind Drake
Windbrisk Raptor
Winged Coatl
Withstand
Withstand Death
Wolfbriar Elemental
Woodland Changeling
Woodland Druid
Woolly Thoctar
Wort, Boggart Auntie
Wrap in Vigor
Wrecking Ball
Wrexial, the Risen Deep
Wurmcoil Engine
Yavimaya Barbarian
Yavimaya Wurm
Yotian Soldier
Youthful Knight
Zealous Guardian
Zealous Persecution
Zendikar Farguide
Zephyr Sprite
Zodiac Monkey
Zombie Goliath
Zombie Outlander
Zombify

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 609 B

View File

@ -1,91 +0,0 @@
>images
>mods
>hqcards
Forest2.jpg;http://magiccards.info/scans/en/uh/140.jpg
Island2.jpg;http://magiccards.info/scans/en/uh/137.jpg
Mountain2.jpg;http://magiccards.info/scans/en/uh/139.jpg
Plains2.jpg;http://magiccards.info/scans/en/uh/136.jpg
Swamp2.jpg;http://magiccards.info/scans/en/uh/138.jpg
>avatars
face01.png;http://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Gnome-face-smile.svg/120px-Gnome-face-smile.svg.png
face02.png;http://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Gnome-face-smirk.svg/120px-Gnome-face-smirk.svg.png
face03.png;http://upload.wikimedia.org/wikipedia/commons/thumb/4/47/Gnome-face-wink.svg/120px-Gnome-face-wink.svg.png
face04.png;http://upload.wikimedia.org/wikipedia/commons/thumb/9/9e/Gnome-face-surprise.svg/120px-Gnome-face-surprise.svg.png
face05.png;http://upload.wikimedia.org/wikipedia/commons/thumb/e/ee/Gnome-face-plain.svg/120px-Gnome-face-plain.svg.png
face06.png;http://upload.wikimedia.org/wikipedia/commons/thumb/2/21/Gnome-face-raspberry.svg/120px-Gnome-face-raspberry.svg.png
face07.png;http://upload.wikimedia.org/wikipedia/commons/thumb/a/a0/Gnome-face-laugh.svg/120px-Gnome-face-laugh.svg.png
face08.png;http://upload.wikimedia.org/wikipedia/commons/thumb/9/92/Gnome-face-smile-big.svg/120px-Gnome-face-smile-big.svg.png
face09.png;http://upload.wikimedia.org/wikipedia/commons/thumb/7/7a/Gnome-face-cool.svg/120px-Gnome-face-cool.svg.png
face10.png;http://upload.wikimedia.org/wikipedia/commons/thumb/f/fe/Gnome-face-uncertain.svg/120px-Gnome-face-uncertain.svg.png
face11.png;http://upload.wikimedia.org/wikipedia/commons/thumb/b/b7/Gnome-face-worried.svg/120px-Gnome-face-worried.svg.png
face12.png;http://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/Gnome-face-tired.svg/120px-Gnome-face-tired.svg.png
face13.png;http://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Gnome-face-embarrassed.svg/120px-Gnome-face-embarrassed.svg.png
face14.png;http://upload.wikimedia.org/wikipedia/commons/thumb/4/43/Gnome-face-kiss.svg/120px-Gnome-face-kiss.svg.png
face15.png;http://upload.wikimedia.org/wikipedia/commons/thumb/2/2d/Gnome-face-angel.svg/120px-Gnome-face-angel.svg.png
face16.png;http://upload.wikimedia.org/wikipedia/commons/thumb/b/b2/Gnome-face-devilish.svg/120px-Gnome-face-devilish.svg.png
face17.png;http://upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Gnome-face-angry.svg/120px-Gnome-face-angry.svg.png
face18.png;http://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/Gnome-face-monkey.svg/120px-Gnome-face-monkey.svg.png
face19.png;http://upload.wikimedia.org/wikipedia/commons/thumb/5/5a/Crystal_Clear_app_Startup_Wizard2.png/120px-Crystal_Clear_app_Startup_Wizard2.png
face20.png;http://upload.wikimedia.org/wikipedia/commons/thumb/8/80/Crystal_Project_wizard.png/120px-Crystal_Project_wizard.png
>symbols
big_black.gif;http://gatherer.wizards.com/Handlers/Image.ashx?size=medium&name=B&type=symbol
big_blue.gif;http://gatherer.wizards.com/Handlers/Image.ashx?size=medium&name=U&type=symbol
big_green.gif;http://gatherer.wizards.com/Handlers/Image.ashx?size=medium&name=G&type=symbol
big_red.gif;http://gatherer.wizards.com/Handlers/Image.ashx?size=medium&name=R&type=symbol
big_white.gif;http://gatherer.wizards.com/Handlers/Image.ashx?size=medium&name=W&type=symbol
big_one.gif;http://gatherer.wizards.com/Handlers/Image.ashx?size=medium&name=1&type=symbol
black.gif;http://forums.mtgsalvation.com/images/smilies/manab.gif
blue.gif;http://forums.mtgsalvation.com/images/smilies/manau.gif
green.gif;http://forums.mtgsalvation.com/images/smilies/manag.gif
red.gif;http://forums.mtgsalvation.com/images/smilies/manar.gif
white.gif;http://forums.mtgsalvation.com/images/smilies/manaw.gif
black_green.gif;http://forums.mtgsalvation.com/images/smilies/manabg.gif
black_red.gif;http://forums.mtgsalvation.com/images/smilies/manabr.gif
blue_black.gif;http://forums.mtgsalvation.com/images/smilies/manaub.gif
blue_red.gif;http://forums.mtgsalvation.com/images/smilies/manaur.gif
green_blue.gif;http://forums.mtgsalvation.com/images/smilies/managu.gif
green_white.gif;http://forums.mtgsalvation.com/images/smilies/managw.gif
red_green.gif;http://forums.mtgsalvation.com/images/smilies/manarg.gif
red_white.gif;http://forums.mtgsalvation.com/images/smilies/manarw.gif
white_black.gif;http://forums.mtgsalvation.com/images/smilies/manawb.gif
white_blue.gif;http://forums.mtgsalvation.com/images/smilies/manawu.gif
zero.gif;http://forums.mtgsalvation.com/images/smilies/mana0.gif
one.gif;http://forums.mtgsalvation.com/images/smilies/mana1.gif
two.gif;http://forums.mtgsalvation.com/images/smilies/mana2.gif
three.gif;http://forums.mtgsalvation.com/images/smilies/mana3.gif
four.gif;http://forums.mtgsalvation.com/images/smilies/mana4.gif
five.gif;http://forums.mtgsalvation.com/images/smilies/mana5.gif
six.gif;http://forums.mtgsalvation.com/images/smilies/mana6.gif
seven.gif;http://forums.mtgsalvation.com/images/smilies/mana7.gif
eight.gif;http://forums.mtgsalvation.com/images/smilies/mana8.gif
nine.gif;http://forums.mtgsalvation.com/images/smilies/mana9.gif
x.gif;http://forums.mtgsalvation.com/images/smilies/manax.gif
tapped.gif;http://forums.mtgsalvation.com/images/smilies/tap.gif
>tokens
Ape.jpg;http://forums.mtgsalvation.com/attachment.php?attachmentid=42431&stc=1&d=1173951187
Bat.jpg;http://forums.mtgsalvation.com/attachment.php?attachmentid=19964&d=1143669815
Beast3.jpg;http://gatherer.wizards.com/Handlers/Image.ashx?type=card&multiverseid=201842
Beast4.jpg;http://gatherer.wizards.com/Handlers/Image.ashx?type=card&multiverseid=201844
Beast8.jpg;http://www.wizards.com/mtg/images/daily/arcana/1688_token5.jpg
Dragon4.jpg;http://www.wizards.com/mtg/images/daily/arcana/1688_token4.jpg
Dragon5.jpg;http://www.wizards.com/mtg/images/daily/arcana/371_tk2.jpg
Eldrazi Spawn.jpg;http://www.wizards.com/mtg/images/daily/arcana/421_spawn1.jpg
Elephant.jpg;http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=201843&type=card
Germ.jpg;http://media.wizards.com/images/magic/tcg/products/mbs/07he2j6tbi_en.jpg
Goblin Soldier.jpg;http://www.wizards.com/magic/images/mtgcom/arcana1000/1630_1.jpg
Goblin1.jpg;http://forums.mtgsalvation.com/attachment.php?attachmentid=20001&d=1143672913
Goblin2.jpg;http://forums.mtgsalvation.com/attachment.php?attachmentid=30596&d=1157620938
Griffin.jpg;http://forums.mtgsalvation.com/attachment.php?attachmentid=32242&stc=1&d=1159379525
Ogre.jpg;http://www.wizards.com/mtg/images/daily/arcana/371_tk3.jpg
Saproling.jpg;http://forums.mtgsalvation.com/attachment.php?attachmentid=20047&d=1143749873
Snake.jpg;http://www.wizards.com/mtg/images/daily/arcana/283_ZEN_Token9.jpg
Soldier.jpg;http://www.wizards.com/mtg/images/daily/arcana/1688_token1.jpg
Spirit.jpg;http://forums.mtgsalvation.com/attachment.php?attachmentid=20011&d=1143673311
Tuktuk the Returned.jpg;http://www.cardkingdom.com/media/images/products/standard/130721_1.jpg
Voja.jpg;http://forums.mtgsalvation.com/attachment.php?attachmentid=20055&d=1143749996
Wolf.jpg;http://www.wizards.com/mtg/images/daily/arcana/283_ZEN_Token10.jpg
Worm.jpg;http://www.wizards.com/magic/images/mtgcom/arcana1000/1630_2.jpg
Wurm1.jpg;http://www.cardkingdom.com/media/images/products/standard/132150_1.jpg
Wurm2.jpg;http://www.cardkingdom.com/media/images/products/standard/132151_1.jpg
Zombie.jpg;http://www.wizards.com/mtg/images/daily/arcana/1689_token2a.jpg
Zombie Giant.jpg;http://www.wizards.com/mtg/images/daily/arcana/283_ZEN_Token6.jpg

View File

@ -138,7 +138,7 @@ public class DeckStrCal {
int played = 0;
while (!testTournament.isFinished()) {
final MagicGame game=testTournament.nextGame();
final MagicGame game=testTournament.nextGame(false);
final GameController controller=new GameController(null,game);
controller.runGame();
if (testTournament.getGamesPlayed() > played) {

View File

@ -34,9 +34,13 @@ public class MagicMain {
public static void main(String args[]) {
initializeCards();
new MagicFrame();
}
initialize();
if (new File(gamePath,"ubeefx.txt").exists()) {
new MagicFrame();
} else {
System.out.println("Incompatible data folder!");
}
}
public static String getGamePath() {
@ -61,7 +65,7 @@ public class MagicMain {
MagicStaticLocalVariable.initializeCardDefinitions();
}
public static void initializeCards() {
public static void initialize() {
try {
new File(getGamePath()).mkdir();

View File

@ -1,18 +1,13 @@
package magic;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.HashSet;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import magic.data.CardDefinitions;
import magic.data.CubeDefinitions;
import magic.model.MagicCardDefinition;
public class MagicTools {
@ -35,70 +30,29 @@ public class MagicTools {
static void checkCards() throws IOException {
final CardDefinitions cardDefinitions = CardDefinitions.getInstance();
final String filenames[] = new File(MagicMain.getGamePath(),"hqcards").list();
final String filenames[] = new File(MagicMain.getGamePath(),"cards").list();
final Set<MagicCardDefinition> remaining = new HashSet<MagicCardDefinition>(CardDefinitions.getInstance().getCards());
for (final String filename : filenames) {
final String name = filename.substring(0,filename.length()-4);
if (cardDefinitions.getCard(name) == null) {
System.out.println(name);
final MagicCardDefinition cardDefinition = cardDefinitions.getCard(name);
if (cardDefinition == null) {
System.out.println(">"+name);
} else {
remaining.remove(cardDefinition);
}
}
}
static void moveCardImages() throws Exception {
final Map<String,String> cardUrls=new HashMap<String,String>();
final BufferedReader reader=new BufferedReader(new FileReader("resources/magic/data/images.txt"));
while (true) {
for (final MagicCardDefinition card : remaining) {
String line=reader.readLine();
if (line == null) {
break;
}
line=line.trim();
if (!line.isEmpty()&&!line.startsWith(">")) {
final int index=line.indexOf(";");
final String name=line.substring(0,index-4);
final String url=line.substring(index+1);
System.out.println(name+"="+url);
cardUrls.put(name,url);
if (!card.isToken()) {
System.out.println("<"+card.getName());
}
}
reader.close();
final BufferedReader reader2=new BufferedReader(new FileReader("resources/magic/data/cards.txt"));
final BufferedWriter writer2=new BufferedWriter(new FileWriter("/temp/cards.txt"));
while (true) {
String line=reader2.readLine();
if (line == null) {
break;
}
line=line.trim();
writer2.write(line);
writer2.newLine();
if (line.startsWith(">")) {
final String cardName=line.substring(1);
writer2.write("image="+cardUrls.get(cardName));
writer2.newLine();
final boolean defaultCube=CubeDefinitions.getInstance().getCubeDefinition("ubeefx").contains(cardName);
final boolean allCube=CubeDefinitions.getInstance().getCubeDefinition("singularita").contains(cardName);
if (defaultCube) {
writer2.write("cube=default");
writer2.newLine();
} else if (allCube) {
writer2.write("cube=all");
writer2.newLine();
}
}
}
reader2.close();
writer2.close();
}
public static void main(final String args[]) throws Exception {
MagicMain.initializeEngine();
listAllCards();
checkCards();
}
}

View File

@ -0,0 +1,99 @@
package magic.data;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Vector;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import magic.MagicMain;
import magic.ui.theme.PlayerAvatar;
public class AvatarImages {
private static final AvatarImages INSTANCE = new AvatarImages();
private final File avatarPath;
private final Vector<String> names;
private String current = null;
private PlayerAvatar avatars[];
private AvatarImages() {
avatarPath=new File(MagicMain.getGamePath(),"avatars");
final File[] files=avatarPath.listFiles();
names=new Vector<String>();
for (final File file : files) {
if (file.isDirectory()) {
names.add(file.getName());
}
}
}
public Vector<String> getNames() {
return names;
}
private PlayerAvatar loadAvatar(final File file) {
BufferedImage image;
try {
final InputStream stream=new FileInputStream(file);
image=ImageIO.read(stream);
stream.close();
} catch (final Exception ex) {
image=IconImages.MISSING;
}
return new PlayerAvatar(image);
}
private synchronized void loadAvatars() {
final String avatar=GeneralConfig.getInstance().getAvatar();
if (avatar!=current) {
current=avatar;
final File files[]=new File(avatarPath,current).listFiles();
if (files!=null&&files.length>=2) {
Arrays.sort(files);
avatars=new PlayerAvatar[files.length];
for (int index=0;index<files.length;index++) {
avatars[index]=loadAvatar(files[index]);
}
} else {
avatars=new PlayerAvatar[2];
avatars[0]=loadAvatar(new File(""));
avatars[1]=loadAvatar(new File(""));
}
}
}
public ImageIcon getAvatarIcon(int index,final int size) {
loadAvatars();
if (index<0) {
index=0;
} else if (index>=avatars.length) {
index%=avatars.length;
}
return avatars[index].getIcon(size);
}
public int getNumberOfAvatars() {
loadAvatars();
return avatars.length;
}
public static AvatarImages getInstance() {
return INSTANCE;
}
}

View File

@ -39,9 +39,7 @@ public class CardDefinitions {
private void setProperty(final MagicCardDefinition card,final String property,final String value) {
if ("image".equals(property)) {
card.setImageUrl(value);
} else if ("cube".equals(property)) {
if ("cube".equals(property)) {
if ("default".equals(value)) {
CubeDefinitions.getInstance().getCubeDefinition("all").add(card.getName());
}

View File

@ -1065,6 +1065,28 @@ public class CardEventDefinitions {
}
};
private static final MagicSpellCardEvent PSYCHIC_BARRIER=new MagicSpellCardEvent("Psychic Barrier") {
@Override
public MagicEvent getEvent(final MagicCardOnStack cardOnStack,final MagicPayedCost payedCost) {
final MagicPlayer player=cardOnStack.getController();
return new MagicEvent(cardOnStack.getCard(),player,MagicTargetChoice.NEG_TARGET_CREATURE_SPELL,
new Object[]{cardOnStack},this,"Counter target creature spell$. Its controller loses 1 life.");
}
@Override
public void executeEvent(final MagicGame game,final MagicEvent event,final Object[] data,final Object[] choiceResults) {
game.doAction(new MagicMoveCardAction((MagicCardOnStack)data[0]));
final MagicCardOnStack targetSpell=event.getTarget(game,choiceResults,0);
if (targetSpell!=null) {
game.doAction(new MagicCounterItemOnStackAction(targetSpell));
game.doAction(new MagicChangeLifeAction(targetSpell.getController(),-1));
}
}
};
private static final MagicSpellCardEvent PUNCTURE_BLAST=new MagicSpellCardEvent("Puncture Blast") {
@Override
@ -1981,6 +2003,40 @@ public class CardEventDefinitions {
}
};
private static final MagicSpellCardEvent BREATH_OF_DARIGAAZ=new MagicSpellCardEvent("Breath of Darigaaz") {
@Override
public MagicEvent getEvent(final MagicCardOnStack cardOnStack,final MagicPayedCost payedCost) {
final MagicPlayer player=cardOnStack.getController();
return new MagicEvent(cardOnStack.getCard(),player,
new MagicKickerChoice(null,MagicManaCost.TWO,false),
new Object[]{cardOnStack},this,
"Breath of Darigaaz deals 1 damage to each creature without flying and each player. "+
"If Breath of Darigaaz was kicked$$, it deals 4 damage to each creature without flying and each player instead.");
}
@Override
public void executeEvent(final MagicGame game,final MagicEvent event,final Object[] data,final Object[] choiceResults) {
final MagicCardOnStack cardOnStack=(MagicCardOnStack)data[0];
final MagicSource source=cardOnStack.getSource();
game.doAction(new MagicMoveCardAction(cardOnStack));
final int amount=(Integer)choiceResults[1]>0?4:1;
final Collection<MagicTarget> targets=game.filterTargets(cardOnStack.getController(),MagicTargetFilter.TARGET_CREATURE_WITHOUT_FLYING);
for (final MagicTarget target : targets) {
final MagicDamage damage=new MagicDamage(source,target,amount,false);
game.doAction(new MagicDealDamageAction(damage));
}
for (final MagicPlayer player : game.getPlayers()) {
final MagicDamage damage=new MagicDamage(source,player,amount,false);
game.doAction(new MagicDealDamageAction(damage));
}
}
};
private static final MagicSpellCardEvent CHAIN_REACTION=new MagicSpellCardEvent("Chain Reaction") {
@Override
@ -2386,6 +2442,30 @@ public class CardEventDefinitions {
game.doAction(new MagicDrawAction((MagicPlayer)data[1],(Integer)data[2]));
}
};
private static final MagicSpellCardEvent OVERRUN=new MagicSpellCardEvent("Overrun") {
@Override
public MagicEvent getEvent(final MagicCardOnStack cardOnStack,final MagicPayedCost payedCost) {
final MagicPlayer player=cardOnStack.getController();
return new MagicEvent(cardOnStack.getCard(),player,new Object[]{cardOnStack,player},this,
"Creatures you control get +3/+3 and gain trample until end of turn.");
}
@Override
public void executeEvent(final MagicGame game,final MagicEvent event,final Object[] data,final Object[] choiceResults) {
game.doAction(new MagicMoveCardAction((MagicCardOnStack)data[0]));
final Collection<MagicTarget> targets=game.filterTargets((MagicPlayer)data[1],MagicTargetFilter.TARGET_CREATURE_YOU_CONTROL);
for (final MagicTarget target : targets) {
final MagicPermanent creature=(MagicPermanent)target;
game.doAction(new MagicChangeTurnPTAction(creature,3,3));
game.doAction(new MagicSetAbilityAction(creature,MagicAbility.Trample));
}
}
};
private static final MagicSpellCardEvent OVERWHELMING_STAMPEDE=new MagicSpellCardEvent("Overwhelming Stampede") {
@ -3154,6 +3234,8 @@ public class CardEventDefinitions {
MagicTargetChoice.POS_TARGET_CREATURE,MagicPumpTargetPicker.getInstance());
private static final MagicSpellCardEvent TORPOR_DUST=new MagicPlayAuraEvent("Torpor Dust",
MagicTargetChoice.NEG_TARGET_CREATURE,new MagicWeakenTargetPicker(3,0));
private static final MagicSpellCardEvent UNQUESTIONED_AUTHORITY=new MagicPlayAuraEvent("Unquestioned Authority",
MagicTargetChoice.POS_TARGET_CREATURE,MagicUnblockableTargetPicker.getInstance());
private static final MagicSpellCardEvent VOLCANIC_STRENGTH=new MagicPlayAuraEvent("Volcanic Strength",
MagicTargetChoice.POS_TARGET_CREATURE,MagicPumpTargetPicker.getInstance());
private static final MagicSpellCardEvent WEAKNESS=new MagicPlayAuraEvent("Weakness",
@ -3203,6 +3285,7 @@ public class CardEventDefinitions {
NATURALIZE,
OFFERING_TO_ASHA,
PONGIFY,
PSYCHIC_BARRIER,
PLUMMET,
PUNCTURE_BLAST,
PUTREFY,
@ -3244,6 +3327,7 @@ public class CardEventDefinitions {
BLACK_SUNS_ZENITH,
BLAZE,
BLIGHTNING,
BREATH_OF_DARIGAAZ,
CHAIN_REACTION,
CRUEL_EDICT,
CORPSEHATCH,
@ -3261,6 +3345,7 @@ public class CardEventDefinitions {
MARSH_CASUALTIES,
MARTIAL_COUP,
MIND_SPRING,
OVERRUN,
OVERWHELMING_STAMPEDE,
PULSE_OF_THE_TANGLE,
REANIMATE,
@ -3314,6 +3399,7 @@ public class CardEventDefinitions {
SOUL_LINK,
SPIDER_UMBRA,
TORPOR_DUST,
UNQUESTIONED_AUTHORITY,
VOLCANIC_STRENGTH,
WEAKNESS
);

View File

@ -41,7 +41,7 @@ public class CubeDefinitions {
cubeDefinitions.add(new MagicCubeDefinition(cubeName));
}
}
public String[] getCubeNames() {
final String names[]=new String[cubeDefinitions.size()];

View File

@ -1,47 +0,0 @@
package magic.data;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Proxy;
import java.net.URL;
public class DownloadImageFile {
private final File file;
private final URL url;
public DownloadImageFile(final File file, final URL url) {
this.file=file;
this.url=url;
}
public String getFilename() {
return file.getName();
}
public void download(final Proxy proxy) {
try {
final OutputStream outputStream=new BufferedOutputStream(new FileOutputStream(file));
final InputStream inputStream=url.openConnection(proxy).getInputStream();
final byte buffer[]=new byte[65536];
while (true) {
final int len=inputStream.read(buffer);
if (len<0) {
break;
}
outputStream.write(buffer,0,len);
}
inputStream.close();
outputStream.close();
} catch (final Exception ex) {
file.delete();
}
}
}

View File

@ -1,72 +0,0 @@
package magic.data;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import magic.MagicMain;
import magic.model.MagicCardDefinition;
public class DownloadImageFiles extends ArrayList<DownloadImageFile> {
private static final long serialVersionUID = 1L;
public DownloadImageFiles(final String filename) {
try {
loadDownloadImageFiles(filename);
} catch (final Exception ex) {}
}
private void loadDownloadImageFiles(final String filename) throws IOException {
final InputStream stream;
if (filename.startsWith("file://")) {
stream=new FileInputStream(filename.substring(7));
} else {
stream=this.getClass().getResourceAsStream(filename);
}
final BufferedReader reader=new BufferedReader(new InputStreamReader(stream));
final File gamePathFile=new File(MagicMain.getGamePath());
File imagesPathFile=null;
while (true) {
final String line=reader.readLine();
if (line==null) {
break;
}
if (line.startsWith(">")) {
imagesPathFile=new File(gamePathFile,line.substring(1).trim());
imagesPathFile.mkdir();
} else {
final String parts[]=line.trim().split(";");
if (parts.length==2&&!parts[1].isEmpty()) {
final File imageFile=new File(imagesPathFile,parts[0]);
if (!imageFile.exists()) {
add(new DownloadImageFile(imageFile,new URL(parts[1])));
}
}
}
}
reader.close();
final File cardsPathFile=new File(gamePathFile,"hqcards");
for (final MagicCardDefinition cardDefinition : CardDefinitions.getInstance().getCards()) {
final String imageUrl=cardDefinition.getImageUrl();
if (imageUrl!=null) {
final File imageFile=new File(cardsPathFile,cardDefinition.getImageName()+".jpg");
if (!imageFile.exists()) {
add(new DownloadImageFile(imageFile,new URL(imageUrl)));
}
}
}
}
}

View File

@ -21,8 +21,8 @@ public class GeneralConfig {
private static final String HEIGHT="height";
private static final String MAXIMIZED="maximized";
private static final String THEME="theme";
private static final String AVATAR="avatar";
private static final String AI="ai";
private static final String UNDO_LEVELS="undo";
private static final String TEXT_VIEW="text";
private static final String SKIP_SINGLE="single";
private static final String ALWAYS_PASS="pass";
@ -33,6 +33,7 @@ public class GeneralConfig {
private static final String STRENGTH_DIFFICULTY="strengthDifficulty";
private static final String STRENGTH_GAMES="strengthGames";
private static final String HIGH_QUALITY="hq";
private static final String SOUND="sound";
private static final int DEFAULT_LEFT=-1;
private static final int DEFAULT_TOP=-1;
@ -40,8 +41,8 @@ public class GeneralConfig {
private static final int DEFAULT_HEIGHT=700;
private static final boolean DEFAULT_MAXIMIZED=false;
private static final String DEFAULT_THEME="wood";
private static final String DEFAULT_AVATAR="default";
private static final String DEFAULT_AI="default";
private static final int DEFAULT_UNDO_LEVELS=5;
private static final boolean DEFAULT_TEXT_VIEW=false;
private static final boolean DEFAULT_SINGLE=true;
private static final boolean DEFAULT_PASS=true;
@ -51,7 +52,8 @@ public class GeneralConfig {
private static final int DEFAULT_POPUP_DELAY=300;
private static final int DEFAULT_STRENGTH_DIFFICULTY=2;
private static final int DEFAULT_STRENGTH_GAMES=123;
private static final boolean DEFAULT_HIGH_QUALITY=false;
private static final boolean DEFAULT_HIGH_QUALITY=true;
private static final boolean DEFAULT_SOUND=false;
private int left=DEFAULT_LEFT;
private int top=DEFAULT_TOP;
@ -59,8 +61,8 @@ public class GeneralConfig {
private int height=DEFAULT_HEIGHT;
private boolean maximized=DEFAULT_MAXIMIZED;
private String theme=DEFAULT_THEME;
private String avatar=DEFAULT_AVATAR;
private String ai=DEFAULT_AI;
private int undoLevels=DEFAULT_UNDO_LEVELS;
private boolean textView=DEFAULT_TEXT_VIEW;
private boolean skipSingle=DEFAULT_SINGLE;
private boolean alwaysPass=DEFAULT_PASS;
@ -71,6 +73,7 @@ public class GeneralConfig {
private int strengthDifficulty=DEFAULT_STRENGTH_DIFFICULTY;
private int strengthGames=DEFAULT_STRENGTH_GAMES;
private boolean highQuality=DEFAULT_HIGH_QUALITY;
private boolean sound=DEFAULT_SOUND;
private GeneralConfig() {
@ -136,6 +139,16 @@ public class GeneralConfig {
this.theme=theme;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(final String avatar) {
this.avatar=avatar;
}
public String getAi() {
return ai;
@ -151,16 +164,6 @@ public class GeneralConfig {
final MagicAI playerAi = MagicAIImpl.getAI(ai).getAI();
return new MagicAI[]{playerAi, playerAi};
}
public int getUndoLevels() {
return undoLevels;
}
public void setUndoLevels(final int undoLevels) {
this.undoLevels=undoLevels;
}
public boolean getTextView() {
@ -262,6 +265,16 @@ public class GeneralConfig {
this.highQuality=highQuality;
}
public boolean isSound() {
return sound;
}
public void setSound(final boolean sound) {
this.sound=sound;
}
public void load(final Properties properties) {
left=Integer.parseInt(properties.getProperty(LEFT,""+DEFAULT_LEFT));
@ -270,8 +283,8 @@ public class GeneralConfig {
height=Integer.parseInt(properties.getProperty(HEIGHT,""+DEFAULT_HEIGHT));
maximized=Boolean.parseBoolean(properties.getProperty(MAXIMIZED,""+DEFAULT_MAXIMIZED));
theme=properties.getProperty(THEME,DEFAULT_THEME);
avatar=properties.getProperty(AVATAR,DEFAULT_AVATAR);
ai=properties.getProperty(AI,DEFAULT_AI);
undoLevels=Integer.parseInt(properties.getProperty(UNDO_LEVELS,""+DEFAULT_UNDO_LEVELS));
textView=Boolean.parseBoolean(properties.getProperty(TEXT_VIEW,""+DEFAULT_TEXT_VIEW));
skipSingle=Boolean.parseBoolean(properties.getProperty(SKIP_SINGLE,""+DEFAULT_SINGLE));
alwaysPass=Boolean.parseBoolean(properties.getProperty(ALWAYS_PASS,""+DEFAULT_PASS));
@ -282,6 +295,7 @@ public class GeneralConfig {
strengthDifficulty=Integer.parseInt(properties.getProperty(STRENGTH_DIFFICULTY,""+DEFAULT_STRENGTH_DIFFICULTY));
strengthGames=Integer.parseInt(properties.getProperty(STRENGTH_GAMES,""+DEFAULT_STRENGTH_GAMES));
highQuality=Boolean.parseBoolean(properties.getProperty(HIGH_QUALITY,""+DEFAULT_HIGH_QUALITY));
sound=Boolean.parseBoolean(properties.getProperty(SOUND,""+DEFAULT_SOUND));
}
public void load() {
@ -301,8 +315,8 @@ public class GeneralConfig {
properties.setProperty(HEIGHT,String.valueOf(height));
properties.setProperty(MAXIMIZED,String.valueOf(maximized));
properties.setProperty(THEME,theme);
properties.setProperty(AVATAR,avatar);
properties.setProperty(AI,ai);
properties.setProperty(UNDO_LEVELS,String.valueOf(undoLevels));
properties.setProperty(TEXT_VIEW,String.valueOf(textView));
properties.setProperty(SKIP_SINGLE,String.valueOf(skipSingle));
properties.setProperty(ALWAYS_PASS,String.valueOf(alwaysPass));
@ -313,6 +327,7 @@ public class GeneralConfig {
properties.setProperty(STRENGTH_DIFFICULTY,String.valueOf(strengthDifficulty));
properties.setProperty(STRENGTH_GAMES,String.valueOf(strengthGames));
properties.setProperty(HIGH_QUALITY,String.valueOf(highQuality));
properties.setProperty(SOUND,String.valueOf(sound));
}
public void save() {

View File

@ -36,7 +36,7 @@ public class HighQualityCardImagesProvider implements CardImagesProvider {
final int imageIndex=index%cardDefinition.getImageCount();
final StringBuffer buffer=new StringBuffer();
buffer.append(MagicMain.getGamePath()).append(File.separator);
buffer.append(cardDefinition.isToken()?"tokens":"hqcards").append(File.separator);
buffer.append(cardDefinition.isToken()?"tokens":"cards").append(File.separator);
buffer.append(cardDefinition.getImageName()).append(imageIndex>0?String.valueOf(imageIndex+1):"");
buffer.append(IMAGE_EXTENSION);
return buffer.toString();

View File

@ -95,6 +95,7 @@ public class IconImages {
public static final ImageIcon EDIT=loadIcon("edit.png");
public static final ImageIcon DELAY=loadIcon("delay.png");
public static final ImageIcon PICTURE=loadIcon("picture.png");
public static final ImageIcon AVATAR=loadIcon("avatar.gif");
public static final ImageIcon FLYING=loadIcon("flying.png");
public static final ImageIcon TRAMPLE=loadIcon("trample.png");

View File

@ -62,10 +62,12 @@ public class ManaActivationDefinitions {
addCreatureActivations("Stirring Wildwood",new MagicManaType[]{MagicManaType.Green,MagicManaType.White});
// Creatures.
addCreatureActivations("Alloy Myr",MagicManaType.ALL_TYPES);
addCreatureActivations("Birds of Paradise",MagicManaType.ALL_TYPES);
addCreatureActivations("Llanowar Elves",new MagicManaType[]{MagicManaType.Colorless,MagicManaType.Green});
addCreatureActivations("Noble Hierarch",new MagicManaType[]{MagicManaType.Colorless,MagicManaType.Blue,MagicManaType.Green,MagicManaType.White});
addCreatureActivations("Steward of Valeron",new MagicManaType[]{MagicManaType.Colorless,MagicManaType.Green});
addCreatureActivations("Vine Trellis",new MagicManaType[]{MagicManaType.Colorless,MagicManaType.Green});
addCreatureActivations("Plague Myr",new MagicManaType[]{MagicManaType.Colorless});
}
}

View File

@ -398,6 +398,8 @@ public class PermanentActivationDefinitions {
private static final MagicPermanentActivation CHARGING_TROLL=new MagicRegenerationActivation("Charging Troll",MagicManaCost.GREEN);
private static final MagicPermanentActivation CUDGEL_TROLL=new MagicRegenerationActivation("Cudgel Troll",MagicManaCost.GREEN);
private static final MagicPermanentActivation CUNNING_SPARKMAGE=new MagicPermanentActivation(
"Cunning Sparkmage",new MagicCondition[]{MagicCondition.CAN_TAP_CONDITION},new MagicActivationHints(MagicTiming.Removal)) {
@ -1569,6 +1571,8 @@ public class PermanentActivationDefinitions {
}
};
private static final MagicPermanentActivation SHIVAN_DRAGON=new MagicPumpActivation("Shivan Dragon",MagicManaCost.RED,1,0);
private static final MagicPermanentActivation SKELETAL_VAMPIRE2=new MagicPermanentActivation("Skeletal Vampire",
new MagicCondition[]{MagicCondition.CAN_REGENERATE_CONDITION,MagicCondition.CONTROL_BAT_CONDITION,new MagicSingleActivationCondition()},
new MagicActivationHints(MagicTiming.Pump)) {
@ -2187,6 +2191,28 @@ public class PermanentActivationDefinitions {
}
};
private static final MagicPermanentActivation BATTERSKULL=new MagicPermanentActivation("Batterskull",
new MagicCondition[]{MagicManaCost.THREE.getCondition()},new MagicActivationHints(MagicTiming.Removal)) {
@Override
public MagicEvent[] getCostEvent(final MagicSource source) {
return new MagicEvent[]{new MagicPayManaCostEvent(source,source.getController(),MagicManaCost.THREE)};
}
@Override
public MagicEvent getPermanentEvent(final MagicPermanent source,final MagicPayedCost payedCost) {
return new MagicEvent(source,source.getController(),new Object[]{source},this,"Return Batterskull to its owner's hand.");
}
@Override
public void executeEvent(final MagicGame game,final MagicEvent event,final Object[] data,final Object[] choiceResults) {
game.doAction(new MagicRemoveFromPlayAction((MagicPermanent)data[0],MagicLocationType.OwnersHand));
}
};
private static final MagicPermanentActivation BRITTLE_EFFIGY=new MagicPermanentActivation("Brittle Effigy",
new MagicCondition[]{MagicCondition.CAN_TAP_CONDITION,MagicManaCost.FOUR.getCondition()},new MagicActivationHints(MagicTiming.Removal)) {
@ -2351,6 +2377,42 @@ public class PermanentActivationDefinitions {
}
};
private static final MagicPermanentActivation SHRINE_OF_BURNING_RAGE=new MagicPermanentActivation("Shrine of Burning Rage",
new MagicCondition[]{MagicCondition.CAN_TAP_CONDITION,MagicManaCost.THREE.getCondition()},new MagicActivationHints(MagicTiming.Removal)) {
@Override
public MagicEvent[] getCostEvent(final MagicSource source) {
final MagicPermanent permanent=(MagicPermanent)source;
return new MagicEvent[]{
new MagicTapEvent(permanent),
new MagicPayManaCostEvent(source,source.getController(),MagicManaCost.THREE),
new MagicSacrificeEvent(permanent)};
}
@Override
public MagicEvent getPermanentEvent(final MagicPermanent source,final MagicPayedCost payedCost) {
return new MagicEvent(source,source.getController(),MagicTargetChoice.NEG_TARGET_CREATURE_OR_PLAYER,
new MagicDamageTargetPicker(source.getCounters(MagicCounterType.Charge)),new Object[]{source},this,
"Shrine of Burning Rage deals damage equal to the number of charge counters on it to target creature or player$.");
}
@Override
public void executeEvent(final MagicGame game,final MagicEvent event,final Object[] data,final Object[] choiceResults) {
final MagicTarget target=event.getTarget(game,choiceResults,0);
if (target!=null) {
final MagicPermanent source=(MagicPermanent)data[0];
final int amount=source.getCounters(MagicCounterType.Charge);
if (amount>0) {
final MagicDamage damage=new MagicDamage(source,target,amount,false);
game.doAction(new MagicDealDamageAction(damage));
}
}
}
};
private static final MagicPermanentActivation TRIP_NOOSE=new MagicPermanentActivation("Trip Noose",
new MagicCondition[]{MagicCondition.CAN_TAP_CONDITION,MagicManaCost.TWO.getCondition()},new MagicActivationHints(MagicTiming.Tapping)) {
@ -2623,6 +2685,7 @@ public class PermanentActivationDefinitions {
CINDER_ELEMENTAL,
CHAMELEON_COLOSSUS,
CHARGING_TROLL,
CUDGEL_TROLL,
CUNNING_SPARKMAGE,
CURSECATCHER,
DAUNTLESS_ESCORT,
@ -2675,6 +2738,7 @@ public class PermanentActivationDefinitions {
SIEGE_GANG_COMMANDER,
SILKBIND_FAERIE,
SILVOS_ROGUE_ELEMENTAL,
SHIVAN_DRAGON,
SKELETAL_VAMPIRE1,
SKELETAL_VAMPIRE2,
SKITHIRYX1,
@ -2706,11 +2770,13 @@ public class PermanentActivationDefinitions {
RISE_OF_THE_HOBGOBLINS,
SEAL_OF_DOOM,
SEAL_OF_FIRE,
BATTERSKULL,
BRITTLE_EFFIGY,
CHIMERIC_MASS,
MIND_STONE,
MOONGLOVE_EXTRACT,
SERRATED_ARROWS,
SHRINE_OF_BURNING_RAGE,
TRIP_NOOSE,
CELESTIAL_COLONNADE,
CREEPING_TAR_PIT,

View File

@ -0,0 +1,51 @@
package magic.data;
import java.io.File;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import magic.MagicMain;
import magic.model.MagicGame;
public class SoundEffects {
public static final String WIN_SOUND="win.au";
public static final String LOSE_SOUND="lose.au";
public static final String TURN_SOUND="turn.au";
public static final String RESOLVE_SOUND="resolve.au";
public static final String COMBAT_SOUND="combat.au";
private static final File SOUNDS_PATH=new File(MagicMain.getGamePath(),"sounds");
private static final SoundEffects INSTANCE=new SoundEffects();
private SoundEffects() {
}
public void playClip(final String name) {
if (GeneralConfig.getInstance().isSound()) {
try {
final Clip clip=AudioSystem.getClip();
final AudioInputStream inputStream=AudioSystem.getAudioInputStream(new File(SOUNDS_PATH,name));
clip.open(inputStream);
inputStream.close();
clip.start();
} catch (Exception e) {}
}
}
public void playClip(final MagicGame game,final String name) {
if (game.isSound()) {
playClip(name);
}
}
public static SoundEffects getInstance() {
return INSTANCE;
}
}

View File

@ -210,6 +210,23 @@ public class TokenCardDefinitions {
}
};
public static final MagicCardDefinition FAERIE_ROGUE_TOKEN_CARD=new MagicCardDefinition("Faerie Rogue") {
public void initialize() {
setToken();
setValue(2);
addType(MagicType.Creature);
setSubTypes(new String[]{"Faerie","Rogue"});
setCost(MagicManaCost.ZERO);
setColor(MagicColor.Black);
setColoredType();
setPower(1);
setToughness(1);
setAbility(MagicAbility.Flying);
}
};
public static final MagicCardDefinition GRIFFIN_TOKEN_CARD=new MagicCardDefinition("Griffin") {
public void initialize() {
@ -472,6 +489,7 @@ public class TokenCardDefinitions {
OGRE_TOKEN_CARD,
SPIRIT_TOKEN_CARD,
BAT_TOKEN_CARD,
FAERIE_ROGUE_TOKEN_CARD,
GRIFFIN_TOKEN_CARD,
APE_TOKEN_CARD,
BEAST3_TOKEN_CARD,

View File

@ -58,6 +58,7 @@ import magic.model.event.MagicEvent;
import magic.model.event.MagicEventAction;
import magic.model.event.MagicPlayOgreUnlessEvent;
import magic.model.event.MagicSacrificePermanentEvent;
import magic.model.event.MagicTapEvent;
import magic.model.stack.MagicCardOnStack;
import magic.model.target.MagicBecomeTargetPicker;
import magic.model.target.MagicBounceTargetPicker;
@ -899,6 +900,39 @@ public class TriggerDefinitions {
}
};
private static final MagicTrigger GOBLIN_PILEDRIVER=new MagicTrigger(MagicTriggerType.WhenAttacks,"Goblin Piledriver") {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final Object data) {
if (permanent==data) {
return new MagicEvent(permanent,permanent.getController(),new Object[]{permanent},this,
"Goblin Piledriver gets +2/+0 until end of turn for each other attacking Goblin.");
}
return null;
}
@Override
public void executeEvent(final MagicGame game,final MagicEvent event,final Object data[],final Object[] choiceResults) {
int power=0;
final MagicPermanent creature=(MagicPermanent)data[0];
final Collection<MagicTarget> targets=game.filterTargets(creature.getController(),MagicTargetFilter.TARGET_ATTACKING_CREATURE);
for (final MagicTarget target : targets) {
if (creature!=target) {
final MagicPermanent attacker=(MagicPermanent)target;
if (attacker.hasSubType(MagicSubType.Goblin)) {
power+=2;
}
}
}
if (power>0) {
game.doAction(new MagicChangeTurnPTAction(creature,power,0));
}
}
};
private static final MagicTrigger GUARD_GOMAZOA=new MagicTrigger(MagicTriggerType.IfDamageWouldBeDealt,"Guard Gomazoa",1) {
@Override
@ -1664,7 +1698,7 @@ public class TriggerDefinitions {
}
}
};
private static final MagicTrigger NEMESIS_OF_REASON=new MagicTrigger(MagicTriggerType.WhenAttacks,"Nemesis of Reason") {
@Override
@ -1854,6 +1888,24 @@ public class TriggerDefinitions {
}
};
private static final MagicTrigger PHYREXIAN_RAGER=new MagicTrigger(MagicTriggerType.WhenComesIntoPlay,"Phyrexian Rager") {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final Object data) {
final MagicPlayer player=permanent.getController();
return new MagicEvent(permanent,player,new Object[]{player},this,"You draw a card and you lose 1 life.");
}
@Override
public void executeEvent(final MagicGame game,final MagicEvent event,final Object data[],final Object[] choiceResults) {
final MagicPlayer player=(MagicPlayer)data[0];
game.doAction(new MagicDrawAction(player,1));
game.doAction(new MagicChangeLifeAction(player,-1));
}
};
private static final MagicTrigger PHYREXIAN_VATMOTHER=new MagicTrigger(MagicTriggerType.AtUpkeep,"Phyrexian Vatmother") {
@Override
@ -2270,6 +2322,51 @@ public class TriggerDefinitions {
}
};
private static final MagicTrigger SHEOLDRED_WHISPERING_ONE1=new MagicTrigger(MagicTriggerType.AtUpkeep,"Sheoldred, Whispering One") {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final Object data) {
final MagicPlayer player=permanent.getController();
if (player==data) {
return new MagicEvent(permanent,player,MagicTargetChoice.TARGET_CREATURE_CARD_FROM_GRAVEYARD,MagicGraveyardTargetPicker.getInstance(),
new Object[]{player},this,"Return target creature card$ from your graveyard to the battlefield.");
}
return null;
}
@Override
public void executeEvent(final MagicGame game,final MagicEvent event,final Object data[],final Object[] choiceResults) {
final MagicCard card=event.getTarget(game,choiceResults,0);
if (card!=null) {
game.doAction(new MagicReanimateAction((MagicPlayer)data[0],card,MagicPlayCardAction.NONE));
}
}
};
private static final MagicTrigger SHEOLDRED_WHISPERING_ONE2=new MagicTrigger(MagicTriggerType.AtUpkeep,"Sheoldred, Whispering One") {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final Object data) {
final MagicPlayer player=permanent.getController();
if (player!=data) {
return new MagicEvent(permanent,permanent.getController(),new Object[]{permanent,data},this,"Your opponent sacrifices a creature.");
}
return null;
}
@Override
public void executeEvent(final MagicGame game,final MagicEvent event,final Object data[],final Object[] choiceResults) {
final MagicPlayer opponent=(MagicPlayer)data[1];
if (opponent.controlsPermanentWithType(MagicType.Creature)) {
game.addEvent(new MagicSacrificePermanentEvent((MagicPermanent)data[0],opponent,MagicTargetChoice.SACRIFICE_CREATURE));
}
}
};
private static final MagicTrigger SHIVAN_WURM=new MagicTrigger(MagicTriggerType.WhenComesIntoPlay,"Shivan Wurm") {
@Override
@ -2549,7 +2646,31 @@ public class TriggerDefinitions {
game.doAction(new MagicPlayTokenAction((MagicPlayer)data[0],TokenCardDefinitions.TUKTUK_THE_RETURNED_TOKEN_CARD));
}
};
private static final MagicTrigger URABRASK_THE_HIDDEN=new MagicTrigger(MagicTriggerType.WhenOtherComesIntoPlay,"Urabrask the Hidden") {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final Object data) {
final MagicPermanent otherPermanent=(MagicPermanent)data;
if (otherPermanent.isCreature()&&otherPermanent.getController()!=permanent.getController()) {
return new MagicTapEvent(otherPermanent);
}
return null;
}
@Override
public void executeEvent(final MagicGame game,final MagicEvent event,final Object data[],final Object[] choiceResults) {
}
@Override
public boolean usesStack() {
return false;
}
};
private static final MagicTrigger VENSER_SHAPER_SAVANT=new MagicTrigger(MagicTriggerType.WhenComesIntoPlay,"Venser, Shaper Savant") {
@Override
@ -2775,6 +2896,8 @@ public class TriggerDefinitions {
}
};
private static final MagicTrigger BATTERSKULL=new MagicLivingWeaponTrigger("Batterskull");
private static final MagicTrigger FLAYER_HUSK=new MagicLivingWeaponTrigger("Flayer Husk");
private static final MagicTrigger MAGE_SLAYER=new MagicTrigger(MagicTriggerType.WhenAttacks,"Mage Slayer",1) {
@ -2884,6 +3007,8 @@ public class TriggerDefinitions {
}
};
private static final MagicTrigger SICKLESLICER=new MagicLivingWeaponTrigger("Sickleslicer");
private static final MagicTrigger SHIELD_OF_THE_RIGHTEOUS=new MagicTrigger(MagicTriggerType.WhenBlocks,"Shield of the Righteous") {
@Override
@ -3055,6 +3180,39 @@ public class TriggerDefinitions {
}
};
private static final MagicTrigger SWORD_OF_WAR_AND_PEACE=new MagicTrigger(MagicTriggerType.WhenDamageIsDealt,"Sword of War and Peace") {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final Object data) {
final MagicDamage damage=(MagicDamage)data;
if (damage.getSource()==permanent.getEquippedCreature()&&damage.getTarget().isPlayer()&&damage.isCombat()) {
final MagicPlayer player=permanent.getController();
final MagicTarget targetPlayer=damage.getTarget();
return new MagicEvent(permanent,player,new Object[]{permanent,player,targetPlayer},this,
"Sword of War and Peace deals damage to "+targetPlayer.getName()+" equal to the number of cards in his or her hand and "+
"you gain 1 life for each card in your hand.");
}
return null;
}
@Override
public void executeEvent(final MagicGame game,final MagicEvent event,final Object data[],final Object[] choiceResults) {
final MagicPlayer targetPlayer=(MagicPlayer)data[2];
final int amount1=targetPlayer.getHand().size();
if (amount1>0) {
final MagicDamage damage=new MagicDamage((MagicSource)data[0],targetPlayer,amount1,false);
game.doAction(new MagicDealDamageAction(damage));
}
final MagicPlayer player=(MagicPlayer)data[1];
final int amount2=player.getHand().size();
if (amount2>0) {
game.doAction(new MagicChangeLifeAction(player,amount2));
}
}
};
private static final MagicTrigger SYLVOK_LIFESTAFF=new MagicTrigger(MagicTriggerType.WhenOtherPutIntoGraveyardFromPlay,"Sylvok Lifestaff") {
@Override
@ -3198,6 +3356,28 @@ public class TriggerDefinitions {
}
};
private static final MagicTrigger BITTERBLOSSOM=new MagicTrigger(MagicTriggerType.AtUpkeep,"Bitterblossom") {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final Object data) {
final MagicPlayer player=permanent.getController();
if (player==data) {
return new MagicEvent(permanent,player,new Object[]{player},this,
"You lose 1 life and put a 1/1 black Faerie Rogue creature token with flying onto the battlefield.");
}
return null;
}
@Override
public void executeEvent(final MagicGame game,final MagicEvent event,final Object data[],final Object[] choiceResults) {
final MagicPlayer player=(MagicPlayer)(MagicPlayer)data[0];
game.doAction(new MagicChangeLifeAction(player,-1));
game.doAction(new MagicPlayTokenAction(player,TokenCardDefinitions.FAERIE_ROGUE_TOKEN_CARD));
}
};
private static final MagicTrigger DEBTORS_KNELL=new MagicTrigger(MagicTriggerType.AtUpkeep,"Debtors' Knell") {
@Override
@ -3540,6 +3720,45 @@ public class TriggerDefinitions {
}
};
private static final MagicTrigger SHRINE_OF_BURNING_RAGE1=new MagicTrigger(MagicTriggerType.AtUpkeep,"Shrine of Burning Rage") {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final Object data) {
final MagicPlayer player=permanent.getController();
if (player==data) {
return new MagicEvent(permanent,player,new Object[]{permanent},this,"Put a charge counter on Shrine of Burning Rage.");
}
return null;
}
@Override
public void executeEvent(final MagicGame game,final MagicEvent event,final Object data[],final Object[] choiceResults) {
game.doAction(new MagicChangeCountersAction((MagicPermanent)data[0],MagicCounterType.Charge,1,true));
}
};
private static final MagicTrigger SHRINE_OF_BURNING_RAGE2=new MagicTrigger(MagicTriggerType.WhenSpellIsPlayed,"Shrine of Burning Rage") {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final Object data) {
final MagicPlayer player=permanent.getController();
final MagicCard card=((MagicCardOnStack)data).getCard();
if (card.getOwner()==player&&MagicColor.Red.hasColor(card.getColorFlags())) {
return new MagicEvent(permanent,player,new Object[]{permanent},this,"Put a charge counter on Shrine of Burning Rage.");
}
return null;
}
@Override
public void executeEvent(final MagicGame game,final MagicEvent event,final Object data[],final Object[] choiceResults) {
game.doAction(new MagicChangeCountersAction((MagicPermanent)data[0],MagicCounterType.Charge,1,true));
}
};
private static final MagicTrigger SKULLCAGE=new MagicTrigger(MagicTriggerType.AtUpkeep,"Skullcage") {
@Override
@ -3855,6 +4074,22 @@ public class TriggerDefinitions {
}
};
private static final MagicTrigger UNQUESTIONED_AUTHORITY=new MagicTrigger(MagicTriggerType.WhenComesIntoPlay,"Unquestioned Authority") {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final Object data) {
final MagicPlayer player=permanent.getController();
return new MagicEvent(permanent,player,new Object[]{player},this,"You draw a card.");
}
@Override
public void executeEvent(final MagicGame game,final MagicEvent event,final Object data[],final Object[] choiceResults) {
game.doAction(new MagicDrawAction((MagicPlayer)data[0],1));
}
};
private static final Collection<MagicTrigger> TRIGGERS=Arrays.<MagicTrigger>asList(
ACIDIC_SLIME,
AFFA_GUARD_HOUND,
@ -3895,6 +4130,7 @@ public class TriggerDefinitions {
GHOST_COUNCIL_OF_ORZHOVA,
GRAVE_TITAN1,
GRAVE_TITAN2,
GOBLIN_PILEDRIVER,
GOBLIN_SHORTCUTTER,
GUARD_GOMAZOA,
GUARDIAN_SERAPH,
@ -3941,6 +4177,7 @@ public class TriggerDefinitions {
PERILOUS_MYR,
PERIMETER_CAPTAIN,
OROS_THE_AVENGER,
PHYREXIAN_RAGER,
PHYREXIAN_VATMOTHER,
PIERCE_STRIDER,
PREDATOR_DRAGON,
@ -3956,6 +4193,8 @@ public class TriggerDefinitions {
SKELETAL_VAMPIRE,
SHADOWMAGE_INFILTRATOR,
SKINRENDER,
SHEOLDRED_WHISPERING_ONE1,
SHEOLDRED_WHISPERING_ONE2,
SHIVAN_WURM,
SOULS_OF_THE_FAULTLESS,
SPHINX_OF_LOST_TRUTHS,
@ -3976,6 +4215,7 @@ public class TriggerDefinitions {
TREVA_THE_RENEWER,
TRYGON_PREDATOR,
TUKTUK_THE_EXPLORER,
URABRASK_THE_HIDDEN,
VENSER_SHAPER_SAVANT,
VICTORYS_HERALD,
VIGOR1,
@ -3986,12 +4226,14 @@ public class TriggerDefinitions {
WORT_BOGGART_AUNTIE,
WREXIAL_THE_RISEN_DEEP,
WURMCOIL_ENGINE,
BATTERSKULL,
FLAYER_HUSK,
MAGE_SLAYER,
MASK_OF_MEMORY,
MASK_OF_RIDDLES,
QUIETUS_SPIKE,
RONIN_WARCLUB,
SICKLESLICER,
SHIELD_OF_THE_RIGHTEOUS,
SKULLCLAMP,
SPECTERS_SHROUD,
@ -4000,6 +4242,7 @@ public class TriggerDefinitions {
SWORD_OF_FEAST_AND_FAMINE,
SWORD_OF_FIRE_AND_ICE,
SWORD_OF_LIGHT_AND_SHADOW,
SWORD_OF_WAR_AND_PEACE,
SYLVOK_LIFESTAFF,
BLOOD_CRYPT,
BREEDING_POOL,
@ -4048,6 +4291,7 @@ public class TriggerDefinitions {
SEACHROME_COAST,
RAGING_RAVINE,
AWAKENING_ZONE,
BITTERBLOSSOM,
DISSIPATION_FIELD,
DEBTORS_KNELL,
FERVENT_CHARGE,
@ -4063,6 +4307,8 @@ public class TriggerDefinitions {
ELDRAZI_MONUMENT,
SERRATED_ARROWS1,
SERRATED_ARROWS2,
SHRINE_OF_BURNING_RAGE1,
SHRINE_OF_BURNING_RAGE2,
SKULLCAGE,
ARMADILLO_CLOAK,
ELEPHANT_GUIDE,
@ -4076,7 +4322,8 @@ public class TriggerDefinitions {
RANCOR,
SNAKE_UMBRA,
SOUL_LINK1,
SOUL_LINK2
SOUL_LINK2,
UNQUESTIONED_AUTHORITY
);
public static void addTriggers() {

View File

@ -57,7 +57,6 @@ public class MagicCardDefinition {
private final String name;
private final String fullName;
private String imageUrl=null;
private int index=-1;
private int value=0;
private int removal=0;
@ -134,17 +133,7 @@ public class MagicCardDefinition {
return isBasic()?2:1;
}
public void setImageUrl(final String imageUrl) {
this.imageUrl=imageUrl;
}
public String getImageUrl() {
return imageUrl;
}
public void setValue(final int value) {
this.value = value;

View File

@ -58,6 +58,7 @@ public class MagicGame {
private final MagicEventQueue events;
private final MagicStack stack;
private final MagicPlayer scorePlayer;
private final boolean sound;
private long identifiers[];
private int score=0;
private int turn=1;
@ -82,12 +83,13 @@ public class MagicGame {
private final MagicLogBook logBook;
private final MagicLogMessageBuilder logMessageBuilder;
public MagicGame(final MagicTournament tournament,final MagicGameplay gameplay,final MagicPlayer players[],final MagicPlayer startPlayer) {
public MagicGame(final MagicTournament tournament,final MagicGameplay gameplay,final MagicPlayer players[],final MagicPlayer startPlayer,final boolean sound) {
artificial=false;
this.tournament=tournament;
this.gameplay=gameplay;
this.players=players;
this.sound=sound;
identifiers=new long[MagicIdentifierType.NR_OF_IDENTIFIERS];
triggers=new MagicPermanentTriggerMap();
turnTriggers=new MagicPermanentTriggerList();
@ -108,6 +110,7 @@ public class MagicGame {
public MagicGame(final MagicGame game,final MagicPlayer scorePlayer) {
artificial=true;
sound=false;
final MagicCopyMap copyMap=new MagicCopyMap();
this.tournament=game.tournament;
this.gameplay=game.gameplay;
@ -198,6 +201,11 @@ public class MagicGame {
return artificial;
}
public boolean isSound() {
return sound;
}
public void setFastChoices(final boolean fastChoices) {
this.fastChoices=fastChoices;
@ -399,14 +407,6 @@ public class MagicGame {
}
public void createUndoPoint() {
if (undoPoints.size()==GeneralConfig.getInstance().getUndoLevels()) {
final MagicAction firstMarkerAction=undoPoints.removeFirst();
while (actions.getFirst()!=firstMarkerAction) {
actions.removeFirst();
}
}
final MagicAction markerAction=new MagicMarkerAction();
doAction(markerAction);

View File

@ -182,12 +182,12 @@ public class MagicTournament {
return players;
}
public MagicGame nextGame() {
public MagicGame nextGame(final boolean sound) {
final MagicPlayer player=new MagicPlayer(configuration,playerDefinitions[0],0);
final MagicPlayer opponent=new MagicPlayer(configuration,playerDefinitions[opponentIndex],1);
final MagicPlayer start=startPlayer==0?player:opponent;
return new MagicGame(this,MagicDefaultGameplay.getInstance(),new MagicPlayer[]{player,opponent},start);
return new MagicGame(this,MagicDefaultGameplay.getInstance(),new MagicPlayer[]{player,opponent},start,sound);
}
public int getNrOfPlayers() {

View File

@ -1,5 +1,6 @@
package magic.model.phase;
import magic.data.SoundEffects;
import magic.model.MagicGame;
import magic.model.MagicPlayer;
import magic.model.action.MagicCombatDamageAction;
@ -41,5 +42,6 @@ public class MagicCombatDamagePhase extends MagicPhase {
game.logMessage(defendingPlayer,"{c}"+message.toString());
}
game.setStep(MagicStep.NextPhase);
SoundEffects.getInstance().playClip(game,SoundEffects.COMBAT_SOUND);
}
}

View File

@ -1,5 +1,6 @@
package magic.model.phase;
import magic.data.SoundEffects;
import magic.model.MagicGame;
import magic.model.MagicPermanent;
import magic.model.MagicPlayer;
@ -46,4 +47,10 @@ public class MagicEndOfTurnPhase extends MagicPhase {
game.executeTrigger(MagicTriggerType.AtEndOfTurn,game.getTurnPlayer());
game.setStep(MagicStep.ActivePlayer);
}
@Override
protected void executeEndOfPhase(final MagicGame game) {
SoundEffects.getInstance().playClip(game,SoundEffects.TURN_SOUND);
}
}

View File

@ -1,5 +1,6 @@
package magic.model.phase;
import magic.data.SoundEffects;
import magic.model.MagicGame;
import magic.model.action.MagicStackResolveAction;
import magic.model.event.MagicPriorityEvent;
@ -42,6 +43,7 @@ public abstract class MagicPhase {
// Stack can be empty at this point, for instance by a counter unless event.
if (!game.getStack().isEmpty()) {
game.doAction(new MagicStackResolveAction());
SoundEffects.getInstance().playClip(game,SoundEffects.RESOLVE_SOUND);
}
if (game.isArtificial()) {
// Resolve stack in one go.

View File

@ -45,6 +45,7 @@ public class MagicStaticLocalVariable implements MagicLocalVariable {
public static int spiritOfTheHearth; // You can't be target of spells or abilities your opponent controls.
private static int tolsimirWolfblood;
private static int trueConviction;
private static int urabraskTheHidden;
private static int veteranArmorer;
private static int windbriskRaptor;
@ -167,6 +168,7 @@ public class MagicStaticLocalVariable implements MagicLocalVariable {
}
if (controller.getCount(firesOfYavimaya)>0||
controller.getCount(madrushCyclops)>0||
controller.getCount(urabraskTheHidden)>0||
(controller.getCount(goblinChieftain)>0&&permanent.hasSubType(MagicSubType.Goblin))) {
flags|=MagicAbility.Haste.getMask();
}
@ -246,6 +248,7 @@ public class MagicStaticLocalVariable implements MagicLocalVariable {
spiritOfTheHearth=definitions.getCard("Spirit of the Hearth").getIndex();
tolsimirWolfblood=definitions.getCard("Tolsimir Wolfblood").getIndex();
trueConviction=definitions.getCard("True Conviction").getIndex();
urabraskTheHidden=definitions.getCard("Urabrask the Hidden").getIndex();
veteranArmorer=definitions.getCard("Veteran Armorer").getIndex();
windbriskRaptor=definitions.getCard("Windbrisk Raptor").getIndex();
}

View File

@ -107,34 +107,32 @@ public class TestGameBuilder {
tournament.setPlayers(new MagicPlayerDefinition[]{player1,player2});
tournament.setStartPlayer(0);
final MagicGame game=tournament.nextGame();
final MagicGame game=tournament.nextGame(true);
game.setPhase(MagicMainPhase.getFirstInstance());
final MagicPlayer player=game.getPlayer(0);
final MagicPlayer opponent=game.getPlayer(1);
opponent.setLife(12);
opponent.setLife(1);
addToLibrary(player,"Plains",10);
addToLibrary(opponent,"Island",10);
addToGraveyard(player,"Mogg Fanatic",2);
addToGraveyard(opponent,"Island",2);
addToHand(opponent,"Zephyr Sprite",3);
addToHand(player,"Lightning Greaves",1);
addToHand(player,"Barbed Battlegear",1);
addToHand(player,"Vulshok Battlegear",1);
addToHand(player,"Vindicate",1);
addToHand(player,"Dragon Fodder",1);
addToHand(player,"Juniper Order Ranger",1);
addToHand(player,"Knight Exemplar",1);
addToHand(player,"Silver Knight",1);
addToHand(player,"Silvos, Rogue Elemental",1);
addToHand(player,"Visara the Dreadful",1);
addToHand(player,"Havoc Demon",1);
addToHand(player,"Thunder Dragon",1);
addToHand(player,"Arcanis the Omnipotent",1);
addToHand(player,"Perilous Myr",1);
addToHand(player,"Blackcleave Goblin",1);
createPermanent(game,player,"Watchwolf",false,1);
addToHand(player,"Raging Goblin",1);
addToHand(player,"Alloy Myr",1);
addToHand(player,"Batterskull",1);
addToHand(player,"Breath of Darigaaz",1);
addToHand(player,"Cudgel Troll",1);
addToHand(player,"Hovermyr",1);
addToHand(player,"Shrine of Burning Rage",1);
addToHand(player,"Unquestioned Authority",1);
addToHand(player,"Psychic Barrier",1);
addToHand(player,"Sheoldred, Whispering One",1);
addToHand(player,"Sword of War and Peace",1);
addToHand(player,"Urabrask the Hidden",1);
addToHand(player,"Sickleslicer",1);
createPermanent(game,player,"Raging Goblin",false,1);
createPermanent(game,player,"Bonesplitter",false,1);
createPermanent(game,player,"Rupture Spire",false,7);
createPermanent(game,opponent,"Bloodrock Cyclops",false,1);

View File

@ -1,185 +0,0 @@
package magic.ui;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Proxy.Type;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import magic.data.DownloadImageFile;
import magic.data.DownloadImageFiles;
import magic.data.IconImages;
public class DownloadImagesDialog extends JDialog implements Runnable,ActionListener {
private static final long serialVersionUID = 1L;
private static final String DOWNLOAD_IMAGES_FILENAME="images.txt";
private final DownloadImageFiles files;
private final JComboBox proxyComboBox;
private final JTextField addressTextField;
private final JTextField portTextField;
private final JProgressBar progressBar;
private final JLabel downloadLabel;
private final JButton okButton;
private final JButton cancelButton;
private Proxy proxy=null;
public DownloadImagesDialog(final MagicFrame frame) {
super(frame,true);
this.setLayout(new BorderLayout());
this.setTitle("Download images");
this.setSize(300,405);
this.setLocationRelativeTo(frame);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
final JPanel downloadPanel=new JPanel();
downloadPanel.setLayout(null);
add(downloadPanel,BorderLayout.CENTER);
final Proxy.Type[] proxyTypes=Proxy.Type.values();
final DefaultComboBoxModel proxyModel=new DefaultComboBoxModel(proxyTypes);
proxyComboBox=new JComboBox(proxyModel);
proxyComboBox.setBounds(10,25,220,25);
proxyComboBox.setFocusable(false);
proxyComboBox.addActionListener(this);
final JLabel addressLabel=new JLabel("Address");
addressLabel.setBounds(10,55,220,25);
addressTextField=new JTextField();
addressTextField.setBounds(10,80,220,25);
final JLabel portLabel=new JLabel("Port");
portLabel.setBounds(10,110,220,25);
portTextField=new JTextField();
portTextField.setBounds(10,135,220,25);
final JPanel proxyPanel=new JPanel();
proxyPanel.setBorder(BorderFactory.createTitledBorder("Proxy"));
proxyPanel.setBounds(25,20,240,175);
proxyPanel.setLayout(null);
proxyPanel.add(proxyComboBox);
proxyPanel.add(addressLabel);
proxyPanel.add(addressTextField);
proxyPanel.add(portLabel);
proxyPanel.add(portTextField);
downloadPanel.add(proxyPanel);
progressBar=new JProgressBar();
progressBar.setBounds(10,30,220,25);
downloadLabel=new JLabel();
downloadLabel.setBounds(10,60,220,25);
final JPanel progressPanel=new JPanel();
progressPanel.setBorder(BorderFactory.createTitledBorder("Progress"));
progressPanel.setBounds(25,210,240,100);
progressPanel.setLayout(null);
progressPanel.add(progressBar);
progressPanel.add(downloadLabel);
downloadPanel.add(progressPanel);
okButton=new JButton("OK");
okButton.setFocusable(false);
okButton.setIcon(IconImages.OK);
okButton.addActionListener(this);
cancelButton=new JButton("Cancel");
cancelButton.setFocusable(false);
cancelButton.setIcon(IconImages.CANCEL);
cancelButton.addActionListener(this);
final JPanel buttonPanel=new JPanel();
buttonPanel.setPreferredSize(new Dimension(0,45));
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT,15,0));
buttonPanel.add(okButton);
buttonPanel.add(cancelButton);
add(buttonPanel,BorderLayout.SOUTH);
files=new DownloadImageFiles(DOWNLOAD_IMAGES_FILENAME);
if (files.isEmpty()) {
okButton.setEnabled(false);
progressBar.setMaximum(1);
progressBar.setValue(1);
downloadLabel.setText("All images are present.");
} else {
downloadLabel.setText("Press OK to begin or Cancel.");
}
updateProxy();
setVisible(true);
}
private void updateProxy() {
final boolean use=proxyComboBox.getSelectedItem()!=Type.DIRECT;
addressTextField.setEnabled(use);
portTextField.setEnabled(use);
if (use) {
addressTextField.requestFocus();
}
}
@Override
public void run() {
progressBar.setMinimum(0);
progressBar.setMaximum(files.size());
int count=0;
for (final DownloadImageFile file : files) {
downloadLabel.setText(file.getFilename());
file.download(proxy);
progressBar.setValue(++count);
}
dispose();
System.exit(0);
}
@Override
public void actionPerformed(final ActionEvent event) {
final Object source=event.getSource();
if (source==okButton) {
try {
final Proxy.Type proxyType=(Proxy.Type)proxyComboBox.getSelectedItem();
if (proxyType==Type.DIRECT) {
proxy=Proxy.NO_PROXY;
} else {
final String address=addressTextField.getText();
final int port=Integer.parseInt(portTextField.getText());
proxy=new Proxy(proxyType,new InetSocketAddress(address,port));
}
} catch (final Exception ex) {
return;
}
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
proxyComboBox.setEnabled(false);
addressTextField.setEnabled(false);
portTextField.setEnabled(false);
okButton.setEnabled(false);
cancelButton.setEnabled(false);
new Thread(this).start();
} else if (source==cancelButton) {
dispose();
} else if (source==proxyComboBox) {
updateProxy();
}
}
}

View File

@ -15,6 +15,7 @@ import javax.swing.SwingUtilities;
import magic.ai.MagicAI;
import magic.data.GeneralConfig;
import magic.data.IconImages;
import magic.data.SoundEffects;
import magic.model.MagicCard;
import magic.model.MagicCardDefinition;
import magic.model.MagicGame;
@ -44,6 +45,7 @@ public class GameController {
private boolean undoClicked=false;
private boolean actionClicked=false;
private boolean combatChoice=false;
private boolean resetGame=false;
private Object choiceClicked=null;
private MagicCardDefinition sourceCardDefinition;
@ -88,6 +90,13 @@ public class GameController {
}
}
public void actionKeyPressed() {
if (gamePanel.canClickAction()) {
actionClicked();
}
}
public synchronized void actionClicked() {
undoClicked=false;
@ -96,6 +105,13 @@ public class GameController {
notifyAll();
}
public void undoKeyPressed() {
if (gamePanel.canClickUndo()) {
undoClicked();
}
}
public synchronized void undoClicked() {
if (game.hasUndoPoints()) {
@ -359,13 +375,21 @@ public class GameController {
return;
}
if (choiceResults==MagicChoice.UNDO_CHOICE_RESULTS) {
game.gotoLastUndoPoint();
performUndo();
return;
}
}
game.executeNextEvent(choiceResults);
}
public synchronized void resetGame() {
if (game.hasUndoPoints()) {
resetGame=true;
undoClicked();
}
}
public synchronized void concede() {
if (!gameConceded&&!game.isFinished()) {
@ -376,6 +400,19 @@ public class GameController {
notifyAll();
}
}
public void performUndo() {
if (resetGame) {
resetGame=false;
while (game.hasUndoPoints()) {
game.gotoLastUndoPoint();
}
} else {
game.gotoLastUndoPoint();
}
}
public void haltGame() {
@ -398,9 +435,14 @@ public class GameController {
game.logMessages();
clearValidChoices();
showMessage(null,"{L} "+game.getLosingPlayer()+" "+(gameConceded?"conceded":"lost")+" the game.|Press {f} to continue.");
if (game.getLosingPlayer().getIndex()==0) {
SoundEffects.getInstance().playClip(SoundEffects.LOSE_SOUND);
} else {
SoundEffects.getInstance().playClip(SoundEffects.WIN_SOUND);
}
enableForwardButton();
if (waitForInputOrUndo()) {
game.gotoLastUndoPoint();
performUndo();
update();
continue;
} else {
@ -434,4 +476,4 @@ public class GameController {
}
running.set(false);
}
}
}

View File

@ -162,7 +162,7 @@ public class GamePanel extends JPanel {
@Override
public void actionPerformed(final ActionEvent event) {
actionKeyPressed();
controller.actionKeyPressed();
}
});
@ -173,7 +173,7 @@ public class GamePanel extends JPanel {
@Override
public void actionPerformed(final ActionEvent event) {
undoKeyPressed();
controller.undoKeyPressed();
}
});
@ -206,7 +206,8 @@ public class GamePanel extends JPanel {
getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0),UNDO_KEY);
getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),UNDO_KEY);
getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),SWITCH_KEY);
getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0), LOG_KEY);
getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0),LOG_KEY);
getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_M, 0),LOG_KEY);
stackCombatViewer=new StackCombatViewer(viewerInfo,controller);
handGraveyardViewer=new HandGraveyardExileViewer(viewerInfo,controller);
@ -228,20 +229,16 @@ public class GamePanel extends JPanel {
thread.start();
}
void actionKeyPressed() {
public boolean canClickAction() {
if (gameTournamentViewer.getGameViewer().isActionEnabled()) {
controller.actionClicked();
}
return gameTournamentViewer.getGameViewer().isActionEnabled();
}
void undoKeyPressed() {
if (gameTournamentViewer.getGameViewer().isUndoEnabled()) {
controller.undoClicked();
}
public boolean canClickUndo() {
return gameTournamentViewer.getGameViewer().isUndoEnabled();
}
void switchKeyPressed() {
if (textViewButton.isEnabled()) {

View File

@ -39,6 +39,7 @@ public class MagicFrame extends JFrame implements ActionListener {
private static final String SAVE_DECK_ITEM="SaveDeck";
private static final String SWAP_DECKS_ITEM="Swap";
private static final String PLAY_GAME_ITEM="Play";
private static final String RESET_GAME_ITEM="Reset";
private static final String CONCEDE_GAME_ITEM="Concede";
private static final String CARD_EXPLORER_ITEM="Explorer";
private static final String KEYWORDS_ITEM="Keywords";
@ -55,8 +56,8 @@ public class MagicFrame extends JFrame implements ActionListener {
private JMenuItem saveDeckItem;
private JMenuItem swapDecksItem;
private JMenuItem playGameItem;
private JMenuItem resetGameItem;
private JMenuItem concedeGameItem;
private JMenuItem downloadImagesItem;
private JMenuItem preferencesItem;
private JMenuItem quitItem;
private JMenuItem cardExplorerItem;
@ -128,13 +129,15 @@ public class MagicFrame extends JFrame implements ActionListener {
swapDecksItem.setEnabled(enabled);
} else if (PLAY_GAME_ITEM.equals(item)) {
playGameItem.setEnabled(enabled);
} else if (RESET_GAME_ITEM.equals(item)) {
resetGameItem.setEnabled(enabled);
} else if (CONCEDE_GAME_ITEM.equals(item)) {
concedeGameItem.setEnabled(enabled);
} else if (CARD_EXPLORER_ITEM.equals(item)) {
cardExplorerItem.setEnabled(enabled);
} else if (KEYWORDS_ITEM.equals(item)) {
keywordsItem.setEnabled(enabled);
}
}
}
private void setInitialContent() {
@ -173,6 +176,7 @@ public class MagicFrame extends JFrame implements ActionListener {
enableMenuItem(SAVE_DECK_ITEM,false);
enableMenuItem(SWAP_DECKS_ITEM,false);
enableMenuItem(PLAY_GAME_ITEM,false);
enableMenuItem(RESET_GAME_ITEM,false);
enableMenuItem(CONCEDE_GAME_ITEM,false);
enableMenuItem(CARD_EXPLORER_ITEM,true);
enableMenuItem(KEYWORDS_ITEM,true);
@ -224,16 +228,16 @@ public class MagicFrame extends JFrame implements ActionListener {
playGameItem.addActionListener(this);
tournamentMenu.add(playGameItem);
resetGameItem=new JMenuItem("Reset game");
resetGameItem.addActionListener(this);
tournamentMenu.add(resetGameItem);
concedeGameItem=new JMenuItem("Concede game");
concedeGameItem.addActionListener(this);
tournamentMenu.add(concedeGameItem);
tournamentMenu.addSeparator();
downloadImagesItem=new JMenuItem("Download images...");
downloadImagesItem.addActionListener(this);
tournamentMenu.add(downloadImagesItem);
preferencesItem=new JMenuItem("Preferences...");
preferencesItem.addActionListener(this);
tournamentMenu.add(preferencesItem);
@ -367,17 +371,24 @@ public class MagicFrame extends JFrame implements ActionListener {
}
}
public void resetGame() {
if (gamePanel!=null) {
gamePanel.getController().resetGame();
}
}
public void concedeGame() {
if (gamePanel!=null) {
gamePanel.getController().concede();
}
}
public void nextGame() {
tournament.updateDifficulty();
openGame(tournament.nextGame());
openGame(tournament.nextGame(true));
}
private void openGame(final MagicGame game) {
@ -388,6 +399,7 @@ public class MagicFrame extends JFrame implements ActionListener {
final GameLayeredPane gamePane=new GameLayeredPane(gamePanel,backgroundLabel);
setContent(gamePane);
gamePanel.requestFocus();
enableMenuItem(RESET_GAME_ITEM,true);
enableMenuItem(CONCEDE_GAME_ITEM,true);
}
@ -448,10 +460,10 @@ public class MagicFrame extends JFrame implements ActionListener {
swapDecks();
} else if (source==playGameItem) {
nextGame();
} else if (source==resetGameItem) {
resetGame();
} else if (source==concedeGameItem) {
concedeGame();
} else if (source==downloadImagesItem) {
new DownloadImagesDialog(this);
} else if (source==preferencesItem) {
new PreferencesDialog(this);
} else if (source==quitItem) {

View File

@ -17,6 +17,7 @@ import javax.swing.JLabel;
import javax.swing.JPanel;
import magic.ai.MagicAIImpl;
import magic.data.AvatarImages;
import magic.data.GeneralConfig;
import magic.data.IconImages;
import magic.ui.theme.ThemeFactory;
@ -28,12 +29,13 @@ public class PreferencesDialog extends JDialog implements ActionListener {
private final MagicFrame frame;
private final JComboBox themeComboBox;
private final JComboBox avatarComboBox;
private final JComboBox aiComboBox;
private final JCheckBox soundCheckBox;
private final JCheckBox highQualityCheckBox;
private final JCheckBox skipSingleCheckBox;
private final JCheckBox alwaysPassCheckBox;
private final JCheckBox smartTargetCheckBox;
private final SliderPanel undoLevelsSlider;
private final SliderPanel popupDelaySlider;
private final JButton okButton;
private final JButton cancelButton;
@ -42,7 +44,7 @@ public class PreferencesDialog extends JDialog implements ActionListener {
super(frame,true);
this.setTitle("Preferences");
this.setSize(400,400);
this.setSize(400,420);
this.setLocationRelativeTo(frame);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
@ -79,43 +81,55 @@ public class PreferencesDialog extends JDialog implements ActionListener {
themeComboBox.setSelectedItem(config.getTheme());
mainPanel.add(themeComboBox);
final JLabel avatarLabel=new JLabel("Avatar");
avatarLabel.setBounds(28,55,70,25);
avatarLabel.setIcon(IconImages.AVATAR);
mainPanel.add(avatarLabel);
final ComboBoxModel avatarModel=new DefaultComboBoxModel(AvatarImages.getInstance().getNames());
avatarComboBox=new JComboBox(avatarModel);
avatarComboBox.setFocusable(false);
avatarComboBox.setBounds(100,55,255,25);
avatarComboBox.setSelectedItem(config.getAvatar());
mainPanel.add(avatarComboBox);
final JLabel aiLabel=new JLabel("AI");
aiLabel.setBounds(28,55,70,25);
aiLabel.setBounds(28,90,70,25);
aiLabel.setIcon(IconImages.DIFFICULTY);
mainPanel.add(aiLabel);
final ComboBoxModel aiModel=new DefaultComboBoxModel(MagicAIImpl.getNames());
aiComboBox=new JComboBox(aiModel);
aiComboBox.setFocusable(false);
aiComboBox.setBounds(100,55,255,25);
aiComboBox.setBounds(100,90,255,25);
aiComboBox.setSelectedItem(config.getAi());
mainPanel.add(aiComboBox);
soundCheckBox=new JCheckBox("Enable sound effects",config.isSound());
soundCheckBox.setBounds(25,135,350,20);
soundCheckBox.setFocusable(false);
mainPanel.add(soundCheckBox);
highQualityCheckBox=new JCheckBox("High quality card popup images",config.isHighQuality());
highQualityCheckBox.setBounds(25,95,350,20);
highQualityCheckBox.setBounds(25,165,350,20);
highQualityCheckBox.setFocusable(false);
mainPanel.add(highQualityCheckBox);
skipSingleCheckBox=new JCheckBox("Skip single option choices when appropriate",config.getSkipSingle());
skipSingleCheckBox.setBounds(25,125,350,20);
skipSingleCheckBox.setBounds(25,195,350,20);
skipSingleCheckBox.setFocusable(false);
mainPanel.add(skipSingleCheckBox);
alwaysPassCheckBox=new JCheckBox("Always pass during draw and begin of combat step",config.getAlwaysPass());
alwaysPassCheckBox.setBounds(25,155,350,20);
alwaysPassCheckBox.setBounds(25,225,350,20);
alwaysPassCheckBox.setFocusable(false);
mainPanel.add(alwaysPassCheckBox);
smartTargetCheckBox=new JCheckBox("Filter legal targets when appropriate",config.getSmartTarget());
smartTargetCheckBox.setBounds(25,185,350,20);
smartTargetCheckBox.setBounds(25,255,350,20);
smartTargetCheckBox.setFocusable(false);
mainPanel.add(smartTargetCheckBox);
undoLevelsSlider=new SliderPanel("Undo",IconImages.UNDO,1,7,1,config.getUndoLevels());
undoLevelsSlider.setBounds(60,215,270,50);
mainPanel.add(undoLevelsSlider);
popupDelaySlider=new SliderPanel("Popup",IconImages.DELAY,0,500,50,config.getPopupDelay());
popupDelaySlider.setBounds(60,265,270,50);
popupDelaySlider.setBounds(60,285,270,50);
mainPanel.add(popupDelaySlider);
getContentPane().setLayout(new BorderLayout());
@ -132,12 +146,13 @@ public class PreferencesDialog extends JDialog implements ActionListener {
if (source==okButton) {
final GeneralConfig config=GeneralConfig.getInstance();
config.setTheme((String)themeComboBox.getSelectedItem());
config.setAvatar((String)avatarComboBox.getSelectedItem());
config.setAi((String)aiComboBox.getSelectedItem());
config.setSound(soundCheckBox.isSelected());
config.setHighQuality(highQualityCheckBox.isSelected());
config.setSkipSingle(skipSingleCheckBox.isSelected());
config.setAlwaysPass(alwaysPassCheckBox.isSelected());
config.setSmartTarget(smartTargetCheckBox.isSelected());
config.setUndoLevels(undoLevelsSlider.getValue());
config.setPopupDelay(popupDelaySlider.getValue());
config.save();
ThemeFactory.getInstance().setCurrentTheme(config.getTheme());

View File

@ -27,12 +27,9 @@ import magic.ui.widget.ZoneBackgroundLabel;
public class VersionPanel extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L;
private static final String VERSION = "Magarena 1.11";
private static final String AUTHOR = "by ubeefx";
private static final String WEB = "http://magarena.dyndns.org";
private static final String SPACING = " ";
private static final String VERSION_TEXT = VERSION + SPACING + AUTHOR + SPACING + WEB;
private static final String VERSION = "1.13";
private static final String VERSION_TEXT = "Magarena Limited Edition "+VERSION+" by ubeefx";
private static final Border LOGO_BORDER=BorderFactory.createMatteBorder(2,2,2,2,new Color(0x8C,0x78,0x53));

View File

@ -2,20 +2,12 @@ package magic.ui.theme;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import magic.MagicMain;
import magic.data.AvatarImages;
import magic.data.IconImages;
import magic.ui.widget.FontsAndBorders;
@ -23,15 +15,11 @@ public abstract class AbstractTheme implements Theme {
private final String name;
private final Map<String,Object> themeMap;
private final List<File> avatarFiles;
private final PlayerAvatar avatars[];
public AbstractTheme(final String name) {
this.name=name;
themeMap=new HashMap<String,Object>();
avatarFiles=new ArrayList<File>();
avatars=loadAvatars(avatarFiles);
addToTheme(TEXTURE_LOGO,null);
@ -140,47 +128,16 @@ public abstract class AbstractTheme implements Theme {
final Object value=themeMap.get(name);
return value==null?0:(Integer)value;
}
private PlayerAvatar[] loadAvatars(final List<File> avatarFiles) {
final File files[]=new File(MagicMain.getGamePath()+File.separator+"avatars").listFiles();
if (files==null||files.length<2) {
avatarFiles.add(new File("unknown"));
avatarFiles.add(new File("unknown"));
} else {
avatarFiles.addAll(Arrays.asList(files));
}
Collections.sort(avatarFiles);
return new PlayerAvatar[avatarFiles.size()];
}
@Override
public int getNumberOfAvatars() {
return avatars.length;
return AvatarImages.getInstance().getNumberOfAvatars();
}
@Override
public synchronized ImageIcon getAvatarIcon(int index,final int size) {
public ImageIcon getAvatarIcon(int index,final int size) {
if (index<0) {
index=0;
} else if (index>=avatars.length) {
index%=avatars.length;
}
PlayerAvatar avatar=avatars[index];
if (avatar==null) {
BufferedImage image;
try {
final InputStream stream=new FileInputStream(avatarFiles.get(index));
image=ImageIO.read(stream);
stream.close();
} catch (final Exception ex) {
image=IconImages.MISSING;
}
avatar=new PlayerAvatar(image);
avatars[index]=avatar;
}
return avatar.getIcon(index,size);
return AvatarImages.getInstance().getAvatarIcon(index,size);
}
}

View File

@ -50,7 +50,7 @@ public class CustomTheme extends AbstractTheme {
if (nrOfAvatars==0) {
return super.getAvatarIcon(index, size);
}
return playerAvatars[index%nrOfAvatars].getIcon(index,size);
return playerAvatars[index%nrOfAvatars].getIcon(size);
}
private void parseEntry(final String key,final String value) {

View File

@ -25,7 +25,7 @@ public class PlayerAvatar {
smallIcon=new ImageIcon(smallImage);
}
public ImageIcon getIcon(final int index,final int size) {
public ImageIcon getIcon(final int size) {
switch (size) {
case 2: return mediumIcon;

View File

@ -214,7 +214,7 @@ public class DeckStrengthViewer extends JPanel implements ActionListener {
while (running.get()&&!testTournament.isFinished()) {
gameLabel.setText("Game "+(testTournament.getGamesPlayed()+1));
final MagicGame game=testTournament.nextGame();
final MagicGame game=testTournament.nextGame(false);
controller=new GameController(null,game);
controller.runGame();
progressBar.setValue(testTournament.getGamesPlayed());

View File

@ -70,7 +70,6 @@ public class GameViewer extends TexturedPanel implements ActionListener {
actionPanel.add(actionButton,"2");
undoButton=new JButton(IconImages.UNDO);
undoButton.setFont(FontsAndBorders.FONT0);
undoButton.setMargin(new Insets(1,1,1,1));
undoButton.setIconTextGap(2);
undoButton.setEnabled(false);
@ -158,11 +157,6 @@ public class GameViewer extends TexturedPanel implements ActionListener {
final int undoPoints=game.getNrOfUndoPoints();
final boolean allowUndo=undoPoints>0&&!thinking;
undoButton.setEnabled(allowUndo);
if (undoButton.isEnabled()) {
undoButton.setText(String.valueOf(undoPoints));
} else {
undoButton.setText("");
}
}
public void enableButton(final ImageIcon icon) {

View File

@ -58,6 +58,11 @@ public class ImageCardListViewer extends JPanel implements ChoiceViewer {
@Override
public void mousePressed(final MouseEvent event) {
if (event.getButton() == MouseEvent.BUTTON3) {
controller.actionKeyPressed();
return;
}
final int index=getCardIndexAt(event.getX(),event.getY());
if (index>=0) {
controller.processClick(cardList.get(index));

View File

@ -68,7 +68,9 @@ public class ImageDrawingUtils {
g.drawImage(IconImages.TRAMPLE.getImage(),ax,ay,observer);
ax+=16;
}
if (MagicAbility.Deathtouch.hasAbility(abilityFlags)) {
if (MagicAbility.Deathtouch.hasAbility(abilityFlags)||
MagicAbility.Wither.hasAbility(abilityFlags)||
MagicAbility.Infect.hasAbility(abilityFlags)) {
g.drawImage(IconImages.DEATHTOUCH.getImage(),ax,ay,observer);
ax+=16;
}

View File

@ -1,10 +0,0 @@
# Card blacklist - list of cards to never automatically import by script
# Special cards, such as tokens, or cards that failt to import correctly should be put here
# List one card name per line, empty lines are ignored, hash mark starts a comment
# Tokens
Elemental Shaman
Spirit
Elemental
Goblin

View File

@ -1,63 +0,0 @@
#!/usr/bin/perl
# Generate list of already implemented cards
# Check that all cards have image and HQ image and there is no image or HQ image without a card
use strict;
use mutils;
my %config=default_config();
my %all=();
my %cards=();
my %images=();
my %hq_images=();
# Load cards
open F,"<".$config{'cardfile'};
while (<F>) {
next if (!/^>/);
s/^>//;
s/[\r\n]//gm;
$all{$_}=1;
$cards{$_}=1;
}
close F;
# Load images
my $current='';
open F,"<".$config{'imagefile'};
while (<F>) {
s/[\r\n]+//gm;
if (/^>(.*)/) {
$current=$1;
next;
}
s/\.jpg;.*$//i;
if ($current eq 'cards') {
$all{$_}=1;
$images{$_}=1;
}
if ($current eq 'hqcards') {
$all{$_}=1;
$hq_images{$_}=1;
}
}
close F;
# Save cardlist to defined file
open O,">".$config{'cardlist'};
foreach my $c (sort keys %cards) {
print O $c."\n";
}
close O;
#Check images
foreach my $c (sort keys %all) {
next if ($c=~/^(Forest|Island|Mountain|Plains|Swamp)2$/);
next if ($cards{$c} && $images{$c} && $hq_images{$c});
if (!$cards{$c}) {print "Missing card for image/HQ image $c\n";}
if (!$images{$c} && !$hq_images{$c}) {print "Missing image and HQ image for card $c\n";}
elsif (!$images{$c}) {print "Missing image for card $c\n";}
elsif (!$hq_images{$c}) {print "Missing HQ image for card $c\n";}
}

View File

@ -1,260 +0,0 @@
#!/usr/bin/perl
# Parse cards from a list and output those cards, that can be automatically imported without changing the Java code
use strict;
use mutils;
my %config=default_config();
# Blacklist - list of cards not to be implemented - for example ante cards
my $blacklist='blacklist.txt';
# List of allowed editions
my $editions='editions.txt';
# Output - list of cards that were not fully understood by this parser
my $cardlist='_unparsed_cards.txt';
# Output - parts of rule text not understood by this parser
my $errorlog='_unparsed_code.txt';
# Output - definitions of newly imported cards
my $cardout='_cards.txt';
# Output - images of newly imported cards
my $imageout='_images.txt';
# Output - high quality images of newly imported cards
my $hqimageout='_hqimages.txt';
# List of cards to skip
my %skip=();
# Skip all cards listed in given file when importing.
sub skip_cards {
my $filename=shift;
open P,"<$filename";
while (<P>) {
s/[\r\n]+//gm;
s/#.*//;
s/^\s+//gm;
s/\s+$//gm;
next if (/^$/);
$skip{$_}=1;
}
close P;
}
skip_cards($config{'cardlist'});
skip_cards($blacklist);
load_editions($editions);
# Links to high quality images
my %hqim=();
# Load file with information about high-quality images
open H,"<".$config{'hqhtml'};
binmode H;
while (<H>) {
if (m#<td><a href="/([a-z0-9]+)/([a-z0-9]+)/(\d+).html">([Æûáâàíäöú\-\._'a-zA-Z, \(\)"\?]+)</a></td>#) {
my $url="http://magiccards.info/scans/$2/$1/$3.jpg";
$hqim{$4}=$url;
#http://magiccards.info/5e/en/277.html -> http://magiccards.info/scans/en/5e/277.jpg
} else {
if (m#<td><a href="[^"]+">[^<>]+</a></td>#) {
print STDERR "Unrecognized HQ card: $_";
}
}
}
close H;
#Number of cards imported
my $numc=0;
#Number of cards skipped because not in allowed edition
my $nume=0;
#Card data for current card
my %k=();
open EDI,">".$config{'edition_contents'};
binmode EDI;
open F,"<".$config{'cardhtml'};
binmode F;
open O,">$cardlist";
binmode O;
open OU,">$cardout";
binmode OU;
open ER,">$errorlog";
binmode ER;
open IO,">$imageout";
binmode IO;
open IOH,">$hqimageout";
binmode IOH;
sub emit {
my $name=$k{'Name'};
if (!$name=~/./) {return;}
my $rarity=$k{'Set/Rarity'};
my @ed=edition_list($rarity);
foreach my $e (@ed) {
print EDI "$name|$e\n";
}
if ($skip{$name}) {
%k=();
return;
}
if (!allowed_edition($rarity)) {
$nume++;
return;
}
normalize_type(\%k);
my $txt=normalize_ruletext($k{'Rules Text'},$name);
$k{'Rules Text'}=$txt;
my $cost=$k{'Cost'};
my $complex=1;
my $type=$k{'Type'};
my $subtype=$k{'Subtype'};
if ($type=~/^(Legendary,|Artifact,|)Creature$/) {
my $complex=0;
my @abil=();
my %haveabil=();
my $pt=$k{'Pow/Tgh'};
my $pow='';
my $tou='';
if ($pt=~/^\((.*)\/(.*)\)$/) {
$pow=$1;
$tou=$2;
$k{'Pow/Tgh'}="$pow/$tou";
}
if ($rarity=~/rare/i) {$rarity=3;}
if ($rarity=~/uncommon/i) {$rarity=2;}
if ($rarity=~/common/i) {$rarity=1;}
if (!($pow=~/^[0-9]+$/)) {$complex=1;}
if (!($tou=~/^[0-9]+$/)) {$complex=1;}
while ($txt=~s/^(can't block creatures without flying|can't be blocked except by creatures with flying|can't attack or block|attacks each turn if able|can't be countered|can't block|unblockable|changeling|deathtouch|defender|double strike|exalted|fear|first strike|flash|flying|forestwalk|haste|indestructible|intimidate|islandwalk|lifelink|mountainwalk|plainswalk|persist|protection from (Demons|Dragons|all colors|black|blue|creatures|green|monocolored|red|white)|reach|shroud|swampwalk|trample|vigilance|wither)\s*(,|;|<br\s*\/?>|)\s*//i) {
#battle cry
#can't be blocked by creatures with flying
#can't be the target of spells or abilities your opponent controls
#totem armor
push @abil,lc $1;
$haveabil{lc $1}=1;
}
$txt=~s/^<br \/>//i;
my $abils=join(',',@abil);
if ($txt=~/./) {
$complex=1;
$k{'Complex rules'}=$txt;
$txt=~s/<br \/>/\n/gm;
$txt=~s/$name/(THIS)/gm;
$txt=~s/(\{\([rgbuw]\/[rgbuw]\))*(\{([0-9]+|[RGBUWX]|\([rgbuw]\/[rgbuw]\))\})+/(MANACOST)/gm;
print ER $txt."\n";
}
if ($cost eq '') {$complex=1;}
if (!$complex) {
$subtype=~s/ /,/g;
$numc++;
if ($abils=~/./) {$abils='ability='.$abils."\n";}
my $timing='main';
if ($abils=~/haste|can.t block|shroud/) {$timing="fmain";}
if ($abils=~/defender/) {$timing="smain";}
my $c_conv=0;
my $c_cost='';
if ($cost=~/^(\d+)?((\([RGBUW]\/[RGBUW]\))*)?([RGBUW]+)?$/) {
my $num=$1;
my $xcol=$2;
$xcol=~tr/()/{}/;
my $col=$4;
if (length($num)) {
$c_conv+=$num;
$c_cost='{'.$num.'}';
}
if ($col) {
$c_conv+=length $col;
$c_cost.='{'.join('}{',split(//,$col)).'}';
}
if ($xcol) {
$c_conv+=(length $xcol)/5;
$c_cost.=$xcol;
}
} else {
print STDERR "Unknown casting cost: $cost\n";
}
my $c_color=spell_color($cost);
if ($c_color) { $c_color='color='.$c_color."\n";}
# Output images
my $id=$k{'id'};
if ($id) {
print IO "${name}.jpg;http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=$id&type=card\n";
} else {
print STDERR "Missing image id for $name\n";
}
my $hqi=$hqim{$name};
if ($hqi) {
print IOH "${name}.jpg;$hqi\n";
} else {
print STDERR "Missing HQ image for $name\n";
}
#TODO: value?
print OU <<EOF;
>$name
value=$rarity
${abils}rarity=$rarity
type=$type
subtype=$subtype
${c_color}converted=$c_conv
cost=$c_cost
power=$pow
toughness=$tou
timing=$timing
EOF
}
}
if ($complex) {
foreach my $q (keys %k) {
print O "$q = ".$k{$q}."\n";
}
print O "\n";
}
%k=();
}
my $c='';
while (<F>) {
s/\s+/ /gm;
$c.=$_;
if (m#</tr>#) {
$c=~s/.*<tr/<tr/mi;
$c=~s/\s+</</gmi;
$c=~s/>\s+/>/gmi;
$c=~s/\s+id="[^"<>]+"//gmi;
# if (!/Name:/) {$c='';} else {
if ($c=~/td colspan/) {emit();$c='--';}
if ($c=~m#^<tr><td>([^<>]+):</td><td>(.*)</td></tr>$#) {
my $key=$1;
my $value=$2;
if ($key=~/name/i && $value=~m#<a[^<>]+ href="[^"]*multiverseid=(\d+)">([^<>]+)</a>#) {
$c="$key = $2\nID = $1";
$k{$key}=$2;
$k{'id'}=$1;
} else {
$k{$key}=$value;
$c="$key = $value";
}
}
# print O "::".$c."\n";
$c='';
#
# }
}
}
emit();
close F;
close O;
close OU;
close ER;
close IO;
close IOH;
close EDI;
print STDERR "$numc cards imported\n";
print STDERR "$nume card excluded (bad edition)\n";

View File

@ -1,98 +0,0 @@
#!/usr/bin/perl
# Generate automatically generated cubes based on specified config
use strict;
use mutils;
my %config=default_config();
# Prefix (output directory + possible prefix) for generated cubes
my $cube_output_prefix=$config{'root'}.'resources/magic/data/';
my $cubename='';
my %ban=();
my %allow_all=();
my %allow=();
my %allow_ed=();
my %restrict=();
my %avail=();
# Output only available cards
sub load_cards {
my $filename=shift;
open P,"<$filename";
while (<P>) {
s/[\r\n]+//gm;
$avail{$_}=1;
}
close P;
}
load_cards($config{'cardlist'});
#Load edition contents
my @ed=();
open EDI,"<".$config{'edition_contents'};
while (<EDI>) {
s/[\r\n]+//gm;
push @ed,$_;
}
close EDI;
# Write out a signle cube from data in memory
sub emit {
if ($cubename eq '') {return ;}
my %out=();
foreach my $r (@ed) {
my ($card,$edition)=split(/\|/,$r);
next if ($ban{$card});
if ($allow_all{$card}) {$out{$card}=1;next;};
if ($allow{$card}) {$out{$card}=1;next;};
if ($allow_ed{$edition} || $allow_ed{'*'}) {$out{$card}=1;next;};
}
print STDERR "Generating cube $cubename\n";
open Q,">".$cube_output_prefix.$cubename."_cube.txt";
foreach my $card (sort keys %out) {
next if (!$avail{$card});
print Q "$card\n";
}
close Q;
%ban=();
%allow=();
%allow_ed=();
%restrict=();
$cubename='';
}
# If commandline parameter is specified, use it as source of cube data
if ($ARGV[0]) {
$config{'cubegen_data'}=$ARGV[0]
}
# Load cubegen data
open F,"<".$config{'cubegen_data'};
while (<F>) {
next if (/^#/);
s/[\r\n]+//gm;
s/#.*//;
s/^\s+//gm;
s/\s+$//gm;
next if (/^$/);
if (/^\[(.*)\]/) {
my $nextcube=$1;
emit();
$cubename=$nextcube;
} elsif(/^disallow:(.*)/) {
$ban{$1}=1;
} elsif(/^allow:(.*)/) {
$allow{$1}=1;
} elsif(/^universal:(.*)/) {
$allow_all{$1}=1;
} elsif(/^restrict:(.*)/) {
$restrict{$1}=1;
} else {
$allow_ed{$_}=1;
}
}
emit();
close F;

View File

@ -1,253 +0,0 @@
# Config file for cube generator
# Cubes are generated based on sets, with possibility of additionally allowing or banning single cards
#
# Syntax of this file:
# [Name of the cube]
# Name of set to include in cube (if line is not understood as special command)
# * = all sets
# Special commands are allowed:
# allow:Name of single card to allow
# universal:Name of single card to allow in all cubes
# disallow:Name of card to ban
# restrict:Name of card do restrict
#
# Leading and trailing whitespace is removed, empty lines are ignored, comments begin with hash sign
universal:Forest
universal:Swamp
universal:Mountain
universal:Plains
universal:Island
# This cube is equivalent to all implemented cards that can be used in Legacy tournament format
[Legacy]
*
disallow:Amulet of Quoz
disallow:Ancestral Recall
disallow:Balance
disallow:Bazaar of Baghdad
disallow:Black Lotus
disallow:Black Vise
disallow:Bronze Tablet
disallow:Channel
disallow:Chaos Orb
disallow:Contract from Below
disallow:Darkpact
disallow:Demonic Attorney
disallow:Demonic Consultation
disallow:Demonic Tutor
disallow:Earthcraft
disallow:Falling Star
disallow:Fastbond
disallow:Flash
disallow:Frantic Search
disallow:Goblin Recruiter
disallow:Gush
disallow:Hermit Druid
disallow:Imperial Seal
disallow:Jeweled Bird
disallow:Land Tax
disallow:Library of Alexandria
disallow:Mana Crypt
disallow:Mana Drain
disallow:Mana Vault
disallow:Memory Jar
disallow:Mind Twist
disallow:Mind's Desire
disallow:Mishra's Workshop
disallow:Mox Emerald
disallow:Mox Jet
disallow:Mox Pearl
disallow:Mox Ruby
disallow:Mox Sapphire
disallow:Mystical Tutor
disallow:Necropotence
disallow:Oath of Druids
disallow:Rebirth
disallow:Shahrazad
disallow:Skullclamp
disallow:Sol Ring
disallow:Strip Mine
disallow:Survival of the Fittest
disallow:Tempest Efreet
disallow:Time Vault
disallow:Time Walk
disallow:Timetwister
disallow:Timmerian Fiends
disallow:Tinker
disallow:Tolarian Academy
disallow:Vampiric Tutor
disallow:Wheel of Fortune
disallow:Windfall
disallow:Worldgorger Dragon
disallow:Yawgmoth's Bargain
disallow:Yawgmoth's Will
# This cube is equivalent to all implemented cards that can be used in Vintage tournament format
[Vintage]
*
disallow:Amulet of Quoz
disallow:Bronze Tablet
disallow:Chaos Orb
disallow:Contract from Below
disallow:Darkpact
disallow:Demonic Attorney
disallow:Falling Star
disallow:Jeweled Bird
disallow:Rebirth
disallow:Shahrazad
disallow:Tempest Efreet
disallow:Timmerian Fiends
restrict:Ancestral Recall
restrict:Balance
restrict:Black Lotus
restrict:Brainstorm
restrict:Burning Wish
restrict:Channel
restrict:Demonic Consultation
restrict:Demonic Tutor
restrict:Fact or Fiction
restrict:Fastbond
restrict:Flash
restrict:Gifts Ungiven
restrict:Imperial Seal
restrict:Library of Alexandria
restrict:Lions Eye Diamond
restrict:Lotus Petal
restrict:Mana Crypt
restrict:Mana Vault
restrict:Memory Jar
restrict:Merchant Scroll
restrict:Minds Desire
restrict:Mox Emerald
restrict:Mox Jet
restrict:Mox Pearl
restrict:Mox Ruby
restrict:Mox Sapphire
restrict:Mystical Tutor
restrict:Necropotence
restrict:Ponder
restrict:Regrowth
restrict:Sol Ring
restrict:Strip Mine
restrict:Thirst for Knowledge
restrict:Time Vault
restrict:Time Walk
restrict:Timetwister
restrict:Tinker
restrict:Tolarian Academy
restrict:Trinisphere
restrict:Vampiric Tutor
restrict:Wheel of Fortune
restrict:Windfall
restrict:Yawgmoths Bargain
restrict:Yawgmoths Will
# This cube is equivalent to all implemented cards that can be used in Standard tournament format
[Standard]
Magic 2011
Zendikar
Worldwake
Rise of the Eldrazi
Scars of Mirrodin
Mirrodin Besieged
# This cube is equivalent to all implemented cards that can be used in Extended tournament format
[Extended]
Magic 2010
Magic 2011
Lorwyn
Morningtide
Shadowmoor
Eventide
Shards of Alara
Conflux
Alara Reborn
Zendikar
Worldwake
Rise of the Eldrazi
Scars of Mirrodin
Mirrodin Besieged
# This cube is equivalent to all implemented cards that can be used in Invasion block tournament format
[Invasion block]
Invasion
Planeshift
Apocalypse
# This cube is equivalent to all implemented cards that can be used in Odyssey block tournament format
[Odyssey block]
Odyssey
Torment
Judgment
# This cube is equivalent to all implemented cards that can be used in Onslaught block tournament format
[Onslaught block]
Onslaught
Legions
Scourge
# This cube is equivalent to all implemented cards that can be used in Mirrodin block tournament format
[Mirrodin block]
Mirrodin
Darksteel
Fifth Dawn
disallow:AEther Vial
disallow:Ancient Den
disallow:Arcbound Ravager
disallow:Darksteel Citadel
disallow:Disciple of the Vault
disallow:Great Furnace
disallow:Seat of the Synod
disallow:Tree of Tales
disallow:Vault of Whispers
disallow:Skullclamp
# This cube is equivalent to all implemented cards that can be used in Kamigawa block tournament format
[Kamigawa block]
Champions of Kamigawa
Betrayers of Kamigawa
Saviors of Kamigawa
# This cube is equivalent to all implemented cards that can be used in Ravnica block tournament format
[Ravnica block]
Ravnica: City of Guilds
Guildpact
Dissension
# This cube is equivalent to all implemented cards that can be used in Time Spiral block tournament format
[Time Spiral block]
Time Spiral
Planar Chaos
Future Sight
# This cube is equivalent to all implemented cards that can be used in Lorwyn block tournament format
[Lorwyn block]
Lorwyn
Morningtide
# This cube is equivalent to all implemented cards that can be used in Shadowmoor block tournament format
[Shadowmoor block]
Shadowmoor
Eventide
# This cube is equivalent to all implemented cards that can be used in Shards of Alara block tournament format
[Shards of Alara block]
Shards of Alara
Conflux
Alara Reborn
# This cube is equivalent to all implemented cards that can be used in Zendikar block tournament format
[Zendikar block]
Zendikar
Worldwake
Rise of the Eldrazi
# This cube is equivalent to all implemented cards that can be used in Scars of Mirrodin block tournament format
[Scars of Mirrodin block]
Scars of Mirrodin
Mirrodin Besieged
# This cube contains all implemented cards
[All]
*

View File

@ -1,67 +0,0 @@
# List of allowed editions, used to filter which cards can be automatically imported by a script
# One edition per line, comments start with hash, empty lines are ignored
# Base sets
Seventh Edition
Eighth Edition
Ninth Edition
Tenth Edition
Magic 2010
Magic 2011
# Invasion block
Invasion
Planeshift
Apocalypse
# Odyssey block
Odyssey
Torment
Judgment
# Onslaught block
Onslaught
Legions
Scourge
# Mirrodin block
Mirrodin
Darksteel
Fifth Dawn
# Kamigawa block
Champions of Kamigawa
Betrayers of Kamigawa
Saviors of Kamigawa
# Ravnica block
Ravnica: City of Guilds
Guildpact
Dissension
# Time Spiral block
Time Spiral
Planar Chaos
Future Sight
# Lorwyn block
Lorwyn
Morningtide
# Shadowmoor block
Shadowmoor
Eventide
# Shards of Alara block
Shards of Alara
Conflux
Alara Reborn
# Zendikar block
Zendikar
Worldwake
Rise of the Eldrazi
# Scars of Mirrodin block
Scars of Mirrodin
Mirrodin Besieged

View File

@ -1,173 +0,0 @@
use strict;
#This module contains common function
# List of allowed editions
my %eds=();
# Load list of allowed editions
# Parameter 1: filename - list of allowed editions
sub load_editions {
my $filename=shift;
open P,"<$filename";
while (<P>) {
s/[\r\n]+//gm;
next if (/^#/); # Comment
next if (/^\s+$/); # Empty line
$eds{$_}=1;
}
close P;
}
# Check if the set/rarity of a card contains at least one allowed edition
# Parameter 1: set/rarity of a card (for example "Mirrodin common, Ninth Rare")
# Returns: True if at least one of the editions is allowed
sub allowed_edition {
my $ed=shift;
my @edl=split(/,\s+/,$ed);
foreach my $e (@edl) {
$e=~s/ (Mythic Rare|Rare|Uncommon|Common)$//;
if ($eds{$e}) {return 1;}
}
return 0;
}
# Return list of editions having this card
# Parameter 1: Name of card
# Returns: Array with all editions containing the card
sub edition_list {
my $ed=shift;
my @edl=split(/,\s+/,$ed);
my @out=();
foreach my $e (@edl) {
$e=~s/ (Mythic Rare|Rare|Uncommon|Common)$//;
push @out,$e;
}
return @out;
}
# Load list of cards and return them in an associative array
# Parameter 1: Name of file with card list
# Returns: List as associative array
sub load_list {
my $filename=shift;
my %lst=();
open P,"<$filename";
while (<P>) {
s/[\r\n]+//gm;
$lst{$_}=1;
}
close P;
return %lst;
}
# Return default configuration
sub default_config {
my %config=();
# Root of repository relative to directory with tools
$config{'root'}='../';
# File with card data
$config{'cardfile'}=$config{'root'}.'resources/magic/data/cards.txt';
# File with images (cards, HQ cards and others)
$config{'imagefile'}=$config{'root'}.'resources/magic/data/images.txt';
# List of all cards from gatherer, in text spoiler format. Available from url:
# http://gatherer.wizards.com/Pages/Search/Default.aspx?output=spoiler&method=text&action=advanced&type=%7c%5b%22Creature%22%5d%7c%5b%22Artifact%22%5d%7c%5b%22Land%22%5d%7c%5b%22Instant%22%5d%7c%5b%22Legendary%22%5d%7c%5b%22Basic%22%5d%7c%5b%22Enchantment%22%5d%7c%5b%22Ongoing%22%5d%7c%5b%22Plane%22%5d%7c%5b%22Planeswalker%22%5d%7c%5b%22Scheme%22%5d%7c%5b%22Snow%22%5d%7c%5b%22Sorcery%22%5d%7c%5b%22Tribal%22%5d%7c%5b%22Vanguard%22%5d%7c%5b%22World%22%5d
$config{'cardhtml'}='lists/mtg_all_list.html';
# List of cards from magiccards.info. There is no way to get all cards as single list,
# so this list have to be created by several requests (all common creatures, all uncommon creatures, etc ...) and then concatenating results together
# http://magiccards.info
$config{'hqhtml'}='lists/hq_creatures.html';
# Data for automatic cube generation
$config{'cubegen_data'}='cube_gen.txt';
# Card edition contents
$config{'edition_contents'}='_editions_contents.txt';
# File with list of names of implemented cards
$config{'cardlist'}='_cardlist.txt';
return %config;
}
# Normalize card type and possibly fills up subtype
# Parameter 1: Reference to hash wuith card data to modify
sub normalize_type {
my ($k)=@_;
my $type=$k->{'Type'};
$type=~s/Legendary Creature/Legendary,Creature/;
$type=~s/Artifact Creature/Artifact,Creature/;
my $subtype='';
if ($type=~/^(.+) — (.+)$/) {
$type=$1;
$subtype=$2;
$k->{'Subtype'}=$subtype;
}
$k->{'Type'}=$type;
}
# Return spell color based on its mana cost
# Parameter 1: Spell mana cost
# Returns: spell color
sub spell_color {
my $cost=shift;
my $c_color='';
if ($cost=~/R/) {$c_color.='r';}
if ($cost=~/G/) {$c_color.='g';}
if ($cost=~/B/) {$c_color.='b';}
if ($cost=~/U/) {$c_color.='u';}
if ($cost=~/W/) {$c_color.='w';}
return $c_color;
}
# Normalize rule text. Mostly remove explanatory comments from it.
# Parameter 1: rule text
# Parameter 2: card name
# Returns: normalized text
sub normalize_ruletext {
my $txt=shift;
my $name=shift;
$txt=~s/Protection from ([a-z]+) and from ([a-z]+)/Protection from $1, Protection from $2/i;
$txt=~s/\(\{\(.\/.\)\} can be paid with either \{.\} or \{.\}\.\)//i;
$txt=~s/Defender, flying \(This creature can't attack, and it can block creatures with flying.\)/Defender, flying/i;
$txt=~s/Intimidate \(This creature can't be blocked except by artifact creatures and\/or creatures that share a color with it.\)/Intimidate/i;
$txt=~s/$name attacks each turn if able\./attacks each turn if able/i;
$txt=~s/$name can't be countered\./can't be countered/i;
$txt=~s/$name can't be blocked except by creatures with flying\./can't be blocked except by creatures with flying/i;
$txt=~s/$name is indestructible\.( \((Lethal damage and effects that say "destroy" don't destroy it. If its toughness is 0 or less, it's still put into its owner's graveyard|"Destroy" effects and lethal damage don't destroy it|Effects that say "destroy" don't destroy it).\))?/indestructible/i;
$txt=~s/$name can't block\./can't block/i;
$txt=~s/$name can't attack or block\./can't attack or block/i;
$txt=~s/$name can block only creatures with flying\./can't block creatures without flying/i;
$txt=~s/$name is unblockable\./unblockable/i;
$txt=~s/Fear \(This creature can't be blocked except by artifact creatures and\/or black creatures.\)/Fear/i;
$txt=~s/First strike \(This creature deals combat damage before creatures without first strike.\)/First strike/i;
$txt=~s/Defender \(This creature can't attack.\)/Defender/;
$txt=~s/Banding \(Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.\)/Banding/i;
$txt=~s/Shadow \(This creature can block or be blocked by only creatures with shadow.\)/Shadow/i;
$txt=~s/Double strike \(This creature deals both first-strike and regular combat damage.\)/Double strike/i;
$txt=~s/Vigilance \(Attacking doesn't cause this creature to tap.\)/Vigilance/i;
$txt=~s/Whenever $name deals damage, you gain that much life./Lifelink/i;
$txt=~s/Deathtouch \(Creatures dealt damage by this creature are destroyed. You can divide this creature's combat damage among any of the creatures blocking or blocked by it\.\)/Deathtouch/i;
$txt=~s/Flash \(You may cast this spell any time you could cast an instant.\)/Flash/i;
$txt=~s/Flying \(This creature can't be blocked except by creatures with flying or reach.\)/Flying/i;
$txt=~s/Persist \(When this creature is put into a graveyard from the battlefield, if it had no -1\/-1 counters on it, return it to the battlefield under its owner's control with a -1\/-1 counter on it.\)/Persist/i;
$txt=~s/Shroud \(This (creature|permanent) can't be the target of spells or abilities.\)/Shroud/i;
$txt=~s/Lifelink \(Damage dealt by this creature also causes you to gain that much life.\)/Lifelink/i;
$txt=~s/Changeling \(This card is every creature type at all times.\)/Changeling/i;
$txt=~s/Exalted \(Whenever a creature you control attacks alone, that creature gets \+1\/\+1 until end of turn.\)/Exalted/i;
$txt=~s/Trample \(If this creature would (deal|assign) enough damage to its blockers to destroy them, you may have it (deal|assign) the rest of its damage to defending player or planeswalker.\)/Trample/i;
$txt=~s/Haste \(This creature can attack and \{T\} as soon as it comes under your control.\)/Haste/i;
$txt=~s/Haste \(This creature can attack the turn it comes under your control.\)/Haste/i;
$txt=~s/reach \(This (creature )?can block creatures with flying.\)/Reach/i;
$txt=~s/Flanking \(Whenever a creature without flanking blocks this creature, the blocking creature gets -1\/-1 until end of turn.\)/Flanking/i;
$txt=~s/Wither \(This deals damage to creatures in the form of -1\/-1 counters.\)/Wither/i;
$txt=~s/Deathtouch \(Any amount of damage this deals to a creature is enough to destroy it\.\)/Deathtouch/i;
$txt=~s/(Swamp|Forest|Island|Plains|Mountain)walk \(This creature is unblockable as long as defending player controls an? \1.\)/${1}walk/i;
$txt=~s/^<br \/>//i;
return $txt;
}
1