diff --git a/app/actors/LobbieActor.scala b/app/actors/LobbieActor.scala index d9f7385..b0f2e1a 100644 --- a/app/actors/LobbieActor.scala +++ b/app/actors/LobbieActor.scala @@ -11,6 +11,7 @@ import java.util import scala.collection.JavaConverters.iterableAsScalaIterableConverter import scala.collection.immutable.HashSet import scala.concurrent.duration._ +import scala.util.Try case class LobbyUser(name: String, actorRef: ActorRef) @@ -43,13 +44,11 @@ class LobbieActor(hostUser: LobbyUser, deciderName: String) extends Actor with L private var lobbyType: LobbyType = Last1() - private var isNecrons: Boolean = false - private var firstPlayerSelectedRaces: Option[SelectedRaces] = None private var secondPlayerSelectedRaces: Option[SelectedRaces] = None - private var thirdPlayerSelectedRaces: Option[SelectedRaces] = None + private val isSolo: Boolean = Try(config.getBoolean(s"deciders.$deciderName.isSolo")).getOrElse(false) private val mapsLobby: Set[DeciderMap] = { val configMaps = config.getList(s"deciders.$deciderName.maps").asScala configMaps.map(e => { @@ -67,7 +66,7 @@ class LobbieActor(hostUser: LobbyUser, deciderName: String) extends Actor with L status.toString(), playerTurn, lobbyType.toString(), - isNecrons, + isSolo, mapsLobby)), this.self) @@ -79,6 +78,16 @@ class LobbieActor(hostUser: LobbyUser, deciderName: String) extends Actor with L // notify watchers logger.info(s"Ban map $mapName by ${sender.path.name}") + if (isSolo) { + mapsLobby.find(p => p.map == mapName).foreach(m => m.isBanned = true) + if (isFinish) { + status = Finish() + } else { + status = Draft() + } + refreshAndBanMap(mapName) + } + if (status == Draft()) { if ((playerTurn == 1 && sender == host.actorRef) || (playerTurn == 2 && secondPlayer.exists(_.actorRef == sender))) { @@ -87,19 +96,10 @@ class LobbieActor(hostUser: LobbyUser, deciderName: String) extends Actor with L if (!map.isBanned) { map.isBanned = true if (playerTurn == 1) playerTurn = 2 else playerTurn = 1 - if (mapsLobby.count(_.isBanned == false) == 1 && lobbyType == Last1() || - mapsLobby.count(_.isBanned == false) == 3 && lobbyType == Last3() || - mapsLobby.count(_.isBanned == false) == 5 && lobbyType == Last5() || - mapsLobby.count(_.isBanned == false) == 7 && lobbyType == Last7() - ) { + if (isFinish) { status = Finish() } - users.foreach(_ ! RefreshLobbyInfo(getLobbyInfoResponse)) - - val senderName: String = if (sender == host.actorRef) { - host.name - } else secondPlayer.get.name - users.foreach(_ ! SendBanMapMessage(BanMapMessage(senderName, mapName))) + refreshAndBanMap(mapName) } else { logger.warn(s"User ban map $mapName, but map already banned") } @@ -227,9 +227,25 @@ class LobbieActor(hostUser: LobbyUser, deciderName: String) extends Actor with L status.toString(), playerTurn, lobbyType.toString(), - isNecrons, + isSolo, mapsLobby) } + + private def isFinish: Boolean = { + mapsLobby.count(_.isBanned == false) == 1 && lobbyType == Last1() || + mapsLobby.count(_.isBanned == false) == 3 && lobbyType == Last3() || + mapsLobby.count(_.isBanned == false) == 5 && lobbyType == Last5() || + mapsLobby.count(_.isBanned == false) == 7 && lobbyType == Last7() + } + + private def refreshAndBanMap(mapName: String): Unit = { + val senderName: String = if (sender == host.actorRef) { + host.name + } else secondPlayer.get.name + users.foreach(_ ! SendBanMapMessage(BanMapMessage(senderName, mapName))) + users.foreach(_ ! RefreshLobbyInfo(getLobbyInfoResponse)) + } + } case class BanMap(mapName: String) @@ -269,7 +285,7 @@ case class LobbyInfo(user1Info: UserInfo, status: String, playerTurn: BigDecimal, selectedType: String, - isNecrons: Boolean, + isSolo: Boolean, maps: Set[DeciderMap]) class LobbyStatus diff --git a/app/assets/images/maps/2p_marsh_of_rakat.jpg b/app/assets/images/maps/2p_marsh_of_rakat.jpg new file mode 100644 index 0000000..b506935 Binary files /dev/null and b/app/assets/images/maps/2p_marsh_of_rakat.jpg differ diff --git a/app/assets/images/maps/6p_platform.jpg b/app/assets/images/maps/6p_platform.jpg new file mode 100644 index 0000000..2dde421 Binary files /dev/null and b/app/assets/images/maps/6p_platform.jpg differ diff --git a/app/assets/images/maps/img_6.png b/app/assets/images/maps/img_6.png new file mode 100644 index 0000000..6ccaf57 Binary files /dev/null and b/app/assets/images/maps/img_6.png differ diff --git a/app/assets/images/maps/винегрет.jpg b/app/assets/images/maps/винегрет.jpg new file mode 100644 index 0000000..6f38747 Binary files /dev/null and b/app/assets/images/maps/винегрет.jpg differ diff --git a/app/assets/images/maps/гнездо глухаря.jpg b/app/assets/images/maps/гнездо глухаря.jpg new file mode 100644 index 0000000..bb11213 Binary files /dev/null and b/app/assets/images/maps/гнездо глухаря.jpg differ diff --git a/app/assets/images/maps/грибная поляна.jpg b/app/assets/images/maps/грибная поляна.jpg new file mode 100644 index 0000000..cb522f1 Binary files /dev/null and b/app/assets/images/maps/грибная поляна.jpg differ diff --git a/app/assets/images/maps/из пекинской капусты.jpg b/app/assets/images/maps/из пекинской капусты.jpg new file mode 100644 index 0000000..e8e4960 Binary files /dev/null and b/app/assets/images/maps/из пекинской капусты.jpg differ diff --git a/app/assets/images/maps/крабовый.jpg b/app/assets/images/maps/крабовый.jpg new file mode 100644 index 0000000..505b14b Binary files /dev/null and b/app/assets/images/maps/крабовый.jpg differ diff --git a/app/assets/images/maps/летний.jpg b/app/assets/images/maps/летний.jpg new file mode 100644 index 0000000..623eefe Binary files /dev/null and b/app/assets/images/maps/летний.jpg differ diff --git a/app/assets/images/maps/мимоза.jpg b/app/assets/images/maps/мимоза.jpg new file mode 100644 index 0000000..3564014 Binary files /dev/null and b/app/assets/images/maps/мимоза.jpg differ diff --git a/app/assets/images/maps/оливье.jpg b/app/assets/images/maps/оливье.jpg new file mode 100644 index 0000000..dd5c46c Binary files /dev/null and b/app/assets/images/maps/оливье.jpg differ diff --git a/app/assets/images/maps/орлиное гнездо.jpg b/app/assets/images/maps/орлиное гнездо.jpg new file mode 100644 index 0000000..6c5c186 Binary files /dev/null and b/app/assets/images/maps/орлиное гнездо.jpg differ diff --git a/app/assets/images/maps/селедка под шубой.jpg b/app/assets/images/maps/селедка под шубой.jpg new file mode 100644 index 0000000..cd8bd8d Binary files /dev/null and b/app/assets/images/maps/селедка под шубой.jpg differ diff --git a/app/assets/images/maps/цезарь.jpg b/app/assets/images/maps/цезарь.jpg new file mode 100644 index 0000000..6aacd34 Binary files /dev/null and b/app/assets/images/maps/цезарь.jpg differ diff --git a/app/assets/javascripts/index.js b/app/assets/javascripts/index.js index 9f5053f..3a97e1f 100644 --- a/app/assets/javascripts/index.js +++ b/app/assets/javascripts/index.js @@ -3,6 +3,11 @@ var ws; var userName = "" var raceCount = $("#raceCount").html() +var isSolo = $("#isSolo").html() === 'true' + +var isMuted = false; +var isDraftStarted = false; + window.onload = function() { @@ -96,6 +101,15 @@ window.onload = function() { } }); + $("#mute").click(function(event) { + if(isMuted){ + isMuted = false; + $("#mute").html("🔊"); + }else{ + isMuted = true; + $("#mute").html("🔈"); + } + }); $("#exit").click(function(event) { event.preventDefault(); @@ -123,7 +137,6 @@ window.onload = function() { $("#playerName").html(userName); - ws = new WebSocket($("body").data("ws-url")); ws.onmessage = function(event) { var message; @@ -131,6 +144,7 @@ window.onload = function() { switch (message.type) { case "refreshLobby": if(message.lobby.status === "SelectRace()" && (!isObserver)){ + isDraftStarted = false; renderRaces(); }else { renderMaps(message.lobby.maps, message.lobby.status); @@ -140,7 +154,7 @@ window.onload = function() { case "switchToLobby": console.log(message); switchToLobby(message.lobby.maps, message.lobby.status); - renderPlayersAndStats(message.lobby); + if(!isSolo) renderPlayersAndStats(message.lobby); break; case "sendMessage": console.log(message); @@ -148,7 +162,7 @@ window.onload = function() { break; case "sendMapBanMessage": console.log(message); - addBanMapMessageToChat(message.message); + handleMapBanEvent(message.message); break; case "lobbyError": console.log(message); @@ -295,7 +309,7 @@ function renderRaces() { banned = "bannedRace"; selectedFourthRace = i; } - resHtml += ' '; + resHtml += ' '; } resHtml += ""; } @@ -392,7 +406,7 @@ function renderMaps(maps, lobbyStatus) { banHtml = "
"; banClass = "bannedMap"; } - if(lobbyStatus === "NotStarted()"){ + if(lobbyStatus === "NotStarted()" && !isSolo){ banClass = "bannedMap"; } @@ -427,28 +441,30 @@ function renderFinish(maps, firstPlayerInfo, secondPlayerInfo) { resHtml += "
"; - resHtml += "

" + firstPlayerInfo.name + "

"; - resHtml += " "; - if(raceCount >= 2){ - resHtml += " "; - } - if(raceCount >= 3){ - resHtml += " "; - } - if(raceCount >= 4){ - resHtml += " "; - } + if(!isSolo){ + resHtml += "

" + firstPlayerInfo.name + "

"; + resHtml += " "; + if(raceCount >= 2){ + resHtml += " "; + } + if(raceCount >= 3){ + resHtml += " "; + } + if(raceCount >= 4){ + resHtml += " "; + } - resHtml += "

" + secondPlayerInfo.name + "

"; - resHtml += " "; - if(raceCount >= 2){ - resHtml += " "; - } - if(raceCount >= 3){ - resHtml += " "; - } - if(raceCount >= 4){ - resHtml += " "; + resHtml += "

" + secondPlayerInfo.name + "

"; + resHtml += " "; + if(raceCount >= 2){ + resHtml += " "; + } + if(raceCount >= 3){ + resHtml += " "; + } + if(raceCount >= 4){ + resHtml += " "; + } } resHtml += "" @@ -566,32 +582,39 @@ function renderPlayersAndStats(lobby) { resHtml += "
"; break; case "SelectRace()": + resHtml = "
"+lobby.user1Info.name + " vs " + lobby.user2Info.name + " - " +lobbyTypeText+ "
players select races
"; break; case "Draft()": - console.log(lobby.turn); - var playerTurn = (lobby.playerTurn === 1) ? lobby.user1Info.name : lobby.user2Info.name - resHtml = "
"+lobby.user1Info.name + " vs " + lobby.user2Info.name + " - " +lobbyTypeText+ "
" + playerTurn +" turn
"; - resHtml += "
"; - if(raceCount > 1){ - resHtml += " "; + if(!isDraftStarted){ + isDraftStarted = true; } - if(raceCount > 2){ - resHtml += " "; - } - if(raceCount > 3){ - resHtml += " "; - } - resHtml += " VS "; - resHtml += ""; - if(raceCount > 1){ - resHtml += " "; - } - if(raceCount > 2){ - resHtml += " "; - } - if(raceCount > 3){ - resHtml += " "; + + if(!isSolo){ + var playerTurn = (lobby.playerTurn === 1) ? lobby.user1Info.name : lobby.user2Info.name + resHtml = "
"+lobby.user1Info.name + " vs " + lobby.user2Info.name + " - " +lobbyTypeText+ "
" + playerTurn +" turn
"; + resHtml += "
"; + if(raceCount > 1){ + resHtml += " "; + } + if(raceCount > 2){ + resHtml += " "; + } + if(raceCount > 3){ + resHtml += " "; + } + resHtml += " VS "; + resHtml += ""; + if(raceCount > 1){ + resHtml += " "; + } + if(raceCount > 2){ + resHtml += " "; + } + if(raceCount > 3){ + resHtml += " "; + } + } break; case "Finish()": @@ -611,7 +634,13 @@ function addMessageToChat(message){ chatBox.scrollTop(40000); } -function addBanMapMessageToChat(message){ +function handleMapBanEvent(message){ + if(!isMuted){ + var audioPick = new Audio('/assets/sound/pick.mp3.mpeg'); + audioPick.volume = 0.1; + audioPick.play(); + } + var messageHtml = "
" + convertMapName(message.mapTechName) + " banned by " + message.user + "
"; var chatBox = $("#chatbox"); chatBox.append(messageHtml); @@ -688,6 +717,10 @@ function kickSecondPlayer(){ } function convertMapName (techMapName) { - var mapName = techMapName.replace("2p_", "").replaceAll("_", " ") + " (2)"; + var mapPlayerSize = techMapName.charAt(0); + var mapName = techMapName.replace(mapPlayerSize + "p_", "").replaceAll("_", " ") + + " ("+mapPlayerSize+")"; + + return mapName.charAt(0).toUpperCase() + mapName.slice(1); } diff --git a/app/assets/sound/blip.mp3 b/app/assets/sound/blip.mp3 new file mode 100644 index 0000000..26c5e1a Binary files /dev/null and b/app/assets/sound/blip.mp3 differ diff --git a/app/assets/sound/pick.mp3.mpeg b/app/assets/sound/pick.mp3.mpeg new file mode 100644 index 0000000..b49f55a Binary files /dev/null and b/app/assets/sound/pick.mp3.mpeg differ diff --git a/app/assets/sound/started.mp3 b/app/assets/sound/started.mp3 new file mode 100644 index 0000000..b8dff59 Binary files /dev/null and b/app/assets/sound/started.mp3 differ diff --git a/app/controllers/HomeController.scala b/app/controllers/HomeController.scala index 300c67f..14ee5d0 100644 --- a/app/controllers/HomeController.scala +++ b/app/controllers/HomeController.scala @@ -43,10 +43,11 @@ class HomeController @Inject()(cc: ControllerComponents) extends AbstractControl logger.info(s"Received request from: ${request.remoteAddress}") val deciderHumanName = config.getString(s"deciders.$deciderName.name") val deciderDescription = config.getString(s"deciders.$deciderName.rules") + val isSolo = Try(config.getBoolean(s"deciders.$deciderName.isSolo")).getOrElse(false) val raceCount = Try(config.getInt(s"deciders.$deciderName.raceCount")).getOrElse(1) val lastmapsSettings = LastMapsSelectConfig(true, true, true, true) val raceSelect = RaceSelect(true, false) - Ok(views.html.index(deciderName, deciderHumanName, raceCount, deciderDescription, raceSelect, lastmapsSettings)) + Ok(views.html.index(deciderName, deciderHumanName, raceCount, deciderDescription, raceSelect, lastmapsSettings, isSolo)) } /** diff --git a/app/views/index.scala.html b/app/views/index.scala.html index 2e357a1..aa4575b 100644 --- a/app/views/index.scala.html +++ b/app/views/index.scala.html @@ -1,4 +1,4 @@ -@(deciderName: String, deciderHumanName: String, raceCount: Int, rules: String, raceSelect: RaceSelect, boSettings: LastMapsSelectConfig)(implicit r: Request[_]) +@(deciderName: String, deciderHumanName: String, raceCount: Int, rules: String, raceSelect: RaceSelect, boSettings: LastMapsSelectConfig, isSolo: Boolean)(implicit r: Request[_]) @@ -7,6 +7,7 @@ + @@ -20,7 +21,7 @@ - +