diff --git a/.gitattributes b/.gitattributes index 2ec5bc66e56..585e4386d1a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1064,6 +1064,7 @@ forge-gui-mobile/libs/gdx-sources.jar -text forge-gui-mobile/libs/gdx.jar -text forge-gui-mobile/pom.xml -text forge-gui-mobile/src/forge/Forge.java -text +forge-gui-mobile/src/forge/GuiMobile.java -text forge-gui-mobile/src/forge/assets/CardFaceSymbols.java -text forge-gui-mobile/src/forge/assets/FImage.java -text forge-gui-mobile/src/forge/assets/FSkin.java -text @@ -1129,37 +1130,8 @@ forge-gui-mobile/src/forge/screens/draft/DraftScreen.java -text forge-gui-mobile/src/forge/screens/guantlet/GuantletScreen.java -text forge-gui-mobile/src/forge/screens/home/HomeScreen.java -text forge-gui-mobile/src/forge/screens/match/FControl.java -text -forge-gui-mobile/src/forge/screens/match/FControlGameEventHandler.java -text -forge-gui-mobile/src/forge/screens/match/FControlGamePlayback.java -text +forge-gui-mobile/src/forge/screens/match/InputSelectCard.java -text forge-gui-mobile/src/forge/screens/match/MatchScreen.java -text -forge-gui-mobile/src/forge/screens/match/events/IUiEventVisitor.java -text -forge-gui-mobile/src/forge/screens/match/events/UiEvent.java -text -forge-gui-mobile/src/forge/screens/match/events/UiEventAttackerDeclared.java -text -forge-gui-mobile/src/forge/screens/match/events/UiEventBlockerAssigned.java -text -forge-gui-mobile/src/forge/screens/match/input/ButtonUtil.java -text -forge-gui-mobile/src/forge/screens/match/input/Input.java -text -forge-gui-mobile/src/forge/screens/match/input/InputAttack.java -text -forge-gui-mobile/src/forge/screens/match/input/InputBase.java -text -forge-gui-mobile/src/forge/screens/match/input/InputBlock.java -text -forge-gui-mobile/src/forge/screens/match/input/InputConfirm.java -text -forge-gui-mobile/src/forge/screens/match/input/InputConfirmMulligan.java -text -forge-gui-mobile/src/forge/screens/match/input/InputLockUI.java -text -forge-gui-mobile/src/forge/screens/match/input/InputPassPriority.java -text -forge-gui-mobile/src/forge/screens/match/input/InputPayMana.java -text -forge-gui-mobile/src/forge/screens/match/input/InputPayManaOfCostPayment.java -text -forge-gui-mobile/src/forge/screens/match/input/InputPayManaSimple.java -text -forge-gui-mobile/src/forge/screens/match/input/InputPayManaX.java -text -forge-gui-mobile/src/forge/screens/match/input/InputPlaybackControl.java -text -forge-gui-mobile/src/forge/screens/match/input/InputProliferate.java -text -forge-gui-mobile/src/forge/screens/match/input/InputProxy.java -text -forge-gui-mobile/src/forge/screens/match/input/InputQueue.java -text -forge-gui-mobile/src/forge/screens/match/input/InputSelectCardsForConvoke.java -text -forge-gui-mobile/src/forge/screens/match/input/InputSelectCardsFromList.java -text -forge-gui-mobile/src/forge/screens/match/input/InputSelectEntitiesFromList.java -text -forge-gui-mobile/src/forge/screens/match/input/InputSelectManyBase.java -text -forge-gui-mobile/src/forge/screens/match/input/InputSelectTargets.java -text -forge-gui-mobile/src/forge/screens/match/input/InputSynchronized.java -text -forge-gui-mobile/src/forge/screens/match/input/InputSyncronizedBase.java -text forge-gui-mobile/src/forge/screens/match/views/VAssignDamage.java -text forge-gui-mobile/src/forge/screens/match/views/VAvatar.java -text forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java -text diff --git a/forge-gui-mobile-dev/.project b/forge-gui-mobile-dev/.project index 4dd8ef11dcb..b5c1f308fec 100644 --- a/forge-gui-mobile-dev/.project +++ b/forge-gui-mobile-dev/.project @@ -20,13 +20,6 @@ org.eclipse.m2e.core.maven2Nature org.eclipse.jdt.core.javanature - - - assets - 2 - copy_PARENT/forge-gui/res - - copy_PARENT diff --git a/forge-gui-mobile/src/forge/Forge.java b/forge-gui-mobile/src/forge/Forge.java index c6718aded33..397b061e022 100644 --- a/forge-gui-mobile/src/forge/Forge.java +++ b/forge-gui-mobile/src/forge/Forge.java @@ -52,6 +52,7 @@ public class Forge implements ApplicationListener { } game = this; clipboard = clipboard0; + GuiBase.setInterface(new GuiMobile()); } @Override diff --git a/forge-gui-mobile/src/forge/GuiMobile.java b/forge-gui-mobile/src/forge/GuiMobile.java new file mode 100644 index 00000000000..80a281ea71d --- /dev/null +++ b/forge-gui-mobile/src/forge/GuiMobile.java @@ -0,0 +1,311 @@ +package forge; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang3.tuple.Pair; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Texture; +import com.google.common.base.Function; + +import forge.assets.FSkin; +import forge.assets.FSkinProp; +import forge.assets.FTextureImage; +import forge.assets.ISkinImage; +import forge.deck.Deck; +import forge.deck.FDeckViewer; +import forge.error.BugReporter; +import forge.events.UiEvent; +import forge.game.Game; +import forge.game.GameEntity; +import forge.game.GameType; +import forge.game.card.Card; +import forge.game.combat.Combat; +import forge.game.event.GameEventTurnBegan; +import forge.game.phase.PhaseHandler; +import forge.game.phase.PhaseType; +import forge.game.player.LobbyPlayer; +import forge.game.player.Player; +import forge.game.player.RegisteredPlayer; +import forge.game.spellability.SpellAbility; +import forge.game.zone.ZoneType; +import forge.interfaces.IButton; +import forge.interfaces.IGuiBase; +import forge.item.PaperCard; +import forge.match.input.InputQueue; +import forge.screens.match.FControl; +import forge.screens.match.views.VPhaseIndicator.PhaseLabel; +import forge.screens.match.winlose.ViewWinLose; +import forge.toolbox.FOptionPane; +import forge.toolbox.GuiChoose; +import forge.util.ThreadUtil; + +public class GuiMobile implements IGuiBase { + @Override + public void invokeInEdtLater(Runnable proc) { + Gdx.app.postRunnable(proc); + } + + @Override + public void invokeInEdtAndWait(final Runnable proc) { + if (isGuiThread()) { + // Just run in the current thread. + proc.run(); + } + else { + //TODO + } + } + + @Override + public boolean isGuiThread() { + return !ThreadUtil.isGameThread(); + } + + @Override + public String getInstallRoot() { + switch (Gdx.app.getType()) { + case Desktop: + return "../forge-gui/"; + case Android: + break; + case Applet: + break; + case WebGL: + break; + case iOS: + break; + default: + break; + } + return ""; + } + + @Override + public String getAssetsDir() { + return "res/"; + } + + @Override + public boolean mayShowCard(Card card) { + return FControl.mayShowCard(card); + } + + @Override + public void reportBug(String details) { + BugReporter.reportBug(details); + } + + @Override + public void reportException(Throwable ex) { + BugReporter.reportException(ex); + } + + @Override + public void reportException(Throwable ex, String message) { + BugReporter.reportException(ex, message); + } + + @Override + public ISkinImage getUnskinnedIcon(String path) { + return new FTextureImage(new Texture(path)); + } + + @Override + public int showOptionDialog(String message, String title, FSkinProp icon, String[] options, int defaultOption) { + return FOptionPane.showOptionDialog(message, title, icon == null ? null : FSkin.getImages().get(icon), options, defaultOption); + } + + @Override + public T showInputDialog(String message, String title, FSkinProp icon, T initialInput, T[] inputOptions) { + return FOptionPane.showInputDialog(message, title, icon == null ? null : FSkin.getImages().get(icon), initialInput, inputOptions); + } + + @Override + public List getChoices(final String message, final int min, final int max, final Collection choices, final T selected, final Function display) { + return GuiChoose.getChoices(message, min, max, choices, selected, display); + } + + @Override + public List order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax, + final List sourceChoices, final List destChoices, final Card referenceCard, final boolean sideboardingMode) { + return GuiChoose.order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices, referenceCard, sideboardingMode); + } + + @Override + public void showCardList(final String title, final String message, final List list) { + Deck deck = new Deck(title + " - " + message); + deck.getMain().addAllFlat(list); + FDeckViewer.show(deck); + } + + @Override + public IButton getBtnOK() { + return FControl.getView().getPrompt().getBtnOk(); + } + + @Override + public IButton getBtnCancel() { + return FControl.getView().getPrompt().getBtnCancel(); + } + + @Override + public void focusButton(final IButton button) { + //not needed for mobile game + } + + @Override + public void flashIncorrectAction() { + //SDisplayUtil.remind(VPrompt.SINGLETON_INSTANCE); //TODO + } + + @Override + public void updatePhase() { + PhaseHandler pH = FControl.getGame().getPhaseHandler(); + Player p = pH.getPlayerTurn(); + PhaseType ph = pH.getPhase(); + + PhaseLabel lbl = FControl.getPlayerPanel(p).getPhaseIndicator().getLabel(ph); + + FControl.resetAllPhaseButtons(); + if (lbl != null) { + lbl.setActive(true); + } + } + + @Override + public void updateTurn(final GameEventTurnBegan event, final Game game) { + //VField nextField = FControl.getFieldViewFor(event.turnOwner); + //SDisplayUtil.showTab(nextField); + FControl.getView().getPrompt().updateText(game); + } + + @Override + public void updatePlayerControl() { + //TODO + } + + @Override + public void finishGame() { + new ViewWinLose(FControl.getGame()).setVisible(true); + } + + @Override + public void updateStack() { + FControl.getView().getStack().update(); + } + + @Override + public void startMatch(GameType gameType, List players) { + FControl.startMatch(gameType, players); + } + + @Override + public void setPanelSelection(Card c) { + //GuiUtils.setPanelSelection(c); //TODO + } + + @Override + public SpellAbility getAbilityToPlay(List abilities, Object triggerEvent) { + if (abilities.isEmpty()) { + return null; + } + if (abilities.size() == 1) { + return abilities.get(0); + } + return GuiChoose.oneOrNone("Choose ability to play", abilities); + } + + @Override + public void hear(LobbyPlayer player, String message) { + //FNetOverlay.SINGLETON_INSTANCE.addMessage(player.getName(), message); //TODO + } + + @Override + public int getAvatarCount() { + if (FSkin.isLoaded()) { + return FSkin.getAvatars().size(); + } + return 0; + } + + @Override + public void fireEvent(UiEvent e) { + FControl.fireEvent(e); + } + + @Override + public void setCard(Card card) { + FControl.setCard(card); + } + + @Override + public void showCombat(Combat combat) { + FControl.showCombat(combat); + } + + @Override + public void setUsedToPay(Card card, boolean b) { + FControl.setUsedToPay(card, b); + } + + @Override + public void setHighlighted(Player player, boolean b) { + FControl.setHighlighted(player, b); + } + + @Override + public void showPromptMessage(String message) { + FControl.showMessage(message); + } + + @Override + public boolean stopAtPhase(Player playerTurn, PhaseType phase) { + return FControl.stopAtPhase(playerTurn, phase); + } + + @Override + public InputQueue getInputQueue() { + return FControl.getInputQueue(); + } + + @Override + public Game getGame() { + return FControl.getGame(); + } + + @Override + public void updateZones(List> zonesToUpdate) { + FControl.updateZones(zonesToUpdate); + } + + @Override + public void updateCards(Set cardsToUpdate) { + FControl.updateCards(cardsToUpdate); + } + + @Override + public void updateManaPool(List manaPoolUpdate) { + FControl.updateManaPool(manaPoolUpdate); + } + + @Override + public void updateLives(List livesUpdate) { + FControl.updateLives(livesUpdate); + } + + @Override + public void endCurrentGame() { + FControl.endCurrentGame(); + } + + @Override + public Map getDamageToAssign(Card attacker, List blockers, + int damageDealt, GameEntity defender, boolean overrideOrder) { + return FControl.getDamageToAssign(attacker, blockers, + damageDealt, defender, overrideOrder); + } +} diff --git a/forge-gui-mobile/src/forge/assets/FImage.java b/forge-gui-mobile/src/forge/assets/FImage.java index d8fead1e944..34a09173618 100644 --- a/forge-gui-mobile/src/forge/assets/FImage.java +++ b/forge-gui-mobile/src/forge/assets/FImage.java @@ -2,7 +2,7 @@ package forge.assets; import forge.Forge.Graphics; -public interface FImage { +public interface FImage extends ISkinImage { float getWidth(); float getHeight(); void draw(Graphics g, float x, float y, float w, float h); diff --git a/forge-gui-mobile/src/forge/assets/FSkin.java b/forge-gui-mobile/src/forge/assets/FSkin.java index cb6c91b97ae..ac4260dea6b 100644 --- a/forge-gui-mobile/src/forge/assets/FSkin.java +++ b/forge-gui-mobile/src/forge/assets/FSkin.java @@ -7,7 +7,6 @@ import java.util.Map; import org.apache.commons.lang3.text.WordUtils; -import com.badlogic.gdx.Application.ApplicationType; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.Color; @@ -17,17 +16,13 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion; import forge.assets.FSkinImage.SourceFile; import forge.model.FModel; +import forge.properties.ForgeConstants; import forge.properties.ForgePreferences; import forge.properties.ForgePreferences.FPref; import forge.screens.SplashScreen; import forge.toolbox.FProgressBar; public class FSkin { - private static final String - FILE_SKINS_DIR = "skins/", - FILE_AVATAR_SPRITE = "sprite_avatars.png", - DEFAULT_DIR = FILE_SKINS_DIR + "default/"; - private static final Map images = new HashMap(); private static final Map avatars = new HashMap(); @@ -72,12 +67,12 @@ public class FSkin { // Non-default (preferred) skin name and dir. preferredName = skinName.toLowerCase().replace(' ', '_'); - preferredDir = FILE_SKINS_DIR + preferredName + "/"; + preferredDir = ForgeConstants.SKINS_DIR + preferredName + "/"; - FSkinTexture.BG_TEXTURE.load(preferredDir, DEFAULT_DIR); //load background texture early for splash screen + FSkinTexture.BG_TEXTURE.load(preferredDir, ForgeConstants.DEFAULT_SKINS_DIR); //load background texture early for splash screen if (splashScreen != null) { - final FileHandle f = Gdx.files.internal(preferredDir + "bg_splash.png"); + final FileHandle f = Gdx.files.local(preferredDir + "bg_splash.png"); if (!f.exists()) { if (!skinName.equals("default")) { FSkin.loadLight("default", splashScreen); @@ -138,12 +133,13 @@ public class FSkin { //FView.SINGLETON_INSTANCE.setSplashProgessBarMessage("Processing image sprites: ", 5); // Grab and test various sprite files. - final FileHandle f1 = Gdx.files.internal(DEFAULT_DIR + SourceFile.ICONS.getFilename()); - final FileHandle f2 = Gdx.files.internal(preferredDir + SourceFile.ICONS.getFilename()); - final FileHandle f3 = Gdx.files.internal(DEFAULT_DIR + SourceFile.FOILS.getFilename()); - final FileHandle f4 = Gdx.files.internal(DEFAULT_DIR + FILE_AVATAR_SPRITE); - final FileHandle f5 = Gdx.files.internal(preferredDir + FILE_AVATAR_SPRITE); - final FileHandle f6 = Gdx.files.internal(DEFAULT_DIR + SourceFile.OLD_FOILS.getFilename()); + String defaultDir = ForgeConstants.DEFAULT_SKINS_DIR; + final FileHandle f1 = Gdx.files.local(defaultDir + SourceFile.ICONS.getFilename()); + final FileHandle f2 = Gdx.files.local(preferredDir + SourceFile.ICONS.getFilename()); + final FileHandle f3 = Gdx.files.local(defaultDir + SourceFile.FOILS.getFilename()); + final FileHandle f4 = Gdx.files.local(defaultDir + ForgeConstants.SPRITE_AVATARS_FILE); + final FileHandle f5 = Gdx.files.local(preferredDir + ForgeConstants.SPRITE_AVATARS_FILE); + final FileHandle f6 = Gdx.files.local(defaultDir + SourceFile.OLD_FOILS.getFilename()); try { textures.put(f1.path(), new Texture(f1)); @@ -168,9 +164,9 @@ public class FSkin { //load images for (FSkinImage image : FSkinImage.values()) { - image.load(preferredDir, DEFAULT_DIR, textures, preferredIcons); + image.load(preferredDir, ForgeConstants.DEFAULT_SKINS_DIR, textures, preferredIcons); } - FSkinTexture.BG_MATCH.load(preferredDir, DEFAULT_DIR); + FSkinTexture.BG_MATCH.load(preferredDir, ForgeConstants.DEFAULT_SKINS_DIR); //assemble avatar textures int counter = 0; @@ -302,13 +298,7 @@ public class FSkin { public static ArrayList getSkinDirectoryNames() { final ArrayList mySkins = new ArrayList(); - final FileHandle dir; - if (Gdx.app.getType() == ApplicationType.Desktop) { - dir = Gdx.files.internal("./bin/" + FILE_SKINS_DIR); //needed to iterate over directory for Desktop - } - else { - dir = Gdx.files.internal(FILE_SKINS_DIR); - } + final FileHandle dir = Gdx.files.local(ForgeConstants.SKINS_DIR); if (!dir.exists() || !dir.isDirectory()) { System.err.println("FSkin > can't find skins directory!"); } diff --git a/forge-gui-mobile/src/forge/screens/match/FControl.java b/forge-gui-mobile/src/forge/screens/match/FControl.java index 86309163375..cab765feb5a 100644 --- a/forge-gui-mobile/src/forge/screens/match/FControl.java +++ b/forge-gui-mobile/src/forge/screens/match/FControl.java @@ -22,6 +22,12 @@ import com.google.common.eventbus.Subscribe; import forge.FThreads; import forge.Forge; import forge.card.CardCharacteristicName; +import forge.control.FControlGameEventHandler; +import forge.control.FControlGamePlayback; +import forge.events.IUiEventVisitor; +import forge.events.UiEvent; +import forge.events.UiEventAttackerDeclared; +import forge.events.UiEventBlockerAssigned; import forge.game.Game; import forge.game.GameEntity; import forge.game.GameRules; @@ -41,16 +47,12 @@ import forge.game.player.RegisteredPlayer; import forge.game.trigger.TriggerType; import forge.game.zone.Zone; import forge.game.zone.ZoneType; +import forge.match.input.InputProxy; +import forge.match.input.InputQueue; import forge.model.FModel; import forge.net.FServer; import forge.properties.ForgePreferences; import forge.properties.ForgePreferences.FPref; -import forge.screens.match.events.IUiEventVisitor; -import forge.screens.match.events.UiEvent; -import forge.screens.match.events.UiEventAttackerDeclared; -import forge.screens.match.events.UiEventBlockerAssigned; -import forge.screens.match.input.InputProxy; -import forge.screens.match.input.InputQueue; import forge.screens.match.views.VAssignDamage; import forge.screens.match.views.VCardDisplayArea.CardAreaPanel; import forge.screens.match.views.VPhaseIndicator; diff --git a/forge-gui-mobile/src/forge/screens/match/FControlGameEventHandler.java b/forge-gui-mobile/src/forge/screens/match/FControlGameEventHandler.java deleted file mode 100644 index 7bd2a7def03..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/FControlGameEventHandler.java +++ /dev/null @@ -1,388 +0,0 @@ -package forge.screens.match; - -import com.google.common.eventbus.Subscribe; - -import forge.FThreads; -import forge.game.Game; -import forge.game.card.Card; -import forge.game.event.*; -import forge.game.phase.PhaseHandler; -import forge.game.phase.PhaseType; -import forge.game.player.Player; -import forge.game.zone.PlayerZone; -import forge.game.zone.Zone; -import forge.game.zone.ZoneType; -import forge.net.FServer; -import forge.screens.match.views.VPhaseIndicator.PhaseLabel; -import forge.screens.match.winlose.ViewWinLose; -import forge.toolbox.GuiChoose; -import forge.util.Lang; -import forge.util.maps.MapOfLists; - -import org.apache.commons.lang3.tuple.Pair; - -import java.util.*; -import java.util.Map.Entry; -import java.util.concurrent.atomic.AtomicBoolean; - -public class FControlGameEventHandler extends IGameEventVisitor.Base { - public FControlGameEventHandler() { - } - - @Subscribe - public void receiveGameEvent(final GameEvent ev) { - ev.visit(this); - } - - private final AtomicBoolean phaseUpdPlanned = new AtomicBoolean(false); - @Override - public Void visit(final GameEventTurnPhase ev) { - if (phaseUpdPlanned.getAndSet(true)) return null; - - FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() { - PhaseHandler pH = FControl.getGame().getPhaseHandler(); - Player p = pH.getPlayerTurn(); - PhaseType ph = pH.getPhase(); - - phaseUpdPlanned.set(false); - - PhaseLabel lbl = FControl.getPlayerPanel(p).getPhaseIndicator().getLabel(ph); - - FControl.resetAllPhaseButtons(); - if (lbl != null) { lbl.setActive(true); } - } }); - return null; - } - - /* (non-Javadoc) - * @see forge.game.event.IGameEventVisitor.Base#visit(forge.game.event.GameEventPlayerPriority) - */ - private final AtomicBoolean combatUpdPlanned = new AtomicBoolean(false); - @Override - public Void visit(GameEventPlayerPriority event) { - if (combatUpdPlanned.getAndSet(true)) { return null; } - FThreads.invokeInEdtNowOrLater(new Runnable() { - @Override - public void run() { - combatUpdPlanned.set(false); - FControl.showCombat(FControl.getGame().getCombat()); - } - }); - return null; - } - - private final AtomicBoolean turnUpdPlanned = new AtomicBoolean(false); - @Override - public Void visit(final GameEventTurnBegan event) { - if (turnUpdPlanned.getAndSet(true)) { return null; } - - final Game game = FControl.getGame(); // to make sure control gets a correct game instance - FThreads.invokeInEdtNowOrLater(new Runnable() { - @Override - public void run() { - /*VField nextField = FControl.getFieldViewFor(event.turnOwner); - SDisplayUtil.showTab(nextField);*/ - - turnUpdPlanned.set(false); - FControl.getView().getPrompt().updateText(game); - } - }); - return null; - } - - @Override - public Void visit(GameEventAnteCardsSelected ev) { - // Require EDT here? - List options = new ArrayList(); - for (final Entry kv : ((GameEventAnteCardsSelected) ev).cards.entries()) { - options.add(" -- From " + Lang.getPossesive(kv.getKey().getName()) + " deck --"); - options.add(kv.getValue()); - } - GuiChoose.one("These cards were chosen to ante", options); - return null; - } - - @Override - public Void visit(GameEventPlayerControl ev) { - if (FControl.getGame().isGameOver()) { - return null; - } - - FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() { - /*FControl.initHandViews(FServer.getLobby().getGuiPlayer()); - SLayoutIO.loadLayout(null); - VMatchUI.SINGLETON_INSTANCE.populate(); - for (VHand h : VMatchUI.SINGLETON_INSTANCE.getHands()) { - h.getLayoutControl().updateHand(); - }*/ - } }); - return null; - } - - private final Runnable unlockGameThreadOnGameOver = new Runnable() { - @Override - public void run() { - FControl.getInputQueue().onGameOver(true); // this will unlock any game threads waiting for inputs to complete - } - }; - - @Override - public Void visit(GameEventGameOutcome ev) { - FThreads.invokeInEdtNowOrLater(unlockGameThreadOnGameOver); - return null; - } - - @Override - public Void visit(GameEventGameFinished ev) { - FThreads.invokeInEdtNowOrLater(new Runnable() { - @Override - public void run() { - new ViewWinLose(FControl.getGame()).setVisible(true); - } - }); - return null; - } - - private final AtomicBoolean stackUpdPlanned = new AtomicBoolean(false); - private final Runnable updStack = new Runnable() { - @Override - public void run() { - stackUpdPlanned.set(false); - FControl.getView().getStack().update(); - } - }; - - @Override - public Void visit(GameEventSpellAbilityCast event) { - if (!stackUpdPlanned.getAndSet(true)) { - FThreads.invokeInEdtNowOrLater(updStack); - } - return null; - } - @Override - public Void visit(GameEventSpellResolved event) { - if (!stackUpdPlanned.getAndSet(true)) { - FThreads.invokeInEdtNowOrLater(updStack); - } - return null; - } - @Override - public Void visit(GameEventSpellRemovedFromStack event) { - if (!stackUpdPlanned.getAndSet(true)) { - FThreads.invokeInEdtNowOrLater(updStack); - } - return null; - } - - private final List> zonesToUpdate = new Vector>(); - private final Runnable updZones = new Runnable() { - @Override public void run() { - synchronized (zonesToUpdate) { - FControl.updateZones(zonesToUpdate); - zonesToUpdate.clear(); - } - } - }; - - @Override - public Void visit(GameEventZone event) { - if (event.player != null) { - // anything except stack will get here - updateZone(Pair.of(event.player, event.zoneType)); - } - return null; - } - - @Override - public Void visit(GameEventCardAttachment event) { - // TODO Auto-generated method stub - Game game = event.equipment.getGame(); - PlayerZone zEq = (PlayerZone)game.getZoneOf(event.equipment); - if (event.oldEntiy instanceof Card) { - updateZone(game.getZoneOf((Card)event.oldEntiy)); - } - if (event.newTarget instanceof Card) { - updateZone(game.getZoneOf((Card)event.newTarget)); - } - return updateZone(zEq); - } - - private Void updateZone(Zone z) { - return updateZone(Pair.of(z.getPlayer(), z.getZoneType())); - } - - private Void updateZone(Pair kv) { - boolean needUpdate = false; - synchronized (zonesToUpdate) { - needUpdate = zonesToUpdate.isEmpty(); - if (!zonesToUpdate.contains(kv)) { - zonesToUpdate.add(kv); - } - } - if (needUpdate) { - FThreads.invokeInEdtNowOrLater(updZones); - } - return null; - } - - private final Set cardsToUpdate = new HashSet(); - private final Runnable updCards = new Runnable() { - @Override - public void run() { - synchronized (cardsToUpdate) { - FControl.updateCards(cardsToUpdate); - cardsToUpdate.clear(); - } - } - }; - - @Override - public Void visit(GameEventCardTapped event) { - return updateSingleCard(event.card); - } - - @Override - public Void visit(GameEventCardPhased event) { - return updateSingleCard(event.card); - } - - @Override - public Void visit(GameEventCardDamaged event) { - return updateSingleCard(event.card); - } - - @Override - public Void visit(GameEventCardCounters event) { - return updateSingleCard(event.card); - } - - @Override - public Void visit(GameEventBlockersDeclared event) { // This is to draw icons on blockers declared by AI - for (MapOfLists kv : event.blockers.values()) { - for (Collection blockers : kv.values()) { - updateManyCards(blockers); - } - } - return super.visit(event); - } - - @Override - public Void visit(GameEventAttackersDeclared event) { - // Skip redraw for GUI player? - if (event.player.getLobbyPlayer() == FServer.getLobby().getGuiPlayer()) { - return null; - } - - // Update all attackers. - // Although they might have been updated when they were apped, there could be someone with vigilance, not redrawn yet. - updateManyCards(event.attackersMap.values()); - - return super.visit(event); - } - - @Override - public Void visit(GameEventCombatEnded event) { - // This should remove sword/shield icons from combatants by the time game moves to M2 - updateManyCards(event.attackers); - updateManyCards(event.blockers); - return null; - } - - private Void updateSingleCard(Card c) { - boolean needUpdate = false; - synchronized (cardsToUpdate) { - needUpdate = cardsToUpdate.isEmpty(); - if (!cardsToUpdate.contains(c)) { - cardsToUpdate.add(c); - } - } - if (needUpdate) { - FThreads.invokeInEdtNowOrLater(updCards); - } - return null; - } - - private Void updateManyCards(Collection cc) { - boolean needUpdate = false; - synchronized (cardsToUpdate) { - needUpdate = cardsToUpdate.isEmpty(); - cardsToUpdate.addAll(cc); - } - if (needUpdate) { - FThreads.invokeInEdtNowOrLater(updCards); - } - return null; - } - - /* (non-Javadoc) - * @see forge.game.event.IGameEventVisitor.Base#visit(forge.game.event.GameEventCardStatsChanged) - */ - @Override - public Void visit(GameEventCardStatsChanged event) { - // TODO Smart partial updates - return updateManyCards(event.cards); - } - - // Update manapool - private final List manaPoolUpdate = new Vector(); - private final Runnable updManaPool = new Runnable() { - @Override public void run() { - synchronized (manaPoolUpdate) { - FControl.updateManaPool(manaPoolUpdate); - manaPoolUpdate.clear(); - } - } - }; - - @Override - public Void visit(GameEventManaPool event) { - boolean invokeUpdate = false; - synchronized (manaPoolUpdate) { - if (!manaPoolUpdate.contains(event.player)) { - invokeUpdate = manaPoolUpdate.isEmpty(); - manaPoolUpdate.add(event.player); - } - } - if (invokeUpdate) - FThreads.invokeInEdtNowOrLater(updManaPool); - return null; - } - - // Update lives counters - private final List livesUpdate = new Vector(); - private final Runnable updLives = new Runnable() { - @Override public void run() { - synchronized (livesUpdate) { - FControl.updateLives(livesUpdate); - livesUpdate.clear(); - } - } - }; - @Override - public Void visit(GameEventPlayerLivesChanged event) { - boolean invokeUpdate = false; - synchronized (livesUpdate) { - if (!livesUpdate.contains(event.player)) { - invokeUpdate = livesUpdate.isEmpty(); - livesUpdate.add(event.player); - } - } - if (invokeUpdate) - FThreads.invokeInEdtNowOrLater(updLives); - return null; - } - - @Override - public Void visit(GameEventPlayerPoisoned event) { - boolean invokeUpdate = false; - synchronized (livesUpdate) { - if (!livesUpdate.contains(event.receiver)) { - invokeUpdate = livesUpdate.isEmpty(); - livesUpdate.add(event.receiver); - } - } - if (invokeUpdate) - FThreads.invokeInEdtNowOrLater(updLives); - return null; - } -} \ No newline at end of file diff --git a/forge-gui-mobile/src/forge/screens/match/FControlGamePlayback.java b/forge-gui-mobile/src/forge/screens/match/FControlGamePlayback.java deleted file mode 100644 index 6da9d9079af..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/FControlGamePlayback.java +++ /dev/null @@ -1,176 +0,0 @@ -package forge.screens.match; - -import com.google.common.eventbus.Subscribe; - -import forge.FThreads; -import forge.game.event.*; -import forge.screens.match.input.InputPlaybackControl; - -import java.util.concurrent.BrokenBarrierException; -import java.util.concurrent.CyclicBarrier; -import java.util.concurrent.atomic.AtomicBoolean; - -public class FControlGamePlayback extends IGameEventVisitor.Base { - private final InputPlaybackControl inputPlayback = new InputPlaybackControl(this); - private final AtomicBoolean paused = new AtomicBoolean(false); - - private final CyclicBarrier gameThreadPauser = new CyclicBarrier(2); - - public FControlGamePlayback() { - } - - @Subscribe - public void receiveGameEvent(final GameEvent ev) { ev.visit(this); } - - private int phasesDelay = 200; - private int combatDelay = 400; - private int castDelay = 400; - private int resolveDelay = 400; - - private boolean fasterPlayback = false; - - private void pauseForEvent(int delay) { - try { - Thread.sleep(fasterPlayback ? delay / 10 : delay); - } catch (InterruptedException e) { - // TODO Auto-generated catch block ignores the exception, but sends it to System.err and probably forge.log. - e.printStackTrace(); - } - } - - @Override - public Void visit(GameEventBlockersDeclared event) { - pauseForEvent(combatDelay); - return super.visit(event); - } - - /* (non-Javadoc) - * @see forge.game.event.IGameEventVisitor.Base#visit(forge.game.event.GameEventTurnPhase) - */ - @Override - public Void visit(GameEventTurnPhase ev) { - boolean isUiToStop = FControl.stopAtPhase(ev.playerTurn, ev.phase); - - switch(ev.phase) { - case COMBAT_END: - case COMBAT_DECLARE_ATTACKERS: - case COMBAT_DECLARE_BLOCKERS: - if (FControl.getGame().getPhaseHandler().inCombat()) { - pauseForEvent(combatDelay); - } - break; - default: - if (isUiToStop) { - pauseForEvent(phasesDelay); - } - break; - } - - return null; - } - - /* (non-Javadoc) - * @see forge.game.event.IGameEventVisitor.Base#visit(forge.game.event.GameEventDuelFinished) - */ - @Override - public Void visit(GameEventGameFinished event) { - FControl.getInputQueue().removeInput(inputPlayback); - return null; - } - - @Override - public Void visit(GameEventGameStarted event) { - FControl.getInputQueue().setInput(inputPlayback); - return null; - } - - @Override - public Void visit(GameEventLandPlayed event) { - pauseForEvent(resolveDelay); - return super.visit(event); - } - - @Override - public Void visit(final GameEventSpellResolved event) { - FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() { FControl.setCard(event.spell.getHostCard()); } }); - pauseForEvent(resolveDelay); - return null; - } - - /* (non-Javadoc) - * @see forge.game.event.IGameEventVisitor.Base#visit(forge.game.event.GameEventSpellAbilityCast) - */ - @Override - public Void visit(final GameEventSpellAbilityCast event) { - FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() { FControl.setCard(event.sa.getHostCard()); } }); - pauseForEvent(castDelay); - return null; - } - - /* (non-Javadoc) - * @see forge.game.event.IGameEventVisitor.Base#visit(forge.game.event.GameEventPlayerPriority) - */ - @Override - public Void visit(GameEventPlayerPriority event) { - if (paused.get()) { - try { - inputPlayback.onGamePaused(); - gameThreadPauser.await(); - gameThreadPauser.reset(); - } catch (InterruptedException e) { - e.printStackTrace(); - } catch (BrokenBarrierException e) { - e.printStackTrace(); - } - } - return null; - } - - public void onGameStopRequested() { - paused.set(false); - if (gameThreadPauser.getNumberWaiting() != 0) { - releaseGameThread(); - } - } - - private void releaseGameThread() { - // just need to run another thread through the barrier... not edt preferrably :) - - FControl.getGame().getAction().invoke(new Runnable() { - @Override - public void run() { - try { - gameThreadPauser.await(); - } catch (InterruptedException e) { - // TODO Auto-generated catch block ignores the exception, but sends it to System.err and probably forge.log. - e.printStackTrace(); - } catch (BrokenBarrierException e) { - // TODO Auto-generated catch block ignores the exception, but sends it to System.err and probably forge.log. - e.printStackTrace(); - } - } - }); - } - - public void resume() { - paused.set(false); - releaseGameThread(); - } - - public void pause() { - paused.set(true); - } - - public void singleStep() { - releaseGameThread(); - } - - /** - * TODO: Write javadoc for this method. - * @param isFast - */ - public void setSpeed(boolean isFast) { - fasterPlayback = isFast; - } - -} \ No newline at end of file diff --git a/forge-gui-mobile/src/forge/screens/match/InputSelectCard.java b/forge-gui-mobile/src/forge/screens/match/InputSelectCard.java new file mode 100644 index 00000000000..b3f3c120b5d --- /dev/null +++ b/forge-gui-mobile/src/forge/screens/match/InputSelectCard.java @@ -0,0 +1,41 @@ +package forge.screens.match; + +import java.util.ArrayList; +import java.util.List; + +import forge.game.card.Card; +import forge.game.spellability.SpellAbility; +import forge.match.input.Input; +import forge.match.input.InputPassPriority; +import forge.toolbox.FCardZoom; +import forge.toolbox.FCardZoom.ZoomController; + +public class InputSelectCard { + private InputSelectCard() { + } + + public static void selectCard(Card card, List orderedCards) { + Input currentInput = FControl.getInputQueue().getInput(); + if (currentInput == null) { return; } + + List orderedCardOptions = new ArrayList(orderedCards); //copy list to allow it being modified + + if (currentInput instanceof InputPassPriority) { + FCardZoom.show("Select a spell/ability", card, orderedCardOptions, new ZoomController() { + @Override + public List getOptions(final Card card) { + return card.getAllPossibleAbilities(FControl.getCurrentPlayer(), true); + } + + @Override + public boolean selectOption(final Card card, final SpellAbility option) { + FControl.getInputProxy().selectAbility(option); + return true; //TODO: Avoid hiding card zoom when selecting mana abilities + } + }); + } + else { + FControl.getInputProxy().selectCard(card, null); + } + } +} diff --git a/forge-gui-mobile/src/forge/screens/match/events/IUiEventVisitor.java b/forge-gui-mobile/src/forge/screens/match/events/IUiEventVisitor.java deleted file mode 100644 index 099b57092b7..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/events/IUiEventVisitor.java +++ /dev/null @@ -1,6 +0,0 @@ -package forge.screens.match.events; - -public interface IUiEventVisitor { - T visit(UiEventBlockerAssigned event); - T visit(UiEventAttackerDeclared event); -} \ No newline at end of file diff --git a/forge-gui-mobile/src/forge/screens/match/events/UiEvent.java b/forge-gui-mobile/src/forge/screens/match/events/UiEvent.java deleted file mode 100644 index 4f9fe1571bf..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/events/UiEvent.java +++ /dev/null @@ -1,7 +0,0 @@ -package forge.screens.match.events; - - -public abstract class UiEvent { - - public abstract T visit(IUiEventVisitor visitor); -} \ No newline at end of file diff --git a/forge-gui-mobile/src/forge/screens/match/events/UiEventAttackerDeclared.java b/forge-gui-mobile/src/forge/screens/match/events/UiEventAttackerDeclared.java deleted file mode 100644 index 1c5f755d332..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/events/UiEventAttackerDeclared.java +++ /dev/null @@ -1,32 +0,0 @@ -package forge.screens.match.events; - -import forge.game.GameEntity; -import forge.game.card.Card; - -/** - * TODO: Write javadoc for this type. - * - */ -public class UiEventAttackerDeclared extends UiEvent { - - public final Card attacker; - public final GameEntity defender; - - public UiEventAttackerDeclared(Card card, GameEntity currentDefender) { - attacker = card; - defender = currentDefender; - } - - @Override - public T visit(IUiEventVisitor visitor) { - return visitor.visit(this); - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return attacker.toString() + ( defender == null ? " removed from combat" : " declared to attack " + defender.getName() ); - } -} diff --git a/forge-gui-mobile/src/forge/screens/match/events/UiEventBlockerAssigned.java b/forge-gui-mobile/src/forge/screens/match/events/UiEventBlockerAssigned.java deleted file mode 100644 index fdd68954614..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/events/UiEventBlockerAssigned.java +++ /dev/null @@ -1,21 +0,0 @@ -package forge.screens.match.events; - -import forge.game.card.Card; - -public class UiEventBlockerAssigned extends UiEvent { - - public final Card blocker; - public final Card attackerBeingBlocked; - - public UiEventBlockerAssigned(Card card, Card currentAttacker) { - blocker = card; - attackerBeingBlocked = currentAttacker; - } - - @Override - public T visit(IUiEventVisitor visitor) { - return visitor.visit(this); - } - - -} \ No newline at end of file diff --git a/forge-gui-mobile/src/forge/screens/match/input/ButtonUtil.java b/forge-gui-mobile/src/forge/screens/match/input/ButtonUtil.java deleted file mode 100644 index d8a4164530a..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/ButtonUtil.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.screens.match.input; - -import forge.screens.match.FControl; -import forge.toolbox.FButton; - -/** - * Manages match UI OK/Cancel button enabling and focus - */ -public class ButtonUtil { - public static void setButtonText(String okLabel, String cancelLabel) { - getOk().setText(okLabel); - getCancel().setText(cancelLabel); - } - - public static void reset() { - disableAll(); - getOk().setText("OK"); - getCancel().setText("Cancel"); - } - - public static void enableAll() { - getOk().setEnabled(true); - getCancel().setEnabled(true); - } - - public static void disableAll() { - getOk().setEnabled(false); - getCancel().setEnabled(false); - } - - public static void enableOnlyOk() { - getOk().setEnabled(true); - getCancel().setEnabled(false); - } - - public static void enableOnlyCancel() { - getOk().setEnabled(false); - getCancel().setEnabled(true); - } - - private static FButton getOk() { - return FControl.getView().getPrompt().getBtnOk(); - } - - private static FButton getCancel() { - return FControl.getView().getPrompt().getBtnCancel(); - } -} diff --git a/forge-gui-mobile/src/forge/screens/match/input/Input.java b/forge-gui-mobile/src/forge/screens/match/input/Input.java deleted file mode 100644 index fd3c5f40f17..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/Input.java +++ /dev/null @@ -1,24 +0,0 @@ -package forge.screens.match.input; - -import java.util.List; - -import forge.game.card.Card; -import forge.game.player.Player; -import forge.game.spellability.SpellAbility; - -public interface Input { - - // showMessage() is always the first method called - void showMessageInitial(); - - void selectCard(final Card card, final List orderedCardOptions); - - void selectAbility(final SpellAbility ab); - - void selectPlayer(final Player player); - - void selectButtonOK(); - - void selectButtonCancel(); - -} \ No newline at end of file diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputAttack.java b/forge-gui-mobile/src/forge/screens/match/input/InputAttack.java deleted file mode 100644 index ed365434a2c..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputAttack.java +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.screens.match.input; - -import com.google.common.collect.Iterables; - -import forge.game.GameEntity; -import forge.game.ability.AbilityUtils; -import forge.game.card.Card; -import forge.game.card.CardPredicates; -import forge.game.combat.AttackingBand; -import forge.game.combat.Combat; -import forge.game.combat.CombatUtil; -import forge.game.player.Player; -import forge.game.zone.ZoneType; -import forge.screens.match.FControl; -import forge.screens.match.events.UiEventAttackerDeclared; -import forge.toolbox.FCardZoom; -import forge.toolbox.FCardZoom.ZoomController; - -import java.util.ArrayList; -import java.util.List; - -/** - * - * InputAttack class. - * - * - * @author Forge - * @version $Id: InputAttack.java 24769 2014-02-09 13:56:04Z Hellfish $ - */ -public class InputAttack extends InputSyncronizedBase { - /** Constant serialVersionUID=7849903731842214245L. */ - private static final long serialVersionUID = 7849903731842214245L; - - private final Combat combat; - private final List defenders; - private GameEntity currentDefender; - private final Player playerAttacks; - private final Player playerDeclares; - private AttackingBand activeBand = null; - - public InputAttack(Player attacks, Player declares, Combat combat) { - this.playerAttacks = attacks; - this.playerDeclares = declares; - this.combat = combat; - this.defenders = combat.getDefenders(); - } - - /** {@inheritDoc} */ - @Override - public final void showMessage() { - // TODO still seems to have some issues with multiple planeswalkers - - ButtonUtil.enableOnlyOk(); - - setCurrentDefender(defenders.isEmpty() ? null : defenders.get(0)); - - if ( null == currentDefender ) { - System.err.println("InputAttack has no potential defenders!"); - return; // should even throw here! - } - - List possibleAttackers = playerAttacks.getCardsIn(ZoneType.Battlefield); - for (Card c : Iterables.filter(possibleAttackers, CardPredicates.Presets.CREATURES)) { - if (c.hasKeyword("CARDNAME attacks each turn if able.")) { - for(GameEntity def : defenders ) { - if( CombatUtil.canAttack(c, def, combat) ) { - combat.addAttacker(c, currentDefender); - FControl.fireEvent(new UiEventAttackerDeclared(c, currentDefender)); - break; - } - } - } else if (c.hasStartOfKeyword("CARDNAME attacks specific player each combat if able")) { - final int i = c.getKeywordPosition("CARDNAME attacks specific player each combat if able"); - final String defined = c.getKeyword().get(i).split(":")[1]; - final Player player = AbilityUtils.getDefinedPlayers(c, defined, null).get(0); - if (player != null && CombatUtil.canAttack(c, player, combat)) { - combat.addAttacker(c, player); - FControl.fireEvent(new UiEventAttackerDeclared(c, player)); - } - } - } - } - - private void showCombat() { - // redraw sword icons - FControl.showCombat(combat); - } - - /** {@inheritDoc} */ - @Override - protected final void onOk() { - // TODO Add check to see if each must attack creature is attacking - // Propaganda costs could have been paid here. - setCurrentDefender(null); // remove highlights - activateBand(null); - stop(); - } - - @Override - protected final void onPlayerSelected(Player selected) { - if (defenders.contains(selected)) { - setCurrentDefender(selected); - } - else { - flashIncorrectAction(); // cannot attack that player - } - } - - public enum Option { - DECLARE_AS_ATTACKER("Declare as Attacker"), - REMOVE_FROM_COMBAT("Remove from Combat"), - ATTACK_THIS_DEFENDER("Attack this Defender"), - ACTIVATE_BAND("Activate Band"), - JOIN_BAND("Join Band"); - - private String text; - - private Option(String text0) { - text = text0; - } - - public String toString() { - return text; - } - } - - /** {@inheritDoc} */ - @Override - protected final void onCardSelected(final Card card, final List orderedCardOptions) { - FCardZoom.show(FControl.getView().getPrompt().getMessage(), - card, orderedCardOptions, new ZoomController() { - @Override - public List getOptions(final Card card) { - List options = new ArrayList(); - - if (card.getController().isOpponentOf(playerAttacks)) { - if (defenders.contains(card)) { // planeswalker? - options.add(Option.ATTACK_THIS_DEFENDER); - } - } - else if (combat.getAttackers().contains(card)) { - if (!card.hasKeyword("CARDNAME attacks each turn if able.") && - !card.hasStartOfKeyword("CARDNAME attacks specific player each combat if able")) { - options.add(Option.REMOVE_FROM_COMBAT); - } - - if (combat.isAttacking(card, currentDefender)) { - // Activate band by selecting/deselecting a band member - if (activeBand == null) { - options.add(Option.ACTIVATE_BAND); - } - else if (!activeBand.getAttackers().contains(card) && activeBand.canJoinBand(card)) { - options.add(Option.JOIN_BAND); - } - } - } - else if (playerAttacks.getZone(ZoneType.Battlefield).contains(card) && - CombatUtil.canAttack(card, currentDefender, combat)) { - options.add(Option.DECLARE_AS_ATTACKER); - - if (activeBand != null && activeBand.canJoinBand(card)) { - options.add(Option.JOIN_BAND); - } - } - - return options; - } - - @Override - public boolean selectOption(final Card card, final Option option) { - boolean hideZoomView = false; //keep zoom open while declaring attackers by default - - switch (option) { - case DECLARE_AS_ATTACKER: - if (combat.isAttacking(card)) { - combat.removeFromCombat(card); - } - declareAttacker(card); - showCombat(); - break; - case REMOVE_FROM_COMBAT: - combat.removeFromCombat(card); - FControl.setUsedToPay(card, false); - showCombat(); - activateBand(null); //When removing an attacker clear the attacking band - FControl.fireEvent(new UiEventAttackerDeclared(card, null)); - break; - case ATTACK_THIS_DEFENDER: - setCurrentDefender(card); - hideZoomView = true; //don't keep zoom open if choosing defender - break; - case ACTIVATE_BAND: - activateBand(combat.getBandOfAttacker(card)); - break; - case JOIN_BAND: //Join a band by selecting a non-active band member after activating a band - combat.removeFromCombat(card); - declareAttacker(card); - break; - } - showMessage(); - return hideZoomView; - } - }); - } - - private void declareAttacker(final Card card) { - combat.addAttacker(card, currentDefender, this.activeBand); - this.activateBand(this.activeBand); - updateMessage(); - - FControl.fireEvent(new UiEventAttackerDeclared(card, currentDefender)); - } - - private final void setCurrentDefender(GameEntity def) { - currentDefender = def; - for( GameEntity ge: defenders ) { - if ( ge instanceof Card) { - FControl.setUsedToPay((Card)ge, ge == def); - } - else if (ge instanceof Player) { - FControl.setHighlighted((Player) ge, ge == def); - } - } - - updateMessage(); - - // update UI - } - - private final void activateBand(AttackingBand band) { - if (this.activeBand != null) { - for(Card card : this.activeBand.getAttackers()) { - FControl.setUsedToPay(card, false); - } - } - this.activeBand = band; - - if (this.activeBand != null) { - for(Card card : this.activeBand.getAttackers()) { - FControl.setUsedToPay(card, true); - } - } - - // update UI - } - - private void updateMessage() { - StringBuilder sb = new StringBuilder(); - sb.append(playerDeclares.getName()).append(", "); - sb.append(playerAttacks == playerDeclares ? "declare attackers." : "declare attackers for " + playerAttacks.getName()).append("\n"); - sb.append("Selecting Creatures to Attack ").append(currentDefender).append("\n\n"); - sb.append("To change the current defender, click on the player or planeswalker you wish to attack.\n"); - sb.append("To attack as a band, click an attacking creature to activate its 'band', select another to join the band."); - - showMessage(sb.toString()); - } -} diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputBase.java b/forge-gui-mobile/src/forge/screens/match/input/InputBase.java deleted file mode 100644 index 8ca16e94e03..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputBase.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.screens.match.input; - -import java.util.List; - -import forge.game.Game; -import forge.game.card.Card; -import forge.game.phase.PhaseHandler; -import forge.game.player.Player; -import forge.game.spellability.SpellAbility; -import forge.screens.match.FControl; -import forge.toolbox.FCardZoom; -import forge.toolbox.FCardZoom.ZoomController; - -/** - * - * Abstract Input class. - * - * - * @author Forge - * @version $Id: InputBase.java 24769 2014-02-09 13:56:04Z Hellfish $ - */ -public abstract class InputBase implements java.io.Serializable, Input { - /** Constant serialVersionUID=-6539552513871194081L. */ - private static final long serialVersionUID = -6539552513871194081L; - private boolean finished = false; - protected final boolean isFinished() { return finished; } - protected final void setFinished() { - FCardZoom.hideZoom(); //ensure zoom hidden when input finished - finished = true; - } - - // showMessage() is always the first method called - @Override - public final void showMessageInitial() { - finished = false; - showMessage(); - } - - protected abstract void showMessage(); - - @Override - public final void selectPlayer(final Player player) { - if (isFinished()) { return; } - onPlayerSelected(player); - } - - @Override - public void selectAbility(SpellAbility ab) { } - - @Override - public final void selectButtonCancel() { - if (isFinished()) { return; } - onCancel(); - } - - @Override - public final void selectButtonOK() { - if (isFinished()) { return; } - onOk(); - } - - @Override - public final void selectCard(final Card card, final List orderedCardOptions) { - if (isFinished()) { return; } - onCardSelected(card, orderedCardOptions); - } - - protected void onCardSelected(final Card card, final List orderedCardOptions) { - //for base input, just show zoom view with no options - FCardZoom.show(FControl.getView().getPrompt().getMessage(), - card, orderedCardOptions, new ZoomController() { - @Override - public List getOptions(Card card) { - return null; - } - - @Override - public boolean selectOption(Card card, Object option) { - return true; - } - }); - } - - protected void onPlayerSelected(final Player p) {} - protected void onCancel() {} - protected void onOk() {} - - // to remove need for CMatchUI dependence - protected final void showMessage(String message) { - FControl.showMessage(message); - } - - protected final void flashIncorrectAction() { - FControl.getView().getPrompt().remind(); - } - - protected String getTurnPhasePriorityMessage(Game game) { - final PhaseHandler ph = game.getPhaseHandler(); - final StringBuilder sb = new StringBuilder(); - - sb.append("Priority: ").append(ph.getPriorityPlayer()).append("\n"); - sb.append("Turn ").append(ph.getTurn()).append(" (").append(ph.getPlayerTurn()).append(")\n"); - sb.append("Phase: ").append(ph.getPhase().nameForUi).append("\n"); - sb.append("Stack: "); - if (!game.getStack().isEmpty()) { - sb.append(game.getStack().size()).append(" to Resolve."); - } else { - sb.append("Empty"); - } - sb.append("\n"); - return sb.toString(); - } -} diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputBlock.java b/forge-gui-mobile/src/forge/screens/match/input/InputBlock.java deleted file mode 100644 index ebc4d948a2a..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputBlock.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.screens.match.input; - -import java.util.ArrayList; -import java.util.List; - -import forge.game.card.Card; -import forge.game.combat.Combat; -import forge.game.combat.CombatUtil; -import forge.game.player.Player; -import forge.game.zone.ZoneType; -import forge.screens.match.FControl; -import forge.screens.match.events.UiEventBlockerAssigned; -import forge.toolbox.FCardZoom; -import forge.toolbox.FOptionPane; -import forge.toolbox.FCardZoom.ZoomController; - -/** - * - * Input_Block class. - * - * - * @author Forge - * @version $Id: InputBlock.java 24769 2014-02-09 13:56:04Z Hellfish $ - */ -public class InputBlock extends InputSyncronizedBase { - /** Constant serialVersionUID=6120743598368928128L. */ - private static final long serialVersionUID = 6120743598368928128L; - - private Card currentAttacker = null; - // some cards may block several creatures at a time. (ex: Two-Headed Dragon, Vanguard's Shield) - private final Combat combat; - private final Player defender; - private final Player declarer; - - /** - * TODO: Write javadoc for Constructor. - * @param priority - */ - public InputBlock(Player whoDeclares, Player whoDefends, Combat combat) { - defender = whoDefends; - declarer = whoDeclares; - this.combat = combat; - } - - /** {@inheritDoc} */ - @Override - protected final void showMessage() { - // could add "Reset Blockers" button - ButtonUtil.enableOnlyOk(); - - String prompt = declarer == defender ? "declare blockers." : "declare blockers for " + defender.getName(); - - final StringBuilder sb = new StringBuilder(declarer.getName()); - sb.append(", ").append(prompt).append("\n\n"); - - if (this.currentAttacker == null) { - sb.append("To Block, click on your opponent's attacker first, then your blocker(s).\n"); - sb.append("To cancel a block right-click on your blocker"); - } - else { - final String attackerName = this.currentAttacker.isFaceDown() ? "Morph" : this.currentAttacker.getName(); - sb.append("Select a creature to block ").append(attackerName).append(" ("); - sb.append(this.currentAttacker.getUniqueNumber()).append("). "); - sb.append("To cancel a block right-click on your blocker"); - } - - showMessage(sb.toString()); - FControl.showCombat(combat); - } - - /** {@inheritDoc} */ - @Override - public final void onOk() { - String blockErrors = CombatUtil.validateBlocks(combat, defender); - if( null == blockErrors ) { - // Done blocking - ButtonUtil.reset(); - setCurrentAttacker(null); - stop(); - } - else { - FOptionPane.showMessageDialog(blockErrors); - } - } - - public enum Option { - DECLARE_AS_BLOCKER("Declare as Blocker"), - REMOVE_FROM_COMBAT("Remove from Combat"), - BLOCK_THIS_ATTACKER("Block this Attacker"),; - - private String text; - - private Option(String text0) { - text = text0; - } - - public String toString() { - return text; - } - } - - /** {@inheritDoc} */ - @Override - public final void onCardSelected(final Card card, final List orderedCardOptions) { - FCardZoom.show(FControl.getView().getPrompt().getMessage(), - card, orderedCardOptions, new ZoomController() { - @Override - public List getOptions(final Card card) { - List options = new ArrayList(); - - if (combat.isAttacking(card)) { - options.add(Option.BLOCK_THIS_ATTACKER); - } - else if (card.getController() == defender) { - if (combat.isBlocking(card)) { - options.add(Option.REMOVE_FROM_COMBAT); - } - else if (currentAttacker != null && card.isCreature() && - defender.getZone(ZoneType.Battlefield).contains(card) && - CombatUtil.canBlock(currentAttacker, card, combat)) { - options.add(Option.DECLARE_AS_BLOCKER); - } - } - - return options; - } - - @Override - public boolean selectOption(final Card card, final Option option) { - switch (option) { - case DECLARE_AS_BLOCKER: - combat.addBlocker(currentAttacker, card); - FControl.fireEvent(new UiEventBlockerAssigned(card, currentAttacker)); - break; - case REMOVE_FROM_COMBAT: - combat.removeFromCombat(card); - FControl.fireEvent(new UiEventBlockerAssigned(card, (Card)null)); - break; - case BLOCK_THIS_ATTACKER: - setCurrentAttacker(card); - break; - } - showMessage(); - return true; //hide zoom view after declaring blocker - } - }); - } - - private void setCurrentAttacker(Card card) { - currentAttacker = card; - for(Card c : combat.getAttackers()) { - FControl.setUsedToPay(c, card == c); - } - } -} diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputConfirm.java b/forge-gui-mobile/src/forge/screens/match/input/InputConfirm.java deleted file mode 100644 index b08f8c60403..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputConfirm.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.screens.match.input; - - /** - * - * InputConfirm class. - * - * - * @author Forge - * @version $Id: InputConfirm.java 21647 2013-05-24 22:31:11Z Max mtg $ - */ -public class InputConfirm extends InputSyncronizedBase { - private static final long serialVersionUID = -3591794991788531626L; - - private final String message; - private final String yesButtonText; - private final String noButtonText; - private boolean result; - - public InputConfirm(String message0) { - this(message0, "Yes", "No", true); - } - - public InputConfirm(String message0, String yesButtonText0, String noButtonText0) { - this(message0, yesButtonText0, noButtonText0, true); - } - - public InputConfirm(String message0, String yesButtonText0, String noButtonText0, boolean defaultYes0) { - this.message = message0; - this.yesButtonText = yesButtonText0; - this.noButtonText = noButtonText0; - result = defaultYes0; - } - - /** {@inheritDoc} */ - @Override - protected final void showMessage() { - ButtonUtil.setButtonText(this.yesButtonText, this.noButtonText); - ButtonUtil.enableAll(); - showMessage(this.message); - } - - /** {@inheritDoc} */ - @Override - protected final void onOk() { - this.result = true; - done(); - } - - /** {@inheritDoc} */ - @Override - protected final void onCancel() { - this.result = false; - done(); - } - - private void done() { - ButtonUtil.reset(); - stop(); - } - - public final boolean getResult() { - return this.result; - } -} diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputConfirmMulligan.java b/forge-gui-mobile/src/forge/screens/match/input/InputConfirmMulligan.java deleted file mode 100644 index e34ef14868f..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputConfirmMulligan.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.screens.match.input; - -import forge.game.Game; -import forge.game.card.Card; -import forge.game.player.Player; -import forge.game.zone.ZoneType; -import forge.screens.match.FControl; -import forge.toolbox.FCardZoom; -import forge.toolbox.GuiDialog; -import forge.toolbox.FCardZoom.ZoomController; -import forge.util.Lang; -import forge.util.ThreadUtil; - -import java.util.ArrayList; -import java.util.List; - -/** - * - * InputConfirmMulligan class. - * - * - * @author Forge - * @version $Id: InputConfirmMulligan.java 24769 2014-02-09 13:56:04Z Hellfish $ - */ -public class InputConfirmMulligan extends InputSyncronizedBase { - /** Constant serialVersionUID=-8112954303001155622L. */ - private static final long serialVersionUID = -8112954303001155622L; - - boolean keepHand = false; - final boolean isCommander; - - private final List selected = new ArrayList(); - private final Player player; - private final Player startingPlayer; - - public InputConfirmMulligan(Player humanPlayer, Player startsGame, boolean commander) { - player = humanPlayer; - isCommander = commander; - startingPlayer = startsGame; - } - - /** {@inheritDoc} */ - @Override - public final void showMessage() { - Game game = player.getGame(); - - StringBuilder sb = new StringBuilder(); - if (startingPlayer == player) { - sb.append(player).append(", you are going first!\n\n"); - } - else { - sb.append(startingPlayer.getName()).append(" is going first.\n"); - sb.append(player).append(", you are going ").append(Lang.getOrdinal(game.getPosition(player, startingPlayer))).append(".\n\n"); - } - - if (isCommander) { - ButtonUtil.setButtonText("Keep", "Exile"); - ButtonUtil.enableOnlyOk(); - sb.append("Will you keep your hand or choose some cards to exile those and draw one less card?"); - } - else { - ButtonUtil.setButtonText("Keep", "Mulligan"); - ButtonUtil.enableAll(); - sb.append("Do you want to keep your hand?"); - } - - showMessage(sb.toString()); - } - - /** {@inheritDoc} */ - @Override - protected final void onOk() { - keepHand = true; - done(); - } - - /** {@inheritDoc} */ - @Override - protected final void onCancel() { - keepHand = false; - done(); - } - - private void done() { - ButtonUtil.reset(); - if (isCommander) { - // Clear the "selected" icon after clicking the done button - for (Card c : this.selected) { - FControl.setUsedToPay(c, false); - } - } - stop(); - } - - volatile boolean cardSelectLocked = false; - - @Override - protected void onCardSelected(final Card card, final List orderedCardOptions) { // the only place that would cause troubles - input is supposed only to confirm, not to fire abilities - if (cardSelectLocked) { return; } - - FCardZoom.show(FControl.getView().getPrompt().getMessage(), - card, orderedCardOptions, new ZoomController() { - @Override - public List getOptions(final Card card) { - List options = new ArrayList(); - - if (player.getZone(ZoneType.Hand).contains(card)) { - if (card.getName().equals("Serum Powder")) { - options.add("Exile all the cards from your hand, then draw that many cards."); - } - else if (isCommander) { - if (selected.contains(card)) { - options.add("Select Card"); - } - else { - options.add("Unselect Card"); - } - } - } - return options; - } - - @Override - public boolean selectOption(final Card card, final String option) { - if (option == "Exile all the cards from your hand, then draw that many cards.") { - if (GuiDialog.confirm(card, "This action cannot be undone. Proceed?")) { - cardSelectLocked = true; - ThreadUtil.invokeInGameThread(new Runnable() { - public void run() { - List hand = new ArrayList(card.getController().getCardsIn(ZoneType.Hand)); - for (Card c : hand) { - player.getGame().getAction().exile(c); - } - card.getController().drawCards(hand.size()); - cardSelectLocked = false; - } - }); - } - return true; - } - if (isCommander) { // allow to choose cards for partial paris - if (selected.contains(card)) { - FControl.setUsedToPay(card, false); - selected.remove(card); - } - else { - FControl.setUsedToPay(card, true); - selected.add(card); - } - if (selected.isEmpty()) { - ButtonUtil.enableOnlyOk(); - } - else { - ButtonUtil.enableAll(); - } - return false; //keep zoom view open - } - return true; - } - }); - - - } - - public final boolean isKeepHand() { - return keepHand; - } - - public List getSelectedCards() { - return selected; - } -} diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputLockUI.java b/forge-gui-mobile/src/forge/screens/match/input/InputLockUI.java deleted file mode 100644 index ce30e072ea8..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputLockUI.java +++ /dev/null @@ -1,66 +0,0 @@ -package forge.screens.match.input; - -import forge.FThreads; -import forge.game.card.Card; -import forge.game.player.Player; -import forge.game.spellability.SpellAbility; -import forge.screens.match.FControl; -import forge.util.ThreadUtil; - -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -public class InputLockUI implements Input { - private final AtomicInteger iCall = new AtomicInteger(); - - public InputLockUI(InputQueue inputQueue) { - } - - public void showMessageInitial() { - int ixCall = 1 + iCall.getAndIncrement(); - ThreadUtil.delay(500, new InputUpdater(ixCall)); - } - - @Override - public String toString() { - return "lockUI"; - } - - private class InputUpdater implements Runnable { - final int ixCall; - - public InputUpdater(final int idxCall) { - ixCall = idxCall; - } - - @Override - public void run() { - if ( ixCall != iCall.get() || !isActive()) // cancel the message if it's not from latest call or input is gone already - return; - FThreads.invokeInEdtLater(showMessageFromEdt); - } - }; - - private final Runnable showMessageFromEdt = new Runnable() { - - @Override - public void run() { - ButtonUtil.disableAll(); - showMessage("Waiting for actions..."); - } - }; - - protected final boolean isActive() { - return FControl.getInputQueue().getInput() == this; - } - - protected void showMessage(String message) { - FControl.showMessage(message); - } - - @Override public void selectCard(final Card card, final List orderedCardOptions) {} - @Override public void selectAbility(SpellAbility ab) {} - @Override public void selectPlayer(Player player) {} - @Override public void selectButtonOK() {} - @Override public void selectButtonCancel() {} -} diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputPassPriority.java b/forge-gui-mobile/src/forge/screens/match/input/InputPassPriority.java deleted file mode 100644 index 7df755ae7ba..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputPassPriority.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.screens.match.input; - -import forge.game.card.Card; -import forge.game.player.Player; -import forge.game.spellability.SpellAbility; -import forge.toolbox.FCardZoom; -import forge.toolbox.FCardZoom.ZoomController; - -import java.util.List; - -/** - * - * Input_PassPriority class. - * - * - * @author Forge - * @version $Id: InputPassPriority.java 24769 2014-02-09 13:56:04Z Hellfish $ - */ -public class InputPassPriority extends InputSyncronizedBase { - /** Constant serialVersionUID=-581477682214137181L. */ - private static final long serialVersionUID = -581477682214137181L; - private final Player player; - private SpellAbility chosenSa; - - public InputPassPriority(Player human) { - player = human; - } - - /** {@inheritDoc} */ - @Override - public final void showMessage() { - showMessage(getTurnPhasePriorityMessage(player.getGame())); - chosenSa = null; - ButtonUtil.enableOnlyOk(); - } - - /** {@inheritDoc} */ - @Override - protected final void onOk() { - stop(); - } - - public SpellAbility getChosenSa() { - return chosenSa; - } - - @Override - protected void onCardSelected(final Card card, final List orderedCardOptions) { - FCardZoom.show("Select a spell/ability", card, orderedCardOptions, new ZoomController() { - @Override - public List getOptions(final Card card) { - return card.getAllPossibleAbilities(player, true); - } - - @Override - public boolean selectOption(final Card card, final SpellAbility option) { - selectAbility(option); - return true; //TODO: Avoid hiding card zoom when selecting mana abilities - } - }); - } - - @Override - public void selectAbility(final SpellAbility ab) { - if (ab != null) { - chosenSa = ab; - stop(); - } - } -} diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputPayMana.java b/forge-gui-mobile/src/forge/screens/match/input/InputPayMana.java deleted file mode 100644 index 06eaaf9fdaf..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputPayMana.java +++ /dev/null @@ -1,360 +0,0 @@ -package forge.screens.match.input; - -import forge.FThreads; -import forge.ai.ComputerUtilMana; -import forge.ai.PlayerControllerAi; -import forge.card.ColorSet; -import forge.card.MagicColor; -import forge.card.mana.ManaAtom; -import forge.game.Game; -import forge.game.ability.ApiType; -import forge.game.card.Card; -import forge.game.card.CardUtil; -import forge.game.mana.ManaCostBeingPaid; -import forge.game.player.Player; -import forge.game.replacement.ReplacementEffect; -import forge.game.spellability.AbilityManaPart; -import forge.game.spellability.SpellAbility; -import forge.player.HumanPlay; -import forge.screens.match.FControl; -import forge.toolbox.FCardZoom; -import forge.toolbox.FCardZoom.ZoomController; -import forge.util.Evaluator; - -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -public abstract class InputPayMana extends InputSyncronizedBase { - private static final long serialVersionUID = -9133423708688480255L; - - protected int phyLifeToLose = 0; - - protected final Player player; - protected final Game game; - protected ManaCostBeingPaid manaCost; - protected final SpellAbility saPaidFor; - - private boolean bPaid = false; - private Boolean canPayManaCost = null; - - private boolean locked = false; - - protected InputPayMana(SpellAbility saToPayFor, Player payer) { - this.player = payer; - this.game = player.getGame(); - this.saPaidFor = saToPayFor; - } - - @Override - protected final void onCardSelected(final Card card, final List orderedCardOptions) { - if (locked) { - System.err.print("Should wait till previous call to playAbility finishes."); - return; - } - - FCardZoom.show(FControl.getView().getPrompt().getMessage(), - card, orderedCardOptions, new ZoomController() { - private byte colorCanUse, colorNeeded; - - @Override - public List getOptions(final Card card) { - if (card.getController() != player || card.getManaAbility().isEmpty()) { - return null; - } - - colorCanUse = 0; - colorNeeded = 0; - - for (final byte color : MagicColor.WUBRG) { - if (manaCost.isAnyPartPayableWith(color, player.getManaPool())) { colorCanUse |= color; } - if (manaCost.needsColor(color, player.getManaPool())) { colorNeeded |= color; } - } - if (manaCost.isAnyPartPayableWith((byte) ManaAtom.COLORLESS, player.getManaPool())) - colorCanUse |= ManaAtom.COLORLESS; - - if (colorCanUse == 0) { // no mana cost or something - return null; - } - - // you can't remove unneeded abilities inside a for (am:abilities) loop :( - final String typeRes = manaCost.getSourceRestriction(); - if (StringUtils.isNotBlank(typeRes) && !card.isType(typeRes)) { - return null; - } - - boolean guessAbilityWithRequiredColors = true; - List abilities = new ArrayList(); - - for (SpellAbility ma : card.getManaAbility()) { - ma.setActivatingPlayer(player); - - AbilityManaPart m = ma.getManaPartRecursive(); - if (m == null || !ma.canPlay()) { continue; } - if (!abilityProducesManaColor(ma, m, colorCanUse)) { continue; } - if (ma.isAbility() && ma.getRestrictions().isInstantSpeed()) { continue; } - if (!m.meetsManaRestrictions(saPaidFor)) { continue; } - - abilities.add(ma); - - // skip express mana if the ability is not undoable or reusable - if (!ma.isUndoable() || !ma.getPayCosts().isRenewableResource() || ma.getSubAbility() != null) { - guessAbilityWithRequiredColors = false; - } - } - - if (abilities.isEmpty()) { - return abilities; - } - - // Store some information about color costs to help with any mana choices - if (colorNeeded == 0) { // only colorless left - if (saPaidFor.getHostCard() != null && saPaidFor.getHostCard().hasSVar("ManaNeededToAvoidNegativeEffect")) { - String[] negEffects = saPaidFor.getHostCard().getSVar("ManaNeededToAvoidNegativeEffect").split(","); - for (String negColor : negEffects) { - byte col = MagicColor.fromName(negColor); - colorCanUse |= col; - } - } - } - - // If the card has any ability that tracks mana spent, skip express Mana choice - if (saPaidFor.tracksManaSpent()) { - colorCanUse = MagicColor.ALL_COLORS; - guessAbilityWithRequiredColors = false; - } - - if (guessAbilityWithRequiredColors) { - // express Mana Choice - if (colorNeeded == 0) { - //avoid unnecessary prompt by pretending we need White - //for the sake of "Add one mana of any color" effects - colorNeeded = MagicColor.WHITE; - } - else { - final ArrayList colorMatches = new ArrayList(); - for (SpellAbility sa : abilities) { - if (abilityProducesManaColor(sa, sa.getManaPartRecursive(), colorNeeded)) { - colorMatches.add(sa); - } - } - - if (!colorMatches.isEmpty() && colorMatches.size() < abilities.size()) { - // leave behind only color matches - abilities = colorMatches; - } - } - } - - return abilities; - } - - @Override - public boolean selectOption(final Card card, final SpellAbility option) { - ColorSet colors = ColorSet.fromMask(0 == colorNeeded ? colorCanUse : colorNeeded); - option.getManaPartRecursive().setExpressChoice(colors); - - Runnable proc = new Runnable() { - @Override - public void run() { - HumanPlay.playSpellAbility(option.getActivatingPlayer(), option); - player.getManaPool().payManaFromAbility(saPaidFor, manaCost, option); - - onManaAbilityPaid(); - onStateChanged(); - } - }; - locked = true; - game.getAction().invoke(proc); - return false; - } - }); - } - - public void useManaFromPool(byte colorCode) { - // find the matching mana in pool. - player.getManaPool().tryPayCostWithColor(colorCode, saPaidFor, manaCost); - onManaAbilityPaid(); - showMessage(); - } - - /** - * - * canMake. color is like "G", returns "Green". - * - * - * @param am - * a {@link forge.card.spellability.AbilityMana} object. - * @param mana - * a {@link java.lang.String} object. - * @return a boolean. - */ - private static boolean abilityProducesManaColor(final SpellAbility am, AbilityManaPart m, final byte neededColor) { - if (0 != (neededColor & MagicColor.COLORLESS)) { - return true; - } - - if (m.isAnyMana()) { - return true; - } - - // check for produce mana replacement effects - they mess this up, so just use the mana ability - final Card source = am.getHostCard(); - final Player activator = am.getActivatingPlayer(); - final Game g = source.getGame(); - final HashMap repParams = new HashMap(); - repParams.put("Event", "ProduceMana"); - repParams.put("Mana", m.getOrigProduced()); - repParams.put("Affected", source); - repParams.put("Player", activator); - repParams.put("AbilityMana", am); - - for (final Player p : g.getPlayers()) { - for (final Card crd : p.getAllCards()) { - for (final ReplacementEffect replacementEffect : crd.getReplacementEffects()) { - if (replacementEffect.requirementsCheck(g) - && replacementEffect.canReplace(repParams) - && replacementEffect.getMapParams().containsKey("ManaReplacement") - && replacementEffect.zonesCheck(g.getZoneOf(crd))) { - return true; - } - } - } - } - - if (am.getApi() == ApiType.ManaReflected) { - final Iterable reflectableColors = CardUtil.getReflectableManaColors(am); - for (final String color : reflectableColors) { - if (0 != (neededColor & MagicColor.fromName(color))) { - return true; - } - } - } - else { - String colorsProduced = m.isComboMana() ? m.getComboColors() : m.getOrigProduced(); - for (final String color : colorsProduced.split(" ")) { - if (0 != (neededColor & MagicColor.fromName(color))) { - return true; - } - if( (neededColor & ManaAtom.COLORLESS) != 0) - return true; - } - } - return false; - } - - protected boolean isAlreadyPaid() { - if (manaCost.isPaid()) { - bPaid = true; - } - return bPaid; - } - - protected boolean supportAutoPay() { - return true; - } - - private void runAsAi(Runnable proc) { - this.player.runWithController(proc, new PlayerControllerAi(this.game, this.player, this.player.getOriginalLobbyPlayer())); - } - - /** {@inheritDoc} */ - @Override - protected void onOk() { - if (supportAutoPay()) { - //use AI utility to automatically pay mana cost if possible - final Runnable proc = new Runnable() { - @Override - public void run() { - ComputerUtilMana.payManaCost(manaCost, saPaidFor, player); - } - }; - //must run in game thread as certain payment actions can only be automated there - game.getAction().invoke(new Runnable() { - @Override - public void run() { - runAsAi(proc); - onStateChanged(); - } - }); - } - } - - protected void updateButtons() { - if (supportAutoPay()) { - ButtonUtil.setButtonText("Auto", "Cancel"); - } - ButtonUtil.enableOnlyCancel(); - } - - protected final void updateMessage() { - locked = false; - if (supportAutoPay()) { - if (canPayManaCost == null) { - //use AI utility to determine if mana cost can be paid if that hasn't been determined yet - Evaluator proc = new Evaluator() { - @Override - public Boolean evaluate() { - return ComputerUtilMana.canPayManaCost(manaCost, saPaidFor, player); - } - }; - runAsAi(proc); - canPayManaCost = proc.getResult(); - } - if (canPayManaCost) { - ButtonUtil.enableAll(); //enabled Auto button if mana cost can be paid - } - } - showMessage(getMessage()); - } - - /** {@inheritDoc} */ - @Override - protected final void onStop() { - if (supportAutoPay()) { - ButtonUtil.reset(); - } - } - - /** {@inheritDoc} */ - @Override - public void showMessage() { - if (isFinished()) { return; } - updateButtons(); - onStateChanged(); - } - - protected void onStateChanged() { - if (isAlreadyPaid()) { - done(); - stop(); - } - else { - FThreads.invokeInEdtNowOrLater(new Runnable() { - @Override - public void run() { - updateMessage(); - } - }); - } - } - - protected void onManaAbilityPaid() {} // some inputs overload it - protected abstract void done(); - protected abstract String getMessage(); - - @Override - public String toString() { - return String.format("PayManaBase %s left", manaCost.toString()); - } - - public boolean isPaid() { return bPaid; } - - protected String messagePrefix; - public void setMessagePrefix(String prompt) { - // TODO Auto-generated method stub - messagePrefix = prompt; - } -} diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputPayManaOfCostPayment.java b/forge-gui-mobile/src/forge/screens/match/input/InputPayManaOfCostPayment.java deleted file mode 100644 index afc9e8059ee..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputPayManaOfCostPayment.java +++ /dev/null @@ -1,61 +0,0 @@ -package forge.screens.match.input; - -import forge.game.card.Card; -import forge.game.mana.ManaCostBeingPaid; -import forge.game.player.Player; -import forge.game.spellability.SpellAbility; - -public class InputPayManaOfCostPayment extends InputPayMana { - public InputPayManaOfCostPayment(ManaCostBeingPaid cost, SpellAbility spellAbility, Player payer) { - super(spellAbility, payer); - manaCost = cost; - } - - private static final long serialVersionUID = 3467312982164195091L; - private int phyLifeToLose = 0; - - @Override - protected final void onPlayerSelected(Player selected) { - if (player == selected) { - if (player.canPayLife(this.phyLifeToLose + 2) && manaCost.payPhyrexian()) { - this.phyLifeToLose += 2; - } - - this.showMessage(); - } - } - - @Override - protected void done() { - final Card source = saPaidFor.getHostCard(); - if (this.phyLifeToLose > 0) { - player.payLife(this.phyLifeToLose, source); - } - } - - @Override - protected void onCancel() { - stop(); - } - - @Override - protected String getMessage() { - final String displayMana = manaCost.toString(false); - - final StringBuilder msg = new StringBuilder(); - if( messagePrefix != null ) - msg.append(messagePrefix).append("\n"); - msg.append("Pay Mana Cost: ").append(displayMana); - if (this.phyLifeToLose > 0) { - msg.append(" ("); - msg.append(this.phyLifeToLose); - msg.append(" life paid for phyrexian mana)"); - } - - if (manaCost.containsPhyrexianMana()) { - msg.append("\n(Click on your life total to pay life for phyrexian mana.)"); - } - - return msg.toString(); - } -} diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputPayManaSimple.java b/forge-gui-mobile/src/forge/screens/match/input/InputPayManaSimple.java deleted file mode 100644 index 06f26946702..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputPayManaSimple.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.screens.match.input; - -import forge.card.mana.ManaCost; -import forge.game.Game; -import forge.game.card.Card; -import forge.game.mana.ManaCostBeingPaid; -import forge.game.player.Player; -import forge.game.spellability.SpellAbility; - -//pays the cost of a card played from the player's hand -//the card is removed from the players hand if the cost is paid -//CANNOT be used for ABILITIES -public class InputPayManaSimple extends InputPayMana { - // anything that uses this should be converted to Ability_Cost - /** Constant serialVersionUID=3467312982164195091L. */ - private static final long serialVersionUID = 3467312982164195091L; - - private final Card originalCard; - private final ManaCost originalManaCost; - - public InputPayManaSimple(final Game game, final SpellAbility sa, final ManaCostBeingPaid manaCostToPay) { - super(sa, sa.getActivatingPlayer()); - this.originalManaCost = manaCostToPay.toManaCost(); - this.originalCard = sa.getHostCard(); - - if (sa.getHostCard().isCopiedSpell() && sa.isSpell()) { - this.manaCost = new ManaCostBeingPaid(ManaCost.ZERO); - game.getStack().add(this.saPaidFor); - } - else { - this.manaCost = manaCostToPay; - } - } - - protected void onManaAbilityPaid() { - if (this.manaCost.isPaid()) { - this.originalCard.setSunburstValue(this.manaCost.getSunburst()); - } - } - - /** {@inheritDoc} */ - @Override - protected final void onPlayerSelected(Player selected) { - if (player == selected) { - if (player.canPayLife(this.phyLifeToLose + 2) && manaCost.payPhyrexian()) { - this.phyLifeToLose += 2; - } - - this.showMessage(); - } - } - - /** - * - * done. - * - */ - @Override - protected void done() { - this.originalCard.setSunburstValue(this.manaCost.getSunburst()); - - if (this.phyLifeToLose > 0) { - player.payLife(this.phyLifeToLose, this.originalCard); - } - if (!this.saPaidFor.getHostCard().isCopiedSpell()) { - if (this.saPaidFor.isSpell()) { - this.saPaidFor.setHostCard(game.getAction().moveToStack(this.originalCard)); - } - } - } - - /** {@inheritDoc} */ - @Override - protected final void onCancel() { - player.getManaPool().refundManaPaid(this.saPaidFor); - // Update UI - - this.stop(); - } - - /** {@inheritDoc} */ - @Override - public final void showMessage() { - if (isFinished()) { return; } - - updateButtons(); - - if (this.manaCost.isPaid() && !new ManaCostBeingPaid(this.originalManaCost).isPaid()) { - this.done(); - this.stop(); - } - else { - updateMessage(); - } - } - - /* (non-Javadoc) - * @see forge.control.input.InputPayManaBase#updateMessage() - */ - @Override - protected String getMessage() { - final StringBuilder msg = new StringBuilder("Pay Mana Cost: " + this.manaCost.toString()); - if (this.phyLifeToLose > 0) { - msg.append(" ("); - msg.append(this.phyLifeToLose); - msg.append(" life paid for phyrexian mana)"); - } - - if (this.manaCost.containsPhyrexianMana()) { - msg.append("\n(Click on your life total to pay life for phyrexian mana.)"); - } - - // has its own variant of checkIfPaid - return msg.toString(); - } -} diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputPayManaX.java b/forge-gui-mobile/src/forge/screens/match/input/InputPayManaX.java deleted file mode 100644 index af1d0de5fa6..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputPayManaX.java +++ /dev/null @@ -1,124 +0,0 @@ -package forge.screens.match.input; - -import forge.card.ColorSet; -import forge.card.mana.ManaCost; -import forge.card.mana.ManaCostParser; -import forge.game.card.Card; -import forge.game.mana.Mana; -import forge.game.mana.ManaCostBeingPaid; -import forge.game.spellability.SpellAbility; - -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; - -public class InputPayManaX extends InputPayMana { - private static final long serialVersionUID = -6900234444347364050L; - private int xPaid = 0; - private ArrayList xPaidByColor = new ArrayList<>(); - private byte colorsPaid; - private final ManaCost manaCostPerX; - private final boolean xCanBe0; - private boolean canceled = false; - - public InputPayManaX(final SpellAbility sa0, final int amountX, final boolean xCanBe0) { - super(sa0, sa0.getActivatingPlayer()); - xPaid = 0; - - if (saPaidFor.hasParam("XColor")) { - String xColor = saPaidFor.getParam("XColor"); - if (amountX == 1) { - manaCostPerX = new ManaCost(new ManaCostParser(xColor)); - } - else { - List list = new ArrayList(amountX); - for (int i = 0; i < amountX; i++) { - list.add(xColor); - } - manaCostPerX = new ManaCost(new ManaCostParser(StringUtils.join(list, ' '))); - } - } - else { - manaCostPerX = ManaCost.get(amountX); - } - manaCost = new ManaCostBeingPaid(manaCostPerX); - - this.xCanBe0 = xCanBe0; - colorsPaid = saPaidFor.getHostCard().getColorsPaid(); // for effects like sunburst - } - - /* (non-Javadoc) - * @see forge.control.input.InputPayManaBase#isPaid() - */ - @Override - public boolean isPaid() { - //return !( xPaid == 0 && !costMana.canXbe0() || this.colorX.equals("") && !this.manaCost.toString().equals(strX) ); - // return !( xPaid == 0 && !costMana.canXbe0()) && !(this.colorX.equals("") && !this.manaCost.toString().equals(strX)); - return !canceled && (xPaid > 0 || xCanBe0); - } - - @Override - protected boolean supportAutoPay() { - return false; - } - - @Override - public void showMessage() { - if (isFinished()) { return; } - - updateMessage(); - } - - @Override - protected String getMessage() { - StringBuilder msg = new StringBuilder("Pay X Mana Cost for "); - msg.append(saPaidFor.getHostCard().getName()).append("\n").append(this.xPaid); - msg.append(" Paid so far."); - if (!xCanBe0) { - msg.append(" X Can't be 0."); - } - // Enable just cancel is full X value hasn't been paid for multiple X values - // or X is 0, and x can't be 0 - if (!isPaid()) { - ButtonUtil.enableOnlyCancel(); - } - else { - ButtonUtil.enableAll(); - } - - return msg.toString(); - } - - @Override - protected void onManaAbilityPaid() { - if (this.manaCost.isPaid()) { - this.colorsPaid |= manaCost.getColorsPaid(); - this.manaCost = new ManaCostBeingPaid(manaCostPerX); - this.xPaid++; - this.xPaidByColor.add(saPaidFor.getPayingMana().get(0)); - } - } - - @Override - protected final void onCancel() { - // If you hit cancel, isPaid needs to return false - this.canceled = true; - this.stop(); - } - - @Override - protected final void onOk() { - done(); - this.stop(); - } - - @Override - protected void done() { - final Card card = saPaidFor.getHostCard(); - card.setXManaCostPaid(this.xPaid); - card.setXManaCostPaidByColor(this.xPaidByColor); - card.setColorsPaid(this.colorsPaid); - card.setSunburstValue(ColorSet.fromMask(this.colorsPaid).countColors()); - } -} diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputPlaybackControl.java b/forge-gui-mobile/src/forge/screens/match/input/InputPlaybackControl.java deleted file mode 100644 index 9ce5b4a6d3e..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputPlaybackControl.java +++ /dev/null @@ -1,68 +0,0 @@ -package forge.screens.match.input; - -import forge.screens.match.FControl; -import forge.screens.match.FControlGamePlayback; - -public class InputPlaybackControl extends InputSyncronizedBase implements InputSynchronized { - private static final long serialVersionUID = 7979208993306642072L; - - FControlGamePlayback control; - - private boolean isPaused = false; - private boolean isFast = false; - - /** - * TODO: Write javadoc for Constructor. - * @param fControlGamePlayback - */ - public InputPlaybackControl(FControlGamePlayback fControlGamePlayback) { - control = fControlGamePlayback; - } - - /* (non-Javadoc) - * @see forge.gui.input.InputBase#showMessage() - */ - @Override - protected void showMessage() { - setPause(false); - ButtonUtil.enableAll(); - } - - private void setPause(boolean pause) { - isPaused = pause; - if ( isPaused ) - ButtonUtil.setButtonText("Resume", "Step"); - else { - ButtonUtil.setButtonText("Pause", isFast ? "1x Speed" : "10x Faster"); - showMessage("Press pause to pause game."); - } - } - - public void onGamePaused() { - showMessage(getTurnPhasePriorityMessage(FControl.getGame())); - } - - @Override - protected void onOk() { - if ( isPaused ) { - control.resume(); - setPause(false); - } else { - control.pause(); - setPause(true); - } - } - - @Override - protected void onCancel() { - if ( isPaused ) { - control.singleStep(); - } else { - isFast = !isFast; - control.setSpeed(isFast); - setPause(isPaused); // update message - } - - } - -} diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputProliferate.java b/forge-gui-mobile/src/forge/screens/match/input/InputProliferate.java deleted file mode 100644 index 510f6d58070..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputProliferate.java +++ /dev/null @@ -1,99 +0,0 @@ -package forge.screens.match.input; - -import forge.game.GameEntity; -import forge.game.card.Card; -import forge.game.card.CounterType; -import forge.game.player.Player; -import forge.toolbox.GuiChoose; - -import java.util.*; -import java.util.Map.Entry; - -public final class InputProliferate extends InputSelectManyBase { - private static final long serialVersionUID = -1779224307654698954L; - private Map chosenCounters = new HashMap(); - - public InputProliferate() { - super(1, Integer.MAX_VALUE); - allowUnselect = true; - } - - - protected String getMessage() { - StringBuilder sb = new StringBuilder("Choose permanents and/or players with counters on them to add one more counter of that type."); - sb.append("\n\nYou've selected so far:\n"); - if (chosenCounters.isEmpty()) { - sb.append("(none)"); - } - else { - for (Entry ge : chosenCounters.entrySet()) { - if (ge.getKey() instanceof Player) { - sb.append("* A poison counter to player ").append(ge.getKey()).append("\n"); - } - else { - sb.append("* ").append(ge.getKey()).append(" -> ").append(ge.getValue()).append("counter\n"); - } - } - } - - return sb.toString(); - } - - @Override - protected void onCardSelected(final Card card, final List orderedCardOptions) { - if (!card.hasCounters()) { - return; - } - - boolean entityWasSelected = chosenCounters.containsKey(card); - if (entityWasSelected) { - this.chosenCounters.remove(card); - } - else { - final List choices = new ArrayList(); - for (final CounterType ct : CounterType.values()) { - if (card.getCounters(ct) > 0) { - choices.add(ct); - } - } - - CounterType toAdd = choices.size() == 1 ? choices.get(0) : GuiChoose.one("Select counter type", choices); - chosenCounters.put(card, toAdd); - } - - refresh(); - } - - @Override - protected final void onPlayerSelected(Player player) { - if (player.getPoisonCounters() == 0 || player.hasKeyword("You can't get poison counters")) { - return; - } - - boolean entityWasSelected = chosenCounters.containsKey(player); - if (entityWasSelected) { - this.chosenCounters.remove(player); - } else - this.chosenCounters.put(player, null /* POISON counter is meant */); - - refresh(); - } - - public Map getProliferationMap() { - return chosenCounters; - } - - - @Override - protected boolean hasEnoughTargets() { return true; } - - @Override - protected boolean hasAllTargets() { return false; } - - - @Override - public Collection getSelected() { - // TODO Auto-generated method stub - return chosenCounters.keySet(); - } -} \ No newline at end of file diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputProxy.java b/forge-gui-mobile/src/forge/screens/match/input/InputProxy.java deleted file mode 100644 index a038d2458a9..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputProxy.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.screens.match.input; - -import forge.FThreads; -import forge.game.Game; -import forge.game.card.Card; -import forge.game.player.Player; -import forge.game.spellability.SpellAbility; -import forge.screens.match.FControl; -import forge.toolbox.FOptionPane; - -import java.util.List; -import java.util.Observable; -import java.util.Observer; -import java.util.concurrent.atomic.AtomicReference; - -/** - * - * GuiInput class. - * - * - * @author Forge - * @version $Id: InputProxy.java 24769 2014-02-09 13:56:04Z Hellfish $ - */ -public class InputProxy implements Observer { - - /** The input. */ - private AtomicReference input = new AtomicReference(); - private Game game = null; - -// private static final boolean DEBUG_INPUT = true; // false; - - public void setGame(Game game0) { - game = game0; - FControl.getInputQueue().addObserver(this); - } - - public boolean passPriority() { - Input inp = getInput(); - if (inp != null && inp instanceof InputPassPriority) { - inp.selectButtonOK(); - return true; - } - - FThreads.invokeInEdtNowOrLater(new Runnable() { - @Override - public void run() { - FOptionPane.showMessageDialog("Cannot pass priority at this time."); - } - }); - return false; - } - - @Override - public final void update(final Observable observable, final Object obj) { - final Input nextInput = FControl.getInputQueue().getActualInput(game); - -/* if(DEBUG_INPUT) - System.out.printf("%s ... \t%s on %s, \tstack = %s%n", - FThreads.debugGetStackTraceItem(6, true), nextInput == null ? "null" : nextInput.getClass().getSimpleName(), - game.getPhaseHandler().debugPrintState(), Singletons.getControl().getInputQueue().printInputStack()); -*/ - this.input.set(nextInput); - Runnable showMessage = new Runnable() { - @Override public void run() { - Input current = getInput(); - FControl.getInputQueue().syncPoint(); - //System.out.printf("\t%s > showMessage @ %s/%s during %s%n", FThreads.debugGetCurrThreadId(), nextInput.getClass().getSimpleName(), current.getClass().getSimpleName(), game.getPhaseHandler().debugPrintState()); - current.showMessageInitial(); - } - }; - - FThreads.invokeInEdtLater(showMessage); - } - /** - * - * selectButtonOK. - * - */ - public final void selectButtonOK() { - Input inp = getInput(); - if (inp != null) { - inp.selectButtonOK(); - } - } - - /** - * - * selectButtonCancel. - * - */ - public final void selectButtonCancel() { - Input inp = getInput(); - if (inp != null) { - inp.selectButtonCancel(); - } - } - - /** - * - * selectPlayer. - * - * - * @param player - * a {@link forge.game.player.Player} object. - */ - public final void selectPlayer(final Player player) { - Input inp = getInput(); - if (inp != null) { - inp.selectPlayer(player); - } - } - - /** - * - * selectCard. - * - * - * @param card - * a {@link forge.game.card.Card} object. - * @param orderedCardOptions - */ - public final void selectCard(Card card, List orderedCardOptions) { - Input inp = getInput(); - if (inp != null) { - inp.selectCard(card, orderedCardOptions); - } - } - - public final void selectAbility(SpellAbility ab) { - Input inp = getInput(); - if (inp != null) { - inp.selectAbility(ab); - } - } - - /** {@inheritDoc} */ - @Override - public final String toString() { - Input inp = getInput(); - return null == inp ? "(null)" : inp.toString(); - } - - /** @return {@link forge.gui.InputProxy.InputBase} */ - private Input getInput() { - return this.input.get(); - } -} diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputQueue.java b/forge-gui-mobile/src/forge/screens/match/input/InputQueue.java deleted file mode 100644 index f4c9de7ee9f..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputQueue.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.screens.match.input; - -import forge.game.Game; -import java.util.Observable; -import java.util.concurrent.BlockingDeque; -import java.util.concurrent.LinkedBlockingDeque; - -/** - * - * InputControl class. - * - * - * @author Forge - * @version $Id: InputQueue.java 24769 2014-02-09 13:56:04Z Hellfish $ - */ -public class InputQueue extends Observable { - private final BlockingDeque inputStack = new LinkedBlockingDeque(); - private final InputLockUI inputLock; - - public InputQueue() { - inputLock = new InputLockUI(this); - } - - public final void updateObservers() { - this.setChanged(); - this.notifyObservers(); - } - - public final Input getInput() { - return inputStack.isEmpty() ? null : this.inputStack.peek(); - } - - public final void removeInput(Input inp) { - Input topMostInput = inputStack.isEmpty() ? null : inputStack.pop(); - - if (topMostInput != inp) { - throw new RuntimeException("Cannot remove input " + inp.getClass().getSimpleName() + " because it's not on top of stack. Stack = " + inputStack ); - } - updateObservers(); - } - - /** - * - * updateInput. - * - * - * @return a {@link forge.gui.input.InputBase} object. - */ - public final Input getActualInput(Game game) { - Input topMost = inputStack.peek(); // incoming input to Control - if (topMost != null && !game.isGameOver()) { - return topMost; - } - return inputLock; - } - - // only for debug purposes - public String printInputStack() { - return inputStack.toString(); - } - - public void setInput(InputSynchronized input) { - this.inputStack.push(input); - syncPoint(); - this.updateObservers(); - } - - public void syncPoint() { - synchronized (inputLock) { - // acquire and release lock, so that actions from Game thread happen before EDT reads their results - } - } - - public void onGameOver(boolean releaseAllInputs) { - for (InputSynchronized inp : inputStack) { - inp.relaseLatchWhenGameIsOver(); - if (!releaseAllInputs) { - break; - } - } - } -} diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputSelectCardsForConvoke.java b/forge-gui-mobile/src/forge/screens/match/input/InputSelectCardsForConvoke.java deleted file mode 100644 index f6f5bb25b74..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputSelectCardsForConvoke.java +++ /dev/null @@ -1,98 +0,0 @@ -package forge.screens.match.input; - -import forge.card.mana.ManaCost; -import forge.card.mana.ManaCostShard; -import forge.game.card.Card; -import forge.game.card.CardUtil; -import forge.game.mana.ManaCostBeingPaid; -import forge.game.player.Player; - -import org.apache.commons.lang3.tuple.ImmutablePair; - -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -public final class InputSelectCardsForConvoke extends InputSelectManyBase { - private static final long serialVersionUID = -1779224307654698954L; - private final Map> chosenCards = new HashMap>(); - private final ManaCostBeingPaid remainingCost; - private final Player player; - - public InputSelectCardsForConvoke(Player p, ManaCost cost, List untapped) { - super(1, Math.min(cost.getCMC(), untapped.size())); - remainingCost = new ManaCostBeingPaid(cost); - player = p; - allowUnselect = true; - - } - - - protected String getMessage() { - return "Choose creatures to tap for convoke.\nRemaining mana cost is " + remainingCost.toString(); - } - - @Override - protected void onCardSelected(final Card card, final List orderedCardOptions) { - boolean entityWasSelected = chosenCards.containsKey(card); - if (entityWasSelected) { - ImmutablePair color = this.chosenCards.remove(card); - remainingCost.increaseShard(color.right, 1); - onSelectStateChanged(card, false); - } - else { - - byte chosenColor = player.getController().chooseColorAllowColorless("Convoke " + card.toString() + " for which color?", card, CardUtil.getColors(card)); - - if (remainingCost.getColorlessManaAmount() > 0 && (chosenColor == 0 || !remainingCost.needsColor(chosenColor, player.getManaPool()))) { - registerConvoked(card, ManaCostShard.COLORLESS, chosenColor); - } else { - for (ManaCostShard shard : remainingCost.getDistinctShards()) { - if (shard.canBePaidWithManaOfColor(chosenColor)) { - registerConvoked(card, shard, chosenColor); - return; - } - } - showMessage("The colors provided by " + card.toString() + " you've chosen cannot be used to decrease the manacost of " + remainingCost.toString()); - flashIncorrectAction(); - } - } - - refresh(); - } - - private void registerConvoked(Card card, ManaCostShard shard, byte chosenColor) { - remainingCost.decreaseShard(shard, 1); - chosenCards.put(card, ImmutablePair.of(chosenColor, shard)); - onSelectStateChanged(card, true); - } - - - @Override - protected final void onPlayerSelected(Player player) { - } - - public Map getConvokeMap() { - Map result = new HashMap(); - if( !hasCancelled() ) - for(Entry> c : chosenCards.entrySet()) - result.put(c.getKey(), c.getValue().right); - return result; - } - - - @Override - protected boolean hasEnoughTargets() { return true; } - - @Override - protected boolean hasAllTargets() { return false; } - - - @Override - public Collection getSelected() { - // TODO Auto-generated method stub - return chosenCards.keySet(); - } -} \ No newline at end of file diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputSelectCardsFromList.java b/forge-gui-mobile/src/forge/screens/match/input/InputSelectCardsFromList.java deleted file mode 100644 index a19e4719bb2..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputSelectCardsFromList.java +++ /dev/null @@ -1,21 +0,0 @@ -package forge.screens.match.input; - -import forge.game.card.Card; - -import java.util.Collection; - -public class InputSelectCardsFromList extends InputSelectEntitiesFromList { - private static final long serialVersionUID = 6230360322294805986L; - - public InputSelectCardsFromList(int cnt, Collection validCards) { - super(cnt, cnt, validCards); // to avoid hangs - } - - public InputSelectCardsFromList(int min, int max, Collection validCards) { - super(min, max, validCards); // to avoid hangs - } - - public InputSelectCardsFromList(Collection validCards) { - super(1, 1, validCards); // to avoid hangs - } -} \ No newline at end of file diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputSelectEntitiesFromList.java b/forge-gui-mobile/src/forge/screens/match/input/InputSelectEntitiesFromList.java deleted file mode 100644 index 3c08fb76e36..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputSelectEntitiesFromList.java +++ /dev/null @@ -1,75 +0,0 @@ -package forge.screens.match.input; - -import forge.game.GameEntity; -import forge.game.card.Card; -import forge.game.player.Player; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -public class InputSelectEntitiesFromList extends InputSelectManyBase { - private static final long serialVersionUID = -6609493252672573139L; - - private final Collection validChoices; - protected final List selected = new ArrayList(); - - public InputSelectEntitiesFromList(int min, int max, Collection validChoices) { - super(Math.min(min, validChoices.size()), Math.min(max, validChoices.size())); - this.validChoices = validChoices; - - if ( min > validChoices.size() ) - System.out.println(String.format("Trying to choose at least %d cards from a list with only %d cards!", min, validChoices.size())); - - } - - @Override - protected void onCardSelected(final Card c, final List orderedCardOptions) { - if (!selectEntity(c)) { - return; - } - refresh(); - } - - @Override - protected void onPlayerSelected(final Player p) { - if (!selectEntity(p)) { - return; - } - refresh(); - } - - public final Collection getSelected() { - return selected; - } - - @SuppressWarnings("unchecked") - protected boolean selectEntity(GameEntity c) { - if (!validChoices.contains(c)) { - return false; - } - - boolean entityWasSelected = selected.contains(c); - if (entityWasSelected) { - if (!allowUnselect) - return false; - this.selected.remove(c); - } - else { - this.selected.add((T)c); - } - onSelectStateChanged(c, !entityWasSelected); - - return true; - } - - // might re-define later - protected boolean hasEnoughTargets() { return selected.size() >= min; } - protected boolean hasAllTargets() { return selected.size() >= max; } - - protected String getMessage() { - return max == Integer.MAX_VALUE - ? String.format(message, selected.size()) - : String.format(message, max - selected.size()); - } -} \ No newline at end of file diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputSelectManyBase.java b/forge-gui-mobile/src/forge/screens/match/input/InputSelectManyBase.java deleted file mode 100644 index 1ba006d4883..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputSelectManyBase.java +++ /dev/null @@ -1,101 +0,0 @@ -package forge.screens.match.input; - -import com.google.common.collect.Iterables; - -import forge.game.GameEntity; -import forge.game.card.Card; -import forge.screens.match.FControl; - -import java.util.Collection; - -public abstract class InputSelectManyBase extends InputSyncronizedBase { - private static final long serialVersionUID = -2305549394512889450L; - - protected boolean bCancelled = false; - protected final int min; - protected final int max; - protected boolean allowUnselect = false; - protected boolean allowCancel = false; - - protected String message = "Source-Card-Name - Select %d more card(s)"; - - protected InputSelectManyBase(int min, int max) { - if (min > max) { - throw new IllegalArgumentException("Min must not be greater than Max"); - } - this.min = min; - this.max = max; - } - - protected void refresh() { - if (hasAllTargets()) { - selectButtonOK(); - } - else { - this.showMessage(); - } - } - - protected abstract boolean hasEnoughTargets(); - protected abstract boolean hasAllTargets(); - - protected abstract String getMessage(); - - @Override - public final void showMessage() { - showMessage(getMessage()); - - boolean canCancel = allowCancel; - boolean canOk = hasEnoughTargets(); - - if (canOk && canCancel) { ButtonUtil.enableAll(); } - if (!canOk && canCancel) { ButtonUtil.enableOnlyCancel(); } - if (canOk && !canCancel) { ButtonUtil.enableOnlyOk(); } - if (!canOk && !canCancel) { ButtonUtil.disableAll(); } - } - - - @Override - protected final void onCancel() { - bCancelled = true; - this.getSelected().clear(); - this.stop(); - afterStop(); - } - - public final boolean hasCancelled() { - return bCancelled; - } - - public abstract Collection getSelected(); - public T getFirstSelected() { return Iterables.getFirst(getSelected(), null); } - - @Override - protected final void onOk() { - this.stop(); - afterStop(); - } - - public void setMessage(String message0) { - this.message = message0; - } - - protected void onSelectStateChanged(GameEntity c, boolean newState) { - if (c instanceof Card) { - FControl.setUsedToPay((Card)c, newState); // UI supports card highlighting though this abstraction-breaking mechanism - } - } - - protected void afterStop() { - for (GameEntity c : getSelected()) { - if (c instanceof Card) { - FControl.setUsedToPay((Card)c, false); - } - } - } - - public final boolean isUnselectAllowed() { return allowUnselect; } - public final void setUnselectAllowed(boolean allow) { this.allowUnselect = allow; } - - public final void setCancelAllowed(boolean allow) { this.allowCancel = allow ; } -} diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputSelectTargets.java b/forge-gui-mobile/src/forge/screens/match/input/InputSelectTargets.java deleted file mode 100644 index 272899bf97b..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputSelectTargets.java +++ /dev/null @@ -1,265 +0,0 @@ -package forge.screens.match.input; - -import forge.game.GameEntity; -import forge.game.GameObject; -import forge.game.ability.ApiType; -import forge.game.card.Card; -import forge.game.player.Player; -import forge.game.spellability.SpellAbility; -import forge.game.spellability.TargetRestrictions; -import forge.screens.match.FControl; -import forge.toolbox.GuiChoose; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -public final class InputSelectTargets extends InputSyncronizedBase { - private final List choices; - // some cards can be targeted several times (eg: distribute damage as you choose) - private final Map targetDepth = new HashMap(); - private final TargetRestrictions tgt; - private final SpellAbility sa; - private Card lastTarget = null; - private boolean bCancel = false; - private boolean bOk = false; - private final boolean mandatory; - private static final long serialVersionUID = -1091595663541356356L; - - public final boolean hasCancelled() { return bCancel; } - public final boolean hasPressedOk() { return bOk; } - /** - * TODO: Write javadoc for Constructor. - * @param select - * @param choices - * @param req - * @param alreadyTargeted - * @param targeted - * @param tgt - * @param sa - * @param mandatory - */ - public InputSelectTargets(List choices, SpellAbility sa, boolean mandatory) { - this.choices = choices; - this.tgt = sa.getTargetRestrictions(); - this.sa = sa; - this.mandatory = mandatory; - } - - @Override - public void showMessage() { - final StringBuilder sb = new StringBuilder(); - sb.append("Targeted:\n"); - for (final Entry o : targetDepth.entrySet()) { - sb.append(o.getKey()); - if( o.getValue() > 1 ) - sb.append(" (").append(o.getValue()).append(" times)"); - sb.append("\n"); - } - if (!sa.getUniqueTargets().isEmpty()) { - sb.append("Parent Targeted:"); - sb.append(sa.getUniqueTargets()).append("\n"); - } - sb.append(sa.getHostCard() + " - " + tgt.getVTSelection()); - - int maxTargets = tgt.getMaxTargets(sa.getHostCard(), sa); - int targeted = sa.getTargets().getNumTargeted(); - if(maxTargets > 1) - sb.append("\n(").append(maxTargets - targeted).append(" more can be targeted)"); - - showMessage(sb.toString()); - - // If reached Minimum targets, enable OK button - if (!tgt.isMinTargetsChosen(sa.getHostCard(), sa) || tgt.isDividedAsYouChoose()) { - if (mandatory && tgt.hasCandidates(sa, true)) { - // Player has to click on a target - ButtonUtil.disableAll(); - } else { - ButtonUtil.enableOnlyCancel(); - } - } else { - if (mandatory && tgt.hasCandidates(sa, true)) { - // Player has to click on a target or ok - ButtonUtil.enableOnlyOk(); - } else { - ButtonUtil.enableAll(); - } - } - } - - @Override - protected final void onCancel() { - bCancel = true; - this.done(); - } - - @Override - protected final void onOk() { - bOk = true; - this.done(); - } - - @Override - protected final void onCardSelected(final Card card, final List orderedCardOptions) { - if (!tgt.isUniqueTargets() && targetDepth.containsKey(card)) { - return; - } - - // leave this in temporarily, there some seriously wrong things going on here - // Can be targeted doesn't check if the target is a valid type, only if a card is generally "targetable" - if (!card.canBeTargetedBy(sa)) { - showMessage(sa.getHostCard() + " - Cannot target this card (Shroud? Protection? Restrictions)."); - return; - } - // If all cards must be from the same zone - if (tgt.isSingleZone() && lastTarget != null && !card.getController().equals(lastTarget.getController())) { - showMessage(sa.getHostCard() + " - Cannot target this card (not in the same zone)"); - return; - } - - // If all cards must be from different zones - if (tgt.isDifferentZone() && lastTarget != null && !card.getController().equals(lastTarget.getController().getOpponent())) { - showMessage(sa.getHostCard() + " - Cannot target this card (not in different zones)"); - return; - } - - // If the cards can't share a creature type - if (tgt.isWithoutSameCreatureType() && lastTarget != null && card.sharesCreatureTypeWith(lastTarget)) { - showMessage(sa.getHostCard() + " - Cannot target this card (should not share a creature type)"); - return; - } - - // If all cards must have different controllers - if (tgt.isDifferentControllers()) { - final List targetedControllers = new ArrayList(); - for (GameObject o : targetDepth.keySet()) { - if (o instanceof Card) { - Player p = ((Card) o).getController(); - targetedControllers.add(p); - } - } - if (targetedControllers.contains(card.getController())) { - showMessage(sa.getHostCard() + " - Cannot target this card (must have different controllers)"); - return; - } - } - - if (!choices.contains(card)) { - if (card.isPlaneswalker() && sa.getApi() == ApiType.DealDamage) { - showMessage(sa.getHostCard() + " - To deal an opposing Planeswalker direct damage, target its controller and then redirect the damage on resolution."); - } else { - showMessage(sa.getHostCard() + " - The selected card is not a valid choice to be targeted."); - } - return; - } - - if (tgt.isDividedAsYouChoose()) { - final int stillToDivide = tgt.getStillToDivide(); - int allocatedPortion = 0; - // allow allocation only if the max targets isn't reached and there are more candidates - if ((sa.getTargets().getNumTargeted() + 1 < tgt.getMaxTargets(sa.getHostCard(), sa)) - && (tgt.getNumCandidates(sa, true) - 1 > 0) && stillToDivide > 1) { - final Integer[] choices = new Integer[stillToDivide]; - for (int i = 1; i <= stillToDivide; i++) { - choices[i - 1] = i; - } - String apiBasedMessage = "Distribute how much to "; - if (sa.getApi() == ApiType.DealDamage) { - apiBasedMessage = "Select how much damage to deal to "; - } else if (sa.getApi() == ApiType.PreventDamage) { - apiBasedMessage = "Select how much damage to prevent to "; - } else if (sa.getApi() == ApiType.PutCounter) { - apiBasedMessage = "Select how many counters to distribute to "; - } - final StringBuilder sb = new StringBuilder(); - sb.append(apiBasedMessage); - sb.append(card.toString()); - Integer chosen = GuiChoose.oneOrNone(sb.toString(), choices); - if (null == chosen) { - return; - } - allocatedPortion = chosen; - } else { // otherwise assign the rest of the damage/protection - allocatedPortion = stillToDivide; - } - tgt.setStillToDivide(stillToDivide - allocatedPortion); - tgt.addDividedAllocation(card, allocatedPortion); - } - addTarget(card); - } // selectCard() - - @Override - protected final void onPlayerSelected(Player player) { - if (!tgt.isUniqueTargets() && targetDepth.containsKey(player)) { - return; - } - - if (!sa.canTarget(player)) { - showMessage(sa.getHostCard() + " - Cannot target this player (Hexproof? Protection? Restrictions?)."); - return; - } - - if (tgt.isDividedAsYouChoose()) { - final int stillToDivide = tgt.getStillToDivide(); - int allocatedPortion = 0; - // allow allocation only if the max targets isn't reached and there are more candidates - if ((sa.getTargets().getNumTargeted() + 1 < tgt.getMaxTargets(sa.getHostCard(), sa)) && (tgt.getNumCandidates(sa, true) - 1 > 0) && stillToDivide > 1) { - final Integer[] choices = new Integer[stillToDivide]; - for (int i = 1; i <= stillToDivide; i++) { - choices[i - 1] = i; - } - String apiBasedMessage = "Distribute how much to "; - if (sa.getApi() == ApiType.DealDamage) { - apiBasedMessage = "Select how much damage to deal to "; - } else if (sa.getApi() == ApiType.PreventDamage) { - apiBasedMessage = "Select how much damage to prevent to "; - } - final StringBuilder sb = new StringBuilder(); - sb.append(apiBasedMessage); - sb.append(player.getName()); - Integer chosen = GuiChoose.oneOrNone(sb.toString(), choices); - if (null == chosen) { - return; - } - allocatedPortion = chosen; - } else { // otherwise assign the rest of the damage/protection - allocatedPortion = stillToDivide; - } - tgt.setStillToDivide(stillToDivide - allocatedPortion); - tgt.addDividedAllocation(player, allocatedPortion); - } - addTarget(player); - } - - private void addTarget(GameEntity ge) { - sa.getTargets().add(ge); - if (ge instanceof Card) { - FControl.setUsedToPay((Card) ge, true); - } - Integer val = targetDepth.get(ge); - targetDepth.put(ge, val == null ? Integer.valueOf(1) : Integer.valueOf(val.intValue() + 1) ); - - if (hasAllTargets()) { - bOk = true; - this.done(); - } - else { - this.showMessage(); - } - } - - private void done() { - for (GameEntity c : targetDepth.keySet()) { - if (c instanceof Card) { - FControl.setUsedToPay((Card)c, false); - } - } - this.stop(); - } - - private boolean hasAllTargets() { - return tgt.isMaxTargetsChosen(sa.getHostCard(), sa) || ( tgt.getStillToDivide() == 0 && tgt.isDividedAsYouChoose()); - } -} \ No newline at end of file diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputSynchronized.java b/forge-gui-mobile/src/forge/screens/match/input/InputSynchronized.java deleted file mode 100644 index 63889af7e3e..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputSynchronized.java +++ /dev/null @@ -1,6 +0,0 @@ -package forge.screens.match.input; - -public interface InputSynchronized extends Input { - void awaitLatchRelease(); - void relaseLatchWhenGameIsOver(); -} diff --git a/forge-gui-mobile/src/forge/screens/match/input/InputSyncronizedBase.java b/forge-gui-mobile/src/forge/screens/match/input/InputSyncronizedBase.java deleted file mode 100644 index 591cdcfc532..00000000000 --- a/forge-gui-mobile/src/forge/screens/match/input/InputSyncronizedBase.java +++ /dev/null @@ -1,52 +0,0 @@ -package forge.screens.match.input; - -import forge.FThreads; -import forge.error.BugReporter; -import forge.screens.match.FControl; - -import java.util.concurrent.CountDownLatch; - -public abstract class InputSyncronizedBase extends InputBase implements InputSynchronized { - private static final long serialVersionUID = 8756177361251703052L; - private final CountDownLatch cdlDone; - - public InputSyncronizedBase() { - cdlDone = new CountDownLatch(1); - } - - public void awaitLatchRelease() { - FThreads.assertExecutedByEdt(false); - try{ - cdlDone.await(); - } catch (InterruptedException e) { - BugReporter.reportException(e); - } - } - - public final void relaseLatchWhenGameIsOver() { - cdlDone.countDown(); - } - - public void showAndWait() { - FControl.getInputQueue().setInput(this); - awaitLatchRelease(); - } - - protected final void stop() { - onStop(); - - // ensure input won't accept any user actions. - FThreads.invokeInEdtNowOrLater(new Runnable() { - @Override - public void run() { - setFinished(); - } - }); - - // thread irrelevant - FControl.getInputQueue().removeInput(InputSyncronizedBase.this); - cdlDone.countDown(); - } - - protected void onStop() { } -} \ No newline at end of file diff --git a/forge-gui-mobile/src/forge/screens/match/views/VAvatar.java b/forge-gui-mobile/src/forge/screens/match/views/VAvatar.java index d490905e113..fd388b974a8 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VAvatar.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VAvatar.java @@ -24,7 +24,7 @@ public class VAvatar extends FDisplayObject { @Override public boolean tap(float x, float y, int count) { - FControl.getInputProxy().selectPlayer(player); + FControl.getInputProxy().selectPlayer(player, null); return true; } diff --git a/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java b/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java index e3d70caec96..2f407f39702 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java @@ -7,7 +7,7 @@ import java.util.Map; import forge.FThreads; import forge.game.card.Card; -import forge.screens.match.FControl; +import forge.screens.match.InputSelectCard; import forge.toolbox.FCardPanel; public abstract class VCardDisplayArea extends VDisplayArea { @@ -166,10 +166,28 @@ public abstract class VCardDisplayArea extends VDisplayArea { return attachedPanels; } + public enum AttackOption { + DECLARE_AS_ATTACKER("Declare as Attacker"), + REMOVE_FROM_COMBAT("Remove from Combat"), + ATTACK_THIS_DEFENDER("Attack this Defender"), + ACTIVATE_BAND("Activate Band"), + JOIN_BAND("Join Band"); + + private String text; + + private AttackOption(String text0) { + text = text0; + } + + public String toString() { + return text; + } + } + @Override public boolean tap(float x, float y, int count) { if (displayArea != null) { - FControl.getInputProxy().selectCard(getCard(), new ArrayList(displayArea.orderedCards)); //copy list to allow it being modified + InputSelectCard.selectCard(getCard(), displayArea.orderedCards); } return true; } diff --git a/forge-gui-mobile/src/forge/screens/match/views/VDevMenu.java b/forge-gui-mobile/src/forge/screens/match/views/VDevMenu.java index 283256d88da..fedd9dcc98f 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VDevMenu.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VDevMenu.java @@ -22,6 +22,7 @@ import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; import forge.item.IPaperCard; import forge.item.PaperCard; +import forge.match.input.InputSelectCardsFromList; import forge.menu.FDropDownMenu; import forge.menu.FMenuItem; import forge.model.FModel; @@ -31,7 +32,6 @@ import forge.properties.ForgeConstants; import forge.properties.ForgePreferences; import forge.properties.ForgePreferences.FPref; import forge.screens.match.FControl; -import forge.screens.match.input.InputSelectCardsFromList; import forge.toolbox.FEvent; import forge.toolbox.GuiChoose; import forge.toolbox.GuiDialog; diff --git a/forge-gui-mobile/src/forge/screens/match/views/VManaPool.java b/forge-gui-mobile/src/forge/screens/match/views/VManaPool.java index 3b22a8abd64..a6d71619fe6 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VManaPool.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VManaPool.java @@ -13,10 +13,10 @@ import forge.assets.FSkinColor.Colors; import forge.card.MagicColor; import forge.game.mana.ManaPool; import forge.game.player.Player; +import forge.match.input.Input; +import forge.match.input.InputPayMana; import forge.net.FServer; import forge.screens.match.FControl; -import forge.screens.match.input.Input; -import forge.screens.match.input.InputPayMana; import forge.toolbox.FDisplayObject; public class VManaPool extends VDisplayArea { diff --git a/forge-gui-mobile/src/forge/toolbox/GuiChoose.java b/forge-gui-mobile/src/forge/toolbox/GuiChoose.java index bd4c933b348..f73077e7e55 100644 --- a/forge-gui-mobile/src/forge/toolbox/GuiChoose.java +++ b/forge-gui-mobile/src/forge/toolbox/GuiChoose.java @@ -262,7 +262,7 @@ public class GuiChoose { return order("Sideboard", "Main Deck", -1, -1, sideboard, deck, null, true); } - private static List order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax, + public static List order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax, final List sourceChoices, final List destChoices, final Card referenceCard, final boolean sideboardingMode) { // An input box for handling the order of choices. diff --git a/forge-gui/src/main/java/forge/match/input/Input.java b/forge-gui/src/main/java/forge/match/input/Input.java index 9cb8e8123f9..726c1234989 100644 --- a/forge-gui/src/main/java/forge/match/input/Input.java +++ b/forge-gui/src/main/java/forge/match/input/Input.java @@ -1,28 +1,22 @@ package forge.match.input; +import java.awt.event.MouseEvent; + import forge.game.card.Card; import forge.game.player.Player; import forge.game.spellability.SpellAbility; -import java.awt.event.MouseEvent; -/** - * TODO: Write javadoc for this type. - * - */ public interface Input { - - // showMessage() is always the first method called void showMessageInitial(); void selectCard(Card c, MouseEvent triggerEvent); void selectAbility(SpellAbility ab); - void selectPlayer(Player player, MouseEvent triggerEven); + void selectPlayer(Player player, MouseEvent triggerEvent); void selectButtonOK(); void selectButtonCancel(); - } \ No newline at end of file
- * InputAttack class. - *
serialVersionUID=7849903731842214245L
- * Abstract Input class. - *
serialVersionUID=-6539552513871194081L
- * Input_Block class. - *
serialVersionUID=6120743598368928128L
- * InputConfirm class. - *
- * InputConfirmMulligan class. - *
serialVersionUID=-8112954303001155622L
- * Input_PassPriority class. - *
serialVersionUID=-581477682214137181L
- * canMake. color is like "G", returns "Green". - *
serialVersionUID=3467312982164195091L
- * done. - *
- * GuiInput class. - *
- * selectButtonOK. - *
- * selectButtonCancel. - *
- * selectPlayer. - *
- * selectCard. - *
- * InputControl class. - *
- * updateInput. - *