Видосы и параметризованный выбор кол-ва рас
@ -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
|
||||
@ -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 {
|
||||
|
||||
BIN
app/assets/images/maps/2p_bloody_hell_[Ed].jpg
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
app/assets/images/maps/2p_moonbase_[Ed].jpg
Normal file
|
After Width: | Height: | Size: 230 KiB |
BIN
app/assets/images/maps/2p_winter_confortation.jpg
Normal file
|
After Width: | Height: | Size: 236 KiB |
BIN
app/assets/images/maps/IM_MAP_IM_MAP (1).docx
Normal file
BIN
app/assets/images/maps/IM_MAP_IM_MAP (2).docx
Normal file
BIN
app/assets/images/maps/IM_MAP_IM_MAP.docx
Normal file
@ -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)",
|
||||
|
||||
BIN
app/assets/images/raceIcons/Chaos.gif
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
app/assets/images/raceIcons/De.gif
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
app/assets/images/raceIcons/Eldar.gif
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
app/assets/images/raceIcons/IG.gif
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
app/assets/images/raceIcons/Nec.gif
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
app/assets/images/raceIcons/Orks.gif
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
app/assets/images/raceIcons/SM.gif
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
app/assets/images/raceIcons/Sob.gif
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
app/assets/images/raceIcons/Tau.gif
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
@ -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 += "<div class='col-xs-4'><center><h2>First race</h2>";
|
||||
for(var i = 1; i <= 9; i++){
|
||||
var selected = "raceNotSelected";
|
||||
if($.cookie("race1") == i){
|
||||
selected = "raceSelected";
|
||||
selectedMainRace = i;
|
||||
}
|
||||
resHtml += '<a href = "#" class="'+selected+' mainRaceIcon" onclick="selectMainRace(this, ' +i+')"><img class="raceIcon" src="'+getRaceImageByNumber(i)+'"></a> ';
|
||||
}
|
||||
resHtml += "</center></div>";
|
||||
|
||||
if(raceCount >= 2){
|
||||
resHtml += "<div class='col-xs-4'><center><h2>Second race</h2>";
|
||||
for(var i = 1; i <= 9; i++){
|
||||
var selected = "raceNotSelected";
|
||||
if($.cookie("race2") == i){
|
||||
selected = "raceSelected";
|
||||
selectedSecondRace = i;
|
||||
}
|
||||
resHtml += '<a href = "#" class="'+selected+' additionalRaceIcon" onclick="selectSecondRace(this, ' +i+')"><img class="raceIcon" src="'+getRaceImageByNumber(i)+'"></a> ';
|
||||
}
|
||||
resHtml += "</center></div>";
|
||||
}
|
||||
|
||||
if(raceCount >= 3){
|
||||
resHtml += "<div class='col-xs-4'><center><h2>Ban race</h2>";
|
||||
for(var i = 1; i <= 9; i++){
|
||||
var selected = "raceNotSelected";
|
||||
var banned = "";
|
||||
if($.cookie("race3") == i){
|
||||
selected = "raceSelected";
|
||||
banned = "bannedRace";
|
||||
selectedThirdRace = i;
|
||||
}
|
||||
resHtml += '<a href = "#" class="'+selected+' thirdRaceIcon" onclick="selectThirdRace(this, ' +i+')"><img class="raceIcon '+banned+'" src="'+getRaceImageByNumber(i)+'"></a> ';
|
||||
}
|
||||
resHtml += "</center></div>";
|
||||
}
|
||||
resHtml += "<div class='col-xs-4'></div>";
|
||||
resHtml += "<div style='clear: both;'></div></br>";
|
||||
|
||||
resHtml += "<center><button id = 'selectRace' class='btn btn-primary' disabled onclick='sendSelectedRacesToServer()'>OK</button></center>"
|
||||
$("#mapList").html(resHtml);
|
||||
checkRaceSelectFinish();
|
||||
}
|
||||
|
||||
var selectedMainRace = 0;
|
||||
var selectedSecondRace = 0;
|
||||
var selectedThirdRace = 0;
|
||||
|
||||
function selectMainRace(button, race){
|
||||
selectedMainRace = race;
|
||||
$.cookie("race1", race, { expires: 1 });
|
||||
_.each($(".mainRaceIcon"), function (el){
|
||||
$(el).removeClass("raceSelected");
|
||||
$(el).addClass("raceNotSelected");
|
||||
});
|
||||
$(button).removeClass("raceNotSelected");
|
||||
$(button).addClass("raceSelected");
|
||||
checkRaceSelectFinish();
|
||||
|
||||
}
|
||||
|
||||
function selectSecondRace(button, race){
|
||||
selectedSecondRace = race;
|
||||
$.cookie("race2", race, { expires: 1 });
|
||||
_.each($(".additionalRaceIcon"), function (el){
|
||||
$(el).removeClass("raceSelected");
|
||||
$(el).addClass("raceNotSelected");
|
||||
});
|
||||
$(button).removeClass("raceNotSelected");
|
||||
$(button).addClass("raceSelected");
|
||||
checkRaceSelectFinish();
|
||||
}
|
||||
|
||||
function selectThirdRace(button, race){
|
||||
selectedThirdRace = race;
|
||||
$.cookie("race3", race, { expires: 1 });
|
||||
_.each($(".thirdRaceIcon"), function (el){
|
||||
$(el).removeClass("raceSelected");
|
||||
$(el).children('img').removeClass("bannedRace");
|
||||
$(el).addClass("raceNotSelected");
|
||||
});
|
||||
$(button).removeClass("raceNotSelected");
|
||||
$(button).addClass("raceSelected");
|
||||
$(button).children("img").addClass("bannedRace");
|
||||
checkRaceSelectFinish();
|
||||
}
|
||||
|
||||
function checkRaceSelectFinish(){
|
||||
|
||||
if(selectedMainRace !== 0 && (raceCount < 2 || selectedSecondRace !== 0) && (raceCount < 3 || selectedThirdRace !== 0)){
|
||||
$("#selectRace").removeAttr("disabled")
|
||||
}
|
||||
}
|
||||
|
||||
function sendSelectedRacesToServer(){
|
||||
ws.send(JSON.stringify({
|
||||
type: "selectRace",
|
||||
raceFirst: selectedMainRace,
|
||||
raceSecond: selectedSecondRace,
|
||||
raceThird: selectedThirdRace,
|
||||
}));
|
||||
$("#mapList").html("<center>Waiting another player...</center>");
|
||||
}
|
||||
|
||||
// ---------------------------------------------
|
||||
|
||||
function renderMaps(maps, lobbyStatus) {
|
||||
var resHtml = "";
|
||||
|
||||
@ -217,15 +370,60 @@ function renderMaps(maps, lobbyStatus) {
|
||||
banClass = "bannedMap";
|
||||
}
|
||||
|
||||
var title = ""
|
||||
|
||||
if(map.description != null){
|
||||
title = "title='"+map.description+"'";
|
||||
}
|
||||
|
||||
resHtml = resHtml + '<div class="col-xs-4 col-md-3 col-lg-2"><button class = "mapSelect" onmousedown="banMap(\''+map.map+'\')">'+
|
||||
'<div class="mapImageAndText '+banClass+'">' +
|
||||
'<img class="img-rounded center-block" style="width:128px;" src="/assets/images/maps/'+encodeURI(map.map)+'.jpg">' +
|
||||
'<img class="img-rounded center-block" '+title+' style="width:128px;" src="/assets/images/maps/'+encodeURI(map.map)+'.jpg">' +
|
||||
'</div>'+convertMapName(map.map)+
|
||||
banHtml + '</button></div>';
|
||||
})
|
||||
$("#mapList").html(resHtml);
|
||||
}
|
||||
|
||||
var isObserver = false;
|
||||
|
||||
function renderFinish(maps, firstPlayerInfo, secondPlayerInfo) {
|
||||
var resHtml = "<center>";
|
||||
|
||||
_.each(maps, function (map) {
|
||||
if(!map.isBanned){
|
||||
resHtml = resHtml + '<div class="col-xs-4 col-md-3 col-lg-2"><button class = "mapSelect" >'+
|
||||
'<div class="mapImageAndText ">' +
|
||||
'<img class="img-rounded center-block" style="width:128px;" src="/assets/images/maps/'+encodeURI(map.map)+'.jpg">' +
|
||||
'</div>'+convertMapName(map.map)+ '</button></div>';
|
||||
}
|
||||
})
|
||||
|
||||
resHtml += "<div style='clear: both;'>";
|
||||
|
||||
resHtml += "<h2>" + firstPlayerInfo.name + "</h2>";
|
||||
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(firstPlayerInfo.selectedRaces.firstRace)+"> ";
|
||||
if(raceCount >= 2){
|
||||
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(firstPlayerInfo.selectedRaces.secondRace)+"> ";
|
||||
}
|
||||
if(raceCount >= 3){
|
||||
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(firstPlayerInfo.selectedRaces.thirdRace)+"> ";
|
||||
}
|
||||
|
||||
resHtml += "<h2>" + secondPlayerInfo.name + "</h2>";
|
||||
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(secondPlayerInfo.selectedRaces.firstRace)+"> ";
|
||||
if(raceCount >= 2){
|
||||
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(secondPlayerInfo.selectedRaces.secondRace)+"> ";
|
||||
}
|
||||
if(raceCount >= 3){
|
||||
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(secondPlayerInfo.selectedRaces.thirdRace)+"> ";
|
||||
}
|
||||
|
||||
resHtml += "</center>"
|
||||
|
||||
$("#mapList").html(resHtml);
|
||||
}
|
||||
|
||||
function renderPlayersAndStats(lobby) {
|
||||
var resHtml = "<center>";
|
||||
var player1ReadyBtn = "";
|
||||
@ -269,15 +467,19 @@ function renderPlayersAndStats(lobby) {
|
||||
}
|
||||
|
||||
var lobbyTypeText = "";
|
||||
var last1Selected = "";
|
||||
var last3Selected = "";
|
||||
var last5Selected = "";
|
||||
var superfinalSelected = "";
|
||||
var looserPickSelected = "";
|
||||
var last7Selected = "";
|
||||
|
||||
var isNecronsSelected = "";
|
||||
if(lobby.isNecrons) isNecronsSelected = "checked";
|
||||
|
||||
switch (lobby.selectedType) {
|
||||
case "Last1()":
|
||||
looserPickSelected = "selected";
|
||||
lobbyTypeText = "Play on last map";
|
||||
break;
|
||||
case "Last3()":
|
||||
last3Selected = "selected";
|
||||
lobbyTypeText = "Play on last 3 maps";
|
||||
@ -286,16 +488,13 @@ function renderPlayersAndStats(lobby) {
|
||||
last5Selected = "selected";
|
||||
lobbyTypeText = "Play on last 5 maps";
|
||||
break;
|
||||
case "Superfinal()":
|
||||
superfinalSelected = "selected";
|
||||
lobbyTypeText = "Draft to select 9 maps for BO7";
|
||||
break;
|
||||
case "LooserPick()":
|
||||
looserPickSelected = "selected";
|
||||
lobbyTypeText = "Play on last map";
|
||||
case "Last7()":
|
||||
last7Selected = "selected";
|
||||
lobbyTypeText = "Play on last 7 maps";
|
||||
break;
|
||||
}
|
||||
|
||||
console.log(lobby.status);
|
||||
switch (lobby.status) {
|
||||
case "NotStarted()":
|
||||
resHtml = "<div style='float: left; padding-top: 10px;'> <div>" + lobby.user1Info.name + ": " + player1ReadyBtn +"</div><br/>"
|
||||
@ -318,10 +517,10 @@ function renderPlayersAndStats(lobby) {
|
||||
|
||||
//TODO: here from config
|
||||
resHtml += "<br/><select class=\"form-control\" id = 'deciderOption' onChange='changeLobbyType()' "+disabledText+" >" +
|
||||
"<option "+looserPickSelected+" value = 'looserpick'>Play on last map</option>" +
|
||||
//"<option "+last3Selected+" value = 'last3'>Play on last 3 maps</option>" +
|
||||
//"<option "+last5Selected+" value = 'last5'>Play on last 5 maps</option>" +
|
||||
//"<option "+superfinalSelected+" value = 'superfinal'>Superfinal (BO7)</option>" +
|
||||
"<option "+last1Selected+" value = 'last1'>Play on last map</option>" +
|
||||
"<option "+last3Selected+" value = 'last3'>Play on last 3 maps</option>" +
|
||||
"<option "+last5Selected+" value = 'last5'>Play on last 5 maps</option>" +
|
||||
/*"<option "+last7Selected+" value = 'last7'>Play on last 7 maps</option>" +*/
|
||||
"</select>";
|
||||
|
||||
if(lobby.user1Info.name !== userName && lobby.user2Info.name !== userName){
|
||||
@ -329,26 +528,37 @@ function renderPlayersAndStats(lobby) {
|
||||
}else{
|
||||
disabledText = "";
|
||||
}
|
||||
if($("#necronPresence").html() === "true"){
|
||||
resHtml += "<br/><label><input onchange=\"changeIsNecronSelected()\" id='isNecron' type=\"checkbox\" "+isNecronsSelected +" " + disabledText +">" +
|
||||
" Necrons are present</label>";
|
||||
}
|
||||
/*for(var i = 1; i <= 9; i++){
|
||||
resHtml += '<a href = "#" class="raceNotSelected mainRaceIcon" style="position: absolute; z-index: -1;"><img class="raceIcon" src="'+getRaceImageByNumber(i)+'"></a> ';
|
||||
}*/
|
||||
resHtml += "</div>";
|
||||
break;
|
||||
case "SelectRace()":
|
||||
resHtml = "<center>"+lobby.user1Info.name + " vs " + lobby.user2Info.name + " - " +lobbyTypeText+ "<br/> players select races</center>";
|
||||
break;
|
||||
case "Draft()":
|
||||
console.log(lobby.turn);
|
||||
var playerTurn = (lobby.playerTurn === 1) ? lobby.user1Info.name : lobby.user2Info.name
|
||||
resHtml = "<center>"+lobby.user1Info.name + " vs " + lobby.user2Info.name + " - " +lobbyTypeText+ "<br/><b>" + playerTurn +"</b> turn</center>";
|
||||
resHtml += "<center><img class=\"raceIcon\" src="+getRaceImageByNumber(lobby.user1Info.selectedRaces.firstRace)+"> ";
|
||||
if(raceCount > 1){
|
||||
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(lobby.user1Info.selectedRaces.secondRace)+"> ";
|
||||
}
|
||||
if(raceCount > 2){
|
||||
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(lobby.user1Info.selectedRaces.thirdRace)+"> ";
|
||||
}
|
||||
resHtml += " <span style='font-size: 14px'>VS</span> ";
|
||||
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(lobby.user2Info.selectedRaces.firstRace)+">";
|
||||
if(raceCount > 1){
|
||||
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(lobby.user2Info.selectedRaces.secondRace)+"> ";
|
||||
}
|
||||
if(raceCount > 2){
|
||||
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(lobby.user2Info.selectedRaces.thirdRace)+"> ";
|
||||
}
|
||||
break;
|
||||
case "Finish()":
|
||||
var lastMaps = _.filter(lobby.maps, function (map){
|
||||
return map.isBanned === false;
|
||||
});
|
||||
resHtml = "<center><b>";
|
||||
_.forEach(lastMaps,function (map){
|
||||
resHtml += convertMapName(map.map) + "; "
|
||||
})
|
||||
resHtml += "</b></center>";
|
||||
renderFinish(lobby.maps, lobby.user1Info, lobby.user2Info);
|
||||
break;
|
||||
}
|
||||
|
||||
resHtml = resHtml + "</center>"
|
||||
@ -406,6 +616,7 @@ function changeIsNecronSelected(){
|
||||
}
|
||||
|
||||
function joinDecider(actorName){
|
||||
isObserver = false;
|
||||
ws.send(JSON.stringify({
|
||||
type: "joinDecider",
|
||||
lobbyActorName: actorName
|
||||
@ -413,6 +624,7 @@ function joinDecider(actorName){
|
||||
}
|
||||
|
||||
function observerDecider(actorName){
|
||||
isObserver = true;
|
||||
ws.send(JSON.stringify({
|
||||
type: "observerDecider",
|
||||
lobbyActorName: actorName
|
||||
|
||||
@ -20,6 +20,13 @@
|
||||
-webkit-filter: grayscale(1); /* Webkit браузеры */
|
||||
}
|
||||
|
||||
.bannedRace {
|
||||
height: 96px;
|
||||
background-color: red;
|
||||
clip-path: polygon(20% 0%, 0% 20%, 30% 50%, 0% 80%, 20% 100%, 50% 70%, 80% 100%, 100% 80%, 70% 50%, 100% 20%, 80% 0%, 50% 30%);
|
||||
border: 2px solid red;
|
||||
}
|
||||
|
||||
.mapSelect{
|
||||
margin: 4px;
|
||||
position:relative;
|
||||
@ -29,6 +36,39 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.raceIcon{
|
||||
width: 90px;
|
||||
border-radius: 5px;
|
||||
margin: 3px;
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.raceNotSelected{
|
||||
-webkit-filter: grayscale(1); /* Webkit браузеры */
|
||||
}
|
||||
|
||||
.raceNotSelected:hover{
|
||||
-webkit-filter: grayscale(0); /* Webkit браузеры */
|
||||
}
|
||||
|
||||
.raceSelected{
|
||||
-webkit-filter: brightness(1.3);
|
||||
}
|
||||
|
||||
.tooltip span{
|
||||
border-radius: 5px 5px 5px 5px;
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
left: 200px;
|
||||
background: #fff;
|
||||
box-shadow: -2px 2px 10px -1px #333;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.tooltip:hover span{
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
@keyframes glowing {
|
||||
0% {
|
||||
box-shadow: 0 0 2px #074673;
|
||||
|
||||
BIN
app/assets/video/races/Chaos.mp4
Normal file
BIN
app/assets/video/races/De.mp4
Normal file
BIN
app/assets/video/races/Eldar.mp4
Normal file
BIN
app/assets/video/races/IG.mp4
Normal file
BIN
app/assets/video/races/Nec.mp4
Normal file
BIN
app/assets/video/races/Orks.mp4
Normal file
BIN
app/assets/video/races/SM.mp4
Normal file
BIN
app/assets/video/races/Sob.mp4
Normal file
BIN
app/assets/video/races/Tau.mp4
Normal file
@ -16,8 +16,10 @@ import play.api.mvc._
|
||||
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
import scala.util.Try
|
||||
|
||||
case class LastMapsSelectConfig(last1: Boolean, last3: Boolean, last5: Boolean, last7: Boolean)
|
||||
case class RaceSelect(select: Boolean, showAtStart: Boolean)
|
||||
|
||||
/**
|
||||
* This class creates the actions and the websocket needed.
|
||||
@ -41,9 +43,10 @@ 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 necronPresence = config.getBoolean(s"deciders.$deciderName.necronrestrict")
|
||||
val raceCount = Try(config.getInt(s"deciders.$deciderName.raceCount")).getOrElse(1)
|
||||
val lastmapsSettings = LastMapsSelectConfig(true, true, true, true)
|
||||
Ok(views.html.index(deciderName, deciderHumanName, deciderDescription, necronPresence, lastmapsSettings))
|
||||
val raceSelect = RaceSelect(true, false)
|
||||
Ok(views.html.index(deciderName, deciderHumanName, raceCount, deciderDescription, raceSelect, lastmapsSettings))
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,7 +101,7 @@ class HomeController @Inject()(cc: ControllerComponents) extends AbstractControl
|
||||
* Returns true if the value of the Origin header contains an acceptable value.
|
||||
*/
|
||||
def originMatches(origin: String, remoteAddress: String): Boolean = {
|
||||
origin.contains("139.59.210.74") || origin.contains("localhost") || origin.contains("localhost:9000") || origin.contains("localhost:19001")
|
||||
origin.contains("89.108.83.108") || origin.contains("crosspick.ru") || origin.contains("localhost") || origin.contains("localhost:9000") || origin.contains("localhost:19001")
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
@(deciderName: String, deciderHumanName: String, rules: String, necronPresence: Boolean, boSettings: LastMapsSelectConfig)(implicit r: Request[_])
|
||||
@(deciderName: String, deciderHumanName: String, raceCount: Int, rules: String, raceSelect: RaceSelect, boSettings: LastMapsSelectConfig)(implicit r: Request[_])
|
||||
<!DOCTYPE html>
|
||||
|
||||
<span id="deciderName" style="display: none">@deciderName</span>
|
||||
<span id="necronPresence" style="display: none">@necronPresence</span>
|
||||
<span id="raceCount" style="display: none">@raceCount</span>
|
||||
<span id="last1Presence" style="display: none">@boSettings.last1</span>
|
||||
<span id="last3Presence" style="display: none">@boSettings.last3</span>
|
||||
<span id="last5Presence" style="display: none">@boSettings.last5</span>
|
||||
@ -13,15 +13,14 @@
|
||||
<head>
|
||||
<title>Soulstorm tournament decider</title>
|
||||
<link rel='stylesheet' href='@routes.Assets.at("lib/bootstrap/css/bootstrap.min.css")'>
|
||||
<link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")">
|
||||
<link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css?080422")">
|
||||
<link rel="shortcut icon" type="image/png" href="@routes.Assets.at("images/favicon.png")">
|
||||
<script type='text/javascript' src='@routes.Assets.at("lib/jquery/jquery.min.js")'></script>
|
||||
<script type='text/javascript' src='@routes.Assets.at("lib/flot/jquery.flot.js")'></script>
|
||||
<script type='text/javascript' src='@routes.Assets.at("lib/underscore/underscore.js")'></script>
|
||||
<script type='text/javascript' src='@routes.Assets.at("lib/backbonejs/backbone.js")'></script>
|
||||
<script type="text/javascript" src="@routes.Assets.at("lib/jquery-cookie/jquery.cookie.js")"></script>
|
||||
|
||||
<script type='text/javascript' src='@routes.Assets.at("javascripts/index.js?231021")'></script>
|
||||
<script type='text/javascript' src='@routes.Assets.at("javascripts/index.js?030622")'></script>
|
||||
</head>
|
||||
<body data-ws-url="@routes.HomeController.ws.webSocketURL()">
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
|
||||
@ -18,6 +18,7 @@ libraryDependencies += "org.webjars" % "jquery-cookie" % "1.4.1-1"
|
||||
libraryDependencies += "org.webjars.npm" % "underscore" % "1.11.0"
|
||||
libraryDependencies += "org.webjars" % "backbonejs" % "1.3.3"
|
||||
|
||||
|
||||
libraryDependencies += guice
|
||||
libraryDependencies += "com.typesafe.scala-logging" %% "scala-logging" % "3.9.2"
|
||||
|
||||
|
||||
@ -2,22 +2,58 @@
|
||||
# https://www.playframework.com/documentation/latest/AllowedHostsFilter
|
||||
# Allow requests to localhost:9000.
|
||||
play.filters.hosts {
|
||||
allowed = ["localhost:9000", "localhost", "139.59.210.74", "*"]
|
||||
allowed = ["localhost:9000", "localhost", "89.108.83.108", "*", "crosspick.ru"]
|
||||
}
|
||||
play.http.secret.key="QCY?tAnfk?aZ?iwrNwnxIlR6CTf:123123Latabg@5241AB`R5W:1uDFN];Ik@n"
|
||||
play.server.http.port = 80
|
||||
|
||||
deciders{
|
||||
classic{
|
||||
maps = [["2p_battle_marshes"],
|
||||
["2p_fallen_city_[Rem]"],
|
||||
["2p_fata_morgana_[Rem]"],
|
||||
["2p_quests_triumph"],
|
||||
["2p_meeting_of_minds"],
|
||||
["2p_shrine_of_excellion_[Rem]"],
|
||||
["2p_titan_fall_[Rem]"],
|
||||
["2p_tranquilitys_end_[Rem]"],
|
||||
["2p_fraziersdemise"],
|
||||
["2p_outer_reaches"],
|
||||
["2p_blood_river_[Rem]"],
|
||||
["2p_deadly_fun_archeology"],
|
||||
["2p_bloody_hell_[Ed]"]]
|
||||
name = "Классический десайдер"
|
||||
rules = """"""
|
||||
}
|
||||
turtleshell{
|
||||
maps = [["2p_battle_marshes"],
|
||||
["2p_fallen_city_[Rem]"],
|
||||
["2p_fata_morgana_[Rem]"],
|
||||
["2p_quests_triumph"],
|
||||
["2p_meeting_of_minds"],
|
||||
["2p_shrine_of_excellion_[Rem]"],
|
||||
["2p_titan_fall_[Rem]"],
|
||||
["2p_tranquilitys_end_[Rem]"],
|
||||
["2p_fraziersdemise"],
|
||||
["2p_outer_reaches"],
|
||||
["2p_blood_river_[Rem]"],
|
||||
["2p_deadly_fun_archeology"],
|
||||
["2p_bloody_hell_[Ed]"],
|
||||
["2p_sugaroasis"],
|
||||
["2p_vortex_plateau"]]
|
||||
name = "Turtle Shell tournament"
|
||||
rules = """Выбор карт в BO3: Игроки вычеркивают по очереди карты из маппула, пока их не останется 3 (три). Вычеркивания проводятся вручную в лобби игры или с помощью десайдера, если такая техническая возможность присутствует. Таким образом каждый вычеркнет 6 карт пока не останутся 3 карты."""
|
||||
}
|
||||
dvijcup{
|
||||
maps = ["2p_battle_marshes",
|
||||
"2p_fallen_city_[Rem]",
|
||||
"2p_meeting_of_minds",
|
||||
"2p_fata_morgana_[Rem]",
|
||||
"2p_quests_triumph",
|
||||
"2p_shrine_of_excellion_[Rem]",
|
||||
"2p_titan_fall_[Rem]",
|
||||
"2p_tranquilitys_end_[Rem]",
|
||||
"2p_fraziersdemise",
|
||||
"2p_sugaroasis",
|
||||
"2p_bloody_hell",
|
||||
"2p_blood_river_[Rem]",
|
||||
"2p_deadly_fun_archeology"]
|
||||
name = "Dvij cup"
|
||||
@ -26,26 +62,246 @@ deciders{
|
||||
Затем игроки вычеркивают выбранные карты, пока не останется только одна, на которой и играется первый матч встречи.
|
||||
Тот, кто первым начал вычеркивать из всего маппула, уступает оппоненту право вычеркивания первой карты из оставшихся карт-десайдеров.
|
||||
Во втором и последующем матчах проигравший выбирает карту из числа выбранных 3 (5) десайдеров."""
|
||||
necronrestrict = false
|
||||
}
|
||||
newplayerslegue{
|
||||
necronrestrict = false
|
||||
meatgrinder{
|
||||
maps = ["2p_battle_marshes",
|
||||
"2p_fallen_city",
|
||||
"2p_fata_morgana",
|
||||
"2p_fallen_city_[Rem]",
|
||||
"2p_fata_morgana_[Rem]",
|
||||
"2p_meeting_of_minds",
|
||||
"2p_outer_reaches",
|
||||
"2p_quests_triumph",
|
||||
"2p_shrine_of_excellion",
|
||||
"2p_shrine_of_excellion_[Rem]",
|
||||
"2p_titan_fall_[Rem]",
|
||||
"2p_tranquilitys_end",
|
||||
"2p_emerald_river",
|
||||
"2p_vortex_plateau",
|
||||
"2p_tranquilitys_end_[Rem]",
|
||||
"2p_fraziersdemise",
|
||||
"2p_blood_river"]
|
||||
name = "Лига новых игроков 2"
|
||||
rules = """Первую карту вы с оппонентом выбираете, поочередно вычеркивая неудобные для Вас карты из этих тринадцати. Вычеркиваете, пока не остается одна. На ней и играете. В последующих матчах карту выбирает тот, кто проиграл (это называется лузер-пик). Выбирать повторно карту, на которой вы с этим оппонентом уже играли, нельзя. Играть на ремастер-версиях карт можно по обоюдному согласию игроков. Если один из Вас не скачал новые версии карт - играйте на старых."""
|
||||
necronrestrict = true
|
||||
"2p_vortex_plateau",
|
||||
"2p_sugaroasis",
|
||||
"2p_blood_river_[Rem]"]
|
||||
name = "Meat grinder"
|
||||
rules = """Выбор карт в БО3 и БО5 осуществляется без лузерпиков, с тремя и пятью десайдерами соответственно. Игроки вычеркивают по очереди карты из маппула, пока их не останется 3 (для БО3) или 5 (для БО5). На этих картах и проходят все матчи встречи. Затем игроки вычеркивают выбранные карты, пока не останется только одна, на которой и играется первый матч встречи. Тот, кто первым начал вычеркивать из всего маппула, уступает оппоненту право вычеркивания первой карты из оставшихся карт-десайдеров. Во втором и последующем матчах проигравший выбирает карту из числа выбранных 3 (5) десайдеров. В случае, если один из игроков играет за расу некронов, из маппула исключаются карты MoM и SoE, после чего оба игрока приступают к вычеркиванию карт стандартным образом из 11-картового маппула."""
|
||||
}
|
||||
medskillcup{
|
||||
maps = ["2p_battle_marshes",
|
||||
"2p_fallen_city_[Rem]",
|
||||
"2p_fata_morgana_[Rem]",
|
||||
"2p_meeting_of_minds",
|
||||
"2p_outer_reaches",
|
||||
"2p_quests_triumph",
|
||||
"2p_shrine_of_excellion_[Rem]",
|
||||
"2p_titan_fall_[Rem]",
|
||||
"2p_tranquilitys_end_[Rem]",
|
||||
"2p_fraziersdemise",
|
||||
"2p_emerald_river",
|
||||
"2p_deadly_fun_archeology",
|
||||
"2p_blood_river_[Rem]"]
|
||||
name = "Med skill cup 4"
|
||||
rules = """Вы и ваш оппонент перед началом матчей вычеркиваете из маппула карты, пока не останется 3. На них и играете. Для БО1 - та же самая система выбора карт. В суперфинале игрок из верхней сетки начинает с +1 очком, а игрок из нижней сетки - с лузерпиком. Далее оба игрока вычеркивают по 3 карты, и могут лузерпикать из оставшихся 6 в последующих матчах."""
|
||||
}
|
||||
burgercup{
|
||||
maps = [["2p_battle_marshes"],
|
||||
["2p_fallen_city_[Rem]"],
|
||||
["2p_fata_morgana_[Rem]"],
|
||||
["2p_meeting_of_minds"],
|
||||
["2p_quests_triumph"],
|
||||
["2p_shrine_of_excellion_[Rem]"],
|
||||
["2p_titan_fall_[Rem]"],
|
||||
["2p_tranquilitys_end_[Rem]"],
|
||||
["2p_fraziersdemise"],
|
||||
["2p_bloody_hell_[Ed]"],
|
||||
["2p_deadly_fun_archeology"]]
|
||||
name = "Burger cup"
|
||||
raceCount = 2
|
||||
rules = """Выбор карт в БО3 и БО5 осуществляется без лузерпиков, с тремя и пятью десайдерами соответственно. Игроки вычеркивают по очереди карты из маппула, пока их не останется 3 (для БО3) или 5 (для БО5). На этих картах и проходят все матчи встречи. Затем игроки вычеркивают выбранные карты, пока не останется только одна, на которой и играется первый матч встречи. Тот, кто первым начал вычеркивать из всего маппула, уступает оппоненту право вычеркивания первой карты из оставшихся карт-десайдеров. Во втором и последующем матчах проигравший выбирает карту из числа выбранных 3 (5) десайдеров."""
|
||||
}
|
||||
everyonecup{
|
||||
maps = [["2p_battle_marshes"],
|
||||
["2p_fallen_city_[Rem]"],
|
||||
["2p_moonbase"],
|
||||
["2p_fata_morgana_[Rem]"],
|
||||
["2p_meeting_of_minds"],
|
||||
["2p_emperors_valley"],
|
||||
["2p_titan_fall_[Rem]"],
|
||||
["2p_tranquilitys_end_[Rem]"],
|
||||
["2p_fraziersdemise"],
|
||||
["2p_bloody_hell_[Ed]"],
|
||||
["2p_blood_river_[Rem]"],
|
||||
["2p_deadly_fun_archeology"],
|
||||
["2p_sugaroasis"]]
|
||||
name = "Everyone cup"
|
||||
raceCount = 1
|
||||
rules = """Все матчи БО3. Игроки вычеркивают по очереди карты из маппула, пока их не останется 3. На этих картах и проходят все матчи встречи."""
|
||||
}
|
||||
bigbosswinter{
|
||||
maps = ["2p_battle_marshes",
|
||||
"2p_fallen_city_[Rem]",
|
||||
"2p_fata_morgana_[Rem]",
|
||||
"2p_meeting_of_minds",
|
||||
"2p_outer_reaches",
|
||||
"2p_quests_triumph",
|
||||
"2p_shrine_of_excellion_[Rem]",
|
||||
"2p_titan_fall_[Rem]",
|
||||
"2p_tranquilitys_end_[Rem]",
|
||||
"2p_bloody_hell_[Ed]",
|
||||
"2p_emerald_river",
|
||||
"2p_deadly_fun_archeology",
|
||||
"2p_winter_confrontation"]
|
||||
name = "Big boss of winter"
|
||||
rules = """Выбор карт в БО3 и БО5 осуществляется без лузерпиков, с тремя и пятью десайдерами соответственно. Игроки вычеркивают по очереди карты из маппула, пока их не останется 3 (для БО3) или 5 (для БО5). На этих картах и проходят все матчи встречи. Затем игроки вычеркивают выбранные карты, пока не останется только одна, на которой и играется первый матч встречи. Тот, кто первым начал вычеркивать из всего маппула, уступает оппоненту право вычеркивания первой карты из оставшихся карт-десайдеров. Во втором и последующем матчах проигравший выбирает карту из числа выбранных 3 (5) десайдеров.В суперфинале турнира оба игрока вычеркивают по две карты. После этого из оставшихся 9 карт можно брать любые, выбирает их проигравший в предыдущем матче. Первый лузер-пик - за игроком из нижней сетки, который начинает с -1 очком. """
|
||||
}
|
||||
showmatch{
|
||||
maps = ["2p_battle_marshes",
|
||||
"2p_fallen_city_[Rem]",
|
||||
"2p_fata_morgana_[Rem]",
|
||||
"2p_quests_triumph",
|
||||
"2p_shrine_of_excellion_[Rem]",
|
||||
"2p_titan_fall_[Rem]",
|
||||
"2p_tranquilitys_end_[Rem]",
|
||||
"2p_fraziersdemise",
|
||||
"2p_bloody_hell_[Ed]",
|
||||
"2p_blood_river_[Rem]",
|
||||
"2p_sugaroasis",
|
||||
"2p_meeting_of_minds",
|
||||
"2p_emerald_river",
|
||||
"2p_velvet_duress",
|
||||
"2p_deadly_fun_archeology"]
|
||||
name = "Showmatch"
|
||||
rules = """ """
|
||||
}
|
||||
horusheresycup2{
|
||||
maps = ["2p_battle_marshes",
|
||||
"2p_fallen_city_[Rem]",
|
||||
"2p_fata_morgana_[Rem]",
|
||||
"2p_quests_triumph",
|
||||
"2p_shrine_of_excellion_[Rem]",
|
||||
"2p_titan_fall_[Rem]",
|
||||
"2p_tranquilitys_end_[Rem]",
|
||||
"2p_outer_reaches",
|
||||
"2p_blood_river_[Rem]",
|
||||
"2p_sugaroasis",
|
||||
"2p_meeting_of_minds"]
|
||||
name = "Horus heresy cup 2"
|
||||
rules = """ Первая карта десайдер выбирается методом вычеркивания, остальные лузер пик. По обоюдному согласию игроков разрешен повтор карт. Сетка турнира Double Elimination.
|
||||
Сетка виннеров:
|
||||
Каждая игра до 2х победы (БО3),
|
||||
В суперфинале игра до 3-х побед (БО5).
|
||||
Сетка лузеров:
|
||||
Каждая игра до 1й победы (БО1),
|
||||
Финал сетки лузеров (БО3).
|
||||
Игрок, прошедший в суперфинал из верхней сетки, имеет +1 очко. Игрок из нижней сетки начинает с лузерпиком. """
|
||||
}
|
||||
shouldercup{
|
||||
description = true
|
||||
raceCount = 3
|
||||
maps = [["6p_paynes_retribution", "Количество точек: 28/2/2\nСпорных точек: 10/0/2\nТермогенераторы: 2"],
|
||||
["6p_fury_island", "Количество точек: 26/6/1\nСпорных точек: 6 + 1 крит\nТермогенераторы: Отсутствуют"],
|
||||
["6p_irridene", "Количество точек: 21/6/3\nСпорных точек: 6/0/3\nТермогенераторы: 6"],
|
||||
["6p_shakun_coast", "Количество точек: 24/4/1\nСпорных точек: 6/2/1\nТермогенераторы: 2"],
|
||||
["6p_snowblind", "Количество точек: 22/2/3\nСпорных точек: 4/2/3\nТермогенераторы: отсутствуют"],
|
||||
["6p_temple_cyrene", "Количество точек: 25/4/5\nСпорных точек: 8/0/3\nТермогенераторы: 2"],
|
||||
["6p_testing_grounds", "Количество точек: 32/6/5\nСпорных точек: 10/2/5\nТермогенераторы: 6"],
|
||||
["6p_ruined_greatway", "Количество точек: 22/2/1\nСпорных точек: 2/2/1\nТермогенераторы: 2"],
|
||||
["6p_gear", "Количество точек: 24/2/3\nСпорных точек: 2 крита, но ввиду контактности карты сражение может идти на большинстве внешних точек\nТермогенераторы: 2"]]
|
||||
name = "Shoulder to shoulder cup"
|
||||
rules = """Классическая Double elimination с сеткой лузеров. В сетке виннеров - БО3, в сетке лузеров - БО1, в суперфинале - БО5. Игрок, прошедший в суперфинал из верхней сетки, имеет +1 очко. Игрок из нижней сетки начинает с лузерпиком. """
|
||||
}
|
||||
|
||||
springcup{
|
||||
description = true
|
||||
maps = [["4p_biffys_peril"],
|
||||
["4p_cold_war"],
|
||||
["4p_colosseum_of_deadman"],
|
||||
["4p_gorhael_crater"],
|
||||
["4p_imperial_area"],
|
||||
["4p_saints_square"],
|
||||
["4p_tartarus_center"],
|
||||
["4p_testcake"],
|
||||
["4p_skerries"],
|
||||
["4p_tiboraxx"],
|
||||
["4p_torrents"]]
|
||||
name = "Spring cup 2x2"
|
||||
rules = """Десайдеры выбирается методом вычеркивания до 3 карт, далее из оставшихся карт методом вычеркивания определяется первая карта. Игрок, начавший вычеркивание из основного пула уступает право начать вычеркивание из оставшихся карт. Исключение суперфинал: Команда прошедшая в суперфинал с верхней сетки имеет преимущество в выборе очередности карт из оставшихся 3 после вычеркивания."""
|
||||
}
|
||||
sweatybarrakcup{
|
||||
description = true
|
||||
maps =[["2p_chaos_gate"],
|
||||
["2p_colosseum_suicide"],
|
||||
["2p_emerald_river"],
|
||||
["2p_faceoff"],
|
||||
["2p_moonbase_[Ed]"],
|
||||
["2p_outer_reaches"],
|
||||
["2p_fear"],
|
||||
["2p_fraziersdemise"],
|
||||
["2p_sugaroasis"],
|
||||
["2p_terror_psyclaw"],
|
||||
["2p_titan_fall_[Rem]"],
|
||||
["2p_tranquilitys_end_[Rem]"],
|
||||
["2p_velvet_duress"],
|
||||
["2p_winter_confortation"],
|
||||
["2p_deadly_fun_archeology"]]
|
||||
name = "Sweaty barrack cup"
|
||||
rules = """Перед началом матча, игроки поочередно вычеркивают по одной карте, пока не выберут десайдер. Если иного не сказано в секции "Расы" (см. ограничения для рас). Во второй и всех последующих играх - побежденный выбирает карту.
|
||||
Чтобы не было повторений карт, игроки могу выбрать всего 1 раз карту из списка. """
|
||||
}
|
||||
tpmodcup{
|
||||
maps = ["2p_battle_marshes",
|
||||
"2p_fallen_city_[Rem]",
|
||||
"2p_fata_morgana_[Rem]",
|
||||
"2p_quests_triumph",
|
||||
"2p_shrine_of_excellion_[Rem]",
|
||||
"2p_titan_fall_[Rem]",
|
||||
"2p_tranquilitys_end_[Rem]",
|
||||
"2p_blood_river_[Rem]",
|
||||
"2p_sugaroasis",
|
||||
"2p_faceoff",
|
||||
"2p_deadly_fun_archeology",
|
||||
"2p_terror_psyclaw",
|
||||
"2p_meeting_of_minds"]
|
||||
name = "Турнир по ТП моду"
|
||||
rules = """ Первая карта десайдер выбирается методом вычеркивания, остальные лузер пик."""
|
||||
}
|
||||
bestfriendscup{
|
||||
maps = ["4p_gorhael_crater",
|
||||
"4p_gurmuns_pass",
|
||||
"4p_saints_square",
|
||||
"4p_skerries",
|
||||
"4p_panrea_lowlands",
|
||||
"4p_doom_spiral",
|
||||
"4p_tiboraxx"]
|
||||
name = "Best friends cup cup"
|
||||
rules = """ Обе команды вычеркивают по очереди неудобные для себя карты. Каждая команда вычеркивает в общей сложности 3. На оставшейся, седьмой карте, проходит Ваш первый матч - она называется десайдером. Во всех последующих играх карту выбирает команда, проигравшая в последнем матче. Это называется лузерпиком - выбором проигравших. В суперфинале турнира сражается команда из сетки виннеров против финалистов из сетки лузеров, в формате БО5 (до трёх побед). """
|
||||
}
|
||||
noweaknesscup{
|
||||
maps = [["2p_battle_marshes"],
|
||||
["2p_fallen_city_[Rem]"],
|
||||
["2p_fata_morgana_[Rem]"],
|
||||
["2p_quests_triumph"],
|
||||
["2p_shrine_of_excellion_[Rem]"],
|
||||
["2p_titan_fall_[Rem]"],
|
||||
["2p_tranquilitys_end_[Rem]"],
|
||||
["2p_fraziersdemise"],
|
||||
["2p_bloody_hell_[Ed]"],
|
||||
["2p_blood_river_[Rem]"],
|
||||
["2p_deadly_fun_archeology"]]
|
||||
name = "No Weakness cup"
|
||||
rules = """Выбор карт в БО3 и БО5 осуществляется без лузерпиков, с тремя и пятью десайдерами соответственно. Игроки вычеркивают по очереди карты из маппула, пока их не останется 3 (для БО3) или 5 (для БО5). На этих картах и проходят все матчи встречи. Затем игроки вычеркивают выбранные карты, пока не останется только одна, на которой и играется первый матч встречи. Тот, кто первым начал вычеркивать из всего маппула, уступает оппоненту право вычеркивания первой карты из оставшихся карт-десайдеров. Во втором и последующем матчах проигравший выбирает карту из числа выбранных 3 (5) десайдеров. """
|
||||
}
|
||||
|
||||
casinocup {
|
||||
maps = [["2p_battle_marshes"],
|
||||
["2p_fallen_city_[Rem]"],
|
||||
["2p_fata_morgana_[Rem]"],
|
||||
["2p_quests_triumph"],
|
||||
["2p_shrine_of_excellion_[Rem]"],
|
||||
["2p_titan_fall_[Rem]"],
|
||||
["2p_tranquilitys_end_[Rem]"],
|
||||
["2p_fraziersdemise"],
|
||||
["2p_bloody_hell"],
|
||||
["2p_blood_river_[Rem]"],
|
||||
["2p_deadly_fun_archeology"],
|
||||
["2p_outer_reaches"],
|
||||
["2p_meeting_of_minds"]]
|
||||
name = "Casino cup"
|
||||
rules = """Выбор карт без лузерпиков, с тремя и пятью десайдерами соответственно. Игроки вычеркивают по очереди карты из маппула, пока их не останется 3 (для БО3) или 5 (для БО5). На этих картах и проходят все матчи встречи. Затем игроки вычеркивают выбранные карты, пока не останется только одна, на которой и играется первый матч встречи. Тот, кто первым начал вычеркивать из всего маппула, уступает оппоненту право вычеркивания первой карты из оставшихся карт-десайдеров. Во втором и последующем матчах проигравший выбирает карту из числа выбранных 3 (5) десайдеров. """
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,42 +1,48 @@
|
||||
<!--
|
||||
Copyright (C) Lightbend Inc. <https://www.lightbend.com>
|
||||
-->
|
||||
|
||||
<!-- The default logback configuration that Play uses if no other configuration is provided -->
|
||||
<configuration>
|
||||
|
||||
<conversionRule conversionWord="coloredLevel" converterClass="play.api.libs.logback.ColoredLevel"/>
|
||||
<conversionRule conversionWord="coloredLevel" converterClass="play.api.libs.logback.ColoredLevel" />
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%coloredLevel %logger{15} - %message%n%xException{10}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="FILE" class="ch.qos.logback.core.RollingFileAppender">
|
||||
<file>logs/decider.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- daily rollover -->
|
||||
<fileNamePattern>logs/decider.%d{yyyy-MM-dd_HH-mm}.log</fileNamePattern>
|
||||
<appender name="ASYNCSTDOUT" class="ch.qos.logback.classic.AsyncAppender">
|
||||
<!-- increases the default queue size -->
|
||||
<queueSize>512</queueSize>
|
||||
<!-- don't discard messages -->
|
||||
<discardingThreshold>0</discardingThreshold>
|
||||
<!-- block when queue is full -->
|
||||
<neverBlock>false</neverBlock>
|
||||
<appender-ref ref="STDOUT" />
|
||||
</appender>
|
||||
|
||||
<!-- keep 30 days' worth of history capped at 3GB total size -->
|
||||
<maxHistory>30</maxHistory>
|
||||
<totalSizeCap>3GB</totalSizeCap>
|
||||
</rollingPolicy>
|
||||
<logger name="play" level="INFO" />
|
||||
|
||||
<logger name="com.gargoylesoftware.htmlunit.javascript" level="OFF" />
|
||||
|
||||
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
|
||||
<file>${application.home:-.}/logs/application.log</file>
|
||||
<encoder>
|
||||
<pattern>%date [%level] from %logger in %thread - %message%n%xException</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%coloredLevel %logger{15} - [%marker] %message%n%xException{10}</pattern>
|
||||
</encoder>
|
||||
<appender name="ASYNCFILE" class="ch.qos.logback.classic.AsyncAppender">
|
||||
<appender-ref ref="FILE" />
|
||||
</appender>
|
||||
|
||||
<logger name="play" level="INFO"/>
|
||||
|
||||
<!-- actors logging -->
|
||||
<logger name="akka" level="DEBUG"/>
|
||||
|
||||
<logger name="actors" level="DEBUG"/>
|
||||
|
||||
<!-- controllers -->
|
||||
<logger name="controllers" level="DEBUG"/>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT"/>
|
||||
<appender-ref ref="FILE"/>
|
||||
<appender-ref ref="ASYNCFILE" />
|
||||
<appender-ref ref="ASYNCSTDOUT" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
<shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook"/>
|
||||
|
||||
</configuration>
|
||||