Sending warnings to user when decision made was invalid.
Started work on animating when some card affects another card.
This commit is contained in:
@@ -41,4 +41,6 @@ public interface GameStateListener {
|
|||||||
public void setSite(PhysicalCard card);
|
public void setSite(PhysicalCard card);
|
||||||
|
|
||||||
public void setZoneSize(String playerId, Zone zone, int size);
|
public void setZoneSize(String playerId, Zone zone, int size);
|
||||||
|
|
||||||
|
public void cardAffectedByCard(PhysicalCard card, PhysicalCard affectedCard);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,5 +5,7 @@ import com.gempukku.lotro.logic.decisions.AwaitingDecision;
|
|||||||
public interface UserFeedback {
|
public interface UserFeedback {
|
||||||
public void sendAwaitingDecision(String playerId, AwaitingDecision awaitingDecision);
|
public void sendAwaitingDecision(String playerId, AwaitingDecision awaitingDecision);
|
||||||
|
|
||||||
|
public void sendWarning(String playerId, String warning);
|
||||||
|
|
||||||
public boolean hasPendingDecisions();
|
public boolean hasPendingDecisions();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -219,6 +219,11 @@ public class GameState {
|
|||||||
addCardToZone(card, Zone.ATTACHED);
|
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) {
|
public void stackCard(PhysicalCard card, PhysicalCard stackOn) {
|
||||||
((PhysicalCardImpl) card).stackOn((PhysicalCardImpl) stackOn);
|
((PhysicalCardImpl) card).stackOn((PhysicalCardImpl) stackOn);
|
||||||
addCardToZone(card, Zone.STACKED);
|
addCardToZone(card, Zone.STACKED);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
public class DefaultUserFeedback implements UserFeedback {
|
public class DefaultUserFeedback implements UserFeedback {
|
||||||
private Map<String, AwaitingDecision> _awaitingDecisionMap = new HashMap<String, AwaitingDecision>();
|
private Map<String, AwaitingDecision> _awaitingDecisionMap = new HashMap<String, AwaitingDecision>();
|
||||||
|
private Map<String, String> _warnings = new HashMap<String, String>();
|
||||||
|
|
||||||
public void participantDecided(String playerId) {
|
public void participantDecided(String playerId) {
|
||||||
_awaitingDecisionMap.remove(playerId);
|
_awaitingDecisionMap.remove(playerId);
|
||||||
@@ -23,11 +24,20 @@ public class DefaultUserFeedback implements UserFeedback {
|
|||||||
_awaitingDecisionMap.put(playerId, awaitingDecision);
|
_awaitingDecisionMap.put(playerId, awaitingDecision);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendWarning(String playerId, String warning) {
|
||||||
|
_warnings.put(playerId, warning);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasPendingDecisions() {
|
public boolean hasPendingDecisions() {
|
||||||
return _awaitingDecisionMap.size() > 0;
|
return _awaitingDecisionMap.size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String consumeWarning(String playerId) {
|
||||||
|
return _warnings.remove(playerId);
|
||||||
|
}
|
||||||
|
|
||||||
public Set<String> getUsersPendingDecision() {
|
public Set<String> getUsersPendingDecision() {
|
||||||
return _awaitingDecisionMap.keySet();
|
return _awaitingDecisionMap.keySet();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ public class GameEvent {
|
|||||||
START_SKIRMISH, END_SKIRMISH,
|
START_SKIRMISH, END_SKIRMISH,
|
||||||
ADD_TOKENS, REMOVE_TOKENS,
|
ADD_TOKENS, REMOVE_TOKENS,
|
||||||
MESSAGE, WARNING,
|
MESSAGE, WARNING,
|
||||||
ZONE_SIZE
|
ZONE_SIZE,
|
||||||
|
CARD_AFFECTS_CARD
|
||||||
}
|
}
|
||||||
|
|
||||||
private String _message;
|
private String _message;
|
||||||
|
|||||||
@@ -115,6 +115,11 @@ public class GatheringParticipantCommunicationChannel implements GameStateListen
|
|||||||
_events.add(new GameEvent(ZONE_SIZE).participantId(playerId).zone(zone).count(size));
|
_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() {
|
public List<GameEvent> consumeGameEvents() {
|
||||||
List<GameEvent> result = _events;
|
List<GameEvent> result = _events;
|
||||||
_events = new LinkedList<GameEvent>();
|
_events = new LinkedList<GameEvent>();
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ public class LotroGameMediator {
|
|||||||
|
|
||||||
} catch (DecisionResultInvalidException decisionResultInvalidException) {
|
} catch (DecisionResultInvalidException decisionResultInvalidException) {
|
||||||
// Participant provided wrong answer - send a warning message, and ask again for the same decision
|
// 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);
|
_userFeedback.sendAwaitingDecision(lotroGameParticipant, awaitingDecision);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,6 +185,11 @@ public class LotroGameMediator {
|
|||||||
if (communicationChannel != null) {
|
if (communicationChannel != null) {
|
||||||
for (GameEvent gameEvent : communicationChannel.consumeGameEvents())
|
for (GameEvent gameEvent : communicationChannel.consumeGameEvents())
|
||||||
visitor.visitGameEvent(gameEvent);
|
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);
|
AwaitingDecision awaitingDecision = _userFeedback.getAwaitingDecision(participantId);
|
||||||
if (awaitingDecision != null)
|
if (awaitingDecision != null)
|
||||||
visitor.visitAwaitingDecision(awaitingDecision);
|
visitor.visitAwaitingDecision(awaitingDecision);
|
||||||
|
|||||||
@@ -54,6 +54,8 @@ var GempLotrGameUI = Class.extend({
|
|||||||
|
|
||||||
tabPane: null,
|
tabPane: null,
|
||||||
|
|
||||||
|
animationEffectDiv: null,
|
||||||
|
|
||||||
init: function(url) {
|
init: function(url) {
|
||||||
log("ui initialized");
|
log("ui initialized");
|
||||||
var that = this;
|
var that = this;
|
||||||
@@ -116,7 +118,6 @@ var GempLotrGameUI = Class.extend({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this.specialGroup = new NormalCardGroup(this.cardActionDialog, function(card) {
|
this.specialGroup = new NormalCardGroup(this.cardActionDialog, function(card) {
|
||||||
return (card.zone == "SPECIAL");
|
return (card.zone == "SPECIAL");
|
||||||
}, false);
|
}, false);
|
||||||
@@ -180,6 +181,10 @@ var GempLotrGameUI = Class.extend({
|
|||||||
function (event) {
|
function (event) {
|
||||||
that.clickCardFunction(event);
|
that.clickCardFunction(event);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.animationEffectDiv = $("<div id='animation'></div>");
|
||||||
|
this.animationEffectDiv.hide();
|
||||||
|
$("#main").append(this.animationEffectDiv);
|
||||||
},
|
},
|
||||||
|
|
||||||
addBottomLeftTabPane: function() {
|
addBottomLeftTabPane: function() {
|
||||||
@@ -260,21 +265,21 @@ var GempLotrGameUI = Class.extend({
|
|||||||
initializeDialogs: function() {
|
initializeDialogs: function() {
|
||||||
this.smallDialog = $("<div></div>")
|
this.smallDialog = $("<div></div>")
|
||||||
.dialog({
|
.dialog({
|
||||||
autoOpen: false,
|
autoOpen: false,
|
||||||
closeOnEscape: false,
|
closeOnEscape: false,
|
||||||
resizable: false,
|
resizable: false,
|
||||||
width: 400,
|
width: 400,
|
||||||
height: 200
|
height: 200
|
||||||
});
|
});
|
||||||
|
|
||||||
this.cardActionDialog = $("<div></div>")
|
this.cardActionDialog = $("<div></div>")
|
||||||
.dialog({
|
.dialog({
|
||||||
autoOpen: false,
|
autoOpen: false,
|
||||||
closeOnEscape: false,
|
closeOnEscape: false,
|
||||||
resizable: true,
|
resizable: true,
|
||||||
width: 600,
|
width: 600,
|
||||||
height: 300
|
height: 300
|
||||||
});
|
});
|
||||||
|
|
||||||
var that = this;
|
var that = this;
|
||||||
|
|
||||||
@@ -286,15 +291,15 @@ var GempLotrGameUI = Class.extend({
|
|||||||
|
|
||||||
this.infoDialog = $("<div></div>")
|
this.infoDialog = $("<div></div>")
|
||||||
.dialog({
|
.dialog({
|
||||||
autoOpen: false,
|
autoOpen: false,
|
||||||
closeOnEscape: true,
|
closeOnEscape: true,
|
||||||
resizable: true,
|
resizable: true,
|
||||||
title: "Card information",
|
title: "Card information",
|
||||||
minHeight: 80,
|
minHeight: 80,
|
||||||
minWidth: 200,
|
minWidth: 200,
|
||||||
width: 600,
|
width: 600,
|
||||||
height: 300
|
height: 300
|
||||||
});
|
});
|
||||||
|
|
||||||
var swipeOptions = {
|
var swipeOptions = {
|
||||||
threshold: 20,
|
threshold: 20,
|
||||||
@@ -499,6 +504,8 @@ var GempLotrGameUI = Class.extend({
|
|||||||
this.message(gameEvent);
|
this.message(gameEvent);
|
||||||
} else if (eventType == "WARNING") {
|
} else if (eventType == "WARNING") {
|
||||||
this.warning(gameEvent);
|
this.warning(gameEvent);
|
||||||
|
} else if (eventType == "CARD_AFFECTS_CARD") {
|
||||||
|
this.cardAffectsCard(gameEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var skirmish = element.getElementsByTagName("skirmish")
|
var skirmish = element.getElementsByTagName("skirmish")
|
||||||
@@ -573,9 +580,9 @@ var GempLotrGameUI = Class.extend({
|
|||||||
else if (zone == "DISCARD")
|
else if (zone == "DISCARD")
|
||||||
$("#discard" + this.getPlayerIndex(playerId)).text("Discard: " + count);
|
$("#discard" + this.getPlayerIndex(playerId)).text("Discard: " + count);
|
||||||
else if (zone == "DEAD")
|
else if (zone == "DEAD")
|
||||||
$("#deadPile" + this.getPlayerIndex(playerId)).text("Dead pile: " + count);
|
$("#deadPile" + this.getPlayerIndex(playerId)).text("Dead pile: " + count);
|
||||||
else if (zone == "DECK")
|
else if (zone == "DECK")
|
||||||
$("#deck" + this.getPlayerIndex(playerId)).text("Deck: " + count);
|
$("#deck" + this.getPlayerIndex(playerId)).text("Deck: " + count);
|
||||||
},
|
},
|
||||||
|
|
||||||
playerPosition: function(element) {
|
playerPosition: function(element) {
|
||||||
@@ -631,6 +638,38 @@ var GempLotrGameUI = Class.extend({
|
|||||||
this.chatBox.appendMessage(message, "warningMessage");
|
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) {
|
startSkirmish: function(element) {
|
||||||
var cardId = element.getAttribute("cardId");
|
var cardId = element.getAttribute("cardId");
|
||||||
var opposingCardIds = element.getAttribute("opposingCardIds").split(",");
|
var opposingCardIds = element.getAttribute("opposingCardIds").split(",");
|
||||||
@@ -729,7 +768,7 @@ var GempLotrGameUI = Class.extend({
|
|||||||
if (index != -1)
|
if (index != -1)
|
||||||
cardData.attachedCards.splice(index, 1);
|
cardData.attachedCards.splice(index, 1);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
var card = $(".card:cardId(" + cardId + ")");
|
var card = $(".card:cardId(" + cardId + ")");
|
||||||
var cardData = card.data("card");
|
var cardData = card.data("card");
|
||||||
@@ -850,7 +889,7 @@ var GempLotrGameUI = Class.extend({
|
|||||||
if (index != -1)
|
if (index != -1)
|
||||||
cardData.attachedCards.splice(index, 1);
|
cardData.attachedCards.splice(index, 1);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
card.remove();
|
card.remove();
|
||||||
@@ -922,13 +961,13 @@ var GempLotrGameUI = Class.extend({
|
|||||||
this.smallDialog
|
this.smallDialog
|
||||||
.html(text + "<br /><input id='integerDecision' type='text' value='0'>")
|
.html(text + "<br /><input id='integerDecision' type='text' value='0'>")
|
||||||
.dialog("option", "buttons",
|
.dialog("option", "buttons",
|
||||||
{
|
{
|
||||||
"OK": function() {
|
"OK": function() {
|
||||||
$(this).dialog("close");
|
$(this).dialog("close");
|
||||||
that.decisionFunction(id, $("#integerDecision").val());
|
that.decisionFunction(id, $("#integerDecision").val());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
$("#integerDecision").SpinnerControl({ type: 'range',
|
$("#integerDecision").SpinnerControl({ type: 'range',
|
||||||
typedata: {
|
typedata: {
|
||||||
@@ -960,13 +999,13 @@ var GempLotrGameUI = Class.extend({
|
|||||||
this.smallDialog
|
this.smallDialog
|
||||||
.html(html)
|
.html(html)
|
||||||
.dialog("option", "buttons",
|
.dialog("option", "buttons",
|
||||||
{
|
{
|
||||||
"OK": function() {
|
"OK": function() {
|
||||||
$(this).dialog("close");
|
$(this).dialog("close");
|
||||||
that.decisionFunction(id, $("#multipleChoiceDecision").val());
|
that.decisionFunction(id, $("#multipleChoiceDecision").val());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
this.smallDialog.dialog("open");
|
this.smallDialog.dialog("open");
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
TO DO:
|
TO DO:
|
||||||
Before release:
|
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:
|
Next priority:
|
||||||
24. The events that are played and cards affected should be shown to the players briefly using animations to make it
|
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
|
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.
|
final methods were possible to avoid implementation errors on new cards added.
|
||||||
10. Add active/all cards switch to the user interface.
|
10. Add active/all cards switch to the user interface.
|
||||||
34.
|
35.
|
||||||
|
|
||||||
DONE:
|
DONE:
|
||||||
1. Introduce AbstractPermanent into Blueprint hierarchy.
|
1. Introduce AbstractPermanent into Blueprint hierarchy.
|
||||||
@@ -48,3 +46,6 @@ with Filters.sameCard(...) filter.
|
|||||||
26. The game area should display chat from the start.
|
26. The game area should display chat from the start.
|
||||||
13. Add dead/discard pile displays.
|
13. Add dead/discard pile displays.
|
||||||
25. Remove all non-essencial alerts, instead add warnings to chat panel.
|
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.
|
||||||
|
|||||||
Reference in New Issue
Block a user