From 01f5e65b3dd0c78fa3aa2de7fd8427f4adb0c6cd Mon Sep 17 00:00:00 2001 From: mkalender Date: Fri, 19 Jun 2015 10:18:38 -0400 Subject: [PATCH 01/16] placeholder for new card --- .../src/mage/sets/invasion/TeferisMoat.java | 54 ++++++++++++++++++ .../mage/sets/timeshifted/TeferisMoat.java | 57 +++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/invasion/TeferisMoat.java create mode 100644 Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java diff --git a/Mage.Sets/src/mage/sets/invasion/TeferisMoat.java b/Mage.Sets/src/mage/sets/invasion/TeferisMoat.java new file mode 100644 index 0000000000..7d9047a2e5 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/TeferisMoat.java @@ -0,0 +1,54 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.invasion; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author anonymous + */ +public class TeferisMoat extends mage.sets.timeshifted.TeferisMoat { + + public TeferisMoat(UUID ownerId) { + super(ownerId); + this.cardNumber = 279; + this.expansionSetCode = "INV"; + this.rarity = Rarity.RARE; + } + + public TeferisMoat(final TeferisMoat card) { + super(card); + } + + @Override + public TeferisMoat copy() { + return new TeferisMoat(this); + } +} diff --git a/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java b/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java new file mode 100644 index 0000000000..b91d4f147e --- /dev/null +++ b/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java @@ -0,0 +1,57 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.timeshifted; + +import java.util.UUID; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author anonymous + */ +public class TeferisMoat extends CardImpl { + + public TeferisMoat(UUID ownerId) { + super(ownerId, 103, "Teferi's Moat", Rarity.SPECIAL, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}{U}"); + this.expansionSetCode = "TSB"; + + // As Teferi's Moat enters the battlefield, choose a color. + // Creatures of the chosen color without flying can't attack you. + } + + public TeferisMoat(final TeferisMoat card) { + super(card); + } + + @Override + public TeferisMoat copy() { + return new TeferisMoat(this); + } +} From 15800987c3619b3442e3f450dc7a7be265fdcf25 Mon Sep 17 00:00:00 2001 From: mkalender Date: Fri, 19 Jun 2015 12:07:33 -0400 Subject: [PATCH 02/16] 1st attempt at implementing new card Teferi's Moat --- .../mage/sets/timeshifted/TeferisMoat.java | 41 ++++++++++++++++++- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java b/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java index b91d4f147e..7a9177e9b7 100644 --- a/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java +++ b/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java @@ -28,22 +28,37 @@ package mage.sets.timeshifted; import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.RestrictionEffect; +import mage.abilities.effects.common.ChooseColorEffect; +import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; + /** * - * @author anonymous + * @author Markedagain */ public class TeferisMoat extends CardImpl { public TeferisMoat(UUID ownerId) { super(ownerId, 103, "Teferi's Moat", Rarity.SPECIAL, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}{U}"); this.expansionSetCode = "TSB"; - + // As Teferi's Moat enters the battlefield, choose a color. + this.addAbility(new EntersBattlefieldAbility(new ChooseColorEffect(Outcome.Neutral))); // Creatures of the chosen color without flying can't attack you. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new TeferisMoatRestrictionEffect())); } public TeferisMoat(final TeferisMoat card) { @@ -55,3 +70,25 @@ public class TeferisMoat extends CardImpl { return new TeferisMoat(this); } } + +class TeferisMoatRestrictionEffect extends RestrictionEffect { + + TeferisMoatRestrictionEffect(){ + super(Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "Creatures of the chosen color without flying can't attack you"; + } + TeferisMoatRestrictionEffect(final TeferisMoatRestrictionEffect effect) { + super(effect); + } + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + ObjectColor chosenColor = (ObjectColor) game.getState().getValue(source.getSourceId() + "_color"); + if (chosenColor == null) + return false; + return permanent.getCardType().contains(CardType.CREATURE) && !permanent.getAbilities().contains(FlyingAbility.getInstance()) && !permanent.getColor(game).shares(chosenColor); + } + @Override + public TeferisMoatRestrictionEffect copy() { + return new TeferisMoatRestrictionEffect(this); + } +} \ No newline at end of file From bfc4d2592a3d8c597f97ea7e3266dcd40c96d6b6 Mon Sep 17 00:00:00 2001 From: mkalender Date: Fri, 19 Jun 2015 13:00:36 -0400 Subject: [PATCH 03/16] commiting to work on home, so far when enchantment goes into battlefiled other creatures are not allowed to attack regardless of color choice --- Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java b/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java index 7a9177e9b7..26e69265d3 100644 --- a/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java +++ b/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java @@ -77,17 +77,25 @@ class TeferisMoatRestrictionEffect extends RestrictionEffect { super(Duration.WhileOnBattlefield, Outcome.Benefit); staticText = "Creatures of the chosen color without flying can't attack you"; } + TeferisMoatRestrictionEffect(final TeferisMoatRestrictionEffect effect) { super(effect); } - @Override + + @Override public boolean applies(Permanent permanent, Ability source, Game game) { ObjectColor chosenColor = (ObjectColor) game.getState().getValue(source.getSourceId() + "_color"); if (chosenColor == null) return false; return permanent.getCardType().contains(CardType.CREATURE) && !permanent.getAbilities().contains(FlyingAbility.getInstance()) && !permanent.getColor(game).shares(chosenColor); } - @Override + + @Override + public boolean canAttack(UUID defenderId, Ability source, Game game) { + return !defenderId.equals(source.getControllerId()); + } + + @Override public TeferisMoatRestrictionEffect copy() { return new TeferisMoatRestrictionEffect(this); } From 8685c676796d1bdfeb930ba3ec9a2677b28b4083 Mon Sep 17 00:00:00 2001 From: brodee Date: Sun, 21 Jun 2015 18:52:43 -0700 Subject: [PATCH 04/16] Update readme.md --- readme.md | 36 ++---------------------------------- 1 file changed, 2 insertions(+), 34 deletions(-) diff --git a/readme.md b/readme.md index a7ee59046a..3ffe232abc 100644 --- a/readme.md +++ b/readme.md @@ -1,35 +1,3 @@ -# XMage - Magic, Another Game Engine +Fork of xmage for chaos cube implementation. -XMage allows you to play Magic against one or more online players or computer opponents. It includes full rules enforcement for over **10,000** unique cards (nearly 20,000 counting all cards from different editions). Starting with Eventide, all regular sets have nearly all the cards implemented ([detailed overview](http://ct-magefree.rhcloud.com/stats)). - -There are public servers where you can play XMage against other players. You can also host your own server to play against the AI and/or your friends. - -You can visit the XMage forum [here](http://www.slightlymagic.net/forum/viewforum.php?f=70). - -## Features -* Deck editor to build your desired decks. -* There is a simple computer AI opponent available. -* You can play either a two player duel or a multiplayer free-for-all game with up to 10 players. -* Commander format (also up to 10 players). -* Tiny Leaders duels. -* There are two tournament types supported, which can be played with up to 16 players: -* Elimination or swiss type handling -* Booster (also Cube) draft tournaments (4-16) -* Sealed (also from Cube) tournaments (2-16) - -## Installation -Download and install the [latest XMage release](http://XMage.de). -You will need to have the [Java Runtime Environment](http://java.com/en/) Version 7 or later. - -Look [here](http://www.slightlymagic.net/forum/viewtopic.php?f=70&t=13632) for more detailed instructions. -[Here](http://github.com/magefree/mage/wiki/Release-changes) you can find a log of the latest changes. - -## Developer - -If you are interested in developing XMage, here are some useful resources: -* [Developer Getting Started](http://github.com/magefree/mage/wiki/Developer-Getting-Started) -* [Developer Notes](http://github.com/magefree/mage/wiki/Developer-Notes) -* [Developer Testing Tools](http://github.com/magefree/mage/wiki/Developer-Testing-Tools) -* [Double Faced Cards](http://github.com/magefree/mage/wiki/Double-Faced-Cards) -* [Card Requests](http://www.slightlymagic.net/forum/viewtopic.php?f=70&t=4554) -* [Tournament Relevant Card Requests](http://www.slightlymagic.net/forum/viewtopic.php?f=70&t=14062) \ No newline at end of file +a chaos booster draft is one where a pack pool is created with random packs and randomly distributed. you draft with those. Typically you use 24 different sets, so the decks are super weird. From 35241d7805651b69b9fe0b11763911c3cb083582 Mon Sep 17 00:00:00 2001 From: LoneFox Date: Mon, 22 Jun 2015 08:02:59 +0300 Subject: [PATCH 05/16] Implement cards: Ashnod's Transmogrant, Mountain Yeti, Sea Drake, and Unstable Mutation --- .../sets/antiquities/AshnodsTransmogrant.java | 55 ++++++++++++ .../sets/arabiannights/UnstableMutation.java | 81 ++++++++++++++++++ .../fifthedition/AshnodsTransmogrant.java | 84 +++++++++++++++++++ .../sets/fifthedition/UnstableMutation.java | 53 ++++++++++++ .../sets/fourthedition/UnstableMutation.java | 53 ++++++++++++ .../src/mage/sets/legends/MountainYeti.java | 75 +++++++++++++++++ .../mastersedition/AshnodsTransmogrant.java | 53 ++++++++++++ .../sets/mastersedition/MountainYeti.java | 55 ++++++++++++ .../mage/sets/masterseditionii/SeaDrake.java | 80 ++++++++++++++++++ .../mage/sets/portalsecondage/SeaDrake.java | 55 ++++++++++++ .../sets/revisededition/UnstableMutation.java | 53 ++++++++++++ .../sets/timeshifted/UnstableMutation.java | 55 ++++++++++++ .../mage/sets/vintagemasters/SeaDrake.java | 53 ++++++++++++ 13 files changed, 805 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/antiquities/AshnodsTransmogrant.java create mode 100644 Mage.Sets/src/mage/sets/arabiannights/UnstableMutation.java create mode 100644 Mage.Sets/src/mage/sets/fifthedition/AshnodsTransmogrant.java create mode 100644 Mage.Sets/src/mage/sets/fifthedition/UnstableMutation.java create mode 100644 Mage.Sets/src/mage/sets/fourthedition/UnstableMutation.java create mode 100644 Mage.Sets/src/mage/sets/legends/MountainYeti.java create mode 100644 Mage.Sets/src/mage/sets/mastersedition/AshnodsTransmogrant.java create mode 100644 Mage.Sets/src/mage/sets/mastersedition/MountainYeti.java create mode 100644 Mage.Sets/src/mage/sets/masterseditionii/SeaDrake.java create mode 100644 Mage.Sets/src/mage/sets/portalsecondage/SeaDrake.java create mode 100644 Mage.Sets/src/mage/sets/revisededition/UnstableMutation.java create mode 100644 Mage.Sets/src/mage/sets/timeshifted/UnstableMutation.java create mode 100644 Mage.Sets/src/mage/sets/vintagemasters/SeaDrake.java diff --git a/Mage.Sets/src/mage/sets/antiquities/AshnodsTransmogrant.java b/Mage.Sets/src/mage/sets/antiquities/AshnodsTransmogrant.java new file mode 100644 index 0000000000..697fba14be --- /dev/null +++ b/Mage.Sets/src/mage/sets/antiquities/AshnodsTransmogrant.java @@ -0,0 +1,55 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.antiquities; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author LoneFox + + */ +public class AshnodsTransmogrant extends mage.sets.fifthedition.AshnodsTransmogrant { + + public AshnodsTransmogrant(UUID ownerId) { + super(ownerId); + this.cardNumber = 5; + this.expansionSetCode = "ATQ"; + this.rarity = Rarity.UNCOMMON; + } + + public AshnodsTransmogrant(final AshnodsTransmogrant card) { + super(card); + } + + @Override + public AshnodsTransmogrant copy() { + return new AshnodsTransmogrant(this); + } +} diff --git a/Mage.Sets/src/mage/sets/arabiannights/UnstableMutation.java b/Mage.Sets/src/mage/sets/arabiannights/UnstableMutation.java new file mode 100644 index 0000000000..aa36417fe6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/arabiannights/UnstableMutation.java @@ -0,0 +1,81 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.arabiannights; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.counter.AddCountersAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + + */ +public class UnstableMutation extends CardImpl { + + public UnstableMutation(UUID ownerId) { + super(ownerId, 28, "Unstable Mutation", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{U}"); + this.expansionSetCode = "ARN"; + this.subtype.add("Aura"); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // Enchanted creature gets +3/+3. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3, 3))); + // At the beginning of the upkeep of enchanted creature's controller, put a -1/-1 counter on that creature. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new AddCountersAttachedEffect(CounterType.M1M1.createInstance(), "that creature"), + TargetController.CONTROLLER_ATTACHED_TO, false)); + } + + public UnstableMutation(final UnstableMutation card) { + super(card); + } + + @Override + public UnstableMutation copy() { + return new UnstableMutation(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fifthedition/AshnodsTransmogrant.java b/Mage.Sets/src/mage/sets/fifthedition/AshnodsTransmogrant.java new file mode 100644 index 0000000000..458a67e1bc --- /dev/null +++ b/Mage.Sets/src/mage/sets/fifthedition/AshnodsTransmogrant.java @@ -0,0 +1,84 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.fifthedition; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.AddCardTypeTargetEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + + */ +public class AshnodsTransmogrant extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonartifact creature"); + + static { + filter.add(Predicates.not(new CardTypePredicate(CardType.ARTIFACT))); + } + + public AshnodsTransmogrant(UUID ownerId) { + super(ownerId, 350, "Ashnod's Transmogrant", Rarity.COMMON, new CardType[]{CardType.ARTIFACT}, "{1}"); + this.expansionSetCode = "5ED"; + + // {T}, Sacrifice Ashnod's Transmogrant: Put a +1/+1 counter on target nonartifact creature. That creature becomes an artifact in addition to its other types. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + Effect effect = new AddCardTypeTargetEffect(CardType.ARTIFACT, Duration.WhileOnBattlefield); + effect.setText("That creature becomes an artifact in addition to its other types"); + ability.addEffect(effect); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + } + + public AshnodsTransmogrant(final AshnodsTransmogrant card) { + super(card); + } + + @Override + public AshnodsTransmogrant copy() { + return new AshnodsTransmogrant(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fifthedition/UnstableMutation.java b/Mage.Sets/src/mage/sets/fifthedition/UnstableMutation.java new file mode 100644 index 0000000000..6c050c6433 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fifthedition/UnstableMutation.java @@ -0,0 +1,53 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.fifthedition; + +import java.util.UUID; + +/** + * + * @author LoneFox + + */ +public class UnstableMutation extends mage.sets.arabiannights.UnstableMutation { + + public UnstableMutation(UUID ownerId) { + super(ownerId); + this.cardNumber = 131; + this.expansionSetCode = "5ED"; + } + + public UnstableMutation(final UnstableMutation card) { + super(card); + } + + @Override + public UnstableMutation copy() { + return new UnstableMutation(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fourthedition/UnstableMutation.java b/Mage.Sets/src/mage/sets/fourthedition/UnstableMutation.java new file mode 100644 index 0000000000..fa1406f5f8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fourthedition/UnstableMutation.java @@ -0,0 +1,53 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.fourthedition; + +import java.util.UUID; + +/** + * + * @author LoneFox + + */ +public class UnstableMutation extends mage.sets.arabiannights.UnstableMutation { + + public UnstableMutation(UUID ownerId) { + super(ownerId); + this.cardNumber = 110; + this.expansionSetCode = "4ED"; + } + + public UnstableMutation(final UnstableMutation card) { + super(card); + } + + @Override + public UnstableMutation copy() { + return new UnstableMutation(this); + } +} diff --git a/Mage.Sets/src/mage/sets/legends/MountainYeti.java b/Mage.Sets/src/mage/sets/legends/MountainYeti.java new file mode 100644 index 0000000000..3ab9be2476 --- /dev/null +++ b/Mage.Sets/src/mage/sets/legends/MountainYeti.java @@ -0,0 +1,75 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.legends; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.keyword.MountainwalkAbility; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author LoneFox + + */ +public class MountainYeti extends CardImpl { + + private static final FilterCard filter = new FilterCard("White"); + + static { + filter.add(new ColorPredicate(ObjectColor.WHITE)); + } + + public MountainYeti(UUID ownerId) { + super(ownerId, 156, "Mountain Yeti", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); + this.expansionSetCode = "LEG"; + this.subtype.add("Yeti"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Mountainwalk + this.addAbility(new MountainwalkAbility()); + // protection from white + this.addAbility(new ProtectionAbility(filter)); + } + + public MountainYeti(final MountainYeti card) { + super(card); + } + + @Override + public MountainYeti copy() { + return new MountainYeti(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mastersedition/AshnodsTransmogrant.java b/Mage.Sets/src/mage/sets/mastersedition/AshnodsTransmogrant.java new file mode 100644 index 0000000000..c3c23f16fe --- /dev/null +++ b/Mage.Sets/src/mage/sets/mastersedition/AshnodsTransmogrant.java @@ -0,0 +1,53 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.mastersedition; + +import java.util.UUID; + +/** + * + * @author LoneFox + + */ +public class AshnodsTransmogrant extends mage.sets.fifthedition.AshnodsTransmogrant { + + public AshnodsTransmogrant(UUID ownerId) { + super(ownerId); + this.cardNumber = 152; + this.expansionSetCode = "MED"; + } + + public AshnodsTransmogrant(final AshnodsTransmogrant card) { + super(card); + } + + @Override + public AshnodsTransmogrant copy() { + return new AshnodsTransmogrant(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mastersedition/MountainYeti.java b/Mage.Sets/src/mage/sets/mastersedition/MountainYeti.java new file mode 100644 index 0000000000..776066c87f --- /dev/null +++ b/Mage.Sets/src/mage/sets/mastersedition/MountainYeti.java @@ -0,0 +1,55 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.mastersedition; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author LoneFox + + */ +public class MountainYeti extends mage.sets.legends.MountainYeti { + + public MountainYeti(UUID ownerId) { + super(ownerId); + this.cardNumber = 105; + this.expansionSetCode = "MED"; + this.rarity = Rarity.COMMON; + } + + public MountainYeti(final MountainYeti card) { + super(card); + } + + @Override + public MountainYeti copy() { + return new MountainYeti(this); + } +} diff --git a/Mage.Sets/src/mage/sets/masterseditionii/SeaDrake.java b/Mage.Sets/src/mage/sets/masterseditionii/SeaDrake.java new file mode 100644 index 0000000000..197e904597 --- /dev/null +++ b/Mage.Sets/src/mage/sets/masterseditionii/SeaDrake.java @@ -0,0 +1,80 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.masterseditionii; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.common.TargetLandPermanent; + +/** + * + * @author LoneFox + + */ +public class SeaDrake extends CardImpl { + + private static final FilterLandPermanent filter = new FilterLandPermanent("land you control"); + + static { + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public SeaDrake(UUID ownerId) { + super(ownerId, 64, "Sea Drake", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{U}"); + this.expansionSetCode = "ME2"; + this.subtype.add("Drake"); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // When Sea Drake enters the battlefield, return two target lands you control to their owner's hand. + Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(), false); + ability.addTarget(new TargetLandPermanent(2, 2, filter, false)); + this.addAbility(ability); + } + + public SeaDrake(final SeaDrake card) { + super(card); + } + + @Override + public SeaDrake copy() { + return new SeaDrake(this); + } +} diff --git a/Mage.Sets/src/mage/sets/portalsecondage/SeaDrake.java b/Mage.Sets/src/mage/sets/portalsecondage/SeaDrake.java new file mode 100644 index 0000000000..dcb6ce9399 --- /dev/null +++ b/Mage.Sets/src/mage/sets/portalsecondage/SeaDrake.java @@ -0,0 +1,55 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.portalsecondage; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author LoneFox + + */ +public class SeaDrake extends mage.sets.masterseditionii.SeaDrake { + + public SeaDrake(UUID ownerId) { + super(ownerId); + this.cardNumber = 45; + this.expansionSetCode = "PO2"; + this.rarity = Rarity.UNCOMMON; + } + + public SeaDrake(final SeaDrake card) { + super(card); + } + + @Override + public SeaDrake copy() { + return new SeaDrake(this); + } +} diff --git a/Mage.Sets/src/mage/sets/revisededition/UnstableMutation.java b/Mage.Sets/src/mage/sets/revisededition/UnstableMutation.java new file mode 100644 index 0000000000..4a34fc5347 --- /dev/null +++ b/Mage.Sets/src/mage/sets/revisededition/UnstableMutation.java @@ -0,0 +1,53 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.revisededition; + +import java.util.UUID; + +/** + * + * @author LoneFox + + */ +public class UnstableMutation extends mage.sets.arabiannights.UnstableMutation { + + public UnstableMutation(UUID ownerId) { + super(ownerId); + this.cardNumber = 86; + this.expansionSetCode = "3ED"; + } + + public UnstableMutation(final UnstableMutation card) { + super(card); + } + + @Override + public UnstableMutation copy() { + return new UnstableMutation(this); + } +} diff --git a/Mage.Sets/src/mage/sets/timeshifted/UnstableMutation.java b/Mage.Sets/src/mage/sets/timeshifted/UnstableMutation.java new file mode 100644 index 0000000000..c1a2b09f3f --- /dev/null +++ b/Mage.Sets/src/mage/sets/timeshifted/UnstableMutation.java @@ -0,0 +1,55 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.timeshifted; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author LoneFox + + */ +public class UnstableMutation extends mage.sets.arabiannights.UnstableMutation { + + public UnstableMutation(UUID ownerId) { + super(ownerId); + this.cardNumber = 33; + this.expansionSetCode = "TSB"; + this.rarity = Rarity.SPECIAL; + } + + public UnstableMutation(final UnstableMutation card) { + super(card); + } + + @Override + public UnstableMutation copy() { + return new UnstableMutation(this); + } +} diff --git a/Mage.Sets/src/mage/sets/vintagemasters/SeaDrake.java b/Mage.Sets/src/mage/sets/vintagemasters/SeaDrake.java new file mode 100644 index 0000000000..ed188e40ea --- /dev/null +++ b/Mage.Sets/src/mage/sets/vintagemasters/SeaDrake.java @@ -0,0 +1,53 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.vintagemasters; + +import java.util.UUID; + +/** + * + * @author LoneFox + + */ +public class SeaDrake extends mage.sets.masterseditionii.SeaDrake { + + public SeaDrake(UUID ownerId) { + super(ownerId); + this.cardNumber = 92; + this.expansionSetCode = "VMA"; + } + + public SeaDrake(final SeaDrake card) { + super(card); + } + + @Override + public SeaDrake copy() { + return new SeaDrake(this); + } +} From 6ea6cc66566177ea0d25f8aa5c19e5c9d9f67c44 Mon Sep 17 00:00:00 2001 From: LoneFox Date: Mon, 22 Jun 2015 20:08:31 +0300 Subject: [PATCH 06/16] Implement cards: Opal Archangel, Opal Caryatid, Opal Champion, Opal Gargoyle, and Opal Guardian --- .../mage/sets/timespiral/OpalGuardian.java | 95 +++++++++++++++++++ .../mage/sets/urzaslegacy/OpalChampion.java | 84 ++++++++++++++++ .../mage/sets/urzassaga/OpalArchangel.java | 86 +++++++++++++++++ .../src/mage/sets/urzassaga/OpalCaryatid.java | 82 ++++++++++++++++ .../src/mage/sets/urzassaga/OpalGargoyle.java | 84 ++++++++++++++++ .../common/SourceMatchesFilterCondition.java | 6 +- .../BecomesCreatureSourceEffect.java | 24 +++-- 7 files changed, 451 insertions(+), 10 deletions(-) create mode 100644 Mage.Sets/src/mage/sets/timespiral/OpalGuardian.java create mode 100644 Mage.Sets/src/mage/sets/urzaslegacy/OpalChampion.java create mode 100644 Mage.Sets/src/mage/sets/urzassaga/OpalArchangel.java create mode 100644 Mage.Sets/src/mage/sets/urzassaga/OpalCaryatid.java create mode 100644 Mage.Sets/src/mage/sets/urzassaga/OpalGargoyle.java diff --git a/Mage.Sets/src/mage/sets/timespiral/OpalGuardian.java b/Mage.Sets/src/mage/sets/timespiral/OpalGuardian.java new file mode 100644 index 0000000000..04e6861f17 --- /dev/null +++ b/Mage.Sets/src/mage/sets/timespiral/OpalGuardian.java @@ -0,0 +1,95 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.timespiral; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.filter.FilterCard; +import mage.filter.common.FilterCreatureSpell; +import mage.filter.common.FilterEnchantmentPermanent; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.game.permanent.token.Token; + +/** + * + * @author LoneFox + + */ +public class OpalGuardian extends CardImpl { + + public OpalGuardian(UUID ownerId) { + super(ownerId, 30, "Opal Guardian", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{W}{W}{W}"); + this.expansionSetCode = "TSP"; + + // When an opponent casts a creature spell, if Opal Guardian is an enchantment, Opal Guardian becomes a 3/4 Gargoyle creature with flying and protection from red. + TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect(new OpalGuardianGargoyle(), "", Duration.WhileOnBattlefield, true), + new FilterCreatureSpell(), false); + this.addAbility(new ConditionalTriggeredAbility(ability, new SourceMatchesFilterCondition(new FilterEnchantmentPermanent()), + "When an opponent casts a creature spell, if {this} is an enchantment, {this} becomes a 3/4 Gargoyle creature with flying and protection from red.")); + } + + public OpalGuardian(final OpalGuardian card) { + super(card); + } + + @Override + public OpalGuardian copy() { + return new OpalGuardian(this); + } +} + +class OpalGuardianGargoyle extends Token { + + private static final FilterCard filter = new FilterCard("red"); + + static { + filter.add(new ColorPredicate(ObjectColor.RED)); + } + + public OpalGuardianGargoyle() { + super("Gargoyle", "a 3/4 Gargoyle creature with flying and protection from red"); + cardType.add(CardType.CREATURE); + subtype.add("Knight"); + power = new MageInt(3); + toughness = new MageInt(4); + this.addAbility(FlyingAbility.getInstance()); + this.addAbility(new ProtectionAbility(filter)); + } +} diff --git a/Mage.Sets/src/mage/sets/urzaslegacy/OpalChampion.java b/Mage.Sets/src/mage/sets/urzaslegacy/OpalChampion.java new file mode 100644 index 0000000000..a0975dbf76 --- /dev/null +++ b/Mage.Sets/src/mage/sets/urzaslegacy/OpalChampion.java @@ -0,0 +1,84 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.urzaslegacy; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.filter.common.FilterCreatureSpell; +import mage.filter.common.FilterEnchantmentPermanent; +import mage.game.permanent.token.Token; + +/** + * + * @author LoneFox + + */ +public class OpalChampion extends CardImpl { + + public OpalChampion(UUID ownerId) { + super(ownerId, 16, "Opal Champion", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); + this.expansionSetCode = "ULG"; + + // When an opponent casts a creature spell, if Opal Champion is an enchantment, Opal Champion becomes a 3/3 Knight creature with first strike. + TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect(new OpalChampionKnight(), "", Duration.WhileOnBattlefield, true), + new FilterCreatureSpell(), false); + this.addAbility(new ConditionalTriggeredAbility(ability, new SourceMatchesFilterCondition(new FilterEnchantmentPermanent()), + "When an opponent casts a creature spell, if {this} is an enchantment, {this} becomes a 3/3 Knight creature with first strike.")); + } + + public OpalChampion(final OpalChampion card) { + super(card); + } + + @Override + public OpalChampion copy() { + return new OpalChampion(this); + } +} + +class OpalChampionKnight extends Token { + + public OpalChampionKnight() { + super("Knight", "a 3/3 Knight creature with first strike"); + cardType.add(CardType.CREATURE); + subtype.add("Knight"); + power = new MageInt(3); + toughness = new MageInt(3); + this.addAbility(FirstStrikeAbility.getInstance()); + } +} diff --git a/Mage.Sets/src/mage/sets/urzassaga/OpalArchangel.java b/Mage.Sets/src/mage/sets/urzassaga/OpalArchangel.java new file mode 100644 index 0000000000..274081c672 --- /dev/null +++ b/Mage.Sets/src/mage/sets/urzassaga/OpalArchangel.java @@ -0,0 +1,86 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.urzassaga; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.filter.common.FilterCreatureSpell; +import mage.filter.common.FilterEnchantmentPermanent; +import mage.game.permanent.token.Token; + +/** + * + * @author LoneFox + + */ +public class OpalArchangel extends CardImpl { + + public OpalArchangel(UUID ownerId) { + super(ownerId, 23, "Opal Archangel", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{4}{W}"); + this.expansionSetCode = "USG"; + + // When an opponent casts a creature spell, if Opal Archangel is an enchantment, Opal Archangel becomes a 5/5 Angel creature with flying and vigilance. + TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect(new OpalArchangelToken(), "", Duration.WhileOnBattlefield, true), + new FilterCreatureSpell(), false); + this.addAbility(new ConditionalTriggeredAbility(ability, new SourceMatchesFilterCondition(new FilterEnchantmentPermanent()), + "When an opponent casts a creature spell, if {this} is an enchantment, {this} becomes a 5/5 Angel creature with flying and vigilance.")); + } + + public OpalArchangel(final OpalArchangel card) { + super(card); + } + + @Override + public OpalArchangel copy() { + return new OpalArchangel(this); + } +} + +class OpalArchangelToken extends Token { + + public OpalArchangelToken() { + super("Angel", "a 3/3 Angelt creature with flying and vigilance"); + cardType.add(CardType.CREATURE); + subtype.add("Angel"); + power = new MageInt(5); + toughness = new MageInt(5); + this.addAbility(FlyingAbility.getInstance()); + this.addAbility(VigilanceAbility.getInstance()); + } +} diff --git a/Mage.Sets/src/mage/sets/urzassaga/OpalCaryatid.java b/Mage.Sets/src/mage/sets/urzassaga/OpalCaryatid.java new file mode 100644 index 0000000000..3981a15928 --- /dev/null +++ b/Mage.Sets/src/mage/sets/urzassaga/OpalCaryatid.java @@ -0,0 +1,82 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.urzassaga; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.filter.common.FilterCreatureSpell; +import mage.filter.common.FilterEnchantmentPermanent; +import mage.game.permanent.token.Token; + +/** + * + * @author LoneFox + + */ +public class OpalCaryatid extends CardImpl { + + public OpalCaryatid(UUID ownerId) { + super(ownerId, 24, "Opal Caryatid", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{W}"); + this.expansionSetCode = "USG"; + + // When an opponent casts a creature spell, if Opal Caryatid is an enchantment, Opal Caryatid becomes a 2/2 Soldier creature. + TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect(new OpalCaryatidSoldier(), "", Duration.WhileOnBattlefield, true), + new FilterCreatureSpell(), false); + this.addAbility(new ConditionalTriggeredAbility(ability, new SourceMatchesFilterCondition(new FilterEnchantmentPermanent()), + "When an opponent casts a creature spell, if {this} is an enchantment, {this} becomes a 2/2 Soldier creature.")); + } + + public OpalCaryatid(final OpalCaryatid card) { + super(card); + } + + @Override + public OpalCaryatid copy() { + return new OpalCaryatid(this); + } +} + +class OpalCaryatidSoldier extends Token { + + public OpalCaryatidSoldier() { + super("Soldier", "a 2/2 Soldier creature"); + cardType.add(CardType.CREATURE); + subtype.add("Soldier"); + power = new MageInt(2); + toughness = new MageInt(2); + } +} diff --git a/Mage.Sets/src/mage/sets/urzassaga/OpalGargoyle.java b/Mage.Sets/src/mage/sets/urzassaga/OpalGargoyle.java new file mode 100644 index 0000000000..be650e80db --- /dev/null +++ b/Mage.Sets/src/mage/sets/urzassaga/OpalGargoyle.java @@ -0,0 +1,84 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.urzassaga; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.filter.common.FilterCreatureSpell; +import mage.filter.common.FilterEnchantmentPermanent; +import mage.game.permanent.token.Token; + +/** + * + * @author LoneFox + + */ +public class OpalGargoyle extends CardImpl { + + public OpalGargoyle(UUID ownerId) { + super(ownerId, 25, "Opal Gargoyle", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); + this.expansionSetCode = "USG"; + + // When an opponent casts a creature spell, if Opal Gargoyle is an enchantment, Opal Gargoyle becomes a 2/2 Gargoyle creature with flying. + TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect(new OpalGargoyleToken(), "", Duration.WhileOnBattlefield, true), + new FilterCreatureSpell(), false); + this.addAbility(new ConditionalTriggeredAbility(ability, new SourceMatchesFilterCondition(new FilterEnchantmentPermanent()), + "When an opponent casts a creature spell, if {this} is an enchantment, {this} becomes a 2/2 Gargoyle creature with flying.")); + } + + public OpalGargoyle(final OpalGargoyle card) { + super(card); + } + + @Override + public OpalGargoyle copy() { + return new OpalGargoyle(this); + } +} + +class OpalGargoyleToken extends Token { + + public OpalGargoyleToken() { + super("Gargoyle", "a 2/2 Gargoyle creature with flying"); + cardType.add(CardType.CREATURE); + subtype.add("Knight"); + power = new MageInt(2); + toughness = new MageInt(2); + this.addAbility(FlyingAbility.getInstance()); + } +} diff --git a/Mage/src/mage/abilities/condition/common/SourceMatchesFilterCondition.java b/Mage/src/mage/abilities/condition/common/SourceMatchesFilterCondition.java index 7aeca178e7..8c2b39a8ad 100644 --- a/Mage/src/mage/abilities/condition/common/SourceMatchesFilterCondition.java +++ b/Mage/src/mage/abilities/condition/common/SourceMatchesFilterCondition.java @@ -29,7 +29,7 @@ package mage.abilities.condition.common; import mage.abilities.Ability; import mage.abilities.condition.Condition; -import mage.filter.common.FilterCreaturePermanent; +import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -41,9 +41,9 @@ import mage.game.permanent.Permanent; */ public class SourceMatchesFilterCondition implements Condition { - private FilterCreaturePermanent filter; + private FilterPermanent filter; - public SourceMatchesFilterCondition(FilterCreaturePermanent filter) { + public SourceMatchesFilterCondition(FilterPermanent filter) { this.filter = filter; } diff --git a/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureSourceEffect.java b/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureSourceEffect.java index 927f897446..37d0e41ac4 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/BecomesCreatureSourceEffect.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,7 +20,7 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. @@ -49,25 +49,32 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements protected Token token; protected String type; + protected boolean losePreviousTypes; - public BecomesCreatureSourceEffect(Token token, String type, Duration duration) { + public BecomesCreatureSourceEffect(Token token, String type, Duration duration, boolean losePreviousTypes) { super(duration, Outcome.BecomeCreature); this.token = token; this.type = type; + this.losePreviousTypes = losePreviousTypes; setText(); } + public BecomesCreatureSourceEffect(Token token, String type, Duration duration) { + this(token, type, duration, false); + } + public BecomesCreatureSourceEffect(final BecomesCreatureSourceEffect effect) { super(effect); this.token = effect.token.copy(); this.type = effect.type; + this.losePreviousTypes = effect.losePreviousTypes; } @Override public BecomesCreatureSourceEffect copy() { return new BecomesCreatureSourceEffect(this); } - + @Override public void init(Ability source, Game game) { super.init(source, game); @@ -88,6 +95,9 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl implements switch (layer) { case TypeChangingEffects_4: if (sublayer == SubLayer.NA) { + if (losePreviousTypes) { + permanent.getCardType().clear(); + } if (token.getCardType().size() > 0) { for (CardType t : token.getCardType()) { if (!permanent.getCardType().contains(t)) { From 73495db4bdec57230ee3fb7efb07935500f1d92b Mon Sep 17 00:00:00 2001 From: brodee Date: Mon, 22 Jun 2015 19:20:24 -0700 Subject: [PATCH 07/16] Update readme.md --- readme.md | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 3ffe232abc..7a6a9bb2f5 100644 --- a/readme.md +++ b/readme.md @@ -1,3 +1,35 @@ -Fork of xmage for chaos cube implementation. +# XMage - Magic, Another Game Engine -a chaos booster draft is one where a pack pool is created with random packs and randomly distributed. you draft with those. Typically you use 24 different sets, so the decks are super weird. +XMage allows you to play Magic against one or more online players or computer opponents. It includes full rules enforcement for over **10,000** unique cards (nearly 20,000 counting all cards from different editions). Starting with Eventide, all regular sets have nearly all the cards implemented ([detailed overview](http://ct-magefree.rhcloud.com/stats)). + +There are public servers where you can play XMage against other players. You can also host your own server to play against the AI and/or your friends. + +You can visit the XMage forum [here](http://www.slightlymagic.net/forum/viewforum.php?f=70). + +## Features +* Deck editor to build your desired decks. +* There is a simple computer AI opponent available. +* You can play either a two player duel or a multiplayer free-for-all game with up to 10 players. +* Commander format (also up to 10 players). +* Tiny Leaders duels. +* There are two tournament types supported, which can be played with up to 16 players: +* Elimination or swiss type handling +* Booster (also Cube) draft tournaments (4-16) +* Sealed (also from Cube) tournaments (2-16) + +## Installation +Download and install the [latest XMage release](http://XMage.de). +You will need to have the [Java Runtime Environment](http://java.com/en/) Version 7 or later. + +Look [here](http://www.slightlymagic.net/forum/viewtopic.php?f=70&t=13632) for more detailed instructions. +[Here](http://github.com/magefree/mage/wiki/Release-changes) you can find a log of the latest changes. + +## Developer + +If you are interested in developing XMage, here are some useful resources: +* [Developer Getting Started](http://github.com/magefree/mage/wiki/Developer-Getting-Started) +* [Developer Notes](http://github.com/magefree/mage/wiki/Developer-Notes) +* [Developer Testing Tools](http://github.com/magefree/mage/wiki/Developer-Testing-Tools) +* [Double Faced Cards](http://github.com/magefree/mage/wiki/Double-Faced-Cards) +* [Card Requests](http://www.slightlymagic.net/forum/viewtopic.php?f=70&t=4554) +* [Tournament Relevant Card Requests](http://www.slightlymagic.net/forum/viewtopic.php?f=70&t=14062) From e3b84eaab551e0eb00bbbc87977024942e5a1010 Mon Sep 17 00:00:00 2001 From: brodee <> Date: Mon, 22 Jun 2015 21:55:43 -0700 Subject: [PATCH 08/16] chaos booster draft implementation first check-in --- .../client/dialog/NewTournamentDialog.form | 22 +++- .../client/dialog/NewTournamentDialog.java | 102 ++++++++++++++++-- .../java/mage/client/draft/DraftPanel.java | 13 ++- .../src/mage/view/TournamentTypeView.java | 7 +- ...haosBoosterDraftEliminationTournament.java | 58 ++++++++++ ...BoosterDraftEliminationTournamentType.java | 51 +++++++++ .../ChaosBoosterDraftSwissTournament.java | 58 ++++++++++ .../ChaosBoosterDraftSwissTournamentType.java | 51 +++++++++ Mage.Server/config/config.xml | 2 + .../mage/game/draft/ChaosBoosterDraft.java | 96 +++++++++++++++++ .../mage/game/tournament/LimitedOptions.java | 9 +- .../mage/game/tournament/TournamentType.java | 7 +- 12 files changed, 462 insertions(+), 14 deletions(-) create mode 100644 Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/ChaosBoosterDraftEliminationTournament.java create mode 100644 Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/ChaosBoosterDraftEliminationTournamentType.java create mode 100644 Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/ChaosBoosterDraftSwissTournament.java create mode 100644 Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/ChaosBoosterDraftSwissTournamentType.java create mode 100644 Mage/src/mage/game/draft/ChaosBoosterDraft.java diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.form b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.form index 9e201ee6a2..cf2bffccce 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.form +++ b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.form @@ -118,6 +118,7 @@ + @@ -168,6 +169,8 @@ + + @@ -188,7 +191,7 @@ - + @@ -470,7 +473,7 @@ - + @@ -508,5 +511,20 @@ + + + + + + + + + + + + + + + diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java index 168442a87c..a3b6bb5f77 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java @@ -39,8 +39,13 @@ import java.util.List; import java.util.UUID; import javax.swing.ComboBoxModel; import javax.swing.DefaultComboBoxModel; +import javax.swing.DefaultListModel; +import javax.swing.DefaultListSelectionModel; import javax.swing.JComboBox; +import javax.swing.JList; import javax.swing.JOptionPane; +import javax.swing.JScrollPane; +import static javax.swing.ListSelectionModel.SINGLE_SELECTION; import javax.swing.SpinnerNumberModel; import mage.cards.decks.importer.DeckImporterUtil; import mage.cards.repository.ExpansionInfo; @@ -75,8 +80,10 @@ public class NewTournamentDialog extends MageDialog { private UUID roomId; private final Session session; private String lastSessionId; + private JList chaosList = new JList(); private final List players = new ArrayList<>(); private final List packs = new ArrayList<>(); + private final List chaosPacks = new ArrayList<>(); private final int CONSTRUCTION_TIME_MIN = 6; private final int CONSTRUCTION_TIME_MAX = 30; @@ -171,6 +178,7 @@ public class NewTournamentDialog extends MageDialog { pnlOtherPlayers = new javax.swing.JPanel(); btnOk = new javax.swing.JButton(); btnCancel = new javax.swing.JButton(); + pnlChaosPacks = new javax.swing.JPanel(); setTitle("New Tournament"); @@ -316,7 +324,7 @@ public class NewTournamentDialog extends MageDialog { ); pnlPlayersLayout.setVerticalGroup( pnlPlayersLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(pnlOtherPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, 7, Short.MAX_VALUE) + .addComponent(pnlOtherPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); btnOk.setText("OK"); @@ -333,6 +341,9 @@ public class NewTournamentDialog extends MageDialog { } }); + pnlChaosPacks.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + pnlChaosPacks.setLayout(new java.awt.GridLayout(0, 1, 2, 0)); + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( @@ -414,7 +425,8 @@ public class NewTournamentDialog extends MageDialog { .addComponent(lblPassword) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(txtPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 56, javax.swing.GroupLayout.PREFERRED_SIZE))))) - .addComponent(player1Panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(player1Panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(pnlChaosPacks, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) ); layout.setVerticalGroup( @@ -457,6 +469,8 @@ public class NewTournamentDialog extends MageDialog { .addGroup(layout.createSequentialGroup() .addComponent(pnlPacks, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pnlChaosPacks, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(cbAllowSpectators, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) @@ -464,7 +478,7 @@ public class NewTournamentDialog extends MageDialog { .addComponent(lblNumRounds)) .addComponent(lblNbrPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(spnNumPlayers) - .addComponent(pnlDraftOptions, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) + .addComponent(pnlDraftOptions, javax.swing.GroupLayout.DEFAULT_SIZE, 0, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(lblPlayer1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) @@ -472,7 +486,7 @@ public class NewTournamentDialog extends MageDialog { .addComponent(lblConstructionTime) .addComponent(chkRollbackTurnsAllowed))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(player1Panel, javax.swing.GroupLayout.DEFAULT_SIZE, 64, Short.MAX_VALUE) + .addComponent(player1Panel, javax.swing.GroupLayout.DEFAULT_SIZE, 61, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(pnlPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) @@ -517,6 +531,16 @@ public class NewTournamentDialog extends MageDialog { tOptions.getLimitedOptions().setConstructionTime((Integer)this.spnConstructTime.getValue() * 60); if (tournamentType.isCubeBooster()) { tOptions.getLimitedOptions().setDraftCubeName(this.cbDraftCube.getSelectedItem().toString()); + } else if (tournamentType.isChaos()){ + for (Integer pack: chaosList.getSelectedIndices()){ + String packStr = (String)chaosList.getModel().getElementAt(pack); + String code = packStr.substring(0, 3); + tOptions.getLimitedOptions().getSetCodes().add(code); + } + if (tOptions.getLimitedOptions().getSetCodes().size() < 2){ + // At least two sets must be chosen. + return; + } } else { for (JComboBox pack: packs) { tOptions.getLimitedOptions().getSetCodes().add(((ExpansionInfo) pack.getSelectedItem()).getCode()); @@ -629,7 +653,11 @@ public class NewTournamentDialog extends MageDialog { createPlayers((Integer) spnNumPlayers.getValue() - 1); if (tournamentType.isLimited()) { - createPacks(tournamentType.getNumBoosters()); + if (tournamentType.isChaos()){ + createChaosPacks(); + }else{ + createPacks(tournamentType.getNumBoosters()); + } } } @@ -668,11 +696,19 @@ public class NewTournamentDialog extends MageDialog { this.cbDraftCube.setVisible(true); this.lblPacks.setVisible(false); this.pnlPacks.setVisible(false); + this.pnlChaosPacks.setVisible(false); + } else if (tournamentType.isChaos()){ + this.lblDraftCube.setVisible(false); + this.cbDraftCube.setVisible(false); + this.lblPacks.setVisible(true); + this.pnlChaosPacks.setVisible(true); + this.pnlPacks.setVisible(false); } else { this.lblDraftCube.setVisible(false); this.cbDraftCube.setVisible(false); this.lblPacks.setVisible(true); this.pnlPacks.setVisible(true); + this.pnlChaosPacks.setVisible(false); } } else { // construced @@ -680,9 +716,60 @@ public class NewTournamentDialog extends MageDialog { this.cbDraftCube.setVisible(false); this.pnlPacks.setVisible(false); this.pnlPacks.setVisible(false); + this.pnlChaosPacks.setVisible(false); } } +private void createChaosPacks() { + if (pnlChaosPacks.getComponentCount() == 0 ){ + DefaultListModel chaosListModel = new DefaultListModel(); + chaosList = new JList(chaosListModel); + ExpansionInfo[] allExpansions = ExpansionRepository.instance.getWithBoostersSortedByReleaseDate(); + for (ExpansionInfo expansion: allExpansions){ + String exp = expansion.getCode() + " - " + expansion.getName(); + chaosListModel.addElement(exp); + } + chaosList.setSelectionModel(new DefaultListSelectionModel() { + private boolean mGestureStarted; + @Override + public void setSelectionInterval(int index0, int index1) { + // Toggle only one element while the user is dragging the mouse + if (!mGestureStarted) { + if (isSelectedIndex(index0)) { + super.removeSelectionInterval(index0, index1); + } else { + if (getSelectionMode() == SINGLE_SELECTION) { + super.setSelectionInterval(index0, index1); + } else { + super.addSelectionInterval(index0, index1); + } + } + } + // Disable toggling till the adjusting is over, or keep it + // enabled in case setSelectionInterval was called directly. + mGestureStarted = getValueIsAdjusting(); + } + + @Override + public void setValueIsAdjusting(boolean isAdjusting) { + super.setValueIsAdjusting(isAdjusting); + + if (isAdjusting == false) { + // Enable toggling + mGestureStarted = false; + } + } + }); + chaosList.setSelectionInterval(0, chaosListModel.size()-1); + JScrollPane list1scr = new JScrollPane(chaosList); + chaosList.setVisibleRowCount(4); + pnlChaosPacks.add(list1scr); + } + this.pack(); + this.revalidate(); + this.repaint(); + } + private void createPacks(int numPacks) { while (packs.size() > numPacks) { pnlPacks.remove(packs.get(packs.size() - 1)); @@ -829,7 +916,9 @@ public class NewTournamentDialog extends MageDialog { if (tournamentType.isDraft()) { numPlayers = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PLAYERS_DRAFT, "4")); setTournamentOptions(numPlayers); - loadBoosterPacks(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PACKS_DRAFT, "")); + if (!tournamentType.isChaos()){ + loadBoosterPacks(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PACKS_DRAFT, "")); + } String draftTiming = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_DRAFT_TIMING, "REGULAR"); for (TimingOption timingOption : DraftOptions.TimingOption.values()) { @@ -942,6 +1031,7 @@ public class NewTournamentDialog extends MageDialog { private javax.swing.JLabel lblPlayer1; private javax.swing.JLabel lblTournamentType; private mage.client.table.NewPlayerPanel player1Panel; + private javax.swing.JPanel pnlChaosPacks; private javax.swing.JPanel pnlDraftOptions; private javax.swing.JPanel pnlOtherPlayers; private javax.swing.JPanel pnlPacks; diff --git a/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java b/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java index 573a1b8be8..2a89715224 100644 --- a/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java +++ b/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java @@ -152,9 +152,16 @@ public class DraftPanel extends javax.swing.JPanel { } public void updateDraft(DraftView draftView) { - this.txtPack1.setText(draftView.getSets().get(0)); - this.txtPack2.setText(draftView.getSets().get(1)); - this.txtPack3.setText(draftView.getSets().get(2)); + if (draftView.getSets().size() != 3){ + // Chaos draft + this.txtPack1.setText("???"); + this.txtPack2.setText("???"); + this.txtPack3.setText("???"); + }else{ + this.txtPack1.setText(draftView.getSets().get(0)); + this.txtPack2.setText(draftView.getSets().get(1)); + this.txtPack3.setText(draftView.getSets().get(2)); + } this.chkPack1.setSelected(draftView.getBoosterNum() > 0); this.chkPack2.setSelected(draftView.getBoosterNum() > 1); this.chkPack3.setSelected(draftView.getBoosterNum() > 2); diff --git a/Mage.Common/src/mage/view/TournamentTypeView.java b/Mage.Common/src/mage/view/TournamentTypeView.java index b524e6a96e..7a3519a1cf 100644 --- a/Mage.Common/src/mage/view/TournamentTypeView.java +++ b/Mage.Common/src/mage/view/TournamentTypeView.java @@ -36,7 +36,7 @@ import mage.game.tournament.TournamentType; * @author BetaSteward_at_googlemail.com */ public class TournamentTypeView implements Serializable { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 2L; private final String name; private final int minPlayers; @@ -46,6 +46,7 @@ public class TournamentTypeView implements Serializable { private final boolean limited; private final boolean cubeBooster; private final boolean elimination; + private final boolean chaos; public TournamentTypeView(TournamentType tournamentType) { @@ -57,6 +58,7 @@ public class TournamentTypeView implements Serializable { this.limited = tournamentType.isLimited(); this.cubeBooster = tournamentType.isCubeBooster(); this.elimination = tournamentType.isElimination(); + this.chaos = tournamentType.isChaos(); } @Override @@ -96,4 +98,7 @@ public class TournamentTypeView implements Serializable { return elimination; } + public boolean isChaos(){ + return chaos; + } } diff --git a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/ChaosBoosterDraftEliminationTournament.java b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/ChaosBoosterDraftEliminationTournament.java new file mode 100644 index 0000000000..2a98c558ea --- /dev/null +++ b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/ChaosBoosterDraftEliminationTournament.java @@ -0,0 +1,58 @@ +/* + * Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.tournament; + +import mage.constants.TournamentPlayerState; +import mage.game.draft.DraftOptions; +import mage.game.events.TableEvent.EventType; +import mage.game.tournament.TournamentPlayer; +import mage.game.draft.ChaosBoosterDraft; +import mage.game.tournament.TournamentOptions; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class ChaosBoosterDraftEliminationTournament extends BoosterDraftEliminationTournament { + + public ChaosBoosterDraftEliminationTournament(TournamentOptions options) { + super(options); + currentStep = TournamentStep.START; + } + + @Override + protected void draft() { + draft = new ChaosBoosterDraft((DraftOptions) options.getLimitedOptions(), getSets()); + for (TournamentPlayer player: players.values()) { + draft.addPlayer(player.getPlayer()); + player.setState(TournamentPlayerState.DRAFTING); + } + tableEventSource.fireTableEvent(EventType.START_DRAFT, null, draft); + } +} diff --git a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/ChaosBoosterDraftEliminationTournamentType.java b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/ChaosBoosterDraftEliminationTournamentType.java new file mode 100644 index 0000000000..6ac57a9ae6 --- /dev/null +++ b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/ChaosBoosterDraftEliminationTournamentType.java @@ -0,0 +1,51 @@ +/* + * Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.tournament; + +import mage.game.tournament.TournamentType; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class ChaosBoosterDraftEliminationTournamentType extends TournamentType { + + public ChaosBoosterDraftEliminationTournamentType() { + this.name = "Booster Draft Elimination (Chaos)"; + this.maxPlayers = 16; + this.minPlayers = 4; + this.numBoosters = 3; + this.draft = true; + this.limited = true; + this.cubeBooster = false; + this.elimination = false; + this.isChaos = true; + } + +} diff --git a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/ChaosBoosterDraftSwissTournament.java b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/ChaosBoosterDraftSwissTournament.java new file mode 100644 index 0000000000..75f0761f65 --- /dev/null +++ b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/ChaosBoosterDraftSwissTournament.java @@ -0,0 +1,58 @@ +/* + * Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.tournament; + +import mage.constants.TournamentPlayerState; +import mage.game.draft.DraftOptions; +import mage.game.events.TableEvent.EventType; +import mage.game.tournament.TournamentPlayer; +import mage.game.draft.ChaosBoosterDraft; +import mage.game.tournament.TournamentOptions; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class ChaosBoosterDraftSwissTournament extends BoosterDraftSwissTournament { + + public ChaosBoosterDraftSwissTournament(TournamentOptions options) { + super(options); + currentStep = TournamentStep.START; + } + + @Override + protected void draft() { + draft = new ChaosBoosterDraft((DraftOptions) options.getLimitedOptions(), getSets()); + for (TournamentPlayer player: players.values()) { + draft.addPlayer(player.getPlayer()); + player.setState(TournamentPlayerState.DRAFTING); + } + tableEventSource.fireTableEvent(EventType.START_DRAFT, null, draft); + } +} diff --git a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/ChaosBoosterDraftSwissTournamentType.java b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/ChaosBoosterDraftSwissTournamentType.java new file mode 100644 index 0000000000..8f638e2ea3 --- /dev/null +++ b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/ChaosBoosterDraftSwissTournamentType.java @@ -0,0 +1,51 @@ +/* + * Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.tournament; + +import mage.game.tournament.TournamentType; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class ChaosBoosterDraftSwissTournamentType extends TournamentType { + + public ChaosBoosterDraftSwissTournamentType() { + this.name = "Booster Draft Swiss (Chaos)"; + this.maxPlayers = 16; + this.minPlayers = 4; + this.numBoosters = 3; + this.draft = true; + this.limited = true; + this.cubeBooster = false; + this.elimination = false; + this.isChaos = true; + } + +} diff --git a/Mage.Server/config/config.xml b/Mage.Server/config/config.xml index ec01eac5b8..31d0368995 100644 --- a/Mage.Server/config/config.xml +++ b/Mage.Server/config/config.xml @@ -55,8 +55,10 @@ + + diff --git a/Mage/src/mage/game/draft/ChaosBoosterDraft.java b/Mage/src/mage/game/draft/ChaosBoosterDraft.java new file mode 100644 index 0000000000..3c25bfea68 --- /dev/null +++ b/Mage/src/mage/game/draft/ChaosBoosterDraft.java @@ -0,0 +1,96 @@ +/* + * Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.game.draft; + +import java.util.ArrayList; +import java.util.List; +import mage.cards.ExpansionSet; +import java.util.Collections; +import java.lang.RuntimeException; + +/** + * + * @author BrodyLodmell_at_googlemail.com + */ +public class ChaosBoosterDraft extends BoosterDraft { + + List allSets; + List usedBoosters; + public ChaosBoosterDraft(DraftOptions options, List sets) { + super(options, sets); + if (sets.isEmpty()){ + throw new RuntimeException("At least one set must be selected for chaos booster draft"); + } + allSets = new ArrayList<>(sets); + resetBoosters(); + } + + @Override + public void start() { + while (!isAbort() && boosterNum < numberBoosters) { + openBooster(); + while (!isAbort() && pickCards()) { + if (boosterNum % 2 == 1) { + passLeft(); + } else { + passRight(); + } + fireUpdatePlayersEvent(); + } + } + resetBufferedCards(); + this.fireEndDraftEvent(); + } + + @Override + protected void openBooster() { + if (boosterNum < numberBoosters) { + for (DraftPlayer player: players.values()) { + player.setBooster(getNextBooster().createBooster()); + } + } + boosterNum++; + cardNum = 1; + fireUpdatePlayersEvent(); + } + + private ExpansionSet getNextBooster() { + if (0 == usedBoosters.size()){ + resetBoosters(); + } + ExpansionSet theBooster = usedBoosters.get(0); + usedBoosters.remove(theBooster); + return theBooster; + } + + private void resetBoosters(){ + usedBoosters = new ArrayList<>(allSets); + Collections.shuffle(usedBoosters); + } +} diff --git a/Mage/src/mage/game/tournament/LimitedOptions.java b/Mage/src/mage/game/tournament/LimitedOptions.java index e44b7efec9..4c5e3b0080 100644 --- a/Mage/src/mage/game/tournament/LimitedOptions.java +++ b/Mage/src/mage/game/tournament/LimitedOptions.java @@ -44,6 +44,7 @@ public class LimitedOptions implements Serializable { protected String draftCubeName; protected DraftCube draftCube; protected int numberBoosters; + protected boolean isChaos; public List getSetCodes() { return sets; @@ -80,5 +81,11 @@ public class LimitedOptions implements Serializable { public void setNumberBoosters(int numberBoosters) { this.numberBoosters = numberBoosters; } - + + public boolean getIsChaos(){ + return isChaos; + } + public void setIsChaos(boolean isChaos){ + this.isChaos = isChaos; + } } diff --git a/Mage/src/mage/game/tournament/TournamentType.java b/Mage/src/mage/game/tournament/TournamentType.java index af872e3705..88505f678d 100644 --- a/Mage/src/mage/game/tournament/TournamentType.java +++ b/Mage/src/mage/game/tournament/TournamentType.java @@ -44,6 +44,7 @@ public class TournamentType implements Serializable { protected boolean draft; // or sealed protected boolean limited; // or construced protected boolean elimination; // or Swiss + protected boolean isChaos; protected TournamentType() {} @@ -83,5 +84,9 @@ public class TournamentType implements Serializable { public boolean isCubeBooster() { return cubeBooster; } - + + public boolean isChaos(){ + return this.isChaos; + } + } From 07aa53618c287175442aaed358535314ade8055b Mon Sep 17 00:00:00 2001 From: BrodyL Date: Mon, 22 Jun 2015 22:13:25 -0700 Subject: [PATCH 09/16] Revert "Update readme.md" This reverts commit 73495db4bdec57230ee3fb7efb07935500f1d92b. --- readme.md | 36 ++---------------------------------- 1 file changed, 2 insertions(+), 34 deletions(-) diff --git a/readme.md b/readme.md index 7a6a9bb2f5..3ffe232abc 100644 --- a/readme.md +++ b/readme.md @@ -1,35 +1,3 @@ -# XMage - Magic, Another Game Engine +Fork of xmage for chaos cube implementation. -XMage allows you to play Magic against one or more online players or computer opponents. It includes full rules enforcement for over **10,000** unique cards (nearly 20,000 counting all cards from different editions). Starting with Eventide, all regular sets have nearly all the cards implemented ([detailed overview](http://ct-magefree.rhcloud.com/stats)). - -There are public servers where you can play XMage against other players. You can also host your own server to play against the AI and/or your friends. - -You can visit the XMage forum [here](http://www.slightlymagic.net/forum/viewforum.php?f=70). - -## Features -* Deck editor to build your desired decks. -* There is a simple computer AI opponent available. -* You can play either a two player duel or a multiplayer free-for-all game with up to 10 players. -* Commander format (also up to 10 players). -* Tiny Leaders duels. -* There are two tournament types supported, which can be played with up to 16 players: -* Elimination or swiss type handling -* Booster (also Cube) draft tournaments (4-16) -* Sealed (also from Cube) tournaments (2-16) - -## Installation -Download and install the [latest XMage release](http://XMage.de). -You will need to have the [Java Runtime Environment](http://java.com/en/) Version 7 or later. - -Look [here](http://www.slightlymagic.net/forum/viewtopic.php?f=70&t=13632) for more detailed instructions. -[Here](http://github.com/magefree/mage/wiki/Release-changes) you can find a log of the latest changes. - -## Developer - -If you are interested in developing XMage, here are some useful resources: -* [Developer Getting Started](http://github.com/magefree/mage/wiki/Developer-Getting-Started) -* [Developer Notes](http://github.com/magefree/mage/wiki/Developer-Notes) -* [Developer Testing Tools](http://github.com/magefree/mage/wiki/Developer-Testing-Tools) -* [Double Faced Cards](http://github.com/magefree/mage/wiki/Double-Faced-Cards) -* [Card Requests](http://www.slightlymagic.net/forum/viewtopic.php?f=70&t=4554) -* [Tournament Relevant Card Requests](http://www.slightlymagic.net/forum/viewtopic.php?f=70&t=14062) +a chaos booster draft is one where a pack pool is created with random packs and randomly distributed. you draft with those. Typically you use 24 different sets, so the decks are super weird. From d57ff3b0b31378d514df323791630f53c4fcb72c Mon Sep 17 00:00:00 2001 From: BrodyL Date: Mon, 22 Jun 2015 22:13:38 -0700 Subject: [PATCH 10/16] Revert "Update readme.md" This reverts commit 8685c676796d1bdfeb930ba3ec9a2677b28b4083. --- readme.md | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 3ffe232abc..a7ee59046a 100644 --- a/readme.md +++ b/readme.md @@ -1,3 +1,35 @@ -Fork of xmage for chaos cube implementation. +# XMage - Magic, Another Game Engine -a chaos booster draft is one where a pack pool is created with random packs and randomly distributed. you draft with those. Typically you use 24 different sets, so the decks are super weird. +XMage allows you to play Magic against one or more online players or computer opponents. It includes full rules enforcement for over **10,000** unique cards (nearly 20,000 counting all cards from different editions). Starting with Eventide, all regular sets have nearly all the cards implemented ([detailed overview](http://ct-magefree.rhcloud.com/stats)). + +There are public servers where you can play XMage against other players. You can also host your own server to play against the AI and/or your friends. + +You can visit the XMage forum [here](http://www.slightlymagic.net/forum/viewforum.php?f=70). + +## Features +* Deck editor to build your desired decks. +* There is a simple computer AI opponent available. +* You can play either a two player duel or a multiplayer free-for-all game with up to 10 players. +* Commander format (also up to 10 players). +* Tiny Leaders duels. +* There are two tournament types supported, which can be played with up to 16 players: +* Elimination or swiss type handling +* Booster (also Cube) draft tournaments (4-16) +* Sealed (also from Cube) tournaments (2-16) + +## Installation +Download and install the [latest XMage release](http://XMage.de). +You will need to have the [Java Runtime Environment](http://java.com/en/) Version 7 or later. + +Look [here](http://www.slightlymagic.net/forum/viewtopic.php?f=70&t=13632) for more detailed instructions. +[Here](http://github.com/magefree/mage/wiki/Release-changes) you can find a log of the latest changes. + +## Developer + +If you are interested in developing XMage, here are some useful resources: +* [Developer Getting Started](http://github.com/magefree/mage/wiki/Developer-Getting-Started) +* [Developer Notes](http://github.com/magefree/mage/wiki/Developer-Notes) +* [Developer Testing Tools](http://github.com/magefree/mage/wiki/Developer-Testing-Tools) +* [Double Faced Cards](http://github.com/magefree/mage/wiki/Double-Faced-Cards) +* [Card Requests](http://www.slightlymagic.net/forum/viewtopic.php?f=70&t=4554) +* [Tournament Relevant Card Requests](http://www.slightlymagic.net/forum/viewtopic.php?f=70&t=14062) \ No newline at end of file From 9097ffbfc3daad0e6af69d440b0638901e2b3c56 Mon Sep 17 00:00:00 2001 From: mkalender Date: Tue, 23 Jun 2015 11:41:33 -0400 Subject: [PATCH 11/16] fixed all triggers and abilities of card --- Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java b/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java index 26e69265d3..4ae362d68d 100644 --- a/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java +++ b/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java @@ -87,7 +87,11 @@ class TeferisMoatRestrictionEffect extends RestrictionEffect { ObjectColor chosenColor = (ObjectColor) game.getState().getValue(source.getSourceId() + "_color"); if (chosenColor == null) return false; - return permanent.getCardType().contains(CardType.CREATURE) && !permanent.getAbilities().contains(FlyingAbility.getInstance()) && !permanent.getColor(game).shares(chosenColor); + boolean creature = permanent.getCardType().contains(CardType.CREATURE); + boolean flying = permanent.getAbilities().contains(FlyingAbility.getInstance()); + boolean sharesColor = permanent.getColor(game).shares(chosenColor); + + return creature && !flying && sharesColor; } @Override From 43cb449a28ee00ae1ffc3798e472a14f87a5583a Mon Sep 17 00:00:00 2001 From: LoneFox Date: Tue, 23 Jun 2015 20:51:33 +0300 Subject: [PATCH 12/16] Implement cards: Llanowar Sentinel, Shrieking Grotesque, and Spectral Lynx --- .../mage/sets/apocalypse/SpectralLynx.java | 79 +++++++++++++ .../sets/guildpact/ShriekingGrotesque.java | 76 +++++++++++++ .../sets/tenthedition/LlanowarSentinel.java | 53 +++++++++ .../sets/weatherlight/LlanowarSentinel.java | 107 ++++++++++++++++++ 4 files changed, 315 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/apocalypse/SpectralLynx.java create mode 100644 Mage.Sets/src/mage/sets/guildpact/ShriekingGrotesque.java create mode 100644 Mage.Sets/src/mage/sets/tenthedition/LlanowarSentinel.java create mode 100644 Mage.Sets/src/mage/sets/weatherlight/LlanowarSentinel.java diff --git a/Mage.Sets/src/mage/sets/apocalypse/SpectralLynx.java b/Mage.Sets/src/mage/sets/apocalypse/SpectralLynx.java new file mode 100644 index 0000000000..81a0e9e9d6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/apocalypse/SpectralLynx.java @@ -0,0 +1,79 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.apocalypse; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.RegenerateSourceEffect; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author LoneFox + + */ +public class SpectralLynx extends CardImpl { + + private static final FilterCard filter = new FilterCard("green"); + + static { + filter.add(new ColorPredicate(ObjectColor.GREEN)); + } + + public SpectralLynx(UUID ownerId) { + super(ownerId, 17, "Spectral Lynx", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{W}"); + this.expansionSetCode = "APC"; + this.subtype.add("Cat"); + this.subtype.add("Spirit"); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Protection from green + this.addAbility(new ProtectionAbility(filter)); + // {B}: Regenerate Spectral Lynx. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl("{B}"))); + } + + public SpectralLynx(final SpectralLynx card) { + super(card); + } + + @Override + public SpectralLynx copy() { + return new SpectralLynx(this); + } +} diff --git a/Mage.Sets/src/mage/sets/guildpact/ShriekingGrotesque.java b/Mage.Sets/src/mage/sets/guildpact/ShriekingGrotesque.java new file mode 100644 index 0000000000..2228930acb --- /dev/null +++ b/Mage.Sets/src/mage/sets/guildpact/ShriekingGrotesque.java @@ -0,0 +1,76 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.guildpact; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.ManaWasSpentCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.discard.DiscardTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.ColoredManaSymbol; +import mage.constants.Rarity; +import mage.target.TargetPlayer; +import mage.watchers.common.ManaSpentToCastWatcher; + +/** + * + * @author LoneFox + + */ +public class ShriekingGrotesque extends CardImpl { + + public ShriekingGrotesque(UUID ownerId) { + super(ownerId, 15, "Shrieking Grotesque", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{W}"); + this.expansionSetCode = "GPT"; + this.subtype.add("Gargoyle"); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // When Shrieking Grotesque enters the battlefield, if {B} was spent to cast it, target player discards a card. + TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new DiscardTargetEffect(1), false); + ability.addTarget(new TargetPlayer()); + this.addAbility(new ConditionalTriggeredAbility(ability, new ManaWasSpentCondition(ColoredManaSymbol.B), + "if {B} was spent to cast {this}, target player discards a card."), new ManaSpentToCastWatcher()); + } + + public ShriekingGrotesque(final ShriekingGrotesque card) { + super(card); + } + + @Override + public ShriekingGrotesque copy() { + return new ShriekingGrotesque(this); + } +} diff --git a/Mage.Sets/src/mage/sets/tenthedition/LlanowarSentinel.java b/Mage.Sets/src/mage/sets/tenthedition/LlanowarSentinel.java new file mode 100644 index 0000000000..69943fff72 --- /dev/null +++ b/Mage.Sets/src/mage/sets/tenthedition/LlanowarSentinel.java @@ -0,0 +1,53 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.tenthedition; + +import java.util.UUID; + +/** + * + * @author LoneFox + + */ +public class LlanowarSentinel extends mage.sets.weatherlight.LlanowarSentinel { + + public LlanowarSentinel(UUID ownerId) { + super(ownerId); + this.cardNumber = 275; + this.expansionSetCode = "10E"; + } + + public LlanowarSentinel(final LlanowarSentinel card) { + super(card); + } + + @Override + public LlanowarSentinel copy() { + return new LlanowarSentinel(this); + } +} diff --git a/Mage.Sets/src/mage/sets/weatherlight/LlanowarSentinel.java b/Mage.Sets/src/mage/sets/weatherlight/LlanowarSentinel.java new file mode 100644 index 0000000000..840ab9ae1d --- /dev/null +++ b/Mage.Sets/src/mage/sets/weatherlight/LlanowarSentinel.java @@ -0,0 +1,107 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.weatherlight; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.NamePredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author LoneFox + + */ +public class LlanowarSentinel extends CardImpl { + + public LlanowarSentinel(UUID ownerId) { + super(ownerId, 76, "Llanowar Sentinel", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{G}"); + this.expansionSetCode = "WTH"; + this.subtype.add("Elf"); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // When Llanowar Sentinel enters the battlefield, you may pay {1}{G}. If you do, search your library for a card named Llanowar Sentinel and put that card onto the battlefield. Then shuffle your library. + this.addAbility(new EntersBattlefieldTriggeredAbility(new LlanowarSentinelEffect())); + } + + public LlanowarSentinel(final LlanowarSentinel card) { + super(card); + } + + @Override + public LlanowarSentinel copy() { + return new LlanowarSentinel(this); + } +} + +class LlanowarSentinelEffect extends OneShotEffect { + + LlanowarSentinelEffect() { + super(Outcome.Benefit); + this.staticText = "you may pay {1}{G}. If you do, search your library for a card named Llanowar Sentinel and put that card onto the battlefield. Then shuffle your library"; } + + LlanowarSentinelEffect(final LlanowarSentinelEffect effect) { + super(effect); + } + + @Override + public LlanowarSentinelEffect copy() { + return new LlanowarSentinelEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if(player != null) { + if(player.chooseUse(Outcome.BoostCreature, "Do you want to to pay {1}{G}?", game)) { + Cost cost = new ManaCostsImpl("{1}{G}"); + if(cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { + FilterCard filter = new FilterCard("card named Llanowar Sentinel"); + filter.add(new NamePredicate("Llanowar Sentinel")); + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 1, filter), false, true).apply(game, source); + } + return true; + } + } + return false; + } +} From 085870de1f9fee84bbfcf59298a020d4cfb78c32 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 23 Jun 2015 22:10:02 +0200 Subject: [PATCH 13/16] Minor code optimization. --- Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java b/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java index 4ae362d68d..e1edcb283c 100644 --- a/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java +++ b/Mage.Sets/src/mage/sets/timeshifted/TeferisMoat.java @@ -85,13 +85,10 @@ class TeferisMoatRestrictionEffect extends RestrictionEffect { @Override public boolean applies(Permanent permanent, Ability source, Game game) { ObjectColor chosenColor = (ObjectColor) game.getState().getValue(source.getSourceId() + "_color"); - if (chosenColor == null) - return false; - boolean creature = permanent.getCardType().contains(CardType.CREATURE); - boolean flying = permanent.getAbilities().contains(FlyingAbility.getInstance()); - boolean sharesColor = permanent.getColor(game).shares(chosenColor); - - return creature && !flying && sharesColor; + return chosenColor != null && + !permanent.getAbilities().contains(FlyingAbility.getInstance()) && + permanent.getColor(game).shares(chosenColor) && + permanent.getCardType().contains(CardType.CREATURE); } @Override From c2bba588fff70e16084f74d3cf21937d79d0919e Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 24 Jun 2015 00:10:06 +0200 Subject: [PATCH 14/16] [ORI] Implemented Renown keyword. --- .../mage/abilities/keyword/RenownAbility.java | 111 ++++++++++++++++++ Mage/src/mage/game/events/GameEvent.java | 1 + Mage/src/mage/game/permanent/Permanent.java | 3 + .../mage/game/permanent/PermanentImpl.java | 11 ++ Utils/keywords.txt | 1 + 5 files changed, 127 insertions(+) create mode 100644 Mage/src/mage/abilities/keyword/RenownAbility.java diff --git a/Mage/src/mage/abilities/keyword/RenownAbility.java b/Mage/src/mage/abilities/keyword/RenownAbility.java new file mode 100644 index 0000000000..506071634a --- /dev/null +++ b/Mage/src/mage/abilities/keyword/RenownAbility.java @@ -0,0 +1,111 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.abilities.keyword; + +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.DamagedPlayerEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.util.CardUtil; + +/** + * + * @author LevelX2 + */ + + +public class RenownAbility extends TriggeredAbilityImpl { + + private int renownValue; + + public RenownAbility(int renownValue) { + super(Zone.BATTLEFIELD, new BecomeRenownSourceEffect(renownValue), false); + this.renownValue = renownValue; + } + + public RenownAbility(final RenownAbility ability) { + super(ability); + this.renownValue = ability.renownValue; + } + + @Override + public RenownAbility copy() { + return new RenownAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return event.getSourceId().equals(getSourceId()) + && ((DamagedPlayerEvent) event).isCombatDamage(); + } + + @Override + public String getRule() { + return "Whenever {this} deals combat damage to a player, " + super.getRule(); + } + + public int getRenownValue() { + return renownValue; + } +} + +class BecomeRenownSourceEffect extends OneShotEffect { + + public BecomeRenownSourceEffect(int renownValue) { + super(Outcome.BoostCreature); + this.staticText = setText(renownValue); + } + + public BecomeRenownSourceEffect(final BecomeRenownSourceEffect effect) { + super(effect); + } + + @Override + public BecomeRenownSourceEffect copy() { + return new BecomeRenownSourceEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null && !permanent.isRenown() && source instanceof RenownAbility) { + game.informPlayers(permanent.getLogName() + " is now renown"); + int renownValue = ((RenownAbility) source).getRenownValue(); + // handle renown = X + if (renownValue == Integer.MAX_VALUE) { + renownValue = source.getManaCostsToPay().getX(); + } + new AddCountersSourceEffect(CounterType.P1P1.createInstance(renownValue),true).apply(game, source); + permanent.setRenown(true); + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.BECOMES_RENOWN, source.getSourceId(), source.getSourceId(), source.getControllerId(), renownValue)); + return true; + } + return false; + } + + private String setText(int renownValue) { + // Renown 1 (When this creature deals combat damage to a player, if it isn't renowned, put a +1/+1 counter on it and it becomes renowned.) + StringBuilder sb = new StringBuilder("Renown "); + sb.append(renownValue == Integer.MAX_VALUE ? "X":renownValue) + .append(". (When this creature deals combat damage to a player, if it isn't renowned, put ") + .append(renownValue == Integer.MAX_VALUE ? "X":CardUtil.numberToText(renownValue, "a")) + .append(" +1/+1 counter on it and it becomes renowned.)").toString(); + return sb.toString(); + } + +} diff --git a/Mage/src/mage/game/events/GameEvent.java b/Mage/src/mage/game/events/GameEvent.java index aae2b81a16..4b0c5223b6 100644 --- a/Mage/src/mage/game/events/GameEvent.java +++ b/Mage/src/mage/game/events/GameEvent.java @@ -185,6 +185,7 @@ public class GameEvent implements Serializable { UNFLIP, UNFLIPPED, TRANSFORM, TRANSFORMED, BECOMES_MONSTROUS, + BECOMES_RENOWN, PHASE_OUT, PHASED_OUT, PHASE_IN, PHASED_IN, TURNFACEUP, TURNEDFACEUP, diff --git a/Mage/src/mage/game/permanent/Permanent.java b/Mage/src/mage/game/permanent/Permanent.java index 8e7258301a..22e6319590 100644 --- a/Mage/src/mage/game/permanent/Permanent.java +++ b/Mage/src/mage/game/permanent/Permanent.java @@ -75,6 +75,9 @@ public interface Permanent extends Card, Controllable { boolean isMonstrous(); void setMonstrous(boolean value); + boolean isRenown(); + void setRenown(boolean value); + void setCardNumber(int cid); void setExpansionSetCode(String expansionSetCode); void setRarity(Rarity rarity); diff --git a/Mage/src/mage/game/permanent/PermanentImpl.java b/Mage/src/mage/game/permanent/PermanentImpl.java index e50d04cb09..60df01dae3 100644 --- a/Mage/src/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/mage/game/permanent/PermanentImpl.java @@ -91,6 +91,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { protected boolean flipped; protected boolean transformed; protected boolean monstrous; + protected boolean renown; protected boolean manifested = false; protected boolean morphed = false; protected UUID originalControllerId; @@ -1265,6 +1266,16 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { this.monstrous = value; } + @Override + public boolean isRenown() { + return this.renown; + } + + @Override + public void setRenown(boolean value) { + this.renown = value; + } + @Override public void setPairedCard(UUID pairedCard) { this.pairedCard = pairedCard; diff --git a/Utils/keywords.txt b/Utils/keywords.txt index 57945d8a0f..0e7ad4bea2 100644 --- a/Utils/keywords.txt +++ b/Utils/keywords.txt @@ -52,6 +52,7 @@ Provoke|new| Prowess|new| Reach|instance| Rebound|new| +Renown|number| Scavenge|cost| Shadow|instance| Shroud|instance| From 94ad36058c955e92b0184dc6730db29e6ddc6d9d Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 24 Jun 2015 00:11:03 +0200 Subject: [PATCH 15/16] [ORI] Added 5 cards with Renown relation and a renown test. --- .../sets/magicorigins/EnshroudingMist.java | 75 +++++++++ .../sets/magicorigins/HonoredHierarch.java | 87 +++++++++++ .../magicorigins/KnightOfThePilgrimsRoad.java | 63 ++++++++ .../mage/sets/magicorigins/RelicSeeker.java | 81 ++++++++++ .../mage/sets/magicorigins/RhoxMaulers.java | 66 ++++++++ .../mage/sets/mediainserts/RelicSeeker.java | 55 +++++++ .../cards/abilities/keywords/RenownTest.java | 142 ++++++++++++++++++ ...ecomesMonstrousSourceTriggeredAbility.java | 1 - .../BecomesRenownSourceTriggeredAbility.java | 59 ++++++++ .../condition/common/RenownCondition.java | 47 ++++++ 10 files changed, 675 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/sets/magicorigins/EnshroudingMist.java create mode 100644 Mage.Sets/src/mage/sets/magicorigins/HonoredHierarch.java create mode 100644 Mage.Sets/src/mage/sets/magicorigins/KnightOfThePilgrimsRoad.java create mode 100644 Mage.Sets/src/mage/sets/magicorigins/RelicSeeker.java create mode 100644 Mage.Sets/src/mage/sets/magicorigins/RhoxMaulers.java create mode 100644 Mage.Sets/src/mage/sets/mediainserts/RelicSeeker.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/RenownTest.java create mode 100644 Mage/src/mage/abilities/common/BecomesRenownSourceTriggeredAbility.java create mode 100644 Mage/src/mage/abilities/condition/common/RenownCondition.java diff --git a/Mage.Sets/src/mage/sets/magicorigins/EnshroudingMist.java b/Mage.Sets/src/mage/sets/magicorigins/EnshroudingMist.java new file mode 100644 index 0000000000..9c81ff6e17 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/EnshroudingMist.java @@ -0,0 +1,75 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.abilities.condition.common.RenownCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.PreventDamageToTargetEffect; +import mage.abilities.effects.common.UntapSourceEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class EnshroudingMist extends CardImpl { + + public EnshroudingMist(UUID ownerId) { + super(ownerId, 13, "Enshrouding Mist", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{W}"); + this.expansionSetCode = "ORI"; + + // Target creature gets +1/+1 until end of turn. Prevent all damage that would dealt to it this turn. If it's renowned, untap it. + this.getSpellAbility().addEffect(new BoostTargetEffect(1, 1, Duration.EndOfTurn)); + Effect effect = new PreventDamageToTargetEffect(Duration.EndOfTurn, Integer.MAX_VALUE); + effect.setText("Prevent all damage that would dealt to it this turn"); + this.getSpellAbility().addEffect(effect); + OneShotEffect effect2 = new UntapSourceEffect(); + effect2.setText("untap it"); + this.getSpellAbility().addEffect(new ConditionalOneShotEffect(effect2, RenownCondition.getInstance())); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + + + } + + public EnshroudingMist(final EnshroudingMist card) { + super(card); + } + + @Override + public EnshroudingMist copy() { + return new EnshroudingMist(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/HonoredHierarch.java b/Mage.Sets/src/mage/sets/magicorigins/HonoredHierarch.java new file mode 100644 index 0000000000..d09a2fb9e6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/HonoredHierarch.java @@ -0,0 +1,87 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.RenownCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.RenownAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.abilities.mana.AnyColorManaAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; + +/** + * + * @author LevelX2 + */ +public class HonoredHierarch extends CardImpl { + + public HonoredHierarch(UUID ownerId) { + super(ownerId, 182, "Honored Hierarch", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{G}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Human"); + this.subtype.add("Druid"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Renown 1 (When this creature deals combat damage to a player, if it isn't renowned put a +1/+1 counter on it and it becomes renowned.) + this.addAbility(new RenownAbility(1)); + + // As long as Honored Hierarch is renowned, it has vigilance and "{T}: Add one mana of any color to your mana pool." + Effect effect = new ConditionalContinuousEffect( + new GainAbilitySourceEffect(VigilanceAbility.getInstance(), Duration.WhileOnBattlefield), + RenownCondition.getInstance(), + "As long as {this} is renown, it has vigilance"); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect); + effect = new ConditionalContinuousEffect( + new GainAbilitySourceEffect(new AnyColorManaAbility(), Duration.WhileOnBattlefield), + RenownCondition.getInstance(), + "and \"{T}: Add one mana of any color to your mana pool.\""); + ability.addEffect(effect); + this.addAbility(ability); + + } + + public HonoredHierarch(final HonoredHierarch card) { + super(card); + } + + @Override + public HonoredHierarch copy() { + return new HonoredHierarch(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/KnightOfThePilgrimsRoad.java b/Mage.Sets/src/mage/sets/magicorigins/KnightOfThePilgrimsRoad.java new file mode 100644 index 0000000000..78462196d1 --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/KnightOfThePilgrimsRoad.java @@ -0,0 +1,63 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.keyword.RenownAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class KnightOfThePilgrimsRoad extends CardImpl { + + public KnightOfThePilgrimsRoad(UUID ownerId) { + super(ownerId, 20, "Knight of the Pilgrim's Road", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{W}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Human"); + this.subtype.add("Knight"); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Renown 1 (When this creature deals combat damage to a player, if it isn't renowned, put a +1/+1 counter on it and it becomes renowned.) + this.addAbility(new RenownAbility(1)); + } + + public KnightOfThePilgrimsRoad(final KnightOfThePilgrimsRoad card) { + super(card); + } + + @Override + public KnightOfThePilgrimsRoad copy() { + return new KnightOfThePilgrimsRoad(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/RelicSeeker.java b/Mage.Sets/src/mage/sets/magicorigins/RelicSeeker.java new file mode 100644 index 0000000000..612b08ceac --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/RelicSeeker.java @@ -0,0 +1,81 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.BecomesRenownSourceTriggeredAbility; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.abilities.keyword.RenownAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author LevelX2 + */ +public class RelicSeeker extends CardImpl { + + private static final FilterCard filter = new FilterCard("an Equipment card"); + + static { + filter.add(new CardTypePredicate(CardType.ARTIFACT)); + filter.add(new SubtypePredicate("Equipment")); + } + + public RelicSeeker(UUID ownerId) { + super(ownerId, 107, "Relic Seeker", Rarity.SPECIAL, new CardType[]{CardType.CREATURE}, "{1}{W}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Human"); + this.subtype.add("Soldier"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Renown 1 + this.addAbility(new RenownAbility(1)); + + // When Relic Seeker becomes renowned, you may search your library for an Equipment card, reveal it, put it into your hand, then shuffle your library. + TargetCardInLibrary target = new TargetCardInLibrary(1, 1, filter); + this.addAbility(new BecomesRenownSourceTriggeredAbility(new SearchLibraryPutInHandEffect(target, true, true), true)); + + } + + public RelicSeeker(final RelicSeeker card) { + super(card); + } + + @Override + public RelicSeeker copy() { + return new RelicSeeker(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/RhoxMaulers.java b/Mage.Sets/src/mage/sets/magicorigins/RhoxMaulers.java new file mode 100644 index 0000000000..0ca73fcf3a --- /dev/null +++ b/Mage.Sets/src/mage/sets/magicorigins/RhoxMaulers.java @@ -0,0 +1,66 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.magicorigins; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.keyword.TrampleAbility; +import mage.abilities.keyword.RenownAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class RhoxMaulers extends CardImpl { + + public RhoxMaulers(UUID ownerId) { + super(ownerId, 196, "Rhox Maulers", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{4}{G}"); + this.expansionSetCode = "ORI"; + this.subtype.add("Rhino"); + this.subtype.add("Soldier"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + // Renown 2 + this.addAbility(new RenownAbility(2)); + } + + public RhoxMaulers(final RhoxMaulers card) { + super(card); + } + + @Override + public RhoxMaulers copy() { + return new RhoxMaulers(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mediainserts/RelicSeeker.java b/Mage.Sets/src/mage/sets/mediainserts/RelicSeeker.java new file mode 100644 index 0000000000..bf67641740 --- /dev/null +++ b/Mage.Sets/src/mage/sets/mediainserts/RelicSeeker.java @@ -0,0 +1,55 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.mediainserts; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class RelicSeeker extends mage.sets.magicorigins.RelicSeeker { + + public RelicSeeker(UUID ownerId) { + super(ownerId); + this.cardNumber = 107; + this.expansionSetCode = "MBP"; + this.rarity = Rarity.RARE; + + } + + public RelicSeeker(final RelicSeeker card) { + super(card); + } + + @Override + public RelicSeeker copy() { + return new RelicSeeker(this); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/RenownTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/RenownTest.java new file mode 100644 index 0000000000..7db71b1959 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/RenownTest.java @@ -0,0 +1,142 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package org.mage.test.cards.abilities.keywords; + +import mage.abilities.keyword.VigilanceAbility; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class RenownTest extends CardTestPlayerBase { + + @Test + public void testKnightOfThePilgrimsRoad() { + addCard(Zone.BATTLEFIELD, playerA, "Plains", 3); + // Renown 1 (When this creature deals combat damage to a player, if it isn't renowned, put a +1/+1 counter on it and it becomes renowned.) + addCard(Zone.HAND, playerA, "Knight of the Pilgrim's Road"); // 3/2 + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Knight of the Pilgrim's Road"); + + attack(3, playerA, "Knight of the Pilgrim's Road"); // 3 damage + attack(5, playerA, "Knight of the Pilgrim's Road"); // 4 damage + attack(7, playerA, "Knight of the Pilgrim's Road"); // 4 damage + + setStopAt(7, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertPowerToughness(playerA, "Knight of the Pilgrim's Road", 4, 3); + + assertLife(playerA, 20); + assertLife(playerB, 9); + + } + + /** + * Test renown trigger + */ + @Test + public void testRelicSeeker() { + addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + // Renown 1 (When this creature deals combat damage to a player, if it isn't renowned, put a +1/+1 counter on it and it becomes renowned.) + // When Relic Seeker becomes renowned, you may search your library for an Equipment card, reveal it, put it into your hand, then shuffle your library. + addCard(Zone.HAND, playerA, "Relic Seeker"); // 2/2 + + addCard(Zone.LIBRARY, playerA, "Veteran's Sidearm"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Relic Seeker"); + + attack(3, playerA, "Relic Seeker"); // 2 damage + attack(5, playerA, "Relic Seeker"); // 3 damage + + setStopAt(5, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertPowerToughness(playerA, "Relic Seeker", 3, 3); + assertHandCount(playerA, "Veteran's Sidearm", 1); + + assertLife(playerA, 20); + assertLife(playerB, 15); + + } + + /** + * Test renown state + */ + @Test + public void testHonoredHierarch() { + addCard(Zone.BATTLEFIELD, playerA, "Forest", 1); + // As long as Honored Hierarch is renowned, it has vigilance and "{T}: Add one mana of any color to your mana pool." + addCard(Zone.HAND, playerA, "Honored Hierarch"); // 1/1 + + addCard(Zone.LIBRARY, playerA, "Veteran's Sidearm"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Honored Hierarch"); + + attack(3, playerA, "Honored Hierarch"); // 1 damage + attack(5, playerA, "Honored Hierarch"); // 2 damage + + setStopAt(5, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertPowerToughness(playerA, "Honored Hierarch", 2, 2); + assertTapped("Honored Hierarch", false); + assertAbility(playerA, "Honored Hierarch", VigilanceAbility.getInstance(), true); + + assertLife(playerA, 20); + assertLife(playerB, 17); + + } + /** + * Test renown > 1 + */ + @Test + public void testRhoxMaulers() { + addCard(Zone.BATTLEFIELD, playerA, "Forest", 5); + // Trample + // Renown 2 + addCard(Zone.HAND, playerA, "Rhox Maulers"); // 4/4 + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rhox Maulers"); + + attack(3, playerA, "Rhox Maulers"); // 4 damage + attack(5, playerA, "Rhox Maulers"); // 6 damage + attack(7, playerA, "Rhox Maulers"); // 6 damage + + setStopAt(7, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertPowerToughness(playerA, "Rhox Maulers", 6, 6); + + assertLife(playerA, 20); + assertLife(playerB, 4); + + } +} diff --git a/Mage/src/mage/abilities/common/BecomesMonstrousSourceTriggeredAbility.java b/Mage/src/mage/abilities/common/BecomesMonstrousSourceTriggeredAbility.java index 42f1dfec1f..ad84726754 100644 --- a/Mage/src/mage/abilities/common/BecomesMonstrousSourceTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/BecomesMonstrousSourceTriggeredAbility.java @@ -32,7 +32,6 @@ import mage.abilities.effects.Effect; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; /** * diff --git a/Mage/src/mage/abilities/common/BecomesRenownSourceTriggeredAbility.java b/Mage/src/mage/abilities/common/BecomesRenownSourceTriggeredAbility.java new file mode 100644 index 0000000000..0864328cee --- /dev/null +++ b/Mage/src/mage/abilities/common/BecomesRenownSourceTriggeredAbility.java @@ -0,0 +1,59 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.abilities.common; + +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; + +/** + * + * @author LevelX2 + */ + +public class BecomesRenownSourceTriggeredAbility extends TriggeredAbilityImpl { + + private int renownValue; + + public BecomesRenownSourceTriggeredAbility(Effect effect, boolean optional) { + super(Zone.BATTLEFIELD, effect, optional); + } + + public BecomesRenownSourceTriggeredAbility(final BecomesRenownSourceTriggeredAbility ability) { + super(ability); + this.renownValue = ability.renownValue; + } + + @Override + public BecomesRenownSourceTriggeredAbility copy() { + return new BecomesRenownSourceTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.BECOMES_RENOWN; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getSourceId().equals(this.getSourceId())) { + this.renownValue = event.getAmount(); + return true; + } + return false; + } + + public int getRenownValue() { + return renownValue; + } + + @Override + public String getRule() { + return "When {this} becomes monstrous, " + super.getRule(); + } +} \ No newline at end of file diff --git a/Mage/src/mage/abilities/condition/common/RenownCondition.java b/Mage/src/mage/abilities/condition/common/RenownCondition.java new file mode 100644 index 0000000000..1e00bba442 --- /dev/null +++ b/Mage/src/mage/abilities/condition/common/RenownCondition.java @@ -0,0 +1,47 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.abilities.condition.common; + +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * Checks if a Permanent is renown + * + * @author LevelX2 + */ + +public class RenownCondition implements Condition { + + private static RenownCondition fInstance = null; + + private RenownCondition() {} + + public static RenownCondition getInstance() { + if (fInstance == null) { + fInstance = new RenownCondition(); + } + return fInstance; + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null) { + return permanent.isRenown(); + } + return false; + } + + @Override + public String toString() { + return "it's renowned"; + } + + +} \ No newline at end of file From 6c95c7139e9442d4489f03444be51b037c7e483b Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 24 Jun 2015 00:19:04 +0200 Subject: [PATCH 16/16] * Fixed possible NPE for SacrificeSourceEffect. --- .../mage/abilities/effects/common/SacrificeSourceEffect.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/Mage/src/mage/abilities/effects/common/SacrificeSourceEffect.java b/Mage/src/mage/abilities/effects/common/SacrificeSourceEffect.java index 6d8727059a..bb1f89ea2c 100644 --- a/Mage/src/mage/abilities/effects/common/SacrificeSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/SacrificeSourceEffect.java @@ -65,9 +65,6 @@ public class SacrificeSourceEffect extends OneShotEffect { return permanent.sacrifice(source.getSourceId(), game); } return true; - } else { - // no permanent? - sourceObject.getName(); } return false; }