Deck inspection post-game

- Added a GAME_ENDED event which fires after the game has ended
- After the game has ended, the server sends all of the remaining cards in a player's draw deck to the client
- The client triggers on the GAME_ENDED signal to enable a new deck view similar to the existing zones, which captures all those ending cards for inspection
This commit is contained in:
Christian 'ketura' McCarty
2023-05-13 20:46:32 -05:00
parent d9d1e30ea4
commit ef51c5f79c
7 changed files with 62 additions and 25 deletions

View File

@@ -228,6 +228,10 @@ var GameAnimations = Class.extend({
that.game.adventureDeckDialogs[participantId].append(cardDiv);
else if (zone == "REMOVED")
that.game.removedPileDialogs[participantId].append(cardDiv);
else if (zone == "DECK") {
that.game.miscPileDialogs[participantId].append(cardDiv);
animate = false;
}
else
$("#main").append(cardDiv);
@@ -248,7 +252,7 @@ var GameAnimations = Class.extend({
}
if (animate && (this.game.spectatorMode || this.game.replayMode || (participantId != this.game.bottomPlayerId))
&& zone != "DISCARD" && zone != "DEAD" && zone != "HAND" && zone != "ADVENTURE_DECK") {
&& zone != "DISCARD" && zone != "DEAD" && zone != "HAND" && zone != "ADVENTURE_DECK" && zone != "DECK") {
var oldValues = {};
$("#main").queue(

View File

@@ -34,6 +34,8 @@ var GempLotrGameUI = Class.extend({
deadPileGroups: null,
removedPileDialogs: null,
removedPileGroups: null,
miscPileDialogs: null,
miscPileGroups: null,
statsDiv: null,
@@ -150,6 +152,8 @@ var GempLotrGameUI = Class.extend({
this.deadPileGroups = {};
this.removedPileDialogs = {};
this.removedPileGroups = {};
this.miscPileDialogs = {};
this.miscPileGroups = {};
this.skirmishShadowGroup = new NormalCardGroup($("#main"), function (card) {
return card.zone == "SHADOW_CHARACTERS" && card.skirmish == true;
@@ -458,6 +462,20 @@ var GempLotrGameUI = Class.extend({
return that.dragStopCardFunction(event);
});
},
processGameEnd: function() {
var that = this;
$("#deck" + this.getPlayerIndex(this.bottomPlayerId)).addClass("clickable").click(
(function (index) {
return function () {
var dialog = that.miscPileDialogs[index];
var group = that.miscPileGroups[index];
openSizeDialog(dialog);
that.dialogResize(dialog, group);
group.layoutCards();
};
})(that.bottomPlayerId));
},
addBottomLeftTabPane: function () {
var that = this;
@@ -1048,6 +1066,10 @@ var GempLotrGameUI = Class.extend({
for (var playerId in this.removedPileGroups)
if (this.removedPileGroups.hasOwnProperty(playerId))
this.removedPileGroups[playerId].layoutCards();
for (var playerId in this.miscPileGroups)
if (this.miscPileGroups.hasOwnProperty(playerId))
this.miscPileGroups[playerId].layoutCards();
}
this.tabPane.css({
position: "absolute",
@@ -1273,6 +1295,8 @@ var GempLotrGameUI = Class.extend({
this.animations.cardActivated(gameEvent, animate);
} else if (eventType == "D") {
this.animations.processDecision(gameEvent, animate);
} else if (eventType == "EG") {
this.processGameEnd();
}
},
@@ -1412,6 +1436,7 @@ var GempLotrGameUI = Class.extend({
}
this.createPile(participantId, "Adventure Deck", "adventureDeckDialogs", "adventureDeckGroups");
this.createPile(participantId, "Draw Deck", "miscPileDialogs", "miscPileGroups");
}
for (var i = 0; i < this.allPlayerIds.length; i++) {
@@ -1430,30 +1455,6 @@ var GempLotrGameUI = Class.extend({
this.layoutUI(true);
},
createAdventureDeckPiles: function(id) {
var adventureDeckDialog = $("<div></div>").dialog({
autoOpen: false,
closeOnEscape: true,
resizable: true,
title: "Adventure deck - " + participantId,
minHeight: 80,
minWidth: 200,
width: 600,
height: 300
});
this.adventureDeckDialogs[participantId] = adventureDeckDialog;
this.adventureDeckGroups[participantId] = new NormalCardGroup(adventureDeckDialog, function (card) {
return true;
}, false);
this.adventureDeckGroups[participantId].setBounds(this.padding, this.padding, 580 - 2 * (this.padding), 250 - 2 * (this.padding));
adventureDeckDialog.bind("dialogresize", function () {
that.dialogResize(adventureDeckDialog, that.adventureDeckGroups[participantId]);
});
},
createPile: function(playerId, name, dialogsName, groupsName) {
var dialog = $("<div></div>").dialog({
autoOpen: false,

View File

@@ -11,6 +11,7 @@ import java.util.Set;
public interface GameStateListener {
public void cardCreated(PhysicalCard card);
public void cardCreated(PhysicalCard card, boolean overridePlayerVisibility);
public void cardMoved(PhysicalCard card);
@@ -57,4 +58,6 @@ public interface GameStateListener {
public void decisionRequired(String playerId, AwaitingDecision awaitingDecision);
public void sendWarning(String playerId, String warning);
public void endGame();
}

View File

@@ -121,6 +121,13 @@ public class GameCommunicationChannel implements GameStateListener, LongPollable
appendEvent(new GameEvent(PUT_CARD_INTO_PLAY).card(card));
}
@Override
public void cardCreated(PhysicalCard card, boolean overridePlayerVisibility) {
boolean publicDiscard = card.getZone() == Zone.DISCARD && _format.discardPileIsPublic();
if (card.getZone().isPublic() || publicDiscard || ((overridePlayerVisibility || card.getZone().isVisibleByOwner()) && card.getOwner().equals(_self)))
appendEvent(new GameEvent(PUT_CARD_INTO_PLAY).card(card));
}
@Override
public void cardMoved(PhysicalCard card) {
appendEvent(new GameEvent(MOVE_CARD_IN_PLAY).card(card));
@@ -223,4 +230,9 @@ public class GameCommunicationChannel implements GameStateListener, LongPollable
public long getLastAccessed() {
return _lastConsumed;
}
@Override
public void endGame() {
appendEvent(new GameEvent(GAME_ENDED));
}
}

View File

@@ -24,6 +24,7 @@ public class GameEvent {
SEND_MESSAGE("M"), SEND_WARNING("W"),
GAME_STATS("GS"),
CHAT_MESSAGE("CM"),
GAME_ENDED("EG"),
CARD_AFFECTED_BY_CARD("CAC"), SHOW_CARD_ON_SCREEN("EP"), FLASH_CARD_IN_PLAY("CA"), DECISION("D");
private final String code;

View File

@@ -118,6 +118,20 @@ public class GameState {
}
}
public void finish() {
for (GameStateListener listener : getAllGameStateListeners()) {
listener.endGame();
}
for (String playerId : _playerOrder.getAllPlayers()) {
for(var card : getDeck(playerId)) {
for (GameStateListener listener : getAllGameStateListeners()) {
listener.cardCreated(card, true);
}
}
}
}
public boolean isMoving() {
return _moving;
}

View File

@@ -192,6 +192,8 @@ public class DefaultLotroGame implements LotroGame {
if (_gameState != null)
_gameState.sendMessage(_winnerPlayerId + " is the winner due to: " + reason);
_gameState.finish();
for (GameResultListener gameResultListener : _gameResultListeners)
gameResultListener.gameFinished(_winnerPlayerId, reason, _losers);