[BOK] 12 cards

This commit is contained in:
LevelX2 2012-11-03 16:42:53 +01:00
parent 7eb6ee15c0
commit fec750ef01
12 changed files with 1623 additions and 0 deletions

View file

@ -0,0 +1,129 @@
/*
* 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 LIAB8LE 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.betrayersofkamigawa;
import java.util.List;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Duration;
import mage.Constants.Rarity;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.costs.AlternativeCost;
import mage.abilities.costs.AlternativeCostImpl;
import mage.abilities.costs.Cost;
import mage.abilities.costs.Costs;
import mage.abilities.costs.common.ExileFromHandCost;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.continious.BoostTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.filter.predicate.other.OwnerPredicate;
import mage.game.Game;
import mage.target.common.TargetCardInHand;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author LevelX2
*/
public class BlazingShoal extends CardImpl<BlazingShoal> {
private static final String ALTERNATIVE_COST_DESCRIPTION = "You may exile a red card with converted mana cost X from your hand rather than pay Blazing Shoal's mana cost";
private static final FilterCard filter = new FilterCard("red card from your hand");
static {
filter.add(new ColorPredicate(ObjectColor.RED));
filter.add(new OwnerPredicate(Constants.TargetController.YOU));
}
public BlazingShoal(UUID ownerId) {
super(ownerId, 96, "Blazing Shoal", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{X}{R}{R}");
this.expansionSetCode = "BOK";
this.subtype.add("Arcane");
this.color.setRed(true);
// You may exile a red card with converted mana cost X from your hand rather than pay Blazing Shoal's mana cost.
this.getSpellAbility().addAlternativeCost(new AlternativeCostImpl(ALTERNATIVE_COST_DESCRIPTION, new ExileFromHandCost(new TargetCardInHand(filter))));
// Target creature gets +X/+0 until end of turn.
this.getSpellAbility().addEffect(new BoostTargetEffect(new BlazingShoalVariableValue(), new StaticValue(0), Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
public BlazingShoal(final BlazingShoal card) {
super(card);
}
@Override
public BlazingShoal copy() {
return new BlazingShoal(this);
}
}
class BlazingShoalVariableValue implements DynamicValue {
@Override
public int calculate(Game game, Ability sourceAbility) {
List<AlternativeCost> aCosts = sourceAbility.getAlternativeCosts();
for (AlternativeCost aCost: aCosts) {
if (aCost.isPaid()) {
Costs aCostsList = (Costs) aCost;
for (int x=0; x < aCostsList.size(); x++) {
Cost cost = (Cost) aCostsList.get(x);
if (cost instanceof ExileFromHandCost) {
int xMana = 0;
for (Card card : ((ExileFromHandCost) cost).getCards()) {
xMana += card.getManaCost().convertedManaCost();
}
return xMana;
}
}
}
}
return sourceAbility.getManaCostsToPay().getX();
}
@Override
public DynamicValue clone() {
return new BlazingShoalVariableValue();
}
@Override
public String toString() {
return "X";
}
@Override
public String getMessage() {
return "";
}
}

View file

@ -0,0 +1,162 @@
/*
* 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 LIAB8LE 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.betrayersofkamigawa;
import java.util.List;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Outcome;
import mage.Constants.Rarity;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.costs.AlternativeCost;
import mage.abilities.costs.AlternativeCostImpl;
import mage.abilities.costs.Cost;
import mage.abilities.costs.Costs;
import mage.abilities.costs.common.ExileFromHandCost;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.filter.predicate.other.OwnerIdPredicate;
import mage.filter.predicate.other.OwnerPredicate;
import mage.game.Game;
import mage.game.stack.Spell;
import mage.target.TargetSpell;
import mage.target.common.TargetCardInHand;
/**
*
* @author LevelX2
*/
public class DisruptingShoal extends CardImpl<DisruptingShoal> {
private static final String ALTERNATIVE_COST_DESCRIPTION = "You may exile a blue card with converted mana cost X from your hand rather than pay Disrupting Shoal's mana cost";
private static final FilterCard filter = new FilterCard("blue card from your hand");
static {
filter.add(new ColorPredicate(ObjectColor.BLUE));
filter.add(new OwnerPredicate(Constants.TargetController.YOU));
}
public DisruptingShoal(UUID ownerId) {
super(ownerId, 33, "Disrupting Shoal", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{X}{U}{U}");
this.expansionSetCode = "BOK";
this.subtype.add("Arcane");
this.color.setBlue(true);
// You may exile a blue card with converted mana cost X from your hand rather than pay Disrupting Shoal's mana cost.
this.getSpellAbility().addAlternativeCost(new AlternativeCostImpl(ALTERNATIVE_COST_DESCRIPTION, new ExileFromHandCost(new TargetCardInHand(filter))));
// 2/1/2005: Disrupting Shoal can target any spell, but does nothing unless that spell's converted mana cost is X.
// Counter target spell if its converted mana cost is X.
this.getSpellAbility().addEffect(new DisruptingShoalCounterTargetEffect());
this.getSpellAbility().addTarget(new TargetSpell());
}
public DisruptingShoal(final DisruptingShoal card) {
super(card);
}
@Override
public DisruptingShoal copy() {
return new DisruptingShoal(this);
}
}
// ConvertedManaExileFromHandOrVariableManaValue
class DisruptingShoalVariableValue implements DynamicValue {
@Override
public int calculate(Game game, Ability sourceAbility) {
for (AlternativeCost aCost: (List<AlternativeCost>) sourceAbility.getAlternativeCosts()) {
if (aCost.isPaid()) {
for (int x=0; x < ((Costs) aCost).size(); x++) {
Cost cost = (Cost) ((Costs) aCost).get(x);
if (cost instanceof ExileFromHandCost) {
int xValue = 0;
for (Card card : ((ExileFromHandCost) cost).getCards()) {
xValue += card.getManaCost().convertedManaCost();
}
return xValue;
}
}
}
}
return sourceAbility.getManaCostsToPay().getX();
}
@Override
public DynamicValue clone() {
return new DisruptingShoalVariableValue();
}
@Override
public String toString() {
return "X";
}
@Override
public String getMessage() {
return "";
}
}
class DisruptingShoalCounterTargetEffect extends OneShotEffect<DisruptingShoalCounterTargetEffect> {
public DisruptingShoalCounterTargetEffect() {
super(Outcome.Detriment);
}
public DisruptingShoalCounterTargetEffect(final DisruptingShoalCounterTargetEffect effect) {
super(effect);
}
@Override
public DisruptingShoalCounterTargetEffect copy() {
return new DisruptingShoalCounterTargetEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
DynamicValue amount = new DisruptingShoalVariableValue();
Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source));
if (spell != null && spell.getManaCost().convertedManaCost() == amount.calculate(game, source)) {
return game.getStack().counter(source.getFirstTarget(), source.getSourceId(), game);
}
return false;
}
@Override
public String getText(Mode mode) {
return "Counter target spell if its converted mana cost is X";
}
}

View file

@ -0,0 +1,99 @@
/*
* 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 LIAB8LE 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.betrayersofkamigawa;
import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Outcome;
import mage.Constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author LevelX2
*/
public class FirstVolley extends CardImpl<FirstVolley> {
public FirstVolley(UUID ownerId) {
super(ownerId, 100, "First Volley", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{R}");
this.expansionSetCode = "BOK";
this.subtype.add("Arcane");
this.color.setRed(true);
// First Volley deals 1 damage to target creature and 1 damage to that creature's controller.
this.getSpellAbility().addEffect(new FirstVolleyEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
public FirstVolley(final FirstVolley card) {
super(card);
}
@Override
public FirstVolley copy() {
return new FirstVolley(this);
}
}
class FirstVolleyEffect extends OneShotEffect<FirstVolleyEffect> {
public FirstVolleyEffect() {
super(Outcome.Damage);
this.staticText = "{this} deals 1 damage to target creature and 1 damage to that creature's controller";
}
public FirstVolleyEffect(final FirstVolleyEffect effect) {
super(effect);
}
@Override
public FirstVolleyEffect copy() {
return new FirstVolleyEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source));
if (permanent != null) {
Player controller = game.getPlayer(permanent.getControllerId());
if (controller != null) {
permanent.damage(1, source.getSourceId(), game, true, false);
controller.damage(1, source.getSourceId(), game, false, true);
return true;
}
}
return false;
}
}

View file

@ -0,0 +1,126 @@
/*
* 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 LIAB8LE 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.betrayersofkamigawa;
import java.util.List;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.costs.AlternativeCost;
import mage.abilities.costs.AlternativeCostImpl;
import mage.abilities.costs.Cost;
import mage.abilities.costs.Costs;
import mage.abilities.costs.common.ExileFromHandCost;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.common.GainLifeEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.filter.predicate.other.OwnerPredicate;
import mage.game.Game;
import mage.target.common.TargetCardInHand;
/**
*
* @author LevelX2
*/
public class NourishingShoal extends CardImpl<NourishingShoal> {
private static final String ALTERNATIVE_COST_DESCRIPTION = "You may exile a green card with converted mana cost X from your hand rather than pay Nourishing Shoal's mana cost";
private static final FilterCard filter = new FilterCard("green card from your hand");
static {
filter.add(new ColorPredicate(ObjectColor.GREEN));
filter.add(new OwnerPredicate(Constants.TargetController.YOU));
}
public NourishingShoal(UUID ownerId) {
super(ownerId, 137, "Nourishing Shoal", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{X}{G}{G}");
this.expansionSetCode = "BOK";
this.subtype.add("Arcane");
this.color.setGreen(true);
// You may exile a green card with converted mana cost X from your hand rather than pay Nourishing Shoal's mana cost.
this.getSpellAbility().addAlternativeCost(new AlternativeCostImpl(ALTERNATIVE_COST_DESCRIPTION, new ExileFromHandCost(new TargetCardInHand(filter))));
// You gain X life.
this.getSpellAbility().addEffect(new GainLifeEffect(new NourishingShoalVariableValue()));
}
public NourishingShoal(final NourishingShoal card) {
super(card);
}
@Override
public NourishingShoal copy() {
return new NourishingShoal(this);
}
}
class NourishingShoalVariableValue implements DynamicValue {
@Override
public int calculate(Game game, Ability sourceAbility) {
List<AlternativeCost> aCosts = sourceAbility.getAlternativeCosts();
for (AlternativeCost aCost: aCosts) {
if (aCost.isPaid()) {
Costs aCostsList = (Costs) aCost;
for (int x=0; x < aCostsList.size(); x++) {
Cost cost = (Cost) aCostsList.get(x);
if (cost instanceof ExileFromHandCost) {
int xMana = 0;
for (Card card : ((ExileFromHandCost) cost).getCards()) {
xMana += card.getManaCost().convertedManaCost();
}
return xMana;
}
}
}
}
return sourceAbility.getManaCostsToPay().getX();
}
@Override
public DynamicValue clone() {
return new NourishingShoalVariableValue();
}
@Override
public String toString() {
return "X";
}
@Override
public String getMessage() {
return "";
}
}

View file

@ -0,0 +1,212 @@
/*
* 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.betrayersofkamigawa;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Outcome;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.PreventionEffectImpl;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.keyword.BushidoAbility;
import mage.abilities.keyword.DefenderAbility;
import mage.cards.CardImpl;
import mage.game.Game;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetSource;
/**
* @author LevelX2
*/
public class OpalEyeKondasYojimbo extends CardImpl<OpalEyeKondasYojimbo> {
public OpalEyeKondasYojimbo(UUID ownerId) {
super(ownerId, 17, "Opal-Eye, Konda's Yojimbo", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{W}{W}");
this.expansionSetCode = "BOK";
this.supertype.add("Legendary");
this.subtype.add("Fox");
this.subtype.add("Samurai");
this.color.setWhite(true);
this.power = new MageInt(1);
this.toughness = new MageInt(4);
// Defender (This creature can't attack.)
this.addAbility(DefenderAbility.getInstance());
// Bushido 1 (When this blocks or becomes blocked, it gets +1/+1 until end of turn.)
this.addAbility(new BushidoAbility(1));
// {T}: The next time a source of your choice would deal damage this turn, that damage is dealt to Opal-Eye, Konda's Yojimbo instead.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new OpalEyeKondasYojimboRedirectionEffect(), new TapSourceCost());
ability.addTarget(new TargetSource());
this.addAbility(ability);
// {1}{W}: Prevent the next 1 damage that would be dealt to Opal-Eye this turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new OpalEyeKondasYojimboPreventEffect(), new ManaCostsImpl("{1}{W}")));
}
public OpalEyeKondasYojimbo(final OpalEyeKondasYojimbo card) {
super(card);
}
@Override
public OpalEyeKondasYojimbo copy() {
return new OpalEyeKondasYojimbo(this);
}
}
class OpalEyeKondasYojimboRedirectionEffect extends ReplacementEffectImpl<OpalEyeKondasYojimboRedirectionEffect> {
OpalEyeKondasYojimboRedirectionEffect() {
super(Constants.Duration.EndOfTurn, Outcome.RedirectDamage);
staticText = "The next time a source of your choice would deal damage this turn, that damage is dealt to {this} instead";
}
OpalEyeKondasYojimboRedirectionEffect(final OpalEyeKondasYojimboRedirectionEffect effect) {
super(effect);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (!this.used) {
if (event.getType().equals(GameEvent.EventType.DAMAGE_CREATURE ) ||
event.getType().equals(GameEvent.EventType.DAMAGE_PLANESWALKER ) ||
event.getType().equals(GameEvent.EventType.DAMAGE_PLAYER ) ) {
if (event.getSourceId().equals(targetPointer.getFirst(game, source))) {
// check source
MageObject object = game.getObject(event.getSourceId());
if (object == null) {
game.informPlayers("Couldn't find source of damage");
return false;
}
return true;
}
}
}
return false;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
DamageEvent damageEvent = (DamageEvent)event;
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (sourcePermanent != null) {
// get name of old target
Permanent targetPermanent = game.getPermanent(event.getTargetId());
StringBuilder message = new StringBuilder();
message.append(sourcePermanent.getName()).append(": gets ");
message.append(damageEvent.getAmount()).append(" damage redirected from ");
if (targetPermanent != null) {
message.append(targetPermanent.getName());
}
else {
Player targetPlayer = game.getPlayer(event.getTargetId());
if (targetPlayer != null) {
message.append(targetPlayer.getName());
}
else {
message.append("unknown");
}
}
game.informPlayers(message.toString());
// remember redirection effect (614.5)
event.getAppliedEffects().add(getId());
// redirect damage
this.used = true;
sourcePermanent.damage(damageEvent.getAmount(), damageEvent.getSourceId(), game, damageEvent.isPreventable(), damageEvent.isCombatDamage(), event.getAppliedEffects());
return true;
}
return false;
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public OpalEyeKondasYojimboRedirectionEffect copy() {
return new OpalEyeKondasYojimboRedirectionEffect(this);
}
}
class OpalEyeKondasYojimboPreventEffect extends PreventionEffectImpl<OpalEyeKondasYojimboPreventEffect> {
public OpalEyeKondasYojimboPreventEffect() {
super(Constants.Duration.EndOfTurn);
staticText = "Prevent the next 1 damage that would be dealt to {this} this turn";
}
public OpalEyeKondasYojimboPreventEffect(final OpalEyeKondasYojimboPreventEffect effect) {
super(effect);
}
@Override
public OpalEyeKondasYojimboPreventEffect copy() {
return new OpalEyeKondasYojimboPreventEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), event.getAmount(), false);
if (!game.replaceEvent(preventEvent)) {
if (event.getAmount() >= 1) {
int damage = 1;
event.setAmount(event.getAmount() - 1);
this.used = true;
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), damage));
}
}
return false;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (!this.used && super.applies(event, source, game) && event.getTargetId().equals(source.getSourceId())) {
return true;
}
return false;
}
}

View file

@ -0,0 +1,71 @@
/*
* 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.betrayersofkamigawa;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.MageInt;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.common.continious.BoostControlledEffect;
import mage.abilities.keyword.OfferingAbility;
import mage.cards.CardImpl;
import mage.filter.common.FilterCreaturePermanent;
/**
* @author LevelX2
*/
public class PatronOfTheAkki extends CardImpl<PatronOfTheAkki> {
public PatronOfTheAkki(UUID ownerId) {
super(ownerId, 115, "Patron of the Akki", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{R}{R}");
this.expansionSetCode = "BOK";
this.supertype.add("Legendary");
this.subtype.add("Spirit");
this.color.setRed(true);
this.power = new MageInt(5);
this.toughness = new MageInt(5);
// Goblin offering (You may cast this card any time you could cast an instant by sacrificing a Goblin and paying the difference in mana costs between this and the sacrificed Goblin. Mana cost includes color.)
this.addAbility(new OfferingAbility("Goblin"));
// Whenever Patron of the Akki attacks, creatures you control get +2/+0 until end of turn.
this.addAbility(new AttacksTriggeredAbility(new BoostControlledEffect(2, 0, Constants.Duration.EndOfTurn, new FilterCreaturePermanent(), false), false));
}
public PatronOfTheAkki(final PatronOfTheAkki card) {
super(card);
}
@Override
public PatronOfTheAkki copy() {
return new PatronOfTheAkki(this);
}
}

View file

@ -0,0 +1,102 @@
/*
* 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.betrayersofkamigawa;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.keyword.OfferingAbility;
import mage.cards.CardImpl;
import mage.game.Game;
import mage.game.events.GameEvent;
/**
* @author LevelX2
*/
public class PatronOfTheKitsune extends CardImpl<PatronOfTheKitsune> {
public PatronOfTheKitsune(UUID ownerId) {
super(ownerId, 19, "Patron of the Kitsune", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{W}{W}");
this.expansionSetCode = "BOK";
this.supertype.add("Legendary");
this.subtype.add("Spirit");
this.color.setWhite(true);
this.power = new MageInt(5);
this.toughness = new MageInt(5);
// Fox offering (You may cast this card any time you could cast an instant by sacrificing a Fox and paying the difference in mana costs between this and the sacrificed Fox. Mana cost includes color.)
this.addAbility(new OfferingAbility("Fox"));
// Whenever a creature attacks, you may gain 1 life.
this.addAbility(new PatronOfTheKitsuneTriggeredAbility());
}
public PatronOfTheKitsune(final PatronOfTheKitsune card) {
super(card);
}
@Override
public PatronOfTheKitsune copy() {
return new PatronOfTheKitsune(this);
}
}
class PatronOfTheKitsuneTriggeredAbility extends TriggeredAbilityImpl<PatronOfTheKitsuneTriggeredAbility> {
public PatronOfTheKitsuneTriggeredAbility() {
super(Constants.Zone.BATTLEFIELD, new GainLifeEffect(1), true);
}
public PatronOfTheKitsuneTriggeredAbility(PatronOfTheKitsuneTriggeredAbility ability) {
super(ability);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.ATTACKER_DECLARED) {
return true;
}
return false;
}
@Override
public PatronOfTheKitsuneTriggeredAbility copy() {
return new PatronOfTheKitsuneTriggeredAbility(this);
}
@Override
public String getRule() {
return "Whenever a creature attacks, " + super.getRule();
}
}

View file

@ -0,0 +1,116 @@
/*
* 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.betrayersofkamigawa;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.OfferingAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.filter.common.FilterLandCard;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCardInHand;
/**
* @author LevelX2
*/
public class PatronOfTheMoon extends CardImpl<PatronOfTheMoon> {
public PatronOfTheMoon(UUID ownerId) {
super(ownerId, 45, "Patron of the Moon", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{5}{U}{U}");
this.expansionSetCode = "BOK";
this.supertype.add("Legendary");
this.subtype.add("Spirit");
this.color.setBlue(true);
this.power = new MageInt(5);
this.toughness = new MageInt(4);
// Moonfolk offering (You may cast this card any time you could cast an instant by sacrificing a Moonfolk and paying the difference in mana costs between this and the sacrificed Moonfolk. Mana cost includes color.)
this.addAbility(new OfferingAbility("Moonfolk"));
// Flying
this.addAbility(FlyingAbility.getInstance());
// {1}: Put up to two land cards from your hand onto the battlefield tapped.
Ability ability = new SimpleActivatedAbility(Constants.Zone.BATTLEFIELD, new PatronOfTheMoonEffect(), new ManaCostsImpl("{1}"));
ability.addTarget(new TargetCardInHand(0,2, new FilterLandCard()));
this.addAbility(ability);
}
public PatronOfTheMoon(final PatronOfTheMoon card) {
super(card);
}
@Override
public PatronOfTheMoon copy() {
return new PatronOfTheMoon(this);
}
}
class PatronOfTheMoonEffect extends OneShotEffect<PatronOfTheMoonEffect> {
PatronOfTheMoonEffect() {
super(Constants.Outcome.PutLandInPlay);
staticText = "Put up to two land cards from your hand onto the battlefield tapped";
}
PatronOfTheMoonEffect(final PatronOfTheMoonEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
for (UUID cardId : targetPointer.getTargets(game, source)) {
Card c = game.getCard(cardId);
if (c != null) {
c.moveToZone(Constants.Zone.BATTLEFIELD, source.getSourceId(), game, false);
Permanent land = game.getPermanent(cardId);
if (land != null) {
land.setTapped(true);
}
}
}
return true;
}
@Override
public PatronOfTheMoonEffect copy() {
return new PatronOfTheMoonEffect(this);
}
}

View file

@ -0,0 +1,115 @@
/*
* 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.betrayersofkamigawa;
import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.LoseLifeTargetEffect;
import mage.abilities.keyword.OfferingAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.events.ZoneChangeEvent;
import mage.target.targetpointer.FixedTarget;
/**
* @author LevelX2
*/
public class PatronOfTheNezumi extends CardImpl<PatronOfTheNezumi> {
public PatronOfTheNezumi(UUID ownerId) {
super(ownerId, 77, "Patron of the Nezumi", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{5}{B}{B}");
this.expansionSetCode = "BOK";
this.supertype.add("Legendary");
this.subtype.add("Spirit");
this.color.setBlack(true);
this.power = new MageInt(6);
this.toughness = new MageInt(6);
// Rat offering (You may cast this card any time you could cast an instant by sacrificing a Rat and paying the difference in mana costs between this and the sacrificed Rat. Mana cost includes color.)
this.addAbility(new OfferingAbility("Rat"));
// Whenever a permanent is put into an opponent's graveyard, that player loses 1 life.
this.addAbility(new PatronOfTheNezumiTriggeredAbility(new LoseLifeTargetEffect(1)));
}
public PatronOfTheNezumi(final PatronOfTheNezumi card) {
super(card);
}
@Override
public PatronOfTheNezumi copy() {
return new PatronOfTheNezumi(this);
}
}
class PatronOfTheNezumiTriggeredAbility extends TriggeredAbilityImpl<PatronOfTheNezumiTriggeredAbility> {
public PatronOfTheNezumiTriggeredAbility(Effect effect) {
super(Zone.BATTLEFIELD, effect, false);
}
public PatronOfTheNezumiTriggeredAbility(final PatronOfTheNezumiTriggeredAbility ability) {
super(ability);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == EventType.ZONE_CHANGE) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
if (zEvent.getFromZone() == Zone.BATTLEFIELD
&& zEvent.getToZone() == Zone.GRAVEYARD) {
Card card = game.getCard(zEvent.getTargetId());
if (card != null && game.getOpponents(controllerId).contains(card.getOwnerId())) {
this.getEffects().get(0).setTargetPointer(new FixedTarget(zEvent.getPlayerId()));
return true;
}
}
}
return false;
}
@Override
public String getRule() {
return "Whenever a permanent is put into an opponent's graveyard, that player loses 1 life.";
}
@Override
public PatronOfTheNezumiTriggeredAbility copy() {
return new PatronOfTheNezumiTriggeredAbility(this);
}
}

View file

@ -0,0 +1,120 @@
/*
* 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.betrayersofkamigawa;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.ActivateOncePerTurnActivatedAbility;
import mage.abilities.effects.OneShotEffect;
import mage.ObjectColor;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.keyword.OfferingAbility;
import mage.cards.CardImpl;
import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.filter.predicate.mageobject.NamePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
* @author LevelX2
*/
public class PatronOfTheOrochi extends CardImpl<PatronOfTheOrochi> {
public PatronOfTheOrochi(UUID ownerId) {
super(ownerId, 138, "Patron of the Orochi", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{6}{G}{G}");
this.expansionSetCode = "BOK";
this.supertype.add("Legendary");
this.subtype.add("Spirit");
this.color.setGreen(true);
this.power = new MageInt(7);
this.toughness = new MageInt(7);
// Snake offering (You may cast this card any time you could cast an instant by sacrificing a Snake and paying the difference in mana costs between this and the sacrificed Snake. Mana cost includes color.)
this.addAbility(new OfferingAbility("Snake"));
// {T}: Untap all Forests and all green creatures. Activate this ability only once each turn.
this.addAbility(new ActivateOncePerTurnActivatedAbility(Constants.Zone.BATTLEFIELD, new PatronOfTheOrochiEffect(), new TapSourceCost()));
}
public PatronOfTheOrochi(final PatronOfTheOrochi card) {
super(card);
}
@Override
public PatronOfTheOrochi copy() {
return new PatronOfTheOrochi(this);
}
}
class PatronOfTheOrochiEffect extends OneShotEffect<PatronOfTheOrochiEffect> {
private static final FilterPermanent filter = new FilterPermanent();
static {
filter.add(Predicates.or( new NamePredicate("Forest"),
Predicates.and(new CardTypePredicate(CardType.CREATURE),
new ColorPredicate(ObjectColor.GREEN))
));
}
public PatronOfTheOrochiEffect() {
super(Constants.Outcome.Untap);
staticText = "Untap all Forests and all green creatures";
}
public PatronOfTheOrochiEffect(final PatronOfTheOrochiEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
for (Permanent permanent: game.getBattlefield().getAllActivePermanents(filter, game)) {
permanent.untap(game);
}
return true;
}
return false;
}
@Override
public PatronOfTheOrochiEffect copy() {
return new PatronOfTheOrochiEffect(this);
}
}

View file

@ -0,0 +1,244 @@
/*
* 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 LIAB8LE 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.betrayersofkamigawa;
import java.util.List;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.MageObject;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.costs.AlternativeCost;
import mage.abilities.costs.AlternativeCostImpl;
import mage.abilities.costs.Cost;
import mage.abilities.costs.Costs;
import mage.abilities.costs.common.ExileFromHandCost;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.PreventionEffectImpl;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.filter.predicate.other.OwnerPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetSource;
import mage.target.common.TargetCardInHand;
import mage.target.common.TargetCreatureOrPlayer;
/**
*
* @author LevelX2
*/
public class ShiningShoal extends CardImpl<ShiningShoal> {
private static final String ALTERNATIVE_COST_DESCRIPTION = "You may exile a white card with converted mana cost X from your hand rather than pay Shining Shoal's mana cost";
private static final FilterCard filter = new FilterCard("white card from your hand");
static {
filter.add(new ColorPredicate(ObjectColor.WHITE));
filter.add(new OwnerPredicate(Constants.TargetController.YOU));
}
public ShiningShoal(UUID ownerId) {
super(ownerId, 21, "Shining Shoal", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{X}{W}{W}");
this.expansionSetCode = "BOK";
this.subtype.add("Arcane");
this.color.setWhite(true);
// You may exile a white card with converted mana cost X from your hand rather than pay Shining Shoal's mana cost
this.getSpellAbility().addAlternativeCost(new AlternativeCostImpl(ALTERNATIVE_COST_DESCRIPTION, new ExileFromHandCost(new TargetCardInHand(filter))));
// The next X damage that a source of your choice would deal to you and/or creatures you control this turn is dealt to target creature or player instead.
this.getSpellAbility().addEffect(new ShiningShoalPreventDamageTargetEffect(Constants.Duration.EndOfTurn, new ShiningShoalVariableValue()));
this.getSpellAbility().addTarget(new TargetSource());
this.getSpellAbility().addTarget(new TargetCreatureOrPlayer());
}
public ShiningShoal(final ShiningShoal card) {
super(card);
}
@Override
public ShiningShoal copy() {
return new ShiningShoal(this);
}
}
class ShiningShoalVariableValue implements DynamicValue {
@Override
public int calculate(Game game, Ability sourceAbility) {
List<AlternativeCost> aCosts = sourceAbility.getAlternativeCosts();
for (AlternativeCost aCost: aCosts) {
if (aCost.isPaid()) {
Costs aCostsList = (Costs) aCost;
for (int x=0; x < aCostsList.size(); x++) {
Cost cost = (Cost) aCostsList.get(x);
if (cost instanceof ExileFromHandCost) {
int xMana = 0;
for (Card card : ((ExileFromHandCost) cost).getCards()) {
xMana += card.getManaCost().convertedManaCost();
}
return xMana;
}
}
}
}
return sourceAbility.getManaCostsToPay().getX();
}
@Override
public DynamicValue clone() {
return new ShiningShoalVariableValue();
}
@Override
public String toString() {
return "X";
}
@Override
public String getMessage() {
return "";
}
}
class ShiningShoalPreventDamageTargetEffect extends PreventionEffectImpl<ShiningShoalPreventDamageTargetEffect> {
private DynamicValue dynamicAmount;
private int amount;
public ShiningShoalPreventDamageTargetEffect(Constants.Duration duration, DynamicValue dynamicAmount) {
super(duration);
this.dynamicAmount = dynamicAmount;
staticText = "The next X damage that a source of your choice would deal to you and/or creatures you control this turn is dealt to target creature or player instead";
}
public ShiningShoalPreventDamageTargetEffect(final ShiningShoalPreventDamageTargetEffect effect) {
super(effect);
this.amount = effect.amount;
this.dynamicAmount = effect.dynamicAmount;
}
@Override
public ShiningShoalPreventDamageTargetEffect copy() {
return new ShiningShoalPreventDamageTargetEffect(this);
}
@Override
public void init(Ability source, Game game) {
this.amount = dynamicAmount.calculate(game, source);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), event.getAmount(), false);
if (!game.replaceEvent(preventEvent)) {
int prevented = 0;
if (event.getAmount() >= this.amount) {
int damage = amount;
event.setAmount(event.getAmount() - amount);
this.used = true;
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), damage));
prevented = damage;
} else {
int damage = event.getAmount();
event.setAmount(0);
amount -= damage;
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), damage));
prevented = damage;
}
// deal damage now
if (prevented > 0) {
UUID redirectTo = source.getTargets().get(1).getFirstTarget();
Permanent permanent = game.getPermanent(redirectTo);
if (permanent != null) {
game.informPlayers("Dealing " + prevented + " to " + permanent.getName() + " instead");
// keep the original source id as it is redirecting
event.getAppliedEffects().add(getId());
permanent.damage(prevented, event.getSourceId(), game, true, false, event.getAppliedEffects());
}
Player player = game.getPlayer(redirectTo);
if (player != null) {
game.informPlayers("Dealing " + prevented + " to " + player.getName() + " instead");
// keep the original source id as it is redirecting
event.getAppliedEffects().add(getId());
player.damage(prevented, event.getSourceId(), game, true, false, event.getAppliedEffects());
}
}
}
return false;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (!this.used && super.applies(event, source, game) && !event.getAppliedEffects().contains(getId())) {
// check source
MageObject object = game.getObject(event.getSourceId());
if (object == null) {
game.informPlayers("Couldn't find source of damage");
return false;
}
if (!object.getId().equals(source.getFirstTarget())) {
return false;
}
// check target
// check creature first
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null && permanent.getCardType().contains(CardType.CREATURE)) {
if (permanent.getControllerId().equals(source.getControllerId())) {
// it's your creature
return true;
}
}
// check player
Player player = game.getPlayer(event.getTargetId());
if (player != null) {
if (player.getId().equals(source.getControllerId())) {
// it is you
return true;
}
}
}
return false;
}
}

View file

@ -0,0 +1,127 @@
/*
* 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 LIAB8LE 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.betrayersofkamigawa;
import java.util.List;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.costs.AlternativeCost;
import mage.abilities.costs.AlternativeCostImpl;
import mage.abilities.costs.Cost;
import mage.abilities.costs.Costs;
import mage.abilities.costs.common.ExileFromHandCost;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.SignInversionDynamicValue;
import mage.abilities.effects.common.continious.BoostTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.filter.predicate.other.OwnerPredicate;
import mage.game.Game;
import mage.target.common.TargetCardInHand;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author LevelX2
*/
public class SickeningShoal extends CardImpl<SickeningShoal> {
private static final String ALTERNATIVE_COST_DESCRIPTION = "You may exile a black card with converted mana cost X from your hand rather than pay Sickening Shoal's mana cost";
private static final FilterCard filter = new FilterCard("black card from your hand");
static {
filter.add(new ColorPredicate(ObjectColor.BLACK));
filter.add(new OwnerPredicate(Constants.TargetController.YOU));
}
public SickeningShoal(UUID ownerId) {
super(ownerId, 82, "Sickening Shoal", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{X}{B}{B}");
this.expansionSetCode = "BOK";
this.subtype.add("Arcane");
this.color.setBlack(true);
// You may exile a black card with converted mana cost X from your hand rather than pay Sickening Shoal's mana cost.
this.getSpellAbility().addAlternativeCost(new AlternativeCostImpl(ALTERNATIVE_COST_DESCRIPTION, new ExileFromHandCost(new TargetCardInHand(filter))));
// Target creature gets -X/-X until end of turn.
DynamicValue x = new SignInversionDynamicValue(new SickeningShoalVariableValue());
this.getSpellAbility().addEffect(new BoostTargetEffect(x, x, Constants.Duration.EndOfTurn, true));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
public SickeningShoal(final SickeningShoal card) {
super(card);
}
@Override
public SickeningShoal copy() {
return new SickeningShoal(this);
}
}
// ConvertedManaExileFromHandOrVariableManaValue
class SickeningShoalVariableValue implements DynamicValue {
@Override
public int calculate(Game game, Ability sourceAbility) {
for (AlternativeCost aCost: (List<AlternativeCost>) sourceAbility.getAlternativeCosts()) {
if (aCost.isPaid()) {
for (int x=0; x < ((Costs) aCost).size(); x++) {
Cost cost = (Cost) ((Costs) aCost).get(x);
if (cost instanceof ExileFromHandCost) {
int xValue = 0;
for (Card card : ((ExileFromHandCost) cost).getCards()) {
xValue += card.getManaCost().convertedManaCost();
}
return xValue;
}
}
}
}
return sourceAbility.getManaCostsToPay().getX();
}
@Override
public DynamicValue clone() {
return new SickeningShoalVariableValue();
}
@Override
public String toString() {
return "X";
}
@Override
public String getMessage() {
return "";
}
}