mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 18:58:00 +00:00
MH3: nethergoyf.txt + support (#5311)
This commit is contained in:
@@ -202,12 +202,23 @@ public class CostExile extends CostPartWithList {
|
||||
type = TextUtil.fastReplace(type, "+withSharedCardType", "");
|
||||
}
|
||||
|
||||
int nTypes = -1;
|
||||
if (type.contains("+withTypesGE")) {
|
||||
String num = type.split("withTypesGE")[1];
|
||||
type = TextUtil.fastReplace(type, TextUtil.concatNoSpace("+withTypesGE", num), "");
|
||||
nTypes = Integer.parseInt(num);
|
||||
}
|
||||
|
||||
if (!type.contains("X") || ability.getXManaCostPaid() != null) {
|
||||
list = CardLists.getValidCards(list, type.split(";"), payer, source, ability);
|
||||
}
|
||||
|
||||
int amount = this.getAbilityAmount(ability);
|
||||
|
||||
if (nTypes > -1) {
|
||||
if (CardFactoryUtil.getCardTypesFromList(list) < nTypes) return false;
|
||||
}
|
||||
|
||||
if (sharedType) { // will need more logic if cost ever wants more than 2 that share a type
|
||||
if (list.size() < amount) return false;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
|
||||
10
forge-gui/res/cardsfolder/upcoming/nethergoyf.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/nethergoyf.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
Name:Nethergoyf
|
||||
ManaCost:B
|
||||
Types:Creature Lhurgoyf
|
||||
PT:*/1+*
|
||||
S:Mode$ Continuous | EffectZone$ All | CharacteristicDefining$ True | SetPower$ Count$ValidGraveyard Card.YouOwn$CardTypes | SetToughness$ Count$ValidGraveyard Card.YouOwn$CardTypes/Plus.1 | Description$ CARDNAME's power is equal to the number of card types among cards in your graveyard and its toughness is equal to that number plus 1.
|
||||
K:Escape:2 B ExileFromGrave<X/Card.Other+withTypesGE4/other cards from your graveyard with four or more card types among them>
|
||||
SVar:X:Count$xPaid
|
||||
AI:RemoveDeck:All
|
||||
DeckHints:Ability$Discard|Sacrifice|Graveyard
|
||||
Oracle:Nethergoyf's power is equal to the number of card types among cards in your graveyard and its toughness is equal to that number plus 1.\nEscape—{2}{B}, Exile any number of other cards from your graveyard with four or more card types among them. (You may cast this card from your graveyard for its escape cost.)
|
||||
@@ -2479,6 +2479,7 @@ lblSelectATargetToSacrifice=Wähle ein(e) {0} zum Opfern (noch {1})
|
||||
lblSelectOneOfCardsToTapAlreadyChosen=Wähle eine Karte zum tappen. Bereits gewählt:
|
||||
lblSelectACreatureToTap=Wähle eine Kreatur zum Tappen.
|
||||
lblSelectToExile=Select {0} or more to exile
|
||||
lblSelectAnyNumToExile=Select any number to exile
|
||||
lblEnoughValidCardNotToPayTheCost=Nicht genug gültige Karten zum Tappen übrig um die Kosten zu bezahlen.
|
||||
lblCostPaymentInvalid=Bezahlung der Kosten unmöglich
|
||||
lblSelectATargetToTap=Wähle ein(e) {0} zum Tappen (noch {1})
|
||||
|
||||
@@ -2492,6 +2492,7 @@ lblSelectATargetToSacrifice=Select {0} to sacrifice ({1} left)
|
||||
lblSelectOneOfCardsToTapAlreadyChosen=Select one of the cards to tap. Already chosen:
|
||||
lblSelectACreatureToTap=Select a creature to tap.
|
||||
lblSelectToExile=Select {0} or more to exile
|
||||
lblSelectAnyNumToExile=Select any number to exile
|
||||
lblCollectEvidence=Exile evidence with a total CMC {0} or more
|
||||
lblEnoughValidCardNotToPayTheCost=Not enough valid cards left to tap to pay the cost.
|
||||
lblCostPaymentInvalid=Cost payment invalid
|
||||
|
||||
@@ -2480,6 +2480,7 @@ lblSelectATargetToSacrifice=Selecciona un {0} para sacrificar ({1} pendiente)
|
||||
lblSelectOneOfCardsToTapAlreadyChosen=Selecciona una de las cartas para girar. Ya elegido:
|
||||
lblSelectACreatureToTap=Selecciona una criatura para girar.
|
||||
lblSelectToExile=Selecciona {0} o más para exilar
|
||||
lblSelectAnyNumToExile=Select any number to exile
|
||||
lblEnoughValidCardNotToPayTheCost=No quedan suficientes cartas válidas para girar para pagar el coste.
|
||||
lblCostPaymentInvalid=Pago del coste no válido
|
||||
lblSelectATargetToTap=Selecciona un/a {0} para girar ({1} pendiente)
|
||||
|
||||
@@ -2483,6 +2483,7 @@ lblSelectATargetToSacrifice=Sélectionnez {0} à sacrifier ({1} à gauche)
|
||||
lblSelectOneOfCardsToTapAlreadyChosen=S\u00e9lectionnez une des cartes \u00e0 tapoter. Déjà choisi :
|
||||
lblSelectACreatureToTap=S\u00e9lectionnez une cr\u00e9ature \u00e0 engager.
|
||||
lblSelectToExile=Sélectionnez {0} ou plus pour exiler
|
||||
lblSelectAnyNumToExile=Select any number to exile
|
||||
lblEnoughValidCardNotToPayTheCost=Il ne reste plus assez de cartes valides à toucher pour payer le coût.
|
||||
lblCostPaymentInvalid=Paiement de coût invalide
|
||||
lblSelectATargetToTap=Sélectionnez un(e) {0} à appuyer ({1} à gauche)
|
||||
|
||||
@@ -2480,6 +2480,7 @@ lblSelectATargetToSacrifice=Seleziona una carta {0} da scarificare ({1} rimasta/
|
||||
lblSelectOneOfCardsToTapAlreadyChosen=Seleziona una delle carta da tappare. Già scelto:
|
||||
lblSelectACreatureToTap=Seleziona una creatura da tappare.
|
||||
lblSelectToExile=Seleziona {0} o più per esiliare
|
||||
lblSelectAnyNumToExile=Select any number to exile
|
||||
lblEnoughValidCardNotToPayTheCost=Non sono rimaste abbastanza carte valide da tappare per pagare il costo
|
||||
lblCostPaymentInvalid=Pagamento del costo non valido
|
||||
lblSelectATargetToTap=Seleziona una carta {0} da tapapre ({1} rimasta/e)
|
||||
|
||||
@@ -2479,6 +2479,7 @@ lblSelectATargetToSacrifice=生け贄に捧げ {0}を選択(残り{1})
|
||||
lblSelectOneOfCardsToTapAlreadyChosen=タップするカードを選ぶ。既に選択:
|
||||
lblSelectACreatureToTap=タップするクリーチャーを選ぶ。
|
||||
lblSelectToExile=追放するには{0}個以上を選択してください
|
||||
lblSelectAnyNumToExile=Select any number to exile
|
||||
lblEnoughValidCardNotToPayTheCost=コストを支払いためにタップできるカードが足りません。
|
||||
lblCostPaymentInvalid=無効な支払い
|
||||
lblSelectATargetToTap=タップする {0}を選択(残り{1})
|
||||
|
||||
@@ -2555,6 +2555,7 @@ lblSelectATargetToSacrifice=Selecione {0} para sacrificar ({1} restantes)
|
||||
lblSelectOneOfCardsToTapAlreadyChosen=Escolha uma das cartas para virar. Já escolhido\:
|
||||
lblSelectACreatureToTap=Escolha as criaturas para virar.
|
||||
lblSelectToExile=Selecione {0} ou mais para exilar
|
||||
lblSelectAnyNumToExile=Select any number to exile
|
||||
lblEnoughValidCardNotToPayTheCost=Cartas válidas insuficientes para pagar o custo.
|
||||
lblCostPaymentInvalid=Custo de pagamento inválido
|
||||
lblSelectATargetToTap=Escolha um(n) {0} para virar ({1} restante)
|
||||
|
||||
@@ -2484,6 +2484,7 @@ lblSelectATargetToSacrifice=选择一个{0}进行牺牲(还剩{1})
|
||||
lblSelectOneOfCardsToTapAlreadyChosen=选择其中的一张进行横置。已经选择:
|
||||
lblSelectACreatureToTap=选择一个生物进行横置
|
||||
lblSelectToExile=选择{0}个或更多要放逐的
|
||||
lblSelectAnyNumToExile=Select any number to exile
|
||||
lblEnoughValidCardNotToPayTheCost=没有足够的有效卡牌用于支付费用。
|
||||
lblCostPaymentInvalid=付费失败
|
||||
lblSelectATargetToTap=选择{0}进行横置(还剩{1})
|
||||
|
||||
@@ -24,8 +24,8 @@ public class InputSelectCardsFromList extends InputSelectEntitiesFromList<Card>
|
||||
super(controller, min, max, validCards, sa);
|
||||
}
|
||||
|
||||
public InputSelectCardsFromList(final PlayerControllerHuman controller, final int min, final int max, final FCollectionView<Card> validCards, final SpellAbility sa, final int tally) {
|
||||
super(controller, min, max, validCards, sa, tally);
|
||||
public InputSelectCardsFromList(final PlayerControllerHuman controller, final int min, final int max, final FCollectionView<Card> validCards, final SpellAbility sa, final String tallyType, final int tally) {
|
||||
super(controller, min, max, validCards, sa, tallyType, tally);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.card.CardView;
|
||||
@@ -32,15 +33,15 @@ public class InputSelectEntitiesFromList<T extends GameEntity> extends InputSele
|
||||
protected Iterable<PlayerZoneUpdate> zonesShown; // want to hide these zones when input done
|
||||
|
||||
public InputSelectEntitiesFromList(final PlayerControllerHuman controller, final int min, final int max, final FCollectionView<T> validChoices0) {
|
||||
this(controller, min, max, validChoices0, null, 0);
|
||||
this(controller, min, max, validChoices0, null, "", 0);
|
||||
}
|
||||
|
||||
public InputSelectEntitiesFromList(final PlayerControllerHuman controller, final int min, final int max, final FCollectionView<T> validChoices0, final SpellAbility sa0) {
|
||||
this(controller, min, max, validChoices0, sa0, 0);
|
||||
this(controller, min, max, validChoices0, sa0, "", 0);
|
||||
}
|
||||
|
||||
public InputSelectEntitiesFromList(final PlayerControllerHuman controller, final int min, final int max, final FCollectionView<T> validChoices0, final SpellAbility sa0, final int tally0) {
|
||||
super(controller, Math.min(min, validChoices0.size()), Math.min(max, validChoices0.size()), sa0, tally0);
|
||||
public InputSelectEntitiesFromList(final PlayerControllerHuman controller, final int min, final int max, final FCollectionView<T> validChoices0, final SpellAbility sa0, final String tallyType0, final int tally0) {
|
||||
super(controller, Math.min(min, validChoices0.size()), Math.min(max, validChoices0.size()), sa0, tallyType0, tally0);
|
||||
validChoices = validChoices0;
|
||||
if (min > validChoices.size()) { // pfps does this really do anything useful??
|
||||
System.out.println(String.format("Trying to choose at least %d things from a list with only %d things!", min, validChoices.size()));
|
||||
@@ -142,10 +143,17 @@ public class InputSelectEntitiesFromList<T extends GameEntity> extends InputSele
|
||||
|
||||
}
|
||||
else if (sa.getPayCosts().hasSpecificCostType(CostExile.class) && tally > 0) {
|
||||
msg.append("\n").append(Localizer.getInstance().getMessage("lblCMC")).append(": ");
|
||||
msg.append(CardLists.getTotalCMC((FCollection<Card>)getSelected())).append(" / ").append(tally);
|
||||
msg.append("\n");
|
||||
if (tallyType.equals("CMC")) {
|
||||
msg.append(Localizer.getInstance().getMessage("lblCMC")).append(": ");
|
||||
msg.append(CardLists.getTotalCMC((FCollection<Card>)getSelected())).append(" / ").append(tally);
|
||||
} else if (tallyType.equals("Types")) {
|
||||
msg.append(Localizer.getInstance().getMessage("lblTypes")).append(": ");
|
||||
msg.append(AbilityUtils.countCardTypesFromList((FCollection<Card>)getSelected(), false));
|
||||
msg.append(" / ").append(tally);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return msg.toString();
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ public abstract class InputSelectManyBase<T extends GameEntity> extends InputSyn
|
||||
protected boolean allowCancel = false;
|
||||
protected SpellAbility sa = null;
|
||||
protected CardView card;
|
||||
protected String tallyType;
|
||||
protected int tally;
|
||||
|
||||
protected String message = "Source-Card-Name - Select %d more card(s)";
|
||||
@@ -44,12 +45,13 @@ public abstract class InputSelectManyBase<T extends GameEntity> extends InputSyn
|
||||
}
|
||||
}
|
||||
|
||||
protected InputSelectManyBase(final PlayerControllerHuman controller, final int min, final int max, final SpellAbility sa0, final int tally0) {
|
||||
protected InputSelectManyBase(final PlayerControllerHuman controller, final int min, final int max, final SpellAbility sa0, final String tallyType0, final int tally0) {
|
||||
this(controller,min,max);
|
||||
this.sa = sa0;
|
||||
if (sa0 != null) {
|
||||
this.card = sa0.getView().getHostCard();
|
||||
}
|
||||
this.tallyType = tallyType0;
|
||||
this.tally = tally0;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import forge.game.ability.AbilityUtils;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardCollectionView;
|
||||
import forge.game.card.CardFactoryUtil;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.card.CardPredicates;
|
||||
import forge.game.card.CardPredicates.Presets;
|
||||
@@ -84,7 +85,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
CardCollection list = CardLists.filter(player.getCardsIn(ZoneType.Graveyard), CardPredicates.canExiledBy(ability, isEffect()));
|
||||
final int total = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
|
||||
final InputSelectCardsFromList inp =
|
||||
new InputSelectCardsFromList(controller, 0, list.size(), list, ability, total);
|
||||
new InputSelectCardsFromList(controller, 0, list.size(), list, ability, "CMC", total);
|
||||
inp.setMessage(Localizer.getInstance().getMessage("lblCollectEvidence", total));
|
||||
inp.setCancelAllowed(true);
|
||||
inp.showAndWait();
|
||||
@@ -265,6 +266,12 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
sharedType = true;
|
||||
type = TextUtil.fastReplace(type, "+withSharedCardType", "");
|
||||
}
|
||||
int nTypes = -1;
|
||||
if (type.contains("+withTypesGE")) {
|
||||
String num = type.split("withTypesGE")[1];
|
||||
type = TextUtil.fastReplace(type, TextUtil.concatNoSpace("+withTypesGE", num), "");
|
||||
nTypes = Integer.parseInt(num);
|
||||
}
|
||||
|
||||
CardCollection list;
|
||||
if (cost.zoneRestriction != 1) {
|
||||
@@ -286,7 +293,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
int needed = Integer.parseInt(cost.getAmount().split("\\+")[0]);
|
||||
final int total = AbilityUtils.calculateAmount(source, totalM, ability);
|
||||
final InputSelectCardsFromList inp =
|
||||
new InputSelectCardsFromList(controller, needed, list.size(), list, ability, total);
|
||||
new InputSelectCardsFromList(controller, needed, list.size(), list, ability, "CMC", total);
|
||||
inp.setMessage(Localizer.getInstance().getMessage("lblSelectToExile", Lang.getNumeral(needed)));
|
||||
inp.setCancelAllowed(true);
|
||||
inp.showAndWait();
|
||||
@@ -297,6 +304,21 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
return PaymentDecision.card(inp.getSelected());
|
||||
}
|
||||
|
||||
if (nTypes > -1) {
|
||||
final InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, 1, list.size(), list,
|
||||
ability, "Types", nTypes);
|
||||
inp.setMessage(cost.getAmount().equals("X") ?
|
||||
Localizer.getInstance().getMessage("lblSelectAnyNumToExile") :
|
||||
Localizer.getInstance().getMessage("lblSelectToExile", Lang.getNumeral(nTypes)));
|
||||
inp.setCancelAllowed(true);
|
||||
inp.showAndWait();
|
||||
if (inp.hasCancelled() ||
|
||||
!Expressions.compare(CardFactoryUtil.getCardTypesFromList(list), "GE", nTypes)) {
|
||||
return null;
|
||||
}
|
||||
return PaymentDecision.card(inp.getSelected());
|
||||
}
|
||||
|
||||
int c = cost.getAbilityAmount(ability);
|
||||
|
||||
if (list.size() < c) {
|
||||
|
||||
Reference in New Issue
Block a user