1
0
Fork 0
mirror of https://github.com/correl/mage.git synced 2025-04-06 01:04:10 -09:00

* Added card hints to Avatar of Might, Avatar of Will, Avatar of Woe, Dusk Feaster, Rekindled Flame;

* Refactor: removed custom spell cost reduction effects;
This commit is contained in:
Oleg Agafonov 2020-06-27 05:36:04 +04:00
parent c46e5d2399
commit 2252648f01
13 changed files with 167 additions and 411 deletions

View file

@ -1,27 +1,30 @@
package mage.cards.a; package mage.cards.a;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.Mana;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.cost.CostModificationEffectImpl; import mage.abilities.condition.Condition;
import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect;
import mage.abilities.hint.ConditionHint;
import mage.abilities.keyword.TrampleAbility; import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class AvatarOfMight extends CardImpl { public final class AvatarOfMight extends CardImpl {
private static final Condition condition = new AvatarOfMightCondition();
public AvatarOfMight(UUID ownerId, CardSetInfo setInfo) { public AvatarOfMight(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{G}{G}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{G}{G}");
this.subtype.add(SubType.AVATAR); this.subtype.add(SubType.AVATAR);
@ -29,7 +32,10 @@ public final class AvatarOfMight extends CardImpl {
this.toughness = new MageInt(8); this.toughness = new MageInt(8);
// If an opponent controls at least four more creatures than you, Avatar of Might costs {6} less to cast. // If an opponent controls at least four more creatures than you, Avatar of Might costs {6} less to cast.
this.addAbility(new SimpleStaticAbility(Zone.ALL, new AvatarOfMightCostReductionEffect())); this.addAbility(new SimpleStaticAbility(Zone.ALL, new SpellCostReductionSourceEffect(6, condition)
.setText("If an opponent controls at least four more creatures than you, {this} costs {6} less to cast"))
.addHint(new ConditionHint(condition, "Opponent controls at least four more creatures than you"))
);
// Trample // Trample
this.addAbility(TrampleAbility.getInstance()); this.addAbility(TrampleAbility.getInstance());
@ -45,49 +51,17 @@ public final class AvatarOfMight extends CardImpl {
} }
} }
class AvatarOfMightCostReductionEffect extends CostModificationEffectImpl { class AvatarOfMightCondition implements Condition {
AvatarOfMightCostReductionEffect() {
super(Duration.Custom, Outcome.Benefit, CostModificationType.REDUCE_COST);
staticText = "If an opponent controls at least four more creatures than you, {this} costs {6} less to cast";
}
AvatarOfMightCostReductionEffect(final AvatarOfMightCostReductionEffect effect) {
super(effect);
}
@Override @Override
public boolean apply(Game game, Ability source, Ability abilityToModify) { public boolean apply(Game game, Ability source) {
SpellAbility spellAbility = (SpellAbility) abilityToModify; int creatures = game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game);
Mana mana = spellAbility.getManaCostsToPay().getMana(); for (UUID playerId : game.getOpponents(source.getControllerId())) {
if (mana.getGeneric() > 0) { Player opponent = game.getPlayer(playerId);
int newCount = mana.getGeneric() - 6; if (opponent != null && game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURE, opponent.getId(), game) >= creatures + 4) {
if (newCount < 0) { return true;
newCount = 0;
}
mana.setGeneric(newCount);
spellAbility.getManaCostsToPay().load(mana.toString());
return true;
}
return false;
}
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
if (abilityToModify.getSourceId().equals(source.getSourceId()) && (abilityToModify instanceof SpellAbility)) {
int creatures = game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game);
for (UUID playerId : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(playerId);
if (opponent != null && game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURE, opponent.getId(), game) >= creatures + 4) {
return true;
}
} }
} }
return false; return false;
} }
@Override
public AvatarOfMightCostReductionEffect copy() {
return new AvatarOfMightCostReductionEffect(this);
}
} }

View file

@ -1,22 +1,20 @@
package mage.cards.a; package mage.cards.a;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.cost.CostModificationEffectImpl; import mage.abilities.condition.common.OpponentHasNoCardsInHandCondition;
import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect;
import mage.abilities.hint.ConditionHint;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.CardType;
import mage.game.Game; import mage.constants.SubType;
import mage.players.Player; import mage.constants.Zone;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class AvatarOfWill extends CardImpl { public final class AvatarOfWill extends CardImpl {
@ -28,7 +26,10 @@ public final class AvatarOfWill extends CardImpl {
this.toughness = new MageInt(6); this.toughness = new MageInt(6);
// If an opponent has no cards in hand, Avatar of Will costs {6} less to cast. // If an opponent has no cards in hand, Avatar of Will costs {6} less to cast.
this.addAbility(new SimpleStaticAbility(Zone.ALL, new AvatarOfWillCostReductionEffect())); this.addAbility(new SimpleStaticAbility(Zone.ALL, new SpellCostReductionSourceEffect(6, OpponentHasNoCardsInHandCondition.instance)
.setText("If an opponent has no cards in hand, Avatar of Will costs {6} less to cast")
).addHint(new ConditionHint(OpponentHasNoCardsInHandCondition.instance, "Opponent has no cards in hand"))
);
// Flying // Flying
this.addAbility(FlyingAbility.getInstance()); this.addAbility(FlyingAbility.getInstance());
@ -43,49 +44,3 @@ public final class AvatarOfWill extends CardImpl {
return new AvatarOfWill(this); return new AvatarOfWill(this);
} }
} }
class AvatarOfWillCostReductionEffect extends CostModificationEffectImpl {
AvatarOfWillCostReductionEffect() {
super(Duration.Custom, Outcome.Benefit, CostModificationType.REDUCE_COST);
staticText = "If an opponent has no cards in hand, {this} costs {6} less to cast";
}
AvatarOfWillCostReductionEffect(final AvatarOfWillCostReductionEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source, Ability abilityToModify) {
SpellAbility spellAbility = (SpellAbility) abilityToModify;
Mana mana = spellAbility.getManaCostsToPay().getMana();
if (mana.getGeneric() > 0) {
int newCount = mana.getGeneric() - 6;
if (newCount < 0) {
newCount = 0;
}
mana.setGeneric(newCount);
spellAbility.getManaCostsToPay().load(mana.toString());
return true;
}
return false;
}
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
if (abilityToModify.getSourceId().equals(source.getSourceId())) {
for (UUID playerId : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(playerId);
if (opponent != null && opponent.getHand().isEmpty()) {
return true;
}
}
}
return false;
}
@Override
public AvatarOfWillCostReductionEffect copy() {
return new AvatarOfWillCostReductionEffect(this);
}
}

View file

@ -1,30 +1,36 @@
package mage.cards.a; package mage.cards.a;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.Mana;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.CardsInAllGraveyardsCount; import mage.abilities.dynamicvalue.common.CardsInAllGraveyardsCount;
import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.cost.CostModificationEffectImpl; import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect;
import mage.abilities.hint.ValueHint;
import mage.abilities.keyword.FearAbility; import mage.abilities.keyword.FearAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.Game; import mage.game.Game;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/** /**
*
* @author emerald000 * @author emerald000
*/ */
public final class AvatarOfWoe extends CardImpl { public final class AvatarOfWoe extends CardImpl {
protected static final DynamicValue graveyardCount = new CardsInAllGraveyardsCount(StaticFilters.FILTER_CARD_CREATURE);
private static final Condition condition = new AvatarOfWoeCondition();
public AvatarOfWoe(UUID ownerId, CardSetInfo setInfo) { public AvatarOfWoe(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{B}{B}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{B}{B}");
this.subtype.add(SubType.AVATAR); this.subtype.add(SubType.AVATAR);
@ -32,12 +38,15 @@ public final class AvatarOfWoe extends CardImpl {
this.toughness = new MageInt(5); this.toughness = new MageInt(5);
// If there are ten or more creature cards total in all graveyards, Avatar of Woe costs {6} less to cast. // If there are ten or more creature cards total in all graveyards, Avatar of Woe costs {6} less to cast.
this.addAbility(new SimpleStaticAbility(Zone.ALL, new AvatarOfWoeCostReductionEffect())); this.addAbility(new SimpleStaticAbility(Zone.ALL, new SpellCostReductionSourceEffect(6, condition)
.setText("If there are ten or more creature cards total in all graveyards, {this} costs {6} less to cast"))
.addHint(new ValueHint("Creature cards in all graveyards", graveyardCount))
);
// Fear // Fear
this.addAbility(FearAbility.getInstance()); this.addAbility(FearAbility.getInstance());
// {tap}: Destroy target creature. It can't be regenerated. // {T}: Destroy target creature. It can't be regenerated.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(true), new TapSourceCost()); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(true), new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent()); ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability); this.addAbility(ability);
@ -53,42 +62,13 @@ public final class AvatarOfWoe extends CardImpl {
} }
} }
class AvatarOfWoeCostReductionEffect extends CostModificationEffectImpl { class AvatarOfWoeCondition implements Condition {
AvatarOfWoeCostReductionEffect() {
super(Duration.Custom, Outcome.Benefit, CostModificationType.REDUCE_COST);
staticText = "If there are ten or more creature cards total in all graveyards, {this} costs {6} less to cast";
}
AvatarOfWoeCostReductionEffect(final AvatarOfWoeCostReductionEffect effect) {
super(effect);
}
@Override @Override
public boolean apply(Game game, Ability source, Ability abilityToModify) { public boolean apply(Game game, Ability source) {
SpellAbility spellAbility = (SpellAbility) abilityToModify; if (AvatarOfWoe.graveyardCount.calculate(game, source, null) >= 10) {
Mana mana = spellAbility.getManaCostsToPay().getMana();
if (mana.getGeneric() > 0) {
int newCount = mana.getGeneric() - 6;
if (newCount < 0) {
newCount = 0;
}
mana.setGeneric(newCount);
spellAbility.getManaCostsToPay().load(mana.toString());
return true; return true;
} }
return false; return false;
} }
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
return abilityToModify.getSourceId().equals(source.getSourceId())
&& (abilityToModify instanceof SpellAbility)
&& new CardsInAllGraveyardsCount(StaticFilters.FILTER_CARD_CREATURE).calculate(game, source, this) >= 10;
}
@Override
public AvatarOfWoeCostReductionEffect copy() {
return new AvatarOfWoeCostReductionEffect(this);
}
} }

View file

@ -1,17 +1,15 @@
package mage.cards.d; package mage.cards.d;
import mage.MageInt; import mage.MageInt;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.common.DevotionCount; import mage.abilities.dynamicvalue.common.DevotionCount;
import mage.abilities.effects.common.cost.CostModificationEffectImpl; import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.CardType;
import mage.game.Game; import mage.constants.SubType;
import mage.constants.Zone;
import java.util.UUID; import java.util.UUID;
@ -28,7 +26,9 @@ public final class DaybreakChimera extends CardImpl {
this.toughness = new MageInt(3); this.toughness = new MageInt(3);
// This spell costs {X} less to cast, where X is your devotion to white. // This spell costs {X} less to cast, where X is your devotion to white.
this.addAbility(new SimpleStaticAbility(Zone.ALL, new DaybreakChimeraEffect()).addHint(DevotionCount.W.getHint())); this.addAbility(new SimpleStaticAbility(Zone.ALL, new SpellCostReductionSourceEffect(DevotionCount.W))
.addHint(DevotionCount.W.getHint())
);
// Flying // Flying
this.addAbility(FlyingAbility.getInstance()); this.addAbility(FlyingAbility.getInstance());
@ -43,40 +43,3 @@ public final class DaybreakChimera extends CardImpl {
return new DaybreakChimera(this); return new DaybreakChimera(this);
} }
} }
class DaybreakChimeraEffect extends CostModificationEffectImpl {
DaybreakChimeraEffect() {
super(Duration.Custom, Outcome.Benefit, CostModificationType.REDUCE_COST);
staticText = "This spell costs {X} less to cast, where X is your devotion to white. " +
"<i>(Each {W} in the mana costs of permanents you control counts toward your devotion to white.)</i>";
}
private DaybreakChimeraEffect(final DaybreakChimeraEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source, Ability abilityToModify) {
SpellAbility spellAbility = (SpellAbility) abilityToModify;
Mana mana = spellAbility.getManaCostsToPay().getMana();
if (mana.getGeneric() == 0) {
return false;
}
int count = DevotionCount.W.calculate(game, source, this);
mana.setGeneric(Math.max(mana.getGeneric() - count, 0));
spellAbility.getManaCostsToPay().load(mana.toString());
return true;
}
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
return abilityToModify instanceof SpellAbility
&& abilityToModify.getSourceId().equals(source.getSourceId());
}
@Override
public DaybreakChimeraEffect copy() {
return new DaybreakChimeraEffect(this);
}
}

View file

@ -1,16 +1,13 @@
package mage.cards.d; package mage.cards.d;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.common.DevotionCount; import mage.abilities.dynamicvalue.common.DevotionCount;
import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.cost.CostModificationEffectImpl; import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.CardType;
import mage.game.Game; import mage.constants.Zone;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import java.util.UUID; import java.util.UUID;
@ -24,7 +21,7 @@ public final class DragToTheUnderworld extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{B}{B}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{B}{B}");
// This spell costs {X} less to cast, where X is your devotion to black. // This spell costs {X} less to cast, where X is your devotion to black.
this.addAbility(new SimpleStaticAbility(Zone.ALL, new DragToTheUnderworldEffect()) this.addAbility(new SimpleStaticAbility(Zone.ALL, new SpellCostReductionSourceEffect(DevotionCount.B))
.addHint(DevotionCount.B.getHint()) .addHint(DevotionCount.B.getHint())
.setRuleAtTheTop(true)); .setRuleAtTheTop(true));
@ -41,41 +38,4 @@ public final class DragToTheUnderworld extends CardImpl {
public DragToTheUnderworld copy() { public DragToTheUnderworld copy() {
return new DragToTheUnderworld(this); return new DragToTheUnderworld(this);
} }
} }
class DragToTheUnderworldEffect extends CostModificationEffectImpl {
DragToTheUnderworldEffect() {
super(Duration.Custom, Outcome.Benefit, CostModificationType.REDUCE_COST);
staticText = "This spell costs {X} less to cast, where X is your devotion to black. " +
"<i>(Each {B} in the mana costs of permanents you control counts toward your devotion to black.)</i> ";
}
private DragToTheUnderworldEffect(final DragToTheUnderworldEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source, Ability abilityToModify) {
SpellAbility spellAbility = (SpellAbility) abilityToModify;
Mana mana = spellAbility.getManaCostsToPay().getMana();
if (mana.getGeneric() == 0) {
return false;
}
int count = DevotionCount.B.calculate(game, source, this);
mana.setGeneric(Math.max(mana.getGeneric() - count, 0));
spellAbility.getManaCostsToPay().load(mana.toString());
return true;
}
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
return abilityToModify instanceof SpellAbility
&& abilityToModify.getSourceId().equals(source.getSourceId());
}
@Override
public DragToTheUnderworldEffect copy() {
return new DragToTheUnderworldEffect(this);
}
}

View file

@ -1,36 +1,38 @@
package mage.cards.d; package mage.cards.d;
import java.util.EnumSet;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.Mana;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.cost.CostModificationEffectImpl; import mage.abilities.condition.common.DeliriumCondition;
import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect;
import mage.abilities.hint.common.DeliriumHint;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.AbilityWord;
import mage.game.Game; import mage.constants.CardType;
import mage.players.Player; import mage.constants.SubType;
import mage.constants.Zone;
import java.util.UUID;
/** /**
*
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com) * @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
*/ */
public final class DuskFeaster extends CardImpl { public final class DuskFeaster extends CardImpl {
public DuskFeaster(UUID ownerId, CardSetInfo setInfo) { public DuskFeaster(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{B}{B}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{B}");
this.subtype.add(SubType.VAMPIRE); this.subtype.add(SubType.VAMPIRE);
this.power = new MageInt(4); this.power = new MageInt(4);
this.toughness = new MageInt(5); this.toughness = new MageInt(5);
// Delirium - Dusk Feaster costs {2} less to cast if there are four or more card types among cards in your graveyard. // <i>Delirium</i> &mdash; This spell costs {2} less to cast if there are four or more card types among cards in your graveyard.
this.addAbility(new SimpleStaticAbility(Zone.ALL, new DuskFeasterCostReductionEffect())); Ability ability = new SimpleStaticAbility(Zone.ALL, new SpellCostReductionSourceEffect(2, DeliriumCondition.instance));
ability.setRuleAtTheTop(true);
ability.setAbilityWord(AbilityWord.DELIRIUM);
ability.addHint(DeliriumHint.instance);
this.addAbility(ability);
// Flying // Flying
this.addAbility(FlyingAbility.getInstance()); this.addAbility(FlyingAbility.getInstance());
@ -44,56 +46,4 @@ public final class DuskFeaster extends CardImpl {
public DuskFeaster copy() { public DuskFeaster copy() {
return new DuskFeaster(this); return new DuskFeaster(this);
} }
}
class DuskFeasterCostReductionEffect extends CostModificationEffectImpl {
DuskFeasterCostReductionEffect() {
super(Duration.Custom, Outcome.Benefit, CostModificationType.REDUCE_COST);
staticText = "<i>Delirium</i> &mdash; {this} costs {2} less to cast if there are four or more card types among cards in your graveyard";
}
DuskFeasterCostReductionEffect(final DuskFeasterCostReductionEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source, Ability abilityToModify) {
SpellAbility spellAbility = (SpellAbility) abilityToModify;
Mana mana = spellAbility.getManaCostsToPay().getMana();
if (mana.getGeneric() > 0) {
int newCount = mana.getGeneric() - 2;
if (newCount < 0) {
newCount = 0;
}
mana.setGeneric(newCount);
spellAbility.getManaCostsToPay().load(mana.toString());
return true;
}
return false;
}
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
boolean hasDelirium = false;
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
EnumSet<CardType> foundCardTypes = EnumSet.noneOf(CardType.class);
for (Card card : controller.getGraveyard().getCards(game)) {
foundCardTypes.addAll(card.getCardType());
}
int number = foundCardTypes.size();
hasDelirium = number > 3;
}
return abilityToModify.getSourceId().equals(source.getSourceId())
&& (abilityToModify instanceof SpellAbility)
&& hasDelirium;
}
@Override
public DuskFeasterCostReductionEffect copy() {
return new DuskFeasterCostReductionEffect(this);
}
} }

View file

@ -1,7 +1,5 @@
package mage.cards.g; package mage.cards.g;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
@ -16,14 +14,15 @@ import mage.filter.common.FilterControlledPermanent;
import mage.game.Game; import mage.game.Game;
import mage.util.CardUtil; import mage.util.CardUtil;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class GearseekerSerpent extends CardImpl { public final class GearseekerSerpent extends CardImpl {
public GearseekerSerpent(UUID ownerId, CardSetInfo setInfo) { public GearseekerSerpent(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{U}{U}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}{U}");
this.subtype.add(SubType.SERPENT); this.subtype.add(SubType.SERPENT);
this.power = new MageInt(5); this.power = new MageInt(5);
this.toughness = new MageInt(6); this.toughness = new MageInt(6);
@ -70,7 +69,6 @@ class GearseekerSerpentCostReductionEffect extends CostModificationEffectImpl {
if (count > 0) { if (count > 0) {
CardUtil.reduceCost(abilityToModify, count); CardUtil.reduceCost(abilityToModify, count);
} }
return true; return true;
} }

View file

@ -1,16 +1,15 @@
package mage.cards.m; package mage.cards.m;
import mage.MageInt; import mage.MageInt;
import mage.Mana;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.common.DevotionCount; import mage.abilities.dynamicvalue.common.DevotionCount;
import mage.abilities.effects.common.cost.CostModificationEffectImpl; import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.CardType;
import mage.game.Game; import mage.constants.SubType;
import mage.constants.Zone;
import java.util.UUID; import java.util.UUID;
@ -26,9 +25,11 @@ public final class MarshmistTitan extends CardImpl {
this.power = new MageInt(4); this.power = new MageInt(4);
this.toughness = new MageInt(5); this.toughness = new MageInt(5);
// Marshmist Titan costs {X} less to cast, where X is your devotion to black. // This spell costs {X} less to cast, where X is your devotion to black.
this.addAbility(new SimpleStaticAbility(Zone.ALL, new MarshmistTitanCostReductionEffect()) Ability ability = new SimpleStaticAbility(Zone.ALL, new SpellCostReductionSourceEffect(DevotionCount.B));
.addHint(DevotionCount.B.getHint())); ability.addHint(DevotionCount.B.getHint());
this.addAbility(ability);
} }
private MarshmistTitan(final MarshmistTitan card) { private MarshmistTitan(final MarshmistTitan card) {
@ -40,40 +41,3 @@ public final class MarshmistTitan extends CardImpl {
return new MarshmistTitan(this); return new MarshmistTitan(this);
} }
} }
class MarshmistTitanCostReductionEffect extends CostModificationEffectImpl {
MarshmistTitanCostReductionEffect() {
super(Duration.Custom, Outcome.Benefit, CostModificationType.REDUCE_COST);
staticText = "This spell costs {X} less to cast, where X is your devotion to black. " +
"<i>(Each {B} in the mana costs of permanents you control counts toward your devotion to black.)</i> ";
}
private MarshmistTitanCostReductionEffect(final MarshmistTitanCostReductionEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source, Ability abilityToModify) {
SpellAbility spellAbility = (SpellAbility) abilityToModify;
Mana mana = spellAbility.getManaCostsToPay().getMana();
if (mana.getGeneric() == 0) {
return false;
}
int count = DevotionCount.B.calculate(game, source, this);
mana.setGeneric(Math.max(mana.getGeneric() - count, 0));
spellAbility.getManaCostsToPay().load(mana.toString());
return true;
}
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
return abilityToModify instanceof SpellAbility
&& abilityToModify.getSourceId().equals(source.getSourceId());
}
@Override
public MarshmistTitanCostReductionEffect copy() {
return new MarshmistTitanCostReductionEffect(this);
}
}

View file

@ -1,30 +1,26 @@
package mage.cards.r; package mage.cards.r;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.condition.Condition; import mage.abilities.condition.common.OpponentHasNoCardsInHandCondition;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect; import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect;
import mage.abilities.hint.ConditionHint;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.TargetController; import mage.constants.TargetController;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetAnyTarget; import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/** /**
*
* @author jeffwadsworth * @author jeffwadsworth
*/ */
public final class RekindledFlame extends CardImpl { public final class RekindledFlame extends CardImpl {
static final String rule = "if an opponent has no cards in hand, you may return Rekindled Flame from your graveyard to your hand";
public RekindledFlame(UUID ownerId, CardSetInfo setInfo) { public RekindledFlame(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}{R}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}{R}");
@ -34,10 +30,10 @@ public final class RekindledFlame extends CardImpl {
// At the beginning of your upkeep, if an opponent has no cards in hand, you may return Rekindled Flame from your graveyard to your hand. // At the beginning of your upkeep, if an opponent has no cards in hand, you may return Rekindled Flame from your graveyard to your hand.
Ability ability = new ConditionalInterveningIfTriggeredAbility( Ability ability = new ConditionalInterveningIfTriggeredAbility(
new BeginningOfUpkeepTriggeredAbility( new BeginningOfUpkeepTriggeredAbility(Zone.GRAVEYARD, new ReturnSourceFromGraveyardToHandEffect(), TargetController.YOU, true),
Zone.GRAVEYARD, new ReturnSourceFromGraveyardToHandEffect(), TargetController.YOU, true OpponentHasNoCardsInHandCondition.instance,
), "If an opponent has no cards in hand, you may return Rekindled Flame from your graveyard to your hand.");
new OpponentHasNoCardsInHandCondition(), rule); ability.addHint(new ConditionHint(OpponentHasNoCardsInHandCondition.instance, "Opponent has no cards in hand"));
ability.setRuleVisible(true); ability.setRuleVisible(true);
this.addAbility(ability); this.addAbility(ability);
@ -51,21 +47,4 @@ public final class RekindledFlame extends CardImpl {
public RekindledFlame copy() { public RekindledFlame copy() {
return new RekindledFlame(this); return new RekindledFlame(this);
} }
} }
class OpponentHasNoCardsInHandCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
for (UUID playerId : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(playerId);
if (opponent != null && opponent.getHand().isEmpty()) {
return true;
}
}
}
return false;
}
}

View file

@ -0,0 +1,36 @@
package mage.abilities.condition.common;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
* @author JayDi85
*/
public enum OpponentHasNoCardsInHandCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
for (UUID playerId : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(playerId);
if (opponent != null && opponent.getHand().isEmpty()) {
return true;
}
}
}
return false;
}
@Override
public String toString() {
return "an opponent has no cards in hand";
}
}

View file

@ -1,6 +1,5 @@
package mage.abilities.effects.common; package mage.abilities.effects.common;
import mage.Mana;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.SpellAbility; import mage.abilities.SpellAbility;
import mage.abilities.effects.common.cost.CostModificationEffectImpl; import mage.abilities.effects.common.cost.CostModificationEffectImpl;
@ -9,9 +8,10 @@ import mage.constants.Duration;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.filter.common.FilterControlledPermanent; import mage.filter.common.FilterControlledPermanent;
import mage.game.Game; import mage.game.Game;
import mage.util.CardUtil;
public class AffinityEffect extends CostModificationEffectImpl { public class AffinityEffect extends CostModificationEffectImpl {
private final FilterControlledPermanent filter; private final FilterControlledPermanent filter;
public AffinityEffect(FilterControlledPermanent affinityFilter) { public AffinityEffect(FilterControlledPermanent affinityFilter) {
@ -27,20 +27,12 @@ public class AffinityEffect extends CostModificationEffectImpl {
@Override @Override
public boolean apply(Game game, Ability source, Ability abilityToModify) { public boolean apply(Game game, Ability source, Ability abilityToModify) {
SpellAbility spellAbility = (SpellAbility)abilityToModify; // abilityToModify.getControllerId() works with Sen Triplets and in multiplayer games, see https://github.com/magefree/mage/issues/5931
Mana mana = spellAbility.getManaCostsToPay().getMana(); int count = game.getBattlefield().getActivePermanents(filter, abilityToModify.getControllerId(), source.getId(), game).size();
if (mana.getGeneric() > 0) { if (count > 0) {
// the following works with Sen Triplets and in multiplayer games CardUtil.reduceCost(abilityToModify, count);
int count = game.getBattlefield().getActivePermanents(filter, abilityToModify.getControllerId(), source.getId(), game).size();
int newCount = mana.getGeneric() - count;
if (newCount < 0) {
newCount = 0;
}
mana.setGeneric(newCount);
spellAbility.getManaCostsToPay().load(mana.toString());
return true;
} }
return false; return true;
} }
@Override @Override

View file

@ -5,6 +5,8 @@ import mage.abilities.SpellAbility;
import mage.abilities.condition.Condition; import mage.abilities.condition.Condition;
import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCost;
import mage.abilities.costs.mana.ManaCosts; import mage.abilities.costs.mana.ManaCosts;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.constants.CostModificationType; import mage.constants.CostModificationType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Outcome; import mage.constants.Outcome;
@ -16,7 +18,7 @@ import mage.util.CardUtil;
*/ */
public class SpellCostReductionSourceEffect extends CostModificationEffectImpl { public class SpellCostReductionSourceEffect extends CostModificationEffectImpl {
private final int amount; private final DynamicValue amount;
private ManaCosts<ManaCost> manaCostsToReduce = null; private ManaCosts<ManaCost> manaCostsToReduce = null;
private Condition condition; private Condition condition;
@ -26,7 +28,7 @@ public class SpellCostReductionSourceEffect extends CostModificationEffectImpl {
public SpellCostReductionSourceEffect(ManaCosts<ManaCost> manaCostsToReduce, Condition condition) { public SpellCostReductionSourceEffect(ManaCosts<ManaCost> manaCostsToReduce, Condition condition) {
super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST); super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST);
this.amount = 0; this.amount = StaticValue.get(0);
this.manaCostsToReduce = manaCostsToReduce; this.manaCostsToReduce = manaCostsToReduce;
this.condition = condition; this.condition = condition;
@ -44,19 +46,30 @@ public class SpellCostReductionSourceEffect extends CostModificationEffectImpl {
} }
public SpellCostReductionSourceEffect(int amount) { public SpellCostReductionSourceEffect(int amount) {
this(StaticValue.get(amount), null);
}
public SpellCostReductionSourceEffect(DynamicValue amount) {
this(amount, null); this(amount, null);
} }
public SpellCostReductionSourceEffect(int amount, Condition condition) { public SpellCostReductionSourceEffect(int amount, Condition condition) {
this(StaticValue.get(amount), condition);
}
public SpellCostReductionSourceEffect(DynamicValue amount, Condition condition) {
super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST); super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST);
this.amount = amount; this.amount = amount;
this.condition = condition; this.condition = condition;
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("this spell costs {").append(amount).append("} less to cast"); sb.append("this spell costs {").append(this.amount).append("} less to cast");
if (this.condition != null) { if (this.condition != null) {
sb.append(" ").append(this.condition.toString().startsWith("if ") ? "" : "if "); sb.append(" ").append(this.condition.toString().startsWith("if ") ? "" : "if ");
sb.append(this.condition.toString()); sb.append(this.condition.toString());
} }
if (this.amount.toString().equals("X")) {
sb.append(", where {X} is ").append(this.amount.getMessage());
}
this.staticText = sb.toString(); this.staticText = sb.toString();
} }
@ -72,7 +85,7 @@ public class SpellCostReductionSourceEffect extends CostModificationEffectImpl {
if (manaCostsToReduce != null) { if (manaCostsToReduce != null) {
CardUtil.adjustCost((SpellAbility) abilityToModify, manaCostsToReduce, false); CardUtil.adjustCost((SpellAbility) abilityToModify, manaCostsToReduce, false);
} else { } else {
CardUtil.reduceCost(abilityToModify, this.amount); CardUtil.reduceCost(abilityToModify, this.amount.calculate(game, source, this));
} }
return true; return true;
} }

View file

@ -1,12 +1,12 @@
package mage.abilities.effects.common.cost; package mage.abilities.effects.common.cost;
import mage.Mana;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.SpellAbility; import mage.abilities.SpellAbility;
import mage.constants.CostModificationType; import mage.constants.CostModificationType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.game.Game; import mage.game.Game;
import mage.util.CardUtil;
public class SpellCostReductionSourceForOpponentsEffect extends CostModificationEffectImpl { public class SpellCostReductionSourceForOpponentsEffect extends CostModificationEffectImpl {
@ -25,19 +25,11 @@ public class SpellCostReductionSourceForOpponentsEffect extends CostModification
@Override @Override
public boolean apply(Game game, Ability source, Ability abilityToModify) { public boolean apply(Game game, Ability source, Ability abilityToModify) {
SpellAbility spellAbility = (SpellAbility) abilityToModify; int count = game.getOpponents(source.getControllerId()).size();
Mana mana = spellAbility.getManaCostsToPay().getMana(); if (count > 0) {
if (mana.getGeneric() > 0) { CardUtil.reduceCost(abilityToModify, count);
int count = game.getOpponents(source.getControllerId()).size();
int newCount = mana.getGeneric() - count;
if (newCount < 0) {
newCount = 0;
}
mana.setGeneric(newCount);
spellAbility.getManaCostsToPay().load(mana.toString());
return true;
} }
return false; return true;
} }
@Override @Override