Sending warnings to user when decision made was invalid.

Started work on animating when some card affects another card.
This commit is contained in:
marcins78@gmail.com
2011-09-21 10:39:08 +00:00
parent a66e3aa4f7
commit 2df7d2f261
9 changed files with 116 additions and 46 deletions

View File

@@ -41,4 +41,6 @@ public interface GameStateListener {
public void setSite(PhysicalCard card);
public void setZoneSize(String playerId, Zone zone, int size);
public void cardAffectedByCard(PhysicalCard card, PhysicalCard affectedCard);
}

View File

@@ -5,5 +5,7 @@ import com.gempukku.lotro.logic.decisions.AwaitingDecision;
public interface UserFeedback {
public void sendAwaitingDecision(String playerId, AwaitingDecision awaitingDecision);
public void sendWarning(String playerId, String warning);
public boolean hasPendingDecisions();
}

View File

@@ -219,6 +219,11 @@ public class GameState {
addCardToZone(card, Zone.ATTACHED);
}
public void cardAffectsCard(PhysicalCard card, PhysicalCard affectedCard) {
for (GameStateListener listener : getAllGameStateListeners())
listener.cardAffectedByCard(card, affectedCard);
}
public void stackCard(PhysicalCard card, PhysicalCard stackOn) {
((PhysicalCardImpl) card).stackOn((PhysicalCardImpl) stackOn);
addCardToZone(card, Zone.STACKED);

View File

@@ -9,6 +9,7 @@ import java.util.Set;
public class DefaultUserFeedback implements UserFeedback {
private Map<String, AwaitingDecision> _awaitingDecisionMap = new HashMap<String, AwaitingDecision>();
private Map<String, String> _warnings = new HashMap<String, String>();
public void participantDecided(String playerId) {
_awaitingDecisionMap.remove(playerId);
@@ -23,11 +24,20 @@ public class DefaultUserFeedback implements UserFeedback {
_awaitingDecisionMap.put(playerId, awaitingDecision);
}
@Override
public void sendWarning(String playerId, String warning) {
_warnings.put(playerId, warning);
}
@Override
public boolean hasPendingDecisions() {
return _awaitingDecisionMap.size() > 0;
}
public String consumeWarning(String playerId) {
return _warnings.remove(playerId);
}
public Set<String> getUsersPendingDecision() {
return _awaitingDecisionMap.keySet();
}

View File

@@ -15,7 +15,8 @@ public class GameEvent {
START_SKIRMISH, END_SKIRMISH,
ADD_TOKENS, REMOVE_TOKENS,
MESSAGE, WARNING,
ZONE_SIZE
ZONE_SIZE,
CARD_AFFECTS_CARD
}
private String _message;

View File

@@ -115,6 +115,11 @@ public class GatheringParticipantCommunicationChannel implements GameStateListen
_events.add(new GameEvent(ZONE_SIZE).participantId(playerId).zone(zone).count(size));
}
@Override
public void cardAffectedByCard(PhysicalCard card, PhysicalCard affectedCard) {
_events.add(new GameEvent(CARD_AFFECTS_CARD).card(card).targetCardId(affectedCard.getCardId()));
}
public List<GameEvent> consumeGameEvents() {
List<GameEvent> result = _events;
_events = new LinkedList<GameEvent>();

View File

@@ -168,7 +168,7 @@ public class LotroGameMediator {
} catch (DecisionResultInvalidException decisionResultInvalidException) {
// Participant provided wrong answer - send a warning message, and ask again for the same decision
// _userCommunication.sendWarning(lotroGameParticipant, decisionResultInvalidException.getWarningMessage());
_userFeedback.sendWarning(lotroGameParticipant, decisionResultInvalidException.getWarningMessage());
_userFeedback.sendAwaitingDecision(lotroGameParticipant, awaitingDecision);
}
}
@@ -185,6 +185,11 @@ public class LotroGameMediator {
if (communicationChannel != null) {
for (GameEvent gameEvent : communicationChannel.consumeGameEvents())
visitor.visitGameEvent(gameEvent);
String warning = _userFeedback.consumeWarning(participantId);
if (warning != null)
visitor.visitGameEvent(new GameEvent(GameEvent.Type.WARNING).message(warning));
AwaitingDecision awaitingDecision = _userFeedback.getAwaitingDecision(participantId);
if (awaitingDecision != null)
visitor.visitAwaitingDecision(awaitingDecision);

View File

@@ -54,6 +54,8 @@ var GempLotrGameUI = Class.extend({
tabPane: null,
animationEffectDiv: null,
init: function(url) {
log("ui initialized");
var that = this;
@@ -116,7 +118,6 @@ var GempLotrGameUI = Class.extend({
});
}
this.specialGroup = new NormalCardGroup(this.cardActionDialog, function(card) {
return (card.zone == "SPECIAL");
}, false);
@@ -180,6 +181,10 @@ var GempLotrGameUI = Class.extend({
function (event) {
that.clickCardFunction(event);
});
this.animationEffectDiv = $("<div id='animation'></div>");
this.animationEffectDiv.hide();
$("#main").append(this.animationEffectDiv);
},
addBottomLeftTabPane: function() {
@@ -260,21 +265,21 @@ var GempLotrGameUI = Class.extend({
initializeDialogs: function() {
this.smallDialog = $("<div></div>")
.dialog({
autoOpen: false,
closeOnEscape: false,
resizable: false,
width: 400,
height: 200
});
autoOpen: false,
closeOnEscape: false,
resizable: false,
width: 400,
height: 200
});
this.cardActionDialog = $("<div></div>")
.dialog({
autoOpen: false,
closeOnEscape: false,
resizable: true,
width: 600,
height: 300
});
autoOpen: false,
closeOnEscape: false,
resizable: true,
width: 600,
height: 300
});
var that = this;
@@ -286,15 +291,15 @@ var GempLotrGameUI = Class.extend({
this.infoDialog = $("<div></div>")
.dialog({
autoOpen: false,
closeOnEscape: true,
resizable: true,
title: "Card information",
minHeight: 80,
minWidth: 200,
width: 600,
height: 300
});
autoOpen: false,
closeOnEscape: true,
resizable: true,
title: "Card information",
minHeight: 80,
minWidth: 200,
width: 600,
height: 300
});
var swipeOptions = {
threshold: 20,
@@ -499,6 +504,8 @@ var GempLotrGameUI = Class.extend({
this.message(gameEvent);
} else if (eventType == "WARNING") {
this.warning(gameEvent);
} else if (eventType == "CARD_AFFECTS_CARD") {
this.cardAffectsCard(gameEvent);
}
}
var skirmish = element.getElementsByTagName("skirmish")
@@ -573,9 +580,9 @@ var GempLotrGameUI = Class.extend({
else if (zone == "DISCARD")
$("#discard" + this.getPlayerIndex(playerId)).text("Discard: " + count);
else if (zone == "DEAD")
$("#deadPile" + this.getPlayerIndex(playerId)).text("Dead pile: " + count);
else if (zone == "DECK")
$("#deck" + this.getPlayerIndex(playerId)).text("Deck: " + count);
$("#deadPile" + this.getPlayerIndex(playerId)).text("Dead pile: " + count);
else if (zone == "DECK")
$("#deck" + this.getPlayerIndex(playerId)).text("Deck: " + count);
},
playerPosition: function(element) {
@@ -631,6 +638,38 @@ var GempLotrGameUI = Class.extend({
this.chatBox.appendMessage(message, "warningMessage");
},
cardAffectsCard: function(element) {
var participantId = element.getAttribute("participantId");
var blueprintId = element.getAttribute("blueprintId");
var targetCardId = element.getAttribute("targetCardId");
var card = new Card(blueprintId, "ANIMATION", "anim", participantId);
var cardDiv = createCardDiv(card.imageUrl);
this.animationEffectDiv.queue("anim",
function(next) {
var targetCard = $(".card:cardId(" + targetCardId + ")");
if (targetCard.length > 0) {
targetCard = targetCard[0];
$("#animation").html(cardDiv);
$("#animation").css({
position: "absolute",
left: targetCard.position().left(),
top: targetCard.position().top,
width: targetCard.width(),
height: targetCard.height(),
"z-index": 100});
$("#animation").show();
$('#animation').animate(
{opacity: 0},
{duration: 500,
queue: false,
complete: next
});
}
}).dequeue("anim");
},
startSkirmish: function(element) {
var cardId = element.getAttribute("cardId");
var opposingCardIds = element.getAttribute("opposingCardIds").split(",");
@@ -729,7 +768,7 @@ var GempLotrGameUI = Class.extend({
if (index != -1)
cardData.attachedCards.splice(index, 1);
}
);
);
var card = $(".card:cardId(" + cardId + ")");
var cardData = card.data("card");
@@ -850,7 +889,7 @@ var GempLotrGameUI = Class.extend({
if (index != -1)
cardData.attachedCards.splice(index, 1);
}
);
);
}
card.remove();
@@ -922,13 +961,13 @@ var GempLotrGameUI = Class.extend({
this.smallDialog
.html(text + "<br /><input id='integerDecision' type='text' value='0'>")
.dialog("option", "buttons",
{
"OK": function() {
$(this).dialog("close");
that.decisionFunction(id, $("#integerDecision").val());
}
}
);
{
"OK": function() {
$(this).dialog("close");
that.decisionFunction(id, $("#integerDecision").val());
}
}
);
$("#integerDecision").SpinnerControl({ type: 'range',
typedata: {
@@ -960,13 +999,13 @@ var GempLotrGameUI = Class.extend({
this.smallDialog
.html(html)
.dialog("option", "buttons",
{
"OK": function() {
$(this).dialog("close");
that.decisionFunction(id, $("#multipleChoiceDecision").val());
}
}
);
{
"OK": function() {
$(this).dialog("close");
that.decisionFunction(id, $("#multipleChoiceDecision").val());
}
}
);
this.smallDialog.dialog("open");
},

View File

@@ -1,7 +1,5 @@
TO DO:
Before release:
31. Allow to cancel selection to reset to none-selected and go with different selection if no auto-accept is set or
multiple choices required.
Next priority:
24. The events that are played and cards affected should be shown to the players briefly using animations to make it
@@ -14,7 +12,7 @@ Optional:
4. Modify the Blueprint hierarchy to return possible return objects (PlayEventAction), TriggeredAction, etc. Use
final methods were possible to avoid implementation errors on new cards added.
10. Add active/all cards switch to the user interface.
34.
35.
DONE:
1. Introduce AbstractPermanent into Blueprint hierarchy.
@@ -48,3 +46,6 @@ with Filters.sameCard(...) filter.
26. The game area should display chat from the start.
13. Add dead/discard pile displays.
25. Remove all non-essencial alerts, instead add warnings to chat panel.
31. Allow to cancel selection to reset to none-selected and go with different selection if no auto-accept is set or
multiple choices required.
34. Player should be able to concede the game at any time.