[Mobile] add Experimental Rollback Phase

This commit is contained in:
Anthony Calosa
2021-03-14 11:57:20 +08:00
parent 84aaccc3da
commit 68ecf41511
17 changed files with 95 additions and 7 deletions

View File

@@ -1153,7 +1153,7 @@ public class PhaseHandler implements java.io.Serializable {
}
turn = cturn;
game.fireEvent(new GameEventTurnPhase(playerTurn, phase, ""));
game.fireEvent(new GameEventTurnPhase(playerTurn, phase, "dev"));
if (endCombat) {
endCombat(); // not-null can be created only when declare attackers phase begins
}

View File

@@ -51,6 +51,7 @@ import forge.ImageCache;
import forge.LobbyPlayer;
import forge.Singletons;
import forge.StaticData;
import forge.ai.GameState;
import forge.assets.FSkinProp;
import forge.card.CardStateName;
import forge.control.KeyboardShortcuts;
@@ -620,6 +621,11 @@ public final class CMatchUI
});
}
@Override
public GameState getGamestate() {
return null;
}
@Override
public List<JMenu> getMenus() {
return menus.getMenus();
@@ -771,7 +777,7 @@ public final class CMatchUI
}
@Override
public void updatePhase() {
public void updatePhase(boolean saveState) {
final PlayerView p = getGameView().getPlayerTurn();
final PhaseType ph = getGameView().getPhase();
// this should never happen, but I've seen it periodically... so, need to get to the bottom of it

View File

@@ -7,7 +7,9 @@ import java.util.List;
import java.util.Map;
import forge.FThreads;
import forge.ai.GameState;
import forge.assets.FSkinImage;
import forge.item.IPaperCard;
import forge.util.Localizer;
import org.apache.commons.lang3.StringUtils;
@@ -71,6 +73,11 @@ public class MatchController extends AbstractGuiGame {
private static HostedMatch hostedMatch;
private static MatchScreen view;
private static GameState phaseGameState;
private GameState getPhaseGameState() {
return phaseGameState;
}
private final Map<PlayerView, InfoTab> zonesToRestore = Maps.newHashMap();
@@ -122,6 +129,11 @@ public class MatchController extends AbstractGuiGame {
refreshCardDetails(null);
}
@Override
public GameState getGamestate() {
return getPhaseGameState();
}
public boolean hotSeatMode() {
return FModel.getPreferences().getPrefBoolean(FPref.MATCH_HOT_SEAT_MODE);
}
@@ -199,7 +211,7 @@ public class MatchController extends AbstractGuiGame {
}
@Override
public void updatePhase() {
public void updatePhase(boolean saveState) {
final PlayerView p = getGameView().getPlayerTurn();
final PhaseType ph = getGameView().getPhase();
@@ -217,6 +229,20 @@ public class MatchController extends AbstractGuiGame {
}
if(GuiBase.isNetworkplay())
checkStack();
if (saveState) {
phaseGameState = new GameState() {
@Override //todo get specific card edition for this function?
public IPaperCard getPaperCard(final String cardName) {
return FModel.getMagicDb().getCommonCards().getCard(cardName);
}
};
try {
phaseGameState.initFromGame(getGameView().getGame());
} catch (Exception e) {
System.out.println(phaseGameState);
}
}
}

View File

@@ -378,6 +378,9 @@ public class MatchScreen extends FScreen {
devMenu.setEnabled(true);
else
devMenu.setEnabled(false);
//rollbackphase enable -- todo limit by gametype?
devMenu.getChildAt(2).setEnabled(game.getPlayers().size() == 2 && game.getStack().size() == 0 && !GuiBase.isNetworkplay());
}
}

View File

@@ -34,6 +34,17 @@ public class VDevMenu extends FDropDownMenu {
});
}
}));
addItem(new FMenuItem(Localizer.getInstance().getMessage("lblRollbackPhase"), new FEventHandler() {
@Override
public void handleEvent(FEvent e) {
ThreadUtil.invokeInGameThread(new Runnable() { //must invoke all these in game thread since they may require synchronous user input
@Override
public void run() {
MatchController.instance.getGameController().cheat().rollbackPhase();
}
});
}
}));
addItem(new FMenuItem(Localizer.getInstance().getMessage("lblCastSpellOrPlayLand"), new FEventHandler() {
@Override
public void handleEvent(FEvent e) {

View File

@@ -1947,6 +1947,7 @@ lblViewAll=Zeige alle Karten
lblSetupGame=Spielstand erstellen
lblDumpGame=Spielstand sichern
lblTutor=Suche nach Karte
lblRollbackPhase=Rollback Phase
lblAddCounterPermanent=Marken zu Karte hinzufügen
lblSubCounterPermanent=Marken von Karte entfernen
lblTapPermanent=Bleibende Karte tappen

View File

@@ -1947,6 +1947,7 @@ lblViewAll=View All Cards
lblSetupGame=Setup Game State
lblDumpGame=Dump Game State
lblTutor=Tutor for Card
lblRollbackPhase=Rollback Phase
lblAddCounterPermanent=Add Counters to Card
lblSubCounterPermanent=Sub Counters from Card
lblTapPermanent=Tap Permanents

View File

@@ -1947,6 +1947,7 @@ lblViewAll=Ver todas las cartas
lblSetupGame=Configurar el estado del juego
lblDumpGame=Volcar el estado del juego
lblTutor=Tutor para la carta
lblRollbackPhase=Rollback Phase
lblAddCounterPermanent=Añadir contadores a la carta
lblSubCounterPermanent=Quitar contadores a la carta
lblTapPermanent=Girar permanentes

View File

@@ -1947,6 +1947,7 @@ lblViewAll=View All Cards
lblSetupGame=Setup Game State
lblDumpGame=Dump Game State
lblTutor=Tutor for Card
lblRollbackPhase=Rollback Phase
lblAddCounterPermanent=Add Counters to Card
lblSubCounterPermanent=Sub Counters from Card
lblTapPermanent=Tap Permanents

View File

@@ -1947,6 +1947,7 @@ lblViewAll=View All Cards
lblSetupGame=Setup Game State
lblDumpGame=Dump Game State
lblTutor=Tutor for Card
lblRollbackPhase=Rollback Phase
lblAddCounterPermanent=Add Counters to Card
lblSubCounterPermanent=Sub Counters from Card
lblTapPermanent=Tap Permanents

View File

@@ -1947,6 +1947,7 @@ lblViewAll=查看所有牌
lblSetupGame=设定游戏状态
lblDumpGame=转储游戏状态
lblTutor=导师牌
lblRollbackPhase=Rollback Phase
lblAddCounterPermanent=向牌添加指示物
lblSubCounterPermanent=从牌减少指示物
lblTapPermanent=横置永久物

View File

@@ -39,6 +39,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
private boolean processEventsQueued, needPhaseUpdate, needCombatUpdate, needStackUpdate, needPlayerControlUpdate, refreshFieldUpdate;
private boolean gameOver, gameFinished;
private boolean needSaveState = false;
private PlayerView turnUpdate;
public FControlGameEventHandler(final PlayerControllerHuman humanController0) {
@@ -81,7 +82,12 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
}
if (needPhaseUpdate) {
needPhaseUpdate = false;
matchController.updatePhase();
if (needSaveState) {
needSaveState = false;
matchController.updatePhase(true);
} else {
matchController.updatePhase(false);
}
}
if (needCombatUpdate) {
needCombatUpdate = false;
@@ -173,6 +179,10 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
@Override
public Void visit(final GameEventTurnPhase ev) {
needPhaseUpdate = true;
if (ev.phaseDesc == "dev")
needSaveState = false;
else
needSaveState = true;
return processEvent();
}

View File

@@ -8,6 +8,8 @@ public interface IDevModeCheats {
void generateMana();
void rollbackPhase();
void dumpGameState();
void setupGameState();
@@ -95,6 +97,11 @@ public interface IDevModeCheats {
@Override
public void generateMana() {
}
@Override
public void rollbackPhase() {
}
@Override
public void dumpGameState() {
}

View File

@@ -7,6 +7,7 @@ import java.util.Map;
import com.google.common.base.Function;
import forge.LobbyPlayer;
import forge.ai.GameState;
import forge.assets.FSkinProp;
import forge.deck.CardPool;
import forge.game.GameEntityView;
@@ -42,7 +43,7 @@ public interface IGuiGame {
void updateButtons(PlayerView owner, String label1, String label2, boolean enable1, boolean enable2, boolean focus1);
void flashIncorrectAction();
void alertUser();
void updatePhase();
void updatePhase(boolean saveState);
void updateTurn(PlayerView player);
void updatePlayerControl();
void enableOverlay();
@@ -61,6 +62,7 @@ public interface IGuiGame {
void updateCards(Iterable<CardView> cards);
void refreshCardDetails(Iterable<CardView> cards);
void refreshField();
GameState getGamestate();
void updateManaPool(Iterable<PlayerView> manaPoolUpdate);
void updateLives(Iterable<PlayerView> livesUpdate);
void setPanelSelection(CardView hostCard);

View File

@@ -418,7 +418,7 @@ public class HostedMatch {
gui.openView(new TrackableCollection<>(p.getView()));
gui.setGameView(null);
gui.setGameView(gameView);
gui.updatePhase();
gui.updatePhase(true);
gui.message(event.message);
}
}

View File

@@ -2,6 +2,7 @@ package forge.net.server;
import com.google.common.base.Function;
import forge.LobbyPlayer;
import forge.ai.GameState;
import forge.assets.FSkinProp;
import forge.deck.CardPool;
import forge.game.GameEntityView;
@@ -93,7 +94,7 @@ public class NetGuiGame extends AbstractGuiGame {
public void alertUser() { send(ProtocolMethod.alertUser); }
@Override
public void updatePhase() {
public void updatePhase(boolean saveState) {
updateGameView();
send(ProtocolMethod.updatePhase);
}
@@ -189,6 +190,11 @@ public class NetGuiGame extends AbstractGuiGame {
send(ProtocolMethod.refreshField);
}
@Override
public GameState getGamestate() {
return null;
}
@Override
public SpellAbilityView getAbilityToPlay(final CardView hostCard, final List<SpellAbilityView> abilities, final ITriggerEvent triggerEvent) {
return sendAndWait(ProtocolMethod.getAbilityToPlay, hostCard, abilities, null/*triggerEvent*/); //someplatform don't have mousetriggerevent class or it will not allow them to click/tap

View File

@@ -2140,6 +2140,17 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
});
}
@Override
public void rollbackPhase() {
final Player pPriority = getGame().getPhaseHandler().getPriorityPlayer();
if (pPriority == null) {
getGui().message(localizer.getMessage("lblNoPlayerPriorityGameStateCannotBeSetup"));
return;
}
if (getGui().getGamestate() != null)
getGui().getGamestate().applyToGame(getGame());
}
private GameState createGameStateObject() {
return new GameState() {
@Override