diff --git a/Mage/src/main/java/mage/abilities/Ability.java b/Mage/src/main/java/mage/abilities/Ability.java index e1bb0a5618b..512da5e120a 100644 --- a/Mage/src/main/java/mage/abilities/Ability.java +++ b/Mage/src/main/java/mage/abilities/Ability.java @@ -549,6 +549,8 @@ public interface Ability extends Controllable, Serializable { */ Ability setCostAdjuster(CostAdjuster costAdjuster); + CostAdjuster getCostAdjuster(); + /** * Prepare {X} settings for announce */ diff --git a/Mage/src/main/java/mage/abilities/AbilityImpl.java b/Mage/src/main/java/mage/abilities/AbilityImpl.java index 2fd281c59a8..4a01534e11b 100644 --- a/Mage/src/main/java/mage/abilities/AbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilityImpl.java @@ -1761,6 +1761,11 @@ public abstract class AbilityImpl implements Ability { return this; } + @Override + public CostAdjuster getCostAdjuster() { + return costAdjuster; + } + @Override public void adjustX(Game game) { if (costAdjuster != null) { diff --git a/Mage/src/main/java/mage/abilities/keyword/CastFromGraveyardAbility.java b/Mage/src/main/java/mage/abilities/keyword/CastFromGraveyardAbility.java index 73de96cf5e7..54bbd86d884 100644 --- a/Mage/src/main/java/mage/abilities/keyword/CastFromGraveyardAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/CastFromGraveyardAbility.java @@ -114,6 +114,7 @@ public abstract class CastFromGraveyardAbility extends SpellAbility { spellAbilityCopy.addCost(this.getCosts().copy()); spellAbilityCopy.addCost(this.getManaCosts().copy()); spellAbilityCopy.setSpellAbilityCastMode(this.getSpellAbilityCastMode()); + spellAbilityCopy.setCostAdjuster(this.getCostAdjuster()); spellAbilityToResolve = spellAbilityCopy; ContinuousEffect effect = new CastFromGraveyardReplacementEffect(); effect.setTargetPointer(new FixedTarget(getSourceId(), game.getState().getZoneChangeCounter(getSourceId()))); diff --git a/Mage/src/main/java/mage/abilities/keyword/HarmonizeAbility.java b/Mage/src/main/java/mage/abilities/keyword/HarmonizeAbility.java index d18de35de8c..e4f7b9936e2 100644 --- a/Mage/src/main/java/mage/abilities/keyword/HarmonizeAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/HarmonizeAbility.java @@ -4,15 +4,12 @@ import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.SpellAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.costs.Cost; -import mage.abilities.costs.VariableCostImpl; -import mage.abilities.costs.VariableCostType; +import mage.abilities.costs.CostAdjuster; import mage.abilities.costs.common.TapTargetCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.cost.CostModificationEffectImpl; import mage.cards.Card; -import mage.constants.*; +import mage.constants.Outcome; +import mage.constants.SpellAbilityCastMode; import mage.filter.StaticFilters; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.permanent.PermanentIdPredicate; @@ -23,9 +20,6 @@ import mage.target.TargetPermanent; import mage.target.common.TargetControlledPermanent; import mage.util.CardUtil; -import java.util.Objects; -import java.util.UUID; - /** * @author TheElk801 */ @@ -36,8 +30,7 @@ public class HarmonizeAbility extends CastFromGraveyardAbility { public HarmonizeAbility(Card card, String manaString) { super(card, new ManaCostsImpl<>(manaString), SpellAbilityCastMode.HARMONIZE); - this.addCost(new HarmonizeCost()); - this.addSubAbility(new SimpleStaticAbility(Zone.ALL, new HarmonizeCostReductionEffect()).setRuleVisible(false)); + this.setCostAdjuster(HarmonizeAbilityAdjuster.instance); } private HarmonizeAbility(final HarmonizeAbility ability) { @@ -57,123 +50,45 @@ public class HarmonizeAbility extends CastFromGraveyardAbility { } } -class HarmonizeCostReductionEffect extends CostModificationEffectImpl { - - HarmonizeCostReductionEffect() { - super(Duration.WhileOnStack, Outcome.Benefit, CostModificationType.REDUCE_COST); - } - - private HarmonizeCostReductionEffect(final HarmonizeCostReductionEffect effect) { - super(effect); - } +enum HarmonizeAbilityAdjuster implements CostAdjuster { + instance; @Override - public boolean apply(Game game, Ability source, Ability abilityToModify) { - SpellAbility spellAbility = (SpellAbility) abilityToModify; - int power; + public void reduceCost(Ability ability, Game game) { if (game.inCheckPlayableState()) { - power = game + int amount = game .getBattlefield() .getActivePermanents( StaticFilters.FILTER_CONTROLLED_UNTAPPED_CREATURE, - source.getControllerId(), source, game - ).stream() + ability.getControllerId(), ability, game + ) + .stream() .map(MageObject::getPower) .mapToInt(MageInt::getValue) .max() .orElse(0); - } else { - power = CardUtil - .castStream(spellAbility.getCosts().stream(), HarmonizeCost.class) - .map(HarmonizeCost::getChosenCreature) - .map(game::getPermanent) - .filter(Objects::nonNull) - .map(MageObject::getPower) - .mapToInt(MageInt::getValue) - .map(x -> Math.max(x, 0)) - .sum(); + CardUtil.reduceCost(ability, amount); + return; } - if (power > 0) { - CardUtil.adjustCost(spellAbility, power); - } - return true; - } - - @Override - public boolean applies(Ability abilityToModify, Ability source, Game game) { - return abilityToModify instanceof SpellAbility - && abilityToModify.getSourceId().equals(source.getSourceId()); - } - - @Override - public HarmonizeCostReductionEffect copy() { - return new HarmonizeCostReductionEffect(this); - } -} - -class HarmonizeCost extends VariableCostImpl { - - private UUID chosenCreature = null; - - HarmonizeCost() { - super(VariableCostType.ADDITIONAL, "", ""); - } - - private HarmonizeCost(final HarmonizeCost cost) { - super(cost); - this.chosenCreature = cost.chosenCreature; - } - - @Override - public HarmonizeCost copy() { - return new HarmonizeCost(this); - } - - @Override - public void clearPaid() { - super.clearPaid(); - chosenCreature = null; - } - - @Override - public int getMaxValue(Ability source, Game game) { - return game.getBattlefield().contains(StaticFilters.FILTER_CONTROLLED_UNTAPPED_CREATURE, source, game, 1) ? 1 : 0; - } - - @Override - public int announceXValue(Ability source, Game game) { - Player player = game.getPlayer(source.getControllerId()); + Player player = game.getPlayer(ability.getControllerId()); if (player == null || !game.getBattlefield().contains( - StaticFilters.FILTER_CONTROLLED_UNTAPPED_CREATURE, source, game, 1 + StaticFilters.FILTER_CONTROLLED_UNTAPPED_CREATURE, ability, game, 1 ) || !player.chooseUse( - Outcome.Benefit, "Tap an untapped creature you control for harmonize?", source, game + Outcome.Tap, "Tap a creature to reduce the cost of this spell?", ability, game )) { - return 0; + return; } TargetPermanent target = new TargetPermanent(StaticFilters.FILTER_CONTROLLED_UNTAPPED_CREATURE); target.withNotTarget(true); - target.withChooseHint("for harmonize"); - player.choose(Outcome.PlayForFree, target, source, game); + target.withChooseHint("to pay for harmonize"); + player.choose(Outcome.Tap, target, ability, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent == null) { - return 0; + return; } - chosenCreature = permanent.getId(); - return 1; - } - - private FilterControlledPermanent makeFilter() { - FilterControlledPermanent filter = new FilterControlledPermanent("tap the chosen creature"); - filter.add(new PermanentIdPredicate(chosenCreature)); - return filter; - } - - @Override - public Cost getFixedCostsFromAnnouncedValue(int xValue) { - return new TapTargetCost(new TargetControlledPermanent(xValue, xValue, makeFilter(), true)); - } - - public UUID getChosenCreature() { - return chosenCreature; + CardUtil.reduceCost(ability, permanent.getPower().getValue()); + FilterControlledPermanent filter = new FilterControlledPermanent("creature chosen to tap for harmonize"); + filter.add(new PermanentIdPredicate(permanent.getId())); + ability.addCost(new TapTargetCost(new TargetControlledPermanent(filter))); } } diff --git a/Mage/src/main/java/mage/game/stack/StackAbility.java b/Mage/src/main/java/mage/game/stack/StackAbility.java index 34fb4333ab9..422e3c79585 100644 --- a/Mage/src/main/java/mage/game/stack/StackAbility.java +++ b/Mage/src/main/java/mage/game/stack/StackAbility.java @@ -787,6 +787,11 @@ public class StackAbility extends StackObjectImpl implements Ability { return this; } + @Override + public CostAdjuster getCostAdjuster() { + return costAdjuster; + } + @Override public void adjustX(Game game) { if (costAdjuster != null) {