From 7c3368a32e22c4535c543037869d2fd0622095f5 Mon Sep 17 00:00:00 2001 From: Tim Mocny Date: Thu, 16 Sep 2021 12:20:27 +0000 Subject: [PATCH] MID: Hostile Hostel // Creeping Inn and support --- .../main/java/forge/game/cost/CostExile.java | 18 +++++++----- .../upcoming/hostile_hostel_creeping_inn.txt | 28 +++++++++++++++++++ .../java/forge/player/HumanCostDecision.java | 14 ++++++---- 3 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 forge-gui/res/cardsfolder/upcoming/hostile_hostel_creeping_inn.txt diff --git a/forge-game/src/main/java/forge/game/cost/CostExile.java b/forge-game/src/main/java/forge/game/cost/CostExile.java index 3f1218b155f..7d3409d9397 100644 --- a/forge-game/src/main/java/forge/game/cost/CostExile.java +++ b/forge-game/src/main/java/forge/game/cost/CostExile.java @@ -83,14 +83,15 @@ public class CostExile extends CostPartWithList { public final String toString() { final Integer i = this.convertAmount(); String desc = this.getTypeDescription() == null ? this.getType() : this.getTypeDescription(); + String origin = this.from.name().toLowerCase(); if (this.payCostFromSource()) { if (!this.from.equals(ZoneType.Battlefield)) { - return String.format("Exile %s from your %s", this.getType(), this.from.name()); + return String.format("Exile %s from your %s", this.getType(), origin); } return String.format("Exile %s", this.getType()); } else if (this.getType().equals("All")) { - return String.format("Exile all cards from your %s", this.from.name()); + return String.format("Exile all cards from your %s", origin); } if (this.from.equals(ZoneType.Battlefield)) { @@ -102,16 +103,16 @@ public class CostExile extends CostPartWithList { if (!desc.equals("Card") && !desc.endsWith("card")) { if (this.sameZone) { - return String.format("Exile card %s from the same %s", Cost.convertAmountTypeToWords(i, this.getAmount(), desc), this.from.name()); + return String.format("Exile card %s from the same %s", Cost.convertAmountTypeToWords(i, this.getAmount(), desc), origin); } - return String.format("Exile card %s from your %s", Cost.convertAmountTypeToWords(i, this.getAmount(), desc), this.from.name()); + return String.format("Exile card %s from your %s", Cost.convertAmountTypeToWords(i, this.getAmount(), desc), origin); } if (this.sameZone) { - return String.format("Exile %s from the same %s", Cost.convertAmountTypeToWords(i, this.getAmount(), desc), this.from.name()); + return String.format("Exile %s from the same %s", Cost.convertAmountTypeToWords(i, this.getAmount(), desc), origin); } - return String.format("Exile %s from your %s", Cost.convertAmountTypeToWords(i, this.getAmount(), desc), this.from.name()); + return String.format("Exile %s from your %s", Cost.convertAmountTypeToWords(i, this.getAmount(), desc), origin); } @Override @@ -171,7 +172,10 @@ public class CostExile extends CostPartWithList { @Override protected Card doPayment(SpellAbility ability, Card targetCard) { final Game game = targetCard.getGame(); - return game.getAction().exile(targetCard, null); + Card newCard = game.getAction().exile(targetCard, null); + newCard.setExiledWith(ability.getHostCard()); + newCard.setExiledBy(ability.getActivatingPlayer()); + return newCard; } public static final String HashLKIListKey = "Exiled"; diff --git a/forge-gui/res/cardsfolder/upcoming/hostile_hostel_creeping_inn.txt b/forge-gui/res/cardsfolder/upcoming/hostile_hostel_creeping_inn.txt new file mode 100644 index 00000000000..3b650f3f410 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/hostile_hostel_creeping_inn.txt @@ -0,0 +1,28 @@ +Name:Hostile Hostel +ManaCost:no cost +Types:Land +A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}. +A:AB$ PutCounter | Cost$ 1 T Sac<1/Creature/creature> | CounterType$ SOUL | CounterNum$ 1 | SubAbility$ DBBranch | SorcerySpeed$ True | SpellDescription$ Put a soul counter on CARDNAME. Then if there are three or more soul counters on it, remove those counters, transform it, then untap it. Activate only as a sorcery. +SVar:DBBranch:DB$ Branch | BranchConditionSVar$ Soul | TrueSubAbility$ DBRemoveCtrs | StackDescription$ Then if there are three or more soul counters on it, remove those counters, transform it, then untap it. Activate only as a sorcery. +SVar:DBRemoveCtrs:DB$ RemoveCounter | Defined$ Self | CounterType$ SOUL | CounterNum$ All | SubAbility$ DBTransform +SVar:DBTransform:DB$ SetState | Defined$ Self | Mode$ Transform | SubAbility$ DBUntap +SVar:DBUntap:DB$ Untap +SVar:Soul:Count$Valid Card.Self+counters_GE3_SOUL +AlternateMode:DoubleFaced +DeckHas:Ability$Mana.Colorless & Ability$Sacrifice & Ability$Counters +Oracle:{T}: Add {C}.\n{1}, {T}, Sacrifice a creature: Put a soul counter on Hostile Hostel. Then if there are three or more soul counters on it, remove those counters, transform it, then untap it. Activate only as a sorcery. + +ALTERNATE + +Name:Creeping Inn +ManaCost:no cost +Colors:black +Types:Artifact Creature Horror Construct +PT:3/7 +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigDrain | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME attacks, you may exile a creature card from your graveyard. If you do, each opponent loses X life and you gain X life, where X is the number of creature cards exiled with CARDNAME. +SVar:TrigDrain:AB$ LoseLife | Cost$ ExileFromGrave<1/Creature/creature card> | Defined$ Opponent | LifeAmount$ X | SubAbility$ DBGainLife +SVar:DBGainLife:DB$ GainLife | LifeAmount$ X +SVar:X:Count$ValidExile Creature.ExiledWithSource +A:AB$ Phases | Cost$ 4 | Defined$ Self | SpellDescription$ CARDNAME phases out. +DeckHas:Ability$LifeGain & Ability$Graveyard +Oracle:Whenever Creeping Inn attacks, you may exile a creature card from your graveyard. If you do, each opponent loses X life and you gain X life, where X is the number of creature cards exiled with Creeping Inn.\n{4}: Creeping Inn phases out. diff --git a/forge-gui/src/main/java/forge/player/HumanCostDecision.java b/forge-gui/src/main/java/forge/player/HumanCostDecision.java index 8b4306429ff..b3f34444f73 100644 --- a/forge-gui/src/main/java/forge/player/HumanCostDecision.java +++ b/forge-gui/src/main/java/forge/player/HumanCostDecision.java @@ -378,14 +378,16 @@ public class HumanCostDecision extends CostDecisionMakerBase { private PaymentDecision exileFromMiscZone(final CostExile cost, final SpellAbility sa, final int nNeeded, final CardCollection typeList) { if (typeList.size() < nNeeded) { return null; } - GameEntityViewMap gameCacheCard = GameEntityView.getMap(typeList); - + final List origin = Lists.newArrayList(); + origin.add(cost.from); final CardCollection exiled = new CardCollection(); - for (int i = 0; i < nNeeded; i++) { - final CardView cv = controller.getGui().oneOrNone(Localizer.getInstance().getMessage("lblExileProgressFromZone", String.valueOf(i + 1), String.valueOf(nNeeded), cost.getFrom().getTranslatedName()), gameCacheCard.getTrackableKeys()); - if (cv == null || !gameCacheCard.containsKey(cv)) { return null; } - exiled.add(gameCacheCard.remove(cv)); + final List chosen = controller.chooseCardsForZoneChange(ZoneType.Exile, origin, sa, typeList, 0, + nNeeded, null, cost.toString(), null); + + exiled.addAll(chosen); + if (exiled.isEmpty()) { + return null; } return PaymentDecision.card(exiled); }