diff --git a/app/actors/LobbieActor.scala b/app/actors/LobbieActor.scala index 2ea8240..55805cb 100644 --- a/app/actors/LobbieActor.scala +++ b/app/actors/LobbieActor.scala @@ -1,20 +1,20 @@ package actors -import actors.UserActor.{BanMapMessage, GetName, HostLeaveLobby, LobbyFatal, Message, RefreshLobbyInfo, SecondPlayerLeaveLobby, SendBanMapMessage, SendMessage, SetUserAsHost, SetUserAsObs, SetUserAsSecondPlayer} -import akka.actor.{Actor, ActorLogging, ActorRef} +import actors.UserActor._ +import akka.actor.{Actor, ActorRef} import akka.event.LoggingReceive -import com.typesafe.scalalogging.LazyLogging -import akka.pattern.ask import akka.util.Timeout -import com.typesafe.config.{Config, ConfigFactory} +import com.typesafe.config.ConfigFactory +import com.typesafe.scalalogging.LazyLogging +import java.util import scala.collection.JavaConverters.iterableAsScalaIterableConverter -import scala.collection.immutable.{HashSet, Queue} -import scala.concurrent.Await +import scala.collection.immutable.HashSet import scala.concurrent.duration._ case class LobbyUser(name: String, actorRef: ActorRef) -case class DeciderMap(map: String, var isBanned: Boolean = false) + +case class DeciderMap(map: String, description: Option[String] = None, var isBanned: Boolean = false) /** * There is one StockActor per stock symbol. The StockActor maintains a list of users watching the stock and the stock @@ -41,20 +41,26 @@ class LobbieActor(hostUser: LobbyUser, deciderName: String) extends Actor with L private var status: LobbyStatus = NotStarted() - private var lobbyType: LobbyType = Last3() + 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 mapsLobby: Set[DeciderMap] = { - val configMaps = config.getStringList(s"deciders.$deciderName.maps").asScala + val configMaps = config.getList(s"deciders.$deciderName.maps").asScala configMaps.map(e => { - DeciderMap(e) + val mapConfig = e.unwrapped().asInstanceOf[util.ArrayList[String]].asScala + DeciderMap(mapConfig.head, mapConfig.tail.headOption) }).toSet } hostUser.actorRef.tell( SetUserAsHost(LobbyInfo( - UserInfo(hostUser.name,firstPlayerReady), + UserInfo(hostUser.name, firstPlayerReady), UserInfo("", secondPlayerReady), self.path.name, deciderName, @@ -73,23 +79,24 @@ class LobbieActor(hostUser: LobbyUser, deciderName: String) extends Actor with L // notify watchers logger.info(s"Ban map $mapName by ${sender.path.name}") - if(status == Draft()){ - if((playerTurn == 1 && sender == host.actorRef) || - (playerTurn == 2 && secondPlayer.exists(_.actorRef == sender))){ + if (status == Draft()) { + if ((playerTurn == 1 && sender == host.actorRef) || + (playerTurn == 2 && secondPlayer.exists(_.actorRef == sender))) { mapsLobby.find(p => p.map == mapName) match { case Some(map) => - if(!map.isBanned){ + if (!map.isBanned) { map.isBanned = true - if (playerTurn== 1) playerTurn = 2 else playerTurn = 1 - if(mapsLobby.count(_.isBanned == false) == 3 && lobbyType == Last3() || + 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) == 9 && lobbyType == Superfinal() || - mapsLobby.count(_.isBanned == false) == 1 && lobbyType == LooserPick()){ + mapsLobby.count(_.isBanned == false) == 7 && lobbyType == Last7() + ) { status = Finish() } users.foreach(_ ! RefreshLobbyInfo(getLobbyInfoResponse)) - val senderName: String = if (sender == host.actorRef) { + val senderName: String = if (sender == host.actorRef) { host.name } else secondPlayer.get.name users.foreach(_ ! SendBanMapMessage(BanMapMessage(senderName, mapName))) @@ -99,23 +106,35 @@ class LobbieActor(hostUser: LobbyUser, deciderName: String) extends Actor with L case None => logger.error(s"Map $mapName not exist") } - } else{ + } else { logger.warn(s"Player ${sender.path.name} ban map, but turn is $playerTurn") } } else { logger.warn(s"Player ${sender.path.name} ban map, but lobby status is '$status' status") } + case selectedRaces: SelectedRaces => + if (sender == host.actorRef) { + firstPlayerSelectedRaces = Some(selectedRaces) + logger.info(s"First player select $selectedRaces") + } else if (sender == secondPlayer.get.actorRef) { + secondPlayerSelectedRaces = Some(selectedRaces) + logger.info(s"Second player select $selectedRaces") + } + if (firstPlayerSelectedRaces.nonEmpty && secondPlayerSelectedRaces.nonEmpty) { + status = Draft() + users.foreach(_ ! RefreshLobbyInfo(getLobbyInfoResponse)) + } case SetReady => // notify watchers var readyPlayer = sender() - if(readyPlayer == hostUser.actorRef){ + if (readyPlayer == hostUser.actorRef) { firstPlayerReady = true } else if (secondPlayer.exists(sp => sp.actorRef == readyPlayer)) { secondPlayerReady = true } - if(firstPlayerReady && secondPlayerReady){ - status = Draft() + if (firstPlayerReady && secondPlayerReady) { + status = SelectRace() } users.foreach(_ ! RefreshLobbyInfo(getLobbyInfoResponse)) @@ -123,7 +142,7 @@ class LobbieActor(hostUser: LobbyUser, deciderName: String) extends Actor with L case SetNotReady => // notify watchers var notReadyPlayer = sender() - if(notReadyPlayer == hostUser.actorRef){ + if (notReadyPlayer == hostUser.actorRef) { firstPlayerReady = false } else if (secondPlayer.exists(sp => sp.actorRef == notReadyPlayer)) { secondPlayerReady = false @@ -132,22 +151,23 @@ class LobbieActor(hostUser: LobbyUser, deciderName: String) extends Actor with L case ChangeLobbyType(lobbyTypeNew) => lobbyTypeNew match { + case "last1" => + lobbyType = Last1() case "last3" => lobbyType = Last3() case "last5" => lobbyType = Last5() - case "superfinal" => - lobbyType = Superfinal() - case "looserpick" => - lobbyType = LooserPick() + case "last7" => + lobbyType = Last7() + } users.foreach(_ ! RefreshLobbyInfo(getLobbyInfoResponse)) case ChangeIsNecronSelected(isSelected) => isNecrons = isSelected - if(isSelected) { - mapsLobby.foreach(map => if(map.map == "2p_meeting_of_minds" || map.map == "2p_shrine_of_excellion_[Rem]") map.isBanned = true) - }else{ + if (isSelected) { + mapsLobby.foreach(map => if (map.map == "2p_meeting_of_minds" || map.map == "2p_shrine_of_excellion_[Rem]") map.isBanned = true) + } else { mapsLobby.foreach(map => map.isBanned = false) } users.foreach(_ ! RefreshLobbyInfo(getLobbyInfoResponse)) @@ -163,7 +183,7 @@ class LobbieActor(hostUser: LobbyUser, deciderName: String) extends Actor with L case MessageForLobby(message) => if (sender() == host.actorRef) { users.foreach(_ ! SendMessage(Message(host.name, message))) - }else if (secondPlayer.exists(sp => sp.actorRef == sender())){ + } else if (secondPlayer.exists(sp => sp.actorRef == sender())) { users.foreach(_ ! SendMessage(Message(secondPlayer.get.name, message))) } case JoinLobbyAsPlayer(sp) => @@ -184,16 +204,16 @@ class LobbieActor(hostUser: LobbyUser, deciderName: String) extends Actor with L sender ! SetUserAsObs(getLobbyInfoResponse) case LeaveLobby => users = users - sender - if(host.actorRef == sender()){ + if (host.actorRef == sender()) { users.foreach(_ ! HostLeaveLobby) context.stop(self) - }else if(secondPlayer.exists(_.actorRef == sender())){ + } else if (secondPlayer.exists(_.actorRef == sender())) { secondPlayerReady = false secondPlayer = None - if(status == Draft()){ + if (status == Draft() || status == SelectRace()) { users.foreach(_ ! SecondPlayerLeaveLobby) context.stop(self) - }else { + } else { users.foreach(_ ! RefreshLobbyInfo(getLobbyInfoResponse)) } } @@ -209,8 +229,8 @@ class LobbieActor(hostUser: LobbyUser, deciderName: String) extends Actor with L private def getLobbyInfoResponse: LobbyInfo = { val user2Name = secondPlayer.map(_.name).getOrElse("") LobbyInfo( - UserInfo(host.name, firstPlayerReady), - UserInfo(user2Name, secondPlayerReady), + UserInfo(host.name, firstPlayerReady, firstPlayerSelectedRaces), + UserInfo(user2Name, secondPlayerReady, secondPlayerSelectedRaces), self.path.name, deciderName, status.toString(), @@ -247,7 +267,9 @@ case class ChangeIsNecronSelected(isSelected: Boolean) case object InfoQuery -case class UserInfo(name: String, isReady: Boolean) +case class SelectedRaces(firstRace: Int, secondRace: Int, thirdRace: Int) + +case class UserInfo(name: String, isReady: Boolean, selectedRaces: Option[SelectedRaces] = None) case class LobbyInfo(user1Info: UserInfo, user2Info: UserInfo, @@ -262,12 +284,21 @@ case class LobbyInfo(user1Info: UserInfo, class LobbyStatus sealed case class NotStarted() extends LobbyStatus + +sealed case class SelectRace() extends LobbyStatus + sealed case class Draft() extends LobbyStatus + sealed case class Finish() extends LobbyStatus class LobbyType +sealed case class Last1() extends LobbyType + sealed case class Last3() extends LobbyType + sealed case class Last5() extends LobbyType + +sealed case class Last7() extends LobbyType + sealed case class Superfinal() extends LobbyType -sealed case class LooserPick() extends LobbyType \ No newline at end of file diff --git a/app/actors/UserActor.scala b/app/actors/UserActor.scala index b2854ce..8b8c5df 100644 --- a/app/actors/UserActor.scala +++ b/app/actors/UserActor.scala @@ -23,11 +23,14 @@ class UserActor(out: ActorRef, def writes(deciderMap: DeciderMap): JsValue = { Json.obj( "map" -> deciderMap.map, + "description" -> deciderMap.description, "isBanned" -> deciderMap.isBanned ) } } + implicit val selectedRacesWrites: OWrites[SelectedRaces] = Json.writes[SelectedRaces] + implicit val userInfoWrites: OWrites[UserInfo] = Json.writes[UserInfo] implicit val lobbyWrites: Writes[LobbyInfo] = new Writes[LobbyInfo]{ @@ -172,6 +175,12 @@ class UserActor(out: ActorRef, val map = (json \ "map").as[String] lobbieActor.foreach(lobby => lobby ! BanMap(map)) + case Some("selectRace") => + val firstRace = (json \ "raceFirst").as[Int] + val secondRace = (json \ "raceSecond").as[Int] + val thirdRace = (json \ "raceThird").as[Int] + lobbieActor.foreach(lobby => lobby ! SelectedRaces(firstRace, secondRace, thirdRace)) + case Some("getLobbies") => logger.debug("Get all lobby request") (LobbiesActor.actor ? GetAllLobbies).mapTo[List[RefreshLobbyInfo]] onComplete { diff --git a/app/assets/images/maps/2p_bloody_hell_[Ed].jpg b/app/assets/images/maps/2p_bloody_hell_[Ed].jpg new file mode 100644 index 0000000..7719c1b Binary files /dev/null and b/app/assets/images/maps/2p_bloody_hell_[Ed].jpg differ diff --git a/app/assets/images/maps/2p_moonbase_[Ed].jpg b/app/assets/images/maps/2p_moonbase_[Ed].jpg new file mode 100644 index 0000000..42f664b Binary files /dev/null and b/app/assets/images/maps/2p_moonbase_[Ed].jpg differ diff --git a/app/assets/images/maps/2p_winter_confortation.jpg b/app/assets/images/maps/2p_winter_confortation.jpg new file mode 100644 index 0000000..f954277 Binary files /dev/null and b/app/assets/images/maps/2p_winter_confortation.jpg differ diff --git a/app/assets/images/maps/IM_MAP_IM_MAP (1).docx b/app/assets/images/maps/IM_MAP_IM_MAP (1).docx new file mode 100644 index 0000000..2b0ce96 Binary files /dev/null and b/app/assets/images/maps/IM_MAP_IM_MAP (1).docx differ diff --git a/app/assets/images/maps/IM_MAP_IM_MAP (2).docx b/app/assets/images/maps/IM_MAP_IM_MAP (2).docx new file mode 100644 index 0000000..5481293 Binary files /dev/null and b/app/assets/images/maps/IM_MAP_IM_MAP (2).docx differ diff --git a/app/assets/images/maps/IM_MAP_IM_MAP.docx b/app/assets/images/maps/IM_MAP_IM_MAP.docx new file mode 100644 index 0000000..9db4a04 Binary files /dev/null and b/app/assets/images/maps/IM_MAP_IM_MAP.docx differ diff --git a/app/assets/images/maps/allMaps.json b/app/assets/images/maps/allMaps.json index d0ccf71..791c6f6 100644 --- a/app/assets/images/maps/allMaps.json +++ b/app/assets/images/maps/allMaps.json @@ -132,6 +132,8 @@ "6p_agamar_desert": "Agamar Desert (6)", "6p_alvarus": "Alvarus (6)", "6p_kaurav_city": "Kaurav City (6)", + "6p_snowblind": "Snowblind (6)", + "6p_ruined_greatway": "Ruined Greatway (6)", "8p_forbidden_jungle": "Forbidden Jungle (8)", "8p_rhean_jungle": "Rhean Jungle (8)", "8p_thurabis_plateau": "ThurAbis Plateau (8)", diff --git a/app/assets/images/raceIcons/Chaos.gif b/app/assets/images/raceIcons/Chaos.gif new file mode 100644 index 0000000..091bc26 Binary files /dev/null and b/app/assets/images/raceIcons/Chaos.gif differ diff --git a/app/assets/images/raceIcons/De.gif b/app/assets/images/raceIcons/De.gif new file mode 100644 index 0000000..c6a4d8a Binary files /dev/null and b/app/assets/images/raceIcons/De.gif differ diff --git a/app/assets/images/raceIcons/Eldar.gif b/app/assets/images/raceIcons/Eldar.gif new file mode 100644 index 0000000..a6ce058 Binary files /dev/null and b/app/assets/images/raceIcons/Eldar.gif differ diff --git a/app/assets/images/raceIcons/IG.gif b/app/assets/images/raceIcons/IG.gif new file mode 100644 index 0000000..73fc495 Binary files /dev/null and b/app/assets/images/raceIcons/IG.gif differ diff --git a/app/assets/images/raceIcons/Nec.gif b/app/assets/images/raceIcons/Nec.gif new file mode 100644 index 0000000..6a0c0cd Binary files /dev/null and b/app/assets/images/raceIcons/Nec.gif differ diff --git a/app/assets/images/raceIcons/Orks.gif b/app/assets/images/raceIcons/Orks.gif new file mode 100644 index 0000000..7a3ce49 Binary files /dev/null and b/app/assets/images/raceIcons/Orks.gif differ diff --git a/app/assets/images/raceIcons/SM.gif b/app/assets/images/raceIcons/SM.gif new file mode 100644 index 0000000..99af907 Binary files /dev/null and b/app/assets/images/raceIcons/SM.gif differ diff --git a/app/assets/images/raceIcons/Sob.gif b/app/assets/images/raceIcons/Sob.gif new file mode 100644 index 0000000..3de5065 Binary files /dev/null and b/app/assets/images/raceIcons/Sob.gif differ diff --git a/app/assets/images/raceIcons/Tau.gif b/app/assets/images/raceIcons/Tau.gif new file mode 100644 index 0000000..ed0c93a Binary files /dev/null and b/app/assets/images/raceIcons/Tau.gif differ diff --git a/app/assets/javascripts/index.js b/app/assets/javascripts/index.js index e3e9094..8b0a817 100644 --- a/app/assets/javascripts/index.js +++ b/app/assets/javascripts/index.js @@ -2,6 +2,8 @@ var ws; var userName = "" +var raceCount = $("#raceCount").html() + window.onload = function() { 'use strict'; @@ -78,6 +80,7 @@ window.onload = function() { $("#createDecider").click(function(event) { event.preventDefault(); + isObserver = false; ws.send(JSON.stringify({ type: "createDecider", deciderName: $("#deciderName").html() @@ -104,14 +107,20 @@ window.onload = function() { $(".navbar").show(); }); - if($.cookie('user')=== undefined){ - var result = prompt("Enter nickname: ", ); - $.cookie('user', result, { expires: 1337 }); - userName = result; - }else{ - userName = $.cookie('user'); + function requestName(){ + if($.cookie('user') === undefined || $.cookie('user')=== "null"|| $.cookie('user')=== ""){ + var result = prompt("Enter nickname: ", ); + $.cookie('user', result, { expires: 1337 }); + userName = result; + requestName(); + }else{ + userName = $.cookie('user'); + } } + requestName(); + + $("#playerName").html(userName); @@ -121,7 +130,11 @@ window.onload = function() { message = JSON.parse(event.data); switch (message.type) { case "refreshLobby": - renderMaps(message.lobby.maps, message.lobby.status); + if(message.lobby.status === "SelectRace()" && (!isObserver)){ + renderRaces(); + }else { + renderMaps(message.lobby.maps, message.lobby.status); + } renderPlayersAndStats(message.lobby); break; case "switchToLobby": @@ -202,6 +215,146 @@ function disconnectLobby(error) { alert(error); } +// ---------------Выбор рас -------------- + +function getRaceImageByNumber(number){ + switch (number) { + case 1: return "/assets/images/raceIcons/SM.gif"; + case 2: return "/assets/images/raceIcons/Chaos.gif"; + case 3: return "/assets/images/raceIcons/Eldar.gif"; + case 4: return "/assets/images/raceIcons/Orks.gif"; + case 5: return "/assets/images/raceIcons/IG.gif"; + case 6: return "/assets/images/raceIcons/Nec.gif"; + case 7: return "/assets/images/raceIcons/Tau.gif"; + case 8: return "/assets/images/raceIcons/Sob.gif"; + case 9: return "/assets/images/raceIcons/De.gif"; + } +} + +function getRaceVideoByNumber(number){ + switch (number) { + case 1: return "/assets/video/races/SM.mp4"; + case 2: return "/assets/video/races/Chaos.mp4"; + case 3: return "/assets/video/races/Eldar.mp4"; + case 4: return "/assets/video/races/Orks.mp4"; + case 5: return "/assets/video/races/IG.mp4"; + case 6: return "/assets/video/races/Nec.mp4"; + case 7: return "/assets/video/races/Tau.mp4"; + case 8: return "/assets/video/races/Sob.mp4"; + case 9: return "/assets/video/races/SM.mp4"; + } +} + +function renderRaces() { + var resHtml = ""; + resHtml += "