Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions forge-game/src/main/java/forge/game/GameState.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ static class PlayerState {
private String precast = null;
private String putOnStack = null;
private final Map<ZoneType, String> cardTexts = new EnumMap<>(ZoneType.class);
private String name = null;
}
private final List<PlayerState> playerStates = new ArrayList<>();

Expand Down Expand Up @@ -574,6 +575,8 @@ else if (categoryName.endsWith("phaseadvance"))
getPlayerState(categoryName).manaPool = categoryValue;
} else if (categoryName.endsWith("persistentmana")) {
getPlayerState(categoryName).persistentMana = categoryValue;
} else if (categoryName.endsWith("name")) {
getPlayerState(categoryName).name = categoryValue;
} else {
System.err.println("Unknown key: " + categoryName);
}
Expand Down Expand Up @@ -1136,6 +1139,9 @@ private void applyCountersToGameEntity(GameEntity entity, String counterString)

private void setupPlayerState(final Player p, final PlayerState state) {
// Lock check static as we setup player state
if (state.name != null && !state.name.isEmpty()) {
p.setName(state.name);
}

// Clear all zones first, this ensures that any lingering cards and effects (e.g. in command zone) get cleared up
// before setting up a new state
Expand Down
3 changes: 3 additions & 0 deletions forge-game/src/main/java/forge/game/GameView.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ public void updatePlayers(final Game game) {
public String getTitle() {
return get(TrackableProperty.Title);
}
public void updateTitle() {
set(TrackableProperty.Title, match.getTitle());
}

public boolean isCommander() {
return get(TrackableProperty.IsCommander);
Expand Down
5 changes: 4 additions & 1 deletion forge-game/src/main/java/forge/game/Match.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class Match {
private List<PaperCard> removedCards = Lists.newArrayList();
private final List<RegisteredPlayer> players;
private final GameRules rules;
private final String title;
private String title;

private final EventBus events = new EventBus("match events");
private final Map<Integer, GameOutcome> gameOutcomes = Maps.newHashMap();
Expand All @@ -49,6 +49,9 @@ public Match(final GameRules rules0, final List<RegisteredPlayer> players0, fina
public GameRules getRules() {
return rules;
}
public void setTitle(final String title) {
this.title = title;
}
String getTitle() {
final Multiset<RegisteredPlayer> wins = getGamesWon();
final StringBuilder titleAppend = new StringBuilder(title);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ private void startPuzzleCreate() {
SOptionPane.showMessageDialog(Localizer.getInstance().getMessage("lblWelcomePuzzleModeMessage"),
Localizer.getInstance().getMessage("lblCreateNewPuzzle"), SOptionPane.WARNING_ICON);
emptyPuzzle.applyToGame(hostedMatch.getGame());
hostedMatch.refreshTitle();
});

final List<RegisteredPlayer> players = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ private boolean startPuzzleSolve() {
hostedMatch.setStartGameHook(() -> {
SOptionPane.showMessageDialog(selected.getGoalDescription(), selected.getName(), SOptionPane.INFORMATION_ICON);
selected.applyToGame(hostedMatch.getGame());
hostedMatch.refreshTitle();
});

hostedMatch.setEndGameHook((() -> selected.savePuzzleSolve(hostedMatch.getGame().getOutcome().isWinner(GamePlayerUtil.getGuiPlayer()))));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ private boolean startPuzzleSolve() {
hostedMatch.setStartGameHook(() -> {
SOptionPane.showMessageDialog(selected.getGoalDescription(), selected.getName(), SOptionPane.INFORMATION_ICON);
selected.applyToGame(hostedMatch.getGame());
hostedMatch.refreshTitle();
});

hostedMatch.setEndGameHook((() -> selected.savePuzzleSolve(hostedMatch.getGame().getOutcome().isWinner(GamePlayerUtil.getGuiPlayer()))));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ protected void startMatch() {
LoadingOverlay.show(Forge.getLocalizer().getMessage("lblLoadingThePuzzle"), true, () -> {
// Load selected puzzle
final HostedMatch hostedMatch = GuiBase.getInterface().hostMatch();
hostedMatch.setStartGameHook(() -> chosen.applyToGame(hostedMatch.getGame()));
hostedMatch.setStartGameHook(() -> {
chosen.applyToGame(hostedMatch.getGame());
hostedMatch.refreshTitle();
});

hostedMatch.setEndGameHook((() -> chosen.savePuzzleSolve(hostedMatch.getGame().getOutcome().isWinner(GamePlayerUtil.getGuiPlayer()))));

Expand Down
22 changes: 22 additions & 0 deletions forge-gui/res/puzzle/Duelist_Number_5.pzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[metadata]
Name:Magic the Puzzling - Duelist #5 - Eeny Meeny Miney Moe
Goal:Win
Turns:1
Difficulty:Common
Description:Your opponent is Nick. He's under the false assumption that he's going to win this duel. Of course, with Circles of Protection for two of your three colors, four blockers, and a Conversion in play, he has plenty of reason to be cocky. But then, you draw an Instill Energy and the solution comes to you. You're going to take Nick down this turn and you plan to enjoy the look on his face when you do it.\n\nIt is the beginning of your upkeep phase. Defeat Nick this turn without dying.
[state]
ActivePlayer=human
ActivePhase=upkeep
HumanLife=5
AILife=12
AIName=Nick
humanhand=Black Ward|Set:3ED; Disenchant|Set:3ED; Earthbind|Set:3ED; Swords to Plowshares|Set:3ED; Instill Energy|Set:3ED; Flashfires|Set:3ED; Red Elemental Blast|Set:3ED; Stone Rain|Set:3ED; Giant Growth|Set:3ED; Black Knight|Set:3ED;
humanprecast=
humangraveyard=
humanlibrary=
humanBattlefield=Plains|Set:3ED; Plains|Set:3ED; Plains|Set:3ED; Plains|Set:3ED; Forest|Set:3ED; Forest|Set:3ED; Mountain|Set:3ED; Mountain|Set:3ED; Mountain|Set:3ED; Mountain|Set:3ED; Basalt Monolith|Set:3ED; Sol Ring|Set:3ED; Rod of Ruin|Set:3ED; Stone Giant|Id:1|Set:3ED; Dwarven Weaponsmith|Set:3ED; Grizzly Bears|Set:3ED; Hill Giant|Set:3ED; Library of Leng|Set:3ED;
aibattlefield=Plains|Set:3ED; Plains|Set:3ED; Swamp|Tapped|Set:3ED; Swamp|Tapped|Set:3ED; Swamp|Tapped|Set:3ED; Island|Tapped|Set:3ED; Island|Tapped|Set:3ED; Sol Ring|Tapped|Set:3ED; Circle of Protection: Red|Set:3ED; Circle of Protection: Green|Set:3ED; Phantasmal Forces|Set:3ED; Hypnotic Specter|Counters:M1M1=3|Id:11|Set:3ED; Unstable Mutation|AttachedTo:11|Set:3ED; Pearled Unicorn|Id:10|Set:3ED; Flight|AttachedTo:10|Set:3ED; Wall of Water|Set:3ED; Conversion|Set:3ED; Dingus Egg|Set:3ED;Weakness|AttachedTo:1|Set:3ED;
aiprecast=
aigraveyard=
ailibrary=
aiexile=
27 changes: 27 additions & 0 deletions forge-gui/src/main/java/forge/gamemodes/match/HostedMatch.java
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,33 @@ public GameView getGameView() {
return game == null ? null : game.getView();
}

// Recomputes the "X vs Y" match title from the players' current in-game names
// and re-pushes it to any open guis. Needed after a puzzle renames a player
// (e.g. via AIName) since the title is normally captured once at match start,
// before the puzzle's GameState has been applied.
public void refreshTitle() {
if (game == null || match == null) {
return;
}
final FCollectionView<Player> players = game.getPlayers();
if (players.size() != 2) {
return;
}
match.setTitle(TextUtil.concatNoSpace(players.get(0).getName(), " vs ", players.get(1).getName()));

final GameView gameView = getGameView();
if (gameView == null) {
return;
}
gameView.updateTitle();

FThreads.invokeInEdtNowOrLater(() -> {
for (final IGuiGame gui : guis.values()) {
gui.setGameView(gameView);
}
});
}

public void endCurrentGame() {
if (game == null) { return; }
boolean isMatchOver = game.getView().isMatchOver();
Expand Down
10 changes: 10 additions & 0 deletions forge-gui/src/main/java/forge/gamemodes/puzzle/Puzzle.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class Puzzle extends GameState implements InventoryItem, Comparable<Puzzl
String url;
String difficulty;
String description;
String aiName;
String targets;
int targetCount = 1;
boolean humanControl = false;
Expand Down Expand Up @@ -62,6 +63,8 @@ private void loadMetaData(List<String> metadataLines) {
this.difficulty = split[1].trim();
} else if ("Description".equalsIgnoreCase(split[0])) {
this.description = split[1].trim();
} else if ("AIName".equalsIgnoreCase(split[0])) {
this.aiName = split[1].trim();
} else if ("Targets".equalsIgnoreCase(split[0])) {
this.targets = split[1].trim();
} else if ("TargetCount".equalsIgnoreCase(split[0])) {
Expand Down Expand Up @@ -94,6 +97,11 @@ public String getGoalDescription() {
desc.append("\nTurns Limit: ");
desc.append(this.turns);

if (this.aiName != null) {
desc.append("\nOpponent: ");
desc.append(this.aiName);
}

if (this.description != null) {
desc.append("\n\n");
desc.append(this.description.replace("\\n", "\n"));
Expand Down Expand Up @@ -247,6 +255,8 @@ public String getName() {

public boolean getCompleted() { return completed; }

public String getAIName() { return aiName; }

public String toString() {
StringBuilder sb = new StringBuilder();
if (this.completed) {
Expand Down