Merge branch 'topsy' into 'master'

Topsy Turvy

See merge request core-developers/forge!3933
This commit is contained in:
Michael Kamensky
2021-02-20 15:56:28 +00:00
4 changed files with 69 additions and 35 deletions

View File

@@ -306,7 +306,7 @@ public class Game {
* Gets the players who are still fighting to win, in turn order.
*/
public final PlayerCollection getPlayersInTurnOrder() {
if (turnOrder.isDefaultDirection()) {
if (getTurnOrder().isDefaultDirection()) {
return ingamePlayers;
}
final PlayerCollection players = new PlayerCollection(ingamePlayers);
@@ -321,7 +321,7 @@ public class Game {
// Don't use getPlayersInTurnOrder to prevent copying the player collection twice
final PlayerCollection players = new PlayerCollection(ingamePlayers);
players.remove(phaseHandler.getPlayerTurn());
if (!turnOrder.isDefaultDirection()) {
if (!getTurnOrder().isDefaultDirection()) {
Collections.reverse(players);
}
return players;
@@ -416,6 +416,9 @@ public class Game {
* The Direction in which the turn order of this Game currently proceeds.
*/
public final Direction getTurnOrder() {
if (phaseHandler.getPlayerTurn() != null && phaseHandler.getPlayerTurn().hasKeyword("The turn order is reversed.")) {
return turnOrder.getOtherDirection();
}
return turnOrder;
}
public final void reverseTurnOrder() {
@@ -677,7 +680,7 @@ public class Game {
* {@code null} if there are no players in the game.
*/
public Player getNextPlayerAfter(final Player playerTurn) {
return getNextPlayerAfter(playerTurn, turnOrder);
return getNextPlayerAfter(playerTurn, getTurnOrder());
}
/**

View File

@@ -143,6 +143,8 @@ public class PhaseHandler implements java.io.Serializable {
private void advanceToNextPhase() {
PhaseType oldPhase = phase;
boolean isTopsy = playerTurn.hasKeyword("The phases of your turn are reversed.");
boolean turnEnded = false;
if (bRepeatCleanup) { // for when Cleanup needs to repeat itself
bRepeatCleanup = false;
@@ -160,15 +162,16 @@ public class PhaseHandler implements java.io.Serializable {
setPhase(nextPhase);
}
else {
setPhase(PhaseType.getNext(phase));
turnEnded = PhaseType.isLast(phase, isTopsy);
setPhase(PhaseType.getNext(phase, isTopsy));
}
}
game.getStack().clearUndoStack(); //can't undo action from previous phase
String phaseType = oldPhase == phase ? "Repeat" : phase == PhaseType.getNext(oldPhase) ? "" : "Additional";
String phaseType = oldPhase == phase ? "Repeat" : phase == PhaseType.getNext(oldPhase, isTopsy) ? "" : "Additional";
if (phase == PhaseType.UNTAP) {
if (turnEnded) {
turn++;
game.updateTurnForView();
game.fireEvent(new GameEventTurnBegan(playerTurn, turn));
@@ -1127,7 +1130,7 @@ public class PhaseHandler implements java.io.Serializable {
}
public final boolean devAdvanceToPhase(PhaseType targetPhase) {
while (phase.isBefore(targetPhase)) {
while (phase.isBefore(targetPhase, playerTurn.hasKeyword("The phases of your turn are reversed."))) {
if (checkStateBasedEffects()) {
return false;
}

View File

@@ -1,12 +1,9 @@
package forge.game.phase;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.*;
public enum PhaseType {
@@ -24,16 +21,32 @@ public enum PhaseType {
END_OF_TURN("End of Turn"),
CLEANUP("Cleanup");
public static final List<PhaseType> ALL_PHASES = Collections.unmodifiableList(
Arrays.asList(
UNTAP, UPKEEP, DRAW,
MAIN1,
COMBAT_BEGIN, COMBAT_DECLARE_ATTACKERS, COMBAT_DECLARE_BLOCKERS, COMBAT_FIRST_STRIKE_DAMAGE, COMBAT_DAMAGE, COMBAT_END,
MAIN2,
END_OF_TURN, CLEANUP
)
public static final List<List<PhaseType>> PHASE_GROUPS = Arrays.asList(
Arrays.asList(UNTAP, UPKEEP, DRAW),
Arrays.asList(MAIN1),
Arrays.asList(COMBAT_BEGIN, COMBAT_DECLARE_ATTACKERS, COMBAT_DECLARE_BLOCKERS, COMBAT_FIRST_STRIKE_DAMAGE, COMBAT_DAMAGE, COMBAT_END),
Arrays.asList(MAIN2),
Arrays.asList(END_OF_TURN)
);
public static List<PhaseType> AllPhases() {
return AllPhases(false);
}
public static List<PhaseType> AllPhases(boolean isTopsy) {
List<PhaseType> result = new ArrayList<PhaseType>();
List<List<PhaseType>> phase_groups = PHASE_GROUPS;
if (isTopsy) {
phase_groups = Lists.reverse(phase_groups);
}
for (final List<PhaseType> group : phase_groups) {
result.addAll(group);
}
result.add(CLEANUP); // Some cards get confused if cleanup isn't last, it works better this way.
return result;
}
public final String nameForUi;
public final String nameForScripts;
@@ -47,21 +60,19 @@ public enum PhaseType {
public final boolean phaseforUpdateField() {
boolean result =
((ALL_PHASES.indexOf(this) >= ALL_PHASES.indexOf(UNTAP)
&& ALL_PHASES.indexOf(this) < ALL_PHASES.indexOf(COMBAT_FIRST_STRIKE_DAMAGE))
|| (ALL_PHASES.indexOf(this) >= ALL_PHASES.indexOf(MAIN2)
&& ALL_PHASES.indexOf(this) < ALL_PHASES.indexOf(CLEANUP)));
return result;
return ((AllPhases().indexOf(this) >= AllPhases().indexOf(UNTAP)
&& AllPhases().indexOf(this) < AllPhases().indexOf(COMBAT_FIRST_STRIKE_DAMAGE))
|| (AllPhases().indexOf(this) >= AllPhases().indexOf(MAIN2)
&& AllPhases().indexOf(this) < AllPhases().indexOf(CLEANUP)));
}
public final boolean isCombatPhase() {
return ((ALL_PHASES.indexOf(this) >= ALL_PHASES.indexOf(COMBAT_BEGIN))
&& (ALL_PHASES.indexOf(this) <= ALL_PHASES.indexOf(COMBAT_END)));
return ((AllPhases().indexOf(this) >= AllPhases().indexOf(COMBAT_BEGIN))
&& (AllPhases().indexOf(this) <= AllPhases().indexOf(COMBAT_END)));
}
public final boolean isAfter(final PhaseType phase) {
return ALL_PHASES.indexOf(this) > ALL_PHASES.indexOf(phase);
return AllPhases().indexOf(this) > AllPhases().indexOf(phase);
}
public final boolean isMain() {
@@ -69,7 +80,11 @@ public enum PhaseType {
}
public final boolean isBefore(final PhaseType phase) {
return ALL_PHASES.indexOf(this) < ALL_PHASES.indexOf(phase);
return isBefore(phase, false);
}
public final boolean isBefore(final PhaseType phase, boolean isTopsy) {
return AllPhases(isTopsy).indexOf(this) < AllPhases(isTopsy).indexOf(phase);
}
public static PhaseType smartValueOf(final String value) {
@@ -101,7 +116,6 @@ public enum PhaseType {
PhaseType from = PhaseType.smartValueOf(s.substring(0, idxArrow));
String sTo = s.substring(idxArrow + 2);
PhaseType to = StringUtils.isBlank(sTo) ? PhaseType.CLEANUP : PhaseType.smartValueOf(sTo);
result.addAll(EnumSet.range(from, to));
}
else {
@@ -111,15 +125,22 @@ public enum PhaseType {
return result;
}
public static boolean isLast(PhaseType current, boolean isTopsy) {
if (current == null) {
return true;
}
return AllPhases(isTopsy).indexOf(current) == AllPhases(isTopsy).size() - 1;
}
/**
* Get the next PhaseType in turn order.
* @return
*/
public static PhaseType getNext(PhaseType current) {
int iNext = ALL_PHASES.indexOf(current) + 1;
if (iNext >= ALL_PHASES.size()) {
public static PhaseType getNext(PhaseType current, boolean isTopsy) {
int iNext = AllPhases(isTopsy).indexOf(current) + 1;
if (iNext >= AllPhases(isTopsy).size()) {
iNext = 0;
}
return ALL_PHASES.get(iNext);
return AllPhases(isTopsy).get(iNext);
}
}