Game replay and changes in playing cards.

This commit is contained in:
marcins78@gmail.com
2011-10-25 21:20:20 +00:00
parent fdf02bdea0
commit 1864a662e9
9 changed files with 174 additions and 152 deletions

View File

@@ -91,7 +91,10 @@ public class PlayEventAction extends AbstractCostToEffectAction {
if (cost != null)
return cost;
if (!_cardPlayed) {
if (_eventPlayed.getZone() != null)
game.getGameState().removeCardsFromZone(_eventPlayed.getOwner(), Collections.singleton(_eventPlayed));
_cardPlayed = true;
return _playCardEffect;
}
@@ -105,6 +108,8 @@ public class PlayEventAction extends AbstractCostToEffectAction {
if (!_cardDiscarded && !_skipDiscardCard) {
_cardDiscarded = true;
if (_eventPlayed.getZone() != null)
game.getGameState().removeCardsFromZone(_eventPlayed.getOwner(), Collections.singleton(_eventPlayed));
final Zone targetZone = _playCardEffect.getPlayEventResult().getTargetZone();
if (targetZone != null)
game.getGameState().addCardToZone(game, _eventPlayed, targetZone);

View File

@@ -79,6 +79,8 @@ public class PlayPermanentAction extends AbstractCostToEffectAction {
if (!_cardPutIntoPlay) {
_cardPutIntoPlay = true;
if (_permanentPlayed.getZone() != null)
game.getGameState().removeCardsFromZone(_permanentPlayed.getOwner(), Collections.singleton(_permanentPlayed));
game.getGameState().addCardToZone(game, _permanentPlayed, _zone);
}
@@ -93,6 +95,8 @@ public class PlayPermanentAction extends AbstractCostToEffectAction {
} else {
if (!_cardDiscarded) {
_cardDiscarded = true;
if (_permanentPlayed.getZone() != null)
game.getGameState().removeCardsFromZone(_permanentPlayed.getOwner(), Collections.singleton(_permanentPlayed));
game.getGameState().addCardToZone(game, _permanentPlayed, Zone.DISCARD);
}
}

View File

@@ -146,7 +146,7 @@ public class GameEvent {
}
public GameEvent card(PhysicalCard physicalCard) {
GameEvent gameEvent = cardId(physicalCard.getCardId()).blueprintId(physicalCard.getBlueprintId()).participantId(physicalCard.getOwner()).zone(physicalCard.getZone()).side(physicalCard.getBlueprint().getSide().name());
GameEvent gameEvent = cardId(physicalCard.getCardId()).blueprintId(physicalCard.getBlueprintId()).participantId(physicalCard.getOwner()).zone(physicalCard.getZone());
if (physicalCard.getCardController() != null)
gameEvent = gameEvent.controllerId(physicalCard.getCardController());
PhysicalCard attachedTo = physicalCard.getAttachedTo();

View File

@@ -46,7 +46,6 @@ public class PlayCardEffect extends AbstractEffect {
@Override
protected FullEffectResult playEffectReturningResult(LotroGame game) {
game.getGameState().removeCardsFromZone(_cardPlayed.getOwner(), Collections.singleton(_cardPlayed));
return new FullEffectResult(Collections.singleton(new PlayCardResult(_cardPlayed, _attachedToCard)), true, true);
}
}

View File

@@ -24,7 +24,6 @@ public class PlayEventEffect extends PlayCardEffect {
@Override
protected FullEffectResult playEffectReturningResult(LotroGame game) {
game.getGameState().removeCardsFromZone(_cardPlayed.getOwner(), Collections.singleton(_cardPlayed));
return new FullEffectResult(Collections.singleton(_playEventResult), true, true);
}
}

View File

@@ -126,9 +126,16 @@ public class ServerResource {
public StreamingOutput getReplay(
@PathParam("replayId") String replayId) throws ParserConfigurationException {
File gameReplayFolder = new File("i:\\gemp-lotr\\replay");
if (!replayId.contains("$"))
sendError(Response.Status.NOT_FOUND);
if (replayId.contains("."))
sendError(Response.Status.NOT_FOUND);
final File replayFile = new File(gameReplayFolder, replayId);
String[] split = replayId.split("\\$");
if (split.length != 2)
sendError(Response.Status.NOT_FOUND);
final File replayFile = new File(new File(gameReplayFolder, split[0]), split[1] + ".xml");
if (!replayFile.exists() || !replayFile.isFile())
sendError(Response.Status.NOT_FOUND);
@@ -138,8 +145,9 @@ public class ServerResource {
InputStream is = new FileInputStream(replayFile);
try {
byte[] bytes = new byte[1024];
int count = is.read(bytes);
outputStream.write(bytes, 0, count);
int count;
while ((count = is.read(bytes)) != -1)
outputStream.write(bytes, 0, count);
} finally {
is.close();
}

View File

@@ -75,7 +75,8 @@ var ChatBoxUI = Class.extend({
if (this.chatListDiv != null)
this.chatListDiv.css({ position: "absolute", left: x + width - userListWidth + "px", top: y + "px", width: userListWidth, height: height - this.talkBoxHeight - 3 * talkBoxPadding, overflow: "auto" });
this.chatMessagesDiv.css({ position: "absolute", left: x + "px", top: y + "px", width: width - userListWidth, height: height - this.talkBoxHeight - 3 * talkBoxPadding, overflow: "auto" });
this.chatTalkDiv.css({ position: "absolute", left: x + talkBoxPadding + "px", top: y - 2 * talkBoxPadding + (height - this.talkBoxHeight) + "px", width: width - 3 * talkBoxPadding , height: this.talkBoxHeight });
if (this.chatTalkDiv != null)
this.chatTalkDiv.css({ position: "absolute", left: x + talkBoxPadding + "px", top: y - 2 * talkBoxPadding + (height - this.talkBoxHeight) + "px", width: width - 3 * talkBoxPadding , height: this.talkBoxHeight });
},
appendMessage: function(message, msgClass) {

View File

@@ -10,6 +10,12 @@ var GameAnimations = Class.extend({
this.game = gameUI;
},
getAnimationLength: function(origValue) {
if (this.game.replayMode)
return origValue * 2;
return origValue;
},
cardActivated: function(element, animate) {
if (animate) {
var that = this;
@@ -18,19 +24,19 @@ var GameAnimations = Class.extend({
var cardId = element.getAttribute("cardId");
// Play-out game event animation only if it's not the player who initiated it
if (this.game.spectatorMode || (participantId != this.game.bottomPlayerId)) {
if (this.game.spectatorMode || this.game.replayMode || (participantId != this.game.bottomPlayerId)) {
var cardDiv = $(".card:cardId(" + cardId + ")");
if (cardDiv != null) {
$("#main").queue(
function(next) {
$(".borderOverlay", cardDiv)
.switchClass("borderOverlay", "highlightBorderOverlay", that.cardActivatedDuration / 6)
.switchClass("highlightBorderOverlay", "borderOverlay", that.cardActivatedDuration / 6)
.switchClass("borderOverlay", "highlightBorderOverlay", that.cardActivatedDuration / 6)
.switchClass("highlightBorderOverlay", "borderOverlay", that.cardActivatedDuration / 6)
.switchClass("borderOverlay", "highlightBorderOverlay", that.cardActivatedDuration / 6)
.switchClass("highlightBorderOverlay", "borderOverlay", that.cardActivatedDuration / 6);
setTimeout(next, that.cardActivatedDuration);
.switchClass("borderOverlay", "highlightBorderOverlay", that.getAnimationLength(that.cardActivatedDuration / 6))
.switchClass("highlightBorderOverlay", "borderOverlay", that.getAnimationLength(that.cardActivatedDuration / 6))
.switchClass("borderOverlay", "highlightBorderOverlay", that.getAnimationLength(that.cardActivatedDuration / 6))
.switchClass("highlightBorderOverlay", "borderOverlay", that.getAnimationLength(that.cardActivatedDuration / 6))
.switchClass("borderOverlay", "highlightBorderOverlay", that.getAnimationLength(that.cardActivatedDuration / 6))
.switchClass("highlightBorderOverlay", "borderOverlay", that.getAnimationLength(that.cardActivatedDuration / 6));
setTimeout(next, that.getAnimationLength(that.cardActivatedDuration));
});
}
}
@@ -45,7 +51,7 @@ var GameAnimations = Class.extend({
var blueprintId = element.getAttribute("blueprintId");
// Play-out game event animation only if it's not the player who initiated it
if (this.game.spectatorMode || (participantId != this.game.bottomPlayerId)) {
if (this.game.spectatorMode || this.game.replayMode || (participantId != this.game.bottomPlayerId)) {
var card = new Card(blueprintId, "ANIMATION", "anim", participantId);
var cardDiv = createSimpleCardDiv(card.imageUrl);
@@ -61,40 +67,40 @@ var GameAnimations = Class.extend({
var cardWidth = card.getWidthForHeight(cardHeight);
$(cardDiv).css(
{
position: "absolute",
left: (gameWidth / 2 - cardWidth / 4),
top: gameHeight * (3 / 8),
width: cardWidth / 2,
height: cardHeight / 2,
"z-index": 100,
opacity: 0});
{
position: "absolute",
left: (gameWidth / 2 - cardWidth / 4),
top: gameHeight * (3 / 8),
width: cardWidth / 2,
height: cardHeight / 2,
"z-index": 100,
opacity: 0});
$(cardDiv).animate(
{
left: "-=" + cardWidth / 4,
top: "-=" + (gameHeight / 8),
width: "+=" + (cardWidth / 2),
height: "+=" + (cardHeight / 2),
opacity: 1},
{
duration: that.playEventDuration / 8,
easing: "linear",
queue: false,
complete: next});
{
left: "-=" + cardWidth / 4,
top: "-=" + (gameHeight / 8),
width: "+=" + (cardWidth / 2),
height: "+=" + (cardHeight / 2),
opacity: 1},
{
duration: that.getAnimationLength(that.playEventDuration / 8),
easing: "linear",
queue: false,
complete: next});
}).queue(
function(next) {
setTimeout(next, that.playEventDuration * (5 / 8));
setTimeout(next, that.getAnimationLength(that.playEventDuration * (5 / 8)));
}).queue(
function(next) {
$(cardDiv).animate(
{
opacity: 0},
{
duration: that.playEventDuration / 4,
easing: "easeOutQuart",
queue: false,
complete: next});
{
opacity: 0},
{
duration: that.getAnimationLength(that.playEventDuration / 4),
easing: "easeOutQuart",
queue: false,
complete: next});
}).queue(
function(next) {
$(cardDiv).remove();
@@ -113,7 +119,7 @@ var GameAnimations = Class.extend({
var targetCardIds = element.getAttribute("otherCardIds").split(",");
// Play-out card affects card animation only if it's not the player who initiated it
if (this.game.spectatorMode || (participantId != this.game.bottomPlayerId)) {
if (this.game.spectatorMode || this.game.replayMode || this.game.replayMode || (participantId != this.game.bottomPlayerId)) {
$("#main").queue(
function(next) {
for (var i = 0; i < targetCardIds.length; i++) {
@@ -132,29 +138,29 @@ var GameAnimations = Class.extend({
var targetCardHeight = $(targetCard).height();
$(cardDiv).css(
{
position: "absolute",
left: $(targetCard).position().left,
top: $(targetCard).position().top,
width: targetCardWidth,
height: targetCardHeight,
"z-index": 100,
opacity: 1});
{
position: "absolute",
left: $(targetCard).position().left,
top: $(targetCard).position().top,
width: targetCardWidth,
height: targetCardHeight,
"z-index": 100,
opacity: 1});
$(cardDiv).animate(
{
opacity: 0,
left: "-=" + (targetCardWidth / 2),
top: "-=" + (targetCardHeight / 2),
width: "+=" + targetCardWidth,
height: "+=" + targetCardHeight},
{
duration: that.cardAffectsCardDuration,
easing: "easeInQuart",
queue: false,
complete: null});
{
opacity: 0,
left: "-=" + (targetCardWidth / 2),
top: "-=" + (targetCardHeight / 2),
width: "+=" + targetCardWidth,
height: "+=" + targetCardHeight},
{
duration: that.getAnimationLength(that.cardAffectsCardDuration),
easing: "easeInQuart",
queue: false,
complete: null});
}
setTimeout(next, that.cardAffectsCardDuration);
setTimeout(next, that.getAnimationLength(that.cardAffectsCardDuration));
}
}).queue(
function(next) {
@@ -165,7 +171,7 @@ var GameAnimations = Class.extend({
$(this).remove();
}
}
);
);
next();
});
}
@@ -217,7 +223,7 @@ var GameAnimations = Class.extend({
});
}
if (animate && (this.game.spectatorMode || (participantId != this.game.bottomPlayerId))
if (animate && (this.game.spectatorMode || this.game.replayMode || (participantId != this.game.bottomPlayerId))
&& zone != "DISCARD" && zone != "DEAD" && zone != "HAND") {
var oldValues = {};
@@ -241,32 +247,32 @@ var GameAnimations = Class.extend({
var cardWidth = card.getWidthForHeight(cardHeight);
$(cardDiv).css(
{
position: "absolute",
left: (gameWidth / 2 - cardWidth / 4),
top: gameHeight * (3 / 8),
width: cardWidth / 2,
height: cardHeight / 2,
"z-index": 100,
opacity: 0});
{
position: "absolute",
left: (gameWidth / 2 - cardWidth / 4),
top: gameHeight * (3 / 8),
width: cardWidth / 2,
height: cardHeight / 2,
"z-index": 100,
opacity: 0});
$(cardDiv).animate(
{
opacity: 1},
{
duration: that.putCardIntoPlayDuration / 8,
easing: "linear",
step: function(now, fx) {
layoutCardElem(cardDiv,
(gameWidth / 2 - cardWidth / 4) - now * (cardWidth / 4),
gameHeight * (3 / 8) - now * (gameHeight / 8),
cardWidth / 2 + now * (cardWidth / 2),
cardHeight / 2 + now * (cardHeight / 2), 100);
},
complete: next});
{
opacity: 1},
{
duration: that.getAnimationLength(that.putCardIntoPlayDuration / 8),
easing: "linear",
step: function(now, fx) {
layoutCardElem(cardDiv,
(gameWidth / 2 - cardWidth / 4) - now * (cardWidth / 4),
gameHeight * (3 / 8) - now * (gameHeight / 8),
cardWidth / 2 + now * (cardWidth / 2),
cardHeight / 2 + now * (cardHeight / 2), 100);
},
complete: next});
}).queue(
function(next) {
setTimeout(next, that.putCardIntoPlayDuration * (5 / 8));
setTimeout(next, that.getAnimationLength(that.putCardIntoPlayDuration * (5 / 8)));
}).queue(
function(next) {
var cardDiv = $(".card:cardId(" + cardId + ")");
@@ -278,20 +284,20 @@ var GameAnimations = Class.extend({
var startHeight = cardDiv.height();
$(cardDiv).animate(
{
left: oldValues["left"]},
{
duration: that.putCardIntoPlayDuration / 4,
easing: "linear",
step: function(now, fx) {
var state = fx.state;
layoutCardElem(cardDiv,
startLeft + (oldValues["left"] - startLeft) * state,
startTop + (oldValues["top"] - startTop) * state,
startWidth + (oldValues["width"] - startWidth) * state,
startHeight + (oldValues["height"] - startHeight) * state, 100);
},
complete: next});
{
left: oldValues["left"]},
{
duration: that.getAnimationLength(that.putCardIntoPlayDuration / 4),
easing: "linear",
step: function(now, fx) {
var state = fx.state;
layoutCardElem(cardDiv,
startLeft + (oldValues["left"] - startLeft) * state,
startTop + (oldValues["top"] - startTop) * state,
startWidth + (oldValues["width"] - startWidth) * state,
startHeight + (oldValues["height"] - startHeight) * state, 100);
},
complete: next});
}).queue(
function(next) {
var cardDiv = $(".card:cardId(" + cardId + ")");
@@ -327,7 +333,7 @@ var GameAnimations = Class.extend({
if (index != -1)
cardData.attachedCards.splice(index, 1);
}
);
);
var card = $(".card:cardId(" + cardId + ")");
var cardData = card.data("card");
@@ -358,18 +364,18 @@ var GameAnimations = Class.extend({
var cardRemovedIds = element.getAttribute("otherCardIds").split(",");
var participantId = element.getAttribute("participantId");
if (animate && (this.game.spectatorMode || (participantId != this.game.bottomPlayerId))) {
if (animate && (this.game.spectatorMode || this.game.replayMode || (participantId != this.game.bottomPlayerId))) {
$("#main").queue(
function(next) {
$(".card:cardId(" + cardRemovedIds + ")")
.animate(
{
opacity: 0},
{
duration: that.removeCardFromPlayDuration,
easing: "easeOutQuart",
queue: false});
setTimeout(next, that.removeCardFromPlayDuration);
{
opacity: 0},
{
duration: that.getAnimationLength(that.removeCardFromPlayDuration),
easing: "easeOutQuart",
queue: false});
setTimeout(next, that.getAnimationLength(that.removeCardFromPlayDuration));
});
}
$("#main").queue(
@@ -393,7 +399,7 @@ var GameAnimations = Class.extend({
if (index != -1)
cardData.attachedCards.splice(index, 1);
}
);
);
}
card.remove();

View File

@@ -281,7 +281,7 @@ var GempLotrGameUI = Class.extend({
this.displayCard(card);
var cardId = card.cardId;
if (cardId.length < 4 || cardId.substring(0, 4) != "temp")
if (!this.replayMode && (cardId.length < 4 || cardId.substring(0, 4) != "temp"))
this.getCardModifiersFunction(cardId, this.setCardModifiers);
},
@@ -292,21 +292,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;
@@ -321,15 +321,15 @@ var GempLotrGameUI = Class.extend({
this.infoDialog = $("<div></div>")
.dialog({
autoOpen: false,
closeOnEscape: true,
resizable: true,
title: "Card information",
minHeight: 80,
minWidth: 200,
width: Math.max(600, width * 0.75),
height: Math.max(300, height * 0.75)
});
autoOpen: false,
closeOnEscape: true,
resizable: true,
title: "Card information",
minHeight: 80,
minWidth: 200,
width: Math.max(600, width * 0.75),
height: Math.max(300, height * 0.75)
});
var swipeOptions = {
threshold: 20,
@@ -472,7 +472,7 @@ var GempLotrGameUI = Class.extend({
var that = this;
this.communication.getReplay(replayId,
function(xml) {
that.processXml(xml, false);
that.processXml(xml, true);
});
},
@@ -503,7 +503,7 @@ var GempLotrGameUI = Class.extend({
processXml: function(xml, animate) {
log(xml);
var root = xml.documentElement;
if (root.tagName == 'gameState' || root.tagName == 'update')
if (root.tagName == 'gameState' || root.tagName == 'update' || root.tagName == 'gameReplay')
this.processGameEventsXml(root, animate);
},
@@ -720,13 +720,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: {
@@ -758,13 +758,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");
},
@@ -1013,8 +1013,8 @@ var GempLotrGameUI = Class.extend({
$(div).find('LI.hover').removeClass('hover');
$(this).parent().addClass('hover');
}).mouseout(function() {
$(div).find('LI.hover').removeClass('hover');
});
$(div).find('LI.hover').removeClass('hover');
});
var getRidOfContextMenu = function() {
$(div).remove();