Adding greyed-out styling for inactive cards

- Inactive cards are now automatically greyed out whenever a new turn starts
- Fixed the deck inspection window not showing when your deck play operation failed (such as when using Bridge of Khazad-dum with no Balrog)
This commit is contained in:
Christian 'ketura' McCarty
2024-11-22 20:07:59 -06:00
parent c0b54f76cd
commit d2c05f6045
10 changed files with 87 additions and 14 deletions

View File

@@ -473,4 +473,12 @@ ul.ui-tabs-nav {
.ui-button-icon-primary.ui-icon.ui-icon-search,
.ui-button-icon-primary.ui-icon.ui-icon-circle-close {
margin-left:4px;
}
.card.inactive img {
filter: grayscale(0.7) contrast(0.5) brightness(0.6);
}
.card.inactive tokenOverlay {
color: #777777;
}

View File

@@ -505,6 +505,7 @@ class Card {
return foil;
}
//Used for representing physical cards
static CreateCardDiv(image, testingText, text, foil, tokens, noBorder, errata, incomplete) {
var cardDiv = $("<div class='card'><img src='" + image + "' width='100%' height='100%'>" + ((text != null) ? text : "") + "</div>");
@@ -534,7 +535,7 @@ class Card {
// var collapsedDiv = $("<div class='collapsedOverlay'><img src='https://res.starwarsccg.org/gemp/collapsed.jpg' width='100%' height='100%'></div>");
// cardDiv.append(collapsedDiv);
if (tokens === undefined || tokens) {
var overlayDiv = $("<div class='tokenOverlay'></div>");
cardDiv.append(overlayDiv);
@@ -563,6 +564,7 @@ class Card {
return cardDiv;
}
//Used by non-game pages such as the deckbuilder and main hall
static CreateFullCardDiv(image, testingText, foil, horizontal, noBorder) {
var foilPresentation = Card.getFoilPresentation();
@@ -611,6 +613,7 @@ class Card {
return cardDiv;
}
//Used for ephemeral card displays such as event display or the "affected by card" effect
static CreateSimpleCardDiv(image, testingText, foil, incomplete, borderWidth) {
var cardDiv = $("<div class='card'><img src='" + image + "' width='100%' height='100%'></div>");

View File

@@ -97,6 +97,9 @@ class CardDisplay {
if(card !== undefined && maxWidth !== undefined && maxHeight !== undefined) {
this.reloadFromCard(card, maxWidth, maxHeight);
}
else {
this.baseDiv.data("card", {});
}
}
clear() {
@@ -115,6 +118,7 @@ class CardDisplay {
}
reloadFromCard(card, maxWidth, maxHeight, noborder) {
this.baseDiv.data("card", card);
this.currentBP = card.blueprintId;
this.frontside = card.imageUrl;
if(!this.frontside) {

View File

@@ -60,6 +60,9 @@ var GameAnimations = Class.extend({
if (this.game.spectatorMode || this.game.replayMode || (participantId != this.game.bottomPlayerId)) {
var card = new Card(blueprintId, testingText, backSideTestingText, "ANIMATION", "anim", participantId);
var cardDiv = Card.CreateSimpleCardDiv(card.imageUrl, card.testingText, card.foil, card.incomplete, 16);
// var display = new CardDisplay(card, $("#main").width() / 2, $("#main").width() / 2)
// var cardDiv = display.baseDiv;
$("#main").queue(
function (next) {
@@ -137,7 +140,10 @@ var GameAnimations = Class.extend({
var card = new Card(blueprintId, testingText, backSideTestingText, "ANIMATION", "anim" + i, participantId);
var cardDiv = Card.CreateSimpleCardDiv(card.imageUrl, card.testingText, card.foil, card.incomplete, 16);
// var display = new CardDisplay(card, $("#main").width() / 2, $("#main").width() / 2)
// var cardDiv = display.baseDiv;
var targetCard = $(".card:cardId(" + targetCardId + ")");
if (targetCard.length > 0) {
cardDiv.data("card", card);
@@ -433,10 +439,13 @@ var GameAnimations = Class.extend({
if (card.length > 0) {
var cardData = card.data("card");
if (cardData.zone == "ATTACHED" || cardData.zone == "STACKED") {
$(".card").each(
function () {
var cardData = $(this).data("card");
if(!cardData || !cardData.attachedCards)
return;
var index = -1;
for (var i = 0; i < cardData.attachedCards.length; i++)
if (cardData.attachedCards[i].data("card").cardId == cardId) {
@@ -493,6 +502,7 @@ var GameAnimations = Class.extend({
var that = this;
$("#main").queue(
function (next) {
var inactiveCardIds = element.getAttribute("otherCardIds");
var playerId = element.getAttribute("participantId");
var playerIndex = that.game.getPlayerIndex(playerId);
@@ -505,6 +515,20 @@ var GameAnimations = Class.extend({
$(this).removeClass("current");
});
that.game.advPathGroup.setCurrentPlayerIndex(playerIndex);
if(inactiveCardIds) {
var ids = inactiveCardIds.split(",");
$(".card").each(function () {
var cardData = $(this).data("card");
if ($.inArray(cardData.cardId, ids) > -1) {
$(this).addClass("inactive");
}
else {
$(this).removeClass("inactive");
}
});
}
next();
});
@@ -658,7 +682,7 @@ var GameAnimations = Class.extend({
$(".card").each(function () {
var cardData = $(this).data("card");
if (cardData.skirmish == true) {
if (cardData && cardData.skirmish == true) {
delete cardData.skirmish;
}
});

View File

@@ -8,7 +8,6 @@ import com.gempukku.lotro.logic.timing.GameStats;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
public interface GameStateListener {
@@ -26,7 +25,7 @@ public interface GameStateListener {
void setTwilight(int twilightPool);
void setCurrentPlayerId(String playerId);
void setCurrentPlayerId(String playerId, Set<PhysicalCard> inactiveCards);
String getAssignedPlayerId();
void setCurrentPhase(String currentPhase);

View File

@@ -10,7 +10,6 @@ import com.gempukku.lotro.logic.timing.GameStats;
import com.gempukku.polling.LongPollableResource;
import com.gempukku.polling.WaitingRequest;
import java.time.LocalDateTime;
import java.util.*;
import static com.gempukku.lotro.game.state.GameEvent.Type.*;
@@ -167,8 +166,10 @@ public class GameCommunicationChannel implements GameStateListener, LongPollable
}
@Override
public void setCurrentPlayerId(String currentPlayerId) {
appendEvent(new GameEvent(TURN_CHANGE).participantId(currentPlayerId));
public void setCurrentPlayerId(String currentPlayerId, Set<PhysicalCard> inactiveCards) {
appendEvent(new GameEvent(TURN_CHANGE)
.participantId(currentPlayerId)
.otherCardIds(getCardIds(inactiveCards)));
}
@Override

View File

@@ -13,6 +13,7 @@ import org.apache.logging.log4j.Logger;
import java.security.InvalidParameterException;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
public class GameState {
private static final Logger _log = LogManager.getLogger(GameState.class);
@@ -230,7 +231,7 @@ public class GameState {
if (_playerOrder != null) {
listener.initializeBoard(_playerOrder.getAllPlayers(), _format.discardPileIsPublic());
if (_currentPlayerId != null)
listener.setCurrentPlayerId(_currentPlayerId);
listener.setCurrentPlayerId(_currentPlayerId, Collections.emptySet());
if (_currentPhase != null)
listener.setCurrentPhase(getPhaseString());
listener.setTwilight(_twilightPool);
@@ -301,6 +302,9 @@ public class GameState {
}
listener.sendGameStats(gameStats);
if (_currentPlayerId != null)
listener.setCurrentPlayerId(_currentPlayerId, getInactiveCards());
}
for (String lastMessage : _lastMessages)
@@ -821,8 +825,15 @@ public class GameState {
_moveCount = 0;
_fierceSkirmishes = false;
for (GameStateListener listener : getAllGameStateListeners())
listener.setCurrentPlayerId(_currentPlayerId);
for (var listener : getAllGameStateListeners()) {
listener.setCurrentPlayerId(_currentPlayerId, getInactiveCards());
}
}
public Set<PhysicalCard> getInactiveCards() {
return _inPlay.stream()
.filter(x -> !isCardInPlayActive(x))
.collect(Collectors.toSet());
}
public int getTurnNumber() {

View File

@@ -55,9 +55,31 @@ public abstract class ChooseCardsFromDeckEffect extends AbstractEffect {
int minimum = Math.min(_minimum, cards.size());
if (_maximum == 0) {
cardsSelected(game, Collections.emptySet());
if (showAll) {
game.getUserFeedback().sendAwaitingDecision(_playerId,
new ArbitraryCardsSelectionDecision(2, "You may inspect the contents of your deck while retrieving cards", game.getGameState().getDeck(_deckId), new LinkedList<>(), 0, 0) {
@Override
public void decisionMade(String result2) throws DecisionResultInvalidException {
cardsSelected(game, Collections.emptySet());
}
});
}
else {
cardsSelected(game, Collections.emptySet());
}
} else if (cards.size() == minimum) {
cardsSelected(game, cards);
if (showAll) {
game.getUserFeedback().sendAwaitingDecision(_playerId,
new ArbitraryCardsSelectionDecision(2, "You may inspect the contents of your deck while retrieving cards", game.getGameState().getDeck(_deckId), new LinkedList<>(), 0, 0) {
@Override
public void decisionMade(String result2) throws DecisionResultInvalidException {
cardsSelected(game, cards);
}
});
}
else {
cardsSelected(game, cards);
}
} else {
game.getUserFeedback().sendAwaitingDecision(_playerId,
new ArbitraryCardsSelectionDecision(1, "Choose cards from deck", new LinkedList<>(cards), minimum, _maximum) {

View File

@@ -38,6 +38,7 @@ public class RemoveFromGameAtTest extends AbstractAtTest {
pass(P2);
selectYes(P1);
selectCardAction(P2, grond);
pass(P2); //dismiss revealed deck cards
assertEquals(Zone.REMOVED, gimliInDeck.getZone());
assertEquals(Zone.REMOVED, aragornInDeck.getZone());
}

View File

@@ -131,7 +131,7 @@ public class Card_01_087_Tests
assertEquals(Zone.HAND, bb.getZone());
scn.FreepsPlayCard(late);
scn.FreepsDismissRevealedCards();
assertEquals(Zone.DISCARD, late.getZone());
}
}