summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoffrey Bion <joffrey.bion@booking.com>2020-07-01 22:52:12 +0200
committerJoffrey Bion <joffrey.bion@booking.com>2020-07-01 23:00:36 +0200
commit420a4c922101668578792c76493be2cb9eea19f3 (patch)
treedf6a204c4bbd809a43b7f571fb223bed5a825583
parentUse font from CDN instead of relying on "fantasy" (diff)
downloadseven-wonders-420a4c922101668578792c76493be2cb9eea19f3.tar.gz
seven-wonders-420a4c922101668578792c76493be2cb9eea19f3.tar.bz2
seven-wonders-420a4c922101668578792c76493be2cb9eea19f3.zip
Add setup sidebar to choose wonder sides
Resolves: https://github.com/joffrey-bion/seven-wonders/issues/35
-rw-r--r--sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Lobby.kt4
-rw-r--r--sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/wonders/Wonders.kt8
-rw-r--r--sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/lobby/Lobby.kt96
3 files changed, 85 insertions, 23 deletions
diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Lobby.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Lobby.kt
index 1438600a..324482bb 100644
--- a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Lobby.kt
+++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Lobby.kt
@@ -20,6 +20,10 @@ data class LobbyDTO(
val hasEnoughPlayers: Boolean,
val maxPlayersReached: Boolean
) {
+ private val wondersByName = allWonders.associateBy { it.name }
+
+ fun findWonder(name: String): PreGameWonder = wondersByName[name] ?: error("Unknown wonder '$name'")
+
fun joinability(userDisplayName: String): Actionability = when {
state != State.LOBBY -> Actionability(false, "Cannot join: the game has already started")
maxPlayersReached -> Actionability(false, "Cannot join: the game is full")
diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/wonders/Wonders.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/wonders/Wonders.kt
index 888e1c47..fcecd010 100644
--- a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/wonders/Wonders.kt
+++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/wonders/Wonders.kt
@@ -32,11 +32,9 @@ enum class WonderSide {
fun List<PreGameWonder>.deal(nbPlayers: Int, random: Random = Random): List<AssignedWonder> =
shuffled(random).take(nbPlayers).map { it.withRandomSide(random) }
-fun PreGameWonder.withRandomSide(random: Random = Random): AssignedWonder {
- val side = WonderSide.values().random(random)
- val sideImage = images.getValue(side)
- return AssignedWonder(name, side, sideImage)
-}
+fun PreGameWonder.withRandomSide(random: Random = Random): AssignedWonder = withSide(WonderSide.values().random(random))
+
+fun PreGameWonder.withSide(side: WonderSide): AssignedWonder = AssignedWonder(name, side, images.getValue(side))
@Serializable
data class ApiWonder(
diff --git a/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/lobby/Lobby.kt b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/lobby/Lobby.kt
index 910fd71d..763898b3 100644
--- a/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/lobby/Lobby.kt
+++ b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/lobby/Lobby.kt
@@ -1,15 +1,12 @@
package org.luxons.sevenwonders.ui.components.lobby
-import com.palantir.blueprintjs.Intent
-import com.palantir.blueprintjs.bpButton
-import com.palantir.blueprintjs.bpNonIdealState
+import com.palantir.blueprintjs.*
import kotlinx.css.*
import kotlinx.css.properties.*
-import kotlinx.html.DIV
import org.luxons.sevenwonders.model.api.LobbyDTO
import org.luxons.sevenwonders.model.api.PlayerDTO
-import org.luxons.sevenwonders.model.wonders.AssignedWonder
-import org.luxons.sevenwonders.model.wonders.deal
+import org.luxons.sevenwonders.model.wonders.*
+import org.luxons.sevenwonders.model.wonders.withRandomSide
import org.luxons.sevenwonders.ui.redux.*
import react.RBuilder
import react.RComponent
@@ -18,6 +15,7 @@ import react.RState
import react.dom.*
import styled.css
import styled.styledDiv
+import styled.styledH2
private val BOT_NAMES = listOf("Wall-E", "B-Max", "Sonny", "T-800", "HAL", "GLaDOS")
@@ -52,10 +50,13 @@ class LobbyPresenter(props: LobbyProps) : RComponent<LobbyProps, RState>(props)
h2 { +"${currentGame.name} — Lobby" }
radialPlayerList(currentGame.players, currentPlayer)
actionButtons(currentPlayer, currentGame)
+ if (currentPlayer.isGameOwner) {
+ sideBar(currentGame)
+ }
}
}
- private fun RDOMBuilder<DIV>.actionButtons(currentPlayer: PlayerDTO, currentGame: LobbyDTO) {
+ private fun RBuilder.actionButtons(currentPlayer: PlayerDTO, currentGame: LobbyDTO) {
styledDiv {
css {
position = Position.fixed
@@ -64,10 +65,10 @@ class LobbyPresenter(props: LobbyProps) : RComponent<LobbyProps, RState>(props)
transform { translate((-50).pct) }
}
if (currentPlayer.isGameOwner) {
- startButton(currentGame, currentPlayer)
- addBotButton(currentGame)
- reorderPlayersButton(currentGame)
- randomizeWondersButton(currentGame)
+ bpButtonGroup {
+ startButton(currentGame, currentPlayer)
+ addBotButton(currentGame)
+ }
} else {
leaveButton()
}
@@ -88,10 +89,38 @@ class LobbyPresenter(props: LobbyProps) : RComponent<LobbyProps, RState>(props)
}
}
+ private fun RBuilder.sideBar(currentGame: LobbyDTO) {
+ styledDiv {
+ css {
+ position = Position.fixed
+ top = 2.rem
+ right = 1.rem
+ width = 15.rem
+ }
+ bpCard(Elevation.ONE) {
+ styledH2 {
+ css {
+ margin(top = 0.px)
+ }
+ +"Game setup"
+ }
+ bpDivider()
+ h3 {
+ +"Players"
+ }
+ reorderPlayersButton(currentGame)
+ h3 {
+ +"Wonders"
+ }
+ randomizeWondersButton(currentGame)
+ wonderSideSelectionGroup(currentGame)
+ }
+ }
+ }
+
private fun RBuilder.addBotButton(currentGame: LobbyDTO) {
bpButton(
large = true,
- intent = Intent.NONE,
icon = "plus",
rightIcon = "desktop",
title = if (currentGame.maxPlayersReached) "Max players reached" else "Add a bot to this game",
@@ -109,13 +138,13 @@ class LobbyPresenter(props: LobbyProps) : RComponent<LobbyProps, RState>(props)
private fun RBuilder.reorderPlayersButton(currentGame: LobbyDTO) {
bpButton(
- large = true,
- intent = Intent.NONE,
icon = "random",
rightIcon = "people",
title = "Re-order players randomly",
onClick = { reorderPlayers(currentGame) }
- )
+ ) {
+ +"Reorder players"
+ }
}
private fun reorderPlayers(currentGame: LobbyDTO) {
@@ -124,13 +153,36 @@ class LobbyPresenter(props: LobbyProps) : RComponent<LobbyProps, RState>(props)
private fun RBuilder.randomizeWondersButton(currentGame: LobbyDTO) {
bpButton(
- large = true,
- intent = Intent.NONE,
icon = "random",
title = "Re-assign wonders to players randomly",
onClick = { randomizeWonders(currentGame) }
) {
- +"W"
+ +"Randomize wonders"
+ }
+ }
+
+ private fun RBuilder.wonderSideSelectionGroup(currentGame: LobbyDTO) {
+ h4 {
+ +"Select wonder sides:"
+ }
+ bpButtonGroup {
+ bpButton(
+ icon = "random",
+ title = "Re-roll wonder sides randomly",
+ onClick = { randomizeWonderSides(currentGame) }
+ )
+ bpButton(
+ title = "Choose side A for everyone",
+ onClick = { setWonderSides(currentGame, WonderSide.A) }
+ ) {
+ +"A"
+ }
+ bpButton(
+ title = "Choose side B for everyone",
+ onClick = { setWonderSides(currentGame, WonderSide.B) }
+ ) {
+ +"B"
+ }
}
}
@@ -138,6 +190,14 @@ class LobbyPresenter(props: LobbyProps) : RComponent<LobbyProps, RState>(props)
props.reassignWonders(currentGame.allWonders.deal(currentGame.players.size))
}
+ private fun randomizeWonderSides(currentGame: LobbyDTO) {
+ props.reassignWonders(currentGame.players.map { currentGame.findWonder(it.wonder.name).withRandomSide() })
+ }
+
+ private fun setWonderSides(currentGame: LobbyDTO, side: WonderSide) {
+ props.reassignWonders(currentGame.players.map { currentGame.findWonder(it.wonder.name).withSide(side) })
+ }
+
private fun RBuilder.leaveButton() {
bpButton(
large = true,
bgstack15