diff --git a/knockoutwhistweb/app/model/sessions/UserSession.scala b/knockoutwhistweb/app/model/sessions/UserSession.scala index 0f40c69..7067850 100644 --- a/knockoutwhistweb/app/model/sessions/UserSession.scala +++ b/knockoutwhistweb/app/model/sessions/UserSession.scala @@ -28,7 +28,7 @@ class UserSession(val user: User, val host: Boolean, val gameLobby: GameLobby) e else canInteract = Some(InteractionType.Card) case _ => } - websocketActor.foreach(_.transmitEventToClient(event, gameLobby)) + websocketActor.foreach(_.transmitEventToClient(event, gameLobby, user)) } override def id: UUID = user.id @@ -41,7 +41,7 @@ class UserSession(val user: User, val host: Boolean, val gameLobby: GameLobby) e def handleWebResponse(eventType: String, data: JsObject, user: User, gameLobby: GameLobby): Unit = { lock.lock() - Try { + val result = Try { eventType match { case "Ping" => // No action needed for Ping @@ -49,9 +49,32 @@ class UserSession(val user: User, val host: Boolean, val gameLobby: GameLobby) e case "Start Game" => println("INSIDE HANDLE WEB RESPONSE" + data) gameLobby.startGame(user) + case "play Card" => + println("PLAYING CARD..." + data) + val maybeCardIndex: Option[Int] = (data \ "cardindex").asOpt[Int] + maybeCardIndex match { + case Some(index) => + val session = gameLobby.getUserSession(user.id) + gameLobby.playCard(session, index) + case None => + println("Card Index not found or is not a number.") + } + case "Picked Trumpsuit" => + val maybeSuitIndex: Option[Int] = (data \ "suitIndex").asOpt[Int] + maybeSuitIndex match { + case Some(index) => + val session = gameLobby.getUserSession(user.id) + gameLobby.selectTrump(session, index) + case None => + println("Card Index not found or is not a number.") + } } } lock.unlock() + if (result.isFailure) { + val throwable = result.failed.get + throw throwable + } } } diff --git a/knockoutwhistweb/app/model/sessions/UserWebsocketActor.scala b/knockoutwhistweb/app/model/sessions/UserWebsocketActor.scala index 6c612d6..ffb7c0a 100644 --- a/knockoutwhistweb/app/model/sessions/UserWebsocketActor.scala +++ b/knockoutwhistweb/app/model/sessions/UserWebsocketActor.scala @@ -1,6 +1,9 @@ package model.sessions import de.knockoutwhist.utils.events.SimpleEvent +import logic.PodManager +import logic.game.GameLobby +import model.users.User import org.apache.pekko.actor.{Actor, ActorRef} import play.api.libs.json.{JsObject, JsValue, Json} import util.WebsocketEventMapper @@ -96,7 +99,8 @@ class UserWebsocketActor( transmitTextToClient(jsonObj.toString()) } - def transmitEventToClient(event: SimpleEvent): Unit = { + def transmitEventToClient(event: SimpleEvent, gameLobby: GameLobby, user: User): Unit = { + val session = gameLobby.getUserSession(user.id) transmitJsonToClient(WebsocketEventMapper.toJson(event, session)) } diff --git a/knockoutwhistweb/app/util/WebsocketEventMapper.scala b/knockoutwhistweb/app/util/WebsocketEventMapper.scala index 518b5d8..cb8bb6f 100644 --- a/knockoutwhistweb/app/util/WebsocketEventMapper.scala +++ b/knockoutwhistweb/app/util/WebsocketEventMapper.scala @@ -7,6 +7,7 @@ import play.api.libs.json.{JsValue, Json} import tools.jackson.databind.json.JsonMapper import tools.jackson.module.scala.ScalaModule import util.mapper.{CardPlayedEventMapper, GameStateEventMapper, KickEventMapper, LeftEventMapper, LobbyUpdateEventMapper, ReceivedHandEventMapper, SessionClosedMapper, SimpleEventMapper, TurnEventMapper} +import util.mapper.{GameStateEventMapper, NewRoundEventMapper, NewTrickEventMapper, ReceivedHandEventMapper, RequestCardEventMapper, SimpleEventMapper, TrickEndEventMapper, CardPlayedEventMapper} object WebsocketEventMapper { diff --git a/knockoutwhistweb/app/util/mapper/NewRoundEventMapper.scala b/knockoutwhistweb/app/util/mapper/NewRoundEventMapper.scala index b7be5ea..2e63029 100644 --- a/knockoutwhistweb/app/util/mapper/NewRoundEventMapper.scala +++ b/knockoutwhistweb/app/util/mapper/NewRoundEventMapper.scala @@ -2,12 +2,14 @@ package util.mapper import de.knockoutwhist.events.global.NewRoundEvent import logic.game.GameLobby +import model.sessions.UserSession import play.api.libs.json.{JsObject, Json} object NewRoundEventMapper extends SimpleEventMapper[NewRoundEvent]{ override def id: String = "NewRoundEvent" - override def toJson(event: NewRoundEvent, gameLobby: GameLobby): JsObject = { + override def toJson(event: NewRoundEvent, session: UserSession): JsObject = { + val gameLobby = session.gameLobby Json.obj( "trumpsuit" -> gameLobby.getLogic.getCurrentRound.get.trumpSuit.toString, "players" -> gameLobby.getLogic.getCurrentMatch.get.playersIn.map(player => player.toString) diff --git a/knockoutwhistweb/app/util/mapper/NewTrickEventMapper.scala b/knockoutwhistweb/app/util/mapper/NewTrickEventMapper.scala index 863c75d..4861ae3 100644 --- a/knockoutwhistweb/app/util/mapper/NewTrickEventMapper.scala +++ b/knockoutwhistweb/app/util/mapper/NewTrickEventMapper.scala @@ -2,12 +2,13 @@ package util.mapper import de.knockoutwhist.events.global.NewTrickEvent import logic.game.GameLobby +import model.sessions.UserSession import play.api.libs.json.{JsObject, Json} object NewTrickEventMapper extends SimpleEventMapper[NewTrickEvent]{ override def id: String = "NewTrickEvent" - override def toJson(event: NewTrickEvent, gameLobby: GameLobby): JsObject = { + override def toJson(event: NewTrickEvent, session: UserSession): JsObject = { Json.obj() } } diff --git a/knockoutwhistweb/app/util/mapper/RequestCardEventMapper.scala b/knockoutwhistweb/app/util/mapper/RequestCardEventMapper.scala index 8b193cf..217f859 100644 --- a/knockoutwhistweb/app/util/mapper/RequestCardEventMapper.scala +++ b/knockoutwhistweb/app/util/mapper/RequestCardEventMapper.scala @@ -2,12 +2,13 @@ package util.mapper import de.knockoutwhist.events.player.RequestCardEvent import logic.game.GameLobby +import model.sessions.UserSession import play.api.libs.json.{JsObject, Json} object RequestCardEventMapper extends SimpleEventMapper[RequestCardEvent]{ override def id: String = "RequestCardEvent" - override def toJson(event: RequestCardEvent, gameLobby: GameLobby): JsObject = { + override def toJson(event: RequestCardEvent, session: UserSession): JsObject = { Json.obj( "player" -> event.player.name ) diff --git a/knockoutwhistweb/app/util/mapper/TrickEndEventMapper.scala b/knockoutwhistweb/app/util/mapper/TrickEndEventMapper.scala index 9e6e1f7..a133f9b 100644 --- a/knockoutwhistweb/app/util/mapper/TrickEndEventMapper.scala +++ b/knockoutwhistweb/app/util/mapper/TrickEndEventMapper.scala @@ -3,12 +3,14 @@ package util.mapper import de.knockoutwhist.events.global.TrickEndEvent import de.knockoutwhist.rounds.Trick import logic.game.GameLobby +import model.sessions.UserSession import play.api.libs.json.{JsObject, Json} object TrickEndEventMapper extends SimpleEventMapper[TrickEndEvent]{ override def id: String = "TrickEndEvent" - override def toJson(event: TrickEndEvent, gameLobby: GameLobby): JsObject = { + override def toJson(event: TrickEndEvent, session: UserSession): JsObject = { + val gameLobby = session.gameLobby Json.obj( "playerwon" -> event.winner.name, "playersin" -> gameLobby.getLogic.getCurrentMatch.get.playersIn.map(player => player.name), diff --git a/knockoutwhistweb/app/views/ingame/ingame.scala.html b/knockoutwhistweb/app/views/ingame/ingame.scala.html index e4f1382..8d437e7 100644 --- a/knockoutwhistweb/app/views/ingame/ingame.scala.html +++ b/knockoutwhistweb/app/views/ingame/ingame.scala.html @@ -107,7 +107,7 @@ } else { @for(i <- player.currentHand().get.cards.indices) {
-
+
@util.WebUIUtils.cardtoImage(player.currentHand().get.cards(i)) width="120px" style="border-radius: 6px"/>
@if(player.isInDogLife) { diff --git a/knockoutwhistweb/app/views/ingame/selecttrump.scala.html b/knockoutwhistweb/app/views/ingame/selecttrump.scala.html index 8700adc..92ff345 100644 --- a/knockoutwhistweb/app/views/ingame/selecttrump.scala.html +++ b/knockoutwhistweb/app/views/ingame/selecttrump.scala.html @@ -18,25 +18,25 @@
-
+
@util.WebUIUtils.cardtoImage(de.knockoutwhist.cards.Card(de.knockoutwhist.cards.CardValue.Ace, de.knockoutwhist.cards.Suit.Spades)) width="120px" style="border-radius: 6px"/>
-
+
@util.WebUIUtils.cardtoImage(de.knockoutwhist.cards.Card(de.knockoutwhist.cards.CardValue.Ace, de.knockoutwhist.cards.Suit.Hearts)) width="120px" style="border-radius: 6px"/>
-
+
@util.WebUIUtils.cardtoImage(de.knockoutwhist.cards.Card(de.knockoutwhist.cards.CardValue.Ace, de.knockoutwhist.cards.Suit.Diamonds)) width="120px" style="border-radius: 6px"/>
-
+
@util.WebUIUtils.cardtoImage(de.knockoutwhist.cards.Card(de.knockoutwhist.cards.CardValue.Ace, de.knockoutwhist.cards.Suit.Clubs)) width="120px" style="border-radius: 6px"/>
diff --git a/knockoutwhistweb/public/javascripts/events.js b/knockoutwhistweb/public/javascripts/events.js index bff1444..803bd38 100644 --- a/knockoutwhistweb/public/javascripts/events.js +++ b/knockoutwhistweb/public/javascripts/events.js @@ -133,9 +133,9 @@ function trickEndEvent(eventData) { playerorder.forEach( player => { newHtml += `
-
'${player}'
+
${player}
- '${playercounts.get(player)}' + ${playercounts.get(player)}
` @@ -143,14 +143,12 @@ function trickEndEvent(eventData) { tricktable.html(newHtml); } function newTrickEvent() { - const firstCardContainer = $('first-card-container'); + const firstCardContainer = $('#first-card-container'); let newHtml = ''; - newHtml += ` - Blank Card + Blank Card `; - firstCardContainer.html(newHtml); } function requestCardEvent(eventData) { @@ -158,7 +156,6 @@ function requestCardEvent(eventData) { const handElement = $('#card-slide') handElement.removeClass('inactive'); } -//alertMessage("It worked!") function receiveGameStateChange(eventData) { @@ -207,37 +204,6 @@ function receiveCardPlayedEvent(eventData) { `; firstCardContainer.html(newFirstCardHTML); } -function receiveTurnEvent(eventData) { - const currentPlayer = eventData.currentPlayer; - const nextPlayers = eventData.nextPlayers; - - const currentPlayerNameContainer = $('#current-player-name'); - const nextPlayersContainer = $('#next-players-container'); - const nextPlayerText = $('#next-players-section'); - - let currentPlayerName = currentPlayer.name; - if (currentPlayer.dog) { - currentPlayerName += " 🐶"; - } - currentPlayerNameContainer.text(currentPlayerName); - - if (nextPlayers.length === 0) { - nextPlayerText.hide(); - nextPlayersContainer.html(''); - } else { - nextPlayerText.show(); - let nextPlayersHtml = ''; - nextPlayers.forEach((player) => { - let playerName = player.name; - if (player.dog) { - playerName += " 🐶"; - } - nextPlayersHtml += `

${playerName}

`; - }); - nextPlayersContainer.html(nextPlayersHtml); - } -} - function receiveLobbyUpdateEvent(eventData) { const host = eventData.host; const maxPlayers = eventData.maxPlayers; @@ -349,4 +315,6 @@ onEvent("LobbyUpdateEvent", receiveLobbyUpdateEvent) onEvent("LeftEvent", receiveGameStateChange) onEvent("KickEvent", receiveKickEvent) onEvent("SessionClosed", receiveSessionClosedEvent) -onEvent("TurnEvent", receiveTurnEvent) \ No newline at end of file +onEvent("TurnEvent", receiveTurnEvent) + +globalThis.alertMessage = alertMessage \ No newline at end of file diff --git a/knockoutwhistweb/public/javascripts/interact.js b/knockoutwhistweb/public/javascripts/interact.js index ae476ea..af04ab5 100644 --- a/knockoutwhistweb/public/javascripts/interact.js +++ b/knockoutwhistweb/public/javascripts/interact.js @@ -1,5 +1,40 @@ -function handlePlayCard(card, dog) { - // TODO needs implementation +function handlePlayCard(cardIndex, dog) { + const cardslide = $('#card-slide') + cardslide.addClass("inactive") + + const payload = { + cardindex: cardIndex, + isDog: dog + } + sendEventAndWait("play Card", payload).then( + () => { + console.debug("play card successful") + const datacardid = $(`#${cardIndex}`) + datacardid.parent('.handcard').remove(); + cardslide.find('.handcard').each(function(newIndex) { + + const $innerButton = $(this).find('.btn'); + + $innerButton.attr('id', newIndex); + $innerButton.attr('data-card-id', newIndex); + + const isInDogLife = $innerButton.attr('onclick').includes("'true'") ? 'true' : 'false'; + $innerButton.attr('onclick', `handlePlayCard(${newIndex}, '${isInDogLife}')`); + + console.debug(`Re-indexed card: Old index was ${$innerButton.attr('data-card-id')}, New index is ${newIndex}`); + }); + } + ).catch( + (err) => { + const cardslide = $('#card-slide') + console.log("EERROOOORRR PLAYING CARD" + (err.toString() === "You can't play this card!") + err.message) + console.warn("play card was not successful") + if (err.message === "You can't play this card!") { + cardslide.removeClass("inactive") + } + alertMessage("You aren't allowed to play this card") + } + ) } function handleSkipDogLife(button) { @@ -8,6 +43,17 @@ function handleSkipDogLife(button) { function startGame() { sendEvent("Start Game") } + +function handleTrumpSelection(object) { + const $button = $(object); + const trumpIndex = parseInt($button.data('trump')); + const payload = { + suitIndex: trumpIndex + } + console.log("SENDING TRUMP SUIT SELECTION:", payload); + sendEvent("Picked Trumpsuit", payload) + +} function handleKickPlayer(playerId) { // TODO needs implementation } diff --git a/knockoutwhistweb/public/javascripts/websocket.js b/knockoutwhistweb/public/javascripts/websocket.js index fcd1c92..9008c6b 100644 --- a/knockoutwhistweb/public/javascripts/websocket.js +++ b/knockoutwhistweb/public/javascripts/websocket.js @@ -31,7 +31,7 @@ function setupSocketHandlers(socket) { if (status === "success") { entry.resolve(data === undefined ? {} : data); } else { - entry.reject(new Error(msg.error || "Server returned error")); + entry.reject(new Error(msg.error || "Server returned error")); } return; }