diff --git a/forge-ai/src/main/java/forge/ai/AiController.java b/forge-ai/src/main/java/forge/ai/AiController.java index 94ae941f7bd..3385bca089c 100644 --- a/forge-ai/src/main/java/forge/ai/AiController.java +++ b/forge-ai/src/main/java/forge/ai/AiController.java @@ -1097,9 +1097,9 @@ public class AiController { if (landsWannaPlay != null && !landsWannaPlay.isEmpty() && player.canPlayLand(null)) { Card land = chooseBestLandToPlay(landsWannaPlay); if (ComputerUtil.damageFromETB(player, land) < player.getLife() || !player.canLoseLife()) { - Ability.PLAY_LAND_SURROGATE.setHostCard(land); + game.PLAY_LAND_SURROGATE.setHostCard(land); final List abilities = new ArrayList(); - abilities.add(Ability.PLAY_LAND_SURROGATE); + abilities.add(game.PLAY_LAND_SURROGATE); return abilities; } } diff --git a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java index 0f506f907cc..885fdff5c4f 100644 --- a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java +++ b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java @@ -397,10 +397,9 @@ public class PlayerControllerAi extends PlayerController { @Override public void playChosenSpellAbility(SpellAbility sa) { // System.out.println("Playing sa: " + sa); - if (sa == Ability.PLAY_LAND_SURROGATE) { + if (sa == sa.getHostCard().getGame().PLAY_LAND_SURROGATE) { player.playLand(sa.getHostCard(), false); - } - else { + } else { ComputerUtil.handlePlayingSpellAbility(player, sa, game); } } diff --git a/forge-ai/src/main/java/forge/ai/simulation/GameSimulator.java b/forge-ai/src/main/java/forge/ai/simulation/GameSimulator.java index fc319bc32cc..7019f5e0368 100644 --- a/forge-ai/src/main/java/forge/ai/simulation/GameSimulator.java +++ b/forge-ai/src/main/java/forge/ai/simulation/GameSimulator.java @@ -15,7 +15,6 @@ import forge.game.GameObject; import forge.game.card.Card; import forge.game.card.CardCollection; import forge.game.player.Player; -import forge.game.spellability.Ability; import forge.game.spellability.SpellAbility; import forge.game.spellability.TargetChoices; import forge.game.spellability.TargetRestrictions; @@ -152,7 +151,7 @@ public class GameSimulator { } } - if (sa == Ability.PLAY_LAND_SURROGATE) { + if (sa == origSa.getHostCard().getGame().PLAY_LAND_SURROGATE) { aiPlayer.playLand(sa.getHostCard(), false); } else { if (debugPrint && !sa.getAllTargetChoices().isEmpty()) { diff --git a/forge-game/src/main/java/forge/game/Game.java b/forge-game/src/main/java/forge/game/Game.java index b254c37056f..3a7fe5e8094 100644 --- a/forge-game/src/main/java/forge/game/Game.java +++ b/forge-game/src/main/java/forge/game/Game.java @@ -44,6 +44,7 @@ import forge.game.card.CardLists; import forge.game.card.CardPredicates; import forge.game.card.CardView; import forge.game.combat.Combat; +import forge.game.cost.Cost; import forge.game.event.Event; import forge.game.event.GameEventGameOutcome; import forge.game.phase.Phase; @@ -107,6 +108,19 @@ public class Game { private final GameView view; private final Tracker tracker = new Tracker(); + public final Ability PLAY_LAND_SURROGATE = new Ability(null, (Cost) null) { + @Override + public boolean canPlay() { + return true; //if this ability is added anywhere, it can be assumed that land can be played + } + @Override + public void resolve() { + throw new RuntimeException("This ability is intended to indicate \"land to play\" choice only"); + } + @Override + public String toUnsuppressedString() { return "Play land"; } + }; + private final GameEntityCache playerCache = new GameEntityCache<>(); public Player getPlayer(PlayerView playerView) { return playerCache.get(playerView); @@ -140,7 +154,7 @@ public class Game { rules = rules0; match = match0; - spabCache.put(Ability.PLAY_LAND_SURROGATE.getId(), Ability.PLAY_LAND_SURROGATE); + spabCache.put(PLAY_LAND_SURROGATE.getId(), PLAY_LAND_SURROGATE); int highestTeam = -1; for (RegisteredPlayer psc : players0) { 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 9f395b3905a..e34036fae09 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -6427,8 +6427,8 @@ public class Card extends GameEntity implements Comparable { } if (getState(CardStateName.Original).getType().isLand() && player.canPlayLand(this)) { - Ability.PLAY_LAND_SURROGATE.setHostCard(this); - abilities.add(Ability.PLAY_LAND_SURROGATE); + game.PLAY_LAND_SURROGATE.setHostCard(this); + abilities.add(game.PLAY_LAND_SURROGATE); } return abilities; diff --git a/forge-game/src/main/java/forge/game/spellability/Ability.java b/forge-game/src/main/java/forge/game/spellability/Ability.java index 4c8d7c97dd1..2880966829e 100644 --- a/forge-game/src/main/java/forge/game/spellability/Ability.java +++ b/forge-game/src/main/java/forge/game/spellability/Ability.java @@ -76,16 +76,4 @@ public abstract class Ability extends SpellAbility { return this.getHostCard().isInPlay() && !this.getHostCard().isFaceDown(); } - public static final Ability PLAY_LAND_SURROGATE = new Ability(null, (Cost) null) { - @Override - public boolean canPlay() { - return true; //if this ability is added anywhere, it can be assumed that land can be played - } - @Override - public void resolve() { - throw new RuntimeException("This ability is intended to indicate \"land to play\" choice only"); - } - @Override - public String toUnsuppressedString() { return "Play land"; } - }; } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java b/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java index f1d3481f3ec..2ba76261dae 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java @@ -813,6 +813,7 @@ public final class CMatchUI @Override public void afterGameEnd() { + Singletons.getView().getLpnDocument().remove(targetingOverlay.getPanel()); FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() { Singletons.getView().getNavigationBar().closeTab(screen); diff --git a/forge-gui/src/main/java/forge/match/HostedMatch.java b/forge-gui/src/main/java/forge/match/HostedMatch.java index 4911297c4ba..e575de2759e 100644 --- a/forge-gui/src/main/java/forge/match/HostedMatch.java +++ b/forge-gui/src/main/java/forge/match/HostedMatch.java @@ -215,7 +215,7 @@ public class HostedMatch { // It's important to run match in a different thread to allow GUI inputs to be invoked from inside game. // Game is set on pause while gui player takes decisions game.getAction().invoke(new Runnable() { - @Override public void run() { + @Override public final void run() { if (humanCount == 0) { // Create FControlGamePlayback in game thread to allow pausing playbackControl = new FControlGamePlayback(humanControllers.get(0)); @@ -235,6 +235,9 @@ public class HostedMatch { addNextGameDecision(null, NextGameDecision.CONTINUE); } } + if (match.isMatchOver()) { + isMatchOver = true; + } } }); diff --git a/forge-gui/src/main/java/forge/match/input/InputPassPriority.java b/forge-gui/src/main/java/forge/match/input/InputPassPriority.java index 64b69484df6..ac6e87af596 100644 --- a/forge-gui/src/main/java/forge/match/input/InputPassPriority.java +++ b/forge-gui/src/main/java/forge/match/input/InputPassPriority.java @@ -23,7 +23,6 @@ import java.util.List; import forge.game.Game; import forge.game.card.Card; import forge.game.player.Player; -import forge.game.spellability.Ability; import forge.game.spellability.SpellAbility; import forge.model.FModel; import forge.player.GamePlayerUtil; @@ -161,7 +160,7 @@ public class InputPassPriority extends InputSyncronizedBase { if (sa.isSpell()) { return "cast spell"; } - if (sa == Ability.PLAY_LAND_SURROGATE) { + if (sa == card.getGame().PLAY_LAND_SURROGATE) { return "play land"; } return "activate ability"; diff --git a/forge-gui/src/main/java/forge/player/HumanPlay.java b/forge-gui/src/main/java/forge/player/HumanPlay.java index 815dbdb06ea..9eb10b5d8f8 100644 --- a/forge-gui/src/main/java/forge/player/HumanPlay.java +++ b/forge-gui/src/main/java/forge/player/HumanPlay.java @@ -1,5 +1,11 @@ package forge.player; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; + import com.google.common.base.Predicate; import com.google.common.collect.Iterables; @@ -12,14 +18,43 @@ import forge.game.ability.AbilityUtils; import forge.game.ability.ApiType; import forge.game.ability.effects.CharmEffect; import forge.game.ability.effects.FlipCoinEffect; -import forge.game.card.*; +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; -import forge.game.cost.*; +import forge.game.card.CardView; +import forge.game.card.CounterType; +import forge.game.cost.Cost; +import forge.game.cost.CostAddMana; +import forge.game.cost.CostDamage; +import forge.game.cost.CostDiscard; +import forge.game.cost.CostDraw; +import forge.game.cost.CostExile; +import forge.game.cost.CostFlipCoin; +import forge.game.cost.CostGainControl; +import forge.game.cost.CostGainLife; +import forge.game.cost.CostMill; +import forge.game.cost.CostPart; +import forge.game.cost.CostPartMana; +import forge.game.cost.CostPartWithList; +import forge.game.cost.CostPayLife; +import forge.game.cost.CostPayment; +import forge.game.cost.CostPutCardToLib; +import forge.game.cost.CostPutCounter; +import forge.game.cost.CostRemoveAnyCounter; +import forge.game.cost.CostRemoveCounter; +import forge.game.cost.CostReturn; +import forge.game.cost.CostReveal; +import forge.game.cost.CostSacrifice; +import forge.game.cost.CostTapType; +import forge.game.cost.PaymentDecision; import forge.game.mana.ManaCostAdjustment; import forge.game.mana.ManaCostBeingPaid; import forge.game.player.Player; import forge.game.player.PlayerView; -import forge.game.spellability.Ability; import forge.game.spellability.SpellAbility; import forge.game.spellability.TargetRestrictions; import forge.game.zone.ZoneType; @@ -31,12 +66,6 @@ import forge.util.FCollectionView; import forge.util.Lang; import forge.util.gui.SGuiChoose; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - public class HumanPlay { @@ -54,7 +83,7 @@ public class HumanPlay { public final static void playSpellAbility(final PlayerControllerHuman controller, final Player p, SpellAbility sa) { FThreads.assertExecutedByEdt(false); - if (sa == Ability.PLAY_LAND_SURROGATE) { + if (sa == controller.getGame().PLAY_LAND_SURROGATE) { p.playLand(sa.getHostCard(), false); return; }