Рабочий десайдер

This commit is contained in:
v.holodov 2023-05-04 23:58:43 +03:00
parent dc228d82be
commit 31ce4b7beb
23 changed files with 206 additions and 97 deletions

View File

@ -11,6 +11,7 @@ import java.util
import scala.collection.JavaConverters.iterableAsScalaIterableConverter import scala.collection.JavaConverters.iterableAsScalaIterableConverter
import scala.collection.immutable.HashSet import scala.collection.immutable.HashSet
import scala.concurrent.duration._ import scala.concurrent.duration._
import scala.util.Try
case class LobbyUser(name: String, actorRef: ActorRef) 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 lobbyType: LobbyType = Last1()
private var isNecrons: Boolean = false
private var firstPlayerSelectedRaces: Option[SelectedRaces] = None private var firstPlayerSelectedRaces: Option[SelectedRaces] = None
private var secondPlayerSelectedRaces: 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] = { private val mapsLobby: Set[DeciderMap] = {
val configMaps = config.getList(s"deciders.$deciderName.maps").asScala val configMaps = config.getList(s"deciders.$deciderName.maps").asScala
configMaps.map(e => { configMaps.map(e => {
@ -67,7 +66,7 @@ class LobbieActor(hostUser: LobbyUser, deciderName: String) extends Actor with L
status.toString(), status.toString(),
playerTurn, playerTurn,
lobbyType.toString(), lobbyType.toString(),
isNecrons, isSolo,
mapsLobby)), mapsLobby)),
this.self) this.self)
@ -79,6 +78,16 @@ class LobbieActor(hostUser: LobbyUser, deciderName: String) extends Actor with L
// notify watchers // notify watchers
logger.info(s"Ban map $mapName by ${sender.path.name}") 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 (status == Draft()) {
if ((playerTurn == 1 && sender == host.actorRef) || if ((playerTurn == 1 && sender == host.actorRef) ||
(playerTurn == 2 && secondPlayer.exists(_.actorRef == sender))) { (playerTurn == 2 && secondPlayer.exists(_.actorRef == sender))) {
@ -87,19 +96,10 @@ class LobbieActor(hostUser: LobbyUser, deciderName: String) extends Actor with L
if (!map.isBanned) { if (!map.isBanned) {
map.isBanned = true map.isBanned = true
if (playerTurn == 1) playerTurn = 2 else playerTurn = 1 if (playerTurn == 1) playerTurn = 2 else playerTurn = 1
if (mapsLobby.count(_.isBanned == false) == 1 && lobbyType == Last1() || if (isFinish) {
mapsLobby.count(_.isBanned == false) == 3 && lobbyType == Last3() ||
mapsLobby.count(_.isBanned == false) == 5 && lobbyType == Last5() ||
mapsLobby.count(_.isBanned == false) == 7 && lobbyType == Last7()
) {
status = Finish() status = Finish()
} }
users.foreach(_ ! RefreshLobbyInfo(getLobbyInfoResponse)) refreshAndBanMap(mapName)
val senderName: String = if (sender == host.actorRef) {
host.name
} else secondPlayer.get.name
users.foreach(_ ! SendBanMapMessage(BanMapMessage(senderName, mapName)))
} else { } else {
logger.warn(s"User ban map $mapName, but map already banned") 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(), status.toString(),
playerTurn, playerTurn,
lobbyType.toString(), lobbyType.toString(),
isNecrons, isSolo,
mapsLobby) 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) case class BanMap(mapName: String)
@ -269,7 +285,7 @@ case class LobbyInfo(user1Info: UserInfo,
status: String, status: String,
playerTurn: BigDecimal, playerTurn: BigDecimal,
selectedType: String, selectedType: String,
isNecrons: Boolean, isSolo: Boolean,
maps: Set[DeciderMap]) maps: Set[DeciderMap])
class LobbyStatus class LobbyStatus

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 499 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View File

@ -3,6 +3,11 @@ var ws;
var userName = "" var userName = ""
var raceCount = $("#raceCount").html() var raceCount = $("#raceCount").html()
var isSolo = $("#isSolo").html() === 'true'
var isMuted = false;
var isDraftStarted = false;
window.onload = function() { 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) { $("#exit").click(function(event) {
event.preventDefault(); event.preventDefault();
@ -123,7 +137,6 @@ window.onload = function() {
$("#playerName").html(userName); $("#playerName").html(userName);
ws = new WebSocket($("body").data("ws-url")); ws = new WebSocket($("body").data("ws-url"));
ws.onmessage = function(event) { ws.onmessage = function(event) {
var message; var message;
@ -131,6 +144,7 @@ window.onload = function() {
switch (message.type) { switch (message.type) {
case "refreshLobby": case "refreshLobby":
if(message.lobby.status === "SelectRace()" && (!isObserver)){ if(message.lobby.status === "SelectRace()" && (!isObserver)){
isDraftStarted = false;
renderRaces(); renderRaces();
}else { }else {
renderMaps(message.lobby.maps, message.lobby.status); renderMaps(message.lobby.maps, message.lobby.status);
@ -140,7 +154,7 @@ window.onload = function() {
case "switchToLobby": case "switchToLobby":
console.log(message); console.log(message);
switchToLobby(message.lobby.maps, message.lobby.status); switchToLobby(message.lobby.maps, message.lobby.status);
renderPlayersAndStats(message.lobby); if(!isSolo) renderPlayersAndStats(message.lobby);
break; break;
case "sendMessage": case "sendMessage":
console.log(message); console.log(message);
@ -148,7 +162,7 @@ window.onload = function() {
break; break;
case "sendMapBanMessage": case "sendMapBanMessage":
console.log(message); console.log(message);
addBanMapMessageToChat(message.message); handleMapBanEvent(message.message);
break; break;
case "lobbyError": case "lobbyError":
console.log(message); console.log(message);
@ -295,7 +309,7 @@ function renderRaces() {
banned = "bannedRace"; banned = "bannedRace";
selectedFourthRace = i; selectedFourthRace = i;
} }
resHtml += '<a href = "#" class="'+selected+' thirdRaceIcon" onclick="selectFourthRace(this, ' +i+')"><img class="raceIcon" src="'+getRaceImageByNumber(i)+'"></a> '; resHtml += '<a href = "#" class="'+selected+' fourthRaceIcon" onclick="selectFourthRace(this, ' +i+')"><img class="raceIcon" src="'+getRaceImageByNumber(i)+'"></a> ';
} }
resHtml += "</center></div>"; resHtml += "</center></div>";
} }
@ -392,7 +406,7 @@ function renderMaps(maps, lobbyStatus) {
banHtml = "<div class = 'banX'>&#x2715;</div>"; banHtml = "<div class = 'banX'>&#x2715;</div>";
banClass = "bannedMap"; banClass = "bannedMap";
} }
if(lobbyStatus === "NotStarted()"){ if(lobbyStatus === "NotStarted()" && !isSolo){
banClass = "bannedMap"; banClass = "bannedMap";
} }
@ -427,28 +441,30 @@ function renderFinish(maps, firstPlayerInfo, secondPlayerInfo) {
resHtml += "<div style='clear: both;'>"; resHtml += "<div style='clear: both;'>";
resHtml += "<h2>" + firstPlayerInfo.name + "</h2>"; if(!isSolo){
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(firstPlayerInfo.selectedRaces.firstRace)+"> "; resHtml += "<h2>" + firstPlayerInfo.name + "</h2>";
if(raceCount >= 2){ resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(firstPlayerInfo.selectedRaces.firstRace)+"> ";
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(firstPlayerInfo.selectedRaces.secondRace)+"> "; if(raceCount >= 2){
} resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(firstPlayerInfo.selectedRaces.secondRace)+"> ";
if(raceCount >= 3){ }
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(firstPlayerInfo.selectedRaces.thirdRace)+"> "; if(raceCount >= 3){
} resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(firstPlayerInfo.selectedRaces.thirdRace)+"> ";
if(raceCount >= 4){ }
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(firstPlayerInfo.selectedRaces.fourthRace)+"> "; if(raceCount >= 4){
} resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(firstPlayerInfo.selectedRaces.fourthRace)+"> ";
}
resHtml += "<h2>" + secondPlayerInfo.name + "</h2>"; resHtml += "<h2>" + secondPlayerInfo.name + "</h2>";
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(secondPlayerInfo.selectedRaces.firstRace)+"> "; resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(secondPlayerInfo.selectedRaces.firstRace)+"> ";
if(raceCount >= 2){ if(raceCount >= 2){
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(secondPlayerInfo.selectedRaces.secondRace)+"> "; resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(secondPlayerInfo.selectedRaces.secondRace)+"> ";
} }
if(raceCount >= 3){ if(raceCount >= 3){
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(secondPlayerInfo.selectedRaces.thirdRace)+"> "; resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(secondPlayerInfo.selectedRaces.thirdRace)+"> ";
} }
if(raceCount >= 4){ if(raceCount >= 4){
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(secondPlayerInfo.selectedRaces.fourthRace)+"> "; resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(secondPlayerInfo.selectedRaces.fourthRace)+"> ";
}
} }
resHtml += "</center>" resHtml += "</center>"
@ -566,32 +582,39 @@ function renderPlayersAndStats(lobby) {
resHtml += "</div>"; resHtml += "</div>";
break; break;
case "SelectRace()": case "SelectRace()":
resHtml = "<center>"+lobby.user1Info.name + " vs " + lobby.user2Info.name + " - " +lobbyTypeText+ "<br/> players select races</center>"; resHtml = "<center>"+lobby.user1Info.name + " vs " + lobby.user2Info.name + " - " +lobbyTypeText+ "<br/> players select races</center>";
break; break;
case "Draft()": case "Draft()":
console.log(lobby.turn); if(!isDraftStarted){
var playerTurn = (lobby.playerTurn === 1) ? lobby.user1Info.name : lobby.user2Info.name isDraftStarted = true;
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)+"> "; if(!isSolo){
} var playerTurn = (lobby.playerTurn === 1) ? lobby.user1Info.name : lobby.user2Info.name
if(raceCount > 3){ resHtml = "<center>"+lobby.user1Info.name + " vs " + lobby.user2Info.name + " - " +lobbyTypeText+ "<br/><b>" + playerTurn +"</b> turn</center>";
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(lobby.user1Info.selectedRaces.fourthRace)+"> "; resHtml += "<center><img class=\"raceIcon\" src="+getRaceImageByNumber(lobby.user1Info.selectedRaces.firstRace)+"> ";
} if(raceCount > 1){
resHtml += " <span style='font-size: 14px'>VS</span> "; resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(lobby.user1Info.selectedRaces.secondRace)+"> ";
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(lobby.user2Info.selectedRaces.firstRace)+">"; }
if(raceCount > 1){ if(raceCount > 2){
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(lobby.user2Info.selectedRaces.secondRace)+"> "; resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(lobby.user1Info.selectedRaces.thirdRace)+"> ";
} }
if(raceCount > 2){ if(raceCount > 3){
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(lobby.user2Info.selectedRaces.thirdRace)+"> "; resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(lobby.user1Info.selectedRaces.fourthRace)+"> ";
} }
if(raceCount > 3){ resHtml += " <span style='font-size: 14px'>VS</span> ";
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(lobby.user2Info.selectedRaces.fourthRace)+"> "; 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)+"> ";
}
if(raceCount > 3){
resHtml += "<img class=\"raceIcon\" src="+getRaceImageByNumber(lobby.user2Info.selectedRaces.fourthRace)+"> ";
}
} }
break; break;
case "Finish()": case "Finish()":
@ -611,7 +634,13 @@ function addMessageToChat(message){
chatBox.scrollTop(40000); 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 = "<div class='msgln'><span style='color: #2C3D9B'>" + convertMapName(message.mapTechName) + "</span> banned by " + message.user + "<br></div>"; var messageHtml = "<div class='msgln'><span style='color: #2C3D9B'>" + convertMapName(message.mapTechName) + "</span> banned by " + message.user + "<br></div>";
var chatBox = $("#chatbox"); var chatBox = $("#chatbox");
chatBox.append(messageHtml); chatBox.append(messageHtml);
@ -688,6 +717,10 @@ function kickSecondPlayer(){
} }
function convertMapName (techMapName) { 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); return mapName.charAt(0).toUpperCase() + mapName.slice(1);
} }

BIN
app/assets/sound/blip.mp3 Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -43,10 +43,11 @@ class HomeController @Inject()(cc: ControllerComponents) extends AbstractControl
logger.info(s"Received request from: ${request.remoteAddress}") logger.info(s"Received request from: ${request.remoteAddress}")
val deciderHumanName = config.getString(s"deciders.$deciderName.name") val deciderHumanName = config.getString(s"deciders.$deciderName.name")
val deciderDescription = config.getString(s"deciders.$deciderName.rules") 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 raceCount = Try(config.getInt(s"deciders.$deciderName.raceCount")).getOrElse(1)
val lastmapsSettings = LastMapsSelectConfig(true, true, true, true) val lastmapsSettings = LastMapsSelectConfig(true, true, true, true)
val raceSelect = RaceSelect(true, false) 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))
} }
/** /**

View File

@ -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[_])
<!DOCTYPE html> <!DOCTYPE html>
<span id="deciderName" style="display: none">@deciderName</span> <span id="deciderName" style="display: none">@deciderName</span>
@ -7,6 +7,7 @@
<span id="last3Presence" style="display: none">@boSettings.last3</span> <span id="last3Presence" style="display: none">@boSettings.last3</span>
<span id="last5Presence" style="display: none">@boSettings.last5</span> <span id="last5Presence" style="display: none">@boSettings.last5</span>
<span id="last7Presence" style="display: none">@boSettings.last7</span> <span id="last7Presence" style="display: none">@boSettings.last7</span>
<span id="isSolo" style="display: none">@isSolo</span>
<html> <html>
@ -20,7 +21,7 @@
<script type='text/javascript' src='@routes.Assets.at("lib/underscore/underscore.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/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("lib/jquery-cookie/jquery.cookie.js")"></script>
<script type='text/javascript' src='@routes.Assets.at("javascripts/index.js?270822")'></script> <script type='text/javascript' src='@routes.Assets.at("javascripts/index.js?301222")'></script>
</head> </head>
<body data-ws-url="@routes.HomeController.ws.webSocketURL()"> <body data-ws-url="@routes.HomeController.ws.webSocketURL()">
<div class="navbar navbar-inverse navbar-fixed-top"> <div class="navbar navbar-inverse navbar-fixed-top">
@ -44,6 +45,7 @@
<div id = "decider" style="display:none"> <div id = "decider" style="display:none">
<button id = "exit" class="btn btn-primary">Exit</button> <button id = "exit" class="btn btn-primary">Exit</button>
<button id = "mute" class="btn btn-primary">🔊</button>
<br/> <br/>
<div id = "mapList" class="container"></div> <div id = "mapList" class="container"></div>
<div id = "playersStatsList"></div> <div id = "playersStatsList"></div>

View File

@ -6,6 +6,7 @@ lazy val root = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.12.8" scalaVersion := "2.12.8"
cancelable in Global := true
// scalaz-bintray resolver needed for specs2 library // scalaz-bintray resolver needed for specs2 library
resolvers += "scalaz-bintray" at "https://dl.bintray.com/scalaz/releases" resolvers += "scalaz-bintray" at "https://dl.bintray.com/scalaz/releases"

View File

@ -25,6 +25,42 @@ deciders{
name = "Классический десайдер" name = "Классический десайдер"
rules = """""" rules = """"""
} }
flazzomappool{
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_emerald_river"],
["2p_sugaroasis"],
["2p_blood_river_[Rem]"],
["2p_deadly_fun_archeology"],
["2p_bloody_hell_[Ed]"]]
raceCount = 2
name = "Десайдер flazzo"
rules = """"""
}
salats{
maps = [["винегрет"],
["грибная поляна"],
["крабовый"],
["мимоза"],
["оливье"],
["селедка под шубой"],
["цезарь"],
["из пекинской капусты"],
["гнездо глухаря"],
["летний"]]
name = "Выбираем салат на новый год"
isSolo = true
rules = """"""
}
turtleshell{ turtleshell{
maps = [["2p_battle_marshes"], maps = [["2p_battle_marshes"],
["2p_fallen_city_[Rem]"], ["2p_fallen_city_[Rem]"],
@ -44,6 +80,35 @@ deciders{
name = "Turtle Shell tournament" name = "Turtle Shell tournament"
rules = """Выбор карт в BO3: Игроки вычеркивают по очереди карты из маппула, пока их не останется 3 (три). Вычеркивания проводятся вручную в лобби игры или с помощью десайдера, если такая техническая возможность присутствует. Таким образом каждый вычеркнет 6 карт пока не останутся 3 карты.""" rules = """Выбор карт в BO3: Игроки вычеркивают по очереди карты из маппула, пока их не останется 3 (три). Вычеркивания проводятся вручную в лобби игры или с помощью десайдера, если такая техническая возможность присутствует. Таким образом каждый вычеркнет 6 карт пока не останутся 3 карты."""
} }
winter_adventures{
maps = [["6p_ruined_greatway"],
["6p_fury_island"],
["6p_irridene"],
["6p_testing_grounds"],
["6p_paynes_retribution"],
["6p_shakun_coast"],
["6p_paynes_retribution"],
["6p_gear"]]
name = "Winter adventures"
raceCount = 3
rules = """Капитаны команд по очереди вычеркивают карты из маппула, пока их не останется 3-ри. На этих картах проходят все матчи встречи. Затем капитаны вычеркивают выбранные карты, пока не останется только одна, на которой и играется первый матч встречи. Выбор оставшихся карт встречи определяется правом лузерпика - проигравший определяет карту из оставшихся. """
}
noloody_mappool{
maps = [["2p_battle_marshes"],
["2p_fallen_city"],
["2p_outer_reaches"],
["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 = "Noloody map pool"
raceCount = 2
rules = """См. в дискорде"""
}
dvijcup{ dvijcup{
maps = ["2p_battle_marshes", maps = ["2p_battle_marshes",
"2p_fallen_city_[Rem]", "2p_fallen_city_[Rem]",
@ -121,6 +186,20 @@ deciders{
raceCount = 2 raceCount = 2
rules = """Выбор карт в БО3 и БО5 осуществляется без лузерпиков, с тремя и пятью десайдерами соответственно. Игроки вычеркивают по очереди карты из маппула, пока их не останется 3 (для БО3) или 5 (для БО5). На этих картах и проходят все матчи встречи. Затем игроки вычеркивают выбранные карты, пока не останется только одна, на которой и играется первый матч встречи. Тот, кто первым начал вычеркивать из всего маппула, уступает оппоненту право вычеркивания первой карты из оставшихся карт-десайдеров. Во втором и последующем матчах проигравший выбирает карту из числа выбранных 3 (5) десайдеров.""" rules = """Выбор карт в БО3 и БО5 осуществляется без лузерпиков, с тремя и пятью десайдерами соответственно. Игроки вычеркивают по очереди карты из маппула, пока их не останется 3 (для БО3) или 5 (для БО5). На этих картах и проходят все матчи встречи. Затем игроки вычеркивают выбранные карты, пока не останется только одна, на которой и играется первый матч встречи. Тот, кто первым начал вычеркивать из всего маппула, уступает оппоненту право вычеркивания первой карты из оставшихся карт-десайдеров. Во втором и последующем матчах проигравший выбирает карту из числа выбранных 3 (5) десайдеров."""
} }
customcup{
maps = [["2p_battle_marshes"],
["2p_blood_river_[Rem]"],
["2p_fallen_city_[Rem]"],
["2p_outer_reaches"],
["2p_quests_triumph"],
["2p_shrine_of_excellion_[Rem]"],
["2p_sugaroasis"],
["2p_titan_fall_[Rem]"],
["2p_tranquilitys_end_[Rem]"]]
name = "Custom Cup"
raceCount = 2
rules = """Выбор карт в БО3 и БО5 осуществляется без лузерпиков, с тремя и пятью десайдерами соответственно. Игроки вычеркивают по очереди карты из маппула, пока их не останется 3 (для БО3) или 5 (для БО5). На этих картах и проходят все матчи встречи. Затем игроки вычеркивают выбранные карты, пока не останется только одна, на которой и играется первый матч встречи. Тот, кто первым начал вычеркивать из всего маппула, уступает оппоненту право вычеркивания первой карты из оставшихся карт-десайдеров. Во втором и последующем матчах проигравший выбирает карту из числа выбранных 3 (5) десайдеров."""
}
everyonecup{ everyonecup{
maps = [["2p_battle_marshes"], maps = [["2p_battle_marshes"],
["2p_fallen_city_[Rem]"], ["2p_fallen_city_[Rem]"],
@ -205,7 +284,7 @@ deciders{
["6p_fury_island", "Количество точек: 26/6/1\nСпорных точек: 6 + 1 крит\nТермогенераторы: Отсутствуют"], ["6p_fury_island", "Количество точек: 26/6/1\nСпорных точек: 6 + 1 крит\nТермогенераторы: Отсутствуют"],
["6p_irridene", "Количество точек: 21/6/3\nСпорных точек: 6/0/3\nТермогенераторы: 6"], ["6p_irridene", "Количество точек: 21/6/3\nСпорных точек: 6/0/3\nТермогенераторы: 6"],
["6p_shakun_coast", "Количество точек: 24/4/1\nСпорных точек: 6/2/1\nТермогенераторы: 2"], ["6p_shakun_coast", "Количество точек: 24/4/1\nСпорных точек: 6/2/1\nТермогенераторы: 2"],
["6p_snowblind", "Количество точек: 22/2/3\nСпорных точек: 4/2/3\nТермогенераторы: отсутствуют"], ["6p_platform", "Количество точек: 26/2/3\nТермогенераторы: 2"],
["6p_temple_cyrene", "Количество точек: 25/4/5\nСпорных точек: 8/0/3\nТермогенераторы: 2"], ["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_testing_grounds", "Количество точек: 32/6/5\nСпорных точек: 10/2/5\nТермогенераторы: 6"],
["6p_ruined_greatway", "Количество точек: 22/2/1\nСпорных точек: 2/2/1\nТермогенераторы: 2"], ["6p_ruined_greatway", "Количество точек: 22/2/1\nСпорных точек: 2/2/1\nТермогенераторы: 2"],
@ -217,16 +296,16 @@ deciders{
description = true description = true
raceCount = 4 raceCount = 4
maps = [["8p_burial_grounds", "Количество стратегических/реликтовых/критических точек: 32/2/4\nСпорных точек: 4/2/2\nТермогенераторы: 3"], maps = [["8p_burial_grounds", "Количество стратегических/реликтовых/критических точек: 32/2/4\nСпорных точек: 4/2/2\nТермогенераторы: 3"],
["8p_daturias_pits", "Количество стратегических/реликтовых/критических точек: 26/6/1\nСпорных точек: 2/2/1\nТермогенераторы: 0"], ["8p_daturias_pits", "Количество стратегических/реликтовых/критических точек: 32/4/5\nСпорных точек: 2/2/1\nТермогенераторы: 0"],
["8p_forbidden_jungle", "Количество стратегических/реликтовых/критических точек: 36/5/0\nСпорных точек: 12/5/0\nТермогенераторы: 4"], ["8p_forbidden_jungle", "Количество стратегических/реликтовых/критических точек: 36/5/0\nСпорных точек: 12/5/0\nТермогенераторы: 4"],
["8p_demes_northlands", "Количество стратегических/реликтовых/критических точек: 32/4/3\nСпорных точек: 3/2/2\nТермогенераторы: 2"], ["8p_demes_northlands", "Количество стратегических/реликтовых/критических точек: 32/4/3\nСпорных точек: 3/2/2\nТермогенераторы: 2"],
["8p_glacier", "Количество стратегических/реликтовых/критических точек: 24/4/5\nСпорных точек: 0/0/4\nТермогенераторы: 4"], ["8p_glacier", "Количество стратегических/реликтовых/критических точек: 24/4/5\nСпорных точек: 0/0/4\nТермогенераторы: 4"],
["8p_jalaganda_lowlands", "Количество стратегических/реликтовых/критических точек: 26/5/3\nСпорных точек: 2/1/3\nТермогенераторы: 0"], ["8p_jalaganda_lowlands", "Количество стратегических/реликтовых/критических точек: 26/5/3\nСпорных точек: 2/1/3\nТермогенераторы: 0"],
["8p_monse", "Количество стратегических/реликтовых/критических точек: 26/4/4\nСпорных точек: 2/2/4\nТермогенераторы: 1t"], ["8p_monse", "Количество стратегических/реликтовых/критических точек: 26/4/4\nСпорных точек: 2/2/4\nТермогенераторы: 1"],
["8p_thurabis_plateau", "Количество стратегических/реликтовых/критических точек: 32/2/0\nСпорных точек: 12/2/0\nТермогенераторы: 0"], ["8p_thurabis_plateau", "Количество стратегических/реликтовых/критических точек: 32/2/0\nСпорных точек: 12/2/0\nТермогенераторы: 0"],
["8p_verdant_isles_ed", "Количество стратегических/реликтовых/критических точек: 32/4/3\nСпорных точек: 0/4/3\nТермогенераторы: 0"]] ["8p_verdant_isles_ed", "Количество стратегических/реликтовых/критических точек: 32/4/3\nСпорных точек: 0/4/3\nТермогенераторы: 0"]]
name = "Shoulder to shoulder cup" name = "Shoulder to shoulder cup"
rules = """Классическая Double elimination с сеткой лузеров. В сетке виннеров - БО3, в сетке лузеров - БО1, в суперфинале - БО5. Игрок, прошедший в суперфинал из верхней сетки, имеет +1 очко. Игрок из нижней сетки начинает с лузерпиком. """ rules = """Черкается по правилу лузерпиков: сначала оставляется одна карта, далее команда выбирает, на какой карте будет играть. """
} }
springcup{ springcup{
description = true description = true
@ -313,13 +392,11 @@ deciders{
description = true description = true
maps =[["2p_battle_marshes"], maps =[["2p_battle_marshes"],
["2p_fallen_city_[Rem]"], ["2p_fallen_city_[Rem]"],
["2p_fata_morgana_[Rem]"],
["2p_emerald_river"], ["2p_emerald_river"],
["2p_quests_triumph"], ["2p_quests_triumph"],
["2p_shrine_of_excellion_[Rem]"], ["2p_shrine_of_excellion_[Rem]"],
["2p_titan_fall_[Rem]"], ["2p_titan_fall_[Rem]"],
["2p_tranquilitys_end_[Rem]"], ["2p_tranquilitys_end_[Rem]"],
["2p_fraziersdemise"],
["2p_bloody_hell_[Ed]"], ["2p_bloody_hell_[Ed]"],
["2p_blood_river_[Rem]"], ["2p_blood_river_[Rem]"],
["2p_deadly_fun_archeology"], ["2p_deadly_fun_archeology"],
@ -329,27 +406,6 @@ deciders{
name = "Frenetic map pool" name = "Frenetic map pool"
rules = """ """ rules = """ """
} }
freneticmappool{
raceCount = 2
description = true
maps =[["2p_battle_marshes"],
["2p_fallen_city_[Rem]"],
["2p_fata_morgana_[Rem]"],
["2p_emerald_river"],
["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"],
["2p_sugaroasis"],
["2p_outer_reaches"],
["2p_meeting_of_minds"]]
name = "Frenetic map pool"
rules = """ """
}
freneticmappool2{ freneticmappool2{
raceCount = 2 raceCount = 2
description = true description = true