From a83c06baf0913aa566d6e0be72f4e62539545d79 Mon Sep 17 00:00:00 2001 From: Lyu Zong-Hong Date: Mon, 12 Jul 2021 11:27:22 +0900 Subject: [PATCH] Add Dragon's Fire --- .../main/java/forge/ai/AiCostDecision.java | 2 +- .../src/main/java/forge/game/cost/Cost.java | 10 ++++-- .../main/java/forge/game/cost/CostReveal.java | 34 ++++++++++++++----- .../game/spellability/OptionalCostValue.java | 6 ++-- .../res/cardsfolder/upcoming/dragons_fire.txt | 8 +++++ 5 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 forge-gui/res/cardsfolder/upcoming/dragons_fire.txt diff --git a/forge-ai/src/main/java/forge/ai/AiCostDecision.java b/forge-ai/src/main/java/forge/ai/AiCostDecision.java index 8058d6d973c..b147420577f 100644 --- a/forge-ai/src/main/java/forge/ai/AiCostDecision.java +++ b/forge-ai/src/main/java/forge/ai/AiCostDecision.java @@ -533,7 +533,7 @@ public class AiCostDecision extends CostDecisionMakerBase { return null; } - if (cost.getRevealFrom().equals(ZoneType.Exile)) { + if (cost.getRevealFrom().get(0).equals(ZoneType.Exile)) { hand = CardLists.getValidCards(hand, type.split(";"), player, source, ability); return PaymentDecision.card(getBestCreatureAI(hand)); } diff --git a/forge-game/src/main/java/forge/game/cost/Cost.java b/forge-game/src/main/java/forge/game/cost/Cost.java index 28cf15de4df..80a0021c52f 100644 --- a/forge-game/src/main/java/forge/game/cost/Cost.java +++ b/forge-game/src/main/java/forge/game/cost/Cost.java @@ -193,7 +193,7 @@ public class Cost implements Serializable { } private Cost() { - + } private Cost(int genericMana) { @@ -440,7 +440,13 @@ public class Cost implements Serializable { if (parse.startsWith("RevealFromExile<")) { final String[] splitStr = abCostParse(parse, 3); final String description = splitStr.length > 2 ? splitStr[2] : null; - return new CostReveal(splitStr[0], splitStr[1], description, ZoneType.Exile); + return new CostReveal(splitStr[0], splitStr[1], description, "Exile"); + } + + if (parse.startsWith("RevealOrChoose<")) { + final String[] splitStr = abCostParse(parse, 3); + final String description = splitStr.length > 2 ? splitStr[2] : null; + return new CostReveal(splitStr[0], splitStr[1], description, "Hand,Battlefield"); } if (parse.startsWith("ExiledMoveToGrave<")) { diff --git a/forge-game/src/main/java/forge/game/cost/CostReveal.java b/forge-game/src/main/java/forge/game/cost/CostReveal.java index 602021a940e..d6003290689 100644 --- a/forge-game/src/main/java/forge/game/cost/CostReveal.java +++ b/forge-game/src/main/java/forge/game/cost/CostReveal.java @@ -17,6 +17,9 @@ */ package forge.game.cost; +import java.util.Arrays; +import java.util.List; + import com.google.common.base.Predicate; import forge.game.GameLogEntryType; @@ -39,15 +42,15 @@ public class CostReveal extends CostPartWithList { */ private static final long serialVersionUID = 1L; - private ZoneType revealFrom = ZoneType.Hand; + private List revealFrom = Arrays.asList(ZoneType.Hand); public CostReveal(final String amount, final String type, final String description) { super(amount, type, description); } - public CostReveal(final String amount, final String type, final String description, final ZoneType zoneType) { + public CostReveal(final String amount, final String type, final String description, final String zoneType) { super(amount, type, description); - this.revealFrom = zoneType; + this.revealFrom = ZoneType.listValueOf(zoneType); } @Override @@ -56,7 +59,7 @@ public class CostReveal extends CostPartWithList { @Override public boolean isRenewable() { return true; } - public ZoneType getRevealFrom() { + public List getRevealFrom() { return revealFrom; } @@ -83,7 +86,7 @@ public class CostReveal extends CostPartWithList { final Integer amount = this.convertAmount(); if (this.payCostFromSource()) { - return source.isInZone(revealFrom); + return revealFrom.contains(source.getLastKnownZone().getZoneType()); } else if (this.getType().equals("Hand")) { return true; } else if (this.getType().equals("SameColor")) { @@ -134,7 +137,16 @@ public class CostReveal extends CostPartWithList { } sb.append(" from your "); - sb.append(revealFrom.getTranslatedName()); + sb.append(revealFrom.get(0).getTranslatedName()); + + if (revealFrom.size() > 1) { + final StringBuilder desc = new StringBuilder(); + desc.append(this.getTypeDescription() == null ? this.getType() : this.getTypeDescription()); + desc.append(" card"); + sb.append(" or choose "); + sb.append(Cost.convertAmountTypeToWords(i, this.getAmount(), desc.toString())); + sb.append(" you control"); + } return sb.toString(); } @@ -143,7 +155,13 @@ public class CostReveal extends CostPartWithList { protected Card doPayment(SpellAbility ability, Card targetCard) { targetCard.getGame().getAction().reveal(new CardCollection(targetCard), ability.getActivatingPlayer()); StringBuilder sb = new StringBuilder(); - sb.append(ability.getActivatingPlayer()).append(" reveals ").append(targetCard).append(" to pay a cost for "); + sb.append(ability.getActivatingPlayer()); + if (targetCard.isInZone(ZoneType.Hand)) { + sb.append(" reveals "); + } else { + sb.append(" chooses "); + } + sb.append(targetCard).append(" to pay a cost for "); sb.append(ability); targetCard.getGame().getGameLog().add(GameLogEntryType.INFORMATION, sb.toString()); return targetCard; @@ -177,7 +195,7 @@ public class CostReveal extends CostPartWithList { @Override public int paymentOrder() { // Caller of the Untamed needs the reveal to happen before the mana cost - if (!revealFrom.equals(ZoneType.Hand)) { return -1; } + if (!revealFrom.get(0).equals(ZoneType.Hand)) { return -1; } return 5; } } diff --git a/forge-game/src/main/java/forge/game/spellability/OptionalCostValue.java b/forge-game/src/main/java/forge/game/spellability/OptionalCostValue.java index b6bb2a9e47c..bd38678c8bb 100644 --- a/forge-game/src/main/java/forge/game/spellability/OptionalCostValue.java +++ b/forge-game/src/main/java/forge/game/spellability/OptionalCostValue.java @@ -51,8 +51,10 @@ public class OptionalCostValue implements Serializable { @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append(type.getName()); - sb.append(" "); + if (type != OptionalCost.Generic) { + sb.append(type.getName()); + sb.append(" "); + } sb.append(cost.toSimpleString()); return sb.toString(); } diff --git a/forge-gui/res/cardsfolder/upcoming/dragons_fire.txt b/forge-gui/res/cardsfolder/upcoming/dragons_fire.txt new file mode 100644 index 00000000000..962298ec6bc --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/dragons_fire.txt @@ -0,0 +1,8 @@ +Name:Dragon's Fire +ManaCost:1 R +Types:Instant +K:Kicker:RevealOrChoose<1/Dragon>:Generic +A:SP$ DealDamage | ValidTgts$ Creature,Planeswalker | NumDmg$ 3 | Condition$ OptionalCost | ConditionOptionalPaid$ False | SubAbility$ DBDragonDamage | CostDesc$ As an additional cost to cast this spell, you may reveal a Dragon card from your hand or choose a Dragon you control. | StackDescription$ SpellDescription | SpellDescription$ CARDNAME deals 3 damage to target creature or planeswalker. If you revealed a Dragon card or chose a Dragon as you cast this spell, CARDNAME deals damage equal to the power of that card or creature instead. +SVar:DBDragonDamage:DB$ DealDamage | Defined$ Targeted | NumDmg$ X | Condition$ OptionalCost | ConditionOptionalPaid$ True | StackDescription$ +SVar:X:Revealed$CardPower +Oracle:As an additional cost to cast this spell, you may reveal a Dragon card from your hand or choose a Dragon you control.\nDragon's Fire deals 3 damage to target creature or planeswalker. If you revealed a Dragon card or chose a Dragon as you cast this spell, Dragon's Fire deals damage equal to the power of that card or creature instead.