merged limited to trunk
commit
2114cb3980
46
build.xml
46
build.xml
|
@ -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>
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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.
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
<<a href="http://fsf.org/">http://fsf.org/</a>></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> <one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
</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> <program> Copyright (C) <year> <name of author>
|
||||
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
|
||||
<<a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>>.</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
|
||||
<<a href="http://www.gnu.org/philosophy/why-not-lgpl.html">http://www.gnu.org/philosophy/why-not-lgpl.html</a>>.</p>
|
||||
|
||||
</body></html>
|
|
@ -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
|
|
@ -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 |
|
@ -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
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
|
@ -41,7 +41,7 @@ public class CubeDefinitions {
|
|||
cubeDefinitions.add(new MagicCubeDefinition(cubeName));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String[] getCubeNames() {
|
||||
|
||||
final String names[]=new String[cubeDefinitions.size()];
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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});
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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()) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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";}
|
||||
}
|
|
@ -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";
|
|
@ -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;
|
|
@ -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:Lion’s Eye Diamond
|
||||
restrict:Lotus Petal
|
||||
restrict:Mana Crypt
|
||||
restrict:Mana Vault
|
||||
restrict:Memory Jar
|
||||
restrict:Merchant Scroll
|
||||
restrict:Mind’s 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:Yawgmoth’s Bargain
|
||||
restrict:Yawgmoth’s 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]
|
||||
*
|
|
@ -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
|
173
tools/mutils.pm
173
tools/mutils.pm
|
@ -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
|
Loading…
Reference in New Issue