Support Supertype for Deckhints (#2750)

This commit is contained in:
tool4ever
2023-03-25 11:23:02 +01:00
committed by GitHub
parent 283a434df9
commit 23875bcc16
7 changed files with 19 additions and 46 deletions

View File

@@ -201,7 +201,11 @@ public class DeckHints {
Predicate<CardRules> op;
if (t.contains(".")) {
String[] typeParts = t.split("\\.");
op = Predicates.and(CardRulesPredicates.coreType(true, typeParts[0]), CardRulesPredicates.subType(typeParts[1]));
if (CardType.isASupertype(typeParts[0])) {
op = Predicates.and(CardRulesPredicates.superType(true, typeParts[0]), CardRulesPredicates.coreType(true, typeParts[1]));
} else {
op = Predicates.and(CardRulesPredicates.coreType(true, typeParts[0]), CardRulesPredicates.subType(typeParts[1]));
}
} else {
op = CardRulesPredicates.joinedType(StringOp.CONTAINS_IC, t);
}

View File

@@ -7,7 +7,6 @@ import com.google.common.collect.Sets;
import forge.game.player.DelayedReveal;
import forge.game.player.PlayerView;
import forge.util.CardTranslation;
import org.apache.commons.lang3.StringUtils;
import forge.card.CardType;
import forge.game.Game;
@@ -86,9 +85,7 @@ public class ChooseCardEffect extends SpellAbilityEffect {
final String amountValue = sa.getParamOrDefault("Amount", "1");
int validAmount;
if (StringUtils.isNumeric(amountValue)) {
validAmount = Integer.parseInt(amountValue);
} else if (amountValue.equals("Random")) {
if (amountValue.equals("Random")) {
validAmount = Aggregates.randomInt(0, choices.size());
} else {
validAmount = AbilityUtils.calculateAmount(host, amountValue, sa);

View File

@@ -2,8 +2,6 @@ package forge.game.ability.effects;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import forge.game.Game;
import forge.game.ability.AbilityUtils;
import forge.game.ability.SpellAbilityEffect;
@@ -125,8 +123,7 @@ public class ChooseSourceEffect extends SpellAbilityEffect {
return;
}
final String numericAmount = sa.getParamOrDefault("Amount", "1");
final int validAmount = StringUtils.isNumeric(numericAmount) ? Integer.parseInt(numericAmount) : AbilityUtils.calculateAmount(host, numericAmount, sa);
final int validAmount = AbilityUtils.calculateAmount(host, sa.getParamOrDefault("Amount", "1"), sa);
for (final Player p : tgtPlayers) {
if (!p.isInGame()) {

View File

@@ -18,7 +18,6 @@ import forge.game.zone.ZoneType;
import forge.util.Lang;
import forge.util.Localizer;
import forge.util.TextUtil;
import org.apache.commons.lang3.StringUtils;
import java.util.Map;
@@ -63,11 +62,8 @@ public class SetStateEffect extends SpellAbilityEffect {
CardCollectionView choices = game.getCardsIn(ZoneType.Battlefield);
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), p, host, sa);
final String numericAmount = sa.getParamOrDefault("Amount", "1");
final int validAmount = StringUtils.isNumeric(numericAmount) ? Integer.parseInt(numericAmount) :
AbilityUtils.calculateAmount(host, numericAmount, sa);
final int minAmount = sa.hasParam("MinAmount") ? Integer.parseInt(sa.getParam("MinAmount")) :
validAmount;
final int validAmount = AbilityUtils.calculateAmount(host, sa.getParamOrDefault("Amount", "1"), sa);
final int minAmount = sa.hasParam("MinAmount") ? Integer.parseInt(sa.getParam("MinAmount")) : validAmount;
if (validAmount <= 0) {
return;

View File

@@ -4,7 +4,7 @@ Types:Legendary Planeswalker Tyvar
Loyalty:3
S:Mode$ ActivateAbilityAsIfHaste | ValidCard$ Creature.YouCtrl | Description$ You may activate abilities of creatures you control as though those creatures had haste.
A:AB$ Untap | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | ValidTgts$ Creature | TargetMin$ 0 | TargetMax$ 1 | SpellDescription$ Untap up to one target creature.
A:AB$ Mill | Cost$ SubCounter<1/LOYALTY> | Planeswalker$ True | NumCards$ 3 | Defined$ You | SubAbility$ DBChange | SpellDescription$ Mill three cards, then you may return a creature card with mana value 2 or less from your graveyard to the battlefield.
A:AB$ Mill | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | NumCards$ 3 | Defined$ You | SubAbility$ DBChange | SpellDescription$ Mill three cards, then you may return a creature card with mana value 2 or less from your graveyard to the battlefield.
SVar:DBChange:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | SelectPrompt$ Choose a creature card with mana value 2 or less | Hidden$ True | ChangeType$ Creature.YouOwn+cmcLE2
DeckHas:Ability$Graveyard|Mill
DeckHints:Ability$Graveyard

View File

@@ -1,13 +1,11 @@
package forge.player;
import java.util.ArrayList;
import java.util.List;
import forge.ImageKeys;
import forge.game.cost.*;
import forge.game.spellability.SpellAbilityStackInstance;
import org.apache.commons.lang3.StringUtils;
import com.google.common.collect.Iterables;
@@ -198,24 +196,6 @@ public class HumanPlay {
req.playAbility(!useOldTargets, false, true);
}
private static int getAmountFromPart(CostPart part, Card source, SpellAbility sourceAbility) {
String amountString = part.getAmount();
return StringUtils.isNumeric(amountString) ? Integer.parseInt(amountString) : AbilityUtils.calculateAmount(source, amountString, sourceAbility);
}
/**
* TODO: Write javadoc for this method.
* @param part
* @param source
* @param sourceAbility
* @return
*/
private static int getAmountFromPartX(CostPart part, Card source, SpellAbility sourceAbility) {
String amountString = part.getAmount();
// Probably should just be -
return AbilityUtils.calculateAmount(source, amountString, sourceAbility);
}
/**
* <p>
* payCostDuringAbilityResolve.
@@ -327,7 +307,7 @@ public class HumanPlay {
list = new CardCollection(p.getCardsIn(from));
}
list = CardLists.getValidCards(list, part.getType().split(";"), p, source, sourceAbility);
final int nNeeded = getAmountFromPart(part, source, sourceAbility);
final int nNeeded = part.getAbilityAmount(sourceAbility);
if (list.size() < nNeeded) {
return false;
}
@@ -380,7 +360,7 @@ public class HumanPlay {
if (part.getType().equals("All")) {
payList.addAll(saList);
} else {
final int c = getAmountFromPart(part, source, sourceAbility);
final int c = part.getAbilityAmount(sourceAbility);
if (saList.size() < c) {
return false;
@@ -466,12 +446,12 @@ public class HumanPlay {
}
else if (part instanceof CostReturn) {
CardCollectionView list = CardLists.getValidCards(p.getCardsIn(ZoneType.Battlefield), part.getType(), p, source, sourceAbility);
int amount = getAmountFromPartX(part, source, sourceAbility);
int amount = part.getAbilityAmount(sourceAbility);
boolean hasPaid = payCostPart(controller, p, sourceAbility, hcd.isEffect(), (CostPartWithList)part, amount, list, Localizer.getInstance().getMessage("lblReturnToHand") + orString);
if (!hasPaid) { return false; }
}
else if (part instanceof CostDiscard) {
int amount = getAmountFromPartX(part, source, sourceAbility);
int amount = part.getAbilityAmount(sourceAbility);
if ("Hand".equals(part.getType())) {
if (!p.getController().confirmPayment(part, Localizer.getInstance().getMessage("lblDoYouWantDiscardYourHand"), sourceAbility)) {
return false;
@@ -493,14 +473,14 @@ public class HumanPlay {
else if (part instanceof CostReveal) {
CostReveal costReveal = (CostReveal) part;
CardCollectionView list = CardLists.getValidCards(p.getCardsIn(costReveal.getRevealFrom()), part.getType(), p, source, sourceAbility);
int amount = getAmountFromPartX(part, source, sourceAbility);
int amount = part.getAbilityAmount(sourceAbility);
boolean hasPaid = payCostPart(controller, p, sourceAbility, hcd.isEffect(), (CostPartWithList)part, amount, list, Localizer.getInstance().getMessage("lblReveal") + orString);
if (!hasPaid) { return false; }
}
else if (part instanceof CostTapType) {
CardCollectionView list = CardLists.getValidCards(p.getCardsIn(ZoneType.Battlefield), part.getType(), p, source, sourceAbility);
list = CardLists.filter(list, Presets.UNTAPPED);
int amount = getAmountFromPartX(part, source, sourceAbility);
int amount = part.getAbilityAmount(sourceAbility);
boolean hasPaid = payCostPart(controller, p, sourceAbility, hcd.isEffect(), (CostPartWithList)part, amount, list, Localizer.getInstance().getMessage("lblTap") + orString);
if (!hasPaid) { return false; }
}
@@ -511,7 +491,7 @@ public class HumanPlay {
}
else if (part instanceof CostPayEnergy) {
CounterType counterType = CounterType.get(CounterEnumType.ENERGY);
int amount = getAmountFromPartX(part, source, sourceAbility);
int amount = part.getAbilityAmount(sourceAbility);
if (!mandatory && !p.getController().confirmPayment(part, Localizer.getInstance().getMessage("lblDoYouWantSpendNTargetTypeCounter", String.valueOf(amount), counterType.getName()), sourceAbility)) {
return false;
@@ -525,7 +505,7 @@ public class HumanPlay {
else if (part instanceof CostPayShards) {
CounterType counterType = CounterType.get(CounterEnumType.MANASHARDS);
int amount = getAmountFromPartX(part, source, sourceAbility);
int amount = part.getAbilityAmount(sourceAbility);
if (!mandatory && !p.getController().confirmPayment(part, Localizer.getInstance().getMessage("lblDoYouWantSpendNTargetTypeCounter", String.valueOf(amount), counterType.getName()), sourceAbility)) {
return false;

View File

@@ -1850,8 +1850,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
}
@Override
public ReplacementEffect chooseSingleReplacementEffect(final String prompt,
final List<ReplacementEffect> possibleReplacers) {
public ReplacementEffect chooseSingleReplacementEffect(final String prompt, final List<ReplacementEffect> possibleReplacers) {
final ReplacementEffect first = possibleReplacers.get(0);
if (possibleReplacers.size() == 1) {
return first;