update cards and effects that missed canPaySacrificeCost (#13916)

* update SacrificeAttachmentCost to work with canPaySacrificeCost

* update SacrificeXTargetCost to use canPaySacrificeCost

* update SacrificeXManaValueCost to use canPaySacrificeCost and getMaxValue

* update Phyrexian Dreadnought to use canPaySacrificeCost

* enable testNahiriSacrificePrevented test
This commit is contained in:
Jmlundeen 2025-08-27 21:38:02 -05:00 committed by GitHub
parent 366ffbb1e0
commit 47f2eb4c94
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 73 additions and 5 deletions

View file

@ -1,5 +1,6 @@
package mage.cards.n;
import mage.abilities.Ability;
import mage.abilities.costs.Cost;
import mage.abilities.costs.SacrificeCost;
import mage.abilities.costs.VariableCostImpl;
@ -15,6 +16,9 @@ import mage.constants.ComparisonType;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanentAmount;
import java.util.UUID;
@ -90,4 +94,33 @@ class SacrificeXManaValueCost extends VariableCostImpl implements SacrificeCost
return new SacrificeTargetCost(manavaluefilter);
}
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
Player controller = game.getPlayer(controllerId);
if (controller == null) {
return false;
}
int validTargets = 0;
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, controllerId, game)) {
if (controller.canPaySacrificeCost(permanent, source, controllerId, game)) {
validTargets++;
}
}
return validTargets > 0;
}
@Override
public int getMaxValue(Ability source, Game game) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return super.getMaxValue(source, game);
}
int maxValue = 0;
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) {
if (controller.canPaySacrificeCost(permanent, source, controller.getId(), game)) {
maxValue = Math.max(maxValue, permanent.getManaValue());
}
}
return maxValue;
}
}

View file

@ -17,6 +17,7 @@ import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import java.util.UUID;
@ -83,10 +84,16 @@ class PhyrexianDreadnoughtSacrificeCost extends CostImpl {
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
Player controller = game.getPlayer(controllerId);
if (controller == null) {
return false;
}
int sumPower = 0;
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, controllerId, game)) {
if (controller.canPaySacrificeCost(permanent, source, controllerId, game)) {
sumPower += permanent.getPower().getValue();
}
}
return sumPower >= 12;
}

View file

@ -2,7 +2,6 @@ package org.mage.test.cards.single.one;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
@ -41,7 +40,6 @@ public class NahirisSacrificeTest extends CardTestPlayerBase {
}
@Test
@Ignore // Enable after merging #13916
public void testNahirisSacrificePrevented() {
setStrictChooseMode(true);

View file

@ -6,6 +6,7 @@ import mage.abilities.costs.SacrificeCost;
import mage.abilities.costs.UseAttachedCost;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.UUID;
@ -52,7 +53,12 @@ public class SacrificeAttachmentCost extends UseAttachedCost implements Sacrific
if (!super.canPay(ability, source, controllerId, game)) {
return false;
}
return game.getPermanent(source.getSourceId()).canBeSacrificed();
Player controller = game.getPlayer(controllerId);
Permanent permanent = mageObjectReference.getPermanent(game);
if (controller == null || permanent == null) {
return false;
}
return controller.canPaySacrificeCost(permanent, source, controllerId, game);
}
@Override

View file

@ -7,8 +7,12 @@ import mage.abilities.costs.VariableCostImpl;
import mage.abilities.costs.VariableCostType;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetSacrifice;
import java.util.UUID;
/**
* @author LevelX2
*/
@ -39,6 +43,26 @@ public class SacrificeXTargetCost extends VariableCostImpl implements SacrificeC
this.minValue = cost.minValue;
}
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
int canSacAmount = getValidSacAmount(source, controllerId, game);
return canSacAmount >= minValue;
}
private int getValidSacAmount(Ability source, UUID controllerId, Game game) {
Player controller = game.getPlayer(controllerId);
if (controller == null) {
return -1;
}
int canSacAmount = 0;
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, controllerId, game)) {
if (controller.canPaySacrificeCost(permanent, source, controllerId, game)) {
canSacAmount++;
}
}
return canSacAmount;
}
@Override
public SacrificeXTargetCost copy() {
return new SacrificeXTargetCost(this);
@ -51,7 +75,7 @@ public class SacrificeXTargetCost extends VariableCostImpl implements SacrificeC
@Override
public int getMaxValue(Ability source, Game game) {
return game.getBattlefield().count(filter, source.getControllerId(), source, game);
return getValidSacAmount(source, source.getControllerId(), game);
}
@Override