PlayEffect: support restrictions for both MDFC sides & split halves

This commit is contained in:
Bug Hunter
2021-02-08 19:09:38 +00:00
committed by Michael Kamensky
parent 74935cf4aa
commit 01c7aa5889
11 changed files with 82 additions and 23 deletions

View File

@@ -177,6 +177,12 @@ public class ForgeScript {
return sa.getActivatingPlayer().equals(sourceController);
} else if (property.equals("OppCtrl")) {
return sa.getActivatingPlayer().isOpponentOf(sourceController);
} else if (property.startsWith("cmc")) {
int y = sa.getPayCosts().getTotalMana().getCMC();
int x = AbilityUtils.calculateAmount(spellAbility.getHostCard(), property.substring(5), spellAbility);
if (!Expressions.compare(y, property, x)) {
return false;
}
} else if (sa.getHostCard() != null) {
return sa.getHostCard().hasProperty(property, sourceController, source, spellAbility);
}

View File

@@ -3,7 +3,10 @@ package forge.game.ability;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import forge.card.CardStateName;
import forge.card.CardType;
import forge.card.ColorSet;
import forge.card.MagicColor;
@@ -1814,7 +1817,11 @@ public class AbilityUtils {
public static final List<SpellAbility> getBasicSpellsFromPlayEffect(final Card tgtCard, final Player controller) {
List<SpellAbility> sas = new ArrayList<>();
for (SpellAbility s : tgtCard.getBasicSpells()) {
List<SpellAbility> list = Lists.newArrayList(tgtCard.getBasicSpells());
if (tgtCard.isModal()) {
list.addAll(Lists.newArrayList(tgtCard.getBasicSpells(tgtCard.getState(CardStateName.Modal))));
}
for (SpellAbility s : list) {
final Spell newSA = (Spell) s.copy();
newSA.setActivatingPlayer(controller);
SpellAbilityRestriction res = new SpellAbilityRestriction();

View File

@@ -1,6 +1,7 @@
package forge.game.ability.effects;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
@@ -28,6 +29,7 @@ import forge.game.replacement.ReplacementHandler;
import forge.game.replacement.ReplacementLayer;
import forge.game.spellability.AlternativeCost;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.SpellAbilityPredicates;
import forge.game.trigger.TriggerType;
import forge.game.zone.Zone;
import forge.game.zone.ZoneType;
@@ -82,7 +84,7 @@ public class PlayEffect extends SpellAbilityEffect {
tgtCards = new CardCollection(
AbilityUtils.filterListByType(game.getCardsIn(zones), sa.getParam("Valid"), sa)
);
if ( sa.hasParam("ShowCards") ) {
if (sa.hasParam("ShowCards")) {
showCards = new CardCollection(AbilityUtils.filterListByType(game.getCardsIn(zones), sa.getParam("ShowCards"), sa));
}
}
@@ -102,7 +104,7 @@ public class PlayEffect extends SpellAbilityEffect {
final CardCollection choice = new CardCollection();
final String num = sa.hasParam("RandomNum") ? sa.getParam("RandomNum") : "1";
int ncopied = AbilityUtils.calculateAmount(source, num, sa);
while(ncopied > 0) {
while (ncopied > 0) {
final PaperCard cp = Aggregates.random(copysource);
final Card possibleCard = Card.fromPaperCard(cp, sa.getActivatingPlayer());
// Need to temporarily set the Owner so the Game is set
@@ -145,6 +147,21 @@ public class PlayEffect extends SpellAbilityEffect {
return;
}
if (sa.hasParam("ValidSA")) {
final String valid[] = {sa.getParam("ValidSA")};
final Iterator<Card> itr = tgtCards.iterator();
while (itr.hasNext()) {
final Card c = itr.next();
final List<SpellAbility> validSA = Lists.newArrayList(Iterables.filter(AbilityUtils.getBasicSpellsFromPlayEffect(c, controller), SpellAbilityPredicates.isValid(valid, controller , c, sa)));
if (validSA.size() == 0) {
itr.remove();
}
}
if (tgtCards.isEmpty()) {
return;
}
}
if (sa.hasParam("Amount") && sa.getParam("Amount").equals("All")) {
amount = tgtCards.size();
}
@@ -214,7 +231,12 @@ public class PlayEffect extends SpellAbilityEffect {
}
// get basic spells (no flashback, etc.)
final List<SpellAbility> sas = AbilityUtils.getBasicSpellsFromPlayEffect(tgtCard, controller);
List<SpellAbility> sas = AbilityUtils.getBasicSpellsFromPlayEffect(tgtCard, controller);
if (sa.hasParam("ValidSA")) {
final String valid[] = {sa.getParam("ValidSA")};
sas = Lists.newArrayList(Iterables.filter(sas, SpellAbilityPredicates.isValid(valid, controller , source, sa)));
}
if (sas.isEmpty()) {
continue;
}
@@ -233,6 +255,10 @@ public class PlayEffect extends SpellAbilityEffect {
// For Illusionary Mask effect
tgtSA = CardFactoryUtil.abilityMorphDown(tgtCard);
}
// in case player canceled from choice dialog
if (tgtSA == null) {
continue;
}
final boolean noManaCost = sa.hasParam("WithoutManaCost");
if (noManaCost) {