From 90c3a13e3d0583b10052977a20c20cb80d92c5f1 Mon Sep 17 00:00:00 2001 From: tool4ever Date: Fri, 15 Dec 2023 09:58:30 +0100 Subject: [PATCH] Fix facedown permanent with adventure (#4355) * Restore adventure text when card not in play * Remove obsolete code * Fix crash with Cybership * Fix NPE --- .../src/main/java/forge/ai/ability/AttachAi.java | 4 +--- forge-ai/src/main/java/forge/ai/ability/FogAi.java | 8 ++++---- forge-game/src/main/java/forge/game/GameAction.java | 13 ++++--------- .../src/main/java/forge/game/GameLogFormatter.java | 4 ++-- forge-game/src/main/java/forge/game/PlanarDice.java | 9 +++------ .../java/forge/game/TriggerReplacementBase.java | 1 - .../java/forge/game/ability/effects/DigEffect.java | 5 ++--- forge-game/src/main/java/forge/game/card/Card.java | 7 ++----- forge-gui/res/cardsfolder/b/blood_for_bones.txt | 5 ++--- .../res/cardsfolder/t/timothar_baron_of_bats.txt | 2 +- 10 files changed, 21 insertions(+), 37 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/AttachAi.java b/forge-ai/src/main/java/forge/ai/ability/AttachAi.java index 62dd7c9df8c..729c94c84c4 100644 --- a/forge-ai/src/main/java/forge/ai/ability/AttachAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/AttachAi.java @@ -635,8 +635,7 @@ public class AttachAi extends SpellAbilityAi { } // Cards that trigger on dealing damage - private static Card attachAICuriosityPreference(final SpellAbility sa, final List list, final boolean mandatory, - final Card attachSource) { + private static Card attachAICuriosityPreference(final SpellAbility sa, final List list, final boolean mandatory, final Card attachSource) { Card chosen = null; int priority = 0; for (Card card : list) { @@ -690,7 +689,6 @@ public class AttachAi extends SpellAbilityAi { } } - return chosen; } /** diff --git a/forge-ai/src/main/java/forge/ai/ability/FogAi.java b/forge-ai/src/main/java/forge/ai/ability/FogAi.java index 44c89517017..6c197ca8d4f 100644 --- a/forge-ai/src/main/java/forge/ai/ability/FogAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/FogAi.java @@ -23,8 +23,8 @@ import forge.game.zone.ZoneType; public class FogAi extends SpellAbilityAi { /* (non-Javadoc) - * @see forge.card.abilityfactory.SpellAiLogic#canPlayAI(forge.game.player.Player, java.util.Map, forge.card.spellability.SpellAbility) - */ + * @see forge.card.abilityfactory.SpellAiLogic#canPlayAI(forge.game.player.Player, java.util.Map, forge.card.spellability.SpellAbility) + */ @Override protected boolean canPlayAI(Player ai, SpellAbility sa) { final Game game = ai.getGame(); @@ -121,7 +121,7 @@ public class FogAi extends SpellAbilityAi { int fogs = 0; for (Card c : ai.getCardsActivatableInExternalZones(false)) { for (SpellAbility ability : c.getSpellAbilities()) { - if (ability.getApi().equals(ApiType.Fog)) { + if (ApiType.Fog.equals(ability.getApi())) { fogs++; break; } @@ -130,7 +130,7 @@ public class FogAi extends SpellAbilityAi { for (Card c : ai.getCardsIn(ZoneType.Hand)) { for (SpellAbility ability : c.getSpellAbilities()) { - if (ability.getApi().equals(ApiType.Fog)) { + if (ApiType.Fog.equals(ability.getApi())) { fogs++; break; } diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 0d4c1de4fdb..026b8bfe3f2 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -510,11 +510,6 @@ public class GameAction { } } - // if an adventureCard is put from Stack somewhere else, need to reset to Original State - if (copied.isAdventureCard() && ((zoneFrom != null && zoneFrom.is(ZoneType.Stack)) || !zoneTo.is(ZoneType.Stack))) { - copied.setState(CardStateName.Original, false); - } - GameEntityCounterTable table = new GameEntityCounterTable(); if (mergedCards != null) { @@ -992,11 +987,11 @@ public class GameAction { if (!lki.getController().equals(lki.getOwner())) { game.getTriggerHandler().registerActiveLTBTrigger(lki); } + final Map runParams = AbilityKey.mapFromCard(c); + runParams.put(AbilityKey.CardLKI, lki); + runParams.put(AbilityKey.Origin, c.getZone().getZoneType().name()); + game.getTriggerHandler().runTrigger(TriggerType.ChangesZone, runParams, false); } - final Map runParams = AbilityKey.mapFromCard(c); - runParams.put(AbilityKey.CardLKI, lki); - runParams.put(AbilityKey.Origin, c.getZone().getZoneType().name()); - game.getTriggerHandler().runTrigger(TriggerType.ChangesZone, runParams, false); } } diff --git a/forge-game/src/main/java/forge/game/GameLogFormatter.java b/forge-game/src/main/java/forge/game/GameLogFormatter.java index 628d415860d..fba87ebc50a 100644 --- a/forge-game/src/main/java/forge/game/GameLogFormatter.java +++ b/forge-game/src/main/java/forge/game/GameLogFormatter.java @@ -143,13 +143,13 @@ public class GameLogFormatter extends IGameEventVisitor.Base { for (final GameOutcome game : gamesPlayed) { RegisteredPlayer player = game.getWinningPlayer(); - int amount = winCount.containsKey(player) ? winCount.get(player) : 0; + int amount = winCount.getOrDefault(player, 0); winCount.put(player, amount + 1); } final StringBuilder sb = new StringBuilder(); for (Entry entry : players.entrySet()) { - int amount = winCount.containsKey(entry.getKey()) ? winCount.get(entry.getKey()) : 0; + int amount = winCount.getOrDefault(entry.getKey(), 0); sb.append(entry.getValue()).append(": ").append(amount).append(" "); } diff --git a/forge-game/src/main/java/forge/game/PlanarDice.java b/forge-game/src/main/java/forge/game/PlanarDice.java index 7c549469c00..7f0b92c7f60 100644 --- a/forge-game/src/main/java/forge/game/PlanarDice.java +++ b/forge-game/src/main/java/forge/game/PlanarDice.java @@ -58,8 +58,6 @@ public enum PlanarDice { } PlanarDice res = results.get(0); - PlanarDice trigRes = res; - final Map resRepParams = AbilityKey.mapFromAffected(roller); resRepParams.put(AbilityKey.Result, res); @@ -67,14 +65,14 @@ public enum PlanarDice { case NotReplaced: break; case Updated: { - trigRes = (PlanarDice) resRepParams.get(AbilityKey.Result); + res = (PlanarDice) resRepParams.get(AbilityKey.Result); break; } } Map runParams = AbilityKey.mapFromPlayer(roller); - runParams.put(AbilityKey.Result, trigRes); - game.getTriggerHandler().runTrigger(TriggerType.PlanarDice, runParams,false); + runParams.put(AbilityKey.Result, res); + game.getTriggerHandler().runTrigger(TriggerType.PlanarDice, runParams, false); // Also run normal RolledDie and RolledDieOnce triggers for (int r = 0; r < rolls; r++) { @@ -98,7 +96,6 @@ public enum PlanarDice { * @return enum equivalent */ public static PlanarDice smartValueOf(String value) { - final String valToCompate = value.trim(); for (final PlanarDice v : PlanarDice.values()) { if (v.name().compareToIgnoreCase(valToCompate) == 0) { diff --git a/forge-game/src/main/java/forge/game/TriggerReplacementBase.java b/forge-game/src/main/java/forge/game/TriggerReplacementBase.java index cc2b4ebece3..eb71faacd76 100644 --- a/forge-game/src/main/java/forge/game/TriggerReplacementBase.java +++ b/forge-game/src/main/java/forge/game/TriggerReplacementBase.java @@ -38,7 +38,6 @@ public abstract class TriggerReplacementBase extends CardTraitBase implements II public Set getActiveZone() { return validHostZones; } - public void setActiveZone(EnumSet zones) { validHostZones = zones; } diff --git a/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java index cc1a68f625d..28874fe7d6d 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java @@ -374,9 +374,8 @@ public class DigEffect extends SpellAbilityEffect { for (Card c : movedCards) { final ZoneType origin = c.getZone().getZoneType(); - final PlayerZone zone = c.getOwner().getZone(destZone1); - if (zone.is(ZoneType.Library) || zone.is(ZoneType.PlanarDeck) || zone.is(ZoneType.SchemeDeck)) { + if (destZone1.equals(ZoneType.Library) || destZone1.equals(ZoneType.PlanarDeck) || destZone1.equals(ZoneType.SchemeDeck)) { c = game.getAction().moveTo(destZone1, c, libraryPosition, sa); } else { Map moveParams = AbilityKey.newMap(); @@ -410,7 +409,7 @@ public class DigEffect extends SpellAbilityEffect { host.removeRemembered(c); animate.setSVar("unanimateTimestamp", String.valueOf(game.getTimestamp())); } - c = game.getAction().moveTo(zone, c, sa, moveParams); + c = game.getAction().moveTo(c.getController().getZone(destZone1), c, sa, moveParams); if (destZone1.equals(ZoneType.Battlefield)) { if (addToCombat(c, c.getController(), sa, "Attacking", "Blocking")) { combatChanged = true; diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index ba1b5d3a85f..e6253473efd 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -2682,11 +2682,6 @@ public class Card extends GameEntity implements Comparable, IHasSVars { continue; } - // skip Basic Spells - if (sa.isSpell() && sa.isBasicSpell()) { - continue; - } - // should not print Spelldescription for Morph if (sa.isCastFaceDown()) { continue; @@ -2704,6 +2699,8 @@ public class Card extends GameEntity implements Comparable, IHasSVars { sbSA.append(": "); sbSA.append(sAbility); sAbility = sbSA.toString(); + } else if (sa.isSpell() && sa.isBasicSpell()) { + continue; } if (sa.getManaPart() != null) { diff --git a/forge-gui/res/cardsfolder/b/blood_for_bones.txt b/forge-gui/res/cardsfolder/b/blood_for_bones.txt index 949a151a314..366acde1f78 100644 --- a/forge-gui/res/cardsfolder/b/blood_for_bones.txt +++ b/forge-gui/res/cardsfolder/b/blood_for_bones.txt @@ -1,8 +1,7 @@ Name:Blood for Bones ManaCost:3 B Types:Sorcery -A:SP$ ChangeZone | Cost$ 3 B Sac<1/Creature> | Origin$ Graveyard | Destination$ Battlefield | Hidden$ True | Mandatory$ True | ChangeType$ Creature.YouOwn | PrimaryPrompt$ Choose a creature card to return to the battlefield | ChangeTypeDesc$ creature | RememberChanged$ True | SubAbility$ DBChangeZone | SpellDescription$ Return a creature card from your graveyard to the battlefield, then return another creature card from your graveyard to your hand. -SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | Hidden$ True | Mandatory$ True | ChangeType$ Creature.YouOwn+IsNotRemembered | PrimaryPrompt$ Choose another creature card to return to your hand | ChangeNumDesc$ another | ChangeTypeDesc$ creature | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +A:SP$ ChangeZone | Cost$ 3 B Sac<1/Creature> | Origin$ Graveyard | Destination$ Battlefield | Hidden$ True | Mandatory$ True | ChangeType$ Creature.YouOwn | PrimaryPrompt$ Choose a creature card to return to the battlefield | ChangeTypeDesc$ creature | SubAbility$ DBChangeZone | SpellDescription$ Return a creature card from your graveyard to the battlefield, then return another creature card from your graveyard to your hand. +SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | Hidden$ True | Mandatory$ True | ChangeType$ Creature.YouOwn | PrimaryPrompt$ Choose another creature card to return to your hand | ChangeNumDesc$ another | ChangeTypeDesc$ creature AI:RemoveDeck:Random Oracle:As an additional cost to cast this spell, sacrifice a creature.\nReturn a creature card from your graveyard to the battlefield, then return another creature card from your graveyard to your hand. diff --git a/forge-gui/res/cardsfolder/t/timothar_baron_of_bats.txt b/forge-gui/res/cardsfolder/t/timothar_baron_of_bats.txt index 8ebdd33e1ff..11200b1b0c2 100644 --- a/forge-gui/res/cardsfolder/t/timothar_baron_of_bats.txt +++ b/forge-gui/res/cardsfolder/t/timothar_baron_of_bats.txt @@ -8,7 +8,7 @@ SVar:TrigToken:AB$ Token | Cost$ 1 ExileAnyGrave<1/Card.TriggeredNewCard> | Toke SVar:DBAnimate:DB$ Animate | Defined$ Imprinted | Duration$ Permanent | Triggers$ CDTrigger SVar:CDTrigger:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigSac | TriggerZones$ Battlefield | TriggerDescription$ When this creature deals combat damage to a player, sacrifice it and return the exiled card to the battlefield tapped. SVar:TrigSac:DB$ Sacrifice | SubAbility$ DBReturn -SVar:DBReturn:DB$ ChangeZone | Defined$ Remembered | Origin$ Exile | Destination$ Battlefield | Tapped$ True +SVar:DBReturn:DB$ ChangeZone | Defined$ Remembered | Origin$ Exile | Destination$ Battlefield | Tapped$ True | GainControl$ True DeckNeeds:Type$Vampire DeckHas:Ability$Token|Sacrifice Oracle:Ward—Discard a card.\nWhenever another nontoken Vampire you control dies, you may pay {1} and exile it. If you do, create a 1/1 black Bat creature token with flying. It gains "When this creature deals combat damage to a player, sacrifice it and return the exiled card to the battlefield tapped."