mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28:00 +00:00
Support Supertype for Deckhints (#2750)
This commit is contained in:
@@ -201,7 +201,11 @@ public class DeckHints {
|
|||||||
Predicate<CardRules> op;
|
Predicate<CardRules> op;
|
||||||
if (t.contains(".")) {
|
if (t.contains(".")) {
|
||||||
String[] typeParts = t.split("\\.");
|
String[] typeParts = t.split("\\.");
|
||||||
|
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]));
|
op = Predicates.and(CardRulesPredicates.coreType(true, typeParts[0]), CardRulesPredicates.subType(typeParts[1]));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
op = CardRulesPredicates.joinedType(StringOp.CONTAINS_IC, t);
|
op = CardRulesPredicates.joinedType(StringOp.CONTAINS_IC, t);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import com.google.common.collect.Sets;
|
|||||||
import forge.game.player.DelayedReveal;
|
import forge.game.player.DelayedReveal;
|
||||||
import forge.game.player.PlayerView;
|
import forge.game.player.PlayerView;
|
||||||
import forge.util.CardTranslation;
|
import forge.util.CardTranslation;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import forge.card.CardType;
|
import forge.card.CardType;
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
@@ -86,9 +85,7 @@ public class ChooseCardEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
final String amountValue = sa.getParamOrDefault("Amount", "1");
|
final String amountValue = sa.getParamOrDefault("Amount", "1");
|
||||||
int validAmount;
|
int validAmount;
|
||||||
if (StringUtils.isNumeric(amountValue)) {
|
if (amountValue.equals("Random")) {
|
||||||
validAmount = Integer.parseInt(amountValue);
|
|
||||||
} else if (amountValue.equals("Random")) {
|
|
||||||
validAmount = Aggregates.randomInt(0, choices.size());
|
validAmount = Aggregates.randomInt(0, choices.size());
|
||||||
} else {
|
} else {
|
||||||
validAmount = AbilityUtils.calculateAmount(host, amountValue, sa);
|
validAmount = AbilityUtils.calculateAmount(host, amountValue, sa);
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ package forge.game.ability.effects;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.ability.SpellAbilityEffect;
|
import forge.game.ability.SpellAbilityEffect;
|
||||||
@@ -125,8 +123,7 @@ public class ChooseSourceEffect extends SpellAbilityEffect {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String numericAmount = sa.getParamOrDefault("Amount", "1");
|
final int validAmount = AbilityUtils.calculateAmount(host, sa.getParamOrDefault("Amount", "1"), sa);
|
||||||
final int validAmount = StringUtils.isNumeric(numericAmount) ? Integer.parseInt(numericAmount) : AbilityUtils.calculateAmount(host, numericAmount, sa);
|
|
||||||
|
|
||||||
for (final Player p : tgtPlayers) {
|
for (final Player p : tgtPlayers) {
|
||||||
if (!p.isInGame()) {
|
if (!p.isInGame()) {
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import forge.game.zone.ZoneType;
|
|||||||
import forge.util.Lang;
|
import forge.util.Lang;
|
||||||
import forge.util.Localizer;
|
import forge.util.Localizer;
|
||||||
import forge.util.TextUtil;
|
import forge.util.TextUtil;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -63,11 +62,8 @@ public class SetStateEffect extends SpellAbilityEffect {
|
|||||||
CardCollectionView choices = game.getCardsIn(ZoneType.Battlefield);
|
CardCollectionView choices = game.getCardsIn(ZoneType.Battlefield);
|
||||||
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), p, host, sa);
|
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), p, host, sa);
|
||||||
|
|
||||||
final String numericAmount = sa.getParamOrDefault("Amount", "1");
|
final int validAmount = AbilityUtils.calculateAmount(host, sa.getParamOrDefault("Amount", "1"), sa);
|
||||||
final int validAmount = StringUtils.isNumeric(numericAmount) ? Integer.parseInt(numericAmount) :
|
final int minAmount = sa.hasParam("MinAmount") ? Integer.parseInt(sa.getParam("MinAmount")) : validAmount;
|
||||||
AbilityUtils.calculateAmount(host, numericAmount, sa);
|
|
||||||
final int minAmount = sa.hasParam("MinAmount") ? Integer.parseInt(sa.getParam("MinAmount")) :
|
|
||||||
validAmount;
|
|
||||||
|
|
||||||
if (validAmount <= 0) {
|
if (validAmount <= 0) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Types:Legendary Planeswalker Tyvar
|
|||||||
Loyalty:3
|
Loyalty:3
|
||||||
S:Mode$ ActivateAbilityAsIfHaste | ValidCard$ Creature.YouCtrl | Description$ You may activate abilities of creatures you control as though those creatures had haste.
|
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$ 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
|
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
|
DeckHas:Ability$Graveyard|Mill
|
||||||
DeckHints:Ability$Graveyard
|
DeckHints:Ability$Graveyard
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
package forge.player;
|
package forge.player;
|
||||||
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import forge.ImageKeys;
|
import forge.ImageKeys;
|
||||||
import forge.game.cost.*;
|
import forge.game.cost.*;
|
||||||
import forge.game.spellability.SpellAbilityStackInstance;
|
import forge.game.spellability.SpellAbilityStackInstance;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
@@ -198,24 +196,6 @@ public class HumanPlay {
|
|||||||
req.playAbility(!useOldTargets, false, true);
|
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>
|
* <p>
|
||||||
* payCostDuringAbilityResolve.
|
* payCostDuringAbilityResolve.
|
||||||
@@ -327,7 +307,7 @@ public class HumanPlay {
|
|||||||
list = new CardCollection(p.getCardsIn(from));
|
list = new CardCollection(p.getCardsIn(from));
|
||||||
}
|
}
|
||||||
list = CardLists.getValidCards(list, part.getType().split(";"), p, source, sourceAbility);
|
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) {
|
if (list.size() < nNeeded) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -380,7 +360,7 @@ public class HumanPlay {
|
|||||||
if (part.getType().equals("All")) {
|
if (part.getType().equals("All")) {
|
||||||
payList.addAll(saList);
|
payList.addAll(saList);
|
||||||
} else {
|
} else {
|
||||||
final int c = getAmountFromPart(part, source, sourceAbility);
|
final int c = part.getAbilityAmount(sourceAbility);
|
||||||
|
|
||||||
if (saList.size() < c) {
|
if (saList.size() < c) {
|
||||||
return false;
|
return false;
|
||||||
@@ -466,12 +446,12 @@ public class HumanPlay {
|
|||||||
}
|
}
|
||||||
else if (part instanceof CostReturn) {
|
else if (part instanceof CostReturn) {
|
||||||
CardCollectionView list = CardLists.getValidCards(p.getCardsIn(ZoneType.Battlefield), part.getType(), p, source, sourceAbility);
|
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);
|
boolean hasPaid = payCostPart(controller, p, sourceAbility, hcd.isEffect(), (CostPartWithList)part, amount, list, Localizer.getInstance().getMessage("lblReturnToHand") + orString);
|
||||||
if (!hasPaid) { return false; }
|
if (!hasPaid) { return false; }
|
||||||
}
|
}
|
||||||
else if (part instanceof CostDiscard) {
|
else if (part instanceof CostDiscard) {
|
||||||
int amount = getAmountFromPartX(part, source, sourceAbility);
|
int amount = part.getAbilityAmount(sourceAbility);
|
||||||
if ("Hand".equals(part.getType())) {
|
if ("Hand".equals(part.getType())) {
|
||||||
if (!p.getController().confirmPayment(part, Localizer.getInstance().getMessage("lblDoYouWantDiscardYourHand"), sourceAbility)) {
|
if (!p.getController().confirmPayment(part, Localizer.getInstance().getMessage("lblDoYouWantDiscardYourHand"), sourceAbility)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -493,14 +473,14 @@ public class HumanPlay {
|
|||||||
else if (part instanceof CostReveal) {
|
else if (part instanceof CostReveal) {
|
||||||
CostReveal costReveal = (CostReveal) part;
|
CostReveal costReveal = (CostReveal) part;
|
||||||
CardCollectionView list = CardLists.getValidCards(p.getCardsIn(costReveal.getRevealFrom()), part.getType(), p, source, sourceAbility);
|
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);
|
boolean hasPaid = payCostPart(controller, p, sourceAbility, hcd.isEffect(), (CostPartWithList)part, amount, list, Localizer.getInstance().getMessage("lblReveal") + orString);
|
||||||
if (!hasPaid) { return false; }
|
if (!hasPaid) { return false; }
|
||||||
}
|
}
|
||||||
else if (part instanceof CostTapType) {
|
else if (part instanceof CostTapType) {
|
||||||
CardCollectionView list = CardLists.getValidCards(p.getCardsIn(ZoneType.Battlefield), part.getType(), p, source, sourceAbility);
|
CardCollectionView list = CardLists.getValidCards(p.getCardsIn(ZoneType.Battlefield), part.getType(), p, source, sourceAbility);
|
||||||
list = CardLists.filter(list, Presets.UNTAPPED);
|
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);
|
boolean hasPaid = payCostPart(controller, p, sourceAbility, hcd.isEffect(), (CostPartWithList)part, amount, list, Localizer.getInstance().getMessage("lblTap") + orString);
|
||||||
if (!hasPaid) { return false; }
|
if (!hasPaid) { return false; }
|
||||||
}
|
}
|
||||||
@@ -511,7 +491,7 @@ public class HumanPlay {
|
|||||||
}
|
}
|
||||||
else if (part instanceof CostPayEnergy) {
|
else if (part instanceof CostPayEnergy) {
|
||||||
CounterType counterType = CounterType.get(CounterEnumType.ENERGY);
|
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)) {
|
if (!mandatory && !p.getController().confirmPayment(part, Localizer.getInstance().getMessage("lblDoYouWantSpendNTargetTypeCounter", String.valueOf(amount), counterType.getName()), sourceAbility)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -525,7 +505,7 @@ public class HumanPlay {
|
|||||||
|
|
||||||
else if (part instanceof CostPayShards) {
|
else if (part instanceof CostPayShards) {
|
||||||
CounterType counterType = CounterType.get(CounterEnumType.MANASHARDS);
|
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)) {
|
if (!mandatory && !p.getController().confirmPayment(part, Localizer.getInstance().getMessage("lblDoYouWantSpendNTargetTypeCounter", String.valueOf(amount), counterType.getName()), sourceAbility)) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -1850,8 +1850,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ReplacementEffect chooseSingleReplacementEffect(final String prompt,
|
public ReplacementEffect chooseSingleReplacementEffect(final String prompt, final List<ReplacementEffect> possibleReplacers) {
|
||||||
final List<ReplacementEffect> possibleReplacers) {
|
|
||||||
final ReplacementEffect first = possibleReplacers.get(0);
|
final ReplacementEffect first = possibleReplacers.get(0);
|
||||||
if (possibleReplacers.size() == 1) {
|
if (possibleReplacers.size() == 1) {
|
||||||
return first;
|
return first;
|
||||||
|
|||||||
Reference in New Issue
Block a user